eimxml 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,58 @@
1
+ = Easy IMplemented XML
2
+ :lang:ja
3
+ Easy IMplemented XML(EimXML)は、RubyスクリプトからXMLを作成するためのライブラリです。
4
+ 動作が軽くなるように、単純さを心がけて実装しています。
5
+
6
+ :lang:en
7
+ Easy IMplemented XML(EimXML) is library to construct XML on Ruby.
8
+ For light weight performance, this library is implemented simply.
9
+
10
+ :lang:
11
+ = URLs
12
+ * Document(Japanese)[http://eimxml.rubyforge.org/ja/]
13
+ * Document(English)[http://eimxml.rubyforge.org/en/]
14
+ * MercurialRepository[https://hg.hinet.mydns.jp/eim_xml/]
15
+
16
+ = Sample
17
+ :lang:ja
18
+ 例えば、次のようなHTMLを作成する場合は
19
+
20
+ :lang:en
21
+ For example, to construct html like bellow
22
+
23
+ :lang:
24
+ <html>
25
+ <head>
26
+ <title>TITLE</title>
27
+ </head>
28
+ <body>
29
+ <p>Texts...</p>
30
+ </body>
31
+ </html>
32
+
33
+ :lang:ja
34
+ スクリプトは以下のように記述します。
35
+
36
+ :lang:en
37
+ write script like bellow.
38
+
39
+ :lang:
40
+ #!/usr/bin/ruby
41
+ # require "rubygems"
42
+ require "eim_xml/xhtml"
43
+
44
+ include EimXML::XHTML
45
+ html = HTML.new do |html|
46
+ html << Head.new do |head|
47
+ head << Title.new do |title|
48
+ title << "TITLE"
49
+ end
50
+ end
51
+ html << Body.new do |body|
52
+ body << P.new do |par|
53
+ par << "Text..."
54
+ end
55
+ end
56
+ end
57
+
58
+ html.write($stdout, false)
data/Rakefile ADDED
@@ -0,0 +1,94 @@
1
+ require "rake/clean"
2
+ require "rake/testtask"
3
+ require "rake/rdoctask"
4
+ require "rake/gempackagetask"
5
+
6
+ FILES = FileList["**/*"].exclude("pkg", "html")
7
+
8
+ task :default => :test
9
+
10
+ ### Document ###
11
+ RDOC_DIR = "./html/"
12
+ RDOC_OPTS = ["-S", "-w", "3", "-c", "UTF-8", "-m", "README"]
13
+ RDOC_OPTS << "-d" if ENV["DOT"]
14
+ RDOC_FILES = FileList["lib/**/*.rb"]
15
+ RDOC_EXTRAS = FileList["README"]
16
+ ["", "ja", "en"].each do |l|
17
+ dir = RDOC_DIR.dup
18
+ dir << "#{l}/" unless l.empty?
19
+ Rake::RDocTask.new("rdoc#{":"+l unless l.empty?}") do |rdoc|
20
+ rdoc.title = "Easy IMplemented XML"
21
+ rdoc.options = RDOC_OPTS.dup
22
+ rdoc.options << "-l" << l unless l.empty?
23
+ rdoc.rdoc_dir = dir
24
+ rdoc.rdoc_files.include(RDOC_FILES, RDOC_EXTRAS)
25
+ end
26
+ end
27
+ task "rdoc:all" => ["rdoc", "rdoc:ja", "rdoc:en"]
28
+ task "rerdoc:all" => ["rerdoc", "rerdoc:ja", "rerdoc:en"]
29
+
30
+
31
+ ### Publish document ###
32
+ task :publish => [:clobber_rdoc, "rdoc:ja", "rdoc:en"] do
33
+ require "rake/contrib/rubyforgepublisher"
34
+ cp "index.html", "html/index.html"
35
+ Rake::RubyForgePublisher.new("eimxml", "hiraku").upload
36
+ end
37
+
38
+ ### Test ###
39
+ task :test => "test:apart"
40
+ namespace :test do
41
+ FileList["test/*_test.rb"].sort{|a,b| File.mtime(a)<=>File.mtime(b)}.reverse.each do |i|
42
+ Rake::TestTask.new(:apart) do |t|
43
+ t.test_files = i
44
+ end
45
+ end
46
+ task(:apart).comment = "Run tests separately"
47
+
48
+ Rake::TestTask.new(:lump) do |t|
49
+ t.test_files = FileList["test/*_test.rb"]
50
+ end
51
+ task(:lump).comment = "Run all tests in a lump"
52
+ end
53
+
54
+ ### Build GEM ###
55
+ GEM_DIR = "./pkg"
56
+ directory GEM_DIR
57
+ def build_gem(unstable=false)
58
+ spec = Gem::Specification.new do |spec|
59
+ spec.name = "eimxml"
60
+ spec.rubyforge_project = "eimxml"
61
+ spec.version = "0.0.1"
62
+ spec.summary = "Easy IMplemented XML"
63
+ spec.author = "KURODA Hiraku"
64
+ spec.email = "hiraku@hinet.mydns.jp"
65
+ spec.homepage = "http://eimxml.rubyforge.org/"
66
+ spec.files = FILES
67
+ spec.test_files = Dir.glob("test/*.rb")
68
+ spec.has_rdoc = true
69
+ spec.rdoc_options = RDOC_OPTS.dup
70
+ spec.extra_rdoc_files = RDOC_EXTRAS
71
+ end
72
+
73
+ spec.version = spec.version.to_s << Time.now.strftime(".%Y.%m%d.%H%M") if unstable
74
+ b = Gem::Builder.new(spec)
75
+ gname = b.build
76
+ mv gname, "#{GEM_DIR}/"
77
+ end
78
+
79
+ desc "Build gem package"
80
+ task :gem => GEM_DIR do
81
+ build_gem
82
+ end
83
+
84
+ desc "Build unstable version gem package"
85
+ task "gem:unstable" do
86
+ build_gem(true)
87
+ end
88
+
89
+
90
+ ### Build package ###
91
+ package_task = Rake::PackageTask.new("eim_xml",ENV["VER"] || :noversion) do |t|
92
+ t.package_files.include(FILES)
93
+ t.need_tar_gz = true
94
+ end
@@ -0,0 +1,16 @@
1
+ require "eim_xml"
2
+
3
+ module EimXML::Assertions
4
+ def assert_has(expect, element, message="")
5
+ message << "\n" unless message.size==0
6
+ message << "<#{element}> doesn't have\n<#{expect.inspect}>"
7
+ assert_block(message) do
8
+ element.has?(expect)
9
+ end
10
+ rescue Test::Unit::AssertionFailedError=>e
11
+ bt = e.backtrace.find_all do |b|
12
+ b !~ /#{Regexp.escape(__FILE__)}/
13
+ end
14
+ raise Test::Unit::AssertionFailedError, e.message, bt
15
+ end
16
+ end
@@ -0,0 +1,99 @@
1
+ # XML parser for EimXML
2
+ #
3
+ # Copyright (C) 2006, KURODA Hiraku <hiraku@hinet.mydns.jp>
4
+ # You can redistribute it and/or modify it under GPL2.
5
+ #
6
+
7
+ require "eim_xml"
8
+ require "strscan"
9
+
10
+ module EimXML
11
+ class ParseError < StandardError
12
+ end
13
+
14
+ class Parser
15
+ attr_reader :scanner
16
+ module RE
17
+ EMPTY_ELEMENT = /<([^>]*?)\/>/
18
+ START_TAG = /<([^>]*?([^\/>]\s*))>/
19
+ END_TAG = /<\/(\S+)\s*>/
20
+ ATTRIBUTE = /\s+([^=\s]+)\s*=\s*('(.*?)'|"(.*?)")/m
21
+ STRING = /[^<]+/
22
+ end
23
+
24
+ def initialize(src, *space_holders)
25
+ @scanner = StringScanner.new(src)
26
+ @space_holders = []
27
+ @space_holder_res = []
28
+ space_holders.each do |i|
29
+ if i.is_a?(Regexp)
30
+ @space_holder_res << i
31
+ else
32
+ @space_holders << i.to_sym
33
+ end
34
+ end
35
+ end
36
+
37
+ def parse(hold_space = false)
38
+ @scanner.scan(/\s+/) unless hold_space
39
+ if @scanner.scan(RE::EMPTY_ELEMENT)
40
+ parse_empty_element(hold_space)
41
+ elsif @scanner.scan(RE::START_TAG)
42
+ parse_start_tag(hold_space)
43
+ elsif @scanner.scan(RE::STRING)
44
+ parse_string(hold_space)
45
+ else
46
+ nil
47
+ end
48
+ end
49
+
50
+ def parse_tag
51
+ s = StringScanner.new(@scanner[1])
52
+ e = Element.new(s.scan(/\S+/))
53
+ e[s[1]] = s[3] ? s[3] : s[4] while s.scan(RE::ATTRIBUTE)
54
+ e
55
+ end
56
+ protected :parse_tag
57
+
58
+ def space_holder?(ename)
59
+ return true if @space_holders.include?(ename)
60
+ s = ename.to_s
61
+ @space_holder_res.each do |re|
62
+ return true if re=~s
63
+ end
64
+ false
65
+ end
66
+
67
+ def parse_empty_element(hold_space)
68
+ e = parse_tag
69
+ hold_space = space_holder?(e.name) unless hold_space
70
+ e.hold_space if hold_space
71
+ e
72
+ end
73
+ protected :parse_empty_element
74
+
75
+ def parse_start_tag(hold_space)
76
+ e = parse_tag
77
+ hold_space = space_holder?(e.name) unless hold_space
78
+
79
+ e.hold_space if hold_space
80
+ @scanner.scan(/\s*/) unless hold_space
81
+ until @scanner.scan(RE::END_TAG)
82
+ c = parse(hold_space)
83
+ raise ParseError.new("Syntax error.") unless c
84
+ e << c
85
+ @scanner.scan(/\s*/) unless hold_space
86
+ end
87
+ raise ParseError.new("End tag mismatched.") unless @scanner[1].to_sym==e.name
88
+ e
89
+ end
90
+ protected :parse_start_tag
91
+
92
+ def parse_string(hold_space)
93
+ s = @scanner[0]
94
+ s.strip! unless hold_space
95
+ PCString.new(s)
96
+ end
97
+ protected :parse_string
98
+ end
99
+ end
data/lib/eim_xml.rb ADDED
@@ -0,0 +1,235 @@
1
+ # Easy IMplementation of XML
2
+ #
3
+ # Copyright (C) 2006, KURODA Hiraku <hiraku@hinet.mydns.jp>
4
+ # You can redistribute it and/or modify it under GPL2.
5
+ #
6
+
7
+ module EimXML
8
+ XML_DECLARATION = %[<?xml version="1.0"?>]
9
+
10
+ class PCString
11
+ attr_reader :encoded_string
12
+ alias to_s encoded_string
13
+
14
+ def self.encode(s)
15
+ s.gsub(/&\#?\w+;|[&\"\'<>]/) do |m|
16
+ case m
17
+ when /&\#?\w+;/
18
+ m
19
+ when "&"
20
+ "&amp;"
21
+ when '"'
22
+ "&quot;"
23
+ when "'"
24
+ "&apos;"
25
+ when "<"
26
+ "&lt;"
27
+ when ">"
28
+ "&gt;"
29
+ end
30
+ end
31
+ end
32
+
33
+ def initialize(s, encoded=false)
34
+ @encoded_string = encoded ? s : PCString.encode(s)
35
+ end
36
+
37
+ def ==(other)
38
+ @encoded_string==other.encoded_string
39
+ end
40
+ end
41
+
42
+ class SymbolKeyHash < Hash
43
+ def initialize(src=nil)
44
+ case src
45
+ when self.class
46
+ super(src)
47
+ when Hash
48
+ src.each_key do |k|
49
+ store(k, src[k])
50
+ end
51
+ end
52
+ end
53
+
54
+ def update(src)
55
+ src = self.class.new(src) unless src.is_a?(self.class)
56
+ super(src)
57
+ end
58
+ alias :merge! :update
59
+
60
+ def merge(src)
61
+ super(self.class.new(src))
62
+ end
63
+
64
+ def store(k, v)
65
+ super(k.to_sym, v)
66
+ end
67
+
68
+ alias :[]= :store
69
+ end
70
+
71
+ class Element
72
+ attr_reader :name, :attributes, :contents
73
+
74
+ NEST = " "
75
+
76
+ def initialize(name, attributes=nil)
77
+ @name = name.to_sym
78
+ @attributes = SymbolKeyHash.new
79
+ @contents = Array.new
80
+ @hold_space = false
81
+
82
+ @attributes.update(attributes) if attributes
83
+
84
+ yield(self) if block_given?
85
+ end
86
+
87
+ def name=(new_name)
88
+ @name = new_name.to_sym
89
+ end
90
+ protected :name=
91
+
92
+ def hold_space
93
+ @hold_space = true
94
+ self
95
+ end
96
+
97
+ def unhold_space
98
+ @hold_space = false
99
+ self
100
+ end
101
+
102
+ def hold_space?
103
+ @hold_space
104
+ end
105
+
106
+ def add(v)
107
+ case v
108
+ when nil
109
+ when Element, PCString
110
+ @contents << v
111
+ when Array
112
+ v.each{|i| self.add(i)}
113
+ else
114
+ @contents << v.to_s
115
+ end
116
+ self
117
+ end
118
+ alias << add
119
+
120
+ def write(dst=String.new, level=0, is_head=true)
121
+ nest = NEST*level
122
+ head = is_head ? nest : ""
123
+ lf = @hold_space ? "" : "\n"
124
+
125
+ attributes = ""
126
+ @attributes.each do |k, v|
127
+ v = k.to_s unless v
128
+ attributes << " #{k}='#{PCString===v ? v : PCString.encode(v)}'"
129
+ end
130
+
131
+ case @contents.size
132
+ when 0
133
+ dst << "#{head}<#{@name}#{attributes} />"
134
+ when 1
135
+ dst << "#{head}<#{@name}#{attributes}>"
136
+ write_content_to(dst, @contents[0], level, false)
137
+ dst << "</#{@name}>"
138
+ else
139
+ dst << "#{head}<#{@name}#{attributes}>#{lf}"
140
+ @contents.each {|i| write_content_to(dst, i, level+1, !@hold_space) << lf}
141
+ dst << "#{@hold_space ? "" : nest}</#{@name}>"
142
+ end
143
+ end
144
+ def to_s(*args)
145
+ args.unshift("")
146
+ write(*args)
147
+ end
148
+ alias :inspect :to_s
149
+
150
+ def write_content_to(dst, c, level, is_head)
151
+ return c.write(dst, level, is_head) if c.is_a?(Element)
152
+ dst << (is_head ? NEST*level : "") + (c.is_a?(PCString) ? c.to_s : PCString.encode(c))
153
+ end
154
+ private :write_content_to
155
+
156
+ def ==(xml)
157
+ return false unless xml.is_a?(Element)
158
+ (@name==xml.name && @attributes==xml.attributes && @contents==xml.contents && @hold_space==xml.hold_space?)
159
+ end
160
+
161
+ def add_attribute(key, value)
162
+ @attributes[key.to_sym] = value
163
+ end
164
+ alias []= add_attribute
165
+
166
+ def [](key)
167
+ if key.is_a?(Fixnum)
168
+ @contents[key]
169
+ else
170
+ @attributes[key.to_sym]
171
+ end
172
+ end
173
+
174
+ def del_attribute(key)
175
+ @attributes.delete(key.to_sym)
176
+ end
177
+
178
+ def match?(name, attrs=nil)
179
+ case name
180
+ when Module
181
+ return is_a?(name)
182
+ when Element
183
+ return match?(name.name, name.attributes)
184
+ when Array
185
+ return match?(name[0], name[1])
186
+ end
187
+
188
+ if name.is_a?(Regexp)
189
+ return false unless name=~@name.to_s
190
+ else
191
+ return false unless @name==name
192
+ end
193
+
194
+ (attrs||[]).all? do |k, v|
195
+ if k.is_a?(Regexp)
196
+ @attributes.any? do |sk, sv|
197
+ next false unless k===sk.to_s
198
+ v===sv
199
+ end
200
+ else
201
+ v===@attributes[k]
202
+ end
203
+ end
204
+ end
205
+ alias :=~ :match?
206
+
207
+ def has?(name, attrs=nil, find_deep=true)
208
+ return true if match?(name, attrs)
209
+ @contents.any? do |i|
210
+ if i.is_a?(Element)
211
+ if find_deep
212
+ i=~[name, attrs] || i.has?(name, attrs, find_deep)
213
+ else
214
+ i=~[name, attrs]
215
+ end
216
+ else
217
+ name.is_a?(Module) && i.is_a?(name)
218
+ end
219
+ end
220
+ end
221
+
222
+ def find(name, attrs=nil)
223
+ r = []
224
+ r << self if match?(name, attrs)
225
+ @contents.each do |i|
226
+ if i.is_a?(Element)
227
+ r.concat(i.find(name, attrs))
228
+ else
229
+ r << i if name.is_a?(Module) && i.is_a?(name)
230
+ end
231
+ end
232
+ r
233
+ end
234
+ end
235
+ end
@@ -0,0 +1,29 @@
1
+ # Test for eim_xml/assertions.rb
2
+ #
3
+ # Copyright (C) 2006, KURODA Hiraku <hiraku@hinet.mydns.jp>
4
+ # You can redistribute it and/or modify it under GPL2.
5
+
6
+ require "test/unit"
7
+ require "eim_xml/assertions"
8
+
9
+ class TC_EimXML_Assertions < Test::Unit::TestCase
10
+ include EimXML
11
+ include EimXML::Assertions
12
+
13
+ def test_assert_has
14
+ e = Element.new(:tag) do |e|
15
+ e <<= Element.new(:sub)
16
+ end
17
+
18
+ assert_nothing_raised do
19
+ assert_has(:sub, e)
20
+ end
21
+
22
+ a = assert_raises(Test::Unit::AssertionFailedError) do
23
+ assert_has(:no, e)
24
+ end
25
+ assert(!a.backtrace.any?{ |i|
26
+ i=~/eim_xml\/assertions\.rb/
27
+ })
28
+ end
29
+ end
@@ -0,0 +1,428 @@
1
+ # Test for eim_xml.rb
2
+ #
3
+ # Copyright (C) 2006, KURODA Hiraku <hiraku@hinet.mydns.jp>
4
+ # You can redistribute it and/or modify it under GPL2.
5
+
6
+ require "test/unit"
7
+ require "eim_xml"
8
+
9
+ class TC_PCString < Test::Unit::TestCase
10
+ include EimXML
11
+
12
+ def test_encode
13
+ assert_equal("&lt;&gt;&quot;&apos;&amp;", PCString.encode("<>\"'&"))
14
+ assert_equal("&test;", PCString.encode("&test;"))
15
+ assert_equal("&\#0ax;", PCString.encode("&#0ax;"))
16
+ assert_equal("&amp;test", PCString.encode("&test"))
17
+ assert_equal("&amp;\#0ax", PCString.encode("&#0ax"))
18
+ end
19
+
20
+ def test_new
21
+ assert_equal("&amp;", PCString.new("&").encoded_string)
22
+ assert_equal("&", PCString.new("&", true).encoded_string)
23
+ end
24
+
25
+ def test_equal
26
+ p1 = PCString.new("str")
27
+ p2 = PCString.new("str")
28
+ assert_equal(p1, p2)
29
+ end
30
+ end
31
+
32
+ class TC_Element < Test::Unit::TestCase
33
+ include EimXML
34
+
35
+ class Dummy < Element
36
+ def chgname(name)
37
+ self.name = name
38
+ end
39
+ end
40
+
41
+ def test_name
42
+ e = Element.new("el")
43
+ assert_equal(:el, e.name)
44
+ assert_raises(NoMethodError){e.name="changed"}
45
+
46
+ d = Dummy.new("el1")
47
+ assert_equal(:el1, d.name)
48
+ d.chgname(:el2)
49
+ assert_equal(:el2, d.name)
50
+ d.chgname("el3")
51
+ assert_equal(:el3, d.name)
52
+ end
53
+
54
+ def test_attributes
55
+ e = Element.new("el", {"a1"=>"v1", "a2"=>"v2", "a3"=>nil})
56
+ assert_equal(:el, e.name)
57
+ assert_equal({:a1=>"v1", :a2=>"v2", :a3=>nil}, e.attributes)
58
+ end
59
+
60
+ def test_bracket
61
+ e = Element.new(:el, :attr=>"value")
62
+ e << "test"
63
+ assert_equal("value", e[:attr])
64
+ assert_equal("test", e[0])
65
+ end
66
+
67
+ def test_add_attribute
68
+ e = Element.new("el")
69
+ e.add_attribute("key_str", "value1")
70
+ e.add_attribute(:key_sym, "value2")
71
+ assert_equal({:key_str=>"value1", :key_sym=>"value2"}, e.attributes)
72
+ e.add_attribute(:nil, nil)
73
+ assert_equal({:key_str=>"value1", :key_sym=>"value2", :nil=>nil}, e.attributes)
74
+ end
75
+
76
+ def test_del_attribute
77
+ e = Element.new("el", {:a1=>"v1", :a2=>"v2"})
78
+ e.del_attribute("a1")
79
+ assert_equal({:a2=>"v2"}, e.attributes)
80
+ e.del_attribute(:a2)
81
+ assert_equal({}, e.attributes)
82
+ end
83
+
84
+ def test_contents
85
+ sub = Element.new("sub")
86
+ e = Element.new("el") << "String1" << "String2" << sub
87
+ assert_equal(["String1", "String2", sub], e.contents)
88
+ end
89
+
90
+ def test_add
91
+ e = Element.new("el").add(Element.new("sub"))
92
+ assert_instance_of(Element, e, "add Element")
93
+ assert_equal(:el, e.name)
94
+
95
+ e = Element.new("el")
96
+ e.add(Element.new("sub1"))
97
+ e.add([Element.new("sub2").add("text"), "string"])
98
+ assert_equal([Element.new("sub1"), Element.new("sub2").add("text"), "string"], e.contents, "add Array")
99
+
100
+ e = Element.new("el")
101
+ e.add(nil)
102
+ assert_equal(0, e.contents.size, "add nil")
103
+
104
+ e = Element.new("el").add(:symbol)
105
+ assert_equal(["symbol"], e.contents, "add anything(which has to_s)")
106
+
107
+ e = Element.new("super") << Element.new("sub")
108
+ assert_equal(:super, e.name)
109
+ assert_equal([Element.new("sub")], e.contents)
110
+ end
111
+
112
+ def test_write
113
+ e = Element.new("el")
114
+ s = String.new
115
+ assert_equal(s.object_id, e.write(s).object_id)
116
+ assert_equal("<el />", s)
117
+
118
+ e = Element.new("super")
119
+ e << Element.new("sub")
120
+ assert_equal("<super><sub /></super>", e.write)
121
+ e << Element.new("sub2")
122
+ assert_equal("<super>\n <sub />\n <sub2 />\n</super>", e.write)
123
+ assert_equal(" <super>\n <sub />\n <sub2 />\n </super>", e.write("", 1))
124
+ assert_equal("<super>\n <sub />\n <sub2 />\n </super>", e.write("", 1, false))
125
+
126
+ s = Element.new("supersuper")
127
+ s << e
128
+ assert_equal("<supersuper><super>\n <sub />\n <sub2 />\n</super></supersuper>", s.write)
129
+
130
+ e = Element.new("el") << "str"
131
+ s = Element.new("sub")
132
+ s << "inside"
133
+ e << s
134
+ assert_equal("<el>\n str\n <sub>inside</sub>\n</el>", e.write)
135
+
136
+ e = Element.new("el")
137
+ e.attributes["a1"] = "v1"
138
+ e.attributes["a2"] = "'\"<>&"
139
+ s = e.write
140
+ assert_match(/\A<el ([^>]*) \/>\z/, s)
141
+ assert_match(/a1='v1'/, s)
142
+ assert_match(/a2='&apos;&quot;&lt;&gt;&amp;'/, s)
143
+
144
+ e = Element.new("el", {"a1"=>nil})
145
+ assert_equal("<el a1='a1' />", e.write)
146
+ end
147
+
148
+ def test_spcial_string
149
+ e = Element.new("el") << "&\"'<>"
150
+ e << PCString.new("&\"'<>", true)
151
+ e.attributes["key"] = PCString.new("&\"'<>", true)
152
+ assert_equal(%[<el key='&\"'<>'>\n &amp;&quot;&apos;&lt;&gt;\n &\"'<>\n</el>], e.to_s)
153
+ end
154
+
155
+ def test_dup
156
+ e = Element.new("el")
157
+ e.attributes["key"] = "value"
158
+ e << "String"
159
+ e << "Freeze".freeze
160
+ s = Element.new("sub")
161
+ s.attributes["subkey"] = "subvalue"
162
+ e << s
163
+ f = e.dup
164
+
165
+ assert_equal(e.attributes.object_id, f.attributes.object_id)
166
+ assert_equal(e.contents.object_id, f.contents.object_id)
167
+
168
+ assert_equal(e.to_s, f.to_s)
169
+
170
+ e = Element.new("el")
171
+ e.hold_space
172
+ f = e.dup
173
+ assert(f.hold_space?)
174
+ end
175
+
176
+ def test_clone
177
+ e = Element.new("el")
178
+ e.attributes["key"] = "value"
179
+ e << "String"
180
+ e << "Freeze".freeze
181
+ s = Element.new("sub")
182
+ s.attributes["subkey"] = "subvalue"
183
+ e << s
184
+ f = e.clone
185
+
186
+ assert_equal(e.attributes.object_id, f.attributes.object_id)
187
+ assert_equal(e.contents.object_id, f.contents.object_id)
188
+
189
+ assert_equal(e.to_s, f.to_s)
190
+
191
+ e = Element.new("el")
192
+ e.hold_space
193
+ f = e.clone
194
+ assert(f.hold_space?)
195
+ end
196
+
197
+ def test_hold_space
198
+ e = Element.new("el") << "Line1" << "Line2"
199
+ s = Element.new("sub") << "Sub1" << "Sub2"
200
+ e << s
201
+ e.hold_space
202
+ assert_equal("<el>Line1Line2<sub>\n Sub1\n Sub2\n </sub></el>", e.to_s)
203
+
204
+ e.unhold_space
205
+ assert_equal("<el>\n Line1\n Line2\n <sub>\n Sub1\n Sub2\n </sub>\n</el>", e.to_s)
206
+
207
+ e = Element.new("e")
208
+ assert_equal(e.object_id, e.hold_space.object_id)
209
+ assert_equal(e.object_id, e.unhold_space.object_id)
210
+ end
211
+
212
+ def test_equal
213
+ e1 = Element.new("el")
214
+ e1.attributes["key"] = "value"
215
+ s = Element.new("sub")
216
+ s << "String"
217
+ e1 << s
218
+ e2 = e1.dup
219
+ assert_equal(e1, e2)
220
+
221
+ e3 = Element.new("e")
222
+ e3.attributes["key"] = "value"
223
+ s = Element.new("sub")
224
+ s << "String"
225
+ e3 << s
226
+ assert_not_equal(e1, e3)
227
+
228
+ e3 = Element.new("e")
229
+ e3.attributes["k"] = "value"
230
+ s = Element.new("sub")
231
+ s << "String"
232
+ e3 << s
233
+ assert_not_equal(e1, e3)
234
+
235
+ e3 = Element.new("e")
236
+ e3.attributes["key"] = "v"
237
+ s = Element.new("sub")
238
+ s << "String"
239
+ e3 << s
240
+ assert_not_equal(e1, e3)
241
+
242
+ e3 = Element.new("e")
243
+ e3.attributes["key"] = "value"
244
+ s = Element.new("sub")
245
+ s << "S"
246
+ e3 << s
247
+ assert_not_equal(e1, e3)
248
+
249
+ e3 = Element.new("e")
250
+ e3.attributes["key"] = "value"
251
+ s = Element.new("s")
252
+ s << "String"
253
+ e3 << s
254
+ assert_not_equal(e1, e3)
255
+
256
+ assert_not_equal(e1, "string")
257
+ end
258
+
259
+ def test_new_with_block
260
+ b = nil
261
+ e = Element.new("base") do |b|
262
+ b["attr"]="value"
263
+ b << Element.new("sub")
264
+ end
265
+ assert_same(e, b)
266
+ e2 = Element.new("base", "attr"=>"value")
267
+ e2 << Element.new("sub")
268
+ assert_equal(e, e2)
269
+
270
+ e = Element.new("base") do |e|
271
+ e <<= Element.new("sub1") do |e|
272
+ e <<= Element.new("sub12")
273
+ end
274
+ e <<= Element.new("sub2")
275
+ end
276
+ base = Element.new("base")
277
+ sub1 = Element.new("sub1")
278
+ sub1 << Element.new("sub12")
279
+ sub2 = Element.new("sub2")
280
+ base << sub1 << sub2
281
+ assert_equal(base, e)
282
+ end
283
+
284
+ def test_symbol_string_compatible
285
+ sym = Element.new(:tag, :attr=>"value")
286
+ str = Element.new("tag", "attr"=>"value")
287
+
288
+ assert_equal(sym.to_s, str.to_s)
289
+ assert_equal(sym, str)
290
+ end
291
+
292
+ def test_match
293
+ e = Element.new(:tag, :attr=>"value")
294
+ assert(e.match?(:tag))
295
+ assert(e.match?(:tag, :attr=>"value"))
296
+ assert(! e.match?(:t))
297
+ assert(! e.match?(:tag, :attr2=>"value"))
298
+ assert(! e.match?(:tag, :attr=>"value2"))
299
+
300
+ assert(e.match?(Element.new(:tag)))
301
+ assert(e.match?(Element.new(:tag, :attr=>"value")))
302
+ assert(! e.match?(Element.new(:t)))
303
+ assert(! e.match?(Element.new(:tag, :attr2=>"value")))
304
+ assert(! e.match?(Element.new(:tag, :attr=>"value2")))
305
+
306
+ assert(e.match?(/ag/))
307
+ assert(e.match?(/ag/, /tt/=>/al/))
308
+ assert(! e.match?(/elem/))
309
+ assert(! e.match?(/tag/, /attr2/=>/val/))
310
+ assert(! e.match?(/tag/, /attr/=>/v2/))
311
+
312
+ assert(e.match?(:tag, :attr=>/val/))
313
+ assert(e.match?(/t/, /at/=>"value"))
314
+
315
+ e = Element.new(:tag, :attr1=>"value", :attr2=>"test")
316
+ assert(e.match?(:tag, /attr/=>"value"))
317
+ assert(e.match?(:tag, /attr/=>/t/))
318
+
319
+ assert(e.match?(Element))
320
+ assert(!e.match?(Dummy))
321
+ assert(!e.match?(String))
322
+ end
323
+
324
+ def test_match_by_array
325
+ e = Element.new(:tag, :attr=>"value", :a2=>"v2")
326
+ assert(e.match?([:tag]))
327
+ assert(e.match?([:tag, {:attr=>"value"}]))
328
+ assert(e.match?([:tag, {:attr=>"value", :a2=>"v2"}]))
329
+ assert(e.match?([/tag/, {/a/=>/v/}]))
330
+ end
331
+
332
+ def test_match_operator
333
+ e = Element.new(:tag, :attr=>"value", :a2=>"v2")
334
+ assert_match(:tag, e)
335
+ assert_match(Element.new(:tag), e)
336
+ assert_match([:tag], e)
337
+ assert_match([:tag, {:attr=>"value"}], e)
338
+ assert_match(Element.new(:tag, :a2=>"v2"), e)
339
+ assert_match([/t/, {/a/=>/v/}], e)
340
+
341
+ assert(e !~ :t)
342
+ assert(e !~ Element.new(:t))
343
+ assert(e !~ [:t])
344
+ assert(e !~ [:tag, {:a=>"v"}])
345
+ assert(e !~ Element.new(:tag, :a=>"v"))
346
+ end
347
+
348
+ def test_has
349
+ e = Element.new(:base) do |b|
350
+ b <<= Element.new(:sub) do |s|
351
+ s <<= Element.new(:deep) do |d|
352
+ d << "text"
353
+ end
354
+ end
355
+ b <<= Element.new(:sub, :attr=>"value")
356
+ end
357
+
358
+ assert(e.has?(:base))
359
+ assert(e.has?(:sub))
360
+ assert(e.has?(:sub, :attr=>"value"))
361
+ assert(!e.has?(:sub, :attr=>"value", :attr2=>""))
362
+ assert(e.has?(:deep))
363
+ assert(! e.has?(:deep, {}, false))
364
+
365
+ assert(e.has?(String))
366
+ end
367
+
368
+ def test_find
369
+ s1 = Element.new(:sub)
370
+ d = Element.new(:deep)
371
+ d << "3rd"
372
+ s1 << "2nd" << d
373
+ s2 = Element.new(:sub, :attr=>"value")
374
+ e = Element.new(:base)
375
+ e << "1st" << s1 << s2
376
+
377
+ assert_equal([d], e.find(:deep))
378
+ assert_equal([s1, s2], e.find(:sub))
379
+ assert_equal([e, s1, d, s2], e.find(//))
380
+
381
+ assert_equal(["1st", "2nd", "3rd"], e.find(String))
382
+ end
383
+ end
384
+
385
+ class TC_SymbolKeyHash < Test::Unit::TestCase
386
+ SKH = EimXML::SymbolKeyHash
387
+
388
+ def test_new
389
+ s = SKH.new({"key1"=>"value1", :key2=>"value2"})
390
+ assert_equal({:key1=>"value1", :key2=>"value2"}, s)
391
+ end
392
+
393
+ def test_update
394
+ h = {"key"=>"value"}
395
+ s = SKH.new
396
+ s.update(h)
397
+ assert_equal({:key=>"value"}, s)
398
+
399
+ s2 = SKH.new
400
+ s2.update(s)
401
+ assert_equal(s, s2)
402
+ end
403
+
404
+ def test_merge
405
+ s = SKH.new
406
+ s2 = s.merge({"key"=>"value"})
407
+ assert_equal({}, s)
408
+ assert_equal({:key=>"value"}, s2)
409
+ end
410
+
411
+ def test_merge!
412
+ s = SKH.new
413
+ s2 = s.merge!({"key"=>"value"})
414
+ h = {:key=>"value"}
415
+ assert_equal(h, s)
416
+ assert_equal(h, s2)
417
+ end
418
+
419
+ def test_store
420
+ s = SKH.new
421
+ s.store(:sym1, "value1")
422
+ s.store("str1", "value2")
423
+ s[:sym2] = "value3"
424
+ s["str2"] = "value4"
425
+
426
+ assert_equal({:sym1=>"value1", :str1=>"value2", :sym2=>"value3", :str2=>"value4"}, s)
427
+ end
428
+ end
@@ -0,0 +1,102 @@
1
+ # Test for eim_xml/parser.rb
2
+ #
3
+ # Copyright (C) 2006, KURODA Hiraku <hiraku@hinet.mydns.jp>
4
+ # You can redistribute it and/or modify it under GPL2.
5
+
6
+ require "test/unit"
7
+ require "eim_xml/parser"
8
+
9
+ class TC_Parser < Test::Unit::TestCase
10
+ include EimXML
11
+
12
+ def parse(src)
13
+ Parser.new(src).parse
14
+ end
15
+
16
+ def test_parse
17
+ s = " <e /> "
18
+ assert_equal(Parser.new(s).parse, parse(s))
19
+ end
20
+
21
+ def test_parse_empty_element
22
+ assert_equal(Element.new("e"), parse("<e />"))
23
+ assert_equal(Element.new("e"), parse("<e/>"))
24
+
25
+ assert_equal(Element.new("e", "key"=>"value"), parse(%[<e key="value"/>]))
26
+ assert_equal(Element.new("e", "key"=>"value"), parse(%[<e key='value'/>]))
27
+ assert_equal(Element.new("e", "key"=>"value"), parse(%[<e key="value" />]))
28
+ assert_equal(Element.new("e", "key"=>"value"), parse(%[<e key='value' />]))
29
+
30
+ assert_equal(Element.new("e", "key"=>"value", "key2"=>"value2"), parse(%[<e key="value" key2="value2"/>]))
31
+ assert_equal(Element.new("e", "key"=>"value", "key2"=>"value2"), parse(%[<e key="value" key2="value2" />]))
32
+
33
+ s = " <e1 /> <e2 /> "
34
+ p = Parser.new(s)
35
+ assert_equal(Element.new("e1"), p.parse)
36
+ assert_equal(Element.new("e2"), p.parse)
37
+ end
38
+
39
+ def test_parse_nonempty_element
40
+ assert_equal(Element.new("super") << Element.new("sub"), parse("<super><sub /></super>"))
41
+ e = assert_raises(ParseError){parse("<el></e>")}
42
+ assert_equal("End tag mismatched.", e.message)
43
+ e = assert_raises(ParseError){parse("<el><></el>")}
44
+ assert_equal("Syntax error.", e.message)
45
+ end
46
+
47
+ def test_parse_string
48
+ e = parse("string&amp;")
49
+ assert_instance_of(PCString, e)
50
+ assert_equal("string&amp;", e.to_s)
51
+ e = parse(" string &amp; ")
52
+ assert_instance_of(PCString, e)
53
+ assert_equal("string &amp;", e.to_s)
54
+
55
+ e = Element.new("e")
56
+ e << PCString.new("string")
57
+ assert_equal(e, parse("<e> string </e>"))
58
+ assert_equal(e, parse("<e>string</e>"))
59
+ end
60
+
61
+ def test_hold_space
62
+ s = "<e> string with space\n</e>"
63
+ e = Element.new("e")
64
+ e << PCString.new("string with space", true)
65
+ assert_equal(e, parse(s))
66
+
67
+ e = Element.new("e").hold_space
68
+ e << PCString.new(" string with space\n", true)
69
+ assert_not_equal(e, Parser.new(s).parse)
70
+ assert_equal(e, Parser.new(s).parse(true))
71
+ assert_equal(e, Parser.new(s, "dummy", "e").parse)
72
+ assert_equal(e, Parser.new(s, /dummy/, /e/).parse)
73
+ assert_equal(e, Parser.new(s, :dummy, :e).parse)
74
+ assert_equal(e, Parser.new(s, :dummy, /^(.*:)?e$/).parse)
75
+
76
+ s = "<ns:e> string with space\n</ns:e>"
77
+ e = Element.new("ns:e")
78
+ e << PCString.new("string with space")
79
+ assert_equal(e, Parser.new(s).parse)
80
+
81
+ e = Element.new("ns:e").hold_space
82
+ e << PCString.new(" string with space\n")
83
+ assert_equal(e, Parser.new(s, /^(.*:)?e$/).parse)
84
+
85
+ s = "<a> string without space <b> string with space <a> string with space 2 </a> </b> </a>"
86
+ oa = Element.new("a") << PCString.new("string without space")
87
+ b = Element.new("b").hold_space
88
+ b << PCString.new(" string with space ")
89
+ ia = Element.new("a").hold_space
90
+ ia << PCString.new(" string with space 2 ")
91
+ b << ia
92
+ b << PCString.new(" ")
93
+ oa << b
94
+ assert_equal(oa, Parser.new(s, "b").parse)
95
+
96
+ s = "<a><b/></a>"
97
+ a = Element.new("a").hold_space
98
+ b = Element.new("b").hold_space
99
+ a << b
100
+ assert_equal(a, Parser.new(s, "a").parse)
101
+ end
102
+ end
@@ -0,0 +1,138 @@
1
+ # Test for eim_xml/xhtml.rb
2
+ #
3
+ # Copyright (C) 2007, KURODA Hiraku <hiraku@hinet.mydns.jp>
4
+ # You can redistribute it and/or modify it under GPL2.
5
+
6
+ require "eim_xml/xhtml"
7
+ require "test/unit"
8
+
9
+ class TC_XHTML < Test::Unit::TestCase
10
+ include EimXML::XHTML
11
+ Element = EimXML::Element
12
+
13
+ def test_html
14
+ h = HTML.new(:attr=>"value")
15
+ assert_equal(Element.new(:html, :attr=>"value"), h)
16
+
17
+ h = HTML.new do |e|
18
+ e <<= Element.new(:sub)
19
+ end
20
+ h2 = HTML.new
21
+ h2 << Element.new(:sub)
22
+ assert_equal(h, h2)
23
+ end
24
+
25
+ def test_html_with_declarations
26
+ decs = EimXML::XML_DECLARATION + "\n" + DocType::XHTML_MATHML + "\n"
27
+ h = HTML.new
28
+ assert_equal(decs + "<html />", h.to_s)
29
+
30
+ h = HTML.new
31
+ assert_equal("<html />", h.to_s(false))
32
+
33
+ h = HTML.new do |h|
34
+ h << Body.new do |b|
35
+ b << "test"
36
+ end
37
+ end
38
+
39
+ assert_equal(decs+h.to_s(false), h.to_s)
40
+
41
+ s1 = ""
42
+ s2 = ""
43
+ assert_equal(decs+h.write(s1, false), h.write(s2))
44
+ end
45
+
46
+ def test_head
47
+ assert_equal(:head, Head.new.name)
48
+ end
49
+
50
+ def test_title
51
+ assert_equal(:title, Title.new.name)
52
+ end
53
+
54
+ def test_body
55
+ assert_equal(:body, Body.new.name)
56
+ end
57
+
58
+ def test_pre
59
+ assert_equal(:pre, Pre.new.name)
60
+ end
61
+
62
+ def test_form
63
+ assert_equal(:form, Form.new.name)
64
+ end
65
+
66
+ def test_hn
67
+ assert_equal(:h1, Hn.new(1).name)
68
+ assert_equal(:h6, Hn.new(6).name)
69
+ assert_raises(ArgumentError){Hn.new(7)}
70
+ assert_raises(ArgumentError){Hn.new(0)}
71
+ end
72
+
73
+ def test_p
74
+ assert_equal(:p, P.new.name)
75
+ end
76
+
77
+ def test_a
78
+ assert_equal(:a, A.new.name)
79
+ end
80
+
81
+ def test_em
82
+ assert_equal(:em, Em.new.name)
83
+ end
84
+
85
+ def test_strong
86
+ assert_equal(:strong, Strong.new.name)
87
+ end
88
+
89
+ def test_div
90
+ assert_equal(:div, Div.new.name)
91
+ end
92
+
93
+ def test_ul
94
+ assert_equal(:ul, Ul.new.name)
95
+ end
96
+
97
+ def test_ol
98
+ assert_equal(:ol, Ol.new.name)
99
+ end
100
+
101
+ def test_li
102
+ assert_equal(:li, Li.new.name)
103
+ end
104
+
105
+ def test_text_area
106
+ assert_equal(Element.new(:textarea, :name=>"item"), TextArea.new("item"))
107
+ assert_equal(Element.new(:textarea, :name=>"item"), TextArea.new(:item))
108
+ assert_equal(Element.new(:textarea, :name=>"item", :class=>"cv"), TextArea.new("item", :class=>"cv"))
109
+ end
110
+
111
+ def test_input
112
+ assert_equal(Element.new(:input, :type=>"test", :name=>"item", :value=>"v"), Input.new(:test, :item, "v"))
113
+ assert_equal(Element.new(:input, :type=>"test", :name=>"item", :value=>"v"), Input.new("test", "item", "v"))
114
+ assert_equal(Element.new(:input, :type=>"test", :name=>"item", :value=>"v", :class=>"c"), Input.new(:test, :item, "v", :class=>"c"))
115
+
116
+ assert_equal(Element.new(:input, :type=>"submit", :value=>"v"), Input.new(:submit, nil, "v"))
117
+ assert_equal(Element.new(:input, :type=>"submit", :name=>"item"), Input.new(:submit, "item", nil))
118
+ end
119
+
120
+ def test_hidden
121
+ assert_equal(Element.new(:input, :type=>"hidden", :name=>"item", :value=>"v"), Hidden.new("item", "v"))
122
+ assert_equal(Element.new(:input, :type=>"hidden", :name=>"item", :value=>"v"), Hidden.new(:item, "v"))
123
+ assert_equal(Element.new(:input, :type=>"hidden", :name=>"item", :value=>"v", :class=>"c"), Hidden.new(:item, "v", :class=>"c"))
124
+ end
125
+
126
+ def test_submit
127
+ assert_equal(Element.new(:input, :type=>"submit"), Submit.new)
128
+ assert_equal(Element.new(:input, :type=>"submit", :value=>"OK"), Submit.new("OK"))
129
+ assert_equal(Element.new(:input, :type=>"submit", :value=>"OK", :class=>"c"), Submit.new("OK", :class=>"c"))
130
+ end
131
+
132
+ def test_text
133
+ assert_equal(Element.new(:input, :type=>"text", :name=>"item"), Text.new(:item))
134
+ assert_equal(Element.new(:input, :type=>"text", :name=>"item"), Text.new("item"))
135
+ assert_equal(Element.new(:input, :type=>"text", :name=>"item", :value=>"txt"), Text.new(:item, "txt"))
136
+ assert_equal(Element.new(:input, :type=>"text", :name=>"item", :value=>"txt", :class=>"c"), Text.new(:item, "txt", :class=>"c"))
137
+ end
138
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: eimxml
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-10-23 00:00:00 +09:00
8
+ summary: Easy IMplemented XML
9
+ require_paths:
10
+ - lib
11
+ email: hiraku@hinet.mydns.jp
12
+ homepage: http://eimxml.rubyforge.org/
13
+ rubyforge_project: eimxml
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - KURODA Hiraku
31
+ files:
32
+ - lib
33
+ - test
34
+ - Rakefile
35
+ - README
36
+ - lib/eim_xml.rb
37
+ - lib/eim_xml
38
+ - lib/eim_xml/parser.rb
39
+ - lib/eim_xml/assertions.rb
40
+ - test/assertions_test.rb
41
+ - test/eim_xml_test.rb
42
+ - test/parser_test.rb
43
+ test_files:
44
+ - test/assertions_test.rb
45
+ - test/xhtml_test.rb
46
+ - test/eim_xml_test.rb
47
+ - test/parser_test.rb
48
+ rdoc_options:
49
+ - -S
50
+ - -w
51
+ - "3"
52
+ - -c
53
+ - UTF-8
54
+ - -m
55
+ - README
56
+ extra_rdoc_files:
57
+ - README
58
+ executables: []
59
+
60
+ extensions: []
61
+
62
+ requirements: []
63
+
64
+ dependencies: []
65
+