rddd 0.2.0 → 0.2.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.
- data/.DS_Store +0 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +3 -1
- data/README.md +8 -2
- data/Rakefile +5 -0
- data/lib/rddd.rb +5 -5
- data/lib/rddd/aggregates/entity.rb +75 -0
- data/lib/rddd/aggregates/finders.rb +23 -0
- data/lib/rddd/aggregates/repositories/base.rb +20 -0
- data/lib/rddd/aggregates/repositories/factory.rb +33 -0
- data/lib/rddd/aggregates/root.rb +25 -0
- data/lib/rddd/configuration.rb +1 -9
- data/lib/rddd/{service.rb → services/service.rb} +11 -9
- data/lib/rddd/{service_bus.rb → services/service_bus.rb} +23 -20
- data/lib/rddd/services/service_factory.rb +23 -0
- data/lib/rddd/version.rb +1 -1
- data/lib/rddd/views/cache.rb +24 -0
- data/lib/rddd/views/cacheable.rb +50 -0
- data/lib/rddd/views/view.rb +38 -0
- data/spec/integration_spec.rb +9 -9
- data/spec/lib/aggregates/entity_spec.rb +17 -0
- data/spec/lib/{aggregate_root_spec.rb → aggregates/root_spec.rb} +7 -7
- data/spec/lib/repositories/repository_factory_spec.rb +49 -0
- data/spec/lib/repositories/repository_spec.rb +30 -0
- data/spec/lib/{service_bus_spec.rb → services/service_bus_spec.rb} +6 -6
- data/spec/lib/services/service_factory_spec.rb +61 -0
- data/spec/lib/services/service_spec.rb +31 -0
- data/spec/lib/views/integration_spec.rb +153 -0
- metadata +29 -24
- data/lib/rddd/aggregate_root.rb +0 -17
- data/lib/rddd/aggregate_root_finders.rb +0 -21
- data/lib/rddd/entity.rb +0 -11
- data/lib/rddd/repository.rb +0 -16
- data/lib/rddd/repository_factory.rb +0 -25
- data/lib/rddd/service_factory.rb +0 -21
- data/spec/lib/entity_spec.rb +0 -17
- data/spec/lib/repository_factory_spec.rb +0 -47
- data/spec/lib/repository_spec.rb +0 -26
- data/spec/lib/service_factory_spec.rb +0 -59
- data/spec/lib/service_spec.rb +0 -27
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rddd/views/cache'
|
2
|
+
require 'rddd/views/cacheable'
|
3
|
+
|
4
|
+
module Rddd
|
5
|
+
module Views
|
6
|
+
class View
|
7
|
+
include Cacheable
|
8
|
+
extend Caching
|
9
|
+
|
10
|
+
attr_reader :id
|
11
|
+
|
12
|
+
def initialize(id)
|
13
|
+
@id = id
|
14
|
+
end
|
15
|
+
|
16
|
+
def name
|
17
|
+
self.class.name.downcase.to_sym
|
18
|
+
end
|
19
|
+
|
20
|
+
def build
|
21
|
+
raise NotImplementedError
|
22
|
+
end
|
23
|
+
|
24
|
+
def data
|
25
|
+
return build if self.class.cache_disabled
|
26
|
+
|
27
|
+
cached_data = read_cache
|
28
|
+
|
29
|
+
return cached_data if cached_data
|
30
|
+
|
31
|
+
data = build
|
32
|
+
update_cache(data)
|
33
|
+
|
34
|
+
data
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/spec/integration_spec.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'rddd/
|
3
|
-
require 'rddd/
|
4
|
-
require 'rddd/service_bus'
|
5
|
-
require 'rddd/service'
|
2
|
+
require 'rddd/aggregates/root'
|
3
|
+
require 'rddd/services/service'
|
4
|
+
require 'rddd/services/service_bus'
|
5
|
+
require 'rddd/services/service'
|
6
6
|
|
7
|
-
class Project < Rddd::
|
7
|
+
class Project < Rddd::Aggregates::Root
|
8
8
|
attr_accessor :name
|
9
9
|
end
|
10
10
|
|
11
|
-
class CreateProjectService < Rddd::Service
|
11
|
+
class CreateProjectService < Rddd::Services::Service
|
12
12
|
def execute
|
13
13
|
project = Project.new(@attributes[:id])
|
14
14
|
project.name = @attributes[:name]
|
@@ -24,7 +24,7 @@ class ProjectRepository
|
|
24
24
|
end
|
25
25
|
|
26
26
|
class ProjectsController
|
27
|
-
include Rddd::ServiceBus
|
27
|
+
include Rddd::Services::ServiceBus
|
28
28
|
|
29
29
|
def create(params)
|
30
30
|
execute_service(:create_project, params)
|
@@ -60,8 +60,8 @@ end
|
|
60
60
|
describe 'NotExistingService' do
|
61
61
|
it 'should raise' do
|
62
62
|
controller = Object.new
|
63
|
-
controller.extend Rddd::ServiceBus
|
63
|
+
controller.extend Rddd::Services::ServiceBus
|
64
64
|
|
65
|
-
expect { controller.execute_service(:foo) }.to raise_exception Rddd::ServiceFactory::InvalidService
|
65
|
+
expect { controller.execute_service(:foo) }.to raise_exception Rddd::Services::ServiceFactory::InvalidService
|
66
66
|
end
|
67
67
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rddd/aggregates/entity'
|
3
|
+
|
4
|
+
describe Rddd::Aggregates::Entity do
|
5
|
+
it 'should have identity' do
|
6
|
+
entity = Rddd::Aggregates::Entity.new('1234')
|
7
|
+
|
8
|
+
entity.id.should == '1234'
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'two entities with same identity are equal' do
|
12
|
+
a = Rddd::Aggregates::Entity.new('1234')
|
13
|
+
b = Rddd::Aggregates::Entity.new('1234')
|
14
|
+
|
15
|
+
(a == b).should be_true
|
16
|
+
end
|
17
|
+
end
|
@@ -1,22 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'rddd/
|
2
|
+
require 'rddd/aggregates/root'
|
3
3
|
|
4
|
-
describe Rddd::
|
4
|
+
describe Rddd::Aggregates::Root do
|
5
5
|
let(:id) { stub('id') }
|
6
6
|
|
7
|
-
let(:aggregate_root) { Rddd::
|
7
|
+
let(:aggregate_root) { Rddd::Aggregates::Root.new(id) }
|
8
8
|
|
9
9
|
it 'should be entity' do
|
10
|
-
aggregate_root.should be_kind_of Rddd::Entity
|
10
|
+
aggregate_root.should be_kind_of Rddd::Aggregates::Entity
|
11
11
|
end
|
12
12
|
|
13
13
|
describe '#find' do
|
14
|
-
subject { Rddd::
|
14
|
+
subject { Rddd::Aggregates::Root.find(id) }
|
15
15
|
|
16
16
|
let(:repository) { stub('repository') }
|
17
17
|
|
18
18
|
before {
|
19
|
-
Rddd::
|
19
|
+
Rddd::Repositories::Factory.expects(:build).returns(repository)
|
20
20
|
repository.expects(:find).with(id)
|
21
21
|
}
|
22
22
|
|
@@ -30,7 +30,7 @@ describe Rddd::AggregateRoot do
|
|
30
30
|
let(:repository) { stub('repository') }
|
31
31
|
|
32
32
|
it 'should call #create on repository' do
|
33
|
-
Rddd::
|
33
|
+
Rddd::Repositories::Factory.expects(:build).with(Rddd::Aggregates::Root).returns(repository)
|
34
34
|
|
35
35
|
repository.expects(action).with(subject)
|
36
36
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rddd/aggregates/repositories/factory'
|
3
|
+
|
4
|
+
module Rddd
|
5
|
+
module Repositories
|
6
|
+
describe Factory do
|
7
|
+
let(:project) { stub('project', :name => 'Foo', :class => stub(:name => 'Foo')) }
|
8
|
+
|
9
|
+
let(:repository_creator) do
|
10
|
+
lambda do |clazz|
|
11
|
+
class_name = "#{clazz.name.to_s.camel_case}Repository"
|
12
|
+
Repositories.const_get(class_name.to_sym)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
before do
|
17
|
+
Repositories.const_set(:FooRepository, Class.new)
|
18
|
+
end
|
19
|
+
|
20
|
+
after do
|
21
|
+
Repositories.class_eval { remove_const(:FooRepository) }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '.build' do
|
25
|
+
context 'configuration repository_creator given' do
|
26
|
+
before do
|
27
|
+
Rddd.configure { |config| config.repository_creator = repository_creator }
|
28
|
+
end
|
29
|
+
|
30
|
+
after do
|
31
|
+
Rddd.configure { |config| config.repository_creator = nil }
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should call the appropriate service' do
|
35
|
+
FooRepository.expects(:new)
|
36
|
+
|
37
|
+
Factory.build(project.class)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'configuration repository_creator not given' do
|
42
|
+
it 'should raise exception' do
|
43
|
+
expect { Factory.build(project.class) }.to raise_exception Factory::CreatorNotGiven
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rddd/aggregates/repositories/base'
|
3
|
+
|
4
|
+
module Rddd
|
5
|
+
module Repositories
|
6
|
+
describe Base do
|
7
|
+
let(:repository) { Base.new }
|
8
|
+
|
9
|
+
let(:aggregate_root) { stub('aggregate_root') }
|
10
|
+
|
11
|
+
describe '#create' do
|
12
|
+
subject { repository.create(aggregate_root) }
|
13
|
+
|
14
|
+
it { expect { subject }.to raise_exception NotImplementedError }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#update' do
|
18
|
+
subject { repository.update(aggregate_root) }
|
19
|
+
|
20
|
+
it { expect { subject }.to raise_exception NotImplementedError }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#delete' do
|
24
|
+
subject { repository.delete(aggregate_root) }
|
25
|
+
|
26
|
+
it { expect { subject }.to raise_exception NotImplementedError }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'rddd/service_bus'
|
2
|
+
require 'rddd/services/service_bus'
|
3
3
|
|
4
|
-
describe Rddd::ServiceBus do
|
4
|
+
describe Rddd::Services::ServiceBus do
|
5
5
|
let(:attributes) { stub('attributes') }
|
6
6
|
|
7
7
|
let(:controller) do
|
8
|
-
stub('controller').tap { |controller| controller.extend Rddd::ServiceBus }
|
8
|
+
stub('controller').tap { |controller| controller.extend Rddd::Services::ServiceBus }
|
9
9
|
end
|
10
10
|
|
11
11
|
describe '.execute_service' do
|
@@ -15,7 +15,7 @@ describe Rddd::ServiceBus do
|
|
15
15
|
|
16
16
|
context 'existing service' do
|
17
17
|
it do
|
18
|
-
Rddd::ServiceFactory.expects(:build).with(:foo, attributes).returns(service)
|
18
|
+
Rddd::Services::ServiceFactory.expects(:build).with(:foo, attributes).returns(service)
|
19
19
|
service.expects(:execute)
|
20
20
|
|
21
21
|
subject
|
@@ -27,7 +27,7 @@ describe Rddd::ServiceBus do
|
|
27
27
|
before { service.stubs(:valid?).returns(false) }
|
28
28
|
|
29
29
|
it do
|
30
|
-
Rddd::ServiceFactory.expects(:build).with(:foo, attributes).returns(service)
|
30
|
+
Rddd::Services::ServiceFactory.expects(:build).with(:foo, attributes).returns(service)
|
31
31
|
service.expects(:execute).never
|
32
32
|
|
33
33
|
subject
|
@@ -45,7 +45,7 @@ describe Rddd::ServiceBus do
|
|
45
45
|
let(:error_block) { lambda {|errors|} }
|
46
46
|
|
47
47
|
it do
|
48
|
-
Rddd::ServiceFactory.expects(:build).with(:foo, attributes).returns(service)
|
48
|
+
Rddd::Services::ServiceFactory.expects(:build).with(:foo, attributes).returns(service)
|
49
49
|
service.expects(:execute).never
|
50
50
|
|
51
51
|
controller.execute_service(:foo, attributes, &error_block)
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rddd/services/service_factory'
|
3
|
+
|
4
|
+
module Rddd
|
5
|
+
module Services
|
6
|
+
describe ServiceFactory do
|
7
|
+
let(:attributes) { stub('attributes') }
|
8
|
+
|
9
|
+
let(:service_creator) do
|
10
|
+
lambda do |name|
|
11
|
+
class_name = "#{name.to_s.camel_case}Service"
|
12
|
+
Services.const_get(class_name.to_sym)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
before do
|
17
|
+
Services.const_set(:CreateProjectService, Class.new)
|
18
|
+
end
|
19
|
+
|
20
|
+
after do
|
21
|
+
Services.class_eval {remove_const(:CreateProjectService)}
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '.build' do
|
25
|
+
context 'configuration service_creator given' do
|
26
|
+
before do
|
27
|
+
Rddd.configure { |config| config.service_creator = service_creator }
|
28
|
+
end
|
29
|
+
|
30
|
+
after do
|
31
|
+
Rddd.configure { |config| config.service_creator = nil }
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should call the appropriate service' do
|
35
|
+
CreateProjectService.expects(:new).with(attributes)
|
36
|
+
|
37
|
+
ServiceFactory.build(:create_project, attributes)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'not existing service' do
|
42
|
+
before do
|
43
|
+
Rddd.configure { |config| config.service_creator = service_creator }
|
44
|
+
end
|
45
|
+
|
46
|
+
after do
|
47
|
+
Rddd.configure { |config| config.service_creator = nil }
|
48
|
+
end
|
49
|
+
|
50
|
+
it { expect { ServiceFactory.build(:foo, attributes) }.to raise_exception ServiceFactory::InvalidService }
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'configuration service_creator not given' do
|
54
|
+
it 'should raise exception' do
|
55
|
+
expect { Rddd::Services::ServiceFactory.build(:create_project, attributes) }.to raise_exception Rddd::Services::ServiceFactory::CreatorNotGiven
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rddd/services/service'
|
3
|
+
|
4
|
+
module Rddd
|
5
|
+
module Services
|
6
|
+
describe Service do
|
7
|
+
let(:attributes) { stub('attributes') }
|
8
|
+
|
9
|
+
describe '#initialize' do
|
10
|
+
subject { Service.new(attributes) }
|
11
|
+
|
12
|
+
it 'should store attributes' do
|
13
|
+
subject.instance_variable_get(:@attributes).should == attributes
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#valid?' do
|
18
|
+
subject { Service.new.valid? }
|
19
|
+
it { should be_true }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#execute' do
|
23
|
+
it 'should raise not implemented' do
|
24
|
+
lambda do
|
25
|
+
Service.new(attributes).execute
|
26
|
+
end.should raise_exception(NotImplementedError)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rddd/views/view'
|
3
|
+
require 'rddd/aggregates/repositories/base'
|
4
|
+
|
5
|
+
class ViewRepository < Rddd::Repositories::Base
|
6
|
+
def get(id)
|
7
|
+
end
|
8
|
+
|
9
|
+
def set(id, value, timeout)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Rddd::Views::View do
|
14
|
+
let(:id) { :id }
|
15
|
+
|
16
|
+
let(:view) { Rddd::Views::View.new(id) }
|
17
|
+
|
18
|
+
let(:view_repository) { stub('view_repository') }
|
19
|
+
|
20
|
+
let(:data) { stub('data') }
|
21
|
+
|
22
|
+
subject { view }
|
23
|
+
|
24
|
+
describe '#initialize' do
|
25
|
+
its(:id) { should == id}
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#name' do
|
29
|
+
its(:name) { should == :'rddd::views::view' }
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#build' do
|
33
|
+
subject { view.build }
|
34
|
+
|
35
|
+
it { lambda {subject}.should raise_exception NotImplementedError }
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#warm_cache' do
|
39
|
+
subject { view.warm_cache }
|
40
|
+
|
41
|
+
before do
|
42
|
+
ViewRepository.expects(:new).returns(view_repository)
|
43
|
+
|
44
|
+
view.expects(:build).returns(data)
|
45
|
+
|
46
|
+
view_repository.expects(:set).with("rddd::views::#{:view}#{:id}", data, anything)
|
47
|
+
end
|
48
|
+
|
49
|
+
it { subject }
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#invalidate' do
|
53
|
+
subject { view.invalidate }
|
54
|
+
|
55
|
+
before do
|
56
|
+
ViewRepository.expects(:new).returns(view_repository)
|
57
|
+
|
58
|
+
view_repository.expects(:set).with("rddd::views::#{:view}#{:id}", nil)
|
59
|
+
end
|
60
|
+
|
61
|
+
it { subject }
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#data' do
|
65
|
+
subject { view.data }
|
66
|
+
|
67
|
+
context 'without view repository' do
|
68
|
+
before do
|
69
|
+
view.expects(:build).returns(data)
|
70
|
+
end
|
71
|
+
|
72
|
+
it { subject.should == data }
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'not cached' do
|
76
|
+
before do
|
77
|
+
ViewRepository.expects(:new).returns(view_repository)
|
78
|
+
end
|
79
|
+
|
80
|
+
before do
|
81
|
+
view_repository.expects(:get).with("rddd::views::#{:view}#{:id}").returns(nil)
|
82
|
+
|
83
|
+
view.expects(:build).returns(data)
|
84
|
+
|
85
|
+
view_repository.expects(:set).with("rddd::views::#{:view}#{:id}", data, nil)
|
86
|
+
end
|
87
|
+
|
88
|
+
it { subject.should == data }
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'cached' do
|
92
|
+
before do
|
93
|
+
ViewRepository.expects(:new).returns(view_repository)
|
94
|
+
view_repository.expects(:get).with("rddd::views::#{:view}#{:id}").returns(data)
|
95
|
+
end
|
96
|
+
|
97
|
+
it { subject.should == data }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'cache disabling' do
|
102
|
+
class CacheLessView < Rddd::Views::View
|
103
|
+
cache :enabled => false
|
104
|
+
|
105
|
+
def build
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
let(:id) { stub('id') }
|
110
|
+
|
111
|
+
let(:cache_less_view) do
|
112
|
+
CacheLessView.new(id)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should not try to load data from cache' do
|
116
|
+
ViewRepository.expects(:new).never
|
117
|
+
|
118
|
+
cache_less_view.expects(:build).returns(data)
|
119
|
+
|
120
|
+
cache_less_view.data.should == data
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe 'timeout enabling' do
|
125
|
+
class TimeoutingView < Rddd::Views::View
|
126
|
+
cache :timeout => 24 * 60
|
127
|
+
|
128
|
+
def build
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
let(:id) { :id }
|
133
|
+
|
134
|
+
let(:timeouting_view) do
|
135
|
+
TimeoutingView.new(id)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should set timeout to cache data' do
|
139
|
+
ViewRepository.expects(:new).returns(view_repository)
|
140
|
+
view_repository.expects(:get).with("#{:timeoutingview}#{:id}").returns(nil)
|
141
|
+
|
142
|
+
timeouting_view.expects(:build).returns(data)
|
143
|
+
|
144
|
+
view_repository.expects(:set).with do |got_id, got_data, got_time|
|
145
|
+
got_id == "#{:timeoutingview}#{:id}" &&
|
146
|
+
got_data == data &&
|
147
|
+
got_time.to_i == (Time.now + 24 * 60 * 60).to_i
|
148
|
+
end
|
149
|
+
|
150
|
+
timeouting_view.data
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|