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,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Selector
|
4
|
+
|
5
|
+
describe Selector::Anything do
|
6
|
+
|
7
|
+
let(:anything) { described_class.instance }
|
8
|
+
|
9
|
+
describe ".instance" do
|
10
|
+
|
11
|
+
subject { anything }
|
12
|
+
|
13
|
+
it { is_expected.to be_kind_of Condition }
|
14
|
+
it { is_expected.to be_kind_of Singleton }
|
15
|
+
it { is_expected.to be_frozen }
|
16
|
+
|
17
|
+
end # describe .instance
|
18
|
+
|
19
|
+
describe "#[]" do
|
20
|
+
|
21
|
+
subject { anything[:foo] }
|
22
|
+
|
23
|
+
it { is_expected.to eql(true) }
|
24
|
+
|
25
|
+
end # describe #[]
|
26
|
+
|
27
|
+
end # describe Selector::Anything
|
28
|
+
|
29
|
+
end # module Selector
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Selector
|
4
|
+
|
5
|
+
describe Selector::Array do
|
6
|
+
|
7
|
+
let(:left) { described_class.new [:foo, :bar] }
|
8
|
+
let(:right) { described_class.new [:bar, :baz] }
|
9
|
+
|
10
|
+
describe ".new" do
|
11
|
+
|
12
|
+
subject { left }
|
13
|
+
|
14
|
+
it { is_expected.to be_kind_of Collection }
|
15
|
+
|
16
|
+
it { is_expected.to be_frozen }
|
17
|
+
|
18
|
+
it "sets the attribute" do
|
19
|
+
expect(subject.attribute).to eql(Set.new [:foo, :bar])
|
20
|
+
end
|
21
|
+
|
22
|
+
end # describe .new
|
23
|
+
|
24
|
+
describe "#&" do
|
25
|
+
|
26
|
+
subject { left & right }
|
27
|
+
|
28
|
+
context "array" do
|
29
|
+
|
30
|
+
it "returns the array" do
|
31
|
+
expect(subject).to be_kind_of described_class
|
32
|
+
end
|
33
|
+
|
34
|
+
it "composes the attributes" do
|
35
|
+
expect(subject.attribute).to eql(Set.new [:bar])
|
36
|
+
end
|
37
|
+
|
38
|
+
end # context
|
39
|
+
|
40
|
+
context "non-array" do
|
41
|
+
|
42
|
+
let(:right) { Condition.new }
|
43
|
+
it { is_expected.to be_kind_of(And) }
|
44
|
+
|
45
|
+
end # context
|
46
|
+
|
47
|
+
end # describe #&
|
48
|
+
|
49
|
+
describe "#|" do
|
50
|
+
|
51
|
+
subject { left | right }
|
52
|
+
|
53
|
+
context "array" do
|
54
|
+
|
55
|
+
it "returns the array" do
|
56
|
+
expect(subject).to be_kind_of described_class
|
57
|
+
end
|
58
|
+
|
59
|
+
it "composes the attributes" do
|
60
|
+
expect(subject.attribute).to eql(Set.new [:foo, :bar, :baz])
|
61
|
+
end
|
62
|
+
|
63
|
+
end # context
|
64
|
+
|
65
|
+
context "non-array" do
|
66
|
+
|
67
|
+
let(:right) { Condition.new }
|
68
|
+
it { is_expected.to be_kind_of(Or) }
|
69
|
+
|
70
|
+
end # context
|
71
|
+
|
72
|
+
end # describe #&
|
73
|
+
|
74
|
+
end # describe Selector::Array
|
75
|
+
|
76
|
+
end # module Selector
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Selector
|
4
|
+
|
5
|
+
describe Selector::Collection do
|
6
|
+
|
7
|
+
let(:collection) { described_class.new set }
|
8
|
+
let(:set) { Set.new [:foo, :bar] }
|
9
|
+
|
10
|
+
describe ".new" do
|
11
|
+
|
12
|
+
subject { collection }
|
13
|
+
|
14
|
+
it { is_expected.to be_kind_of Condition }
|
15
|
+
it { is_expected.to be_frozen }
|
16
|
+
|
17
|
+
it "requires exactly 1 argument" do
|
18
|
+
expect(collection.attribute).to eql(set)
|
19
|
+
expect { described_class.new }.to raise_error ArgumentError
|
20
|
+
expect { described_class.new [:foo], [:bar] }
|
21
|
+
.to raise_error ArgumentError
|
22
|
+
end
|
23
|
+
|
24
|
+
end # describe .new
|
25
|
+
|
26
|
+
describe "#[]" do
|
27
|
+
|
28
|
+
subject { collection[value] }
|
29
|
+
|
30
|
+
context "existing value" do
|
31
|
+
|
32
|
+
let(:value) { :foo }
|
33
|
+
it { is_expected.to eql(true) }
|
34
|
+
|
35
|
+
end # context
|
36
|
+
|
37
|
+
context "absent value" do
|
38
|
+
|
39
|
+
let(:value) { :baz }
|
40
|
+
it { is_expected.to eql(false) }
|
41
|
+
|
42
|
+
end # context
|
43
|
+
|
44
|
+
end # describe #[]
|
45
|
+
|
46
|
+
end # describe Selector::Collection
|
47
|
+
|
48
|
+
end # module Selector
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Selector
|
4
|
+
|
5
|
+
describe Selector::Condition do
|
6
|
+
|
7
|
+
let(:test_klass) { Class.new(described_class) }
|
8
|
+
let(:attributes) { 2.times.map { double(freeze: true) } }
|
9
|
+
let(:condition) { test_klass.new(*attributes) }
|
10
|
+
let(:other) { test_klass.new }
|
11
|
+
|
12
|
+
describe ".new" do
|
13
|
+
|
14
|
+
subject { condition }
|
15
|
+
|
16
|
+
it { is_expected.to be_kind_of Comparable }
|
17
|
+
it { is_expected.to be_frozen }
|
18
|
+
|
19
|
+
it "doesn't freeze attributes" do
|
20
|
+
expect { subject }.not_to change { attributes.frozen? }
|
21
|
+
end
|
22
|
+
|
23
|
+
end # describe .new
|
24
|
+
|
25
|
+
describe "#attributes" do
|
26
|
+
|
27
|
+
subject { condition.attributes }
|
28
|
+
|
29
|
+
it { is_expected.to eql attributes }
|
30
|
+
it { is_expected.to be_frozen }
|
31
|
+
|
32
|
+
context "by default" do
|
33
|
+
|
34
|
+
let(:condition) { test_klass.new }
|
35
|
+
it { is_expected.to eql [] }
|
36
|
+
|
37
|
+
end # context
|
38
|
+
|
39
|
+
end # describe #attributes
|
40
|
+
|
41
|
+
describe "#attribute" do
|
42
|
+
|
43
|
+
subject { condition.attribute }
|
44
|
+
it { is_expected.to eql attributes.first }
|
45
|
+
|
46
|
+
end # describe #attribute
|
47
|
+
|
48
|
+
describe "#==" do
|
49
|
+
|
50
|
+
subject { condition == other }
|
51
|
+
|
52
|
+
let(:other) { test_klass.new(*attributes) }
|
53
|
+
|
54
|
+
context "with the same type and attributes" do
|
55
|
+
|
56
|
+
it { is_expected.to eql(true) }
|
57
|
+
|
58
|
+
end # context
|
59
|
+
|
60
|
+
context "with other attributes" do
|
61
|
+
|
62
|
+
let(:other) { test_klass.new }
|
63
|
+
it { is_expected.to eql(false) }
|
64
|
+
|
65
|
+
end # context
|
66
|
+
|
67
|
+
context "with another type" do
|
68
|
+
|
69
|
+
let(:other) { described_class.new(*attributes) }
|
70
|
+
it { is_expected.to eql(false) }
|
71
|
+
|
72
|
+
end # context
|
73
|
+
|
74
|
+
end # describe #==
|
75
|
+
|
76
|
+
describe "#[]" do
|
77
|
+
|
78
|
+
subject { condition[:foo] }
|
79
|
+
|
80
|
+
it "should be implemented" do
|
81
|
+
expect { subject }.to raise_error do |error|
|
82
|
+
expect(error).to be_kind_of NotImplementedError
|
83
|
+
expect(error.message).to eql "#{test_klass}#[] not implemented"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end # describe #[]
|
88
|
+
|
89
|
+
describe "#!" do
|
90
|
+
|
91
|
+
subject { !condition }
|
92
|
+
|
93
|
+
it "returns the inversion" do
|
94
|
+
expect(subject).to be_kind_of Not
|
95
|
+
expect(subject.attributes).to eql [condition]
|
96
|
+
end
|
97
|
+
|
98
|
+
end # describe #!
|
99
|
+
|
100
|
+
describe "#&" do
|
101
|
+
|
102
|
+
subject { condition & other }
|
103
|
+
|
104
|
+
it "creates composition" do
|
105
|
+
expect(subject).to be_kind_of(And)
|
106
|
+
expect(subject.attributes).to contain_exactly(condition, other)
|
107
|
+
end
|
108
|
+
|
109
|
+
end # describe #&
|
110
|
+
|
111
|
+
describe "#-" do
|
112
|
+
|
113
|
+
subject { condition - other }
|
114
|
+
|
115
|
+
it "creates composition" do
|
116
|
+
expect(subject).to be_kind_of(And)
|
117
|
+
expect(subject.attributes).to contain_exactly(condition, !other)
|
118
|
+
end
|
119
|
+
|
120
|
+
end # describe #
|
121
|
+
|
122
|
+
describe "#|" do
|
123
|
+
|
124
|
+
subject { condition | other }
|
125
|
+
|
126
|
+
it "creates composition" do
|
127
|
+
expect(subject).to be_kind_of(Or)
|
128
|
+
expect(subject.attributes).to contain_exactly(condition, other)
|
129
|
+
end
|
130
|
+
|
131
|
+
end # describe #|
|
132
|
+
|
133
|
+
end # describe Selector::Condition
|
134
|
+
|
135
|
+
end # module Selector
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Selector
|
4
|
+
|
5
|
+
describe Selector::Function do
|
6
|
+
|
7
|
+
let(:function) { described_class.new -> v { v[/foo/] } }
|
8
|
+
|
9
|
+
describe ".new" do
|
10
|
+
|
11
|
+
subject { function }
|
12
|
+
|
13
|
+
it { is_expected.to be_kind_of Condition }
|
14
|
+
it { is_expected.to be_frozen }
|
15
|
+
|
16
|
+
it "requires exactly 1 argument" do
|
17
|
+
expect { described_class.new }.to raise_error ArgumentError
|
18
|
+
expect { described_class.new [:foo], [:bar] }
|
19
|
+
.to raise_error ArgumentError
|
20
|
+
end
|
21
|
+
|
22
|
+
end # describe .new
|
23
|
+
|
24
|
+
describe "#[]" do
|
25
|
+
|
26
|
+
subject { function[value] }
|
27
|
+
|
28
|
+
context "existing value" do
|
29
|
+
|
30
|
+
let(:value) { :foo }
|
31
|
+
it { is_expected.to eql(true) }
|
32
|
+
|
33
|
+
end # context
|
34
|
+
|
35
|
+
context "absent value" do
|
36
|
+
|
37
|
+
let(:value) { :baz }
|
38
|
+
it { is_expected.to eql(false) }
|
39
|
+
|
40
|
+
end # context
|
41
|
+
|
42
|
+
end # describe #[]
|
43
|
+
|
44
|
+
end # describe Selector::Function
|
45
|
+
|
46
|
+
end # module Selector
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Selector
|
4
|
+
|
5
|
+
describe Selector::Not do
|
6
|
+
|
7
|
+
let(:inversion) { described_class.new condition }
|
8
|
+
let(:condition) do
|
9
|
+
result = double freeze: true
|
10
|
+
allow(result).to receive(:[]) { |value| value == :foo }
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
describe ".new" do
|
15
|
+
|
16
|
+
subject { inversion }
|
17
|
+
|
18
|
+
it { is_expected.to be_kind_of Condition }
|
19
|
+
it { is_expected.to be_frozen }
|
20
|
+
|
21
|
+
context "ANYTHING" do
|
22
|
+
|
23
|
+
let(:condition) { ANYTHING }
|
24
|
+
it { is_expected.to eql NOTHING }
|
25
|
+
|
26
|
+
end # context
|
27
|
+
|
28
|
+
context "NOTHING" do
|
29
|
+
|
30
|
+
let(:condition) { NOTHING }
|
31
|
+
it { is_expected.to eql ANYTHING }
|
32
|
+
|
33
|
+
end # context
|
34
|
+
|
35
|
+
context "other" do
|
36
|
+
|
37
|
+
it { is_expected.to be_kind_of described_class }
|
38
|
+
|
39
|
+
end # context
|
40
|
+
|
41
|
+
end # describe .new
|
42
|
+
|
43
|
+
describe "#[]" do
|
44
|
+
|
45
|
+
it "inverts the condition" do
|
46
|
+
expect(inversion[:foo]).to eql(false)
|
47
|
+
expect(inversion[:bar]).to eql(true)
|
48
|
+
end
|
49
|
+
|
50
|
+
end # describe #[]
|
51
|
+
|
52
|
+
describe "#!" do
|
53
|
+
|
54
|
+
subject { !inversion }
|
55
|
+
it { is_expected.to equal condition }
|
56
|
+
|
57
|
+
end # describe #!
|
58
|
+
|
59
|
+
end # describe Selector::Not
|
60
|
+
|
61
|
+
end # module Selector
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Selector
|
4
|
+
|
5
|
+
describe Selector::Nothing do
|
6
|
+
|
7
|
+
let(:nothing) { described_class.instance }
|
8
|
+
|
9
|
+
describe ".instance" do
|
10
|
+
|
11
|
+
subject { nothing }
|
12
|
+
|
13
|
+
it { is_expected.to be_kind_of Condition }
|
14
|
+
it { is_expected.to be_kind_of Singleton }
|
15
|
+
it { is_expected.to be_frozen }
|
16
|
+
|
17
|
+
end # describe .instance
|
18
|
+
|
19
|
+
describe "#[]" do
|
20
|
+
|
21
|
+
subject { nothing[:foo] }
|
22
|
+
|
23
|
+
it { is_expected.to eql(false) }
|
24
|
+
|
25
|
+
end # describe #[]
|
26
|
+
|
27
|
+
end # describe Selector::Nothing
|
28
|
+
|
29
|
+
end # module Selector
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "shared/generator"
|
4
|
+
|
5
|
+
module Selector
|
6
|
+
|
7
|
+
describe Selector::Or do
|
8
|
+
|
9
|
+
let(:foo) { generate(/foo/) }
|
10
|
+
let(:bar) { generate(/bar/) }
|
11
|
+
let(:baz) { generate(/baz/) }
|
12
|
+
|
13
|
+
let(:composition) { described_class.new(foo, bar) }
|
14
|
+
|
15
|
+
describe ".new" do
|
16
|
+
|
17
|
+
subject { composition }
|
18
|
+
|
19
|
+
it { is_expected.to be_kind_of Condition }
|
20
|
+
it { is_expected.to be_frozen }
|
21
|
+
|
22
|
+
it "returns NOTHING when possible" do
|
23
|
+
subject = described_class.new NOTHING
|
24
|
+
expect(subject).to eql NOTHING
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns ANYTHING if exists" do
|
28
|
+
subject = described_class.new foo, bar, ANYTHING
|
29
|
+
expect(subject).to eql ANYTHING
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns ANYTHING when possible" do
|
33
|
+
subject = described_class.new foo, !foo
|
34
|
+
expect(subject).to eql ANYTHING
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns the only attribute" do
|
38
|
+
subject = described_class.new foo, NOTHING
|
39
|
+
expect(subject).to eql foo
|
40
|
+
end
|
41
|
+
|
42
|
+
it "ignores duplication" do
|
43
|
+
subject = described_class.new foo, bar, foo
|
44
|
+
expect(subject.attributes).to eql [foo, bar]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "ignores NOTHING" do
|
48
|
+
subject = described_class.new foo, bar, NOTHING
|
49
|
+
expect(subject.attributes).to eql [foo, bar]
|
50
|
+
end
|
51
|
+
|
52
|
+
end # describe .new
|
53
|
+
|
54
|
+
describe "#[]" do
|
55
|
+
|
56
|
+
subject { composition[value] }
|
57
|
+
|
58
|
+
context "when any of the conditions is satisfied" do
|
59
|
+
|
60
|
+
let(:value) { "foo" }
|
61
|
+
it { is_expected.to eql(true) }
|
62
|
+
|
63
|
+
end # context
|
64
|
+
|
65
|
+
context "when all conditions aren't satisfied" do
|
66
|
+
|
67
|
+
let(:value) { "baz" }
|
68
|
+
it { is_expected.to eql(false) }
|
69
|
+
|
70
|
+
end # context
|
71
|
+
|
72
|
+
end # describe #[]
|
73
|
+
|
74
|
+
describe "#|" do
|
75
|
+
|
76
|
+
subject { composition | baz }
|
77
|
+
|
78
|
+
it { is_expected.to be_kind_of(described_class) }
|
79
|
+
|
80
|
+
it "updates conditions (avoids nesting)" do
|
81
|
+
expect(subject.attributes).to eql [foo, bar, baz]
|
82
|
+
end
|
83
|
+
|
84
|
+
end # describe #|
|
85
|
+
|
86
|
+
end # describe Selector::Or
|
87
|
+
|
88
|
+
end # module Selector
|