LittleWeasel 3.0.3 → 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 (151) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +3 -0
  3. data/.reek.yml +17 -0
  4. data/.rspec +4 -2
  5. data/.rubocop.yml +187 -0
  6. data/.ruby-version +1 -1
  7. data/.yardopts +2 -0
  8. data/CHANGELOG.md +22 -1
  9. data/Gemfile +3 -1
  10. data/Jenkinsfile +20 -0
  11. data/LittleWeasel.gemspec +31 -18
  12. data/README.md +408 -42
  13. data/Rakefile +296 -3
  14. data/lib/LittleWeasel/block_results.rb +81 -0
  15. data/lib/LittleWeasel/configure.rb +98 -0
  16. data/lib/LittleWeasel/dictionary.rb +125 -0
  17. data/lib/LittleWeasel/dictionary_key.rb +48 -0
  18. data/lib/LittleWeasel/dictionary_manager.rb +91 -0
  19. data/lib/LittleWeasel/errors/dictionary_file_already_loaded_error.rb +9 -0
  20. data/lib/LittleWeasel/errors/dictionary_file_empty_error.rb +8 -0
  21. data/lib/LittleWeasel/errors/dictionary_file_not_found_error.rb +8 -0
  22. data/lib/LittleWeasel/errors/dictionary_file_too_large_error.rb +16 -0
  23. data/lib/LittleWeasel/errors/language_required_error.rb +8 -0
  24. data/lib/LittleWeasel/errors/must_override_error.rb +8 -0
  25. data/lib/LittleWeasel/filters/en_us/currency_filter.rb +19 -0
  26. data/lib/LittleWeasel/filters/en_us/numeric_filter.rb +19 -0
  27. data/lib/LittleWeasel/filters/en_us/single_character_word_filter.rb +21 -0
  28. data/lib/LittleWeasel/filters/word_filter.rb +59 -0
  29. data/lib/LittleWeasel/filters/word_filter_managable.rb +80 -0
  30. data/lib/LittleWeasel/filters/word_filter_validatable.rb +31 -0
  31. data/lib/LittleWeasel/filters/word_filterable.rb +19 -0
  32. data/lib/LittleWeasel/filters/word_filters_validatable.rb +29 -0
  33. data/lib/LittleWeasel/metadata/dictionary_metadata.rb +145 -0
  34. data/lib/LittleWeasel/metadata/invalid_words_metadata.rb +134 -0
  35. data/lib/LittleWeasel/metadata/invalid_words_service_results.rb +45 -0
  36. data/lib/LittleWeasel/metadata/metadata_observable_validatable.rb +22 -0
  37. data/lib/LittleWeasel/metadata/metadata_observerable.rb +90 -0
  38. data/lib/LittleWeasel/metadata/metadatable.rb +134 -0
  39. data/lib/LittleWeasel/modules/class_name_to_symbol.rb +26 -0
  40. data/lib/LittleWeasel/modules/configurable.rb +26 -0
  41. data/lib/LittleWeasel/modules/deep_dup.rb +11 -0
  42. data/lib/LittleWeasel/modules/dictionary_cache_keys.rb +34 -0
  43. data/lib/LittleWeasel/modules/dictionary_cache_servicable.rb +26 -0
  44. data/lib/LittleWeasel/modules/dictionary_cache_validatable.rb +18 -0
  45. data/lib/LittleWeasel/modules/dictionary_creator_servicable.rb +27 -0
  46. data/lib/LittleWeasel/modules/dictionary_file_loader.rb +67 -0
  47. data/lib/LittleWeasel/modules/dictionary_key_validatable.rb +17 -0
  48. data/lib/LittleWeasel/modules/dictionary_keyable.rb +24 -0
  49. data/lib/LittleWeasel/modules/dictionary_metadata_servicable.rb +29 -0
  50. data/lib/LittleWeasel/modules/dictionary_metadata_validatable.rb +15 -0
  51. data/lib/LittleWeasel/modules/dictionary_source_validatable.rb +15 -0
  52. data/lib/LittleWeasel/modules/dictionary_sourceable.rb +86 -0
  53. data/lib/LittleWeasel/modules/dictionary_validatable.rb +18 -0
  54. data/lib/LittleWeasel/modules/language.rb +24 -0
  55. data/lib/LittleWeasel/modules/language_validatable.rb +14 -0
  56. data/lib/LittleWeasel/modules/locale.rb +23 -0
  57. data/lib/LittleWeasel/modules/order_validatable.rb +16 -0
  58. data/lib/LittleWeasel/modules/orderable.rb +17 -0
  59. data/lib/LittleWeasel/modules/region.rb +24 -0
  60. data/lib/LittleWeasel/modules/region_validatable.rb +14 -0
  61. data/lib/LittleWeasel/modules/tag_validatable.rb +14 -0
  62. data/lib/LittleWeasel/modules/taggable.rb +31 -0
  63. data/lib/LittleWeasel/modules/word_results_validatable.rb +28 -0
  64. data/lib/LittleWeasel/preprocessors/en_us/capitalize_preprocessor.rb +22 -0
  65. data/lib/LittleWeasel/preprocessors/preprocessed_word.rb +29 -0
  66. data/lib/LittleWeasel/preprocessors/preprocessed_word_validatable.rb +56 -0
  67. data/lib/LittleWeasel/preprocessors/preprocessed_words.rb +59 -0
  68. data/lib/LittleWeasel/preprocessors/preprocessed_words_validatable.rb +28 -0
  69. data/lib/LittleWeasel/preprocessors/word_preprocessable.rb +19 -0
  70. data/lib/LittleWeasel/preprocessors/word_preprocessor.rb +123 -0
  71. data/lib/LittleWeasel/preprocessors/word_preprocessor_managable.rb +114 -0
  72. data/lib/LittleWeasel/preprocessors/word_preprocessor_validatable.rb +40 -0
  73. data/lib/LittleWeasel/preprocessors/word_preprocessors_validatable.rb +24 -0
  74. data/lib/LittleWeasel/services/dictionary_cache_service.rb +211 -0
  75. data/lib/LittleWeasel/services/dictionary_creator_service.rb +94 -0
  76. data/lib/LittleWeasel/services/dictionary_file_loader_service.rb +37 -0
  77. data/lib/LittleWeasel/services/dictionary_killer_service.rb +35 -0
  78. data/lib/LittleWeasel/services/dictionary_metadata_service.rb +116 -0
  79. data/lib/LittleWeasel/services/invalid_words_service.rb +59 -0
  80. data/lib/LittleWeasel/version.rb +3 -1
  81. data/lib/LittleWeasel/word_results.rb +146 -0
  82. data/lib/LittleWeasel.rb +5 -184
  83. data/spec/factories/dictionary.rb +43 -0
  84. data/spec/factories/dictionary_cache_service.rb +95 -0
  85. data/spec/factories/dictionary_creator_service.rb +16 -0
  86. data/spec/factories/dictionary_file_loader_service.rb +13 -0
  87. data/spec/factories/dictionary_hash.rb +39 -0
  88. data/spec/factories/dictionary_key.rb +14 -0
  89. data/spec/factories/dictionary_killer_service.rb +14 -0
  90. data/spec/factories/dictionary_manager.rb +10 -0
  91. data/spec/factories/dictionary_metadata.rb +16 -0
  92. data/spec/factories/dictionary_metadata_service.rb +16 -0
  93. data/spec/factories/numeric_filter.rb +12 -0
  94. data/spec/factories/preprocessed_word.rb +16 -0
  95. data/spec/factories/preprocessed_words.rb +41 -0
  96. data/spec/factories/single_character_word_filter.rb +12 -0
  97. data/spec/factories/word_results.rb +16 -0
  98. data/spec/lib/LittleWeasel/block_results_spec.rb +248 -0
  99. data/spec/lib/LittleWeasel/configure_spec.rb +74 -0
  100. data/spec/lib/LittleWeasel/dictionary_key_spec.rb +118 -0
  101. data/spec/lib/LittleWeasel/dictionary_manager_spec.rb +166 -0
  102. data/spec/lib/LittleWeasel/dictionary_spec.rb +289 -0
  103. data/spec/lib/LittleWeasel/filters/en_us/currency_filter_spec.rb +80 -0
  104. data/spec/lib/LittleWeasel/filters/en_us/numeric_filter_spec.rb +66 -0
  105. data/spec/lib/LittleWeasel/filters/en_us/single_character_word_filter_spec.rb +58 -0
  106. data/spec/lib/LittleWeasel/filters/word_filter_managable_spec.rb +180 -0
  107. data/spec/lib/LittleWeasel/filters/word_filter_spec.rb +151 -0
  108. data/spec/lib/LittleWeasel/filters/word_filter_validatable_spec.rb +94 -0
  109. data/spec/lib/LittleWeasel/filters/word_filters_validatable_spec.rb +48 -0
  110. data/spec/lib/LittleWeasel/integraton_tests/dictionary_integration_spec.rb +201 -0
  111. data/spec/lib/LittleWeasel/metadata/dictionary_creator_servicable_spec.rb +54 -0
  112. data/spec/lib/LittleWeasel/metadata/dictionary_metadata_spec.rb +209 -0
  113. data/spec/lib/LittleWeasel/metadata/invalid_words_metadata_spec.rb +155 -0
  114. data/spec/lib/LittleWeasel/metadata/metadata_observerable_spec.rb +31 -0
  115. data/spec/lib/LittleWeasel/metadata/metadatable_spec.rb +35 -0
  116. data/spec/lib/LittleWeasel/modules/class_name_to_symbol_spec.rb +21 -0
  117. data/spec/lib/LittleWeasel/modules/dictionary_file_loader_spec.rb +125 -0
  118. data/spec/lib/LittleWeasel/modules/dictionary_sourceable_spec.rb +81 -0
  119. data/spec/lib/LittleWeasel/modules/language_spec.rb +112 -0
  120. data/spec/lib/LittleWeasel/modules/locale_spec.rb +95 -0
  121. data/spec/lib/LittleWeasel/modules/region_spec.rb +112 -0
  122. data/spec/lib/LittleWeasel/preprocessors/en_us/capitalize_preprocessor_spec.rb +34 -0
  123. data/spec/lib/LittleWeasel/preprocessors/preprocessed_word_spec.rb +105 -0
  124. data/spec/lib/LittleWeasel/preprocessors/preprocessed_word_validatable_spec.rb +143 -0
  125. data/spec/lib/LittleWeasel/preprocessors/preprocessed_words_spec.rb +77 -0
  126. data/spec/lib/LittleWeasel/preprocessors/preprocessed_words_validatable_spec.rb +58 -0
  127. data/spec/lib/LittleWeasel/preprocessors/word_preprocessor_managable_spec.rb +242 -0
  128. data/spec/lib/LittleWeasel/preprocessors/word_preprocessor_spec.rb +218 -0
  129. data/spec/lib/LittleWeasel/preprocessors/word_preprocessor_validatable_spec.rb +109 -0
  130. data/spec/lib/LittleWeasel/preprocessors/word_preprocessors_validatable_spec.rb +49 -0
  131. data/spec/lib/LittleWeasel/services/dictionary_cache_service_spec.rb +444 -0
  132. data/spec/lib/LittleWeasel/services/dictionary_creator_service_spec.rb +119 -0
  133. data/spec/lib/LittleWeasel/services/dictionary_file_loader_service_spec.rb +71 -0
  134. data/spec/lib/LittleWeasel/services/dictionary_metadata_service_spec.rb +279 -0
  135. data/spec/lib/LittleWeasel/word_results_spec.rb +275 -0
  136. data/spec/lib/LittleWeasel/workflow/workflow_spec.rb +20 -0
  137. data/spec/spec_helper.rb +117 -6
  138. data/spec/support/factory_bot.rb +15 -0
  139. data/spec/support/file_helpers.rb +46 -0
  140. data/spec/support/files/empty-dictionary.txt +0 -0
  141. data/{lib/dictionary → spec/support/files/en-US-big.txt} +262156 -31488
  142. data/spec/support/files/en-US-tagged.txt +26 -0
  143. data/spec/support/files/en-US.txt +26 -0
  144. data/spec/support/files/en.txt +26 -0
  145. data/spec/support/files/es-ES.txt +27 -0
  146. data/spec/support/files/es.txt +27 -0
  147. data/spec/support/general_helpers.rb +68 -0
  148. data/spec/support/shared_contexts.rb +107 -0
  149. data/spec/support/shared_examples.rb +105 -0
  150. metadata +378 -38
  151. data/spec/checker/checker_spec.rb +0 -286
