diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..212ca32 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,53 @@ +FROM ubuntu:24.04 + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + sudo && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* && \ + echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + curl \ + libffi-dev \ + libyaml-dev \ + zlib1g-dev && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +USER ubuntu + +ENV PATH=/home/ubuntu/.rbenv/bin:/home/ubuntu/.rbenv/shims:${PATH} +RUN mkdir -p /home/ubuntu/.rbenv && \ + curl -fsSL https://github.com/rbenv/rbenv/archive/refs/tags/v1.3.2.tar.gz | \ + tar -xz --strip-components=1 -C /home/ubuntu/.rbenv && \ + mkdir -p /home/ubuntu/.rbenv/plugins/ruby-build && \ + curl -fsSL https://github.com/rbenv/ruby-build/archive/refs/tags/v20251203.tar.gz | \ + tar -xz --strip-components=1 -C /home/ubuntu/.rbenv/plugins/ruby-build && \ + rbenv install 2.7.8 && \ + /home/ubuntu/.rbenv/versions/2.7.8/bin/gem install \ + ceedling -v 0.31.0 && \ + rbenv install 3.4.7 && \ + /home/ubuntu/.rbenv/versions/3.4.7/bin/gem install \ + ceedling -v 1.0.1 + +USER root + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + gdb \ + git \ + npm \ + neovim \ + ssh && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /home/ubuntu + +CMD ["/bin/bash"] diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..c538a44 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,15 @@ +{ + "name": "ruby-ceedling", + "build": { + "dockerfile": "Dockerfile" + }, + "remoteUser": "ubuntu", + "customizations": { + "vscode": { + "extensions": [ + "hbenl.vscode-test-explorer", + "ms-vscode.cpptools" + ] + } + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index a508d37..dee74e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +## [1.13.0] - 2025-12-17 + +### Added + +* Add support for ruby `#{ENV['FOO']}` syntax. +* Add support for Ceedling 1.0+ `report_tests_log_factory` plugin with CppUnit format. +* Add `ceedlingExplorer.debugTestExecutablePath` command that returns the full path to test executable. +* Add `isCeedling1Plus()` helper method for reliable Ceedling 1.0+ detection using plugin configuration. +* Add configuration documentation for both Ceedling versions in README. + +### Fixed + +* Fix compatibility with Ceedling 1.0+ (addresses issues #137 and #145). +* Fix debug executable path detection for Ceedling 1.0+ by checking for `report_tests_log_factory` plugin instead of relying on version string parsing. +* Ensure test executables in subdirectories (e.g., `test_name/test_name.out`) are correctly located for debugging. + ## [1.12.0] - 2024-01-02 ### Added @@ -182,7 +198,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * Initial features -[Unreleased]: https://github.com/numaru/vscode-ceedling-test-adapter/compare/v1.12.0...develop +[Unreleased]: https://github.com/numaru/vscode-ceedling-test-adapter/compare/v1.13.0...develop +[1.13.0]: https://github.com/numaru/vscode-ceedling-test-adapter/compare/v1.12.0...v1.13.0 [1.12.0]: https://github.com/numaru/vscode-ceedling-test-adapter/compare/v1.11.0...v1.12.0 [1.11.0]: https://github.com/numaru/vscode-ceedling-test-adapter/compare/v1.10.1...v1.11.0 [1.10.1]: https://github.com/numaru/vscode-ceedling-test-adapter/compare/v1.10.0...v1.10.1 diff --git a/README.md b/README.md index 9571468..d5456b1 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,9 @@ Run your [Ceedling](https://github.com/ThrowTheSwitch/Ceedling) tests using the * Open the workspace or folder containing your Ceedling project * Configure your `project.yml` path in the VS Code's settings if required [see below](#options) * Configure the shell path where Ceedling is installed in the VS Code's settings if required (It might be required on Windows) [see below](#options) -* Enable the `xml_tests_report` Ceedling plugin in your `project.yml` [see the Ceedling doc](https://github.com/ThrowTheSwitch/Ceedling/blob/master/docs/CeedlingPacket.md#tool-element-runtime-substitution-notational-substitution) +* Enable the appropriate Ceedling XML report plugin in your `project.yml`: + * **Ceedling 0.31.x**: Enable the `xml_tests_report` plugin [see the Ceedling doc](https://github.com/ThrowTheSwitch/Ceedling/blob/master/docs/CeedlingPacket.md#tool-element-runtime-substitution-notational-substitution) + * **Ceedling 1.0+**: Enable the `report_tests_log_factory` plugin with `cppunit` report format (see [Configuration Examples](#ceedling-plugin-configuration)) * Open the Test view * Run your tests using the ![Run](img/run.png) icons in the Test Explorer or the CodeLenses in your test file @@ -41,6 +43,7 @@ Property | Description `ceedlingExplorer.testCaseMacroAliases` | An array of aliases for the `TEST_CASE` macro. By default it is `["TEST_CASE"]` `ceedlingExplorer.testRangeMacroAliases`| An array of aliases for the `TEST_RANGE` macro. By default it is `["TEST_RANGE"]` `ceedlingExplorer.ansiEscapeSequencesRemoved`| Should the ansi escape sequences be removed from ceedling stdout and stderr. By default it is `true` +`ceedlingExplorer.evalRubyInStrings`| Evaluate the #{ruby_code} in the string using the ruby cli. By default it is `false`
### Problem matching @@ -92,6 +95,41 @@ Example pattern object (GCC compiler warnings): } ``` +### Ceedling Plugin Configuration + +This extension supports both Ceedling 0.31.x and Ceedling 1.0+ by accepting either the legacy `xml_tests_report` plugin or the new `report_tests_log_factory` plugin with CppUnit format. + +#### Ceedling 0.31.x Configuration + +```yaml +:plugins: + :enabled: + - xml_tests_report + +# Optional: customize report filename +:xml_tests_report: + :artifact_filename: report.xml # default +``` + +#### Ceedling 1.0+ Configuration + +```yaml +:plugins: + :enabled: + - report_tests_log_factory + +:report_tests_log_factory: + :reports: + - cppunit # Required for Test Explorer + +# Optional: customize report filename +:report_tests_log_factory: + :cppunit: + :filename: cppunit_tests_report.xml # default +``` + +**Note**: The extension requires the **CppUnit XML format** specifically. While `report_tests_log_factory` can generate multiple report formats (JUnit, JSON, HTML), only the CppUnit format is compatible with this extension. + ## Commands The following commands are available in VS Code's command palette, use the ID to add them to your keyboard shortcuts: diff --git a/package-lock.json b/package-lock.json index 6345ed3..d33706d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-ceedling-test-adapter", - "version": "1.12.0", + "version": "1.13.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "vscode-ceedling-test-adapter", - "version": "1.12.0", + "version": "1.13.0", "license": "MIT", "dependencies": { "@types/js-yaml": "^3.12.0", @@ -28,7 +28,7 @@ "@types/vscode": "^1.71.0", "@vscode/test-electron": "^2.3.8", "@vscode/vsce": "^2.22.0", - "esbuild": "^0.19.11", + "esbuild": "^0.27.2", "glob": "^7.1.6", "mocha": "^10.0.0", "typescript": "^4.6.3" @@ -38,9 +38,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz", - "integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", "cpu": [ "ppc64" ], @@ -50,13 +50,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz", - "integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", "cpu": [ "arm" ], @@ -66,13 +66,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz", - "integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", "cpu": [ "arm64" ], @@ -82,13 +82,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz", - "integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", "cpu": [ "x64" ], @@ -98,13 +98,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz", - "integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", "cpu": [ "arm64" ], @@ -114,13 +114,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz", - "integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", "cpu": [ "x64" ], @@ -130,13 +130,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz", - "integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", "cpu": [ "arm64" ], @@ -146,13 +146,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz", - "integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", "cpu": [ "x64" ], @@ -162,13 +162,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz", - "integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", "cpu": [ "arm" ], @@ -178,13 +178,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz", - "integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", "cpu": [ "arm64" ], @@ -194,13 +194,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz", - "integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", "cpu": [ "ia32" ], @@ -210,13 +210,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz", - "integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", "cpu": [ "loong64" ], @@ -226,13 +226,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz", - "integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", "cpu": [ "mips64el" ], @@ -242,13 +242,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz", - "integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", "cpu": [ "ppc64" ], @@ -258,13 +258,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz", - "integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", "cpu": [ "riscv64" ], @@ -274,13 +274,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz", - "integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", "cpu": [ "s390x" ], @@ -290,13 +290,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz", - "integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", "cpu": [ "x64" ], @@ -306,13 +306,29 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz", - "integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", "cpu": [ "x64" ], @@ -322,13 +338,29 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz", - "integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", "cpu": [ "x64" ], @@ -338,13 +370,29 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz", - "integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", "cpu": [ "x64" ], @@ -354,13 +402,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz", - "integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", "cpu": [ "arm64" ], @@ -370,13 +418,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz", - "integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", "cpu": [ "ia32" ], @@ -386,13 +434,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz", - "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", "cpu": [ "x64" ], @@ -402,7 +450,7 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@tootallnate/once": { @@ -546,9 +594,9 @@ } }, "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, "engines": { "node": ">=6" @@ -680,9 +728,9 @@ "dev": true }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "dependencies": { "balanced-match": "^1.0.0", @@ -690,12 +738,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -929,12 +977,12 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1008,9 +1056,9 @@ } }, "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "engines": { "node": ">=0.3.1" @@ -1100,41 +1148,44 @@ } }, "node_modules/esbuild": { - "version": "0.19.11", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz", - "integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.11", - "@esbuild/android-arm": "0.19.11", - "@esbuild/android-arm64": "0.19.11", - "@esbuild/android-x64": "0.19.11", - "@esbuild/darwin-arm64": "0.19.11", - "@esbuild/darwin-x64": "0.19.11", - "@esbuild/freebsd-arm64": "0.19.11", - "@esbuild/freebsd-x64": "0.19.11", - "@esbuild/linux-arm": "0.19.11", - "@esbuild/linux-arm64": "0.19.11", - "@esbuild/linux-ia32": "0.19.11", - "@esbuild/linux-loong64": "0.19.11", - "@esbuild/linux-mips64el": "0.19.11", - "@esbuild/linux-ppc64": "0.19.11", - "@esbuild/linux-riscv64": "0.19.11", - "@esbuild/linux-s390x": "0.19.11", - "@esbuild/linux-x64": "0.19.11", - "@esbuild/netbsd-x64": "0.19.11", - "@esbuild/openbsd-x64": "0.19.11", - "@esbuild/sunos-x64": "0.19.11", - "@esbuild/win32-arm64": "0.19.11", - "@esbuild/win32-ia32": "0.19.11", - "@esbuild/win32-x64": "0.19.11" + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" } }, "node_modules/escalade": { @@ -1187,9 +1238,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -1236,6 +1287,20 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1573,9 +1638,9 @@ "dev": true }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -1845,32 +1910,31 @@ "optional": true }, "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", @@ -1878,10 +1942,6 @@ }, "engines": { "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" } }, "node_modules/mocha/node_modules/argparse": { @@ -1890,6 +1950,15 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/mocha/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1903,37 +1972,25 @@ } }, "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/mocha/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1944,9 +2001,9 @@ } }, "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "dependencies": { "argparse": "^2.0.1" @@ -1956,9 +2013,9 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -1967,21 +2024,6 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -1998,9 +2040,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node_modules/mute-stream": { @@ -2009,18 +2051,6 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", @@ -2344,21 +2374,6 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -2385,9 +2400,9 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -2539,9 +2554,9 @@ } }, "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", "dev": true, "optional": true, "dependencies": { @@ -2584,15 +2599,12 @@ } }, "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, "engines": { - "node": ">=8.17.0" + "node": ">=14.14" } }, "node_modules/to-regex-range": { @@ -2716,9 +2728,9 @@ } }, "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true }, "node_modules/wrap-ansi": { @@ -2830,9 +2842,9 @@ } }, "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "engines": { "node": ">=10" diff --git a/package.json b/package.json index 13462fd..524b497 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "name": "Kin Numaru" }, "publisher": "numaru", - "version": "1.12.0", + "version": "1.13.0", "license": "MIT", "homepage": "https://github.com/numaru/vscode-ceedling-test-adapter", "repository": { @@ -57,7 +57,7 @@ "@types/vscode": "^1.71.0", "@vscode/test-electron": "^2.3.8", "@vscode/vsce": "^2.22.0", - "esbuild": "^0.19.11", + "esbuild": "^0.27.2", "glob": "^7.1.6", "mocha": "^10.0.0", "typescript": "^4.6.3" @@ -236,6 +236,12 @@ "type": "boolean", "default": true, "scope": "resource" + }, + "ceedlingExplorer.evalRubyInStrings": { + "markdownDescription": "Evaluate the #{ruby_code} in the string using the ruby cli", + "type": "boolean", + "default": false, + "scope": "resource" } } }, @@ -250,4 +256,4 @@ } ] } -} \ No newline at end of file +} diff --git a/src/adapter.ts b/src/adapter.ts index c097634..9051850 100644 --- a/src/adapter.ts +++ b/src/adapter.ts @@ -37,6 +37,7 @@ export class CeedlingAdapter implements TestAdapter { private fileLabelRegex: RegExp | undefined; private testLabelRegex: RegExp | undefined; private debugTestExecutable: string = ''; + private debugTestExecutablePath: string = ''; private buildDirectory: string = ''; private reportFilename: string = ''; private watchedFileForAutorunList: string[] = []; @@ -182,11 +183,12 @@ export class CeedlingAdapter implements TestAdapter { const testFileName = `${/([^/]*).c$/.exec(testToExec)![1]}`; // Set current test executable - const ceedlingVersion = await this.getCeedlingVersion(); - if (this.detectTestSpecificDefines(ymlProjectData, testFileName) || semver.satisfies(ceedlingVersion, ">0.31.1")) - this.setDebugTestExecutable(`${testFileName}/${testFileName}${ext}`); - else - this.setDebugTestExecutable(`${testFileName}${ext}`); + // Use subdirectory format for Ceedling 1.0+ or tests with specific defines + const useSubdirectory = this.isCeedling1Plus(ymlProjectData) || this.detectTestSpecificDefines(ymlProjectData, testFileName); + const executableRelPath = useSubdirectory ? `${testFileName}/${testFileName}${ext}` : `${testFileName}${ext}`; + + this.setDebugTestExecutable(executableRelPath); + this.setDebugTestExecutablePath(`${this.buildDirectory}/test/out/${executableRelPath}`); // Launch debugger if (!await vscode.debug.startDebugging(this.workspaceFolder, debugConfiguration)) @@ -195,6 +197,7 @@ export class CeedlingAdapter implements TestAdapter { finally { // Reset current test executable this.setDebugTestExecutable(""); + this.setDebugTestExecutablePath(""); } } @@ -207,6 +210,15 @@ export class CeedlingAdapter implements TestAdapter { this.logger.info(`Set the debugTestExecutable to ${this.debugTestExecutable}`); } + getDebugTestExecutablePath(): string { + return this.debugTestExecutablePath; + } + + setDebugTestExecutablePath(path: string) { + this.debugTestExecutablePath = path; + this.logger.info(`Set the debugTestExecutablePath to ${this.debugTestExecutablePath}`); + } + async clean(): Promise { this.logger.trace(`clean()`); const result = await vscode.window.withProgress( @@ -284,14 +296,30 @@ export class CeedlingAdapter implements TestAdapter { `Please check the ceedlingExplorer.projectPath option.`; } try { - if (!ymlProjectData[':plugins'][':enabled'].includes('xml_tests_report')) { + const hasXmlTestsReport = ymlProjectData[':plugins'][':enabled'].includes('xml_tests_report'); + const hasReportFactory = ymlProjectData[':plugins'][':enabled'].includes('report_tests_log_factory'); + + if (!hasXmlTestsReport && !hasReportFactory) { throw 'Xml report plugin not enabled'; } + + // For report_tests_log_factory, verify cppunit format is enabled + if (hasReportFactory && !hasXmlTestsReport) { + try { + const reports = ymlProjectData[':report_tests_log_factory'][':reports']; + if (!reports || !reports.includes('cppunit')) { + throw 'CppUnit report not enabled in report_tests_log_factory'; + } + } catch (e) { + return `The 'report_tests_log_factory' plugin is enabled but 'cppunit' report format is not configured. ` + + `Add 'cppunit' to :report_tests_log_factory::reports list in your project.yml file.`; + } + } } catch (e) { - return `The required Ceedling plugin 'xml_tests_report' is not enabled. ` + - `You have to edit your 'project.xml' file to enable the plugin.\n` + - `see https://github.com/ThrowTheSwitch/Ceedling/blob/master/docs/CeedlingPacket.md` + - `#tool-element-runtime-substitution-notational-substitution`; + return `A required Ceedling XML report plugin is not enabled. ` + + `For Ceedling 0.31.x, enable 'xml_tests_report' plugin. ` + + `For Ceedling 1.0+, enable 'report_tests_log_factory' plugin with 'cppunit' report format.\n` + + `see https://github.com/ThrowTheSwitch/Ceedling/blob/master/docs/CeedlingPacket.md`; } } @@ -331,7 +359,11 @@ export class CeedlingAdapter implements TestAdapter { return value.startsWith(" - "); }).map((value: string) => { return value.substr(3).trim(); - }) + }).filter((filePath: string) => { + // Exclude files from the build output directory (preprocessed files, runners, etc.) + // These would create duplicate entries in the test explorer + return !filePath.includes(this.buildDirectory); + }); } } finally { release(); @@ -386,6 +418,15 @@ export class CeedlingAdapter implements TestAdapter { return false; } + private isCeedling1Plus(ymlProjectData: any = undefined): boolean { + if (ymlProjectData) { + try { + return ymlProjectData[':plugins'][':enabled'].includes('report_tests_log_factory'); + } catch (e) { } + } + return false; + } + private async getCeedlingVersion(): Promise { const result = await this.execCeedling(['version']); const regex = new RegExp('^\\s*Ceedling::\\s*(.*)$', 'gm'); @@ -465,13 +506,42 @@ export class CeedlingAdapter implements TestAdapter { ); } + private execRubySync(args: ReadonlyArray): string { + this.logger.trace(`execRuby(args=${util.format(args)})`); + const command = `ruby -e "${args.join(" ").replace(/"/g, '\\"')}"`; + const cwd = this.getProjectPath(); + const shell = this.getShellPath(); + const stdout = child_process.execSync( + command, { cwd: cwd, shell: shell }, + ).toString().trim(); + this.logger.debug(`execSync(command=${util.format(command)}, ` + + `cwd=${util.format(cwd)}, ` + + `shell=${util.format(shell)}, ` + + `stdout=${util.format(stdout)}`); + return stdout; + } + + private evalRuby(str: string) { + const evalRuby = this.getConfiguration().get('evalRubyInStrings', false); + if (!evalRuby) { + return str; + } + return str.replace(/#\{(.+)\}/g, (_, match) => { + const stdout = this.execRubySync(["p", match]); + if (stdout.startsWith('"') && stdout.endsWith('"')) { + return stdout.slice(1, -1); + } + return stdout; + }); + } + private setBuildDirectory(ymlProjectData: any = undefined) { let buildDirectory = 'build'; if (ymlProjectData) { try { const ymlProjectBuildDirectory = ymlProjectData[':project'][':build_root']; if (ymlProjectBuildDirectory != undefined) { - buildDirectory = ymlProjectBuildDirectory; + buildDirectory = this.evalRuby(ymlProjectBuildDirectory); } } catch (e) { } } @@ -481,12 +551,28 @@ export class CeedlingAdapter implements TestAdapter { private setXmlReportPath(ymlProjectData: any = undefined) { let reportFilename = 'report.xml'; if (ymlProjectData) { + // Try new Ceedling 1.0+ report_tests_log_factory plugin first try { - const ymlProjectReportFilename = ymlProjectData[':xml_tests_report'][':artifact_filename']; + const ymlProjectReportFilename = ymlProjectData[':report_tests_log_factory'][':cppunit'][':filename']; if (ymlProjectReportFilename != undefined) { reportFilename = ymlProjectReportFilename; } - } catch (e) { } + } catch (e) { + // Fall back to old xml_tests_report plugin (Ceedling 0.31.x) + try { + const ymlProjectReportFilename = ymlProjectData[':xml_tests_report'][':artifact_filename']; + if (ymlProjectReportFilename != undefined) { + reportFilename = ymlProjectReportFilename; + } + } catch (e) { + // If report_tests_log_factory is enabled but no custom filename, use default + try { + if (ymlProjectData[':plugins'][':enabled'].includes('report_tests_log_factory')) { + reportFilename = 'cppunit_tests_report.xml'; + } + } catch (e) { } + } + } } this.reportFilename = reportFilename; } diff --git a/src/main.ts b/src/main.ts index d939013..11f6b08 100644 --- a/src/main.ts +++ b/src/main.ts @@ -23,6 +23,22 @@ function debugTestExecutable(): string | null { return null; } +function debugTestExecutablePath(): string | null { + if (!adapters) return null; + for (let adapter of adapters) { + let debugTestExecutablePath = adapter.getDebugTestExecutablePath(); + if (debugTestExecutablePath) { + return debugTestExecutablePath; + } + } + logger.showError("No debug test executable path found"); + logger.showInfo( + "A debug configuration with a path containing `${command:ceedlingExplorer.debugTestExecutablePath}` " + + "cannot be started from F5 or the Run pannel. It should be started from a bug icon in the Test pannel." + ); + return null; +} + function ceedlingClean(): void { if (!adapters) return; for (let adapter of adapters) { @@ -41,6 +57,7 @@ export async function activate(context: vscode.ExtensionContext) { const testExplorerExtension = vscode.extensions.getExtension(testExplorerExtensionId); if (testExplorerExtension) { context.subscriptions.push(vscode.commands.registerCommand("ceedlingExplorer.debugTestExecutable", debugTestExecutable)); + context.subscriptions.push(vscode.commands.registerCommand("ceedlingExplorer.debugTestExecutablePath", debugTestExecutablePath)); context.subscriptions.push(vscode.commands.registerCommand("ceedlingExplorer.clean", ceedlingClean)); context.subscriptions.push(vscode.commands.registerCommand("ceedlingExplorer.clobber", ceedlingClobber)); context.subscriptions.push(logger); diff --git a/tests/e2e/.gitignore b/tests/e2e/.gitignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/tests/e2e/.gitignore @@ -0,0 +1 @@ +build diff --git a/tests/e2e/v0.31/.ruby-version b/tests/e2e/v0.31/.ruby-version new file mode 100644 index 0000000..6a81b4c --- /dev/null +++ b/tests/e2e/v0.31/.ruby-version @@ -0,0 +1 @@ +2.7.8 diff --git a/tests/e2e/v0.31/temp_sensor/.vscode/launch.json b/tests/e2e/v0.31/temp_sensor/.vscode/launch.json new file mode 100644 index 0000000..1f1b7a9 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "configurations": [ + { + "name": "Ceedling Test Explorer Debug", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/test/out/${command:ceedlingExplorer.debugTestExecutable}", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + }, + ] +} diff --git a/tests/e2e/v0.31/temp_sensor/.vscode/settings.json b/tests/e2e/v0.31/temp_sensor/.vscode/settings.json new file mode 100644 index 0000000..5d3dcb2 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "ceedlingExplorer.debugConfiguration": "Ceedling Test Explorer Debug" +} diff --git a/tests/e2e/v0.31/temp_sensor/project.yml b/tests/e2e/v0.31/temp_sensor/project.yml new file mode 100644 index 0000000..dd272dd --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/project.yml @@ -0,0 +1,69 @@ +--- + +# Notes: +# Sample project C code is not presently written to produce a release artifact. +# As such, release build options are disabled. +# This sample, therefore, only demonstrates running a collection of unit tests. + +:project: + :use_exceptions: FALSE + :use_test_preprocessor: TRUE + :use_auxiliary_dependencies: TRUE + :build_root: build + # :release_build: TRUE + :test_file_prefix: Test + :which_ceedling: gem + :ceedling_version: '?' + +#:release_build: +# :output: TempSensor.out +# :use_assembly: FALSE + +:environment: [] + +:extension: + :executable: .out + +:paths: + :test: + - +:test/** + - -:test/support + :source: + - src/** + :support: + - test/support + +:defines: + :common: &common_defines [] + :test: + - *common_defines + - TEST + :test_preprocess: + - *common_defines + - TEST + +:cmock: + :when_no_prototypes: :warn + :enforce_strict_ordering: TRUE + :plugins: + - :ignore + :treat_as: + uint8: HEX8 + uint16: HEX16 + uint32: UINT32 + int8: INT8 + bool: UINT8 + +:libraries: + :system: + - m + +:plugins: + :load_paths: + - "#{Ceedling.load_path}" + :enabled: + - stdout_pretty_tests_report + - module_generator + - gcov + - xml_tests_report +... diff --git a/tests/e2e/v0.31/temp_sensor/src/AdcConductor.c b/tests/e2e/v0.31/temp_sensor/src/AdcConductor.c new file mode 100644 index 0000000..28d9d20 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/AdcConductor.c @@ -0,0 +1,42 @@ +#include "Types.h" +#include "AdcConductor.h" +#include "AdcModel.h" +#include "AdcHardware.h" + +void AdcConductor_Init(void) +{ + AdcHardware_Init(); +} + +void AdcConductor_Run(void) +{ + if (AdcModel_DoGetSample() && AdcHardware_GetSampleComplete()) + { + AdcModel_ProcessInput(AdcHardware_GetSample()); + AdcHardware_StartConversion(); + } +} + +bool AdcConductor_JustHereToTest(void) +{ + EXAMPLE_STRUCT_T ExampleStruct; + ExampleStruct.x = 5; + ExampleStruct.y = 7; + + return AdcModel_DoNothingExceptTestASpecialType(ExampleStruct); +} + +bool AdcConductor_AlsoHereToTest(void) +{ + EXAMPLE_STRUCT_T example = AdcModel_DoNothingExceptReturnASpecialType(); + + return ((example.x == 99) && (example.y == 1)); +} + +bool AdcConductor_YetAnotherTest(void) +{ + uint32 example = 3; + + return AdModel_DoNothingExceptTestPointers(&example); +} + diff --git a/tests/e2e/v0.31/temp_sensor/src/AdcConductor.h b/tests/e2e/v0.31/temp_sensor/src/AdcConductor.h new file mode 100644 index 0000000..867375b --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/AdcConductor.h @@ -0,0 +1,13 @@ +#ifndef _ADCCONDUCTOR_H +#define _ADCCONDUCTOR_H + +#include "Types.h" + +void AdcConductor_Init(void); +void AdcConductor_Run(void); + +bool AdcConductor_JustHereToTest(void); +bool AdcConductor_AlsoHereToTest(void); +bool AdcConductor_YetAnotherTest(void); + +#endif // _ADCCONDUCTOR_H diff --git a/tests/e2e/v0.31/temp_sensor/src/AdcHardware.c b/tests/e2e/v0.31/temp_sensor/src/AdcHardware.c new file mode 100644 index 0000000..9807641 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/AdcHardware.c @@ -0,0 +1,27 @@ +#include "Types.h" +#include "AdcHardware.h" +#include "AdcHardwareConfigurator.h" +#include "AdcTemperatureSensor.h" + +void AdcHardware_Init(void) +{ + Adc_Reset(); + Adc_ConfigureMode(); + Adc_EnableTemperatureChannel(); + Adc_StartTemperatureSensorConversion(); +} + +void AdcHardware_StartConversion(void) +{ + Adc_StartTemperatureSensorConversion(); +} + +bool AdcHardware_GetSampleComplete(void) +{ + return Adc_TemperatureSensorSampleReady(); +} + +uint16 AdcHardware_GetSample(void) +{ + return Adc_ReadTemperatureSensor(); +} diff --git a/tests/e2e/v0.31/temp_sensor/src/AdcHardware.h b/tests/e2e/v0.31/temp_sensor/src/AdcHardware.h new file mode 100644 index 0000000..2245762 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/AdcHardware.h @@ -0,0 +1,11 @@ +#ifndef _ADCHARDWARE_H +#define _ADCHARDWARE_H + +#include "Types.h" + +void AdcHardware_Init(void); +void AdcHardware_StartConversion(void); +bool AdcHardware_GetSampleComplete(void); +uint16 AdcHardware_GetSample(void); + +#endif // _ADCHARDWARE_H diff --git a/tests/e2e/v0.31/temp_sensor/src/AdcHardwareConfigurator.c b/tests/e2e/v0.31/temp_sensor/src/AdcHardwareConfigurator.c new file mode 100644 index 0000000..f7e08a2 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/AdcHardwareConfigurator.c @@ -0,0 +1,18 @@ +#include "Types.h" +#include "AdcHardwareConfigurator.h" +#include "ModelConfig.h" + +void Adc_Reset(void) +{ + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; +} + +void Adc_ConfigureMode(void) +{ + AT91C_BASE_ADC->ADC_MR = (((uint32)11) << 8) | (((uint32)4) << 16); +} + +void Adc_EnableTemperatureChannel(void) +{ + AT91C_BASE_ADC->ADC_CHER = 0x10; +} diff --git a/tests/e2e/v0.31/temp_sensor/src/AdcHardwareConfigurator.h b/tests/e2e/v0.31/temp_sensor/src/AdcHardwareConfigurator.h new file mode 100644 index 0000000..78b9e9f --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/AdcHardwareConfigurator.h @@ -0,0 +1,10 @@ +#ifndef _ADCHARDWARECONFIGURATOR_H +#define _ADCHARDWARECONFIGURATOR_H + +#include "Types.h" + +void Adc_Reset(void); +void Adc_ConfigureMode(void); +void Adc_EnableTemperatureChannel(void); + +#endif // _ADCHARDWARECONFIGURATOR_H diff --git a/tests/e2e/v0.31/temp_sensor/src/AdcModel.c b/tests/e2e/v0.31/temp_sensor/src/AdcModel.c new file mode 100644 index 0000000..ad9111d --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/AdcModel.c @@ -0,0 +1,33 @@ +#include "AdcModel.h" +#include "TaskScheduler.h" +#include "TemperatureCalculator.h" +#include "TemperatureFilter.h" + +bool AdcModel_DoGetSample(void) +{ + return TaskScheduler_DoAdc(); +} + +void AdcModel_ProcessInput(uint16 millivolts) +{ + TemperatureFilter_ProcessInput(TemperatureCalculator_Calculate(millivolts)); +} + +bool AdcModel_DoNothingExceptTestASpecialType(EXAMPLE_STRUCT_T ExampleStruct) +{ + //This doesn't really do anything. it's only here to make sure I can compare a struct. + return FALSE; +} +bool AdModel_DoNothingExceptTestPointers(uint32* pExample) +{ + //This doesn't really do anything. it's only here to make sure I can compare a pointer value. + return FALSE; +} + +EXAMPLE_STRUCT_T AdcModel_DoNothingExceptReturnASpecialType(void) +{ + EXAMPLE_STRUCT_T example; //again, this just is here to test that I can return a struct + example.x = 99; + example.y = 1; + return example; +} diff --git a/tests/e2e/v0.31/temp_sensor/src/AdcModel.h b/tests/e2e/v0.31/temp_sensor/src/AdcModel.h new file mode 100644 index 0000000..6b871fd --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/AdcModel.h @@ -0,0 +1,13 @@ +#ifndef _ADCMODEL_H +#define _ADCMODEL_H + +#include "Types.h" + +bool AdcModel_DoGetSample(void); +void AdcModel_ProcessInput(uint16 millivolts); + +bool AdcModel_DoNothingExceptTestASpecialType(EXAMPLE_STRUCT_T ExampleStruct); +bool AdModel_DoNothingExceptTestPointers(uint32* pExample); +EXAMPLE_STRUCT_T AdcModel_DoNothingExceptReturnASpecialType(void); + +#endif // _ADCMODEL_H diff --git a/tests/e2e/v0.31/temp_sensor/src/AdcTemperatureSensor.c b/tests/e2e/v0.31/temp_sensor/src/AdcTemperatureSensor.c new file mode 100644 index 0000000..b2a3f2c --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/AdcTemperatureSensor.c @@ -0,0 +1,51 @@ +#include "Types.h" +#include "AdcTemperatureSensor.h" + +static inline uint32 ConvertAdcCountsToPicovolts(uint32 counts); +static inline uint16 ConvertPicovoltsToMillivolts(uint32 picovolts); + +// +// PUBLIC METHODS +// + +void Adc_StartTemperatureSensorConversion(void) +{ + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; +} + +bool Adc_TemperatureSensorSampleReady(void) +{ + return ((AT91C_BASE_ADC->ADC_SR & AT91C_ADC_EOC4) == AT91C_ADC_EOC4); +} + +uint16 Adc_ReadTemperatureSensor(void) +{ + uint32 picovolts = ConvertAdcCountsToPicovolts(AT91C_BASE_ADC->ADC_CDR4); + return ConvertPicovoltsToMillivolts(picovolts); +} + +// +// PRIVATE HELPERS +// + +static inline uint32 ConvertAdcCountsToPicovolts(uint32 counts) +{ + // ADC bit weight at 10-bit resolution with 3.0V reference = 2.9296875 mV/LSB + uint32 picovoltsPerAdcCount = 2929688; + + // Shift decimal point by 6 places to preserve accuracy in fixed-point math + return counts * picovoltsPerAdcCount; +} + +static inline uint16 ConvertPicovoltsToMillivolts(uint32 picovolts) +{ + const uint32 halfMillivoltInPicovolts = 500000; + const uint32 picovoltsPerMillivolt = 1000000; + + // Add 0.5 mV to result so that truncation yields properly rounded result + picovolts += halfMillivoltInPicovolts; + + // Divide appropriately to convert to millivolts + return (uint16)(picovolts / picovoltsPerMillivolt); +} + diff --git a/tests/e2e/v0.31/temp_sensor/src/AdcTemperatureSensor.h b/tests/e2e/v0.31/temp_sensor/src/AdcTemperatureSensor.h new file mode 100644 index 0000000..bf2cc5b --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/AdcTemperatureSensor.h @@ -0,0 +1,10 @@ +#ifndef _ADCTEMPERATURESENSOR_H +#define _ADCTEMPERATURESENSOR_H + +#include "Types.h" + +void Adc_StartTemperatureSensorConversion(void); +bool Adc_TemperatureSensorSampleReady(void); +uint16 Adc_ReadTemperatureSensor(void); + +#endif // _ADCTEMPERATURESENSOR_H diff --git a/tests/e2e/v0.31/temp_sensor/src/Executor.c b/tests/e2e/v0.31/temp_sensor/src/Executor.c new file mode 100644 index 0000000..7e45c3e --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/Executor.c @@ -0,0 +1,25 @@ +#include "Types.h" +#include "Executor.h" +#include "Model.h" +#include "UsartConductor.h" +#include "TimerConductor.h" +#include "AdcConductor.h" +#include "IntrinsicsWrapper.h" + + +void Executor_Init(void) +{ + Model_Init(); + UsartConductor_Init(); + AdcConductor_Init(); + TimerConductor_Init(); + Interrupt_Enable(); +} + +bool Executor_Run(void) +{ + UsartConductor_Run(); + TimerConductor_Run(); + AdcConductor_Run(); + return TRUE; +} diff --git a/tests/e2e/v0.31/temp_sensor/src/Executor.h b/tests/e2e/v0.31/temp_sensor/src/Executor.h new file mode 100644 index 0000000..51a61a9 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/Executor.h @@ -0,0 +1,9 @@ +#ifndef _EXECUTOR_H +#define _EXECUTOR_H + +#include "Types.h" + +void Executor_Init(void); +bool Executor_Run(void); + +#endif // _EXECUTOR_H diff --git a/tests/e2e/v0.31/temp_sensor/src/IntrinsicsWrapper.c b/tests/e2e/v0.31/temp_sensor/src/IntrinsicsWrapper.c new file mode 100644 index 0000000..8b082ae --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/IntrinsicsWrapper.c @@ -0,0 +1,18 @@ +#include "IntrinsicsWrapper.h" +#ifdef __ICCARM__ +#include +#endif + +void Interrupt_Enable(void) +{ +#ifdef __ICCARM__ + __enable_interrupt(); +#endif +} + +void Interrupt_Disable(void) +{ +#ifdef __ICCARM__ + __disable_interrupt(); +#endif +} diff --git a/tests/e2e/v0.31/temp_sensor/src/IntrinsicsWrapper.h b/tests/e2e/v0.31/temp_sensor/src/IntrinsicsWrapper.h new file mode 100644 index 0000000..9273317 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/IntrinsicsWrapper.h @@ -0,0 +1,7 @@ +#ifndef _INTRINSICS_WRAPPER_H +#define _INTRINSICS_WRAPPER_H + +void Interrupt_Enable(void); +void Interrupt_Disable(void); + +#endif // _INTRINSICS_WRAPPER_H diff --git a/tests/e2e/v0.31/temp_sensor/src/Main.c b/tests/e2e/v0.31/temp_sensor/src/Main.c new file mode 100644 index 0000000..a784f47 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/Main.c @@ -0,0 +1,46 @@ +#include "Types.h" + +#include "IntrinsicsWrapper.h" +#include "Executor.h" + +#include "Model.h" +#include "TaskScheduler.h" +#include "TemperatureCalculator.h" +#include "TemperatureFilter.h" + +#include "UsartConductor.h" +#include "UsartHardware.h" +#include "UsartConfigurator.h" +#include "UsartPutChar.h" +#include "UsartModel.h" +#include "UsartBaudRateRegisterCalculator.h" +#include "UsartTransmitBufferStatus.h" + +#include "TimerConductor.h" +#include "TimerHardware.h" +#include "TimerConfigurator.h" +#include "TimerInterruptConfigurator.h" +#include "TimerInterruptHandler.h" +#include "TimerModel.h" + +#include "AdcConductor.h" +#include "AdcHardware.h" +#include "AdcHardwareConfigurator.h" +#include "AdcTemperatureSensor.h" +#include "AdcModel.h" + +int AppMain(void) +{ + Executor_Init(); + + while(Executor_Run()); + + return 0; +} + +#ifndef TEST +int main(void) +{ + return AppMain(); +} +#endif // TEST diff --git a/tests/e2e/v0.31/temp_sensor/src/Main.h b/tests/e2e/v0.31/temp_sensor/src/Main.h new file mode 100644 index 0000000..6cbe5f4 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/Main.h @@ -0,0 +1,7 @@ +#ifndef _MAIN_H_ +#define _MAIN_H_ + +int AppMain(void); +int main(void); + +#endif // _MAIN_H_ diff --git a/tests/e2e/v0.31/temp_sensor/src/Model.c b/tests/e2e/v0.31/temp_sensor/src/Model.c new file mode 100644 index 0000000..5b34c40 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/Model.c @@ -0,0 +1,10 @@ +#include "Model.h" +#include "TaskScheduler.h" +#include "TemperatureFilter.h" + +void Model_Init(void) +{ + TaskScheduler_Init(); + TemperatureFilter_Init(); +} + diff --git a/tests/e2e/v0.31/temp_sensor/src/Model.h b/tests/e2e/v0.31/temp_sensor/src/Model.h new file mode 100644 index 0000000..d130938 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/Model.h @@ -0,0 +1,8 @@ +#ifndef _MODEL_H +#define _MODEL_H + +#include "Types.h" + +void Model_Init(void); + +#endif // _MODEL_H diff --git a/tests/e2e/v0.31/temp_sensor/src/ModelConfig.h b/tests/e2e/v0.31/temp_sensor/src/ModelConfig.h new file mode 100644 index 0000000..edc8e8d --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/ModelConfig.h @@ -0,0 +1,7 @@ +#ifndef _MODELCONFIG_H +#define _MODELCONFIG_H + +#define MASTER_CLOCK 48054857 // Master Clock +#define USART0_BAUDRATE 115200 // USART Baudrate + +#endif // _MODELCONFIG_H diff --git a/tests/e2e/v0.31/temp_sensor/src/TaskScheduler.c b/tests/e2e/v0.31/temp_sensor/src/TaskScheduler.c new file mode 100644 index 0000000..bcc0e64 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TaskScheduler.c @@ -0,0 +1,72 @@ +#include "Types.h" +#include "TaskScheduler.h" + +typedef struct _Task +{ + bool doIt; + uint32 period; + uint32 startTime; +} Task; + +typedef struct _TaskSchedulerInstance +{ + Task usart; + Task adc; +} TaskSchedulerInstance; + +static TaskSchedulerInstance this; + +void TaskScheduler_Init(void) +{ + this.usart.doIt = FALSE; + this.usart.startTime = 0; + + //The correct period + this.usart.period = 1000; + + this.adc.doIt = FALSE; + this.adc.startTime = 0; + this.adc.period = 100; +} + +void TaskScheduler_Update(uint32 time) +{ + if ((time - this.usart.startTime) >= this.usart.period) + { + this.usart.doIt = TRUE; + this.usart.startTime = time - (time % this.usart.period); + } + + if ((time - this.adc.startTime) >= this.adc.period) + { + this.adc.doIt = TRUE; + this.adc.startTime = time - (time % this.adc.period); + } +} + +bool TaskScheduler_DoUsart(void) +{ + bool doIt = FALSE; + + if (this.usart.doIt) + { + doIt = TRUE; + this.usart.doIt = FALSE; + } + + return doIt; +} + +bool TaskScheduler_DoAdc(void) +{ + bool doIt = FALSE; + + if (this.adc.doIt) + { + doIt = TRUE; + this.adc.doIt = FALSE; + } + + return doIt; +} + diff --git a/tests/e2e/v0.31/temp_sensor/src/TaskScheduler.h b/tests/e2e/v0.31/temp_sensor/src/TaskScheduler.h new file mode 100644 index 0000000..cc58342 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TaskScheduler.h @@ -0,0 +1,11 @@ +#ifndef _TASKSCHEDULER_H +#define _TASKSCHEDULER_H + +#include "Types.h" + +void TaskScheduler_Init(void); +void TaskScheduler_Update(uint32 time); +bool TaskScheduler_DoUsart(void); +bool TaskScheduler_DoAdc(void); + +#endif // _TASKSCHEDULER_H diff --git a/tests/e2e/v0.31/temp_sensor/src/TemperatureCalculator.c b/tests/e2e/v0.31/temp_sensor/src/TemperatureCalculator.c new file mode 100644 index 0000000..04cec59 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TemperatureCalculator.c @@ -0,0 +1,27 @@ +#include "Types.h" +#include "TemperatureCalculator.h" +#include + +#ifndef logl +#define logl log +#endif + +float TemperatureCalculator_Calculate(uint16 millivolts) +{ + const double supply_voltage = 3.0; + const double series_resistance = 5000; + const double coefficient_A = 316589.698; + const double coefficient_B = -0.1382009; + double sensor_voltage = ((double)millivolts / 1000); + double resistance; + + if (millivolts == 0) + { + return -INFINITY; + } + + // Series resistor is 5k Ohms; Reference voltage is 3.0V + // R(t) = A * e^(B*t); R is resistance of thermisor; t is temperature in C + resistance = ((supply_voltage * series_resistance) / sensor_voltage) - series_resistance; + return (float)(logl(resistance / coefficient_A) / coefficient_B); +} diff --git a/tests/e2e/v0.31/temp_sensor/src/TemperatureCalculator.h b/tests/e2e/v0.31/temp_sensor/src/TemperatureCalculator.h new file mode 100644 index 0000000..73f3df3 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TemperatureCalculator.h @@ -0,0 +1,8 @@ +#ifndef _TEMPERATURECALCULATOR_H +#define _TEMPERATURECALCULATOR_H + +#include "Types.h" + +float TemperatureCalculator_Calculate(uint16 millivolts); + +#endif // _TEMPERATURECALCULATOR_H diff --git a/tests/e2e/v0.31/temp_sensor/src/TemperatureFilter.c b/tests/e2e/v0.31/temp_sensor/src/TemperatureFilter.c new file mode 100644 index 0000000..6fa6bab --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TemperatureFilter.c @@ -0,0 +1,38 @@ +#include "Types.h" +#include "TemperatureFilter.h" +#include + +static bool initialized; +static float temperatureInCelcius; + +void TemperatureFilter_Init(void) +{ + initialized = FALSE; + temperatureInCelcius = -INFINITY; +} + +float TemperatureFilter_GetTemperatureInCelcius(void) +{ + return temperatureInCelcius; +} + +void TemperatureFilter_ProcessInput(float temperature) +{ + if (!initialized) + { + temperatureInCelcius = temperature; + initialized = TRUE; + } + else + { + if (temperature == +INFINITY || + temperature == -INFINITY || + isnan(temperature)) + { + initialized = FALSE; + temperature = -INFINITY; + } + + temperatureInCelcius = (temperatureInCelcius * 0.75f) + (temperature * 0.25); + } +} diff --git a/tests/e2e/v0.31/temp_sensor/src/TemperatureFilter.h b/tests/e2e/v0.31/temp_sensor/src/TemperatureFilter.h new file mode 100644 index 0000000..31413f4 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TemperatureFilter.h @@ -0,0 +1,10 @@ +#ifndef _TEMPERATUREFILTER_H +#define _TEMPERATUREFILTER_H + +#include "Types.h" + +void TemperatureFilter_Init(void); +float TemperatureFilter_GetTemperatureInCelcius(void); +void TemperatureFilter_ProcessInput(float temperature); + +#endif // _TEMPERATUREFILTER_H diff --git a/tests/e2e/v0.31/temp_sensor/src/TimerConductor.c b/tests/e2e/v0.31/temp_sensor/src/TimerConductor.c new file mode 100644 index 0000000..569b489 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TimerConductor.c @@ -0,0 +1,15 @@ +#include "Types.h" +#include "TimerConductor.h" +#include "TimerModel.h" +#include "TimerHardware.h" +#include "TimerInterruptHandler.h" + +void TimerConductor_Init(void) +{ + TimerHardware_Init(); +} + +void TimerConductor_Run(void) +{ + TimerModel_UpdateTime(Timer_GetSystemTime()); +} diff --git a/tests/e2e/v0.31/temp_sensor/src/TimerConductor.h b/tests/e2e/v0.31/temp_sensor/src/TimerConductor.h new file mode 100644 index 0000000..7cd4109 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TimerConductor.h @@ -0,0 +1,9 @@ +#ifndef _TIMERCONDUCTOR_H +#define _TIMERCONDUCTOR_H + +#include "Types.h" + +void TimerConductor_Init(void); +void TimerConductor_Run(void); + +#endif // _TIMERCONDUCTOR_H diff --git a/tests/e2e/v0.31/temp_sensor/src/TimerConfigurator.c b/tests/e2e/v0.31/temp_sensor/src/TimerConfigurator.c new file mode 100644 index 0000000..996cede --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TimerConfigurator.c @@ -0,0 +1,51 @@ +#include "Types.h" +#include "TimerConfigurator.h" +#include "TimerInterruptConfigurator.h" + +void Timer_EnablePeripheralClocks(void) +{ + AT91C_BASE_PMC->PMC_PCER = TIMER0_CLOCK_ENABLE | PIOB_CLOCK_ENABLE; +} + +void Timer_Reset(void) +{ + uint32 dummy; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC0->TC_IDR = 0xffffffff; + dummy = AT91C_BASE_TC0->TC_SR; + dummy = dummy; +} + +void Timer_ConfigureMode(void) +{ + AT91C_BASE_TC0->TC_CMR = 0x000CC004; // ACPC=toggle TIOA on RC compare; mode=WAVE; WAVE_SEL=UP w/auto-trigger on RC compare; clock=MCK/1024 +} + +void Timer_ConfigurePeriod(void) +{ + AT91C_BASE_TC0->TC_RC = 469; // 10ms period for timer clock source of MCK/1024 with MCK=48054857 +} + +void Timer_EnableOutputPin(void) +{ + AT91C_BASE_PIOB->PIO_PDR = TIOA0_PIN_MASK; +} + +void Timer_Enable(void) +{ + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN; +} + +void Timer_ConfigureInterruptHandler(void) +{ + Timer_DisableInterrupt(); + Timer_ResetSystemTime(); + Timer_ConfigureInterrupt(); + Timer_EnableInterrupt(); +} + +void Timer_Start(void) +{ + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; +} + diff --git a/tests/e2e/v0.31/temp_sensor/src/TimerConfigurator.h b/tests/e2e/v0.31/temp_sensor/src/TimerConfigurator.h new file mode 100644 index 0000000..d078c54 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TimerConfigurator.h @@ -0,0 +1,15 @@ +#ifndef _TIMERCONFIGURATOR_H +#define _TIMERCONFIGURATOR_H + +#include "Types.h" + +void Timer_EnablePeripheralClocks(void); +void Timer_Reset(void); +void Timer_ConfigureMode(void); +void Timer_ConfigurePeriod(void); +void Timer_EnableOutputPin(void); +void Timer_Enable(void); +void Timer_ConfigureInterruptHandler(void); +void Timer_Start(void); + +#endif // _TIMERCONFIGURATOR_H diff --git a/tests/e2e/v0.31/temp_sensor/src/TimerHardware.c b/tests/e2e/v0.31/temp_sensor/src/TimerHardware.c new file mode 100644 index 0000000..d5e983f --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TimerHardware.c @@ -0,0 +1,15 @@ +#include "Types.h" +#include "TimerHardware.h" +#include "TimerConfigurator.h" + +void TimerHardware_Init(void) +{ + Timer_EnablePeripheralClocks(); + Timer_Reset(); + Timer_ConfigureMode(); + Timer_ConfigurePeriod(); + Timer_EnableOutputPin(); + Timer_Enable(); + Timer_ConfigureInterruptHandler(); + Timer_Start(); +} diff --git a/tests/e2e/v0.31/temp_sensor/src/TimerHardware.h b/tests/e2e/v0.31/temp_sensor/src/TimerHardware.h new file mode 100644 index 0000000..92fa287 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TimerHardware.h @@ -0,0 +1,8 @@ +#ifndef _TIMERHARDWARE_H +#define _TIMERHARDWARE_H + +#include "Types.h" + +void TimerHardware_Init(void); + +#endif // _TIMERHARDWARE_H diff --git a/tests/e2e/v0.31/temp_sensor/src/TimerInterruptConfigurator.c b/tests/e2e/v0.31/temp_sensor/src/TimerInterruptConfigurator.c new file mode 100644 index 0000000..fe603ef --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TimerInterruptConfigurator.c @@ -0,0 +1,55 @@ +#include "Types.h" +#include "TimerInterruptConfigurator.h" +#include "TimerInterruptHandler.h" + +static inline void SetInterruptHandler(void); +static inline void ConfigureInterruptSourceModeRegister(void); +static inline void ClearInterrupt(void); +static inline void EnableCompareInterruptForRegisterC(void); + +void Timer_DisableInterrupt(void) +{ + AT91C_BASE_AIC->AIC_IDCR = TIMER0_ID_MASK; +} + +void Timer_ResetSystemTime(void) +{ + Timer_SetSystemTime(0); +} + +void Timer_ConfigureInterrupt(void) +{ + SetInterruptHandler(); + ConfigureInterruptSourceModeRegister(); + ClearInterrupt(); + EnableCompareInterruptForRegisterC(); +} + +void Timer_EnableInterrupt(void) +{ + AT91C_BASE_AIC->AIC_IECR = TIMER0_ID_MASK; +} + +// +// Helpers +// + +static inline void SetInterruptHandler(void) +{ + AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (uint32)Timer_InterruptHandler; +} + +static inline void ConfigureInterruptSourceModeRegister(void) +{ + AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = 1; +} + +static inline void ClearInterrupt(void) +{ + AT91C_BASE_AIC->AIC_ICCR = TIMER0_ID_MASK; +} + +static inline void EnableCompareInterruptForRegisterC(void) +{ + AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS; +} diff --git a/tests/e2e/v0.31/temp_sensor/src/TimerInterruptConfigurator.h b/tests/e2e/v0.31/temp_sensor/src/TimerInterruptConfigurator.h new file mode 100644 index 0000000..bdf6471 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TimerInterruptConfigurator.h @@ -0,0 +1,13 @@ +#ifndef _TIMERINTERRUPTCONFIGURATOR_H +#define _TIMERINTERRUPTCONFIGURATOR_H + +#include "Types.h" + +#define TIMER0_ID_MASK (((uint32)0x1) << AT91C_ID_TC0) + +void Timer_DisableInterrupt(void); +void Timer_ResetSystemTime(void); +void Timer_ConfigureInterrupt(void); +void Timer_EnableInterrupt(void); + +#endif // _TIMERINTERRUPTCONFIGURATOR_H diff --git a/tests/e2e/v0.31/temp_sensor/src/TimerInterruptHandler.c b/tests/e2e/v0.31/temp_sensor/src/TimerInterruptHandler.c new file mode 100644 index 0000000..ebb543d --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TimerInterruptHandler.c @@ -0,0 +1,25 @@ +#include "Types.h" +#include "TimerInterruptHandler.h" +#include "TimerInterruptConfigurator.h" + +static uint32 systemTime; + +void Timer_SetSystemTime(uint32 time) +{ + systemTime = time; +} + +uint32 Timer_GetSystemTime(void) +{ + return systemTime; +} + +void Timer_InterruptHandler(void) +{ + uint32 status = AT91C_BASE_TC0->TC_SR; + if (status & AT91C_TC_CPCS) + { + systemTime += 10; + } +} + diff --git a/tests/e2e/v0.31/temp_sensor/src/TimerInterruptHandler.h b/tests/e2e/v0.31/temp_sensor/src/TimerInterruptHandler.h new file mode 100644 index 0000000..29c0413 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TimerInterruptHandler.h @@ -0,0 +1,10 @@ +#ifndef _TIMERINTERRUPTHANDLER_H +#define _TIMERINTERRUPTHANDLER_H + +#include "Types.h" + +void Timer_SetSystemTime(uint32 time); +uint32 Timer_GetSystemTime(void); +void Timer_InterruptHandler(void); + +#endif // _TIMERINTERRUPTHANDLER_H diff --git a/tests/e2e/v0.31/temp_sensor/src/TimerModel.c b/tests/e2e/v0.31/temp_sensor/src/TimerModel.c new file mode 100644 index 0000000..fcc9db9 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TimerModel.c @@ -0,0 +1,9 @@ +#include "Types.h" +#include "TimerModel.h" +#include "TaskScheduler.h" + +void TimerModel_UpdateTime(uint32 systemTime) +{ + TaskScheduler_Update(systemTime); +} + diff --git a/tests/e2e/v0.31/temp_sensor/src/TimerModel.h b/tests/e2e/v0.31/temp_sensor/src/TimerModel.h new file mode 100644 index 0000000..54be21a --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/TimerModel.h @@ -0,0 +1,8 @@ +#ifndef _TIMERMODEL_H +#define _TIMERMODEL_H + +#include "Types.h" + +void TimerModel_UpdateTime(uint32 systemTime); + +#endif // _TIMERMODEL_H diff --git a/tests/e2e/v0.31/temp_sensor/src/Types.h b/tests/e2e/v0.31/temp_sensor/src/Types.h new file mode 100644 index 0000000..8944c57 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/Types.h @@ -0,0 +1,90 @@ +#ifndef _MYTYPES_H_ +#define _MYTYPES_H_ + +#include + +// Application Type Definitions +typedef unsigned int uint32; +typedef int int32; +typedef unsigned short uint16; +typedef short int16; +typedef unsigned char uint8; +typedef char int8; +typedef char bool; + +// Application Special Value Definitions +#ifndef TRUE +#define TRUE (1) +#endif +#ifndef FALSE +#define FALSE (0) +#endif +#ifndef NULL +#define NULL (0) +#endif // NULL +#define DONT_CARE (0) + +#ifndef INFINITY +#define INFINITY (1.0 / 0.0) +#endif + +#ifndef NAN +#define NAN (0.0 / 0.0) +#endif + +// MIN/MAX Definitions for Standard Types +#ifndef INT8_MAX +#define INT8_MAX 127 +#endif + +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif + +#ifndef UINT8_MAX +#define UINT8_MAX 0xFFU +#endif + +#ifndef UINT8_MIN +#define UINT8_MIN 0x00U +#endif + +#ifndef INT16_MAX +#define INT16_MAX 32767 +#endif + +#ifndef INT16_MIN +#define INT16_MIN (-32768) +#endif + +#ifndef UINT16_MAX +#define UINT16_MAX 0xFFFFU +#endif + +#ifndef UINT16_MIN +#define UINT16_MIN 0x0000U +#endif + +#ifndef INT32_MAX +#define INT32_MAX 0x7FFFFFFF +#endif + +#ifndef INT32_MIN +#define INT32_MIN (-INT32_MAX - 1) +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX 0xFFFFFFFFU +#endif + +#ifndef UINT32_MIN +#define UINT32_MIN 0x00000000U +#endif + +typedef struct _EXAMPLE_STRUCT_T +{ + int x; + int y; +} EXAMPLE_STRUCT_T; + +#endif // _MYTYPES_H_ diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartBaudRateRegisterCalculator.c b/tests/e2e/v0.31/temp_sensor/src/UsartBaudRateRegisterCalculator.c new file mode 100644 index 0000000..f4ad147 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartBaudRateRegisterCalculator.c @@ -0,0 +1,18 @@ +#include "Types.h" +#include "UsartBaudRateRegisterCalculator.h" + +uint8 UsartModel_CalculateBaudRateRegisterSetting(uint32 masterClock, uint32 baudRate) +{ + uint32 registerSetting = ((masterClock * 10) / (baudRate * 16)); + + if ((registerSetting % 10) >= 5) + { + registerSetting = (registerSetting / 10) + 1; + } + else + { + registerSetting /= 10; + } + + return (uint8)registerSetting; +} diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartBaudRateRegisterCalculator.h b/tests/e2e/v0.31/temp_sensor/src/UsartBaudRateRegisterCalculator.h new file mode 100644 index 0000000..70cd118 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartBaudRateRegisterCalculator.h @@ -0,0 +1,8 @@ +#ifndef _USARTBAUDRATEREGISTERCALCULATOR_H +#define _USARTBAUDRATEREGISTERCALCULATOR_H + +#include "Types.h" + +uint8 UsartModel_CalculateBaudRateRegisterSetting(uint32 masterClock, uint32 baudRate); + +#endif // _USARTBAUDRATEREGISTERCALCULATOR_H diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartConductor.c b/tests/e2e/v0.31/temp_sensor/src/UsartConductor.c new file mode 100644 index 0000000..3eeec3c --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartConductor.c @@ -0,0 +1,21 @@ +#include "Types.h" +#include "UsartConductor.h" +#include "UsartHardware.h" +#include "UsartModel.h" +#include "TaskScheduler.h" + +void UsartConductor_Init(void) +{ + UsartHardware_Init(UsartModel_GetBaudRateRegisterSetting()); + UsartHardware_TransmitString(UsartModel_GetWakeupMessage()); +} + +void UsartConductor_Run(void) +{ + char* temp; + if (TaskScheduler_DoUsart()) + { + temp = UsartModel_GetFormattedTemperature(); + UsartHardware_TransmitString(temp); + } +} diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartConductor.h b/tests/e2e/v0.31/temp_sensor/src/UsartConductor.h new file mode 100644 index 0000000..f420736 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartConductor.h @@ -0,0 +1,7 @@ +#ifndef _USARTCONDUCTOR_H +#define _USARTCONDUCTOR_H + +void UsartConductor_Init(void); +void UsartConductor_Run(void); + +#endif // _USARTCONDUCTOR_H diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartConfigurator.c b/tests/e2e/v0.31/temp_sensor/src/UsartConfigurator.c new file mode 100644 index 0000000..b8c2cdc --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartConfigurator.c @@ -0,0 +1,39 @@ +#include "Types.h" +#include "UsartConfigurator.h" + +void Usart_ConfigureUsartIO(void) +{ + AT91C_BASE_PIOA->PIO_ASR = USART0_TX_PIN; + AT91C_BASE_PIOA->PIO_BSR = 0; + AT91C_BASE_PIOA->PIO_PDR = USART0_TX_PIN; +} + +void Usart_EnablePeripheralClock(void) +{ + AT91C_BASE_PMC->PMC_PCER = ((uint32)1) << USART0_CLOCK_ENABLE; +} + +void Usart_Reset(void) +{ + AT91C_BASE_US0->US_IDR = 0xffffffff; + AT91C_BASE_US0->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS; +} + +void Usart_ConfigureMode(void) +{ + AT91C_BASE_US0->US_MR = AT91C_US_USMODE_NORMAL | + AT91C_US_NBSTOP_1_BIT | + AT91C_US_PAR_NONE | + AT91C_US_CHRL_8_BITS | + AT91C_US_CLKS_CLOCK; +} + +void Usart_SetBaudRateRegister(uint8 baudRateRegisterSetting) +{ + AT91C_BASE_US0->US_BRGR = baudRateRegisterSetting; +} + +void Usart_Enable(void) +{ + AT91C_BASE_US0->US_CR = AT91C_US_TXEN; +} diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartConfigurator.h b/tests/e2e/v0.31/temp_sensor/src/UsartConfigurator.h new file mode 100644 index 0000000..02bede2 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartConfigurator.h @@ -0,0 +1,13 @@ +#ifndef _USARTCONFIGURATOR_H +#define _USARTCONFIGURATOR_H + +#include "Types.h" + +void Usart_ConfigureUsartIO(void); +void Usart_EnablePeripheralClock(void); +void Usart_Reset(void); +void Usart_ConfigureMode(void); +void Usart_SetBaudRateRegister(uint8 baudRateRegisterSetting); +void Usart_Enable(void); + +#endif // _USARTCONFIGURATOR_H diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartHardware.c b/tests/e2e/v0.31/temp_sensor/src/UsartHardware.c new file mode 100644 index 0000000..e37c2c6 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartHardware.c @@ -0,0 +1,22 @@ +#include "Types.h" +#include "UsartHardware.h" +#include "UsartConfigurator.h" +#include "UsartPutChar.h" + +void UsartHardware_Init(uint8 baudRateRegisterSetting) +{ + Usart_ConfigureUsartIO(); + Usart_EnablePeripheralClock(); + Usart_Reset(); + Usart_ConfigureMode(); + Usart_SetBaudRateRegister(baudRateRegisterSetting); + Usart_Enable(); +} + +void UsartHardware_TransmitString(char* data) +{ + while(*data != NULL) + { + Usart_PutChar(*data++); + } +} diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartHardware.h b/tests/e2e/v0.31/temp_sensor/src/UsartHardware.h new file mode 100644 index 0000000..041e280 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartHardware.h @@ -0,0 +1,9 @@ +#ifndef _USARTHARDWARE_H +#define _USARTHARDWARE_H + +#include "Types.h" + +void UsartHardware_Init(uint8 baudRateRegisterSetting); +void UsartHardware_TransmitString(char* data); + +#endif // _USARTHARDWARE_H diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartModel.c b/tests/e2e/v0.31/temp_sensor/src/UsartModel.c new file mode 100644 index 0000000..d722a2f --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartModel.c @@ -0,0 +1,34 @@ +#include "Types.h" +#include "UsartModel.h" +#include "ModelConfig.h" +#include "UsartBaudRateRegisterCalculator.h" +#include "TemperatureFilter.h" +#include +#include + +char formattedTemperature[32]; +char* wakeup = "It's Awesome Time!\n"; + +uint8 UsartModel_GetBaudRateRegisterSetting(void) +{ + return UsartModel_CalculateBaudRateRegisterSetting(MASTER_CLOCK, USART0_BAUDRATE); +} + +char* UsartModel_GetFormattedTemperature(void) +{ + float temperature = TemperatureFilter_GetTemperatureInCelcius(); + if (temperature == -INFINITY) + { + sprintf(formattedTemperature, "%s", "Temperature sensor failure!\n"); + } + else + { + sprintf(formattedTemperature, "%.1f C\n", temperature); + } + return formattedTemperature; +} + +char* UsartModel_GetWakeupMessage(void) +{ + return wakeup; +} diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartModel.h b/tests/e2e/v0.31/temp_sensor/src/UsartModel.h new file mode 100644 index 0000000..7d94854 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartModel.h @@ -0,0 +1,10 @@ +#ifndef _USARTMODEL_H +#define _USARTMODEL_H + +#include "Types.h" + +uint8 UsartModel_GetBaudRateRegisterSetting(void); +char* UsartModel_GetFormattedTemperature(void); +char* UsartModel_GetWakeupMessage(void); + +#endif // _USARTMODEL_H diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartPutChar.c b/tests/e2e/v0.31/temp_sensor/src/UsartPutChar.c new file mode 100644 index 0000000..9e3ce2c --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartPutChar.c @@ -0,0 +1,16 @@ +#include "Types.h" +#include "UsartPutChar.h" +#include "UsartTransmitBufferStatus.h" +#ifdef SIMULATE +#include +#endif + +void Usart_PutChar(char data) +{ + while(!Usart_ReadyToTransmit()); +#ifdef SIMULATE + printf("%c", data); +#else + AT91C_BASE_US0->US_THR = data; +#endif +} diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartPutChar.h b/tests/e2e/v0.31/temp_sensor/src/UsartPutChar.h new file mode 100644 index 0000000..924446a --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartPutChar.h @@ -0,0 +1,8 @@ +#ifndef _USARTPUT_HAR_H +#define _USARTPUT_HAR_H + +#include "Types.h" + +void Usart_PutChar(char data); + +#endif // _USARTPUT_HAR_H diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartTransmitBufferStatus.c b/tests/e2e/v0.31/temp_sensor/src/UsartTransmitBufferStatus.c new file mode 100644 index 0000000..914b2e1 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartTransmitBufferStatus.c @@ -0,0 +1,7 @@ +#include "Types.h" +#include "UsartTransmitBufferStatus.h" + +bool Usart_ReadyToTransmit(void) +{ + return (AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY) > 0; +} diff --git a/tests/e2e/v0.31/temp_sensor/src/UsartTransmitBufferStatus.h b/tests/e2e/v0.31/temp_sensor/src/UsartTransmitBufferStatus.h new file mode 100644 index 0000000..b5925ba --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/src/UsartTransmitBufferStatus.h @@ -0,0 +1,8 @@ +#ifndef _USARTTRANSMITBUFFERSTATUS_H +#define _USARTTRANSMITBUFFERSTATUS_H + +#include "Types.h" + +bool Usart_ReadyToTransmit(void); + +#endif // _USARTTRANSMITBUFFERSTATUS_H diff --git a/tests/e2e/v0.31/temp_sensor/test/TestAdcConductor.c b/tests/e2e/v0.31/temp_sensor/test/TestAdcConductor.c new file mode 100644 index 0000000..a15d7d1 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestAdcConductor.c @@ -0,0 +1,121 @@ +#include "unity.h" +#include "UnityHelper.h" +#include "Types.h" +#include "Types.h" +#include "AdcConductor.h" +#include "MockAdcModel.h" +#include "MockAdcHardware.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldCallHardwareInit(void) +{ + AdcHardware_Init_Expect(); + AdcConductor_Init(); +} + +void testRunShouldNotDoAnythingIfItIsNotTime(void) +{ + AdcModel_DoGetSample_ExpectAndReturn(FALSE); + + AdcConductor_Run(); +} + +void testRunShouldNotPassAdcResultToModelIfSampleIsNotComplete(void) +{ + AdcModel_DoGetSample_ExpectAndReturn(TRUE); + AdcHardware_GetSampleComplete_ExpectAndReturn(FALSE); + + AdcConductor_Run(); +} + +void testRunShouldGetLatestSampleFromAdcAndPassItToModelAndStartNewConversionWhenItIsTime(void) +{ + AdcModel_DoGetSample_ExpectAndReturn(TRUE); + AdcHardware_GetSampleComplete_ExpectAndReturn(TRUE); + AdcHardware_GetSample_ExpectAndReturn(293U); + AdcModel_ProcessInput_Expect(293U); + AdcHardware_StartConversion_Expect(); + + AdcConductor_Run(); +} + +void testJustHereToTest_Should_ProperlyPassAStructAndVerifyIt(void) +{ + EXAMPLE_STRUCT_T TestStruct; + TestStruct.x = 5; + TestStruct.y = 7; + + AdcModel_DoNothingExceptTestASpecialType_ExpectAndReturn(TestStruct, TRUE); + + TEST_ASSERT_TRUE(AdcConductor_JustHereToTest()); +} + +//void testJustHereToTest_Should_FailThisTestIfYouUncommentXIsBecauseItsWrong(void) +//{ +// EXAMPLE_STRUCT_T TestStruct; +// TestStruct.x = 6; +// TestStruct.y = 7; +// +// AdcModel_DoNothingExceptTestASpecialType_ExpectAndReturn(TestStruct, TRUE); +// +// TEST_ASSERT_TRUE(AdcConductor_JustHereToTest()); +//} +// +//void testJustHereToTest_Should_FailThisTestIfYouUncommentYIsBecauseItsWrong(void) +//{ +// EXAMPLE_STRUCT_T TestStruct; +// TestStruct.x = 5; +// TestStruct.y = 8; +// +// AdcModel_DoNothingExceptTestASpecialType_ExpectAndReturn(TestStruct, TRUE); +// +// TEST_ASSERT_TRUE(AdcConductor_JustHereToTest()); +//} + +void test_AdcConductor_AlsoHereToTest_Should_ProperlyReturnAStructAsExpected1(void) +{ + EXAMPLE_STRUCT_T TestStruct; + TestStruct.x = 99; + TestStruct.y = 1; + + AdcModel_DoNothingExceptReturnASpecialType_ExpectAndReturn(TestStruct); + + TEST_ASSERT_TRUE(AdcConductor_AlsoHereToTest()); +} + +void test_AdcConductor_AlsoHereToTest_Should_ProperlyReturnAStructAsExpected2(void) +{ + EXAMPLE_STRUCT_T TestStruct; + TestStruct.x = 98; + TestStruct.y = 1; + + AdcModel_DoNothingExceptReturnASpecialType_ExpectAndReturn(TestStruct); + + TEST_ASSERT_FALSE(AdcConductor_AlsoHereToTest()); +} + +void test_AdcConductor_YetAnotherTest_Should_VerifyThatPointersToStructsAreTestable(void) +{ + uint32 TestNum = 3; + + AdModel_DoNothingExceptTestPointers_ExpectAndReturn(&TestNum, TRUE); + + TEST_ASSERT_TRUE(AdcConductor_YetAnotherTest()); +} + +//void test_AdcConductor_YetAnotherTest_Should_FailIfYouUncommentThisTestBecauseTheValuePointedToIsWrong(void) +//{ +// uint32 TestNum = 7; +// +// AdModel_DoNothingExceptTestPointers_ExpectAndReturn(&TestNum, FALSE); +// +// TEST_ASSERT_FALSE(AdcConductor_YetAnotherTest()); +//} + diff --git a/tests/e2e/v0.31/temp_sensor/test/TestAdcHardware.c b/tests/e2e/v0.31/temp_sensor/test/TestAdcHardware.c new file mode 100644 index 0000000..7aabaa7 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestAdcHardware.c @@ -0,0 +1,44 @@ +#include "unity.h" +#include "Types.h" +#include "AdcHardware.h" +#include "MockAdcHardwareConfigurator.h" +#include "MockAdcTemperatureSensor.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldDelegateToConfiguratorAndTemperatureSensor(void) +{ + Adc_Reset_Expect(); + Adc_ConfigureMode_Expect(); + Adc_EnableTemperatureChannel_Expect(); + Adc_StartTemperatureSensorConversion_Expect(); + + AdcHardware_Init(); +} + +void testGetSampleCompleteShouldReturn_FALSE_WhenTemperatureSensorSampleReadyReturns_FALSE(void) +{ + Adc_TemperatureSensorSampleReady_ExpectAndReturn(FALSE); + TEST_ASSERT(!AdcHardware_GetSampleComplete()); +} + +void testGetSampleCompleteShouldReturn_TRUE_WhenTemperatureSensorSampleReadyReturns_TRUE(void) +{ + Adc_TemperatureSensorSampleReady_ExpectAndReturn(TRUE); + TEST_ASSERT(AdcHardware_GetSampleComplete()); +} + +void testGetSampleShouldDelegateToAdcTemperatureSensor(void) +{ + uint16 sample; + Adc_ReadTemperatureSensor_ExpectAndReturn(847); + + sample = AdcHardware_GetSample(); + TEST_ASSERT_EQUAL(847, sample); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestAdcModel.c b/tests/e2e/v0.31/temp_sensor/test/TestAdcModel.c new file mode 100644 index 0000000..f1dcb4a --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestAdcModel.c @@ -0,0 +1,33 @@ +#include "unity.h" +#include "Types.h" +#include "AdcModel.h" +#include "MockTaskScheduler.h" +#include "MockTemperatureCalculator.h" +#include "MockTemperatureFilter.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testDoGetSampleShouldReturn_FALSE_WhenTaskSchedulerReturns_FALSE(void) +{ + TaskScheduler_DoAdc_ExpectAndReturn(FALSE); + TEST_ASSERT_EQUAL(FALSE, AdcModel_DoGetSample()); +} + +void testDoGetSampleShouldReturn_TRUE_WhenTaskSchedulerReturns_TRUE(void) +{ + TaskScheduler_DoAdc_ExpectAndReturn(TRUE); + TEST_ASSERT_EQUAL(TRUE, AdcModel_DoGetSample()); +} + +void testProcessInputShouldDelegateToTemperatureCalculatorAndPassResultToFilter(void) +{ + TemperatureCalculator_Calculate_ExpectAndReturn(21473, 23.5f); + TemperatureFilter_ProcessInput_Expect(23.5f); + AdcModel_ProcessInput(21473); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestExecutor.c b/tests/e2e/v0.31/temp_sensor/test/TestExecutor.c new file mode 100644 index 0000000..8e48326 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestExecutor.c @@ -0,0 +1,36 @@ +#include "unity.h" +#include "Types.h" +#include "Executor.h" +#include "MockModel.h" +#include "MockUsartConductor.h" +#include "MockAdcConductor.h" +#include "MockTimerConductor.h" +#include "MockIntrinsicsWrapper.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldCallInitOfAllConductorsAndTheModel(void) +{ + Model_Init_Expect(); + UsartConductor_Init_Expect(); + AdcConductor_Init_Expect(); + TimerConductor_Init_Expect(); + Interrupt_Enable_Expect(); + + Executor_Init(); +} + +void testRunShouldCallRunForEachConductorAndReturnTrueAlways(void) +{ + UsartConductor_Run_Expect(); + TimerConductor_Run_Expect(); + AdcConductor_Run_Expect(); + + TEST_ASSERT_EQUAL(TRUE, Executor_Run()); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestMain.c b/tests/e2e/v0.31/temp_sensor/test/TestMain.c new file mode 100644 index 0000000..baf3382 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestMain.c @@ -0,0 +1,24 @@ +#include "unity.h" +#include "Types.h" +#include "MockExecutor.h" +#include "Main.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testMainShouldCallExecutorInitAndContinueToCallExecutorRunUntilHalted(void) +{ + Executor_Init_Expect(); + Executor_Run_ExpectAndReturn(TRUE); + Executor_Run_ExpectAndReturn(TRUE); + Executor_Run_ExpectAndReturn(TRUE); + Executor_Run_ExpectAndReturn(TRUE); + Executor_Run_ExpectAndReturn(FALSE); + + AppMain(); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestModel.c b/tests/e2e/v0.31/temp_sensor/test/TestModel.c new file mode 100644 index 0000000..59dda1d --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestModel.c @@ -0,0 +1,20 @@ +#include "unity.h" +#include "Types.h" +#include "Model.h" +#include "MockTaskScheduler.h" +#include "MockTemperatureFilter.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldCallSchedulerAndTemperatureFilterInit(void) +{ + TaskScheduler_Init_Expect(); + TemperatureFilter_Init_Expect(); + Model_Init(); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestTaskScheduler.c b/tests/e2e/v0.31/temp_sensor/test/TestTaskScheduler.c new file mode 100644 index 0000000..29d1edf --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestTaskScheduler.c @@ -0,0 +1,104 @@ +#include "unity.h" +#include "Types.h" +#include "TaskScheduler.h" + +void setUp(void) +{ + TaskScheduler_Init(); +} + +void tearDown(void) +{ +} + +void testShouldScheduleUsartTaskAfter1000ms(void) +{ + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); + + TaskScheduler_Update(999); + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); + + TaskScheduler_Update(1000); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); +} + +void testShouldClearUsartDoFlagAfterReported(void) +{ + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); + TaskScheduler_Update(1000); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); +} + +void testShouldScheduleUsartTaskEvery1000ms(void) +{ + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); + + TaskScheduler_Update(1300); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); + + TaskScheduler_Update(2000); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); + + TaskScheduler_Update(3100); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); +} + +void testShouldScheduleUsartTaskOnlyOncePerPeriod(void) +{ + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); + TaskScheduler_Update(1000); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); + TaskScheduler_Update(1001); + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); + TaskScheduler_Update(1999); + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); + TaskScheduler_Update(2000); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); +} + +void testShouldScheduleAdcTaskAfter100ms(void) +{ + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); + + TaskScheduler_Update(99); + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); + + TaskScheduler_Update(100); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); +} + +void testShouldClearAdcDoFlagAfterReported(void) +{ + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); + TaskScheduler_Update(100); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); +} + +void testShouldScheduleAdcTaskEvery100ms(void) +{ + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); + + TaskScheduler_Update(121); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); + + TaskScheduler_Update(200); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); + + TaskScheduler_Update(356); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); +} + +void testShouldScheduleAdcTaskOnlyOncePerPeriod(void) +{ + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); + TaskScheduler_Update(100); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); + TaskScheduler_Update(101); + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); + TaskScheduler_Update(199); + TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); + TaskScheduler_Update(200); + TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestTemperatureCalculator.c b/tests/e2e/v0.31/temp_sensor/test/TestTemperatureCalculator.c new file mode 100644 index 0000000..e54fbbf --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestTemperatureCalculator.c @@ -0,0 +1,36 @@ +#include "unity.h" +#include "Types.h" +#include + +TEST_FILE("TemperatureCalculator.c") + +extern float TemperatureCalculator_Calculate(uint16_t val); + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testTemperatureCalculatorShouldCalculateTemperatureFromMillivolts(void) +{ + float result; + + // Series resistor is 5k Ohms; Reference voltage is 3.0V + // R(t) = A * e^(B*t); R is resistance of thermisor; t is temperature in C + result = TemperatureCalculator_Calculate(1000); + TEST_ASSERT_FLOAT_WITHIN(0.01f, 25.0f, result); + + result = TemperatureCalculator_Calculate(2985); + TEST_ASSERT_FLOAT_WITHIN(0.01f, 68.317f, result); + + result = TemperatureCalculator_Calculate(3); + TEST_ASSERT_FLOAT_WITHIN(0.01f, -19.96f, result); +} + +void testShouldReturnNegativeInfinityWhen_0_millivoltsInput(void) +{ + TEST_ASSERT_FLOAT_IS_NEG_INF(TemperatureCalculator_Calculate(0)); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestTemperatureFilter.c b/tests/e2e/v0.31/temp_sensor/test/TestTemperatureFilter.c new file mode 100644 index 0000000..4d34f5d --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestTemperatureFilter.c @@ -0,0 +1,79 @@ +#include "unity.h" +#include "Types.h" +#include "TemperatureFilter.h" +#include + +void setUp(void) +{ + TemperatureFilter_Init(); +} + +void tearDown(void) +{ +} + +void testShouldInitializeTemeratureToInvalidValue(void) +{ + TemperatureFilter_Init(); + TEST_ASSERT_FLOAT_IS_NEG_INF(TemperatureFilter_GetTemperatureInCelcius()); +} + +void testShouldInitializeTemperatureAfterCallToInit(void) +{ + TemperatureFilter_Init(); + TemperatureFilter_ProcessInput(17.8f); + TEST_ASSERT_FLOAT_WITHIN(0.0001f, 17.8f, TemperatureFilter_GetTemperatureInCelcius()); + + TemperatureFilter_Init(); + TemperatureFilter_ProcessInput(32.6f); + TEST_ASSERT_FLOAT_WITHIN(0.0001f, 32.6f, TemperatureFilter_GetTemperatureInCelcius()); +} + +void setValueAndVerifyResponse(float input, float response) +{ + float actual; + TemperatureFilter_ProcessInput(input); + actual = TemperatureFilter_GetTemperatureInCelcius(); + + if (input == +INFINITY || + input == -INFINITY || + isnan(input)) + { + TEST_ASSERT_FLOAT_IS_NEG_INF(actual); + } + else + { + TEST_ASSERT_FLOAT_WITHIN(0.0001f, response, actual); + } +} + +void testShouldWeightEachSubsequentValueBy25PercentAfterInitialValue(void) +{ + TemperatureFilter_Init(); + setValueAndVerifyResponse(0.0f, 0.0f); + setValueAndVerifyResponse(10.0f, 2.5f); + setValueAndVerifyResponse(10.0f, 4.375f); + setValueAndVerifyResponse(10.0f, 5.78125f); + + TemperatureFilter_Init(); + setValueAndVerifyResponse(100.0f, 100.0f); + setValueAndVerifyResponse(0.0f, 75.0f); + setValueAndVerifyResponse(0.0f, 56.25f); + setValueAndVerifyResponse(0.0f, 42.1875f); +} + +void setInvalidTemperatureAndVerifyReinitialized(float invalidTemperature) +{ + TemperatureFilter_Init(); + setValueAndVerifyResponse(100.0f, 100.0f); + setValueAndVerifyResponse(invalidTemperature, -INFINITY); + setValueAndVerifyResponse(14.3f, 14.3f); +} + +void testShouldResetAverageIfPassedInfinityOrInvalidValue(void) +{ + setInvalidTemperatureAndVerifyReinitialized(-INFINITY); + setInvalidTemperatureAndVerifyReinitialized(+INFINITY); + setInvalidTemperatureAndVerifyReinitialized(+NAN); + setInvalidTemperatureAndVerifyReinitialized(-NAN); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestTimerConductor.c b/tests/e2e/v0.31/temp_sensor/test/TestTimerConductor.c new file mode 100644 index 0000000..8064a8c --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestTimerConductor.c @@ -0,0 +1,32 @@ +#include "unity.h" +#include "Types.h" +#include "TimerConductor.h" +#include "MockTimerHardware.h" +#include "MockTimerModel.h" +#include "MockTimerInterruptHandler.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldCallHardwareInit(void) +{ + TimerHardware_Init_Expect(); + + TimerConductor_Init(); +} + +void testRunShouldGetSystemTimeAndPassOnToModelForEventScheduling(void) +{ + Timer_GetSystemTime_ExpectAndReturn(1230); + TimerModel_UpdateTime_Expect(1230); + TimerConductor_Run(); + + Timer_GetSystemTime_ExpectAndReturn(837460); + TimerModel_UpdateTime_Expect(837460); + TimerConductor_Run(); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestTimerHardware.c b/tests/e2e/v0.31/temp_sensor/test/TestTimerHardware.c new file mode 100644 index 0000000..16339d0 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestTimerHardware.c @@ -0,0 +1,26 @@ +#include "unity.h" +#include "Types.h" +#include "TimerHardware.h" +#include "MockTimerConfigurator.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldDelegateAppropriatelyToConfigurator(void) +{ + Timer_EnablePeripheralClocks_Expect(); + Timer_Reset_Expect(); + Timer_ConfigureMode_Expect(); + Timer_ConfigurePeriod_Expect(); + Timer_EnableOutputPin_Expect(); + Timer_Enable_Expect(); + Timer_ConfigureInterruptHandler_Expect(); + Timer_Start_Expect(); + + TimerHardware_Init(); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestTimerModel.c b/tests/e2e/v0.31/temp_sensor/test/TestTimerModel.c new file mode 100644 index 0000000..e92a96a --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestTimerModel.c @@ -0,0 +1,18 @@ +#include "unity.h" +#include "Types.h" +#include "TimerModel.h" +#include "MockTaskScheduler.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testUpdateTimeShouldDelegateToTaskScheduler(void) +{ + TaskScheduler_Update_Expect(19387L); + TimerModel_UpdateTime(19387L); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestUsartBaudRateRegisterCalculator.c b/tests/e2e/v0.31/temp_sensor/test/TestUsartBaudRateRegisterCalculator.c new file mode 100644 index 0000000..08dc045 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestUsartBaudRateRegisterCalculator.c @@ -0,0 +1,21 @@ +#include "unity.h" +#include "Types.h" +#include "UsartBaudRateRegisterCalculator.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testCalculateBaudRateRegisterSettingShouldCalculateRegisterSettingAppropriately(void) +{ + // BaudRate = MCK / (CD x 16) - per datasheet section 30.6.1.2 "Baud Rate Calculation Example" + TEST_ASSERT_EQUAL(26, UsartModel_CalculateBaudRateRegisterSetting(48000000, 115200)); + TEST_ASSERT_EQUAL(6, UsartModel_CalculateBaudRateRegisterSetting(3686400, 38400)); + TEST_ASSERT_EQUAL(23, UsartModel_CalculateBaudRateRegisterSetting(14318180, 38400)); + TEST_ASSERT_EQUAL(20, UsartModel_CalculateBaudRateRegisterSetting(12000000, 38400)); + TEST_ASSERT_EQUAL(13, UsartModel_CalculateBaudRateRegisterSetting(12000000, 56800)); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestUsartConductor.c b/tests/e2e/v0.31/temp_sensor/test/TestUsartConductor.c new file mode 100644 index 0000000..e23ef77 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestUsartConductor.c @@ -0,0 +1,40 @@ +#include "unity.h" +#include "Types.h" +#include "UsartConductor.h" +#include "MockUsartModel.h" +#include "MockUsartHardware.h" +#include "MockTaskScheduler.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testShouldInitializeHardwareWhenInitCalled(void) +{ + UsartModel_GetBaudRateRegisterSetting_ExpectAndReturn(4); + UsartHardware_Init_Expect(4); + UsartModel_GetWakeupMessage_ExpectAndReturn("Hey there!"); + UsartHardware_TransmitString_Expect("Hey there!"); + + UsartConductor_Init(); +} + +void testRunShouldNotDoAnythingIfSchedulerSaysItIsNotTimeYet(void) +{ + TaskScheduler_DoUsart_ExpectAndReturn(FALSE); + + UsartConductor_Run(); +} + +void testRunShouldGetCurrentTemperatureAndTransmitIfSchedulerSaysItIsTime(void) +{ + TaskScheduler_DoUsart_ExpectAndReturn(TRUE); + UsartModel_GetFormattedTemperature_ExpectAndReturn("hey there"); + UsartHardware_TransmitString_Expect("hey there"); + + UsartConductor_Run(); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestUsartHardware.c b/tests/e2e/v0.31/temp_sensor/test/TestUsartHardware.c new file mode 100644 index 0000000..5e8df75 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestUsartHardware.c @@ -0,0 +1,36 @@ +#include "unity.h" +#include "Types.h" +#include "UsartHardware.h" +#include "MockUsartConfigurator.h" +#include "MockUsartPutChar.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldConfigureUsartPeripheralByCallingConfiguratorAppropriately(void) +{ + Usart_ConfigureUsartIO_Expect(); + Usart_EnablePeripheralClock_Expect(); + Usart_Reset_Expect(); + Usart_ConfigureMode_Expect(); + Usart_SetBaudRateRegister_Expect(73); + Usart_Enable_Expect(); + + UsartHardware_Init(73); +} + +void testTransmitStringShouldSendDesiredStringOutUsingUsart(void) +{ + Usart_PutChar_Expect('h'); + Usart_PutChar_Expect('e'); + Usart_PutChar_Expect('l'); + Usart_PutChar_Expect('l'); + Usart_PutChar_Expect('o'); + + UsartHardware_TransmitString("hello"); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/TestUsartModel.c b/tests/e2e/v0.31/temp_sensor/test/TestUsartModel.c new file mode 100644 index 0000000..6ab23bc --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/TestUsartModel.c @@ -0,0 +1,40 @@ +#include "unity.h" +#include "Types.h" +#include "UsartModel.h" +#include "ModelConfig.h" +#include "MockTemperatureFilter.h" +#include "MockUsartBaudRateRegisterCalculator.h" +#include + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testGetBaudRateRegisterSettingShouldReturnAppropriateBaudRateRegisterSetting(void) +{ + uint8 dummyRegisterSetting = 17; + UsartModel_CalculateBaudRateRegisterSetting_ExpectAndReturn(MASTER_CLOCK, USART0_BAUDRATE, dummyRegisterSetting); + + TEST_ASSERT_EQUAL(dummyRegisterSetting, UsartModel_GetBaudRateRegisterSetting()); +} + +void testGetFormattedTemperatureFormatsTemperatureFromCalculatorAppropriately(void) +{ + TemperatureFilter_GetTemperatureInCelcius_ExpectAndReturn(25.0f); + TEST_ASSERT_EQUAL_STRING("25.0 C\n", UsartModel_GetFormattedTemperature()); +} + +void testShouldReturnErrorMessageUponInvalidTemperatureValue(void) +{ + TemperatureFilter_GetTemperatureInCelcius_ExpectAndReturn(-INFINITY); + TEST_ASSERT_EQUAL_STRING("Temperature sensor failure!\n", UsartModel_GetFormattedTemperature()); +} + +void testShouldReturnWakeupMessage(void) +{ + TEST_ASSERT_EQUAL_STRING("It's Awesome Time!\n", UsartModel_GetWakeupMessage()); +} diff --git a/tests/e2e/v0.31/temp_sensor/test/support/.gitkeep b/tests/e2e/v0.31/temp_sensor/test/support/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/e2e/v0.31/temp_sensor/test/support/UnityHelper.c b/tests/e2e/v0.31/temp_sensor/test/support/UnityHelper.c new file mode 100644 index 0000000..e60521f --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/support/UnityHelper.c @@ -0,0 +1,12 @@ +#include "unity.h" +#include "unity_internals.h" +#include "UnityHelper.h" + +#if 0 +void AssertEqualMyDataType(const MyDataType_T expected, const MyDataType_T actual, const unsigned short line) +{ + UNITY_TEST_ASSERT_EQUAL_INT(expected.length, actual.length, line, "MyDataType_T.length check failed"); + UNITY_TEST_ASSERT_EQUAL_MEMORY(expected.buffer, actual.buffer, expected.length, line, "MyDataType_T.buffer check failed"); +} +#endif + diff --git a/tests/e2e/v0.31/temp_sensor/test/support/UnityHelper.h b/tests/e2e/v0.31/temp_sensor/test/support/UnityHelper.h new file mode 100644 index 0000000..81667a3 --- /dev/null +++ b/tests/e2e/v0.31/temp_sensor/test/support/UnityHelper.h @@ -0,0 +1,12 @@ +#ifndef _TESTHELPER_H +#define _TESTHELPER_H + +// #include "MyTypes.h" + +#if 0 +void AssertEqualMyDataType(const MyDataType_T expected, const MyDataType_T actual, const unsigned short line); + +#define UNITY_TEST_ASSERT_EQUAL_MyDataType_T(expected, actual, line, message) {AssertEqualMyDataType(expected, actual, line);} +#endif + +#endif // _TESTHELPER_H diff --git a/tests/e2e/v1.0/.ruby-version b/tests/e2e/v1.0/.ruby-version new file mode 100644 index 0000000..2aa5131 --- /dev/null +++ b/tests/e2e/v1.0/.ruby-version @@ -0,0 +1 @@ +3.4.7 diff --git a/tests/e2e/v1.0/temp_sensor/.vscode/launch.json b/tests/e2e/v1.0/temp_sensor/.vscode/launch.json new file mode 100644 index 0000000..1f1b7a9 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "configurations": [ + { + "name": "Ceedling Test Explorer Debug", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/test/out/${command:ceedlingExplorer.debugTestExecutable}", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + }, + ] +} diff --git a/tests/e2e/v1.0/temp_sensor/.vscode/settings.json b/tests/e2e/v1.0/temp_sensor/.vscode/settings.json new file mode 100644 index 0000000..5d3dcb2 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "ceedlingExplorer.debugConfiguration": "Ceedling Test Explorer Debug" +} diff --git a/tests/e2e/v1.0/temp_sensor/README.md b/tests/e2e/v1.0/temp_sensor/README.md new file mode 100644 index 0000000..b455741 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/README.md @@ -0,0 +1,18 @@ +# Ceedling Temp-Sensor Example + +*Welcome to the Temp-Sensor Example!* This is a medium-sized example of how Ceedling +might work in your system. You can use it to verify you have all the tools installed. +You can use it as a starting point for your own code. You can build upon it for your +own creations, though honestly it's a bit of a mess. While it has some good ideas in +it, really it serves as a testing ground for some of Ceedling's features, and a place +for you to explore how Ceedling works. + +You'll find all the source files in the `src` folder. You'll find all the tests in +(you guessed it) the `test` folder (and its sub-folders). There are also some files +in the `test/support` folder, which demonstrate how you can create your own assertions. + +This project assumes you have `gcov` and `gcovr` installed for collecting coverage +information. If that's not true, you can just remove the `gcov` plugin from the +`plugins` list. Everything else will work fine. + +Have fun poking around! diff --git a/tests/e2e/v1.0/temp_sensor/mixin/add_gcov.yml b/tests/e2e/v1.0/temp_sensor/mixin/add_gcov.yml new file mode 100644 index 0000000..1a60bf1 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/mixin/add_gcov.yml @@ -0,0 +1,51 @@ +# ========================================================================= +# Ceedling - Test-Centered Build System for C +# ThrowTheSwitch.org +# Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams +# SPDX-License-Identifier: MIT +# ========================================================================= + +--- + +# Enable gcov plugin +:plugins: + :enabled: + - gcov + +# Add -gcov to the plugins list to make sure of the gcov plugin +# You will need to have gcov and gcovr both installed to make it work. +# For more information on these options, see docs in plugins/gcov +:gcov: + :utilities: + - gcovr # Use gcovr to create the specified reports (default). + #- ReportGenerator # Use ReportGenerator to create the specified reports. + :reports: # Specify one or more reports to generate. + # Make an HTML summary report. + # - HtmlBasic + - HtmlDetailed + # - Text + # - Cobertura + # - SonarQube + # - JSON + # - HtmlInline + # - HtmlInlineAzure + # - HtmlInlineAzureDark + # - HtmlChart + # - MHtml + # - Badges + # - CsvSummary + # - Latex + # - LatexSummary + # - PngChart + # - TeamCitySummary + # - lcov + # - Xml + # - XmlSummary + :gcovr: + # :html_artifact_filename: TestCoverageReport.html + # :html_title: Test Coverage Report + :html_medium_threshold: 75 + :html_high_threshold: 90 + # :html_absolute_paths: TRUE + # :html_encoding: UTF-8 +... diff --git a/tests/e2e/v1.0/temp_sensor/mixin/add_unity_helper.yml b/tests/e2e/v1.0/temp_sensor/mixin/add_unity_helper.yml new file mode 100644 index 0000000..74069f4 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/mixin/add_unity_helper.yml @@ -0,0 +1,26 @@ +# ========================================================================= +# Ceedling - Test-Centered Build System for C +# ThrowTheSwitch.org +# Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams +# SPDX-License-Identifier: MIT +# ========================================================================= + +--- + +# Enable the unity helper's define to enable our custom assertion +:defines: + :test: + '*': + - TEST # Simple list option to add symbol 'TEST' to compilation of all files in all test executables + - TEST_CUSTOM_EXAMPLE_STRUCT_T + 'TestUsartIntegrated.c': + - TEST + - TEST_CUSTOM_EXAMPLE_STRUCT_T + - TEST_USART_INTEGRATED_STRING=\"It's Awesome Time!\n\" + :release: [] + +# Add the unity helper configuration to cmock +:cmock: + :unity_helper_path: + - test/support/UnityHelper.h +... diff --git a/tests/e2e/v1.0/temp_sensor/project.yml b/tests/e2e/v1.0/temp_sensor/project.yml new file mode 100644 index 0000000..e34c8d1 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/project.yml @@ -0,0 +1,355 @@ +# ========================================================================= +# Ceedling - Test-Centered Build System for C +# ThrowTheSwitch.org +# Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams +# SPDX-License-Identifier: MIT +# ========================================================================= + +--- +:project: + # how to use ceedling. If you're not sure, leave this as `gem` and `?` + :which_ceedling: gem + :ceedling_version: '?' + + # optional features. If you don't need them, keep them turned off for performance + :use_mocks: TRUE + :use_test_preprocessor: :all # options are :none, :mocks, :tests, or :all + :use_deep_preprocessor: :none # options are :none, :mocks, :tests, or :all + :use_backtrace: :none # options are :none, :simple, or :gdb + :use_decorators: :auto # decorate Ceedling's output text. options are :auto, :all, or :none + + + # tweak the way ceedling handles automatic tasks + :build_root: build + :test_file_prefix: Test + :default_tasks: + - test:all + + # performance options. If your tools start giving mysterious errors, consider + # dropping this to 1 to force single-tasking + :test_threads: 8 + :compile_threads: 8 + + # enable release build (more details in release_build section below) + :release_build: FALSE + +# further details to configure the way Ceedling handles test code +:test_build: + :use_assembly: FALSE + +# further details to configure the way Ceedling handles release code +:release_build: + :output: MyApp.out + :use_assembly: FALSE + :artifacts: [] + +# Specify where to find mixins and any that should be enabled automatically +:mixins: + :enabled: [] + :load_paths: + - mixin + +# Plugins are optional Ceedling features which can be enabled. Ceedling supports +# a variety of plugins which may effect the way things are compiled, reported, +# or may provide new command options. Refer to the readme in each plugin for +# details on how to use it. +:plugins: + :load_paths: [] + :enabled: + #- beep # beeps when finished, so you don't waste time waiting for ceedling + - module_generator # handy for quickly creating source, header, and test templates + #- gcov # test coverage using gcov. Requires gcc, gcov, and a coverage analyzer like gcovr + #- bullseye # test coverage using bullseye. Requires bullseye for your platform + #- command_hooks # write custom actions to be called at different points during the build process + #- compile_commands_json_db # generate a compile_commands.json file + #- dependencies # automatically fetch 3rd party libraries, etc. + #- subprojects # managing builds and test for static libraries + #- fake_function_framework # use FFF instead of CMock + + # Report options (You'll want to choose one stdout option, but may choose multiple stored options if desired) + #- report_build_warnings_log + #- report_tests_gtestlike_stdout + #- report_tests_ide_stdout + - report_tests_log_factory + - report_tests_pretty_stdout + #- report_tests_raw_output_log + #- report_tests_teamcity_stdout + +# Specify which reports you'd like from the log factory +:report_tests_log_factory: + :reports: + - json + - junit + - cppunit + - html + +# override the default extensions for your system and toolchain +:extension: + #:header: .h + #:source: .c + #:assembly: .s + #:dependencies: .d + #:object: .o + :executable: .out + #:testpass: .pass + #:testfail: .fail + #:subprojects: .a + +# This is where Ceedling should look for your source and test files. +# see documentation for the many options for specifying this. +:paths: + :test: + - +:test/** + - -:test/support + :source: + - src/** + :include: + - src/** + :support: + - test/support + :libraries: [] + +# You can even specify specific files to add or remove from your test +# and release collections. Usually it's better to use paths and let +# Ceedling do the work for you! +:files: + :test: [] + :source: [] + +# Compilation symbols to be injected into builds +# See documentation for advanced options: +# - Test name matchers for different symbols per test executable build +# - Referencing symbols in multiple lists using advanced YAML +# - Specifiying symbols used during test preprocessing +:defines: + :test: + '*': + - TEST # Simple list option to add symbol 'TEST' to compilation of all files in all test executables + 'TestUsartIntegrated.c': + - TEST + - TEST_USART_INTEGRATED_STRING=\"It's Awesome Time!\n\" + :release: [] + + # Enable to inject name of a test as a unique compilation symbol into its respective executable build. + :use_test_definition: FALSE + +# Configure additional command line flags provided to tools used in each build step +:flags: + :test: + :compile: + :TemperatureCalculator: + - '-DSUPPLY_VOLTAGE=3.0' + +# Configuration Options specific to CMock. See CMock docs for details +:cmock: + :mock_prefix: Mock + :when_no_prototypes: :warn + :enforce_strict_ordering: TRUE + :plugins: + - :ignore + - :callback + :treat_as: + uint8: HEX8 + uint16: HEX16 + uint32: UINT32 + int8: INT8 + bool: UINT8 + +# You can optionally have ceedling create environment variables for you before +# performing the rest of its tasks. +:environment: [] +# :environment: +# # List enforces order allowing later to reference earlier with inline Ruby substitution +# - :var1: value +# - :var2: another value +# - :path: # Special PATH handling with platform-specific path separators +# - #{ENV['PATH']} # Environment variables can use inline Ruby substitution +# - /another/path/to/include + +# LIBRARIES +# These libraries are automatically injected into the build process. Those specified as +# common will be used in all types of builds. Otherwise, libraries can be injected in just +# tests or releases. These options are MERGED with the options in supplemental yaml files. +:libraries: + :placement: :end + :flag: "-l${1}" + :path_flag: "-L ${1}" + :system: + - m + :test: [] + :release: [] + +################################################################ +# PLUGIN CONFIGURATION +################################################################ + +# Add -gcov to the plugins list to make sure of the gcov plugin +# You will need to have gcov and gcovr both installed to make it work. +# For more information on these options, see docs in plugins/gcov +:gcov: + :utilities: + - gcovr # Use gcovr to create the specified reports (default). + #- ReportGenerator # Use ReportGenerator to create the specified reports. + :reports: # Specify one or more reports to generate. + # Make an HTML summary report. + - HtmlBasic + # - HtmlDetailed + # - Text + # - Cobertura + # - SonarQube + # - JSON + # - HtmlInline + # - HtmlInlineAzure + # - HtmlInlineAzureDark + # - HtmlChart + # - MHtml + # - Badges + # - CsvSummary + # - Latex + # - LatexSummary + # - PngChart + # - TeamCitySummary + # - lcov + # - Xml + # - XmlSummary + :gcovr: + # :html_artifact_filename: TestCoverageReport.html + # :html_title: Test Coverage Report + :html_medium_threshold: 75 + :html_high_threshold: 90 + # :html_absolute_paths: TRUE + # :html_encoding: UTF-8 + +# :module_generator: +# :naming: :snake #options: :bumpy, :camel, :caps, or :snake +# :includes: +# :tst: [] +# :src: []:module_generator: +# :boilerplates: +# :src: "" +# :inc: "" +# :tst: "" + +# :dependencies: +# :libraries: +# - :name: WolfSSL +# :source_path: third_party/wolfssl/source +# :build_path: third_party/wolfssl/build +# :artifact_path: third_party/wolfssl/install +# :fetch: +# :method: :zip +# :source: \\shared_drive\third_party_libs\wolfssl\wolfssl-4.2.0.zip +# :environment: +# - CFLAGS+=-DWOLFSSL_DTLS_ALLOW_FUTURE +# :build: +# - "autoreconf -i" +# - "./configure --enable-tls13 --enable-singlethreaded" +# - make +# - make install +# :artifacts: +# :static_libraries: +# - lib/wolfssl.a +# :dynamic_libraries: +# - lib/wolfssl.so +# :includes: +# - include/** + +# :subprojects: +# :paths: +# - :name: libprojectA +# :source: +# - ./subprojectA/source +# :include: +# - ./subprojectA/include +# :build_root: ./subprojectA/build +# :defines: [] + +# :command_hooks: +# :pre_mock_preprocess: +# :post_mock_preprocess: +# :pre_test_preprocess: +# :post_test_preprocess: +# :pre_mock_generate: +# :post_mock_generate: +# :pre_runner_generate: +# :post_runner_generate: +# :pre_compile_execute: +# :post_compile_execute: +# :pre_link_execute: +# :post_link_execute: +# :pre_test_fixture_execute: +# :post_test_fixture_execute: +# :pre_test: +# :post_test: +# :pre_release: +# :post_release: +# :pre_build: +# :post_build: +# :post_error: + +################################################################ +# TOOLCHAIN CONFIGURATION +################################################################ + + +#:tools: +# Ceedling defaults to using gcc for compiling, linking, etc. +# As [:tools] is blank, gcc will be used (so long as it's in your system path) +# See documentation to configure a given toolchain for use +# :tools: +# :test_compiler: +# :executable: +# :arguments: [] +# :name: +# :optional: FALSE +# :test_linker: +# :executable: +# :arguments: [] +# :name: +# :optional: FALSE +# :test_assembler: +# :executable: +# :arguments: [] +# :name: +# :optional: FALSE +# :test_fixture: +# :executable: +# :arguments: [] +# :name: +# :optional: FALSE +# :test_includes_preprocessor: +# :executable: +# :arguments: [] +# :name: +# :optional: FALSE +# :test_file_preprocessor: +# :executable: +# :arguments: [] +# :name: +# :optional: FALSE +# :test_file_preprocessor_directives: +# :executable: +# :arguments: [] +# :name: +# :optional: FALSE +# :release_compiler: +# :executable: +# :arguments: [] +# :name: +# :optional: FALSE +# :release_linker: +# :executable: +# :arguments: [] +# :name: +# :optional: FALSE +# :release_assembler: +# :executable: +# :arguments: [] +# :name: +# :optional: FALSE +# :release_dependencies_generator: +# :executable: +# :arguments: [] +# :name: +# :optional: FALSE +... diff --git a/tests/e2e/v1.0/temp_sensor/src/AdcConductor.c b/tests/e2e/v1.0/temp_sensor/src/AdcConductor.c new file mode 100644 index 0000000..323c4b7 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/AdcConductor.c @@ -0,0 +1,49 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "AdcConductor.h" +#include "AdcModel.h" +#include "AdcHardware.h" + +void AdcConductor_Init(void) +{ + AdcHardware_Init(); +} + +void AdcConductor_Run(void) +{ + if (AdcModel_DoGetSample() && AdcHardware_GetSampleComplete()) + { + AdcModel_ProcessInput(AdcHardware_GetSample()); + AdcHardware_StartConversion(); + } +} + +bool AdcConductor_JustHereToTest(void) +{ + EXAMPLE_STRUCT_T ExampleStruct; + ExampleStruct.x = 5; + ExampleStruct.y = 7; + + return AdcModel_DoNothingExceptTestASpecialType(ExampleStruct); +} + +bool AdcConductor_AlsoHereToTest(void) +{ + EXAMPLE_STRUCT_T example = AdcModel_DoNothingExceptReturnASpecialType(); + + return ((example.x == 99) && (example.y == 1)); +} + +bool AdcConductor_YetAnotherTest(void) +{ + uint32 example = 3; + + return AdModel_DoNothingExceptTestPointers(&example); +} + diff --git a/tests/e2e/v1.0/temp_sensor/src/AdcConductor.h b/tests/e2e/v1.0/temp_sensor/src/AdcConductor.h new file mode 100644 index 0000000..d4edf07 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/AdcConductor.h @@ -0,0 +1,20 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _ADCCONDUCTOR_H +#define _ADCCONDUCTOR_H + +#include "Types.h" + +void AdcConductor_Init(void); +void AdcConductor_Run(void); + +bool AdcConductor_JustHereToTest(void); +bool AdcConductor_AlsoHereToTest(void); +bool AdcConductor_YetAnotherTest(void); + +#endif // _ADCCONDUCTOR_H diff --git a/tests/e2e/v1.0/temp_sensor/src/AdcHardware.c b/tests/e2e/v1.0/temp_sensor/src/AdcHardware.c new file mode 100644 index 0000000..842ed13 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/AdcHardware.c @@ -0,0 +1,34 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "AdcHardware.h" +#include "AdcHardwareConfigurator.h" +#include "AdcTemperatureSensor.h" + +void AdcHardware_Init(void) +{ + Adc_Reset(); + Adc_ConfigureMode(); + Adc_EnableTemperatureChannel(); + Adc_StartTemperatureSensorConversion(); +} + +void AdcHardware_StartConversion(void) +{ + Adc_StartTemperatureSensorConversion(); +} + +bool AdcHardware_GetSampleComplete(void) +{ + return Adc_TemperatureSensorSampleReady(); +} + +uint16 AdcHardware_GetSample(void) +{ + return Adc_ReadTemperatureSensor(); +} diff --git a/tests/e2e/v1.0/temp_sensor/src/AdcHardware.h b/tests/e2e/v1.0/temp_sensor/src/AdcHardware.h new file mode 100644 index 0000000..1561237 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/AdcHardware.h @@ -0,0 +1,18 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _ADCHARDWARE_H +#define _ADCHARDWARE_H + +#include "Types.h" + +void AdcHardware_Init(void); +void AdcHardware_StartConversion(void); +bool AdcHardware_GetSampleComplete(void); +uint16 AdcHardware_GetSample(void); + +#endif // _ADCHARDWARE_H diff --git a/tests/e2e/v1.0/temp_sensor/src/AdcHardwareConfigurator.c b/tests/e2e/v1.0/temp_sensor/src/AdcHardwareConfigurator.c new file mode 100644 index 0000000..18183ca --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/AdcHardwareConfigurator.c @@ -0,0 +1,25 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "AdcHardwareConfigurator.h" +#include "ModelConfig.h" + +void Adc_Reset(void) +{ + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; +} + +void Adc_ConfigureMode(void) +{ + AT91C_BASE_ADC->ADC_MR = (((uint32)11) << 8) | (((uint32)4) << 16); +} + +void Adc_EnableTemperatureChannel(void) +{ + AT91C_BASE_ADC->ADC_CHER = 0x10; +} diff --git a/tests/e2e/v1.0/temp_sensor/src/AdcHardwareConfigurator.h b/tests/e2e/v1.0/temp_sensor/src/AdcHardwareConfigurator.h new file mode 100644 index 0000000..b237900 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/AdcHardwareConfigurator.h @@ -0,0 +1,17 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _ADCHARDWARECONFIGURATOR_H +#define _ADCHARDWARECONFIGURATOR_H + +#include "Types.h" + +void Adc_Reset(void); +void Adc_ConfigureMode(void); +void Adc_EnableTemperatureChannel(void); + +#endif // _ADCHARDWARECONFIGURATOR_H diff --git a/tests/e2e/v1.0/temp_sensor/src/AdcModel.c b/tests/e2e/v1.0/temp_sensor/src/AdcModel.c new file mode 100644 index 0000000..1bf6680 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/AdcModel.c @@ -0,0 +1,40 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "AdcModel.h" +#include "TaskScheduler.h" +#include "TemperatureCalculator.h" +#include "TemperatureFilter.h" + +bool AdcModel_DoGetSample(void) +{ + return TaskScheduler_DoAdc(); +} + +void AdcModel_ProcessInput(uint16 millivolts) +{ + TemperatureFilter_ProcessInput(TemperatureCalculator_Calculate(millivolts)); +} + +bool AdcModel_DoNothingExceptTestASpecialType(EXAMPLE_STRUCT_T ExampleStruct) +{ + //This doesn't really do anything. it's only here to make sure I can compare a struct. + return FALSE; +} +bool AdModel_DoNothingExceptTestPointers(uint32* pExample) +{ + //This doesn't really do anything. it's only here to make sure I can compare a pointer value. + return FALSE; +} + +EXAMPLE_STRUCT_T AdcModel_DoNothingExceptReturnASpecialType(void) +{ + EXAMPLE_STRUCT_T example; //again, this just is here to test that I can return a struct + example.x = 99; + example.y = 1; + return example; +} diff --git a/tests/e2e/v1.0/temp_sensor/src/AdcModel.h b/tests/e2e/v1.0/temp_sensor/src/AdcModel.h new file mode 100644 index 0000000..5cb6811 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/AdcModel.h @@ -0,0 +1,20 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _ADCMODEL_H +#define _ADCMODEL_H + +#include "Types.h" + +bool AdcModel_DoGetSample(void); +void AdcModel_ProcessInput(uint16 millivolts); + +bool AdcModel_DoNothingExceptTestASpecialType(EXAMPLE_STRUCT_T ExampleStruct); +bool AdModel_DoNothingExceptTestPointers(uint32* pExample); +EXAMPLE_STRUCT_T AdcModel_DoNothingExceptReturnASpecialType(void); + +#endif // _ADCMODEL_H diff --git a/tests/e2e/v1.0/temp_sensor/src/AdcTemperatureSensor.c b/tests/e2e/v1.0/temp_sensor/src/AdcTemperatureSensor.c new file mode 100644 index 0000000..487b08e --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/AdcTemperatureSensor.c @@ -0,0 +1,58 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "AdcTemperatureSensor.h" + +static inline uint32 ConvertAdcCountsToPicovolts(uint32 counts); +static inline uint16 ConvertPicovoltsToMillivolts(uint32 picovolts); + +// +// PUBLIC METHODS +// + +void Adc_StartTemperatureSensorConversion(void) +{ + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; +} + +bool Adc_TemperatureSensorSampleReady(void) +{ + return ((AT91C_BASE_ADC->ADC_SR & AT91C_ADC_EOC4) == AT91C_ADC_EOC4); +} + +uint16 Adc_ReadTemperatureSensor(void) +{ + uint32 picovolts = ConvertAdcCountsToPicovolts(AT91C_BASE_ADC->ADC_CDR4); + return ConvertPicovoltsToMillivolts(picovolts); +} + +// +// PRIVATE HELPERS +// + +static inline uint32 ConvertAdcCountsToPicovolts(uint32 counts) +{ + // ADC bit weight at 10-bit resolution with 3.0V reference = 2.9296875 mV/LSB + uint32 picovoltsPerAdcCount = 2929688; + + // Shift decimal point by 6 places to preserve accuracy in fixed-point math + return counts * picovoltsPerAdcCount; +} + +static inline uint16 ConvertPicovoltsToMillivolts(uint32 picovolts) +{ + const uint32 halfMillivoltInPicovolts = 500000; + const uint32 picovoltsPerMillivolt = 1000000; + + // Add 0.5 mV to result so that truncation yields properly rounded result + picovolts += halfMillivoltInPicovolts; + + // Divide appropriately to convert to millivolts + return (uint16)(picovolts / picovoltsPerMillivolt); +} + diff --git a/tests/e2e/v1.0/temp_sensor/src/AdcTemperatureSensor.h b/tests/e2e/v1.0/temp_sensor/src/AdcTemperatureSensor.h new file mode 100644 index 0000000..cb4f23f --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/AdcTemperatureSensor.h @@ -0,0 +1,17 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _ADCTEMPERATURESENSOR_H +#define _ADCTEMPERATURESENSOR_H + +#include "Types.h" + +void Adc_StartTemperatureSensorConversion(void); +bool Adc_TemperatureSensorSampleReady(void); +uint16 Adc_ReadTemperatureSensor(void); + +#endif // _ADCTEMPERATURESENSOR_H diff --git a/tests/e2e/v1.0/temp_sensor/src/Executor.c b/tests/e2e/v1.0/temp_sensor/src/Executor.c new file mode 100644 index 0000000..9fde9ce --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/Executor.c @@ -0,0 +1,32 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "Executor.h" +#include "Model.h" +#include "UsartConductor.h" +#include "TimerConductor.h" +#include "AdcConductor.h" +#include "IntrinsicsWrapper.h" + + +void Executor_Init(void) +{ + Model_Init(); + UsartConductor_Init(); + AdcConductor_Init(); + TimerConductor_Init(); + Interrupt_Enable(); +} + +bool Executor_Run(void) +{ + UsartConductor_Run(); + TimerConductor_Run(); + AdcConductor_Run(); + return TRUE; +} diff --git a/tests/e2e/v1.0/temp_sensor/src/Executor.h b/tests/e2e/v1.0/temp_sensor/src/Executor.h new file mode 100644 index 0000000..238baee --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/Executor.h @@ -0,0 +1,16 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _EXECUTOR_H +#define _EXECUTOR_H + +#include "Types.h" + +void Executor_Init(void); +bool Executor_Run(void); + +#endif // _EXECUTOR_H diff --git a/tests/e2e/v1.0/temp_sensor/src/IntrinsicsWrapper.c b/tests/e2e/v1.0/temp_sensor/src/IntrinsicsWrapper.c new file mode 100644 index 0000000..e6863ed --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/IntrinsicsWrapper.c @@ -0,0 +1,25 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "IntrinsicsWrapper.h" +#ifdef __ICCARM__ +#include +#endif + +void Interrupt_Enable(void) +{ +#ifdef __ICCARM__ + __enable_interrupt(); +#endif +} + +void Interrupt_Disable(void) +{ +#ifdef __ICCARM__ + __disable_interrupt(); +#endif +} diff --git a/tests/e2e/v1.0/temp_sensor/src/IntrinsicsWrapper.h b/tests/e2e/v1.0/temp_sensor/src/IntrinsicsWrapper.h new file mode 100644 index 0000000..fd69610 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/IntrinsicsWrapper.h @@ -0,0 +1,14 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _INTRINSICS_WRAPPER_H +#define _INTRINSICS_WRAPPER_H + +void Interrupt_Enable(void); +void Interrupt_Disable(void); + +#endif // _INTRINSICS_WRAPPER_H diff --git a/tests/e2e/v1.0/temp_sensor/src/Main.c b/tests/e2e/v1.0/temp_sensor/src/Main.c new file mode 100644 index 0000000..b665097 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/Main.c @@ -0,0 +1,53 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" + +#include "IntrinsicsWrapper.h" +#include "Executor.h" + +#include "Model.h" +#include "TaskScheduler.h" +#include "TemperatureCalculator.h" +#include "TemperatureFilter.h" + +#include "UsartConductor.h" +#include "UsartHardware.h" +#include "UsartConfigurator.h" +#include "UsartPutChar.h" +#include "UsartModel.h" +#include "UsartBaudRateRegisterCalculator.h" +#include "UsartTransmitBufferStatus.h" + +#include "TimerConductor.h" +#include "TimerHardware.h" +#include "TimerConfigurator.h" +#include "TimerInterruptConfigurator.h" +#include "TimerInterruptHandler.h" +#include "TimerModel.h" + +#include "AdcConductor.h" +#include "AdcHardware.h" +#include "AdcHardwareConfigurator.h" +#include "AdcTemperatureSensor.h" +#include "AdcModel.h" + +int AppMain(void) +{ + Executor_Init(); + + while(Executor_Run()); + + return 0; +} + +#ifndef TEST +int main(void) +{ + return AppMain(); +} +#endif // TEST diff --git a/tests/e2e/v1.0/temp_sensor/src/Main.h b/tests/e2e/v1.0/temp_sensor/src/Main.h new file mode 100644 index 0000000..b0cb090 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/Main.h @@ -0,0 +1,14 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _MAIN_H_ +#define _MAIN_H_ + +int AppMain(void); +int main(void); + +#endif // _MAIN_H_ diff --git a/tests/e2e/v1.0/temp_sensor/src/Model.c b/tests/e2e/v1.0/temp_sensor/src/Model.c new file mode 100644 index 0000000..cf84f6c --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/Model.c @@ -0,0 +1,17 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Model.h" +#include "TaskScheduler.h" +#include "TemperatureFilter.h" + +void Model_Init(void) +{ + TaskScheduler_Init(); + TemperatureFilter_Init(); +} + diff --git a/tests/e2e/v1.0/temp_sensor/src/Model.h b/tests/e2e/v1.0/temp_sensor/src/Model.h new file mode 100644 index 0000000..c449aa1 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/Model.h @@ -0,0 +1,15 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _MODEL_H +#define _MODEL_H + +#include "Types.h" + +void Model_Init(void); + +#endif // _MODEL_H diff --git a/tests/e2e/v1.0/temp_sensor/src/ModelConfig.h b/tests/e2e/v1.0/temp_sensor/src/ModelConfig.h new file mode 100644 index 0000000..368e405 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/ModelConfig.h @@ -0,0 +1,14 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _MODELCONFIG_H +#define _MODELCONFIG_H + +#define MASTER_CLOCK 48054857 // Master Clock +#define USART0_BAUDRATE 115200 // USART Baudrate + +#endif // _MODELCONFIG_H diff --git a/tests/e2e/v1.0/temp_sensor/src/TaskScheduler.c b/tests/e2e/v1.0/temp_sensor/src/TaskScheduler.c new file mode 100644 index 0000000..323e6ca --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TaskScheduler.c @@ -0,0 +1,79 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "TaskScheduler.h" + +typedef struct _Task +{ + bool doIt; + uint32 period; + uint32 startTime; +} Task; + +typedef struct _TaskSchedulerInstance +{ + Task usart; + Task adc; +} TaskSchedulerInstance; + +static TaskSchedulerInstance this; + +void TaskScheduler_Init(void) +{ + this.usart.doIt = FALSE; + this.usart.startTime = 0; + + //The correct period + this.usart.period = 1000; + + this.adc.doIt = FALSE; + this.adc.startTime = 0; + this.adc.period = 100; +} + +void TaskScheduler_Update(uint32 time) +{ + if ((time - this.usart.startTime) >= this.usart.period) + { + this.usart.doIt = TRUE; + this.usart.startTime = time - (time % this.usart.period); + } + + if ((time - this.adc.startTime) >= this.adc.period) + { + this.adc.doIt = TRUE; + this.adc.startTime = time - (time % this.adc.period); + } +} + +bool TaskScheduler_DoUsart(void) +{ + bool doIt = FALSE; + + if (this.usart.doIt) + { + doIt = TRUE; + this.usart.doIt = FALSE; + } + + return doIt; +} + +bool TaskScheduler_DoAdc(void) +{ + bool doIt = FALSE; + + if (this.adc.doIt) + { + doIt = TRUE; + this.adc.doIt = FALSE; + } + + return doIt; +} + diff --git a/tests/e2e/v1.0/temp_sensor/src/TaskScheduler.h b/tests/e2e/v1.0/temp_sensor/src/TaskScheduler.h new file mode 100644 index 0000000..1b21c0b --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TaskScheduler.h @@ -0,0 +1,18 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _TASKSCHEDULER_H +#define _TASKSCHEDULER_H + +#include "Types.h" + +void TaskScheduler_Init(void); +void TaskScheduler_Update(uint32 time); +bool TaskScheduler_DoUsart(void); +bool TaskScheduler_DoAdc(void); + +#endif // _TASKSCHEDULER_H diff --git a/tests/e2e/v1.0/temp_sensor/src/TemperatureCalculator.c b/tests/e2e/v1.0/temp_sensor/src/TemperatureCalculator.c new file mode 100644 index 0000000..eb98723 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TemperatureCalculator.c @@ -0,0 +1,38 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "TemperatureCalculator.h" +#include + +#ifndef logl +#define logl log +#endif + +#ifndef SUPPLY_VOLTAGE +#define SUPPLY_VOLTAGE 5.0 +#endif + +float TemperatureCalculator_Calculate(uint16 millivolts) +{ + const double supply_voltage = SUPPLY_VOLTAGE; + const double series_resistance = 5000; + const double coefficient_A = 316589.698; + const double coefficient_B = -0.1382009; + double sensor_voltage = ((double)millivolts / 1000); + double resistance; + + if (millivolts == 0) + { + return -INFINITY; + } + + // Series resistor is 5k Ohms; Reference voltage is 3.0V + // R(t) = A * e^(B*t); R is resistance of thermisor; t is temperature in C + resistance = ((supply_voltage * series_resistance) / sensor_voltage) - series_resistance; + return (float)(logl(resistance / coefficient_A) / coefficient_B); +} diff --git a/tests/e2e/v1.0/temp_sensor/src/TemperatureCalculator.h b/tests/e2e/v1.0/temp_sensor/src/TemperatureCalculator.h new file mode 100644 index 0000000..00b0c41 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TemperatureCalculator.h @@ -0,0 +1,15 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _TEMPERATURECALCULATOR_H +#define _TEMPERATURECALCULATOR_H + +#include "Types.h" + +float TemperatureCalculator_Calculate(uint16 millivolts); + +#endif // _TEMPERATURECALCULATOR_H diff --git a/tests/e2e/v1.0/temp_sensor/src/TemperatureFilter.c b/tests/e2e/v1.0/temp_sensor/src/TemperatureFilter.c new file mode 100644 index 0000000..977e2d7 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TemperatureFilter.c @@ -0,0 +1,45 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "TemperatureFilter.h" +#include + +static bool initialized; +static float temperatureInCelcius; + +void TemperatureFilter_Init(void) +{ + initialized = FALSE; + temperatureInCelcius = -INFINITY; +} + +float TemperatureFilter_GetTemperatureInCelcius(void) +{ + return temperatureInCelcius; +} + +void TemperatureFilter_ProcessInput(float temperature) +{ + if (!initialized) + { + temperatureInCelcius = temperature; + initialized = TRUE; + } + else + { + if (temperature == +INFINITY || + temperature == -INFINITY || + isnan(temperature)) + { + initialized = FALSE; + temperature = -INFINITY; + } + + temperatureInCelcius = (temperatureInCelcius * 0.75f) + (temperature * 0.25); + } +} diff --git a/tests/e2e/v1.0/temp_sensor/src/TemperatureFilter.h b/tests/e2e/v1.0/temp_sensor/src/TemperatureFilter.h new file mode 100644 index 0000000..0e53a1d --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TemperatureFilter.h @@ -0,0 +1,17 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _TEMPERATUREFILTER_H +#define _TEMPERATUREFILTER_H + +#include "Types.h" + +void TemperatureFilter_Init(void); +float TemperatureFilter_GetTemperatureInCelcius(void); +void TemperatureFilter_ProcessInput(float temperature); + +#endif // _TEMPERATUREFILTER_H diff --git a/tests/e2e/v1.0/temp_sensor/src/TimerConductor.c b/tests/e2e/v1.0/temp_sensor/src/TimerConductor.c new file mode 100644 index 0000000..83c522f --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TimerConductor.c @@ -0,0 +1,22 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "TimerConductor.h" +#include "TimerModel.h" +#include "TimerHardware.h" +#include "TimerInterruptHandler.h" + +void TimerConductor_Init(void) +{ + TimerHardware_Init(); +} + +void TimerConductor_Run(void) +{ + TimerModel_UpdateTime(Timer_GetSystemTime()); +} diff --git a/tests/e2e/v1.0/temp_sensor/src/TimerConductor.h b/tests/e2e/v1.0/temp_sensor/src/TimerConductor.h new file mode 100644 index 0000000..e189ed0 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TimerConductor.h @@ -0,0 +1,16 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _TIMERCONDUCTOR_H +#define _TIMERCONDUCTOR_H + +#include "Types.h" + +void TimerConductor_Init(void); +void TimerConductor_Run(void); + +#endif // _TIMERCONDUCTOR_H diff --git a/tests/e2e/v1.0/temp_sensor/src/TimerConfigurator.c b/tests/e2e/v1.0/temp_sensor/src/TimerConfigurator.c new file mode 100644 index 0000000..cc32051 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TimerConfigurator.c @@ -0,0 +1,58 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "TimerConfigurator.h" +#include "TimerInterruptConfigurator.h" + +void Timer_EnablePeripheralClocks(void) +{ + AT91C_BASE_PMC->PMC_PCER = TIMER0_CLOCK_ENABLE | PIOB_CLOCK_ENABLE; +} + +void Timer_Reset(void) +{ + uint32 dummy; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC0->TC_IDR = 0xffffffff; + dummy = AT91C_BASE_TC0->TC_SR; + dummy = dummy; +} + +void Timer_ConfigureMode(void) +{ + AT91C_BASE_TC0->TC_CMR = 0x000CC004; // ACPC=toggle TIOA on RC compare; mode=WAVE; WAVE_SEL=UP w/auto-trigger on RC compare; clock=MCK/1024 +} + +void Timer_ConfigurePeriod(void) +{ + AT91C_BASE_TC0->TC_RC = 469; // 10ms period for timer clock source of MCK/1024 with MCK=48054857 +} + +void Timer_EnableOutputPin(void) +{ + AT91C_BASE_PIOB->PIO_PDR = TIOA0_PIN_MASK; +} + +void Timer_Enable(void) +{ + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN; +} + +void Timer_ConfigureInterruptHandler(void) +{ + Timer_DisableInterrupt(); + Timer_ResetSystemTime(); + Timer_ConfigureInterrupt(); + Timer_EnableInterrupt(); +} + +void Timer_Start(void) +{ + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; +} + diff --git a/tests/e2e/v1.0/temp_sensor/src/TimerConfigurator.h b/tests/e2e/v1.0/temp_sensor/src/TimerConfigurator.h new file mode 100644 index 0000000..c103a8e --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TimerConfigurator.h @@ -0,0 +1,22 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _TIMERCONFIGURATOR_H +#define _TIMERCONFIGURATOR_H + +#include "Types.h" + +void Timer_EnablePeripheralClocks(void); +void Timer_Reset(void); +void Timer_ConfigureMode(void); +void Timer_ConfigurePeriod(void); +void Timer_EnableOutputPin(void); +void Timer_Enable(void); +void Timer_ConfigureInterruptHandler(void); +void Timer_Start(void); + +#endif // _TIMERCONFIGURATOR_H diff --git a/tests/e2e/v1.0/temp_sensor/src/TimerHardware.c b/tests/e2e/v1.0/temp_sensor/src/TimerHardware.c new file mode 100644 index 0000000..4c674ba --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TimerHardware.c @@ -0,0 +1,22 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "TimerHardware.h" +#include "TimerConfigurator.h" + +void TimerHardware_Init(void) +{ + Timer_EnablePeripheralClocks(); + Timer_Reset(); + Timer_ConfigureMode(); + Timer_ConfigurePeriod(); + Timer_EnableOutputPin(); + Timer_Enable(); + Timer_ConfigureInterruptHandler(); + Timer_Start(); +} diff --git a/tests/e2e/v1.0/temp_sensor/src/TimerHardware.h b/tests/e2e/v1.0/temp_sensor/src/TimerHardware.h new file mode 100644 index 0000000..f388487 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TimerHardware.h @@ -0,0 +1,15 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _TIMERHARDWARE_H +#define _TIMERHARDWARE_H + +#include "Types.h" + +void TimerHardware_Init(void); + +#endif // _TIMERHARDWARE_H diff --git a/tests/e2e/v1.0/temp_sensor/src/TimerInterruptConfigurator.c b/tests/e2e/v1.0/temp_sensor/src/TimerInterruptConfigurator.c new file mode 100644 index 0000000..a0f9192 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TimerInterruptConfigurator.c @@ -0,0 +1,62 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "TimerInterruptConfigurator.h" +#include "TimerInterruptHandler.h" + +static inline void SetInterruptHandler(void); +static inline void ConfigureInterruptSourceModeRegister(void); +static inline void ClearInterrupt(void); +static inline void EnableCompareInterruptForRegisterC(void); + +void Timer_DisableInterrupt(void) +{ + AT91C_BASE_AIC->AIC_IDCR = TIMER0_ID_MASK; +} + +void Timer_ResetSystemTime(void) +{ + Timer_SetSystemTime(0); +} + +void Timer_ConfigureInterrupt(void) +{ + SetInterruptHandler(); + ConfigureInterruptSourceModeRegister(); + ClearInterrupt(); + EnableCompareInterruptForRegisterC(); +} + +void Timer_EnableInterrupt(void) +{ + AT91C_BASE_AIC->AIC_IECR = TIMER0_ID_MASK; +} + +// +// Helpers +// + +static inline void SetInterruptHandler(void) +{ + AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (uint32)Timer_InterruptHandler; +} + +static inline void ConfigureInterruptSourceModeRegister(void) +{ + AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = 1; +} + +static inline void ClearInterrupt(void) +{ + AT91C_BASE_AIC->AIC_ICCR = TIMER0_ID_MASK; +} + +static inline void EnableCompareInterruptForRegisterC(void) +{ + AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS; +} diff --git a/tests/e2e/v1.0/temp_sensor/src/TimerInterruptConfigurator.h b/tests/e2e/v1.0/temp_sensor/src/TimerInterruptConfigurator.h new file mode 100644 index 0000000..114a398 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TimerInterruptConfigurator.h @@ -0,0 +1,20 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _TIMERINTERRUPTCONFIGURATOR_H +#define _TIMERINTERRUPTCONFIGURATOR_H + +#include "Types.h" + +#define TIMER0_ID_MASK (((uint32)0x1) << AT91C_ID_TC0) + +void Timer_DisableInterrupt(void); +void Timer_ResetSystemTime(void); +void Timer_ConfigureInterrupt(void); +void Timer_EnableInterrupt(void); + +#endif // _TIMERINTERRUPTCONFIGURATOR_H diff --git a/tests/e2e/v1.0/temp_sensor/src/TimerInterruptHandler.c b/tests/e2e/v1.0/temp_sensor/src/TimerInterruptHandler.c new file mode 100644 index 0000000..20c1bbd --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TimerInterruptHandler.c @@ -0,0 +1,32 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "TimerInterruptHandler.h" +#include "TimerInterruptConfigurator.h" + +static uint32 systemTime; + +void Timer_SetSystemTime(uint32 time) +{ + systemTime = time; +} + +uint32 Timer_GetSystemTime(void) +{ + return systemTime; +} + +void Timer_InterruptHandler(void) +{ + uint32 status = AT91C_BASE_TC0->TC_SR; + if (status & AT91C_TC_CPCS) + { + systemTime += 10; + } +} + diff --git a/tests/e2e/v1.0/temp_sensor/src/TimerInterruptHandler.h b/tests/e2e/v1.0/temp_sensor/src/TimerInterruptHandler.h new file mode 100644 index 0000000..6f5b505 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TimerInterruptHandler.h @@ -0,0 +1,17 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _TIMERINTERRUPTHANDLER_H +#define _TIMERINTERRUPTHANDLER_H + +#include "Types.h" + +void Timer_SetSystemTime(uint32 time); +uint32 Timer_GetSystemTime(void); +void Timer_InterruptHandler(void); + +#endif // _TIMERINTERRUPTHANDLER_H diff --git a/tests/e2e/v1.0/temp_sensor/src/TimerModel.c b/tests/e2e/v1.0/temp_sensor/src/TimerModel.c new file mode 100644 index 0000000..2be9d4d --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TimerModel.c @@ -0,0 +1,16 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "TimerModel.h" +#include "TaskScheduler.h" + +void TimerModel_UpdateTime(uint32 systemTime) +{ + TaskScheduler_Update(systemTime); +} + diff --git a/tests/e2e/v1.0/temp_sensor/src/TimerModel.h b/tests/e2e/v1.0/temp_sensor/src/TimerModel.h new file mode 100644 index 0000000..bdef366 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/TimerModel.h @@ -0,0 +1,15 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _TIMERMODEL_H +#define _TIMERMODEL_H + +#include "Types.h" + +void TimerModel_UpdateTime(uint32 systemTime); + +#endif // _TIMERMODEL_H diff --git a/tests/e2e/v1.0/temp_sensor/src/Types.h b/tests/e2e/v1.0/temp_sensor/src/Types.h new file mode 100644 index 0000000..04c3016 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/Types.h @@ -0,0 +1,97 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _MYTYPES_H_ +#define _MYTYPES_H_ + +#include + +// Application Type Definitions +typedef unsigned int uint32; +typedef int int32; +typedef unsigned short uint16; +typedef short int16; +typedef unsigned char uint8; +typedef char int8; +typedef char bool; + +// Application Special Value Definitions +#ifndef TRUE +#define TRUE (1) +#endif +#ifndef FALSE +#define FALSE (0) +#endif +#ifndef NULL +#define NULL (0) +#endif // NULL +#define DONT_CARE (0) + +#ifndef INFINITY +#define INFINITY (1.0 / 0.0) +#endif + +#ifndef NAN +#define NAN (0.0 / 0.0) +#endif + +// MIN/MAX Definitions for Standard Types +#ifndef INT8_MAX +#define INT8_MAX 127 +#endif + +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif + +#ifndef UINT8_MAX +#define UINT8_MAX 0xFFU +#endif + +#ifndef UINT8_MIN +#define UINT8_MIN 0x00U +#endif + +#ifndef INT16_MAX +#define INT16_MAX 32767 +#endif + +#ifndef INT16_MIN +#define INT16_MIN (-32768) +#endif + +#ifndef UINT16_MAX +#define UINT16_MAX 0xFFFFU +#endif + +#ifndef UINT16_MIN +#define UINT16_MIN 0x0000U +#endif + +#ifndef INT32_MAX +#define INT32_MAX 0x7FFFFFFF +#endif + +#ifndef INT32_MIN +#define INT32_MIN (-INT32_MAX - 1) +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX 0xFFFFFFFFU +#endif + +#ifndef UINT32_MIN +#define UINT32_MIN 0x00000000U +#endif + +typedef struct _EXAMPLE_STRUCT_T +{ + int x; + int y; +} EXAMPLE_STRUCT_T; + +#endif // _MYTYPES_H_ diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartBaudRateRegisterCalculator.c b/tests/e2e/v1.0/temp_sensor/src/UsartBaudRateRegisterCalculator.c new file mode 100644 index 0000000..8c122f6 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartBaudRateRegisterCalculator.c @@ -0,0 +1,25 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "UsartBaudRateRegisterCalculator.h" + +uint8 UsartModel_CalculateBaudRateRegisterSetting(uint32 masterClock, uint32 baudRate) +{ + uint32 registerSetting = ((masterClock * 10) / (baudRate * 16)); + + if ((registerSetting % 10) >= 5) + { + registerSetting = (registerSetting / 10) + 1; + } + else + { + registerSetting /= 10; + } + + return (uint8)registerSetting; +} diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartBaudRateRegisterCalculator.h b/tests/e2e/v1.0/temp_sensor/src/UsartBaudRateRegisterCalculator.h new file mode 100644 index 0000000..a1b4959 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartBaudRateRegisterCalculator.h @@ -0,0 +1,15 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _USARTBAUDRATEREGISTERCALCULATOR_H +#define _USARTBAUDRATEREGISTERCALCULATOR_H + +#include "Types.h" + +uint8 UsartModel_CalculateBaudRateRegisterSetting(uint32 masterClock, uint32 baudRate); + +#endif // _USARTBAUDRATEREGISTERCALCULATOR_H diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartConductor.c b/tests/e2e/v1.0/temp_sensor/src/UsartConductor.c new file mode 100644 index 0000000..c949df2 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartConductor.c @@ -0,0 +1,28 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "UsartConductor.h" +#include "UsartHardware.h" +#include "UsartModel.h" +#include "TaskScheduler.h" + +void UsartConductor_Init(void) +{ + UsartHardware_Init(UsartModel_GetBaudRateRegisterSetting()); + UsartHardware_TransmitString(UsartModel_GetWakeupMessage()); +} + +void UsartConductor_Run(void) +{ + char* temp; + if (TaskScheduler_DoUsart()) + { + temp = UsartModel_GetFormattedTemperature(); + UsartHardware_TransmitString(temp); + } +} diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartConductor.h b/tests/e2e/v1.0/temp_sensor/src/UsartConductor.h new file mode 100644 index 0000000..c75e728 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartConductor.h @@ -0,0 +1,14 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _USARTCONDUCTOR_H +#define _USARTCONDUCTOR_H + +void UsartConductor_Init(void); +void UsartConductor_Run(void); + +#endif // _USARTCONDUCTOR_H diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartConfigurator.c b/tests/e2e/v1.0/temp_sensor/src/UsartConfigurator.c new file mode 100644 index 0000000..a1866cf --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartConfigurator.c @@ -0,0 +1,46 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "UsartConfigurator.h" + +void Usart_ConfigureUsartIO(void) +{ + AT91C_BASE_PIOA->PIO_ASR = USART0_TX_PIN; + AT91C_BASE_PIOA->PIO_BSR = 0; + AT91C_BASE_PIOA->PIO_PDR = USART0_TX_PIN; +} + +void Usart_EnablePeripheralClock(void) +{ + AT91C_BASE_PMC->PMC_PCER = ((uint32)1) << USART0_CLOCK_ENABLE; +} + +void Usart_Reset(void) +{ + AT91C_BASE_US0->US_IDR = 0xffffffff; + AT91C_BASE_US0->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS; +} + +void Usart_ConfigureMode(void) +{ + AT91C_BASE_US0->US_MR = AT91C_US_USMODE_NORMAL | + AT91C_US_NBSTOP_1_BIT | + AT91C_US_PAR_NONE | + AT91C_US_CHRL_8_BITS | + AT91C_US_CLKS_CLOCK; +} + +void Usart_SetBaudRateRegister(uint8 baudRateRegisterSetting) +{ + AT91C_BASE_US0->US_BRGR = baudRateRegisterSetting; +} + +void Usart_Enable(void) +{ + AT91C_BASE_US0->US_CR = AT91C_US_TXEN; +} diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartConfigurator.h b/tests/e2e/v1.0/temp_sensor/src/UsartConfigurator.h new file mode 100644 index 0000000..e42657e --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartConfigurator.h @@ -0,0 +1,20 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _USARTCONFIGURATOR_H +#define _USARTCONFIGURATOR_H + +#include "Types.h" + +void Usart_ConfigureUsartIO(void); +void Usart_EnablePeripheralClock(void); +void Usart_Reset(void); +void Usart_ConfigureMode(void); +void Usart_SetBaudRateRegister(uint8 baudRateRegisterSetting); +void Usart_Enable(void); + +#endif // _USARTCONFIGURATOR_H diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartHardware.c b/tests/e2e/v1.0/temp_sensor/src/UsartHardware.c new file mode 100644 index 0000000..dc82e85 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartHardware.c @@ -0,0 +1,29 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "UsartHardware.h" +#include "UsartConfigurator.h" +#include "UsartPutChar.h" + +void UsartHardware_Init(uint8 baudRateRegisterSetting) +{ + Usart_ConfigureUsartIO(); + Usart_EnablePeripheralClock(); + Usart_Reset(); + Usart_ConfigureMode(); + Usart_SetBaudRateRegister(baudRateRegisterSetting); + Usart_Enable(); +} + +void UsartHardware_TransmitString(char* data) +{ + while(*data != NULL) + { + Usart_PutChar(*data++); + } +} diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartHardware.h b/tests/e2e/v1.0/temp_sensor/src/UsartHardware.h new file mode 100644 index 0000000..4014e37 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartHardware.h @@ -0,0 +1,16 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _USARTHARDWARE_H +#define _USARTHARDWARE_H + +#include "Types.h" + +void UsartHardware_Init(uint8 baudRateRegisterSetting); +void UsartHardware_TransmitString(char* data); + +#endif // _USARTHARDWARE_H diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartModel.c b/tests/e2e/v1.0/temp_sensor/src/UsartModel.c new file mode 100644 index 0000000..77b4d6a --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartModel.c @@ -0,0 +1,41 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "UsartModel.h" +#include "ModelConfig.h" +#include "UsartBaudRateRegisterCalculator.h" +#include "TemperatureFilter.h" +#include +#include + +char formattedTemperature[32]; +char* wakeup = "It's Awesome Time!\n"; + +uint8 UsartModel_GetBaudRateRegisterSetting(void) +{ + return UsartModel_CalculateBaudRateRegisterSetting(MASTER_CLOCK, USART0_BAUDRATE); +} + +char* UsartModel_GetFormattedTemperature(void) +{ + float temperature = TemperatureFilter_GetTemperatureInCelcius(); + if (temperature == -INFINITY) + { + sprintf(formattedTemperature, "%s", "Temperature sensor failure!\n"); + } + else + { + sprintf(formattedTemperature, "%.1f C\n", temperature); + } + return formattedTemperature; +} + +char* UsartModel_GetWakeupMessage(void) +{ + return wakeup; +} diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartModel.h b/tests/e2e/v1.0/temp_sensor/src/UsartModel.h new file mode 100644 index 0000000..7754b02 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartModel.h @@ -0,0 +1,17 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _USARTMODEL_H +#define _USARTMODEL_H + +#include "Types.h" + +uint8 UsartModel_GetBaudRateRegisterSetting(void); +char* UsartModel_GetFormattedTemperature(void); +char* UsartModel_GetWakeupMessage(void); + +#endif // _USARTMODEL_H diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartPutChar.c b/tests/e2e/v1.0/temp_sensor/src/UsartPutChar.c new file mode 100644 index 0000000..036a95d --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartPutChar.c @@ -0,0 +1,23 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "UsartPutChar.h" +#include "UsartTransmitBufferStatus.h" +#ifdef SIMULATE +#include +#endif + +void Usart_PutChar(char data) +{ + while(!Usart_ReadyToTransmit()); +#ifdef SIMULATE + printf("%c", data); +#else + AT91C_BASE_US0->US_THR = data; +#endif +} diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartPutChar.h b/tests/e2e/v1.0/temp_sensor/src/UsartPutChar.h new file mode 100644 index 0000000..f5cd017 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartPutChar.h @@ -0,0 +1,15 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _USARTPUT_HAR_H +#define _USARTPUT_HAR_H + +#include "Types.h" + +void Usart_PutChar(char data); + +#endif // _USARTPUT_HAR_H diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartTransmitBufferStatus.c b/tests/e2e/v1.0/temp_sensor/src/UsartTransmitBufferStatus.c new file mode 100644 index 0000000..f061f66 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartTransmitBufferStatus.c @@ -0,0 +1,14 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "Types.h" +#include "UsartTransmitBufferStatus.h" + +bool Usart_ReadyToTransmit(void) +{ + return (AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY) > 0; +} diff --git a/tests/e2e/v1.0/temp_sensor/src/UsartTransmitBufferStatus.h b/tests/e2e/v1.0/temp_sensor/src/UsartTransmitBufferStatus.h new file mode 100644 index 0000000..c322329 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/src/UsartTransmitBufferStatus.h @@ -0,0 +1,15 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _USARTTRANSMITBUFFERSTATUS_H +#define _USARTTRANSMITBUFFERSTATUS_H + +#include "Types.h" + +bool Usart_ReadyToTransmit(void); + +#endif // _USARTTRANSMITBUFFERSTATUS_H diff --git a/tests/e2e/v1.0/temp_sensor/test/TestExecutor.c b/tests/e2e/v1.0/temp_sensor/test/TestExecutor.c new file mode 100644 index 0000000..305f9c0 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestExecutor.c @@ -0,0 +1,43 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "Executor.h" +#include "MockModel.h" +#include "MockUsartConductor.h" +#include "MockAdcConductor.h" +#include "MockTimerConductor.h" +#include "MockIntrinsicsWrapper.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldCallInitOfAllConductorsAndTheModel(void) +{ + Model_Init_Expect(); + UsartConductor_Init_Expect(); + AdcConductor_Init_Expect(); + TimerConductor_Init_Expect(); + Interrupt_Enable_Expect(); + + Executor_Init(); +} + +void testRunShouldCallRunForEachConductorAndReturnTrueAlways(void) +{ + UsartConductor_Run_Expect(); + TimerConductor_Run_Expect(); + AdcConductor_Run_Expect(); + + TEST_ASSERT_TRUE(Executor_Run()); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestMain.c b/tests/e2e/v1.0/temp_sensor/test/TestMain.c new file mode 100644 index 0000000..8c63882 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestMain.c @@ -0,0 +1,31 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "MockExecutor.h" +#include "Main.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testMainShouldCallExecutorInitAndContinueToCallExecutorRunUntilHalted(void) +{ + Executor_Init_Expect(); + Executor_Run_ExpectAndReturn(TRUE); + Executor_Run_ExpectAndReturn(TRUE); + Executor_Run_ExpectAndReturn(TRUE); + Executor_Run_ExpectAndReturn(TRUE); + Executor_Run_ExpectAndReturn(FALSE); + + AppMain(); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestModel.c b/tests/e2e/v1.0/temp_sensor/test/TestModel.c new file mode 100644 index 0000000..c5fee38 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestModel.c @@ -0,0 +1,27 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "Model.h" +#include "MockTaskScheduler.h" +#include "MockTemperatureFilter.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldCallSchedulerAndTemperatureFilterInit(void) +{ + TaskScheduler_Init_Expect(); + TemperatureFilter_Init_Expect(); + Model_Init(); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestTaskScheduler.c b/tests/e2e/v1.0/temp_sensor/test/TestTaskScheduler.c new file mode 100644 index 0000000..317da2d --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestTaskScheduler.c @@ -0,0 +1,111 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "TaskScheduler.h" + +void setUp(void) +{ + TaskScheduler_Init(); +} + +void tearDown(void) +{ +} + +void testShouldScheduleUsartTaskAfter1000ms(void) +{ + TEST_ASSERT_FALSE(TaskScheduler_DoUsart()); + + TaskScheduler_Update(999); + TEST_ASSERT_FALSE(TaskScheduler_DoUsart()); + + TaskScheduler_Update(1000); + TEST_ASSERT_TRUE(TaskScheduler_DoUsart()); +} + +void testShouldClearUsartDoFlagAfterReported(void) +{ + TEST_ASSERT_FALSE(TaskScheduler_DoUsart()); + TaskScheduler_Update(1000); + TEST_ASSERT_TRUE(TaskScheduler_DoUsart()); + TEST_ASSERT_FALSE(TaskScheduler_DoUsart()); +} + +void testShouldScheduleUsartTaskEvery1000ms(void) +{ + TEST_ASSERT_FALSE(TaskScheduler_DoUsart()); + + TaskScheduler_Update(1300); + TEST_ASSERT_TRUE(TaskScheduler_DoUsart()); + + TaskScheduler_Update(2000); + TEST_ASSERT_TRUE(TaskScheduler_DoUsart()); + + TaskScheduler_Update(3100); + TEST_ASSERT_TRUE(TaskScheduler_DoUsart()); +} + +void testShouldScheduleUsartTaskOnlyOncePerPeriod(void) +{ + TEST_ASSERT_FALSE(TaskScheduler_DoUsart()); + TaskScheduler_Update(1000); + TEST_ASSERT_TRUE(TaskScheduler_DoUsart()); + TaskScheduler_Update(1001); + TEST_ASSERT_FALSE(TaskScheduler_DoUsart()); + TaskScheduler_Update(1999); + TEST_ASSERT_FALSE(TaskScheduler_DoUsart()); + TaskScheduler_Update(2000); + TEST_ASSERT_TRUE(TaskScheduler_DoUsart()); +} + +void testShouldScheduleAdcTaskAfter100ms(void) +{ + TEST_ASSERT_FALSE(TaskScheduler_DoAdc()); + + TaskScheduler_Update(99); + TEST_ASSERT_FALSE(TaskScheduler_DoAdc()); + + TaskScheduler_Update(100); + TEST_ASSERT_TRUE(TaskScheduler_DoAdc()); +} + +void testShouldClearAdcDoFlagAfterReported(void) +{ + TEST_ASSERT_FALSE(TaskScheduler_DoAdc()); + TaskScheduler_Update(100); + TEST_ASSERT_TRUE(TaskScheduler_DoAdc()); + TEST_ASSERT_FALSE(TaskScheduler_DoAdc()); +} + +void testShouldScheduleAdcTaskEvery100ms(void) +{ + TEST_ASSERT_FALSE(TaskScheduler_DoAdc()); + + TaskScheduler_Update(121); + TEST_ASSERT_TRUE(TaskScheduler_DoAdc()); + + TaskScheduler_Update(200); + TEST_ASSERT_TRUE(TaskScheduler_DoAdc()); + + TaskScheduler_Update(356); + TEST_ASSERT_TRUE(TaskScheduler_DoAdc()); +} + +void testShouldScheduleAdcTaskOnlyOncePerPeriod(void) +{ + TEST_ASSERT_FALSE(TaskScheduler_DoAdc()); + TaskScheduler_Update(100); + TEST_ASSERT_TRUE(TaskScheduler_DoAdc()); + TaskScheduler_Update(101); + TEST_ASSERT_FALSE(TaskScheduler_DoAdc()); + TaskScheduler_Update(199); + TEST_ASSERT_FALSE(TaskScheduler_DoAdc()); + TaskScheduler_Update(200); + TEST_ASSERT_TRUE(TaskScheduler_DoAdc()); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestTemperatureCalculator.c b/tests/e2e/v1.0/temp_sensor/test/TestTemperatureCalculator.c new file mode 100644 index 0000000..746e5cd --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestTemperatureCalculator.c @@ -0,0 +1,43 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include + +TEST_SOURCE_FILE("TemperatureCalculator.c") + +extern float TemperatureCalculator_Calculate(uint16_t val); + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testTemperatureCalculatorShouldCalculateTemperatureFromMillivolts(void) +{ + float result; + + // Series resistor is 5k Ohms; Reference voltage is 3.0V + // R(t) = A * e^(B*t); R is resistance of thermisor; t is temperature in C + result = TemperatureCalculator_Calculate(1000); + TEST_ASSERT_FLOAT_WITHIN(0.01f, 25.0f, result); + + result = TemperatureCalculator_Calculate(2985); + TEST_ASSERT_FLOAT_WITHIN(0.01f, 68.317f, result); + + result = TemperatureCalculator_Calculate(3); + TEST_ASSERT_FLOAT_WITHIN(0.01f, -19.96f, result); +} + +void testShouldReturnNegativeInfinityWhen_0_millivoltsInput(void) +{ + TEST_ASSERT_FLOAT_IS_NEG_INF(TemperatureCalculator_Calculate(0)); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestTemperatureFilter.c b/tests/e2e/v1.0/temp_sensor/test/TestTemperatureFilter.c new file mode 100644 index 0000000..47cfe86 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestTemperatureFilter.c @@ -0,0 +1,86 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "TemperatureFilter.h" +#include + +void setUp(void) +{ + TemperatureFilter_Init(); +} + +void tearDown(void) +{ +} + +void testShouldInitializeTemeratureToInvalidValue(void) +{ + TemperatureFilter_Init(); + TEST_ASSERT_FLOAT_IS_NEG_INF(TemperatureFilter_GetTemperatureInCelcius()); +} + +void testShouldInitializeTemperatureAfterCallToInit(void) +{ + TemperatureFilter_Init(); + TemperatureFilter_ProcessInput(17.8f); + TEST_ASSERT_FLOAT_WITHIN(0.0001f, 17.8f, TemperatureFilter_GetTemperatureInCelcius()); + + TemperatureFilter_Init(); + TemperatureFilter_ProcessInput(32.6f); + TEST_ASSERT_FLOAT_WITHIN(0.0001f, 32.6f, TemperatureFilter_GetTemperatureInCelcius()); +} + +void setValueAndVerifyResponse(float input, float response) +{ + float actual; + TemperatureFilter_ProcessInput(input); + actual = TemperatureFilter_GetTemperatureInCelcius(); + + if (input == +INFINITY || + input == -INFINITY || + isnan(input)) + { + TEST_ASSERT_FLOAT_IS_NEG_INF(actual); + } + else + { + TEST_ASSERT_FLOAT_WITHIN(0.0001f, response, actual); + } +} + +void testShouldWeightEachSubsequentValueBy25PercentAfterInitialValue(void) +{ + TemperatureFilter_Init(); + setValueAndVerifyResponse(0.0f, 0.0f); + setValueAndVerifyResponse(10.0f, 2.5f); + setValueAndVerifyResponse(10.0f, 4.375f); + setValueAndVerifyResponse(10.0f, 5.78125f); + + TemperatureFilter_Init(); + setValueAndVerifyResponse(100.0f, 100.0f); + setValueAndVerifyResponse(0.0f, 75.0f); + setValueAndVerifyResponse(0.0f, 56.25f); + setValueAndVerifyResponse(0.0f, 42.1875f); +} + +void setInvalidTemperatureAndVerifyReinitialized(float invalidTemperature) +{ + TemperatureFilter_Init(); + setValueAndVerifyResponse(100.0f, 100.0f); + setValueAndVerifyResponse(invalidTemperature, -INFINITY); + setValueAndVerifyResponse(14.3f, 14.3f); +} + +void testShouldResetAverageIfPassedInfinityOrInvalidValue(void) +{ + setInvalidTemperatureAndVerifyReinitialized(-INFINITY); + setInvalidTemperatureAndVerifyReinitialized(+INFINITY); + setInvalidTemperatureAndVerifyReinitialized(+NAN); + setInvalidTemperatureAndVerifyReinitialized(-NAN); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestTimerConductor.c b/tests/e2e/v1.0/temp_sensor/test/TestTimerConductor.c new file mode 100644 index 0000000..9cd8630 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestTimerConductor.c @@ -0,0 +1,39 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "TimerConductor.h" +#include "MockTimerHardware.h" +#include "MockTimerModel.h" +#include "MockTimerInterruptHandler.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldCallHardwareInit(void) +{ + TimerHardware_Init_Expect(); + + TimerConductor_Init(); +} + +void testRunShouldGetSystemTimeAndPassOnToModelForEventScheduling(void) +{ + Timer_GetSystemTime_ExpectAndReturn(1230); + TimerModel_UpdateTime_Expect(1230); + TimerConductor_Run(); + + Timer_GetSystemTime_ExpectAndReturn(837460); + TimerModel_UpdateTime_Expect(837460); + TimerConductor_Run(); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestTimerHardware.c b/tests/e2e/v1.0/temp_sensor/test/TestTimerHardware.c new file mode 100644 index 0000000..d02ac96 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestTimerHardware.c @@ -0,0 +1,33 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "TimerHardware.h" +#include "MockTimerConfigurator.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldDelegateAppropriatelyToConfigurator(void) +{ + Timer_EnablePeripheralClocks_Expect(); + Timer_Reset_Expect(); + Timer_ConfigureMode_Expect(); + Timer_ConfigurePeriod_Expect(); + Timer_EnableOutputPin_Expect(); + Timer_Enable_Expect(); + Timer_ConfigureInterruptHandler_Expect(); + Timer_Start_Expect(); + + TimerHardware_Init(); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestTimerIntegrated.c b/tests/e2e/v1.0/temp_sensor/test/TestTimerIntegrated.c new file mode 100644 index 0000000..437df96 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestTimerIntegrated.c @@ -0,0 +1,53 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "TimerConductor.h" +#include "TimerHardware.h" +#include "TimerModel.h" +#include "MockTimerConfigurator.h" +#include "MockTimerInterruptHandler.h" +#include "MockTaskScheduler.h" + +/* NOTE: we probably wouldn't actually perform this test on our own projects + but it's a good example of testing the same module(s) from multiple test + files, and therefore we like having it in this example. +*/ + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldCallHardwareInit(void) +{ + Timer_EnablePeripheralClocks_Expect(); + Timer_Reset_Expect(); + Timer_ConfigureMode_Expect(); + Timer_ConfigurePeriod_Expect(); + Timer_EnableOutputPin_Expect(); + Timer_Enable_Expect(); + Timer_ConfigureInterruptHandler_Expect(); + Timer_Start_Expect(); + + TimerConductor_Init(); +} + +void testRunShouldGetSystemTimeAndPassOnToModelForEventScheduling(void) +{ + Timer_GetSystemTime_ExpectAndReturn(1230); + TaskScheduler_Update_Expect(1230); + TimerConductor_Run(); + + Timer_GetSystemTime_ExpectAndReturn(837460); + TaskScheduler_Update_Expect(837460); + TimerConductor_Run(); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestTimerModel.c b/tests/e2e/v1.0/temp_sensor/test/TestTimerModel.c new file mode 100644 index 0000000..7e5db34 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestTimerModel.c @@ -0,0 +1,25 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "TimerModel.h" +#include "MockTaskScheduler.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testUpdateTimeShouldDelegateToTaskScheduler(void) +{ + TaskScheduler_Update_Expect(19387L); + TimerModel_UpdateTime(19387L); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestUsartBaudRateRegisterCalculator.c b/tests/e2e/v1.0/temp_sensor/test/TestUsartBaudRateRegisterCalculator.c new file mode 100644 index 0000000..00b3859 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestUsartBaudRateRegisterCalculator.c @@ -0,0 +1,28 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "UsartBaudRateRegisterCalculator.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testCalculateBaudRateRegisterSettingShouldCalculateRegisterSettingAppropriately(void) +{ + // BaudRate = MCK / (CD x 16) - per datasheet section 30.6.1.2 "Baud Rate Calculation Example" + TEST_ASSERT_EQUAL_INT(26, UsartModel_CalculateBaudRateRegisterSetting(48000000, 115200)); + TEST_ASSERT_EQUAL_INT(6, UsartModel_CalculateBaudRateRegisterSetting(3686400, 38400)); + TEST_ASSERT_EQUAL_INT(23, UsartModel_CalculateBaudRateRegisterSetting(14318180, 38400)); + TEST_ASSERT_EQUAL_INT(20, UsartModel_CalculateBaudRateRegisterSetting(12000000, 38400)); + TEST_ASSERT_EQUAL_INT(13, UsartModel_CalculateBaudRateRegisterSetting(12000000, 56800)); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestUsartConductor.c b/tests/e2e/v1.0/temp_sensor/test/TestUsartConductor.c new file mode 100644 index 0000000..a6f30e7 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestUsartConductor.c @@ -0,0 +1,47 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "UsartConductor.h" +#include "MockUsartModel.h" +#include "MockUsartHardware.h" +#include "MockTaskScheduler.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testShouldInitializeHardwareWhenInitCalled(void) +{ + UsartModel_GetBaudRateRegisterSetting_ExpectAndReturn(4); + UsartHardware_Init_Expect(4); + UsartModel_GetWakeupMessage_ExpectAndReturn("Hey there!"); + UsartHardware_TransmitString_Expect("Hey there!"); + + UsartConductor_Init(); +} + +void testRunShouldNotDoAnythingIfSchedulerSaysItIsNotTimeYet(void) +{ + TaskScheduler_DoUsart_ExpectAndReturn(FALSE); + + UsartConductor_Run(); +} + +void testRunShouldGetCurrentTemperatureAndTransmitIfSchedulerSaysItIsTime(void) +{ + TaskScheduler_DoUsart_ExpectAndReturn(TRUE); + UsartModel_GetFormattedTemperature_ExpectAndReturn("hey there"); + UsartHardware_TransmitString_Expect("hey there"); + + UsartConductor_Run(); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestUsartHardware.c b/tests/e2e/v1.0/temp_sensor/test/TestUsartHardware.c new file mode 100644 index 0000000..39aec77 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestUsartHardware.c @@ -0,0 +1,43 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "UsartHardware.h" +#include "MockUsartConfigurator.h" +#include "MockUsartPutChar.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldConfigureUsartPeripheralByCallingConfiguratorAppropriately(void) +{ + Usart_ConfigureUsartIO_Expect(); + Usart_EnablePeripheralClock_Expect(); + Usart_Reset_Expect(); + Usart_ConfigureMode_Expect(); + Usart_SetBaudRateRegister_Expect(73); + Usart_Enable_Expect(); + + UsartHardware_Init(73); +} + +void testTransmitStringShouldSendDesiredStringOutUsingUsart(void) +{ + Usart_PutChar_Expect('h'); + Usart_PutChar_Expect('e'); + Usart_PutChar_Expect('l'); + Usart_PutChar_Expect('l'); + Usart_PutChar_Expect('o'); + + UsartHardware_TransmitString("hello"); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestUsartIntegrated.c b/tests/e2e/v1.0/temp_sensor/test/TestUsartIntegrated.c new file mode 100644 index 0000000..3aab795 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestUsartIntegrated.c @@ -0,0 +1,63 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "UsartConductor.h" +#include "UsartModel.h" +#include "UsartHardware.h" +#include "ModelConfig.h" +#include "MockTaskScheduler.h" +#include "MockUsartConfigurator.h" +#include "MockUsartPutChar.h" +#include "MockTemperatureFilter.h" +#include "MockUsartBaudRateRegisterCalculator.h" +#include + +/* NOTE: we probably wouldn't actually perform this test on our own projects + but it's a good example of testing the same module(s) from multiple test + files, and therefore we like having it in this example. +*/ + +#ifndef TEST_USART_INTEGRATED_STRING +#define TEST_USART_INTEGRATED_STRING "THIS WILL FAIL" +#endif + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testShouldInitializeHardwareWhenInitCalled(void) +{ + size_t i; + const char* test_str = TEST_USART_INTEGRATED_STRING; + + UsartModel_CalculateBaudRateRegisterSetting_ExpectAndReturn(MASTER_CLOCK, USART0_BAUDRATE, 4); + Usart_ConfigureUsartIO_Expect(); + Usart_EnablePeripheralClock_Expect(); + Usart_Reset_Expect(); + Usart_ConfigureMode_Expect(); + Usart_SetBaudRateRegister_Expect(4); + Usart_Enable_Expect(); + for (i=0; i < strlen(test_str); i++) + { + Usart_PutChar_Expect(test_str[i]); + } + + UsartConductor_Init(); +} + +void testRunShouldNotDoAnythingIfSchedulerSaysItIsNotTimeYet(void) +{ + TaskScheduler_DoUsart_ExpectAndReturn(FALSE); + + UsartConductor_Run(); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/TestUsartModel.c b/tests/e2e/v1.0/temp_sensor/test/TestUsartModel.c new file mode 100644 index 0000000..c475392 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/TestUsartModel.c @@ -0,0 +1,47 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "UsartModel.h" +#include "ModelConfig.h" +#include "MockTemperatureFilter.h" +#include "MockUsartBaudRateRegisterCalculator.h" +#include + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testGetBaudRateRegisterSettingShouldReturnAppropriateBaudRateRegisterSetting(void) +{ + uint8 dummyRegisterSetting = 17; + UsartModel_CalculateBaudRateRegisterSetting_ExpectAndReturn(MASTER_CLOCK, USART0_BAUDRATE, dummyRegisterSetting); + + TEST_ASSERT_EQUAL_UINT8(dummyRegisterSetting, UsartModel_GetBaudRateRegisterSetting()); +} + +void testGetFormattedTemperatureFormatsTemperatureFromCalculatorAppropriately(void) +{ + TemperatureFilter_GetTemperatureInCelcius_ExpectAndReturn(25.0f); + TEST_ASSERT_EQUAL_STRING("25.0 C\n", UsartModel_GetFormattedTemperature()); +} + +void testShouldReturnErrorMessageUponInvalidTemperatureValue(void) +{ + TemperatureFilter_GetTemperatureInCelcius_ExpectAndReturn(-INFINITY); + TEST_ASSERT_EQUAL_STRING("Temperature sensor failure!\n", UsartModel_GetFormattedTemperature()); +} + +void testShouldReturnWakeupMessage(void) +{ + TEST_ASSERT_EQUAL_STRING("It's Awesome Time!\n", UsartModel_GetWakeupMessage()); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/adc/TestAdcConductor.c b/tests/e2e/v1.0/temp_sensor/test/adc/TestAdcConductor.c new file mode 100644 index 0000000..4b037e0 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/adc/TestAdcConductor.c @@ -0,0 +1,128 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "UnityHelper.h" +#include "Types.h" +#include "Types.h" +#include "AdcConductor.h" +#include "MockAdcModel.h" +#include "MockAdcHardware.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldCallHardwareInit(void) +{ + AdcHardware_Init_Expect(); + AdcConductor_Init(); +} + +void testRunShouldNotDoAnythingIfItIsNotTime(void) +{ + AdcModel_DoGetSample_ExpectAndReturn(FALSE); + + AdcConductor_Run(); +} + +void testRunShouldNotPassAdcResultToModelIfSampleIsNotComplete(void) +{ + AdcModel_DoGetSample_ExpectAndReturn(TRUE); + AdcHardware_GetSampleComplete_ExpectAndReturn(FALSE); + + AdcConductor_Run(); +} + +void testRunShouldGetLatestSampleFromAdcAndPassItToModelAndStartNewConversionWhenItIsTime(void) +{ + AdcModel_DoGetSample_ExpectAndReturn(TRUE); + AdcHardware_GetSampleComplete_ExpectAndReturn(TRUE); + AdcHardware_GetSample_ExpectAndReturn(293U); + AdcModel_ProcessInput_Expect(293U); + AdcHardware_StartConversion_Expect(); + + AdcConductor_Run(); +} + +void testJustHereToTest_Should_ProperlyPassAStructAndVerifyIt(void) +{ + EXAMPLE_STRUCT_T TestStruct; + TestStruct.x = 5; + TestStruct.y = 7; + + AdcModel_DoNothingExceptTestASpecialType_ExpectAndReturn(TestStruct, TRUE); + + TEST_ASSERT_TRUE(AdcConductor_JustHereToTest()); +} + +//void testJustHereToTest_Should_FailThisTestIfYouUncommentXIsBecauseItsWrong(void) +//{ +// EXAMPLE_STRUCT_T TestStruct; +// TestStruct.x = 6; +// TestStruct.y = 7; +// +// AdcModel_DoNothingExceptTestASpecialType_ExpectAndReturn(TestStruct, TRUE); +// +// TEST_ASSERT_TRUE(AdcConductor_JustHereToTest()); +//} +// +//void testJustHereToTest_Should_FailThisTestIfYouUncommentYIsBecauseItsWrong(void) +//{ +// EXAMPLE_STRUCT_T TestStruct; +// TestStruct.x = 5; +// TestStruct.y = 8; +// +// AdcModel_DoNothingExceptTestASpecialType_ExpectAndReturn(TestStruct, TRUE); +// +// TEST_ASSERT_TRUE(AdcConductor_JustHereToTest()); +//} + +void test_AdcConductor_AlsoHereToTest_Should_ProperlyReturnAStructAsExpected1(void) +{ + EXAMPLE_STRUCT_T TestStruct; + TestStruct.x = 99; + TestStruct.y = 1; + + AdcModel_DoNothingExceptReturnASpecialType_ExpectAndReturn(TestStruct); + + TEST_ASSERT_TRUE(AdcConductor_AlsoHereToTest()); +} + +void test_AdcConductor_AlsoHereToTest_Should_ProperlyReturnAStructAsExpected2(void) +{ + EXAMPLE_STRUCT_T TestStruct; + TestStruct.x = 98; + TestStruct.y = 1; + + AdcModel_DoNothingExceptReturnASpecialType_ExpectAndReturn(TestStruct); + + TEST_ASSERT_FALSE(AdcConductor_AlsoHereToTest()); +} + +void test_AdcConductor_YetAnotherTest_Should_VerifyThatPointersToStructsAreTestable(void) +{ + uint32 TestNum = 3; + + AdModel_DoNothingExceptTestPointers_ExpectAndReturn(&TestNum, TRUE); + + TEST_ASSERT_TRUE(AdcConductor_YetAnotherTest()); +} + +//void test_AdcConductor_YetAnotherTest_Should_FailIfYouUncommentThisTestBecauseTheValuePointedToIsWrong(void) +//{ +// uint32 TestNum = 7; +// +// AdModel_DoNothingExceptTestPointers_ExpectAndReturn(&TestNum, FALSE); +// +// TEST_ASSERT_FALSE(AdcConductor_YetAnotherTest()); +//} + diff --git a/tests/e2e/v1.0/temp_sensor/test/adc/TestAdcHardware.c b/tests/e2e/v1.0/temp_sensor/test/adc/TestAdcHardware.c new file mode 100644 index 0000000..89a222f --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/adc/TestAdcHardware.c @@ -0,0 +1,51 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "AdcHardware.h" +#include "MockAdcHardwareConfigurator.h" +#include "MockAdcTemperatureSensor.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testInitShouldDelegateToConfiguratorAndTemperatureSensor(void) +{ + Adc_Reset_Expect(); + Adc_ConfigureMode_Expect(); + Adc_EnableTemperatureChannel_Expect(); + Adc_StartTemperatureSensorConversion_Expect(); + + AdcHardware_Init(); +} + +void testGetSampleCompleteShouldReturn_FALSE_WhenTemperatureSensorSampleReadyReturns_FALSE(void) +{ + Adc_TemperatureSensorSampleReady_ExpectAndReturn(FALSE); + TEST_ASSERT(!AdcHardware_GetSampleComplete()); +} + +void testGetSampleCompleteShouldReturn_TRUE_WhenTemperatureSensorSampleReadyReturns_TRUE(void) +{ + Adc_TemperatureSensorSampleReady_ExpectAndReturn(TRUE); + TEST_ASSERT(AdcHardware_GetSampleComplete()); +} + +void testGetSampleShouldDelegateToAdcTemperatureSensor(void) +{ + uint16 sample; + Adc_ReadTemperatureSensor_ExpectAndReturn(847); + + sample = AdcHardware_GetSample(); + TEST_ASSERT_EQUAL_INT(847, sample); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/adc/TestAdcModel.c b/tests/e2e/v1.0/temp_sensor/test/adc/TestAdcModel.c new file mode 100644 index 0000000..48a9c01 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/adc/TestAdcModel.c @@ -0,0 +1,40 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "Types.h" +#include "AdcModel.h" +#include "MockTaskScheduler.h" +#include "MockTemperatureCalculator.h" +#include "MockTemperatureFilter.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void testDoGetSampleShouldReturn_FALSE_WhenTaskSchedulerReturns_FALSE(void) +{ + TaskScheduler_DoAdc_ExpectAndReturn(FALSE); + TEST_ASSERT_FALSE(AdcModel_DoGetSample()); +} + +void testDoGetSampleShouldReturn_TRUE_WhenTaskSchedulerReturns_TRUE(void) +{ + TaskScheduler_DoAdc_ExpectAndReturn(TRUE); + TEST_ASSERT_TRUE(AdcModel_DoGetSample()); +} + +void testProcessInputShouldDelegateToTemperatureCalculatorAndPassResultToFilter(void) +{ + TemperatureCalculator_Calculate_ExpectAndReturn(21473, 23.5f); + TemperatureFilter_ProcessInput_Expect(23.5f); + AdcModel_ProcessInput(21473); +} diff --git a/tests/e2e/v1.0/temp_sensor/test/support/UnityHelper.c b/tests/e2e/v1.0/temp_sensor/test/support/UnityHelper.c new file mode 100644 index 0000000..5f2552b --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/support/UnityHelper.c @@ -0,0 +1,19 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#include "unity.h" +#include "unity_internals.h" +#include "UnityHelper.h" + +#if TEST_CUSTOM_EXAMPLE_STRUCT_T +void AssertEqualEXAMPLE_STRUCT_T(const EXAMPLE_STRUCT_T expected, const EXAMPLE_STRUCT_T actual, const unsigned short line) +{ + UNITY_TEST_ASSERT_EQUAL_INT(expected.x, actual.x, line, "EXAMPLE_STRUCT_T.x check failed"); + UNITY_TEST_ASSERT_EQUAL_INT(expected.y, actual.y, line, "EXAMPLE_STRUCT_T.y check failed"); +} +#endif + diff --git a/tests/e2e/v1.0/temp_sensor/test/support/UnityHelper.h b/tests/e2e/v1.0/temp_sensor/test/support/UnityHelper.h new file mode 100644 index 0000000..c255792 --- /dev/null +++ b/tests/e2e/v1.0/temp_sensor/test/support/UnityHelper.h @@ -0,0 +1,17 @@ +/* ========================================================================= + Ceedling - Test-Centered Build System for C + ThrowTheSwitch.org + Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams + SPDX-License-Identifier: MIT +========================================================================= */ + +#ifndef _TESTHELPER_H +#define _TESTHELPER_H + +#if TEST_CUSTOM_EXAMPLE_STRUCT_T +#include "Types.h" +void AssertEqualEXAMPLE_STRUCT_T(const EXAMPLE_STRUCT_T expected, const EXAMPLE_STRUCT_T actual, const unsigned short line); +#define UNITY_TEST_ASSERT_EQUAL_EXAMPLE_STRUCT_T(expected, actual, line, message) {AssertEqualEXAMPLE_STRUCT_T(expected, actual, line);} +#endif + +#endif // _TESTHELPER_H diff --git a/tests/unit/adapter.plugin.test.ts b/tests/unit/adapter.plugin.test.ts new file mode 100644 index 0000000..af0d295 --- /dev/null +++ b/tests/unit/adapter.plugin.test.ts @@ -0,0 +1,231 @@ +import * as assert from 'assert'; +import { describe, it } from 'mocha'; + +/** + * Unit tests for Ceedling plugin compatibility in adapter.ts + * Tests both legacy xml_tests_report (0.31.x) and new report_tests_log_factory (1.0+) + */ + +describe('CeedlingAdapter Plugin Detection', () => { + + describe('sanityCheck() - Plugin Validation', () => { + + it('should accept xml_tests_report plugin (Ceedling 0.31.x)', () => { + const ymlProjectData = { + ':plugins': { + ':enabled': ['xml_tests_report'] + } + }; + + // Verify old plugin is detected + const hasXmlTestsReport = ymlProjectData[':plugins'][':enabled'].includes('xml_tests_report'); + const hasReportFactory = ymlProjectData[':plugins'][':enabled'].includes('report_tests_log_factory'); + + assert.strictEqual(hasXmlTestsReport, true, 'Should detect xml_tests_report plugin'); + assert.strictEqual(hasReportFactory, false, 'Should not detect report_tests_log_factory plugin'); + assert.strictEqual(hasXmlTestsReport || hasReportFactory, true, 'Should have at least one valid plugin'); + }); + + it('should accept report_tests_log_factory plugin with cppunit (Ceedling 1.0+)', () => { + const ymlProjectData = { + ':plugins': { + ':enabled': ['report_tests_log_factory'] + }, + ':report_tests_log_factory': { + ':reports': ['cppunit', 'junit', 'json'] + } + }; + + // Verify new plugin is detected + const hasXmlTestsReport = ymlProjectData[':plugins'][':enabled'].includes('xml_tests_report'); + const hasReportFactory = ymlProjectData[':plugins'][':enabled'].includes('report_tests_log_factory'); + + assert.strictEqual(hasXmlTestsReport, false, 'Should not detect xml_tests_report plugin'); + assert.strictEqual(hasReportFactory, true, 'Should detect report_tests_log_factory plugin'); + + // Verify cppunit format is present + const reports = ymlProjectData[':report_tests_log_factory'][':reports']; + assert.strictEqual(reports.includes('cppunit'), true, 'Should have cppunit format enabled'); + }); + + it('should reject when neither plugin is enabled', () => { + const ymlProjectData = { + ':plugins': { + ':enabled': ['module_generator', 'gcov'] + } + }; + + const hasXmlTestsReport = ymlProjectData[':plugins'][':enabled'].includes('xml_tests_report'); + const hasReportFactory = ymlProjectData[':plugins'][':enabled'].includes('report_tests_log_factory'); + + assert.strictEqual(hasXmlTestsReport || hasReportFactory, false, 'Should not have any valid plugin'); + }); + + it('should reject report_tests_log_factory without cppunit format', () => { + const ymlProjectData = { + ':plugins': { + ':enabled': ['report_tests_log_factory'] + }, + ':report_tests_log_factory': { + ':reports': ['junit', 'json'] // Missing cppunit! + } + }; + + const hasReportFactory = ymlProjectData[':plugins'][':enabled'].includes('report_tests_log_factory'); + assert.strictEqual(hasReportFactory, true, 'Plugin is enabled'); + + const reports = ymlProjectData[':report_tests_log_factory'][':reports']; + assert.strictEqual(reports.includes('cppunit'), false, 'Should not have cppunit format'); + }); + + it('should prefer xml_tests_report when both plugins are enabled', () => { + const ymlProjectData = { + ':plugins': { + ':enabled': ['xml_tests_report', 'report_tests_log_factory'] + }, + ':report_tests_log_factory': { + ':reports': ['cppunit'] + } + }; + + const hasXmlTestsReport = ymlProjectData[':plugins'][':enabled'].includes('xml_tests_report'); + const hasReportFactory = ymlProjectData[':plugins'][':enabled'].includes('report_tests_log_factory'); + + assert.strictEqual(hasXmlTestsReport, true, 'Should detect old plugin'); + assert.strictEqual(hasReportFactory, true, 'Should detect new plugin'); + // When both are present, validation should pass (old takes precedence) + }); + }); + + describe('setXmlReportPath() - Report Filename Detection', () => { + + it('should use default filename when no configuration provided', () => { + const ymlProjectData = undefined; + let reportFilename = 'report.xml'; // default + + // This is the logic from setXmlReportPath when ymlProjectData is undefined + if (!ymlProjectData) { + // Keep default + } + + assert.strictEqual(reportFilename, 'report.xml', 'Should use default filename'); + }); + + it('should detect custom filename from xml_tests_report plugin', () => { + const ymlProjectData = { + ':plugins': { + ':enabled': ['xml_tests_report'] + }, + ':xml_tests_report': { + ':artifact_filename': 'custom_report.xml' + } + }; + + let reportFilename = 'report.xml'; + + // Simulate the fallback logic - try new plugin first, then old + const newFilename = (ymlProjectData as any)[':report_tests_log_factory']?.[':cppunit']?.[':filename']; + if (newFilename) { + reportFilename = newFilename; + } else { + // Try old plugin + const oldFilename = (ymlProjectData as any)[':xml_tests_report']?.[':artifact_filename']; + if (oldFilename) { + reportFilename = oldFilename; + } + } + + assert.strictEqual(reportFilename, 'custom_report.xml', 'Should use custom filename from old plugin'); + }); + + it('should detect custom filename from report_tests_log_factory plugin', () => { + const ymlProjectData = { + ':plugins': { + ':enabled': ['report_tests_log_factory'] + }, + ':report_tests_log_factory': { + ':cppunit': { + ':filename': 'custom_cppunit.xml' + }, + ':reports': ['cppunit'] + } + }; + + let reportFilename = 'report.xml'; + + // Simulate detection - try new plugin first + try { + const newFilename = (ymlProjectData as any)[':report_tests_log_factory']?.[':cppunit']?.[':filename']; + if (newFilename) { + reportFilename = newFilename; + } + } catch (e) { } + + assert.strictEqual(reportFilename, 'custom_cppunit.xml', 'Should use custom filename from new plugin'); + }); + + it('should use default cppunit filename when report_tests_log_factory has no custom filename', () => { + const ymlProjectData = { + ':plugins': { + ':enabled': ['report_tests_log_factory'] + }, + ':report_tests_log_factory': { + ':reports': ['cppunit'] + // No :cppunit::filename specified + } + }; + + let reportFilename = 'report.xml'; + + // Try new plugin + const newFilename = (ymlProjectData as any)[':report_tests_log_factory']?.[':cppunit']?.[':filename']; + if (newFilename) { + reportFilename = newFilename; + } else { + // No custom filename, check if plugin is enabled and use default + if ((ymlProjectData as any)[':plugins'][':enabled'].includes('report_tests_log_factory')) { + reportFilename = 'cppunit_tests_report.xml'; + } + } + + assert.strictEqual(reportFilename, 'cppunit_tests_report.xml', 'Should use default cppunit filename'); + }); + + it('should prefer new plugin filename over old when both exist', () => { + const ymlProjectData = { + ':plugins': { + ':enabled': ['xml_tests_report', 'report_tests_log_factory'] + }, + ':xml_tests_report': { + ':artifact_filename': 'old_report.xml' + }, + ':report_tests_log_factory': { + ':cppunit': { + ':filename': 'new_report.xml' + }, + ':reports': ['cppunit'] + } + }; + + let reportFilename = 'report.xml'; + + // Try new plugin first (this is the order in the implementation) + try { + const newFilename = (ymlProjectData as any)[':report_tests_log_factory']?.[':cppunit']?.[':filename']; + if (newFilename) { + reportFilename = newFilename; + } + } catch (e) { + // Fall back to old + try { + const oldFilename = (ymlProjectData as any)[':xml_tests_report']?.[':artifact_filename']; + if (oldFilename) { + reportFilename = oldFilename; + } + } catch (e) { } + } + + assert.strictEqual(reportFilename, 'new_report.xml', 'Should prefer new plugin filename'); + }); + }); +});