domain_driven 0.0.8.1 → 0.0.8.3

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 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