summaryrefslogtreecommitdiff
path: root/test/test_singleton.rb
blob: b3c48bb5f5dbc7c1049f5056e4704c9d3e66cbd8 (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
# frozen_string_literal: false
require 'test/unit'
require 'singleton'

class TestSingleton < Test::Unit::TestCase
  class SingletonTest
    include Singleton
  end

  def test_marshal
    o1 = SingletonTest.instance
    m = Marshal.dump(o1)
    o2 = Marshal.load(m)
    assert_same(o1, o2)
  end

  def test_instance_never_changes
    a = SingletonTest.instance
    b = SingletonTest.instance
    assert_same a, b
  end

  def test_initialize_raises_exception
    assert_raise NoMethodError do
      SingletonTest.new
    end
  end

  def test_allocate_raises_exception
    assert_raise NoMethodError do
      SingletonTest.allocate
    end
  end

  def test_clone_raises_exception
    exception = assert_raise TypeError do
      SingletonTest.instance.clone
    end

    expected = "can't clone instance of singleton TestSingleton::SingletonTest"

    assert_equal expected, exception.message
  end

  def test_dup_raises_exception
    exception = assert_raise TypeError do
      SingletonTest.instance.dup
    end

    expected = "can't dup instance of singleton TestSingleton::SingletonTest"

    assert_equal expected, exception.message
  end

  def test_include_in_module_raises_exception
    mod = Module.new

    exception = assert_raise TypeError do
      mod.class_eval do
        include Singleton
      end
    end

    expected = "Inclusion of the OO-Singleton module in module #{mod}"

    assert_equal expected, exception.message
  end

  def test_extending_singleton_raises_exception
    assert_raise NoMethodError do
      'foo'.extend Singleton
    end
  end

  def test_inheritance_works_with_overridden_inherited_method
    super_super_called = false

    outer = Class.new do
      define_singleton_method :inherited do |sub|
        super_super_called = true
      end
    end

    inner = Class.new(outer) do
      include Singleton
    end

    tester = Class.new(inner)

    assert super_super_called

    a = tester.instance
    b = tester.instance
    assert_same a, b
  end

  def test_class_level_cloning_preserves_singleton_behavior
    klass = SingletonTest.clone

    a = klass.instance
    b = klass.instance
    assert_same a, b
  end
end