├── autograder ├── src │ ├── test │ │ ├── resources │ │ │ └── comp215-build │ │ │ │ ├── logs │ │ │ │ ├── success.log │ │ │ │ ├── whitespace-success.log │ │ │ │ ├── testfail.log │ │ │ │ └── mainfail.log │ │ │ │ ├── google-java-format │ │ │ │ └── 0.8 │ │ │ │ │ └── settings.txt │ │ │ │ ├── weirder-broken-google-java-format │ │ │ │ ├── 0.8 │ │ │ │ │ └── settings.txt │ │ │ │ └── Version=1.1.1 Build_time=2019-10-09T13:00:48Z │ │ │ │ │ └── settings.txt │ │ │ │ ├── weird-google-java-format │ │ │ │ └── Version=1.1.1 Build_time=2019-10-09T13:00:48Z │ │ │ │ │ └── settings.txt │ │ │ │ └── test-results │ │ │ │ └── test │ │ │ │ ├── TEST-edu.rice.lens.ListLens.xml │ │ │ │ ├── TEST-edu.rice.lens.TimeExample.xml │ │ │ │ ├── TEST-edu.rice.lens.MonkeyExample.xml │ │ │ │ ├── TEST-edu.rice.week2lists.MListTest.xml │ │ │ │ ├── TEST-edu.rice.week9lenses.Week9Lab.xml │ │ │ │ ├── TEST-edu.rice.week8turtle.TurtleTest.xml │ │ │ │ ├── TEST-edu.rice.github.EventsApiTests.xml │ │ │ │ ├── TEST-edu.rice.util.DoubleTrouble.xml │ │ │ │ ├── TEST-edu.rice.io.JsonResourceIOTest.xml │ │ │ │ ├── TEST-edu.rice.util.DoubleTheories.xml │ │ │ │ ├── TEST-edu.rice.prettypictures.GeneTreeTheories.xml │ │ │ │ ├── TEST-edu.rice.week10covariance.CarsAndLensesTest.xml │ │ │ │ ├── TEST-edu.rice.regex.MatcherTest.xml │ │ │ │ ├── TEST-edu.rice.util.OptionLiftTest.xml │ │ │ │ ├── TEST-edu.rice.week2cars.ModelTest.xml │ │ │ │ ├── TEST-edu.rice.week2subsets.SubsetsTest.xml │ │ │ │ ├── TEST-edu.rice.image.ImagesTest.xml │ │ │ │ ├── TEST-edu.rice.json.BuildersTest.xml │ │ │ │ ├── TEST-edu.rice.week2primes.PrimesTest.xml │ │ │ │ ├── TEST-edu.rice.week3subsets.SubsetsTest.xml │ │ │ │ ├── TEST-edu.rice.week12mockito.Week12LabTest.xml │ │ │ │ ├── TEST-edu.rice.week10covariance.Week10LabTest.xml │ │ │ │ ├── TEST-edu.rice.week5sorting.HeapSorterTest.xml │ │ │ │ ├── TEST-edu.rice.util.StringsTest.xml │ │ │ │ ├── TEST-edu.rice.tree.BinaryHeapTest.xml │ │ │ │ ├── TEST-edu.rice.week1hangman.HangmanTest.xml │ │ │ │ ├── TEST-edu.rice.tree.TreeToListLaziness.xml │ │ │ │ ├── TEST-edu.rice.week3lists.Week3Filters.xml │ │ │ │ ├── TEST-edu.rice.week2cars.DreamGarageTest.xml │ │ │ │ ├── TEST-edu.rice.week10covariance.CarExamplesTest.xml │ │ │ │ ├── TEST-edu.rice.week2lists.ObjectListTest.xml │ │ │ │ ├── TEST-edu.rice.prettypictures.ExternalImageAllelesTest.xml │ │ │ │ ├── TEST-edu.rice.week6counting.FreqCountTest.xml │ │ │ │ ├── TEST-edu.rice.util.HelpersTest.xml │ │ │ │ ├── TEST-edu.rice.json.LensTest.xml │ │ │ │ ├── TEST-edu.rice.prettypictures.TestGenesWeek3Test.xml │ │ │ │ ├── TEST-edu.rice.dynamic.MemoizedBiFunctionTest.xml │ │ │ │ ├── TEST-edu.rice.vavr.VavrHelperTests.xml │ │ │ │ ├── TEST-edu.rice.json.ValueTheories.xml │ │ │ │ ├── TEST-edu.rice.week4subsets.SubsetsTest.xml │ │ │ │ ├── TEST-edu.rice.prettypictures.RandomGeneTreeTest.xml │ │ │ │ ├── TEST-edu.rice.prettypictures.GeneTreeLensTests.xml │ │ │ │ ├── TEST-edu.rice.week5knapsack.KnapsackTest.xml │ │ │ │ ├── TEST-edu.rice.regex.RegexScannerTest.xml │ │ │ │ ├── TEST-edu.rice.sexpr.SimpleParserTest.xml │ │ │ │ ├── TEST-edu.rice.dynamic.MemoizedFunctionTest.xml │ │ │ │ ├── TEST-edu.rice.week1intro.StringThingTest.xml │ │ │ │ ├── TEST-edu.rice.json.ScannerTest.xml │ │ │ │ ├── TEST-edu.rice.prettypictures.RgbColorTest.xml │ │ │ │ ├── TEST-edu.rice.week3lists.Week3Project.xml │ │ │ │ ├── TEST-edu.rice.json.OperationsTest.xml │ │ │ │ ├── TEST-edu.rice.week13newspaper.DBTest.xml │ │ │ │ ├── TEST-edu.rice.week2cars.ManufacturerTest.xml │ │ │ │ ├── TEST-edu.rice.cparser.ParserFunctionTest.xml │ │ │ │ ├── TEST-edu.rice.week3lists.GListTest.xml │ │ │ │ ├── TEST-edu.rice.prettypictures.AlleleTest.xml │ │ │ │ ├── TEST-edu.rice.week4queue.ListQueueTest.xml │ │ │ │ ├── TEST-edu.rice.util.OptionTest.xml │ │ │ │ ├── TEST-edu.rice.cparser.SexprTest.xml │ │ │ │ ├── TEST-edu.rice.week5sorting.SortPerformance.xml │ │ │ │ ├── TEST-edu.rice.rpn.RpnCalculatorTestPrivate.xml │ │ │ │ ├── TEST-edu.rice.rpn.RpnCalculatorTest.xml │ │ │ │ ├── TEST-edu.rice.json.ParserTest.xml │ │ │ │ ├── TEST-edu.rice.stream.StreamHelpersTest.xml │ │ │ │ ├── TEST-edu.rice.tree.TreePerformance.xml │ │ │ │ ├── TEST-edu.rice.sexpr.SimpleScannerTest.xml │ │ │ │ ├── TEST-edu.rice.util.LogTest.xml │ │ │ │ └── TEST-edu.rice.prettypictures.TestGenesWeek1Test.xml │ │ ├── java │ │ │ └── edu │ │ │ │ └── rice │ │ │ │ └── autogradertest │ │ │ │ ├── Project3.java │ │ │ │ ├── package-info.java │ │ │ │ ├── TestProject2.java │ │ │ │ ├── TestProject1.java │ │ │ │ └── TestProject3.java │ │ └── kotlin │ │ │ └── edu │ │ │ └── rice │ │ │ └── autograder │ │ │ ├── CheckStyleResultsScannerTest.kt │ │ │ ├── WordWrapTest.kt │ │ │ ├── CompilerLogScannerTest.kt │ │ │ ├── GoogleJavaFormatScannerTest.kt │ │ │ ├── JUnitSuiteScannerTest.kt │ │ │ └── VerifyTestAnnotations.kt │ └── main │ │ ├── resources │ │ └── logback.xml │ │ ├── kotlin │ │ └── edu │ │ │ └── rice │ │ │ └── autograder │ │ │ ├── WordWrap.kt │ │ │ ├── CompilerLogScanner.kt │ │ │ ├── GradeProjectIO.kt │ │ │ ├── JacksonHelpers.kt │ │ │ ├── ArrowHelpers.kt │ │ │ ├── GoogleJavaFormatScanner.kt │ │ │ ├── CheckStyleScanner.kt │ │ │ └── EvaluatorResult.kt │ │ └── java │ │ └── edu │ │ └── rice │ │ └── autograder │ │ └── annotations │ │ ├── Grades.java │ │ ├── GradeTopics.java │ │ ├── GradeCoverages.java │ │ ├── GradeProjects.java │ │ ├── GradeCoverage.java │ │ ├── GradeTopic.java │ │ ├── Grade.java │ │ └── GradeProject.java └── .editorconfig ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle ├── exampleRpn ├── README.md ├── config │ └── grade.yml ├── src │ ├── test │ │ └── java │ │ │ └── edu │ │ │ └── rice │ │ │ └── rpn │ │ │ └── RpnCalcTest.java │ └── main │ │ └── java │ │ └── edu │ │ └── rice │ │ └── rpn │ │ └── RpnCalc.java └── build.gradle ├── .github └── workflows │ └── ricechecks-ci.yml ├── exampleSort ├── README.md ├── src │ ├── main │ │ └── java │ │ │ └── edu │ │ │ └── rice │ │ │ └── sort │ │ │ ├── package-info.java │ │ │ ├── Sorter.java │ │ │ ├── InsertionSort.java │ │ │ ├── ShellSort.java │ │ │ ├── HeapSort.java │ │ │ └── PatienceSort.java │ └── test │ │ └── java │ │ └── edu │ │ └── rice │ │ └── sort │ │ ├── HeapSortTest.java │ │ ├── ShellSortTest.java │ │ ├── PatienceSortTest.java │ │ ├── InsertionSortTest.java │ │ └── TestAnySorter.java ├── config │ └── grade.yml └── build.gradle ├── exampleRegex ├── README.md ├── config │ └── grade.yml ├── src │ ├── main │ │ └── java │ │ │ └── edu │ │ │ └── rice │ │ │ └── regex │ │ │ └── Patterns.java │ └── test │ │ └── java │ │ └── edu │ │ └── rice │ │ └── regex │ │ └── TestPatterns.java └── build.gradle ├── standaloneSort ├── README.md ├── src │ ├── main │ │ └── java │ │ │ └── edu │ │ │ └── rice │ │ │ └── sort │ │ │ ├── package-info.java │ │ │ ├── Sorter.java │ │ │ ├── InsertionSort.java │ │ │ ├── ShellSort.java │ │ │ ├── HeapSort.java │ │ │ └── PatienceSort.java │ └── test │ │ └── java │ │ └── edu │ │ └── rice │ │ └── sort │ │ ├── HeapSortTest.java │ │ ├── ShellSortTest.java │ │ ├── PatienceSortTest.java │ │ ├── InsertionSortTest.java │ │ └── TestAnySorter.java ├── config │ └── grade.yml └── build.gradle ├── run-github-actions.sh └── gradlew.bat /autograder/src/test/resources/comp215-build/logs/success.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/logs/whitespace-success.log: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiceComp215-Staff/RiceChecks/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/google-java-format/0.8/settings.txt: -------------------------------------------------------------------------------- 1 | #Generated; DO NOT CHANGE!!! 2 | #Mon Mar 25 10:13:02 CDT 2019 3 | toolVersion=1.7 4 | options= 5 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/weirder-broken-google-java-format/0.8/settings.txt: -------------------------------------------------------------------------------- 1 | #Generated; DO NOT CHANGE!!! 2 | #Mon Mar 25 10:13:02 CDT 2019 3 | toolVersion=1.7 4 | options= 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | *.swp 4 | *.class 5 | build 6 | out 7 | .gradle 8 | .idea 9 | *.iml 10 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/weird-google-java-format/Version=1.1.1 Build_time=2019-10-09T13:00:48Z/settings.txt: -------------------------------------------------------------------------------- 1 | #Generated; DO NOT CHANGE!!! 2 | #Mon Mar 25 10:13:02 CDT 2019 3 | toolVersion=1.7 4 | options= 5 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/weirder-broken-google-java-format/Version=1.1.1 Build_time=2019-10-09T13:00:48Z/settings.txt: -------------------------------------------------------------------------------- 1 | #Generated; DO NOT CHANGE!!! 2 | #Mon Mar 25 10:13:02 CDT 2019 3 | toolVersion=1.7 4 | options= 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | rootProject.name = 'RiceChecks' 8 | 9 | include ':autograder' 10 | include ':exampleRegex' 11 | include ':exampleRpn' 12 | include ':exampleSort' 13 | include ':standaloneSort' 14 | -------------------------------------------------------------------------------- /exampleRpn/README.md: -------------------------------------------------------------------------------- 1 | # RiceChecks: exampleRpn 2 | 3 | In this hypothetical project, students are asked to implement a simple RPN calculator; 4 | there are many cases, so we require minimum test coverage. 5 | 6 | To play with this outside of the RiceChecks codebase, check out the standalone version of this project: 7 | - https://github.com/RiceComp215-Staff/RiceChecks-RpnExample -------------------------------------------------------------------------------- /.github/workflows/ricechecks-ci.yml: -------------------------------------------------------------------------------- 1 | name: RiceChecks Autograder 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: Set up Java8 13 | uses: actions/setup-java@v1 14 | with: 15 | java-version: 1.8 16 | - name: Build with Gradle 17 | run: sh run-github-actions.sh 18 | -------------------------------------------------------------------------------- /autograder/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{kt,kts}] 2 | # possible values: number (e.g. 2), "unset" (makes ktlint ignore indentation completely) 3 | indent_size=4 4 | # true (recommended) / false 5 | insert_final_newline=true 6 | # possible values: number (e.g. 120) (package name, imports & comments are ignored), "off" 7 | # it's automatically set to 100 on `ktlint --android ...` (per Android Kotlin Style Guide) 8 | max_line_length=100 -------------------------------------------------------------------------------- /exampleSort/README.md: -------------------------------------------------------------------------------- 1 | # RiceChecks: exampleSort 2 | In this hypothetical project, students are asked to implement four sorting algorithms; 3 | their work is tested with [QuickTheories](https://github.com/quicktheories/QuickTheories), 4 | generating hundreds of random inputs. 5 | 6 | To play with this outside of the RiceChecks codebase, check out the standalone version of this project: 7 | - https://github.com/RiceComp215-Staff/RiceChecks-SortExample 8 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/logs/testfail.log: -------------------------------------------------------------------------------- 1 | :compileTestJava 2 | /Users/dwallach/IdeaProjects/comp215-code/src/test/java/edu/rice/qt/QtHelpers.java:35: error: incompatible types: int cannot be converted to T 3 | store.add(3); 4 | ^ 5 | where T is a type-variable: 6 | T extends Object declared in method qtGenOnce(Gen) 7 | Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output 8 | 1 error 9 | -------------------------------------------------------------------------------- /autograder/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | %date [%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /exampleRegex/README.md: -------------------------------------------------------------------------------- 1 | # RiceChecks: exampleRegex 2 | 3 | In this hypothetical project, students are asked to implement several regular expressions; 4 | their work is tested using JUnit5's [TestFactory](https://junit.org/junit5/docs/5.4.0/api/org/junit/jupiter/api/TestFactory.html), 5 | which has a list of examples for each regex that should be accepted and another list 6 | of examples that should be rejected by the regex. 7 | 8 | To play with this outside of the RiceChecks codebase, check out the standalone version of this project: 9 | - https://github.com/RiceComp215-Staff/RiceChecks-RegexExample 10 | -------------------------------------------------------------------------------- /standaloneSort/README.md: -------------------------------------------------------------------------------- 1 | # RiceChecks: standaloneSort 2 | In this hypothetical project, students are asked to implement four sorting algorithms; 3 | their work is tested with [QuickTheories](https://github.com/quicktheories/QuickTheories), 4 | generating hundreds of random inputs. 5 | 6 | To play with this outside of the RiceChecks codebase, check out the standalone version of this project: 7 | - https://github.com/RiceComp215-Staff/RiceChecks-SortExample 8 | 9 | That standalone version is set up to use Java11. The [build.gradle](build.gradle) file here 10 | is a suitable starting point for integrating RiceChecks into projects using Java8. 11 | -------------------------------------------------------------------------------- /exampleSort/src/main/java/edu/rice/sort/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | @ParametersAreNonnullByDefault 8 | @CheckReturnValue 9 | @GradeProject( 10 | name = "Sorting", 11 | description = "Implement Many Sorting Algorithms", 12 | warningPoints = 1.0, 13 | coveragePoints = 1.0, 14 | coveragePercentage = 90) 15 | package edu.rice.sort; 16 | 17 | import edu.rice.autograder.annotations.GradeProject; 18 | import javax.annotation.CheckReturnValue; 19 | import javax.annotation.ParametersAreNonnullByDefault; 20 | -------------------------------------------------------------------------------- /standaloneSort/src/main/java/edu/rice/sort/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | @ParametersAreNonnullByDefault 8 | @CheckReturnValue 9 | @GradeProject( 10 | name = "Sorting", 11 | description = "Implement Many Sorting Algorithms", 12 | warningPoints = 1.0, 13 | coveragePoints = 1.0, 14 | coveragePercentage = 90) 15 | package edu.rice.sort; 16 | 17 | import edu.rice.autograder.annotations.GradeProject; 18 | import javax.annotation.CheckReturnValue; 19 | import javax.annotation.ParametersAreNonnullByDefault; 20 | -------------------------------------------------------------------------------- /autograder/src/test/java/edu/rice/autogradertest/Project3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autogradertest; 8 | 9 | import edu.rice.autograder.annotations.GradeCoverage; 10 | 11 | @GradeCoverage(project = "TP3") 12 | public class Project3 { 13 | static long factorial(int n) { 14 | if (n <= 1) { 15 | return 1; 16 | } else { 17 | return n * factorial(n - 1); 18 | } 19 | } 20 | 21 | static long choose(int n, int r) { 22 | return factorial(n) / (factorial(n - r) * factorial(r)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/logs/mainfail.log: -------------------------------------------------------------------------------- 1 | :compileJava 2 | /Users/dwallach/IdeaProjects/comp215-code/src/main/java/edu/rice/vavr/Tries.java:42: error: no suitable constructor found for NullPointerException(String,int) 3 | () -> new NullPointerException("expected non-null result from supplier", 27))); 4 | ^ 5 | constructor NullPointerException.NullPointerException() is not applicable 6 | (actual and formal argument lists differ in length) 7 | constructor NullPointerException.NullPointerException(String) is not applicable 8 | (actual and formal argument lists differ in length) 9 | 1 error 10 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.lens.ListLens.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /autograder/src/main/kotlin/edu/rice/autograder/WordWrap.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | import org.davidmoten.text.utils.WordWrap 10 | 11 | /** Thin wrapper around the WordWrap library by David Moten. */ 12 | fun wordWrap(text: String, lineWidth: Int): List = 13 | ( 14 | WordWrap 15 | .from(text) 16 | .maxWidth(lineWidth) 17 | .extraWordChars("0123456789") 18 | .insertHyphens(true) 19 | .wrap() ?: "" 20 | ) 21 | .split("\n") 22 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.lens.TimeExample.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.lens.MonkeyExample.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week2lists.MListTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week9lenses.Week9Lab.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week8turtle.TurtleTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.github.EventsApiTests.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.util.DoubleTrouble.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.io.JsonResourceIOTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /autograder/src/main/java/edu/rice/autograder/annotations/Grades.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder.annotations; 8 | 9 | import java.lang.annotation.Documented; 10 | import java.lang.annotation.ElementType; 11 | import java.lang.annotation.Retention; 12 | import java.lang.annotation.RetentionPolicy; 13 | import java.lang.annotation.Target; 14 | 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.METHOD) 17 | @Documented 18 | public @interface Grades { 19 | /** When multiple Grade annotations are applied, this is what you get back. */ 20 | Grade[] value(); 21 | } 22 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.util.DoubleTheories.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.prettypictures.GeneTreeTheories.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week10covariance.CarsAndLensesTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /autograder/src/test/java/edu/rice/autogradertest/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | @GradeProject( 8 | name = "TP2", 9 | description = "Another fairly basic project", 10 | maxPoints = 10.0, 11 | warningPoints = 1.0) 12 | @GradeTopic(project = "TP2", topic = "Group1", maxPoints = 5.0) 13 | @GradeTopic(project = "TP2", topic = "Group2", maxPoints = 4.0) 14 | @GradeCoverage(project = "TP2") 15 | package edu.rice.autogradertest; 16 | 17 | import edu.rice.autograder.annotations.GradeCoverage; 18 | import edu.rice.autograder.annotations.GradeProject; 19 | import edu.rice.autograder.annotations.GradeTopic; 20 | -------------------------------------------------------------------------------- /autograder/src/main/java/edu/rice/autograder/annotations/GradeTopics.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder.annotations; 8 | 9 | import java.lang.annotation.Documented; 10 | import java.lang.annotation.ElementType; 11 | import java.lang.annotation.Retention; 12 | import java.lang.annotation.RetentionPolicy; 13 | import java.lang.annotation.Target; 14 | 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target({ElementType.TYPE, ElementType.PACKAGE}) 17 | @Documented 18 | public @interface GradeTopics { 19 | /** When multiple GradeTopic annotations are specified, this is what you get back. */ 20 | GradeTopic[] value(); 21 | } 22 | -------------------------------------------------------------------------------- /autograder/src/main/java/edu/rice/autograder/annotations/GradeCoverages.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder.annotations; 8 | 9 | import java.lang.annotation.Documented; 10 | import java.lang.annotation.ElementType; 11 | import java.lang.annotation.Retention; 12 | import java.lang.annotation.RetentionPolicy; 13 | import java.lang.annotation.Target; 14 | 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target({ElementType.TYPE, ElementType.PACKAGE}) 17 | @Documented 18 | public @interface GradeCoverages { 19 | /** When multiple GradeCoverage annotations specified, this is what you get back. */ 20 | GradeCoverage[] value(); 21 | } 22 | -------------------------------------------------------------------------------- /autograder/src/main/java/edu/rice/autograder/annotations/GradeProjects.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder.annotations; 8 | 9 | import java.lang.annotation.Documented; 10 | import java.lang.annotation.ElementType; 11 | import java.lang.annotation.Retention; 12 | import java.lang.annotation.RetentionPolicy; 13 | import java.lang.annotation.Target; 14 | 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target({ElementType.TYPE, ElementType.PACKAGE}) 17 | @Documented 18 | public @interface GradeProjects { 19 | /** When multiple GradeProject annotations are specified, this is what you get back. */ 20 | GradeProject[] value(); 21 | } 22 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.regex.MatcherTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.util.OptionLiftTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week2cars.ModelTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week2subsets.SubsetsTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.image.ImagesTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.json.BuildersTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week2primes.PrimesTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week3subsets.SubsetsTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week12mockito.Week12LabTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /exampleSort/src/main/java/edu/rice/sort/Sorter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | public interface Sorter> { 10 | /** Sorts the given data in its natural ({@link Comparable} order. */ 11 | void sortInPlace(T[] data); 12 | 13 | /** Helper method: checks whether an array is sorted in its natural ({@link Comparable}) order. */ 14 | static > boolean isSorted(T[] data) { 15 | T previous = null; 16 | 17 | for (T x : data) { 18 | if (previous != null && previous.compareTo(x) > 0) { 19 | return false; 20 | } 21 | previous = x; 22 | } 23 | 24 | return true; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /standaloneSort/src/main/java/edu/rice/sort/Sorter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | public interface Sorter> { 10 | /** Sorts the given data in its natural ({@link Comparable} order. */ 11 | void sortInPlace(T[] data); 12 | 13 | /** Helper method: checks whether an array is sorted in its natural ({@link Comparable}) order. */ 14 | static > boolean isSorted(T[] data) { 15 | T previous = null; 16 | 17 | for (T x : data) { 18 | if (previous != null && previous.compareTo(x) > 0) { 19 | return false; 20 | } 21 | previous = x; 22 | } 23 | 24 | return true; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week10covariance.Week10LabTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week5sorting.HeapSorterTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /exampleSort/src/test/java/edu/rice/sort/HeapSortTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.Grade; 10 | import edu.rice.autograder.annotations.GradeTopic; 11 | import org.junit.jupiter.api.Test; 12 | 13 | @GradeTopic(project = "Sorting", topic = "HeapSort") 14 | public class HeapSortTest { 15 | @Test 16 | @Grade(project = "Sorting", topic = "HeapSort", points = 1.0) 17 | public void heapSortStrings() { 18 | TestAnySorter.exerciseStrings(new HeapSort<>()); 19 | } 20 | 21 | @Test 22 | @Grade(project = "Sorting", topic = "HeapSort", points = 1.0) 23 | public void heapSortIntegers() { 24 | TestAnySorter.exerciseIntegers(new HeapSort<>()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /run-github-actions.sh: -------------------------------------------------------------------------------- 1 | # this script avoids a weird problem where Gradle is printing the autograder output at the wrong time 2 | 3 | export RICECHECKS_QUIET=true 4 | ./gradlew --console=plain :autograder:check autograder 5 | retVal=$? 6 | echo 7 | echo ============= exampleRegex/ 8 | echo 9 | cat exampleRegex/build/autograder/report.txt 10 | echo 11 | echo ============= exampleRpn/ 12 | echo 13 | cat exampleRpn/build/autograder/report.txt 14 | echo 15 | echo ============= exampleSort/ 16 | echo 17 | cat exampleSort/build/autograder/report.txt 18 | echo 19 | echo ============= standaloneSort/ 20 | echo 21 | cat standaloneSort/build/autograder/report.txt 22 | 23 | # debugging for GitHub Actions 24 | # echo 'Where are the google-java-format directories?' 25 | # find . -name google-java-format -print | xargs ls -lR > tmp 26 | # cat tmp 27 | 28 | exit $retVal 29 | -------------------------------------------------------------------------------- /standaloneSort/src/test/java/edu/rice/sort/HeapSortTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.Grade; 10 | import edu.rice.autograder.annotations.GradeTopic; 11 | import org.junit.jupiter.api.Test; 12 | 13 | @GradeTopic(project = "Sorting", topic = "HeapSort") 14 | public class HeapSortTest { 15 | @Test 16 | @Grade(project = "Sorting", topic = "HeapSort", points = 1.0) 17 | public void heapSortStrings() { 18 | TestAnySorter.exerciseStrings(new HeapSort<>()); 19 | } 20 | 21 | @Test 22 | @Grade(project = "Sorting", topic = "HeapSort", points = 1.0) 23 | public void heapSortIntegers() { 24 | TestAnySorter.exerciseIntegers(new HeapSort<>()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /exampleSort/src/test/java/edu/rice/sort/ShellSortTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.Grade; 10 | import edu.rice.autograder.annotations.GradeTopic; 11 | import org.junit.jupiter.api.Test; 12 | 13 | @GradeTopic(project = "Sorting", topic = "ShellSort") 14 | public class ShellSortTest { 15 | @Test 16 | @Grade(project = "Sorting", topic = "ShellSort", points = 1.0) 17 | public void shellSortStrings() { 18 | TestAnySorter.exerciseStrings(new ShellSort<>()); 19 | } 20 | 21 | @Test 22 | @Grade(project = "Sorting", topic = "ShellSort", points = 1.0) 23 | public void shellSortIntegers() { 24 | TestAnySorter.exerciseIntegers(new ShellSort<>()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /standaloneSort/src/test/java/edu/rice/sort/ShellSortTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.Grade; 10 | import edu.rice.autograder.annotations.GradeTopic; 11 | import org.junit.jupiter.api.Test; 12 | 13 | @GradeTopic(project = "Sorting", topic = "ShellSort") 14 | public class ShellSortTest { 15 | @Test 16 | @Grade(project = "Sorting", topic = "ShellSort", points = 1.0) 17 | public void shellSortStrings() { 18 | TestAnySorter.exerciseStrings(new ShellSort<>()); 19 | } 20 | 21 | @Test 22 | @Grade(project = "Sorting", topic = "ShellSort", points = 1.0) 23 | public void shellSortIntegers() { 24 | TestAnySorter.exerciseIntegers(new ShellSort<>()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.util.StringsTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.tree.BinaryHeapTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /exampleRpn/config/grade.yml: -------------------------------------------------------------------------------- 1 | # THIS FILE IS AUTOMATICALLY GENERATED (Wed, 17 Apr 2019 21:51:26 -0500), DO NOT EDIT! 2 | --- 3 | name: "RPN" 4 | description: "Simple RPN Calculator" 5 | maxPoints: 10.0 6 | warningPoints: 1.0 7 | useCheckStyle: true 8 | useGoogleJavaFormat: true 9 | useJavacWarnings: true 10 | coveragePoints: 3.0 11 | coverageStyle: "LINES" 12 | coveragePercentage: 90.0 13 | coverageAnnotations: 14 | - scope: "CLASS" 15 | excluded: false 16 | name: "edu.rice.rpn.RpnCalc" 17 | topics: 18 | - name: "Correctness" 19 | maxPoints: 6.0 20 | tests: 21 | - points: 3.0 22 | maxPoints: 0.0 23 | className: "edu.rice.rpn.RpnCalcTest" 24 | methodName: "testBasicArithmetic" 25 | testFactory: false 26 | - points: 3.0 27 | maxPoints: 0.0 28 | className: "edu.rice.rpn.RpnCalcTest" 29 | methodName: "testStackHandling" 30 | testFactory: false 31 | -------------------------------------------------------------------------------- /exampleSort/src/test/java/edu/rice/sort/PatienceSortTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.Grade; 10 | import edu.rice.autograder.annotations.GradeTopic; 11 | import org.junit.jupiter.api.Test; 12 | 13 | @GradeTopic(project = "Sorting", topic = "PatienceSort") 14 | public class PatienceSortTest { 15 | @Test 16 | @Grade(project = "Sorting", topic = "PatienceSort", points = 1.0) 17 | public void cycleSortStrings() { 18 | TestAnySorter.exerciseStrings(new PatienceSort<>()); 19 | } 20 | 21 | @Test 22 | @Grade(project = "Sorting", topic = "PatienceSort", points = 1.0) 23 | public void cycleSortIntegers() { 24 | TestAnySorter.exerciseIntegers(new PatienceSort<>()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /standaloneSort/src/test/java/edu/rice/sort/PatienceSortTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.Grade; 10 | import edu.rice.autograder.annotations.GradeTopic; 11 | import org.junit.jupiter.api.Test; 12 | 13 | @GradeTopic(project = "Sorting", topic = "PatienceSort") 14 | public class PatienceSortTest { 15 | @Test 16 | @Grade(project = "Sorting", topic = "PatienceSort", points = 1.0) 17 | public void cycleSortStrings() { 18 | TestAnySorter.exerciseStrings(new PatienceSort<>()); 19 | } 20 | 21 | @Test 22 | @Grade(project = "Sorting", topic = "PatienceSort", points = 1.0) 23 | public void cycleSortIntegers() { 24 | TestAnySorter.exerciseIntegers(new PatienceSort<>()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /exampleSort/src/test/java/edu/rice/sort/InsertionSortTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.Grade; 10 | import edu.rice.autograder.annotations.GradeTopic; 11 | import org.junit.jupiter.api.Test; 12 | 13 | @GradeTopic(project = "Sorting", topic = "InsertionSort") 14 | public class InsertionSortTest { 15 | @Test 16 | @Grade(project = "Sorting", topic = "InsertionSort", points = 1.0) 17 | public void insertionSortStrings() { 18 | TestAnySorter.exerciseStrings(new InsertionSort<>()); 19 | } 20 | 21 | @Test 22 | @Grade(project = "Sorting", topic = "InsertionSort", points = 1.0) 23 | public void insertionSortIntegers() { 24 | TestAnySorter.exerciseIntegers(new InsertionSort<>()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week1hangman.HangmanTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /standaloneSort/src/test/java/edu/rice/sort/InsertionSortTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.Grade; 10 | import edu.rice.autograder.annotations.GradeTopic; 11 | import org.junit.jupiter.api.Test; 12 | 13 | @GradeTopic(project = "Sorting", topic = "InsertionSort") 14 | public class InsertionSortTest { 15 | @Test 16 | @Grade(project = "Sorting", topic = "InsertionSort", points = 1.0) 17 | public void insertionSortStrings() { 18 | TestAnySorter.exerciseStrings(new InsertionSort<>()); 19 | } 20 | 21 | @Test 22 | @Grade(project = "Sorting", topic = "InsertionSort", points = 1.0) 23 | public void insertionSortIntegers() { 24 | TestAnySorter.exerciseIntegers(new InsertionSort<>()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.tree.TreeToListLaziness.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week3lists.Week3Filters.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /exampleSort/src/main/java/edu/rice/sort/InsertionSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.GradeCoverage; 10 | 11 | @GradeCoverage(project = "Sorting") 12 | public class InsertionSort> implements Sorter { 13 | public InsertionSort() {} 14 | 15 | @Override 16 | public void sortInPlace(T[] a) { 17 | // Borrowed from RosettaCode, with some changes to make it suitably generic. 18 | // https://rosettacode.org/wiki/Sorting_algorithms/Insertion_sort#Java 19 | for (int i = 1; i < a.length; i++) { 20 | T value = a[i]; 21 | int j = i - 1; 22 | while (j >= 0 && a[j].compareTo(value) > 0) { 23 | a[j + 1] = a[j]; 24 | j = j - 1; 25 | } 26 | a[j + 1] = value; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /standaloneSort/src/main/java/edu/rice/sort/InsertionSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.GradeCoverage; 10 | 11 | @GradeCoverage(project = "Sorting") 12 | public class InsertionSort> implements Sorter { 13 | public InsertionSort() {} 14 | 15 | @Override 16 | public void sortInPlace(T[] a) { 17 | // Borrowed from RosettaCode, with some changes to make it suitably generic. 18 | // https://rosettacode.org/wiki/Sorting_algorithms/Insertion_sort#Java 19 | for (int i = 1; i < a.length; i++) { 20 | T value = a[i]; 21 | int j = i - 1; 22 | while (j >= 0 && a[j].compareTo(value) > 0) { 23 | a[j + 1] = a[j]; 24 | j = j - 1; 25 | } 26 | a[j + 1] = value; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week2cars.DreamGarageTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /autograder/src/test/kotlin/edu/rice/autograder/CheckStyleResultsScannerTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | import org.junit.jupiter.api.Assertions.assertFalse 10 | import org.junit.jupiter.api.Assertions.assertTrue 11 | import org.junit.jupiter.api.Test 12 | 13 | class CheckStyleResultsScannerTest { 14 | @Test 15 | fun testCheckStyleInputs() { 16 | val mainData = readResource("comp215-build/reports/checkstyle/main.xml").getOrFail() 17 | val mainResults = checkStyleParser(mainData).eval("main") 18 | val testData = readResource("comp215-build/reports/checkstyle/test.xml").getOrFail() 19 | val testResults = checkStyleParser(testData).eval("test") 20 | 21 | assertTrue(mainResults.passing) // passing 22 | assertFalse(testResults.passing) // failing! 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week10covariance.CarExamplesTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week2lists.ObjectListTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.prettypictures.ExternalImageAllelesTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week6counting.FreqCountTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.util.HelpersTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.json.LensTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.prettypictures.TestGenesWeek3Test.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.dynamic.MemoizedBiFunctionTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.vavr.VavrHelperTests.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /autograder/src/test/kotlin/edu/rice/autograder/WordWrapTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | import org.junit.jupiter.api.Assertions.assertEquals 10 | import org.junit.jupiter.api.Test 11 | 12 | class WordWrapTest { 13 | @Test 14 | fun basics() { 15 | assertEquals(listOf("Hello", "World"), wordWrap("Hello World", 6)) 16 | } 17 | 18 | @Test 19 | fun lessBasics() { 20 | assertEquals( 21 | listOf( 22 | "edu.rice.regex.TestProject4.", 23 | "testClassIdentifiers: missing" 24 | ), 25 | wordWrap("edu.rice.regex.TestProject4.testClassIdentifiers: missing", 40) 26 | ) 27 | assertEquals( 28 | listOf( 29 | "edu.rice.regex.TestProject4.", 30 | "testClassIdentifiers: missing" 31 | ), 32 | wordWrap("edu.rice.regex.TestProject4.testClassIdentifiers: missing", 30) 33 | ) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.json.ValueTheories.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week4subsets.SubsetsTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.prettypictures.RandomGeneTreeTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.prettypictures.GeneTreeLensTests.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week5knapsack.KnapsackTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /autograder/src/test/java/edu/rice/autogradertest/TestProject2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autogradertest; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | import edu.rice.autograder.annotations.Grade; 12 | import org.junit.jupiter.api.Test; 13 | 14 | public class TestProject2 { 15 | @Grade(project = "TP2", topic = "Group1", points = 1.0) 16 | @Test 17 | public void test1() { 18 | assertTrue(true); 19 | } 20 | 21 | @Grade(project = "TP2", topic = "Group1", points = 1.0) 22 | @Test 23 | public void test2() { 24 | assertTrue(true); 25 | } 26 | 27 | @Grade(project = "TP2", topic = "Group1", points = 1.0) 28 | @Test 29 | public void test3() { 30 | assertTrue(true); 31 | } 32 | 33 | @Grade(project = "TP2", topic = "Group2", points = 1.0) 34 | @Test 35 | public void test4() { 36 | assertTrue(true); 37 | } 38 | 39 | @Grade(project = "TP2", topic = "Group2", points = 1.0) 40 | @Test 41 | public void test5() { 42 | assertTrue(true); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /exampleSort/src/main/java/edu/rice/sort/ShellSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.GradeCoverage; 10 | 11 | @GradeCoverage(project = "Sorting") 12 | public class ShellSort> implements Sorter { 13 | public ShellSort() {} 14 | 15 | @Override 16 | public void sortInPlace(T[] a) { 17 | // Code from RosettaCode, except made generic. 18 | // https://rosettacode.org/wiki/Sorting_algorithms/Shell_sort#Java 19 | 20 | int increment = a.length / 2; 21 | while (increment > 0) { 22 | for (int i = increment; i < a.length; i++) { 23 | int j = i; 24 | T temp = a[i]; 25 | while (j >= increment && a[j - increment].compareTo(temp) > 0) { 26 | a[j] = a[j - increment]; 27 | j = j - increment; 28 | } 29 | a[j] = temp; 30 | } 31 | if (increment == 2) { 32 | increment = 1; 33 | } else { 34 | increment = (int) (increment * 5.0 / 11); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /standaloneSort/src/main/java/edu/rice/sort/ShellSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.GradeCoverage; 10 | 11 | @GradeCoverage(project = "Sorting") 12 | public class ShellSort> implements Sorter { 13 | public ShellSort() {} 14 | 15 | @Override 16 | public void sortInPlace(T[] a) { 17 | // Code from RosettaCode, except made generic. 18 | // https://rosettacode.org/wiki/Sorting_algorithms/Shell_sort#Java 19 | 20 | int increment = a.length / 2; 21 | while (increment > 0) { 22 | for (int i = increment; i < a.length; i++) { 23 | int j = i; 24 | T temp = a[i]; 25 | while (j >= increment && a[j - increment].compareTo(temp) > 0) { 26 | a[j] = a[j - increment]; 27 | j = j - increment; 28 | } 29 | a[j] = temp; 30 | } 31 | if (increment == 2) { 32 | increment = 1; 33 | } else { 34 | increment = (int) (increment * 5.0 / 11); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.regex.RegexScannerTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /exampleRegex/config/grade.yml: -------------------------------------------------------------------------------- 1 | # THIS FILE IS AUTOMATICALLY GENERATED (Wed, 17 Apr 2019 21:50:07 -0500), DO NOT EDIT! 2 | --- 3 | name: "RE" 4 | description: "Writing regular expressions" 5 | maxPoints: 10.0 6 | warningPoints: 1.0 7 | useCheckStyle: true 8 | useGoogleJavaFormat: true 9 | useJavacWarnings: true 10 | coveragePoints: 0.0 11 | coverageStyle: "LINES" 12 | coveragePercentage: 0.0 13 | coverageAnnotations: [] 14 | topics: 15 | - name: "Identifiers" 16 | maxPoints: 3.0 17 | tests: 18 | - points: 0.5 19 | maxPoints: 1.5 20 | className: "edu.rice.regex.TestPatterns" 21 | methodName: "testClassIdentifiers" 22 | testFactory: true 23 | - points: 0.5 24 | maxPoints: 1.5 25 | className: "edu.rice.regex.TestPatterns" 26 | methodName: "testMethodIdentifiers" 27 | testFactory: true 28 | - name: "Numbers" 29 | maxPoints: 6.0 30 | tests: 31 | - points: 1.0 32 | maxPoints: 1.0 33 | className: "edu.rice.regex.TestPatterns" 34 | methodName: "testIntegerUnderscores" 35 | testFactory: true 36 | - points: 1.0 37 | maxPoints: 5.0 38 | className: "edu.rice.regex.TestPatterns" 39 | methodName: "testIntegers" 40 | testFactory: true 41 | -------------------------------------------------------------------------------- /autograder/src/test/kotlin/edu/rice/autograder/CompilerLogScannerTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | import org.junit.jupiter.api.Assertions.assertFalse 10 | import org.junit.jupiter.api.Assertions.assertTrue 11 | import org.junit.jupiter.api.Test 12 | 13 | class CompilerLogScannerTest { 14 | @Test 15 | fun testCompilerErrors() { 16 | val badFiles = listOf("mainfail.log", "testfail.log").map { 17 | readResource("comp215-build/logs/$it").getOrFail() 18 | } 19 | 20 | badFiles.forEach { assertFalse(javacZeroWarnings(it).passing) } 21 | } 22 | 23 | @Test 24 | fun goodCompilation() { 25 | assertTrue( 26 | javacZeroWarnings( 27 | readResource("comp215-build/logs/success.log").getOrFail() 28 | ).passing 29 | ) 30 | } 31 | 32 | @Test 33 | fun goodCompilationWhitespace() { 34 | assertTrue( 35 | javacZeroWarnings( 36 | readResource("comp215-build/logs/whitespace-success.log").getOrFail() 37 | ).passing 38 | ) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.sexpr.SimpleParserTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.dynamic.MemoizedFunctionTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week1intro.StringThingTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 16 | ]]> 17 | 18 | 19 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.json.ScannerTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /exampleSort/src/test/java/edu/rice/sort/TestAnySorter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import static org.quicktheories.QuickTheory.qt; 10 | import static org.quicktheories.generators.SourceDSL.*; 11 | 12 | /** General infrastructure for testing any {@link edu.rice.sort.Sorter}. */ 13 | public class TestAnySorter { 14 | /** Runs QuickTheories on the sorter with random arrays of strings. */ 15 | public static void exerciseStrings(Sorter sorter) { 16 | qt().forAll( 17 | arrays() 18 | .ofStrings(strings().basicLatinAlphabet().ofLengthBetween(0, 10)) 19 | .withLengthBetween(0, 100)) 20 | .check( 21 | a -> { 22 | sorter.sortInPlace(a); 23 | return Sorter.isSorted(a); 24 | }); 25 | } 26 | 27 | /** Runs QuickTheories on the sorter with random arrays of integers. */ 28 | public static void exerciseIntegers(Sorter sorter) { 29 | qt().forAll(arrays().ofIntegers(integers().all()).withLengthBetween(1, 100)) 30 | .check( 31 | a -> { 32 | sorter.sortInPlace(a); 33 | return Sorter.isSorted(a); 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /standaloneSort/src/test/java/edu/rice/sort/TestAnySorter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import static org.quicktheories.QuickTheory.qt; 10 | import static org.quicktheories.generators.SourceDSL.*; 11 | 12 | /** General infrastructure for testing any {@link edu.rice.sort.Sorter}. */ 13 | public class TestAnySorter { 14 | /** Runs QuickTheories on the sorter with random arrays of strings. */ 15 | public static void exerciseStrings(Sorter sorter) { 16 | qt().forAll( 17 | arrays() 18 | .ofStrings(strings().basicLatinAlphabet().ofLengthBetween(0, 10)) 19 | .withLengthBetween(0, 100)) 20 | .check( 21 | a -> { 22 | sorter.sortInPlace(a); 23 | return Sorter.isSorted(a); 24 | }); 25 | } 26 | 27 | /** Runs QuickTheories on the sorter with random arrays of integers. */ 28 | public static void exerciseIntegers(Sorter sorter) { 29 | qt().forAll(arrays().ofIntegers(integers().all()).withLengthBetween(1, 100)) 30 | .check( 31 | a -> { 32 | sorter.sortInPlace(a); 33 | return Sorter.isSorted(a); 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.prettypictures.RgbColorTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week3lists.Week3Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.json.OperationsTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week13newspaper.DBTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /autograder/src/main/java/edu/rice/autograder/annotations/GradeCoverage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder.annotations; 8 | 9 | import java.lang.annotation.Documented; 10 | import java.lang.annotation.ElementType; 11 | import java.lang.annotation.Repeatable; 12 | import java.lang.annotation.Retention; 13 | import java.lang.annotation.RetentionPolicy; 14 | import java.lang.annotation.Target; 15 | 16 | /** 17 | * This annotation is used to annotate a specific Java class or package as being subject to a code 18 | * coverage requirement for a given project. When multiple annotations apply to a given class, they 19 | * are evaluated from the outside to the inside (i.e., first the package, then the outer class, then 20 | * the inner class). Whichever annotation is "closest" to a given class will determine whether it is 21 | * included or excluded from coverage test requirements. 22 | */ 23 | @Retention(RetentionPolicy.RUNTIME) 24 | @Target({ElementType.TYPE, ElementType.PACKAGE}) 25 | @Repeatable(GradeCoverages.class) 26 | @Documented 27 | public @interface GradeCoverage { 28 | /** The project is specified the same as in {@link Grade#project()}. */ 29 | String project(); 30 | 31 | /** 32 | * Sometimes you want to exclude a class or package from consideration for coverage 33 | * testing. 34 | */ 35 | boolean exclude() default false; 36 | } 37 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week2cars.ManufacturerTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /exampleRegex/src/main/java/edu/rice/regex/Patterns.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.regex; 8 | 9 | import org.intellij.lang.annotations.Language; 10 | 11 | public class Patterns { 12 | // Java class-names start with capital letters and after that, by convention, we use 13 | // upper and lower-case letters and numbers, and nothing else. Write a regular 14 | // expression that matches this. 15 | @Language("RegExp") 16 | public static final String classPattern = "[A-Z][A-Za-z0-9]*"; 17 | 18 | // Java method-names start with a lower-case letter, and after that, by convention, 19 | // we use upper and lower-case letters and numbers, and nothing else. Write a regular 20 | // expression that matches this. 21 | @Language("RegExp") 22 | public static final String methodPattern = "[a-z][A-Za-z0-9]*"; 23 | 24 | // Java base-10 integers can have an optional minus sign at the front, then a series of 25 | // digits. Note that "negative zero" is allowed, but 0 followed by digits isn't (that's 26 | // a base-8 "octal" number). Also, an optional capital L at the end signifies a "long" 27 | // number. Also, underscores may appear between any digits. Write a regular expression 28 | // that matches this. 29 | @Language("RegExp") 30 | public static final String integerPattern = "(-)?(0|[1-9](_[0-9]|[0-9])*)(L)?"; 31 | // or try this: "(-)?(0|[1-9][0-9]*)(L)?"; -- doesn't know about underscores 32 | } 33 | -------------------------------------------------------------------------------- /autograder/src/main/kotlin/edu/rice/autograder/CompilerLogScanner.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | private const val TAG = "Javac" 10 | 11 | val javacLogMissing = CodeStyleDeduction( 12 | "Compiler: Can't find output", 13 | 0.0, TAG, "", false, 0, 0 14 | ) 15 | 16 | // This is almost too easy: our Gradle configuration copies stdout from the compiler 17 | // to a file: build/logs/compile.log 18 | 19 | // If the file has zero length or has nothing but blank lines, then the compile succeeded. 20 | // Anything else, then there were warnings and/or errors. 21 | 22 | fun javacZeroWarnings(fileData: String): CodeStyleDeduction { 23 | val lines = fileData.split("\n", "\r") 24 | .filter { it.isNotEmpty() } // ignore blank lines 25 | .filter { !it.startsWith(":") } // ignore Gradle build steps 26 | .filter { !it.startsWith("Note:") } // ignore Javac complaining about enabling preview features 27 | 28 | val result = 29 | if (fileData.isEmpty() || lines.isEmpty()) { 30 | CodeStyleDeduction( 31 | "Compiler: No warnings or errors", 32 | 0.0, TAG, "", true, 0, 0 33 | ) 34 | } else { 35 | CodeStyleDeduction( 36 | "Compiler: One or more warnings / errors", 37 | 0.0, TAG, "", false, 0, 0 38 | ) 39 | } 40 | 41 | Log.i(TAG, result) 42 | return result 43 | } 44 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.cparser.ParserFunctionTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week3lists.GListTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /autograder/src/test/java/edu/rice/autogradertest/TestProject1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autogradertest; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | import edu.rice.autograder.annotations.Grade; 12 | import edu.rice.autograder.annotations.GradeProject; 13 | import edu.rice.autograder.annotations.GradeTopic; 14 | import org.junit.jupiter.api.Test; 15 | 16 | @GradeProject( 17 | name = "TP1", 18 | description = "A fairly basic project", 19 | maxPoints = 10.0, 20 | warningPoints = 1.0) 21 | @GradeTopic(project = "TP1", topic = "Group1", maxPoints = 5.0) 22 | @GradeTopic(project = "TP1", topic = "Group2", maxPoints = 4.0) 23 | public class TestProject1 { 24 | @Grade(project = "TP1", topic = "Group1", points = 1.0) 25 | @Test 26 | public void test1() { 27 | assertTrue(true); 28 | } 29 | 30 | @Grade(project = "TP1", topic = "Group1", points = 1.0) 31 | @Test 32 | public void test2() { 33 | assertTrue(true); 34 | } 35 | 36 | @Grade(project = "TP1", topic = "Group1", points = 1.0) 37 | @Test 38 | public void test3() { 39 | assertTrue(true); 40 | } 41 | 42 | @Grade(project = "TP1", topic = "Group2", points = 1.0) 43 | @Test 44 | public void test4() { 45 | assertTrue(true); 46 | } 47 | 48 | @Grade(project = "TP1", topic = "Group2", points = 1.0) 49 | @Grade(project = "TP2", topic = "Group2", points = 1.0) 50 | @Test 51 | public void test5() { 52 | assertTrue(true); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /autograder/src/test/kotlin/edu/rice/autograder/GoogleJavaFormatScannerTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | import org.junit.jupiter.api.Assertions.assertEquals 10 | import org.junit.jupiter.api.Assertions.assertFalse 11 | import org.junit.jupiter.api.Assertions.assertTrue 12 | import org.junit.jupiter.api.Test 13 | 14 | class GoogleJavaFormatScannerTest { 15 | @Test 16 | fun testReadDir() { 17 | val comp215BuildDir = readResourceDir("comp215-build").getOrFail().toList() 18 | assertEquals(6, comp215BuildDir.size) 19 | assertTrue(comp215BuildDir.contains("comp215-build/google-java-format")) 20 | } 21 | 22 | @Test 23 | fun testFileStatesExample() { 24 | val input = readResource("comp215-build/google-java-format/0.8/fileStates.txt").getOrFail() 25 | val testResult = googleJavaFormatParser(input).eval() 26 | assertFalse(testResult.passing) 27 | } 28 | 29 | @Test 30 | fun testCrazyGoogleJavaFormatDirectories() { 31 | val input = readFileWildcardDir( 32 | "src/test/resources/comp215-build/weird-google-java-format", 33 | "fileStates.txt" 34 | ).getOrFail() 35 | val testResult = googleJavaFormatParser(input).eval() 36 | assertFalse(testResult.passing) 37 | 38 | val input2 = readFileWildcardDir( 39 | "src/test/resources/comp215-build/weirder-google-java-format", 40 | "fileStates.txt" 41 | ) 42 | assertTrue(input2.isFailure()) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /exampleSort/src/main/java/edu/rice/sort/HeapSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.GradeCoverage; 10 | 11 | @GradeCoverage(project = "Sorting") 12 | public class HeapSort> implements Sorter { 13 | // Borrowed from RosettaCode, then modified to fit a standard sorting interface we can test 14 | // https://rosettacode.org/wiki/Sorting_algorithms/Heapsort#Java 15 | 16 | public HeapSort() {} 17 | 18 | @Override 19 | public void sortInPlace(T[] a) { 20 | int count = a.length; 21 | 22 | heapify(a, count); 23 | 24 | int end = count - 1; 25 | while (end > 0) { 26 | T tmp = a[end]; 27 | a[end] = a[0]; 28 | a[0] = tmp; 29 | siftDown(a, 0, end - 1); 30 | end--; 31 | } 32 | } 33 | 34 | private void heapify(T[] a, int count) { 35 | int start = (count - 2) / 2; 36 | 37 | while (start >= 0) { 38 | siftDown(a, start, count - 1); 39 | start--; 40 | } 41 | } 42 | 43 | private void siftDown(T[] a, int start, int end) { 44 | int root = start; 45 | 46 | while ((root * 2 + 1) <= end) { 47 | int child = root * 2 + 1; 48 | if (child + 1 <= end && a[child].compareTo(a[child + 1]) < 0) { 49 | child = child + 1; 50 | } 51 | if (a[root].compareTo(a[child]) < 0) { 52 | T tmp = a[root]; 53 | a[root] = a[child]; 54 | a[child] = tmp; 55 | root = child; 56 | } else { 57 | return; 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /standaloneSort/src/main/java/edu/rice/sort/HeapSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.GradeCoverage; 10 | 11 | @GradeCoverage(project = "Sorting") 12 | public class HeapSort> implements Sorter { 13 | // Borrowed from RosettaCode, then modified to fit a standard sorting interface we can test 14 | // https://rosettacode.org/wiki/Sorting_algorithms/Heapsort#Java 15 | 16 | public HeapSort() {} 17 | 18 | @Override 19 | public void sortInPlace(T[] a) { 20 | int count = a.length; 21 | 22 | heapify(a, count); 23 | 24 | int end = count - 1; 25 | while (end > 0) { 26 | T tmp = a[end]; 27 | a[end] = a[0]; 28 | a[0] = tmp; 29 | siftDown(a, 0, end - 1); 30 | end--; 31 | } 32 | } 33 | 34 | private void heapify(T[] a, int count) { 35 | int start = (count - 2) / 2; 36 | 37 | while (start >= 0) { 38 | siftDown(a, start, count - 1); 39 | start--; 40 | } 41 | } 42 | 43 | private void siftDown(T[] a, int start, int end) { 44 | int root = start; 45 | 46 | while ((root * 2 + 1) <= end) { 47 | int child = root * 2 + 1; 48 | if (child + 1 <= end && a[child].compareTo(a[child + 1]) < 0) { 49 | child = child + 1; 50 | } 51 | if (a[root].compareTo(a[child]) < 0) { 52 | T tmp = a[root]; 53 | a[root] = a[child]; 54 | a[child] = tmp; 55 | root = child; 56 | } else { 57 | return; 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /autograder/src/test/java/edu/rice/autogradertest/TestProject3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autogradertest; 8 | 9 | import static edu.rice.autogradertest.Project3.choose; 10 | import static edu.rice.autogradertest.Project3.factorial; 11 | import static org.junit.jupiter.api.Assertions.assertEquals; 12 | import static org.junit.jupiter.api.DynamicTest.dynamicTest; 13 | 14 | import edu.rice.autograder.annotations.Grade; 15 | import edu.rice.autograder.annotations.GradeProject; 16 | import edu.rice.autograder.annotations.GradeTopic; 17 | import java.util.Arrays; 18 | import org.junit.jupiter.api.DynamicTest; 19 | import org.junit.jupiter.api.Test; 20 | import org.junit.jupiter.api.TestFactory; 21 | 22 | @GradeProject( 23 | name = "TP3", 24 | description = "Factorial and Choose", 25 | warningPoints = 1.0, 26 | coveragePoints = 1.0, 27 | coveragePercentage = 80, 28 | coverageMethod = "INSTRUCTIONS") 29 | @GradeTopic(project = "TP3", topic = "Correctness") 30 | public class TestProject3 { 31 | @TestFactory 32 | @Grade(project = "TP3", topic = "Correctness", points = 2.0, maxPoints = 4.0) 33 | Iterable testFactorial() { 34 | return Arrays.asList( 35 | dynamicTest("0", () -> assertEquals(1, factorial(0))), 36 | dynamicTest("1", () -> assertEquals(1, factorial(1))), 37 | dynamicTest("3", () -> assertEquals(6, factorial(3)))); 38 | } 39 | 40 | @Test 41 | @Grade(project = "TP3", topic = "Correctness", points = 4.0) 42 | void testChoose() { 43 | assertEquals(15, choose(6, 2)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.prettypictures.AlleleTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /standaloneSort/src/main/java/edu/rice/sort/PatienceSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.GradeCoverage; 10 | import java.util.ArrayDeque; 11 | import java.util.ArrayList; 12 | import java.util.Collections; 13 | import java.util.PriorityQueue; 14 | 15 | @GradeCoverage(project = "Sorting") 16 | public class PatienceSort> implements Sorter { 17 | public PatienceSort() {} 18 | 19 | @Override 20 | public void sortInPlace(T[] n) { 21 | // Started with RosettaCode, made more generic. 22 | // https://rosettacode.org/wiki/Sorting_algorithms/Patience_sort#Java 23 | 24 | ArrayList> piles = new ArrayList<>(); 25 | for (T x : n) { 26 | Pile newPile = new Pile<>(); 27 | newPile.push(x); 28 | int i = Collections.binarySearch(piles, newPile); 29 | if (i < 0) { 30 | i = ~i; 31 | } 32 | if (i != piles.size()) { 33 | piles.get(i).push(x); 34 | } else { 35 | piles.add(newPile); 36 | } 37 | } 38 | 39 | PriorityQueue> heap = new PriorityQueue<>(piles); 40 | for (int c = 0; c < n.length; c++) { 41 | Pile smallPile = heap.poll(); 42 | n[c] = smallPile.pop(); 43 | if (!smallPile.isEmpty()) { 44 | heap.offer(smallPile); 45 | } 46 | } 47 | assert (heap.isEmpty()); 48 | } 49 | 50 | private static class Pile> extends ArrayDeque 51 | implements Comparable> { 52 | @Override 53 | public int compareTo(Pile y) { 54 | return peek().compareTo(y.peek()); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /autograder/src/main/kotlin/edu/rice/autograder/GradeProjectIO.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | import arrow.core.Try 10 | import com.fasterxml.jackson.module.kotlin.readValue 11 | 12 | private const val TAG = "YamlExporter" 13 | 14 | /** 15 | * Given a project name, as specified with a [GGradeProject] annotation, 16 | * and the output of running [scanEverything], this scans for 17 | * the project grading specifications and produces a human-readable 18 | * (YAML) version of the policy. Useful for debugging. 19 | */ 20 | fun Map.yamlExporter( 21 | projectName: String, 22 | suppressDoNotEditLine: Boolean = false 23 | ): String { 24 | val project = this[projectName] ?: Log.ethrow(TAG, "Unknown project: $projectName") 25 | return project.yamlExporter(suppressDoNotEditLine) 26 | } 27 | 28 | /** 29 | * Given a [GGradeProject], extracts a string in YAML format, suitable for 30 | * printing to the user or saving in a file. Normally, a header comment 31 | * is generated saying "DO NOT EDIT". If you want to suppress that, 32 | * set the [suppressDoNotEditLine] parameter to *true*. 33 | */ 34 | fun GGradeProject.yamlExporter(suppressDoNotEditLine: Boolean = false) = 35 | (if (suppressDoNotEditLine) "" else yamlHeader) + 36 | ( 37 | jacksonYamlMapper.writeValueAsString(this) 38 | ?: Log.ethrow(TAG, "Jackson YAML failure?!") 39 | ) 40 | 41 | /** 42 | * Given a string in YAML format, tries to produce a [GGradeProject] 43 | * corresponding to the YAML file. 44 | */ 45 | fun yamlImporter(input: String) = Try { 46 | jacksonYamlMapper.readValue(input) 47 | } 48 | -------------------------------------------------------------------------------- /autograder/src/main/kotlin/edu/rice/autograder/JacksonHelpers.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | import com.fasterxml.jackson.databind.DeserializationFeature 10 | import com.fasterxml.jackson.databind.MapperFeature 11 | import com.fasterxml.jackson.databind.ObjectMapper 12 | import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule 13 | import com.fasterxml.jackson.dataformat.xml.XmlMapper 14 | import com.fasterxml.jackson.dataformat.yaml.YAMLMapper 15 | import com.fasterxml.jackson.module.kotlin.registerKotlinModule 16 | import java.time.ZoneId 17 | import java.time.ZonedDateTime 18 | import java.time.format.DateTimeFormatter 19 | 20 | // 21 | // Jackson has these ObjectMapper things that are used both to serialize and 22 | // deserialize. We create and configure them here. 23 | // 24 | 25 | private fun ObjectMapper.setup() = 26 | this.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true) 27 | .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 28 | .registerKotlinModule() 29 | 30 | val yamlHeader = "# THIS FILE IS AUTOMATICALLY GENERATED (%s), DO NOT EDIT!\n".format( 31 | ZonedDateTime.now(ZoneId.systemDefault()) 32 | .format(DateTimeFormatter.RFC_1123_DATE_TIME) 33 | ) 34 | 35 | /** General-purpose Jackson YAML mapper. */ 36 | val jacksonYamlMapper = YAMLMapper().setup() 37 | 38 | /** General-purpose Jackson XML mapper. */ 39 | val jacksonXmlMapper: ObjectMapper = XmlMapper( 40 | JacksonXmlModule().apply { 41 | setDefaultUseWrapper(false) 42 | } 43 | ).setup() 44 | 45 | /** General-purpose Jackson JSON mapper. */ 46 | val jacksonJsonMapper: ObjectMapper = ObjectMapper().setup() 47 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week4queue.ListQueueTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /autograder/src/main/kotlin/edu/rice/autograder/ArrowHelpers.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | import arrow.core.Option 10 | import arrow.core.Try 11 | 12 | // 13 | // Missing features from Arrow that we want/need 14 | // 15 | 16 | /** Runs the given lambda on the exception contained inside a [Try]'s failure. Returns the original Try. */ 17 | fun Try.onFailure(consumer: (Throwable) -> Unit): Try = 18 | fold({ consumer(it); this }, { this }) 19 | 20 | /** Runs the given lambda on the value contained inside a [Try]'s success. Returns the original Try. */ 21 | fun Try.onSuccess(consumer: (T) -> Unit): Try = 22 | fold({ this }, { consumer(it); this }) 23 | 24 | /** Converts a [Try] to a [List] of one or zero elements */ 25 | fun Try.asList(): List = fold({ emptyList() }, { listOf(it) }) 26 | 27 | /** Extracts a [Try] success value or (re-throws) an exception. */ 28 | fun Try.getOrFail(): T = fold({ throw it }, { it }) 29 | 30 | /** Extracts an [Option] some()'s value or throws an exception on none(). */ 31 | fun Option.getOrFail(): T = 32 | fold({ throw IllegalStateException("getOrFail() on an Option.none") }, { it }) 33 | 34 | // 35 | // Also useful, in our quest to avoid nulls at all costs. 36 | // 37 | 38 | /** 39 | * Like [Iterable.associateBy], but if the [keySelector] returns null, that key is ignored 40 | * and we move onward. 41 | */ 42 | fun Iterable?.associateNotNullBy(keySelector: (T) -> K?): Map = 43 | if (this == null) { 44 | emptyMap() 45 | } else { 46 | flatMap { 47 | val tmp = keySelector(it) 48 | if (tmp == null) emptyList() 49 | else listOf(tmp to it) 50 | }.toMap() 51 | } 52 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.util.OptionTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.cparser.SexprTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /exampleSort/src/main/java/edu/rice/sort/PatienceSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.sort; 8 | 9 | import edu.rice.autograder.annotations.GradeCoverage; 10 | import java.util.ArrayDeque; 11 | import java.util.ArrayList; 12 | import java.util.Collections; 13 | import java.util.PriorityQueue; 14 | 15 | @GradeCoverage(project = "Sorting") 16 | public class PatienceSort> implements Sorter { 17 | public PatienceSort() {} 18 | 19 | @Override 20 | public void sortInPlace(T[] n) { 21 | // Started with RosettaCode, made more generic. 22 | // https://rosettacode.org/wiki/Sorting_algorithms/Patience_sort#Java 23 | 24 | ArrayList> piles = new ArrayList<>(); 25 | for (T x : n) { 26 | Pile newPile = new Pile<>(); 27 | newPile.push(x); 28 | int i = Collections.binarySearch(piles, newPile); 29 | if (i < 0) { 30 | i = ~i; 31 | } 32 | if (i != piles.size()) { 33 | piles.get(i).push(x); 34 | } else { 35 | piles.add(newPile); 36 | } 37 | } 38 | 39 | PriorityQueue> heap = new PriorityQueue<>(piles); 40 | for (int c = 0; c < n.length; c++) { 41 | Pile smallPile = heap.poll(); 42 | n[c] = smallPile.pop(); 43 | if (!smallPile.isEmpty()) { 44 | heap.offer(smallPile); 45 | } 46 | } 47 | assert (heap.isEmpty()); 48 | } 49 | 50 | // We're excluding this as a test of our coverage logic; in reality, you'd 51 | // probably want to have this inner class covered as well. 52 | @GradeCoverage(project = "Sorting", exclude = true) 53 | private static class Pile> extends ArrayDeque 54 | implements Comparable> { 55 | @Override 56 | public int compareTo(Pile y) { 57 | return peek().compareTo(y.peek()); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /autograder/src/test/kotlin/edu/rice/autograder/JUnitSuiteScannerTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | import org.junit.jupiter.api.Assertions.assertEquals 10 | import org.junit.jupiter.api.Assertions.assertTrue 11 | import org.junit.jupiter.api.Assertions.fail 12 | import org.junit.jupiter.api.Test 13 | 14 | class JUnitSuiteScannerTest { 15 | @Test 16 | fun testLoader() { 17 | val files = 18 | readResourceDir("comp215-build/test-results/test") 19 | .fold({ emptyList() }, { it.toList() }) 20 | val fileContents = files.flatMap { readResource(it).asList() } 21 | val xmlResults = fileContents.map { junitSuiteParser(it) } 22 | val allTests = xmlResults.flatMap { it.tests ?: emptyList() } 23 | val failedTests = allTests.filter { it.failure != null } 24 | 25 | assertEquals(1287, xmlResults.sumBy { it.numTests }) 26 | assertEquals(1287, allTests.size) 27 | assertEquals(10, xmlResults.sumBy { it.numFailures }) 28 | assertEquals(10, failedTests.size) 29 | assertEquals(0, xmlResults.sumBy { it.numSkipped }) 30 | 31 | val stringConcatResult = failedTests.filter { it.className == "edu.rice.qt.ListTheories" } 32 | assertEquals(2, stringConcatResult.size) 33 | 34 | val stackTrace = stringConcatResult[0].failure?.stackTraceList ?: fail() 35 | assertEquals("org.opentest4j.AssertionFailedError", stackTrace[0]) 36 | assertEquals( 37 | "at edu.rice.qt.ListTheories." + 38 | "stringConcatenationIsNotCommutative(ListTheories.java:132)", 39 | stackTrace[3] 40 | ) 41 | } 42 | 43 | @Test 44 | fun testMethodMatcher() { 45 | val test1 = JTestCase("testObjects()[1]", "edu.rice.json.ParserTestPrivate", 0.0, null) 46 | assertTrue(test1.matches("edu.rice.json.ParserTestPrivate", "testObjects")) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.week5sorting.SortPerformance.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /exampleRpn/src/test/java/edu/rice/rpn/RpnCalcTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.rpn; 8 | 9 | import static org.junit.jupiter.api.Assertions.*; 10 | 11 | import edu.rice.autograder.annotations.Grade; 12 | import edu.rice.autograder.annotations.GradeProject; 13 | import edu.rice.autograder.annotations.GradeTopic; 14 | import java.util.NoSuchElementException; 15 | import org.junit.jupiter.api.Test; 16 | 17 | @GradeProject( 18 | name = "RPN", 19 | description = "Simple RPN Calculator", 20 | warningPoints = 1.0, 21 | coveragePoints = 3.0, 22 | coveragePercentage = 90) 23 | @GradeTopic(project = "RPN", topic = "Correctness") 24 | class RpnCalcTest { 25 | @Test 26 | @Grade(project = "RPN", topic = "Correctness", points = 3.0) 27 | void testBasicArithmetic() { 28 | RpnCalc rpnCalc = new RpnCalc(); 29 | assertEquals("7.0", rpnCalc.eval("3 4 +")); 30 | assertEquals("12.0", rpnCalc.eval("3 4 *")); 31 | assertEquals("-1.0", rpnCalc.eval("3 4 -")); 32 | assertEquals("0.75", rpnCalc.eval("3 4 /")); 33 | assertEquals("8.0", rpnCalc.eval("2 3 ^")); 34 | } 35 | 36 | @Test 37 | @Grade(project = "RPN", topic = "Correctness", points = 3.0) 38 | void testStackHandling() { 39 | RpnCalc rpnCalc = new RpnCalc(); 40 | assertEquals("7.0", rpnCalc.eval("3 4 +")); 41 | assertEquals("Empty", rpnCalc.eval("drop")); 42 | assertThrows(NoSuchElementException.class, () -> rpnCalc.eval("drop")); 43 | assertEquals("4.0", rpnCalc.eval("1 2 3 4")); 44 | assertEquals("3.0", rpnCalc.eval("drop")); 45 | assertEquals("2.0", rpnCalc.eval("drop")); 46 | assertEquals("1.0", rpnCalc.eval("drop")); 47 | assertEquals("Empty", rpnCalc.eval("drop")); 48 | assertEquals("1.0", rpnCalc.eval("3 4 swap -")); 49 | assertEquals("3.0", rpnCalc.eval("2 6 swap /")); 50 | } 51 | 52 | @Test 53 | void testToString() { 54 | RpnCalc rpnCalc = new RpnCalc(); 55 | rpnCalc.eval("1.0"); 56 | rpnCalc.eval("2.0"); 57 | rpnCalc.eval("3.0"); 58 | 59 | assertEquals("3.0, 2.0, 1.0", rpnCalc.toString()); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.rpn.RpnCalculatorTestPrivate.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /autograder/src/main/java/edu/rice/autograder/annotations/GradeTopic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder.annotations; 8 | 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Repeatable; 11 | import java.lang.annotation.Retention; 12 | import java.lang.annotation.RetentionPolicy; 13 | import java.lang.annotation.Target; 14 | 15 | /** 16 | * This annotation, which may appear either on a class or on a package (i.e., in 17 | * package-info.java), may appear multiple times and specifies a series of "topics", 18 | * representing groups of items being graded. Every {@link Grade} annotation names a topic. 19 | * 20 | *

