Skip to content

Commit 6fa9a3b

Browse files
committed
feat: lab2
1 parent 81b5a0f commit 6fa9a3b

5 files changed

Lines changed: 155 additions & 84 deletions

File tree

lab1/main_test.js

Lines changed: 8 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -3,97 +3,21 @@ const assert = require('assert');
33
const { MyClass, Student } = require('./main');
44

55
test("Test MyClass's addStudent", () => {
6-
7-
// Create an instance of MyClass
8-
const myClass = new MyClass();
9-
10-
// Test 1: Passing a non-Student object should return -1
11-
assert.strictEqual(myClass.addStudent("Jonh"), -1, "test 1 at addStudent");
12-
13-
// Test 2: Adding a valid Student object should return index 0
14-
const student0 = new Student();
15-
student0.setName("John");
16-
assert.strictEqual(myClass.addStudent(student0), 0, "test 2 at addStudent");
17-
18-
// Test 3: Adding another Student should return index 1 (Fix the expected value)
19-
const student1 = new Student();
20-
student1.setName("Jane");
21-
assert.strictEqual(myClass.addStudent(student1), 1, "test 3 at addStudent");
22-
23-
// No need to throw an error; tests are implemented
24-
// throw new Error("Test not implemented");
6+
// TODO
7+
throw new Error("Test not implemented");
258
});
269

2710
test("Test MyClass's getStudentById", () => {
28-
29-
// Create an instance of MyClass
30-
const myClass = new MyClass();
31-
32-
// add student
33-
const student0 = new Student(), student1 = new Student(), student2 = new Student();
34-
student0.setName("Doe");
35-
36-
const newStudentId0 = myClass.addStudent(student0);
37-
38-
// Test 1: Passing an invalid ID (< 0) should return null
39-
assert.strictEqual(myClass.getStudentById(-1), null, "test 1 at getStudentById");
40-
41-
// Test 2: Valid ID should return the correct student object
42-
assert.strictEqual(myClass.getStudentById(newStudentId0), student0, "test 2 at getStudentById");
43-
44-
// Test 3: Passing an out-of-bounds ID should return null
45-
assert.strictEqual(myClass.getStudentById(999), null, "test 3 at getStudentById");
46-
47-
// No need to throw an error; tests are implemented
48-
// throw new Error("Test not implemented");
11+
// TODO
12+
throw new Error("Test not implemented");
4913
});
5014

5115
test("Test Student's setName", () => {
52-
53-
// Test 1: userName is an integer, should not change name (remain undefined)
54-
const student0 = new Student();
55-
const name0= 20250306;
56-
student0.setName(name0);
57-
assert.strictEqual(student0.getName(), '', "test 1 at setName");
58-
59-
// Test 2: userName is a float, should not change name (remain undefined)
60-
const student1 = new Student();
61-
const name1= 3.14156;
62-
student1.setName(name1);
63-
assert.strictEqual(student1.getName(), '', "test 2 at setName");
64-
65-
// Test 3: userName is a valid string, should set the name correctly
66-
const student2 = new Student();
67-
const name3= 'Smith';
68-
student2.setName(name3);
69-
assert.strictEqual(student2.getName(), name3, "test 3 at setName");
70-
71-
// No need to throw an error; tests are implemented
72-
// throw new Error("Test not implemented");
16+
// TODO
17+
throw new Error("Test not implemented");
7318
});
7419

7520
test("Test Student's getName", () => {
76-
77-
// Test 1: Set a valid name and retrieve it
78-
const student0 = new Student();
79-
const name0 = "John";
80-
student0.setName(name0);
81-
assert.strictEqual(student0.getName(), name0, "test 1 at getName");
82-
83-
// Test 2: Set an invalid name (integer), getName() should return an empty string
84-
const student1 = new Student();
85-
student1.setName(1);
86-
assert.strictEqual(student1.getName(), '', "test 2 at getName");
87-
88-
// Test 3: Set an empty string as name, should return an empty string
89-
const student2 = new Student();
90-
student2.setName('');
91-
assert.strictEqual(student2.getName(), '', "test 3 at getName");
92-
93-
// Test 4: Default value of getName() before setting any name
94-
const student3 = new Student();
95-
assert.strictEqual(student3.getName(), '', "test 4 at getName");
96-
97-
// No need to throw an error; tests are implemented
98-
// throw new Error("Test not implemented");
21+
// TODO
22+
throw new Error("Test not implemented");
9923
});

