blather 0.2.1 → 0.2.2
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/LICENSE +2 -0
 - data/README.rdoc +54 -29
 - data/Rakefile +94 -13
 - data/VERSION.yml +4 -0
 - data/examples/drb_client.rb +2 -4
 - data/examples/echo.rb +13 -8
 - data/examples/pubsub/cli.rb +64 -0
 - data/examples/pubsub/ping_pong.rb +18 -0
 - data/examples/pubsub/pubsub_dsl.rb +52 -0
 - data/examples/pubsub_client.rb +39 -0
 - data/examples/rosterprint.rb +14 -0
 - data/examples/xmpp4r/echo.rb +35 -0
 - data/ext/extconf.rb +65 -0
 - data/lib/blather.rb +18 -121
 - data/lib/blather/client.rb +13 -0
 - data/lib/blather/client/client.rb +165 -0
 - data/lib/blather/client/dsl.rb +99 -0
 - data/lib/blather/client/pubsub.rb +53 -0
 - data/lib/blather/client/pubsub/node.rb +27 -0
 - data/lib/blather/core_ext/active_support.rb +1 -0
 - data/lib/blather/core_ext/libxml.rb +7 -1
 - data/lib/blather/errors.rb +39 -18
 - data/lib/blather/errors/sasl_error.rb +87 -0
 - data/lib/blather/errors/stanza_error.rb +262 -0
 - data/lib/blather/errors/stream_error.rb +253 -0
 - data/lib/blather/jid.rb +9 -16
 - data/lib/blather/roster.rb +9 -0
 - data/lib/blather/roster_item.rb +7 -4
 - data/lib/blather/stanza.rb +19 -25
 - data/lib/blather/stanza/disco.rb +9 -0
 - data/lib/blather/stanza/disco/disco_info.rb +84 -0
 - data/lib/blather/stanza/disco/disco_items.rb +59 -0
 - data/lib/blather/stanza/iq.rb +16 -4
 - data/lib/blather/stanza/iq/query.rb +6 -4
 - data/lib/blather/stanza/iq/roster.rb +38 -38
 - data/lib/blather/stanza/pubsub.rb +33 -0
 - data/lib/blather/stanza/pubsub/affiliations.rb +52 -0
 - data/lib/blather/stanza/pubsub/errors.rb +9 -0
 - data/lib/blather/stanza/pubsub/event.rb +21 -0
 - data/lib/blather/stanza/pubsub/items.rb +59 -0
 - data/lib/blather/stanza/pubsub/owner.rb +9 -0
 - data/lib/blather/stanza/pubsub/subscriptions.rb +57 -0
 - data/lib/blather/stream.rb +125 -57
 - data/lib/blather/stream/client.rb +26 -0
 - data/lib/blather/stream/component.rb +34 -0
 - data/lib/blather/stream/parser.rb +17 -27
 - data/lib/blather/stream/resource.rb +21 -24
 - data/lib/blather/stream/sasl.rb +60 -37
 - data/lib/blather/stream/session.rb +12 -19
 - data/lib/blather/stream/stream_handler.rb +39 -0
 - data/lib/blather/stream/tls.rb +22 -18
 - data/lib/blather/xmpp_node.rb +91 -17
 - data/spec/blather/core_ext/libxml_spec.rb +58 -0
 - data/spec/blather/errors/sasl_error_spec.rb +56 -0
 - data/spec/blather/errors/stanza_error_spec.rb +148 -0
 - data/spec/blather/errors/stream_error_spec.rb +114 -0
 - data/spec/blather/errors_spec.rb +40 -0
 - data/spec/blather/jid_spec.rb +0 -7
 - data/spec/blather/roster_item_spec.rb +5 -0
 - data/spec/blather/roster_spec.rb +6 -6
 - data/spec/blather/stanza/discos/disco_info_spec.rb +207 -0
 - data/spec/blather/stanza/discos/disco_items_spec.rb +136 -0
 - data/spec/blather/stanza/iq/query_spec.rb +9 -2
 - data/spec/blather/stanza/iq/roster_spec.rb +117 -1
 - data/spec/blather/stanza/iq_spec.rb +29 -0
 - data/spec/blather/stanza/presence/subscription_spec.rb +12 -1
 - data/spec/blather/stanza/presence_spec.rb +29 -0
 - data/spec/blather/stanza/pubsub/affiliations_spec.rb +46 -0
 - data/spec/blather/stanza/pubsub/items_spec.rb +59 -0
 - data/spec/blather/stanza/pubsub/subscriptions_spec.rb +63 -0
 - data/spec/blather/stanza/pubsub_spec.rb +26 -0
 - data/spec/blather/stanza_spec.rb +13 -1
 - data/spec/blather/stream/client_spec.rb +787 -0
 - data/spec/blather/stream/component_spec.rb +86 -0
 - data/spec/blather/xmpp_node_spec.rb +75 -22
 - data/spec/fixtures/pubsub.rb +157 -0
 - data/spec/spec_helper.rb +6 -14
 - metadata +86 -74
 - data/CHANGELOG +0 -5
 - data/Manifest +0 -47
 - data/blather.gemspec +0 -41
 - data/lib/blather/stanza/error.rb +0 -31
 - data/spec/blather/stream_spec.rb +0 -462
 - data/spec/build_safe.rb +0 -20
 
| 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe 'Blather::Stream::Component' do
         
     | 
| 
      
 4 
     | 
    
         
            +
              class MockServer; end
         
     | 
