diff --git a/.github/workflows/lab-autograding.yml b/.github/workflows/lab-autograding.yml index 918d29b8..52f68ea6 100644 --- a/.github/workflows/lab-autograding.yml +++ b/.github/workflows/lab-autograding.yml @@ -12,8 +12,9 @@ jobs: os: [ubuntu-22.04] fail-fast: false steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 with: + ref: "${{ github.event.pull_request.merge_commit_sha }}" fetch-depth: 1 - uses: actions/setup-node@v4 with: diff --git a/lab3/README.md b/lab3/README.md new file mode 100644 index 00000000..f95c2ca0 --- /dev/null +++ b/lab3/README.md @@ -0,0 +1,29 @@ +# Lab3 + +## Introduction + +In this lab, you will write unit tests for functions implemented in `main.js`. You can learn how to use classes and functions in it by uncommenting the code in it. (But remember don't commit them on GitHub) + +## Preparation (Important!!!) + +1. Sync fork on GitHub +2. `git checkout -b lab3` (**NOT** your student ID !!!) + +## Requirement + +1. (40%) Write test cases in `main_test.js` and achieve 100% code coverage. +2. (30%) For each function, parameterize their testcases to test the error-results. +3. (30%) For each function, use at least 3 parameterized testcases to test the non-error-results. + +You can run `validate.sh` in your local to test if you satisfy the requirements. + +Please note that you must not alter files other than `main_test.js`. You will get 0 points if + +1. you modify other files to achieve requirements. +2. you can't pass all CI on your PR. + +## Submission + +You need to open a pull request to your branch (e.g. 311XXXXXX, your student number) and contain the code that satisfies the abovementioned requirements. + +Moreover, please submit the URL of your PR to E3. Your submission will only be accepted when you present at both places. diff --git a/lab3/main.js b/lab3/main.js new file mode 100644 index 00000000..cee5de7f --- /dev/null +++ b/lab3/main.js @@ -0,0 +1,34 @@ +class Calculator { + exp(x) { + if (!Number.isFinite(x)) { + throw Error('unsupported operand type'); + } + const result = Math.exp(x); + if (result === Infinity) { + throw Error('overflow'); + } + return result; + } + + log(x) { + if (!Number.isFinite(x)) { + throw Error('unsupported operand type'); + } + const result = Math.log(x); + if (result === -Infinity) { + throw Error('math domain error (1)'); + } + if (Number.isNaN(result)) { + throw Error('math domain error (2)'); + } + return result; + } +} + +// const calculator = new Calculator(); +// console.log(calculator.exp(87)); +// console.log(calculator.log(48763)); + +module.exports = { + Calculator +}; \ No newline at end of file diff --git a/lab3/main_test.js b/lab3/main_test.js new file mode 100644 index 00000000..e6d6414e --- /dev/null +++ b/lab3/main_test.js @@ -0,0 +1,5 @@ +const {describe, it} = require('node:test'); +const assert = require('assert'); +const { Calculator } = require('./main'); + +// TODO: write your tests here diff --git a/lab3/validate.sh b/lab3/validate.sh new file mode 100755 index 00000000..7a758fb3 --- /dev/null +++ b/lab3/validate.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Check for unwanted files +for file in *; do + if [[ $file != "main.js" && $file != "main_test.js" && $file != "README.md" && $file != "validate.sh" ]]; then + echo "[!] Unwanted file detected: $file." + exit 1 + fi +done + +node=$(which node) +test_path="${BASH_SOURCE[0]}" +solution_path="$(realpath .)" +tmp_dir=$(mktemp -d -t lab3-XXXXXXXXXX) + +cd $tmp_dir + +rm -rf * +cp $solution_path/*.js . +result=$($"node" --test --experimental-test-coverage) ; ret=$? +if [ $ret -ne 0 ] ; then + echo "[!] testing fails" + exit 1 +else + coverage=$(echo "$result" | grep 'all files' | awk -F '|' '{print $2}' | sed 's/ //g') + if (( $(echo "$coverage < 100" | bc -l) )); then + echo "[!] Coverage is only $coverage%" + exit 1 + else + echo "[V] Coverage is 100%" + fi +fi + +rm -rf $tmp_dir + +exit 0 + +# vim: set fenc=utf8 ff=unix et sw=2 ts=2 sts=2: \ No newline at end of file