File: dereferenceable_shared.rb

package info (click to toggle)
ruby-concurrent 1.1.6%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 30,284 kB
  • sloc: ruby: 30,875; java: 6,117; ansic: 288; makefile: 9; sh: 6
file content (138 lines) | stat: -rw-r--r-- 4,309 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
RSpec.shared_examples :dereferenceable do

  it 'defaults :dup_on_deref to false' do
    value = 'value'
    expect(value).not_to receive(:dup).with(any_args)

    subject = dereferenceable_subject(value)
    subject.value

    subject = dereferenceable_subject(value, dup_on_deref: false)
    subject.value

    subject = dereferenceable_subject(value, dup: false)
    subject.value
  end

  it 'calls #dup when the :dup_on_deref option is true' do
    value = 'value'

    subject = dereferenceable_subject(value, dup_on_deref: true)
    expect(subject.value.object_id).not_to eq value.object_id

    subject = dereferenceable_subject(value, dup: true)
    expect(subject.value.object_id).not_to eq value.object_id
  end

  it 'defaults :freeze_on_deref to false' do
    value = 'value'
    expect(value).not_to receive(:freeze).with(any_args)

    subject = dereferenceable_subject(value)
    subject.value

    subject = dereferenceable_subject(value, freeze_on_deref: false)
    subject.value

    subject = dereferenceable_subject(value, freeze: false)
    subject.value
  end

  it 'calls #freeze when the :freeze_on_deref option is true' do
    value = 'value'

    subject = dereferenceable_subject(value, freeze_on_deref: true)
    expect(subject.value).to be_frozen

    subject = dereferenceable_subject(value, freeze: true)
    expect(subject.value).to be_frozen
  end

  it 'defaults :copy_on_deref to nil' do
    value = 'value'

    subject = dereferenceable_subject(value)
    expect(subject.value.object_id).to eq(value.object_id)

    subject = dereferenceable_subject(value, copy_on_deref: nil)
    expect(subject.value.object_id).to eq(value.object_id)

    subject = dereferenceable_subject(value, copy: nil)
    expect(subject.value.object_id).to eq(value.object_id)
  end

  it 'calls the block when the :copy_on_deref option is passed a proc' do
    value = 'value'
    copy = proc{|val| 'copy' }

    subject = dereferenceable_subject(value, copy_on_deref: copy)
    expect(subject.value.object_id).not_to eq(value.object_id)

    subject = dereferenceable_subject(value, copy: copy)
    expect(subject.value.object_id).not_to eq(value.object_id)
  end

  it 'calls the :copy block first followed by #dup followed by #freeze' do
    value = 'value'
    copied = 'copied'
    dup = 'dup'
    frozen = 'frozen'
    copy = proc{|val| copied }

    expect(copied).to receive(:dup).at_least(:once).with(no_args).and_return(dup)
    expect(dup).to receive(:freeze).at_least(:once).with(no_args).and_return(frozen)

    subject = dereferenceable_subject(value, dup_on_deref: true, freeze_on_deref: true, copy_on_deref: copy)
    expect(subject.value).to eq frozen
  end

  it 'does not call #dup when #dup_on_deref is set and the value is nil' do
    allow_message_expectations_on_nil
    result = nil
    expect(result).not_to receive(:dup).with(any_args)
    subject = dereferenceable_subject(result, dup_on_deref: true)
    subject.value
  end

  it 'does not call #freeze when #freeze_on_deref is set and the value is nil' do
    allow_message_expectations_on_nil
    result = nil
    expect(result).not_to receive(:freeze).with(any_args)
    subject = dereferenceable_subject(result, freeze_on_deref: true)
    subject.value
  end

  it 'does not call the #copy_on_deref block when the value is nil' do
    copier = proc { 42 }
    subject = dereferenceable_subject(nil, copy_on_deref: copier)
    expect(subject.value).to be_nil
  end

  it 'supports dereference flags with observers' do

    if dereferenceable_subject(0).respond_to?(:add_observer)

      latch = Concurrent::CountDownLatch.new
      observer = Class.new do
        def initialize(latch)
          @latch = latch
        end
        def update(*args)
          @latch.count_down
        end
      end.new(latch)

      result = 'result'
      copier = proc { result }
      expect(result).to receive(:dup).at_least(:once).and_return(result)
      expect(result).to receive(:freeze).at_least(:once).and_return(result)
      expect(copier).to receive(:call).at_least(:once).and_return(result)

      subject = dereferenceable_observable(dup_on_deref: true, freeze_on_deref: true, copy_on_deref: copier)

      subject.add_observer(observer)
      execute_dereferenceable(subject)
      latch.wait(1)
    end
  end
end