Different results between command-line and test execution

I have a several classes that need to be extended to have a representation in JSON. Following the instruction of the JSON docs, and recognizing that I need the same code in many places, I created a pair of modules, one to be included in and one to extend the the class in question. So,

class Game

  require 'assets/json_serializable'

  require 'assets/json_deserializable'

  include JSONSerializable

  extend JSONDeserializable


  attr_accessor :label


  def initialize(label)

    @label = label

  end


  def json_serialization_list

    [label]

  end

end
and
module JSONSerializable
  require 'json/add/core'
  def to_json(*a)
    {
      json_class: self.class.name,
      data: json_serialization_list
    }.to_json(*a)
  end
end

and
module JSONDeserializable
  def json_create(a)
    new(*a['data'])
  end
end


In irb, using the same (only) ruby on the machine:
1.9.3p385 :002 > require 'app/models/game'
=> true
1.9.3p385 :003 > g = Game.new('7')
=> G7[OID:14415960]:  
1.9.3p385 :004 > g2 = JSON.parse JSON.generate g
=> G7[OID:14336280]:  
1.9.3p385 :005 > g2.eql? g
=> true

whereas in the test:
describe Game do
  before { @game = Game.new('7') }
  subject { @game }
  it "should have a JSON representation" do
    c2 = JSON.parse JSON.generate @game
    c2.should eql @game
  end
end

gives:
expected: G7[OID:32512660]:
     got: {"json_class"=>"Game", "data"=>["7"]}


(compared using eql?)


Diff:
@@ -1,2 +1,3 @@
-G7[OID:32512660]:
+"data" => ["7"],
+"json_class" => "Game"


What am I doing wrong/what should I examine that causes the json representation in the RubyMine to be different in the test than at the command line (in the irb environment)? I've had problems with what I would call a kind of caching behavior, where the results of tests change if I exit RubyMine and restart it. That was not the case here.
8 comments

I should add that this is RM 4.5.4.

Also, the identical result is obtained (works at the irb console) whether executed inside or outside of RubyMine (here, from inside):

?> $LOAD_PATH << '~/Projects/MyApp' << '~/Projects/MyApp/lib'

$LOAD_PATH << '~/Projects/MyApp' << '~/Projects/MyApp/lib'
=> ["~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/site_ruby/1.9.1", "~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/site_ruby/1.9.1/x86_64-linux", "~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/site_ruby", "~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/vendor_ruby/1.9.1", "~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/vendor_ruby/1.9.1/x86_64-linux", "~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/vendor_ruby", "~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1", "~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/x86_64-linux", "~/Projects/MyApp", "~/Projects/MyApp/lib"] (editted for clarity)



?>                          require 'app/models/game'
                         require 'app/models/game'
=> true

?> g = Game.new('7')
=> G7[OID:16883820]:

?>  g2 = JSON.parse JSON.generate g
=> G7[OID:16866140]:

?> g2.eql? g
=> true

Message was edited by: Derrell Durrett
0

Hi Derrell,

I think that this is not about RM but about test framework you are using (it is RSpec or something else?)
I'd expect that the problem is in should or eq matcher.  I'd suggest to debug the test and see what is going wrong.

Regards, Oleg.     

0

I'm trying to explore that possibilty, but since I've seen such behavior before (though, in the past, the difference has cleared up if I restart RubyMine), I thought I'd ask.

0

Also, as the behavior is clearly distinguished by the fact that JSON.parse returns different values in the irb environment versus the rspec environment, it can't be the rspec matchers themselves.

0

In a further attempt to understand the differences, I've wrapped the class so as to execute it, and I get more interesting results. To recap the earlier result, at the irb command line, both inside

and outside of RubyMine, I get a result that would be considered expected:

a = Thing.new

b = JSON.parse JSON.generate a

a.eql? b # ==> true
If I execute the same code in RubyMine (it is, modulo some quote marks, the same command line), I get:

a = Thing.new
b = JSON.parse JSON.generate a
a.eql? b # ==> true


So, something is different about the RubyMine environment.

This is the class:

class Thing
  require 'assets/json_serializable'
  require 'assets/json_deserializable'
  include JSONSerializable
  extend JSONDeserializable
  attr_accessor :foo
  def initialize(f)
    @foo = f
  end
  def json_serialization_list
    [foo]
  end


  def eql?(other)
    other.is_a?(self.class) and foo.eql? other.foo
  end


  alias == eql?


  a = Thing.new("bar")
  b = JSON.parse JSON.generate a
  puts a.eql? b
end



This is assets/json_serializable:

module JSONSerializable

  require 'json/add/core'


  # including this module requires defining

  # json_serialization_list, which should be the list

  # of attributes passed to the constructor

  def to_json(*a)

    {

      json_class: self.class.name,

      data: json_serialization_list

    }.to_json(*a)

  end

end

This is assets/json_deserializable:


module JSONDeserializable

  def json_create(a)

    new(*a['data'])

  end

end

This is the command line (from in RubyMine-- the one for the command line has '' wrapping the argument to -e:
~/.rvm/rubies/ruby-1.9.3-p385/bin/ruby -I~/Projects/MyApp/ -I~/Projects/MyApp/lib -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) ~/Projects/MyApp/app/models/thing.rb

When I execute in RubyMine, the output of the 'puts' is false, and when at a terminal command line, it is true.

What could be different about the loaded modules (and how would I tell?) between the RubyMine environment, and the command line environment?

If I add a 'puts $LOAD_PATH' to the output, this is what I get:
(Inside RubyMine)

~/.rvm/gems/ruby-1.9.3-p385@global/gems/uglifier-1.3.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/sqlite3-1.3.7/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/shoulda-3.3.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/shoulda-matchers-1.4.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/shoulda-context-1.0.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/sass-rails-3.2.6/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rspec-rails-2.12.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rgl-0.4.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/stream-0.5/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rb-inotify-0.8.8/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rails-3.2.11/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/libnotify-0.5.9/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/jquery-rails-2.2.1/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/guard-spork-1.4.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/spork-0.9.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/guard-rspec-2.4.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rspec-2.12.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rspec-mocks-2.12.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rspec-expectations-2.12.1/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rspec-core-2.12.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/guard-1.6.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/terminal-table-1.4.5/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/pry-0.9.12/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/slop-3.4.3/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/method_source-0.8.1/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/lumberjack-1.0.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/listen-0.7.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/diff-lcs-1.1.3/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/coffee-rails-3.2.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/railties-3.2.11/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/thor-0.17.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rdoc-3.12.1/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/json-1.7.7/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rack-ssl-1.3.3/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/coffee-script-2.2.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/execjs-1.4.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/coffee-script-source-1.4.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/coderay-1.0.8/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/capybara-2.0.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/xpath-1.0.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/selenium-webdriver-2.29.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/websocket-1.0.7/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rubyzip-0.9.9/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/childprocess-0.3.8/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/ffi-1.4.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/ffi-1.4.0/ext/ffi_c
~/.rvm/gems/ruby-1.9.3-p385@global/gems/nokogiri-1.5.6/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/bourne-1.1.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/mocha-0.10.5/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/metaclass-0.0.1/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/bootstrap-sass-2.3.0.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/sass-3.2.5/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/bcrypt-ruby-3.0.1/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/activeresource-3.2.11/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/activerecord-3.2.11/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/tzinfo-0.3.35/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/arel-3.0.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/active_attr-0.7.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/actionmailer-3.2.11/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/mail-2.4.4/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/treetop-1.4.12/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/polyglot-0.3.3/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/mime-types-1.21/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/actionpack-3.2.11/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/sprockets-2.2.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/tilt-1.3.3/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/hike-1.2.1/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rack-test-0.6.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rack-cache-1.2/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rack-1.4.5/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/journey-1.0.4/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/erubis-2.7.0/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/activemodel-3.2.11/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/builder-3.0.4/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/activesupport-3.2.11/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/multi_json-1.6.1/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/i18n-0.6.1/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/rake-10.0.3/lib
~/Projects/MyApp
~/Projects/MyApp/lib
~/.rvm/gems/ruby-1.9.3-p385@global/gems/bundler-1.3.0.pre.8/lib
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/site_ruby/1.9.1
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/site_ruby/1.9.1/x86_64-linux
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/site_ruby
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/vendor_ruby/1.9.1
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/vendor_ruby/1.9.1/x86_64-linux
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/vendor_ruby
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/x86_64-linux

(At the terminal command line)
~/Projects/MyApp
~/Projects/MyApp/lib
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/site_ruby/1.9.1
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/site_ruby/1.9.1/x86_64-linux
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/site_ruby
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/vendor_ruby/1.9.1
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/vendor_ruby/1.9.1/x86_64-linux
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/vendor_ruby
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1
~/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/x86_64-linux


Any ideas?

Thanks in advance.
0

I've finally understood the source of my problem: different behavior of the to_json method between multi_json and json.

I can't yet figure out how to solve the resulting problem, but I at least understand why the difference in behavior between irb and execution in the context of the app.     

0

Are you using Gemfile and bundler for the app?  Usually them provide better control on environment.

Regards, Oleg.

0

I am using Gemfile and bundler.

As it turns out, once I knew enough to ask the right question, I discovered this is a well-known problem: http://stackoverflow.com/questions/683989/how-do-you-deal-with-the-conflict-between-activesupportjson-and-the-json-gem

So, I'm struggling to find the right magic to override the behavior of the JSON in ActiveSupport. But at least I know the problem isn't mysterious. Just annoying!     

0

Please sign in to leave a comment.