class Object

The #ruby_exe helper provides a wrapper for invoking the same Ruby interpreter as the one running the specs and getting the output from running the code. If code is a file that exists, it will be run. Otherwise, code should be Ruby code that will be run with the -e command line option. For example:

ruby_exe('path/to/some/file.rb')

will be executed as

%x`#{RUBY_EXE} #{'path/to/some/file.rb'}`

while

ruby_exe('puts "hello, world."')

will be executed as

%x`#{RUBY_EXE} -e #{'puts "hello, world."'}`

The #ruby_exe helper also accepts an options hash with three keys: :options, :args and :env. For example:

ruby_exe('file.rb', :options => "-w",
                    :args => "> file.txt",
                    :env => { :FOO => "bar" })

will be executed as

%x`#{RUBY_EXE} -w #{'file.rb'} > file.txt`

with access to ENV with value “bar”.

If nil is passed for the first argument, the command line will be built only from the options hash.

The RUBY_EXE constant can be set explicitly since the value is used each time #ruby_exe is invoked. The mspec runner script will set ENV to the name of the executable used to invoke the mspec-run script. The value of RUBY_EXE will be constructed as follows:

1. the value of ENV['RUBY_EXE']
2. an explicit value based on RUBY_NAME
3. cwd/(RUBY_NAME + $(EXEEXT) || $(exeext) || '')
4. $(bindir)/$(RUBY_INSTALL_NAME)

The value will only be used if the file exists and is executable.

These 4 ways correspond to the following scenarios:

 1. Using the MSpec runner scripts, the name of the
    executable is explicitly passed by ENV['RUBY_EXE']
    so there is no ambiguity.

Otherwise, if using RSpec (or something else)

 2. Running the specs while developing an alternative
    Ruby implementation. This explicitly names the
    executable in the development directory based on
    the value of RUBY_NAME, which is probably initialized
    from the value of RUBY_ENGINE.
 3. Running the specs within the source directory for
    some implementation. (E.g. a local build directory.)
 4. Running the specs against some installed Ruby
    implementation.

Constants

MSPEC_HOME
NO_MATCHER_GIVEN
RUBY_EXE
RUBY_NAME
SPEC_TEMP_DIR

Creates a temporary directory in the current working directory for temporary files created while running the specs. All specs should clean up any temporary files created so that the temp directory is empty when the process exits.

SPEC_TEMP_UNIQUIFIER
SPEC_TMEM_DIR_PID
TOLERANCE

Public Instance Methods

after(at=:each, &block) click to toggle source
# File lib/mspec/runner/object.rb, line 6
def after(at=:each, &block)
  MSpec.current.after at, &block
end
argv(args) { || ... } click to toggle source

Convenience helper for altering ARGV. Saves the value of ARGV and sets it to args. If a block is given, yields to the block and then restores the value of ARGV. The previously saved value of ARGV can be restored by passing :restore. The former is useful in a single spec. The latter is useful in before/after actions. For example:

describe "This" do
  before do
    argv ['a', 'b']
  end

  after do
    argv :restore
  end

  it "does something" do
    # do something
  end
end

describe "That" do
  it "does something" do
    argv ['a', 'b'] do
      # do something
    end
  end
end
# File lib/mspec/helpers/argv.rb, line 31
def argv(args)
  if args == :restore
    ARGV.replace(@__mspec_saved_argv__ || [])
  else
    @__mspec_saved_argv__ = ARGV
    ARGV.replace args
    if block_given?
      yield
      argv :restore
    end
  end
end
as_superuser() { || ... } click to toggle source
# File lib/mspec/guards/superuser.rb, line 10
def as_superuser
  g = SuperUserGuard.new
  g.name = :as_superuser
  yield if g.yield?
ensure
  g.unregister
end
as_user() { || ... } click to toggle source
# File lib/mspec/guards/user.rb, line 10
def as_user
  g = UserGuard.new
  g.name = :as_user
  yield if g.yield?
ensure
  g.unregister
end
be_an_instance_of(expected) click to toggle source
# File lib/mspec/matchers/be_an_instance_of.rb, line 23
def be_an_instance_of(expected)
  BeAnInstanceOfMatcher.new(expected)
end
be_ancestor_of(expected) click to toggle source
# File lib/mspec/matchers/be_ancestor_of.rb, line 21
def be_ancestor_of(expected)
  BeAncestorOfMatcher.new(expected)
end
be_close(expected, tolerance) click to toggle source
# File lib/mspec/matchers/be_close.rb, line 24
def be_close(expected, tolerance)
  BeCloseMatcher.new(expected, tolerance)
end
be_computed_by(sym, *args) click to toggle source
# File lib/mspec/matchers/be_computed_by.rb, line 34
def be_computed_by(sym, *args)
  BeComputedByMatcher.new(sym, *args)
end
be_computed_by_function(sym, *args) click to toggle source
# File lib/mspec/matchers/be_computed_by_function.rb, line 32
def be_computed_by_function(sym, *args)
  BeComputedByFunctionMatcher.new(sym, *args)
end
be_empty() click to toggle source
# File lib/mspec/matchers/be_empty.rb, line 17
def be_empty
  BeEmptyMatcher.new
end
be_false() click to toggle source
# File lib/mspec/matchers/be_false.rb, line 17
def be_false
  BeFalseMatcher.new
end
be_kind_of(expected) click to toggle source
# File lib/mspec/matchers/be_kind_of.rb, line 21
def be_kind_of(expected)
  BeKindOfMatcher.new(expected)
end
be_nan() click to toggle source
# File lib/mspec/matchers/be_nan.rb, line 17
def be_nan
  BeNaNMatcher.new
end
be_negative_infinity() click to toggle source
# File lib/mspec/matchers/infinity.rb, line 25
def be_negative_infinity
  InfinityMatcher.new(-1)
end
be_negative_zero() click to toggle source
# File lib/mspec/matchers/signed_zero.rb, line 25
def be_negative_zero
  SignedZeroMatcher.new(-1)
end
be_nil() click to toggle source
# File lib/mspec/matchers/be_nil.rb, line 17
def be_nil
  BeNilMatcher.new
end
be_positive_infinity() click to toggle source
# File lib/mspec/matchers/infinity.rb, line 21
def be_positive_infinity
  InfinityMatcher.new(1)
end
be_positive_zero() click to toggle source
# File lib/mspec/matchers/signed_zero.rb, line 21
def be_positive_zero
  SignedZeroMatcher.new(1)
end
be_true() click to toggle source
# File lib/mspec/matchers/be_true.rb, line 17
def be_true
  BeTrueMatcher.new
end
be_valid_DNS_name() click to toggle source
# File lib/mspec/matchers/be_valid_dns_name.rb, line 22
def be_valid_DNS_name
  BeValidDNSName.new
end
before(at=:each, &block) click to toggle source
# File lib/mspec/runner/object.rb, line 2
def before(at=:each, &block)
  MSpec.current.before at, &block
end
big_endian() { || ... } click to toggle source
# File lib/mspec/guards/endian.rb, line 26
def big_endian
  g = BigEndianGuard.new
  g.name = :big_endian
  yield if g.yield?
ensure
  g.unregister
end
bignum_value(plus=0) click to toggle source
# File lib/mspec/helpers/numeric.rb, line 10
def bignum_value(plus=0)
  0x8000_0000_0000_0000 + plus
end
complain(complaint=nil) click to toggle source
# File lib/mspec/matchers/complain.rb, line 53
def complain(complaint=nil)
  ComplainMatcher.new(complaint)
end
compliant_on(*args) { || ... } click to toggle source
# File lib/mspec/guards/compliance.rb, line 22
def compliant_on(*args)
  g = CompliantOnGuard.new(*args)
  g.name = :compliant_on
  yield if g.yield?
ensure
  g.unregister
end
conflicts_with(*modules) { || ... } click to toggle source

In some cases, libraries will modify another Ruby method's behavior. The specs for the method's behavior will then fail if that library is loaded. This guard will not run if any of the specified constants exist in Object.constants.

# File lib/mspec/guards/conflict.rb, line 16
def conflicts_with(*modules)
  g = ConflictsGuard.new(*modules)
  g.name = :conflicts_with
  yield if g.yield? true
ensure
  g.unregister
end
context(mod, msg=nil, options=nil, &block)
Alias for: describe
cp(source, dest) click to toggle source

Copies a file

# File lib/mspec/helpers/fs.rb, line 3
def cp(source, dest)
  File.open(dest, "w") do |d|
    File.open(source, "r") do |s|
      while data = s.read(1024)
        d.write data
      end
    end
  end
end
describe(mod, msg=nil, options=nil, &block) click to toggle source
# File lib/mspec/runner/object.rb, line 10
def describe(mod, msg=nil, options=nil, &block)
  MSpec.describe mod, msg, &block
end
Also aliased as: context
dev_null() click to toggle source
# File lib/mspec/helpers/environment.rb, line 33
def dev_null
  if PlatformGuard.windows?
    "NUL"
  else
    "/dev/null"
  end
end
deviates_on(*args) { || ... } click to toggle source
# File lib/mspec/guards/noncompliance.rb, line 13
def deviates_on(*args)
  g = NonComplianceGuard.new(*args)
  g.name = :deviates_on
  yield if g.yield?
ensure
  g.unregister
end
doc(*a) click to toggle source

For ReadRuby compatiability

# File lib/mspec/runner/object.rb, line 23
def doc(*a)
end
does_not_respond_to(sym) click to toggle source
# File lib/mspec/helpers/ducktype.rb, line 10
def does_not_respond_to(sym)
  singleton_class.class_eval <<-END
    def respond_to?(sym, include_private=false)
      sym.to_sym == #{sym.to_sym.inspect} ? false : super
    end
  END
end
encode(str, encoding) click to toggle source

Helper to handle String encodings. The str and encoding parameters must be Strings and an ArgumentError will be raised if not. This ensures that the encode() helper can be used regardless of whether Encoding exits. The helper is a no-op (i.e. passes through str unmodified) if the :encoding feature is not enabled (see #with_feature guard). If the :encoding feature is enabled, str.force_encoding(encoding) is called.

# File lib/mspec/helpers/encode.rb, line 10
def encode(str, encoding)
  unless str.is_a? String and encoding.is_a? String
    raise ArgumentError, "encoding name must be a String"
  end

  if FeatureGuard.enabled? :encoding
    str.force_encoding encoding
  end

  str
end
enumerator_class() click to toggle source

Returns the Enumerator class (either Enumerator or Enumerable::Enumerator) depending of the version.

# File lib/mspec/helpers/enumerator_class.rb, line 6
def enumerator_class
  SpecVersion.new(RUBY_VERSION) < "1.9" ? Enumerable::Enumerator : Enumerator
end
env() click to toggle source
# File lib/mspec/helpers/environment.rb, line 4
def env
  env = ""
  if PlatformGuard.windows?
    env = Hash[*%x`cmd.exe /C set`.split("\n").map { |e| e.split("=", 2) }.flatten]
  else
    env = Hash[*%x`env`.split("\n").map { |e| e.split("=", 2) }.flatten]
  end
  env
end
eql(expected) click to toggle source
# File lib/mspec/matchers/eql.rb, line 23
def eql(expected)
  EqlMatcher.new(expected)
end
equal(expected) click to toggle source
# File lib/mspec/matchers/equal.rb, line 23
def equal(expected)
  EqualMatcher.new(expected)
end
equal_element(*args) click to toggle source
# File lib/mspec/matchers/equal_element.rb, line 75
def equal_element(*args)
  EqualElementMatcher.new(*args)
end
equal_utf16(expected) click to toggle source
# File lib/mspec/matchers/equal_utf16.rb, line 29
def equal_utf16(expected)
  EqualUtf16Matcher.new(expected)
end
extended_on(*args) { || ... } click to toggle source
# File lib/mspec/guards/extensions.rb, line 13
def extended_on(*args)
  g = ExtensionsGuard.new(*args)
  g.name = :extended_on
  yield if g.yield?
ensure
  g.unregister
end
fake!(sym, value=nil) click to toggle source
# File lib/mspec/helpers/ducktype.rb, line 24
def fake!(sym, value=nil)
  responds_to sym

  singleton_class.class_eval <<-END
    def method_missing(sym, *args)
      return #{value.inspect} if sym.to_sym == #{sym.to_sym.inspect}
    end
  END
end
fixnum_max() click to toggle source
# File lib/mspec/helpers/numeric.rb, line 23
def fixnum_max()
  (2**30) - 1
end
fixnum_min() click to toggle source
# File lib/mspec/helpers/numeric.rb, line 27
def fixnum_min()
  -(2**30)
end
fixture(dir, *args) click to toggle source

Returns the name of a fixture file by adjoining the directory of the dir argument with “fixtures” and the contents of the args array. For example,

+dir+ == "some/path"

and

+args+ == ["dir", "file.txt"]

then the result is the expanded path of

"some/fixtures/dir/file.txt".
# File lib/mspec/helpers/fixture.rb, line 15
def fixture(dir, *args)
  path = File.dirname(dir)
  path = path[0..-7] if path[-7..-1] == "/shared"
  dir = path[-9..-1] == "/fixtures" ? "" : "fixtures"
  File.expand_path(File.join(path, dir, args))
end
flunk(msg="This example is a failure") click to toggle source
# File lib/mspec/helpers/flunk.rb, line 2
def flunk(msg="This example is a failure")
  SpecExpectation.fail_with "Failed:", msg
end
fmode(mode) click to toggle source

This helper simplifies passing file access modes regardless of whether the :encoding feature is enabled. Only the access specifier itself will be returned if :encoding is not enabled. Otherwise, the full mode string will be returned (i.e. the helper is a no-op).

# File lib/mspec/helpers/io.rb, line 57
def fmode(mode)
  if FeatureGuard.enabled? :encoding
    mode
  else
    mode.split(':').first
  end
end
hash_class() click to toggle source
# File lib/mspec/helpers/hash.rb, line 7
def hash_class
  Hash
end
have_class_variable(variable) click to toggle source
# File lib/mspec/matchers/have_class_variable.rb, line 9
def have_class_variable(variable)
  HaveClassVariableMatcher.new(variable)
end
have_constant(variable) click to toggle source
# File lib/mspec/matchers/have_constant.rb, line 9
def have_constant(variable)
  HaveConstantMatcher.new(variable)
end
have_data(data, mode="rb:binary") click to toggle source

Opens a file specified by the string the matcher is called on and compares the data passed to the matcher with the contents of the file. Expects to match the first N bytes of the file with data. For example, suppose @name is the name of a file:

@name.should have_data("123")

passes if the file @name has “123” as the first 3 bytes. The file can contain more bytes than data. The extra bytes do not affect the result.

# File lib/mspec/matchers/have_data.rb, line 46
def have_data(data, mode="rb:binary")
  HaveDataMatcher.new(data, mode)
end
have_instance_method(method, include_super=true) click to toggle source
# File lib/mspec/matchers/have_instance_method.rb, line 21
def have_instance_method(method, include_super=true)
  HaveInstanceMethodMatcher.new method, include_super
end
have_instance_variable(variable) click to toggle source
# File lib/mspec/matchers/have_instance_variable.rb, line 9
def have_instance_variable(variable)
  HaveInstanceVariableMatcher.new(variable)
end
have_method(method, include_super=true) click to toggle source
# File lib/mspec/matchers/have_method.rb, line 21
def have_method(method, include_super=true)
  HaveMethodMatcher.new method, include_super
end
have_private_instance_method(method, include_super=true) click to toggle source
# File lib/mspec/matchers/have_private_instance_method.rb, line 21
def have_private_instance_method(method, include_super=true)
  HavePrivateInstanceMethodMatcher.new method, include_super
end
have_private_method(method, include_super=true) click to toggle source
# File lib/mspec/matchers/have_private_method.rb, line 21
def have_private_method(method, include_super=true)
  HavePrivateMethodMatcher.new method, include_super
end
have_protected_instance_method(method, include_super=true) click to toggle source
# File lib/mspec/matchers/have_protected_instance_method.rb, line 21
def have_protected_instance_method(method, include_super=true)
  HaveProtectedInstanceMethodMatcher.new method, include_super
end
have_public_instance_method(method, include_super=true) click to toggle source
# File lib/mspec/matchers/have_public_instance_method.rb, line 21
def have_public_instance_method(method, include_super=true)
  HavePublicInstanceMethodMatcher.new method, include_super
end
have_singleton_method(method, include_super=true) click to toggle source
# File lib/mspec/matchers/have_singleton_method.rb, line 21
def have_singleton_method(method, include_super=true)
  HaveSingletonMethodMatcher.new method, include_super
end
home_directory() click to toggle source
# File lib/mspec/helpers/environment.rb, line 28
def home_directory
  return ENV['HOME'] unless PlatformGuard.windows?
  windows_env_echo('HOMEDRIVE') + windows_env_echo('HOMEPATH')
end
hostname() click to toggle source
# File lib/mspec/helpers/environment.rb, line 41
def hostname
  commands = ['hostname', 'uname -n']
  commands.each do |command|
    name = %x`#{command}`
    return name.strip if $?.success?
  end
  raise Exception, "hostname: unable to find a working command"
end
infinity_value() click to toggle source
# File lib/mspec/helpers/numeric.rb, line 6
def infinity_value
  1/0.0
end
it(msg, &block) click to toggle source
# File lib/mspec/runner/object.rb, line 14
def it(msg, &block)
  MSpec.current.it msg, &block
end
Also aliased as: specify
it_behaves_like(desc, meth, obj=nil) click to toggle source
# File lib/mspec/runner/shared.rb, line 4
def it_behaves_like(desc, meth, obj=nil)
  send :before, :all do
    @method = meth
    @object = obj
  end

  send :it_should_behave_like, desc.to_s
end
it_should_behave_like(desc) click to toggle source
# File lib/mspec/runner/object.rb, line 18
def it_should_behave_like(desc)
  MSpec.current.it_should_behave_like desc
end
little_endian() { || ... } click to toggle source
# File lib/mspec/guards/endian.rb, line 34
def little_endian
  g = LittleEndianGuard.new
  g.name = :little_endian
  yield if g.yield?
ensure
  g.unregister
end
match_yaml(expected) click to toggle source
# File lib/mspec/matchers/match_yaml.rb, line 43
def match_yaml(expected)
  MatchYAMLMatcher.new(expected)
end
mkdir_p(path) click to toggle source

Creates each directory in path that does not exist.

# File lib/mspec/helpers/fs.rb, line 14
def mkdir_p(path)
  parts = File.expand_path(path).split %r[/|\]
  name = parts.shift
  parts.each do |part|
    name = File.join name, part

    if File.file? name
      raise ArgumentError, "path component of #{path} is a file"
    end

    Dir.mkdir name unless File.directory? name
  end
end
mock(name, options={}) click to toggle source
# File lib/mspec/mocks/object.rb, line 17
def mock(name, options={})
  MockObject.new name, options
end
mock_int(val) click to toggle source
# File lib/mspec/mocks/object.rb, line 21
def mock_int(val)
  MockIntObject.new(val)
end
mock_numeric(name, options={}) click to toggle source
# File lib/mspec/mocks/object.rb, line 25
def mock_numeric(name, options={})
  NumericMockObject.new name, options
end
mock_to_path(path) click to toggle source
# File lib/mspec/helpers/mock_to_path.rb, line 2
def mock_to_path(path)
  obj = mock('path')
  obj.should_receive(:to_path).and_return(path)
  obj
end
nan_value() click to toggle source
# File lib/mspec/helpers/numeric.rb, line 2
def nan_value
  0/0.0
end
new_datetime(opts={}) click to toggle source

The #new_datetime helper makes writing DateTime specs more simple by providing default constructor values and accepting a Hash of only the constructor values needed for the particular spec. For example:

new_datetime :hour => 1, :minute => 20

Possible keys are:

:year, :month, :day, :hour, :minute, :second, :offset and :sg.
# File lib/mspec/helpers/datetime.rb, line 11
def new_datetime(opts={})
  require 'date'

  value = {
    :year   => -4712,
    :month  => 1,
    :day    => 1,
    :hour   => 0,
    :minute => 0,
    :second => 0,
    :offset => 0,
    :sg     => Date::ITALY
  }.merge opts

  DateTime.new value[:year], value[:month], value[:day], value[:hour],
    value[:minute], value[:second], value[:offset], value[:sg]
end
new_fd(name, mode="w:utf-8") click to toggle source

Creates a “bare” file descriptor (i.e. one that is not associated with any Ruby object). The file descriptor can safely be passed to IO.new without creating a Ruby object alias to the fd.

# File lib/mspec/helpers/io.rb, line 33
def new_fd(name, mode="w:utf-8")
  mode = options_or_mode(mode)

  if mode.kind_of? Hash
    if mode.key? :mode
      mode = mode[:mode]
    else
      raise ArgumentError, "new_fd options Hash must include :mode"
    end
  end

  IO.sysopen name, fmode(mode)
end
new_hash(*args, &block) click to toggle source

Returns a new instance of hash_class.

# File lib/mspec/helpers/hash.rb, line 13
def new_hash(*args, &block)
  if block
    hash_class.new(&block)
  elsif args.size == 1
    value = args.first
    if value.is_a?(Hash) or value.is_a?(hash_class)
      hash_class[value]
    else
      hash_class.new value
    end
  else
    hash_class[*args]
  end
end
new_io(name, mode="w:utf-8") click to toggle source

Creates an IO instance for a temporary file name. The file must be deleted.

# File lib/mspec/helpers/io.rb, line 49
def new_io(name, mode="w:utf-8")
  IO.new new_fd(name, options_or_mode(mode)), options_or_mode(mode)
end
not_compliant_on(*args) { || ... } click to toggle source
# File lib/mspec/guards/compliance.rb, line 30
def not_compliant_on(*args)
  g = NotCompliantOnGuard.new(*args)
  g.name = :not_compliant_on
  yield if g.yield?
ensure
  g.unregister
end
not_supported_on(*args) { || ... } click to toggle source
# File lib/mspec/guards/support.rb, line 13
def not_supported_on(*args)
  g = SupportedGuard.new(*args)
  g.name = :not_supported_on
  yield if g.yield?
ensure
  g.unregister
end
options_or_mode(oom) click to toggle source

This helper simplifies passing file access modes or options regardless of whether the :encoding feature is enabled. Only the access specifier itself will be returned if :encoding is not enabled. Otherwise, the full mode string or option will be returned (i.e. the helper is a no-op).

# File lib/mspec/helpers/io.rb, line 69
def options_or_mode(oom)
  return fmode(oom) if oom.kind_of? String

  if FeatureGuard.enabled? :encoding
    oom
  else
    fmode(oom[:mode] || "r:utf-8")
  end
end
output(stdout=nil, stderr=nil) click to toggle source
# File lib/mspec/matchers/output.rb, line 64
def output(stdout=nil, stderr=nil)
  OutputMatcher.new(stdout, stderr)
end
output_to_fd(what, where = STDOUT) click to toggle source
# File lib/mspec/matchers/output_to_fd.rb, line 68
def output_to_fd(what, where = STDOUT)
  OutputToFDMatcher.new what, where
end
pack_int(*ary) click to toggle source
# File lib/mspec/helpers/pack.rb, line 1
def pack_int(*ary)
  ary.pack("i*")
end
platform_is(*args) { || ... } click to toggle source
# File lib/mspec/guards/platform.rb, line 32
def platform_is(*args)
  g = PlatformGuard.new(*args)
  g.name = :platform_is
  yield if g.yield?
ensure
  g.unregister
end
platform_is_not(*args) { || ... } click to toggle source
# File lib/mspec/guards/platform.rb, line 40
def platform_is_not(*args)
  g = PlatformGuard.new(*args)
  g.name = :platform_is_not
  yield if g.yield? true
ensure
  g.unregister
end
process_is_foreground() { || ... } click to toggle source
# File lib/mspec/guards/background.rb, line 14
def process_is_foreground
  g = BackgroundGuard.new
  g.name = :process_is_foreground
  yield if g.yield? true
ensure
  g.unregister
end
quarantine!() { || ... } click to toggle source
# File lib/mspec/guards/quarantine.rb, line 10
def quarantine!
  g = QuarantineGuard.new
  g.name = :quarantine!
  yield if g.yield?
ensure
  g.unregister
end
raise_error(exception=Exception, message=nil, &block) click to toggle source
# File lib/mspec/matchers/raise_error.rb, line 47
def raise_error(exception=Exception, message=nil, &block)
  RaiseErrorMatcher.new(exception, message, &block)
end
raise_exception(exception=Exception, message=nil, &block) click to toggle source
# File lib/mspec/matchers/raise_exception.rb, line 47
def raise_exception(exception=Exception, message=nil, &block)
  RaiseExceptionMatcher.new(exception, message, &block)
end
resolve_ruby_exe() click to toggle source
# File lib/mspec/helpers/ruby_exe.rb, line 104
def resolve_ruby_exe
  [:env, :engine, :name, :install_name].each do |option|
    next unless cmd = ruby_exe_options(option)
    exe, *rest = cmd.split(" ")

    # It has been reported that File.executable is not reliable
    # on Windows platforms (see commit 56bc555c). So, we check the
    # platform.
    if File.exist?(exe) and (PlatformGuard.windows? or File.executable?(exe))
      return [File.expand_path(exe), *rest].join(" ")
    end
  end
  nil
end
respond_to(expected) click to toggle source
# File lib/mspec/matchers/respond_to.rb, line 21
def respond_to(expected)
  RespondToMatcher.new(expected)
end
responds_to(sym) click to toggle source
# File lib/mspec/helpers/ducktype.rb, line 2
def responds_to(sym)
  singleton_class.class_eval <<-END
    def respond_to?(sym, include_private=false)
      sym.to_sym == #{sym.to_sym.inspect} ? true : super
    end
  END
end
rm_r(*paths) click to toggle source

Recursively removes all files and directories in path if path is a directory. Removes the file if path is a file.

# File lib/mspec/helpers/fs.rb, line 31
def rm_r(*paths)
  paths.each do |path|
    path = File.expand_path path

    prefix = SPEC_TEMP_DIR
    unless path[0, prefix.size] == prefix
      raise ArgumentError, "#{path} is not prefixed by #{prefix}"
    end

    # File.symlink? needs to be checked first as
    # File.exist? returns false for dangling symlinks
    if File.symlink? path
      File.unlink path
    elsif File.directory? path
      Dir.entries(path).each { |x| rm_r "#{path}/#{x}" unless x =~ /^\.\.?$/ }
      Dir.rmdir path
    elsif File.exist? path
      File.delete path
    end
  end
end
ruby_bug(bug, version) { || ... } click to toggle source
# File lib/mspec/guards/bug.rb, line 17
def ruby_bug(bug, version)
  g = BugGuard.new bug, version
  g.name = :ruby_bug
  yield if g.yield? true
ensure
  g.unregister
end
ruby_cmd(code, opts = {}) click to toggle source
# File lib/mspec/helpers/ruby_exe.rb, line 142
def ruby_cmd(code, opts = {})
  body = code

  if code and not File.exist?(code)
    if opts[:escape]
      code = "'#{code}'"
    else
      code = code.inspect
    end
    body = "-e #{code}"
  end

  [RUBY_EXE, ENV['RUBY_FLAGS'], opts[:options], body, opts[:args]].compact.join(' ')
end
ruby_exe(code, opts = {}) click to toggle source
# File lib/mspec/helpers/ruby_exe.rb, line 119
def ruby_exe(code, opts = {})
  env = opts[:env] || {}
  working_dir = opts[:dir] || "."
  Dir.chdir(working_dir) do
    saved_env = {}
    env.each do |key, value|
      key = key.to_s
      saved_env[key] = ENV[key] if ENV.key? key
      ENV[key] = value
    end

    begin
      %x`#{ruby_cmd(code, opts)}`
    ensure
      saved_env.each { |key, value| ENV[key] = value }
      env.keys.each do |key|
        key = key.to_s
        ENV.delete key unless saved_env.key? key
      end
    end
  end
end
ruby_exe_options(option) click to toggle source
# File lib/mspec/helpers/ruby_exe.rb, line 73
def ruby_exe_options(option)
  case option
  when :env
    ENV['RUBY_EXE']
  when :engine
    case RUBY_NAME
    when 'rbx'
      if SpecGuard.ruby_version < "1.9"
        "bin/rbx"
      else
        "bin/rbx -X19"
      end
    when 'jruby'
      "bin/jruby"
    when 'maglev'
      "maglev-ruby"
    when 'topaz'
      "topaz"
    when 'ironruby'
      "ir"
    end
  when :name
    bin = RUBY_NAME + (RbConfig::CONFIG['EXEEXT'] || RbConfig::CONFIG['exeext'] || '')
    File.join(".", bin)
  when :install_name
    bin = RbConfig::CONFIG["RUBY_INSTALL_NAME"] || RbConfig::CONFIG["ruby_install_name"]
    bin << (RbConfig::CONFIG['EXEEXT'] || RbConfig::CONFIG['exeext'] || '')
    File.join(RbConfig::CONFIG['bindir'], bin)
  end
end
ruby_version_is(*args) { || ... } click to toggle source
# File lib/mspec/guards/version.rb, line 31
def ruby_version_is(*args)
  g = VersionGuard.new(*args)
  begin
    g.name = :ruby_version_is
    yield if g.yield?
  ensure
    g.unregister
  end
end
runner_is(*args) { || ... } click to toggle source
# File lib/mspec/guards/runner.rb, line 19
def runner_is(*args)
  g = RunnerGuard.new(*args)
  g.name = :runner_is
  yield if g.yield?
ensure
  g.unregister
end
runner_is_not(*args) { || ... } click to toggle source
# File lib/mspec/guards/runner.rb, line 27
def runner_is_not(*args)
  g = RunnerGuard.new(*args)
  g.name = :runner_is_not
  yield if g.yield? true
ensure
  g.unregister
end
should(matcher=NO_MATCHER_GIVEN) click to toggle source
# File lib/mspec/expectations/should.rb, line 3
def should(matcher=NO_MATCHER_GIVEN)
  MSpec.expectation
  MSpec.actions :expectation, MSpec.current.state
  unless matcher.equal?(NO_MATCHER_GIVEN)
    unless matcher.matches?(self)
      SpecExpectation.fail_with(*matcher.failure_message)
    end
  else
    SpecPositiveOperatorMatcher.new(self)
  end
end
should_not(matcher=NO_MATCHER_GIVEN) click to toggle source
# File lib/mspec/expectations/should.rb, line 15
def should_not(matcher=NO_MATCHER_GIVEN)
  MSpec.expectation
  MSpec.actions :expectation, MSpec.current.state
  unless matcher.equal?(NO_MATCHER_GIVEN)
    if matcher.matches?(self)
      SpecExpectation.fail_with(*matcher.negative_failure_message)
    end
  else
    SpecNegativeOperatorMatcher.new(self)
  end
end
should_not_receive(sym) click to toggle source
# File lib/mspec/mocks/object.rb, line 12
def should_not_receive(sym)
  proxy = Mock.install_method self, sym
  proxy.exactly(0).times
end
should_receive(sym) click to toggle source
# File lib/mspec/mocks/object.rb, line 8
def should_receive(sym)
  Mock.install_method self, sym
end
singleton_class() click to toggle source
# File lib/mspec/helpers/singleton_class.rb, line 3
def singleton_class
  class << self; self; end
end
specified_on(*args) { || ... } click to toggle source

This guard wraps specs for one or more particular implementations. See the unspecified guard for further documentation.

# File lib/mspec/guards/specified.rb, line 59
def specified_on(*args)
  g = SpecifiedOnGuard.new(*args)
  g.name = :specified_on
  yield if g.yield?
ensure
  g.unregister
end
specify(msg, &block)
Alias for: it
stasy(one, *rest) click to toggle source

Accepts either a single argument or an Array of arguments. If RUBY_VERSION is less than 1.9, converts the argument(s) to Strings; otherwise, converts the argument(s) to Symbols.

If one argument is passed, the converted argument is returned. If an Array is passed, an Array is returned.

For example, if RUBY_VERSION == 1.8.7

stasy(:some) => "some"
stasy("nom") => "nom"

while if RUBY_VERSION == 1.9.0

stasy(:some) => :some
stasy("nom") => :nom
# File lib/mspec/helpers/stasy.rb, line 22
def stasy(one, *rest)
  era = SpecVersion.new(SpecGuard.ruby_version) < "1.9"
  convert = era ? :to_s : :to_sym

  one = one.send convert
  if rest.empty?
    one
  else
    [one].concat rest.map { |x| x.send convert }
  end
end
stub!(sym) click to toggle source
# File lib/mspec/mocks/object.rb, line 4
def stub!(sym)
  Mock.install_method self, sym, :stub
end
tmp(name, uniquify=true) click to toggle source
# File lib/mspec/helpers/tmp.rb, line 34
def tmp(name, uniquify=true)
  Dir.mkdir SPEC_TEMP_DIR unless File.exist? SPEC_TEMP_DIR

  if uniquify and !name.empty?
    slash = name.rindex "/"
    index = slash ? slash + 1 : 0
    name.insert index, "#{SPEC_TEMP_UNIQUIFIER.succ!}-"
  end

  File.join SPEC_TEMP_DIR, name
end
touch(name, mode="w") { |f| ... } click to toggle source

Creates a file name. Creates the directory for name if it does not exist.

# File lib/mspec/helpers/fs.rb, line 55
def touch(name, mode="w")
  mkdir_p File.dirname(name)

  File.open(name, mode) do |f|
    yield f if block_given?
  end
end
undefine(sym) click to toggle source
# File lib/mspec/helpers/ducktype.rb, line 18
def undefine(sym)
  singleton_class.class_eval <<-END
    undef_method #{sym.to_sym.inspect}
  END
end
unspecified() { || ... } click to toggle source

This guard wraps one or more specified_on guards to group them and document the specs. The purpose of the guard is for situations where MRI either does not specify Ruby behavior or where MRI's behavior is all but impossible to spec, for example due to relying on platform-specific behavior that is not easily testable from Ruby code. In such cases, it may be desirable for implementations to explore a specified set of behaviors that are explicitly documented in the specs.

unspecified do
  specified_on :rubinius, :ironruby do
    it "returns true when passed :foo" do
      # ...
    end

    it "returns false when passed :bar" do
      # ...
    end
  end

  specified_on :jruby do
    it "returns true when passed :bar" do
      # ...
    end
  end
end

Note that these guards do not change the policy of the compliant_on, not_compliant_on, deviates_on, extended_on, and not_supported_on guards.

# File lib/mspec/guards/specified.rb, line 49
def unspecified
  g = UnspecifiedGuard.new
  g.name = :unspecified
  yield if g.yield?
ensure
  g.unregister
end
username() click to toggle source
# File lib/mspec/helpers/environment.rb, line 18
def username
  user = ""
  if PlatformGuard.windows?
    user = windows_env_echo('USERNAME')
  else
    user = %x`whoami`.strip
  end
  user
end
windows_env_echo(var) click to toggle source
# File lib/mspec/helpers/environment.rb, line 14
def windows_env_echo(var)
  %x`cmd.exe /C ECHO %#{var}%`.strip
end
with_block_device() { || ... } click to toggle source
# File lib/mspec/guards/block_device.rb, line 15
def with_block_device
  g = BlockDeviceGuard.new
  g.name = :with_block_device
  yield if g.yield?
ensure
  g.unregister
end
with_feature(*features) { || ... } click to toggle source

Provides better documentation in the specs by naming sets of features that work together as a whole. Examples include :encoding, :fiber, :continuation, :fork.

Usage example:

with_feature :encoding do
  # specs for a method that provides aspects
  # of the encoding feature
end

Multiple features must all be enabled for the guard to run:

with_feature :one, :two do
  # these specs will run if features :one AND
  # :two are enabled.
end

The implementation must explicitly enable a feature by adding code like the following to the .mspec configuration file:

MSpec.enable_feature :encoding
# File lib/mspec/guards/feature.rb, line 40
def with_feature(*features)
  g = FeatureGuard.new(*features)
  g.name = :with_feature
  yield if g.yield?
ensure
  g.unregister
end
with_tty() { || ... } click to toggle source
# File lib/mspec/guards/tty.rb, line 13
def with_tty
  g = TTYGuard.new
  g.name = :with_tty
  yield if g.yield?
ensure
  g.unregister
end