| 
      
 5 
     | 
    
         
            +
              module ServerMock
         
     | 
| 
      
 6 
     | 
    
         
            +
                def receive_data(data)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @server ||= MockServer.new
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @server.receive_data data, self
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def mocked_server(times = nil, &block)
         
     | 
| 
      
 13 
     | 
    
         
            +
                @client ||= mock()
         
     | 
| 
      
 14 
     | 
    
         
            +
                @client.stubs(:stopped) unless @client.respond_to?(:stopped)
         
     | 
| 
      
 15 
     | 
    
         
            +
                @client.stubs(:jid=) unless @client.respond_to?(:jid=)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                MockServer.any_instance.expects(:receive_data).send(*(times ? [:times, times] : [:at_least, 1])).with &block
         
     | 
| 
      
 18 
     | 
    
         
            +
                EventMachine::run {
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # Mocked server
         
     | 
| 
      
 20 
     | 
    
         
            +
                  EventMachine::start_server '127.0.0.1', 12345, ServerMock
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  # Stream connection
         
     | 
| 
      
 23 
     | 
    
         
            +
                  EM.connect('127.0.0.1', 12345, Stream::Component, @client, @jid || 'comp.id', 'secret') { |c| @stream = c }
         
     | 
| 
      
 24 
     | 
    
         
            +
                }
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              it 'can be started' do
         
     | 
| 
      
 28 
     | 
    
         
            +
                client = mock()
         
     | 
| 
      
 29 
     | 
    
         
            +
                params = [client, 'comp.id', 'secret', 'host', 1234]
         
     | 
| 
      
 30 
     | 
    
         
            +
                EM.expects(:connect).with do |*parms|
         
     | 
| 
      
 31 
     | 
    
         
            +
                  parms[0] == 'host'    &&
         
     | 
| 
      
 32 
     | 
    
         
            +
                  parms[1] == 1234      &&
         
     | 
| 
      
 33 
     | 
    
         
            +
                  parms[3] == client    &&
         
     | 
| 
      
 34 
     | 
    
         
            +
                  parms[4] == 'comp.id'
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                Stream::Component.start *params
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              it 'shakes hands with the server' do
         
     | 
| 
      
 41 
     | 
    
         
            +
                state = nil
         
     | 
| 
      
 42 
     | 
    
         
            +
                mocked_server(2) do |val, server|
         
     | 
| 
      
 43 
     | 
    
         
            +
                  case state
         
     | 
| 
      
 44 
     | 
    
         
            +
                  when nil
         
     | 
| 
      
 45 
     | 
    
         
            +
                    state = :started
         
     | 
| 
      
 46 
     | 
    
         
            +
                    server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams' id='12345'>"
         
     | 
| 
      
 47 
     | 
    
         
            +
                    val.must_match(/stream:stream/)
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  when :started
         
     | 
| 
      
 50 
     | 
    
         
            +
                    server.send_data '<handshake/>'
         
     | 
| 
      
 51 
     | 
    
         
            +
                    EM.stop
         
     | 
| 
      
 52 
     | 
    
         
            +
                    val.must_equal "<handshake>#{Digest::SHA1.hexdigest('12345'+"secret")}</handshake>"
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
              it 'starts the stream once the connection is complete' do
         
     | 
| 
      
 59 
     | 
    
         
            +
                mocked_server(1) { |val, _| EM.stop; val.must_match(/stream:stream/) }
         
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
              it 'sends stanzas to the client when the stream is ready' do
         
     | 
| 
      
 63 
     | 
    
         
            +
                @client = mock(:stream_started)
         
     | 
| 
      
 64 
     | 
    
         
            +
                @client.expects(:call).with do |n|
         
     | 
| 
      
 65 
     | 
    
         
            +
                  EM.stop
         
     | 
| 
      
 66 
     | 
    
         
            +
                  n.kind_of?(Stanza::Message) && @stream.ready?.must_equal(true)
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                state = nil
         
     | 
| 
      
 70 
     | 
    
         
            +
                mocked_server(2) do |val, server|
         
     | 
| 
      
 71 
     | 
    
         
            +
                  case state
         
     | 
| 
      
 72 
     | 
    
         
            +
                  when nil
         
     | 
| 
      
 73 
     | 
    
         
            +
                    state = :started
         
     | 
| 
      
 74 
     | 
    
         
            +
                    server.send_data "<?xml version='1.0'?><stream:stream xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams' id='12345'>"
         
     | 
| 
      
 75 
     | 
    
         
            +
                    val.must_match(/stream:stream/)
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  when :started
         
     | 
| 
      
 78 
     | 
    
         
            +
                    server.send_data '<handshake/>'
         
     | 
| 
      
 79 
     | 
    
         
            +
                    server.send_data "<message to='comp.id' from='d@e/f' type='chat' xml:lang='en'><body>Message!</body></message>"
         
     | 
| 
      
 80 
     | 
    
         
            +
                    val.must_equal "<handshake>#{Digest::SHA1.hexdigest('12345'+"secret")}</handshake>"
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -14,38 +14,85 @@ describe 'Blather::XMPPNode' do 
     | 
|
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
              it 'sets the namespace on creation' do
         
     | 
| 
       16 
16 
     | 
    
         
             
                class Foo < XMPPNode; end
         
     | 
| 
       17 
     | 
    
         
            -
                Foo. 
     | 
