errol 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/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +220 -0
- data/Rakefile +17 -0
- data/errol.gemspec +26 -0
- data/lib/errol.rb +8 -0
- data/lib/errol/entity.rb +109 -0
- data/lib/errol/inquiry.rb +33 -0
- data/lib/errol/repository.rb +178 -0
- data/lib/errol/version.rb +3 -0
- data/test/entity/access_generation_test.rb +75 -0
- data/test/entity/access_methods_test.rb +32 -0
- data/test/entity/entity_test.rb +35 -0
- data/test/entity/repository_method_test.rb +92 -0
- data/test/inquiry/inquiry_test.rb +57 -0
- data/test/repository/contruction_test.rb +62 -0
- data/test/repository/page_test.rb +163 -0
- data/test/repository/query_test.rb +190 -0
- data/test/test_config.rb +27 -0
- metadata +144 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
module Errol
|
2
|
+
class Repository
|
3
|
+
RecordAbsent = Class.new(StandardError)
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def build(entries={})
|
7
|
+
entity = dispatch(record_class.new)
|
8
|
+
entries.each do |attribute, value|
|
9
|
+
entity.public_send "#{attribute}=", value
|
10
|
+
end
|
11
|
+
yield entity if block_given?
|
12
|
+
entity
|
13
|
+
end
|
14
|
+
|
15
|
+
def create(*arguments, &block)
|
16
|
+
build(*arguments, &block).tap(&method(:save))
|
17
|
+
end
|
18
|
+
|
19
|
+
def save(entity)
|
20
|
+
receive(entity).save
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def remove(entity)
|
25
|
+
begin
|
26
|
+
receive(entity).destroy
|
27
|
+
rescue Sequel::NoExistingObject
|
28
|
+
raise RecordAbsent
|
29
|
+
end
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def empty?(requirements={})
|
34
|
+
new(requirements, false).empty?
|
35
|
+
end
|
36
|
+
|
37
|
+
def count(requirements={})
|
38
|
+
new(requirements, false).count
|
39
|
+
end
|
40
|
+
|
41
|
+
def first(requirements={})
|
42
|
+
new(requirements, false).first
|
43
|
+
end
|
44
|
+
|
45
|
+
def last(requirements={})
|
46
|
+
new(requirements, false).last
|
47
|
+
end
|
48
|
+
|
49
|
+
def [](id, requirements={})
|
50
|
+
new(requirements, false)[id]
|
51
|
+
end
|
52
|
+
|
53
|
+
def fetch(id, requirements={}, &block)
|
54
|
+
new(requirements, false).fetch(id, &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def all(requirements={})
|
58
|
+
new(requirements, false).all
|
59
|
+
end
|
60
|
+
|
61
|
+
def each(requirements={}, &block)
|
62
|
+
new(requirements, false).each &block
|
63
|
+
end
|
64
|
+
|
65
|
+
def raw_dataset
|
66
|
+
record_class.dataset
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
include Enumerable
|
71
|
+
|
72
|
+
def initialize(requirements={}, paginate=true)
|
73
|
+
@requirements = requirements
|
74
|
+
@inquiry = self.class.inquiry(requirements)
|
75
|
+
@paginate = paginate
|
76
|
+
end
|
77
|
+
|
78
|
+
def current_page
|
79
|
+
paginated_dataset.current_page
|
80
|
+
end
|
81
|
+
|
82
|
+
def page_size
|
83
|
+
paginated_dataset.page_size
|
84
|
+
end
|
85
|
+
|
86
|
+
def first_page?
|
87
|
+
paginated_dataset.first_page?
|
88
|
+
end
|
89
|
+
|
90
|
+
def last_page?
|
91
|
+
paginated_dataset.last_page?
|
92
|
+
end
|
93
|
+
|
94
|
+
def page_count
|
95
|
+
paginated_dataset.page_count
|
96
|
+
end
|
97
|
+
|
98
|
+
def page_range
|
99
|
+
paginated_dataset.page_range
|
100
|
+
end
|
101
|
+
|
102
|
+
def next_page
|
103
|
+
paginated_dataset.next_page
|
104
|
+
end
|
105
|
+
|
106
|
+
def previous_page
|
107
|
+
paginated_dataset.prev_page
|
108
|
+
end
|
109
|
+
|
110
|
+
attr_reader :inquiry
|
111
|
+
|
112
|
+
def empty?
|
113
|
+
paginated_dataset.empty?
|
114
|
+
end
|
115
|
+
|
116
|
+
def count
|
117
|
+
paginated_dataset.count
|
118
|
+
end
|
119
|
+
|
120
|
+
def first
|
121
|
+
dispatch(paginated_dataset.first)
|
122
|
+
end
|
123
|
+
|
124
|
+
def last
|
125
|
+
# TODO say what!!
|
126
|
+
all.last
|
127
|
+
# dispatch(paginated_dataset.last)
|
128
|
+
end
|
129
|
+
|
130
|
+
def [](id)
|
131
|
+
dispatch(dataset.first(:id => id))
|
132
|
+
end
|
133
|
+
|
134
|
+
def fetch(id)
|
135
|
+
item = self[id]
|
136
|
+
return item if item
|
137
|
+
return yield id if block_given?
|
138
|
+
record_absent(id)
|
139
|
+
end
|
140
|
+
|
141
|
+
def all
|
142
|
+
paginated_dataset.map { |record| dispatch(record) }
|
143
|
+
end
|
144
|
+
|
145
|
+
def each
|
146
|
+
paginated_dataset.each do |record|
|
147
|
+
yield dispatch(record)
|
148
|
+
end
|
149
|
+
self
|
150
|
+
end
|
151
|
+
|
152
|
+
def raw_dataset
|
153
|
+
self.class.raw_dataset
|
154
|
+
end
|
155
|
+
|
156
|
+
def paginate?
|
157
|
+
@paginate
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
def dispatch(item)
|
163
|
+
self.class.dispatch(item) if item
|
164
|
+
end
|
165
|
+
|
166
|
+
def record_absent(id)
|
167
|
+
raise RecordAbsent, "#{self.class.name} contains no record with id: #{id}"
|
168
|
+
end
|
169
|
+
|
170
|
+
def paginated_dataset
|
171
|
+
if paginate?
|
172
|
+
dataset.paginate(inquiry.page.to_i, inquiry.page_size.to_i)
|
173
|
+
else
|
174
|
+
dataset
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative '../test_config'
|
2
|
+
|
3
|
+
module Errol
|
4
|
+
class EntityTest < MiniTest::Test
|
5
|
+
def test_entry_reader_sets_reader_method
|
6
|
+
entity = Class.new Errol::Entity do
|
7
|
+
entry_reader :test_attribute
|
8
|
+
end
|
9
|
+
record = OpenStruct.new
|
10
|
+
instance = entity.new record
|
11
|
+
record.test_attribute = :value
|
12
|
+
assert_equal :value, instance.test_attribute
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_entry_writer_sets_writer_method
|
16
|
+
entity = Class.new Errol::Entity do
|
17
|
+
entry_writer :test_attribute
|
18
|
+
end
|
19
|
+
record = OpenStruct.new
|
20
|
+
instance = entity.new record
|
21
|
+
instance.test_attribute = :value
|
22
|
+
assert_equal :value, record.test_attribute
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_boolean_query_sets_query_method
|
26
|
+
entity = Class.new Errol::Entity do
|
27
|
+
boolean_query :test_attribute
|
28
|
+
end
|
29
|
+
record = OpenStruct.new
|
30
|
+
instance = entity.new record
|
31
|
+
record.test_attribute = :value
|
32
|
+
assert_equal true, instance.test_attribute?
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_entry_accessor_sets_reader_method
|
36
|
+
entity = Class.new Errol::Entity do
|
37
|
+
entry_accessor :test_attribute
|
38
|
+
end
|
39
|
+
record = OpenStruct.new
|
40
|
+
instance = entity.new record
|
41
|
+
record.test_attribute = :value
|
42
|
+
assert_equal :value, instance.test_attribute
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_entry_accessor_sets_writer_method
|
46
|
+
entity = Class.new Errol::Entity do
|
47
|
+
entry_accessor :test_attribute
|
48
|
+
end
|
49
|
+
record = OpenStruct.new
|
50
|
+
instance = entity.new record
|
51
|
+
instance.test_attribute = :value
|
52
|
+
assert_equal :value, record.test_attribute
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_boolean_accessor_sets_query_method
|
56
|
+
entity = Class.new Errol::Entity do
|
57
|
+
boolean_accessor :test_attribute
|
58
|
+
end
|
59
|
+
record = OpenStruct.new
|
60
|
+
instance = entity.new record
|
61
|
+
record.test_attribute = :value
|
62
|
+
assert_equal true, instance.test_attribute?
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_boolean_accessor_sets_writer_method
|
66
|
+
entity = Class.new Errol::Entity do
|
67
|
+
boolean_accessor :test_attribute
|
68
|
+
end
|
69
|
+
record = OpenStruct.new
|
70
|
+
instance = entity.new record
|
71
|
+
instance.test_attribute = :value
|
72
|
+
assert_equal :value, record.test_attribute
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative '../test_config'
|
2
|
+
|
3
|
+
module Errol
|
4
|
+
class EntityTest < MiniTest::Test
|
5
|
+
def test_set_sends_to_self
|
6
|
+
entity = Class.new Errol::Entity do
|
7
|
+
entry_accessor :test_attribute
|
8
|
+
end
|
9
|
+
record = OpenStruct.new
|
10
|
+
entity.new(record).set :test_attribute => 25
|
11
|
+
assert_equal 25, record.test_attribute
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_set_returns_self
|
15
|
+
entity = Class.new Errol::Entity do
|
16
|
+
entry_accessor :test_attribute
|
17
|
+
end
|
18
|
+
record = OpenStruct.new
|
19
|
+
instance = entity.new(record)
|
20
|
+
out = instance.set :test_attribute => 25
|
21
|
+
assert_equal instance, out
|
22
|
+
end
|
23
|
+
|
24
|
+
# def test_save_after_set
|
25
|
+
# mock_repo.expect :save, mock_repo, [instance]
|
26
|
+
# instance.stub :set, instance do
|
27
|
+
# instance.set!
|
28
|
+
# end
|
29
|
+
# mock_repo.verify
|
30
|
+
# end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../test_config'
|
2
|
+
|
3
|
+
module Errol
|
4
|
+
class EntityTest < MiniTest::Test
|
5
|
+
|
6
|
+
def test_make_available_id
|
7
|
+
klass = Class.new(Errol::Entity)
|
8
|
+
record = OpenStruct.new :id => 4
|
9
|
+
instance = klass.new record
|
10
|
+
assert_equal 4, instance.id
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_equal_if_wrapping_same_record
|
14
|
+
klass = Class.new(Errol::Entity)
|
15
|
+
assert_equal klass.new(:record), klass.new(:record)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_not_equal_for_different_records
|
19
|
+
klass = Class.new(Errol::Entity)
|
20
|
+
refute_equal klass.new(:record_b), klass.new(:record_a)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_not_equal_if_different_classes
|
24
|
+
klass1 = Class.new(Errol::Entity)
|
25
|
+
klass2 = Class.new(Errol::Entity)
|
26
|
+
refute_equal klass1.new(:record), klass2.new(:record)
|
27
|
+
end
|
28
|
+
|
29
|
+
# def test_undefined_bang
|
30
|
+
# assert_raises NoMethodError do
|
31
|
+
# instance.random!
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require_relative '../test_config'
|
2
|
+
|
3
|
+
module Errol
|
4
|
+
class EntityTest < MiniTest::Test
|
5
|
+
|
6
|
+
def test_raises_informative_error_on_class_before_repository_set
|
7
|
+
entity = Class.new Errol::Entity
|
8
|
+
assert_raises Errol::Entity::RepositoryUndefined do
|
9
|
+
entity.repository
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_raises_informative_error_on_instance_before_repository_set
|
14
|
+
entity = Class.new Errol::Entity
|
15
|
+
instance = entity.new :record
|
16
|
+
assert_raises Errol::Entity::RepositoryUndefined do
|
17
|
+
instance.repository
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_sets_repository_on_instance
|
22
|
+
entity = Class.new Errol::Entity
|
23
|
+
entity.repository = :repository
|
24
|
+
instance = entity.new :record
|
25
|
+
assert_equal :repository, instance.repository
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_sets_repository_on_class
|
29
|
+
entity = Class.new Errol::Entity
|
30
|
+
entity.repository = :repository
|
31
|
+
assert_equal :repository, entity.repository
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_saves_self_to_repository
|
35
|
+
entity = Class.new Errol::Entity
|
36
|
+
mock = MiniTest::Mock.new
|
37
|
+
entity.repository = mock
|
38
|
+
instance = entity.new mock
|
39
|
+
mock.expect :save, mock, [instance]
|
40
|
+
instance.save
|
41
|
+
mock.verify
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_save_returns_self
|
45
|
+
entity = Class.new Errol::Entity
|
46
|
+
mock = MiniTest::Mock.new
|
47
|
+
entity.repository = mock
|
48
|
+
instance = entity.new mock
|
49
|
+
mock.expect :save, mock, [instance]
|
50
|
+
assert_equal instance.object_id, instance.save.object_id
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_removes_self_with_repository
|
54
|
+
entity = Class.new Errol::Entity
|
55
|
+
mock = MiniTest::Mock.new
|
56
|
+
entity.repository = mock
|
57
|
+
instance = entity.new mock
|
58
|
+
mock.expect :remove, mock, [instance]
|
59
|
+
instance.destroy
|
60
|
+
mock.verify
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_destroy_returns_self
|
64
|
+
entity = Class.new Errol::Entity
|
65
|
+
mock = MiniTest::Mock.new
|
66
|
+
entity.repository = mock
|
67
|
+
instance = entity.new mock
|
68
|
+
mock.expect :remove, mock, [instance]
|
69
|
+
assert_equal instance.object_id, instance.destroy.object_id
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_refreshes_itself_with_repository
|
73
|
+
entity = Class.new Errol::Entity
|
74
|
+
mock = MiniTest::Mock.new
|
75
|
+
entity.repository = mock
|
76
|
+
instance = entity.new mock
|
77
|
+
mock.expect :refresh, mock, [instance]
|
78
|
+
instance.refresh
|
79
|
+
mock.verify
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_refresh_returns_self
|
83
|
+
entity = Class.new Errol::Entity
|
84
|
+
mock = MiniTest::Mock.new
|
85
|
+
entity.repository = mock
|
86
|
+
instance = entity.new mock
|
87
|
+
mock.expect :refresh, mock, [instance]
|
88
|
+
assert_equal instance.object_id, instance.refresh.object_id
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require_relative '../test_config'
|
2
|
+
|
3
|
+
module Errol
|
4
|
+
class InquiryTest < MiniTest::Test
|
5
|
+
def inquiry_class
|
6
|
+
@inquiry_class ||= Class.new(Inquiry)
|
7
|
+
end
|
8
|
+
|
9
|
+
def inquiry
|
10
|
+
@inquiry ||= inquiry_class.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
@inquiry_class = nil
|
15
|
+
@inquiry = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_can_set_paginate_false
|
19
|
+
inquiry_class.default :paginate, false
|
20
|
+
assert_equal false, inquiry.paginate?
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_throws_error_for_undefined_value
|
24
|
+
err = assert_raises Inquiry::DefaultValueUndefined do
|
25
|
+
inquiry.random
|
26
|
+
end
|
27
|
+
assert_match(/random/, err.message)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_can_set_arbitrary_number_of_defaults
|
31
|
+
inquiry_class.default :filter_a, []
|
32
|
+
inquiry_class.default :filter_b, :ballon
|
33
|
+
assert_equal [], inquiry.filter_a
|
34
|
+
assert_equal :ballon, inquiry.filter_b
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_can_set_with_string
|
38
|
+
inquiry_class.default 'filter', :ballon
|
39
|
+
assert_equal :ballon, inquiry.filter
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_can_check_if_value_set
|
43
|
+
inquiry_class.default :filter, :ballon
|
44
|
+
assert_equal true, inquiry.filter?
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_can_over_write_on_initialize
|
48
|
+
inquiry_class.default :filter, :ballon
|
49
|
+
assert_equal :smidge, inquiry_class.new(:filter => :smidge).filter
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_can_over_write_on_initialize_with_string
|
53
|
+
inquiry_class.default :filter, :ballon
|
54
|
+
assert_equal :smidge, inquiry_class.new('filter' => :smidge).filter
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|