blankslate 2.1.2.4 → 3.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ = Builder 1.2.4 Released.
2
+
3
+ Added a "CDATA" method to the XML Markup builder (from Josh Knowles).
4
+
5
+ == What is Builder?
6
+
7
+ Builder::XmlMarkup allows easy programmatic creation of XML markup.
8
+ For example:
9
+
10
+ builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
11
+ builder.person { |b| b.name("Jim"); b.phone("555-1234") }
12
+ puts builder.target!
13
+
14
+ will generate:
15
+
16
+ <person>
17
+ <name>Jim</name>
18
+ <phone>555-1234</phone>
19
+ </person>
20
+
21
+ == Availability
22
+
23
+ The easiest way to get and install builder is via RubyGems ...
24
+
25
+ gem install builder (you may need root/admin privileges)
26
+
27
+ == Thanks
28
+
29
+ * Josh Knowles for the cdata! patch.
30
+
31
+ -- Jim Weirich
@@ -0,0 +1,46 @@
1
+ = Builder 2.0.0 Released.
2
+
3
+ == Changes in 2.0.0
4
+
5
+ * UTF-8 characters in data are now correctly translated to their XML
6
+ equivalents. (Thanks to Sam Ruby)
7
+
8
+ * Attribute values are now escaped by default. See the README
9
+ file for details.
10
+
11
+ <b>NOTE:</b> The escaping attribute values by default is different
12
+ than in previous releases of Builder. This makes version 2.0.0
13
+ somewhat incompatible with the 1.x series of Builder. If you use "&",
14
+ "<", or ">" in attributes values, you may have to change your
15
+ code. (Essentially you remove the manual escaping. The new way is
16
+ easier, believe me).
17
+
18
+ == What is Builder?
19
+
20
+ Builder::XmlMarkup is a library that allows easy programmatic creation
21
+ of XML markup. For example:
22
+
23
+ builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
24
+ builder.person { |b| b.name("Jim"); b.phone("555-1234") }
25
+
26
+ will generate:
27
+
28
+ <person>
29
+ <name>Jim</name>
30
+ <phone>555-1234</phone>
31
+ </person>
32
+
33
+ == Availability
34
+
35
+ The easiest way to get and install builder is via RubyGems ...
36
+
37
+ gem install builder (you may need root/admin privileges)
38
+
39
+ == Thanks
40
+
41
+ * Sam Ruby for the XChar module and the related UTF-8 translation
42
+ tools.
43
+ * Also to Sam Ruby for gently persuading me to start quoting attribute
44
+ values.
45
+
46
+ -- Jim Weirich
@@ -0,0 +1,58 @@
1
+ = Builder 2.1.1 Released.
2
+
3
+ Release 2.1.1 of Builder is mainly a bug fix release.
4
+
5
+ == Changes in 2.1.1
6
+
7
+ * Added <tt>reveal</tt> capability to BlankSlate.
8
+
9
+ * Fixed a bug in BlankSlate where including a module into Object could
10
+ cause methods to leak into BlankSlate.
11
+
12
+ * Fixed typo in XmlMarkup class docs (from Martin Fowler).
13
+
14
+ * Fixed test on private methods to differentiate between targetted and
15
+ untargetted private methods.
16
+
17
+ * Removed legacy capture of @self in XmlBase (@self was used back when
18
+ we used instance eval).
19
+
20
+ * Added additional tests for global functions (both direct and
21
+ included).
22
+
23
+ * Several misc internal cleanups, including rearranging the source
24
+ code tree.
25
+
26
+ <b>NOTE:</b> The escaping attribute values by default is different
27
+ than in previous releases of Builder. This makes version 2.0.x
28
+ somewhat incompatible with the 1.x series of Builder. If you use "&",
29
+ "<", or ">" in attributes values, you may have to change your
30
+ code. (Essentially you remove the manual escaping. The new way is
31
+ easier, believe me).
32
+
33
+ == What is Builder?
34
+
35
+ Builder::XmlMarkup is a library that allows easy programmatic creation
36
+ of XML markup. For example:
37
+
38
+ builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
39
+ builder.person { |b| b.name("Jim"); b.phone("555-1234") }
40
+
41
+ will generate:
42
+
43
+ <person>
44
+ <name>Jim</name>
45
+ <phone>555-1234</phone>
46
+ </person>
47
+
48
+ == Availability
49
+
50
+ The easiest way to get and install builder is via RubyGems ...
51
+
52
+ gem install builder (you may need root/admin privileges)
53
+
54
+ == Thanks
55
+
56
+ * Martin Fowler for spotting some typos in the documentation.
57
+
58
+ -- Jim Weirich
@@ -8,6 +8,30 @@
8
8
  # above copyright notice is included.
