Initial
This commit is contained in:
commit
d2efb6f0f9
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/bower_components/
|
||||
/node_modules/
|
||||
/.pulp-cache/
|
||||
/output/
|
||||
/generated-docs/
|
||||
/.psc-package/
|
||||
/.psc*
|
||||
/.purs*
|
||||
/.psa*
|
14
.travis.yml
Normal file
14
.travis.yml
Normal file
@ -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
|
||||
|
9
LICENSE
Normal file
9
LICENSE
Normal file
@ -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.
|
65
README.md
Normal file
65
README.md
Normal file
@ -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 = """
|
||||
<ul id="fruits">
|
||||
<li class="apple">Apple</li>
|
||||
<li class="orange">Orange</li>
|
||||
<li class="pear">Pear</li>
|
||||
</ul>
|
||||
"""
|
||||
|
||||
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
|
29
bower.json
Normal file
29
bower.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
25
examples/Basic.purs
Normal file
25
examples/Basic.purs
Normal file
@ -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 = """
|
||||
<ul id="fruits">
|
||||
<li class="apple">Apple</li>
|
||||
<li class="orange">Orange</li>
|
||||
<li class="pear">Pear</li>
|
||||
</ul>
|
||||
"""
|
||||
|
||||
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
|
176
package-lock.json
generated
Normal file
176
package-lock.json
generated
Normal file
@ -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="
|
||||
}
|
||||
}
|
||||
}
|
25
package.json
Normal file
25
package.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
13
psc-package.json
Normal file
13
psc-package.json
Normal file
@ -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"
|
||||
]
|
||||
}
|
62
src/Cheerio.js
Normal file
62
src/Cheerio.js
Normal file
@ -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;
|
||||
}
|
48
src/Cheerio.purs
Normal file
48
src/Cheerio.purs
Normal file
@ -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
|
24
src/Cheerio/Static.js
Normal file
24
src/Cheerio/Static.js
Normal file
@ -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)
|
||||
}
|
36
src/Cheerio/Static.purs
Normal file
36
src/Cheerio/Static.purs
Normal file
@ -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
|
131
test/Test/Cheerio.purs
Normal file
131
test/Test/Cheerio.purs
Normal file
@ -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)
|
53
test/Test/Cheerio/Static.purs
Normal file
53
test/Test/Cheerio/Static.purs
Normal file
@ -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 """<li class="apple">Apple</li>""")
|
||||
(loadRoot htmlEx # find ".apple" # html)
|
10
test/Test/HtmlEx.purs
Normal file
10
test/Test/HtmlEx.purs
Normal file
@ -0,0 +1,10 @@
|
||||
module Test.HtmlEx where
|
||||
|
||||
htmlEx :: String
|
||||
htmlEx = """
|
||||
<ul id="fruits">
|
||||
<li class="apple">Apple</li>
|
||||
<li class="orange">Orange</li>
|
||||
<li class="pear">Pear</li>
|
||||
</ul>
|
||||
"""
|
21
test/Test/Main.purs
Normal file
21
test/Test/Main.purs
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user