├── .appends └── .github │ └── labels.yml ├── .config └── dotnet-tools.json ├── .dockerignore ├── .editorconfig ├── .gitattributes ├── .github ├── CODEOWNERS ├── dependabot.yml ├── labels.yml └── workflows │ ├── deploy.yml │ ├── pause-community-contributions.yml │ ├── ping-cross-track-maintainers-team.yml │ ├── sync-labels.yml │ └── test.yml ├── .gitignore ├── .prettierignore ├── CODE_OF_CONDUCT.md ├── Dockerfile ├── Excercism.Analyzers.CSharp.sln ├── LICENSE ├── README.md ├── bin ├── run-in-docker.sh ├── run-tests-in-docker.sh ├── run-tests.sh ├── run.sh └── update-golden-tests.sh ├── src └── Exercism.Analyzers.CSharp │ ├── Analysis.cs │ ├── Analyzers │ ├── CollatzConjectureAnalyzer.cs │ ├── CommonAnalyzer.cs │ ├── DifferenceOfSquaresAnalyzer.cs │ ├── GigasecondAnalyzer.cs │ ├── GrainsAnalyzer.cs │ ├── IsogramAnalyzer.cs │ ├── LeapAnalyzer.cs │ ├── PangramAnalyzer.cs │ ├── ProteinTranslationAnalyzer.cs │ ├── RaindropsAnalyzer.cs │ ├── ReverseStringAnalyzer.cs │ ├── TagAnalyzer.cs │ ├── TwoFerAnalyzer.cs │ └── WeighingMachineAnalyzer.cs │ ├── Comments.cs │ ├── Exercism.Analyzers.CSharp.csproj │ ├── Loader.cs │ ├── Output.cs │ └── Program.cs └── tests ├── bank-account └── approaches │ ├── lock-statement │ ├── .meta │ │ └── config.json │ ├── BankAccount.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── mutex │ ├── .meta │ └── config.json │ ├── BankAccount.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── bob └── approaches │ ├── answer-array │ ├── .meta │ │ └── config.json │ ├── Bob.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── if │ ├── .meta │ │ └── config.json │ ├── Bob.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── regular-expressions │ ├── .meta │ │ └── config.json │ ├── Bob.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── switch-on-tuple │ ├── .meta │ └── config.json │ ├── Bob.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── collatz-conjecture └── approaches │ ├── recursion │ ├── .meta │ │ └── config.json │ ├── CollatzConjecture.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── sequence │ ├── .meta │ │ └── config.json │ ├── CollatzConjecture.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── while-loop │ ├── .meta │ └── config.json │ ├── CollatzConjecture.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── common ├── assign-and-return │ ├── .meta │ │ └── config.json │ ├── Common.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── has-compile-errors │ ├── .meta │ │ └── config.json │ ├── Errors.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── has-main-method │ ├── .meta │ │ └── config.json │ ├── Common.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── ignore-non-solution-files │ ├── .meta │ │ ├── Example.cs │ │ └── config.json │ ├── Additional.cs │ ├── Editor.cs │ ├── Invalidator.cs │ ├── Solution.cs │ ├── Solution.csproj │ ├── Tests.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── missing-solution-file │ ├── .meta │ │ └── config.json │ ├── expected_analysis.json │ └── expected_tags.json └── writes-to-console │ ├── console-error-write-line │ ├── .meta │ │ └── config.json │ ├── Errors.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── console-error-write │ ├── .meta │ │ └── config.json │ ├── Errors.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── console-out-write-line │ ├── .meta │ │ └── config.json │ ├── Errors.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── console-out-write │ ├── .meta │ │ └── config.json │ ├── Errors.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── console-write-line │ ├── .meta │ │ └── config.json │ ├── Errors.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── console-write │ ├── .meta │ └── config.json │ ├── Errors.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── darts └── approaches │ ├── if-statements │ ├── .meta │ │ └── config.json │ ├── Darts.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── switch-expression │ ├── .meta │ └── config.json │ ├── Darts.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── difference-of-squares └── approaches │ ├── for-statement │ ├── .meta │ │ └── config.json │ ├── DifferenceOfSquares.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── linq │ ├── .meta │ │ └── config.json │ ├── DifferenceOfSquares.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── math │ ├── equations-only │ ├── .meta │ │ └── config.json │ ├── Math.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── using-math-class │ ├── .meta │ └── config.json │ ├── Math.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── diffie-hellman └── approaches │ └── big-integer │ ├── .meta │ └── config.json │ ├── DiffieHellman.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── gigasecond ├── add-seconds │ ├── digits-with-separator │ │ ├── .meta │ │ │ └── config.json │ │ ├── Gigasecond.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── digits-without-separator │ │ ├── .meta │ │ │ └── config.json │ │ ├── Gigasecond.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── math-pow │ │ ├── .meta │ │ │ └── config.json │ │ ├── Gigasecond.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ └── scientific-notation │ │ ├── lower-case │ │ ├── .meta │ │ │ └── config.json │ │ ├── Gigasecond.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ │ └── upper-case │ │ ├── .meta │ │ └── config.json │ │ ├── Gigasecond.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json ├── add │ ├── .meta │ │ └── config.json │ ├── Gigasecond.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── approaches │ ├── add-seconds │ │ ├── .meta │ │ │ └── config.json │ │ ├── Gigasecond.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ └── time-span │ │ ├── .meta │ │ └── config.json │ │ ├── Gigasecond.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json ├── create-date-time │ ├── .meta │ │ └── config.json │ ├── Gigasecond.cs │ ├── expected_analysis.json │ └── expected_tags.json └── plus-operator │ ├── .meta │ └── config.json │ ├── Gigasecond.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── grade-school └── approaches │ └── sorted-collections │ ├── .meta │ └── config.json │ ├── GradeSchool.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── grains └── approaches │ ├── bit-shifting │ ├── .meta │ │ └── config.json │ ├── Grains.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── max-value │ ├── .meta │ │ └── config.json │ ├── Grains.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── pow │ ├── .meta │ └── config.json │ ├── Grains.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── hamming └── approaches │ ├── for-loop │ ├── .meta │ │ └── config.json │ ├── Hamming.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── linq │ ├── .meta │ └── config.json │ ├── Hamming.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── isogram └── approaches │ ├── bitfield │ ├── .meta │ │ └── config.json │ ├── Isogram.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── distinct │ ├── .meta │ │ └── config.json │ ├── Isogram.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── groupby │ ├── .meta │ └── config.json │ ├── Isogram.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── leap ├── approaches │ ├── boolean-chain │ │ ├── .meta │ │ │ └── config.json │ │ ├── Leap.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── built-in-method │ │ ├── .meta │ │ │ └── config.json │ │ ├── Leap.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── datetime-addition │ │ ├── .meta │ │ │ └── config.json │ │ ├── Leap.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── switch-on-a-tuple │ │ ├── .meta │ │ │ └── config.json │ │ ├── Leap.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ └── ternary-operator │ │ ├── .meta │ │ └── config.json │ │ ├── Leap.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json ├── if-statements │ ├── .meta │ │ └── config.json │ ├── Leap.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── nested-if-statement │ ├── .meta │ │ └── config.json │ ├── Leap.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── too-many-checks │ ├── .meta │ │ └── config.json │ ├── Leap.cs │ ├── expected_analysis.json │ └── expected_tags.json └── use-is-leap-year │ ├── block-body │ ├── .meta │ │ └── config.json │ ├── Leap.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── expression-body │ ├── .meta │ └── config.json │ ├── Leap.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── missing └── no-analyzer-implemented │ ├── .meta │ └── config.json │ ├── Missing.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── palindrome-products └── approaches │ └── factors-first │ ├── .meta │ └── config.json │ ├── PalindromeProducts.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── pangram └── approaches │ ├── all-contains-case-insensitive │ ├── .meta │ │ └── config.json │ ├── Pangram.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── all-contains-tolower │ ├── .meta │ │ └── config.json │ ├── Pangram.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── bitfield │ ├── .meta │ └── config.json │ ├── Pangram.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── parallel-letter-frequency └── approaches │ └── as-parallel │ ├── .meta │ └── config.json │ ├── ParallelLetterFrequency.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── perfect-numbers └── approaches │ ├── if-statements │ ├── .meta │ │ └── config.json │ ├── PerfectNumbers.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── switch-expression │ ├── .meta │ └── config.json │ ├── PerfectNumbers.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── phone-number └── approaches │ └── regular-expression │ ├── .meta │ └── config.json │ ├── PhoneNumber.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── pig-latin └── approaches │ └── regular-expressions │ ├── .meta │ └── config.json │ ├── PigLatin.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── poker └── approaches │ ├── icomparer │ ├── .meta │ │ └── config.json │ ├── Poker.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── integer-score │ ├── .meta │ └── config.json │ ├── Poker.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── protein-translation └── approaches │ ├── linq-dict │ ├── .meta │ │ └── config.json │ ├── ProteinTranslation.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── substring-dict │ ├── .meta │ │ └── config.json │ ├── ProteinTranslation.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── substring-switch │ ├── .meta │ │ └── config.json │ ├── ProteinTranslation.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── yield-dict │ ├── .meta │ │ └── config.json │ ├── ProteinTranslation.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── yield-switch │ ├── .meta │ └── config.json │ ├── ProteinTranslation.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── proverb └── approaches │ ├── for-loop │ ├── .meta │ │ └── config.json │ ├── Proverb.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── linq │ ├── .meta │ └── config.json │ ├── Proverb.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── raindrops └── approaches │ ├── aggregate │ ├── .meta │ │ └── config.json │ ├── Raindrops.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── if-statements │ ├── .meta │ └── config.json │ ├── Raindrops.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── reverse-string └── approaches │ ├── array-reverse │ ├── .meta │ │ └── config.json │ ├── ReverseString.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── linq │ ├── .meta │ │ └── config.json │ ├── ReverseString.cs │ ├── expected_analysis.json │ └── expected_tags.json │ ├── span │ ├── .meta │ │ └── config.json │ ├── ReverseString.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── string-builder │ ├── .meta │ └── config.json │ ├── ReverseString.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── rna-transcription └── approaches │ ├── dictionary │ ├── .meta │ │ └── config.json │ ├── RnaTranscription.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── switch-expression │ ├── .meta │ └── config.json │ ├── RnaTranscription.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── series └── approaches │ ├── for-loop │ ├── .meta │ │ └── config.json │ ├── Series.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── linq │ ├── .meta │ └── config.json │ ├── Series.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── sieve └── approaches │ ├── bit-array │ ├── .meta │ │ └── config.json │ ├── Sieve.cs │ ├── expected_analysis.json │ └── expected_tags.json │ └── hash-set │ ├── .meta │ └── config.json │ ├── Sieve.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── tags ├── constructs │ ├── comments │ │ ├── .meta │ │ │ └── config.json │ │ ├── Comments.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── compound-assignment │ │ ├── .meta │ │ │ └── config.json │ │ ├── CompoundAssignment.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── events │ │ ├── .meta │ │ │ └── config.json │ │ ├── Event.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── exceptions │ │ ├── .meta │ │ │ └── config.json │ │ ├── Exceptions.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── flow-control │ │ ├── .meta │ │ │ └── config.json │ │ ├── FlowControl.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── functional │ │ ├── .meta │ │ │ └── config.json │ │ ├── Functional.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── methods │ │ ├── .meta │ │ │ └── config.json │ │ ├── Methods.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── resources │ │ ├── .meta │ │ │ └── config.json │ │ ├── Resources.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ └── types │ │ ├── .meta │ │ └── config.json │ │ ├── Types.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json ├── paradigms │ └── reflective │ │ ├── .meta │ │ └── config.json │ │ ├── Reflective.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json ├── techniques │ └── recursion │ │ ├── .meta │ │ └── config.json │ │ ├── Recursion.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json └── uses │ └── types │ ├── basic │ ├── framework-types │ │ ├── .meta │ │ │ └── config.json │ │ ├── Types.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ ├── language-types │ │ ├── .meta │ │ │ └── config.json │ │ ├── Types.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ └── literals │ │ ├── .meta │ │ └── config.json │ │ ├── Types.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ └── collections │ └── framework-types │ ├── .meta │ └── config.json │ ├── Types.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── two-bucket └── approaches │ └── graph-shortest-path │ ├── .meta │ └── config.json │ ├── TwoBucket.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── two-fer ├── approaches │ ├── method-overloading │ │ ├── .meta │ │ │ └── config.json │ │ ├── TwoFer.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ └── optional-parameter │ │ ├── .meta │ │ └── config.json │ │ ├── TwoFer.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json ├── concatenation │ ├── .meta │ │ └── config.json │ ├── TwoFer.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── if │ ├── .meta │ │ └── config.json │ ├── TwoFer.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── interpolation │ ├── .meta │ │ └── config.json │ ├── TwoFer.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── invalid-default-value │ ├── .meta │ │ └── config.json │ ├── TwoFer.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── is-null-or-empty │ ├── .meta │ │ └── config.json │ ├── TwoFer.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── is-null-or-white-space │ ├── .meta │ │ └── config.json │ ├── TwoFer.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── null-coalescing │ ├── .meta │ │ └── config.json │ ├── TwoFer.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── string.concat │ ├── .meta │ │ └── config.json │ ├── TwoFer.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── string.format │ ├── .meta │ │ └── config.json │ ├── TwoFer.cs │ ├── expected_analysis.json │ └── expected_tags.json └── string.join │ ├── .meta │ └── config.json │ ├── TwoFer.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── weighing-machine ├── backing-field-should-be-private │ ├── .meta │ │ └── config.json │ ├── WeighingMachine.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── exemplar │ ├── .meta │ │ └── config.json │ ├── WeighingMachine.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── is-not-auto-property │ ├── property-precision │ │ ├── .meta │ │ │ └── config.json │ │ ├── WeighingMachine.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json │ └── property-tare-adjustment │ │ ├── .meta │ │ └── config.json │ │ ├── WeighingMachine.cs │ │ ├── expected_analysis.json │ │ └── expected_tags.json ├── precision-is-not-getter-only │ ├── .meta │ │ └── config.json │ ├── WeighingMachine.cs │ ├── expected_analysis.json │ └── expected_tags.json ├── round-method-called │ ├── .meta │ │ └── config.json │ ├── WeighingMachine.cs │ ├── expected_analysis.json │ └── expected_tags.json └── use-initializer │ ├── .meta │ └── config.json │ ├── WeighingMachine.cs │ ├── expected_analysis.json │ └── expected_tags.json └── yacht └── approaches └── linq ├── .meta └── config.json ├── Yacht.cs ├── expected_analysis.json └── expected_tags.json /.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-format": { 6 | "version": "5.1.250801", 7 | "commands": ["dotnet-format"] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !src/Exercism.Analyzers.CSharp 3 | src/Exercism.Analyzers.CSharp/bin 4 | src/Exercism.Analyzers.CSharp/obj 5 | !bin/run.sh 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.cs diff=csharp 3 | *.sh eol=lf 4 | *.sln eol=crlf -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @exercism/guardians 2 | 3 | /Dockerfile @exercism/ops 4 | /.dockerignore @exercism/ops 5 | /.github/CODEOWNERS @exercism/ops 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | # Keep GitHub Actions dependencies up-to-date 5 | - package-ecosystem: "github-actions" 6 | directory: "/" 7 | schedule: 8 | interval: 'monthly' 9 | 10 | # Keep NuGet dependencies up-to-date 11 | - package-ecosystem: "nuget" 12 | directory: "/" 13 | schedule: 14 | interval: 'monthly' 15 | 16 | # Keep Docker dependencies up-to-date 17 | - package-ecosystem: "docker" 18 | directory: "/" 19 | schedule: 20 | interval: 'monthly' 21 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | workflow_dispatch: 8 | 9 | permissions: 10 | contents: write 11 | 12 | jobs: 13 | build-and-push-image: 14 | if: github.repository_owner == 'exercism' # Stops this job from running on forks. 15 | uses: exercism/github-actions/.github/workflows/docker-build-push-image.yml@main 16 | secrets: 17 | AWS_ACCOUNT_ID: ${{secrets.AWS_ACCOUNT_ID}} 18 | AWS_REGION: ${{secrets.AWS_REGION}} 19 | AWS_ECR_ACCESS_KEY_ID: ${{secrets.AWS_ECR_ACCESS_KEY_ID}} 20 | AWS_ECR_SECRET_ACCESS_KEY: ${{secrets.AWS_ECR_SECRET_ACCESS_KEY}} 21 | DOCKERHUB_USERNAME: ${{secrets.DOCKERHUB_USERNAME}} 22 | DOCKERHUB_PASSWORD: ${{secrets.DOCKERHUB_PASSWORD}} 23 | -------------------------------------------------------------------------------- /.github/workflows/pause-community-contributions.yml: -------------------------------------------------------------------------------- 1 | name: Pause Community Contributions 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | pull_request_target: 8 | types: 9 | - opened 10 | 11 | permissions: 12 | issues: write 13 | pull-requests: write 14 | 15 | jobs: 16 | pause: 17 | if: github.repository_owner == 'exercism' # Stops this job from running on forks 18 | uses: exercism/github-actions/.github/workflows/community-contributions.yml@main 19 | with: 20 | forum_category: csharp 21 | secrets: 22 | github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }} 23 | -------------------------------------------------------------------------------- /.github/workflows/ping-cross-track-maintainers-team.yml: -------------------------------------------------------------------------------- 1 | name: Ping cross-track maintainers team 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | 8 | permissions: 9 | pull-requests: write 10 | 11 | jobs: 12 | ping: 13 | if: github.repository_owner == 'exercism' # Stops this job from running on forks 14 | uses: exercism/github-actions/.github/workflows/ping-cross-track-maintainers-team.yml@main 15 | secrets: 16 | github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }} 17 | -------------------------------------------------------------------------------- /.github/workflows/sync-labels.yml: -------------------------------------------------------------------------------- 1 | name: Tools 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - .github/labels.yml 9 | - .github/workflows/sync-labels.yml 10 | workflow_dispatch: 11 | schedule: 12 | - cron: 0 0 1 * * # First day of each month 13 | 14 | permissions: 15 | issues: write 16 | 17 | jobs: 18 | sync-labels: 19 | uses: exercism/github-actions/.github/workflows/labels.yml@main 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build files 2 | bin/ 3 | obj/ 4 | !/bin/ 5 | 6 | # IDE files 7 | .vs/ 8 | .vscode/ 9 | .idea/ 10 | 11 | # User files 12 | *.suo 13 | *.user 14 | *.userprefs 15 | 16 | # Package manager files 17 | .nuget 18 | .packages/ 19 | 20 | # Misc files 21 | *.DS_Store 22 | 23 | # Plugin files 24 | .ionide/ 25 | 26 | launchSettings.json 27 | 28 | # Generated analysis files 29 | /tests/**/*/analysis.json 30 | /tests/**/*/tags.json 31 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .ionide/ 3 | .vscode/ 4 | bin/ 5 | obj/ 6 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine3.20-amd64 AS build 2 | WORKDIR /app 3 | 4 | # Copy csproj and restore as distinct layer 5 | COPY src/Exercism.Analyzers.CSharp/Exercism.Analyzers.CSharp.csproj . 6 | RUN dotnet restore -r linux-musl-x64 7 | 8 | # Copy everything else and build 9 | COPY src/Exercism.Analyzers.CSharp . 10 | RUN dotnet publish -r linux-musl-x64 -c Release --self-contained true -o /opt/analyzer 11 | 12 | # Build runtime image 13 | FROM mcr.microsoft.com/dotnet/runtime-deps:9.0-alpine3.20-amd64 AS runtime 14 | WORKDIR /opt/analyzer 15 | 16 | COPY --from=build /opt/analyzer/ . 17 | COPY --from=build /usr/local/bin/ /usr/local/bin/ 18 | 19 | COPY bin/run.sh /opt/analyzer/bin/ 20 | 21 | ENTRYPOINT ["sh", "/opt/analyzer/bin/run.sh"] 22 | -------------------------------------------------------------------------------- /bin/update-golden-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # Synopsis: 4 | # Update the golden tests. 5 | 6 | # Example: 7 | # ./bin/update-golden-tests.sh 8 | 9 | # Generate the up-to-date analysis.json and tags.json files 10 | ./bin/run-tests-in-docker.sh 11 | 12 | # Overwrite the existing files 13 | find tests -name analysis.json -execdir cp analysis.json expected_analysis.json \; 14 | find tests -name tags.json -execdir cp tags.json expected_tags.json \; 15 | -------------------------------------------------------------------------------- /src/Exercism.Analyzers.CSharp/Analyzers/CollatzConjectureAnalyzer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CSharp.Syntax; 2 | 3 | namespace Exercism.Analyzers.CSharp.Analyzers; 4 | 5 | internal class CollatzConjectureAnalyzer : Analyzer 6 | { 7 | public CollatzConjectureAnalyzer(Submission submission) : base(submission) 8 | { 9 | } 10 | 11 | public override void VisitInvocationExpression(InvocationExpressionSyntax node) 12 | { 13 | if (GetConstructedFromSymbolName(node) == "System.Collections.Generic.IEnumerable.Count()") 14 | AddTags(Tags.UsesEnumerableCount); 15 | 16 | base.VisitInvocationExpression(node); 17 | } 18 | 19 | private static class Tags 20 | { 21 | public const string UsesEnumerableCount = "uses:Enumerable.Count"; 22 | } 23 | } -------------------------------------------------------------------------------- /src/Exercism.Analyzers.CSharp/Analyzers/ProteinTranslationAnalyzer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CSharp.Syntax; 2 | 3 | namespace Exercism.Analyzers.CSharp.Analyzers; 4 | 5 | internal class ProteinTranslationAnalyzer : Analyzer 6 | { 7 | public ProteinTranslationAnalyzer(Submission submission) : base(submission) 8 | { 9 | } 10 | 11 | public override void VisitInvocationExpression(InvocationExpressionSyntax node) 12 | { 13 | switch (GetSymbolName(node)) 14 | { 15 | case "string.Substring(int, int)": 16 | AddTags(Tags.UsesStringSubstring); 17 | break; 18 | } 19 | 20 | base.VisitInvocationExpression(node); 21 | } 22 | 23 | private static class Tags 24 | { 25 | public const string UsesStringSubstring = "uses:String.Substring"; 26 | } 27 | } -------------------------------------------------------------------------------- /src/Exercism.Analyzers.CSharp/Analyzers/ReverseStringAnalyzer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CSharp.Syntax; 2 | 3 | namespace Exercism.Analyzers.CSharp.Analyzers; 4 | 5 | internal class ReverseStringAnalyzer : Analyzer 6 | { 7 | public ReverseStringAnalyzer(Submission submission) : base(submission) 8 | { 9 | } 10 | 11 | public override void VisitInvocationExpression(InvocationExpressionSyntax node) 12 | { 13 | if (GetConstructedFromSymbolName(node) == "System.Array.Reverse(T[])") 14 | AddTags(Tags.UsesArrayReverse); 15 | 16 | base.VisitInvocationExpression(node); 17 | } 18 | 19 | private static class Tags 20 | { 21 | public const string UsesArrayReverse = "uses:Array.Reverse"; 22 | } 23 | } -------------------------------------------------------------------------------- /src/Exercism.Analyzers.CSharp/Comments.cs: -------------------------------------------------------------------------------- 1 | namespace Exercism.Analyzers.CSharp; 2 | 3 | internal enum CommentType 4 | { 5 | Essential, 6 | Actionable, 7 | Informative, 8 | Celebratory 9 | } 10 | 11 | internal record CommentParameter(string Key, string Value); 12 | 13 | internal record Comment(string Text, CommentType Type, params CommentParameter[] Parameters); 14 | -------------------------------------------------------------------------------- /src/Exercism.Analyzers.CSharp/Exercism.Analyzers.CSharp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | Exe 6 | true 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/bank-account/approaches/lock-statement/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "BankAccount.csproj" 8 | ], 9 | "solution": [ 10 | "BankAccount.cs" 11 | ], 12 | "test": [ 13 | "BankAccountTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/bank-account/approaches/lock-statement/BankAccount.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public class BankAccount 4 | { 5 | private readonly object _lock = new(); 6 | 7 | private decimal _balance; 8 | private bool _isOpen; 9 | 10 | public void Open() => _isOpen = true; 11 | 12 | public void Close() => _isOpen = false; 13 | 14 | public decimal Balance => _isOpen ? _balance : throw new InvalidOperationException("Account is closed"); 15 | 16 | public void UpdateBalance(decimal change) 17 | { 18 | if (!_isOpen) 19 | throw new InvalidOperationException("Account is closed"); 20 | 21 | lock (_lock) 22 | _balance += change; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/bank-account/approaches/lock-statement/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/bank-account/approaches/mutex/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "BankAccount.csproj" 8 | ], 9 | "solution": [ 10 | "BankAccount.cs" 11 | ], 12 | "test": [ 13 | "BankAccountTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/bank-account/approaches/mutex/BankAccount.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | public class BankAccount 5 | { 6 | private readonly Mutex _mutex = new(); 7 | 8 | private decimal _balance; 9 | private bool _isOpen; 10 | 11 | public void Open() => _isOpen = true; 12 | 13 | public void Close() => _isOpen = false; 14 | 15 | public decimal Balance => _isOpen ? _balance : throw new InvalidOperationException(); 16 | 17 | public void UpdateBalance(decimal change) 18 | { 19 | if (!_isOpen) 20 | throw new InvalidOperationException("Account is closed"); 21 | 22 | _mutex.WaitOne(); 23 | 24 | try 25 | { 26 | _balance += change; 27 | } 28 | finally 29 | { 30 | _mutex.ReleaseMutex(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/bank-account/approaches/mutex/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/bob/approaches/answer-array/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Bob.csproj" 8 | ], 9 | "solution": [ 10 | "Bob.cs" 11 | ], 12 | "test": [ 13 | "BobTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/bob/approaches/answer-array/Bob.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | public static class Bob 4 | { 5 | private static readonly string[] answers = {"Whatever.", "Sure.", "Whoa, chill out!", "Calm down, I know what I'm doing!"}; 6 | 7 | public static string Response(string statement) 8 | { 9 | var input = statement.TrimEnd(); 10 | if (input == "") 11 | return "Fine. Be that way!"; 12 | 13 | var isShout = input.Any(c => char.IsLetter(c)) && input.ToUpper() == input ? 2: 0; 14 | 15 | var isQuestion = input.EndsWith('?') ? 1: 0; 16 | 17 | return answers[isShout + isQuestion]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/bob/approaches/answer-array/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/bob/approaches/if/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Bob.csproj" 8 | ], 9 | "solution": [ 10 | "Bob.cs" 11 | ], 12 | "test": [ 13 | "BobTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/bob/approaches/if/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "IsSilence" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/bob/approaches/if/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:boolean", 4 | "construct:char", 5 | "construct:class", 6 | "construct:equality", 7 | "construct:if", 8 | "construct:implicit-conversion", 9 | "construct:invocation", 10 | "construct:lambda", 11 | "construct:linq", 12 | "construct:logical-and", 13 | "construct:method", 14 | "construct:parameter", 15 | "construct:return", 16 | "construct:string", 17 | "construct:using-directive", 18 | "construct:visibility-modifiers", 19 | "paradigm:functional", 20 | "paradigm:object-oriented", 21 | "technique:boolean-logic", 22 | "technique:higher-order-functions", 23 | "technique:short-circuiting" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/bob/approaches/regular-expressions/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Bob.csproj" 8 | ], 9 | "solution": [ 10 | "Bob.cs" 11 | ], 12 | "test": [ 13 | "BobTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/bob/approaches/regular-expressions/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "IsSilence" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/bob/approaches/regular-expressions/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:boolean", 4 | "construct:class", 5 | "construct:if", 6 | "construct:invocation", 7 | "construct:logical-and", 8 | "construct:method", 9 | "construct:parameter", 10 | "construct:return", 11 | "construct:string", 12 | "construct:using-directive", 13 | "construct:verbatim-string", 14 | "construct:visibility-modifiers", 15 | "paradigm:object-oriented", 16 | "technique:boolean-logic", 17 | "technique:regular-expression", 18 | "technique:short-circuiting", 19 | "uses:Regex" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/bob/approaches/switch-on-tuple/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Bob.csproj" 8 | ], 9 | "solution": [ 10 | "Bob.cs" 11 | ], 12 | "test": [ 13 | "BobTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/bob/approaches/switch-on-tuple/Bob.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | public static class Bob 4 | { 5 | private static bool IsShout(string input) => input.Any(c => char.IsLetter(c)) && input.ToUpper() == input; 6 | 7 | public static string Response(string statement) 8 | { 9 | var input = statement.TrimEnd(); 10 | if (input == "") 11 | return "Fine. Be that way!"; 12 | 13 | switch ((input.EndsWith('?'), IsShout(input))) 14 | { 15 | case (true, true): return "Calm down, I know what I'm doing!"; 16 | case (_, true): return "Whoa, chill out!"; 17 | case (true, _): return "Sure."; 18 | default: return "Whatever."; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/bob/approaches/switch-on-tuple/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/collatz-conjecture/approaches/recursion/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "CollatzConjecture.csproj" 8 | ], 9 | "solution": [ 10 | "CollatzConjecture.cs" 11 | ], 12 | "test": [ 13 | "CollatzConjectureTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/collatz-conjecture/approaches/recursion/CollatzConjecture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class CollatzConjecture 4 | { 5 | public static int Steps(int number) 6 | { 7 | if (number <= 0) 8 | throw new ArgumentOutOfRangeException(nameof(number)); 9 | 10 | return Steps(number, 0); 11 | } 12 | 13 | private static int Steps(int number, int stepCount) 14 | { 15 | if (number == 1) 16 | return stepCount; 17 | 18 | if (number % 2 == 0) 19 | return Steps(number / 2, stepCount + 1); 20 | 21 | return Steps(number * 3 + 1, stepCount + 1); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/collatz-conjecture/approaches/recursion/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/collatz-conjecture/approaches/sequence/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "CollatzConjecture.csproj" 8 | ], 9 | "solution": [ 10 | "CollatzConjecture.cs" 11 | ], 12 | "test": [ 13 | "CollatzConjectureTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/collatz-conjecture/approaches/sequence/CollatzConjecture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | public static class CollatzConjecture 6 | { 7 | public static int Steps(int number) 8 | { 9 | if (number <= 0) 10 | throw new ArgumentOutOfRangeException(nameof(number)); 11 | 12 | return Sequence(number).Count(); 13 | } 14 | 15 | private static IEnumerable Sequence(int number) 16 | { 17 | var currentNumber = number; 18 | 19 | while (currentNumber != 1) 20 | { 21 | if (currentNumber % 2 == 0) 22 | currentNumber = currentNumber / 2; 23 | else 24 | currentNumber = currentNumber * 3 + 1; 25 | 26 | yield return currentNumber; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/collatz-conjecture/approaches/sequence/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/collatz-conjecture/approaches/while-loop/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "CollatzConjecture.csproj" 8 | ], 9 | "solution": [ 10 | "CollatzConjecture.cs" 11 | ], 12 | "test": [ 13 | "CollatzConjectureTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/collatz-conjecture/approaches/while-loop/CollatzConjecture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class CollatzConjecture 4 | { 5 | public static int Steps(int number) 6 | { 7 | if (number <= 0) 8 | throw new ArgumentOutOfRangeException(nameof(number)); 9 | 10 | var currentNumber = number; 11 | var stepCount = 0; 12 | 13 | while (currentNumber != 1) 14 | { 15 | if (currentNumber % 2 == 0) 16 | currentNumber = currentNumber / 2; 17 | else 18 | currentNumber = currentNumber * 3 + 1; 19 | 20 | stepCount++; 21 | } 22 | 23 | return stepCount; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/collatz-conjecture/approaches/while-loop/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/common/assign-and-return/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Common.csproj" 8 | ], 9 | "solution": [ 10 | "Common.cs" 11 | ], 12 | "test": [ 13 | "CommonTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/common/assign-and-return/Common.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | public static class AssignAndReturn 4 | { 5 | public static int AssignInMethod(int year) 6 | { 7 | var x = 1; 8 | return x; 9 | } 10 | 11 | public static int AssignInBlock(int year) 12 | { 13 | if (true) 14 | { 15 | var x = 1; 16 | return x; 17 | } 18 | 19 | return 2; 20 | } 21 | 22 | public static int AssignInLambda(int year) 23 | { 24 | return Enumerable.Range(1, 10).Select((i) => 25 | { 26 | var x = i; 27 | return x; 28 | }).Max(); 29 | } 30 | } -------------------------------------------------------------------------------- /tests/common/assign-and-return/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.do_not_assign_and_return", 5 | "type": "actionable", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.general.use_expression_bodied_member", 10 | "type": "informative", 11 | "params": { 12 | "name": "AssignInLambda" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/common/assign-and-return/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:boolean", 4 | "construct:class", 5 | "construct:if", 6 | "construct:int", 7 | "construct:integral-number", 8 | "construct:invocation", 9 | "construct:lambda", 10 | "construct:linq", 11 | "construct:method", 12 | "construct:number", 13 | "construct:parameter", 14 | "construct:return", 15 | "construct:using-directive", 16 | "construct:variable", 17 | "construct:visibility-modifiers", 18 | "paradigm:functional", 19 | "paradigm:object-oriented", 20 | "technique:higher-order-functions" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/common/has-compile-errors/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Errors.csproj" 8 | ], 9 | "solution": [ 10 | "Errors.cs" 11 | ], 12 | "test": [ 13 | "ErrorsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/common/has-compile-errors/Errors.cs: -------------------------------------------------------------------------------- 1 | public static class Errors 2 | { 3 | public static DateTime Add 4 | } -------------------------------------------------------------------------------- /tests/common/has-compile-errors/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/common/has-compile-errors/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/common/has-main-method/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Common.csproj" 8 | ], 9 | "solution": [ 10 | "Common.cs" 11 | ], 12 | "test": [ 13 | "CommonTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/common/has-main-method/Common.cs: -------------------------------------------------------------------------------- 1 | static class Program 2 | { 3 | static void Main(string[] args) 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /tests/common/has-main-method/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.has_main_method", 5 | "type": "essential", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/common/has-main-method/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:method", 5 | "construct:parameter", 6 | "paradigm:object-oriented" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /tests/common/ignore-non-solution-files/.meta/Example.cs: -------------------------------------------------------------------------------- 1 | public class Example 2 | { 3 | public void Test() 4 | { 5 | // The ulong type is only used in this file. As we should be ignoring 6 | // any example file, we should _not_ see the tag for the ulong type 7 | // in the resulting analysis.json 8 | ulong x; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/common/ignore-non-solution-files/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Common.csproj", "Invalidator.cs" 8 | ], 9 | "editor": [ 10 | "Editor.cs" 11 | ], 12 | "solution": [ 13 | "Solution.cs" 14 | ], 15 | "test": [ 16 | "Tests.cs" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/common/ignore-non-solution-files/Additional.cs: -------------------------------------------------------------------------------- 1 | public class Additional 2 | { 3 | public void Test() 4 | { 5 | // The short type is only used in this file. As we should be including 6 | // any solution file, we _should_ see the tag for the short type 7 | // in the resulting analysis.json 8 | short x; 9 | } 10 | } -------------------------------------------------------------------------------- /tests/common/ignore-non-solution-files/Editor.cs: -------------------------------------------------------------------------------- 1 | public class Editor 2 | { 3 | public void Test() 4 | { 5 | // The uint type is only used in this file. As we should be ignoring 6 | // any editor file, we should _not_ see the tag for the uint type 7 | // in the resulting analysis.json 8 | uint x; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/common/ignore-non-solution-files/Invalidator.cs: -------------------------------------------------------------------------------- 1 | public class Invalidator 2 | { 3 | public void Test() 4 | { 5 | // The ushort type is only used in this file. As we should be ignoring 6 | // any invalidator file, we should _not_ see the tag for the ushort type 7 | // in the resulting analysis.json 8 | ushort x; 9 | } 10 | } -------------------------------------------------------------------------------- /tests/common/ignore-non-solution-files/Solution.cs: -------------------------------------------------------------------------------- 1 | public class Solution 2 | { 3 | public void Test() 4 | { 5 | // The sbyte type is only used in this file. As we should be including 6 | // any solution file, we _should_ see the tag for the sbyte type 7 | // in the resulting analysis.json 8 | sbyte x; 9 | } 10 | } -------------------------------------------------------------------------------- /tests/common/ignore-non-solution-files/Solution.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/common/ignore-non-solution-files/Tests.cs: -------------------------------------------------------------------------------- 1 | public class Tests 2 | { 3 | public void Test() 4 | { 5 | // The long type is only used in this file. As we should be ignoring 6 | // any test file, we should _not_ see the tag for the long type 7 | // in the resulting analysis.json 8 | long x; 9 | } 10 | } -------------------------------------------------------------------------------- /tests/common/ignore-non-solution-files/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/common/ignore-non-solution-files/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:comment", 5 | "construct:integral-number", 6 | "construct:method", 7 | "construct:sbyte", 8 | "construct:short", 9 | "construct:variable", 10 | "construct:visibility-modifiers", 11 | "paradigm:object-oriented" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/common/missing-solution-file/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "MissingFile.csproj" 8 | ], 9 | "solution": [ 10 | "MissingFile.cs" 11 | ], 12 | "test": [ 13 | "MissingFileTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/common/missing-solution-file/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/common/missing-solution-file/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-error-write-line/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Errors.csproj" 8 | ], 9 | "solution": [ 10 | "Errors.cs" 11 | ], 12 | "test": [ 13 | "ErrorsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-error-write-line/Errors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Errors 4 | { 5 | public static void Test() 6 | { 7 | Console.Error.WriteLine("Test"); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-error-write-line/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.do_not_write_to_console", 5 | "type": "actionable", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-error-write-line/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:invocation", 5 | "construct:method", 6 | "construct:string", 7 | "construct:using-directive", 8 | "construct:visibility-modifiers", 9 | "paradigm:object-oriented" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-error-write/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Errors.csproj" 8 | ], 9 | "solution": [ 10 | "Errors.cs" 11 | ], 12 | "test": [ 13 | "ErrorsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-error-write/Errors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Errors 4 | { 5 | public static void Test() 6 | { 7 | Console.Error.Write("Test"); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-error-write/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.do_not_write_to_console", 5 | "type": "actionable", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-error-write/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:invocation", 5 | "construct:method", 6 | "construct:string", 7 | "construct:using-directive", 8 | "construct:visibility-modifiers", 9 | "paradigm:object-oriented" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-out-write-line/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Errors.csproj" 8 | ], 9 | "solution": [ 10 | "Errors.cs" 11 | ], 12 | "test": [ 13 | "ErrorsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-out-write-line/Errors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Errors 4 | { 5 | public static void Test() 6 | { 7 | Console.Out.WriteLine("Test"); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-out-write-line/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.do_not_write_to_console", 5 | "type": "actionable", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-out-write-line/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:invocation", 5 | "construct:method", 6 | "construct:string", 7 | "construct:using-directive", 8 | "construct:visibility-modifiers", 9 | "paradigm:object-oriented" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-out-write/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Errors.csproj" 8 | ], 9 | "solution": [ 10 | "Errors.cs" 11 | ], 12 | "test": [ 13 | "ErrorsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-out-write/Errors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Errors 4 | { 5 | public static void Test() 6 | { 7 | Console.Out.Write("Test"); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-out-write/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.do_not_write_to_console", 5 | "type": "actionable", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-out-write/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:invocation", 5 | "construct:method", 6 | "construct:string", 7 | "construct:using-directive", 8 | "construct:visibility-modifiers", 9 | "paradigm:object-oriented" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-write-line/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Errors.csproj" 8 | ], 9 | "solution": [ 10 | "Errors.cs" 11 | ], 12 | "test": [ 13 | "ErrorsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-write-line/Errors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Errors 4 | { 5 | public static void Test() 6 | { 7 | Console.WriteLine("Test"); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-write-line/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.do_not_write_to_console", 5 | "type": "actionable", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-write-line/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:invocation", 5 | "construct:method", 6 | "construct:string", 7 | "construct:using-directive", 8 | "construct:visibility-modifiers", 9 | "paradigm:object-oriented" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-write/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Errors.csproj" 8 | ], 9 | "solution": [ 10 | "Errors.cs" 11 | ], 12 | "test": [ 13 | "ErrorsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-write/Errors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Errors 4 | { 5 | public static void Test() 6 | { 7 | Console.Write("Test"); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-write/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.do_not_write_to_console", 5 | "type": "actionable", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/common/writes-to-console/console-write/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:invocation", 5 | "construct:method", 6 | "construct:string", 7 | "construct:using-directive", 8 | "construct:visibility-modifiers", 9 | "paradigm:object-oriented" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/darts/approaches/if-statements/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Darts.csproj" 8 | ], 9 | "solution": [ 10 | "Darts.cs" 11 | ], 12 | "test": [ 13 | "DartsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/darts/approaches/if-statements/Darts.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Darts 4 | { 5 | public static int Score(double x, double y) 6 | { 7 | var distanceFromCenter = Math.Sqrt(x * x + y * y); 8 | 9 | if (distanceFromCenter > 10.0) 10 | return 0; 11 | 12 | if (distanceFromCenter > 5.0) 13 | return 1; 14 | 15 | if (distanceFromCenter > 1.0) 16 | return 5; 17 | 18 | return 10; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/darts/approaches/if-statements/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/darts/approaches/if-statements/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:add", 4 | "construct:class", 5 | "construct:double", 6 | "construct:floating-point-number", 7 | "construct:if", 8 | "construct:int", 9 | "construct:integral-number", 10 | "construct:invocation", 11 | "construct:lambda", 12 | "construct:method", 13 | "construct:multiply", 14 | "construct:number", 15 | "construct:parameter", 16 | "construct:return", 17 | "construct:using-directive", 18 | "construct:variable", 19 | "construct:visibility-modifiers", 20 | "paradigm:functional", 21 | "paradigm:object-oriented", 22 | "technique:higher-order-functions" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/darts/approaches/switch-expression/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Darts.csproj" 8 | ], 9 | "solution": [ 10 | "Darts.cs" 11 | ], 12 | "test": [ 13 | "DartsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/darts/approaches/switch-expression/Darts.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Darts 4 | { 5 | public static int Score(double x, double y) 6 | { 7 | return Math.Sqrt(x * x + y * y) switch 8 | { 9 | > 10.0 => 0, 10 | > 5.0 => 1, 11 | > 1.0 => 5, 12 | _ => 10 13 | }; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/darts/approaches/switch-expression/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Score" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/darts/approaches/switch-expression/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:add", 4 | "construct:class", 5 | "construct:double", 6 | "construct:floating-point-number", 7 | "construct:int", 8 | "construct:integral-number", 9 | "construct:invocation", 10 | "construct:lambda", 11 | "construct:method", 12 | "construct:multiply", 13 | "construct:number", 14 | "construct:parameter", 15 | "construct:pattern-matching", 16 | "construct:return", 17 | "construct:switch-expression", 18 | "construct:using-directive", 19 | "construct:visibility-modifiers", 20 | "paradigm:functional", 21 | "paradigm:object-oriented", 22 | "technique:higher-order-functions" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/for-statement/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "DifferenceOfSquares.csproj" 8 | ], 9 | "solution": [ 10 | "DifferenceOfSquares.cs" 11 | ], 12 | "test": [ 13 | "DifferenceOfSquaresTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/for-statement/DifferenceOfSquares.cs: -------------------------------------------------------------------------------- 1 | public static class DifferenceOfSquares 2 | { 3 | public static int CalculateSquareOfSum(int max) 4 | { 5 | var sum = 0; 6 | 7 | for (var i = 1; i <= max; i++) 8 | sum += i; 9 | 10 | return sum * sum; 11 | } 12 | 13 | public static int CalculateSumOfSquares(int max) 14 | { 15 | var sumOfSquares = 0; 16 | 17 | for (var i = 1; i <= max; i++) 18 | sumOfSquares += i * i; 19 | 20 | return sumOfSquares; 21 | } 22 | 23 | public static int CalculateDifferenceOfSquares(int max) => 24 | CalculateSquareOfSum(max) - CalculateSumOfSquares(max); 25 | } 26 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/for-statement/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/for-statement/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:add", 4 | "construct:add-assignment", 5 | "construct:assignment", 6 | "construct:class", 7 | "construct:expression-bodied-member", 8 | "construct:for-loop", 9 | "construct:int", 10 | "construct:integral-number", 11 | "construct:invocation", 12 | "construct:method", 13 | "construct:multiply", 14 | "construct:number", 15 | "construct:parameter", 16 | "construct:postfix-increment", 17 | "construct:return", 18 | "construct:subtract", 19 | "construct:variable", 20 | "construct:visibility-modifiers", 21 | "paradigm:imperative", 22 | "paradigm:object-oriented", 23 | "technique:compound-assignment", 24 | "technique:looping", 25 | "technique:math" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/linq/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "DifferenceOfSquares.csproj" 8 | ], 9 | "solution": [ 10 | "DifferenceOfSquares.cs" 11 | ], 12 | "test": [ 13 | "DifferenceOfSquaresTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/linq/DifferenceOfSquares.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | public static class DifferenceOfSquares 4 | { 5 | public static int CalculateSquareOfSum(int max) => 6 | Square(Enumerable.Range(1, max).Sum()); 7 | 8 | public static int CalculateSumOfSquares(int max) => 9 | Enumerable.Range(1, max).Sum(Square); 10 | 11 | public static int CalculateDifferenceOfSquares(int max) => 12 | CalculateSquareOfSum(max) - CalculateSumOfSquares(max); 13 | 14 | private static int Square(int number) => number * number; 15 | } 16 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/linq/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/linq/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:expression-bodied-member", 5 | "construct:int", 6 | "construct:integral-number", 7 | "construct:invocation", 8 | "construct:lambda", 9 | "construct:linq", 10 | "construct:method", 11 | "construct:multiply", 12 | "construct:number", 13 | "construct:parameter", 14 | "construct:subtract", 15 | "construct:using-directive", 16 | "construct:visibility-modifiers", 17 | "paradigm:functional", 18 | "paradigm:object-oriented", 19 | "technique:higher-order-functions", 20 | "technique:math" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/math/equations-only/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Math.csproj" 8 | ], 9 | "solution": [ 10 | "Math.cs" 11 | ], 12 | "test": [ 13 | "MathTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/math/equations-only/Math.cs: -------------------------------------------------------------------------------- 1 | public static class DifferenceOfSquares 2 | { 3 | public static int CalculateSquareOfSum(int max) 4 | { 5 | var sum = max * (max + 1) / 2; 6 | return sum * sum; 7 | } 8 | 9 | public static int CalculateSumOfSquares(int max) => 10 | (max * (max + 1) * ((max * 2) + 1)) / 6; 11 | 12 | public static int CalculateDifferenceOfSquares(int max) => 13 | CalculateSquareOfSum(max) - CalculateSumOfSquares(max); 14 | } 15 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/math/equations-only/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/math/equations-only/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:add", 4 | "construct:class", 5 | "construct:divide", 6 | "construct:expression-bodied-member", 7 | "construct:int", 8 | "construct:integral-number", 9 | "construct:invocation", 10 | "construct:method", 11 | "construct:multiply", 12 | "construct:number", 13 | "construct:parameter", 14 | "construct:return", 15 | "construct:subtract", 16 | "construct:variable", 17 | "construct:visibility-modifiers", 18 | "paradigm:object-oriented", 19 | "technique:math" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/math/using-math-class/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Math.csproj" 8 | ], 9 | "solution": [ 10 | "Math.cs" 11 | ], 12 | "test": [ 13 | "MathTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/math/using-math-class/Math.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class DifferenceOfSquares 4 | { 5 | public static int CalculateSquareOfSum(int max) 6 | => (int)Math.Pow((max * (max + 1)) / 2, 2); 7 | 8 | public static int CalculateSumOfSquares(int max) 9 | => (max * (max + 1) * (2 * max + 1)) / 6; 10 | 11 | public static int CalculateDifferenceOfSquares(int max) 12 | => Math.Abs(CalculateSumOfSquares(max) - CalculateSquareOfSum(max)); 13 | } -------------------------------------------------------------------------------- /tests/difference-of-squares/approaches/math/using-math-class/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/diffie-hellman/approaches/big-integer/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "DiffieHellman.csproj" 8 | ], 9 | "solution": [ 10 | "DiffieHellman.cs" 11 | ], 12 | "test": [ 13 | "DiffieHellmanTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/diffie-hellman/approaches/big-integer/DiffieHellman.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | 4 | public static class DiffieHellman 5 | { 6 | public static BigInteger PrivateKey(BigInteger p) => 7 | new(Random.Shared.NextInt64(1, (long)p)); 8 | 9 | public static BigInteger PublicKey(BigInteger p, BigInteger g, BigInteger privateKey) => 10 | BigInteger.ModPow(g, privateKey, p); 11 | 12 | public static BigInteger Secret(BigInteger p, BigInteger publicKey, BigInteger privateKey) => 13 | BigInteger.ModPow(publicKey, privateKey, p); 14 | } 15 | -------------------------------------------------------------------------------- /tests/diffie-hellman/approaches/big-integer/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/diffie-hellman/approaches/big-integer/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:big-integer", 4 | "construct:class", 5 | "construct:explicit-conversion", 6 | "construct:expression-bodied-member", 7 | "construct:implicit-conversion", 8 | "construct:implicit-object-creation", 9 | "construct:integral-number", 10 | "construct:invocation", 11 | "construct:lambda", 12 | "construct:long", 13 | "construct:method", 14 | "construct:number", 15 | "construct:parameter", 16 | "construct:using-directive", 17 | "construct:visibility-modifiers", 18 | "paradigm:functional", 19 | "paradigm:object-oriented", 20 | "technique:higher-order-functions", 21 | "technique:randomness", 22 | "technique:type-conversion", 23 | "uses:Random" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/digits-with-separator/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Gigasecond.csproj" 8 | ], 9 | "solution": [ 10 | "Gigasecond.cs" 11 | ], 12 | "test": [ 13 | "GigasecondTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/digits-with-separator/Gigasecond.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Gigasecond 4 | { 5 | public static DateTime Add(DateTime birthDate) 6 | { 7 | return birthDate.AddSeconds(1_000_000_000); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/digits-with-separator/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Add" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/digits-with-separator/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:date-time", 5 | "construct:double", 6 | "construct:floating-point-number", 7 | "construct:implicit-conversion", 8 | "construct:invocation", 9 | "construct:method", 10 | "construct:number", 11 | "construct:parameter", 12 | "construct:return", 13 | "construct:underscored-number", 14 | "construct:using-directive", 15 | "construct:visibility-modifiers", 16 | "paradigm:object-oriented", 17 | "uses:DateTime", 18 | "uses:DateTime.AddSeconds" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/digits-without-separator/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Gigasecond.csproj" 8 | ], 9 | "solution": [ 10 | "Gigasecond.cs" 11 | ], 12 | "test": [ 13 | "GigasecondTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/digits-without-separator/Gigasecond.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Gigasecond 4 | { 5 | public static DateTime Add(DateTime birthDate) 6 | { 7 | return birthDate.AddSeconds(1000000000); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/digits-without-separator/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.gigasecond.use_1e9_or_digit_separator", 5 | "type": "informative", 6 | "params": { 7 | "value": "1000000000" 8 | } 9 | }, 10 | { 11 | "comment": "csharp.general.use_expression_bodied_member", 12 | "type": "informative", 13 | "params": { 14 | "name": "Add" 15 | } 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/digits-without-separator/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:date-time", 5 | "construct:double", 6 | "construct:floating-point-number", 7 | "construct:implicit-conversion", 8 | "construct:invocation", 9 | "construct:method", 10 | "construct:number", 11 | "construct:parameter", 12 | "construct:return", 13 | "construct:using-directive", 14 | "construct:visibility-modifiers", 15 | "paradigm:object-oriented", 16 | "uses:DateTime", 17 | "uses:DateTime.AddSeconds" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/math-pow/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Gigasecond.csproj" 8 | ], 9 | "solution": [ 10 | "Gigasecond.cs" 11 | ], 12 | "test": [ 13 | "GigasecondTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/math-pow/Gigasecond.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Gigasecond 4 | { 5 | public static DateTime Add(DateTime birthDate) 6 | { 7 | return birthDate.AddSeconds(Math.Pow(10, 9)); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/math-pow/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.gigasecond.use_1e9_not_math_pow", 5 | "type": "informative", 6 | "params": { 7 | "value": "Math.Pow(10, 9)" 8 | } 9 | }, 10 | { 11 | "comment": "csharp.general.use_expression_bodied_member", 12 | "type": "informative", 13 | "params": { 14 | "name": "Add" 15 | } 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/math-pow/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:date-time", 5 | "construct:double", 6 | "construct:floating-point-number", 7 | "construct:implicit-conversion", 8 | "construct:invocation", 9 | "construct:lambda", 10 | "construct:method", 11 | "construct:number", 12 | "construct:parameter", 13 | "construct:return", 14 | "construct:using-directive", 15 | "construct:visibility-modifiers", 16 | "paradigm:functional", 17 | "paradigm:object-oriented", 18 | "technique:higher-order-functions", 19 | "uses:DateTime", 20 | "uses:DateTime.AddSeconds", 21 | "uses:Math.Pow" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/scientific-notation/lower-case/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Gigasecond.csproj" 8 | ], 9 | "solution": [ 10 | "Gigasecond.cs" 11 | ], 12 | "test": [ 13 | "GigasecondTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/scientific-notation/lower-case/Gigasecond.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Gigasecond 4 | { 5 | public static DateTime Add(DateTime birthDate) 6 | { 7 | return birthDate.AddSeconds(1e9); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/scientific-notation/lower-case/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Add" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/scientific-notation/lower-case/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:date-time", 5 | "construct:double", 6 | "construct:floating-point-number", 7 | "construct:invocation", 8 | "construct:method", 9 | "construct:number", 10 | "construct:parameter", 11 | "construct:return", 12 | "construct:using-directive", 13 | "construct:visibility-modifiers", 14 | "paradigm:object-oriented", 15 | "uses:DateTime", 16 | "uses:DateTime.AddSeconds" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/scientific-notation/upper-case/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Gigasecond.csproj" 8 | ], 9 | "solution": [ 10 | "Gigasecond.cs" 11 | ], 12 | "test": [ 13 | "GigasecondTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/scientific-notation/upper-case/Gigasecond.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Gigasecond 4 | { 5 | public static DateTime Add(DateTime birthDate) 6 | { 7 | return birthDate.AddSeconds(1E9); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/scientific-notation/upper-case/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Add" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/gigasecond/add-seconds/scientific-notation/upper-case/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:date-time", 5 | "construct:double", 6 | "construct:floating-point-number", 7 | "construct:invocation", 8 | "construct:method", 9 | "construct:number", 10 | "construct:parameter", 11 | "construct:return", 12 | "construct:using-directive", 13 | "construct:visibility-modifiers", 14 | "paradigm:object-oriented", 15 | "uses:DateTime", 16 | "uses:DateTime.AddSeconds" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/gigasecond/add/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Gigasecond.csproj" 8 | ], 9 | "solution": [ 10 | "Gigasecond.cs" 11 | ], 12 | "test": [ 13 | "GigasecondTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/add/Gigasecond.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Gigasecond 4 | { 5 | public static DateTime Add(DateTime birthDate) 6 | { 7 | return birthDate.Add(TimeSpan.FromSeconds(1000000000)); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/gigasecond/add/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.gigasecond.use_add_seconds", 5 | "type": "actionable", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.general.use_expression_bodied_member", 10 | "type": "informative", 11 | "params": { 12 | "name": "Add" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/add/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:date-time", 5 | "construct:implicit-conversion", 6 | "construct:integral-number", 7 | "construct:invocation", 8 | "construct:lambda", 9 | "construct:long", 10 | "construct:method", 11 | "construct:number", 12 | "construct:parameter", 13 | "construct:return", 14 | "construct:using-directive", 15 | "construct:visibility-modifiers", 16 | "paradigm:functional", 17 | "paradigm:object-oriented", 18 | "technique:higher-order-functions", 19 | "uses:DateTime" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/gigasecond/approaches/add-seconds/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Gigasecond.csproj" 8 | ], 9 | "solution": [ 10 | "Gigasecond.cs" 11 | ], 12 | "test": [ 13 | "GigasecondTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/approaches/add-seconds/Gigasecond.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Gigasecond 4 | { 5 | public static DateTime Add(DateTime birthDate) 6 | { 7 | return birthDate.AddSeconds(1_000_000_000); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/gigasecond/approaches/add-seconds/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Add" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/gigasecond/approaches/add-seconds/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:date-time", 5 | "construct:double", 6 | "construct:floating-point-number", 7 | "construct:implicit-conversion", 8 | "construct:invocation", 9 | "construct:method", 10 | "construct:number", 11 | "construct:parameter", 12 | "construct:return", 13 | "construct:underscored-number", 14 | "construct:using-directive", 15 | "construct:visibility-modifiers", 16 | "paradigm:object-oriented", 17 | "uses:DateTime", 18 | "uses:DateTime.AddSeconds" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /tests/gigasecond/approaches/time-span/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Gigasecond.csproj" 8 | ], 9 | "solution": [ 10 | "Gigasecond.cs" 11 | ], 12 | "test": [ 13 | "GigasecondTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/approaches/time-span/Gigasecond.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Gigasecond 4 | { 5 | public static DateTime Add(DateTime birthDate) 6 | { 7 | return birthDate + TimeSpan.FromSeconds(1_000_000_000); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/gigasecond/approaches/time-span/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.gigasecond.use_add_seconds", 5 | "type": "actionable", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.general.use_expression_bodied_member", 10 | "type": "informative", 11 | "params": { 12 | "name": "Add" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/approaches/time-span/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:add", 4 | "construct:class", 5 | "construct:implicit-conversion", 6 | "construct:integral-number", 7 | "construct:invocation", 8 | "construct:long", 9 | "construct:method", 10 | "construct:number", 11 | "construct:parameter", 12 | "construct:return", 13 | "construct:underscored-number", 14 | "construct:using-directive", 15 | "construct:visibility-modifiers", 16 | "paradigm:object-oriented", 17 | "uses:DateTime.Plus(TimeSpan)" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tests/gigasecond/create-date-time/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Gigasecond.csproj" 8 | ], 9 | "solution": [ 10 | "Gigasecond.cs" 11 | ], 12 | "test": [ 13 | "GigasecondTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/create-date-time/Gigasecond.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Gigasecond 4 | { 5 | public static DateTime Add(DateTime moment) 6 | { 7 | return new DateTime(moment.Ticks).AddSeconds(1000000000); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/gigasecond/create-date-time/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.gigasecond.do_not_create_datetime", 5 | "type": "essential", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.gigasecond.use_1e9_or_digit_separator", 10 | "type": "informative", 11 | "params": { 12 | "value": "1000000000" 13 | } 14 | }, 15 | { 16 | "comment": "csharp.general.use_expression_bodied_member", 17 | "type": "informative", 18 | "params": { 19 | "name": "Add" 20 | } 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /tests/gigasecond/create-date-time/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:constructor", 5 | "construct:date-time", 6 | "construct:double", 7 | "construct:floating-point-number", 8 | "construct:implicit-conversion", 9 | "construct:invocation", 10 | "construct:method", 11 | "construct:number", 12 | "construct:parameter", 13 | "construct:return", 14 | "construct:using-directive", 15 | "construct:visibility-modifiers", 16 | "paradigm:object-oriented", 17 | "uses:DateTime", 18 | "uses:DateTime.AddSeconds", 19 | "uses:DateTime.DateTime(long)" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/gigasecond/plus-operator/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Gigasecond.csproj" 8 | ], 9 | "solution": [ 10 | "Gigasecond.cs" 11 | ], 12 | "test": [ 13 | "GigasecondTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/plus-operator/Gigasecond.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Gigasecond 4 | { 5 | public static DateTime Add(DateTime birthDate) 6 | { 7 | return birthDate + TimeSpan.FromSeconds(1000000000); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/gigasecond/plus-operator/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.gigasecond.use_add_seconds", 5 | "type": "actionable", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.general.use_expression_bodied_member", 10 | "type": "informative", 11 | "params": { 12 | "name": "Add" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/gigasecond/plus-operator/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:add", 4 | "construct:class", 5 | "construct:implicit-conversion", 6 | "construct:integral-number", 7 | "construct:invocation", 8 | "construct:long", 9 | "construct:method", 10 | "construct:number", 11 | "construct:parameter", 12 | "construct:return", 13 | "construct:using-directive", 14 | "construct:visibility-modifiers", 15 | "paradigm:object-oriented", 16 | "uses:DateTime.Plus(TimeSpan)" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/grade-school/approaches/sorted-collections/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "GradeSchool.csproj" 8 | ], 9 | "solution": [ 10 | "GradeSchool.cs" 11 | ], 12 | "test": [ 13 | "GradeSchoolTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/grade-school/approaches/sorted-collections/GradeSchool.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | public class GradeSchool 5 | { 6 | private readonly SortedDictionary> _roster = new(); 7 | 8 | public bool Add(string student, int grade) 9 | { 10 | if (_roster.Values.Any(students => students.Contains(student))) 11 | return false; 12 | 13 | if (!_roster.TryAdd(grade, new SortedSet { student })) 14 | _roster[grade].Add(student); 15 | 16 | return true; 17 | } 18 | 19 | public IEnumerable Roster() => _roster.Values.SelectMany(students => students); 20 | 21 | public IEnumerable Grade(int grade) => 22 | _roster.TryGetValue(grade, out var students) ? students : Enumerable.Empty(); 23 | } 24 | -------------------------------------------------------------------------------- /tests/grade-school/approaches/sorted-collections/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/grains/approaches/bit-shifting/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Grains.csproj" 8 | ], 9 | "solution": [ 10 | "Grains.cs" 11 | ], 12 | "test": [ 13 | "GrainsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/grains/approaches/bit-shifting/Grains.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | 4 | public static class Grains 5 | { 6 | public static ulong Square(int n) 7 | { 8 | switch (n) 9 | { 10 | case int num when num > 0 && num < 65: return (ulong)1 << (num - 1); 11 | default: throw new ArgumentOutOfRangeException("n must be 1 through 64"); 12 | } 13 | } 14 | 15 | public static ulong Total() 16 | { 17 | return (ulong)((BigInteger.One << 64) - 1); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/grains/approaches/bit-shifting/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Total" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/grains/approaches/max-value/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Grains.csproj" 8 | ], 9 | "solution": [ 10 | "Grains.cs" 11 | ], 12 | "test": [ 13 | "GrainsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/grains/approaches/max-value/Grains.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Grains 4 | { 5 | public static double Square(int i) 6 | { 7 | if (i is <= 0 or > 64) 8 | throw new ArgumentOutOfRangeException(nameof(i)); 9 | 10 | return Math.Pow(2, i - 1); 11 | } 12 | 13 | public static double Total() 14 | { 15 | return System.UInt64.MaxValue; 16 | } 17 | } -------------------------------------------------------------------------------- /tests/grains/approaches/max-value/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Total" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/grains/approaches/pow/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Grains.csproj" 8 | ], 9 | "solution": [ 10 | "Grains.cs" 11 | ], 12 | "test": [ 13 | "GrainsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/grains/approaches/pow/Grains.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | public static class Grains 5 | { 6 | public static double Square(int i) 7 | { 8 | if (i is <= 0 or > 64) 9 | throw new ArgumentOutOfRangeException(nameof(i)); 10 | 11 | return Math.Pow(2, i - 1); 12 | } 13 | 14 | public static double Total() 15 | { 16 | return Enumerable.Range(1, 64).Sum(Square); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/grains/approaches/pow/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Total" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/hamming/approaches/for-loop/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Hamming.csproj" 8 | ], 9 | "solution": [ 10 | "Hamming.cs" 11 | ], 12 | "test": [ 13 | "HammingTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/hamming/approaches/for-loop/Hamming.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Hamming 4 | { 5 | public static int Distance(string strand1, string strand2) 6 | { 7 | if (strand1.Length != strand2.Length) 8 | throw new ArgumentException("Strands have different length"); 9 | 10 | var distance = 0; 11 | 12 | for (var i = 0; i < strand1.Length; i++) 13 | { 14 | if (strand1[i] != strand2[i]) 15 | distance++; 16 | } 17 | 18 | return distance; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/hamming/approaches/for-loop/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/hamming/approaches/for-loop/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:constructor", 5 | "construct:for-loop", 6 | "construct:if", 7 | "construct:indexer", 8 | "construct:inequality", 9 | "construct:int", 10 | "construct:integral-number", 11 | "construct:method", 12 | "construct:number", 13 | "construct:parameter", 14 | "construct:postfix-increment", 15 | "construct:return", 16 | "construct:string", 17 | "construct:throw", 18 | "construct:using-directive", 19 | "construct:variable", 20 | "construct:visibility-modifiers", 21 | "paradigm:object-oriented", 22 | "technique:exceptions", 23 | "technique:looping" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/hamming/approaches/linq/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Hamming.csproj" 8 | ], 9 | "solution": [ 10 | "Hamming.cs" 11 | ], 12 | "test": [ 13 | "HammingTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/hamming/approaches/linq/Hamming.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | public static class Hamming 5 | { 6 | public static int Distance(string strand1, string strand2) 7 | { 8 | if (strand1.Length != strand2.Length) 9 | throw new ArgumentException("Strands have different length"); 10 | 11 | return strand1.Zip(strand2).Count(pair => pair.First != pair.Second); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/hamming/approaches/linq/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/hamming/approaches/linq/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:constructor", 5 | "construct:if", 6 | "construct:implicit-conversion", 7 | "construct:inequality", 8 | "construct:invocation", 9 | "construct:lambda", 10 | "construct:linq", 11 | "construct:method", 12 | "construct:parameter", 13 | "construct:return", 14 | "construct:string", 15 | "construct:throw", 16 | "construct:using-directive", 17 | "construct:visibility-modifiers", 18 | "paradigm:functional", 19 | "paradigm:object-oriented", 20 | "technique:exceptions", 21 | "technique:higher-order-functions" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /tests/isogram/approaches/bitfield/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Isogram.csproj" 8 | ], 9 | "solution": [ 10 | "Isogram.cs" 11 | ], 12 | "test": [ 13 | "IsogramTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/isogram/approaches/bitfield/Isogram.cs: -------------------------------------------------------------------------------- 1 | public static class Isogram 2 | { 3 | public static bool IsIsogram(string word) { 4 | int letter_flags = 0; 5 | foreach (char letter in word) 6 | { 7 | if (letter >= 'a' && letter <= 'z') 8 | { 9 | if ((letter_flags & (1 << (letter - 'a'))) != 0) 10 | return false; 11 | else 12 | letter_flags |= (1 << (letter - 'a')); 13 | } 14 | else if (letter >= 'A' && letter <= 'Z') 15 | { 16 | if ((letter_flags & (1 << (letter - 'A'))) != 0) 17 | return false; 18 | else 19 | letter_flags |= (1 << (letter - 'A')); 20 | } 21 | } 22 | return true; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/isogram/approaches/bitfield/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/isogram/approaches/distinct/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Isogram.csproj" 8 | ], 9 | "solution": [ 10 | "Isogram.cs" 11 | ], 12 | "test": [ 13 | "IsogramTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/isogram/approaches/distinct/Isogram.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | public static class Isogram 4 | { 5 | public static bool IsIsogram(string word) 6 | { 7 | var lowerLetters = word.ToLower().Where(char.IsLetter).ToList(); 8 | return lowerLetters.Distinct().Count() == lowerLetters.Count; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/isogram/approaches/distinct/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/isogram/approaches/distinct/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:char", 4 | "construct:class", 5 | "construct:equality", 6 | "construct:implicit-conversion", 7 | "construct:invocation", 8 | "construct:lambda", 9 | "construct:linq", 10 | "construct:list", 11 | "construct:method", 12 | "construct:parameter", 13 | "construct:return", 14 | "construct:string", 15 | "construct:using-directive", 16 | "construct:variable", 17 | "construct:visibility-modifiers", 18 | "paradigm:functional", 19 | "paradigm:object-oriented", 20 | "technique:higher-order-functions", 21 | "uses:Enumerable.Distinct", 22 | "uses:List" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/isogram/approaches/groupby/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Isogram.csproj" 8 | ], 9 | "solution": [ 10 | "Isogram.cs" 11 | ], 12 | "test": [ 13 | "IsogramTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/isogram/approaches/groupby/Isogram.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | public static class Isogram 4 | { 5 | public static bool IsIsogram(string word) 6 | { 7 | return word.ToLower().Where(char.IsLetter).GroupBy(ltr => ltr).All(ltr_grp => ltr_grp.Count() == 1); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/isogram/approaches/groupby/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "IsIsogram" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/isogram/approaches/groupby/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:char", 4 | "construct:class", 5 | "construct:equality", 6 | "construct:implicit-conversion", 7 | "construct:int", 8 | "construct:integral-number", 9 | "construct:invocation", 10 | "construct:lambda", 11 | "construct:linq", 12 | "construct:method", 13 | "construct:number", 14 | "construct:parameter", 15 | "construct:return", 16 | "construct:string", 17 | "construct:using-directive", 18 | "construct:visibility-modifiers", 19 | "paradigm:functional", 20 | "paradigm:object-oriented", 21 | "technique:higher-order-functions", 22 | "uses:Enumerable.GroupBy" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/leap/approaches/boolean-chain/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Leap.csproj" 8 | ], 9 | "solution": [ 10 | "Leap.cs" 11 | ], 12 | "test": [ 13 | "LeapTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/approaches/boolean-chain/Leap.cs: -------------------------------------------------------------------------------- 1 | public static class Leap 2 | { 3 | public static bool IsLeapYear(int year) 4 | { 5 | return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/leap/approaches/boolean-chain/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "IsLeapYear" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/leap/approaches/boolean-chain/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:boolean", 4 | "construct:class", 5 | "construct:equality", 6 | "construct:inequality", 7 | "construct:int", 8 | "construct:integral-number", 9 | "construct:logical-and", 10 | "construct:logical-or", 11 | "construct:method", 12 | "construct:modulo", 13 | "construct:number", 14 | "construct:parameter", 15 | "construct:return", 16 | "construct:visibility-modifiers", 17 | "paradigm:object-oriented", 18 | "technique:boolean-logic", 19 | "technique:short-circuiting" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/leap/approaches/built-in-method/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Leap.csproj" 8 | ], 9 | "solution": [ 10 | "Leap.cs" 11 | ], 12 | "test": [ 13 | "LeapTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/approaches/built-in-method/Leap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Leap 4 | { 5 | public static bool IsLeapYear(int year) 6 | { 7 | return DateTime.IsLeapYear(year); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/leap/approaches/built-in-method/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.leap.do_not_use_is_leap_year", 5 | "type": "essential", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.general.use_expression_bodied_member", 10 | "type": "informative", 11 | "params": { 12 | "name": "IsLeapYear" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/approaches/built-in-method/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:date-time", 5 | "construct:invocation", 6 | "construct:method", 7 | "construct:parameter", 8 | "construct:return", 9 | "construct:using-directive", 10 | "construct:visibility-modifiers", 11 | "paradigm:object-oriented", 12 | "uses:DateTime", 13 | "uses:DateTime.IsLeapYear" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/leap/approaches/datetime-addition/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Leap.csproj" 8 | ], 9 | "solution": [ 10 | "Leap.cs" 11 | ], 12 | "test": [ 13 | "LeapTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/approaches/datetime-addition/Leap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Leap 4 | { 5 | public static bool IsLeapYear(int year) => (new DateTime(year, 2, 28)).AddDays(1.0).Day == 29; 6 | } 7 | -------------------------------------------------------------------------------- /tests/leap/approaches/datetime-addition/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/leap/approaches/datetime-addition/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:constructor", 5 | "construct:date-time", 6 | "construct:double", 7 | "construct:equality", 8 | "construct:expression-bodied-member", 9 | "construct:floating-point-number", 10 | "construct:int", 11 | "construct:integral-number", 12 | "construct:invocation", 13 | "construct:method", 14 | "construct:number", 15 | "construct:parameter", 16 | "construct:using-directive", 17 | "construct:visibility-modifiers", 18 | "paradigm:object-oriented", 19 | "uses:DateTime", 20 | "uses:DateTime.AddDays" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/leap/approaches/switch-on-a-tuple/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Leap.csproj" 8 | ], 9 | "solution": [ 10 | "Leap.cs" 11 | ], 12 | "test": [ 13 | "LeapTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/approaches/switch-on-a-tuple/Leap.cs: -------------------------------------------------------------------------------- 1 | public static class Leap 2 | { 3 | public static bool IsLeapYear(int year) 4 | { 5 | return (year % 4, year % 100, year % 400) switch 6 | { 7 | (_, _, 0) => true, 8 | (_, 0, _) => false, 9 | (0, _, _) => true, 10 | _ => false, 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/leap/approaches/switch-on-a-tuple/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "IsLeapYear" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/leap/approaches/switch-on-a-tuple/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:boolean", 4 | "construct:class", 5 | "construct:int", 6 | "construct:integral-number", 7 | "construct:lambda", 8 | "construct:method", 9 | "construct:modulo", 10 | "construct:number", 11 | "construct:parameter", 12 | "construct:pattern-matching", 13 | "construct:return", 14 | "construct:switch-expression", 15 | "construct:tuple", 16 | "construct:visibility-modifiers", 17 | "paradigm:functional", 18 | "paradigm:object-oriented", 19 | "technique:higher-order-functions", 20 | "uses:ValueTuple" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/leap/approaches/ternary-operator/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Leap.csproj" 8 | ], 9 | "solution": [ 10 | "Leap.cs" 11 | ], 12 | "test": [ 13 | "LeapTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/approaches/ternary-operator/Leap.cs: -------------------------------------------------------------------------------- 1 | public static class Leap 2 | { 3 | public static bool IsLeapYear(int year) 4 | { 5 | return year % 100 == 0 ? year % 400 == 0 : year % 4 == 0; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/leap/approaches/ternary-operator/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "IsLeapYear" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/leap/approaches/ternary-operator/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:equality", 5 | "construct:int", 6 | "construct:integral-number", 7 | "construct:method", 8 | "construct:modulo", 9 | "construct:number", 10 | "construct:parameter", 11 | "construct:return", 12 | "construct:ternary", 13 | "construct:visibility-modifiers", 14 | "paradigm:object-oriented" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/if-statements/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Leap.csproj" 8 | ], 9 | "solution": [ 10 | "Leap.cs" 11 | ], 12 | "test": [ 13 | "LeapTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/if-statements/Leap.cs: -------------------------------------------------------------------------------- 1 | public static class Leap 2 | { 3 | public static bool IsLeapYear(int year) 4 | { 5 | if (year % 4 != 0) 6 | { 7 | return false; 8 | } 9 | if (year % 100 != 0 || year % 400 == 0) 10 | { 11 | return true; 12 | } 13 | 14 | return false; 15 | } 16 | } -------------------------------------------------------------------------------- /tests/leap/if-statements/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.leap.do_not_use_if_statement", 5 | "type": "actionable", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/leap/if-statements/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:boolean", 4 | "construct:class", 5 | "construct:equality", 6 | "construct:if", 7 | "construct:inequality", 8 | "construct:int", 9 | "construct:integral-number", 10 | "construct:logical-or", 11 | "construct:method", 12 | "construct:modulo", 13 | "construct:number", 14 | "construct:parameter", 15 | "construct:return", 16 | "construct:visibility-modifiers", 17 | "paradigm:object-oriented", 18 | "technique:boolean-logic", 19 | "technique:short-circuiting" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/leap/nested-if-statement/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Leap.csproj" 8 | ], 9 | "solution": [ 10 | "Leap.cs" 11 | ], 12 | "test": [ 13 | "LeapTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/nested-if-statement/Leap.cs: -------------------------------------------------------------------------------- 1 | public static class Leap 2 | { 3 | public static bool IsLeapYear(int year) 4 | { 5 | if (year % 4 == 0) 6 | { 7 | if (year % 100 != 0) 8 | { 9 | return true; 10 | } 11 | 12 | if (year % 400 == 0) 13 | { 14 | return true; 15 | } 16 | } 17 | 18 | return false; 19 | } 20 | } -------------------------------------------------------------------------------- /tests/leap/nested-if-statement/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.leap.do_not_use_if_statement", 5 | "type": "actionable", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/leap/nested-if-statement/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:boolean", 4 | "construct:class", 5 | "construct:equality", 6 | "construct:if", 7 | "construct:inequality", 8 | "construct:int", 9 | "construct:integral-number", 10 | "construct:method", 11 | "construct:modulo", 12 | "construct:number", 13 | "construct:parameter", 14 | "construct:return", 15 | "construct:visibility-modifiers", 16 | "paradigm:object-oriented" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/leap/too-many-checks/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Leap.csproj" 8 | ], 9 | "solution": [ 10 | "Leap.cs" 11 | ], 12 | "test": [ 13 | "LeapTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/too-many-checks/Leap.cs: -------------------------------------------------------------------------------- 1 | public static class Leap 2 | { 3 | public static bool IsLeapYear(int year) 4 | { 5 | return year % 4 == 0 && year % 100 != 0 || year % 100 == 0 && year % 400 == 0; 6 | } 7 | } -------------------------------------------------------------------------------- /tests/leap/too-many-checks/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.leap.use_minimum_number_of_checks", 5 | "type": "actionable", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.general.use_expression_bodied_member", 10 | "type": "informative", 11 | "params": { 12 | "name": "IsLeapYear" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/too-many-checks/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:boolean", 4 | "construct:class", 5 | "construct:equality", 6 | "construct:inequality", 7 | "construct:int", 8 | "construct:integral-number", 9 | "construct:logical-and", 10 | "construct:logical-or", 11 | "construct:method", 12 | "construct:modulo", 13 | "construct:number", 14 | "construct:parameter", 15 | "construct:return", 16 | "construct:visibility-modifiers", 17 | "paradigm:object-oriented", 18 | "technique:boolean-logic", 19 | "technique:short-circuiting" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/leap/use-is-leap-year/block-body/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Leap.csproj" 8 | ], 9 | "solution": [ 10 | "Leap.cs" 11 | ], 12 | "test": [ 13 | "LeapTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/use-is-leap-year/block-body/Leap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Leap 4 | { 5 | public static bool IsLeapYear(int year) 6 | { 7 | return DateTime.IsLeapYear(year); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/leap/use-is-leap-year/block-body/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.leap.do_not_use_is_leap_year", 5 | "type": "essential", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.general.use_expression_bodied_member", 10 | "type": "informative", 11 | "params": { 12 | "name": "IsLeapYear" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/use-is-leap-year/block-body/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:date-time", 5 | "construct:invocation", 6 | "construct:method", 7 | "construct:parameter", 8 | "construct:return", 9 | "construct:using-directive", 10 | "construct:visibility-modifiers", 11 | "paradigm:object-oriented", 12 | "uses:DateTime", 13 | "uses:DateTime.IsLeapYear" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/leap/use-is-leap-year/expression-body/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Leap.csproj" 8 | ], 9 | "solution": [ 10 | "Leap.cs" 11 | ], 12 | "test": [ 13 | "LeapTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/leap/use-is-leap-year/expression-body/Leap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Leap 4 | { 5 | public static bool IsLeapYear(int year) => 6 | DateTime.IsLeapYear(year); 7 | } -------------------------------------------------------------------------------- /tests/leap/use-is-leap-year/expression-body/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.leap.do_not_use_is_leap_year", 5 | "type": "essential", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/leap/use-is-leap-year/expression-body/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:date-time", 5 | "construct:expression-bodied-member", 6 | "construct:invocation", 7 | "construct:method", 8 | "construct:parameter", 9 | "construct:using-directive", 10 | "construct:visibility-modifiers", 11 | "paradigm:object-oriented", 12 | "uses:DateTime", 13 | "uses:DateTime.IsLeapYear" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/missing/no-analyzer-implemented/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Missing.csproj" 8 | ], 9 | "solution": [ 10 | "Missing.cs" 11 | ], 12 | "test": [ 13 | "MissingTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/missing/no-analyzer-implemented/Missing.cs: -------------------------------------------------------------------------------- 1 | public static class Missing 2 | { 3 | 4 | } -------------------------------------------------------------------------------- /tests/missing/no-analyzer-implemented/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/missing/no-analyzer-implemented/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:visibility-modifiers", 5 | "paradigm:object-oriented" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tests/palindrome-products/approaches/factors-first/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "PalindromeProducts.csproj" 8 | ], 9 | "solution": [ 10 | "PalindromeProducts.cs" 11 | ], 12 | "test": [ 13 | "PalindromeProductsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/palindrome-products/approaches/factors-first/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/pangram/approaches/all-contains-case-insensitive/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Pangram.csproj" 8 | ], 9 | "solution": [ 10 | "Pangram.cs" 11 | ], 12 | "test": [ 13 | "PangramTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/pangram/approaches/all-contains-case-insensitive/Pangram.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | public static class Pangram 5 | { 6 | private static readonly StringComparison xcase = StringComparison.CurrentCultureIgnoreCase; 7 | 8 | public static bool IsPangram(string input) 9 | { 10 | return "abcdefghijklmnopqrstuvwxyz".All(c => input.Contains(c, xcase)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/pangram/approaches/all-contains-case-insensitive/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "IsPangram" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/pangram/approaches/all-contains-case-insensitive/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:field", 5 | "construct:implicit-conversion", 6 | "construct:invocation", 7 | "construct:lambda", 8 | "construct:linq", 9 | "construct:method", 10 | "construct:parameter", 11 | "construct:read-only", 12 | "construct:return", 13 | "construct:string", 14 | "construct:using-directive", 15 | "construct:variable", 16 | "construct:visibility-modifiers", 17 | "paradigm:functional", 18 | "paradigm:object-oriented", 19 | "technique:higher-order-functions", 20 | "uses:Enumerable.All", 21 | "uses:string.Contains(char, System.StringComparison)" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /tests/pangram/approaches/all-contains-tolower/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Pangram.csproj" 8 | ], 9 | "solution": [ 10 | "Pangram.cs" 11 | ], 12 | "test": [ 13 | "PangramTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/pangram/approaches/all-contains-tolower/Pangram.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | public static class Pangram 4 | { 5 | private const string Letters = "abcdefghijklmnopqrstuvwxyz"; 6 | 7 | public static bool IsPangram(string input) 8 | { 9 | var lowerCaseInput = input.ToLower(); 10 | return Letters.All(letter => lowerCaseInput.Contains(letter)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/pangram/approaches/all-contains-tolower/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/pangram/approaches/all-contains-tolower/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:const", 5 | "construct:field", 6 | "construct:implicit-conversion", 7 | "construct:invocation", 8 | "construct:lambda", 9 | "construct:linq", 10 | "construct:method", 11 | "construct:parameter", 12 | "construct:return", 13 | "construct:string", 14 | "construct:using-directive", 15 | "construct:variable", 16 | "construct:visibility-modifiers", 17 | "paradigm:functional", 18 | "paradigm:object-oriented", 19 | "technique:higher-order-functions", 20 | "uses:Enumerable.All", 21 | "uses:String.Contains(char)", 22 | "uses:String.ToLower" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/pangram/approaches/bitfield/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Pangram.csproj" 8 | ], 9 | "solution": [ 10 | "Pangram.cs" 11 | ], 12 | "test": [ 13 | "PangramTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/pangram/approaches/bitfield/Pangram.cs: -------------------------------------------------------------------------------- 1 | public static class Pangram 2 | { 3 | public static bool IsPangram(string input) { 4 | int phrasemask = 0; 5 | foreach (char letter in input) 6 | { 7 | if (letter > 96 && letter < 123) 8 | phrasemask |= 1 << (letter - 'a'); 9 | else if (letter > 64 && letter < 91) 10 | phrasemask |= 1 << (letter - 'A'); 11 | } 12 | return phrasemask == 67108863; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/pangram/approaches/bitfield/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/parallel-letter-frequency/approaches/as-parallel/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "ParallelLetterFrequency.csproj" 8 | ], 9 | "solution": [ 10 | "ParallelLetterFrequency.cs" 11 | ], 12 | "test": [ 13 | "ParallelLetterFrequencyTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/parallel-letter-frequency/approaches/as-parallel/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Calculate" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/perfect-numbers/approaches/if-statements/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "PerfectNumbers.csproj" 8 | ], 9 | "solution": [ 10 | "PerfectNumbers.cs" 11 | ], 12 | "test": [ 13 | "PerfectNumbersTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/perfect-numbers/approaches/if-statements/PerfectNumbers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | public enum Classification 5 | { 6 | Perfect, 7 | Abundant, 8 | Deficient 9 | } 10 | 11 | public class PerfectNumbers 12 | { 13 | public static Classification Classify(int number) 14 | { 15 | if (number < 1) 16 | throw new ArgumentOutOfRangeException(nameof(number)); 17 | 18 | var sumOfFactors = Enumerable.Range(1, number / 2) 19 | .Where(factor => number % factor == 0) 20 | .Sum(); 21 | 22 | if (sumOfFactors < number) 23 | return Classification.Deficient; 24 | 25 | if (sumOfFactors > number) 26 | return Classification.Abundant; 27 | 28 | return Classification.Perfect; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/perfect-numbers/approaches/if-statements/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/perfect-numbers/approaches/if-statements/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:constructor", 5 | "construct:divide", 6 | "construct:enum", 7 | "construct:equality", 8 | "construct:if", 9 | "construct:int", 10 | "construct:integral-number", 11 | "construct:invocation", 12 | "construct:lambda", 13 | "construct:linq", 14 | "construct:method", 15 | "construct:modulo", 16 | "construct:nameof", 17 | "construct:number", 18 | "construct:parameter", 19 | "construct:return", 20 | "construct:throw", 21 | "construct:using-directive", 22 | "construct:variable", 23 | "construct:visibility-modifiers", 24 | "paradigm:functional", 25 | "paradigm:object-oriented", 26 | "technique:exceptions", 27 | "technique:higher-order-functions" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /tests/perfect-numbers/approaches/switch-expression/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "PerfectNumbers.csproj" 8 | ], 9 | "solution": [ 10 | "PerfectNumbers.cs" 11 | ], 12 | "test": [ 13 | "PerfectNumbersTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/perfect-numbers/approaches/switch-expression/PerfectNumbers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | public enum Classification 6 | { 7 | Perfect, 8 | Abundant, 9 | Deficient 10 | } 11 | 12 | public static class PerfectNumbers 13 | { 14 | public static Classification Classify(int number) 15 | { 16 | var sum = Enumerable.Range(1, number - 1) 17 | .Sum(n => number % n == 0 ? n : 0); 18 | 19 | return (sum < number, sum > number) switch 20 | { 21 | (true, _) => Classification.Deficient, 22 | (_, true) => Classification.Abundant, 23 | _ => Classification.Perfect, 24 | }; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/perfect-numbers/approaches/switch-expression/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/phone-number/approaches/regular-expression/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "PhoneNumber.csproj" 8 | ], 9 | "solution": [ 10 | "PhoneNumber.cs" 11 | ], 12 | "test": [ 13 | "PhoneNumberTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/phone-number/approaches/regular-expression/PhoneNumber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.RegularExpressions; 3 | 4 | public static class PhoneNumber 5 | { 6 | public static string Clean(string phoneNumber) 7 | { 8 | var match = Regex.Match(phoneNumber, @"^[^\d]*?1?[^\d]*?([2-9]\d{2})[^\d]*?([2-9]\d{2})[^\d]*?(\d{4})[^\d]*$"); 9 | if (!match.Success) 10 | throw new ArgumentException("Invalid phone number", nameof(phoneNumber)); 11 | 12 | return $"{match.Groups[1].Value}{match.Groups[2].Value}{match.Groups[3].Value}"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/phone-number/approaches/regular-expression/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/phone-number/approaches/regular-expression/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:constructor", 5 | "construct:if", 6 | "construct:indexer", 7 | "construct:int", 8 | "construct:integral-number", 9 | "construct:invocation", 10 | "construct:logical-not", 11 | "construct:method", 12 | "construct:nameof", 13 | "construct:number", 14 | "construct:parameter", 15 | "construct:return", 16 | "construct:string", 17 | "construct:string-interpolation", 18 | "construct:throw", 19 | "construct:using-directive", 20 | "construct:variable", 21 | "construct:verbatim-string", 22 | "construct:visibility-modifiers", 23 | "paradigm:object-oriented", 24 | "technique:exceptions", 25 | "technique:regular-expression", 26 | "uses:Regex" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /tests/pig-latin/approaches/regular-expressions/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "PigLatin.csproj" 8 | ], 9 | "solution": [ 10 | "PigLatin.cs" 11 | ], 12 | "test": [ 13 | "PigLatinTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/pig-latin/approaches/regular-expressions/PigLatin.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | public static class PigLatin 4 | { 5 | private const string VowelPattern = @"(?^|\s+)(?[aeiou]|xr|yt)(?\w+)"; 6 | private const string ConsonantPattern = @"(?^|\s+)(?([^aeiou]?qu|[^aeiou]+))(?[aeiouy]\w*)"; 7 | 8 | private const string VowelReplacement = "${begin}${vowel}${rest}ay"; 9 | private const string ConsonantReplacement = "${begin}${rest}${consonant}ay"; 10 | 11 | public static string Translate(string sentence) => 12 | Regex.IsMatch(sentence, VowelPattern) 13 | ? Regex.Replace(sentence, VowelPattern, VowelReplacement) 14 | : Regex.Replace(sentence, ConsonantPattern, ConsonantReplacement); 15 | } 16 | -------------------------------------------------------------------------------- /tests/pig-latin/approaches/regular-expressions/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/pig-latin/approaches/regular-expressions/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:const", 5 | "construct:expression-bodied-member", 6 | "construct:field", 7 | "construct:invocation", 8 | "construct:method", 9 | "construct:parameter", 10 | "construct:string", 11 | "construct:ternary", 12 | "construct:using-directive", 13 | "construct:variable", 14 | "construct:verbatim-string", 15 | "construct:visibility-modifiers", 16 | "paradigm:object-oriented", 17 | "technique:regular-expression", 18 | "uses:Regex" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /tests/poker/approaches/icomparer/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Poker.csproj" 8 | ], 9 | "solution": [ 10 | "Poker.cs" 11 | ], 12 | "test": [ 13 | "PokerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/poker/approaches/icomparer/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/poker/approaches/integer-score/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Poker.csproj" 8 | ], 9 | "solution": [ 10 | "Poker.cs" 11 | ], 12 | "test": [ 13 | "PokerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/poker/approaches/integer-score/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/protein-translation/approaches/linq-dict/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "ProteinTranslation.csproj" 8 | ], 9 | "solution": [ 10 | "ProteinTranslation.cs" 11 | ], 12 | "test": [ 13 | "ProteinTranslationTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/protein-translation/approaches/linq-dict/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Proteins" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/protein-translation/approaches/substring-dict/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "ProteinTranslation.csproj" 8 | ], 9 | "solution": [ 10 | "ProteinTranslation.cs" 11 | ], 12 | "test": [ 13 | "ProteinTranslationTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/protein-translation/approaches/substring-dict/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/protein-translation/approaches/substring-switch/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "ProteinTranslation.csproj" 8 | ], 9 | "solution": [ 10 | "ProteinTranslation.cs" 11 | ], 12 | "test": [ 13 | "ProteinTranslationTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/protein-translation/approaches/substring-switch/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/protein-translation/approaches/yield-dict/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "ProteinTranslation.csproj" 8 | ], 9 | "solution": [ 10 | "ProteinTranslation.cs" 11 | ], 12 | "test": [ 13 | "ProteinTranslationTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/protein-translation/approaches/yield-dict/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/protein-translation/approaches/yield-switch/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "ProteinTranslation.csproj" 8 | ], 9 | "solution": [ 10 | "ProteinTranslation.cs" 11 | ], 12 | "test": [ 13 | "ProteinTranslationTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/protein-translation/approaches/yield-switch/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/proverb/approaches/for-loop/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Proverb.csproj" 8 | ], 9 | "solution": [ 10 | "Proverb.cs" 11 | ], 12 | "test": [ 13 | "ProverbTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/proverb/approaches/for-loop/Proverb.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class Proverb 4 | { 5 | public static string[] Recite(string[] subjects) 6 | { 7 | if (subjects.Length == 0) 8 | return Array.Empty(); 9 | 10 | var lines = new string[subjects.Length]; 11 | 12 | for (int i = 0; i < subjects.Length - 1; i++) 13 | lines[i] = $"For want of a {subjects[i]} the {subjects[i + 1]} was lost."; 14 | 15 | lines[^1] = $"And all for the want of a {subjects[0]}."; 16 | 17 | return lines; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/proverb/approaches/for-loop/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/proverb/approaches/linq/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Proverb.csproj" 8 | ], 9 | "solution": [ 10 | "Proverb.cs" 11 | ], 12 | "test": [ 13 | "ProverbTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/proverb/approaches/linq/Proverb.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | public static class Proverb 5 | { 6 | public static string[] Recite(string[] subjects) 7 | { 8 | if (subjects.Length == 0) 9 | return Array.Empty(); 10 | 11 | return subjects.Zip(subjects.Skip(1)) 12 | .Select((pair => $"For want of a {pair.First} the {pair.Second} was lost.")) 13 | .Append($"And all for the want of a {subjects.First()}.") 14 | .ToArray(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/proverb/approaches/linq/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/proverb/approaches/linq/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:array", 4 | "construct:class", 5 | "construct:equality", 6 | "construct:if", 7 | "construct:implicit-conversion", 8 | "construct:int", 9 | "construct:integral-number", 10 | "construct:invocation", 11 | "construct:lambda", 12 | "construct:linq", 13 | "construct:method", 14 | "construct:number", 15 | "construct:parameter", 16 | "construct:return", 17 | "construct:string-interpolation", 18 | "construct:using-directive", 19 | "construct:visibility-modifiers", 20 | "paradigm:functional", 21 | "paradigm:object-oriented", 22 | "technique:higher-order-functions" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/raindrops/approaches/aggregate/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Raindrops.csproj" 8 | ], 9 | "solution": [ 10 | "Raindrops.cs" 11 | ], 12 | "test": [ 13 | "RaindropsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/raindrops/approaches/aggregate/Raindrops.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | public static class Raindrops 4 | { 5 | private static readonly (int, string)[] drips = { (3, "Pling"), (5, "Plang"), (7, "Plong") }; 6 | 7 | public static string Convert(int number) 8 | { 9 | var drops = drips.Aggregate("", (acc, drop) => number % drop.Item1 == 0 ? acc + drop.Item2 : acc); 10 | return drops.Length > 0 ? drops : number.ToString(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/raindrops/approaches/aggregate/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_string_interpolation_not_string_concatenation", 5 | "type": "informative", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/raindrops/approaches/if-statements/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Raindrops.csproj" 8 | ], 9 | "solution": [ 10 | "Raindrops.cs" 11 | ], 12 | "test": [ 13 | "RaindropsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/raindrops/approaches/if-statements/Raindrops.cs: -------------------------------------------------------------------------------- 1 | public static class Raindrops 2 | { 3 | public static string Convert(int number) 4 | { 5 | var drops = ""; 6 | if (number % 3 == 0) 7 | drops += "Pling"; 8 | if (number % 5 == 0) 9 | drops += "Plang"; 10 | if (number % 7 == 0) 11 | drops += "Plong"; 12 | return drops.Length > 0 ? drops : number.ToString(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/raindrops/approaches/if-statements/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/raindrops/approaches/if-statements/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:add", 4 | "construct:add-assignment", 5 | "construct:assignment", 6 | "construct:class", 7 | "construct:equality", 8 | "construct:if", 9 | "construct:int", 10 | "construct:integral-number", 11 | "construct:invocation", 12 | "construct:method", 13 | "construct:modulo", 14 | "construct:number", 15 | "construct:parameter", 16 | "construct:return", 17 | "construct:string", 18 | "construct:ternary", 19 | "construct:variable", 20 | "construct:visibility-modifiers", 21 | "paradigm:imperative", 22 | "paradigm:object-oriented", 23 | "technique:compound-assignment" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/array-reverse/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "ReverseString.csproj" 8 | ], 9 | "solution": [ 10 | "ReverseString.cs" 11 | ], 12 | "test": [ 13 | "ReverseStringTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/array-reverse/ReverseString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class ReverseString 4 | { 5 | public static string Reverse(string input) 6 | { 7 | var chars = input.ToCharArray(); 8 | Array.Reverse(chars); 9 | return new string(chars); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/array-reverse/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/array-reverse/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:array", 4 | "construct:class", 5 | "construct:constructor", 6 | "construct:invocation", 7 | "construct:method", 8 | "construct:parameter", 9 | "construct:return", 10 | "construct:string", 11 | "construct:using-directive", 12 | "construct:variable", 13 | "construct:visibility-modifiers", 14 | "paradigm:object-oriented", 15 | "uses:Array.Reverse" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/linq/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "ReverseString.csproj" 8 | ], 9 | "solution": [ 10 | "ReverseString.cs" 11 | ], 12 | "test": [ 13 | "ReverseStringTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/linq/ReverseString.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | public static class ReverseString 4 | { 5 | public static string Reverse(string input) 6 | { 7 | return new string(input.Reverse().ToArray()); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/linq/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Reverse" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/linq/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:constructor", 5 | "construct:implicit-conversion", 6 | "construct:invocation", 7 | "construct:lambda", 8 | "construct:linq", 9 | "construct:method", 10 | "construct:parameter", 11 | "construct:return", 12 | "construct:string", 13 | "construct:using-directive", 14 | "construct:visibility-modifiers", 15 | "paradigm:functional", 16 | "paradigm:object-oriented", 17 | "technique:higher-order-functions" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/span/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "ReverseString.csproj" 8 | ], 9 | "solution": [ 10 | "ReverseString.cs" 11 | ], 12 | "test": [ 13 | "ReverseStringTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/span/ReverseString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class ReverseString 4 | { 5 | public static string Reverse(string input) 6 | { 7 | Span chars = stackalloc char[input.Length]; 8 | for (var i = 0; i < input.Length; i++) 9 | { 10 | chars[input.Length - 1 - i] = input[i]; 11 | } 12 | return new string(chars); 13 | } 14 | } -------------------------------------------------------------------------------- /tests/reverse-string/approaches/span/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/string-builder/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "ReverseString.csproj" 8 | ], 9 | "solution": [ 10 | "ReverseString.cs" 11 | ], 12 | "test": [ 13 | "ReverseStringTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/string-builder/ReverseString.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | public static class ReverseString 4 | { 5 | public static string Reverse(string input) 6 | { 7 | var chars = new StringBuilder(); 8 | for (var i = input.Length - 1; i >= 0; i--) 9 | { 10 | chars.Append(input[i]); 11 | } 12 | return chars.ToString(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/string-builder/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/reverse-string/approaches/string-builder/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:constructor", 5 | "construct:for-loop", 6 | "construct:indexer", 7 | "construct:int", 8 | "construct:integral-number", 9 | "construct:invocation", 10 | "construct:method", 11 | "construct:number", 12 | "construct:parameter", 13 | "construct:postfix-decrement", 14 | "construct:return", 15 | "construct:string", 16 | "construct:subtract", 17 | "construct:using-directive", 18 | "construct:variable", 19 | "construct:visibility-modifiers", 20 | "paradigm:object-oriented", 21 | "technique:looping", 22 | "uses:StringBuilder" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/rna-transcription/approaches/dictionary/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "RnaTranscription.csproj" 8 | ], 9 | "solution": [ 10 | "RnaTranscription.cs" 11 | ], 12 | "test": [ 13 | "RnaTranscriptionTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/rna-transcription/approaches/dictionary/RnaTranscription.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | public static class RnaTranscription 5 | { 6 | public static string ToRna(string dna) => 7 | new(dna.Select(nucleotide => Complements[nucleotide]).ToArray()); 8 | 9 | private static readonly Dictionary Complements = 10 | new() { ['G'] = 'C', ['C'] = 'G', ['T'] = 'A', ['A'] = 'U' }; 11 | } 12 | -------------------------------------------------------------------------------- /tests/rna-transcription/approaches/dictionary/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/rna-transcription/approaches/switch-expression/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "RnaTranscription.csproj" 8 | ], 9 | "solution": [ 10 | "RnaTranscription.cs" 11 | ], 12 | "test": [ 13 | "RnaTranscriptionTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/rna-transcription/approaches/switch-expression/RnaTranscription.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | public static class RnaTranscription 4 | { 5 | public static string ToRna(string dna) => 6 | new(dna.Select(Complement).ToArray()); 7 | 8 | private static char Complement(char nucleotide) => 9 | nucleotide switch 10 | { 11 | 'G' => 'C', 12 | 'C' => 'G', 13 | 'T' => 'A', 14 | 'A' => 'U' 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /tests/rna-transcription/approaches/switch-expression/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/rna-transcription/approaches/switch-expression/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:char", 4 | "construct:class", 5 | "construct:expression-bodied-member", 6 | "construct:implicit-conversion", 7 | "construct:implicit-object-creation", 8 | "construct:invocation", 9 | "construct:lambda", 10 | "construct:linq", 11 | "construct:method", 12 | "construct:parameter", 13 | "construct:pattern-matching", 14 | "construct:switch-expression", 15 | "construct:using-directive", 16 | "construct:visibility-modifiers", 17 | "paradigm:functional", 18 | "paradigm:object-oriented", 19 | "technique:higher-order-functions" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/series/approaches/for-loop/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Series.csproj" 8 | ], 9 | "solution": [ 10 | "Series.cs" 11 | ], 12 | "test": [ 13 | "SeriesTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/series/approaches/for-loop/Series.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | public static class Series 5 | { 6 | public static IEnumerable Slices(string input, int length) 7 | { 8 | if (length < 1 || length > input.Length) 9 | throw new ArgumentException("Invalid length"); 10 | 11 | for (var i = 0; i <= input.Length - length; i++) 12 | yield return input.Substring(i, length); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/series/approaches/for-loop/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/series/approaches/linq/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Series.csproj" 8 | ], 9 | "solution": [ 10 | "Series.cs" 11 | ], 12 | "test": [ 13 | "SeriesTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/series/approaches/linq/Series.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | public static class Series 6 | { 7 | public static IEnumerable Slices(string input, int length) 8 | { 9 | if (length < 1 || length > input.Length) 10 | throw new ArgumentException("Invalid length"); 11 | 12 | return Enumerable.Range(0, input.Length - length + 1) 13 | .Select(i => input.Substring(i, length)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/series/approaches/linq/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/series/approaches/linq/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:add", 4 | "construct:boolean", 5 | "construct:class", 6 | "construct:constructor", 7 | "construct:if", 8 | "construct:int", 9 | "construct:integral-number", 10 | "construct:invocation", 11 | "construct:lambda", 12 | "construct:linq", 13 | "construct:logical-or", 14 | "construct:method", 15 | "construct:number", 16 | "construct:parameter", 17 | "construct:return", 18 | "construct:string", 19 | "construct:subtract", 20 | "construct:throw", 21 | "construct:using-directive", 22 | "construct:visibility-modifiers", 23 | "paradigm:functional", 24 | "paradigm:object-oriented", 25 | "technique:boolean-logic", 26 | "technique:exceptions", 27 | "technique:higher-order-functions", 28 | "technique:short-circuiting" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /tests/sieve/approaches/bit-array/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Sieve.csproj" 8 | ], 9 | "solution": [ 10 | "Sieve.cs" 11 | ], 12 | "test": [ 13 | "SieveTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/sieve/approaches/bit-array/Sieve.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | public static class Sieve 6 | { 7 | public static IEnumerable Primes(int max) 8 | { 9 | if (max < 0) 10 | throw new ArgumentOutOfRangeException(nameof(max)); 11 | 12 | var primes = new BitArray(max + 1, true); 13 | 14 | for (var i = 2; i <= max; i++) 15 | { 16 | if (!primes[i]) 17 | continue; 18 | 19 | for (var j = i * 2; j <= max; j += i) 20 | primes[j] = false; 21 | 22 | yield return i; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/sieve/approaches/bit-array/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/sieve/approaches/hash-set/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Sieve.csproj" 8 | ], 9 | "solution": [ 10 | "Sieve.cs" 11 | ], 12 | "test": [ 13 | "SieveTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/sieve/approaches/hash-set/Sieve.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | public static class Sieve 5 | { 6 | public static IEnumerable Primes(int max) 7 | { 8 | if (max < 0) 9 | throw new ArgumentOutOfRangeException(nameof(max)); 10 | 11 | var primeMultiples = new HashSet(); 12 | 13 | for (var i = 2; i <= max; i++) 14 | { 15 | if (primeMultiples.Contains(i)) 16 | continue; 17 | 18 | for (var j = i * 2; j <= max; j += i) 19 | primeMultiples.Add(j); 20 | 21 | yield return i; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/sieve/approaches/hash-set/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/tags/constructs/comments/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Comments.csproj" 8 | ], 9 | "solution": [ 10 | "FlowControl.cs" 11 | ], 12 | "test": [ 13 | "FlowControlTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/constructs/comments/Comments.cs: -------------------------------------------------------------------------------- 1 | public static class Program 2 | { 3 | /// 4 | /// This is an XML comment 5 | /// 6 | public static void Main() 7 | { 8 | // Single line comment 9 | var x = 1; 10 | 11 | /* 12 | * Multi line comment 13 | */ 14 | var y = 2; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/constructs/comments/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.has_main_method", 5 | "type": "essential", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/tags/constructs/comments/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:comment", 5 | "construct:int", 6 | "construct:integral-number", 7 | "construct:method", 8 | "construct:number", 9 | "construct:variable", 10 | "construct:visibility-modifiers", 11 | "paradigm:object-oriented" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/tags/constructs/compound-assignment/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "CompoundAssignment.csproj" 8 | ], 9 | "solution": [ 10 | "CompoundAssignment.cs" 11 | ], 12 | "test": [ 13 | "CompoundAssignmentTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/constructs/compound-assignment/CompoundAssignment.cs: -------------------------------------------------------------------------------- 1 | namespace DefaultNamespace; 2 | 3 | public static class Program 4 | { 5 | public static void Main() 6 | { 7 | var i = 0; 8 | i += 1; 9 | i -= 2; 10 | i *= 3; 11 | i /= 4; 12 | i %= 5; 13 | i <<= 6; 14 | i >>= 7; 15 | i |= 8; 16 | i &= 9; 17 | i ^= 10; 18 | 19 | string j = null; 20 | j ??= "a"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/tags/constructs/compound-assignment/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.has_main_method", 5 | "type": "essential", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/tags/constructs/events/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Events.csproj" 8 | ], 9 | "solution": [ 10 | "Events.cs" 11 | ], 12 | "test": [ 13 | "EventsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/constructs/events/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.do_not_write_to_console", 5 | "type": "actionable", 6 | "params": {} 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/tags/constructs/exceptions/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Exceptions.csproj" 8 | ], 9 | "solution": [ 10 | "Exceptions.cs" 11 | ], 12 | "test": [ 13 | "ExceptionsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/constructs/exceptions/Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public class CustomException : Exception 4 | { 5 | public CustomException() 6 | { 7 | } 8 | } 9 | 10 | public static class Program 11 | { 12 | public static void Exceptions() 13 | { 14 | try 15 | { 16 | throw new CustomException(); 17 | } 18 | catch (Exception ex) when (ex.Message.Contains("404")) 19 | { 20 | } 21 | finally 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /tests/tags/constructs/exceptions/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/tags/constructs/exceptions/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:catch", 4 | "construct:catch-filter", 5 | "construct:class", 6 | "construct:constructor", 7 | "construct:finally", 8 | "construct:invocation", 9 | "construct:method", 10 | "construct:string", 11 | "construct:throw", 12 | "construct:try", 13 | "construct:user-defined-exception", 14 | "construct:using-directive", 15 | "construct:visibility-modifiers", 16 | "paradigm:object-oriented", 17 | "technique:exceptions", 18 | "technique:inheritance" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /tests/tags/constructs/flow-control/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "FlowControl.csproj" 8 | ], 9 | "solution": [ 10 | "FlowControl.cs" 11 | ], 12 | "test": [ 13 | "FlowControlTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/constructs/flow-control/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.has_main_method", 5 | "type": "essential", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.general.do_not_write_to_console", 10 | "type": "actionable", 11 | "params": {} 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/tags/constructs/functional/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Functional.csproj" 8 | ], 9 | "solution": [ 10 | "Functional.cs" 11 | ], 12 | "test": [ 13 | "FunctionalTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/constructs/functional/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "FunctionParameter" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/tags/constructs/methods/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Methods.csproj" 8 | ], 9 | "solution": [ 10 | "Methods.cs" 11 | ], 12 | "test": [ 13 | "MethodsTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/constructs/methods/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Parameters" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/tags/constructs/methods/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:add", 4 | "construct:class", 5 | "construct:file-scoped-namespace", 6 | "construct:int", 7 | "construct:integral-number", 8 | "construct:invocation", 9 | "construct:local-function", 10 | "construct:method", 11 | "construct:named-argument", 12 | "construct:namespace", 13 | "construct:number", 14 | "construct:optional-parameter", 15 | "construct:parameter", 16 | "construct:return", 17 | "construct:varargs", 18 | "construct:visibility-modifiers", 19 | "paradigm:object-oriented" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/tags/constructs/resources/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Resources.csproj" 8 | ], 9 | "solution": [ 10 | "Resources.cs" 11 | ], 12 | "test": [ 13 | "ResourcesTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/constructs/resources/Resources.cs: -------------------------------------------------------------------------------- 1 | namespace DefaultNamespace; 2 | 3 | using System; 4 | using System.IO; 5 | 6 | public class Resources : IDisposable 7 | { 8 | public void ManualDispose() 9 | { 10 | var reader = File.OpenText("tmp.json"); 11 | reader.Dispose(); 12 | } 13 | 14 | public void AutomaticDisposeInBlock() 15 | { 16 | using (var reader = File.OpenText("tmp.json")) 17 | { 18 | } 19 | } 20 | 21 | public void AutomaticDispose() 22 | { 23 | using var reader = File.OpenText("tmp.json"); 24 | } 25 | 26 | public void Dispose() 27 | { 28 | } 29 | } -------------------------------------------------------------------------------- /tests/tags/constructs/resources/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/tags/constructs/resources/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:file-scoped-namespace", 5 | "construct:invocation", 6 | "construct:method", 7 | "construct:namespace", 8 | "construct:string", 9 | "construct:using-directive", 10 | "construct:using-statement", 11 | "construct:variable", 12 | "construct:visibility-modifiers", 13 | "paradigm:object-oriented", 14 | "technique:inheritance", 15 | "uses:IDisposable" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/tags/constructs/types/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Types.csproj" 8 | ], 9 | "solution": [ 10 | "Types.cs" 11 | ], 12 | "test": [ 13 | "TypesTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/constructs/types/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.do_not_write_to_console", 5 | "type": "actionable", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.general.use_expression_bodied_member", 10 | "type": "informative", 11 | "params": { 12 | "name": "Sample" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/paradigms/reflective/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Reflective.csproj" 8 | ], 9 | "solution": [ 10 | "Reflective.cs" 11 | ], 12 | "test": [ 13 | "ReflectiveTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/paradigms/reflective/Reflective.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | public static class Reflective 5 | { 6 | public static void UsingGetType() 7 | { 8 | var x = 2.GetType(); 9 | } 10 | 11 | public static void UsingTypeof() 12 | { 13 | var x = typeof(int); 14 | } 15 | } -------------------------------------------------------------------------------- /tests/tags/paradigms/reflective/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/tags/paradigms/reflective/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:int", 5 | "construct:integral-number", 6 | "construct:invocation", 7 | "construct:method", 8 | "construct:number", 9 | "construct:using-directive", 10 | "construct:variable", 11 | "construct:visibility-modifiers", 12 | "paradigm:object-oriented", 13 | "paradigm:reflective" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/tags/techniques/recursion/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Recursion.csproj" 8 | ], 9 | "solution": [ 10 | "Recursion.cs" 11 | ], 12 | "test": [ 13 | "RecursionTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/techniques/recursion/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "NonRecursiveMethod" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/tags/techniques/recursion/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:add", 4 | "construct:class", 5 | "construct:equality", 6 | "construct:if", 7 | "construct:int", 8 | "construct:integral-number", 9 | "construct:invocation", 10 | "construct:lambda", 11 | "construct:local-function", 12 | "construct:method", 13 | "construct:multiply", 14 | "construct:number", 15 | "construct:parameter", 16 | "construct:return", 17 | "construct:subtract", 18 | "construct:visibility-modifiers", 19 | "paradigm:functional", 20 | "paradigm:object-oriented", 21 | "technique:higher-order-functions", 22 | "technique:recursion" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/tags/uses/types/basic/framework-types/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Types.csproj" 8 | ], 9 | "solution": [ 10 | "Types.cs" 11 | ], 12 | "test": [ 13 | "TypesTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/uses/types/basic/framework-types/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/tags/uses/types/basic/language-types/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Types.csproj" 8 | ], 9 | "solution": [ 10 | "Types.cs" 11 | ], 12 | "test": [ 13 | "TypesTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/uses/types/basic/language-types/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/tags/uses/types/basic/language-types/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:byte", 4 | "construct:class", 5 | "construct:decimal", 6 | "construct:double", 7 | "construct:float", 8 | "construct:floating-point-number", 9 | "construct:implicit-conversion", 10 | "construct:int", 11 | "construct:integral-number", 12 | "construct:long", 13 | "construct:method", 14 | "construct:nint", 15 | "construct:nuint", 16 | "construct:number", 17 | "construct:sbyte", 18 | "construct:short", 19 | "construct:string", 20 | "construct:uint", 21 | "construct:ulong", 22 | "construct:ushort", 23 | "construct:variable", 24 | "construct:visibility-modifiers", 25 | "paradigm:object-oriented" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/tags/uses/types/basic/literals/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Types.csproj" 8 | ], 9 | "solution": [ 10 | "Types.cs" 11 | ], 12 | "test": [ 13 | "TypesTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/uses/types/basic/literals/Types.cs: -------------------------------------------------------------------------------- 1 | public static class Types 2 | { 3 | public static void Integrals() 4 | { 5 | var implicitInt = 0; 6 | var implicitUint = 1u; 7 | var implicitLong = 2l; 8 | var implicitUlong = 3ul; 9 | } 10 | 11 | public static void FloatingPoint() 12 | { 13 | var implicitFloat = 0.0f; 14 | var implicitDouble = 1.0d; 15 | var implicitDecimal = 2.0m; 16 | } 17 | 18 | public static void Other() 19 | { 20 | var implicitString = ""; 21 | } 22 | } -------------------------------------------------------------------------------- /tests/tags/uses/types/basic/literals/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/tags/uses/types/basic/literals/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:decimal", 5 | "construct:double", 6 | "construct:float", 7 | "construct:floating-point-number", 8 | "construct:int", 9 | "construct:integral-number", 10 | "construct:long", 11 | "construct:method", 12 | "construct:number", 13 | "construct:string", 14 | "construct:uint", 15 | "construct:ulong", 16 | "construct:variable", 17 | "construct:visibility-modifiers", 18 | "paradigm:object-oriented" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /tests/tags/uses/types/collections/framework-types/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Types.csproj" 8 | ], 9 | "solution": [ 10 | "Types.cs" 11 | ], 12 | "test": [ 13 | "TypesTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/tags/uses/types/collections/framework-types/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/two-bucket/approaches/graph-shortest-path/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoBucket.csproj" 8 | ], 9 | "solution": [ 10 | "TwoBucket.cs" 11 | ], 12 | "test": [ 13 | "TwoBucketTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-bucket/approaches/graph-shortest-path/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/two-fer/approaches/method-overloading/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoFer.csproj" 8 | ], 9 | "solution": [ 10 | "TwoFer.cs" 11 | ], 12 | "test": [ 13 | "TwoFerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/approaches/method-overloading/TwoFer.cs: -------------------------------------------------------------------------------- 1 | public static class TwoFer 2 | { 3 | public static string Speak() 4 | { 5 | return Speak("you"); 6 | } 7 | 8 | public static string Speak(string name) 9 | { 10 | return $"One for {name}, one for me."; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/two-fer/approaches/method-overloading/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.two-fer.use_default_value_not_overloads", 5 | "type": "essential", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.two-fer.use_default_value", 10 | "type": "essential", 11 | "params": { 12 | "name": "name" 13 | } 14 | }, 15 | { 16 | "comment": "csharp.general.use_expression_bodied_member", 17 | "type": "informative", 18 | "params": { 19 | "name": "Speak" 20 | } 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /tests/two-fer/approaches/method-overloading/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:invocation", 5 | "construct:method", 6 | "construct:method-overloading", 7 | "construct:parameter", 8 | "construct:return", 9 | "construct:string", 10 | "construct:string-interpolation", 11 | "construct:visibility-modifiers", 12 | "paradigm:object-oriented" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/two-fer/approaches/optional-parameter/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoFer.csproj" 8 | ], 9 | "solution": [ 10 | "TwoFer.cs" 11 | ], 12 | "test": [ 13 | "TwoFerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/approaches/optional-parameter/TwoFer.cs: -------------------------------------------------------------------------------- 1 | public static class TwoFer 2 | { 3 | public static string Speak(string name = "you") 4 | { 5 | return $"One for {name}, one for me."; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/two-fer/approaches/optional-parameter/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Speak" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/two-fer/approaches/optional-parameter/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:method", 5 | "construct:optional-parameter", 6 | "construct:parameter", 7 | "construct:return", 8 | "construct:string", 9 | "construct:string-interpolation", 10 | "construct:visibility-modifiers", 11 | "paradigm:object-oriented" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/two-fer/concatenation/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoFer.csproj" 8 | ], 9 | "solution": [ 10 | "TwoFer.cs" 11 | ], 12 | "test": [ 13 | "TwoFerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/concatenation/TwoFer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class TwoFer 4 | { 5 | public static string Speak(string input = "you") 6 | { 7 | return "One for " + input + ", one for me."; 8 | } 9 | } -------------------------------------------------------------------------------- /tests/two-fer/concatenation/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Speak" 8 | } 9 | }, 10 | { 11 | "comment": "csharp.general.use_string_interpolation_not_string_concatenation", 12 | "type": "informative", 13 | "params": {} 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/concatenation/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:add", 4 | "construct:class", 5 | "construct:method", 6 | "construct:optional-parameter", 7 | "construct:parameter", 8 | "construct:return", 9 | "construct:string", 10 | "construct:using-directive", 11 | "construct:visibility-modifiers", 12 | "paradigm:object-oriented" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/two-fer/if/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoFer.csproj" 8 | ], 9 | "solution": [ 10 | "TwoFer.cs" 11 | ], 12 | "test": [ 13 | "TwoFerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/if/TwoFer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class TwoFer 4 | { 5 | public static string Speak(string input = null) 6 | { 7 | if (input == null) 8 | return "One for you, one for me."; 9 | else 10 | return "One for " + input + ", one for me."; 11 | } 12 | } -------------------------------------------------------------------------------- /tests/two-fer/if/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.two-fer.invalid_default_value", 5 | "type": "actionable", 6 | "params": { 7 | "name": "input", 8 | "value": "null" 9 | } 10 | }, 11 | { 12 | "comment": "csharp.general.use_string_interpolation_not_string_concatenation", 13 | "type": "informative", 14 | "params": {} 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/two-fer/if/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:add", 4 | "construct:class", 5 | "construct:else", 6 | "construct:equality", 7 | "construct:if", 8 | "construct:method", 9 | "construct:null", 10 | "construct:nullability", 11 | "construct:optional-parameter", 12 | "construct:parameter", 13 | "construct:return", 14 | "construct:string", 15 | "construct:using-directive", 16 | "construct:visibility-modifiers", 17 | "paradigm:object-oriented" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tests/two-fer/interpolation/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoFer.csproj" 8 | ], 9 | "solution": [ 10 | "TwoFer.cs" 11 | ], 12 | "test": [ 13 | "TwoFerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/interpolation/TwoFer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class TwoFer 4 | { 5 | public static string Speak(string input = "you") 6 | { 7 | return $"One for {input}, one for me."; 8 | } 9 | } -------------------------------------------------------------------------------- /tests/two-fer/interpolation/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_expression_bodied_member", 5 | "type": "informative", 6 | "params": { 7 | "name": "Speak" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/two-fer/interpolation/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:method", 5 | "construct:optional-parameter", 6 | "construct:parameter", 7 | "construct:return", 8 | "construct:string", 9 | "construct:string-interpolation", 10 | "construct:using-directive", 11 | "construct:visibility-modifiers", 12 | "paradigm:object-oriented" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/two-fer/invalid-default-value/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoFer.csproj" 8 | ], 9 | "solution": [ 10 | "TwoFer.cs" 11 | ], 12 | "test": [ 13 | "TwoFerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/invalid-default-value/TwoFer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class TwoFer 4 | { 5 | public static string Speak(string input = "hi") => 6 | $"One for {input}, one for me."; 7 | } -------------------------------------------------------------------------------- /tests/two-fer/invalid-default-value/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.two-fer.invalid_default_value", 5 | "type": "actionable", 6 | "params": { 7 | "name": "input", 8 | "value": "\"hi\"" 9 | } 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/two-fer/invalid-default-value/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:expression-bodied-member", 5 | "construct:method", 6 | "construct:optional-parameter", 7 | "construct:parameter", 8 | "construct:string", 9 | "construct:string-interpolation", 10 | "construct:using-directive", 11 | "construct:visibility-modifiers", 12 | "paradigm:object-oriented" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/two-fer/is-null-or-empty/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoFer.csproj" 8 | ], 9 | "solution": [ 10 | "TwoFer.cs" 11 | ], 12 | "test": [ 13 | "TwoFerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/is-null-or-empty/TwoFer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class TwoFer 4 | { 5 | public static string Speak(string input = null) 6 | { 7 | return $"One for {(string.IsNullOrEmpty(input) ? "you" : input)}, one for me."; 8 | } 9 | } -------------------------------------------------------------------------------- /tests/two-fer/is-null-or-empty/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.two-fer.invalid_default_value", 5 | "type": "actionable", 6 | "params": { 7 | "name": "input", 8 | "value": "null" 9 | } 10 | }, 11 | { 12 | "comment": "csharp.two-fer.use_null_coalescing_operator_not_is_null_or_empty", 13 | "type": "actionable", 14 | "params": {} 15 | }, 16 | { 17 | "comment": "csharp.general.use_expression_bodied_member", 18 | "type": "informative", 19 | "params": { 20 | "name": "Speak" 21 | } 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/two-fer/is-null-or-empty/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:invocation", 5 | "construct:method", 6 | "construct:null", 7 | "construct:nullability", 8 | "construct:optional-parameter", 9 | "construct:parameter", 10 | "construct:return", 11 | "construct:string", 12 | "construct:string-interpolation", 13 | "construct:ternary", 14 | "construct:using-directive", 15 | "construct:visibility-modifiers", 16 | "paradigm:object-oriented" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/two-fer/is-null-or-white-space/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoFer.csproj" 8 | ], 9 | "solution": [ 10 | "TwoFer.cs" 11 | ], 12 | "test": [ 13 | "TwoFerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/is-null-or-white-space/TwoFer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class TwoFer 4 | { 5 | public static string Speak(string input = null) 6 | { 7 | return $"One for {(string.IsNullOrWhiteSpace(input) ? "you" : input)}, one for me."; 8 | } 9 | } -------------------------------------------------------------------------------- /tests/two-fer/is-null-or-white-space/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.two-fer.invalid_default_value", 5 | "type": "actionable", 6 | "params": { 7 | "name": "input", 8 | "value": "null" 9 | } 10 | }, 11 | { 12 | "comment": "csharp.two-fer.use_null_coalescing_operator_not_is_null_or_white_space", 13 | "type": "actionable", 14 | "params": {} 15 | }, 16 | { 17 | "comment": "csharp.general.use_expression_bodied_member", 18 | "type": "informative", 19 | "params": { 20 | "name": "Speak" 21 | } 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/two-fer/is-null-or-white-space/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:invocation", 5 | "construct:method", 6 | "construct:null", 7 | "construct:nullability", 8 | "construct:optional-parameter", 9 | "construct:parameter", 10 | "construct:return", 11 | "construct:string", 12 | "construct:string-interpolation", 13 | "construct:ternary", 14 | "construct:using-directive", 15 | "construct:visibility-modifiers", 16 | "paradigm:object-oriented" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/two-fer/null-coalescing/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoFer.csproj" 8 | ], 9 | "solution": [ 10 | "TwoFer.cs" 11 | ], 12 | "test": [ 13 | "TwoFerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/null-coalescing/TwoFer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class TwoFer 4 | { 5 | public static string Speak(string input = null) 6 | { 7 | return $"One for {input ?? "you"}, one for me."; 8 | } 9 | } -------------------------------------------------------------------------------- /tests/two-fer/null-coalescing/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.two-fer.invalid_default_value", 5 | "type": "actionable", 6 | "params": { 7 | "name": "input", 8 | "value": "null" 9 | } 10 | }, 11 | { 12 | "comment": "csharp.general.use_expression_bodied_member", 13 | "type": "informative", 14 | "params": { 15 | "name": "Speak" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tests/two-fer/null-coalescing/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:method", 5 | "construct:null", 6 | "construct:null-coalesce", 7 | "construct:nullability", 8 | "construct:optional-parameter", 9 | "construct:parameter", 10 | "construct:return", 11 | "construct:string", 12 | "construct:string-interpolation", 13 | "construct:using-directive", 14 | "construct:visibility-modifiers", 15 | "paradigm:object-oriented", 16 | "technique:short-circuiting" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/two-fer/string.concat/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoFer.csproj" 8 | ], 9 | "solution": [ 10 | "TwoFer.cs" 11 | ], 12 | "test": [ 13 | "TwoFerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/string.concat/TwoFer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class TwoFer 4 | { 5 | public static string Speak(string input = "you") 6 | { 7 | return string.Concat("One for ", input, ", one for me."); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/two-fer/string.concat/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.two-fer.use_string_interpolation_not_string_concat", 5 | "type": "actionable", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.general.use_expression_bodied_member", 10 | "type": "informative", 11 | "params": { 12 | "name": "Speak" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/string.concat/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:invocation", 5 | "construct:method", 6 | "construct:optional-parameter", 7 | "construct:parameter", 8 | "construct:return", 9 | "construct:string", 10 | "construct:using-directive", 11 | "construct:visibility-modifiers", 12 | "paradigm:object-oriented" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/two-fer/string.format/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoFer.csproj" 8 | ], 9 | "solution": [ 10 | "TwoFer.cs" 11 | ], 12 | "test": [ 13 | "TwoFerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/string.format/TwoFer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class TwoFer 4 | { 5 | public static string Speak(string input = "you") 6 | { 7 | return string.Format("One for {0}, one for me.", input); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/two-fer/string.format/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_string_interpolation_not_string_format", 5 | "type": "actionable", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.general.use_expression_bodied_member", 10 | "type": "informative", 11 | "params": { 12 | "name": "Speak" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/string.format/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:class", 4 | "construct:invocation", 5 | "construct:method", 6 | "construct:optional-parameter", 7 | "construct:parameter", 8 | "construct:return", 9 | "construct:string", 10 | "construct:using-directive", 11 | "construct:visibility-modifiers", 12 | "paradigm:object-oriented" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/two-fer/string.join/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "TwoFer.csproj" 8 | ], 9 | "solution": [ 10 | "TwoFer.cs" 11 | ], 12 | "test": [ 13 | "TwoFerTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/two-fer/string.join/TwoFer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public static class TwoFer 4 | { 5 | public static string Speak(string input = null) 6 | { 7 | string name = string.IsNullOrEmpty(input) ? "you" : input; 8 | var sentence = new[] { "One for ", name, ", one for me."}; 9 | 10 | return String.Join("", sentence); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/two-fer/string.join/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.two-fer.invalid_default_value", 5 | "type": "actionable", 6 | "params": { 7 | "name": "input", 8 | "value": "null" 9 | } 10 | }, 11 | { 12 | "comment": "csharp.two-fer.use_null_coalescing_operator_not_is_null_or_empty", 13 | "type": "actionable", 14 | "params": {} 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/two-fer/string.join/expected_tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "construct:array", 4 | "construct:class", 5 | "construct:implicit-array-creation", 6 | "construct:initializer", 7 | "construct:invocation", 8 | "construct:method", 9 | "construct:null", 10 | "construct:nullability", 11 | "construct:optional-parameter", 12 | "construct:parameter", 13 | "construct:return", 14 | "construct:string", 15 | "construct:ternary", 16 | "construct:using-directive", 17 | "construct:variable", 18 | "construct:visibility-modifiers", 19 | "paradigm:object-oriented" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/weighing-machine/backing-field-should-be-private/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "WeighingMachine.csproj" 8 | ], 9 | "solution": [ 10 | "WeighingMachine.cs" 11 | ], 12 | "test": [ 13 | "WeighingMachineTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/weighing-machine/backing-field-should-be-private/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.use_private_visibility", 5 | "type": "actionable", 6 | "params": { 7 | "name": "_weightStrangeName" 8 | } 9 | }, 10 | { 11 | "comment": "csharp.general.use_string_interpolation_not_string_concatenation", 12 | "type": "informative", 13 | "params": {} 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/weighing-machine/exemplar/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "WeighingMachine.csproj" 8 | ], 9 | "solution": [ 10 | "WeighingMachine.cs" 11 | ], 12 | "test": [ 13 | "WeighingMachineTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/weighing-machine/exemplar/WeighingMachine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | class WeighingMachine 4 | { 5 | private double _weight; 6 | 7 | public WeighingMachine(int precision) 8 | { 9 | Precision = precision; 10 | } 11 | 12 | public int Precision { get; } 13 | 14 | public double TareAdjustment { get; set; } = 5.0; 15 | 16 | public double Weight 17 | { 18 | get 19 | { 20 | return _weight; 21 | } 22 | set 23 | { 24 | if (value < 0) throw new ArgumentOutOfRangeException(); 25 | _weight = value; 26 | } 27 | } 28 | 29 | public string DisplayWeight 30 | { 31 | get 32 | { 33 | return $"{Math.Round(Weight - TareAdjustment, Precision).ToString($"F{Precision}")} kg"; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/weighing-machine/exemplar/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | -------------------------------------------------------------------------------- /tests/weighing-machine/is-not-auto-property/property-precision/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "WeighingMachine.csproj" 8 | ], 9 | "solution": [ 10 | "WeighingMachine.cs" 11 | ], 12 | "test": [ 13 | "WeighingMachineTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/weighing-machine/is-not-auto-property/property-precision/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.property_is_not_auto_property", 5 | "type": "actionable", 6 | "params": { 7 | "name": "Precision" 8 | } 9 | }, 10 | { 11 | "comment": "csharp.general.use_string_interpolation_not_string_concatenation", 12 | "type": "informative", 13 | "params": {} 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/weighing-machine/is-not-auto-property/property-tare-adjustment/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "WeighingMachine.csproj" 8 | ], 9 | "solution": [ 10 | "WeighingMachine.cs" 11 | ], 12 | "test": [ 13 | "WeighingMachineTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/weighing-machine/is-not-auto-property/property-tare-adjustment/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.property_is_not_auto_property", 5 | "type": "actionable", 6 | "params": { 7 | "name": "TareAdjustment" 8 | } 9 | }, 10 | { 11 | "comment": "csharp.general.use_string_interpolation_not_string_concatenation", 12 | "type": "informative", 13 | "params": {} 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/weighing-machine/precision-is-not-getter-only/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "WeighingMachine.csproj" 8 | ], 9 | "solution": [ 10 | "WeighingMachine.cs" 11 | ], 12 | "test": [ 13 | "WeighingMachineTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/weighing-machine/precision-is-not-getter-only/WeighingMachine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | class WeighingMachine 4 | { 5 | private double _weight; 6 | 7 | public WeighingMachine(int precision) 8 | { 9 | Precision = precision; 10 | } 11 | 12 | public int Precision { get; set; } 13 | 14 | public double TareAdjustment { get; set; } = 5.0; 15 | 16 | public double Weight 17 | { 18 | get 19 | { 20 | return _weight; 21 | } 22 | set 23 | { 24 | if (value < 0) throw new ArgumentOutOfRangeException(); 25 | _weight = value; 26 | } 27 | } 28 | 29 | public string DisplayWeight 30 | { 31 | get 32 | { 33 | return Math.Round(Weight - TareAdjustment, Precision).ToString($"F{Precision}") + " kg"; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/weighing-machine/precision-is-not-getter-only/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.property_use_getter_only", 5 | "type": "actionable", 6 | "params": { 7 | "name": "Precision" 8 | } 9 | }, 10 | { 11 | "comment": "csharp.general.use_string_interpolation_not_string_concatenation", 12 | "type": "informative", 13 | "params": {} 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/weighing-machine/round-method-called/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "WeighingMachine.csproj" 8 | ], 9 | "solution": [ 10 | "WeighingMachine.cs" 11 | ], 12 | "test": [ 13 | "WeighingMachineTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/weighing-machine/round-method-called/WeighingMachine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | class WeighingMachine 4 | { 5 | private double _weighte; 6 | 7 | public WeighingMachine(int precision) 8 | { 9 | Precision = precision; 10 | } 11 | 12 | public int Precision { get; } 13 | 14 | public double TareAdjustment { get; set; } = 5.0; 15 | 16 | public double Weight 17 | { 18 | get 19 | { 20 | return _weighte; 21 | } 22 | set 23 | { 24 | if (value < 0) throw new ArgumentOutOfRangeException(); 25 | _weighte = value; 26 | } 27 | } 28 | 29 | public string DisplayWeight 30 | { 31 | get 32 | { 33 | return (Weight - TareAdjustment).ToString($"F{Precision}") + " kg"; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/weighing-machine/round-method-called/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.weighing-machine.use_math_round_in_display_weight", 5 | "type": "essential", 6 | "params": {} 7 | }, 8 | { 9 | "comment": "csharp.general.use_string_interpolation_not_string_concatenation", 10 | "type": "informative", 11 | "params": {} 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/weighing-machine/use-initializer/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "WeighingMachine.csproj" 8 | ], 9 | "solution": [ 10 | "WeighingMachine.cs" 11 | ], 12 | "test": [ 13 | "WeighingMachineTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/weighing-machine/use-initializer/WeighingMachine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | class WeighingMachine 4 | { 5 | private double _weighte; 6 | 7 | public WeighingMachine(int precision) 8 | { 9 | Precision = precision; 10 | TareAdjustment = 5.0; 11 | } 12 | 13 | public int Precision { get; } 14 | 15 | public double TareAdjustment { get; set; } 16 | 17 | public double Weight 18 | { 19 | get 20 | { 21 | return _weighte; 22 | } 23 | set 24 | { 25 | if (value < 0) throw new ArgumentOutOfRangeException(); 26 | _weighte = value; 27 | } 28 | } 29 | 30 | public string DisplayWeight 31 | { 32 | get 33 | { 34 | return Math.Round(Weight - TareAdjustment, Precision).ToString($"F{Precision}") + " kg"; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/weighing-machine/use-initializer/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "comment": "csharp.general.property_better_use_initializer", 5 | "type": "actionable", 6 | "params": { 7 | "name": "TareAdjustment" 8 | } 9 | }, 10 | { 11 | "comment": "csharp.general.use_string_interpolation_not_string_concatenation", 12 | "type": "informative", 13 | "params": {} 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/yacht/approaches/linq/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "example": [ 4 | ".meta/Example.cs" 5 | ], 6 | "invalidator": [ 7 | "Yacht.csproj" 8 | ], 9 | "solution": [ 10 | "Yacht.cs" 11 | ], 12 | "test": [ 13 | "YachtTests.cs" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/yacht/approaches/linq/expected_analysis.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [] 3 | } 4 | --------------------------------------------------------------------------------