From 853823da896da85ada81513b544ea1cbe48fed7b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 25 Nov 2025 06:24:06 +0000
Subject: [PATCH 1/4] Initial plan
From 8a7e7c925456d05455ddb54e89a05154b70dc5b6 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 25 Nov 2025 06:30:22 +0000
Subject: [PATCH 2/4] Add enhanced error reporting for single-file components
Co-authored-by: grantcopley <1197835+grantcopley@users.noreply.github.com>
---
models/Component.cfc | 133 +++++++++++++++++++++++++-
models/EmptySingleFileComponent.bx | 11 +++
models/EmptySingleFileComponent.cfc | 11 +++
models/SingleFileComponentBuilder.cfc | 24 ++++-
4 files changed, 176 insertions(+), 3 deletions(-)
diff --git a/models/Component.cfc b/models/Component.cfc
index 606bf24..b2a859c 100644
--- a/models/Component.cfc
+++ b/models/Component.cfc
@@ -702,6 +702,14 @@ component output="true" accessors="true" {
params=arguments.params
);
} catch ( any e ) {
+ // Enhance exception for single-file components
+ if ( _isSingleFileComponent() ) {
+ throw(
+ type = "CBWIREException",
+ message = "Failure when calling onMount(). " & _buildEnhancedErrorMessage( e ),
+ detail = e.detail ?: ""
+ );
+ }
throw( type="CBWIREException", message="Failure when calling onMount(). #e.message#" );
}
}
@@ -1102,6 +1110,14 @@ component output="true" accessors="true" {
} catch ( ValidationException e ) {
// silently fail so the component can continue to render
} catch( any e ) {
+ // Enhance exception for single-file components
+ if ( _isSingleFileComponent() ) {
+ throw(
+ type = e.type ?: "CBWIREException",
+ message = _buildEnhancedErrorMessage( e ),
+ detail = e.detail ?: ""
+ );
+ }
rethrow;
}
} );
@@ -1706,8 +1722,20 @@ component output="true" accessors="true" {
// should render based on if onSecure exists and allows rendering. render only if true.
var renderedContent = "";
if( _onSecureShouldRender() ){
- local.trimmedHTML = isNull( arguments.rendering ) ? trim( onRender() ) : trim( arguments.rendering );
- renderedContent = variables._renderService.render( this, local.trimmedHTML );
+ try {
+ local.trimmedHTML = isNull( arguments.rendering ) ? trim( onRender() ) : trim( arguments.rendering );
+ renderedContent = variables._renderService.render( this, local.trimmedHTML );
+ } catch ( any e ) {
+ // Enhance exception for single-file components
+ if ( _isSingleFileComponent() ) {
+ throw(
+ type = e.type ?: "CBWIREException",
+ message = _buildEnhancedErrorMessage( e ),
+ detail = e.detail ?: ""
+ );
+ }
+ rethrow;
+ }
}else{
// fireInterceptor event for blocked render
@@ -1731,6 +1759,107 @@ component output="true" accessors="true" {
return variables._compileTimeKey;
}
+ /**
+ * Returns true if this component was generated from a single-file component.
+ *
+ * @return boolean
+ */
+ function _isSingleFileComponent() {
+ return variables.keyExists( "_singleFileSourcePath" ) && len( variables._singleFileSourcePath );
+ }
+
+ /**
+ * Returns the original source file path for single-file components.
+ * Returns empty string for regular components.
+ *
+ * @return string
+ */
+ function _getSingleFileSourcePath() {
+ return variables.keyExists( "_singleFileSourcePath" ) ? variables._singleFileSourcePath : "";
+ }
+
+ /**
+ * Returns the line offset for mapping generated code back to the original source file.
+ * This is the line number where @startWire begins in the original file.
+ *
+ * @return numeric
+ */
+ function _getSingleFileLineOffset() {
+ return variables.keyExists( "_singleFileLineOffset" ) ? variables._singleFileLineOffset : 0;
+ }
+
+ /**
+ * Enhances an exception with single-file component source information.
+ * This helps developers understand where errors originated in their original source file.
+ *
+ * @exception struct | The caught exception to enhance
+ *
+ * @return struct | Enhanced exception information with source file context
+ */
+ function _enhanceExceptionForSingleFile( required any exception ) {
+ var enhanced = {
+ "originalException": arguments.exception,
+ "isSingleFileComponent": _isSingleFileComponent(),
+ "message": arguments.exception.message ?: "",
+ "detail": arguments.exception.detail ?: "",
+ "type": arguments.exception.type ?: "Application"
+ };
+
+ if ( enhanced.isSingleFileComponent ) {
+ enhanced[ "singleFileSourcePath" ] = _getSingleFileSourcePath();
+ enhanced[ "singleFileLineOffset" ] = _getSingleFileLineOffset();
+ enhanced[ "enhancedMessage" ] = _buildEnhancedErrorMessage( arguments.exception );
+ }
+
+ return enhanced;
+ }
+
+ /**
+ * Builds an enhanced error message that includes single-file component source information.
+ *
+ * @exception struct | The caught exception
+ *
+ * @return string | The enhanced error message
+ */
+ function _buildEnhancedErrorMessage( required any exception ) {
+ var sourcePath = _getSingleFileSourcePath();
+ var lineOffset = _getSingleFileLineOffset();
+ var originalMessage = arguments.exception.message ?: "Unknown error";
+
+ var enhancedMessage = originalMessage;
+ enhancedMessage &= chr(10) & chr(10) & "=== CBWIRE Single-File Component Debug Info ===" & chr(10);
+ enhancedMessage &= "Original source file: " & sourcePath & chr(10);
+
+ if ( lineOffset > 0 ) {
+ enhancedMessage &= "Wire code starts at line: " & lineOffset & " in the original file" & chr(10);
+ enhancedMessage &= "To find the actual error line in your source file, add " & lineOffset & " to any line numbers shown in the generated component stack trace." & chr(10);
+ }
+
+ // Try to extract line number from the exception if available
+ if ( structKeyExists( arguments.exception, "tagContext" ) && isArray( arguments.exception.tagContext ) && arguments.exception.tagContext.len() ) {
+ // Look for the tmp file reference in the stack trace
+ for ( var ctx in arguments.exception.tagContext ) {
+ if ( structKeyExists( ctx, "template" ) && ctx.template contains "cbwire" && ctx.template contains "tmp" ) {
+ var generatedLine = structKeyExists( ctx, "line" ) ? ctx.line : 0;
+ if ( generatedLine > 0 && lineOffset > 0 ) {
+ // The generated component has some header lines, so we need to account for that
+ // The header in EmptySingleFileComponent.cfc has approximately 14 lines before CFC_CONTENTS
+ var headerLines = 14;
+ var estimatedSourceLine = generatedLine - headerLines + lineOffset;
+ if ( estimatedSourceLine > 0 ) {
+ enhancedMessage &= "Estimated source line: ~" & estimatedSourceLine & chr(10);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ enhancedMessage &= "================================================";
+
+ return enhancedMessage;
+ }
+
/**
* Fires an interceptor event.
* Standardizes data passed to interceptors fired from base wire Component.cfc
diff --git a/models/EmptySingleFileComponent.bx b/models/EmptySingleFileComponent.bx
index 676d96a..199c539 100644
--- a/models/EmptySingleFileComponent.bx
+++ b/models/EmptySingleFileComponent.bx
@@ -1,5 +1,16 @@
class extends="{{ EXTENDS_PATH }}" {
+ /**
+ * Path to the original single-file component source for error reporting.
+ */
+ variables._singleFileSourcePath = "{{ SOURCE_PATH }}";
+
+ /**
+ * Line offset for mapping generated code back to original source.
+ * This is the line number in the original file where @startWire begins.
+ */
+ variables._singleFileLineOffset = {{ LINE_OFFSET }};
+
{{ CFC_CONTENTS }}
function onRender() {
diff --git a/models/EmptySingleFileComponent.cfc b/models/EmptySingleFileComponent.cfc
index a6877a6..ac3e592 100644
--- a/models/EmptySingleFileComponent.cfc
+++ b/models/EmptySingleFileComponent.cfc
@@ -1,5 +1,16 @@
component extends="{{ EXTENDS_PATH }}" {
+ /**
+ * Path to the original single-file component source for error reporting.
+ */
+ variables._singleFileSourcePath = "{{ SOURCE_PATH }}";
+
+ /**
+ * Line offset for mapping generated code back to original source.
+ * This is the line number in the original file where @startWire begins.
+ */
+ variables._singleFileLineOffset = {{ LINE_OFFSET }};
+
{{ CFC_CONTENTS }}
function onRender() {
diff --git a/models/SingleFileComponentBuilder.cfc b/models/SingleFileComponentBuilder.cfc
index 799ada3..e7ad815 100644
--- a/models/SingleFileComponentBuilder.cfc
+++ b/models/SingleFileComponentBuilder.cfc
@@ -50,6 +50,8 @@ component accessors="true" singleton {
local.startedWire = false;
local.endedWire = false;
+ local.lineNumber = 0;
+ local.startWireLineNumber = 0;
local.isBoxLang = arguments.cfmPath.listToArray(".").last() == "bxm" ? true : false;
local.insideScriptTag = false;
@@ -57,6 +59,7 @@ component accessors="true" singleton {
local.REEndScriptTag = local.isBoxLang ? "<\s*/\s*bx:script\s*>" : "<\s*/\s*cfscript\s*>";
for ( local.line in local.fileContents.listToArray( chr( 10 ) ) ) {
+ local.lineNumber++;
if ( REFindNoCase( local.REStartScriptTag, local.line ) > 0 ) {
local.insideScriptTag = true;
@@ -80,6 +83,7 @@ component accessors="true" singleton {
if ( local.insideScriptTag && local.line contains "@startWire" ) {
local.startedWire = true;
+ local.startWireLineNumber = local.lineNumber;
continue;
}
if ( local.insideScriptTag && local.line contains "@endWire" ) {
@@ -97,7 +101,8 @@ component accessors="true" singleton {
return {
"singleFileContents" : local.singleFileContents,
"remainingContents" : local.remainingContents,
- "extendsPath" : local.extendsPath
+ "extendsPath" : local.extendsPath,
+ "startWireLineNumber" : local.startWireLineNumber
};
}
@@ -173,6 +178,23 @@ component accessors="true" singleton {
"one"
);
+ // Add source path for error reporting (escape backslashes for Windows paths)
+ local.escapedSourcePath = replace( arguments.sourcePath, "\", "\\", "all" );
+ local.emptySingleFileComponent = replaceNoCase(
+ local.emptySingleFileComponent,
+ "{{ SOURCE_PATH }}",
+ local.escapedSourcePath,
+ "one"
+ );
+
+ // Add line offset for error reporting
+ local.emptySingleFileComponent = replaceNoCase(
+ local.emptySingleFileComponent,
+ "{{ LINE_OFFSET }}",
+ local.parsedContents.startWireLineNumber,
+ "one"
+ );
+
local.uuid = createUUID();
fileWrite( local.tmpClassPath, local.emptySingleFileComponent );
From fdc775f3437768f44478fa0503a8a5d80be7d313 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 25 Nov 2025 06:31:35 +0000
Subject: [PATCH 3/4] Add unit tests for single-file component error reporting
Co-authored-by: grantcopley <1197835+grantcopley@users.noreply.github.com>
---
.../tests/specs/unit/ComponentSpec.cfc | 94 ++++++++++++++++
.../unit/SingleFileComponentBuilderSpec.cfc | 100 ++++++++++++++++++
2 files changed, 194 insertions(+)
create mode 100644 test-harness/tests/specs/unit/SingleFileComponentBuilderSpec.cfc
diff --git a/test-harness/tests/specs/unit/ComponentSpec.cfc b/test-harness/tests/specs/unit/ComponentSpec.cfc
index 4073c2c..6739e1c 100644
--- a/test-harness/tests/specs/unit/ComponentSpec.cfc
+++ b/test-harness/tests/specs/unit/ComponentSpec.cfc
@@ -78,6 +78,100 @@ component extends="coldbox.system.testing.BaseTestCase" {
});
+ describe( "Single-file component error reporting", function() {
+
+ it( "_isSingleFileComponent returns false for regular components", function() {
+ // Regular components don't have _singleFileSourcePath set
+ var result = variables.wireComponent._isSingleFileComponent();
+ expect( result ).toBeFalse();
+ });
+
+ it( "_getSingleFileSourcePath returns empty string for regular components", function() {
+ var result = variables.wireComponent._getSingleFileSourcePath();
+ expect( result ).toBe( "" );
+ });
+
+ it( "_getSingleFileLineOffset returns 0 for regular components", function() {
+ var result = variables.wireComponent._getSingleFileLineOffset();
+ expect( result ).toBe( 0 );
+ });
+
+ it( "_isSingleFileComponent returns true when _singleFileSourcePath is set", function() {
+ // Simulate a single-file component by setting the variables
+ variables.wireComponent.$property( propertyName="_singleFileSourcePath", mock="/path/to/TestComponent.cfm" );
+ var result = variables.wireComponent._isSingleFileComponent();
+ expect( result ).toBeTrue();
+ });
+
+ it( "_getSingleFileSourcePath returns the path when set", function() {
+ var testPath = "/path/to/TestComponent.cfm";
+ variables.wireComponent.$property( propertyName="_singleFileSourcePath", mock=testPath );
+ var result = variables.wireComponent._getSingleFileSourcePath();
+ expect( result ).toBe( testPath );
+ });
+
+ it( "_getSingleFileLineOffset returns the offset when set", function() {
+ variables.wireComponent.$property( propertyName="_singleFileLineOffset", mock=15 );
+ var result = variables.wireComponent._getSingleFileLineOffset();
+ expect( result ).toBe( 15 );
+ });
+
+ it( "_buildEnhancedErrorMessage includes source file path", function() {
+ variables.wireComponent.$property( propertyName="_singleFileSourcePath", mock="/path/to/TestComponent.cfm" );
+ variables.wireComponent.$property( propertyName="_singleFileLineOffset", mock=10 );
+
+ var mockException = {
+ "message": "Test error message",
+ "detail": "Test detail",
+ "type": "TestException"
+ };
+
+ var result = variables.wireComponent._buildEnhancedErrorMessage( mockException );
+
+ expect( result ).toInclude( "Test error message" );
+ expect( result ).toInclude( "/path/to/TestComponent.cfm" );
+ expect( result ).toInclude( "CBWIRE Single-File Component Debug Info" );
+ expect( result ).toInclude( "Wire code starts at line: 10" );
+ });
+
+ it( "_enhanceExceptionForSingleFile returns enhanced struct for single-file components", function() {
+ variables.wireComponent.$property( propertyName="_singleFileSourcePath", mock="/path/to/TestComponent.cfm" );
+ variables.wireComponent.$property( propertyName="_singleFileLineOffset", mock=10 );
+
+ var mockException = {
+ "message": "Test error message",
+ "detail": "Test detail",
+ "type": "TestException"
+ };
+
+ var result = variables.wireComponent._enhanceExceptionForSingleFile( mockException );
+
+ expect( result ).toHaveKey( "isSingleFileComponent" );
+ expect( result.isSingleFileComponent ).toBeTrue();
+ expect( result ).toHaveKey( "singleFileSourcePath" );
+ expect( result.singleFileSourcePath ).toBe( "/path/to/TestComponent.cfm" );
+ expect( result ).toHaveKey( "singleFileLineOffset" );
+ expect( result.singleFileLineOffset ).toBe( 10 );
+ expect( result ).toHaveKey( "enhancedMessage" );
+ });
+
+ it( "_enhanceExceptionForSingleFile returns basic struct for regular components", function() {
+ var mockException = {
+ "message": "Test error message",
+ "detail": "Test detail",
+ "type": "TestException"
+ };
+
+ var result = variables.wireComponent._enhanceExceptionForSingleFile( mockException );
+
+ expect( result ).toHaveKey( "isSingleFileComponent" );
+ expect( result.isSingleFileComponent ).toBeFalse();
+ expect( result ).notToHaveKey( "singleFileSourcePath" );
+ expect( result ).notToHaveKey( "enhancedMessage" );
+ });
+
+ });
+
});
}
diff --git a/test-harness/tests/specs/unit/SingleFileComponentBuilderSpec.cfc b/test-harness/tests/specs/unit/SingleFileComponentBuilderSpec.cfc
new file mode 100644
index 0000000..c70d45f
--- /dev/null
+++ b/test-harness/tests/specs/unit/SingleFileComponentBuilderSpec.cfc
@@ -0,0 +1,100 @@
+component extends="coldbox.system.testing.BaseTestCase" {
+
+ function beforeAll() {
+ // Create the service instance
+ variables.builder = new cbwire.models.SingleFileComponentBuilder();
+ }
+
+ function run() {
+ describe( "SingleFileComponentBuilder", function() {
+
+ describe( "parseContents()", function() {
+
+ it( "should track the line number where @startWire begins", function() {
+ // Create a temp file with known content
+ var testContent = "" & chr( 10 ) &
+ "// some comment" & chr( 10 ) &
+ "// @startWire" & chr( 10 ) &
+ " data = { 'name': 'test' };" & chr( 10 ) &
+ "// @endWire" & chr( 10 ) &
+ "" & chr( 10 ) &
+ "test
";
+
+ var tempFile = getTempDirectory() & "testWire_" & createUUID() & ".cfm";
+ fileWrite( tempFile, testContent );
+
+ try {
+ var result = variables.builder.parseContents( tempFile );
+
+ // @startWire is on line 3
+ expect( result.startWireLineNumber ).toBe( 3 );
+ expect( result ).toHaveKey( "singleFileContents" );
+ expect( result ).toHaveKey( "remainingContents" );
+ expect( result ).toHaveKey( "extendsPath" );
+ } finally {
+ // Clean up temp file
+ if ( fileExists( tempFile ) ) {
+ fileDelete( tempFile );
+ }
+ }
+ });
+
+ it( "should return 0 for startWireLineNumber when @startWire is not found", function() {
+ // Create a temp file without @startWire
+ var testContent = "" & chr( 10 ) &
+ "// some comment" & chr( 10 ) &
+ "" & chr( 10 ) &
+ "test
";
+
+ var tempFile = getTempDirectory() & "testWireNoAnnotation_" & createUUID() & ".cfm";
+ fileWrite( tempFile, testContent );
+
+ try {
+ var result = variables.builder.parseContents( tempFile );
+
+ expect( result.startWireLineNumber ).toBe( 0 );
+ } finally {
+ // Clean up temp file
+ if ( fileExists( tempFile ) ) {
+ fileDelete( tempFile );
+ }
+ }
+ });
+
+ it( "should correctly parse the wire contents between @startWire and @endWire", function() {
+ // Create a temp file with known content
+ var testContent = "" & chr( 10 ) &
+ "// @startWire" & chr( 10 ) &
+ " data = { 'counter': 0 };" & chr( 10 ) &
+ " function increment() { data.counter++; }" & chr( 10 ) &
+ "// @endWire" & chr( 10 ) &
+ "" & chr( 10 ) &
+ "test
";
+
+ var tempFile = getTempDirectory() & "testWireContents_" & createUUID() & ".cfm";
+ fileWrite( tempFile, testContent );
+
+ try {
+ var result = variables.builder.parseContents( tempFile );
+
+ // Wire contents should include the data and function definitions
+ expect( result.singleFileContents ).toInclude( "data = { 'counter': 0 }" );
+ expect( result.singleFileContents ).toInclude( "function increment()" );
+
+ // Remaining contents should include the template part
+ expect( result.remainingContents ).toInclude( "" );
+ expect( result.remainingContents ).toInclude( "test
" );
+ } finally {
+ // Clean up temp file
+ if ( fileExists( tempFile ) ) {
+ fileDelete( tempFile );
+ }
+ }
+ });
+
+ });
+
+ });
+ }
+
+}
From f17a160c418a96f55491813cd78a7b61941e9e40 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 25 Nov 2025 06:33:45 +0000
Subject: [PATCH 4/4] Address code review feedback: fix docblocks, improve line
number estimation
Co-authored-by: grantcopley <1197835+grantcopley@users.noreply.github.com>
---
models/Component.cfc | 24 +++--
.../unit/SingleFileComponentBuilderSpec.cfc | 101 +++++++++---------
2 files changed, 64 insertions(+), 61 deletions(-)
diff --git a/models/Component.cfc b/models/Component.cfc
index b2a859c..2aeae85 100644
--- a/models/Component.cfc
+++ b/models/Component.cfc
@@ -1792,9 +1792,9 @@ component output="true" accessors="true" {
* Enhances an exception with single-file component source information.
* This helps developers understand where errors originated in their original source file.
*
- * @exception struct | The caught exception to enhance
+ * @exception any The caught exception to enhance
*
- * @return struct | Enhanced exception information with source file context
+ * @return struct Enhanced exception information with source file context
*/
function _enhanceExceptionForSingleFile( required any exception ) {
var enhanced = {
@@ -1817,9 +1817,9 @@ component output="true" accessors="true" {
/**
* Builds an enhanced error message that includes single-file component source information.
*
- * @exception struct | The caught exception
+ * @exception any The caught exception
*
- * @return string | The enhanced error message
+ * @return string The enhanced error message
*/
function _buildEnhancedErrorMessage( required any exception ) {
var sourcePath = _getSingleFileSourcePath();
@@ -1842,11 +1842,17 @@ component output="true" accessors="true" {
if ( structKeyExists( ctx, "template" ) && ctx.template contains "cbwire" && ctx.template contains "tmp" ) {
var generatedLine = structKeyExists( ctx, "line" ) ? ctx.line : 0;
if ( generatedLine > 0 && lineOffset > 0 ) {
- // The generated component has some header lines, so we need to account for that
- // The header in EmptySingleFileComponent.cfc has approximately 14 lines before CFC_CONTENTS
- var headerLines = 14;
- var estimatedSourceLine = generatedLine - headerLines + lineOffset;
- if ( estimatedSourceLine > 0 ) {
+ /*
+ * The generated component file (EmptySingleFileComponent.cfc/.bx) has header lines
+ * before the {{ CFC_CONTENTS }} placeholder where user code is inserted.
+ * This includes: component declaration, variable definitions for source path and
+ * line offset, comments, and blank lines. Currently this is approximately 14 lines.
+ * See models/EmptySingleFileComponent.cfc for the template structure.
+ */
+ var generatedTemplateHeaderLines = 14;
+ var estimatedSourceLine = generatedLine - generatedTemplateHeaderLines + lineOffset;
+ // Only show the estimated line if it's a positive, reasonable value
+ if ( estimatedSourceLine > 0 && estimatedSourceLine <= 10000 ) {
enhancedMessage &= "Estimated source line: ~" & estimatedSourceLine & chr(10);
}
}
diff --git a/test-harness/tests/specs/unit/SingleFileComponentBuilderSpec.cfc b/test-harness/tests/specs/unit/SingleFileComponentBuilderSpec.cfc
index c70d45f..3bf65fd 100644
--- a/test-harness/tests/specs/unit/SingleFileComponentBuilderSpec.cfc
+++ b/test-harness/tests/specs/unit/SingleFileComponentBuilderSpec.cfc
@@ -3,6 +3,33 @@ component extends="coldbox.system.testing.BaseTestCase" {
function beforeAll() {
// Create the service instance
variables.builder = new cbwire.models.SingleFileComponentBuilder();
+ // Track temp files for cleanup
+ variables.tempFiles = [];
+ }
+
+ function afterAll() {
+ // Clean up any remaining temp files
+ for ( var tempFile in variables.tempFiles ) {
+ if ( fileExists( tempFile ) ) {
+ fileDelete( tempFile );
+ }
+ }
+ }
+
+ /**
+ * Helper method to create a temp file with the given content.
+ * The file is automatically tracked for cleanup.
+ *
+ * @content string The content to write to the file
+ * @extension string The file extension (default: .cfm)
+ *
+ * @return string The path to the created temp file
+ */
+ private function createTempFile( required string content, string extension = ".cfm" ) {
+ var tempFile = getTempDirectory() & "testWire_" & createUUID() & arguments.extension;
+ fileWrite( tempFile, arguments.content );
+ variables.tempFiles.append( tempFile );
+ return tempFile;
}
function run() {
@@ -11,7 +38,6 @@ component extends="coldbox.system.testing.BaseTestCase" {
describe( "parseContents()", function() {
it( "should track the line number where @startWire begins", function() {
- // Create a temp file with known content
var testContent = "" & chr( 10 ) &
"// some comment" & chr( 10 ) &
"// @startWire" & chr( 10 ) &
@@ -20,49 +46,29 @@ component extends="coldbox.system.testing.BaseTestCase" {
"" & chr( 10 ) &
"test
";
- var tempFile = getTempDirectory() & "testWire_" & createUUID() & ".cfm";
- fileWrite( tempFile, testContent );
-
- try {
- var result = variables.builder.parseContents( tempFile );
-
- // @startWire is on line 3
- expect( result.startWireLineNumber ).toBe( 3 );
- expect( result ).toHaveKey( "singleFileContents" );
- expect( result ).toHaveKey( "remainingContents" );
- expect( result ).toHaveKey( "extendsPath" );
- } finally {
- // Clean up temp file
- if ( fileExists( tempFile ) ) {
- fileDelete( tempFile );
- }
- }
+ var tempFile = createTempFile( testContent );
+ var result = variables.builder.parseContents( tempFile );
+
+ // @startWire is on line 3
+ expect( result.startWireLineNumber ).toBe( 3 );
+ expect( result ).toHaveKey( "singleFileContents" );
+ expect( result ).toHaveKey( "remainingContents" );
+ expect( result ).toHaveKey( "extendsPath" );
});
it( "should return 0 for startWireLineNumber when @startWire is not found", function() {
- // Create a temp file without @startWire
var testContent = "" & chr( 10 ) &
"// some comment" & chr( 10 ) &
"" & chr( 10 ) &
"test
";
- var tempFile = getTempDirectory() & "testWireNoAnnotation_" & createUUID() & ".cfm";
- fileWrite( tempFile, testContent );
-
- try {
- var result = variables.builder.parseContents( tempFile );
-
- expect( result.startWireLineNumber ).toBe( 0 );
- } finally {
- // Clean up temp file
- if ( fileExists( tempFile ) ) {
- fileDelete( tempFile );
- }
- }
+ var tempFile = createTempFile( testContent );
+ var result = variables.builder.parseContents( tempFile );
+
+ expect( result.startWireLineNumber ).toBe( 0 );
});
it( "should correctly parse the wire contents between @startWire and @endWire", function() {
- // Create a temp file with known content
var testContent = "" & chr( 10 ) &
"// @startWire" & chr( 10 ) &
" data = { 'counter': 0 };" & chr( 10 ) &
@@ -71,25 +77,16 @@ component extends="coldbox.system.testing.BaseTestCase" {
"" & chr( 10 ) &
"test
";
- var tempFile = getTempDirectory() & "testWireContents_" & createUUID() & ".cfm";
- fileWrite( tempFile, testContent );
-
- try {
- var result = variables.builder.parseContents( tempFile );
-
- // Wire contents should include the data and function definitions
- expect( result.singleFileContents ).toInclude( "data = { 'counter': 0 }" );
- expect( result.singleFileContents ).toInclude( "function increment()" );
-
- // Remaining contents should include the template part
- expect( result.remainingContents ).toInclude( "" );
- expect( result.remainingContents ).toInclude( "test
" );
- } finally {
- // Clean up temp file
- if ( fileExists( tempFile ) ) {
- fileDelete( tempFile );
- }
- }
+ var tempFile = createTempFile( testContent );
+ var result = variables.builder.parseContents( tempFile );
+
+ // Wire contents should include the data and function definitions
+ expect( result.singleFileContents ).toInclude( "data = { 'counter': 0 }" );
+ expect( result.singleFileContents ).toInclude( "function increment()" );
+
+ // Remaining contents should include the template part
+ expect( result.remainingContents ).toInclude( "" );
+ expect( result.remainingContents ).toInclude( "test
" );
});
});