Skip to content

Commit

Permalink
- Added config options and argument option -e, --error-log, for error…
Browse files Browse the repository at this point in the history
… log path and name

- Added mock errors to testsuite error log
- At the end of the testsuites an exception will be thrown, if any errors were found
- Fixed bug, where an 88 reverse compare, would show one value not being reversed.
- Minor refactoring

Signed-off-by: dakaa16 <davidkaan@gmail.com>
  • Loading branch information
dakaa16 committed May 2, 2022
1 parent 8810d93 commit c99db5e
Show file tree
Hide file tree
Showing 22 changed files with 580 additions and 211 deletions.
62 changes: 31 additions & 31 deletions CC##99.CBL

Large diffs are not rendered by default.

14 changes: 13 additions & 1 deletion config.properties
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ cobolcheck.test.program.path = ./
#---------------------------------------------------------------------------------------------------------------------
cobolcheck.test.program.name = CC##99.CBL

#---------------------------------------------------------------------------------------------------------------------
# Path for the generated testsuite parse error log
# Default: ./
#---------------------------------------------------------------------------------------------------------------------
testsuite.parser.error.log.path = ./

#---------------------------------------------------------------------------------------------------------------------
# Name of the generated testsuite parse error log file - with extension
# Default: ParserErrorLog.txt
#---------------------------------------------------------------------------------------------------------------------
testsuite.parser.error.log.name = ParserErrorLog.txt

#---------------------------------------------------------------------------------------------------------------------
# The charset that cobolcheck will use when reading- and writing to files.
# See https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html, for a list of
Expand Down Expand Up @@ -133,7 +145,7 @@ application.copybook.filename.suffix = CBL,cbl,COB,cob
# This is the relative or absolute path of the concatenated file. If not specified, the default
# is "./ALLTESTS" relative to the directory in which Cobol Check was started.
#---------------------------------------------------------------------------------------------------------------------
concatenated.test.suites = C:/Udvikler/Workspace/cobol-check-main/ALLTESTS
concatenated.test.suites = ./ALLTESTS

#---------------------------------------------------------------------------------------------------------------------
# Shell scripts and JCL files for executing your test suites.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.openmainframeproject.cobolcheck.exceptions;

