selector 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|