Coverage for src/tests/test_i18next.py: 100%

104 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-12-25 10:58 +0000

1import pytest 

2 

3from couchers.i18n.i18next import I18Next, LocalizationError 

4from couchers.i18n.plurals import PluralRules 

5 

6 

7def test_lookup(): 

8 i18next = I18Next() 

9 i18next.add_language("en", PluralRules.en).add_string("greeting", "hello") 

10 assert i18next.localize("greeting", "en") == "hello" 

11 

12 

13def test_substitution(): 

14 i18next = I18Next() 

15 i18next.add_language("en", PluralRules.en).add_string("greeting", "hello {{name}}!") 

16 assert i18next.localize("greeting", "en", {"name": "world"}) == "hello world!" 

17 

18 

19def test_localized(): 

20 i18next = I18Next() 

21 en = i18next.add_language("en", PluralRules.en) 

22 en.add_string("greeting", "hello") 

23 fr = i18next.add_language("fr", PluralRules.en) 

24 fr.add_string("greeting", "bonjour") 

25 fr.fallback = en 

26 assert i18next.localize("greeting", "fr") == "bonjour" 

27 

28 

29def test_fallback(): 

30 i18next = I18Next() 

31 en = i18next.add_language("en", PluralRules.en) 

32 en.add_string("greeting", "hello") 

33 fr = i18next.add_language("fr", PluralRules.en) 

34 fr.fallback = en 

35 assert i18next.localize("greeting", "fr") == "hello" 

36 

37 

38def test_plural_suffixes(): 

39 i18next = I18Next() 

40 en = i18next.add_language("en", PluralRules.en) 

41 en.add_string("apples_one", "{{count}} apple") 

42 en.add_string("apples_other", "{{count}} apples") 

43 assert i18next.localize("apples", "en", {"count": 1}) == "1 apple" 

44 assert i18next.localize("apples", "en", {"count": 2}) == "2 apples" 

45 

46 

47def test_plural_suffix_fallback(): 

48 i18next = I18Next() 

49 en = i18next.add_language("en", PluralRules.en) 

50 en.add_string("apples", "{{count}} apples") 

51 en.add_string("apples_one", "{{count}} apple") 

52 assert i18next.localize("apples", "en", {"count": 1}) == "1 apple" 

53 assert i18next.localize("apples", "en", {"count": 2}) == "2 apples" 

54 

55 

56def test_plural_no_count(): 

57 i18next = I18Next() 

58 en = i18next.add_language("en", PluralRules.en) 

59 en.add_string("apples_one", "apple") 

60 en.add_string("apples_other", "apples") 

61 assert i18next.localize("apples", "en", {"count": 1}) == "apple" 

62 assert i18next.localize("apples", "en", {"count": 2}) == "apples" 

63 

64 

65def test_load_simple_json(): 

66 i18next = I18Next() 

67 en = i18next.add_language("en", PluralRules.en) 

68 en.load_json_dict({"greeting": "hello"}) 

69 assert i18next.localize("greeting", "en") == "hello" 

70 

71 

72def test_load_nested_json(): 

73 i18next = I18Next() 

74 en = i18next.add_language("en", PluralRules.en) 

75 en.load_json_dict({"greeting": {"short": "hi"}}) 

76 assert i18next.localize("greeting.short", "en") == "hi" 

77 

78 

79def test_fallback_locale(): 

80 i18next = I18Next() 

81 en = i18next.add_language("en", PluralRules.en) 

82 en.add_string("greeting", "hello") 

83 i18next.fallback_language = en 

84 assert i18next.localize("greeting", "fr") == "hello" 

85 

86 

87def test_missing_locale(): 

88 i18next = I18Next() 

89 with pytest.raises(LocalizationError) as raised: 

90 i18next.localize("greeting", "en") 

91 assert raised.value.language_code == "en" 

92 assert raised.value.string_key == "greeting" 

93 

94 

95def test_missing_string(): 

96 i18next = I18Next() 

97 i18next.add_language("en", PluralRules.en) 

98 with pytest.raises(LocalizationError) as raised: 

99 i18next.localize("greeting", "en") 

100 assert raised.value.language_code == "en" 

101 assert raised.value.string_key == "greeting" 

102 

103 

104def test_missing_plural_form(): 

105 i18next = I18Next() 

106 en = i18next.add_language("en", PluralRules.en) 

107 en.add_string("apples_one", "{{count}} apple") 

108 assert i18next.localize("apples", "en", {"count": 1}) == "1 apple" 

109 with pytest.raises(LocalizationError) as raised: 

110 i18next.localize("apples", "en", {"count": 2}) 

111 assert raised.value.language_code == "en" 

112 assert raised.value.string_key == "apples" 

113 

114 

115def test_extra_substitution(): 

116 i18next = I18Next() 

117 i18next.add_language("en", PluralRules.en).add_string("greeting", "hello") 

118 assert i18next.localize("greeting", "en", substitutions={"e": "mc2"}) 

119 

120 

121def test_missing_substitution(): 

122 i18next = I18Next() 

123 i18next.add_language("en", PluralRules.en).add_string("greeting", "hello {{name}}") 

124 with pytest.raises(LocalizationError) as raised: 

125 i18next.localize("greeting", "en") 

126 assert raised.value.language_code == "en" 

127 assert raised.value.string_key == "greeting" 

128 

129 

130def test_missing_substitution_fallback(): 

131 i18next = I18Next() 

132 en = i18next.add_language("en", PluralRules.en) 

133 en.add_string("greeting", "hello {{name}}") 

134 fr = i18next.add_language("fr", PluralRules.fr) 

135 fr.add_string("greeting", "bonjour {{nom}}") 

136 fr.fallback = en 

137 assert i18next.localize("greeting", "fr", substitutions={"name": "world"}) == "hello world"