LittleWeasel 3.0.4 → 4.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.
- checksums.yaml +5 -5
- data/.gitignore +3 -0
- data/.reek.yml +17 -0
- data/.rspec +4 -2
- data/.rubocop.yml +187 -0
- data/.ruby-version +1 -1
- data/.yardopts +2 -0
- data/Gemfile +3 -1
- data/LittleWeasel.gemspec +31 -18
- data/README.md +408 -42
- data/Rakefile +296 -3
- data/lib/LittleWeasel.rb +5 -184
- data/lib/LittleWeasel/block_results.rb +81 -0
- data/lib/LittleWeasel/configure.rb +98 -0
- data/lib/LittleWeasel/dictionary.rb +125 -0
- data/lib/LittleWeasel/dictionary_key.rb +48 -0
- data/lib/LittleWeasel/dictionary_manager.rb +85 -0
- data/lib/LittleWeasel/errors/dictionary_file_already_loaded_error.rb +9 -0
- data/lib/LittleWeasel/errors/dictionary_file_empty_error.rb +8 -0
- data/lib/LittleWeasel/errors/dictionary_file_not_found_error.rb +8 -0
- data/lib/LittleWeasel/errors/dictionary_file_too_large_error.rb +16 -0
- data/lib/LittleWeasel/errors/language_required_error.rb +8 -0
- data/lib/LittleWeasel/errors/must_override_error.rb +8 -0
- data/lib/LittleWeasel/filters/en_us/currency_filter.rb +19 -0
- data/lib/LittleWeasel/filters/en_us/numeric_filter.rb +19 -0
- data/lib/LittleWeasel/filters/en_us/single_character_word_filter.rb +21 -0
- data/lib/LittleWeasel/filters/word_filter.rb +59 -0
- data/lib/LittleWeasel/filters/word_filter_managable.rb +80 -0
- data/lib/LittleWeasel/filters/word_filter_validatable.rb +31 -0
- data/lib/LittleWeasel/filters/word_filterable.rb +19 -0
- data/lib/LittleWeasel/filters/word_filters_validatable.rb +29 -0
- data/lib/LittleWeasel/metadata/dictionary_metadata.rb +145 -0
- data/lib/LittleWeasel/metadata/invalid_words_metadata.rb +134 -0
- data/lib/LittleWeasel/metadata/invalid_words_service_results.rb +45 -0
- data/lib/LittleWeasel/metadata/metadata_observable_validatable.rb +22 -0
- data/lib/LittleWeasel/metadata/metadata_observerable.rb +90 -0
- data/lib/LittleWeasel/metadata/metadatable.rb +136 -0
- data/lib/LittleWeasel/modules/class_name_to_symbol.rb +26 -0
- data/lib/LittleWeasel/modules/configurable.rb +26 -0
- data/lib/LittleWeasel/modules/deep_dup.rb +11 -0
- data/lib/LittleWeasel/modules/dictionary_cache_keys.rb +34 -0
- data/lib/LittleWeasel/modules/dictionary_cache_servicable.rb +26 -0
- data/lib/LittleWeasel/modules/dictionary_cache_validatable.rb +20 -0
- data/lib/LittleWeasel/modules/dictionary_creator_servicable.rb +27 -0
- data/lib/LittleWeasel/modules/dictionary_file_loader.rb +67 -0
- data/lib/LittleWeasel/modules/dictionary_key_validatable.rb +19 -0
- data/lib/LittleWeasel/modules/dictionary_keyable.rb +24 -0
- data/lib/LittleWeasel/modules/dictionary_loader_servicable.rb +27 -0
- data/lib/LittleWeasel/modules/dictionary_metadata_servicable.rb +29 -0
- data/lib/LittleWeasel/modules/dictionary_metadata_validatable.rb +17 -0
- data/lib/LittleWeasel/modules/dictionary_sourceable.rb +26 -0
- data/lib/LittleWeasel/modules/dictionary_validatable.rb +30 -0
- data/lib/LittleWeasel/modules/language.rb +23 -0
- data/lib/LittleWeasel/modules/language_validatable.rb +16 -0
- data/lib/LittleWeasel/modules/locale.rb +40 -0
- data/lib/LittleWeasel/modules/order_validatable.rb +18 -0
- data/lib/LittleWeasel/modules/orderable.rb +17 -0
- data/lib/LittleWeasel/modules/region.rb +23 -0
- data/lib/LittleWeasel/modules/region_validatable.rb +16 -0
- data/lib/LittleWeasel/modules/tag_validatable.rb +16 -0
- data/lib/LittleWeasel/modules/taggable.rb +31 -0
- data/lib/LittleWeasel/modules/word_results_validatable.rb +28 -0
- data/lib/LittleWeasel/preprocessors/en_us/capitalize_preprocessor.rb +22 -0
- data/lib/LittleWeasel/preprocessors/preprocessed_word.rb +28 -0
- data/lib/LittleWeasel/preprocessors/preprocessed_word_validatable.rb +55 -0
- data/lib/LittleWeasel/preprocessors/preprocessed_words.rb +55 -0
- data/lib/LittleWeasel/preprocessors/preprocessed_words_validatable.rb +27 -0
- data/lib/LittleWeasel/preprocessors/word_preprocessable.rb +19 -0
- data/lib/LittleWeasel/preprocessors/word_preprocessor.rb +122 -0
- data/lib/LittleWeasel/preprocessors/word_preprocessor_managable.rb +114 -0
- data/lib/LittleWeasel/preprocessors/word_preprocessor_validatable.rb +40 -0
- data/lib/LittleWeasel/preprocessors/word_preprocessors_validatable.rb +24 -0
- data/lib/LittleWeasel/services/dictionary_cache_service.rb +262 -0
- data/lib/LittleWeasel/services/dictionary_creator_service.rb +94 -0
- data/lib/LittleWeasel/services/dictionary_file_loader_service.rb +37 -0
- data/lib/LittleWeasel/services/dictionary_killer_service.rb +35 -0
- data/lib/LittleWeasel/services/dictionary_loader_service.rb +59 -0
- data/lib/LittleWeasel/services/dictionary_metadata_service.rb +114 -0
- data/lib/LittleWeasel/services/invalid_words_service.rb +59 -0
- data/lib/LittleWeasel/version.rb +3 -1
- data/lib/LittleWeasel/word_results.rb +146 -0
- data/spec/factories/dictionary.rb +43 -0
- data/spec/factories/dictionary_cache_service.rb +95 -0
- data/spec/factories/dictionary_creator_service.rb +16 -0
- data/spec/factories/dictionary_file_loader_service.rb +13 -0
- data/spec/factories/dictionary_hash.rb +39 -0
- data/spec/factories/dictionary_key.rb +14 -0
- data/spec/factories/dictionary_killer_service.rb +14 -0
- data/spec/factories/dictionary_loader_service.rb +14 -0
- data/spec/factories/dictionary_manager.rb +10 -0
- data/spec/factories/dictionary_metadata.rb +16 -0
- data/spec/factories/dictionary_metadata_service.rb +16 -0
- data/spec/factories/numeric_filter.rb +12 -0
- data/spec/factories/preprocessed_word.rb +16 -0
- data/spec/factories/preprocessed_words.rb +41 -0
- data/spec/factories/single_character_word_filter.rb +12 -0
- data/spec/factories/word_results.rb +16 -0
- data/spec/lib/LittleWeasel/block_results_spec.rb +248 -0
- data/spec/lib/LittleWeasel/configure_spec.rb +74 -0
- data/spec/lib/LittleWeasel/dictionary_key_spec.rb +118 -0
- data/spec/lib/LittleWeasel/dictionary_manager_spec.rb +116 -0
- data/spec/lib/LittleWeasel/dictionary_spec.rb +289 -0
- data/spec/lib/LittleWeasel/filters/en_us/currency_filter_spec.rb +80 -0
- data/spec/lib/LittleWeasel/filters/en_us/numeric_filter_spec.rb +66 -0
- data/spec/lib/LittleWeasel/filters/en_us/single_character_word_filter_spec.rb +58 -0
- data/spec/lib/LittleWeasel/filters/word_filter_managable_spec.rb +180 -0
- data/spec/lib/LittleWeasel/filters/word_filter_spec.rb +151 -0
- data/spec/lib/LittleWeasel/filters/word_filter_validatable_spec.rb +94 -0
- data/spec/lib/LittleWeasel/filters/word_filters_validatable_spec.rb +48 -0
- data/spec/lib/LittleWeasel/integraton_tests/dictionary_integration_spec.rb +201 -0
- data/spec/lib/LittleWeasel/metadata/dictionary_creator_servicable_spec.rb +54 -0
- data/spec/lib/LittleWeasel/metadata/dictionary_metadata_spec.rb +209 -0
- data/spec/lib/LittleWeasel/metadata/invalid_words_metadata_spec.rb +155 -0
- data/spec/lib/LittleWeasel/metadata/metadata_observerable_spec.rb +31 -0
- data/spec/lib/LittleWeasel/metadata/metadatable_spec.rb +35 -0
- data/spec/lib/LittleWeasel/modules/class_name_to_symbol_spec.rb +21 -0
- data/spec/lib/LittleWeasel/modules/dictionary_file_loader_spec.rb +125 -0
- data/spec/lib/LittleWeasel/modules/dictionary_sourceable_spec.rb +44 -0
- data/spec/lib/LittleWeasel/modules/language_spec.rb +52 -0
- data/spec/lib/LittleWeasel/modules/locale_spec.rb +140 -0
- data/spec/lib/LittleWeasel/modules/region_spec.rb +52 -0
- data/spec/lib/LittleWeasel/preprocessors/en_us/capitalize_preprocessor_spec.rb +34 -0
- data/spec/lib/LittleWeasel/preprocessors/preprocessed_word_spec.rb +105 -0
- data/spec/lib/LittleWeasel/preprocessors/preprocessed_word_validatable_spec.rb +143 -0
- data/spec/lib/LittleWeasel/preprocessors/preprocessed_words_spec.rb +77 -0
- data/spec/lib/LittleWeasel/preprocessors/preprocessed_words_validatable_spec.rb +58 -0
- data/spec/lib/LittleWeasel/preprocessors/word_preprocessor_managable_spec.rb +216 -0
- data/spec/lib/LittleWeasel/preprocessors/word_preprocessor_spec.rb +175 -0
- data/spec/lib/LittleWeasel/preprocessors/word_preprocessor_validatable_spec.rb +109 -0
- data/spec/lib/LittleWeasel/preprocessors/word_preprocessors_validatable_spec.rb +49 -0
- data/spec/lib/LittleWeasel/services/dictionary_cache_service_spec.rb +444 -0
- data/spec/lib/LittleWeasel/services/dictionary_creator_service_spec.rb +119 -0
- data/spec/lib/LittleWeasel/services/dictionary_file_loader_service_spec.rb +71 -0
- data/spec/lib/LittleWeasel/services/dictionary_loader_service_spec.rb +50 -0
- data/spec/lib/LittleWeasel/services/dictionary_metadata_service_spec.rb +279 -0
- data/spec/lib/LittleWeasel/word_results_spec.rb +275 -0
- data/spec/lib/LittleWeasel/workflow/workflow_spec.rb +20 -0
- data/spec/spec_helper.rb +117 -6
- data/spec/support/factory_bot.rb +15 -0
- data/spec/support/file_helpers.rb +32 -0
- data/spec/support/files/empty-dictionary.txt +0 -0
- data/{lib/dictionary → spec/support/files/en-US-big.txt} +262156 -31488
- data/spec/support/files/en-US-tagged.txt +26 -0
- data/spec/support/files/en-US.txt +26 -0
- data/spec/support/files/en.txt +26 -0
- data/spec/support/files/es-ES.txt +27 -0
- data/spec/support/files/es.txt +27 -0
- data/spec/support/general_helpers.rb +68 -0
- data/spec/support/shared_contexts.rb +108 -0
- data/spec/support/shared_examples.rb +105 -0
- metadata +408 -65
- data/spec/checker/checker_spec.rb +0 -286
|
@@ -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
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe LittleWeasel::Modules::DictionaryCreatorServicable, type: :module do
|
|
6
|
+
include_context 'dictionary keys'
|
|
7
|
+
|
|
8
|
+
DictionaryCreatorServicable = described_class
|
|
9
|
+
|
|
10
|
+
class SubjectMock
|
|
11
|
+
include DictionaryCreatorServicable
|
|
12
|
+
include LittleWeasel::Filters::WordFilterable
|
|
13
|
+
include LittleWeasel::Modules::DictionaryKeyable
|
|
14
|
+
include LittleWeasel::Modules::DictionaryMetadataServicable
|
|
15
|
+
|
|
16
|
+
def initialize(dictionary_key:, dictionary_cache:, dictionary_metadata:, word_filters:)
|
|
17
|
+
self.dictionary_key = dictionary_key
|
|
18
|
+
self.dictionary_cache = dictionary_cache
|
|
19
|
+
self.dictionary_metadata = dictionary_metadata
|
|
20
|
+
self.word_filters = word_filters
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subject { SubjectMock.new(dictionary_key: dictionary_key, dictionary_cache: dictionary_cache, dictionary_metadata: dictionary_metadata, word_filters: word_filters) }
|
|
25
|
+
|
|
26
|
+
let(:en_us_dictionary_key) { dictionary_key_for(language: :en, region: :us) }
|
|
27
|
+
let(:dictionary_key) { en_us_dictionary_key }
|
|
28
|
+
let(:key) { dictionary_key.key }
|
|
29
|
+
let(:file) { dictionary_path_for(file_name: key) }
|
|
30
|
+
let(:dictionary_cache) { {} }
|
|
31
|
+
let(:dictionary_metadata) { {} }
|
|
32
|
+
let(:word_filters) {}
|
|
33
|
+
|
|
34
|
+
#attributes
|
|
35
|
+
describe 'attributes' do
|
|
36
|
+
it 'responds to the correct attributes' do
|
|
37
|
+
expect(subject).to respond_to(
|
|
38
|
+
:dictionary_key,
|
|
39
|
+
:dictionary_cache,
|
|
40
|
+
:word_filters)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#dictionary_creator_service
|
|
45
|
+
describe '#dictionary_creator_service' do
|
|
46
|
+
it 'responds to #dictionary_creator_service' do
|
|
47
|
+
expect(subject).to respond_to(:dictionary_creator_service)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'returns a Services::DictionaryCreatorService object' do
|
|
51
|
+
expect(subject.dictionary_creator_service).to be_kind_of LittleWeasel::Services::DictionaryCreatorService
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe LittleWeasel::Metadata::DictionaryMetadata do
|
|
6
|
+
subject { create(:dictionary_metadata, dictionary_words: dictionary_words, dictionary_key: dictionary_key, dictionary_cache: dictionary_cache, dictionary_metadata: dictionary_metadata) }
|
|
7
|
+
|
|
8
|
+
let!(:dictionary_cache_service) { create(:dictionary_cache_service, dictionary_key: dictionary_key, dictionary_cache: dictionary_cache, dictionary_file_source: true, load: true) }
|
|
9
|
+
let!(:dictionary_metadata_service) { create(:dictionary_metadata_service, dictionary_key: dictionary_key, dictionary_cache: dictionary_cache, dictionary_metadata: dictionary_metadata) }
|
|
10
|
+
let(:dictionary_words) { create(:dictionary_hash) }
|
|
11
|
+
let(:dictionary_key) { create(:dictionary_key) }
|
|
12
|
+
let(:dictionary_cache) { {} }
|
|
13
|
+
let(:dictionary_metadata) { {} }
|
|
14
|
+
let(:invalid_words_metadata_key) { invalid_words_metadata_class.metadata_key }
|
|
15
|
+
let(:invalid_words_metadata_class) { LittleWeasel::Metadata::InvalidWordsMetadata }
|
|
16
|
+
|
|
17
|
+
#.new
|
|
18
|
+
describe '#.new' do
|
|
19
|
+
context 'with valid arguments' do
|
|
20
|
+
it 'instantiates the object' do
|
|
21
|
+
expect { subject }.to_not raise_error
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context 'with invalid arguments' do
|
|
26
|
+
context 'when dictionary_words is nil' do
|
|
27
|
+
# Note: do not use the factory for this spec becasue
|
|
28
|
+
# it creates a dictionary if a nil dictionay is passed
|
|
29
|
+
# so the test will never pass if using the factory.
|
|
30
|
+
subject { described_class.new(dictionary_words: dictionary_words, dictionary_key: dictionary_key, dictionary_cache: dictionary_cache, dictionary_metadata: dictionary_metadata) }
|
|
31
|
+
|
|
32
|
+
let(:dictionary_words) {}
|
|
33
|
+
|
|
34
|
+
it 'raises an error' do
|
|
35
|
+
expect { subject }.to raise_error(/Argument dictionary_words is not a Hash/)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context 'when dictionary_words is not a Hash' do
|
|
40
|
+
let(:dictionary_words) { %w(I am a bad dictionary) }
|
|
41
|
+
|
|
42
|
+
it 'raises an error' do
|
|
43
|
+
expect { subject }.to raise_error(/Argument dictionary_words is not a Hash/)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#[]
|
|
50
|
+
describe '#[]' do
|
|
51
|
+
context 'when passing a valid metadata_key' do
|
|
52
|
+
context 'when it is a key that points to a valid metadata observer' do
|
|
53
|
+
before do
|
|
54
|
+
subject.add_observers
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'returns the metadata observer object' do
|
|
58
|
+
expect(subject[invalid_words_metadata_key]).to be_kind_of invalid_words_metadata_class
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context 'when it is a key that DOES NOT point to a valid metadata observer' do
|
|
63
|
+
it 'returns nil' do
|
|
64
|
+
expect(subject[invalid_words_metadata_key]).to be_nil
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context 'when passing an INVALID metadata_key' do
|
|
70
|
+
it 'returns nil' do
|
|
71
|
+
expect(subject[:bad_metadata_key]).to be_nil
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
#init
|
|
77
|
+
describe '#init' do
|
|
78
|
+
context 'when there are observers attached' do
|
|
79
|
+
before do
|
|
80
|
+
subject.add_observers
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context 'when metadata is in the dictionary cache' do
|
|
84
|
+
it 'observers are notified to init' do
|
|
85
|
+
# Sanity check.
|
|
86
|
+
expect(subject.count_observers).to eq 1
|
|
87
|
+
expect(subject.observers[invalid_words_metadata_key]).to receive(:init)
|
|
88
|
+
subject.init
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
context 'when there are NO observers attached' do
|
|
94
|
+
it 'observers are NOT notified to init' do
|
|
95
|
+
# Sanity check.
|
|
96
|
+
expect(subject.count_observers).to eq 0
|
|
97
|
+
expect(subject.observers[invalid_words_metadata_key]).to_not receive(:init)
|
|
98
|
+
subject.init
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
context 'when dictionary metadata is already in the dictionary cache' do
|
|
103
|
+
it 'inits the metadata with what is currently in the dictionary cache' do
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
#refresh
|
|
109
|
+
describe '#refresh' do
|
|
110
|
+
context 'when there are observers attached' do
|
|
111
|
+
before do
|
|
112
|
+
subject.add_observers
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it 'observers are notified to refresh' do
|
|
116
|
+
# Sanity check.
|
|
117
|
+
expect(subject.count_observers).to eq 1
|
|
118
|
+
expect(subject.observers[invalid_words_metadata_key]).to receive(:refresh)
|
|
119
|
+
subject.refresh
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
context 'when there are NO observers attached' do
|
|
124
|
+
it 'observers are NOT notified to refresh' do
|
|
125
|
+
# Sanity check.
|
|
126
|
+
expect(subject.count_observers).to eq 0
|
|
127
|
+
expect(subject.observers[invalid_words_metadata_key]).to_not receive(:refresh)
|
|
128
|
+
subject.refresh
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
context 'when dictionary metadata is already in the dictionary cache' do
|
|
133
|
+
it 'refreshes the metadata with what is currently in the dictionary cache' do
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
#delete_observer
|
|
139
|
+
describe '#delete_observer' do
|
|
140
|
+
context 'when a valid observer object is passed' do
|
|
141
|
+
before do
|
|
142
|
+
subject.add_observers
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
let(:observer) { subject.observers.values.first }
|
|
146
|
+
|
|
147
|
+
it 'the observer is removed from the #observers list' do
|
|
148
|
+
expect { subject.delete_observer(observer) }
|
|
149
|
+
.to change { subject.observers.count }
|
|
150
|
+
.from(1)
|
|
151
|
+
.to(0)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
context 'when an INVALID observer object is passed' do
|
|
156
|
+
let(:bad_observer) { :bad_observer }
|
|
157
|
+
|
|
158
|
+
it 'raises an error' do
|
|
159
|
+
expect { subject.delete_observer(bad_observer) }.to raise_error 'Argument metadata_observable is not a ' \
|
|
160
|
+
"Metadata::MetadataObserverable object: #{bad_observer.class}"
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
#add_observers
|
|
166
|
+
describe '#add_observers' do
|
|
167
|
+
it 'returns the same object that was called' do
|
|
168
|
+
expect(subject.add_observers).to be subject
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
context 'when a metadata object is in a state to observe' do
|
|
172
|
+
it 'added as an observer' do
|
|
173
|
+
expect(subject.add_observers.count_observers).to eq 1
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
context 'when #add_observers is called more than once' do
|
|
177
|
+
context 'when argument force is true (force: true)' do
|
|
178
|
+
before do
|
|
179
|
+
subject.add_observers
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it 'reinstantiates and replaces the observers' do
|
|
183
|
+
expect(subject.add_observers(force: true).count_observers).to eq 1
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
context 'when argument force is false (force: false)' do
|
|
188
|
+
before do
|
|
189
|
+
subject.add_observers
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it 'raises an error' do
|
|
193
|
+
expect { subject.add_observers }.to raise_error 'Observers have already been added; use #add_observers(force: true) instead'
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
context 'when a metadata object is NOT in a state to observe' do
|
|
200
|
+
before do
|
|
201
|
+
allow(LittleWeasel::Metadata::InvalidWordsMetadata).to receive(:observe?).and_return(false)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it 'NOT added as an observer' do
|
|
205
|
+
expect(subject.add_observers.count_observers).to eq 0
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|