mspec 1.0.0
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.
- data/LICENSE +22 -0
- data/README +101 -0
- data/Rakefile +44 -0
- data/bin/mkspec +7 -0
- data/bin/mspec +7 -0
- data/bin/mspec-ci +8 -0
- data/bin/mspec-run +8 -0
- data/bin/mspec-tag +8 -0
- data/lib/mspec.rb +6 -0
- data/lib/mspec/commands/mkspec.rb +147 -0
- data/lib/mspec/commands/mspec-ci.rb +71 -0
- data/lib/mspec/commands/mspec-run.rb +80 -0
- data/lib/mspec/commands/mspec-tag.rb +87 -0
- data/lib/mspec/commands/mspec.rb +143 -0
- data/lib/mspec/expectations.rb +2 -0
- data/lib/mspec/expectations/expectations.rb +12 -0
- data/lib/mspec/expectations/should.rb +23 -0
- data/lib/mspec/guards.rb +13 -0
- data/lib/mspec/guards/bug.rb +27 -0
- data/lib/mspec/guards/compliance.rb +18 -0
- data/lib/mspec/guards/conflict.rb +16 -0
- data/lib/mspec/guards/endian.rb +40 -0
- data/lib/mspec/guards/extensions.rb +12 -0
- data/lib/mspec/guards/guard.rb +120 -0
- data/lib/mspec/guards/noncompliance.rb +12 -0
- data/lib/mspec/guards/platform.rb +38 -0
- data/lib/mspec/guards/quarantine.rb +15 -0
- data/lib/mspec/guards/runner.rb +30 -0
- data/lib/mspec/guards/superuser.rb +15 -0
- data/lib/mspec/guards/support.rb +12 -0
- data/lib/mspec/guards/version.rb +40 -0
- data/lib/mspec/helpers.rb +6 -0
- data/lib/mspec/helpers/bignum.rb +5 -0
- data/lib/mspec/helpers/const_lookup.rb +5 -0
- data/lib/mspec/helpers/flunk.rb +5 -0
- data/lib/mspec/helpers/io.rb +13 -0
- data/lib/mspec/helpers/scratch.rb +17 -0
- data/lib/mspec/helpers/tmp.rb +32 -0
- data/lib/mspec/matchers.rb +16 -0
- data/lib/mspec/matchers/base.rb +95 -0
- data/lib/mspec/matchers/be_ancestor_of.rb +24 -0
- data/lib/mspec/matchers/be_close.rb +27 -0
- data/lib/mspec/matchers/be_empty.rb +20 -0
- data/lib/mspec/matchers/be_false.rb +20 -0
- data/lib/mspec/matchers/be_kind_of.rb +24 -0
- data/lib/mspec/matchers/be_nil.rb +20 -0
- data/lib/mspec/matchers/be_true.rb +20 -0
- data/lib/mspec/matchers/complain.rb +56 -0
- data/lib/mspec/matchers/eql.rb +26 -0
- data/lib/mspec/matchers/equal.rb +26 -0
- data/lib/mspec/matchers/equal_utf16.rb +34 -0
- data/lib/mspec/matchers/include.rb +32 -0
- data/lib/mspec/matchers/output.rb +67 -0
- data/lib/mspec/matchers/output_to_fd.rb +71 -0
- data/lib/mspec/matchers/raise_error.rb +48 -0
- data/lib/mspec/mocks.rb +3 -0
- data/lib/mspec/mocks/mock.rb +123 -0
- data/lib/mspec/mocks/object.rb +28 -0
- data/lib/mspec/mocks/proxy.rb +112 -0
- data/lib/mspec/runner.rb +13 -0
- data/lib/mspec/runner/actions.rb +6 -0
- data/lib/mspec/runner/actions/debug.rb +17 -0
- data/lib/mspec/runner/actions/filter.rb +40 -0
- data/lib/mspec/runner/actions/gdb.rb +17 -0
- data/lib/mspec/runner/actions/tag.rb +97 -0
- data/lib/mspec/runner/actions/tally.rb +80 -0
- data/lib/mspec/runner/actions/timer.rb +22 -0
- data/lib/mspec/runner/filters.rb +4 -0
- data/lib/mspec/runner/filters/match.rb +22 -0
- data/lib/mspec/runner/filters/profile.rb +54 -0
- data/lib/mspec/runner/filters/regexp.rb +7 -0
- data/lib/mspec/runner/filters/tag.rb +29 -0
- data/lib/mspec/runner/formatters.rb +7 -0
- data/lib/mspec/runner/formatters/dotted.rb +81 -0
- data/lib/mspec/runner/formatters/html.rb +87 -0
- data/lib/mspec/runner/formatters/specdoc.rb +27 -0
- data/lib/mspec/runner/formatters/spinner.rb +89 -0
- data/lib/mspec/runner/formatters/summary.rb +8 -0
- data/lib/mspec/runner/formatters/unit.rb +25 -0
- data/lib/mspec/runner/formatters/yaml.rb +43 -0
- data/lib/mspec/runner/mspec.rb +232 -0
- data/lib/mspec/runner/object.rb +20 -0
- data/lib/mspec/runner/shared.rb +12 -0
- data/lib/mspec/runner/state.rb +116 -0
- data/lib/mspec/runner/tag.rb +20 -0
- data/lib/mspec/utils/name_map.rb +130 -0
- data/lib/mspec/utils/options.rb +344 -0
- data/lib/mspec/utils/script.rb +77 -0
- data/lib/mspec/version.rb +3 -0
- data/spec/commands/mkspec_spec.rb +321 -0
- data/spec/commands/mspec_ci_spec.rb +139 -0
- data/spec/commands/mspec_run_spec.rb +146 -0
- data/spec/commands/mspec_spec.rb +359 -0
- data/spec/commands/mspec_tag_spec.rb +131 -0
- data/spec/expectations/expectations_spec.rb +16 -0
- data/spec/expectations/should_spec.rb +99 -0
- data/spec/guards/bug_spec.rb +137 -0
- data/spec/guards/compliance_spec.rb +70 -0
- data/spec/guards/conflict_spec.rb +20 -0
- data/spec/guards/endian_spec.rb +42 -0
- data/spec/guards/extensions_spec.rb +36 -0
- data/spec/guards/guard_spec.rb +355 -0
- data/spec/guards/noncompliance_spec.rb +36 -0
- data/spec/guards/platform_spec.rb +84 -0
- data/spec/guards/quarantine_spec.rb +19 -0
- data/spec/guards/runner_spec.rb +75 -0
- data/spec/guards/superuser_spec.rb +22 -0
- data/spec/guards/support_spec.rb +22 -0
- data/spec/guards/version_spec.rb +133 -0
- data/spec/helpers/bignum_spec.rb +11 -0
- data/spec/helpers/const_lookup_spec.rb +19 -0
- data/spec/helpers/flunk_spec.rb +15 -0
- data/spec/helpers/io_spec.rb +34 -0
- data/spec/helpers/scratch_spec.rb +22 -0
- data/spec/helpers/tmp_spec.rb +72 -0
- data/spec/matchers/base_spec.rb +180 -0
- data/spec/matchers/be_ancestor_of_spec.rb +28 -0
- data/spec/matchers/be_close_spec.rb +46 -0
- data/spec/matchers/be_empty_spec.rb +26 -0
- data/spec/matchers/be_false_spec.rb +28 -0
- data/spec/matchers/be_kind_of_spec.rb +29 -0
- data/spec/matchers/be_nil_spec.rb +27 -0
- data/spec/matchers/be_true_spec.rb +28 -0
- data/spec/matchers/complain_spec.rb +52 -0
- data/spec/matchers/eql_spec.rb +33 -0
- data/spec/matchers/equal_spec.rb +33 -0
- data/spec/matchers/equal_utf16_spec.rb +47 -0
- data/spec/matchers/include_spec.rb +37 -0
- data/spec/matchers/output_spec.rb +74 -0
- data/spec/matchers/output_to_fd_spec.rb +33 -0
- data/spec/matchers/raise_error_spec.rb +56 -0
- data/spec/mocks/mock_spec.rb +272 -0
- data/spec/mocks/proxy_spec.rb +259 -0
- data/spec/runner/actions/debug_spec.rb +61 -0
- data/spec/runner/actions/filter_spec.rb +84 -0
- data/spec/runner/actions/gdb_spec.rb +61 -0
- data/spec/runner/actions/tag_spec.rb +253 -0
- data/spec/runner/actions/tally_spec.rb +107 -0
- data/spec/runner/actions/timer_spec.rb +42 -0
- data/spec/runner/filters/a.yaml +4 -0
- data/spec/runner/filters/b.yaml +11 -0
- data/spec/runner/filters/match_spec.rb +44 -0
- data/spec/runner/filters/profile_spec.rb +117 -0
- data/spec/runner/filters/regexp_spec.rb +13 -0
- data/spec/runner/filters/tag_spec.rb +77 -0
- data/spec/runner/formatters/dotted_spec.rb +184 -0
- data/spec/runner/formatters/html_spec.rb +191 -0
- data/spec/runner/formatters/specdoc_spec.rb +57 -0
- data/spec/runner/formatters/spinner_spec.rb +78 -0
- data/spec/runner/formatters/summary_spec.rb +29 -0
- data/spec/runner/formatters/unit_spec.rb +71 -0
- data/spec/runner/formatters/yaml_spec.rb +123 -0
- data/spec/runner/mspec_spec.rb +393 -0
- data/spec/runner/shared_spec.rb +41 -0
- data/spec/runner/state_spec.rb +535 -0
- data/spec/runner/tag_spec.rb +93 -0
- data/spec/runner/tags.txt +3 -0
- data/spec/spec_helper.rb +46 -0
- data/spec/utils/name_map_spec.rb +178 -0
- data/spec/utils/options_spec.rb +862 -0
- data/spec/utils/script_spec.rb +240 -0
- metadata +217 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class SpecTag
|
|
2
|
+
attr_accessor :tag, :comment, :description
|
|
3
|
+
|
|
4
|
+
def initialize(string=nil)
|
|
5
|
+
parse(string) if string
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def parse(string)
|
|
9
|
+
m = /^([^()#:]+)(\(([^)]+)?\))?:(.*)/.match string
|
|
10
|
+
@tag, @comment, @description = m.values_at(1, 3, 4) if m
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_s
|
|
14
|
+
"#{@tag}#{ "(#{@comment})" if @comment }:#{@description}"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def ==(o)
|
|
18
|
+
@tag == o.tag and @comment == o.comment and @description == o.description
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
require 'mspec/helpers/const_lookup'
|
|
2
|
+
|
|
3
|
+
class NameMap
|
|
4
|
+
MAP = {
|
|
5
|
+
'`' => 'backtick',
|
|
6
|
+
'+' => 'plus',
|
|
7
|
+
'-' => 'minus',
|
|
8
|
+
'+@' => 'uplus',
|
|
9
|
+
'-@' => 'uminus',
|
|
10
|
+
'*' => 'multiply',
|
|
11
|
+
'/' => 'divide',
|
|
12
|
+
'%' => 'modulo',
|
|
13
|
+
'<<' => {'Bignum' => 'left_shift',
|
|
14
|
+
'Fixnum' => 'left_shift',
|
|
15
|
+
'IO' => 'output',
|
|
16
|
+
:default => 'append' },
|
|
17
|
+
'>>' => 'right_shift',
|
|
18
|
+
'<' => 'lt',
|
|
19
|
+
'<=' => 'lte',
|
|
20
|
+
'>' => 'gt',
|
|
21
|
+
'>=' => 'gte',
|
|
22
|
+
'=' => 'assignment',
|
|
23
|
+
'==' => 'equal_value',
|
|
24
|
+
'===' => 'case_compare',
|
|
25
|
+
'<=>' => 'comparison',
|
|
26
|
+
'[]' => 'element_reference',
|
|
27
|
+
'[]=' => 'element_set',
|
|
28
|
+
'**' => 'exponent',
|
|
29
|
+
'!' => 'not',
|
|
30
|
+
'~' => {'Bignum' => 'complement',
|
|
31
|
+
'Fixnum' => 'complement',
|
|
32
|
+
'Regexp' => 'match',
|
|
33
|
+
'String' => 'match' },
|
|
34
|
+
'!=' => 'not_equal',
|
|
35
|
+
'!~' => 'not_match',
|
|
36
|
+
'=~' => 'match',
|
|
37
|
+
'&' => {'Bignum' => 'bit_and',
|
|
38
|
+
'Fixnum' => 'bit_and',
|
|
39
|
+
'Array' => 'intersection',
|
|
40
|
+
'TrueClass' => 'and',
|
|
41
|
+
'FalseClass' => 'and',
|
|
42
|
+
'NilClass' => 'and',
|
|
43
|
+
'Set' => 'intersection' },
|
|
44
|
+
'|' => {'Bignum' => 'bit_or',
|
|
45
|
+
'Fixnum' => 'bit_or',
|
|
46
|
+
'Array' => 'union',
|
|
47
|
+
'TrueClass' => 'or',
|
|
48
|
+
'FalseClass' => 'or',
|
|
49
|
+
'NilClass' => 'or',
|
|
50
|
+
'Set' => 'union' },
|
|
51
|
+
'^' => {'Bignum' => 'bit_xor',
|
|
52
|
+
'Fixnum' => 'bit_xor',
|
|
53
|
+
'TrueClass' => 'xor',
|
|
54
|
+
'FalseClass' => 'xor',
|
|
55
|
+
'NilClass' => 'xor',
|
|
56
|
+
'Set' => 'exclusion'},
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
EXCLUDED = %w[
|
|
60
|
+
MSpecScript
|
|
61
|
+
MkSpec
|
|
62
|
+
DTracer
|
|
63
|
+
NameMap
|
|
64
|
+
OptionParser
|
|
65
|
+
YAML
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
def initialize(filter=false)
|
|
69
|
+
@seen = {}
|
|
70
|
+
@filter = filter
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def exception?(name)
|
|
74
|
+
return false unless c = class_or_module(name)
|
|
75
|
+
c == Errno or c.ancestors.include? Exception
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def class_or_module(c)
|
|
79
|
+
const = const_lookup(c)
|
|
80
|
+
filtered = @filter && EXCLUDED.include?(const.name)
|
|
81
|
+
return const if Module === const and not filtered
|
|
82
|
+
rescue NameError
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def namespace(mod, const)
|
|
86
|
+
return const.to_s if mod.nil? or %w[Object Class Module].include? mod
|
|
87
|
+
"#{mod}::#{const}"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def map(hash, constants, mod=nil)
|
|
91
|
+
@seen = {} unless mod
|
|
92
|
+
|
|
93
|
+
constants.each do |const|
|
|
94
|
+
name = namespace mod, const
|
|
95
|
+
m = class_or_module name
|
|
96
|
+
next unless m and not @seen[m]
|
|
97
|
+
@seen[m] = true
|
|
98
|
+
|
|
99
|
+
ms = m.methods false
|
|
100
|
+
hash["#{name}."] = ms.sort unless ms.empty?
|
|
101
|
+
|
|
102
|
+
ms = m.public_instance_methods(false) +
|
|
103
|
+
m.private_instance_methods(false) +
|
|
104
|
+
m.protected_instance_methods(false)
|
|
105
|
+
hash["#{name}#"] = ms.sort unless ms.empty?
|
|
106
|
+
|
|
107
|
+
map hash, m.constants, name
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
hash
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def dir_name(c, base)
|
|
114
|
+
return File.join(base, 'exception') if exception? c
|
|
115
|
+
|
|
116
|
+
c.split('::').inject(base) do |dir, name|
|
|
117
|
+
name.gsub!(/Class/, '') unless name == 'Class'
|
|
118
|
+
File.join dir, name.downcase
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def file_name(m, c)
|
|
123
|
+
if MAP.key?(m)
|
|
124
|
+
name = MAP[m].is_a?(Hash) ? MAP[m][c.split('::').last] || MAP[m][:default] : MAP[m]
|
|
125
|
+
else
|
|
126
|
+
name = m.gsub(/[?!=]/, '')
|
|
127
|
+
end
|
|
128
|
+
"#{name}_spec.rb"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# FIXME: There are essentially two options for these runner
|
|
2
|
+
# scripts: 1. all in one file, 2. in separate files. The fact
|
|
3
|
+
# that the subcommands share a number of options weighs
|
|
4
|
+
# toward having a single script. However, the subcommands
|
|
5
|
+
# also take specialized options which can be confusing. Added
|
|
6
|
+
# to this the support for switches to specify a different
|
|
7
|
+
# implementation and the balance swings to separate scripts.
|
|
8
|
+
#
|
|
9
|
+
# Now, the fun begins. The main script needs a way to specify
|
|
10
|
+
# certain command line options and then pass the rest to the
|
|
11
|
+
# invoked subscript. Unfortunately, this possibility does not
|
|
12
|
+
# exist in the universe inhabited by OptionParser or GetoptLong.
|
|
13
|
+
#
|
|
14
|
+
# The #filter! method below does not properly handle optional
|
|
15
|
+
# arguments to a switch.
|
|
16
|
+
class OptionParser
|
|
17
|
+
class Switch
|
|
18
|
+
def consume?(opt)
|
|
19
|
+
if opt == short.to_s or opt == long.to_s
|
|
20
|
+
return arg ? 2 : 1
|
|
21
|
+
elsif opt[0..1] == short.to_s and opt.size > 2
|
|
22
|
+
return 1
|
|
23
|
+
else
|
|
24
|
+
return 0
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def filter!(argv)
|
|
30
|
+
@stack.inject(options=[]) do |list, entry|
|
|
31
|
+
entry.list.each do |switch|
|
|
32
|
+
next unless switch.kind_of? OptionParser::Switch
|
|
33
|
+
list << switch
|
|
34
|
+
end
|
|
35
|
+
list
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
filtered = []
|
|
39
|
+
recognized = []
|
|
40
|
+
consume = nil
|
|
41
|
+
until argv.empty?
|
|
42
|
+
opt = argv.shift
|
|
43
|
+
options.find { |o| consume = o.consume?(opt); consume != 0 }
|
|
44
|
+
if consume == 0
|
|
45
|
+
filtered << opt
|
|
46
|
+
else
|
|
47
|
+
recognized << opt
|
|
48
|
+
recognized << argv.shift if consume == 2
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
argv.replace recognized
|
|
52
|
+
filtered
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
require 'mspec/version'
|
|
57
|
+
|
|
58
|
+
# MSpecOptions wraps OptionParser and provides a composable set of
|
|
59
|
+
# options that the runner scripts pick from.
|
|
60
|
+
class MSpecOptions
|
|
61
|
+
attr_reader :parser
|
|
62
|
+
|
|
63
|
+
def initialize(config, command, *args)
|
|
64
|
+
@parser = OptionParser.new(*args) do |opts|
|
|
65
|
+
opts.banner = "mspec #{command} [options] (FILE|DIRECTORY|GLOB)+"
|
|
66
|
+
opts.separator ""
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
@config = config
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def add_config(&block)
|
|
73
|
+
on("-B", "--config FILE", String,
|
|
74
|
+
"Load FILE containing configuration options", &block)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def add_name
|
|
78
|
+
on("-n", "--name RUBY_NAME", String,
|
|
79
|
+
"Set the value of RUBY_NAME (used to determine the implementation)") do |n|
|
|
80
|
+
Object.const_set :RUBY_NAME, n
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def add_targets
|
|
85
|
+
on("-t", "--target TARGET", String,
|
|
86
|
+
"Implementation to run the specs, where:") do |t|
|
|
87
|
+
case t
|
|
88
|
+
when 'r', 'ruby'
|
|
89
|
+
@config[:target] = 'ruby'
|
|
90
|
+
@config[:flags] << '-v'
|
|
91
|
+
when 'r19', 'ruby19'
|
|
92
|
+
@config[:target] = 'ruby19'
|
|
93
|
+
when 'x', 'rubinius'
|
|
94
|
+
@config[:target] = 'shotgun/rubinius'
|
|
95
|
+
when 'X', 'rbx'
|
|
96
|
+
@config[:target] = 'rbx'
|
|
97
|
+
when 'j', 'jruby'
|
|
98
|
+
@config[:target] = 'jruby'
|
|
99
|
+
else
|
|
100
|
+
@config[:target] = t
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
separator ""
|
|
105
|
+
separator " 'r' or 'ruby' invokes ruby in PATH"
|
|
106
|
+
separator " 'r19' or 'ruby19' invokes ruby19 in PATH"
|
|
107
|
+
separator " 'x' or 'rubinius' invokes ./shotgun/rubinius"
|
|
108
|
+
separator " 'X' or 'rbx' invokes rbx in PATH"
|
|
109
|
+
separator " 'j' or 'jruby' invokes jruby in PATH\n"
|
|
110
|
+
|
|
111
|
+
on("-T", "--target-opt OPT", String,
|
|
112
|
+
"Pass OPT as a flag to the target implementation") do |t|
|
|
113
|
+
@config[:flags] << t
|
|
114
|
+
end
|
|
115
|
+
on("-I", "--include DIR", String,
|
|
116
|
+
"Pass DIR through as the -I option to the target") do |d|
|
|
117
|
+
@config[:includes] << "-I#{d}"
|
|
118
|
+
end
|
|
119
|
+
on("-r", "--require LIBRARY", String,
|
|
120
|
+
"Pass LIBRARY through as the -r option to the target") do |f|
|
|
121
|
+
@config[:requires] << "-r#{f}"
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def add_tags_dir
|
|
126
|
+
on("-X", "--tags-dir DIR", String,
|
|
127
|
+
"Use DIR as the path prefix for locating spec tag files") do |d|
|
|
128
|
+
@config[:tags_dir] = d
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def add_formatters
|
|
133
|
+
on("-f", "--format FORMAT", String,
|
|
134
|
+
"Formatter for reporting, where FORMAT is one of:") do |o|
|
|
135
|
+
case o
|
|
136
|
+
when 's', 'spec', 'specdoc'
|
|
137
|
+
@config[:formatter] = SpecdocFormatter
|
|
138
|
+
when 'h', 'html'
|
|
139
|
+
@config[:formatter] = HtmlFormatter
|
|
140
|
+
when 'd', 'dot', 'dotted'
|
|
141
|
+
@config[:formatter] = DottedFormatter
|
|
142
|
+
when 'u', 'unit', 'unitdiff'
|
|
143
|
+
@config[:formatter] = UnitdiffFormatter
|
|
144
|
+
when 'm', 'summary'
|
|
145
|
+
@config[:formatter] = SummaryFormatter
|
|
146
|
+
when 'a', '*', 'spin'
|
|
147
|
+
@config[:formatter] = SpinnerFormatter
|
|
148
|
+
when 'y', 'yaml'
|
|
149
|
+
@config[:formatter] = YamlFormatter
|
|
150
|
+
else
|
|
151
|
+
puts "Unknown format: #{o}"
|
|
152
|
+
puts @parser
|
|
153
|
+
exit
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
separator("")
|
|
157
|
+
separator(" s, spec, specdoc SpecdocFormatter")
|
|
158
|
+
separator(" h, html, HtmlFormatter")
|
|
159
|
+
separator(" d, dot, dotted DottedFormatter")
|
|
160
|
+
separator(" u, unit, unitdiff UnitdiffFormatter")
|
|
161
|
+
separator(" m, summary SummaryFormatter")
|
|
162
|
+
separator(" a, *, spin SpinnerFormatter")
|
|
163
|
+
separator(" y, yaml YamlFormatter\n")
|
|
164
|
+
on("-o", "--output FILE", String,
|
|
165
|
+
"Write formatter output to FILE") do |f|
|
|
166
|
+
@config[:output] = f
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def add_filters
|
|
171
|
+
on("-e", "--example STR", String,
|
|
172
|
+
"Run examples with descriptions matching STR") do |o|
|
|
173
|
+
@config[:includes] << o
|
|
174
|
+
end
|
|
175
|
+
on("-E", "--exclude STR", String,
|
|
176
|
+
"Exclude examples with descriptions matching STR") do |o|
|
|
177
|
+
@config[:excludes] << o
|
|
178
|
+
end
|
|
179
|
+
on("-p", "--pattern PATTERN", Regexp,
|
|
180
|
+
"Run examples with descriptions matching PATTERN") do |o|
|
|
181
|
+
@config[:patterns] << o
|
|
182
|
+
end
|
|
183
|
+
on("-P", "--excl-pattern PATTERN", Regexp,
|
|
184
|
+
"Exclude examples with descriptions matching PATTERN") do |o|
|
|
185
|
+
@config[:xpatterns] << o
|
|
186
|
+
end
|
|
187
|
+
on("-g", "--tag TAG", String,
|
|
188
|
+
"Run examples with descriptions matching ones tagged with TAG") do |o|
|
|
189
|
+
@config[:tags] << o
|
|
190
|
+
end
|
|
191
|
+
on("-G", "--excl-tag TAG", String,
|
|
192
|
+
"Exclude examples with descriptions matching ones tagged with TAG") do |o|
|
|
193
|
+
@config[:xtags] << o
|
|
194
|
+
end
|
|
195
|
+
on("-w", "--profile FILE", String,
|
|
196
|
+
"Run examples for methods listed in the profile FILE") do |f|
|
|
197
|
+
@config[:profiles] << f
|
|
198
|
+
end
|
|
199
|
+
on("-W", "--excl-profile FILE", String,
|
|
200
|
+
"Exclude examples for methods listed in the profile FILE") do |f|
|
|
201
|
+
@config[:xprofiles] << f
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def add_pretend
|
|
206
|
+
on("-Z", "--dry-run",
|
|
207
|
+
"Invoke formatters and other actions, but don't execute the specs") do
|
|
208
|
+
MSpec.register_mode :pretend
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def add_randomize
|
|
213
|
+
on("-H", "--random",
|
|
214
|
+
"Randomize the list of spec files") do
|
|
215
|
+
MSpec.randomize
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def add_verbose
|
|
220
|
+
on("-V", "--verbose", "Output the name of each file processed") do
|
|
221
|
+
obj = Object.new
|
|
222
|
+
def obj.start
|
|
223
|
+
@width = MSpec.retrieve(:files).inject(0) { |max, f| f.size > max ? f.size : max }
|
|
224
|
+
end
|
|
225
|
+
def obj.load
|
|
226
|
+
file = MSpec.retrieve :file
|
|
227
|
+
print "\n#{file.ljust(@width)}"
|
|
228
|
+
end
|
|
229
|
+
MSpec.register :start, obj
|
|
230
|
+
MSpec.register :load, obj
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
on("-m", "--marker MARKER", String,
|
|
234
|
+
"Output MARKER for each file processed") do |o|
|
|
235
|
+
obj = Object.new
|
|
236
|
+
obj.instance_variable_set :@marker, o
|
|
237
|
+
def obj.load
|
|
238
|
+
print @marker
|
|
239
|
+
end
|
|
240
|
+
MSpec.register :load, obj
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def add_interrupt
|
|
245
|
+
on("--int-spec", "Control-C interupts the current spec only") do
|
|
246
|
+
@config[:abort] = false
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def add_verify
|
|
251
|
+
on("-Y", "--verify",
|
|
252
|
+
"Verify that guarded specs pass and fail as expected") do
|
|
253
|
+
MSpec.set_mode :verify
|
|
254
|
+
end
|
|
255
|
+
on("-O", "--report", "Report guarded specs") do
|
|
256
|
+
MSpec.set_mode :report
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def add_tagging
|
|
261
|
+
on("-N", "--add TAG", String,
|
|
262
|
+
"Add TAG with format 'tag' or 'tag(comment)' (see -Q, -F, -L)") do |o|
|
|
263
|
+
@config[:tagger] = :add
|
|
264
|
+
@config[:tag] = "#{o}:"
|
|
265
|
+
end
|
|
266
|
+
on("-R", "--del TAG", String,
|
|
267
|
+
"Delete TAG (see -Q, -F, -L)") do |o|
|
|
268
|
+
@config[:tagger] = :del
|
|
269
|
+
@config[:tag] = "#{o}:"
|
|
270
|
+
@config[:outcome] = :pass
|
|
271
|
+
end
|
|
272
|
+
on("-Q", "--pass", "Apply action to specs that pass (default for --del)") do
|
|
273
|
+
@config[:outcome] = :pass
|
|
274
|
+
end
|
|
275
|
+
on("-F", "--fail", "Apply action to specs that fail (default for --add)") do
|
|
276
|
+
@config[:outcome] = :fail
|
|
277
|
+
end
|
|
278
|
+
on("-L", "--all", "Apply action to all specs") do
|
|
279
|
+
@config[:outcome] = :all
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def add_action_filters
|
|
284
|
+
on("-K", "--action-tag TAG", String,
|
|
285
|
+
"Spec descriptions marked with TAG will trigger the specified action") do |o|
|
|
286
|
+
@config[:atags] << o
|
|
287
|
+
end
|
|
288
|
+
on("-S", "--action-string STR", String,
|
|
289
|
+
"Spec descriptions matching STR will trigger the specified action") do |o|
|
|
290
|
+
@config[:astrings] << o
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def add_actions
|
|
295
|
+
on("--spec-debug",
|
|
296
|
+
"Invoke the debugger when a spec description matches (see -K, -S)") do
|
|
297
|
+
@config[:debugger] = true
|
|
298
|
+
end
|
|
299
|
+
on("--spec-gdb",
|
|
300
|
+
"Invoke Gdb when a spec description matches (see -K, -S)") do
|
|
301
|
+
@config[:gdb] = true
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
def add_version
|
|
306
|
+
on("-v", "--version", "Show version") do
|
|
307
|
+
puts "#{File.basename $0} #{MSpec::VERSION}"
|
|
308
|
+
exit
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def add_help
|
|
313
|
+
on("-h", "--help", "Show this message") do
|
|
314
|
+
puts @parser
|
|
315
|
+
exit
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def on(*args, &block)
|
|
320
|
+
@parser.on(*args, &block)
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
def separator(str)
|
|
324
|
+
@parser.separator str
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def parse(argv=ARGV)
|
|
328
|
+
result = @parser.parse argv
|
|
329
|
+
|
|
330
|
+
if (@config[:debugger] || @config[:gdb]) &&
|
|
331
|
+
@config[:atags].empty? && @config[:astrings].empty?
|
|
332
|
+
puts "Missing --action-tag or --action-string."
|
|
333
|
+
puts @parser
|
|
334
|
+
exit 1
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
result
|
|
338
|
+
rescue OptionParser::ParseError => e
|
|
339
|
+
puts @parser
|
|
340
|
+
puts
|
|
341
|
+
puts e
|
|
342
|
+
exit 1
|
|
343
|
+
end
|
|
344
|
+
end
|