LittleWeasel 4.0.0 → 5.0.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -1
  3. data/Jenkinsfile +20 -0
  4. data/LittleWeasel.gemspec +3 -3
  5. data/README.md +1 -1
  6. data/lib/LittleWeasel/dictionary_key.rb +2 -2
  7. data/lib/LittleWeasel/dictionary_manager.rb +10 -4
  8. data/lib/LittleWeasel/metadata/metadatable.rb +5 -7
  9. data/lib/LittleWeasel/modules/dictionary_cache_validatable.rb +3 -5
  10. data/lib/LittleWeasel/modules/dictionary_key_validatable.rb +3 -5
  11. data/lib/LittleWeasel/modules/dictionary_metadata_validatable.rb +3 -5
  12. data/lib/LittleWeasel/modules/dictionary_source_validatable.rb +15 -0
  13. data/lib/LittleWeasel/modules/dictionary_sourceable.rb +66 -6
  14. data/lib/LittleWeasel/modules/dictionary_validatable.rb +0 -12
  15. data/lib/LittleWeasel/modules/language.rb +10 -9
  16. data/lib/LittleWeasel/modules/language_validatable.rb +2 -4
  17. data/lib/LittleWeasel/modules/locale.rb +7 -24
  18. data/lib/LittleWeasel/modules/order_validatable.rb +3 -5
  19. data/lib/LittleWeasel/modules/region.rb +10 -9
  20. data/lib/LittleWeasel/modules/region_validatable.rb +2 -4
  21. data/lib/LittleWeasel/modules/tag_validatable.rb +2 -4
  22. data/lib/LittleWeasel/preprocessors/preprocessed_word.rb +1 -0
  23. data/lib/LittleWeasel/preprocessors/preprocessed_word_validatable.rb +1 -0
  24. data/lib/LittleWeasel/preprocessors/preprocessed_words.rb +6 -2
  25. data/lib/LittleWeasel/preprocessors/preprocessed_words_validatable.rb +1 -0
  26. data/lib/LittleWeasel/preprocessors/word_preprocessor.rb +1 -0
  27. data/lib/LittleWeasel/services/dictionary_cache_service.rb +11 -62
  28. data/lib/LittleWeasel/services/dictionary_creator_service.rb +2 -2
  29. data/lib/LittleWeasel/services/dictionary_file_loader_service.rb +1 -1
  30. data/lib/LittleWeasel/services/dictionary_metadata_service.rb +4 -2
  31. data/lib/LittleWeasel/version.rb +1 -1
  32. data/spec/factories/dictionary_cache_service.rb +2 -2
  33. data/spec/lib/LittleWeasel/dictionary_manager_spec.rb +52 -2
  34. data/spec/lib/LittleWeasel/metadata/invalid_words_metadata_spec.rb +1 -1
  35. data/spec/lib/LittleWeasel/modules/dictionary_sourceable_spec.rb +56 -19
  36. data/spec/lib/LittleWeasel/modules/language_spec.rb +65 -5
  37. data/spec/lib/LittleWeasel/modules/locale_spec.rb +4 -49
  38. data/spec/lib/LittleWeasel/modules/region_spec.rb +65 -5
  39. data/spec/lib/LittleWeasel/preprocessors/word_preprocessor_managable_spec.rb +28 -2
  40. data/spec/lib/LittleWeasel/preprocessors/word_preprocessor_spec.rb +43 -0
  41. data/spec/lib/LittleWeasel/services/dictionary_cache_service_spec.rb +25 -25
  42. data/spec/support/file_helpers.rb +17 -3
  43. data/spec/support/shared_contexts.rb +0 -1
  44. metadata +12 -15
  45. data/lib/LittleWeasel/modules/dictionary_loader_servicable.rb +0 -27
  46. data/lib/LittleWeasel/services/dictionary_loader_service.rb +0 -59
  47. data/spec/factories/dictionary_loader_service.rb +0 -14
  48. data/spec/lib/LittleWeasel/services/dictionary_loader_service_spec.rb +0 -50
