aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/test/configurable_test.rb
blob: 1cf40261dc5105be6ed58ac20e815625dc39ede9 (plain) (blame)
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
# frozen_string_literal: true

require "abstract_unit"
require "active_support/configurable"

class ConfigurableActiveSupport < ActiveSupport::TestCase
  class Parent
    include ActiveSupport::Configurable
    config_accessor :foo
    config_accessor :bar, instance_reader: false, instance_writer: false
    config_accessor :baz, instance_accessor: false
  end

  class Child < Parent
  end

  setup do
    Parent.config.clear
    Parent.config.foo = :bar

    Child.config.clear
  end

  test "adds a configuration hash" do
    assert_equal({ foo: :bar }, Parent.config)
  end

  test "adds a configuration hash to a module as well" do
    mixin = Module.new { include ActiveSupport::Configurable }
    mixin.config.foo = :bar
    assert_equal({ foo: :bar }, mixin.config)
  end

  test "configuration hash is inheritable" do
    assert_equal :bar, Child.config.foo
    assert_equal :bar, Parent.config.foo

    Child.config.foo = :baz
    assert_equal :baz, Child.config.foo
    assert_equal :bar, Parent.config.foo
  end

  test "configuration accessors are not available on instance" do
    instance = Parent.new

    assert_not_respond_to instance, :bar
    assert_not_respond_to instance, :bar=

    assert_not_respond_to instance, :baz
    assert_not_respond_to instance, :baz=
  end

  test "configuration accessors can take a default value" do
    parent = Class.new do
      include ActiveSupport::Configurable
      config_accessor :hair_colors, :tshirt_colors do
        [:black, :blue, :white]
      end
    end

    assert_equal [:black, :blue, :white], parent.hair_colors
    assert_equal [:black, :blue, :white], parent.tshirt_colors
  end

  test "configuration hash is available on instance" do
    instance = Parent.new
    assert_equal :bar, instance.config.foo
    assert_equal :bar, Parent.config.foo

    instance.config.foo = :baz
    assert_equal :baz, instance.config.foo
    assert_equal :bar, Parent.config.foo
  end

  test "configuration is crystalizeable" do
    parent = Class.new { include ActiveSupport::Configurable }
    child  = Class.new(parent)

    parent.config.bar = :foo
    assert_method_not_defined parent.config, :bar
    assert_method_not_defined child.config, :bar
    assert_method_not_defined child.new.config, :bar

    parent.config.compile_methods!
    assert_equal :foo, parent.config.bar
    assert_equal :foo, child.new.config.bar

    assert_method_defined parent.config, :bar
    assert_method_defined child.config, :bar
    assert_method_defined child.new.config, :bar
  end

  test "should raise name error if attribute name is invalid" do
    assert_raises NameError do
      Class.new do
        include ActiveSupport::Configurable
        config_accessor "invalid attribute name"
      end
    end

    assert_raises NameError do
      Class.new do
        include ActiveSupport::Configurable
        config_accessor "invalid\nattribute"
      end
    end

    assert_raises NameError do
      Class.new do
        include ActiveSupport::Configurable
        config_accessor "invalid\n"
      end
    end
  end

  test "the config_accessor method should not be publicly callable" do
    assert_raises NoMethodError do
      Class.new {
        include ActiveSupport::Configurable
      }.config_accessor :foo
    end
  end

  def assert_method_defined(object, method)
    methods = object.public_methods.map(&:to_s)
    assert_includes methods, method.to_s, "Expected #{methods.inspect} to include #{method.to_s.inspect}"
  end

  def assert_method_not_defined(object, method)
    methods = object.public_methods.map(&:to_s)
    assert_not_includes methods, method.to_s, "Expected #{methods.inspect} to not include #{method.to_s.inspect}"
  end
end