From cc21cc22a07b1c425fd495ac75beaba09430c9ba Mon Sep 17 00:00:00 2001 From: Marcel Gaupp Date: Mon, 28 Oct 2024 20:28:54 +0100 Subject: [PATCH] Add C# template --- build.gradle | 1 + ...ProgrammingPlagiarismDetectionService.java | 4 +- .../domain/ProgrammingLanguage.java | 1 + .../service/TemplateUpgradePolicyService.java | 5 +- .../ci/ContinuousIntegrationService.java | 10 +- ...alCIProgrammingLanguageFeatureService.java | 2 + src/main/resources/config/application.yml | 2 + .../templates/aeolus/c_sharp/default.sh | 26 + .../templates/aeolus/c_sharp/default.yaml | 13 + .../templates/c_sharp/exercise/.gitignore | 484 ++++++++++++++++++ .../templates/c_sharp/exercise/BubbleSort.cs | 13 + .../templates/c_sharp/exercise/Client.cs | 90 ++++ .../templates/c_sharp/exercise/MergeSort.cs | 13 + .../c_sharp/exercise/assignment.csproj | 10 + src/main/resources/templates/c_sharp/readme | 91 ++++ .../templates/c_sharp/solution/.gitignore | 484 ++++++++++++++++++ .../templates/c_sharp/solution/BubbleSort.cs | 22 + .../templates/c_sharp/solution/Client.cs | 85 +++ .../templates/c_sharp/solution/Context.cs | 23 + .../c_sharp/solution/ISortStrategy.cs | 10 + .../templates/c_sharp/solution/MergeSort.cs | 70 +++ .../templates/c_sharp/solution/Policy.cs | 37 ++ .../c_sharp/solution/assignment.csproj | 10 + .../templates/c_sharp/test/.gitignore | 484 ++++++++++++++++++ .../templates/c_sharp/test/BehaviorTest.cs | 88 ++++ .../templates/c_sharp/test/GlobalUsings.cs | 2 + .../templates/c_sharp/test/StructuralTest.cs | 134 +++++ .../templates/c_sharp/test/test.csproj | 25 + .../src/${packageNameFolder}/Policy.cs | 30 ++ .../programming/programming-exercise.model.ts | 1 + src/test/resources/config/application.yml | 2 + 31 files changed, 2262 insertions(+), 10 deletions(-) create mode 100644 src/main/resources/templates/aeolus/c_sharp/default.sh create mode 100644 src/main/resources/templates/aeolus/c_sharp/default.yaml create mode 100644 src/main/resources/templates/c_sharp/exercise/.gitignore create mode 100644 src/main/resources/templates/c_sharp/exercise/BubbleSort.cs create mode 100644 src/main/resources/templates/c_sharp/exercise/Client.cs create mode 100644 src/main/resources/templates/c_sharp/exercise/MergeSort.cs create mode 100644 src/main/resources/templates/c_sharp/exercise/assignment.csproj create mode 100644 src/main/resources/templates/c_sharp/readme create mode 100644 src/main/resources/templates/c_sharp/solution/.gitignore create mode 100644 src/main/resources/templates/c_sharp/solution/BubbleSort.cs create mode 100644 src/main/resources/templates/c_sharp/solution/Client.cs create mode 100644 src/main/resources/templates/c_sharp/solution/Context.cs create mode 100644 src/main/resources/templates/c_sharp/solution/ISortStrategy.cs create mode 100644 src/main/resources/templates/c_sharp/solution/MergeSort.cs create mode 100644 src/main/resources/templates/c_sharp/solution/Policy.cs create mode 100644 src/main/resources/templates/c_sharp/solution/assignment.csproj create mode 100644 src/main/resources/templates/c_sharp/test/.gitignore create mode 100644 src/main/resources/templates/c_sharp/test/BehaviorTest.cs create mode 100644 src/main/resources/templates/c_sharp/test/GlobalUsings.cs create mode 100644 src/main/resources/templates/c_sharp/test/StructuralTest.cs create mode 100644 src/main/resources/templates/c_sharp/test/test.csproj create mode 100644 src/main/resources/templates/java/solution/src/${packageNameFolder}/Policy.cs diff --git a/build.gradle b/build.gradle index 5f9283d1f9ea..f49a6d89e691 100644 --- a/build.gradle +++ b/build.gradle @@ -249,6 +249,7 @@ dependencies { implementation "de.jplag:c:${jplag_version}" implementation "de.jplag:cpp:${jplag_version}" + implementation "de.jplag:csharp:${jplag_version}" implementation "de.jplag:java:${jplag_version}" implementation "de.jplag:javascript:${jplag_version}" implementation "de.jplag:kotlin:${jplag_version}" diff --git a/src/main/java/de/tum/cit/aet/artemis/plagiarism/service/ProgrammingPlagiarismDetectionService.java b/src/main/java/de/tum/cit/aet/artemis/plagiarism/service/ProgrammingPlagiarismDetectionService.java index e0707ca62144..6760538078c7 100644 --- a/src/main/java/de/tum/cit/aet/artemis/plagiarism/service/ProgrammingPlagiarismDetectionService.java +++ b/src/main/java/de/tum/cit/aet/artemis/plagiarism/service/ProgrammingPlagiarismDetectionService.java @@ -31,6 +31,7 @@ import de.jplag.c.CLanguage; import de.jplag.clustering.ClusteringOptions; import de.jplag.cpp.CPPLanguage; +import de.jplag.csharp.CSharpLanguage; import de.jplag.exceptions.ExitException; import de.jplag.java.JavaLanguage; import de.jplag.javascript.JavaScriptLanguage; @@ -315,6 +316,7 @@ private Language getJPlagProgrammingLanguage(ProgrammingExercise programmingExer return switch (programmingExercise.getProgrammingLanguage()) { case C -> new CLanguage(); case C_PLUS_PLUS -> new CPPLanguage(); + case C_SHARP -> new CSharpLanguage(); case JAVA -> new JavaLanguage(); case JAVASCRIPT -> new JavaScriptLanguage(); case KOTLIN -> new KotlinLanguage(); @@ -323,7 +325,7 @@ private Language getJPlagProgrammingLanguage(ProgrammingExercise programmingExer case RUST -> new RustLanguage(); case SWIFT -> new SwiftLanguage(); case TYPESCRIPT -> new TypeScriptLanguage(); - case EMPTY, PHP, DART, HASKELL, ASSEMBLER, OCAML, C_SHARP, SQL, GO, MATLAB, BASH, VHDL, RUBY, POWERSHELL, ADA -> throw new BadRequestAlertException( + case EMPTY, PHP, DART, HASKELL, ASSEMBLER, OCAML, SQL, GO, MATLAB, BASH, VHDL, RUBY, POWERSHELL, ADA -> throw new BadRequestAlertException( "Programming language " + programmingExercise.getProgrammingLanguage() + " not supported for plagiarism check.", "ProgrammingExercise", "notSupported"); }; } diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/domain/ProgrammingLanguage.java b/src/main/java/de/tum/cit/aet/artemis/programming/domain/ProgrammingLanguage.java index 71f00210c2df..a2a11cfc36d8 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/domain/ProgrammingLanguage.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/domain/ProgrammingLanguage.java @@ -41,6 +41,7 @@ public enum ProgrammingLanguage { ASSEMBLER, C, C_PLUS_PLUS, + C_SHARP, HASKELL, JAVA, JAVASCRIPT, diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/TemplateUpgradePolicyService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/TemplateUpgradePolicyService.java index 07dc44fada0e..2ec466bb943c 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/TemplateUpgradePolicyService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/TemplateUpgradePolicyService.java @@ -32,9 +32,8 @@ public TemplateUpgradePolicyService(JavaTemplateUpgradeService javaRepositoryUpg public TemplateUpgradeService getUpgradeService(ProgrammingLanguage programmingLanguage) { return switch (programmingLanguage) { case JAVA -> javaRepositoryUpgradeService; - case KOTLIN, PYTHON, C, HASKELL, VHDL, ASSEMBLER, SWIFT, OCAML, EMPTY, RUST, JAVASCRIPT, R, C_PLUS_PLUS, TYPESCRIPT -> defaultRepositoryUpgradeService; - case C_SHARP, SQL, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> - throw new UnsupportedOperationException("Unsupported programming language: " + programmingLanguage); + case KOTLIN, PYTHON, C, HASKELL, VHDL, ASSEMBLER, SWIFT, OCAML, EMPTY, RUST, JAVASCRIPT, R, C_PLUS_PLUS, TYPESCRIPT, C_SHARP -> defaultRepositoryUpgradeService; + case SQL, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> throw new UnsupportedOperationException("Unsupported programming language: " + programmingLanguage); }; } } diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationService.java index ec8e2165c46a..6aaeb9602110 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationService.java @@ -219,9 +219,8 @@ enum RepositoryCheckoutPath implements CustomizableCheckoutPath { @Override public String forProgrammingLanguage(ProgrammingLanguage language) { return switch (language) { - case JAVA, PYTHON, C, HASKELL, KOTLIN, VHDL, ASSEMBLER, SWIFT, OCAML, EMPTY, RUST, JAVASCRIPT, R, C_PLUS_PLUS, TYPESCRIPT -> "assignment"; - case C_SHARP, SQL, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> - throw new UnsupportedOperationException("Unsupported programming language: " + language); + case JAVA, PYTHON, C, HASKELL, KOTLIN, VHDL, ASSEMBLER, SWIFT, OCAML, EMPTY, RUST, JAVASCRIPT, R, C_PLUS_PLUS, TYPESCRIPT, C_SHARP -> "assignment"; + case SQL, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> throw new UnsupportedOperationException("Unsupported programming language: " + language); }; } }, @@ -231,9 +230,8 @@ public String forProgrammingLanguage(ProgrammingLanguage language) { public String forProgrammingLanguage(ProgrammingLanguage language) { return switch (language) { case JAVA, PYTHON, HASKELL, KOTLIN, SWIFT, EMPTY, RUST, JAVASCRIPT, R, C_PLUS_PLUS, TYPESCRIPT -> ""; - case C, VHDL, ASSEMBLER, OCAML -> "tests"; - case C_SHARP, SQL, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> - throw new UnsupportedOperationException("Unsupported programming language: " + language); + case C, VHDL, ASSEMBLER, OCAML, C_SHARP -> "tests"; + case SQL, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> throw new UnsupportedOperationException("Unsupported programming language: " + language); }; } }, diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java index d86199310720..e0486750422f 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java @@ -4,6 +4,7 @@ import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.ASSEMBLER; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.C; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.C_PLUS_PLUS; +import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.C_SHARP; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.EMPTY; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.HASKELL; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.JAVA; @@ -45,6 +46,7 @@ public LocalCIProgrammingLanguageFeatureService() { programmingLanguageFeatures.put(ASSEMBLER, new ProgrammingLanguageFeature(ASSEMBLER, false, false, false, false, false, List.of(), false, true)); programmingLanguageFeatures.put(C, new ProgrammingLanguageFeature(C, false, true, true, false, false, List.of(FACT, GCC), false, true)); programmingLanguageFeatures.put(C_PLUS_PLUS, new ProgrammingLanguageFeature(C_PLUS_PLUS, false, false, true, false, false, List.of(), false, true)); + programmingLanguageFeatures.put(C_SHARP, new ProgrammingLanguageFeature(C_SHARP, false, false, true, false, false, List.of(), false, true)); programmingLanguageFeatures.put(HASKELL, new ProgrammingLanguageFeature(HASKELL, true, false, false, false, true, List.of(), false, true)); programmingLanguageFeatures.put(JAVA, new ProgrammingLanguageFeature(JAVA, true, true, true, true, false, List.of(PLAIN_GRADLE, GRADLE_GRADLE, PLAIN_MAVEN, MAVEN_MAVEN), false, true)); diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index e51e9f84e749..0d12c8e284f9 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -95,6 +95,8 @@ artemis: default: "ghcr.io/ls1intum/artemis-r-docker:v1.0.0" c_plus_plus: default: "ghcr.io/ls1intum/artemis-cpp-docker:v1.0.0" + c_sharp: + default: "ghcr.io/ls1intum/artemis-csharp-docker:v1.0.0" typescript: default: "ghcr.io/ls1intum/artemis-javascript-docker:v1.0.0" diff --git a/src/main/resources/templates/aeolus/c_sharp/default.sh b/src/main/resources/templates/aeolus/c_sharp/default.sh new file mode 100644 index 000000000000..3ffe2df48e1a --- /dev/null +++ b/src/main/resources/templates/aeolus/c_sharp/default.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -e +export AEOLUS_INITIAL_DIRECTORY=${PWD} +build () { + echo '⚙️ executing build' + dotnet build "./tests" +} + +test () { + echo '⚙️ executing test' + dotnet test --logger=junit "./tests" +} + +main () { + if [[ "${1}" == "aeolus_sourcing" ]]; then + return 0 # just source to use the methods in the subshell, no execution + fi + local _script_name + _script_name=${BASH_SOURCE[0]:-$0} + cd "${AEOLUS_INITIAL_DIRECTORY}" + bash -c "source ${_script_name} aeolus_sourcing; build" + cd "${AEOLUS_INITIAL_DIRECTORY}" + bash -c "source ${_script_name} aeolus_sourcing; test" +} + +main "${@}" diff --git a/src/main/resources/templates/aeolus/c_sharp/default.yaml b/src/main/resources/templates/aeolus/c_sharp/default.yaml new file mode 100644 index 000000000000..64ad8288e691 --- /dev/null +++ b/src/main/resources/templates/aeolus/c_sharp/default.yaml @@ -0,0 +1,13 @@ +api: v0.0.1 +metadata: + name: "C#" + id: c_sharp +actions: + - name: build + script: dotnet build "./tests" + - name: test + script: dotnet test --logger=junit "./tests" + results: + - name: NUnit Test Results + path: tests/TestResults/TestResults.xml + type: junit diff --git a/src/main/resources/templates/c_sharp/exercise/.gitignore b/src/main/resources/templates/c_sharp/exercise/.gitignore new file mode 100644 index 000000000000..104b54414e4d --- /dev/null +++ b/src/main/resources/templates/c_sharp/exercise/.gitignore @@ -0,0 +1,484 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from `dotnet new gitignore` + +# dotenv files +.env + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET +project.lock.json +project.fragment.lock.json +artifacts/ + +# Tye +.tye/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml +.idea + +## +## Visual studio for Mac +## + + +# globs +Makefile.in +*.userprefs +*.usertasks +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.tar.gz +tarballs/ +test-results/ + +# Mac bundle stuff +*.dmg +*.app + +# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# Vim temporary swap files +*.swp diff --git a/src/main/resources/templates/c_sharp/exercise/BubbleSort.cs b/src/main/resources/templates/c_sharp/exercise/BubbleSort.cs new file mode 100644 index 000000000000..3813e63ea4d4 --- /dev/null +++ b/src/main/resources/templates/c_sharp/exercise/BubbleSort.cs @@ -0,0 +1,13 @@ +namespace assignment; + +public class BubbleSort +{ + /// + /// Sorts dates with BubbleSort. + /// + /// the List of Dates to be sorted + public void PerformSort(List dates) + { + //TODO: implement + } +} \ No newline at end of file diff --git a/src/main/resources/templates/c_sharp/exercise/Client.cs b/src/main/resources/templates/c_sharp/exercise/Client.cs new file mode 100644 index 000000000000..78002ed11a6b --- /dev/null +++ b/src/main/resources/templates/c_sharp/exercise/Client.cs @@ -0,0 +1,90 @@ +namespace assignment; + +public static class Client +{ + // TODO: Implement BubbleSort + // TODO: Implement MergeSort + + // TODO: Create a ISortStrategy interface according to the UML class diagram + // TODO: Make the sorting algorithms implement this interface. + + // TODO: Create and implement a Context class according to the UML class diagram + // TODO: Create and implement a Policy class as described in the problem statement + + private const int ITERATIONS = 10; + + private const int RANDOM_FLOOR = 5; + + private const int RANDOM_CEILING = 15; + + private static readonly Random random = new(); + + /// + /// Main method. + /// Add code to demonstrate your implementation here. + /// + public static void Main() + { + // TODO: Init Context and Policy + + // Run multiple times to simulate different sorting strategies + for (int i = 0; i < ITERATIONS; i++) + { + List dates = CreateRandomDatesList(); + + // TODO: Configure context + + Console.Write("Unsorted Array of course dates = "); + PrintDateList(dates); + + // TODO: Sort dates + + Console.Write("Sorted Array of course dates = "); + PrintDateList(dates); + } + } + + /// + /// Generates a List of random Date objects with random List size between + /// RANDOM_FLOOR and RANDOM_CEILING. + /// + /// A List of random Date objects. + private static List CreateRandomDatesList() + { + int listLength = random.Next(RANDOM_FLOOR, RANDOM_CEILING); + List list = []; + + DateTime lowestDate = new(2024, 09, 15); + DateTime highestDate = new(2025, 01, 15); + + for (int i = 0; i < listLength; i++) + { + DateTime randomDate = RandomDateWithin(lowestDate, highestDate); + list.Add(randomDate); + } + return list; + } + + /// + /// Creates a random Date within the given range. + /// + /// the lower bound + /// the upper bound + /// A random DateTime within the given range. + private static DateTime RandomDateWithin(DateTime low, DateTime high) + { + long randomTick = random.NextInt64(low.Ticks, high.Ticks); + return new DateTime(randomTick); + } + + /// + /// Prints out the given Array of Date objects. + /// + /// list of the dates to print + private static void PrintDateList(List list) + { + var formattedDates = from date in list select date.ToString("O"); + var joinedDates = string.Join(", ", formattedDates); + Console.WriteLine($"[{joinedDates}]"); + } +} diff --git a/src/main/resources/templates/c_sharp/exercise/MergeSort.cs b/src/main/resources/templates/c_sharp/exercise/MergeSort.cs new file mode 100644 index 000000000000..c15e070fc2a5 --- /dev/null +++ b/src/main/resources/templates/c_sharp/exercise/MergeSort.cs @@ -0,0 +1,13 @@ +namespace assignment; + +public class MergeSort +{ + /// + /// Sorts dates with MergeSort. + /// + /// the List of Dates to be sorted + public void PerformSort(List input) + { + // TODO: implement + } +} diff --git a/src/main/resources/templates/c_sharp/exercise/assignment.csproj b/src/main/resources/templates/c_sharp/exercise/assignment.csproj new file mode 100644 index 000000000000..2150e3797ba5 --- /dev/null +++ b/src/main/resources/templates/c_sharp/exercise/assignment.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/src/main/resources/templates/c_sharp/readme b/src/main/resources/templates/c_sharp/readme new file mode 100644 index 000000000000..1c594e4ca864 --- /dev/null +++ b/src/main/resources/templates/c_sharp/readme @@ -0,0 +1,91 @@ +# Sorting with the Strategy Pattern + +In this exercise, we want to implement sorting algorithms and choose them based on runtime specific variables. + +### Part 1: Sorting + +First, we need to implement two sorting algorithms, in this case `MergeSort` and `BubbleSort`. + +**You have the following tasks:** + +1. [task][Implement Bubble Sort](TestBubbleSort) +Implement the method `PerformSort(List)` in the class `BubbleSort`. Make sure to follow the Bubble Sort algorithm exactly. + +2. [task][Implement Merge Sort](TestMergeSort) +Implement the method `PerformSort(List)` in the class `MergeSort`. Make sure to follow the Merge Sort algorithm exactly. + +### Part 2: Strategy Pattern + +We want the application to apply different algorithms for sorting a `List` of `DateTime` objects. +Use the strategy pattern to select the right sorting algorithm at runtime. +Implement public C# properties for the UML attributes and associations. + +**You have the following tasks:** + +1. [task][ISortStrategy Interface](TestISortStrategyType,TestISortStrategyMethods,TestMergeSortInterface,TestBubbleSortInterface) +Create a `ISortStrategy` interface and adjust the sorting algorithms so that they implement this interface. + +2. [task][Context Class](TestContextType,TestContextPropertyDates,TestContextPropertySortAlgorithm,TestContextMethods) +Create and implement a `Context` class following the below class diagram + +3. [task][Context Policy](TestPolicyType,TestPolicyConstructor,TestPolicyPropertyContext,TestPolicyMethods) +Create and implement a `Policy` class following the below class diagram with a simple configuration mechanism: + + 1. [task][Select MergeSort](TestUseMergeSortForBigList) + Select `MergeSort` when the List has more than 10 dates. + + 2. [task][Select BubbleSort](TestUseBubbleSortForSmallList) + Select `BubbleSort` when the List has less or equal 10 dates. + +4. Complete the `Client` class which demonstrates switching between two strategies at runtime. + +@startuml + +class Client { +} + +class Policy ##testsColor(TestPolicyType) { ++Policy() <> ++Configure() +} + +class Context ##testsColor(TestContextType) { +-dates: List ++Sort() +} + +interface ISortStrategy ##testsColor(TestISortStrategyType) { ++PerformSort(List) +} + +class BubbleSort { ++PerformSort(List) +} + +class MergeSort { ++PerformSort(List) +} + +MergeSort -up-|> ISortStrategy #testsColor(TestMergeSortInterface) +BubbleSort -up-|> ISortStrategy #testsColor(TestBubbleSortInterface) +Policy -right-> Context #testsColor(TestPolicyPropertyContext): context +Context -right-> ISortStrategy #testsColor(TestContextPropertySortAlgorithm): sortAlgorithm +Client .down.> Policy +Client .down.> Context + +hide empty fields +hide empty methods + +@enduml + + +### Part 3: Optional Challenges + +(These are not tested) + +1. Create a new class `QuickSort` that implements `SortStrategy` and implement the Quick Sort algorithm. + +2. Make the method `PerformSort(List)` generic, so that other objects can also be sorted by the same method. +**Hint:** Have a look at C# Generics and the interface `IComparable`. + +3. Think about a useful decision in `Policy` when to use the new `QuickSort` algorithm. diff --git a/src/main/resources/templates/c_sharp/solution/.gitignore b/src/main/resources/templates/c_sharp/solution/.gitignore new file mode 100644 index 000000000000..104b54414e4d --- /dev/null +++ b/src/main/resources/templates/c_sharp/solution/.gitignore @@ -0,0 +1,484 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from `dotnet new gitignore` + +# dotenv files +.env + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET +project.lock.json +project.fragment.lock.json +artifacts/ + +# Tye +.tye/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml +.idea + +## +## Visual studio for Mac +## + + +# globs +Makefile.in +*.userprefs +*.usertasks +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.tar.gz +tarballs/ +test-results/ + +# Mac bundle stuff +*.dmg +*.app + +# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# Vim temporary swap files +*.swp diff --git a/src/main/resources/templates/c_sharp/solution/BubbleSort.cs b/src/main/resources/templates/c_sharp/solution/BubbleSort.cs new file mode 100644 index 000000000000..dbd6eea52da4 --- /dev/null +++ b/src/main/resources/templates/c_sharp/solution/BubbleSort.cs @@ -0,0 +1,22 @@ +namespace assignment; + +public class BubbleSort : ISortStrategy +{ + /// + /// Sorts dates with BubbleSort. + /// + /// the List of Dates to be sorted + public void PerformSort(List dates) + { + for (int i = dates.Count - 1; i >= 0; i--) + { + for (int j = 0; j < i; j++) + { + if (dates[j] > dates[j + 1]) + { + (dates[j + 1], dates[j]) = (dates[j], dates[j + 1]); + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/templates/c_sharp/solution/Client.cs b/src/main/resources/templates/c_sharp/solution/Client.cs new file mode 100644 index 000000000000..06f35877205b --- /dev/null +++ b/src/main/resources/templates/c_sharp/solution/Client.cs @@ -0,0 +1,85 @@ +namespace assignment; + +public static class Client +{ + + private const int ITERATIONS = 10; + + private const int RANDOM_FLOOR = 5; + + private const int RANDOM_CEILING = 15; + + private static readonly Random random = new(); + + /// + /// Main method. + /// Add code to demonstrate your implementation here. + /// + public static void Main() + { + // Init Context and Policy + Context sortingContext = new(); + Policy policy = new(sortingContext); + + // Run multiple times to simulate different sorting strategies + for (int i = 0; i < ITERATIONS; i++) + { + List dates = CreateRandomDatesList(); + + sortingContext.Dates = dates; + policy.Configure(); + + Console.Write("Unsorted Array of course dates = "); + PrintDateList(dates); + + sortingContext.Sort(); + + Console.Write("Sorted Array of course dates = "); + PrintDateList(dates); + } + } + + /// + /// Generates a List of random Date objects with random List size between + /// RANDOM_FLOOR and RANDOM_CEILING. + /// + /// A List of random Date objects. + private static List CreateRandomDatesList() + { + int listLength = random.Next(RANDOM_FLOOR, RANDOM_CEILING); + List list = []; + + DateTime lowestDate = new(2024, 09, 15); + DateTime highestDate = new(2025, 01, 15); + + for (int i = 0; i < listLength; i++) + { + DateTime randomDate = RandomDateWithin(lowestDate, highestDate); + list.Add(randomDate); + } + return list; + } + + /// + /// Creates a random Date within the given range. + /// + /// the lower bound + /// the upper bound + /// A random DateTime within the given range. + private static DateTime RandomDateWithin(DateTime low, DateTime high) + { + long randomTick = random.NextInt64(low.Ticks, high.Ticks); + return new DateTime(randomTick); + } + + /// + /// Prints out the given Array of Date objects. + /// + /// list of the dates to print + private static void PrintDateList(List list) + { + var formattedDates = from date in list select date.ToString("O"); + var joinedDates = string.Join(", ", formattedDates); + Console.WriteLine($"[{joinedDates}]"); + } +} diff --git a/src/main/resources/templates/c_sharp/solution/Context.cs b/src/main/resources/templates/c_sharp/solution/Context.cs new file mode 100644 index 000000000000..2b00b3795283 --- /dev/null +++ b/src/main/resources/templates/c_sharp/solution/Context.cs @@ -0,0 +1,23 @@ +namespace assignment; + +public class Context +{ + private ISortStrategy? sortAlgorithm; + private List? dates; + + public ISortStrategy? SortAlgorithm { get => sortAlgorithm; set => sortAlgorithm = value; } + public List? Dates { get => dates; set => dates = value; } + + /// + /// Runs the configured sort algorithm. + /// + public void Sort() + { + if (sortAlgorithm == null || dates == null) + { + throw new InvalidOperationException("SortAlgorithm and Dates have to be set before Sort() can be called"); + } + + sortAlgorithm.PerformSort(dates); + } +} diff --git a/src/main/resources/templates/c_sharp/solution/ISortStrategy.cs b/src/main/resources/templates/c_sharp/solution/ISortStrategy.cs new file mode 100644 index 000000000000..14853eb114c2 --- /dev/null +++ b/src/main/resources/templates/c_sharp/solution/ISortStrategy.cs @@ -0,0 +1,10 @@ +namespace assignment; + +public interface ISortStrategy +{ + /// + /// Sorts a list of Dates. + /// + /// the List of Dates to be sorted + void PerformSort(List dates); +} \ No newline at end of file diff --git a/src/main/resources/templates/c_sharp/solution/MergeSort.cs b/src/main/resources/templates/c_sharp/solution/MergeSort.cs new file mode 100644 index 000000000000..b145cdb6c1ea --- /dev/null +++ b/src/main/resources/templates/c_sharp/solution/MergeSort.cs @@ -0,0 +1,70 @@ +namespace assignment; + +public class MergeSort : ISortStrategy +{ + + /// + /// Wrapper method for the real MergeSort algorithm. + /// + /// the List of Dates to be sorted + public void PerformSort(List input) + { + Mergesort(input, 0, input.Count - 1); + } + + /// + /// Recursive merge sort method + /// + private void Mergesort(List input, int low, int high) + { + if (high - low < 1) + { + return; + } + + int mid = (low + high) / 2; + + Mergesort(input, low, mid); + Mergesort(input, mid + 1, high); + Merge(input, low, mid, high); + } + + /// + /// Merge method + /// + private void Merge(List input, int low, int middle, int high) + { + DateTime[] temp = new DateTime[high - low + 1]; + + int leftIndex = low; + int rightIndex = middle + 1; + int wholeIndex = 0; + + while (leftIndex <= middle && rightIndex <= high) + { + if (input[leftIndex] <= input[rightIndex]) + { + temp[wholeIndex] = input[leftIndex++]; + } + else + { + temp[wholeIndex] = input[rightIndex++]; + } + wholeIndex++; + } + + while (leftIndex <= middle) + { + temp[wholeIndex++] = input[leftIndex++]; + } + while (rightIndex <= high) + { + temp[wholeIndex++] = input[rightIndex++]; + } + + for (wholeIndex = 0; wholeIndex < temp.Length; wholeIndex++) + { + input[wholeIndex + low] = temp[wholeIndex]; + } + } +} diff --git a/src/main/resources/templates/c_sharp/solution/Policy.cs b/src/main/resources/templates/c_sharp/solution/Policy.cs new file mode 100644 index 000000000000..fd769b0ca0b4 --- /dev/null +++ b/src/main/resources/templates/c_sharp/solution/Policy.cs @@ -0,0 +1,37 @@ +namespace assignment; + +public class Policy +{ + private const int DATES_SIZE_THRESHOLD = 10; + + private Context context; + + public Policy(Context context) + { + this.context = context; + } + + public Context Context { get => context; set => context = value; } + + /// + /// Chooses a strategy depending on the number of date objects. + /// + public void Configure() + { + if (this.context.Dates == null) + { + throw new InvalidOperationException("Dates of Context has to be set before Configure() can be called"); + } + + if (this.context.Dates.Count > DATES_SIZE_THRESHOLD) + { + Console.WriteLine("More than " + DATES_SIZE_THRESHOLD + " dates, choosing merge sort!"); + this.context.SortAlgorithm = new MergeSort(); + } + else + { + Console.WriteLine("Less or equal than " + DATES_SIZE_THRESHOLD + " dates. choosing quick sort!"); + this.context.SortAlgorithm = new BubbleSort(); + } + } +} diff --git a/src/main/resources/templates/c_sharp/solution/assignment.csproj b/src/main/resources/templates/c_sharp/solution/assignment.csproj new file mode 100644 index 000000000000..2150e3797ba5 --- /dev/null +++ b/src/main/resources/templates/c_sharp/solution/assignment.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/src/main/resources/templates/c_sharp/test/.gitignore b/src/main/resources/templates/c_sharp/test/.gitignore new file mode 100644 index 000000000000..104b54414e4d --- /dev/null +++ b/src/main/resources/templates/c_sharp/test/.gitignore @@ -0,0 +1,484 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from `dotnet new gitignore` + +# dotenv files +.env + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET +project.lock.json +project.fragment.lock.json +artifacts/ + +# Tye +.tye/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml +.idea + +## +## Visual studio for Mac +## + + +# globs +Makefile.in +*.userprefs +*.usertasks +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.tar.gz +tarballs/ +test-results/ + +# Mac bundle stuff +*.dmg +*.app + +# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# Vim temporary swap files +*.swp diff --git a/src/main/resources/templates/c_sharp/test/BehaviorTest.cs b/src/main/resources/templates/c_sharp/test/BehaviorTest.cs new file mode 100644 index 000000000000..1d914e2111b6 --- /dev/null +++ b/src/main/resources/templates/c_sharp/test/BehaviorTest.cs @@ -0,0 +1,88 @@ +using System.Reflection; + +namespace test; + +public class BehaviorTest +{ + private readonly Assembly assignment = Assembly.Load("assignment"); + private List dates; + + + [SetUp] + public void Setup() + { + dates = [ + new(2018, 11, 08), + new(2017, 04, 15), + new(2016, 02, 15), + new(2017, 09, 15), + ]; + } + + [Test, Timeout(1000)] + public void TestBubbleSort() + { + BubbleSort bubbleSort = new(); + + bubbleSort.PerformSort(dates); + + Assert.That(dates, Is.Ordered); + } + + [Test, Timeout(1000)] + public void TestMergeSort() + { + MergeSort mergeSort = new(); + + mergeSort.PerformSort(dates); + + Assert.That(dates, Is.Ordered); + } + + [Test, Timeout(1000)] + public void TestUseMergeSortForBigList() + { + List bigList = Enumerable.Repeat(new DateTime(), 11).ToList(); + + object? sortStrategy = ConfigurePolicyAndContext(bigList); + + Assert.That(sortStrategy, Is.InstanceOf()); + } + + [Test, Timeout(1000)] + public void TestUseBubbleSortForSmallList() + { + List smallList = Enumerable.Repeat(new DateTime(), 3).ToList(); + + object? sortStrategy = ConfigurePolicyAndContext(smallList); + + Assert.That(sortStrategy, Is.InstanceOf()); + } + + private object? ConfigurePolicyAndContext(List dates) + { + Type? contextType = assignment.GetType("assignment.Context"); + Assert.That(contextType, Is.Not.Null); + object? contextInstance = Activator.CreateInstance(contextType); + Assert.That(contextInstance, Is.Not.Null); + + PropertyInfo? datesProperty = contextType.GetProperty("Dates"); + Assert.That(datesProperty, Is.Not.Null); + datesProperty.SetValue(contextInstance, dates); + + Type? policyType = assignment.GetType("assignment.Policy"); + Assert.That(policyType, Is.Not.Null); + object? policyInstance = Activator.CreateInstance(policyType, contextInstance); + Assert.That(policyInstance, Is.Not.Null); + + MethodInfo? configureMethod = policyType.GetMethod("Configure"); + Assert.That(configureMethod, Is.Not.Null); + configureMethod.Invoke(policyInstance, []); + + PropertyInfo? sortAlgorithmProperty = contextType.GetProperty("SortAlgorithm"); + Assert.That(sortAlgorithmProperty, Is.Not.Null); + object? sortAlgorithm = sortAlgorithmProperty.GetValue(contextInstance); + + return sortAlgorithm; + } +} \ No newline at end of file diff --git a/src/main/resources/templates/c_sharp/test/GlobalUsings.cs b/src/main/resources/templates/c_sharp/test/GlobalUsings.cs new file mode 100644 index 000000000000..469dcd6d648d --- /dev/null +++ b/src/main/resources/templates/c_sharp/test/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using NUnit.Framework; +global using assignment; diff --git a/src/main/resources/templates/c_sharp/test/StructuralTest.cs b/src/main/resources/templates/c_sharp/test/StructuralTest.cs new file mode 100644 index 000000000000..2ebebcfc1a64 --- /dev/null +++ b/src/main/resources/templates/c_sharp/test/StructuralTest.cs @@ -0,0 +1,134 @@ +using System.Reflection; + +namespace test; + +public class StructuralTest +{ + private readonly Assembly assignment = Assembly.Load("assignment"); + + [Test] + public void TestISortStrategyType() + { + Type? type = assignment.GetType("assignment.ISortStrategy"); + + Assert.That(type, Is.Not.Null); + Assert.That(type.IsInterface, Is.True); + } + + [Test] + public void TestISortStrategyMethods() + { + Type? type = assignment.GetType("assignment.ISortStrategy"); + MethodInfo? method = type?.GetMethod("PerformSort", BindingFlags.Instance | BindingFlags.Public, [typeof(List)]); + + Assert.That(method, Is.Not.Null); + Assert.That(method.ReturnType, Is.EqualTo(typeof(void))); + } + + [Test] + public void TestMergeSortInterface() + { + Type? type = assignment.GetType("assignment.MergeSort"); + Type? iface = type?.GetInterface("assignment.ISortStrategy"); + + Assert.That(iface, Is.Not.Null); + } + + [Test] + public void TestBubbleSortInterface() + { + Type? type = assignment.GetType("assignment.BubbleSort"); + Type? iface = type?.GetInterface("assignment.ISortStrategy"); + + Assert.That(iface, Is.Not.Null); + } + + [Test] + public void TestContextType() + { + Type? type = assignment.GetType("assignment.Context"); + + Assert.That(type, Is.Not.Null); + Assert.Multiple(() => + { + Assert.That(type.IsClass, Is.True); + Assert.That(type.IsAbstract, Is.False); + }); + } + + [Test] + public void TestContextPropertyDates() + { + Type? type = assignment.GetType("assignment.Context"); + PropertyInfo? datesProperty = type?.GetProperty("Dates", BindingFlags.Instance | BindingFlags.Public); + + Assert.That(datesProperty, Is.Not.Null); + Assert.That(datesProperty.PropertyType, Is.EqualTo(typeof(List))); + } + + [Test] + public void TestContextPropertySortAlgorithm() + { + Type? type = assignment.GetType("assignment.Context"); + Type? sortStrategyType = assignment.GetType("assignment.ISortStrategy"); + PropertyInfo? sortAlgorithmProperty = type?.GetProperty("SortAlgorithm", BindingFlags.Instance | BindingFlags.Public); + + Assert.That(sortAlgorithmProperty, Is.Not.Null); + Assert.That(sortAlgorithmProperty.PropertyType, Is.EqualTo(sortStrategyType)); + } + + [Test] + public void TestContextMethods() + { + Type? type = assignment.GetType("assignment.Context"); + MethodInfo? method = type?.GetMethod("Sort", BindingFlags.Instance | BindingFlags.Public, []); + + Assert.That(method, Is.Not.Null); + Assert.That(method.ReturnType, Is.EqualTo(typeof(void))); + } + + [Test] + public void TestPolicyType() + { + Type? type = assignment.GetType("assignment.Policy"); + + Assert.That(type, Is.Not.Null); + Assert.Multiple(() => + { + Assert.That(type.IsClass, Is.True); + Assert.That(type.IsAbstract, Is.False); + }); + } + + [Test] + public void TestPolicyPropertyContext() + { + Type? type = assignment.GetType("assignment.Policy"); + Type? contextType = assignment.GetType("assignment.Context"); + PropertyInfo? contextProperty = type?.GetProperty("Context", BindingFlags.Instance | BindingFlags.Public); + + Assert.That(contextProperty, Is.Not.Null); + Assert.That(contextProperty.PropertyType, Is.EqualTo(contextType)); + } + + [Test] + public void TestPolicyMethods() + { + Type? type = assignment.GetType("assignment.Policy"); + MethodInfo? method = type?.GetMethod("Configure", BindingFlags.Instance | BindingFlags.Public, []); + + Assert.That(method, Is.Not.Null); + Assert.That(method.ReturnType, Is.EqualTo(typeof(void))); + } + + [Test] + public void TestPolicyConstructor() + { + Type? type = assignment.GetType("assignment.Policy"); + Type? contextType = assignment.GetType("assignment.Context"); + Assert.That(contextType, Is.Not.Null); + + ConstructorInfo? constructor = type?.GetConstructor(BindingFlags.Instance | BindingFlags.Public, [contextType]); + Assert.That(constructor, Is.Not.Null); + } +} diff --git a/src/main/resources/templates/c_sharp/test/test.csproj b/src/main/resources/templates/c_sharp/test/test.csproj new file mode 100644 index 000000000000..7951527ee35a --- /dev/null +++ b/src/main/resources/templates/c_sharp/test/test.csproj @@ -0,0 +1,25 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + diff --git a/src/main/resources/templates/java/solution/src/${packageNameFolder}/Policy.cs b/src/main/resources/templates/java/solution/src/${packageNameFolder}/Policy.cs new file mode 100644 index 000000000000..d9f079dd9450 --- /dev/null +++ b/src/main/resources/templates/java/solution/src/${packageNameFolder}/Policy.cs @@ -0,0 +1,30 @@ +namespace assignment; + +public class Policy { + + /** + * @oracleIgnore + */ + private static final int DATES_SIZE_THRESHOLD = 10; + + private Context context; + + public Policy(Context context) { + this.context = context; + } + + /** + * Chooses a strategy depending on the number of date objects. + */ + public void configure() { + if (this.context.getDates().size() > DATES_SIZE_THRESHOLD) { + System.out.println("More than " + DATES_SIZE_THRESHOLD + + " dates, choosing merge sort!"); + this.context.setSortAlgorithm(new MergeSort()); + } else { + System.out.println("Less or equal than " + DATES_SIZE_THRESHOLD + + " dates. choosing quick sort!"); + this.context.setSortAlgorithm(new BubbleSort()); + } + } +} diff --git a/src/main/webapp/app/entities/programming/programming-exercise.model.ts b/src/main/webapp/app/entities/programming/programming-exercise.model.ts index f00dc636caca..543d7f138bab 100644 --- a/src/main/webapp/app/entities/programming/programming-exercise.model.ts +++ b/src/main/webapp/app/entities/programming/programming-exercise.model.ts @@ -17,6 +17,7 @@ export enum ProgrammingLanguage { ASSEMBLER = 'ASSEMBLER', C = 'C', C_PLUS_PLUS = 'C_PLUS_PLUS', + C_SHARP = 'C_SHARP', HASKELL = 'HASKELL', JAVA = 'JAVA', JAVASCRIPT = 'JAVASCRIPT', diff --git a/src/test/resources/config/application.yml b/src/test/resources/config/application.yml index 037112ce70fb..337990a0ae2c 100644 --- a/src/test/resources/config/application.yml +++ b/src/test/resources/config/application.yml @@ -74,6 +74,8 @@ artemis: default: "~~invalid~~" c_plus_plus: default: "~~invalid~~" + c_sharp: + default: "~~invalid~~" typescript: default: "~~invalid~~" build-agent: