require 'spec_helper' describe Volt::EJSON, '.parse' do subject { Volt::EJSON } let(:epoch) { 135820576553 } let(:ruby_epoch) { epoch / 1000.0 } context 'safe escaping' do it 'does not parse date objects with invalid values' do parsed = subject.parse '{"a" : {"$escape" : {"$date" : "something"}}}' expect(parsed).to eq('a' => { '$date' => 'something' }) end it 'only escapes one level down' do parsed = subject.parse %({"$escape": {"$date": {"$date": #{epoch}}}}) expect(parsed).to eq('$date' => Time.at(ruby_epoch)) end end context 'parsing EJSON fields' do context 'date' do it 'is not parsed when given a bad value' do expect(subject.parse '{"a": {"$date" : "something"}}'). to eq('a' => { '$date' => 'something' }) end it 'parses proper $date EJSON fields' do parsed = subject.parse '{"a" : {"$date": 135820576553}}' expect(parsed['a']).to eq Time.at(ruby_epoch) end it 'parses nested EJSON date fields' do parsed = subject.parse '{"a" : {"b" : {"$date": 135820576553}}}' expect(parsed['a']['b']).to eq Time.at(ruby_epoch) end it 'parses nested $dates within $escapes' do parsed = subject.parse( '{"a" : {"$escape": {"$date" : {"date" : {"$date": 135820576553}}}}}' ) expect(parsed['a']['$date']['date']).to eq Time.at(ruby_epoch) end it 'parses multiple EJSON date fields' do ejson = begin %({"when":{"$date":#{epoch}},"then":{"$date":#{epoch}}}) end expect(subject.parse ejson).to eq( "when" => Time.at(ruby_epoch), "then" => Time.at(ruby_epoch) ) end end end end describe Volt::EJSON, '.stringify' do subject { Volt::EJSON } context 'marshaling dates' do let(:now) { Time.now } let(:now_js_epoch) { now.to_i * 1_000 } it 'does nothing with regular hashes' do stringified = subject.stringify plain: 'jane' expect(stringified).to eq '{"plain":"jane"}' end it 'marshals when given a date' do stringified = subject.stringify when: now expect(stringified).to eq %({"when":{"$date":#{now_js_epoch}}}) end it 'marshals nested dates' do stringified = subject.stringify how: { when: now } expect(stringified).to eq %({"how":{"when":{"$date":#{now_js_epoch}}}}) end it 'marshals multiple dates' do stringified = subject.stringify when: now, then: now expect(stringified.gsub(' ', '')).to eq( %({"when":{"$date":#{now_js_epoch}},"then":{"$date":#{now_js_epoch}}}) ) end it 'escapes reserved key when type is incorrect' do stringified = subject.stringify '$date' => 'something' expect(stringified).to eq '{"$escape":{"$date":"something"}}' end end end