| 
       18 
     | 
    
         
            -
                Foo.new('foo'). 
     | 
| 
      
 17 
     | 
    
         
            +
                Foo.ns = 'foo'
         
     | 
| 
      
 18 
     | 
    
         
            +
                Foo.new('foo').namespace.must_equal 'foo'
         
     | 
| 
       19 
19 
     | 
    
         
             
              end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
              it 'registers sub classes' do
         
     | 
| 
       22 
22 
     | 
    
         
             
                class Foo < XMPPNode; register 'foo', 'foo:bar'; end
         
     | 
| 
       23 
23 
     | 
    
         
             
                Foo.name.must_equal 'foo'
         
     | 
| 
       24 
     | 
    
         
            -
                Foo. 
     | 
| 
      
 24 
     | 
    
         
            +
                Foo.ns.must_equal 'foo:bar'
         
     | 
| 
       25 
25 
     | 
    
         
             
                XMPPNode.class_from_registration('foo', 'foo:bar').must_equal Foo
         
     | 
| 
       26 
26 
     | 
    
         
             
              end
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
              it 'imports another node' do
         
     | 
| 
       29 
29 
     | 
    
         
             
                class Foo < XMPPNode; register 'foo', 'foo:bar'; end
         
     | 
| 
       30 
30 
     | 
    
         
             
                n = XMPPNode.new('foo')
         
     | 
| 
       31 
     | 
    
         
            -
                n. 
     | 
| 
      
 31 
     | 
    
         
            +
                n.namespace = 'foo:bar'
         
     | 
| 
       32 
32 
     | 
    
         
             
                XMPPNode.import(n).must_be_kind_of Foo
         
     | 
| 
       33 
33 
     | 
    
         
             
              end
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
      
 35 
     | 
    
         
            +
              it 'provides an attribute_reader' do
         
     | 
| 
      
 36 
     | 
    
         
            +
                class Foo < XMPPNode
         
     | 
| 
      
 37 
     | 
    
         
            +
                  attribute_reader :foo
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
                f = Foo.new
         
     | 
| 
      
 40 
     | 
    
         
            +
                f.must_respond_to :foo
         
     | 
| 
      
 41 
     | 
    
         
            +
                f.foo.must_be_nil
         
     | 
| 
      
 42 
     | 
    
         
            +
                f.attributes[:foo] = 'bar'
         
     | 
| 
      
 43 
     | 
    
         
            +
                f.foo.must_equal :bar
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
              it 'provides an attribute_reader and not convert to syms' do
         
     | 
| 
      
 47 
     | 
    
         
            +
                class Foo < XMPPNode
         
     | 
| 
      
 48 
     | 
    
         
            +
                  attribute_reader :foo, :to_sym => false
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
                f = Foo.new
         
     | 
| 
      
 51 
     | 
    
         
            +
                f.must_respond_to :foo
         
     | 
| 
      
 52 
     | 
    
         
            +
                f.foo.must_be_nil
         
     | 
| 
      
 53 
     | 
    
         
            +
                f.attributes[:foo] = 'bar'
         
     | 
| 
      
 54 
     | 
    
         
            +
                f.foo.must_equal 'bar'
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              it 'provides an attribute_writer' do
         
     | 
| 
      
 58 
     | 
    
         
            +
                class Foo < XMPPNode
         
     | 
| 
      
 59 
     | 
    
         
            +
                  attribute_writer :foo
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
                f = Foo.new
         
     | 
| 
      
 62 
     | 
    
         
            +
                f.attributes[:foo].must_be_nil
         
     | 
| 
      
 63 
     | 
    
         
            +
                f.foo = 'bar'
         
     | 
| 
      
 64 
     | 
    
         
            +
                f.attributes[:foo].must_equal 'bar'
         
     | 
| 
      
 65 
     | 
    
         
            +
              end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              it 'provides an attribute_accessor' do
         
     | 
| 
      
 68 
     | 
    
         
            +
                class Foo < XMPPNode
         
     | 
| 
      
 69 
     | 
    
         
            +
                  attribute_accessor :foo
         
     | 
| 
      
 70 
     | 
    
         
            +
                  attribute_accessor :bar, :to_sym => false
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
                f = Foo.new
         
     | 
| 
      
 73 
     | 
    
         
            +
                f.must_respond_to :foo
         
     | 
| 
      
 74 
     | 
    
         
            +
                f.foo.must_be_nil
         
     | 
| 
      
 75 
     | 
    
         
            +
                f.foo = 'bar'
         
     | 
| 
      
 76 
     | 
    
         
            +
                f.foo.must_equal :bar
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                f.must_respond_to :bar
         
     | 
| 
      
 79 
     | 
    
         
            +
                f.bar.must_be_nil
         
     | 
| 
      
 80 
     | 
    
         
            +
                f.bar = 'baz'
         
     | 
| 
      
 81 
     | 
    
         
            +
                f.bar.must_equal 'baz'
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
       35 
84 
     | 
    
         
             
              it 'can convert itself into a stanza' do
         
     | 
| 
       36 
85 
     | 
    
         
             
                class Foo < XMPPNode; register 'foo'; end
         
     | 
| 
       37 
86 
     | 
    
         
             
                n = XMPPNode.new('foo')
         
     | 
| 
       38 
87 
     | 
    
         
             
                n.to_stanza.must_be_kind_of Foo
         
     | 
| 
       39 
88 
     | 
    
         
             
              end
         
     | 
