1# Note: for manual testing on Mac, the following can be used to set a multi-byte
2# but non-UTF-8 locale:
3# Sys.setlocale("LC_ALL", "ja_JP.SJIS")
4
5
6test_that("Non-ASCII keys are represented as UTF-8", {
7  m <- fastmap()
8
9  k1 <- "abc"
10  # "åbc" in UTF-8
11  k2 <- "\u00e5bc"
12  # "åbc" in latin1
13  k3 <- iconv(k2, from = "UTF-8", to = "latin1")
14  # "中 A" in UTF-8
15  k4 <- "\u4e2d A"
16
17  expect_identical(Encoding(k2), "UTF-8")
18  expect_identical(Encoding(k3), "latin1")
19  expect_identical(Encoding(k4), "UTF-8")
20
21  m$set(k1, 1)
22  m$set(k2, 2)
23  # Should overwrite k2 since the keys are the same strings in different
24  # encodings, and fastmap converts keys to UTF-8.
25  m$set(k3, 3)
26  m$set(k4, 4)
27  expect_identical(m$get(k1), 1)
28  expect_identical(m$get(k2), 3)
29  expect_identical(m$get(k3), 3)
30  expect_identical(m$get(k4), 4)
31
32  # keys() should be in UTF-8
33  keys <- m$keys()
34  # Note: expect_setequal (and expect_identical, for that matter) compares
35  # strings but converts them to the same encoding before comparison, so we need
36  # to separately check encoding.
37  expect_setequal(keys, c(k1, k2, k4))
38  expect_true(Encoding(keys[keys == k1]) == "unknown")
39  expect_true(Encoding(keys[keys == k2]) == "UTF-8")
40  expect_true(Encoding(keys[keys == k3]) == "UTF-8")
41  expect_true(Encoding(keys[keys == k4]) == "UTF-8")
42
43  # names for as_list() should be in UTF-8
44  m_list <- m$as_list()
45  expect_mapequal(
46    m_list,
47    setNames(list(1, 3, 4), c(k1, k2, k4))
48  )
49  keys <- names(m_list)
50  expect_setequal(keys, c(k1, k2, k4))
51  expect_true(Encoding(keys[keys == k1]) == "unknown")
52  expect_true(Encoding(keys[keys == k2]) == "UTF-8")
53  expect_true(Encoding(keys[keys == k3]) == "UTF-8")
54  expect_true(Encoding(keys[keys == k4]) == "UTF-8")
55})
56
57
58test_that("Non-ASCII keys with mset and mget", {
59  m <- fastmap()
60
61  k1 <- "abc"
62  # "åbc" in UTF-8
63  k2 <- "\u00e5bc"
64  # "åbc" in latin1
65  k3 <- iconv(k2, from = "UTF-8", to = "latin1")
66  # "中 A" in UTF-8
67  k4 <- "\u4e2d A"
68
69  args <- setNames(list(1, 2, 3, 4), c(k1, k2, k3, k4))
70  expect_identical(
71    Encoding(names(args)),
72    c("unknown", "UTF-8", "latin1", "UTF-8")
73  )
74
75  # These are just here for comparison purposes. R will convert the argument
76  # names to native encoding before fastmap can convert the names (keys) to
77  # UTF-8. In a UTF-8 locale, the tests below would pass; in some non-UTF-8
78  # locales, the tests would fail. They're commented out because we can't expect
79  # them to pass on all platforms.
80  # do.call(m$mset, args)
81  # expect_identical(m$get(k1), 1)
82  # expect_identical(m$get(k2), 3)
83  # expect_identical(m$get(k3), 3)
84  # expect_identical(m$get(k4), 4)
85
86  # Same as above, but using .list. This should succeed in all locales.
87  m <- fastmap()
88  m$mset(.list = args)
89  expect_identical(m$get(k1), 1)
90  expect_identical(m$get(k2), 3)
91  expect_identical(m$get(k3), 3)
92  expect_identical(m$get(k4), 4)
93
94  # names for as_list() should be in UTF-8
95  m_list <- m$as_list()
96  expect_mapequal(
97    m_list,
98    setNames(list(1, 3, 4), c(k1, k2, k4))
99  )
100  keys <- names(m_list)
101  expect_setequal(keys, c(k1, k2, k4))
102  expect_true(Encoding(keys[keys == k1]) == "unknown")
103  expect_true(Encoding(keys[keys == k2]) == "UTF-8")
104  expect_true(Encoding(keys[keys == k3]) == "UTF-8")
105  expect_true(Encoding(keys[keys == k4]) == "UTF-8")
106
107  # mget will convert the latin1 key to UTF-8
108  res <- m$mget(c(k1, k2, k3, k4))
109  expect_identical(
110    Encoding(names(res)),
111    c("unknown", "UTF-8", "UTF-8", "UTF-8")
112  )
113  expect_identical(names(res), c(k1, k2, k2, k4))
114  expect_identical(unname(res), list(1, 3, 3, 4))
115})
116