allegro_api_client 0.0.1
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.
- checksums.yaml +7 -0
- data/.bundle/config +3 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +25 -0
- data/README.md +19 -0
- data/apiclient.gemspec +24 -0
- data/gems/ruby/2.1.0/bin/httparty +23 -0
- data/gems/ruby/2.1.0/bin/rake +23 -0
- data/gems/ruby/2.1.0/build_info/git_repository-0.0.11.info +1 -0
- data/gems/ruby/2.1.0/build_info/httparty-0.13.1.info +1 -0
- data/gems/ruby/2.1.0/build_info/multi_xml-0.5.5.info +1 -0
- data/gems/ruby/2.1.0/build_info/rake-10.3.2.info +1 -0
- data/gems/ruby/2.1.0/cache/git_repository-0.0.11.gem +0 -0
- data/gems/ruby/2.1.0/cache/httparty-0.13.1.gem +0 -0
- data/gems/ruby/2.1.0/cache/multi_xml-0.5.5.gem +0 -0
- data/gems/ruby/2.1.0/cache/rake-10.3.2.gem +0 -0
- data/gems/ruby/2.1.0/gems/git_repository-0.0.11/lib/git_repository.rb +62 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/.gitignore +10 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/.travis.yml +7 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/Gemfile +14 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/Guardfile +16 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/History +303 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/MIT-LICENSE +20 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/README.md +74 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/Rakefile +12 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/bin/httparty +117 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/cucumber.yml +1 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/aaws.rb +32 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/basic.rb +28 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/crack.rb +19 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/custom_parsers.rb +67 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/delicious.rb +37 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/google.rb +16 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/headers_and_user_agents.rb +6 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/nokogiri_html_parser.rb +22 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/rubyurl.rb +14 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/stackexchange.rb +24 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/tripit_sign_in.rb +33 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/twitter.rb +31 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/examples/whoismyrep.rb +10 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/basic_authentication.feature +20 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/command_line.feature +7 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/deals_with_http_error_codes.feature +26 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/digest_authentication.feature +20 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/handles_compressed_responses.feature +27 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/handles_multiple_formats.feature +57 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/steps/env.rb +22 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/steps/httparty_response_steps.rb +52 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/steps/httparty_steps.rb +43 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/steps/mongrel_helper.rb +94 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/steps/remote_service_steps.rb +74 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/supports_read_timeout_option.feature +13 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/supports_redirection.feature +22 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/features/supports_timeout_option.feature +13 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/httparty.gemspec +26 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty.rb +600 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/connection_adapter.rb +187 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/cookie_hash.rb +22 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/core_extensions.rb +32 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/exceptions.rb +29 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/hash_conversions.rb +51 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/logger/apache_logger.rb +22 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/logger/curl_logger.rb +48 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/logger/logger.rb +18 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/module_inheritable_attributes.rb +56 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/net_digest_auth.rb +84 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/parser.rb +141 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/request.rb +331 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/response.rb +72 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/response/headers.rb +31 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/lib/httparty/version.rb +3 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/script/release +42 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/delicious.xml +23 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/empty.xml +0 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/google.html +3 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/ssl/generate.sh +29 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/ssl/generated/1fe462c2.0 +16 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/ssl/generated/bogushost.crt +13 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/ssl/generated/ca.crt +16 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/ssl/generated/ca.key +15 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/ssl/generated/selfsigned.crt +14 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/ssl/generated/server.crt +13 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/ssl/generated/server.key +15 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/ssl/openssl-exts.cnf +9 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/twitter.csv +2 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/twitter.json +1 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/twitter.xml +403 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/httparty/connection_adapter_spec.rb +354 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/httparty/cookie_hash_spec.rb +83 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/httparty/exception_spec.rb +23 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/httparty/logger/apache_logger_spec.rb +26 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/httparty/logger/curl_logger_spec.rb +18 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/httparty/logger/logger_spec.rb +22 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/httparty/net_digest_auth_spec.rb +152 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/httparty/parser_spec.rb +165 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/httparty/request_spec.rb +638 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/httparty/response_spec.rb +221 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/httparty/ssl_spec.rb +74 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/httparty_spec.rb +764 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/spec.opts +2 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/spec_helper.rb +37 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/support/ssl_test_helper.rb +47 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/support/ssl_test_server.rb +80 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/spec/support/stub_response.rb +43 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/website/css/common.css +47 -0
- data/gems/ruby/2.1.0/gems/httparty-0.13.1/website/index.html +73 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/.yardopts +8 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/CHANGELOG.md +93 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/CONTRIBUTING.md +49 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/LICENSE.md +20 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/README.md +97 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/Rakefile +21 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/lib/multi_xml.rb +296 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/lib/multi_xml/parsers/libxml.rb +30 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/lib/multi_xml/parsers/libxml2_parser.rb +74 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/lib/multi_xml/parsers/nokogiri.rb +32 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/lib/multi_xml/parsers/ox.rb +97 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/lib/multi_xml/parsers/rexml.rb +113 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/lib/multi_xml/version.rb +3 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/multi_xml.gemspec +24 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/spec/helper.rb +17 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/spec/multi_xml_spec.rb +43 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/spec/parser_shared_example.rb +694 -0
- data/gems/ruby/2.1.0/gems/multi_xml-0.5.5/spec/speed.rb +63 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/.autotest +7 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/.gemtest +0 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/.rubocop.yml +27 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/.togglerc +7 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/CONTRIBUTING.rdoc +34 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/History.rdoc +609 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/MIT-LICENSE +21 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/Manifest.txt +162 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/README.rdoc +137 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/Rakefile +81 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/bin/rake +33 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/command_line_usage.rdoc +158 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/example/Rakefile1 +38 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/example/Rakefile2 +35 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/example/a.c +6 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/example/b.c +6 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/example/main.c +11 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/glossary.rdoc +43 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/jamis.rb +591 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/proto_rake.rdoc +127 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/rake.1.gz +0 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/rakefile.rdoc +653 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/rational.rdoc +151 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.4.14.rdoc +23 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.4.15.rdoc +35 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.5.0.rdoc +53 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.5.3.rdoc +78 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.5.4.rdoc +46 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.6.0.rdoc +141 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.7.0.rdoc +119 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.7.1.rdoc +59 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.7.2.rdoc +121 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.7.3.rdoc +47 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.8.0.rdoc +114 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.8.2.rdoc +165 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.8.3.rdoc +112 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.8.4.rdoc +147 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.8.5.rdoc +53 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.8.6.rdoc +37 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.8.7.rdoc +55 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.9.0.rdoc +112 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.9.1.rdoc +52 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.9.2.2.rdoc +55 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.9.2.rdoc +49 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.9.3.rdoc +102 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.9.4.rdoc +60 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.9.5.rdoc +55 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-0.9.6.rdoc +64 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-10.0.0.rdoc +178 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-10.0.1.rdoc +58 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-10.0.2.rdoc +53 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-10.0.3.rdoc +191 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/doc/release_notes/rake-10.1.0.rdoc +61 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake.rb +78 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/alt_system.rb +110 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/application.rb +783 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/backtrace.rb +23 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/clean.rb +76 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/cloneable.rb +16 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/contrib/.document +0 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/contrib/compositepublisher.rb +21 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/contrib/ftptools.rb +137 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/contrib/publisher.rb +81 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/contrib/rubyforgepublisher.rb +18 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/contrib/sshpublisher.rb +61 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/contrib/sys.rb +4 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/cpu_counter.rb +109 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/default_loader.rb +14 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/dsl_definition.rb +198 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/early_time.rb +21 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/ext/core.rb +25 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/ext/module.rb +1 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/ext/string.rb +173 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/ext/time.rb +15 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/file_creation_task.rb +24 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/file_list.rb +414 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/file_task.rb +46 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/file_utils.rb +116 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/file_utils_ext.rb +144 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/gempackagetask.rb +4 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/invocation_chain.rb +56 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/invocation_exception_mixin.rb +16 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/linked_list.rb +103 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/loaders/makefile.rb +40 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/multi_task.rb +13 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/name_space.rb +38 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/packagetask.rb +202 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/pathmap.rb +3 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/phony.rb +15 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/private_reader.rb +20 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/promise.rb +99 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/pseudo_status.rb +29 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/rake_module.rb +38 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/rake_test_loader.rb +22 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/rdoctask.rb +4 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/ruby182_test_unit_fix.rb +29 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/rule_recursion_overflow_error.rb +20 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/runtest.rb +27 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/scope.rb +42 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/task.rb +383 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/task_argument_error.rb +7 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/task_arguments.rb +98 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/task_manager.rb +310 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/tasklib.rb +24 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/testtask.rb +212 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/thread_history_display.rb +48 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/thread_pool.rb +164 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/trace_output.rb +22 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/version.rb +7 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/lib/rake/win32.rb +56 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/rakelib/publish.rake +20 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/rakelib/test_times.rake +25 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/file_creation.rb +34 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/helper.rb +127 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/support/rakefile_definitions.rb +478 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/support/ruby_runner.rb +33 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_private_reader.rb +42 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake.rb +40 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_application.rb +641 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_application_options.rb +466 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_backtrace.rb +119 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_clean.rb +55 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_cpu_counter.rb +50 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_definitions.rb +79 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_directory_task.rb +63 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_dsl.rb +40 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_early_time.rb +31 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_extension.rb +59 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_file_creation_task.rb +56 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_file_list.rb +627 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_file_list_path_map.rb +8 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_file_task.rb +186 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_file_utils.rb +309 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_ftp_file.rb +74 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_functional.rb +482 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_invocation_chain.rb +64 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_linked_list.rb +84 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_makefile_loader.rb +46 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_multi_task.rb +58 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_name_space.rb +57 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_package_task.rb +79 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_path_map.rb +168 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_path_map_explode.rb +34 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_path_map_partial.rb +18 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_pseudo_status.rb +21 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_rake_test_loader.rb +20 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_reduce_compat.rb +26 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_require.rb +40 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_rules.rb +388 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_scope.rb +44 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_task.rb +392 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_task_argument_parsing.rb +109 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_task_arguments.rb +127 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_task_lib.rb +9 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_task_manager.rb +178 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_task_manager_argument_resolution.rb +19 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_task_with_arguments.rb +171 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_test_task.rb +141 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_thread_pool.rb +142 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_top_level_functions.rb +71 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_rake_win32.rb +72 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_thread_history_display.rb +101 -0
- data/gems/ruby/2.1.0/gems/rake-10.3.2/test/test_trace_output.rb +52 -0
- data/gems/ruby/2.1.0/specifications/git_repository-0.0.11.gemspec +16 -0
- data/gems/ruby/2.1.0/specifications/httparty-0.13.1.gemspec +36 -0
- data/gems/ruby/2.1.0/specifications/multi_xml-0.5.5.gemspec +31 -0
- data/gems/ruby/2.1.0/specifications/rake-10.3.2.gemspec +43 -0
- data/rakefile.rb +33 -0
- data/src/APIClient.rb +23 -0
- data/test/test_git_repository_commit.rb +19 -0
- metadata +395 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
module MultiXml
|
|
2
|
+
module Parsers
|
|
3
|
+
module Libxml2Parser #:nodoc:
|
|
4
|
+
# Convert XML document to hash
|
|
5
|
+
#
|
|
6
|
+
# node::
|
|
7
|
+
# The XML node object to convert to a hash.
|
|
8
|
+
#
|
|
9
|
+
# hash::
|
|
10
|
+
# Hash to merge the converted element into.
|
|
11
|
+
def node_to_hash(node, hash={})
|
|
12
|
+
node_hash = {MultiXml::CONTENT_ROOT => ''}
|
|
13
|
+
|
|
14
|
+
name = node_name(node)
|
|
15
|
+
|
|
16
|
+
# Insert node hash into parent hash correctly.
|
|
17
|
+
case hash[name]
|
|
18
|
+
when Array then hash[name] << node_hash
|
|
19
|
+
when Hash then hash[name] = [hash[name], node_hash]
|
|
20
|
+
when nil then hash[name] = node_hash
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Handle child elements
|
|
24
|
+
each_child(node) do |c|
|
|
25
|
+
if c.element?
|
|
26
|
+
node_to_hash(c, node_hash)
|
|
27
|
+
elsif c.text? || c.cdata?
|
|
28
|
+
node_hash[MultiXml::CONTENT_ROOT] << c.content
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Remove content node if it is empty
|
|
33
|
+
if node_hash[MultiXml::CONTENT_ROOT].strip.empty?
|
|
34
|
+
node_hash.delete(MultiXml::CONTENT_ROOT)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Handle attributes
|
|
38
|
+
each_attr(node) do |a|
|
|
39
|
+
key = node_name(a)
|
|
40
|
+
|
|
41
|
+
node_hash[key] = if v = node_hash[key]
|
|
42
|
+
[a.value, v]
|
|
43
|
+
else
|
|
44
|
+
a.value
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
hash
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Parse an XML Document IO into a simple hash.
|
|
52
|
+
# xml::
|
|
53
|
+
# XML Document IO to parse
|
|
54
|
+
def parse(xml)
|
|
55
|
+
raise NotImplementedError, "inheritor should define #{__method__}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# :stopdoc:
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def each_child(*args)
|
|
62
|
+
raise NotImplementedError, "inheritor should define #{__method__}"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def each_attr(*args)
|
|
66
|
+
raise NotImplementedError, "inheritor should define #{__method__}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def node_name(*args)
|
|
70
|
+
raise NotImplementedError, "inheritor should define #{__method__}"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'nokogiri' unless defined?(Nokogiri)
|
|
2
|
+
require 'multi_xml/parsers/libxml2_parser'
|
|
3
|
+
|
|
4
|
+
module MultiXml
|
|
5
|
+
module Parsers
|
|
6
|
+
module Nokogiri #:nodoc:
|
|
7
|
+
include Libxml2Parser
|
|
8
|
+
|
|
9
|
+
extend self
|
|
10
|
+
|
|
11
|
+
def parse_error() ::Nokogiri::XML::SyntaxError end
|
|
12
|
+
|
|
13
|
+
def parse(xml)
|
|
14
|
+
doc = ::Nokogiri::XML(xml)
|
|
15
|
+
raise doc.errors.first if doc.errors.length > 0
|
|
16
|
+
node_to_hash(doc.root)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def each_child(node, &block)
|
|
20
|
+
node.children.each(&block)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def each_attr(node, &block)
|
|
24
|
+
node.attribute_nodes.each(&block)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def node_name(node)
|
|
28
|
+
node.node_name
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'ox' unless defined?(Ox)
|
|
2
|
+
|
|
3
|
+
# Each MultiXml parser is expected to parse an XML document into a Hash. The
|
|
4
|
+
# conversion rules are:
|
|
5
|
+
#
|
|
6
|
+
# - Each document starts out as an empty Hash.
|
|
7
|
+
#
|
|
8
|
+
# - Reading an element created an entry in the parent Hash that has a key of
|
|
9
|
+
# the element name and a value of a Hash with attributes as key value
|
|
10
|
+
# pairs. Children are added as described by this rule.
|
|
11
|
+
#
|
|
12
|
+
# - Text and CDATE is stored in the parent element Hash with a key of
|
|
13
|
+
# MultiXml::CONTENT_ROOT and a value of the text itself.
|
|
14
|
+
#
|
|
15
|
+
# - If a key already exists in the Hash then the value associated with the key
|
|
16
|
+
# is converted to an Array with the old and new value in it.
|
|
17
|
+
#
|
|
18
|
+
# - Other elements such as the xml prolog, doctype, and comments are ignored.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
module MultiXml
|
|
22
|
+
module Parsers
|
|
23
|
+
module Ox #:nodoc:
|
|
24
|
+
|
|
25
|
+
extend self
|
|
26
|
+
|
|
27
|
+
def parse_error
|
|
28
|
+
Exception
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def parse(io)
|
|
32
|
+
handler = Handler.new
|
|
33
|
+
::Ox.sax_parse(handler, io, :convert_special => true)
|
|
34
|
+
handler.doc
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class Handler
|
|
38
|
+
attr_accessor :stack
|
|
39
|
+
|
|
40
|
+
def initialize()
|
|
41
|
+
@stack = []
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def doc
|
|
45
|
+
@stack[0]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def attr(name, value)
|
|
49
|
+
unless @stack.empty?
|
|
50
|
+
append(name, value)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def text(value)
|
|
55
|
+
append(MultiXml::CONTENT_ROOT, value)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def cdata(value)
|
|
59
|
+
append(MultiXml::CONTENT_ROOT, value)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def start_element(name)
|
|
63
|
+
if @stack.empty?
|
|
64
|
+
@stack.push(Hash.new)
|
|
65
|
+
end
|
|
66
|
+
h = Hash.new
|
|
67
|
+
append(name, h)
|
|
68
|
+
@stack.push(h)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def end_element(name)
|
|
72
|
+
@stack.pop()
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def error(message, line, column)
|
|
76
|
+
raise Exception.new("#{message} at #{line}:#{column}")
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def append(key, value)
|
|
80
|
+
key = key.to_s
|
|
81
|
+
h = @stack.last
|
|
82
|
+
if h.has_key?(key)
|
|
83
|
+
v = h[key]
|
|
84
|
+
if v.is_a?(Array)
|
|
85
|
+
v << value
|
|
86
|
+
else
|
|
87
|
+
h[key] = [v, value]
|
|
88
|
+
end
|
|
89
|
+
else
|
|
90
|
+
h[key] = value
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
end # Handler
|
|
95
|
+
end # Ox
|
|
96
|
+
end # Parsers
|
|
97
|
+
end # MultiXml
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'rexml/document' unless defined?(REXML::Document)
|
|
2
|
+
|
|
3
|
+
module MultiXml
|
|
4
|
+
module Parsers
|
|
5
|
+
module Rexml #:nodoc:
|
|
6
|
+
extend self
|
|
7
|
+
def parse_error; ::REXML::ParseException; end
|
|
8
|
+
|
|
9
|
+
# Parse an XML Document IO into a simple hash using REXML
|
|
10
|
+
#
|
|
11
|
+
# xml::
|
|
12
|
+
# XML Document IO to parse
|
|
13
|
+
def parse(xml)
|
|
14
|
+
doc = REXML::Document.new(xml)
|
|
15
|
+
if doc.root
|
|
16
|
+
merge_element!({}, doc.root)
|
|
17
|
+
else
|
|
18
|
+
raise REXML::ParseException, "The document #{doc.to_s.inspect} does not have a valid root"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
# Convert an XML element and merge into the hash
|
|
25
|
+
#
|
|
26
|
+
# hash::
|
|
27
|
+
# Hash to merge the converted element into.
|
|
28
|
+
# element::
|
|
29
|
+
# XML element to merge into hash
|
|
30
|
+
def merge_element!(hash, element)
|
|
31
|
+
merge!(hash, element.name, collapse(element))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Actually converts an XML document element into a data structure.
|
|
35
|
+
#
|
|
36
|
+
# element::
|
|
37
|
+
# The document element to be collapsed.
|
|
38
|
+
def collapse(element)
|
|
39
|
+
hash = get_attributes(element)
|
|
40
|
+
|
|
41
|
+
if element.has_elements?
|
|
42
|
+
element.each_element {|child| merge_element!(hash, child) }
|
|
43
|
+
merge_texts!(hash, element) unless empty_content?(element)
|
|
44
|
+
hash
|
|
45
|
+
else
|
|
46
|
+
merge_texts!(hash, element)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Merge all the texts of an element into the hash
|
|
51
|
+
#
|
|
52
|
+
# hash::
|
|
53
|
+
# Hash to add the converted element to.
|
|
54
|
+
# element::
|
|
55
|
+
# XML element whose texts are to me merged into the hash
|
|
56
|
+
def merge_texts!(hash, element)
|
|
57
|
+
unless element.has_text?
|
|
58
|
+
hash
|
|
59
|
+
else
|
|
60
|
+
# must use value to prevent double-escaping
|
|
61
|
+
texts = ''
|
|
62
|
+
element.texts.each { |t| texts << t.value }
|
|
63
|
+
merge!(hash, MultiXml::CONTENT_ROOT, texts)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Adds a new key/value pair to an existing Hash. If the key to be added
|
|
68
|
+
# already exists and the existing value associated with key is not
|
|
69
|
+
# an Array, it will be wrapped in an Array. Then the new value is
|
|
70
|
+
# appended to that Array.
|
|
71
|
+
#
|
|
72
|
+
# hash::
|
|
73
|
+
# Hash to add key/value pair to.
|
|
74
|
+
# key::
|
|
75
|
+
# Key to be added.
|
|
76
|
+
# value::
|
|
77
|
+
# Value to be associated with key.
|
|
78
|
+
def merge!(hash, key, value)
|
|
79
|
+
if hash.has_key?(key)
|
|
80
|
+
if hash[key].instance_of?(Array)
|
|
81
|
+
hash[key] << value
|
|
82
|
+
else
|
|
83
|
+
hash[key] = [hash[key], value]
|
|
84
|
+
end
|
|
85
|
+
elsif value.instance_of?(Array)
|
|
86
|
+
hash[key] = [value]
|
|
87
|
+
else
|
|
88
|
+
hash[key] = value
|
|
89
|
+
end
|
|
90
|
+
hash
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Converts the attributes array of an XML element into a hash.
|
|
94
|
+
# Returns an empty Hash if node has no attributes.
|
|
95
|
+
#
|
|
96
|
+
# element::
|
|
97
|
+
# XML element to extract attributes from.
|
|
98
|
+
def get_attributes(element)
|
|
99
|
+
attributes = {}
|
|
100
|
+
element.attributes.each { |n,v| attributes[n] = v }
|
|
101
|
+
attributes
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Determines if a document element has text content
|
|
105
|
+
#
|
|
106
|
+
# element::
|
|
107
|
+
# XML element to be checked.
|
|
108
|
+
def empty_content?(element)
|
|
109
|
+
element.texts.join.strip.empty?
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'multi_xml/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.add_development_dependency 'bundler', '~> 1.0'
|
|
8
|
+
spec.author = "Erik Michaels-Ober"
|
|
9
|
+
spec.cert_chain = ['certs/sferik.pem']
|
|
10
|
+
spec.description = %q{Provides swappable XML backends utilizing LibXML, Nokogiri, Ox, or REXML.}
|
|
11
|
+
spec.email = 'sferik@gmail.com'
|
|
12
|
+
spec.files = %w(.yardopts CHANGELOG.md CONTRIBUTING.md LICENSE.md README.md Rakefile multi_xml.gemspec)
|
|
13
|
+
spec.files += Dir.glob("lib/**/*.rb")
|
|
14
|
+
spec.files += Dir.glob("spec/**/*")
|
|
15
|
+
spec.homepage = 'https://github.com/sferik/multi_xml'
|
|
16
|
+
spec.licenses = ['MIT']
|
|
17
|
+
spec.name = 'multi_xml'
|
|
18
|
+
spec.require_paths = ['lib']
|
|
19
|
+
spec.required_rubygems_version = '>= 1.3.5'
|
|
20
|
+
spec.signing_key = File.expand_path("~/.gem/private_key.pem") if $0 =~ /gem\z/
|
|
21
|
+
spec.summary = %q{A generic swappable back-end for XML parsing}
|
|
22
|
+
spec.test_files = Dir.glob("spec/**/*")
|
|
23
|
+
spec.version = MultiXml::VERSION
|
|
24
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'simplecov'
|
|
2
|
+
require 'coveralls'
|
|
3
|
+
|
|
4
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
|
5
|
+
SimpleCov::Formatter::HTMLFormatter,
|
|
6
|
+
Coveralls::SimpleCov::Formatter
|
|
7
|
+
]
|
|
8
|
+
SimpleCov.start
|
|
9
|
+
|
|
10
|
+
require 'multi_xml'
|
|
11
|
+
require 'rspec'
|
|
12
|
+
|
|
13
|
+
RSpec.configure do |config|
|
|
14
|
+
config.expect_with :rspec do |c|
|
|
15
|
+
c.syntax = :expect
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
require 'parser_shared_example'
|
|
3
|
+
|
|
4
|
+
class MockDecoder; end
|
|
5
|
+
|
|
6
|
+
describe "MultiXml" do
|
|
7
|
+
context "Parsers" do
|
|
8
|
+
it "picks a default parser" do
|
|
9
|
+
expect(MultiXml.parser).to be_kind_of(Module)
|
|
10
|
+
expect(MultiXml.parser).to respond_to(:parse)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "defaults to the best available gem" do
|
|
14
|
+
# Clear cache variable already set by previous tests
|
|
15
|
+
MultiXml.send(:remove_instance_variable, :@parser)
|
|
16
|
+
expect(MultiXml.parser.name).to eq('MultiXml::Parsers::Ox')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "is settable via a symbol" do
|
|
20
|
+
MultiXml.parser = :rexml
|
|
21
|
+
expect(MultiXml.parser.name).to eq('MultiXml::Parsers::Rexml')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "is settable via a class" do
|
|
25
|
+
MultiXml.parser = MockDecoder
|
|
26
|
+
expect(MultiXml.parser.name).to eq('MockDecoder')
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
[['LibXML', 'libxml'],
|
|
31
|
+
['REXML', 'rexml/document'],
|
|
32
|
+
['Nokogiri', 'nokogiri'],
|
|
33
|
+
['Ox', 'ox']].each do |parser|
|
|
34
|
+
begin
|
|
35
|
+
require parser.last
|
|
36
|
+
context "#{parser.first} parser" do
|
|
37
|
+
it_behaves_like "a parser", parser.first
|
|
38
|
+
end
|
|
39
|
+
rescue LoadError => e
|
|
40
|
+
puts "Tests not run for #{parser.first} due to a LoadError"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,694 @@
|
|
|
1
|
+
shared_examples_for "a parser" do |parser|
|
|
2
|
+
|
|
3
|
+
before do
|
|
4
|
+
begin
|
|
5
|
+
MultiXml.parser = parser
|
|
6
|
+
rescue LoadError
|
|
7
|
+
pending "Parser #{parser} couldn't be loaded"
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe ".parse" do
|
|
12
|
+
context "a blank string" do
|
|
13
|
+
before do
|
|
14
|
+
@xml = ''
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "returns an empty Hash" do
|
|
18
|
+
expect(MultiXml.parse(@xml)).to eq({})
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "a whitespace string" do
|
|
23
|
+
before do
|
|
24
|
+
@xml = ' '
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "returns an empty Hash" do
|
|
28
|
+
expect(MultiXml.parse(@xml)).to eq({})
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "an invalid XML document" do
|
|
33
|
+
before do
|
|
34
|
+
@xml = '<open></close>'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "raises MultiXml::ParseError" do
|
|
38
|
+
expect{MultiXml.parse(@xml)}.to raise_error(MultiXml::ParseError)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context "a valid XML document" do
|
|
43
|
+
before do
|
|
44
|
+
@xml = '<user/>'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "parses correctly" do
|
|
48
|
+
expect(MultiXml.parse(@xml)).to eq({'user' => nil})
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context "with CDATA" do
|
|
52
|
+
before do
|
|
53
|
+
@xml = '<user><![CDATA[Erik Michaels-Ober]]></user>'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "returns the correct CDATA" do
|
|
57
|
+
expect(MultiXml.parse(@xml)['user']).to eq("Erik Michaels-Ober")
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
context "element with the same inner element and attribute name" do
|
|
62
|
+
before do
|
|
63
|
+
@xml = "<user name='John'><name>Smith</name></user>"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "returns nams as Array" do
|
|
67
|
+
expect(MultiXml.parse(@xml)['user']['name']).to eq ['John', 'Smith']
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context "with content" do
|
|
72
|
+
before do
|
|
73
|
+
@xml = '<user>Erik Michaels-Ober</user>'
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "returns the correct content" do
|
|
77
|
+
expect(MultiXml.parse(@xml)['user']).to eq("Erik Michaels-Ober")
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context "with an attribute" do
|
|
82
|
+
before do
|
|
83
|
+
@xml = '<user name="Erik Michaels-Ober"/>'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "returns the correct attribute" do
|
|
87
|
+
expect(MultiXml.parse(@xml)['user']['name']).to eq("Erik Michaels-Ober")
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context "with multiple attributes" do
|
|
92
|
+
before do
|
|
93
|
+
@xml = '<user name="Erik Michaels-Ober" screen_name="sferik"/>'
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "returns the correct attributes" do
|
|
97
|
+
expect(MultiXml.parse(@xml)['user']['name']).to eq("Erik Michaels-Ober")
|
|
98
|
+
expect(MultiXml.parse(@xml)['user']['screen_name']).to eq("sferik")
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
context "typecast management" do
|
|
103
|
+
before do
|
|
104
|
+
@xml = %Q{
|
|
105
|
+
<global-settings>
|
|
106
|
+
<group>
|
|
107
|
+
<name>Settings</name>
|
|
108
|
+
<setting type="string">
|
|
109
|
+
<description>Test</description>
|
|
110
|
+
</setting>
|
|
111
|
+
</group>
|
|
112
|
+
</global-settings>
|
|
113
|
+
}
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
context "with :typecast_xml_value => true" do
|
|
117
|
+
before do
|
|
118
|
+
@setting = MultiXml.parse(@xml)["global_settings"]["group"]["setting"]
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it { expect(@setting).to eq "" }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
context "with :typecast_xml_value => false" do
|
|
125
|
+
before do
|
|
126
|
+
@setting = MultiXml.parse(@xml, :typecast_xml_value => false)["global_settings"]["group"]["setting"]
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it { expect(@setting).to eq({"type"=>"string", "description"=>{"__content__"=>"Test"}}) }
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
context "with :symbolize_keys => true" do
|
|
134
|
+
before do
|
|
135
|
+
@xml = '<users><user name="Erik Michaels-Ober"/><user><name>Wynn Netherland</name></user></users>'
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "symbolizes keys" do
|
|
139
|
+
expect(MultiXml.parse(@xml, :symbolize_keys => true)).to eq({:users => {:user => [{:name => "Erik Michaels-Ober"}, {:name => "Wynn Netherland"}]}})
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
context "with an attribute type=\"boolean\"" do
|
|
144
|
+
%w(true false).each do |boolean|
|
|
145
|
+
context "when #{boolean}" do
|
|
146
|
+
it "returns #{boolean}" do
|
|
147
|
+
xml = "<tag type=\"boolean\">#{boolean}</tag>"
|
|
148
|
+
expect(MultiXml.parse(xml)['tag']).to instance_eval("be_#{boolean}")
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
context "when 1" do
|
|
154
|
+
before do
|
|
155
|
+
@xml = '<tag type="boolean">1</tag>'
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "returns true" do
|
|
159
|
+
expect(MultiXml.parse(@xml)['tag']).to be_true
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
context "when 0" do
|
|
164
|
+
before do
|
|
165
|
+
@xml = '<tag type="boolean">0</tag>'
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "returns false" do
|
|
169
|
+
expect(MultiXml.parse(@xml)['tag']).to be_false
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
context "with an attribute type=\"integer\"" do
|
|
175
|
+
context "with a positive integer" do
|
|
176
|
+
before do
|
|
177
|
+
@xml = '<tag type="integer">1</tag>'
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "returns a Fixnum" do
|
|
181
|
+
expect(MultiXml.parse(@xml)['tag']).to be_a(Fixnum)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "returns a positive number" do
|
|
185
|
+
expect(MultiXml.parse(@xml)['tag']).to be > 0
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it "returns the correct number" do
|
|
189
|
+
expect(MultiXml.parse(@xml)['tag']).to eq(1)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
context "with a negative integer" do
|
|
194
|
+
before do
|
|
195
|
+
@xml = '<tag type="integer">-1</tag>'
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it "returns a Fixnum" do
|
|
199
|
+
expect(MultiXml.parse(@xml)['tag']).to be_a(Fixnum)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it "returns a negative number" do
|
|
203
|
+
expect(MultiXml.parse(@xml)['tag']).to be < 0
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "returns the correct number" do
|
|
207
|
+
expect(MultiXml.parse(@xml)['tag']).to eq(-1)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
context "with an attribute type=\"string\"" do
|
|
213
|
+
before do
|
|
214
|
+
@xml = '<tag type="string"></tag>'
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it "returns a String" do
|
|
218
|
+
expect(MultiXml.parse(@xml)['tag']).to be_a(String)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
it "returns the correct string" do
|
|
222
|
+
expect(MultiXml.parse(@xml)['tag']).to eq("")
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
context "with an attribute type=\"date\"" do
|
|
227
|
+
before do
|
|
228
|
+
@xml = '<tag type="date">1970-01-01</tag>'
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it "returns a Date" do
|
|
232
|
+
expect(MultiXml.parse(@xml)['tag']).to be_a(Date)
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
it "returns the correct date" do
|
|
236
|
+
expect(MultiXml.parse(@xml)['tag']).to eq(Date.parse('1970-01-01'))
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
context "with an attribute type=\"datetime\"" do
|
|
241
|
+
before do
|
|
242
|
+
@xml = '<tag type="datetime">1970-01-01 00:00</tag>'
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
it "returns a Time" do
|
|
246
|
+
expect(MultiXml.parse(@xml)['tag']).to be_a(Time)
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
it "returns the correct time" do
|
|
250
|
+
expect(MultiXml.parse(@xml)['tag']).to eq(Time.parse('1970-01-01 00:00'))
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
context "with an attribute type=\"dateTime\"" do
|
|
255
|
+
before do
|
|
256
|
+
@xml = '<tag type="datetime">1970-01-01 00:00</tag>'
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
it "returns a Time" do
|
|
260
|
+
expect(MultiXml.parse(@xml)['tag']).to be_a(Time)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it "returns the correct time" do
|
|
264
|
+
expect(MultiXml.parse(@xml)['tag']).to eq(Time.parse('1970-01-01 00:00'))
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
context "with an attribute type=\"double\"" do
|
|
269
|
+
before do
|
|
270
|
+
@xml = '<tag type="double">3.14159265358979</tag>'
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it "returns a Float" do
|
|
274
|
+
expect(MultiXml.parse(@xml)['tag']).to be_a(Float)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
it "returns the correct number" do
|
|
278
|
+
expect(MultiXml.parse(@xml)['tag']).to eq(3.14159265358979)
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
context "with an attribute type=\"decimal\"" do
|
|
283
|
+
before do
|
|
284
|
+
@xml = '<tag type="decimal">3.14159265358979</tag>'
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it "returns a BigDecimal" do
|
|
288
|
+
expect(MultiXml.parse(@xml)['tag']).to be_a(BigDecimal)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
it "returns the correct number" do
|
|
292
|
+
expect(MultiXml.parse(@xml)['tag']).to eq(3.14159265358979)
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
context "with an attribute type=\"base64Binary\"" do
|
|
297
|
+
before do
|
|
298
|
+
@xml = '<tag type="base64Binary">aW1hZ2UucG5n</tag>'
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it "returns a String" do
|
|
302
|
+
expect(MultiXml.parse(@xml)['tag']).to be_a(String)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
it "returns the correct string" do
|
|
306
|
+
expect(MultiXml.parse(@xml)['tag']).to eq("image.png")
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
context "with an attribute type=\"yaml\"" do
|
|
311
|
+
before do
|
|
312
|
+
@xml = "<tag type=\"yaml\">--- \n1: returns an integer\n:message: Have a nice day\narray: \n- has-dashes: true\n has_underscores: true\n</tag>"
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
it "raises MultiXML::DisallowedTypeError by default" do
|
|
316
|
+
expect{ MultiXml.parse(@xml)['tag'] }.to raise_error(MultiXml::DisallowedTypeError)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
it "returns the correctly parsed YAML when the type is allowed" do
|
|
320
|
+
expect(MultiXml.parse(@xml, :disallowed_types => [])['tag']).to eq({:message => "Have a nice day", 1 => "returns an integer", "array" => [{"has-dashes" => true, "has_underscores" => true}]})
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
context "with an attribute type=\"symbol\"" do
|
|
325
|
+
before do
|
|
326
|
+
@xml = "<tag type=\"symbol\">my_symbol</tag>"
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
it "raises MultiXML::DisallowedTypeError" do
|
|
330
|
+
expect{ MultiXml.parse(@xml)['tag'] }.to raise_error(MultiXml::DisallowedTypeError)
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
it "returns the correctly parsed Symbol when the type is allowed" do
|
|
334
|
+
expect(MultiXml.parse(@xml, :disallowed_types => [])['tag']).to eq(:my_symbol)
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
context "with an attribute type=\"file\"" do
|
|
339
|
+
before do
|
|
340
|
+
@xml = '<tag type="file" name="data.txt" content_type="text/plain">ZGF0YQ==</tag>'
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
it "returns a StringIO" do
|
|
344
|
+
expect(MultiXml.parse(@xml)['tag']).to be_a(StringIO)
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
it "is decoded correctly" do
|
|
348
|
+
expect(MultiXml.parse(@xml)['tag'].string).to eq('data')
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
it "has the correct file name" do
|
|
352
|
+
expect(MultiXml.parse(@xml)['tag'].original_filename).to eq('data.txt')
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
it "has the correct content type" do
|
|
356
|
+
expect(MultiXml.parse(@xml)['tag'].content_type).to eq('text/plain')
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
context "with missing name and content type" do
|
|
360
|
+
before do
|
|
361
|
+
@xml = '<tag type="file">ZGF0YQ==</tag>'
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
it "returns a StringIO" do
|
|
365
|
+
expect(MultiXml.parse(@xml)['tag']).to be_a(StringIO)
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
it "is decoded correctly" do
|
|
369
|
+
expect(MultiXml.parse(@xml)['tag'].string).to eq('data')
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
it "has the default file name" do
|
|
373
|
+
expect(MultiXml.parse(@xml)['tag'].original_filename).to eq('untitled')
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
it "has the default content type" do
|
|
377
|
+
expect(MultiXml.parse(@xml)['tag'].content_type).to eq('application/octet-stream')
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
context "with an attribute type=\"array\"" do
|
|
383
|
+
before do
|
|
384
|
+
@xml = '<users type="array"><user>Erik Michaels-Ober</user><user>Wynn Netherland</user></users>'
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
it "returns an Array" do
|
|
388
|
+
expect(MultiXml.parse(@xml)['users']).to be_a(Array)
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
it "returns the correct array" do
|
|
392
|
+
expect(MultiXml.parse(@xml)['users']).to eq(["Erik Michaels-Ober", "Wynn Netherland"])
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
context "with an attribute type=\"array\" in addition to other attributes" do
|
|
397
|
+
before do
|
|
398
|
+
@xml = '<users type="array" foo="bar"><user>Erik Michaels-Ober</user><user>Wynn Netherland</user></users>'
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
it "returns an Array" do
|
|
402
|
+
expect(MultiXml.parse(@xml)['users']).to be_a(Array)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
it "returns the correct array" do
|
|
406
|
+
expect(MultiXml.parse(@xml)['users']).to eq(["Erik Michaels-Ober", "Wynn Netherland"])
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
context "with an attribute type=\"array\" containing only one item" do
|
|
411
|
+
before do
|
|
412
|
+
@xml = '<users type="array"><user>Erik Michaels-Ober</user></users>'
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
it "returns an Array" do
|
|
416
|
+
expect(MultiXml.parse(@xml)['users']).to be_a(Array)
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
it "returns the correct array" do
|
|
420
|
+
expect(MultiXml.parse(@xml)['users']).to eq(["Erik Michaels-Ober"])
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
%w(integer boolean date datetime file).each do |type|
|
|
425
|
+
context "with an empty attribute type=\"#{type}\"" do
|
|
426
|
+
before do
|
|
427
|
+
@xml = "<tag type=\"#{type}\"/>"
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
it "returns nil" do
|
|
431
|
+
expect(MultiXml.parse(@xml)['tag']).to be_nil
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
%w{yaml symbol}.each do |type|
|
|
437
|
+
context "with an empty attribute type=\"#{type}\"" do
|
|
438
|
+
before do
|
|
439
|
+
@xml = "<tag type=\"#{type}\"/>"
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
it "raises MultiXml::DisallowedTypeError by default" do
|
|
443
|
+
expect{ MultiXml.parse(@xml)['tag']}.to raise_error(MultiXml::DisallowedTypeError)
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
it "returns nil when the type is allowed" do
|
|
447
|
+
expect(MultiXml.parse(@xml, :disallowed_types => [])['tag']).to be_nil
|
|
448
|
+
end
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
context "with an empty attribute type=\"array\"" do
|
|
453
|
+
before do
|
|
454
|
+
@xml = '<tag type="array"/>'
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
it "returns an empty Array" do
|
|
458
|
+
expect(MultiXml.parse(@xml)['tag']).to eq([])
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
context "with whitespace" do
|
|
462
|
+
before do
|
|
463
|
+
@xml = '<tag type="array"> </tag>'
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
it "returns an empty Array" do
|
|
467
|
+
expect(MultiXml.parse(@xml)['tag']).to eq([])
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
context "with XML entities" do
|
|
473
|
+
before do
|
|
474
|
+
@xml_entities = {
|
|
475
|
+
"<" => "<",
|
|
476
|
+
">" => ">",
|
|
477
|
+
'"' => """,
|
|
478
|
+
"'" => "'",
|
|
479
|
+
"&" => "&"
|
|
480
|
+
}
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
context "in content" do
|
|
484
|
+
it "returns unescaped XML entities" do
|
|
485
|
+
@xml_entities.each do |key, value|
|
|
486
|
+
xml = "<tag>#{value}</tag>"
|
|
487
|
+
expect(MultiXml.parse(xml)['tag']).to eq(key)
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
context "in attribute" do
|
|
493
|
+
it "returns unescaped XML entities" do
|
|
494
|
+
@xml_entities.each do |key, value|
|
|
495
|
+
xml = "<tag attribute=\"#{value}\"/>"
|
|
496
|
+
expect(MultiXml.parse(xml)['tag']['attribute']).to eq(key)
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
context "with dasherized tag" do
|
|
504
|
+
before do
|
|
505
|
+
@xml = '<tag-1/>'
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
it "returns undasherize tag" do
|
|
509
|
+
expect(MultiXml.parse(@xml).keys).to include('tag_1')
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
context "with dasherized attribute" do
|
|
514
|
+
before do
|
|
515
|
+
@xml = '<tag attribute-1="1"></tag>'
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
it "returns undasherize attribute" do
|
|
519
|
+
expect(MultiXml.parse(@xml)['tag'].keys).to include('attribute_1')
|
|
520
|
+
end
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
context "with children" do
|
|
524
|
+
context "with attributes" do
|
|
525
|
+
before do
|
|
526
|
+
@xml = '<users><user name="Erik Michaels-Ober"/></users>'
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
it "returns the correct attributes" do
|
|
530
|
+
expect(MultiXml.parse(@xml)['users']['user']['name']).to eq("Erik Michaels-Ober")
|
|
531
|
+
end
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
context "with text" do
|
|
535
|
+
before do
|
|
536
|
+
@xml = '<user><name>Erik Michaels-Ober</name></user>'
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
it "returns the correct text" do
|
|
540
|
+
expect(MultiXml.parse(@xml)['user']['name']).to eq("Erik Michaels-Ober")
|
|
541
|
+
end
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
context "with an unrecognized attribute type" do
|
|
545
|
+
before do
|
|
546
|
+
@xml = '<user type="admin"><name>Erik Michaels-Ober</name></user>'
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
it "passes through the type" do
|
|
550
|
+
expect(MultiXml.parse(@xml)['user']['type']).to eq('admin')
|
|
551
|
+
end
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
context "with attribute tags on content nodes" do
|
|
555
|
+
context "non 'type' attributes" do
|
|
556
|
+
before do
|
|
557
|
+
@xml = <<-XML
|
|
558
|
+
<options>
|
|
559
|
+
<value currency='USD'>123</value>
|
|
560
|
+
<value number='percent'>0.123</value>
|
|
561
|
+
</options>
|
|
562
|
+
XML
|
|
563
|
+
@parsed_xml = MultiXml.parse(@xml)
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
it "adds the attributes to the value hash" do
|
|
567
|
+
expect(@parsed_xml['options']['value'][0]['__content__']).to eq('123')
|
|
568
|
+
expect(@parsed_xml['options']['value'][0]['currency']).to eq('USD')
|
|
569
|
+
expect(@parsed_xml['options']['value'][1]['__content__']).to eq('0.123')
|
|
570
|
+
expect(@parsed_xml['options']['value'][1]['number']).to eq('percent')
|
|
571
|
+
end
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
context "unrecognized type attributes" do
|
|
575
|
+
before do
|
|
576
|
+
@xml = <<-XML
|
|
577
|
+
<options>
|
|
578
|
+
<value type='USD'>123</value>
|
|
579
|
+
<value type='percent'>0.123</value>
|
|
580
|
+
<value currency='USD'>123</value>
|
|
581
|
+
</options>
|
|
582
|
+
XML
|
|
583
|
+
@parsed_xml = MultiXml.parse(@xml)
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
it "adds the attributes to the value hash passing through the type" do
|
|
587
|
+
expect(@parsed_xml['options']['value'][0]['__content__']).to eq('123')
|
|
588
|
+
expect(@parsed_xml['options']['value'][0]['type']).to eq('USD')
|
|
589
|
+
expect(@parsed_xml['options']['value'][1]['__content__']).to eq('0.123')
|
|
590
|
+
expect(@parsed_xml['options']['value'][1]['type']).to eq('percent')
|
|
591
|
+
expect(@parsed_xml['options']['value'][2]['__content__']).to eq('123')
|
|
592
|
+
expect(@parsed_xml['options']['value'][2]['currency']).to eq('USD')
|
|
593
|
+
end
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
context "mixing attributes and non-attributes content nodes type attributes" do
|
|
597
|
+
before do
|
|
598
|
+
@xml = <<-XML
|
|
599
|
+
<options>
|
|
600
|
+
<value type='USD'>123</value>
|
|
601
|
+
<value type='percent'>0.123</value>
|
|
602
|
+
<value>123</value>
|
|
603
|
+
</options>
|
|
604
|
+
XML
|
|
605
|
+
@parsed_xml = MultiXml.parse(@xml)
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
it "adds the attributes to the value hash passing through the type" do
|
|
609
|
+
expect(@parsed_xml['options']['value'][0]['__content__']).to eq('123')
|
|
610
|
+
expect(@parsed_xml['options']['value'][0]['type']).to eq('USD')
|
|
611
|
+
expect(@parsed_xml['options']['value'][1]['__content__']).to eq('0.123')
|
|
612
|
+
expect(@parsed_xml['options']['value'][1]['type']).to eq('percent')
|
|
613
|
+
expect(@parsed_xml['options']['value'][2]).to eq('123')
|
|
614
|
+
end
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
context "mixing recognized type attribute and non-type attributes on content nodes" do
|
|
618
|
+
before do
|
|
619
|
+
@xml = <<-XML
|
|
620
|
+
<options>
|
|
621
|
+
<value number='USD' type='integer'>123</value>
|
|
622
|
+
</options>
|
|
623
|
+
XML
|
|
624
|
+
@parsed_xml = MultiXml.parse(@xml)
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
it "adds the the non-type attribute and remove the recognized type attribute and do the typecast" do
|
|
628
|
+
expect(@parsed_xml['options']['value']['__content__']).to eq(123)
|
|
629
|
+
expect(@parsed_xml['options']['value']['number']).to eq('USD')
|
|
630
|
+
end
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
context "mixing unrecognized type attribute and non-type attributes on content nodes" do
|
|
634
|
+
before do
|
|
635
|
+
@xml = <<-XML
|
|
636
|
+
<options>
|
|
637
|
+
<value number='USD' type='currency'>123</value>
|
|
638
|
+
</options>
|
|
639
|
+
XML
|
|
640
|
+
@parsed_xml = MultiXml.parse(@xml)
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
it "adds the the non-type attributes and type attribute to the value hash" do
|
|
644
|
+
expect(@parsed_xml['options']['value']['__content__']).to eq('123')
|
|
645
|
+
expect(@parsed_xml['options']['value']['number']).to eq('USD')
|
|
646
|
+
expect(@parsed_xml['options']['value']['type']).to eq('currency')
|
|
647
|
+
end
|
|
648
|
+
end
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
context "with newlines and whitespace" do
|
|
652
|
+
before do
|
|
653
|
+
@xml = <<-XML
|
|
654
|
+
<user>
|
|
655
|
+
<name>Erik Michaels-Ober</name>
|
|
656
|
+
</user>
|
|
657
|
+
XML
|
|
658
|
+
end
|
|
659
|
+
|
|
660
|
+
it "parses correctly" do
|
|
661
|
+
expect(MultiXml.parse(@xml)).to eq({"user" => {"name" => "Erik Michaels-Ober"}})
|
|
662
|
+
end
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
# Babies having babies
|
|
666
|
+
context "with children" do
|
|
667
|
+
before do
|
|
668
|
+
@xml = '<users><user name="Erik Michaels-Ober"><status text="Hello"/></user></users>'
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
it "parses correctly" do
|
|
672
|
+
expect(MultiXml.parse(@xml)).to eq({"users" => {"user" => {"name" => "Erik Michaels-Ober", "status" => {"text" => "Hello"}}}})
|
|
673
|
+
end
|
|
674
|
+
end
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
context "with sibling children" do
|
|
678
|
+
before do
|
|
679
|
+
@xml = '<users><user>Erik Michaels-Ober</user><user>Wynn Netherland</user></users>'
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
it "returns an Array" do
|
|
683
|
+
expect(MultiXml.parse(@xml)['users']['user']).to be_a(Array)
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
it "parses correctly" do
|
|
687
|
+
expect(MultiXml.parse(@xml)).to eq({"users" => {"user" => ["Erik Michaels-Ober", "Wynn Netherland"]}})
|
|
688
|
+
end
|
|
689
|
+
end
|
|
690
|
+
|
|
691
|
+
end
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
end
|