diff --git a/src/main/cobol/GREETING.CBL b/src/main/cobol/GREETING.CBL
index 419ad176..c18f16b8 100644
--- a/src/main/cobol/GREETING.CBL
+++ b/src/main/cobol/GREETING.CBL
@@ -16,7 +16,7 @@
01 WS-FRIEND PIC X(10) VALUE SPACES.
01 WS-GREETING.
10 FILLER PIC X(07) VALUE 'Hello, '.
- 10 WS-USER-NAME PIC X(06) VALUE SPACES.
+ 10 WS-USER-NAME PIC X(05) VALUE SPACES.
10 FILLER PIC X VALUE '!'.
01 WS-FAREWELL.
10 FILLER PIC X(15) VALUE 'See you later, '.
diff --git a/src/main/java/org/openmainframeproject/cobolcheck/features/testSuiteParser/TestSuiteConcatenator.java b/src/main/java/org/openmainframeproject/cobolcheck/features/testSuiteParser/TestSuiteConcatenator.java
index 580ba18e..6b1228ff 100644
--- a/src/main/java/org/openmainframeproject/cobolcheck/features/testSuiteParser/TestSuiteConcatenator.java
+++ b/src/main/java/org/openmainframeproject/cobolcheck/features/testSuiteParser/TestSuiteConcatenator.java
@@ -106,9 +106,12 @@ Reader concatenateTestSuites(String programTestSuiteSubdirectory) {
for (String matchingFile : matchingFiles) {
BufferedReader testFileReader = new BufferedReader(EncodingIO.getReaderWithCorrectEncoding(matchingFile));
String line = Constants.EMPTY_STRING;
+ // Line number is set to zero, to be used in Replace.replace() method
+ // So that replace is performed regardless of line number
+ int lineNumber = 0;
concatenatedTestSuitesWriter.write(StringHelper.commentOutLine("From file: " + matchingFile) + Constants.NEWLINE);
while((line = testFileReader.readLine()) != null) {
- concatenatedTestSuitesWriter.write(Replace.replace(line) + Constants.NEWLINE);
+ concatenatedTestSuitesWriter.write(Replace.replace(line, lineNumber) + Constants.NEWLINE);
}
testFileReader.close();
}
diff --git a/src/main/java/org/openmainframeproject/cobolcheck/features/testSuiteParser/TestSuiteParser.java b/src/main/java/org/openmainframeproject/cobolcheck/features/testSuiteParser/TestSuiteParser.java
index cbd3d50e..b23cc078 100644
--- a/src/main/java/org/openmainframeproject/cobolcheck/features/testSuiteParser/TestSuiteParser.java
+++ b/src/main/java/org/openmainframeproject/cobolcheck/features/testSuiteParser/TestSuiteParser.java
@@ -882,7 +882,6 @@ private void handleEndOfMockStatement(BufferedReader testSuiteReader, String tes
*
* @param parsedTestSuiteLines The parsed lines, that the generated lines are
* appended to
- * @return - the next token from the testSuiteReader.
* @throws VerifyReferencesNonexistentMockException if referenced mock, does not
* exist
*/
diff --git a/src/main/java/org/openmainframeproject/cobolcheck/services/StringHelper.java b/src/main/java/org/openmainframeproject/cobolcheck/services/StringHelper.java
index f7218093..0c7bf7b6 100644
--- a/src/main/java/org/openmainframeproject/cobolcheck/services/StringHelper.java
+++ b/src/main/java/org/openmainframeproject/cobolcheck/services/StringHelper.java
@@ -90,7 +90,7 @@ public static String changeFileExtension(String path, String extension){
/**
* Trims only the end of the string.
- * Ex.: " Hey \n" => " Hey"
+ * Ex.: " Hey \n" ~ " Hey"
*
* @param line - original string
* @return - string trimmed at the end.
@@ -123,7 +123,7 @@ public static boolean occursFirst (String text, char expectedFirst, char expecte
/**
* Swaps two characters in a given string.
- * Example: swapChars("1.000.000,00", '.', ',') => "1,000,000.00"
+ * Example: swapChars("1.000.000,00", '.', ',') ~ "1,000,000.00"
* @param c1 - One of the chars to swap
* @param c2 - One of the chars to swap
* @return - The given string with the given char values swapped
diff --git a/src/main/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/Replace.java b/src/main/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/Replace.java
index cc17b332..f1674429 100644
--- a/src/main/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/Replace.java
+++ b/src/main/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/Replace.java
@@ -4,8 +4,6 @@
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;
@@ -60,9 +58,10 @@ public class Replace {
* 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
+ * @param lineNumber the line number of the source line
* @return the source line there the appropriate replacement has been made
*/
- public static String replace(String source) {
+ public static String replace(String source, int lineNumber) {
if (!inspect_performed) {
if (!inspect_performed_warned) {
inspect_performed_warned = true;
@@ -86,7 +85,7 @@ public static String replace(String source) {
for (ReplaceSet replaceSet : replaceMap) {
Log.trace("Replace.replace(): Key: <" + replaceSet.getFrom() + ">, Value: <" + replaceSet.getTo() + ">");
- replacesString = replaceSet.replaceInline(replacesString);
+ replacesString = replaceSet.replaceInline(replacesString, lineNumber);
if ((Log.level() == LogLevel.TRACE) && (!replacesString.equals(source))) {
Log.trace("Replace.replace(): Key: <" + replaceSet.getFrom() + ">, result: " + replacesString);
}
@@ -94,6 +93,10 @@ public static String replace(String source) {
return replacesString;
}
+ public static String replace(String source) {
+ return replace(source, 0);
+ }
+
public static void inspectProgram(File cobolProgram) {
Log.trace("Replace.inspectProgram(): Inspecting the COBOL program file: " + cobolProgram);
@@ -152,4 +155,34 @@ private static void reset() {
inspect_performed = false;
inspect_performed_warned = false;
}
+
+ public static String replaceInProgram(File program) {
+ // write the replaced program back to disk
+
+ String newFileName = program+"_MOD";
+ Log.warn("Replace.replaceInProgram(): Writing the COBOL program file: " + newFileName);
+ try {
+ BufferedWriter writer = new BufferedWriter(new FileWriter(newFileName));
+ // read the program one line at the time
+ BufferedReader reader = new BufferedReader(new FileReader(program));
+ //for every line in the program, replace and write to output file
+ String line;
+ int lineCount = 0;
+ while ((line = reader.readLine()) != null) {
+ writer.write(Replace.replace(line, lineCount++));
+ writer.newLine();
+ }
+ writer.close();
+ reader.close();
+ } catch (IOException e) {
+ Log.error("Replace.replaceInProgram(): Error writing the COBOL program file: " + program);
+ }
+ return newFileName;
+ }
+
+ public static void showReplaceSets() {
+ for (ReplaceSet replaceSet : replaceMap) {
+ Log.info("Replace.showReplaceSets():" + replaceSet.toString());
+ }
+ }
}
diff --git a/src/main/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceSet.java b/src/main/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceSet.java
index 957c30ac..20c4bd5e 100644
--- a/src/main/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceSet.java
+++ b/src/main/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceSet.java
@@ -4,13 +4,21 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+/**
+ * Class to handle the COBOL REPLACE statement keys on the test suite/test case source code.
+ *
+ * When fromSourceLine and untilSourceLine are set, the replace is only performed on the lines between these two lines.
+ * When the values are zero, the replace key set is applied to all lines.
+ */
public class ReplaceSet {
private String from;
private String to;
private boolean trailing;
private boolean leading;
+ private int fromSourceLine;
+ private int untilSourceLine;
- public ReplaceSet(String from, String to, boolean trailing, boolean leading) {
+ public ReplaceSet(String from, String to, boolean trailing, boolean leading,int fromSourceLine, int untilSourceLine) {
if (trailing && leading) {
throw new IllegalArgumentException("Cannot have both trailing and leading set to true");
}
@@ -19,6 +27,8 @@ public ReplaceSet(String from, String to, boolean trailing, boolean leading) {
this.to = to;
this.trailing = trailing;
this.leading = leading;
+ this.fromSourceLine = fromSourceLine;
+ this.untilSourceLine = untilSourceLine;
}
public ReplaceSet() {
@@ -26,10 +36,12 @@ public ReplaceSet() {
this.to = "";
this.trailing = false;
this.leading = false;
+ this.fromSourceLine = 0;
+ this.untilSourceLine = 0;
}
/**
- * Perform 'Replace' in the string (line param). Correponding to the 'REPLACE' statement in COBOL program
+ * Perform 'Replace' in the string (line param). Corresponding to the 'REPLACE' statement in COBOL program
* And the values parsed from the statements are used to replace the values in the line.
*
* @param line The line to replace in
@@ -60,6 +72,28 @@ public String replaceInline(String line) {
}
}
+ /**
+ * Perform 'Replace' in the string (line param). Corresponding to the 'REPLACE' statement in COBOL program
+ * And the values parsed from the statements are used to replace the values in the line.
+ * @param line
+ * @param sourceLine
+ * @return
+ */
+ public String replaceInline(String line, int sourceLine) {
+ // if the line is zero, the replace key set is applied
+ if (sourceLine == 0) return replaceInline(line);
+
+ // when fromSourceLine and untilSourceLine are zero, the replace key set is applied to all lines.
+ if (fromSourceLine == 0 && untilSourceLine == 0) return replaceInline(line);
+
+ // when the line number is between fromSourceLine and untilSourceLine, the replace is performed
+ if ((sourceLine >= fromSourceLine && sourceLine <= untilSourceLine) ||
+ ((sourceLine >= fromSourceLine && untilSourceLine == 0))) return replaceInline(line);
+
+ // Otherwise, return the line as is
+ return line;
+ }
+
public void setTrailing(boolean trailing) {
if (trailing && this.leading) {
throw new IllegalArgumentException("Cannot have both trailing and leading set to true");
@@ -97,4 +131,20 @@ public boolean isTrailing() {
public boolean isLeading() {
return leading;
}
+
+ public void setFromSourceLine(int sourceLineNumber) {
+ this.fromSourceLine = sourceLineNumber;
+ }
+ public void setUntilSourceLine(int sourceLineNumber) {
+ this.untilSourceLine = sourceLineNumber;
+ }
+ public int getFromSourceLine() {
+ return fromSourceLine;
+ }
+ public int getUntilSourceLine() {
+ return untilSourceLine;
+ }
+ public String toString() {
+ return "From: " + from + ", To: " + to + ", Trailing: " + trailing + ", Leading: " + leading + ", FromSourceLine: " + fromSourceLine + ", UntilSourceLine: " + untilSourceLine;
+ }
}
diff --git a/src/main/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceStatementLocator.java b/src/main/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceStatementLocator.java
index 06d274fc..bd084683 100644
--- a/src/main/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceStatementLocator.java
+++ b/src/main/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceStatementLocator.java
@@ -1,5 +1,6 @@
package org.openmainframeproject.cobolcheck.services.cobolLogic.replace;
+import org.jetbrains.annotations.NotNull;
import org.openmainframeproject.cobolcheck.services.log.Log;
import java.io.*;
@@ -16,9 +17,11 @@ public class ReplaceStatementLocator {
// because it can be split over multiple lines
private final ReplaceTokenizer tokenizer = new ReplaceTokenizer();
protected StringBuilder currentStatement;
+ protected int statementLineNumber = 0;
protected boolean we_are_parsing_a_replace_statement = false;
protected int sourceLinesProcessed = 0;
protected int commentLinesFound = 0;
+ private int currentSourcecodeLine = -1;
public ReplaceStatementLocator() {
Log.trace("ReplaceStatementLocator(): No file provided, only for testing purposes");
@@ -29,8 +32,9 @@ public ReplaceStatementLocator(File cobolFile) {
//Iterate over the file and inspect each line
try (BufferedReader reader = new BufferedReader(new FileReader(cobolFile))) {
String line;
+ int lineCounter = 0;
while ((line = reader.readLine()) != null) {
- accumulateStatement(line);
+ accumulateStatement(line,++lineCounter);
}
} catch (FileNotFoundException e) {
Log.error("ReplaceStatementLocator(): File not found: " + e.getMessage());
@@ -45,7 +49,7 @@ public LinkedList getReplaceSets() {
return replaceSets;
}
- protected void accumulateStatement(String line) {
+ protected void accumulateStatement(String line, int sourceLineNumber) {
// tokenize the line
tokenizer.tokenize(line);
@@ -66,25 +70,40 @@ protected void accumulateStatement(String line) {
if (t.getType() == ReplaceTokenType.REPLACE) {
// if we have a REPLACE token, start accumulating the statement
currentStatement = new StringBuilder().append(t.getValue());
+ this.statementLineNumber = sourceLineNumber;
we_are_parsing_a_replace_statement = true;
} else if (t.getType() == ReplaceTokenType.TERMINATOR && we_are_parsing_a_replace_statement) {
// if we have a terminator token, process the statement
- createStatements(currentStatement.toString());
+ createStatements(currentStatement.toString(),this.statementLineNumber);
we_are_parsing_a_replace_statement = false;
}
}
}
+ /**
+ * Update the untilSourceLine in all ReplaceSet objects where the from is equal to the given value
+ * @param untilSourceLine the new value for untilSourceLine
+ */
+ protected void updateUntilInReplaceSets(int fromSourceLine, int untilSourceLine) {
+ for (ReplaceSet replaceSet : replaceSets) {
+ if (replaceSet.getFromSourceLine() == fromSourceLine) replaceSet.setUntilSourceLine(untilSourceLine);
+ }
+ }
+
/**
* process a complete REPLACE statement and create the ReplaceSet objects
* @param statement string of tokens from replace to terminator (.)
*/
- protected void createStatements(String statement) {
+ protected void createStatements(String statement, int sourceLineNumber) {
ReplaceTokenizer statementTokenizer = new ReplaceTokenizer();
statementTokenizer.tokenize(statement);
- ReplaceSet replaceSet = new ReplaceSet();
+ ReplaceSet replaceSet = getNewReplaceSet(sourceLineNumber);
+ // update the ReplaceSets that may have been created from the 'currentSourcecodeLine' location
+ // from and to values are corrected to avoid replacing the REPLACE statement itself
+ this.updateUntilInReplaceSets(this.currentSourcecodeLine + 1,sourceLineNumber - 1);
+ this.currentSourcecodeLine = sourceLineNumber;
ReplaceToken t;
boolean nextTokenIsTo = false;
@@ -111,7 +130,7 @@ protected void createStatements(String statement) {
replaceSet.setTo(t.getValue().replace("==", ""));
nextTokenIsTo = false;
replaceSets.add(replaceSet);
- replaceSet = new ReplaceSet();
+ replaceSet = getNewReplaceSet(sourceLineNumber);
} else {
replaceSet.setFrom(t.getValue().replace("==", ""));
}
@@ -119,4 +138,12 @@ protected void createStatements(String statement) {
}
}
}
+
+ private static @NotNull ReplaceSet getNewReplaceSet(int sourceLineNumber) {
+ ReplaceSet replaceSet = new ReplaceSet();
+ // one is added to the sourceLineNumber because the REPLACE statement is on current line and the replace is done from the next line
+ // This way we won´t replace the REPLACE statement itself
+ replaceSet.setFromSourceLine(sourceLineNumber + 1);
+ return replaceSet;
+ }
}
diff --git a/src/main/java/org/openmainframeproject/cobolcheck/workers/Generator.java b/src/main/java/org/openmainframeproject/cobolcheck/workers/Generator.java
index b55642f7..68469bbb 100644
--- a/src/main/java/org/openmainframeproject/cobolcheck/workers/Generator.java
+++ b/src/main/java/org/openmainframeproject/cobolcheck/workers/Generator.java
@@ -68,9 +68,12 @@ public Generator(InterpreterController interpreter, WriterController writerContr
public void prepareAndRunMerge(String programName, String testFileNames) {
RunInfo.setCurrentProgramName(new File(programName).getName());
RunInfo.setCurrentProgramPath(new File(programName).getAbsolutePath());
- Replace.inspectProgram(new File(PathHelper.appendMatchingFileSuffix(programName, Config.getApplicationFilenameSuffixes())));
+ File originalSource = new File(PathHelper.appendMatchingFileSuffix(programName, Config.getApplicationFilenameSuffixes()));
+ Replace.inspectProgram(originalSource);
matchingTestDirectories = PrepareMergeController.getMatchingTestDirectoriesForProgram(programName);
+ //replace in the program, return the program name with the corrected source code.
+ programName = Replace.replaceInProgram(originalSource);
for (String matchingDirectory : matchingTestDirectories) {
Reader sourceReader = PrepareMergeController.getSourceReader(programName);
diff --git a/src/test/cobol/GREETING/GreetingByName.cut b/src/test/cobol/GREETING/GreetingByName.cut
index 79816e06..f1a569f7 100644
--- a/src/test/cobol/GREETING/GreetingByName.cut
+++ b/src/test/cobol/GREETING/GreetingByName.cut
@@ -7,11 +7,11 @@
PERFORM 2000-SPEAK
EXPECT WS-GREETING TO BE "Hello, James!"
- TESTCASE "When message type is farewell it returns Goodbye, James!"
+ TESTCASE "When message type is farewell it returns Goodbye, James !"
SET MESSAGE-IS-FAREWELL TO TRUE
MOVE "James" TO WS-FRIEND
PERFORM 2000-SPEAK
- EXPECT WS-FAREWELL TO BE "Goodbye, James!"
+ EXPECT WS-FAREWELL TO BE "See you later, James !"
TESTCASE "User name for greeting and farewell are consistent"
SET MESSAGE-IS-GREETING TO TRUE
diff --git a/src/test/cobol/GREETING/GreetingByType.cut b/src/test/cobol/GREETING/GreetingByType.cut
index a75869c0..e4b44e39 100644
--- a/src/test/cobol/GREETING/GreetingByType.cut
+++ b/src/test/cobol/GREETING/GreetingByType.cut
@@ -2,6 +2,7 @@
"Greeting returns the appropriate message based on message type"
TestCase "When message type is greeting it returns 'Hello, World!'"
+ move space to WS-FRIEND
SET MESSAGE-IS-GREETING TO TRUE
PERFORM 2000-SPEAK
EXPECT WS-GREETING TO BE "Hello, World!"
@@ -11,6 +12,7 @@
EXPECT WS-COUNT TO BE 1
TESTCASE "try 88 level compare"
+ set message-is-farewell to true
EXPECT MESSAGE-IS-GREETING TO BE FALSE
TESTCASE "When message type is farewell it returns See you later, alligator!"
@@ -19,6 +21,6 @@
Expect WS-FAREWELL To Be "See you later, alligator!"
TESTCASE "Message type greeting is not true"
- SET MESSAGE-IS-GREETING TO TRUE
+ SET MESSAGE-IS-FAREWELL TO TRUE
Expect MESSAGE-IS-GREETING NOT TO BE TRUE
diff --git a/src/test/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceSetTest.java b/src/test/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceSetTest.java
index 4accd7df..e021a460 100644
--- a/src/test/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceSetTest.java
+++ b/src/test/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceSetTest.java
@@ -10,19 +10,19 @@ public class ReplaceSetTest {
public void testReplaceSet() {
// Create a Replace set
- ReplaceSet replaceSet = new ReplaceSet("REPLACE", "REPLACED", false, false);
+ ReplaceSet replaceSet = new ReplaceSet("REPLACE", "REPLACED", false, false,0,0);
assertEquals("REPLACE", replaceSet.getFrom());
assertEquals("REPLACED", replaceSet.getTo());
assertFalse(replaceSet.isTrailing());
assertFalse(replaceSet.isLeading());
- replaceSet = new ReplaceSet("BRUCE", "CAITLYN", true, false);
+ replaceSet = new ReplaceSet("BRUCE", "CAITLYN", true, false,0,0);
assertEquals("BRUCE", replaceSet.getFrom());
assertEquals("CAITLYN", replaceSet.getTo());
assertTrue(replaceSet.isTrailing());
assertFalse(replaceSet.isLeading());
- replaceSet = new ReplaceSet("JOHNNY", "JAY", false, true);
+ replaceSet = new ReplaceSet("JOHNNY", "JAY", false, true,0,0);
assertEquals("JOHNNY", replaceSet.getFrom());
assertEquals("JAY", replaceSet.getTo());
assertFalse(replaceSet.isTrailing());
@@ -31,17 +31,17 @@ public void testReplaceSet() {
// Having both trailing and leading set to true is not allowed
// This should throw an exception
// Not possible via constructor
- assertThrows(IllegalArgumentException.class, () -> new ReplaceSet("JOHNNY", "JAY", true, true));
+ assertThrows(IllegalArgumentException.class, () -> new ReplaceSet("JOHNNY", "JAY", true, true,0,0));
// not possible via setter
- ReplaceSet replaceSetLeading = new ReplaceSet("REPLACE", "REPLACED", false, true);
+ ReplaceSet replaceSetLeading = new ReplaceSet("REPLACE", "REPLACED", false, true,0,0);
assertThrows(IllegalArgumentException.class, () -> replaceSetLeading.setTrailing(true));
- ReplaceSet replaceSetTrailing = new ReplaceSet("REPLACE", "REPLACED", true, false);
+ ReplaceSet replaceSetTrailing = new ReplaceSet("REPLACE", "REPLACED", true, false,0,0);
assertThrows(IllegalArgumentException.class, () -> replaceSetTrailing.setLeading(true));
}
@Test
public void testReplaceInline() {
- ReplaceSet replaceSet = new ReplaceSet("JOHNNY", "JAY", false, false);
+ ReplaceSet replaceSet = new ReplaceSet("JOHNNY", "JAY", false, false,0,0);
String from = "Johnny is behind the iconic late-night desk.";
String expected = "JAY is behind the iconic late-night desk.";
assertEquals(expected, replaceSet.replaceInline(from));
@@ -49,7 +49,7 @@ public void testReplaceInline() {
@Test
public void testReplaceInlineTrailing() {
- ReplaceSet replaceSet = new ReplaceSet("night", "day", true, false);
+ ReplaceSet replaceSet = new ReplaceSet("night", "day", true, false,0,0);
String from = "Johnny is behind the iconic late-night desk.";
String expected = "Johnny is behind the iconic late-day desk.";
assertEquals(expected, replaceSet.replaceInline(from));
@@ -61,13 +61,11 @@ public void testReplaceInlineTrailing() {
from = "Johnny is working day and night behind the iconic desk.";
expected = "Johnny is working day and night behind the iconic desk.";
assertEquals(expected, replaceSet.replaceInline(from));
-
-
}
@Test
public void testReplaceInlineLeading() {
- ReplaceSet replaceSet = new ReplaceSet("late", "early", false, true);
+ ReplaceSet replaceSet = new ReplaceSet("late", "early", false, true,0,0);
String from = "Johnny is behind the iconic late-night desk.";
String expected = "Johnny is behind the iconic early-night desk.";
assertEquals(expected, replaceSet.replaceInline(from));
@@ -80,4 +78,26 @@ public void testReplaceInlineLeading() {
expected = "Johnny is working early and late behind the iconic desk.";
assertEquals(expected, replaceSet.replaceInline(from));
}
+
+ @Test
+ public void testReplaceInlinewithlinenumbering() {
+ ReplaceSet replaceSet = new ReplaceSet("late", "early", false, true,10,100);
+ String from = "Johnny is behind the iconic late-night desk.";
+ String expected = "Johnny is behind the iconic early-night desk.";
+ // unchanged as line number is not in the range
+ assertEquals(from, replaceSet.replaceInline(from,5));
+ // changed as line number is in the range
+ assertEquals(expected, replaceSet.replaceInline(from,15));
+ }
+
+ @Test
+ public void testReplaceinLineWithLinenumberingLastReplaceSetHasZeroAsUntilSourceLine() {
+ ReplaceSet replaceSet = new ReplaceSet("late", "early", false, true,10,0);
+ String from = "Johnny is behind the iconic late-night desk.";
+ String expected = "Johnny is behind the iconic early-night desk.";
+ // unchanged as line number is not in the range
+ assertEquals(from, replaceSet.replaceInline(from,5));
+ // changed as line number is in the range
+ assertEquals(expected, replaceSet.replaceInline(from,15));
+ }
}
diff --git a/src/test/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceStatementLocatorTest.java b/src/test/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceStatementLocatorTest.java
index 0e79242a..c33c14de 100644
--- a/src/test/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceStatementLocatorTest.java
+++ b/src/test/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceStatementLocatorTest.java
@@ -42,37 +42,33 @@ public void testReplaceStatementLocator() {
public void testAccumulateStatement() {
ReplaceStatementLocator locator = new ReplaceStatementLocator();
- locator.accumulateStatement("123245 REPLACE ==REPLACE== BY ==REPLACED==.");
+ locator.accumulateStatement("123245 REPLACE ==REPLACE== BY ==REPLACED==.",0);
assertEquals(1, locator.getReplaceSets().size());
assertEquals("REPLACE", locator.getReplaceSets().get(0).getFrom());
assertEquals("REPLACED", locator.getReplaceSets().get(0).getTo());
-
-
-
}
@Test
public void testAccumulateStatementWithMultipleLines() {
ReplaceStatementLocator locator = new ReplaceStatementLocator();
- locator.accumulateStatement("123245 REPLACE ==REPLACE== BY ==REPLACED== ");
- locator.accumulateStatement("123456 ==PETER== BY ==PHIL==. ");
+ locator.accumulateStatement("123245 REPLACE ==REPLACE== BY ==REPLACED== ",0);
+ locator.accumulateStatement("123456 ==PETER== BY ==PHIL==. ",0);
assertEquals(2, locator.getReplaceSets().size());
assertEquals("REPLACE", locator.getReplaceSets().get(0).getFrom());
assertEquals("REPLACED", locator.getReplaceSets().get(0).getTo());
assertEquals("PETER", locator.getReplaceSets().get(1).getFrom());
assertEquals("PHIL", locator.getReplaceSets().get(1).getTo());
-
}
@Test
public void testAccumulateStatementWithMultipleLinesAndComments() {
ReplaceStatementLocator locator = new ReplaceStatementLocator();
- locator.accumulateStatement("123456* REPLACE ==REPLACE== BY ==REPLACED== ");
- locator.accumulateStatement("123456 REPLACE ==REPLACE== BY ==REPLACED== ");
- locator.accumulateStatement("123456* REPLACE ==BEEF== BY ==SALAD== ");
- locator.accumulateStatement("123456 ==PETER== BY ==PHIL==. ");
+ locator.accumulateStatement("123456* REPLACE ==REPLACE== BY ==REPLACED== ",0);
+ locator.accumulateStatement("123456 REPLACE ==REPLACE== BY ==REPLACED== ",0);
+ locator.accumulateStatement("123456* REPLACE ==BEEF== BY ==SALAD== ",0);
+ locator.accumulateStatement("123456 ==PETER== BY ==PHIL==. ",0);
assertEquals(2, locator.getReplaceSets().size());
assertEquals("REPLACE", locator.getReplaceSets().get(0).getFrom());
assertEquals("REPLACED", locator.getReplaceSets().get(0).getTo());
@@ -81,10 +77,10 @@ public void testAccumulateStatementWithMultipleLinesAndComments() {
locator = new ReplaceStatementLocator();
- locator.accumulateStatement("* REPLACE ==REPLACE== BY ==REPLACED== ");
- locator.accumulateStatement(" REPLACE ==REPLACE== BY ==REPLACED== ");
- locator.accumulateStatement(" * REPLACE ==BEEF== BY ==SALAD== ");
- locator.accumulateStatement(" ==PETER== BY ==PHIL==. ");
+ locator.accumulateStatement("* REPLACE ==REPLACE== BY ==REPLACED== ",0);
+ locator.accumulateStatement(" REPLACE ==REPLACE== BY ==REPLACED== ",0);
+ locator.accumulateStatement(" * REPLACE ==BEEF== BY ==SALAD== ",0);
+ locator.accumulateStatement(" ==PETER== BY ==PHIL==. ",0);
assertEquals(2, locator.getReplaceSets().size());
assertEquals("REPLACE", locator.getReplaceSets().get(0).getFrom());
assertEquals("REPLACED", locator.getReplaceSets().get(0).getTo());
@@ -97,14 +93,14 @@ public void testCreateStatements() {
//one set of keywords
ReplaceStatementLocator locator = new ReplaceStatementLocator();
- locator.createStatements("REPLACE ==REPLACE== BY ==REPLACED==");
+ locator.createStatements("REPLACE ==REPLACE== BY ==REPLACED==",0);
assertEquals(1, locator.getReplaceSets().size());
assertEquals("REPLACE", locator.getReplaceSets().get(0).getFrom());
assertEquals("REPLACED", locator.getReplaceSets().get(0).getTo());
//Two sets of keywords
locator = new ReplaceStatementLocator();
- locator.createStatements("REPLACE ==REPLACE== BY ==REPLACED== ==PETER== BY ==PHIL==");
+ locator.createStatements("REPLACE ==REPLACE== BY ==REPLACED== ==PETER== BY ==PHIL==",0);
assertEquals(2, locator.getReplaceSets().size());
assertEquals("REPLACE", locator.getReplaceSets().get(0).getFrom());
assertEquals("REPLACED", locator.getReplaceSets().get(0).getTo());
@@ -113,7 +109,7 @@ public void testCreateStatements() {
//Two sets of keywords with one leading and one trailing
locator = new ReplaceStatementLocator();
- locator.createStatements("REPLACE TRAILING ==REPLACE== BY ==REPLACED== LEADING ==PETER== BY ==PHIL==");
+ locator.createStatements("REPLACE TRAILING ==REPLACE== BY ==REPLACED== LEADING ==PETER== BY ==PHIL==",0);
assertEquals(2, locator.getReplaceSets().size());
assertEquals("REPLACE", locator.getReplaceSets().get(0).getFrom());
assertEquals("REPLACED", locator.getReplaceSets().get(0).getTo());
@@ -122,4 +118,54 @@ public void testCreateStatements() {
assertTrue(locator.getReplaceSets().get(0).isTrailing());
assertTrue(locator.getReplaceSets().get(1).isLeading());
}
+
+ @Test
+ public void testSourcelinesAreAddedToReplaceSets() {
+ ReplaceStatementLocator locator = new ReplaceStatementLocator();
+ locator.createStatements("REPLACE ==REPLACE== BY ==REPLACED==", 10);
+ assertEquals(1, locator.getReplaceSets().size());
+ assertEquals(11, locator.getReplaceSets().get(0).getFromSourceLine());
+ assertEquals(0, locator.getReplaceSets().get(0).getUntilSourceLine());
+
+ // add a second set of keywords, the previous set should have the untilSourceLine set
+ locator.createStatements("REPLACE ==MONDAY== BY ==TUESDAY==",100);
+ assertEquals(2, locator.getReplaceSets().size());
+ assertEquals(11, locator.getReplaceSets().get(0).getFromSourceLine());
+ assertEquals(99, locator.getReplaceSets().get(0).getUntilSourceLine());
+ assertEquals(101, locator.getReplaceSets().get(1).getFromSourceLine());
+ assertEquals(0, locator.getReplaceSets().get(1).getUntilSourceLine());
+
+ // add a third set of keywords, the previous set should have the untilSourceLine set
+ locator.createStatements("REPLACE ==THURSDAY== BY ==FRIDAY==",785);
+ assertEquals(3, locator.getReplaceSets().size());
+ assertEquals(11, locator.getReplaceSets().get(0).getFromSourceLine());
+ assertEquals(99, locator.getReplaceSets().get(0).getUntilSourceLine());
+ assertEquals(101, locator.getReplaceSets().get(1).getFromSourceLine());
+ assertEquals(784, locator.getReplaceSets().get(1).getUntilSourceLine());
+ assertEquals(786, locator.getReplaceSets().get(2).getFromSourceLine());
+ assertEquals(0, locator.getReplaceSets().get(2).getUntilSourceLine());
+
+ // add a fourth time - two sets, the previous set should have the untilSourceLine set
+ locator.createStatements("REPLACE TRAILING ==REPLACE== BY ==REPLACED== LEADING ==PETER== BY ==PHIL==",950);
+ assertEquals(5, locator.getReplaceSets().size());
+ assertEquals(786, locator.getReplaceSets().get(2).getFromSourceLine());
+ assertEquals(949, locator.getReplaceSets().get(2).getUntilSourceLine());
+ assertEquals(951, locator.getReplaceSets().get(3).getFromSourceLine());
+ assertEquals(0, locator.getReplaceSets().get(3).getUntilSourceLine());
+ assertEquals(951, locator.getReplaceSets().get(4).getFromSourceLine());
+ assertEquals(0, locator.getReplaceSets().get(4).getUntilSourceLine());
+
+ // add a fifth time - two sets, the previous sets should have the untilSourceLine set
+ locator.createStatements("REPLACE TRAILING ==REPLACE== BY ==NEW-WORD== LEADING ==PETER== BY ==Nicholas==",1000);
+ assertEquals(7, locator.getReplaceSets().size());
+ assertEquals(951, locator.getReplaceSets().get(3).getFromSourceLine());
+ assertEquals(999, locator.getReplaceSets().get(3).getUntilSourceLine());
+ assertEquals(951, locator.getReplaceSets().get(4).getFromSourceLine());
+ assertEquals(999, locator.getReplaceSets().get(4).getUntilSourceLine());
+ assertEquals(1001, locator.getReplaceSets().get(5).getFromSourceLine());
+ assertEquals(0, locator.getReplaceSets().get(5).getUntilSourceLine());
+ assertEquals(1001, locator.getReplaceSets().get(6).getFromSourceLine());
+ assertEquals(0, locator.getReplaceSets().get(6).getUntilSourceLine());
+ }
+
}
diff --git a/src/test/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceTest.java b/src/test/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceTest.java
index 0305e01e..c1968ca5 100644
--- a/src/test/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceTest.java
+++ b/src/test/java/org/openmainframeproject/cobolcheck/services/cobolLogic/replace/ReplaceTest.java
@@ -1,6 +1,5 @@
package org.openmainframeproject.cobolcheck.services.cobolLogic.replace;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.File;
@@ -26,40 +25,63 @@ public void test_General_setup() {
Replace.inspectProgram(new File("./testfiles/REPLACE.CBL"));
assertTrue(Replace.isReplaceOn());
assertEquals(5, Replace.getReplaceSetsSize());
- assertEquals("In Genesys, the lead singer is Phil",Replace.replace("In Genesys, the lead singer is Peter"));
+ assertEquals("In Genesys, the lead singer is Phil",Replace.replace("In Genesys, the lead singer is Peter", 62));
}
@Test
public void test_replace() {
Replace.inspectProgram(new File("./testfiles/REPLACE.CBL"));
- assertEquals("In Genesys, the lead singer is Phil",Replace.replace("In Genesys, the lead singer is Peter"));
- assertEquals(" MOVE 'CAITLIN' TO WS-OMEGA",Replace.replace(" MOVE 'BRUCE' TO WS-OMEGA"));
- assertEquals(" MOVE 'SOFT' TO WS-OMEGA",Replace.replace(" MOVE 'SOFT' TO WS-OMEGA"));
+ // line replaces in file:
+ // Replace.showReplaceSets();
+ // 23 REPLACE TRAILING ==ACTUAL== BY ==EXPECTED==.
+ // 42 REPLACE TRAILING ==ALPHA== BY ==GAMMA==.
+ // 52 REPLACE LEADING ==:WS:== BY ==UT==.
+ // 61 REPLACE ==Bruce== BY ==CAITLIN== ==PETER== BY ==Phil==.
+ assertEquals("In Genesys, the lead singer is Peter",Replace.replace("In Genesys, the lead singer is Peter", 50));
+ assertEquals("In Genesys, the lead singer is Phil",Replace.replace("In Genesys, the lead singer is Peter", 64));
+ assertEquals(" MOVE 'CAITLIN' TO WS-OMEGA",Replace.replace(" MOVE 'BRUCE' TO WS-OMEGA", 65));
+ assertEquals(" MOVE 'SOFT' TO WS-OMEGA",Replace.replace(" MOVE 'SOFT' TO WS-OMEGA", 310));
// When lines are comments, they should not be replaced
- assertEquals(" * MOVE 'BRUCE' TO WS-OMEGA",Replace.replace(" * MOVE 'BRUCE' TO WS-OMEGA"));
- assertEquals(" * MOVE 'SOFT' TO WS-OMEGA",Replace.replace(" * MOVE 'SOFT' TO WS-OMEGA"));
+ assertEquals(" * MOVE 'BRUCE' TO WS-OMEGA",Replace.replace(" * MOVE 'BRUCE' TO WS-OMEGA", 65));
+ assertEquals(" * MOVE 'SOFT' TO WS-OMEGA",Replace.replace(" * MOVE 'SOFT' TO WS-OMEGA", 310));
}
@Test
public void test_replace_leading() {
Replace.inspectProgram(new File("./testfiles/REPLACE.CBL"));
- assertEquals(" * USING WS-NOT-USED WS-OMEGA", Replace.replace(" * USING WS-NOT-USED WS-OMEGA"));
- assertEquals(" MOVE 'B' TO UT-EXPECTED",Replace.replace(" MOVE 'B' TO :WS:-EXPECTED"));
- assertEquals(" MOVE 'Y' TO UT-OMEGA",Replace.replace(" MOVE 'Y' TO :WS:-OMEGA"));
- assertEquals(" MOVE 'Y' TO WS-:WS:",Replace.replace(" MOVE 'Y' TO WS-:WS:"));
+ assertEquals(" * USING WS-NOT-USED WS-OMEGA", Replace.replace(" * USING WS-NOT-USED WS-OMEGA", 57));
+ assertEquals(" MOVE 'B' TO UT-EXPECTED",Replace.replace(" MOVE 'B' TO :WS:-EXPECTED", 58));
+ assertEquals(" MOVE 'Y' TO UT-OMEGA",Replace.replace(" MOVE 'Y' TO :WS:-OMEGA", 59));
+ assertEquals(" MOVE 'Y' TO WS-:WS:",Replace.replace(" MOVE 'Y' TO WS-:WS:", 69));
}
@Test
public void test_replace_trailing() {
Replace.inspectProgram(new File("./testfiles/REPLACE.CBL"));
- assertEquals(" * USING WS-ALPHA WS-OMEGA", Replace.replace(" * USING WS-ALPHA WS-OMEGA"));
- assertEquals(" MOVE 'B' TO UT-EXPECTED",Replace.replace(" MOVE 'B' TO UT-EXPECTED"));
- assertEquals(" MOVE 'Y' TO UT-GAMMA",Replace.replace(" MOVE 'Y' TO UT-ALPHA"));
- assertEquals(" MOVE 'Y' TO WS-EXPECTED",Replace.replace(" MOVE 'Y' TO WS-ACTUAL"));
+ assertEquals(" * USING WS-ALPHA WS-OMEGA", Replace.replace(" * USING WS-ALPHA WS-OMEGA", 43));
+ assertEquals(" MOVE 'B' TO UT-EXPECTED",Replace.replace(" MOVE 'B' TO UT-EXPECTED", 32));
+ assertEquals(" MOVE 'Y' TO UT-GAMMA",Replace.replace(" MOVE 'Y' TO UT-ALPHA", 46));
+ assertEquals(" MOVE 'Y' TO WS-EXPECTED",Replace.replace(" MOVE 'Y' TO WS-ACTUAL", 27));
}
+ @Test
+ public void test_replace_FI01_only_when_the_line_is_correct() {
+ Replace.inspectProgram(new File("./testfiles/REPLACE2.CBL"));
+ Replace.showReplaceSets();
+ assertEquals(" PERFORM INC-:XXXX:-SKRIV", Replace.replace(" PERFORM INC-:XXXX:-SKRIV", 69));
+ assertEquals(" INC-FI01-SKRIV SECTION.", Replace.replace(" INC-:XXXX:-SKRIV SECTION.", 72));
+ }
+
+ @Test
+ public void test_for_linenumber_0_every_replace_is_performed() {
+ Replace.inspectProgram(new File("./testfiles/REPLACE.CBL"));
+ assertEquals(" MOVE 'B' TO UT-EXPECTED",Replace.replace(" MOVE 'B' TO :WS:-EXPECTED", 0));
+ assertEquals(" MOVE 'Y' TO UT-OMEGA",Replace.replace(" MOVE 'Y' TO :WS:-OMEGA", 0));
+ assertEquals(" MOVE 'Y' TO WS-EXPECTED",Replace.replace(" MOVE 'Y' TO WS-ACTUAL", 0));
+ }
+
diff --git a/testfiles/REPLACE2.CBL b/testfiles/REPLACE2.CBL
new file mode 100644
index 00000000..74e9ae6b
--- /dev/null
+++ b/testfiles/REPLACE2.CBL
@@ -0,0 +1,77 @@
+ **********************************************************************
+ * AUTHOR: T. N. KRAMER
+ * DATE: 14 FEB 2025
+ * PURPOSE: DEMONSTRATE REPLACE STATEMENT
+ **********************************************************************
+ IDENTIFICATION DIVISION.
+ PROGRAM-ID. REPLDEMO.
+ ENVIRONMENT DIVISION.
+ DATA DIVISION.
+ WORKING-STORAGE SECTION.
+ 77 WS-OMEGA PIC X.
+ 77 WS-GAMMA PIC X.
+ 77 UT-OMEGA PIC X.
+ 77 UT-GAMMA PIC X.
+ 77 WS-SUBPROGRAM-NAME PIC X(08).
+ 77 UT-COMPARE-DEFAULT PIC X VALUE 'N'.
+ 77 UT-NORMAL-COMPARE PIC X VALUE 'N'.
+ 77 UT-ACTUAL PIC X.
+ 77 UT-EXPECTED PIC X.
+ 77 UT-TEST-CASE-COUNT PIC 9(4) VALUE 0.
+ 77 UT-TEST-CASE-COUNT PIC 9(4) VALUE 0.
+
+ REPLACE TRAILING ==ACTUAL== BY ==EXPECTED==.
+
+ PROCEDURE DIVISION.
+
+ SET UT-COMPARE-DEFAULT TO TRUE
+ PERFORM UT-ASSERT-EQUAL
+ ADD 1 TO UT-TEST-CASE-COUNT
+ SET UT-NORMAL-COMPARE TO TRUE
+ MOVE WS-OMEGA TO UT-ACTUAL
+ MOVE 'Y' TO UT-EXPECTED
+ .
+ 3000-DYNAMIC-CALL.
+ MOVE 'A' TO WS-ALPHA
+ MOVE 'Z' TO WS-OMEGA
+ * CALL WS-SUBPROGRAM-NAME
+ * USING WS-ALPHA WS-OMEGA
+ MOVE "B" TO WS-ALPHA
+ MOVE "Y" TO WS-OMEGA
+ .
+ REPLACE TRAILING ==ALPHA== BY ==GAMMA==.
+
+
+
+ 3001-DYNAMIC-CALL
+ MOVE 'A' TO WS-ALPHA
+ MOVE 'Z' TO WS-OMEGA
+ * CALL WS-SUBPROGRAM-NAME
+ * USING WS-ALPHA WS-OMEGA
+ MOVE "B" TO WS-ALPHA
+ MOVE "Y" TO WS-OMEGA
+ .
+ REPLACE LEADING ==:WS:== BY ==UT==.
+ 3002-DYNAMIC-CALL
+ MOVE 'A' TO WS-ALPHA
+ MOVE 'Z' TO WS-OMEGA
+ * CALL WS-SUBPROGRAM-NAME
+ * USING WS-ALPHA WS-OMEGA
+ MOVE "B" TO :WS:-EXPECTED
+ MOVE "Y" TO :WS:-OMEGA
+ .
+ REPLACE ==Bruce== BY ==CAITLIN==
+ ==PETER== BY ==Phil==.
+ 3002-DYNAMIC-CALL
+ MOVE 'PETER' TO WS-ALPHA
+ MOVE 'BRUCE' TO WS-OMEGA
+
+ PERFORM INC-:XXXX:-SKRIV
+
+ REPLACE ==:XXXX:== BY ==FI01==.
+ INC-:XXXX:-SKRIV SECTION.
+ ADD 1 TO UT-TEST-CASE-COUNT
+ * do some writing
+ .
+ 9999-END.
+ .
\ No newline at end of file