mirror of
https://github.com/github/rails.git
synced 2026-01-13 00:28:26 -05:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81d67c66b0 | ||
|
|
cf8f36930c | ||
|
|
d622643e47 | ||
|
|
3f0241a613 | ||
|
|
38a7432590 | ||
|
|
1220d3c3ed |
@@ -6,3 +6,4 @@ gem install rack -v=1.4.5
|
|||||||
gem install erubis -v=2.7.0
|
gem install erubis -v=2.7.0
|
||||||
gem install json -v=1.8.0
|
gem install json -v=1.8.0
|
||||||
gem install i18n -v=0.6.9
|
gem install i18n -v=0.6.9
|
||||||
|
gem install builder -v=3.2.2
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.3.14.github36
|
2.3.14.github38
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
# Prefer gems to the bundled libs.
|
# Prefer gems to the bundled libs.
|
||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
|
|
||||||
begin
|
|
||||||
gem 'builder', '~> 2.1.2'
|
|
||||||
rescue Gem::LoadError
|
|
||||||
$:.unshift "#{File.dirname(__FILE__)}/vendor/builder-2.1.2"
|
|
||||||
end
|
|
||||||
require 'builder'
|
require 'builder'
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
#!/usr/bin/env ruby
|
|
||||||
|
|
||||||
#--
|
|
||||||
# Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
|
|
||||||
# All rights reserved.
|
|
||||||
|
|
||||||
# Permission is granted for use, copying, modification, distribution,
|
|
||||||
# and distribution of modified versions of this work as long as the
|
|
||||||
# above copyright notice is included.
|
|
||||||
#++
|
|
||||||
|
|
||||||
require 'builder/xmlmarkup'
|
|
||||||
require 'builder/xmlevents'
|
|
||||||
@@ -1,248 +0,0 @@
|
|||||||
#!/usr/bin/env ruby
|
|
||||||
#--
|
|
||||||
# Copyright 2004, 2005 by Jim Weirich (jim@weirichhouse.org).
|
|
||||||
# Copyright 2005 by Scott Barron (scott@elitists.net).
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Permission is granted for use, copying, modification, distribution,
|
|
||||||
# and distribution of modified versions of this work as long as the
|
|
||||||
# above copyright notice is included.
|
|
||||||
#
|
|
||||||
# Much of this is taken from Jim's work in xmlbase.rb and xmlmarkup.rb.
|
|
||||||
# Documentation has also been copied and pasted and modified to reflect
|
|
||||||
# that we're building CSS here instead of XML. Jim is conducting the
|
|
||||||
# orchestra here and I'm just off in the corner playing a flute.
|
|
||||||
#++
|
|
||||||
|
|
||||||
# Provide a flexible and easy to use Builder for creating Cascading
|
|
||||||
# Style Sheets (CSS).
|
|
||||||
|
|
||||||
|
|
||||||
module Builder
|
|
||||||
|
|
||||||
# Create a Cascading Style Sheet (CSS) using Ruby.
|
|
||||||
#
|
|
||||||
# Example usage:
|
|
||||||
#
|
|
||||||
# css = Builder::CSS.new
|
|
||||||
#
|
|
||||||
# text_color = '#7F7F7F'
|
|
||||||
# preferred_fonts = 'Helvetica, Arial, sans_serif'
|
|
||||||
#
|
|
||||||
# css.comment! 'This is our stylesheet'
|
|
||||||
# css.body {
|
|
||||||
# background_color '#FAFAFA'
|
|
||||||
# font_size 'small'
|
|
||||||
# font_family preferred_fonts
|
|
||||||
# color text_color
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# css.id!('navbar') {
|
|
||||||
# width '500px'
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# css.class!('navitem') {
|
|
||||||
# color 'red'
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# css.a :hover {
|
|
||||||
# text_decoration 'underline'
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# css.div(:id => 'menu') {
|
|
||||||
# background 'green'
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# css.div(:class => 'foo') {
|
|
||||||
# background 'red'
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# This will yield the following stylesheet:
|
|
||||||
#
|
|
||||||
# /* This is our stylesheet */
|
|
||||||
# body {
|
|
||||||
# background_color: #FAFAFA;
|
|
||||||
# font_size: small;
|
|
||||||
# font_family: Helvetica, Arial, sans_serif;
|
|
||||||
# color: #7F7F7F;
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# #navbar {
|
|
||||||
# width: 500px;
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# .navitem {
|
|
||||||
# color: red;
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# a:hover {
|
|
||||||
# text_decoration: underline;
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# div#menu {
|
|
||||||
# background: green;
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# div.foo {
|
|
||||||
# background: red;
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
class CSS < BasicObject
|
|
||||||
|
|
||||||
# Create a CSS builder.
|
|
||||||
#
|
|
||||||
# out:: Object receiving the markup.1 +out+ must respond to
|
|
||||||
# <tt><<</tt>.
|
|
||||||
# indent:: Number of spaces used for indentation (0 implies no
|
|
||||||
# indentation and no line breaks).
|
|
||||||
#
|
|
||||||
def initialize(indent=2)
|
|
||||||
@indent = indent
|
|
||||||
@target = []
|
|
||||||
@parts = []
|
|
||||||
@library = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
def +(part)
|
|
||||||
_join_with_op! '+'
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def >>(part)
|
|
||||||
_join_with_op! ''
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def >(part)
|
|
||||||
_join_with_op! '>'
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def |(part)
|
|
||||||
_join_with_op! ','
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
# Return the target of the builder
|
|
||||||
def target!
|
|
||||||
@target * ''
|
|
||||||
end
|
|
||||||
|
|
||||||
# Create a comment string in the output.
|
|
||||||
def comment!(comment_text)
|
|
||||||
@target << "/* #{comment_text} */\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
def id!(arg, &block)
|
|
||||||
_start_container('#'+arg.to_s, nil, block_given?)
|
|
||||||
_css_block(block) if block
|
|
||||||
_unify_block
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def class!(arg, &block)
|
|
||||||
_start_container('.'+arg.to_s, nil, block_given?)
|
|
||||||
_css_block(block) if block
|
|
||||||
_unify_block
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def store!(sym, &block)
|
|
||||||
@library[sym] = block.to_proc
|
|
||||||
end
|
|
||||||
|
|
||||||
def group!(*args, &block)
|
|
||||||
args.each do |arg|
|
|
||||||
if arg.is_a?(::Symbol)
|
|
||||||
instance_eval(&@library[arg])
|
|
||||||
else
|
|
||||||
instance_eval(&arg)
|
|
||||||
end
|
|
||||||
_text ', ' unless arg == args.last
|
|
||||||
end
|
|
||||||
if block
|
|
||||||
_css_block(block)
|
|
||||||
_unify_block
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def method_missing(sym, *args, &block)
|
|
||||||
sym = "#{sym}:#{args.shift}" if args.first.kind_of?(::Symbol)
|
|
||||||
if block
|
|
||||||
_start_container(sym, args.first)
|
|
||||||
_css_block(block)
|
|
||||||
_unify_block
|
|
||||||
elsif @in_block
|
|
||||||
_indent
|
|
||||||
_css_line(sym, *args)
|
|
||||||
_newline
|
|
||||||
return self
|
|
||||||
else
|
|
||||||
_start_container(sym, args.first, false)
|
|
||||||
_unify_block
|
|
||||||
end
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
# "Cargo culted" from Jim who also "cargo culted" it. See xmlbase.rb.
|
|
||||||
def nil?
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def _unify_block
|
|
||||||
@target << @parts * ''
|
|
||||||
@parts = []
|
|
||||||
end
|
|
||||||
|
|
||||||
def _join_with_op!(op)
|
|
||||||
rhs, lhs = @target.pop, @target.pop
|
|
||||||
@target << "#{lhs} #{op} #{rhs}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def _text(text)
|
|
||||||
@parts << text
|
|
||||||
end
|
|
||||||
|
|
||||||
def _css_block(block)
|
|
||||||
_newline
|
|
||||||
_nested_structures(block)
|
|
||||||
_end_container
|
|
||||||
_end_block
|
|
||||||
end
|
|
||||||
|
|
||||||
def _end_block
|
|
||||||
_newline
|
|
||||||
_newline
|
|
||||||
end
|
|
||||||
|
|
||||||
def _newline
|
|
||||||
_text "\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
def _indent
|
|
||||||
_text ' ' * @indent
|
|
||||||
end
|
|
||||||
|
|
||||||
def _nested_structures(block)
|
|
||||||
@in_block = true
|
|
||||||
self.instance_eval(&block)
|
|
||||||
@in_block = false
|
|
||||||
end
|
|
||||||
|
|
||||||
def _start_container(sym, atts = {}, with_bracket = true)
|
|
||||||
selector = sym.to_s
|
|
||||||
selector << ".#{atts[:class]}" if atts && atts[:class]
|
|
||||||
selector << '#' + "#{atts[:id]}" if atts && atts[:id]
|
|
||||||
@parts << "#{selector}#{with_bracket ? ' {' : ''}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def _end_container
|
|
||||||
@parts << "}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def _css_line(sym, *args)
|
|
||||||
_text("#{sym.to_s.gsub('_','-')}: #{args * ' '};")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
#!/usr/bin/env ruby
|
|
||||||
|
|
||||||
# The XChar library is provided courtesy of Sam Ruby (See
|
|
||||||
# http://intertwingly.net/stories/2005/09/28/xchar.rb)
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
|
|
||||||
# If the Builder::XChar module is not currently defined, fail on any
|
|
||||||
# name clashes in standard library classes.
|
|
||||||
|
|
||||||
module Builder
|
|
||||||
def self.check_for_name_collision(klass, method_name, defined_constant=nil)
|
|
||||||
if klass.instance_methods.include?(method_name.to_s)
|
|
||||||
fail RuntimeError,
|
|
||||||
"Name Collision: Method '#{method_name}' is already defined in #{klass}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if ! defined?(Builder::XChar)
|
|
||||||
Builder.check_for_name_collision(String, "to_xs")
|
|
||||||
Builder.check_for_name_collision(Fixnum, "xchr")
|
|
||||||
end
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
module Builder
|
|
||||||
|
|
||||||
####################################################################
|
|
||||||
# XML Character converter, from Sam Ruby:
|
|
||||||
# (see http://intertwingly.net/stories/2005/09/28/xchar.rb).
|
|
||||||
#
|
|
||||||
module XChar # :nodoc:
|
|
||||||
|
|
||||||
# See
|
|
||||||
# http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
|
|
||||||
# for details.
|
|
||||||
CP1252 = { # :nodoc:
|
|
||||||
128 => 8364, # euro sign
|
|
||||||
130 => 8218, # single low-9 quotation mark
|
|
||||||
131 => 402, # latin small letter f with hook
|
|
||||||
132 => 8222, # double low-9 quotation mark
|
|
||||||
133 => 8230, # horizontal ellipsis
|
|
||||||
134 => 8224, # dagger
|
|
||||||
135 => 8225, # double dagger
|
|
||||||
136 => 710, # modifier letter circumflex accent
|
|
||||||
137 => 8240, # per mille sign
|
|
||||||
138 => 352, # latin capital letter s with caron
|
|
||||||
139 => 8249, # single left-pointing angle quotation mark
|
|
||||||
140 => 338, # latin capital ligature oe
|
|
||||||
142 => 381, # latin capital letter z with caron
|
|
||||||
145 => 8216, # left single quotation mark
|
|
||||||
146 => 8217, # right single quotation mark
|
|
||||||
147 => 8220, # left double quotation mark
|
|
||||||
148 => 8221, # right double quotation mark
|
|
||||||
149 => 8226, # bullet
|
|
||||||
150 => 8211, # en dash
|
|
||||||
151 => 8212, # em dash
|
|
||||||
152 => 732, # small tilde
|
|
||||||
153 => 8482, # trade mark sign
|
|
||||||
154 => 353, # latin small letter s with caron
|
|
||||||
155 => 8250, # single right-pointing angle quotation mark
|
|
||||||
156 => 339, # latin small ligature oe
|
|
||||||
158 => 382, # latin small letter z with caron
|
|
||||||
159 => 376, # latin capital letter y with diaeresis
|
|
||||||
}
|
|
||||||
|
|
||||||
# See http://www.w3.org/TR/REC-xml/#dt-chardata for details.
|
|
||||||
PREDEFINED = {
|
|
||||||
38 => '&', # ampersand
|
|
||||||
60 => '<', # left angle bracket
|
|
||||||
62 => '>', # right angle bracket
|
|
||||||
}
|
|
||||||
|
|
||||||
# See http://www.w3.org/TR/REC-xml/#charsets for details.
|
|
||||||
VALID = [
|
|
||||||
0x9, 0xA, 0xD,
|
|
||||||
(0x20..0xD7FF),
|
|
||||||
(0xE000..0xFFFD),
|
|
||||||
(0x10000..0x10FFFF)
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
# Enhance the Fixnum class with a XML escaped character conversion.
|
|
||||||
#
|
|
||||||
class Fixnum
|
|
||||||
XChar = Builder::XChar if ! defined?(XChar)
|
|
||||||
|
|
||||||
# XML escaped version of chr
|
|
||||||
def xchr
|
|
||||||
n = XChar::CP1252[self] || self
|
|
||||||
case n when *XChar::VALID
|
|
||||||
XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
|
|
||||||
else
|
|
||||||
'*'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
# Enhance the String class with a XML escaped character version of
|
|
||||||
# to_s.
|
|
||||||
#
|
|
||||||
class String
|
|
||||||
# XML escaped version of to_s
|
|
||||||
def to_xs
|
|
||||||
unpack('U*').map {|n| n.xchr}.join # ASCII, UTF-8
|
|
||||||
rescue
|
|
||||||
unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
#!/usr/bin/env ruby
|
|
||||||
|
|
||||||
module Builder
|
|
||||||
|
|
||||||
# Generic error for builder
|
|
||||||
class IllegalBlockError < RuntimeError; end
|
|
||||||
|
|
||||||
# XmlBase is a base class for building XML builders. See
|
|
||||||
# Builder::XmlMarkup and Builder::XmlEvents for examples.
|
|
||||||
class XmlBase < BasicObject
|
|
||||||
|
|
||||||
# Create an XML markup builder.
|
|
||||||
#
|
|
||||||
# out:: Object receiving the markup. +out+ must respond to
|
|
||||||
# <tt><<</tt>.
|
|
||||||
# indent:: Number of spaces used for indentation (0 implies no
|
|
||||||
# indentation and no line breaks).
|
|
||||||
# initial:: Level of initial indentation.
|
|
||||||
#
|
|
||||||
def initialize(indent=0, initial=0)
|
|
||||||
@indent = indent
|
|
||||||
@level = initial
|
|
||||||
end
|
|
||||||
|
|
||||||
# Create a tag named +sym+. Other than the first argument which
|
|
||||||
# is the tag name, the arguments are the same as the tags
|
|
||||||
# implemented via <tt>method_missing</tt>.
|
|
||||||
def tag!(sym, *args, &block)
|
|
||||||
method_missing(sym.to_sym, *args, &block)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Create XML markup based on the name of the method. This method
|
|
||||||
# is never invoked directly, but is called for each markup method
|
|
||||||
# in the markup block.
|
|
||||||
def method_missing(sym, *args, &block)
|
|
||||||
text = nil
|
|
||||||
attrs = nil
|
|
||||||
sym = "#{sym}:#{args.shift}" if args.first.kind_of?(::Symbol)
|
|
||||||
args.each do |arg|
|
|
||||||
case arg
|
|
||||||
when ::Hash
|
|
||||||
attrs ||= {}
|
|
||||||
attrs.merge!(arg)
|
|
||||||
else
|
|
||||||
text ||= ''
|
|
||||||
text << arg.to_s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if block
|
|
||||||
unless text.nil?
|
|
||||||
raise ::ArgumentError, "XmlMarkup cannot mix a text argument with a block"
|
|
||||||
end
|
|
||||||
_indent
|
|
||||||
_start_tag(sym, attrs)
|
|
||||||
_newline
|
|
||||||
_nested_structures(block)
|
|
||||||
_indent
|
|
||||||
_end_tag(sym)
|
|
||||||
_newline
|
|
||||||
elsif text.nil?
|
|
||||||
_indent
|
|
||||||
_start_tag(sym, attrs, true)
|
|
||||||
_newline
|
|
||||||
else
|
|
||||||
_indent
|
|
||||||
_start_tag(sym, attrs)
|
|
||||||
text! text
|
|
||||||
_end_tag(sym)
|
|
||||||
_newline
|
|
||||||
end
|
|
||||||
@target
|
|
||||||
end
|
|
||||||
|
|
||||||
# Append text to the output target. Escape any markup. May be
|
|
||||||
# used within the markup brackets as:
|
|
||||||
#
|
|
||||||
# builder.p { |b| b.br; b.text! "HI" } #=> <p><br/>HI</p>
|
|
||||||
def text!(text)
|
|
||||||
_text(_escape(text))
|
|
||||||
end
|
|
||||||
|
|
||||||
# Append text to the output target without escaping any markup.
|
|
||||||
# May be used within the markup brackets as:
|
|
||||||
#
|
|
||||||
# builder.p { |x| x << "<br/>HI" } #=> <p><br/>HI</p>
|
|
||||||
#
|
|
||||||
# This is useful when using non-builder enabled software that
|
|
||||||
# generates strings. Just insert the string directly into the
|
|
||||||
# builder without changing the inserted markup.
|
|
||||||
#
|
|
||||||
# It is also useful for stacking builder objects. Builders only
|
|
||||||
# use <tt><<</tt> to append to the target, so by supporting this
|
|
||||||
# method/operation builders can use other builders as their
|
|
||||||
# targets.
|
|
||||||
def <<(text)
|
|
||||||
_text(text)
|
|
||||||
end
|
|
||||||
|
|
||||||
# For some reason, nil? is sent to the XmlMarkup object. If nil?
|
|
||||||
# is not defined and method_missing is invoked, some strange kind
|
|
||||||
# of recursion happens. Since nil? won't ever be an XML tag, it
|
|
||||||
# is pretty safe to define it here. (Note: this is an example of
|
|
||||||
# cargo cult programming,
|
|
||||||
# cf. http://fishbowl.pastiche.org/2004/10/13/cargo_cult_programming).
|
|
||||||
def nil?
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
require 'builder/xchar'
|
|
||||||
def _escape(text)
|
|
||||||
text.to_xs
|
|
||||||
end
|
|
||||||
|
|
||||||
def _escape_quote(text)
|
|
||||||
_escape(text).gsub(%r{"}, '"') # " WART
|
|
||||||
end
|
|
||||||
|
|
||||||
def _newline
|
|
||||||
return if @indent == 0
|
|
||||||
text! "\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
def _indent
|
|
||||||
return if @indent == 0 || @level == 0
|
|
||||||
text!(" " * (@level * @indent))
|
|
||||||
end
|
|
||||||
|
|
||||||
def _nested_structures(block)
|
|
||||||
@level += 1
|
|
||||||
block.call(self)
|
|
||||||
ensure
|
|
||||||
@level -= 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#!/usr/bin/env ruby
|
|
||||||
|
|
||||||
#--
|
|
||||||
# Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
|
|
||||||
# All rights reserved.
|
|
||||||
|
|
||||||
# Permission is granted for use, copying, modification, distribution,
|
|
||||||
# and distribution of modified versions of this work as long as the
|
|
||||||
# above copyright notice is included.
|
|
||||||
#++
|
|
||||||
|
|
||||||
require 'builder/xmlmarkup'
|
|
||||||
|
|
||||||
module Builder
|
|
||||||
|
|
||||||
# Create a series of SAX-like XML events (e.g. start_tag, end_tag)
|
|
||||||
# from the markup code. XmlEvent objects are used in a way similar
|
|
||||||
# to XmlMarkup objects, except that a series of events are generated
|
|
||||||
# and passed to a handler rather than generating character-based
|
|
||||||
# markup.
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# xe = Builder::XmlEvents.new(handler)
|
|
||||||
# xe.title("HI") # Sends start_tag/end_tag/text messages to the handler.
|
|
||||||
#
|
|
||||||
# Indentation may also be selected by providing value for the
|
|
||||||
# indentation size and initial indentation level.
|
|
||||||
#
|
|
||||||
# xe = Builder::XmlEvents.new(handler, indent_size, initial_indent_level)
|
|
||||||
#
|
|
||||||
# == XML Event Handler
|
|
||||||
#
|
|
||||||
# The handler object must expect the following events.
|
|
||||||
#
|
|
||||||
# [<tt>start_tag(tag, attrs)</tt>]
|
|
||||||
# Announces that a new tag has been found. +tag+ is the name of
|
|
||||||
# the tag and +attrs+ is a hash of attributes for the tag.
|
|
||||||
#
|
|
||||||
# [<tt>end_tag(tag)</tt>]
|
|
||||||
# Announces that an end tag for +tag+ has been found.
|
|
||||||
#
|
|
||||||
# [<tt>text(text)</tt>]
|
|
||||||
# Announces that a string of characters (+text+) has been found.
|
|
||||||
# A series of characters may be broken up into more than one
|
|
||||||
# +text+ call, so the client cannot assume that a single
|
|
||||||
# callback contains all the text data.
|
|
||||||
#
|
|
||||||
class XmlEvents < XmlMarkup
|
|
||||||
def text!(text)
|
|
||||||
@target.text(text)
|
|
||||||
end
|
|
||||||
|
|
||||||
def _start_tag(sym, attrs, end_too=false)
|
|
||||||
@target.start_tag(sym, attrs)
|
|
||||||
_end_tag(sym) if end_too
|
|
||||||
end
|
|
||||||
|
|
||||||
def _end_tag(sym)
|
|
||||||
@target.end_tag(sym)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -1,328 +0,0 @@
|
|||||||
#!/usr/bin/env ruby
|
|
||||||
#--
|
|
||||||
# Copyright 2004, 2005 by Jim Weirich (jim@weirichhouse.org).
|
|
||||||
# All rights reserved.
|
|
||||||
|
|
||||||
# Permission is granted for use, copying, modification, distribution,
|
|
||||||
# and distribution of modified versions of this work as long as the
|
|
||||||
# above copyright notice is included.
|
|
||||||
#++
|
|
||||||
|
|
||||||
# Provide a flexible and easy to use Builder for creating XML markup.
|
|
||||||
# See XmlBuilder for usage details.
|
|
||||||
|
|
||||||
require 'builder/xmlbase'
|
|
||||||
|
|
||||||
module Builder
|
|
||||||
|
|
||||||
# Create XML markup easily. All (well, almost all) methods sent to
|
|
||||||
# an XmlMarkup object will be translated to the equivalent XML
|
|
||||||
# markup. Any method with a block will be treated as an XML markup
|
|
||||||
# tag with nested markup in the block.
|
|
||||||
#
|
|
||||||
# Examples will demonstrate this easier than words. In the
|
|
||||||
# following, +xm+ is an +XmlMarkup+ object.
|
|
||||||
#
|
|
||||||
# xm.em("emphasized") # => <em>emphasized</em>
|
|
||||||
# xm.em { xmm.b("emp & bold") } # => <em><b>emph & bold</b></em>
|
|
||||||
# xm.a("A Link", "href"=>"http://onestepback.org")
|
|
||||||
# # => <a href="http://onestepback.org">A Link</a>
|
|
||||||
# xm.div { br } # => <div><br/></div>
|
|
||||||
# xm.target("name"=>"compile", "option"=>"fast")
|
|
||||||
# # => <target option="fast" name="compile"\>
|
|
||||||
# # NOTE: order of attributes is not specified.
|
|
||||||
#
|
|
||||||
# xm.instruct! # <?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
# xm.html { # <html>
|
|
||||||
# xm.head { # <head>
|
|
||||||
# xm.title("History") # <title>History</title>
|
|
||||||
# } # </head>
|
|
||||||
# xm.body { # <body>
|
|
||||||
# xm.comment! "HI" # <! -- HI -->
|
|
||||||
# xm.h1("Header") # <h1>Header</h1>
|
|
||||||
# xm.p("paragraph") # <p>paragraph</p>
|
|
||||||
# } # </body>
|
|
||||||
# } # </html>
|
|
||||||
#
|
|
||||||
# == Notes:
|
|
||||||
#
|
|
||||||
# * The order that attributes are inserted in markup tags is
|
|
||||||
# undefined.
|
|
||||||
#
|
|
||||||
# * Sometimes you wish to insert text without enclosing tags. Use
|
|
||||||
# the <tt>text!</tt> method to accomplish this.
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# xm.div { # <div>
|
|
||||||
# xm.text! "line"; xm.br # line<br/>
|
|
||||||
# xm.text! "another line"; xmbr # another line<br/>
|
|
||||||
# } # </div>
|
|
||||||
#
|
|
||||||
# * The special XML characters <, >, and & are converted to <,
|
|
||||||
# > and & automatically. Use the <tt><<</tt> operation to
|
|
||||||
# insert text without modification.
|
|
||||||
#
|
|
||||||
# * Sometimes tags use special characters not allowed in ruby
|
|
||||||
# identifiers. Use the <tt>tag!</tt> method to handle these
|
|
||||||
# cases.
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# xml.tag!("SOAP:Envelope") { ... }
|
|
||||||
#
|
|
||||||
# will produce ...
|
|
||||||
#
|
|
||||||
# <SOAP:Envelope> ... </SOAP:Envelope>"
|
|
||||||
#
|
|
||||||
# <tt>tag!</tt> will also take text and attribute arguments (after
|
|
||||||
# the tag name) like normal markup methods. (But see the next
|
|
||||||
# bullet item for a better way to handle XML namespaces).
|
|
||||||
#
|
|
||||||
# * Direct support for XML namespaces is now available. If the
|
|
||||||
# first argument to a tag call is a symbol, it will be joined to
|
|
||||||
# the tag to produce a namespace:tag combination. It is easier to
|
|
||||||
# show this than describe it.
|
|
||||||
#
|
|
||||||
# xml.SOAP :Envelope do ... end
|
|
||||||
#
|
|
||||||
# Just put a space before the colon in a namespace to produce the
|
|
||||||
# right form for builder (e.g. "<tt>SOAP:Envelope</tt>" =>
|
|
||||||
# "<tt>xml.SOAP :Envelope</tt>")
|
|
||||||
#
|
|
||||||
# * XmlMarkup builds the markup in any object (called a _target_)
|
|
||||||
# that accepts the <tt><<</tt> method. If no target is given,
|
|
||||||
# then XmlMarkup defaults to a string target.
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
#
|
|
||||||
# xm = Builder::XmlMarkup.new
|
|
||||||
# result = xm.title("yada")
|
|
||||||
# # result is a string containing the markup.
|
|
||||||
#
|
|
||||||
# buffer = ""
|
|
||||||
# xm = Builder::XmlMarkup.new(buffer)
|
|
||||||
# # The markup is appended to buffer (using <<)
|
|
||||||
#
|
|
||||||
# xm = Builder::XmlMarkup.new(STDOUT)
|
|
||||||
# # The markup is written to STDOUT (using <<)
|
|
||||||
#
|
|
||||||
# xm = Builder::XmlMarkup.new
|
|
||||||
# x2 = Builder::XmlMarkup.new(:target=>xm)
|
|
||||||
# # Markup written to +x2+ will be send to +xm+.
|
|
||||||
#
|
|
||||||
# * Indentation is enabled by providing the number of spaces to
|
|
||||||
# indent for each level as a second argument to XmlBuilder.new.
|
|
||||||
# Initial indentation may be specified using a third parameter.
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# xm = Builder.new(:indent=>2)
|
|
||||||
# # xm will produce nicely formatted and indented XML.
|
|
||||||
#
|
|
||||||
# xm = Builder.new(:indent=>2, :margin=>4)
|
|
||||||
# # xm will produce nicely formatted and indented XML with 2
|
|
||||||
# # spaces per indent and an over all indentation level of 4.
|
|
||||||
#
|
|
||||||
# builder = Builder::XmlMarkup.new(:target=>$stdout, :indent=>2)
|
|
||||||
# builder.name { |b| b.first("Jim"); b.last("Weirich) }
|
|
||||||
# # prints:
|
|
||||||
# # <name>
|
|
||||||
# # <first>Jim</first>
|
|
||||||
# # <last>Weirich</last>
|
|
||||||
# # </name>
|
|
||||||
#
|
|
||||||
# * The instance_eval implementation which forces self to refer to
|
|
||||||
# the message receiver as self is now obsolete. We now use normal
|
|
||||||
# block calls to execute the markup block. This means that all
|
|
||||||
# markup methods must now be explicitly send to the xml builder.
|
|
||||||
# For instance, instead of
|
|
||||||
#
|
|
||||||
# xml.div { strong("text") }
|
|
||||||
#
|
|
||||||
# you need to write:
|
|
||||||
#
|
|
||||||
# xml.div { xml.strong("text") }
|
|
||||||
#
|
|
||||||
# Although more verbose, the subtle change in semantics within the
|
|
||||||
# block was found to be prone to error. To make this change a
|
|
||||||
# little less cumbersome, the markup block now gets the markup
|
|
||||||
# object sent as an argument, allowing you to use a shorter alias
|
|
||||||
# within the block.
|
|
||||||
#
|
|
||||||
# For example:
|
|
||||||
#
|
|
||||||
# xml_builder = Builder::XmlMarkup.new
|
|
||||||
# xml_builder.div { |xml|
|
|
||||||
# xml.stong("text")
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
class XmlMarkup < XmlBase
|
|
||||||
|
|
||||||
# Create an XML markup builder. Parameters are specified by an
|
|
||||||
# option hash.
|
|
||||||
#
|
|
||||||
# :target=><em>target_object</em>::
|
|
||||||
# Object receiving the markup. +out+ must respond to the
|
|
||||||
# <tt><<</tt> operator. The default is a plain string target.
|
|
||||||
#
|
|
||||||
# :indent=><em>indentation</em>::
|
|
||||||
# Number of spaces used for indentation. The default is no
|
|
||||||
# indentation and no line breaks.
|
|
||||||
#
|
|
||||||
# :margin=><em>initial_indentation_level</em>::
|
|
||||||
# Amount of initial indentation (specified in levels, not
|
|
||||||
# spaces).
|
|
||||||
#
|
|
||||||
# :escape_attrs=><b>OBSOLETE</em>::
|
|
||||||
# The :escape_attrs option is no longer supported by builder
|
|
||||||
# (and will be quietly ignored). String attribute values are
|
|
||||||
# now automatically escaped. If you need unescaped attribute
|
|
||||||
# values (perhaps you are using entities in the attribute
|
|
||||||
# values), then give the value as a Symbol. This allows much
|
|
||||||
# finer control over escaping attribute values.
|
|
||||||
#
|
|
||||||
def initialize(options={})
|
|
||||||
indent = options[:indent] || 0
|
|
||||||
margin = options[:margin] || 0
|
|
||||||
super(indent, margin)
|
|
||||||
@target = options[:target] || ""
|
|
||||||
end
|
|
||||||
|
|
||||||
# Return the target of the builder.
|
|
||||||
def target!
|
|
||||||
@target
|
|
||||||
end
|
|
||||||
|
|
||||||
def comment!(comment_text)
|
|
||||||
_ensure_no_block ::Kernel.block_given?
|
|
||||||
_special("<!-- ", " -->", comment_text, nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Insert an XML declaration into the XML markup.
|
|
||||||
#
|
|
||||||
# For example:
|
|
||||||
#
|
|
||||||
# xml.declare! :ELEMENT, :blah, "yada"
|
|
||||||
# # => <!ELEMENT blah "yada">
|
|
||||||
def declare!(inst, *args, &block)
|
|
||||||
_indent
|
|
||||||
@target << "<!#{inst}"
|
|
||||||
args.each do |arg|
|
|
||||||
case arg
|
|
||||||
when ::String
|
|
||||||
@target << %{ "#{arg}"} # " WART
|
|
||||||
when ::Symbol
|
|
||||||
@target << " #{arg}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if ::Kernel.block_given?
|
|
||||||
@target << " ["
|
|
||||||
_newline
|
|
||||||
_nested_structures(block)
|
|
||||||
@target << "]"
|
|
||||||
end
|
|
||||||
@target << ">"
|
|
||||||
_newline
|
|
||||||
end
|
|
||||||
|
|
||||||
# Insert a processing instruction into the XML markup. E.g.
|
|
||||||
#
|
|
||||||
# For example:
|
|
||||||
#
|
|
||||||
# xml.instruct!
|
|
||||||
# #=> <?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
# xml.instruct! :aaa, :bbb=>"ccc"
|
|
||||||
# #=> <?aaa bbb="ccc"?>
|
|
||||||
#
|
|
||||||
def instruct!(directive_tag=:xml, attrs={})
|
|
||||||
_ensure_no_block ::Kernel.block_given?
|
|
||||||
if directive_tag == :xml
|
|
||||||
a = { :version=>"1.0", :encoding=>"UTF-8" }
|
|
||||||
attrs = a.merge attrs
|
|
||||||
end
|
|
||||||
_special(
|
|
||||||
"<?#{directive_tag}",
|
|
||||||
"?>",
|
|
||||||
nil,
|
|
||||||
attrs,
|
|
||||||
[:version, :encoding, :standalone])
|
|
||||||
end
|
|
||||||
|
|
||||||
# Insert a CDATA section into the XML markup.
|
|
||||||
#
|
|
||||||
# For example:
|
|
||||||
#
|
|
||||||
# xml.cdata!("text to be included in cdata")
|
|
||||||
# #=> <![CDATA[text to be included in cdata]]>
|
|
||||||
#
|
|
||||||
def cdata!(text)
|
|
||||||
_ensure_no_block ::Kernel.block_given?
|
|
||||||
_special("<![CDATA[", "]]>", text, nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# NOTE: All private methods of a builder object are prefixed when
|
|
||||||
# a "_" character to avoid possible conflict with XML tag names.
|
|
||||||
|
|
||||||
# Insert text directly in to the builder's target.
|
|
||||||
def _text(text)
|
|
||||||
@target << text
|
|
||||||
end
|
|
||||||
|
|
||||||
# Insert special instruction.
|
|
||||||
def _special(open, close, data=nil, attrs=nil, order=[])
|
|
||||||
_indent
|
|
||||||
@target << open
|
|
||||||
@target << data if data
|
|
||||||
_insert_attributes(attrs, order) if attrs
|
|
||||||
@target << close
|
|
||||||
_newline
|
|
||||||
end
|
|
||||||
|
|
||||||
# Start an XML tag. If <tt>end_too</tt> is true, then the start
|
|
||||||
# tag is also the end tag (e.g. <br/>
|
|
||||||
def _start_tag(sym, attrs, end_too=false)
|
|
||||||
@target << "<#{sym}"
|
|
||||||
_insert_attributes(attrs)
|
|
||||||
@target << "/" if end_too
|
|
||||||
@target << ">"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Insert an ending tag.
|
|
||||||
def _end_tag(sym)
|
|
||||||
@target << "</#{sym}>"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Insert the attributes (given in the hash).
|
|
||||||
def _insert_attributes(attrs, order=[])
|
|
||||||
return if attrs.nil?
|
|
||||||
order.each do |k|
|
|
||||||
v = attrs[k]
|
|
||||||
@target << %{ #{k}="#{_attr_value(v)}"} if v # " WART
|
|
||||||
end
|
|
||||||
attrs.each do |k, v|
|
|
||||||
@target << %{ #{k}="#{_attr_value(v)}"} unless order.member?(k) # " WART
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def _attr_value(value)
|
|
||||||
case value
|
|
||||||
when ::Symbol
|
|
||||||
value.to_s
|
|
||||||
else
|
|
||||||
_escape_quote(value.to_s)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def _ensure_no_block(got_block)
|
|
||||||
if got_block
|
|
||||||
fail IllegalBlockError,
|
|
||||||
"Blocks are not allowed on XML instructions"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -505,7 +505,7 @@ class HashToXmlTest < Test::Unit::TestCase
|
|||||||
assert_equal "<person>", xml.first(8)
|
assert_equal "<person>", xml.first(8)
|
||||||
assert xml.include?(%(<street>Paulina</street>))
|
assert xml.include?(%(<street>Paulina</street>))
|
||||||
assert xml.include?(%(<name>David</name>))
|
assert xml.include?(%(<name>David</name>))
|
||||||
assert xml.include?(%(<age nil="true"></age>))
|
assert_includes xml, %(<age nil="true"/>)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_one_level_with_skipping_types
|
def test_one_level_with_skipping_types
|
||||||
@@ -513,7 +513,7 @@ class HashToXmlTest < Test::Unit::TestCase
|
|||||||
assert_equal "<person>", xml.first(8)
|
assert_equal "<person>", xml.first(8)
|
||||||
assert xml.include?(%(<street>Paulina</street>))
|
assert xml.include?(%(<street>Paulina</street>))
|
||||||
assert xml.include?(%(<name>David</name>))
|
assert xml.include?(%(<name>David</name>))
|
||||||
assert xml.include?(%(<age nil="true"></age>))
|
assert_includes xml, %(<age nil="true"/>)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_one_level_with_yielding
|
def test_one_level_with_yielding
|
||||||
@@ -618,12 +618,12 @@ class HashToXmlTest < Test::Unit::TestCase
|
|||||||
EOT
|
EOT
|
||||||
|
|
||||||
expected_topic_hash = {
|
expected_topic_hash = {
|
||||||
:title => nil,
|
:title => nil,
|
||||||
:id => nil,
|
:id => nil,
|
||||||
:approved => nil,
|
:approved => nil,
|
||||||
:written_on => nil,
|
:written_on => nil,
|
||||||
:viewed_at => nil,
|
:viewed_at => nil,
|
||||||
:content => nil,
|
:content => nil,
|
||||||
:parent_id => nil
|
:parent_id => nil
|
||||||
}.stringify_keys
|
}.stringify_keys
|
||||||
|
|
||||||
@@ -701,7 +701,7 @@ class HashToXmlTest < Test::Unit::TestCase
|
|||||||
|
|
||||||
assert_equal expected_topic_hash, Hash.from_xml(topic_xml)["rsp"]["photos"]["photo"]
|
assert_equal expected_topic_hash, Hash.from_xml(topic_xml)["rsp"]["photos"]["photo"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_empty_array_from_xml
|
def test_empty_array_from_xml
|
||||||
blog_xml = <<-XML
|
blog_xml = <<-XML
|
||||||
<blog>
|
<blog>
|
||||||
@@ -815,13 +815,13 @@ class HashToXmlTest < Test::Unit::TestCase
|
|||||||
|
|
||||||
assert_equal expected_bacon_hash, Hash.from_xml(bacon_xml)["bacon"]
|
assert_equal expected_bacon_hash, Hash.from_xml(bacon_xml)["bacon"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_type_trickles_through_when_unknown
|
def test_type_trickles_through_when_unknown
|
||||||
product_xml = <<-EOT
|
product_xml = <<-EOT
|
||||||
<product>
|
<product>
|
||||||
<weight type="double">0.5</weight>
|
<weight type="double">0.5</weight>
|
||||||
<image type="ProductImage"><filename>image.gif</filename></image>
|
<image type="ProductImage"><filename>image.gif</filename></image>
|
||||||
|
|
||||||
</product>
|
</product>
|
||||||
EOT
|
EOT
|
||||||
|
|
||||||
@@ -830,7 +830,7 @@ class HashToXmlTest < Test::Unit::TestCase
|
|||||||
:image => {'type' => 'ProductImage', 'filename' => 'image.gif' },
|
:image => {'type' => 'ProductImage', 'filename' => 'image.gif' },
|
||||||
}.stringify_keys
|
}.stringify_keys
|
||||||
|
|
||||||
assert_equal expected_product_hash, Hash.from_xml(product_xml)["product"]
|
assert_equal expected_product_hash, Hash.from_xml(product_xml)["product"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_should_use_default_value_for_unknown_key
|
def test_should_use_default_value_for_unknown_key
|
||||||
@@ -864,41 +864,41 @@ class HashToXmlTest < Test::Unit::TestCase
|
|||||||
assert_equal expected, hash.to_xml(@xml_options)
|
assert_equal expected, hash.to_xml(@xml_options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_empty_string_works_for_typecast_xml_value
|
def test_empty_string_works_for_typecast_xml_value
|
||||||
assert_nothing_raised do
|
assert_nothing_raised do
|
||||||
Hash.__send__(:typecast_xml_value, "")
|
Hash.__send__(:typecast_xml_value, "")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_escaping_to_xml
|
def test_escaping_to_xml
|
||||||
hash = {
|
hash = {
|
||||||
:bare_string => 'First & Last Name',
|
:bare_string => 'First & Last Name',
|
||||||
:pre_escaped_string => 'First & Last Name'
|
:pre_escaped_string => 'First & Last Name'
|
||||||
}.stringify_keys
|
}.stringify_keys
|
||||||
|
|
||||||
expected_xml = '<person><bare-string>First & Last Name</bare-string><pre-escaped-string>First &amp; Last Name</pre-escaped-string></person>'
|
expected_xml = '<person><bare-string>First & Last Name</bare-string><pre-escaped-string>First &amp; Last Name</pre-escaped-string></person>'
|
||||||
assert_equal expected_xml, hash.to_xml(@xml_options)
|
assert_equal expected_xml, hash.to_xml(@xml_options)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_unescaping_from_xml
|
def test_unescaping_from_xml
|
||||||
xml_string = '<person><bare-string>First & Last Name</bare-string><pre-escaped-string>First &amp; Last Name</pre-escaped-string></person>'
|
xml_string = '<person><bare-string>First & Last Name</bare-string><pre-escaped-string>First &amp; Last Name</pre-escaped-string></person>'
|
||||||
expected_hash = {
|
expected_hash = {
|
||||||
:bare_string => 'First & Last Name',
|
:bare_string => 'First & Last Name',
|
||||||
:pre_escaped_string => 'First & Last Name'
|
:pre_escaped_string => 'First & Last Name'
|
||||||
}.stringify_keys
|
}.stringify_keys
|
||||||
assert_equal expected_hash, Hash.from_xml(xml_string)['person']
|
assert_equal expected_hash, Hash.from_xml(xml_string)['person']
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_roundtrip_to_xml_from_xml
|
def test_roundtrip_to_xml_from_xml
|
||||||
hash = {
|
hash = {
|
||||||
:bare_string => 'First & Last Name',
|
:bare_string => 'First & Last Name',
|
||||||
:pre_escaped_string => 'First & Last Name'
|
:pre_escaped_string => 'First & Last Name'
|
||||||
}.stringify_keys
|
}.stringify_keys
|
||||||
|
|
||||||
assert_equal hash, Hash.from_xml(hash.to_xml(@xml_options))['person']
|
assert_equal hash, Hash.from_xml(hash.to_xml(@xml_options))['person']
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_to_xml_dups_options
|
def test_to_xml_dups_options
|
||||||
options = {:skip_instruct => true}
|
options = {:skip_instruct => true}
|
||||||
{}.to_xml(options)
|
{}.to_xml(options)
|
||||||
@@ -916,7 +916,7 @@ class HashToXmlTest < Test::Unit::TestCase
|
|||||||
assert alert_at.utc?
|
assert alert_at.utc?
|
||||||
assert_equal Time.utc(2008, 2, 10, 15, 30, 45), alert_at
|
assert_equal Time.utc(2008, 2, 10, 15, 30, 45), alert_at
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_datetime_xml_type_with_non_utc_time
|
def test_datetime_xml_type_with_non_utc_time
|
||||||
alert_xml = <<-XML
|
alert_xml = <<-XML
|
||||||
<alert>
|
<alert>
|
||||||
@@ -927,7 +927,7 @@ class HashToXmlTest < Test::Unit::TestCase
|
|||||||
assert alert_at.utc?
|
assert alert_at.utc?
|
||||||
assert_equal Time.utc(2008, 2, 10, 15, 30, 45), alert_at
|
assert_equal Time.utc(2008, 2, 10, 15, 30, 45), alert_at
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_datetime_xml_type_with_far_future_date
|
def test_datetime_xml_type_with_far_future_date
|
||||||
alert_xml = <<-XML
|
alert_xml = <<-XML
|
||||||
<alert>
|
<alert>
|
||||||
|
|||||||
Reference in New Issue
Block a user