Skip to content

Commit abfc304

Browse files
你的GitHub帳號名稱你的GitHub帳號名稱
你的GitHub帳號名稱
authored and
你的GitHub帳號名稱
committed
Lab2
1 parent 5f127b3 commit abfc304

File tree

1 file changed

+184
-3
lines changed

1 file changed

+184
-3
lines changed

Diff for: lab2/main_test.js

+184-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,187 @@
1-
const test = require('node:test');
21
const assert = require('assert');
2+
const test = require('node:test');
33
const { Application, MailSystem } = require('./main');
4+
const fs = require('node:fs');
5+
const util = require('util');
6+
const writeFile = util.promisify(fs.writeFile);
7+
const unlinkFile = util.promisify(fs.unlink);
8+
9+
async function createTestFile(content = "Alice\nBob\nCharlie") {
10+
await writeFile("name_list.txt", content, 'utf-8');
11+
}
12+
13+
async function removeTestFile() {
14+
try {
15+
await unlinkFile("name_list.txt");
16+
} catch (error) {
17+
// Ignore errors
18+
}
19+
}
20+
21+
// 我們使用單獨的測試進行設置
22+
test('Setup test environment', async () => {
23+
await createTestFile();
24+
});
25+
26+
// Tests for MailSystem class
27+
test('MailSystem.write should return congratulatory message', (t) => {
28+
const mailSystem = new MailSystem();
29+
const result = mailSystem.write('John');
30+
assert.strictEqual(result, 'Congrats, John!');
31+
});
32+
33+
test('MailSystem.send should return boolean indicating success', (t) => {
34+
const mailSystem = new MailSystem();
35+
36+
const originalRandom = Math.random;
37+
38+
// Test success case
39+
Math.random = () => 0.6; // return true
40+
const successResult = mailSystem.send('John', 'Congrats, John!');
41+
assert.strictEqual(successResult, true);
42+
43+
// Test failure case
44+
Math.random = () => 0.4; // return false
45+
const failureResult = mailSystem.send('John', 'Congrats, John!');
46+
assert.strictEqual(failureResult, false);
47+
48+
Math.random = originalRandom;
49+
});
50+
51+
test('Application constructor should initialize properties', async (t) => {
52+
await createTestFile("Alice\nBob\nCharlie");
53+
const app = new Application();
54+
55+
await new Promise(resolve => setTimeout(resolve, 10));
56+
57+
assert.deepStrictEqual(app.people, ['Alice', 'Bob', 'Charlie']);
58+
assert.deepStrictEqual(app.selected, []);
59+
assert.ok(app.mailSystem instanceof MailSystem);
60+
});
61+
62+
test('getNames should read and parse names from file', async (t) => {
63+
await createTestFile("Dave\nEve\nFrank");
64+
65+
const app = new Application();
66+
const [people, selected] = await app.getNames();
67+
68+
assert.deepStrictEqual(people, ['Dave', 'Eve', 'Frank']);
69+
assert.deepStrictEqual(selected, []);
70+
});
71+
72+
test('getRandomPerson should return a person from the people array', async (t) => {
73+
const app = new Application();
74+
75+
await new Promise(resolve => setTimeout(resolve, 10));
76+
77+
app.people = ['Alice', 'Bob', 'Charlie'];
78+
79+
const originalRandom = Math.random;
80+
const originalFloor = Math.floor;
81+
82+
// Create a spy
83+
let floorCallCount = 0;
84+
Math.floor = (num) => {
85+
floorCallCount++;
86+
return originalFloor(num);
87+
};
88+
89+
Math.random = () => 0; //select idx 0
90+
assert.strictEqual(app.getRandomPerson(), 'Alice');
91+
92+
Math.random = () => 0.34; // select idx 1
93+
assert.strictEqual(app.getRandomPerson(), 'Bob');
94+
95+
Math.random = () => 0.67; // select idx 2
96+
assert.strictEqual(app.getRandomPerson(), 'Charlie');
97+
98+
assert.strictEqual(floorCallCount, 3);
99+
100+
Math.random = originalRandom;
101+
Math.floor = originalFloor;
102+
});
103+
104+
test('selectNextPerson should select a random unselected person', async (t) => {
105+
const app = new Application();
106+
await new Promise(resolve => setTimeout(resolve, 10));
107+
108+
app.people = ['Alice', 'Bob', 'Charlie'];
109+
app.selected = [];
110+
111+
const originalGetRandomPerson = app.getRandomPerson;
112+
let randomPersonCalls = 0;
113+
114+
app.getRandomPerson = () => {
115+
randomPersonCalls++;
116+
if (randomPersonCalls === 1) return 'Bob';
117+
if (randomPersonCalls === 2) return 'Bob';
118+
if (randomPersonCalls === 3) return 'Alice';
119+
return 'Charlie';
120+
};
121+
122+
const result = app.selectNextPerson();
123+
assert.strictEqual(result, 'Bob');
124+
assert.deepStrictEqual(app.selected, ['Bob']);
125+
126+
const secondResult = app.selectNextPerson();
127+
assert.strictEqual(secondResult, 'Alice');
128+
assert.deepStrictEqual(app.selected, ['Bob', 'Alice']);
129+
130+
app.getRandomPerson = originalGetRandomPerson;
131+
});
132+
133+
test('selectNextPerson should return null when all people are selected', async (t) => {
134+
const app = new Application();
135+
await new Promise(resolve => setTimeout(resolve, 10));
136+
137+
app.people = ['Alice', 'Bob'];
138+
app.selected = ['Alice', 'Bob'];
139+
140+
const result = app.selectNextPerson();
141+
142+
assert.strictEqual(result, null);
143+
});
144+
145+
test('notifySelected should send mail to all selected people', async (t) => {
146+
const app = new Application();
147+
await new Promise(resolve => setTimeout(resolve, 10));
148+
149+
app.selected = ['Alice', 'Bob'];
150+
151+
const originalWrite = app.mailSystem.write;
152+
const originalSend = app.mailSystem.send;
153+
154+
const writeCalls = [];
155+
const sendCalls = [];
156+
157+
app.mailSystem.write = (name) => {
158+
writeCalls.push(name);
159+
return `Congrats, ${name}!`;
160+
};
161+
162+
app.mailSystem.send = (name, context) => {
163+
sendCalls.push({ name, context });
164+
return true;
165+
};
166+
167+
app.notifySelected();
168+
169+
assert.strictEqual(writeCalls.length, 2);
170+
assert.strictEqual(sendCalls.length, 2);
171+
172+
assert.strictEqual(writeCalls[0], 'Alice');
173+
assert.strictEqual(writeCalls[1], 'Bob');
174+
175+
assert.strictEqual(sendCalls[0].name, 'Alice');
176+
assert.strictEqual(sendCalls[0].context, 'Congrats, Alice!');
177+
assert.strictEqual(sendCalls[1].name, 'Bob');
178+
assert.strictEqual(sendCalls[1].context, 'Congrats, Bob!');
179+
180+
app.mailSystem.write = originalWrite;
181+
app.mailSystem.send = originalSend;
182+
});
4183

5-
// TODO: write your tests here
6-
// Remember to use Stub, Mock, and Spy when necessary
184+
// 我們使用單獨的測試進行清理
185+
test('Cleanup test environment', async () => {
186+
await removeTestFile();
187+
});

0 commit comments

Comments
 (0)