| 
       40 
89 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
              it 'provides "attr_accessor" for  
     | 
| 
      
 90 
     | 
    
         
            +
              it 'provides "attr_accessor" for namespace' do
         
     | 
| 
       42 
91 
     | 
    
         
             
                n = XMPPNode.new('foo')
         
     | 
| 
       43 
     | 
    
         
            -
                n. 
     | 
| 
       44 
     | 
    
         
            -
                n['xmlns'].must_be_nil
         
     | 
| 
      
 92 
     | 
    
         
            +
                n.namespace.must_be_nil
         
     | 
| 
       45 
93 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
                n. 
     | 
| 
       47 
     | 
    
         
            -
                n. 
     | 
| 
       48 
     | 
    
         
            -
                n['xmlns'].must_equal 'foo:bar'
         
     | 
| 
      
 94 
     | 
    
         
            +
                n.namespace = 'foo:bar'
         
     | 
| 
      
 95 
     | 
    
         
            +
                n.namespace.must_equal 'foo:bar'
         
     | 
| 
       49 
96 
     | 
    
         
             
              end
         
     | 
| 
       50 
97 
     | 
    
         | 
| 
       51 
98 
     | 
    
         
             
              it 'will remove a child element' do
         
     | 
| 
         @@ -53,22 +100,22 @@ describe 'Blather::XMPPNode' do 
     | 
|
| 
       53 
100 
     | 
    
         
             
                n << XMPPNode.new('bar')
         
     | 
| 
       54 
101 
     | 
    
         
             
                n << XMPPNode.new('bar')
         
     | 
| 
       55 
