diff --git a/.gitignore b/.gitignore
index 750e364..132dba7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,14 @@ src/jacoco/*.jar
src/defaultJars/*.jar
src/JavaTddPluginSupport.jar
src/junit-4.8.2.jar
+src/findbugs/README.txt
+src/findbugs/bin/
+src/findbugs/doc/
+src/findbugs/lib/
+src/findbugs/optionalPlugin/
+src/findbugs/plugin/
+src/findbugs/src/
+src/pmd/*.jar
+src/pmd/LICENSE
+src/checkstyle/*.jar
+src/pit/*.jar
diff --git a/src/JavaTddPluginSupport.jar b/src/JavaTddPluginSupport.jar
index ba51455..9bac3fc 100644
Binary files a/src/JavaTddPluginSupport.jar and b/src/JavaTddPluginSupport.jar differ
diff --git a/src/build.xml b/src/build.xml
index f7b535b..a81487a 100644
--- a/src/build.xml
+++ b/src/build.xml
@@ -6,6 +6,7 @@
\s*|\s*<\/p>$//gso;
+ $detail =~ s/ < / < /go;
+ $detail =~ s/ <= / <= /go;
+ $detail =~ s/ > / > /go;
+ $detail =~ s/ >= / >= /go;
+ $detail =~ s/x&x/x&x/go;
+ $detail = ' ' . $detail . ' ' . $msg . ' Code Coverage: ");
+ $status{'feedback'}->print(" " .
+ ($usePit ? "Mutants Detected" : "Code Coverage") .": ");
if ($codeCoveragePercent < 100)
{
$status{'feedback'}->print(
@@ -3241,9 +3553,10 @@ sub processStatementsUncovered
my $descr = $cfg->getProperty("statElementsLabel", "Methods Executed");
$descr =~ tr/A-Z/a-z/;
- $descr =~ s/\s*executed\s*$//;
+ $descr =~ s/\s*Detected\s*$/ detected/;
+ $descr =~ s/\s*executed\s*$/ exercised/;
$status{'feedback'}->print(<enscript and
- ps2pdf as external commands, and requires these programs to
- be correctly installed and configured.";
- },
-/*
- {
- property = enscriptStyle;
- type = shortText;
- size = 15;
- default = "msvc";
- name = "PDF Formatting Style (for Enscript)";
- category = "Basic Settings";
- description =
- "If you are generating PDF printouts, you can specify the formatting style
- used by enscript. This name will be passed to
- enscript using its --style= parameter. See your
- enscript documentation for more information about the styles that are
- supported. Many enscript installations support the following styles:
- a2ps, emacs, emacs-verbose,
- ifh, and msvc. It is possible to add your
- own custom formatting definitions to your enscript installation and then
- use your own style name here as well.";
- },
-*/
- {
- property = wantClassDiagrams;
- type = boolean;
- default = true;
- name = "Generate Class Diagrams";
- category = "Basic Settings";
- description =
- "Set to true if you wish to generate class diagrams from students' code.
- The diagrams will be viewable by students, and accessible by TAs during
- grading. Note: This option uses both doxygen and
- dot as external commands, and requires these programs to
- be correctly installed and configured in the JavaTddPlugin's global
- configuration options.";
- },
- {
- property = debug;
- type = integer;
- advanced = true;
- default = 0;
- name = "Debug Level";
- category = "Developer Settings";
- description =
- "Set to a non-zero value for the script to produce debugging output (the
- larger the number, the greater the detail, up to about 5). Debugging output
- on each grading script run will be e-mailed to the instructor.";
- },
- {
- property = doNotDelete;
- type = antBoolean;
- advanced = true;
- name = "Preserve Derived Files";
- category = "Developer Settings";
- description =
- "Set to true to prevent the plug-in from deleting the derived files it
- creates during the build/test process for each submission. Normally, these
- files are deleted when a given submission has been completely processed.
- This setting is provided for debugging purposes, when one wishes to
- inspect the intermediate test driver source code or other derived files.";
- },
- {
- property = generateHeatmaps;
- type = antBoolean;
- advanced = true;
- name = "Generate Bug Heatmaps";
- category = "Developer Settings";
- description =
- "Set to true to generate GZoltar-based defect heatmaps. This option is
- experimental and for research use only. Using it will slow down
- generation of student feedback.";
- },
- {
- property = useEnhancedFeedback;
- type = boolean;
- advanced = true;
- default = false;
- name = "Use Enhanced Feedback (Experimental)";
- category = "Developer Settings";
- description =
- "Set to true to use the new (experimental) enhanced feedback layout.";
- },
- {
- property = useIndicatorFeedback;
- type = boolean;
- advanced = true;
- default = false;
- name = "Use Growth Mindset Feedback (Experimental)";
- category = "Developer Settings";
- description =
- "Set to true to use the new (experimental) growth mindset progress feedback.";
- },
- {
- property = useMaria;
- type = boolean;
- advanced = true;
- default = false;
- name = "Use Maria (Experimental)";
- category = "Developer Settings";
- description =
- "Set to true to show Maria (experimental), the virtual teaching assistant
- chatbot.";
- },
- {
- property = useMariaExplanations;
- type = boolean;
- advanced = true;
- default = false;
- name = "Use Maria Explanations (Experimental)";
- category = "Developer Settings";
- description =
- "Set to true to show \"Explain...\" links (experimental) by error messages.";
- },
- {
- property = useDailyMissions;
- type = boolean;
- advanced = true;
- default = false;
- name = "Use Daily Missions (Experimental)";
- category = "Developer Settings";
- description =
- "Set to true to give students daily mission challenges (experimental).";
- },
- {
- property = showAllTestOutcomes;
- type = boolean;
- advanced = true;
- default = false;
- name = "Show All Test Outcomes (Experimental)";
- category = "Developer Settings";
- description =
- "Set to true to use the new (experimental) feature to show all test outcomes
- instead of limited hints. Students still need to meet the coverage
- requirements and other requirements to see test outcomes, but will see
- the full table of tests instead of limited hints.";
- }
- );
- globalOptions = (
- {
- property = doxygenDir;
- type = shortText;
- size = 40;
- name = "Doxygen Directory";
- description =
- "The directory on the local server that contains the Doxygen executable.
- Doxygen (and Dot, below) are used to generate class diagrams for the code
- that students submit; if you do not have a copy of Doxygen or wish to
- disable diagram generation across all assignments, you can leave this
- field blank. If you are not the user administering this Web-CAT server,
- you will need to have your system administrator install this tool and set
- this path if you wish to use it.";
- },
- {
- property = dotDir;
- type = shortText;
- size = 40;
- name = "Dot Directory";
- description =
- "The directory on the local server that contains the Dot executable (from
- the Graphviz package). Dot (and Doxygen, above) are used to generate
- class diagrams for the code that students submit; if you do not have a copy
- of Dot or wish to disable diagram generation across all assignments, you can
- leave this field blank. If you are not the user administering this Web-CAT
- server, you will need to have your system administrator install this tool
- and set this path if you wish to use it.";
- }
- );
-}
+{
+ name = "JavaTddPlugin";
+ version.major = 4;
+ version.minor = 1;
+ version.revision = 3;
+ version.date = 20220206;
+ autoPublish = true;
+ requires = ( ANTForPlugins, PerlForPlugins,
+ PMDForPlugins, CheckstyleForPlugins );
+ provider = "Virginia Tech Computer Science";
+ provider.url = "http://web-cat.org/updates";
+ license = "GNU Affero General Public License v.3";
+ license.url = "http://www.gnu.org/licenses/agpl.html";
+ copyright =
+ "(c) 2006-2022 Virginia Tech Department of Computer Science";
+ info.url = "http://wiki.web-cat.org/WCWiki/JavaTddPlugin";
+ history.url =
+ "http://wiki.web-cat.org/WCWiki/JavaTddPlugin/ChangeHistory";
+ executable = execute.pl;
+ interpreter.prefix = "${PerlForPlugins.perl.exe}";
+ author = "Stephen Edwards (edwards@cs.vt.edu)";
+ authorUid = edwards;
+ languages = ( { name = Java; version = 1.14; } );
+ description = "This \"all-in-one\" plug-in is designed to provide full
+ processing and feedback generation for Java assignments where
+ students write their own JUnit test cases.
+ It includes ANT-based compilation, JUnit processing of student-written
+ tests, support for instructor-written reference tests, PMD and
+ Checkstyle analysis, and Clover-based tracking of code coverage
+ during student testing.";
+ timeoutMultiplier = 2;
+ timeoutInternalPadding = 400;
+ assignmentOptions = (
+ {
+ property = testCases;
+ type = fileOrDir;
+ fileTypes = ( java );
+ name = "Hidden JUnit Reference Test Class(es)";
+ description =
+ "A Java source file (or directory of source files) containing JUnit tests
+ to run against student code to assess completeness of problem coverage.
+ Test outcomes are not directly visible to students, an students only see
+ hints about what may be incorrect.
+ If you select a single Java file, it must contain a JUnit test class
+ declared in the default package. If you select a directory, it should
+ contain JUnit test classes arranged in subdirectories according to their
+ Java package declarations. If you make no selection, an empty set of
+ instructor reference tests will be used instead.";
+ },
+/* {
+ property = visibleTestCases;
+ type = fileOrDir;
+ fileTypes = ( java );
+ name = "Visible JUnit Reference Test Class(es)";
+ description =
+ "A Java source file (or directory of source files) containing JUnit tests
+ to run against student code to assess completeness of problem coverage.
+ \"Visible\" here means pass/fail information for every test is shown (not
+ limited by hint controls).
+ If you select a single Java file, it must contain a JUnit test class
+ declared in the default package. If you select a directory, it should
+ contain JUnit test classes arranged in subdirectories according to their
+ Java package declarations. If you make no selection, an empty set of
+ instructor reference tests will be used instead.";
+ },
+*/ {
+ property = assignmentJar;
+ type = fileOrDir;
+ fileTypes = ( jar );
+ name = "Supplemental Classes for Assignment";
+ description =
+ "A jar file (or a directory of class files in subdirs reflecting their
+ package structure, or a directory of multiple jar files) containing
+ precompiled classes to add to the classpath when compiling and running
+ submissions for this assignment. If you want to apply the same
+ jar settings to many assignments, use the \"Supplemental Classes\" setting
+ in the \"Reusable Configuration Options\" section instead. If you have
+ multiple jars to provide, place them all in the same directory in your
+ Web-CAT file space and then select the whole directory.";
+ },
+ {
+ property = localFiles;
+ type = fileOrDir;
+ name = "Data Files for Student";
+ description =
+ "A file (or a directory of files) to place in the student's current working
+ directory when running his/her tests and when running reference tests. The
+ file you select (or the entire contents of the directory you select) will be
+ copied into the current working directory during grading so that
+ student-written and instructor-written test cases can read and/or write to
+ the file(s). The default is to copy no files.";
+ }
+ );
+ optionCategories = (
+ "Basic Settings",
+ "Advanced Settings",
+ "Developer Settings"
+ );
+ options = (
+ {
+ property = useAssertions;
+ type = boolean;
+ default = true;
+ name = "Use Java Assertions";
+ category = "Basic Settings";
+ description =
+ "Enable Java assertions during execution. When set to false, assertions
+ in student or instructor-provided code will be treated as non-executable
+ (no-op's).";
+ },
+ {
+ property = useDefaultJar;
+ type = boolean;
+ default = true;
+ name = "Use Built-in Jars";
+ category = "Basic Settings";
+ description =
+ "Set to true to have a set of built-in jars containing Virginia Tech
+ CS 1/CS 2 classes placed on the classpath for assignments. Set to
+ false to omit these jars from the classpath.";
+ },
+ {
+ property = classpathJar;
+ type = fileOrDir;
+ fileTypes = ( jar );
+ name = "Predefined Classes";
+ category = "Basic Settings";
+ description =
+ "A jar file (or a directory of class files in subdirs reflecting their
+ package structure, or a directory of multiple jar files) containing
+ precompiled classes to add to the classpath when compiling and running
+ submissions. Use this setting if you'd like to share the same jar(s)
+ across several assignments. If you have multiple jars to provide,
+ place them all in the same directory in your Web-CAT file space and
+ then select the whole directory.";
+ },
+ {
+ property = useXvfb;
+ type = boolean;
+ default = false;
+ name = "Enable Xvfb During Test Execution";
+ category = "Advanced Settings";
+ description =
+ "This option is necessary for running GUI software tests on Linux servers.
+ It uses an instance of Xvfb, the X virtual frame buffer server, to run
+ unit tests so that GUI tests can render to a live X server. Note that
+ enabling this option will slow down test execution, since it takes time to
+ start up an X server, but it is required for GUI testing on a linux
+ server. Also, this option requires that Xvfb is already installed on
+ the server.";
+ },
+ {
+ property = policyFile;
+ advanced = true;
+ type = file;
+ fileTypes = ( policy );
+ name = "Java Security Policy";
+ category = "Advanced Settings";
+ description =
+ "A Java security policy file used to limit actions on student programs at
+ run-time. Leave unset to use the built-in default, which plugs most
+ security holes and prevents any file system access outside the subtree
+ rooted at the program's working directory.";
+ },
+ {
+ property = remote.post.url;
+ advanced = true;
+ type = shortText;
+ size = 40;
+ name = "Remotely Post Submissions";
+ category = "Advanced Settings";
+ description =
+ "A URL to which submissions will be posted as they are processed, to
+ allow for external tools to receive student submissions. If a URL is
+ specified an HTML POST request will be sent to the given URL, with the
+ student's user name provided in the parameter 'user', and the student's
+ submission file provided in the parameter 'uploadedfile'.";
+ },
+ {
+ property = "grader.partnerExcludePatterns";
+ advanced = true;
+ type = shortText;
+ size = 40;
+ name = "Partner Name Exclude Patterns";
+ category = "Basic Settings";
+ description =
+ "The plug-in will automatically scan @author tags in source code
+ to try to identify the user names of partners when partners are allowed
+ on an assignment. Here, you can provide a comma-separated list of names
+ to exclude from consideration (e.g., the names of instructors, if some
+ instructor names are listed in @author lines in pre-provided code).
+ Full Perl-style regular expressions can be used if desired.";
+ },
+ {
+ property = allStudentTestsMustPass;
+ type = boolean;
+ default = false;
+ name = "All Student Tests Must Pass";
+ category = "Basic Settings";
+ description =
+ "If you are truly following test-driven development practices, then no code
+ is ever released until all of its unit tests pass. If this option is set to
+ true, students will not receive a non-zero score or receive further
+ assessment feedback unless all student tests pass. If this option is not
+ set, then students may continue to proceed even if some student-written
+ tests fail The student's correctness/testing score is multiplied by the
+ proportion of their tests that pass.";
+ },
+ {
+ property = studentsMustSubmitTests;
+ type = boolean;
+ default = true;
+ name = "Students Must Submit Tests";
+ category = "Basic Settings";
+ description =
+ "When set, this option requires all students to submit test cases for their
+ own code. Submissions without test cases will received feedback to that
+ effect (and no more), as well as a zero score. If you unset this option,
+ then student submissions will not be required to include
+ student-written test cases, and only the reference test pass rate
+ will be used for scoring (i.e., student code coverage and student test pass
+ rate will not be included in scoring).";
+ },
+ {
+ property = includeStudentTestsInGrading;
+ type = boolean;
+ default = true;
+ name = "Include Student Test Results in Grading";
+ category = "Basic Settings";
+ description =
+ "When set, if students are required to submit tests, they are also included
+ in the scoring formula. When false, student test pass/fail ressults are
+ not included in the score calculation.";
+ },
+ {
+ property = coverageMetric;
+ advanced = true;
+ type = radioChoice;
+ name = "Test Coverage Metric";
+ category = "Basic Settings";
+ default = 0;
+ description = "Choose the criterion used to measure how thoroughly
+ a student's tests cover the corresponding code.";
+ choices = ( { label = "Methods executed"; value = 0; },
+ { label = "Lines executed"; value = 1; },
+ { label = "Methods + conditions executed";
+ value = 2; },
+ { label = "Lines + conditions executed";
+ value = 3; },
+ { label = "Methods + lines + conditions executed";
+ value = 4; }
+ );
+ },
+ {
+ property = coverageGoal;
+ type = double;
+ name = "Test Coverage Goal";
+ category = "Basic Settings";
+ description =
+ "If students are required to submit tests, this value is the target test
+ coverage threshold that must be achieved in order for students to receive
+ full credit. It should be a number between 0.0-100.0 representing the
+ minimum percent coverage required for full credit. The default is 100.0,
+ but a lower value may be used to allow students some slack in test coverage
+ when JaCoCo test coverage measures make achieving 100% too challenging.";
+ },
+ {
+ property = includeTestSuitesInCoverage;
+ type = boolean;
+ default = false;
+ name = "Include Student Test Code in Coverage Measures";
+ category = "Basic Settings";
+ description =
+ "Normally, this plug-in excludes student-written tests from all coverage
+ calculations, since the goal of the testing is to test the solution, not
+ to execute more tests. When this option is set, student-written tests
+ will be included in code coverage measures for the purposes of scoring,
+ meaning that students will have to execute all of the code in their
+ test classes.";
+ },
+ {
+ property = requireSimpleExceptionCoverage;
+ type = boolean;
+ default = false;
+ name = "Require Coverage of Simple Catch Blocks";
+ category = "Basic Settings";
+ description =
+ "When set, this option requires students to test all catch blocks, including
+ simple try/catch statements that are provided purely for compiler compliance
+ and that simply print a stack trace or re-throw the exception. If unchecked,
+ catch blocks that contain only a statement to print the stack trace or
+ re-throw a wrapped version of the exception are not counted in
+ coverage measurements, and do not result in point deductions.";
+ },
+ {
+ property = requireSimpleGetterSetterCoverage;
+ type = boolean;
+ default = false;
+ name = "Require Coverage of Simple Getters and Setters";
+ category = "Basic Settings";
+ description =
+ "When set, this option requires students to test all simple getter and
+ setter methods. A simple getter is a method whose name starts with
+ \"get\", and whose body simply returns a field value. A simple setter is
+ a void method whose name starts with \"set\" accepting one parameter, and
+ whose body simply assigns that parameter to a field. If unchecked,
+ simple getters and setters are not counted in coverage measurements, and
+ do not result in point deductions.";
+ },
+/*
+ {
+ property = "clover.includes";
+ type = shortText;
+ size = 40;
+ default = "**";
+ name = "Classes to Include in Coverage Measures";
+ category = "Basic Settings";
+ description =
+ "Specify the Java file names that should be included in Clover coverage
+ analysis. Only student class files with names that match the patterns you
+ list here will be processed by Clover. Patterns are
+ case-insensitive. Use * as a wildcard character (ANT-style pattern
+ matching is used).";
+ },
+ {
+ property = "clover.excludes";
+ type = shortText;
+ size = 40;
+ default = "none";
+ name = "Classes to Exclude from Coverage Measures";
+ category = "Basic Settings";
+ description =
+ "Specify Java file names that should not be processed by
+ Clover. Any classes that match the \"Classes to Include in Coverage
+ Measures\" above and also match the patterns you list here
+ will not be processed by Clover. Patterns are
+ case-insensitive. Use * as a wildcard character (ANT-style pattern
+ matching is used). Use \"none\" if you do not wish to use any
+ exclusion patterns.";
+ },
+*/
+ {
+ property = studentTestInclude;
+ type = shortText;
+ size = 40;
+ default = "*test *tests";
+ name = "Students Test Class Patterns";
+ category = "Basic Settings";
+ description =
+ "Specify the Java class names that should be treated as JUnit-style
+ test cases. Only student classes with names that match the patterns you
+ list here will be executed as test cases. Patterns are case-insensitive.
+ Use * as a wildcard character (ANT-style pattern matching is used).";
+ },
+ {
+ property = studentTestExclude;
+ type = shortText;
+ size = 40;
+ default = "abstract* *$*";
+ name = "Students Test Class Exclusion Patterns";
+ category = "Basic Settings";
+ description =
+ "Specify Java class names that should not be treated as JUnit-style
+ test cases. Any classes that match the \"Student Test Class Patterns\"
+ above and also match the patterns you list here
+ will not be treated as executable test cases. Patterns are
+ case-insensitive. Use * as a wildcard character (ANT-style pattern matching
+ is used). Use \"none\" if you do not wish to use any exclusion patterns.";
+ },
+ {
+ property = refTestInclude;
+ type = shortText;
+ size = 40;
+ default = "*";
+ name = "Reference Test Class Patterns";
+ category = "Basic Settings";
+ description =
+ "Specify the Java class names that should be treated as JUnit-style
+ test cases when selected as reference tests by an instructor. This
+ setting is only relevant when an instructor selects an entire directory
+ or folder of Java classes. In that case, only instructor reference classes
+ with names that match the patterns you list here will be executed as test
+ cases. Patterns are case-insensitive. Use * as a wildcard character
+ (ANT-style pattern matching is used).";
+ },
+ {
+ property = refTestExclude;
+ type = shortText;
+ size = 40;
+ default = "abstract* *$*";
+ name = "Reference Test Class Exclusion Patterns";
+ category = "Basic Settings";
+ description =
+ "Specify Java class names that should not be treated as JUnit-style
+ test cases when selected as reference tests by an instructor. This
+ setting is only relevant when an instructor selects an entire directory or
+ folder of Java classes. In that case, any classes that match the
+ \"Reference Test Class Patterns\" above and also match the
+ patterns you list here will not be treated as executable test cases.
+ Patterns are case-insensitive. Use * as a wildcard character (ANT-style
+ pattern matching is used).";
+ },
+ {
+ property = student.testingsupport.junit4.AdaptiveTimeout.ceiling;
+ advanced = true;
+ type = integer;
+ name = "Default Test Case Time Limit (in ms)";
+ category = "Basic Settings";
+ description =
+ "This plug-in provides built-in adaptive detection and termination of
+ infinite loops that occur within individual test methods. This setting
+ controls the default timeout before a single test case method is judged as
+ \"taking too long\", although this amount will be gradually increased up
+ to a higher maximum value if test methods terminate but come close to
+ this limit. The default if unset is ten seconds (10000 ms).";
+ },
+ {
+ property = student.testingsupport.junit4.AdaptiveTimeout.maximum;
+ advanced = true;
+ type = integer;
+ name = "Default Test Case Maximum Time (in ms)";
+ category = "Basic Settings";
+ description =
+ "This plug-in provides built-in adaptive detection and termination of
+ infinite loops that occur within individual test methods. This setting
+ controls the maximum allowable timeout before a single test case is judged
+ as \"taking too long\". The default if unset is twenty seconds (20000 ms).";
+ },
+ {
+ property = disableCheckstyle;
+ type = antBoolean;
+ name = "Turn Checkstyle Off";
+ category = "Basic Settings";
+ description =
+ "Disable Checkstyle for static analysis entirely (no need to upload a
+ separate configuration file to turn it off).";
+ },
+ {
+ property = checkstyleConfig;
+ advanced = true;
+ type = file;
+ fileTypes = ( xml );
+ name = "Checkstyle Configuration";
+ category = "Basic Settings";
+ description =
+ "An XML file containing a Checkstyle rule configuration (see the
+ Checksyle
+ documentation). This plug-in uses Checkstyle v5.6. If you would
+ like to turn off all Checkstyle checks entirely, use the \"Turn
+ Checkstyle Off\" option instead.";
+ },
+ {
+ property = disablePmd;
+ type = antBoolean;
+ name = "Turn PMD Off";
+ category = "Basic Settings";
+ description =
+ "Disable PMD for static analysis entirely (no need to upload a
+ separate configuration file to turn it off).";
+ },
+ {
+ property = pmdConfig;
+ advanced = true;
+ type = file;
+ fileTypes = ( xml );
+ name = "PMD Configuration";
+ category = "Basic Settings";
+ description =
+ "An XML file containing a set of PMD rules (see the
+ PMD
+ documentation). This plug-in uses PMD v5.0.5. If you owuld like to
+ turn off all PMD checks entirely, use the \"Turn PMD Off\" options instead.";
+ },
+ {
+ property = use.comtor;
+ type = antBoolean;
+ name = "Run COMTOR Comment Analyzer";
+ category = "Basic Settings";
+ description =
+ "Set to true to run the COMTOR Comment Analyzer and include the results
+ as part of the overall feedback report.";
+ },
+ {
+ property = staticAnalysisInclude;
+ type = shortText;
+ size = 40;
+ default = "*";
+ name = "Classes to Analyze";
+ category = "Basic Settings";
+ description =
+ "Specify the Java class names that should be included in Checkstyle and
+ PMD analysis. Only student classes with names that match the patterns you
+ list here will be processed by Checkstyle and PMD. Patterns are
+ case-insensitive. Use * as a wildcard character (ANT-style pattern
+ matching is used).";
+ },
+ {
+ property = staticAnalysisExclude;
+ type = shortText;
+ size = 40;
+ default = "none";
+ name = "Classes to Exclude from Analysis";
+ category = "Basic Settings";
+ description =
+ "Specify Java class names that should not be processed by
+ Checkstyle or PMD. Any classes that match the \"Classes to Analyze\"
+ above and also match the patterns you list here
+ will not be processed by Checkstyle or PMD. Patterns are
+ case-insensitive. Use * as a wildcard character (ANT-style pattern
+ matching is used). Use \"none\" if you do not wish to use any
+ exclusion patterns.";
+ },
+ {
+ property = markupProperties;
+ advanced = true;
+ type = file;
+ fileTypes = ( properties );
+ name = "Static Analysis Scoring Scheme";
+ category = "Basic Settings";
+ description =
+ "A Java properties file containing the point deductions and limits to
+ use for messages generated by Checkstyle or PMD. The point deductions
+ are specified in a fairly generic way so they can be used for many
+ assignments. Deductions in the default scheme are typically 1, 2, or 5
+ 'points', which are really simply relative weights. Specify a scaling
+ factor below to adjust how these weights are translated into point
+ deductions for a student.";
+ },
+ {
+ property = toolDeductionScaleFactor;
+ advanced = true;
+ type = double;
+ name = "Static Analysis Deduction Scaling Factor";
+ category = "Basic Settings";
+ description =
+ "The Static Analysis Scoring Scheme above defines the point deductions
+ and limits to use for messages generated by Checkstyle or PMD in a generic
+ way, with most deductions in the default scheme being 1, 2, or 5 points.
+ Deductions in the static analysis scoring scheme are multiplied by this
+ factor to translate them into actual 'point deductions' shown to the
+ student.";
+ },
+ {
+ property = hintsLimit;
+ type = integer;
+ default = 3;
+ name = "Hints Limit";
+ category = "Basic Settings";
+ description =
+ "Maximum number of hints the student will receive from failed reference
+ tests.";
+ },
+ {
+ property = minCoverageLevel;
+ type = double;
+ name = "Minimum Test Coverage for Hints";
+ category = "Basic Settings";
+ description =
+ "If students are required to submit tests, this value is a minimum test
+ coverage threshold that must be achieved in order for any hints to be
+ given. It should be a number between 0.0-100.0 representing the minimum
+ percent coverage required to see hints.";
+ },
+ {
+ property = junitErrorsHideHints;
+ type = boolean;
+ default = false;
+ name = "Clean JUnit Tests Required for Hints";
+ category = "Basic Settings";
+ description =
+ "If students are required to submit tests, this option requires all test
+ case classes to be free of PMD-based JUnit style errors, such as failing
+ to include at least one test method in each test case class, failing
+ to include assert*() calls in each test case method, or using \"bogus\"
+ assertions such as assertEquals(1, 1).";
+ },
+ {
+ property = hideHintsWithin;
+ advanced = true;
+ type = integer;
+ default = 0;
+ name = "Hide Hints X Days Before Deadline";
+ category = "Basic Settings";
+ description =
+ "Suppress all hints from failed reference tests for submissions within this
+ many days of the deadline (set to zero for hints to always be visible).
+ This setting allows the instructor to \"hide\" hints close to the assignment
+ deadline in an attempt to encourage students to start working earlier.";
+ },
+ {
+ property = showHintsWithin;
+ advanced = true;
+ type = integer;
+ default = 0;
+ name = "Show Hints X Days Before Deadline";
+ category = "Basic Settings";
+ description =
+ "Show hints (up to the Hints Limit) from failed reference tests for
+ submissions within this many days of the deadline (only useful when Hide
+ Hints X Days Before Deadline is non-zero, to restore hints as the
+ deadline approaches).";
+ },
+ {
+ property = wantPDF;
+ type = boolean;
+ default = false;
+ name = "Generate PDF Printouts";
+ category = "Basic Settings";
+ description =
+ "Set to true if you wish for a single PDF file containing a pretty-printed
+ source code printout to be generated from the student's code. The printout
+ will be downloadable by students, and accessible by TAs during grading.
+ Note: This option uses both enscript and
+ ps2pdf as external commands, and requires these programs to
+ be correctly installed and configured.";
+ },
+/*
+ {
+ property = enscriptStyle;
+ type = shortText;
+ size = 15;
+ default = "msvc";
+ name = "PDF Formatting Style (for Enscript)";
+ category = "Basic Settings";
+ description =
+ "If you are generating PDF printouts, you can specify the formatting style
+ used by enscript. This name will be passed to
+ enscript using its --style= parameter. See your
+ enscript documentation for more information about the styles that are
+ supported. Many enscript installations support the following styles:
+ a2ps, emacs, emacs-verbose,
+ ifh, and msvc. It is possible to add your
+ own custom formatting definitions to your enscript installation and then
+ use your own style name here as well.";
+ },
+*/
+ {
+ property = wantClassDiagrams;
+ type = boolean;
+ default = true;
+ name = "Generate Class Diagrams";
+ category = "Basic Settings";
+ description =
+ "Set to true if you wish to generate class diagrams from students' code.
+ The diagrams will be viewable by students, and accessible by TAs during
+ grading. Note: This option uses both doxygen and
+ dot as external commands, and requires these programs to
+ be correctly installed and configured in the JavaTddPlugin's global
+ configuration options.";
+ },
+ {
+ property = debug;
+ type = integer;
+ advanced = true;
+ default = 0;
+ name = "Debug Level";
+ category = "Developer Settings";
+ description =
+ "Set to a non-zero value for the script to produce debugging output (the
+ larger the number, the greater the detail, up to about 5). Debugging output
+ on each grading script run will be e-mailed to the instructor.";
+ },
+ {
+ property = doNotDelete;
+ type = antBoolean;
+ advanced = true;
+ name = "Preserve Derived Files";
+ category = "Developer Settings";
+ description =
+ "Set to true to prevent the plug-in from deleting the derived files it
+ creates during the build/test process for each submission. Normally, these
+ files are deleted when a given submission has been completely processed.
+ This setting is provided for debugging purposes, when one wishes to
+ inspect the intermediate test driver source code or other derived files.";
+ },
+ {
+ property = generateHeatmaps;
+ type = antBoolean;
+ advanced = true;
+ name = "Generate Bug Heatmaps";
+ category = "Developer Settings";
+ description =
+ "Set to true to generate GZoltar-based defect heatmaps. This option is
+ experimental and for research use only. Using it will slow down
+ generation of student feedback.";
+ },
+ {
+ property = useEnhancedFeedback;
+ type = boolean;
+ advanced = true;
+ default = false;
+ name = "Use Enhanced Feedback (Experimental)";
+ category = "Developer Settings";
+ description =
+ "Set to true to use the new (experimental) enhanced feedback layout.";
+ },
+ {
+ property = useIndicatorFeedback;
+ type = boolean;
+ advanced = true;
+ default = false;
+ name = "Use Growth Mindset Feedback (Experimental)";
+ category = "Developer Settings";
+ description =
+ "Set to true to use the new (experimental) growth mindset progress feedback.";
+ },
+ {
+ property = useMaria;
+ type = boolean;
+ advanced = true;
+ default = false;
+ name = "Use Maria (Experimental)";
+ category = "Developer Settings";
+ description =
+ "Set to true to show Maria (experimental), the virtual teaching assistant
+ chatbot.";
+ },
+ {
+ property = useMariaExplanations;
+ type = boolean;
+ advanced = true;
+ default = false;
+ name = "Use Maria Explanations (Experimental)";
+ category = "Developer Settings";
+ description =
+ "Set to true to show \"Explain...\" links (experimental) by error messages.";
+ },
+ {
+ property = useDailyMissions;
+ type = boolean;
+ advanced = true;
+ default = false;
+ name = "Use Daily Missions (Experimental)";
+ category = "Developer Settings";
+ description =
+ "Set to true to give students daily mission challenges (experimental).";
+ },
+ {
+ property = showAllTestOutcomes;
+ type = boolean;
+ advanced = true;
+ default = false;
+ name = "Show All Test Outcomes (Experimental)";
+ category = "Developer Settings";
+ description =
+ "Set to true to use the new (experimental) feature to show all test outcomes
+ instead of limited hints. Students still need to meet the coverage
+ requirements and other requirements to see test outcomes, but will see
+ the full table of tests instead of limited hints.";
+ },
+ {
+ property = useFindBugs;
+ type = boolean;
+ advanced = true;
+ default = false;
+ name = "Use FindBugs (Experimental)";
+ category = "Developer Settings";
+ description =
+ "Set to true to add FindBugs analysis to the static analysis scoring of
+ the assignment. This will cause FindBugs to be run on student submissions,
+ and the results will be used to give feedback to students. Not all FindBugs
+ warnings/errors will be shown--the specific list used is research-driven.
+ There currently are no controls for changing the scoring scheme or enabling
+ or disabling specific FindBugs checks.";
+ },
+ {
+ property = usePit;
+ type = antBoolean;
+ advanced = true;
+ default = false;
+ name = "Use PIT Mutation Analysis (Experimental)";
+ category = "Developer Settings";
+ description =
+ "Set to true to turn on mutation analysis for evaluating student-written
+ test suites. This is highly experimental and not advised for production
+ use except in research settings.";
+ },
+ {
+ property = useEMRN;
+ type = antBoolean;
+ advanced = true;
+ default = false;
+ name = "Use EMRN Grading (Experimental)";
+ category = "Developer Settings";
+ description =
+ "Set to true to turn on EMRN grading scale support instead of points.";
+ },
+ {
+ property = useJdk11;
+ type = boolean;
+ advanced = true;
+ default = false;
+ name = "Use Java 11 (Experimental)";
+ category = "Developer Settings";
+ description =
+ "Set to true to switch to Java 11.";
+ }
+ );
+ globalOptions = (
+ {
+ property = doxygenDir;
+ type = shortText;
+ size = 40;
+ name = "Doxygen Directory";
+ description =
+ "The directory on the local server that contains the Doxygen executable.
+ Doxygen (and Dot, below) are used to generate class diagrams for the code
+ that students submit; if you do not have a copy of Doxygen or wish to
+ disable diagram generation across all assignments, you can leave this
+ field blank. If you are not the user administering this Web-CAT server,
+ you will need to have your system administrator install this tool and set
+ this path if you wish to use it.";
+ },
+ {
+ property = dotDir;
+ type = shortText;
+ size = 40;
+ name = "Dot Directory";
+ description =
+ "The directory on the local server that contains the Dot executable (from
+ the Graphviz package). Dot (and Doxygen, above) are used to generate
+ class diagrams for the code that students submit; if you do not have a copy
+ of Dot or wish to disable diagram generation across all assignments, you can
+ leave this field blank. If you are not the user administering this Web-CAT
+ server, you will need to have your system administrator install this tool
+ and set this path if you wish to use it.";
+ }
+ );
+}
diff --git a/src/execute.pl b/src/execute.pl
index 90b57c3..2798f12 100644
--- a/src/execute.pl
+++ b/src/execute.pl
@@ -52,6 +52,7 @@
filePattern
copyHere
htmlEscape
+ smartHtmlEscape
addReportFile
scanTo
scanThrough
@@ -70,6 +71,7 @@
compilerErrorEnhancedMessage
setResultDir
codingStyleMessageValue
+ findBugsMessage
);
use Web_CAT::Indicators::ProgressTracker;
use Web_CAT::Indicators::ProgressCommenter;
@@ -101,6 +103,16 @@
if ($useDailyMissions) { $useIndicatorFeedback = 1; }
my $showAllTestOutcomes = $cfg->getProperty('showAllTestOutcomes', 0);
$showAllTestOutcomes = ($showAllTestOutcomes =~ m/^(true|on|yes|y|1)$/i);
+my $useFindBugs = $cfg->getProperty('useFindBugs', 0);
+$useFindBugs = ($useFindBugs =~ m/^(true|on|yes|y|1)$/i);
+if ($useFindBugs) { $cfg->setProperty('enableFindBugs', 'true'); }
+my $usePit = $cfg->getProperty('usePit', 0);
+$usePit = ($usePit =~ m/^(true|on|yes|y|1)$/i);
+if ($usePit) { $cfg->setProperty('enablePit', 'true'); }
+my $useEMRN = $cfg->getProperty('useEMRN', 0);
+$useEMRN = ($useEMRN =~ m/^(true|on|yes|y|1)$/i);
+my $useJdk11 = $cfg->getProperty('useJdk11', 0);
+$useJdk11 = ($useJdk11 =~ m/^(true|on|yes|y|1)$/i);
my $allTestOutcomeResults = '';
my $allTestOutcomesLeader = '';
my $progressTracker = new Web_CAT::Indicators::ProgressTracker($cfg);
@@ -324,6 +336,10 @@
#-------------------------------------------------------
# In addition, some local definitions within this script
#-------------------------------------------------------
+if ($useJdk11)
+{
+ $ENV{JAVA_HOME} = '/usr/java/jdk-11';
+}
Web_CAT::Utilities::initFromConfig($cfg);
if (defined($ENV{JAVA_HOME}))
{
@@ -333,6 +349,10 @@
. $Web_CAT::Utilities::PATH_SEPARATOR . $ENV{PATH};
}
+# overide TMPDIR to keep temp files local
+$ENV{TMPDIR} = "${workingDir}/local_tmp";
+if (! -d "$ENV{TMPDIR}") { mkdir("$ENV{TMPDIR}"); }
+
die "ANT_HOME environment variable is not set! (Should come from ANTForPlugins)"
if !defined($ENV{ANT_HOME});
$ENV{PATH} =
@@ -373,6 +393,7 @@
my $coverageGoal =
$cfg->getProperty('coverageGoal', 100.0);
if ($coverageGoal <= 0) { $coverageGoal = 100; }
+my $printableCoverageGoal = $coverageGoal;
if ($coverageGoal >= 1) { $coverageGoal /= 100.0; }
my $useXvfb =
@@ -386,11 +407,19 @@
$cfg->getProperty('allStudentTestsMustPass', 0);
$allStudentTestsMustPass =
($allStudentTestsMustPass =~ m/^(true|on|yes|y|1)$/i);
+my $includeStudentTestsInGrading =
+ $cfg->getProperty('includeStudentTestsInGrading', 0);
+$includeStudentTestsInGrading =
+ ($includeStudentTestsInGrading =~ m/^(true|on|yes|y|1)$/i);
my $studentsMustSubmitTests =
$cfg->getProperty('studentsMustSubmitTests', 0);
$studentsMustSubmitTests =
($studentsMustSubmitTests =~ m/^(true|on|yes|y|1)$/i);
-if (!$studentsMustSubmitTests) { $allStudentTestsMustPass = 0; }
+if (!$studentsMustSubmitTests)
+{
+ $allStudentTestsMustPass = 0;
+ $includeStudentTestsInGrading = 0;
+}
my $includeTestSuitesInCoverage =
$cfg->getProperty('includeTestSuitesInCoverage', 0);
$includeTestSuitesInCoverage =
@@ -908,7 +937,7 @@ sub generateCompilerErrorWarningStruct
$fileName =~ s,\\,/,go;
my $lineNum = $fileDetails[1];
my $codeLines = extractAboveBelowLinesOfCode($fileName, $lineNum);
- $fileName =~ s,^\Q$workingDir/\E,,i;
+ $fileName =~ s,^.*\Q$workingDir/\E,,i;
# For compiler warning we dont have enhanced messages
# For "cannot find symbol" errors, "addCannotFindSymbolStruct" computes
@@ -1281,7 +1310,7 @@ sub addCannotFindSymbolStruct
#=============================================================================
-# Load checkstyle and PMD reports into internal data structures
+# Load checkstyle, PMD, and FindBugs reports into internal data structures
#=============================================================================
# The configuration file for scoring tool messages
@@ -1603,6 +1632,7 @@ sub markStyleSection
# violation: the XML::Smart structure referring to the violation
# (used for error message printing only)
#
+my $debugTracking = 0;
sub trackMessageInstance
{
croak 'usage: recordPMDMessageStats(rule, fileName, violation)'
@@ -1616,6 +1646,16 @@ sub trackMessageInstance
* $toolDeductionScaleFactor;
my $overLimit = 0;
+ if ($debug > 2 || $debugTracking)
+ {
+ print "trackMessageInstance($rule, $fileName, ...)\n";
+ my $msg = $violation->data_pointer(noheader => 1, nometagen => 1);
+ if (defined $msg)
+ {
+ print $msg;
+ }
+ }
+
if (!$violation->{line}->content
&& $violation->{endline}->content)
{
@@ -1844,7 +1884,7 @@ sub trackMessageInstance
next if ($file->{name}->null);
my $fileName = $file->{name}->content;
$fileName =~ s,\\,/,go;
- $fileName =~ s,^\Q$workingDir/\E,,i;
+ $fileName =~ s,^.*\Q$workingDir/\E,,i;
if (!defined $codeMarkupIds{$fileName})
{
$codeMarkupIds{$fileName} = ++$numCodeMarkups;
@@ -1875,7 +1915,7 @@ sub trackMessageInstance
next if ($file->{name}->null);
my $fileName = $file->{name}->content;
$fileName =~ s,\\,/,go;
- $fileName =~ s,^\Q$workingDir/\E,,i;
+ $fileName =~ s,^.*\Q$workingDir/\E,,i;
if (!defined $codeMarkupIds{$fileName})
{
$codeMarkupIds{$fileName} = ++$numCodeMarkups;
@@ -1891,8 +1931,137 @@ sub trackMessageInstance
}
}
+ my $findBugsLog = "$resultDir/findbugs.xml";
+ if (-f $findBugsLog)
+ {
+ my $fb = XML::Smart->new($findBugsLog);
+# print "parsed findbugs =\n", $fb->data(noheader => 1, nometagen => 1), "\n";
+ # First, pull long error details
+ my %msgs = ();
+ foreach my $pat (@{ $fb->{BugCollection}{BugPattern} })
+ {
+ my $detail = $pat->{Details}->content;
+ $detail =~ s/^\s+|\s+$//gso;
+ $detail =~ s/^$1<\/code>?/;
+ $msg .= ' ' . $v;
+ }
+ elsif ($v =~ m/named\s+(\S+)\s*$/o)
+ {
+ $v = $1;
+ $msg =~ s/\Q$v\E/$v<\/code>/g;
+ }
+ }
+
+ # highlight method name, if there is one
+ my $method = $bug->{Method}{Message};
+ if (!$method->null)
+ {
+ $method = htmlEscape($method->content);
+ if ($method =~ m/[Mm]ethod\s+(\S+)\s*$/o)
+ {
+ $method = $1;
+ $msg =~ s/\Q$method\E/$method<\/code>/g;
+ }
+ }
+
+ # Add field message, if there is one
+ my $field = $bug->{Field}{Message};
+ if (!$field->null)
+ {
+ my $fmsg = htmlEscape($field->content);
+ if ($fmsg =~ m/^\s*Did/so)
+ {
+ $fmsg =~ s/field\s+(\S+)\?\s*$/field $1<\/code>?/;
+ $msg .= ' ' . $fmsg;
+ }
+ elsif ($fmsg =~ m/[Ff]ield\s+(\S+)\s*$/o)
+ {
+ $fmsg = $1;
+ $msg =~ s/\Q$fmsg\E/$fmsg<\/code>/g;
+ }
+ }
+
+ my $fileName = '';
+ $bug->{beginline} =
+ $bug->{SourceLine}{start}->content
+ || $bug->{Method}{SourceLine}{start}->content
+ || $bug->{Field}{SourceLine}{start}->content
+ || $bug->{Class}{SourceLine}{start}->content
+ || 1;
+ $bug->{endline} =
+ $bug->{SourceLine}{end}->content
+ || $bug->{Method}{SourceLine}{end}->content
+ || $bug->{Field}{SourceLine}{end}->content
+ || $bug->{Class}{SourceLine}{end}->content
+ || $bug->{beginline}->content;
+ $fileName =
+ $bug->{SourceLine}{sourcepath}->content
+ || $bug->{Method}{SourceLine}{sourcepath}->content
+ || $bug->{Field}{SourceLine}{sourcepath}->content
+ || $bug->{Class}{SourceLine}{sourcepath}->content;
+ $fileName =~ s,\\,/,go;
+ $fileName =~ s,^.*\Q$workingDir/\E,,i;
+ if ($fileName ne '' && ! -f $fileName && -f 'src/' . $fileName)
+ {
+ $fileName = 'src/' . $fileName;
+ }
+ if ($msg ne '') { $msg = '
You can improve your testing by looking for any
lines highlighted in this color
in your code listings above. Such lines have not been sufficiently
@@ -3827,6 +4140,9 @@ sub generateCompleteErrorStruct
my $errorMessage = shift;
my $enhancedMessage = shift || '';
+ carp "no line number provided"
+ if !defined($lineNum) || $lineNum eq '';
+
my $codeLines = extractAboveBelowLinesOfCode($fileName, $lineNum);
my $errorStruct = expandedMessage->new(
@@ -3870,7 +4186,10 @@ sub generateCompleteErrorStruct
#print $c->{rule}->content;
#print("\n");
- my $lineNum = $c->{line}->content;
+ my $lineNum =
+ $c->{line}->null
+ ? $c->{beginline}->content
+ : $c->{line}->content;
# This is the case of "TestsHaveAssertions" rule from pmd
# where beginline is the one which contains the declaration
@@ -3881,6 +4200,12 @@ sub generateCompleteErrorStruct
{
$lineNum = $c->{beginline}->content;
}
+
+ if (!defined($lineNum) || $lineNum eq '' )
+ {
+ print "no line number found in:\n",
+ $c->data_pointer(noheader => 1, nometagen => 1), "\n";
+ }
my $codingStyleStruct = generateCompleteErrorStruct(
$ff, $lineNum, $message);
@@ -4913,7 +5238,7 @@ sub groupStructsByFileName
#=============================================================================
# generate score explanation for student
#=============================================================================
-if ($can_proceed && $studentsMustSubmitTests)
+if ($can_proceed && $studentsMustSubmitTests && !$useEMRN)
{
my $scoreToTenths = int($runtimeScore * 10 + 0.5) / 10;
my $possible = int($maxCorrectnessScore * 10 + 0.5) / 10;
@@ -4922,17 +5247,36 @@ sub groupStructsByFileName
. "($scoreToTenths/$possible)",
++$expSectionId,
1);
+ my $covLabel = ($usePit ? "Mutants detected by" : "Code coverage from");
$status{'feedback'}->print(< ',
- htmlEscape($errorStruct->errorMessage), ' ';
+ smartHtmlEscapeAndPeel($errorStruct->errorMessage), ' ';
my $msg = '';
@@ -5376,7 +5734,8 @@ sub computeExpandSectionId
if ($errorStruct->enhancedMessage)
{
print IMPROVEDFEEDBACKFILE ' ',
- htmlEscape($errorStruct->enhancedMessage), ' ', htmlEscape($errorStruct->errorMessage),
+ ' ',
+ smartHtmlEscapeAndPeel($errorStruct->errorMessage),
' ';
my $msg = '';
@@ -5563,7 +5924,8 @@ sub computeExpandSectionId
if ($errorStruct->enhancedMessage)
{
print IMPROVEDFEEDBACKFILE ' ',
- htmlEscape($errorStruct->enhancedMessage), ' Fix Unit Test Coding Problems '
. '(see above) for behavioral analysis. Your own software tests must be included for '
@@ -5732,7 +6095,8 @@ sub computeExpandSectionId
foreach my $errorStruct (@{$behaviorSectionExpanded{$element}})
{
print IMPROVEDFEEDBACKFILE ' ', htmlEscape($errorStruct->errorMessage), ' ';
+ ' ',
+ smartHtmlEscapeAndPeel($errorStruct->errorMessage), ' ';
my $msg = Web_CAT::Maria::explainButton(
runtimeErrorHintKey($errorStruct->errorMessage),
$useMariaExplanations);
@@ -5763,7 +6127,8 @@ sub computeExpandSectionId
if ($errorStruct->enhancedMessage)
{
print IMPROVEDFEEDBACKFILE ' ',
- htmlEscape($errorStruct->enhancedMessage), ' ', htmlEscape($errorStruct->errorMessage),
+ ' ',
+ smartHtmlEscapeAndPeel($errorStruct->errorMessage),
" ',
- htmlEscape($errorStruct->enhancedMessage), ' The == operator compares the memory addresses of two ' . htmlEscape($msg) . ' '
+# }
+# }
+
+ return '';
+}
+
sub setResultDir
{
$resultDir = shift;
diff --git a/src/perllib/Web_CAT/ExpandedFeedbackUtil.pm b/src/perllib/Web_CAT/ExpandedFeedbackUtil.pm
index 7a6d416..0fe0a48 100644
--- a/src/perllib/Web_CAT/ExpandedFeedbackUtil.pm
+++ b/src/perllib/Web_CAT/ExpandedFeedbackUtil.pm
@@ -38,6 +38,10 @@ sub extractAboveBelowLinesOfCode
my $filePath = shift;
my $errorLineNum = shift;
+ carp "no error line provided"
+ if !defined($errorLineNum) || $errorLineNum eq '';
+
+
if (!defined $filePath)
{
# cluck, but on stdout
diff --git a/src/pit/README.md b/src/pit/README.md
new file mode 100644
index 0000000..e1e7f45
--- /dev/null
+++ b/src/pit/README.md
@@ -0,0 +1,9 @@
+# VT Pit Selective Mutators JARs:
+
+This is the Pit version which uses the Selective Mutator Operators as part of the research conducted by the Digital Education Lab in Virginia Tech.
+The Selective Mutator Operators are by default:
+- AOD (Arithmetic Operator Deletion)
+- RemoveConditionals
+
+The folder "required JARs for IDE plugin" contains the three necessary JARs required for modified PitClipse IDE plugin.
+
diff --git a/src/plugin-rulesets/design.xml b/src/plugin-rulesets/design.xml
index 1f356f8..4962342 100644
--- a/src/plugin-rulesets/design.xml
+++ b/src/plugin-rulesets/design.xml
@@ -69,9 +69,10 @@
-
-Results from running your tests:
$studentCasesPercent% Code coverage from your tests:
+
+EOF
+ if ($coverageGoal < 1)
+ {
+ $status{'feedback'}->print(<$covLabel your tests:
$codeCoveragePercent% Coverage goal for full credit:
+$printableCoverageGoal%
+EOF
+ }
+ $status{'feedback'}->print(<Estimate of problem coverage:
$instructorCasesPercent%
score =
-$studentCasesPercent%
-* $codeCoveragePercent%
+EOF
+ if ($includeStudentTestsInGrading)
+ {
+ $status{'feedback'}->print(" $studentCasesPercent% * ");
+ }
+ $status{'feedback'}->print("$codeCoveragePercent% ");
+ if ($coverageGoal < 1)
+ {
+ $status{'feedback'}->print("/ $printableCoverageGoal% ");
+ }
+ $status{'feedback'}->print(< ', $errorStruct->entityName, '
', $errorStruct->entityName, '
',
- '', $errorStruct->entityName, '
',
- '', $errorStruct->entityName, '
',
- 'Strings. Use equals() instead.