peachy 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/History.txt +11 -3
  2. data/README.rdoc +12 -4
  3. data/lib/method_not_in_ruby_convention.rb +1 -1
  4. data/lib/nothing_to_mimic.rb +2 -0
  5. data/lib/peachy.rb +1 -3
  6. data/lib/peachy/childless_proxy_with_attributes.rb +1 -1
  7. data/lib/peachy/method_mask.rb +1 -3
  8. data/lib/peachy/method_name.rb +14 -0
  9. data/lib/peachy/mimic.rb +5 -1
  10. data/lib/peachy/morph_into_array.rb +6 -4
  11. data/lib/peachy/parsers/nokogiri_wrapper.rb +4 -0
  12. data/lib/peachy/parsers/rexml_attribute_wrapper.rb +4 -0
  13. data/lib/peachy/parsers/rexml_wrapper.rb +4 -0
  14. data/lib/peachy/proxy.rb +9 -4
  15. data/lib/peachy/proxy_factory.rb +1 -1
  16. data/lib/peachy/simple_content.rb +7 -9
  17. data/lib/peachy/version.rb +2 -2
  18. data/lib/peachy/xml_node.rb +1 -1
  19. data/spec/attributes_on_a_parent_node_spec.rb +2 -2
  20. data/spec/camel_case_names_spec.rb +3 -3
  21. data/spec/childless_elements_referenced_as_collections_spec.rb +8 -5
  22. data/spec/collections_with_children_as_arrays_spec.rb +1 -1
  23. data/spec/elements_referenced_as_collections_spec.rb +3 -3
  24. data/spec/hyphen_separated_names_spec.rb +3 -3
  25. data/spec/inferring_a_method_from_an_attribute_spec.rb +2 -2
  26. data/spec/inferring_a_method_from_element_name_spec.rb +5 -4
  27. data/spec/method_name_spec.rb +22 -11
  28. data/spec/mimc_spec.rb +24 -0
  29. data/spec/nested_elements_spec.rb +2 -2
  30. data/spec/nodes_with_children_spec.rb +2 -2
  31. data/spec/nokogiri_is_the_available_xml_parser_spec.rb +1 -1
  32. data/spec/only_rexml_is_available_spec.rb +1 -1
  33. data/spec/parsers/all_parser_wrappers_spec.rb +3 -21
  34. data/spec/parsers/nokigiri_wrapper_spec.rb +15 -0
  35. data/spec/parsers/rexml_attribute_wrapper_spec.rb +14 -0
  36. data/spec/parsers/rexml_wrapper_spec.rb +14 -0
  37. data/spec/pascal_case_names_spec.rb +3 -3
  38. data/spec/proxy_spec.rb +21 -0
  39. data/spec/simple_content_wrapper_for_Peachy_spec.rb +18 -12
  40. data/spec/simple_element_referenced_as_collections_spec.rb +3 -3
  41. data/spec/simple_xml_collections_as_arrays_spec.rb +1 -1
  42. data/spec/using_peachy_proxy_incorrectly_spec.rb +5 -3
  43. metadata +9 -4
  44. data/lib/peachy/convention_checks.rb +0 -17
@@ -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
-
@@ -28,7 +28,8 @@ node name:
28
28
  puts 'Contents: ' + proxy.xml.node.value
29
29
  -> Contents: Peachy
30
30
 
31
- Either .value or .to_s can be called to get the contents of the current node.
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 parsing
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.
@@ -1,6 +1,6 @@
1
1
  class MethodNotInRubyConvention < Exception
2
2
  def initialize method_name
3
- super(MessageTemplate.gsub /method_name/, method_name.to_s)
3
+ super(MessageTemplate.gsub(/method_name/, method_name.to_s))
4
4
  end
5
5
 
6
6
  private
@@ -0,0 +1,2 @@
1
+ class NothingToMimic < Exception
2
+ end
@@ -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__), 'peachy/convention_checks')
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
@@ -8,7 +8,7 @@ module Peachy
8
8
 
9
9
  private
10
10
  def generate_method_for_xml method_name
11
- check_for_convention(method_name)
11
+ method_name.check_for_convention
12
12
  create_method_for_attribute(method_name) {|match| no_matching_xml(method_name) if match.nil? }
13
13
  end
14
14
  end
@@ -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 do |to_stay_public|
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
@@ -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
@@ -1,7 +1,11 @@
1
1
  module Peachy
2
2
  module Mimic
3
+ def mimic
4
+ raise NothingToMimic.new
5
+ end
6
+
3
7
  def method_missing method_name, *args, &block
4
- @mimicked.send(method_name, *args, &block)
8
+ mimic.send(method_name, *args, &block)
5
9
  end
6
10
  end
7
11
  end
