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,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../modules/configurable'
4
+ require_relative '../modules/dictionary_cache_servicable'
5
+ require_relative '../modules/dictionary_file_loader'
6
+ require_relative '../modules/dictionary_keyable'
7
+
8
+ module LittleWeasel
9
+ module Services
10
+ # This class provides a service for loading dictionaries from disk and
11
+ # returning a Hash of dictionary words that can be used to instantiate
12
+ # a Dictionary object or otherwise.
13
+ class DictionaryFileLoaderService
14
+ include Modules::Configurable
15
+ include Modules::DictionaryCacheServicable
16
+ include Modules::DictionaryFileLoader
17
+ include Modules::DictionaryKeyable
18
+
19
+ def initialize(dictionary_key:, dictionary_cache:)
20
+ validate_dictionary_key dictionary_key: dictionary_key
21
+ self.dictionary_key = dictionary_key
22
+
23
+ validate_dictionary_cache dictionary_cache: dictionary_cache
24
+ self.dictionary_cache = dictionary_cache
25
+ end
26
+
27
+ def execute
28
+ if dictionary_cache_service.dictionary_exists?
29
+ raise ArgumentError,
30
+ "The dictionary associated with key '#{key}' already exists."
31
+ end
32
+
33
+ load dictionary_cache_service.dictionary_file!
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../modules/dictionary_cache_servicable'
4
+ require_relative '../modules/dictionary_metadata_servicable'
5
+ require_relative '../modules/dictionary_keyable'
6
+
7
+ module LittleWeasel
8
+ module Services
9
+ # This service removes a dictionary (Dictionary object) associated with
10
+ # the dictionary key from the dictionary cache along with the dictionary
11
+ # file reference and any metadata associated with the dictionary from the
12
+ # dictionary cache.
13
+ class DictionaryKillerService
14
+ include Modules::DictionaryCacheServicable
15
+ include Modules::DictionaryMetadataServicable
16
+ include Modules::DictionaryKeyable
17
+
18
+ def initialize(dictionary_key:, dictionary_cache:, dictionary_metadata:)
19
+ validate_dictionary_key dictionary_key: dictionary_key
20
+ self.dictionary_key = dictionary_key
21
+
22
+ validate_dictionary_cache dictionary_cache: dictionary_cache
23
+ self.dictionary_cache = dictionary_cache
24
+
25
+ validate_dictionary_metadata dictionary_metadata: dictionary_metadata
26
+ self.dictionary_metadata = dictionary_metadata
27
+ end
28
+
29
+ def execute
30
+ dictionary_cache_service.init
31
+ dictionary_metadata_service.class.init dictionary_metadata: dictionary_metadata
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../dictionary'
4
+ require_relative '../metadata/dictionary_metadata'
5
+ require_relative '../modules/dictionary_cache_servicable'
6
+ require_relative '../modules/dictionary_metadata_servicable'
7
+ require_relative '../modules/dictionary_keyable'
8
+ require_relative 'dictionary_file_loader_service'
9
+
10
+ module LittleWeasel
11
+ module Services
12
+ # This class provides services to load dictionaries from either disk (if
13
+ # the dictionary has not been loaded) or from the dictionary cache if the
14
+ # dictionary has already been loaded from disk.
15
+ class DictionaryLoaderService
16
+ include Modules::DictionaryKeyable
17
+ include Modules::DictionaryCacheServicable
18
+ include Modules::DictionaryMetadataServicable
19
+
20
+ def initialize(dictionary_key:, dictionary_cache:, dictionary_metadata:)
21
+ validate_dictionary_key dictionary_key: dictionary_key
22
+ self.dictionary_key = dictionary_key
23
+
24
+ validate_dictionary_cache dictionary_cache: dictionary_cache
25
+ self.dictionary_cache = dictionary_cache
26
+
27
+ validate_dictionary_metadata dictionary_metadata: dictionary_metadata
28
+ self.dictionary_metadata = dictionary_metadata
29
+ end
30
+
31
+ def execute
32
+ if dictionary_cache_service.dictionary_exists?
33
+ load_from_cache
34
+ else
35
+ dictionary_cache_service.dictionary_object = load_from_disk
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def load_from_cache
42
+ dictionary_cache_service.dictionary_object!
43
+ end
44
+
45
+ def load_from_disk
46
+ dictionary_for dictionary_words: dictionary_file_loader_service.execute
47
+ end
48
+
49
+ def dictionary_for(dictionary_words:)
50
+ Dictionary.new dictionary_key: dictionary_key, dictionary_cache: dictionary_cache,
51
+ dictionary_metadata: dictionary_metadata, dictionary_words: dictionary_words
52
+ end
53
+
54
+ def dictionary_file_loader_service
55
+ Services::DictionaryFileLoaderService.new dictionary_key: dictionary_key, dictionary_cache: dictionary_cache
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../modules/dictionary_cache_servicable'
4
+ require_relative '../modules/dictionary_keyable'
5
+ require_relative '../modules/dictionary_metadata_validatable'
6
+
7
+ module LittleWeasel
8
+ module Services
9
+ # This class provides methods for managing and manipulating the
10
+ # dictionary metadata associated with the given dictionary,
11
+ # (dictionary_key) for the supplied metadata_key.
12
+ class DictionaryMetadataService
13
+ include Modules::DictionaryKeyable
14
+ include Modules::DictionaryCacheServicable
15
+ include Modules::DictionaryMetadataValidatable
16
+
17
+ attr_reader :dictionary_metadata
18
+
19
+ # @example metadata Hash structure:
20
+ #
21
+ # {
22
+ # <dictionary_id!> =>
23
+ # {
24
+ # :<metadata_key> => <metadata_object>
25
+ # },
26
+ # ...
27
+ # }
28
+ # }
29
+ def initialize(dictionary_key:, dictionary_cache:, dictionary_metadata:)
30
+ validate_dictionary_key dictionary_key: dictionary_key
31
+ self.dictionary_key = dictionary_key
32
+
33
+ validate_dictionary_cache dictionary_cache: dictionary_cache
34
+ self.dictionary_cache = dictionary_cache
35
+
36
+ validate_dictionary_metadata dictionary_metadata: dictionary_metadata
37
+ self.dictionary_metadata = dictionary_metadata
38
+ end
39
+
40
+ class << self
41
+ # This method initializes the dictionary_metadata object to its
42
+ # initialized state - all data is lost, but the object reference is
43
+ # maintained.
44
+ def init(dictionary_metadata:)
45
+ Modules::DictionaryMetadataValidatable.validate dictionary_metadata: dictionary_metadata
46
+
47
+ dictionary_metadata.each_key { |key| dictionary_metadata.delete(key) }
48
+ dictionary_metadata
49
+ end
50
+
51
+ # Returns true if the dictionary metadata is initialized; that is, if
52
+ # it's in the same state the dictionary metadata would be in if #init
53
+ # were called.
54
+ def init?(dictionary_metadata:)
55
+ Modules::DictionaryMetadataValidatable.validate dictionary_metadata: dictionary_metadata
56
+
57
+ initialized_dictionary_metadata = init(dictionary_metadata: {})
58
+ dictionary_metadata.eql?(initialized_dictionary_metadata)
59
+ end
60
+ alias initialized? init?
61
+ end
62
+
63
+ # This method initializes the dictionary metadata for dictionary metadata
64
+ # associated with the dictionary_id! and metadata_key.
65
+ def init(metadata_key:)
66
+ metadata = dictionary_metadata[dictionary_id!]
67
+ metadata&.delete(metadata_key)
68
+ metadata = dictionary_metadata_init_if
69
+ metadata[metadata_key] = nil
70
+ self
71
+ end
72
+
73
+ # This method will return true if metadata exists for the dictionary
74
+ # associated with the given dictionary key, for the given metadata key.
75
+ def dictionary_metadata?(metadata_key:)
76
+ dictionary_metadata.dig(dictionary_id, metadata_key)&.present? || false
77
+ end
78
+
79
+ def get_dictionary_metadata(metadata_key:)
80
+ dictionary_metadata.dig(dictionary_id!, metadata_key)
81
+ end
82
+
83
+ def set_dictionary_metadata(value:, metadata_key:)
84
+ dictionary_metadata[dictionary_id!][metadata_key] = value
85
+ self
86
+ end
87
+
88
+ private
89
+
90
+ attr_writer :dictionary_metadata
91
+
92
+ def dictionary_metadata_init_needed?
93
+ dictionary_metadata[dictionary_id!].blank?
94
+ end
95
+
96
+ # This method initializes the metadata for the
97
+ # dictionary_id! if it is not already initialized.
98
+ # The metadata for the given dictionary_id! is returned.
99
+ def dictionary_metadata_init_if
100
+ return dictionary_metadata[dictionary_id!] unless dictionary_metadata_init_needed?
101
+
102
+ dictionary_metadata[dictionary_id!] = {}
103
+ end
104
+
105
+ def dictionary_id
106
+ dictionary_cache_service.dictionary_id
107
+ end
108
+
109
+ def dictionary_id!
110
+ dictionary_cache_service.dictionary_id!
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../metadata/invalid_words_service_results'
4
+
5
+ module LittleWeasel
6
+ module Services
7
+ # This class calculates the total amount of bytes cached invalid words take
8
+ # up in the given dictionary and returns the results. In addition to this,
9
+ # metadata is also compiled to determine how many more bytes of invalid
10
+ # word data can be cached before the cache is depleted and shutdown.
11
+ class InvalidWordsService
12
+ def initialize(dictionary)
13
+ self.dictionary = dictionary
14
+ self.current_bytesize = 0
15
+ end
16
+
17
+ def execute
18
+ return build_return unless max_invalid_words_bytesize?
19
+
20
+ self.current_bytesize = calculate_current_bytesize
21
+ build_return
22
+ end
23
+
24
+ private
25
+
26
+ attr_accessor :current_bytesize, :dictionary
27
+
28
+ def calculate_current_bytesize
29
+ dictionary.reduce(0) do |bytesize, word_and_found|
30
+ unless word_and_found.last
31
+ bytesize += word_and_found.first.bytesize
32
+ break unless bytesize < max_invalid_words_bytesize
33
+ end
34
+ bytesize
35
+ end
36
+ end
37
+
38
+ def build_return
39
+ Metadata::InvalidWordsServiceResults.new(
40
+ max_invalid_words_bytesize_on: max_invalid_words_bytesize?,
41
+ current_invalid_word_bytesize: current_bytesize,
42
+ max_invalid_words_bytesize: max_invalid_words_bytesize
43
+ )
44
+ end
45
+
46
+ def max_invalid_words_bytesize
47
+ @max_invalid_words_bytesize ||= config.max_invalid_words_bytesize
48
+ end
49
+
50
+ def max_invalid_words_bytesize?
51
+ config.max_invalid_words_bytesize?
52
+ end
53
+
54
+ def config
55
+ @config ||= LittleWeasel.configuration
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # The version of this gem
2
4
  module LittleWeasel
