Skip to content

[LAB4] 511558025 #579

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 39 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
dfaa7dc
feat: lab2
AlaRduTP Mar 13, 2024
a916599
Update main_test.js
Highwaist Mar 17, 2024
9735cfb
Merge branch '511558025' into 511558025
Highwaist Mar 17, 2024
8e6a34b
Merge pull request #66 from Highwaist/511558025
AlaRduTP Mar 20, 2024
1aaa748
feat: lab3
AlaRduTP Mar 20, 2024
7e0b643
Update main_test.js
Highwaist Mar 25, 2024
166166c
Update main_test.js
Highwaist Mar 26, 2024
65c18c3
Merge branch '511558025' into 511558025
Highwaist Mar 26, 2024
89361f0
Update main_test.js
Highwaist Mar 26, 2024
f64bb8d
Update main_test.js
Highwaist Mar 26, 2024
33fde4f
Update main_test.js
Highwaist Mar 26, 2024
8aff5cd
Update main_test.js
Highwaist Mar 26, 2024
cd95aa0
Update main_test.js
Highwaist Mar 26, 2024
7ec4ad1
Update main_test.js
Highwaist Mar 26, 2024
4825474
Update main_test.js
Highwaist Mar 26, 2024
d956dee
Update main_test.js
Highwaist Mar 26, 2024
fcf7db7
Update main_test.js
Highwaist Mar 26, 2024
a3380b2
feat: lab4
AlaRduTP Mar 27, 2024
e01b1c9
Merge pull request #142 from Highwaist/511558025
TaiYou-TW Apr 3, 2024
665b523
Update main_test.js
Highwaist Apr 13, 2024
e772bf2
Merge branch '511558025' into 511558025
Highwaist Apr 13, 2024
272b72a
feat: lab5
YingMuo Apr 17, 2024
02a54ac
fix: gh-script syntax error
AlaRduTP Apr 18, 2024
fdbe43a
Update main_test.js
Highwaist Apr 22, 2024
3703f55
Update main_test.js
Highwaist Apr 22, 2024
9256225
Update main_test.js
Highwaist Apr 22, 2024
4001395
Update main_test.js
Highwaist Apr 22, 2024
0057c71
Merge branch '511558025' into 511558025
Highwaist Apr 22, 2024
8a61504
feat: lab6
TaiYou-TW Apr 24, 2024
ce85b08
Lab7: merge
YingMuo May 1, 2024
45f16c9
Update Answer.md
Highwaist May 15, 2024
31bc7ed
Update Answer.md
Highwaist May 15, 2024
099cdb3
Update Answer.md
Highwaist May 15, 2024
083fc7c
Merge branch 'SQLab:511558025' into 511558025
Highwaist May 18, 2024
85216d9
Update Answer.md
Highwaist May 18, 2024
a3cf86a
Update Answer.md
Highwaist May 18, 2024
309c4bd
Update Answer.md
Highwaist May 18, 2024
c0beebe
Update Answer.md
Highwaist May 18, 2024
e6c28f9
Update main_test.js
s33557 Jun 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 19 additions & 15 deletions .github/workflows/PR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,31 @@ jobs:
const { owner, repo, number: issue_number } = context.issue;
const pr = await github.rest.pulls.get({ owner, repo, pull_number: issue_number });
const title = pr.data.title;
const labRegex = /\[LAB(\d+)\]/;
const titleRegex = /^\[LAB\d+\] [\da-zA-Z]+$/;

