Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Project Goals In this project, you will be developing a simple Java application (texttool) using an agile, test-driven process involving multiple deliverables. While you will

Project Goals

In this project, you will be developing a simple Java application (texttool) using an agile, test-driven process involving multiple deliverables. While you will receive one grade for the entire project, each deliverable must be completed by its own due date, and all deliverables will contribute to the overall project grade.

Specification of thetexttool Utility

texttoolis a simple command-line utility written in Java with the following specification:

Summary

texttool allows for simple text manipulation of the content of a file.

Syntax

texttool [OPTIONS] FILE

Description

Program texttool performs basic text transformations on lines of text from an input FILE. Unless the -f option (see below) is specified, the program writes transformed text to stdout and errors/usage messages to stderr. The FILE parameter is required and must be the last parameter. OPTIONS may be zero or more of the following and may occur in any order:

  • -f Edit file in place. The program overwrites the input file with transformed text instead of writing to stdout. This option must be mutually exclusive with -o below. Input file is assured to always be writable.
  • -o The program writes the output tooutput_file_name with transformed text instead of writing to stdout. This option must be mutually exclusive with -f above. Ifoutput_file_name already exists, the program shall result in an error.
  • -r Replaces the first instance of stringoldin each line with stringnew. The search is case-sensitive. This option must be mutually exclusive with -c below.
  • -i Used with the -r flag ONLY; the search of -r becomes case-insensitive.
  • -p Adds the stringprefix at the beginning of each line.
  • -d Duplicate each line in the file n times, where n is an integer in the inclusive range of 1 to 10. The duplicate lines shall be sequential to each other.
  • -c Encodes the text using acipher that replaces each alphabetic characterchar with a new character that is atnpositions fromchar in the English alphabet (wrapping from "z" to "a" or from "a" to "z" if needed). Here, n is an integer in the inclusive range of -25 to 25, thus negative values n are valid. The cipher shall respect capitalization and ignore special characters and numbers. This option must be mutually exclusive with -r above.

NOTES:

  • While the last command-line parameter provided is always treated as the filename, OPTIONS flags can be provided in any order and shall be applied as follows:
    • Options -f/-o/-i shall be processed first, as they determine global parameters of the computation.
    • Options -r, -p, -c, and -d shall be processed in this order. That is: (1) if -r is present, then replacements are performed based on the option parameters, using a case insensitive old string if -i is present; (2) if -p is present, then a prefix shall be applied; (3) if -c is present, apply the given cipher; (4) if -d is present, then duplicate the lines based upon the specified parameter.
  • To keep this application simple, all errors shall result in display of the standard usage message.
  • Specifying option -i without having specified option -r shall result in an error.
  • Specifying option -r with an empty string as the parameter shall result in an error.
  • Specifying option -p with an empty string as the parameter shall result in an error.
  • Specifying option -d with a non-integer value or an integer out of range shall result in an error.
  • Specifying option -c and -r simultaneously shall result in an error.
  • Specifying option -c without a valid integer value or an integer out of range shall result in an error.
  • If options are repeated, only their last occurrence is applied.
  • All program option parameters are required, resulting in an error if omitted.
  • You shall assume that the command line parameter strings will not contain newline characters ( , , and so on), as the behavior of the program would be platform dependent and may result in errors during grading. Therefore,there should be no test cases using these values as option parameters.
  • An empty input file shall produce an empty output file.
  • The last line of a non-empty input file must be newline terminated. Otherwise, the program shall generate an error.

EXAMPLES OF USAGE(In the following, "" represents a newline character.)

Example 1: texttool -f FILE

input FILE:

alphanumeric123foobar

edited FILE:

alphanumeric123foobar

stdout:nothing sent to stdout

stderr:nothing sent to stderr

Example 2: texttool -r 123 456 FILE

input FILE:

alphanumeric123foobar123

edited FILE:file not edited

stdout:

alphanumeric456foobar123

stderr:nothing sent to stderr

Example 3: texttool -i -r foo candy FILE

input FILE:

alphanumeric123FOObar123

edited FILE:file not edited

stdout:

alphanumeric123candybar123

