Skip to content

Commit 20d154a

Browse files
Add fixtures for API responses (#211)
1 parent 52c81fc commit 20d154a

8 files changed

+142
-3
lines changed

client/.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ install:
77
- npm install
88
- bower install --production
99
script:
10-
- npm run -s build
10+
- npm run -s bundle

client/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
},
77
"scripts": {
88
"clean": "rimraf output",
9-
"build": "spago bundle-app --path $npm_package_config_configpath --purs-args '--censor-lib --strict' --to public/js/index.js"
9+
"test": "spago test --path $npm_package_config_configpath",
10+
"build": "spago build --path $npm_package_config_configpath",
11+
"bundle": "spago bundle-app --path $npm_package_config_configpath --purs-args '--censor-lib --strict' --to public/js/index.js"
1012
},
1113
"devDependencies": {
1214
"purescript": "^0.13.6",

client/spago.dhall

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ You can edit this file as you like.
77
[ "aff"
88
, "affjax"
99
, "arrays"
10+
, "assert"
1011
, "bifunctors"
1112
, "console"
1213
, "const"
@@ -35,6 +36,7 @@ You can edit this file as you like.
3536
, "lazy"
3637
, "math"
3738
, "maybe"
39+
, "node-fs"
3840
, "ordered-collections"
3941
, "parallel"
4042
, "prelude"
@@ -56,5 +58,5 @@ You can edit this file as you like.
5658
, "web-html"
5759
]
5860
, packages = ./packages.dhall
59-
, sources = [ "src/**/*.purs" ]
61+
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
6062
}

client/test/Fixture.purs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
module Test.Fixture.Json where
2+
3+
import Prelude
4+
5+
import Data.Argonaut.Core (Json)
6+
import Data.Argonaut.Parser as Json
7+
import Data.Either (either)
8+
import Effect (Effect)
9+
import Effect.Exception (throw)
10+
import Node.Buffer as Buffer
11+
import Node.Encoding as Encoding
12+
import Node.FS.Sync as FS.Sync
13+
14+
type Fixtures =
15+
{ compileFailure :: Json
16+
, compileOtherError :: Json
17+
, compileSuccess :: Json
18+
}
19+
20+
readFile :: String -> Effect Json
21+
readFile path = do
22+
buffer <- FS.Sync.readFile path
23+
file <- Buffer.toString Encoding.UTF8 buffer
24+
Json.jsonParser file # either (throw <<< append "Malformed fixture: ") pure
25+
26+
readFixtures :: Effect Fixtures
27+
readFixtures = do
28+
compileFailure <- readFile "test/Fixture/compile-failure.json"
29+
compileOtherError <- readFile "test/Fixture/compile-other-error.json"
30+
compileSuccess <- readFile "test/Fixture/compile-success.json"
31+
32+
pure
33+
{ compileFailure
34+
, compileOtherError
35+
, compileSuccess
36+
}
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"error": {
3+
"tag": "CompilerErrors",
4+
"contents": [
5+
{
6+
"suggestion": null,
7+
"moduleName": null,
8+
"errorLink": "https://github.com/purescript/documentation/blob/master/errors/ErrorParsingModule.md",
9+
"errorCode": "ErrorParsingModule",
10+
"message": " Unable to parse module:\n Unexpected token 'String'\n",
11+
"allSpans": [{ "start": [10, 28], "name": "<file>", "end": [10, 34] }],
12+
"filename": "<file>",
13+
"position": {
14+
"startLine": 10,
15+
"endLine": 10,
16+
"startColumn": 28,
17+
"endColumn": 34
18+
}
19+
}
20+
]
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"error": {
3+
"tag": "OtherError",
4+
"contents": "The name of the main module should be Main."
5+
}
6+
}
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"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};",
3+
"warnings": [
4+
{
5+
"suggestion": {
6+
"replaceRange": {
7+
"startLine": 22,
8+
"endLine": 22,
9+
"startColumn": 1,
10+
"endColumn": 1
11+
},
12+
"replacement": "main :: Effect Unit\n\n"
13+
},
14+
"moduleName": "Main",
15+
"errorLink": "https://github.com/purescript/documentation/blob/master/errors/MissingTypeDeclaration.md",
16+
"errorCode": "MissingTypeDeclaration",
17+
"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",
18+
"allSpans": [{ "start": [22, 1], "name": "<file>", "end": [23, 51] }],
19+
"filename": "<file>",
20+
"position": {
21+
"startLine": 22,
22+
"endLine": 23,
23+
"startColumn": 1,
24+
"endColumn": 51
25+
}
26+
}
27+
]
28+
}

client/test/Main.purs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module Test.Main where
2+
3+
import Prelude
4+
5+
import Control.Monad.Except (runExceptT)
6+
import Data.Argonaut.Core (Json)
7+
import Data.Bitraversable (ltraverse)
8+
import Data.Either (Either, isRight)
9+
import Data.Identity (Identity(..))
10+
import Data.List.Types (NonEmptyList)
11+
import Data.Newtype (un)
12+
import Effect (Effect)
13+
import Effect.Class.Console (log, logShow)
14+
import Foreign (ForeignError, unsafeToForeign)
15+
import Foreign.Generic (class Decode, decode)
16+
import Test.Assert (assert)
17+
import Test.Fixture.Json (Fixtures, readFixtures)
18+
import Try.API (CompileResult)
19+
import Type.Proxy (Proxy(..))
20+
21+
main :: Effect Unit
22+
main = do
23+
fixtures <- readFixtures
24+
apiTests fixtures
25+
26+
apiTests :: Fixtures -> Effect Unit
27+
apiTests fixtures = do
28+
shouldDecode (Proxy :: _ CompileResult) fixtures.compileOtherError
29+
shouldDecode (Proxy :: _ CompileResult) fixtures.compileFailure
30+
shouldDecode (Proxy :: _ CompileResult) fixtures.compileSuccess
31+
32+
-- | Test that a JSON response decodes successfully.
33+
shouldDecode :: forall a. Decode a => Proxy a -> Json -> Effect Unit
34+
shouldDecode _ fixture = do
35+
let
36+
result :: Either (NonEmptyList ForeignError) a
37+
result = un Identity $ runExceptT $ decode $ unsafeToForeign fixture
38+
39+
_ <- result # ltraverse \errors -> do
40+
log "Failed to decode fixture:\n"
41+
logShow errors
42+
43+
assert (isRight result)

0 commit comments

Comments
 (0)