selector 0.0.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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +9 -0
  4. data/.metrics +9 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +2 -0
  7. data/.travis.yml +20 -0
  8. data/.yardopts +3 -0
  9. data/CHANGELOG.md +5 -0
  10. data/Gemfile +7 -0
  11. data/Guardfile +14 -0
  12. data/LICENSE +21 -0
  13. data/README.md +147 -0
  14. data/Rakefile +27 -0
  15. data/config/metrics/STYLEGUIDE +230 -0
  16. data/config/metrics/cane.yml +5 -0
  17. data/config/metrics/churn.yml +6 -0
  18. data/config/metrics/flay.yml +2 -0
  19. data/config/metrics/metric_fu.yml +14 -0
  20. data/config/metrics/reek.yml +1 -0
  21. data/config/metrics/roodi.yml +24 -0
  22. data/config/metrics/rubocop.yml +72 -0
  23. data/config/metrics/saikuro.yml +3 -0
  24. data/config/metrics/simplecov.yml +6 -0
  25. data/config/metrics/yardstick.yml +37 -0
  26. data/lib/selector.rb +55 -0
  27. data/lib/selector/and.rb +64 -0
  28. data/lib/selector/anything.rb +30 -0
  29. data/lib/selector/array.rb +42 -0
  30. data/lib/selector/collection.rb +37 -0
  31. data/lib/selector/condition.rb +99 -0
  32. data/lib/selector/function.rb +36 -0
  33. data/lib/selector/not.rb +50 -0
  34. data/lib/selector/nothing.rb +30 -0
  35. data/lib/selector/or.rb +54 -0
  36. data/lib/selector/regexp.rb +49 -0
  37. data/lib/selector/version.rb +9 -0
  38. data/selector.gemspec +25 -0
  39. data/spec/integration/blacklist_spec.rb +33 -0
  40. data/spec/integration/composition_spec.rb +34 -0
  41. data/spec/integration/negation_spec.rb +13 -0
  42. data/spec/integration/whitelist_spec.rb +33 -0
  43. data/spec/shared/generator.rb +8 -0
  44. data/spec/spec_helper.rb +12 -0
  45. data/spec/unit/selector/and_spec.rb +100 -0
  46. data/spec/unit/selector/anything_spec.rb +29 -0
  47. data/spec/unit/selector/array_spec.rb +76 -0
  48. data/spec/unit/selector/collection_spec.rb +48 -0
  49. data/spec/unit/selector/condition_spec.rb +135 -0
  50. data/spec/unit/selector/function_spec.rb +46 -0
  51. data/spec/unit/selector/not_spec.rb +61 -0
  52. data/spec/unit/selector/nothing_spec.rb +29 -0
  53. data/spec/unit/selector/or_spec.rb +88 -0
  54. data/spec/unit/selector/regexp_spec.rb +69 -0
  55. data/spec/unit/selector_spec.rb +148 -0
  56. metadata +145 -0
