peachy 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +11 -3
- data/README.rdoc +12 -4
- data/lib/method_not_in_ruby_convention.rb +1 -1
- data/lib/nothing_to_mimic.rb +2 -0
- data/lib/peachy.rb +1 -3
- data/lib/peachy/childless_proxy_with_attributes.rb +1 -1
- data/lib/peachy/method_mask.rb +1 -3
- data/lib/peachy/method_name.rb +14 -0
- data/lib/peachy/mimic.rb +5 -1
- data/lib/peachy/morph_into_array.rb +6 -4
- data/lib/peachy/parsers/nokogiri_wrapper.rb +4 -0
- data/lib/peachy/parsers/rexml_attribute_wrapper.rb +4 -0
- data/lib/peachy/parsers/rexml_wrapper.rb +4 -0
- data/lib/peachy/proxy.rb +9 -4
- data/lib/peachy/proxy_factory.rb +1 -1
- data/lib/peachy/simple_content.rb +7 -9
- data/lib/peachy/version.rb +2 -2
- data/lib/peachy/xml_node.rb +1 -1
- data/spec/attributes_on_a_parent_node_spec.rb +2 -2
- data/spec/camel_case_names_spec.rb +3 -3
- data/spec/childless_elements_referenced_as_collections_spec.rb +8 -5
- data/spec/collections_with_children_as_arrays_spec.rb +1 -1
- data/spec/elements_referenced_as_collections_spec.rb +3 -3
- data/spec/hyphen_separated_names_spec.rb +3 -3
- data/spec/inferring_a_method_from_an_attribute_spec.rb +2 -2
- data/spec/inferring_a_method_from_element_name_spec.rb +5 -4
- data/spec/method_name_spec.rb +22 -11
- data/spec/mimc_spec.rb +24 -0
- data/spec/nested_elements_spec.rb +2 -2
- data/spec/nodes_with_children_spec.rb +2 -2
- data/spec/nokogiri_is_the_available_xml_parser_spec.rb +1 -1
- data/spec/only_rexml_is_available_spec.rb +1 -1
- data/spec/parsers/all_parser_wrappers_spec.rb +3 -21
- data/spec/parsers/nokigiri_wrapper_spec.rb +15 -0
- data/spec/parsers/rexml_attribute_wrapper_spec.rb +14 -0
- data/spec/parsers/rexml_wrapper_spec.rb +14 -0
- data/spec/pascal_case_names_spec.rb +3 -3
- data/spec/proxy_spec.rb +21 -0
- data/spec/simple_content_wrapper_for_Peachy_spec.rb +18 -12
- data/spec/simple_element_referenced_as_collections_spec.rb +3 -3
- data/spec/simple_xml_collections_as_arrays_spec.rb +1 -1
- data/spec/using_peachy_proxy_incorrectly_spec.rb +5 -3
- metadata +9 -4
- data/lib/peachy/convention_checks.rb +0 -17
data/History.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 0.3.2
|
2
|
+
* Minor improvements
|
3
|
+
* Better support for Ruby 1.8.6
|
4
|
+
* Better implementation of MorphIntoArray, which introduced the Mimic module.
|
5
|
+
* Standardised to_s implementations to return the encapsulated XML from Proxies.
|
6
|
+
|
7
|
+
== 0.3.1
|
8
|
+
* Minor improvements
|
9
|
+
* Should now work on 1.8.6, so removed minimum rqeuirement of Ruby version 1.8.7
|
10
|
+
* Tweaked some implementation details.
|
11
|
+
|
1
12
|
== 0.3.0
|
2
13
|
|
3
14
|
* Major improvements
|
@@ -7,7 +18,6 @@
|
|
7
18
|
* Minor improvements
|
8
19
|
* Improved implementation of NokogiriWrapper.
|
9
20
|
|
10
|
-
|
11
21
|
== 0.2.1
|
12
22
|
|
13
23
|
* Major improvements
|
@@ -16,11 +26,9 @@
|
|
16
26
|
* Only children can now be treated as if they are arrays in any way, morphing into
|
17
27
|
an array if treated as an array.
|
18
28
|
|
19
|
-
|
20
29
|
== 0.2.0
|
21
30
|
|
22
31
|
* Major improvements
|
23
32
|
* Can now treat only children as if they are the first element in an array.
|
24
33
|
* Console output is now configurable.
|
25
34
|
* Test specs are now included in gem.
|
26
|
-
|
data/README.rdoc
CHANGED
@@ -28,7 +28,8 @@ node name:
|
|
28
28
|
puts 'Contents: ' + proxy.xml.node.value
|
29
29
|
-> Contents: Peachy
|
30
30
|
|
31
|
-
|
31
|
+
Call #value on a childless node to get the contents the node, such as the example
|
32
|
+
above.
|
32
33
|
|
33
34
|
Peachy expects method names to be called in the Ruby convention of lowercase with
|
34
35
|
underscores. It will do it's best to match method names to elements and attributes
|
@@ -37,15 +38,23 @@ or hyphen-separated-names)
|
|
37
38
|
|
38
39
|
More detailed usage examples can be found in the .rb files in the /test directory.
|
39
40
|
|
40
|
-
=== XML
|
41
|
+
=== Getting the underlying XML
|
42
|
+
It's possible to call #to_s on any node in the tree to get the underlying XML at
|
43
|
+
that point in the tree, such as:
|
44
|
+
|
45
|
+
puts 'XML: ' + proxy.xml.node
|
46
|
+
-> <node>Peachy</node>
|
47
|
+
|
48
|
+
The exact representation of the XML will depend on the underlying XML parser that
|
49
|
+
is being used, but the XML will be valid and correct.
|
41
50
|
|
51
|
+
=== XML parsing
|
42
52
|
Peachy tries to determine which XML parser to load when it is first used. Nokogiri
|
43
53
|
is currently the first choice, defaulting to REXML if Nokogiri is not available.
|
44
54
|
It's possible to extend this out so let me know if there are any other XML parsers
|
45
55
|
that you'd like Peachy to support.
|
46
56
|
|
47
57
|
=== Elements and Attributes
|
48
|
-
|
49
58
|
Currently, elements and attributes are accessed in almost exactly the same way;
|
50
59
|
call a method on your current node matching the attribute or element name that
|
51
60
|
is required next. Elements need to have .value or .to_s called on them to get
|
@@ -63,7 +72,6 @@ Peachy is just for slurping XML, so this convention should make it easy to know
|
|
63
72
|
how to access the property that you're after, be they elements or attributes.
|
64
73
|
|
65
74
|
=== No method name match
|
66
|
-
|
67
75
|
Peachy is currently short-tempered, in that if no element or attribute match is
|
68
76
|
found when drilling down through proxies, a NoMatchingXmlPart error will be
|
69
77
|
raised.
|
data/lib/peachy.rb
CHANGED
@@ -4,7 +4,7 @@ require File.join(File.dirname(__FILE__), 'already_an_only_child')
|
|
4
4
|
require File.join(File.dirname(__FILE__), 'invalid_proxy_parameters')
|
5
5
|
require File.join(File.dirname(__FILE__), 'method_not_in_ruby_convention')
|
6
6
|
require File.join(File.dirname(__FILE__), 'no_matching_xml_part')
|
7
|
-
require File.join(File.dirname(__FILE__), '
|
7
|
+
require File.join(File.dirname(__FILE__), 'nothing_to_mimic')
|
8
8
|
require File.join(File.dirname(__FILE__), 'peachy/string_styler')
|
9
9
|
require File.join(File.dirname(__FILE__), 'peachy/method_name')
|
10
10
|
require File.join(File.dirname(__FILE__), 'peachy/method_mask')
|
@@ -23,8 +23,6 @@ require File.join(File.dirname(__FILE__), 'peachy/proxy')
|
|
23
23
|
require File.join(File.dirname(__FILE__), 'peachy/proxy_factory')
|
24
24
|
require File.join(File.dirname(__FILE__), 'peachy/childless_proxy_with_attributes')
|
25
25
|
|
26
|
-
# first up, load the underlying XML parser that Peachy will use
|
27
|
-
|
28
26
|
module Peachy
|
29
27
|
def self.whine
|
30
28
|
@whine = true
|
data/lib/peachy/method_mask.rb
CHANGED
@@ -3,9 +3,7 @@ module Peachy
|
|
3
3
|
private
|
4
4
|
def hide_public_methods exceptions
|
5
5
|
methods_to_hide = public_instance_methods.clone
|
6
|
-
exceptions.each
|
7
|
-
methods_to_hide.delete(to_stay_public)
|
8
|
-
end
|
6
|
+
exceptions.each {|stay_public| methods_to_hide.delete(stay_public) }
|
9
7
|
private *methods_to_hide
|
10
8
|
end
|
11
9
|
end
|
data/lib/peachy/method_name.rb
CHANGED
@@ -15,6 +15,13 @@ module Peachy
|
|
15
15
|
end).uniq
|
16
16
|
end
|
17
17
|
|
18
|
+
# Checks whether the method name is in the accepted convention, raising a
|
19
|
+
# MethodNotInRubyConvention if it's not. This check does not allow method
|
20
|
+
# names to have question marks, exclamation marks or numbers, however.
|
21
|
+
def check_for_convention
|
22
|
+
raise MethodNotInRubyConvention.new(self) unless matches_convention?
|
23
|
+
end
|
24
|
+
|
18
25
|
def to_s
|
19
26
|
return @method_name
|
20
27
|
end
|
@@ -27,5 +34,12 @@ module Peachy
|
|
27
34
|
def variation_methods
|
28
35
|
Peachy::StringStyler.private_instance_methods
|
29
36
|
end
|
37
|
+
|
38
|
+
# Checks whether the method name matches the Ruby convention of lowercase with
|
39
|
+
# underscores. This method does not allow question marks, excalmation marks
|
40
|
+
# or numbers, however.
|
41
|
+
def matches_convention?
|
42
|
+
!(@method_name =~ /^[a-z]+(?:_[a-z]+){0,}$/).nil?
|
43
|
+
end
|
30
44
|
end
|
31
45
|
end
|
data/lib/peachy/mimic.rb
CHANGED
@@ -10,14 +10,16 @@ module Peachy
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def mimic object_to_mimic
|
13
|
-
|
14
|
-
|
13
|
+
eval_on_singleton_class do
|
14
|
+
define_method(:mimic) { object_to_mimic }
|
15
|
+
include Mimic
|
16
|
+
end
|
15
17
|
end
|
16
18
|
|
17
19
|
def morph_into_array to_add_to_array, method_to_invoke, *args, &block
|
18
20
|
puts "[Peachy::Proxy] Currently acts as #{@acts_as}" if Peachy.whiny?
|
19
|
-
raise AlreadyAnOnlyChild.new(
|
20
|
-
puts "[Peachy::Proxy] So #{
|
21
|
+
raise AlreadyAnOnlyChild.new(name) if is_an_only_child
|
22
|
+
puts "[Peachy::Proxy] So #{name} should be an Array, then." if Peachy.whiny?
|
21
23
|
mimic [to_add_to_array]
|
22
24
|
return send(method_to_invoke, *args, &block)
|
23
25
|
end
|
data/lib/peachy/proxy.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Peachy
|
2
2
|
class Proxy
|
3
3
|
extend MethodMask
|
4
|
-
include
|
4
|
+
include MorphIntoArray, MyMetaClass, XmlNode
|
5
5
|
|
6
6
|
# This hides all public methods on the class except for 'methods', 'nil?'
|
7
7
|
# 'respond_to?' and 'inspect', which I've found are too useful to hide for
|
@@ -15,6 +15,11 @@ module Peachy
|
|
15
15
|
@node = xml_node if xml_node.kind_of? Peachy::Parsers::ParserWrapper
|
16
16
|
end
|
17
17
|
|
18
|
+
def to_s
|
19
|
+
return @xml unless @xml.nil?
|
20
|
+
node.to_s
|
21
|
+
end
|
22
|
+
|
18
23
|
# Overloaded so that calls to methods representative of an XML element or
|
19
24
|
# attribute can be generated dynamically.
|
20
25
|
#
|
@@ -88,8 +93,8 @@ module Peachy
|
|
88
93
|
|
89
94
|
private
|
90
95
|
def generate_method_for_xml method_name
|
91
|
-
check_for_convention
|
92
|
-
attribute_content = create_attribute
|
96
|
+
method_name.check_for_convention
|
97
|
+
attribute_content = create_attribute(method_name)
|
93
98
|
return attribute_content unless attribute_content.nil?
|
94
99
|
matches = node.find_matches(method_name)
|
95
100
|
matches.nil? ? nil : create_method_for_child_or_content(method_name, matches)
|
@@ -133,7 +138,7 @@ module Peachy
|
|
133
138
|
end
|
134
139
|
|
135
140
|
def no_matching_xml method_name
|
136
|
-
raise NoMatchingXmlPart.new(method_name,
|
141
|
+
raise NoMatchingXmlPart.new(method_name, name)
|
137
142
|
end
|
138
143
|
end
|
139
144
|
end
|
data/lib/peachy/proxy_factory.rb
CHANGED
@@ -1,26 +1,24 @@
|
|
1
1
|
module Peachy
|
2
2
|
class SimpleContent
|
3
|
-
alias_method :original_method_missing, :method_missing
|
4
|
-
attr_reader :node_name
|
5
3
|
include MorphIntoArray, MyMetaClass
|
6
|
-
[:to_s, :name].each {|method_name| define_method(method_name) { value } }
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
[:name, :to_s].each {|method| define_method(method) { @xml.send(method) }}
|
6
|
+
|
7
|
+
def initialize xml
|
8
|
+
@xml = xml
|
11
9
|
end
|
12
10
|
|
13
11
|
def value
|
14
12
|
acts_as_only_child
|
15
|
-
@
|
13
|
+
@xml.content
|
16
14
|
end
|
17
15
|
|
18
16
|
def method_missing method_name, *args, &block
|
19
17
|
if you_use_me_like_an_array(method_name, block_given?, *args)
|
20
|
-
new_content = SimpleContent.new(@
|
18
|
+
new_content = SimpleContent.new(@xml)
|
21
19
|
return morph_into_array(new_content, method_name, *args, &block)
|
22
20
|
end
|
23
|
-
|
21
|
+
super
|
24
22
|
end
|
25
23
|
end
|
26
24
|
end
|
data/lib/peachy/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Peachy
|
2
|
-
VERSION = '0.3.
|
3
|
-
end
|
2
|
+
VERSION = '0.3.2'
|
3
|
+
end
|
data/lib/peachy/xml_node.rb
CHANGED
@@ -15,10 +15,10 @@ describe "attributes on a parent node" do
|
|
15
15
|
|
16
16
|
it "should define the attribute name as a method" do
|
17
17
|
@proxy.root.test_node.name
|
18
|
-
@proxy.root.test_node.methods.should include
|
18
|
+
@proxy.root.test_node.methods.should include('name')
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should raise an error if the attirbute does not exist" do
|
22
|
-
lambda { @proxy.root.test_node.other }.should raise_error
|
22
|
+
lambda { @proxy.root.test_node.other }.should raise_error(NoMatchingXmlPart)
|
23
23
|
end
|
24
24
|
end
|
@@ -16,7 +16,7 @@ XML
|
|
16
16
|
|
17
17
|
it "should define a method from a camel cased element name" do
|
18
18
|
@proxy.root.test_node.value.should == 'Check meh.'
|
19
|
-
@proxy.root.methods.should include
|
19
|
+
@proxy.root.methods.should include('test_node')
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should match a method to an attribute by camel case" do
|
@@ -25,12 +25,12 @@ XML
|
|
25
25
|
|
26
26
|
it "should define a method from camel cased attribute name" do
|
27
27
|
@proxy.root.second_node.record_label
|
28
|
-
@proxy.root.second_node.methods.should include
|
28
|
+
@proxy.root.second_node.methods.should include('record_label')
|
29
29
|
end
|
30
30
|
|
31
31
|
it "should match parent attribute names" do
|
32
32
|
@proxy.root.third_node.record_label.should == 'Wall of Sound'
|
33
|
-
@proxy.root.third_node.methods.should include
|
33
|
+
@proxy.root.third_node.methods.should include('record_label')
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
1
3
|
describe "a childless element with attributes referenced as the first part of a collection" do
|
2
4
|
before(:each) do
|
3
5
|
xml = <<XML
|
@@ -23,26 +25,27 @@ XML
|
|
23
25
|
|
24
26
|
element_as_array = @proxy.xml.list.item
|
25
27
|
element_as_array.any?.should be_true
|
26
|
-
element_as_array.one?.should be_true
|
27
28
|
element_as_array.empty?.should be_false
|
28
29
|
element_as_array.size.should == 1
|
29
30
|
element_as_array[0].value.should == 'Hello'
|
30
31
|
end
|
31
32
|
|
32
33
|
it "should raise an error if the element value has already been accessed as an only child" do
|
33
|
-
|
34
|
-
lambda { @proxy.xml.list.item[0] }.should raise_error AlreadyAnOnlyChild, <<MSG
|
34
|
+
expected_message = <<MSG
|
35
35
|
The 'item' node has already been accessed as a single child, but you are now trying to use it as a collection.
|
36
36
|
Do not try to access Peachy::Proxies in a mixed manner in your implementation.
|
37
37
|
MSG
|
38
|
+
@proxy.xml.list.item.value
|
39
|
+
lambda { @proxy.xml.list.item[0] }.should raise_error(AlreadyAnOnlyChild, expected_message)
|
38
40
|
end
|
39
41
|
|
40
42
|
it "should raise an error if the element's attributes have already been accessed as an only child" do
|
41
|
-
|
42
|
-
lambda { @proxy.xml.list.item[0] }.should raise_error AlreadyAnOnlyChild, <<MSG
|
43
|
+
expected_message = <<MSG
|
43
44
|
The 'item' node has already been accessed as a single child, but you are now trying to use it as a collection.
|
44
45
|
Do not try to access Peachy::Proxies in a mixed manner in your implementation.
|
45
46
|
MSG
|
47
|
+
@proxy.xml.list.item.id
|
48
|
+
lambda { @proxy.xml.list.item[0] }.should raise_error(AlreadyAnOnlyChild, expected_message)
|
46
49
|
end
|
47
50
|
end
|
48
51
|
|
@@ -26,7 +26,7 @@ STR
|
|
26
26
|
|
27
27
|
it "should define a method for the name of the list items" do
|
28
28
|
@peachy_proxy.xml.list.item
|
29
|
-
@peachy_proxy.xml.list.methods.should include
|
29
|
+
@peachy_proxy.xml.list.methods.should include('item')
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should create the children as expected" do
|
@@ -27,7 +27,6 @@ XML
|
|
27
27
|
|
28
28
|
element_as_array = @proxy.xml.list.item
|
29
29
|
element_as_array.any?.should be_true
|
30
|
-
element_as_array.one?.should be_true
|
31
30
|
element_as_array.empty?.should be_false
|
32
31
|
element_as_array.size.should == 1
|
33
32
|
(element_as_array.map {|item| item.child.value }).should == ['one']
|
@@ -46,11 +45,12 @@ XML
|
|
46
45
|
end
|
47
46
|
|
48
47
|
it "should raise an error if the element has already been accessed as a single child" do
|
49
|
-
|
50
|
-
lambda { @proxy.xml.list.item[0] }.should raise_error AlreadyAnOnlyChild, <<MSG
|
48
|
+
expected_message = <<MSG
|
51
49
|
The 'item' node has already been accessed as a single child, but you are now trying to use it as a collection.
|
52
50
|
Do not try to access Peachy::Proxies in a mixed manner in your implementation.
|
53
51
|
MSG
|
52
|
+
@proxy.xml.list.item.child
|
53
|
+
lambda { @proxy.xml.list.item[0] }.should raise_error(AlreadyAnOnlyChild, expected_message)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -17,7 +17,7 @@ XML
|
|
17
17
|
|
18
18
|
it "should define a method for the element name" do
|
19
19
|
@proxy.test_node
|
20
|
-
@proxy.methods.should include
|
20
|
+
@proxy.methods.should include('test_node')
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should match a method to an attribute by pascal case" do
|
@@ -26,12 +26,12 @@ XML
|
|
26
26
|
|
27
27
|
it "should define a method from pascal cased attribute name" do
|
28
28
|
@proxy.test_node.second_child.record_label
|
29
|
-
@proxy.test_node.second_child.methods.should include
|
29
|
+
@proxy.test_node.second_child.methods.should include('record_label')
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should define a method on a parent with attributes" do
|
33
33
|
@proxy.test_node.third_child.record_label.should == 'Rough Trade'
|
34
|
-
@proxy.test_node.third_child.methods.should include
|
34
|
+
@proxy.test_node.third_child.methods.should include('record_label')
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should allow child nodes to be selected after an attrbiute is selected on a parent node" do
|
@@ -13,11 +13,11 @@ describe "inferring a method from an attribute" do
|
|
13
13
|
|
14
14
|
it "should define a method for the attribute name" do
|
15
15
|
@proxy.test_node.another
|
16
|
-
@proxy.test_node.methods.should include
|
16
|
+
@proxy.test_node.methods.should include('another')
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should raise an error if method name doesn't match an attribute name" do
|
20
|
-
lambda { @proxy.test_node.missing }.should raise_error
|
20
|
+
lambda { @proxy.test_node.missing }.should raise_error(NoMatchingXmlPart, "missing is not contained as a child of the node test-node.")
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -7,11 +7,11 @@ describe "inferring a method from an element name" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should defer method_missing to the base class implementation if arguments are passed with the missing method" do
|
10
|
-
lambda { @proxy.my_call "argument" }.should raise_error
|
10
|
+
lambda { @proxy.my_call "argument" }.should raise_error(NoMethodError)
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should defer method_missing to the base class implementation if block is given with method_missing" do
|
14
|
-
lambda { @proxy.my_call() { puts "Blockhead." } }.should raise_error
|
14
|
+
lambda { @proxy.my_call() { puts "Blockhead." } }.should raise_error(NoMethodError)
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should not expose the original method_missing alias publically" do
|
@@ -25,8 +25,8 @@ describe "inferring a method from an element name" do
|
|
25
25
|
|
26
26
|
it 'should define the method on an instance, not on the class' do
|
27
27
|
@proxy.testnode
|
28
|
-
@proxy.methods.should include
|
29
|
-
@another_proxy.methods.should_not include
|
28
|
+
@proxy.methods.should include('testnode')
|
29
|
+
@another_proxy.methods.should_not include('testnode')
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should return the node contents when the node isn't defined as a method and the contents of the node is at the lowest point of the tree" do
|
@@ -45,6 +45,7 @@ describe "inferring a method from an element name" do
|
|
45
45
|
@proxy.methods.should include('methods')
|
46
46
|
@proxy.methods.should include('nil?')
|
47
47
|
@proxy.methods.should include('respond_to?')
|
48
|
+
@proxy.methods.should include('to_s')
|
48
49
|
@proxy.methods.should_not include('id')
|
49
50
|
end
|
50
51
|
end
|
data/spec/method_name_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
1
3
|
describe "how to use Peachy::MethodName" do
|
2
4
|
before(:each) do
|
3
5
|
@method_name = Peachy::MethodName.new 'method_name'
|
@@ -18,10 +20,10 @@ describe "how to use Peachy::MethodName" do
|
|
18
20
|
it "should return the expected variation formats" do
|
19
21
|
variations = @method_name.variations
|
20
22
|
|
21
|
-
variations.should include
|
22
|
-
variations.should include
|
23
|
-
variations.should include
|
24
|
-
variations.should include
|
23
|
+
variations.should include('method_name')
|
24
|
+
variations.should include('methodName')
|
25
|
+
variations.should include('method-name')
|
26
|
+
variations.should include('MethodName')
|
25
27
|
end
|
26
28
|
|
27
29
|
it "should be possible to create a MethodName from a symbol" do
|
@@ -31,10 +33,10 @@ describe "how to use Peachy::MethodName" do
|
|
31
33
|
@method_name.to_s.should == 'this_method'
|
32
34
|
@method_name.to_sym.should == :this_method
|
33
35
|
|
34
|
-
variations.should include
|
35
|
-
variations.should include
|
36
|
-
variations.should include
|
37
|
-
variations.should include
|
36
|
+
variations.should include('this_method')
|
37
|
+
variations.should include('thisMethod')
|
38
|
+
variations.should include('this-method')
|
39
|
+
variations.should include('ThisMethod')
|
38
40
|
end
|
39
41
|
|
40
42
|
it "should not include duplicates in variations" do
|
@@ -42,8 +44,17 @@ describe "how to use Peachy::MethodName" do
|
|
42
44
|
variations = @method_name.variations
|
43
45
|
|
44
46
|
variations.size.should == 2
|
45
|
-
variations.should include
|
46
|
-
variations.should include
|
47
|
+
variations.should include('method')
|
48
|
+
variations.should include('Method')
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should know how to check for convention" do
|
52
|
+
@method_name = Peachy::MethodName.new('method_name')
|
53
|
+
@method_name.check_for_convention.should be_nil
|
47
54
|
end
|
48
|
-
end
|
49
55
|
|
56
|
+
it "should know when a method name does not match the accepted convention" do
|
57
|
+
method_name = Peachy::MethodName.new('method_Name')
|
58
|
+
lambda { method_name.check_for_convention }.should raise_error(MethodNotInRubyConvention)
|
59
|
+
end
|
60
|
+
end
|
data/spec/mimc_spec.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "using a Mimic" do
|
4
|
+
before(:each) do
|
5
|
+
@mimic = Object.new
|
6
|
+
class << @mimic
|
7
|
+
include Peachy::Mimic
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should raise an error if the mimic method has not been overridden" do
|
12
|
+
lambda { @mimic.mimic }.should raise_error(NothingToMimic)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should call the underlying object" do
|
16
|
+
to_mimic = "Hello"
|
17
|
+
@mimic.instance_eval do
|
18
|
+
(class << self; self; end).instance_eval { define_method(:mimic) { to_mimic } }
|
19
|
+
end
|
20
|
+
|
21
|
+
@mimic.chomp('o').should == "Hell"
|
22
|
+
@mimic.rjust(8).should == " Hello"
|
23
|
+
end
|
24
|
+
end
|
@@ -12,8 +12,8 @@ describe "nested elements should be handled corectly by Peachy" do
|
|
12
12
|
|
13
13
|
it "should define methods for the ancestors" do
|
14
14
|
@proxy.root.first.second
|
15
|
-
@proxy.root.methods.should include
|
16
|
-
@proxy.root.first.methods.should include
|
15
|
+
@proxy.root.methods.should include('first')
|
16
|
+
@proxy.root.first.methods.should include('second')
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -11,8 +11,8 @@ describe "nodes with multiple children should be handled correctly" do
|
|
11
11
|
it "should define a method with the child name on the proxy" do
|
12
12
|
@node_to_test.child
|
13
13
|
@node_to_test.second_child
|
14
|
-
@node_to_test.methods.should include
|
15
|
-
@node_to_test.methods.should include
|
14
|
+
@node_to_test.methods.should include('child')
|
15
|
+
@node_to_test.methods.should include('second_child')
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should recurse the Proxy to ancestors so that a child will have the correct value" do
|
@@ -33,7 +33,7 @@ describe "nokogiri is the available XML parser" do
|
|
33
33
|
it "should create a NokogiriWrapper from xml" do
|
34
34
|
@factory.load_parser
|
35
35
|
wrapper = @factory.make_from '<thing>Stuff</thing>'
|
36
|
-
wrapper.should be_a
|
36
|
+
wrapper.should be_a(Peachy::Parsers::NokogiriWrapper)
|
37
37
|
wrapper.content.should == 'Stuff'
|
38
38
|
end
|
39
39
|
end
|
@@ -34,7 +34,7 @@ describe "only REXML is available" do
|
|
34
34
|
it "should create a REXMLWrapper from xml" do
|
35
35
|
@factory.load_parser
|
36
36
|
wrapper = @factory.make_from '<thing>Stuff</thing>'
|
37
|
-
wrapper.should be_a
|
37
|
+
wrapper.should be_a(Peachy::Parsers::REXMLWrapper)
|
38
38
|
wrapper.has_children?.should be_true
|
39
39
|
end
|
40
40
|
end
|
@@ -6,7 +6,7 @@ shared_examples_for "all parser wrappers" do
|
|
6
6
|
matches.size.should == 1
|
7
7
|
matches[0].name.should == 'child'
|
8
8
|
matches[0].content.should == 'Name'
|
9
|
-
matches[0].should be_a
|
9
|
+
matches[0].should be_a(@expected_wrapper_class)
|
10
10
|
end
|
11
11
|
|
12
12
|
it "should return no matches for a child name that doesn't exist" do
|
@@ -36,26 +36,8 @@ shared_examples_for "all parser wrappers" do
|
|
36
36
|
it "should indicate that an element has both children and an attribute" do
|
37
37
|
@wrapper.has_children_and_attributes?.should be_true
|
38
38
|
end
|
39
|
-
end
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
noko = Nokogiri::XML('<root type="test"><child>Name</child></root>')
|
44
|
-
@wrapper = Peachy::Parsers::NokogiriWrapper.new((noko/'root')[0])
|
45
|
-
@expected_wrapper_class = Peachy::Parsers::NokogiriWrapper
|
40
|
+
it "should return a string representation of the XML" do
|
41
|
+
@wrapper.to_s.should == @raw_xml
|
46
42
|
end
|
47
|
-
|
48
|
-
it_should_behave_like "all parser wrappers"
|
49
43
|
end
|
50
|
-
|
51
|
-
require 'rexml/document'
|
52
|
-
|
53
|
-
describe "the REXML parser wrapper class" do
|
54
|
-
before(:each) do
|
55
|
-
rexml = REXML::Document.new('<root type="test"><child>Name</child></root>')
|
56
|
-
@wrapper = Peachy::Parsers::REXMLWrapper.new rexml.root
|
57
|
-
@expected_wrapper_class = Peachy::Parsers::REXMLWrapper
|
58
|
-
end
|
59
|
-
|
60
|
-
it_should_behave_like "all parser wrappers"
|
61
|
-
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'nokogiri'
|
3
|
+
require File.join(File.dirname(__FILE__), 'all_parser_wrappers_spec')
|
4
|
+
|
5
|
+
describe "a Peachy::Parsers::NokogiriWrapper" do
|
6
|
+
before(:each) do
|
7
|
+
@raw_xml = "<root type=\"test\">\n <child>Name</child>\n</root>"
|
8
|
+
noko = Nokogiri::XML(@raw_xml)
|
9
|
+
@wrapper = Peachy::Parsers::NokogiriWrapper.new((noko/'root')[0])
|
10
|
+
@expected_wrapper_class = Peachy::Parsers::NokogiriWrapper
|
11
|
+
end
|
12
|
+
|
13
|
+
it_should_behave_like "all parser wrappers"
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "a REXMLAttributeWrapper" do
|
4
|
+
before(:each) do
|
5
|
+
@attribute_name = 'name'
|
6
|
+
@attribute_value = 'value'
|
7
|
+
@wrapper = Peachy::Parsers::REXMLAttributeWrapper.new [@attribute_name, @attribute_value]
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should return the string contents of the attribute" do
|
11
|
+
@wrapper.to_s.should == @attribute_value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rexml/document'
|
3
|
+
require File.join(File.dirname(__FILE__), 'all_parser_wrappers_spec')
|
4
|
+
|
5
|
+
describe "the REXML parser wrapper class" do
|
6
|
+
before(:each) do
|
7
|
+
@raw_xml = "<root type='test'>\n <child>Name</child>\n</root>"
|
8
|
+
rexml = REXML::Document.new(@raw_xml)
|
9
|
+
@wrapper = Peachy::Parsers::REXMLWrapper.new rexml.root
|
10
|
+
@expected_wrapper_class = Peachy::Parsers::REXMLWrapper
|
11
|
+
end
|
12
|
+
|
13
|
+
it_should_behave_like "all parser wrappers"
|
14
|
+
end
|
@@ -17,7 +17,7 @@ XML
|
|
17
17
|
|
18
18
|
it "should define a method from a pascal cased element name" do
|
19
19
|
@proxy.root.test_node.value.should == 'Check meh.'
|
20
|
-
@proxy.root.methods.should include
|
20
|
+
@proxy.root.methods.should include('test_node')
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should match a method to an attribute by pascal case" do
|
@@ -26,12 +26,12 @@ XML
|
|
26
26
|
|
27
27
|
it "should define a method from pascal cased attribute name" do
|
28
28
|
@proxy.root.second_node.record_label
|
29
|
-
@proxy.root.second_node.methods.should include
|
29
|
+
@proxy.root.second_node.methods.should include('record_label')
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should define a method on a parent with attributes" do
|
33
33
|
@proxy.root.third_node.record_label.should == 'Wall of Sound'
|
34
|
-
@proxy.root.third_node.methods.should include
|
34
|
+
@proxy.root.third_node.methods.should include('record_label')
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should allow child nodes to be selected after an attrbiute is selected on a parent node" do
|
data/spec/proxy_spec.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "stringifying a Proxy" do
|
4
|
+
it "should return the stringified underlying parser wrapper" do
|
5
|
+
expected_string = "<some><xml>XML!!</xml></some>"
|
6
|
+
stub_wrapper = mock()
|
7
|
+
stub_wrapper.stubs(:to_s).returns(expected_string)
|
8
|
+
stub_wrapper.stubs(:kind_of?).with(String).returns(false)
|
9
|
+
stub_wrapper.stubs(:kind_of?).with(Peachy::Parsers::ParserWrapper).returns(true)
|
10
|
+
proxy = Peachy::Proxy.new stub_wrapper
|
11
|
+
|
12
|
+
proxy.to_s.should == expected_string
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return the XML that is passed in to the consructor" do
|
16
|
+
expected_string = "<some><xml>XML!!</xml></some>"
|
17
|
+
proxy = Peachy::Proxy.new expected_string
|
18
|
+
proxy.to_s.should == expected_string
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -1,45 +1,51 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
|
2
3
|
describe "Peachy::SimpleContent wrapper for the contents of a simple XML element" do
|
3
4
|
before(:each) do
|
4
|
-
@
|
5
|
-
|
5
|
+
@expected_to_s = "<blar>boo</blar>"
|
6
|
+
mock_wrapper = mock()
|
7
|
+
mock_wrapper.stubs(:name).returns('real_node')
|
8
|
+
mock_wrapper.stubs(:content).returns('the real value')
|
9
|
+
mock_wrapper.stubs(:to_s).returns(@expected_to_s)
|
10
|
+
@content = Peachy::SimpleContent.new mock_wrapper
|
6
11
|
end
|
7
12
|
|
8
13
|
it "should return the expected content" do
|
9
|
-
@content.value.should == 'the value'
|
14
|
+
@content.value.should == 'the real value'
|
10
15
|
end
|
11
16
|
|
12
17
|
it "should to_s in the expected way" do
|
13
|
-
@content.to_s.should ==
|
18
|
+
@content.to_s.should == @expected_to_s
|
14
19
|
end
|
15
20
|
|
16
21
|
it "should return the value from the index of 0" do
|
17
22
|
item = @content[0]
|
18
|
-
item.value.should == 'the value'
|
23
|
+
item.value.should == 'the real value'
|
19
24
|
end
|
20
25
|
|
21
26
|
it "should make the name of the parent node available" do
|
22
|
-
@content.
|
27
|
+
@content.name.should == 'real_node'
|
23
28
|
end
|
24
29
|
|
25
30
|
it "should raise an error if the SimpleContent is treated as an Array after being treated as SimpleContent" do
|
26
|
-
|
27
|
-
|
28
|
-
The 'parent_node' node has already been accessed as a single child, but you are now trying to use it as a collection.
|
31
|
+
expected_message = <<MESSAGE
|
32
|
+
The 'real_node' node has already been accessed as a single child, but you are now trying to use it as a collection.
|
29
33
|
Do not try to access Peachy::Proxies in a mixed manner in your implementation.
|
30
34
|
MESSAGE
|
35
|
+
@content.value
|
36
|
+
lambda { @content[0].value }.should raise_error(AlreadyAnOnlyChild, expected_message)
|
31
37
|
end
|
32
38
|
|
33
39
|
it "should behave as other objects when a method does not exist" do
|
34
|
-
lambda { @content.how_random }.should raise_error
|
40
|
+
lambda { @content.how_random }.should raise_error(NoMethodError)
|
35
41
|
end
|
36
42
|
|
37
43
|
it "should behave as other objects when a method with a parameter does not exist" do
|
38
|
-
lambda { @content.how_random("Hello") }.should raise_error
|
44
|
+
lambda { @content.how_random("Hello") }.should raise_error(NoMethodError)
|
39
45
|
end
|
40
46
|
|
41
47
|
it "should behave as other objects when a method with a block does not exist" do
|
42
|
-
lambda { @content.how_random() { puts "Boo!" } }.should raise_error
|
48
|
+
lambda { @content.how_random() { puts "Boo!" } }.should raise_error(NoMethodError)
|
43
49
|
end
|
44
50
|
end
|
45
51
|
|
@@ -19,7 +19,6 @@ XML
|
|
19
19
|
|
20
20
|
element_as_array = @proxy.xml.list.item
|
21
21
|
element_as_array.any?.should be_true
|
22
|
-
element_as_array.one?.should be_true
|
23
22
|
element_as_array.empty?.should be_false
|
24
23
|
element_as_array.size.should == 1
|
25
24
|
(element_as_array.map {|item| item.value }).should == ['Hello']
|
@@ -27,10 +26,11 @@ XML
|
|
27
26
|
end
|
28
27
|
|
29
28
|
it "should raise an error if the element value has already been accessed as an only child" do
|
30
|
-
|
31
|
-
lambda { @proxy.xml.list.item[0] }.should raise_error AlreadyAnOnlyChild, <<MSG
|
29
|
+
expected_message = <<MSG
|
32
30
|
The 'item' node has already been accessed as a single child, but you are now trying to use it as a collection.
|
33
31
|
Do not try to access Peachy::Proxies in a mixed manner in your implementation.
|
34
32
|
MSG
|
33
|
+
@proxy.xml.list.item.value
|
34
|
+
lambda { @proxy.xml.list.item[0] }.should raise_error(AlreadyAnOnlyChild, expected_message)
|
35
35
|
end
|
36
36
|
end
|
@@ -10,7 +10,7 @@ describe "a simple XML collection should be interpretted as an array" do
|
|
10
10
|
|
11
11
|
it "should define a method for the item list name" do
|
12
12
|
@proxy.xml.stuff.item
|
13
|
-
@proxy.xml.stuff.methods.should include
|
13
|
+
@proxy.xml.stuff.methods.should include('item')
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should set each array item to the content for the list item" do
|
@@ -8,19 +8,21 @@ describe "using Peachy::Proxy incorrectly" do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should raise an error if the method name is not in Ruby convention" do
|
11
|
-
|
11
|
+
expected_message = <<EOF
|
12
12
|
You've tried to infer testNode using Peachy, but Peachy doesn't currently like defining methods that break Ruby convention.
|
13
13
|
Please use methods matching ^[a-z]+(?:_[a-z]+)?{0,}$ and Peachy will try to do the rest with your XML.*/
|
14
14
|
EOF
|
15
|
+
lambda { @proxy.testNode }.should raise_error(MethodNotInRubyConvention, expected_message)
|
15
16
|
end
|
16
17
|
|
17
18
|
it "should throw an InvalidProxyParameters error if an incorrect type of parameter was passed as the initializer argument" do
|
18
|
-
|
19
|
-
lambda { invalid_proxy.boom }.should raise_error InvalidProxyParameters, <<EOF
|
19
|
+
expected_message = <<EOF
|
20
20
|
The parameters that you passed to the Proxy were invalid.
|
21
21
|
:nokogiri = nil
|
22
22
|
:xml = nil
|
23
23
|
EOF
|
24
|
+
invalid_proxy = Peachy::Proxy.new Hash.new
|
25
|
+
lambda { invalid_proxy.boom }.should raise_error(InvalidProxyParameters, expected_message)
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 2
|
9
|
+
version: 0.3.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- NJ Pearman
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-31 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -32,7 +32,6 @@ extra_rdoc_files:
|
|
32
32
|
- README.rdoc
|
33
33
|
files:
|
34
34
|
- lib/peachy/xml_node.rb
|
35
|
-
- lib/peachy/convention_checks.rb
|
36
35
|
- lib/peachy/childless_proxy_with_attributes.rb
|
37
36
|
- lib/peachy/method_name.rb
|
38
37
|
- lib/peachy/mimic.rb
|
@@ -50,6 +49,7 @@ files:
|
|
50
49
|
- lib/peachy/morph_into_array.rb
|
51
50
|
- lib/peachy/my_meta_class.rb
|
52
51
|
- lib/peachy/string_styler.rb
|
52
|
+
- lib/nothing_to_mimic.rb
|
53
53
|
- lib/no_matching_xml_part.rb
|
54
54
|
- lib/invalid_proxy_parameters.rb
|
55
55
|
- lib/method_not_in_ruby_convention.rb
|
@@ -57,6 +57,7 @@ files:
|
|
57
57
|
- lib/peachy.rb
|
58
58
|
- spec/nokogiri_is_the_available_xml_parser_spec.rb
|
59
59
|
- spec/hyphen_separated_names_spec.rb
|
60
|
+
- spec/proxy_spec.rb
|
60
61
|
- spec/elements_referenced_as_collections_spec.rb
|
61
62
|
- spec/simple_content_wrapper_for_Peachy_spec.rb
|
62
63
|
- spec/collections_with_children_as_arrays_spec.rb
|
@@ -65,13 +66,17 @@ files:
|
|
65
66
|
- spec/simple_xml_collections_as_arrays_spec.rb
|
66
67
|
- spec/simple_element_referenced_as_collections_spec.rb
|
67
68
|
- spec/using_peachy_proxy_incorrectly_spec.rb
|
69
|
+
- spec/mimc_spec.rb
|
68
70
|
- spec/inferring_a_method_from_an_attribute_spec.rb
|
69
71
|
- spec/camel_case_names_spec.rb
|
70
72
|
- spec/attributes_on_a_parent_node_spec.rb
|
71
73
|
- spec/pascal_case_names_spec.rb
|
72
74
|
- spec/peachy_spec.rb
|
73
75
|
- spec/only_rexml_is_available_spec.rb
|
76
|
+
- spec/parsers/rexml_attribute_wrapper_spec.rb
|
74
77
|
- spec/parsers/all_parser_wrappers_spec.rb
|
78
|
+
- spec/parsers/nokigiri_wrapper_spec.rb
|
79
|
+
- spec/parsers/rexml_wrapper_spec.rb
|
75
80
|
- spec/inferring_a_method_from_element_name_spec.rb
|
76
81
|
- spec/spec_helper.rb
|
77
82
|
- spec/nested_elements_spec.rb
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Peachy
|
2
|
-
module ConventionChecks
|
3
|
-
private
|
4
|
-
# Checks whether the provided method name is in the accepted convention,
|
5
|
-
# raising a MethodNotInRubyConvention if it's not.
|
6
|
-
def check_for_convention method_name
|
7
|
-
raise MethodNotInRubyConvention.new(method_name) unless matches_convention(method_name)
|
8
|
-
end
|
9
|
-
|
10
|
-
# Checks whether the given method name matches the Ruby convention of
|
11
|
-
# lowercase with underscores. This method does not allow question marks,
|
12
|
-
# excalmation marks or numbers, however.
|
13
|
-
def matches_convention method_name
|
14
|
-
method_name.to_s =~ /^[a-z]+(?:_[a-z]+){0,}$/
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|