if (!titleRegex.test(title)) {
core.setFailed('PR title does not match the required format. Please use the format [LAB#] student#.');
const titleRegex = /^\[LAB(\d+)\] [a-zA-Z]?\d+$/;
const match = title.match(titleRegex);

let labNumberStr = undefined;
if (match) {
labNumberStr = match[1];
} else {
core.setFailed('PR title does not match the required format. Please use the format: [LAB#] <studentId>.');
}

if (pr.data.head.ref !== pr.data.base.ref) {
core.setFailed('The source branch and target branch must be the same.');
const labelToAdd = `lab${labNumberStr}`;
if (labNumberStr) {
await github.rest.issues.addLabels({ owner, repo, issue_number, labels: [labelToAdd] });
}

if (pr.data.base.ref === 'main') {
core.setFailed('The target branch cannot be main.');
}

const match = title.match(labRegex);
if (match) {
const labelToAdd = 'lab' + match[1];
await github.rest.issues.addLabels({ owner, repo, issue_number, labels: [labelToAdd] });
} else {
core.setFailed('No match found in PR title. Please add a label in the format [LAB#] to the PR title.');
if (labNumberStr < 3 && pr.data.head.ref !== pr.data.base.ref) {
core.setFailed('The source branch and target branch must be the same.');
}
if (labNumberStr >= 3 && pr.data.head.ref !== labelToAdd) {
core.setFailed(`The source branch must be '${labelToAdd}'`);
}
checklist-check:
runs-on: ubuntu-latest
Expand All @@ -49,12 +53,12 @@ jobs:
const pr = await github.rest.pulls.get({ owner, repo, pull_number: issue_number });
const body = pr.data.body;

const checkboxes = body.match(/\- \[[x ]\]/g);
const checkboxes = body.match(/^ ?(-|\*) \[[x ]\]/gmi);
if (!checkboxes || checkboxes.length !== 5) {
core.setFailed('The PR description must contain exactly 5 checkboxes.');
}

const unchecked = body.match(/\- \[ \]/g);
const unchecked = body.match(/^ ?(-|\*) \[ \]/gm);
if (unchecked && unchecked.length > 0) {
core.setFailed(`There are ${unchecked.length} unchecked items in the PR description.`);
core.setFailed(`There are ${unchecked.length} unchecked item(s) in the PR description.`);
}
56 changes: 56 additions & 0 deletions .github/workflows/lab-autograding.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Autograding

on:
pull_request_target:
types: [labeled, synchronize, opened, reopened, ready_for_review]

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
fail-fast: false
steps:
- uses: actions/checkout@v4
with:
ref: "${{ github.event.pull_request.merge_commit_sha }}"
fetch-depth: 1
- uses: actions/setup-node@v4
with:
node-version: latest
- name: Extract lab number and Check no changes other than specific files
uses: actions/github-script@v5
id: lab
with:
result-encoding: string
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { owner, repo, number: issue_number } = context.issue;
const pr = await github.rest.pulls.get({ owner, repo, pull_number: issue_number });
const labels = pr.data.labels;
const lab = labels.find((label) => label.name.startsWith('lab'));
if (!lab) {
core.setFailed('No lab label found on the PR.');
return { number: 0 };
}
const labNumberMatch = lab.name.match(/lab(\d+)/);
if (!labNumberMatch) {
core.setFailed('Invalid lab label found on the PR.');
return { number: 0 };
}
const labNumber = labNumberMatch[1];
console.log(`Lab number: ${labNumber}`)

const files = await github.rest.pulls.listFiles({ owner, repo, pull_number: issue_number });
const changedFiles = files.data.map((file) => file.filename);
const allowedFileRegex = /^lab\d+\/main_test.js$/;
const specialChangedFiles = ["lab5/Answer.md", "lab5/antiasan.c", "lab6/Answer.md", "lab7/sol.py"];
if (!changedFiles.every((file) => (allowedFileRegex.test(file) || specialChangedFiles.includes(file)))) {
core.setFailed('The PR contains changes to files other than the allowed files.');
}
return labNumber;
- name: Grading
run: |
cd lab${{ steps.lab.outputs.result }}
./validate.sh
26 changes: 0 additions & 26 deletions .github/workflows/lab1.yml

This file was deleted.

26 changes: 0 additions & 26 deletions .github/workflows/lab2.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
57 changes: 48 additions & 9 deletions lab1/main_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,60 @@ const assert = require('assert');
const { MyClass, Student } = require('./main');

test("Test MyClass's addStudent", () => {
// TODO
throw new Error("Test not implemented");
const myClass = new MyClass();
//create 2 students John & Jane
const student1 = new Student();
student1.setName('John');
const id1 = myClass.addStudent(student1);
assert.strictEqual(id1, 0);

const student2 = new Student();
student2.setName('Jane');
const id2 = myClass.addStudent(student2);
assert.strictEqual(id2, 1);

//新增一個TESTING student
const invalidStudent = 'TESTING';
const invalidId = myClass.addStudent(invalidStudent);
assert.strictEqual(invalidId, -1);

});

test("Test MyClass's getStudentById", () => {
// TODO
throw new Error("Test not implemented");
const myClass = new MyClass();
const student1 = new Student();
student1.setName('John');
myClass.addStudent(student1);

const retrievedStudent = myClass.getStudentById(0);
assert.strictEqual(retrievedStudent.getName(), 'John');

const invalidStudent = myClass.getStudentById(-1);
assert.strictEqual(invalidStudent, null);

const outOfBoundsStudent = myClass.getStudentById(1);
assert.strictEqual(outOfBoundsStudent, null);

});

test("Test Student's setName", () => {
// TODO
throw new Error("Test not implemented");
const student = new Student();
//測試變數是否有效
student.setName('Alice');
assert.strictEqual(student.getName(), 'Alice');

student.setName(123);
assert.strictEqual(student.getName(), 'Alice');

});

test("Test Student's getName", () => {
// TODO
throw new Error("Test not implemented");
});
const student = new Student();
// 初始化未設置
assert.strictEqual(student.getName(), '');

// 設置變數後返回
student.setName('Bob');
assert.strictEqual(student.getName(), 'Bob');

});
64 changes: 61 additions & 3 deletions lab2/main_test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,64 @@
const test = require('node:test');
const testUtil = require('node:test');
const assert = require('assert');
const fs = require('fs');

// Mock the file containing names
testUtil.mock.method(fs, 'readFile', (file, options, callback) => {
callback(null, 'Alice\nBob\ncat');
});

const { Application, MailSystem } = require('./main');

// TODO: write your tests here
// Remember to use Stub, Mock, and Spy when necessary
testUtil('MailSystem_write()', () => {
const mailSystem = new MailSystem();
assert.strictEqual(mailSystem.write('Alice'), 'Congrats, Alice!');
assert.strictEqual(mailSystem.write(202), 'Congrats, 202!');
assert.strictEqual(mailSystem.write(null), 'Congrats, null!');
});

testUtil('MailSystem_send()', () => {
const mailSystem = new MailSystem();
const name = 'Alice';
testUtil.mock.method(Math, 'random', () => 0.9);
assert.strictEqual(mailSystem.send(name, 'success'), true);
testUtil.mock.method(Math, 'random', () => 0.2);
assert.strictEqual(mailSystem.send(name, 'fail'), false);
});

testUtil('Application_getNames()', async () => {
const app = new Application();
const nameList = ['Alice', 'Bob', 'cat'];
const [names, selected] = await app.getNames();
assert.deepStrictEqual(names, nameList);
assert.deepStrictEqual(selected, []);
});

testUtil('Application_getRandomPerson()', async () => {
const app = new Application();
const [names] = await app.getNames();
const randomPerson = app.getRandomPerson();
});

testUtil('Application_selectNextPerson()', async () => {
const app = new Application();
const [names] = await app.getNames();
app.selected = ['Alice'];
let count = 0;
testUtil.mock.method(app, 'getRandomPerson', () => names[count++]);
assert.strictEqual(app.selectNextPerson(), 'Bob');
assert.deepStrictEqual(app.selected, ['Alice', 'Bob']);
assert.strictEqual(app.selectNextPerson(), 'cat');
assert.deepStrictEqual(app.selected, ['Alice', 'Bob', 'cat']);
assert.strictEqual(app.selectNextPerson(), null);
});

testUtil('Application_notifySelected()', async () => {
const app = new Application();
const [names] = await app.getNames();
app.selected = names.slice(); // Select all names initially
app.mailSystem.send = testUtil.mock.fn(app.mailSystem.send);
app.mailSystem.write = testUtil.mock.fn(app.mailSystem.write);
app.notifySelected();
assert.strictEqual(app.mailSystem.send.mock.calls.length, names.length);
assert.strictEqual(app.mailSystem.write.mock.calls.length, names.length);
});
31 changes: 31 additions & 0 deletions lab3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Lab3

## Introduction

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)

