domain_driven 0.0.8.1 → 0.0.8.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9bb12d535dea79b8e0eb9ac30203f27dc0b00670
4
- data.tar.gz: d94e3602f95a715d9c750462e11f4dd452c9c6a4
3
+ metadata.gz: 212330e091078c401fb20be56c0afcbd6ab54743
4
+ data.tar.gz: 5f897a5e7a5a256d69483407f57585ee1551330f
5
5
  SHA512:
6
- metadata.gz: 286f326e5e1ba7621cb5ae31c299bb780e13cd05e92eae88bf28d3e46280a8171cafacc083cdd3c9eaad1ae03cb711ecb34f434b82565206fcc4815859871d15
7
- data.tar.gz: 40c132e2cc378b64db9fd2d189aaa12fe0d4768239fe894f2dae1e899a41171c7110a0b8ea45281241646bb1bd23815bea75c3f47abd49a5c143150435b3a5a0
6
+ metadata.gz: 3a5fa9bb7c91cf0bfa70b02801a3d1dad1c26b4101a147a0cfd3006b5aca48d00fc1cf1c20bfbb5c47a5b7b9a733db2489d3bf2fe91482cbd82bdb43c08817b2
7
+ data.tar.gz: c0d1fe134f69849145a3575c38d03116ee9caec6092cb6dd9a8ba74d3ca50f84646f0c4b586340fb5cbcaece05950d6008dd245022c5fee2b0e0afc11e9dd292
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = DomainDriven::VERSION
9
9
  spec.authors = ["Mark Windholtz", "Rob Biedenharn" ]
10
10
  spec.email = ["mark@agiledna.com", "Rob@AgileConsultingLLC.com"]
11
- spec.summary = %q{Domain Driven provides Rails hooks for a Domain Driven Design}
12
- spec.description = %q{Domain Driven provides Rails abstract classes and generators to support for a Domain Driven Design}
11
+ spec.summary = %q{domain_driven allows Domain Driven Design (DDD) within RubyOnRails }
12
+ spec.description = %q{domain_driven provides Rails abstract classes and generators to support for a Domain Driven Design}
13
13
  spec.homepage = "https://github.com/mwindholtz/domain_driven"
14
14
  spec.license = "MIT"
15
15
 
@@ -35,8 +35,8 @@ module DomainDriven
35
35
 
36
36
  private
37
37
 
38
- def no_db_methods
39
- fail ActiveRecordNotAvailableError, "No DB methods on Business Objects"
40
- end
38
+ def no_db_methods
39
+ fail ActiveRecordNotAvailableError, "No DB methods on Business Objects"
40
+ end
41
41
  end
42
42
  end
@@ -24,17 +24,12 @@ module DomainDriven
24
24
  @chain = []
25
25
  end
26
26
 
27
- def shift(criteria)
27
+ def merge(criteria)
28
28
  criteria.chain.each do |e|
29
29
  add_message(e)
30
30
  end
31
31
  self
32
32
  end
33
-
34
- def unshift(criteria)
35
- criteria.shift(self)
36
- criteria
37
- end
38
33
 
39
34
  # sugar
40
35
  def add(name, *args)
@@ -27,18 +27,19 @@ module DomainDriven
27
27
  def entity?
28
28
  true
29
29
  end
30
-
30
+
31
+ alias :_real_class :class
31
32
  def class
32
33
  _data.class
33
34
  end
34
-
35
+
35
36
  def self.wrap(entity)
36
37
  entity ? new(entity) : nil
37
38
  end
38
39
 
39
40
  def self.wraps(entities)
40
41
  return nil unless entities
41
- wrap(entities.extend Model).extend Collection
42
+ wrap(entities.extend Model).extend Collection
42
43
  end
43
44
 
44
45
  end
@@ -46,9 +47,16 @@ module DomainDriven
46
47
  module Collection
47
48
  def each
48
49
  _data.each do |_item|
49
- yield wrap(_item)
50
+ yield self._real_class.wrap(_item)
51
+ end
52
+ end
53
+
54
+ def to_a
55
+ _data.inject([]) do |array, _item|
56
+ array << self._real_class.wrap(_item)
50
57
  end
51
58
  end
59
+
52
60
  def include?(other)
53
61
  if other.respond_to?(:_data)
54
62
  _data.include?(other._data)
@@ -32,7 +32,7 @@ module DomainDriven
32
32
  raise DomainDriven::Error.new(error)
33
33
  end
34
34
 
