aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorinoas <mail@inoas.com>2022-05-17 18:31:37 +0000
committerGitHub <noreply@github.com>2022-05-17 19:31:37 +0100
commitf9d57db847ff2a8471c9136bd309c870b610d04d (patch)
tree640efa9eca0636e357a7265b6db81df9be2a29c6
parent81fbb692283a0fff2334d8f3f9f5249c5fda7172 (diff)
downloadgleam_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.md2
-rw-r--r--src/gleam/string.gleam32
-rw-r--r--test/gleam/string_test.gleam82
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() {