File: serialization_spec.rb

package info (click to toggle)
ruby-spy 1.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 360 kB
  • sloc: ruby: 3,101; makefile: 2
file content (116 lines) | stat: -rw-r--r-- 3,323 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
require 'spec_helper'
require 'yaml'
require 'psych'
require 'syck'

module Spy
  describe "serialization" do

    class SerializableObject < Struct.new(:foo, :bar); end

    class SerializableMockProxy
      attr_reader :mock_proxy

      def initialize(mock_proxy)
        @mock_proxy = mock_proxy
      end

      def ==(other)
        other.class == self.class && other.mock_proxy == mock_proxy
      end
    end

    def self.with_yaml_loaded(&block)
      context 'with YAML loaded' do
        module_eval(&block)
      end
    end

    def self.without_yaml_loaded(&block)
      context 'without YAML loaded' do
        before do
          # We can't really unload yaml, but we can fake it here...
          @yaml = YAML
          Object.send(:remove_const, "YAML")
          Struct.class_eval do
            alias __old_to_yaml to_yaml
            undef to_yaml
          end
        end

        module_eval(&block)

        after do
          Struct.class_eval do
            alias to_yaml __old_to_yaml
            undef __old_to_yaml
          end

          Object.send(:const_set, "YAML", @yaml)
        end
      end
    end

    let(:serializable_object) { SerializableObject.new(7, "something") }

    def set_spy
      Spy::Subroutine.new(serializable_object, :bazz).hook(force: true).and_return(5)
    end

    shared_examples_for 'normal YAML serialization' do
      it 'serializes to yaml the same with and without stubbing, using #to_yaml' do
        set_spy
        expect { Spy.get(serializable_object, :bazz) }.to_not change { serializable_object.to_yaml }
      end

      it 'serializes to yaml the same with and without stubbing, using YAML.dump' do
        set_spy
        expect { Spy.get(serializable_object, :bazz) }.to_not change { ::YAML.dump(serializable_object) }
      end
    end

    with_yaml_loaded do
      compiled_with_psych = begin
                              require 'psych'
                              true
                            rescue LoadError
                              false
                            end

      if compiled_with_psych
        context 'using Syck as the YAML engine' do
          before(:each) { ::YAML::ENGINE.yamler = 'syck' }
          it_behaves_like 'normal YAML serialization'
        end

        context 'using Psych as the YAML engine' do
          before(:each) { ::YAML::ENGINE.yamler = 'psych' }
          it_behaves_like 'normal YAML serialization'
        end
      else
        it_behaves_like 'normal YAML serialization'
      end
    end

    without_yaml_loaded do
      it 'does not add #to_yaml to the stubbed object' do
        expect(serializable_object).not_to respond_to(:to_yaml)
        set_spy
        expect(serializable_object).not_to respond_to(:to_yaml)
      end
    end

    it 'marshals the same with and without stubbing' do
      expect { Spy.get(serializable_object, :bazz) }.to_not change { Marshal.dump(serializable_object) }
    end

    describe "an object that has its own mock_proxy instance variable" do
      let(:serializable_object) { SerializableMockProxy.new(:my_mock_proxy) }

      it 'does not interfere with its marshalling' do
        marshalled_copy = Marshal.load(Marshal.dump(serializable_object))
        expect(marshalled_copy).to eq serializable_object
      end
    end
  end
end