## Preparation (Important!!!)

1. Sync fork your branch (e.g., `SQLab:311XXXXXX`)
2. `git checkout 311XXXXXX`
3. `git pull`
4. `git checkout -b lab3` (**NOT** your student ID !!!)

## Requirement

1. (40%) Write test cases in `main_test.js` and achieve 100% code coverage.
2. (30%) For each function, parameterize its testcases to test the error-results.
3. (30%) For each function, use at least 3 parameterized testcases to test the non-error-results.

You can run `validate.sh` in your local to test if you satisfy the requirements.

Please note that you must not alter files other than `main_test.js`. You will get 0 points if

1. you modify other files to achieve requirements.
2. you can't pass all CI on your PR.

## Submission

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.

Moreover, please submit the URL of your PR to E3. Your submission will only be accepted when you present at both places.
34 changes: 34 additions & 0 deletions lab3/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class Calculator {
exp(x) {
if (!Number.isFinite(x)) {
throw Error('unsupported operand type');
}
const result = Math.exp(x);
if (result === Infinity) {
throw Error('overflow');
}
return result;
}

log(x) {
if (!Number.isFinite(x)) {
throw Error('unsupported operand type');
}
const result = Math.log(x);
if (result === -Infinity) {
throw Error('math domain error (1)');
}
if (Number.isNaN(result)) {
throw Error('math domain error (2)');
}
return result;
}
}

// const calculator = new Calculator();
// console.log(calculator.exp(87));
// console.log(calculator.log(48763));

module.exports = {
Calculator
};
Loading
Loading