diff options
author | Danny Martini <despair.blue@gmail.com> | 2023-04-29 15:23:27 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-29 14:23:27 +0100 |
commit | 8924398359342ad33e99d707a3c8a7fb44d99da0 (patch) | |
tree | b87de09c589474d8d23226d07b740f0cc7da65c7 | |
parent | 13f8dc62e08fb499e600a4bcacfae7a29008dbfa (diff) | |
download | gleam_stdlib-8924398359342ad33e99d707a3c8a7fb44d99da0.tar.gz gleam_stdlib-8924398359342ad33e99d707a3c8a7fb44d99da0.zip |
fix decode_map throwing when `null` is being passed in (#432)
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rw-r--r-- | src/gleam_stdlib.erl | 1 | ||||
-rw-r--r-- | src/gleam_stdlib.mjs | 18 | ||||
-rw-r--r-- | test/gleam/dynamic_test.gleam | 34 | ||||
-rwxr-xr-x | test/gleam_stdlib_test_ffi.mjs | 4 |
5 files changed, 56 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index f6504dd..a21b485 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Don't crash when `null` or `undefined` is passed to `dynamic.map` + +## v0.28.1 - 2023-04-10 - The `iterator` module gains the `each` function. - Fixed a bug in maps when running on JavaScript where value membership could be incorrectly stated in some cases. diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl index e1fdbb1..33c9609 100644 --- a/src/gleam_stdlib.erl +++ b/src/gleam_stdlib.erl @@ -41,6 +41,7 @@ decode_error_msg(Expected, Data) when is_binary(Expected) -> decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> {error, [{decode_error, Expected, Got, []}]}. +classify_dynamic(nil) -> <<"Nil">>; classify_dynamic(X) when is_atom(X) -> <<"Atom">>; classify_dynamic(X) when is_binary(X) -> <<"String">>; classify_dynamic(X) when is_bitstring(X) -> <<"BitString">>; diff --git a/src/gleam_stdlib.mjs b/src/gleam_stdlib.mjs index 632c668..2b0a6e1 100644 --- a/src/gleam_stdlib.mjs +++ b/src/gleam_stdlib.mjs @@ -392,11 +392,11 @@ export function regex_scan(regex, string) { const submatches = []; for (let n = match.length - 1; n > 0; n--) { if (match[n]) { - submatches[n-1] = new Some(match[n]) - continue + submatches[n - 1] = new Some(match[n]); + continue; } - if(submatches.length > 0) { - submatches[n-1] = new None() + if (submatches.length > 0) { + submatches[n - 1] = new None(); } } return new RegexMatch(content, List.fromArray(submatches)); @@ -564,6 +564,10 @@ export function classify_dynamic(data) { return "Map"; } else if (typeof data === "number") { return "Float"; + } else if (data === null) { + return "Null"; + } else if (data === undefined) { + return "Nil"; } else { let type = typeof data; return type.charAt(0).toUpperCase() + type.slice(1); @@ -633,6 +637,12 @@ export function decode_map(data) { if (data instanceof PMap) { return new Ok(PMap.fromMap(data)); } + if (data == null) { + return decoder_error("Map", data); + } + if (typeof data !== "object") { + return decoder_error("Map", data); + } const proto = Object.getPrototypeOf(data); if (proto === Object.prototype || proto === null) { return new Ok(PMap.fromObject(data)); diff --git a/test/gleam/dynamic_test.gleam b/test/gleam/dynamic_test.gleam index ffd8b73..a220e6e 100644 --- a/test/gleam/dynamic_test.gleam +++ b/test/gleam/dynamic_test.gleam @@ -51,6 +51,35 @@ if javascript { } } +if erlang { + pub type MyAtom { + ThisIsAnAtom + } + + pub fn map_from_atom_test() { + ThisIsAnAtom + |> dynamic.from + |> dynamic.map(dynamic.string, dynamic.int) + |> should.equal(Error([ + DecodeError(expected: "Map", found: "Atom", path: []), + ])) + } +} + +if javascript { + external fn get_null() -> dynamic.Dynamic = + "../gleam_stdlib_test_ffi.mjs" "get_null" + + pub fn map_from_null_test() { + get_null() + |> dynamic.from + |> dynamic.map(dynamic.string, dynamic.int) + |> should.equal(Error([ + DecodeError(expected: "Map", found: "Null", path: []), + ])) + } +} + pub fn string_test() { "" |> dynamic.from @@ -758,6 +787,11 @@ pub fn map_test() { |> should.equal(Error([ DecodeError(expected: "Map", found: "Function", path: []), ])) + + Nil + |> dynamic.from + |> dynamic.map(dynamic.string, dynamic.int) + |> should.equal(Error([DecodeError(expected: "Map", found: "Nil", path: [])])) } pub fn shallow_list_test() { diff --git a/test/gleam_stdlib_test_ffi.mjs b/test/gleam_stdlib_test_ffi.mjs index 68922c9..c859093 100755 --- a/test/gleam_stdlib_test_ffi.mjs +++ b/test/gleam_stdlib_test_ffi.mjs @@ -6,3 +6,7 @@ export function uint8array(list) { } return array; } + +export function get_null() { + return null; +} |