3
- VERSION = "3.0.4"
5
+ VERSION = '4.0.0'
4
6
  end
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/module/delegation'
4
+ require_relative 'modules/word_results_validatable'
5
+ require_relative 'preprocessors/preprocessed_words_validatable'
6
+
7
+ module LittleWeasel
8
+ # This class represents the results of gathering information about a word.
9
+ class WordResults
10
+ include Modules::WordResultsValidatable
11
+ include Preprocessors::PreprocessedWordsValidatable
12
+
13
+ attr_reader :filters_matched, :original_word, :preprocessed_words, :word_cached, :word_valid
14
+
15
+ delegate :preprocessed_word, to: :preprocessed_words, allow_nil: true
16
+
17
+ # Important: Regarding Boolean Methods
18
+ #
19
+ # The return value of some of the boolean methods (i.e. methods ending with
20
+ # a '?') of this class depend on whether or not #original_word
21
+ # has passed through any preprocessing. If #orginal_word has passed
22
+ # through preprocessing, the following boolean methods will reflect
23
+ # that of #preprocessed_word; if #original_word has NOT passed through
24
+ # any preprocessing, the following methods will reflect that of
25
+ # #original_word:
26
+ #
27
+ # #success?
28
+ # #filter_match?
29
+ # #word_cached?
30
+ # #word_valid?
31
+ #
32
+ # In other words, if #original_word has passed through preprocessing
33
+ # and has been altered by any of the preprocessing modules, it is the
34
+ # #preprocessed_word that is passed through any subsequent word filters,
35
+ # checked against the dictionary for validity, and cached, NOT
36
+ # #original_word.
37
+ # :reek:BooleanParameter - ignored, boolean params do not determine logic path, but only report status.
38
+ def initialize(original_word:, filters_matched: [],
39
+ preprocessed_words: nil, word_cached: false, word_valid: false)
40
+
41
+ self.original_word = original_word
42
+ self.filters_matched = filters_matched
43
+ self.word_cached = word_cached
44
+ self.word_valid = word_valid
45
+ self.preprocessed_words = preprocessed_words
46
+ end
47
+
48
+ def original_word=(value)
49
+ @original_word = value
50
+ validate_original_word
51
+ end
52
+
53
+ def filters_matched=(value)
54
+ @filters_matched = value
55
+ validate_filters_matched
56
+ end
57
+
58
+ def word_cached=(value)
59
+ @word_cached = value
60
+ validate_word_cached
61
+ end
62
+
63
+ def word_valid=(value)
64
+ @word_valid = value
65
+ vaidate_word_valid
66
+ end
67
+
68
+ def preprocessed_words=(value)
69
+ if value.present?
70
+ validate_prepreprocessed_words preprocessed_words: value
71
+ @preprocessed_words = value
72
+ else
73
+ @preprocessed_words = nil
74
+ end
75
+ end
76
+
77
+ # Returns true if the word is valid (found in the dictionary), or
78
+ # the word was matched against at least one filter; false, otherwise.
79
+ #
80
+ # Use the results of this method if you want to consider a word's
81
+ # validity as having been found in the dictionary as a valid word OR
82
+ # if the word has at least one word filter match. If the word has
83
+ # NOT passed through any word filters, or if word DID NOT match any
84
+ # filters, yet, it was found as a valid word in the dictionary, this
85
+ # method will return true and vice versa.
86
+ #
87
+ # See "Important: Regarding Boolean Methods" notes at the top of this
88
+ # class definition for more detail.
89
+ def success?
90
+ filter_match? || word_valid?
91
+ end
92
+
93
+ # Returns true if the word was found in the dictionary; false, otherwise.
94
+ #
95
+ # Use the results of this method if you want to consider a word's
96
+ # validity irrespective of whether or not the word has matched any word
97
+ # filters (if any).
98
+ #
99
+ # See "Important: Regarding Boolean Methods" notes at the top of this
100
+ # class definition for more detail.
101
+ def word_valid?
102
+ word_valid
103
+ end
104
+
105
+ # Returns true if the word was matched against at least one filter;
106
+ # false, otherwise.
107
+ #
108
+ # See "Important: Regarding Boolean Methods" notes at the top of this
109
+ # class definition for more detail.
110
+ def filter_match?
111
+ filters_matched.present?
112
+ end
113
+
114
+ # Returns true if #original_word passed through any preprocessing. If
115
+ # this is the case, #preprocessed_word may be different than
116
+ # #original_word. Preprocessing should take place before any filtering
117
+ # takes place.
118
+ #
119
+ # #word_cached, #word_valid and #filters_matched should all
120
+ # reflect that of the #preprocessed_word if #preprocessed_word is
121
+ # present?; otherwise, they should all reflect that of #original_word.
122
+ def preprocessed_word?
123
+ preprocessed_word.present?
124
+ end
125
+
126
+ # Returns #preprocessed_word (if available) or #original_word.
127
+ # #preprocessed_word will be present if #original_word has
128
+ # met the criteria for preprocessing and passed through at least
129
+ # one preprocessor.
130
+ #
131
+ # See "Important: Regarding Boolean Methods" notes at the top of this
132
+ # class definition for more detail.
133
+ def preprocessed_word_or_original_word
134
+ preprocessed_word || original_word
135
+ end
136
+
137
+ # Returns true if the word was found in the dictionary as a valid word
138
+ # OR if the word was found in the cache as an invalid word.
139
+ #
140
+ # See "Important: Regarding Boolean Methods" notes at the top of this
141
+ # class definition for more detail.
142
+ def word_cached?
143
+ word_cached
144
+ end
145
+ end
146
+ end