diff --git a/.gitignore b/.gitignore index 7f3cfe48..20549cf5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ elm-stuff -tests/test.js -node_modules/ \ No newline at end of file +node_modules/ +*.dat +doc*.json +tests/.elm +*~ diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 00000000..d3525490 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,3 @@ +elm-home/ +src/ +elm.js diff --git a/tests/elm-package.json b/tests/elm-package.json deleted file mode 100644 index e27cfa49..00000000 --- a/tests/elm-package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": "1.1.1", - "summary": "Tests for Elm's standard libraries", - "repository": "http://github.com/elm-lang/core.git", - "license": "BSD3", - "source-directories": [ - ".", - "../src" - ], - "exposed-modules": [ ], - "native-modules": true, - "dependencies": { - "elm-community/elm-test": "3.1.0 <= v < 4.0.0", - "rtfeldman/node-test-runner": "3.0.0 <= v < 4.0.0" - }, - "elm-version": "0.18.0 <= v < 0.19.0" -} diff --git a/tests/elm.json b/tests/elm.json new file mode 100644 index 00000000..679d6479 --- /dev/null +++ b/tests/elm.json @@ -0,0 +1,14 @@ +{ + "type": "package", + "name": "elm/core", + "summary": "Elm's standard libraries", + "license": "BSD-3-Clause", + "version": "1.0.2", + "exposed-modules": [], + "elm-version": "0.19.0 <= v < 0.20.0", + "dependencies": { + "elm/random": "1.0.0 <= v < 2.0.0", + "elm-explorations/test": "1.2.1 <= v < 2.0.0" + }, + "test-dependencies": {} +} \ No newline at end of file diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 9e2f9bcf..3909f131 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -1,19 +1,70 @@ -#!/bin/sh +#!/usr/bin/env bash -cd "$(dirname "$0")" -set -e +set -o errexit; +set -o nounset; +#let the caller supply an ELM_TEST binary if desired +if [ ! -v ELM_TEST ]; then + npm install elm-test; + ELM_TEST=node_modules/elm-test/bin/elm-test; +fi -elm-package install -y +# since elm/core is treated specially by the compiler (it's always +# inserted as a dependency even when not declared explicitly), we use +# a bit of a hack to make the tests run against the local source code +# rather than the elm/core source fetched from package.elm-lang.org. -VERSION_DIR="$(ls elm-stuff/packages/elm-lang/core/)" -CORE_PACKAGE_DIR="elm-stuff/packages/elm-lang/core/$VERSION_DIR" +# create a local directory where the compiler will look for the +# elm/core source code: + +DIR="$(dirname $0)"; + +cd "$DIR"; + +export ELM_HOME="$(pwd)/.elm"; + +rm -rf "$ELM_HOME" && mkdir -p "$ELM_HOME"; + +# elm-test also puts some things in elm-stuff, start with a clean +# slate there as well + +rm -rf elm-stuff; + +# now make an initial run of the tests to populate .elm and elm-stuff; +# this will test against elm/core from package.elm-lang.org, so we +# don't really care what the results are; we just need to force all +# the *other* dependencies to be fetched and set up. + +echo "seeding framework for test dependencies ..."; + +# '|| true' lets us ignore failures here and keep the script running. +# useful when developing a fix for a bug that exists in the version of +# elm/core hosted on package.elm-lang.org +"${ELM_TEST}" tests/Main.elm > /dev/null || true; + +# clear out the copy of elm-core fetched by the above and replace it +# with the local source code we want to actually test + +VERSION_DIR="$(ls ${ELM_HOME}/0.19.0/package/elm/core/)" +CORE_PACKAGE_DIR="${ELM_HOME}/0.19.0/package/elm/core/$VERSION_DIR" CORE_GIT_DIR="$(dirname $PWD)" +echo; echo "Linking $CORE_PACKAGE_DIR to $CORE_GIT_DIR" -rm -rf $CORE_PACKAGE_DIR -ln -s $CORE_GIT_DIR $CORE_PACKAGE_DIR +echo; +rm -rf "$CORE_PACKAGE_DIR" +ln -sv "$CORE_GIT_DIR" "$CORE_PACKAGE_DIR" +rm -vf "${CORE_GIT_DIR}"/*.dat "${CORE_GIT_DIR}"/doc*.json + +# we also need to clear out elm-test's elm-stuff dir, since otherwise +# the compiler complains that its .dat files are out of sync + +rm -rf elm-stuff; + +# now we can run the tests against the symlinked source code for real -elm-make --yes --output test.js Main.elm +echo; +echo "running tests ..."; +echo; -elm-test Main.elm +"${ELM_TEST}" tests/Main.elm; diff --git a/tests/test.js b/tests/test.js new file mode 100644 index 00000000..57bda620 --- /dev/null +++ b/tests/test.js @@ -0,0 +1,109 @@ +'use strict'; +const fs = require('fs'); +const {promisify} = require('util'); +const {exec} = require('child_process'); +const path = require('path'); + +const mkdir = promisify(fs.mkdir); +const readdir = promisify(fs.readdir); +const lstat = promisify(fs.lstat); +const copyFile = promisify(fs.copyFile); +const unlink = promisify(fs.unlink); +const rmdir = promisify(fs.rmdir); + + +const remove = async dir => { + let files = []; + try { + files = await readdir(dir); + } catch (error) { + if (error.code === 'ENOENT') { + return; + } else { + throw error; + } + } + + await Promise.all(files.map(async file => { + const filename = path.join(dir, file); + const stat = await lstat(filename); + + if (filename == "." || filename == "..") { + // pass these files + } else if (stat.isDirectory()) { + // rmdir recursively + await remove(filename); + } else if (stat.isSymbolicLink()) { + throw new Error("Cannot remove symbolic link!"); + } else { + await unlink(filename); + } + })); + await rmdir(dir); +}; + + +const copyDir = async (src, dest) => { + try { + await mkdir(dest); + } catch (error) { + if (error.code !== "EEXIST") { + throw error; + } + } + const files = await readdir(src); + + await Promise.all(files.map(async file => { + const current = await lstat(path.join(src, file)); + + if (current.isDirectory()) { + await copyDir(path.join(src, file), path.join(dest, file)); + } else if (current.isSymbolicLink()) { + throw new Error("Cannot copy symbolic link!"); + } else { + await copyFile(path.join(src, file), path.join(dest, file)); + } + })); +}; + +(async () => { + try { + process.chdir(__dirname); + + await remove('src'); + + await copyDir('../src', 'src'); + await copyDir(path.join('tests'), path.join('src')); + } catch (error) { + console.error(" ** Error generating files **"); + console.error(error); + process.exit(1); + return; + } + try { + await new Promise((resolve, reject) => { + exec('elm make src/Run.elm --output elm.js', (error, stdout, stderr) => { + if (error != null) { + reject(error); + } else { + process.stdout.write(stdout); + process.stderr.write(stderr); + resolve(); + } + }); + }); + } catch (error) { + console.error(" ** Error compiling files **"); + console.error(error); + process.exit(1); + return; + } + try { + require('./elm.js'); + } catch (error) { + console.error(" ** Tests failed **"); + console.error(error); + process.exit(1); + return; + } +})(); diff --git a/tests/Main.elm b/tests/tests/Main.elm similarity index 70% rename from tests/Main.elm rename to tests/tests/Main.elm index 89da5a02..015babf9 100644 --- a/tests/Main.elm +++ b/tests/tests/Main.elm @@ -1,11 +1,6 @@ -port module Main exposing (..) +module Main exposing (..) -import Basics exposing (..) -import Task exposing (..) import Test exposing (..) -import Platform.Cmd exposing (Cmd) -import Json.Decode exposing (Value) -import Test.Runner.Node exposing (run, TestProgram) import Test.Array as Array import Test.Basics as Basics import Test.Bitwise as Bitwise @@ -14,7 +9,6 @@ import Test.CodeGen as CodeGen import Test.Dict as Dict import Test.Maybe as Maybe import Test.Equality as Equality -import Test.Json as Json import Test.List as List import Test.Result as Result import Test.Set as Set @@ -39,11 +33,3 @@ tests = , Maybe.tests , Tuple.tests ] - - -main : TestProgram -main = - run emit tests - - -port emit : ( String, Value ) -> Cmd msg diff --git a/tests/tests/Run.elm b/tests/tests/Run.elm new file mode 100644 index 00000000..bfe3a909 --- /dev/null +++ b/tests/tests/Run.elm @@ -0,0 +1,129 @@ +module Run exposing (main) + +{-| HOW TO RUN THESE TESTS + +$ node test + +Note that this always uses an initial seed of 902101337, since it can't do effects. + +-} + +import Basics exposing (..) +import List exposing ((::)) +import Maybe exposing (Maybe(..)) +import Result exposing (Result(..)) +import String exposing (String) +import Char exposing (Char) +import Tuple + +import Debug + +import Platform exposing ( Program ) +import Platform.Cmd as Cmd exposing ( Cmd ) +import Platform.Sub as Sub exposing ( Sub ) + +import Array +import Dict +import Set + +import Test exposing (Test) +import Test.Runner +import Random +import Expect +import Main exposing (tests) + +type alias Summary = + { passed : Int, autoFail : Maybe String } + +main : Program () () msg +main = + let + summary = + run tests + + _ = + case summary.autoFail of + Just reason -> + Debug.log "Auto failed" reason + |> (\_ -> Debug.todo "FAILED TEST RUN") + Nothing -> + Debug.log "All tests passed, count" summary.passed + in + Platform.worker + { init = \() -> ( (), Cmd.none ) + , update = \_ () -> ( (), Cmd.none ) + , subscriptions = \() -> Sub.none + } + + +run : Test -> Summary +run test = + let + seededRunners = + Test.Runner.fromTest 100 (Random.initialSeed 902101337) test + + _ = + Debug.log "Running" "Tests ..." + in + toOutput + { passed = 0 + , autoFail = Just "no tests were run" + } + seededRunners + + +toOutput : Summary -> Test.Runner.SeededRunners -> Summary +toOutput summary seededRunners = + let + render = + List.foldl toOutputHelp + in + case seededRunners of + Test.Runner.Plain runners -> + render { summary | autoFail = Nothing } runners + + Test.Runner.Only runners -> + render { summary | autoFail = Just "Test.only was used" } runners + + Test.Runner.Skipping runners -> + render { summary | autoFail = Just "Test.skip was used" } runners + + Test.Runner.Invalid message -> + Debug.log "Invalid message" message + |> Debug.todo "FAIL" + + +toOutputHelp : Test.Runner.Runner -> Summary -> Summary +toOutputHelp runner summary = + runner.run () + |> List.foldl (fromExpectation runner.labels) summary + + +fromExpectation : List String -> Expect.Expectation -> Summary -> Summary +fromExpectation labels expectation summary = + case Test.Runner.getFailureReason expectation of + Nothing -> + { summary | passed = summary.passed + 1 } + + Just { given, description, reason } -> + let + message = + description ++ ": " ++ Debug.toString reason + + prefix = + case given of + Nothing -> + "" + + Just g -> + "Given " ++ g ++ "\n\n" + + labelString = + labels + |> List.reverse + |> String.join "\n" + + newOutput = + "\n\n" ++ labelString ++ "\n" ++ (prefix ++ message) ++ "\n" + in + Debug.todo newOutput diff --git a/tests/Test/Array.elm b/tests/tests/Test/Array.elm similarity index 95% rename from tests/Test/Array.elm rename to tests/tests/Test/Array.elm index c8aac42a..32d1dfb8 100644 --- a/tests/Test/Array.elm +++ b/tests/tests/Test/Array.elm @@ -1,9 +1,9 @@ module Test.Array exposing (tests) -import Array +import Array exposing (..) import Basics exposing (..) import List exposing ((::)) -import Maybe exposing (..) +import Maybe exposing (Maybe(..)) import Test exposing (..) import Fuzz exposing (Fuzzer, intRange) import Expect @@ -193,8 +193,8 @@ transformTests = |> Expect.equal (List.range 0 (size - 1)) , fuzz defaultSizeRange "filter" <| \size -> - toList (filter (\a -> a % 2 == 0) (initialize size identity)) - |> Expect.equal (List.filter (\a -> a % 2 == 0) (List.range 0 (size - 1))) + toList (filter (\a -> modBy 2 a == 0) (initialize size identity)) + |> Expect.equal (List.filter (\a -> modBy 2 a == 0) (List.range 0 (size - 1))) , fuzz defaultSizeRange "map" <| \size -> map ((+) 1) (initialize size identity) @@ -215,14 +215,6 @@ transformTests = \s1 s2 -> append (initialize s1 identity) (initialize s2 ((+) s1)) |> Expect.equal (initialize (s1 + s2) identity) - , fuzz (defaultSizeRange) "toString" <| - \size -> - let - ls = - List.range 0 size - in - Array.toString (fromList ls) - |> Expect.equal ("Array " ++ Basics.toString ls) ] diff --git a/tests/Test/Basics.elm b/tests/tests/Test/Basics.elm similarity index 90% rename from tests/Test/Basics.elm rename to tests/tests/Test/Basics.elm index 56742cb5..323ae15d 100644 --- a/tests/Test/Basics.elm +++ b/tests/tests/Test/Basics.elm @@ -3,13 +3,13 @@ module Test.Basics exposing (tests) import Array import Tuple exposing (first, second) import Basics exposing (..) -import Date import Set import Dict import Test exposing (..) -import Expect +import Expect exposing (FloatingPointTolerance(..)) import List import String +import Debug exposing (toString) tests : Test @@ -33,14 +33,12 @@ tests = , test "6 <= 6" <| \() -> Expect.equal True (6 <= 6) , test "compare \"A\" \"B\"" <| \() -> Expect.equal LT (compare "A" "B") , test "compare 'f' 'f'" <| \() -> Expect.equal EQ (compare 'f' 'f') - , test "compare (1, 2, 3, 4, 5, 6) (0, 1, 2, 3, 4, 5)" <| \() -> Expect.equal GT (compare ( 1, 2, 3, 4, 5, 6 ) ( 0, 1, 2, 3, 4, 5 )) + , test "compare (1, 2, 3) (0, 1, 2)" <| \() -> Expect.equal GT (compare ( 1, 2, 3 ) ( 0, 1, 2 )) , test "compare ['a'] ['b']" <| \() -> Expect.equal LT (compare [ 'a' ] [ 'b' ]) , test "array equality" <| \() -> Expect.equal (Array.fromList [ 1, 1, 1, 1 ]) (Array.repeat 4 1) , test "set equality" <| \() -> Expect.equal (Set.fromList [ 1, 2 ]) (Set.fromList [ 2, 1 ]) , test "dict equality" <| \() -> Expect.equal (Dict.fromList [ ( 1, 1 ), ( 2, 2 ) ]) (Dict.fromList [ ( 2, 2 ), ( 1, 1 ) ]) , test "char equality" <| \() -> Expect.notEqual '0' '饑' - , test "date equality" <| \() -> Expect.equal (Date.fromString "2/7/1992") (Date.fromString "2/7/1992") - , test "date equality" <| \() -> Expect.notEqual (Date.fromString "11/16/1995") (Date.fromString "2/7/1992") ] toStringTests = @@ -118,16 +116,16 @@ tests = describe "Basic Math Tests" [ test "add float" <| \() -> Expect.equal 159 (155.6 + 3.4) , test "add int" <| \() -> Expect.equal 17 ((round 10) + (round 7)) - , test "subtract float" <| \() -> Expect.equal -6.3 (1 - 7.3) + , test "subtract float" <| \() -> Expect.within (Absolute 0.00000001) -6.3 (1 - 7.3) , test "subtract int" <| \() -> Expect.equal 1130 ((round 9432) - (round 8302)) - , test "multiply float" <| \() -> Expect.equal 432 (96 * 4.5) + , test "multiply float" <| \() -> Expect.within (Relative 0.00000001) 432 (96 * 4.5) , test "multiply int" <| \() -> Expect.equal 90 ((round 10) * (round 9)) - , test "divide float" <| \() -> Expect.equal 13.175 (527 / 40) + , test "divide float" <| \() -> Expect.within (Relative 0.00000001) 13.175 (527 / 40) , test "divide int" <| \() -> Expect.equal 23 (70 // 3) - , test "2 |> rem 7" <| \() -> Expect.equal 1 (2 |> rem 7) - , test "4 |> rem -1" <| \() -> Expect.equal -1 (4 |> rem -1) - , test "7 % 2" <| \() -> Expect.equal 1 (7 % 2) - , test "-1 % 4" <| \() -> Expect.equal 3 (-1 % 4) + , test "7 |> remainderBy 2" <| \() -> Expect.equal 1 (7 |> remainderBy 2) + , test "-1 |> remainderBy 4" <| \() -> Expect.equal -1 (-1 |> remainderBy 4) + , test "modBy 2 7" <| \() -> Expect.equal 1 (modBy 2 7) + , test "modBy 4 -1" <| \() -> Expect.equal 3 (modBy 4 -1) , test "3^2" <| \() -> Expect.equal 9 (3 ^ 2) , test "sqrt" <| \() -> Expect.equal 9 (sqrt 81) , test "negate 42" <| \() -> Expect.equal -42 (negate 42) @@ -192,7 +190,6 @@ tests = , test "<|" <| \() -> Expect.equal 9 (identity <| 3 + 6) , test "|>" <| \() -> Expect.equal 9 (3 + 6 |> identity) , test "<<" <| \() -> Expect.equal True (not << xor True <| True) - , test "<<" <| \() -> Expect.equal True (not << xor True <| True) , describe ">>" [ test "with xor" <| \() -> @@ -204,9 +201,6 @@ tests = |> List.map (.foo >> String.reverse) |> Expect.equal [ "SaN" ] ] - , test "flip" <| \() -> Expect.equal 10 ((flip (//)) 2 20) - , test "curry" <| \() -> Expect.equal 1 ((curry (\( a, b ) -> a + b)) -5 6) - , test "uncurry" <| \() -> Expect.equal 1 ((uncurry (+)) ( -5, 6 )) ] in describe "Basics" diff --git a/tests/Test/Bitwise.elm b/tests/tests/Test/Bitwise.elm similarity index 100% rename from tests/Test/Bitwise.elm rename to tests/tests/Test/Bitwise.elm diff --git a/tests/Test/Char.elm b/tests/tests/Test/Char.elm similarity index 99% rename from tests/Test/Char.elm rename to tests/tests/Test/Char.elm index e9d2b7f0..c910ada2 100644 --- a/tests/Test/Char.elm +++ b/tests/tests/Test/Char.elm @@ -48,8 +48,8 @@ decCodes = oneOf : List a -> a -> Bool -oneOf = - flip List.member +oneOf list e = + List.member e list tests : Test diff --git a/tests/Test/CodeGen.elm b/tests/tests/Test/CodeGen.elm similarity index 87% rename from tests/Test/CodeGen.elm rename to tests/tests/Test/CodeGen.elm index 4a89c63d..d5fc043d 100644 --- a/tests/Test/CodeGen.elm +++ b/tests/tests/Test/CodeGen.elm @@ -50,15 +50,6 @@ caseQualified = 0 -caseScope : String -caseScope = - case "Not this one!" of - string -> - case "Hi" of - string -> - string - - tests : Test tests = let @@ -79,11 +70,6 @@ tests = , test "case" <| \() -> Expect.equal 42 caseQualified ] - scope : Test - scope = - describe "Scoping" - [ test "case" <| \() -> Expect.equal "Hi" caseScope ] - hex : Test hex = describe "Hex" @@ -104,6 +90,5 @@ tests = describe "CodeGen" [ underscores , qualifiedPatterns - , scope , hex ] diff --git a/tests/Test/Dict.elm b/tests/tests/Test/Dict.elm similarity index 99% rename from tests/Test/Dict.elm rename to tests/tests/Test/Dict.elm index 372b2c92..7476fef3 100644 --- a/tests/Test/Dict.elm +++ b/tests/tests/Test/Dict.elm @@ -6,6 +6,7 @@ import List import Maybe exposing (..) import Test exposing (..) import Expect +import String exposing (String) animals : Dict.Dict String String diff --git a/tests/Test/Equality.elm b/tests/tests/Test/Equality.elm similarity index 91% rename from tests/Test/Equality.elm rename to tests/tests/Test/Equality.elm index 17374779..d39d61ff 100644 --- a/tests/Test/Equality.elm +++ b/tests/tests/Test/Equality.elm @@ -4,6 +4,7 @@ import Basics exposing (..) import Maybe exposing (..) import Test exposing (..) import Expect +import String exposing (String) type Different @@ -19,7 +20,7 @@ tests = [ test "As eq" <| \() -> Expect.equal True (A "a" == A "a") , test "Bs eq" <| \() -> Expect.equal True (B [ 1 ] == B [ 1 ]) , test "A left neq" <| \() -> Expect.equal True (A "a" /= B [ 1 ]) - , test "A left neq" <| \() -> Expect.equal True (B [ 1 ] /= A "a") + , test "A right neq" <| \() -> Expect.equal True (B [ 1 ] /= A "a") ] recordTests = diff --git a/tests/Test/List.elm b/tests/tests/Test/List.elm similarity index 94% rename from tests/Test/List.elm rename to tests/tests/Test/List.elm index ed26f0fa..36d0ac15 100644 --- a/tests/Test/List.elm +++ b/tests/tests/Test/List.elm @@ -3,8 +3,10 @@ module Test.List exposing (tests) import Test exposing (..) import Expect import Basics exposing (..) -import Maybe exposing (Maybe(Nothing, Just)) +import Maybe exposing (Maybe(..)) import List exposing (..) +import Tuple +import String tests : Test @@ -42,7 +44,7 @@ testListOfN n = mid = n // 2 in - describe (toString n ++ " elements") + describe (String.fromInt n ++ " elements") [ describe "foldl" [ test "order" <| \() -> Expect.equal (n) (foldl (\x acc -> x) 0 xs) , test "total" <| \() -> Expect.equal (xsSum) (foldl (+) 0 xs) @@ -110,7 +112,7 @@ testListOfN n = , test "all" <| \() -> Expect.equal (xsNeg) (filterMap (\x -> Just -x) xs) , let halve x = - if x % 2 == 0 then + if modBy 2 x == 0 then Just (x // 2) else Nothing @@ -121,7 +123,7 @@ testListOfN n = [ test "none" <| \() -> Expect.equal ([]) (concatMap (\x -> []) xs) , test "all" <| \() -> Expect.equal (xsNeg) (concatMap (\x -> [ -x ]) xs) ] - , test "indexedMap" <| \() -> Expect.equal (map2 (,) zs xsNeg) (indexedMap (\i x -> ( i, -x )) xs) + , test "indexedMap" <| \() -> Expect.equal (map2 Tuple.pair zs xsNeg) (indexedMap (\i x -> ( i, -x )) xs) , test "sum" <| \() -> Expect.equal (xsSum) (sum xs) , test "product" <| \() -> Expect.equal (0) (product zs) , test "maximum" <| @@ -153,8 +155,7 @@ testListOfN n = , test "unsorted" <| \() -> Expect.equal (xsNeg) (sortBy negate xsOpp) ] , describe "sortWith" - [ test "sorted" <| \() -> Expect.equal (xsNeg) (sortWith (flip compare) xsNeg) - , test "unsorted" <| \() -> Expect.equal (xsNeg) (sortWith (flip compare) xsOpp) + [ test "sorted" <| \() -> Expect.equal (xsNeg) (sortWith (\x -> \y -> compare y x) xsNeg) + , test "unsorted" <| \() -> Expect.equal (xsNeg) (sortWith (\x -> \y -> compare y x) xsOpp) ] - , test "scanl" <| \() -> Expect.equal (0 :: map sumSeq xs) (scanl (+) 0 xs) ] diff --git a/tests/Test/Maybe.elm b/tests/tests/Test/Maybe.elm similarity index 100% rename from tests/Test/Maybe.elm rename to tests/tests/Test/Maybe.elm diff --git a/tests/Test/Result.elm b/tests/tests/Test/Result.elm similarity index 81% rename from tests/Test/Result.elm rename to tests/tests/Test/Result.elm index 6679e7e9..9e60e199 100644 --- a/tests/Test/Result.elm +++ b/tests/tests/Test/Result.elm @@ -3,17 +3,25 @@ module Test.Result exposing (tests) import Basics exposing (..) import Result import Result exposing (Result(..)) -import String +import String exposing (String) import Test exposing (..) import Expect +import Maybe exposing (Maybe(..)) isEven n = - if n % 2 == 0 then + if modBy 2 n == 0 then Ok n else Err "number is odd" +toIntResult : String -> Result String Int +toIntResult s = + case String.toInt s of + Just i -> + Ok i + Nothing -> + Err <| "could not convert string '" ++ s ++ "' to an Int" add3 a b c = a + b + c @@ -50,17 +58,17 @@ tests = andThenTests = describe "andThen Tests" - [ test "andThen Ok" <| \() -> Expect.equal (Ok 42) ((String.toInt "42") |> Result.andThen isEven) + [ test "andThen Ok" <| \() -> Expect.equal (Ok 42) ((toIntResult "42") |> Result.andThen isEven) , test "andThen first Err" <| \() -> Expect.equal (Err "could not convert string '4.2' to an Int") - (String.toInt "4.2" |> Result.andThen isEven) + (toIntResult "4.2" |> Result.andThen isEven) , test "andThen second Err" <| \() -> Expect.equal (Err "number is odd") - (String.toInt "41" |> Result.andThen isEven) + (toIntResult "41" |> Result.andThen isEven) ] in describe "Result Tests" diff --git a/tests/Test/Set.elm b/tests/tests/Test/Set.elm similarity index 100% rename from tests/Test/Set.elm rename to tests/tests/Test/Set.elm diff --git a/tests/Test/String.elm b/tests/tests/Test/String.elm similarity index 93% rename from tests/Test/String.elm rename to tests/tests/Test/String.elm index 221f2985..723cf0df 100644 --- a/tests/Test/String.elm +++ b/tests/tests/Test/String.elm @@ -4,7 +4,7 @@ import Basics exposing (..) import List import Maybe exposing (..) import Result exposing (Result(..)) -import String +import String exposing (String) import Test exposing (..) import Expect @@ -51,9 +51,9 @@ tests = , badInt "1e31" , badInt "123a" , goodInt "0123" 123 - , goodInt "0x001A" 26 - , goodInt "0x001a" 26 - , goodInt "0xBEEF" 48879 + , badInt "0x001A" + , badInt "0x001a" + , badInt "0xBEEF" , badInt "0x12.0" , badInt "0x12an" ] @@ -101,26 +101,26 @@ tests = goodInt : String -> Int -> Test goodInt str int = test str <| \_ -> - Expect.equal (Ok int) (String.toInt str) + Expect.equal (Just int) (String.toInt str) badInt : String -> Test badInt str = test str <| \_ -> Expect.equal - (Err ("could not convert string '" ++ str ++ "' to an Int")) + Nothing (String.toInt str) goodFloat : String -> Float -> Test goodFloat str float = test str <| \_ -> - Expect.equal (Ok float) (String.toFloat str) + Expect.equal (Just float) (String.toFloat str) badFloat : String -> Test badFloat str = test str <| \_ -> Expect.equal - (Err ("could not convert string '" ++ str ++ "' to a Float")) + Nothing (String.toFloat str) diff --git a/tests/Test/Tuple.elm b/tests/tests/Test/Tuple.elm similarity index 100% rename from tests/Test/Tuple.elm rename to tests/tests/Test/Tuple.elm