packages feed

servant-js 0.9 → 0.9.1

raw patch · 8 files changed

+57/−22 lines, 8 filesdep +QuickCheckdep ~aesondep ~hspecdep ~servantnew-uploader

Dependencies added: QuickCheck

Dependency ranges changed: aeson, hspec, servant, servant-foreign, servant-server

Files

CHANGELOG.md view
@@ -1,3 +1,9 @@+0.9.1+-----++* Fix javascript function name generation+* Allow servant-0.10+ 0.5 ---- 
servant-js.cabal view
@@ -1,16 +1,16 @@ name:                servant-js-version:             0.9+version:             0.9.1 synopsis:            Automatically derive javascript functions to query servant webservices. description:   Automatically derive javascript functions to query servant webservices.   .   Supports deriving functions using vanilla javascript AJAX requests, Angulari, Axios or JQuery.   .-  You can find an example <https://github.com/haskell-servant/servant/blob/master/servant-js/examples/counter.hs here>+  You can find an example <https://github.com/haskell-servant/servant-js/blob/master/servant-js/examples/counter.hs here>   which serves the generated javascript to a webpage that allows you to trigger   webservice calls.   .-  <https://github.com/haskell-servant/servant/blob/master/servant-js/CHANGELOG.md CHANGELOG>+  <https://github.com/haskell-servant/servant-js/blob/master/CHANGELOG.md CHANGELOG> license:             BSD3 license-file:        LICENSE author:              Servant Contributors@@ -20,14 +20,15 @@ build-type:          Simple cabal-version:       >=1.10 homepage:            http://haskell-servant.readthedocs.org/-Bug-reports:         http://github.com/haskell-servant/servant/issues+bug-reports:         http://github.com/haskell-servant/servant-js/issues+tested-with:         GHC==7.8.3, GHC==7.10.3, GHC==8.0.1 extra-source-files:   include/*.h   CHANGELOG.md   README.md source-repository head   type: git-  location: http://github.com/haskell-servant/servant.git+  location: http://github.com/haskell-servant/servant-js.git  flag example   description: Build the example too@@ -45,8 +46,8 @@                      , base-compat     >= 0.9                      , charset         >= 0.3                      , lens            >= 4-                     , servant-foreign == 0.9.*-                     , servant         == 0.9.*+                     , servant-foreign >= 0.9 && <0.11+                     , servant         >= 0.9 && <0.11                      , text            >= 1.2  && < 1.3    hs-source-dirs:      src@@ -86,11 +87,12 @@       Servant.JSSpec.CustomHeaders   build-depends:     base                    , base-compat-                   , hspec >= 2.1.8+                   , hspec >= 2.3.0 && <2.5                    , hspec-expectations                    , language-ecmascript >= 0.16                    , lens                    , servant                    , servant-js                    , text+                   , QuickCheck   default-language:  Haskell2010
src/Servant/JS/Angular.hs view
@@ -132,7 +132,7 @@          fsep = if hasService then ":" else " =" -        fname = namespace <> (functionNameBuilder opts $ req ^. reqFuncName)+        fname = namespace <> (toValidFunctionName (functionNameBuilder opts $ req ^. reqFuncName))          method = req ^. reqMethod         url = if url' == "'" then "'/'" else url'
src/Servant/JS/Axios.hs view
@@ -120,7 +120,7 @@                where                   hasNoModule = moduleName opts == "" -        fname = namespace <> (functionNameBuilder opts $ req ^. reqFuncName)+        fname = namespace <> (toValidFunctionName (functionNameBuilder opts $ req ^. reqFuncName))          method = T.toLower . decodeUtf8 $ req ^. reqMethod         url = if url' == "'" then "'/'" else url'
src/Servant/JS/Internal.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ViewPatterns #-}  module Servant.JS.Internal   ( JavaScriptGenerator@@ -116,25 +115,30 @@       setFirstChar x `T.cons` T.filter remainder xs     Nothing -> "_"   where-    setFirstChar c = if firstChar c then c else '_'-    firstChar c = prefixOK c || Set.member c firstLetterOK-    remainder c = prefixOK c || Set.member c remainderOK-    prefixOK c = c `elem` ['$','_']-    firstLetterOK = mconcat-                      [ Set.lowercaseLetter+    setFirstChar c = if Set.member c firstLetterOK then c else '_'+    remainder c = Set.member c remainderOK+    firstLetterOK = (filterBmpChars $ mconcat+                      [ Set.fromDistinctAscList "$_"+                      , Set.lowercaseLetter                       , Set.uppercaseLetter                       , Set.titlecaseLetter                       , Set.modifierLetter                       , Set.otherLetter                       , Set.letterNumber-                      ]+                      ])     remainderOK   = firstLetterOK-               <> mconcat+               <> (filterBmpChars $ mconcat                     [ Set.nonSpacingMark                     , Set.spacingCombiningMark                     , Set.decimalNumber                     , Set.connectorPunctuation-                    ]+                    ])++-- Javascript identifiers can only contain codepoints in the Basic Multilingual Plane+-- that is, codepoints that can be encoded in UTF-16 without a surrogate pair (UCS-2)+-- that is, codepoints that can fit in 16-bits, up to 0xffff (65535)+filterBmpChars :: Set.CharSet -> Set.CharSet+filterBmpChars = Set.filter (< '\65536')  toJSHeader :: HeaderArg f -> Text toJSHeader (HeaderArg n)
src/Servant/JS/JQuery.hs view
@@ -86,7 +86,7 @@         namespace = if (moduleName opts) == ""                        then "var "                        else (moduleName opts) <> "."-        fname = namespace <> (functionNameBuilder opts $ req ^. reqFuncName)+        fname = namespace <> (toValidFunctionName (functionNameBuilder opts $ req ^. reqFuncName))          method = req ^. reqMethod         url = if url' == "'" then "'/'" else url'
src/Servant/JS/Vanilla.hs view
@@ -97,7 +97,7 @@         namespace = if moduleName opts == ""                        then "var "                        else (moduleName opts) <> "."-        fname = namespace <> (functionNameBuilder opts $ req ^. reqFuncName)+        fname = namespace <> (toValidFunctionName (functionNameBuilder opts $ req ^. reqFuncName))          method = req ^. reqMethod         url = if url' == "'" then "'/'" else url'
test/Servant/JSSpec.hs view
@@ -15,10 +15,14 @@ import           Data.Proxy import           Data.Text                    (Text) import qualified Data.Text                    as T+import           Language.ECMAScript3.Lexer   (identifier) import           Language.ECMAScript3.Parser  (program, parse) import           Prelude                      () import           Prelude.Compat import           Test.Hspec  hiding (shouldContain, shouldNotContain)+import           Test.QuickCheck              (Arbitrary (..),+                                               choose, listOf,+                                               property)  import           Servant.API.Internal.Test.ComprehensiveAPI import           Servant.API.ContentTypes@@ -97,6 +101,7 @@     angularSpec    Angular     axiosSpec     --angularSpec    AngularCustom+    internalSpec  shouldContain :: Text -> Text -> Expectation a `shouldContain` b  = shouldSatisfy a (T.isInfixOf b)@@ -151,6 +156,24 @@         testName = "MyService"         ngOpts = NG.defAngularOptions { NG.serviceName = testName }         genJS req = NG.angularService ngOpts req++newtype ASCII = ASCII {getASCII :: T.Text} deriving (Show)++instance Arbitrary ASCII where+    -- Our arbitrary instance is generating only ASCII, since the language-ecmascript's lexer+    -- is currently (October 2016) still a bit naïve+    arbitrary = fmap (ASCII . T.pack) $ listOf $ choose (minBound, '\127')+    shrink xs = (ASCII . T.pack) <$> shrink (T.unpack $ getASCII xs)++internalSpec :: Spec+internalSpec = describe "Internal" $ do+    it "should generate only valid javascript identifiers for any ASCII route" $ do+        let parseIdentifier = fmap T.pack. parse identifier ""+        property $ \x -> let valid = toValidFunctionName $ getASCII x in+                         Right valid == parseIdentifier valid++    it "should generate a valid javascript identifier when supplied with hyphens, unicode whitespace, non-bmp unicode" $ do+        toValidFunctionName "a_--a\66352b\6158c\65075" `shouldBe` "a_abc\65075"  generateJSSpec :: TestNames -> (AjaxReq -> Text) -> Spec generateJSSpec n gen = describe specLabel $ do