code_driven_development 0.0.2 → 0.0.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: c144f5b085c9dd8d557b3603539d0d48d20a9e7b
4
- data.tar.gz: d3efd3ac64d9c9ce5f68d26db313468dc75705db
3
+ metadata.gz: b09b6d5336aaa29537662229c0c204572ee2e81d
4
+ data.tar.gz: 610a995a3c9012fbd5d6ff374b096793e6fbf259
5
5
  SHA512:
6
- metadata.gz: 59908017bb8718d06e375823a82cc6e621492748ce239b588b0bdf163f66957c206a35cd29742ebd8286cb7f595480427e676f832758976f4af1bfc12e94fe9d
7
- data.tar.gz: 743edeb664f209fcfc5aec2c827b7b9a899a57b1c8a2308b6d6c2a73e3122553d8bb50bee47dbb9daff1988c22822c516551971beacdca031971feaae5d3d761
6
+ metadata.gz: e83e416be1af608df38ae343b34e7c10dc6775a98f8b3290348eeb4bc4634a83c39beb0aaca10498697ba8761ef89672ff7985f021ee5ee6754b5522af94884d
7
+ data.tar.gz: 900dd1f8ce764b77eec4126e39d66d5c5d2028696bd24a3cb7d6d7ef749f9d631408639bd0c30bb672413c481c724506398264343bbb7f43907f49bade1c3076
data/README.md CHANGED
@@ -13,6 +13,7 @@ class Bunker < ActiveRecord::Base
13
13
  end
14
14
 
15
15
  def alert_president
16
+ alert_staff
16
17
  SecretService.stand_down
17
18
  President.alert
18
19
  end
@@ -22,25 +23,32 @@ end
22
23
  And this is what CDD thinks of it:
23
24
 
