eactionpack 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +7 -0
- data/MIT-LICENSE +21 -0
- data/README +469 -0
- data/RUNNING_UNIT_TESTS +24 -0
- data/Rakefile +146 -0
- data/install.rb +30 -0
- data/lib/action_controller.rb +79 -0
- data/lib/action_controller/assertions.rb +69 -0
- data/lib/action_controller/assertions/dom_assertions.rb +39 -0
- data/lib/action_controller/assertions/model_assertions.rb +20 -0
- data/lib/action_controller/assertions/response_assertions.rb +172 -0
- data/lib/action_controller/assertions/routing_assertions.rb +146 -0
- data/lib/action_controller/assertions/selector_assertions.rb +491 -0
- data/lib/action_controller/assertions/tag_assertions.rb +130 -0
- data/lib/action_controller/base.rb +1288 -0
- data/lib/action_controller/benchmarking.rb +94 -0
- data/lib/action_controller/caching.rb +72 -0
- data/lib/action_controller/caching/actions.rb +144 -0
- data/lib/action_controller/caching/fragments.rb +138 -0
- data/lib/action_controller/caching/pages.rb +154 -0
- data/lib/action_controller/caching/sql_cache.rb +18 -0
- data/lib/action_controller/caching/sweeping.rb +97 -0
- data/lib/action_controller/cgi_ext.rb +16 -0
- data/lib/action_controller/cgi_ext/cookie.rb +110 -0
- data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
- data/lib/action_controller/cgi_ext/session.rb +73 -0
- data/lib/action_controller/cgi_ext/stdinput.rb +24 -0
- data/lib/action_controller/cgi_process.rb +223 -0
- data/lib/action_controller/components.rb +166 -0
- data/lib/action_controller/cookies.rb +96 -0
- data/lib/action_controller/dispatcher.rb +162 -0
- data/lib/action_controller/filters.rb +642 -0
- data/lib/action_controller/flash.rb +172 -0
- data/lib/action_controller/headers.rb +31 -0
- data/lib/action_controller/helpers.rb +221 -0
- data/lib/action_controller/http_authentication.rb +124 -0
- data/lib/action_controller/integration.rb +634 -0
- data/lib/action_controller/layout.rb +309 -0
- data/lib/action_controller/mime_responds.rb +173 -0
- data/lib/action_controller/mime_type.rb +186 -0
- data/lib/action_controller/mime_types.rb +20 -0
- data/lib/action_controller/polymorphic_routes.rb +191 -0
- data/lib/action_controller/record_identifier.rb +102 -0
- data/lib/action_controller/request.rb +764 -0
- data/lib/action_controller/request_forgery_protection.rb +140 -0
- data/lib/action_controller/request_profiler.rb +169 -0
- data/lib/action_controller/rescue.rb +258 -0
- data/lib/action_controller/resources.rb +572 -0
- data/lib/action_controller/response.rb +76 -0
- data/lib/action_controller/routing.rb +387 -0
- data/lib/action_controller/routing/builder.rb +203 -0
- data/lib/action_controller/routing/optimisations.rb +120 -0
- data/lib/action_controller/routing/recognition_optimisation.rb +162 -0
- data/lib/action_controller/routing/route.rb +240 -0
- data/lib/action_controller/routing/route_set.rb +436 -0
- data/lib/action_controller/routing/routing_ext.rb +46 -0
- data/lib/action_controller/routing/segments.rb +283 -0
- data/lib/action_controller/session/active_record_store.rb +340 -0
- data/lib/action_controller/session/cookie_store.rb +166 -0
- data/lib/action_controller/session/drb_server.rb +32 -0
- data/lib/action_controller/session/drb_store.rb +35 -0
- data/lib/action_controller/session/mem_cache_store.rb +98 -0
- data/lib/action_controller/session_management.rb +158 -0
- data/lib/action_controller/status_codes.rb +88 -0
- data/lib/action_controller/streaming.rb +155 -0
- data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_controller/templates/rescues/_trace.erb +26 -0
- data/lib/action_controller/templates/rescues/diagnostics.erb +11 -0
- data/lib/action_controller/templates/rescues/layout.erb +29 -0
- data/lib/action_controller/templates/rescues/missing_template.erb +2 -0
- data/lib/action_controller/templates/rescues/routing_error.erb +10 -0
- data/lib/action_controller/templates/rescues/template_error.erb +21 -0
- data/lib/action_controller/templates/rescues/unknown_action.erb +2 -0
- data/lib/action_controller/test_case.rb +83 -0
- data/lib/action_controller/test_process.rb +526 -0
- data/lib/action_controller/url_rewriter.rb +142 -0
- data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
- data/lib/action_controller/verification.rb +130 -0
- data/lib/action_pack.rb +24 -0
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +44 -0
- data/lib/action_view/base.rb +335 -0
- data/lib/action_view/helpers/active_record_helper.rb +276 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +599 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +143 -0
- data/lib/action_view/helpers/benchmark_helper.rb +33 -0
- data/lib/action_view/helpers/cache_helper.rb +40 -0
- data/lib/action_view/helpers/capture_helper.rb +161 -0
- data/lib/action_view/helpers/date_helper.rb +711 -0
- data/lib/action_view/helpers/debug_helper.rb +31 -0
- data/lib/action_view/helpers/form_helper.rb +767 -0
- data/lib/action_view/helpers/form_options_helper.rb +458 -0
- data/lib/action_view/helpers/form_tag_helper.rb +458 -0
- data/lib/action_view/helpers/javascript_helper.rb +148 -0
- data/lib/action_view/helpers/number_helper.rb +186 -0
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +59 -0
- data/lib/action_view/helpers/sanitize_helper.rb +229 -0
- data/lib/action_view/helpers/tag_helper.rb +134 -0
- data/lib/action_view/helpers/text_helper.rb +507 -0
- data/lib/action_view/helpers/url_helper.rb +573 -0
- data/lib/action_view/inline_template.rb +20 -0
- data/lib/action_view/partial_template.rb +70 -0
- data/lib/action_view/partials.rb +158 -0
- data/lib/action_view/template.rb +125 -0
- data/lib/action_view/template_error.rb +110 -0
- data/lib/action_view/template_finder.rb +176 -0
- data/lib/action_view/template_handler.rb +34 -0
- data/lib/action_view/template_handlers/builder.rb +27 -0
- data/lib/action_view/template_handlers/compilable.rb +128 -0
- data/lib/action_view/template_handlers/erb.rb +56 -0
- data/lib/action_view/test_case.rb +58 -0
- data/lib/actionpack.rb +1 -0
- data/test/abstract_unit.rb +36 -0
- data/test/active_record_unit.rb +105 -0
- data/test/activerecord/active_record_store_test.rb +141 -0
- data/test/activerecord/render_partial_with_record_identification_test.rb +191 -0
- data/test/adv_attr_test.rb +20 -0
- data/test/controller/action_pack_assertions_test.rb +543 -0
- data/test/controller/addresses_render_test.rb +43 -0
- data/test/controller/assert_select_test.rb +331 -0
- data/test/controller/base_test.rb +219 -0
- data/test/controller/benchmark_test.rb +32 -0
- data/test/controller/caching_test.rb +581 -0
- data/test/controller/capture_test.rb +89 -0
- data/test/controller/cgi_test.rb +116 -0
- data/test/controller/components_test.rb +140 -0
- data/test/controller/content_type_test.rb +139 -0
- data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
- data/test/controller/cookie_test.rb +146 -0
- data/test/controller/custom_handler_test.rb +45 -0
- data/test/controller/deprecation/deprecated_base_methods_test.rb +37 -0
- data/test/controller/dispatcher_test.rb +105 -0
- data/test/controller/fake_controllers.rb +33 -0
- data/test/controller/fake_models.rb +11 -0
- data/test/controller/filter_params_test.rb +49 -0
- data/test/controller/filters_test.rb +881 -0
- data/test/controller/flash_test.rb +146 -0
- data/test/controller/header_test.rb +14 -0
- data/test/controller/helper_test.rb +210 -0
- data/test/controller/html-scanner/cdata_node_test.rb +15 -0
- data/test/controller/html-scanner/document_test.rb +148 -0
- data/test/controller/html-scanner/node_test.rb +89 -0
- data/test/controller/html-scanner/sanitizer_test.rb +269 -0
- data/test/controller/html-scanner/tag_node_test.rb +238 -0
- data/test/controller/html-scanner/text_node_test.rb +50 -0
- data/test/controller/html-scanner/tokenizer_test.rb +131 -0
- data/test/controller/http_authentication_test.rb +54 -0
- data/test/controller/integration_test.rb +252 -0
- data/test/controller/integration_upload_test.rb +43 -0
- data/test/controller/layout_test.rb +255 -0
- data/test/controller/mime_responds_test.rb +514 -0
- data/test/controller/mime_type_test.rb +84 -0
- data/test/controller/new_render_test.rb +843 -0
- data/test/controller/polymorphic_routes_test.rb +174 -0
- data/test/controller/record_identifier_test.rb +139 -0
- data/test/controller/redirect_test.rb +289 -0
- data/test/controller/render_test.rb +484 -0
- data/test/controller/request_forgery_protection_test.rb +305 -0
- data/test/controller/request_test.rb +928 -0
- data/test/controller/rescue_test.rb +517 -0
- data/test/controller/resources_test.rb +873 -0
- data/test/controller/routing_test.rb +2464 -0
- data/test/controller/selector_test.rb +628 -0
- data/test/controller/send_file_test.rb +138 -0
- data/test/controller/session/cookie_store_test.rb +258 -0
- data/test/controller/session/mem_cache_store_test.rb +181 -0
- data/test/controller/session_fixation_test.rb +89 -0
- data/test/controller/session_management_test.rb +178 -0
- data/test/controller/test_test.rb +695 -0
- data/test/controller/url_rewriter_test.rb +310 -0
- data/test/controller/verification_test.rb +270 -0
- data/test/controller/view_paths_test.rb +140 -0
- data/test/controller/webservice_test.rb +229 -0
- data/test/fixtures/addresses/list.erb +1 -0
- data/test/fixtures/bad_customers/_bad_customer.html.erb +1 -0
- data/test/fixtures/companies.yml +24 -0
- data/test/fixtures/company.rb +10 -0
- data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_js.js.erb +1 -0
- data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
- data/test/fixtures/customers/_customer.html.erb +1 -0
- data/test/fixtures/db_definitions/sqlite.sql +49 -0
- data/test/fixtures/developer.rb +9 -0
- data/test/fixtures/developers.yml +21 -0
- data/test/fixtures/developers_projects.yml +13 -0
- data/test/fixtures/fun/games/hello_world.erb +1 -0
- data/test/fixtures/functional_caching/_partial.erb +3 -0
- data/test/fixtures/functional_caching/fragment_cached.html.erb +2 -0
- data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +1 -0
- data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +1 -0
- data/test/fixtures/good_customers/_good_customer.html.erb +1 -0
- data/test/fixtures/helpers/abc_helper.rb +5 -0
- data/test/fixtures/helpers/fun/games_helper.rb +3 -0
- data/test/fixtures/helpers/fun/pdf_helper.rb +3 -0
- data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
- data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
- data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
- data/test/fixtures/layouts/block_with_layout.erb +3 -0
- data/test/fixtures/layouts/builder.builder +3 -0
- data/test/fixtures/layouts/partial_with_layout.erb +3 -0
- data/test/fixtures/layouts/standard.erb +1 -0
- data/test/fixtures/layouts/talk_from_action.erb +2 -0
- data/test/fixtures/layouts/yield.erb +2 -0
- data/test/fixtures/mascot.rb +3 -0
- data/test/fixtures/mascots.yml +4 -0
- data/test/fixtures/mascots/_mascot.html.erb +1 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/boundary_problem_file +10 -0
- data/test/fixtures/multipart/bracketed_param +5 -0
- data/test/fixtures/multipart/large_text_file +10 -0
- data/test/fixtures/multipart/mixed_files +0 -0
- data/test/fixtures/multipart/mona_lisa.jpg +0 -0
- data/test/fixtures/multipart/single_parameter +5 -0
- data/test/fixtures/multipart/text_file +10 -0
- data/test/fixtures/override/test/hello_world.erb +1 -0
- data/test/fixtures/override2/layouts/test/sub.erb +1 -0
- data/test/fixtures/post_test/layouts/post.html.erb +1 -0
- data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
- data/test/fixtures/post_test/post/index.html.erb +1 -0
- data/test/fixtures/post_test/post/index.iphone.erb +1 -0
- data/test/fixtures/post_test/super_post/index.html.erb +1 -0
- data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
- data/test/fixtures/project.rb +3 -0
- data/test/fixtures/projects.yml +7 -0
- data/test/fixtures/public/404.html +1 -0
- data/test/fixtures/public/500.html +1 -0
- data/test/fixtures/public/images/rails.png +0 -0
- data/test/fixtures/public/javascripts/application.js +1 -0
- data/test/fixtures/public/javascripts/bank.js +1 -0
- data/test/fixtures/public/javascripts/robber.js +1 -0
- data/test/fixtures/public/javascripts/version.1.0.js +1 -0
- data/test/fixtures/public/stylesheets/bank.css +1 -0
- data/test/fixtures/public/stylesheets/robber.css +1 -0
- data/test/fixtures/public/stylesheets/version.1.0.css +1 -0
- data/test/fixtures/replies.yml +15 -0
- data/test/fixtures/reply.rb +7 -0
- data/test/fixtures/respond_to/all_types_with_layout.html.erb +1 -0
- data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
- data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
- data/test/fixtures/respond_to/using_defaults.html.erb +1 -0
- data/test/fixtures/respond_to/using_defaults.js.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults.xml.builder +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +1 -0
- data/test/fixtures/scope/test/modgreet.erb +1 -0
- data/test/fixtures/shared.html.erb +1 -0
- data/test/fixtures/symlink_parent/symlinked_layout.erb +5 -0
- data/test/fixtures/test/_customer.erb +1 -0
- data/test/fixtures/test/_customer_counter.erb +1 -0
- data/test/fixtures/test/_customer_greeting.erb +1 -0
- data/test/fixtures/test/_form.erb +1 -0
- data/test/fixtures/test/_hash_greeting.erb +1 -0
- data/test/fixtures/test/_hash_object.erb +2 -0
- data/test/fixtures/test/_hello.builder +1 -0
- data/test/fixtures/test/_labelling_form.erb +1 -0
- data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
- data/test/fixtures/test/_partial.erb +1 -0
- data/test/fixtures/test/_partial.html.erb +1 -0
- data/test/fixtures/test/_partial.js.erb +1 -0
- data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
- data/test/fixtures/test/_partial_only.erb +1 -0
- data/test/fixtures/test/_person.erb +2 -0
- data/test/fixtures/test/_raise.html.erb +1 -0
- data/test/fixtures/test/action_talk_to_layout.erb +2 -0
- data/test/fixtures/test/block_content_for.erb +2 -0
- data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
- data/test/fixtures/test/capturing.erb +4 -0
- data/test/fixtures/test/content_for.erb +2 -0
- data/test/fixtures/test/content_for_concatenated.erb +3 -0
- data/test/fixtures/test/content_for_with_parameter.erb +2 -0
- data/test/fixtures/test/delete_with_js.rjs +2 -0
- data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +1 -0
- data/test/fixtures/test/enum_rjs_test.rjs +6 -0
- data/test/fixtures/test/erb_content_for.erb +2 -0
- data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.builder +1 -0
- data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
- data/test/fixtures/test/greeting.erb +1 -0
- data/test/fixtures/test/greeting.js.rjs +1 -0
- data/test/fixtures/test/hello.builder +4 -0
- data/test/fixtures/test/hello_world.erb +1 -0
- data/test/fixtures/test/hello_world_container.builder +3 -0
- data/test/fixtures/test/hello_world_from_rxml.builder +4 -0
- data/test/fixtures/test/hello_world_with_layout_false.erb +1 -0
- data/test/fixtures/test/hello_xml_world.builder +11 -0
- data/test/fixtures/test/list.erb +1 -0
- data/test/fixtures/test/non_erb_block_content_for.builder +4 -0
- data/test/fixtures/test/potential_conflicts.erb +4 -0
- data/test/fixtures/test/render_file_from_template.html.erb +1 -0
- data/test/fixtures/test/render_file_with_ivar.erb +1 -0
- data/test/fixtures/test/render_file_with_locals.erb +1 -0
- data/test/fixtures/test/render_to_string_test.erb +1 -0
- data/test/fixtures/test/update_element_with_capture.erb +9 -0
- data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
- data/test/fixtures/topic.rb +3 -0
- data/test/fixtures/topics.yml +22 -0
- data/test/fixtures/topics/_topic.html.erb +1 -0
- data/test/template/active_record_helper_test.rb +268 -0
- data/test/template/asset_tag_helper_test.rb +514 -0
- data/test/template/atom_feed_helper_test.rb +179 -0
- data/test/template/benchmark_helper_test.rb +60 -0
- data/test/template/date_helper_test.rb +1791 -0
- data/test/template/deprecated_erb_variable_test.rb +9 -0
- data/test/template/erb_util_test.rb +24 -0
- data/test/template/form_helper_test.rb +885 -0
- data/test/template/form_options_helper_test.rb +1333 -0
- data/test/template/form_tag_helper_test.rb +272 -0
- data/test/template/javascript_helper_test.rb +73 -0
- data/test/template/number_helper_test.rb +97 -0
- data/test/template/record_tag_helper_test.rb +54 -0
- data/test/template/sanitize_helper_test.rb +48 -0
- data/test/template/tag_helper_test.rb +77 -0
- data/test/template/template_finder_test.rb +73 -0
- data/test/template/template_object_test.rb +95 -0
- data/test/template/test_test.rb +56 -0
- data/test/template/text_helper_test.rb +367 -0
- data/test/template/url_helper_test.rb +544 -0
- data/test/testing_sandbox.rb +15 -0
- metadata +469 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require 'abstract_unit'
|
|
2
|
+
|
|
3
|
+
class NodeTest < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
class MockNode
|
|
6
|
+
def initialize(matched, value)
|
|
7
|
+
@matched = matched
|
|
8
|
+
@value = value
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def find(conditions)
|
|
12
|
+
@matched && self
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_s
|
|
16
|
+
@value.to_s
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def setup
|
|
21
|
+
@node = HTML::Node.new("parent")
|
|
22
|
+
@node.children.concat [MockNode.new(false,1), MockNode.new(true,"two"), MockNode.new(false,:three)]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def test_match
|
|
26
|
+
assert !@node.match("foo")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_tag
|
|
30
|
+
assert !@node.tag?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_to_s
|
|
34
|
+
assert_equal "1twothree", @node.to_s
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_find
|
|
38
|
+
assert_equal "two", @node.find('blah').to_s
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_parse_strict
|
|
42
|
+
s = "<b foo='hello'' bar='baz'>"
|
|
43
|
+
assert_raise(RuntimeError) { HTML::Node.parse(nil,0,0,s) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_parse_relaxed
|
|
47
|
+
s = "<b foo='hello'' bar='baz'>"
|
|
48
|
+
node = nil
|
|
49
|
+
assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
|
|
50
|
+
assert node.attributes.has_key?("foo")
|
|
51
|
+
assert !node.attributes.has_key?("bar")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_to_s_with_boolean_attrs
|
|
55
|
+
s = "<b foo bar>"
|
|
56
|
+
node = HTML::Node.parse(nil,0,0,s)
|
|
57
|
+
assert node.attributes.has_key?("foo")
|
|
58
|
+
assert node.attributes.has_key?("bar")
|
|
59
|
+
assert "<b foo bar>", node.to_s
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def test_parse_with_unclosed_tag
|
|
63
|
+
s = "<span onmouseover='bang'"
|
|
64
|
+
node = nil
|
|
65
|
+
assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
|
|
66
|
+
assert node.attributes.has_key?("onmouseover")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_parse_with_valid_cdata_section
|
|
70
|
+
s = "<![CDATA[<span>contents</span>]]>"
|
|
71
|
+
node = nil
|
|
72
|
+
assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
|
|
73
|
+
assert_kind_of HTML::CDATA, node
|
|
74
|
+
assert_equal '<span>contents</span>', node.content
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_parse_strict_with_unterminated_cdata_section
|
|
78
|
+
s = "<![CDATA[neverending..."
|
|
79
|
+
assert_raise(RuntimeError) { HTML::Node.parse(nil,0,0,s) }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test_parse_relaxed_with_unterminated_cdata_section
|
|
83
|
+
s = "<![CDATA[neverending..."
|
|
84
|
+
node = nil
|
|
85
|
+
assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
|
|
86
|
+
assert_kind_of HTML::CDATA, node
|
|
87
|
+
assert_equal 'neverending...', node.content
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
require 'abstract_unit'
|
|
2
|
+
|
|
3
|
+
class SanitizerTest < Test::Unit::TestCase
|
|
4
|
+
def setup
|
|
5
|
+
@sanitizer = nil # used by assert_sanitizer
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def test_strip_tags
|
|
9
|
+
sanitizer = HTML::FullSanitizer.new
|
|
10
|
+
assert_equal("<<<bad html", sanitizer.sanitize("<<<bad html"))
|
|
11
|
+
assert_equal("<<", sanitizer.sanitize("<<<bad html>"))
|
|
12
|
+
assert_equal("Dont touch me", sanitizer.sanitize("Dont touch me"))
|
|
13
|
+
assert_equal("This is a test.", sanitizer.sanitize("<p>This <u>is<u> a <a href='test.html'><strong>test</strong></a>.</p>"))
|
|
14
|
+
assert_equal("Weirdos", sanitizer.sanitize("Wei<<a>a onclick='alert(document.cookie);'</a>/>rdos"))
|
|
15
|
+
assert_equal("This is a test.", sanitizer.sanitize("This is a test."))
|
|
16
|
+
assert_equal(
|
|
17
|
+
%{This is a test.\n\n\nIt no longer contains any HTML.\n}, sanitizer.sanitize(
|
|
18
|
+
%{<title>This is <b>a <a href="" target="_blank">test</a></b>.</title>\n\n<!-- it has a comment -->\n\n<p>It no <b>longer <strong>contains <em>any <strike>HTML</strike></em>.</strong></b></p>\n}))
|
|
19
|
+
assert_equal "This has a here.", sanitizer.sanitize("This has a <!-- comment --> here.")
|
|
20
|
+
assert_equal "This has a here.", sanitizer.sanitize("This has a <![CDATA[<section>]]> here.")
|
|
21
|
+
assert_equal "This has an unclosed ", sanitizer.sanitize("This has an unclosed <![CDATA[<section>]] here...")
|
|
22
|
+
[nil, '', ' '].each { |blank| assert_equal blank, sanitizer.sanitize(blank) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def test_strip_links
|
|
26
|
+
sanitizer = HTML::LinkSanitizer.new
|
|
27
|
+
assert_equal "Dont touch me", sanitizer.sanitize("Dont touch me")
|
|
28
|
+
assert_equal "on my mind\nall day long", sanitizer.sanitize("<a href='almost'>on my mind</a>\n<A href='almost'>all day long</A>")
|
|
29
|
+
assert_equal "0wn3d", sanitizer.sanitize("<a href='http://www.rubyonrails.com/'><a href='http://www.rubyonrails.com/' onlclick='steal()'>0wn3d</a></a>")
|
|
30
|
+
assert_equal "Magic", sanitizer.sanitize("<a href='http://www.rubyonrails.com/'>Mag<a href='http://www.ruby-lang.org/'>ic")
|
|
31
|
+
assert_equal "FrrFox", sanitizer.sanitize("<href onlclick='steal()'>FrrFox</a></href>")
|
|
32
|
+
assert_equal "My mind\nall <b>day</b> long", sanitizer.sanitize("<a href='almost'>My mind</a>\n<A href='almost'>all <b>day</b> long</A>")
|
|
33
|
+
assert_equal "all <b>day</b> long", sanitizer.sanitize("<<a>a href='hello'>all <b>day</b> long<</A>/a>")
|
|
34
|
+
|
|
35
|
+
assert_equal "<a<a", sanitizer.sanitize("<a<a")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_sanitize_form
|
|
39
|
+
assert_sanitized "<form action=\"/foo/bar\" method=\"post\"><input></form>", ''
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_sanitize_plaintext
|
|
43
|
+
raw = "<plaintext><span>foo</span></plaintext>"
|
|
44
|
+
assert_sanitized raw, "<span>foo</span>"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_sanitize_script
|
|
48
|
+
assert_sanitized "a b c<script language=\"Javascript\">blah blah blah</script>d e f", "a b cd e f"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# fucked
|
|
52
|
+
def test_sanitize_js_handlers
|
|
53
|
+
raw = %{onthis="do that" <a href="#" onclick="hello" name="foo" onbogus="remove me">hello</a>}
|
|
54
|
+
assert_sanitized raw, %{onthis="do that" <a name="foo" href="#">hello</a>}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_sanitize_javascript_href
|
|
58
|
+
raw = %{href="javascript:bang" <a href="javascript:bang" name="hello">foo</a>, <span href="javascript:bang">bar</span>}
|
|
59
|
+
assert_sanitized raw, %{href="javascript:bang" <a name="hello">foo</a>, <span>bar</span>}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def test_sanitize_image_src
|
|
63
|
+
raw = %{src="javascript:bang" <img src="javascript:bang" width="5">foo</img>, <span src="javascript:bang">bar</span>}
|
|
64
|
+
assert_sanitized raw, %{src="javascript:bang" <img width="5">foo</img>, <span>bar</span>}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
HTML::WhiteListSanitizer.allowed_tags.each do |tag_name|
|
|
68
|
+
define_method "test_should_allow_#{tag_name}_tag" do
|
|
69
|
+
assert_sanitized "start <#{tag_name} title=\"1\" onclick=\"foo\">foo <bad>bar</bad> baz</#{tag_name}> end", %(start <#{tag_name} title="1">foo bar baz</#{tag_name}> end)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def test_should_allow_anchors
|
|
74
|
+
assert_sanitized %(<a href="foo" onclick="bar"><script>baz</script></a>), %(<a href="foo"></a>)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# RFC 3986, sec 4.2
|
|
78
|
+
def test_allow_colons_in_path_component
|
|
79
|
+
assert_sanitized("<a href=\"./this:that\">foo</a>")
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
%w(src width height alt).each do |img_attr|
|
|
83
|
+
define_method "test_should_allow_image_#{img_attr}_attribute" do
|
|
84
|
+
assert_sanitized %(<img #{img_attr}="foo" onclick="bar" />), %(<img #{img_attr}="foo" />)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def test_should_handle_non_html
|
|
89
|
+
assert_sanitized 'abc'
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def test_should_handle_blank_text
|
|
93
|
+
assert_sanitized nil
|
|
94
|
+
assert_sanitized ''
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def test_should_allow_custom_tags
|
|
98
|
+
text = "<u>foo</u>"
|
|
99
|
+
sanitizer = HTML::WhiteListSanitizer.new
|
|
100
|
+
assert_equal(text, sanitizer.sanitize(text, :tags => %w(u)))
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_should_allow_only_custom_tags
|
|
104
|
+
text = "<u>foo</u> with <i>bar</i>"
|
|
105
|
+
sanitizer = HTML::WhiteListSanitizer.new
|
|
106
|
+
assert_equal("<u>foo</u> with bar", sanitizer.sanitize(text, :tags => %w(u)))
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_should_allow_custom_tags_with_attributes
|
|
110
|
+
text = %(<blockquote cite="http://example.com/">foo</blockquote>)
|
|
111
|
+
sanitizer = HTML::WhiteListSanitizer.new
|
|
112
|
+
assert_equal(text, sanitizer.sanitize(text))
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def test_should_allow_custom_tags_with_custom_attributes
|
|
116
|
+
text = %(<blockquote foo="bar">Lorem ipsum</blockquote>)
|
|
117
|
+
sanitizer = HTML::WhiteListSanitizer.new
|
|
118
|
+
assert_equal(text, sanitizer.sanitize(text, :attributes => ['foo']))
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
[%w(img src), %w(a href)].each do |(tag, attr)|
|
|
122
|
+
define_method "test_should_strip_#{attr}_attribute_in_#{tag}_with_bad_protocols" do
|
|
123
|
+
assert_sanitized %(<#{tag} #{attr}="javascript:bang" title="1">boo</#{tag}>), %(<#{tag} title="1">boo</#{tag}>)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_should_flag_bad_protocols
|
|
128
|
+
sanitizer = HTML::WhiteListSanitizer.new
|
|
129
|
+
%w(about chrome data disk hcp help javascript livescript lynxcgi lynxexec ms-help ms-its mhtml mocha opera res resource shell vbscript view-source vnd.ms.radio wysiwyg).each do |proto|
|
|
130
|
+
assert sanitizer.send(:contains_bad_protocols?, 'src', "#{proto}://bad")
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def test_should_accept_good_protocols
|
|
135
|
+
sanitizer = HTML::WhiteListSanitizer.new
|
|
136
|
+
HTML::WhiteListSanitizer.allowed_protocols.each do |proto|
|
|
137
|
+
assert !sanitizer.send(:contains_bad_protocols?, 'src', "#{proto}://good")
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def test_should_reject_hex_codes_in_protocol
|
|
142
|
+
assert_sanitized %(<a href="%6A%61%76%61%73%63%72%69%70%74%3A%61%6C%65%72%74%28%22%58%53%53%22%29">1</a>), "<a>1</a>"
|
|
143
|
+
assert @sanitizer.send(:contains_bad_protocols?, 'src', "%6A%61%76%61%73%63%72%69%70%74%3A%61%6C%65%72%74%28%22%58%53%53%22%29")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def test_should_block_script_tag
|
|
147
|
+
assert_sanitized %(<SCRIPT\nSRC=http://ha.ckers.org/xss.js></SCRIPT>), ""
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
[%(<IMG SRC="javascript:alert('XSS');">),
|
|
151
|
+
%(<IMG SRC=javascript:alert('XSS')>),
|
|
152
|
+
%(<IMG SRC=JaVaScRiPt:alert('XSS')>),
|
|
153
|
+
%(<IMG """><SCRIPT>alert("XSS")</SCRIPT>">),
|
|
154
|
+
%(<IMG SRC=javascript:alert("XSS")>),
|
|
155
|
+
%(<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>),
|
|
156
|
+
%(<IMG SRC=javascript:alert('XSS')>),
|
|
157
|
+
%(<IMG SRC=javascript:alert('XSS')>),
|
|
158
|
+
%(<IMG SRC=javascript:alert('XSS')>),
|
|
159
|
+
%(<IMG SRC="jav\tascript:alert('XSS');">),
|
|
160
|
+
%(<IMG SRC="jav	ascript:alert('XSS');">),
|
|
161
|
+
%(<IMG SRC="jav
ascript:alert('XSS');">),
|
|
162
|
+
%(<IMG SRC="jav
ascript:alert('XSS');">),
|
|
163
|
+
%(<IMG SRC="  javascript:alert('XSS');">),
|
|
164
|
+
%(<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>)].each_with_index do |img_hack, i|
|
|
165
|
+
define_method "test_should_not_fall_for_xss_image_hack_#{i+1}" do
|
|
166
|
+
assert_sanitized img_hack, "<img>"
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def test_should_sanitize_tag_broken_up_by_null
|
|
171
|
+
assert_sanitized %(<SCR\0IPT>alert(\"XSS\")</SCR\0IPT>), "alert(\"XSS\")"
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def test_should_sanitize_invalid_script_tag
|
|
175
|
+
assert_sanitized %(<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>), ""
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def test_should_sanitize_script_tag_with_multiple_open_brackets
|
|
179
|
+
assert_sanitized %(<<SCRIPT>alert("XSS");//<</SCRIPT>), "<"
|
|
180
|
+
assert_sanitized %(<iframe src=http://ha.ckers.org/scriptlet.html\n<a), %(<a)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def test_should_sanitize_unclosed_script
|
|
184
|
+
assert_sanitized %(<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>), "<b>"
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def test_should_sanitize_half_open_scripts
|
|
188
|
+
assert_sanitized %(<IMG SRC="javascript:alert('XSS')"), "<img>"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def test_should_not_fall_for_ridiculous_hack
|
|
192
|
+
img_hack = %(<IMG\nSRC\n=\n"\nj\na\nv\na\ns\nc\nr\ni\np\nt\n:\na\nl\ne\nr\nt\n(\n'\nX\nS\nS\n'\n)\n"\n>)
|
|
193
|
+
assert_sanitized img_hack, "<img>"
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# fucked
|
|
197
|
+
def test_should_sanitize_attributes
|
|
198
|
+
assert_sanitized %(<SPAN title="'><script>alert()</script>">blah</SPAN>), %(<span title="'><script>alert()</script>">blah</span>)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def test_should_sanitize_illegal_style_properties
|
|
202
|
+
raw = %(display:block; position:absolute; left:0; top:0; width:100%; height:100%; z-index:1; background-color:black; background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg); background-x:center; background-y:center; background-repeat:repeat;)
|
|
203
|
+
expected = %(display: block; width: 100%; height: 100%; background-color: black; background-image: ; background-x: center; background-y: center;)
|
|
204
|
+
assert_equal expected, sanitize_css(raw)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def test_should_sanitize_with_trailing_space
|
|
208
|
+
raw = "display:block; "
|
|
209
|
+
expected = "display: block;"
|
|
210
|
+
assert_equal expected, sanitize_css(raw)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def test_should_sanitize_xul_style_attributes
|
|
214
|
+
raw = %(-moz-binding:url('http://ha.ckers.org/xssmoz.xml#xss'))
|
|
215
|
+
assert_equal '', sanitize_css(raw)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def test_should_sanitize_invalid_tag_names
|
|
219
|
+
assert_sanitized(%(a b c<script/XSS src="http://ha.ckers.org/xss.js"></script>d e f), "a b cd e f")
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def test_should_sanitize_non_alpha_and_non_digit_characters_in_tags
|
|
223
|
+
assert_sanitized('<a onclick!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>foo</a>', "<a>foo</a>")
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def test_should_sanitize_invalid_tag_names_in_single_tags
|
|
227
|
+
assert_sanitized('<img/src="http://ha.ckers.org/xss.js"/>', "<img />")
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def test_should_sanitize_img_dynsrc_lowsrc
|
|
231
|
+
assert_sanitized(%(<img lowsrc="javascript:alert('XSS')" />), "<img />")
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def test_should_sanitize_div_background_image_unicode_encoded
|
|
235
|
+
raw = %(background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029)
|
|
236
|
+
assert_equal '', sanitize_css(raw)
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def test_should_sanitize_div_style_expression
|
|
240
|
+
raw = %(width: expression(alert('XSS'));)
|
|
241
|
+
assert_equal '', sanitize_css(raw)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def test_should_sanitize_img_vbscript
|
|
245
|
+
assert_sanitized %(<img src='vbscript:msgbox("XSS")' />), '<img />'
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def test_should_sanitize_cdata_section
|
|
249
|
+
assert_sanitized "<![CDATA[<span>section</span>]]>", "<![CDATA[<span>section</span>]]>"
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def test_should_sanitize_unterminated_cdata_section
|
|
253
|
+
assert_sanitized "<![CDATA[<span>neverending...", "<![CDATA[<span>neverending...]]>"
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
protected
|
|
257
|
+
def assert_sanitized(input, expected = nil)
|
|
258
|
+
@sanitizer ||= HTML::WhiteListSanitizer.new
|
|
259
|
+
if input
|
|
260
|
+
assert_dom_equal expected || input, @sanitizer.sanitize(input)
|
|
261
|
+
else
|
|
262
|
+
assert_nil @sanitizer.sanitize(input)
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def sanitize_css(input)
|
|
267
|
+
(@sanitizer ||= HTML::WhiteListSanitizer.new).sanitize_css(input)
|
|
268
|
+
end
|
|
269
|
+
end
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
require 'abstract_unit'
|
|
2
|
+
|
|
3
|
+
class TagNodeTest < Test::Unit::TestCase
|
|
4
|
+
def test_open_without_attributes
|
|
5
|
+
node = tag("<tag>")
|
|
6
|
+
assert_equal "tag", node.name
|
|
7
|
+
assert_equal Hash.new, node.attributes
|
|
8
|
+
assert_nil node.closing
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_open_with_attributes
|
|
12
|
+
node = tag("<TAG1 foo=hey_ho x:bar=\"blah blah\" BAZ='blah blah blah' >")
|
|
13
|
+
assert_equal "tag1", node.name
|
|
14
|
+
assert_equal "hey_ho", node["foo"]
|
|
15
|
+
assert_equal "blah blah", node["x:bar"]
|
|
16
|
+
assert_equal "blah blah blah", node["baz"]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_self_closing_without_attributes
|
|
20
|
+
node = tag("<tag/>")
|
|
21
|
+
assert_equal "tag", node.name
|
|
22
|
+
assert_equal Hash.new, node.attributes
|
|
23
|
+
assert_equal :self, node.closing
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_self_closing_with_attributes
|
|
27
|
+
node = tag("<tag a=b/>")
|
|
28
|
+
assert_equal "tag", node.name
|
|
29
|
+
assert_equal( { "a" => "b" }, node.attributes )
|
|
30
|
+
assert_equal :self, node.closing
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_closing_without_attributes
|
|
34
|
+
node = tag("</tag>")
|
|
35
|
+
assert_equal "tag", node.name
|
|
36
|
+
assert_nil node.attributes
|
|
37
|
+
assert_equal :close, node.closing
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_bracket_op_when_no_attributes
|
|
41
|
+
node = tag("</tag>")
|
|
42
|
+
assert_nil node["foo"]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_bracket_op_when_attributes
|
|
46
|
+
node = tag("<tag a=b/>")
|
|
47
|
+
assert_equal "b", node["a"]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_attributes_with_escaped_quotes
|
|
51
|
+
node = tag("<tag a='b\\'c' b=\"bob \\\"float\\\"\">")
|
|
52
|
+
assert_equal "b\\'c", node["a"]
|
|
53
|
+
assert_equal "bob \\\"float\\\"", node["b"]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_to_s
|
|
57
|
+
node = tag("<a b=c d='f' g=\"h 'i'\" />")
|
|
58
|
+
assert_equal %(<a b='c' d='f' g='h \\'i\\'' />), node.to_s
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_tag
|
|
62
|
+
assert tag("<tag>").tag?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_match_tag_as_string
|
|
66
|
+
assert tag("<tag>").match(:tag => "tag")
|
|
67
|
+
assert !tag("<tag>").match(:tag => "b")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_match_tag_as_regexp
|
|
71
|
+
assert tag("<tag>").match(:tag => /t.g/)
|
|
72
|
+
assert !tag("<tag>").match(:tag => /t[bqs]g/)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def test_match_attributes_as_string
|
|
76
|
+
t = tag("<tag a=something b=else />")
|
|
77
|
+
assert t.match(:attributes => {"a" => "something"})
|
|
78
|
+
assert t.match(:attributes => {"b" => "else"})
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_match_attributes_as_regexp
|
|
82
|
+
t = tag("<tag a=something b=else />")
|
|
83
|
+
assert t.match(:attributes => {"a" => /^something$/})
|
|
84
|
+
assert t.match(:attributes => {"b" => /e.*e/})
|
|
85
|
+
assert t.match(:attributes => {"a" => /me..i/, "b" => /.ls.$/})
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def test_match_attributes_as_number
|
|
89
|
+
t = tag("<tag a=15 b=3.1415 />")
|
|
90
|
+
assert t.match(:attributes => {"a" => 15})
|
|
91
|
+
assert t.match(:attributes => {"b" => 3.1415})
|
|
92
|
+
assert t.match(:attributes => {"a" => 15, "b" => 3.1415})
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def test_match_attributes_exist
|
|
96
|
+
t = tag("<tag a=15 b=3.1415 />")
|
|
97
|
+
assert t.match(:attributes => {"a" => true})
|
|
98
|
+
assert t.match(:attributes => {"b" => true})
|
|
99
|
+
assert t.match(:attributes => {"a" => true, "b" => true})
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def test_match_attributes_not_exist
|
|
103
|
+
t = tag("<tag a=15 b=3.1415 />")
|
|
104
|
+
assert t.match(:attributes => {"c" => false})
|
|
105
|
+
assert t.match(:attributes => {"c" => nil})
|
|
106
|
+
assert t.match(:attributes => {"a" => true, "c" => false})
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_match_parent_success
|
|
110
|
+
t = tag("<tag a=15 b='hello'>", tag("<foo k='value'>"))
|
|
111
|
+
assert t.match(:parent => {:tag => "foo", :attributes => {"k" => /v.l/, "j" => false}})
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_match_parent_fail
|
|
115
|
+
t = tag("<tag a=15 b='hello'>", tag("<foo k='value'>"))
|
|
116
|
+
assert !t.match(:parent => {:tag => /kafka/})
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def test_match_child_success
|
|
120
|
+
t = tag("<tag x:k='something'>")
|
|
121
|
+
tag("<child v=john a=kelly>", t)
|
|
122
|
+
tag("<sib m=vaughn v=james>", t)
|
|
123
|
+
assert t.match(:child => { :tag => "sib", :attributes => {"v" => /j/}})
|
|
124
|
+
assert t.match(:child => { :attributes => {"a" => "kelly"}})
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_match_child_fail
|
|
128
|
+
t = tag("<tag x:k='something'>")
|
|
129
|
+
tag("<child v=john a=kelly>", t)
|
|
130
|
+
tag("<sib m=vaughn v=james>", t)
|
|
131
|
+
assert !t.match(:child => { :tag => "sib", :attributes => {"v" => /r/}})
|
|
132
|
+
assert !t.match(:child => { :attributes => {"v" => false}})
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def test_match_ancestor_success
|
|
136
|
+
t = tag("<tag x:k='something'>", tag("<parent v=john a=kelly>", tag("<grandparent m=vaughn v=james>")))
|
|
137
|
+
assert t.match(:ancestor => {:tag => "parent", :attributes => {"a" => /ll/}})
|
|
138
|
+
assert t.match(:ancestor => {:attributes => {"m" => "vaughn"}})
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def test_match_ancestor_fail
|
|
142
|
+
t = tag("<tag x:k='something'>", tag("<parent v=john a=kelly>", tag("<grandparent m=vaughn v=james>")))
|
|
143
|
+
assert !t.match(:ancestor => {:tag => /^parent/, :attributes => {"v" => /m/}})
|
|
144
|
+
assert !t.match(:ancestor => {:attributes => {"v" => false}})
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def test_match_descendant_success
|
|
148
|
+
tag("<grandchild m=vaughn v=james>", tag("<child v=john a=kelly>", t = tag("<tag x:k='something'>")))
|
|
149
|
+
assert t.match(:descendant => {:tag => "child", :attributes => {"a" => /ll/}})
|
|
150
|
+
assert t.match(:descendant => {:attributes => {"m" => "vaughn"}})
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def test_match_descendant_fail
|
|
154
|
+
tag("<grandchild m=vaughn v=james>", tag("<child v=john a=kelly>", t = tag("<tag x:k='something'>")))
|
|
155
|
+
assert !t.match(:descendant => {:tag => /^child/, :attributes => {"v" => /m/}})
|
|
156
|
+
assert !t.match(:descendant => {:attributes => {"v" => false}})
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def test_match_child_count
|
|
160
|
+
t = tag("<tag x:k='something'>")
|
|
161
|
+
tag("hello", t)
|
|
162
|
+
tag("<child v=john a=kelly>", t)
|
|
163
|
+
tag("<sib m=vaughn v=james>", t)
|
|
164
|
+
assert t.match(:children => { :count => 2 })
|
|
165
|
+
assert t.match(:children => { :count => 2..4 })
|
|
166
|
+
assert t.match(:children => { :less_than => 4 })
|
|
167
|
+
assert t.match(:children => { :greater_than => 1 })
|
|
168
|
+
assert !t.match(:children => { :count => 3 })
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def test_conditions_as_strings
|
|
172
|
+
t = tag("<tag x:k='something'>")
|
|
173
|
+
assert t.match("tag" => "tag")
|
|
174
|
+
assert t.match("attributes" => { "x:k" => "something" })
|
|
175
|
+
assert !t.match("tag" => "gat")
|
|
176
|
+
assert !t.match("attributes" => { "x:j" => "something" })
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def test_attributes_as_symbols
|
|
180
|
+
t = tag("<child v=john a=kelly>")
|
|
181
|
+
assert t.match(:attributes => { :v => /oh/ })
|
|
182
|
+
assert t.match(:attributes => { :a => /ll/ })
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def test_match_sibling
|
|
186
|
+
t = tag("<tag x:k='something'>")
|
|
187
|
+
tag("hello", t)
|
|
188
|
+
tag("<span a=b>", t)
|
|
189
|
+
tag("world", t)
|
|
190
|
+
m = tag("<span k=r>", t)
|
|
191
|
+
tag("<span m=l>", t)
|
|
192
|
+
|
|
193
|
+
assert m.match(:sibling => {:tag => "span", :attributes => {:a => true}})
|
|
194
|
+
assert m.match(:sibling => {:tag => "span", :attributes => {:m => true}})
|
|
195
|
+
assert !m.match(:sibling => {:tag => "span", :attributes => {:k => true}})
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def test_match_sibling_before
|
|
199
|
+
t = tag("<tag x:k='something'>")
|
|
200
|
+
tag("hello", t)
|
|
201
|
+
tag("<span a=b>", t)
|
|
202
|
+
tag("world", t)
|
|
203
|
+
m = tag("<span k=r>", t)
|
|
204
|
+
tag("<span m=l>", t)
|
|
205
|
+
|
|
206
|
+
assert m.match(:before => {:tag => "span", :attributes => {:m => true}})
|
|
207
|
+
assert !m.match(:before => {:tag => "span", :attributes => {:a => true}})
|
|
208
|
+
assert !m.match(:before => {:tag => "span", :attributes => {:k => true}})
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def test_match_sibling_after
|
|
212
|
+
t = tag("<tag x:k='something'>")
|
|
213
|
+
tag("hello", t)
|
|
214
|
+
tag("<span a=b>", t)
|
|
215
|
+
tag("world", t)
|
|
216
|
+
m = tag("<span k=r>", t)
|
|
217
|
+
tag("<span m=l>", t)
|
|
218
|
+
|
|
219
|
+
assert m.match(:after => {:tag => "span", :attributes => {:a => true}})
|
|
220
|
+
assert !m.match(:after => {:tag => "span", :attributes => {:m => true}})
|
|
221
|
+
assert !m.match(:after => {:tag => "span", :attributes => {:k => true}})
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def test_to_s
|
|
225
|
+
t = tag("<b x='foo'>")
|
|
226
|
+
tag("hello", t)
|
|
227
|
+
tag("<hr />", t)
|
|
228
|
+
assert_equal %(<b x="foo">hello<hr /></b>), t.to_s
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
private
|
|
232
|
+
|
|
233
|
+
def tag(content, parent=nil)
|
|
234
|
+
node = HTML::Node.parse(parent,0,0,content)
|
|
235
|
+
parent.children << node if parent
|
|
236
|
+
node
|
|
237
|
+
end
|
|
238
|
+
end
|