-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslides.rb
222 lines (183 loc) · 5.32 KB
/
slides.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# encoding: utf-8
def b(str)
"\e[1m#{str}\e[0m"
end
center <<~EOS
#{b 'A bit of RSpec history'}
Josua Schmid
@schmijos
Railshöck Spring 2019
EOS
section 'What is RSpec' do
block <<~EOS
A library for Behaviour Driven Development
The three amigos discuss specifications
and gather a common understanding.
#{b 'Not'} verification testing #{b 'but'} behaviour specification
EOS
code <<~EOS
describe 'hash generation' do
context 'of the first position' do
subject { instance[0].to_h }
let(:bbs_attributes) do
{
subpositions: [
a_hash_including(product_code: bse.product_code),
a_hash_including(product_code: bso.product_code),
a_hash_including(product_code: bss.product_code)
]
}
end
it { is_expected.to include(bbs_attributes) }
end
end
EOS
block <<~EOS
RSpec Timeline:
* 2004 "Why your code sucks" of Dave Astel
* 2005 Reference implementation of Steven Baker
* 2006 v0.7 uses now RSpec instead of TestUnit
* 2007 v0.8 switches to expectation matchers
* 2007 v1.0 (Ruby 1.8)
* 2010 v2.0 (Ruby 1.9) takes in micronaut runner
* 2014 v3.0 (Ruby 2.1)
EOS
block <<~EOS
Cucumber Timeline:
* 2004 JBehave
* 2007 RBehave
* 2007 RBehave becomes RSpec story runner
* 2009 Cucumber gets extracted
EOS
end
section '2005 – RSpec v0.1' do
code File.read('./rspec-0.1.0_2005/test_spec.rb')
code <<~EOS
def should_include(sub, message=nil)
message ||= "<\#{self.inspect}> should include <\#{sub.inspect}>"
\e[32mshould\e[0m(message) { self.include? sub }
end
EOS
code <<~EOS
def \e[32mshould\e[0m(message=nil)
message ||= "Expectation not met."
if (! yield)
raise Spec::Exceptions::ExpectationNotMetError.new(message)
end
end
EOS
end
section '2006 – RSpec v0.3' do
code File.read('./rspec-0.3.2_2006/test_spec.rb')
block <<~EOS
"specification" is aliased if an environment variable is defined
USER=marick bundle exec spec ./test_spec.rb
EOS
end
section '2007 – RSpec v0.8' do
code File.read('./rspec-0.8.2_2007/test1_spec.rb')
code File.read('./rspec-0.8.2_2007/test2_spec.rb')
code File.read('./rspec-0.8.2_2007/test3_spec.rb')
code File.read('./rspec-0.8.2_2007/test4_spec.rb')
end
section '2009 – RSpec v1.2' do
code File.read('./rspec-1.2.9_2009/test1_spec.rb')
code File.read('./rspec-1.2.9_2009/test2_spec.rb')
code <<~EOS
# lib/spec/matchers/include.rb
if actual.is_a?(Hash)
if expected.is_a?(Hash)
expected.each_pair do |k,v|
return false unless actual[k] == v
end
else
return false unless actual.has_key?(expected)
end
else
return false unless actual.include?(expected)
end
return true
EOS
end
section '2013 – RSpec v2.13' do
code File.read('./rspec-2.13.0_2013/test_new_spec.rb')
code <<~EOS
# lib/rspec/matchers/built_in/include.rb
if comparing_hash_values?(actuals, expected)
expected.__send__(hash_predicate) { |k,v|
actuals.has_key?(k) && actuals[k] == v
}
elsif comparing_hash_keys?(actuals, expected)
actuals.has_key?(expected)
elsif comparing_with_matcher?(actual, expected)
actual.any? { |value| \e[32mexpected.matches?(value)\e[0m }
else
actuals.include?(expected)
end
EOS
end
section '2014 – RSpec v3.0' do
code File.read('./rspec-3.0.0_2014/test_spec.rb')
code <<~EOS
# lib/rspec/matchers.rb
def include(*expected)
BuiltIn::Include.new(*expected)
end
alias_matcher :a_collection_including, :include
alias_matcher :a_string_including, :include
alias_matcher :a_hash_including, :include
alias_matcher :including, :include
EOS
code <<~EOS
class Include < BaseMatcher; … end
class BaseMatcher
include RSpec::Matchers::Composable
end
module Composable
def and(matcher) …
def or(matcher) …
def values_match?(expected, actual) …
end
EOS
code <<~EOS
# lib/rspec/matchers/composable.rb
def values_match?(expected, actual)
expected = with_matchers_cloned(expected)
Support::FuzzyMatcher.values_match?(expected, actual)
end
EOS
code <<~EOS
# lib/rspec/support/fuzzy_matcher.rb
def self.hashes_match?(expected_hash, actual_hash)
return false if expected_hash.size != actual_hash.size
expected_hash.all? do |expected_key, expected_value|
actual_value = actual_hash.fetch(expected_key) { return false }
\e[32mvalues_match?(expected_value, actual_value)\e[0m
end
end
EOS
end
section 'Future' do
code <<~EOS
describe 'Renuo knows and teaches' do
let(:employees) do
[
{ name: 'Alessandro', knows: %w(Rails Cancancan), teaches: %w('Rails')},
{ name: 'Josua', knows: %w(Ruby) }
]
end
it 'can do rails' do
employees.should include(a_hash_including(
a_string_matching(/knows|teaches/): a_collection_including('Rails')
))
end
end
EOS
code <<~EOS
# spec/rspec/support/fuzzy_matcher_spec.rb:118
it 'does not fuzzy match on keys' do
expect(/foo/ => 1).not_to match_against("foo" => 1)
end
EOS
end
center 'Thank you!'