@@ -4,7 +4,6 @@ require_relative '../modules/dictionary_cache_keys'
4
4
  require_relative '../modules/dictionary_cache_validatable'
5
5
  require_relative '../modules/dictionary_keyable'
6
6
  require_relative '../modules/dictionary_sourceable'
7
- require_relative '../modules/dictionary_validatable'
8
7
 
9
8
  module LittleWeasel
10
9
  module Services
@@ -17,11 +16,10 @@ module LittleWeasel
17
16
  # objects to share dictionary information, in particular, the dictionary
18
17
  # file and dictionary metadata.
19
18
  class DictionaryCacheService
20
- include Modules::DictionaryKeyable
21
- include Modules::DictionaryCacheValidatable
22
19
  include Modules::DictionaryCacheKeys
20
+ include Modules::DictionaryCacheValidatable
21
+ include Modules::DictionaryKeyable
23
22
  include Modules::DictionarySourceable
24
- include Modules::DictionaryValidatable
25
23
 
26
24
  attr_reader :dictionary_cache
27
25
 
@@ -129,26 +127,6 @@ module LittleWeasel
129
127
  dictionary_cache[DICTIONARY_CACHE][DICTIONARIES].key? dictionary_id
130
128
  end
131
129
 
132
- # Adds a dictionary source. A "dictionary source" specifies the source from which
133
- # the dictionary ultimately obtains its words.
134
- #
135
- # @param source [String] the dictionary source. This can be a file path
136
- # or a memory source indicator to signify that the dictionary was created
137
- # dynamically from memory.
138
- def add_dictionary_source(source:)
139
- validate_dictionary_source_does_not_exist dictionary_cache_service: self
140
-
141
- dictionary_id = dictionary_id_for_dictionary_source(source: source)
142
- self.dictionary_reference = dictionary_id
143
- # Only set the dictionary source if it doesn't already exist because settings
144
- # the dictionary source wipes out the #dictionary_object; dictionary objects
145
- # can have more than one dictionary reference pointing to them, and we don't
146
- # want to blow away the #dictionary_object, metadata, or any other data
147
- # associated with it if it already exists.
148
- self.dictionary_source = source unless dictionary?
149
- self
150
- end
151
-
152
130
  # Returns the dictionary id if there is a dictionary id in the dictionary
153
131
  # cache associated with the given key; nil otherwise.
154
132
  def dictionary_id
@@ -164,25 +142,19 @@ module LittleWeasel
164
142
  raise ArgumentError, "A dictionary id could not be found for key '#{key}'."
165
143
  end
166
144
 
167
- def dictionary_source!
168
- raise ArgumentError, "A dictionary source could not be found for key '#{key}'." unless dictionary_reference?
169
-
170
- dictionary_cache[DICTIONARY_CACHE][DICTIONARIES][dictionary_id!][SOURCE]
171
- end
172
- alias dictionary_file! dictionary_source!
173
-
174
- def dictionary_source
175
- dictionary_cache.dig(DICTIONARY_CACHE, DICTIONARIES, dictionary_id, SOURCE)
176
- end
177
- alias dictionary_file dictionary_source
178
-
179
145
  # This method returns true if the dictionary associated with the
180
146
  # given dictionary key is loaded/cached. If this is the case,
181
147
  # a dictionary object is available in the dictionary cache.
182
148
  def dictionary_object?
183
149
  dictionary_object.present?
184
150
  end
185
- alias dictionary_exists? dictionary_object?
151
+ alias dictionary_exist? dictionary_object?
152
+
153
+ # <b>DEPRECATED:</b> Use <tt>dictionary_exist?</tt> instead.
154
+ def dictionary_exists?
155
+ warn "[DEPRECATION] 'dictionary_exists?' is deprecated. Please use 'dictionary_exist?' instead."
156
+ dictionary_object?
157
+ end
186
158
 
187
159
  # Returns the dictionary object from the dictionary cache for the given
