slang 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ module Slang
2
+ VERSION = "0.34.0"
3
+ end
@@ -0,0 +1,20 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "slang/version"
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "slang"
7
+ gem.version = Slang::VERSION
8
+ gem.authors = ["Adrian B. Danieli"]
9
+ gem.email = ["support@getslang.com"]
10
+ gem.summary = "Slang Ruby Client"
11
+ gem.homepage = "https://getslang.com/"
12
+
13
+ gem.files = `git ls-files`.split
14
+ gem.test_files = gem.files.grep(%r{\Atest/})
15
+ gem.require_paths = ["lib"]
16
+
17
+ gem.required_ruby_version = ">= 2.0.0"
18
+
19
+ gem.add_runtime_dependency "oj", "~> 2.12"
20
+ end
@@ -0,0 +1,64 @@
1
+ [
2
+ 6,
3
+ "6DIMm9XmJ5GkYOBpV9Hg",
4
+ 1403213582,
5
+ "en",
6
+ [
7
+ ["de","en","one_other",true,"german","deutsch"],
8
+ ["en",null,"one_other",true]
9
+ ],
10
+ [
11
+ ["apples_bananas","apples=N:bananas=N",
12
+ [
13
+ "one:one","",
14
+ "one:other","",
15
+ "one:zero","",
16
+ "other:one","",
17
+ "other:other","",
18
+ "other:zero","",
19
+ "zero:one","",
20
+ "zero:other","",
21
+ "zero:zero",""
22
+ ],
23
+ [
24
+ "one:one","I'll eat one apple and one banana.",
25
+ "one:other","I'll eat one apple, and then I'll eat {bananas} bananas.",
26
+ "one:zero","I'll eat one apple, but no bananas.",
27
+ "other:one","I'll eat {apples} apples, but just one banana.",
28
+ "other:other","I'll eat {apples} apples and {bananas} bananas.",
29
+ "other:zero","I'll eat {apples} apples, but no bananas.",
30
+ "zero:one","I don't like apples, but I'll eat a banana.",
31
+ "zero:other","I don't like apples, but I'll eat {bananas} bananas.",
32
+ "zero:zero","I don't like to eat apples nor bananas."
33
+ ]
34
+ ],
35
+ ["foo","","voo","foo"],
36
+ ["hello","","Guten Tag {a} und {b}.","Hello {a} and {b}."],
37
+ ["missing","","","Found in English"],
38
+ ["profile_update","gender=G",
39
+ [
40
+ "female","",
41
+ "male","",
42
+ "unknown",""
43
+ ],
44
+ [
45
+ "female","{name} updated her profile.",
46
+ "male","{name} updated his profile.",
47
+ "unknown","{name} updated their profile."
48
+ ]
49
+ ],
50
+ ["unread","count=N",
51
+ [
52
+ "one","",
53
+ "other","",
54
+ "zero",""
55
+ ],
56
+ [
57
+ "one","You have one unread message.",
58
+ "other","You have {count} unread messages.",
59
+ "zero",""
60
+ ]
61
+ ],
62
+ ["welcome","","Willkommen {user}!","Welcome {user}!"]
63
+ ]
64
+ ]
@@ -0,0 +1,4 @@
1
+ require "bundler/setup"
2
+ require "minitest/autorun"
3
+ module Slang; TEST=true; end
4
+ require "slang"
@@ -0,0 +1,47 @@
1
+ require "helper"
2
+
3
+ module Slang
4
+ class TestLocale < Minitest::Test
5
+ Locale = Snapshot::Locale
6
+ parallelize_me!
7
+
8
+ def setup
9
+ @array = ["de", "en", "one_other", true, "german"]
10
+ @locale = Locale.new(@array, 2)
11
+ end
12
+
13
+ def test_code_symbolized
14
+ assert_equal(:de, @locale.code)
15
+ end
16
+
17
+ def test_fallback_symbolized
18
+ assert_equal(:en, @locale.fallback)
19
+ end
20
+
21
+ def test_aliases_symbolized
22
+ assert_equal([ :german ], @locale.aliases)
23
+ end
24
+
25
+ def test_pluralization_method
26
+ assert_equal(:pluralization_one_other, @locale.pluralization_method)
27
+ end
28
+
29
+ def test_translation_index
30
+ assert_equal(2, @locale.translation_index)
31
+ end
32
+
33
+ def test_missing_fallback
34
+ @array[1] = nil
35
+ locale = Locale.new(@array, 0)
36
+ assert_nil(locale.fallback)
37
+ end
38
+
39
+ def test_missing_aliases
40
+ @array = @array.slice(0,4)
41
+ locale = Locale.new(@array, 0)
42
+ assert_empty(locale.aliases)
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,133 @@
1
+ require "helper"
2
+
3
+ module Slang
4
+ class TestRules < Minitest::Test
5
+ Rules = Snapshot::Rules
6
+ Locale = Snapshot::Locale
7
+
8
+ parallelize_me!
9
+
10
+ def setup
11
+ @rules = Object.new.extend(Rules)
12
+ end
13
+
14
+ def test_rules_from_pattern
15
+ gender_rule = [ "gender", :gender ]
16
+ count_rule = [ "count", :pluralization ]
17
+ number_rule = [ "num", :pluralization ]
18
+
19
+ assert_equal([gender_rule], @rules.rules_from_pattern("gender=G"))
20
+ assert_equal([count_rule], @rules.rules_from_pattern("count=N"))
21
+ assert_equal([gender_rule, count_rule], @rules.rules_from_pattern("gender=G:count=N"))
22
+ assert_equal([count_rule, gender_rule, number_rule], @rules.rules_from_pattern("count=N:gender=G:num=N"))
23
+ end
24
+
25
+ def test_evaluate_rule
26
+ locale = Locale.new(["de","en","one_other",true,"german"], 0)
27
+
28
+ assert_equal(Rules::GENDER_FEMALE, @rules.evaluate_rule(locale, :gender, "Female"))
29
+ assert_equal(Rules::GENDER_MALE, @rules.evaluate_rule(locale, :gender, "M"))
30
+ assert_equal(Rules::GENDER_UNKNOWN, @rules.evaluate_rule(locale, :gender, nil))
31
+
32
+ assert_equal(Rules::PLURAL_ZERO_OR_OTHER, @rules.evaluate_rule(locale, :pluralization, 0))
33
+ assert_equal(Rules::PLURAL_ONE, @rules.evaluate_rule(locale, :pluralization, 1))
34
+ assert_equal(Rules::PLURAL_OTHER, @rules.evaluate_rule(locale, :pluralization, 2))
35
+ end
36
+
37
+ def test_gender
38
+ assert_equal(Rules::GENDER_FEMALE, @rules.gender(:female))
39
+ assert_equal(Rules::GENDER_MALE, @rules.gender(:male))
40
+ assert_equal(Rules::GENDER_UNKNOWN, @rules.gender(:unknown))
41
+ assert_equal(Rules::GENDER_UNKNOWN, @rules.gender(nil))
42
+ end
43
+
44
+ def test_genderize
45
+ assert_equal(:female, @rules.genderize(:female))
46
+ assert_equal(:female, @rules.genderize("female"))
47
+ assert_equal(:female, @rules.genderize("FEMALE"))
48
+ assert_equal(:female, @rules.genderize("f"))
49
+ assert_equal(:female, @rules.genderize("F"))
50
+ assert_equal(:female, @rules.genderize(:F))
51
+
52
+ assert_equal(:male, @rules.genderize(:male))
53
+ assert_equal(:male, @rules.genderize("male"))
54
+ assert_equal(:male, @rules.genderize("MALE"))
55
+ assert_equal(:male, @rules.genderize("m"))
56
+ assert_equal(:male, @rules.genderize("M"))
57
+ assert_equal(:male, @rules.genderize(:M))
58
+
59
+ assert_equal(:unknown, @rules.genderize(:unknown))
60
+ assert_equal(:unknown, @rules.genderize(nil))
61
+ assert_equal(:unknown, @rules.genderize("unknown"))
62
+ assert_equal(:unknown, @rules.genderize("UNKNOWN"))
63
+ assert_equal(:unknown, @rules.genderize(""))
64
+ end
65
+
66
+ def test_pluralization_other
67
+ assert_equal(Rules::PLURAL_ZERO_OR_OTHER, @rules.pluralization_other(0))
68
+ [1, 1.1, 2, 3, 4, 5, 10, 11, 12, 20, 21, 22, 98, 99, 100].each do |n|
69
+ assert_equal(Rules::PLURAL_OTHER, @rules.pluralization_other(n))
70
+ end
71
+ end
72
+
73
+ def test_pluralization_one_other
74
+ assert_equal(Rules::PLURAL_ZERO_OR_OTHER, @rules.pluralization_one_other(0))
75
+ assert_equal(Rules::PLURAL_ONE, @rules.pluralization_one_other(1))
76
+ [1.1, 2, 3, 4, 5, 10, 11, 12, 20, 21, 22, 98, 99, 100].each do |n|
77
+ assert_equal(Rules::PLURAL_OTHER, @rules.pluralization_one_other(n))
78
+ end
79
+ end
80
+
81
+ def test_pluralization_zero_and_one_other
82
+ assert_equal(Rules::PLURAL_ZERO_OR_ONE, @rules.pluralization_zero_and_one_other(0))
83
+ assert_equal(Rules::PLURAL_ONE, @rules.pluralization_zero_and_one_other(1))
84
+ [1.1, 2, 3, 4, 5, 10, 11, 12, 20, 21, 22, 98, 99, 100].each do |n|
85
+ assert_equal(Rules::PLURAL_OTHER, @rules.pluralization_zero_and_one_other(n))
86
+ end
87
+ end
88
+
89
+ def test_pluralization_east_slavic
90
+ assert_equal(Rules::PLURAL_ZERO_OR_MANY, @rules.pluralization_east_slavic(0))
91
+ [1, 21, 31, 41, 91, 101].each do |n|
92
+ assert_equal(Rules::PLURAL_ONE, @rules.pluralization_east_slavic(n))
93
+ end
94
+ [2, 3, 4, 22, 23, 24, 92, 93, 94, 102, 103, 104].each do |n|
95
+ assert_equal(Rules::PLURAL_FEW, @rules.pluralization_east_slavic(n))
96
+ end
97
+ [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 29, 90, 95, 99, 100].each do |n|
98
+ assert_equal(Rules::PLURAL_MANY, @rules.pluralization_east_slavic(n))
99
+ end
100
+ assert_equal(Rules::PLURAL_OTHER, @rules.pluralization_east_slavic(1.1))
101
+ end
102
+
103
+ def test_pluralization_arabic
104
+ assert_equal(Rules::PLURAL_ZERO, @rules.pluralization_arabic(0))
105
+ assert_equal(Rules::PLURAL_ONE, @rules.pluralization_arabic(1))
106
+ assert_equal(Rules::PLURAL_TWO, @rules.pluralization_arabic(2))
107
+ [3, 4, 5, 6, 7, 8, 9, 10, 103, 104, 105, 106, 107, 108, 109, 110].each do |n|
108
+ assert_equal(Rules::PLURAL_FEW, @rules.pluralization_arabic(n))
109
+ end
110
+ [11, 12, 13, 21, 99, 111, 112, 199].each do |n|
111
+ assert_equal(Rules::PLURAL_MANY, @rules.pluralization_arabic(n))
112
+ end
113
+ [1.1, 100, 101, 102, 200, 201, 202].each do |n|
114
+ assert_equal(Rules::PLURAL_OTHER, @rules.pluralization_arabic(n))
115
+ end
116
+ end
117
+
118
+ def test_pluralization_polish
119
+ assert_equal(Rules::PLURAL_ZERO_OR_MANY, @rules.pluralization_polish(0))
120
+ assert_equal(Rules::PLURAL_ONE, @rules.pluralization_polish(1))
121
+ [2, 3, 4, 22, 23, 24, 92, 93, 94, 102, 103, 104].each do |n|
122
+ assert_equal(Rules::PLURAL_FEW, @rules.pluralization_polish(n))
123
+ end
124
+ [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 25, 26, 27, 28, 29, 30, 31, 100, 101].each do |n|
125
+ assert_equal(Rules::PLURAL_MANY, @rules.pluralization_polish(n))
126
+ end
127
+ [1.2, 2.07, 5.94].each do |n|
128
+ assert_equal(Rules::PLURAL_OTHER, @rules.pluralization_polish(n), n)
129
+ end
130
+ end
131
+
132
+ end
133
+ end
@@ -0,0 +1,132 @@
1
+ # TODO: test key generation
2
+ require "helper"
3
+
4
+ module Slang
5
+
6
+ class TestSnapshot < Minitest::Test
7
+
8
+ # TODO: when parallelized, the stubbed Slang.config method fails nondeterministically, but only when the entire
9
+ # test suite is run. If just this file is run (TEST=test/test_snapshot.rb) it does not fail.
10
+ # To replicate, uncomment parallelize_me!, and run: while :; do rake; done
11
+ #parallelize_me!
12
+
13
+ class KeyReporterStub
14
+ def unknown_key(key, variable_map)
15
+ # do nothing
16
+ end
17
+ end
18
+
19
+ SNAPSHOT_KEYS = %w(apples_bananas foo hello missing profile_update unread welcome)
20
+
21
+ def setup
22
+ @array = Oj.strict_load(File.read("test/data/snapshot.json"))
23
+ @snapshot = Snapshot.new(@array) # format, id, timestamp, default_locale_code, locales_array, translations_array
24
+ end
25
+
26
+ def test_initialize
27
+ assert_equal("6DIMm9XmJ5GkYOBpV9Hg", @snapshot.id)
28
+ assert_equal(1403213582, @snapshot.timestamp)
29
+ assert_equal(:en, @snapshot.default_locale.code)
30
+ end
31
+
32
+ def test_initialize_unknown_format
33
+ @array[0] = 0
34
+ @snapshot = Snapshot.new(@array)
35
+ assert_equal("6DIMm9XmJ5GkYOBpV9Hg", @snapshot.id)
36
+ assert_equal(1403213582, @snapshot.timestamp)
37
+ assert_equal(:en, @snapshot.default_locale.code)
38
+ end
39
+
40
+ def test_initialize_unknown_default_locale
41
+ @array[3] = "xx"
42
+ @snapshot = Snapshot.new(@array)
43
+ assert_equal(:de, @snapshot.default_locale.code)
44
+ end
45
+
46
+ def test_initialize_empty
47
+ s = Snapshot.from_json(Snapshot::EMPTY_SNAPSHOT_JSON)
48
+ assert_equal("0" * 20, s.id)
49
+ assert_equal(0, s.timestamp)
50
+ assert_equal(:en, s.default_locale.code)
51
+ assert_empty(s.keys)
52
+ end
53
+
54
+ def test_keys
55
+ assert_equal(SNAPSHOT_KEYS, @snapshot.keys)
56
+ end
57
+
58
+ def test_translate
59
+ assert_equal("foo", @snapshot.translate(:en, "foo", {}))
60
+ assert_equal("foo", @snapshot.translate(:en, :foo, {}))
61
+ assert_equal("foo", @snapshot.translate(:en, "FOo", {}))
62
+ assert_equal("voo", @snapshot.translate(:de, "foo", {}))
63
+ end
64
+
65
+ def test_translate_missing
66
+ assert_equal("{{en:missing_key}}", @snapshot.translate(:en, "missing_key", {}))
67
+ Slang.stub(:key_reporter, KeyReporterStub.new) do
68
+ assert_equal("MissingKey", @snapshot.translate(:en, "missing_key", {}))
69
+ end
70
+ end
71
+
72
+ def test_translate_missing_with_fallback
73
+ assert_equal("Found in English", @snapshot.translate(:de, "missing", {}))
74
+ end
75
+
76
+ def test_translate_interpolation
77
+ assert_equal("Welcome sickp!", @snapshot.translate(:en, "welcome", user: "sickp"))
78
+ assert_equal("Willkommen sickp!", @snapshot.translate(:de, "welcome", user: "sickp"))
79
+ end
80
+
81
+ def test_translate_missing_interpolation_variable
82
+ assert_equal("Hello {a} and {b}.", @snapshot.translate(:en, "hello", {}))
83
+ assert_equal("Hello {a} and Bob.", @snapshot.translate(:en, "hello", b: "Bob"))
84
+ end
85
+
86
+ def test_translate_rule
87
+ assert_equal("Jack updated his profile.", @snapshot.translate(:en, "profile_update", name: "Jack", gender: "M"))
88
+ assert_equal("Jill updated her profile.", @snapshot.translate(:en, "profile_update", name: "Jill", gender: "F"))
89
+ assert_equal("Thing 1 updated their profile.", @snapshot.translate(:en, "profile_update", name: "Thing 1", gender: nil))
90
+ end
91
+
92
+ def test_translate_missing_rule_variable
93
+ assert_equal("{{en:profile_update:<gender>}}", @snapshot.translate(:en, "profile_update", name: "Jack"))
94
+ end
95
+
96
+ def test_translate_with_locale_alias
97
+ assert_equal("Guten Tag Jack und Jill.", @snapshot.translate(:german, "hello", a: "Jack", b: "Jill"))
98
+ end
99
+
100
+ def test_translate_unknown_locale
101
+ assert_equal("Welcome earthling!", @snapshot.translate(:martian, "welcome", user: "earthling"))
102
+ end
103
+
104
+ def test_translate_key_name_malformed
105
+ assert_equal("{{en:bad$langkey}}", @snapshot.translate(:en, "bad$langkey", {}))
106
+ Slang.stub(:key_reporter, KeyReporterStub.new) do
107
+ error = assert_raises(ArgumentError) do
108
+ @snapshot.translate(:en, "bad$slangkey", [])
109
+ end
110
+ assert_match(/key name malformed/i, error.message)
111
+ end
112
+ end
113
+
114
+ def test_translate_variable_name_malformed
115
+ assert_equal("Welcome {user}!", @snapshot.translate(:en, "welcome", "U$ER" => "friend"))
116
+ Slang.stub(:key_reporter, KeyReporterStub.new) do
117
+ error = assert_raises(ArgumentError) do
118
+ @snapshot.translate(:en, "welcome", "U$ER" => "friend")
119
+ end
120
+ assert_match(/variable name malformed/i, error.message)
121
+ end
122
+ end
123
+
124
+ # def test_new_key_generation
125
+ # assert_equal("MissingKey", @key_reporter.new_key("missing_key", {}, nil))
126
+ # assert_equal("Some Other Key", @key_reporter.new_key("some.other.key", {}, nil))
127
+ # assert_equal("ActiveRecord Model Errors", @key_reporter.new_key("active_record.model.errors", {}, nil))
128
+ # assert_equal("Vars (a=Apple, b=Banana)", @key_reporter.new_key("vars", { "a" => "Apple", "b" => "Banana" }, nil))
129
+ # end
130
+
131
+ end
132
+ end
@@ -0,0 +1,49 @@
1
+ # TODO: test variable_name_regex, variable_scan_regex
2
+ require "helper"
3
+
4
+ module Slang
5
+ class TestTemplate < Minitest::Test
6
+ Template = Snapshot::Template
7
+ parallelize_me!
8
+
9
+ def test_non_interpolation
10
+ t = Template.new("Hello")
11
+ assert_equal("Hello", t.interpolate({}))
12
+ assert_equal("Hello", t.interpolate("hello" => "hi"))
13
+ end
14
+
15
+ def test_interpolation
16
+ t = Template.new("Hello {name}!")
17
+ assert_equal("Hello Jack!", t.interpolate("name" => "Jack"))
18
+ assert_equal("Hello Jill!", t.interpolate("name" => "Jill", "extra" => "ignored"))
19
+ end
20
+
21
+ def test_complex_interpolation
22
+ t = Template.new("This is {name}. {name} is a {thing}.")
23
+ assert_equal("This is Jamie. Jamie is a cat.", t.interpolate("name" => "Jamie", "thing" => "cat"))
24
+ end
25
+
26
+ def test_missing_variables
27
+ t = Template.new("It is {weather} in {city}.")
28
+ result, missing_variables = t.interpolate({})
29
+ assert_equal("It is {weather} in {city}.", result)
30
+ assert_includes(missing_variables, "city")
31
+ assert_includes(missing_variables, "weather")
32
+ result, missing_variables = t.interpolate("weather" => "sunny")
33
+ assert_equal("It is sunny in {city}.", result)
34
+ assert_includes(missing_variables, "city")
35
+ end
36
+
37
+ def test_freezer
38
+ t = Template.new("A simple template.")
39
+ assert(t.string.frozen?)
40
+ assert(t.interpolate({}).frozen?)
41
+ t = Template.new("Hi {a}")
42
+ assert(t.interpolate("a" => "A").frozen?)
43
+ result, _missing_variables = t.interpolate({})
44
+ assert(result.frozen?)
45
+ end
46
+
47
+ end
48
+
49
+ end