@@ -0,0 +1,5 @@
1
+ ---
2
+ abc_max: "10"
3
+ line_length: "80"
4
+ no_doc: "y"
5
+ no_readme: "y"
@@ -0,0 +1,6 @@
1
+ ---
2
+ ignore_files:
3
+ - spec
4
+ - config
5
+ minimum_churn_count: 0
6
+ start_date: "1 year ago"
@@ -0,0 +1,2 @@
1
+ ---
2
+ minimum_score: 5
@@ -0,0 +1,14 @@
1
+ ---
2
+ folders: # The list of folders to be used by any metric.
3
+ - lib
4
+ metrics: # The list of allowed metrics. The other metrics are disabled.
5
+ - cane
6
+ - churn
7
+ - flay
8
+ - flog
9
+ - reek
10
+ - roodi
11
+ - saikuro
12
+ format: html
13
+ output: tmp/metric_fu
14
+ verbose: false
@@ -0,0 +1 @@
1
+ ---
@@ -0,0 +1,24 @@
1
+ ---
2
+ AssignmentInConditionalCheck:
3
+ CaseMissingElseCheck:
4
+ ClassLineCountCheck:
5
+ line_count: 100
6
+ ClassNameCheck:
7
+ pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/
8
+ ClassVariableCheck:
9
+ CyclomaticComplexityBlockCheck:
10
+ complexity: 2
11
+ CyclomaticComplexityMethodCheck:
12
+ complexity: 3
13
+ EmptyRescueBodyCheck:
14
+ ForLoopCheck:
15
+ MethodLineCountCheck:
16
+ line_count: 6
17
+ MethodNameCheck:
18
+ pattern: !ruby/regexp /^[\||\^|\&|\!]$|^[_a-z<>=\[|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/
19
+ ModuleLineCountCheck:
20
+ line_count: 100
21
+ ModuleNameCheck:
22
+ pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/
23
+ ParameterNumberCheck:
24
+ parameter_count: 4
@@ -0,0 +1,72 @@
1
+ ---
2
+ # settings added by the 'hexx-suit' module
3
+ # output: "tmp/rubocop"
4
+ # format: "html"
5
+
6
+ AllCops:
7
+ Exclude:
8
+ - '**/db/schema.rb'
9
+
10
+ Lint/HandleExceptions:
11
+ Exclude:
12
+ - '**/*_spec.rb'
13
+
14
+ Lint/RescueException:
15
+ Exclude:
16
+ - '**/*_spec.rb'
17
+
18
+ Style/AccessorMethodName:
19
+ Exclude:
20
+ - '**/*_spec.rb'
21
+
22
+ Style/AsciiComments:
23
+ Enabled: false
24
+
25
+ Style/ClassAndModuleChildren:
26
+ Enabled: false
27
+
28
+ Style/Documentation:
29
+ Enabled: false
30
+
31
+ Style/EmptyLinesAroundBlockBody:
32
+ Enabled: false
33
+
34
+ Style/EmptyLinesAroundClassBody:
35
+ Enabled: false
36
+
37
+ Style/EmptyLinesAroundMethodBody:
38
+ Enabled: false
39
+
40
+ Style/EmptyLinesAroundModuleBody:
41
+ Enabled: false
42
+
43
+ Style/EmptyLineBetweenDefs:
44
+ Enabled: false
45
+
46
+ Style/FileName:
47
+ Enabled: false
48
+
49
+ Style/RaiseArgs:
50
+ EnforcedStyle: compact
51
+
52
+ Style/SingleLineMethods:
53
+ Exclude:
54
+ - '**/*_spec.rb'
55
+
56
+ Style/SingleSpaceBeforeFirstArg:
57
+ Enabled: false
58
+
59
+ Style/SpecialGlobalVars:
60
+ Exclude:
61
+ - '**/Gemfile'
62
+ - '**/*.gemspec'
63
+
64
+ Style/StringLiterals:
65
+ EnforcedStyle: double_quotes
66
+
67
+ Style/StringLiteralsInInterpolation:
68
+ EnforcedStyle: double_quotes
69
+
70
+ Style/TrivialAccessors:
71
+ Exclude:
72
+ - '**/*_spec.rb'
@@ -0,0 +1,3 @@
1
+ ---
2
+ warn_cyclo: 4
3
+ error_cyclo: 6
@@ -0,0 +1,6 @@
1
+ ---
2
+ output: tmp/coverage
3
+ filters: # The list of paths to be excluded from coverage checkup
4
+ - "spec/"
5
+ - "config/"
6
+ groups: []
@@ -0,0 +1,37 @@
1
+ ---
2
+ # Settings added by the 'hexx-suit' gem
3
+ output: "tmp/yardstick/output.log"
4
+ path: "lib/**/*.rb"
5
+ rules:
6
+ ApiTag::Presence:
7
+ enabled: true
8
+ exclude: []
9
+ ApiTag::Inclusion:
10
+ enabled: true
11
+ exclude: []
12
+ ApiTag::ProtectedMethod:
13
+ enabled: true
14
+ exclude: []
15
+ ApiTag::PrivateMethod:
16
+ enabled: false
17
+ exclude: []
18
+ ExampleTag:
19
+ enabled: true
20
+ exclude: []
21
+ ReturnTag:
22
+ enabled: true
23
+ exclude: []
24
+ Summary::Presence:
25
+ enabled: true
26
+ exclude: []
27
+ Summary::Length:
28
+ enabled: true
29
+ exclude: []
30
+ Summary::Delimiter:
31
+ enabled: true
32
+ exclude: []
33
+ Summary::SingleLine:
34
+ enabled: true
35
+ exclude: []
36
+ threshold: 100
37
+ verbose: false
data/lib/selector.rb ADDED
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+
3
+ require "ice_nine"
4
+ require "singleton"
5
+
6
+ require_relative "selector/condition"
7
+ require_relative "selector/anything"
8
+ require_relative "selector/nothing"
9
+
10
+ require_relative "selector/not"
11
+ require_relative "selector/and"
12
+ require_relative "selector/or"
13
+
14
+ require_relative "selector/collection"
15
+ require_relative "selector/array"
16
+ require_relative "selector/regexp"
17
+ require_relative "selector/function"
18
+
19
+ # Composable filters for lists of values
20
+ #
21
+ module Selector
22
+
23
+ # Creates a condition from options
24
+ #
25
+ # @param [Hash] options
26
+ #
27
+ # @return [Selector::Condition]
28
+ #
29
+ def self.new(options)
30
+ white = options.fetch(:only) { ANYTHING }
31
+ black = options.fetch(:except) { NOTHING }
32
+ build(white) - build(black)
33
+ end
34
+
35
+ # Factory method that builds a condition instance depending on argument type
36
+ #
37
+ # @param [Object] clause
38
+ #
39
+ # @return [Selector::Condition]
40
+ #
41
+ def self.build(clause)
42
+ return clause if [ANYTHING, NOTHING].include? clause
43
+ return Regexp.new(clause) if clause.instance_of? ::Regexp
44
+ return Array.new(clause) if [::Array, Set].include? clause.class
45
+ return Collection.new(clause) if clause.is_a? Enumerable
46
+ return Function.new(clause) if clause.respond_to? :call
47
+ Array.new [clause]
48
+ end
49
+
50
+ private # for yard
51
+
52
+ ANYTHING = Anything.instance
53
+ NOTHING = Nothing.instance
54
+
55
+ end # module Selector
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+
3
+ module Selector
4
+
5
+ # The composition of several conditions. Requires each of them to be satisfied
6
+ #
7
+ # @example (see #[])
8
+ #
9
+ class And < Condition
10
+
11
+ # @private
12
+ def self.new(*attributes)
13
+ attrs = attributes.uniq - [ANYTHING]
14
+
15
+ return ANYTHING if attrs.empty?
16
+ return attrs.first if attrs.count.equal?(1)
17
+ return NOTHING if attrs.include? NOTHING
18
+ return NOTHING if (attrs & attrs.map(&:!)).any?
19
+
20
+ super(*attrs)
21
+ end
22
+
23
+ # Checks if value satisfies each of composed conditions
24
+ #
25
+ # @example
26
+ # left = Selector.new only: /foo/
27
+ # right = Selector.new only: /bar/
28
+ # composition = Selector::And.new(left, right)
29
+ #
30
+ # composition[:foo] # => false
31
+ # composition[:bar] # => false
32
+ # composition[:foobar] # => true
33
+ #
34
+ # @param (see Selector::Composition#[])
35
+ #
36
+ # @return (see Selector::Composition#[])
37
+ #
38
+ def [](value)
39
+ attributes.detect { |part| !part[value] } ? false : true
40
+ end
41
+
42
+ # Adds the other condition to the composition (avoids nesting)
43
+ #
44
+ # @param (see Selector::Composition#&)
45
+ #
46
+ # @return (see Selector::Composition#&)
47
+ #
48
+ def &(other)
49
+ And.new(*attributes, other)
50
+ end
51
+
52
+ # Adds inversion of the other condition to the composition (avoids nesting)
53
+ #
54
+ # @param (see Selector::Composition#-)
55
+ #
56
+ # @return (see Selector::Composition#-)
57
+ #
58
+ def -(other)
59
+ And.new(*attributes, !other)
60
+ end
61
+
62
+ end # class And
63
+
64
+ end # module Selector
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ module Selector
4
+
5
+ # The condition that accepts any value
6
+ #
7
+ # @example (see #[])
8
+ #
9
+ class Anything < Condition
10
+
11
+ include Singleton
12
+
13
+ # @!method [](value)
14
+ # Returns true
15
+ #
16
+ # @example
17
+ # condition = Selector::Anything.instance # singleton
18
+ # condition[:foo] # => true
19
+ #
20
+ # @param (see Selector::Condition#[])
21
+ #
22
+ # @return [true]
23
+ #
24
+ def [](_value)
25
+ true
26
+ end
27
+
28
+ end # class Anything
29
+
30
+ end # module Selector
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ module Selector
4
+
5
+ # The condition checks if a value is included to the array
6
+ #
7
+ class Array < Collection
8
+
9
+ # @private
10
+ def initialize(array)
11
+ super Set.new(array)
12
+ end
13
+
14
+ # Creates an AND composition
15
+ #
16
+ # If other value is a array, then creates modified array to avoid nesting
17
+ #
18
+ # @param (see Selector::Composition#&)
19
+ #
20
+ # @return (see Selector::Composition#&)
21
+ #
22
+ def &(other)
23
+ return super unless other.instance_of? self.class
24
+ self.class.new attribute & other.attribute
25
+ end
26
+
27
+ # Creates an OR composition
28
+ #
29
+ # If other value is a array, then creates modified array to avoid nesting
30
+ #
31
+ # @param (see Selector::Composition#|)
32
+ #
33
+ # @return (see Selector::Composition#|)
34
+ #
35
+ def |(other)
36
+ return super unless other.instance_of? self.class
37
+ self.class.new attribute | other.attribute
38
+ end
39
+
40
+ end # class Array
41
+
42
+ end # module Selector
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ module Selector
4
+
5
+ # The condition checks if a value is included to the collection
6
+ #
7
+ # @example (see #[])
8
+ #
9
+ class Collection < Condition
10
+
11
+ # @!method initialize(collection)
12
+ # Initializes the condition with a collection of allowed values
13
+ #
14
+ # @param [Enumerable] collection
15
+ #
16
+ def initialize(_)
17
+ super
18
+ end
19
+
20
+ # Checks if the array includes the value
21
+ #
22
+ # @example
23
+ # condition = Set.new [:foo, :bar]
24
+ # condition[:foo] # => true
25
+ # condition[:baz] # => false
26
+ #
27
+ # @param (see Selector::Condition#[])
28
+ #
29
+ # @return (see Selector::Condition#[])
30
+ #
31
+ def [](value)
32
+ attribute.include? value
33
+ end
34
+
35
+ end # class Collection
36
+
37
+ end # module Selector
@@ -0,0 +1,99 @@
1
+ # encoding: utf-8
2
+
3
+ module Selector
4
+
5
+ # Describe an immutable condition for selecting values
6
+ #
7
+ class Condition
8
+
9
+ include Comparable
10
+
11
+ # @!attribute [r] attributes
12
+ #
13
+ # @return [Array] The array of initialized attributes
14
+ #
15
+ attr_reader :attributes
16
+
17
+ # The first attribute
18
+ #
19
+ # @return [Object]
20
+ #
21
+ def attribute
22
+ attributes.first
23
+ end
24
+
25
+ # @private
26
+ def initialize(*attributes)
27
+ @attributes = attributes
28
+ IceNine.deep_freeze(self)
29
+ end
30
+
31
+ # Compares the condition to the other object by type and attributes
32
+ #
33
+ # @param [Object] other
34
+ #
35
+ # @return [Boolean]
36
+ #
37
+ def ==(other)
38
+ other.instance_of?(self.class) && attributes.eql?(other.attributes)
39
+ end
40
+
41
+ # @!method [](value)
42
+ # Checks if the value satisfies the condtion
43
+ #
44
+ # @param [Object] value
45
+ #
46
+ # @return [Boolean]
47
+ #
48
+ # @abstract
49
+ # @raise [NotImplementedError] by default
50
+ #
51
+ def [](_value)
52
+ fail NotImplementedError.new "#{self.class}#[] not implemented"
53
+ end
54
+
55
+ # Inverts the condition
56
+ #
57
+ # @return [Selector::Condition]
58
+ #
59
+ def !
60
+ Not.new(self)
61
+ end
62
+
63
+ # Composes (by AND) the condition to the other condition
64
+ #
65
+ # @param [Selector::Condition] other
66
+ #
67
+ # @return [Selector::Condition]
68
+ #
69
+ def &(other)
70
+ And.new(self, other)
71
+ end
72
+
73
+ # Composes (by AND) the condition to inversion of the other condition
74
+ #
75
+ # This is the same as `&(!other)`
76
+ #
77
+ # @param [Selector::Condition] other
78
+ #
79
+ # @return [Selector::Condition]
80
+ #
81
+ def -(other)
82
+ And.new(self, !other)
83
+ end
84
+
85
+ # Composes (by OR) the condition to the other condition
86
+ #
87
+ # This is the same as `!((!self)&(!other))`
88
+ #
89
+ # @param [Selector::Condition] other
90
+ #
91
+ # @return [Selector::Condition]
92
+ #
93
+ def |(other)
94
+ Or.new(self, other)
95
+ end
96
+
97
+ end # class Condition
98
+
99
+ end # module Selector