Skip to content

Commit 844cc6e

Browse files
straight-shootaRX14
authored andcommittedOct 26, 2017
Add docs to expectations methods (#5092)
* Add docs to expectations methods * improve wording and example code for `be` matchers * Add documentation to other Spec methods * Improve wording in spec preface
1 parent 4e079f9 commit 844cc6e

File tree

3 files changed

+90
-11
lines changed

3 files changed

+90
-11
lines changed
 

‎src/spec.cr

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
require "./spec/dsl"
22

3-
# Crystal's built-in testing library.
3+
# Crystal's built-in testing library. It provides a structure for writing executable examples
4+
# of how your code should behave. A domain specific language allows you to write them in a way similar to natural language.
5+
#
6+
# The Crystal compiler has a `spec` command with tools to constrain which examples get run and tailor the output.
47
#
58
# A basic spec looks something like this:
69
#
710
# ```
811
# require "spec"
912
#
10-
# describe "Array" do
13+
# describe Array do
1114
# describe "#size" do
1215
# it "correctly reports the number of elements in the Array" do
1316
# [1, 2, 3].size.should eq 3
@@ -45,21 +48,19 @@ require "./spec/dsl"
4548
# returned. See the example above for details.
4649
#
4750
# By convention, specs live in the `spec` directory of a project. You can compile
48-
# and run the specs of a project by running:
51+
# and run the specs of a project by running `crystal spec`.
4952
#
5053
# ```shell
54+
# # Run all specs in files matching spec/**/*_spec.cr
5155
# crystal spec
52-
# ```
5356
#
54-
# You can also compile and run individual spec files by providing their path:
57+
# # Run all specs in files matching spec/my/test/**/*_spec.cr
58+
# crystal spec spec/my/test/
5559
#
56-
# ```shell
60+
# # Run all specs in spec/my/test/file_spec.cr
5761
# crystal spec spec/my/test/file_spec.cr
58-
# ```
59-
#
60-
# In addition, you may run individual specs by providing a line number:
6162
#
62-
# ```shell
63+
# # Run the spec or group defined in line 14 of spec/my/test/file_spec.cr
6364
# crystal spec spec/my/test/file_spec.cr:14
6465
# ```
6566
module Spec

‎src/spec/expectations.cr

+37-1
Original file line numberDiff line numberDiff line change
@@ -200,62 +200,92 @@ module Spec
200200
end
201201
end
202202

203+
# This module defines a number of methods to create expectations, which are
204+
# automatically included into the top level namespace.
205+
#
206+
# Expectations are used by `Spec::ObjectExtensions#should` and `Spec::ObjectExtensions#should_not`.
203207
module Expectations
208+
# Creates an `Expectation` that passes if actual equals *value* (`==`).
204209
def eq(value)
205210
Spec::EqualExpectation.new value
206211
end
207212

213+
# Creates an `Expectation` that passes if actual and *value* are identical (`.same?`).
208214
def be(value)
209215
Spec::BeExpectation.new value
210216
end
211217

218+
# Creates an `Expectation` that passes if actual is true (`== true`).
212219
def be_true
213220
eq true
214221
end
215222

223+
# Creates an `Expectation` that passes if actual is false (`== false`).
216224
def be_false
217225
eq false
218226
end
219227

228+
# Creates an `Expectation` that passes if actual is truthy (neither `nil` nor `false`).
220229
def be_truthy
221230
Spec::BeTruthyExpectation.new
222231
end
223232

233+
# Creates an `Expectation` that passes if actual is falsy (`nil` or `false`).
224234
def be_falsey
225235
Spec::BeFalseyExpectation.new
226236
end
227237

238+
# Creates an `Expectation` that passes if actual is nil (`== nil`).
228239
def be_nil
229240
Spec::BeNilExpectation.new
230241
end
231242

243+
# Creates an `Expectation` that passes if actual is within *delta* of *expected*.
232244
def be_close(expected, delta)
233245
Spec::CloseExpectation.new(expected, delta)
234246
end
235247

248+
# Returns a factory to create a comparison `Expectation` that:
249+
#
250+
# * passes if actual is lesser than *value*: `be < value`
251+
# * passes if actual is lesser than or equal *value*: `be <= value`
252+
# * passes if actual is greater than *value*: `be > value`
253+
# * passes if actual is greater than or equal *value*: `be >= value`
236254
def be
237255
Spec::Be
238256
end
239257

258+
# Creates an `Expectation` that passes if actual matches *value* (`=~`).
240259
def match(value)
241260
Spec::MatchExpectation.new(value)
242261
end
243262

244-
# Passes if actual includes *expected*. Works on collections and `String`.
263+
# Creates an `Expectation` that passes if actual includes *expected* (`.includes?`).
264+
# Works on collections and `String`.
245265
def contain(expected)
246266
Spec::ContainExpectation.new(expected)
247267
end
248268

269+
# Creates an `Expectation` that passes if actual is of type *type* (`is_a?`).
249270
macro be_a(type)
250271
Spec::BeAExpectation({{type}}).new
251272
end
252273

274+
# Runs the block and passes if it raises an exception of type *klass*.
275+
#
276+
# It returns the rescued exception.
253277
macro expect_raises(klass)
254278
expect_raises({{klass}}, nil) do
255279
{{yield}}
256280
end
257281
end
258282

283+
# Runs the block and passes if it raises an exception of type *klass* and the error message matches.
284+
#
285+
# If *message* is a string, it matches if the exception's error message contains that string.
286+
# If *message* is a regular expression, it is used to match the error message.
287+
#
288+
# It returns the rescued exception.
259289
macro expect_raises(klass, message, file = __FILE__, line = __LINE__)
260290
%failed = false
261291
begin
@@ -297,12 +327,18 @@ module Spec
297327
end
298328

299329
module ObjectExtensions
330+
# Validates an expectation and fails the example if it does not match.
331+
#
332+
# See `Spec::Expecations` for available expectations.
300333
def should(expectation, file = __FILE__, line = __LINE__)
301334
unless expectation.match self
302335
fail(expectation.failure_message(self), file, line)
303336
end
304337
end
305338

339+
# Validates an expectation and fails the example if it matches.
340+
#
341+
# See `Spec::Expecations` for available expectations.
306342
def should_not(expectation, file = __FILE__, line = __LINE__)
307343
if expectation.match self
308344
fail(expectation.negative_failure_message(self), file, line)

‎src/spec/methods.cr

+42
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,40 @@
11
module Spec::Methods
2+
# Defines an example group that describes a unit to be tested.
3+
# Inside *&block* examples are defined by `#it` or `#pending`.
4+
#
5+
# Several `describe` blocks can be nested.
6+
#
7+
# Example:
8+
# ```
9+
# describe "Int32" do
10+
# describe "+" do
11+
# it "adds" { (1 + 1).should eq 2 }
12+
# end
13+
# end
14+
# ```
215
def describe(description, file = __FILE__, line = __LINE__, &block)
316
Spec::RootContext.describe(description.to_s, file, line, &block)
417
end
518

19+
# Defines an example group that establishes a specifc context,
20+
# like *empty array* versus *array with elements*.
21+
# Inside *&block* examples are defined by `#it` or `#pending`.
22+
#
23+
# It is functionally equivalent to `#describe`.
624
def context(description, file = __FILE__, line = __LINE__, &block)
725
describe(description.to_s, file, line, &block)
826
end
927

28+
# Defines a concrete test case.
29+
#
30+
# The test is performed by the block supplied to *&block*.
31+
#
32+
# Example:
33+
# ```
34+
# it "adds" { (1 + 1).should eq 2 }
35+
# ```
36+
#
37+
# It is usually used inside a `#describe` or `#context` section.
1038
def it(description = "assert", file = __FILE__, line = __LINE__, end_line = __END_LINE__, &block)
1139
return unless Spec.matches?(description, file, line, end_line)
1240

@@ -28,6 +56,17 @@ module Spec::Methods
2856
end
2957
end
3058

59+
# Defines a pending test case.
60+
#
61+
# *&block* is never evaluated.
62+
# It can be used to describe behaviour that is not yet implemented.
63+
#
64+
# Example:
65+
# ```
66+
# pending "check cat" { cat.alive? }
67+
# ```
68+
#
69+
# It is usually used inside a `#describe` or `#context` section.
3170
def pending(description = "assert", file = __FILE__, line = __LINE__, end_line = __END_LINE__, &block)
3271
return unless Spec.matches?(description, file, line, end_line)
3372

@@ -41,6 +80,9 @@ module Spec::Methods
4180
{{ raise "'assert' was removed: use 'it' instead".id }}
4281
end
4382

83+
# Fails an example.
84+
#
85+
# This method can be used to manually fail an example defined in an `#it` block.
4486
def fail(msg, file = __FILE__, line = __LINE__)
4587
raise Spec::AssertionFailed.new(msg, file, line)
4688
end

0 commit comments

Comments
 (0)
Please sign in to comment.