@@ -10,14 +10,16 @@ module Peachy
10
10
  end
11
11
 
12
12
  def mimic object_to_mimic
13
- @mimicked = object_to_mimic
14
- eval_on_singleton_class { include Mimic }
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(node_name) if is_an_only_child
20
- puts "[Peachy::Proxy] So #{node_name} should be an Array, then." if Peachy.whiny?
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
@@ -45,6 +45,10 @@ module Peachy
45
45
  @nokogiri.name
46
46
  end
47
47
 
48
+ def to_s
49
+ @nokogiri.to_s
50
+ end
51
+
48
52
  private
49
53
  def xpath xpath
50
54
  @nokogiri.xpath(xpath).map{|noko_node| make_from(noko_node) }
@@ -12,6 +12,10 @@ module Peachy
12
12
  def name
13
13
  @attribute.first
14
14
  end
15
+
16
+ def to_s
17
+ @attribute.last
18
+ end
15
19
  end
16
20
  end
17
21
  end
@@ -37,6 +37,10 @@ module Peachy
37
37
  def name
38
38
  @rexml.name
39
39
  end
40
+
41
+ def to_s
42
+ @rexml.to_s
43
+ end
40
44
  end
41
45
  end
42
46
  end
@@ -1,7 +1,7 @@
1
1
  module Peachy
2
2
  class Proxy
3
3
  extend MethodMask
4
- include ConventionChecks, MorphIntoArray, MyMetaClass, XmlNode
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(method_name)
92
- attribute_content = create_attribute method_name
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, node_name)
141
+ raise NoMatchingXmlPart.new(method_name, name)
137
142
  end
138
143
  end
139
144
  end
@@ -8,7 +8,7 @@ module Peachy
8
8
  end
9
9
 
10
10
  def create_content_child match
11
- SimpleContent.new(match.content, match.name)
11
+ SimpleContent.new(match)
12
12
  end
13
13
 
14
14
  def create_proxy match
@@ -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
- def initialize value, node_name
9
- @value = value
10
- @node_name = node_name
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
- @value
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(@value, @node_name)
18
+ new_content = SimpleContent.new(@xml)
21
19
  return morph_into_array(new_content, method_name, *args, &block)
22
20
  end
23
- original_method_missing method_name, *args
21
+ super
24
22
  end
25
23
  end
26
24
  end
@@ -1,3 +1,3 @@
1
1
  module Peachy
2
- VERSION = '0.3.1'
3
- end
2
+ VERSION = '0.3.2'
3
+ end
@@ -6,7 +6,7 @@ module Peachy
6
6
  end
7
7
 
8
8
  # Returns the name of the encapsulated node.
9
- def node_name
9
+ def name
10
10
  node.name
11
11
  end
12
12
 
@@ -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 'name'
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 NoMatchingXmlPart
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 'test_node'
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 'record_label'
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 'record_label'
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
- @proxy.xml.list.item.value
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
- @proxy.xml.list.item.id
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 'item'
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
- @proxy.xml.list.item.child
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 'test_node'
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 'record_label'
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 'record_label'
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 'another'
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 NoMatchingXmlPart, "missing is not contained as a child of the node test-node."
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 NoMethodError
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 NoMethodError
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 'testnode'
29
- @another_proxy.methods.should_not include 'testnode'
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
@@ -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 'method_name'
22
- variations.should include 'methodName'
23
- variations.should include 'method-name'
24
- variations.should include 'MethodName'
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 'this_method'
35
- variations.should include 'thisMethod'
36
- variations.should include 'this-method'
37
- variations.should include 'ThisMethod'
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 'method'
46
- variations.should include 'Method'
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
@@ -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 'first'
16
- @proxy.root.first.methods.should include 'second'
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 'child'
15
- @node_to_test.methods.should include 'second_child'
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 Peachy::Parsers::NokogiriWrapper
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 Peachy::Parsers::REXMLWrapper
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 @expected_wrapper_class
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
- describe "the Nokogiri parser wrapper class" do
42
- before(:each) do
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 'test_node'
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 'record_label'
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 'record_label'
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
@@ -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
- @node_name = 'parent_node'
5
- @content = Peachy::SimpleContent.new 'the value', @node_name
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 == 'the value'
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.node_name.should == @node_name
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
- @content.value
27
- lambda { @content[0].value }.should raise_error AlreadyAnOnlyChild, <<MESSAGE
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 NoMethodError
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 NoMethodError
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 NoMethodError
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
- @proxy.xml.list.item.value
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 'item'
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
- lambda { @proxy.testNode }.should raise_error MethodNotInRubyConvention, <<EOF
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
- invalid_proxy = Peachy::Proxy.new Hash.new
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
- - 1
9
- version: 0.3.1
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-26 00:00:00 +01:00
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