Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9f709b2
Fixed multiple line SQLCA problem on ZOS
WildtBrian Jan 3, 2025
4b4a672
version bump
WildtBrian Jan 3, 2025
acb18e6
version bump
WildtBrian Jan 3, 2025
a5096eb
only read statement as 1 line if it starts with EXEC SQL
WildtBrian Jan 7, 2025
995b6da
added 0.2.14.jar
WildtBrian Jan 7, 2025
f0908e4
Added old 0.2.14 jar to fix git
Jan 8, 2025
5bf85f0
Merge pull request #367 from openmainframeproject/Fix_git_jar
TommyTechh Jan 8, 2025
337f9d2
Merge pull request #363 from WildtBrian/Developer
oakmount1966 Jan 9, 2025
04e7be1
Replace class
thomasNellemann-BD Jan 27, 2025
80f2a60
Replace class
thomasNellemann-BD Feb 11, 2025
274e91e
Replace class
thomasNellemann-BD Feb 12, 2025
c28a11a
Replace class
thomasNellemann-BD Feb 12, 2025
2ce7789
remove
thomasNellemann-BD Feb 12, 2025
b346ccb
replace
thomasNellemann-BD Feb 12, 2025
88abf8c
replace
thomasNellemann-BD Feb 12, 2025
6805197
replace
thomasNellemann-BD Feb 12, 2025
a0fdd97
fix double space
SMoRG75 Feb 14, 2025
1bccc44
small tweaks
SMoRG75 Feb 14, 2025
8bca130
Replace statement handling
thomasNellemann-BD Feb 19, 2025
475c6d4
RegEx
thomasNellemann-BD Feb 19, 2025
c71da2e
Replace statement
thomasNellemann-BD Feb 19, 2025
7f61547
distributions are keept
thomasNellemann-BD Feb 19, 2025
4d2c227
Update testCOBOLtests.cmd
SMoRG75 Feb 20, 2025
a73d49b
gradle test update
thomasNellemann-BD Feb 21, 2025
0baf4a9
test fix
thomasNellemann-BD Feb 21, 2025
517a446
import removed
thomasNellemann-BD Feb 21, 2025
bed8ed2
test fix and cleanup
thomasNellemann-BD Feb 21, 2025
4290865
test fix
thomasNellemann-BD Feb 21, 2025
211549f
Merge pull request #370 from thomasNellemann-BD/add-replace-to-unit-t…
oakmount1966 Feb 21, 2025
310b530
Merge pull request #369 from openmainframeproject/fix-too-many-spaces
TommyTechh Feb 25, 2025
0403694
Merge branch 'main' into Developer
Feb 26, 2025
48c783c
0.2.16_release
Feb 26, 2025
5b30a6e
0.2.16_release
Feb 26, 2025
2f7ae82
0.2.16_release
Feb 26, 2025
d7e24ba
0.2.16_release
Feb 26, 2025
e93db09
Merge pull request #372 from openmainframeproject/0.2.16_release
TommyTechh Feb 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Mock SQL tables
- Mock batch file I/O



## \[0.2.16\] 2024-12-05
- Fixed a bug an extra space would be added to the list of mocks, which would create issues when looking for mocks.
- Added support for the replace statement in unit test source

## \[0.2.14\] 2024-12-05
- Fixed a bug where an exit code of 4 was not allowed.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ As of March 2022 we could use help with:

## Downloads

Version 0.2.14 pre-release is available!
Version 0.2.16 pre-release is available!

