lzell-mapricot 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +3 -0
 - data/License.txt +19 -0
 - data/README.rdoc +118 -0
 - data/examples/lastfm_api.rb +41 -0
 - data/examples/lastfm_api_no_request.rb +126 -0
 - data/examples/natural_inputs.rb +22 -0
 - data/examples/readme_examples.rb +82 -0
 - data/lib/mapricot.rb +174 -0
 - data/mapricot.gemspec +28 -0
 - data/test/mapricot_spec.rb +118 -0
 - data/test/mapricot_tests.rb +109 -0
 - metadata +76 -0
 
    
        data/History.txt
    ADDED
    
    
    
        data/License.txt
    ADDED
    
    | 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2009 Louis Zell <lzell11@gmail.com>
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
      
 4 
     | 
    
         
            +
            of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
      
 5 
     | 
    
         
            +
            in the Software without restriction, including without limitation the rights
         
     | 
| 
      
 6 
     | 
    
         
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 7 
     | 
    
         
            +
            copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
      
 8 
     | 
    
         
            +
            furnished to do so, subject to the following conditions:
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be included in
         
     | 
| 
      
 11 
     | 
    
         
            +
            all copies or substantial portions of the Software.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 14 
     | 
    
         
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
      
 15 
     | 
    
         
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
      
 16 
     | 
    
         
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
      
 17 
     | 
    
         
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
      
 18 
     | 
    
         
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
      
 19 
     | 
    
         
            +
            THE SOFTWARE.
         
     | 
    
        data/README.rdoc
    ADDED
    
    | 
         @@ -0,0 +1,118 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            == Mapricot
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Makes working with XML stupid easy.  XML to object mapper with an interface similar to ActiveRecord associations.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            == Install
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            Do some stuff...
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            == Usage
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            Your classes should inherit from Mapricot::Base, which provides the class methods 
         
     | 
| 
      
 13 
     | 
    
         
            +
            * has_one(name, type, opts = {})
         
     | 
| 
      
 14 
     | 
    
         
            +
            * has_many(name, type, opts = {})
         
     | 
| 
      
 15 
     | 
    
         
            +
            * has_attribute(name)
         
     | 
| 
      
 16 
     | 
    
         
            +
              
         
     | 
| 
      
 17 
     | 
    
         
            +
            When you instantiate a Mapricot::Base object, you can pass it a string of xml:
         
     | 
| 
      
 18 
     | 
    
         
            +
              class MapMe < Mapricot::Base
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
              
         
     | 
| 
      
 21 
     | 
    
         
            +
              MapMe.new :xml => "<some_stuff>...</some_stuff>"
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            Or you can pass it a url:
         
     | 
| 
      
 24 
     | 
    
         
            +
              class MapMeToo < Mapricot::Base
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
              
         
     | 
| 
      
 27 
     | 
    
         
            +
              MapMeToo.new :url => "http://some_url"
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            == Examples
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            ==== Super Simple
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              simple_xml = %(
         
     | 
| 
      
 34 
     | 
    
         
            +
                <user>
         
     | 
| 
      
 35 
     | 
    
         
            +
                  <id>1</name>
         
     | 
| 
      
 36 
     | 
    
         
            +
                  <name>Bob</name>
         
     | 
| 
      
 37 
     | 
    
         
            +
                  <pet>cat</pet>
         
     | 
| 
      
 38 
     | 
    
         
            +
                  <pet>dog</pet>
         
     | 
| 
      
 39 
     | 
    
         
            +
                </user>
         
     | 
| 
      
 40 
     | 
    
         
            +
              )
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              class User < Mapricot::Base
         
     | 
| 
      
 43 
     | 
    
         
            +
                has_one   :id,    :integer
         
     | 
| 
      
 44 
     | 
    
         
            +
                has_one   :name,  :string
         
     | 
| 
      
 45 
     | 
    
         
            +
                has_many  :pets,  :string
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              user = User.new(:xml => simple_xml)
         
     | 
| 
      
 49 
     | 
    
         
            +
              puts user.id                # => 1
         
     | 
| 
      
 50 
     | 
    
         
            +
              puts user.id.class          # => Fixnum
         
     | 
| 
      
 51 
     | 
    
         
            +
              puts user.name              # => Bob
         
     | 
| 
      
 52 
     | 
    
         
            +
              puts user.pets.class        # => Array
         
     | 
| 
      
 53 
     | 
    
         
            +
              puts user.pets.join(", ")   # => cat, dog
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            ==== A little more realistic
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
              xml = %(
         
     | 
| 
      
 59 
     | 
    
         
            +
                <user>
         
     | 
| 
      
 60 
     | 
    
         
            +
                  <id>2</name>
         
     | 
| 
      
 61 
     | 
    
         
            +
                  <name>Sally</name>
         
     | 
| 
      
 62 
     | 
    
         
            +
                  <location code="ny123">
         
     | 
| 
      
 63 
     | 
    
         
            +
                    <city>New York</city>
         
     | 
| 
      
 64 
     | 
    
         
            +
                    <state>NY</state>
         
     | 
| 
      
 65 
     | 
    
         
            +
                  </location>
         
     | 
| 
      
 66 
     | 
    
         
            +
                  <hobby>
         
     | 
| 
      
 67 
     | 
    
         
            +
                    <description>Skiing</description>
         
     | 
| 
      
 68 
     | 
    
         
            +
                    <number_of_years>2</number_of_years>
         
     | 
| 
      
 69 
     | 
    
         
            +
                  </hobby>
         
     | 
| 
      
 70 
     | 
    
         
            +
                  <hobby>
         
     | 
| 
      
 71 
     | 
    
         
            +
                    <description>Hiking</description>
         
     | 
| 
      
 72 
     | 
    
         
            +
                    <number_of_years>3</number_of_years>
         
     | 
| 
      
 73 
     | 
    
         
            +
                  </hobby>
         
     | 
| 
      
 74 
     | 
    
         
            +
                </user>
         
     | 
| 
      
 75 
     | 
    
         
            +
              )
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
              class User < Mapricot::Base
         
     | 
| 
      
 79 
     | 
    
         
            +
                has_one   :id,        :integer
         
     | 
| 
      
 80 
     | 
    
         
            +
                has_one   :name       # Tag type will default to :string
         
     | 
| 
      
 81 
     | 
    
         
            +
                has_many  :pets
         
     | 
| 
      
 82 
     | 
    
         
            +
                has_one   :location,  :xml
         
     | 
| 
      
 83 
     | 
    
         
            +
                has_many  :hobbies,   :xml
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
              class Location < Mapricot::Base
         
     | 
| 
      
 87 
     | 
    
         
            +
                has_attribute :code
         
     | 
| 
      
 88 
     | 
    
         
            +
                has_one       :city
         
     | 
| 
      
 89 
     | 
    
         
            +
                has_one       :state
         
     | 
| 
      
 90 
     | 
    
         
            +
              end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
              class Hobby < Mapricot::Base
         
     | 
| 
      
 93 
     | 
    
         
            +
                has_one :description,     :string
         
     | 
| 
      
 94 
     | 
    
         
            +
                has_one :number_of_years, :integer
         
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
              user = User.new(:xml => xml)
         
     | 
| 
      
 98 
     | 
    
         
            +
              puts user.name            # => Sally
         
     | 
| 
      
 99 
     | 
    
         
            +
              puts user.pets.inspect    # => []
         
     | 
| 
      
 100 
     | 
    
         
            +
              puts user.location.class  # => Location
         
     | 
| 
      
 101 
     | 
    
         
            +
              puts user.location.city   # => New York
         
     | 
| 
      
 102 
     | 
    
         
            +
              puts user.location.state  # => NY
         
     | 
| 
      
 103 
     | 
    
         
            +
              puts user.location.code   # => ny123
         
     | 
| 
      
 104 
     | 
    
         
            +
              puts user.hobbies.class         # => Array
         
     | 
