therealadam (owner)

Forks

Revisions

gist: 119286 Download_button fork
public
Public Clone URL: git://gist.github.com/119286.git
Embed All Files: show embed
accessor_macros.rb #
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
# A shoulda macro for verifying a class has the writer attribute readers,
# writers and accessors. NOTE: I could be silly for wanting this. But it was
# there. So here it is.
#
# (c) Copyright 2009 Adam Keys. MIT license.
 
module AccessorMacros
  
  def should_have_reader(name)
    should "have an attribute reader for #{name.to_s}" do
      assert ShouldHaveAccessor.new(self, name, :reader).verify?
    end
  end
  
  def should_have_writer(name)
    should "have an attribute writer for #{name.to_s}" do
      assert ShouldHaveAccessor.new(self, name, :writer).verify?
    end
  end
  
  def should_have_accessor(name)
    should_have_reader(name)
    should_have_writer(name)
  end
  
  def should_have_readers(*names)
    names.each { |n| should_have_reader(n) }
  end
  
  def should_have_writers(*names)
    names.each { |n| should_have_writer(n) }
  end
  
  def should_have_accessors(*names)
    names.each { |n| should_have_accessor(n) }
  end
  
  class ShouldHaveAccessor
    
    attr_reader :object, :name, :kind
    
    def initialize(object, name, kind)
      @object = object
      @name = name
      @kind = kind
    end
    
    def verify?
      selector = case kind
      when :reader
        name.to_s
      when :writer
        "#{name.to_s}="
      end
      subject.respond_to?(selector)
    end
    
    def subject
      klass_name = object.class.name.gsub(/Test$/, '').downcase
      if object.respond_to?(:subject)
        object.subject
      else
        object.instance_variable_get("@#{klass_name}")
      end
    end
  end
  
end
 
%w{test/unit rubygems shoulda}.each { |l| require(l) }
 
class Test::Unit::TestCase
  extend AccessorMacros
end
 
class Gizmo
  attr_accessor :foo
  attr_reader :bar
  attr_writer :baz
  attr_reader :one, :two, :three
  attr_accessor :oink, :boink
  attr_writer :abbott, :costello
end
 
class GizmoTest < Test::Unit::TestCase
  
  context 'A gizmo' do
    
    setup { @gizmo = Gizmo.new }
    
    should_have_accessor :foo
    should_have_reader :bar
    should_have_writer :baz
    
    should_have_readers :one, :two, :three
    should_have_writers :abbott, :costello
    should_have_accessors :oink, :boink
    
  end
  
end
 
class HorriblyNamedThingy; attr_accessor :foo; end
 
class HorriblyNamedClassTest < Test::Unit::TestCase
  
  context 'A class that you would never want to type out' do
    
    setup { @thing = HorriblyNamedThingy.new }
    
    should_have_accessor :foo
    
  end
  
  def subject
    @thing
  end
  
end