Skip to content

[LAB5] 313581042 #405

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

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/lab-autograding.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
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 = ["lab0/lab0.js"];
const specialChangedFiles = ["lab0/lab0.js", "lab5/antiasan.c"];
if (!changedFiles.every((file) => (allowedFileRegex.test(file) || specialChangedFiles.includes(file)))) {
core.setFailed('The PR contains changes to files other than the allowed files.');
}
Expand Down
1 change: 1 addition & 0 deletions lab0/lab0.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("Hello world!");
22 changes: 22 additions & 0 deletions lab1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Lab1

## 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)

## Requirement

1. Write test cases in `main_test.js` and achieve 100% code coverage. (100%)

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.
55 changes: 55 additions & 0 deletions lab1/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// NOTICE: DO NOT MODIFY THE CODE IN THIS FILE
// But you can uncomment code below and run this file to understand how to use the classes

class MyClass {
constructor() {
this.students = [];
}

addStudent(student) {
if (!(student instanceof Student)) {
return -1;
}
this.students.push(student);
return this.students.length - 1;
}

getStudentById(id) {
if (id < 0 || id >= this.students.length) {
return null;
}
return this.students[id];
}
}

class Student {
constructor() {
this.name = undefined;
}

setName(userName) {
if (typeof userName !== 'string') {
return;
}
this.name = userName;
}

getName() {
if (this.name === undefined) {
return '';
}
return this.name;
}
}

// const myClass = new MyClass();
// const names = ['John', 'Jane', 'Doe', 'Smith'];
// names.forEach(name => {
// const student = new Student();
// student.setName(name);
// const newStudentId = myClass.addStudent(student);
// const newStudentName = myClass.getStudentById(newStudentId).getName();
// console.log('[+] Added student with id: %d, name: %s', newStudentId, newStudentName);
// });

module.exports = { MyClass, Student };
23 changes: 23 additions & 0 deletions lab1/main_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const test = require('node:test');
const assert = require('assert');
const { MyClass, Student } = require('./main');

test("Test MyClass's addStudent", () => {
// TODO
throw new Error("Test not implemented");
});

test("Test MyClass's getStudentById", () => {
// TODO
throw new Error("Test not implemented");
});

test("Test Student's setName", () => {
// TODO
throw new Error("Test not implemented");
});

test("Test Student's getName", () => {
// TODO
throw new Error("Test not implemented");
});
38 changes: 38 additions & 0 deletions lab1/validate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash

# Check for unwanted files
for file in *; do
if [[ $file != "main.js" && $file != "main_test.js" && $file != "README.md" && $file != "validate.sh" ]]; then
echo "[!] Unwanted file detected: $file."
exit 1
fi
done

node=$(which node)
test_path="${BASH_SOURCE[0]}"
solution_path="$(realpath .)"
tmp_dir=$(mktemp -d -t lab1-XXXXXXXXXX)

cd $tmp_dir

rm -rf *
cp $solution_path/*.js .
result=$($"node" --test --experimental-test-coverage) ; ret=$?
if [ $ret -ne 0 ] ; then
echo "[!] testing fails."
exit 1
else
coverage=$(echo "$result" | grep 'all files' | awk -F '|' '{print $2}' | sed 's/ //g')
if (( $(echo "$coverage < 100" | bc -l) )); then
echo "[!] Coverage is only $coverage%, should be 100%."
exit 1
else
echo "[V] Coverage is 100%, great job!"
fi
fi

rm -rf $tmp_dir

exit 0

# vim: set fenc=utf8 ff=unix et sw=2 ts=2 sts=2:
22 changes: 22 additions & 0 deletions lab2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Lab2

## 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)

## Requirement

1. Write test cases in `main_test.js` and achieve 100% code coverage. Remember to use Mock, Spy, or Stub when necessary, you need to at least use one of them in your test cases. (100%)

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.
81 changes: 81 additions & 0 deletions lab2/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);

class MailSystem {
write(name) {
console.log('--write mail for ' + name + '--');
const context = 'Congrats, ' + name + '!';
return context;
}

send(name, context) {
console.log('--send mail to ' + name + '--');
// Interact with mail system and send mail
// random success or failure
const success = Math.random() > 0.5;
if (success) {
console.log('mail sent');
} else {
console.log('mail failed');
}
return success;
}
}

class Application {
constructor() {
this.people = [];
this.selected = [];
this.mailSystem = new MailSystem();
this.getNames().then(([people, selected]) => {
this.people = people;
this.selected = selected;
});
}

async getNames() {
const data = await readFile('name_list.txt', 'utf8');
const people = data.split('\n');
const selected = [];
return [people, selected];
}

getRandomPerson() {
const i = Math.floor(Math.random() * this.people.length);
return this.people[i];
}

selectNextPerson() {
console.log('--select next person--');
if (this.people.length === this.selected.length) {
console.log('all selected');
return null;
}
let person = this.getRandomPerson();
while (this.selected.includes(person)) {
person = this.getRandomPerson();
}
this.selected.push(person);
return person;
}

notifySelected() {
console.log('--notify selected--');
for (const x of this.selected) {
const context = this.mailSystem.write(x);
this.mailSystem.send(x, context);
}
}
}

// const app = new Application();
// app.selectNextPerson();
// app.selectNextPerson();
// app.selectNextPerson();
// app.notifySelected();

module.exports = {
Application,
MailSystem,
};
Loading
Loading