Topics might be broad things like "Correctness", "Performance", etc., or they might be 21 | * anything else that fits the assignment, e.g., "HeapSort", "InsertionSort", "QuickSort". 22 | * 23 | *

The general idea, then, is that all of the unit tests for a given project and topic, as 24 | * specified by Grade annotations, will deduct their points, if they fail, from the pool of points 25 | * specified in the GradeTopic. This means it's possible to have more deductions than available 26 | * points, but the resulting point score for that topic will never go below zero. 27 | * 28 | *

If maxPoints isn't specified, it will be derived by adding together all of the {@link 29 | * Grade} tests associated with the given GradeTopic. 30 | */ 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ElementType.TYPE, ElementType.PACKAGE}) 33 | @Repeatable(GradeTopics.class) 34 | public @interface GradeTopic { 35 | /** Name of the project being graded (e.g., "Week1"). */ 36 | String project(); 37 | 38 | /** Name of the topic being defined (e.g., "Correctness"). */ 39 | String topic(); 40 | 41 | /** 42 | * Number of points to be associated with the topic. If unspecified, all the individual {@link 43 | * Grade} annotations for the given project and topic will have their {@link Grade#points()} (or 44 | * in the case of TestFactory tests, {@link Grade#maxPoints()}) accumulated together. 45 | */ 46 | double maxPoints() default 0.0; 47 | } 48 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.rpn.RpnCalculatorTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Some(List(10.0, 3.0)) 21 | 2019-03-29 09:20:36,812 [Test worker] ?[34mINFO ?[0;39m ?[36mRpnCalculatorTest?[0;39m - Some(List(10.0, 3.0)) -> Some(List(13.0)) 22 | 2019-03-29 09:20:36,812 [Test worker] ?[34mINFO ?[0;39m ?[36mRpnCalculatorTest?[0;39m - Some(List(13.0)) -> Some(List(27.0, 13.0)) 23 | 2019-03-29 09:20:36,812 [Test worker] ?[34mINFO ?[0;39m ?[36mRpnCalculatorTest?[0;39m - Some(List(27.0, 13.0)) -> Some(List(351.0)) 24 | ]]> 25 | 26 | 27 | -------------------------------------------------------------------------------- /standaloneSort/config/grade.yml: -------------------------------------------------------------------------------- 1 | # THIS FILE IS AUTOMATICALLY GENERATED (Sat, 20 Apr 2019 13:26:35 -0500), DO NOT EDIT! 2 | --- 3 | name: "Sorting" 4 | description: "Implement Many Sorting Algorithms" 5 | maxPoints: 10.0 6 | warningPoints: 1.0 7 | useCheckStyle: true 8 | useGoogleJavaFormat: true 9 | useJavacWarnings: true 10 | coveragePoints: 1.0 11 | coverageStyle: "LINES" 12 | coveragePercentage: 90.0 13 | coverageAnnotations: 14 | - scope: "CLASS" 15 | excluded: false 16 | name: "edu.rice.sort.HeapSort" 17 | - scope: "CLASS" 18 | excluded: false 19 | name: "edu.rice.sort.InsertionSort" 20 | - scope: "CLASS" 21 | excluded: false 22 | name: "edu.rice.sort.PatienceSort" 23 | - scope: "CLASS" 24 | excluded: false 25 | name: "edu.rice.sort.ShellSort" 26 | topics: 27 | - name: "HeapSort" 28 | maxPoints: 2.0 29 | tests: 30 | - points: 1.0 31 | maxPoints: 0.0 32 | className: "edu.rice.sort.HeapSortTest" 33 | methodName: "heapSortIntegers" 34 | testFactory: false 35 | - points: 1.0 36 | maxPoints: 0.0 37 | className: "edu.rice.sort.HeapSortTest" 38 | methodName: "heapSortStrings" 39 | testFactory: false 40 | - name: "InsertionSort" 41 | maxPoints: 2.0 42 | tests: 43 | - points: 1.0 44 | maxPoints: 0.0 45 | className: "edu.rice.sort.InsertionSortTest" 46 | methodName: "insertionSortIntegers" 47 | testFactory: false 48 | - points: 1.0 49 | maxPoints: 0.0 50 | className: "edu.rice.sort.InsertionSortTest" 51 | methodName: "insertionSortStrings" 52 | testFactory: false 53 | - name: "PatienceSort" 54 | maxPoints: 2.0 55 | tests: 56 | - points: 1.0 57 | maxPoints: 0.0 58 | className: "edu.rice.sort.PatienceSortTest" 59 | methodName: "cycleSortIntegers" 60 | testFactory: false 61 | - points: 1.0 62 | maxPoints: 0.0 63 | className: "edu.rice.sort.PatienceSortTest" 64 | methodName: "cycleSortStrings" 65 | testFactory: false 66 | - name: "ShellSort" 67 | maxPoints: 2.0 68 | tests: 69 | - points: 1.0 70 | maxPoints: 0.0 71 | className: "edu.rice.sort.ShellSortTest" 72 | methodName: "shellSortIntegers" 73 | testFactory: false 74 | - points: 1.0 75 | maxPoints: 0.0 76 | className: "edu.rice.sort.ShellSortTest" 77 | methodName: "shellSortStrings" 78 | testFactory: false 79 | -------------------------------------------------------------------------------- /exampleSort/config/grade.yml: -------------------------------------------------------------------------------- 1 | # THIS FILE IS AUTOMATICALLY GENERATED (Tue, 23 Apr 2019 20:36:26 -0500), DO NOT EDIT! 2 | --- 3 | name: "Sorting" 4 | description: "Implement Many Sorting Algorithms" 5 | maxPoints: 10.0 6 | warningPoints: 1.0 7 | useCheckStyle: true 8 | useGoogleJavaFormat: true 9 | useJavacWarnings: true 10 | coveragePoints: 1.0 11 | coverageStyle: "LINES" 12 | coveragePercentage: 90.0 13 | coverageAnnotations: 14 | - scope: "CLASS" 15 | excluded: false 16 | name: "edu.rice.sort.HeapSort" 17 | - scope: "CLASS" 18 | excluded: false 19 | name: "edu.rice.sort.InsertionSort" 20 | - scope: "CLASS" 21 | excluded: false 22 | name: "edu.rice.sort.PatienceSort" 23 | - scope: "CLASS" 24 | excluded: true 25 | name: "edu.rice.sort.PatienceSort.Pile" 26 | - scope: "CLASS" 27 | excluded: false 28 | name: "edu.rice.sort.ShellSort" 29 | topics: 30 | - name: "HeapSort" 31 | maxPoints: 2.0 32 | tests: 33 | - points: 1.0 34 | maxPoints: 0.0 35 | className: "edu.rice.sort.HeapSortTest" 36 | methodName: "heapSortIntegers" 37 | testFactory: false 38 | - points: 1.0 39 | maxPoints: 0.0 40 | className: "edu.rice.sort.HeapSortTest" 41 | methodName: "heapSortStrings" 42 | testFactory: false 43 | - name: "InsertionSort" 44 | maxPoints: 2.0 45 | tests: 46 | - points: 1.0 47 | maxPoints: 0.0 48 | className: "edu.rice.sort.InsertionSortTest" 49 | methodName: "insertionSortIntegers" 50 | testFactory: false 51 | - points: 1.0 52 | maxPoints: 0.0 53 | className: "edu.rice.sort.InsertionSortTest" 54 | methodName: "insertionSortStrings" 55 | testFactory: false 56 | - name: "PatienceSort" 57 | maxPoints: 2.0 58 | tests: 59 | - points: 1.0 60 | maxPoints: 0.0 61 | className: "edu.rice.sort.PatienceSortTest" 62 | methodName: "cycleSortIntegers" 63 | testFactory: false 64 | - points: 1.0 65 | maxPoints: 0.0 66 | className: "edu.rice.sort.PatienceSortTest" 67 | methodName: "cycleSortStrings" 68 | testFactory: false 69 | - name: "ShellSort" 70 | maxPoints: 2.0 71 | tests: 72 | - points: 1.0 73 | maxPoints: 0.0 74 | className: "edu.rice.sort.ShellSortTest" 75 | methodName: "shellSortIntegers" 76 | testFactory: false 77 | - points: 1.0 78 | maxPoints: 0.0 79 | className: "edu.rice.sort.ShellSortTest" 80 | methodName: "shellSortStrings" 81 | testFactory: false 82 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.json.ParserTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /autograder/src/main/java/edu/rice/autograder/annotations/Grade.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder.annotations; 8 | 9 | import java.lang.annotation.Documented; 10 | import java.lang.annotation.ElementType; 11 | import java.lang.annotation.Repeatable; 12 | import java.lang.annotation.Retention; 13 | import java.lang.annotation.RetentionPolicy; 14 | import java.lang.annotation.Target; 15 | 16 | /** 17 | * This annotation is used to annotate a specific unit test to indicate which project it might be 18 | * (e.g., "Week1") and what it's topic might be (e.g., "Correctness"). Also specified should be the 19 | * number of points that the unit test is worth. 20 | * 21 | *