@@ -0,0 +1,279 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LittleWeasel::Services::DictionaryMetadataService do
6
+ include_context 'dictionary cache'
7
+ include_context 'dictionary keys'
8
+
9
+ subject { create(:dictionary_metadata_service, dictionary_key: dictionary_key, dictionary_metadata: dictionary_metadata, dictionary_cache: dictionary_cache) }
10
+
11
+ let(:en_us_dictionary_key) { dictionary_key_for(language: :en, region: :us) }
12
+ let(:en_gb_dictionary_key) { dictionary_key_for(language: :en, region: :gb) }
13
+ let(:es_es_dictionary_key) { dictionary_key_for(language: :es, region: :es) }
14
+
15
+ let(:dictionary_key) { en_us_dictionary_key }
16
+ let(:key) { dictionary_key.key }
17
+ let(:file) { dictionary_path_for(file_name: key) }
18
+ let(:dictionary_cache) { {} }
19
+ let(:metadata_key) { :metadata_key }
20
+ let(:dictionary_metadata) do
21
+ {
22
+ 0 => { metadata_key => :metadata_object0 },
23
+ 1 => { metadata_key1: :metadata_object1 }
24
+ }
25
+ end
26
+
27
+ shared_examples 'the dictionary_metadata object reference has not changed' do
28
+ it 'the dictionary_metadata object has not changed' do
29
+ expect(actual_dictionary_metadata).to be expected_dictionary_metadata
30
+ end
31
+ end
32
+
33
+ shared_examples 'the dictionary_cache object reference has not changed' do
34
+ it 'the dictionary_cache object has not changed' do
35
+ expect(actual_dictionary_cache).to be expected_dictionary_cache
36
+ end
37
+ end
38
+
39
+ describe 'class methods' do
40
+ #.init
41
+ describe '.init' do
42
+ context 'with a valid dictionary metadata argument' do
43
+ it 'initializes the dictionary metadata' do
44
+ expect(described_class.init(dictionary_metadata: dictionary_metadata)).to eq({})
45
+ end
46
+
47
+ it_behaves_like 'the dictionary_metadata object reference has not changed' do
48
+ let(:expected_dictionary_metadata) { dictionary_metadata }
49
+ let(:actual_dictionary_metadata) { subject.dictionary_metadata }
50
+ end
51
+ end
52
+
53
+ context 'with an INVALID dictionary metadata argument' do
54
+ subject { described_class.init(dictionary_metadata: dictionary_metadata) }
55
+
56
+ it_behaves_like 'the dictionary_metadata is invalid'
57
+ end
58
+ end
59
+
60
+ #.init?
61
+ describe '.init?' do
62
+ context 'with a valid dictionary metadata argument' do
63
+ context 'when the dictionary metadata is in an initialized state' do
64
+ let(:dictionary_metadata) { {} }
65
+
66
+ it 'returns true' do
67
+ expect(described_class.init?(dictionary_metadata: dictionary_metadata)).to eq true
68
+ end
69
+ end
70
+
71
+ context 'when the dictionary metadata is NOT in an initialized state' do
72
+ it 'returns false' do
73
+ expect(described_class.init?(dictionary_metadata: dictionary_metadata)).to eq false
74
+ end
75
+ end
76
+ end
77
+
78
+ context 'with an INVALID dictionary metadata argument' do
79
+ subject { described_class.init?(dictionary_metadata: dictionary_metadata) }
80
+
81
+ it_behaves_like 'the dictionary_metadata is invalid'
82
+ end
83
+ end
84
+ end
85
+
86
+ #.new
87
+ describe '.new' do
88
+ context 'when the arguments are valid' do
89
+ it 'instantiates without errors' do
90
+ expect { subject }.to_not raise_error
91
+ end
92
+ end
93
+
94
+ it_behaves_like 'the dictionary_key is invalid'
95
+ it_behaves_like 'the dictionary_cache is invalid'
96
+ it_behaves_like 'the dictionary_metadata is invalid'
97
+ end
98
+
99
+ #init
100
+ describe '#init' do
101
+ let(:expected_dictionary_metadata) do
102
+ {
103
+ 0 => { :metadata_key=>nil },
104
+ 1 => { metadata_key1: :metadata_object1 }
105
+ }
106
+ end
107
+
108
+ context 'when the dictionary_id is valid' do
109
+ before do
110
+ allow(subject).to receive(:dictionary_id!).and_return(0)
111
+ end
112
+
113
+ it 'initializes the metadata associated with the dictionary id for the given metadata_key' do
114
+ expect(subject.get_dictionary_metadata(metadata_key: metadata_key)).to eq dictionary_metadata.dig(0, metadata_key)
115
+ subject.init(metadata_key: metadata_key)
116
+ expect(subject.get_dictionary_metadata(metadata_key: metadata_key)).to be_nil
117
+ expect(dictionary_metadata).to eq expected_dictionary_metadata
118
+ end
119
+
120
+ it_behaves_like 'the dictionary_metadata object reference has not changed' do
121
+ let(:expected_dictionary_metadata) { dictionary_metadata }
122
+ let(:actual_dictionary_metadata) { subject.dictionary_metadata }
123
+ end
124
+
125
+ it_behaves_like 'the dictionary_cache object reference has not changed' do
126
+ let(:expected_dictionary_cache) { dictionary_cache }
127
+ let(:actual_dictionary_cache) { subject.dictionary_cache_service.dictionary_cache }
128
+ end
129
+ end
130
+
131
+ context 'when the dictionary_id is INVALID' do
132
+ it 'raises an error' do
133
+ expect { subject.init(metadata_key: metadata_key) }.to raise_error "A dictionary id could not be found for key '#{key}'."
134
+ end
135
+ end
136
+ end
137
+
138
+ #dictionary_metadata?
139
+ describe '#dictionary_metadata?' do
140
+ before do
141
+ allow(subject).to receive(:dictionary_id).and_return(0)
142
+ end
143
+
144
+ context 'when there is dictionary metadata associated with the dictionary for the metadata_key' do
145
+ it 'returns true' do
146
+ expect(subject.dictionary_metadata?(metadata_key: metadata_key)).to eq true
147
+ end
148
+ end
149
+
150
+ context 'when there is NO dictionary metadata associated with the dictionary for the metadata_key' do
151
+ context 'when there is no dictionary metadata for the dictionary_id' do
152
+ let(:dictionary_metadata) do
153
+ {
154
+ 99 => { metadata_key => :metadata_object }
155
+ }
156
+ end
157
+
158
+ it 'returns false' do
159
+ expect(subject.dictionary_metadata?(metadata_key: metadata_key)).to eq false
160
+ end
161
+ end
162
+
163
+ context 'when there is no dictionary metadata for the metadata_key' do
164
+ let(:dictionary_metadata) do
165
+ {
166
+ 0 => { :wrong_metadata_key => :metadata_object }
167
+ }
168
+ end
169
+
170
+ it 'returns false' do
171
+ expect(subject.dictionary_metadata?(metadata_key: metadata_key)).to eq false
172
+ end
173
+ end
174
+
175
+ context 'when the dictionary metadata for the metadata_key is not present' do
176
+ let(:dictionary_metadata) do
177
+ {
178
+ 0 => { metadata_key => nil }
179
+ }
180
+ end
181
+
182
+ it 'returns false' do
183
+ expect(subject.dictionary_metadata?(metadata_key: metadata_key)).to eq false
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ #get_dictionary_metadata
190
+ describe '#get_dictionary_metadata' do
191
+ before do
192
+ allow(subject).to receive(:dictionary_id!).and_return(0)
193
+ end
194
+
195
+ context 'when there is no dictionary_id found in the dictionary metadata associated with the dictionary key' do
196
+ before do
197
+ allow(subject).to receive(:dictionary_id!).and_call_original
198
+ end
199
+
200
+ it 'raises an error' do
201
+ expect { subject.get_dictionary_metadata(metadata_key: metadata_key) }.to raise_error "A dictionary id could not be found for key '#{key}'."
202
+ end
203
+ end
204
+
205
+ context 'when there is dictionary metadata associated with the dictionary for the metadata_key' do
206
+ it 'returns true' do
207
+ expect(subject.get_dictionary_metadata(metadata_key: metadata_key)).to eq :metadata_object0
208
+ end
209
+ end
210
+
211
+ context 'when there is NO dictionary metadata associated with the dictionary for the metadata_key' do
212
+ context 'when there is no dictionary metadata for the dictionary_id' do
213
+ let(:dictionary_metadata) do
214
+ {
215
+ 99 => { metadata_key => :metadata_object0 }
216
+ }
217
+ end
218
+
219
+ it 'returns false' do
220
+ expect(subject.get_dictionary_metadata(metadata_key: metadata_key)).to eq nil
221
+ end
222
+ end
223
+
224
+ context 'when there is no dictionary metadata for the metadata_key' do
225
+ let(:dictionary_metadata) do
226
+ {
227
+ 0 => { :wrong_metadata_key => :metadata_object0 }
228
+ }
229
+ end
230
+
231
+ it 'returns false' do
232
+ expect(subject.get_dictionary_metadata(metadata_key: metadata_key)).to eq nil
233
+ end
234
+ end
235
+
236
+ context 'when the dictionary metadata for the metadata_key is not present' do
237
+ let(:dictionary_metadata) do
238
+ {
239
+ 0 => { metadata_key => nil }
240
+ }
241
+ end
242
+
243
+ it 'returns false' do
244
+ expect(subject.get_dictionary_metadata(metadata_key: metadata_key)).to eq nil
245
+ end
246
+ end
247
+ end
248
+ end
249
+
250
+ #set_dictionary_metadata
251
+ describe '#set_dictionary_metadata' do
252
+ before do
253
+ allow(subject).to receive(:dictionary_id!).and_return(0)
254
+ end
255
+
256
+ let(:new_metadata_object) { :new_metadata_object0 }
257
+
258
+ context 'when passing valid arguments' do
259
+ it 'returns self' do
260
+ expect(subject.set_dictionary_metadata(value: new_metadata_object, metadata_key: metadata_key)).to be subject
261
+ end
262
+
263
+ it 'sets the dictionary metadata value' do
264
+ subject.set_dictionary_metadata(value: new_metadata_object, metadata_key: metadata_key)
265
+ expect(subject.get_dictionary_metadata(metadata_key: metadata_key)).to eq new_metadata_object
266
+ end
267
+ end
268
+
269
+ context 'when there is no dictionary_id found in the dictionary metadata associated with the dictionary key' do
270
+ before do
271
+ allow(subject).to receive(:dictionary_id!).and_call_original
272
+ end
273
+
274
+ it 'raises an error' do
275
+ expect { subject.get_dictionary_metadata(metadata_key: metadata_key) }.to raise_error "A dictionary id could not be found for key '#{key}'."
276
+ end
277
+ end
278
+ end
279
+ end
@@ -0,0 +1,275 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LittleWeasel::WordResults do
6
+ subject do
7
+ create(:word_results,
8
+ original_word: original_word,
9
+ filters_matched: filters_matched,
10
+ preprocessed_words: preprocessed_words,
11
+ word_cached: word_cached,
12
+ word_valid: word_valid)
13
+ end
14
+
15
+ let(:original_word) { 'original-word' }
16
+ let(:word) { original_word }
17
+ let(:filters_matched) { [] }
18
+ let(:preprocessed_words) {}
19
+ let(:word_cached) { false }
20
+ let(:word_valid) { false }
21
+
22
+ #.new
23
+ describe '.new' do
24
+ context 'with valid arguments' do
25
+ it 'instantiates the object' do
26
+ expect { subject }.to_not raise_error
27
+ end
28
+ end
29
+
30
+ context 'with INVALID arguments' do
31
+ context 'when argument original_word is invalid' do
32
+ let(:original_word) {}
33
+
34
+ it 'raises an error' do
35
+ expect { subject }.to raise_error(/Argument original_word is not a String/)
36
+ end
37
+ end
38
+
39
+ context 'when argument filters_matched is invalid' do
40
+ let(:filters_matched) {}
41
+
42
+ it 'raises an error' do
43
+ expect { subject }.to raise_error(/Argument filters_matched is not an Array/)
44
+ end
45
+ end
46
+
47
+ context 'when argument preprocessed_words is invalid' do
48
+ let(:preprocessed_words) { :invalid }
49
+
50
+ it 'raises an error' do
51
+ expect { subject }.to raise_error(/Argument preprocessed_words does not respond to/)
52
+ end
53
+ end
54
+
55
+ context 'when argument word_cached is invalid' do
56
+ let(:word_cached) {}
57
+
58
+ it 'raises an error' do
59
+ expect { subject }.to raise_error(/Argument word_cached is not true or false/)
60
+ end
61
+ end
62
+
63
+ context 'when argument word_valid is invalid' do
64
+ let(:word_valid) {}
65
+
66
+ it 'raises an error' do
67
+ expect { subject }.to raise_error(/Argument word_valid is not true or false/)
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ #original_word=
74
+ describe '#original_word=' do
75
+ let(:changed_value) { "#{original_word}-changed" }
76
+
77
+ it 'sets @original_word' do
78
+ expect(subject.original_word).to eq original_word
79
+ subject.original_word = changed_value
80
+ expect(subject.original_word).to eq changed_value
81
+ end
82
+ end
83
+
84
+ #filters_matched=
85
+ describe '#filters_matched=' do
86
+ let(:filters_matched) { [:filters_matched] }
87
+ let(:changed_value) { [:filters_matched_changed] }
88
+
89
+ it 'sets @filters_matched' do
90
+ expect(subject.filters_matched).to eq filters_matched
91
+ subject.filters_matched = changed_value
92
+ expect(subject.filters_matched).to eq changed_value
93
+ end
94
+ end
95
+
96
+ #word_cached=
97
+ describe '#word_cached=' do
98
+ let(:changed_value) { !word_cached }
99
+
100
+ it 'sets @word_cached' do
101
+ expect(subject.word_cached).to eq word_cached
102
+ subject.word_cached = changed_value
103
+ expect(subject.word_cached).to eq changed_value
104
+ end
105
+ end
106
+
107
+ #word_valid=
108
+ describe '#word_valid=' do
109
+ let(:changed_value) { !word_valid }
110
+
111
+ it 'sets @word_valid' do
112
+ expect(subject.word_valid).to eq word_valid
113
+ subject.word_valid = changed_value
114
+ expect(subject.word_valid).to eq changed_value
115
+ end
116
+ end
117
+
118
+ #preprocesed_words=
119
+ describe '#preprocesed_words=' do
120
+ let(:changed_value) do
121
+ create(:preprocessed_words, with_word_processors: 2, original_word: original_word)
122
+ end
123
+
124
+ it 'sets @preprocesed_words' do
125
+ expect { subject.preprocessed_words = changed_value }.to \
126
+ change { subject.preprocessed_words }
127
+ .from(preprocessed_words)
128
+ .to(changed_value)
129
+ end
130
+ end
131
+
132
+ #success?
133
+ describe '#success?' do
134
+ context 'when #filter_match? is false AND #word_valid? is false' do
135
+ before do
136
+ allow(subject).to receive(:filter_match?).and_return false
137
+ allow(subject).to receive(:word_valid?).and_return false
138
+ end
139
+
140
+ it 'returns false' do
141
+ expect(subject.success?).to be false
142
+ end
143
+ end
144
+
145
+ context 'when #filter_match? is true OR #word_valid? is true' do
146
+ context 'when #filter_match? is true' do
147
+ before do
148
+ allow(subject).to receive(:filter_match?).and_return true
149
+ allow(subject).to receive(:word_valid?).and_return false
150
+ end
151
+
152
+ it 'returns true' do
153
+ expect(subject.success?).to be true
154
+ end
155
+ end
156
+
157
+ context 'when #word_valid? is true' do
158
+ before do
159
+ allow(subject).to receive(:filter_match?).and_return false
160
+ allow(subject).to receive(:word_valid?).and_return true
161
+ end
162
+
163
+ it 'returns true' do
164
+ expect(subject.success?).to be true
165
+ end
166
+ end
167
+ end
168
+ end
169
+
170
+ #filter_match?
171
+ describe '#filter_match?' do
172
+ context '#when filters_matched is present' do
173
+ let(:filters_matched) { [:matched_filter] }
174
+
175
+ it 'returns true' do
176
+ expect(subject.filter_match?).to eq true
177
+ end
178
+ end
179
+
180
+ context '#when filters_matched is NOT present' do
181
+ it 'returns false' do
182
+ expect(subject.filter_match?).to eq false
183
+ end
184
+ end
185
+ end
186
+
187
+ #word_cached?
188
+ describe '#word_cached?' do
189
+ context '#when word_cached is true' do
190
+ let(:word_cached) { true }
191
+
192
+ it 'returns true' do
193
+ expect(subject.word_cached?).to eq true
194
+ end
195
+ end
196
+
197
+ context '#when word_cached is false' do
198
+ it 'returns false' do
199
+ expect(subject.word_cached?).to eq false
200
+ end
201
+ end
202
+ end
203
+
204
+ #word_valid?
205
+ describe '#word_valid?' do
206
+ context '#when word_valid is true' do
207
+ let(:word_valid) { true }
208
+
209
+ it 'returns true' do
210
+ expect(subject.word_valid?).to eq true
211
+ end
212
+ end
213
+
214
+ context '#when word_valid is false' do
215
+ it 'returns false' do
216
+ expect(subject.word_valid?).to eq false
217
+ end
218
+ end
219
+ end
220
+
221
+ #preprocessed_word?
222
+ describe '#preprocessed_word?' do
223
+ subject do
224
+ create(:word_results,
225
+ original_word: original_word,
226
+ filters_matched: [],
227
+ preprocessed_words: preprocessed_words,
228
+ word_cached: false,
229
+ word_valid: false)
230
+ end
231
+
232
+ context 'when #preprocessed_word is NOT nil' do
233
+ let(:preprocessed_words) do
234
+ create(:preprocessed_words, with_word_processors: 2)
235
+ end
236
+
237
+ it 'returns true' do
238
+ expect(subject.preprocessed_word?).to be true
239
+ end
240
+ end
241
+
242
+ context 'when #preprocessed_word is nil' do
243
+ let(:preprocessed_words) do
244
+ create(:preprocessed_words)
245
+ end
246
+
247
+ it 'returns false' do
248
+ expect(subject.preprocessed_word?).to be false
249
+ end
250
+ end
251
+ end
252
+
253
+ #preprocessed_word_or_original_word
254
+ describe '#preprocessed_word_or_original_word' do
255
+ let(:original_word) { 'word' }
256
+
257
+ context 'when the word has been preprocessed' do
258
+ let(:preprocessed_words) do
259
+ create(:preprocessed_words,
260
+ original_word: original_word,
261
+ with_word_processors: 2)
262
+ end
263
+
264
+ it 'returns #preprocesed_word' do
265
+ expect(subject.preprocessed_word_or_original_word).to eq 'word-0-1'
266
+ end
267
+ end
268
+
269
+ context 'when the word has NOT been preprocessed' do
270
+ it 'returns #original_word' do
271
+ expect(subject.preprocessed_word_or_original_word).to eq original_word
272
+ end
273
+ end
274
+ end
275
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe 'Workflow tests' do
6
+ include_context 'dictionary cache'
7
+ include_context 'dictionary keys'
8
+
9
+ subject { LittleWeasel::DictionaryManager.new }
10
+
11
+ # This loads the BIG en-US-big dictionary
12
+ let(:en_us_dictionary_key) { dictionary_key_for(language: :en, region: :us, tag: :big) }
13
+ let(:en_gb_dictionary_key) { dictionary_key_for(language: :en, region: :gb) }
14
+ let(:es_es_dictionary_key) { dictionary_key_for(language: :es, region: :es) }
15
+
16
+ let(:dictionary_key) { en_us_dictionary_key }
17
+ let(:key) { dictionary_key.key }
18
+ let(:file) { dictionary_path_for(file_name: key) }
19
+ let(:dictionary_words) { dictionary_words_for(dictionary_file_path: file) }
20
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,12 +1,123 @@
1
+ require 'pry-byebug'
2
+ require 'simplecov'
3
+
4
+ SimpleCov.start do
5
+ add_filter 'spec'
6
+ end
7
+
1
8
  require File.expand_path(File.dirname(__FILE__) + '../../lib/LittleWeasel')