188
160
  # key. This method raises an error if the dictionary is not in the cache;
@@ -209,7 +181,7 @@ module LittleWeasel
209
181
  end
210
182
  return if object.equal? dictionary_object
211
183
 
212
- if dictionary_exists?
184
+ if dictionary_exist?
213
185
  raise ArgumentError,
214
186
  "The dictionary is already loaded/cached for key '#{key}'; use #unload or #kill first."
215
187
  end
@@ -225,35 +197,12 @@ module LittleWeasel
225
197
  dictionary_cache.dig(DICTIONARY_CACHE, DICTIONARY_REFERENCES, key)
226
198
  end
227
199
 
228
- def dictionary_reference=(dictionary_id)
200
+ def set_dictionary_reference(dictionary_id:)
229
201
  dictionary_cache[DICTIONARY_CACHE][DICTIONARY_REFERENCES][key] = {
230
202
  DICTIONARY_ID => dictionary_id
231
203
  }
232
204
  end
233
205
 
234
- # Returns the dictionary_id for the source if it exists in dictionaries;
235
- # otherwise, returns the new dictionary id that should be used.
236
- def dictionary_id_for_dictionary_source(source:)
237
- dictionary_source?(source: source) || SecureRandom.uuid[0..7]
238
- end
239
-
240
- # Returns the dictionary_id associated with source if source exists;
241
- # nil otherwise.
242
- def dictionary_source?(source:)
243
- dictionaries = dictionary_cache.dig(DICTIONARY_CACHE, DICTIONARIES)
244
- dictionaries&.each_pair do |dictionary_id, dictionary_hash|
245
- return dictionary_id if source == dictionary_hash[SOURCE]
246
- end
247
- nil
248
- end
249
-
250
- def dictionary_source=(source)
251
- dictionary_cache[DICTIONARY_CACHE][DICTIONARIES][dictionary_id!] = {
252
- SOURCE => source,
253
- DICTIONARY_OBJECT => {}
254
- }
255
- end
256
-
257
206
  def dictionary_id?
258
207
  dictionary_id.present?
259
208
  end
@@ -77,7 +77,7 @@ module LittleWeasel
77
77
  #
78
78
  # @return returns a reference to self.
79
79
  def add_dictionary_file_source(file:)
80
- dictionary_cache_service.add_dictionary_source(source: file)
80
+ dictionary_cache_service.add_dictionary_source(dictionary_source: file)
81
81
  end
82
82
 
83
83
  # Adds a dictionary memory source. A "memory source" indicates that the
@@ -87,7 +87,7 @@ module LittleWeasel
87
87
  #
88
88
  # @return returns a reference to self.
89
89
  def add_dictionary_memory_source
90
- dictionary_cache_service.add_dictionary_source(source: memory_source)
90
+ dictionary_cache_service.add_dictionary_source(dictionary_source: memory_source)
91
91
  end
92
92
  end
93
93
  end
@@ -25,7 +25,7 @@ module LittleWeasel
25
25
  end
26
26
 
27
27
  def execute
28
- if dictionary_cache_service.dictionary_exists?
28
+ if dictionary_cache_service.dictionary_exist?
29
29
  raise ArgumentError,
30
30
  "The dictionary associated with key '#{key}' already exists."
31
31
  end
@@ -42,7 +42,8 @@ module LittleWeasel
42
42
  # initialized state - all data is lost, but the object reference is
43
43
  # maintained.
44
44
  def init(dictionary_metadata:)
45
- Modules::DictionaryMetadataValidatable.validate dictionary_metadata: dictionary_metadata
45
+ Modules::DictionaryMetadataValidatable.validate_dictionary_metadata \
46
+ dictionary_metadata: dictionary_metadata
46
47
 
47
48
  dictionary_metadata.each_key { |key| dictionary_metadata.delete(key) }
48
49
  dictionary_metadata
@@ -52,7 +53,8 @@ module LittleWeasel
52
53
  # it's in the same state the dictionary metadata would be in if #init
