Locale.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. describe("errors", () => {
  2. test("called without new", () => {
  3. expect(() => {
  4. Intl.Locale();
  5. }).toThrowWithMessage(TypeError, "Intl.Locale constructor must be called with 'new'");
  6. });
  7. test("tag is neither object nor string", () => {
  8. expect(() => {
  9. new Intl.Locale(1);
  10. }).toThrowWithMessage(TypeError, "tag is neither an object nor a string");
  11. });
  12. test("structurally invalid tag", () => {
  13. expect(() => {
  14. new Intl.Locale("root");
  15. }).toThrowWithMessage(RangeError, "root is not a structurally valid language tag");
  16. expect(() => {
  17. new Intl.Locale("en-");
  18. }).toThrowWithMessage(RangeError, "en- is not a structurally valid language tag");
  19. expect(() => {
  20. new Intl.Locale("Latn");
  21. }).toThrowWithMessage(RangeError, "Latn is not a structurally valid language tag");
  22. expect(() => {
  23. new Intl.Locale("en-u-aa-U-aa");
  24. }).toThrowWithMessage(RangeError, "en-u-aa-U-aa is not a structurally valid language tag");
  25. });
  26. test("locale option fields are not valid Unicode TR35 subtags", () => {
  27. expect(() => {
  28. new Intl.Locale("en", { language: "a" });
  29. }).toThrowWithMessage(RangeError, "a is not a valid value for option language");
  30. expect(() => {
  31. new Intl.Locale("en", { script: "a" });
  32. }).toThrowWithMessage(RangeError, "a is not a valid value for option script");
  33. expect(() => {
  34. new Intl.Locale("en", { region: "a" });
  35. }).toThrowWithMessage(RangeError, "a is not a valid value for option region");
  36. });
  37. test("keyword option fields are not valid Unicode TR35 types", () => {
  38. expect(() => {
  39. new Intl.Locale("en", { calendar: "a" });
  40. }).toThrowWithMessage(RangeError, "a is not a valid value for option calendar");
  41. expect(() => {
  42. new Intl.Locale("en", { collation: "a" });
  43. }).toThrowWithMessage(RangeError, "a is not a valid value for option collation");
  44. expect(() => {
  45. new Intl.Locale("en", { hourCycle: "a" });
  46. }).toThrowWithMessage(RangeError, "a is not a valid value for option hourCycle");
  47. expect(() => {
  48. new Intl.Locale("en", { caseFirst: "a" });
  49. }).toThrowWithMessage(RangeError, "a is not a valid value for option caseFirst");
  50. });
  51. });
  52. describe("normal behavior", () => {
  53. test("length is 1", () => {
  54. expect(Intl.Locale).toHaveLength(1);
  55. });
  56. test("locale option fields create subtags", () => {
  57. const sr = new Intl.Locale("sr", { script: "Latn" });
  58. expect(sr.toString()).toBe("sr-Latn");
  59. const en = new Intl.Locale("en", { region: "US" });
  60. expect(en.toString()).toBe("en-US");
  61. });
  62. test("locale option fields replace subtags", () => {
  63. const es = new Intl.Locale("en", { language: "es" });
  64. expect(es.toString()).toBe("es");
  65. const sr = new Intl.Locale("sr-Latn", { script: "Cyrl" });
  66. expect(sr.toString()).toBe("sr-Cyrl");
  67. const en = new Intl.Locale("en-US", { region: "GB" });
  68. expect(en.toString()).toBe("en-GB");
  69. });
  70. test("construction from another locale", () => {
  71. const en1 = new Intl.Locale("en", { region: "US" });
  72. const en2 = new Intl.Locale(en1, { script: "Latn" });
  73. expect(en2.toString()).toBe("en-Latn-US");
  74. });
  75. test("locale is canonicalized", () => {
  76. const en = new Intl.Locale("EN", { script: "lAtN", region: "us" });
  77. expect(en.toString()).toBe("en-Latn-US");
  78. });
  79. test("calendar extension", () => {
  80. const en1 = new Intl.Locale("en-u-ca-abc");
  81. expect(en1.toString()).toBe("en-u-ca-abc");
  82. const en2 = new Intl.Locale("en", { calendar: "abc" });
  83. expect(en2.toString()).toBe("en-u-ca-abc");
  84. const en3 = new Intl.Locale("en-u-ca-abc", { calendar: "def" });
  85. expect(en3.toString()).toBe("en-u-ca-def");
  86. });
  87. test("collation extension", () => {
  88. const en1 = new Intl.Locale("en-u-co-abc");
  89. expect(en1.toString()).toBe("en-u-co-abc");
  90. const en2 = new Intl.Locale("en", { collation: "abc" });
  91. expect(en2.toString()).toBe("en-u-co-abc");
  92. const en3 = new Intl.Locale("en-u-co-abc", { collation: "def" });
  93. expect(en3.toString()).toBe("en-u-co-def");
  94. });
  95. test("hour-cycle extension", () => {
  96. const en1 = new Intl.Locale("en-u-hc-h11");
  97. expect(en1.toString()).toBe("en-u-hc-h11");
  98. const en2 = new Intl.Locale("en", { hourCycle: "h12" });
  99. expect(en2.toString()).toBe("en-u-hc-h12");
  100. const en3 = new Intl.Locale("en-u-hc-h23", { hourCycle: "h24" });
  101. expect(en3.toString()).toBe("en-u-hc-h24");
  102. });
  103. test("case-first extension", () => {
  104. const en1 = new Intl.Locale("en-u-kf-upper");
  105. expect(en1.toString()).toBe("en-u-kf-upper");
  106. const en2 = new Intl.Locale("en", { caseFirst: "lower" });
  107. expect(en2.toString()).toBe("en-u-kf-lower");
  108. const en3 = new Intl.Locale("en-u-kf-upper", { caseFirst: "false" });
  109. expect(en3.toString()).toBe("en-u-kf-false");
  110. });
  111. test("numeric extension", () => {
  112. // Note: "true" values are removed from Unicode locale extensions during canonicalization.
  113. const en1 = new Intl.Locale("en-u-kn-true");
  114. expect(en1.toString()).toBe("en-u-kn");
  115. const en2 = new Intl.Locale("en", { numeric: false });
  116. expect(en2.toString()).toBe("en-u-kn-false");
  117. const en3 = new Intl.Locale("en-u-kn-false", { numeric: 1 });
  118. expect(en3.toString()).toBe("en-u-kn");
  119. });
  120. test("numbering-system extension", () => {
  121. const en1 = new Intl.Locale("en-u-nu-abc");
  122. expect(en1.toString()).toBe("en-u-nu-abc");
  123. const en2 = new Intl.Locale("en", { numberingSystem: "abc" });
  124. expect(en2.toString()).toBe("en-u-nu-abc");
  125. const en3 = new Intl.Locale("en-u-nu-abc", { numberingSystem: "def" });
  126. expect(en3.toString()).toBe("en-u-nu-def");
  127. });
  128. test("unicode extension inserted before private use extension", () => {
  129. const en1 = new Intl.Locale("en-x-abcd", { calendar: "abc" });
  130. expect(en1.toString()).toBe("en-u-ca-abc-x-abcd");
  131. });
  132. });