lab2/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Lab2
2+
3+
## Introduction
4+
5+
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)
6+
7+
## Requirement
8+
9+
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%)
10+
11+
You can run `validate.sh` in your local to test if you satisfy the requirements.
12+
13+
Please note that you must not alter files other than `main_test.js`. You will get 0 points if
14+
15+
1. you modify other files to achieve requirements.
16+
2. you can't pass all CI on your PR.
17+
18+
## Submission
19+
20+
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.
21+
22+
Moreover, please submit the URL of your PR to E3. Your submission will only be accepted when you present at both places.

lab2/main.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
const fs = require('fs');
2+
const util = require('util');
3+
const readFile = util.promisify(fs.readFile);
4+
5+
class MailSystem {
6+
write(name) {
7+
console.log('--write mail for ' + name + '--');
8+
const context = 'Congrats, ' + name + '!';
9+
return context;
10+
}
11+
12+
send(name, context) {
13+
console.log('--send mail to ' + name + '--');
14+
// Interact with mail system and send mail
15+
// random success or failure
16+
const success = Math.random() > 0.5;
17+
if (success) {
18+
console.log('mail sent');
19+
} else {
20+
console.log('mail failed');
21+
}
22+
return success;
23+
}
24+
}
25+
26+
class Application {
27+
constructor() {
28+
this.people = [];
29+
this.selected = [];
30+
this.mailSystem = new MailSystem();
31+
this.getNames().then(([people, selected]) => {
32+
this.people = people;
33+
this.selected = selected;
34+
});
35+
}
36+
37+
async getNames() {
38+
const data = await readFile('name_list.txt', 'utf8');
39+
const people = data.split('\n');
40+
const selected = [];
41+
return [people, selected];
42+
}
43+
44+
getRandomPerson() {
45+
const i = Math.floor(Math.random() * this.people.length);
46+
return this.people[i];
47+
}
48+
49+
selectNextPerson() {
50+
console.log('--select next person--');
51+
if (this.people.length === this.selected.length) {
52+
console.log('all selected');
53+
return null;
54+
}
55+
let person = this.getRandomPerson();
56+
while (this.selected.includes(person)) {
57+
person = this.getRandomPerson();
58+
}
59+
this.selected.push(person);
60+
return person;
61+
}
62+
63+
notifySelected() {
64+
console.log('--notify selected--');
65+
for (const x of this.selected) {
66+
const context = this.mailSystem.write(x);
67+
this.mailSystem.send(x, context);
68+
}
69+
}
70+
}
71+
72+
// const app = new Application();
73+
// app.selectNextPerson();
74+
// app.selectNextPerson();
75+
// app.selectNextPerson();
76+
// app.notifySelected();
77+
78+
module.exports = {
79+
Application,
80+
MailSystem,
81+
};

lab2/main_test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const test = require('node:test');
2+
const assert = require('assert');
3+
const { Application, MailSystem } = require('./main');
4+
5+
// TODO: write your tests here
6+
// Remember to use Stub, Mock, and Spy when necessary

lab2/validate.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
3+
# Check for unwanted files
4+
for file in *; do
5+
if [[ $file != "main.js" && $file != "main_test.js" && $file != "README.md" && $file != "validate.sh" ]]; then
6+
echo "[!] Unwanted file detected: $file."
7+
exit 1
8+
fi
9+
done
10+
11+
node=$(which node)
12+
test_path="${BASH_SOURCE[0]}"
13+
solution_path="$(realpath .)"
14+
tmp_dir=$(mktemp -d -t lab2-XXXXXXXXXX)
15+
16+
cd $tmp_dir
17+
18+
rm -rf *
19+
cp $solution_path/*.js .
20+
result=$($"node" --test --experimental-test-coverage) ; ret=$?
21+
if [ $ret -ne 0 ] ; then
22+
echo "[!] testing fails"
23+
exit 1
24+
else
25+
coverage=$(echo "$result" | grep 'all files' | awk -F '|' '{print $2}' | sed 's/ //g')
26+
if (( $(echo "$coverage < 100" | bc -l) )); then
27+
echo "[!] Coverage is only $coverage%"
28+
exit 1
29+
else
30+
echo "[V] Coverage is 100%"
31+
fi
32+
fi
33+
34+
rm -rf $tmp_dir
35+
36+
exit 0
37+
38+
# vim: set fenc=utf8 ff=unix et sw=2 ts=2 sts=2:

0 commit comments

Comments
 (0)