[//]: # (- Find the download on the project home page on the [Neo Pragma site](https://neopragma.com/projects/cobol-check/).)
- Find distributions here: [Cobol Check Ditributions](https://github.com/openmainframeproject/cobol-check/tree/Developer/build/distributions).
Expand Down
2 changes: 1 addition & 1 deletion approvaltestWin.cmd
Original file line number Diff line number Diff line change
@@ -1 +1 @@
./cobolcheck -p NUMBERS ALPHA GREETING FILECOPY MOCKTEST DPICNUMBERS > approval-test-actual.txt
./cobolcheck -p ALPHA DB2PROG DPICNUMBERS FILECOPY GREETING MOCK MOCKPARA MOCKTEST NUMBERS RETURNCODE TESTNESTED > approval-test-actual.txt
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
id 'jacoco'
}

def productVersion = '0.2.14'
def productVersion = '0.2.16'
def productName = 'cobol-check'
group = 'org.openmainframeproject'
description = 'Unit testing framework for Cobol'
Expand Down
Binary file added build/distributions/cobol-check-0.2.15.zip
Binary file not shown.
Binary file added build/distributions/cobol-check-0.2.16.zip
Binary file not shown.
48 changes: 48 additions & 0 deletions src/main/cobol/BIPM012.CBL
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
ID DIVISION.
PROGRAM-ID. BIPM012.
AUTHOR. (TNP).
DATE-WRITTEN. 20.01.2025.
*--------------+------+-------------------------------------------
*
* FUNKTION UNITTEST VALIDATION - REPLACE
*
*--------------+------+-------------------------------------------
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
DECIMAL-POINT IS COMMA.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.

WORKING-STORAGE SECTION.
*-----------------------------------------------------------------
01 WORK-FIELDS-1.
03 MOVE-IDX PIC S9(4) COMP.
03 WS-BALANCE-X PIC S9(11)V9(2) VALUE 0 COMP.
03 WS-NUMBER-OF-MOVE PIC S9(07) COMP-3.

03 WS-DATE-BEFORE PIC X(10).
03 WS-DATE-AFTER PIC X(10).
*-----------------------------------------------------------------
01 BIPM012-PARM.
07 INPUT-DATA.
10 USERNO PIC 9(03).
07 OUTPUT-DATA.
10 MAX-HEIGHT usage COMP-3 PIC S9(5).
10 MAX-LENGTH PIC S9(07) usage COMP-3.

*-----------------------------------------------------------------

REPLACE ==:BDSIXXX:== BY ==BIPM012==.

*-----------------------------------------------------------------
PROCEDURE DIVISION.
*-----------------------------------------------------------------
MOVE ZERO TO MAX-LENGTH IN :BDSIXXX:-PARM
.
100-MOVE-DATA SECTION.
*-----------------------------------------------------------------
MOVE WS-DATE-BEFORE TO WS-DATE-AFTER
.
11 changes: 11 additions & 0 deletions src/main/cobol/MOCK.CBL
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,17 @@
MOVE output-value TO VALUE-1
.

611-CALL-WITH-STRUCTURE.
MOVE "1" to ACTION-PARAM
MOVE "2" to BOOK-PARAM
MOVE "3" to OUTPUT-VALUE
CALL 'MYCOBOL' USING ACTION-PARAM,
BOOK-PARAM IN COBOL-STRUCTURE,
OUTPUT-VALUE IN COBOL-STRUCTURE
END-CALL
MOVE OUTPUT-VALUE IN COBOL-STRUCTURE TO VALUE-1
.

700-MAKE-CALL.
MOVE "arg1" to VALUE-1
MOVE "arg2" to VALUE-2
Expand Down
14 changes: 14 additions & 0 deletions src/main/cobol/copy/BIPM012I.CBL
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
*-----------------------------------------------------------------
* >>> START COPYBOOK BIPM012I
*
*-----------------------------------------------------------------
04 MODULE-DATA.
05 IO-TABLE.
07 INPUT-DATA.
09 USERNO PIC 9(03).
07 OUTPUT-DATA.
10 MAX-HEIGHT COMP-3 PIC S9(5).
10 MAX-LENGTH PIC S9(07) COMP-3.
*-----------------------------------------------------------------
* <<< END COPYBOOK BIPM012I
*-----------------------------------------------------------------
Original file line number Diff line number Diff line change
Expand Up @@ -451,25 +451,25 @@ private void updateLineRepository(CobolLine line) throws IOException {
}
}

