Skip to content

Commit fc4b5a3

Browse files
authored
Merge pull request #190 from vivian921207/111550064
[LAB2] 111550064
2 parents fe005ce + 08c2f7b commit fc4b5a3

1 file changed

Lines changed: 119 additions & 3 deletions

File tree

lab2/main_test.js

Lines changed: 119 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,122 @@
11
const test = require('node:test');
22
const assert = require('assert');
3-
const { Application, MailSystem } = require('./main');
3+
const fs = require('fs');
4+
const util = require('util');
45

5-
// TODO: write your tests here
6-
// Remember to use Stub, Mock, and Spy when necessary
6+
// 1️⃣ Stub `fs.readFile` 為 Promise 版本
7+
fs.readFile = util.promisify((path, encoding, callback) => {
8+
callback(null, 'Alice\nBob\nCharlie\nDavid'); // 回傳假名單
9+
});
10+
11+
const { Application, MailSystem } = require('./main'); // 確保這是你的主程式
12+
13+
test('Application getNames should return list of names from stubbed file', async () => {
14+
const app = new Application();
15+
await new Promise((resolve) => setTimeout(resolve, 100)); // 確保 `getNames` 完成
16+
assert.deepStrictEqual(app.people, ['Alice', 'Bob', 'Charlie', 'David']);
17+
});
18+
19+
test('MailSystem write should generate mail content', () => {
20+
const mailSystem = new MailSystem();
21+
const name = 'Alice';
22+
const result = mailSystem.write(name);
23+
assert.strictEqual(result, 'Congrats, Alice!');
24+
});
25+
26+
test('MailSystem send should return both true and false', () => {
27+
const mailSystem = new MailSystem();
28+
const name = 'Alice';
29+
const context = 'Congrats, Alice!';
30+
31+
let seenTrue = false;
32+
let seenFalse = false;
33+
let attempts = 0;
34+
const maxAttempts = 100; // 限制最大迴圈次數避免無窮迴圈
35+
36+
while (!(seenTrue && seenFalse) && attempts < maxAttempts) {
37+
const result = mailSystem.send(name, context);
38+
if (result) {
39+
seenTrue = true;
40+
} else {
41+
seenFalse = true;
42+
}
43+
attempts++;
44+
}
45+
46+
assert.strictEqual(seenTrue, true, 'MailSystem.send() should return true at least once');
47+
assert.strictEqual(seenFalse, true, 'MailSystem.send() should return false at least once');
48+
});
49+
50+
51+
test('Application getRandomPerson should return a valid person', async () => {
52+
const app = new Application();
53+
await new Promise((resolve) => setTimeout(resolve, 100)); // 確保 getNames 完成
54+
const person = app.getRandomPerson();
55+
assert.ok(['Alice', 'Bob', 'Charlie', 'David'].includes(person));
56+
});
57+
58+
test('Application selectNextPerson should return null when all are selected', async () => {
59+
const app = new Application();
60+
await new Promise((resolve) => setTimeout(resolve, 100));
61+
app.people = ['Alice', 'Bob'];
62+
app.selected = ['Alice', 'Bob'];
63+
const result = app.selectNextPerson();
64+
assert.strictEqual(result, null);
65+
});
66+
67+
test('Application selectNextPerson should select a new person each time', async () => {
68+
const app = new Application();
69+
await new Promise((resolve) => setTimeout(resolve, 100));
70+
const selected1 = app.selectNextPerson();
71+
const selected2 = app.selectNextPerson();
72+
assert.notStrictEqual(selected1, null);
73+
assert.notStrictEqual(selected2, null);
74+
assert.notStrictEqual(selected1, selected2);
75+
});
76+
77+
test('Application selectNextPerson should avoid duplicate selection', async () => {
78+
const app = new Application();
79+
await new Promise((resolve) => setTimeout(resolve, 100));
80+
app.people = ['Alice', 'Bob', 'Charlie', 'David'];
81+
app.selected = ['Alice'];
82+
const selected = new Set(app.selected);
83+
for (let i = 0; i < 4; i++) {
84+
const newPerson = app.selectNextPerson();
85+
assert.ok(!selected.has(newPerson));
86+
selected.add(newPerson);
87+
}
88+
});
89+
90+
test('Application notifySelected should send emails to selected people', async () => {
91+
const app = new Application();
92+
await new Promise((resolve) => setTimeout(resolve, 100));
93+
app.selectNextPerson();
94+
app.selectNextPerson();
95+
96+
// Spy: 監視方法呼叫次數
97+
let writeCallCount = 0;
98+
let sendCallCount = 0;
99+
100+
const originalWrite = app.mailSystem.write;
101+
const originalSend = app.mailSystem.send;
102+
103+
// Mock: 取代方法回傳預期值
104+
app.mailSystem.write = () => {
105+
writeCallCount++;
106+
return 'Mock Content';
107+
};
108+
109+
app.mailSystem.send = () => {
110+
sendCallCount++;
111+
return true;
112+
};
113+
114+
app.notifySelected();
115+
116+
assert.strictEqual(writeCallCount, app.selected.length);
117+
assert.strictEqual(sendCallCount, app.selected.length);
118+
119+
// 還原原始方法
120+
app.mailSystem.write = originalWrite;
121+
app.mailSystem.send = originalSend;
122+
});

0 commit comments

Comments
 (0)