-- | -- -- Module : Data.Aeson.Optics.ExtSpec -- Copyright : (c) 2025 Patrick Brisbin -- License : AGPL-3 -- Maintainer : pbrisbin@gmail.com -- Stability : experimental -- Portability : POSIX module Data.Aeson.Optics.ExtSpec ( spec ) where import Prelude import Data.Aeson.Key qualified as Key import Data.Aeson.Optics import Data.Aeson.Optics.Ext import Data.Aeson.QQ import Data.Foldable (for_) import Optics import Test.Hspec spec :: Spec spec = do describe "atNth" $ do it "indexes arrays as expected" $ do let input = [aesonQQ| ["a", "b"] |] input ^? atNth (-1) % _Just `shouldBe` Nothing input ^? atNth 0 % _Just % _String `shouldBe` Just "a" input ^? atNth 1 % _Just % _String `shouldBe` Just "b" input ^? atNth 2 % _Just `shouldBe` Nothing it "adds to arrays by shifting elements right" $ do let input = [aesonQQ| ["a", "b"] |] input & atNth (-1) ?~ "x" & (`shouldBe` input) input & atNth 0 ?~ "x" & (`shouldBe` [aesonQQ| ["x", "a", "b"] |]) input & atNth 1 ?~ "x" & (`shouldBe` [aesonQQ| ["a", "x", "b"] |]) input & atNth 2 ?~ "x" & (`shouldBe` [aesonQQ| ["a", "b", "x"] |]) input & atNth 3 ?~ "x" & (`shouldBe` input) it "removes from arrays by shifting elements left" $ do let input = [aesonQQ| ["a", "b", "c"] |] input & atNth (-1) .~ Nothing & (`shouldBe` input) input & atNth 0 .~ Nothing & (`shouldBe` [aesonQQ| ["b", "c"] |]) input & atNth 1 .~ Nothing & (`shouldBe` [aesonQQ| ["a", "c"] |]) input & atNth 2 .~ Nothing & (`shouldBe` [aesonQQ| ["a", "b"] |]) input & atNth 3 .~ Nothing & (`shouldBe` input) context "targeting an Object" $ do let input = [aesonQQ| {"0":"a", "1":"b", "2":"c"} |] for_ [-1 .. 3] $ \n -> do let k = Key.fromString $ show n index l = input ^? l add l = input & l ?~ "x" remove l = input & l .~ Nothing it ("indexes like atKey for " <> show n) $ do index (atNth n) `shouldBe` index (atKey k) it ("adds like atKey for " <> show n) $ do add (atNth n) `shouldBe` add (atKey k) it ("removes like atKey for " <> show n) $ do remove (atNth n) `shouldBe` remove (atKey k)