stderr:nothing sent to stderr

Example 4: texttool -p ## FILE

input FILE:

alphanumeric123foobar

edited FILE:file not edited

stdout:

##alphanumeric123foobar

stderr:nothing sent to stderr

Example 5: texttool -d 3 FILE

input FILE:

alphanumeric123foobar

edited FILE:file not edited

stdout: alphanumeric123foobar

alphanumeric123foobar

alphanumeric123foobar

alphanumeric123foobar

stderr:nothing sent to stderr

Example 6: texttool -r foo FOO -f -p !!! -d 1 FILE

input FILE:

foobar0Foobar1

foobar2foobar3

foobar4Foobar5

foobar6foobar7

foobar8Foobar9

edited FILE:

!!!FOObar0Foobar1

!!!FOObar0Foobar1

!!!FOObar2foobar3

!!!FOObar2foobar3

!!!FOObar4Foobar5

!!!FOObar4Foobar5

!!!FOObar6foobar7

!!!FOObar6foobar7

!!!FOObar8Foobar9

!!!FOObar8Foobar9

stdout:nothing sent to stdout

stderr:nothing sent to stderr

Example 7: texttool -c -20 -d 5 -d 1 -p !!! -p ## FILE

input FILE:

alphanumeric123foobar

edited FILE:file not edited

stdout: ##grvngtaskxoi123luuhgx

##grvngtaskxoi123luuhgx

stderr:nothing sent to stderr

Example 8: texttool

input FILE:

01234abc

56789def

01234ABC

56789DEF

edited FILE:file not edited

stdout:nothing sent to stdout

stderr:

Usage: texttool [ -f | -o output_file_name | -i | -r old new | -p prefix | -c n | -d n ] FILE

Example 9: texttool -c 1 FILE

input FILE:

alphanumeric123foobar

edited FILE:file not edited

stdout:

bmqibovnfsjd123gppcbs

stderr:nothing sent to stderr

Deliverables Summary

This part of the document is provided to help you keep track of where you are in the individual project and will be updated in future deliverables.

DELIVERABLE 1

  • Provided:
    • texttool specification
    • Skeleton of the main class fortexttool
    • Example tests and skeleton of the test class to submit
    • JUnit libraries
  • Expected:
    • Part I (Category Partition)
      • catpart.txt: TSL file you created
      • catpart.txt.tsl: test specifications generated by theTSLgenerator tool when run on your TSL file.
    • Part II (Junit Tests)

Junit tests derived from your category partition test frames (MyMainTest.java)

DELIVERABLE 2 (this deliverable, see below for details)

  • Provided:
    • Reference implementation oftexttool utility

  • Expected:
    • Possibly revised set of tests that (1) pass on the reference implementation, (2) cover a set of scenarios (provided through Gradescope), and (3) have suitable oracles.

Deliverable 1: Instructions

Part I

Generatebetween 50 and 90 test-case specifications (i.e., generated test frames) for thetexttool utility using the category-partition method presented in lesson P4L2.Make sure to watch the lesson and demo before getting started.

When defining your test specifications, your goal is to suitably cover the domain of the application under test, includingrelevant erroneous inputs and input combinations. Just to give you an example, if you were testing a calculator, you may want to cover the case of a division by zero.

Do not manually generate combinations of inputs as single choices. Instead, use multiple categories and choices with necessary constraints to cause the tool to generate meaningful combinations. Using the calculator example again, you should not offer choices "add", "multiply", and also "add and multiply" in a single category.

In particular,make sure to use constraints (error and single), selector expression (if), and properties appropriately, rather than eliminating choices, to keep the number of test cases within the specified thresholds.

Note thatthe domain is that of the java application under test, so you can assume that anything the shell would reject (e.g., unmatched double quotes) will not reach the application. In other words,you must test for invalid input arguments, but do not need to test for errors involving parsing the command-line arguments before they are sent to the java application. In other words, you may assume thatMain.main() will be called with a validString[] of args. Although this application will only use the simplified command-line parsing given in the specification above, you can find more details about comprehensive command-line argument parsing atthis link. To illustrate, the sample tests in Part II will demonstrate how input arguments would be sent to your application.

