eapi 0.1.2 → 0.2.0
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 +4 -4
- data/.travis.yml +1 -2
- data/README.md +85 -26
- data/eapi.gemspec +1 -0
- data/lib/eapi.rb +7 -2
- data/lib/eapi/common.rb +11 -28
- data/lib/eapi/definition_runners.rb +3 -0
- data/lib/eapi/definition_runners/list.rb +60 -0
- data/lib/eapi/definition_runners/property.rb +100 -0
- data/lib/eapi/definition_runners/runner.rb +44 -0
- data/lib/eapi/item.rb +31 -0
- data/lib/eapi/list.rb +145 -0
- data/lib/eapi/methods/accessor.rb +1 -23
- data/lib/eapi/methods/properties.rb +47 -12
- data/lib/eapi/{multiple.rb → multiple_value.rb} +1 -1
- data/lib/eapi/version.rb +1 -1
- data/spec/basic_spec.rb +36 -35
- data/spec/definition_spec.rb +1 -1
- data/spec/extension_spec.rb +2 -2
- data/spec/function_spec.rb +70 -41
- data/spec/list_elements_spec.rb +123 -0
- data/spec/list_spec.rb +378 -81
- data/spec/to_h_spec.rb +1 -1
- data/spec/type_spec.rb +2 -2
- data/spec/validations_spec.rb +8 -8
- metadata +25 -4
- data/lib/eapi/definition_runner.rb +0 -109
data/spec/basic_spec.rb
CHANGED
@@ -4,55 +4,56 @@ RSpec.describe Eapi do
|
|
4
4
|
|
5
5
|
context 'basic behaviour' do
|
6
6
|
class MyTestKlass
|
7
|
-
include Eapi::
|
8
|
-
|
7
|
+
include Eapi::Item
|
9
8
|
property :something
|
10
9
|
end
|
11
10
|
|
12
|
-
describe
|
13
|
-
describe '#something
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
describe MyTestKlass do
|
12
|
+
describe '#something (fluent setter/getter)' do
|
13
|
+
describe '#something as getter' do
|
14
|
+
it 'return the value' do
|
15
|
+
eapi = described_class.new something: :hey
|
16
|
+
expect(eapi.something).to eq :hey
|
17
|
+
end
|
17
18
|
end
|
18
|
-
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
describe '#something("val")' do
|
21
|
+
it 'set the value and return self' do
|
22
|
+
eapi = described_class.new something: :hey
|
23
|
+
res = eapi.something :other
|
24
|
+
expect(eapi).to be res
|
25
|
+
expect(eapi.something).to eq :other
|
26
|
+
end
|
26
27
|
end
|
27
|
-
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
describe '#set_something("val")' do
|
30
|
+
it 'set the value and return self' do
|
31
|
+
eapi = described_class.new something: :hey
|
32
|
+
res = eapi.set_something :other
|
33
|
+
expect(eapi).to be res
|
34
|
+
expect(eapi.something).to eq :other
|
35
|
+
end
|
35
36
|
end
|
36
37
|
end
|
37
|
-
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
describe '#get' do
|
40
|
+
it 'will use the getter' do
|
41
|
+
eapi = described_class.new something: :hey
|
42
|
+
expect(eapi.get(:something)).to eq :hey
|
43
|
+
expect(eapi.get('something')).to eq :hey
|
44
|
+
end
|
45
45
|
|
46
|
-
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
48
|
+
describe '#set' do
|
49
|
+
it 'will use the fluent setter' do
|
50
|
+
eapi = described_class.new
|
51
|
+
expect(eapi.set(:something, :hey)).to equal eapi
|
52
|
+
expect(eapi.get(:something)).to eq :hey
|
53
|
+
end
|
53
54
|
end
|
54
|
-
end
|
55
55
|
|
56
|
+
end
|
56
57
|
end
|
57
58
|
|
58
59
|
end
|
data/spec/definition_spec.rb
CHANGED
data/spec/extension_spec.rb
CHANGED
@@ -8,14 +8,14 @@ RSpec.describe Eapi do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
class MyExtensionExternalKlass
|
11
|
-
include MyExtension::
|
11
|
+
include MyExtension::Item
|
12
12
|
|
13
13
|
property :something
|
14
14
|
end
|
15
15
|
|
16
16
|
module MyExtension
|
17
17
|
class TestKlass
|
18
|
-
include MyExtension::
|
18
|
+
include MyExtension::Item
|
19
19
|
|
20
20
|
property :something
|
21
21
|
end
|
data/spec/function_spec.rb
CHANGED
@@ -2,63 +2,92 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe Eapi do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
class MyTestKlassOutside
|
6
|
+
include Eapi::Item
|
7
|
+
|
8
|
+
property :something
|
9
|
+
end
|
10
|
+
|
11
|
+
class MyTestListOutside
|
12
|
+
include Eapi::List
|
13
|
+
end
|
14
|
+
|
15
|
+
module Somewhere
|
16
|
+
class TestKlassInModule
|
17
|
+
include Eapi::Item
|
8
18
|
|
9
19
|
property :something
|
10
20
|
end
|
11
21
|
|
12
|
-
|
13
|
-
|
14
|
-
|
22
|
+
class TestListInModule
|
23
|
+
include Eapi::List
|
24
|
+
end
|
25
|
+
end
|
15
26
|
|
16
|
-
|
27
|
+
describe 'Eapi::Children' do
|
28
|
+
describe '#list' do
|
29
|
+
it 'returns the list of Eapi enabled classes' do
|
30
|
+
list = Eapi::Children.list
|
31
|
+
expect(list).to include(MyTestKlassOutside)
|
32
|
+
expect(list).to include(MyTestListOutside)
|
17
33
|
end
|
18
34
|
end
|
19
35
|
|
20
|
-
describe '
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
36
|
+
describe '#has?' do
|
37
|
+
it 'true if the given class is an Eapi enabled class' do
|
38
|
+
expect(Eapi::Children).not_to be_has('nope')
|
39
|
+
expect(Eapi::Children).to be_has(MyTestKlassOutside)
|
40
|
+
expect(Eapi::Children).to be_has('MyTestKlassOutside')
|
41
|
+
expect(Eapi::Children).to be_has('my_test_klass_outside')
|
42
|
+
expect(Eapi::Children).to be_has(MyTestListOutside)
|
43
|
+
expect(Eapi::Children).to be_has('MyTestListOutside')
|
44
|
+
expect(Eapi::Children).to be_has('my_test_list_outside')
|
26
45
|
end
|
46
|
+
end
|
27
47
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
48
|
+
describe '#get' do
|
49
|
+
it 'get the given class if it is an Eapi enabled class' do
|
50
|
+
expect(Eapi::Children.get('nope')).to be_nil
|
51
|
+
expect(Eapi::Children.get(MyTestKlassOutside)).to eq MyTestKlassOutside
|
52
|
+
expect(Eapi::Children.get('MyTestKlassOutside')).to eq MyTestKlassOutside
|
53
|
+
expect(Eapi::Children.get('my_test_klass_outside')).to eq MyTestKlassOutside
|
54
|
+
expect(Eapi::Children.get(MyTestListOutside)).to eq MyTestListOutside
|
55
|
+
expect(Eapi::Children.get('MyTestListOutside')).to eq MyTestListOutside
|
56
|
+
expect(Eapi::Children.get('my_test_list_outside')).to eq MyTestListOutside
|
35
57
|
end
|
58
|
+
end
|
59
|
+
end
|
36
60
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
61
|
+
describe 'initialise using method calls to Eapi', :focus do
|
62
|
+
[
|
63
|
+
[:MyTestKlassOutside, MyTestKlassOutside],
|
64
|
+
[:my_test_klass_outside, MyTestKlassOutside],
|
65
|
+
[:Somewhere__TestKlassInModule, Somewhere::TestKlassInModule],
|
66
|
+
[:somewhere__test_klass_in_module, Somewhere::TestKlassInModule],
|
67
|
+
[:Somewhere_TestKlassInModule, Somewhere::TestKlassInModule],
|
68
|
+
[:somewhere_test_klass_in_module, Somewhere::TestKlassInModule],
|
69
|
+
].each do |(meth, klass)|
|
70
|
+
describe "Eapi.#{meth}(...)" do
|
71
|
+
it "calls #{klass}.new" do
|
72
|
+
eapi = Eapi.send meth, something: :hey
|
73
|
+
expect(eapi).to be_a klass
|
74
|
+
expect(eapi.something).to eq :hey
|
43
75
|
end
|
44
76
|
end
|
45
77
|
end
|
46
78
|
|
47
|
-
|
48
|
-
[
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
expect(eapi).to be_a klass
|
60
|
-
expect(eapi.something).to eq :hey
|
61
|
-
end
|
79
|
+
[
|
80
|
+
[:MyTestListOutside, MyTestListOutside],
|
81
|
+
[:my_test_list_outside, MyTestListOutside],
|
82
|
+
[:Somewhere__TestListInModule, Somewhere::TestListInModule],
|
83
|
+
[:somewhere__test_list_in_module, Somewhere::TestListInModule],
|
84
|
+
[:Somewhere_TestListInModule, Somewhere::TestListInModule],
|
85
|
+
[:somewhere_test_list_in_module, Somewhere::TestListInModule],
|
86
|
+
].each do |(meth, klass)|
|
87
|
+
describe "Eapi.#{meth}(...)" do
|
88
|
+
it "calls #{klass}.new" do
|
89
|
+
eapi = Eapi.send meth
|
90
|
+
expect(eapi).to be_a klass
|
62
91
|
end
|
63
92
|
end
|
64
93
|
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Eapi do
|
4
|
+
|
5
|
+
context 'list elements' do
|
6
|
+
class MyTestClassValMult
|
7
|
+
include Eapi::Item
|
8
|
+
|
9
|
+
property :something, multiple: true
|
10
|
+
end
|
11
|
+
|
12
|
+
it '#add_something' do
|
13
|
+
eapi = MyTestClassValMult.new something: [1, 2]
|
14
|
+
res = eapi.add_something 3
|
15
|
+
expect(res).to be eapi
|
16
|
+
expect(eapi.something).to eq [1, 2, 3]
|
17
|
+
end
|
18
|
+
|
19
|
+
it '#init_something called on first add if element is nil' do
|
20
|
+
eapi = MyTestClassValMult.new
|
21
|
+
res = eapi.add_something :a
|
22
|
+
expect(res).to be eapi
|
23
|
+
expect(eapi.something.to_a).to eq [:a]
|
24
|
+
end
|
25
|
+
|
26
|
+
class MyTestClassValMultImpl
|
27
|
+
include Eapi::Item
|
28
|
+
|
29
|
+
property :something, type: Set
|
30
|
+
end
|
31
|
+
|
32
|
+
class MyMultiple
|
33
|
+
def self.is_multiple?
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def <<(x)
|
38
|
+
@elements ||= []
|
39
|
+
@elements << x
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_a
|
43
|
+
@elements.to_a
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class MyTestClassValMultImpl2
|
48
|
+
include Eapi::Item
|
49
|
+
|
50
|
+
property :something, type: MyMultiple
|
51
|
+
end
|
52
|
+
|
53
|
+
class MyMultipleValueTestKlass
|
54
|
+
include Eapi::MultipleValue
|
55
|
+
|
56
|
+
def <<(x)
|
57
|
+
@elements ||= []
|
58
|
+
@elements << x
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_a
|
62
|
+
@elements.to_a
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class MyTestClassValMultImpl3
|
67
|
+
include Eapi::Item
|
68
|
+
|
69
|
+
property :something, type: MyMultipleValueTestKlass
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'if type is Array or Set, or responds true to is_multiple?, it is multiple implicitly + uses that class to initialize the property when adding' do
|
73
|
+
[
|
74
|
+
[MyTestClassValMult, Array],
|
75
|
+
[MyTestClassValMultImpl, Set],
|
76
|
+
[MyTestClassValMultImpl2, MyMultiple],
|
77
|
+
[MyTestClassValMultImpl3, MyMultipleValueTestKlass],
|
78
|
+
].each do |(eapi_class, type_class)|
|
79
|
+
eapi = eapi_class.new
|
80
|
+
res = eapi.add_something :a
|
81
|
+
expect(res).to be eapi
|
82
|
+
expect(eapi.something.to_a).to eq [:a]
|
83
|
+
expect(eapi.something).to be_a_kind_of type_class
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'element validation' do
|
88
|
+
class MyTestClassValElements
|
89
|
+
include Eapi::Item
|
90
|
+
property :something, multiple: true, element_type: Hash
|
91
|
+
property :other, multiple: true, validate_element_with: ->(record, attr, value) do
|
92
|
+
record.errors.add(attr, "element must pass my custom validation") unless value == :valid_val
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe 'using `type_element` property in definition' do
|
97
|
+
it 'will validate the type of all the elements in the list' do
|
98
|
+
eapi = MyTestClassValElements.new
|
99
|
+
eapi.add_something 1
|
100
|
+
expect(eapi).not_to be_valid
|
101
|
+
expect(eapi.errors.full_messages).to eq ["Something element must be a Hash"]
|
102
|
+
expect(eapi.errors.messages).to eq({something: ["element must be a Hash"]})
|
103
|
+
|
104
|
+
eapi.something [{a: :b}]
|
105
|
+
expect(eapi).to be_valid
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe 'using `validate_element_with` property in definition' do
|
110
|
+
it 'will run that custom validation for all the elements in the list' do
|
111
|
+
eapi = MyTestClassValElements.new
|
112
|
+
eapi.add_other 1
|
113
|
+
expect(eapi).not_to be_valid
|
114
|
+
expect(eapi.errors.full_messages).to eq ["Other element must pass my custom validation"]
|
115
|
+
expect(eapi.errors.messages).to eq({other: ["element must pass my custom validation"]})
|
116
|
+
|
117
|
+
eapi.other [:valid_val]
|
118
|
+
expect(eapi).to be_valid
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/spec/list_spec.rb
CHANGED
@@ -3,122 +3,419 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe Eapi do
|
4
4
|
|
5
5
|
context 'list' do
|
6
|
-
class MyTestClassValMult
|
7
|
-
include Eapi::Common
|
8
6
|
|
9
|
-
|
7
|
+
class MyListKlass
|
8
|
+
include Eapi::List
|
10
9
|
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
res = eapi.add_something 3
|
15
|
-
expect(res).to be eapi
|
16
|
-
expect(eapi.something).to eq [1, 2, 3]
|
17
|
-
end
|
18
|
-
|
19
|
-
it '#init_something called on first add if element is nil' do
|
20
|
-
eapi = MyTestClassValMult.new
|
21
|
-
res = eapi.add_something :a
|
22
|
-
expect(res).to be eapi
|
23
|
-
expect(eapi.something.to_a).to eq [:a]
|
24
|
-
end
|
25
|
-
|
26
|
-
class MyTestClassValMultImpl
|
27
|
-
include Eapi::Common
|
28
|
-
|
29
|
-
property :something, type: Set
|
30
|
-
end
|
11
|
+
describe 'list behaviour' do
|
12
|
+
subject { MyListKlass.new }
|
31
13
|
|
32
|
-
|
33
|
-
|
34
|
-
|
14
|
+
context '#<<' do
|
15
|
+
it 'append element, normal behaviour' do
|
16
|
+
res = subject << :hey
|
17
|
+
expect(res).to eq [:hey]
|
18
|
+
expect(subject.to_a).to eq [:hey]
|
19
|
+
end
|
35
20
|
end
|
36
21
|
|
37
|
-
|
38
|
-
|
39
|
-
|
22
|
+
context '#add' do
|
23
|
+
it 'fluent adder, returns self' do
|
24
|
+
res = subject.add(:hey).add(:you)
|
25
|
+
expect(res).to eq subject
|
26
|
+
expect(subject.to_a).to eq [:hey, :you]
|
27
|
+
end
|
40
28
|
end
|
41
29
|
|
42
|
-
|
43
|
-
|
30
|
+
context '#to_a' do
|
31
|
+
it 'executes validation' do
|
32
|
+
|
33
|
+
end
|
44
34
|
end
|
45
35
|
end
|
46
36
|
|
47
|
-
|
48
|
-
|
37
|
+
describe 'list methods' do
|
38
|
+
KNOWN_METHODS = {
|
39
|
+
not_supported: [:transpose, :assoc, :rassoc, :permutation, :combination, :repeated_permutation, :repeated_combination, :product, :pack],
|
40
|
+
not_same: [:pry, :to_s, :inspect, :to_a, :to_h, :hash, :eql?, :to_ary, :pretty_print, :pretty_print_cycle],
|
41
|
+
block: [:cycle, :each, :each_index, :reverse_each],
|
42
|
+
special: [:[], :[]=, :<<, :==],
|
43
|
+
other_array: [:concat, :+, :-, :&, :|, :replace, :<=>],
|
44
|
+
at: [:at, :fetch, :delete_at, :from, :to],
|
45
|
+
index: [:index, :find_index, :rindex, :delete],
|
46
|
+
push: [:push, :unshift, :append, :prepend],
|
47
|
+
insert: [:insert],
|
48
|
+
map: [:map, :map!, :collect!, :collect],
|
49
|
+
select!: [:keep_if, :select!, :reject!, :select, :delete_if, :reject, :drop_while, :take_while, :bsearch],
|
50
|
+
by_number: [:in_groups_of, :in_groups, :drop, :take, :include?, :*, :to_query, :fill],
|
51
|
+
slice: [:slice, :slice!],
|
52
|
+
sort_by: [:sort_by!],
|
53
|
+
sample: [:sample],
|
54
|
+
shuffle: [:shuffle, :shuffle!],
|
55
|
+
}
|
49
56
|
|
50
|
-
|
51
|
-
|
57
|
+
SUPPORTED_METHODS = [].public_methods(false) - KNOWN_METHODS[:not_supported]
|
58
|
+
MIMIC_METHODS = [].public_methods(false) - KNOWN_METHODS.values.flatten
|
52
59
|
|
53
|
-
|
54
|
-
|
60
|
+
subject { MyListKlass.new.add(1).add(2).add(3) }
|
61
|
+
let(:other) { MyListKlass.new.add(1).add(2).add(3) }
|
62
|
+
let(:array) { [1, 2, 3] }
|
55
63
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
64
|
+
context 'array methods' do
|
65
|
+
describe 'respond to methods' do
|
66
|
+
KNOWN_METHODS[:not_supported].each do |m|
|
67
|
+
it "does not respond to #{m}" do
|
68
|
+
expect(subject).not_to respond_to(m)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
SUPPORTED_METHODS.each do |m|
|
73
|
+
it "responds to #{m}" do
|
74
|
+
expect(subject).to respond_to(m)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'same behaviour as list array' do
|
80
|
+
|
81
|
+
describe 'to_ary' do
|
82
|
+
it { expect(subject.to_ary).to eq array }
|
83
|
+
it { expect(subject.to_ary).not_to equal subject }
|
84
|
+
it { expect(subject.to_ary).to equal subject._list }
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'method ==' do
|
88
|
+
it { expect(subject).to eq array }
|
89
|
+
it { expect(subject).to eq other }
|
90
|
+
it { expect(subject).not_to eq [3, 2, 1] }
|
91
|
+
it { expect(subject).not_to eq MyListKlass.new }
|
92
|
+
end
|
93
|
+
|
94
|
+
describe 'method []' do
|
95
|
+
it { expect(subject[2]).to eq array[2] }
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'method []=' do
|
99
|
+
it { expect(subject[2] = :paco).to eq(array[2] = :paco) }
|
100
|
+
it do
|
101
|
+
subject[2] = :paco
|
102
|
+
expect(subject[2]).to eq :paco
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe 'method <<' do
|
107
|
+
it { expect(subject << :paco).to eq(array << :paco) }
|
108
|
+
it do
|
109
|
+
subject << :paco
|
110
|
+
expect(subject.last).to eq :paco
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
KNOWN_METHODS[:other_array].each do |m|
|
115
|
+
describe "method #{m}" do
|
116
|
+
it { expect(subject.public_send(m, other)).to eq array.public_send(m, other._list) }
|
117
|
+
it { expect(subject.public_send(m, other._list)).to eq(array.public_send(m, other._list)) }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
KNOWN_METHODS[:at].each do |m|
|
123
|
+
describe "method #{m}" do
|
124
|
+
it { expect(subject.public_send(m, 2)).to eq array.public_send(m, 2) }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
KNOWN_METHODS[:index].each do |m|
|
129
|
+
describe "method #{m}" do
|
130
|
+
it { expect(subject.public_send(m, 2)).to eq array.public_send(m, 2) }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
KNOWN_METHODS[:push].each do |m|
|
135
|
+
describe "method #{m}" do
|
136
|
+
it { expect(subject.public_send(m, :paco)).to eq(array.public_send(m, :paco)) }
|
137
|
+
it do
|
138
|
+
subject.public_send(m, :paco)
|
139
|
+
array.public_send(m, :paco)
|
140
|
+
expect(subject).to eq array
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
KNOWN_METHODS[:insert].each do |m|
|
146
|
+
describe "method #{m}" do
|
147
|
+
it { expect(subject.public_send(m, 1, :paco)).to eq(array.public_send(m, 1, :paco)) }
|
148
|
+
it do
|
149
|
+
subject.public_send(m, 1, :paco)
|
150
|
+
array.public_send(m, 1, :paco)
|
151
|
+
expect(subject).to eq array
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "method sample" do
|
157
|
+
it do
|
158
|
+
expect(subject._list).to include(subject.sample)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "method shuffle" do
|
163
|
+
it do
|
164
|
+
list_before_shuffle = subject._list.dup
|
165
|
+
list_after_shuffle = subject.shuffle._list.dup
|
166
|
+
expect(list_before_shuffle.sort).to eq list_after_shuffle.sort
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "method shuffle!" do
|
171
|
+
it do
|
172
|
+
list_before_shuffle = subject._list.dup
|
173
|
+
subject.shuffle!
|
174
|
+
list_after_shuffle = subject._list.dup
|
175
|
+
expect(list_before_shuffle.sort).to eq list_after_shuffle.sort
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
KNOWN_METHODS[:map].each do |m|
|
181
|
+
describe "method #{m}" do
|
182
|
+
let(:subject_applied_block) do
|
183
|
+
subject.public_send(m) { |x| x + 1 }
|
184
|
+
end
|
185
|
+
|
186
|
+
let(:array_applied_block) do
|
187
|
+
array.public_send(m) { |x| x + 1 }
|
188
|
+
end
|
189
|
+
|
190
|
+
it do
|
191
|
+
expect(subject_applied_block).to eq array_applied_block
|
192
|
+
end
|
193
|
+
|
194
|
+
it do
|
195
|
+
subject_applied_block
|
196
|
+
array_applied_block
|
197
|
+
expect(subject).to eq array
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
KNOWN_METHODS[:select!].each do |m|
|
204
|
+
describe "method #{m}" do
|
205
|
+
let(:subject_applied_block) do
|
206
|
+
subject.public_send(m) { |x| x.odd? }
|
207
|
+
end
|
208
|
+
|
209
|
+
let(:array_applied_block) do
|
210
|
+
array.public_send(m) { |x| x.odd? }
|
211
|
+
end
|
212
|
+
|
213
|
+
it do
|
214
|
+
expect(subject_applied_block).to eq array_applied_block
|
215
|
+
end
|
216
|
+
|
217
|
+
it do
|
218
|
+
subject_applied_block
|
219
|
+
array_applied_block
|
220
|
+
expect(subject).to eq array
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
KNOWN_METHODS[:by_number].each do |m|
|
227
|
+
describe "method #{m}" do
|
228
|
+
let(:subject_result) do
|
229
|
+
subject.public_send(m, 2)
|
230
|
+
end
|
231
|
+
|
232
|
+
let(:array_result) do
|
233
|
+
array.public_send(m, 2)
|
234
|
+
end
|
60
235
|
|
61
|
-
|
62
|
-
|
236
|
+
it do
|
237
|
+
expect(subject_result).to eq array_result
|
238
|
+
end
|
239
|
+
|
240
|
+
it do
|
241
|
+
subject_result
|
242
|
+
array_result
|
243
|
+
expect(subject).to eq array
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
|
249
|
+
KNOWN_METHODS[:slice].each do |m|
|
250
|
+
describe "method #{m}" do
|
251
|
+
let(:subject_result) do
|
252
|
+
subject.public_send(m, 2)
|
253
|
+
end
|
254
|
+
|
255
|
+
let(:array_result) do
|
256
|
+
array.public_send(m, 2)
|
257
|
+
end
|
258
|
+
|
259
|
+
it do
|
260
|
+
expect(subject_result).to eq array_result
|
261
|
+
end
|
262
|
+
|
263
|
+
it do
|
264
|
+
subject_result
|
265
|
+
array_result
|
266
|
+
expect(subject).to eq array
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
describe "method sort_by!" do
|
272
|
+
let(:subject_enumerator) do
|
273
|
+
subject.sort_by!
|
274
|
+
end
|
275
|
+
|
276
|
+
let(:array_enumerator) do
|
277
|
+
array.sort_by!
|
278
|
+
end
|
279
|
+
|
280
|
+
let(:subject_with_block) do
|
281
|
+
subject.sort_by! { |x| -1 * x }
|
282
|
+
end
|
283
|
+
|
284
|
+
let(:array_with_block) do
|
285
|
+
array.sort_by! { |x| -1 * x }
|
286
|
+
end
|
287
|
+
|
288
|
+
it do
|
289
|
+
expect(subject_enumerator.to_a).to eq array_enumerator.to_a
|
290
|
+
end
|
291
|
+
|
292
|
+
it do
|
293
|
+
expect(subject_with_block.to_a).to eq array_with_block.to_a
|
294
|
+
end
|
295
|
+
|
296
|
+
it do
|
297
|
+
subject_with_block
|
298
|
+
array_with_block
|
299
|
+
expect(subject).to eq array
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
|
304
|
+
describe 'block methods' do
|
305
|
+
describe 'method cycle' do
|
306
|
+
it 'behaves like the method in Array' do
|
307
|
+
sl = []
|
308
|
+
al = []
|
309
|
+
subject.cycle(2) { |x| sl << (x + 1) }
|
310
|
+
array.cycle(2) { |x| al << (x + 1) }
|
311
|
+
|
312
|
+
expect(sl).to eq al
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
|
318
|
+
MIMIC_METHODS.each do |m|
|
319
|
+
describe "method #{m}" do
|
320
|
+
it 'behaves like the method in Array' do
|
321
|
+
lr = subject.public_send m
|
322
|
+
ar = array.public_send m
|
323
|
+
|
324
|
+
if ar.equal? array
|
325
|
+
expect(lr).to equal subject
|
326
|
+
else
|
327
|
+
expect(lr).to eq ar
|
328
|
+
end
|
329
|
+
|
330
|
+
expect(subject._list).to eq array
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
63
335
|
end
|
64
336
|
end
|
65
337
|
|
66
|
-
|
67
|
-
|
338
|
+
describe 'list definition' do
|
339
|
+
class ListDefinitionTestKlass
|
340
|
+
include Eapi::List
|
68
341
|
|
69
|
-
|
70
|
-
|
342
|
+
elements required: true, type: String, unique: true
|
343
|
+
end
|
344
|
+
|
345
|
+
let(:definition) { {required: true, type: String, unique: true} }
|
71
346
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
[MyTestClassValMultImpl2, MyMultiple],
|
77
|
-
[MyTestClassValMultImpl3, MyMultipleEapi],
|
78
|
-
].each do |(eapi_class, type_class)|
|
79
|
-
eapi = eapi_class.new
|
80
|
-
res = eapi.add_something :a
|
81
|
-
expect(res).to be eapi
|
82
|
-
expect(eapi.something.to_a).to eq [:a]
|
83
|
-
expect(eapi.something).to be_a_kind_of type_class
|
347
|
+
subject { ListDefinitionTestKlass.new }
|
348
|
+
|
349
|
+
context '.is_multiple?' do
|
350
|
+
it { expect(subject.class).to be_is_multiple }
|
84
351
|
end
|
85
|
-
end
|
86
352
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
353
|
+
context '.definition_for_elements' do
|
354
|
+
it { expect(subject.class.definition_for_elements).to eq definition }
|
355
|
+
end
|
356
|
+
|
357
|
+
context 'required' do
|
358
|
+
it 'fails if empty' do
|
359
|
+
expect(subject).not_to be_valid
|
360
|
+
subject.add "Something"
|
361
|
+
expect(subject).to be_valid
|
93
362
|
end
|
94
363
|
end
|
95
364
|
|
96
|
-
|
97
|
-
it '
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
expect(
|
102
|
-
|
365
|
+
context 'type' do
|
366
|
+
it 'fails if any element is not of valid type' do
|
367
|
+
subject.add "Something"
|
368
|
+
subject.add :is
|
369
|
+
subject.add 1
|
370
|
+
expect(subject).not_to be_valid
|
371
|
+
subject.clear
|
372
|
+
subject.add "Just Strings"
|
373
|
+
subject.add "Many Strings"
|
374
|
+
expect(subject).to be_valid
|
375
|
+
end
|
376
|
+
end
|
103
377
|
|
104
|
-
|
105
|
-
|
378
|
+
context 'unique' do
|
379
|
+
it 'fails if has any repeated elements' do
|
380
|
+
subject.add "Cramer"
|
381
|
+
subject.add "vs"
|
382
|
+
subject.add "Cramer"
|
383
|
+
|
384
|
+
expect(subject).not_to be_valid
|
385
|
+
|
386
|
+
msgs = {:_list => ["elements must be unique (repeated elements: {\"Cramer\"=>2})"]}
|
387
|
+
expect(subject.errors.messages).to eq msgs
|
388
|
+
|
389
|
+
subject.clear
|
390
|
+
|
391
|
+
subject.add "Cramer"
|
392
|
+
subject.add "vs"
|
393
|
+
subject.add "Other Guy"
|
394
|
+
|
395
|
+
expect(subject).to be_valid
|
106
396
|
end
|
107
397
|
end
|
108
398
|
|
109
|
-
|
399
|
+
context 'validate_with lambda' do
|
400
|
+
class MyTestClassListValElements
|
401
|
+
include Eapi::List
|
402
|
+
elements validate_with: ->(record, attr, value) do
|
403
|
+
record.errors.add(attr, "element must pass my custom validation") unless value == :valid_val
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
110
407
|
it 'will run that custom validation for all the elements in the list' do
|
111
|
-
eapi =
|
112
|
-
eapi.
|
408
|
+
eapi = MyTestClassListValElements.new
|
409
|
+
eapi.add 1
|
113
410
|
expect(eapi).not_to be_valid
|
114
|
-
expect(eapi.errors.full_messages).to eq ["
|
115
|
-
expect(eapi.errors.messages).to eq({
|
411
|
+
expect(eapi.errors.full_messages).to eq [" list element must pass my custom validation"]
|
412
|
+
expect(eapi.errors.messages).to eq({_list: ["element must pass my custom validation"]})
|
116
413
|
|
117
|
-
eapi.
|
414
|
+
eapi.clear.add :valid_val
|
118
415
|
expect(eapi).to be_valid
|
119
416
|
end
|
120
417
|
end
|
418
|
+
|
121
419
|
end
|
122
420
|
end
|
123
|
-
|
124
421
|
end
|