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.
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