Git Product home page Git Product logo

mocha's Introduction

Mocha CircleCI status of freerange/mocha Gem Version

Description

  • A Ruby library for mocking and stubbing - but deliberately not (yet) faking or spying.
  • A unified, simple and readable syntax for both full & partial mocking.
  • Built-in support for Minitest and Test::Unit.
  • Supported by many other test frameworks.

Intended Usage

Mocha is intended to be used in unit tests for the Mock Object or Test Stub types of Test Double, not the Fake Object or Test Spy types. Although it would be possible to extend Mocha to allow the implementation of fakes and spies, we have chosen to keep it focused on mocks and stubs.

Installation

Gem

Install the latest version of the gem with the following command...

$ gem install mocha

Note: If you are intending to use Mocha with Test::Unit or Minitest, you should only setup Mocha after loading the relevant test library...

Test::Unit
require 'rubygems'
gem 'mocha'
require 'test/unit'
require 'mocha/test_unit'
Minitest
require 'rubygems'
gem 'mocha'
require 'minitest/autorun'
require 'mocha/minitest'

Bundler

If you're using Bundler, include Mocha in the Gemfile and then setup Mocha later once you know the test library has been loaded...

Test::Unit
# Gemfile
gem 'mocha'

# Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'`
require 'test/unit'
require 'mocha/test_unit'
Minitest
# Gemfile
gem 'mocha'

# Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'`
require 'minitest/autorun'
require 'mocha/minitest'
RSpec

RSpec includes a mocha adapter. Just tell RSpec you want to mock with :mocha:

# Gemfile in Rails app
gem 'mocha'

# Within `spec/spec_helper.rb`
RSpec.configure do |config|
  config.mock_with :mocha
end

Note: There is no need to use a require statement to setup Mocha; RSpec does this itself.

Cucumber
# In e.g. features/support/mocha.rb
require 'mocha/api'

World(Mocha::API)

Around do |scenario, block|
  begin
    mocha_setup
    block.call
    mocha_verify
  ensure
    mocha_teardown
  end
end

Rails

If you're loading Mocha using Bundler within a Rails application, you should setup Mocha manually e.g. at the bottom of your test_helper.rb.

Minitest

Note that since Rails v4 (at least), ActiveSupport::TestCase has inherited from Minitest::Test or its earlier equivalents. Thus unless you are explicitly using Test::Unit, you are likely to be using Minitest.

# Gemfile in Rails app
gem 'mocha'

# At bottom of test_helper.rb (or at least after `require 'rails/test_help'`)
require 'mocha/minitest'
Other Test Framework

Follow the instructions for the relevant test framework in the Bundler section, but ensure that the relevant Mocha file (mocha/minitest, mocha/test_unit, or mocha/api) is required after the test framework has been loaded, e.g. at the bottom of test_helper.rb or spec_helper.rb, or at least after rails/test_help has been required.

Known Issues

  • In Mocha v1.10.0 an undocumented feature of API#mock, API#stub & API#stub_everything was changed. Previously when these methods were passed a single symbol, they returned a mock object that responded to the method identified by the symbol. Now Passing a single symbol is equivalent to passing a single string, i.e. it now defines the 'name' of the mock object.
  • In Mocha v1.2.0 there is a scenario where stubbing a class method originally defined in a module hangs the Ruby interpreter due to a bug in Ruby v2.3.1. See #272. This was fixed in Mocha v1.2.1.
  • Since v1.1.0 Mocha has used prepended modules internally for stubbing methods. There is an obscure Ruby bug in many (but not all) versions of Ruby between v2.0 & v2.3 which under certain circumstances may cause your Ruby interpreter to hang. See the Ruby bug report for more details. The bug has been fixed in Ruby v2.3.3 & v2.4.0.
  • Stubbing an aliased class method, where the original method is defined in a module that's used to extend the class doesn't work in Ruby 1.8.x. See stub_method_defined_on_module_and_aliased_test.rb for an example of this behaviour.
  • 0.13.x versions cause a harmless, but annoying, deprecation warning when used with Rails 3.2.0-3.2.12, 3.1.0-3.1.10 & 3.0.0-3.0.19.
  • 0.11.x versions don't work with Rails 3.2.13 (TypeError: superclass mismatch for class ExpectationError). See #115.
  • Versions 0.10.2, 0.10.3 & 0.11.0 of the Mocha gem were broken. Please do not use these versions.

Usage

Quick Start

require 'test/unit'
require 'mocha/test_unit'

class MiscExampleTest < Test::Unit::TestCase
  def test_mocking_a_class_method
    product = Product.new
    Product.expects(:find).with(1).returns(product)
    assert_equal product, Product.find(1)
  end

  def test_mocking_an_instance_method_on_a_real_object
    product = Product.new
    product.expects(:save).returns(true)
    assert product.save
  end

  def test_stubbing_instance_methods_on_real_objects
    prices = [stub(pence: 1000), stub(pence: 2000)]
    product = Product.new
    product.stubs(:prices).returns(prices)
    assert_equal [1000, 2000], product.prices.collect {|p| p.pence}
  end

  def test_stubbing_an_instance_method_on_all_instances_of_a_class
    Product.any_instance.stubs(:name).returns('stubbed_name')
    product = Product.new
    assert_equal 'stubbed_name', product.name
  end

  def test_traditional_mocking
    object = mock('object')
    object.expects(:expected_method).with(:p1, :p2).returns(:result)
    assert_equal :result, object.expected_method(:p1, :p2)
  end

  def test_shortcuts
    object = stub(method1: :result1, method2: :result2)
    assert_equal :result1, object.method1
    assert_equal :result2, object.method2
  end
end

Mock Objects

class Enterprise
  def initialize(dilithium)
    @dilithium = dilithium
  end

  def go(warp_factor)
    warp_factor.times { @dilithium.nuke(:anti_matter) }
  end
end

require 'test/unit'
require 'mocha/test_unit'

