diff --git a/TcUnit/TcUnit/POUs/FB_XmlControl.TcPOU b/TcUnit/TcUnit/POUs/FB_XmlControl.TcPOU index 28c59e4..ad3ce96 100644 --- a/TcUnit/TcUnit/POUs/FB_XmlControl.TcPOU +++ b/TcUnit/TcUnit/POUs/FB_XmlControl.TcPOU @@ -7,7 +7,7 @@ *) FUNCTION_BLOCK FB_XmlControl VAR - XmlBuffer : FB_StreamBuffer; + XmlFileStream : REFERENCE TO FB_XmlFileStream; TagListBuffer : FB_StreamBuffer; Tags : T_MaxString; TagListSeekBuffer : FB_StreamBuffer; @@ -15,6 +15,7 @@ VAR TagBuffer : FB_StreamBuffer; Tag : T_MaxString; TagOpen: BOOL; + TagOpenCount : INT; Select : UDINT; SearchPosition : UDINT; END_VAR @@ -32,6 +33,10 @@ VAR CONSTANT TAB : STRING(2) := '$T'; CR_LF : STRING(4) := '$R$N'; + CR_AS_BYTE : BYTE := 13; + LF_AS_BYTE : BYTE := 10; + SPACE_AS_BYTE : BYTE := 32; + // $OD : ASCII code for carriage return (CR) // $$ : to add a $R // $' : to add ' (apostrophe) @@ -43,13 +48,34 @@ END_VAR]]> + + + + + + @@ -66,28 +92,50 @@ VAR ClosedTag : T_MaxString; END_VAR]]> - + + + + + + - + @@ -104,12 +152,12 @@ VAR_INPUT END_VAR]]> +XmlFileStream.Append := OPEN_COMMENT; +XmlFileStream.Append := Comment; +XmlFileStream.Append := CLOSE_COMMENT;]]> @@ -124,12 +172,12 @@ VAR_INPUT Value : T_MaxString; END_VAR]]> - + @@ -145,10 +193,14 @@ VAR_INPUT END_VAR]]> @@ -160,24 +212,11 @@ VAR_INPUT Data : T_MaxString; END_VAR]]> - - - - - - - - + diff --git a/TcUnit/TcUnit/POUs/FB_XmlFileStream.TcPOU b/TcUnit/TcUnit/POUs/FB_XmlFileStream.TcPOU new file mode 100644 index 0000000..9556dca --- /dev/null +++ b/TcUnit/TcUnit/POUs/FB_XmlFileStream.TcPOU @@ -0,0 +1,102 @@ + + + + + + + + + + + + + 0 AND _Length < _BufferSize DO + ByteBuffer^ := ByteIn^; //Copy the 1st byte + _Length := _Length + 1; // set new buffer length + ByteIn := ByteIn + 1; // calculate new start address + ByteBuffer := ByteBuffer + 1; // calculate new start address + END_WHILE; + + IF ByteIn^ <> 0 + THEN + Flush(); + Clear(); + ByteBuffer := _PointerToStringBuffer; + END_IF + +UNTIL ByteIn^ = 0 END_REPEAT + +ByteBuffer := _PointerToStringBuffer + _Length; // String End +ByteBuffer^ := 0; // null terminated string]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TcUnit/TcUnit/POUs/FB_xUnitXmlPublisher.TcPOU b/TcUnit/TcUnit/POUs/FB_xUnitXmlPublisher.TcPOU index 741e7ee..d3855f6 100644 --- a/TcUnit/TcUnit/POUs/FB_xUnitXmlPublisher.TcPOU +++ b/TcUnit/TcUnit/POUs/FB_xUnitXmlPublisher.TcPOU @@ -5,39 +5,17 @@ FUNCTION_BLOCK FB_xUnitXmlPublisher IMPLEMENTS I_TestResultLogger VAR // Dependency injection via FB_Init - TestResults : I_TestResults; + _testResults : I_TestResults; - // File access mode - AccessMode : SysFile.ACCESS_MODE := SysFile.AM_WRITE_PLUS; + _xmlFileStream : FB_XmlFileStream; + _xml : FB_XMLControl(_xmlFileStream); - File : FB_FileControl; - Xml : FB_XMLControl; - BufferInitialised : BOOL := FALSE; - Buffer : ARRAY [0..(GVL_Param_TcUnit.XUnitBufferSize - 1)] OF BYTE; - WritingTestSuiteResultNumber : UINT(1..GVL_Param_TcUnit.MaxNumberOfTestSuites); - PublishTrigger : R_TRIG; + _writingTestSuiteResultNumber : UINT(1..GVL_Param_TcUnit.MaxNumberOfTestSuites); + _publishTrigger : R_TRIG; END_VAR]]> - - - - - - - - - - - - - + @@ -87,44 +53,46 @@ VAR CONSTANT TEST_STATUS_FAIL : STRING := 'FAIL'; END_VAR]]> - - Xml.WriteDocumentHeader(Header := ''); + _xml.WriteDocumentHeader(Header := ''); // - Xml.NewTag('testsuites'); - Xml.NewParameter('disabled', ''); - Xml.NewParameter('failures', UINT_TO_STRING(UnitTestResults.NumberOfFailedTestCases)); - Xml.NewParameter('tests', UINT_TO_STRING(UnitTestResults.NumberOfSuccessfulTestCases)); - Xml.NewParameter('time', LREAL_TO_STRING(UnitTestResults.Duration)); + _xml.NewTag('testsuites'); + _xml.NewParameter('disabled', ''); + _xml.NewParameter('failures', UINT_TO_STRING(UnitTestResults.NumberOfFailedTestCases)); + _xml.NewParameter('tests', UINT_TO_STRING(UnitTestResults.NumberOfSuccessfulTestCases)); + _xml.NewParameter('time', LREAL_TO_STRING(UnitTestResults.Duration)); FOR CurrentSuiteNumber := 1 TO UnitTestResults.NumberOfTestSuites BY 1 DO // - Xml.NewTag('testsuite'); - Xml.NewParameter('id', UINT_TO_STRING(UnitTestResults.TestSuiteResults[CurrentSuiteNumber].Identity)); - Xml.NewParameter('name', UnitTestResults.TestSuiteResults[CurrentSuiteNumber].name); - Xml.NewParameter('tests', UINT_TO_STRING(UnitTestResults.TestSuiteResults[CurrentSuiteNumber].NumberOfTests)); - Xml.NewParameter('failures', UINT_TO_STRING(UnitTestResults.TestSuiteResults[CurrentSuiteNumber].NumberOfFailedTests)); - Xml.NewParameter('time', LREAL_TO_STRING(UnitTestResults.TestSuiteResults[CurrentSuiteNumber].Duration)); + _xml.NewTag('testsuite'); + _xml.NewParameter('id', UINT_TO_STRING(UnitTestResults.TestSuiteResults[CurrentSuiteNumber].Identity)); + _xml.NewParameter('name', UnitTestResults.TestSuiteResults[CurrentSuiteNumber].name); + _xml.NewParameter('tests', UINT_TO_STRING(UnitTestResults.TestSuiteResults[CurrentSuiteNumber].NumberOfTests)); + _xml.NewParameter('failures', UINT_TO_STRING(UnitTestResults.TestSuiteResults[CurrentSuiteNumber].NumberOfFailedTests)); + _xml.NewParameter('time', LREAL_TO_STRING(UnitTestResults.TestSuiteResults[CurrentSuiteNumber].Duration)); FOR CurrentTestCount := 1 TO UnitTestResults.TestSuiteResults[CurrentSuiteNumber].NumberOfTests BY 1 DO // - Xml.NewTag('testcase'); - Xml.NewParameter('name', UnitTestResults.TestSuiteResults[CurrentSuiteNumber].TestCaseResults[CurrentTestCount].TestName); - Xml.NewParameter('classname', UnitTestResults.TestSuiteResults[CurrentSuiteNumber].TestCaseResults[CurrentTestCount].TestClassName); - Xml.NewParameter('time', LREAL_TO_STRING(UnitTestResults.TestSuiteResults[CurrentSuiteNumber].TestCaseResults[CurrentTestCount].Duration)); + _xml.NewTag('testcase'); + _xml.NewParameter('name', UnitTestResults.TestSuiteResults[CurrentSuiteNumber].TestCaseResults[CurrentTestCount].TestName); + _xml.NewParameter('classname', UnitTestResults.TestSuiteResults[CurrentSuiteNumber].TestCaseResults[CurrentTestCount].TestClassName); + _xml.NewParameter('time', LREAL_TO_STRING(UnitTestResults.TestSuiteResults[CurrentSuiteNumber].TestCaseResults[CurrentTestCount].Duration)); IF UnitTestResults.TestSuiteResults[CurrentSuiteNumber].TestCaseResults[CurrentTestCount].TestIsFailed THEN - Xml.NewParameter('status', TEST_STATUS_FAIL); + _xml.NewParameter('status', TEST_STATUS_FAIL); ELSIF UnitTestResults.TestSuiteResults[CurrentSuiteNumber].TestCaseResults[CurrentTestCount].TestIsSkipped THEN - Xml.NewParameter('status', TEST_STATUS_SKIP); + _xml.NewParameter('status', TEST_STATUS_SKIP); ELSE - Xml.NewParameter('status', TEST_STATUS_PASS); + _xml.NewParameter('status', TEST_STATUS_PASS); END_IF // Determine testcase fail or success @@ -132,32 +100,29 @@ IF PublishTrigger.Q THEN (* In case of fail *) - Xml.NewTag('failure'); - Xml.NewParameter('message', UnitTestResults.TestSuiteResults[CurrentSuiteNumber].TestCaseResults[CurrentTestCount].FailureMessage); - Xml.NewParameter('type', F_AssertionTypeToString(UnitTestResults.TestSuiteResults[CurrentSuiteNumber].TestCaseResults[CurrentTestCount].FailureType)); + _xml.NewTag('failure'); + _xml.NewParameter('message', UnitTestResults.TestSuiteResults[CurrentSuiteNumber].TestCaseResults[CurrentTestCount].FailureMessage); + _xml.NewParameter('type', F_AssertionTypeToString(UnitTestResults.TestSuiteResults[CurrentSuiteNumber].TestCaseResults[CurrentTestCount].FailureType)); // Close failure tag - Xml.CloseTag(); - ELSE - // In case of success - Xml.NewTagData(''); - + _xml.CloseTag(); END_IF + // Close testcase tag - Xml.CloseTag(); + _xml.CloseTag(); END_FOR // Close testsuite tag - Xml.CloseTag(); + _xml.CloseTag(); END_FOR // Close testsuites - Xml.CloseTag(); + _xml.CloseTag(); // Delete, open, save and close the file - DeleteOpenWriteClose(); + _xmlFileStream.CloseFile(); // Clear the internal buffer - Xml.ClearBuffer(); + _xml.ClearBuffer(); // Inform user GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_HINT, @@ -175,4 +140,4 @@ END_IF]]> - \ No newline at end of file + diff --git a/TcUnit/TcUnit/TcUnit.plcproj b/TcUnit/TcUnit/TcUnit.plcproj index 89fb59a..bc61395 100644 --- a/TcUnit/TcUnit/TcUnit.plcproj +++ b/TcUnit/TcUnit/TcUnit.plcproj @@ -113,6 +113,9 @@ Documentation and examples are available at www.tcunit.org Code + + Code + Code