narrative 0.0.1 → 0.0.2

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: 7c2af8f475764b8c72d356ad9175a8d993f38c57
4
- data.tar.gz: bfec77ba8e70dd340bd07d02c966a285c3279e96
3
+ metadata.gz: 4be14aa29aa4368e0cd86bfce8682eb9e01bf261
4
+ data.tar.gz: 107c00177921a2d3ea4d96059bb15cf9110363fe
5
5
  SHA512:
6
- metadata.gz: cde76f1dde76492243dae1983fb5037cd1c34f67dc7b87eccd52f6d73d1d28c9ec9542fc025dfa46efd6369a7d7c142602456f9e4e6f4a54b897df01940a4504
7
- data.tar.gz: 4b488d38c59cfe34292d25061c8d6114f117c4be876d136e0d08c8dd4c127221a0aa142268eb1ef4fda3513bb7904580ca9791da8ec54f98064f8ba7c8a21f31
6
+ metadata.gz: 1cfb7f996f64b1a7a8b37628a4325e962ee3b44614585fd5def54e7f66522f2b2b49210ba82df718dccfe14231731d6a8b52d6bb3bd0b43a4d30d85206d85832
7
+ data.tar.gz: 7a6ae0d04bb3e8d0130ba937ca7c28b0c1a63d606daf73bc91691805eec2f1bd2fcd169e08f72ee18979abf7383b15cfd68fe21cc13e5ac725d856f40cb8e220
data/.travis.yml CHANGED
@@ -1,3 +1,5 @@
1
1
  language: ruby
2
2
  rvm: 2.1.1
3
- cache: [bundler]
3
+ cache: [bundler, apt]
4
+ before_install:
5
+ - 'gem install bundler'
data/Gemfile CHANGED
@@ -1,2 +1,9 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
+
4
+ group :development do
5
+ gem 'bundler', '>= 1.5.3'
6
+ gem 'pry'
7
+ gem 'rake'
8
+ gem 'rspec', '~> 3.0.0.beta2'
9
+ end
@@ -4,14 +4,15 @@ module Narrative
4
4
  module Context
5
5
  module Teller
6
6
  def with_context(context_name, data, &block)
7
- context_for(context_name).bind! data, &block
7
+ context_for(context_name, data).perform(&block)
8
8
  end
9
9
 
10
10
  private
11
11
 
12
- def context_for(name)
12
+ def context_for(name, data)
13
13
  context_names = name.split << 'context'
14
- context_names.map(&:capitalize).join.constantize
14
+ context_class = context_names.map(&:capitalize).join.constantize
15
+ context_class.new(data)
15
16
  end
16
17
  end
17
18
  end
@@ -1,34 +1,41 @@
1
1
  require 'active_support'
2
+ require_relative 'role_definition'
2
3
 
3
4
  module Narrative
4
5
  module Context
5
6
  extend ActiveSupport::Concern
6
7
 
7
8
  included do
8
- cattr_reader(:roles, instance_accessor: false) { {} }
9
+ cattr_reader(:roles) { [] }
9
10
  end
10
11
 
11
12
  module ClassMethods
12
- def role(name, &block)
13
- roles[name] = block
13
+ def role(name, partners: [], &block)
14
+ roles << RoleDefinition.new(name, partners, &block)
15
+ define_method(name.to_sym) { @actors[name] }
14
16
  end
17
+ end
15
18
 
16
- def bind!(data, &block)
17
- block.call bind_roles!(data, &block)
18
- end
19
+ def initialize(data)
20
+ validate!(data)
19
21
 
20
- private
22
+ @actors = cast!(data)
23
+ end
21
24
 
22
- def bind_roles!(data, &block)
23
- context_roles = block.parameters.map(&:last)
24
- context_roles.each_with_object({}) {|role_name, actors|
25
- actors[role_name] = cast!(data[role_name], &roles[role_name])
26
- }
27
- end
25
+ def perform(&block)
26
+ block.call @actors.slice(*block.parameters.map(&:last))
27
+ end
28
+
29
+ private
30
+
31
+ def validate!(data)
32
+ raise 'data and role definition did not same' if data.keys.to_set != roles.map(&:name).to_set
33
+ raise 'data did not allow to contain nil' if data.values.include?(nil)
34
+ end
28
35
 
29
- def cast!(datum, &method_block)
30
- datum.instance_eval(&method_block)
31
- datum
36
+ def cast!(data)
37
+ roles.each_with_object({}) do |role_definition, memo|
38
+ memo[role_definition.name] = role_definition.cast!(data)
32
39
  end
33
40
  end
34
41
  end
@@ -0,0 +1,37 @@
1
+ module Narrative
2
+ module Context
3
+ class RoleDefinition
4
+ attr_reader :name
5
+
6
+ def initialize(name, partners, &responsibilities)
7
+ @name = name
8
+ @partners = partners
9
+ @responsibilities = responsibilities
10
+ end
11
+
12
+ def cast!(actors)
13
+ actor = actor!(actors)
14
+ relationship!(actor, actors)
15
+
16
+ actor
17
+ end
18
+
19
+ private
20
+
21
+ def actor!(actors)
22
+ actor = actors[@name]
23
+ actor.instance_eval(&@responsibilities)
24
+ actor
25
+ end
26
+
27
+ def relationship!(actor, actors)
28
+ klass = class << actor; self end
29
+ actors.slice(*@partners).each do |role_name, partner|
30
+ klass.instance_eval do
31
+ define_method(role_name) { partner }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,3 +1,3 @@
1
1
  module Narrative
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
data/narrative.gemspec CHANGED
@@ -18,8 +18,4 @@ Gem::Specification.new do |spec|
18
18
  spec.require_paths = ['lib']