35
- end
35
+ end # ClassMethods
36
36
 
37
37
 
38
38
  def self.included(klass)
@@ -1,11 +1,24 @@
1
- class DomainDriven::Repository
2
-
3
- protected
4
- def initialize(name, logger)
5
- @name = name
6
- @logger = logger
1
+ require 'logger'
2
+
3
+ module DomainDriven
4
+ module Repository
5
+ attr_accessor :logger
6
+ def to_s
7
+ "#{@name}"
7
8
  end
8
-
9
- def logger; @logger; end
10
-
9
+
10
+ module ClassMethods
11
+ end
12
+
13
+ protected
14
+ def initialize(name)
15
+ @name = name
16
+ self.logger = Logger.new(STDOUT)
17
+ end
18
+
19
+ def self.included(klass)
20
+ super
21
+ klass.extend ClassMethods
22
+ end
23
+ end
11
24
  end
@@ -12,10 +12,46 @@ module DomainDriven
12
12
  raise
13
13
  rescue Pundit::NotAuthorizedError
14
14
  raise
15
- # rescue => x
16
- # perform_rescue(x)
17
15
  end
18
16
 
17
+ module Repo # this is the Repository Factory
18
+ module_function
19
+
20
+ class << self
21
+ attr_writer :logger, :factory
22
+ end
23
+
24
+ def logger
25
+ @logger ||= Logger.new(STDOUT)
26
+ end
27
+
28
+ def factory
29
+ return @factory if @factory
30
+ raise "Repo has no factory initialized. Add an intializer file with something like this: DomainDriven::Service::Repo.factory = { course: CourseRepository, ...}"
31
+ end
32
+
33
+ def for(name)
34
+ logger.info("Provisioning Repo #{name}")
35
+ if repo_class_name = factory[name]
36
+ repo_class = repo_class_name.to_s.classify.constantize
37
+ repo = repo_class.new(name)
38
+ repo
39
+ else
40
+ raise "repository not found: (#{name})"
41
+ end
42
+ end
43
+
44
+
45
+ def method_missing(name,*args)
46
+ if name.to_s[0...4] == 'for_'
47
+ self.for(name.to_s[4..-1].to_sym)
48
+ else
49
+ super
50
+ end
51
+ end
52
+
53
+ end # module Repo
54
+
19
55
  protected
20
56
  def current_user
21
57
  context[:current_member]
@@ -25,6 +61,10 @@ module DomainDriven
25
61
  context[:request]
26
62
  end
27
63
 
64
+ def criteria
65
+ context[:criteria] || DomainDriven::Criteria.new
66
+ end
67
+
28
68
  def perform_main
29
69
  raise "subclass responsibility for #{self.class} "
30
70
  end
@@ -34,6 +74,11 @@ module DomainDriven
34
74
  context.fail!
35
75
  end
36
76
 
37
- end
77
+ end # class Service
78
+
38
79
 
80
+ class ServiceOrganizer
81
+ include Interactor::Organizer
82
+ end #
83
+
39
84
  end
@@ -1,3 +1,4 @@
1
1
  module DomainDriven
2
- VERSION = "0.0.8.1"
2
+ VERSION = "0.0.8.3"
3
3
  end
4
+
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ class EntityUnderTest < DomainDriven::Entity
4
+ end
5
+
6
+ class RaiseEverything
7
+ def method_missing(name,*args)
8
+ raise "RaiseEverything should never receieve any message"
9
+ end
10
+ end
11
+
12
+ describe 'Entity' do
13
+
14
+ Given! (:model) { RaiseEverything.new }
15
+ Given! (:entity) { EntityUnderTest.new(model) }
16
+
17
+ context 'attempting to call active_record methods should not delegate to the model: ' do
18
+
19
+ context "save" do
20
+ When(:result) { entity.save }
21
+ Then { expect(result).to have_failed(DomainDriven::ActiveRecordNotAvailableError) }
22
+ end
23
+
24
+ context "save!" do
25
+ When(:result) { entity.save! }
26
+ Then { expect(result).to have_failed(DomainDriven::ActiveRecordNotAvailableError) }
27
+ end
28
+
29
+ context "update_attribute" do
30
+ When(:result) { entity.update_attribute }
31
+ Then { expect(result).to have_failed(DomainDriven::ActiveRecordNotAvailableError) }
32
+ end
33
+
34
+ context "update_attribute!" do
35
+ When(:result) { entity.update_attribute! }
36
+ Then { expect(result).to have_failed(DomainDriven::ActiveRecordNotAvailableError) }
37
+ end
38
+
39
+ context "update_attributes" do
40
+ When(:result) { entity.update_attributes }
41
+ Then { expect(result).to have_failed(DomainDriven::ActiveRecordNotAvailableError) }
42
+ end
43
+
44
+ context "update_attributes!" do
45
+ When(:result) { entity.update_attributes! }
46
+ Then { expect(result).to have_failed(DomainDriven::ActiveRecordNotAvailableError) }
47
+ end
48
+
49
+
50
+ end
51
+ end
@@ -10,16 +10,11 @@ describe 'Criteria' do
10
10
  Given { criteria1.where("id=5") }
