Recent songlist
Create a recent song list to hold a unique set of songs that have been played.
The most recently played song is at the start of the list, the least recently played song is the last in the list.
- A recently-used-list is initially empty.
- Songs in the list are unique, so repeatedly played songs should only appear once in the list
- Songs can be looked up by index, which counts from zero.
- Empty song names are not allowed.
- Add a limit to the number of songs the list contains, with the least recently added items dropped when that limit is reached.
Create a new Clojure project
Use Clojure CLI tools and clj-new to create a new Clojure project.
clojure -M:new app practicalli/recent-songlist
Using clojure.test
We are writing our tests with the clojure.test
library
Open test/playground/recent-song-list-test.clj
file in your editor and update the namespace definition to include clojure.test
(ns practicalli.recent-songlist-test
(:require [clojure.test :refer [deftest is testing]]
[playground.recent-song-list :as SUT]))
Run Tests
At any time we can call the run-tests
function in the REPL to get a report back on all of the tests in our current namespace (recent-song-list
)
(run-tests)
The Cognitect Labs test runner is included in the project by default and can be run from the command line in the root directory of the project.
clojure -M:test:runner
Define a recent song list
In the source file,
src/playground/recent-song-list.clj
, define a name for your collection of recent songsYou can use an empty collection to start with. Which collection type will you use though?
Write a test to check a song-list exists
A simple test that compares an empty vector with the value of recent-songs
(deftest song-list-empty-test
(testing "Is song list empty if we haven't added any songs"
(is
(= [] recent-songs))))
Here is the same test using the empty?
function instead of the =
function.
(deftest song-list-empty-test-2
(testing "Is song list empty if we haven't added any songs"
(is
(empty? recent-songs))))
Write a test to add a song to the list
(deftest adding-songs-test
(testing "add song returns a song list with entries"
(is
(not (empty?
(add-song "Barry Manilow - Love on the rocks" recent-songs)))))
(testing "add multiple song returns a song list with entries"
(is
(not (empty?
(->> recent-songs
(add-song "Barry Manilow - Love on the rocks")
(add-song "Phil Colins - Sususudio" )))))))
This suggested solution defines our recent songs as an empty vector.
The add-song
function takes the name of a song and the song list to which it will be added.
A Thread-last macro ->>
is used to pass the song list over two functions.
The song-list
is first passed to the remove
expression as its last argument. This expression will remove any occurrence of the new song we want to add from the song-list
.
The results of the remove
expression are then passed to the cons
expression as its last argument. The cons
expression simply adds the new song to the start of the list, making it the most recent song.
(def recent-songs [])
(defn add-song [song song-list]
(->> song-list
(remove #(= song %))
(cons song)))