git.iko.soy/typeable/servant-reflex
on master help sign in
Try using nix for running tests on travis and improve nix shell
commitc9b0e3051cd13b925dc5e9edb8fb9c352052b3b8 authorGreg Hale <imalsogreg@gmail.com> dateMon 18 Jun 2018, 08:17 (8 years ago) parent1761f87
23 files changed+259−60
.gitmodules−12 .travis.yml+8−39 default.nix+34 deps/http-api-data−1 deps/reflex-platform−1 deps/servant−1 deps/servant-snap−1 nix.conf+3 nix/reflex-platform.nix+9 nix/servant-reflex.nix+14 nix/testdriver.nix+3 nix/testresults.nix+22 nix/testserver.nix+25 release.nix+27 shell.nix+3 testdriver/default.nix+16 testdriver/shell.nix+1 testdriver/test/Servant/ReflexSpec.hs+1−1 testserver/API.hs+69−1 testserver/Main.hs+8−3 testserver/default.nix+14 testserver/shell.nix+1 testserver/testserver.cabal+1
.gitmodules−12
@@ -1,12 +0,0 @@
1−[submodule "deps/http-api-data"]
2− path = deps/http-api-data
3− url = https://github.com/fizruk/http-api-data
4−[submodule "deps/servant"]
5− path = deps/servant
6− url = https://github.com/haskell-servant/servant
7−[submodule "deps/servant-snap"]
8− path = deps/servant-snap
9− url = https://github.com/haskell-servant/servant-snap
10−[submodule "deps/reflex-platform"]
11− path = deps/reflex-platform
12− url = https://github.com/reflex-frp/reflex-platform
.travis.yml+8−39
@@ -1,53 +1,22 @@
1−sudo: required
2−
3−before_cache:
4− - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
5− - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
6−
7−addons:
8− apt:
9− - phantomjs
10−
11−matrix:
12− include:
13− - env: CABALVER=1.24 GHCVER=7.10.3
14− compiler: ": #GHC 7.10.3"
15− addons: {apt: {packages: [cabal-install-1.24,ghc-7.10.3], sources: [hvr-ghc]}}
16− - env: CABALVER=1.24 GHCVER=8.0.1
17− compiler: ": #GHC 8.0.1"
18− addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1], sources: [hvr-ghc]}}
1+language: nix
192
3+cache: false
204
215
226before_install:
237 - unset CC
24− - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
25− - git submodule update --init --recursive
268
279install:
28− - cabal --version
29− - BENCH=${BENCH---enable-benchmarks}
30− - TEST=${TEST---enable-tests}
31− - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
32− - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];
33− then
34− zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >
35− $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;
36− fi
37− - travis_retry cabal update -v
38− - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
39− - deps/reflex-platform/work-on ./overrides-ghc.nix ./testserver --command "cd testserver && cabal configure -fExample && cabal build"
40− - deps/reflex-platform/work-on ghc ./testdriver --command "cd testdriver && cabal configure && cabal build"
41− - cd testserver && dist/build/back/back -p 8000 &
42− - sleep 3
43− - phantomjs --webdriver=127.0.0.1:4444 &
44− - sleep 3
4510
4611script:
12+ - git clone https://github.com/reflex-frp/reflex-platform
13+ - cd reflex-platform && sudo echo "Yes" | ./try-reflex --command "exit 0"
14+ - strace nix build -f ../release.nix servant-reflex
15+
16+ - nix build -f ./release.nix servant-reflex --substituters https://cache.nixos.org --substituters https://nixcache.reflex-frp.org
17+ - nix build -f ./release.nix testresults
4718 - git config --global user.email "travis-ci@example.com"
4819 - git config --global user.name "Travis-CI"
49− - ./build.sh
50− # - testdriver/dist/build/spec/spec
5120
5221cache:
5322 directories:
default.nixnew file+34
@@ -0,0 +1,34 @@
1+{ mkDerivation, aeson, base, bytestring, case-insensitive
2+, containers, data-default, exceptions, ghcjs-dom, http-api-data
3+, http-media, jsaddle, mtl, network-uri, reflex, reflex-dom
4+, reflex-dom-core, safe, scientific, servant, servant-auth, stdenv
5+, string-conversions, text, transformers
6+}:
7+mkDerivation {
8+ pname = "servant-reflex";
9+ version = "0.3.3";
10+ # src = ./.;
11+ src = builtins.filterSource
12+ (path: type:
13+ baseNameOf path != "result"
14+ && baseNameOf path != "nix"
15+ # baseNameOf (toString path) == "src" ||
16+ # baseNameOf (toString path) == "exec" ||
17+ # baseNameOf (toString path) == "servant-reflex.cabal"
18+
19+ ) ./.;
20+ configureFlags = [ "-fexample" ];
21+ isLibrary = true;
22+ isExecutable = true;
23+ libraryHaskellDepends = [
24+ base bytestring case-insensitive containers data-default exceptions
25+ ghcjs-dom http-api-data http-media jsaddle mtl network-uri reflex
26+ reflex-dom-core safe servant servant-auth string-conversions text
27+ transformers
28+ ];
29+ executableHaskellDepends = [
30+ aeson base reflex reflex-dom scientific servant text
31+ ];
32+ description = "Servant reflex API generator";
33+ license = stdenv.lib.licenses.bsd3;
34+}
deps/http-api-datadeleted−1