class EnterpriseTest < Test::Unit::TestCase
  def test_should_boldly_go
    dilithium = mock()
    dilithium.expects(:nuke).with(:anti_matter).at_least_once  # auto-verified at end of test
    enterprise = Enterprise.new(dilithium)
    enterprise.go(2)
  end
end

Partial Mocking

class Order
  attr_accessor :shipped_on

  def total_cost
    line_items.inject(0) { |total, line_item| total + line_item.price } + shipping_cost
  end

  def total_weight
    line_items.inject(0) { |total, line_item| total + line_item.weight }
  end

  def shipping_cost
    total_weight * 5 + 10
  end

  class << self
    def find_all
      # Database.connection.execute('select * from orders...
    end

    def number_shipped_since(date)
      find_all.select { |order| order.shipped_on > date }.length
    end

    def unshipped_value
      find_all.inject(0) { |total, order| order.shipped_on ? total : total + order.total_cost }
    end
  end
end

require 'test/unit'
require 'mocha/test_unit'

class OrderTest < Test::Unit::TestCase
  # illustrates stubbing instance method
  def test_should_calculate_shipping_cost_based_on_total_weight
    order = Order.new
    order.stubs(:total_weight).returns(10)
    assert_equal 60, order.shipping_cost
  end

  # illustrates stubbing class method
  def test_should_count_number_of_orders_shipped_after_specified_date
    now = Time.now; week_in_secs = 7 * 24 * 60 * 60
    order_1 = Order.new; order_1.shipped_on = now - 1 * week_in_secs
    order_2 = Order.new; order_2.shipped_on = now - 3 * week_in_secs
    Order.stubs(:find_all).returns([order_1, order_2])
    assert_equal 1, Order.number_shipped_since(now - 2 * week_in_secs)
  end

  # illustrates stubbing instance method for all instances of a class
  def test_should_calculate_value_of_unshipped_orders
    Order.stubs(:find_all).returns([Order.new, Order.new, Order.new])
    Order.any_instance.stubs(:shipped_on).returns(nil)
    Order.any_instance.stubs(:total_cost).returns(10)
    assert_equal 30, Order.unshipped_value
  end
end

Thread safety

Mocha currently does not attempt to be thread-safe.

Can I test multi-threaded code with Mocha?

The short answer is no. In multi-threaded code Mocha exceptions may be raised in a thread other than the one which is running the test and thus a Mocha exception may not be correctly intercepted by Mocha exception handling code.

Can I run my tests across multiple threads?

Maybe, but probably not. Partial mocking changes the state of objects in the ObjectSpace which is shared across all threads in the Ruby process and this access to what is effectively global state is not synchronized. So, for example, if two tests are running concurrently and one uses #any_instance to modify a class, both tests will see those changes immediately.

Expectation matching / invocation order

Stubs and expectations are basically the same thing. A stub is just an expectation of zero or more invocations. The Expectation#stubs method is syntactic sugar to make the intent of the test more explicit.

When a method is invoked on a mock object, the mock object searches through its expectations from newest to oldest to find one that matches the invocation. After the invocation, the matching expectation might stop matching further invocations.

See the documentation for Mocha::Mock for further details.

Configuration

If you want, Mocha can generate a warning or raise an exception when:

  • stubbing a method unnecessarily
  • stubbing method on a non-mock object
  • stubbing a non-existent method
  • stubbing a non-public method

See the documentation for Mocha::Configuration for further details.

MOCHA_OPTIONS

MOCHA_OPTIONS is an environment variable whose value can be set to a comma-separated list, so that we can specify multiple options e.g. MOCHA_OPTIONS=debug,use_test_unit_gem. Only the following values are currently recognized and have an effect:

  • debug: Enables a debug mode which will output backtraces for each deprecation warning. This is useful for finding where in the test suite the deprecated calls are.

Semantic versioning

  • Every effort is made to comply with semantic versioning.
  • However, this only applies to the behaviour documented in the public API.
  • The documented public API does not include the content or format of messsages displayed to the user, e.g. assertion failure messages.

Useful Links

Contributors

See this list of contributors.

Releasing a new version

$ MOCHA_GENERATE_DOCS=true bundle install

$ MOCHA_GENERATE_DOCS=true rake generate_docs
$ curl -u <email-address> -H 'OTP:<one-time-password>' https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
  • Release gem to Rubygems:
$ rake release
[runs tests]
mocha 1.2.0 built to pkg/mocha-1.2.0.gem.
Tagged v1.2.0.
Pushed git commits and tags.
Pushed mocha 1.2.0 to rubygems.org.

History

Mocha was initially harvested from projects at Reevoo. It's syntax is heavily based on that of jMock.

License

ยฉ Copyright James Mead 2006

You may use, copy and redistribute this library under the same terms as Ruby itself or under the MIT license.

mocha's People

Contributors

10io avatar alexcoco avatar alloy avatar andyw8 avatar arthurnn avatar byroot avatar chrisroos avatar chrisroos-and-floehopper avatar cstyles avatar dan-manges avatar deepj avatar denisdefreyne avatar floehopper avatar gabetax avatar greysteil avatar herwinw avatar junaruga avatar lazyatom avatar lukeredpath avatar mishina2228 avatar mrsimo avatar nicklewis avatar nitishr avatar simi avatar stevenyxu avatar techbelly avatar thewoolleyman avatar threedaymonk avatar tmm1 avatar wasabigeek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mocha's Issues

Examples for sequences should show expectations across multiple objects

require "test/unit"
require "mocha"

class FooTest < Test::Unit::TestCase
  def test_foo
    sequence = sequence(:task_order)
    task_one = mock("task_one")
    task_two = mock("task_two")

    task_one.expects(:execute).in_sequence(sequence)
    task_two.expects(:execute).in_sequence(sequence)

    task_one.execute
    task_two.execute
  end
end

Mock Clickatell API

Environment:
Rails: 3.0.10
Jruby: 1.6.5(1.9.2)
Clickatell gem: 0.8.2
Mocha: 0.10.0

Is there a way to mock the Clickatell::API.

What I Need:

Clickatell::API.authenticate('api_id', 'user', 'password') => <Clickatell::API:0x19a7f62 @auth_options={:session_id=>"session_id"}>

Thanks

Setting an expectation on the same object in multiple tests fails

If you set an expectation on the same class in two tests, it doesn't get set up properly the second time. This was broken in commit 3fbcad2. The issue appears to be that in the second test add_mock does not get called (because the mocha object is no longer cleaned up after the first test).

I've managed to write a failing acceptance test:

require File.expand_path('../acceptance_test_helper', __FILE__)
require 'mocha'

module TestExpectTwice
  def foo
    1
  end
end

class SequenceTest < Test::Unit::TestCase

  include AcceptanceTest

  def setup
    setup_acceptance_test
  end

  def teardown
    teardown_acceptance_test
  end

  def test_expect_should_work_twice_in_a_row
    test1 = run_as_test do
      TestExpectTwice.expects(:foo).never
    end
    assert_passed(test1)
    test2 = run_as_test do
      TestExpectTwice.expects(:foo)
    end
    assert_failed(test2)
  end
end

Class method stub being lost during testing

I have an expectation defined on a class in an RSpec before(:all) block, like so

before :all do
  Item.expects(:find).returns([])
end

If I call the find method, Item.find, directly after this, I get the correct response. If I let the tests run, which are capybara-webkit integration tests, the expectation never gets triggered.

The method is definitely getting called, as various debug statements I entered have shown, but the mocha expectation always fails.

The method lives in the index action, and is being called in a before(:each) block

before :each do
  @user = Factory(:user)
  visit '/users/sign_in'
  fill_in "user_email", :with => @user.email
  fill_in "user_password", :with => @user.password
  click_button 'Sign in'
  visit '/admin/items'
end

I've tried setting the expectation it various points in the test, such as in :all, :each, :suite hooks, and even just before visiting the url. In each case, I can also successfully call Item.find after setting the expectation and observe the correct response.

More information will probably be required for this, so please let me know what info would help.

Update README: say you need to use :require => "false" with Bundler

Hiya,

Thanks for writing the mocha gem! What a great tool. One thing that bit me was when I moved to using bundler - I didn't realise that I had to append :require => false to the gem declaration in the Gemfile, ie.

gem "mocha", "0.9.9", :require => false

It would be great if you could note it in the README, around the point where you say that you need to explicitly load Mocha after the test framework.

Thanks a mill,
Dec

cannot load such file -- mocha/mockery when expectation not met

I have a Sinatra app where I am testing the following assertion

def test_get_resized_image_with_proper_signature_should_return_image
  OpenSSL::HMAC.expects(:hexdigest).returns("zzz")
  get '/pic/2?width=123&sig=zzz'
  assert_equal 404, last_response.status
end

This fails with Mocha failing to load it's component

  1) Error:
test_get_resized_image_with_proper_signature_should_return_image(TestMappe):
LoadError: cannot load such file -- mocha/mockery
method require in dependencies.rb at line 239
method block in require in dependencies.rb at line 239
method block in load_dependency in dependencies.rb at line 225
method new_constants_in in dependencies.rb at line 596
method load_dependency in dependencies.rb at line 225
method require in dependencies.rb at line 239
method method_missing in mock.rb at line 166
method hexdigest in class_method.rb at line 46
method block in <class:Mappe> in app.rb at line 256
method call in base.rb at line 1212
method block in compile! in base.rb at line 1212
method [] in base.rb at line 772
method block (3 levels) in route! in base.rb at line 772
method route_eval in base.rb at line 788
method block (2 levels) in route! in base.rb at line 772
method block in process_route in base.rb at line 821
method catch in base.rb at line 819
method process_route in base.rb at line 819
method block in route! in base.rb at line 771
method each in base.rb at line 770
method route! in base.rb at line 770
method dispatch! in base.rb at line 886
method block in call! in base.rb at line 706
method block in invoke in base.rb at line 871
method catch in base.rb at line 871
method invoke in base.rb at line 871
method call! in base.rb at line 706
method call in base.rb at line 692
method call in static.rb at line 66
method call in reconnect.rb at line 9
method call in conditional_auth.rb at line 12
method call in conditional_auth.rb at line 12
method call in no_record.rb at line 7
method call in xss_header.rb at line 22
method call in base.rb at line 47
method call in base.rb at line 47
method call in path_traversal.rb at line 16
method call in json_csrf.rb at line 17
method call in base.rb at line 47
method call in xss_header.rb at line 22
method context in id.rb at line 205
method call in id.rb at line 200
method call in nulllogger.rb at line 9
method call in head.rb at line 9
method call in methodoverride.rb at line 21
method block in call in base.rb at line 1334
method synchronize in <internal:prelude> at line 10
method synchronize in base.rb at line 1401
method call in base.rb at line 1334
method request in mock_session.rb at line 30
method process_request in test.rb at line 219
method get in test.rb at line 57
method get in index_test.rb at line 18
method test_get_resized_image_with_proper_signature_should_return_image in index_test.rb at line 62
method run in version_230_to_262.rb at line 28
method run in testcase.rb at line 17

My Gemfile reads

group :test do
  gem "rack-test", :require => "rack/test"
  gem "minitest"
  gem "mocha", :git => 'git://github.com/floehopper/mocha.git', :require => false 
end

and I am running on ruby 1.9.3-p0

This references line 166 of mock.rb which reads

      require 'mocha/mockery'

and this problem might be intrinsic to new Rubies when doing a require inside a method_missing block. Once I move the require into the header of the file loading Mockery at once the problem dissapears.

How come .then doesn't work like an implicit sequence?

I always expect:

    object.expects(:method).returns(false).then.returns(true)

to work equivalently to:

    seq = sequence("name")
    object.expects(:method).returns(false).in_sequence(seq)
    object.expects(:method).returns(true).in_sequence(seq)

How come it doesn't? It always throws me.

-jon

Expectations are not respected when a method is stubbed out

If you stub a method on a class and then set an expectation on that method, the expectation is not actually respected.

Reproduction:

class Foo
  def self.bar
    puts 'hi'
  end
  def self.car
    puts 'bye'
  end
end

Foo.bar
# => hi

require 'mocha'

Foo.stubs(:bar => 'stub')
Foo.bar
# => "stub"

Foo.expects(:bar).never
Foo.bar
# => "stub"

Foo.expects(:car).never
Foo.car

# Mocha::ExpectationError: unexpected invocation: Foo.car()
# unsatisfied expectations:
# - expected never, invoked once: Foo.car(any_parameters)
# satisfied expectations:
# - expected never, not yet invoked: Foo.bar(any_parameters)
# - allowed any number of times, invoked twice: Foo.bar(any_parameters)

Unstubbing one method causes an ExpectationError if calling a non-unstubbed method

Reproduction:

class Foo
  def self.bar
    puts 'hi'
  end
  def self.car
    puts 'bye'
  end
end
>> Foo.stubs(:bar => 'bar', :car => 'car')
=> #<Mocha::Expectation:0x101780580 @invocation_count=0, @method_matcher=#<Mocha::MethodMatcher:0x101780508 @expected_method_name=:car>, @parameters_matcher=#<Mocha::ParametersMatcher:0x1017804b8 @matching_block=nil, @expected_parameters=[#<Mocha::ParameterMatchers::AnyParameters:0x101780440>]>, @return_values=#<Mocha::ReturnValues:0x10177ff90 @values=[#<Mocha::SingleReturnValue:0x10177ffe0 @value="car">]>, @side_effects=[], @yield_parameters=#<Mocha::YieldParameters:0x101780210 @parameter_groups=[]>, @mock=Foo, @backtrace=["/Library/Ruby/Gems/1.8/gems/mocha-0.10.0/lib/mocha/argument_iterator.rb:12:in `call'", "/Library/Ruby/Gems/1.8/gems/mocha-0.10.0/lib/mocha/argument_iterator.rb:12:in `each'", "/Library/Ruby/Gems/1.8/gems/mocha-0.10.0/lib/mocha/argument_iterator.rb:11:in `each'", "/Library/Ruby/Gems/1.8/gems/mocha-0.10.0/lib/mocha/object.rb:97:in `stubs'", "(irb):11:in `irb_binding'", "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/workspace.rb:52:in `irb_binding'", "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/workspace.rb:52"], @ordering_constraints=[], @cardinality=#<Mocha::Cardinality:0x1017800f8 @required=0, @maximum=Infinity>>
>> Foo.bar
=> "bar"
>> Foo.car
=> "car"
>> Foo.unstub(:bar)
=> [:bar]
>> Foo.car
Mocha::ExpectationError: unexpected invocation: Foo.car()
satisfied expectations:
- allowed any number of times, invoked once: Foo.car(any_parameters)
- allowed any number of times, invoked once: Foo.bar(any_parameters)

        from (irb):15

I would not have expected Foo.car to throw an exception here.

Verifying Expectation halfway through the test

Is there a way to check single Expectation before the end of a test?

Rspec-Mocks has following syntax

it "should increment the count" do
  expect { Counter.increment }.to change{Counter.count}.from(0).to(1)
end

and it got me thinking if it's possible to verify expectation and then replace it with another one (for example to test two functions in one test case).

6 Tests fail on Ruby 1.9.3

Hi,
6 tests fail for me on Ruby 1.9.3:

  1. Failure:
    test_should_stub_private_method_and_leave_it_unchanged_after_test(StubClassMethodDefinedOnModuleTest) [/home/bkabrda/rpmbuild/BUILDROOT/rubygem-mocha-0.10.0-1.fc16.x86_64/usr/share/gems/gems/mocha-0.10.0/test/acceptance/stub_class_method_defined_on_module_test.rb:66]:
    Snapshot has changed: {:added=>[#Class:#Class:0x0000000156b570#my_class_method (private)], :removed=>[]}

  2. Failure:
    test_should_stub_protected_method_and_leave_it_unchanged_after_test(StubClassMethodDefinedOnModuleTest) [/home/bkabrda/rpmbuild/BUILDROOT/rubygem-mocha-0.10.0-1.fc16.x86_64/usr/share/gems/gems/mocha-0.10.0/test/acceptance/stub_class_method_defined_on_module_test.rb:46]:
    Snapshot has changed: {:added=>[#Class:#Class:0x000000014fc4e0#my_class_method (protected)], :removed=>[]}

  3. Failure:
    test_should_stub_public_method_and_leave_it_unchanged_after_test(StubClassMethodDefinedOnModuleTest) [/home/bkabrda/rpmbuild/BUILDROOT/rubygem-mocha-0.10.0-1.fc16.x86_64/usr/share/gems/gems/mocha-0.10.0/test/acceptance/stub_class_method_defined_on_module_test.rb:26]:
    Snapshot has changed: {:added=>[#Class:#Class:0x00000000a89be8#my_class_method (public)], :removed=>[]}

  4. Failure:
    test_should_stub_private_method_and_leave_it_unchanged_after_test(StubClassMethodDefinedOnSuperclassTest) [/home/bkabrda/rpmbuild/BUILDROOT/rubygem-mocha-0.10.0-1.fc16.x86_64/usr/share/gems/gems/mocha-0.10.0/test/acceptance/stub_class_method_defined_on_superclass_test.rb:66]:
    Snapshot has changed: {:added=>[#Class:#Class:0x0000000153bd98#my_class_method (private)], :removed=>[]}

  5. Failure:
    test_should_stub_protected_method_and_leave_it_unchanged_after_test(StubClassMethodDefinedOnSuperclassTest) [/home/bkabrda/rpmbuild/BUILDROOT/rubygem-mocha-0.10.0-1.fc16.x86_64/usr/share/gems/gems/mocha-0.10.0/test/acceptance/stub_class_method_defined_on_superclass_test.rb:46]:
    Snapshot has changed: {:added=>[#Class:#Class:0x000000009ceb68#my_class_method (protected)], :removed=>[]}

  6. Failure:
    test_should_stub_public_method_and_leave_it_unchanged_after_test(StubClassMethodDefinedOnSuperclassTest) [/home/bkabrda/rpmbuild/BUILDROOT/rubygem-mocha-0.10.0-1.fc16.x86_64/usr/share/gems/gems/mocha-0.10.0/test/acceptance/stub_class_method_defined_on_superclass_test.rb:26]:
    Snapshot has changed: {:added=>[#Class:#Class:0x000000014fac08#my_class_method (public)], :removed=>[]}

mocha release 0.10.0
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-linux]

Thank you :)

Redefine a class constant

I would like to mock a class constant but it does not work:

require 'test/unit'
require 'mocha'

class A
  MY_CONST = 'a'
end

class MyTest < Test::Unit::TestCase
  def test_should_returns_b
    assert_equal( 'a', A::MY_CONST )
    A.stubs( :MY_CONST ).returns( 'b' )
    assert_equal( 'b', A::MY_CONST )
  end
end

Is there any way to do something like this?

Thanks.

f.

mocha_inspect on ActiveRecord classes is overly verbose

When an expectation is unsatisfied or there is an unexpected invocation, the output is overly verbose for Rails ActiveRecord classes. For example:

- allowed any number of times, not yet invoked: #<AnyInstance:Event(id: integer, user_id: integer, name: string, host: 
string, time: datetime, time_zone: string, state: string, options: text, last_viewed_stats_at: datetime, created_at: datetime, 
updated_at: datetime, removed: boolean, trash: boolean, reminder_sent: boolean, type: string, time_all_day: boolean, 
archived: boolean, stationery_template_id: integer, sent_at: datetime, subject: string, end_time: datetime, 
has_end_time: boolean, clone_of_id: integer, account_id: integer, email_route: string, postmark_id: integer, is_xtreme: 
boolean, public_key: string, is_shared: boolean, shared_at: datetime, template: boolean, from_package_id: integer, 
create_version: string, shared_short_link: string)>.update_text(any_parameters)

All I care about is #<AnyInstance:Event>, but Rails' inspect method outputs information about the model's attributes, making it difficult to see the problematic class and method at a glance. Would it be possible to make Mocha just call #to_s on the class rather than #inspect?

Provide block syntax for sequences

It should be possible to provide the following syntax for a simple sequence i.e. one that is not interleaved with another :-

in_sequence(:task_order) do
  task_one.should_receive(:execute)
  task_two.should_receive(:execute)
end

Any expectations within the block would be assigned to the sequence specified in the block.

See https://gist.github.com/1704783 for some relation discussions.

Mocha::API#mocha_teardown not called under MiniTest v2.4.0

$ MOCHA_OPTIONS=debug ruby -Itest ./test/unit//api_test.rb
Detected MiniTest version: 2.4.0
*** MiniTest integration has not been verified but patching anyway ***
Monkey patching MiniTest >= v2.0.1 <= v2.0.2
Loaded suite ./test/unit//api_test
Started

ApiEpisodeTest:
     PASS test_season_number (0.00s) 
     PASS test_banner_path (0.00s) 
     PASS test_should_extract_the_network_id (0.00s) 
     PASS test_name (0.00s) 
     PASS test_overview (0.00s) 
     PASS test_episode_number (0.00s) 
     PASS test_attributes_hash (0.00s) 

Finished in 0.005293 seconds.

7 tests, 8 assertions, 0 failures, 0 errors, 0 skips

$ bundle show | ack minitest
  * minitest (2.4.0)

I can assert this by modifying [Mocha::API#mocha_teardown|https://github.com/floehopper/mocha/blob/master/lib/mocha/api.rb#L159] with a debugger/raise/warn statement, and we simply don't get in there.

This manifests as bleeding test suites, with my expectations and assertions leaking between tests. Resulting in tests which pass when run alone.

Sequencing failure messages are unclear

Given this example:

require "test/unit"
require "mocha"

class FooTest < Test::Unit::TestCase
  def test_foo
    sequence = sequence(:task_order)
    task_one = mock("task_one")
    task_two = mock("task_two")

    task_one.expects(:execute).in_sequence(sequence)
    task_two.expects(:execute).in_sequence(sequence)

    task_two.execute
    task_one.execute
  end
end

The failure message is unclear:

  1) Failure:
test_foo(FooTest) [example_spec.rb:13]:
unexpected invocation: #<Mock:task_two>.execute()
unsatisfied expectations:
- expected exactly once, not yet invoked: #<Mock:task_one>.execute(any_parameters); in sequence :task_order
- expected exactly once, not yet invoked: #<Mock:task_two>.execute(any_parameters); in sequence :task_order

I'd propose something like this:

  1) Failure:
test_foo(FooTest) [example_spec.rb:13]:
invocation: #<Mock:task_two>.execute() received out of order

Warning: loading in progress, circular require considered harmful

On behalf of @kennyj :-

I'm a rails contributor.

When I executed rake test_postgresql in rails/active_record. I found
a warning in mocha.
I'm using ruby-1.9.3-p0.

/home/kennyj/.rvm/gems/ruby-1.9.3-p0/gems/mocha-0.10.4/lib/mocha/mock.rb:9: warning: loading in progress, circular require considered harmful - /home/kennyj/.rvm/gems/ruby-1.9.3-p0/gems/mocha-0.10.4/lib/mocha/mockery.rb

In mocha/mockery.rb
...
require 'mocha/mock' # the cause of problem ???
...

Should fail at_least_once

Why do these tests pass? It is taken from documentation.

require "mocha"

describe "test" do
  it "should pass" do
    object = mock()
    object.expects(:expected_method).at_least_once
    object.expected_method
    # => verify succeeds
  end

  it "should fail" do
    object = mock()
    object.expects(:expected_method).at_least_once
    # => verify fails
  end
end

rspec 2.5.1, mocha 0.9.12, ruby 1.9.2-p136

stubbed methods in one test method carry over to others

The stubbed save method within the second test causes the first test to fail. The first test passes when run on its own as does the last test.

This can also be seen by stubbing out a dummy method within one test and have the stubbed method available in other test methods.

test "create should save the product" do
  create_setup

  puts Product.new.foo  # prints out "bar" due to the stubbed method within the next test

  # this assertion fails due to the save method being stubbed in the next test
  assert_difference "Product.all.size", 1 do
    post :create, {:product => @params}, {:user_id => @admin.id}
  end
end

test "create should render the new page if an error occurs" do
  @product = Product.new
  @product.stubs(:save).returns(false)
  Product.stubs(:new).returns(@product)

  # the below method results in the same issue
  # Product.any_instance.stubs(:save).returns(false)

  Product.any_instance.stubs(:foo).returns("bar")

  create_setup
  post :create, {:product => @params}, {:user_id => @admin.id}
  assert_template :new
end

Stubbing in setup then expecting in a test creates less useful failure messages

It's convenient to stub methods in a setup and then have a separate expectation in a specific test. If you run this Gist you'll get the following output:

  1) Failure:
test_something(TestFooWithStubbingInSetup) [test.rb:21]:
not all expectations were satisfied
unsatisfied expectations:
- expected exactly once, not yet invoked: Bar.hello('zab')
satisfied expectations:
- allowed any number of times, already invoked once: Bar.hello(any_parameters)

  2) Failure:
test_something(TestFooWithoutStubbingInSetup)
    [test.rb:7:in `say_hello_to'
     test.rb:39:in `test_something']:
unexpected invocation: Bar.hello('baz')
unsatisfied expectations:
- expected exactly once, not yet invoked: Bar.hello('zab')

As you can see when I stub in the setup the output isn't all that useful, I get the unsatisfied expectation but also a satisfied expectation which swallows some useful information. Whereas if I don't stub in the setup I get both the unexpected invocation and the unsatisfied expectation which is everything I need to see what's actually going on.

So, when adding an expectation to an already stubbed method I feel it wouldn't it be better to remove the stub?

Ben

.expects doesn't fail if not called (Rails)

This test doesn't fail:

def test_expectation
  string = 'wadus string'
  string.expects( :downcase )
  assert true
end
  • Ruby: 1.8.7
  • Rails: 3.0.5
  • Mocha: 0.9.12

How to reproduce it:

git clone git://github.com/fguillen/MochaTest.git
cd MochaTest
bundle install
ruby -Itest test/unit/my_mocha_test.rb

Result:

Loaded suite test/unit/my_mocha_test
Started
.
Finished in 0.1353 seconds.

1 tests, 1 assertions, 0 failures, 0 errors

Any suggestion is welcome :/

Failing tests on 1.9.2-head

Running the Railties test suit of Rails gives the following error:

ActiveSupport::Testing::RemoteError: caught NameError: method run' not defined in Test::Unit::TestCase /home/rohit/.rvm/gems/ruby-1.9.2-head@bugmash/gems/mocha-0.9.8/lib/mocha/integration/test_unit.rb:17:inremove_method'

The full trace is in a pastie => http://pastie.org/pastes/1011960

The tests pass fine on 1.8.7.

I'm not entirely sure if this is a mocha issue but it might just be, so I thought I should create a ticket here.

More info:
ruby 1.9.2dev (2010-06-06 revision 28184)
mocha-0.9.8
Rails master

If you need any more info let me know, also if this is an obvious non mocha issue please close the ticket. :)

Stubbing methods with arguments returns a Errno::ENOENT: No such file or directory - getcwd error

Hi there.

It's rather hard to find any documentation on Mocha, so I'm afraid I'm totally at sea here. I have found a problem with stubbing methods that pass arguments. So for instance if I set up a class like this:

class Red
  def gets(*args)
    @input.gets(*args)
  end
  def puts(*args)
    @output.puts(*args)    
  end
  def initialize
    @input = $stdin
    @output = $stdout
  end
  private
  def first_method
    input = gets.chomp
    if input == "test"
      second_method(input)
    end
  end
  def second_method(value)
    puts value
    second_method(value)
  end
end

Yes it's contrived, but it's a simplification of the idea that you may have a method that you don't want called in the test.

So I might write a test such as:

setup do
  @project = Red.new
  @project.instance_variable_set(:@input, StringIO.new("test\n"))
  @project.stubs(:second_method)
end
should "pass input value to second_method" do
  @project.expects(:second_method).with("test").once
  @project.instance_eval {first_method}
end

Now I would expect this to pass. But instead I get this rather arcane error message:

Errno::ENOENT: No such file or directory - getcwd
/Users/i0n/.rvm/gems/ruby-1.9.2-head/gems/mocha-0.9.8/lib/mocha/backtrace_filter.rb:12:in expand_path' /Users/i0n/.rvm/gems/ruby-1.9.2-head/gems/mocha-0.9.8/lib/mocha/backtrace_filter.rb:12:inblock in filtered'
/Users/i0n/.rvm/gems/ruby-1.9.2-head/gems/mocha-0.9.8/lib/mocha/backtrace_filter.rb:12:in reject' /Users/i0n/.rvm/gems/ruby-1.9.2-head/gems/mocha-0.9.8/lib/mocha/backtrace_filter.rb:12:infiltered'
/Users/i0n/.rvm/gems/ruby-1.9.2-head/gems/mocha-0.9.8/lib/mocha/expectation_error.rb:10:in initialize' /Users/i0n/.rvm/gems/ruby-1.9.2-head/gems/mocha-0.9.8/lib/mocha/mockery.rb:53:innew'
/Users/i0n/.rvm/gems/ruby-1.9.2-head/gems/mocha-0.9.8/lib/mocha/mockery.rb:53:in verify' /Users/i0n/.rvm/gems/ruby-1.9.2-head/gems/mocha-0.9.8/lib/mocha/api.rb:156:inmocha_verify'
/Users/i0n/.rvm/gems/ruby-1.9.2-head/gems/mocha-0.9.8/lib/mocha/integration/mini_test/version_131_and_above.rb:27:in `run'

This means absolutely nothing to me, other than something deep in Mochas bowels has just gone clang. If I write the same sort of test without an argument passing to the second method I get no problem. Am I missing something?

Stubbing a method leaves behind a copy in the singleton class

Mocha is leaving behind a copy of stubbed methods in the singleton class of the object on which the method is stubbed. So a later stub to any_instance of the class isn't seen by the original object. The following rspec test case illustrates the problem:

require 'rspec'
require 'mocha'

RSpec.configure do |config|
  config.mock_with :mocha
end

class Foo 
  def bar; 10 end 
end

foo = Foo.new

describe "stubbing instances and any_instance" do
  it "stub bar" do
    foo.stubs(:bar).returns(50)
  end 

  it "bar should be equal to 20" do
    Foo.any_instance.stubs(:bar).returns(20)
    foo.bar.should == 20
  end 
end

A work-around is to add another "test" after the one that adds the stub, which will remove the method from the singleton class.

The cause appears to be at lib/mocha/class_method.rb:54, which restores the original method into the singleton class, regardless of whether that was where it came from in the first place. I'll work on a patch if I get the time.

Incidentally, the same line of code seems to be the perpetrator of #3.

Thanks.

An expectation on two classes that inherit from the same class fails.

mailer = mock()
mailer.stubs(:deliver!)
ServiceMailer.expects(:service_approved_notification).returns(mailer)
AdminMailer.expects(:service_approved_notification).returns(mailer)
@service.approve!
after_create do
  AdminMailer.new_service_notification(self).deliver!
  ServiceMailer.new_service_notification(self).deliver!
end
Mocha::ExpectationError: unexpected invocation: ServiceMailer.service_approved_notification(#<Service:0x8197910>)
unsatisfied expectations:
- expected exactly once, invoked twice: ServiceMailer.service_approved_notification(any_parameters)
- expected exactly once, not yet invoked: AdminMailer.service_approved_notification(any_parameters)

expectations changing visibility of methods

if I have a private method on object, and I set an expectation on it:

object.expects(:private_method)

the visibility of this method is changed to public.
If I have any code, that is checking for visibility of methods, ie:

if private_methods.include?(:private_method)

then obviously mocha will change the behavior of this code.
temporarily, I work around it with

object.expects(:private_method)
object.class_eval "private :private_method" # fix for mocha issues

which works - that means that mocha doesn't need to make it public, right?

.expects with Rails 3.1 will not fail if goes uncalled

I have a single test in a fresh rails 3.1 project which reads like this:

class AppTest < ActiveSupport::TestCase
test 'blah' do
App.expects(:new)
end
end

The test passes when I run it even though it should fail since App.new is never called.

I have my require 'mocha' in the test_helper.rb file and I even have the :require => false flag set in the Gemfile for mocha.

Am I doing something wrong or is this a bug?

Mocking Random unexpected behaviour

I am using Ruby 1.9.3-p0, Rails 3.2.1, RSpec 2.8.0, Mocha 0.10.3

describe 'weird behaviour' do
  describe 'mocha' do
    it 'sets some expectations and satisfies them' do
      random_generator = Random.new
      random_generator.expects(:rand).with(15..30)
      Random.expects(:new).returns(random_generator)
      Random.new.rand(15..30)
    end
  end
  describe 'mocha again' do
    it 'sets an expectation but an error is never raised if left uninvoked' do
      Random.expects(:new)
    end
  end
end

When I run the specs in the listed order they will both pass. When the order is switched, the test in the 'mocha again' block will fail as expected.

This doesn't seem to be the expected behaviour, or am I doing it all wrong?

4 test failures

On a fresh clone of Mocha, 4 of the tests fail.

1) Failure:
test_should_display_backtrace_indicating_line_number_where_attempt_to_stub_method_on_non_mock_object_was_made(StubbingErrorBacktraceTest) [/Users/Alex/Desktop/test/mocha/test/acceptance/stubbing_error_backtrace_test.rb:50]:
<file: /Users/Alex/Desktop/test/mocha/test/acceptance/stubbing_error_backtrace_test.rb; line: 47> expected but was
<file: /Users/Alex/Desktop/test/mocha/test/acceptance/stubbing_error_backtrace_test.rb; line: 46>.

2) Failure:
test_should_display_backtrace_indicating_line_number_where_attempt_to_stub_non_existent_method_was_made(StubbingErrorBacktraceTest) [/Users/Alex/Desktop/test/mocha/test/acceptance/stubbing_error_backtrace_test.rb:25]:
<file: /Users/Alex/Desktop/test/mocha/test/acceptance/stubbing_error_backtrace_test.rb; line: 22> expected but was
<file: /Users/Alex/Desktop/test/mocha/test/acceptance/stubbing_error_backtrace_test.rb; line: 21>.

3) Failure:
test_should_display_backtrace_indicating_line_number_where_attempt_to_stub_non_public_method_was_made(StubbingErrorBacktraceTest) [/Users/Alex/Desktop/test/mocha/test/acceptance/stubbing_error_backtrace_test.rb:39]:
<file: /Users/Alex/Desktop/test/mocha/test/acceptance/stubbing_error_backtrace_test.rb; line: 36> expected but was
<file: /Users/Alex/Desktop/test/mocha/test/acceptance/stubbing_error_backtrace_test.rb; line: 35>.

4) Failure:
test_should_display_backtrace_indicating_line_number_where_method_was_unnecessarily_stubbed(StubbingErrorBacktraceTest) [/Users/Alex/Desktop/test/mocha/test/acceptance/stubbing_error_backtrace_test.rb:61]:
<file: /Users/Alex/Desktop/test/mocha/test/acceptance/stubbing_error_backtrace_test.rb; line: 58> expected but was
<file: /Users/Alex/Desktop/test/mocha/test/acceptance/stubbing_error_backtrace_test.rb; line: 57>.

Strange error with Rails 2.3.x Bundler and Vanity

I want to report an issue wich i think stems from changed loadpaths with bundler.

We recently introduced Bundler in our big Rails project. Some time after that we wanted to remove the Vanity gem and suddenly a lot of Tests started to fail, because the mocks don't seem to get replayed in teardown.

Errors were like:

unexpected invocation: User.authenticate

We boiled it down in the Vanity gem to these 4 lines of code:

module ActionController
  class TestCase
  end
end

If those lines were not included/loaded before mocha gem then, mocha/integration.rb would not include the monkeypatches for TestUnit.

We now include the monkey-patches directly in the test-helper:

require 'mocha/integration/test_unit/ruby_version_186_and_above'
module Test
  module Unit
    class TestCase
      include Mocha::API

      alias_method :run_before_mocha, :run
      remove_method :run

      include Mocha::Integration::TestUnit::RubyVersion186AndAbove
    end
  end
end

Does someone have an idea of what might be going wrong and how to fix it?

undefined method `run' in >=0.10.1

# mocha_test.rb
require "test/unit"
require "mocha"

class MochaTest < Test::Unit::TestCase
  def test_mocha
    assert(true)
  end
end

Install version 0.10.2

$ rvm use 1.9.2@mocha_test
$ gem install mocha -v"0.10.2"

Error in test execution

$ ruby mocha_test.rb
Loaded suite mocha_test
Started
/Users/fguillen/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/minitest/unit.rb:641:in `block (2 levels) in run_test_suites': undefined method `run' for #<MochaTest:0x00000100bb4120> (NoMethodError)
[...]

Install version 0.10.0

$ gem uninstall mocha -v"0.10.2"
$ gem install mocha -v"0.10.0"

No error in test execution

$ ruby mocha_test.rb
Loaded suite mocha_test
Started
.
Finished in 0.000506 seconds.

1 tests, 1 assertions, 0 failures, 0 errors, 0 skips

Matching a hash containing an instance_of does not match

User.expects(:foo).with({:arg => instance_of(User) })

Will always fail. This is because the matcher will call == to which instance_of will not respond correctly.

I recommend the following Monkey Patch.

module Mocha
  module ParameterMatchers
    class InstanceOf
      def ==(parameter)
        parameter.instance_of?(@klass)
      end
    end

    class Equals
      def matches?(available_parameters)
        parameter = available_parameters.shift
        @value == parameter
      end
    end
  end
end

In the Equals class the @value instance var has been moved to the LHS.

ability to pass a block to returns

So I have a specific scenario where Im testing a method foo that calls a service method bar and returns the result IF it took less than a minute.

def foo
   begin = Time.now
   result = Bar.bar
   time = Time.now - begin
   time < 60 ? result : "FAILED"

end

Testing this is hard, but would be easier if returns took a block, since then I could do
Bar.stubs(:bar).returns do |b|
later = 1.minute.from_now
Time.stubs(:now).returns(later)
"SUCCESS"
end

Unstubbing

Once you stub a method, there is no clean way to unstub it ;( I had to have a monkey patch with aliasing to get around this. Any plans on changing this? Maybe a UnStub method

has_entry drops additional has key/values silently

has_entry supports testing parameters with a hash, like

expects(:thing).with(has_entry(:foo => :bar))

However, there may come a time where a developer adds another entry to this hash, and will want to update existing tests to reflect that

expects(:thing).with(has_entry(:foo => :bar, :qux => 1))

The problem is that has_entry will only respect one on the entries in the hash passed to it. The fix is to use has_entries

expects(:thing).with(has_entries(:foo => :bar, :qux => 1))

However, this is very easy to overlook.

I want to contribute a patch, however I am wondering if any of these are the right way to go:

  • Bring has_entries into has_entry, as I am having a hard time figuring out when one would want to drop the rest of the hash.
  • Change the method signature to not allow a hash as a parameter, so that this mistake cannot be made.
  • Throw an exception if the hash that was passed in has more than one entry.
  • Get over it, fix my own code and don't patch.

Thanks

mocha is incompatible with SimpleDelegator

I can't call stubs or expects on an instance of SimpleDelegator because that object will just pass the stubs or expects call on to the delegated object (confusingly called a "stub"). For example:

require 'mocha'
require 'delegate'

class Foo
  def foo; 'foo'; end
end

class Bar < SimpleDelegator
  def bar; 'bar'; end
  def foobar; foo + bar; end
end

foo = Foo.new
bar = Bar.new(foo)

# this actually ends up as "foo.stubs(:bar).returns('baz')"
bar.stubs(:bar).returns('baz')

# since foo.bar is never called, the stub is meaningless:
bar.foobar # => 'foobar'

mocha breaks minitest before/setup blocks

I haven't tracked down explicitly what happens, but when mocha's included in a project that uses minitest, before/setup blocks fail silently. I saw somewhere that mocha monkeypatches minitest - perhaps this is the issue. all I know is that ultimately run_setup_hooks fails to be called in the runner, and Bad Things happen. Took me 2 hours to track down what was causing it :-\

I'd be willing to send in a patch, if someone pointed me in the right direction - don't know mocha's codebase.

mocha integration breaks with minitest ~> 2.10.0

This is because of the string version comparison in lib/mocha/integration/mini_test.rb

Detected MiniTest version: 2.10.0
Monkey patching MiniTest >= v2.0.1 <= v2.2.2

There is Gem::Version for this kind of comparisons but I am not so sure if you can depend on it being present.

'with' modifier too much restricted

Hi,

I'm trying to do something like this:

object.stubs( :method ).with( one_value ).returns( mocking_value )

But not affecting to calls like this:

object.method( other_value )

What I'm trying is to mock a method return_value only if a precisely parameter_value is sent and not mocking the method if other value is sent.

Now I don't find the way because the above example fails on the object.method call with a value that is not the one on the mocking description.

So what I think is that the with modifier is too much constraint.

Is it possible to do what I'm trying to explain here? if it is not, I can try to added.

Regards

f.

Multiple 'with' configuration?

Is it possible something like this?

require 'rubygems'
require 'test/unit'
require 'mocha'

class A
  def self.wadus(value); end
end

class MyTest < Test::Unit::TestCase
  def test_should_mocking_two_calls_in_a_row
    A.expects(:wadus).with(1).then.with(2)
    A.wadus(1)
    A.wadus(2)
  end
end

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.