| 
      
 105 
     | 
    
         
            +
              puts user.hobbies.first.class   # => Hobby
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
              user.hobbies.each do |hobby|
         
     | 
| 
      
 108 
     | 
    
         
            +
                puts "#{hobby.description} for #{hobby.number_of_years} years"
         
     | 
| 
      
 109 
     | 
    
         
            +
              end
         
     | 
| 
      
 110 
     | 
    
         
            +
              # => Skiing for 2 years
         
     | 
| 
      
 111 
     | 
    
         
            +
              # => Hiking for 3 years
         
     | 
| 
      
 112 
     | 
    
         
            +
              
         
     | 
| 
      
 113 
     | 
    
         
            +
            == Credits
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
            All to why the luck stiff for Hpricot.
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            Copyright (c) 2009 Lou Zell, released under the MIT license
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Get events in nyc with:
         
     | 
| 
      
 2 
     | 
    
         
            +
            # http://ws.audioscrobbler.com/2.0/?method=geo.getevents&city=new+york&api_key=YOUR_API_KEY_HERE
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            # The point of this is to demonstrate mapping xml from a real api response.
         
     | 
| 
      
 5 
     | 
    
         
            +
            # The only difference is you instantiate with:
         
     | 
| 
      
 6 
     | 
    
         
            +
            # Response.new(:url => "http://someurl")
         
     | 
| 
      
 7 
     | 
    
         
            +
            # instead of:
         
     | 
| 
      
 8 
     | 
    
         
            +
            # Response.new(:xml => "some string of xml")
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            # If you do not have an API key, see examples/lastfm_api_no_request.rb
         
     | 
| 
      
 11 
     | 
    
         
            +
            require '../lib/mapricot'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            class Response < Mapricot::Base
         
     | 
| 
      
 14 
     | 
    
         
            +
              has_many :events,   :xml
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            class Event < Mapricot::Base
         
     | 
| 
      
 18 
     | 
    
         
            +
              has_one :title
         
     | 
| 
      
 19 
     | 
    
         
            +
              has_one :venue,   :xml
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            class Venue < Mapricot::Base
         
     | 
| 
      
 23 
     | 
    
         
            +
              has_one :name
         
     | 
| 
      
 24 
     | 
    
         
            +
              has_one :location, :xml
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            class Location < Mapricot::Base
         
     | 
| 
      
 28 
     | 
    
         
            +
              has_one :city
         
     | 
| 
      
 29 
     | 
    
         
            +
              has_one :country
         
     | 
| 
      
 30 
     | 
    
         
            +
              has_one :street
         
     | 
| 
      
 31 
     | 
    
         
            +
              has_one :postalcode,  :integer
         
     | 
| 
      
 32 
     | 
    
         
            +
            end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            response = Response.new(:url => "http://ws.audioscrobbler.com/2.0/?method=geo.getevents&city=new+york&api_key=#{YOUR_API_KEY_HERE}")
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            response.events.each do |event|
         
     | 
| 
      
 37 
     | 
    
         
            +
              puts "-------------"
         
     | 
| 
      
 38 
     | 
    
         
            +
              puts event.title
         
     | 
| 
      
 39 
     | 
    
         
            +
              puts event.venue.name
         
     | 
| 
      
 40 
     | 
    
         
            +
              puts event.venue.location.city
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,126 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require '../lib/mapricot'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            last_fm_example = %(
         
     | 
| 
      
 5 
     | 
    
         
            +
            <?xml version="1.0" encoding="utf-8"?>
         
     | 
| 
      
 6 
     | 
    
         
            +
            <lfm status="ok">
         
     | 
| 
      
 7 
     | 
    
         
            +
            <events location="New York, United States" page="1" totalpages="92" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" total="917">
         
     | 
| 
      
 8 
     | 
    
         
            +
            <event>
         
     | 
| 
      
 9 
     | 
    
         
            +
              <id>895664</id>
         
     | 
| 
      
 10 
     | 
    
         
            +
              <title>Lydia</title>
         
     | 
| 
      
 11 
     | 
    
         
            +
              <artists>
         
     | 
| 
      
 12 
     | 
    
         
            +
                <artist>Lydia</artist>
         
     | 
| 
      
 13 
     | 
    
         
            +
                <artist>Black Gold</artist>
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                <headliner>Lydia</headliner>
         
     | 
| 
      
 16 
     | 
    
         
            +
              </artists>
         
     | 
| 
      
 17 
     | 
    
         
            +
              <venue>
         
     | 
| 
      
 18 
     | 
    
         
            +
                <name>Mercury Lounge</name>
         
     | 
| 
      
 19 
     | 
    
         
            +
                <location>
         
     | 
| 
      
 20 
     | 
    
         
            +
                  <city>New York</city>
         
     | 
| 
      
 21 
     | 
    
         
            +
                  <country>United States</country>
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  <street>217 East Houston Street</street>
         
     | 
| 
      
 24 
     | 
    
         
            +
                  <postalcode>10002</postalcode>
         
     | 
| 
      
 25 
     | 
    
         
            +
                  <geo:point>
         
     | 
| 
      
 26 
     | 
    
         
            +
                     <geo:lat>40.722024</geo:lat>
         
     | 
| 
      
 27 
     | 
    
         
            +
                     <geo:long>-73.98682</geo:long>
         
     | 
| 
      
 28 
     | 
    
         
            +
                  </geo:point>
         
     | 
| 
      
 29 
     | 
    
         
            +
                          <timezone>EST</timezone>
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                      </location>
         
     | 
| 
      
 32 
     | 
    
         
            +
                <url>http://www.last.fm/venue/8899833</url>
         
     | 
| 
      
 33 
     | 
    
         
            +
              </venue>
         
     | 
| 
      
 34 
     | 
    
         
            +
              <startDate>Thu, 05 Mar 2009</startDate>
         
     | 
| 
      
 35 
     | 
    
         
            +
              <startTime>18:30</startTime>
         
     | 
| 
      
 36 
     | 
    
         
            +
              <description><![CDATA[<div class="bbcode">On Sale Fri 1/16 at Noon<br />
         
     | 
| 
      
 37 
     | 
    
         
            +
            21+<br />
         
     | 
| 
      
 38 
     | 
    
         
            +
            $10<br />
         
     | 
| 
      
 39 
     | 
    
         
            +
            Doors 6:30pm/ Show 7:30pm</div>]]></description>
         
     | 
| 
      
 40 
     | 
    
         
            +
              <image size="small">http://userserve-ak.last.fm/serve/34/9158303.jpg</image>
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              <image size="medium">http://userserve-ak.last.fm/serve/64/9158303.jpg</image>
         
     | 
| 
      
 43 
     | 
    
         
            +
              <image size="large">http://userserve-ak.last.fm/serve/126/9158303.jpg</image>
         
     | 
| 
      
 44 
     | 
    
         
            +
               <attendance>7</attendance>
         
     | 
| 
      
 45 
     | 
    
         
            +
               <reviews>0</reviews>
         
     | 
| 
      
 46 
     | 
    
         
            +
               <tag>lastfm:event=895664</tag>  
         
     | 
| 
      
 47 
     | 
    
         
            +
              <url>http://www.last.fm/event/895664</url>
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            </event>
         
     | 
| 
      
 50 
     | 
    
         
            +
            <event>
         
     | 
| 
      
 51 
     | 
    
         
            +
              <id>924763</id>
         
     | 
| 
      
 52 
     | 
    
         
            +
              <title>Stars Like Fleas</title>
         
     | 
| 
      
 53 
     | 
    
         
            +
              <artists>
         
     | 
| 
      
 54 
     | 
    
         
            +
                <artist>Stars Like Fleas</artist>
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                <artist>Frances</artist>
         
     | 
| 
      
 57 
     | 
    
         
            +
                <artist>twi the humble feather</artist>
         
     | 
| 
      
 58 
     | 
    
         
            +
                <artist>La Strada</artist>
         
     | 
| 
      
 59 
     | 
    
         
            +
                <headliner>Stars Like Fleas</headliner>
         
     | 
| 
      
 60 
     | 
    
         
            +
              </artists>
         
     | 
| 
      
 61 
     | 
    
         
            +
              <venue>
         
     | 
| 
      
 62 
     | 
    
         
            +
                <name>Music Hall of Williamsburg</name>
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                <location>
         
     | 
| 
      
 65 
     | 
    
         
            +
                  <city>Brooklyn, NY</city>
         
     | 
| 
      
 66 
     | 
    
         
            +
                  <country>United States</country>
         
     | 
| 
      
 67 
     | 
    
         
            +
                  <street>66 North 6th Street</street>
         
     | 
| 
      
 68 
     | 
    
         
            +
                  <postalcode>11211</postalcode>
         
     | 
| 
      
 69 
     | 
    
         
            +
                  <geo:point>
         
     | 
| 
      
 70 
     | 
    
         
            +
                     <geo:lat>40.719308</geo:lat>
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                     <geo:long>-73.961607</geo:long>
         
     | 
| 
      
 73 
     | 
    
         
            +
                  </geo:point>
         
     | 
| 
      
 74 
     | 
    
         
            +
                          <timezone>EST</timezone>
         
     | 
| 
      
 75 
     | 
    
         
            +
                      </location>
         
     | 
| 
      
 76 
     | 
    
         
            +
                <url>http://www.last.fm/venue/8851989</url>
         
     | 
| 
      
 77 
     | 
    
         
            +
              </venue>
         
     | 
| 
      
 78 
     | 
    
         
            +
              <startDate>Thu, 05 Mar 2009</startDate>
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
              <startTime>19:00</startTime>
         
     | 
| 
      
 81 
     | 
    
         
            +
              <description><![CDATA[<div class="bbcode">Doors 7 p.m. / Show 8 p.m.<br />
         
     | 
| 
      
 82 
     | 
    
         
            +
            $10 advance / $12 day of show<br />
         
     | 
| 
      
 83 
     | 
    
         
            +
            18+<br />
         
     | 
| 
      
 84 
     | 
    
         
            +
            <br />
         
     | 
| 
      
 85 
     | 
    
         
            +
            On sale Wed. 2/4 at noon</div>]]></description>
         
     | 
| 
      
 86 
     | 
    
         
            +
              <image size="small">http://userserve-ak.last.fm/serve/34/3598785.jpg</image>
         
     | 
| 
      
 87 
     | 
    
         
            +
              <image size="medium">http://userserve-ak.last.fm/serve/64/3598785.jpg</image>
         
     | 
| 
      
 88 
     | 
    
         
            +
              <image size="large">http://userserve-ak.last.fm/serve/126/3598785.jpg</image>
         
     | 
| 
      
 89 
     | 
    
         
            +
               <attendance>1</attendance>
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
               <reviews>0</reviews>
         
     | 
| 
      
 92 
     | 
    
         
            +
               <tag>lastfm:event=924763</tag>  
         
     | 
| 
      
 93 
     | 
    
         
            +
              <url>http://www.last.fm/event/924763</url>
         
     | 
| 
      
 94 
     | 
    
         
            +
            </event>
         
     | 
| 
      
 95 
     | 
    
         
            +
            </events></lfm>
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            )
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            class Response < Mapricot::Base
         
     | 
