diff --git a/src/main/java/ortus/boxlang/runtime/components/system/Log.java b/src/main/java/ortus/boxlang/runtime/components/system/Log.java new file mode 100644 index 000000000..538506426 --- /dev/null +++ b/src/main/java/ortus/boxlang/runtime/components/system/Log.java @@ -0,0 +1,64 @@ + +/** + * [BoxLang] + * + * Copyright [2023] [Ortus Solutions, Corp] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ortus.boxlang.runtime.components.system; + +import ortus.boxlang.runtime.components.Attribute; +import ortus.boxlang.runtime.components.Component; +import ortus.boxlang.runtime.context.IBoxContext; +import ortus.boxlang.runtime.events.BoxEvent; +import ortus.boxlang.runtime.scopes.Key; +import ortus.boxlang.runtime.types.IStruct; + +public class Log extends Component { + + private final Key writeLogKey = Key.of( "writeLog" ); + + /** + * Constructor + */ + public Log() { + super(); + // Uncomment and define declare argument to this Component + declaredAttributes = new Attribute[] { + new Attribute( Key.text, "string" ), + new Attribute( Key.file, "string" ), + new Attribute( Key.log, "string", "Application" ), + new Attribute( Key.type, "string", "Information" ), + }; + } + + /** + * Describe what the invocation of your component does + * + * @param context The context in which the Component is being invoked + * @param attributes The attributes to the Component + * @param body The body of the Component + * @param executionState The execution state of the Component + * + * @attribute.foo Describe any expected arguments + */ + public BodyResult _invoke( IBoxContext context, IStruct attributes, ComponentBody body, IStruct executionState ) { + + interceptorService.announce( BoxEvent.LOG_MESSAGE, attributes ); + + return DEFAULT_RETURN; + } + +} diff --git a/src/test/java/ortus/boxlang/runtime/components/system/LogTest.java b/src/test/java/ortus/boxlang/runtime/components/system/LogTest.java new file mode 100644 index 000000000..2fd2ae9b3 --- /dev/null +++ b/src/test/java/ortus/boxlang/runtime/components/system/LogTest.java @@ -0,0 +1,155 @@ + +/** + * [BoxLang] + * + * Copyright [2023] [Ortus Solutions, Corp] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ortus.boxlang.runtime.components.system; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.file.Paths; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import ortus.boxlang.compiler.parser.BoxSourceType; +import ortus.boxlang.runtime.BoxRuntime; +import ortus.boxlang.runtime.context.IBoxContext; +import ortus.boxlang.runtime.context.ScriptingRequestBoxContext; +import ortus.boxlang.runtime.dynamic.casters.StringCaster; +import ortus.boxlang.runtime.scopes.IScope; +import ortus.boxlang.runtime.scopes.Key; +import ortus.boxlang.runtime.scopes.VariablesScope; +import ortus.boxlang.runtime.util.FileSystemUtil; + +public class LogTest { + + static BoxRuntime instance; + static String logsDirectory; + IBoxContext context; + IScope variables; + static Key result = new Key( "result" ); + + @BeforeAll + public static void setUp() { + instance = BoxRuntime.getInstance( true ); + logsDirectory = instance.getConfiguration().runtime.logsDirectory; + + } + + @AfterAll + public static void teardown() { + } + + @BeforeEach + public void setupEach() { + context = new ScriptingRequestBoxContext( instance.getRuntimeContext() ); + variables = context.getScopeNearby( VariablesScope.name ); + } + + @DisplayName( "It tests the BIF Log with Script parsing" ) + @Test + public void testComponentScript() { + instance.executeSource( + """ + log text="Hello Logger!" log="Foo" file="foo.log"; + """, + context, BoxSourceType.BOXSCRIPT ); + } + + @DisplayName( "It tests the BIF Log with CFML parsing" ) + @Test + public void testComponentCF() { + instance.executeSource( + """ + + """, + context, BoxSourceType.CFTEMPLATE ); + } + + @DisplayName( "It tests the BIF Log with BoxLang parsing" ) + @Test + public void testComponentBX() { + instance.executeSource( + """ + + """, + context, BoxSourceType.BOXTEMPLATE ); + } + + @DisplayName( "It tests the BIF Log with Script parsing" ) + @Test + public void testComponentCustomLogScript() { + String logFilePath = Paths.get( logsDirectory, "/foo.log" ).normalize().toString(); + if ( FileSystemUtil.exists( logFilePath ) ) { + FileSystemUtil.deleteFile( logFilePath ); + } + + instance.executeSource( + """ + log text="Hello Logger!" log="Foo" file="foo.log"; + """, + context, BoxSourceType.BOXSCRIPT ); + + assertTrue( FileSystemUtil.exists( logFilePath ) ); + String fileContent = StringCaster.cast( FileSystemUtil.read( logFilePath ) ); + assertTrue( StringUtils.contains( fileContent, "Hello Logger!" ) ); + } + + @DisplayName( "It tests the BIF Log with CF tag parsing" ) + @Test + public void testComponentCustomLogCF() { + String logFilePath = Paths.get( logsDirectory, "/foo.log" ).normalize().toString(); + if ( FileSystemUtil.exists( logFilePath ) ) { + FileSystemUtil.deleteFile( logFilePath ); + } + + instance.executeSource( + """ + + """, + context, BoxSourceType.CFTEMPLATE ); + + assertTrue( FileSystemUtil.exists( logFilePath ) ); + String fileContent = StringCaster.cast( FileSystemUtil.read( logFilePath ) ); + assertTrue( StringUtils.contains( fileContent, "Hello Logger!" ) ); + } + + @DisplayName( "It tests the BIF Log with BX tag parsing" ) + @Test + public void testComponentCustomLogBX() { + String logFilePath = Paths.get( logsDirectory, "/foo.log" ).normalize().toString(); + if ( FileSystemUtil.exists( logFilePath ) ) { + FileSystemUtil.deleteFile( logFilePath ); + } + + instance.executeSource( + """ + + """, + context, BoxSourceType.BOXTEMPLATE ); + + assertTrue( FileSystemUtil.exists( logFilePath ) ); + String fileContent = StringCaster.cast( FileSystemUtil.read( logFilePath ) ); + assertTrue( StringUtils.contains( fileContent, "Hello Logger!" ) ); + } + +} diff --git a/workbench/tasks/ScaffoldComponent.cfc b/workbench/tasks/ScaffoldComponent.cfc index 8305f7f7a..50fc4cbff 100644 --- a/workbench/tasks/ScaffoldComponent.cfc +++ b/workbench/tasks/ScaffoldComponent.cfc @@ -149,6 +149,7 @@ component { import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; + import ortus.boxlang.compiler.parser.BoxSourceType; import ortus.boxlang.runtime.BoxRuntime; import ortus.boxlang.runtime.context.IBoxContext; import ortus.boxlang.runtime.context.ScriptingRequestBoxContext; @@ -193,7 +194,7 @@ component { @DisplayName( "It tests the BIF #componentName# with BoxLang parsing" ) @Test - public void testComponentCF() { + public void testComponentBX() { instance.executeSource( """