53
54
  # were called.
54
55
  def init?(dictionary_metadata:)
55
- Modules::DictionaryMetadataValidatable.validate dictionary_metadata: dictionary_metadata
56
+ Modules::DictionaryMetadataValidatable.validate_dictionary_metadata \
57
+ dictionary_metadata: dictionary_metadata
56
58
 
57
59
  initialized_dictionary_metadata = init(dictionary_metadata: {})
58
60
  dictionary_metadata.eql?(initialized_dictionary_metadata)
@@ -2,5 +2,5 @@
2
2
 
3
3
  # The version of this gem
4
4
  module LittleWeasel
5
- VERSION = '4.0.0'
5
+ VERSION = '5.0.0'
6
6
  end
@@ -70,9 +70,9 @@ FactoryBot.define do
70
70
  else
71
71
  dictionary_file_source
72
72
  end
73
- dictionary_cache_service.add_dictionary_source(source: dictionary_path_for(file_name: file_name))
73
+ dictionary_cache_service.add_dictionary_source(dictionary_source: dictionary_path_for(file_name: file_name))
74
74
  elsif dictionary_memory_source
75
- dictionary_cache_service.add_dictionary_source(source: LittleWeasel::Modules::DictionarSourceable.memory_source)
75
+ dictionary_cache_service.add_dictionary_source(dictionary_source: LittleWeasel::Modules::DictionarSourceable.memory_source)
76
76
  end
77
77
 
78
78
  if load
@@ -3,6 +3,8 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe LittleWeasel::DictionaryManager do
6
+ include_context 'dictionary keys'
7
+
6
8
  subject { create(:dictionary_manager) }
7
9
 
8
10
  let(:dictionary_cache_service) { create(:dictionary_cache_service, dictionary_key: dictionary_key, dictionary_cache: dictionary_cache)}
@@ -31,6 +33,54 @@ RSpec.describe LittleWeasel::DictionaryManager do
31
33
  end
32
34
  end
33
35
 
36
+ #dictionary_exist?
37
+ describe '#dictionary_exist?' do
38
+ let!(:expected_dictionary_object) do
39
+ subject.create_dictionary_from_memory(dictionary_key: dictionary_key,
40
+ dictionary_words: %w(My dictionary words) )
41
+ end
42
+
43
+ context 'when the dictionary exists' do
44
+ it 'returns true' do
45
+ expect(subject.dictionary_exist? dictionary_key: dictionary_key)
46
+ .to eq true
47
+ end
48
+ end
49
+
50
+ context 'when the dictionary DOES NOT exist' do
51
+ let(:en_gb_dictionary_key) { dictionary_key_for(language: :en, region: :gb) }
52
+
53
+ it 'returns false' do
54
+ expect(subject.dictionary_exist? dictionary_key: en_gb_dictionary_key)
55
+ .to eq false
56
+ end
57
+ end
58
+ end
59
+
60
+ #dictionary_for
61
+ describe '#dictionary_for' do
62
+ let!(:expected_dictionary_object) do
63
+ subject.create_dictionary_from_memory(dictionary_key: dictionary_key,
64
+ dictionary_words: %w(My dictionary words) )
65
+ end
66
+
67
+ context 'when the dictionary exists' do
68
+ it 'returns the dictionary object' do
69
+ expect(subject.dictionary_for dictionary_key: dictionary_key)
70
+ .to be expected_dictionary_object
71
+ end
72
+ end
73
+
74
+ context 'when the dictionary DOES NOT exist' do
75
+ let(:en_gb_dictionary_key) { dictionary_key_for(language: :en, region: :gb) }
76
+
77
+ it 'raises an error' do
78
+ expect { subject.dictionary_for dictionary_key: en_gb_dictionary_key }
79
+ .to raise_error("The dictionary object associated with argument key '#{en_gb_dictionary_key.key}' is not in the cache.")
80
+ end
81
+ end
82
+ end
83
+
34
84
  #create_dictionary_from_file
