archan937/motion-bundler

Proposal: mock native library

Closed this issue · 4 comments

When I mock the dependency libraries of net/pop, socket.rb depends socket.so, I think socket.rb is reusable, just need to mock socket.so with socket.so.rb, but cannot do in version 0.1.6.

I create a branch mock-native at https://github.com/cpunion/motion-bundler-mock-debug/tree/mock-native, rake result:

$ rake
     Build ./build/iPhoneSimulator-6.1-Development
   Compile /Users/cpunion/test/motion/motion-bundler-mock-debug/.motion-bundler.rb
      Link ./build/iPhoneSimulator-6.1-Development/motion-bundler-mock-debug.app/motion-bundler-mock-debug
    Create ./build/iPhoneSimulator-6.1-Development/motion-bundler-mock-debug.dSYM
  Simulate ./build/iPhoneSimulator-6.1-Development/motion-bundler-mock-debug.app
   Warning Called `require "socket.so"`
           Add within setup block: app.require "socket.so"
(main)>    Warning Called `require "openssl.so"`
           Add within setup block: app.require "openssl.so"
   Warning Called `require "openssl/bn"`
           Add within setup block: app.require "openssl/bn"
   Warning Called `require "openssl/cipher"`
           Add within setup block: app.require "openssl/cipher"
   Warning Called `require "openssl/config"`
           Add within setup block: app.require "openssl/config"
   Warning Called `require "openssl/digest"`
           Add within setup block: app.require "openssl/digest"
   Warning Called `require "openssl/x509"`
           Add within setup block: app.require "openssl/x509"
   Warning Called `require "openssl/ssl"`
           Add within setup block: app.require "openssl/ssl"
2013-06-14 11:20:48.916 motion-bundler-mock-debug[76522:c07] pop.rb:544:in `block in do_start:': uninitialized constant Net::POP3::TCPSocket (NameError)
    from timeout.rb:65:in `timeout:'
    from pop.rb:543:in `do_start:'
    from pop.rb:536:in `start:'
    from app_delega:in `application:didFinishLaunchingWithOptions:'
2013-06-14 11:20:48.928 motion-bundler-mock-debug[76522:c07] *** Terminating app due to uncaught exception 'NameError', reason: 'pop.rb:544:in `block in do_start:': uninitialized constant Net::POP3::TCPSocket (NameError)
    from timeout.rb:65:in `timeout:'
    from pop.rb:543:in `do_start:'
    from pop.rb:536:in `start:'
    from app_delega:in `application:didFinishLaunchingWithOptions:'
'
*** First throw call stack:
(0x18ca012 0x23ae7e 0x13ee6d 0x2f22 0x2be5)
libc++abi.dylib: terminate called throwing an exception
((null))> rake aborted!
Command failed with status (1): [DYLD_FRAMEWORK_PATH="/Applications/Xcode.a...]
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/file_utils.rb:53:in `block in create_shell_runner'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/file_utils.rb:45:in `call'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/file_utils.rb:45:in `sh'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/file_utils_ext.rb:37:in `sh'
/Library/RubyMotion/lib/motion/project/template/ios.rb:109:in `block in <top (required)>'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/task.rb:246:in `call'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/task.rb:246:in `block in execute'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/task.rb:241:in `each'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/task.rb:241:in `execute'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/task.rb:184:in `block in invoke_with_call_chain'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/task.rb:177:in `invoke_with_call_chain'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/task.rb:205:in `block in invoke_prerequisites'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/task.rb:203:in `each'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/task.rb:203:in `invoke_prerequisites'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/task.rb:183:in `block in invoke_with_call_chain'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/task.rb:177:in `invoke_with_call_chain'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/task.rb:170:in `invoke'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/application.rb:143:in `invoke_task'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/application.rb:101:in `block (2 levels) in top_level'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/application.rb:101:in `each'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/application.rb:101:in `block in top_level'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/application.rb:110:in `run_with_threads'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/application.rb:95:in `top_level'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/application.rb:73:in `block in run'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/application.rb:160:in `standard_exception_handling'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0@global/gems/rake-10.0.4/lib/rake/application.rb:70:in `run'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `eval'
/Users/cpunion/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `<main>'
Tasks: TOP => default => simulator
(See full trace by running task with --trace)

I did some tracing, the socket.rb be loaded before the rake tasks will be executed, so the Tracer cannot trace into require 'socket.rb' to capture require 'socket.so'.

I tried to modify net/pop.rb to test, replace require 'md5' with require 'md5.so', then mock it success with mocks/digest/md5.so.rb.

Is this testing useful?

I commit a smallest testing at https://github.com/cpunion/motion-bundler-mock-debug/tree/mock-native, it works! but cannot work with socket.rb.

Fixed this issue since commit 5f4675a. The sample application demonstrates how to tackle this case. Thanks for issuing!

0.1.7 is incomplete solution for this issue. I commit a new test case at https://github.com/cpunion/motion-bundler-mock-debug/blob/mock-socket/ , the dependencies in .motion-bundler.rb is:

  FILES_DEPENDENCIES = {
    "/Users/cpunion/test/motion/motion-bundler-mock-debug/app/app_delegate.rb" => [
      "/Users/cpunion/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/net/pop.rb"
    ],
    "/Users/cpunion/.rvm/gems/ruby-2.0.0-p0/gems/motion-bundler-0.1.7/lib/motion-bundler/simulator/boot.rb" => [
      "/Users/cpunion/.rvm/gems/ruby-2.0.0-p0/gems/motion-bundler-0.1.7/lib/motion-bundler/simulator/core_ext.rb",
      "/Users/cpunion/.rvm/gems/ruby-2.0.0-p0/gems/motion-bundler-0.1.7/lib/motion-bundler/simulator/console.rb"
    ],
    "/Users/cpunion/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/net/pop.rb" => [
      "/Users/cpunion/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/net/protocol.rb",
      "/Users/cpunion/test/motion/motion-bundler-mock-debug/mocks/digest/md5.rb"
    ]
  }

It missing some dependencies:

"net/protocol.rb" => ["socket.rb", "timeout.rb", "openssl.rb"],
"socket.rb" => "socket.so",
"openssl.rb" => ["openssl.so", "openssl/bn.rb", ...]

In sample_app/app/controllers/app_controller.rb, when I remove require 'socket', mocks/socket.so.rb cannot compile into app, it indirectly required by net/pop.