| 
      
 101 
     | 
    
         
            +
              has_many :events, :xml
         
     | 
| 
      
 102 
     | 
    
         
            +
            end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            class Event < Mapricot::Base
         
     | 
| 
      
 105 
     | 
    
         
            +
              has_one :id,              :integer
         
     | 
| 
      
 106 
     | 
    
         
            +
              has_one :title,           :string
         
     | 
| 
      
 107 
     | 
    
         
            +
              has_one :artist_group,    :xml,       :tag_name => "artists"
         
     | 
| 
      
 108 
     | 
    
         
            +
              has_one :venue,           :xml
         
     | 
| 
      
 109 
     | 
    
         
            +
            end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            class ArtistGroup < Mapricot::Base
         
     | 
| 
      
 112 
     | 
    
         
            +
              has_many  :artists,       :string
         
     | 
| 
      
 113 
     | 
    
         
            +
              has_one   :headliner,     :string
         
     | 
| 
      
 114 
     | 
    
         
            +
            end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            class Venue < Mapricot::Base
         
     | 
| 
      
 117 
     | 
    
         
            +
              has_one   :name,          :string
         
     | 
| 
      
 118 
     | 
    
         
            +
            end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            lfm = Response.new(:xml => last_fm_example)
         
     | 
| 
      
 121 
     | 
    
         
            +
            lfm.events.each do |event|
         
     | 
| 
      
 122 
     | 
    
         
            +
              puts "-------------------------------"
         
     | 
| 
      
 123 
     | 
    
         
            +
              puts event.title
         
     | 
| 
      
 124 
     | 
    
         
            +
              puts event.artist_group.artists.inspect
         
     | 
| 
      
 125 
     | 
    
         
            +
              puts event.venue.name
         
     | 
| 
      
 126 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Coming soon!
         
     | 
| 
      
 2 
     | 
    
         
            +
            # class NaturalInputs < Mapricot
         
     | 
| 
      
 3 
     | 
    
         
            +
            #   has_one   :message, :string
         
     | 
| 
      
 4 
     | 
    
         
            +
            #   has_many  :occurrences, :xml
         
     | 
| 
      
 5 
     | 
    
         
            +
            # end
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            #
         
     | 
| 
      
 8 
     | 
    
         
            +
            # class Occurrence < Mapricot::Base
         
     | 
| 
      
 9 
     | 
    
         
            +
            #   has_one   :start_date
         
     | 
| 
      
 10 
     | 
    
         
            +
            #   has_one   :end_date
         
     | 
| 
      
 11 
     | 
    
         
            +
            #   has_one   :interval
         
     | 
| 
      
 12 
     | 
    
         
            +
            #   has_one   :day_of_week
         
     | 
| 
      
 13 
     | 
    
         
            +
            #   has_one   :week_of_month
         
     | 
| 
      
 14 
     | 
    
         
            +
            #   has_one   :start_time
         
     | 
| 
      
 15 
     | 
    
         
            +
            #   has_one   :end_time
         
     | 
| 
      
 16 
     | 
    
         
            +
            #   has_one   :date_of_month
         
     | 
| 
      
 17 
     | 
    
         
            +
            # end
         
     | 
| 
      
 18 
     | 
    
         
            +
            # 
         
     | 
| 
      
 19 
     | 
    
         
            +
            # 
         
     | 
| 
      
 20 
     | 
    
         
            +
            # n = NaturalInputs.new("http://localhost:3000/query?q=lunch+this+friday+with+maria")
         
     | 
| 
      
 21 
     | 
    
         
            +
            # puts n.message # => "lunch with maria"
         
     | 
| 
      
 22 
     | 
    
         
            +
            # puts n.occurrences.first.start_date # => "2009-01-16"
         
     | 
| 
         @@ -0,0 +1,82 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require '../lib/mapricot'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # super simple
         
     | 
| 
      
 4 
     | 
    
         
            +
            simple_xml = %(
         
     | 
| 
      
 5 
     | 
    
         
            +
              <user>
         
     | 
| 
      
 6 
     | 
    
         
            +
                <id>1</name>
         
     | 
| 
      
 7 
     | 
    
         
            +
                <name>Bob</name>
         
     | 
| 
      
 8 
     | 
    
         
            +
                <pet>cat</pet>
         
     | 
| 
      
 9 
     | 
    
         
            +
                <pet>dog</pet>
         
     | 
| 
      
 10 
     | 
    
         
            +
              </user>
         
     | 
| 
      
 11 
     | 
    
         
            +
            )
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            class User < Mapricot::Base
         
     | 
| 
      
 14 
     | 
    
         
            +
              has_one   :id,    :integer
         
     | 