102 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
                n.find( 
     | 
| 
      
 103 
     | 
    
         
            +
                n.find(:bar).size.must_equal 2
         
     | 
| 
       57 
104 
     | 
    
         
             
                n.remove_child 'bar'
         
     | 
| 
       58 
     | 
    
         
            -
                n.find( 
     | 
| 
      
 105 
     | 
    
         
            +
                n.find(:bar).size.must_equal 1
         
     | 
| 
       59 
106 
     | 
    
         
             
              end
         
     | 
| 
       60 
107 
     | 
    
         | 
| 
       61 
108 
     | 
    
         
             
              it 'will remove a child with a specific xmlns' do
         
     | 
| 
       62 
109 
     | 
    
         
             
                n = XMPPNode.new 'foo'
         
     | 
| 
       63 
110 
     | 
    
         
             
                n << XMPPNode.new('bar')
         
     | 
| 
       64 
111 
     | 
    
         
             
                c = XMPPNode.new('bar')
         
     | 
| 
       65 
     | 
    
         
            -
                c. 
     | 
| 
      
 112 
     | 
    
         
            +
                c.namespace = 'foo:bar'
         
     | 
| 
       66 
113 
     | 
    
         
             
                n << c
         
     | 
| 
       67 
114 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
                n.find( 
     | 
| 
      
 115 
     | 
    
         
            +
                n.find(:bar).size.must_equal 2
         
     | 
| 
       69 
116 
     | 
    
         
             
                n.remove_child 'bar', 'foo:bar'
         
     | 
| 
       70 
     | 
    
         
            -
                n.find( 
     | 
| 
       71 
     | 
    
         
            -
                n.find( 
     | 
| 
      
 117 
     | 
    
         
            +
                n.find(:bar).size.must_equal 1
         
     | 
| 
      
 118 
     | 
    
         
            +
                n.find(:bar).first.namespace.must_be_nil
         
     | 
| 
       72 
119 
     | 
    
         
             
              end
         
     | 
| 
       73 
120 
     | 
    
         | 
| 
       74 
121 
     | 
    
         
             
              it 'will remove all child elements' do
         
     | 
| 
         @@ -76,9 +123,9 @@ describe 'Blather::XMPPNode' do 
     | 
|
| 
       76 
123 
     | 
    
         
             
                n << XMPPNode.new('bar')
         
     | 
| 
       77 
124 
     | 
    
         
             
                n << XMPPNode.new('bar')
         
     | 
| 
       78 
125 
     | 
    
         | 
| 
       79 
     | 
    
         
            -
                n.find( 
     | 
| 
      
 126 
     | 
    
         
            +
                n.find(:bar).size.must_equal 2
         
     | 
| 
       80 
127 
     | 
    
         
             
                n.remove_children 'bar'
         
     | 
| 
       81 
     | 
    
         
            -
                n.find( 
     | 
| 
      
 128 
     | 
    
         
            +
                n.find(:bar).size.must_equal 0
         
     | 
| 
       82 
129 
     | 
    
         
             
              end
         
     | 
| 
       83 
130 
     | 
    
         | 
| 
       84 
131 
     | 
    
         
             
              it 'provides a helper to grab content from a child' do
         
     | 
| 
         @@ -113,18 +160,24 @@ describe 'Blather::XMPPNode' do 
     | 
|
| 
       113 
160 
     | 
    
         
             
                n['foo'].must_equal 'bar'
         
     | 
| 
       114 
161 
     | 
    
         
             
              end
         
     | 
| 
       115 
162 
     | 
    
         | 
| 
       116 
     | 
    
         
            -
              it 'cuts line breaks out of # 
     | 
| 
      
 163 
     | 
    
         
            +
              it 'cuts line breaks out of #to_xml' do
         
     | 
| 
       117 
164 
     | 
    
         
             
                n = XMPPNode.new 'foo'
         
     | 
| 
       118 
165 
     | 
    
         
             
                n << XMPPNode.new('bar', 'baz')
         
     | 
| 
       119 
     | 
    
         
            -
                n. 
     | 
| 
      
 166 
     | 
    
         
            +
                n.to_xml.scan(">\n<").size.must_equal 0
         
     | 
| 
       120 
167 
     | 
    
         
             
              end
         
     | 
| 
       121 
168 
     | 
    
         | 
| 
       122 
169 
     | 
    
         
             
              it 'overrides #find to find without xpath' do
         
     | 
| 
       123 
170 
     | 
    
         
             
                n = XMPPNode.new 'foo'
         
     | 
| 
       124 
171 
     | 
    
         
             
                n << XMPPNode.new('bar', 'baz')
         
     | 
| 
       125 
     | 
    
         
            -
                n.find( 
     | 
| 
      
 172 
     | 
    
         
            +
                n.find(:bar).must_be_kind_of Array
         
     | 
| 
       126 
173 
     | 
    
         | 
| 
       127 
174 
     | 
    
         
             
                XML::Document.new.root = n
         
     | 
| 
       128 
     | 
    
         
            -
                n.find( 
     | 
| 
      
 175 
     | 
    
         
            +
                n.find(:bar).must_be_kind_of XML::XPath::Object
         
     | 
| 
      
 176 
     | 
    
         
            +
              end
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
              it 'can find using a symbol' do
         
     | 
| 
      
 179 
     | 
    
         
            +
                n = XMPPNode.new 'foo'
         
     | 
| 
      
 180 
     | 
    
         
            +
                n << XMPPNode.new('bar', 'baz')
         
     | 
| 
      
 181 
     | 
    
         
            +
                n.find(:bar).first.to_s.must_equal "<bar>baz</bar>"
         
     | 
| 
       129 
182 
     | 
    
         
             
              end
         
     | 
| 
       130 
183 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,157 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            def items_all_nodes_xml
         
     | 
| 
      
 2 
     | 
    
         
            +
            <<-ITEMS
         
     | 
| 
      
 3 
     | 
    
         
            +
            <iq type='result'
         
     | 
| 
      
 4 
     | 
    
         
            +
                from='pubsub.shakespeare.lit'
         
     | 
| 
      
 5 
     | 
    
         
            +
                to='francisco@denmark.lit/barracks'
         
     | 
| 
      
 6 
     | 
    
         
            +
                id='items1'>
         
     | 
| 
      
 7 
     | 
    
         
            +
              <pubsub xmlns='http://jabber.org/protocol/pubsub'>
         
     | 
| 
      
 8 
     | 
    
         
            +
                <items node='princely_musings'>
         
     | 
| 
      
 9 
     | 
    
         
            +
                  <item id='368866411b877c30064a5f62b917cffe'>
         
     | 
| 
      
 10 
     | 
    
         
            +
                    <entry xmlns='http://www.w3.org/2005/Atom'>
         
     | 
| 
      
 11 
     | 
    
         
            +
                      <title>The Uses of This World</title>
         
     | 
| 
      
 12 
     | 
    
         
            +
                      <summary>
         
     | 
| 
      
 13 
     | 
    
         
            +
            O, that this too too solid flesh would melt
         
     | 
| 
      
 14 
     | 
    
         
            +
            Thaw and resolve itself into a dew!
         
     | 
| 
      
 15 
     | 
    
         
            +
                      </summary>
         
     | 
| 
      
 16 
     | 
    
         
            +
                      <link rel='alternate' type='text/html'
         
     | 
| 
      
 17 
     | 
    
         
            +
                            href='http://denmark.lit/2003/12/13/atom03'/>
         
     | 
| 
      
 18 
     | 
    
         
            +
                      <id>tag:denmark.lit,2003:entry-32396</id>
         
     | 
| 
      
 19 
     | 
    
         
            +
                      <published>2003-12-12T17:47:23Z</published>
         
     | 
| 
      
 20 
     | 
    
         
            +
                      <updated>2003-12-12T17:47:23Z</updated>
         
     | 
| 
      
 21 
     | 
    
         
            +
                    </entry>
         
     | 
| 
      
 22 
     | 
    
         
            +
                  </item>
         
     | 
| 
      
 23 
     | 
    
         
            +
                  <item id='3300659945416e274474e469a1f0154c'>
         
     | 
| 
      
 24 
     | 
    
         
            +
                    <entry xmlns='http://www.w3.org/2005/Atom'>
         
     | 
| 
      
 25 
     | 
    
         
            +
                      <title>Ghostly Encounters</title>
         
     | 
| 
      
 26 
     | 
    
         
            +
                      <summary>
         
     | 
| 
      
 27 
     | 
    
         
            +
            O all you host of heaven! O earth! what else?
         
     | 
| 
      
 28 
     | 
    
         
            +
            And shall I couple hell? O, fie! Hold, hold, my heart;
         
     | 
| 
      
 29 
     | 
    
         
            +
            And you, my sinews, grow not instant old,
         
     | 
| 
      
 30 
     | 
    
         
            +
            But bear me stiffly up. Remember thee!
         
     | 
| 
      
 31 
     | 
    
         
            +
                      </summary>
         
     | 
| 
      
 32 
     | 
    
         
            +
                      <link rel='alternate' type='text/html'
         
     | 
| 
      
 33 
     | 
    
         
            +
                            href='http://denmark.lit/2003/12/13/atom03'/>
         
     | 
| 
      
 34 
     | 
    
         
            +
                      <id>tag:denmark.lit,2003:entry-32396</id>
         
     | 
| 
      
 35 
     | 
    
         
            +
                      <published>2003-12-12T23:21:34Z</published>
         
     | 
| 
      
 36 
     | 
    
         
            +
                      <updated>2003-12-12T23:21:34Z</updated>
         
     | 
| 
      
 37 
     | 
    
         
            +
                    </entry>
         
     | 
| 
      
 38 
     | 
    
         
            +
                  </item>
         
     | 
| 
      
 39 
     | 
    
         
            +
                  <item id='4e30f35051b7b8b42abe083742187228'>
         
     | 
| 
      
 40 
     | 
    
         
            +
                    <entry xmlns='http://www.w3.org/2005/Atom'>
         
     | 
| 
      
 41 
     | 
    
         
            +
                      <title>Alone</title>
         
     | 
| 
      
 42 
     | 
    
         
            +
                      <summary>
         
     | 
| 
      
 43 
     | 
    
         
            +
            Now I am alone.
         
     | 
| 
      
 44 
     | 
    
         
            +
            O, what a rogue and peasant slave am I!
         
     | 
| 
      
 45 
     | 
    
         
            +
                      </summary>
         
     | 
| 
      
 46 
     | 
    
         
            +
                      <link rel='alternate' type='text/html'
         
     | 
| 
      
 47 
     | 
    
         
            +
                            href='http://denmark.lit/2003/12/13/atom03'/>
         
     | 
| 
      
 48 
     | 
    
         
            +
                      <id>tag:denmark.lit,2003:entry-32396</id>
         
     | 
| 
      
 49 
     | 
    
         
            +
                      <published>2003-12-13T11:09:53Z</published>
         
     | 
| 
      
 50 
     | 
    
         
            +
                      <updated>2003-12-13T11:09:53Z</updated>
         
     | 
| 
      
 51 
     | 
    
         
            +
                    </entry>
         
     | 
| 
      
 52 
     | 
    
         
            +
                  </item>
         
     | 
| 
      
 53 
     | 
    
         
            +
                  <item id='ae890ac52d0df67ed7cfdf51b644e901'>
         
     | 
| 
      
 54 
     | 
    
         
            +
                    <entry xmlns='http://www.w3.org/2005/Atom'>
         
     | 
| 
      
 55 
     | 
    
         
            +
                      <title>Soliloquy</title>
         
     | 
| 
      
 56 
     | 
    
         
            +
                      <summary>
         
     | 
| 
      
 57 
     | 
    
         
            +
            To be, or not to be: that is the question:
         
     | 
| 
      
 58 
     | 
    
         
            +
            Whether 'tis nobler in the mind to suffer
         
     | 
| 
      
 59 
     | 
    
         
            +
            The slings and arrows of outrageous fortune,
         
     | 
| 
      
 60 
     | 
    
         
            +
            Or to take arms against a sea of troubles,
         
     | 
| 
      
 61 
     | 
    
         
            +
            And by opposing end them?
         
     | 
| 
      
 62 
     | 
    
         
            +
                      </summary>
         
     | 
| 
      
 63 
     | 
    
         
            +
                      <link rel='alternate' type='text/html'
         
     | 
| 
      
 64 
     | 
    
         
            +
                            href='http://denmark.lit/2003/12/13/atom03'/>
         
     | 
| 
      
 65 
     | 
    
         
            +
                      <id>tag:denmark.lit,2003:entry-32397</id>
         
     | 
| 
      
 66 
     | 
    
         
            +
                      <published>2003-12-13T18:30:02Z</published>
         
     | 
| 
      
 67 
     | 
    
         
            +
                      <updated>2003-12-13T18:30:02Z</updated>
         
     | 
| 
      
 68 
     | 
    
         
            +
                    </entry>
         
     | 
| 
      
 69 
     | 
    
         
            +
                  </item>
         
     | 
| 
      
 70 
     | 
    
         
            +
                </items>
         
     | 
| 
      
 71 
     | 
    
         
            +
              </pubsub>
         
     | 
| 
      
 72 
     | 
    
         
            +
            </iq>
         
     | 
| 
      
 73 
     | 
    
         
            +
            ITEMS
         
     | 
| 
      
 74 
     | 
    
         
            +
            end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            def pubsub_items_some_xml
         
     | 
| 
      
 77 
     | 
    
         
            +
            <<-ITEMS
         
     | 
| 
      
 78 
     | 
    
         
            +
            <iq type='result'
         
     | 
| 
      
 79 
     | 
    
         
            +
                from='pubsub.shakespeare.lit'
         
     | 
| 
      
 80 
     | 
    
         
            +
                to='francisco@denmark.lit/barracks'
         
     | 
| 
      
 81 
     | 
    
         
            +
                id='items1'>
         
     | 
| 
      
 82 
     | 
    
         
            +
              <pubsub xmlns='http://jabber.org/protocol/pubsub'>
         
     | 
| 
      
 83 
     | 
    
         
            +
                <items node='princely_musings'>
         
     | 
| 
      
 84 
     | 
    
         
            +
                  <item id='368866411b877c30064a5f62b917cffe'>
         
     | 
| 
      
 85 
     | 
    
         
            +
                    <entry xmlns='http://www.w3.org/2005/Atom'>
         
     | 
| 
      
 86 
     | 
    
         
            +
                      <title>The Uses of This World</title>
         
     | 
| 
      
 87 
     | 
    
         
            +
                      <summary>
         
     | 
| 
      
 88 
     | 
    
         
            +
            O, that this too too solid flesh would melt
         
     | 
| 
      
 89 
     | 
    
         
            +
            Thaw and resolve itself into a dew!
         
     | 
| 
      
 90 
     | 
    
         
            +
                      </summary>
         
     | 
| 
      
 91 
     | 
    
         
            +
                      <link rel='alternate' type='text/html'
         
     | 
| 
      
 92 
     | 
    
         
            +
                            href='http://denmark.lit/2003/12/13/atom03'/>
         
     | 
| 
      
 93 
     | 
    
         
            +
                      <id>tag:denmark.lit,2003:entry-32396</id>
         
     | 
| 
      
 94 
     | 
    
         
            +
                      <published>2003-12-12T17:47:23Z</published>
         
     | 
| 
      
 95 
     | 
    
         
            +
                      <updated>2003-12-12T17:47:23Z</updated>
         
     | 
| 
      
 96 
     | 
    
         
            +
                    </entry>
         
     | 
| 
      
 97 
     | 
    
         
            +
                  </item>
         
     | 
| 
      
 98 
     | 
    
         
            +
                  <item id='3300659945416e274474e469a1f0154c'>
         
     | 
| 
      
 99 
     | 
    
         
            +
                    <entry xmlns='http://www.w3.org/2005/Atom'>
         
     | 
| 
      
 100 
     | 
    
         
            +
                      <title>Ghostly Encounters</title>
         
     | 
| 
      
 101 
     | 
    
         
            +
                      <summary>
         
     | 
| 
      
 102 
     | 
    
         
            +
            O all you host of heaven! O earth! what else?
         
     | 
| 
      
 103 
     | 
    
         
            +
            And shall I couple hell? O, fie! Hold, hold, my heart;
         
     | 
| 
      
 104 
     | 
    
         
            +
            And you, my sinews, grow not instant old,
         
     | 
| 
      
 105 
     | 
    
         
            +
            But bear me stiffly up. Remember thee!
         
     | 
| 
      
 106 
     | 
    
         
            +
                      </summary>
         
     | 
| 
      
 107 
     | 
    
         
            +
                      <link rel='alternate' type='text/html'
         
     | 
| 
      
 108 
     | 
    
         
            +
                            href='http://denmark.lit/2003/12/13/atom03'/>
         
     | 
| 
      
 109 
     | 
    
         
            +
                      <id>tag:denmark.lit,2003:entry-32396</id>
         
     | 
| 
      
 110 
     | 
    
         
            +
                      <published>2003-12-12T23:21:34Z</published>
         
     | 
| 
      
 111 
     | 
    
         
            +
                      <updated>2003-12-12T23:21:34Z</updated>
         
     | 
| 
      
 112 
     | 
    
         
            +
                    </entry>
         
     | 
| 
      
 113 
     | 
    
         
            +
                  </item>
         
     | 
| 
      
 114 
     | 
    
         
            +
                  <item id='4e30f35051b7b8b42abe083742187228'>
         
     | 
| 
      
 115 
     | 
    
         
            +
                    <entry xmlns='http://www.w3.org/2005/Atom'>
         
     | 
| 
      
 116 
     | 
    
         
            +
                      <title>Alone</title>
         
     | 
| 
      
 117 
     | 
    
         
            +
                      <summary>
         
     | 
| 
      
 118 
     | 
    
         
            +
            Now I am alone.
         
     | 
| 
      
 119 
     | 
    
         
            +
            O, what a rogue and peasant slave am I!
         
     | 
| 
      
 120 
     | 
    
         
            +
                      </summary>
         
     | 
| 
      
 121 
     | 
    
         
            +
                      <link rel='alternate' type='text/html'
         
     | 
| 
      
 122 
     | 
    
         
            +
                            href='http://denmark.lit/2003/12/13/atom03'/>
         
     | 
| 
      
 123 
     | 
    
         
            +
                      <id>tag:denmark.lit,2003:entry-32396</id>
         
     | 
| 
      
 124 
     | 
    
         
            +
                      <published>2003-12-13T11:09:53Z</published>
         
     | 
| 
      
 125 
     | 
    
         
            +
                      <updated>2003-12-13T11:09:53Z</updated>
         
     | 
| 
      
 126 
     | 
    
         
            +
                    </entry>
         
     | 
| 
      
 127 
     | 
    
         
            +
                  </item>
         
     | 
| 
      
 128 
     | 
    
         
            +
                </items>
         
     | 
| 
      
 129 
     | 
    
         
            +
                <set xmlns='http://jabber.org/protocol/rsm'>
         
     | 
| 
      
 130 
     | 
    
         
            +
                  <first index='0'>368866411b877c30064a5f62b917cffe</first>
         
     | 
| 
      
 131 
     | 
    
         
            +
                  <last>4e30f35051b7b8b42abe083742187228</last>
         
     | 
| 
      
 132 
     | 
    
         
            +
                  <count>19</count>
         
     | 
| 
      
 133 
     | 
    
         
            +
                </set>
         
     | 
| 
      
 134 
     | 
    
         
            +
              </pubsub>
         
     | 
| 
      
 135 
     | 
    
         
            +
            </iq>
         
     | 
| 
      
 136 
     | 
    
         
            +
            ITEMS
         
     | 
| 
      
 137 
     | 
    
         
            +
            end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
            def affiliations_xml
         
     | 
| 
      
 140 
     | 
    
         
            +
            <<-NODE
         
     | 
| 
      
 141 
     | 
    
         
            +
            <iq type='result'
         
     | 
| 
      
 142 
     | 
    
         
            +
                from='pubsub.shakespeare.lit'
         
     | 
| 
      
 143 
     | 
    
         
            +
                to='francisco@denmark.lit'
         
     | 
| 
      
 144 
     | 
    
         
            +
                id='affil1'>
         
     | 
| 
      
 145 
     | 
    
         
            +
              <pubsub xmlns='http://jabber.org/protocol/pubsub'>
         
     | 
| 
      
 146 
     | 
    
         
            +
                <affiliations>
         
     | 
| 
      
 147 
     | 
    
         
            +
                  <affiliation node='node1' affiliation='owner'/>
         
     | 
| 
      
 148 
     | 
    
         
            +
                  <affiliation node='node2' affiliation='owner'/>
         
     | 
| 
      
 149 
     | 
    
         
            +
                  <affiliation node='node3' affiliation='publisher'/>
         
     | 
| 
      
 150 
     | 
    
         
            +
                  <affiliation node='node4' affiliation='outcast'/>
         
     | 
| 
      
 151 
     | 
    
         
            +
                  <affiliation node='node5' affiliation='member'/>
         
     | 
| 
      
 152 
     | 
    
         
            +
                  <affiliation node='node6' affiliation='none'/>
         
     | 
| 
      
 153 
     | 
    
         
            +
                </affiliations>
         
     | 
| 
      
 154 
     | 
    
         
            +
              </pubsub>
         
     | 
| 
      
 155 
     | 
    
         
            +
            </iq>
         
     | 
| 
      
 156 
     | 
    
         
            +
            NODE
         
     | 
| 
      
 157 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | 
         @@ -2,27 +2,23 @@ require File.join(File.dirname(__FILE__), *%w[.. lib blather]) 
     | 
|
| 
       2 
2 
     | 
    
         
             
            require 'rubygems'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'minitest/spec'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'mocha'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'mocha/expectation_error'
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            module MiniTest
         
     | 
| 
       7 
     | 
    
         
            -
              if MINI_DIR =~ %r{^./}
         
     | 
| 
       8 
     | 
    
         
            -
                require 'pathname'
         
     | 
| 
       9 
     | 
    
         
            -
                path = Pathname.new(MINI_DIR).realpath
         
     | 
| 
       10 
     | 
    
         
            -
            #    remove_const 'MINI_DIR'
         
     | 
| 
       11 
     | 
    
         
            -
            #    const_set 'MINI_DIR', path.to_s
         
     | 
| 
       12 
     | 
    
         
            -
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
              require 'pathname' if MINI_DIR =~ %r{^./}
         
     | 
| 
       13 
9 
     | 
    
         | 
| 
       14 
10 
     | 
    
         
             
              module Assertions
         
     | 
| 
       15 
     | 
    
         
            -
                def assert_change( 
     | 
| 
      
 11 
     | 
    
         
            +
                def assert_change(stmt, args = {}, msg = nil)
         
     | 
| 
       16 
12 
     | 
    
         
             
                  msg ||= proc {
         
     | 
| 
       17 
     | 
    
         
            -
                    m = "Expected #{ 
     | 
| 
      
 13 
     | 
    
         
            +
                    m = "Expected #{stmt} to change"
         
     | 
| 
       18 
14 
     | 
    
         
             
                    m << " by #{mu_pp args[:by]}" if args[:by]
         
     | 
| 
       19 
15 
     | 
    
         
             
                    m << (args[:from] ? " from #{mu_pp args[:from]}" : '') + " to #{mu_pp args[:to]}" if args[:to]
         
     | 
| 
       20 
16 
     | 
    
         
             
                    m
         
     | 
| 
       21 
17 
     | 
    
         
             
                  }.call
         
     | 
| 
       22 
18 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
                  init_val = eval( 
     | 
| 
      
 19 
     | 
    
         
            +
                  init_val = eval(stmt)
         
     | 
| 
       24 
20 
     | 
    
         
             
                  yield
         
     | 
| 
       25 
     | 
    
         
            -
                  new_val = eval( 
     | 
| 
      
 21 
     | 
    
         
            +
                  new_val = eval(stmt)
         
     | 
| 
       26 
22 
     | 
    
         | 
| 
       27 
23 
     | 
    
         
             
                  assert_equal(args[:by], (new_val - init_val), msg) if args[:by]
         
     | 
| 
       28 
24 
     | 
    
         
             
                  assert_equal([args[:from], args[:to]], [(init_val if args[:from]), new_val], msg) if args[:to]
         
     | 
| 
         @@ -37,11 +33,7 @@ class Object 
     | 
|
| 
       37 
33 
     | 
    
         
             
              end
         
     | 
| 
       38 
34 
     | 
    
         
             
            end
         
     | 
| 
       39 
35 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
            require 'mocha/expectation_error'
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
36 
     | 
    
         
             
            include Blather
         
     | 
| 
       43 
37 
     | 
    
         
             
            include MiniTest
         
     | 
| 
       44 
38 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
            LOG.level = Logger::INFO
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
39 
     | 
    
         
             
            Unit.autorun
         
     |