diff options
author | inoas <mail@inoas.com> | 2022-05-17 18:31:37 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-17 19:31:37 +0100 |
commit | f9d57db847ff2a8471c9136bd309c870b610d04d (patch) | |
tree | 640efa9eca0636e357a7265b6db81df9be2a29c6 | |
parent | 81fbb692283a0fff2334d8f3f9f5249c5fda7172 (diff) | |
download | gleam_stdlib-f9d57db847ff2a8471c9136bd309c870b610d04d.tar.gz gleam_stdlib-f9d57db847ff2a8471c9136bd309c870b610d04d.zip |
javascript tests and fixes for string.reverse() / string.slice() / string.to_graphemes() (#298)
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | src/gleam/string.gleam | 32 | ||||
-rw-r--r-- | test/gleam/string_test.gleam | 82 |
3 files changed, 93 insertions, 23 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 02b3a65..2457140 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ - The `float` module gains the `divide` function. - The `int` module gains the `divide`, `power`, and `square_root` functions. - The `string` module gains the `first`, `last`, and `capitalise` functions. +- Fixed a bug where `string.reverse` would break utf8 strings on target JavaScript. +- Fixed a bug where `string.slice` would break utf8 strings on target JavaScript. ## v0.21.0 - 2022-04-24 diff --git a/src/gleam/string.gleam b/src/gleam/string.gleam index 37baed4..45d4d31 100644 --- a/src/gleam/string.gleam +++ b/src/gleam/string.gleam @@ -73,10 +73,25 @@ if javascript { /// ``` /// pub fn reverse(string: String) -> String { - string - |> string_builder.from_string - |> string_builder.reverse - |> string_builder.to_string + do_reverse(string) +} + +if erlang { + fn do_reverse(string: String) -> String { + string + |> string_builder.from_string + |> string_builder.reverse + |> string_builder.to_string + } +} + +if javascript { + fn do_reverse(string: String) -> String { + string + |> to_graphemes + |> list.reverse + |> concat + } } /// Creates a new `String` by replacing all occurrences of a given substring. @@ -233,8 +248,13 @@ if erlang { } if javascript { - external fn do_slice(String, Int, Int) -> String = - "../gleam_stdlib.mjs" "slice_string" + fn do_slice(string: String, idx: Int, len: Int) -> String { + string + |> to_graphemes + |> list.drop(idx) + |> list.take(len) + |> concat + } } /// Drops contents of the first `String` that occur before the second `String`. diff --git a/test/gleam/string_test.gleam b/test/gleam/string_test.gleam index bb9aff0..4c73b41 100644 --- a/test/gleam/string_test.gleam +++ b/test/gleam/string_test.gleam @@ -25,13 +25,34 @@ pub fn uppercase_test() { } pub fn reverse_test() { - string.reverse("Gleam") + "Gleam" + |> string.reverse |> should.equal("maelG") -} -pub fn unicode_reverse_test() { - string.reverse("👍 OK") + " Gleam" + |> string.reverse + |> should.equal("maelG ") + + "👍 OK" + |> string.reverse |> should.equal("KO 👍") + + "👍" + |> string.reverse + |> should.equal("👍") + + "ÅÄÖ" + |> string.reverse + |> should.equal("ÖÄÅ") + + "👶🏿" + |> string.reverse + |> should.equal("👶🏿") + + "👶🏿" + |> string.reverse + |> string.reverse + |> should.equal("👶🏿") } pub fn split_test() { @@ -132,19 +153,19 @@ pub fn join_test() { pub fn trim_test() { " hats \n" - |> string.trim() + |> string.trim |> should.equal("hats") } pub fn trim_left_test() { " hats \n" - |> string.trim_left() + |> string.trim_left |> should.equal("hats \n") } pub fn trim_right_test() { " hats \n" - |> string.trim_right() + |> string.trim_right |> should.equal(" hats") } @@ -208,6 +229,10 @@ pub fn slice_test() { "gleam" |> string.slice(at_index: 2, length: -3) |> should.equal("") + + "👶🏿" + |> string.slice(at_index: 0, length: 3) + |> should.equal("👶🏿") } pub fn crop_test() { @@ -313,30 +338,53 @@ pub fn pad_right_test() { pub fn pop_grapheme_test() { "gleam" - |> string.pop_grapheme() + |> string.pop_grapheme |> should.equal(Ok(#("g", "leam"))) "g" - |> string.pop_grapheme() + |> string.pop_grapheme |> should.equal(Ok(#("g", ""))) "" - |> string.pop_grapheme() + |> string.pop_grapheme |> should.equal(Error(Nil)) } pub fn to_graphemes_test() { - "abc" - |> string.to_graphemes() - |> should.equal(["a", "b", "c"]) + "" + |> string.to_graphemes + |> should.equal([]) + + "\n\t\r\"\\" + |> string.to_graphemes + |> should.equal(["\n", "\t", "\r", "\"", "\\"]) "a" - |> string.to_graphemes() + |> string.to_graphemes |> should.equal(["a"]) - "" - |> string.to_graphemes() - |> should.equal([]) + "abc" + |> string.to_graphemes + |> should.equal(["a", "b", "c"]) + + "🌷🎁💩😜👍🏳️🌈" + |> string.to_graphemes + |> should.equal(["🌷", "🎁", "💩", "😜", "👍", "🏳️🌈"]) + + "Ĺo͂řȩm̅" + |> string.to_graphemes + |> should.equal(["Ĺ", "o͂", "ř", "ȩ", "m̅"]) + + "뎌쉐" + |> string.to_graphemes + |> should.equal(["뎌", "쉐"]) + + "Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯̞̠͍A̴̵̜̰͔ͫ͗͢L̠ͨͧͩ͘G̴̻͈͍͔̹̑͗̎̅͛́Ǫ̵̹̻̝̳͂̌̌͘!͖̬̰̙̗̿̋ͥͥ̂ͣ̐́́͜͞" + |> string.to_graphemes + |> should.equal([ + "Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯̞̠͍", "A̴̵̜̰͔ͫ͗͢", "L̠ͨͧͩ͘", + "G̴̻͈͍͔̹̑͗̎̅͛́", "Ǫ̵̹̻̝̳͂̌̌͘", "!͖̬̰̙̗̿̋ͥͥ̂ͣ̐́́͜͞", + ]) } pub fn utf_codepoint_test() { |