the_array_comparator 0.1.1

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 (54) hide show
  1. data/.gitignore +16 -0
  2. data/.rspec +2 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +6 -0
  5. data/CONTRIBUTIONS.md +7 -0
  6. data/Gemfile +30 -0
  7. data/Gemfile.lock +122 -0
  8. data/LICENSE.md +20 -0
  9. data/README.md +121 -0
  10. data/RELEASE_NOTES.md +0 -0
  11. data/Rakefile +93 -0
  12. data/TODO.md +1 -0
  13. data/gemfiles/Gemfile.default +30 -0
  14. data/gemfiles/Gemfile.travis +15 -0
  15. data/lib/the_array_comparator/check.rb +27 -0
  16. data/lib/the_array_comparator/comparator.rb +123 -0
  17. data/lib/the_array_comparator/exceptions.rb +21 -0
  18. data/lib/the_array_comparator/result.rb +21 -0
  19. data/lib/the_array_comparator/sample.rb +28 -0
  20. data/lib/the_array_comparator/strategies/base.rb +41 -0
  21. data/lib/the_array_comparator/strategies/contains_all.rb +35 -0
  22. data/lib/the_array_comparator/strategies/contains_all_with_substring_search.rb +39 -0
  23. data/lib/the_array_comparator/strategies/contains_any.rb +34 -0
  24. data/lib/the_array_comparator/strategies/contains_any_with_substring_search.rb +33 -0
  25. data/lib/the_array_comparator/strategies/contains_not.rb +32 -0
  26. data/lib/the_array_comparator/strategies/contains_not_with_substring_search.rb +33 -0
  27. data/lib/the_array_comparator/strategies/is_equal.rb +30 -0
  28. data/lib/the_array_comparator/strategies/is_not_equal.rb +30 -0
  29. data/lib/the_array_comparator/testing_helper/data_set.rb +63 -0
  30. data/lib/the_array_comparator/testing_helper/test_data.rb +33 -0
  31. data/lib/the_array_comparator/testing_helper.rb +55 -0
  32. data/lib/the_array_comparator/version.rb +6 -0
  33. data/lib/the_array_comparator.rb +34 -0
  34. data/script/console +8 -0
  35. data/script/terminal +12 -0
  36. data/spec/benchmark/benchmark_spec.rb +28 -0
  37. data/spec/check_spec.rb +30 -0
  38. data/spec/comparator/base_spec.rb +16 -0
  39. data/spec/comparator/comparator_spec.rb +198 -0
  40. data/spec/comparator/contains_all_spec.rb +52 -0
  41. data/spec/comparator/contains_all_with_substring_search_spec.rb +41 -0
  42. data/spec/comparator/contains_any_spec.rb +45 -0
  43. data/spec/comparator/contains_any_with_substring_search_spec.rb +35 -0
  44. data/spec/comparator/contains_not_spec.rb +45 -0
  45. data/spec/comparator/contains_not_with_substring_search_spec.rb +28 -0
  46. data/spec/comparator/is_equal_spec.rb +51 -0
  47. data/spec/comparator/is_not_equal_spec.rb +39 -0
  48. data/spec/result_spec.rb +31 -0
  49. data/spec/sample_spec.rb +24 -0
  50. data/spec/spec_helper.rb +38 -0
  51. data/spec/strategies_helper.rb +11 -0
  52. data/spec/testing_helper/testing_helper_spec.rb +27 -0
  53. data/the_array_comparator.gemspec +21 -0
  54. metadata +132 -0
