From 775703781c5fa5261bbdecea1afce02c885b2a1e Mon Sep 17 00:00:00 2001 From: ShangHungWan Date: Thu, 7 Mar 2024 00:12:26 +0800 Subject: [PATCH 01/12] doc: fix typo in lab1 README --- lab1/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lab1/README.md b/lab1/README.md index 5b2779a5..df0ab9f5 100644 --- a/lab1/README.md +++ b/lab1/README.md @@ -2,7 +2,7 @@ ## 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 `main.js.` (But remember don't commit them on GitHub) +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) ## Requirement From 2233c14158a4c07746a2efb364e10e2c1190e6b1 Mon Sep 17 00:00:00 2001 From: AlaRduTP Date: Wed, 13 Mar 2024 12:36:45 +0800 Subject: [PATCH 02/12] fix: improve workflows --- .github/pull_request_template.md | 4 ++-- .github/workflows/PR.yml | 2 +- .github/workflows/lab1.yml | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1074fb66..1ac3010f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -7,11 +7,11 @@ --- - + - [ ] A clear title (name your PR "[LAB{lab_number}] {your_student_id}") - [ ] A meaningful message for PR, as well as its commits - [ ] From your specific branch (***not main or other's branch***) merging to your branch - [ ] Excluding any irrelevant files, such as binaries, text files, or dot files -- [ ] Passing all CI +- [ ] Passing all CI (You should check it first to pass one of the validations in CI. However, you need to make sure your PR passes all CI after you submit it.) diff --git a/.github/workflows/PR.yml b/.github/workflows/PR.yml index 598e3b99..10f942ec 100644 --- a/.github/workflows/PR.yml +++ b/.github/workflows/PR.yml @@ -16,7 +16,7 @@ jobs: const pr = await github.rest.pulls.get({ owner, repo, pull_number: issue_number }); const title = pr.data.title; const labRegex = /\[LAB(\d+)\]/; - const titleRegex = /\[LAB\d+\] [\da-zA-Z]+/; + const titleRegex = /^\[LAB\d+\] [\da-zA-Z]+$/; if (!titleRegex.test(title)) { core.setFailed('PR title does not match the required format. Please use the format [LAB#] student#.'); diff --git a/.github/workflows/lab1.yml b/.github/workflows/lab1.yml index 1bd7d006..49a5d578 100644 --- a/.github/workflows/lab1.yml +++ b/.github/workflows/lab1.yml @@ -22,6 +22,5 @@ jobs: sudo apt-get install -y nodejs - name: grading run: | - echo "cd lab1" cd lab1 ./validate.sh From e2b8057170d91c8219433460cc61fd60a2b7ce2f Mon Sep 17 00:00:00 2001 From: AlaRduTP Date: Wed, 13 Mar 2024 12:37:29 +0800 Subject: [PATCH 03/12] fix: scripts/rebase-all.sh will fail due to too frequent remote operation --- scripts/rebase-all.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/scripts/rebase-all.sh b/scripts/rebase-all.sh index 26eef16b..2cefe8dc 100644 --- a/scripts/rebase-all.sh +++ b/scripts/rebase-all.sh @@ -12,17 +12,11 @@ for branch in $(git branch -r | grep -v HEAD); do echo "Checkout failed for branch $branch" exit 1 fi - git pull origin "$branch" - if [[ $? -ne 0 ]]; then - echo "Pull failed for branch $branch" - exit 1 - fi git rebase main if [[ $? -ne 0 ]]; then echo "Rebase failed for branch $branch" exit 1 fi - git push origin "$branch" fi done From 8336df355115175597ef649f2a6a04db8ed64a82 Mon Sep 17 00:00:00 2001 From: AlaRduTP Date: Wed, 13 Mar 2024 12:38:02 +0800 Subject: [PATCH 04/12] feat: lab2 --- .github/workflows/lab2.yml | 26 ++++++++++++ lab2/README.md | 22 +++++++++++ lab2/main.js | 81 ++++++++++++++++++++++++++++++++++++++ lab2/main_test.js | 6 +++ lab2/validate.sh | 38 ++++++++++++++++++ 5 files changed, 173 insertions(+) create mode 100644 .github/workflows/lab2.yml create mode 100644 lab2/README.md create mode 100644 lab2/main.js create mode 100644 lab2/main_test.js create mode 100755 lab2/validate.sh diff --git a/.github/workflows/lab2.yml b/.github/workflows/lab2.yml new file mode 100644 index 00000000..2cb76fa7 --- /dev/null +++ b/.github/workflows/lab2.yml @@ -0,0 +1,26 @@ +name: lab2 autograding + +on: + pull_request: + types: [labeled, synchronize, opened, reopened, ready_for_review] + +jobs: + build: + if: contains(github.event.pull_request.labels.*.name, 'lab2') + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-22.04] + fail-fast: false + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 1 + - name: dependency (ubuntu) + run: | + curl -fsSL https://deb.nodesource.com/setup_21.x | sudo -E bash - &&\ + sudo apt-get install -y nodejs + - name: grading + run: | + cd lab2 + ./validate.sh diff --git a/lab2/README.md b/lab2/README.md new file mode 100644 index 00000000..60a9c805 --- /dev/null +++ b/lab2/README.md @@ -0,0 +1,22 @@ +# Lab2 + +## 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) + +## Requirement + +1. Write test cases in `main_test.js` and achieve 100% code coverage. Remember to use Mock, Spy, or Stub when necessary, you need to at least use one of them in your test cases. (100%) + +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/lab2/main.js b/lab2/main.js new file mode 100644 index 00000000..2e159e75 --- /dev/null +++ b/lab2/main.js @@ -0,0 +1,81 @@ +const fs = require('fs'); +const util = require('util'); +const readFile = util.promisify(fs.readFile); + +class MailSystem { + write(name) { + console.log('--write mail for ' + name + '--'); + const context = 'Congrats, ' + name + '!'; + return context; + } + + send(name, context) { + console.log('--send mail to ' + name + '--'); + // Interact with mail system and send mail + // random success or failure + const success = Math.random() > 0.5; + if (success) { + console.log('mail sent'); + } else { + console.log('mail failed'); + } + return success; + } +} + +class Application { + constructor() { + this.people = []; + this.selected = []; + this.mailSystem = new MailSystem(); + this.getNames().then(([people, selected]) => { + this.people = people; + this.selected = selected; + }); + } + + async getNames() { + const data = await readFile('name_list.txt', 'utf8'); + const people = data.split('\n'); + const selected = []; + return [people, selected]; + } + + getRandomPerson() { + const i = Math.floor(Math.random() * this.people.length); + return this.people[i]; + } + + selectNextPerson() { + console.log('--select next person--'); + if (this.people.length === this.selected.length) { + console.log('all selected'); + return null; + } + let person = this.getRandomPerson(); + while (this.selected.includes(person)) { + person = this.getRandomPerson(); + } + this.selected.push(person); + return person; + } + + notifySelected() { + console.log('--notify selected--'); + for (const x of this.selected) { + const context = this.mailSystem.write(x); + this.mailSystem.send(x, context); + } + } +} + +// const app = new Application(); +// app.selectNextPerson(); +// app.selectNextPerson(); +// app.selectNextPerson(); +// app.notifySelected(); + +module.exports = { + Application, + MailSystem, +}; \ No newline at end of file diff --git a/lab2/main_test.js b/lab2/main_test.js new file mode 100644 index 00000000..5034468e --- /dev/null +++ b/lab2/main_test.js @@ -0,0 +1,6 @@ +const test = require('node:test'); +const assert = require('assert'); +const { Application, MailSystem } = require('./main'); + +// TODO: write your tests here +// Remember to use Stub, Mock, and Spy when necessary \ No newline at end of file diff --git a/lab2/validate.sh b/lab2/validate.sh new file mode 100755 index 00000000..13b53ed8 --- /dev/null +++ b/lab2/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 lab2-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 From 0f5c5ddd707093c3f5e013d117f2d11e7969da5b Mon Sep 17 00:00:00 2001 From: AlaRduTP Date: Wed, 13 Mar 2024 12:44:44 +0800 Subject: [PATCH 05/12] feat: merge-all --- scripts/merge-all.sh | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100755 scripts/merge-all.sh diff --git a/scripts/merge-all.sh b/scripts/merge-all.sh new file mode 100755 index 00000000..a3be7f90 --- /dev/null +++ b/scripts/merge-all.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +if [ $# -ne 1 ]; then + echo "./merge-all.sh " + exit 1 +fi + +git fetch origin + +for branch in $(git branch -r | grep -v HEAD); do + # Remove the "origin/" prefix + branch=${branch#origin/} + + if [[ "$branch" != "main" ]]; then + git checkout "$branch" + if [[ $? -ne 0 ]]; then + echo "Checkout failed for branch $branch" + exit 1 + fi + git merge --squash main + if [[ $? -ne 0 ]]; then + echo "Merge failed for branch $branch" + exit 1 + fi + git commit -m "$1" + fi +done + +git checkout main \ No newline at end of file From 3fe2a07e39508357abd99194f96b75afb7a73f74 Mon Sep 17 00:00:00 2001 From: funiris <162334368+funiris@users.noreply.github.com> Date: Sat, 16 Mar 2024 18:28:38 +0800 Subject: [PATCH 06/12] Update main_test.js --- lab1/main_test.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/lab1/main_test.js b/lab1/main_test.js index 74a716b4..9fe3b6e3 100644 --- a/lab1/main_test.js +++ b/lab1/main_test.js @@ -3,21 +3,29 @@ const assert = require('assert'); const { MyClass, Student } = require('./main'); test("Test MyClass's addStudent", () => { - // TODO - throw new Error("Test not implemented"); + const myClass = new MyClass(); + const student = new Student(); + student.setName('John'); + const result = myClass.addStudent(student); + assert.strictEqual(result, 0, "Student should be added successfully"); }); test("Test MyClass's getStudentById", () => { - // TODO - throw new Error("Test not implemented"); + const myClass = new MyClass(); + const student = new Student(); + student.setName('Jane'); + myClass.addStudent(student); + const retrievedStudent = myClass.getStudentById(0); + assert.strictEqual(retrievedStudent.getName(), 'Jane', "Retrieved student name should be 'Jane'"); }); test("Test Student's setName", () => { - // TODO - throw new Error("Test not implemented"); + const student = new Student(); + student.setName('Doe'); + assert.strictEqual(student.getName(), 'Doe', "Student name should be 'Doe'"); }); test("Test Student's getName", () => { - // TODO - throw new Error("Test not implemented"); -}); \ No newline at end of file + const student = new Student(); + assert.strictEqual(student.getName(), '', "Student name should be an empty string initially"); +}); From 4ec6e606dffdaf4604fcedbed538d510fdd723e2 Mon Sep 17 00:00:00 2001 From: funiris <162334368+funiris@users.noreply.github.com> Date: Sun, 17 Mar 2024 15:43:42 +0800 Subject: [PATCH 07/12] Update main_test.js --- lab2/main_test.js | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/lab2/main_test.js b/lab2/main_test.js index 5034468e..a07cd050 100644 --- a/lab2/main_test.js +++ b/lab2/main_test.js @@ -2,5 +2,38 @@ const test = require('node:test'); const assert = require('assert'); const { Application, MailSystem } = require('./main'); -// TODO: write your tests here -// Remember to use Stub, Mock, and Spy when necessary \ No newline at end of file +test("Test Application's selectNextPerson", () => { + const app = new Application(); + const initialSelectedLength = app.selected.length; + const selectedPerson = app.selectNextPerson(); + assert.strictEqual(app.selected.length, initialSelectedLength + 1, "One person should be selected"); +}); + +test("Test Application's notifySelected", () => { + const app = new Application(); + const consoleSpy = jest.spyOn(console, 'log'); + app.notifySelected(); + expect(consoleSpy).toHaveBeenCalled(); +}); + +test("Test MailSystem's write method", () => { + const mailSystem = new MailSystem(); + const name = "John"; + const context = mailSystem.write(name); + assert.strictEqual(context, `Congrats, ${name}!`, "Context should match expected"); +}); + +test("Test MailSystem's send method", () => { + const mailSystem = new MailSystem(); + const name = "John"; + const context = "Test context"; + const result = mailSystem.send(name, context); + assert(result === true || result === false, "send method should return a boolean"); +}); + +test("Test Application's getRandomPerson", () => { + const app = new Application(); + const getRandomPersonSpy = jest.spyOn(app, 'getRandomPerson'); + app.getRandomPerson(); + expect(getRandomPersonSpy).toHaveBeenCalled(); +}); From f605f92057e482cdca7fde662d5597ab61a0be23 Mon Sep 17 00:00:00 2001 From: funiris <162334368+funiris@users.noreply.github.com> Date: Mon, 18 Mar 2024 19:30:22 +0800 Subject: [PATCH 08/12] first main_test.js --- lab2/main_test.js | 37 ++----------------------------------- 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/lab2/main_test.js b/lab2/main_test.js index a07cd050..0c3108d6 100644 --- a/lab2/main_test.js +++ b/lab2/main_test.js @@ -2,38 +2,5 @@ const test = require('node:test'); const assert = require('assert'); const { Application, MailSystem } = require('./main'); -test("Test Application's selectNextPerson", () => { - const app = new Application(); - const initialSelectedLength = app.selected.length; - const selectedPerson = app.selectNextPerson(); - assert.strictEqual(app.selected.length, initialSelectedLength + 1, "One person should be selected"); -}); - -test("Test Application's notifySelected", () => { - const app = new Application(); - const consoleSpy = jest.spyOn(console, 'log'); - app.notifySelected(); - expect(consoleSpy).toHaveBeenCalled(); -}); - -test("Test MailSystem's write method", () => { - const mailSystem = new MailSystem(); - const name = "John"; - const context = mailSystem.write(name); - assert.strictEqual(context, `Congrats, ${name}!`, "Context should match expected"); -}); - -test("Test MailSystem's send method", () => { - const mailSystem = new MailSystem(); - const name = "John"; - const context = "Test context"; - const result = mailSystem.send(name, context); - assert(result === true || result === false, "send method should return a boolean"); -}); - -test("Test Application's getRandomPerson", () => { - const app = new Application(); - const getRandomPersonSpy = jest.spyOn(app, 'getRandomPerson'); - app.getRandomPerson(); - expect(getRandomPersonSpy).toHaveBeenCalled(); -}); +// TODO: write your tests here +// Remember to use Stub, Mock, and Spy when necessary From 81f4cdc9a71924ce3cb9c4a4e5b8d3a7944bf1d9 Mon Sep 17 00:00:00 2001 From: funiris <162334368+funiris@users.noreply.github.com> Date: Mon, 18 Mar 2024 21:46:47 +0800 Subject: [PATCH 09/12] Update main_test.js --- lab1/main_test.js | 54 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/lab1/main_test.js b/lab1/main_test.js index 9fe3b6e3..71883dc4 100644 --- a/lab1/main_test.js +++ b/lab1/main_test.js @@ -4,28 +4,58 @@ const { MyClass, Student } = require('./main'); test("Test MyClass's addStudent", () => { const myClass = new MyClass(); - const student = new Student(); - student.setName('John'); - const result = myClass.addStudent(student); - assert.strictEqual(result, 0, "Student should be added successfully"); + const student1 = new Student(); + const student2 = new Student(); + + // Adding the first student + const studentId1 = myClass.addStudent(student1); + expect(studentId1).to.equal(0); + + // Adding the second student + const studentId2 = myClass.addStudent(student2); + expect(studentId2).to.equal(1); }); test("Test MyClass's getStudentById", () => { const myClass = new MyClass(); - const student = new Student(); - student.setName('Jane'); - myClass.addStudent(student); - const retrievedStudent = myClass.getStudentById(0); - assert.strictEqual(retrievedStudent.getName(), 'Jane', "Retrieved student name should be 'Jane'"); + const student1 = new Student(); + const student2 = new Student(); + student1.setName('John'); + student2.setName('Jane'); + myClass.addStudent(student1); + myClass.addStudent(student2); + + // Getting an existing student + const existingStudent1 = myClass.getStudentById(0); + expect(existingStudent1.getName()).to.equal('John'); + + const existingStudent2 = myClass.getStudentById(1); + expect(existingStudent2.getName()).to.equal('Jane'); + + // Getting a non-existing student + const nonExistingStudent = myClass.getStudentById(2); + expect(nonExistingStudent).to.be.null; }); test("Test Student's setName", () => { const student = new Student(); - student.setName('Doe'); - assert.strictEqual(student.getName(), 'Doe', "Student name should be 'Doe'"); + + // Setting a valid name + student.setName('John'); + expect(student.getName()).to.equal('John'); + + // Setting an invalid name + student.setName(123); // Setting a non-string name + expect(student.getName()).to.equal(''); // Name should remain unchanged }); test("Test Student's getName", () => { const student = new Student(); - assert.strictEqual(student.getName(), '', "Student name should be an empty string initially"); + + // Getting name when it's not set + expect(student.getName()).to.equal(''); + + // Getting name after setting it + student.setName('Jane'); + expect(student.getName()).to.equal('Jane'); }); From cb7aacd1b87b0c10cdaa9ee9638bcc2648d3b71a Mon Sep 17 00:00:00 2001 From: funiris <162334368+funiris@users.noreply.github.com> Date: Mon, 18 Mar 2024 21:48:04 +0800 Subject: [PATCH 10/12] Update main_test.js --- lab2/main_test.js | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/lab2/main_test.js b/lab2/main_test.js index 0c3108d6..1d09ee75 100644 --- a/lab2/main_test.js +++ b/lab2/main_test.js @@ -2,5 +2,46 @@ const test = require('node:test'); const assert = require('assert'); const { Application, MailSystem } = require('./main'); -// TODO: write your tests here -// Remember to use Stub, Mock, and Spy when necessary +test("Test Application's selectNextPerson", () => { + const app = new Application(); + const initialSelectedLength = app.selected.length; + const selectedPerson = app.selectNextPerson(); + assert.strictEqual(app.selected.length, initialSelectedLength + 1, "One person should be selected"); +}); + +test("Test Application's notifySelected", () => { + const app = new Application(); + const consoleSpy = jest.spyOn(console, 'log'); + app.notifySelected(); + expect(consoleSpy).toHaveBeenCalled(); +}); + +test("Test MailSystem's write method", () => { + const mailSystem = new MailSystem(); + const name = "John"; + const context = mailSystem.write(name); + assert.strictEqual(context, `Congrats, ${name}!`, "Context should match expected"); +}); + +test("Test MailSystem's send method", () => { + const mailSystem = new MailSystem(); + const name = "John"; + const context = "Test context"; + const result = mailSystem.send(name, context); + assert(result === true || result === false, "send method should return a boolean"); +}); + +test("Test Application's getRandomPerson", () => { + const app = new Application(); + const getRandomPersonSpy = jest.spyOn(app, 'getRandomPerson'); + app.getRandomPerson(); + expect(getRandomPersonSpy).toHaveBeenCalled(); +}); + +test("Test Application's getRandomPerson with stubbed getNames method", () => { + const app = new Application(); + const stubbedNames = ['John', 'Jane', 'Doe']; + app.getNames = jest.fn().mockResolvedValue([stubbedNames, []]); + const randomPerson = app.getRandomPerson(); + expect(stubbedNames).toContain(randomPerson); +}); From f21b8fe4281c09639c6f86b25d31c021540d32e4 Mon Sep 17 00:00:00 2001 From: funiris <162334368+funiris@users.noreply.github.com> Date: Tue, 19 Mar 2024 20:54:40 +0800 Subject: [PATCH 11/12] Update main_test.js --- lab1/main_test.js | 117 +++++++++++++++++++++++++++++++--------------- 1 file changed, 80 insertions(+), 37 deletions(-) diff --git a/lab1/main_test.js b/lab1/main_test.js index 71883dc4..51230e1c 100644 --- a/lab1/main_test.js +++ b/lab1/main_test.js @@ -4,58 +4,101 @@ const { MyClass, Student } = require('./main'); test("Test MyClass's addStudent", () => { const myClass = new MyClass(); - const student1 = new Student(); - const student2 = new Student(); - // Adding the first student - const studentId1 = myClass.addStudent(student1); - expect(studentId1).to.equal(0); + // 測試正確的學生物件是否被成功加入到班級中 + const student = new Student(); + student.setName("John"); + const result = myClass.addStudent(student); + assert.strict(result, 0); // 預期加入成功,並且回傳加入的位置為 0 + + // 測試傳入非學生物件時是否回傳 -1 + const nonStudent = {}; // 非學生物件 + const resultNonStudent = myClass.addStudent(nonStudent); + assert.strictEqual(resultNonStudent, -1); // 預期回傳 -1 - // Adding the second student - const studentId2 = myClass.addStudent(student2); - expect(studentId2).to.equal(1); + // 新增測試對 MyClass 的其他方法進行邊界測試,例如空值或邊界情況 + // 測試傳入空值時是否回傳 -1 + const resultNull = myClass.addStudent(null); + assert.strictEqual(resultNull, -1); // 預期回傳 -1 }); test("Test MyClass's getStudentById", () => { const myClass = new MyClass(); - const student1 = new Student(); - const student2 = new Student(); - student1.setName('John'); - student2.setName('Jane'); - myClass.addStudent(student1); - myClass.addStudent(student2); - - // Getting an existing student - const existingStudent1 = myClass.getStudentById(0); - expect(existingStudent1.getName()).to.equal('John'); - - const existingStudent2 = myClass.getStudentById(1); - expect(existingStudent2.getName()).to.equal('Jane'); - - // Getting a non-existing student - const nonExistingStudent = myClass.getStudentById(2); - expect(nonExistingStudent).to.be.null; + const student = new Student(); + student.setName("Jane"); + myClass.addStudent(student); + + // 測試給定正確 id 時是否能夠正確地取得對應的學生物件 + const retrievedStudent = myClass.getStudentById(0); + assert.strictEqual(retrievedStudent.getName(), "Jane"); // 預期取得的學生名稱為 "Jane" + + // 測試給定不存在的 id 時是否回傳 null + const nonExistentStudent = myClass.getStudentById(1); + assert.strictEqual(nonExistentStudent, null); // 預期回傳 null + + // 新增測試對 MyClass 的其他方法進行邊界測試,例如空值或邊界情況 + // 測試給定負數的 id 時是否回傳 null + const resultNegativeId = myClass.getStudentById(-1); + assert.strictEqual(resultNegativeId, null); // 預期回傳 null + + // 測試在空的學生列表中查找學生時是否回傳 null + const resultEmptyList = myClass.getStudentById(0); + assert.strictEqual(resultEmptyList, null); // 預期回傳 null + + // 新增測試傳入空字串時是否回傳 -1 + const emptyStringStudent = ""; // 空字串 + const resultEmptyStringStudent = myClass.addStudent(emptyStringStudent); + assert.strictEqual(resultEmptyStringStudent, -1); // 預期回傳 -1 + + // 新增測試傳入數字時是否回傳 -1 + const numberStudent = 123; // 數字 + const resultNumberStudent = myClass.addStudent(numberStudent); + assert.strictEqual(resultNumberStudent, -1); // 預期回傳 -1 + + // 新增測試傳入布林值時是否回傳 -1 + const booleanStudent = true; // 布林值 + const resultBooleanStudent = myClass.addStudent(booleanStudent); + assert.strictEqual(resultBooleanStudent, -1); // 預期回傳 -1 + }); test("Test Student's setName", () => { const student = new Student(); - // Setting a valid name - student.setName('John'); - expect(student.getName()).to.equal('John'); + // 測試設定學生姓名的功能是否正常運作 + student.setName("Alice"); + assert.strictEqual(student.name, "Alice"); // 預期設定學生姓名為 "Alice" + + // 新增測試對 Student 的其他方法進行邊界測試,例如空值或邊界情況 + // 測試傳入空值時是否正確處理 + student.setName(null); + assert.strictEqual(student.getName(), ""); // 預期取得的學生姓名為空字串 + + // 測試傳入非字串類型的姓名是否能正確處理 + student.setName(123); // 傳入數字 + assert.strictEqual(student.getName(), ""); // 預期取得的學生姓名為空字串 + + // 新增測試傳入空字串時是否回傳 -1 + const emptyStringStudent = ""; // 空字串 + const resultEmptyStringStudent = myClass.addStudent(emptyStringStudent); + assert.strictEqual(resultEmptyStringStudent, -1); // 預期回傳 -1 + + // 新增測試傳入數字時是否回傳 -1 + const numberStudent = 123; // 數字 + const resultNumberStudent = myClass.addStudent(numberStudent); + assert.strictEqual(resultNumberStudent, -1); // 預期回傳 -1 + + // 新增測試傳入布林值時是否回傳 -1 + const booleanStudent = true; // 布林值 + const resultBooleanStudent = myClass.addStudent(booleanStudent); + assert.strictEqual(resultBooleanStudent, -1); // 預期回傳 -1 - // Setting an invalid name - student.setName(123); // Setting a non-string name - expect(student.getName()).to.equal(''); // Name should remain unchanged }); test("Test Student's getName", () => { const student = new Student(); - // Getting name when it's not set - expect(student.getName()).to.equal(''); - - // Getting name after setting it - student.setName('Jane'); - expect(student.getName()).to.equal('Jane'); + // 測試取得學生姓名的功能是否正常運作 + student.setName("Bob"); + assert.strictEqual(student.getName(), "Bob"); // 預期取得的學生姓名為 "Bob" }); From 9788d389671aa81a0ac7b31ab6205fc3d2babd36 Mon Sep 17 00:00:00 2001 From: funiris <162334368+funiris@users.noreply.github.com> Date: Tue, 19 Mar 2024 22:46:45 +0800 Subject: [PATCH 12/12] Update main_test.js 0319 --- lab1/main_test.js | 116 ++++++++++++++-------------------------------- 1 file changed, 36 insertions(+), 80 deletions(-) diff --git a/lab1/main_test.js b/lab1/main_test.js index 51230e1c..2bb19a34 100644 --- a/lab1/main_test.js +++ b/lab1/main_test.js @@ -3,102 +3,58 @@ const assert = require('assert'); const { MyClass, Student } = require('./main'); test("Test MyClass's addStudent", () => { + // Test adding a valid student const myClass = new MyClass(); - - // 測試正確的學生物件是否被成功加入到班級中 - const student = new Student(); - student.setName("John"); - const result = myClass.addStudent(student); - assert.strict(result, 0); // 預期加入成功,並且回傳加入的位置為 0 - - // 測試傳入非學生物件時是否回傳 -1 - const nonStudent = {}; // 非學生物件 - const resultNonStudent = myClass.addStudent(nonStudent); - assert.strictEqual(resultNonStudent, -1); // 預期回傳 -1 - - // 新增測試對 MyClass 的其他方法進行邊界測試,例如空值或邊界情況 - // 測試傳入空值時是否回傳 -1 - const resultNull = myClass.addStudent(null); - assert.strictEqual(resultNull, -1); // 預期回傳 -1 + const student1 = new Student(); + assert.strictEqual(myClass.addStudent(student1), 0); + assert.strictEqual(myClass.students.length, 1); + assert.strictEqual(myClass.students[0], student1); + + // Test adding another valid student + const student2 = new Student(); + assert.strictEqual(myClass.addStudent(student2), 1); + assert.strictEqual(myClass.students.length, 2); + assert.strictEqual(myClass.students[1], student2); + + // Test adding an invalid student + assert.strictEqual(myClass.addStudent({}), -1); + assert.strictEqual(myClass.students.length, 2); // Should not add invalid student }); test("Test MyClass's getStudentById", () => { + // Test getting student by valid id const myClass = new MyClass(); - const student = new Student(); - student.setName("Jane"); - myClass.addStudent(student); - - // 測試給定正確 id 時是否能夠正確地取得對應的學生物件 - const retrievedStudent = myClass.getStudentById(0); - assert.strictEqual(retrievedStudent.getName(), "Jane"); // 預期取得的學生名稱為 "Jane" - - // 測試給定不存在的 id 時是否回傳 null - const nonExistentStudent = myClass.getStudentById(1); - assert.strictEqual(nonExistentStudent, null); // 預期回傳 null - - // 新增測試對 MyClass 的其他方法進行邊界測試,例如空值或邊界情況 - // 測試給定負數的 id 時是否回傳 null - const resultNegativeId = myClass.getStudentById(-1); - assert.strictEqual(resultNegativeId, null); // 預期回傳 null + const student1 = new Student(); + const student2 = new Student(); - // 測試在空的學生列表中查找學生時是否回傳 null - const resultEmptyList = myClass.getStudentById(0); - assert.strictEqual(resultEmptyList, null); // 預期回傳 null + myClass.addStudent(student1); + myClass.addStudent(student2); - // 新增測試傳入空字串時是否回傳 -1 - const emptyStringStudent = ""; // 空字串 - const resultEmptyStringStudent = myClass.addStudent(emptyStringStudent); - assert.strictEqual(resultEmptyStringStudent, -1); // 預期回傳 -1 - - // 新增測試傳入數字時是否回傳 -1 - const numberStudent = 123; // 數字 - const resultNumberStudent = myClass.addStudent(numberStudent); - assert.strictEqual(resultNumberStudent, -1); // 預期回傳 -1 - - // 新增測試傳入布林值時是否回傳 -1 - const booleanStudent = true; // 布林值 - const resultBooleanStudent = myClass.addStudent(booleanStudent); - assert.strictEqual(resultBooleanStudent, -1); // 預期回傳 -1 + assert.strictEqual(myClass.getStudentById(0), student1); + assert.strictEqual(myClass.getStudentById(1), student2); + // Test getting student by invalid id + assert.strictEqual(myClass.getStudentById(-1), null); + assert.strictEqual(myClass.getStudentById(2), null); }); test("Test Student's setName", () => { + // Test setting valid name const student = new Student(); + student.setName("CHINA"); + assert.strictEqual(student.name, "CHINA"); - // 測試設定學生姓名的功能是否正常運作 - student.setName("Alice"); - assert.strictEqual(student.name, "Alice"); // 預期設定學生姓名為 "Alice" - - // 新增測試對 Student 的其他方法進行邊界測試,例如空值或邊界情況 - // 測試傳入空值時是否正確處理 - student.setName(null); - assert.strictEqual(student.getName(), ""); // 預期取得的學生姓名為空字串 - - // 測試傳入非字串類型的姓名是否能正確處理 - student.setName(123); // 傳入數字 - assert.strictEqual(student.getName(), ""); // 預期取得的學生姓名為空字串 - - // 新增測試傳入空字串時是否回傳 -1 - const emptyStringStudent = ""; // 空字串 - const resultEmptyStringStudent = myClass.addStudent(emptyStringStudent); - assert.strictEqual(resultEmptyStringStudent, -1); // 預期回傳 -1 - - // 新增測試傳入數字時是否回傳 -1 - const numberStudent = 123; // 數字 - const resultNumberStudent = myClass.addStudent(numberStudent); - assert.strictEqual(resultNumberStudent, -1); // 預期回傳 -1 - - // 新增測試傳入布林值時是否回傳 -1 - const booleanStudent = true; // 布林值 - const resultBooleanStudent = myClass.addStudent(booleanStudent); - assert.strictEqual(resultBooleanStudent, -1); // 預期回傳 -1 - + // Test setting invalid name + student.setName(8081); + assert.strictEqual(student.name, "CHINA"); // Should not change name if invalid }); test("Test Student's getName", () => { + // Test getting name when name is not set const student = new Student(); + assert.strictEqual(student.getName(), ""); - // 測試取得學生姓名的功能是否正常運作 - student.setName("Bob"); - assert.strictEqual(student.getName(), "Bob"); // 預期取得的學生姓名為 "Bob" + // Test getting name when name is set + student.setName("CUBA"); + assert.strictEqual(student.getName(), "CUBA"); });