Skip to content

Commit

Permalink
Generate documentation using YARD instead of RDoc.
Browse files Browse the repository at this point in the history
- YARD allows for much richer documentation.
- It looks prettier too.
- I hope to remove the dependencies on rdoc & coderay.
  • Loading branch information
floehopper committed Mar 31, 2012
1 parent 5753a8a commit 4e28497
Show file tree
Hide file tree
Showing 34 changed files with 1,070 additions and 663 deletions.
2 changes: 1 addition & 1 deletion COPYING.rdoc
@@ -1,3 +1,3 @@
Copyright Revieworld Ltd. 2006 Copyright Revieworld Ltd. 2006


You may use, copy and redistribute this library under the same terms as {Ruby itself}[http://www.ruby-lang.org/en/LICENSE.txt] or under the {MIT license}[/files/MIT-LICENSE.rdoc.html]. You may use, copy and redistribute this library under the same terms as {Ruby itself}[http://www.ruby-lang.org/en/LICENSE.txt] or under the {file:MIT-LICENSE.rdoc MIT license}.
8 changes: 4 additions & 4 deletions README.rdoc
Expand Up @@ -36,9 +36,9 @@ Note that versions 0.9.6 & 0.9.7 of the Rails plugin were broken. As of version


== Examples == Examples


* Quick Start - {Usage Examples}[/examples/misc.html] * Quick Start - {file:misc.rb Usage Examples}
* Traditional mocking - {Star Trek Example}[/examples/mocha.html] * Traditional mocking - {file:mocha.rb Star Trek Example}
* Setting expectations on real classes - {Order Example}[/examples/stubba.html] * Setting expectations on real classes - {file:stubba.rb Order Example}
* More examples on {James Mead's Blog}[http://jamesmead.org/blog/] * More examples on {James Mead's Blog}[http://jamesmead.org/blog/]
* {Mailing List Archives}[http://groups.google.com/group/mocha-developer] * {Mailing List Archives}[http://groups.google.com/group/mocha-developer]


Expand All @@ -51,4 +51,4 @@ Note that versions 0.9.6 & 0.9.7 of the Rails plugin were broken. As of version


Copyright Revieworld Ltd. 2006 Copyright Revieworld Ltd. 2006


You may use, copy and redistribute this library under the same terms as {Ruby itself}[http://www.ruby-lang.org/en/LICENSE.txt] or under the {MIT license}[/files/MIT-LICENSE.rdoc.html]. You may use, copy and redistribute this library under the same terms as {Ruby itself}[http://www.ruby-lang.org/en/LICENSE.txt] or under the {file:MIT-LICENSE.rdoc MIT license}.
43 changes: 22 additions & 21 deletions Rakefile
Expand Up @@ -2,7 +2,7 @@ require "bundler"
Bundler::GemHelper.install_tasks Bundler::GemHelper.install_tasks
require "bundler/setup" require "bundler/setup"


require 'rdoc/task' require 'yard'
require 'rake/testtask' require 'rake/testtask'


desc "Run all tests" desc "Run all tests"
Expand Down Expand Up @@ -81,37 +81,38 @@ def benchmark_test_case(klass, iterations)
end end
end end


desc 'Generate RDoc' desc 'Remove generated documentation'
Rake::RDocTask.new('rdoc') do |task| task 'clobber_yardoc' do
task.generator = 'hanna' `rm -rf ./doc`
task.main = 'README.rdoc' end
task.title = "Mocha #{Mocha::VERSION}"
task.rdoc_dir = 'doc' desc 'Generate documentation'
template = File.expand_path(File.join(File.dirname(__FILE__), "templates", "html_with_google_analytics.rb")) YARD::Rake::YardocTask.new('yardoc') do |task|
if File.exist?(template) task.options = ["--title", "Mocha #{Mocha::VERSION}", "--no-private"]
puts "*** Using RDoc template incorporating Google Analytics" task.files = [
task.template = template
end
task.rdoc_files.include(
'README.rdoc',
'RELEASE.rdoc',
'COPYING.rdoc',
'MIT-LICENSE.rdoc',
'agiledox.txt',
'lib/mocha/api.rb', 'lib/mocha/api.rb',
'lib/mocha/mock.rb', 'lib/mocha/mock.rb',
'lib/mocha/expectation.rb', 'lib/mocha/expectation.rb',
'lib/mocha/object.rb', 'lib/mocha/object.rb',
'lib/mocha/parameter_matchers.rb', 'lib/mocha/parameter_matchers.rb',
'lib/mocha/parameter_matchers', 'lib/mocha/parameter_matchers',
'lib/mocha/state_machine.rb', 'lib/mocha/state_machine.rb',
'lib/mocha/sequence.rb',
'lib/mocha/configuration.rb', 'lib/mocha/configuration.rb',
'lib/mocha/stubbing_error.rb' 'lib/mocha/stubbing_error.rb',
) '-',
'RELEASE.rdoc',
'COPYING.rdoc',
'MIT-LICENSE.rdoc',
'agiledox.txt',
'examples/mocha.rb',
'examples/stubba.rb',
'examples/misc.rb',
]
end end


desc "Generate documentation" desc "Generate documentation"
task 'generate_docs' => ['clobber_rdoc', 'rdoc', 'examples', 'agiledox.txt'] task 'generate_docs' => ['clobber_yardoc', 'agiledox.txt', 'yardoc']


desc "Publish docs to Github (relies on running 'generate_docs' task and committing changes to master branch)" desc "Publish docs to Github (relies on running 'generate_docs' task and committing changes to master branch)"
task 'publish_docs' do task 'publish_docs' do
Expand Down
226 changes: 120 additions & 106 deletions lib/mocha/api.rb
Expand Up @@ -2,40 +2,40 @@
require 'mocha/mockery' require 'mocha/mockery'
require 'mocha/sequence' require 'mocha/sequence'


module Mocha # :nodoc: module Mocha

# Methods added to Test::Unit::TestCase or equivalent. # Methods added to +Test::Unit::TestCase+ or equivalent.
module API module API

include ParameterMatchers include ParameterMatchers

# :call-seq: mock(name, &block) -> mock object # Builds a new mock object
# mock(expected_methods = {}, &block) -> mock object #
# mock(name, expected_methods = {}, &block) -> mock object # @param [String] name identifies mock object in error messages.
# # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {Mock#expects} were called multiple times.
# Creates a mock object. # @yield optional block to be evaluated against the mock object instance, giving an alternative way to setup expectations.
# # @return [Mock] a new mock object
# +name+ is a +String+ identifier for the mock object. #
# # @overload def mock(name, &block)
# +expected_methods+ is a +Hash+ with expected method name symbols as keys and corresponding return values as values. # @overload def mock(expected_methods_vs_return_values = {}, &block)
# # @overload def mock(name, expected_methods_vs_return_values = {}, &block)
# Note that (contrary to expectations set up by #stub) these expectations <b>must</b> be fulfilled during the test. #
# def test_product # @example Using expected_methods_vs_return_values Hash to setup expectations.
# product = mock('ipod_product', :manufacturer => 'ipod', :price => 100) # def test_motor_starts_and_stops
# assert_equal 'ipod', product.manufacturer # motor = mock('motor', :start => true, :stop => true)
# assert_equal 100, product.price # assert motor.start
# # an error will be raised unless both Product#manufacturer and Product#price have been called # assert motor.stop
# end # # an error will be raised unless both Motor#start and Motor#stop have been called
# # end
# +block+ is an optional block to be evaluated against the mock object instance, giving an alernative way to set up expectations & stubs. # @example Using the optional block to setup expectations & stubbed methods.
# def test_product # def test_motor_starts_and_stops
# product = mock('ipod_product') do # motor = mock('motor') do
# expects(:manufacturer).returns('ipod') # expects(:start).with(100.rpm).returns(true)
# expects(:price).returns(100) # stubs(:stop).returns(true)
# end # end
# assert_equal 'ipod', product.manufacturer # assert motor.start(100.rpm)
# assert_equal 100, product.price # assert motor.stop
# # an error will be raised unless both Product#manufacturer and Product#price have been called # # an error will only be raised if Motor#start(100.rpm) has not been called
# end # end
def mock(*arguments, &block) def mock(*arguments, &block)
name = arguments.shift if arguments.first.is_a?(String) name = arguments.shift if arguments.first.is_a?(String)
Expand All @@ -44,58 +44,61 @@ def mock(*arguments, &block)
mock.expects(expectations) mock.expects(expectations)
mock mock
end end


# :call-seq: stub(name, &block) -> mock object # Builds a new mock object
# stub(stubbed_methods = {}, &block) -> mock object #
# stub(name, stubbed_methods = {}, &block) -> mock object # @param [String] name identifies mock object in error messages.
# # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {Mock#stubs} were called multiple times.
# Creates a mock object. # @yield optional block to be evaluated against the mock object instance, giving an alternative way to setup stubbed methods.
# # @return [Mock] a new mock object
# +name+ is a +String+ identifier for the mock object. #
# # @overload def stub(name, &block)
# +stubbed_methods+ is a +Hash+ with stubbed method name symbols as keys and corresponding return values as values. # @overload def stub(stubbed_methods_vs_return_values = {}, &block)
# Note that (contrary to expectations set up by #mock) these expectations <b>need not</b> be fulfilled during the test. # @overload def stub(name, stubbed_methods_vs_return_values = {}, &block)
# def test_product #
# product = stub('ipod_product', :manufacturer => 'ipod', :price => 100) # @example Using stubbed_methods_vs_return_values Hash to setup stubbed methods.
# assert_equal 'ipod', product.manufacturer # def test_motor_starts_and_stops
# assert_equal 100, product.price # motor = mock('motor', :start => true, :stop => true)
# # an error will not be raised even if Product#manufacturer and Product#price have not been called # assert motor.start
# assert motor.stop
# # an error will not be raised even if either Motor#start or Motor#stop has not been called
# end # end
# #
# +block+ is an optional block to be evaluated against the mock object instance, giving an alernative way to set up expectations & stubs. # @example Using the optional block to setup expectations & stubbed methods.
# def test_product # def test_motor_starts_and_stops
# product = stub('ipod_product') do # motor = mock('motor') do
# stubs(:manufacturer).returns('ipod') # expects(:start).with(100.rpm).returns(true)
# stubs(:price).returns(100) # stubs(:stop).returns(true)
# end # end
# assert_equal 'ipod', product.manufacturer # assert motor.start(100.rpm)
# assert_equal 100, product.price # assert motor.stop
# # an error will not be raised even if Product#manufacturer and Product#price have not been called # # an error will only be raised if Motor#start(100.rpm) has not been called
# end # end
def stub(*arguments, &block) def stub(*arguments, &block)
name = arguments.shift if arguments.first.is_a?(String) name = arguments.shift if arguments.first.is_a?(String)
expectations = arguments.shift || {} expectations = arguments.shift || {}
stub = name ? Mockery.instance.named_mock(name, &block) : Mockery.instance.unnamed_mock(&block) stub = name ? Mockery.instance.named_mock(name, &block) : Mockery.instance.unnamed_mock(&block)
stub.stubs(expectations) stub.stubs(expectations)
stub stub
end end


# :call-seq: stub_everything(name, &block) -> mock object # Builds a mock object that accepts calls to any method. By default it will return +nil+ for any method call.
# stub_everything(stubbed_methods = {}, &block) -> mock object #
# stub_everything(name, stubbed_methods = {}, &block) -> mock object # @param [String] name identifies mock object in error messages.
# # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {Mock#stubs} were called multiple times.
# Creates a mock object that accepts calls to any method. # @yield optional block to be evaluated against the mock object instance, giving an alternative way to setup stubbed methods.
# # @return [Mock] a new mock object
# By default it will return +nil+ for any method call. #
# # @overload def stub_everything(name, &block)
# +block+ is a block to be evaluated against the mock object instance, giving an alernative way to set up expectations & stubs. # @overload def stub_everything(stubbed_methods_vs_return_values = {}, &block)
# # @overload def stub_everything(name, stubbed_methods_vs_return_values = {}, &block)
# +name+ and +stubbed_methods+ work in the same way as for #stub. #
# def test_product # @example Ignore invocations of irrelevant methods.
# product = stub_everything('ipod_product', :price => 100) # def test_motor_stops
# assert_nil product.manufacturer # motor = stub_everything('motor', :stop => true)
# assert_nil product.any_old_method # assert_nil motor.irrelevant_method_1 # => no error raised
# assert_equal 100, product.price # assert_nil motor.irrelevant_method_2 # => no error raised
# assert motor.stop
# end # end
def stub_everything(*arguments, &block) def stub_everything(*arguments, &block)
name = arguments.shift if arguments.first.is_a?(String) name = arguments.shift if arguments.first.is_a?(String)
Expand All @@ -105,69 +108,80 @@ def stub_everything(*arguments, &block)
stub.stubs(expectations) stub.stubs(expectations)
stub stub
end end

# :call-seq: sequence(name) -> sequence # Builds a new sequence which can be used to constrain the order in which expectations can occur.
# #
# Returns a new sequence that is used to constrain the order in which expectations can occur. # Specify that an expected invocation must occur within a named {Sequence} by using {Expectation#in_sequence}.
# #
# Specify that an expected invocation must occur in within a named +sequence+ by using Expectation#in_sequence. # @return [Sequence] a new sequence
# #
# See also Expectation#in_sequence. # @see Expectation#in_sequence
#
# @example Ensure methods on egg are invoked in correct order.
# breakfast = sequence('breakfast') # breakfast = sequence('breakfast')
# #
# egg = mock('egg') # egg = mock('egg') do
# egg.expects(:crack).in_sequence(breakfast) # expects(:crack).in_sequence(breakfast)
# egg.expects(:fry).in_sequence(breakfast) # expects(:fry).in_sequence(breakfast)
# egg.expects(:eat).in_sequence(breakfast) # expects(:eat).in_sequence(breakfast)
# end
def sequence(name) def sequence(name)
Sequence.new(name) Sequence.new(name)
end end

# :call-seq: states(name) -> state_machine # Builds a new state machine which can be used to constrain the order in which expectations can occur.
# #
# Returns a new +state_machine+ that is used to constrain the order in which expectations can occur. # Specify the initial state of the state machine by using {StateMachine#starts_as}.
# #
# Specify the initial +state+ of the +state_machine+ by using StateMachine#starts_as. # Specify that an expected invocation should change the state of the state machine by using {Expectation#then}.
# #
# Specify that an expected invocation should change the +state+ of the +state_machine+ by using Expectation#then. # Specify that an expected invocation should be constrained to occur within a particular +state+ by using {Expectation#when}.
# #
# Specify that an expected invocation should be constrained to occur within a particular +state+ by using Expectation#when. # A test can contain multiple state machines.
# #
# A test can contain multiple +state_machines+. # @return [StateMachine] a new state machine
# #
# See also Expectation#then, Expectation#when and StateMachine. # @see Expectation#then
# @see Expectation#when
# @see StateMachine
# @example Constrain expected invocations to occur in particular states.
# power = states('power').starts_as('off') # power = states('power').starts_as('off')
# #
# radio = mock('radio') # radio = mock('radio') do
# radio.expects(:switch_on).then(power.is('on')) # expects(:switch_on).then(power.is('on'))
# radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on')) # expects(:select_channel).with('BBC Radio 4').when(power.is('on'))
# radio.expects(:adjust_volume).with(+5).when(power.is('on')) # expects(:adjust_volume).with(+5).when(power.is('on'))
# radio.expects(:select_channel).with('BBC World Service').when(power.is('on')) # expects(:select_channel).with('BBC World Service').when(power.is('on'))
# radio.expects(:adjust_volume).with(-5).when(power.is('on')) # expects(:adjust_volume).with(-5).when(power.is('on'))
# radio.expects(:switch_off).then(power.is('off')) # expects(:switch_off).then(power.is('off'))
# end
def states(name) def states(name)
Mockery.instance.new_state_machine(name) Mockery.instance.new_state_machine(name)
end end


def mocha_setup # :nodoc: # @private
def mocha_setup
end end


def mocha_verify(assertion_counter = nil) # :nodoc: # @private
def mocha_verify(assertion_counter = nil)
Mockery.instance.verify(assertion_counter) Mockery.instance.verify(assertion_counter)
end end


def mocha_teardown # :nodoc: # @private
def mocha_teardown
Mockery.instance.teardown Mockery.instance.teardown
Mockery.reset_instance Mockery.reset_instance
end end

end end


# @private
def self.const_missing(name) def self.const_missing(name)
return super unless name == :Standalone return super unless name == :Standalone
require 'mocha/deprecation' require 'mocha/deprecation'
Deprecation.warning "Mocha::Standalone has been renamed to Mocha::API" Deprecation.warning "Mocha::Standalone has been renamed to Mocha::API"
return API return API
end end

end end

0 comments on commit 4e28497

Please sign in to comment.