git.iko.soy/rowtype-yoga/purescript-docs-search
on master help sign in
Fix everything except toppoki tests
commit7ef455f041dea9b0fb870fd26dd129618249652d authorVladimir Kalnitsky <klntsky@gmail.com> dateSun 8 May 2022, 21:06 (4 years ago) parent66bffd8
25 files changed+526−353
package.json+2−1 packages.dhall+47−27 spago.dhall+1−2 src/Docs/Search/App.purs+5−5 src/Docs/Search/App/SearchField.purs+1−1 src/Docs/Search/App/SearchResults.purs+2−2 src/Docs/Search/App/Sidebar.purs+4−4 src/Docs/Search/BrowserEngine.js+1−1 src/Docs/Search/IndexBuilder.js+4−5 src/Docs/Search/IndexBuilder.purs+4−3 src/Docs/Search/Loader.js+1−1 src/Docs/Search/ModuleIndex.js+1−1 src/Docs/Search/ModuleIndex.purs+3−4 src/Docs/Search/TypeIndex.js+1−1 src/Docs/Search/TypeQuery.purs+3−3 src/Docs/Search/TypeShape.js+1−1 src/Docs/Search/URIHash.js+1−1 src/Docs/Search/URIHash.purs+2−2 test/Main.purs+6−4 test/Test/Declarations.purs+12−13 test/Test/Extra.purs+6−5 test/Test/IndexBuilder.purs+9−9 test/Test/ModuleIndex.purs+8−10 test/Test/TypeJson.purs+18−18 test/Test/TypeQuery.purs+383−229
package.json+2−1
@@ -1,5 +1,6 @@
11{
22 "name": "purescript-docs-search",
3+ "type": "module",
34 "version": "0.0.11",
45 "description": "Search frontend for the documentation generated by the PureScript compiler.",
56 "directories": {
@@ -19,7 +20,7 @@
1920 "bundle-app": "spago bundle-app --no-build --no-install -m Docs.Search.App --to dist/docs-search-app.js",
2021 "esbuild-app": "esbuild dist/docs-search-app.js --target=es2016 --bundle --minify --outfile=dist/docs-search-app.min.js && mv dist/docs-search-app.min.js dist/docs-search-app.js",
2122 "build-app": "npm run bundle-app && npm run esbuild-app",
22− "bundle-main": "spago bundle-app --no-build --no-install -m Docs.Search.Main --to dist/main.js",
23+ "bundle-main": "spago bundle-app --no-build --no-install --platform node -m Docs.Search.Main --to dist/main.js",
2324 "esbuild-main": "esbuild dist/main.js --platform=node --bundle --minify --outfile=dist/main.min.js && mv dist/main.min.js dist/main.js",
2425 "add-shebang": "echo \"#!/usr/bin/env node\" > dist/purescript-docs-search && cat dist/main.js >> dist/purescript-docs-search",
2526 "chmod-main": "chmod +x dist/purescript-docs-search",
packages.dhall+47−27
@@ -1,8 +1,10 @@
11let mkPackage =
2− https://raw.githubusercontent.com/purescript/package-sets/psc-0.13.2-20190725/src/mkPackage.dhall sha256:0b197efa1d397ace6eb46b243ff2d73a3da5638d8d0ac8473e8e4a8fc528cf57
2+ https://raw.githubusercontent.com/purescript/package-sets/psc-0.13.2-20190725/src/mkPackage.dhall
3+ sha256:0b197efa1d397ace6eb46b243ff2d73a3da5638d8d0ac8473e8e4a8fc528cf57
34
45let upstream =
5− https://github.com/purescript/package-sets/releases/download/psc-0.14.0-20210409/packages.dhall sha256:e81c2f2ce790c0e0d79869d22f7a37d16caeb5bd81cfda71d46c58f6199fd33f
6+ https://github.com/purescript/package-sets/releases/download/psc-0.15.0-20220506/packages.dhall
7+ sha256:f83b68ff07cf6557e82379e749118e6ff11eecc6be5754540aae855cd1e46917
68
79let overrides = {=}
810
@@ -33,12 +35,7 @@ let additions =
3335 , "web-uievents"
3436 ]
3537 "https://github.com/purescript-halogen/purescript-halogen.git"
36− "v6.1.0"
37− , halogen-css =
38− mkPackage
39− [ "halogen" ]
40− "https://github.com/slamdata/purescript-halogen-css.git"
41− "v8.0.0"
38+ "v7.0.0"
4239 , memoize =
4340 mkPackage
4441 [ "prelude"
@@ -67,8 +64,8 @@ let additions =
6764 , "free"
6865 , "memoize"
6966 ]
70− "https://github.com/srghma/purescript-optparse.git"
71− "d49b03fcd35f5be167e9c5c44ab1c17ca0956fb1"
67+ "https://github.com/klntsky/purescript-optparse.git"
68+ "2fe4265b7c6b09744c11190a43ca06777c752473"
7269 , exitcodes =
7370 mkPackage
7471 [ "enums" ]
@@ -77,30 +74,42 @@ let additions =
7774 , markdown-it =
7875 mkPackage
7976 [ "prelude", "effect", "options" ]
80− "https://github.com/nonbili/purescript-markdown-it.git"
81− "v0.4.0"
77+ "https://github.com/klntsky/purescript-markdown-it.git"
78+ "f3b7654783a83a80d7c09b6caaa7cd40b93ddce1"
79+ , string-parsers =
80+ mkPackage
81+ [ "arrays"
82+ , "assert"
83+ , "bifunctors"
84+ , "console"
85+ , "control"
86+ , "effect"
87+ , "either"
88+ , "enums"
89+ , "foldable-traversable"
90+ , "lists"
91+ , "maybe"
92+ , "minibench"
93+ , "nonempty"
94+ , "partial"
95+ , "prelude"
96+ , "strings"
97+ , "tailrec"
98+ , "transformers"
99+ , "unfoldable"
100+ ]
101+ "https://github.com/purescript-contrib/purescript-string-parsers.git"
102+ "v8.0.0"
82103 , html-parser-halogen =
83104 mkPackage
84105 [ "string-parsers", "halogen" ]
85− "https://github.com/rnons/purescript-html-parser-halogen.git"
86− "458e492e441fcf69a66911b7b64beea5849e0dad"
106+ "https://github.com/klntsky/purescript-html-parser-halogen.git"
107+ "5c31890d060d5abd0038fed6acd3f999a9362369"
87108 , markdown-it-halogen =
88109 mkPackage
89110 [ "markdown-it", "html-parser-halogen" ]
90111 "https://github.com/nonbili/purescript-markdown-it-halogen.git"
91112 "08c9625015bf04214be14e45230e8ce12f3fa2bf"
92− , toppokki =
93− mkPackage
94− [ "prelude"
95− , "record"
96− , "functions"
97− , "node-http"
98− , "aff-promise"
99− , "node-buffer"
100− , "node-fs-aff"
101− ]
102− "https://github.com/justinwoo/purescript-toppokki.git"
103− "v2.4.0"
104113 , search-trie =
105114 mkPackage
106115 [ "prelude"
@@ -126,7 +135,18 @@ let additions =
126135 , "transformers"
127136 ]
128137 "https://github.com/purescript-contrib/purescript-css.git"
129− "5c1a44ee95c259352a2b4570b060de14130540bc"
138+ "710d6a742beb88299faf08aaeb997ee1e24483ab"
139+ , jest =
140+ mkPackage
141+ [ "aff"
142+ , "aff-promise"
143+ , "effect"
144+ , "prelude"
145+ , "psci-support"
146+ , "foldable-traversable"
147+ ]
148+ "https://github.com/klntsky/purescript-jest.git"
149+ "7feaa5a880fc75002c4eca312993174e7220252b"
130150 }
131151
132152in upstream // overrides // additions
spago.dhall+1−2
@@ -39,10 +39,9 @@
3939 , "profunctor"
4040 , "profunctor-lenses"
4141 , "search-trie"
42+ , "spec"
4243 , "string-parsers"
4344 , "strings"
44− , "test-unit"
45− , "toppokki"
4645 , "transformers"
4746 , "tuples"
4847 , "unfoldable"
src/Docs/Search/App.purs+5−5
@@ -86,7 +86,7 @@ main = do
8686 srio <- runUI resultsComponent unit searchResults
8787
8888 void $ H.liftEffect $ subscribe sfio.messages $ \sfm -> do
89− launchAff_ do
89+ launchAff_ $ void do
9090 srio.query (SearchResults.MessageFromSearchField sfm unit)
9191
9292 -- We need to read the URI hash only when both components are initialized and
@@ -97,8 +97,8 @@ main = do
9797 H.liftEffect do
9898
9999 listener <-
100− eventListener \event ->
101− launchAff_ do
100+ eventListener \_event ->
101+ launchAff_ $ void do
102102 sfio.query $ SearchField.ReadURIHash unit
103103
104104 addEventListener hashchange listener true (Window.toEventTarget window)
@@ -111,8 +111,8 @@ main = do
111111 H.liftEffect do
112112
113113 listener <-
114− eventListener \event ->
115− launchAff_ do
114+ eventListener \_event ->
115+ launchAff_ $ void do
116116 sbio.query $ Sidebar.UpdateModuleGrouping unit
117117
118118 addEventListener focus listener true (Window.toEventTarget window)
src/Docs/Search/App/SearchField.purs+1−1
@@ -156,7 +156,7 @@ render state =
156156 [ HH.input
157157 [ HP.value state.input
158158 , HP.placeholder "Search for definitions... (S to focus)"
159− , HP.id_ "docs-search-query-field"
159+ , HP.id "docs-search-query-field"
160160 , HP.type_ HP.InputText
161161 , HE.onKeyUp (\event ->
162162 case KeyboardEvent.code event of
src/Docs/Search/App/SearchResults.purs+2−2
@@ -202,9 +202,9 @@ render state@{ mode: Active } =
202202 , HH.div_ $
203203 Array.concat $ shownResults <#> renderResult state
204204
205− , HH.div [ HP.class_ (wrap "load_more"), HP.id_ "load-more" ]
205+ , HH.div [ HP.class_ (wrap "load_more"), HP.id "load-more" ]
206206 [ if Array.length shownResults < Array.length state.results
207− then HH.a [ HP.id_ "load-more-link"
207+ then HH.a [ HP.id "load-more-link"
208208 , HE.onClick $ const MoreResultsRequested ]
209209 [ HH.text "Show more results" ]
210210 else HH.p_
src/Docs/Search/App/Sidebar.purs+4−4
@@ -17,7 +17,6 @@ import Data.Maybe (Maybe(..), isJust, fromMaybe)
1717import Data.Newtype (wrap, unwrap)
1818import Data.Set (Set)
1919import Data.Set as Set
20−import Data.Symbol (SProxy(..))
2120import Data.Tuple.Nested (type (/\), (/\))
2221import Effect (Effect)
2322import Effect.Aff (Aff)
@@ -25,6 +24,7 @@ import Halogen as H
2524import Halogen.HTML as HH
2625import Halogen.HTML.Events as HE
2726import Halogen.HTML.Properties as HP
27+import Type.Proxy (Proxy(..))
2828import Web.HTML as HTML
2929import Web.HTML.Window as Window
3030import Web.Storage.Storage as Storage
@@ -131,7 +131,7 @@ render state@{ groupingMode, moduleNames, localPackageName } =
131131 ]
132132
133133 [ HH.h3_ [ HH.text $ if groupingMode == DontGroup then "Modules" else "Packages" ]
134− , HH.input [ HP.id_ "group-modules__input"
134+ , HH.input [ HP.id "group-modules__input"
135135 , HP.type_ HP.InputCheckbox
136136 , HP.checked (groupingMode == GroupByPackage)
137137 , HE.onChecked $ ToggleGrouping <<< isCheckedToGroupingMode
@@ -139,7 +139,7 @@ render state@{ groupingMode, moduleNames, localPackageName } =
139139
140140 , HH.text " "
141141 , HH.label [ HP.for "group-modules__input"
142− , HP.id_ "group-modules__label"
142+ , HP.id "group-modules__label"
143143 ]
144144 [ HH.text " GROUP BY PACKAGE" ]
145145
@@ -215,4 +215,4 @@ isCheckedToGroupingMode = if _ then GroupByPackage else DontGroup
215215-- Some optics:
216216
217217_groupingMode :: forall a b rest. (a -> b) -> { groupingMode :: a | rest } -> { groupingMode :: b | rest }
218−_groupingMode = prop (SProxy :: SProxy "groupingMode")
218+_groupingMode = prop (Proxy :: Proxy "groupingMode")
src/Docs/Search/BrowserEngine.js+1−1
@@ -1,6 +1,6 @@
11/* global exports */
22
3−exports.loadIndex_ = function (partId) {
3+export function loadIndex_ (partId) {
44 return function (url) {
55 return function () {
66 return new Promise(function(resolve, reject) {
src/Docs/Search/IndexBuilder.js+4−5
@@ -1,14 +1,13 @@
11/* global __dirname require exports */
22
3−var path = require('path');
4−var glob = require('glob');
3+import globMain from "glob";
54
6−exports.getDirname = function () {
5+export function getDirname () {
76 return __dirname;
87};
98
10−exports.glob = function (pattern) {
9+export function glob (pattern) {
1110 return function () {
12− return glob.sync(pattern);
11+ return globMain.sync(pattern);
1312 };
1413};
src/Docs/Search/IndexBuilder.purs+4−3
@@ -43,7 +43,8 @@ import Effect.Aff (Aff, launchAff_, parallel, sequential)
4343import Effect.Class (liftEffect)
4444import Effect.Console (log)
4545import Node.Encoding (Encoding(UTF8))
46−import Node.FS.Aff (exists, mkdir, readFile, readTextFile, readdir, stat, writeFile, writeTextFile)
46+import Node.FS.Aff (mkdir, readFile, readTextFile, readdir, stat, writeFile, writeTextFile)
47+import Node.FS.Sync (exists)
4748import Node.FS.Stats (isDirectory, isFile)
4849import Node.Process as Process
4950import Web.Bower.PackageMeta (PackageMeta(..))
@@ -369,7 +370,7 @@ copyAppFile { generatedDocs } = do
369370
370371directoryExists :: String -> Aff Boolean
371372directoryExists path = do
372− doesExist <- exists path
373+ doesExist <- liftEffect $ exists path
373374 case doesExist of
374375 false -> pure false
375376 true -> isDirectory <$> stat path
@@ -377,7 +378,7 @@ directoryExists path = do
377378
378379fileExists :: String -> Aff Boolean
379380fileExists path = do
380− doesExist <- exists path
381+ doesExist <- liftEffect $ exists path
381382 case doesExist of
382383 false -> pure false
383384 true -> isFile <$> stat path
src/Docs/Search/Loader.js+1−1
@@ -1,6 +1,6 @@
11/* global exports */
22
3−exports.loadFromScript = function (globalIdentifier) {
3+export function loadFromScript (globalIdentifier) {
44 return function (url) {
55 return function () {
66 return new Promise(function (resolve, reject) {
src/Docs/Search/ModuleIndex.js+1−1
@@ -1,6 +1,6 @@
11/* global exports */
22
3−exports.load = function (url) {
3+export function load (url) {
44 return function () {
55 return new Promise(function (resolve, reject) {
66 if (typeof window.DocsSearchModuleIndex === 'undefined') {
src/Docs/Search/ModuleIndex.purs+3−4
@@ -30,12 +30,11 @@ import Data.Set as Set
3030import Data.String.CodeUnits (toCharArray) as String
3131import Data.String.Common (split, toLower) as String
3232import Data.String.Pattern (Pattern(..))
33−import Data.Symbol (SProxy(..))
3433import Data.Traversable (foldr, for_)
3534import Data.Tuple.Nested ((/\))
3635import Effect (Effect)
3736import Effect.Aff (Aff)
38−
37+import Type.Proxy (Proxy(..))
3938
4039-- | Module index that is actually stored in a JS file.
4140type PackedModuleIndex = Map PackageInfo (Set ModuleName)
@@ -116,7 +115,7 @@ foreign import load
116115
117116
118117_modulePackages :: forall a b rest. (a -> b) -> { modulePackages :: a | rest } -> { modulePackages :: b | rest }
119−_modulePackages = prop (SProxy :: SProxy "modulePackages")
118+_modulePackages = prop (Proxy :: Proxy "modulePackages")
120119
121120_index :: forall a b rest. (a -> b) -> { index :: a | rest } -> { index :: b | rest }
122−_index = prop (SProxy :: SProxy "index")
121+_index = prop (Proxy :: Proxy "index")
src/Docs/Search/TypeIndex.js+1−1
@@ -1,6 +1,6 @@
11/* global exports */
22
3−exports.lookup_ = function (shape) {
3+export function lookup_ (shape) {
44 return function (url) {
55 return function () {
66 return new Promise(function (resolve, reject) {
src/Docs/Search/TypeQuery.purs+3−3
@@ -34,9 +34,9 @@ import Data.Set as Set
3434import Data.String.CodeUnits (fromCharArray)
3535import Data.String.Common (trim) as String
3636import Data.Tuple (Tuple(..), fst, snd)
37−import Text.Parsing.StringParser (ParseError, Parser, runParser, try)
38−import Text.Parsing.StringParser.CodePoints (alphaNum, anyLetter, char, eof, lowerCaseChar, skipSpaces, string, upperCaseChar)
39−import Text.Parsing.StringParser.Combinators (fix, sepBy, sepBy1, sepEndBy, sepEndBy1)
37+import StringParser (ParseError, Parser, runParser, try)
38+import StringParser.CodePoints (alphaNum, anyLetter, char, eof, lowerCaseChar, skipSpaces, string, upperCaseChar)
39+import StringParser.Combinators (fix, sepBy, sepBy1, sepEndBy, sepEndBy1)
4040
4141
4242-- | We need type queries because we don't have a full-featured type parser
src/Docs/Search/TypeShape.js+1−1
@@ -1,6 +1,6 @@
11/* global exports */
22
3−exports.hash = function (string) {
3+export function hash (string) {
44 var hash = Math.floor(Number.MAX_SAFE_INTEGER / 2);
55 if (string.length == 0) {
66 return hash;
src/Docs/Search/URIHash.js+1−1
@@ -1,7 +1,7 @@
11/* global exports history */
22
33// https://stackoverflow.com/questions/1397329
4−exports.removeHash = function () {
4+export function removeHash () {
55 var scrollV, scrollH, loc = window.location;
66 if ("pushState" in history)
77 history.pushState("", document.title, loc.pathname + loc.search);
src/Docs/Search/URIHash.purs+2−2
@@ -7,7 +7,7 @@ where
77
88import Prelude
99
10−import Data.Maybe (Maybe(Just), fromMaybe)
10+import Data.Maybe (fromMaybe)
1111import Data.String.CodeUnits as String
1212import Effect (Effect)
1313import JSURI (decodeURIComponent, encodeURIComponent)
@@ -31,7 +31,7 @@ getInput = do
3131 location <- Window.location window
3232 hash <- Location.hash location
3333 pure $
34− if String.slice 0 8 hash == Just "#search:"
34+ if String.slice 0 8 hash == "#search:"
3535 then fromMaybe "" $
3636 decodeURIComponent $
3737 String.drop 8 hash
test/Main.purs+6−4
@@ -9,15 +9,17 @@ import Test.ModuleIndex as ModuleIndex
99import Test.TypeQuery as TypeQuery
1010import Test.TypeJson as TypeJson
1111import Test.UI as UI
12−import Test.Unit (TestSuite)
13−import Test.Unit.Main (runTest)
12+import Test.Spec (Spec)
13+import Test.Spec.Reporter.Console (consoleReporter)
14+import Test.Spec.Runner (runSpec)
15+import Effect.Aff (launchAff_)
1416
1517main :: Effect Unit
1618main = do
17− runTest mainTest
19+ launchAff_ $ runSpec [consoleReporter] mainTest
1820 UI.main
1921
20−mainTest :: TestSuite
22+mainTest :: Spec Unit
2123mainTest = do
2224 TypeQuery.tests
2325 TypeJson.tests
test/Test/Declarations.purs+12−13
@@ -7,33 +7,32 @@ import Docs.Search.Types (PackageName(..), PackageInfo(..))
77
88import Data.Maybe (Maybe(..))
99import Data.Newtype (wrap)
10+import Test.Spec (Spec, describe, it)
11+import Test.Spec.Assertions (shouldEqual)
1012
11−import Test.Unit (TestSuite, suite, test)
12−import Test.Unit.Assert as Assert
13−
14−tests :: TestSuite
13+tests :: Spec Unit
1514tests = do
16− suite "Declarations" do
17− test "extractPackageName" do
18− Assert.equal Builtin (extractPackageName (wrap "Prim") Nothing)
19− Assert.equal Builtin (extractPackageName (wrap "Prim.Foo") Nothing)
20− Assert.equal Builtin (extractPackageName (wrap "Prim.Foo.Bar") Nothing)
21− Assert.equal UnknownPackage (extractPackageName (wrap "Primitive") Nothing)
22− Assert.equal (Package $ PackageName "foo")
15+ describe "Declarations" do
16+ it "extractPackageName works correctly" do
17+ Builtin `shouldEqual` (extractPackageName (wrap "Prim") Nothing)
18+ Builtin `shouldEqual` (extractPackageName (wrap "Prim.Foo") Nothing)
19+ Builtin `shouldEqual` (extractPackageName (wrap "Prim.Foo.Bar") Nothing)
20+ UnknownPackage `shouldEqual` (extractPackageName (wrap "Primitive") Nothing)
21+ Package (PackageName "foo") `shouldEqual`
2322 (extractPackageName (wrap "Foo") $
2423 Just { start: []
2524 , end: []
2625 , name: ".spago/foo/src/Foo.purs"
2726 }
2827 )
29− Assert.equal (Package $ PackageName "bar")
28+ Package (PackageName "bar") `shouldEqual`
3029 (extractPackageName (wrap "Bar") $
3130 Just { start: []
3231 , end: []
3332 , name: "/path/to/somewhere/bower_components/bar/src/Bar.purs"
3433 }
3534 )
36− Assert.equal LocalPackage
35+ LocalPackage `shouldEqual`
3736 (extractPackageName (wrap "Bar") $
3837 Just { start: []
3938 , end: []
test/Test/Extra.purs+6−5
@@ -4,7 +4,8 @@ import Prelude
44
55import Data.Either (Either(..))
66import Effect.Aff (Aff)
7−import Test.Unit.Assert as Assert
7+import Test.Spec.Assertions (shouldEqual)
8+
89
910assertRight
1011 :: forall a b
@@ -17,7 +18,7 @@ assertRight
1718 -> Aff Unit
1819assertRight eiActual expected =
1920 case eiActual of
20− Left string -> do
21− Assert.equal (Right expected) eiActual
22− Right actual -> do
23− Assert.equal (Right expected) eiActual
21+ Left _ -> do
22+ Right expected `shouldEqual` eiActual
23+ Right _ -> do
24+ Right expected `shouldEqual` eiActual
test/Test/IndexBuilder.purs+9−9
@@ -5,16 +5,16 @@ import Prelude
55import Docs.Search.IndexBuilder (patchHTML)
66
77import Data.Tuple (snd)
8−import Test.Unit (TestSuite, suite, test)
9−import Test.Unit.Assert as Assert
8+import Test.Spec (Spec, describe, it)
9+import Test.Spec.Assertions (shouldEqual, shouldNotSatisfy)
1010
11−tests :: TestSuite
11+tests :: Spec Unit
1212tests = do
13− suite "IndexBuilder" do
14− suite "patchHTML" do
15− test "works" do
13+ describe "IndexBuilder" do
14+ describe "patchHTML" do
15+ it "works" do
1616 let input = "</body>"
17− Assert.assertFalse "patchHTML works" (snd (patchHTML input) == input)
18− test "is idempotent" do
17+ shouldNotSatisfy (snd (patchHTML input)) (eq input)
18+ it "is idempotent" do
1919 let input = "</body>"
20− Assert.equal (snd $ patchHTML $ snd $ patchHTML input) (snd $ patchHTML input)
20+ shouldEqual (snd $ patchHTML $ snd $ patchHTML input) (snd $ patchHTML input)
test/Test/ModuleIndex.purs+8−10
@@ -6,20 +6,18 @@ import Prelude
66
77import Data.List as List
88import Data.Newtype (wrap)
9−import Test.Unit (TestSuite, suite, test)
10−import Test.Unit.Assert as Assert
9+import Test.Spec (Spec, describe, it)
10+import Test.Spec.Assertions (shouldEqual)
1111
1212
13−tests :: TestSuite
13+tests :: Spec Unit
1414tests = do
15− suite "ModuleIndex" do
15+ describe "ModuleIndex" do
1616
17− test "test #0" do
18− Assert.equal (extractModuleNameParts $ wrap "Data.Array.ST") (
17+ it "test #0" do
18+ extractModuleNameParts (wrap "Data.Array.ST") `shouldEqual`
1919 List.fromFoldable [ "st", "array.st", "data.array.st" ]
20− )
2120
22− test "test #1" do
23− Assert.equal (extractModuleNameParts $ wrap "Foo") (
21+ it "test #1" do
22+ extractModuleNameParts (wrap "Foo") `shouldEqual`
2423 List.fromFoldable [ "foo" ]
25− )
test/Test/TypeJson.purs+18−18
@@ -15,13 +15,13 @@ import Data.Argonaut.Parser (jsonParser)
1515import Data.Either (Either(..))
1616import Data.Maybe (Maybe(..))
1717import Partial.Unsafe (unsafePartial)
18−import Test.Unit (TestSuite, suite, test)
18+import Test.Spec (Spec, describe, it)
1919
2020
21−tests :: TestSuite
21+tests :: Spec Unit
2222tests = do
23− suite "FunDeps decoder" do
24− test "FunDeps" do
23+ describe "FunDeps decoder" do
24+ it "FunDeps" do
2525 let
2626 funDeps = mkJson """
2727 [
@@ -42,8 +42,8 @@ tests = do
4242 }
4343 ])
4444
45− suite "Constraint decoder" do
46− test "Constraint" do
45+ describe "Constraint decoder" do
46+ it "Constraint" do
4747 let constraint = mkJson """
4848 {
4949 "constraintAnn": [],
@@ -62,8 +62,8 @@ tests = do
6262 , constraintArgs: []
6363 })
6464
65− suite "Type decoder" do
66− test "TypeVar" do
65+ describe "Type decoder" do
66+ it "TypeVar" do
6767 let typeVar = mkJson """
6868 {
6969 "annotation": [],
@@ -75,7 +75,7 @@ tests = do
7575 assertRight (decodeJson typeVar)
7676 (TypeVar "m")
7777
78− test "TypeApp" do
78+ it "TypeApp" do
7979 let typeApp1 = mkJson """
8080 {
8181 "annotation": [],
@@ -114,7 +114,7 @@ tests = do
114114 ))
115115 (TypeVar "h")
116116
117− test "TypeOp" do
117+ it "TypeOp" do
118118 let typeOp = mkJson """
119119 {
120120 "annotation": [],
@@ -131,7 +131,7 @@ tests = do
131131 assertRight (decodeJson typeOp) $
132132 TypeOp $ qualified [ "Data", "NaturalTransformation" ] "~>"
133133
134− test "BinaryNoParens" do
134+ it "BinaryNoParens" do
135135 let binaryNoParens = mkJson """
136136 {
137137 "annotation": [],
@@ -168,7 +168,7 @@ tests = do
168168 (TypeVar "m")
169169 (TypeVar "n")
170170
171− test "ParensInType" do
171+ it "ParensInType" do
172172 let parensInType = mkJson """
173173 {
174174 "annotation": [],
@@ -208,7 +208,7 @@ tests = do
208208 TypeApp
209209 (TypeConstructor (qualified [ "Data", "Maybe" ] "Maybe"))
210210 (TypeConstructor (qualified [ "Prim" ] "String"))
211− test "RCons" do
211+ it "RCons" do
212212
213213 let rcons = mkJson """
214214 {
@@ -253,7 +253,7 @@ tests = do
253253 (TypeVar "t"))
254254 REmpty
255255
256− test "ForAll #1" do
256+ it "ForAll #1" do
257257 let forallJson = mkJson """
258258 {"annotation":[],"tag":"ForAll","contents":["a",{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"String"]}]},{"annotation":[],"tag":"TypeVar","contents":"a"}]},null]}
259259 """
@@ -262,13 +262,13 @@ tests = do
262262 (TypeConstructor $ qualified ["Prim"] "String"))
263263 (TypeVar "a"))
264264
265− test "KindApp" do
265+ it "KindApp" do
266266 let kindAppJson = mkJson """
267267 {"annotation":[],"tag":"KindApp","contents":[{"annotation":[],"tag":"REmpty"},{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Type"]}]}
268268 """
269269 assertRight (decodeJson kindAppJson) $
270270 KindApp REmpty (TypeConstructor (qualified ["Prim"] "Type"))
271− test "KindedType" do
271+ it "KindedType" do
272272 let kindedTypeJson = mkJson """
273273 {"annotation":[],"tag":"KindedType","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Data","Const"],"Const"]},{"annotation":[],"tag":"TypeConstructor","contents":[["Data","Void"],"Void"]}]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Type"]}]},{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Type"]}]}]}
274274 """
@@ -281,9 +281,9 @@ tests = do
281281 (TypeConstructor (qualified ["Prim"] "Function"))
282282 (TypeConstructor (qualified ["Prim"] "Type" )))
283283 (TypeConstructor (qualified ["Prim"] "Type")))
284− suite "jsons" do
284+ describe "jsons" do
285285
286− test "jsons #1" do
286+ it "jsons #1" do
287287 let json = mkJson """
288288{"annotation":[],"tag":"ForAll","contents":["o",{"annotation":[],"tag":"ForAll","contents":["r",{"annotation":[],"tag":"ForAll","contents":["l",{"annotation":[],"tag":"ConstrainedType","contents":[{"constraintAnn":[],"constraintClass":[["Type","Data","Boolean"],"And"],"constraintArgs":[{"annotation":[],"tag":"TypeVar","contents":"l"},{"annotation":[],"tag":"TypeVar","contents":"r"},{"annotation":[],"tag":"TypeVar","contents":"o"}],"constraintData":null},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"l"}]}]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"r"}]}]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"o"}]}]}]}]},null]},null]},null]}
289289 """
test/Test/TypeQuery.purs+383−229
@@ -15,384 +15,535 @@ import Data.List.NonEmpty as NonEmptyList
1515import Data.Set as Set
1616import Data.Tuple (Tuple(..))
1717import Test.Extra (assertRight)
18−import Test.Unit (TestSuite, suite, test)
19−import Test.Unit.Assert as Assert
18+import Test.Spec (Spec, describe, it)
19+import Test.Spec.Assertions (shouldEqual, shouldSatisfy)
2020import Data.Maybe (Maybe(..))
2121
22−
23−tests :: TestSuite
22+tests :: Spec Unit
2423tests = do
25− suite "TypeQuery parser" do
24+ describe "TypeQuery parser" do
2625
27− test "test #0" do
26+ it "test #0" do
2827 let input = "a"
2928 assertRight (parseTypeQuery input) (qVar "a")
3029
31− test "test #1" do
30+ it "test #1" do
3231 let input = "ab"
3332 assertRight (parseTypeQuery input) (qVar "ab")
3433
35− test "test #2" do
34+ it "test #2" do
3635 let input = "a b"
3736 assertRight (parseTypeQuery input) (QApp (qVar "a") (qVar "b"))
3837
39− test "test #3" do
38+ it "test #3" do
4039 let input = "a b c"
4140 assertRight (parseTypeQuery input) (QApp (QApp (qVar "a") (qVar "b")) (qVar "c"))
4241
43− test "test #4" do
42+ it "test #4" do
4443 let input = "a -> b"
4544 assertRight (parseTypeQuery input) (QFun (qVar "a") (qVar "b"))
4645
47− test "test #5" do
46+ it "test #5" do
4847 let input = "a -> b c"
4948 assertRight (parseTypeQuery input) (QFun (qVar "a") (QApp (qVar "b") (qVar "c")))
5049
51− test "test #6" do
50+ it "test #6" do
5251 let input = "a b -> c"
5352 assertRight (parseTypeQuery input) (QFun (QApp (qVar "a") (qVar "b")) (qVar "c"))
5453
55− test "test #7" do
54+ it "test #7" do
5655 let input = "a b"
5756 assertRight (parseTypeQuery input) (QApp (qVar "a") (qVar "b"))
5857
59− test "test #8" do
58+ it "test #8" do
6059 let input = "a (b c)"
6160 assertRight (parseTypeQuery input) (QApp (qVar "a") (QApp (qVar "b") (qVar "c")))
6261
63− test "test #9" do
62+ it "test #9" do
6463 let input = "(a b) (c d)"
6564 assertRight (parseTypeQuery input)
66− (QApp (QApp (qVar "a") (qVar "b"))
67− (QApp (qVar "c") (qVar "d")))
65+ ( QApp (QApp (qVar "a") (qVar "b"))
66+ (QApp (qVar "c") (qVar "d"))
67+ )
6868
69− test "test #10" do
69+ it "test #10" do
7070 let input = "a ( b c )"
7171 assertRight (parseTypeQuery input) (QApp (qVar "a") (QApp (qVar "b") (qVar "c")))
7272
73− test "test #11" do
73+ it "test #11" do
7474 let input = "aaa"
7575 assertRight (parseTypeQuery input) (qVar "aaa")
7676
77− test "test #12" do
77+ it "test #12" do
7878 let input = "aaa ( bbb ccc )"
7979 assertRight (parseTypeQuery input) (QApp (qVar "aaa") (QApp (qVar "bbb") (qVar "ccc")))
8080
81− test "test #13" do
81+ it "test #13" do
8282 let input = "(a -> b) -> (c -> d)"
83− assertRight (parseTypeQuery input) (QFun (QFun (qVar "a") (qVar "b"))
84− (QFun (qVar "c") (qVar "d")))
83+ assertRight (parseTypeQuery input)
84+ ( QFun (QFun (qVar "a") (qVar "b"))
85+ (QFun (qVar "c") (qVar "d"))
86+ )
8587
86− test "test #14" do
88+ it "test #14" do
8789 let input = "a -> b -> c -> d"
88− assertRight (parseTypeQuery input) (QFun (qVar "a")
89− (QFun (qVar "b")
90− (QFun (qVar "c") (qVar "d"))))
90+ assertRight (parseTypeQuery input)
91+ ( QFun (qVar "a")
92+ ( QFun (qVar "b")
93+ (QFun (qVar "c") (qVar "d"))
94+ )
95+ )
9196
92− test "test #15" do
97+ it "test #15" do
9398 let input = "a -> b -> c"
94− assertRight (parseTypeQuery input) (QFun (qVar "a")
95− (QFun (qVar "b")
96− (qVar "c")))
99+ assertRight (parseTypeQuery input)
100+ ( QFun (qVar "a")
101+ ( QFun (qVar "b")
102+ (qVar "c")
103+ )
104+ )
97105
98− test "test #16" do
106+ it "test #16" do
99107 let input = "forall a b c. c"
100− assertRight (parseTypeQuery input) (QForAll (nl "a" ["b", "c"]) (qVar "c"))
108+ assertRight (parseTypeQuery input) (QForAll (nl "a" [ "b", "c" ]) (qVar "c"))
101109
102− test "test #17" do
110+ it "test #17" do
103111 let input = "forall a. Maybe a"
104112 assertRight (parseTypeQuery input) (QForAll (nl "a" $ []) (QApp (qConst "Maybe") (qVar "a")))
105113
106− test "test #18" do
114+ it "test #18" do
107115 let input = "forall m a. Monad m => a -> m a"
108116 assertRight (parseTypeQuery input)
109− (QForAll (nl "m" ["a"])
110− (qConstraint "Monad" (l [qVar "m"])
111− (QFun (qVar "a")
112− (QApp (qVar "m") (qVar "a")))))
113−
114− test "test #19" do
117+ ( QForAll (nl "m" [ "a" ])
118+ ( qConstraint "Monad" (l [ qVar "m" ])
119+ ( QFun (qVar "a")
120+ (QApp (qVar "m") (qVar "a"))
121+ )
122+ )
123+ )
124+
125+ it "test #19" do
115126 let input = "{ a :: Int }"
116127 assertRight (parseTypeQuery input)
117128 (QApp (qConst "Record") (QRow (pure (Tuple (Identifier "a") (qConst "Int")))))
118129
119− test "test #20" do
130+ it "test #20" do
120131 let input = "{a::Int}"
121132 assertRight (parseTypeQuery input)
122133 (QApp (qConst "Record") (QRow (pure (Tuple (Identifier "a") (qConst "Int")))))
123134
124− test "test #21" do
135+ it "test #21" do
125136 let input = "Int"
126137 assertRight (parseTypeQuery input) (qConst "Int")
127138
128− test "test #22" do
139+ it "test #22" do
129140 let input = "a->b"
130141 assertRight (parseTypeQuery input) (QFun (qVar "a") (qVar "b"))
131142
132− test "test #23" do
143+ it "test #23" do
133144 let input = "forall m a. MonadRec m => Process m a -> m a"
134− assertRight (parseTypeQuery input) (QForAll (nl "m" ("a" : Nil))
135− (qConstraint "MonadRec" (l [qVar "m"])
136− (QFun (QApp (QApp (qConst "Process")
137− (qVar "m")) (qVar "a"))
138− (QApp (qVar "m") (qVar "a")))))
139−
140− test "test #24" do
145+ assertRight (parseTypeQuery input)
146+ ( QForAll (nl "m" ("a" : Nil))
147+ ( qConstraint "MonadRec" (l [ qVar "m" ])
148+ ( QFun
149+ ( QApp
150+ ( QApp (qConst "Process")
151+ (qVar "m")
152+ )
153+ (qVar "a")
154+ )
155+ (QApp (qVar "m") (qVar "a"))
156+ )
157+ )
158+ )
159+
160+ it "test #24" do
141161 let input = "forall t f a. Foldable1 t => Apply f => f"
142− assertRight (parseTypeQuery input) (QForAll (nl "t" ["f", "a"])
143− (qConstraint "Foldable1" (l [qVar "t"])
144− (qConstraint "Apply" (l [qVar "f"]) (qVar "f"))))
162+ assertRight (parseTypeQuery input)
163+ ( QForAll (nl "t" [ "f", "a" ])
164+ ( qConstraint "Foldable1" (l [ qVar "t" ])
165+ (qConstraint "Apply" (l [ qVar "f" ]) (qVar "f"))
166+ )
167+ )
145168
146− test "test #25" do
169+ it "test #25" do
147170 let input = "forall m a.MonadRec m=>Process m a->m a"
148− assertRight (parseTypeQuery input) ((QForAll (nl "m" ("a" : Nil))
149− (qConstraint "MonadRec" (l [qVar "m"])
150− (QFun (QApp (QApp (qConst "Process")
151− (qVar "m")) (qVar "a"))
152− (QApp (qVar "m") (qVar "a"))))))
153−
154− test "test #26" do
171+ assertRight (parseTypeQuery input)
172+ ( ( QForAll (nl "m" ("a" : Nil))
173+ ( qConstraint "MonadRec" (l [ qVar "m" ])
174+ ( QFun
175+ ( QApp
176+ ( QApp (qConst "Process")
177+ (qVar "m")
178+ )
179+ (qVar "a")
180+ )
181+ (QApp (qVar "m") (qVar "a"))
182+ )
183+ )
184+ )
185+ )
186+
187+ it "test #26" do
155188 let input = "m a -> (a -> m b) -> m b"
156189 assertRight (parseTypeQuery input) (QFun (QApp (qVar "m") (qVar "a")) (QFun (QFun (qVar "a") (QApp (qVar "m") (qVar "b"))) (QApp (qVar "m") (qVar "b"))))
157190
158− test "test #27" do
191+ it "test #27" do
159192 let input = "forall f a. Alternative f => Lazy (f (List a)) => f a -> f (List a)"
160− assertRight (parseTypeQuery input) ((QForAll (nl "f" ["a"]))
161− (qConstraint "Alternative" (l [qVar "f"])
162− (qConstraint "Lazy" (l [QApp (qVar "f")
163− (QApp (qConst "List") (qVar "a"))])
164− (QFun (QApp (qVar "f") (qVar "a"))
165− (QApp (qVar "f")
166− (QApp (qConst "List") (qVar "a")))))))
167−
168− test "test #28" do
193+ assertRight (parseTypeQuery input)
194+ ( (QForAll (nl "f" [ "a" ]))
195+ ( qConstraint "Alternative" (l [ qVar "f" ])
196+ ( qConstraint "Lazy"
197+ ( l
198+ [ QApp (qVar "f")
199+ (QApp (qConst "List") (qVar "a"))
200+ ]
201+ )
202+ ( QFun (QApp (qVar "f") (qVar "a"))
203+ ( QApp (qVar "f")
204+ (QApp (qConst "List") (qVar "a"))
205+ )
206+ )
207+ )
208+ )
209+ )
210+
211+ it "test #28" do
169212 let input = "forall f a. Alternative f => Lazy(f (List a))=>f a -> f (List a)"
170− assertRight (parseTypeQuery input) ((QForAll (nl "f" ["a"]))
171− (qConstraint "Alternative" (l [qVar "f"])
172− (qConstraint "Lazy" (l [QApp (qVar "f")
173− (QApp (qConst "List") (qVar "a"))])
174− (QFun (QApp (qVar "f") (qVar "a"))
175− (QApp (qVar "f")
176− (QApp (qConst "List") (qVar "a")))))))
177−
178− test "test #29" do
213+ assertRight (parseTypeQuery input)
214+ ( (QForAll (nl "f" [ "a" ]))
215+ ( qConstraint "Alternative" (l [ qVar "f" ])
216+ ( qConstraint "Lazy"
217+ ( l
218+ [ QApp (qVar "f")
219+ (QApp (qConst "List") (qVar "a"))
220+ ]
221+ )
222+ ( QFun (QApp (qVar "f") (qVar "a"))
223+ ( QApp (qVar "f")
224+ (QApp (qConst "List") (qVar "a"))
225+ )
226+ )
227+ )
228+ )
229+ )
230+
231+ it "test #29" do
179232 let input = "{a::Int,b::Int}"
180233 assertRight (parseTypeQuery input)
181− (QApp (qConst "Record") (QRow (List.fromFoldable
182− [ Tuple (Identifier "a") (qConst "Int")
183− , Tuple (Identifier "b") (qConst "Int")])))
184−
185− test "test #30" do
234+ ( QApp (qConst "Record")
235+ ( QRow
236+ ( List.fromFoldable
237+ [ Tuple (Identifier "a") (qConst "Int")
238+ , Tuple (Identifier "b") (qConst "Int")
239+ ]
240+ )
241+ )
242+ )
243+
244+ it "test #30" do
186245 let input = "{record''' :: Int}"
187246 assertRight (parseTypeQuery input)
188− (QApp (qConst "Record") (QRow (List.fromFoldable [ Tuple (Identifier "record'''") (qConst "Int")])))
247+ (QApp (qConst "Record") (QRow (List.fromFoldable [ Tuple (Identifier "record'''") (qConst "Int") ])))
189248
190− test "test #31" do
249+ it "test #31" do
191250 let input = "(row''' :: Int)"
192251 assertRight (parseTypeQuery input)
193− (QRow (List.fromFoldable [ Tuple (Identifier "row'''") (qConst "Int")]))
252+ (QRow (List.fromFoldable [ Tuple (Identifier "row'''") (qConst "Int") ]))
194253
195− test "test #32" do
254+ it "test #32" do
196255 let input = "(row1 :: Int, row2 :: (),row3::(row4::{}))"
197256 assertRight (parseTypeQuery input)
198− (QRow (l [ Tuple (Identifier "row1") (qConst "Int")
199− , Tuple (Identifier "row2") (QRow Nil)
200− , Tuple (Identifier "row3") (QRow (l [ Tuple (Identifier "row4") (QApp (qConst "Record") (QRow Nil)) ])) ]))
201−
202− test "test #33" do
257+ ( QRow
258+ ( l
259+ [ Tuple (Identifier "row1") (qConst "Int")
260+ , Tuple (Identifier "row2") (QRow Nil)
261+ , Tuple (Identifier "row3") (QRow (l [ Tuple (Identifier "row4") (QApp (qConst "Record") (QRow Nil)) ]))
262+ ]
263+ )
264+ )
265+
266+ it "test #33" do
203267 let input = "Foldable1 t => Apply f => t (f a) -> f Unit"
204268 assertRight (parseTypeQuery input)
205269 (qConstraint "Foldable1" ((qVar "t") : Nil) (qConstraint "Apply" ((qVar "f") : Nil) (QFun (QApp (qVar "t") (QApp (qVar "f") (qVar "a"))) (QApp (qVar "f") (qConst "Unit")))))
206270
207− test "test #34" do
271+ it "test #34" do
208272 let input = "Foldable1 t => Apply f => t (f a) -> f a"
209273 assertRight (parseTypeQuery input)
210274 (qConstraint "Foldable1" ((qVar "t") : Nil) (qConstraint "Apply" ((qVar "f") : Nil) (QFun (QApp (qVar "t") (QApp (qVar "f") (qVar "a"))) (QApp (qVar "f") (qVar "a")))))
211275
212− test "test #35" do
276+ it "test #35" do
213277 let input = "Generic a rep => GenericEq rep => a -> a -> Boolean"
214278 assertRight (parseTypeQuery input)
215− (qConstraint "Generic" ((qVar "a") : (qVar "rep") : Nil)
216− (qConstraint "GenericEq" ((qVar "rep") : Nil)
217− (QFun (qVar "a") (QFun (qVar "a") (qConst "Boolean")))))
279+ ( qConstraint "Generic" ((qVar "a") : (qVar "rep") : Nil)
280+ ( qConstraint "GenericEq" ((qVar "rep") : Nil)
281+ (QFun (qVar "a") (QFun (qVar "a") (qConst "Boolean")))
282+ )
283+ )
218284
219− suite "polish notation" do
285+ describe "polish notation" do
220286
221− test "test #1" do
287+ it "test #1" do
222288 let input = "(a -> b) -> (b -> ((a -> b) -> c))"
223289 assertRight (shapeOfTypeQuery <$> parseTypeQuery input)
224− (l [ PForAll 3, PFun, PFun, PVar, PVar, PFun, PVar, PFun, PFun
225− , PVar, PVar, PVar ])
226−
227− test "test #2" do
290+ ( l
291+ [ PForAll 3
292+ , PFun
293+ , PFun
294+ , PVar
295+ , PVar
296+ , PFun
297+ , PVar
298+ , PFun
299+ , PFun
300+ , PVar
301+ , PVar
302+ , PVar
303+ ]
304+ )
305+
306+ it "test #2" do
228307 let input = "forall a. (a -> b) -> (b -> ((a -> b) -> c))"
229308 assertRight (shapeOfTypeQuery <$> parseTypeQuery input)
230− (l [ PForAll 3, PFun, PFun, PVar, PVar, PFun, PVar, PFun, PFun
231− , PVar, PVar, PVar ])
232−
233− test "test #3" do
309+ ( l
310+ [ PForAll 3
311+ , PFun
312+ , PFun
313+ , PVar
314+ , PVar
315+ , PFun
316+ , PVar
317+ , PFun
318+ , PFun
319+ , PVar
320+ , PVar
321+ , PVar
322+ ]
323+ )
324+
325+ it "test #3" do
234326 let input = "forall a. (a -> b) -> (b -> ((a -> b) -> c))"
235327 assertRight (shapeOfTypeQuery <$> parseTypeQuery input)
236− (l [ PForAll 3, PFun, PFun, PVar, PVar, PFun, PVar, PFun, PFun
237− , PVar, PVar, PVar ])
238−
239− test "test #4" do
328+ ( l
329+ [ PForAll 3
330+ , PFun
331+ , PFun
332+ , PVar
333+ , PVar
334+ , PFun
335+ , PVar
336+ , PFun
337+ , PFun
338+ , PVar
339+ , PVar
340+ , PVar
341+ ]
342+ )
343+
344+ it "test #4" do
240345 let input = "forall a. (forall h. ST h (STArray h a)) -> Array a"
241346 assertRight (shapeOfTypeQuery <$> parseTypeQuery input)
242− (l [ PForAll 1, PFun, PForAll 1, PApp, PApp, PVar, PVar, PApp, PApp, PVar, PVar, PVar, PApp, PVar, PVar ])
243−
244− suite "type shapes" do
245− test "test #1" do
246− let query = "Generic a rep => GenericEq rep => a -> a -> Boolean"
247− c1 = constr (qname [""] "Generic") [TypeVar "a", TypeVar "rep"]
248− c2 = constr (qname [""] "GenericEq") [TypeVar "rep"]
249−
250− fun t1 t2 =
251− TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"]
252− , name: Identifier "Function" })) t1) t2
253− type_ =
254− ForAll "a" Nothing $
255− ForAll "rep" Nothing $
256− ConstrainedType c1
257− (ConstrainedType c2
258− (fun (TypeVar "a") (fun (TypeVar "b")
259− (TypeConstructor $ qname ["Prim", "Boolean"] "Boolean"))))
260− shape = shapeOfTypeQuery <$> parseTypeQuery query
261− Assert.equal (pure $ shapeOfType type_) shape
262−
263− suite "free variable counting" do
264−
265− test "test #1" do
347+ (l [ PForAll 1, PFun, PForAll 1, PApp, PApp, PVar, PVar, PApp, PApp, PVar, PVar, PVar, PApp, PVar, PVar ])
348+
349+ describe "type shapes" do
350+ it "test #1" do
351+ let
352+ query = "Generic a rep => GenericEq rep => a -> a -> Boolean"
353+ c1 = constr (qname [ "" ] "Generic") [ TypeVar "a", TypeVar "rep" ]
354+ c2 = constr (qname [ "" ] "GenericEq") [ TypeVar "rep" ]
355+
356+ fun t1 t2 =
357+ TypeApp
358+ ( TypeApp
359+ ( TypeConstructor
360+ ( QualifiedName
361+ { moduleNameParts: [ "Prim" ]
362+ , name: Identifier "Function"
363+ }
364+ )
365+ )
366+ t1
367+ )
368+ t2
369+ type_ =
370+ ForAll "a" Nothing
371+ $ ForAll "rep" Nothing
372+ $
373+ ConstrainedType c1
374+ ( ConstrainedType c2
375+ ( fun (TypeVar "a")
376+ ( fun (TypeVar "b")
377+ (TypeConstructor $ qname [ "Prim", "Boolean" ] "Boolean")
378+ )
379+ )
380+ )
381+ shape = shapeOfTypeQuery <$> parseTypeQuery query
382+ pure (shapeOfType type_) `shouldEqual` shape
383+
384+ describe "free variable counting" do
385+
386+ it "test #1" do
266387 let input = "forall a. (a -> b) -> (b -> ((a -> b) -> c))"
267388 assertRight (countFreeVars <$> parseTypeQuery input) 2
268389
269− test "test #2" do
390+ it "test #2" do
270391 -- `b` is not bound on the left, `a` is not bound on the right
271392 let input = "(forall a. (a -> b)) -> forall b. (b -> a)"
272393 assertRight (countFreeVars <$> parseTypeQuery input) 2
273394
274− test "test #3" do
395+ it "test #3" do
275396 let input = "a -> forall a. a"
276397 assertRight (countFreeVars <$> parseTypeQuery input) 1
277398
278− test "test #4" do
399+ it "test #4" do
279400 let input = "(forall a. a) -> a"
280401 assertRight (countFreeVars <$> parseTypeQuery input) 1
281402
282− test "test #5" do
403+ it "test #5" do
283404 let input = "forall a. a -> a"
284405 assertRight (countFreeVars <$> parseTypeQuery input) 0
285406
286− test "test #6" do
407+ it "test #6" do
287408 let input = "a -> b -> c"
288409 assertRight (countFreeVars <$> parseTypeQuery input) 3
289410
290− test "test #7" do
411+ it "test #7" do
291412 let input = "forall m a. Monad m => a -> m a"
292413 assertRight (countFreeVars <$> parseTypeQuery input) 0
293414
294− test "test #8" do
415+ it "test #8" do
295416 let input = "Monad m => a -> m a"
296417 assertRight (countFreeVars <$> parseTypeQuery input) 2
297418
298− test "test #9" do
419+ it "test #9" do
299420 let input = "Monad m => a -> a"
300421 assertRight (countFreeVars <$> parseTypeQuery input) 2
301422
302− test "test #10" do
423+ it "test #10" do
303424 let input = "forall a. (forall a. a) a"
304425 assertRight (countFreeVars <$> parseTypeQuery input) 0
305426
306− test "test #11" do
427+ it "test #11" do
307428 let input = "forall a. (forall b. a) a"
308429 assertRight (countFreeVars <$> parseTypeQuery input) 0
309430
310− test "test #12" do
431+ it "test #12" do
311432 let input = "forall a. (forall b. a) a b"
312433 assertRight (countFreeVars <$> parseTypeQuery input) 1
313434
314− suite "typeVarPenalty" do
315−
316− test "#0" do
317− Assert.equal 0 (typeVarPenalty mempty)
318−
319− test "#1" do
320− Assert.equal 0 (typeVarPenalty $ l [ substitute "a" "b"
321− , substitute "b" "a"
322− ])
323−
324− test "#2" do
325− Assert.equal 0 (typeVarPenalty $ l [ substitute "a" "b"
326− , substitute "a" "b"
327− , substitute "a" "b"
328− ])
329−
330− test "#3" do
331− Assert.equal 1 (typeVarPenalty $ l [ substitute "a" "b"
332− , substitute "a" "c"
333− ])
334−
335− test "#4" do
336− Assert.equal 1 (typeVarPenalty $ l [ substitute "a" "b"
337− , substitute "b" "a"
338− , substitute "b" "c"
339− ])
340−
341− test "#5" do
342− Assert.equal 0 (typeVarPenalty $ l [ substitute "a" "b"
343− , substitute "b" "c"
344− , substitute "c" "a"
345− ])
346−
347− test "#6" do
348− Assert.equal 2 (typeVarPenalty $ l [ substitute "a" "b"
349− , substitute "a" "c"
350− , substitute "a" "a"
351− ])
352−
353− test "#7" do
354− Assert.equal 2 (typeVarPenalty $ l [ substitute "a" "a"
355− , substitute "b" "a"
356− , substitute "c" "a"
357− ])
358−
359− test "#8" do
360− Assert.equal 4 (typeVarPenalty $ l [ substitute "a" "a"
361− , substitute "b" "a"
362− , substitute "c" "a"
363− , substitute "a" "b"
364− , substitute "a" "c"
365− , substitute "a" "a"
366− ])
367−
368− test "#9" do
369− Assert.equal 0 (typeVarPenalty $ l [ substitute "a" "e"
370− , substitute "b" "d"
371− , substitute "c" "f"
372− ])
373−
374− suite "unification" do
375− test "instantiation #0" do
376− let mVarQuery = qVar "m"
377− unitConstQuery = qConst "Unit"
378−
379− Assert.assert "instantiation #0" $
380− (penalty unitConstQuery unitType < penalty mVarQuery unitType)
381−
382− test "generalization #0" do
383− let query = qVar "m"
384− t1 = TypeVar "m"
385−
386− Assert.assert "qeneralization #0" $
387− (penalty query unitType > penalty query t1)
388−
435+ describe "typeVarPenalty" do
436+
437+ it "#0" do
438+ 0 `shouldEqual` (typeVarPenalty mempty)
439+
440+ it "#1" do
441+ 0 `shouldEqual`
442+ ( typeVarPenalty $ l
443+ [ substitute "a" "b"
444+ , substitute "b" "a"
445+ ]
446+ )
447+
448+ it "#2" do
449+ 0 `shouldEqual`
450+ ( typeVarPenalty $ l
451+ [ substitute "a" "b"
452+ , substitute "a" "b"
453+ , substitute "a" "b"
454+ ]
455+ )
456+
457+ it "#3" do
458+ 1 `shouldEqual`
459+ ( typeVarPenalty $ l
460+ [ substitute "a" "b"
461+ , substitute "a" "c"
462+ ]
463+ )
464+
465+ it "#4" do
466+ 1 `shouldEqual`
467+ ( typeVarPenalty $ l
468+ [ substitute "a" "b"
469+ , substitute "b" "a"
470+ , substitute "b" "c"
471+ ]
472+ )
473+
474+ it "#5" do
475+ 0 `shouldEqual`
476+ ( typeVarPenalty $ l
477+ [ substitute "a" "b"
478+ , substitute "b" "c"
479+ , substitute "c" "a"
480+ ]
481+ )
482+
483+ it "#6" do
484+ 2 `shouldEqual`
485+ ( typeVarPenalty $ l
486+ [ substitute "a" "b"
487+ , substitute "a" "c"
488+ , substitute "a" "a"
489+ ]
490+ )
491+
492+ it "#7" do
493+ 2 `shouldEqual`
494+ ( typeVarPenalty $ l
495+ [ substitute "a" "a"
496+ , substitute "b" "a"
497+ , substitute "c" "a"
498+ ]
499+ )
500+
501+ it "#8" do
502+ 4 `shouldEqual`
503+ ( typeVarPenalty $ l
504+ [ substitute "a" "a"
505+ , substitute "b" "a"
506+ , substitute "c" "a"
507+ , substitute "a" "b"
508+ , substitute "a" "c"
509+ , substitute "a" "a"
510+ ]
511+ )
512+
513+ it "#9" do
514+ 0 `shouldEqual`
515+ ( typeVarPenalty $ l
516+ [ substitute "a" "e"
517+ , substitute "b" "d"
518+ , substitute "c" "f"
519+ ]
520+ )
521+
522+ describe "unification" do
523+ it "instantiation #0" do
524+ let
525+ mVarQuery = qVar "m"
526+ unitConstQuery = qConst "Unit"
527+
528+ shouldSatisfy
529+ (penalty unitConstQuery unitType)
530+ (_ < penalty mVarQuery unitType)
531+
532+ it "generalization #0" do
533+ let
534+ query = qVar "m"
535+ t1 = TypeVar "m"
536+
537+ shouldSatisfy
538+ (penalty query unitType)
539+ (_ > penalty query t1)
389540
390541l :: forall f. Foldable f => (forall a. f a -> List a)
391542l = List.fromFoldable
392543
393544nl
394545 :: forall t
395− . Foldable t
546+ . Foldable t
396547 => Functor t
397548 => String
398549 -> t String
@@ -400,9 +551,12 @@ nl
400551nl x rst = NonEmptyList.cons' (Identifier x) $ List.fromFoldable (rst <#> Identifier)
401552
402553unitType :: Type
403−unitType = TypeConstructor (QualifiedName { moduleNameParts: []
404− , name: Identifier "Unit"
405− })
554+unitType = TypeConstructor
555+ ( QualifiedName
556+ { moduleNameParts: []
557+ , name: Identifier "Unit"
558+ }
559+ )
406560
407561countFreeVars :: TypeQuery -> Int
408562countFreeVars = getFreeVariables >>> Set.size