| 
      
 15 
     | 
    
         
            +
              has_one   :name,  :string
         
     | 
| 
      
 16 
     | 
    
         
            +
              has_many  :pets,  :string
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            user = User.new(:xml => simple_xml)
         
     | 
| 
      
 20 
     | 
    
         
            +
            puts user.id                # => 1
         
     | 
| 
      
 21 
     | 
    
         
            +
            puts user.id.class          # => Fixnum
         
     | 
| 
      
 22 
     | 
    
         
            +
            puts user.name              # => Bob
         
     | 
| 
      
 23 
     | 
    
         
            +
            puts user.pets.class        # => Array
         
     | 
| 
      
 24 
     | 
    
         
            +
            puts user.pets.join(", ")   # => cat, dog
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            puts "-------------------"
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            # A little more realistic
         
     | 
| 
      
 29 
     | 
    
         
            +
            xml = %(
         
     | 
| 
      
 30 
     | 
    
         
            +
              <user>
         
     | 
| 
      
 31 
     | 
    
         
            +
                <id>2</name>
         
     | 
| 
      
 32 
     | 
    
         
            +
                <name>Sally</name>
         
     | 
| 
      
 33 
     | 
    
         
            +
                <location code="ny123">
         
     | 
| 
      
 34 
     | 
    
         
            +
                  <city>New York</city>
         
     | 
| 
      
 35 
     | 
    
         
            +
                  <state>NY</state>
         
     | 
| 
      
 36 
     | 
    
         
            +
                </location>
         
     | 
| 
      
 37 
     | 
    
         
            +
                <hobby>
         
     | 
| 
      
 38 
     | 
    
         
            +
                  <description>Skiing</description>
         
     | 
| 
      
 39 
     | 
    
         
            +
                  <number_of_years>2</number_of_years>
         
     | 
| 
      
 40 
     | 
    
         
            +
                </hobby>
         
     | 
| 
      
 41 
     | 
    
         
            +
                <hobby>
         
     | 
| 
      
 42 
     | 
    
         
            +
                  <description>Hiking</description>
         
     | 
| 
      
 43 
     | 
    
         
            +
                  <number_of_years>3</number_of_years>
         
     | 
| 
      
 44 
     | 
    
         
            +
                </hobby>
         
     | 
| 
      
 45 
     | 
    
         
            +
              </user>
         
     | 
| 
      
 46 
     | 
    
         
            +
            )
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            class User < Mapricot::Base
         
     | 
| 
      
 50 
     | 
    
         
            +
              has_one   :id,        :integer
         
     | 
| 
      
 51 
     | 
    
         
            +
              has_one   :name       # Tag type will default to :string
         
     | 
| 
      
 52 
     | 
    
         
            +
              has_many  :pets
         
     | 
| 
      
 53 
     | 
    
         
            +
              has_one   :location,  :xml
         
     | 
| 
      
 54 
     | 
    
         
            +
              has_many  :hobbies,   :xml
         
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            class Location < Mapricot::Base
         
     | 
| 
      
 58 
     | 
    
         
            +
              has_attribute :code
         
     | 
| 
      
 59 
     | 
    
         
            +
              has_one       :city
         
     | 
| 
      
 60 
     | 
    
         
            +
              has_one       :state
         
     | 
| 
      
 61 
     | 
    
         
            +
            end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            class Hobby < Mapricot::Base
         
     | 
| 
      
 64 
     | 
    
         
            +
              has_one :description,     :string
         
     | 
| 
      
 65 
     | 
    
         
            +
              has_one :number_of_years, :integer
         
     | 
| 
      
 66 
     | 
    
         
            +
            end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            user = User.new(:xml => xml)
         
     | 
| 
      
 69 
     | 
    
         
            +
            puts user.name            # => Sally
         
     | 
| 
      
 70 
     | 
    
         
            +
            puts user.pets.inspect    # => []
         
     | 
| 
      
 71 
     | 
    
         
            +
            puts user.location.class  # => Location
         
     | 
| 
      
 72 
     | 
    
         
            +
            puts user.location.city   # => New York
         
     | 
| 
      
 73 
     | 
    
         
            +
            puts user.location.state  # => NY
         
     | 
| 
      
 74 
     | 
    
         
            +
            puts user.location.code   # => ny123
         
     | 
| 
      
 75 
     | 
    
         
            +
            puts user.hobbies.class         # => Array
         
     | 
| 
      
 76 
     | 
    
         
            +
            puts user.hobbies.first.class   # => Hobby
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            user.hobbies.each do |hobby|
         
     | 
| 
      
 79 
     | 
    
         
            +
              puts "#{hobby.description} for #{hobby.number_of_years} years"
         
     | 
| 
      
 80 
     | 
    
         
            +
            end
         
     | 
| 
      
 81 
     | 
    
         
            +
            # => Skiing for 2 years
         
     | 
| 
      
 82 
     | 
    
         
            +
            # => Hiking for 3 years
         
     | 
    
        data/lib/mapricot.rb
    ADDED
    
    | 
         @@ -0,0 +1,174 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'open-uri'
         
     | 
| 
      
 2 
     | 
    
         
            +
            begin
         
     | 
| 
      
 3 
     | 
    
         
            +
              require 'hpricot'
         
     | 
| 
      
 4 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 5 
     | 
    
         
            +
              require 'rubygems'
         
     | 
| 
      
 6 
     | 
    
         
            +
              require 'hpricot'
         
     | 
| 
      
 7 
     | 
    
         
            +
            end
         
     | 
| 
      
 8 
     | 
    
         
            +
            # singularize, constantize, camelize, classify; doc here: http://api.rubyonrails.com/classes/Inflector.html
         
     | 
| 
      
 9 
     | 
    
         
            +
            require 'active_support/inflector'
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            module Mapricot
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              # Inherit from base, e.g. class Animal < Mapricot::Base
         
     | 
| 
      
 14 
     | 
    
         
            +
              # Use either a string of xml or a url to initialize
         
     | 
| 
      
 15 
     | 
    
         
            +
              class Base
         
     | 
| 
      
 16 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # @associations is used to initialize instance variables
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # creates a new HasOneAssociation and appends it to the @associations list
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def has_one(name, type = :string, opts = {})
         
     | 
| 
      
 20 
     | 
    
         
            +
                    ass = HasOneAssociation.new(name, type, opts)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    self.name.match(/::/) && ass.namespace = self.name.match(/(.*)::[^:]+$/)[1]
         
     | 
| 
      
 22 
     | 
    
         
            +
                    associations << ass
         
     | 
| 
      
 23 
     | 
    
         
            +
                    class_eval "attr_reader :#{name}", __FILE__, __LINE__
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  # creates a new HasManyAssociation and appends it to the @associations list
         
     | 
| 
      
 26 
     | 
    
         
            +
                  def has_many(name, type = :string, opts = {})
         
     | 
| 
      
 27 
     | 
    
         
            +
                    ass = HasManyAssociation.new(name, type, opts)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    self.name.match(/::/) && ass.namespace = self.name.match(/(.*)::[^:]+$/)[1]
         
     | 
| 
      
 29 
     | 
    
         
            +
                    associations << ass
         
     | 
| 
      
 30 
     | 
    
         
            +
                    class_eval "attr_reader :#{name}", __FILE__, __LINE__
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  def has_attribute(name)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    attributes << name
         
     | 
| 
      
 34 
     | 
    
         
            +
                    class_eval "attr_reader :#{name}", __FILE__, __LINE__
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
                  def associations
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @associations ||= []
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
                  def attributes
         
     | 
| 
      
 40 
     | 
    
         
            +
                    @attributes ||= []
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                # class SomeClass < Mapricot::Base; end;
         
     | 
| 
      
 45 
     | 
    
         
            +
                # SomeClass.new :url => "http://some_url"
         
     | 
| 
      
 46 
     | 
    
         
            +
                # SomeClass.new :xml => %(<hi></hi>)
         
     | 
| 
      
 47 
     | 
    
         
            +
                def initialize(opts)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  @xml = Hpricot::XML(open(opts[:url])) if opts[:url]
         
     | 
| 
      
 49 
     | 
    
         
            +
                  @xml = Hpricot::XML(opts[:xml]) if opts[:xml]
         
     | 
| 
      
 50 
     | 
    
         
            +
                  load_associations   
         
     | 
| 
      
 51 
     | 
    
         
            +
                  load_attributes
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
                
         
     | 
| 
      
 54 
     | 
    
         
            +
                # searches xml for a tag with association.name, sets association.value to the inner html of this tag and typecasts it
         
     | 
| 
      
 55 
     | 
    
         
            +
                def load_has_one(has_one_association)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  has_one_association.search(@xml)
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
                
         
     | 
| 
      
 59 
     | 
    
         
            +
                def load_has_many(has_many_association)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  has_many_association.search(@xml)
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
              
         
     | 
| 
      
 63 
     | 
    
         
            +
                def load_associations
         
     | 
| 
      
 64 
     | 
    
         
            +
                  # loop through the class's instance variable @attributes, which holds all of our associations
         
     | 
| 
      
 65 
     | 
    
         
            +
                  association_list = self.class.instance_variable_get(:@associations)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  association_list && association_list.each do |ass|
         
     | 
| 
      
 67 
     | 
    
         
            +
                    load_has_one(ass) if ass.is_a?(HasOneAssociation)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    load_has_many(ass) if ass.is_a?(HasManyAssociation)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    # set instance variables and create accessors for each
         
     | 
| 
      
 70 
     | 
    
         
            +
                    instance_variable_set("@#{ass.name}", ass.value)  
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
                
         
     | 
| 
      
 74 
     | 
    
         
            +
                def load_attributes
         
     | 
| 
      
 75 
     | 
    
         
            +
                  attr_list = self.class.instance_variable_get(:@attributes)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  attr_list && attr_list.each do |att|
         
     | 
| 
      
 77 
     | 
    
         
            +
                    val = (@xml/self.class.name.downcase.match(/[^:]+$/)[0]).first.attributes[att.to_s]
         
     | 
| 
      
 78 
     | 
    
         
            +
                    instance_variable_set("@#{att}", val)
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
              
         
     | 
| 
      
 83 
     | 
    
         
            +
              # Abstract class; used to subclass HasOneAssociation and HasManyAssociation
         
     | 
| 
      
 84 
     | 
    
         
            +
              class Association
         
     | 
| 
      
 85 
     | 
    
         
            +
                VALID_TYPES = [:integer, :time, :xml, :string]
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                attr_accessor :name, :type, :value
         
     | 
| 
      
 88 
     | 
    
         
            +
                attr_accessor :namespace
         
     | 
| 
      
 89 
     | 
    
         
            +
                def initialize(name, type, opts = {})
         
     | 
| 
      
 90 
     | 
    
         
            +
                  raise "Don't instantiate me" if abstract_class?
         
     | 
| 
      
 91 
     | 
    
         
            +
                  @name, @type, @opts = name, type, opts
         
     | 
| 
      
 92 
     | 
    
         
            +
                  @namespace = nil
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
              
         
     | 
| 
      
 95 
     | 
    
         
            +
                def typecast
         
     | 
| 
      
 96 
     | 
    
         
            +
                  raise "association type is invalid" unless VALID_TYPES.include?(@type)
         
     | 
| 
      
 97 
     | 
    
         
            +
                  if [:integer, :time].include?(@type)
         
     | 
| 
      
 98 
     | 
    
         
            +
                    @value = self.send("typecast_#{@type}")
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
      
 100 
     | 
    
         
            +
                end
         
     | 
| 
      
 101 
     | 
    
         
            +
                
         
     | 
| 
      
 102 
     | 
    
         
            +
                def typecast_integer
         
     | 
| 
      
 103 
     | 
    
         
            +
                  @value.is_a?(Array) ? @value.collect {|v| v.to_i} : @value.to_i
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
                
         
     | 
| 
      
 106 
     | 
    
         
            +
                def typecast_time
         
     | 
| 
      
 107 
     | 
    
         
            +
                  if @value.is_a?(Array)
         
     | 
| 
      
 108 
     | 
    
         
            +
                    @value.collect {|v| Time.parse(v) }
         
     | 
| 
      
 109 
     | 
    
         
            +
                  else
         
     | 
| 
      
 110 
     | 
    
         
            +
                    Time.parse(@value)
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
                end
         
     | 
| 
      
 113 
     | 
    
         
            +
                
         
     | 
| 
      
 114 
     | 
    
         
            +
                private
         
     | 
| 
      
 115 
     | 
    
         
            +
                def abstract_class?
         
     | 
| 
      
 116 
     | 
    
         
            +
                  self.class == Association
         
     | 
| 
      
 117 
     | 
    
         
            +
                end
         
     | 
| 
      
 118 
     | 
    
         
            +
                
         
     | 
| 
      
 119 
     | 
    
         
            +
                def singular_name
         
     | 
| 
      
 120 
     | 
    
         
            +
                  @name.to_s
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
                
         
     | 
| 
      
 123 
     | 
    
         
            +
                def class_from_name
         
     | 
| 
      
 124 
     | 
    
         
            +
                  # ok, first we have to find how the class that inherited from Mapricot::Base is namespaced
         
     | 
| 
      
 125 
     | 
    
         
            +
                  # the class will an @associations class instance var, that will hold an instance of 
         
     | 
| 
      
 126 
     | 
    
         
            +
                  if @namespace
         
     | 
| 
      
 127 
     | 
    
         
            +
                    "#{@namespace}::#{singular_name.classify}".constantize
         
     | 
| 
      
 128 
     | 
    
         
            +
                  else
         
     | 
| 
      
 129 
     | 
    
         
            +
                    singular_name.classify.constantize
         
     | 
| 
      
 130 
     | 
    
         
            +
                  end
         
     | 
| 
      
 131 
     | 
    
         
            +
                end
         
     | 
| 
      
 132 
     | 
    
         
            +
              end
         
     | 
| 
      
 133 
     | 
    
         
            +
              
         
     | 
| 
      
 134 
     | 
    
         
            +
              
         
     | 
| 
      
 135 
     | 
    
         
            +
              class HasOneAssociation < Association
         
     | 
| 
      
 136 
     | 
    
         
            +
                # searches xml for tag name, sets the inner xml as association value and typecasts it
         
     | 
| 
      
 137 
     | 
    
         
            +
                def search(xml)
         
     | 
| 
      
 138 
     | 
    
         
            +
                  # if tag_name option was passed, use it:
         
     | 
| 
      
 139 
     | 
    
         
            +
                  element = (xml/"#{ @opts[:tag_name] || @name }").first      # class Hpricot::Elements
         
     | 
| 
      
 140 
     | 
    
         
            +
                  if element
         
     | 
| 
      
 141 
     | 
    
         
            +
                    if @type == :xml
         
     | 
| 
      
 142 
     | 
    
         
            +
                      @value = class_from_name.new(:xml => element.to_s)    # we want to include the tag, not just the inner_html
         
     | 
| 
      
 143 
     | 
    
         
            +
                    else
         
     | 
| 
      
 144 
     | 
    
         
            +
                      @value = element.inner_html
         
     | 
| 
      
 145 
     | 
    
         
            +
                    end
         
     | 
| 
      
 146 
     | 
    
         
            +
                    self.typecast
         
     | 
| 
      
 147 
     | 
    
         
            +
                  end
         
     | 
| 
      
 148 
     | 
    
         
            +
                end
         
     | 
| 
      
 149 
     | 
    
         
            +
              end
         
     | 
| 
      
 150 
     | 
    
         
            +
              
         
     | 
| 
      
 151 
     | 
    
         
            +
              
         
     | 
| 
      
 152 
     | 
    
         
            +
              class HasManyAssociation < Association
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                def singular_name
         
     | 