11
11
  Given { criteria2.page("3") }
12
12
 
13
- context "shift" do
14
- When(:result) { criteria1.shift(criteria2) }
13
+ context "merge" do
14
+ When(:result) { criteria1.merge(criteria2) }
15
15
  Then { result.to_s.should eq("target.where(id=5).page(3)") }
16
16
  end
17
17
 
18
- context "unshift" do
19
- When(:result) { criteria2.unshift(criteria1) }
20
- Then { result.to_s.should eq("target.where(id=5).page(3)") }
21
- end
22
-
23
18
  end
24
19
 
25
20
  context "empty criteria has no effect" do
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ class EntityUnderTest < DomainDriven::Entity
4
+ def some_biz_logic; 42; end
5
+ end
6
+
7
+ describe 'Entity' do
8
+
9
+ Given! (:model) { FakeModel.new }
10
+ Given! (:entity) { EntityUnderTest.wrap(model) }
11
+
12
+ context 'has model as _data ' do
13
+ Then { entity.entity?.should == true }
14
+ Then { entity._data.entity?.should == false }
15
+ Then { entity._data.should == model}
16
+ end
17
+
18
+ context 'same as _data ' do
19
+ Then { entity._data == entity}
20
+ end
21
+
22
+ context 'same as self' do
23
+ Then { entity == entity}
24
+ end
25
+
26
+ context 'class name' do
27
+ context 'wrap same class as model' do
28
+ Then { entity.class.to_s == "FakeModel" }
29
+ end
30
+
31
+ context 'wrap nil is still nil' do
32
+ When(:entity) { EntityUnderTest.wrap(nil) }
33
+ Then { entity.class.to_s == "NilClass"}
34
+ end
35
+
36
+ context 'wraps nil is still nil' do
37
+ When(:entity_list) { EntityUnderTest.wraps(nil) }
38
+ Then { entity_list.class.to_s == "NilClass"}
39
+ end
40
+
41
+ context 'class wraps a set of models' do
42
+ When(:entity_list) { EntityUnderTest.wraps( [model, model]) }
43
+ Then { entity_list.class.to_s == "Array"}
44
+ end
45
+
46
+ context 'class wraps each model into a set of models' do
47
+ When(:entity_list) { EntityUnderTest.wraps( [model, model]) }
48
+ Then { entity_list.each{|e| e.should be_entity } }
49
+ Then { entity_list.each{|e| e.some_biz_logic.should == 42 } }
50
+ end
51
+
52
+ end
53
+
54
+ def self.wrap(entity)
55
+ entity ? new(entity) : nil
56
+ end
57
+
58
+
59
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Model' do
4
+
5
+ Given! (:model) { FakeModel.new }
6
+
7
+ Then { model._data === model }
8
+ Then { model.entity? == false }
9
+
10
+
11
+ context "find" do
12
+ When(:result) { FakeModel.find('ignore') }
13
+ Then { expect(result).to have_failed( DomainDriven::RecordNotFound, 'clever message' ) }
14
+ end
15
+
16
+
17
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Repository' do
4
+
5
+ Given! (:repository) { RepositoryUnderTest.new(:fake_repo) }
6
+
7
+ Then { repository.to_s == 'fake_repo'}
8
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ require 'logger'
3
+
4
+ class FakeService < DomainDriven::Service
5
+ def perform_main
6
+ context[:course] = 'Its a horse-course of course'
7
+ end
8
+
9
+ end
10
+
11
+ describe 'Service' do
12
+
13
+ context 'performing' do
14
+ When(:result) { FakeService.perform(request: {id: 123}, current_member: 'a-user',
15
+ page_param: 1,
16
+ logger: Logger.new($stdout)) }
17
+ Then { result.context[:course] == 'Its a horse-course of course' }
18
+ Then { result.context[:request][:id] == 123 }
19
+ end
20
+
21
+ context 'repository exists' do
22
+
23
+ Given(:repo) { DomainDriven::Service::Repo }
24
+ Given { repo.logger = FastSpecLogger.instance }
25
+
26
+
27
+ context 'lookup by string class name' do
28
+ Given { repo.factory = { course: 'FakeRepository' } }
29
+
30
+ context 'direct lookup ' do
31
+ When(:result) { repo.for(:course) }
32
+ Then { result.class.should == FakeRepository }
33
+ end
34
+
35
+ context 'method_missing lookup ' do
36
+ When(:result) { repo.for_course }
37
+ Then { result.class.should == FakeRepository }
38
+ end
39
+ end
40
+
41
+ context 'lookup by symbol' do
42
+ Given { repo.factory = { course: :fake_repository } }
43
+ When(:result) { repo.for(:course) }
44
+ Then { result.class.should == FakeRepository }
45
+ end
46
+
47
+ context 'lookup by lowercase string' do
48
+ Given { repo.factory = { course: 'fake_repository' } }
49
+ When(:result) { repo.for(:course) }
50
+ Then { result.class.should == FakeRepository }
51
+ end
52
+
53
+ end
54
+
55
+
56
+ end
@@ -1,6 +1,31 @@
1
1
  require 'rubygems'
