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/learn-github-actions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: learn-github-actions
run-name: ${{ github.actor }} is learning GitHub Actions
on: [push]
jobs:
check-bats-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install -g bats
- run: bats -v
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/
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
# Lab 5 - Starter
Ned Bitar

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.

I would use unit tests to make sure that the messages sent are being exactly the same as the messages recieved. You can also write tests to see how the program will react with special characters and no text.

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.

I would use unit tests to make sure the user cannot exceed the specified limit. I would test it in several languages to see how my code would function in those various languages.

[My Website](https://nedbitar.github.io/Lab5_Starter/expose.html)
2 changes: 1 addition & 1 deletion __tests__/sum.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// sum.test.js

test('adds 1 + 2 to equal 3', () => {
// TODO
expect(1+2).toBe(3);
});
77 changes: 76 additions & 1 deletion __tests__/unit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,79 @@ import {
isHexColor,
} from '../code-to-unit-test/unit-test-me';

// TODO - Part 2
describe('Test Functions', () => {
describe('isPhoneNumber', () => {
test('Returns true for valid phone number format', () => {
expect(isPhoneNumber('123-123-1234')).toBe(true);
});
test('Returns true for valid phone number format', () => {
expect(isPhoneNumber('000-000-0000')).toBe(true);
});
test('Returns false for invalid phone number format', () => {
expect(isPhoneNumber('--')).toBe(false);
});
test('Returns false for invalid phone number format', () => {
expect(isPhoneNumber('abc-efg-hijk')).toBe(false);
});
});

describe('isEmail', () => {
test('Returns true for valid email format', () => {
expect(isEmail('nabitar@ucsd.edu')).toBe(true);
});
test('Returns true for valid email format', () => {
expect(isEmail('nabitar1@ucsd.edu')).toBe(true);
});
test('Returns false for invalid email format', () => {
expect(isEmail('nabitar@ucsd')).toBe(false);
});
test('Returns false for invalid email format', () => {
expect(isEmail('nabitareng.ucsd.edu')).toBe(false);
});
});

describe('isStrongPassword', () => {
test('Returns true for strong password format', () => {
expect(isStrongPassword('HelloWorld123_')).toBe(true);
});
test('Returns true for strong password format', () => {
expect(isStrongPassword('Ned1')).toBe(true);
});
test('Returns false for weak password format', () => {
expect(isStrongPassword('nabitar@ucsd')).toBe(false);
});
test('Returns false for weak password format', () => {
expect(isStrongPassword('123Pass_')).toBe(false);
});
});

describe('isDate', () => {
test('Returns true for valid date format', () => {
expect(isDate('12/31/2026')).toBe(true);
});
test('Returns true for valid date format', () => {
expect(isDate('5/7/2026')).toBe(true);
});
test('Returns false for invalid date format', () => {
expect(isDate('2026/12/31')).toBe(false);
});
test('Returns false for invalid date format', () => {
expect(isDate('31/12/26')).toBe(false);
});
});

describe('isHexColor', () => {
test('Returns true for valid orange hex color', () => {
expect(isHexColor('#FFA500')).toBe(true);
});
test('Returns true for valid lower-case orange hex color', () => {
expect(isHexColor('#ffa500')).toBe(true);
});
test('Returns false for invalid hex code with missing character', () => {
expect(isHexColor('#FFA50')).toBe(false);
});
test('Returns false for invalid hex code with invalid character', () => {
expect(isHexColor('#FFA50G')).toBe(false);
});
});
});
71 changes: 67 additions & 4 deletions assets/scripts/explore.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,70 @@
// explore.js

window.addEventListener('DOMContentLoaded', init);
const synth = window.speechSynthesis;


function init() {
// TODO
}
const voices = synth.getVoices(); // Corrected line

for (let i = 0; i < voices.length; i++) {
const option = document.createElement("option");
option.textContent = `${voices[i].name} (${voices[i].lang})`;

if (voices[i].default) {
option.textContent += " — DEFAULT";
}

option.setAttribute("data-lang", voices[i].lang);
option.setAttribute("data-name", voices[i].name);
document.getElementById("voice-select").appendChild(option);
}

const button = document.querySelector("button"); // Assuming button ID is "speak-button"
button.addEventListener("click", function() {
const textData = document.getElementById('text-to-speak').value;
playText(textData);
});
}



function playText(text) {
const utterThis = new SpeechSynthesisUtterance(text);
var getPhoto = document.querySelector("img");
const selectedOption = document.getElementById('voice-select').selectedOptions[0].getAttribute('data-name');

const voices = synth.getVoices(); // Moved inside playText function
for (let i = 0; i < voices.length; i++) {
if (voices[i].name === selectedOption) {
console.log("found");
utterThis.voice = voices[i];
}
}

// Event listener for when speech synthesis starts
utterThis.addEventListener(synth.speaking === true, () => {
getPhoto.src = "assets/images/smiling-open.png";
});

// Event listener for when speech synthesis ends
utterThis.addEventListener(synth.speaking === false, () => {
getPhoto.src = "assets/images/smiling.png"; // Change to the path of your other image
});

// Event listener for when speech synthesis starts
utterThis.onstart = () => {
getPhoto.src = "assets/images/smiling-open.png";
};

// Event listener for when speech synthesis ends
utterThis.onend = () => {
getPhoto.src = "assets/images/smiling.png"; // Change to the path of your other image
};




synth.speak(utterThis);


// inputTxt.blur(); // inputTxt is not defined, comment it out
}
64 changes: 60 additions & 4 deletions assets/scripts/expose.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,63 @@
// expose.js

window.addEventListener('DOMContentLoaded', init);
const jsConfetti = new JSConfetti()

function init() {
// TODO
}
const hornType = document.getElementById('horn-select');
hornType.addEventListener("change", function() {
changeHorn(hornType.value);
});

const button = document.querySelector("button");
button.addEventListener("click", function() {
const audio = document.querySelector(".hidden");
if (document.getElementById('horn-select').value == "party-horn") {
jsConfetti.addConfetti()
}
audio.play();
});

const vol = document.getElementById('volume');
vol.addEventListener("input", function() { // Changed to "input" event to update continuously
console.log(vol.value);
changeVol(parseInt(vol.value, 10));
const audio = document.querySelector(".hidden");
audio.volume = vol.value / 100; // Corrected setting volume
})
}

function changeVol(volume) {
const volIco = document.getElementById('volume-controls').querySelector("img");
if (volume === 0) {
volIco.src = "assets/icons/volume-level-0.svg";
} else if (volume < 33) {
volIco.src = "assets/icons/volume-level-1.svg";
} else if (volume < 67) {
volIco.src = "assets/icons/volume-level-2.svg";
} else {
volIco.src = "assets/icons/volume-level-3.svg";
}
}

function changeHorn(hornType) {
const img = document.querySelector("img");
const audio = document.querySelector(".hidden");

switch (hornType) {
case 'air-horn':
img.src = "assets/images/air-horn.svg";
audio.src = "assets/audio/air-horn.mp3";
break;
case 'car-horn':
img.src = "assets/images/car-horn.svg";
audio.src = "assets/audio/car-horn.mp3";
break;
case 'party-horn':
img.src = "assets/images/party-horn.svg";
audio.src = "assets/audio/party-horn.mp3";
break;
default:
// Handle default case
img.src = "assets/images/no-image.png";
break;
}
}
Loading