rss-nokogiri 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/.gemtest +0 -0
  2. data/.gitignore +19 -0
  3. data/.gitmodules +3 -0
  4. data/BSDL +22 -0
  5. data/COPYING +56 -0
  6. data/COPYING.ja +51 -0
  7. data/Gemfile +4 -0
  8. data/LEGAL +8 -0
  9. data/README.markdown +51 -0
  10. data/Rakefile +12 -0
  11. data/lib/rss/nokogiri.rb +92 -0
  12. data/rss-nokogiri.gemspec +24 -0
  13. data/test/regression/dot.png +0 -0
  14. data/test/regression/rss-assertions.rb +2090 -0
  15. data/test/regression/rss-testcase.rb +478 -0
  16. data/test/regression/test_1.0.rb +295 -0
  17. data/test/regression/test_2.0.rb +409 -0
  18. data/test/regression/test_accessor.rb +103 -0
  19. data/test/regression/test_atom.rb +681 -0
  20. data/test/regression/test_content.rb +104 -0
  21. data/test/regression/test_dublincore.rb +279 -0
  22. data/test/regression/test_image.rb +214 -0
  23. data/test/regression/test_inherit.rb +40 -0
  24. data/test/regression/test_itunes.rb +347 -0
  25. data/test/regression/test_maker_0.9.rb +474 -0
  26. data/test/regression/test_maker_1.0.rb +516 -0
  27. data/test/regression/test_maker_2.0.rb +757 -0
  28. data/test/regression/test_maker_atom_entry.rb +393 -0
  29. data/test/regression/test_maker_atom_feed.rb +454 -0
  30. data/test/regression/test_maker_content.rb +47 -0
  31. data/test/regression/test_maker_dc.rb +149 -0
  32. data/test/regression/test_maker_image.rb +62 -0
  33. data/test/regression/test_maker_itunes.rb +471 -0
  34. data/test/regression/test_maker_slash.rb +37 -0
  35. data/test/regression/test_maker_sy.rb +44 -0
  36. data/test/regression/test_maker_taxo.rb +81 -0
  37. data/test/regression/test_maker_trackback.rb +41 -0
  38. data/test/regression/test_maker_xml-stylesheet.rb +83 -0
  39. data/test/regression/test_parser.rb +62 -0
  40. data/test/regression/test_parser_1.0.rb +528 -0
  41. data/test/regression/test_parser_2.0.rb +122 -0
  42. data/test/regression/test_parser_atom_entry.rb +163 -0
  43. data/test/regression/test_parser_atom_feed.rb +276 -0
  44. data/test/regression/test_setup_maker_0.9.rb +246 -0
  45. data/test/regression/test_setup_maker_1.0.rb +550 -0
  46. data/test/regression/test_setup_maker_2.0.rb +308 -0
  47. data/test/regression/test_setup_maker_atom_entry.rb +409 -0
  48. data/test/regression/test_setup_maker_atom_feed.rb +445 -0
  49. data/test/regression/test_setup_maker_itunes.rb +144 -0
  50. data/test/regression/test_setup_maker_slash.rb +38 -0
  51. data/test/regression/test_slash.rb +64 -0
  52. data/test/regression/test_syndication.rb +125 -0
  53. data/test/regression/test_taxonomy.rb +172 -0
  54. data/test/regression/test_to_s.rb +670 -0
  55. data/test/regression/test_trackback.rb +135 -0
  56. data/test/regression/test_version.rb +9 -0
  57. data/test/regression/test_xml-stylesheet.rb +108 -0
  58. metadata +220 -0