2
2
  require 'rspec-given'
3
3
  require 'domain_driven'
4
+ require 'ostruct'
5
+
6
+ module ActiveRecord
7
+ class RecordNotFound < StandardError
8
+ end
9
+ end
10
+
11
+ class RepositoryUnderTest
12
+ include DomainDriven::Repository
13
+ end
14
+
15
+ class FakeRepository
16
+ include DomainDriven::Repository
17
+ end
18
+
19
+ class FakeBaseModel
20
+ def self.find(*)
21
+ raise(ActiveRecord::RecordNotFound.new('clever message'))
22
+ end
23
+ end
24
+
25
+ class FakeModel < FakeBaseModel
26
+ include DomainDriven::Model
27
+ def course_type; 'A'; end
28
+ end
4
29
 
5
30
  module Given
6
31
  module ClassExtensions
@@ -8,3 +33,13 @@ module Given
8
33
  alias Whereas! Given!
9
34
  end
10
35
  end
36
+
37
+ class FastSpecLogger
38
+ def self.instance
39
+ @instance ||= FastSpecLogger.new
40
+ end
41
+
42
+ def initialize; @last_error = ''; end
43
+ def error(value); @last_error = value; end
44
+ def info(value); @last_error = value; end
45
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: domain_driven
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8.1
4
+ version: 0.0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Windholtz
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-05 00:00:00.000000000 Z
12
+ date: 2014-03-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -123,7 +123,7 @@ dependencies:
123
123
  - - ">="
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
- description: Domain Driven provides Rails abstract classes and generators to support
126
+ description: domain_driven provides Rails abstract classes and generators to support
127
127
  for a Domain Driven Design
128
128
  email:
129
129
  - mark@agiledna.com
@@ -148,7 +148,12 @@ files:
148
148
  - lib/domain_driven/repository.rb
149
149
  - lib/domain_driven/service.rb
150
150
  - lib/domain_driven/version.rb
151
+ - spec/domain_driven/block_active_record_spec.rb
151
152
  - spec/domain_driven/criteria_spec.rb
153
+ - spec/domain_driven/entity_spec.rb
154
+ - spec/domain_driven/model_spec.rb
155
+ - spec/domain_driven/repository_spec.rb
156
+ - spec/domain_driven/service_spec.rb
152
157
  - spec/spec_helper.rb
153
158
  homepage: https://github.com/mwindholtz/domain_driven
154
159
  licenses:
@@ -173,7 +178,12 @@ rubyforge_project:
173
178
  rubygems_version: 2.2.2
174
179
  signing_key:
175
180
  specification_version: 4
176
- summary: Domain Driven provides Rails hooks for a Domain Driven Design
181
+ summary: domain_driven allows Domain Driven Design (DDD) within RubyOnRails
177
182
  test_files:
183
+ - spec/domain_driven/block_active_record_spec.rb
178
184
  - spec/domain_driven/criteria_spec.rb
185
+ - spec/domain_driven/entity_spec.rb
186
+ - spec/domain_driven/model_spec.rb
187
+ - spec/domain_driven/repository_spec.rb
188
+ - spec/domain_driven/service_spec.rb
179
189
  - spec/spec_helper.rb