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/
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
# Lab 5 - Starter
Zhamilya Shakirova


explore.html:
https://zshakirova.github.io/Lab5_Starter/explore.html

expose.html:
https://zshakirova.github.io/Lab5_Starter/expose.html

Answers to the Unit Testing with Jest
1. It depends on the complexity of the "message" function. If the feature is complex and involves many interactions or dependencies, unit testing may not be good option. This is because unit tests are best suited for testing isolated, small pieces of code. But we can still use unit tests to test individual functionality in the message function.

2. Yes, I can use a unit test to test the "max message length" function. This function is a good candidate for unit testing because it is a discrete, isolated function that can be easily tested in isolation. This type of unit test is simple and can be completed quickly, providing immediate feedback during development.


// my merge request was not completing the check for myError.png
9 changes: 7 additions & 2 deletions __tests__/sum.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
// sum.test.js

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


123 changes: 120 additions & 3 deletions __tests__/unit.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,128 @@
// unit.test.js


import {
isPhoneNumber,
isEmail,
isStrongPassword,
isDate,
isHexColor,
} from '../code-to-unit-test/unit-test-me';

// TODO - Part 2
} from '../code-to-unit-test/unit-test-me';


// TODO - Part 2


//number
test('true test 1 for phone number', () => {
expect(isPhoneNumber('123-456-7890')).toBe(true);
});


test('true test 2 for phone number', () => {
expect(isPhoneNumber('(123) 456-7890')).toBe(true);
});


test('false test 3 for phone number', () => {
expect(isPhoneNumber('123-45-6789')).toBe(false);
});


test('false test 4 for phone number', () => {
expect(isPhoneNumber('123456-89-1234')).toBe(false);
});


//email


test('true test 5 for email', () => {
expect(isEmail('username@example.com')).toBe(true);
});
test('true test 6 for email', () => {
expect(isEmail('user_name@domain_site.co')).toBe(true);
});


test('false test 7 for email', () => {
expect(isEmail('username@examplecom')).toBe(false);
});


test('false test 8 for email', () => {
expect(isEmail('user@domain1234.commm')).toBe(false);
});


// password


test('true test 9 for password', () => {
expect(isStrongPassword('Abcd1234')).toBe(true);
});


test('true test 10 for password', () => {
expect(isStrongPassword('A1234567890123')).toBe(true);
});


test('false test 11 for password', () => {
expect(isStrongPassword('A1b')).toBe(false);
});


test('false test 12 for password', () => {
expect(isStrongPassword('1abcdEFG')).toBe(false);
});


//date


test('true test 13 for date', () => {
expect(isDate('12/25/2020')).toBe(true);
});


test('true test 14 for date', () => {
expect(isDate('1/1/2023')).toBe(true);
});


test('false test 15 for date', () => {
expect(isDate('12-25-2020')).toBe(false);
});
test('false test 16 for date', () => {
expect(isDate('12/25/20')).toBe(false);
});


//color
test('true test 17 for color', () => {
expect(isHexColor('#1A2B3C')).toBe(true);
});


test('true test 18 for color', () => {
expect(isHexColor('#ABC')).toBe(true);
});


test('false test 19 for color', () => {
expect(isHexColor('#098876678')).toBe(false);
});


test('false test 20 for color', () => {
expect(isHexColor('#1234')).toBe(false);
});








46 changes: 43 additions & 3 deletions assets/scripts/explore.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,47 @@
// explore.js

window.addEventListener('DOMContentLoaded', init);

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

// Check if Speech Synthesis is supported by the browser
if ('speechSynthesis' in window) {
loadVoices(); // Initially load voices
speechSynthesis.onvoiceschanged = loadVoices; // Update voices when they change

pressToTalkButton.addEventListener('click', speakText);
} else {
console.error('Speech Synthesis is not supported by your browser');
}

function loadVoices() {
const voices = speechSynthesis.getVoices();
voiceSelect.innerHTML = ''; // Clear existing options
voices.forEach(voice => {
const option = document.createElement('option');
option.value = voice.name;
option.textContent = `${voice.name} (${voice.lang})`;
voiceSelect.appendChild(option);
});
}

function speakText() {
const textToSpeak = textToSpeakTextarea.value;
const utterance = new SpeechSynthesisUtterance(textToSpeak);
const selectedVoiceName = voiceSelect.value;
const voices = speechSynthesis.getVoices();
const selectedVoice = voices.find(voice => voice.name === selectedVoiceName);

if (selectedVoice) {
utterance.voice = selectedVoice;
utterance.onstart = () => faceImage.src = 'assets/images/smiling-open.png';
utterance.onend = () => faceImage.src = 'assets/images/smiling.png';

speechSynthesis.speak(utterance);
} else {
console.error('Selected voice not found');
}
}
}
57 changes: 56 additions & 1 deletion assets/scripts/expose.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,60 @@
window.addEventListener('DOMContentLoaded', init);

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

hornSelect.addEventListener('change', function() {
updateHorn(hornSelect.value);
});

volumeSlider.addEventListener('input', function() {
updateVolume(volumeSlider.value);
});

playButton.addEventListener('click', function() {
playSound();
});

function updateHorn(selectedHorn) {
switch (selectedHorn) {
case 'air-horn':
imageElement.src = 'assets/images/air-horn.svg';
audioElement.src = 'assets/audio/air-horn.mp3';
break;
case 'car-horn':
imageElement.src = 'assets/images/car-horn.svg';
audioElement.src = 'assets/audio/car-horn.mp3';
break;
case 'party-horn':
imageElement.src = 'assets/images/party-horn.svg';
audioElement.src = 'assets/audio/party-horn.mp3';
break;
}
}

function updateVolume(volume) {
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 >= 33 && volume < 67) {
volumeIcon.src = 'assets/icons/volume-level-2.svg';
} else if (volume >= 67) {
volumeIcon.src = 'assets/icons/volume-level-3.svg';
}
}

function playSound() {
audioElement.play();
if (hornSelect.value === 'party-horn') {
jsConfetti.addConfetti();
}
}
}
2 changes: 2 additions & 0 deletions code-to-unit-test/unit-test-me.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ export function isHexColor(color) {
const colorRegex = /^\#?[A-Fa-f0-9]{3}([A-Fa-f0-9]{3})?$/;
return colorRegex.test(color);
}


1 change: 0 additions & 1 deletion explore.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<title>Lab 5 - Party Horn</title>

<!-- Main Stylesheet & Scripts -->
<link rel="stylesheet" href="assets/styles/global.css" />
<script src="./assets/scripts/explore.js" type="module"></script>
</head>
Expand Down
Binary file added merged.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added myError.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading