mspec 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. data/LICENSE +22 -0
  2. data/README +101 -0
  3. data/Rakefile +44 -0
  4. data/bin/mkspec +7 -0
  5. data/bin/mspec +7 -0
  6. data/bin/mspec-ci +8 -0
  7. data/bin/mspec-run +8 -0
  8. data/bin/mspec-tag +8 -0
  9. data/lib/mspec.rb +6 -0
  10. data/lib/mspec/commands/mkspec.rb +147 -0
  11. data/lib/mspec/commands/mspec-ci.rb +71 -0
  12. data/lib/mspec/commands/mspec-run.rb +80 -0
  13. data/lib/mspec/commands/mspec-tag.rb +87 -0
  14. data/lib/mspec/commands/mspec.rb +143 -0
  15. data/lib/mspec/expectations.rb +2 -0
  16. data/lib/mspec/expectations/expectations.rb +12 -0
  17. data/lib/mspec/expectations/should.rb +23 -0
  18. data/lib/mspec/guards.rb +13 -0
  19. data/lib/mspec/guards/bug.rb +27 -0
  20. data/lib/mspec/guards/compliance.rb +18 -0
  21. data/lib/mspec/guards/conflict.rb +16 -0
  22. data/lib/mspec/guards/endian.rb +40 -0
  23. data/lib/mspec/guards/extensions.rb +12 -0
  24. data/lib/mspec/guards/guard.rb +120 -0
  25. data/lib/mspec/guards/noncompliance.rb +12 -0
  26. data/lib/mspec/guards/platform.rb +38 -0
  27. data/lib/mspec/guards/quarantine.rb +15 -0
  28. data/lib/mspec/guards/runner.rb +30 -0
  29. data/lib/mspec/guards/superuser.rb +15 -0
  30. data/lib/mspec/guards/support.rb +12 -0
  31. data/lib/mspec/guards/version.rb +40 -0
  32. data/lib/mspec/helpers.rb +6 -0
  33. data/lib/mspec/helpers/bignum.rb +5 -0
  34. data/lib/mspec/helpers/const_lookup.rb +5 -0
  35. data/lib/mspec/helpers/flunk.rb +5 -0
  36. data/lib/mspec/helpers/io.rb +13 -0
  37. data/lib/mspec/helpers/scratch.rb +17 -0
  38. data/lib/mspec/helpers/tmp.rb +32 -0
  39. data/lib/mspec/matchers.rb +16 -0
  40. data/lib/mspec/matchers/base.rb +95 -0
  41. data/lib/mspec/matchers/be_ancestor_of.rb +24 -0
  42. data/lib/mspec/matchers/be_close.rb +27 -0
  43. data/lib/mspec/matchers/be_empty.rb +20 -0
  44. data/lib/mspec/matchers/be_false.rb +20 -0
  45. data/lib/mspec/matchers/be_kind_of.rb +24 -0
  46. data/lib/mspec/matchers/be_nil.rb +20 -0
  47. data/lib/mspec/matchers/be_true.rb +20 -0
  48. data/lib/mspec/matchers/complain.rb +56 -0
  49. data/lib/mspec/matchers/eql.rb +26 -0
  50. data/lib/mspec/matchers/equal.rb +26 -0
  51. data/lib/mspec/matchers/equal_utf16.rb +34 -0
  52. data/lib/mspec/matchers/include.rb +32 -0
  53. data/lib/mspec/matchers/output.rb +67 -0
  54. data/lib/mspec/matchers/output_to_fd.rb +71 -0
  55. data/lib/mspec/matchers/raise_error.rb +48 -0
  56. data/lib/mspec/mocks.rb +3 -0
  57. data/lib/mspec/mocks/mock.rb +123 -0
  58. data/lib/mspec/mocks/object.rb +28 -0
  59. data/lib/mspec/mocks/proxy.rb +112 -0
  60. data/lib/mspec/runner.rb +13 -0
  61. data/lib/mspec/runner/actions.rb +6 -0
  62. data/lib/mspec/runner/actions/debug.rb +17 -0
  63. data/lib/mspec/runner/actions/filter.rb +40 -0
  64. data/lib/mspec/runner/actions/gdb.rb +17 -0
  65. data/lib/mspec/runner/actions/tag.rb +97 -0
  66. data/lib/mspec/runner/actions/tally.rb +80 -0
  67. data/lib/mspec/runner/actions/timer.rb +22 -0
  68. data/lib/mspec/runner/filters.rb +4 -0
  69. data/lib/mspec/runner/filters/match.rb +22 -0
  70. data/lib/mspec/runner/filters/profile.rb +54 -0
  71. data/lib/mspec/runner/filters/regexp.rb +7 -0
  72. data/lib/mspec/runner/filters/tag.rb +29 -0
  73. data/lib/mspec/runner/formatters.rb +7 -0
  74. data/lib/mspec/runner/formatters/dotted.rb +81 -0
  75. data/lib/mspec/runner/formatters/html.rb +87 -0
  76. data/lib/mspec/runner/formatters/specdoc.rb +27 -0
  77. data/lib/mspec/runner/formatters/spinner.rb +89 -0
  78. data/lib/mspec/runner/formatters/summary.rb +8 -0
  79. data/lib/mspec/runner/formatters/unit.rb +25 -0
  80. data/lib/mspec/runner/formatters/yaml.rb +43 -0
  81. data/lib/mspec/runner/mspec.rb +232 -0
  82. data/lib/mspec/runner/object.rb +20 -0
  83. data/lib/mspec/runner/shared.rb +12 -0
  84. data/lib/mspec/runner/state.rb +116 -0
  85. data/lib/mspec/runner/tag.rb +20 -0
  86. data/lib/mspec/utils/name_map.rb +130 -0
  87. data/lib/mspec/utils/options.rb +344 -0
  88. data/lib/mspec/utils/script.rb +77 -0
  89. data/lib/mspec/version.rb +3 -0
  90. data/spec/commands/mkspec_spec.rb +321 -0
  91. data/spec/commands/mspec_ci_spec.rb +139 -0
  92. data/spec/commands/mspec_run_spec.rb +146 -0
  93. data/spec/commands/mspec_spec.rb +359 -0
  94. data/spec/commands/mspec_tag_spec.rb +131 -0
  95. data/spec/expectations/expectations_spec.rb +16 -0
  96. data/spec/expectations/should_spec.rb +99 -0
  97. data/spec/guards/bug_spec.rb +137 -0
  98. data/spec/guards/compliance_spec.rb +70 -0
  99. data/spec/guards/conflict_spec.rb +20 -0
  100. data/spec/guards/endian_spec.rb +42 -0
  101. data/spec/guards/extensions_spec.rb +36 -0
  102. data/spec/guards/guard_spec.rb +355 -0
  103. data/spec/guards/noncompliance_spec.rb +36 -0
  104. data/spec/guards/platform_spec.rb +84 -0
  105. data/spec/guards/quarantine_spec.rb +19 -0
  106. data/spec/guards/runner_spec.rb +75 -0
  107. data/spec/guards/superuser_spec.rb +22 -0
  108. data/spec/guards/support_spec.rb +22 -0
  109. data/spec/guards/version_spec.rb +133 -0
  110. data/spec/helpers/bignum_spec.rb +11 -0
  111. data/spec/helpers/const_lookup_spec.rb +19 -0
  112. data/spec/helpers/flunk_spec.rb +15 -0
  113. data/spec/helpers/io_spec.rb +34 -0
  114. data/spec/helpers/scratch_spec.rb +22 -0
  115. data/spec/helpers/tmp_spec.rb +72 -0
  116. data/spec/matchers/base_spec.rb +180 -0
  117. data/spec/matchers/be_ancestor_of_spec.rb +28 -0
  118. data/spec/matchers/be_close_spec.rb +46 -0
  119. data/spec/matchers/be_empty_spec.rb +26 -0
  120. data/spec/matchers/be_false_spec.rb +28 -0
  121. data/spec/matchers/be_kind_of_spec.rb +29 -0
  122. data/spec/matchers/be_nil_spec.rb +27 -0
  123. data/spec/matchers/be_true_spec.rb +28 -0
  124. data/spec/matchers/complain_spec.rb +52 -0
  125. data/spec/matchers/eql_spec.rb +33 -0
  126. data/spec/matchers/equal_spec.rb +33 -0
  127. data/spec/matchers/equal_utf16_spec.rb +47 -0
  128. data/spec/matchers/include_spec.rb +37 -0
  129. data/spec/matchers/output_spec.rb +74 -0
  130. data/spec/matchers/output_to_fd_spec.rb +33 -0
  131. data/spec/matchers/raise_error_spec.rb +56 -0
  132. data/spec/mocks/mock_spec.rb +272 -0
  133. data/spec/mocks/proxy_spec.rb +259 -0
  134. data/spec/runner/actions/debug_spec.rb +61 -0
  135. data/spec/runner/actions/filter_spec.rb +84 -0
  136. data/spec/runner/actions/gdb_spec.rb +61 -0
  137. data/spec/runner/actions/tag_spec.rb +253 -0
  138. data/spec/runner/actions/tally_spec.rb +107 -0
  139. data/spec/runner/actions/timer_spec.rb +42 -0
  140. data/spec/runner/filters/a.yaml +4 -0
  141. data/spec/runner/filters/b.yaml +11 -0
  142. data/spec/runner/filters/match_spec.rb +44 -0
  143. data/spec/runner/filters/profile_spec.rb +117 -0
  144. data/spec/runner/filters/regexp_spec.rb +13 -0
  145. data/spec/runner/filters/tag_spec.rb +77 -0
  146. data/spec/runner/formatters/dotted_spec.rb +184 -0
  147. data/spec/runner/formatters/html_spec.rb +191 -0
  148. data/spec/runner/formatters/specdoc_spec.rb +57 -0
  149. data/spec/runner/formatters/spinner_spec.rb +78 -0
  150. data/spec/runner/formatters/summary_spec.rb +29 -0
  151. data/spec/runner/formatters/unit_spec.rb +71 -0
  152. data/spec/runner/formatters/yaml_spec.rb +123 -0
  153. data/spec/runner/mspec_spec.rb +393 -0
  154. data/spec/runner/shared_spec.rb +41 -0
  155. data/spec/runner/state_spec.rb +535 -0
  156. data/spec/runner/tag_spec.rb +93 -0
  157. data/spec/runner/tags.txt +3 -0
  158. data/spec/spec_helper.rb +46 -0
  159. data/spec/utils/name_map_spec.rb +178 -0
  160. data/spec/utils/options_spec.rb +862 -0
  161. data/spec/utils/script_spec.rb +240 -0
  162. metadata +217 -0
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2008 Engine Yard, Inc. All rights reserved.
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,101 @@
1
+ = Overview
2
+
3
+ MSpec is a specialized framework that is syntax-compatible with RSpec for
4
+ basic things like +describe+, +it+ blocks and +before+, +after+ actions. MSpec
5
+ contains additional features that assist in writing the RubySpecs used by
6
+ multiple Ruby implementations.
7
+
8
+ MSpec attempts to use the simplest Ruby language features so that beginning
9
+ Ruby implementations can run the Ruby specs. So, for example, there is not
10
+ great concern given to constant clashes. Namespacing (or module scoping) is
11
+ not used because implementing this correctly took a significant amount of work
12
+ in Rubinius and it is likely that other implementations would also face
13
+ difficulties.
14
+
15
+ MSpec is not intended as a replacement for RSpec. MSpec attempts to provide a
16
+ subset of RSpec's features in some cases and a superset in others. It does not
17
+ provide all the matchers, for instance. However, MSpec provides several
18
+ extensions to facilitate writing the Ruby specs in a manner compatible with
19
+ multiple Ruby implementations.
20
+
21
+ First, MSpec offers a set of guards to control execution of the specs. These
22
+ guards not only enable or disable execution but also annotate the specs with
23
+ additional information about why they are run or not run. Second, MSpec
24
+ provides a different shared spec implementation specifically designed to ease
25
+ writing specs for the numerous aliased methods in Ruby. The MSpec shared spec
26
+ implementation should not conflict with RSpec's own shared behavior facility.
27
+ Third, MSpec provides various helper methods to simplify some specs, for
28
+ example, creating temporary file names. Finally, MSpec has several specialized
29
+ runner scripts that includes a configuration facility with a default project
30
+ file and user-specific overrides.
31
+
32
+ Caveats:
33
+
34
+ * Use RSpec to run the MSpec specs. There are no plans currently to make
35
+ the MSpec specs runnable by MSpec.
36
+ * Don't mock the #hash method as MSpec's Mock implementation uses Hash
37
+ internally. This can be replaced if necessary, but at this point there is no
38
+ compelling need to do so.
39
+
40
+
41
+ == Architecture
42
+
43
+
44
+ == Matchers
45
+
46
+ Matchers are additional aids for the verification process. The default
47
+ is of course to #should or #should_not using the #== operator and its
48
+ friends but the matchers add a new set of 'operators' to help in the
49
+ task. They reside in `mspec/matchers/`. There are two broad categories,
50
+ those that apply to an individual object and those that apply to a
51
+ block:
52
+
53
+ === Object
54
+
55
+ - `base` implements the standard #==, #< #<= #>= #> and #=~ with their
56
+ normal semantics for the objects that you invoke them on.
57
+
58
+ - `be_ancestor_of` is equivalent to checking `obj.ancestors.include?`.
59
+
60
+ - `be_close` is a "delta" for floating-point math. Due to the very
61
+ nature of it, floating-point comparisons should never be treated as
62
+ exact. By default the tolerance is 0.00003 but it can be altered if
63
+ so desired. So `0.23154.should be_close(0.23157)` would succeed
64
+ (which is usually close enough for floating point unless you are
65
+ doing some scientific computing.)
66
+
67
+ - `be_empty` checks `obj.empty?`
68
+
69
+ - `be_kind_of` is equivalent to `obj.kind_of?`
70
+
71
+ - `include` is `obj.include?`
72
+
73
+ === Block
74
+
75
+ All of these should be applied to a block created with `lambda` or `proc`:
76
+
77
+ - `complain` is probably clearer stated as `lambda {...}.should complain`;
78
+ it checks that the block issues a warning. The message can be checked
79
+ against either a String or a Regexp.
80
+
81
+ - `output` checks that the block produces the given output (stdout as well
82
+ as stderr, in that order) matched either to a String or a Regexp. This one
83
+ uses overrides so if that is a problem (for e.g. speccing Readline or
84
+ something) see below.
85
+
86
+ - `output_to_fd` is a lower-level version and actually verifies that output
87
+ to a certain file descriptor is correct whether from an in-/output stream
88
+ or an actual file. Also can check with either a String or a Regexp.
89
+
90
+ - `raise_error` verifies the exception type (if any) raised by the block it
91
+ is associated with. The exception class can be given for finer-grained
92
+ control (inheritance works normally so Exception would catch everything.)
93
+
94
+
95
+ == Guards
96
+
97
+
98
+ == Helpers
99
+
100
+
101
+ == Runners
data/Rakefile ADDED
@@ -0,0 +1,44 @@
1
+ require 'rubygems'
2
+ require 'spec/rake/spectask'
3
+ require 'rake/gempackagetask'
4
+
5
+ Spec::Rake::SpecTask.new
6
+
7
+ task :default => :spec
8
+
9
+
10
+ spec = Gem::Specification.new do |s|
11
+ s.name = %q{mspec}
12
+ s.version = "1.0.0"
13
+
14
+ s.specification_version = 2 if s.respond_to? :specification_version=
15
+
16
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
17
+ s.authors = ["Brian Ford"]
18
+ s.date = %q{2008-05-21}
19
+ s.email = %q{bford@engineyard.com}
20
+ s.has_rdoc = true
21
+ s.extra_rdoc_files = %w[ README LICENSE ]
22
+ s.executables = ["mkspec", "mspec", "mspec-ci", "mspec-run", "mspec-tag"]
23
+ s.files = FileList[ '{bin,lib,spec}/**/*.{yaml,txt,rb}', 'Rakefile', *s.extra_rdoc_files ]
24
+ s.homepage = %q{http://rubyspec.org}
25
+ s.rubyforge_project = 'http://rubyforge.org/projects/mspec'
26
+ s.require_paths = ["lib"]
27
+ s.rubygems_version = %q{1.1.1}
28
+ s.summary = <<EOS
29
+ MSpec is a specialized framework that is syntax-compatible
30
+ with RSpec for basic things like describe, it blocks and
31
+ before, after actions.
32
+
33
+ MSpec contains additional features that assist in writing
34
+ the RubySpecs used by multiple Ruby implementations. Also,
35
+ MSpec attempts to use the simplest Ruby language features
36
+ so that beginning Ruby implementations can run it.
37
+ EOS
38
+
39
+ s.rdoc_options << '--title' << 'MSpec Gem' <<
40
+ '--main' << 'README' <<
41
+ '--line-numbers'
42
+ end
43
+
44
+ Rake::GemPackageTask.new(spec){ |pkg| pkg.gem_spec = spec }
data/bin/mkspec ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+
5
+ require 'mspec/commands/mkspec'
6
+
7
+ MkSpec.main
data/bin/mspec ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+
5
+ require 'mspec/commands/mspec'
6
+
7
+ MSpecMain.main
data/bin/mspec-ci ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+
5
+ require 'mspec/commands/mspec-ci'
6
+ require 'mspec'
7
+
8
+ MSpecCI.main
data/bin/mspec-run ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+
5
+ require 'mspec/commands/mspec-run'
6
+ require 'mspec'
7
+
8
+ MSpecRun.main
data/bin/mspec-tag ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+
5
+ require 'mspec/commands/mspec-tag'
6
+ require 'mspec'
7
+
8
+ MSpecTag.main
data/lib/mspec.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'mspec/matchers'
2
+ require 'mspec/expectations'
3
+ require 'mspec/mocks'
4
+ require 'mspec/runner'
5
+ require 'mspec/guards'
6
+ require 'mspec/helpers'
@@ -0,0 +1,147 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ MSPEC_HOME = File.expand_path(File.dirname(__FILE__) + '/../../..')
4
+
5
+ require 'fileutils'
6
+ require 'optparse'
7
+ require 'rbconfig'
8
+ require 'mspec/version'
9
+ require 'mspec/utils/name_map'
10
+
11
+
12
+ class MkSpec
13
+ attr_reader :config
14
+
15
+ def initialize
16
+ @config = {
17
+ :constants => [],
18
+ :requires => [],
19
+ :base => "spec/ruby/1.8/core"
20
+ }
21
+ @map = NameMap.new
22
+ end
23
+
24
+ def options(argv=ARGV)
25
+ options = OptionParser.new
26
+ options.version = MSpec::VERSION
27
+ options.banner = "mkspec [options]"
28
+ options.separator ""
29
+
30
+ options.on("-c", "--constant CONSTANT", String,
31
+ "Class or Module to generate spec stubs for") do |name|
32
+ config[:constants] << name
33
+ end
34
+ options.on("-b", "--base DIR", String,
35
+ "Directory to generate specs into") do |directory|
36
+ config[:base] = File.expand_path directory
37
+ end
38
+ options.on("-r", "--require LIBRARY", String,
39
+ "A library to require") do |file|
40
+ config[:requires] << file
41
+ end
42
+
43
+ options.separator "\n How might this work in the real world?\n"
44
+ options.separator " 1. To create spec stubs for every class or module in Object\n"
45
+ options.separator " $ mkspec\n"
46
+ options.separator " 2. To create spec stubs for Fixnum\n"
47
+ options.separator " $ mkspec -c Fixnum\n"
48
+ options.separator " 3. To create spec stubs for Complex in 'superspec/complex'\n"
49
+ options.separator " $ mkspec -c Complex -rcomplex -b superspec"
50
+ options.separator ""
51
+
52
+ options.parse argv
53
+ rescue OptionParser::ParseError => e
54
+ puts options
55
+ puts
56
+ puts e
57
+ exit 1
58
+ end
59
+
60
+ def create_directory(mod)
61
+ subdir = @map.dir_name mod, config[:base]
62
+
63
+ if File.exist? subdir
64
+ unless File.directory? subdir
65
+ puts "#{subdir} already exists and is not a directory."
66
+ return nil
67
+ end
68
+ else
69
+ FileUtils.mkdir_p subdir
70
+ end
71
+
72
+ subdir
73
+ end
74
+
75
+ def write_requires(dir, file)
76
+ /\A#{Regexp.escape config[:base]}\/?(.*)/ =~ dir
77
+ parents = '../' * ($1.split('/').length + 1)
78
+
79
+ File.open file, 'w' do |f|
80
+ f.puts "require File.dirname(__FILE__) + '/#{parents}spec_helper'"
81
+ config[:requires].each do |lib|
82
+ f.puts "require '#{lib}'"
83
+ end
84
+ end
85
+ end
86
+
87
+ def write_spec(file, meth, exists)
88
+ if exists
89
+ out = `#{ruby} #{MSPEC_HOME}/bin/mspec-run --dry-run -fs -e '#{meth}' #{file}`
90
+ return if out =~ /#{Regexp.escape meth}/
91
+ end
92
+
93
+ File.open file, 'a' do |f|
94
+ f.puts <<-EOS
95
+
96
+ describe "#{meth}" do
97
+ it "needs to be reviewed for spec completeness" do
98
+ end
99
+ end
100
+ EOS
101
+ end
102
+
103
+ puts file
104
+ end
105
+
106
+ def create_file(dir, mod, meth, name)
107
+ file = File.join dir, @map.file_name(meth, mod)
108
+ exists = File.exist? file
109
+
110
+ write_requires dir, file unless exists
111
+ write_spec file, name, exists
112
+ end
113
+
114
+ def run
115
+ config[:requires].each { |lib| require lib }
116
+ constants = config[:constants]
117
+ constants = @map.filter(Object.constants) if constants.empty?
118
+
119
+ @map.map({}, constants).each do |mod, methods|
120
+ name = mod.chop
121
+ next unless dir = create_directory(name)
122
+
123
+ methods.each { |method| create_file dir, name, method, mod + method }
124
+ end
125
+ end
126
+
127
+ ##
128
+ # Determine and return the path of the ruby executable.
129
+
130
+ def ruby
131
+ ruby = File.join(Config::CONFIG['bindir'],
132
+ Config::CONFIG['ruby_install_name'])
133
+
134
+ ruby.gsub! File::SEPARATOR, File::ALT_SEPARATOR if File::ALT_SEPARATOR
135
+
136
+ return ruby
137
+ end
138
+
139
+ def self.main
140
+ ENV['MSPEC_RUNNER'] = '1'
141
+
142
+ script = new
143
+ script.options
144
+ script.run
145
+ end
146
+ end
147
+
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+
5
+ require 'optparse'
6
+ require 'mspec/utils/options'
7
+ require 'mspec/utils/script'
8
+
9
+
10
+ class MSpecCI < MSpecScript
11
+ def options(argv=ARGV)
12
+ options = MSpecOptions.new config, "ci", "", 28, " "
13
+
14
+ options.separator " Ask yourself:"
15
+ options.separator " 1. How to run the specs?"
16
+ options.separator " 2. How to display the output?"
17
+ options.separator " 3. What action to perform?"
18
+ options.separator " 4. When to perform it?"
19
+
20
+ options.separator "\n How to run the specs"
21
+ options.add_config { |f| load f }
22
+ options.add_name
23
+ options.add_tags_dir
24
+ options.add_pretend
25
+ options.add_interrupt
26
+
27
+ options.separator "\n How to display their output"
28
+ options.add_formatters
29
+ options.add_verbose
30
+
31
+ options.separator "\n What action to perform"
32
+ options.add_actions
33
+
34
+ options.separator "\n When to perform it"
35
+ options.add_action_filters
36
+
37
+ options.separator "\n Help!"
38
+ options.add_version
39
+ options.add_help
40
+
41
+ options.separator "\n How might this work in the real world?"
42
+ options.separator "\n 1. To simply run the known good specs"
43
+ options.separator "\n $ mspec ci"
44
+ options.separator "\n 2. To run a subset of the known good specs"
45
+ options.separator "\n $ mspec ci path/to/specs"
46
+ options.separator "\n 3. To start the debugger before the spec matching 'this crashes'"
47
+ options.separator "\n $ mspec ci --spec-debug -S 'this crashes'"
48
+ options.separator ""
49
+
50
+ @patterns = options.parse argv
51
+ @patterns = config[:ci_files] if @patterns.empty?
52
+ end
53
+
54
+ def run
55
+ files = []
56
+ @patterns.each do |item|
57
+ stat = File.stat(File.expand_path(item))
58
+ files << item if stat.file?
59
+ files.concat(Dir[item+"/**/*_spec.rb"].sort) if stat.directory?
60
+ end
61
+
62
+ MSpec.register_tags_path config[:tags_dir]
63
+ MSpec.register_files files
64
+ TagFilter.new(:exclude, "fails").register
65
+ TagFilter.new(:exclude, "unstable").register
66
+ TagFilter.new(:exclude, "incomplete").register
67
+
68
+ MSpec.process
69
+ exit MSpec.exit_code
70
+ end
71
+ end