corpus

Log | Files | Refs | README | LICENSE

commit 91f00219a6799aad4ca110510503048856b705d3
parent fbf0143888d418d809dc034a502eb71e744d60df
Author: mtmn <miro@haravara.org>
Date:   Sun, 12 Apr 2026 22:25:12 +0200

feat: add tests

Diffstat:
Mspago.lock | 107++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mspago.yaml | 10+++++++++-
Msrc/Types.purs | 15+++++++++++++++
Mtest/Main.purs | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
4 files changed, 215 insertions(+), 6 deletions(-)

diff --git a/spago.lock b/spago.lock @@ -45,7 +45,16 @@ ] }, "test": { - "dependencies": [] + "dependencies": [ + "aff", + "argonaut", + "argonaut-core", + "arrays", + "either", + "maybe", + "spec", + "transformers" + ] } } }, @@ -756,6 +765,16 @@ "prelude" ] }, + "ansi": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-tOUaXJFzPSfBVAqLI8hc+Tz2M1rg16cXqyHaK/3SmFg=", + "dependencies": [ + "foldable-traversable", + "lists", + "prelude" + ] + }, "argonaut": { "type": "registry", "version": "9.0.0", @@ -858,6 +877,20 @@ "unsafe-coerce" ] }, + "avar": { + "type": "registry", + "version": "5.0.1", + "integrity": "sha256-8V4SxF4TIWZ9Ik1P4lPzIRUAZeFBe8w5WA2VcCEKsIk=", + "dependencies": [ + "aff", + "effect", + "either", + "exceptions", + "functions", + "maybe", + "prelude" + ] + }, "bifunctors": { "type": "registry", "version": "6.1.0", @@ -1529,6 +1562,23 @@ "prelude" ] }, + "mmorph": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-Cfltaq+tfYjuSoSBN/b8cSQZbvZTqIRs6ebQewbIkGs=", + "dependencies": [ + "bifunctors", + "either", + "free", + "functors", + "identity", + "maybe", + "newtype", + "prelude", + "transformers", + "tuples" + ] + }, "newtype": { "type": "registry", "version": "5.0.0", @@ -1842,6 +1892,27 @@ "integrity": "sha256-mdrlJBAgFMh79hNRW39uv7c+BwnnaOrAMmdh7+VhEhs=", "dependencies": [] }, + "pipes": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-dtUNpG8BGVr7pu6mQZyAnUAftUHgNS7f0QH3Kw5UTpQ=", + "dependencies": [ + "aff", + "control", + "effect", + "either", + "foldable-traversable", + "identity", + "lists", + "maybe", + "mmorph", + "newtype", + "prelude", + "tailrec", + "transformers", + "tuples" + ] + }, "posix-types": { "type": "registry", "version": "6.0.0", @@ -1928,6 +1999,40 @@ "unsafe-coerce" ] }, + "spec": { + "type": "registry", + "version": "8.1.2", + "integrity": "sha256-klPPJ6lBQI1CGOAdLJ+ZoGRt8XZippkTKjn53BrSkL0=", + "dependencies": [ + "aff", + "ansi", + "arrays", + "avar", + "bifunctors", + "control", + "datetime", + "effect", + "either", + "exceptions", + "foldable-traversable", + "fork", + "identity", + "integers", + "lists", + "maybe", + "newtype", + "now", + "ordered-collections", + "parallel", + "pipes", + "prelude", + "refs", + "strings", + "tailrec", + "transformers", + "tuples" + ] + }, "st": { "type": "registry", "version": "6.2.0", diff --git a/spago.yaml b/spago.yaml @@ -40,7 +40,15 @@ package: - web-html test: main: Test.Main - dependencies: [] + dependencies: + - spec + - aff + - argonaut + - argonaut-core + - either + - maybe + - transformers + - arrays workspace: packageSet: registry: 75.9.0 diff --git a/src/Types.purs b/src/Types.purs @@ -6,6 +6,7 @@ import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson import Data.Argonaut.Core (jsonEmptyObject) import Data.Maybe (Maybe) import Data.Generic.Rep (class Generic) +import Data.Show.Generic (genericShow) newtype ListenBrainzResponse = ListenBrainzResponse { payload :: Payload @@ -13,6 +14,8 @@ newtype ListenBrainzResponse = ListenBrainzResponse derive instance eqListenBrainzResponse :: Eq ListenBrainzResponse derive instance genericListenBrainzResponse :: Generic ListenBrainzResponse _ +instance showListenBrainzResponse :: Show ListenBrainzResponse where + show = genericShow instance DecodeJson ListenBrainzResponse where decodeJson json = do @@ -31,6 +34,8 @@ newtype Payload = Payload derive instance eqPayload :: Eq Payload derive instance genericPayload :: Generic Payload _ +instance showPayload :: Show Payload where + show = genericShow instance DecodeJson Payload where decodeJson json = do @@ -50,6 +55,8 @@ newtype Listen = Listen derive instance eqListen :: Eq Listen derive instance genericListen :: Generic Listen _ +instance showListen :: Show Listen where + show = genericShow instance DecodeJson Listen where decodeJson json = do @@ -74,6 +81,8 @@ newtype TrackMetadata = TrackMetadata derive instance eqTrackMetadata :: Eq TrackMetadata derive instance genericTrackMetadata :: Generic TrackMetadata _ +instance showTrackMetadata :: Show TrackMetadata where + show = genericShow instance DecodeJson TrackMetadata where decodeJson json = do @@ -101,6 +110,8 @@ newtype MbidMapping = MbidMapping derive instance eqMbidMapping :: Eq MbidMapping derive instance genericMbidMapping :: Generic MbidMapping _ +instance showMbidMapping :: Show MbidMapping where + show = genericShow instance DecodeJson MbidMapping where decodeJson json = do @@ -122,6 +133,8 @@ newtype StatsEntry = StatsEntry derive instance eqStatsEntry :: Eq StatsEntry derive instance genericStatsEntry :: Generic StatsEntry _ +instance showStatsEntry :: Show StatsEntry where + show = genericShow instance DecodeJson StatsEntry where decodeJson json = do @@ -144,6 +157,8 @@ newtype Stats = Stats derive instance eqStats :: Eq Stats derive instance genericStats :: Generic Stats _ +instance showStats :: Show Stats where + show = genericShow instance DecodeJson Stats where decodeJson json = do diff --git a/test/Main.purs b/test/Main.purs @@ -2,10 +2,91 @@ module Test.Main where import Prelude +import Data.Argonaut (decodeJson, encodeJson, parseJson) +import Data.Array (length) +import Data.Either (Either(..)) +import Data.Maybe (Maybe(..)) import Effect (Effect) -import Effect.Class.Console (log) +import Effect.Aff (launchAff_) +import Test.Spec (describe, it) +import Test.Spec.Assertions (shouldEqual, fail) +import Test.Spec.Reporter.Console (consoleReporter) +import Test.Spec.Runner (runSpec) +import Types (Listen(..), ListenBrainzResponse(..), MbidMapping(..), Payload(..), Stats(..), StatsEntry(..), TrackMetadata(..)) +import Db (connect, initDb, checkExists, upsertScrobble, getScrobbles, initReleaseMetadata, upsertReleaseMetadata, getStats) main :: Effect Unit -main = do - log "🍝" - log "You should add some tests." +main = launchAff_ $ runSpec [consoleReporter] do + describe "Scorpus Types" do + describe "MbidMapping Codecs" do + it "should roundtrip MbidMapping" do + let mbid = MbidMapping { releaseMbid: Just "release-123", caaReleaseMbid: Just "caa-456" } + decodeJson (encodeJson mbid) `shouldEqual` Right mbid + + it "should decode MbidMapping with missing fields" do + let jsonStr = "{\"release_mbid\": \"abc\"}" + let expected = MbidMapping { releaseMbid: Just "abc", caaReleaseMbid: Nothing } + (parseJson jsonStr >>= decodeJson) `shouldEqual` Right expected + + describe "TrackMetadata Codecs" do + it "should roundtrip TrackMetadata" do + let meta = TrackMetadata + { trackName: Just "Song" + , artistName: Just "Artist" + , releaseName: Just "Album" + , mbidMapping: Just (MbidMapping { releaseMbid: Just "rb", caaReleaseMbid: Nothing }) + , genre: Just "Rock" + } + decodeJson (encodeJson meta) `shouldEqual` Right meta + + describe "Listen Codecs" do + it "should roundtrip Listen" do + let listen = Listen + { trackMetadata: TrackMetadata + { trackName: Just "Song" + , artistName: Just "Artist" + , releaseName: Nothing + , mbidMapping: Nothing + , genre: Nothing + } + , listenedAt: Just 1600000000 + } + decodeJson (encodeJson listen) `shouldEqual` Right listen + + describe "Stats Codecs" do + it "should roundtrip Stats" do + let stats = Stats + { genres: [StatsEntry { name: "Rock", count: 10 }] + , labels: [StatsEntry { name: "Label", count: 5 }] + , years: [StatsEntry { name: "2023", count: 15 }] + } + decodeJson (encodeJson stats) `shouldEqual` Right stats + + describe "ListenBrainzResponse Codecs" do + it "should decode a full ListenBrainz response" do + let jsonStr = """ + { + "payload": { + "listens": [ + { + "listened_at": 123456789, + "track_metadata": { + "track_name": "Test Track", + "artist_name": "Test Artist", + "release_name": "Test Album", + "mbid_mapping": { + "release_mbid": "rel-mbid", + "caa_release_mbid": "caa-mbid" + } + } + } + ] + } + } + """ + let result = parseJson jsonStr >>= decodeJson + case result of + Right (ListenBrainzResponse { payload: Payload { listens } }) -> do + length listens `shouldEqual` 1 + Left err -> + fail $ "Decoding failed: " <> show err