| 
      
 155 
     | 
    
         
            +
                  # @name.to_s[0..-2]
         
     | 
| 
      
 156 
     | 
    
         
            +
                  "#{@name}".singularize
         
     | 
| 
      
 157 
     | 
    
         
            +
                end
         
     | 
| 
      
 158 
     | 
    
         
            +
                
         
     | 
| 
      
 159 
     | 
    
         
            +
                # searches xml for all occurrences of self.singular_name, the inner xml from each tag is stored in an array and set as the association value
         
     | 
| 
      
 160 
     | 
    
         
            +
                # finally, each element in the array is typecast
         
     | 
| 
      
 161 
     | 
    
         
            +
                def search(xml)
         
     | 
| 
      
 162 
     | 
    
         
            +
                  @value = []
         
     | 
| 
      
 163 
     | 
    
         
            +
                  (xml/"#{@opts[:tag_name] || self.singular_name}").each do |tag|
         
     | 
| 
      
 164 
     | 
    
         
            +
                    if @type == :xml
         
     | 
| 
      
 165 
     | 
    
         
            +
                      @value << class_from_name.new(:xml => tag.to_s)  # a bit of recursion if the inner xml is more xml
         
     | 
| 
      
 166 
     | 
    
         
            +
                    else
         
     | 
| 
      
 167 
     | 
    
         
            +
                      @value << tag.inner_html   # in the case of a string, integer, etc.
         
     | 
| 
      
 168 
     | 
    
         
            +
                    end
         
     | 
| 
      
 169 
     | 
    
         
            +
                  end
         
     | 
| 
      
 170 
     | 
    
         
            +
                end
         
     | 
| 
      
 171 
     | 
    
         
            +
                
         
     | 
| 
      
 172 
     | 
    
         
            +
              end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
            end
         
     | 
    
        data/mapricot.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Gem::Specification.new do |s|
         
     | 
| 
      
 2 
     | 
    
         
            +
              s.name     = "mapricot"
         
     | 
| 
      
 3 
     | 
    
         
            +
              s.version  = "0.0.1"
         
     | 
| 
      
 4 
     | 
    
         
            +
              s.date     = "2009-03-06"
         
     | 
| 
      
 5 
     | 
    
         
            +
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         
     | 
| 
      
 6 
     | 
    
         
            +
              s.summary  = "XML to object mapper"
         
     | 
| 
      
 7 
     | 
    
         
            +
              s.email    = "lzell11@gmail.com"
         
     | 
| 
      
 8 
     | 
    
         
            +
              s.homepage = ""
         
     | 
| 
      
 9 
     | 
    
         
            +
            	s.description = "Makes working with XML stupid easy.  XML to object mapper with an interface similar to ActiveRecord associations."
         
     | 
| 
      
 10 
     | 
    
         
            +
              s.has_rdoc = true
         
     | 
| 
      
 11 
     | 
    
         
            +
              s.authors  = ["Lou Zell"]
         
     | 
| 
      
 12 
     | 
    
         
            +
              s.files    = ["README.rdoc", 
         
     | 
| 
      
 13 
     | 
    
         
            +
                  "History.txt",
         
     | 
| 
      
 14 
     | 
    
         
            +
                  "License.txt",
         
     | 
| 
      
 15 
     | 
    
         
            +
                  "mapricot.gemspec",
         
     | 
| 
      
 16 
     | 
    
         
            +
                  "examples/lastfm_api.rb",
         
     | 
| 
      
 17 
     | 
    
         
            +
                  "examples/lastfm_api_no_request.rb",
         
     | 
| 
      
 18 
     | 
    
         
            +
                  "examples/natural_inputs.rb",
         
     | 
| 
      
 19 
     | 
    
         
            +
                  "examples/readme_examples.rb",
         
     | 
| 
      
 20 
     | 
    
         
            +
                  "test/mapricot_tests.rb",
         
     | 
| 
      
 21 
     | 
    
         
            +
                  "test/mapricot_spec.rb",
         
     | 
| 
      
 22 
     | 
    
         
            +
                  "lib/mapricot.rb"]
         
     | 
| 
      
 23 
     | 
    
         
            +
              s.require_paths = ["lib"]
         
     | 
| 
      
 24 
     | 
    
         
            +
              s.rdoc_options = ["--main", "README.rdoc", "--inline-source", "--title", "Mapricot"]
         
     | 
| 
      
 25 
     | 
    
         
            +
              s.extra_rdoc_files = ["README.rdoc"]
         
     | 
| 
      
 26 
     | 
    
         
            +
              s.add_dependency("hpricot")
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,118 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require '../lib/mapricot'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'spec'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            # Using a Facebook example:
         
     | 
| 
      
 5 
     | 
    
         
            +
            XML = %(
         
     | 
| 
      
 6 
     | 
    
         
            +
            <?xml version="1.0" encoding="UTF-8"?>
         
     | 
| 
      
 7 
     | 
    
         
            +
              <users_getInfo_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/ http://api.facebook.com/1.0/facebook.xsd" list="true">
         
     | 
| 
      
 8 
     | 
    
         
            +
                <user>
         
     | 
| 
      
 9 
     | 
    
         
            +
                  <uid>8055</uid>
         
     | 
| 
      
 10 
     | 
    
         
            +
                  <about_me>This field perpetuates the glorification of the ego. Also, it has a character limit.</about_me>
         
     | 
| 
      
 11 
     | 
    
         
            +
                  <activities>Here: facebook, etc. There: Glee Club, a capella, teaching.</activities>
         
     | 
| 
      
 12 
     | 
    
         
            +
                  <affiliations list="true">
         
     | 
| 
      
 13 
     | 
    
         
            +
                    <affiliation>
         
     | 
| 
      
 14 
     | 
    
         
            +
                      <nid>50453093</nid>
         
     | 
| 
      
 15 
     | 
    
         
            +
                      <name>Facebook Developers</name>
         
     | 
| 
      
 16 
     | 
    
         
            +
                      <type>work</type>
         
     | 
| 
      
 17 
     | 
    
         
            +
                      <status/>
         
     | 
| 
      
 18 
     | 
    
         
            +
                      <year/>
         
     | 
| 
      
 19 
     | 
    
         
            +
                    </affiliation>
         
     | 
| 
      
 20 
     | 
    
         
            +
                  </affiliations>
         
     | 
| 
      
 21 
     | 
    
         
            +
                  <birthday>November 3</birthday>
         
     | 
| 
      
 22 
     | 
    
         
            +
                  <books>The Brothers K, GEB, Ken Wilber, Zen and the Art, Fitzgerald, The Emporer's New Mind, The Wonderful Story of Henry Sugar</books>
         
     | 
| 
      
 23 
     | 
    
         
            +
                  <current_location>
         
     | 
| 
      
 24 
     | 
    
         
            +
                    <city>Palo Alto</city>
         
     | 
| 
      
 25 
     | 
    
         
            +
                    <state>CA</state>
         
     | 
| 
      
 26 
     | 
    
         
            +
                    <country>United States</country>
         
     | 
| 
      
 27 
     | 
    
         
            +
                    <zip>94303</zip>
         
     | 
| 
      
 28 
     | 
    
         
            +
                  </current_location> 
         
     | 
| 
      
 29 
     | 
    
         
            +
                </user>
         
     | 
| 
      
 30 
     | 
    
         
            +
              </users_getInfo_reponse>
         
     | 
| 
      
 31 
     | 
    
         
            +
            )
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            class UsersGetInfoResponse < Mapricot::Base
         
     | 
| 
      
 35 
     | 
    
         
            +
              has_many :users,    :xml
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            class User < Mapricot::Base
         
     | 
| 
      
 39 
     | 
    
         
            +
              has_one :uid,               :integer
         
     | 
| 
      
 40 
     | 
    
         
            +
              has_one :about_me,          :string
         
     | 