Please also keep in mind thatyou are only required to specify test inputs, but you do not have to specify the expected outcome for such inputs in Part I. It is therefore OK if you do not know how the system would behave for a specific input. Using the calculator example, you could test the case of a division by zero even if you did not know how exactly the calculator would behave for that input.

Tools and Useful Files

You will use theTSLgenerator tool to generate test frames starting from a TSL file, just like we did in the demo for lesson P4L2. Versions of theTSLgenerator for Linux, Mac OS X, and Windows, together with a user manual, are available at:

  • TSLgenerator-manual.txt
  • TSL generator for Linux
  • TSL generator for Mac OS
  • TSL generator for Windows 8 and newer
  • TSL generator for Windows XP and earlier

We are also providing the TSL file for the example we used in the lesson,cp-example.txt, for your reference.

Important:

  • These are command-line tools, which means thatyou have to run them from the command line, as we do in the video demo, rather than by clicking on them.
  • On Linux and Mac systems, you may need to change the permissions of the files to make them executable using thechmod utility. To run the tool on a Mac, for instance, you should do the following, from a terminal: chmod +x TSLgenerator-mac ./TSLgenerator-mac
  • You can run theTSLgenerator as follows: [--manpage] [-cs] infile [-o outfile] Where is the specific tool for your architecture, and the command-line flags have the following meaning:
--manpage Prints the man page for the tool.
-c Reports the number of test frames that would be generated, without actually producing them.
-s Outputs the result to standard output.
-o outfile Outputs the result to file outfile,unless the -s option is also used.

  • If you encounter issues while using the tool, please post a public question on Ed Discussion and consider running the tool on the VM provided for the class or on a different platform (if you have the option to do so). Gradescope will execute the tool on a Linux platform.

Deliverable 2: Instructions

In this deliverable, we will assume that someone else in your company implemented thetexttool utility while you were creating test cases for it. For the sake of the assignment, we will also assume that your colleague is an infallible developer and produced a flawless implementation. Consequently,all the test cases you created for Deliverable 1 are supposed to pass on this implementation.

To complete this deliverable, you will thus submit your test cases (i.e., classMyMainTest) and make sure that they pass on the reference implementation (Gradescope will run them for you and report information about passing and failing tests).

main.java

