yesod-raml-mock (empty) → 0.1.0
raw patch · 8 files changed
+270/−0 lines, 8 filesdep +aesondep +basedep +bytestringsetup-changed
Dependencies added: aeson, base, bytestring, containers, hspec, network-uri, regex-posix, template-haskell, text, unordered-containers, vector, yaml, yesod-core, yesod-raml, yesod-raml-mock, yesod-test
Files
- ChangeLog.md +3/−0
- LICENSE +20/−0
- README.md +41/−0
- Setup.hs +2/−0
- Yesod/Raml/Mock.hs +105/−0
- tests/test.hs +27/−0
- tests/test.raml +14/−0
- yesod-raml-mock.cabal +58/−0
+ ChangeLog.md view
@@ -0,0 +1,3 @@+## 0.1.0++* First Release
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 Junji Hashimoto++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ README.md view
@@ -0,0 +1,41 @@+# Yesod-Raml-Mock: ++Yesod-Raml-Mock makes mock-handler from example-tag of [RAML](http://raml.org/spec.html) File.++## Usage++```parseRamlMockFile``` makes mock-handler from RAML file.+Example is below.+++At first, write example-tag with media type.++```+title: Hoge API+baseUri: 'https://hoge/api/{version}'+version: v1+protocols: [ HTTPS ]+/user:+ /{String}:+ handler: HogeR+ get:+ description: hoger+ responses:+ 200:+ body:+ application/json:+ example: '{ "test": "123" }'+```++Second, put ```parseRamlMockFile``` with RAML file.++```+$(parseRamlMockFile "config/routes.raml")+```++This ```parseRamlMockFile``` makes following handler.++```+getHogeR :: Yesod app => String -> Handler app IO TypedContent+getHogeR _ = return $ TypedContent "application/json" "{ \"test\": \"123\" }"+```
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Yesod/Raml/Mock.hs view
@@ -0,0 +1,105 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE CPP #-}++module Yesod.Raml.Mock (+ parseRamlMockFile+, mockFromRaml+) where++import Yesod.Raml.Routes++import Control.Monad++import Yesod.Core+import Data.Char(toLower)+import Language.Haskell.TH.Syntax+import Yesod.Raml.Type+import Yesod.Raml.Parser ()+import Yesod.Routes.TH.Types+import qualified Data.Text as T+import qualified Data.Yaml.Include as YI+++parseRamlMockFile :: FilePath -> Q [Dec]+parseRamlMockFile file = do+ qAddDependentFile file+ s <- qRunIO $ do+ eRaml <- YI.decodeFileEither file+ let raml = case eRaml of+ Right v -> v+ Left e -> error $ "Invalid raml :" ++ show e+ return $ raml+ mockFromRaml s++mockFromRaml :: Raml -> Q [Dec]+mockFromRaml raml = do+ case routesFromRaml raml of+ Left err -> fail err+ Right routes -> do+ decs <- forM routes handlerFromRoute+ return $ concat decs++handlerFromRoute :: RouteEx -> Q [Dec]+handlerFromRoute RouteEx{..} = do+ decs <- forM re_methods (handlerFromRoute' re_pieces re_handler)+ return $ concat decs++handlerFromRoute' :: [Piece String] -> String -> MethodEx -> Q [Dec]+handlerFromRoute' paths handler MethodEx{..} = do+ let method = map toLower $ me_method+ handlerFunc = mkName $ method ++ handler+ args = argsFromPiecies paths+ app = mkName "app"+ ret = mkName "return"+ cont = mkName "TypedContent"+ notfound = mkName "notFound"+ output =+ case me_example of+ Nothing -> (VarE notfound)+ Just (typ,ex) ->+ (AppE+ (VarE ret)+ (AppE+ (AppE (ConE cont)+ (LitE (StringL (T.unpack typ))))+ (LitE (StringL (T.unpack ex)))+ )+ )+ + return [+ SigD handlerFunc (+ ForallT+ [PlainTV app]+#if MIN_VERSION_template_haskell(2,10,0)+ [AppT (ConT ''Yesod) (VarT app)]+#else+ [ClassP ''Yesod [VarT app]]+#endif+ (typeList+ args + (AppT+ (AppT+ (AppT (ConT ''HandlerT) (VarT app))+ (ConT ''IO)+ )+ (ConT ''TypedContent)+ )+ )+ ),+ FunD handlerFunc+ [Clause (wildPs args)+ (NormalB output) []+ ]+ ]+ where+ typeList [] v = v+ typeList (x:xs) v = (AppT (AppT ArrowT (ConT x)) (typeList xs v))+ wildPs xs = map (\_ -> WildP) xs++argsFromPiecies :: [Piece String] -> [Name]+argsFromPiecies [] = []+argsFromPiecies (Static _ : xs ) = argsFromPiecies xs+argsFromPiecies (Dynamic typ : xs ) = mkName typ : argsFromPiecies xs
+ tests/test.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE TypeFamilies #-}++import Test.Hspec+import Yesod.Core+import Yesod.Raml.Mock+import Yesod.Test++$(parseRamlMockFile "tests/test.raml")++data App = App++instance Yesod App++mkYesod "App" [parseRoutes|+/api/v1/user/#String HogeR GET+|]++main :: IO ()+main = hspec $ before (return App) $ do+ it "loads mock handler" $ do+ get $ HogeR "hoge"+ statusIs 200+ bodyContains "123"
+ tests/test.raml view
@@ -0,0 +1,14 @@+title: Hoge API+baseUri: 'https://hoge/api/{version}'+version: v1+protocols: [ HTTPS ]+/user:+ /{String}:+ handler: HogeR+ get:+ description: hoger+ responses:+ 200:+ body:+ application/json:+ example: '{ "test": "123" }'
+ yesod-raml-mock.cabal view
@@ -0,0 +1,58 @@+name: yesod-raml-mock+version: 0.1.0+synopsis: A mock-handler generator library from RAML.+description: A mock-handler generator library from RAML.+license: MIT+license-file: LICENSE+author: junji.hashimoto+maintainer: junji.hashimoto@gmail.com+category: Web, Yesod+build-type: Simple+cabal-version: >=1.10+extra-source-files: ChangeLog.md+ , README.md+ , tests/test.raml++bug-reports: https://github.com/junjihashimoto/yesod-raml/issues++source-repository head+ type: git+ location: https://github.com/junjihashimoto/yesod-raml.git++library+ exposed-modules: Yesod.Raml.Mock+ -- other-modules: + build-depends: base ==4.*+ , yesod-core+ , yesod-raml == 0.2.*+ , containers+ , text+ , yaml+ , bytestring+ , template-haskell+ default-language: Haskell2010+ ghc-options: -Wall+++test-suite test+ type: exitcode-stdio-1.0+ main-is: test.hs+ hs-source-dirs: tests, .+ build-depends: base ==4.*+ , text+ , bytestring+ , aeson+ , unordered-containers+ , containers+ , yaml+ , yesod-core+ , template-haskell+ , hspec+ , yesod-raml+ , yesod-raml-mock+ , network-uri+ , regex-posix+ , vector+ , yesod-test+ default-language: Haskell2010+ ghc-options: -Wall