Submodule changed.

deps/reflex-platformdeleted−1

Submodule changed.

deps/servantdeleted−1

Submodule changed.

deps/servant-snapdeleted−1

Submodule changed.

nix.confnew file+3
@@ -0,0 +1,3 @@
1+substituters = https://cache.nixos.org https://cache.nixos.org https://nixcache.reflex-frp.org
2+trusted-substituters = https://cache.nixos.org https://cache.nixos.org https://nixcache.reflex-frp.org
3+trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI=
nix/reflex-platform.nixnew file+9
@@ -0,0 +1,9 @@
1+{ fetchFromGitHub }:
2+
3+
4+import (fetchFromGitHub {
5+ owner = "reflex-frp";
6+ repo = "reflex-platform";
7+ rev = "a4d679629b52f80ecae857864591d79d902a5c5d";
8+ sha256 = "1p34qc3ryar81jh01g4jm0svr05yri83vlswm2jbxiabigy47652";
9+ }) {}
nix/servant-reflex.nixnew file+14
@@ -0,0 +1,14 @@
1+{ pkgs ? import <nixpkgs> {}, reflexPlatform, compiler ? "ghcjs" }:
2+
3+let
4+
5+ ghcjsPackages = reflexPlatform.${compiler}.override {
6+ overrides = self: super: {
7+ servant = super.servant;
8+ wai = super.wai;
9+ servant-reflex = pkgs.haskell.lib.appendConfigureFlag
10+ (self.callPackage ../. {}) "-fExample";
11+ };
12+ };
13+
14+in ghcjsPackages.servant-reflex
nix/testdriver.nixnew file+3
@@ -0,0 +1,3 @@
1+{ reflexPlatform }:
2+
3+reflexPlatform.ghc.callPackage ../testdriver/default.nix {}
nix/testresults.nixnew file+22
@@ -0,0 +1,22 @@
1+{ curl, reflexPlatform, testdriver, testserver, phantomjs }:
2+
3+reflexPlatform.nixpkgs.pkgs.runCommand "runWebdriveTest.sh" {} ''
4+ echo About to phantom
5+ ${phantomjs}/bin/phantomjs --webdriver=127.0.0.1:4444 &
6+ sleep 3
7+
8+ echo About to server
9+ cd ${testserver} && ./back -q --no-access-log --no-error-log &
10+ sleep 3
11+
12+ ${curl}/bin/curl localhost:8000
13+ ${curl}/bin/curl localhost:8000/runmain.js
14+
15+ echo About to testdrive
16+ ${testdriver}/bin/spec
17+ echo Done
18+ mkdir $out
19+ echo Done > $out/out.txt
20+ trap "exit" INT TERM
21+ trap "kill 0" EXIT
22+ ''
nix/testserver.nixnew file+25
@@ -0,0 +1,25 @@
1+{ servant-reflex, reflexPlatform }:
2+
3+let
4+ ghcPackages = reflexPlatform.ghc.override {
5+ overrides = self: super: {
6+ snap = reflexPlatform.lib.doJailbreak (self.callCabal2nix "snap" ../../snap {});
7+ hspec-snap = reflexPlatform.lib.doJailbreak (super.hspec-snap);
8+ servant-snap = reflexPlatform.lib.doJailbreak (super.servant-snap);
9+ skylighting = reflexPlatform.lib.dontCheck super.skylighting;
10+ testserver = (self.callPackage ../testserver/default.nix {}).overrideDerivation (old:
11+ { postInstall = ''
12+ echo "SOURCE IS: $src"
13+ echo "ls IS: $ls"
14+ echo "EXAMPLE IS: ${servant-reflex}"
15+ cp dist/build/back/back $out/back
16+ mkdir $out/static
17+ cp ${servant-reflex}/bin/example.jsexe/* $out/static/
18+ '';
19+ }
20+ );
21+ heist = reflexPlatform.lib.doJailbreak super.heist;
22+ };
23+ };
24+
25+in ghcPackages.testserver
release.nixnew file+27
@@ -0,0 +1,27 @@
1+{ pkgs ? import <nixpkgs> {}, compiler ? "ghcjs" }:
2+
3+let
4+ reflexPlatform =
5+ import ./nix/reflex-platform.nix {
6+ fetchFromGitHub = pkgs.fetchFromGitHub;
7+ };
8+
9+in rec {
10+
11+ servant-reflex = import ./nix/servant-reflex.nix {
12+ reflexPlatform = reflexPlatform;
13+ compiler = compiler;
14+ };
15+ testserver = import ./nix/testserver.nix
16+ { reflexPlatform = reflexPlatform;
17+ servant-reflex = servant-reflex ;
18+ };
19+ testdriver = import ./nix/testdriver.nix
20+ { reflexPlatform = reflexPlatform;
21+ };
22+ testresults = import ./nix/testresults.nix
23+ { inherit reflexPlatform testserver testdriver;
24+ inherit (pkgs) curl;
25+ phantomjs = pkgs.phantomjs2;
26+ };
27+ }
shell.nixnew file+3
@@ -0,0 +1,3 @@
1+{ compiler ? "ghcjs" }:
2+
3+(import ./release.nix { inherit compiler; }).servant-reflex.env
testdriver/default.nixnew file+16
@@ -0,0 +1,16 @@
1+{ mkDerivation, base, hspec, hspec-webdriver, stdenv, text
2+, webdriver
3+}:
4+mkDerivation {
5+ pname = "testdriver";
6+ version = "0.2";
7+ src = ./.;
8+ isLibrary = false;
9+ isExecutable = true;
10+ executableHaskellDepends = [
11+ base hspec hspec-webdriver text webdriver
12+ ];
13+ description = "Selenium test driver for Servant reflex";
14+ license = stdenv.lib.licenses.bsd3;
15+ hydraPlatforms = stdenv.lib.platforms.none;
16+}
testdriver/shell.nixnew file+1
@@ -0,0 +1 @@
1+(import ../release3.nix {}).testdriver.env
testdriver/test/Servant/ReflexSpec.hs+1−1
@@ -28,7 +28,7 @@ spec :: Spec
2828spec = do
2929 describe "servant-reflex tests" $ do
3030
31− session "test page" $ using Chrome $ do
31+ session "test page" $ using [chromeCaps] $ do
3232
3333 it "opens the page" $ runWD $
3434 openPage "http://localhost:8000"
testserver/API.hsmode 120000 → 100644+69−1
@@ -1 +0,0 @@
1−../exec/API.hs
@@ -0,0 +1,69 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE TypeOperators #-}
4+
5+module API where
6+
7+import Data.Aeson
8+import Data.Aeson.Types (typeMismatch)
9+import Data.Text (Text)
10+import Servant.API
11+
12+newtype Question = Question { unQuestion :: Text } deriving (Show)
13+
14+instance ToJSON Question where
15+ toJSON (Question txt) = object ["question" .= txt]
16+
17+instance FromJSON Question where
18+ parseJSON (Object v) = Question <$> v .: "question"
19+ parseJSON x = typeMismatch "Couldn't find key 'question'" x
20+
21+newtype Answer = Answer { unAnswer :: Text } deriving (Show)
22+
23+instance ToJSON Answer where
24+ toJSON (Answer txt) = object ["answer" .= txt]
25+
26+instance FromJSON Answer where
27+ parseJSON (Object v) = Answer <$> v .: "answer"
28+ parseJSON x = typeMismatch "Couldn't find key 'answer'" x
29+
30+
31+-- | API spec for server, client, and docs
32+type API = "getunit" :> Get '[JSON] ()
33+ :<|> "getint" :> Get '[JSON] Int
34+ :<|> "sayhi" :> QueryParam "username" Text
35+ :> QueryParams "greetings" Text
36+ :> QueryFlag "gusto"
37+ :> Get '[JSON] Text
38+ :<|> "double" :> ReqBody '[JSON] Double
39+ :> Post '[JSON] Double
40+ :<|> "a" :> "b" :> QueryFlag "gusto" :> Get '[JSON] Text
41+ :<|> "qna" :> ReqBody '[JSON] Question
42+ :> Post '[JSON] Answer
43+ :<|> "secret" :> BasicAuth "realm" () :> Get '[JSON] Int
44+ :<|> Raw
45+
46+type GET = Get '[JSON] ()
47+
48+-- Imported the comprehensive API example for testing.
49+-- https://github.com/haskell-servant/servant/blob/master/servant/src/Servant/API/Internal/Test/ComprehensiveAPI.hs
50+type ComprehensiveAPI =
51+ GET :<|>
52+ Get '[JSON] Int :<|>
53+ Capture "foo" Int :> GET :<|>
54+ Header "foo" Int :> GET :<|>
55+ HttpVersion :> GET :<|>
56+ IsSecure :> GET :<|>
57+ QueryParam "foo" Int :> GET :<|>
58+ QueryParams "foo" Int :> GET :<|>
59+ QueryFlag "foo" :> GET :<|>
60+-- Raw :<|>
61+ RemoteHost :> GET :<|>
62+ ReqBody '[JSON] Int :> GET :<|>
63+ Get '[JSON] (Headers '[Header "foo" Int] ()) :<|>
64+ "foo" :> GET :<|>
65+ Vault :> GET :<|>
66+ Verb 'POST 204 '[JSON] () :<|>
67+ Verb 'POST 204 '[JSON] Int
68+-- This one isn't in scope
69+-- :<|> WithNamedContext "foo" '[] GET
testserver/Main.hs+8−3
@@ -18,12 +18,12 @@ import Data.Text hiding (head, length, map,
1818import qualified Data.Text as T
1919import qualified Data.Text.IO as T
2020import GHC.Generics
21−import Servant.Server.Internal.SnapShims
2221import Snap.Core
2322import Snap.Http.Server
2423
2524import Servant
26−import Servant.Server
25+import Servant.Server ()
26+import System.Directory
2727-- import Snap.Util.FileServe
2828import API
2929import Snap
@@ -85,6 +85,8 @@ test = serveSnapWithContext testApi
8585
8686initApp :: SnapletInit App App
8787initApp = makeSnaplet "myapp" "example" Nothing $ do
88+ liftIO $ print =<< listDirectory "."
89+ liftIO $ print =<< listDirectory "static"
8890 addRoutes [("", test)
8991 ,("", serveDirectory "static")
9092 ]
@@ -92,4 +94,7 @@ initApp = makeSnaplet "myapp" "example" Nothing $ do
9294
9395-- Put this all to work!
9496main :: IO ()
95−main = serveSnaplet mempty initApp
97+main = commandLineConfig emptyConfig >>= \cfg -> print cfg >> serveSnaplet cfg initApp
98+-- main = serveSnaplet (defaultConfig { accessLog = "/tmp/log/testserver-access.log"
99+-- , errorLog = "/tmp/log/testserver-error.log"
100+-- }) initApp
testserver/default.nixnew file+14
@@ -0,0 +1,14 @@
1+{ mkDerivation, aeson, base, servant, servant-snap, snap, snap-core
2+, snap-server, stdenv, text
3+}:
4+mkDerivation {
5+ pname = "testserver";
6+ version = "0.1.0.0";
7+ src = ./.;
8+ isLibrary = false;
9+ isExecutable = true;
10+ executableHaskellDepends = [
11+ aeson base servant servant-snap snap snap-core snap-server text
12+ ];
13+ license = stdenv.lib.licenses.bsd3;
14+}
testserver/shell.nixnew file+1
@@ -0,0 +1 @@
1+(import ../release2.nix {}).testserver.env
testserver/testserver.cabal+1
@@ -21,6 +21,7 @@ executable back
2121 -- other-extensions:
2222 build-depends: aeson >= 0.9 && < 1.4
2323 , base >=4.8 && <4.11
24+ , directory >= 1.2 && < 1.4
2425 , snap >= 1.0 && < 1.2
2526 , snap-server >= 1.0 && < 1.1
2627 , snap-core >= 1.0 && < 1.1