24
25
  ``` ruby
26
+
25
27
  describe Bunker do
26
28
  it { should validate_secure_of :password }
27
29
  it { should validate_protected_of :location }
28
-
30
+
29
31
  describe "#alert_staff" do
32
+ let(:obj) { described_class.new }
30
33
  before do
31
34
  allow(Staff).to receive :alert_all
32
- described_class.new.alert_staff
35
+ obj.alert_staff
33
36
  end
34
37
  it "calls Staff.alert_all" do
35
38
  expect(Staff).to have_received :alert_all
36
39
  end
37
40
  end
38
-
41
+
39
42
  describe "#alert_president" do
43
+ let(:obj) { described_class.new }
40
44
  before do
45
+ allow(obj).to receive :alert_staff
41
46
  allow(SecretService).to receive :stand_down
42
47
  allow(President).to receive :alert
43
- described_class.new.alert_president
48
+ obj.alert_president
49
+ end
50
+ it "calls #alert_staff" do
51
+ expect(obj).to have_received :alert_staff
44
52
  end
45
53
  it "calls SecretService.stand_down" do
46
54
  expect(SecretService).to have_received :stand_down
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "bundler", "~> 1.3"
24
24
  spec.add_development_dependency "rake"
25
25
  spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency "pry"
26
27
  end
@@ -8,10 +8,12 @@ require "code_driven_development/test_component/test"
8
8
  require "code_driven_development/test_component/one_line_test"
9
9
  require "code_driven_development/test_component/context"
10
10
  require "code_driven_development/test_component/blank_slate"
11
+ require "code_driven_development/test_component/let"
11
12
 
12
13
  require "code_driven_development/rule/abstract_rule"
13
14
  require "code_driven_development/rule/set"
14
- require "code_driven_development/rule/method_call"
15
+ require "code_driven_development/rule/constant_method_call"
16
+ require "code_driven_development/rule/instance_method_call"
15
17
  require "code_driven_development/rule/default"
16
18
  require "code_driven_development/rule/class"
17
19
  require "code_driven_development/rule/validation"
@@ -23,7 +23,8 @@ module CodeDrivenDevelopment
23
23
  Rule::Class,
24
24
  Rule::Validation,
25
25
  Rule::InstanceMethod,
26
- Rule::MethodCall,
26
+ Rule::ConstantMethodCall,
27
+ Rule::InstanceMethodCall,
27
28
  default: Rule::Default
28
29
  )
29
30
  end
@@ -0,0 +1,35 @@
1
+ module CodeDrivenDevelopment
2
+ module Rule
3
+ class ConstantMethodCall < AbstractRule
4
+ def capable?
5
+ code.sexp_type == :call &&
6
+ method_name != :validate &&
7
+ receiver_type == :const
8
+ end
9
+
10
+ def test
11
+ test_context.befores << "allow(#{receiver_value}).to receive :#{method_name}"
12
+ body = ["expect(#{receiver_value}).to have_received :#{method_name}"]
13
+ test_context << TestComponent::Test.new("calls #{receiver_value}.#{method_name}", body)
14
+ end
15
+
16
+ private
17
+
18
+ def receiver_value
19
+ receiver.value
20
+ end
21
+
22
+ def receiver_type
23
+ receiver && receiver.sexp_type
24
+ end
25
+
26
+ def receiver
27
+ code[1]
28
+ end
29
+
30
+ def method_name
31
+ code[2]
32
+ end
33
+ end
34
+ end
35
+ end
@@ -11,7 +11,8 @@ module CodeDrivenDevelopment
11
11
  test_context << new_context
12
12
 
13
13
  # Do this last so that the method invocation is the last line in the before.
14
- new_context.befores << "described_class.new.#{method_name}"
14
+ new_context.befores << "obj.#{method_name}"
15
+ new_context.lets << TestComponent::Let.new(:obj, "described_class.new")
15
16
  end
16
17
 
17
18
  private
@@ -0,0 +1,35 @@
1
+ module CodeDrivenDevelopment
2
+ module Rule
3
+ class InstanceMethodCall < AbstractRule
4
+ def capable?
5
+ code.sexp_type == :call &&
6
+ method_name != :validate &&
7
+ receiver_type.nil?
8
+ end
9
+
10
+ def test
11
+ test_context.befores << "allow(#{receiver_value}).to receive :#{method_name}"
12
+ body = ["expect(#{receiver_value}).to have_received :#{method_name}"]
13
+ test_context << TestComponent::Test.new("calls ##{method_name}", body)
14
+ end
15
+
16
+ private
17
+
18
+ def receiver_value
19
+ "obj"
20
+ end
21
+
22
+ def receiver_type
23
+ receiver && receiver.sexp_type
24
+ end
25
+
26
+ def receiver
27
+ code[1]
28
+ end
29
+
30
+ def method_name
31
+ code[2]
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,11 +1,11 @@
1
1
  module CodeDrivenDevelopment
2
2
  module TestComponent
3
3
  class Context
4
- def initialize(description = nil, befores = [], tests = [])
5
- @description, @befores, @tests = description, befores, tests
4
+ def initialize(description = nil, befores = [], tests = [], lets = [])
5
+ @description, @befores, @tests, @lets = description, befores, tests, lets
6
6
  end
7
7
 
8
- attr_reader :tests, :befores
8
+ attr_reader :tests, :befores, :lets
9
9
  attr_accessor :description
10
10
 
11
11
  def << child
@@ -16,6 +16,9 @@ module CodeDrivenDevelopment
16
16
  io << ""
17
17
  io << "describe #@description do"
18
18
  io.indented do
19
+ lets.each do |let|
20
+ let.indented_output(io)
21
+ end
19
22
  if befores.any?
20
23
  io << "before do"
21
24
  io.indented do
@@ -0,0 +1,13 @@
1
+ module CodeDrivenDevelopment
2
+ module TestComponent
3
+ class Let
4
+ def initialize(name, value)
5
+ @name, @value = name, value
6
+ end
7
+
8
+ def indented_output(io)
9
+ io << "let(:#@name) { #@value }"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module CodeDrivenDevelopment
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -7,6 +7,7 @@ class Bunker < ActiveRecord::Base
7
7
  end
8
8
 
9
9
  def alert_president
10
+ alert_staff
10
11
  SecretService.stand_down
11
12
  President.alert
12
13
  end
data/spec/my_spec.rb CHANGED
@@ -9,6 +9,14 @@ describe CodeDrivenDevelopment::CodeDrivenDevelopment do
9
9
  def i_call_things
10
10
  CentralBureaucracy.file_report
11
11
  end
12
+
13
+ def i_call_instance_methods
14
+ meth
15
+ end
16
+
17
+ def weigh_options
18
+ should_i_stay || should_i_go
19
+ end
12
20
  end
13
21
  EOT
14
22
 
@@ -23,14 +31,42 @@ describe CodeDrivenDevelopment::CodeDrivenDevelopment do
23
31
  expect(@test).to match /^\tit.*should.*validate_presence_of.*:cuteness/
24
32
  end
25
33
 
26
- it "stubs out method calls" do
34
+ it "stubs out method calls to constants" do
27
35
  expect(@test).to have_consecutive_lines_matching [
28
36
  /^\tdescribe.*"#i_call_things"/,
29
37
  /^\t\tbefore/,
30
38
  /^\t\t\tallow.CentralBureaucracy..to.*receive.*:file_report/,
31
- /^\t\t\tdescribed_class.new.i_call_things/,
39
+ /^\t\t\tobj.i_call_things/,
32
40
  /^\t\tit.*calls Central.*do/,
33
41
  /^\t\t\texpect.CentralBureaucracy..to.*have_received.*:file_report/
34
42
  ]
35
43
  end
44
+
45
+ it "stubs out instance method calls" do
46
+ expect(@test).to have_consecutive_lines_matching [
47
+ /^\tdescribe.*"#i_call_instance_methods"/,
48
+ /^\t\tlet.:obj.*described_class.new/,
49
+ /^\t\tbefore/,
50
+ /^\t\t\tallow.obj..to.*receive.*:meth/,
51
+ /^\t\t\tobj.i_call_instance_methods/,
52
+ /^\t\tit.*calls #meth.*do/,
53
+ /^\t\t\texpect.obj..to.*have_received.*:meth/
54
+ ]
55
+ end
56
+
57
+ it "handles ORs with aplomb" do
58
+ expect(@test).to have_consecutive_lines_matching [
59
+ /^\tdescribe.*"#weigh_options"/,
60
+ /^\t\tlet.:obj.*described_class.new/,
61
+ /^\t\tbefore/,
62
+ /^\t\t\tallow.obj..to.*receive.*:should_i_stay/,
63
+ /^\t\t\tallow.obj..to.*receive.*:should_i_go/,
64
+ /^\t\tcontext.*when.*should_i_stay.*truthy/,
65
+ /^\t\tbefore do/,
66
+ /^\t\t\t
67
+ /^\t\t\tobj.weigh_options/,
68
+ /^\t\tit.*calls #meth.*do/,
69
+ /^\t\t\texpect.obj..to.*have_received.*:meth/
70
+ ]
71
+ end
36
72
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code_driven_development
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Finnie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-02 00:00:00.000000000 Z
11
+ date: 2014-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby_parser
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  description: Automatically generate stubby tests from your implementation.
70
84
  email:
71
85
  - dan@danfinnie.com
@@ -87,17 +101,19 @@ files:
87
101
  - lib/code_driven_development/indented_output.rb
88
102
  - lib/code_driven_development/rule/abstract_rule.rb
89
103
  - lib/code_driven_development/rule/class.rb
104
+ - lib/code_driven_development/rule/constant_method_call.rb
90
105
  - lib/code_driven_development/rule/default.rb
91
106
  - lib/code_driven_development/rule/instance_method.rb
92
- - lib/code_driven_development/rule/method_call.rb
107
+ - lib/code_driven_development/rule/instance_method_call.rb
93
108
  - lib/code_driven_development/rule/set.rb
94
109
  - lib/code_driven_development/rule/validation.rb
95
110
  - lib/code_driven_development/test_component/blank_slate.rb
96
111
  - lib/code_driven_development/test_component/context.rb
112
+ - lib/code_driven_development/test_component/let.rb
97
113
  - lib/code_driven_development/test_component/one_line_test.rb
98
114
  - lib/code_driven_development/test_component/test.rb
99
115
  - lib/code_driven_development/version.rb
100
- - samples/validations.rb
116
+ - samples/president.rb
101
117
  - spec/my_spec.rb
102
118
  - spec/spec_helper.rb
103
119
  - spec/support/have_consecutive_lines_matching_matcher.rb
@@ -1,26 +0,0 @@
1
- module CodeDrivenDevelopment
2
- module Rule
3
- class MethodCall < AbstractRule
4
- def capable?
5
- code.sexp_type == :call &&
6
- method_name != :validate
7
- end
8
-
9
- def test
10
- test_context.befores << "allow(#{receiver}).to receive :#{method_name}"
11
- body = ["expect(#{receiver}).to have_received :#{method_name}"]
12
- test_context << TestComponent::Test.new("calls #{receiver}.#{method_name}", body)
13
- end
14
-
15
- private
16
-
17
- def receiver
18
- code[1].value
19
- end
20
-
21
- def method_name
22
- code[2]
23
- end
24
- end
25
- end
26
- end