19
19
 
20
20
  spec.add_dependency 'activesupport', '>= 3.0'
21
-
22
- spec.add_development_dependency 'bundler', '~> 1.5.3'
23
- spec.add_development_dependency 'rake'
24
- spec.add_development_dependency 'rspec', '~> 3.0.0.beta2'
25
21
  end
@@ -14,23 +14,96 @@ describe Narrative::Context do
14
14
  role :product_owner do; end
15
15
  end
16
16
 
17
- it { expect(ProjectContext.roles).to include(:programmer) }
18
- it { expect(ProjectContext.roles).not_to include(:product_owner) }
17
+ subject { ProjectContext.roles.map(&:name) }
18
+
19
+ it { is_expected.to include(:programmer) }
20
+ it { is_expected.not_to include(:product_owner) }
21
+ end
22
+
23
+ describe 'cast roles to data' do
24
+ class ProjectContext
25
+ include Narrative::Context
26
+
27
+ role :programmer do
28
+ def coding; end
29
+ end
30
+
31
+ role :tester do
32
+ def report_bug; end
33
+ end
34
+ end
35
+
36
+ let(:data) { {programmer: 'alice', tester: 'bob' } }
37
+
38
+ subject { ProjectContext.new(data) }
39
+
40
+ context 'programmer alice and tester bob' do
41
+ it { is_expected.to respond_to(:programmer) }
42
+ it { is_expected.to respond_to(:tester) }
43
+ end
44
+
45
+ context 'tester is require but absent' do
46
+ let(:data) { {programmer: 'alice', tester: nil} }
47
+
48
+ it { expect { ProjectContext.new(data) }.to raise_error }
49
+ end
50
+
51
+ context 'excessive role' do
52
+ let(:data) { {programmer: 'alice', tester: 'bob', product_owner: 'charlie'} }
53
+
54
+ it { expect { ProjectContext.new(data) }.to raise_error }
55
+ end
56
+ end
57
+
58
+ describe 'can refer to other roles' do
59
+ class BugfixContext
60
+ include Narrative::Context
61
+
62
+ role :programmer do
63
+ def correct!(code)
64
+ code.modified!
65
+ end
66
+ end
67
+
68
+ role :tester, partners: [:programmer] do
69
+ def report_bug(code)
70
+ programmer.correct!(code)
71
+ end
72
+ end
73
+ end
74
+
75
+ specify do
76
+ code = double('defected code')
77
+ allow(code).to receive(:modified!)
78
+
79
+ BugfixContext.new(programmer: 'alice', tester: 'bob').perform do |programmer:, tester:|
80
+ tester.report_bug(code)
81
+ end
82
+
83
+ expect(code).to have_received(:modified!).once
84
+ end
19
85
  end
20
86
 
21
- describe '.bind' do
87
+ describe '#perform' do
22
88
  class ProjectContext
23
89
  include Narrative::Context
24
90
 
25
91
  role :programmer do
26
92
  def coding; end
27
93
  end
94
+
95
+ role :tester do
96
+ def report_bug; end
97
+ end
28
98
  end
29
99
 
30
100
  specify do
31
101
  called = false
32
- ProjectContext.bind! programmer: 'alice' do |programmer:|
33
- expect(programmer).to respond_to(:coding)
102
+ context = ProjectContext.new({programmer: 'alice', tester: 'bob'})
103
+
104
+ context.perform do |programmer:, tester:|
105
+ expect(programmer).to eq(context.programmer)
106
+ expect(tester).to eq(context.tester)
34
107
 
35
108
  called = true
36
109
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: narrative
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takuya Watanabe
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-16 00:00:00.000000000 Z
12
+ date: 2014-04-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -25,48 +25,6 @@ dependencies:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: '3.0'
28
- - !ruby/object:Gem::Dependency
29
- name: bundler
30
- requirement: !ruby/object:Gem::Requirement
31
- requirements:
32
- - - "~>"
33
- - !ruby/object:Gem::Version
34
- version: 1.5.3
35
- type: :development
36
- prerelease: false
37
- version_requirements: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - "~>"
40
- - !ruby/object:Gem::Version
41
- version: 1.5.3
42
- - !ruby/object:Gem::Dependency
43
- name: rake
44
- requirement: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: '0'
49
- type: :development
50
- prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: '0'
56
- - !ruby/object:Gem::Dependency
57
- name: rspec
58
- requirement: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - "~>"
61
- - !ruby/object:Gem::Version
62
- version: 3.0.0.beta2
63
- type: :development
64
- prerelease: false
65
- version_requirements: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - "~>"
68
- - !ruby/object:Gem::Version
69
- version: 3.0.0.beta2
70
28
  description: a simple implementation of DCI.
71
29
  email:
72
30
  - tkywtnb@gmail.com
@@ -85,6 +43,7 @@ files:
85
43
  - lib/narrative.rb
86
44
  - lib/narrative/context.rb
87
45
  - lib/narrative/context/teller.rb
46
+ - lib/narrative/role_definition.rb
88
47
  - lib/narrative/version.rb
89
48
  - narrative.gemspec
90
49
  - spec/lib/narrative/context/teller_spec.rb