@@ -0,0 +1,41 @@
1
+ #encoding: utf-8
2
+
3
+ # the main module
4
+ module TheArrayComparator
5
+ # the available strategies
6
+ module Strategies
7
+ #base class for strategies
8
+ class Base
9
+
10
+ # Create a new instance of strategy
11
+ #
12
+ # @param [Sample] sample
13
+ # the probe which should be used for the check
14
+ #
15
+ # @return [Object]
16
+ # the strategy
17
+ def initialize(sample=Sample.new)
18
+ @data = sample.data
19
+ @keywords = sample.keywords
20
+ @exceptions = sample.exceptions
21
+ @tag = sample.tag
22
+ end
23
+
24
+ # Check the keywords with the data
25
+ #
26
+ # @note
27
+ # needs to be implemented by the concrete strategy
28
+ # @raise [RuntimeError]
29
+ # error when not implemented by strategy
30
+ def success?
31
+ raise Exceptions::IncompatibleComparator, "The chosen comparator is incompatible, Please check the documentation for comparator strategies on how to build a compatible one."
32
+ end
33
+
34
+ private
35
+
36
+ def warning_unsupported_exceptions
37
+ warn "Exceptions are not supported by this strategy." unless @exceptions.blank?
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,35 @@
1
+ #encoding: utf-8
2
+
3
+ # the main module
4
+ module TheArrayComparator
5
+ # the available strategies
6
+ module Strategies
7
+ #strategy contains
8
+ class ContainsAll < Base
9
+
10
+ # Create a new instance of strategy
11
+ #
12
+ # @see Base
13
+ def initialize(sample=Sample.new)
14
+ super
15
+
16
+ warning_unsupported_exceptions
17
+ end
18
+
19
+ # Check the keywords with the data
20
+ #
21
+ # @return [Boolean]
22
+ # The result of the check
23
+ def success?
24
+ return true if @keywords.blank? and @data.blank?
25
+ return false if @keywords.blank? or @data.blank?
26
+
27
+ if ( @keywords - @data ).blank?
28
+ return true
29
+ else
30
+ return false
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,39 @@
1
+ #encoding: utf-8
2
+
3
+ # the main module
4
+ module TheArrayComparator
5
+ # the available strategies
6
+ module Strategies
7
+ # strategy contains substring
8
+ class ContainsAllWithSubstringSearch < Base
9
+
10
+ # Create a new instance of strategy
11
+ #
12
+ # @see Base
13
+ def initialize(sample=Sample.new)
14
+ super
15
+ end
16
+
17
+ # Check the keywords with the data
18
+ #
19
+ # @return [Boolean]
20
+ # The result of the check
21
+ def success?
22
+ return true if @keywords.blank? and @data.blank?
23
+
24
+ #return true if @data.all? do |line|
25
+ # #does a keyword match and it is not an the exception list
26
+ # binding.pry
27
+ # @keywords.all?{ |k| line[k] } and not @exceptions.any?{ |e| line[e] }
28
+ #end
29
+
30
+ return true if @keywords.all? do |word|
31
+ #does a keyword match and it is not an the exception list
32
+ @data.any?{ |line| line[word] and not @exceptions.any?{ |e| line[e] } }
33
+ end
34
+
35
+ false
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,34 @@
1
+ #encoding: utf-8
2
+
3
+ # the main module
4
+ module TheArrayComparator
5
+ # the available strategies
6
+ module Strategies
7
+ #strategy contains
8
+ class ContainsAny < Base
9
+
10
+ # Create a new instance of strategy
11
+ #
12
+ # @see Base
13
+ def initialize(sample=Sample.new)
14
+ super
15
+
16
+ warning_unsupported_exceptions
17
+ end
18
+
19
+ # Check the keywords with the data
20
+ #
21
+ # @return [Boolean]
22
+ # The result of the check
23
+ def success?
24
+ return true if @keywords.blank? and @data.blank?
25
+
26
+ if ( @keywords & @data ).blank?
27
+ return false
28
+ else
29
+ return true
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,33 @@
1
+ #encoding: utf-8
2
+
3
+ # the main module
4
+ module TheArrayComparator
5
+ # the available strategies
6
+ module Strategies
7
+ # strategy contains substring
8
+ class ContainsAnyWithSubstringSearch < Base
9
+
10
+ # Create a new instance of strategy
11
+ #
12
+ # @see Base
13
+ def initialize(sample=Sample.new)
14
+ super
15
+ end
16
+
17
+ # Check the keywords with the data
18
+ #
19
+ # @return [Boolean]
20
+ # The result of the check
21
+ def success?
22
+ return true if @keywords.blank? and @data.blank?
23
+
24
+ return true if @data.any? do |line|
25
+ #does a keyword match and it is not an the exception list
26
+ @keywords.any?{ |k| line[k] } and not @exceptions.any?{ |e| line[e] }
27
+ end
28
+
29
+ false
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,32 @@
1
+ #encoding: utf-8
2
+
3
+ # the main module
4
+ module TheArrayComparator
5
+ # the available strategies
6
+ module Strategies
7
+ #strategy contains
8
+ class ContainsNot < Base
9
+
10
+ # Create a new instance of strategy
11
+ #
12
+ # @see Base
13
+ def initialize(sample=Sample.new)
14
+ super
15
+ end
16
+
17
+ # Check the keywords with the data
18
+ #
19
+ # @return [Boolean]
20
+ # The result of the check
21
+ def success?
22
+ return false if @keywords.blank? and @data.blank?
23
+
24
+ if ( @keywords & @data ).blank?
25
+ return true
26
+ else
27
+ return false
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ #encoding: utf-8
2
+
3
+ # the main module
4
+ module TheArrayComparator
5
+ # the available strategies
6
+ module Strategies
7
+ # strategy not contains substring
8
+ class ContainsNotWithSubstringSearch < Base
9
+
10
+ # Create a new instance of strategy
11
+ #
12
+ # @see Base
13
+ def initialize(sample=Sample.new)
14
+ super
15
+ end
16
+
17
+ # Check the keywords with the data
18
+ #
19
+ # @return [Boolean]
20
+ # The result of the check
21
+ def success?
22
+ return false if @keywords.blank? and @data.blank?
23
+
24
+ return true if @data.all? do |line|
25
+ #if a keyword is found, check if there's an exception
26
+ @keywords.none?{ |k| line[k] } or @exceptions.any?{ |e| line[e] }
27
+ end
28
+
29
+ false
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ #encoding: utf-8
2
+
3
+ # the main module
4
+ module TheArrayComparator
5
+ # the available strategies
6
+ module Strategies
7
+ #strategy is equal
8
+ class IsEqual < Base
9
+
10
+ # Create a new instance of strategy
11
+ #
12
+ # @see Base
13
+ def initialize(sample=Sample.new)
14
+ super
15
+
16
+ warning_unsupported_exceptions
17
+ end
18
+
19
+ # Check the keywords with the data
20
+ #
21
+ # @return [Boolean]
22
+ # The result of the check
23
+ def success?
24
+ return true if @keywords.to_a == @data
25
+
26
+ false
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ #encoding: utf-8
2
+
3
+ # the main module
4
+ module TheArrayComparator
5
+ # the available strategies
6
+ module Strategies
7
+ #strategy is not equal
8
+ class IsNotEqual < Base
9
+
10
+ # Create a new instance of strategy
11
+ #
12
+ # @see Base
13
+ def initialize(sample=Sample.new)
14
+ super
15
+
16
+ warning_unsupported_exceptions
17
+ end
18
+
19
+ # Check the keywords with the data
20
+ #
21
+ # @return [Boolean]
22
+ # The result of the check
23
+ def success?
24
+ return true if @keywords.to_a != @data
25
+
26
+ false
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,63 @@
1
+ module TheArrayComparator
2
+ module TestingHelper
3
+ # Keywords only make sense together with the raw data
4
+ class DataSet
5
+ #@!attribute [rw] keywords
6
+ # keywords which need to be hidden in the raw data
7
+ #
8
+ #@!attribute [rw] raw_data
9
+ # the raw data which should be used to hide the keywords
10
+ attr_accessor :keywords, :raw_data
11
+
12
+ # Create new instance
13
+ #
14
+ # @return [DataSet]
15
+ # the object holding the data
16
+ def initialize(keywords=[],raw_data=[])
17
+ @keywords = keywords
18
+ @raw_data = raw_data
19
+ end
20
+
21
+ # A stripe of data
22
+ #
23
+ # @return [Array]
24
+ # a pice of raw data
25
+ def stripe_of_data
26
+ raw_data.shift(stripe_size)
27
+ end
28
+
29
+ # A tripe of the keywords
30
+ #
31
+ # @return [String,Integer]
32
+ # one keyword
33
+ def stripe_of_keywords
34
+ keywords.shift unless keywords.blank?
35
+ end
36
+
37
+ # The count of the keywords
38
+ # @return [Integer]
39
+ # How many key words are available
40
+ def count_of_keywords
41
+ keywords.size
42
+ end
43
+
44
+ private
45
+
46
+ def divisor
47
+ if count_of_keywords > 0 and count_of_keywords <= count_of_rawdata
48
+ return count_of_keywords
49
+ else
50
+ return 1
51
+ end
52
+ end
53
+
54
+ def stripe_size
55
+ raw_data.size / divisor
56
+ end
57
+
58
+ def count_of_rawdata
59
+ raw_data.size
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,33 @@
1
+ module TheArrayComparator
2
+ module TestingHelper
3
+ class TestData
4
+
5
+ # Create test data instance
6
+ #
7
+ # @return [TestData]
8
+ # the test data object used to generate the test data
9
+ def initialize(dataset)
10
+ @dataset = dataset
11
+ @data = []
12
+ end
13
+
14
+ # Generate the test data
15
+ #
16
+ # @return [Array]
17
+ # the test data
18
+ def generate
19
+ if @data.blank?
20
+ @dataset.count_of_keywords.times do
21
+ @data.concat @dataset.stripe_of_data
22
+ @data << @dataset.stripe_of_keywords
23
+ end
24
+
25
+ #put the rest into the output
26
+ @data.concat @dataset.raw_data
27
+ end
28
+
29
+ @data
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,55 @@
1
+ #the main module
2
+ module TheArrayComparator
3
+ # helper for tests
4
+ module TestingHelper
5
+
6
+ # Generate data for the tests
7
+ #
8
+ # @param [Hash] options
9
+ #
10
+ # @option options [Array] :keywords
11
+ # the keywords which should be hidden in the data
12
+ #
13
+ # @option options [Array] :raw_data
14
+ # the data which should be used to hide the keywords
15
+ #
16
+ # @option options [Integer] :count_of_data
17
+ # how much raw data should be generated if none is given
18
+ #
19
+ # @return [Array]
20
+ # the testdata (raw_data + keywords)
21
+ def generate_testdata(options)
22
+ opts = {
23
+ keywords: [],
24
+ raw_data: [],
25
+ count_of_data: 100,
26
+ }.merge options
27
+
28
+ raw_data = options[:raw_data] || Faker::Lorem.sentences(opts[:count_of_data])
29
+ dataset = DataSet.new(options[:keywords],raw_data)
30
+
31
+ testdata = TestData.new(dataset)
32
+ testdata.generate
33
+ end
34
+ end
35
+ end
36
+
37
+ module Kernel
38
+ #
39
+ # Captures the given stream and returns it:
40
+ #
41
+ # stream = capture(:stdout) { puts 'Cool' }
42
+ # stream # => "Cool\n"
43
+ def capture(stream)
44
+ begin
45
+ stream = stream.to_s
46
+ eval "$#{stream} = StringIO.new"
47
+ yield
48
+ result = eval("$#{stream}").string
49
+ ensure
50
+ eval("$#{stream} = #{stream.upcase}")
51
+ end
52
+
53
+ result
54
+ end
55
+ end
@@ -0,0 +1,6 @@
1
+ #encoding: utf-8
2
+
3
+ #main TheArrayComparator
4
+ module TheArrayComparator
5
+ VERSION = '0.1.1'
6
+ end
@@ -0,0 +1,34 @@
1
+ #encoding: utf-8
2
+
3
+ require 'active_support/core_ext/object/blank'
4
+ require 'set'
5
+ require 'forwardable'
6
+
7
+ require 'the_array_comparator/version'
8
+ require 'the_array_comparator/exceptions'
9
+ require 'the_array_comparator/sample'
10
+ require 'the_array_comparator/check'
11
+ require 'the_array_comparator/result'
12
+ require 'the_array_comparator/strategies/base'
13
+ require 'the_array_comparator/strategies/contains_all_with_substring_search'
14
+ require 'the_array_comparator/strategies/contains_any_with_substring_search'
15
+ require 'the_array_comparator/strategies/contains_all'
16
+ require 'the_array_comparator/strategies/contains_any'
17
+ require 'the_array_comparator/strategies/contains_not_with_substring_search'
18
+ require 'the_array_comparator/strategies/contains_not'
19
+ require 'the_array_comparator/strategies/is_equal'
20
+ require 'the_array_comparator/strategies/is_not_equal'
21
+ require 'the_array_comparator/comparator'
22
+
23
+
24
+ # main module
25
+ module TheArrayComparator
26
+ Comparator.register :contains_all, Strategies::ContainsAll
27
+ Comparator.register :contains_any, Strategies::ContainsAny
28
+ Comparator.register :not_contains, Strategies::ContainsNot
29
+ Comparator.register :contains_all_as_substring, Strategies::ContainsAllWithSubstringSearch
30
+ Comparator.register :contains_any_as_substring, Strategies::ContainsAnyWithSubstringSearch
31
+ Comparator.register :not_contains_substring, Strategies::ContainsNotWithSubstringSearch
32
+ Comparator.register :is_equal, Strategies::IsEqual
33
+ Comparator.register :is_not_equal, Strategies::IsNotEqual
34
+ end
data/script/console ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.expand_path('../lib', File.dirname(__FILE__))
4
+
5
+ require 'the_array_comparator'
6
+ require 'pry'
7
+
8
+ Pry.start
data/script/terminal ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'tmrb'
4
+
5
+ tmux = TmRb::Multiplexer.new
6
+ #creates an empty window
7
+ tmux.new_session(session_name: 'the_array_comparator')
8
+
9
+ tmux.new_window(:name => 'code', :command => "zsh -c 'vim -p lib/**/*.rb'")
10
+ tmux.new_window(:name => 'spec', :command => "zsh -c 'vim -p spec/**/*.rb'")
11
+ tmux.new_window(:name => 'features', :command => "zsh -c 'vim -p features/**/*.{rb,feature}'")
12
+ tmux.start
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe "benchmark for strategies" do
5
+ let(:count_of_lines) { 100000 }
6
+
7
+ describe "strategy contains with substring search" do
8
+ let(:keywords) { %w{ab c d} }
9
+ let(:data) { generate_testdata(keywords: keywords, count_of_data: count_of_lines) }
10
+
11
+ it "is fast", :bm => true do
12
+ comparator = Strategies::ContainsWithSubstringSearch.add_check(data,keywords)
13
+ time_taken = Benchmark.realtime { comparator.success? }
14
+ expect(time_taken).to be < 1
15
+ end
16
+ end
17
+
18
+ describe "strategy contains" do
19
+ let(:keywords) { %w{a c d} }
20
+ let(:data) { generate_testdata(keywords: keywords, count_of_data: count_of_lines) }
21
+
22
+ it "is fast", :bm => true do
23
+ comparator = Strategies::Contains.add_check(data,keywords)
24
+ time_taken = Benchmark.realtime { comparator.success? }
25
+ expect(time_taken).to be < 1
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Check do
4
+ strategy_klass = Class.new do
5
+ def success?
6
+ true
7
+ end
8
+
9
+ def initialize(sample=nil)
10
+ end
11
+ end
12
+
13
+ sample_klass = Class.new do; end
14
+
15
+ it "add a sample and a comparator" do
16
+ Check.new(strategy_klass,sample_klass.new)
17
+ end
18
+
19
+ it "is true if the check is successfull" do
20
+ check = Check.new(strategy_klass,sample_klass.new)
21
+ result = check.success?
22
+ expect(result).to eq(true)
23
+ end
24
+
25
+ it "is able to return the sample of the check" do
26
+ sample = sample_klass.new
27
+ check = Check.new(strategy_klass,sample)
28
+ expect(check.sample).to eq(sample)
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ #enconding: utf-8
2
+ require 'spec_helper'
3
+ require 'strategies_helper'
4
+
5
+ describe Strategies::Base do
6
+
7
+ it "raise an exception if api is not implemented" do
8
+ class TestStrategy < Strategies::Base
9
+ end
10
+
11
+ expect {
12
+ test_strategy = TestStrategy.new
13
+ test_strategy.success?
14
+ }.to raise_error Exceptions::IncompatibleComparator
15
+ end
16
+ end