From 8114b979226d2b3fc9eeb084a5c291d33854f24e Mon Sep 17 00:00:00 2001 From: liujayo <37663339+toey8612@users.noreply.github.com> Date: Sun, 17 Mar 2024 15:17:45 +0800 Subject: [PATCH 1/6] Update main_test.js --- lab2/main_test.js | 49 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/lab2/main_test.js b/lab2/main_test.js index 5034468e..2fc698b3 100644 --- a/lab2/main_test.js +++ b/lab2/main_test.js @@ -3,4 +3,51 @@ 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 +// Remember to use Stub, Mock, and Spy when necessary + +const sinon = require('sinon'); + +test('Application selects unique people', async () => { + const app = new Application(); + const people = ['Alice', 'Bob', 'Charlie']; + sinon.stub(app, 'getNames').resolves([people, []]); + + const selected1 = await app.selectNextPerson(); + const selected2 = await app.selectNextPerson(); + const selected3 = await app.selectNextPerson(); + + assert.notEqual(selected1, selected2); + assert.notEqual(selected1, selected3); + assert.notEqual(selected2, selected3); +}); + +test('Application notifies selected people', async () => { + const app = new Application(); + const people = ['Alice']; + sinon.stub(app, 'getNames').resolves([people, []]); + sinon.stub(app.mailSystem, 'write').returns('Test context'); + sinon.spy(app.mailSystem, 'send'); + + await app.selectNextPerson(); + await app.notifySelected(); + + assert.strictEqual(app.mailSystem.send.callCount, 1); + assert.strictEqual(app.mailSystem.send.args[0][0], 'Alice'); + assert.strictEqual(app.mailSystem.send.args[0][1], 'Test context'); +}); + +// 測試 MailSystem 類 +test('MailSystem writes mail content', () => { + const mailSystem = new MailSystem(); + const context = mailSystem.write('John Doe'); + assert.strictEqual(context, 'Congrats, John Doe!'); +}); + +test('MailSystem sends mail with success or failure', async () => { + const mailSystem = new MailSystem(); + sinon.stub(console, 'log'); // console.log 输出 + + await mailSystem.send('John Doe', 'Test context'); + assert(console.log.calledWith('--send mail to John Doe--')); + assert(console.log.calledWith('mail sent')); // 或 mail failed +}); From 3e99541e1989df5a62a6b4a43fa98e3a878e8742 Mon Sep 17 00:00:00 2001 From: liujayo <37663339+toey8612@users.noreply.github.com> Date: Sun, 17 Mar 2024 15:46:20 +0800 Subject: [PATCH 2/6] Update main_test.js --- lab2/main_test.js | 116 +++++++++++++++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 33 deletions(-) diff --git a/lab2/main_test.js b/lab2/main_test.js index 2fc698b3..47982b23 100644 --- a/lab2/main_test.js +++ b/lab2/main_test.js @@ -5,49 +5,99 @@ const { Application, MailSystem } = require('./main'); // TODO: write your tests here // Remember to use Stub, Mock, and Spy when necessary -const sinon = require('sinon'); +// Stub: 模擬郵件發送 +class MockMailSystem extends MailSystem { + constructor() { + super(); + this.sentMails = []; + } -test('Application selects unique people', async () => { - const app = new Application(); - const people = ['Alice', 'Bob', 'Charlie']; - sinon.stub(app, 'getNames').resolves([people, []]); + send(name, context) { + console.log('--mock send mail to ' + name + '--'); + this.sentMails.push({ name, context }); + return true; + } - const selected1 = await app.selectNextPerson(); - const selected2 = await app.selectNextPerson(); - const selected3 = await app.selectNextPerson(); + getSentMails() { + return this.sentMails; + } +} - assert.notEqual(selected1, selected2); - assert.notEqual(selected1, selected3); - assert.notEqual(selected2, selected3); +test('Application selects and notifies one person', () => { + const app = new Application(); + const mockMailSystem = new MockMailSystem(); + app.mailSystem = mockMailSystem; + + // 模擬 getRandomPerson 返回特定人 + app.getRandomPerson = () => 'John Doe'; + + const selectedPerson = app.selectNextPerson(); + assert.strictEqual(selectedPerson, 'John Doe', 'Selected person should be John Doe'); + + app.notifySelected(); + + const sentMails = mockMailSystem.getSentMails(); + assert.strictEqual(sentMails.length, 1, 'One mail should have been sent'); + assert.strictEqual(sentMails[0].name, 'John Doe', 'Sent mail should be to John Doe'); + assert.strictEqual(sentMails[0].context, 'Congrats, John Doe!', 'Mail content should be correct'); }); -test('Application notifies selected people', async () => { - const app = new Application(); - const people = ['Alice']; - sinon.stub(app, 'getNames').resolves([people, []]); - sinon.stub(app.mailSystem, 'write').returns('Test context'); - sinon.spy(app.mailSystem, 'send'); +test('Application selects and notifies multiple people', () => { + const app = new Application(); + const mockMailSystem = new MockMailSystem(); + app.mailSystem = mockMailSystem; + // 模擬 getRandomPerson 返回不同人 + let count = 0; + app.getRandomPerson = () => { + const people = ['Alice', 'Bob', 'Charlie']; + return people[count++ % people.length]; + }; - await app.selectNextPerson(); - await app.notifySelected(); + // Select and notify multiple people + for (let i = 0; i < 3; i++) { + const selectedPerson = app.selectNextPerson(); + assert.ok(['Alice', 'Bob', 'Charlie'].includes(selectedPerson), 'Selected person should be one of Alice, Bob, Charlie'); + } - assert.strictEqual(app.mailSystem.send.callCount, 1); - assert.strictEqual(app.mailSystem.send.args[0][0], 'Alice'); - assert.strictEqual(app.mailSystem.send.args[0][1], 'Test context'); + app.notifySelected(); + + const sentMails = mockMailSystem.getSentMails(); + assert.strictEqual(sentMails.length, 3, 'Three mails should have been sent'); + + const expectedContexts = ['Congrats, Alice!', 'Congrats, Bob!', 'Congrats, Charlie!']; + sentMails.forEach((mail, index) => { + assert.strictEqual(mail.context, expectedContexts[index], 'Mail content should be correct'); + }); }); -// 測試 MailSystem 類 -test('MailSystem writes mail content', () => { - const mailSystem = new MailSystem(); - const context = mailSystem.write('John Doe'); - assert.strictEqual(context, 'Congrats, John Doe!'); +test('MailSystem should log "mail sent" on successful send', () => { + const mailSystem = new MailSystem(); + + // 返回 < 0.5 (success) + const stub = test.stub(Math, 'random').returns(0.4); + + const consoleSpy = test.spy(console, 'log'); + + mailSystem.send('John Doe', 'Test Mail'); + + stub.restore(); + consoleSpy.restore(); + + assert.ok(consoleSpy.calledWith('mail sent'), 'Console should log "mail sent"'); }); -test('MailSystem sends mail with success or failure', async () => { - const mailSystem = new MailSystem(); - sinon.stub(console, 'log'); // console.log 输出 +test('MailSystem should log "mail failed" on failed send', () => { + const mailSystem = new MailSystem(); + + // 返回 >= 0.5 (failure) + const stub = test.stub(Math, 'random').returns(0.6); + + const consoleSpy = test.spy(console, 'log'); + + mailSystem.send('John Doe', 'Test Mail'); + + stub.restore(); + consoleSpy.restore(); - await mailSystem.send('John Doe', 'Test context'); - assert(console.log.calledWith('--send mail to John Doe--')); - assert(console.log.calledWith('mail sent')); // 或 mail failed + assert.ok(consoleSpy.calledWith('mail failed'), 'Console should log "mail failed"'); }); From efa21312e58e6d7c3332f0314c04ee307d11c1b8 Mon Sep 17 00:00:00 2001 From: liujayo <37663339+toey8612@users.noreply.github.com> Date: Sun, 17 Mar 2024 16:08:13 +0800 Subject: [PATCH 3/6] Update main_test.js --- lab2/main_test.js | 107 ++++++++++------------------------------------ 1 file changed, 22 insertions(+), 85 deletions(-) diff --git a/lab2/main_test.js b/lab2/main_test.js index 47982b23..1524b93b 100644 --- a/lab2/main_test.js +++ b/lab2/main_test.js @@ -1,103 +1,40 @@ + 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 - -// Stub: 模擬郵件發送 -class MockMailSystem extends MailSystem { - constructor() { - super(); - this.sentMails = []; - } - - send(name, context) { - console.log('--mock send mail to ' + name + '--'); - this.sentMails.push({ name, context }); - return true; - } - - getSentMails() { - return this.sentMails; - } -} - -test('Application selects and notifies one person', () => { +test("Test Application's selectNextPerson", () => { const app = new Application(); - const mockMailSystem = new MockMailSystem(); - app.mailSystem = mockMailSystem; - - // 模擬 getRandomPerson 返回特定人 - app.getRandomPerson = () => 'John Doe'; - + const initialSelectedLength = app.selected.length; const selectedPerson = app.selectNextPerson(); - assert.strictEqual(selectedPerson, 'John Doe', 'Selected person should be John Doe'); - - app.notifySelected(); - - const sentMails = mockMailSystem.getSentMails(); - assert.strictEqual(sentMails.length, 1, 'One mail should have been sent'); - assert.strictEqual(sentMails[0].name, 'John Doe', 'Sent mail should be to John Doe'); - assert.strictEqual(sentMails[0].context, 'Congrats, John Doe!', 'Mail content should be correct'); + assert.strictEqual(app.selected.length, initialSelectedLength + 1, "One person should be selected"); }); -test('Application selects and notifies multiple people', () => { +test("Test Application's notifySelected", () => { const app = new Application(); - const mockMailSystem = new MockMailSystem(); - app.mailSystem = mockMailSystem; - // 模擬 getRandomPerson 返回不同人 - let count = 0; - app.getRandomPerson = () => { - const people = ['Alice', 'Bob', 'Charlie']; - return people[count++ % people.length]; - }; - - // Select and notify multiple people - for (let i = 0; i < 3; i++) { - const selectedPerson = app.selectNextPerson(); - assert.ok(['Alice', 'Bob', 'Charlie'].includes(selectedPerson), 'Selected person should be one of Alice, Bob, Charlie'); - } - + const consoleSpy = jest.spyOn(console, 'log'); app.notifySelected(); - - const sentMails = mockMailSystem.getSentMails(); - assert.strictEqual(sentMails.length, 3, 'Three mails should have been sent'); - - const expectedContexts = ['Congrats, Alice!', 'Congrats, Bob!', 'Congrats, Charlie!']; - sentMails.forEach((mail, index) => { - assert.strictEqual(mail.context, expectedContexts[index], 'Mail content should be correct'); - }); + expect(consoleSpy).toHaveBeenCalled(); }); -test('MailSystem should log "mail sent" on successful send', () => { +test("Test MailSystem's write method", () => { const mailSystem = new MailSystem(); - - // 返回 < 0.5 (success) - const stub = test.stub(Math, 'random').returns(0.4); - - const consoleSpy = test.spy(console, 'log'); - - mailSystem.send('John Doe', 'Test Mail'); - - stub.restore(); - consoleSpy.restore(); - - assert.ok(consoleSpy.calledWith('mail sent'), 'Console should log "mail sent"'); + const name = "John"; + const context = mailSystem.write(name); + assert.strictEqual(context, `Congrats, ${name}!`, "Context should match expected"); }); -test('MailSystem should log "mail failed" on failed send', () => { +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"); +}); - // 返回 >= 0.5 (failure) - const stub = test.stub(Math, 'random').returns(0.6); - - const consoleSpy = test.spy(console, 'log'); - - mailSystem.send('John Doe', 'Test Mail'); - - stub.restore(); - consoleSpy.restore(); - - assert.ok(consoleSpy.calledWith('mail failed'), 'Console should log "mail failed"'); +test("Test Application's getRandomPerson", () => { + const app = new Application(); + const getRandomPersonSpy = jest.spyOn(app, 'getRandomPerson'); + app.getRandomPerson(); + expect(getRandomPersonSpy).toHaveBeenCalled(); }); From 90f7d450187a6d5e7025247cff6ef6791baa316d Mon Sep 17 00:00:00 2001 From: liujayo <37663339+toey8612@users.noreply.github.com> Date: Sun, 17 Mar 2024 16:13:38 +0800 Subject: [PATCH 4/6] Update main_test.js --- lab2/main_test.js | 106 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 22 deletions(-) diff --git a/lab2/main_test.js b/lab2/main_test.js index 1524b93b..e5666a1c 100644 --- a/lab2/main_test.js +++ b/lab2/main_test.js @@ -1,40 +1,102 @@ - const test = require('node:test'); const assert = require('assert'); const { Application, MailSystem } = require('./main'); -test("Test Application's selectNextPerson", () => { +// Stub: Mock MailSystem to simulate sending mail +class MockMailSystem extends MailSystem { + constructor() { + super(); + this.sentMails = []; + } + + send(name, context) { + console.log('--mock send mail to ' + name + '--'); + // Simulate mail sending + this.sentMails.push({ name, context }); + return true; // Always successful in this mock + } + + getSentMails() { + return this.sentMails; + } +} + +test('Application selects and notifies one person', () => { const app = new Application(); - const initialSelectedLength = app.selected.length; + const mockMailSystem = new MockMailSystem(); + app.mailSystem = mockMailSystem; + + // Mocking getRandomPerson to return a specific person + app.getRandomPerson = () => 'John Doe'; + const selectedPerson = app.selectNextPerson(); - assert.strictEqual(app.selected.length, initialSelectedLength + 1, "One person should be selected"); + assert.strictEqual(selectedPerson, 'John Doe', 'Selected person should be John Doe'); + + app.notifySelected(); + + const sentMails = mockMailSystem.getSentMails(); + assert.strictEqual(sentMails.length, 1, 'One mail should have been sent'); + assert.strictEqual(sentMails[0].name, 'John Doe', 'Sent mail should be to John Doe'); + assert.strictEqual(sentMails[0].context, 'Congrats, John Doe!', 'Mail content should be correct'); }); -test("Test Application's notifySelected", () => { +test('Application selects and notifies multiple people', () => { const app = new Application(); - const consoleSpy = jest.spyOn(console, 'log'); + const mockMailSystem = new MockMailSystem(); + app.mailSystem = mockMailSystem; + + // Mocking getRandomPerson to return different people + let count = 0; + app.getRandomPerson = () => { + const people = ['Alice', 'Bob', 'Charlie']; + return people[count++ % people.length]; + }; + + // Select and notify multiple people + for (let i = 0; i < 3; i++) { + const selectedPerson = app.selectNextPerson(); + assert.ok(['Alice', 'Bob', 'Charlie'].includes(selectedPerson), 'Selected person should be one of Alice, Bob, Charlie'); + } + app.notifySelected(); - expect(consoleSpy).toHaveBeenCalled(); + + const sentMails = mockMailSystem.getSentMails(); + assert.strictEqual(sentMails.length, 3, 'Three mails should have been sent'); + + const expectedContexts = ['Congrats, Alice!', 'Congrats, Bob!', 'Congrats, Charlie!']; + sentMails.forEach((mail, index) => { + assert.strictEqual(mail.context, expectedContexts[index], 'Mail content should be correct'); + }); }); -test("Test MailSystem's write method", () => { +test('MailSystem should log "mail sent" on successful send', () => { const mailSystem = new MailSystem(); - const name = "John"; - const context = mailSystem.write(name); - assert.strictEqual(context, `Congrats, ${name}!`, "Context should match expected"); + + // Mocking Math.random to always return a value < 0.5 (success) + const stub = test.stub(Math, 'random').returns(0.4); + + const consoleSpy = test.spy(console, 'log'); + + mailSystem.send('John Doe', 'Test Mail'); + + stub.restore(); + consoleSpy.restore(); + + assert.ok(consoleSpy.calledWith('mail sent'), 'Console should log "mail sent"'); }); -test("Test MailSystem's send method", () => { +test('MailSystem should log "mail failed" on failed send', () => { 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(); + // Mocking Math.random to always return a value >= 0.5 (failure) + const stub = test.stub(Math, 'random').returns(0.6); + + const consoleSpy = test.spy(console, 'log'); + + mailSystem.send('John Doe', 'Test Mail'); + + stub.restore(); + consoleSpy.restore(); + + assert.ok(consoleSpy.calledWith('mail failed'), 'Console should log "mail failed"'); }); From 143379b9742e2402677703628260cc8eb6082d85 Mon Sep 17 00:00:00 2001 From: liujayo <37663339+toey8612@users.noreply.github.com> Date: Thu, 21 Mar 2024 23:28:59 +0800 Subject: [PATCH 5/6] Update main_test.js --- lab2/main_test.js | 147 +++++++++++++++++++--------------------------- 1 file changed, 60 insertions(+), 87 deletions(-) diff --git a/lab2/main_test.js b/lab2/main_test.js index e5666a1c..929e5e35 100644 --- a/lab2/main_test.js +++ b/lab2/main_test.js @@ -1,102 +1,75 @@ const test = require('node:test'); const assert = require('assert'); -const { Application, MailSystem } = require('./main'); - -// Stub: Mock MailSystem to simulate sending mail -class MockMailSystem extends MailSystem { - constructor() { - super(); - this.sentMails = []; - } - - send(name, context) { - console.log('--mock send mail to ' + name + '--'); - // Simulate mail sending - this.sentMails.push({ name, context }); - return true; // Always successful in this mock - } - - getSentMails() { - return this.sentMails; - } -} +const fs = require('fs'); -test('Application selects and notifies one person', () => { - const app = new Application(); - const mockMailSystem = new MockMailSystem(); - app.mailSystem = mockMailSystem; - - // Mocking getRandomPerson to return a specific person - app.getRandomPerson = () => 'John Doe'; +// 模擬 fs.readFile ,返回假數據 +test.mock.method(fs, 'readFile', (file, options, callback) => { + callback(null, 'Alice\njohn\nBob'); +}); - const selectedPerson = app.selectNextPerson(); - assert.strictEqual(selectedPerson, 'John Doe', 'Selected person should be John Doe'); +// 從 main.js 導入 Application 和 MailSystem 類 +const { Application, MailSystem } = require('./main'); - app.notifySelected(); +// testMailSystem_write() +test('MailSystem_write()', () => { + const ms = new MailSystem(); + assert.equal(ms.write('Alice'), 'Congrats, Alice!'); + assert.equal(ms.write(null), 'Congrats, null!'); + assert.equal(ms.write(512558020), 'Congrats, 512558020!'); +}); - const sentMails = mockMailSystem.getSentMails(); - assert.strictEqual(sentMails.length, 1, 'One mail should have been sent'); - assert.strictEqual(sentMails[0].name, 'John Doe', 'Sent mail should be to John Doe'); - assert.strictEqual(sentMails[0].context, 'Congrats, John Doe!', 'Mail content should be correct'); +// test MailSystem_send() +test('MailSystem_send()', () => { + const ms = new MailSystem(); + const name = 'Alice'; + test.mock.method(Math, 'random', () => 0.6); + assert.equal(ms.send(name, 'success'), true); + test.mock.method(Math, 'random', () => 0.4); + assert.equal(ms.send(name, 'fail'), false); }); -test('Application selects and notifies multiple people', () => { +// test Application_getNames() +test('Application_getNames()', async () => { const app = new Application(); - const mockMailSystem = new MockMailSystem(); - app.mailSystem = mockMailSystem; - - // Mocking getRandomPerson to return different people - let count = 0; - app.getRandomPerson = () => { - const people = ['Alice', 'Bob', 'Charlie']; - return people[count++ % people.length]; - }; - - // Select and notify multiple people - for (let i = 0; i < 3; i++) { - const selectedPerson = app.selectNextPerson(); - assert.ok(['Alice', 'Bob', 'Charlie'].includes(selectedPerson), 'Selected person should be one of Alice, Bob, Charlie'); - } - - app.notifySelected(); - - const sentMails = mockMailSystem.getSentMails(); - assert.strictEqual(sentMails.length, 3, 'Three mails should have been sent'); - - const expectedContexts = ['Congrats, Alice!', 'Congrats, Bob!', 'Congrats, Charlie!']; - sentMails.forEach((mail, index) => { - assert.strictEqual(mail.context, expectedContexts[index], 'Mail content should be correct'); - }); + const name_list = ['Alice', 'john', 'Bob']; + const names = await app.getNames(); + assert.deepStrictEqual(names, [name_list, []]); }); -test('MailSystem should log "mail sent" on successful send', () => { - const mailSystem = new MailSystem(); - - // Mocking Math.random to always return a value < 0.5 (success) - const stub = test.stub(Math, 'random').returns(0.4); - - const consoleSpy = test.spy(console, 'log'); - - mailSystem.send('John Doe', 'Test Mail'); - - stub.restore(); - consoleSpy.restore(); - - assert.ok(consoleSpy.calledWith('mail sent'), 'Console should log "mail sent"'); +// test Application_getRandomPerson() +test('Application_getRandomPerson()', async () => { + const app = new Application(); + const names = await app.getNames(); + const randomPerson = app.getRandomPerson(); + assert.ok(names[0].includes(randomPerson)); }); -test('MailSystem should log "mail failed" on failed send', () => { - const mailSystem = new MailSystem(); - - // Mocking Math.random to always return a value >= 0.5 (failure) - const stub = test.stub(Math, 'random').returns(0.6); - - const consoleSpy = test.spy(console, 'log'); - - mailSystem.send('John Doe', 'Test Mail'); - - stub.restore(); - consoleSpy.restore(); +// test Application_selectNextPerson() +test('Application_selectNextPerson()', async () => { + const app = new Application(); + const names = await app.getNames(); + app.selected = ['Alice']; + let cnt = 0; + test.mock.method(app, 'getRandomPerson', () => { + if (cnt <= names[0].length) { + return names[0][cnt++]; + } + }); + assert.strictEqual(app.selectNextPerson(), 'john'); + assert.deepStrictEqual(app.selected, ['Alice', 'john']); + assert.strictEqual(app.selectNextPerson(), 'Bob'); + assert.deepStrictEqual(app.selected, ['Alice', 'john', 'Bob']); + assert.strictEqual(app.selectNextPerson(), null); +}); - assert.ok(consoleSpy.calledWith('mail failed'), 'Console should log "mail failed"'); +// test Application_notifySelected() +test('Application_notifySelected()', async () => { + const app = new Application(); + app.people = ['Alice', 'john', 'Bob']; + app.selected = ['Alice', 'john', 'Bob']; + app.mailSystem.send = test.mock.fn(app.mailSystem.send); + app.mailSystem.write = test.mock.fn(app.mailSystem.write); + app.notifySelected(); + assert.strictEqual(app.mailSystem.send.mock.calls.length, 3); + assert.strictEqual(app.mailSystem.write.mock.calls.length, 3); }); From df76f4b2c3de2f1738246d37832c04f1a4b542e0 Mon Sep 17 00:00:00 2001 From: liujayo <37663339+toey8612@users.noreply.github.com> Date: Thu, 21 Mar 2024 23:36:28 +0800 Subject: [PATCH 6/6] Update main_test.js --- lab2/main_test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lab2/main_test.js b/lab2/main_test.js index 929e5e35..e2373f1e 100644 --- a/lab2/main_test.js +++ b/lab2/main_test.js @@ -1,3 +1,4 @@ + const test = require('node:test'); const assert = require('assert'); const fs = require('fs');