Skip to content
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
13 changes: 13 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Unit Tests # name of the test

on: [push] # the Github Action will activate "on" the event that you "push" to the repo

jobs: # the things being executed
tests: # the name of your status check, will become important when you do branch protection
runs-on: ubuntu-latest # which device on Github's server that you are running the Actions on
steps:
- uses: actions/checkout@v4 # using version 4 of Actions
- name: Install Dependencies
run: npm install
- name: Unit Test
run: npm test ./__tests__/sum.test.js # the actual testing line
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.DS_Store
.DS_Store
node_modules/
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,15 @@
# Lab 5 - Starter

## Check Your Understanding

### Question 1
Would you use a unit test to test the “message” feature of a messaging application? Why or why not? For this question, assume the “message” feature allows a user to write and send a message to another user.

**Answer:**
Unit testing might not be the best choice for testing the entire "message" feature due to its reliance on multiple interacting components. However, unit tests are suitable for testing individual parts of the feature such as the message formatting and validation functions.

### Question 2
Would you use a unit test to test the “max message length” feature of a messaging application? Why or why not? For this question, assume the “max message length” feature prevents the user from typing more than 80 characters.

**Answer:**
Yes, unit testing is appropriate for the "max message length" feature. This feature's functionality is isolated and can be precisely defined and tested without external dependencies, making it ideal for unit testing.
6 changes: 6 additions & 0 deletions __tests__/sum.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// sum.test.js
import { sum } from '../code-to-unit-test/sum';

test('adds 1 + 2 to equal 3', () => {
// TODO
expect(sum(1 + 2)).toBe(3);
});

test('adds 1 + 2 to equal 3', () => {
expect(sum(1,2)).toBe(4); //should be wrong
});
49 changes: 49 additions & 0 deletions __tests__/unit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,52 @@ import {
} from '../code-to-unit-test/unit-test-me';

// TODO - Part 2
// Tests for isPhoneNumber
describe('isPhoneNumber', () => {
test('validates correct phone number', () => {
expect(isPhoneNumber('123-456-7890')).toBe(true);
});
test('rejects incorrect phone number', () => {
expect(isPhoneNumber('123-45-6789')).toBe(false);
});
});

// Tests for isEmail
describe('isEmail', () => {
test('validates correct email', () => {
expect(isEmail('test@example.com')).toBe(true);
});
test('rejects incorrect email', () => {
expect(isEmail('test@example')).toBe(false);
});
});

// Tests for isStrongPassword
describe('isStrongPassword', () => {
test('validates strong password', () => {
expect(isStrongPassword('Example123!')).toBe(true);
});
test('rejects weak password', () => {
expect(isStrongPassword('examp')).toBe(false);
});
});

// Tests for isDate
describe('isDate', () => {
test('validates correct date', () => {
expect(isDate('2021-04-12')).toBe(true);
});
test('rejects incorrect date', () => {
expect(isDate('April 12, 2021')).toBe(false);
});
});

// Tests for isHexColor
describe('isHexColor', () => {
test('validates correct hex color', () => {
expect(isHexColor('#FFFFFF')).toBe(true);
});
test('rejects incorrect hex color', () => {
expect(isHexColor('FFFFFF')).toBe(false);
});
});
50 changes: 50 additions & 0 deletions assets/scripts/explore.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,54 @@ window.addEventListener('DOMContentLoaded', init);

function init() {
// TODO
const textArea = document.getElementById('text-to-speak');
const voiceSelect = document.getElementById('voice-select');
const talkButton = document.querySelector('button');
const faceImage = document.querySelector('img');

function populateVoiceList() {
if (typeof speechSynthesis === 'undefined') {
return;
}
let voices = speechSynthesis.getVoices();

for (let i = 0; i < voices.length; i++) {
let option = document.createElement('option');
option.textContent = voices[i].name + ' (' + voices[i].lang + ')';
if (voices[i].default) {
option.textContent += ' — DEFAULT';
}
option.setAttribute('data-name', voices[i].name);
option.setAttribute('data-lang', voices[i].lang);
voiceSelect.appendChild(option);
}
}

populateVoiceList();
if (typeof speechSynthesis !== 'undefined' && speechSynthesis.onvoiceschanged !== null) {
speechSynthesis.onvoiceschanged = populateVoiceList;
}

function speak() {
if (speechSynthesis.speaking) {
console.error('speechSynthesis.speaking');
return;
}
if (textArea.value !== '') {
let utterance = new SpeechSynthesisUtterance(textArea.value);
let selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
utterance.voice = speechSynthesis.getVoices().find(voice => voice.name === selectedOption);

utterance.onstart = function () {
faceImage.src = 'assets/images/smiling-open.png';
};
utterance.onend = function () {
faceImage.src = 'assets/images/smiling.png';
};

speechSynthesis.speak(utterance);
}
}

talkButton.addEventListener('click', speak);
}
35 changes: 35 additions & 0 deletions assets/scripts/expose.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,39 @@ window.addEventListener('DOMContentLoaded', init);

function init() {
// TODO
const hornSelect = document.getElementById('horn-select');
const volumeSlider = document.getElementById('volume');
const playButton = document.querySelector('button');
const audioElement = document.querySelector('audio');
const imageElement = document.querySelector('#expose img');
const volumeIcon = document.querySelector('#volume-controls img');

hornSelect.addEventListener('change', function() {
const selectedOption = hornSelect.options[hornSelect.selectedIndex].value;
imageElement.src = `assets/images/${selectedOption}.svg`;
audioElement.src = `assets/audio/${selectedOption}.mp3`;
});

volumeSlider.addEventListener('input', function() {
const volume = parseInt(volumeSlider.value);
audioElement.volume = volume / 100;

if (volume === 0) {
volumeIcon.src = 'assets/icons/volume-level-0.svg';
} else if (volume < 33) {
volumeIcon.src = 'assets/icons/volume-level-1.svg';
} else if (volume < 67) {
volumeIcon.src = 'assets/icons/volume-level-2.svg';
} else {
volumeIcon.src = 'assets/icons/volume-level-3.svg';
}
});

playButton.addEventListener('click', function() {
audioElement.play();
if (hornSelect.value === 'party-horn') {
const jsConfetti = new JSConfetti();
jsConfetti.addConfetti();
}
});
}