data/.gemtest ADDED
File without changes
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ vendor
19
+ *~
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "vendor/ruby"]
2
+ path = vendor/ruby
3
+ url = https://github.com/ruby/ruby.git
data/BSDL ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (C) 2012 KITAITI Makoto. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ 2. Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ SUCH DAMAGE.
data/COPYING ADDED
@@ -0,0 +1,56 @@
1
+ Ruby is copyrighted free software by KITAITI Makoto <KitaitiMakoto@gmail.com>.
2
+ You can redistribute it and/or modify it under either the terms of the
3
+ 2-clause BSDL (see the file BSDL), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) give non-standard binaries non-standard names, with
21
+ instructions on where to get the original software distribution.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or binary form,
26
+ provided that you do at least ONE of the following:
27
+
28
+ a) distribute the binaries and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c) give non-standard binaries non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under these terms.
43
+
44
+ For the list of those files and their copying conditions, see the
45
+ file LEGAL.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
data/COPYING.ja ADDED
@@ -0,0 +1,51 @@
1
+ 本プログラムはフリーソフトウェアです.2-clause BSDL
2
+ または以下に示す条件で本プログラムを再配布できます
3
+ 2-clause BSDLについてはBSDLファイルを参照して下さい.
4
+
5
+ 1. 複製は制限なく自由です.
6
+
7
+ 2. 以下の条件のいずれかを満たす時に本プログラムのソースを
8
+ 自由に変更できます.
9
+
10
+ (a) ネットニューズにポストしたり,作者に変更を送付する
11
+ などの方法で,変更を公開する.
12
+
13
+ (b) 変更した本プログラムを自分の所属する組織内部だけで
14
+ 使う.
15
+
16
+ (c) 変更点を明示したうえ,ソフトウェアの名前を変更する.
17
+ そのソフトウェアを配布する時には変更前の本プログラ
18
+ ムも同時に配布する.または変更前の本プログラムのソー
19
+ スの入手法を明示する.
20
+
21
+ (d) その他の変更条件を作者と合意する.
22
+
23
+ 3. 以下の条件のいずれかを満たす時に本プログラムをコンパイ
24
+ ルしたオブジェクトコードや実行形式でも配布できます.
25
+
26
+ (a) バイナリを受け取った人がソースを入手できるように,
27
+ ソースの入手法を明示する.
28
+
29
+ (b) 機械可読なソースコードを添付する.
30
+
31
+ (c) 変更を行ったバイナリは名前を変更したうえ,オリジナ
32
+ ルのソースコードの入手法を明示する.
33
+
34
+ (d) その他の配布条件を作者と合意する.
35
+
36
+ 4. 他のプログラムへの引用はいかなる目的であれ自由です.た
37
+ だし,本プログラムに含まれる他の作者によるコードは,そ
38
+ れぞれの作者の意向による制限が加えられる場合があります.
39
+
40
+ それらファイルの一覧とそれぞれの配布条件などに付いては
41
+ LEGALファイルを参照してください.
42
+
43
+ 5. 本プログラムへの入力となるスクリプトおよび,本プログラ
44
+ ムからの出力の権利は本プログラムの作者ではなく,それぞ
45
+ れの入出力を生成した人に属します.また,本プログラムに
46
+ 組み込まれるための拡張ライブラリについても同様です.
47
+
48
+ 6. 本プログラムは無保証です.作者は本プログラムをサポート
49
+ する意志はありますが,プログラム自身のバグあるいは本プ
50
+ ログラムの実行などから発生するいかなる損害に対しても責
51
+ 任を持ちません.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rss-nokogiri.gemspec
4
+ gemspec
data/LEGAL ADDED
@@ -0,0 +1,8 @@
1
+ LEGAL NOTICE INFORMATION
2
+ ------------------------
3
+
4
+ All the files in this distribution are covered under either the Ruby's
5
+ license (see the file COPYING) or public-domain except some files
6
+ mentioned below.
7
+
8
+ none
data/README.markdown ADDED
@@ -0,0 +1,51 @@
1
+ RSS NokogiriParser
2
+ ==================
3
+
4
+ This gem enable standard bundled RSS library to use [Nokogiri][nokogiri] as parser.
5
+
6
+ [nokogiri]: http://nokogiri.org/
7
+
8
+ Installation
9
+ ------------
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'rss-nokogiri'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install rss-nokogiri
22
+
23
+ Usage
24
+ -----
25
+
26
+ Require this library:
27
+
28
+ require 'rss/nokogiri'
29
+
30
+ Now `RSS::Parser.default_parser` have become `RSS::NokogiriParser` instead of the default `RSS::REXMLParser`.
31
+
32
+ If you want to use other parsers, call `RSS::Parser.default_parser=`. Available parsers can be seen in `RSS::AVAILABLE_PARSERS`.
33
+
34
+ Todo
35
+ ----
36
+
37
+ * Handling processing instruction.
38
+
39
+ Contributing
40
+ ------------
41
+
42
+ 1. Fork it
43
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
44
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
45
+ 4. Push to the branch (`git push origin my-new-feature`)
46
+ 5. Create new Merge Request
47
+
48
+ License
49
+ -------
50
+
51
+ This library is distributed under the Ruby's license. See the file COPYING for the term.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require 'rake/testtask'
3
+ require 'yard'
4
+ require "bundler/gem_tasks"
5
+
6
+ task :default => :test
7
+
8
+ Rake::TestTask.new do |t|
9
+ t.ruby_opts << '-I test/regression'
10
+ t.test_files = FileList['test/**/test_*.rb']
11
+ end
12
+ YARD::Rake::YardocTask.new
@@ -0,0 +1,92 @@
1
+ require 'rss'
2
+
3
+ module RSS
4
+ class NokogiriParser < BaseParser
5
+ VERSION = '0.0.1'
6
+
7
+ class << self
8
+ def listener
9
+ NokogiriListener
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def _parse
16
+ parser = ::Nokogiri::XML::SAX::Parser.new(@listener)
17
+ parser.parse(@rss) do |ctx|
18
+ ctx.replace_entities = true
19
+ end
20
+ end
21
+ end
22
+
23
+ class NokogiriListener < BaseListener
24
+ include ListenerMixin
25
+
26
+ def xmldecl version, encoding, standalone
27
+ super(version, encoding, standalone == 'yes')
28
+ end
29
+
30
+ def start_document
31
+ end
32
+
33
+ def end_document
34
+ end
35
+
36
+ def start_element(name, attrs = [])
37
+ end
38
+
39
+ def end_element(name)
40
+ end
41
+
42
+ def start_element_namespace(name, attributes = [], prefix = nil, uri = nil, ns = [])
43
+ name = [prefix, name].compact.join(':')
44
+ attrs = {}
45
+ attributes.each do |attr|
46
+ key = [attr.prefix, attr.localname].compact.join(':')
47
+ attrs[key] = attr.value
48
+ end
49
+ ns.each do |(prefix, uri)|
50
+ key = ['xmlns', prefix].compact.join(':')
51
+ attrs[key] = uri
52
+ end
53
+
54
+ tag_start name, attrs
55
+ end
56
+
57
+ def end_element_namespace(name, prefix = nil, uri = nil)
58
+ name = [prefix, name].compact.join(':')
59
+
60
+ tag_end name
61
+ end
62
+
63
+ def characters(string)
64
+ text(string)
65
+ end
66
+
67
+ def comment(string)
68
+ end
69
+
70
+ def warning(string)
71
+ end
72
+
73
+ def error(string)
74
+ raise NotWellFormedError.new(string) if string =~ /Entity '.*' not defined/
75
+ end
76
+
77
+ def cdata_block(string)
78
+ text(string)
79
+ end
80
+ end
81
+
82
+ begin
83
+ lib = 'nokogiri'
84
+ require lib
85
+
86
+ AVAILABLE_PARSER_LIBRARIES << ['rss/nokogiri', :NokogiriParser]
87
+ AVAILABLE_PARSERS << NokogiriParser
88
+ Parser.default_parser = NokogiriParser
89
+ rescue LoadError
90
+ warn "Couldn't load #{lib}. Falled back to the default parser(#{Parser.default_parser})."
91
+ end
92
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/rss/nokogiri', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["KITAITI Makoto"]
6
+ gem.email = ["KitaitiMakoto@gmail.com"]
7
+ gem.description = %q{Enable starndard bundled RSS library to use Nokogiri as a parser.}
8
+ gem.summary = %q{Parse RSS/Atom using Nokogiri}
9
+ gem.homepage = "https://gitorious.org/rss/nokogiri"
10
+
11
+ gem.files = `git ls-files`.split($\) - ['vendor/ruby']
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "rss-nokogiri"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = RSS::NokogiriParser::VERSION
17
+
18
+ gem.add_development_dependency 'rake'
19
+ gem.add_development_dependency 'yard'
20
+ gem.add_development_dependency 'redcarpet'
21
+ gem.add_development_dependency 'pry'
22
+ gem.add_development_dependency 'pry-doc'
23
+ gem.add_runtime_dependency 'nokogiri'
24
+ end
Binary file
@@ -0,0 +1,2090 @@
1
+ require 'erb'
2
+
3
+ module RSS
4
+ module Assertions
5
+ def _wrap_assertion
6
+ yield
7
+ end
8
+
9
+ def assert_parse(rss, assert_method, *args)
10
+ __send__("assert_#{assert_method}", *args) do
11
+ ::RSS::Parser.parse(rss)
12
+ end
13
+ __send__("assert_#{assert_method}", *args) do
14
+ ::RSS::Parser.parse(rss, false).validate
15
+ end
16
+ end
17
+
18
+ def assert_ns(prefix, uri)
19
+ _wrap_assertion do
20
+ begin
21
+ yield
22
+ flunk("Not raise NSError")
23
+ rescue ::RSS::NSError => e
24
+ assert_equal(prefix, e.prefix)
25
+ assert_equal(uri, e.uri)
26
+ end
27
+ end
28
+ end
29
+
30
+ def assert_missing_tag(tag, parent)
31
+ _wrap_assertion do
32
+ begin
33
+ yield
34
+ flunk("Not raise MissingTagError")
35
+ rescue ::RSS::MissingTagError => e
36
+ assert_equal(tag, e.tag)
37
+ assert_equal(parent, e.parent)
38
+ end
39
+ end
40
+ end
41
+
42
+ def assert_too_much_tag(tag, parent)
43
+ _wrap_assertion do
44
+ begin
45
+ yield
46
+ flunk("Not raise TooMuchTagError")
47
+ rescue ::RSS::TooMuchTagError => e
48
+ assert_equal(tag, e.tag)
49
+ assert_equal(parent, e.parent)
50
+ end
51
+ end
52
+ end
53
+
54
+ def assert_missing_attribute(tag, attrname)
55
+ _wrap_assertion do
56
+ begin
57
+ yield
58
+ flunk("Not raise MissingAttributeError")
59
+ rescue ::RSS::MissingAttributeError => e
60
+ assert_equal(tag, e.tag)
61
+ assert_equal(attrname, e.attribute)
62
+ end
63
+ end
64
+ end
65
+
66
+ def assert_not_expected_tag(tag, uri, parent)
67
+ _wrap_assertion do
68
+ begin
69
+ yield
70
+ flunk("Not raise NotExpectedTagError")
71
+ rescue ::RSS::NotExpectedTagError => e
72
+ assert_equal(tag, e.tag)
73
+ assert_equal(uri, e.uri)
74
+ assert_equal(parent, e.parent)
75
+ end
76
+ end
77
+ end
78
+
79
+ def assert_not_available_value(tag, value, attribute=nil)
80
+ _wrap_assertion do
81
+ begin
82
+ yield
83
+ flunk("Not raise NotAvailableValueError")
84
+ rescue ::RSS::NotAvailableValueError => e
85
+ assert_equal(tag, e.tag)
86
+ assert_equal(value, e.value)
87
+ assert_equal(attribute, e.attribute)
88
+ end
89
+ end
90
+ end
91
+
92
+ def assert_not_set_error(name, variables)
93
+ _wrap_assertion do
94
+ begin
95
+ yield
96
+ flunk("Not raise NotSetError")
97
+ rescue ::RSS::NotSetError => e
98
+ assert_equal(name, e.name)
99
+ assert_kind_of(Array, variables)
100
+ assert_equal(variables.sort, e.variables.sort)
101
+ end
102
+ end
103
+ end
104
+
105
+ def assert_xml_declaration(version, encoding, standalone, rss)
106
+ _wrap_assertion do
107
+ assert_equal(version, rss.version)
108
+ assert_equal(encoding, rss.encoding)
109
+ assert_equal(standalone, rss.standalone)
110
+ end
111
+ end
112
+
113
+ def assert_xml_stylesheet_attrs(attrs, xsl)
114
+ _wrap_assertion do
115
+ n_attrs = normalized_attrs(attrs)
116
+ ::RSS::XMLStyleSheet::ATTRIBUTES.each do |name|
117
+ assert_equal(n_attrs[name], xsl.__send__(name))
118
+ end
119
+ end
120
+ end
121
+
122
+ def assert_xml_stylesheet(target, attrs, xsl)
123
+ _wrap_assertion do
124
+ if attrs.has_key?(:href)
125
+ if !attrs.has_key?(:type) and attrs.has_key?(:guess_type)
126
+ attrs[:type] = attrs[:guess_type]
127
+ end
128
+ assert_equal("xml-stylesheet", target)
129
+ assert_xml_stylesheet_attrs(attrs, xsl)
130
+ else
131
+ assert_nil(target)
132
+ assert_equal("", xsl.to_s)
133
+ end
134
+ end
135
+ end
136
+
137
+ def assert_xml_stylesheet_pis(attrs_ary, rss=nil)
138
+ _wrap_assertion do
139
+ if rss.nil?
140
+ rss = ::RSS::RDF.new
141
+ setup_rss10(rss)
142
+ end
143
+ xss_strs = []
144
+ attrs_ary.each do |attrs|
145
+ xss = ::RSS::XMLStyleSheet.new(attrs)
146
+ xss_strs.push(xss.to_s)
147
+ rss.xml_stylesheets.push(xss)
148
+ end
149
+ pi_str = rss.to_s.gsub(/<\?xml .*\n/, "").gsub(/\s*<[^\?].*\z/m, "")
150
+ assert_equal(xss_strs.join("\n"), pi_str)
151
+ end
152
+ end
153
+
154
+ def assert_xml_stylesheets(attrs, xss)
155
+ _wrap_assertion do
156
+ xss.each_with_index do |xs, i|
157
+ assert_xml_stylesheet_attrs(attrs[i], xs)
158
+ end
159
+ end
160
+ end
161
+
162
+
163
+ def assert_atom_person(tag_name, generator)
164
+ _wrap_assertion do
165
+ name = "Mark Pilgrim"
166
+ uri = "http://example.org/"
167
+ email = "f8dy@example.com"
168
+
169
+ assert_parse(generator.call(<<-EOA), :missing_tag, "name", tag_name)
170
+ <#{tag_name}/>
171
+ EOA
172
+
173
+ assert_parse(generator.call(<<-EOA), :missing_tag, "name", tag_name)
174
+ <#{tag_name}>
175
+ <uri>#{uri}</uri>
176
+ <email>#{email}</email>
177
+ </#{tag_name}>
178
+ EOA
179
+
180
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
181
+ <#{tag_name}>
182
+ <name>#{name}</name>
183
+ </#{tag_name}>
184
+ EOA
185
+
186
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
187
+ <#{tag_name}>
188
+ <name>#{name}</name>
189
+ <uri>#{uri}</uri>
190
+ <email>#{email}</email>
191
+ </#{tag_name}>
192
+ EOA
193
+
194
+ person = yield(feed)
195
+ assert_not_nil(person)
196
+ assert_equal(name, person.name.content)
197
+ assert_equal(uri, person.uri.content)
198
+ assert_equal(email, person.email.content)
199
+ end
200
+ end
201
+
202
+ def assert_atom_category(generator)
203
+ _wrap_assertion do
204
+ term = "Music"
205
+ scheme = "http://xmlns.com/wordnet/1.6/"
206
+ label = "music"
207
+
208
+ missing_args = [:missing_attribute, "category", "term"]
209
+ assert_parse(generator.call(<<-EOA), *missing_args)
210
+ <category/>
211
+ EOA
212
+
213
+ assert_parse(generator.call(<<-EOA), *missing_args)
214
+ <category scheme="#{scheme}" label="#{label}"/>
215
+ EOA
216
+
217
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
218
+ <category term="#{term}"/>
219
+ EOA
220
+
221
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
222
+ <category term="#{term}" scheme="#{scheme}" label="#{label}"/>
223
+ EOA
224
+
225
+ category = yield(feed)
226
+ assert_not_nil(category)
227
+ assert_equal(term, category.term)
228
+ assert_equal(scheme, category.scheme)
229
+ assert_equal(label, category.label)
230
+ end
231
+ end
232
+
233
+ def assert_atom_link(generator)
234
+ _wrap_assertion do
235
+ href = "http://example.org/feed.atom"
236
+ rel = "self"
237
+ type = "application/atom+xml"
238
+ hreflang = "en"
239
+ title = "Atom"
240
+ length = "1024"
241
+
242
+ assert_parse(generator.call(<<-EOA), :missing_attribute, "link", "href")
243
+ <link/>
244
+ EOA
245
+
246
+ assert_parse(generator.call(<<-EOA), :missing_attribute, "link", "href")
247
+ <link rel="#{rel}" type="#{type}" hreflang="#{hreflang}"
248
+ title="#{title}" length="#{length}"/>
249
+ EOA
250
+
251
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
252
+ <link href="#{href}"/>
253
+ EOA
254
+
255
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
256
+ <link href="#{href}" rel="#{rel}" type="#{type}" hreflang="#{hreflang}"
257
+ title="#{title}" length="#{length}"/>
258
+ EOA
259
+
260
+ link = yield(feed)
261
+ assert_not_nil(link)
262
+ assert_equal(href, link.href)
263
+ assert_equal(rel, link.rel)
264
+ assert_equal(type, link.type)
265
+ assert_equal(hreflang, link.hreflang)
266
+ assert_equal(title, link.title)
267
+ assert_equal(length, link.length)
268
+
269
+
270
+ href = "http://example.org/index.html.ja"
271
+ parent = link.parent.tag_name
272
+ return if parent == "source"
273
+
274
+ optional_attributes = %w(hreflang="ja" type="text/html")
275
+ 0.upto(optional_attributes.size) do |i|
276
+ combination(optional_attributes, i).each do |attributes|
277
+ attrs = attributes.join(" ")
278
+ assert_parse(generator.call(<<-EOA), :too_much_tag, "link", parent)
279
+ <link rel="alternate" #{attrs} href="#{href}"/>
280
+ <link rel="alternate" #{attrs} href="#{href}"/>
281
+ EOA
282
+ end
283
+ end
284
+ end
285
+ end
286
+
287
+ def assert_atom_generator(generator)
288
+ _wrap_assertion do
289
+ uri = "http://www.example.com/"
290
+ version = "1.0"
291
+ content = "Example Toolkit"
292
+
293
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
294
+ <generator/>
295
+ EOA
296
+
297
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
298
+ <generator uri="#{uri}" version="#{version}"/>
299
+ EOA
300
+
301
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
302
+ <generator uri="#{uri}" version="#{version}">#{content}</generator>
303
+ EOA
304
+
305
+ gen = yield(feed)
306
+ assert_not_nil(gen)
307
+ assert_equal(uri, gen.uri)
308
+ assert_equal(version, gen.version)
309
+ assert_equal(content, gen.content)
310
+ end
311
+ end
312
+
313
+ def assert_atom_icon(generator)
314
+ _wrap_assertion do
315
+ content = "http://www.example.com/example.png"
316
+
317
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
318
+ <icon/>
319
+ EOA
320
+
321
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
322
+ <icon>#{content}</icon>
323
+ EOA
324
+
325
+ icon = yield(feed)
326
+ assert_not_nil(icon)
327
+ assert_equal(content, icon.content)
328
+ end
329
+ end
330
+
331
+ def assert_atom_text_construct(tag_name, generator)
332
+ _wrap_assertion do
333
+ [nil, "text", "html"].each do |type|
334
+ attr = ""
335
+ attr = " type=\"#{type}\""if type
336
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
337
+ <#{tag_name}#{attr}/>
338
+ EOA
339
+ end
340
+
341
+ assert_parse(generator.call(<<-EOA), :missing_tag, "div", tag_name)
342
+ <#{tag_name} type="xhtml"/>
343
+ EOA
344
+
345
+ args = ["x", Atom::URI, tag_name]
346
+ assert_parse(generator.call(<<-EOA), :not_expected_tag, *args)
347
+ <#{tag_name} type="xhtml"><x/></#{tag_name}>
348
+ EOA
349
+
350
+ invalid_value = "invalid"
351
+ args = ["type", invalid_value]
352
+ assert_parse(generator.call(<<-EOA), :not_available_value, *args)
353
+ <#{tag_name} type="#{invalid_value}"/>
354
+ EOA
355
+
356
+ [
357
+ [nil, "A lot of effort went into making this effortless"],
358
+ ["text", "A lot of effort went into making this effortless"],
359
+ ["html", "A <em>lot</em> of effort went into making this effortless"],
360
+ ].each do |type, content|
361
+ attr = ""
362
+ attr = " type=\"#{type}\"" if type
363
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
364
+ <#{tag_name}#{attr}>#{h content}</#{tag_name}>
365
+ EOA
366
+
367
+ element = yield(feed)
368
+ assert_not_nil(element)
369
+ assert_equal(type, element.type)
370
+ assert_equal(content, element.content)
371
+ end
372
+
373
+ [false, true].each do |with_space|
374
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
375
+ xhtml_content = "<div xmlns=\"#{xhtml_uri}\">abc</div>"
376
+ xhtml_element = RSS::XML::Element.new("div", nil, xhtml_uri,
377
+ {"xmlns" => xhtml_uri},
378
+ ["abc"])
379
+ content = xhtml_content
380
+ content = " #{content} " if with_space
381
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
382
+ <#{tag_name} type="xhtml">#{content}</#{tag_name}>
383
+ EOA
384
+
385
+ element = yield(feed)
386
+ assert_not_nil(element)
387
+ assert_equal("xhtml", element.type)
388
+ assert_equal(xhtml_content, element.content)
389
+ assert_equal(xhtml_element, element.xhtml)
390
+ end
391
+ end
392
+ end
393
+
394
+ def assert_atom_date_construct(tag_name, generator)
395
+ _wrap_assertion do
396
+ args = [tag_name, ""]
397
+ assert_parse(generator.call(<<-EOR), :not_available_value, *args)
398
+ <#{tag_name}/>
399
+ EOR
400
+
401
+ [
402
+ ["xxx", false],
403
+ ["2007", false],
404
+ ["2007/02/09", true],
405
+ ].each do |invalid_value, can_parse|
406
+ assert_not_available_value(tag_name, invalid_value) do
407
+ RSS::Parser.parse(generator.call(<<-EOR))
408
+ <#{tag_name}>#{invalid_value}</#{tag_name}>
409
+ EOR
410
+ end
411
+
412
+ feed = RSS::Parser.parse(generator.call(<<-EOR), false)
413
+ <#{tag_name}>#{invalid_value}</#{tag_name}>
414
+ EOR
415
+ value = yield(feed).content
416
+ if can_parse
417
+ assert_equal(Time.parse(invalid_value), value)
418
+ else
419
+ assert_nil(value)
420
+ end
421
+ end
422
+
423
+ [
424
+ "2003-12-13T18:30:02Z",
425
+ "2003-12-13T18:30:02.25Z",
426
+ "2003-12-13T18:30:02+01:00",
427
+ "2003-12-13T18:30:02.25+01:00",
428
+ ].each do |valid_value|
429
+ assert_parse(generator.call(<<-EOR), :nothing_raised)
430
+ <#{tag_name}>#{valid_value}</#{tag_name}>
431
+ EOR
432
+
433
+ feed = RSS::Parser.parse(generator.call(<<-EOR))
434
+ <#{tag_name}>#{valid_value}</#{tag_name}>
435
+ EOR
436
+ assert_equal(Time.parse(valid_value), yield(feed).content)
437
+ end
438
+ end
439
+ end
440
+
441
+ def assert_atom_logo(generator)
442
+ _wrap_assertion do
443
+ content = "http://www.example.com/example.png"
444
+
445
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
446
+ <logo/>
447
+ EOA
448
+
449
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
450
+ <logo>#{content}</logo>
451
+ EOA
452
+
453
+ logo = yield(feed)
454
+ assert_not_nil(logo)
455
+ assert_equal(content, logo.content)
456
+ end
457
+ end
458
+
459
+ def assert_atom_content(generator, &getter)
460
+ _wrap_assertion do
461
+ assert_atom_content_inline_text(generator, &getter)
462
+ assert_atom_content_inline_xhtml(generator, &getter)
463
+ assert_atom_content_inline_other(generator, &getter)
464
+ assert_atom_content_out_of_line(generator, &getter)
465
+ end
466
+ end
467
+
468
+ def assert_atom_content_inline_text(generator)
469
+ _wrap_assertion do
470
+ [nil, "text", "html"].each do |type|
471
+ content = "<content"
472
+ content << " type='#{type}'" if type
473
+
474
+ suffix = "/>"
475
+ assert_parse(generator.call(content + suffix), :nothing_raised)
476
+ suffix = ">xxx</content>"
477
+ assert_parse(generator.call(content + suffix), :nothing_raised)
478
+ end
479
+
480
+ [
481
+ ["text", "sample content"],
482
+ ["text/plain", "sample content"],
483
+ ["html", "<em>sample</em> content"]
484
+ ].each do |type, content_content|
485
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
486
+ <content type="#{type}">#{h content_content}</content>
487
+ EOA
488
+ content = yield(feed)
489
+ assert_equal(type, content.type)
490
+ if %w(text html).include?(type)
491
+ assert(content.inline_text?)
492
+ else
493
+ assert(!content.inline_text?)
494
+ end
495
+ if type == "html"
496
+ assert(content.inline_html?)
497
+ else
498
+ assert(!content.inline_html?)
499
+ end
500
+ assert(!content.inline_xhtml?)
501
+ if type == "text/plain"
502
+ assert(content.inline_other?)
503
+ assert(content.inline_other_text?)
504
+ else
505
+ assert(!content.inline_other?)
506
+ assert(!content.inline_other_text?)
507
+ end
508
+ assert(!content.inline_other_xml?)
509
+ assert(!content.inline_other_base64?)
510
+ assert(!content.out_of_line?)
511
+ assert(!content.have_xml_content?)
512
+ assert_equal(content_content, content.content)
513
+ end
514
+ end
515
+ end
516
+
517
+ def assert_atom_content_inline_xhtml(generator)
518
+ _wrap_assertion do
519
+ args = ["div", "content"]
520
+ assert_parse(generator.call(<<-EOA), :missing_tag, *args)
521
+ <content type="xhtml"/>
522
+ EOA
523
+
524
+ args = ["x", Atom::URI, "content"]
525
+ assert_parse(generator.call(<<-EOA), :not_expected_tag, *args)
526
+ <content type="xhtml"><x/></content>
527
+ EOA
528
+
529
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
530
+ xhtml_content = "<div xmlns=\"#{xhtml_uri}\">abc</div>"
531
+ xhtml_element = RSS::XML::Element.new("div", nil, xhtml_uri,
532
+ {"xmlns" => xhtml_uri},
533
+ ["abc"])
534
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
535
+ <content type="xhtml">#{xhtml_content}</content>
536
+ EOA
537
+
538
+ content = yield(feed)
539
+ assert_not_nil(content)
540
+ assert_equal("xhtml", content.type)
541
+ assert(!content.inline_text?)
542
+ assert(!content.inline_html?)
543
+ assert(content.inline_xhtml?)
544
+ assert(!content.inline_other?)
545
+ assert(!content.inline_other_text?)
546
+ assert(!content.inline_other_xml?)
547
+ assert(!content.inline_other_base64?)
548
+ assert(!content.out_of_line?)
549
+ assert(content.have_xml_content?)
550
+ assert_equal(xhtml_content, content.content)
551
+ assert_equal(xhtml_element, content.xhtml)
552
+ end
553
+ end
554
+
555
+ def assert_atom_content_inline_other(generator, &getter)
556
+ _wrap_assertion do
557
+ assert_atom_content_inline_other_text(generator, &getter)
558
+ assert_atom_content_inline_other_xml(generator, &getter)
559
+ end
560
+ end
561
+
562
+ def assert_atom_content_inline_other_text(generator)
563
+ _wrap_assertion do
564
+ type = "image/png"
565
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
566
+ <content type="#{type}"/>
567
+ EOA
568
+
569
+ png_file = File.join(File.dirname(__FILE__), "dot.png")
570
+ png = File.open(png_file, "rb") do |file|
571
+ file.read.force_encoding("binary")
572
+ end
573
+ base64_content = [png].pack("m").delete("\n")
574
+
575
+ [false, true].each do |with_space|
576
+ xml_content = base64_content
577
+ xml_content = " #{base64_content}" if with_space
578
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
579
+ <content type="#{type}">#{xml_content}</content>
580
+ EOA
581
+
582
+ content = yield(feed)
583
+ assert_not_nil(content)
584
+ assert_equal(type, content.type)
585
+ assert(!content.inline_text?)
586
+ assert(!content.inline_html?)
587
+ assert(!content.inline_xhtml?)
588
+ assert(content.inline_other?)
589
+ assert(!content.inline_other_text?)
590
+ assert(!content.inline_other_xml?)
591
+ assert(content.inline_other_base64?)
592
+ assert(!content.out_of_line?)
593
+ assert(!content.have_xml_content?)
594
+ assert_equal(png, content.content)
595
+
596
+ xml = REXML::Document.new(content.to_s).root
597
+ assert_rexml_element([], {"type" => type}, base64_content, xml)
598
+ end
599
+ end
600
+ end
601
+
602
+ def assert_atom_content_inline_other_xml(generator)
603
+ _wrap_assertion do
604
+ type = "image/svg+xml"
605
+
606
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
607
+ <content type="#{type}"/>
608
+ EOA
609
+
610
+ svg_uri = "http://www.w3.org/2000/svg"
611
+ svg_width = "50pt"
612
+ svg_height = "20pt"
613
+ svg_version = "1.0"
614
+ text_x = "15"
615
+ text_y = "15"
616
+ text = "text"
617
+ svg_content = <<-EOS
618
+ <svg
619
+ xmlns="#{svg_uri}"
620
+ width="#{svg_width}"
621
+ height="#{svg_height}"
622
+ version="#{svg_version}"
623
+ ><text x="#{text_x}" y="#{text_y}">#{text}</text
624
+ ></svg>
625
+ EOS
626
+
627
+ text_element = RSS::XML::Element.new("text", nil, svg_uri,
628
+ {
629
+ "x" => text_x,
630
+ "y" => text_y,
631
+ },
632
+ [text])
633
+ svg_element = RSS::XML::Element.new("svg", nil, svg_uri,
634
+ {
635
+ "xmlns" => svg_uri,
636
+ "width" => svg_width,
637
+ "height" => svg_height,
638
+ "version" => svg_version,
639
+ },
640
+ [text_element])
641
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
642
+ <content type="#{type}">#{svg_content}</content>
643
+ EOA
644
+
645
+ content = yield(feed)
646
+ assert_not_nil(content)
647
+ assert_equal(type, content.type)
648
+ assert(!content.inline_text?)
649
+ assert(!content.inline_html?)
650
+ assert(!content.inline_xhtml?)
651
+ assert(content.inline_other?)
652
+ assert(!content.inline_other_text?)
653
+ assert(content.inline_other_xml?)
654
+ assert(!content.inline_other_base64?)
655
+ assert(!content.out_of_line?)
656
+ assert(content.have_xml_content?)
657
+ assert_equal(REXML::Document.new(svg_content).to_s.chomp,
658
+ REXML::Document.new(content.content).to_s.chomp)
659
+ assert_equal(svg_element, content.xml)
660
+ assert_nil(content.xhtml)
661
+ end
662
+ end
663
+
664
+ def assert_atom_content_out_of_line(generator)
665
+ _wrap_assertion do
666
+ text_type = "text/plain"
667
+ text_src = "http://example.com/README.txt"
668
+
669
+ missing_args = [:missing_attribute, "content", "type"]
670
+ # RSS Parser raises error even if this is "should" not "must".
671
+ assert_parse(generator.call(<<-EOA), *missing_args)
672
+ <content src="#{text_src}"/>
673
+ EOA
674
+
675
+ content_content = "xxx"
676
+ not_available_value_args = [:not_available_value,
677
+ "content", content_content]
678
+ assert_parse(generator.call(<<-EOA), *not_available_value_args)
679
+ <content type="#{text_type}" src="#{text_src}">#{content_content}</content>
680
+ EOA
681
+
682
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
683
+ <content type="#{text_type}" src="#{text_src}"/>
684
+ EOA
685
+ content = yield(feed)
686
+ assert_not_nil(content)
687
+ assert_equal(text_type, content.type)
688
+ assert_equal(text_src, content.src)
689
+ assert(!content.inline_text?)
690
+ assert(!content.inline_html?)
691
+ assert(!content.inline_xhtml?)
692
+ assert(!content.inline_other?)
693
+ assert(!content.inline_other_text?)
694
+ assert(!content.inline_other_xml?)
695
+ assert(!content.inline_other_base64?)
696
+ assert(content.out_of_line?)
697
+ assert(!content.have_xml_content?)
698
+ assert_nil(content.xml)
699
+ assert_nil(content.xhtml)
700
+ assert_equal("", content.content)
701
+ end
702
+ end
703
+
704
+ def assert_atom_source(generator, &getter)
705
+ _wrap_assertion do
706
+ assert_atom_source_author(generator, &getter)
707
+ assert_atom_source_category(generator, &getter)
708
+ assert_atom_source_contributor(generator, &getter)
709
+ assert_atom_source_generator(generator, &getter)
710
+ assert_atom_source_icon(generator, &getter)
711
+ assert_atom_source_id(generator, &getter)
712
+ assert_atom_source_link(generator, &getter)
713
+ assert_atom_source_logo(generator, &getter)
714
+ assert_atom_source_rights(generator, &getter)
715
+ assert_atom_source_subtitle(generator, &getter)
716
+ assert_atom_source_title(generator, &getter)
717
+ assert_atom_source_updated(generator, &getter)
718
+ end
719
+ end
720
+
721
+ def assert_atom_source_author(generator)
722
+ assert_atom_person("author", generator) do |feed|
723
+ source = yield(feed)
724
+ assert_equal(1, source.authors.size)
725
+ source.author
726
+ end
727
+ end
728
+
729
+ def assert_atom_source_category(generator)
730
+ assert_atom_category(generator) do |feed|
731
+ source = yield(feed)
732
+ assert_equal(1, source.categories.size)
733
+ source.category
734
+ end
735
+ end
736
+
737
+ def assert_atom_source_contributor(generator)
738
+ assert_atom_person("contributor", generator) do |feed|
739
+ source = yield(feed)
740
+ assert_equal(1, source.contributors.size)
741
+ source.contributor
742
+ end
743
+ end
744
+
745
+ def assert_atom_source_generator(generator)
746
+ assert_atom_generator(generator) do |feed|
747
+ yield(feed).generator
748
+ end
749
+ end
750
+
751
+ def assert_atom_source_icon(generator)
752
+ assert_atom_icon(generator) do |feed|
753
+ yield(feed).icon
754
+ end
755
+ end
756
+
757
+ def assert_atom_source_id(generator)
758
+ id_content = "urn:uuid:a2fb588b-5674-4898-b420-265a734fea69"
759
+ id = "<id>#{id_content}</id>"
760
+ feed = RSS::Parser.parse(generator.call(id))
761
+ assert_equal(id_content, yield(feed).id.content)
762
+ end
763
+
764
+ def assert_atom_source_link(generator)
765
+ assert_atom_link(generator) do |feed|
766
+ source = yield(feed)
767
+ assert_equal(1, source.links.size)
768
+ source.link
769
+ end
770
+ end
771
+
772
+ def assert_atom_source_logo(generator)
773
+ assert_atom_logo(generator) do |feed|
774
+ yield(feed).logo
775
+ end
776
+ end
777
+
778
+ def assert_atom_source_rights(generator)
779
+ assert_atom_text_construct("rights", generator) do |feed|
780
+ yield(feed).rights
781
+ end
782
+ end
783
+
784
+ def assert_atom_source_subtitle(generator)
785
+ assert_atom_text_construct("subtitle", generator) do |feed|
786
+ yield(feed).subtitle
787
+ end
788
+ end
789
+
790
+ def assert_atom_source_title(generator)
791
+ assert_atom_text_construct("title", generator) do |feed|
792
+ yield(feed).title
793
+ end
794
+ end
795
+
796
+ def assert_atom_source_updated(generator)
797
+ assert_atom_date_construct("updated", generator) do |feed|
798
+ yield(feed).updated
799
+ end
800
+ end
801
+
802
+ def assert_dublin_core(elems, target)
803
+ _wrap_assertion do
804
+ elems.each do |name, value|
805
+ assert_equal(value, target.__send__("dc_#{name}"))
806
+ end
807
+ end
808
+ end
809
+
810
+ def assert_multiple_dublin_core(elems, target)
811
+ _wrap_assertion do
812
+ elems.each do |name, values, plural|
813
+ plural ||= "#{name}s"
814
+ actual = target.__send__("dc_#{plural}").collect{|x| x.value}
815
+ assert_equal(values, actual)
816
+ end
817
+ end
818
+ end
819
+
820
+ def assert_syndication(elems, target)
821
+ _wrap_assertion do
822
+ elems.each do |name, value|
823
+ meth = "sy_#{name}"
824
+ value = value.to_i if meth == "sy_updateFrequency"
825
+ assert_equal(value, target.__send__(meth ))
826
+ end
827
+ end
828
+ end
829
+
830
+ def assert_content(elems, target)
831
+ _wrap_assertion do
832
+ elems.each do |name, value|
833
+ assert_equal(value, target.__send__("content_#{name}"))
834
+ end
835
+ end
836
+ end
837
+
838
+ def assert_trackback(attrs, target)
839
+ _wrap_assertion do
840
+ n_attrs = normalized_attrs(attrs)
841
+ if n_attrs["ping"]
842
+ assert_equal(n_attrs["ping"], target.trackback_ping)
843
+ end
844
+ if n_attrs["abouts"]
845
+ n_attrs["abouts"].each_with_index do |about, i|
846
+ assert_equal(about, target.trackback_abouts[i].value)
847
+ end
848
+ end
849
+ end
850
+ end
851
+
852
+ def assert_taxo_topic(topics, target)
853
+ _wrap_assertion do
854
+ topics.each_with_index do |topic, i|
855
+ taxo_topic = target.taxo_topics[i]
856
+ topic.each do |name, value|
857
+ case name
858
+ when :link
859
+ assert_equal(value, taxo_topic.about)
860
+ assert_equal(value, taxo_topic.taxo_link)
861
+ when :topics
862
+ assert_equal(value, taxo_topic.taxo_topics.resources)
863
+ else
864
+ assert_equal(value, taxo_topic.__send__("dc_#{name}"))
865
+ end
866
+ end
867
+ end
868
+ end
869
+ end
870
+
871
+
872
+ def assert_attributes(attrs, names, target)
873
+ _wrap_assertion do
874
+ n_attrs = normalized_attrs(attrs)
875
+ names.each do |info|
876
+ if info.is_a?(String)
877
+ name = info
878
+ type = nil
879
+ else
880
+ name, type = info
881
+ end
882
+ value = n_attrs[name]
883
+ if value.is_a?(Time)
884
+ actual = target.__send__(name)
885
+ assert_instance_of(Time, actual)
886
+ assert_equal(value.to_i, actual.to_i)
887
+ elsif value
888
+ case type
889
+ when :integer
890
+ value = value.to_i
891
+ when :boolean
892
+ value = value == "true" if value.is_a?(String)
893
+ end
894
+ assert_equal(value, target.__send__(name))
895
+ end
896
+ end
897
+ end
898
+ end
899
+
900
+ def assert_rexml_element(children, attrs, text, element, text_type=nil)
901
+ _wrap_assertion do
902
+ if children
903
+ children_info = element.elements.collect {|e| [e.namespace, e.name]}
904
+ assert_equal(children.collect {|uri, name| [uri, name]}.sort,
905
+ children_info.sort)
906
+ end
907
+ if attrs
908
+ assert_equal(attrs.collect {|k, v| [k, v]}.sort,
909
+ element.attributes.collect {|k, v| [k, v]}.sort)
910
+ end
911
+ case text_type
912
+ when :time
913
+ assert_not_nil(element.text)
914
+ assert_equal(Time.parse(text).to_s, Time.parse(element.text).to_s)
915
+ else
916
+ assert_equal(text, element.text)
917
+ end
918
+ end
919
+ end
920
+
921
+ def _assert_maker_atom_persons(feed_type, maker_readers, feed_readers)
922
+ _wrap_assertion do
923
+ persons = []
924
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
925
+ yield maker
926
+ targets = chain_reader(maker, maker_readers)
927
+ targets.each do |target|
928
+ person = {
929
+ :name => target.name,
930
+ :uri => target.uri,
931
+ :email => target.email,
932
+ }
933
+ persons << person if person[:name]
934
+ end
935
+ end
936
+
937
+ actual_persons = chain_reader(feed, feed_readers) || []
938
+ actual_persons = actual_persons.collect do |person|
939
+ {
940
+ :name => person.name ? person.name.content : nil,
941
+ :uri => person.uri ? person.uri.content : nil,
942
+ :email => person.email ? person.email.content : nil,
943
+ }
944
+ end
945
+ assert_equal(persons, actual_persons)
946
+ end
947
+ end
948
+
949
+ def assert_maker_atom_persons(feed_type, maker_readers, feed_readers,
950
+ not_set_error_name=nil,
951
+ parent_not_set_error_name=nil,
952
+ parent_not_set_variable=nil)
953
+ _wrap_assertion do
954
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
955
+
956
+ args = [feed_type, maker_readers, feed_readers]
957
+ if parent_not_set_error_name or parent_not_set_variable
958
+ assert_not_set_error(parent_not_set_error_name,
959
+ parent_not_set_variable) do
960
+ _assert_maker_atom_persons(*args) do |maker|
961
+ yield maker
962
+ end
963
+ end
964
+ else
965
+ _assert_maker_atom_persons(*args) do |maker|
966
+ yield maker
967
+ end
968
+ end
969
+
970
+ assert_not_set_error(not_set_error_name, %w(name)) do
971
+ _assert_maker_atom_persons(feed_type, maker_readers,
972
+ feed_readers) do |maker|
973
+ yield maker
974
+ targets = chain_reader(maker, maker_readers)
975
+ target = targets.new_child
976
+ end
977
+ end
978
+
979
+ assert_not_set_error(not_set_error_name, %w(name)) do
980
+ _assert_maker_atom_persons(feed_type, maker_readers,
981
+ feed_readers) do |maker|
982
+ yield maker
983
+ targets = chain_reader(maker, maker_readers)
984
+ target = targets.new_child
985
+ target.uri = "http://example.com/~me/"
986
+ end
987
+ end
988
+
989
+ assert_not_set_error(not_set_error_name, %w(name)) do
990
+ _assert_maker_atom_persons(feed_type, maker_readers,
991
+ feed_readers) do |maker|
992
+ yield maker
993
+ targets = chain_reader(maker, maker_readers)
994
+ target = targets.new_child
995
+ target.email = "me@example.com"
996
+ end
997
+ end
998
+
999
+ assert_not_set_error(not_set_error_name, %w(name)) do
1000
+ _assert_maker_atom_persons(feed_type, maker_readers,
1001
+ feed_readers) do |maker|
1002
+ yield maker
1003
+ targets = chain_reader(maker, maker_readers)
1004
+ target = targets.new_child
1005
+ target.uri = "http://example.com/~me/"
1006
+ target.email = "me@example.com"
1007
+ end
1008
+ end
1009
+
1010
+ _assert_maker_atom_persons(feed_type, maker_readers,
1011
+ feed_readers) do |maker|
1012
+ yield maker
1013
+ targets = chain_reader(maker, maker_readers)
1014
+ target = targets.new_child
1015
+ target.name = "me"
1016
+ end
1017
+
1018
+ _assert_maker_atom_persons(feed_type, maker_readers,
1019
+ feed_readers) do |maker|
1020
+ yield maker
1021
+ targets = chain_reader(maker, maker_readers)
1022
+ target = targets.new_child
1023
+ target.name = "me"
1024
+ target.uri = "http://example.com/~me/"
1025
+ end
1026
+
1027
+ _assert_maker_atom_persons(feed_type, maker_readers,
1028
+ feed_readers) do |maker|
1029
+ yield maker
1030
+ targets = chain_reader(maker, maker_readers)
1031
+ target = targets.new_child
1032
+ target.name = "me"
1033
+ target.email = "me@example.com"
1034
+ end
1035
+
1036
+ _assert_maker_atom_persons(feed_type, maker_readers,
1037
+ feed_readers) do |maker|
1038
+ yield maker
1039
+ targets = chain_reader(maker, maker_readers)
1040
+ target = targets.new_child
1041
+ target.name = "me"
1042
+ target.uri = "http://example.com/~me/"
1043
+ target.email = "me@example.com"
1044
+ end
1045
+
1046
+ _assert_maker_atom_persons(feed_type, maker_readers,
1047
+ feed_readers) do |maker|
1048
+ yield maker
1049
+ targets = chain_reader(maker, maker_readers)
1050
+
1051
+ target = targets.new_child
1052
+ target.name = "me"
1053
+ target.uri = "http://example.com/~me/"
1054
+ target.email = "me@example.com"
1055
+
1056
+ target = targets.new_child
1057
+ target.name = "you"
1058
+ target.uri = "http://example.com/~you/"
1059
+ target.email = "you@example.com"
1060
+ end
1061
+
1062
+ assert_not_set_error(not_set_error_name, %w(name)) do
1063
+ _assert_maker_atom_persons(feed_type, maker_readers,
1064
+ feed_readers) do |maker|
1065
+ yield maker
1066
+ targets = chain_reader(maker, maker_readers)
1067
+
1068
+ target = targets.new_child
1069
+ target.name = "me"
1070
+ target.uri = "http://example.com/~me/"
1071
+ target.email = "me@example.com"
1072
+
1073
+ target = targets.new_child
1074
+ end
1075
+ end
1076
+ end
1077
+ end
1078
+
1079
+ def _assert_maker_atom_text_construct(feed_type, maker_readers,
1080
+ feed_readers, &block)
1081
+ maker_extractor = Proc.new do |target|
1082
+ text = {
1083
+ :type => target.type,
1084
+ :content => target.content,
1085
+ :xml_content => target.xml_content,
1086
+ }
1087
+ if text[:type] == "xhtml"
1088
+ if text[:xml_content]
1089
+ xml_content = text[:xml_content]
1090
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
1091
+ unless xml_content.is_a?(RSS::XML::Element) and
1092
+ ["div", xhtml_uri] == [xml_content.name, xml_content.uri]
1093
+ children = xml_content
1094
+ children = [children] unless children.is_a?(Array)
1095
+ xml_content = RSS::XML::Element.new("div", nil, xhtml_uri,
1096
+ {"xmlns" => xhtml_uri},
1097
+ children)
1098
+ text[:xml_content] = xml_content
1099
+ end
1100
+ text
1101
+ else
1102
+ nil
1103
+ end
1104
+ else
1105
+ text[:content] ? text : nil
1106
+ end
1107
+ end
1108
+ feed_extractor = Proc.new do |target|
1109
+ {
1110
+ :type => target.type,
1111
+ :content => target.content,
1112
+ :xml_content => target.xhtml,
1113
+ }
1114
+ end
1115
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
1116
+ maker_extractor, feed_extractor,
1117
+ &block)
1118
+ end
1119
+
1120
+ def assert_maker_atom_text_construct(feed_type, maker_readers, feed_readers,
1121
+ parent_not_set_error_name=nil,
1122
+ parent_not_set_variable=nil,
1123
+ not_set_error_name=nil)
1124
+ _wrap_assertion do
1125
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
1126
+
1127
+ args = [feed_type, maker_readers, feed_readers]
1128
+ if parent_not_set_error_name or parent_not_set_variable
1129
+ assert_not_set_error(parent_not_set_error_name,
1130
+ parent_not_set_variable) do
1131
+ _assert_maker_atom_text_construct(*args) do |maker|
1132
+ yield maker
1133
+ end
1134
+ end
1135
+ else
1136
+ _assert_maker_atom_text_construct(*args) do |maker|
1137
+ yield maker
1138
+ end
1139
+ end
1140
+
1141
+ assert_not_set_error(not_set_error_name, %w(content)) do
1142
+ _assert_maker_atom_text_construct(*args) do |maker|
1143
+ yield maker
1144
+ target = chain_reader(maker, maker_readers) {|x| x}
1145
+ target.type = "text"
1146
+ end
1147
+ end
1148
+
1149
+ assert_not_set_error(not_set_error_name, %w(content)) do
1150
+ _assert_maker_atom_text_construct(*args) do |maker|
1151
+ yield maker
1152
+ target = chain_reader(maker, maker_readers) {|x| x}
1153
+ target.type = "html"
1154
+ end
1155
+ end
1156
+
1157
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
1158
+ _assert_maker_atom_text_construct(*args) do |maker|
1159
+ yield maker
1160
+ target = chain_reader(maker, maker_readers) {|x| x}
1161
+ target.type = "xhtml"
1162
+ end
1163
+ end
1164
+
1165
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
1166
+ _assert_maker_atom_text_construct(*args) do |maker|
1167
+ yield maker
1168
+ target = chain_reader(maker, maker_readers) {|x| x}
1169
+ target.type = "xhtml"
1170
+ target.content = "Content"
1171
+ end
1172
+ end
1173
+
1174
+ _assert_maker_atom_text_construct(*args) do |maker|
1175
+ yield maker
1176
+ target = chain_reader(maker, maker_readers) {|x| x}
1177
+ target.type = "text"
1178
+ target.content = "Content"
1179
+ end
1180
+
1181
+ _assert_maker_atom_text_construct(*args) do |maker|
1182
+ yield maker
1183
+ target = chain_reader(maker, maker_readers) {|x| x}
1184
+ target.type = "html"
1185
+ target.content = "<em>Content</em>"
1186
+ end
1187
+
1188
+ _assert_maker_atom_text_construct(*args) do |maker|
1189
+ yield maker
1190
+ target = chain_reader(maker, maker_readers) {|x| x}
1191
+ target.type = "xhtml"
1192
+ target.xml_content = "text only"
1193
+ end
1194
+
1195
+ _assert_maker_atom_text_construct(*args) do |maker|
1196
+ yield maker
1197
+ target = chain_reader(maker, maker_readers) {|x| x}
1198
+ target.type = "xhtml"
1199
+ target.xml_content = RSS::XML::Element.new("unknown")
1200
+ end
1201
+ end
1202
+ end
1203
+
1204
+ def _assert_maker_atom_date_construct(feed_type, maker_readers,
1205
+ feed_readers, &block)
1206
+ maker_extractor = Proc.new do |target|
1207
+ date = {
1208
+ :content => target,
1209
+ }
1210
+ date[:content] ? date : nil
1211
+ end
1212
+ feed_extractor = Proc.new do |target|
1213
+ {
1214
+ :content => target.content,
1215
+ }
1216
+ end
1217
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
1218
+ maker_extractor, feed_extractor,
1219
+ &block)
1220
+ end
1221
+
1222
+ def assert_maker_atom_date_construct(feed_type, maker_readers, feed_readers,
1223
+ parent_not_set_error_name=nil,
1224
+ parent_not_set_variable=nil)
1225
+ _wrap_assertion do
1226
+ args = [feed_type, maker_readers, feed_readers]
1227
+ if parent_not_set_error_name or parent_not_set_variable
1228
+ assert_not_set_error(parent_not_set_error_name,
1229
+ parent_not_set_variable) do
1230
+ _assert_maker_atom_date_construct(*args) do |maker|
1231
+ yield maker
1232
+ end
1233
+ end
1234
+ else
1235
+ _assert_maker_atom_date_construct(*args) do |maker|
1236
+ yield maker
1237
+ end
1238
+ end
1239
+
1240
+ maker_readers = maker_readers.dup
1241
+ writer = "#{maker_readers.pop}="
1242
+ _assert_maker_atom_date_construct(*args) do |maker|
1243
+ yield maker
1244
+ target = chain_reader(maker, maker_readers)
1245
+ target.__send__(writer, Time.now)
1246
+ end
1247
+ end
1248
+ end
1249
+
1250
+ def _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
1251
+ maker_extractor, feed_extractor)
1252
+ _wrap_assertion do
1253
+ element = nil
1254
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
1255
+ yield maker
1256
+ target = chain_reader(maker, maker_readers) {|x| x}
1257
+ element = maker_extractor.call(target)
1258
+ end
1259
+
1260
+ target = chain_reader(feed, feed_readers)
1261
+ if target
1262
+ actual_element = feed_extractor.call(target)
1263
+ else
1264
+ actual_element = nil
1265
+ end
1266
+ assert_equal(element, actual_element)
1267
+ end
1268
+ end
1269
+
1270
+ def _assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
1271
+ maker_extractor, feed_extractor,
1272
+ invalid_feed_checker=nil)
1273
+ _wrap_assertion do
1274
+ elements = []
1275
+ invalid_feed_exception = nil
1276
+ feed = nil
1277
+ begin
1278
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
1279
+ yield maker
1280
+ targets = chain_reader(maker, maker_readers)
1281
+ targets.each do |target|
1282
+ element = maker_extractor.call(target)
1283
+ elements << element if element
1284
+ end
1285
+ if invalid_feed_checker
1286
+ invalid_feed_exception = invalid_feed_checker.call(targets)
1287
+ end
1288
+ end
1289
+ rescue RSS::Error
1290
+ if invalid_feed_exception.is_a?(RSS::TooMuchTagError)
1291
+ assert_too_much_tag(invalid_feed_exception.tag,
1292
+ invalid_feed_exception.parent) do
1293
+ raise
1294
+ end
1295
+ else
1296
+ raise
1297
+ end
1298
+ end
1299
+
1300
+ if invalid_feed_exception.nil?
1301
+ actual_elements = chain_reader(feed, feed_readers) || []
1302
+ actual_elements = actual_elements.collect do |target|
1303
+ feed_extractor.call(target)
1304
+ end
1305
+ assert_equal(elements, actual_elements)
1306
+ end
1307
+ end
1308
+ end
1309
+
1310
+ def assert_maker_atom_element(feed_type, maker_readers, feed_readers,
1311
+ setup_target, optional_variables,
1312
+ required_variable, assert_method_name,
1313
+ not_set_error_name=nil,
1314
+ *additional_args)
1315
+ _wrap_assertion do
1316
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
1317
+
1318
+ 0.upto(optional_variables.size) do |i|
1319
+ combination(optional_variables, i).each do |names|
1320
+ have = {}
1321
+ names.each do |name|
1322
+ have[name.intern] = true
1323
+ end
1324
+ have_required_variable_too =
1325
+ have.merge({required_variable.intern => true})
1326
+
1327
+ assert_not_set_error(not_set_error_name, [required_variable]) do
1328
+ __send__(assert_method_name, feed_type, maker_readers,
1329
+ feed_readers, *additional_args) do |maker|
1330
+ yield maker
1331
+ target = chain_reader(maker, maker_readers) {|x| x}
1332
+ setup_target.call(target, have)
1333
+ end
1334
+ end
1335
+
1336
+ __send__(assert_method_name, feed_type, maker_readers, feed_readers,
1337
+ *additional_args) do |maker|
1338
+ yield maker
1339
+ target = chain_reader(maker, maker_readers) {|x| x}
1340
+ setup_target.call(target, have_required_variable_too)
1341
+ end
1342
+ end
1343
+ end
1344
+ end
1345
+ end
1346
+
1347
+ def assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
1348
+ setup_target, optional_variables,
1349
+ required_variable, assert_method_name,
1350
+ not_set_error_name=nil,
1351
+ *additional_args)
1352
+ _wrap_assertion do
1353
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
1354
+
1355
+ 0.upto(optional_variables.size) do |i|
1356
+ combination(optional_variables, i).each do |names|
1357
+ have = {}
1358
+ names.each do |name|
1359
+ have[name.intern] = true
1360
+ end
1361
+ have_required_variable_too =
1362
+ have.merge({required_variable.intern => true})
1363
+
1364
+ assert_not_set_error(not_set_error_name, [required_variable]) do
1365
+ __send__(assert_method_name, feed_type, maker_readers,
1366
+ feed_readers, *additional_args) do |maker|
1367
+ yield maker
1368
+ targets = chain_reader(maker, maker_readers)
1369
+ setup_target.call(targets, have)
1370
+ end
1371
+ end
1372
+
1373
+ __send__(assert_method_name, feed_type, maker_readers, feed_readers,
1374
+ *additional_args) do |maker|
1375
+ yield maker
1376
+ targets = chain_reader(maker, maker_readers)
1377
+ setup_target.call(targets, have_required_variable_too)
1378
+ end
1379
+
1380
+ __send__(assert_method_name, feed_type, maker_readers, feed_readers,
1381
+ *additional_args) do |maker|
1382
+ yield maker
1383
+ targets = chain_reader(maker, maker_readers)
1384
+ setup_target.call(targets, have_required_variable_too)
1385
+ setup_target.call(targets, have_required_variable_too)
1386
+ end
1387
+
1388
+ assert_not_set_error(not_set_error_name, [required_variable]) do
1389
+ __send__(assert_method_name, feed_type, maker_readers, feed_readers,
1390
+ *additional_args) do |maker|
1391
+ yield maker
1392
+ targets = chain_reader(maker, maker_readers)
1393
+ setup_target.call(targets, have_required_variable_too)
1394
+ setup_target.call(targets, have)
1395
+ end
1396
+ end
1397
+ end
1398
+ end
1399
+ end
1400
+ end
1401
+
1402
+ def _assert_maker_atom_categories(feed_type, maker_readers,
1403
+ feed_readers, &block)
1404
+ maker_extractor = Proc.new do |target|
1405
+ category = {
1406
+ :term => target.term,
1407
+ :scheme => target.scheme,
1408
+ :label => target.label,
1409
+ }
1410
+ category[:term] ? category : nil
1411
+ end
1412
+ feed_extractor = Proc.new do |target|
1413
+ {
1414
+ :term => target.term,
1415
+ :scheme => target.scheme,
1416
+ :label => target.label,
1417
+ }
1418
+ end
1419
+ _assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
1420
+ maker_extractor, feed_extractor, &block)
1421
+ end
1422
+
1423
+ def assert_maker_atom_categories(feed_type, maker_readers, feed_readers,
1424
+ not_set_error_name=nil, &block)
1425
+ _wrap_assertion do
1426
+ _assert_maker_atom_categories(feed_type, maker_readers,
1427
+ feed_readers) do |maker|
1428
+ yield maker
1429
+ end
1430
+
1431
+ setup_target = Proc.new do |targets, have|
1432
+ target = targets.new_child
1433
+ target.term = "music" if have[:term]
1434
+ target.scheme = "http://example.com/category/music" if have[:scheme]
1435
+ target.label = "Music" if have[:label]
1436
+ end
1437
+
1438
+ optional_variables = %w(scheme label)
1439
+
1440
+ assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
1441
+ setup_target, optional_variables,
1442
+ "term", :_assert_maker_atom_categories,
1443
+ not_set_error_name, &block)
1444
+ end
1445
+ end
1446
+
1447
+ def _assert_maker_atom_generator(feed_type, maker_readers,
1448
+ feed_readers, &block)
1449
+ maker_extractor = Proc.new do |target|
1450
+ generator = {
1451
+ :uri => target.uri,
1452
+ :version => target.version,
1453
+ :content => target.content,
1454
+ }
1455
+ generator[:content] ? generator : nil
1456
+ end
1457
+ feed_extractor = Proc.new do |target|
1458
+ {
1459
+ :uri => target.uri,
1460
+ :version => target.version,
1461
+ :content => target.content,
1462
+ }
1463
+ end
1464
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
1465
+ maker_extractor, feed_extractor,
1466
+ &block)
1467
+ end
1468
+
1469
+ def assert_maker_atom_generator(feed_type, maker_readers, feed_readers,
1470
+ not_set_error_name=nil, &block)
1471
+ _wrap_assertion do
1472
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
1473
+
1474
+ _assert_maker_atom_generator(feed_type, maker_readers,
1475
+ feed_readers) do |maker|
1476
+ yield maker
1477
+ end
1478
+
1479
+ setup_target = Proc.new do |target, have|
1480
+ target.content = "RSS Maker" if have[:content]
1481
+ target.uri = "http://example.com/rss/maker" if have[:uri]
1482
+ target.version = "0.0.1" if have[:version]
1483
+ end
1484
+
1485
+ optional_variables = %w(uri version)
1486
+
1487
+ assert_maker_atom_element(feed_type, maker_readers, feed_readers,
1488
+ setup_target, optional_variables,
1489
+ "content", :_assert_maker_atom_generator,
1490
+ not_set_error_name, &block)
1491
+ end
1492
+ end
1493
+
1494
+ def _assert_maker_atom_icon(feed_type, maker_readers, feed_readers,
1495
+ accessor_base, &block)
1496
+ maker_extractor = Proc.new do |target|
1497
+ icon = {
1498
+ :content => target.__send__(accessor_base),
1499
+ }
1500
+ icon[:content] ? icon : nil
1501
+ end
1502
+ feed_extractor = Proc.new do |target|
1503
+ {
1504
+ :content => target.content,
1505
+ }
1506
+ end
1507
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
1508
+ maker_extractor, feed_extractor,
1509
+ &block)
1510
+ end
1511
+
1512
+ def assert_maker_atom_icon(feed_type, maker_readers, feed_readers,
1513
+ accessor_base=nil, not_set_error_name=nil)
1514
+ _wrap_assertion do
1515
+ accessor_base ||= "url"
1516
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
1517
+
1518
+ _assert_maker_atom_icon(feed_type, maker_readers, feed_readers,
1519
+ accessor_base) do |maker|
1520
+ yield maker
1521
+ end
1522
+
1523
+ _assert_maker_atom_icon(feed_type, maker_readers, feed_readers,
1524
+ accessor_base) do |maker|
1525
+ yield maker
1526
+ target = chain_reader(maker, maker_readers)
1527
+ target.__send__("#{accessor_base}=", "http://example.com/icon.png")
1528
+ end
1529
+ end
1530
+ end
1531
+
1532
+ def _assert_maker_atom_links(feed_type, maker_readers, feed_readers,
1533
+ allow_duplication=false, &block)
1534
+ maker_extractor = Proc.new do |target|
1535
+ link = {
1536
+ :href => target.href,
1537
+ :rel => target.rel,
1538
+ :type => target.type,
1539
+ :hreflang => target.hreflang,
1540
+ :title => target.title,
1541
+ :length => target.length,
1542
+ }
1543
+ link[:href] ? link : nil
1544
+ end
1545
+ feed_extractor = Proc.new do |target|
1546
+ {
1547
+ :href => target.href,
1548
+ :rel => target.rel,
1549
+ :type => target.type,
1550
+ :hreflang => target.hreflang,
1551
+ :title => target.title,
1552
+ :length => target.length,
1553
+ }
1554
+ end
1555
+
1556
+ if feed_readers.first == "entries"
1557
+ parent = "entry"
1558
+ else
1559
+ parent = feed_type
1560
+ end
1561
+ invalid_feed_checker = Proc.new do |targets|
1562
+ infos = {}
1563
+ invalid_exception = nil
1564
+ targets.each do |target|
1565
+ key = [target.hreflang, target.type]
1566
+ if infos.has_key?(key)
1567
+ invalid_exception = RSS::TooMuchTagError.new("link", parent)
1568
+ break
1569
+ end
1570
+ infos[key] = true if target.rel.nil? or target.rel == "alternate"
1571
+ end
1572
+ invalid_exception
1573
+ end
1574
+ invalid_feed_checker = nil if allow_duplication
1575
+ _assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
1576
+ maker_extractor, feed_extractor,
1577
+ invalid_feed_checker,
1578
+ &block)
1579
+ end
1580
+
1581
+ def assert_maker_atom_links(feed_type, maker_readers, feed_readers,
1582
+ not_set_error_name=nil, allow_duplication=false,
1583
+ &block)
1584
+ _wrap_assertion do
1585
+ _assert_maker_atom_links(feed_type, maker_readers,
1586
+ feed_readers) do |maker|
1587
+ yield maker
1588
+ end
1589
+
1590
+ langs = %(ja en fr zh po)
1591
+ setup_target = Proc.new do |targets, have|
1592
+ target = targets.new_child
1593
+ lang = langs[targets.size % langs.size]
1594
+ target.href = "http://example.com/index.html.#{lang}" if have[:href]
1595
+ target.rel = "alternate" if have[:rel]
1596
+ target.type = "text/xhtml" if have[:type]
1597
+ target.hreflang = lang if have[:hreflang]
1598
+ target.title = "FrontPage(#{lang})" if have[:title]
1599
+ target.length = 1024 if have[:length]
1600
+ end
1601
+
1602
+ optional_variables = %w(rel type hreflang title length)
1603
+
1604
+ assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
1605
+ setup_target, optional_variables,
1606
+ "href", :_assert_maker_atom_links,
1607
+ not_set_error_name, allow_duplication,
1608
+ &block)
1609
+ end
1610
+ end
1611
+
1612
+ def _assert_maker_atom_logo(feed_type, maker_readers, feed_readers,
1613
+ accessor_base, &block)
1614
+ maker_extractor = Proc.new do |target|
1615
+ logo = {
1616
+ :uri => target.__send__(accessor_base),
1617
+ }
1618
+ logo[:uri] ? logo : nil
1619
+ end
1620
+ feed_extractor = Proc.new do |target|
1621
+ {
1622
+ :uri => target.content,
1623
+ }
1624
+ end
1625
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
1626
+ maker_extractor, feed_extractor,
1627
+ &block)
1628
+ end
1629
+
1630
+ def assert_maker_atom_logo(feed_type, maker_readers, feed_readers,
1631
+ accessor_base=nil, not_set_error_name=nil)
1632
+ _wrap_assertion do
1633
+ accessor_base ||= "uri"
1634
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
1635
+
1636
+ _assert_maker_atom_logo(feed_type, maker_readers, feed_readers,
1637
+ accessor_base) do |maker|
1638
+ yield maker
1639
+ end
1640
+
1641
+ _assert_maker_atom_logo(feed_type, maker_readers, feed_readers,
1642
+ accessor_base) do |maker|
1643
+ yield maker
1644
+ target = chain_reader(maker, maker_readers)
1645
+ target.__send__("#{accessor_base}=", "http://example.com/logo.png")
1646
+ end
1647
+ end
1648
+ end
1649
+
1650
+ def _assert_maker_atom_id(feed_type, maker_readers, feed_readers, &block)
1651
+ maker_extractor = Proc.new do |target|
1652
+ id = {
1653
+ :uri => target.id,
1654
+ }
1655
+ id[:uri] ? id : nil
1656
+ end
1657
+ feed_extractor = Proc.new do |target|
1658
+ if target.id
1659
+ {
1660
+ :uri => target.id.content,
1661
+ }
1662
+ else
1663
+ nil
1664
+ end
1665
+ end
1666
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
1667
+ maker_extractor, feed_extractor,
1668
+ &block)
1669
+ end
1670
+
1671
+ def assert_maker_atom_id(feed_type, maker_readers, feed_readers,
1672
+ not_set_error_name=nil)
1673
+ _wrap_assertion do
1674
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
1675
+
1676
+ args = [feed_type, maker_readers, feed_readers]
1677
+ _assert_maker_atom_id(*args) do |maker|
1678
+ yield maker
1679
+ end
1680
+
1681
+ _assert_maker_atom_id(*args) do |maker|
1682
+ yield maker
1683
+ target = chain_reader(maker, maker_readers)
1684
+ target.id = "http://example.com/id/1"
1685
+ end
1686
+ end
1687
+ end
1688
+
1689
+ def _assert_maker_atom_content(feed_type, maker_readers,
1690
+ feed_readers, &block)
1691
+ maker_extractor = Proc.new do |target|
1692
+ content = {
1693
+ :type => target.type,
1694
+ :src => target.src,
1695
+ :content => target.content,
1696
+ :xml => target.xml,
1697
+ :inline_text => target.inline_text?,
1698
+ :inline_html => target.inline_html?,
1699
+ :inline_xhtml => target.inline_xhtml?,
1700
+ :inline_other => target.inline_other?,
1701
+ :inline_other_text => target.inline_other_text?,
1702
+ :inline_other_xml => target.inline_other_xml?,
1703
+ :inline_other_base64 => target.inline_other_base64?,
1704
+ :out_of_line => target.out_of_line?,
1705
+ }
1706
+ content[:src] = nil if content[:src] and content[:content]
1707
+ if content[:type] or content[:content]
1708
+ content
1709
+ else
1710
+ nil
1711
+ end
1712
+ end
1713
+ feed_extractor = Proc.new do |target|
1714
+ {
1715
+ :type => target.type,
1716
+ :src => target.src,
1717
+ :content => target.content,
1718
+ :xml => target.xml,
1719
+ :inline_text => target.inline_text?,
1720
+ :inline_html => target.inline_html?,
1721
+ :inline_xhtml => target.inline_xhtml?,
1722
+ :inline_other => target.inline_other?,
1723
+ :inline_other_text => target.inline_other_text?,
1724
+ :inline_other_xml => target.inline_other_xml?,
1725
+ :inline_other_base64 => target.inline_other_base64?,
1726
+ :out_of_line => target.out_of_line?,
1727
+ }
1728
+ end
1729
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
1730
+ maker_extractor, feed_extractor,
1731
+ &block)
1732
+ end
1733
+
1734
+ def assert_maker_atom_content(feed_type, maker_readers, feed_readers,
1735
+ not_set_error_name=nil, &block)
1736
+ _wrap_assertion do
1737
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
1738
+ args = [feed_type, maker_readers, feed_readers, not_set_error_name]
1739
+ assert_maker_atom_content_inline_text(*args, &block)
1740
+ assert_maker_atom_content_inline_xhtml(*args, &block)
1741
+ assert_maker_atom_content_inline_other(*args, &block)
1742
+ assert_maker_atom_content_out_of_line(*args, &block)
1743
+ end
1744
+ end
1745
+
1746
+ def assert_maker_atom_content_inline_text(feed_type, maker_readers,
1747
+ feed_readers, not_set_error_name)
1748
+ _wrap_assertion do
1749
+ args = [feed_type, maker_readers, feed_readers]
1750
+ _assert_maker_atom_content(*args) do |maker|
1751
+ yield maker
1752
+ end
1753
+
1754
+ assert_not_set_error(not_set_error_name, %w(content)) do
1755
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
1756
+ yield maker
1757
+ target = chain_reader(maker, maker_readers)
1758
+ target.type = "text"
1759
+ end
1760
+ end
1761
+
1762
+ assert_not_set_error(not_set_error_name, %w(content)) do
1763
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
1764
+ yield maker
1765
+ target = chain_reader(maker, maker_readers)
1766
+ target.type = "html"
1767
+ end
1768
+ end
1769
+
1770
+ _assert_maker_atom_content(*args) do |maker|
1771
+ yield maker
1772
+ target = chain_reader(maker, maker_readers)
1773
+ target.content = ""
1774
+ end
1775
+
1776
+ _assert_maker_atom_content(*args) do |maker|
1777
+ yield maker
1778
+ target = chain_reader(maker, maker_readers)
1779
+ target.type = "text"
1780
+ target.content = "example content"
1781
+ end
1782
+
1783
+ _assert_maker_atom_content(*args) do |maker|
1784
+ yield maker
1785
+ target = chain_reader(maker, maker_readers)
1786
+ target.type = "html"
1787
+ target.content = "<em>text</em>"
1788
+ end
1789
+ end
1790
+ end
1791
+
1792
+ def assert_maker_atom_content_inline_xhtml(feed_type, maker_readers,
1793
+ feed_readers, not_set_error_name)
1794
+ _wrap_assertion do
1795
+ args = [feed_type, maker_readers, feed_readers]
1796
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
1797
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
1798
+ yield maker
1799
+ target = chain_reader(maker, maker_readers)
1800
+ target.type = "xhtml"
1801
+ end
1802
+ end
1803
+
1804
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
1805
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
1806
+ yield maker
1807
+ target = chain_reader(maker, maker_readers)
1808
+ target.type = "xhtml"
1809
+ target.content = "dummy"
1810
+ end
1811
+ end
1812
+
1813
+ _assert_maker_atom_content(*args) do |maker|
1814
+ yield maker
1815
+ target = chain_reader(maker, maker_readers)
1816
+ target.type = "xhtml"
1817
+ target.xml_content = "text"
1818
+ end
1819
+
1820
+ _assert_maker_atom_content(*args) do |maker|
1821
+ yield maker
1822
+ target = chain_reader(maker, maker_readers)
1823
+ target.type = "xhtml"
1824
+ target.xml = "text"
1825
+ end
1826
+
1827
+ _assert_maker_atom_content(*args) do |maker|
1828
+ yield maker
1829
+ target = chain_reader(maker, maker_readers)
1830
+ target.type = "xhtml"
1831
+ target.xml_content =
1832
+ RSS::XML::Element.new("em", nil, nil, {}, ["text"])
1833
+ end
1834
+
1835
+ _assert_maker_atom_content(*args) do |maker|
1836
+ yield maker
1837
+ target = chain_reader(maker, maker_readers)
1838
+ target.type = "xhtml"
1839
+ target.xml = RSS::XML::Element.new("em", nil, nil, {}, ["text"])
1840
+ end
1841
+
1842
+
1843
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
1844
+ em = RSS::XML::Element.new("em", nil, nil, {}, ["text"])
1845
+ em_with_xhtml_uri =
1846
+ RSS::XML::Element.new("em", nil, xhtml_uri, {}, ["text"])
1847
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
1848
+ yield maker
1849
+ target = chain_reader(maker, maker_readers)
1850
+ target.type = "xhtml"
1851
+ target.xml = em
1852
+ end
1853
+ assert_equal(RSS::XML::Element.new("div", nil, xhtml_uri,
1854
+ {"xmlns" => xhtml_uri},
1855
+ [em_with_xhtml_uri]),
1856
+ chain_reader(feed, feed_readers).xml)
1857
+
1858
+ div = RSS::XML::Element.new("div", nil, xhtml_uri,
1859
+ {"xmlns" => xhtml_uri,
1860
+ "class" => "sample"},
1861
+ ["text"])
1862
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
1863
+ yield maker
1864
+ target = chain_reader(maker, maker_readers)
1865
+ target.type = "xhtml"
1866
+ target.xml = div
1867
+ end
1868
+ assert_equal(div, chain_reader(feed, feed_readers).xml)
1869
+ end
1870
+ end
1871
+
1872
+ def assert_maker_atom_content_inline_other(*args, &block)
1873
+ _wrap_assertion do
1874
+ assert_maker_atom_content_inline_other_xml(*args, &block)
1875
+ assert_maker_atom_content_inline_other_text(*args, &block)
1876
+ assert_maker_atom_content_inline_other_base64(*args, &block)
1877
+ end
1878
+ end
1879
+
1880
+ def assert_maker_atom_content_inline_other_xml(feed_type, maker_readers,
1881
+ feed_readers,
1882
+ not_set_error_name)
1883
+ _wrap_assertion do
1884
+ args = [feed_type, maker_readers, feed_readers]
1885
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
1886
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
1887
+ yield maker
1888
+ target = chain_reader(maker, maker_readers)
1889
+ target.type = "application/xml"
1890
+ end
1891
+ end
1892
+
1893
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
1894
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
1895
+ yield maker
1896
+ target = chain_reader(maker, maker_readers)
1897
+ target.type = "svg/image+xml"
1898
+ end
1899
+ end
1900
+
1901
+ svg_uri = "http://www.w3.org/2000/svg"
1902
+ rect = RSS::XML::Element.new("rect", nil, svg_uri,
1903
+ {"x" => "0.5cm",
1904
+ "y" => "0.5cm",
1905
+ "width" => "2cm",
1906
+ "height" => "1cm"})
1907
+ svg = RSS::XML::Element.new("svg", nil, svg_uri,
1908
+ {"xmlns" => svg_uri,
1909
+ "version" => "1.1",
1910
+ "width" => "5cm",
1911
+ "height" => "4cm"},
1912
+ [rect])
1913
+ _assert_maker_atom_content(*args) do |maker|
1914
+ yield maker
1915
+ target = chain_reader(maker, maker_readers)
1916
+ target.type = "image/svg+xml"
1917
+ target.xml = svg
1918
+ end
1919
+
1920
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
1921
+ yield maker
1922
+ target = chain_reader(maker, maker_readers)
1923
+ target.type = "image/svg+xml"
1924
+ target.xml = svg
1925
+ end
1926
+ assert_equal(svg, chain_reader(feed, feed_readers).xml)
1927
+ end
1928
+ end
1929
+
1930
+ def assert_maker_atom_content_inline_other_text(feed_type, maker_readers,
1931
+ feed_readers,
1932
+ not_set_error_name)
1933
+ _wrap_assertion do
1934
+ args = [feed_type, maker_readers, feed_readers]
1935
+ assert_not_set_error(not_set_error_name, %w(content)) do
1936
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
1937
+ yield maker
1938
+ target = chain_reader(maker, maker_readers)
1939
+ target.type = "text/plain"
1940
+ end
1941
+ end
1942
+
1943
+ _assert_maker_atom_content(*args) do |maker|
1944
+ yield maker
1945
+ target = chain_reader(maker, maker_readers)
1946
+ target.type = "text/plain"
1947
+ target.content = "text"
1948
+ end
1949
+ end
1950
+ end
1951
+
1952
+ def assert_maker_atom_content_inline_other_base64(feed_type, maker_readers,
1953
+ feed_readers,
1954
+ not_set_error_name)
1955
+ _wrap_assertion do
1956
+ args = [feed_type, maker_readers, feed_readers]
1957
+ content = "\211PNG\r\n\032\n"
1958
+ _assert_maker_atom_content(*args) do |maker|
1959
+ yield maker
1960
+ target = chain_reader(maker, maker_readers)
1961
+ target.type = "image/png"
1962
+ target.content = content
1963
+ end
1964
+
1965
+ _assert_maker_atom_content(*args) do |maker|
1966
+ yield maker
1967
+ target = chain_reader(maker, maker_readers)
1968
+ target.type = "image/png"
1969
+ target.src = "http://example.com/logo.png"
1970
+ target.content = content
1971
+ end
1972
+
1973
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
1974
+ yield maker
1975
+ target = chain_reader(maker, maker_readers)
1976
+ target.type = "image/png"
1977
+ target.src = "http://example.com/logo.png"
1978
+ target.content = content
1979
+ end
1980
+ target = chain_reader(feed, feed_readers)
1981
+ assert_nil(target.src)
1982
+ assert_equal(content, target.content)
1983
+ end
1984
+ end
1985
+
1986
+ def assert_maker_atom_content_out_of_line(feed_type, maker_readers,
1987
+ feed_readers, not_set_error_name)
1988
+ _wrap_assertion do
1989
+ args = [feed_type, maker_readers, feed_readers]
1990
+ assert_not_set_error(not_set_error_name, %w(content)) do
1991
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
1992
+ yield maker
1993
+ target = chain_reader(maker, maker_readers)
1994
+ target.type = "image/png"
1995
+ end
1996
+ end
1997
+
1998
+ assert_not_set_error(not_set_error_name, %w(type)) do
1999
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
2000
+ yield maker
2001
+ target = chain_reader(maker, maker_readers)
2002
+ target.src = "http://example.com/logo.png"
2003
+ end
2004
+ end
2005
+
2006
+ _assert_maker_atom_content(*args) do |maker|
2007
+ yield maker
2008
+ target = chain_reader(maker, maker_readers)
2009
+ target.type = "image/png"
2010
+ target.src = "http://example.com/logo.png"
2011
+ end
2012
+
2013
+ _assert_maker_atom_content(*args) do |maker|
2014
+ yield maker
2015
+ target = chain_reader(maker, maker_readers)
2016
+ target.type = "image/png"
2017
+ target.content = "\211PNG\r\n\032\n"
2018
+ end
2019
+
2020
+ _assert_maker_atom_content(*args) do |maker|
2021
+ yield maker
2022
+ target = chain_reader(maker, maker_readers)
2023
+ target.type = "application/xml"
2024
+ target.src = "http://example.com/sample.xml"
2025
+ end
2026
+
2027
+
2028
+ _assert_maker_atom_content(*args) do |maker|
2029
+ yield maker
2030
+ target = chain_reader(maker, maker_readers)
2031
+ target.type = "text/plain"
2032
+ target.src = "http://example.com/README.txt"
2033
+ end
2034
+ end
2035
+ end
2036
+
2037
+ def assert_slash_elements(expected, target)
2038
+ assert_equal(expected,
2039
+ {
2040
+ "section" => target.slash_section,
2041
+ "department" => target.slash_department,
2042
+ "comments" => target.slash_comments,
2043
+ "hit_parades" => target.slash_hit_parades,
2044
+ })
2045
+ assert_equal(expected["hit_parades"].join(","),
2046
+ target.slash_hit_parade)
2047
+ end
2048
+
2049
+ def chain_reader(target, readers, &block)
2050
+ readers.inject(target) do |result, reader|
2051
+ return nil if result.nil?
2052
+ result.__send__(reader, &block)
2053
+ end
2054
+ end
2055
+
2056
+ def normalized_attrs(attrs)
2057
+ n_attrs = {}
2058
+ attrs.each do |name, value|
2059
+ n_attrs[name.to_s] = value
2060
+ end
2061
+ n_attrs
2062
+ end
2063
+
2064
+ def combination(elements, n)
2065
+ if n <= 0 or elements.size < n
2066
+ []
2067
+ elsif n == 1
2068
+ elements.collect {|element| [element]}
2069
+ else
2070
+ first, *rest = elements
2071
+ combination(rest, n - 1).collect do |sub_elements|
2072
+ [first, *sub_elements]
2073
+ end + combination(rest, n)
2074
+ end
2075
+ end
2076
+
2077
+ def tag(name, content=nil, attributes={})
2078
+ attributes = attributes.collect do |key, value|
2079
+ "#{ERB::Util.h(key)}=\"#{ERB::Util.h(value)}\""
2080
+ end.join(" ")
2081
+ begin_tag = "<#{name}"
2082
+ begin_tag << " #{attributes}" unless attributes.empty?
2083
+ if content
2084
+ "#{begin_tag}>#{content}</#{name}>\n"
2085
+ else
2086
+ "#{begin_tag}/>\n"
2087
+ end
2088
+ end
2089
+ end
2090
+ end