narrative 0.0.1 → 0.0.2

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