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.
- checksums.yaml +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +9 -0
- data/.metrics +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +20 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +7 -0
- data/Guardfile +14 -0
- data/LICENSE +21 -0
- data/README.md +147 -0
- data/Rakefile +27 -0
- data/config/metrics/STYLEGUIDE +230 -0
- data/config/metrics/cane.yml +5 -0
- data/config/metrics/churn.yml +6 -0
- data/config/metrics/flay.yml +2 -0
- data/config/metrics/metric_fu.yml +14 -0
- data/config/metrics/reek.yml +1 -0
- data/config/metrics/roodi.yml +24 -0
- data/config/metrics/rubocop.yml +72 -0
- data/config/metrics/saikuro.yml +3 -0
- data/config/metrics/simplecov.yml +6 -0
- data/config/metrics/yardstick.yml +37 -0
- data/lib/selector.rb +55 -0
- data/lib/selector/and.rb +64 -0
- data/lib/selector/anything.rb +30 -0
- data/lib/selector/array.rb +42 -0
- data/lib/selector/collection.rb +37 -0
- data/lib/selector/condition.rb +99 -0
- data/lib/selector/function.rb +36 -0
- data/lib/selector/not.rb +50 -0
- data/lib/selector/nothing.rb +30 -0
- data/lib/selector/or.rb +54 -0
- data/lib/selector/regexp.rb +49 -0
- data/lib/selector/version.rb +9 -0
- data/selector.gemspec +25 -0
- data/spec/integration/blacklist_spec.rb +33 -0
- data/spec/integration/composition_spec.rb +34 -0
- data/spec/integration/negation_spec.rb +13 -0
- data/spec/integration/whitelist_spec.rb +33 -0
- data/spec/shared/generator.rb +8 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/unit/selector/and_spec.rb +100 -0
- data/spec/unit/selector/anything_spec.rb +29 -0
- data/spec/unit/selector/array_spec.rb +76 -0
- data/spec/unit/selector/collection_spec.rb +48 -0
- data/spec/unit/selector/condition_spec.rb +135 -0
- data/spec/unit/selector/function_spec.rb +46 -0
- data/spec/unit/selector/not_spec.rb +61 -0
- data/spec/unit/selector/nothing_spec.rb +29 -0
- data/spec/unit/selector/or_spec.rb +88 -0
- data/spec/unit/selector/regexp_spec.rb +69 -0
- data/spec/unit/selector_spec.rb +148 -0
- metadata +145 -0
@@ -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,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
|
data/lib/selector/and.rb
ADDED
@@ -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
|