on master help sign in
Merge branch 'master' into webgl
7f7b545John P Mayer Jr
.gitignore+4
@@ -13,3 +13,7 @@ data
13build
13build
14cache
14cache
15*~
15*~
16+tests/elm/build/
17+tests/elm/cache/
18+tests/elm/exe.js
19+node_modules/
.gitmodulesnew file+9
@@ -0,0 +1,9 @@
1+[submodule "IO"]
2+ path = IO
3+ url = https://github.com/maxsnew/IO.git
4+[submodule "automaton"]
5+ path = automaton
6+ url = https://github.com/evancz/automaton.git
7+[submodule "Elm-Test"]
8+ path = Elm-Test
9+ url = https://github.com/deadfoxygrandpa/Elm-Test.git
CONTRIBUTING.md+20−19
@@ -5,31 +5,32 @@ describes the basic standards for opening pull requests:
5
5
6## Branches
6## Branches
7
7
8− * The master branch of Elm is for tagging previous releases
8+ * [The master branch](https://github.com/elm-lang/Elm/tree/master) is the
9− and non-breaking changes, like bug fixes. This branch is
9+ home of the next release of the compiler so new features and improvements
10− handy for folks who want to build the most recent public
10+ get merged there. Most pull requests should target this branch!
11− release from source.
12
11
13− * The dev branch is where the most active development occurs.
12+ * [The stable branch](https://github.com/elm-lang/Elm/tree/stable) is for
14− It is the home of the next release of the compiler so new
13+ tagging previous releases and critical bug fixes. This branch is handy for
15− features and improvements get merged there.
14+ folks who want to build the most recent public release from source.
15+
16+If you are working on a fairly large feature, we will probably want to merge it
17+in as its own branch and do some testing before bringing it into the master
18+branch. This way we can keep releases of the master branch independent of new
19+features.
16
20
17## Opening a pull request
21## Opening a pull request
18
22
19−**Please open PRs against the [dev branch of
23+**Please open PRs against the [master branch of
20−Elm](http://github.com/evancz/elm/tree/dev) whenever possible.** Changes that
24+Elm](http://github.com/elm-lang/elm/tree/master) whenever possible.**
21−are compatible with the API of master will be merged to master as soon as
22−possible. Changes that affect Elm's API will be merged to master with a future
23−release of the compiler.
24
25
25−Note that changes in the master branch of [Elm](https://github.com/evancz/Elm/)
26+Note that changes in the master branch of [Elm](https://github.com/elm-lang/Elm/)
26are able to be compiled against the master branch of the [elm-lang.org
27are able to be compiled against the master branch of the [elm-lang.org
27−repo](https://github.com/evancz/elm-lang.org), and the dev branch of
28+repo](https://github.com/elm-lang/elm-lang.org), and the stable branch of
28−[Elm](https://github.com/evancz/Elm/) is able to be built with the dev branch of
29+[Elm](https://github.com/elm-lang/Elm/) is able to be built with the stable
29−the [elm-lang.org repo](https://github.com/evancz/elm-lang.org). Please make
30+branch of the [elm-lang.org repo](https://github.com/elm-lang/elm-lang.org).
30−sure that your changes maintain this compatibility.
31+Please make sure that your changes maintain this compatibility.
31
32
32## Licensing
33## Licensing
33
34
34−You should sign the [contributor agreement](ContributorAgreement.pdf)
35+You need to sign the [contributor agreement](ContributorAgreement.pdf)
35−and send it to <info@elm-lang.org> before opening your pull request.
36+and send it to <info@elm-lang.org> before opening your pull request.
Elm-Testnew file+1

Submodule changed.

Elm.cabal+20−13
@@ -96,7 +96,7 @@ Library
96
96
97 Build-depends: aeson,
97 Build-depends: aeson,
98 base >=4.2 && <5,
98 base >=4.2 && <5,
99− binary >= 0.6.4.0,
99+ binary >= 0.7.0.0,
100 blaze-html >= 0.5 && < 0.8,
100 blaze-html >= 0.5 && < 0.8,
101 blaze-markup,
101 blaze-markup,
102 bytestring,
102 bytestring,
@@ -179,7 +179,7 @@ Executable elm
179
179
180 Build-depends: aeson,
180 Build-depends: aeson,
181 base >=4.2 && <5,
181 base >=4.2 && <5,
182− binary >= 0.6.4.0,
182+ binary >= 0.7.0.0,
183 blaze-html >= 0.5 && < 0.8,
183 blaze-html >= 0.5 && < 0.8,
184 blaze-markup,
184 blaze-markup,
185 bytestring,
185 bytestring,
@@ -224,7 +224,7 @@ Executable elm-doc
224 Build-depends: aeson,
224 Build-depends: aeson,
225 aeson-pretty,
225 aeson-pretty,
226 base >=4.2 && <5,
226 base >=4.2 && <5,
227− binary >= 0.6.4.0,
227+ binary >= 0.7.0.0,
228 bytestring,
228 bytestring,
229 cmdargs,
229 cmdargs,
230 containers >= 0.3,
230 containers >= 0.3,
@@ -239,35 +239,32 @@ Executable elm-doc
239 text,
239 text,
240 union-find
240 union-find
241
241
242−Test-Suite test-elm
242+Test-Suite compiler-tests
243 Type: exitcode-stdio-1.0
243 Type: exitcode-stdio-1.0
244− Hs-Source-Dirs: tests, compiler
244+ Hs-Source-Dirs: tests/hs, compiler
245− Main-is: Main.hs
245+ Main-is: CompilerTest.hs
246 other-modules: Tests.Compiler
246 other-modules: Tests.Compiler
247 Tests.Property
247 Tests.Property
248 Tests.Property.Arbitrary
248 Tests.Property.Arbitrary
249 SourceSyntax.Helpers
249 SourceSyntax.Helpers
250 SourceSyntax.Literal
250 SourceSyntax.Literal
251 SourceSyntax.PrettyPrint
251 SourceSyntax.PrettyPrint
252− build-depends: base,
253− directory,
254− Elm,
255− test-framework,
252+ build-depends: test-framework,
256 test-framework-hunit,
253 test-framework-hunit,
257 test-framework-quickcheck2 >= 0.3,
254 test-framework-quickcheck2 >= 0.3,
258 HUnit,
255 HUnit,
259− pretty,
260 QuickCheck >= 2 && < 3,
256 QuickCheck >= 2 && < 3,
261− filemanip,
262 aeson,
257 aeson,
263 base >=4.2 && <5,
258 base >=4.2 && <5,
264− binary >= 0.6.4.0,
259+ binary >= 0.7.0.0,
265 blaze-html == 0.5.* || == 0.6.*,
260 blaze-html == 0.5.* || == 0.6.*,
266 blaze-markup == 0.5.1.*,
261 blaze-markup == 0.5.1.*,
267 bytestring,
262 bytestring,
268 cmdargs,
263 cmdargs,
269 containers >= 0.3,
264 containers >= 0.3,
270 directory,
265 directory,
266+ Elm,
267+ filemanip,
271 filepath,
268 filepath,
272 indents,
269 indents,
273 language-ecmascript >=0.15 && < 1.0,
270 language-ecmascript >=0.15 && < 1.0,
@@ -280,3 +277,13 @@ Test-Suite test-elm
280 transformers >= 0.2,
277 transformers >= 0.2,
281 union-find,
278 union-find,
282 unordered-containers
279 unordered-containers
280+
281+Test-Suite lib-tests
282+ Type: exitcode-stdio-1.0
283+ Hs-Source-Dirs: tests/hs
284+ Main-is: LibTest.hs
285+ build-depends: base,
286+ directory,
287+ Elm,
288+ filepath,
289+ process >= 1.2
IOnew file+1

Submodule changed.

README.md+11−46
@@ -4,55 +4,20 @@ Learn about the Elm programming language at [elm-lang.org](http://elm-lang.org/)
4
4
5## Install
5## Install
6
6
7−**Arch Linux** &mdash; follow [these directions](https://github.com/elm-lang/Elm/wiki/Installing-Elm#arch-linux) and then
7+Follow [these instructions][installer] if you just want to use Elm. To build
8−jump to the [My First Project](#my-first-project) section.
8+the compiler from source, run the following commands:
9−<br/>
10−**OS X 10.9 or XCode 5** &mdash; follow
11−[these directions](http://justtesting.org/post/64947952690/the-glasgow-haskell-compiler-ghc-on-os-x-10-9)
12−before continuing with the platform agnostic directions below.
13
9
14−**Platform Agnostic** &mdash;
10+ [installer]: https://github.com/elm-lang/elm-platform/blob/master/README.md#elm-platform
15−download the [Haskell Platform 2012.2.0.0 or later](http://hackage.haskell.org/platform/).
16−Once the Haskell Platform is installed:
17
11
18− cabal update
12+```bash
19− cabal install elm
13+git clone https://github.com/elm-lang/Elm.git
20− cabal install elm-server
14+cd Elm
15+cabal configure
16+cabal build
17+```
21
18
22−## Use
19+This will build the compiler in `/dist/build/elm/elm` but it will not be on
23−
20+your PATH.
24−To use `elm` and `elm-server` you may need to add a new directory to your PATH.
25−
26−Cabal should tell you where your executables are located upon
27−successful installation. It'll be something like `/home/evan/.cabal/bin`
28−which you should append to your PATH variable.
29−See this tutorial if you are new to changing your PATH in
30−[Unix/Linux](http://www.cyberciti.biz/faq/unix-linux-adding-path/).
31−
32−## My First Project
33−
34−Now we will create a simple Elm project.
35−The following commands will set-up a very basic project and start the Elm server.
36−
37− mkdir helloElm
38− cd helloElm
39− printf "import Mouse\n\nmain = lift asText Mouse.position" > Main.elm
40− elm-server
41−
42−The first two commands create a new directory and navigate into it. The `printf`
43−commands place a simple program into `Main.elm`. Do this manually if you do not
44−have `printf`. The final command starts the Elm server at [localhost:8000](http://localhost:8000/),
45−allowing you to navigate to `Main.elm` and see your first program in action.
46−
47−#### Final Notes
48−
49−The `elm` package provides
50−[some utility functions](http://hackage.haskell.org/package/Elm) for
51−working with Elm in Haskell. This can be useful for creating tooling
52−for Elm, and has been useful for projects like
53−[the website](http://elm-lang.org/) and
54−[`elm-get`](https://github.com/elm-lang/elm-get). Email the list if you
55−want to rely on these functions!
56
21
57If you are stuck, email
22If you are stuck, email
58[the list](https://groups.google.com/forum/?fromgroups#!forum/elm-discuss)
23[the list](https://groups.google.com/forum/?fromgroups#!forum/elm-discuss)
automatonnew file+1

Submodule changed.

libraries/Array.elm+61−75
@@ -1,23 +1,23 @@
1module Array where
1module Array where
2
2
3−{-| A library for immutable arrays. The elements in an array must have the same
3+{-| A library for fast immutable arrays. The elements in an array must have the
4−type. The arrays are implemented in Relaxed Radix Balanced-Trees for fast
4+same type. The arrays are implemented in Relaxed Radix Balanced-Trees for fast
5−reads, updates, and concatenation.
5+reads, updates, and appends.
6
6
7−If you use more then one map or zip function on an array, consider turning it
7+# Creating Arrays
8−into a list before operating on it, and then turning it back into an array.
8+@docs empty, repeat, initialize, fromList
9
9
10# Basics
10# Basics
11−@docs empty, length, get, getMaybe, getSafe
11+@docs length, push, append
12
12
13−# Putting Arrays Together
13+# Get and Set
14−@docs fill, fromList, concat, set, updates, push
14+@docs get, getMaybe, getWithDefault, set
15
15
16# Taking Arrays Apart
16# Taking Arrays Apart
17−@docs toList, toIndexedList, indices, slice
17+@docs toList, toIndexedList, slice
18
18
19−# Mapping, folding, zipping
19+# Mapping and Folding
20−@docs map, indexedMap, foldl, foldr, zip, zipWith
20+@docs map, indexedMap, foldl, foldr
21-}
21-}
22
22
23import Native.Array
23import Native.Array
@@ -27,17 +27,29 @@ import List
27
27
28data Array a = Array
28data Array a = Array
29
29
30−{-| Fills an array with a given length and a default element.
30+{-| Initialize an array. `initialize n f` creates an array of length `n` with
31+the element at index `i` initialized to the result of `(f i)`.
31
32
32− fill 3 5 == fromList [5,5,5]
33+ initialize 4 id == fromList [0,1,2,3]
34+ initialize 4 (\n -> n*n) == fromList [0,1,4,9]
35+ initialize 4 (always 0) == fromList [0,0,0,0]
33-}
36-}
34−fill : Int -> a -> Array a
37+initialize : Int -> (Int -> a) -> Array a
35−fill len e = fromList <| List.map (always e) [1..len]
38+initialize = Native.Array.initialize
39+
40+{-| Creates an array with a given length, filled with a default element.
41+
42+ repeat 5 0 == fromList [0,0,0,0,0]
43+ repeat 3 "cat" == fromList ["cat","cat","cat"]
44+
45+Notice that `repeat 3 x` is the same as `initialize 3 (always x)`.
46+-}
47+repeat : Int -> a -> Array a
48+repeat n e = initialize n (always e)
36
49
37−-- TODO: make this a native function.
38{-| Create an array from a list. -}
50{-| Create an array from a list. -}
39fromList : [a] -> Array a
51fromList : [a] -> Array a
40−fromList = List.foldl (Native.Array.push) Native.Array.empty
52+fromList = Native.Array.fromList
41
53
42{-| Create a list of elements from an array.
54{-| Create a list of elements from an array.
43
55
@@ -46,24 +58,19 @@ fromList = List.foldl (Native.Array.push) Native.Array.empty
46toList : Array a -> [a]
58toList : Array a -> [a]
47toList = Native.Array.toList
59toList = Native.Array.toList
48
60
49−{-| Create a list of the possible indices of an array.
50−
51− indices (fromList [3,5,8] == [0,1,2])
52−-}
53−indices : Array a -> [Int]
54−indices a = [0..Native.Array.length a - 1]
55−
56-- TODO: make this a native function.
61-- TODO: make this a native function.
57−{-| Create a list of tuples (Index, Element) from an array.
62+{-| Create an indexed list from an array. Each element of the array will be
63+paired with its index.
58
64
59− toIndexedList (fromList [3,5,8]) == [(0,3), (1,5), (2,8)]
65+ toIndexedList (fromList ["cat","dog"]) == [(0,"cat"), (1,"dog")]
60-}
66-}
61toIndexedList : Array a -> [(Int, a)]
67toIndexedList : Array a -> [(Int, a)]
68+toIndexedList array =
62−toIndexedList a = List.zip (indices a) (Native.Array.toList a)
69+ List.zip [ 0 .. Native.Array.length array - 1 ] (Native.Array.toList array)
63
70
64{-| Apply a function on every element in an array.
71{-| Apply a function on every element in an array.
65
72
66− map (\x -> x*x) (fromList [1,2,3]) == fromList [1,4,9]
73+ map sqrt (fromList [1,4,9]) == fromList [1,2,3]
67-}
74-}
68map : (a -> b) -> Array a -> Array b
75map : (a -> b) -> Array a -> Array b
69map = Native.Array.map
76map = Native.Array.map
@@ -77,35 +84,18 @@ indexedMap = Native.Array.indexedMap
77
84
78{-| Reduce an array from the left.
85{-| Reduce an array from the left.
79
86
80− foldl (+) 0 (fill 3 5) == 15
87+ foldl (::) [] (fromList [1,2,3]) == [3,2,1]
81-}
88-}
82foldl : (a -> b -> b) -> b -> Array a -> b
89foldl : (a -> b -> b) -> b -> Array a -> b
83foldl = Native.Array.foldl
90foldl = Native.Array.foldl
84
91
85{-| Reduce an array from the right.
92{-| Reduce an array from the right.
86
93
87− foldr (::) [] (fromList [1,2,3]) == [3,2,1]
94+ foldr (+) 0 (repeat 3 5) == 15
88-}
95-}
89foldr : (a -> b -> b) -> b -> Array a -> b
96foldr : (a -> b -> b) -> b -> Array a -> b
90foldr = Native.Array.foldr
97foldr = Native.Array.foldr
91
98
92−{-| Zip the elements of two arrays via a tuple into a new array. If one array is
93−longer, the extra elements are dropped.
94−
95− zip (fromList [1,2,3,4]) (fromList [0,0,0]) = fromList [(1,0), (2,0), (3,0)]
96−-}
97−zip : Array a -> Array b -> Array (a,b)
98−zip = zipWith (,)
99−
100−{-| Zips the elements of two arrays via a function into a new array. If one array
101−is longer, the extra elements are dropped.
102−
103− zipWith (+) (fill 3 5) (fill 5 8) == fill 3 13
104−-}
105−zipWith : (a -> b -> c) -> Array a -> Array b -> Array c
106−zipWith f a b =
107− fromList <| List.zipWith f (Native.Array.toList a) (Native.Array.toList b)
108−
109{-| Return an empty array.
99{-| Return an empty array.
110
100
111 length empty == 0
101 length empty == 0
@@ -121,7 +111,7 @@ push : a -> Array a -> Array a
121push = Native.Array.push
111push = Native.Array.push
122
112
123{-| Return the element at the index. Breaks, if index is out of range. If the
113{-| Return the element at the index. Breaks, if index is out of range. If the
124−array length is unkown, use safeGet oder getWithDefault.
114+array length is unkown, use withDefaultGet oder getWithDefault.
125
115
126 get 2 (A.fromList [3,2,1]) == 1
116 get 2 (A.fromList [3,2,1]) == 1
127-}
117-}
@@ -130,46 +120,42 @@ get = Native.Array.get
130
120
131{-| Return Just the element at the index or Nothing if the index is out of range.
121{-| Return Just the element at the index or Nothing if the index is out of range.
132
122
133− getMaybe 2 (A.fromList [3,2,1]) == Just 2
123+ getMaybe 2 (fromList [3,2,1]) == Just 2
134− getMaybe 5 (A.fromList [3,2,1]) == Nothing
124+ getMaybe 5 (fromList [3,2,1]) == Nothing
125+ getMaybe -1 (fromList [3,2,1]) == Nothing
135-}
126-}
136getMaybe : Int -> Array a -> Maybe a
127getMaybe : Int -> Array a -> Maybe a
128+getMaybe i array =
137−getMaybe i array = if Native.Array.length array > i
129+ if 0 <= i && i < Native.Array.length array
138− then Just (Native.Array.get i array)
130+ then Just (Native.Array.get i array)
139− else Nothing
131+ else Nothing
140
132
141{-| Get the element at the index. If the index is out of range, the given default
133{-| Get the element at the index. If the index is out of range, the given default
142element is returned.
134element is returned.
143
135
144− getSafe 0 2 (A.fromList [3,2,1]) == 1
136+ getWithDefault 0 2 (fromList [3,2,1]) == 1
145− getSafe 0 5 (A.fromList [3,2,1]) == 0
137+ getWithDefault 0 5 (fromList [3,2,1]) == 0
146-}
138-}
147−getSafe : a -> Int -> Array a -> a
139+getWithDefault : a -> Int -> Array a -> a
140+getWithDefault default i array =
148−getSafe default i array = if Native.Array.length array > i
141+ if 0 <= i && i < Native.Array.length array
149− then Native.Array.get i array else default
142+ then Native.Array.get i array
143+ else default
150
144
151−{-| Set the element at the index. Returns the updated array, or if the index is
145+{-| Set the element at a particular index. Returns an updated array.
152−out of range, the unaltered array.
146+If the index is out of range, the array is unaltered.
153
147
154 set 1 7 (fromList [1,2,3]) == fromList [1,7,3]
148 set 1 7 (fromList [1,2,3]) == fromList [1,7,3]
155-}
149-}
156set : Int -> a -> Array a -> Array a
150set : Int -> a -> Array a -> Array a
157set = Native.Array.set
151set = Native.Array.set
158
152
159−{-| Update an array with a a list tuples, wherein the first Int is the index.
160−
161− updates [(1,7),(2,8)] (fill 3 1) == fromList [1,7,8]
162−-}
163−updates : [(Int, a)] -> Array a -> Array a
164−updates us array = List.foldl (uncurry Native.Array.set) array us
165−
166{-| Slice an array given a range. The selection is inclusive, so the last
153{-| Slice an array given a range. The selection is inclusive, so the last
167element in the selection will also be in the new array. This may change in the
154element in the selection will also be in the new array. This may change in the
168−future.
169−You can select from the end by giving a negative Int.
155+future. You can select from the end by giving a negative Int.
170
156
171− slice 1 2 (fromList [0,1,2,3,4]) == fromList [1,2]
157+ slice 1 2 (fromList [0,1,2,3,4]) == fromList [1,2]
172− slice 1 -2 (fromList [0,1,2,3,4]) == fromList [1,2,3]
158+ slice 1 -2 (fromList [0,1,2,3,4]) == fromList [1,2,3]
173 slice -3 -2 (fromList [0,1,2,3,4]) == fromList [2,3]
159 slice -3 -2 (fromList [0,1,2,3,4]) == fromList [2,3]
174-}
160-}
175slice : Int -> Int -> Array a -> Array a
161slice : Int -> Int -> Array a -> Array a
@@ -182,9 +168,9 @@ slice = Native.Array.slice
182length : Array a -> Int
168length : Array a -> Int
183length = Native.Array.length
169length = Native.Array.length
184
170
185−{-| Concat two arrays to a new one.
171+{-| Append two arrays to a new one.
186
172
187− concat (fill 3 1) (fill 4 2) == fromList [1,1,1,2,2,2,2]
173+ append (array 2 42) (array 3 81) == fromList [42,42,81,81,81]
188-}
174-}
189−concat : Array a -> Array a -> Array a
175+append : Array a -> Array a -> Array a
190−concat = Native.Array.concat
176+append = Native.Array.append
libraries/Graphics/Input.elm+1−1
@@ -89,7 +89,7 @@ button = Native.Graphics.Input.button
89
89
90 prettyButton : Element
90 prettyButton : Element
91 prettyButton =
91 prettyButton =
92− customButton click.handle
92+ customButton click.handle ()
93 (image 100 40 "/button_up.jpg")
93 (image 100 40 "/button_up.jpg")
94 (image 100 40 "/button_hover.jpg")
94 (image 100 40 "/button_hover.jpg")
95 (image 100 40 "/button_down.jpg")
95 (image 100 40 "/button_down.jpg")
libraries/Native/Array.js+133−32
@@ -25,18 +25,21 @@ Elm.Native.Array.make = function(elm) {
25 var empty = { ctor:"_Array", height:0, table:new Array() };
25 var empty = { ctor:"_Array", height:0, table:new Array() };
26
26
27 // Gets the value at index i recursively.
27 // Gets the value at index i recursively.
28− function get(i, a) {
28+ function get(i, array) {
29− if (a.height == 0) {
30− if (i < a.table.length) {
29+ if (i < 0 || i >= length(array)) {
31− return a.table[i];
32− } else {
33− throw new Error("Index "+ i +" is out of range. Check the length of your array first or use getSafe or getMaybe.");
30+ throw new Error("Index " + i + " is out of range. Check the length of " +
31+ "your array first or use getMaybe or getWithDefault.");
34 }
32 }
33+ return unsafeGet(i, array);
35− }
34+ }
36
35
36+ function unsafeGet(i, array) {
37+ if (array.height == 0) {
38+ return array.table[i];
39+ }
37− var slot = getSlot(i, a);
40+ var slot = getSlot(i, array);
38− var sub = slot > 0 ? a.lengths[slot-1] : 0;
41+ var offset = slot > 0 ? array.lengths[slot-1] : 0;
39− return get(i - sub, a.table[slot]);
42+ return unsafeGet(i - offset, array.table[slot]);
40 }
43 }
41
44
42 // Sets the value at the index i. Only the nodes leading to i will get
45 // Sets the value at the index i. Only the nodes leading to i will get
@@ -58,6 +61,102 @@ Elm.Native.Array.make = function(elm) {
58 return newA;
61 return newA;
59 }
62 }
60
63
64+ function initialize(len, f) {
65+ if (len == 0) { return empty; }
66+ var h = Math.floor(Math.log(len)/Math.log(M));
67+ return initialize_(f, h, 0, len);
68+ }
69+
70+ function initialize_(f, h, from, to) {
71+ if (h == 0) {
72+ var table = new Array((to - from) % (M + 1));
73+ for (var i = 0; i < table.length; i++) {
74+ table[i] = f(from + i);
75+ }
76+ return { ctor:"_Array", height:0, table:table };
77+ }
78+
79+ var step = Math.pow(M, h);
80+ var table = new Array(Math.ceil((to - from) / step));
81+ var lengths = new Array(table.length);
82+ for (var i = 0; i < table.length; i++) {
83+ table[i] = initialize_( f, h - 1, from + (i * step)
84+ , Math.min(from + ((i + 1) * step), to));
85+ lengths[i] = length(table[i]) + (i > 0 ? lengths[i-1] : 0);
86+ }
87+ return { ctor:"_Array", height:h, table:table, lengths:lengths };
88+ }
89+
90+ function fromList(list) {
91+ if (list == List.Nil) { return empty; }
92+
93+ // Allocate M sized blocks (table) and write list elements to it.
94+ var table = new Array(M);
95+ var nodes = new Array();
96+ var i = 0;
97+
98+ while (list.ctor !== '[]') {
99+ table[i] = list._0;
100+ list = list._1;
101+ i++;
102+
103+ // table is full, so we can push a leaf containing it into the
104+ // next node.
105+ if (i == M) {
106+ fromListPush({ ctor:"_Array", height:0, table:table }
107+ , nodes);
108+ table = new Array(M);
109+ i = 0;
110+ }
111+ }
112+
113+ // Maybe there is something left on the table.
114+ if (i > 0) {
115+ fromListPush({ ctor:"_Array", height:0, table:table.splice(0,i) }
116+ , nodes);
117+ }
118+
119+ // Go through all of the nodes and eventually push them into higher nodes.
120+ for (var h = 0; h < nodes.length - 1; h++) {
121+ if (nodes[h].table.length > 0) {
122+ fromListPush(nodes[h], nodes);
123+ }
124+ }
125+
126+ var head = nodes[nodes.length - 1];
127+ if (head.height > 0 && head.table.length == 1) {
128+ return head.table[0];
129+ } else {
130+ return head;
131+ }
132+ }
133+
134+ // Push a node into a higher node as a child.
135+ function fromListPush(toPush, nodes) {
136+ var h = toPush.height;
137+
138+ // Maybe the node on this height does not exist.
139+ if (nodes.length == h) {
140+ nodes.push({ ctor:"_Array", height:h + 1
141+ , table:new Array()
142+ , lengths:new Array() });
143+ }
144+
145+ nodes[h].table.push(toPush);
146+ var len = length(toPush);
147+ if (nodes[h].lengths.length > 0) {
148+ len += nodes[h].lengths[nodes[h].lengths.length - 1];
149+ }
150+ nodes[h].lengths.push(len);
151+
152+ if (nodes[h].table.length == M) {
153+ fromListPush(nodes[h], nodes);
154+ nodes[h] = { ctor:"_Array", height:h + 1
155+ , table:new Array()
156+ , lengths:new Array() };
157+ }
158+ }
159+
61 // Pushes an item via push_ to the bottom right of a tree.
160 // Pushes an item via push_ to the bottom right of a tree.
62 function push(item, a) {
161 function push(item, a) {
63 var pushed = push_(item, a);
162 var pushed = push_(item, a);
@@ -65,7 +164,7 @@ Elm.Native.Array.make = function(elm) {
65 return pushed;
164 return pushed;
66 }
165 }
67
166
68− newTree = create(item, a.height);
167+ var newTree = create(item, a.height);
69 return siblise(a, newTree);
168 return siblise(a, newTree);
70 }
169 }
71
170
@@ -232,15 +331,15 @@ Elm.Native.Array.make = function(elm) {
232 return newA;
331 return newA;
233 }
332 }
234
333
235− // Concats two trees.
334+ // Appends two trees.
236− // TODO: Add support for concatting trees of different sizes. Current
335+ // TODO: Add support for appending trees of different sizes. Current
237− // behavior will just rise the lower tree and then concat them.
336+ // behavior will just rise the lower tree and then append them.
238− function concat(a, b) {
337+ function append(a,b) {
239− if (b.height > a.height) { return concat(parentise(a, b.height), b); }
338+ if (b.height > a.height) { return append(parentise(a, b.height), b); }
240− if (a.height > b.height) { return concat(a, parentise(b, a.height)); }
339+ if (a.height > b.height) { return append(a, parentise(b, a.height)); }
241− if (a.height == 0) { return concat(parentise(a, 1), parentise(b, 1)); }
340+ if (a.height == 0) { return append(parentise(a, 1), parentise(b, 1)); }
242
341
243− var c = concat_(a, b);
342+ var c = append_(a, b);
244 if (c[1].table.length > 0) {
343 if (c[1].table.length > 0) {
245 return siblise(c[0], c[1]);
344 return siblise(c[0], c[1]);
246 } else {
345 } else {
@@ -249,9 +348,9 @@ Elm.Native.Array.make = function(elm) {
249 }
348 }
250
349
251 // Returns an array of two nodes. The second node _may_ be empty. This case
350 // Returns an array of two nodes. The second node _may_ be empty. This case
252− // needs to be handled by the function, that called concat_. May be only
351+ // needs to be handled by the function, that called append_. May be only
253 // called for trees with an minimal height of 1.
352 // called for trees with an minimal height of 1.
254− function concat_(a, b) {
353+ function append_(a, b) {
255 if (a.height == 1) {
354 if (a.height == 1) {
256 // Check if balancing is needed and return based on that.
355 // Check if balancing is needed and return based on that.
257 var toRemove = calcToRemove(a, b);
356 var toRemove = calcToRemove(a, b);
@@ -262,18 +361,18 @@ Elm.Native.Array.make = function(elm) {
262 return shuffle(a, b, toRemove);
361 return shuffle(a, b, toRemove);
263 }
362 }
264
363
265− var concated = concat_(botRight(a), botLeft(b));
364+ var appended = append_(botRight(a), botLeft(b));
266 a = nodeCopy(a), b = nodeCopy(b);
365 a = nodeCopy(a), b = nodeCopy(b);
267
366
268 // Adjust the bottom right side of the new tree.
367 // Adjust the bottom right side of the new tree.
269− a.table[a.table.length - 1] = concated[0];
368+ a.table[a.table.length - 1] = appended[0];
270− a.lengths[a.lengths.length - 1] = length(concated[0])
369+ a.lengths[a.lengths.length - 1] = length(appended[0])
271 a.lengths[a.lengths.length - 1] += a.lengths.length > 1 ? a.lengths[a.lengths.length - 2] : 0;
370 a.lengths[a.lengths.length - 1] += a.lengths.length > 1 ? a.lengths[a.lengths.length - 2] : 0;
272
371
273 // Adjust the bottom left side of the new tree.
372 // Adjust the bottom left side of the new tree.
274− if (concated[1].table.length > 0) {
373+ if (appended[1].table.length > 0) {
275− b.table[0] = concated[1];
374+ b.table[0] = appended[1];
276− b.lengths[0] = length(concated[1]);
375+ b.lengths[0] = length(appended[1]);
277 for (var i = 1, len = length(b.table[0]); i < b.lengths.length; i++) {
376 for (var i = 1, len = length(b.table[0]); i < b.lengths.length; i++) {
278 len += length(b.table[i]);
377 len += length(b.table[i]);
279 b.lengths[i] = len;
378 b.lengths[i] = len;
@@ -423,11 +522,11 @@ Elm.Native.Array.make = function(elm) {
423 }
522 }
424
523
425 // Returns how many items are in the tree.
524 // Returns how many items are in the tree.
426− function length(a) {
525+ function length(array) {
427− if (a.height == 0) {
526+ if (array.height == 0) {
428− return a.table.length;
527+ return array.table.length;
429 } else {
528 } else {
430− return a.lengths[a.lengths.length - 1];
529+ return array.lengths[array.lengths.length - 1];
431 }
530 }
432 }
531 }
433
532
@@ -474,8 +573,10 @@ Elm.Native.Array.make = function(elm) {
474
573
475 Elm.Native.Array.values = {
574 Elm.Native.Array.values = {
476 empty:empty,
575 empty:empty,
576+ fromList:fromList,
477 toList:toList,
577 toList:toList,
478− concat:F2(concat),
578+ initialize:F2(initialize),
579+ append:F2(append),
479 push:F2(push),
580 push:F2(push),
480 slice:F3(slice),
581 slice:F3(slice),
481 get:F2(get),
582 get:F2(get),
libraries/Native/Graphics/Input.js−29
@@ -134,13 +134,6 @@ Elm.Native.Graphics.Input.make = function(elm) {
134
134
135 btn.appendChild(btn.elm_up);
135 btn.appendChild(btn.elm_up);
136
136
137− var clicker = newNode('div');
138− clicker.style.width = btn.elm_up.style.width;
139− clicker.style.height = btn.elm_up.style.height;
140− clicker.style.position = 'absolute';
141− clicker.style.top = 0;
142− btn.appendChild(clicker);
143−
144 return btn;
137 return btn;
145 }
138 }
146
139
@@ -297,29 +290,7 @@ Elm.Native.Graphics.Input.make = function(elm) {
297 }));
290 }));
298 }
291 }
299
292
300− function mouseUpdate(event) {
301− var direction = field.selectionDirection === 'forward' ? 'Forward' : 'Backward';
302− elm.notify(field.elm_signal.id, field.elm_handler({
303− _:{},
304− string: field.value,
305− selection: {
306− _:{},
307− start: field.selectionStart,
308− end: field.selectionEnd,
309− direction: { ctor: direction }
310− },
311− }));
312− }
313− function mousedown(event) {
314− mouseUpdate(event);
315− elm.node.addEventListener('mouseup', mouseup);
316− }
317− function mouseup(event) {
318− mouseUpdate(event);
319− elm.node.removeEventListener('mouseup', mouseup)
320− }
321 field.addEventListener('input', inputUpdate);
293 field.addEventListener('input', inputUpdate);
322− field.addEventListener('mousedown', mousedown);
323 field.addEventListener('focus', function() {
294 field.addEventListener('focus', function() {
324 field.elm_hasFocus = true;
295 field.elm_hasFocus = true;
325 });
296 });
libraries/Native/Utils.js+13−8
@@ -30,11 +30,15 @@ Elm.Native.Utils.make = function(elm) {
30 function compare(x,y) { return { ctor: ord[cmp(x,y)+1] } }
30 function compare(x,y) { return { ctor: ord[cmp(x,y)+1] } }
31 function cmp(x,y) {
31 function cmp(x,y) {
32 var ord;
32 var ord;
33− if (typeof x !== 'object' || x instanceof String){
33+ if (typeof x !== 'object'){
34 return x === y ? EQ : x < y ? LT : GT;
34 return x === y ? EQ : x < y ? LT : GT;
35 }
35 }
36−
36+ else if (x.isChar){
37+ var a = x.toString();
38+ var b = y.toString();
39+ return a === b ? EQ : a < b ? LT : GT;
40+ }
37− if (x.ctor === "::" || x.ctor === "[]") {
41+ else if (x.ctor === "::" || x.ctor === "[]") {
38 while (true) {
42 while (true) {
39 if (x.ctor === "[]" && y.ctor === "[]") return EQ;
43 if (x.ctor === "[]" && y.ctor === "[]") return EQ;
40 if (x.ctor !== y.ctor) return x.ctor === '[]' ? LT : GT;
44 if (x.ctor !== y.ctor) return x.ctor === '[]' ? LT : GT;
@@ -44,8 +48,7 @@ Elm.Native.Utils.make = function(elm) {
44 y = y._1;
48 y = y._1;
45 }
49 }
46 }
50 }
47−
48− if (x.ctor.slice(0,6) === '_Tuple') {
51+ else if (x.ctor.slice(0,6) === '_Tuple') {
49 var n = x.ctor.slice(6) - 0;
52 var n = x.ctor.slice(6) - 0;
50 var err = 'cannot compare tuples with more than 6 elements.';
53 var err = 'cannot compare tuples with more than 6 elements.';
51 if (n === 0) return EQ;
54 if (n === 0) return EQ;
@@ -58,9 +61,11 @@ Elm.Native.Utils.make = function(elm) {
58 if (n >= 7) throw new Error('Comparison error: ' + err); } } } } } }
61 if (n >= 7) throw new Error('Comparison error: ' + err); } } } } } }
59 return EQ;
62 return EQ;
60 }
63 }
64+ else {
61− throw new Error('Comparison error: comparison is only defined on ints, ' +
65+ throw new Error('Comparison error: comparison is only defined on ints, ' +
62− 'floats, times, chars, strings, lists of comparable values, ' +
66+ 'floats, times, chars, strings, lists of comparable values, ' +
63− 'and tuples of comparable values.')
67+ 'and tuples of comparable values.');
68+ }
64 }
69 }
65
70
66
71
libraries/Signal.elm−3
@@ -31,10 +31,7 @@ the `Time` library.
31
31
32import Native.Signal
32import Native.Signal
33import List (foldr)
33import List (foldr)
34−
35import Basics (fst, snd, not)
34import Basics (fst, snd, not)
36−import Native.Error
37−import Maybe as M
38
35
39data Signal a = Signal
36data Signal a = Signal
40
37
runtime/Render/Element.js+8−2
@@ -31,6 +31,7 @@ function setProps(elem, e) {
31 a.style.display = 'block';
31 a.style.display = 'block';
32 a.style.position = 'absolute';
32 a.style.position = 'absolute';
33 e.style.position = 'relative';
33 e.style.position = 'relative';
34+ a.style.pointerEvents = 'auto';
34 e.appendChild(a);
35 e.appendChild(a);
35 }
36 }
36 if (props.hover.ctor !== '_Tuple0') {
37 if (props.hover.ctor !== '_Tuple0') {
@@ -45,8 +46,9 @@ function setProps(elem, e) {
45function addClick(e, handler) {
46function addClick(e, handler) {
46 e.style.pointerEvents = 'auto';
47 e.style.pointerEvents = 'auto';
47 e.elm_click_handler = handler;
48 e.elm_click_handler = handler;
48− function trigger() {
49+ function trigger(ev) {
49 e.elm_click_handler(Utils.Tuple0);
50 e.elm_click_handler(Utils.Tuple0);
51+ ev.stopPropagation();
50 }
52 }
51 e.elm_click_trigger = trigger;
53 e.elm_click_trigger = trigger;
52 e.addEventListener('click', trigger);
54 e.addEventListener('click', trigger);
@@ -63,14 +65,16 @@ function addHover(e, handler) {
63 e.elm_hover_handler = handler;
65 e.elm_hover_handler = handler;
64 e.elm_hover_count = 0;
66 e.elm_hover_count = 0;
65
67
66− function over() {
68+ function over(evt) {
67 if (e.elm_hover_count++ > 0) return;
69 if (e.elm_hover_count++ > 0) return;
68 e.elm_hover_handler(true);
70 e.elm_hover_handler(true);
71+ evt.stopPropagation();
69 }
72 }
70 function out(evt) {
73 function out(evt) {
71 if (e.contains(evt.toElement || evt.relatedTarget)) return;
74 if (e.contains(evt.toElement || evt.relatedTarget)) return;
72 e.elm_hover_count = 0;
75 e.elm_hover_count = 0;
73 e.elm_hover_handler(false);
76 e.elm_hover_handler(false);
77+ evt.stopPropagation();
74 }
78 }
75 e.elm_hover_over = over;
79 e.elm_hover_over = over;
76 e.elm_hover_out = out;
80 e.elm_hover_out = out;
@@ -232,6 +236,7 @@ function rawHtml(elem) {
232 }
236 }
233 document.body.removeChild(div);
237 document.body.removeChild(div);
234 div.style.visibility = 'visible';
238 div.style.visibility = 'visible';
239+ div.style.pointerEvents = 'auto';
235 return div;
240 return div;
236}
241}
237
242
@@ -375,6 +380,7 @@ function updateProps(node, curr, next) {
375 a.style.display = 'block';
380 a.style.display = 'block';
376 a.style.position = 'absolute';
381 a.style.position = 'absolute';
377 e.style.position = 'relative';
382 e.style.position = 'relative';
383+ a.style.pointerEvents = 'auto';
378 e.appendChild(a);
384 e.appendChild(a);
379 } else {
385 } else {
380 node.lastNode.href = props.href;
386 node.lastNode.href = props.href;
tests/elm/Test.elmnew file+28
@@ -0,0 +1,28 @@
1+module Main where
2+
3+import ElmTest.Assertion as A
4+import ElmTest.Run as R
5+import ElmTest.Runner.Console (runDisplay)
6+import ElmTest.Test (..)
7+
8+import IO.IO (..)
9+import IO.Runner (Request, Response)
10+import IO.Runner as Run
11+
12+import Test.String as String
13+import Test.Trampoline as Trampoline
14+import Test.Array as Array
15+
16+tests : [Test]
17+tests = String.tests ++ Trampoline.tests ++ Array.tests
18+
19+console : IO ()
20+console = runDisplay tests
21+
22+port requests : Signal [{ mPut : Maybe String
23+ , mExit : Maybe Int
24+ , mGet : Bool
25+ }]
26+port requests = Run.run responses console
27+
28+port responses : Signal (Maybe String)
tests/elm/Test/Array.elmnew file+47
@@ -0,0 +1,47 @@
1+module Test.Array (tests) where
2+
3+import List
4+import Array
5+
6+import ElmTest.Assertion (..)
7+import ElmTest.Test (..)
8+
9+tests : [Test]
10+tests =
11+ let creationTests = [ test "empty" <| assertEqual Array.empty (Array.fromList [])
12+ , test "initialize" <| assertEqual (Array.initialize 4 id) (Array.fromList [0,1,2,3])
13+ , test "initialize 2" <| assertEqual (Array.initialize 4 (\n -> n*n)) (Array.fromList [0,1,4,9])
14+ , test "initialize 3" <| assertEqual (Array.initialize 4 (always 0)) (Array.fromList [0,0,0,0])
15+ , test "initialize Empty" <| assertEqual (Array.initialize 0 id) Array.empty
16+ , test "initialize 4" <| assertEqual (Array.initialize 2 (always 0)) (Array.fromList [0,0])
17+ , test "repeat" <| assertEqual (Array.repeat 5 40) (Array.fromList [40,40,40,40,40])
18+ , test "repeat 2" <| assertEqual (Array.repeat 5 0) (Array.fromList [0,0,0,0,0])
19+ , test "repeat 3" <| assertEqual (Array.repeat 3 "cat") (Array.fromList ["cat","cat","cat"])
20+ , test "fromList" <| assertEqual (Array.fromList []) Array.empty
21+ ]
22+ basicsTests = [ test "length" <| assertEqual (Array.length (Array.fromList [1,2,3])) 3
23+ , test "length - Long" <| assertEqual (Array.length (Array.repeat 10000 0)) 10000
24+ , test "push" <| assertEqual (Array.push 3 (Array.fromList [1,2])) (Array.fromList [1,2,3])
25+ , test "append" <| assertEqual (Array.toList <| Array.append (Array.repeat 2 42) (Array.repeat 3 81)) ([42,42,81,81,81])
26+ ]
27+ getAndSetTests = [ test "get" <| assertEqual (Array.get 2 (Array.fromList [3,2,1])) 1
28+ , test "getMaybe" <| assertEqual (Array.getMaybe 1 (Array.fromList [3,2,1])) (Just 2)
29+ , test "getMaybe 2" <| assertEqual (Array.getMaybe 5 (Array.fromList [3,2,1])) Nothing
30+ , test "getMaybe 3" <| assertEqual (Array.getMaybe -1 (Array.fromList [3,2,1])) Nothing
31+ , test "getWithDefault" <| assertEqual (Array.getWithDefault 0 2 (Array.fromList [3,2,1])) 1
32+ , test "getWithDefault 2" <| assertEqual (Array.getWithDefault 0 5 (Array.fromList [3,2,1])) 0
33+ , test "set" <| assertEqual (Array.set 1 7 (Array.fromList [1,2,3])) (Array.fromList [1,7,3])
34+ ]
35+ takingArraysApartTests = [ test "toList" <| assertEqual (Array.toList (Array.fromList [3,5,8])) [3,5,8]
36+ , test "toIndexedList" <| assertEqual (Array.toIndexedList (Array.fromList ["cat","dog"])) [(0,"cat"), (1,"dog")]
37+ , test "slice" <| assertEqual (Array.slice 1 2 (Array.fromList [0,1,2,3,4])) (Array.fromList [1,2])
38+ , test "slice 2" <| assertEqual (Array.slice 1 -2 (Array.fromList [0,1,2,3,4])) (Array.fromList [1,2,3])
39+ , test "slice 3" <| assertEqual (Array.slice -3 -2 (Array.fromList [0,1,2,3,4])) (Array.fromList [2,3])
40+ ]
41+ mappingAndFoldingTests = [ test "map" <| assertEqual (Array.map sqrt (Array.fromList [1,4,9])) (Array.fromList [1,2,3])
42+ , test "indexedMap" <| assertEqual (Array.indexedMap (*) (Array.fromList [5,5,5])) (Array.fromList [0,5,10])
43+ , test "foldl" <| assertEqual (Array.foldl (::) [] (Array.fromList [1,2,3])) [1,2,3]
44+ , test "foldr" <| assertEqual (Array.foldr (+) 0 (Array.repeat 3 5)) 15
45+ , test "foldl 2" <| assertEqual (Array.foldr (::) [] (Array.fromList [1,2,3])) [3,2,1]
46+ ]
47+ in List.concat [creationTests, basicsTests, getAndSetTests, takingArraysApartTests, mappingAndFoldingTests]
tests/elm/Test/String.elmnew file+26
@@ -0,0 +1,26 @@
1+module Test.String (tests) where
2+
3+import List
4+import String (..)
5+
6+import ElmTest.Assertion (..)
7+import ElmTest.Test (..)
8+
9+tests : [Test]
10+tests =
11+ let isEmptyTests = [test "empty is empty" <| assert <| isEmpty "",
12+ test "not empty" <| assert <| not . isEmpty <| "the world"]
13+ lengthTest = test "length of innumerable" <| assertEqual 11 (length "innumerable")
14+ reverseTest = test "reverse test" <| assertEqual "desserts" (reverse "stressed")
15+ repeatTest = test "repeat test" <| assertEqual "hahaha" (repeat 3 "ha")
16+ unconsTests = [test "nonempty uncons" <| assertEqual (Just ('a',"bc")) (uncons "abc"),
17+ test "empty uncons" <| assertEqual Nothing (uncons "")]
18+ appendTest = test "append test" <| assertEqual "butterfly" (append "butter" "fly")
19+ concatTest = test "concat test" <| assertEqual "nevertheless" (concat ["never","the","less"])
20+ splitTests = [test "split commas" <| assertEqual ["cat","dog","cow"] (split "," "cat,dog,cow"),
21+ test "split slashes"<| assertEqual ["home","evan","Desktop", ""] (split "/" "home/evan/Desktop/")]
22+ joinTests = [test "join spaces" <| assertEqual "cat dog cow" (join " " ["cat","dog","cow"]),
23+ test "join slashes" <| assertEqual "home/evan/Desktop" (join "/" ["home","evan","Desktop"])]
24+
25+ endsWithTest = test "endsWith Check" (assert <| endsWith "h" "th")
26+ in List.concat [isEmptyTests, [lengthTest, reverseTest, repeatTest], unconsTests, [appendTest, concatTest], splitTests, joinTests, [endsWithTest]]
tests/elm/Test/Trampoline.elmnew file+29
@@ -0,0 +1,29 @@
1+module Test.Trampoline (tests) where
2+
3+import Trampoline (..)
4+
5+import ElmTest.Assertion (..)
6+import ElmTest.Test (..)
7+
8+badSum : Int -> Int
9+badSum n =
10+ let loop x acc =
11+ case x of
12+ 0 -> acc
13+ _ -> loop (x-1) (acc+x)
14+ in loop n 0
15+
16+goodSum : Int -> Int
17+goodSum n =
18+ let sumT x acc =
19+ case x of
20+ 0 -> Done acc
21+ _ -> Continue (\_ -> sumT (x-1) (acc+x))
22+ in trampoline <| sumT n 0
23+
24+tests : [Test]
25+tests =
26+ let mkLoopCheck n = test ("Equivalent Loop Check #"++ show n) (assertEqual (badSum n) (goodSum n))
27+ loopChecks = map mkLoopCheck [0..25]
28+ noStackOverflow = test "Trampoline Deep Recursion Test" (assertEqual 500000500000 (goodSum 1000000))
29+ in noStackOverflow :: loopChecks
tests/Main.hs → tests/hs/CompilerTest.hsrenamed

The content is the same.

tests/hs/LibTest.hsnew file+27
@@ -0,0 +1,27 @@
1+module Main where
2+
3+import System.Directory
4+import System.Exit
5+import System.FilePath
6+import System.Process
7+
8+import Elm.Internal.Paths as Elm
9+
10+main :: IO ()
11+main = do
12+ top <- getCurrentDirectory
13+ let ioScript s = top</>"IO"</>s
14+ runCmd "git submodule init"
15+ runCmd "npm install jsdom"
16+ setCurrentDirectory $ top</>"tests"</>"elm"
17+ runCmd $ concat [top</>"dist"</>"build"</>"elm"</>"elm --make --only-js --src-dir=" , top</>"automaton", " --src-dir=", top</>"IO", " --src-dir=", top</>"Elm-Test", " Test.elm"]
18+ runCmd $ unwords ["cat ", ioScript "prescript.js", Elm.runtime, "build"</>"Test.js", ioScript "handler.js", "> exe.js"]
19+ exitWith =<< waitForProcess =<< (runCommand "node exe.js")
20+ where runCmd cmd = do
21+ putStrLn cmd
22+ exitCode <- waitForProcess =<< runCommand cmd
23+ case exitCode of
24+ ExitSuccess -> return ()
25+ ExitFailure _ -> error "something went wrong"
26+
27+
tests/Tests/Compiler.hs → tests/hs/Tests/Compiler.hsrenamed

The content is the same.

tests/Tests/Property.hs → tests/hs/Tests/Property.hsrenamed

The content is the same.

tests/Tests/Property/Arbitrary.hs → tests/hs/Tests/Property/Arbitrary.hsrenamed

The content is the same.

tests/test-files/bad/BBTArgs → tests/hs/test-files/bad/BBTArgsrenamed

The content is the same.

tests/test-files/bad/InfiniteType.elm → tests/hs/test-files/bad/InfiniteType.elmrenamed

The content is the same.

tests/test-files/bad/NonElementMain.elm → tests/hs/test-files/bad/NonElementMain.elmrenamed

The content is the same.

tests/test-files/bad/Strings/ExtraClose.elm → tests/hs/test-files/bad/Strings/ExtraClose.elmrenamed

The content is the same.

tests/test-files/good/AliasSubstitution.elm → tests/hs/test-files/good/AliasSubstitution.elmrenamed

The content is the same.

tests/test-files/good/NoExpressions.elm → tests/hs/test-files/good/NoExpressions.elmrenamed

The content is the same.

tests/test-files/good/Otherwise.elm → tests/hs/test-files/good/Otherwise.elmrenamed

The content is the same.

tests/test-files/good/Ports.elm → tests/hs/test-files/good/Ports.elmrenamed

The content is the same.

tests/test-files/good/QuotesAndComments.elm → tests/hs/test-files/good/QuotesAndComments.elmrenamed

The content is the same.

tests/test-files/good/Soundness/Apply.elm → tests/hs/test-files/good/Soundness/Apply.elmrenamed

The content is the same.

tests/test-files/good/Soundness/ApplyAnnotated.elm → tests/hs/test-files/good/Soundness/ApplyAnnotated.elmrenamed

The content is the same.

tests/test-files/good/Soundness/Id.elm → tests/hs/test-files/good/Soundness/Id.elmrenamed

The content is the same.

tests/test-files/good/Soundness/IdAnnotated.elm → tests/hs/test-files/good/Soundness/IdAnnotated.elmrenamed

The content is the same.

tests/test-files/good/Soundness/TrickyId.elm → tests/hs/test-files/good/Soundness/TrickyId.elmrenamed

The content is the same.

tests/test-files/good/Soundness/TrickyIdAnnotated.elm → tests/hs/test-files/good/Soundness/TrickyIdAnnotated.elmrenamed

The content is the same.

tests/test-files/good/Strings/Multiline.elm → tests/hs/test-files/good/Strings/Multiline.elmrenamed

The content is the same.

tests/test-files/good/Strings/MultilineNormal.elm → tests/hs/test-files/good/Strings/MultilineNormal.elmrenamed

The content is the same.

tests/test-files/good/Unify/LockedVars.elm → tests/hs/test-files/good/Unify/LockedVars.elmrenamed

The content is the same.

tests/test-files/good/Unify/NonHomogeneousRecords.elm → tests/hs/test-files/good/Unify/NonHomogeneousRecords.elmrenamed

The content is the same.