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,180 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LittleWeasel::Filters::WordFilterManagable, type: :module do
6
+ include_context 'mock word filters'
7
+
8
+ WordFilterManagable = described_class
9
+
10
+ subject do
11
+ Class.new do
12
+ include WordFilterManagable
13
+ include LittleWeasel::Modules::Configurable
14
+
15
+ def initialize(word_filters)
16
+ self.word_filters = word_filters
17
+ end
18
+ end.new(word_filters)
19
+ end
20
+
21
+ let(:word_filters) { [numeric_filter] }
22
+ let(:numeric_filter) { LittleWeasel::Filters::EnUs::NumericFilter.new }
23
+
24
+ #clear_filters
25
+ describe '#clear_filters' do
26
+ it 'sets #word_filters to an empty Array ([])' do
27
+ expect { subject.clear_filters }.to \
28
+ change { subject.word_filters.count }.from(1).to(0)
29
+ end
30
+ end
31
+
32
+ #add_filters
33
+ describe '#add_filters' do
34
+ context 'when argument word_filters is nil' do
35
+ context 'when no block is passed' do
36
+ it 'raises an error' do
37
+ expect { subject.add_filters }.to raise_error 'A block is required if argument word_filters is nil'
38
+ end
39
+ end
40
+
41
+ context 'when a block is passed' do
42
+ before do
43
+ subject.add_filters do |word_filters|
44
+ word_filters << WordFilter01.new
45
+ word_filters << WordFilter02.new
46
+ end
47
+ end
48
+
49
+ it 'the word filters are appended to the word_filters Array' do
50
+ expect(subject.word_filters.count).to eq 3
51
+ expect(subject.word_filters).to include(a_kind_of(WordFilter01))
52
+ expect(subject.word_filters).to include(a_kind_of(WordFilter02))
53
+ expect(subject.word_filters).to include(a_kind_of(LittleWeasel::Filters::EnUs::NumericFilter))
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'when argument word_filters is a blank Array ([])' do
59
+ it 'nothing is changed' do
60
+ expect { subject.add_filters(word_filters: []) }.to_not change { subject.word_filters.count }.from(subject.word_filters.count)
61
+ end
62
+ end
63
+
64
+ context 'when argument word_filters is not an Array' do
65
+ it 'raises an error' do
66
+ expect { subject.add_filters(word_filters: :not_an_array) }.to raise_error(/Argument word_filters is not an Array:/)
67
+ end
68
+ end
69
+
70
+ context 'when argument word_filters is NOT nil' do
71
+ it 'the word filters passed to the method are appended to the #word_filters Array' do
72
+ expect(subject.add_filters(word_filters: [WordFilter01.new, WordFilter02.new]).count).to eq 3
73
+ expect(subject.word_filters).to include(a_kind_of(WordFilter01))
74
+ expect(subject.word_filters).to include(a_kind_of(WordFilter02))
75
+ expect(subject.word_filters).to include(a_kind_of(LittleWeasel::Filters::EnUs::NumericFilter))
76
+ end
77
+ end
78
+
79
+ context 'when a block is passed' do
80
+ before do
81
+ subject.add_filters do |word_filters|
82
+ word_filters << WordFilter01.new
83
+ word_filters << WordFilter02.new
84
+ end
85
+ end
86
+
87
+ it 'word filters added from the block are appended to the #word_filters Array' do
88
+ expect(subject.word_filters.count).to eq 3
89
+ expect(subject.word_filters).to include(a_kind_of(WordFilter01))
90
+ expect(subject.word_filters).to include(a_kind_of(WordFilter02))
91
+ expect(subject.word_filters).to include(a_kind_of(LittleWeasel::Filters::EnUs::NumericFilter))
92
+ end
93
+ end
94
+ end
95
+
96
+ #replace_filters
97
+ describe '#replace_filters' do
98
+ it 'replaces any existing word filters' do
99
+ expect(subject.word_filters.count).to eq 1
100
+ expect(subject.word_filters).to include(a_kind_of(LittleWeasel::Filters::EnUs::NumericFilter))
101
+ expect(subject.replace_filters(word_filters: [WordFilter01.new, WordFilter02.new]).count).to eq 2
102
+ expect(subject.word_filters).to include(a_kind_of(WordFilter01))
103
+ expect(subject.word_filters).to include(a_kind_of(WordFilter02))
104
+ end
105
+ end
106
+
107
+ #filters_on=
108
+ describe '#filters_on=' do
109
+ context 'when a boolean is not passed' do
110
+ it 'raises an error' do
111
+ expect { subject.filters_on = :not_a_boolean }.to raise_error(/Argument on is not true or false:/)
112
+ end
113
+ end
114
+
115
+ context 'when true is assigned' do
116
+ it 'turns all the filters on' do
117
+ expect(subject.word_filters.count).to_not be_zero
118
+ expect(subject.word_filters.all? { |word_filter| word_filter.filter_on? })
119
+ subject.filters_on = true
120
+ expect(subject.word_filters.all? { |word_filter| word_filter.filter_off? })
121
+ end
122
+ end
123
+
124
+ context 'when false is assigned' do
125
+ before do
126
+ subject.filters_on = false
127
+ end
128
+
129
+ it 'turns all the filters off' do
130
+ expect(subject.word_filters.count).to_not be_zero
131
+ expect(subject.word_filters.all? { |word_filter| word_filter.filter_off? })
132
+ subject.filters_on = false
133
+ expect(subject.word_filters.all? { |word_filter| word_filter.filter_on? })
134
+ end
135
+ end
136
+ end
137
+
138
+ #filter_match?
139
+ describe '#filter_match?' do
140
+ context 'when argument word is not a String' do
141
+ let(:word) { :not_a_string }
142
+
143
+ it 'raises an error' do
144
+ expect { subject.filter_match? word }.to raise_error "Argument word is not a String: #{word.class}"
145
+ end
146
+ end
147
+
148
+ context 'when argument word is empty' do
149
+ let(:word) { '' }
150
+
151
+ it 'returns false' do
152
+ expect(subject.filter_match? word).to eq false
153
+ end
154
+ end
155
+
156
+ context 'when argument word matches a filter' do
157
+ before do
158
+ subject.filters_on = true
159
+ end
160
+
161
+ let(:word) { '123456789' }
162
+
163
+ it 'returns true' do
164
+ expect(subject.filter_match? word).to eq true
165
+ end
166
+ end
167
+
168
+ context 'when argument word DOES NOT match a filter' do
169
+ before do
170
+ subject.filters_on = false
171
+ end
172
+
173
+ let(:word) { '123456789' }
174
+
175
+ it 'returns false' do
176
+ expect(subject.filter_match? word).to eq false
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LittleWeasel::Filters::WordFilter do
6
+ subject { described_class.new }
7
+
8
+ #.new
9
+ describe '.new' do
10
+ it 'instantiates the object' do
11
+ expect { subject }.to_not raise_error
12
+ end
13
+
14
+ it 'sets #filter_on to true by default' do
15
+ expect(subject.filter_on).to eq true
16
+ end
17
+ end
18
+
19
+ #filter_off!
20
+ describe '#filter_off!' do
21
+ before do
22
+ subject.filter_off!
23
+ end
24
+
25
+ it 'sets the filter off' do
26
+ expect(subject.filter_off?).to eq true
27
+ end
28
+ end
29
+
30
+ #filter_on
31
+ describe '#filter_on' do
32
+ context 'when set to true' do
33
+ before do
34
+ subject.filter_on = true
35
+ end
36
+
37
+ it 'returns true' do
38
+ expect(subject.filter_on).to eq true
39
+ end
40
+ end
41
+
42
+ context 'when set to false' do
43
+ before do
44
+ subject.filter_on = false
45
+ end
46
+
47
+ it 'returns false' do
48
+ expect(subject.filter_on).to eq false
49
+ end
50
+ end
51
+ end
52
+
53
+ #filter_on=
54
+ describe '#filter_on=' do
55
+ context 'when argument value is valid' do
56
+ context 'when true' do
57
+ before do
58
+ subject.filter_on = false
59
+ expect(subject.filter_off?).to eq true
60
+ end
61
+
62
+ it 'sets #filter_on to true' do
63
+ subject.filter_on = true
64
+ expect(subject.filter_on).to eq true
65
+ end
66
+ end
67
+
68
+ context 'when false' do
69
+ before do
70
+ subject.filter_on = true
71
+ expect(subject.filter_on?).to eq true
72
+ end
73
+
74
+ it 'sets #filter_on to false' do
75
+ subject.filter_on = false
76
+ expect(subject.filter_on).to eq false
77
+ end
78
+ end
79
+ end
80
+
81
+ context 'when argument value is INVALID' do
82
+ context 'when argument value is not true or false' do
83
+ let(:filter_on) { :not_true_or_false }
84
+
85
+ it 'raises an error' do
86
+ expect { subject.filter_on = filter_on }.to raise_error(/Argument value is not true or false/)
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ #filter_on?
93
+ describe '#filter_on?' do
94
+ context 'when #filter_on is true' do
95
+ it 'returns true' do
96
+ subject.filter_on = true
97
+ expect(subject.filter_on?).to eq true
98
+ end
99
+ end
100
+
101
+ context 'when #filter_on is false' do
102
+ it 'returns false' do
103
+ subject.filter_on = false
104
+ expect(subject.filter_on?).to eq false
105
+ end
106
+ end
107
+ end
108
+
109
+ #filter_match?
110
+ describe '#filter_match?' do
111
+ let(:word) { 'word' }
112
+
113
+ context 'when not overridden' do
114
+ it 'raises an error' do
115
+ expect { subject.filter_match? 'boom' }.to raise_error LittleWeasel::Errors::MustOverrideError
116
+ end
117
+ end
118
+
119
+ context 'when #filter_match? returns true' do
120
+ before { allow(subject.class).to receive(:filter_match?).and_return(true) }
121
+
122
+ context 'when #filter_on? is true' do
123
+ it_behaves_like 'the filter matches and #filter_on? is true'
124
+ end
125
+
126
+ context 'when #filter_on? is false' do
127
+ before do
128
+ subject.filter_on = false
129
+ end
130
+
131
+ it_behaves_like 'the filter matches and #filter_on? is false'
132
+ end
133
+ end
134
+
135
+ context 'when #filter_match? returns false' do
136
+ before { allow(subject.class).to receive(:filter_match?).and_return(false) }
137
+
138
+ context 'when #filter_on? is true' do
139
+ it_behaves_like 'the filter DOES NOT match and #filter_on? is true'
140
+ end
141
+
142
+ context 'when #filter_on? is false' do
143
+ before do
144
+ subject.filter_on = false
145
+ end
146
+
147
+ it_behaves_like 'the filter DOES NOT match and #filter_on? is false'
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LittleWeasel::Filters::WordFilterValidatable, type: :module do
6
+ WordFilterValidatable = described_class
7
+
8
+ class Subject
9
+ include WordFilterValidatable
10
+ end
11
+
12
+ subject { Subject.new }
13
+
14
+ let(:filter_class) do
15
+ filter = Class.new do
16
+ def filter_on?; end
17
+ def filter_off?; end
18
+ def filter_on; end
19
+ def filter_on=; end
20
+ def filter_match?; end
21
+ def self.filter_match?; end
22
+ end
23
+ filter
24
+ end
25
+
26
+ let(:numeric_filter) do
27
+ filter_class.new
28
+ end
29
+ let(:expected_error_message) { "Argument word_filter does not quack right: #{numeric_filter.class}" }
30
+
31
+ #validate_word_filter
32
+ describe '#validate_word_filter' do
33
+ context 'when argument word_filter quacks correctly' do
34
+ it 'does not raise an error' do
35
+ expect { subject.validate_word_filter(word_filter: numeric_filter) }.to_not raise_error
36
+ end
37
+ end
38
+
39
+ context 'when argument word_filter DOES NOT quack correctly to the right instance methods' do
40
+ context 'when word_filter does not respond to #filter_on?' do
41
+ before { numeric_filter.instance_eval("undef #{method_to_check}") }
42
+ let(:method_to_check) { :filter_on? }
43
+
44
+ it 'raises an error' do
45
+ expect { subject.validate_word_filter(word_filter: numeric_filter) }.to raise_error \
46
+ expected_error_message
47
+ end
48
+ end
49
+
50
+ context 'when word_filter does not respond to #filter_on' do
51
+ before { numeric_filter.instance_eval("undef #{method_to_check}") }
52
+ let(:method_to_check) { :filter_on }
53
+
54
+ it 'raises an error' do
55
+ expect { subject.validate_word_filter(word_filter: numeric_filter) }.to raise_error \
56
+ expected_error_message
57
+ end
58
+ end
59
+
60
+ context 'when word_filter does not respond to #filter_on=' do
61
+ before { numeric_filter.instance_eval("undef #{method_to_check}") }
62
+ let(:method_to_check) { :filter_on= }
63
+
64
+ it 'raises an error' do
65
+ expect { subject.validate_word_filter(word_filter: numeric_filter) }.to raise_error \
66
+ expected_error_message
67
+ end
68
+ end
69
+
70
+ context 'when word_filter does not respond to #filter_match?' do
71
+ before { numeric_filter.instance_eval("undef #{method_to_check}") }
72
+ let(:method_to_check) { :filter_match? }
73
+
74
+ it 'raises an error' do
75
+ expect { subject.validate_word_filter(word_filter: numeric_filter) }.to raise_error \
76
+ expected_error_message
77
+ end
78
+ end
79
+ end
80
+
81
+ context 'when argument word_filter DOES NOT quack correctly to the right class methods' do
82
+ before { allow(filter_class).to receive(:respond_to?).with(method_to_check).and_return(false) }
83
+
84
+ context 'when word_filter class does not respond to #filter_match?' do
85
+ let(:method_to_check) { :filter_match? }
86
+
87
+ it 'raises an error' do
88
+ expect { subject.validate_word_filter(word_filter: numeric_filter) }.to raise_error \
89
+ expected_error_message
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LittleWeasel::Filters::WordFiltersValidatable, type: :module do
6
+ include_context 'mock word filters'
7
+
8
+ WordFiltersValidatable = described_class
9
+
10
+ class Subject
11
+ include WordFiltersValidatable
12
+ end
13
+
14
+ subject { Subject.new }
15
+
16
+ let(:word_filters) do
17
+ [
18
+ WordFilter01.new,
19
+ WordFilter02.new
20
+ ]
21
+ end
22
+ let(:expected_error_message) { "Argument word_filter does not quack right: #{numeric_filter.class}" }
23
+
24
+ #validate_word_filters
25
+ describe '#validate_word_filters' do
26
+ context 'when argument word_filters is not an Array' do
27
+ let(:word_filters) { :not_an_array}
28
+
29
+ it 'raises an error' do
30
+ expect { subject.validate_word_filters(word_filters: word_filters) }.to raise_error "Argument word_filters is not an Array: #{word_filters.class}"
31
+ end
32
+ end
33
+
34
+ context 'when argument word_filters contains valid word filters' do
35
+ it 'does not raise an error' do
36
+ expect { subject.validate_word_filters(word_filters: word_filters) }.to_not raise_error
37
+ end
38
+ end
39
+
40
+ context 'when argument word_filters contains INVALID word filters' do
41
+ let(:word_filters) { [Object.new] }
42
+
43
+ it 'does not raise an error' do
44
+ expect { subject.validate_word_filters(word_filters: word_filters) }.to raise_error "Argument word_filter does not quack right: #{word_filters[0].class}"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,201 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe 'Dictionary integration', type: :integration do
6
+ include_context 'dictionary keys'
7
+ include_context 'mock word preprocessors'
8
+
9
+ subject { create(:dictionary_manager) }
10
+
11
+ before(:each) { LittleWeasel.configure { |config| config.reset } }
12
+
13
+ let(:dictionary) do
14
+ subject.create_dictionary_from_file(dictionary_key: dictionary_key, file: dictionary_file_path,
15
+ word_filters: word_filters, word_preprocessors: word_preprocessors)
16
+ end
17
+ let(:dictionary_key) { dictionary_key_for(language: :en, region: :us) }
18
+ let(:dictionary_cache) { subject.dictionary_cache }
19
+ let(:dictionary_metadata) { subject.dictionary_metadata }
20
+ let(:dictionary_file_path) { dictionary_path_for(file_name: dictionary_key.key) }
21
+ let(:dictionary_words) { dictionary_words_for(dictionary_file_path: dictionary_file_path) }
22
+ let(:word_filters) {}
23
+ let(:word_preprocessors) {}
24
+
25
+ #word_results
26
+ describe '#word_results' do
27
+ describe 'when using word filters' do
28
+ let(:word_filters) { [LittleWeasel::Filters::EnUs::NumericFilter.new] }
29
+ let(:number) { 1_000.to_s }
30
+
31
+ context 'with word filters turned on' do
32
+ let(:word_results) { dictionary.word_results(number) }
33
+
34
+ it '#success? returns true' do
35
+ expect(word_results.success?).to eq true
36
+ end
37
+
38
+ it '#filter_match? returns true' do
39
+ expect(word_results.filter_match?).to eq true
40
+ end
41
+
42
+ it '#filters_matched returns the filter(s) that were matched' do
43
+ expect(word_results.filters_matched).to eq [:numeric_filter]
44
+ end
45
+
46
+ it '#word_valid? returns false' do
47
+ expect(word_results.word_valid?).to eq false
48
+ end
49
+
50
+ it '#original_word returns the original word' do
51
+ expect(word_results.preprocessed_word_or_original_word).to eq number
52
+ end
53
+
54
+ it '#preprocessed_word return nil because no word preprocessors were applied' do
55
+ expect(word_results.preprocessed_word).to be_nil
56
+ end
57
+
58
+ it '#preprocessed_word_or_original_word returns the original word' do
59
+ expect(word_results.preprocessed_word_or_original_word).to eq number
60
+ end
61
+
62
+ it '#word_cached? returns false if the word is not in the dictionary' do
63
+ expect(word_results.word_cached?).to eq false
64
+ end
65
+
66
+ it '#word_cached? returns true 2nd-nth time the word was searched if invalid words are being cached by any metadata processing' do
67
+ dictionary.word_results(number)
68
+ expect(word_results.word_cached?).to eq true
69
+ end
70
+ end
71
+
72
+ context 'with filters turned off' do
73
+ before do
74
+ dictionary.filters_on = false
75
+ end
76
+
77
+ let(:word_results) { dictionary.word_results(number) }
78
+
79
+ it '#success? returns false' do
80
+ expect(word_results.success?).to eq false
81
+ end
82
+
83
+ it '#filter_match? returns false' do
84
+ expect(word_results.filter_match?).to eq false
85
+ end
86
+
87
+ it '#filters_matched returns an empty Array' do
88
+ expect(word_results.filters_matched).to eq []
89
+ end
90
+
91
+ it '#word_valid? returns false' do
92
+ expect(word_results.word_valid?).to eq false
93
+ end
94
+
95
+ it '#original_word returns the original word' do
96
+ expect(word_results.original_word).to eq number
97
+ end
98
+
99
+ it '#preprocessed_word return nil because no word preprocessors were applied' do
100
+ expect(word_results.preprocessed_word).to be_nil
101
+ end
102
+
103
+ it '#preprocessed_word_or_original_word returns the original word' do
104
+ expect(word_results.preprocessed_word_or_original_word).to eq number
105
+ end
106
+
107
+ it '#word_cached? returns false if the word is not in the dictionary' do
108
+ expect(word_results.word_cached?).to eq false
109
+ end
110
+
111
+ it '#word_cached? returns true 2nd-nth time the word was searched if invalid words are being cached by any metadata processing' do
112
+ dictionary.word_results(number)
113
+ expect(word_results.word_cached?).to eq true
114
+ end
115
+ end
116
+ end
117
+
118
+ describe 'when using word preprocessors' do
119
+ let(:word_preprocessors) { [DowncaseWordPreprocessor.new(order: 0)] }
120
+ let(:word) { 'ApPlE' }
121
+ let(:word_results) { dictionary.word_results(word) }
122
+
123
+ context 'with preprocessors turned on' do
124
+ it '#success? returns true' do
125
+ expect(word_results.success?).to eq true
126
+ end
127
+
128
+ it '#filter_match? returns false' do
129
+ expect(word_results.filter_match?).to eq false
130
+ end
131
+
132
+ it '#filters_matched returns the filter(s) that were matched' do
133
+ expect(word_results.filters_matched).to eq []
134
+ end
135
+
136
+ it '#word_valid? returns true' do
137
+ expect(word_results.word_valid?).to eq true
138
+ end
139
+
140
+ it '#original_word returns the original word' do
141
+ expect(word_results.original_word).to eq word
142
+ end
143
+
144
+ it '#preprocessed_word returns the preprocessed word' do
145
+ expect(word_results.preprocessed_word).to eq word.downcase
146
+ end
147
+
148
+ it '#preprocessed_word_or_original_word returns the preprocessed word' do
149
+ expect(word_results.preprocessed_word_or_original_word).to eq word.downcase
150
+ end
151
+
152
+ it '#word_cached? returns true if the word is in the dictionary' do
153
+ expect(word_results.word_cached?).to eq true
154
+ end
155
+ end
156
+
157
+ context 'with preprocessors turned off' do
158
+ before do
159
+ dictionary.preprocessors_on = false
160
+ end
161
+
162
+ it '#success? returns false' do
163
+ expect(word_results.success?).to eq false
164
+ end
165
+
166
+ it '#filter_match? returns false' do
167
+ expect(word_results.filter_match?).to eq false
168
+ end
169
+
170
+ it '#filters_matched returns the filter(s) that were matched' do
171
+ expect(word_results.filters_matched).to eq []
172
+ end
173
+
174
+ it '#word_valid? returns false' do
175
+ expect(word_results.word_valid?).to eq false
176
+ end
177
+
178
+ it '#original_word returns the original word' do
179
+ expect(word_results.original_word).to eq word
180
+ end
181
+
182
+ it '#preprocessed_word returns nil' do
183
+ expect(word_results.preprocessed_word).to be_nil
184
+ end
185
+
186
+ it '#preprocessed_word_or_original_word returns the original word' do
187
+ expect(word_results.preprocessed_word_or_original_word).to eq word
188
+ end
189
+
190
+ it '#word_cached? returns false if the word is not in the dictionary' do
191
+ expect(word_results.word_cached?).to eq false
192
+ end
193
+
194
+ it '#word_cached? returns true 2nd-nth time the word was searched if invalid words are being cached by any metadata processing' do
195
+ dictionary.word_results(word)
196
+ expect(word_results.word_cached?).to eq true
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end