-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathspec.cr
141 lines (132 loc) · 4.13 KB
/
spec.cr
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
require "./spec/dsl"
require "./spec/cli"
# Crystal's built-in testing library. It provides a structure for writing executable examples
# of how your code should behave. A domain specific language allows you to write them in a way similar to natural language.
#
# The Crystal compiler has a `spec` command with tools to constrain which examples get run and tailor the output.
#
# A basic spec looks something like this:
#
# ```
# require "spec"
#
# describe Array do
# describe "#size" do
# it "correctly reports the number of elements in the Array" do
# [1, 2, 3].size.should eq 3
# end
# end
#
# describe "#empty?" do
# it "is empty when no elements are in the array" do
# ([] of Int32).empty?.should be_true
# end
#
# it "is not empty if there are elements in the array" do
# [1].empty?.should be_false
# end
# end
#
# # lots more specs
# end
# ```
#
# Test files are structured by use of the `describe` or `context` methods.
# Typically a top level `describe` defines the `outer` unit (such as a class)
# that is to be tested by the spec. Further `describe` calls can be nested within
# the outer unit to specify smaller units under test (such as individual methods).
# `describe` can also be used to set up a certain context - think empty `Array` versus
# `Array` with elements. The `context` method behaves just like the `describe` method
# and may be used instead, to emphasize context to the reader.
#
# Within a `describe` block, concrete test cases are defined with `it` . A
# descriptive string is supplied to `it` describing what the test case
# tests specifically.
#
# Specs then use the `should` method to verify that the expected value is
# returned. See the example above for details.
#
# By convention, specs live in the `spec` directory of a project. You can compile
# and run the specs of a project by running `crystal spec`.
#
# ```console
# # Run all specs in files matching spec/**/*_spec.cr
# crystal spec
#
# # Run all specs in files matching spec/my/test/**/*_spec.cr
# crystal spec spec/my/test/
#
# # Run all specs in spec/my/test/file_spec.cr
# crystal spec spec/my/test/file_spec.cr
#
# # Run the spec or group defined in line 14 of spec/my/test/file_spec.cr
# crystal spec spec/my/test/file_spec.cr:14
#
# # Run all specs tagged with "fast"
# crystal spec --tag 'fast'
#
# # Run all specs not tagged with "slow"
# crystal spec --tag '~slow'
# ```
#
# ## Focusing on a group of specs
#
# A `describe`, `context` or `it` can be marked with `focus: true`, like this:
#
# ```
# it "adds", focus: true do
# (2 + 2).should_not eq(5)
# end
# ```
#
# If any such thing is marked with `focus: true` then only those examples will run.
#
# ## Randomizing order of specs
#
# Specs, by default, run in the order defined, but can be run in a random order
# by passing `--order random` to `crystal spec`.
#
# Specs run in random order will display a seed value upon completion. This seed
# value can be used to rerun the specs in that same order by passing the seed
# value to `--order`.
module Spec
# :nodoc:
class CLI
# :nodoc:
#
# Implement formatter configuration.
def configure_formatter(formatter, output_path = nil)
case formatter
when "junit"
junit_formatter = Spec::JUnitFormatter.file(Path.new(output_path.not_nil!))
add_formatter(junit_formatter)
when "verbose"
override_default_formatter(Spec::VerboseFormatter.new)
when "tap"
override_default_formatter(Spec::TAPFormatter.new)
end
end
def main(args)
Colorize.on_tty_only!
begin
option_parser.parse(args)
rescue e : OptionParser::InvalidOption
abort("Error: #{e.message}")
end
unless args.empty?
STDERR.puts "Error: unknown argument '#{args.first}'"
exit 1
end
if ENV["SPEC_VERBOSE"]? == "1"
override_default_formatter(Spec::VerboseFormatter.new)
end
add_split_filter ENV["SPEC_SPLIT"]?
{% unless flag?(:wasm32) %}
# TODO(wasm): Enable this once `Process.on_terminate` is implemented
Process.on_terminate { abort! }
{% end %}
run
end
end
end
Spec.cli.main(ARGV)