Giter VIP home page Giter VIP logo

mustache's Introduction

mustache Travis Status Hackage Join the chat at https://gitter.im/JustusAdam/mustache

Haskell implementation of mustache templates.

Implements the official specs version 1.1.3

Motivation

The old Haskell implementation of mustache templates hastache seemed pretty abandoned to me. This implementation aims to be much easier to use and (fingers crossed) better maintained.

Since it is so easy to use and requires but a few files of code, I've also written a small executable that compiles and renders mustache templates with data input from json or yaml files.

Usage

Library

Please refer to the documentation on hackage.

Executable haskell-mustache

$ haskell-mustache --help
Simple mustache template substitution

arguments [OPTIONS] TEMPLATE [DATA-FILES]

Common flags:
  -t --templatedirs[=DIRECTORY]  The directory in which to search for the
                                 templates
  -? --help                      Display help message
  -V --version                   Print version information

Current implementation substitutes the TEMPLATE once with each DATA-FILE

Example

$ haskell-mustache my-template-file data-file-1.json data-file-2.json data-file-3.json

Roadmap

  • String parser for mustache templates
  • Template substitution
  • Standalone executable
  • Support for 'set delimiter'
  • More efficiency using Text rather than String
  • More efficient Text parsing
  • Test coverage provided via the official specs
  • Haddock documentation
  • More instances for ToMustache typeclass

mustache's People

Contributors

andrewthad avatar awjchen avatar beerendlauwers avatar berberman avatar chrispenner avatar flip111 avatar gitter-badger avatar jchia avatar justusadam avatar peterbecich avatar potomak avatar sternenseemann avatar tfausak avatar theinnerlight avatar tmcgilchrist avatar tom-bop avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

mustache's Issues

Behavior of nested collections

Here is an example of a template I have:

{{#models}}
data {{model_name.title}}' = {{model_name.title}}' {
  {{#fields}}
    {{model_name.title}} {{field_name.title}}
  {{/fields}}
  }   
{{/models}}

This template is intended to generate part of a haskell data declaration. Here is the result:

data Car' = Car' {
     Speed
     Legal
  }
data Person' = Person' {
     Name
     Age
     Height
  }

I expected to see this:

data Car' = Car' {
     Car Speed
     Car Legal
  }
data Person' = Person' {
     Person Name
     Person Age
     Person Height
  }

The problem is that the fields made available by iterating over models seem to not be in scope in the fields subcollection. I haven't read the mustache spec, so I don't know if this behavior is intended.

Lists not properly rendered

I saw that @JustusAdam 's solution to #23 is almost identical to my code, but mine doesn't seem to work.

template:

= My Notes =

{{ #notes }}
* {{ path }}
{{ /notes }}

I'm substituting the values as follows:

generateIndexContent :: Template -> [FilePath] -> Text
generateIndexContent t notes =
    substituteValue t (object [ "notes" ~> map mk notes ])
    where mk n = object [ "path" ~> n ]

The output I get from this is:

= My Notes =


* 

and if I try adding {{ notes }} just to see what it thinks this is, I get something like:

[fromList [("path","cool note 2.wiki")],fromList [("path","cool note 1.wiki")]]

Proposal: Integral a => ToMustache a

instance Integral a => ToMustache a where
  toMustache = Number . fromIntegral

This replaces the existing instances for Int and Integer and generalizes to other integral types like Word16.

Currently when putting a Word16 into a Value it can't be done directly and something like toMustache . toInteger is needed.

With this change, toMustache can be applied directly to a Word16 value.

Doesn't compile with stack

I've put up a PR that fixes this. However, I'm unsure what the original purpose of the two lines I commented out was.

#4

Lazy Text for temporary structures

While parsing and substituting values it'd probably be more efficient to use lazy Text rather than strict Text to avoid unnecessary copying.

Proposal: Integral a => ToMustache a

instance Integral a => ToMustache a where
  toMustache = Number . fromIntegral

This replaces the existing instances for Int and Integer and generalizes to other integral types like Word16.

Currently when putting a Word16 into a Value with toMustache . fromIntegral, I need to disambiguate the fromIntegral and choose between Int and Integer for the output type of the fromIntegral which is the input type of the toMustache:

word16Mustache :: Word16 -> Value
word16Mustache = toMustache . fromIntegral @_ @Int

Using Lambdas

Hey there; I'm attempting to use lambdas in my templates, and as far as I can tell from the hackage docs they exist; but I'm not really sure how to use them.

Is there any way to rig up a simple (Value -> Text) function in as a lambda? or (Value -> Value)? I'm working with Aeson types mostly. I suppose to generalize it would be something like (ToMustache a, ToMustache b) => a -> b.

Mostly just wanting to run little functions like 'truncate' to cut off descriptions, etc.

Or if you could instruct me in how to use the existing lambdas that would be great! Thanks!

Report errors from substitute (such as missing variables)

I really enjoy using your mustache implementation :) I was wondering if you've considered (optional) reporting of "errors" that occur during substitution, such as missing variables referred to by the mustache template. For an application I'm working on that would be tremendously helpful.

I had a look at substituteValue and made a quick POC replacing its current signature substituteValue ∷ Template → Value → Text with substituteValue ∷ Template → Value → ([Error], Text). It was a bit clunky, but there might be more elegant ways of doing this. However, if error reporting is something you deliberately left out, and have no desire to include, I won't bother taking this any further :)

Test suite build failure

Looks like a missing extra-source-files:

> /tmp/stackage-build8/mustache-2.0$ runghc -clear-package-db -global-package-db -package-db=/var/stackage/work/builds/nightly/pkgdb Setup configure --enable-tests --package-db=clear --package-db=global --package-db=/var/stackage/work/builds/nightly/pkgdb --libdir=/var/stackage/work/builds/nightly/lib --bindir=/var/stackage/work/builds/nightly/bin --datadir=/var/stackage/work/builds/nightly/share --libexecdir=/var/stackage/work/builds/nightly/libexec --sysconfdir=/var/stackage/work/builds/nightly/etc --docdir=/var/stackage/work/builds/nightly/doc/mustache-2.0 --htmldir=/var/stackage/work/builds/nightly/doc/mustache-2.0 --haddockdir=/var/stackage/work/builds/nightly/doc/mustache-2.0 --flags=
Configuring mustache-2.0...
> /tmp/stackage-build8/mustache-2.0$ runghc -clear-package-db -global-package-db -package-db=/var/stackage/work/builds/nightly/pkgdb Setup build
Building mustache-2.0...
Preprocessing library mustache-2.0...
[1 of 6] Compiling Text.Mustache.Internal ( src/Text/Mustache/Internal.hs, dist/build/Text/Mustache/Internal.o )
[2 of 6] Compiling Text.Mustache.Types ( src/Text/Mustache/Types.hs, dist/build/Text/Mustache/Types.o )
[3 of 6] Compiling Text.Mustache.Parser ( src/Text/Mustache/Parser.hs, dist/build/Text/Mustache/Parser.o )
[4 of 6] Compiling Text.Mustache.Compile ( src/Text/Mustache/Compile.hs, dist/build/Text/Mustache/Compile.o )
[5 of 6] Compiling Text.Mustache.Render ( src/Text/Mustache/Render.hs, dist/build/Text/Mustache/Render.o )
[6 of 6] Compiling Text.Mustache    ( src/Text/Mustache.hs, dist/build/Text/Mustache.o )
Preprocessing executable 'haskell-mustache' for mustache-2.0...
[1 of 1] Compiling Main             ( app/Main.hs, dist/build/haskell-mustache/haskell-mustache-tmp/Main.o )
Linking dist/build/haskell-mustache/haskell-mustache ...
Preprocessing test suite 'unit-tests' for mustache-2.0...
[1 of 1] Compiling Main             ( test/unit/Spec.hs, dist/build/unit-tests/unit-tests-tmp/Main.o )

test/unit/Spec.hs:212:15: error:
    • Parse error in mustache template: "test-template.txt.mustache" (line 1, column 1):
Template file 'test-template.txt.mustache' not found
    • In the untyped splice:
        $(embedTemplate
            ["test/unit/examples"] "test-template.txt.mustache")

Rendering JSON value not being rendered as JSON encoded string

I've posted a question on stack overflow: http://stackoverflow.com/questions/42215023/mustache-rendering-not-rendering-json-value-as-json-encoded-string

Essentially:

{-# LANGUAGE OverloadedStrings #-}
module Test2 where

import Data.Aeson
import Text.Mustache

main :: IO ()
main = do
  let example = Data.Aeson.object [ "key" .= (5 :: Integer), "somethingElse" .= (2 :: Integer) ]
  print ("Start" :: String)
  case compileTemplate "" "{{{jsonData}}}" of
    Right x -> do
      print $ substituteValue x (Text.Mustache.object ["jsonData" ~= example])
    Left e -> error . show $ e

Is producing:

"{\"somethingElse\":2,\"key\":5}"
"Start"
"fromList [(\"somethingElse\",2.0),(\"key\",5.0)]"

Any ideas?

Instance of Exception for ParseError

There is a trivial instance of Exception (just using all the default method implementations) possible for ParseError. This would make it possible to throwIO a ParseError. Would a PR with this be accepted?

Array indexing doesn't work

It seems that this package does not allow array indexing. The following code just prints a blank line instead of printing a line with "2":

doTest :: IO ()
doTest = do
  let result = substitute [mustache|{{1}}|] ([0, 2] :: [Int])
  putStrLn result

This mismatches the official behavior at https://mustache.github.io/#demo.

Partial support for compile time compilation

  • It should be possible to use partials for the compile time compilation, at least in embedTemplate.

    I am imagining an API somewhat like this: (names subject to change)

    embedTemplate
        :: FilePath -- Search path for partials
        -> FilePath -- Template name
        -> Q Expr
  • If we provide an embedding function which does not allow partials it should trow errors for missing partials at compile time.
    The current API using compileTemplate will not throw any errors in this case and I think it should, but this is open for debate.

  • I'd also like to evaluate whether it is possible to do some global caching for compiled templates so that

    t1 = $(embedTemplate "template.mustache")
    
    t2 = $(embedTemplate "template.mustache")

    Only compiles the template once.

Keep unknown variables around during substitution

When a variable is missing in the Value, there’s essentially three options:

  1. Replace with "" and ignore
  2. Error out
  3. Keep the variable text verbatim in the output, e.g. {{variable}}.

1 and 2 are possible with this library, but 3 isn’t currently.

Why would one want 3? Basically if you have a big file in some other language, and you just want to replace one or two things in the whole file, you would like “accidental” variable syntax to be ignored. e.g. I have a document which has {{foo}} in the comments, and they get replaced silently.

This is just an idea, maybe the better solution here is to make 2 available from the command line util and then just fix accidental replacements as I notice them.

Character encoding not detected properly while reading template

I'm from Croatia, and we have characters like ČčĆ掞ĐđŠš

If I'm passing them through context, they render correctly, but if characters are present within mustache template file than they end up messed up.

I've tracked problem to your getFile function which uses readFile from Data.Text.IO. This is a problem, because readFile uses current system coding page, which can differ from encoding of a file that is being red.

I had to switch my os coding page with chcp from 852 to 65001 to make it work.

This could be fixed with setLocaleEncoding from GHC.IO package, but it's kind of hacky. Maybe add option to explicitly set encoding for our templates?

Error in $: Failed reading: satisfy

It produce an error in the first example here

template:

Hello {{name}}
You have just won {{value}} dollars!
{{#in_ca}}
Well, {{taxed_value}} dollars, after taxes.
{{/in_ca}}
data:
{
  "name": "Chris",
  "value": 10000,
  "taxed_value": 10000 - (10000 * 0.4),
  "in_ca": true
}

But if I changed the third line to "taxed_value": 6000,, it works.

Hello Chris
You have just won 10000 dollars!
Well, 6000 dollars, after taxes.

I don't know what happened. So I report it here.

Backwards compatible OverlappingInstances

The instances for ToMustache overlap to provide efficient conversions using the OVERLAPPABLE and OVERLAPPING pragmas from GHC 7.10.

Earlier versions of GHC do not support those pragmas and as a result do not compile, complaining about Overlapping Instances.

There are ways to provide the same flexibility in older GHC versions. this should be researched and added.

Support GHC 9.0 in a new Hackage release

With GHC 9.0, there is a TH-related compilation error:

/data/jchia/gh/mustache/src/Text/Mustache/Internal/Types.hs:384:29: error:
    • Could not deduce (Lift Template) arising from a use of ‘lift’
      from the context: Language.Haskell.TH.Syntax.Quote m
        bound by the type signature for:
                   lift :: forall (m :: * -> *).
                           Language.Haskell.TH.Syntax.Quote m =>
                           TemplateCache -> m Language.Haskell.TH.Syntax.Exp
        at src/Text/Mustache/Internal/Types.hs:384:3-6
    • In the first argument of ‘($)’, namely ‘lift’
      In the expression: lift $ HM.toList m
      In the expression:
        [| HM.fromList $(lift $ HM.toList m) |]
        pending(rn) [<splice, lift $ HM.toList m>]
    |
384 |   lift m = [| HM.fromList $(lift $ HM.toList m) |]
    |                             ^^^^

--  While building package mustache-2.3.2 (scroll up to its section to see the error) using:
      /home/jchia/.stack/setup-exe-cache/x86_64-linux-tinfo6/Cabal-simple_mPHDZzAJ_3.4.0.0_ghc-9.0.1 --builddir=.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.4.0.0 build lib:mustache exe:haskell-mustache --ghc-options " -fdiagnostics-color=always"
    Process exited with code: ExitFailure 1

Build error with aeson-2

When I build mustache-2.3.1 with aeson-2.0.1.0, I get the following error:

src/Text/Mustache/Internal/Types.hs:236:42: error:
    • Couldn't match type ‘Data.Aeson.KeyMap.KeyMap’
                     with ‘HM.HashMap Text’
      Expected type: Object
        Actual type: Data.Aeson.KeyMap.KeyMap Value
    • In the second argument of ‘($)’, namely ‘fmap toMustache o’
      In the expression: Object $ fmap toMustache o
      In an equation for ‘toMustache’:
          toMustache (Aeson.Object o) = Object $ fmap toMustache o
    |
236 |   toMustache (Aeson.Object o) = Object $ fmap toMustache o
    |                                          ^^^^^^^^^^^^^^^^^

The conversion package

This is just a suggestion, not really a feature request, so feel free to disagree, since it's your library and it's still a good implementation regardless.

I recommend removing the dependency on conversion and conversion-text as well as the functions that are built on top of the Conversion typeclass. It's a lawless MPTC without fundeps that uses orphan instances, and I believe that your library would be better off if it didn't use it.

Again, it's just my opinion, and I assume that you probably have some particular use for the ~~> and ~~= operators in applications that you've built. But, if you ever start feeling uneasy about the conversion package, know that there's someone else who feels the same and would like to see it go.

Inverted sections don't render with null values

In other mustache implementations, a value of null triggers an inverted section. However in this one, that is not that case.

This would work, I think, if the code was changed to:

-- substituting an inverted section
substituteNode (InvertedSection  Implicit _) = tellError InvertedImplicitSection
substituteNode (InvertedSection (NamedData secName) invSecSTree) =
  search secName >>= \case
    Just (Bool False) -> contents
    Just Null -> contents                                            -- <<< new case
    Just (Array a)    | V.null a -> contents
    Nothing           -> contents
    _                 -> return ()
  where
    contents = mapM_ substituteNode invSecSTree

However, to my surprise, it seems that the standard (https://mustache.github.io/mustache.5.html) does not specify this:

While sections can be used to render text one or more times based on the value of the key, inverted sections may render text once based on the inverse value of the key. That is, they will be rendered if the key doesn't exist, is false, or is an empty list.

Can't render 2nd level partials with automatic compile.

I have main.mustache that looks like this:

main.mustache

Hello from {{>partial01.mustache}}

partial01.mustache

Partial 01 and {{>partial02.mustache}}

partial02.mustache

Partial 02

I'm expecting to see : Hello from Partial 01 and Partial 02 but I just get Hello from Partial 01 and when I run following :

test :: IO Text
test = do
    template <- automaticCompile templateSearchPath "main.mustache"
    return $ renderTemplate template $ object

Does automatic compile does only includes for main template? If so, how can I get around that?

Parsing with attoparsec

There is an experimental branch which uses attoparsec instead of parsec.

It type checks but does not succeed the tests yet.

It'd be nice to fix it and then compare it to the parsec parser.

`Lift Text` instance is now available in Data.Text causing compilation failure

mustache fails to compile against Data.Text 1.2.4.0 because this latest release (uploaded August 10, 2019) includes its own Lift Text instance.

The compilation error is:

[3 of 8] Compiling Text.Mustache.Internal.Types ( src/Text/Mustache/Internal/Types.hs, dist/build/Text/Mustache/Internal/Types.o )

src/Text/Mustache/Internal/Types.hs:350:10: error:
    Duplicate instance declarations:
      instance Lift Text
        -- Defined at src/Text/Mustache/Internal/Types.hs:350:10
      instance Lift Text -- Defined in ‘Data.Text’
    |
350 | instance Lift Text where
    |          ^^^^^^^^^

mustache should probably remove this instance and add a version dependency on this specific version of Data.Text.

Unexpected html entities in substitutions

Thanks for the library. I'm using the it to perform substitutions on json files, and the results are unexpected. This code:

import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Text.Mustache as TM
import qualified Data.Aeson as JS
import Data.Aeson((.=))

main :: IO ()
main = do
  let (Right template) = TM.compileTemplate "" "{\"field\":\"{{param}}\"}"
      ctx = JS.object ["param" .= ("abc&def"::T.Text)]
  T.putStrLn (TM.substitute template ctx)

produces this output:

{"field":"abc&amp;def"}

Why the &amp; entity in lieu of the '&' from the source string? Is there a a way to avoid this behaviour?

mustache-2.4.0 failed to build in Stackage Nightly

/var/stackage/work/unpack-dir/unpacked/mustache-2.4.0-44c4d43ecfe1fee11fb03ffd49b0580ed00eec5144067092801ef4256df77ef8/src/Text/Mustache/Internal/Types.hs:395:1: error:
    • Overlapping instances for Lift TemplateCache
        arising from a use of ‘lift’
      Matching instances:
        two instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the second argument of ‘Language.Haskell.TH.Lib.Internal.appE’, namely
        ‘(lift x2_aclX)’
      In the expression:
        (Language.Haskell.TH.Lib.Internal.appE
           ((Language.Haskell.TH.Lib.Internal.appE
               ((Language.Haskell.TH.Lib.Internal.appE
                   (Language.Haskell.TH.Lib.Internal.conE
                      ((Name (mkOccName "Template"))
                         (((NameG DataName)
                             (mkPkgName "mustache-2.4.0-7gu0iJzW3shKWbIZjtf98g"))
                            (mkModName "Text.Mustache.Internal.Types")))))
                  (lift x0_aclV)))
              (lift x1_aclW)))
          (lift x2_aclX)
      In a case alternative:
          Template x0_aclV x1_aclW x2_aclX
            -> (Language.Haskell.TH.Lib.Internal.appE
                  ((Language.Haskell.TH.Lib.Internal.appE
                      ((Language.Haskell.TH.Lib.Internal.appE
                          (Language.Haskell.TH.Lib.Internal.conE
                             ((Name (mkOccName "Template"))
                                (((NameG DataName)
                                    (mkPkgName "mustache-2.4.0-7gu0iJzW3shKWbIZjtf98g"))
                                   (mkModName "Text.Mustache.Internal.Types")))))
                         (lift x0_aclV)))
                     (lift x1_aclW)))
                 (lift x2_aclX)
    |
395 | deriveLift ''Template
    | ^^^^^^^^^^^^^^^^^^^^^

/var/stackage/work/unpack-dir/unpacked/mustache-2.4.0-44c4d43ecfe1fee11fb03ffd49b0580ed00eec5144067092801ef4256df77ef8/src/Text/Mustache/Internal/Types.hs:397:10: error:
    • Overlapping instances for Lift TemplateCache
        arising from a use of ‘Language.Haskell.TH.Syntax.$dmlift’
      Matching instances:
        two instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the expression:
        Language.Haskell.TH.Syntax.$dmlift
          @('ghc-prim-0.7.0:GHC.Types.LiftedRep) @(TemplateCache)
      In an equation for ‘lift’:
          lift
            = Language.Haskell.TH.Syntax.$dmlift
                @('ghc-prim-0.7.0:GHC.Types.LiftedRep) @(TemplateCache)
      In the instance declaration for ‘Lift TemplateCache’
    |
397 | instance Lift TemplateCache where
    |          ^^^^^^^^^^^^^^^^^^

Making lambdas more like the mustache spec

The mustache spec gives this example:

Template:

{{#wrapped}}
  {{name}} is awesome.
{{/wrapped}}

Hash:

{
  "name": "Willy",
  "wrapped": function() {
    return function(text, render) {
      return "<b>" + render(text) + "</b>"
    }
  }
}
Output:

<b>Willy is awesome.</b>

Issue #30 talked about making lambdas easy to use for simple text transformations, but it's still pretty difficult to do anything more complicated. I'm thinking it would be nice if the Haskell API could align more with the API in the mustache spec, something like

instance ToMustache (Text -> (Text -> SubM Text) -> SubM Text)

The mustache example could then be implemented as

object
  [ "wrapped" ~> \text render -> do
      result <- render text
      return $ "<b>" <> result <> "</b>"
  ]

where the first argument is the raw template text.

Thoughts?

`MustacheConf` constructor not exported

Hi,

in version 1.0.1, Text.Mustache.Parser exports parseWithConf, which takes a MustacheConf as input to customise the delimiters. However, only the default configuration can ever be constructed because the MustacheConf constructor (or, equivalently, a setter for its delimiters field) is not exported, rendering the function useless.

There's a similar problem with MustacheState, although in that case I see no immediate use for exporting the Parser type in the first place.

Cheers,
Jannis

Why is `mustache` excluded from lts-19.5 (GHC 9.0.2)?

I noticed that mustache is included in lts-18.28 (GHC 8.10.7), was included in some of the GHC 9.0.2 nightly series (until 2022-03-03), is included in the current GHC 9.2.2 nightly series, but is excluded from the lts-19.0 to lts-19.5 series (also GHC 9.0.2).

I wondered why mustache is blocked from lts-19.5, if this is something that could be resolved, and if I could help (if it can).

Arrays containing Pairs seems to not work

scripts.mustache:

{{#inlineJavascripts}}
<script>{{javascript}}</script>
{{/inlineJavascripts}}

Renderer.hs

    object [ "inlineJavascripts" ~> map (\x -> "javascript" ~> x) (["alert('Hello world');", "document.write('Gone!');"] :: [Text.Text]) ]

Result:

<script></script>
<script></script>

Own experiment is GHCI:

*> "name" ~> ("Alice" :: Text)
("name","Alice")
*> "people" ~> ["name" ~> ("Alice" :: Text), "name" ~> ("Bob" :: Text)]
("people",[["name","Alice"],["name","Bob"]])
*> toMustache $ "name" ~> ("Alice" :: Text)
["name","Alice"]

mustache-1.0.2 test suite failure on NixOS

It seems the test suite tries to execute curl?

running tests
Running 2 test suites...
Test suite unit-tests: RUNNING...
Test suite unit-tests: PASS
Test suite logged to: dist/test/mustache-1.0.2-unit-tests.log
Test suite language-specifications: RUNNING...
language-specifications: curl: callProcess: runInteractiveProcess: exec: does not exist (No such file or directory)
Test suite language-specifications: FAIL
Test suite logged to: dist/test/mustache-1.0.2-language-specifications.log
1 of 2 test suites (1 of 2 test cases) passed.

That won't wok because (a) curl hasn't been declared as a build-tool and thus isn't available in the build environment and (b) builds don't have network access anyway. How would I remedy this issue? Is there a way to run those tests without depending on the network?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.