9
9
  #++
10
10
 
11
+ class String
12
+ if instance_methods.first.is_a?(Symbol)
13
+ def _blankslate_as_name
14
+ to_sym
15
+ end
16
+ else
17
+ def _blankslate_as_name
18
+ self
19
+ end
20
+ end
21
+ end
22
+
23
+ class Symbol
24
+ if instance_methods.first.is_a?(Symbol)
25
+ def _blankslate_as_name
26
+ self
27
+ end
28
+ else
29
+ def _blankslate_as_name
30
+ to_s
31
+ end
32
+ end
33
+ end
34
+
11
35
  ######################################################################
12
36
  # BlankSlate provides an abstract base class with no predefined
13
37
  # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
@@ -16,12 +40,12 @@
16
40
  #
17
41
  class BlankSlate
18
42
  class << self
19
-
43
+
20
44
  # Hide the method named +name+ in the BlankSlate class. Don't
21
45
  # hide +instance_eval+ or any method beginning with "__".
22
46
  def hide(name)
23
- if instance_methods.map(&:to_sym).include?(name.to_sym) and
24
- name !~ /^(__|instance_eval|object_id)/
47
+ if instance_methods.include?(name._blankslate_as_name) and
48
+ name !~ /^(__|instance_eval$)/
25
49
  @hidden_methods ||= {}
26
50
  @hidden_methods[name.to_sym] = instance_method(name)
27
51
  undef_method name
@@ -41,7 +65,7 @@ class BlankSlate
41
65
  define_method(name, hidden_method)
42
66
  end
43
67
  end
44
-
68
+
45
69
  instance_methods.each { |m| hide(m) }
46
70
  end
47
71
 
@@ -106,4 +130,4 @@ class Module
106
130
  end
107
131
  result
108
132
  end