35
85
  describe '#create_dictionary_from_file' do
36
86
  context 'when the dictionary DOES NOT exist' do
@@ -85,7 +135,7 @@ RSpec.describe LittleWeasel::DictionaryManager do
85
135
  it 'removes the dictionary, file source reference and metadata from the dictionary cache' do
86
136
  metadata_key # Capture this before we unload the dictionary
87
137
  subject.kill_dictionary(dictionary_key: dictionary_key)
88
- expect(dictionary_cache_service.dictionary_exists?).to eq false
138
+ expect(dictionary_cache_service.dictionary_exist?).to eq false
89
139
  expect(dictionary_cache_service.dictionary_reference?).to eq false
90
140
  expect(dictionary_metadata_service.dictionary_metadata?(metadata_key: metadata_key)).to eq false
91
141
  end
@@ -103,7 +153,7 @@ RSpec.describe LittleWeasel::DictionaryManager do
103
153
  it 'removes the dictionary, memory source reference and metadata from the dictionary cache' do
104
154
  metadata_key # Capture this before we unload the dictionary
105
155
  subject.kill_dictionary(dictionary_key: dictionary_key)
106
- expect(dictionary_cache_service.dictionary_exists?).to eq false
156
+ expect(dictionary_cache_service.dictionary_exist?).to eq false
107
157
  expect(dictionary_cache_service.dictionary_reference?).to eq false
108
158
  expect(dictionary_metadata_service.dictionary_metadata?(metadata_key: metadata_key)).to eq false
109
159
  end
@@ -35,7 +35,7 @@ RSpec.describe LittleWeasel::Metadata::InvalidWordsMetadata do
35
35
  subject { invalid_words_metadata }
36
36
 
37
37
  before do
38
- dictionary_cache_service.add_dictionary_source(source: file)
38
+ dictionary_cache_service.add_dictionary_source(dictionary_source: file)
39
39
  end
40
40
 
41
41
  context 'with invalid dictionary metadata object' do
@@ -3,10 +3,24 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe LittleWeasel::Modules::DictionarySourceable, type: :module do
6
+ subject { MockDictionarySourceable.new(dictionary_memory_source) }
7
+
8
+ DictionarySourceable = described_class
9
+
10
+ class MockDictionarySourceable
11
+ include DictionarySourceable
12
+
13
+ def initialize(dictionary_source)
14
+ self.dictionary_source = dictionary_source
15
+ end
16
+ end
17
+
18
+ let(:dictionary_memory_source) { described_class.memory_source }
19
+ let(:dictionary_file_source) { language_dictionary_path language: :en }
6
20
 
7
21
  #.MEMORY_SOURCE
8
22
  describe '::MEMORY_SOURCE' do
9
- it 'returns the memory source value' do
23
+ it 'returns the memory source prefix' do
10
24
  expect(described_class::MEMORY_SOURCE).to eq '*'
11
25
  end
12
26
  end
@@ -14,31 +28,54 @@ RSpec.describe LittleWeasel::Modules::DictionarySourceable, type: :module do
14
28
  #.memory_source
15
29
  describe '.memory_source' do
16
30
  it 'returns a new memory source' do
17
- expect(described_class.memory_source?(described_class.memory_source)).to be_truthy
31
+ expect(described_class.memory_source).to be_truthy
32
+ end
33
+ end
34
+
35
+ #.file_source?
36
+ describe '.file_source?' do
37
+ context 'when dictionary_source is a file source' do
38
+ it 'returns truthy' do
39
+ expect(described_class.file_source? dictionary_file_source).to be_truthy
40
+ end
41
+ end
42
+
43
+ context 'when dictionary_source is NOT a file source' do
44
+ it 'returns falsey' do
45
+ expect(described_class.file_source? dictionary_memory_source).to be_falsey
46
+ end
18
47
  end
19
48
  end
20
49
 
21
50
  #.memory_source?
22
51
  describe '.memory_source?' do
