File: weak_instance_cache_spec.rb

package info (click to toggle)
ruby-roo 3.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 8,216 kB
  • sloc: ruby: 6,529; xml: 88; makefile: 6
file content (92 lines) | stat: -rw-r--r-- 2,375 bytes parent folder | download | duplicates (5)
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
require 'spec_helper'

if RUBY_PLATFORM == "java"
  require 'java'
  java_import 'java.lang.System'
end

describe Roo::Helpers::WeakInstanceCache do
  let(:klass) do
    Class.new do
      include Roo::Helpers::WeakInstanceCache

      def memoized_data
        instance_cache(:@memoized_data) do
          "Some Costly Operation #{rand(1000)}" * 1_000
        end
      end
    end
  end

  subject do
    klass.new
  end

  it 'should be lazy' do
    expect(subject.instance_variables).to_not include(:@memoized_data)
    data = subject.memoized_data
    expect(subject.instance_variables).to include(:@memoized_data)
  end


  it 'should be memoized' do
    data = subject.memoized_data
    expect(subject.memoized_data).to equal(data)
  end

  it 'should recalculate after GC' do
    expect(subject.instance_variables).to_not include(:@memoized_data)
    GC.disable
    subject.memoized_data && nil
    expect(subject.instance_variables).to include(:@memoized_data)

    force_gc
    expect(subject.instance_variables).to_not include(:@memoized_data)
    GC.disable
    subject.memoized_data && nil
    expect(subject.instance_variables).to include(:@memoized_data)
  end

  it 'must remove instance variable' do
    expect(subject.instance_variables).to_not include(:@memoized_data)
    GC.disable
    subject.memoized_data && nil
    expect(subject.instance_variables).to include(:@memoized_data)

    force_gc
    expect(subject.instance_variables).to_not include(:@memoized_data)
  end

  context '#inspect must not raise' do
    it 'before calculation' do
      expect{subject.inspect}.to_not raise_error
    end
    it 'after calculation' do
      GC.disable
      subject.memoized_data && nil
      expect{subject.inspect}.to_not raise_error
      expect(subject.inspect).to include("Some Costly Operation")
      force_gc
    end
    it 'after GC' do
      subject.memoized_data && nil
      force_gc
      expect(subject.instance_variables).to_not include(:@memoized_data)
      expect{subject.inspect}.to_not raise_error
      expect(subject.inspect).to_not include("Some Costly Operation")
    end
  end

  if RUBY_PLATFORM == "java"
    def force_gc
      System.gc
      sleep(0.1)
    end
  else
    def force_gc
      GC.start(full_mark: true, immediate_sweep: true)
      sleep(0.1)
      GC.start(full_mark: true, immediate_sweep: true)
    end
  end
end