| 
      
 41 
     | 
    
         
            +
              has_one :activities,        :string
         
     | 
| 
      
 42 
     | 
    
         
            +
              has_one :affiliation_list,  :xml,     :tag_name => "affiliations"   # this is cumbersome, do something about this
         
     | 
| 
      
 43 
     | 
    
         
            +
              has_one :birthday,          :string
         
     | 
| 
      
 44 
     | 
    
         
            +
              has_one :current_location,  :xml
         
     | 
| 
      
 45 
     | 
    
         
            +
            end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            class AffiliationList < Mapricot::Base
         
     | 
| 
      
 48 
     | 
    
         
            +
              has_many :affiliations,     :xml
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            class Affiliation < Mapricot::Base
         
     | 
| 
      
 52 
     | 
    
         
            +
              has_one :nid,     :integer
         
     | 
| 
      
 53 
     | 
    
         
            +
              has_one :name,    :string
         
     | 
| 
      
 54 
     | 
    
         
            +
              has_one :type,    :string
         
     | 
| 
      
 55 
     | 
    
         
            +
              has_one :status,  :string
         
     | 
| 
      
 56 
     | 
    
         
            +
              has_one :year,    :integer
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            class CurrentLocation < Mapricot::Base
         
     | 
| 
      
 60 
     | 
    
         
            +
              has_one :city,    :string
         
     | 
| 
      
 61 
     | 
    
         
            +
              has_one :state,   :string
         
     | 
| 
      
 62 
     | 
    
         
            +
              has_one :country, :string
         
     | 
| 
      
 63 
     | 
    
         
            +
              has_one :zip,     :integer
         
     | 
| 
      
 64 
     | 
    
         
            +
            end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            describe UsersGetInfoResponse do 
         
     | 
| 
      
 68 
     | 
    
         
            +
              before(:all) { @response = UsersGetInfoResponse.new(:xml => XML) }
         
     | 
| 
      
 69 
     | 
    
         
            +
              
         
     | 
| 
      
 70 
     | 
    
         
            +
              it "should respond to users" do 
         
     | 
| 
      
 71 
     | 
    
         
            +
                @response.should respond_to(:users)
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
              
         
     | 
| 
      
 74 
     | 
    
         
            +
              it "should return an array of size 1 when sent users" do 
         
     | 
| 
      
 75 
     | 
    
         
            +
                @response.users.class.should equal(Array)
         
     | 
| 
      
 76 
     | 
    
         
            +
                @response.users.size.should equal(1)
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
            end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            describe "response.users.first" do 
         
     | 
| 
      
 81 
     | 
    
         
            +
              before(:all) do 
         
     | 
| 
      
 82 
     | 
    
         
            +
                response = UsersGetInfoResponse.new(:xml => XML)
         
     | 
| 
      
 83 
     | 
    
         
            +
                @first_user = response.users.first
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
              
         
     | 
| 
      
 86 
     | 
    
         
            +
              it "should be of class User" do
         
     | 
| 
      
 87 
     | 
    
         
            +
                @first_user.class.should equal(User)
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
              
         
     | 
| 
      
 90 
     | 
    
         
            +
              it "should respond to activities" do 
         
     | 
| 
      
 91 
     | 
    
         
            +
                @first_user.should respond_to(:activities)
         
     | 
| 
      
 92 
     | 
    
         
            +
                @first_user.activities.should == "Here: facebook, etc. There: Glee Club, a capella, teaching."
         
     | 
| 
      
 93 
     | 
    
         
            +
              end
         
     | 
| 
      
 94 
     | 
    
         
            +
              
         
     | 
| 
      
 95 
     | 
    
         
            +
              it "should respond to current_location" do 
         
     | 
| 
      
 96 
     | 
    
         
            +
                @first_user.should respond_to(:current_location)
         
     | 
| 
      
 97 
     | 
    
         
            +
              end
         
     | 
| 
      
 98 
     | 
    
         
            +
            end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            describe "response.users.first.current_location" do 
         
     | 
| 
      
 102 
     | 
    
         
            +
              before(:all) do 
         
     | 
| 
      
 103 
     | 
    
         
            +
                response = UsersGetInfoResponse.new(:xml => XML)
         
     | 
| 
      
 104 
     | 
    
         
            +
                @current_location = response.users.first.current_location
         
     | 
| 
      
 105 
     | 
    
         
            +
              end
         
     | 
| 
      
 106 
     | 
    
         
            +
              
         
     | 
| 
      
 107 
     | 
    
         
            +
              it "should have class CurrentLocation" do 
         
     | 
| 
      
 108 
     | 
    
         
            +
                @current_location.class.should equal(CurrentLocation)
         
     | 
| 
      
 109 
     | 
    
         
            +
              end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
              it "should respond to city, state, country, and zip" do 
         
     | 
| 
      
 112 
     | 
    
         
            +
                @current_location.city.should == 'Palo Alto'
         
     | 
| 
      
 113 
     | 
    
         
            +
                @current_location.state.should == 'CA'
         
     | 
| 
      
 114 
     | 
    
         
            +
                @current_location.country.should == 'United States'
         
     | 
| 
      
 115 
     | 
    
         
            +
                @current_location.zip.should == 94303
         
     | 
| 
      
 116 
     | 
    
         
            +
              end
         
     | 
| 
      
 117 
     | 
    
         
            +
            end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,109 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require '../lib/mapricot'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'test/unit'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            # -------------------------- Test Example 1 of README.txt ------------------ #
         
     | 
| 
      
 6 
     | 
    
         
            +
            SIMPLE_USER_XML = %(
         
     | 
| 
      
 7 
     | 
    
         
            +
              <user>
         
     | 
| 
      
 8 
     | 
    
         
            +
                <id>1</name>
         
     | 
| 
      
 9 
     | 
    
         
            +
                <name>Bob</name>
         
     | 
| 
      
 10 
     | 
    
         
            +
                <pet>cat</pet>
         
     | 
| 
      
 11 
     | 
    
         
            +
                <pet>dog</pet>
         
     | 
| 
      
 12 
     | 
    
         
            +
              </user>
         
     | 
| 
      
 13 
     | 
    
         
            +
            )
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            class SimpleUser < Mapricot::Base
         
     | 
| 
      
 16 
     | 
    
         
            +
              has_one   :id,    :integer
         
     | 
| 
      
 17 
     | 
    
         
            +
              has_one   :name,  :string
         
     | 
| 
      
 18 
     | 
    
         
            +
              has_many  :pets,  :string
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            class TestSimpleUser < Test::Unit::TestCase
         
     | 
| 
      
 23 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 24 
     | 
    
         
            +
                @simple_user = SimpleUser.new(:xml => SIMPLE_USER_XML)
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
              
         
     | 
| 
      
 27 
     | 
    
         
            +
              def test_everything
         
     | 
| 
      
 28 
     | 
    
         
            +
                assert_equal @simple_user.id,   1
         
     | 
| 
      
 29 
     | 
    
         
            +
                assert_equal @simple_user.name, "Bob"
         
     | 
| 
      
 30 
     | 
    
         
            +
                assert_equal @simple_user.pets, ["cat", "dog"]
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
            end
         
     | 
| 
      
 33 
     | 
    
         
            +
            # -------------------------------------------------------------------------- #
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            # -------------------------- Test Example 2 of README.txt ------------------ #
         
     | 