A Grade annotation should be placed on a JUnit5 unit test, built using the new "Jupiter" APIs 22 | * (org.junit.jupiter.api.Test or org.junit.jupiter.api.TestFactory). Anything else is considered an 23 | * error. 24 | * 25 | *

Also of note: multiple Grade annotations on a given unit test are acceptable. Each annotation 26 | * should specify a different project. (Example: if you've got a set of unit tests that will be used 27 | * across multiple weeks of assignments, and you want them to be used in each week's project, then 28 | * simply have multiple Grade annotations.) 29 | */ 30 | @Retention(RetentionPolicy.RUNTIME) 31 | @Target(ElementType.METHOD) 32 | @Documented 33 | @Repeatable(Grades.class) 34 | public @interface Grade { 35 | /** Name of the project being graded (e.g., "Week1"). */ 36 | String project(); 37 | 38 | /** Name of the topic within the project being graded (e.g., "Correctness"). */ 39 | String topic(); 40 | 41 | /** 42 | * Number of points associated with the unit test being annotated. 43 | * 44 | *

When applied to a JUnit5 Test, the points are then subtracted from the requested 45 | * topic if the test fails. If more points are subtracted than a given topic has to begin with, 46 | * then scores won't go below zero. maxPoints is ignored. 47 | * 48 | *

When applied to a JUnit5 TestFactory, which returns a list of dynamic tests to be executed, 49 | * each individual test will be worth the requested number of points, but the maximum 50 | * deduction for failed tests from the given test factory will be maxPoints. 51 | */ 52 | double points(); 53 | 54 | /** 55 | * When applied to a JUnit5 TestFactory, describes the maximum number of points to be associated 56 | * with the TestFactory. This field is ignored for regular unit tests. 57 | */ 58 | double maxPoints() default 0.0; 59 | } 60 | -------------------------------------------------------------------------------- /autograder/src/main/kotlin/edu/rice/autograder/GoogleJavaFormatScanner.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | private const val TAG = "GoogleJavaFormat" 10 | 11 | // the data is formatted something like this: 12 | // - src/test/java/edu/rice/week12mockito/Week12LabTest.java,1546873388046247000,4759,FORMATTED 13 | // - src/main/java/edu/rice/prettypictures/Allele.java,1550594030478707000,18487,FORMATTED 14 | // - src/main/java/edu/rice/cparser/SExpression.java,1551735069772221000,7236,FORMATTED 15 | // - src/test/java/edu/rice/qt/QtHelpers.java,1553526776339910000,1884,UNFORMATTED 16 | 17 | // So, that's CSV format with fileName,fileModTime,fileNumBytes,formattedStatus 18 | // - filestate can apparently be FORMATTED, UNFORMATTED, INVALID, or UNKNOWN 19 | 20 | // Note that this may well change in a future version of the GoogleJavaFormat plugin. 21 | // https://github.com/RiceComp215-Staff/RiceChecks/issues/5 22 | // https://github.com/sherter/google-java-format-gradle-plugin/issues/35 23 | 24 | data class GoogleJavaFormatResult( 25 | val fileName: String, 26 | val fileModTime: Long, 27 | val fileNumBytes: Long, 28 | val formattedStatus: String 29 | ) 30 | 31 | val googleJavaFormatMissing = CodeStyleDeduction("$TAG: no input found", 0.0, TAG, "", false, 0, 0) 32 | 33 | fun List.eval(): CodeStyleDeduction { 34 | if (isEmpty()) { 35 | return googleJavaFormatMissing 36 | } 37 | 38 | val numResults = size 39 | val numFormatted = count { it.formattedStatus == "FORMATTED" } 40 | val feedback = "$TAG: %d of %d files passed".format(numFormatted, numResults) + 41 | if (numFormatted == numResults) "" 42 | else "\nrun the gradle task to fix" 43 | Log.i(TAG, "eval: $feedback") 44 | 45 | return CodeStyleDeduction( 46 | feedback, 0.0, TAG, "", 47 | (numFormatted == numResults), numFormatted, numResults 48 | ) 49 | } 50 | 51 | fun googleJavaFormatParser(fileData: String): List { 52 | Log.i(TAG, "parser: ${fileData.length} bytes") 53 | 54 | return if (fileData.isEmpty()) { 55 | emptyList() 56 | } else { 57 | // Using hand-build lame parser because Jackson CSV wasn't working and this is easy. 58 | // Unlikely we'll have escaped commas or other such landmines that would break this. 59 | fileData 60 | .split(Regex("[\n\r]+")) 61 | .filter { it != "" } 62 | .map { it.split(",") } 63 | .map { (a, b, c, d) -> 64 | GoogleJavaFormatResult(a, b.toLong(), c.toLong(), d) 65 | } 66 | .sortedBy { it.fileName } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.stream.StreamHelpersTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.tree.TreePerformance.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /autograder/src/test/kotlin/edu/rice/autograder/VerifyTestAnnotations.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | import org.junit.jupiter.api.Assertions.assertEquals 10 | import org.junit.jupiter.api.Assertions.assertTrue 11 | import org.junit.jupiter.api.DynamicTest 12 | import org.junit.jupiter.api.DynamicTest.dynamicTest 13 | import org.junit.jupiter.api.Test 14 | import org.junit.jupiter.api.TestFactory 15 | 16 | class VerifyTestAnnotations { 17 | internal val result = scanEverything("edu.rice.autogradertest") 18 | 19 | @Test 20 | fun testDataSanityTest() { 21 | assertEquals(5, result["TP1"]?.topics?.flatMap { it.tests }?.size ?: -1) 22 | assertEquals(6, result["TP2"]?.topics?.flatMap { it.tests }?.size ?: -1) 23 | assertEquals(2, result["TP3"]?.topics?.flatMap { it.tests }?.size ?: -1) 24 | } 25 | 26 | private fun testSaneDouble(s: String, d: Double): DynamicTest = dynamicTest(s) { 27 | assertTrue(d.isFinite()) 28 | assertTrue(d >= 0.0) 29 | } 30 | 31 | // We've got code in the scanner that will note if it ever finds conditions like this, 32 | // but it's handy to still test for it. 33 | @TestFactory 34 | fun noNaNsAnywhere(): Iterable = result.keys 35 | .flatMap { key -> 36 | result[key]?.topics?.flatMap { topic -> 37 | val prefixStr = "Key ($key), Topic(${topic.name})" 38 | val testMaxPoints = 39 | dynamicTest("$prefixStr, MaxPoints") { 40 | assertTrue(topic.maxPoints.isFinite()); assertTrue(topic.maxPoints >= 0) 41 | } 42 | val methodTests = 43 | topic.tests.flatMap { test -> 44 | listOf( 45 | testSaneDouble( 46 | "$prefixStr, ${test.className} / ${test.methodName}", 47 | test.points 48 | ), 49 | testSaneDouble( 50 | "$prefixStr, ${test.className} / ${test.methodName}", 51 | test.points 52 | ) 53 | ) 54 | } 55 | methodTests + testMaxPoints 56 | } ?: emptyList() 57 | } 58 | 59 | @Test 60 | fun printTP1() { 61 | // Doesn't do much, but if there's an exception anywhere here, the test will fail 62 | print(scanEverything("edu.rice.autogradertest").yamlExporter("TP1")) 63 | } 64 | 65 | @Test 66 | fun printTP2() { 67 | print(scanEverything("edu.rice.autogradertest").yamlExporter("TP2")) 68 | } 69 | 70 | @Test 71 | fun printTP3() { 72 | print(scanEverything("edu.rice.autogradertest").yamlExporter("TP3")) 73 | } 74 | 75 | @Test 76 | fun textExportImportEquality() { 77 | // This test makes sure that we don't lose anything between writing YAML out and 78 | // reading it back in again. 79 | result.forEach { (name, project) -> 80 | assertEquals(project, yamlImporter(project.yamlExporter()).getOrFail(), name) 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.sexpr.SimpleScannerTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /autograder/src/main/kotlin/edu/rice/autograder/CheckStyleScanner.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | import com.fasterxml.jackson.annotation.JsonProperty 10 | import com.fasterxml.jackson.annotation.JsonRootName 11 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty 12 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement 13 | import com.fasterxml.jackson.module.kotlin.readValue 14 | 15 | // CheckStyle's XML looks like this: 16 | // 17 | // 18 | // 19 | // 20 | // 21 | // 22 | // 23 | // 24 | // 25 | // ... 26 | // 27 | 28 | // So, what we're looking for are any entities that have entities inside. If we see 29 | // any of them, then we indicate a failure. 30 | 31 | @JsonRootName("checkstyle") 32 | data class CheckStyleResults( 33 | @set:JsonProperty("file") 34 | var files: List = emptyList() 35 | ) 36 | 37 | @JsonRootName("file") 38 | data class CheckStyleFile( 39 | @set:JacksonXmlProperty(localName = "name", isAttribute = true) 40 | var name: String? = null, 41 | 42 | @set:JsonProperty("error") 43 | var errors: List = emptyList() 44 | ) 45 | 46 | @JacksonXmlRootElement(localName = "error") 47 | data class CheckStyleError( 48 | @set:JacksonXmlProperty(localName = "line", isAttribute = true) 49 | var line: String? = null, 50 | 51 | @set:JacksonXmlProperty(localName = "severity", isAttribute = true) 52 | var severity: String? = null, 53 | 54 | @set:JacksonXmlProperty(localName = "message", isAttribute = true) 55 | var message: String? = null, 56 | 57 | @set:JacksonXmlProperty(localName = "source", isAttribute = true) 58 | var source: String? = null 59 | ) 60 | 61 | private const val TAG = "CheckStyle" 62 | 63 | fun checkStyleMissing(moduleName: String) = 64 | CodeStyleDeduction("$TAG ($moduleName): report not found", 0.0, TAG, moduleName, false, 0, 0) 65 | 66 | fun checkStyleParser(fileData: String): CheckStyleResults? { 67 | Log.i(TAG, "checkStyleParser: ${fileData.length} bytes") 68 | 69 | return if (fileData.isEmpty()) null 70 | else jacksonXmlMapper.readValue(fileData) 71 | } 72 | 73 | /** You'll typically run this twice: once for "test" and once for "main". */ 74 | fun CheckStyleResults?.eval(moduleName: String): CodeStyleDeduction { 75 | if (this == null) { 76 | return checkStyleMissing(moduleName) 77 | } 78 | 79 | val numFiles = files.count() 80 | val numCleanFiles = files.count { it.errors.isEmpty() } 81 | 82 | val errorMsg = "CheckStyle ($moduleName): $numCleanFiles of $numFiles files passed" 83 | Log.i(TAG, "checkStyleEvaluator: $moduleName --> $errorMsg") 84 | 85 | val passing = numFiles == numCleanFiles 86 | return CodeStyleDeduction(errorMsg, 0.0, TAG, moduleName, passing, numCleanFiles, numFiles) 87 | } 88 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.util.LogTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 1 15 | 2019-03-29 09:20:35,894 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - "New" -> 3 16 | 2019-03-29 09:20:35,894 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - "World" -> 5 17 | 2019-03-29 09:20:35,895 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - "To" -> 2 18 | 2019-03-29 09:20:35,895 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - "Play" -> 4 19 | 2019-03-29 09:20:35,895 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - "With" -> 4 20 | 2019-03-29 09:20:35,895 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - "Lambda" -> 6 21 | 2019-03-29 09:20:35,896 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - (0, "A") -> 1 22 | 2019-03-29 09:20:35,897 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - (1, "New") -> 4 23 | 2019-03-29 09:20:35,897 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - (4, "World") -> 9 24 | 2019-03-29 09:20:35,897 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - (9, "To") -> 11 25 | 2019-03-29 09:20:35,897 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - (11, "Play") -> 15 26 | 2019-03-29 09:20:35,897 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - (15, "With") -> 19 27 | 2019-03-29 09:20:35,897 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - (19, "Lambda") -> 25 28 | 2019-03-29 09:20:35,898 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - starting basicTest 29 | 2019-03-29 09:20:35,899 [Test worker] ?[1;31mERROR?[0;39m ?[36mLogTest?[0;39m - some error 30 | 2019-03-29 09:20:35,899 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - trying out lambdas 31 | 2019-03-29 09:20:35,899 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - Lambda 100 1000 32 | 2019-03-29 09:20:35,899 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - Formatted 100 1000 33 | 2019-03-29 09:20:35,900 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - messing with log levels 34 | 2019-03-29 09:20:35,900 [Test worker] ?[1;31mERROR?[0;39m ?[36mLogTest?[0;39m - should see this (1/1) 35 | 2019-03-29 09:20:35,900 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - finishing basicTest 36 | 2019-03-29 09:20:35,901 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - Logback: file:/Users/dwallach/IdeaProjects/comp215-code/build/resources/main/logback.xml 37 | 2019-03-29 09:20:35,902 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - And now, we log some other things besides strings 38 | 2019-03-29 09:20:35,903 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - Some(Hello Rice Owls!) 39 | 2019-03-29 09:20:35,903 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - None 40 | 2019-03-29 09:20:35,903 [Test worker] ?[34mINFO ?[0;39m ?[36mLogTest?[0;39m - List(Hello, Rice, Owls) 41 | ]]> 42 | 43 | 44 | -------------------------------------------------------------------------------- /autograder/src/test/resources/comp215-build/test-results/test/TEST-edu.rice.prettypictures.TestGenesWeek1Test.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /autograder/src/main/java/edu/rice/autograder/annotations/GradeProject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder.annotations; 8 | 9 | import java.lang.annotation.Documented; 10 | import java.lang.annotation.ElementType; 11 | import java.lang.annotation.Repeatable; 12 | import java.lang.annotation.Retention; 13 | import java.lang.annotation.RetentionPolicy; 14 | import java.lang.annotation.Target; 15 | 16 | /** 17 | * This annotation is the top-level annotation for a programming "project". It specifies the name of 18 | * the project, an optional description, as well as an optional maxPoints. If missing, 19 | * the maximum number of points will be computed from all of the specified {@link Grade} annotations 20 | * for the project. Otherwise, it's entirely possible to have more deductions available from Grade 21 | * annotations than points present. The ultimate grade will never go below zero. 22 | * 23 | *

