summaryrefslogtreecommitdiff
path: root/test/fiber/test_storage.rb
blob: 3726decbdb5a3a8fb42c9b5e030d67b97ec71513 (plain)
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
# frozen_string_literal: true
require 'test/unit'

class TestFiberStorage < Test::Unit::TestCase
  def test_storage
    Fiber.new do
      Fiber[:x] = 10
      assert_kind_of Hash, Fiber.current.storage
      assert_predicate Fiber.current.storage, :any?
    end.resume
  end

  def test_storage_inherited
    Fiber.new do
      Fiber[:foo] = :bar

      Fiber.new do
        assert_equal :bar, Fiber[:foo]
        Fiber[:bar] = :baz
      end.resume

      assert_nil Fiber[:bar]
    end.resume
  end

  def test_variable_assignment
    Fiber.new do
      Fiber[:foo] = :bar
      assert_equal :bar, Fiber[:foo]
    end.resume
  end

  def test_storage_assignment
    old, Warning[:experimental] = Warning[:experimental], false

    Fiber.new do
      Fiber.current.storage = {foo: :bar}
      assert_equal :bar, Fiber[:foo]
    end.resume
  ensure
    Warning[:experimental] = old
  end

  def test_storage_only_allow_access_from_same_fiber
    old, Warning[:experimental] = Warning[:experimental], false

    f = Fiber.new do
      Fiber[:a] = 1
    end
    assert_raise(ArgumentError) { f.storage }
    assert_raise(ArgumentError) { f.storage = {} }
  ensure
    Warning[:experimental] = old
  end

  def test_inherited_storage
    Fiber.new(storage: {foo: :bar}) do
      f = Fiber.new do
        assert_equal :bar, Fiber[:foo]
      end
      f.resume
    end.resume
  end

  def test_enumerator_inherited_storage
    Fiber.new do
      Fiber[:item] = "Hello World"

      enumerator = Enumerator.new do |out|
        out << Fiber.current
        out << Fiber[:item]
      end

      # The fiber within the enumerator is not equal to the current...
      assert_not_equal Fiber.current, enumerator.next

      # But it inherited the storage from the current fiber:
      assert_equal "Hello World", enumerator.next
    end.resume
  end

  def test_thread_inherited_storage
    Fiber.new do
      Fiber[:x] = 10

      x = Thread.new do
        Fiber[:y] = 20
        Fiber[:x]
      end.value

      assert_equal 10, x
      assert_equal nil, Fiber[:y]
    end.resume
  end

  def test_enumerator_count
    Fiber.new do
      Fiber[:count] = 0

      enumerator = Enumerator.new do |y|
        Fiber[:count] += 1
        y << Fiber[:count]
      end

      assert_equal 1, enumerator.next
      assert_equal 0, Fiber[:count]
    end.resume
  end

  def test_storage_assignment_type_error
    assert_raise(TypeError) do
      Fiber.new(storage: {Object.new => "bar"}) {}
    end
  end
end