<commit_before>{-# LANGUAGE OverloadedStrings #-}

module CanvasHs.Protocol.OutputSpec (main,spec) where

import Test.Hspec
import Test.QuickCheck

import CanvasHs (shape)
import CanvasHs.Protocol (encode)
import CanvasHs.Data

import qualified Data.Text as T
import qualified Data.ByteString.Lazy.UTF8 as B
import Data.Aeson (decode, Value)


main :: IO ()
main = hspec spec

----------------------- TESTS ----------------------

spec :: Spec
spec = do
    describe "Aeson Value" $ do
        it "is equal on equal JSON" $ do
            shapeTextDec "{\"name\":\"JSON\", \"Pizza\":4}" `shouldBe` shapeTextDec "{\"name\":\"JSON\", \"Pizza\":4}"
        it "is equal on JSON with different ordering" $ do
            shapeTextDec "{\"name\":\"JSON\", \"Pizza\":4}" `shouldBe` shapeTextDec "{\"Pizza\":4, \"name\":\"JSON\"}"
        it "is not equal on different fields" $ do
            shapeTextDec "{\"name\":\"JSON\"}" /= shapeTextDec "{\"name\":\"JSON\", \"Pizza\":4}"
        it "is not equal on different field contents" $ do
            shapeTextDec "{\"name\":\"JSON\"}" /= shapeTextDec "{\"name\":\"Frans\"}"

    describe "Protocol.encode" $ do
        describe "encodes both shapes and actions" $ do
            it "omits Nothing shapes" $ do
                dec (Out (Nothing, [])) `shouldBe` textDec "{\"actions\" : []}"
            it "can encode Actions without Shape" $ do
                actionDec [Debug True] `shouldBe` actionsTextDec "[{\"action\": \"debugger\", \"data\": {\"enabled\": true}}]"
            it "can encode Shape without Actions" $ do
                shapeDec (Rect (1,2) 3 4) `shouldBe` shapeTextDec "{\"type\": \"rect\", \"data\": {\"x\": 1, \"y\": 2, \"width\": 3, \"height\": 4, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}"
    describe "Protocol.encode for shapes" $ do
        describe "encode basic shapes" $ do
            it "can encode proper Rectangles" $ do
                shapeDec (Rect (1,2) 3 4) `shouldBe` shapeTextDec "{\"type\": \"rect\", \"data\": {\"x\": 1, \"y\": 2, \"width\": 3, \"height\": 4, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}"
            it "can encode proper Circles" $ do
                shapeDec (Circle (1,2) 3) `shouldBe` shapeTextDec "{\"type\": \"circle\", \"data\": {\"x\": 1, \"y\": 2, \"radius\": 3, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}"
            it "can encode proper Arcs" $ do
                pendingWith "Arcs not yet implemented"
            it "can encode proper Lines" $ do
                shapeDec (Line [(1,2),(3,4),(5,6),(7,8)]) `shouldBe` shapeTextDec "{\"type\": \"line\", \"data\": {\"points\": [1,2,3,4,5,6,7,8], \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}"
            it "can encode proper Polygons" $ do
                shapeDec (Polygon [(1,2),(3,4),(5,6),(7,8)]) `shouldBe` shapeTextDec "{\"type\": \"polygon\", \"data\": {\"points\": [1,2,3,4,5,6,7,8], \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}"   
        describe "Containers" $ do
            it "can be an empty container" $ do
                shapeDec (Container 1 2 []) `shouldBe` shapeTextDec "{\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 1, \"height\": 2, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}, \"children\":[]}"
            it "can place a basic shape in a container" $ do
                shapeDec (Container 1 2 [(Circle (3,4) 5)]) `shouldBe` shapeTextDec "{\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 1, \"height\": 2, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}, \"children\": [{\"type\": \"circle\", \"data\": {\"x\": 3, \"y\": 4, \"radius\": 5, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}]}"
            it "can place basic shapes in a container" $ do
                shapeDec (Container 1 2 [(Circle (3,4) 5), (Rect (6,7) 8 9)]) `shouldBe` shapeTextDec "{\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 1, \"height\": 2, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}, \"children\": [{\"type\": \"circle\", \"data\": {\"x\": 3, \"y\": 4, \"radius\": 5, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}},{\"type\": \"rect\", \"data\": {\"x\": 6, \"y\": 7, \"width\": 8, \"height\": 9, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}]}"
            it "can place containers in containers" $ do
                shapeDec (Container 10 11 [Circle (12,13) 14, Container 1 2 [(Circle (3,4) 5), (Rect (6,7) 8 9)]]) `shouldBe` shapeTextDec "{\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 10, \"height\": 11, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}, \"children\": [{\"type\": \"circle\", \"data\": {\"x\": 12, \"y\": 13, \"radius\": 14, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}, {\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 1, \"height\": 2, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}, \"children\": [{\"type\": \"circle\", \"data\": {\"x\": 3, \"y\": 4, \"radius\": 5, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}},{\"type\": \"rect\", \"data\": {\"x\": 6, \"y\": 7, \"width\": 8, \"height\": 9, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}]}]}"
        describe "Fill" $ do
            it "can change the fill on a basic shape" $ do
                shapeDec (Fill (4,5,6,0.5) (Circle (1,2) 3)) `shouldBe` shapeTextDec "{\"type\": \"circle\", \"data\": {\"x\": 1, \"y\": 2, \"radius\": 3, \"fill\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}}}"
            it "can recursively change the fill on a containter and its contents" $ do
                shapeDec (Fill (4,5,6,0.5) (Container 10 11 [Circle (12,13) 14, Container 1 2 [(Circle (3,4) 5), (Rect (6,7) 8 9)]])) `shouldBe` shapeTextDec "{\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 10, \"height\": 11, \"fill\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}}, \"children\": [{\"type\": \"circle\", \"data\": {\"x\": 12, \"y\": 13, \"radius\": 14, \"fill\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}}}, {\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 1, \"height\": 2, \"fill\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}}, \"children\": [{\"type\": \"circle\", \"data\": {\"x\": 3, \"y\": 4, \"radius\": 5, \"fill\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}}},{\"type\": \"rect\", \"data\": {\"x\": 6, \"y\": 7, \"width\": 8, \"height\": 9, \"fill\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}}}]}]}"
        describe "Stroke" $ do
            it "can add stroke to a basic shape" $ do
                shapeDec (Stroke (4,5,6,0.5) 1 (Rect (1,2) 3 4)) `shouldBe` shapeTextDec "{\"type\": \"rect\", \"data\": {\"x\": 1, \"y\": 2, \"width\": 3, \"height\": 4, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}, \"stroke\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}, \"strokeWidth\": 1}}"
            it "can recursively add stroke on a container and its contents" $ do<commit_msg>Added haskell test for arcs<commit_after>{-# LANGUAGE OverloadedStrings #-}

module CanvasHs.Protocol.OutputSpec (main,spec) where

import Test.Hspec
import Test.QuickCheck

import CanvasHs (shape)
import CanvasHs.Protocol (encode)
import CanvasHs.Data

import qualified Data.Text as T
import qualified Data.ByteString.Lazy.UTF8 as B
import Data.Aeson (decode, Value)


main :: IO ()
main = hspec spec

----------------------- TESTS ----------------------

spec :: Spec
spec = do
    describe "Aeson Value" $ do
        it "is equal on equal JSON" $ do
            shapeTextDec "{\"name\":\"JSON\", \"Pizza\":4}" `shouldBe` shapeTextDec "{\"name\":\"JSON\", \"Pizza\":4}"
        it "is equal on JSON with different ordering" $ do
            shapeTextDec "{\"name\":\"JSON\", \"Pizza\":4}" `shouldBe` shapeTextDec "{\"Pizza\":4, \"name\":\"JSON\"}"
        it "is not equal on different fields" $ do
            shapeTextDec "{\"name\":\"JSON\"}" /= shapeTextDec "{\"name\":\"JSON\", \"Pizza\":4}"
        it "is not equal on different field contents" $ do
            shapeTextDec "{\"name\":\"JSON\"}" /= shapeTextDec "{\"name\":\"Frans\"}"

    describe "Protocol.encode" $ do
        describe "encodes both shapes and actions" $ do
            it "omits Nothing shapes" $ do
                dec (Out (Nothing, [])) `shouldBe` textDec "{\"actions\" : []}"
            it "can encode Actions without Shape" $ do
                actionDec [Debug True] `shouldBe` actionsTextDec "[{\"action\": \"debugger\", \"data\": {\"enabled\": true}}]"
            it "can encode Shape without Actions" $ do
                shapeDec (Rect (1,2) 3 4) `shouldBe` shapeTextDec "{\"type\": \"rect\", \"data\": {\"x\": 1, \"y\": 2, \"width\": 3, \"height\": 4, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}"
    describe "Protocol.encode for shapes" $ do
        describe "encode basic shapes" $ do
            it "can encode proper Rectangles" $ do
                shapeDec (Rect (1,2) 3 4) `shouldBe` shapeTextDec "{\"type\": \"rect\", \"data\": {\"x\": 1, \"y\": 2, \"width\": 3, \"height\": 4, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}"
            it "can encode proper Circles" $ do
                shapeDec (Circle (1,2) 3) `shouldBe` shapeTextDec "{\"type\": \"circle\", \"data\": {\"x\": 1, \"y\": 2, \"radius\": 3, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}"
            it "can encode proper Arcs" $ do
                shapeDec (Arc (1, 2) 3 4) `shouldBe` shapeTextDec "{\"type\": \"arc\", \"data\": {\"x\": 1, \"y\": 2, \"radius\": 3, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}, \"angleDeg\":4 }}"
            it "can encode proper Lines" $ do
                shapeDec (Line [(1,2),(3,4),(5,6),(7,8)]) `shouldBe` shapeTextDec "{\"type\": \"line\", \"data\": {\"points\": [1,2,3,4,5,6,7,8], \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}"
            it "can encode proper Polygons" $ do
                shapeDec (Polygon [(1,2),(3,4),(5,6),(7,8)]) `shouldBe` shapeTextDec "{\"type\": \"polygon\", \"data\": {\"points\": [1,2,3,4,5,6,7,8], \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}"   
        describe "Containers" $ do
            it "can be an empty container" $ do
                shapeDec (Container 1 2 []) `shouldBe` shapeTextDec "{\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 1, \"height\": 2, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}, \"children\":[]}"
            it "can place a basic shape in a container" $ do
                shapeDec (Container 1 2 [(Circle (3,4) 5)]) `shouldBe` shapeTextDec "{\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 1, \"height\": 2, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}, \"children\": [{\"type\": \"circle\", \"data\": {\"x\": 3, \"y\": 4, \"radius\": 5, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}]}"
            it "can place basic shapes in a container" $ do
                shapeDec (Container 1 2 [(Circle (3,4) 5), (Rect (6,7) 8 9)]) `shouldBe` shapeTextDec "{\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 1, \"height\": 2, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}, \"children\": [{\"type\": \"circle\", \"data\": {\"x\": 3, \"y\": 4, \"radius\": 5, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}},{\"type\": \"rect\", \"data\": {\"x\": 6, \"y\": 7, \"width\": 8, \"height\": 9, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}]}"
            it "can place containers in containers" $ do
                shapeDec (Container 10 11 [Circle (12,13) 14, Container 1 2 [(Circle (3,4) 5), (Rect (6,7) 8 9)]]) `shouldBe` shapeTextDec "{\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 10, \"height\": 11, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}, \"children\": [{\"type\": \"circle\", \"data\": {\"x\": 12, \"y\": 13, \"radius\": 14, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}, {\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 1, \"height\": 2, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}, \"children\": [{\"type\": \"circle\", \"data\": {\"x\": 3, \"y\": 4, \"radius\": 5, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}},{\"type\": \"rect\", \"data\": {\"x\": 6, \"y\": 7, \"width\": 8, \"height\": 9, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}}}]}]}"
        describe "Fill" $ do
            it "can change the fill on a basic shape" $ do
                shapeDec (Fill (4,5,6,0.5) (Circle (1,2) 3)) `shouldBe` shapeTextDec "{\"type\": \"circle\", \"data\": {\"x\": 1, \"y\": 2, \"radius\": 3, \"fill\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}}}"
            it "can recursively change the fill on a containter and its contents" $ do
                shapeDec (Fill (4,5,6,0.5) (Container 10 11 [Circle (12,13) 14, Container 1 2 [(Circle (3,4) 5), (Rect (6,7) 8 9)]])) `shouldBe` shapeTextDec "{\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 10, \"height\": 11, \"fill\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}}, \"children\": [{\"type\": \"circle\", \"data\": {\"x\": 12, \"y\": 13, \"radius\": 14, \"fill\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}}}, {\"type\": \"container\", \"data\": {\"x\": 0, \"y\": 0, \"width\": 1, \"height\": 2, \"fill\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}}, \"children\": [{\"type\": \"circle\", \"data\": {\"x\": 3, \"y\": 4, \"radius\": 5, \"fill\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}}},{\"type\": \"rect\", \"data\": {\"x\": 6, \"y\": 7, \"width\": 8, \"height\": 9, \"fill\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}}}]}]}"
        describe "Stroke" $ do
            it "can add stroke to a basic shape" $ do
                shapeDec (Stroke (4,5,6,0.5) 1 (Rect (1,2) 3 4)) `shouldBe` shapeTextDec "{\"type\": \"rect\", \"data\": {\"x\": 1, \"y\": 2, \"width\": 3, \"height\": 4, \"fill\": {\"r\":0,\"g\":0,\"b\":0,\"a\":1.0}, \"stroke\": {\"r\":4,\"g\":5,\"b\":6,\"a\":0.5}, \"strokeWidth\": 1}}"
            it "can recursively add stroke on a container and its contents" $ do
{'fraction_non_alphanumeric': 0.34300965194501315, 'fraction_numerical': 0.04964902018133957, 'mean_word_length': 2.41072319201995, 'pattern_counts': {'":': 547, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1457007', 'n_tokens_mistral': 5337, 'n_tokens_neox': 4980, 'n_words': 1366}