From 5c04de3466e9019067cfa1662428ba9882e0f7e3 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Thu, 18 Mar 2021 19:02:43 -0700 Subject: [PATCH 1/3] Add fixtures for API responses --- client/.travis.yml | 2 +- client/package.json | 4 ++- client/spago.dhall | 3 +- client/test/Fixture.purs | 36 ++++++++++++++++++++ client/test/Fixture/compile-failure.json | 22 ++++++++++++ client/test/Fixture/compile-other-error.json | 6 ++++ client/test/Fixture/compile-success.json | 28 +++++++++++++++ client/test/Main.purs | 9 +++++ 8 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 client/test/Fixture.purs create mode 100644 client/test/Fixture/compile-failure.json create mode 100644 client/test/Fixture/compile-other-error.json create mode 100644 client/test/Fixture/compile-success.json create mode 100644 client/test/Main.purs diff --git a/client/.travis.yml b/client/.travis.yml index ce98764d..156a7a0e 100644 --- a/client/.travis.yml +++ b/client/.travis.yml @@ -7,4 +7,4 @@ install: - npm install - bower install --production script: - - npm run -s build + - npm run -s build:prod diff --git a/client/package.json b/client/package.json index 176e15c5..832a05d3 100644 --- a/client/package.json +++ b/client/package.json @@ -6,7 +6,9 @@ }, "scripts": { "clean": "rimraf output", - "build": "spago bundle-app --path $npm_package_config_configpath --purs-args '--censor-lib --strict' --to public/js/index.js" + "test": "spago test --path ./config/dev/Try.Config.purs", + "build:dev": "spago build --path ./config/dev/Try.Config.purs", + "build:prod": "spago bundle-app --path $npm_package_config_configpath --purs-args '--censor-lib --strict' --to public/js/index.js" }, "devDependencies": { "purescript": "^0.13.6", diff --git a/client/spago.dhall b/client/spago.dhall index dddfd3f7..4a3f9391 100644 --- a/client/spago.dhall +++ b/client/spago.dhall @@ -35,6 +35,7 @@ You can edit this file as you like. , "lazy" , "math" , "maybe" + , "node-fs" , "ordered-collections" , "parallel" , "prelude" @@ -56,5 +57,5 @@ You can edit this file as you like. , "web-html" ] , packages = ./packages.dhall -, sources = [ "src/**/*.purs" ] +, sources = [ "src/**/*.purs", "test/**/*.purs" ] } diff --git a/client/test/Fixture.purs b/client/test/Fixture.purs new file mode 100644 index 00000000..b06a1dde --- /dev/null +++ b/client/test/Fixture.purs @@ -0,0 +1,36 @@ +module Test.Fixture.Json where + +import Prelude + +import Data.Argonaut.Core (Json) +import Data.Argonaut.Parser as Json +import Data.Either (either) +import Effect (Effect) +import Effect.Exception (throw) +import Node.Buffer as Buffer +import Node.Encoding as Encoding +import Node.FS.Sync as FS.Sync + +type Fixtures = + { compileFailure :: Json + , compileOtherError :: Json + , compileSuccess :: Json + } + +readFile :: String -> Effect Json +readFile path = do + buffer <- FS.Sync.readFile path + file <- Buffer.toString Encoding.UTF8 buffer + Json.jsonParser file # either (throw <<< append "Malformed fixture: ") pure + +readFixtures :: Effect Fixtures +readFixtures = do + compileFailure <- readFile "compile-failure.json" + compileOtherError <- readFile "compile-other-error.json" + compileSuccess <- readFile "compile-success.json" + + pure + { compileFailure + , compileOtherError + , compileSuccess + } diff --git a/client/test/Fixture/compile-failure.json b/client/test/Fixture/compile-failure.json new file mode 100644 index 00000000..903d1792 --- /dev/null +++ b/client/test/Fixture/compile-failure.json @@ -0,0 +1,22 @@ +{ + "error": { + "tag": "CompilerErrors", + "contents": [ + { + "suggestion": null, + "moduleName": null, + "errorLink": "https://github.com/purescript/documentation/blob/master/errors/ErrorParsingModule.md", + "errorCode": "ErrorParsingModule", + "message": " Unable to parse module:\n Unexpected token 'String'\n", + "allSpans": [{ "start": [10, 28], "name": "", "end": [10, 34] }], + "filename": "", + "position": { + "startLine": 10, + "endLine": 10, + "startColumn": 28, + "endColumn": 34 + } + } + ] + } +} diff --git a/client/test/Fixture/compile-other-error.json b/client/test/Fixture/compile-other-error.json new file mode 100644 index 00000000..b89e07e6 --- /dev/null +++ b/client/test/Fixture/compile-other-error.json @@ -0,0 +1,6 @@ +{ + "error": { + "tag": "OtherError", + "contents": "The name of the main module should be Main." + } +} diff --git a/client/test/Fixture/compile-success.json b/client/test/Fixture/compile-success.json new file mode 100644 index 00000000..a45f618f --- /dev/null +++ b/client/test/Fixture/compile-success.json @@ -0,0 +1,28 @@ +{ + "js": "\"use strict\";\nvar Control_Bind = require(\"../Control.Bind/index.js\");\nvar Data_Eq = require(\"../Data.Eq/index.js\");\nvar Data_Map_Internal = require(\"../Data.Map.Internal/index.js\");\nvar Data_Maybe = require(\"../Data.Maybe/index.js\");\nvar Data_Ord = require(\"../Data.Ord/index.js\");\nvar Data_Ordering = require(\"../Data.Ordering/index.js\");\nvar Data_Show = require(\"../Data.Show/index.js\");\nvar Effect = require(\"../Effect/index.js\");\nvar Effect_Console = require(\"../Effect.Console/index.js\");\nvar TryPureScript = require(\"../TryPureScript/index.js\");\n\n// | A Name consists of a first name and a last name\nvar Name = (function () {\n function Name(value0, value1) {\n this.value0 = value0;\n this.value1 = value1;\n };\n Name.create = function (value0) {\n return function (value1) {\n return new Name(value0, value1);\n };\n };\n return Name;\n})();\n\n// | The Ord instance allows us to use Names as the\n// | keys in a Map.\nvar phoneBook = Data_Map_Internal.singleton(new Name(\"John\", \"Smith\"))(\"555-555-1234\");\n\n// | With compiler versions >= 0.8.2, we can derive \n// | instances for Eq and Ord, making names comparable.\nvar eqName = new Data_Eq.Eq(function (x) {\n return function (y) {\n return x.value0 === y.value0 && x.value1 === y.value1;\n };\n});\nvar ordName = new Data_Ord.Ord(function () {\n return eqName;\n}, function (x) {\n return function (y) {\n var $20 = Data_Ord.compare(Data_Ord.ordString)(x.value0)(y.value0);\n if ($20 instanceof Data_Ordering.LT) {\n return Data_Ordering.LT.value;\n };\n if ($20 instanceof Data_Ordering.GT) {\n return Data_Ordering.GT.value;\n };\n return Data_Ord.compare(Data_Ord.ordString)(x.value1)(y.value1);\n };\n});\nvar main = Control_Bind.bindFlipped(Effect.bindEffect)(TryPureScript.render)(TryPureScript.withConsole(Effect_Console.logShow(Data_Maybe.showMaybe(Data_Show.showString))(Data_Map_Internal.lookup(ordName)(new Name(\"John\", \"Smith\"))(phoneBook))));\nmodule.exports = {\n Name: Name,\n phoneBook: phoneBook,\n main: main,\n eqName: eqName,\n ordName: ordName\n};", + "warnings": [ + { + "suggestion": { + "replaceRange": { + "startLine": 22, + "endLine": 22, + "startColumn": 1, + "endColumn": 1 + }, + "replacement": "main :: Effect Unit\n\n" + }, + "moduleName": "Main", + "errorLink": "https://github.com/purescript/documentation/blob/master/errors/MissingTypeDeclaration.md", + "errorCode": "MissingTypeDeclaration", + "message": " No type declaration was provided for the top-level declaration of main.\n It is good practice to provide type declarations as a form of documentation.\n The inferred type of main was:\n\n Effect Unit\n\n\nin value declaration main\n", + "allSpans": [{ "start": [22, 1], "name": "", "end": [23, 51] }], + "filename": "", + "position": { + "startLine": 22, + "endLine": 23, + "startColumn": 1, + "endColumn": 51 + } + } + ] +} diff --git a/client/test/Main.purs b/client/test/Main.purs new file mode 100644 index 00000000..f1c25fba --- /dev/null +++ b/client/test/Main.purs @@ -0,0 +1,9 @@ +module Test.Main where + +import Prelude + +import Effect (Effect) +import Effect.Class.Console (log) + +main :: Effect Unit +main = log "Add some tests." From 351c2bb258021cffeb00974bc630335a0425e563 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Fri, 19 Mar 2021 13:28:19 -0700 Subject: [PATCH 2/3] Exercise response decoding in tests --- client/spago.dhall | 1 + client/test/Fixture.purs | 6 +++--- client/test/Main.purs | 38 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/client/spago.dhall b/client/spago.dhall index 4a3f9391..a21cdeea 100644 --- a/client/spago.dhall +++ b/client/spago.dhall @@ -7,6 +7,7 @@ You can edit this file as you like. [ "aff" , "affjax" , "arrays" + , "assert" , "bifunctors" , "console" , "const" diff --git a/client/test/Fixture.purs b/client/test/Fixture.purs index b06a1dde..bbf3ba0c 100644 --- a/client/test/Fixture.purs +++ b/client/test/Fixture.purs @@ -25,9 +25,9 @@ readFile path = do readFixtures :: Effect Fixtures readFixtures = do - compileFailure <- readFile "compile-failure.json" - compileOtherError <- readFile "compile-other-error.json" - compileSuccess <- readFile "compile-success.json" + compileFailure <- readFile "test/Fixture/compile-failure.json" + compileOtherError <- readFile "test/Fixture/compile-other-error.json" + compileSuccess <- readFile "test/Fixture/compile-success.json" pure { compileFailure diff --git a/client/test/Main.purs b/client/test/Main.purs index f1c25fba..9d4fb24c 100644 --- a/client/test/Main.purs +++ b/client/test/Main.purs @@ -2,8 +2,42 @@ module Test.Main where import Prelude +import Control.Monad.Except (runExceptT) +import Data.Argonaut.Core (Json) +import Data.Bitraversable (ltraverse) +import Data.Either (Either, isRight) +import Data.Identity (Identity(..)) +import Data.List.Types (NonEmptyList) +import Data.Newtype (un) import Effect (Effect) -import Effect.Class.Console (log) +import Effect.Class.Console (log, logShow) +import Foreign (ForeignError, unsafeToForeign) +import Foreign.Generic (class Decode, decode) +import Test.Assert (assert) +import Test.Fixture.Json (Fixtures, readFixtures) +import Try.API (CompileResult) +import Type.Proxy (Proxy(..)) main :: Effect Unit -main = log "Add some tests." +main = do + fixtures <- readFixtures + apiTests fixtures + +apiTests :: Fixtures -> Effect Unit +apiTests fixtures = do + shouldDecode (Proxy :: _ CompileResult) fixtures.compileOtherError + shouldDecode (Proxy :: _ CompileResult) fixtures.compileFailure + shouldDecode (Proxy :: _ CompileResult) fixtures.compileSuccess + +-- | Test that a JSON response decodes successfully. +shouldDecode :: forall a. Decode a => Proxy a -> Json -> Effect Unit +shouldDecode _ fixture = do + let + result :: Either (NonEmptyList ForeignError) a + result = un Identity $ runExceptT $ decode $ unsafeToForeign fixture + + _ <- result # ltraverse \errors -> do + log "Failed to decode fixture:\n" + logShow errors + + assert (isRight result) From a3c9755b0a858d6a2f9bfd21adf864d516e4c6d0 Mon Sep 17 00:00:00 2001 From: Thomas Honeyman Date: Fri, 19 Mar 2021 13:31:06 -0700 Subject: [PATCH 3/3] build -> bundle --- client/.travis.yml | 2 +- client/package.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/.travis.yml b/client/.travis.yml index 156a7a0e..754de2b2 100644 --- a/client/.travis.yml +++ b/client/.travis.yml @@ -7,4 +7,4 @@ install: - npm install - bower install --production script: - - npm run -s build:prod + - npm run -s bundle diff --git a/client/package.json b/client/package.json index 832a05d3..489b488c 100644 --- a/client/package.json +++ b/client/package.json @@ -6,9 +6,9 @@ }, "scripts": { "clean": "rimraf output", - "test": "spago test --path ./config/dev/Try.Config.purs", - "build:dev": "spago build --path ./config/dev/Try.Config.purs", - "build:prod": "spago bundle-app --path $npm_package_config_configpath --purs-args '--censor-lib --strict' --to public/js/index.js" + "test": "spago test --path $npm_package_config_configpath", + "build": "spago build --path $npm_package_config_configpath", + "bundle": "spago bundle-app --path $npm_package_config_configpath --purs-args '--censor-lib --strict' --to public/js/index.js" }, "devDependencies": { "purescript": "^0.13.6",