Skip to content

Commit 544d7b4

Browse files
committed
feat: lab3
1 parent 6b0dc06 commit 544d7b4

File tree

5 files changed

+108
-87
lines changed

5 files changed

+108
-87
lines changed

lab2/main_test.js

+2-87
Original file line numberDiff line numberDiff line change
@@ -2,90 +2,5 @@ const test = require('node:test');
22
const assert = require('assert');
33
const { Application, MailSystem } = require('./main');
44

5-
// // TODO: write your tests here
6-
// // Remember to use Stub, Mock, and Spy when necessary
7-
const fs = require('fs');
8-
const path = require('path');
9-
10-
test('MailSystem should return the correct message context.', () => {
11-
const mailSystem = new MailSystem();
12-
const message = mailSystem.write('Justin');
13-
14-
assert.strictEqual(message, 'Congrats, Justin!');
15-
});
16-
17-
test('MailSystem should send mail corrctly', () => {
18-
const mailSystem = new MailSystem();
19-
20-
// SUCCESSFUL CASE
21-
test.mock.method(Math,'random', () => 1);
22-
let isMailSent = mailSystem.send('Alice', "Hello Message");
23-
assert.strictEqual(isMailSent, true, 'Mail should be sent successfully when Math.random() returns 1');
24-
25-
// FAIL CASE
26-
test.mock.method(Math, 'random', () => 0.5);
27-
isMailSent = mailSystem.send('Alice', "Hello Message");
28-
assert.strictEqual(isMailSent, false, 'Mail should fail to send when Math.random() returns a value less than 0.5');
29-
});
30-
31-
test('Application should read names from file correctly', async()=>{
32-
const nameList = 'Alice\nBob\nCharlie\nSam';
33-
const filePath = path.resolve('name_list.txt');
34-
fs.writeFileSync(filePath, nameList);
35-
36-
const app = new Application();
37-
const [names, selected] = await app.getNames(filePath);
38-
39-
assert.deepStrictEqual(names, ['Alice', 'Bob', 'Charlie', 'Sam']);
40-
assert.deepStrictEqual(selected, []);
41-
});
42-
43-
test('Application should return null when all people are selected', async (t) => {
44-
const app = new Application();
45-
app.people = ['Alice', 'Bob', 'Charlie'];
46-
app.selected = ['Alice', 'Bob', 'Charlie'];
47-
48-
const selectedPerson = app.selectNextPerson();
49-
assert.strictEqual(selectedPerson, null);
50-
});
51-
52-
test('Application should return a person randomly selected from the list', () => {
53-
Math.random = () => 0.2;
54-
55-
const app = new Application();
56-
app.people = ['Alice', 'Bob', 'Charlie'];
57-
58-
const selectedPerson = app.getRandomPerson();
59-
assert(app.people.includes(selectedPerson));
60-
});
61-
62-
test('Application should ensure no person is selected more than once', () => {
63-
const app = new Application();
64-
app.people = ['Alice', 'Bob', 'Charlie'];
65-
66-
let randomCallCount = 0;
67-
const people = ['Alice', 'Bob', 'Charlie'];
68-
app.getRandomPerson = () => people[randomCallCount++ % people.length];
69-
70-
app.selected = ['Alice', 'Bob'];
71-
72-
const nextSelectedPerson = app.selectNextPerson();
73-
assert.strictEqual(nextSelectedPerson, 'Charlie');
74-
assert.strictEqual(randomCallCount, 3);
75-
});
76-
77-
test('Application should call write and send for each selected person', () => {
78-
const writeMock = test.mock.fn(() => 'Message context');
79-
const sendMock = test.mock.fn(() => true);
80-
81-
const app = new Application();
82-
app.mailSystem.write = writeMock;
83-
app.mailSystem.send = sendMock;
84-
85-
app.selected = ['Alice', 'Bob', 'Charlie'];
86-
87-
app.notifySelected();
88-
89-
assert.strictEqual(writeMock.mock.callCount(), 3);
90-
assert.strictEqual(sendMock.mock.callCount(), 3);
91-
});
5+
// TODO: write your tests here
6+
// Remember to use Stub, Mock, and Spy when necessary

lab3/README.md

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Lab3
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+
## Preparation (Important!!!)
8+
9+
1. Sync fork on GitHub
10+
2. `git checkout -b lab3` (**NOT** your student ID !!!)
11+
12+
## Requirement
13+
14+
1. (40%) Write test cases in `main_test.js` and achieve 100% code coverage.
15+
2. (30%) For each function, parameterize their testcases to test the error-results.
16+
3. (30%) For each function, use at least 3 parameterized testcases to test the non-error-results.
17+
18+
You can run `validate.sh` in your local to test if you satisfy the requirements.
19+
20+
Please note that you must not alter files other than `main_test.js`. You will get 0 points if
21+
22+
1. you modify other files to achieve requirements.
23+
2. you can't pass all CI on your PR.
24+
25+
## Submission
26+
27+
You need to open a pull request to your branch (e.g. 312XXXXXX, your student number) and contain the code that satisfies the abovementioned requirements.
28+
29+
Moreover, please submit the URL of your PR to E3. Your submission will only be accepted when you present at both places.

lab3/main.js

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
class Calculator {
2+
exp(x) {
3+
if (!Number.isFinite(x)) {
4+
throw Error('unsupported operand type');
5+
}
6+
const result = Math.exp(x);
7+
if (result === Infinity) {
8+
throw Error('overflow');
9+
}
10+
return result;
11+
}
12+
13+
log(x) {
14+
if (!Number.isFinite(x)) {
15+
throw Error('unsupported operand type');
16+
}
17+
const result = Math.log(x);
18+
if (result === -Infinity) {
19+
throw Error('math domain error (1)');
20+
}
21+
if (Number.isNaN(result)) {
22+
throw Error('math domain error (2)');
23+
}
24+
return result;
25+
}
26+
}
27+
28+
// const calculator = new Calculator();
29+
// console.log(calculator.exp(87));
30+
// console.log(calculator.log(48763));
31+
32+
module.exports = {
33+
Calculator
34+
};

lab3/main_test.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const {describe, it} = require('node:test');
2+
const assert = require('assert');
3+
const { Calculator } = require('./main');
4+
5+
// TODO: write your tests here

lab3/validate.sh

+38
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 lab3-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)