twitter_cldr 3.0.1 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -2
- data/History.txt +4 -0
- data/README.md +17 -6
- data/lib/twitter_cldr/resources/postal_codes_importer.rb +12 -1
- data/lib/twitter_cldr/resources/regexp_ast_generator.rb +41 -0
- data/lib/twitter_cldr/resources.rb +1 -0
- data/lib/twitter_cldr/shared/postal_code_generator.rb +50 -0
- data/lib/twitter_cldr/shared/postal_codes.rb +48 -9
- data/lib/twitter_cldr/shared.rb +15 -14
- data/lib/twitter_cldr/utils/regexp_ast.rb +115 -0
- data/lib/twitter_cldr/utils/regexp_sampler.rb +149 -0
- data/lib/twitter_cldr/utils.rb +5 -3
- data/lib/twitter_cldr/version.rb +1 -1
- data/resources/shared/postal_codes.yml +1442 -159
- data/spec/bidi/bidi_spec.rb +1 -1
- data/spec/collation/collation_spec.rb +1 -1
- data/spec/collation/collator_spec.rb +31 -31
- data/spec/collation/implicit_collation_elements_spec.rb +6 -6
- data/spec/collation/sort_key_builder_spec.rb +28 -26
- data/spec/collation/tailoring_spec.rb +1 -1
- data/spec/collation/trie_builder_spec.rb +16 -16
- data/spec/collation/trie_dumps_spec.rb +2 -2
- data/spec/collation/trie_loader_spec.rb +8 -8
- data/spec/collation/trie_spec.rb +61 -61
- data/spec/collation/trie_with_fallback_spec.rb +5 -5
- data/spec/core_ext_spec.rb +1 -1
- data/spec/data_readers/additional_date_format_selector_spec.rb +38 -38
- data/spec/data_readers/date_time_data_reader_spec.rb +2 -2
- data/spec/data_readers/number_data_reader_spec.rb +1 -1
- data/spec/formatters/calendars/datetime_formatter_spec.rb +218 -218
- data/spec/formatters/list_formatter_spec.rb +8 -8
- data/spec/formatters/numbers/abbreviated/abbreviated_number_formatter_spec.rb +14 -14
- data/spec/formatters/numbers/abbreviated/long_decimal_formatter_spec.rb +4 -4
- data/spec/formatters/numbers/abbreviated/short_decimal_formatter_spec.rb +4 -4
- data/spec/formatters/numbers/currency_formatter_spec.rb +11 -11
- data/spec/formatters/numbers/decimal_formatter_spec.rb +3 -3
- data/spec/formatters/numbers/helpers/fraction_spec.rb +3 -3
- data/spec/formatters/numbers/helpers/integer_spec.rb +16 -16
- data/spec/formatters/numbers/number_formatter_spec.rb +21 -21
- data/spec/formatters/numbers/percent_formatter_spec.rb +3 -3
- data/spec/formatters/numbers/rbnf/rbnf_spec.rb +2 -2
- data/spec/formatters/plurals/plural_formatter_spec.rb +41 -41
- data/spec/formatters/plurals/rules_spec.rb +13 -13
- data/spec/localized/localized_array_spec.rb +12 -12
- data/spec/localized/localized_date_spec.rb +33 -33
- data/spec/localized/localized_datetime_spec.rb +11 -11
- data/spec/localized/localized_hash_spec.rb +4 -4
- data/spec/localized/localized_number_spec.rb +36 -36
- data/spec/localized/localized_object_spec.rb +8 -8
- data/spec/localized/localized_string_spec.rb +53 -53
- data/spec/localized/localized_symbol_spec.rb +9 -9
- data/spec/localized/localized_time_spec.rb +10 -10
- data/spec/localized/localized_timespan_spec.rb +8 -8
- data/spec/normalization_spec.rb +6 -6
- data/spec/parsers/number_parser_spec.rb +36 -36
- data/spec/parsers/parser_spec.rb +5 -5
- data/spec/parsers/segmentation_parser_spec.rb +19 -19
- data/spec/parsers/symbol_table_spec.rb +4 -4
- data/spec/parsers/unicode_regex/character_class_spec.rb +19 -19
- data/spec/parsers/unicode_regex/character_range_spec.rb +1 -1
- data/spec/parsers/unicode_regex/character_set_spec.rb +8 -8
- data/spec/parsers/unicode_regex/literal_spec.rb +5 -5
- data/spec/parsers/unicode_regex/unicode_string_spec.rb +2 -2
- data/spec/parsers/unicode_regex_parser_spec.rb +28 -28
- data/spec/resources/loader_spec.rb +32 -32
- data/spec/shared/break_iterator_spec.rb +13 -13
- data/spec/shared/calendar_spec.rb +59 -59
- data/spec/shared/casefolder_spec.rb +5 -5
- data/spec/shared/code_point_spec.rb +46 -46
- data/spec/shared/currencies_spec.rb +7 -7
- data/spec/shared/language_codes_spec.rb +34 -34
- data/spec/shared/languages_spec.rb +30 -30
- data/spec/shared/numbering_system_spec.rb +7 -7
- data/spec/shared/numbers_spec.rb +4 -4
- data/spec/shared/phone_codes_spec.rb +7 -7
- data/spec/shared/postal_code_generator_spec.rb +76 -0
- data/spec/shared/postal_codes_spec.rb +35 -29
- data/spec/shared/territories_spec.rb +40 -40
- data/spec/shared/unicode_regex_spec.rb +71 -71
- data/spec/spec_helper.rb +2 -2
- data/spec/tokenizers/calendars/date_tokenizer_spec.rb +1 -1
- data/spec/tokenizers/calendars/timespan_tokenizer_spec.rb +6 -6
- data/spec/tokenizers/composite_token_spec.rb +3 -3
- data/spec/tokenizers/token_spec.rb +3 -3
- data/spec/twitter_cldr_spec.rb +72 -72
- data/spec/utils/code_points_spec.rb +10 -10
- data/spec/utils/interpolation_spec.rb +32 -32
- data/spec/utils/range_set_spec.rb +36 -36
- data/spec/utils/regexp_ast_spec.rb +44 -0
- data/spec/utils/regexp_sampler_spec.rb +182 -0
- data/spec/utils/yaml/yaml_spec.rb +23 -23
- data/spec/utils_spec.rb +19 -19
- metadata +263 -258
@@ -16,106 +16,106 @@ describe TwitterCldr::Utils do
|
|
16
16
|
|
17
17
|
context 'when argument is a Hash' do
|
18
18
|
it 'does nothing if no placeholder give' do
|
19
|
-
TwitterCldr::Utils.interpolate('foo', :foo => 'bar').
|
19
|
+
expect(TwitterCldr::Utils.interpolate('foo', :foo => 'bar')).to eq('foo')
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'interpolates named placeholders' do
|
23
|
-
TwitterCldr::Utils.interpolate('%{digit} %{sign} %{digit}', :digit => 2, :sign => '+').
|
23
|
+
expect(TwitterCldr::Utils.interpolate('%{digit} %{sign} %{digit}', :digit => 2, :sign => '+')).to eq('2 + 2')
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'interpolates named placeholders with formatting' do
|
27
|
-
TwitterCldr::Utils.interpolate(
|
27
|
+
expect(TwitterCldr::Utils.interpolate(
|
28
28
|
'%<as_integer>d %<as_float>.2f', :as_integer => 3.14, :as_float => 15
|
29
|
-
).
|
29
|
+
)).to eq('3 15.00')
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'interpolates mixed placeholders' do
|
33
|
-
TwitterCldr::Utils.interpolate(
|
33
|
+
expect(TwitterCldr::Utils.interpolate(
|
34
34
|
'%{regular} is approx. %<pi>.4f', :regular => 'pi', :pi => 3.141592
|
35
|
-
).
|
35
|
+
)).to eq('pi is approx. 3.1416')
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'does not recurse' do
|
39
|
-
TwitterCldr::Utils.interpolate(
|
39
|
+
expect(TwitterCldr::Utils.interpolate(
|
40
40
|
'%{top_level}', :top_level => '%<second_level>', :second_level => 'unexpected'
|
41
|
-
).
|
41
|
+
)).to eq('%<second_level>')
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'treats % before placeholder as escape character' do
|
45
|
-
TwitterCldr::Utils.interpolate(
|
45
|
+
expect(TwitterCldr::Utils.interpolate(
|
46
46
|
'%%{foo} = %{foo}, %%<bar>d = %<bar>d', :foo => 1, :bar => 2.3
|
47
|
-
).
|
47
|
+
)).to eq('%{foo} = 1, %<bar>d = 2')
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'interpolates formatted placeholders as Ruby 1.9' do
|
51
|
-
TwitterCldr::Utils.interpolate('%<msg>s', :msg => 'foo').
|
52
|
-
TwitterCldr::Utils.interpolate('%<num>d', :num => 1 ).
|
53
|
-
TwitterCldr::Utils.interpolate('%<num>f', :num => 1.0 ).
|
54
|
-
TwitterCldr::Utils.interpolate('%<num>3.0f', :num => 1.0 ).
|
55
|
-
TwitterCldr::Utils.interpolate('%<num>2.2f', :num => 100.0).
|
56
|
-
TwitterCldr::Utils.interpolate('%<num>#b', :num => 1 ).
|
57
|
-
TwitterCldr::Utils.interpolate('%<num>#x', :num => 100.0).
|
51
|
+
expect(TwitterCldr::Utils.interpolate('%<msg>s', :msg => 'foo')).to eq('foo')
|
52
|
+
expect(TwitterCldr::Utils.interpolate('%<num>d', :num => 1 )).to eq('1')
|
53
|
+
expect(TwitterCldr::Utils.interpolate('%<num>f', :num => 1.0 )).to eq('1.000000')
|
54
|
+
expect(TwitterCldr::Utils.interpolate('%<num>3.0f', :num => 1.0 )).to eq(' 1')
|
55
|
+
expect(TwitterCldr::Utils.interpolate('%<num>2.2f', :num => 100.0)).to eq('100.00')
|
56
|
+
expect(TwitterCldr::Utils.interpolate('%<num>#b', :num => 1 )).to eq('0b1')
|
57
|
+
expect(TwitterCldr::Utils.interpolate('%<num>#x', :num => 100.0)).to eq('0x64')
|
58
58
|
end
|
59
59
|
|
60
60
|
it 'ignores extra values' do
|
61
|
-
TwitterCldr::Utils.interpolate('%{msg}', :msg => 'hello', :extra => 'extra').
|
61
|
+
expect(TwitterCldr::Utils.interpolate('%{msg}', :msg => 'hello', :extra => 'extra')).to eq('hello')
|
62
62
|
end
|
63
63
|
|
64
64
|
it 'raises ArgumentError if formatted placeholder is malformed' do
|
65
|
-
|
66
|
-
|
65
|
+
expect { TwitterCldr::Utils.interpolate('%<num>,d', :num => 100) }.to raise_error(ArgumentError)
|
66
|
+
expect { TwitterCldr::Utils.interpolate('%<num>/d', :num => 100) }.to raise_error(ArgumentError)
|
67
67
|
end
|
68
68
|
|
69
69
|
it 'raises KeyError when the value is missing' do
|
70
|
-
|
70
|
+
expect { TwitterCldr::Utils.interpolate('%{msg}', {}) }.to raise_error(KeyError)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
74
|
context 'when argument is an Array' do
|
75
75
|
it 'does nothing if no placeholder give' do
|
76
|
-
TwitterCldr::Utils.interpolate('foo', [111]).
|
76
|
+
expect(TwitterCldr::Utils.interpolate('foo', [111])).to eq('foo')
|
77
77
|
end
|
78
78
|
|
79
79
|
it 'interpolates all placeholders' do
|
80
|
-
TwitterCldr::Utils.interpolate('%d %s', [12, 'monkeys']).
|
80
|
+
expect(TwitterCldr::Utils.interpolate('%d %s', [12, 'monkeys'])).to eq('12 monkeys')
|
81
81
|
end
|
82
82
|
|
83
83
|
it 'interpolates all placeholders with formatting' do
|
84
|
-
TwitterCldr::Utils.interpolate('%d %.3f %#b', [3.1415, 92, 6]).
|
84
|
+
expect(TwitterCldr::Utils.interpolate('%d %.3f %#b', [3.1415, 92, 6])).to eq('3 92.000 0b110')
|
85
85
|
end
|
86
86
|
|
87
87
|
it 'formats positional arguments' do
|
88
|
-
TwitterCldr::Utils.interpolate('%1$*2$s %2$d %1$s', ['hello', 8]).
|
88
|
+
expect(TwitterCldr::Utils.interpolate('%1$*2$s %2$d %1$s', ['hello', 8])).to eq(' hello 8 hello')
|
89
89
|
end
|
90
90
|
|
91
91
|
it 'treats % as escape character' do
|
92
|
-
TwitterCldr::Utils.interpolate('%s: %+.2f±%.2f%%', ['total', 3.14159, 2.6535]).
|
92
|
+
expect(TwitterCldr::Utils.interpolate('%s: %+.2f±%.2f%%', ['total', 3.14159, 2.6535])).to eq('total: +3.14±2.65%')
|
93
93
|
end
|
94
94
|
|
95
95
|
it 'ignores extra values' do
|
96
|
-
TwitterCldr::Utils.interpolate('%d', [2, 1]).
|
96
|
+
expect(TwitterCldr::Utils.interpolate('%d', [2, 1])).to eq('2')
|
97
97
|
end
|
98
98
|
|
99
99
|
it 'raises ArgumentError when given not enough values' do
|
100
|
-
|
100
|
+
expect { TwitterCldr::Utils.interpolate('%d %d', [1]) }.to raise_error(ArgumentError)
|
101
101
|
end
|
102
102
|
|
103
103
|
it 'raises ArgumentError if the string contains named placeholders' do
|
104
|
-
|
104
|
+
expect { TwitterCldr::Utils.interpolate('%{name} %d', [1, 2]) }.to raise_error(ArgumentError)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
108
|
context 'when argument is a single value' do
|
109
109
|
it 'formats a string' do
|
110
|
-
TwitterCldr::Utils.interpolate('a string: %s', 'string').
|
110
|
+
expect(TwitterCldr::Utils.interpolate('a string: %s', 'string')).to eq('a string: string')
|
111
111
|
end
|
112
112
|
|
113
113
|
it 'formats a number' do
|
114
|
-
TwitterCldr::Utils.interpolate('a number: %4.1f', 3.1415).
|
114
|
+
expect(TwitterCldr::Utils.interpolate('a number: %4.1f', 3.1415)).to eq('a number: 3.1')
|
115
115
|
end
|
116
116
|
|
117
117
|
it 'raises ArgumentError if the string contains named placeholders' do
|
118
|
-
|
118
|
+
expect { TwitterCldr::Utils.interpolate('%{name}', 'must be hash') }.to raise_error(ArgumentError)
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
@@ -10,48 +10,48 @@ include TwitterCldr::Utils
|
|
10
10
|
describe RangeSet do
|
11
11
|
describe "rangify" do
|
12
12
|
it "should identify runs in an array of integers and return an array of ranges" do
|
13
|
-
RangeSet.rangify([1, 2, 3, 6, 7, 8, 11, 14, 17, 18, 19]).
|
14
|
-
|
13
|
+
expect(RangeSet.rangify([1, 2, 3, 6, 7, 8, 11, 14, 17, 18, 19])).
|
14
|
+
to eq([1..3, 6..8, 11..11, 14..14, 17..19])
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should not rangify zero-length values when told to compress" do
|
18
|
-
RangeSet.rangify([1, 2, 3, 5, 8, 11, 12], true).
|
19
|
-
|
18
|
+
expect(RangeSet.rangify([1, 2, 3, 5, 8, 11, 12], true)).
|
19
|
+
to eq([1..3, 5, 8, 11..12])
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
describe "#to_a" do
|
24
24
|
it "should return a copy of the ranges in the set" do
|
25
25
|
set = RangeSet.new([1..10])
|
26
|
-
set.to_a.object_id.
|
26
|
+
expect(set.to_a.object_id).not_to eq(set.ranges.object_id)
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should return compressed ranges when asked" do
|
30
|
-
RangeSet.new([1..10, 12..12]).to_a(true).
|
30
|
+
expect(RangeSet.new([1..10, 12..12]).to_a(true)).to eq([1..10, 12])
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
describe "#to_full_a" do
|
35
35
|
it "expands all ranges" do
|
36
|
-
RangeSet.new([1..5]).to_full_a.
|
36
|
+
expect(RangeSet.new([1..5]).to_full_a).to eq([1, 2, 3, 4, 5])
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
40
|
describe "#new" do
|
41
41
|
it "should flatten leading overlapping ranges" do
|
42
|
-
RangeSet.new([3..10, 1..8]).to_a.
|
42
|
+
expect(RangeSet.new([3..10, 1..8]).to_a).to eq([1..10])
|
43
43
|
end
|
44
44
|
|
45
45
|
it "should flatten trailing overlapping ranges" do
|
46
|
-
RangeSet.new([1..10, 8..12]).to_a.
|
46
|
+
expect(RangeSet.new([1..10, 8..12]).to_a).to eq([1..12])
|
47
47
|
end
|
48
48
|
|
49
49
|
it "should flatten completely overlapping ranges" do
|
50
|
-
RangeSet.new([2..3, 1..10]).to_a.
|
50
|
+
expect(RangeSet.new([2..3, 1..10]).to_a).to eq([1..10])
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should join ranges that are within 1 of each other" do
|
54
|
-
RangeSet.new([1..10, 11..15]).to_a.
|
54
|
+
expect(RangeSet.new([1..10, 11..15]).to_a).to eq([1..15])
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -61,94 +61,94 @@ describe RangeSet do
|
|
61
61
|
RangeSet.new([9..11, 1..2, 2..3, 14..18])
|
62
62
|
)
|
63
63
|
|
64
|
-
set.to_a.
|
64
|
+
expect(set.to_a).to eq([1..11, 14..18])
|
65
65
|
end
|
66
66
|
|
67
67
|
it "should aggregate the ranges correctly even if they're given in reverse order" do
|
68
68
|
set = RangeSet.new([3..10]).union(RangeSet.new([1..4]))
|
69
|
-
set.to_a.
|
69
|
+
expect(set.to_a).to eq([1..10])
|
70
70
|
|
71
71
|
set = RangeSet.new([1..4]).union(RangeSet.new([3..10]))
|
72
|
-
set.to_a.
|
72
|
+
expect(set.to_a).to eq([1..10])
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
76
|
describe "#intersection" do
|
77
77
|
it "computes the intersection for leading overlapping ranges" do
|
78
78
|
set = RangeSet.new([3..10]).intersection(RangeSet.new([1..7]))
|
79
|
-
set.to_a.
|
79
|
+
expect(set.to_a).to eq([3..7])
|
80
80
|
end
|
81
81
|
|
82
82
|
it "computes the intersection for trailing overlapping ranges" do
|
83
83
|
set = RangeSet.new([1..10]).intersection(RangeSet.new([5..15]))
|
84
|
-
set.to_a.
|
84
|
+
expect(set.to_a).to eq([5..10])
|
85
85
|
end
|
86
86
|
|
87
87
|
it "computes the intersection for two completely overlapping ranges" do
|
88
88
|
set = RangeSet.new([1..10]).intersection(RangeSet.new([3..6]))
|
89
|
-
set.to_a.
|
89
|
+
expect(set.to_a).to eq([3..6])
|
90
90
|
end
|
91
91
|
|
92
92
|
it "returns an empty intersection if no elements exist in both ranges" do
|
93
93
|
set = RangeSet.new([1..10]).intersection(RangeSet.new([15..20]))
|
94
|
-
set.to_a.
|
94
|
+
expect(set.to_a).to eq([])
|
95
95
|
end
|
96
96
|
|
97
97
|
it "returns partial intersections when the range set contains multiple matching ranges" do
|
98
98
|
set = RangeSet.new([1..5, 7..10]).intersection(RangeSet.new([3..8]))
|
99
|
-
set.to_a.
|
99
|
+
expect(set.to_a).to eq([3..5, 7..8])
|
100
100
|
end
|
101
101
|
|
102
102
|
it "doesn't matter what order the ranges are compared in" do
|
103
103
|
set = RangeSet.new([2..3]).intersection(RangeSet.new([1..4]))
|
104
|
-
set.to_a.
|
104
|
+
expect(set.to_a).to eq([2..3])
|
105
105
|
|
106
106
|
set = RangeSet.new([1..4]).intersection(RangeSet.new([2..3]))
|
107
|
-
set.to_a.
|
107
|
+
expect(set.to_a).to eq([2..3])
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
111
|
describe "#subtract" do
|
112
112
|
it "subtracts the intersection for leading overlapping ranges" do
|
113
113
|
set = RangeSet.new([3..10]).subtract(RangeSet.new([1..5]))
|
114
|
-
set.to_a.
|
114
|
+
expect(set.to_a).to eq([6..10])
|
115
115
|
end
|
116
116
|
|
117
117
|
it "subtracts the intersection for trailing overlapping ranges" do
|
118
118
|
set = RangeSet.new([1..7]).subtract(RangeSet.new([3..9]))
|
119
|
-
set.to_a.
|
119
|
+
expect(set.to_a).to eq([1..2])
|
120
120
|
end
|
121
121
|
|
122
122
|
it "subtracts the intersection for completely overlapping ranges (generates two ranges)" do
|
123
123
|
set = RangeSet.new([1..10]).subtract(RangeSet.new([4..6]))
|
124
|
-
set.to_a.
|
124
|
+
expect(set.to_a).to eq([1..3, 7..10])
|
125
125
|
end
|
126
126
|
|
127
127
|
it "subtracts the intersection when the range set contians multiple matching ranges" do
|
128
128
|
set = RangeSet.new([1..5, 7..10]).subtract(RangeSet.new([3..8]))
|
129
|
-
set.to_a.
|
129
|
+
expect(set.to_a).to eq([1..2, 9..10])
|
130
130
|
end
|
131
131
|
|
132
132
|
it "does not change object when subtracting an empty set" do
|
133
133
|
set = RangeSet.new([1..5]).subtract(RangeSet.new([]))
|
134
|
-
set.to_a.
|
134
|
+
expect(set.to_a).to eq([1..5])
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
138
|
describe "#difference" do
|
139
139
|
it "returns the symmetric difference (union - intersection) between completely overlapping ranges" do
|
140
140
|
set = RangeSet.new([1..10]).difference(RangeSet.new([3..8]))
|
141
|
-
set.to_a.
|
141
|
+
expect(set.to_a).to eq([1..2, 9..10])
|
142
142
|
end
|
143
143
|
|
144
144
|
it "returns the symmetric difference between leading overlapping ranges" do
|
145
145
|
set = RangeSet.new([3..10]).difference(RangeSet.new([1..5]))
|
146
|
-
set.to_a.
|
146
|
+
expect(set.to_a).to eq([1..2, 6..10])
|
147
147
|
end
|
148
148
|
|
149
149
|
it "returns the symmetric difference between trailing overlapping ranges" do
|
150
150
|
set = RangeSet.new([1..5]).difference(RangeSet.new([3..8]))
|
151
|
-
set.to_a.
|
151
|
+
expect(set.to_a).to eq([1..2, 6..8])
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
@@ -156,16 +156,16 @@ describe RangeSet do
|
|
156
156
|
let (:set) { RangeSet.new([1..5, 9..16]) }
|
157
157
|
|
158
158
|
it "returns true if the set completely includes the range, false otherwise" do
|
159
|
-
set.
|
160
|
-
set.
|
161
|
-
set.
|
159
|
+
expect(set).to include(10..15)
|
160
|
+
expect(set).not_to include(3..8)
|
161
|
+
expect(set).not_to include(8..14)
|
162
162
|
end
|
163
163
|
|
164
164
|
it "returns true if the set contains the value, false otherwise" do
|
165
|
-
set.
|
166
|
-
set.
|
167
|
-
set.
|
168
|
-
set.
|
165
|
+
expect(set).to include(3)
|
166
|
+
expect(set).to include(10)
|
167
|
+
expect(set).not_to include(6)
|
168
|
+
expect(set).not_to include(8)
|
169
169
|
end
|
170
170
|
end
|
171
171
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Copyright 2012 Twitter, Inc
|
4
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
5
|
+
|
6
|
+
require 'spec_helper'
|
7
|
+
|
8
|
+
include TwitterCldr::Utils
|
9
|
+
|
10
|
+
describe RegexpAst do
|
11
|
+
let(:ast) do
|
12
|
+
RegexpAst::Root.new(
|
13
|
+
[RegexpAst::Literal.new([], nil, 'foobar')], nil
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:ast_dump) do
|
18
|
+
"BAhvOihUd2l0dGVyQ2xkcjo6VXRpbHM6OlJlZ2V4cEFzdDo6Um9vdAc6EUBl\n" +
|
19
|
+
"eHByZXNzaW9uc1sGbzorVHdpdHRlckNsZHI6OlV0aWxzOjpSZWdleHBBc3Q6\n" +
|
20
|
+
"OkxpdGVyYWwIOgpAdGV4dEkiC2Zvb2JhcgY6BkVUOwZbADoQQHF1YW50aWZp\n" +
|
21
|
+
"ZXIwOwow\n"
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_ast(obj)
|
25
|
+
obj.should be_a(RegexpAst::Root)
|
26
|
+
expr = obj.expressions.first
|
27
|
+
expr.should be_a(RegexpAst::Literal)
|
28
|
+
expr.text.should == 'foobar'
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#dump" do
|
32
|
+
it "should correctly serialize the ast" do
|
33
|
+
obj = Marshal.load(Base64.decode64(RegexpAst.dump(ast)))
|
34
|
+
check_ast(obj)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#load" do
|
39
|
+
it "should load the dumped ast and construct a valid object" do
|
40
|
+
obj = RegexpAst.load(ast_dump)
|
41
|
+
check_ast(obj)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Copyright 2012 Twitter, Inc
|
4
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
5
|
+
|
6
|
+
require 'spec_helper'
|
7
|
+
|
8
|
+
include TwitterCldr::Utils
|
9
|
+
|
10
|
+
describe RegexpSampler do
|
11
|
+
let(:root) { RegexpAst::Root }
|
12
|
+
let(:digit) { RegexpAst::Digit }
|
13
|
+
let(:word) { RegexpAst::Word }
|
14
|
+
let(:literal) { RegexpAst::Literal }
|
15
|
+
let(:character_set) { RegexpAst::CharacterSet }
|
16
|
+
let(:capture) { RegexpAst::Capture }
|
17
|
+
let(:passive) { RegexpAst::Passive }
|
18
|
+
let(:sequence) { RegexpAst::Sequence }
|
19
|
+
let(:alternation) { RegexpAst::Alternation }
|
20
|
+
let(:quantifier) { RegexpAst::Quantifier }
|
21
|
+
let(:sampler) { RegexpSampler }
|
22
|
+
|
23
|
+
let(:singular_quantifier) { quantifier.new(2, 2) }
|
24
|
+
let(:ranged_quantifier) { quantifier.new(2, 4) }
|
25
|
+
|
26
|
+
def make(ast)
|
27
|
+
sampler.new(root.new([ast], nil))
|
28
|
+
end
|
29
|
+
|
30
|
+
around(:each) do |example|
|
31
|
+
10.times { example.run }
|
32
|
+
end
|
33
|
+
|
34
|
+
context "digits" do
|
35
|
+
it "should return a single digit when no quantifier" do
|
36
|
+
spl = make(digit.new([], nil))
|
37
|
+
spl.generate.should match(/\d/)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return multiple digits when given a singular quantifier" do
|
41
|
+
spl = make(digit.new([], singular_quantifier))
|
42
|
+
spl.generate.should match(/\d{2}/)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return the correct number of digits when given a ranged quantifier" do
|
46
|
+
spl = make(digit.new([], ranged_quantifier))
|
47
|
+
spl.generate.should match(/\d{2,4}/)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "words" do
|
52
|
+
it "should return a single word character when no quantifier" do
|
53
|
+
spl = make(word.new([], nil))
|
54
|
+
spl.generate.should match(/\w/)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return multiple letter characters when given a singular quantifier" do
|
58
|
+
spl = make(word.new([], singular_quantifier))
|
59
|
+
spl.generate.should match(/\w{2}/)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return the correct number of word characters when given a ranged quantifier" do
|
63
|
+
spl = make(word.new([], ranged_quantifier))
|
64
|
+
spl.generate.should match(/\w{2,4}/)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "literals" do
|
69
|
+
it "should return the literal when no quantifier" do
|
70
|
+
spl = make(literal.new([], nil, 'foobar'))
|
71
|
+
spl.generate.should == "foobar"
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should return multiple copies of the literal when given a singular quantifier" do
|
75
|
+
spl = make(literal.new([], singular_quantifier, 'foobar'))
|
76
|
+
spl.generate.should == "foobarfoobar"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should return the correct number of literal copies when given a ranged quantifier" do
|
80
|
+
spl = make(literal.new([], ranged_quantifier, 'foobar'))
|
81
|
+
spl.generate.should match(/(foobar){2,4}/)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "character sets" do
|
86
|
+
it "should handle single characters correctly" do
|
87
|
+
spl = make(character_set.new([], nil, ['a', 'b', 'c'], false))
|
88
|
+
spl.generate.should match(/[abc]/)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should repeat characters when given a singular quantifier" do
|
92
|
+
spl = make(character_set.new([], singular_quantifier, ['a', 'b', 'c'], false))
|
93
|
+
spl.generate.should match(/[abc]{2}/)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should repeat characters when given a ranged quantifier" do
|
97
|
+
spl = make(character_set.new([], ranged_quantifier, ['a', 'b', 'c'], false))
|
98
|
+
spl.generate.should match(/[abc]{2,4}/)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should handle character ranges correctly" do
|
102
|
+
spl = make(character_set.new([], nil, ['a-z'], false))
|
103
|
+
spl.generate.should match(/[a-z]/)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should handle character ranges correctly when given a singular quantifier" do
|
107
|
+
spl = make(character_set.new([], singular_quantifier, ['a-z'], false))
|
108
|
+
spl.generate.should match(/[a-z]{2}/)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should handle character ranges correctly when given a ranged quantifier" do
|
112
|
+
spl = make(character_set.new([], ranged_quantifier, ['a-z'], false))
|
113
|
+
spl.generate.should match(/[a-z]{2,4}/)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context "captures" do
|
118
|
+
it "should ignore captures" do
|
119
|
+
spl = make(capture.new([digit.new([], nil)], nil))
|
120
|
+
spl.generate.should match(/\d/)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "passives (i.e. non-capturing groups)" do
|
125
|
+
it "should ignore non-captures" do
|
126
|
+
spl = make(passive.new([digit.new([], nil)], nil))
|
127
|
+
spl.generate.should match(/\d/)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "alternations" do
|
132
|
+
it "should alternate between the options" do
|
133
|
+
spl = make(alternation.new([
|
134
|
+
literal.new([], nil, 'a'), digit.new([], nil)
|
135
|
+
], nil))
|
136
|
+
|
137
|
+
spl.generate.should match(/a|\d/)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should handle alternation when given a singlular quantifier" do
|
141
|
+
spl = make(alternation.new([
|
142
|
+
literal.new([], nil, 'a'), digit.new([], nil)
|
143
|
+
], singular_quantifier))
|
144
|
+
|
145
|
+
spl.generate.should match(/(?:a|\d){2}/)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should handle alternation when given a ranged quantifier" do
|
149
|
+
spl = make(alternation.new([
|
150
|
+
literal.new([], nil, 'a'), digit.new([], nil)
|
151
|
+
], ranged_quantifier))
|
152
|
+
|
153
|
+
spl.generate.should match(/(?:a|\d){2,4}/)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context "sequences" do
|
158
|
+
it "should process every element in the sequence" do
|
159
|
+
spl = make(sequence.new([
|
160
|
+
digit.new([], nil), word.new([], nil), literal.new([], nil, 'a')
|
161
|
+
], nil))
|
162
|
+
|
163
|
+
spl.generate.should match(/\d\wa/)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should process every element the specified number of times with a singular quantifier" do
|
167
|
+
spl = make(sequence.new([
|
168
|
+
digit.new([], nil), word.new([], nil), literal.new([], nil, 'a')
|
169
|
+
], singular_quantifier))
|
170
|
+
|
171
|
+
spl.generate.should match(/(?:\d\wa){2}/)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should process every element the specified number of times with a ranged quantifier" do
|
175
|
+
spl = make(sequence.new([
|
176
|
+
digit.new([], nil), word.new([], nil), literal.new([], nil, 'a')
|
177
|
+
], ranged_quantifier))
|
178
|
+
|
179
|
+
spl.generate.should match(/(?:\d\wa){2,4}/)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|