9
+ Dir[File.join('.', 'spec/support/**/*.rb')].each do |f|
10
+ require f
11
+ end
2
12
 
3
- # Use :should in stead of :expect
13
+ # This file was generated by the `rspec --init` command. Conventionally, all
14
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
15
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
16
+ # this file to always be loaded, without a need to explicitly require it in any
17
+ # files.
18
+ #
19
+ # Given that it is always loaded, you are encouraged to keep this file as
20
+ # light-weight as possible. Requiring heavyweight dependencies from this file
21
+ # will add to the boot time of your test suite on EVERY test run, even for an
22
+ # individual file that may not need all of that loaded. Instead, consider making
23
+ # a separate helper file that requires the additional dependencies and performs
24
+ # the additional setup, and require it from the spec files that actually need
25
+ # it.
26
+ #
27
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
4
28
  RSpec.configure do |config|
5
- config.expect_with :rspec do |c|
6
- c.syntax = :should
29
+ # rspec-expectations config goes here. You can use an alternate
30
+ # assertion/expectation library such as wrong or the stdlib/minitest
31
+ # assertions if you prefer.
32
+ config.expect_with :rspec do |expectations|
33
+ # This option will default to `true` in RSpec 4. It makes the `description`
34
+ # and `failure_message` of custom matchers include text for helper methods
35
+ # defined using `chain`, e.g.:
36
+ # be_bigger_than(2).and_smaller_than(4).description
37
+ # # => "be bigger than 2 and smaller than 4"
38
+ # ...rather than:
39
+ # # => "be bigger than 2"
40
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
7
41
  end
