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.
Files changed (152) 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/Gemfile +3 -1
  9. data/LittleWeasel.gemspec +31 -18
  10. data/README.md +408 -42
  11. data/Rakefile +296 -3
  12. data/lib/LittleWeasel.rb +5 -184
  13. data/lib/LittleWeasel/block_results.rb +81 -0
  14. data/lib/LittleWeasel/configure.rb +98 -0
  15. data/lib/LittleWeasel/dictionary.rb +125 -0
  16. data/lib/LittleWeasel/dictionary_key.rb +48 -0
  17. data/lib/LittleWeasel/dictionary_manager.rb +85 -0
  18. data/lib/LittleWeasel/errors/dictionary_file_already_loaded_error.rb +9 -0
  19. data/lib/LittleWeasel/errors/dictionary_file_empty_error.rb +8 -0
  20. data/lib/LittleWeasel/errors/dictionary_file_not_found_error.rb +8 -0
  21. data/lib/LittleWeasel/errors/dictionary_file_too_large_error.rb +16 -0
  22. data/lib/LittleWeasel/errors/language_required_error.rb +8 -0
  23. data/lib/LittleWeasel/errors/must_override_error.rb +8 -0
  24. data/lib/LittleWeasel/filters/en_us/currency_filter.rb +19 -0
  25. data/lib/LittleWeasel/filters/en_us/numeric_filter.rb +19 -0
  26. data/lib/LittleWeasel/filters/en_us/single_character_word_filter.rb +21 -0
  27. data/lib/LittleWeasel/filters/word_filter.rb +59 -0
  28. data/lib/LittleWeasel/filters/word_filter_managable.rb +80 -0
  29. data/lib/LittleWeasel/filters/word_filter_validatable.rb +31 -0
  30. data/lib/LittleWeasel/filters/word_filterable.rb +19 -0
  31. data/lib/LittleWeasel/filters/word_filters_validatable.rb +29 -0
  32. data/lib/LittleWeasel/metadata/dictionary_metadata.rb +145 -0
  33. data/lib/LittleWeasel/metadata/invalid_words_metadata.rb +134 -0
  34. data/lib/LittleWeasel/metadata/invalid_words_service_results.rb +45 -0
  35. data/lib/LittleWeasel/metadata/metadata_observable_validatable.rb +22 -0
  36. data/lib/LittleWeasel/metadata/metadata_observerable.rb +90 -0
  37. data/lib/LittleWeasel/metadata/metadatable.rb +136 -0
  38. data/lib/LittleWeasel/modules/class_name_to_symbol.rb +26 -0
  39. data/lib/LittleWeasel/modules/configurable.rb +26 -0
  40. data/lib/LittleWeasel/modules/deep_dup.rb +11 -0
  41. data/lib/LittleWeasel/modules/dictionary_cache_keys.rb +34 -0
  42. data/lib/LittleWeasel/modules/dictionary_cache_servicable.rb +26 -0
  43. data/lib/LittleWeasel/modules/dictionary_cache_validatable.rb +20 -0
  44. data/lib/LittleWeasel/modules/dictionary_creator_servicable.rb +27 -0
  45. data/lib/LittleWeasel/modules/dictionary_file_loader.rb +67 -0
  46. data/lib/LittleWeasel/modules/dictionary_key_validatable.rb +19 -0
  47. data/lib/LittleWeasel/modules/dictionary_keyable.rb +24 -0
  48. data/lib/LittleWeasel/modules/dictionary_loader_servicable.rb +27 -0
  49. data/lib/LittleWeasel/modules/dictionary_metadata_servicable.rb +29 -0
  50. data/lib/LittleWeasel/modules/dictionary_metadata_validatable.rb +17 -0
  51. data/lib/LittleWeasel/modules/dictionary_sourceable.rb +26 -0
  52. data/lib/LittleWeasel/modules/dictionary_validatable.rb +30 -0
  53. data/lib/LittleWeasel/modules/language.rb +23 -0
  54. data/lib/LittleWeasel/modules/language_validatable.rb +16 -0
  55. data/lib/LittleWeasel/modules/locale.rb +40 -0
  56. data/lib/LittleWeasel/modules/order_validatable.rb +18 -0
  57. data/lib/LittleWeasel/modules/orderable.rb +17 -0
  58. data/lib/LittleWeasel/modules/region.rb +23 -0
  59. data/lib/LittleWeasel/modules/region_validatable.rb +16 -0
  60. data/lib/LittleWeasel/modules/tag_validatable.rb +16 -0
  61. data/lib/LittleWeasel/modules/taggable.rb +31 -0
  62. data/lib/LittleWeasel/modules/word_results_validatable.rb +28 -0
  63. data/lib/LittleWeasel/preprocessors/en_us/capitalize_preprocessor.rb +22 -0
  64. data/lib/LittleWeasel/preprocessors/preprocessed_word.rb +28 -0
  65. data/lib/LittleWeasel/preprocessors/preprocessed_word_validatable.rb +55 -0
  66. data/lib/LittleWeasel/preprocessors/preprocessed_words.rb +55 -0
  67. data/lib/LittleWeasel/preprocessors/preprocessed_words_validatable.rb +27 -0
  68. data/lib/LittleWeasel/preprocessors/word_preprocessable.rb +19 -0
  69. data/lib/LittleWeasel/preprocessors/word_preprocessor.rb +122 -0
  70. data/lib/LittleWeasel/preprocessors/word_preprocessor_managable.rb +114 -0
  71. data/lib/LittleWeasel/preprocessors/word_preprocessor_validatable.rb +40 -0
  72. data/lib/LittleWeasel/preprocessors/word_preprocessors_validatable.rb +24 -0
  73. data/lib/LittleWeasel/services/dictionary_cache_service.rb +262 -0
  74. data/lib/LittleWeasel/services/dictionary_creator_service.rb +94 -0
  75. data/lib/LittleWeasel/services/dictionary_file_loader_service.rb +37 -0
  76. data/lib/LittleWeasel/services/dictionary_killer_service.rb +35 -0
  77. data/lib/LittleWeasel/services/dictionary_loader_service.rb +59 -0
  78. data/lib/LittleWeasel/services/dictionary_metadata_service.rb +114 -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/spec/factories/dictionary.rb +43 -0
  83. data/spec/factories/dictionary_cache_service.rb +95 -0
  84. data/spec/factories/dictionary_creator_service.rb +16 -0
  85. data/spec/factories/dictionary_file_loader_service.rb +13 -0
  86. data/spec/factories/dictionary_hash.rb +39 -0
  87. data/spec/factories/dictionary_key.rb +14 -0
  88. data/spec/factories/dictionary_killer_service.rb +14 -0
  89. data/spec/factories/dictionary_loader_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 +116 -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 +44 -0
  119. data/spec/lib/LittleWeasel/modules/language_spec.rb +52 -0
  120. data/spec/lib/LittleWeasel/modules/locale_spec.rb +140 -0
  121. data/spec/lib/LittleWeasel/modules/region_spec.rb +52 -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 +216 -0
  128. data/spec/lib/LittleWeasel/preprocessors/word_preprocessor_spec.rb +175 -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_loader_service_spec.rb +50 -0
  135. data/spec/lib/LittleWeasel/services/dictionary_metadata_service_spec.rb +279 -0
  136. data/spec/lib/LittleWeasel/word_results_spec.rb +275 -0
  137. data/spec/lib/LittleWeasel/workflow/workflow_spec.rb +20 -0
  138. data/spec/spec_helper.rb +117 -6
  139. data/spec/support/factory_bot.rb +15 -0
  140. data/spec/support/file_helpers.rb +32 -0
  141. data/spec/support/files/empty-dictionary.txt +0 -0
  142. data/{lib/dictionary → spec/support/files/en-US-big.txt} +262156 -31488
  143. data/spec/support/files/en-US-tagged.txt +26 -0
  144. data/spec/support/files/en-US.txt +26 -0
  145. data/spec/support/files/en.txt +26 -0
  146. data/spec/support/files/es-ES.txt +27 -0
  147. data/spec/support/files/es.txt +27 -0
  148. data/spec/support/general_helpers.rb +68 -0
  149. data/spec/support/shared_contexts.rb +108 -0
  150. data/spec/support/shared_examples.rb +105 -0
  151. metadata +408 -65
  152. data/spec/checker/checker_spec.rb +0 -286
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LittleWeasel::Services::DictionaryCreatorService do
6
+ include_context 'dictionary keys'
7
+ include_context 'mock word filters'
8
+ include_context 'mock word preprocessors'
9
+
10
+ subject { create(:dictionary_creator_service, dictionary_key: dictionary_key, dictionary_cache: dictionary_cache, dictionary_metadata: dictionary_metadata, word_filters: word_filters, word_preprocessors: word_preprocessors) }
11
+
12
+ let(:language) { :en }
13
+ let(:region) { :us }
14
+ let(:tag) {}
15
+ let(:dictionary_key) { create(:dictionary_key, language: language, region: region, tag: tag) }
16
+ let(:key) { dictionary_key.key }
17
+ let(:file) { dictionary_path_for(file_name: key) }
18
+ let(:dictionary_cache) { {} }
19
+ let(:dictionary_metadata) { {} }
20
+ let(:word_filters) {}
21
+ let(:word_preprocessors) {}
22
+
23
+ shared_examples 'it should' do
24
+ context 'with word_filters' do
25
+ context 'when argument word_filters contains word filters' do
26
+ let(:word_filters) do
27
+ [
28
+ DollarSignFilter.new,
29
+ LittleWeasel::Filters::EnUs::NumericFilter.new,
30
+ LittleWeasel::Filters::EnUs::SingleCharacterWordFilter.new
31
+ ]
32
+ end
33
+
34
+ it 'creates a dictionary with the word filters passed' do
35
+ expect(dictionary).to be_kind_of LittleWeasel::Dictionary
36
+ expect(dictionary.word_results('$').success?).to eq true
37
+ expect(dictionary.word_results('1000').success?).to eq true
38
+ expect(dictionary.word_results('A').success?).to eq true
39
+ end
40
+ end
41
+ end
42
+
43
+ context 'with NO word_filters' do
44
+ context 'when argument word_filters is an empty Array' do
45
+ let(:word_filters) { [] }
46
+
47
+ it 'creates a dictionary that uses no word filters' do
48
+ expect(dictionary).to be_kind_of LittleWeasel::Dictionary
49
+ expect(dictionary.word_filters).to be_blank
50
+ end
51
+ end
52
+
53
+ context 'when argument word_filters is nil' do
54
+ let(:word_filters) {}
55
+
56
+ it 'creates a dictionary that uses no word filters' do
57
+ expect(dictionary).to be_kind_of LittleWeasel::Dictionary
58
+ expect(dictionary.word_filters).to be_blank
59
+ end
60
+ end
61
+ end
62
+
63
+ context 'with word_preprocessors' do
64
+ let(:word_preprocessors) { [UpcaseWordPreprocessor.new(order: 0)] }
65
+ let(:word) { 'a' }
66
+
67
+ context 'when argument word_preprocessors contains word preprocessors' do
68
+ it 'creates a dictionary with the word preprocessors passed' do
69
+ expect(dictionary).to be_kind_of LittleWeasel::Dictionary
70
+ preprocessed_words = dictionary.word_results(word).preprocessed_words
71
+ expect(preprocessed_words.original_word).to eq word
72
+ expect(preprocessed_words.preprocessed_words.count).to eq 1
73
+ expect(preprocessed_words.preprocessed_words[0].original_word).to eq word
74
+ expect(preprocessed_words.preprocessed_words[0].preprocessed_word).to eq word.upcase
75
+ expect(preprocessed_words.preprocessed_words[0].preprocessor).to eq word_preprocessors[0].to_sym
76
+ expect(preprocessed_words.preprocessed_words[0].preprocessed).to eq true
77
+ expect(preprocessed_words.preprocessed_words[0].preprocessor_order).to eq word_preprocessors[0].order
78
+ end
79
+ end
80
+ end
81
+
82
+ context 'with NO word_preprocessors' do
83
+ context 'when argument word_preprocessors is an empty Array' do
84
+ let(:word_preprocessors) { [] }
85
+
86
+ it 'creates a dictionary that uses no word preprocessors' do
87
+ expect(dictionary).to be_kind_of LittleWeasel::Dictionary
88
+ expect(dictionary.word_preprocessors).to be_blank
89
+ end
90
+ end
91
+
92
+ context 'when argument word_preprocessors is nil' do
93
+ let(:word_preprocessors) {}
94
+
95
+ it 'creates a dictionary that uses no word preprocessors' do
96
+ expect(dictionary).to be_kind_of LittleWeasel::Dictionary
97
+ expect(dictionary.word_preprocessors).to be_blank
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ #from_file_source
104
+ describe '#from_file_source' do
105
+ let(:dictionary) { subject.from_file_source file: file }
106
+
107
+ it_behaves_like 'it should'
108
+ end
109
+
110
+ #from_memory_source
111
+ describe '#from_memory_source' do
112
+ let(:dictionary) { subject.from_memory_source dictionary_words: dictionary_words }
113
+ let(:dictionary_words) do
114
+ dictionary_words_for dictionary_file_path: file
115
+ end
116
+
117
+ it_behaves_like 'it should'
118
+ end
119
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LittleWeasel::Services::DictionaryFileLoaderService do
6
+ include_context 'dictionary cache'
7
+
8
+ subject! { create(:dictionary_file_loader_service, dictionary_key: dictionary_key, dictionary_cache: dictionary_cache) }
9
+
10
+ before(:each) do
11
+ LittleWeasel::Services::DictionaryCacheService.init dictionary_cache: dictionary_cache
12
+ end
13
+
14
+ let(:dictionary_key) { create(:dictionary_key, language: :en, region: :us) }
15
+ let(:key) { dictionary_key.key }
16
+ let(:dictionary_cache) { {} }
17
+
18
+ #execute
19
+ describe '#execute' do
20
+ context 'when the dictionary is already loaded/cached' do
21
+ before do
22
+ create(:dictionary_cache_service, dictionary_key: dictionary_key, dictionary_cache: dictionary_cache, dictionary_file_source: true, load: true)
23
+ end
24
+
25
+ it 'raises an error' do
26
+ expect { subject.execute }.to raise_error "The dictionary associated with key '#{key}' already exists."
27
+ end
28
+ end
29
+
30
+ context 'when the dictionary is NOT already loaded/cached' do
31
+ before do
32
+ create(:dictionary_cache_service, dictionary_key: dictionary_key, dictionary_cache: dictionary_cache, dictionary_file_source: true)
33
+ end
34
+
35
+ let(:expected_key) { create(:dictionary_key, language: :en, region: :us).key }
36
+ let(:expected_results) do
37
+ ['apple',
38
+ 'better',
39
+ 'cat',
40
+ 'dog',
41
+ 'everyone',
42
+ 'fat',
43
+ 'game',
44
+ 'help',
45
+ 'italic',
46
+ 'jasmine',
47
+ 'kelp',
48
+ 'love',
49
+ 'man',
50
+ 'nope',
51
+ 'octopus',
52
+ 'popeye',
53
+ 'queue',
54
+ 'ruby',
55
+ 'stop',
56
+ 'top',
57
+ 'ultimate',
58
+ 'very',
59
+ 'was',
60
+ 'xylophone',
61
+ 'yes',
62
+ 'zebra']
63
+ end
64
+
65
+ it 'returns an Array of dictionary words loaded from the file' do
66
+ expect(key).to eq expected_key
67
+ expect(subject.execute).to eq expected_results
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LittleWeasel::Services::DictionaryLoaderService do
6
+ subject { create(:dictionary_loader_service, dictionary_key: dictionary_key, dictionary_cache: dictionary_cache, dictionary_metadata: dictionary_metadata) }
7
+
8
+ let(:language) { :en }
9
+ let(:region) { :us }
10
+ let(:tag) {}
11
+ let(:dictionary_key) { create(:dictionary_key, language: language, region: region, tag: tag) }
12
+ let(:dictionary_cache) { {} }
13
+ let(:dictionary_metadata) { {} }
14
+
15
+ #execute
16
+ describe '#execute' do
17
+ context 'when loading dictionaries created from a file' do
18
+ let!(:dictionary_cache_service) { create(:dictionary_cache_service, dictionary_file_source: true, dictionary_key: dictionary_key, dictionary_cache: dictionary_cache) }
19
+
20
+ context 'when the dictionary is not cached' do
21
+ it 'loads the dictionary file and returns the Dictionary' do
22
+ expect(dictionary_cache_service.dictionary_exists?).to be false
23
+ # Remove this line; there is a bug in SimpleCov that will not
24
+ # recognize #load_from_cache as having test coverage if we
25
+ # stub this out :(
26
+ # expect(subject).to_not receive(:load_from_cache)
27
+ expect(subject.execute).to be_kind_of LittleWeasel::Dictionary
28
+ end
29
+ end
30
+
31
+ context 'when the dictionary is cached' do
32
+ before do
33
+ # This will load the dictionary from disk, and cache it in
34
+ # the dictionary cache; the DictionaryLoaderService loads
35
+ # the dictionary into the dictionary cache if loaded from disk.
36
+ subject.execute
37
+ end
38
+
39
+ it 'loads the dictionary from the dictionary cache and returns the Dictionary' do
40
+ expect(dictionary_cache_service.dictionary_exists?).to be true
41
+ # Remove this line; there is a bug in SimpleCov that will not
42
+ # recognize #load_from_cache as having test coverage if we
43
+ # stub this out :(
44
+ # expect(subject).to receive(:load_from_cache).and_return(dictionary_cache_service.dictionary_object!)
45
+ expect(subject.execute).to be dictionary_cache_service.dictionary_object!
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -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