if (reader.isFlagSet(Constants.WORKING_STORAGE_SECTION) &&
line.containsToken(Constants.EXEC_SQL_TOKEN) &&
(line.containsToken(Constants.INCLUDE)
|| reader.peekNextMeaningfulLine().containsToken(Constants.INCLUDE))) {
Platform platform = PlatformLookup.get();
switch(platform){
case ZOS:
if (line.containsToken("SQLCA") || line.containsToken("SQLDA"))
return;
default:
extractedCopyBook = lineRepository.addExpandedCopyDB2Statements(reader.readStatementAsOneLine());
for (int i = 0; i < extractedCopyBook.size(); i++) {
CobolLine cobolLine = new CobolLine(extractedCopyBook.get(i), tokenExtractor);
List<CobolLine> currentStatement = new ArrayList<>();
currentStatement.add(cobolLine);
this.currentDataStructure = updateCurrentDataStructure(currentStatement, currentDataStructure);
updateNumericFields(cobolLine);
}
break;
if (reader.isFlagSet(Constants.WORKING_STORAGE_SECTION) && line.containsToken(Constants.EXEC_SQL_TOKEN)) {
String statement = reader.readStatementAsOneLine().getTrimmedString().replaceAll("\\s+", " ");
if (statement.startsWith(Constants.EXEC_SQL_TOKEN + " " + Constants.INCLUDE)) {
Platform platform = PlatformLookup.get();
switch(platform){
case ZOS:
if (statement.contains("SQLCA") || statement.contains("SQLDA"))
return;
default:
extractedCopyBook = lineRepository.addExpandedCopyDB2Statements(reader.readStatementAsOneLine());
for (int i = 0; i < extractedCopyBook.size(); i++) {
CobolLine cobolLine = new CobolLine(extractedCopyBook.get(i), tokenExtractor);
List<CobolLine> currentStatement = new ArrayList<>();
currentStatement.add(cobolLine);
this.currentDataStructure = updateCurrentDataStructure(currentStatement, currentDataStructure);
updateNumericFields(cobolLine);
}
break;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.openmainframeproject.cobolcheck.services.Constants;
import org.openmainframeproject.cobolcheck.services.Messages;
import org.openmainframeproject.cobolcheck.services.StringHelper;
import org.openmainframeproject.cobolcheck.services.cobolLogic.replace.Replace;
import org.openmainframeproject.cobolcheck.services.filehelpers.EncodingIO;
import org.openmainframeproject.cobolcheck.services.filehelpers.FileNameMatcher;
import org.openmainframeproject.cobolcheck.services.filehelpers.FilePermission;
Expand Down Expand Up @@ -107,7 +108,7 @@ Reader concatenateTestSuites(String programTestSuiteSubdirectory) {
String line = Constants.EMPTY_STRING;
concatenatedTestSuitesWriter.write(StringHelper.commentOutLine("From file: " + matchingFile) + Constants.NEWLINE);
while((line = testFileReader.readLine()) != null) {
concatenatedTestSuitesWriter.write(line + Constants.NEWLINE);
concatenatedTestSuitesWriter.write(Replace.replace(line) + Constants.NEWLINE);
}
testFileReader.close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ public List<String> getArguments() {
}

public void addArgument(String argument) {
argument = argument.replaceAll("\\s+", " ");
arguments.add(argument);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ private void argumentCheck(Object argumentValue, String messageId) {
private String getKeyBasedOnAssumedDataStructure(String line) {
// We will attempt to split the line on any " IN " and " OF " statements, to isolate the names
// in the referenced data structure.
// TODO - check the validity of the regex. It is not clear if it is correct. Because of the inclusion of the - sign. in W set.
String[] nameTokens = line.toUpperCase().split("(?:^|\\W)OF(?:$|\\W)|(?:^|\\W)IN(?:$|\\W)");
Boolean found=false;
for (String key : fieldTypes.keySet()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package org.openmainframeproject.cobolcheck.services.cobolLogic.replace;

import org.openmainframeproject.cobolcheck.services.log.Log;
import org.openmainframeproject.cobolcheck.services.log.LogLevel;

import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Class to handle the COBOL REPLACE statement on the test suite/test case source code.
* <p>
* Method inspect() should be called on every line of the COBOL source code to set the REPLACE statements.
* The source must at least contain a char in the beginning of the line to be considered a valid source line.
* This char is the comment indicator.
* The REPLACE statement must be in the standard (IBM) format: REPLACE ==FROM-KEYWORD== BY ==TO-KEYWORD==.
* <p>
* Method replace() is called on every line of the unit test source code to replace the strings.
* <p>
* <b>There are two main public methods:</b>
* <ol>
* <li>replace() - Used on Inspects the test source for replacing; replaceFrom to replaceTo strings.</li>
* <li>inspect() - Examines the source line for the REPLACE statement and sets the replaceFrom and replaceTo strings.</li>
* </ol>
* <p>
* <b>And two convenience methods:</b>
* <ol>
* <li>isReplaceOn() - Returns the current state of the replaceOn flag.</li>
* <li>2. reset() - Resets the state of the Replace class.</li>
* </ol>
*/
public class Replace {
private static final String COBOL_COMMENT_INDICATOR = "*";

/**
* Look for the comment indicator in the source line.
* Capture group description:
* 1. 0-6 digits/spaces (group 1) the line numbers (if present)
* 2. * or space (group 2) comment indicator (other markers are not supported)
* 3. (group 3) remainder of the line
*/
private static final Pattern sourceIsCommentPattern = Pattern.compile("^([\\s|\\d]{0,6})(\\"
+ COBOL_COMMENT_INDICATOR + ")(.+)");
private static final int SOURCE_COMMENT_INDICATOR = 2;


/**
* The state of the REPLACE statement.
*/
private static boolean replaceOn = false;
private static final LinkedList<ReplaceSet> replaceMap = new LinkedList<>();

private static boolean inspect_performed = false;
private static boolean inspect_performed_warned = false;

/**
* Looks in the source line for the replace-key and replaces is with the replace-to-value.
*
* @param source a line of cobol-check unit test code
* @return the source line there the appropriate replacement has been made
*/
public static String replace(String source) {
if (!inspect_performed) {
if (!inspect_performed_warned) {
inspect_performed_warned = true;
Log.warn("Replace.replace() called before inspect");
}
}
// if there are no REPLACE statements, return the source line as is
if (!replaceOn) return source;

// avoid null pointer exception
if (source == null || source.isEmpty()) {
return source;
}

// is the source line a comment? quit now...
if (sourceLineIsComment(source)) {
return source;
}

String replacesString = source;

for (ReplaceSet replaceSet : replaceMap) {
Log.trace("Replace.replace(): Key: <" + replaceSet.getFrom() + ">, Value: <" + replaceSet.getTo() + ">");
replacesString = replaceSet.replaceInline(replacesString);
if ((Log.level() == LogLevel.TRACE) && (!replacesString.equals(source))) {
Log.trace("Replace.replace(): Key: <" + replaceSet.getFrom() + ">, result: " + replacesString);
}
}
return replacesString;
}


public static void inspectProgram(File cobolProgram) {
Log.trace("Replace.inspectProgram(): Inspecting the COBOL program file: " + cobolProgram);
reset();

// Use the statement locator to find the REPLACE statements in the COBOL program
ReplaceStatementLocator rsl = new ReplaceStatementLocator(cobolProgram);
replaceMap.addAll(rsl.getReplaceSets());

if (replaceMap.isEmpty()) {
replaceOn = false;
} else {
replaceOn = true;
}
inspect_performed = true;
}

/**
* Examines the source line for the COBOL commment indicator
*
* @param source a line of cobol-check unit test code
* @return true if the source line is a comment, false otherwise
*/
private static boolean sourceLineIsComment(String source) {
Matcher sourceElements = sourceIsCommentPattern.matcher(source);
if (sourceElements.find()) {
// Is the line a comment? true or false
return sourceElements.group(SOURCE_COMMENT_INDICATOR).equals(COBOL_COMMENT_INDICATOR);
}
return false;
}

/**
* Returns the current state of the replaceOn flag.
*
* @return true if there is an active REPLACE statement, false otherwise.
*/
public static boolean isReplaceOn() {
return replaceOn;
}

/**
* Return the number of replace sets
* @return the number of replace sets
*/
public static int getReplaceSetsSize() {
return replaceMap.size();
}

/**
* Resets the state of the Replace class to the initial state.
*/
private static void reset() {
replaceOn = false;
replaceMap.clear();
inspect_performed = false;
inspect_performed_warned = false;
}
}
Loading
Loading