109
- end
133
+ end
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
5
+ # Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
6
+ # All rights reserved.
7
+
8
+ # Permission is granted for use, copying, modification, distribution,
9
+ # and distribution of modified versions of this work as long as the
10
+ # above copyright notice is included.
11
+ #++
12
+
13
+ require 'test/unit'
14
+ require 'test/preload'
15
+ require 'blankslate'
16
+ require 'stringio'
17
+
18
+ # Methods to be introduced into the Object class late.
19
+ module LateObject
20
+ def late_object
21
+ 33
22
+ end
23
+ def LateObject.included(mod)
24
+ # Modules defining an included method should not prevent blank
25
+ # slate erasure!
26
+ end
27
+ end
28
+
29
+ # Methods to be introduced into the Kernel module late.
30
+ module LateKernel
31
+ def late_kernel
32
+ 44
33
+ end
34
+ def LateKernel.included(mod)
35
+ # Modules defining an included method should not prevent blank
36
+ # slate erasure!
37
+ end
38
+ end
39
+
40
+ # Introduce some late methods (both module and direct) into the Kernel
41
+ # module.
42
+ module Kernel
43
+ include LateKernel
44
+
45
+ def late_addition
46
+ 1234
47
+ end
48
+
49
+ def double_late_addition
50
+ 11
51
+ end
52
+
53
+ def double_late_addition
54
+ 22
55
+ end
56
+ end
57
+
58
+
59
+ # Introduce some late methods (both module and direct) into the Object
60
+ # class.
61
+ class Object
62
+ include LateObject
63
+ def another_late_addition
64
+ 4321
65
+ end
66
+ end
67
+
68
+ # Introduce some late methods by inclusion.
69
+ module GlobalModule
70
+ def global_inclusion
71
+ 42
72
+ end
73
+ end
74
+ include GlobalModule
75
+
76
+ def direct_global
77
+ 43
78
+ end
79
+
80
+ ######################################################################
81
+ # Test case for blank slate.
82
+ #
83
+ class TestBlankSlate < Test::Unit::TestCase
84
+ def setup
85
+ @bs = BlankSlate.new
86
+ end
87
+
88
+ def test_undefined_methods_remain_undefined
89
+ assert_raise(NoMethodError) { @bs.no_such_method }
90
+ assert_raise(NoMethodError) { @bs.nil? }
91
+ end
92
+
93
+
94
+ # NOTE: NameError is acceptable because the lack of a '.' means that
95
+ # Ruby can't tell if it is a method or a local variable.
96
+ def test_undefined_methods_remain_undefined_during_instance_eval
97
+ assert_raise(NoMethodError, NameError) do
98
+ @bs.instance_eval do nil? end
99
+ end
100
+ assert_raise(NoMethodError, NameError) do
101
+ @bs.instance_eval do no_such_method end
102
+ end
103
+ end
104
+
105
+ def test_private_methods_are_undefined
106
+ assert_raise(NoMethodError) do
107
+ @bs.puts "HI"
108
+ end
109
+ end
110
+
111
+ def test_targetted_private_methods_are_undefined_during_instance_eval
112
+ assert_raise(NoMethodError, NameError) do
113
+ @bs.instance_eval do self.puts "HI" end
114
+ end
115
+ end
116
+
117
+ def test_untargetted_private_methods_are_defined_during_instance_eval
118
+ oldstdout = $stdout
119
+ $stdout = StringIO.new
120
+ @bs.instance_eval do
121
+ puts "HI"
122
+ end
123
+ ensure
124
+ $stdout = oldstdout
125
+ end
126
+
127
+ def test_methods_added_late_to_kernel_remain_undefined
128
+ assert_equal 1234, nil.late_addition
129
+ assert_raise(NoMethodError) { @bs.late_addition }
130
+ end
131
+
132
+ def test_methods_added_late_to_object_remain_undefined
133
+ assert_equal 4321, nil.another_late_addition
134
+ assert_raise(NoMethodError) { @bs.another_late_addition }
135
+ end
136
+
137
+ def test_methods_added_late_to_global_remain_undefined
138
+ assert_equal 42, global_inclusion
139
+ assert_raise(NoMethodError) { @bs.global_inclusion }
140
+ end
141
+
142
+ def test_preload_method_added
143
+ assert Kernel.k_added_names.include?(:late_addition)
144
+ assert Object.o_added_names.include?(:another_late_addition)
145
+ end
146
+
147
+ def test_method_defined_late_multiple_times_remain_undefined
148
+ assert_equal 22, nil.double_late_addition
149
+ assert_raise(NoMethodError) { @bs.double_late_addition }
150
+ end
151
+
152
+ def test_late_included_module_in_object_is_ok
153
+ assert_equal 33, 1.late_object
154
+ assert_raise(NoMethodError) { @bs.late_object }
155
+ end
156
+
157
+ def test_late_included_module_in_kernel_is_ok
158
+ assert_raise(NoMethodError) { @bs.late_kernel }
159
+ end
160
+
161
+ def test_revealing_previously_hidden_methods_are_callable
162
+ with_to_s = Class.new(BlankSlate) do
163
+ reveal :to_s
164
+ end
165
+ assert_match(/^#<.*>$/, with_to_s.new.to_s)
166
+ end
167
+
168
+ def test_revealing_previously_hidden_methods_are_callable_with_block
169
+ Object.class_eval <<-EOS
170
+ def given_block(&block)
171
+ block
172
+ end
173
+ EOS
174
+
175
+ with_given_block = Class.new(BlankSlate) do
176
+ reveal :given_block
177
+ end
178
+ assert_not_nil with_given_block.new.given_block {}
179
+ end
180
+
181
+ def test_revealing_a_hidden_method_twice_is_ok
182
+ with_to_s = Class.new(BlankSlate) do
183
+ reveal :to_s
184
+ reveal :to_s
185
+ end
186
+ assert_match(/^#<.*>$/, with_to_s.new.to_s)
187
+ end
188
+
189
+ def test_revealing_unknown_hidden_method_is_an_error
190
+ assert_raises(RuntimeError) do
191
+ Class.new(BlankSlate) do
192
+ reveal :xyz
193
+ end
194
+ end
195
+ end
196
+
197
+ def test_global_includes_still_work
198
+ assert_nothing_raised do
199
+ assert_equal 42, global_inclusion
200
+ assert_equal 42, Object.new.global_inclusion
201
+ assert_equal 42, "magic number".global_inclusion
202
+ assert_equal 43, direct_global
203
+ end
204
+ end
205
+
206
+ def test_reveal_should_not_bind_to_an_instance
207
+ with_object_id = Class.new(BlankSlate) do
208
+ reveal(:object_id)
209
+ end
210
+
211
+ obj1 = with_object_id.new
212
+ obj2 = with_object_id.new
213
+
214
+ assert obj1.object_id != obj2.object_id,
215
+ "Revealed methods should not be bound to a particular instance"
216
+ end
217
+ end
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
5
+ # Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
6
+ # All rights reserved.
7
+
8
+ # Permission is granted for use, copying, modification, distribution,
9
+ # and distribution of modified versions of this work as long as the
10
+ # above copyright notice is included.
11
+ #++
12
+
13
+ require 'test/unit'
14
+ require 'test/preload'
15
+ require 'builder'
16
+ require 'builder/xmlevents'
17
+
18
+ class TestEvents < Test::Unit::TestCase
19
+
20
+ class Target
21
+ attr_reader :events
22
+
23
+ def initialize
24
+ @events = []
25
+ end
26
+
27
+ def start_tag(tag, attrs)
28
+ @events << [:start_tag, tag, attrs]
29
+ end
30
+
31
+ def end_tag(tag)
32
+ @events << [:end_tag, tag]
33
+ end
34
+
35
+ def text(string)
36
+ @events << [:text, string]
37
+ end
38
+
39
+ end
40
+
41
+
42
+ def setup
43
+ @target = Target.new
44
+ @xml = Builder::XmlEvents.new(:target=>@target)
45
+ end
46
+
47
+ def test_simple
48
+ @xml.one
49
+ expect [:start_tag, :one, nil]
50
+ expect [:end_tag, :one]
51
+ expect_done
52
+ end
53
+
54
+ def test_nested
55
+ @xml.one { @xml.two }
56
+ expect [:start_tag, :one, nil]
57
+ expect [:start_tag, :two, nil]
58
+ expect [:end_tag, :two]
59
+ expect [:end_tag, :one]
60
+ expect_done
61
+ end
62
+
63
+ def test_text
64
+ @xml.one("a")
65
+ expect [:start_tag, :one, nil]
66
+ expect [:text, "a"]
67
+ expect [:end_tag, :one]
68
+ expect_done
69
+ end
70
+
71
+ def test_special_text
72
+ @xml.one("H&R")
73
+ expect [:start_tag, :one, nil]
74
+ expect [:text, "H&R"]
75
+ expect [:end_tag, :one]
76
+ expect_done
77
+ end
78
+
79
+ def test_text_with_entity
80
+ @xml.one("H&amp;R")
81
+ expect [:start_tag, :one, nil]
82
+ expect [:text, "H&amp;R"]
83
+ expect [:end_tag, :one]
84
+ expect_done
85
+ end
86
+
87
+ def test_attributes
88
+ @xml.a(:b=>"c", :x=>"y")
89
+ expect [:start_tag, :a, {:x => "y", :b => "c"}]
90
+ expect [:end_tag, :a]
91
+ expect_done
92
+ end
93
+
94
+ def test_moderately_complex
95
+ @xml.tag! "address-book" do |x|
96
+ x.entry :id=>"1" do
97
+ x.name {
98
+ x.first "Bill"
99
+ x.last "Smith"
100
+ }
101
+ x.address "Cincinnati"
102
+ end
103
+ x.entry :id=>"2" do
104
+ x.name {
105
+ x.first "John"
106
+ x.last "Doe"
107
+ }
108
+ x.address "Columbus"
109
+ end
110
+ end
111
+ expect [:start_tag, "address-book".intern, nil]
112
+ expect [:start_tag, :entry, {:id => "1"}]
113
+ expect [:start_tag, :name, nil]
114
+ expect [:start_tag, :first, nil]
115
+ expect [:text, "Bill"]
116
+ expect [:end_tag, :first]
117
+ expect [:start_tag, :last, nil]
118
+ expect [:text, "Smith"]
119
+ expect [:end_tag, :last]
120
+ expect [:end_tag, :name]
121
+ expect [:start_tag, :address, nil]
122
+ expect [:text, "Cincinnati"]
123
+ expect [:end_tag, :address]
124
+ expect [:end_tag, :entry]
125
+ expect [:start_tag, :entry, {:id => "2"}]
126
+ expect [:start_tag, :name, nil]
127
+ expect [:start_tag, :first, nil]
128
+ expect [:text, "John"]
129
+ expect [:end_tag, :first]
130
+ expect [:start_tag, :last, nil]
131
+ expect [:text, "Doe"]
132
+ expect [:end_tag, :last]
133
+ expect [:end_tag, :name]
134
+ expect [:start_tag, :address, nil]
135
+ expect [:text, "Columbus"]
136
+ expect [:end_tag, :address]
137
+ expect [:end_tag, :entry]
138
+ expect [:end_tag, "address-book".intern]
139
+ expect_done
140
+ end
141
+
142
+ def expect(value)
143
+ assert_equal value, @target.events.shift
144
+ end
145
+
146
+ def expect_done
147
+ assert_nil @target.events.shift
148
+ end
149
+
150
+ end