public class Main { // Empty Main class for compiling Individual Project. // During Deliverable 1 and Deliverable 2, DO NOT ALTER THIS CLASS or implement it public static void main(String[] args) { // Empty Skeleton Method } private static void usage() { System.err.println("Usage: texttool [ -f | -o output_file_name | -i | -r old new | -p prefix | -c n | -d n ] FILE"); } }

mainTest.java

public class MainTest { @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); private final Charset charset = StandardCharsets.UTF_8; private ByteArrayOutputStream outStream; private ByteArrayOutputStream errStream; private PrintStream outOrig; private PrintStream errOrig; @Before public void setUp() throws Exception { outStream = new ByteArrayOutputStream(); PrintStream out = new PrintStream(outStream); errStream = new ByteArrayOutputStream(); PrintStream err = new PrintStream(errStream); outOrig = System.out; errOrig = System.err; System.setOut(out); System.setErr(err); } @After public void tearDown() throws Exception { System.setOut(outOrig); System.setErr(errOrig); } /* * TEST UTILITIES */ // Create File Utility private File createTmpFile() throws Exception { File tmpfile = temporaryFolder.newFile(); tmpfile.deleteOnExit(); return tmpfile; } // Write File Utility private File createInputFile(String input) throws Exception { File file = createTmpFile(); OutputStreamWriter fileWriter = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8); fileWriter.write(input); fileWriter.close(); return file; } private String getFileContent(String filename) { String content = null; try { content = Files.readString(Paths.get(filename), charset); } catch (IOException e) { e.printStackTrace(); } return content; } /* * TEST CASES */ /* texttool -f FILE input FILE: alphanumeric123foobar edited FILE: alphanumeric123foobar stdout: nothing sent to stdout stderr: nothing sent to stderr */ @Test public void exampleTest1() throws Exception { String input = "alphanumeric123foobar!" + System.lineSeparator(); File inputFile = createInputFile(input); String[] args = {"-f", inputFile.getPath()}; Main.main(args); assertTrue("stderr output should be empty", errStream.toString().isEmpty()); assertTrue("stdout output should be empty", outStream.toString().isEmpty()); assertEquals("input file content not matched", input, getFileContent(inputFile.getPath())); } /* texttool -r 123 456 FILE input FILE: alphanumeric123foobar123 edited FILE: file not edited stdout: alphanumeric456foobar123 stderr: nothing sent to stderr */ @Test public void exampleTest2() throws Exception { String input = "alphanumeric123foobar123" + System.lineSeparator(); String expected = "alphanumeric456foobar123" + System.lineSeparator(); File inputFile = createInputFile(input); String[] args = {"-r", "123", "456", inputFile.getPath()}; Main.main(args); assertTrue("stderr output should be empty", errStream.toString().isEmpty()); assertEquals("stdout output does not match", expected, outStream.toString()); assertEquals("input file content not matched", input, getFileContent(inputFile.getPath())); } /* texttool -i -r foo candy FILE input FILE: alphanumeric123FOObar123 edited FILE: file not edited stdout: alphanumeric123candybar123 stderr: nothing sent to stderr */ @Test public void exampleTest3() throws Exception { String input = "alphanumeric123FOObar123" + System.lineSeparator(); String expected = "alphanumeric123candybar123" + System.lineSeparator(); File inputFile = createInputFile(input); String[] args = {"-i", "-r", "foo", "candy", inputFile.getPath()}; Main.main(args); assertTrue("stderr output should be empty", errStream.toString().isEmpty()); assertEquals("stdout output does not match", expected, outStream.toString()); assertEquals("input file content not matched", input, getFileContent(inputFile.getPath())); } /* texttool -p ## FILE input FILE: alphanumeric123foobar edited FILE: file not edited stdout: ##alphanumeric123foobar stderr: nothing sent to stderr */ @Test public void exampleTest4() throws Exception { String input = "alphanumeric123foobar" + System.lineSeparator(); String expected = "##alphanumeric123foobar" + System.lineSeparator(); File inputFile = createInputFile(input); String[] args = {"-p", "##", inputFile.getPath()}; Main.main(args); assertTrue("stderr output should be empty", errStream.toString().isEmpty()); assertEquals("stdout output does not match", expected, outStream.toString()); assertEquals("input file content not matched", input, getFileContent(inputFile.getPath())); } /* texttool -d 3 FILE input FILE: alphanumeric123foobar edited FILE: file not edited stdout: alphanumeric123foobar alphanumeric123foobar alphanumeric123foobar alphanumeric123foobar stderr: nothing sent to stderr */ @Test public void exampleTest5() throws Exception { String input = "alphanumeric123foobar" + System.lineSeparator(); String expected = "alphanumeric123foobar" + System.lineSeparator() + "alphanumeric123foobar" + System.lineSeparator() + "alphanumeric123foobar" + System.lineSeparator() + "alphanumeric123foobar" + System.lineSeparator(); File inputFile = createInputFile(input); String[] args = {"-d", "3", inputFile.getPath()}; Main.main(args); assertTrue("stderr output should be empty", errStream.toString().isEmpty()); assertEquals("stdout output does not match", expected, outStream.toString()); assertEquals("input file content not matched", input, getFileContent(inputFile.getPath())); } /* texttool -r foo FOO -f -p !!! -d 1 FILE input FILE: foobar0Foobar1 foobar2foobar3 foobar4Foobar5 foobar6foobar7 foobar8Foobar9 edited FILE: !!!FOObar0Foobar1 !!!FOObar0Foobar1 !!!FOObar2foobar3 !!!FOObar2foobar3 !!!FOObar4Foobar5 !!!FOObar4Foobar5 !!!FOObar6foobar7 !!!FOObar6foobar7 !!!FOObar8Foobar9 !!!FOObar8Foobar9 stdout: nothing sent to stdout stderr: nothing sent to stderr */ @Test public void exampleTest6() throws Exception { String input = "foobar0Foobar1" + System.lineSeparator() + "foobar2foobar3" + System.lineSeparator() + "foobar4Foobar5" + System.lineSeparator() + "foobar6foobar7" + System.lineSeparator() + "foobar8Foobar9" + System.lineSeparator(); String expected = "!!!FOObar0Foobar1" + System.lineSeparator() + "!!!FOObar0Foobar1" + System.lineSeparator() + "!!!FOObar2foobar3" + System.lineSeparator() + "!!!FOObar2foobar3" + System.lineSeparator() + "!!!FOObar4Foobar5" + System.lineSeparator() + "!!!FOObar4Foobar5" + System.lineSeparator() + "!!!FOObar6foobar7" + System.lineSeparator() + "!!!FOObar6foobar7" + System.lineSeparator() + "!!!FOObar8Foobar9" + System.lineSeparator() + "!!!FOObar8Foobar9" + System.lineSeparator(); File inputFile = createInputFile(input); String[] args = {"-r", "foo", "FOO", "-f", "-p", "!!!", "-d", "1", inputFile.getPath()}; Main.main(args); assertTrue("stderr output should be empty", errStream.toString().isEmpty()); assertTrue("stdout output should be empty", outStream.toString().isEmpty()); assertEquals("input file content not matched", expected, getFileContent(inputFile.getPath())); } /* texttool -c -20 -d 5 -d 1 -p !!! -p ## FILE input FILE: alphanumeric123foobar edited FILE: file not edited stdout: ##grvngtaskxoi123luuhgx ##grvngtaskxoi123luuhgx stderr: nothing sent to stderr */ @Test public void exampleTest7() throws Exception { String input = "alphanumeric123foobar" + System.lineSeparator(); String expected = "##grvngtaskxoi123luuhgx" + System.lineSeparator() + "##grvngtaskxoi123luuhgx" + System.lineSeparator(); File inputFile = createInputFile(input); String[] args = {"-c", "-20", "-d", "5", "-d", "1", "-p", "!!!", "-p", "##", inputFile.getPath()}; Main.main(args); assertTrue("stderr output should be empty", errStream.toString().isEmpty()); assertEquals("stdout output does not match", expected, outStream.toString()); assertEquals("input file content not matched", input, getFileContent(inputFile.getPath())); } /* texttool input FILE: 01234abc 56789def 01234ABC 56789DEF edited FILE: file not edited stdout: nothing sent to stdout stderr: Usage: texttool [ -f | -o output_file_name | -i | -r old new | -p prefix | -c n | -d n ] FILE */ @Test public void exampleTest8() throws Exception { String input = "01234abc" + System.lineSeparator() + "56789def" + System.lineSeparator() + "01234ABC" + System.lineSeparator() + "56789DEF" + System.lineSeparator(); File inputFile = createInputFile(input); String[] args = {}; Main.main(args); assertEquals("stderr output does not match", "Usage: texttool [ -f | -o output_file_name | -i | -r old new | -p prefix | -c n | -d n ] FILE", errStream.toString().strip()); assertTrue("stdout output should be empty", outStream.toString().isEmpty()); assertEquals("input file content not matched", input, getFileContent(inputFile.getPath())); } /* texttool -c 1 FILE input FILE: alphanumeric123foobar edited FILE: file not edited stdout: bmqibovnfsjd123gppcbs stderr: nothing sent to stderr */ @Test public void exampleTest9() throws Exception { String input = "alphanumeric123foobar" + System.lineSeparator(); String expected = "bmqibovnfsjd123gppcbs" + System.lineSeparator(); File inputFile = createInputFile(input); String[] args = {"-c", "1", inputFile.getPath()}; Main.main(args); assertTrue("stderr output should be empty", errStream.toString().isEmpty()); assertEquals("stdout output does not match", expected, outStream.toString()); assertEquals("input file content not matched", input, getFileContent(inputFile.getPath())); } }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Advanced Accounting

Authors: Joe Hoyle, Thomas Schaefer, Timothy Doupnik

10th edition

0-07-794127-6, 978-0-07-79412, 978-0077431808

More Books

Students also viewed these Programming questions