23
- it 'returns truthy if argument is a valid memory source' do
24
- expect(described_class.memory_source? '*12345678').to be_truthy
25
- expect(described_class.memory_source? '*abcdef00').to be_truthy
26
- expect(described_class.memory_source? '*ABCDEF00').to be_truthy
27
- expect(described_class.memory_source? '*aBcDeF00').to be_truthy
52
+ context 'when dictionary_source is a memory source' do
53
+ it 'returns truthy if argument is a valid memory source' do
54
+ expect(described_class.memory_source? '*12345678').to be_truthy
55
+ expect(described_class.memory_source? '*abcdef00').to be_truthy
56
+ expect(described_class.memory_source? '*ABCDEF00').to be_truthy
57
+ expect(described_class.memory_source? '*aBcDeF00').to be_truthy
58
+ end
59
+
60
+ it 'returns falsey if argument is NOT a memory source' do
61
+ expect(described_class.memory_source? '*123456789').to be_falsey
62
+ expect(described_class.memory_source? '*abcdefg0').to be_falsey
63
+ expect(described_class.memory_source? '*ABCDEFG0').to be_falsey
64
+ expect(described_class.memory_source? '*aBcDeFg0').to be_falsey
65
+ expect(described_class.memory_source? '$12345678').to be_falsey
66
+
67
+ expect(described_class.memory_source? '123456789').to be_falsey
68
+ expect(described_class.memory_source? 'abcdefg0').to be_falsey
69
+ expect(described_class.memory_source? 'ABCDEFG0').to be_falsey
70
+ expect(described_class.memory_source? 'aBcDeFg0').to be_falsey
71
+ expect(described_class.memory_source? '123456789').to be_falsey
72
+ end
28
73
  end
29
74
 
30
- it 'returns falsey if argument is NOT a memory source' do
31
- expect(described_class.memory_source? '*123456789').to be_falsey
32
- expect(described_class.memory_source? '*abcdefg0').to be_falsey
33
- expect(described_class.memory_source? '*ABCDEFG0').to be_falsey
34
- expect(described_class.memory_source? '*aBcDeFg0').to be_falsey
35
- expect(described_class.memory_source? '$12345678').to be_falsey
36
-
37
- expect(described_class.memory_source? '123456789').to be_falsey
38
- expect(described_class.memory_source? 'abcdefg0').to be_falsey
39
- expect(described_class.memory_source? 'ABCDEFG0').to be_falsey
40
- expect(described_class.memory_source? 'aBcDeFg0').to be_falsey
41
- expect(described_class.memory_source? '123456789').to be_falsey
75
+ context 'when dictionary_source is a file source' do
76
+ it 'returns falsey' do
77
+ expect(described_class.memory_source? dictionary_file_source).to be_falsey
78
+ end
42
79
  end
43
80
  end
44
81
  end
@@ -23,14 +23,66 @@ RSpec.describe LittleWeasel::Modules::Language, type: :module do
23
23
 
24
24
  let(:language) {}
25
25
 
