commit d2efb6f0f97d2b7810881c6d75dfc258b649618e Author: icyrockcom Date: Mon Jan 15 23:35:48 2018 -0500 Initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..20e090a --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +/bower_components/ +/node_modules/ +/.pulp-cache/ +/output/ +/generated-docs/ +/.psc-package/ +/.psc* +/.purs* +/.psa* diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..294ac3f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: node_js +node_js: + - "stable" +sudo: false +install: + - npm install -g purescript pulp psc-package + - npm install + - psc-package update +after_success: + - >- + test $TRAVIS_TAG && + echo $GITHUB_TOKEN | pulp login && + echo y | pulp publish --no-push + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b7d4bd3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright 2018. icyrock.com + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..90c97cb --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +[![Build Status](https://travis-ci.org/icyrockcom/purescript-cheerio.svg?branch=master)](https://travis-ci.org/icyrockcom/purescript-cheerio) + +## Description + +Basic bindings for [cheerio](https://cheerio.js.org/). Only includes read-only functionality for now. + +## Installation + +Install [cheerio](https://www.npmjs.com/package/cheerio) dependency: + + $ npm install --save cheerio + +Install this package: + +* Using [bower](https://github.com/purescript/psc-package): + + $ bower install --save purescript-cheerio + +* Using [psc-package](https://github.com/purescript/psc-package): + + $ psc-package install cheerio + + You might need to set up a [custom package set](https://github.com/purescript/psc-package#add-a-package-to-the-package-set). + +## Example + +From [basic example](examples/Basic.purs). + +Imports: + + import Cheerio (Cheerio, find, length) + import Cheerio.Static (loadRoot) + +Example html: + + htmlEx :: String + htmlEx = """ + + """ + +Load it and get the root element: + + root :: Cheerio + root = loadRoot htmlEx + +Use the query functions: + + let fruitCount = find "#fruits" root # length + in log $ "Number of fruits: " <> show fruitCount + +For more examples, please take a look at the [unit tests](test/Test/Main.purs). They cover most of the read-only cheerio functions. + +## Issues or suggestions + +If you run into any issues or have suggestions, please open an issue or submit a pull request. Both are welcome! + +Be prepared to wait more than a couple of days for a response though :) + +## License + +MIT diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..2ece432 --- /dev/null +++ b/bower.json @@ -0,0 +1,29 @@ +{ + "name": "purescript-cheerio", + "description": "PureScript bindings for Cheerio", + "main": "index.js", + "authors": [ + "icyrock.com@icyrock.com" + ], + "license": "MIT", + "homepage": "https://github.com/icyrockcom/purescript-cheerio", + "repository": { + "type": "git", + "url": "https://github.com/icyrockcom/purescript-cheerio.git" + }, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "purescript-functions": "^3.0.0", + "purescript-test-unit": "^13.0.0", + "purescript-psci-support": "^3.0.0", + "purescript-console": "^3.0.0", + "purescript-eff": "^3.1.0", + "purescript-prelude": "^3.1.1" + } +} diff --git a/examples/Basic.purs b/examples/Basic.purs new file mode 100644 index 0000000..585b569 --- /dev/null +++ b/examples/Basic.purs @@ -0,0 +1,25 @@ +module Basic where + +import Prelude + +import Cheerio (Cheerio, find, length) +import Cheerio.Static (loadRoot) +import Control.Monad.Eff (Eff) +import Control.Monad.Eff.Console (CONSOLE, log) + +htmlEx :: String +htmlEx = """ + +""" + +root :: Cheerio +root = loadRoot htmlEx + +example :: forall eff. Eff (console :: CONSOLE | eff) Unit +example = + let fruitCount = find "#fruits" root # length + in log $ "Number of fruits: " <> show fruitCount diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..18e5f92 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,176 @@ +{ + "name": "purescript-cheerio", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/node": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.3.0.tgz", + "integrity": "sha512-wNBfvNjzsJl4tswIZKXCFQY0lss9nKUyJnG6T94X/eqjRgI2jHZ4evdjhQYBSan/vGtF6XVXPApOmNH2rf0KKw==" + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "cheerio": { + "version": "1.0.0-rc.2", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz", + "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=", + "requires": { + "css-select": "1.2.0", + "dom-serializer": "0.1.0", + "entities": "1.1.1", + "htmlparser2": "3.9.2", + "lodash": "4.17.4", + "parse5": "3.0.3" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "1.0.0", + "css-what": "2.1.0", + "domutils": "1.5.1", + "nth-check": "1.0.1" + } + }, + "css-what": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", + "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=" + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "requires": { + "domelementtype": "1.1.3", + "entities": "1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" + } + } + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" + }, + "domhandler": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", + "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", + "requires": { + "domelementtype": "1.3.0" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" + } + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" + }, + "htmlparser2": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", + "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.4.1", + "domutils": "1.5.1", + "entities": "1.1.1", + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "nth-check": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", + "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", + "requires": { + "boolbase": "1.0.0" + } + }, + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "requires": { + "@types/node": "9.3.0" + } + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..83cb2a7 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "purescript-cheerio", + "version": "0.1.0", + "description": "PureScript bindings for Cheerio", + "main": "index.js", + "directories": { + "test": "test" + }, + "scripts": { + "test": "pulp test" + }, + "repository": { + "type": "git", + "url": "https://github.com/icyrockcom/purescript-cheerio.git" + }, + "author": "icyrock.com", + "license": "MIT", + "bugs": { + "url": "https://github.com/icyrockcom/purescript-cheerio/issues" + }, + "homepage": "https://github.com/icyrockcom/purescript-cheerio#readme", + "dependencies": { + "cheerio": "^1.0.0-rc.2" + } +} diff --git a/psc-package.json b/psc-package.json new file mode 100644 index 0000000..d4d6c43 --- /dev/null +++ b/psc-package.json @@ -0,0 +1,13 @@ +{ + "name": "purescript-cheerio", + "set": "psc-0.11.7", + "source": "https://github.com/purescript/package-sets.git", + "depends": [ + "functions", + "test-unit", + "psci-support", + "console", + "eff", + "prelude" + ] +} \ No newline at end of file diff --git a/src/Cheerio.js b/src/Cheerio.js new file mode 100644 index 0000000..eaec570 --- /dev/null +++ b/src/Cheerio.js @@ -0,0 +1,62 @@ +const cheerio = require('cheerio') + +// Attributes +exports.attrImpl = function(name, cheerioInst) { + return cheerioInst.attr(name); +} + +exports.hasClassImpl = function(className, cheerioInst) { + return cheerioInst.hasClass(className); +} + +// Traversing +exports.findImpl = function(selector, cheerioInst) { + return cheerioInst.find(selector); +} + +exports.parent = function(cheerioInst) { + return cheerioInst.parent() +} + +exports.next = function(cheerioInst) { + return cheerioInst.next() +} + +exports.prev = function(cheerioInst) { + return cheerioInst.prev() +} + +exports.siblings = function(cheerioInst) { + return cheerioInst.siblings() +} + +exports.children = function(cheerioInst) { + return cheerioInst.children() +} + +exports.first = function(cheerioInst) { + return cheerioInst.first() +} + +exports.last = function(cheerioInst) { + return cheerioInst.last() +} + +exports.eqImpl = function(index, cheerioInst) { + return cheerioInst.eq(index) +} + +// Rendering +exports.htmlImpl = function(nothing, just, cheerioInst) { + const ret = cheerioInst.html() + return ret != null ? just(ret) : nothing +} + +exports.text = function(cheerioInst) { + return cheerioInst.text() +} + +// Miscellaneous +exports.length = function(cheerioInst) { + return cheerioInst.length; +} \ No newline at end of file diff --git a/src/Cheerio.purs b/src/Cheerio.purs new file mode 100644 index 0000000..95728f3 --- /dev/null +++ b/src/Cheerio.purs @@ -0,0 +1,48 @@ +module Cheerio where + +import Data.Function.Uncurried (Fn2, Fn3, runFn2, runFn3) +import Data.Maybe (Maybe(..)) + +foreign import data Cheerio :: Type + +-- Attributes +foreign import attrImpl :: Fn2 String Cheerio String + +attr :: String -> Cheerio -> String +attr = runFn2 attrImpl + +foreign import hasClassImpl :: Fn2 String Cheerio Boolean + +hasClass :: String -> Cheerio -> Boolean +hasClass = runFn2 hasClassImpl + +-- Traversing +foreign import findImpl :: Fn2 String Cheerio Cheerio + +find :: String -> Cheerio -> Cheerio +find = runFn2 findImpl + +foreign import parent :: Cheerio -> Cheerio +foreign import next :: Cheerio -> Cheerio +foreign import prev :: Cheerio -> Cheerio +foreign import siblings :: Cheerio -> Cheerio +foreign import children :: Cheerio -> Cheerio +foreign import first :: Cheerio -> Cheerio +foreign import last :: Cheerio -> Cheerio + +foreign import eqImpl :: Fn2 Int Cheerio Cheerio + +eq :: Int -> Cheerio -> Cheerio +eq = runFn2 eqImpl + +-- Rendering +foreign import htmlImpl :: forall a. + Fn3 (Maybe a) (a -> Maybe a) Cheerio (Maybe String) + +html :: Cheerio -> Maybe String +html = runFn3 htmlImpl Nothing Just + +foreign import text :: Cheerio -> String + +-- Miscellaneous +foreign import length :: Cheerio -> Int \ No newline at end of file diff --git a/src/Cheerio/Static.js b/src/Cheerio/Static.js new file mode 100644 index 0000000..bd14c73 --- /dev/null +++ b/src/Cheerio/Static.js @@ -0,0 +1,24 @@ +const cheerio = require('cheerio') + +// Loading +exports.load = cheerio.load + +// Selecting +exports.selectImpl = function(str, cheerioStatic) { + return cheerioStatic(str) +} + +exports.selectDeepImpl = function(strArr, cheerioStatic) { + return cheerioStatic.apply(cheerioStatic, strArr) +} + +// Rendering +exports.htmlImpl = function(nothing, just, cheerioInst) { + const ret = cheerio.html(cheerioInst) + return ret != null ? just(ret) : nothing +} + +// Utilities +exports.root = function(cheerioStatic) { + return cheerio.root.call(cheerioStatic) +} \ No newline at end of file diff --git a/src/Cheerio/Static.purs b/src/Cheerio/Static.purs new file mode 100644 index 0000000..d82ea6c --- /dev/null +++ b/src/Cheerio/Static.purs @@ -0,0 +1,36 @@ +module Cheerio.Static where + +import Prelude +import Cheerio (Cheerio) +import Data.Function.Uncurried (Fn2, Fn3, runFn2, runFn3) +import Data.Maybe (Maybe(..)) + +foreign import data CheerioStatic :: Type + +-- Loading +foreign import load :: String -> CheerioStatic + +-- Selectors +foreign import selectImpl :: Fn2 String CheerioStatic Cheerio + +select :: String -> CheerioStatic -> Cheerio +select = runFn2 selectImpl + +foreign import selectDeepImpl :: Fn2 (Array String) CheerioStatic Cheerio + +selectDeep :: Array String -> CheerioStatic -> Cheerio +selectDeep = runFn2 selectDeepImpl + +-- Rendering +foreign import htmlImpl :: forall a. + Fn3 (Maybe a) (a -> Maybe a) Cheerio (Maybe String) + +html :: Cheerio -> Maybe String +html = runFn3 htmlImpl Nothing Just + +-- Utilities +foreign import root :: CheerioStatic -> Cheerio + +-- Convenience +loadRoot :: String -> Cheerio +loadRoot = load >>> root diff --git a/test/Test/Cheerio.purs b/test/Test/Cheerio.purs new file mode 100644 index 0000000..1f28756 --- /dev/null +++ b/test/Test/Cheerio.purs @@ -0,0 +1,131 @@ +module Test.Cheerio where + +import Prelude hiding (eq) + +import Control.Monad.Eff (Eff) +import Control.Monad.Eff.AVar (AVAR) +import Control.Monad.Eff.Console (CONSOLE) +import Data.Maybe (Maybe(..)) +import Test.Unit (TestSuite, suite, test) +import Test.Unit.Assert as Assert +import Test.Unit.Console (TESTOUTPUT) +import Test.Unit.Main (runTest) + +import Cheerio + ( attr + , children + , eq + , find + , first + , hasClass + , html + , last + , length + , next + , parent + , prev + , siblings + , text + ) + +import Cheerio.Static (loadRoot) + +import Test.HtmlEx (htmlEx) + +main :: Eff (avar :: AVAR, console :: CONSOLE, testOutput :: TESTOUTPUT) Unit +main = runTest suites + +suites :: forall eff. TestSuite eff +suites = do + suite "Attributes" do + test "attr" do + Assert.equal + "fruits" + (loadRoot htmlEx # find "ul" # attr "id") + + test "hasClass" do + Assert.equal + true + (loadRoot htmlEx # find ".pear" # hasClass "pear") + + Assert.equal + false + (loadRoot htmlEx # find "apple" # hasClass "fruit") + + Assert.equal + true + (loadRoot htmlEx # find "li" # hasClass "pear") + + suite "Traversing" do + test "find" do + Assert.equal + 3 + (loadRoot htmlEx # find "#fruits" # find "li" # length) + + test "parent" do + Assert.equal + "fruits" + (loadRoot htmlEx # find ".pear" # parent # attr "id") + + test "next" do + Assert.equal + true + (loadRoot htmlEx # find ".apple" # next # hasClass "orange") + + test "prev" do + Assert.equal + true + (loadRoot htmlEx # find ".orange" # prev # hasClass "apple") + + test "siblings" do + Assert.equal + 2 + (loadRoot htmlEx # find ".pear" # siblings # length) + + test "children" do + Assert.equal + 3 + (loadRoot htmlEx # find "#fruits" # children # length) + + test "first" do + Assert.equal + "Apple" + (loadRoot htmlEx # find "#fruits" # children # first # text) + + test "last" do + Assert.equal + "Pear" + (loadRoot htmlEx # find "#fruits" # children # last # text) + + test "eq" do + Assert.equal + "Apple" + (loadRoot htmlEx # find "li" # eq 0 # text) + + Assert.equal + "Pear" + (loadRoot htmlEx # find "li" # eq (-1) # text) + + suite "Rendering" do + test "html" do + Assert.equal + (Just "Apple") + (loadRoot htmlEx # find ".apple" # html) + + test "text" do + Assert.equal + "Apple" + (loadRoot htmlEx # find ".apple" # text) + + suite "More" do + test "Long chain" do + Assert.equal + "Apple" + ( loadRoot htmlEx + # find ".apple" + # siblings + # eq 1 + # parent + # children + # first + # text) diff --git a/test/Test/Cheerio/Static.purs b/test/Test/Cheerio/Static.purs new file mode 100644 index 0000000..955cd92 --- /dev/null +++ b/test/Test/Cheerio/Static.purs @@ -0,0 +1,53 @@ +module Test.Cheerio.Static where + +import Prelude hiding (eq) + +import Control.Monad.Eff (Eff) +import Control.Monad.Eff.AVar (AVAR) +import Control.Monad.Eff.Console (CONSOLE) +import Data.Maybe (Maybe(..)) +import Test.Unit (TestSuite, suite, test) +import Test.Unit.Assert as Assert +import Test.Unit.Console (TESTOUTPUT) +import Test.Unit.Main (runTest) + +import Cheerio (attr, find, length, text) + +import Cheerio.Static + ( load + , select + , selectDeep + , html + , root + , loadRoot + ) + +import Test.HtmlEx (htmlEx) + +main :: Eff (avar :: AVAR, console :: CONSOLE, testOutput :: TESTOUTPUT) Unit +main = runTest suites + +suites :: forall eff. TestSuite eff +suites = do + suite "Loading" do + test "load" do + Assert.equal + 1 + (load htmlEx # root # find "#fruits" # length) + + suite "Selectors" do + test "select" do + Assert.equal + "pear" + (load htmlEx # select "ul .pear" # attr "class") + + test "selectDeep" do + Assert.equal + "Apple" + (load htmlEx # selectDeep [".apple", "#fruits"] # text) + + suite "Rendering" do + test "html" do + Assert.equal + (Just """
  • Apple
  • """) + (loadRoot htmlEx # find ".apple" # html) \ No newline at end of file diff --git a/test/Test/HtmlEx.purs b/test/Test/HtmlEx.purs new file mode 100644 index 0000000..d239233 --- /dev/null +++ b/test/Test/HtmlEx.purs @@ -0,0 +1,10 @@ +module Test.HtmlEx where + +htmlEx :: String +htmlEx = """ + +""" \ No newline at end of file diff --git a/test/Test/Main.purs b/test/Test/Main.purs new file mode 100644 index 0000000..15732b4 --- /dev/null +++ b/test/Test/Main.purs @@ -0,0 +1,21 @@ +module Test.Main where + +import Prelude hiding (eq) + +import Control.Monad.Eff (Eff) +import Control.Monad.Eff.AVar (AVAR) +import Control.Monad.Eff.Console (CONSOLE) +import Test.Unit (TestSuite) +import Test.Unit.Console (TESTOUTPUT) +import Test.Unit.Main (runTest) + +import Test.Cheerio as C +import Test.Cheerio.Static as CS + +main :: Eff (avar :: AVAR, console :: CONSOLE, testOutput :: TESTOUTPUT) Unit +main = runTest suites + +suites :: forall eff. TestSuite eff +suites = do + C.suites + CS.suites \ No newline at end of file