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
12 changes: 9 additions & 3 deletions __tests__/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,15 @@ describe('Player Tests', () => {
it('addSong should generate a new unique ID when it is not supplied', () => {
const newSongId = addSong(...mockSong3Details.slice(0, -1))
expect(newSongId).toBeDefined()
expect(mockPlayer.songs.map(song => song.id).includes(newSongId)).toBe(false)
expect(mockPlayer.songs.map((song) => song.id).includes(newSongId)).toBe(
false
)
})

it('addSong should throw for an ID that is taken', () => {
expect(() => addSong(...mockSong3Details.slice(0, -1), mockSong1.id)).toThrow()
expect(() =>
addSong(...mockSong3Details.slice(0, -1), mockSong1.id)
).toThrow()
})

it('removePlaylist should remove a playlist from the player', () => {
Expand All @@ -134,7 +138,9 @@ describe('Player Tests', () => {
it('createPlaylist should generate a new unique ID when it is not supplied', () => {
const newPlaylistId = createPlaylist(mockPlaylist2.name)
expect(newPlaylistId).toBeDefined()
expect(mockPlayer.playlists.map(p => p.id).includes(newPlaylistId)).toBe(false)
expect(mockPlayer.playlists.map((p) => p.id).includes(newPlaylistId)).toBe(
false
)
})

it('createPlaylist should throw for an ID that is taken', () => {
Expand Down
230 changes: 217 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,51 +48,255 @@ const player = {
{ id: 5, name: 'Israeli', songs: [4, 5] },
],
playSong(song) {
console.log(/* your code here */)
console.log(
'Playing ' +
song.title +
' from ' +
song.album +
' by ' +
song.artist +
' | ' +
durationFormat(song.duration) +
'.'
)
},
}

function playSong(id) {
// your code here
if (!checkId(player.songs, id)) throw new Error('ID is not found')
for (let i = 0; i < player.songs.length; i++) {
//runs on the songs array
if (player.songs[i].id === id) {
player.playSong(player.songs[i])
}
}
}

function removeSong(id) {
// your code here
if (!checkId(player.songs, id)) throw new Error('ID is not found')
for (let i = 0; i < player.songs.length; i++) {
//runs on the songs array
//remove from songs
if (player.songs[i].id === id) {
player.songs.splice(i, 1)
}
}
removeSongsFromPlaylist(id)
}

function addSong(title, album, artist, duration, id) {
// your code here
function addSong(
title,
album,
artist,
duration,
id = generateNewId(player.songs)
) {
if (checkId(player.songs, id))
throw new Error('ID already exist, change the ID or omit it')
duration = oppositOfdurationFormat(duration) //convert from mm:ss format to seconds
player.songs.push({ title, album, artist, duration, id })
return id
}

function removePlaylist(id) {
// your code here
if (!checkId(player.playlists, id)) throw new Error('ID is not found')
let correctPlaylist = findPlaylistById(id)
player.playlists.splice(correctPlaylist, 1)
}

function createPlaylist(name, id) {
// your code here
function createPlaylist(name, id = generateNewId(player.playlists)) {
if (checkId(player.playlists, id))
throw new Error('ID already exist, change the ID or omit it')
player.playlists.push({ name, id, songs: [] })
return id
}

function playPlaylist(id) {
// your code here
if (!checkId(player.playlists, id))
throw new Error("ID isn't exist, change the ID")
let correctPlaylist = findPlaylistById(id)
for (let j = 0; j < correctPlaylist.songs.length; j++) {
//run on the songs array inside the wanted playlist
playSong(correctPlaylist.songs[j])
}
return id
}

function editPlaylist(playlistId, songId) {
// your code here
if (!checkId(player.songs, songId))
throw new Error("ID isn't exist, change the ID")
if (!checkId(player.playlists, playlistId))
throw new Error("ID isn't exist, change the ID")
let correctPlaylist = findPlaylistById(playlistId)
for (let j = 0; j < correctPlaylist.songs.length; j++) {
//runs on the songs array in the playlist
if (songId === correctPlaylist.songs[j]) {
//if the song ID exists in the playlist
correctPlaylist.songs.splice(j, 1) //removes it
} else {
correctPlaylist.songs.push(songId)
}
if (correctPlaylist.songs.length === 0) {
//if it was the only song in the playlist
removePlaylist(correctPlaylist.id) //remove this playlist
}
}
}

function playlistDuration(id) {
// your code here
let correctPlaylist = findPlaylistById(id) //correctPlaylist contain the wanted playlist
let saveSongId = 0,
sum = 0
for (let i = 0; i < correctPlaylist.songs.length; i++) {
//run on the songs array inside this playlist
saveSongId = correctPlaylist.songs[i]
for (let j = 0; j < player.songs.length; j++) {
//run on the songs array
if (player.songs[j].id === saveSongId) sum += player.songs[j].duration
}
}
return sum
}

function searchByQuery(query) {
// your code here
let tempQuery = query.toUpperCase()
const results = { songs: [], playlists: [] }
for (let i = 0; i < player.playlists.length; i++) {
//for playlists
if (player.playlists[i].name.toUpperCase().includes(tempQuery)) {
results.playlists.push(player.playlists[i])
results.playlists.sort((a, b) => {
if (a.name.toUpperCase() < b.name.toUpperCase()) return -1
})
}
}
for (let i = 0; i < player.songs.length; i++) {
//for songs
if (
player.songs[i].album.toUpperCase().includes(tempQuery) ||
player.songs[i].artist.toUpperCase().includes(tempQuery) ||
player.songs[i].title.toUpperCase().includes(tempQuery)
) {
results.songs.push(player.songs[i])
results.songs.sort((a, b) => {
if (a.title.toUpperCase() < b.title.toUpperCase()) return -1
})
}
}
return results
}

function searchByDuration(duration) {
// your code here
duration = oppositOfdurationFormat(duration) //convert from mm:ss format to seconds
let arrSongs = arrLengthSongs(duration) //arrSongs contain array that look like this: [ closest-duartion-for-song , the-object-himself(song) ]
let arrPlaylist = arrLengthPlaylist(duration) //arrPlaylist contain array that look like this: [ closest-duartion-for-playlist , the-object-himself(playlist) ]
return arrSongs[0] < arrPlaylist[0] ? arrSongs[1] : arrPlaylist[1]
}

////////////////////////////////////////////////--- Help Functions(Start) ---////////////////////////////////////////////////////

function arrLengthSongs(duration) {
//gets song duartion return array of [closet-duration-song-in-seconds , closet-duration-song-the-object-himself(song)]
let arr = []
let minDuration = duration,
index = 0
for (let i = 0; i < player.songs.length; i++) {
//run on the songs array
if (minDuration > Math.abs(duration - player.songs[i].duration)) {
minDuration = Math.abs(duration - player.songs[i].duration)
index = i
}
}
arr.push(minDuration)
arr.push(player.songs[index])
return arr
}

function arrLengthPlaylist(duration) {
//gets playlist duartion return array of [closet-duration-playlist-in-seconds , closet-duration-playlist-the-object-himself(playlist)]
let arr = []
let minDuration = duration,
index = 0
for (let i = 0; i < player.playlists.length; i++) {
//run on playlists array
if (
minDuration >
Math.abs(duration - playlistDuration(player.playlists[i].id))
) {
minDuration = Math.abs(
duration - playlistDuration(player.playlists[i].id)
)
index = i
}
}
arr.push(minDuration)
arr.push(player.playlists[index])
return arr
}

function findPlaylistById(id) {
//Get a playlist id and return the wanted playlist by his id
let correctPlaylist
for (let i = 0; i < player.playlists.length; i++) {
//run on playlists array
if (id === player.playlists[i].id) correctPlaylist = player.playlists[i]
}
return correctPlaylist
}

function removeSongsFromPlaylist(id) {
//this function remove a song only from the playlist and not from the songs object
for (let j = 0; j < player.playlists.length; j++) {
// remove from playlists
for (let k = 0; k < player.playlists[j].songs.length; k++) {
if (player.playlists[j].songs[k] === id) {
player.playlists[j].songs.splice(k, 1)
}
}
}
}

function durationFormat(duration) {
//converting from seconds to mm:ss format
let minutes = Math.floor(duration / 60)
let seconds = duration % 60
if (minutes < 10 && seconds < 10) return '0' + minutes + ':' + '0' + seconds
else if (minutes < 10) return '0' + minutes + ':' + seconds
else if (seconds < 10) return minutes + ':' + '0' + seconds
else return minutes + ':' + seconds
}

function oppositOfdurationFormat(duration) {
//convert from mm:ss format to seconds
duration = duration.split(':')
let minutes = parseInt(duration[0]) * 60
let seconds = parseInt(duration[1])
return minutes + seconds
}

function checkId(songsOrPlaylists, id) {
//gets a songs or playlists array and check if this id existed
for (let i = 0; i < songsOrPlaylists.length; i++) {
//run on songs or playlists array
if (songsOrPlaylists[i].id === id) return true
}
return false
}

function generateNewId(songsOrPlaylists) {
//the function return the biggest ID from thw array
let max = songsOrPlaylists[0].id
for (let i = 0; i < songsOrPlaylists.length; i++) {
//run on songs or playlists array
if (max < songsOrPlaylists[i].id) max = songsOrPlaylists[i].id
}
return max + 1
}

/////////////////////////////////////////////////--- Help Functions(End) ---////////////////////////////////////////////////////

module.exports = {
//Don't touch ben tipagach
player,
playSong,
removeSong,
Expand Down
Loading