26
- #normalize_language
27
- describe '#normalize_language' do
26
+ #language?
27
+ describe '#language?' do
28
+ context 'when language is present?' do
29
+ let(:language) { :es }
30
+
31
+ it 'returns true' do
32
+ expect(subject.language?).to eq true
33
+ end
34
+ end
35
+
36
+ context 'when language is NOT present?' do
37
+ it 'returns false' do
38
+ expect(subject.language?).to eq false
39
+ end
40
+ end
41
+ end
42
+
43
+ #normalize_language!
44
+ describe '#normalize_language!' do
45
+ context 'when language is present?' do
46
+ context 'when language responds to #upcase!' do
47
+ before do
48
+ subject.normalize_language!
49
+ end
50
+
51
+ let(:language) { :AA }
52
+
53
+ it 'changes language to lower case' do
54
+ expect(subject.language).to eq :aa
55
+ end
56
+ end
57
+
58
+ context 'when language DOES NOT respond to #downcase' do
59
+ let(:language) { Object.new }
60
+
61
+ it 'raises an error' do
62
+ expect { subject.normalize_language! }.to raise_error(NoMethodError, /undefined method `downcase'/)
63
+ end
64
+ end
65
+ end
66
+
67
+ context 'when language is NOT present?' do
68
+ before do
69
+ subject.normalize_language!
70
+ end
71
+
72
+ it 'does nothing' do
73
+ expect(subject.language).to be_nil
74
+ end
75
+ end
76
+ end
77
+
78
+ #.normalize_language
79
+ describe '#.normalize_language' do
28
80
  context 'with a non-nil language' do
29
81
  context 'when passing a Symbol' do
30
82
  let(:language) { :AbCdEfG }
31
83
 
32
84
  it 'converts the language to a lower-case Symbol' do
33
- expect(subject.normalize_language).to eq :abcdefg
85
+ expect(described_class.normalize_language(language)).to eq :abcdefg
34
86
  end
35
87
  end
36
88
 
@@ -38,14 +90,22 @@ RSpec.describe LittleWeasel::Modules::Language, type: :module do
38
90
  let(:language) { 'AbCdEfG' }
39
91
 
40
92
  it 'converts the language to a lower-case String' do
41
- expect(subject.normalize_language).to eq 'abcdefg'
93
+ expect(described_class.normalize_language(language)).to eq 'abcdefg'
42
94
  end
43
95
  end
44
96
  end
45
97
 
46
98
  context 'with a nil language' do
47
99
  it 'returns nil' do
48
- expect(subject.normalize_language).to be_nil
100
+ expect(described_class.normalize_language(language)).to be_nil
101
+ end
102
+ end
103
+
104
+ context 'when language does not respond to #downcase' do
105
+ let(:language) { 1 }
106
+
107
+ it 'returns nil' do
108
+ expect { described_class.normalize_language(language) }.to raise_error(NoMethodError, /undefined method `downcase'/)
49
109
  end
50
110
  end
51
111
  end
@@ -25,51 +25,6 @@ RSpec.describe LittleWeasel::Modules::Locale, type: :module do
25
25
  let(:language) {}
26
26
  let(:region) {}
27
27
 
28
- #.locale
29
- describe '.locale' do
30
- it 'adds the class method when included' do
31
- expect(subject.class).to respond_to(:locale)
32
- end
33
-
34
- context 'with valid arguments' do
35
- let(:language) { :en }
36
- let(:region) { :us }
37
-
38
- it 'returns the locale as a string' do
39
- expect(subject.class.locale language: language, region: region).to eq 'en-US'
40
- end
41
- end
42
-
43
- context 'with INVALID arguments' do
44
- context 'with an invalid language' do
45
- let(:language) {}
46
- let(:region) { :us }
47
-
48
- it 'raises an error' do
49
- expect { subject.class.locale language: language, region: region }.to raise_error 'Argument language does not respond to :downcase'
50
- end
51
- end
52
-
53
- context 'when region is nil' do
54
- let(:language) { :en }
55
- let(:region) {}
56
-
57
- it 'returns the expected locale as a string' do
58
- expect(subject.class.locale language: language, region: region).to eq language.downcase.to_s
59
- end
60
- end
61
-
62
- context 'when region is invalid' do
63
- let(:language) { :en }
64
- let(:region) { 1 }
65
-
66
- it 'raises an error' do
67
- expect { subject.class.locale language: language, region: region }.to raise_error 'Argument region does not respond to :upcase'
68
- end
69
- end
70
- end
71
- end
72
-
73
28
  #locale
74
29
  describe '#locale' do
75
30
  context 'with valid arguments' do
@@ -119,20 +74,20 @@ RSpec.describe LittleWeasel::Modules::Locale, type: :module do
119
74
  end
120
75
 
121
76
  context 'with invalid arguments' do
122
- context 'with invalid language' do
77
+ context 'when argument language does not respond to #downcase' do
123
78
  let(:language) { 1 }
124
79
 
125
80
  it 'raises an error' do
126
- expect { subject.locale }.to raise_error 'Argument language does not respond to :downcase'
81
+ expect { subject.locale }.to raise_error(NoMethodError, /undefined method `downcase'/)
127
82
  end
128
83
  end
129
84
 
130
- context 'with invalid region' do
85
+ context 'when argument region does not respond to #upcase' do
131
86
  let(:language) { :en }
132
87
  let(:region) { 1 }
133
88
 
134
89
  it 'raises an error' do
135
- expect { subject.locale }.to raise_error 'Argument region does not respond to :upcase'
90
+ expect { subject.locale }.to raise_error(NoMethodError, /undefined method `upcase'/)
136
91
  end
137
92
  end
138
93
  end
@@ -23,14 +23,66 @@ RSpec.describe LittleWeasel::Modules::Region, type: :module do
23
23
 
24
24
  let(:region) {}
25
25
 
26
- #normalize_region
27
- describe '#normalize_region' do
26
+ #region?
27
+ describe '#region?' do
28
+ context 'when region is present?' do
29
+ let(:region) { :es }
30
+
31
+ it 'returns true' do
32
+ expect(subject.region?).to eq true
33
+ end
34
+ end
35
+
36
+ context 'when region is NOT present?' do
37
+ it 'returns false' do
38
+ expect(subject.region?).to eq false
39
+ end
40
+ end
41
+ end
42
+
43
+ #normalize_region!
44
+ describe '#normalize_region!' do
45
+ context 'when region is present?' do
46
+ context 'when region responds to #upcase' do
47
+ before do
48
+ subject.normalize_region!
49
+ end
50
+
51
+ let(:region) { :aa }
52
+
53
+ it 'changes region to upper case' do
54
+ expect(subject.region).to eq :AA
55
+ end
56
+ end
57
+
58
+ context 'when region DOES NOT respond to #upcase' do
59
+ let(:region) { Object.new }
60
+
61
+ it 'raises an error' do
62
+ expect { subject.normalize_region! }.to raise_error(NoMethodError, /undefined method `upcase'/)
63
+ end
64
+ end
65
+ end
66
+
67
+ context 'when region is NOT present?' do
68
+ before do
69
+ subject.normalize_region!
70
+ end
71
+
72
+ it 'does nothing' do
73
+ expect(subject.region).to be_nil
74
+ end
75
+ end
76
+ end
77
+
78
+ #.normalize_region
79
+ describe '#.normalize_region' do
28
80
  context 'with a non-nil region' do
29
81
  context 'when passing a Symbol' do
30
82
  let(:region) { :AbCdEfG }
31
83
 
32
84
  it 'converts the region to a upper-case Symbol' do
33
- expect(subject.normalize_region).to eq :ABCDEFG
85
+ expect(described_class.normalize_region(region)).to eq :ABCDEFG
34
86
  end
35
87
  end
36
88
 
@@ -38,14 +90,22 @@ RSpec.describe LittleWeasel::Modules::Region, type: :module do
38
90
  let(:region) { 'AbCdEfG' }
39
91
 
40
92
  it 'converts the region to a upper-case String' do
41
- expect(subject.normalize_region).to eq 'ABCDEFG'
93
+ expect(described_class.normalize_region(region)).to eq 'ABCDEFG'
42
94
  end
43
95
  end
44
96
  end
45
97
 
46
98
  context 'with a nil region' do
47
99
  it 'returns nil' do
48
- expect(subject.normalize_region).to be_nil
100
+ expect(described_class.normalize_region(region)).to be_nil
101
+ end
102
+ end
103
+
104
+ context 'when region does not respond to #upcase' do
105
+ let(:region) { 1 }
106
+
107
+ it 'returns nil' do
108
+ expect { described_class.normalize_region(region) }.to raise_error(NoMethodError, /undefined method `upcase'/)
49
109
  end
50
110
  end
51
111
  end