diff options
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | src/gleam/base.gleam | 21 | ||||
-rw-r--r-- | src/gleam/bit_builder.gleam | 80 | ||||
-rw-r--r-- | src/gleam/bit_string.gleam | 43 | ||||
-rw-r--r-- | src/gleam/dynamic.gleam | 17 | ||||
-rw-r--r-- | src/gleam/map.gleam | 107 | ||||
-rw-r--r-- | src/gleam_stdlib.erl | 6 | ||||
-rw-r--r-- | src/gleam_stdlib.mjs | 51 | ||||
-rw-r--r-- | test/gleam/dynamic_test.gleam | 78 | ||||
-rw-r--r-- | test/gleam/iterator_test.gleam | 162 | ||||
-rw-r--r-- | test/gleam/map_test.gleam | 393 | ||||
-rw-r--r-- | test/gleam/queue_test.gleam | 12 | ||||
-rw-r--r-- | test/gleam/should.gleam | 64 | ||||
-rw-r--r-- | test/gleam_stdlib_test_ffi.erl | 11 |
14 files changed, 192 insertions, 857 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 22c3766..94ba0d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ ## Unreleased - The `set` module gains the `difference` function. +- The deprecated `bit_string`, `bit_builder`, `base`, and `map` modules have + been removed. +- The deprecated `map`, and `bit_string` functions in the `dynamic` module have + been removed. ## v0.34.0 - 2023-12-17 diff --git a/src/gleam/base.gleam b/src/gleam/base.gleam deleted file mode 100644 index eab2f0b..0000000 --- a/src/gleam/base.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import gleam/bit_array - -@deprecated("Please use `base64_encode` in the `gleam/bit_array` module instead.") -pub fn encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_encode(input, padding) -} - -@deprecated("Please use `base64_decode` in the `gleam/bit_array` module instead.") -pub fn decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_decode(encoded) -} - -@deprecated("Please use `base64_url_encode` in the `gleam/bit_array` module instead.") -pub fn url_encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_url_encode(input, padding) -} - -@deprecated("Please use `base64_url_decode` in the `gleam/bit_array` module instead.") -pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_url_decode(encoded) -} diff --git a/src/gleam/bit_builder.gleam b/src/gleam/bit_builder.gleam deleted file mode 100644 index ce6fe52..0000000 --- a/src/gleam/bit_builder.gleam +++ /dev/null @@ -1,80 +0,0 @@ -//// This module has been deprecated in favour of `gleam/bytes_builder`. - -import gleam/bytes_builder -import gleam/string_builder.{type StringBuilder} - -pub type BitBuilder = - bytes_builder.BytesBuilder - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn new() -> BitBuilder { - bytes_builder.new() -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder { - bytes_builder.prepend(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder { - bytes_builder.append(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { - bytes_builder.prepend_builder(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_builder( - to first: BitBuilder, - suffix second: BitBuilder, -) -> BitBuilder { - bytes_builder.append_builder(first, second) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { - bytes_builder.prepend_string(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { - bytes_builder.append_string(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat(builders: List(BitBuilder)) -> BitBuilder { - bytes_builder.concat(builders) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder { - bytes_builder.concat_bit_arrays(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string(string: String) -> BitBuilder { - bytes_builder.from_string(string) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { - bytes_builder.from_string_builder(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_bit_string(bits: BitArray) -> BitBuilder { - bytes_builder.from_bit_array(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn to_bit_string(builder: BitBuilder) -> BitArray { - bytes_builder.to_bit_array(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn byte_size(builder: BitBuilder) -> Int { - bytes_builder.byte_size(builder) -} diff --git a/src/gleam/bit_string.gleam b/src/gleam/bit_string.gleam deleted file mode 100644 index b703da0..0000000 --- a/src/gleam/bit_string.gleam +++ /dev/null @@ -1,43 +0,0 @@ -//// This module has been deprecated. Please use the `gleam/bit_array` module -//// instead. - -import gleam/bit_array - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn from_string(x: String) -> BitArray { - bit_array.from_string(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn byte_size(x: BitArray) -> Int { - bit_array.byte_size(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - bit_array.append(first, second) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) { - bit_array.slice(string, position, length) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn is_utf8(bits: BitArray) -> Bool { - bit_array.is_utf8(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - bit_array.to_string(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn concat(bit_strings: List(BitArray)) -> BitArray { - bit_array.concat(bit_strings) -} diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam index 42884c7..d0a294a 100644 --- a/src/gleam/dynamic.gleam +++ b/src/gleam/dynamic.gleam @@ -80,11 +80,6 @@ pub fn bit_array(from data: Dynamic) -> Result(BitArray, DecodeErrors) { decode_bit_array(data) } -@deprecated("Please use `bit_array` instead") -pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - bit_array(data) -} - @external(erlang, "gleam_stdlib", "decode_bit_array") @external(javascript, "../gleam_stdlib.mjs", "decode_bit_array") fn decode_bit_array(a: Dynamic) -> Result(BitArray, DecodeErrors) @@ -239,7 +234,9 @@ fn decode_bool(a: Dynamic) -> Result(Bool, DecodeErrors) /// // -> Error([DecodeError(expected: "List", found: "Int", path: [])]) /// ``` /// -pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { +pub fn shallow_list( + from value: Dynamic, +) -> Result(List(Dynamic), DecodeErrors) { decode_list(value) } @@ -1014,14 +1011,6 @@ pub fn dict( } } -@deprecated("Use `dict` instead") -pub fn map( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - dict(key_type, value_type) -} - @external(erlang, "gleam_stdlib", "decode_map") @external(javascript, "../gleam_stdlib.mjs", "decode_map") fn decode_map(a: Dynamic) -> Result(Dict(Dynamic, Dynamic), DecodeErrors) diff --git a/src/gleam/map.gleam b/src/gleam/map.gleam deleted file mode 100644 index b3d0e0f..0000000 --- a/src/gleam/map.gleam +++ /dev/null @@ -1,107 +0,0 @@ -import gleam/option.{type Option} -import gleam/dict - -@deprecated("Please use the `gleam/dict` module instead") -pub type Map(key, value) = - dict.Dict(key, value) - -@deprecated("Please use the `gleam/dict` module instead") -pub fn size(map) -> Int { - dict.size(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn to_list(map) -> List(#(key, value)) { - dict.to_list(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn from_list(list: List(#(k, v))) { - dict.from_list(list) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn has_key(map, key: k) -> Bool { - dict.has_key(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn new() { - dict.new() -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn get(from, get: key) -> Result(value, Nil) { - dict.get(from, get) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn insert(into map, for key: k, insert value: v) { - dict.insert(map, key, value) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn map_values(in map, with fun: fn(k, v) -> w) { - dict.map_values(map, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn keys(map) -> List(keys) { - dict.keys(map) -} - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn values(map) -> List(values) { - dict.values(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn filter(in map, keeping predicate: fn(k, v) -> Bool) { - dict.filter(map, predicate) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn take(from map, keeping desired_keys: List(k)) { - dict.take(map, desired_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn merge(into map, from new_entries) { - dict.merge(map, new_entries) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn delete(from map, delete key: k) { - dict.delete(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn drop(from map, drop disallowed_keys: List(k)) { - dict.drop(map, disallowed_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn update(in map, update key: k, with fun: fn(Option(v)) -> v) { - dict.update(map, key, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn fold(over map, from initial: acc, with fun: fn(acc, k, v) -> acc) -> acc { - dict.fold(map, initial, fun) -} diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl index c6ea125..433b4d4 100644 --- a/src/gleam_stdlib.erl +++ b/src/gleam_stdlib.erl @@ -58,7 +58,7 @@ classify_dynamic(X) when is_integer(X) -> <<"Int">>; classify_dynamic(X) when is_float(X) -> <<"Float">>; classify_dynamic(X) when is_list(X) -> <<"List">>; classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; -classify_dynamic(X) when is_map(X) -> <<"Map">>; +classify_dynamic(X) when is_map(X) -> <<"Dict">>; classify_dynamic(X) when is_tuple(X) -> iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); classify_dynamic(X) when @@ -70,7 +70,7 @@ classify_dynamic(X) when classify_dynamic(_) -> <<"Some other type">>. decode_map(Data) when is_map(Data) -> {ok, Data}; -decode_map(Data) -> decode_error_msg(<<"Map">>, Data). +decode_map(Data) -> decode_error_msg(<<"Dict">>, Data). decode_bit_array(Data) when is_bitstring(Data) -> {ok, Data}; decode_bit_array(Data) -> decode_error_msg(<<"BitArray">>, Data). @@ -94,7 +94,7 @@ decode_field(Data, Key) when is_map(Data) -> {ok, none} end; decode_field(Data, _) -> - decode_error_msg(<<"Map">>, Data). + decode_error_msg(<<"Dict">>, Data). size_of_tuple(Data) -> tuple_size(Data). diff --git a/src/gleam_stdlib.mjs b/src/gleam_stdlib.mjs index 45c28cf..877e707 100644 --- a/src/gleam_stdlib.mjs +++ b/src/gleam_stdlib.mjs @@ -122,7 +122,7 @@ export function string_replace(string, target, substitute) { return string.replace( // $& means the whole matched string new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), - substitute + substitute, ); } @@ -499,7 +499,7 @@ export function encode64(bit_array) { uint6ToB64((nUint24 >>> 18) & 63), uint6ToB64((nUint24 >>> 12) & 63), uint6ToB64((nUint24 >>> 6) & 63), - uint6ToB64(nUint24 & 63) + uint6ToB64(nUint24 & 63), ); nUint24 = 0; } @@ -516,14 +516,14 @@ function uint6ToB64(nUint6) { return nUint6 < 26 ? nUint6 + 65 : nUint6 < 52 - ? nUint6 + 71 - : nUint6 < 62 - ? nUint6 - 4 - : nUint6 === 62 - ? 43 - : nUint6 === 63 - ? 47 - : 65; + ? nUint6 + 71 + : nUint6 < 62 + ? nUint6 - 4 + : nUint6 === 62 + ? 43 + : nUint6 === 63 + ? 47 + : 65; } // From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 @@ -531,14 +531,14 @@ function b64ToUint6(nChr) { return nChr > 64 && nChr < 91 ? nChr - 65 : nChr > 96 && nChr < 123 - ? nChr - 71 - : nChr > 47 && nChr < 58 - ? nChr + 4 - : nChr === 43 - ? 62 - : nChr === 47 - ? 63 - : 0; + ? nChr - 71 + : nChr > 47 && nChr < 58 + ? nChr + 4 + : nChr === 43 + ? 62 + : nChr === 47 + ? 63 + : 0; } // From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 @@ -577,7 +577,7 @@ export function classify_dynamic(data) { } else if (data instanceof BitArray) { return "BitArray"; } else if (data instanceof Dict) { - return "Map"; + return "Dict"; } else if (Number.isInteger(data)) { return "Int"; } else if (Array.isArray(data)) { @@ -600,7 +600,7 @@ function decoder_error(expected, got) { function decoder_error_no_classify(expected, got) { return new Error( - List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) + List.fromArray([new DecodeError(expected, got, List.fromArray([]))]), ); } @@ -701,19 +701,22 @@ export function decode_result(data) { export function decode_map(data) { if (data instanceof Dict) { + return new Ok(data); + } + if (data instanceof Map || data instanceof WeakMap) { return new Ok(Dict.fromMap(data)); } if (data == null) { - return decoder_error("Map", data); + return decoder_error("Dict", data); } if (typeof data !== "object") { - return decoder_error("Map", data); + return decoder_error("Dict", data); } const proto = Object.getPrototypeOf(data); if (proto === Object.prototype || proto === null) { return new Ok(Dict.fromObject(data)); } - return decoder_error("Map", data); + return decoder_error("Dict", data); } export function decode_option(data, decoder) { @@ -729,7 +732,7 @@ export function decode_option(data, decoder) { } export function decode_field(value, name) { - const not_a_map_error = () => decoder_error("Map", value); + const not_a_map_error = () => decoder_error("Dict", value); if ( value instanceof Dict || diff --git a/test/gleam/dynamic_test.gleam b/test/gleam/dynamic_test.gleam index 732949a..4b6fc53 100644 --- a/test/gleam/dynamic_test.gleam +++ b/test/gleam/dynamic_test.gleam @@ -56,11 +56,12 @@ pub type MyAtom { } @target(erlang) -pub fn map_from_atom_test() { +pub fn dict_from_atom_test() { ThisIsAnAtom |> dynamic.from - |> dynamic.map(dynamic.string, dynamic.int) - |> should.equal(Error([DecodeError(expected: "Map", found: "Atom", path: [])]), + |> dynamic.dict(dynamic.string, dynamic.int) + |> should.equal( + Error([DecodeError(expected: "Dict", found: "Atom", path: [])]), ) } @@ -69,11 +70,12 @@ pub fn map_from_atom_test() { fn get_null() -> dynamic.Dynamic @target(javascript) -pub fn map_from_null_test() { +pub fn dict_from_null_test() { get_null() |> dynamic.from - |> dynamic.map(dynamic.string, dynamic.int) - |> should.equal(Error([DecodeError(expected: "Map", found: "Null", path: [])]), + |> dynamic.dict(dynamic.string, dynamic.int) + |> should.equal( + Error([DecodeError(expected: "Dict", found: "Null", path: [])]), ) } @@ -127,7 +129,8 @@ pub fn int_test() { [] |> dynamic.from |> dynamic.int - |> should.equal(Error([DecodeError(expected: "Int", found: "List", path: [])]), + |> should.equal( + Error([DecodeError(expected: "Int", found: "List", path: [])]), ) } @@ -194,7 +197,8 @@ pub fn bool_test() { 1 |> dynamic.from |> dynamic.bool - |> should.equal(Error([DecodeError(expected: "Bool", found: "Int", path: [])]), + |> should.equal( + Error([DecodeError(expected: "Bool", found: "Int", path: [])]), ) 1.5 @@ -236,7 +240,8 @@ pub fn list_test() { 1 |> dynamic.from |> dynamic.list(dynamic.string) - |> should.equal(Error([DecodeError(expected: "List", found: "Int", path: [])]), + |> should.equal( + Error([DecodeError(expected: "List", found: "Int", path: [])]), ) 1.1 @@ -299,7 +304,7 @@ pub fn javascript_object_field_test() { |> dynamic.from |> dynamic.field("Nope", dynamic.int) |> should.equal( - Error([DecodeError(expected: "Map", found: "Result", path: [])]), + Error([DecodeError(expected: "Dict", found: "Result", path: [])]), ) } @@ -341,12 +346,15 @@ pub fn field_test() { 1 |> dynamic.from |> dynamic.field("ok", dynamic.int) - |> should.equal(Error([DecodeError(expected: "Map", found: "Int", path: [])])) + |> should.equal( + Error([DecodeError(expected: "Dict", found: "Int", path: [])]), + ) [] |> dynamic.from |> dynamic.field("ok", dynamic.int) - |> should.equal(Error([DecodeError(expected: "Map", found: "List", path: [])]), + |> should.equal( + Error([DecodeError(expected: "Dict", found: "List", path: [])]), ) dict.new() @@ -354,7 +362,7 @@ pub fn field_test() { |> dynamic.from |> dynamic.field("ok", dynamic.field("not_a_field", dynamic.int)) |> should.equal( - Error([DecodeError(expected: "Map", found: "Int", path: ["ok"])]), + Error([DecodeError(expected: "Dict", found: "Int", path: ["ok"])]), ) } @@ -406,12 +414,15 @@ pub fn optional_field_test() { 1 |> dynamic.from |> dynamic.optional_field("ok", dynamic.int) - |> should.equal(Error([DecodeError(expected: "Map", found: "Int", path: [])])) + |> should.equal( + Error([DecodeError(expected: "Dict", found: "Int", path: [])]), + ) [] |> dynamic.from |> dynamic.optional_field("ok", dynamic.int) - |> should.equal(Error([DecodeError(expected: "Map", found: "List", path: [])]), + |> should.equal( + Error([DecodeError(expected: "Dict", found: "List", path: [])]), ) } @@ -485,7 +496,7 @@ pub fn element_test() { |> dynamic.from |> dynamic.element(0, dynamic.int) |> should.equal( - Error([DecodeError(expected: "Tuple", found: "Map", path: [])]), + Error([DecodeError(expected: "Tuple", found: "Dict", path: [])]), ) } @@ -1063,54 +1074,60 @@ pub fn nested_tuples_test() { ) } -pub fn map_test() { +pub fn dict_test() { dict.new() |> dynamic.from - |> dynamic.map(dynamic.string, dynamic.int) + |> dynamic.dict(dynamic.string, dynamic.int) |> should.equal(Ok(dict.new())) dict.from_list([#("a", 1), #("b", 2)]) |> dynamic.from - |> dynamic.map(dynamic.string, dynamic.int) + |> dynamic.dict(dynamic.string, dynamic.int) |> should.equal(Ok(dict.from_list([#("a", 1), #("b", 2)]))) dict.from_list([#("a", 1), #("b", 2)]) |> dynamic.from - |> dynamic.map(dynamic.int, dynamic.int) + |> dynamic.dict(dynamic.int, dynamic.int) |> should.equal( Error([DecodeError(expected: "Int", found: "String", path: ["keys"])]), ) dict.from_list([#("a", 1), #("b", 2)]) |> dynamic.from - |> dynamic.map(dynamic.string, dynamic.string) + |> dynamic.dict(dynamic.string, dynamic.string) |> should.equal( Error([DecodeError(expected: "String", found: "Int", path: ["values"])]), ) 1 |> dynamic.from - |> dynamic.map(dynamic.string, dynamic.int) - |> should.equal(Error([DecodeError(expected: "Map", found: "Int", path: [])])) + |> dynamic.dict(dynamic.string, dynamic.int) + |> should.equal( + Error([DecodeError(expected: "Dict", found: "Int", path: [])]), + ) #() |> dynamic.from - |> dynamic.map(dynamic.string, dynamic.int) + |> dynamic.dict(dynamic.string, dynamic.int) |> should.equal( - Error([DecodeError(expected: "Map", found: "Tuple of 0 elements", path: [])]), + Error([ + DecodeError(expected: "Dict", found: "Tuple of 0 elements", path: []), + ]), ) fn() { Nil } |> dynamic.from - |> dynamic.map(dynamic.string, dynamic.int) + |> dynamic.dict(dynamic.string, dynamic.int) |> should.equal( - Error([DecodeError(expected: "Map", found: "Function", path: [])]), + Error([DecodeError(expected: "Dict", found: "Function", path: [])]), ) Nil |> dynamic.from - |> dynamic.map(dynamic.string, dynamic.int) - |> should.equal(Error([DecodeError(expected: "Map", found: "Nil", path: [])])) + |> dynamic.dict(dynamic.string, dynamic.int) + |> should.equal( + Error([DecodeError(expected: "Dict", found: "Nil", path: [])]), + ) } pub fn shallow_list_test() { @@ -1132,7 +1149,8 @@ pub fn shallow_list_test() { 1 |> dynamic.from |> dynamic.shallow_list - |> should.equal(Error([DecodeError(expected: "List", found: "Int", path: [])]), + |> should.equal( + Error([DecodeError(expected: "List", found: "Int", path: [])]), ) } diff --git a/test/gleam/iterator_test.gleam b/test/gleam/iterator_test.gleam index 046a814..189f283 100644 --- a/test/gleam/iterator_test.gleam +++ b/test/gleam/iterator_test.gleam @@ -5,21 +5,21 @@ import gleam/should // a |> from_list |> to_list == a pub fn to_from_list_test() { - let test = fn(subject) { + let testcase = fn(subject) { subject |> iterator.from_list |> iterator.to_list |> should.equal(subject) } - test([]) - test([1]) - test([1, 2]) - test([1, 2, 4, 8]) + testcase([]) + testcase([1]) + testcase([1, 2]) + testcase([1, 2, 4, 8]) } pub fn step_test() { - let test = fn(subject) { + let testcase = fn(subject) { let step = subject |> iterator.from_list @@ -41,15 +41,15 @@ pub fn step_test() { } } - test([]) - test([1]) - test([1, 2]) - test([1, 2, 3]) + testcase([]) + testcase([1]) + testcase([1, 2]) + testcase([1, 2, 3]) } // a |> from_list |> take(n) == a |> list.take(_, n) pub fn take_test() { - let test = fn(n, subject) { + let testcase = fn(n, subject) { subject |> iterator.from_list |> iterator.take(n) @@ -57,16 +57,16 @@ pub fn take_test() { |> should.equal(list.take(subject, n)) } - test(0, []) - test(1, []) - test(-1, []) - test(0, [0]) - test(1, [0]) - test(-1, [0]) - test(0, [0, 1, 2, 3, 4]) - test(1, [0, 1, 2, 3, 4]) - test(2, [0, 1, 2, 3, 4]) - test(22, [0, 1, 2, 3, 4]) + testcase(0, []) + testcase(1, []) + testcase(-1, []) + testcase(0, [0]) + testcase(1, [0]) + testcase(-1, [0]) + testcase(0, [0, 1, 2, 3, 4]) + testcase(1, [0, 1, 2, 3, 4]) + testcase(2, [0, 1, 2, 3, 4]) + testcase(22, [0, 1, 2, 3, 4]) } pub fn transform_index_test() { @@ -124,7 +124,7 @@ pub fn transform_scan_test() { // a |> from_list |> fold(a, f) == a |> list.fold(_, a, f) pub fn fold_test() { - let test = fn(subject, acc, f) { + let testcase = fn(subject, acc, f) { subject |> iterator.from_list |> iterator.fold(acc, f) @@ -132,15 +132,15 @@ pub fn fold_test() { } let f = fn(acc, e) { [e, ..acc] } - test([], [], f) - test([1], [], f) - test([1, 2, 3], [], f) - test([1, 2, 3, 4, 5, 6, 7, 8], [], f) + testcase([], [], f) + testcase([1], [], f) + testcase([1, 2, 3], [], f) + testcase([1, 2, 3, 4, 5, 6, 7, 8], [], f) } // a |> from_list |> map(f) |> to_list == a |> list.map(_, f) pub fn map_test() { - let test = fn(subject, f) { + let testcase = fn(subject, f) { subject |> iterator.from_list |> iterator.map(f) @@ -149,29 +149,29 @@ pub fn map_test() { } let f = fn(e) { e * 2 } - test([], f) - test([1], f) - test([1, 2, 3], f) - test([1, 2, 3, 4, 5, 6, 7, 8], f) + testcase([], f) + testcase([1], f) + testcase([1, 2, 3], f) + testcase([1, 2, 3, 4, 5, 6, 7, 8], f) } // map2(from_list(a), from_list(b), f) == list.map2(a, b, f) pub fn map2_test() { - let test = fn(one, other, f) { + let testcase = fn(one, other, f) { iterator.map2(iterator.from_list(one), iterator.from_list(other), f) |> iterator.to_list |> should.equal(list.map2(one, other, f)) } let f = fn(a, b) { a / b } - test([], [], f) - test([], [2, 10, 3], f) - test([10], [2, 10, 3], f) - test([10, 20], [2, 10, 3], f) - test([10, 20, 30], [2, 10, 3], f) - test([10, 20, 30], [2, 10], f) - test([10, 20, 30], [2], f) - test([10, 20, 30], [], f) + testcase([], [], f) + testcase([], [2, 10, 3], f) + testcase([10], [2, 10, 3], f) + testcase([10, 20], [2, 10, 3], f) + testcase([10, 20, 30], [2, 10, 3], f) + testcase([10, 20, 30], [2, 10], f) + testcase([10, 20, 30], [2], f) + testcase([10, 20, 30], [], f) } pub fn map2_is_lazy_test() { @@ -186,7 +186,7 @@ pub fn map2_is_lazy_test() { // a |> from_list |> flat_map(f) |> to_list == // a |> list.map(f) |> list.map(to_list) |> list.concat pub fn flat_map_test() { - let test = fn(subject, f) { + let testcase = fn(subject, f) { subject |> iterator.from_list |> iterator.flat_map(f) @@ -201,14 +201,14 @@ pub fn flat_map_test() { let f = fn(i) { iterator.range(i, i + 2) } - test([], f) - test([1], f) - test([1, 2], f) + testcase([], f) + testcase([1], f) + testcase([1, 2], f) } // a |> from_list |> append(from_list(b)) |> to_list == list.concat([a, b]) pub fn append_test() { - let test = fn(left, right) { + let testcase = fn(left, right) { left |> iterator.from_list |> iterator.append(iterator.from_list(right)) @@ -216,14 +216,14 @@ pub fn append_test() { |> should.equal(list.concat([left, right])) } - test([], []) - test([1], [2]) - test([1, 2], [3, 4]) + testcase([], []) + testcase([1], [2]) + testcase([1, 2], [3, 4]) } // a |> list.map(from_list) |> from_list |> flatten |> to_list == list.concat(a) pub fn flatten_test() { - let test = fn(lists) { + let testcase = fn(lists) { lists |> list.map(iterator.from_list) |> iterator.from_list @@ -232,14 +232,14 @@ pub fn flatten_test() { |> should.equal(list.concat(lists)) } - test([[], []]) - test([[1], [2]]) - test([[1, 2], [3, 4]]) + testcase([[], []]) + testcase([[1], [2]]) + testcase([[1, 2], [3, 4]]) } // a |> list.map(from_list) |> concat |> to_list == list.concat(a) pub fn concat_test() { - let test = fn(lists) { + let testcase = fn(lists) { lists |> list.map(iterator.from_list) |> iterator.concat @@ -247,14 +247,14 @@ pub fn concat_test() { |> should.equal(list.concat(lists)) } - test([[], []]) - test([[1], [2]]) - test([[1, 2], [3, 4]]) + testcase([[], []]) + testcase([[1], [2]]) + testcase([[1, 2], [3, 4]]) } // a |> from_list |> filter(f) |> to_list == a |> list.filter(_, f) pub fn filter_test() { - let test = fn(subject, f) { + let testcase = fn(subject, f) { subject |> iterator.from_list |> iterator.filter(f) @@ -263,13 +263,13 @@ pub fn filter_test() { } let even = fn(x) { x % 2 == 0 } - test([], even) - test([1], even) - test([1, 2], even) - test([1, 2, 3], even) - test([1, 2, 3, 4], even) - test([1, 2, 3, 4, 5], even) - test([1, 2, 3, 4, 5, 6], even) + testcase([], even) + testcase([1], even) + testcase([1, 2], even) + testcase([1, 2, 3], even) + testcase([1, 2, 3, 4], even) + testcase([1, 2, 3, 4, 5], even) + testcase([1, 2, 3, 4, 5, 6], even) } pub fn repeat_test() { @@ -312,18 +312,18 @@ pub fn unfold_test() { } pub fn range_test() { - let test = fn(a, b, expected) { + let testcase = fn(a, b, expected) { iterator.range(a, b) |> iterator.to_list |> should.equal(expected) } - test(0, 0, [0]) - test(1, 1, [1]) - test(-1, -1, [-1]) - test(0, 1, [0, 1]) - test(0, 5, [0, 1, 2, 3, 4, 5]) - test(1, -5, [1, 0, -1, -2, -3, -4, -5]) + testcase(0, 0, [0]) + testcase(1, 1, [1]) + testcase(-1, -1, [-1]) + testcase(0, 1, [0, 1]) + testcase(0, 5, [0, 1, 2, 3, 4, 5]) + testcase(1, -5, [1, 0, -1, -2, -3, -4, -5]) } pub fn drop_test() { @@ -534,7 +534,7 @@ pub fn interleave_test() { // a |> from_list |> fold_until(acc, f) == a |> list.fold_until(acc, f) pub fn fold_until_test() { - let test = fn(subject, acc, f) { + let testcase = fn(subject, acc, f) { subject |> iterator.from_list() |> iterator.fold_until(acc, f) @@ -547,10 +547,10 @@ pub fn fold_until_test() { _ -> list.Stop(acc) } } - test([], [], f) - test([1], [], f) - test([1, 2, 3], [], f) - test([1, 2, 3, 4, 5, 6, 7, 8], [], f) + testcase([], [], f) + testcase([1], [], f) + testcase([1, 2, 3], [], f) + testcase([1, 2, 3, 4, 5, 6, 7, 8], [], f) [1, 2, 3, 4, 5, 6, 7, 8] |> iterator.from_list() @@ -560,7 +560,7 @@ pub fn fold_until_test() { // a |> from_list |> try_fold(acc, f) == a |> list.try_fold(acc, f) pub fn try_fold_test() { - let test = fn(subject, acc, fun) { + let testcase = fn(subject, acc, fun) { subject |> iterator.from_list() |> iterator.try_fold(acc, fun) @@ -573,10 +573,10 @@ pub fn try_fold_test() { _ -> Error("tried to add an odd number") } } - test([], 0, f) - test([2, 4, 6], 0, f) - test([1, 2, 3], 0, f) - test([1, 2, 3, 4, 5, 6, 7, 8], 0, f) + testcase([], 0, f) + testcase([2, 4, 6], 0, f) + testcase([1, 2, 3], 0, f) + testcase([1, 2, 3, 4, 5, 6, 7, 8], 0, f) [0, 2, 4, 6] |> iterator.from_list() diff --git a/test/gleam/map_test.gleam b/test/gleam/map_test.gleam deleted file mode 100644 index b00331f..0000000 --- a/test/gleam/map_test.gleam +++ /dev/null @@ -1,393 +0,0 @@ -import gleam/map -import gleam/option.{None, Some} -import gleam/should -import gleam/string -import gleam/list -import gleam/int - -pub fn from_list_test() { - [#(4, 0), #(1, 0)] - |> map.from_list - |> map.size - |> should.equal(2) - - [#(1, 0), #(1, 1)] - |> map.from_list - |> should.equal(map.from_list([#(1, 1)])) -} - -pub fn has_key_test() { - [] - |> map.from_list - |> map.has_key(1) - |> should.be_false - - [#(1, 0)] - |> map.from_list - |> map.has_key(1) - |> should.be_true - - [#(4, 0), #(1, 0)] - |> map.from_list - |> map.has_key(1) - |> should.be_true - - [#(4, 0), #(1, 0)] - |> map.from_list - |> map.has_key(0) - |> should.be_false -} - -pub fn new_test() { - map.new() - |> map.size - |> should.equal(0) - - map.new() - |> map.to_list - |> should.equal([]) -} - -type Key { - A - B - C -} - -pub fn get_test() { - let proplist = [#(4, 0), #(1, 1)] - let m = map.from_list(proplist) - - m - |> map.get(4) - |> should.equal(Ok(0)) - - m - |> map.get(1) - |> should.equal(Ok(1)) - - m - |> map.get(2) - |> should.equal(Error(Nil)) - - let proplist = [#(A, 0), #(B, 1)] - let m = map.from_list(proplist) - - m - |> map.get(A) - |> should.equal(Ok(0)) - - m - |> map.get(B) - |> should.equal(Ok(1)) - - m - |> map.get(C) - |> should.equal(Error(Nil)) - - let proplist = [#(<<1, 2, 3>>, 0), #(<<3, 2, 1>>, 1)] - let m = map.from_list(proplist) - - m - |> map.get(<<1, 2, 3>>) - |> should.equal(Ok(0)) - - m - |> map.get(<<3, 2, 1>>) - |> should.equal(Ok(1)) - - m - |> map.get(<<1, 3, 2>>) - |> should.equal(Error(Nil)) -} - -pub fn insert_test() { - map.new() - |> map.insert("a", 0) - |> map.insert("b", 1) - |> map.insert("c", 2) - |> should.equal(map.from_list([#("a", 0), #("b", 1), #("c", 2)])) -} - -pub fn map_values_test() { - [#(1, 0), #(2, 1), #(3, 2)] - |> map.from_list - |> map.map_values(fn(k, v) { k + v }) - |> should.equal(map.from_list([#(1, 1), #(2, 3), #(3, 5)])) -} - -pub fn keys_test() { - [#("a", 0), #("b", 1), #("c", 2)] - |> map.from_list - |> map.keys - |> list.sort(string.compare) - |> should.equal(["a", "b", "c"]) -} - -pub fn values_test() { - [#("a", 0), #("b", 1), #("c", 2)] - |> map.from_list - |> map.values - |> list.sort(int.compare) - |> should.equal([0, 1, 2]) -} - -pub fn take_test() { - [#("a", 0), #("b", 1), #("c", 2)] - |> map.from_list - |> map.take(["a", "b", "d"]) - |> should.equal(map.from_list([#("a", 0), #("b", 1)])) -} - -pub fn drop_test() { - [#("a", 0), #("b", 1), #("c", 2)] - |> map.from_list - |> map.drop(["a", "b", "d"]) - |> should.equal(map.from_list([#("c", 2)])) -} - -pub fn merge_same_key_test() { - let a = map.from_list([#("a", 2)]) - let b = map.from_list([#("a", 0)]) - - map.merge(a, b) - |> should.equal(map.from_list([#("a", 0)])) - - map.merge(b, a) - |> should.equal(map.from_list([#("a", 2)])) -} - -pub fn merge_test() { - let a = map.from_list([#("a", 2), #("c", 4), #("d", 3)]) - let b = map.from_list([#("a", 0), #("b", 1), #("c", 2)]) - - map.merge(a, b) - |> should.equal(map.from_list([#("a", 0), #("b", 1), #("c", 2), #("d", 3)])) - - map.merge(b, a) - |> should.equal(map.from_list([#("a", 2), #("b", 1), #("c", 4), #("d", 3)])) -} - -pub fn delete_test() { - [#("a", 0), #("b", 1), #("c", 2)] - |> map.from_list - |> map.delete("a") - |> map.delete("d") - |> should.equal(map.from_list([#("b", 1), #("c", 2)])) -} - -pub fn update_test() { - let dict = map.from_list([#("a", 0), #("b", 1), #("c", 2)]) - - let inc_or_zero = fn(x) { - case x { - Some(i) -> i + 1 - None -> 0 - } - } - - dict - |> map.update("a", inc_or_zero) - |> should.equal(map.from_list([#("a", 1), #("b", 1), #("c", 2)])) - - dict - |> map.update("b", inc_or_zero) - |> should.equal(map.from_list([#("a", 0), #("b", 2), #("c", 2)])) - - dict - |> map.update("z", inc_or_zero) - |> should.equal(map.from_list([#("a", 0), #("b", 1), #("c", 2), #("z", 0)])) -} - -pub fn fold_test() { - let dict = map.from_list([#("a", 0), #("b", 1), #("c", 2), #("d", 3)]) - - let add = fn(acc, _, v) { v + acc } - - dict - |> map.fold(0, add) - |> should.equal(6) - - let prepend = fn(acc, k, _) { list.prepend(acc, k) } - - dict - |> map.fold([], prepend) - |> list.sort(string.compare) - |> should.equal(["a", "b", "c", "d"]) - - map.from_list([]) - |> map.fold(0, add) - |> should.equal(0) -} - -fn range(start, end, a) { - case end - start { - n if n < 1 -> a - _ -> range(start, end - 1, [end - 1, ..a]) - } -} - -fn list_to_map(list) { - list - |> list.map(fn(n) { #(n, n) }) - |> map.from_list -} - -fn grow_and_shrink_map(initial_size, final_size) { - range(0, initial_size, []) - |> list_to_map - |> list.fold( - range(final_size, initial_size, []), - _, - fn(map, item) { map.delete(map, item) }, - ) -} - -// maps should be equal even if the insert/removal order was different -pub fn insert_order_equality_test() { - grow_and_shrink_map(8, 2) - |> should.equal(grow_and_shrink_map(4, 2)) - grow_and_shrink_map(17, 10) - |> should.equal(grow_and_shrink_map(12, 10)) - grow_and_shrink_map(2000, 1000) - |> should.equal(grow_and_shrink_map(1000, 1000)) -} - -// ensure operations on a map don't mutate it -pub fn persistence_test() { - let a = list_to_map([0]) - map.insert(a, 0, 5) - map.insert(a, 1, 6) - map.delete(a, 0) - map.get(a, 0) - |> should.equal(Ok(0)) -} - -// using maps as keys should work (tests hash function) -pub fn map_as_key_test() { - let l = range(0, 1000, []) - let a = list_to_map(l) - let a2 = list_to_map(list.reverse(l)) - let a3 = grow_and_shrink_map(2000, 1000) - let b = grow_and_shrink_map(60, 50) - let c = grow_and_shrink_map(50, 20) - let d = grow_and_shrink_map(2, 2) - - let map1 = - map.new() - |> map.insert(a, "a") - |> map.insert(b, "b") - |> map.insert(c, "c") - |> map.insert(d, "d") - - map.get(map1, a) - |> should.equal(Ok("a")) - map.get(map1, a2) - |> should.equal(Ok("a")) - map.get(map1, a3) - |> should.equal(Ok("a")) - map.get(map1, b) - |> should.equal(Ok("b")) - map.get(map1, c) - |> should.equal(Ok("c")) - map.get(map1, d) - |> should.equal(Ok("d")) - map.insert(map1, a2, "a2") - |> map.get(a) - |> should.equal(Ok("a2")) - map.insert(map1, a3, "a3") - |> map.get(a) - |> should.equal(Ok("a3")) -} - -pub fn large_n_test() { - let n = 10_000 - let l = range(0, n, []) - - let m = list_to_map(l) - list.map(l, fn(i) { should.equal(map.get(m, i), Ok(i)) }) - - let m = grow_and_shrink_map(n, 0) - list.map(l, fn(i) { should.equal(map.get(m, i), Error(Nil)) }) -} - -pub fn size_test() { - let n = 1000 - let m = list_to_map(range(0, n, [])) - map.size(m) - |> should.equal(n) - - let m = grow_and_shrink_map(n, n / 2) - map.size(m) - |> should.equal(n / 2) - - let m = - grow_and_shrink_map(n, 0) - |> map.delete(0) - map.size(m) - |> should.equal(0) - - let m = list_to_map(range(0, 18, [])) - - map.insert(m, 1, 99) - |> map.size() - |> should.equal(18) - map.insert(m, 2, 99) - |> map.size() - |> should.equal(18) -} - -// https://github.com/gleam-lang/stdlib/issues/435 -pub fn peters_bug_test() { - map.new() - |> map.insert(22, Nil) - |> map.insert(21, Nil) - |> map.insert(23, Nil) - |> map.insert(18, Nil) - |> map.insert(17, Nil) - |> map.insert(19, Nil) - |> map.insert(14, Nil) - |> map.insert(13, Nil) - |> map.insert(15, Nil) - |> map.insert(10, Nil) - |> map.insert(9, Nil) - |> map.insert(11, Nil) - |> map.insert(6, Nil) - |> map.insert(5, Nil) - |> map.insert(7, Nil) - |> map.insert(2, Nil) - |> map.insert(1, Nil) - |> map.insert(3, Nil) - |> map.get(0) - |> should.equal(Error(Nil)) -} - -pub fn zero_must_be_contained_test() { - let map = - map.new() - |> map.insert(0, Nil) - - map - |> map.get(0) - |> should.equal(Ok(Nil)) - - map - |> map.has_key(0) - |> should.equal(True) -} - -pub fn empty_map_equality_test() { - let map1 = map.new() - let map2 = map.from_list([#(1, 2)]) - - should.be_false(map1 == map2) - should.be_false(map2 == map1) -} - -pub fn extra_keys_equality_test() { - let map1 = map.from_list([#(1, 2), #(3, 4)]) - let map2 = map.from_list([#(1, 2), #(3, 4), #(4, 5)]) - - should.be_false(map1 == map2) - should.be_false(map2 == map1) -} diff --git a/test/gleam/queue_test.gleam b/test/gleam/queue_test.gleam index 85abb59..6f8465a 100644 --- a/test/gleam/queue_test.gleam +++ b/test/gleam/queue_test.gleam @@ -35,17 +35,17 @@ pub fn is_empty_test() { } pub fn length_test() { - let test = fn(input) { + let testcase = fn(input) { queue.from_list(input) |> queue.length |> should.equal(list.length(input)) } - test([]) - test([1]) - test([1, 2]) - test([1, 2, 1]) - test([1, 2, 1, 5, 2, 7, 2, 7, 8, 4, 545]) + testcase([]) + testcase([1]) + testcase([1, 2]) + testcase([1, 2, 1]) + testcase([1, 2, 1, 5, 2, 7, 2, 7, 8, 4, 545]) } pub fn push_back_test() { diff --git a/test/gleam/should.gleam b/test/gleam/should.gleam index 4618d73..d63f6b7 100644 --- a/test/gleam/should.gleam +++ b/test/gleam/should.gleam @@ -4,78 +4,52 @@ //// More information on running eunit can be found in [the rebar3 //// documentation](https://rebar3.org/docs/testing/eunit/). -@target(erlang) -@external(erlang, "gleam_stdlib_test_ffi", "should_equal") -pub fn equal(a: a, b: a) -> Nil - -@target(erlang) -@external(erlang, "gleam_stdlib_test_ffi", "should_not_equal") -pub fn not_equal(a: a, b: a) -> Nil - -@target(erlang) -@external(erlang, "gleam_stdlib_test_ffi", "should_be_ok") -pub fn be_ok(a: Result(a, b)) -> Nil - -@target(erlang) -@external(erlang, "gleam_stdlib_test_ffi", "should_be_error") -pub fn be_error(a: Result(a, b)) -> Nil - -@target(javascript) import gleam/string -@target(javascript) -@external(javascript, "../gleam.mjs", "inspect") -fn stringify(a: anything) -> String - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "crash") -fn crash(a: String) -> anything - -@target(javascript) -pub fn equal(a, b) { +@external(erlang, "gleam_stdlib_test_ffi", "should_equal") +pub fn equal(a: a, b: a) -> Nil { case a == b { True -> Nil _ -> - crash( + panic as { string.concat([ "\n\t", - stringify(a), + string.inspect(a), "\n\tshould equal \n\t", - stringify(b), - ]), - ) + string.inspect(b), + ]) + } } } -@target(javascript) -pub fn not_equal(a, b) { +@external(erlang, "gleam_stdlib_test_ffi", "should_not_equal") +pub fn not_equal(a: a, b: a) -> Nil { case a != b { True -> Nil _ -> - crash( + panic as { string.concat([ "\n", - stringify(a), + string.inspect(a), "\nshould not equal \n", - stringify(b), - ]), - ) + string.inspect(b), + ]) + } } } -@target(javascript) -pub fn be_ok(a) { +pub fn be_ok(a: Result(a, e)) -> a { case a { - Ok(_) -> Nil - _ -> crash(string.concat(["\n", stringify(a), "\nshould be ok"])) + Ok(e) -> e + _ -> panic as { string.concat(["\n", string.inspect(a), "\nshould be ok"]) } } } -@target(javascript) pub fn be_error(a) { case a { Error(_) -> Nil - _ -> crash(string.concat(["\n", stringify(a), "\nshould be error"])) + _ -> + panic as { string.concat(["\n", string.inspect(a), "\nshould be error"]) } } } diff --git a/test/gleam_stdlib_test_ffi.erl b/test/gleam_stdlib_test_ffi.erl index ee16980..552efc4 100644 --- a/test/gleam_stdlib_test_ffi.erl +++ b/test/gleam_stdlib_test_ffi.erl @@ -1,9 +1,6 @@ -module(gleam_stdlib_test_ffi). --export([ - main/0, should_equal/2, should_not_equal/2, should_be_ok/1, - should_be_error/1, improper_list_append/3 -]). +-export([main/0, should_equal/2, should_not_equal/2, improper_list_append/3]). -include_lib("eunit/include/eunit.hrl"). @@ -32,12 +29,6 @@ should_equal(Actual, Expected) -> should_not_equal(Actual, Expected) -> ?assertNotEqual(Expected, Actual), nil. -should_be_ok(A) -> - ?assertMatch({ok, _}, A), - nil. -should_be_error(A) -> - ?assertMatch({error, _}, A), - nil. improper_list_append(ItemA, ItemB, ImproperTail) -> [ItemA, ItemB | ImproperTail]. |