8
- config.mock_with :rspec do |c|
9
- c.syntax = :should
42
+
43
+ # rspec-mocks config goes here. You can use an alternate test double
44
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
45
+ config.mock_with :rspec do |mocks|
46
+ # Prevents you from mocking or stubbing a method that does not exist on
47
+ # a real object. This is generally recommended, and will default to
48
+ # `true` in RSpec 4.
49
+ mocks.verify_partial_doubles = true
10
50
  end
11
- #config.raise_errors_for_deprecations!
51
+
52
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
53
+ # have no way to turn it off -- the option exists only for backwards
54
+ # compatibility in RSpec 3). It causes shared context metadata to be
55
+ # inherited by the metadata hash of host groups and examples, rather than
56
+ # triggering implicit auto-inclusion in groups with matching metadata.
57
+ config.shared_context_metadata_behavior = :apply_to_host_groups
58
+
59
+ # The settings below are suggested to provide a good initial experience
60
+ # with RSpec, but feel free to customize to your heart's content.
61
+ =begin
62
+ # This allows you to limit a spec run to individual examples or groups
63
+ # you care about by tagging them with `:focus` metadata. When nothing
64
+ # is tagged with `:focus`, all examples get run. RSpec also provides
65
+ # aliases for `it`, `describe`, and `context` that include `:focus`
66
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
67
+ config.filter_run_when_matching :focus
68
+
69
+ # Allows RSpec to persist some state between runs in order to support
70
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
71
+ # you configure your source control system to ignore this file.
72
+ config.example_status_persistence_file_path = "spec/examples.txt"
73
+
74
+ # Limits the available syntax to the non-monkey patched syntax that is
75
+ # recommended. For more details, see:
76
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
77
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
78
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
79
+ config.disable_monkey_patching!
80
+
81
+ # This setting enables warnings. It's recommended, but in some cases may
82
+ # be too noisy due to issues in dependencies.
83
+ config.warnings = true
84
+
85
+ # Many RSpec users commonly either run the entire suite or an individual
86
+ # file, and it's useful to allow more verbose output when running an
87
+ # individual spec file.
88
+ if config.files_to_run.one?
89
+ # Use the documentation formatter for detailed output,
90
+ # unless a formatter has already been configured
91
+ # (e.g. via a command-line flag).
92
+ config.default_formatter = "doc"
93
+ end
94
+
95
+ # Print the 10 slowest examples and example groups at the
96
+ # end of the spec run, to help surface which specs are running
97
+ # particularly slow.
98
+ config.profile_examples = 10
99
+
100
+ # Run specs in random order to surface order dependencies. If you find an
101
+ # order dependency and want to debug it, you can fix the order by providing
102
+ # the seed, which is printed after each run.
103
+ # --seed 1234
104
+ config.order = :random
105
+
106
+ # Seed global randomization in this process using the `--seed` CLI option.
107
+ # Setting this allows you to use `--seed` to deterministically reproduce
108
+ # test failures related to randomization by passing the same `--seed` value
109
+ # as the one that triggered the failure.
110
+ Kernel.srand config.seed
111
+ =end
112
+
113
+ # Enable both should and expect until the old specs are upgraded.
114
+ config.expect_with :rspec do |c|
115
+ c.syntax = %i[should, expect]
116
+ end
117
+
118
+ # Load support files
119
+ config.include Support::FileHelpers
120
+ config.include Support::GeneralHelpers
121
+
122
+ config.before(:each) { LittleWeasel.configure { |config| config.reset } }
12
123
  end