| 
      
 40 
     | 
    
         
            +
            USER_XML = %(
         
     | 
| 
      
 41 
     | 
    
         
            +
              <user>
         
     | 
| 
      
 42 
     | 
    
         
            +
                <id>2</name>
         
     | 
| 
      
 43 
     | 
    
         
            +
                <name>Sally</name>
         
     | 
| 
      
 44 
     | 
    
         
            +
                <location code="ny123">
         
     | 
| 
      
 45 
     | 
    
         
            +
                  <city>New York</city>
         
     | 
| 
      
 46 
     | 
    
         
            +
                  <state>NY</state>
         
     | 
| 
      
 47 
     | 
    
         
            +
                </location>
         
     | 
| 
      
 48 
     | 
    
         
            +
                <hobby>
         
     | 
| 
      
 49 
     | 
    
         
            +
                  <description>Skiing</description>
         
     | 
| 
      
 50 
     | 
    
         
            +
                  <number_of_years>2</number_of_years>
         
     | 
| 
      
 51 
     | 
    
         
            +
                </hobby>
         
     | 
| 
      
 52 
     | 
    
         
            +
                <hobby>
         
     | 
| 
      
 53 
     | 
    
         
            +
                  <description>Hiking</description>
         
     | 
| 
      
 54 
     | 
    
         
            +
                  <number_of_years>3</number_of_years>
         
     | 
| 
      
 55 
     | 
    
         
            +
                </hobby>
         
     | 
| 
      
 56 
     | 
    
         
            +
              </user>
         
     | 
| 
      
 57 
     | 
    
         
            +
            )
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            class User < Mapricot::Base
         
     | 
| 
      
 61 
     | 
    
         
            +
              has_one   :id,        :integer
         
     | 
| 
      
 62 
     | 
    
         
            +
              has_one   :name       # Tag type will default to :string
         
     | 
| 
      
 63 
     | 
    
         
            +
              has_many  :pets
         
     | 
| 
      
 64 
     | 
    
         
            +
              has_one   :location,  :xml
         
     | 
| 
      
 65 
     | 
    
         
            +
              has_many  :hobbies,   :xml
         
     | 
| 
      
 66 
     | 
    
         
            +
            end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            class Location < Mapricot::Base
         
     | 
| 
      
 69 
     | 
    
         
            +
              has_attribute :code
         
     | 
| 
      
 70 
     | 
    
         
            +
              has_one       :city
         
     | 
| 
      
 71 
     | 
    
         
            +
              has_one       :state
         
     | 
| 
      
 72 
     | 
    
         
            +
            end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            class Hobby < Mapricot::Base
         
     | 
| 
      
 75 
     | 
    
         
            +
              has_one :description,     :string
         
     | 
| 
      
 76 
     | 
    
         
            +
              has_one :number_of_years, :integer
         
     | 
| 
      
 77 
     | 
    
         
            +
            end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            class TestUser < Test::Unit::TestCase
         
     | 
| 
      
 80 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 81 
     | 
    
         
            +
                @user = User.new(:xml => USER_XML)
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
              
         
     | 
| 
      
 84 
     | 
    
         
            +
              def test_id_and_name
         
     | 
| 
      
 85 
     | 
    
         
            +
                assert_equal @user.id,    2
         
     | 
| 
      
 86 
     | 
    
         
            +
                assert_equal @user.name,  "Sally"
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
              
         
     | 
| 
      
 89 
     | 
    
         
            +
              def test_location
         
     | 
| 
      
 90 
     | 
    
         
            +
                assert        @user.location.is_a?(Location)
         
     | 
| 
      
 91 
     | 
    
         
            +
                assert_equal  @user.location.city,   "New York"
         
     | 
| 
      
 92 
     | 
    
         
            +
                assert_equal  @user.location.state,  "NY"
         
     | 
| 
      
 93 
     | 
    
         
            +
                assert_equal  @user.location.code,   "ny123"
         
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
              
         
     | 
| 
      
 96 
     | 
    
         
            +
              def test_hobbies
         
     | 
| 
      
 97 
     | 
    
         
            +
                assert        @user.hobbies.is_a?(Array)
         
     | 
| 
      
 98 
     | 
    
         
            +
                assert_equal  @user.hobbies.size,                2
         
     | 
| 
      
 99 
     | 
    
         
            +
                assert_equal  @user.hobbies[0].description,      "Skiing"
         
     | 
| 
      
 100 
     | 
    
         
            +
                assert_equal  @user.hobbies[0].number_of_years,  2
         
     | 
| 
      
 101 
     | 
    
         
            +
                assert_equal  @user.hobbies[1].description,      "Hiking"
         
     | 
| 
      
 102 
     | 
    
         
            +
                assert_equal  @user.hobbies[1].number_of_years,  3
         
     | 
| 
      
 103 
     | 
    
         
            +
              end
         
     | 
| 
      
 104 
     | 
    
         
            +
              
         
     | 
| 
      
 105 
     | 
    
         
            +
              def test_pets
         
     | 
| 
      
 106 
     | 
    
         
            +
                assert(@user.pets.empty?) # Sally has no pets
         
     | 
| 
      
 107 
     | 
    
         
            +
              end
         
     | 
| 
      
 108 
     | 
    
         
            +
            end  
         
     | 
| 
      
 109 
     | 
    
         
            +
            # -------------------------------------------------------------------------- #
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,76 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: lzell-mapricot
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.0.1
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Lou Zell
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2009-03-06 00:00:00 -08:00
         
     | 
| 
      
 13 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 14 
     | 
    
         
            +
            dependencies: 
         
     | 
| 
      
 15 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 16 
     | 
    
         
            +
              name: hpricot
         
     | 
| 
      
 17 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 18 
     | 
    
         
            +
              version_requirement: 
         
     | 
| 
      
 19 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 20 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 21 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 22 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 23 
     | 
    
         
            +
                    version: "0"
         
     | 
| 
      
 24 
     | 
    
         
            +
                version: 
         
     | 
| 
      
 25 
     | 
    
         
            +
            description: Makes working with XML stupid easy.  XML to object mapper with an interface similar to ActiveRecord associations.
         
     | 
| 
      
 26 
     | 
    
         
            +
            email: lzell11@gmail.com
         
     | 
| 
      
 27 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            extra_rdoc_files: 
         
     | 
| 
      
 32 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 33 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 34 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 35 
     | 
    
         
            +
            - History.txt
         
     | 
| 
      
 36 
     | 
    
         
            +
            - License.txt
         
     | 
| 
      
 37 
     | 
    
         
            +
            - mapricot.gemspec
         
     | 
| 
      
 38 
     | 
    
         
            +
            - examples/lastfm_api.rb
         
     | 
| 
      
 39 
     | 
    
         
            +
            - examples/lastfm_api_no_request.rb
         
     | 
| 
      
 40 
     | 
    
         
            +
            - examples/natural_inputs.rb
         
     | 
| 
      
 41 
     | 
    
         
            +
            - examples/readme_examples.rb
         
     | 
| 
      
 42 
     | 
    
         
            +
            - test/mapricot_tests.rb
         
     | 
| 
      
 43 
     | 
    
         
            +
            - test/mapricot_spec.rb
         
     | 
| 
      
 44 
     | 
    
         
            +
            - lib/mapricot.rb
         
     | 
| 
      
 45 
     | 
    
         
            +
            has_rdoc: true
         
     | 
| 
      
 46 
     | 
    
         
            +
            homepage: ""
         
     | 
| 
      
 47 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 48 
     | 
    
         
            +
            rdoc_options: 
         
     | 
| 
      
 49 
     | 
    
         
            +
            - --main
         
     | 
| 
      
 50 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 51 
     | 
    
         
            +
            - --inline-source
         
     | 
| 
      
 52 
     | 
    
         
            +
            - --title
         
     | 
| 
      
 53 
     | 
    
         
            +
            - Mapricot
         
     | 
| 
      
 54 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 55 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 56 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 57 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 58 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 59 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 60 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 61 
     | 
    
         
            +
              version: 
         
     | 
| 
      
 62 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 63 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 64 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 65 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 66 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 67 
     | 
    
         
            +
              version: 
         
     | 
| 
      
 68 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 71 
     | 
    
         
            +
            rubygems_version: 1.2.0
         
     | 
| 
      
 72 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 73 
     | 
    
         
            +
            specification_version: 2
         
     | 
| 
      
 74 
     | 
    
         
            +
            summary: XML to object mapper
         
     | 
| 
      
 75 
     | 
    
         
            +
            test_files: []
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     |