It's also possible to specify here a requirement that there be zeroWarnings. The 24 | * autograder will look at whether the Java compiler (and ErrorProne, if it's configured to run 25 | * alongside it) produced any warnings. By default, it also considers CheckStyle and 26 | * google-java-format. If zeroWarnings is true, then the number of points to be deducted is 27 | * specified by warningPoints. Each of these individual checks can be disabled with optional 28 | * parameters like useCheckStyle or useGoogleJavaFormat. 29 | * 30 | *

To specify a coverage requirement, specify a non-zero coveragePoints, and optionally 31 | * specify the coverageStyle and coveragePercentage. Then, annotate source classes on 32 | * which you want coverage to be measured using {@link GradeCoverage}. 33 | */ 34 | @Retention(RetentionPolicy.RUNTIME) 35 | @Target({ElementType.TYPE, ElementType.PACKAGE}) 36 | @Repeatable(GradeProjects.class) 37 | @Documented 38 | public @interface GradeProject { 39 | /** Specifies the name of the project being graded (e.g., "Week1"). */ 40 | String name(); 41 | 42 | /** 43 | * Specifies an optional description of the project which will appear in the autograder report. 44 | */ 45 | String description() default ""; 46 | 47 | /** 48 | * Specifies the maximum number of points to be associated with this project. If ignored, it will 49 | * be computed from all the different Grade annotations associated with the project. 50 | */ 51 | double maxPoints() default 0.0; 52 | 53 | /** 54 | * Specifies whether zero warnings are required from CheckStyle and so forth. If any warnings 55 | * appear, then the points specific here will deducted. Defaults to zero. 56 | */ 57 | double warningPoints() default 0.0; 58 | 59 | /** Specifies whether CheckStyle is considered as part of the warningPoints. Defaults to true. */ 60 | boolean useCheckStyle() default true; 61 | 62 | /** 63 | * Specifies whether GoogleJavaFormat is considered as part of the warningPoints. Defaults to 64 | * true. 65 | */ 66 | boolean useGoogleJavaFormat() default true; 67 | 68 | /** 69 | * Specifies whether Java compiler warnings are considered as part of the warningPoints. Defaults 70 | * to true. (If you've enabled ErrorProne, its warnings are included alongside the Java compiler's 71 | * warnings.) 72 | */ 73 | boolean useJavacWarnings() default true; 74 | 75 | /** If JaCoCo code coverage is required for this project, specify a non-zero point value here. */ 76 | double coveragePoints() default 0.0; 77 | 78 | /** Specifies a JaCoCo coverage ratio as a percentage (e.g., 70) */ 79 | int coveragePercentage() default 0; 80 | 81 | /** Specifies a JaCoCo coverage testing method (currently supports "LINES" or "INSTRUCTIONS"). */ 82 | String coverageMethod() default "LINES"; 83 | } 84 | -------------------------------------------------------------------------------- /exampleRpn/src/main/java/edu/rice/rpn/RpnCalc.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.rpn; 8 | 9 | import edu.rice.autograder.annotations.GradeCoverage; 10 | import java.util.ArrayDeque; 11 | import java.util.stream.Collectors; 12 | 13 | @GradeCoverage(project = "RPN") 14 | class RpnCalc { 15 | // Try replacing this with LinkedList, and the code will all run correctly, 16 | // but ErrorProne will generate a warning. 17 | ArrayDeque stack = new ArrayDeque<>(); 18 | 19 | // Code here borrowed from RosettaCode and then changed to make it more 20 | // amenable for unit testing. 21 | // http://www.rosettacode.org/wiki/Parsing/RPN_calculator_algorithm#Java_2 22 | 23 | public RpnCalc() {} 24 | 25 | public String eval(String expr) { 26 | // Try eliminating the optional "-1" argument to split and 27 | // you'll see ErrorProne generate a warning, but all the 28 | // unit tests will still pass. 29 | for (String token : expr.split("\\s+", -1)) { 30 | Double tokenNum; 31 | try { 32 | tokenNum = Double.parseDouble(token); 33 | } catch (NumberFormatException e) { 34 | tokenNum = null; 35 | } 36 | if (tokenNum != null) { 37 | stack.push(Double.parseDouble(token)); 38 | } else { 39 | double firstOperand; 40 | double secondOperand; 41 | 42 | switch (token) { 43 | case "*": 44 | secondOperand = stack.pop(); 45 | firstOperand = stack.pop(); 46 | stack.push(firstOperand * secondOperand); 47 | break; 48 | case "/": 49 | secondOperand = stack.pop(); 50 | firstOperand = stack.pop(); 51 | stack.push(firstOperand / secondOperand); 52 | break; 53 | case "-": 54 | secondOperand = stack.pop(); 55 | firstOperand = stack.pop(); 56 | stack.push(firstOperand - secondOperand); 57 | break; 58 | case "+": 59 | secondOperand = stack.pop(); 60 | firstOperand = stack.pop(); 61 | stack.push(firstOperand + secondOperand); 62 | break; 63 | case "^": 64 | secondOperand = stack.pop(); 65 | firstOperand = stack.pop(); 66 | stack.push(Math.pow(firstOperand, secondOperand)); 67 | break; 68 | case "dup": 69 | stack.push(stack.getFirst()); 70 | break; 71 | case "drop": 72 | stack.pop(); 73 | break; 74 | case "swap": 75 | secondOperand = stack.pop(); 76 | firstOperand = stack.pop(); 77 | stack.push(secondOperand); 78 | stack.push(firstOperand); 79 | break; 80 | default: 81 | // just in case 82 | throw new RuntimeException("Unknown operation"); 83 | } 84 | } 85 | } 86 | return stack.isEmpty() ? "Empty" : stack.getFirst().toString(); 87 | } 88 | 89 | // Everything below here is completely contrived code for the sole 90 | // purpose of exercising and testing our handling of code coverage 91 | // of anonymous inner classes. 92 | 93 | interface StackVisitor { 94 | T visit(double value); 95 | } 96 | 97 | public String mapThenJoin(StackVisitor sv) { 98 | return stack.stream().map(sv::visit).collect(Collectors.joining(", ")); 99 | } 100 | 101 | @Override 102 | public String toString() { 103 | return mapThenJoin( 104 | new StackVisitor() { 105 | @Override 106 | public String visit(double value) { 107 | return Double.toString(value); 108 | } 109 | }); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /exampleRegex/src/test/java/edu/rice/regex/TestPatterns.java: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.regex; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertFalse; 10 | import static org.junit.jupiter.api.Assertions.assertTrue; 11 | import static org.junit.jupiter.api.DynamicTest.dynamicTest; 12 | 13 | import edu.rice.autograder.annotations.Grade; 14 | import edu.rice.autograder.annotations.GradeProject; 15 | import edu.rice.autograder.annotations.GradeTopic; 16 | import java.util.Arrays; 17 | import java.util.List; 18 | import java.util.function.Predicate; 19 | import java.util.regex.Pattern; 20 | import java.util.stream.Collectors; 21 | import java.util.stream.Stream; 22 | import org.junit.jupiter.api.DynamicTest; 23 | import org.junit.jupiter.api.TestFactory; 24 | 25 | @GradeProject(name = "RE", description = "Writing regular expressions", warningPoints = 1.0) 26 | @GradeTopic(project = "RE", topic = "Identifiers") 27 | @GradeTopic(project = "RE", topic = "Numbers") 28 | public class TestPatterns { 29 | @Grade(project = "RE", topic = "Identifiers", points = 0.5, maxPoints = 1.5) 30 | @TestFactory 31 | List testClassIdentifiers() { 32 | List goodClassNames = 33 | Arrays.asList("Alice", "Bob", "Charlie", "CamelCaseClasses", "Thing1", "Thing2"); 34 | List badClassNames = 35 | Arrays.asList( 36 | "alice", 37 | "bob", 38 | "charlie", 39 | "camelCaseClasses", 40 | "xThing1", 41 | "xThing2", 42 | "Thing$Thing", 43 | "Thing Thing", 44 | " Thing", 45 | "Thing ", 46 | "Thing_Thing"); 47 | 48 | return goodAndBad(goodClassNames, badClassNames, Patterns.classPattern); 49 | } 50 | 51 | @Grade(project = "RE", topic = "Identifiers", points = 0.5, maxPoints = 1.5) 52 | @TestFactory 53 | List testMethodIdentifiers() { 54 | List goodMethodNames = 55 | Arrays.asList("alice", "bob", "charlie", "camelCaseNames", "thing1", "thing2"); 56 | List badMethodNames = 57 | Arrays.asList( 58 | "Alice", 59 | "Bob", 60 | "Charlie", 61 | "CamelCaseNames", 62 | "XThing1", 63 | "XThing2", 64 | "thing$Thing", 65 | "thing Thing", 66 | " thing", 67 | "thing ", 68 | "thing_Thing"); 69 | 70 | return goodAndBad(goodMethodNames, badMethodNames, Patterns.methodPattern); 71 | } 72 | 73 | @Grade(project = "RE", topic = "Numbers", points = 1, maxPoints = 1) 74 | @TestFactory 75 | List testIntegerUnderscores() { 76 | List goodNumbers = Arrays.asList("234_567", "2_3_4_5_6_7", "-234_567_890L"); 77 | List badNumbers = Arrays.asList("_234_567", "2__3_4_5_6_7", "8_"); 78 | 79 | return goodAndBad(goodNumbers, badNumbers, Patterns.integerPattern); 80 | } 81 | 82 | @Grade(project = "RE", topic = "Numbers", points = 1, maxPoints = 5) 83 | @TestFactory 84 | List testIntegers() { 85 | List goodNumbers = Arrays.asList("-29", "-3", "-0", "0", "1", "22", "9285", "0L", "1L"); 86 | List badNumbers = 87 | Arrays.asList( 88 | "-029", "-03", "-00", "00", "0-", "0-0", "1f", "0x22", "9285.3", "10e5", "NaN"); 89 | 90 | return goodAndBad(goodNumbers, badNumbers, Patterns.integerPattern); 91 | } 92 | 93 | private static List goodAndBad( 94 | List goodExamples, List badExamples, String regex) { 95 | 96 | Predicate regexPredicate = s -> Pattern.compile(regex).matcher(s).matches(); 97 | 98 | Stream positiveTests = 99 | goodExamples.stream() 100 | .map(s -> dynamicTest("Good: " + s, () -> assertTrue(regexPredicate.test(s)))); 101 | Stream negativeTests = 102 | badExamples.stream() 103 | .map(s -> dynamicTest("Bad: " + s, () -> assertFalse(regexPredicate.test(s)))); 104 | 105 | return Stream.concat(positiveTests, negativeTests).collect(Collectors.toList()); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /autograder/src/main/kotlin/edu/rice/autograder/EvaluatorResult.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | package edu.rice.autograder 8 | 9 | /** 10 | * The expectation is that every grade "evaluator" will return one of these, or 11 | * maybe a list of them, indicating whether full marks were given and how many 12 | * points were awarded. 13 | * 14 | * Note that this class doesn't do any arithmetic on the deductions or 15 | * points. The expectation is that the [deductions] listed here will be printed, 16 | * but not accumulated, and the [points] will be printed *and* accumulated. 17 | * Similarly, the [passes] fields will be subject to a boolean-and to discover 18 | * whether the entire project passes. 19 | */ 20 | data class EvaluatorResult( 21 | val passes: Boolean, 22 | val points: Double, 23 | val maxPoints: Double, 24 | val title: String, // meant for the human-readable report 25 | val category: String, // meant for the machine-readable report 26 | val deductions: List 27 | ) 28 | 29 | /** 30 | * The pairs of string/double for the deductions field are for printing 31 | * to the user to explain what went right or wrong. For something that 32 | * went correctly, the [description] might be `googleJavaStyle: 35/35 33 | * files formatted correctly` with a [cost] of 0.0. For something that 34 | * went wrong, the description will give correspondingly useful information 35 | * and the **cost should have a positive number**. They'll be printed with 36 | * negative signs added later. 37 | * 38 | * The human-readable report generator only pays attention to the 39 | * [description] and [cost] fields, which are defined here in the Deduction 40 | * interface. All the concrete implementations of Deduction, below, are then 41 | * required to implement these two properties and then whatever else they 42 | * want, which is only used for the machine-readable reports. See the 43 | * [ResultsReport] class and its associated methods for details. 44 | */ 45 | interface Deduction { 46 | val description: String 47 | val cost: Double 48 | 49 | operator fun component1() = description 50 | operator fun component2() = cost 51 | } 52 | 53 | data class BasicDeduction( 54 | override val description: String, 55 | override val cost: Double 56 | ) : Deduction 57 | 58 | data class UnitTestDeduction( 59 | override val description: String, 60 | override val cost: Double, 61 | val testName: String 62 | ) : Deduction 63 | 64 | data class UnitTestFactoryDeduction( 65 | override val description: String, 66 | override val cost: Double, 67 | val testName: String, 68 | val numPassed: Int, 69 | val numChecked: Int 70 | ) : Deduction 71 | 72 | data class CodeStyleDeduction( 73 | override val description: String, 74 | override val cost: Double, 75 | val toolName: String, 76 | val section: String, 77 | val passing: Boolean, 78 | val numPassed: Int, 79 | val numChecked: Int 80 | ) : Deduction 81 | 82 | data class CoverageDeduction( 83 | override val description: String, 84 | override val cost: Double, 85 | val className: String, 86 | val coveragePercentage: Double 87 | ) : Deduction 88 | 89 | /** When we have a passing result with no deductions to report, this simplifies things. */ 90 | fun passingEvaluatorResult(happyPoints: Double, happyTitle: String, happyCategory: String) = 91 | EvaluatorResult(true, happyPoints, happyPoints, happyTitle, happyCategory, emptyList()) 92 | 93 | // Engineering notes: 94 | // There are many really cool things going on here. First is just Kotlin being great. 95 | // We're defining the Deduction interface to have two "properties" which every 96 | // implementing class is then required to override. This isn't class inheritance. 97 | // If this were in Java, the interface would define getters for description and 98 | // cost, and each class would override those two methods. But because it's Kotlin, 99 | // those getters are coated in nice layer of syntactic sugar and become "properties". 100 | 101 | // Also Kotlin being great are the "operator fun componentN()" methods, which 102 | // allow for all of these classes to be "destructured" when they're the argument 103 | // to a lambda or whatever else. 104 | 105 | // Lastly, these data classes are directly read by Jackson (no doubt using Java 106 | // reflection under the hood), so what you see here maps one-to-one with what's 107 | // ultimately written out in our machine-readable reports. 108 | -------------------------------------------------------------------------------- /exampleRegex/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | buildscript { 8 | ext.gradeProject = "RE" 9 | ext.gradePackage = "edu.rice.regex" 10 | ext.gradeConfig = "config/grade.yml" 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | jcenter() 16 | } 17 | } 18 | 19 | plugins { 20 | id 'java' 21 | id 'checkstyle' 22 | id 'jacoco' 23 | // id "net.ltgt.errorprone" version "0.7.1" // JDK9+ 24 | // id 'net.ltgt.errorprone' version '0.0.14' // JDK8 25 | id "net.ltgt.errorprone" version "3.0.1" 26 | id 'com.github.sherter.google-java-format' version '0.8' 27 | } 28 | 29 | group 'edu.rice' 30 | version '1.0' 31 | 32 | checkstyle { 33 | toolVersion('8.17') 34 | } 35 | 36 | allprojects { 37 | // Makes the "javadoc" action run without a ton of warnings. 38 | tasks.withType(Javadoc) { 39 | options.addStringOption('Xdoclint:none', '-quiet') 40 | } 41 | 42 | tasks.withType(JavaCompile) { 43 | options.fork = true 44 | options.incremental = true 45 | options.encoding = "UTF-8" 46 | 47 | options.compilerArgs << "-Xlint:all" << "-Xlint:-serial" << "-Xlint:-processing" << 48 | "-Xlint:-deprecation" << "-Xep:UnusedVariable:OFF" << "-Xep:UnusedMethod:OFF" 49 | 50 | sourceCompatibility = '1.8' 51 | targetCompatibility = '1.8' 52 | } 53 | } 54 | 55 | //////////////////////////////////////////////////////////////////////////////// 56 | // This section configures JaCoCo (Java Code Coverage), JUnit (unit tests), GoogleJavaFormat, 57 | // and the autograder. 58 | 59 | jacoco { 60 | toolVersion = "0.8.3" 61 | } 62 | 63 | jacocoTestReport { 64 | reports { 65 | xml.enabled = true 66 | csv.enabled = false 67 | html.destination file("${buildDir}/reports/jacoco/") 68 | } 69 | } 70 | 71 | // We need to capture the errors and warnings printed by the Java compiler. 72 | // Everything else is already written into the build directory, but not this. 73 | 74 | task initLogFile { 75 | doLast { 76 | file("$buildDir").mkdir() 77 | file("$buildDir/logs").mkdir() 78 | def gradleBuildLog = file("$buildDir/logs/compile.log") 79 | gradleBuildLog.write("") // empty write forces file to exist with size 0 80 | 81 | def fileLogger = new StandardOutputListener() { 82 | void onOutput(CharSequence output) { 83 | gradleBuildLog << output 84 | } 85 | } 86 | 87 | tasks.withType(JavaCompile) { 88 | logger.info("compilation logging for $it") 89 | logging.addStandardOutputListener(fileLogger) 90 | logging.addStandardErrorListener(fileLogger) 91 | } 92 | } 93 | } 94 | 95 | compileJava.dependsOn initLogFile 96 | 97 | test { 98 | useJUnitPlatform() 99 | outputs.upToDateWhen { false } 100 | 101 | minHeapSize = "512m" 102 | maxHeapSize = "2048m" 103 | jvmArgs = ["-Xss128m"] 104 | ignoreFailures true 105 | } 106 | 107 | googleJavaFormat { 108 | toolVersion = '1.7' 109 | } 110 | 111 | import com.github.sherter.googlejavaformatgradleplugin.VerifyGoogleJavaFormat 112 | task autograderVerifyGoogleJavaFormat(type: VerifyGoogleJavaFormat) { 113 | source 'src/main' 114 | source 'src/test' 115 | include '**/*.java' 116 | ignoreFailures true 117 | } 118 | 119 | task autograder { 120 | dependsOn 'classes', 'jacocoTestCoverageVerification', 'jacocoTestReport', 121 | 'autograderVerifyGoogleJavaFormat', 'checkstyleMain', 'checkstyleTest', 'test' 122 | 123 | doLast { 124 | // See: https://github.com/RiceComp215-Staff/RiceChecks/issues/5 125 | gradle.buildFinished { ignoredResult -> 126 | project.javaexec { 127 | classpath = sourceSets.main.runtimeClasspath 128 | main = "edu.rice.autograder.AutoGraderKt" 129 | args = [ "--project", gradeProject, 130 | "--config", gradeConfig, 131 | "grade" ] 132 | } 133 | } 134 | } 135 | } 136 | 137 | task autograderDebugAnnotations (type: JavaExec) { 138 | classpath([sourceSets.main.runtimeClasspath, sourceSets.test.runtimeClasspath]) 139 | main = "edu.rice.autograder.AutoGraderKt" 140 | args = [ "--package", gradePackage, "--project", gradeProject, "debugAnnotations" ] 141 | } 142 | 143 | task autograderWriteConfig (type: JavaExec) { 144 | classpath([sourceSets.main.runtimeClasspath, sourceSets.test.runtimeClasspath]) 145 | main = "edu.rice.autograder.AutoGraderKt" 146 | args = [ "--package", gradePackage, "--project", gradeProject, "--config", gradeConfig, "writeConfig" ] 147 | } 148 | 149 | //////////////////////////////////////////////////////////////////////////////// 150 | // This section specifies all the external libraries being used by your Java 151 | // program and where to find them. 152 | repositories { 153 | mavenLocal() 154 | google() 155 | mavenCentral() 156 | } 157 | 158 | dependencies { 159 | // this creates a dependency on the autograder subproject: see the README.md 160 | // file for how to set up a standalone project 161 | implementation project (':autograder') 162 | 163 | // logging 164 | implementation 'ch.qos.logback:logback-classic:1.2.9' 165 | 166 | // annotations to help ErrorProne and IntelliJ find bugs 167 | implementation 'org.jetbrains:annotations:15.0' 168 | implementation 'com.google.code.findbugs:jsr305:3.0.2' 169 | implementation 'com.google.code.findbugs:annotations:3.0.1' 170 | implementation 'com.google.errorprone:error_prone_annotations:2.3.3' 171 | 172 | // JUnit5 support 173 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2' 174 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2' 175 | } 176 | -------------------------------------------------------------------------------- /exampleRpn/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | buildscript { 8 | ext.gradeProject = "RPN" 9 | ext.gradePackage = "edu.rice.rpn" 10 | ext.gradeConfig = "config/grade.yml" 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | jcenter() 16 | } 17 | } 18 | 19 | plugins { 20 | id 'java' 21 | id 'checkstyle' 22 | id 'jacoco' 23 | // id "net.ltgt.errorprone" version "0.7.1" // JDK9+ 24 | // id 'net.ltgt.errorprone' version '0.0.14' // JDK8 25 | id "net.ltgt.errorprone" version "3.0.1" 26 | id 'com.github.sherter.google-java-format' version '0.8' 27 | } 28 | 29 | group 'edu.rice' 30 | version '1.0' 31 | 32 | checkstyle { 33 | toolVersion('8.17') 34 | } 35 | 36 | allprojects { 37 | // Makes the "javadoc" action run without a ton of warnings. 38 | tasks.withType(Javadoc) { 39 | options.addStringOption('Xdoclint:none', '-quiet') 40 | } 41 | 42 | tasks.withType(JavaCompile) { 43 | options.fork = true 44 | options.incremental = true 45 | options.encoding = "UTF-8" 46 | 47 | options.compilerArgs << "-Xlint:all" << "-Xlint:-serial" << "-Xlint:-processing" << 48 | "-Xlint:-deprecation" << "-Xep:UnusedVariable:OFF" << "-Xep:UnusedMethod:OFF" 49 | 50 | sourceCompatibility = '1.8' 51 | targetCompatibility = '1.8' 52 | } 53 | } 54 | 55 | //////////////////////////////////////////////////////////////////////////////// 56 | // This section configures JaCoCo (Java Code Coverage), JUnit (unit tests), GoogleJavaFormat, 57 | // and the autograder. 58 | 59 | jacoco { 60 | toolVersion = "0.8.3" 61 | } 62 | 63 | jacocoTestReport { 64 | reports { 65 | xml.enabled = true 66 | csv.enabled = false 67 | html.destination file("${buildDir}/reports/jacoco/") 68 | } 69 | } 70 | 71 | // We need to capture the errors and warnings printed by the Java compiler. 72 | // Everything else is already written into the build directory, but not this. 73 | 74 | task initLogFile { 75 | doLast { 76 | file("$buildDir").mkdir() 77 | file("$buildDir/logs").mkdir() 78 | def gradleBuildLog = file("$buildDir/logs/compile.log") 79 | gradleBuildLog.write("") // empty write forces file to exist with size 0 80 | 81 | def fileLogger = new StandardOutputListener() { 82 | void onOutput(CharSequence output) { 83 | gradleBuildLog << output 84 | } 85 | } 86 | 87 | tasks.withType(JavaCompile) { 88 | logger.info("compilation logging for $it") 89 | logging.addStandardOutputListener(fileLogger) 90 | logging.addStandardErrorListener(fileLogger) 91 | } 92 | } 93 | } 94 | 95 | compileJava.dependsOn initLogFile 96 | 97 | test { 98 | useJUnitPlatform() 99 | outputs.upToDateWhen { false } 100 | 101 | minHeapSize = "512m" 102 | maxHeapSize = "2048m" 103 | jvmArgs = ["-Xss128m"] 104 | ignoreFailures true 105 | } 106 | 107 | googleJavaFormat { 108 | toolVersion = '1.7' 109 | } 110 | 111 | import com.github.sherter.googlejavaformatgradleplugin.VerifyGoogleJavaFormat 112 | task autograderVerifyGoogleJavaFormat(type: VerifyGoogleJavaFormat) { 113 | source 'src/main' 114 | source 'src/test' 115 | include '**/*.java' 116 | ignoreFailures true 117 | } 118 | 119 | task autograder { 120 | dependsOn 'classes', 'jacocoTestCoverageVerification', 'jacocoTestReport', 121 | 'autograderVerifyGoogleJavaFormat', 'checkstyleMain', 'checkstyleTest', 'test' 122 | 123 | doLast { 124 | // See: https://github.com/RiceComp215-Staff/RiceChecks/issues/5 125 | gradle.buildFinished { ignoredResult -> 126 | project.javaexec { 127 | classpath = sourceSets.main.runtimeClasspath 128 | main = "edu.rice.autograder.AutoGraderKt" 129 | args = [ "--project", gradeProject, 130 | "--config", gradeConfig, 131 | "grade" ] 132 | } 133 | } 134 | } 135 | } 136 | 137 | task autograderDebugAnnotations (type: JavaExec) { 138 | dependsOn 'classes' 139 | classpath([sourceSets.main.runtimeClasspath, sourceSets.test.runtimeClasspath]) 140 | main = "edu.rice.autograder.AutoGraderKt" 141 | args = [ "--package", gradePackage, "--project", gradeProject, "debugAnnotations" ] 142 | } 143 | 144 | task autograderWriteConfig (type: JavaExec) { 145 | dependsOn 'classes' 146 | classpath([sourceSets.main.runtimeClasspath, sourceSets.test.runtimeClasspath]) 147 | main = "edu.rice.autograder.AutoGraderKt" 148 | args = [ "--package", gradePackage, "--project", gradeProject, "--config", gradeConfig, "writeConfig" ] 149 | } 150 | 151 | //////////////////////////////////////////////////////////////////////////////// 152 | // This section specifies all the external libraries being used by your Java 153 | // program and where to find them. 154 | repositories { 155 | mavenLocal() 156 | google() 157 | mavenCentral() 158 | } 159 | 160 | dependencies { 161 | // this creates a dependency on the autograder subproject: see the README.md 162 | // file for how to set up a standalone project 163 | implementation project (':autograder') 164 | 165 | // logging 166 | implementation 'ch.qos.logback:logback-classic:1.2.9' 167 | 168 | // annotations to help ErrorProne and IntelliJ find bugs 169 | implementation 'org.jetbrains:annotations:15.0' 170 | implementation 'com.google.code.findbugs:jsr305:3.0.2' 171 | implementation 'com.google.code.findbugs:annotations:3.0.1' 172 | implementation 'com.google.errorprone:error_prone_annotations:2.3.3' 173 | 174 | // JUnit5 support 175 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2' 176 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2' 177 | } 178 | -------------------------------------------------------------------------------- /exampleSort/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | buildscript { 8 | ext.gradeProject = "Sorting" 9 | ext.gradePackage = "edu.rice.sort" 10 | ext.gradeConfig = "config/grade.yml" 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | jcenter() 16 | } 17 | } 18 | 19 | plugins { 20 | id 'java' 21 | id 'checkstyle' 22 | id 'jacoco' 23 | // id "net.ltgt.errorprone" version "0.7.1" // JDK9+ 24 | // id 'net.ltgt.errorprone' version '0.0.14' // JDK8 25 | id "net.ltgt.errorprone" version "3.0.1" 26 | id 'com.github.sherter.google-java-format' version '0.8' 27 | } 28 | 29 | group 'edu.rice' 30 | version '1.0' 31 | 32 | checkstyle { 33 | toolVersion('8.17') 34 | } 35 | 36 | allprojects { 37 | // Makes the "javadoc" action run without a ton of warnings. 38 | tasks.withType(Javadoc) { 39 | options.addStringOption('Xdoclint:none', '-quiet') 40 | } 41 | 42 | tasks.withType(JavaCompile) { 43 | options.fork = true 44 | options.incremental = true 45 | options.encoding = "UTF-8" 46 | 47 | options.compilerArgs << "-Xlint:all" << "-Xlint:-serial" << "-Xlint:-processing" << 48 | "-Xlint:-deprecation" << "-Xep:UnusedVariable:OFF" << "-Xep:UnusedMethod:OFF" 49 | 50 | sourceCompatibility = '1.8' 51 | targetCompatibility = '1.8' 52 | } 53 | } 54 | 55 | //////////////////////////////////////////////////////////////////////////////// 56 | // This section configures JaCoCo (Java Code Coverage), JUnit (unit tests), GoogleJavaFormat, 57 | // and the autograder. 58 | 59 | jacoco { 60 | toolVersion = "0.8.3" 61 | } 62 | 63 | jacocoTestReport { 64 | reports { 65 | xml.enabled = true 66 | csv.enabled = false 67 | html.destination file("${buildDir}/reports/jacoco/") 68 | } 69 | } 70 | 71 | // We need to capture the errors and warnings printed by the Java compiler. 72 | // Everything else is already written into the build directory, but not this. 73 | 74 | task initLogFile { 75 | doLast { 76 | file("$buildDir").mkdir() 77 | file("$buildDir/logs").mkdir() 78 | def gradleBuildLog = file("$buildDir/logs/compile.log") 79 | gradleBuildLog.write("") // empty write forces file to exist with size 0 80 | 81 | def fileLogger = new StandardOutputListener() { 82 | void onOutput(CharSequence output) { 83 | gradleBuildLog << output 84 | } 85 | } 86 | 87 | tasks.withType(JavaCompile) { 88 | logger.info("compilation logging for $it") 89 | logging.addStandardOutputListener(fileLogger) 90 | logging.addStandardErrorListener(fileLogger) 91 | } 92 | } 93 | } 94 | 95 | compileJava.dependsOn initLogFile 96 | 97 | test { 98 | useJUnitPlatform() 99 | outputs.upToDateWhen { false } 100 | 101 | minHeapSize = "512m" 102 | maxHeapSize = "2048m" 103 | jvmArgs = ["-Xss128m"] 104 | ignoreFailures true 105 | } 106 | 107 | googleJavaFormat { 108 | toolVersion = '1.7' 109 | } 110 | 111 | import com.github.sherter.googlejavaformatgradleplugin.VerifyGoogleJavaFormat 112 | task autograderVerifyGoogleJavaFormat(type: VerifyGoogleJavaFormat) { 113 | source 'src/main' 114 | source 'src/test' 115 | include '**/*.java' 116 | ignoreFailures true 117 | } 118 | 119 | task autograder { 120 | dependsOn 'classes', 'jacocoTestCoverageVerification', 'jacocoTestReport', 121 | 'autograderVerifyGoogleJavaFormat', 'checkstyleMain', 'checkstyleTest', 'test' 122 | 123 | doLast { 124 | // See: https://github.com/RiceComp215-Staff/RiceChecks/issues/5 125 | gradle.buildFinished { ignoredResult -> 126 | project.javaexec { 127 | classpath = sourceSets.main.runtimeClasspath 128 | main = "edu.rice.autograder.AutoGraderKt" 129 | args = [ "--project", gradeProject, 130 | "--config", gradeConfig, 131 | "grade" ] 132 | } 133 | } 134 | } 135 | } 136 | 137 | task autograderDebugAnnotations (type: JavaExec) { 138 | dependsOn 'classes' 139 | classpath([sourceSets.main.runtimeClasspath, sourceSets.test.runtimeClasspath]) 140 | main = "edu.rice.autograder.AutoGraderKt" 141 | args = [ "--package", gradePackage, "--project", gradeProject, "--log", "all", "debugAnnotations" ] 142 | } 143 | 144 | task autograderWriteConfig (type: JavaExec) { 145 | dependsOn 'classes' 146 | classpath([sourceSets.main.runtimeClasspath, sourceSets.test.runtimeClasspath]) 147 | main = "edu.rice.autograder.AutoGraderKt" 148 | args = [ "--package", gradePackage, "--project", gradeProject, "--config", gradeConfig, "writeConfig" ] 149 | } 150 | 151 | //////////////////////////////////////////////////////////////////////////////// 152 | // This section specifies all the external libraries being used by your Java 153 | // program and where to find them. 154 | repositories { 155 | mavenLocal() 156 | google() 157 | mavenCentral() 158 | } 159 | 160 | dependencies { 161 | // this creates a dependency on the autograder subproject: see the README.md 162 | // file for how to set up a standalone project 163 | implementation project (':autograder') 164 | 165 | // logging 166 | implementation 'ch.qos.logback:logback-classic:1.2.9' 167 | 168 | // annotations to help ErrorProne and IntelliJ find bugs 169 | implementation 'org.jetbrains:annotations:15.0' 170 | implementation 'com.google.code.findbugs:jsr305:3.0.2' 171 | implementation 'com.google.code.findbugs:annotations:3.0.1' 172 | implementation 'com.google.errorprone:error_prone_annotations:2.3.3' 173 | 174 | // JUnit5 support 175 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2' 176 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2' 177 | 178 | // QuickTheories, for property-based testing 179 | testImplementation 'org.quicktheories:quicktheories:0.26' 180 | } 181 | -------------------------------------------------------------------------------- /standaloneSort/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * RiceChecks 3 | * Copyright (c) 2019, Dan S. Wallach, Rice University 4 | * Available subject to the Apache 2.0 License 5 | */ 6 | 7 | buildscript { 8 | ext.gradeProject = "Sorting" 9 | ext.gradePackage = "edu.rice.sort" 10 | ext.gradeConfig = "config/grade.yml" 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | jcenter() 16 | } 17 | } 18 | 19 | plugins { 20 | id 'java' 21 | id 'checkstyle' 22 | id 'jacoco' 23 | // id "net.ltgt.errorprone" version "0.7.1" // JDK9+ 24 | // id 'net.ltgt.errorprone' version '0.0.14' // JDK8 25 | id "net.ltgt.errorprone" version "3.0.1" 26 | id 'com.github.sherter.google-java-format' version '0.8' 27 | } 28 | 29 | group 'edu.rice' 30 | version '1.0' 31 | 32 | checkstyle { 33 | toolVersion('8.17') 34 | } 35 | 36 | allprojects { 37 | // Makes the "javadoc" action run without a ton of warnings. 38 | tasks.withType(Javadoc) { 39 | options.addStringOption('Xdoclint:none', '-quiet') 40 | } 41 | 42 | tasks.withType(JavaCompile) { 43 | options.fork = true 44 | options.incremental = true 45 | options.encoding = "UTF-8" 46 | 47 | options.compilerArgs << "-Xlint:all" << "-Xlint:-serial" << "-Xlint:-processing" << 48 | "-Xlint:-deprecation" << "-Xep:UnusedVariable:OFF" << "-Xep:UnusedMethod:OFF" 49 | 50 | sourceCompatibility = '1.8' 51 | targetCompatibility = '1.8' 52 | } 53 | } 54 | 55 | //////////////////////////////////////////////////////////////////////////////// 56 | // This section configures JaCoCo (Java Code Coverage), JUnit (unit tests), GoogleJavaFormat, 57 | // and the autograder. 58 | 59 | jacoco { 60 | toolVersion = "0.8.3" 61 | } 62 | 63 | jacocoTestReport { 64 | reports { 65 | xml.enabled = true 66 | csv.enabled = false 67 | html.destination file("${buildDir}/reports/jacoco/") 68 | } 69 | } 70 | 71 | // We need to capture the errors and warnings printed by the Java compiler. 72 | // Everything else is already written into the build directory, but not this. 73 | 74 | task initLogFile { 75 | doLast { 76 | file("$buildDir").mkdir() 77 | file("$buildDir/logs").mkdir() 78 | def gradleBuildLog = file("$buildDir/logs/compile.log") 79 | gradleBuildLog.write("") // empty write forces file to exist with size 0 80 | 81 | def fileLogger = new StandardOutputListener() { 82 | void onOutput(CharSequence output) { 83 | gradleBuildLog << output 84 | } 85 | } 86 | 87 | tasks.withType(JavaCompile) { 88 | logger.info("compilation logging for $it") 89 | logging.addStandardOutputListener(fileLogger) 90 | logging.addStandardErrorListener(fileLogger) 91 | } 92 | } 93 | } 94 | 95 | compileJava.dependsOn initLogFile 96 | 97 | test { 98 | useJUnitPlatform() 99 | outputs.upToDateWhen { false } 100 | 101 | minHeapSize = "512m" 102 | maxHeapSize = "2048m" 103 | jvmArgs = ["-Xss128m"] 104 | ignoreFailures true 105 | } 106 | 107 | googleJavaFormat { 108 | toolVersion = '1.7' 109 | } 110 | 111 | import com.github.sherter.googlejavaformatgradleplugin.VerifyGoogleJavaFormat 112 | task autograderVerifyGoogleJavaFormat(type: VerifyGoogleJavaFormat) { 113 | source 'src/main' 114 | source 'src/test' 115 | include '**/*.java' 116 | ignoreFailures true 117 | } 118 | 119 | configurations { 120 | ricechecks 121 | } 122 | 123 | task autograder { 124 | dependsOn 'classes', 'jacocoTestCoverageVerification', 'jacocoTestReport', 125 | 'autograderVerifyGoogleJavaFormat', 'checkstyleMain', 'checkstyleTest', 'test' 126 | 127 | doLast { 128 | // See: https://github.com/RiceComp215-Staff/RiceChecks/issues/5 129 | gradle.buildFinished { ignoredResult -> 130 | project.javaexec { 131 | classpath = configurations.ricechecks 132 | main = "edu.rice.autograder.AutoGraderKt" 133 | args = [ "--project", gradeProject, 134 | "--config", gradeConfig, 135 | "grade" ] 136 | } 137 | } 138 | } 139 | } 140 | 141 | task autograderDebugAnnotations (type: JavaExec) { 142 | dependsOn 'classes' 143 | classpath([configurations.ricechecks, sourceSets.main.runtimeClasspath, sourceSets.test.runtimeClasspath]) 144 | main = "edu.rice.autograder.AutoGraderKt" 145 | args = [ "--package", gradePackage, "--project", gradeProject, "--log", "all", "debugAnnotations" ] 146 | } 147 | 148 | task autograderWriteConfig (type: JavaExec) { 149 | dependsOn 'classes' 150 | classpath([configurations.ricechecks, sourceSets.main.runtimeClasspath, sourceSets.test.runtimeClasspath]) 151 | main = "edu.rice.autograder.AutoGraderKt" 152 | args = [ "--package", gradePackage, "--project", gradeProject, "--config", gradeConfig, "writeConfig" ] 153 | } 154 | 155 | //////////////////////////////////////////////////////////////////////////////// 156 | // This section specifies all the external libraries being used by your Java 157 | // program and where to find them. 158 | repositories { 159 | mavenLocal() 160 | maven { url "https://maven-central.storage.googleapis.com" } 161 | mavenCentral() 162 | } 163 | 164 | dependencies { 165 | // autograder annotations 166 | implementation 'edu.rice.ricechecks:ricechecks-annotations:0.8.0' 167 | 168 | // autograder tool 169 | ricechecks 'edu.rice.ricechecks:ricechecks:0.8.0' 170 | 171 | // logging 172 | implementation 'ch.qos.logback:logback-classic:1.2.9' 173 | 174 | // annotations to help ErrorProne and IntelliJ find bugs 175 | implementation 'org.jetbrains:annotations:15.0' 176 | implementation 'com.google.code.findbugs:jsr305:3.0.2' 177 | implementation 'com.google.code.findbugs:annotations:3.0.1' 178 | implementation 'com.google.errorprone:error_prone_annotations:2.3.3' 179 | 180 | // JUnit5 support 181 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2' 182 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2' 183 | 184 | // QuickTheories, for property-based testing 185 | testImplementation 'org.quicktheories:quicktheories:0.26' 186 | } 187 | --------------------------------------------------------------------------------