public class TestSuiteSyntaxException extends RuntimeException {
public TestSuiteSyntaxException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.openmainframeproject.cobolcheck.exceptions;

public class VerifyReferencesNonexistentMockException extends RuntimeException {
public class VerifyReferencesNonexistentMockException extends TestSuiteSyntaxException {
public VerifyReferencesNonexistentMockException(String message) {
super(message);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void loadSettingsFromArguments() {
Config.setConcatenatedTestSuitesPath(newPath);
}
if (isKeySet("error-log")){
//To be implemented
Config.setTestSuiteParserErrorLogFileName(getKeyValue("error-log"));
}
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ public class Keywords {
Constants.FIELDNAME_KEYWORD,
Constants.BY_REFERENCE_TOKEN,
Constants.BY_CONTENT_TOKEN,
Constants.BY_VALUE_TOKEN),
Constants.BY_VALUE_TOKEN,
Constants.PARENTHESIS_ENCLOSED_KEYWORD),
KeywordAction.FIELDNAME));
keywordInfo.put(Constants.NOT_KEYWORD,
new Keyword(Constants.NOT_KEYWORD,
Expand Down Expand Up @@ -151,7 +152,8 @@ public class Keywords {
Constants.GREATER_THAN_SIGN_KEYWORD,
Constants.LESS_THAN_SIGN_KEYWORD,
Constants.GREATER_THAN_EQUAL_TO_SIGN_KEYWORD,
Constants.LESS_THAN_EQUAL_TO_SIGN_KEYWORD),
Constants.LESS_THAN_EQUAL_TO_SIGN_KEYWORD,
Constants.COBOL_TOKEN),
KeywordAction.COBOL_STATEMENT));
keywordInfo.put(Constants.ALPHANUMERIC_LITERAL_KEYWORD,
new Keyword(Constants.ALPHANUMERIC_LITERAL_KEYWORD,
Expand Down Expand Up @@ -191,7 +193,8 @@ public class Keywords {
Constants.TESTSUITE_KEYWORD,
Constants.TESTCASE_KEYWORD,
Constants.MOCK_KEYWORD,
Constants.VERIFY_KEYWORD),
Constants.VERIFY_KEYWORD,
Constants.PARENTHESIS_ENCLOSED_KEYWORD),
KeywordAction.COBOL_STATEMENT));
keywordInfo.put(Constants.BOOLEAN_VALUE,
new Keyword(Constants.BOOLEAN_VALUE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public class Mock {
private int testCaseNumber;
private int mockNumber;

private String testSuiteFileName;
private int declarationLineNumberInOriginalFile;
private int declarationIndexNumberInOriginalFile;

public Mock(String testSuiteName, String testCaseName, int testSuiteNumber, int testCaseNumber, int mockNumber) {
this.testSuiteName = testSuiteName;
this.testCaseName = testCaseName;
Expand Down Expand Up @@ -129,6 +133,30 @@ public void addLines(List<String> lines) {

public void addArgument(String argument) {arguments.add(argument);}

public String getTestSuiteFileName() {
return testSuiteFileName;
}

public void setTestSuiteFileName(String testSuiteFileName) {
this.testSuiteFileName = testSuiteFileName;
}

public int getDeclarationLineNumberInOriginalFile() {
return declarationLineNumberInOriginalFile;
}

public void setDeclarationLineNumberInOriginalFile(int declarationLineNumberInOriginalFile) {
this.declarationLineNumberInOriginalFile = declarationLineNumberInOriginalFile;
}

public int getDeclarationIndexNumberInOriginalFile() {
return declarationIndexNumberInOriginalFile;
}

public void setDeclarationIndexNumberInOriginalFile(int declarationIndexNumberInOriginalFile) {
this.declarationIndexNumberInOriginalFile = declarationIndexNumberInOriginalFile;
}

private String getArgumentText(){
String combinedArgs = "";
for (String arg : arguments){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ public class MockRepository {
private List<Mock> mocks = new ArrayList<>();

public void addMock(Mock mock){

if (mockAlreadyExist(mock)){
throw new ComponentMockedTwiceInSameScopeException("Mock for " + mock.getIdentifier() + " in " +
"testsuite: " + mock.getTestSuiteName() + ", testcase: " +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package org.openmainframeproject.cobolcheck.features.testSuiteParser;

import org.openmainframeproject.cobolcheck.services.Config;
import org.openmainframeproject.cobolcheck.services.Constants;
import org.openmainframeproject.cobolcheck.services.Messages;
import org.openmainframeproject.cobolcheck.services.cobolLogic.TokenExtractor;
import org.openmainframeproject.cobolcheck.services.filehelpers.EncodingIO;
import org.openmainframeproject.cobolcheck.services.filehelpers.FilePermission;
import org.openmainframeproject.cobolcheck.services.log.Log;

import java.io.*;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

public class TestSuiteErrorLog {



public enum ErrorTypes {SYNTAX_ERROR, RUNTIME_ERROR, WARNING}
private Keyword lastKeyword;
private String fileMessage = "%1s in file: %2s";
private String lineIndexMessage = "Unexpected token on line %1s, index %2s:";

private String followingExpectedGotMessage = "Following <%1s>" + Constants.NEWLINE +
"Expected %2s" + Constants.NEWLINE + "Got <%3s>";
private String keywordInBlock = "Cannot have Cobol Check keyword <%1s> inside a %2s block";

private boolean errorOccured = false;

private final List<String> cobolCheckStartingAndEndingKeywords = Arrays.asList(Constants.TESTSUITE_KEYWORD,
Constants.TESTCASE_KEYWORD, Constants.EXPECT_KEYWORD, Constants.MOCK_KEYWORD, Constants.ENDMOCK_KEYWORD,
Constants.VERIFY_KEYWORD, Constants.BEFORE_EACH_TOKEN, Constants.END_BEFORE_TOKEN, Constants.AFTER_EACH_TOKEN,
Constants.END_AFTER_TOKEN);

private String errorLogPath;

private String lastErrorLogMessage;

public TestSuiteErrorLog(){
errorLogPath = getTestSuiteParserErrorLogPath();
initializeTestSuiteErrorLogWriter(errorLogPath);
}

public boolean hasErrorOccured() {
return errorOccured;
}

public String getLastErrorMessage(){ return lastErrorLogMessage; }

public void checkExpectedTokenSyntax(Keyword currentKeyword, String currentFile, int lineNumber, int lineIndex){
if (lastKeyword != null){
String error = "";
if (!lastKeyword.getvalidNextKeys().contains(currentKeyword.value())){
errorOccured = true;
error += String.format(fileMessage, displayErrorType(ErrorTypes.SYNTAX_ERROR), currentFile) + Constants.NEWLINE;
error += String.format(lineIndexMessage, lineNumber, lineIndex) + Constants.NEWLINE;
error += String.format(followingExpectedGotMessage, lastKeyword.value(),
Arrays.toString(lastKeyword.getvalidNextKeys().toArray()), currentKeyword.value()) +
Constants.NEWLINE + Constants.NEWLINE;
outputError(error);
}
}
lastKeyword = currentKeyword;
}

public void checkSyntaxInsideBlock(String blockKeyword, List<String> cobolLines, TokenExtractor tokenExtractor, String currentFile, int lineNumber) {
int revertedCount = cobolLines.size();
for (String line : cobolLines){
List<String> keywords = tokenExtractor.extractTokensFrom(line);
for(String keyword : keywords){
if (cobolCheckStartingAndEndingKeywords.contains(keyword.toUpperCase(Locale.ROOT))){
errorOccured = true;
String error = "";
int index = line.indexOf(keyword) + 1;
error += String.format(fileMessage, displayErrorType(ErrorTypes.SYNTAX_ERROR), currentFile) + Constants.NEWLINE;
error += String.format(lineIndexMessage, lineNumber - revertedCount, index) + Constants.NEWLINE;
error += String.format(keywordInBlock, keyword, blockKeyword) + Constants.NEWLINE + Constants.NEWLINE;
outputError(error);
}
}
revertedCount -=1;
}
}

public void logIdenticalMocks(Mock mock){
String error = "";
errorOccured = true;
error += String.format(fileMessage, displayErrorType(ErrorTypes.RUNTIME_ERROR), mock.getTestSuiteFileName()) + Constants.NEWLINE;
error += String.format(lineIndexMessage, mock.getDeclarationLineNumberInOriginalFile(),
mock.getDeclarationIndexNumberInOriginalFile()) + Constants.NEWLINE;
String message = "Mock <" + mock.getIdentifier() + "> already exists " +
(mock.getArguments().isEmpty() ? "" : "with the given arguments ") + "in this " +
mock.getScope().name() + ((mock.getScope() == MockScope.Local) ? " testcase " : " testsuite ") +
"scope";
error += message + Constants.NEWLINE + Constants.NEWLINE;
outputError(error);
}

public void logVerifyReferencesNonExistentMock(VerifyMockCount verify) {
String error = "";
errorOccured = true;
error += String.format(fileMessage, displayErrorType(ErrorTypes.RUNTIME_ERROR), verify.getTestSuiteFileName()) + Constants.NEWLINE;
error += String.format(lineIndexMessage, verify.getDeclarationLineNumberInOriginalFile(),
verify.getDeclarationIndexNumberInOriginalFile()) + Constants.NEWLINE;
String message = "Verify references non existent mock. Mock does not exist for: " + verify.getType() + " " + verify.getIdentifier() +
((verify.getArguments().isEmpty()) ? " with no arguments" : " with the given arguments");
error += message + Constants.NEWLINE + Constants.NEWLINE;
outputError(error);
}

public void logUnusedMocks(List<Mock> mocks){
for (Mock mock : mocks){
if (!mock.isUsed()){
String error = "";
error += String.format(fileMessage, displayErrorType(ErrorTypes.WARNING), mock.getTestSuiteFileName()) + Constants.NEWLINE;
error += String.format(lineIndexMessage, mock.getDeclarationLineNumberInOriginalFile(),
mock.getDeclarationIndexNumberInOriginalFile()) + Constants.NEWLINE;
error += "Mock <" + mock.getType() + "> <" + mock.getIdentifier() + "> does not reference " +
"any construct in the source code" + Constants.NEWLINE + Constants.NEWLINE;
outputError(error);
}
}
}

private void outputError(String error) {
lastErrorLogMessage = error;
System.out.println(error);
BufferedWriter errorLogWriter = null;
try {
errorLogWriter = (BufferedWriter) EncodingIO.getWriterWithCorrectEncoding(errorLogPath, true);
errorLogWriter.write(error);
errorLogWriter.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
errorLogWriter.close();
} catch (Exception e) {
System.out.println("TestSuite error log file could not be closed: " + e.getMessage());
}
}
}

private String displayErrorType(ErrorTypes errorType){
return errorType.name().replace("_", " ");
}

/**
* Gets the path for the TestSuite Parser error log
*/
private String getTestSuiteParserErrorLogPath(){
StringBuilder testSuiteParserErrorLogPath = new StringBuilder();
String configPath = Config.getTestsuiteparserErrorLogPath();
if (configPath == null)
configPath = "." + Constants.FILE_SEPARATOR;
if (configPath.equals("." + Constants.FILE_SEPARATOR))
testSuiteParserErrorLogPath.append(new File(Constants.EMPTY_STRING).getAbsolutePath());
else
testSuiteParserErrorLogPath.append(new File(configPath));

testSuiteParserErrorLogPath.append(Constants.FILE_SEPARATOR);
testSuiteParserErrorLogPath.append(Config.getTestsuiteparserErrorLogName());
return testSuiteParserErrorLogPath.toString();
}

/**
* Returns a Writer for the TestSuite Parser error log.
*/
private void initializeTestSuiteErrorLogWriter(String path){
String testSuiteParserErrorLogPath = path;
Writer testSourceWriter = null;
try {
File testSuiteParserErrorLogFile = new File(testSuiteParserErrorLogPath);
if (testSuiteParserErrorLogFile.exists())
testSuiteParserErrorLogFile.delete();

Writer filecreator = new FileWriter(testSuiteParserErrorLogPath);
filecreator.close();
testSourceWriter = EncodingIO.getWriterWithCorrectEncoding(testSuiteParserErrorLogPath);
FilePermission.setFilePermissionForAllUsers(testSuiteParserErrorLogPath, Config.getGeneratedFilesPermissionAll());
Log.info(Messages.get("INF013", testSuiteParserErrorLogPath));
testSourceWriter.close();
} catch (IOException testSourceOutException) {
System.out.println(testSourceOutException.getMessage());
}
}
}
Loading

0 comments on commit c99db5e

Please sign in to comment.