packages feed

settei-0.1.0.0: test/Settei/SourceTest.hs

{-# LANGUAGE ImportQualifiedPost #-}

module Settei.SourceTest (tests) where

import Data.Generics.Labels ()
import Data.Map.Strict qualified as Map
import Settei
import Settei.Prelude
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (assertBool, testCase, (@?=))

tests :: TestTree
tests =
  testGroup
    "Settei.Source"
    [ testCase "hierarchical keys traverse objects by segment" $ do
        let result = lookupSource servicePort sampleSource
        case result of
          Right (Just found) -> do
            assertBool "expected the nested port" (candidateValue found == RawNumber 8080)
            candidateOrigin found ^. #key @?= servicePort
          _ -> fail "expected one candidate",
      testCase "arrays are values at their exact declared key" $ do
        let result = lookupSource serviceHosts sampleSource
        case result of
          Right (Just found) ->
            assertBool
              "expected the complete array"
              (candidateValue found == RawArray [RawText "one", RawText "two"])
          _ -> fail "expected one array candidate",
      testCase "traversal through a scalar is a structural error" $ do
        let result = lookupSource servicePortChild sampleSource
        case result of
          Left structuralError -> do
            structuralError ^. #key @?= servicePortChild
            structuralError ^. #blockedAt @?= servicePort
            structuralError ^. #shape @?= ScalarShape
          _ -> fail "expected a structural error",
      testCase "leaf enumeration is ordered and treats arrays wholesale" $
        fmap (renderKey . fst) (sourceLeaves sampleSource)
          @?= ["service.hosts", "service.port"],
      testCase "per-key annotations reach only their matching origins" $ do
        let annotated =
              annotateSourceAt
                (\key -> if key == servicePort then Map.singleton "environment.variable" "PORT" else Map.empty)
                sampleSource
        case (lookupSource servicePort annotated, lookupSource serviceHosts annotated) of
          (Right (Just port), Right (Just hosts)) -> do
            port ^. to candidateOrigin . #annotations . at "environment.variable" @?= Just "PORT"
            hosts ^. to candidateOrigin . #annotations . at "environment.variable" @?= Nothing
          _ -> fail "expected both annotated source candidates"
    ]

sampleSource :: Source
sampleSource =
  source
    "built-in"
    BuiltInSource
    ( RawObject
        ( Map.singleton
            "service"
            ( RawObject
                ( Map.fromList
                    [ ("hosts", RawArray [RawText "one", RawText "two"]),
                      ("port", RawNumber 8080)
                    ]
                )
            )
        )
    )

servicePort :: Key
servicePort = validKey "service.port"

serviceHosts :: Key
serviceHosts = validKey "service.hosts"

servicePortChild :: Key
servicePortChild = validKey "service.port.number"

validKey :: Text -> Key
validKey value = either (error . show) id (parseKey value)