Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'release/0.5.1'

  • Loading branch information...
commit edd0dc0134598951a1497023415b63bd07ac3826 2 parents d64e0e8 + cff5627
@benlangfeld benlangfeld authored
View
4 CHANGELOG
@@ -1,3 +1,7 @@
+v0.5.1
+ Feature(benlangfeld): Abstract out Nokogiri extensions and helpers into new Niceogiri gem for better sharing
+ Documentation(benlangfeld)
+
v0.5.0
Feature(radsaq): Add a #connected? method on Blather::Client
Feature(benlangfeld)[API change]: Allow the removal of child nodes from an IQ reply
View
2  LICENSE
@@ -1,6 +1,6 @@
Blather
-Copyright (c) 2009 Jeff Smick
+Copyright (c) 2011 Jeff Smick
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
View
4 README.md
@@ -19,7 +19,7 @@ XMPP DSL (and more) for Ruby written on EventMachine and Nokogiri.
## Installation
- sudo gem install blather
+ gem install blather
## Example
@@ -173,4 +173,4 @@ than a change set made directly on master.
# Copyright
-Copyright (c) 2009 Jeff Smick. See LICENSE for details.
+Copyright (c) 2011 Jeff Smick. See LICENSE for details.
View
2  blather.gemspec
@@ -8,7 +8,6 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.authors = ["Jeff Smick"]
s.email = %q{sprsquish@gmail.com}
- s.date = %q{2010-09-02}
s.homepage = "http://github.com/sprsquish/blather"
s.summary = %q{Simpler XMPP built for speed}
s.description = %q{An XMPP DSL for Ruby written on top of EventMachine and Nokogiri}
@@ -23,6 +22,7 @@ Gem::Specification.new do |s|
s.add_dependency("eventmachine", ["~> 0.12.6"])
s.add_dependency("nokogiri", [">= 1.4.0"])
+ s.add_dependency("niceogiri", [">= 0.0.3"])
s.add_dependency("minitest", [">= 1.7.1"])
s.add_dependency("activesupport", [">= 3.0.7"])
View
3  lib/blather.rb
@@ -2,7 +2,7 @@
%w[
rubygems
eventmachine
- nokogiri
+ niceogiri
ipaddr
digest/md5
digest/sha1
@@ -13,7 +13,6 @@
blather/core_ext/eventmachine
blather/core_ext/ipaddr
- blather/core_ext/nokogiri
blather/errors
blather/errors/sasl_error
View
44 lib/blather/core_ext/nokogiri.rb
@@ -1,44 +0,0 @@
-# @private
-module Nokogiri
-module XML
-
- # Nokogiri::Node extensions
- class Node
- # Alias #name to #element_name so we can use #name in an XMPP Stanza context
- alias_method :element_name, :name
- alias_method :element_name=, :name=
-
- alias_method :attr_set, :[]=
- # Override Nokogiri's attribute setter to add the ability to kill an attribute
- # by setting it to nil and to be able to lookup an attribute by symbol
- #
- # @param [#to_s] name the name of the attribute
- # @param [#to_s, nil] value the new value or nil to remove it
- def []=(name, value)
- name = name.to_s
- value.nil? ? remove_attribute(name) : attr_set(name, value.to_s)
- end
-
- alias_method :nokogiri_xpath, :xpath
- # Override Nokogiri's #xpath method to add the ability to use symbols for lookup
- # and namespace designation
- def xpath(*paths)
- paths[0] = paths[0].to_s
-
- if paths.size > 1 && (namespaces = paths.pop).is_a?(Hash)
- paths << namespaces.inject({}) { |h,v| h[v[0].to_s] = v[1]; h }
- end
-
- nokogiri_xpath *paths
- end
- alias_method :find, :xpath
-
- # Return the first element at a specified xpath
- # @see #xpath
- def find_first(*paths)
- xpath(*paths).first
- end
- end
-
-end #XML
-end #Blather
View
2  lib/blather/version.rb
@@ -1,4 +1,4 @@
module Blather
# Blather version number
- VERSION = '0.5.0'
+ VERSION = '0.5.1'
end
View
174 lib/blather/xmpp_node.rb
@@ -2,15 +2,14 @@ module Blather
# Base XML Node
# All XML classes subclass XMPPNode it allows the addition of helpers
- class XMPPNode < Nokogiri::XML::Node
+ class XMPPNode < Niceogiri::XML::Node
# @private
BASE_NAMES = %w[presence message iq].freeze
# @private
@@registrations = {}
- class_inheritable_accessor :registered_ns,
- :registered_name
+ class_inheritable_accessor :registered_ns, :registered_name
# Register a new stanza class to a name and/or namespace
#
@@ -32,8 +31,7 @@ def self.register(name, ns = nil)
# @param [String, nil] xmlns the namespace the node belongs to
# @return [Class, nil] the class appropriate for the name/ns combination
def self.class_from_registration(name, ns = nil)
- name = name.to_s
- @@registrations[[name, ns]]
+ @@registrations[[name.to_s, ns]]
end
# Import an XML::Node to the appropriate class
@@ -58,43 +56,8 @@ def self.import(node)
# @param [XML::Document, nil] doc the document to attach the node to. If
# not provided one will be created
# @return a new object with the registered name and namespace
- def self.new(name = nil, doc = nil)
- name ||= self.registered_name
-
- node = super name.to_s, (doc || Nokogiri::XML::Document.new)
- node.document.root = node unless doc
- node.namespace = self.registered_ns unless BASE_NAMES.include?(name.to_s)
- node
- end
-
- # Helper method to read an attribute
- #
- # @param [#to_sym] attr_name the name of the attribute
- # @param [String, Symbol, nil] to_call the name of the method to call on
- # the returned value
- # @return nil or the value
- def read_attr(attr_name, to_call = nil)
- val = self[attr_name.to_sym]
- val && to_call ? val.__send__(to_call) : val
- end
-
- # Helper method to write a value to an attribute
- #
- # @param [#to_sym] attr_name the name of the attribute
- # @param [#to_s] value the value to set the attribute to
- def write_attr(attr_name, value)
- self[attr_name.to_sym] = value
- end
-
- # Helper method to read the content of a node
- #
- # @param [#to_sym] node the name of the node
- # @param [String, Symbol, nil] to_call the name of the method to call on
- # the returned value
- # @return nil or the value
- def read_content(node, to_call = nil)
- val = content_from node.to_sym
- val && to_call ? val.__send__(to_call) : val
+ def self.new(name = registered_name, doc = nil)
+ super name, doc, BASE_NAMES.include?(name.to_s) ? nil : self.registered_ns
end
# Turn the object into a proper stanza
@@ -103,133 +66,6 @@ def read_content(node, to_call = nil)
def to_stanza
self.class.import self
end
-
- # @private
- alias_method :nokogiri_namespace=, :namespace=
- # Attach a namespace to the node
- #
- # @overload namespace=(ns)
- # Attach an already created XML::Namespace
- # @param [XML::Namespace] ns the namespace object
- # @overload namespace=(ns)
- # Create a new namespace and attach it
- # @param [String] ns the namespace uri
- # @overload namespace=(namespaces)
- # Createa and add new namespaces from a hash
- # @param [Hash] namespaces a hash of prefix => uri pairs
- def namespace=(namespaces)
- case namespaces
- when Nokogiri::XML::Namespace
- self.nokogiri_namespace = namespaces
- when String
- self.add_namespace nil, namespaces
- when Hash
- if ns = namespaces.delete(nil)
- self.add_namespace nil, ns
- end
- namespaces.each do |p, n|
- ns = self.add_namespace p, n
- self.nokogiri_namespace = ns
- end
- end
- end
-
- # Helper method to get the node's namespace
- #
- # @return [XML::Namespace, nil] The node's namespace object if it exists
- def namespace_href
- namespace.href if namespace
- end
-
- # Remove a child with the name and (optionally) namespace given
- #
- # @param [String] name the name or xpath of the node to remove
- # @param [String, nil] ns the namespace the node is in
- def remove_child(name, ns = nil)
- child = xpath(name, ns).first
- child.remove if child
- end
-
- # Remove all children with a given name regardless of namespace
- #
- # @param [String] name the name of the nodes to remove
- def remove_children(name)
- xpath("./*[local-name()='#{name}']").remove
- end
-
- # The content of the named node
- #
- # @param [String] name the name or xpath of the node
- # @param [String, nil] ns the namespace the node is in
- # @return [String, nil] the content of the node
- def content_from(name, ns = nil)
- child = xpath(name, ns).first
- child.content if child
- end
-
- # Sets the content for the specified node.
- # If the node exists it is updated. If not a new node is created
- # If the node exists and the content is nil, the node will be removed
- # entirely
- #
- # @param [String] node the name of the node to update/create
- # @param [String, nil] content the content to set within the node
- def set_content_for(node, content = nil)
- if content
- child = xpath(node).first
- self << (child = XMPPNode.new(node, self.document)) unless child
- child.content = content
- else
- remove_child node
- end
- end
-
- alias_method :copy, :dup
-
- # Inherit the attributes and children of an XML::Node
- #
- # @param [XML::Node] stanza the node to inherit
- # @return [self]
- def inherit(stanza)
- set_namespace stanza.namespace if stanza.namespace
- inherit_attrs stanza.attributes
- stanza.children.each do |c|
- self << (n = c.dup)
- ns = n.namespace_definitions.find { |ns| ns.prefix == c.namespace.prefix }
- n.namespace = ns if ns
- end
- self
- end
-
- # Inherit a set of attributes
- #
- # @param [Hash] attrs a hash of attributes to set on the node
- # @return [self]
- def inherit_attrs(attrs)
- attrs.each { |name, value| self[name] = value }
- self
- end
-
- # The node as XML
- #
- # @return [String] XML representation of the node
- def inspect
- self.to_xml
- end
-
- # Check that a set of fields are equal between nodes
- #
- # @param [XMPPNode] other the other node to compare against
- # @param [*#to_s] fields the set of fields to compare
- # @return [Fixnum<-1,0,1>]
- def eql?(o, *fields)
- o.is_a?(self.class) && fields.all? { |f| self.__send__(f) == o.__send__(f) }
- end
-
- # @private
- def ==(o)
- eql?(o)
- end
end # XMPPNode
end # Blather
View
195 spec/blather/xmpp_node_spec.rb
@@ -3,28 +3,6 @@
describe Blather::XMPPNode do
before { @doc = Nokogiri::XML::Document.new }
- it 'generates a new node automatically setting the document' do
- n = Blather::XMPPNode.new 'foo'
- n.element_name.must_equal 'foo'
- n.document.wont_equal @doc
- end
-
- it 'sets the new document root to the node' do
- n = Blather::XMPPNode.new 'foo'
- n.document.root.must_equal n
- end
-
- it 'does not set the document root if the document is provided' do
- n = Blather::XMPPNode.new 'foo', @doc
- n.document.root.wont_equal n
- end
-
- it 'generates a new node with the given document' do
- n = Blather::XMPPNode.new 'foo', @doc
- n.element_name.must_equal 'foo'
- n.document.must_equal @doc
- end
-
it 'generates a node based on the registered_name' do
foo = Class.new(Blather::XMPPNode)
foo.registered_name = 'foo'
@@ -51,182 +29,9 @@ class ImportSubClass < Blather::XMPPNode; register 'foo', 'foo:bar'; end
Blather::XMPPNode.import(n).must_be_kind_of ImportSubClass
end
- it 'provides an attribute reader' do
- foo = Blather::XMPPNode.new
- foo.read_attr(:bar).must_be_nil
- foo[:bar] = 'baz'
- foo.read_attr(:bar).must_equal 'baz'
- end
-
- it 'provides an attribute reader with converstion' do
- foo = Blather::XMPPNode.new
- foo.read_attr(:bar, :to_sym).must_be_nil
- foo[:bar] = 'baz'
- foo.read_attr(:bar, :to_sym).must_equal :baz
- end
-
- it 'provides an attribute writer' do
- foo = Blather::XMPPNode.new
- foo[:bar].must_be_nil
- foo.write_attr(:bar, 'baz')
- foo[:bar].must_equal 'baz'
- end
-
- it 'provides a content reader' do
- foo = Blather::XMPPNode.new('foo')
- foo << (bar = Blather::XMPPNode.new('bar', foo.document))
- bar.content = 'baz'
- foo.read_content(:bar).must_equal 'baz'
- end
-
- it 'provides a content reader that converts the value' do
- foo = Blather::XMPPNode.new('foo')
- foo << (bar = Blather::XMPPNode.new('bar', foo.document))
- bar.content = 'baz'
- foo.read_content(:bar, :to_sym).must_equal :baz
- end
-
- it 'provides a content writer' do
- foo = Blather::XMPPNode.new('foo')
- foo.set_content_for :bar, 'baz'
- foo.content_from(:bar).must_equal 'baz'
- end
-
- it 'provides a content writer that removes a child when set to nil' do
- foo = Blather::XMPPNode.new('foo')
- foo << (bar = Blather::XMPPNode.new('bar', foo.document))
- bar.content = 'baz'
- foo.content_from(:bar).must_equal 'baz'
- foo.xpath('bar').wont_be_empty
-
- foo.set_content_for :bar, nil
- foo.content_from(:bar).must_be_nil
- foo.xpath('bar').must_be_empty
- end
-
it 'can convert itself into a stanza' do
class StanzaConvert < Blather::XMPPNode; register 'foo'; end
n = Blather::XMPPNode.new('foo')
n.to_stanza.must_be_kind_of StanzaConvert
end
-
- it 'provides "attr_accessor" for namespace' do
- n = Blather::XMPPNode.new('foo')
- n.namespace.must_be_nil
-
- n.namespace = 'foo:bar'
- n.namespace_href.must_equal 'foo:bar'
- end
-
- it 'will remove a child element' do
- n = Blather::XMPPNode.new 'foo'
- n << Blather::XMPPNode.new('bar', n.document)
- n << Blather::XMPPNode.new('bar', n.document)
-
- n.find(:bar).size.must_equal 2
- n.remove_child 'bar'
- n.find(:bar).size.must_equal 1
- end
-
- it 'will remove a child with a specific xmlns' do
- n = Blather::XMPPNode.new 'foo'
- n << Blather::XMPPNode.new('bar')
- c = Blather::XMPPNode.new('bar')
- c.namespace = 'foo:bar'
- n << c
-
- n.find(:bar).size.must_equal 1
- n.find('//xmlns:bar', :xmlns => 'foo:bar').size.must_equal 1
- n.remove_child '//xmlns:bar', :xmlns => 'foo:bar'
- n.find(:bar).size.must_equal 1
- n.find('//xmlns:bar', :xmlns => 'foo:bar').size.must_equal 0
- end
-
- it 'will remove all child elements' do
- n = Blather::XMPPNode.new 'foo'
- n << Blather::XMPPNode.new('bar')
- n << Blather::XMPPNode.new('bar')
-
- n.find(:bar).size.must_equal 2
- n.remove_children 'bar'
- n.find(:bar).size.must_equal 0
- end
-
- it 'provides a copy mechanism' do
- n = Blather::XMPPNode.new 'foo'
- n2 = n.copy
- n2.object_id.wont_equal n.object_id
- n2.element_name.must_equal n.element_name
- end
-
- it 'provides an inherit mechanism' do
- n = Blather::XMPPNode.new 'foo'
- n2 = Blather::XMPPNode.new 'foo'
- n2.content = 'bar'
- n2['foo'] = 'bar'
-
- n.inherit(n2)
- n['foo'].must_equal 'bar'
- n.content.must_equal 'bar'
- n2.to_s.must_equal n.to_s
- end
-
- it 'holds on to namespaces when inheriting content' do
- n = parse_stanza('<message><bar:foo xmlns:bar="http://bar.com"></message>').root
- n2 = Blather::XMPPNode.new('message').inherit n
- n2.to_s.must_equal n.to_s
- end
-
- it 'provides a mechanism to inherit attrs' do
- n = Blather::XMPPNode.new 'foo'
- n2 = Blather::XMPPNode.new 'foo'
- n2['foo'] = 'bar'
-
- n.inherit_attrs(n2.attributes)
- n['foo'].must_equal 'bar'
- end
-
- it 'has a content_from helper that pulls the content from a child node' do
- f = Blather::XMPPNode.new('foo')
- f << (b = Blather::XMPPNode.new('bar'))
- b.content = 'content'
- f.content_from(:bar).must_equal 'content'
- end
-
- it 'returns nil when sent #content_from and a missing node' do
- f = Blather::XMPPNode.new('foo')
- f.content_from(:bar).must_be_nil
- end
-
- it 'creates a new node and sets content when sent #set_content_for' do
- f = Blather::XMPPNode.new('foo')
- f.must_respond_to :set_content_for
- f.xpath('bar').must_be_empty
- f.set_content_for :bar, :baz
- f.xpath('bar').wont_be_empty
- f.xpath('bar').first.content.must_equal 'baz'
- end
-
- it 'removes a child node when sent #set_content_for with nil' do
- f = Blather::XMPPNode.new('foo')
- f << (b = Blather::XMPPNode.new('bar'))
- f.must_respond_to :set_content_for
- f.xpath('bar').wont_be_empty
- f.set_content_for :bar, nil
- f.xpath('bar').must_be_empty
- end
-
- it 'will change the content of an existing node when sent #set_content_for' do
- f = Blather::XMPPNode.new('foo')
- f << (b = Blather::XMPPNode.new('bar'))
- b.content = 'baz'
- f.must_respond_to :set_content_for
- f.xpath('bar').wont_be_empty
- f.xpath('bar').first.content.must_equal 'baz'
- control = f.xpath('bar').first.pointer_id
-
- f.set_content_for :bar, 'fiz'
- f.xpath('bar').first.content.must_equal 'fiz'
- f.xpath('bar').first.pointer_id.must_equal control
- end
end
Please sign in to comment.
Something went wrong with that request. Please try again.