[macruby-changes] [4794] MacRuby/trunk/test
source_changes at macosforge.org
source_changes at macosforge.org
Thu Oct 14 06:40:35 PDT 2010
Revision: 4794
http://trac.macosforge.org/projects/ruby/changeset/4794
Author: watson1978 at gmail.com
Date: 2010-10-14 06:40:31 -0700 (Thu, 14 Oct 2010)
Log Message:
-----------
imported the Ruby 1.9.2's tests.
Added Paths:
-----------
MacRuby/trunk/test/test-mri/
MacRuby/trunk/test/test-mri/README
MacRuby/trunk/test/test-mri/Rakefile
MacRuby/trunk/test/test-mri/bin/
MacRuby/trunk/test/test-mri/bin/timeout
MacRuby/trunk/test/test-mri/bootstraptest/
MacRuby/trunk/test/test-mri/bootstraptest/pending.rb
MacRuby/trunk/test/test-mri/bootstraptest/runner.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_attr.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_autoload.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_block.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_class.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_eval.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_exception.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_finalizer.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_flip.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_flow.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_fork.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_gc.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_io.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_jump.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_literal.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_load.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_marshal.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_massign.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_method.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_objectspace.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_proc.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_struct.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_syntax.rb
MacRuby/trunk/test/test-mri/bootstraptest/test_thread.rb
MacRuby/trunk/test/test-mri/require_relative.rb
MacRuby/trunk/test/test-mri/test/
MacRuby/trunk/test/test-mri/test/-ext-/
MacRuby/trunk/test/test-mri/test/-ext-/test_bug-3662.rb
MacRuby/trunk/test/test-mri/test/base64/
MacRuby/trunk/test/test-mri/test/base64/test_base64.rb
MacRuby/trunk/test/test-mri/test/benchmark/
MacRuby/trunk/test/test-mri/test/benchmark/test_benchmark.rb
MacRuby/trunk/test/test-mri/test/bigdecimal/
MacRuby/trunk/test/test-mri/test/bigdecimal/test_bigdecimal.rb
MacRuby/trunk/test/test-mri/test/bigdecimal/test_bigmath.rb
MacRuby/trunk/test/test-mri/test/bigdecimal/testbase.rb
MacRuby/trunk/test/test-mri/test/cgi/
MacRuby/trunk/test/test-mri/test/cgi/test_cgi_cookie.rb
MacRuby/trunk/test/test-mri/test/cgi/test_cgi_core.rb
MacRuby/trunk/test/test-mri/test/cgi/test_cgi_header.rb
MacRuby/trunk/test/test-mri/test/cgi/test_cgi_modruby.rb
MacRuby/trunk/test/test-mri/test/cgi/test_cgi_multipart.rb
MacRuby/trunk/test/test-mri/test/cgi/test_cgi_session.rb
MacRuby/trunk/test/test-mri/test/cgi/test_cgi_tag_helper.rb
MacRuby/trunk/test/test-mri/test/cgi/test_cgi_util.rb
MacRuby/trunk/test/test-mri/test/cgi/testdata/
MacRuby/trunk/test/test-mri/test/cgi/testdata/file1.html
MacRuby/trunk/test/test-mri/test/cgi/testdata/large.png
MacRuby/trunk/test/test-mri/test/cgi/testdata/small.png
MacRuby/trunk/test/test-mri/test/csv/
MacRuby/trunk/test/test-mri/test/csv/line_endings.gz
MacRuby/trunk/test/test-mri/test/csv/test_csv_parsing.rb
MacRuby/trunk/test/test-mri/test/csv/test_csv_writing.rb
MacRuby/trunk/test/test-mri/test/csv/test_data_converters.rb
MacRuby/trunk/test/test-mri/test/csv/test_encodings.rb
MacRuby/trunk/test/test-mri/test/csv/test_features.rb
MacRuby/trunk/test/test-mri/test/csv/test_headers.rb
MacRuby/trunk/test/test-mri/test/csv/test_interface.rb
MacRuby/trunk/test/test-mri/test/csv/test_row.rb
MacRuby/trunk/test/test-mri/test/csv/test_serialization.rb
MacRuby/trunk/test/test-mri/test/csv/test_table.rb
MacRuby/trunk/test/test-mri/test/csv/ts_all.rb
MacRuby/trunk/test/test-mri/test/date/
MacRuby/trunk/test/test-mri/test/date/test_date.rb
MacRuby/trunk/test/test-mri/test/date/test_date_arith.rb
MacRuby/trunk/test/test-mri/test/date/test_date_attr.rb
MacRuby/trunk/test/test-mri/test/date/test_date_base.rb
MacRuby/trunk/test/test-mri/test/date/test_date_compat.rb
MacRuby/trunk/test/test-mri/test/date/test_date_conv.rb
MacRuby/trunk/test/test-mri/test/date/test_date_marshal.rb
MacRuby/trunk/test/test-mri/test/date/test_date_new.rb
MacRuby/trunk/test/test-mri/test/date/test_date_parse.rb
MacRuby/trunk/test/test-mri/test/date/test_date_strftime.rb
MacRuby/trunk/test/test-mri/test/date/test_date_strptime.rb
MacRuby/trunk/test/test-mri/test/dbm/
MacRuby/trunk/test/test-mri/test/dbm/test_dbm.rb
MacRuby/trunk/test/test-mri/test/digest/
MacRuby/trunk/test/test-mri/test/digest/test_digest.rb
MacRuby/trunk/test/test-mri/test/digest/test_digest_extend.rb
MacRuby/trunk/test/test-mri/test/digest/test_digest_hmac.rb
MacRuby/trunk/test/test-mri/test/dl/
MacRuby/trunk/test/test-mri/test/dl/test_base.rb
MacRuby/trunk/test/test-mri/test/dl/test_callback.rb
MacRuby/trunk/test/test-mri/test/dl/test_cfunc.rb
MacRuby/trunk/test/test-mri/test/dl/test_cparser.rb
MacRuby/trunk/test/test-mri/test/dl/test_cptr.rb
MacRuby/trunk/test/test-mri/test/dl/test_dl2.rb
MacRuby/trunk/test/test-mri/test/dl/test_func.rb
MacRuby/trunk/test/test-mri/test/dl/test_handle.rb
MacRuby/trunk/test/test-mri/test/dl/test_import.rb
MacRuby/trunk/test/test-mri/test/dl/test_win32.rb
MacRuby/trunk/test/test-mri/test/drb/
MacRuby/trunk/test/test-mri/test/drb/drbtest.rb
MacRuby/trunk/test/test-mri/test/drb/ignore_test_drb.rb
MacRuby/trunk/test/test-mri/test/drb/test_acl.rb
MacRuby/trunk/test/test-mri/test/drb/test_drb.rb
MacRuby/trunk/test/test-mri/test/drb/test_drbssl.rb
MacRuby/trunk/test/test-mri/test/drb/test_drbunix.rb
MacRuby/trunk/test/test-mri/test/drb/ut_array.rb
MacRuby/trunk/test/test-mri/test/drb/ut_array_drbssl.rb
MacRuby/trunk/test/test-mri/test/drb/ut_array_drbunix.rb
MacRuby/trunk/test/test-mri/test/drb/ut_drb.rb
MacRuby/trunk/test/test-mri/test/drb/ut_drb_drbssl.rb
MacRuby/trunk/test/test-mri/test/drb/ut_drb_drbunix.rb
MacRuby/trunk/test/test-mri/test/drb/ut_eval.rb
MacRuby/trunk/test/test-mri/test/drb/ut_large.rb
MacRuby/trunk/test/test-mri/test/drb/ut_port.rb
MacRuby/trunk/test/test-mri/test/drb/ut_safe1.rb
MacRuby/trunk/test/test-mri/test/drb/ut_timerholder.rb
MacRuby/trunk/test/test-mri/test/erb/
MacRuby/trunk/test/test-mri/test/erb/hello.erb
MacRuby/trunk/test/test-mri/test/erb/test_erb.rb
MacRuby/trunk/test/test-mri/test/erb/test_erb_m17n.rb
MacRuby/trunk/test/test-mri/test/etc/
MacRuby/trunk/test/test-mri/test/etc/test_etc.rb
MacRuby/trunk/test/test-mri/test/fiddle/
MacRuby/trunk/test/test-mri/test/fiddle/helper.rb
MacRuby/trunk/test/test-mri/test/fiddle/test_closure.rb
MacRuby/trunk/test/test-mri/test/fiddle/test_fiddle.rb
MacRuby/trunk/test/test-mri/test/fiddle/test_function.rb
MacRuby/trunk/test/test-mri/test/fileutils/
MacRuby/trunk/test/test-mri/test/fileutils/fileasserts.rb
MacRuby/trunk/test/test-mri/test/fileutils/test_dryrun.rb
MacRuby/trunk/test/test-mri/test/fileutils/test_fileutils.rb
MacRuby/trunk/test/test-mri/test/fileutils/test_nowrite.rb
MacRuby/trunk/test/test-mri/test/fileutils/test_verbose.rb
MacRuby/trunk/test/test-mri/test/gdbm/
MacRuby/trunk/test/test-mri/test/gdbm/test_gdbm.rb
MacRuby/trunk/test/test-mri/test/iconv/
MacRuby/trunk/test/test-mri/test/iconv/test_basic.rb
MacRuby/trunk/test/test-mri/test/iconv/test_option.rb
MacRuby/trunk/test/test-mri/test/iconv/test_partial.rb
MacRuby/trunk/test/test-mri/test/iconv/utils.rb
MacRuby/trunk/test/test-mri/test/inlinetest.rb
MacRuby/trunk/test/test-mri/test/io/
MacRuby/trunk/test/test-mri/test/io/nonblock/
MacRuby/trunk/test/test-mri/test/io/nonblock/test_flush.rb
MacRuby/trunk/test/test-mri/test/json/
MacRuby/trunk/test/test-mri/test/json/fixtures/
MacRuby/trunk/test/test-mri/test/json/fixtures/fail1.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail10.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail11.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail12.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail13.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail14.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail18.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail19.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail2.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail20.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail21.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail22.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail23.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail24.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail25.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail27.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail28.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail3.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail4.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail5.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail6.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail7.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail8.json
MacRuby/trunk/test/test-mri/test/json/fixtures/fail9.json
MacRuby/trunk/test/test-mri/test/json/fixtures/pass1.json
MacRuby/trunk/test/test-mri/test/json/fixtures/pass15.json
MacRuby/trunk/test/test-mri/test/json/fixtures/pass16.json
MacRuby/trunk/test/test-mri/test/json/fixtures/pass17.json
MacRuby/trunk/test/test-mri/test/json/fixtures/pass2.json
MacRuby/trunk/test/test-mri/test/json/fixtures/pass26.json
MacRuby/trunk/test/test-mri/test/json/fixtures/pass3.json
MacRuby/trunk/test/test-mri/test/json/test_json.rb
MacRuby/trunk/test/test-mri/test/json/test_json_addition.rb
MacRuby/trunk/test/test-mri/test/json/test_json_encoding.rb
MacRuby/trunk/test/test-mri/test/json/test_json_fixtures.rb
MacRuby/trunk/test/test-mri/test/json/test_json_generate.rb
MacRuby/trunk/test/test-mri/test/json/test_json_rails.rb
MacRuby/trunk/test/test-mri/test/json/test_json_unicode.rb
MacRuby/trunk/test/test-mri/test/logger/
MacRuby/trunk/test/test-mri/test/logger/test_logger.rb
MacRuby/trunk/test/test-mri/test/matrix/
MacRuby/trunk/test/test-mri/test/matrix/test_matrix.rb
MacRuby/trunk/test/test-mri/test/matrix/test_vector.rb
MacRuby/trunk/test/test-mri/test/minitest/
MacRuby/trunk/test/test-mri/test/minitest/test_mini_mock.rb
MacRuby/trunk/test/test-mri/test/minitest/test_mini_spec.rb
MacRuby/trunk/test/test-mri/test/minitest/test_mini_test.rb
MacRuby/trunk/test/test-mri/test/mkmf/
MacRuby/trunk/test/test-mri/test/mkmf/base.rb
MacRuby/trunk/test/test-mri/test/mkmf/test_find_executable.rb
MacRuby/trunk/test/test-mri/test/mkmf/test_sizeof.rb
MacRuby/trunk/test/test-mri/test/monitor/
MacRuby/trunk/test/test-mri/test/monitor/test_monitor.rb
MacRuby/trunk/test/test-mri/test/net/
MacRuby/trunk/test/test-mri/test/net/http/
MacRuby/trunk/test/test-mri/test/net/http/test_http.rb
MacRuby/trunk/test/test-mri/test/net/http/test_httpheader.rb
MacRuby/trunk/test/test-mri/test/net/http/test_httpresponse.rb
MacRuby/trunk/test/test-mri/test/net/http/test_https.rb
MacRuby/trunk/test/test-mri/test/net/http/test_https_proxy.rb
MacRuby/trunk/test/test-mri/test/net/http/utils.rb
MacRuby/trunk/test/test-mri/test/net/imap/
MacRuby/trunk/test/test-mri/test/net/imap/cacert.pem
MacRuby/trunk/test/test-mri/test/net/imap/server.crt
MacRuby/trunk/test/test-mri/test/net/imap/server.key
MacRuby/trunk/test/test-mri/test/net/imap/test_imap.rb
MacRuby/trunk/test/test-mri/test/net/imap/test_imap_response_parser.rb
MacRuby/trunk/test/test-mri/test/net/pop/
MacRuby/trunk/test/test-mri/test/net/pop/test_pop.rb
MacRuby/trunk/test/test-mri/test/nkf/
MacRuby/trunk/test/test-mri/test/nkf/test_kconv.rb
MacRuby/trunk/test/test-mri/test/nkf/test_nkf.rb
MacRuby/trunk/test/test-mri/test/open-uri/
MacRuby/trunk/test/test-mri/test/open-uri/test_open-uri.rb
MacRuby/trunk/test/test-mri/test/open-uri/test_ssl.rb
MacRuby/trunk/test/test-mri/test/openssl/
MacRuby/trunk/test/test-mri/test/openssl/ssl_server.rb
MacRuby/trunk/test/test-mri/test/openssl/test_asn1.rb
MacRuby/trunk/test/test-mri/test/openssl/test_cipher.rb
MacRuby/trunk/test/test-mri/test/openssl/test_config.rb
MacRuby/trunk/test/test-mri/test/openssl/test_digest.rb
MacRuby/trunk/test/test-mri/test/openssl/test_ec.rb
MacRuby/trunk/test/test-mri/test/openssl/test_hmac.rb
MacRuby/trunk/test/test-mri/test/openssl/test_ns_spki.rb
MacRuby/trunk/test/test-mri/test/openssl/test_pair.rb
MacRuby/trunk/test/test-mri/test/openssl/test_pkcs7.rb
MacRuby/trunk/test/test-mri/test/openssl/test_pkey_rsa.rb
MacRuby/trunk/test/test-mri/test/openssl/test_ssl.rb
MacRuby/trunk/test/test-mri/test/openssl/test_x509cert.rb
MacRuby/trunk/test/test-mri/test/openssl/test_x509crl.rb
MacRuby/trunk/test/test-mri/test/openssl/test_x509ext.rb
MacRuby/trunk/test/test-mri/test/openssl/test_x509name.rb
MacRuby/trunk/test/test-mri/test/openssl/test_x509req.rb
MacRuby/trunk/test/test-mri/test/openssl/test_x509store.rb
MacRuby/trunk/test/test-mri/test/openssl/utils.rb
MacRuby/trunk/test/test-mri/test/optparse/
MacRuby/trunk/test/test-mri/test/optparse/test_getopts.rb
MacRuby/trunk/test/test-mri/test/optparse/test_noarg.rb
MacRuby/trunk/test/test-mri/test/optparse/test_optarg.rb
MacRuby/trunk/test/test-mri/test/optparse/test_optparse.rb
MacRuby/trunk/test/test-mri/test/optparse/test_placearg.rb
MacRuby/trunk/test/test-mri/test/optparse/test_reqarg.rb
MacRuby/trunk/test/test-mri/test/optparse/test_summary.rb
MacRuby/trunk/test/test-mri/test/ostruct/
MacRuby/trunk/test/test-mri/test/ostruct/test_ostruct.rb
MacRuby/trunk/test/test-mri/test/pathname/
MacRuby/trunk/test/test-mri/test/pathname/test_pathname.rb
MacRuby/trunk/test/test-mri/test/psych/
MacRuby/trunk/test/test-mri/test/psych/helper.rb
MacRuby/trunk/test/test-mri/test/psych/test_alias_and_anchor.rb
MacRuby/trunk/test/test-mri/test/psych/test_array.rb
MacRuby/trunk/test/test-mri/test/psych/test_boolean.rb
MacRuby/trunk/test/test-mri/test/psych/test_class.rb
MacRuby/trunk/test/test-mri/test/psych/test_coder.rb
MacRuby/trunk/test/test-mri/test/psych/test_date_time.rb
MacRuby/trunk/test/test-mri/test/psych/test_deprecated.rb
MacRuby/trunk/test/test-mri/test/psych/test_document.rb
MacRuby/trunk/test/test-mri/test/psych/test_emitter.rb
MacRuby/trunk/test/test-mri/test/psych/test_encoding.rb
MacRuby/trunk/test/test-mri/test/psych/test_engine_manager.rb
MacRuby/trunk/test/test-mri/test/psych/test_exception.rb
MacRuby/trunk/test/test-mri/test/psych/test_hash.rb
MacRuby/trunk/test/test-mri/test/psych/test_json_tree.rb
MacRuby/trunk/test/test-mri/test/psych/test_null.rb
MacRuby/trunk/test/test-mri/test/psych/test_object.rb
MacRuby/trunk/test/test-mri/test/psych/test_omap.rb
MacRuby/trunk/test/test-mri/test/psych/test_parser.rb
MacRuby/trunk/test/test-mri/test/psych/test_psych.rb
MacRuby/trunk/test/test-mri/test/psych/test_scalar.rb
MacRuby/trunk/test/test-mri/test/psych/test_scalar_scanner.rb
MacRuby/trunk/test/test-mri/test/psych/test_serialize_subclasses.rb
MacRuby/trunk/test/test-mri/test/psych/test_set.rb
MacRuby/trunk/test/test-mri/test/psych/test_string.rb
MacRuby/trunk/test/test-mri/test/psych/test_struct.rb
MacRuby/trunk/test/test-mri/test/psych/test_symbol.rb
MacRuby/trunk/test/test-mri/test/psych/test_to_yaml_properties.rb
MacRuby/trunk/test/test-mri/test/psych/test_tree_builder.rb
MacRuby/trunk/test/test-mri/test/psych/test_yaml.rb
MacRuby/trunk/test/test-mri/test/psych/visitors/
MacRuby/trunk/test/test-mri/test/psych/visitors/test_emitter.rb
MacRuby/trunk/test/test-mri/test/psych/visitors/test_to_ruby.rb
MacRuby/trunk/test/test-mri/test/psych/visitors/test_yaml_tree.rb
MacRuby/trunk/test/test-mri/test/rake/
MacRuby/trunk/test/test-mri/test/rake/capture_stdout.rb
MacRuby/trunk/test/test-mri/test/rake/check_expansion.rb
MacRuby/trunk/test/test-mri/test/rake/check_no_expansion.rb
MacRuby/trunk/test/test-mri/test/rake/contrib/
MacRuby/trunk/test/test-mri/test/rake/contrib/test_ftp.rb
MacRuby/trunk/test/test-mri/test/rake/data/
MacRuby/trunk/test/test-mri/test/rake/data/chains/
MacRuby/trunk/test/test-mri/test/rake/data/chains/Rakefile
MacRuby/trunk/test/test-mri/test/rake/data/default/
MacRuby/trunk/test/test-mri/test/rake/data/default/Rakefile
MacRuby/trunk/test/test-mri/test/rake/data/dryrun/
MacRuby/trunk/test/test-mri/test/rake/data/dryrun/Rakefile
MacRuby/trunk/test/test-mri/test/rake/data/file_creation_task/
MacRuby/trunk/test/test-mri/test/rake/data/file_creation_task/Rakefile
MacRuby/trunk/test/test-mri/test/rake/data/imports/
MacRuby/trunk/test/test-mri/test/rake/data/imports/Rakefile
MacRuby/trunk/test/test-mri/test/rake/data/imports/deps.mf
MacRuby/trunk/test/test-mri/test/rake/data/multidesc/
MacRuby/trunk/test/test-mri/test/rake/data/multidesc/Rakefile
MacRuby/trunk/test/test-mri/test/rake/data/namespace/
MacRuby/trunk/test/test-mri/test/rake/data/namespace/Rakefile
MacRuby/trunk/test/test-mri/test/rake/data/rakelib/
MacRuby/trunk/test/test-mri/test/rake/data/rakelib/test1.rake
MacRuby/trunk/test/test-mri/test/rake/data/rbext/
MacRuby/trunk/test/test-mri/test/rake/data/rbext/rakefile.rb
MacRuby/trunk/test/test-mri/test/rake/data/sample.mf
MacRuby/trunk/test/test-mri/test/rake/data/statusreturn/
MacRuby/trunk/test/test-mri/test/rake/data/statusreturn/Rakefile
MacRuby/trunk/test/test-mri/test/rake/data/unittest/
MacRuby/trunk/test/test-mri/test/rake/data/unittest/Rakefile
MacRuby/trunk/test/test-mri/test/rake/data/unittest/subdir/
MacRuby/trunk/test/test-mri/test/rake/data/unittest/subdir/.gitignore
MacRuby/trunk/test/test-mri/test/rake/filecreation.rb
MacRuby/trunk/test/test-mri/test/rake/in_environment.rb
MacRuby/trunk/test/test-mri/test/rake/rake_test_setup.rb
MacRuby/trunk/test/test-mri/test/rake/reqfile.rb
MacRuby/trunk/test/test-mri/test/rake/reqfile2.rb
MacRuby/trunk/test/test-mri/test/rake/reqfile3.rb
MacRuby/trunk/test/test-mri/test/rake/shellcommand.rb
MacRuby/trunk/test/test-mri/test/rake/test_application.rb
MacRuby/trunk/test/test-mri/test/rake/test_clean.rb
MacRuby/trunk/test/test-mri/test/rake/test_definitions.rb
MacRuby/trunk/test/test-mri/test/rake/test_earlytime.rb
MacRuby/trunk/test/test-mri/test/rake/test_extension.rb
MacRuby/trunk/test/test-mri/test/rake/test_file_creation_task.rb
MacRuby/trunk/test/test-mri/test/rake/test_file_task.rb
MacRuby/trunk/test/test-mri/test/rake/test_filelist.rb
MacRuby/trunk/test/test-mri/test/rake/test_fileutils.rb
MacRuby/trunk/test/test-mri/test/rake/test_invocation_chain.rb
MacRuby/trunk/test/test-mri/test/rake/test_makefile_loader.rb
MacRuby/trunk/test/test-mri/test/rake/test_multitask.rb
MacRuby/trunk/test/test-mri/test/rake/test_namespace.rb
MacRuby/trunk/test/test-mri/test/rake/test_package_task.rb
MacRuby/trunk/test/test-mri/test/rake/test_pathmap.rb
MacRuby/trunk/test/test-mri/test/rake/test_pseudo_status.rb
MacRuby/trunk/test/test-mri/test/rake/test_rake.rb
MacRuby/trunk/test/test-mri/test/rake/test_rdoc_task.rb
MacRuby/trunk/test/test-mri/test/rake/test_require.rb
MacRuby/trunk/test/test-mri/test/rake/test_rules.rb
MacRuby/trunk/test/test-mri/test/rake/test_task_arguments.rb
MacRuby/trunk/test/test-mri/test/rake/test_task_manager.rb
MacRuby/trunk/test/test-mri/test/rake/test_tasklib.rb
MacRuby/trunk/test/test-mri/test/rake/test_tasks.rb
MacRuby/trunk/test/test-mri/test/rake/test_test_task.rb
MacRuby/trunk/test/test-mri/test/rake/test_top_level_functions.rb
MacRuby/trunk/test/test-mri/test/rake/test_win32.rb
MacRuby/trunk/test/test-mri/test/rdoc/
MacRuby/trunk/test/test-mri/test/rdoc/README
MacRuby/trunk/test/test-mri/test/rdoc/binary.dat
MacRuby/trunk/test/test-mri/test/rdoc/hidden.zip.txt
MacRuby/trunk/test/test-mri/test/rdoc/parsers/
MacRuby/trunk/test/test-mri/test/rdoc/parsers/.gitignore
MacRuby/trunk/test/test-mri/test/rdoc/test.ja.rdoc
MacRuby/trunk/test/test-mri/test/rdoc/test.ja.txt
MacRuby/trunk/test/test-mri/test/rdoc/test.txt
MacRuby/trunk/test/test-mri/test/rdoc/test_attribute_manager.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_any_method.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_attr.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_class_module.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_code_object.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_constant.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_context.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_generator_ri.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_include.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_attribute_manager.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_document.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_paragraph.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_parser.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_pre_process.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_raw.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_ansi.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_bs.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_html.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_html_crossref.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_rdoc.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_normal_class.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_normal_module.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_options.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_c.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_perl.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_ruby.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_simple.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_rdoc.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_require.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_ri_driver.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_ri_paths.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_ri_store.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_task.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_text.rb
MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_top_level.rb
MacRuby/trunk/test/test-mri/test/rdoc/xref_data.rb
MacRuby/trunk/test/test-mri/test/rdoc/xref_test_case.rb
MacRuby/trunk/test/test-mri/test/readline/
MacRuby/trunk/test/test-mri/test/readline/test_readline.rb
MacRuby/trunk/test/test-mri/test/readline/test_readline_history.rb
MacRuby/trunk/test/test-mri/test/resolv/
MacRuby/trunk/test/test-mri/test/resolv/test_addr.rb
MacRuby/trunk/test/test-mri/test/resolv/test_dns.rb
MacRuby/trunk/test/test-mri/test/rexml/
MacRuby/trunk/test/test-mri/test/rexml/test_document.rb
MacRuby/trunk/test/test-mri/test/rinda/
MacRuby/trunk/test/test-mri/test/rinda/test_rinda.rb
MacRuby/trunk/test/test-mri/test/rinda/test_tuplebag.rb
MacRuby/trunk/test/test-mri/test/ripper/
MacRuby/trunk/test/test-mri/test/ripper/dummyparser.rb
MacRuby/trunk/test/test-mri/test/ripper/test_files.rb
MacRuby/trunk/test/test-mri/test/ripper/test_filter.rb
MacRuby/trunk/test/test-mri/test/ripper/test_parser_events.rb
MacRuby/trunk/test/test-mri/test/ripper/test_scanner_events.rb
MacRuby/trunk/test/test-mri/test/rss/
MacRuby/trunk/test/test-mri/test/rss/dot.png
MacRuby/trunk/test/test-mri/test/rss/rss-assertions.rb
MacRuby/trunk/test/test-mri/test/rss/rss-testcase.rb
MacRuby/trunk/test/test-mri/test/rss/test_1.0.rb
MacRuby/trunk/test/test-mri/test/rss/test_2.0.rb
MacRuby/trunk/test/test-mri/test/rss/test_accessor.rb
MacRuby/trunk/test/test-mri/test/rss/test_atom.rb
MacRuby/trunk/test/test-mri/test/rss/test_content.rb
MacRuby/trunk/test/test-mri/test/rss/test_dublincore.rb
MacRuby/trunk/test/test-mri/test/rss/test_image.rb
MacRuby/trunk/test/test-mri/test/rss/test_inherit.rb
MacRuby/trunk/test/test-mri/test/rss/test_itunes.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_0.9.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_1.0.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_2.0.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_atom_entry.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_atom_feed.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_content.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_dc.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_image.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_itunes.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_slash.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_sy.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_taxo.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_trackback.rb
MacRuby/trunk/test/test-mri/test/rss/test_maker_xml-stylesheet.rb
MacRuby/trunk/test/test-mri/test/rss/test_parser.rb
MacRuby/trunk/test/test-mri/test/rss/test_parser_1.0.rb
MacRuby/trunk/test/test-mri/test/rss/test_parser_2.0.rb
MacRuby/trunk/test/test-mri/test/rss/test_parser_atom_entry.rb
MacRuby/trunk/test/test-mri/test/rss/test_parser_atom_feed.rb
MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_0.9.rb
MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_1.0.rb
MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_2.0.rb
MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_atom_entry.rb
MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_atom_feed.rb
MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_itunes.rb
MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_slash.rb
MacRuby/trunk/test/test-mri/test/rss/test_slash.rb
MacRuby/trunk/test/test-mri/test/rss/test_syndication.rb
MacRuby/trunk/test/test-mri/test/rss/test_taxonomy.rb
MacRuby/trunk/test/test-mri/test/rss/test_to_s.rb
MacRuby/trunk/test/test-mri/test/rss/test_trackback.rb
MacRuby/trunk/test/test-mri/test/rss/test_version.rb
MacRuby/trunk/test/test-mri/test/rss/test_xml-stylesheet.rb
MacRuby/trunk/test/test-mri/test/ruby/
MacRuby/trunk/test/test-mri/test/ruby/allpairs.rb
MacRuby/trunk/test/test-mri/test/ruby/beginmainend.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/
MacRuby/trunk/test/test-mri/test/ruby/enc/test_big5.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_cp949.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_emoji.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_euc_jp.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_euc_kr.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_euc_tw.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_gb18030.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_gbk.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_iso_8859.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_koi8.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_shift_jis.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_utf16.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_utf32.rb
MacRuby/trunk/test/test-mri/test/ruby/enc/test_windows_1251.rb
MacRuby/trunk/test/test-mri/test/ruby/endblockwarn_rb
MacRuby/trunk/test/test-mri/test/ruby/envutil.rb
MacRuby/trunk/test/test-mri/test/ruby/lbtest.rb
MacRuby/trunk/test/test-mri/test/ruby/marshaltestlib.rb
MacRuby/trunk/test/test-mri/test/ruby/sentence.rb
MacRuby/trunk/test/test-mri/test/ruby/test_alias.rb
MacRuby/trunk/test/test-mri/test/ruby/test_argf.rb
MacRuby/trunk/test/test-mri/test/ruby/test_array.rb
MacRuby/trunk/test/test-mri/test/ruby/test_assignment.rb
MacRuby/trunk/test/test-mri/test/ruby/test_autoload.rb
MacRuby/trunk/test/test-mri/test/ruby/test_basicinstructions.rb
MacRuby/trunk/test/test-mri/test/ruby/test_beginendblock.rb
MacRuby/trunk/test/test-mri/test/ruby/test_bignum.rb
MacRuby/trunk/test/test-mri/test/ruby/test_call.rb
MacRuby/trunk/test/test-mri/test/ruby/test_case.rb
MacRuby/trunk/test/test-mri/test/ruby/test_class.rb
MacRuby/trunk/test/test-mri/test/ruby/test_clone.rb
MacRuby/trunk/test/test-mri/test/ruby/test_comparable.rb
MacRuby/trunk/test/test-mri/test/ruby/test_complex.rb
MacRuby/trunk/test/test-mri/test/ruby/test_complex2.rb
MacRuby/trunk/test/test-mri/test/ruby/test_complexrational.rb
MacRuby/trunk/test/test-mri/test/ruby/test_condition.rb
MacRuby/trunk/test/test-mri/test/ruby/test_const.rb
MacRuby/trunk/test/test-mri/test/ruby/test_continuation.rb
MacRuby/trunk/test/test-mri/test/ruby/test_defined.rb
MacRuby/trunk/test/test-mri/test/ruby/test_dir.rb
MacRuby/trunk/test/test-mri/test/ruby/test_dir_m17n.rb
MacRuby/trunk/test/test-mri/test/ruby/test_econv.rb
MacRuby/trunk/test/test-mri/test/ruby/test_encoding.rb
MacRuby/trunk/test/test-mri/test/ruby/test_enum.rb
MacRuby/trunk/test/test-mri/test/ruby/test_enumerator.rb
MacRuby/trunk/test/test-mri/test/ruby/test_env.rb
MacRuby/trunk/test/test-mri/test/ruby/test_eval.rb
MacRuby/trunk/test/test-mri/test/ruby/test_exception.rb
MacRuby/trunk/test/test-mri/test/ruby/test_fiber.rb
MacRuby/trunk/test/test-mri/test/ruby/test_file.rb
MacRuby/trunk/test/test-mri/test/ruby/test_file_exhaustive.rb
MacRuby/trunk/test/test-mri/test/ruby/test_fixnum.rb
MacRuby/trunk/test/test-mri/test/ruby/test_float.rb
MacRuby/trunk/test/test-mri/test/ruby/test_fnmatch.rb
MacRuby/trunk/test/test-mri/test/ruby/test_gc.rb
MacRuby/trunk/test/test-mri/test/ruby/test_hash.rb
MacRuby/trunk/test/test-mri/test/ruby/test_ifunless.rb
MacRuby/trunk/test/test-mri/test/ruby/test_integer.rb
MacRuby/trunk/test/test-mri/test/ruby/test_integer_comb.rb
MacRuby/trunk/test/test-mri/test/ruby/test_io.rb
MacRuby/trunk/test/test-mri/test/ruby/test_io_m17n.rb
MacRuby/trunk/test/test-mri/test/ruby/test_iterator.rb
MacRuby/trunk/test/test-mri/test/ruby/test_lambda.rb
MacRuby/trunk/test/test-mri/test/ruby/test_literal.rb
MacRuby/trunk/test/test-mri/test/ruby/test_m17n.rb
MacRuby/trunk/test/test-mri/test/ruby/test_m17n_comb.rb
MacRuby/trunk/test/test-mri/test/ruby/test_marshal.rb
MacRuby/trunk/test/test-mri/test/ruby/test_math.rb
MacRuby/trunk/test/test-mri/test/ruby/test_metaclass.rb
MacRuby/trunk/test/test-mri/test/ruby/test_method.rb
MacRuby/trunk/test/test-mri/test/ruby/test_mixed_unicode_escapes.rb
MacRuby/trunk/test/test-mri/test/ruby/test_module.rb
MacRuby/trunk/test/test-mri/test/ruby/test_notimp.rb
MacRuby/trunk/test/test-mri/test/ruby/test_numeric.rb
MacRuby/trunk/test/test-mri/test/ruby/test_object.rb
MacRuby/trunk/test/test-mri/test/ruby/test_objectspace.rb
MacRuby/trunk/test/test-mri/test/ruby/test_optimization.rb
MacRuby/trunk/test/test-mri/test/ruby/test_pack.rb
MacRuby/trunk/test/test-mri/test/ruby/test_parse.rb
MacRuby/trunk/test/test-mri/test/ruby/test_path.rb
MacRuby/trunk/test/test-mri/test/ruby/test_pipe.rb
MacRuby/trunk/test/test-mri/test/ruby/test_primitive.rb
MacRuby/trunk/test/test-mri/test/ruby/test_proc.rb
MacRuby/trunk/test/test-mri/test/ruby/test_process.rb
MacRuby/trunk/test/test-mri/test/ruby/test_rand.rb
MacRuby/trunk/test/test-mri/test/ruby/test_range.rb
MacRuby/trunk/test/test-mri/test/ruby/test_rational.rb
MacRuby/trunk/test/test-mri/test/ruby/test_rational2.rb
MacRuby/trunk/test/test-mri/test/ruby/test_readpartial.rb
MacRuby/trunk/test/test-mri/test/ruby/test_regexp.rb
MacRuby/trunk/test/test-mri/test/ruby/test_require.rb
MacRuby/trunk/test/test-mri/test/ruby/test_rubyoptions.rb
MacRuby/trunk/test/test-mri/test/ruby/test_settracefunc.rb
MacRuby/trunk/test/test-mri/test/ruby/test_signal.rb
MacRuby/trunk/test/test-mri/test/ruby/test_sleep.rb
MacRuby/trunk/test/test-mri/test/ruby/test_sprintf.rb
MacRuby/trunk/test/test-mri/test/ruby/test_sprintf_comb.rb
MacRuby/trunk/test/test-mri/test/ruby/test_string.rb
MacRuby/trunk/test/test-mri/test/ruby/test_stringchar.rb
MacRuby/trunk/test/test-mri/test/ruby/test_struct.rb
MacRuby/trunk/test/test-mri/test/ruby/test_super.rb
MacRuby/trunk/test/test-mri/test/ruby/test_symbol.rb
MacRuby/trunk/test/test-mri/test/ruby/test_system.rb
MacRuby/trunk/test/test-mri/test/ruby/test_thread.rb
MacRuby/trunk/test/test-mri/test/ruby/test_time.rb
MacRuby/trunk/test/test-mri/test/ruby/test_time_tz.rb
MacRuby/trunk/test/test-mri/test/ruby/test_trace.rb
MacRuby/trunk/test/test-mri/test/ruby/test_transcode.rb
MacRuby/trunk/test/test-mri/test/ruby/test_undef.rb
MacRuby/trunk/test/test-mri/test/ruby/test_unicode_escape.rb
MacRuby/trunk/test/test-mri/test/ruby/test_variable.rb
MacRuby/trunk/test/test-mri/test/ruby/test_whileuntil.rb
MacRuby/trunk/test/test-mri/test/ruby/test_yield.rb
MacRuby/trunk/test/test-mri/test/ruby/ut_eof.rb
MacRuby/trunk/test/test-mri/test/rubygems/
MacRuby/trunk/test/test-mri/test/rubygems/bogussources.rb
MacRuby/trunk/test/test-mri/test/rubygems/data/
MacRuby/trunk/test/test-mri/test/rubygems/data/gem-private_key.pem
MacRuby/trunk/test/test-mri/test/rubygems/data/gem-public_cert.pem
MacRuby/trunk/test/test-mri/test/rubygems/fake_certlib/
MacRuby/trunk/test/test-mri/test/rubygems/fake_certlib/openssl.rb
MacRuby/trunk/test/test-mri/test/rubygems/foo/
MacRuby/trunk/test/test-mri/test/rubygems/foo/discover.rb
MacRuby/trunk/test/test-mri/test/rubygems/functional.rb
MacRuby/trunk/test/test-mri/test/rubygems/gem_installer_test_case.rb
MacRuby/trunk/test/test-mri/test/rubygems/gem_package_tar_test_case.rb
MacRuby/trunk/test/test-mri/test/rubygems/gems/
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/rubygems-bug-child-1.0/
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/rubygems-bug-child-1.0/lib/
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/rubygems-bug-child-1.0/lib/.gitignore
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/rubygems-bug-child-1.1/
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/rubygems-bug-child-1.1/lib/
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/rubygems-bug-child-1.1/lib/.gitignore
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/rubygems-bug-parent-1.0/
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/rubygems-bug-parent-1.0/lib/
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/rubygems-bug-parent-1.0/lib/.gitignore
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/specifications/
MacRuby/trunk/test/test-mri/test/rubygems/gems/current/specifications/.gitignore
MacRuby/trunk/test/test-mri/test/rubygems/gemutilities.rb
MacRuby/trunk/test/test-mri/test/rubygems/insure_session.rb
MacRuby/trunk/test/test-mri/test/rubygems/mockgemui.rb
MacRuby/trunk/test/test-mri/test/rubygems/plugin/
MacRuby/trunk/test/test-mri/test/rubygems/plugin/exception/
MacRuby/trunk/test/test-mri/test/rubygems/plugin/exception/rubygems_plugin.rb
MacRuby/trunk/test/test-mri/test/rubygems/plugin/load/
MacRuby/trunk/test/test-mri/test/rubygems/plugin/load/rubygems_plugin.rb
MacRuby/trunk/test/test-mri/test/rubygems/plugin/standarderror/
MacRuby/trunk/test/test-mri/test/rubygems/plugin/standarderror/rubygems_plugin.rb
MacRuby/trunk/test/test-mri/test/rubygems/private_key.pem
MacRuby/trunk/test/test-mri/test/rubygems/public_cert.pem
MacRuby/trunk/test/test-mri/test/rubygems/rubygems/
MacRuby/trunk/test/test-mri/test/rubygems/rubygems/commands/
MacRuby/trunk/test/test-mri/test/rubygems/rubygems/commands/crash_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/rubygems_plugin.rb
MacRuby/trunk/test/test-mri/test/rubygems/simple_gem.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_config.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_activation.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_builder.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_command_manager.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_build_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_cert_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_check_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_contents_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_dependency_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_environment_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_fetch_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_generate_index_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_install_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_list_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_lock_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_mirror_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_outdated_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_owner_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_pristine_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_push_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_query_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_server_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_sources_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_specification_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_stale_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_uninstall_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_unpack_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_update_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_which_command.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_config_file.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_dependency.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_dependency_installer.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_dependency_list.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_doc_manager.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_ext_configure_builder.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_ext_ext_conf_builder.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_ext_rake_builder.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_format.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_gem_path_searcher.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_gem_runner.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_gemcutter_utilities.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_indexer.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_install_update_options.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_installer.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_local_remote_options.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_header.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_input.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_output.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_reader.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_reader_entry.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_writer.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_task.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_platform.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_remote_fetcher.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_requirement.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_server.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_source_index.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_spec_fetcher.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_specification.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_stream_ui.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_uninstaller.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_validator.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_version.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_gem_version_option.rb
MacRuby/trunk/test/test-mri/test/rubygems/test_kernel.rb
MacRuby/trunk/test/test-mri/test/runner.rb
MacRuby/trunk/test/test-mri/test/scanf/
MacRuby/trunk/test/test-mri/test/scanf/data.txt
MacRuby/trunk/test/test-mri/test/scanf/test_scanf.rb
MacRuby/trunk/test/test-mri/test/scanf/test_scanfblocks.rb
MacRuby/trunk/test/test-mri/test/scanf/test_scanfio.rb
MacRuby/trunk/test/test-mri/test/sdbm/
MacRuby/trunk/test/test-mri/test/sdbm/test_sdbm.rb
MacRuby/trunk/test/test-mri/test/socket/
MacRuby/trunk/test/test-mri/test/socket/test_addrinfo.rb
MacRuby/trunk/test/test-mri/test/socket/test_ancdata.rb
MacRuby/trunk/test/test-mri/test/socket/test_basicsocket.rb
MacRuby/trunk/test/test-mri/test/socket/test_nonblock.rb
MacRuby/trunk/test/test-mri/test/socket/test_socket.rb
MacRuby/trunk/test/test-mri/test/socket/test_sockopt.rb
MacRuby/trunk/test/test-mri/test/socket/test_tcp.rb
MacRuby/trunk/test/test-mri/test/socket/test_udp.rb
MacRuby/trunk/test/test-mri/test/socket/test_unix.rb
MacRuby/trunk/test/test-mri/test/stringio/
MacRuby/trunk/test/test-mri/test/stringio/test_stringio.rb
MacRuby/trunk/test/test-mri/test/strscan/
MacRuby/trunk/test/test-mri/test/strscan/test_stringscanner.rb
MacRuby/trunk/test/test-mri/test/syck/
MacRuby/trunk/test/test-mri/test/syck/test_array.rb
MacRuby/trunk/test/test-mri/test/syck/test_boolean.rb
MacRuby/trunk/test/test-mri/test/syck/test_class.rb
MacRuby/trunk/test/test-mri/test/syck/test_engine_manager.rb
MacRuby/trunk/test/test-mri/test/syck/test_exception.rb
MacRuby/trunk/test/test-mri/test/syck/test_hash.rb
MacRuby/trunk/test/test-mri/test/syck/test_null.rb
MacRuby/trunk/test/test-mri/test/syck/test_omap.rb
MacRuby/trunk/test/test-mri/test/syck/test_set.rb
MacRuby/trunk/test/test-mri/test/syck/test_string.rb
MacRuby/trunk/test/test-mri/test/syck/test_struct.rb
MacRuby/trunk/test/test-mri/test/syck/test_symbol.rb
MacRuby/trunk/test/test-mri/test/syck/test_yaml.rb
MacRuby/trunk/test/test-mri/test/syck/test_yaml_properties.rb
MacRuby/trunk/test/test-mri/test/syck/test_yamlstore.rb
MacRuby/trunk/test/test-mri/test/test_delegate.rb
MacRuby/trunk/test/test-mri/test/test_find.rb
MacRuby/trunk/test/test-mri/test/test_ipaddr.rb
MacRuby/trunk/test/test-mri/test/test_mathn.rb
MacRuby/trunk/test/test-mri/test/test_open3.rb
MacRuby/trunk/test/test-mri/test/test_pp.rb
MacRuby/trunk/test/test-mri/test/test_prettyprint.rb
MacRuby/trunk/test/test-mri/test/test_prime.rb
MacRuby/trunk/test/test-mri/test/test_pstore.rb
MacRuby/trunk/test/test-mri/test/test_pty.rb
MacRuby/trunk/test/test-mri/test/test_set.rb
MacRuby/trunk/test/test-mri/test/test_shellwords.rb
MacRuby/trunk/test/test-mri/test/test_singleton.rb
MacRuby/trunk/test/test-mri/test/test_syslog.rb
MacRuby/trunk/test/test-mri/test/test_tempfile.rb
MacRuby/trunk/test/test-mri/test/test_time.rb
MacRuby/trunk/test/test-mri/test/test_timeout.rb
MacRuby/trunk/test/test-mri/test/test_tsort.rb
MacRuby/trunk/test/test-mri/test/testunit/
MacRuby/trunk/test/test-mri/test/testunit/test_assertion.rb
MacRuby/trunk/test/test-mri/test/thread/
MacRuby/trunk/test/test-mri/test/thread/test_queue.rb
MacRuby/trunk/test/test-mri/test/uri/
MacRuby/trunk/test/test-mri/test/uri/test_common.rb
MacRuby/trunk/test/test-mri/test/uri/test_ftp.rb
MacRuby/trunk/test/test-mri/test/uri/test_generic.rb
MacRuby/trunk/test/test-mri/test/uri/test_http.rb
MacRuby/trunk/test/test-mri/test/uri/test_ldap.rb
MacRuby/trunk/test/test-mri/test/uri/test_mailto.rb
MacRuby/trunk/test/test-mri/test/uri/test_parser.rb
MacRuby/trunk/test/test-mri/test/webrick/
MacRuby/trunk/test/test-mri/test/webrick/.htaccess
MacRuby/trunk/test/test-mri/test/webrick/test_cgi.rb
MacRuby/trunk/test/test-mri/test/webrick/test_cookie.rb
MacRuby/trunk/test/test-mri/test/webrick/test_filehandler.rb
MacRuby/trunk/test/test-mri/test/webrick/test_httpauth.rb
MacRuby/trunk/test/test-mri/test/webrick/test_httpproxy.rb
MacRuby/trunk/test/test-mri/test/webrick/test_httprequest.rb
MacRuby/trunk/test/test-mri/test/webrick/test_httpserver.rb
MacRuby/trunk/test/test-mri/test/webrick/test_httputils.rb
MacRuby/trunk/test/test-mri/test/webrick/test_httpversion.rb
MacRuby/trunk/test/test-mri/test/webrick/test_server.rb
MacRuby/trunk/test/test-mri/test/webrick/test_utils.rb
MacRuby/trunk/test/test-mri/test/webrick/utils.rb
MacRuby/trunk/test/test-mri/test/webrick/webrick.cgi
MacRuby/trunk/test/test-mri/test/webrick/webrick_long_filename.cgi
MacRuby/trunk/test/test-mri/test/win32ole/
MacRuby/trunk/test/test-mri/test/win32ole/err_in_callback.rb
MacRuby/trunk/test/test-mri/test/win32ole/orig_data.csv
MacRuby/trunk/test/test-mri/test/win32ole/test_err_in_callback.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_folderitem2_invokeverb.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_nil2vtempty.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_ole_methods.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_propertyputref.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_event.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_method.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_param.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_type.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_typelib.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variable.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variant.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variant_m.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variant_outarg.rb
MacRuby/trunk/test/test-mri/test/win32ole/test_word.rb
MacRuby/trunk/test/test-mri/test/xmlrpc/
MacRuby/trunk/test/test-mri/test/xmlrpc/data/
MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_bool.expected
MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_bool.xml
MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_cdata.expected
MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_cdata.xml
MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_covert.expected
MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_covert.xml
MacRuby/trunk/test/test-mri/test/xmlrpc/data/datetime_iso8601.xml
MacRuby/trunk/test/test-mri/test/xmlrpc/data/fault.xml
MacRuby/trunk/test/test-mri/test/xmlrpc/data/value.expected
MacRuby/trunk/test/test-mri/test/xmlrpc/data/value.xml
MacRuby/trunk/test/test-mri/test/xmlrpc/data/xml1.expected
MacRuby/trunk/test/test-mri/test/xmlrpc/data/xml1.xml
MacRuby/trunk/test/test-mri/test/xmlrpc/test_cookie.rb
MacRuby/trunk/test/test-mri/test/xmlrpc/test_datetime.rb
MacRuby/trunk/test/test-mri/test/xmlrpc/test_features.rb
MacRuby/trunk/test/test-mri/test/xmlrpc/test_marshal.rb
MacRuby/trunk/test/test-mri/test/xmlrpc/test_parser.rb
MacRuby/trunk/test/test-mri/test/xmlrpc/test_webrick_server.rb
MacRuby/trunk/test/test-mri/test/xmlrpc/webrick_testing.rb
MacRuby/trunk/test/test-mri/test/zlib/
MacRuby/trunk/test/test-mri/test/zlib/test_zlib.rb
Added: MacRuby/trunk/test/test-mri/README
===================================================================
--- MacRuby/trunk/test/test-mri/README (rev 0)
+++ MacRuby/trunk/test/test-mri/README 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,27 @@
+* About
+
+ This is a unit test for MacRuby which based on Ruby 1.9.2.
+
+* Test
+
+ Execute the unit test following commands.
+ $ rake
+
+ Test results are stored in "result" directory.
+
+* Bootstraptest
+
+ Execute the unit test following commands.
+ $ cd bootstraptest
+ $ ./runner.rb
+
+* Attention
+
+ 1. The zombi process of MacRuby might be generated with Test.
+ When kills all MacRuby process,
+ $ rake kill
+
+ 2. The "~/.gemrc" and "~/.gem" might be changed with Test.
+ Please back up beforehand.
+
+ 3. Now, it takes around 1 hour till Test is completed.
Added: MacRuby/trunk/test/test-mri/Rakefile
===================================================================
--- MacRuby/trunk/test/test-mri/Rakefile (rev 0)
+++ MacRuby/trunk/test/test-mri/Rakefile 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,55 @@
+GET_LOG_SEGFAULT = true
+DIR_RESULT = "result"
+
+task :default do
+ date = Time.now.strftime('%Y-%m-%d-%H%M%S')
+ output = "log_#{date}.txt"
+ error = "crash_#{date}.txt"
+ opts = ENV['opts'] || ""
+ macruby = ENV['ruby'] || "/usr/local/bin/macruby"
+
+ unless(File.directory?(DIR_RESULT))
+ Dir.mkdir(DIR_RESULT)
+ end
+
+ test_files = Dir.glob(File.join('test', '**/test_*'))
+ test_files.each do |file|
+ # run test
+ if(GET_LOG_SEGFAULT)
+ puts file
+ system "sh -c './bin/timeout -t 180 #{macruby} -r require_relative.rb #{file} #{opts} >> #{DIR_RESULT}/#{output} 2>&1' >> #{DIR_RESULT}/#{error} 2>&1"
+ else
+ system "./bin/timeout -t 180 #{macruby} -r require_relative.rb #{file} #{opts} 2>&1 | tee -a -i #{DIR_RESULT}/#{output}"
+ end
+
+ # kill watchdog
+ ps = `ps | grep sleep`
+ ps.each_line do |line|
+ info = line.split(/\s+/)
+ pid = info[0]
+ pname = info[3]
+
+ if(pname == "sleep")
+ system "kill -KILL #{pid}"
+ end
+ end
+ end
+
+end
+
+task :kill do
+ require 'pp'
+
+ COMMAND = "ps aux | grep macruby"
+ result = `#{COMMAND}`
+
+ prc = result.split("\n")
+ pp prc
+ prc.each do |line|
+ unless(line =~ /#{COMMAND}/)
+ process = line.split(/\s+/)[1]
+ sh "kill -KILL #{process}"
+ end
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/bin/timeout
===================================================================
--- MacRuby/trunk/test/test-mri/bin/timeout (rev 0)
+++ MacRuby/trunk/test/test-mri/bin/timeout 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,61 @@
+#!/usr/bin/env bash
+#
+# adapted from http://www.shelldorado.com/scripts/cmds/timeout
+
+NAME=`basename "$0"` # Program name
+VERSION='1.3'
+
+TIMEOUT=10 # Default [seconds]
+
+usage () {
+ echo >&2 "$NAME - set timeout for a command, $VERSION
+usage: $NAME [-t timeout] command [argument ...]
+ -t: timeout (in seconds, default is $TIMEOUT)"
+ exit 1
+}
+
+message () {
+ for msg_line
+ do echo "$NAME: $msg_line" >&2
+ done
+}
+
+fatal () { message "$@"; exit 1; }
+
+while [ $# -gt 0 ]
+do
+ case "$1" in
+ -p) parent_pid=$2; shift;; # Used internally!
+ -t) time_out="$2"; shift;;
+ --) shift; break;;
+ -h) usage;;
+ -*) usage;;
+ *) break;; # First file name
+ esac
+ shift
+done
+
+: ${time_out:=$TIMEOUT} # Set default [seconds]
+
+if [ -z "$parent_pid" ]
+then
+ # This is the first invokation of this script.
+ # Start "watchdog" process, and then run the command.
+ [ $# -lt 1 ] && fatal "please specify a command to execute"
+ "$0" -p $$ -t $time_out & # Start watchdog
+ #echo >&2 "DEBUG: process id is $$"
+ exec "$@" # Run command
+ exit 2 # NOT REACHED
+else
+ # We run in "watchdog" mode, $parent_pid contains the PID
+ # of the process we should terminate after $time_out seconds.
+ [ $# -ne 0 ] && fatal "please do not use -p option interactively"
+
+ #echo >&2 "DEBUG: $$: parent PID to terminate is $parent_pid"
+
+ exec >/dev/null 0<&1 2>&1 # Suppress error messages
+ sleep $time_out
+ kill $parent_pid && # Give process time to terminate
+ (sleep 2; kill -1 $parent_pid) && (sleep 2; kill -9 $parent_pid)
+ exit 0
+fi
Property changes on: MacRuby/trunk/test/test-mri/bin/timeout
___________________________________________________________________
Added: svn:executable
+ *
Added: MacRuby/trunk/test/test-mri/bootstraptest/pending.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/pending.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/pending.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,39 @@
+assert_equal 'A', %q{
+ class A
+ @@a = 'A'
+ def a=(x)
+ @@a = x
+ end
+ def a
+ @@a
+ end
+ end
+
+ B = A.dup
+ B.new.a = 'B'
+ A.new.a
+}, '[ruby-core:17019]'
+
+assert_equal 'ok', %q{
+ def m
+ lambda{
+ proc{
+ return :ng1
+ }
+ }.call.call
+ :ng2
+ end
+
+ begin
+ m()
+ rescue LocalJumpError
+ :ok
+ end
+}
+
+assert_normal_exit %q{
+ r = Range.allocate
+ def r.<=>(o) true end
+ r.instance_eval { initialize r, r }
+ r.inspect
+}
Added: MacRuby/trunk/test/test-mri/bootstraptest/runner.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/runner.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/runner.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,398 @@
+"exec" "${RUBY-ruby}" "-x" "$0" "$@"; true # -*- mode: ruby; coding: utf-8 -*-
+#!./ruby
+# $Id: runner.rb 26700 2010-02-17 12:27:34Z akr $
+
+# NOTE:
+# Never use optparse in this file.
+# Never use test/unit in this file.
+# Never use Ruby extensions in this file.
+
+begin
+ require 'fileutils'
+ require 'tmpdir'
+rescue LoadError
+ $:.unshift File.join(File.dirname(__FILE__), '../lib')
+ retry
+end
+
+if !Dir.respond_to?(:mktmpdir)
+ # copied from lib/tmpdir.rb
+ def Dir.mktmpdir(prefix_suffix=nil, tmpdir=nil)
+ case prefix_suffix
+ when nil
+ prefix = "d"
+ suffix = ""
+ when String
+ prefix = prefix_suffix
+ suffix = ""
+ when Array
+ prefix = prefix_suffix[0]
+ suffix = prefix_suffix[1]
+ else
+ raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
+ end
+ tmpdir ||= Dir.tmpdir
+ t = Time.now.strftime("%Y%m%d")
+ n = nil
+ begin
+ path = "#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"
+ path << "-#{n}" if n
+ path << suffix
+ Dir.mkdir(path, 0700)
+ rescue Errno::EEXIST
+ n ||= 0
+ n += 1
+ retry
+ end
+
+ if block_given?
+ begin
+ yield path
+ ensure
+ FileUtils.remove_entry_secure path
+ end
+ else
+ path
+ end
+ end
+end
+
+def main
+ @ruby = "/usr/local/bin/macruby"
+ @verbose = false
+ dir = nil
+ quiet = false
+ tests = nil
+ ARGV.delete_if {|arg|
+ case arg
+ when /\A--ruby=(.*)/
+ @ruby = $1
+ @ruby.gsub!(/^([^ ]*)/){File.expand_path($1)}
+ @ruby.gsub!(/(\s+-I\s*)((?!(?:\.\/)*-(?:\s|\z))\S+)/){$1+File.expand_path($2)}
+ @ruby.gsub!(/(\s+-r\s*)(\.\.?\/\S+)/){$1+File.expand_path($2)}
+ true
+ when /\A--sets=(.*)/
+ tests = Dir.glob("#{File.dirname($0)}/test_{#{$1}}*.rb").sort
+ puts tests.map {|path| File.basename(path) }.inspect
+ true
+ when /\A--dir=(.*)/
+ dir = $1
+ true
+ when /\A(--stress|-s)/
+ $stress = true
+ when /\A(-q|--q(uiet))\z/
+ quiet = true
+ true
+ when /\A(-v|--v(erbose))\z/
+ @verbose = true
+ when /\A(-h|--h(elp)?)\z/
+ puts(<<-End)
+Usage: #{File.basename($0, '.*')} --ruby=PATH [--sets=NAME,NAME,...]
+ --sets=NAME,NAME,... Name of test sets.
+ --dir=DIRECTORY Working directory.
+ default: /tmp/bootstraptestXXXXX.tmpwd
+ -s, --stress stress test.
+ -v, --verbose Output test name before exec.
+ -q, --quiet Don\'t print header message.
+ -h, --help Print this message and quit.
+End
+ exit true
+ else
+ false
+ end
+ }
+ if tests and not ARGV.empty?
+ $stderr.puts "--tests and arguments are exclusive"
+ exit false
+ end
+ tests ||= ARGV
+ tests = Dir.glob("#{File.dirname($0)}/test_*.rb").sort if tests.empty?
+ pathes = tests.map {|path| File.expand_path(path) }
+
+ unless quiet
+ puts Time.now
+ if defined?(RUBY_DESCRIPTION)
+ puts "Driver is #{RUBY_DESCRIPTION}"
+ elsif defined?(RUBY_PATCHLEVEL)
+ puts "Driver is ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}#{RUBY_PLATFORM}) [#{RUBY_PLATFORM}]"
+ else
+ puts "Driver is ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
+ end
+ puts "Target is #{`#{@ruby} -v`.chomp}"
+ puts
+ $stdout.flush
+ end
+
+ in_temporary_working_directory(dir) {
+ exec_test pathes
+ }
+end
+
+def exec_test(pathes)
+ @count = 0
+ @error = 0
+ @errbuf = []
+ @location = nil
+ pathes.each do |path|
+ $stderr.print "\n#{File.basename(path)} "
+ load File.expand_path(path)
+ end
+ $stderr.puts
+ if @error == 0
+ if @count == 0
+ $stderr.puts "No tests, no problem"
+ else
+ $stderr.puts "PASS all #{@count} tests"
+ end
+ exit true
+ else
+ @errbuf.each do |msg|
+ $stderr.puts msg
+ end
+ $stderr.puts "FAIL #{@error}/#{@count} tests failed"
+ exit false
+ end
+end
+
+def assert_check(testsrc, message = '', opt = '')
+ $stderr.puts "\##{@count} #{@location}" if @verbose
+ result = get_result_string(testsrc, opt)
+ check_coredump
+ faildesc = yield(result)
+ if !faildesc
+ $stderr.print '.'
+ else
+ $stderr.print 'F'
+ error faildesc, message
+ end
+rescue Exception => err
+ $stderr.print 'E'
+ error err.message, message
+end
+
+def assert_equal(expected, testsrc, message = '')
+ newtest
+ assert_check(testsrc, message) {|result|
+ if expected == result
+ nil
+ else
+ desc = "#{result.inspect} (expected #{expected.inspect})"
+ pretty(testsrc, desc, result)
+ end
+ }
+end
+
+def assert_match(expected_pattern, testsrc, message = '')
+ newtest
+ assert_check(testsrc, message) {|result|
+ if expected_pattern =~ result
+ nil
+ else
+ desc = "#{expected_pattern.inspect} expected to be =~\n#{result.inspect}"
+ pretty(testsrc, desc, result)
+ end
+ }
+end
+
+def assert_not_match(unexpected_pattern, testsrc, message = '')
+ newtest
+ assert_check(testsrc, message) {|result|
+ if unexpected_pattern !~ result
+ nil
+ else
+ desc = "#{unexpected_pattern.inspect} expected to be !~\n#{result.inspect}"
+ pretty(testsrc, desc, result)
+ end
+ }
+end
+
+def assert_valid_syntax(testsrc, message = '')
+ newtest
+ assert_check(testsrc, message, '-c') {|result|
+ result if /Syntax OK/ !~ result
+ }
+end
+
+def assert_normal_exit(testsrc, *rest)
+ opt = {}
+ opt = rest.pop if Hash === rest.last
+ message, ignore_signals = rest
+ message ||= ''
+ timeout = opt[:timeout]
+ newtest
+ $stderr.puts "\##{@count} #{@location}" if @verbose
+ faildesc = nil
+ filename = make_srcfile(testsrc)
+ old_stderr = $stderr.dup
+ timeout_signaled = false
+ begin
+ $stderr.reopen("assert_normal_exit.log", "w")
+ io = IO.popen("#{@ruby} -W0 #{filename}")
+ pid = io.pid
+ th = Thread.new {
+ io.read
+ io.close
+ $?
+ }
+ if !th.join(timeout)
+ Process.kill :KILL, pid
+ timeout_signaled = true
+ end
+ status = th.value
+ ensure
+ $stderr.reopen(old_stderr)
+ old_stderr.close
+ end
+ if status.signaled?
+ signo = status.termsig
+ signame = Signal.list.invert[signo]
+ unless ignore_signals and ignore_signals.include?(signame)
+ sigdesc = "signal #{signo}"
+ if signame
+ sigdesc = "SIG#{signame} (#{sigdesc})"
+ end
+ if timeout_signaled
+ sigdesc << " (timeout)"
+ end
+ faildesc = pretty(testsrc, "killed by #{sigdesc}", nil)
+ stderr_log = File.read("assert_normal_exit.log")
+ if !stderr_log.empty?
+ faildesc << "\n" if /\n\z/ !~ faildesc
+ stderr_log << "\n" if /\n\z/ !~ stderr_log
+ stderr_log.gsub!(/^.*\n/) { '| ' + $& }
+ faildesc << stderr_log
+ end
+ end
+ end
+ if !faildesc
+ $stderr.print '.'
+ true
+ else
+ $stderr.print 'F'
+ error faildesc, message
+ false
+ end
+rescue Exception => err
+ $stderr.print 'E'
+ error err.message, message
+ false
+end
+
+def assert_finish(timeout_seconds, testsrc, message = '')
+ newtest
+ $stderr.puts "\##{@count} #{@location}" if @verbose
+ faildesc = nil
+ filename = make_srcfile(testsrc)
+ io = IO.popen("#{@ruby} -W0 #{filename}")
+ pid = io.pid
+ waited = false
+ tlimit = Time.now + timeout_seconds
+ while Time.now < tlimit
+ if Process.waitpid pid, Process::WNOHANG
+ waited = true
+ break
+ end
+ sleep 0.1
+ end
+ if !waited
+ Process.kill(:KILL, pid)
+ Process.waitpid pid
+ faildesc = pretty(testsrc, "not finished in #{timeout_seconds} seconds", nil)
+ end
+ io.close
+ if !faildesc
+ $stderr.print '.'
+ else
+ $stderr.print 'F'
+ error faildesc, message
+ end
+rescue Exception => err
+ $stderr.print 'E'
+ error err.message, message
+end
+
+def flunk(message = '')
+ newtest
+ $stderr.print 'F'
+ error message, ''
+end
+
+def pretty(src, desc, result)
+ src = src.sub(/\A.*\n/, '')
+ (/\n/ =~ src ? "\n#{adjust_indent(src)}" : src) + " #=> #{desc}"
+end
+
+INDENT = 27
+
+def adjust_indent(src)
+ untabify(src).gsub(/^ {#{INDENT}}/o, '').gsub(/^/, ' ')
+end
+
+def untabify(str)
+ str.gsub(/^\t+/) {' ' * (8 * $&.size) }
+end
+
+def make_srcfile(src)
+ filename = 'bootstraptest.tmp.rb'
+ File.open(filename, 'w') {|f|
+ f.puts "GC.stress = true" if $stress
+ f.puts "print(begin; #{src}; end)"
+ }
+ filename
+end
+
+def get_result_string(src, opt = '')
+ if @ruby
+ filename = make_srcfile(src)
+ begin
+ `#{@ruby} -W0 #{opt} #{filename}`
+ ensure
+ raise CoreDumpError, "core dumped" if $? and $?.coredump?
+ end
+ else
+ eval(src).to_s
+ end
+end
+
+def newtest
+ @location = File.basename(caller(2).first)
+ @count += 1
+ cleanup_coredump
+end
+
+def error(msg, additional_message)
+ @errbuf.push "\##{@count} #{@location}: #{msg} #{additional_message}"
+ @error += 1
+end
+
+def in_temporary_working_directory(dir)
+ if dir
+ Dir.mkdir dir
+ Dir.chdir(dir) {
+ yield
+ }
+ else
+ Dir.mktmpdir(["bootstraptest", ".tmpwd"]) {|d|
+ Dir.chdir(d) {
+ yield
+ }
+ }
+ end
+end
+
+def cleanup_coredump
+ FileUtils.rm_f 'core'
+ FileUtils.rm_f Dir.glob('core.*')
+ FileUtils.rm_f @ruby+'.stackdump' if @ruby
+end
+
+class CoreDumpError < StandardError; end
+
+def check_coredump
+ if File.file?('core') or not Dir.glob('core.*').empty? or
+ (@ruby and File.exist?(@ruby+'.stackdump'))
+ raise CoreDumpError, "core dumped"
+ end
+end
+
+main
Property changes on: MacRuby/trunk/test/test-mri/bootstraptest/runner.rb
___________________________________________________________________
Added: svn:executable
+ *
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_attr.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_attr.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_attr.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,36 @@
+assert_equal 'ok', %q{
+ module M
+ class A
+ class << self
+ attr_accessor :at
+ def workflow_rule
+ yield self
+ end
+
+ def eval_str(str)
+ eval(str)
+ end
+ end
+ end
+ end
+ begin
+ M::A.eval_str(<<-END)
+ workflow_rule do |r|
+ r.at 1
+ end
+ END
+ rescue ArgumentError => e
+ print "ok"
+ end
+}, '[ruby-core:14641]'
+
+assert_equal %{ok}, %{
+ class A
+ attr :m
+ end
+ begin
+ A.new.m(3)
+ rescue ArgumentError => e
+ print "ok"
+ end
+}, '[ruby-core:15120]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_autoload.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_autoload.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_autoload.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,78 @@
+assert_equal 'ok', %q{
+ open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
+ autoload :ZZZ, "./zzz.rb"
+ ZZZ.ok
+}
+
+assert_equal 'ok', %q{
+ open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
+ autoload :ZZZ, "./zzz.rb"
+ require "./zzz.rb"
+ ZZZ.ok
+}
+
+assert_equal 'ok', %q{
+ open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
+ autoload :ZZZ, "./zzz.rb"
+ proc{$SAFE=4; ZZZ.ok}.call
+}
+
+assert_equal 'ok', %q{
+ open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
+ autoload :ZZZ, "./zzz.rb"
+ require "./zzz.rb"
+ proc{$SAFE=4; ZZZ.ok}.call
+}
+
+assert_equal 'ok', %q{
+ open("zzz.rb", "w") {|f| f.puts "class ZZZ; def hoge;:ok;end;end"}
+ autoload :ZZZ, File.join(Dir.pwd, 'zzz.rb')
+ module M; end
+ Thread.new{M.instance_eval('$SAFE=4; ZZZ.new.hoge')}.value
+}
+
+assert_equal 'ok', %q{
+ open("zzz.rb", "w") {|f| f.puts "class ZZZ; def hoge;:ok;end;end"}
+ autoload :ZZZ, File.join(Dir.pwd, 'zzz.rb')
+ module M; end
+ Thread.new{$SAFE=4; M.instance_eval('ZZZ.new.hoge')}.value
+}
+
+assert_equal 'ok', %q{
+ open("zzz.rb", "w") {|f| f.puts "class ZZZ; def hoge;:ok;end;end"}
+ autoload :ZZZ, File.join(Dir.pwd, 'zzz.rb')
+ Thread.new{$SAFE=4; eval('ZZZ.new.hoge')}.value
+}
+
+assert_equal 'ok', %q{
+ open("zzz.rb", "w") {|f| f.puts "class ZZZ; def hoge;:ok;end;end"}
+ autoload :ZZZ, File.join(Dir.pwd, 'zzz.rb')
+ module M; end
+ Thread.new{eval('$SAFE=4; ZZZ.new.hoge')}.value
+}
+
+assert_equal 'okok', %q{
+ open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
+ autoload :ZZZ, "./zzz.rb"
+ t1 = Thread.new {ZZZ.ok}
+ t2 = Thread.new {ZZZ.ok}
+ [t1.value, t2.value].join
+}
+
+assert_finish 5, %q{
+ autoload :ZZZ, File.expand_path(__FILE__)
+ begin
+ ZZZ
+ rescue NameError
+ end
+}, '[ruby-core:21696]'
+
+assert_equal 'A::C', %q{
+ open("zzz.rb", "w") {}
+ class A
+ autoload :C, "./zzz"
+ class C
+ end
+ C
+ end
+}
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_block.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_block.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_block.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,567 @@
+assert_equal %q{1}, %q{
+ 1.times{
+ begin
+ a = 1
+ ensure
+ foo = nil
+ end
+ }
+}
+assert_equal %q{2}, %q{
+ [1,2,3].find{|x| x == 2}
+}
+assert_equal %q{2}, %q{
+ class E
+ include Enumerable
+ def each(&block)
+ [1, 2, 3].each(&block)
+ end
+ end
+ E.new.find {|x| x == 2 }
+}
+assert_equal %q{6}, %q{
+ sum = 0
+ for x in [1, 2, 3]
+ sum += x
+ end
+ sum
+}
+assert_equal %q{15}, %q{
+ sum = 0
+ for x in (1..5)
+ sum += x
+ end
+ sum
+}
+assert_equal %q{0}, %q{
+ sum = 0
+ for x in []
+ sum += x
+ end
+ sum
+}
+assert_equal %q{1}, %q{
+ ans = []
+ 1.times{
+ for n in 1..3
+ a = n
+ ans << a
+ end
+ }
+}
+assert_equal %q{1..3}, %q{
+ ans = []
+ for m in 1..3
+ for n in 1..3
+ a = [m, n]
+ ans << a
+ end
+ end
+}
+assert_equal %q{[1, 2, 3]}, %q{
+ (1..3).to_a
+}
+assert_equal %q{[4, 8, 12]}, %q{
+ (1..3).map{|e|
+ e * 4
+ }
+}
+assert_equal %q{[1, 2, 3]}, %q{
+ class C
+ include Enumerable
+ def each
+ [1,2,3].each{|e|
+ yield e
+ }
+ end
+ end
+
+ C.new.to_a
+}
+assert_equal %q{[4, 5, 6]}, %q{
+ class C
+ include Enumerable
+ def each
+ [1,2,3].each{|e|
+ yield e
+ }
+ end
+ end
+
+ C.new.map{|e|
+ e + 3
+ }
+}
+assert_equal %q{100}, %q{
+ def m
+ yield
+ end
+ def n
+ yield
+ end
+
+ m{
+ n{
+ 100
+ }
+ }
+}
+assert_equal %q{20}, %q{
+ def m
+ yield 1
+ end
+
+ m{|ib|
+ m{|jb|
+ i = 20
+ }
+ }
+}
+assert_equal %q{2}, %q{
+ def m
+ yield 1
+ end
+
+ m{|ib|
+ m{|jb|
+ ib = 20
+ kb = 2
+ }
+ }
+}
+assert_equal %q{3}, %q{
+ def iter1
+ iter2{
+ yield
+ }
+ end
+
+ def iter2
+ yield
+ end
+
+ iter1{
+ jb = 2
+ iter1{
+ jb = 3
+ }
+ jb
+ }
+}
+assert_equal %q{2}, %q{
+ def iter1
+ iter2{
+ yield
+ }
+ end
+
+ def iter2
+ yield
+ end
+
+ iter1{
+ jb = 2
+ iter1{
+ jb
+ }
+ jb
+ }
+}
+assert_equal %q{2}, %q{
+ def m
+ yield 1
+ end
+ m{|ib|
+ ib*2
+ }
+}
+assert_equal %q{92580}, %q{
+ def m
+ yield 12345, 67890
+ end
+ m{|ib,jb|
+ ib*2+jb
+ }
+}
+assert_equal %q{[10, nil]}, %q{
+ def iter
+ yield 10
+ end
+
+ a = nil
+ [iter{|a|
+ a
+ }, a]
+}
+assert_equal %q{21}, %q{
+ def iter
+ yield 10
+ end
+
+ iter{|a|
+ iter{|a|
+ a + 1
+ } + a
+ }
+}
+assert_equal %q{[10, 20, 30, 40, nil, nil, nil, nil]}, %q{
+ def iter
+ yield 10, 20, 30, 40
+ end
+
+ a = b = c = d = nil
+ iter{|a, b, c, d|
+ [a, b, c, d]
+ } + [a, b, c, d]
+}
+assert_equal %q{[10, 20, 30, 40, nil, nil]}, %q{
+ def iter
+ yield 10, 20, 30, 40
+ end
+
+ a = b = nil
+ iter{|a, b, c, d|
+ [a, b, c, d]
+ } + [a, b]
+}
+assert_equal %q{[1]}, %q{
+ $a = []
+
+ def iter
+ yield 1
+ end
+
+ def m
+ x = iter{|x|
+ $a << x
+ y = 0
+ }
+ end
+ m
+ $a
+}
+assert_equal %q{[1, [2]]}, %q{
+ def iter
+ yield 1, 2
+ end
+
+ iter{|a, *b|
+ [a, b]
+ }
+}
+assert_equal %q{[[1, 2]]}, %q{
+ def iter
+ yield 1, 2
+ end
+
+ iter{|*a|
+ [a]
+ }
+}
+assert_equal %q{[1, 2, []]}, %q{
+ def iter
+ yield 1, 2
+ end
+
+ iter{|a, b, *c|
+ [a, b, c]
+ }
+}
+assert_equal %q{[1, 2, nil, []]}, %q{
+ def iter
+ yield 1, 2
+ end
+
+ iter{|a, b, c, *d|
+ [a, b, c, d]
+ }
+}
+assert_equal %q{1}, %q{
+ def m
+ yield
+ end
+ m{
+ 1
+ }
+}
+assert_equal %q{15129}, %q{
+ def m
+ yield 123
+ end
+ m{|ib|
+ m{|jb|
+ ib*jb
+ }
+ }
+}
+assert_equal %q{2}, %q{
+ def m a
+ yield a
+ end
+ m(1){|ib|
+ m(2){|jb|
+ ib*jb
+ }
+ }
+}
+assert_equal %q{9}, %q{
+ sum = 0
+ 3.times{|ib|
+ 2.times{|jb|
+ sum += ib + jb
+ }}
+ sum
+}
+assert_equal %q{10}, %q{
+ 3.times{|bl|
+ break 10
+ }
+}
+assert_equal %q{[1, 2]}, %q{
+ def iter
+ yield 1,2,3
+ end
+
+ iter{|i, j|
+ [i, j]
+ }
+}
+assert_equal %q{[1, nil]}, %q{
+ def iter
+ yield 1
+ end
+
+ iter{|i, j|
+ [i, j]
+ }
+}
+
+assert_equal '0', %q{
+def m()
+end
+m {|(v0,*,(*)),|}
+m {|(*v0,(*)),|}
+m {|(v0,*v1,(*)),|}
+m {|((v0,*v1,v2)),|}
+m {|(v0,*v1,v2),|}
+m {|(v0,*v1,(v2)),|}
+m {|((*),*v0,v1),|}
+m {|((v0),*v1,v2),|}
+m {|(v0,v1,*v2,v3),|}
+m {|v0,(v1,*v2,v3),|}
+m {|(v0,*v1,v2),v3,|}
+m {|(v0,*v1,v2)|}
+m {|(v0,*v1,v2),&v3|}
+m {|(v0,*v1,v2),*|}
+m {|(v0,*v1,v2),*,&v3|}
+m {|*,(v0,*v1,v2)|}
+m {|*,(v0,*v1,v2),&v3|}
+m {|v0,*,(v1,*v2,v3)|}
+m {|v0,*,(v1,*v2,v3),&v4|}
+m {|(v0,*v1,v2),*,v3|}
+m {|(v0,*v1,v2),*,v3,&v4|}
+m {|(v0, *v1, v2)|}
+m {|(*,v)|}
+0
+}, "block parameter (shouldn't SEGV: [ruby-dev:31143])"
+
+assert_equal 'nil', %q{
+ def m
+ yield
+ end
+ m{|&b| b}.inspect
+}, '[ruby-dev:31147]'
+
+assert_equal 'nil', %q{
+ def m()
+ yield
+ end
+ m {|(v,(*))|}.inspect
+}, '[ruby-dev:31160]'
+
+assert_equal 'nil', %q{
+ def m()
+ yield
+ end
+ m {|(*,a,b)|}.inspect
+}, '[ruby-dev:31153]'
+
+assert_equal 'nil', %q{
+ def m()
+ yield
+ end
+ m {|((*))|}.inspect
+}
+
+assert_equal %q{[1, 1, [1, nil], [1, nil], [1, nil], [1, nil], [1, 1], 1, [1, nil], [1, nil], [1, nil], [1, nil], [[1, 1], [1, 1]], [1, 1], [1, 1], [1, 1], [1, nil], [1, nil], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [1, 1], [1, 1], [[[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]]], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[1, 1], [1, 1]], [[1, 1], [1, 1]]]}, %q{
+def m(ary = [])
+ yield(ary)
+end
+
+$ans = []
+o = 1
+5.times{
+ v,(*) = o; $ans << o
+ m(o){|(v,(*))| $ans << v}
+ ((x, y)) = o; $ans << [x, y]
+ m(o){|((x, y))| $ans << [x, y]}
+ (((x, y))) = o; $ans << [x, y]
+ m(o){|(((x, y)))| $ans << [x, y]}
+ o = [o, o]
+}; $ans
+}
+
+assert_equal '0', %q{
+ def m()
+ yield [0]
+ end
+ m {|*,v| v}.inspect
+}, '[ruby-dev:31437]'
+assert_equal '[0]', %q{
+ def m
+ yield [0]
+ end
+ m{|v, &b| v}.inspect
+}, '[ruby-dev:31440]'
+assert_equal 'ok', %q{
+ begin
+ lambda{|a|}.call(1, 2)
+ rescue ArgumentError
+ :ok
+ else
+ :ng
+ end
+}, '[ruby-dev:31464]'
+assert_equal 'ok', %q{
+ begin
+ lambda{|&b|}.call(3)
+ rescue ArgumentError
+ :ok
+ else
+ :ng
+ end
+}, '[ruby-dev:31472]'
+assert_equal 'ok', %q{
+ class C
+ def each
+ yield [1,2]
+ yield 1,2
+ end
+ end
+ vs1 = []
+ C.new.each {|*v| vs1 << v }
+ vs2 = []
+ C.new.to_enum.each {|*v| vs2 << v }
+ vs1 == vs2 ? :ok : :ng
+}, '[ruby-dev:32329]'
+
+assert_normal_exit %q{
+ e = [1,2,3].each
+ 10000.times {
+ e = [e].each
+ }
+ Thread.new { GC.start }.join
+}, '[ruby-dev:32604]'
+
+
+assert_equal '[nil, []]', %q{
+ def m() yield nil,[] end
+ l = lambda {|*v| v}
+ GC.stress=true
+ r = m(&l)
+ GC.stress=false
+ r.inspect
+}, '[ruby-dev:32567]'
+
+assert_equal NilClass.to_s, %q{
+ r = false; 1.times{|&b| r = b}; r.class
+}
+
+assert_equal 'ok', %q{
+ class C
+ define_method(:foo) do |arg, &block|
+ if block then block.call else arg end
+ end
+ end
+ C.new.foo("ng") {"ok"}
+}, '[ruby-talk:266422]'
+
+assert_equal 'ok', %q{
+ class C
+ define_method(:xyz) do |o, k, &block|
+ block.call(o, k)
+ end
+ end
+ C.new.xyz("o","k") {|o, k| o+k}
+}, '[ruby-core:20544]'
+
+assert_equal 'ok', %q{
+ class C
+ define_method(:xyz) do |*args, &block|
+ block.call(*args)
+ end
+ end
+ C.new.xyz("o","k") {|*args| args.join("")}
+}, '[ruby-core:20544]'
+
+assert_equal 'ok', %q{
+ STDERR.reopen(STDOUT)
+ class C
+ define_method(:foo) do |&block|
+ block.call if block
+ end
+ result = "ng"
+ new.foo() {result = "ok"}
+ result
+ end
+}
+
+assert_equal "ok", %q{
+ class Bar
+ def bar; :ok; end
+ end
+ def foo
+ yield(Bar.new) if block_given?
+ end
+ foo(&:bar)
+}, '[ruby-core:14279]'
+
+assert_normal_exit %q{
+ class Controller
+ def respond_to(&block)
+ responder = Responder.new
+ block.call(responder)
+ responder.respond
+ end
+ def test_for_bug
+ respond_to{|format|
+ format.js{
+ puts "in test"
+ render{|obj|
+ puts obj
+ }
+ }
+ }
+ end
+ def render(&block)
+ puts "in render"
+ end
+ end
+
+ class Responder
+ def method_missing(symbol, &block)
+ puts "enter method_missing"
+ @response = Proc.new{
+ puts 'in method missing'
+ block.call
+ }
+ puts "leave method_missing"
+ end
+ def respond
+ @response.call
+ end
+ end
+ t = Controller.new
+ t.test_for_bug
+}, '[ruby-core:14395]'
+
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_class.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_class.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_class.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,159 @@
+# class
+assert_equal 'true', %q( class C; end
+ Object.const_defined?(:C) )
+assert_equal 'Class', %q( class C; end
+ C.class )
+assert_equal 'C', %q( class C; end
+ C.name )
+assert_equal 'C', %q( class C; end
+ C.new.class )
+assert_equal 'C', %q( class C; end
+ C.new.class.name )
+assert_equal 'Class', %q( class C; end
+ C.new.class.class )
+
+# inherited class
+assert_equal 'true', %q( class A; end
+ class C < A; end
+ Object.const_defined?(:C) )
+assert_equal 'Class', %q( class A; end
+ class C < A; end
+ C.class )
+assert_equal 'C', %q( class A; end
+ class C < A; end
+ C.name )
+assert_equal 'C', %q( class A; end
+ class C < A; end
+ C.new.class )
+assert_equal 'C', %q( class A; end
+ class C < A; end
+ C.new.class.name )
+assert_equal 'Class', %q( class A; end
+ class C < A; end
+ C.new.class.class )
+
+# module
+assert_equal 'true', %q( module M; end
+ Object.const_defined?(:M) )
+assert_equal 'Module', %q( module M; end
+ M.class )
+assert_equal 'M', %q( module M; end
+ M.name )
+assert_equal 'C', %q( module M; end
+ class C; include M; end
+ C.new.class )
+
+# nested class
+assert_equal 'A::B', %q( class A; end
+ class A::B; end
+ A::B )
+assert_equal 'A::B', %q( class A; end
+ class A::B; end
+ A::B.name )
+assert_equal 'A::B', %q( class A; end
+ class A::B; end
+ A::B.new.class )
+assert_equal 'Class', %q( class A; end
+ class A::B; end
+ A::B.new.class.class )
+assert_equal 'A::B::C', %q( class A; end
+ class A::B; end
+ class A::B::C; end
+ A::B::C )
+assert_equal 'A::B::C', %q( class A; end
+ class A::B; end
+ class A::B::C; end
+ A::B::C.name )
+assert_equal 'Class', %q( class A; end
+ class A::B; end
+ class A::B::C; end
+ A::B::C.class )
+assert_equal 'A::B::C', %q( class A; end
+ class A::B; end
+ class A::B::C; end
+ A::B::C.new.class )
+assert_equal 'Class', %q( class A; end
+ class A::B; end
+ class A::B::C; end
+ A::B::C.new.class.class )
+assert_equal 'A::B2', %q( class A; end
+ class A::B; end
+ class A::B2 < A::B; end
+ A::B2 )
+assert_equal 'Class', %q( class A; end
+ class A::B; end
+ class A::B2 < A::B; end
+ A::B2.class )
+
+# reopen
+assert_equal 'true', %q( class C; end; c1 = ::C
+ class C; end; c2 = ::C
+ c1.equal?(c2) )
+assert_equal '1', %q( class C; end
+ class A; end
+ begin class C < A; end; rescue TypeError; 1 end )
+assert_equal '1', %q( class C; end
+ begin module C; end; rescue TypeError; 1 end )
+assert_equal '1', %q( C = 1 # [yarv-dev:782]
+ begin class C; end; rescue TypeError; 1 end )
+assert_equal '1', %q( C = 1 # [yarv-dev:800]
+ begin module C; end; rescue TypeError; 1 end )
+
+# colon2, colon3
+assert_equal '1', %q( class A; end; A::C = 1; A::C )
+assert_equal '1', %q( A = 7; begin A::C = 7; rescue TypeError; 1 end )
+assert_equal '1', %q( begin 7::C = 7; rescue TypeError; 1 end )
+assert_equal 'C', %q( class A; class ::C; end end; C )
+assert_equal 'Class', %q( class A; class ::C; end end; C.class )
+assert_equal 'OK', %q( class A; ::C = "OK"; end; C )
+assert_equal 'String', %q( class A; ::C = "OK"; end; C.class )
+
+# class/module dup
+assert_equal 'Class', %q( class C; end; C.dup.class )
+assert_equal 'Module', %q( module M; end; M.dup.class )
+
+
+assert_equal "ok", %q{
+ module Foo
+ end
+
+ begin
+ def foo(&b)
+ Foo.module_eval &b
+ end
+ foo{
+ def bar
+ end
+ }
+ bar()
+ rescue NameError
+ :ok
+ end
+}, '[ruby-core:14378]'
+
+assert_equal '3', %q{
+ $i = 0
+ class C
+ def self.const_missing *args
+ $i+=1
+ end
+ end
+
+ 3.times{
+ C::FOO
+ }
+ $i
+}
+
+assert_match /::C\z/, %q{
+ c = nil
+ Module.new{|m| c = class m::C; name; end}
+ c
+}, '[ruby-dev:38456]'
+
+assert_normal_exit %q{
+ s = Symbol.dup
+ class << s
+ end
+ s.allocate.to_s
+}, '[ruby-core:30843]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_eval.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_eval.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_eval.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,321 @@
+assert_equal %q{ok}, %q{
+ def m
+ a = :ok
+ $b = binding
+ end
+ m
+ eval('a', $b)
+}
+assert_equal %q{[:ok, :ok2]}, %q{
+ def m
+ a = :ok
+ $b = binding
+ end
+ m
+ eval('b = :ok2', $b)
+ eval('[a, b]', $b)
+}
+assert_equal %q{[nil, 1]}, %q{
+ $ans = []
+ def m
+ $b = binding
+ end
+ m
+ $ans << eval(%q{
+ $ans << eval(%q{
+ a
+ }, $b)
+ a = 1
+ }, $b)
+ $ans
+}
+assert_equal %q{C}, %q{
+ Const = :top
+ class C
+ Const = :C
+ def m
+ binding
+ end
+ end
+ eval('Const', C.new.m)
+}
+assert_equal %q{top}, %q{
+ Const = :top
+ a = 1
+ class C
+ Const = :C
+ def m
+ eval('Const', TOPLEVEL_BINDING)
+ end
+ end
+ C.new.m
+}
+assert_equal %q{:ok
+ok}, %q{
+ class C
+ $b = binding
+ end
+ eval %q{
+ def m
+ :ok
+ end
+ }, $b
+ p C.new.m
+}
+assert_equal %q{ok}, %q{
+ b = proc{
+ a = :ok
+ binding
+ }.call
+ a = :ng
+ eval("a", b)
+}
+assert_equal %q{C}, %q{
+ class C
+ def foo
+ binding
+ end
+ end
+ C.new.foo.eval("self.class.to_s")
+}
+assert_equal %q{1}, %q{
+ eval('1')
+}
+assert_equal %q{1}, %q{
+ eval('a=1; a')
+}
+assert_equal %q{1}, %q{
+ a = 1
+ eval('a')
+}
+assert_equal %q{ok}, %q{
+ __send__ :eval, %{
+ :ok
+ }
+}
+assert_equal %q{ok}, %q{
+ 1.__send__ :instance_eval, %{
+ :ok
+ }
+}
+assert_equal %q{1}, %q{
+ 1.instance_eval{
+ self
+ }
+}
+assert_equal %q{foo}, %q{
+ 'foo'.instance_eval{
+ self
+ }
+}
+assert_equal %q{1}, %q{
+ class Fixnum
+ Const = 1
+ end
+ 1.instance_eval %{
+ Const
+ }
+}
+assert_equal %q{top}, %q{
+ Const = :top
+ class C
+ Const = :C
+ end
+ C.module_eval{
+ Const
+ }
+}
+assert_equal %q{C}, %q{
+ Const = :top
+ class C
+ Const = :C
+ end
+ C.class_eval %{
+ def m
+ Const
+ end
+ }
+ C.new.m
+}
+assert_equal %q{C}, %q{
+ Const = :top
+ class C
+ Const = :C
+ end
+ C.class_eval{
+ def m
+ Const
+ end
+ }
+ C.new.m
+}
+assert_equal %q{[:top, :C, :top, :C]}, %q{
+ Const = :top
+ class C
+ Const = :C
+ end
+ $nest = false
+ $ans = []
+ def m
+ $ans << Const
+ C.module_eval %{
+ $ans << Const
+ Boo = false unless defined? Boo
+ unless $nest
+ $nest = true
+ m
+ end
+ }
+ end
+ m
+ $ans
+}
+assert_equal %q{[10, main]}, %q{
+ $nested = false
+ $ans = []
+ $pr = proc{
+ $ans << self
+ unless $nested
+ $nested = true
+ $pr.call
+ end
+ }
+ class C
+ def initialize &b
+ 10.instance_eval(&b)
+ end
+ end
+ C.new(&$pr)
+ $ans
+}
+
+%w[break next redo].each do |keyword|
+ assert_match %r"Can't escape from eval with #{keyword}\z", %{
+ begin
+ eval "0 rescue #{keyword}"
+ rescue SyntaxError => e
+ e.message
+ end
+ }, '[ruby-dev:31372]'
+end
+
+assert_normal_exit %q{
+ STDERR.reopen(STDOUT)
+ class Foo
+ def self.add_method
+ class_eval("def some-bad-name; puts 'hello' unless @some_variable.some_function(''); end")
+ end
+ end
+ Foo.add_method
+}, '[ruby-core:14556] reported by Frederick Cheung'
+
+assert_equal 'ok', %q{
+ class Module
+ def my_module_eval(&block)
+ module_eval(&block)
+ end
+ end
+ class String
+ Integer.my_module_eval do
+ def hoge; end
+ end
+ end
+ if Integer.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) &&
+ !String.instance_methods(false).map{|m|m.to_sym}.include?(:hoge)
+ :ok
+ else
+ :ng
+ end
+}, "[ruby-dev:34236]"
+
+assert_equal 'ok', %q{
+ begin
+ eval("class nil::Foo; end")
+ :ng
+ rescue Exception
+ :ok
+ end
+}
+
+assert_equal 'ok', %q{
+ begin
+ 0.instance_eval { def m() :m end }
+ 1.m
+ :ng
+ rescue Exception
+ :ok
+ end
+}, '[ruby-dev:34579]'
+
+assert_equal 'ok', %q{
+ begin
+ 12.instance_eval { @@a }
+ rescue NameError
+ :ok
+ end
+}, '[ruby-core:16794]'
+
+assert_equal 'ok', %q{
+ begin
+ 12.instance_exec { @@a }
+ rescue NameError
+ :ok
+ end
+}, '[ruby-core:16794]'
+
+assert_equal 'ok', %q{
+ begin
+ nil.instance_eval {
+ def a() :a end
+ }
+ rescue TypeError
+ :ok
+ end
+}, '[ruby-core:16796]'
+
+assert_equal 'ok', %q{
+ begin
+ nil.instance_exec {
+ def a() :a end
+ }
+ rescue TypeError
+ :ok
+ end
+}, '[ruby-core:16796]'
+
+assert_normal_exit %q{
+ eval("", method(:proc).call {}.binding)
+}
+
+assert_equal "", %q{
+ b = binding
+ 10.times{
+ eval('', b)
+ }
+ begin
+ eval('1.times{raise}', b)
+ rescue => e
+ e.message
+ end
+}, '[ruby-dev:35392]'
+
+assert_equal "[:x]", %q{
+ def kaboom!
+ yield.eval("local_variables")
+ end
+
+ for x in enum_for(:kaboom!)
+ binding
+ end
+}, '[ruby-core:25125]'
+
+assert_normal_exit %q{
+ hash = {}
+ ("aaaa".."matz").each_with_index do |s, i|
+ hash[s] = i
+ end
+ begin
+ eval "class C; @@h = #{hash.inspect}; end"
+ rescue SystemStackError
+ end
+}, '[ruby-core:25714]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_exception.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_exception.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_exception.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,416 @@
+assert_equal %q{2}, %q{
+ begin
+ 1+1
+ ensure
+ 2+2
+ end
+}
+assert_equal %q{4}, %q{
+ begin
+ 1+1
+ begin
+ 2+2
+ ensure
+ 3+3
+ end
+ ensure
+ 4+4
+ end
+}
+assert_equal %q{4}, %q{
+ begin
+ 1+1
+ begin
+ 2+2
+ ensure
+ 3+3
+ end
+ ensure
+ 4+4
+ begin
+ 5+5
+ ensure
+ 6+6
+ end
+ end
+}
+assert_equal %q{NilClass}, %q{
+ a = nil
+ 1.times{|e|
+ begin
+ rescue => err
+ end
+ a = err.class
+ }
+ a
+}
+assert_equal %q{RuntimeError}, %q{
+ a = nil
+ 1.times{|e|
+ begin
+ raise
+ rescue => err
+ end
+ a = err.class
+ }
+ a
+}
+assert_equal %q{}, %q{
+ $!
+}
+assert_equal %q{FOO}, %q{
+ begin
+ raise "FOO"
+ rescue
+ $!
+ end
+}
+assert_equal %q{FOO}, %q{
+ def m
+ $!
+ end
+ begin
+ raise "FOO"
+ rescue
+ m()
+ end
+}
+assert_equal %q{[#<RuntimeError: BAR>, #<RuntimeError: FOO>]}, %q{
+ $ans = []
+ def m
+ $!
+ end
+ begin
+ raise "FOO"
+ rescue
+ begin
+ raise "BAR"
+ rescue
+ $ans << m()
+ end
+ $ans << m()
+ end
+ $ans
+}
+assert_equal %q{[#<RuntimeError: FOO>, #<RuntimeError: FOO>]}, %q{
+ $ans = []
+ def m
+ $!
+ end
+
+ begin
+ begin
+ raise "FOO"
+ ensure
+ $ans << m()
+ end
+ rescue
+ $ans << m()
+ end
+}
+assert_equal %q{[nil]}, %q{
+ $ans = []
+ def m
+ $!
+ end
+ def m2
+ 1.times{
+ begin
+ return
+ ensure
+ $ans << m
+ end
+ }
+ end
+ m2
+ $ans
+}
+assert_equal %q{ok}, %q{
+ begin
+ raise
+ rescue
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ begin
+ raise
+ rescue
+ :ok
+ ensure
+ :ng
+ end
+}
+assert_equal %q{RuntimeError}, %q{
+ begin
+ raise
+ rescue => e
+ e.class
+ end
+}
+assert_equal %q{ng}, %q{
+ begin
+ raise
+ rescue StandardError
+ :ng
+ rescue Exception
+ :ok
+ end
+}
+assert_equal %q{c}, %q{
+ begin
+ begin
+ raise "a"
+ rescue
+ raise "b"
+ ensure
+ raise "c"
+ end
+ rescue => e
+ e.message
+ end
+}
+assert_equal %q{33}, %q{
+ def m a, b
+ a + b
+ end
+ m(1, begin
+ raise
+ rescue
+ 2
+ end) +
+ m(10, begin
+ raise
+ rescue
+ 20
+ ensure
+ 30
+ end)
+}
+assert_equal %q{3}, %q{
+ def m a, b
+ a + b
+ end
+ m(begin
+ raise
+ rescue
+ 1
+ end,
+ begin
+ raise
+ rescue
+ 2
+ end)
+}
+assert_equal %q{ok3}, %q{
+ class E1 < Exception
+ end
+
+ def m
+ yield
+ end
+
+ begin
+ begin
+ begin
+ m{
+ raise
+ }
+ rescue E1
+ :ok2
+ ensure
+ end
+ rescue
+ :ok3
+ ensure
+ end
+ rescue E1
+ :ok
+ ensure
+ end
+}
+assert_equal %q{7}, %q{
+ $i = 0
+ def m
+ iter{
+ begin
+ $i += 1
+ begin
+ $i += 2
+ break
+ ensure
+
+ end
+ ensure
+ $i += 4
+ end
+ $i = 0
+ }
+ end
+
+ def iter
+ yield
+ end
+ m
+ $i
+}
+assert_equal %q{10}, %q{
+ $i = 0
+ def m
+ begin
+ $i += 1
+ begin
+ $i += 2
+ return
+ ensure
+ $i += 3
+ end
+ ensure
+ $i += 4
+ end
+ p :end
+ end
+ m
+ $i
+}
+assert_equal %q{1}, %q{
+ begin
+ 1
+ rescue
+ 2
+ end
+}
+assert_equal %q{4}, %q{
+ begin
+ 1
+ begin
+ 2
+ rescue
+ 3
+ end
+ 4
+ rescue
+ 5
+ end
+}
+assert_equal %q{3}, %q{
+ begin
+ 1
+ rescue
+ 2
+ else
+ 3
+ end
+}
+assert_equal %q{2}, %q{
+ begin
+ 1+1
+ rescue
+ 2+2
+ ensure
+ 3+3
+ end
+ }
+assert_equal %q{2}, %q{
+ begin
+ 1+1
+ rescue
+ 2+2
+ ensure
+ 3+3
+ end
+ }
+assert_equal %q{6}, %q{
+ begin
+ 1+1
+ rescue
+ 2+2
+ else
+ 3+3
+ ensure
+ 4+4
+ end
+ }
+assert_equal %q{12}, %q{
+ begin
+ 1+1
+ begin
+ 2+2
+ rescue
+ 3+3
+ else
+ 4+4
+ end
+ rescue
+ 5+5
+ else
+ 6+6
+ ensure
+ 7+7
+ end
+ }
+assert_equal %q{ok}, %q{ #
+ proc{
+ begin
+ raise
+ break
+ rescue
+ :ok
+ end
+ }.call
+}
+assert_equal %q{}, %q{
+ proc do
+ begin
+ raise StandardError
+ redo
+ rescue StandardError
+ end
+ end.call
+}
+
+##
+assert_match /undefined method `foo\'/, %q{#`
+ STDERR.reopen(STDOUT)
+ class C
+ def inspect
+ bar {}
+ end
+
+ def bar
+ raise
+ ensure
+ end
+ end
+ C.new.foo
+}, "[ruby-dev:31407]"
+
+assert_equal 'nil', %q{
+ doit = false
+ exc = nil
+ t = Thread.new {
+ begin
+ doit = true
+ sleep 10
+ ensure
+ exc = $!
+ end
+ }
+ Thread.pass until doit
+ t.kill
+ t.join
+ exc.inspect
+}, '[ruby-dev:32608]'
+
+assert_equal 'exception class/object expected', %q{
+ class ZeroDivisionError
+ def self.new(message)
+ 42
+ end
+ end
+ begin
+ 1/0
+ rescue Exception => e
+ e.message
+ end
+}, '[ruby-core:24767]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_finalizer.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_finalizer.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_finalizer.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,8 @@
+assert_normal_exit %q{
+a1,a2,b1,b2=Array.new(4){""}
+ObjectSpace.define_finalizer(b2,proc{})
+ObjectSpace.define_finalizer(b1,proc{b1.inspect})
+
+ObjectSpace.define_finalizer(a2,proc{a1.inspect})
+ObjectSpace.define_finalizer(a1,proc{})
+}, '[ruby-dev:35778]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_flip.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_flip.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_flip.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+assert_equal %q{E}, %q{$_ = "E"; eval("nil if true..~/^E/",nil,"-e"); $_}
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_flow.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_flow.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_flow.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,525 @@
+assert_equal %q{[1, 2, 4, 5, 6, 7, 8]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each{; $a << 2
+ break; $a << 3
+ }; $a << 4
+ begin; $a << 5
+ ensure; $a << 6
+ end; $a << 7
+; $a << 8
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 6, 7, 8]}, %q{$a = []; begin; ; $a << 1
+ begin; $a << 2
+ [1,2].each do; $a << 3
+ break; $a << 4
+ end; $a << 5
+ ensure; $a << 6
+ end; $a << 7
+; $a << 8
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{ok}, %q{
+ ["a"].inject("ng"){|x,y|
+ break :ok
+ }
+}
+assert_equal %q{ok}, %q{
+ unless ''.respond_to? :lines
+ class String
+ def lines
+ self
+ end
+ end
+ end
+
+ ('a').lines.map{|e|
+ break :ok
+ }
+}
+assert_equal %q{[1, 2, 4, 5]}, %q{$a = []; begin; ; $a << 1
+ ["a"].inject("ng"){|x,y|; $a << 2
+ break :ok; $a << 3
+ }; $a << 4
+; $a << 5
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 4, 5]}, %q{$a = []; begin; ; $a << 1
+ ('a'..'b').map{|e|; $a << 2
+ break :ok; $a << 3
+ }; $a << 4
+; $a << 5
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 7, 8]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each do; $a << 2
+ begin; $a << 3
+ break; $a << 4
+ ensure; $a << 5
+ end; $a << 6
+ end; $a << 7
+; $a << 8
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 6, 9, 10]}, %q{$a = []; begin; ; $a << 1
+ i=0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ begin; $a << 5
+ ensure; $a << 6
+ break; $a << 7
+ end; $a << 8
+ end; $a << 9
+; $a << 10
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 7, 10, 11]}, %q{$a = []; begin; ; $a << 1
+ i=0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ begin; $a << 5
+ raise; $a << 6
+ ensure; $a << 7
+ break; $a << 8
+ end; $a << 9
+ end; $a << 10
+; $a << 11
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 7, 10, 11]}, %q{$a = []; begin; ; $a << 1
+ i=0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ begin; $a << 5
+ raise; $a << 6
+ rescue; $a << 7
+ break; $a << 8
+ end; $a << 9
+ end; $a << 10
+; $a << 11
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each do; $a << 2
+ begin; $a << 3
+ raise StandardError; $a << 4
+ ensure; $a << 5
+ break; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each do; $a << 2
+ begin; $a << 3
+ raise StandardError; $a << 4
+ rescue; $a << 5
+ break; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 6, 8, 10, 11]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each do; $a << 2
+ begin; $a << 3
+ begin; $a << 4
+ break; $a << 5
+ ensure; $a << 6
+ end; $a << 7
+ ensure; $a << 8
+ end; $a << 9
+ end; $a << 10
+; $a << 11
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 6, 7, 8, 10, 13, 3, 4, 5, 6, 7, 8, 10, 13, 3, 4, 5, 6, 7, 8, 10, 13, 14, 15]}, %q{$a = []; begin; ; $a << 1
+ i = 0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ j = 0; $a << 5
+ while j<3; $a << 6
+ j+=1; $a << 7
+ begin; $a << 8
+ raise; $a << 9
+ rescue; $a << 10
+ break; $a << 11
+ end; $a << 12
+ end; $a << 13
+ end; $a << 14
+; $a << 15
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 16, 17]}, %q{$a = []; begin; ; $a << 1
+ i = 0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ j = 0; $a << 5
+ while j<3; $a << 6
+ j+=1; $a << 7
+ 1.times{; $a << 8
+ begin; $a << 9
+ raise; $a << 10
+ rescue; $a << 11
+ break; $a << 12
+ end; $a << 13
+ }; $a << 14
+ end; $a << 15
+ end; $a << 16
+; $a << 17
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 6, 7, 8, 10, 13, 3, 4, 5, 6, 7, 8, 10, 13, 3, 4, 5, 6, 7, 8, 10, 13, 14, 15]}, %q{$a = []; begin; ; $a << 1
+ i = 0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ j = 0; $a << 5
+ while j<3; $a << 6
+ j+=1; $a << 7
+ begin; $a << 8
+ raise; $a << 9
+ ensure; $a << 10
+ break; $a << 11
+ end; $a << 12
+ end; $a << 13
+ end; $a << 14
+; $a << 15
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 16, 17]}, %q{$a = []; begin; ; $a << 1
+ i = 0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ j = 0; $a << 5
+ while j<3; $a << 6
+ j+=1; $a << 7
+ 1.times{; $a << 8
+ begin; $a << 9
+ raise; $a << 10
+ ensure; $a << 11
+ break; $a << 12
+ end; $a << 13
+ }; $a << 14
+ end; $a << 15
+ end; $a << 16
+; $a << 17
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ while true; $a << 2
+ begin; $a << 3
+ break; $a << 4
+ ensure; $a << 5
+ break; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 99]}, %q{
+$a = [];
+begin; ; $a << 1
+ while true; $a << 2
+ begin; $a << 3
+ break; $a << 4
+ ensure; $a << 5
+ raise; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 6, 8, 9, 10, 11]}, %q{$a = []; begin; ; $a << 1
+ begin; $a << 2
+ [1,2].each do; $a << 3
+ begin; $a << 4
+ break; $a << 5
+ ensure; $a << 6
+ end; $a << 7
+ end; $a << 8
+ ensure; $a << 9
+ end; $a << 10
+; $a << 11
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 4, 99]}, %q{$a = []; begin; ; $a << 1
+ begin; $a << 2
+ raise StandardError; $a << 3
+ ensure; $a << 4
+ end; $a << 5
+; $a << 6
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4]}, %q{$a = []; begin; ; $a << 1
+ begin; $a << 2
+ ensure; $a << 3
+ end ; $a << 4
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 5, 99]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each do; $a << 2
+ begin; $a << 3
+ break; $a << 4
+ ensure; $a << 5
+ raise StandardError; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{3}, %q{
+ def m a, b
+ a + b
+ end
+ m(1,
+ while true
+ break 2
+ end
+ )
+}
+assert_equal %q{4}, %q{
+ def m a, b
+ a + b
+ end
+ m(1,
+ (i=0; while i<2
+ i+=1
+ class C
+ next 2
+ end
+ end; 3)
+ )
+}
+assert_equal %q{34}, %q{
+ def m a, b
+ a+b
+ end
+ m(1, 1.times{break 3}) +
+ m(10, (1.times{next 3}; 20))
+}
+assert_equal %q{[1, 2, 3, 6, 7]}, %q{$a = []; begin; ; $a << 1
+ 3.times{; $a << 2
+ class C; $a << 3
+ break; $a << 4
+ end; $a << 5
+ }; $a << 6
+; $a << 7
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ 3.times{; $a << 2
+ class A; $a << 3
+ class B; $a << 4
+ break; $a << 5
+ end; $a << 6
+ end; $a << 7
+ }; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 2, 3, 2, 3, 6, 7]}, %q{$a = []; begin; ; $a << 1
+ 3.times{; $a << 2
+ class C; $a << 3
+ next; $a << 4
+ end; $a << 5
+ }; $a << 6
+; $a << 7
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ 3.times{; $a << 2
+ class C; $a << 3
+ class D; $a << 4
+ next; $a << 5
+ end; $a << 6
+ end; $a << 7
+ }; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 6, 7]}, %q{$a = []; begin; ; $a << 1
+ while true; $a << 2
+ class C; $a << 3
+ break; $a << 4
+ end; $a << 5
+ end; $a << 6
+; $a << 7
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ while true; $a << 2
+ class C; $a << 3
+ class D; $a << 4
+ break; $a << 5
+ end; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 3, 4, 5, 3, 4, 5, 3, 4, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ i=0; $a << 2
+ while i<3; $a << 3
+ i+=1; $a << 4
+ class C; $a << 5
+ next 10; $a << 6
+ end; $a << 7
+ end; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{1}, %q{
+ 1.times{
+ while true
+ class C
+ begin
+ break
+ ensure
+ break
+ end
+ end
+ end
+ }
+}
+assert_equal %q{[1, 2, 3, 5, 2, 3, 5, 7, 8]}, %q{$a = []; begin; ; $a << 1
+ [1,2].each do; $a << 2
+ begin; $a << 3
+ next; $a << 4
+ ensure; $a << 5
+ end; $a << 6
+ end; $a << 7
+; $a << 8
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 2, 6, 3, 5, 7, 8]}, %q{$a = []; begin; ; $a << 1
+ o = "test"; $a << 2
+ def o.test(a); $a << 3
+ return a; $a << 4
+ ensure; $a << 5
+ end; $a << 6
+ o.test(123); $a << 7
+; $a << 8
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 4, 7, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1
+ def m1 *args; $a << 2
+ ; $a << 3
+ end; $a << 4
+ def m2; $a << 5
+ m1(:a, :b, (return 1; :c)); $a << 6
+ end; $a << 7
+ m2; $a << 8
+; $a << 9
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 8, 2, 3, 4, 5, 9, 10]}, %q{$a = []; begin; ; $a << 1
+ def m(); $a << 2
+ begin; $a << 3
+ 2; $a << 4
+ ensure; $a << 5
+ return 3; $a << 6
+ end; $a << 7
+ end; $a << 8
+ m; $a << 9
+; $a << 10
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 3, 11, 4, 5, 6, 7, 12, 13]}, %q{$a = []; begin; ; $a << 1
+ def m2; $a << 2
+ end; $a << 3
+ def m(); $a << 4
+ m2(begin; $a << 5
+ 2; $a << 6
+ ensure; $a << 7
+ return 3; $a << 8
+ end); $a << 9
+ 4; $a << 10
+ end; $a << 11
+ m(); $a << 12
+; $a << 13
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[1, 16, 2, 3, 4, 5, 6, 7, 10, 11, 17, 18]}, %q{$a = []; begin; ; $a << 1
+ def m; $a << 2
+ 1; $a << 3
+ 1.times{; $a << 4
+ 2; $a << 5
+ begin; $a << 6
+ 3; $a << 7
+ return; $a << 8
+ 4; $a << 9
+ ensure; $a << 10
+ 5; $a << 11
+ end; $a << 12
+ 6; $a << 13
+ }; $a << 14
+ 7; $a << 15
+ end; $a << 16
+ m(); $a << 17
+; $a << 18
+; rescue Exception; $a << 99; end; $a}
+assert_equal %q{[:ok, :ok2, :last]}, %q{
+ a = []
+ i = 0
+ begin
+ while i < 1
+ i+=1
+ begin
+ begin
+ next
+ ensure
+ a << :ok
+ end
+ ensure
+ a << :ok2
+ end
+ end
+ ensure
+ a << :last
+ end
+ a
+}
+assert_equal %q{[:ok, :ok2, :last]}, %q{
+ a = []
+ i = 0
+ begin
+ while i < 1
+ i+=1
+ begin
+ begin
+ break
+ ensure
+ a << :ok
+ end
+ ensure
+ a << :ok2
+ end
+ end
+ ensure
+ a << :last
+ end
+ a
+}
+assert_equal %q{[:ok, :ok2, :last]}, %q{
+ a = []
+ i = 0
+ begin
+ while i < 1
+ if i>0
+ break
+ end
+ i+=1
+ begin
+ begin
+ redo
+ ensure
+ a << :ok
+ end
+ ensure
+ a << :ok2
+ end
+ end
+ ensure
+ a << :last
+ end
+ a
+}
+assert_equal %Q{ENSURE\n}, %q{
+ def test
+ while true
+ return
+ end
+ ensure
+ puts("ENSURE")
+ end
+ test
+}, '[ruby-dev:37967]'
+
+[['[ruby-core:28129]', %q{
+ class Bug2728
+ include Enumerable
+ define_method(:dynamic_method) do
+ "dynamically defined method"
+ end
+ def each
+ begin
+ yield :foo
+ ensure
+ dynamic_method
+ end
+ end
+ end
+ e = Bug2728.new
+}]].each do |bug, src|
+ assert_equal "foo", src + %q{e.detect {true}}, bug
+ assert_equal "true", src + %q{e.any? {true}}, bug
+ assert_equal "false", src + %q{e.all? {false}}, bug
+ assert_equal "true", src + %q{e.include?(:foo)}, bug
+end
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_fork.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_fork.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_fork.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,49 @@
+assert_equal '0', %q{
+ begin
+ GC.stress = true
+ pid = fork {}
+ Process.wait pid
+ $?.to_i
+ rescue NotImplementedError
+ 0
+ end
+}, '[ruby-dev:32404]'
+
+assert_finish 10, %q{
+ begin
+ children = (1..10).map{
+ Thread.start{fork{}}.value
+ }
+ while !children.empty? and pid = Process.wait
+ children.delete(pid)
+ end
+ rescue NotImplementedError
+ end
+}, '[ruby-core:22158]'
+
+assert_normal_exit(<<'End', '[ruby-dev:37934]')
+ Thread.new { sleep 1; Thread.kill Thread.main }
+ Process.setrlimit(:NPROC, 1)
+ fork {}
+End
+
+assert_equal 'ok', %q{
+ begin
+ if pid1 = fork
+ sleep 1
+ Process.kill("USR1", pid1)
+ _, s = Process.wait2(pid1)
+ s.success? ? :ok : :ng
+ else
+ if pid2 = fork
+ trap("USR1") { Time.now.to_s }
+ Process.wait2(pid2)
+ else
+ sleep 2
+ end
+ exit 0
+ end
+ rescue NotImplementedError
+ :ok
+ end
+}, '[ruby-core:28924]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_gc.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_gc.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_gc.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,34 @@
+assert_normal_exit %q{
+a = []
+ms = "a".."k"
+("A".."Z").each do |mod|
+ mod = eval("module #{mod}; self; end")
+ ms.each do |meth|
+ iseq = RubyVM::InstructionSequence.compile("module #{mod}; def #{meth}; end; end")
+ GC.stress = true
+ iseq.eval
+ GC.stress = false
+ end
+ o = Object.new.extend(mod)
+ ms.each do |meth|
+ o.send(meth)
+ end
+end
+}, '[ruby-dev:39453]'
+
+assert_normal_exit %q{
+a = []
+ms = "a".."k"
+("A".."Z").each do |mod|
+ mod = eval("module #{mod}; self; end")
+ ms.each do |meth|
+ GC.stress = true
+ mod.module_eval {define_method(meth) {}}
+ GC.stress = false
+ end
+ o = Object.new.extend(mod)
+ ms.each do |meth|
+ o.send(meth)
+ end
+end
+}, '[ruby-dev:39453]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_io.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_io.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_io.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,106 @@
+assert_finish 5, %q{
+ r, w = IO.pipe
+ t1 = Thread.new { r.sysread(1) }
+ t2 = Thread.new { r.sysread(1) }
+ sleep 0.1
+ w.write "a"
+ sleep 0.1
+ w.write "a"
+}, '[ruby-dev:31866]'
+
+assert_finish 10, %q{
+ begin
+ require "io/nonblock"
+ require "timeout"
+ timeout(3) do
+ r, w = IO.pipe
+ w.nonblock?
+ w.nonblock = true
+ w.write_nonblock("a" * 100000)
+ w.nonblock = false
+ t1 = Thread.new { w.write("b" * 4096) }
+ t2 = Thread.new { w.write("c" * 4096) }
+ sleep 0.5
+ r.sysread(4096).length
+ sleep 0.5
+ r.sysread(4096).length
+ t1.join
+ t2.join
+ end
+ rescue LoadError, TimeoutError, NotImplementedError
+ end
+}, '[ruby-dev:32566]'
+
+assert_finish 1, %q{
+ r, w = IO.pipe
+ Thread.new {
+ w << "ab"
+ sleep 0.1
+ w << "ab"
+ }
+ r.gets("abab")
+}
+
+assert_equal 'ok', %q{
+ require 'tmpdir'
+ begin
+ tmpname = "#{Dir.tmpdir}/ruby-btest-#{$$}-#{rand(0x100000000).to_s(36)}"
+ rw = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL)
+ rescue Errno::EEXIST
+ retry
+ end
+ save = STDIN.dup
+ STDIN.reopen(rw)
+ STDIN.reopen(save)
+ rw.close
+ File.unlink(tmpname)
+ :ok
+}
+
+assert_equal 'ok', %q{
+ require 'tmpdir'
+ begin
+ tmpname = "#{Dir.tmpdir}/ruby-btest-#{$$}-#{rand(0x100000000).to_s(36)}"
+ rw = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL)
+ rescue Errno::EEXIST
+ retry
+ end
+ save = STDIN.dup
+ STDIN.reopen(rw)
+ STDIN.print "a"
+ STDIN.reopen(save)
+ rw.close
+ File.unlink(tmpname)
+ :ok
+}
+
+assert_normal_exit %q{
+ ARGF.set_encoding "foo"
+}
+
+10.times do
+ assert_normal_exit %q{
+ at_exit { p :foo }
+
+ megacontent = "abc" * 12345678
+ #File.open("megasrc", "w") {|f| f << megacontent }
+
+ Thread.new { sleep rand*0.2; Process.kill(:INT, $$) }
+
+ r1, w1 = IO.pipe
+ r2, w2 = IO.pipe
+ t1 = Thread.new { w1 << megacontent; w1.close }
+ t2 = Thread.new { r2.read; r2.close }
+ IO.copy_stream(r1, w2) rescue nil
+ w2.close
+ r1.close
+ t1.join
+ t2.join
+ }, 'megacontent-copy_stream', ["INT"], :timeout => 10 or break
+end
+
+assert_normal_exit %q{
+ r, w = IO.pipe
+ STDOUT.reopen(w)
+ STDOUT.reopen(__FILE__, "r")
+}, '[ruby-dev:38131]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_jump.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_jump.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_jump.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,308 @@
+assert_equal %q{ok}, %q{
+ def m
+ :ng1
+ mm{
+ yield
+ }
+ :ng2
+ end
+
+ def mm
+ :ng3
+ yield
+ :ng4
+ end
+
+ m{
+ break :ok
+ }
+}
+assert_equal %q{ok}, %q{
+ 3.times{
+ break :ok
+ }
+}
+assert_equal %q{}, %q{
+ catch(:foo){
+ throw :foo
+ }
+}
+assert_equal %q{false}, %q{
+ catch(:foo){
+ throw :foo, false
+ }
+}
+assert_equal %q{}, %q{
+ catch(:foo){
+ throw :foo, nil
+ }
+}
+assert_equal %q{ok}, %q{
+ catch(:foo){
+ throw :foo, :ok
+ }
+}
+assert_equal %q{}, %q{
+ catch(:foo){
+ 1.times{
+ throw :foo
+ }
+ }
+}
+assert_equal %q{ok}, %q{
+ catch(:foo){
+ 1.times{
+ throw :foo, :ok
+ }
+ }
+}
+assert_equal %q{ok}, %q{
+ catch(:foo){
+ catch(:bar){
+ throw :foo, :ok
+ }
+ :ng
+ }
+}
+assert_equal %q{ok}, %q{
+ catch(:foo){
+ catch(:bar){
+ 1.times{
+ throw :foo, :ok
+ }
+ }
+ :ng
+ }
+}
+assert_equal %q{2}, %q{
+ module Enumerable
+ def all_?
+ self.each{|e|
+ unless yield(e)
+ return false
+ end
+ }
+ true
+ end
+ end
+
+ xxx = 0
+ [1,2].each{|bi|
+ [3,4].each{|bj|
+ [true, nil, true].all_?{|be| be}
+ break
+ }
+ xxx += 1
+ }
+ xxx
+}
+assert_equal %q{ok}, %q{
+ def m
+ yield
+ end
+
+ m{
+ begin
+ ensure
+ break :ok
+ end
+ }
+}
+assert_equal %q{ok}, %q{
+ def m
+ yield
+ :ok
+ end
+ i=0
+ m{
+ if i>10
+ i*i
+ else
+ i+=1
+ next
+ end
+ }
+}
+assert_equal %q{ok}, %q{
+ def m
+ yield
+ end
+
+ m{
+ next :ok
+ }
+}
+assert_equal %q{131}, %q{
+ def m
+ yield + 10
+ end
+ i=0
+ m{
+ if i>10
+ i*i
+ else
+ i+=1
+ redo
+ end
+ }
+}
+assert_equal %q{ok}, %q{
+begin
+ eval %q{
+ 1.times{
+ retry
+ }
+ }
+rescue SyntaxError
+ :ok
+end
+}
+assert_equal %q{3}, %q{
+ def m
+ return 3
+ end
+ m
+}
+assert_equal %q{ok}, %q{
+ def m
+ :ng1
+ mm{
+ return :ok
+ }
+ :ng2
+ end
+
+ def mm
+ :ng3
+ yield
+ :ng4
+ end
+ m
+}
+assert_equal %q{100}, %q{
+ $i = 0
+ def m
+ begin
+ iter{
+ return
+ }
+ ensure
+ $i = 100
+ end
+ end
+
+ def iter
+ yield
+ end
+ m
+ $i
+}
+assert_equal %q{ok}, %q{
+ def m
+ begin
+ raise
+ rescue
+ return :ok
+ end
+ :ng
+ end
+ m
+}
+assert_equal %q{1}, %q{
+ def m
+ begin
+ raise
+ rescue
+ return 1
+ end
+ end
+
+ m
+}
+assert_equal %q{1}, %q{
+ def m
+ begin
+ #
+ ensure
+ return 1
+ end
+ end
+
+ m
+}
+assert_equal 'ok', %q{
+ begin
+ catch {|t| throw t, :ok }
+ rescue ArgumentError
+ :ng
+ end
+}, '[ruby-dev:31609]'
+
+assert_equal "1", %q{
+ catch do |t|
+ begin
+ throw t, 1
+ 2
+ ensure
+ 3
+ end
+ end
+}, "[ruby-dev:31698]"
+
+assert_normal_exit %q{
+ f = 0
+ 1.times do
+ begin
+ f += 1
+ ensure
+ redo unless f > 2
+ end
+ end
+}
+
+assert_normal_exit %q{
+ -> do
+ 1.times do
+ begin
+ raise
+ rescue
+ return
+ end
+ end
+ end.call
+}
+
+assert_normal_exit %q{
+ while true
+ begin
+ raise
+ next
+ rescue
+ end
+ break
+ end
+}, '[ruby-core:28172]'
+
+assert_equal "true", %q{
+ class Object
+ def return_eigenclass
+ class << self
+ return self
+ end
+ end
+ end
+ s = "foo"
+ s.return_eigenclass == class << s; self; end
+}, '[ruby-core:21379]'
+
+assert_equal "true", %q{
+ class Object
+ def yield_eigenclass
+ class << self
+ yield self
+ end
+ end
+ end
+ s = "foo"
+ s.yield_eigenclass {|c| c == class << s; self; end }
+}, '[ruby-dev:40975]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_literal.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_literal.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_literal.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,202 @@
+# empty program
+assert_equal '', ''
+assert_equal '', ' '
+assert_equal '', "\n"
+
+# special const
+assert_equal 'true', 'true'
+assert_equal 'TrueClass', 'true.class'
+assert_equal 'false', 'false'
+assert_equal 'FalseClass', 'false.class'
+assert_equal '', 'nil'
+assert_equal 'nil', 'nil.inspect'
+assert_equal 'NilClass', 'nil.class'
+assert_equal 'sym', ':sym'
+assert_equal ':sym', ':sym.inspect'
+assert_equal 'Symbol', ':sym.class'
+assert_equal '1234', '1234'
+assert_equal 'Fixnum', '1234.class'
+assert_equal '1234', '1_2_3_4'
+assert_equal 'Fixnum', '1_2_3_4.class'
+assert_equal '18', '0x12'
+assert_equal 'Fixnum', '0x12.class'
+assert_equal '15', '0o17'
+assert_equal 'Fixnum', '0o17.class'
+assert_equal '5', '0b101'
+assert_equal 'Fixnum', '0b101.class'
+assert_equal '123456789012345678901234567890', '123456789012345678901234567890'
+assert_equal 'Bignum', '123456789012345678901234567890.class'
+assert_equal '2.0', '2.0'
+assert_equal 'Float', '1.3.class'
+
+# self
+assert_equal 'main', 'self'
+assert_equal 'Object', 'self.class'
+
+# string literal
+assert_equal 'a', '?a'
+assert_equal 'String', '?a.class'
+assert_equal 'A', '?A'
+assert_equal 'String', '?A.class'
+assert_equal "\n", '?\n'
+assert_equal 'String', '?\n.class'
+assert_equal ' ', '?\ '
+assert_equal 'String', '?\ .class'
+assert_equal 'string', "'string'"
+assert_equal 'string', '"string"'
+assert_equal 'string', '%(string)'
+assert_equal 'string', '%q(string)'
+assert_equal 'string', '%Q(string)'
+assert_equal 'string string', '"string string"'
+assert_equal ' ', '" "'
+assert_equal "\0", '"\0"'
+assert_equal "\1", '"\1"'
+assert_equal "3", '"\x33"'
+assert_equal "\n", '"\n"'
+
+# dynamic string literal
+assert_equal '2', '"#{1 + 1}"'
+assert_equal '16', '"#{2 ** 4}"'
+assert_equal 'string', 's = "string"; "#{s}"'
+
+# dynamic symbol literal
+assert_equal 'a3c', ':"a#{1+2}c"'
+assert_equal ':a3c', ':"a#{1+2}c".inspect'
+assert_equal 'Symbol', ':"a#{1+2}c".class'
+
+# xstring
+assert_equal "foo\n", %q(`echo foo`)
+assert_equal "foo\n", %q(s = "foo"; `echo #{s}`)
+
+# regexp
+assert_equal '', '//.source'
+assert_equal 'Regexp', '//.class'
+assert_equal '0', '// =~ "a"'
+assert_equal '0', '// =~ ""'
+assert_equal 'a', '/a/.source'
+assert_equal 'Regexp', '/a/.class'
+assert_equal '0', '/a/ =~ "a"'
+assert_equal '0', '/test/ =~ "test"'
+assert_equal '', '/test/ =~ "tes"'
+assert_equal '0', 're = /test/; re =~ "test"'
+assert_equal '0', 'str = "test"; /test/ =~ str'
+assert_equal '0', 're = /test/; str = "test"; re =~ str'
+
+# dynacmi regexp
+assert_equal 'regexp', %q(/re#{'ge'}xp/.source)
+assert_equal 'Regexp', %q(/re#{'ge'}xp/.class)
+
+# array
+assert_equal 'Array', '[].class'
+assert_equal '0', '[].size'
+assert_equal '0', '[].length'
+assert_equal '[]', '[].inspect'
+assert_equal 'Array', '[0].class'
+assert_equal '1', '[3].size'
+assert_equal '[3]', '[3].inspect'
+assert_equal '3', 'a = [3]; a[0]'
+assert_equal 'Array', '[1,2].class'
+assert_equal '2', '[1,2].size'
+assert_equal '[1, 2]', '[1,2].inspect'
+assert_equal 'Array', '[1,2,3,4,5].class'
+assert_equal '5', '[1,2,3,4,5].size'
+assert_equal '[1, 2, 3, 4, 5]', '[1,2,3,4,5].inspect'
+assert_equal '1', 'a = [1,2]; a[0]'
+assert_equal '2', 'a = [1,2]; a[1]'
+assert_equal 'Array', 'a = [1 + 2, 3 + 4, 5 + 6]; a.class'
+assert_equal '[3, 7, 11]', 'a = [1 + 2, 3 + 4, 5 + 6]; a.inspect'
+assert_equal '7', 'a = [1 + 2, 3 + 4, 5 + 6]; a[1]'
+assert_equal '1', '([0][0] += 1)'
+assert_equal '1', '([2][0] -= 1)'
+assert_equal 'Array', 'a = [obj = Object.new]; a.class'
+assert_equal '1', 'a = [obj = Object.new]; a.size'
+assert_equal 'true', 'a = [obj = Object.new]; a[0] == obj'
+assert_equal '5', 'a = [1,2,3]; a[1] = 5; a[1]'
+assert_equal 'bar', '[*:foo];:bar'
+assert_equal '[1, 2]', 'def nil.to_a; [2]; end; [1, *nil]'
+assert_equal '[1, 2]', 'def nil.to_a; [1, 2]; end; [*nil]'
+assert_equal '[0, 1, {2=>3}]', '[0, *[1], 2=>3]', "[ruby-dev:31592]"
+
+
+# hash
+assert_equal 'Hash', '{}.class'
+assert_equal '{}', '{}.inspect'
+assert_equal 'Hash', '{1=>2}.class'
+assert_equal '{1=>2}', '{1=>2}.inspect'
+assert_equal '2', 'h = {1 => 2}; h[1]'
+assert_equal '0', 'h = {1 => 2}; h.delete(1); h.size'
+assert_equal '', 'h = {1 => 2}; h.delete(1); h[1]'
+assert_equal '2', 'h = {"string" => "literal", "goto" => "hell"}; h.size'
+assert_equal 'literal', 'h = {"string"=>"literal", "goto"=>"hell"}; h["string"]'
+assert_equal 'hell', 'h = {"string"=>"literal", "goto"=>"hell"}; h["goto"]'
+
+# range
+assert_equal 'Range', '(1..2).class'
+assert_equal '1..2', '(1..2).inspect'
+assert_equal '1', '(1..2).begin'
+assert_equal '2', '(1..2).end'
+assert_equal 'false', '(1..2).exclude_end?'
+assert_equal 'Range', 'r = 1..2; r.class'
+assert_equal '1..2', 'r = 1..2; r.inspect'
+assert_equal '1', 'r = 1..2; r.begin'
+assert_equal '2', 'r = 1..2; r.end'
+assert_equal 'false', 'r = 1..2; r.exclude_end?'
+assert_equal 'Range', '(1...3).class'
+assert_equal '1...3', '(1...3).inspect'
+assert_equal '1', '(1...3).begin'
+assert_equal '3', '(1...3).end'
+assert_equal 'true', '(1...3).exclude_end?'
+assert_equal 'Range', 'r = (1...3); r.class'
+assert_equal '1...3', 'r = (1...3); r.inspect'
+assert_equal '1', 'r = (1...3); r.begin'
+assert_equal '3', 'r = (1...3); r.end'
+assert_equal 'true', 'r = (1...3); r.exclude_end?'
+assert_equal 'Range', 'r = (1+2 .. 3+4); r.class'
+assert_equal '3..7', 'r = (1+2 .. 3+4); r.inspect'
+assert_equal '3', 'r = (1+2 .. 3+4); r.begin'
+assert_equal '7', 'r = (1+2 .. 3+4); r.end'
+assert_equal 'false', 'r = (1+2 .. 3+4); r.exclude_end?'
+assert_equal 'Range', 'r = (1+2 ... 3+4); r.class'
+assert_equal '3...7', 'r = (1+2 ... 3+4); r.inspect'
+assert_equal '3', 'r = (1+2 ... 3+4); r.begin'
+assert_equal '7', 'r = (1+2 ... 3+4); r.end'
+assert_equal 'true', 'r = (1+2 ... 3+4); r.exclude_end?'
+assert_equal 'Range', 'r = ("a".."c"); r.class'
+assert_equal '"a".."c"', 'r = ("a".."c"); r.inspect'
+assert_equal 'a', 'r = ("a".."c"); r.begin'
+assert_equal 'c', 'r = ("a".."c"); r.end'
+
+assert_equal 'String', '__FILE__.class'
+assert_equal 'Fixnum', '__LINE__.class'
+
+###
+
+assert_equal 'ok', %q{
+ # this cause "called on terminated object".
+ ObjectSpace.each_object(Module) {|m| m.name.inspect }
+ :ok
+}
+
+assert_normal_exit %q{
+ begin
+ r = 0**-1
+ r + r
+ rescue
+ end
+}, '[ruby-dev:34524]'
+
+assert_normal_exit %q{
+ begin
+ r = Marshal.load("\x04\bU:\rRational[\ai\x06i\x05")
+ r + r
+ rescue
+ end
+}, '[ruby-dev:34536]'
+
+assert_equal 'ok', %q{
+ "#{}""#{}ok"
+}, '[ruby-dev:38968]'
+
+assert_equal 'ok', %q{
+ "#{}o""#{}k""#{}"
+}, '[ruby-core:25284]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_load.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_load.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_load.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,27 @@
+assert_equal 'ok', %q{
+ open("require-lock-test.rb", "w") {|f|
+ f.puts "sleep 0.1"
+ f.puts "module M"
+ f.puts "end"
+ }
+ $:.unshift Dir.pwd
+ vs = (1..2).map {|i|
+ Thread.start {
+ require "require-lock-test"
+ M
+ }
+ }.map {|t| t.value }
+ vs[0] == M && vs[1] == M ? :ok : :ng
+}, '[ruby-dev:32048]'
+
+assert_equal 'ok', %q{
+ %w[a a/foo b].each {|d| Dir.mkdir(d)}
+ open("b/foo", "w") {|f| f.puts "$ok = :ok"}
+ $:.replace(%w[a b])
+ begin
+ load "foo"
+ $ok
+ rescue => e
+ e.message
+ end
+}, '[ruby-dev:38097]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_marshal.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_marshal.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_marshal.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,5 @@
+
+assert_normal_exit %q{
+ Marshal.load(Marshal.dump({"k"=>"v"}), lambda {|v| v})
+}
+
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_massign.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_massign.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_massign.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,183 @@
+assert_equal '[[1], 2, 3]', '*v1, (a, b) = [1,[2, 3]]; [v1, a, b]'
+assert_equal '[[1], 2, 3]', '*v1,(*), (a, b) = [1,:x,[2, 3]]; [v1, a, b]'
+
+assert_equal '[]', '*a = *nil; a'
+assert_equal '[nil]', '*a = nil; a'
+assert_equal '2', 'a, a = 1, 2; a', "[ruby-dev:31522]"
+assert_equal '[1, 2]', 'a, b = 1, 2'
+assert_equal '[1, 2]', %q{
+ ans = []
+ trace_var(:$a){|v| ans << v}
+ trace_var(:$b){|v| ans << v}
+ $a, $b = 1, 2
+ ans
+}
+
+assert_equal 'ok', %q{
+ r = :ok
+ :ng.tap {|(r)|}
+ r
+}, '[ruby-dev:31507]'
+
+=begin
+# generated by this script:
+
+3.times{|i|
+ 8.times{|e|
+ ary = (0...e).to_a
+ a,b,c,d,e,f = nil
+ vals = %w(a b c d e f)
+ vals[i] = '*' + vals[i]
+ program = "#{vals.join(", ")} = *ary"
+ eval(program)
+ ans = [a,b,c,d,e,f]
+ puts %Q{
+ assert_equal "#{ans.inspect}", %q{
+ ary = #{ary.inspect}
+ #{program}; [a, b, c, d, e, f]
+ }}
+ }
+}
+=end
+
+ assert_equal "[[], nil, nil, nil, nil, nil]", %q{
+ ary = []
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[], 0, nil, nil, nil, nil]", %q{
+ ary = [0]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[], 0, 1, nil, nil, nil]", %q{
+ ary = [0, 1]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[], 0, 1, 2, nil, nil]", %q{
+ ary = [0, 1, 2]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[], 0, 1, 2, 3, nil]", %q{
+ ary = [0, 1, 2, 3]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[], 0, 1, 2, 3, 4]", %q{
+ ary = [0, 1, 2, 3, 4]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[0], 1, 2, 3, 4, 5]", %q{
+ ary = [0, 1, 2, 3, 4, 5]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[[0, 1], 2, 3, 4, 5, 6]", %q{
+ ary = [0, 1, 2, 3, 4, 5, 6]
+ *a, b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[nil, [], nil, nil, nil, nil]", %q{
+ ary = []
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [], nil, nil, nil, nil]", %q{
+ ary = [0]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [], 1, nil, nil, nil]", %q{
+ ary = [0, 1]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [], 1, 2, nil, nil]", %q{
+ ary = [0, 1, 2]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [], 1, 2, 3, nil]", %q{
+ ary = [0, 1, 2, 3]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [], 1, 2, 3, 4]", %q{
+ ary = [0, 1, 2, 3, 4]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [1], 2, 3, 4, 5]", %q{
+ ary = [0, 1, 2, 3, 4, 5]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, [1, 2], 3, 4, 5, 6]", %q{
+ ary = [0, 1, 2, 3, 4, 5, 6]
+ a, *b, c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[nil, nil, [], nil, nil, nil]", %q{
+ ary = []
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, nil, [], nil, nil, nil]", %q{
+ ary = [0]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, 1, [], nil, nil, nil]", %q{
+ ary = [0, 1]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, 1, [], 2, nil, nil]", %q{
+ ary = [0, 1, 2]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, 1, [], 2, 3, nil]", %q{
+ ary = [0, 1, 2, 3]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, 1, [], 2, 3, 4]", %q{
+ ary = [0, 1, 2, 3, 4]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, 1, [2], 3, 4, 5]", %q{
+ ary = [0, 1, 2, 3, 4, 5]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+ assert_equal "[0, 1, [2, 3], 4, 5, 6]", %q{
+ ary = [0, 1, 2, 3, 4, 5, 6]
+ a, b, *c, d, e, f = *ary; [a, b, c, d, e, f]
+ }
+
+
+#
+assert_equal 'ok', %q{
+ a,s=[],"aaa"
+ 300.times { a<<s; s=s.succ }
+ eval <<-END__
+ GC.stress=true
+ Fiber.new do
+ #{ a.join(",") },*zzz=1
+ end.resume
+ END__
+ :ok
+}, '[ruby-dev:32581]'
+
+assert_equal 'ok', %q{
+ while true
+ *, z = 1
+ break
+ end
+ :ok
+}, '[ruby-dev:32892]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_method.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_method.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_method.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1177 @@
+# regular argument
+assert_equal '1', 'def m() 1 end; m()'
+assert_equal '1', 'def m(a) a end; m(1)'
+assert_equal '[1, 2]', 'def m(a,b) [a, b] end; m(1,2)'
+assert_equal '[1, 2, 3]', 'def m(a,b,c) [a, b, c] end; m(1,2,3)'
+assert_equal 'wrong number of arguments (1 for 0)', %q{
+ def m; end
+ begin
+ m(1)
+ rescue => e
+ e.message
+ end
+}
+
+assert_equal 'wrong number of arguments (0 for 1)', %q{
+ def m a; end
+ begin
+ m
+ rescue => e
+ e.message
+ end
+}
+
+# default argument
+assert_equal '1', 'def m(x=1) x end; m()'
+assert_equal '1', 'def m(x=7) x end; m(1)'
+assert_equal '1', 'def m(a,x=1) x end; m(7)'
+assert_equal '1', 'def m(a,x=7) x end; m(7,1)'
+assert_equal '1', 'def m(a,b,x=1) x end; m(7,7)'
+assert_equal '1', 'def m(a,b,x=7) x end; m(7,7,1)'
+assert_equal '1', 'def m(a,x=1,y=1) x end; m(7)'
+assert_equal '1', 'def m(a,x=1,y=1) y end; m(7)'
+assert_equal '1', 'def m(a,x=7,y=1) x end; m(7,1)'
+assert_equal '1', 'def m(a,x=7,y=1) y end; m(7,1)'
+assert_equal '1', 'def m(a,x=7,y=7) x end; m(7,1,1)'
+assert_equal '1', 'def m(a,x=7,y=7) y end; m(7,1,1)'
+
+# rest argument
+assert_equal '[]', 'def m(*a) a end; m().inspect'
+assert_equal '[1]', 'def m(*a) a end; m(1).inspect'
+assert_equal '[1, 2]', 'def m(*a) a end; m(1,2).inspect'
+assert_equal '[]', 'def m(x,*a) a end; m(7).inspect'
+assert_equal '[1]', 'def m(x,*a) a end; m(7,1).inspect'
+assert_equal '[1, 2]', 'def m(x,*a) a end; m(7,1,2).inspect'
+assert_equal '[]', 'def m(x,y,*a) a end; m(7,7).inspect'
+assert_equal '[1]', 'def m(x,y,*a) a end; m(7,7,1).inspect'
+assert_equal '[1, 2]', 'def m(x,y,*a) a end; m(7,7,1,2).inspect'
+assert_equal '[]', 'def m(x,y=7,*a) a end; m(7).inspect'
+assert_equal '[]', 'def m(x,y,z=7,*a) a end; m(7,7).inspect'
+assert_equal '[]', 'def m(x,y,z=7,*a) a end; m(7,7,7).inspect'
+assert_equal '[]', 'def m(x,y,z=7,zz=7,*a) a end; m(7,7,7).inspect'
+assert_equal '[]', 'def m(x,y,z=7,zz=7,*a) a end; m(7,7,7,7).inspect'
+assert_equal '1', 'def m(x,y,z=7,zz=1,*a) zz end; m(7,7,7).inspect'
+assert_equal '1', 'def m(x,y,z=7,zz=1,*a) zz end; m(7,7,7).inspect'
+assert_equal '1', 'def m(x,y,z=7,zz=7,*a) zz end; m(7,7,7,1).inspect'
+
+# block argument
+assert_equal 'Proc', 'def m(&block) block end; m{}.class'
+assert_equal 'nil', 'def m(&block) block end; m().inspect'
+assert_equal 'Proc', 'def m(a,&block) block end; m(7){}.class'
+assert_equal 'nil', 'def m(a,&block) block end; m(7).inspect'
+assert_equal '1', 'def m(a,&block) a end; m(1){}'
+assert_equal 'Proc', 'def m(a,b=nil,&block) block end; m(7){}.class'
+assert_equal 'nil', 'def m(a,b=nil,&block) block end; m(7).inspect'
+assert_equal 'Proc', 'def m(a,b=nil,&block) block end; m(7,7){}.class'
+assert_equal '1', 'def m(a,b=nil,&block) b end; m(7,1){}'
+assert_equal 'Proc', 'def m(a,b=nil,*c,&block) block end; m(7){}.class'
+assert_equal 'nil', 'def m(a,b=nil,*c,&block) block end; m(7).inspect'
+assert_equal '1', 'def m(a,b=nil,*c,&block) a end; m(1).inspect'
+assert_equal '1', 'def m(a,b=1,*c,&block) b end; m(7).inspect'
+assert_equal '1', 'def m(a,b=7,*c,&block) b end; m(7,1).inspect'
+assert_equal '[1]', 'def m(a,b=7,*c,&block) c end; m(7,7,1).inspect'
+
+# splat
+assert_equal '1', 'def m(a) a end; m(*[1])'
+assert_equal '1', 'def m(x,a) a end; m(7,*[1])'
+assert_equal '1', 'def m(x,y,a) a end; m(7,7,*[1])'
+assert_equal '1', 'def m(a,b) a end; m(*[1,7])'
+assert_equal '1', 'def m(a,b) b end; m(*[7,1])'
+assert_equal '1', 'def m(x,a,b) b end; m(7,*[7,1])'
+assert_equal '1', 'def m(x,y,a,b) b end; m(7,7,*[7,1])'
+assert_equal '1', 'def m(a,b,c) a end; m(*[1,7,7])'
+assert_equal '1', 'def m(a,b,c) b end; m(*[7,1,7])'
+assert_equal '1', 'def m(a,b,c) c end; m(*[7,7,1])'
+assert_equal '1', 'def m(x,a,b,c) a end; m(7,*[1,7,7])'
+assert_equal '1', 'def m(x,y,a,b,c) a end; m(7,7,*[1,7,7])'
+
+# hash argument
+assert_equal '1', 'def m(h) h end; m(7=>1)[7]'
+assert_equal '1', 'def m(h) h end; m(7=>1).size'
+assert_equal '1', 'def m(h) h end; m(7=>1, 8=>7)[7]'
+assert_equal '2', 'def m(h) h end; m(7=>1, 8=>7).size'
+assert_equal '1', 'def m(h) h end; m(7=>1, 8=>7, 9=>7)[7]'
+assert_equal '3', 'def m(h) h end; m(7=>1, 8=>7, 9=>7).size'
+assert_equal '1', 'def m(x,h) h end; m(7, 7=>1)[7]'
+assert_equal '1', 'def m(x,h) h end; m(7, 7=>1, 8=>7)[7]'
+assert_equal '1', 'def m(x,h) h end; m(7, 7=>1, 8=>7, 9=>7)[7]'
+assert_equal '1', 'def m(x,y,h) h end; m(7,7, 7=>1)[7]'
+assert_equal '1', 'def m(x,y,h) h end; m(7,7, 7=>1, 8=>7)[7]'
+assert_equal '1', 'def m(x,y,h) h end; m(7,7, 7=>1, 8=>7, 9=>7)[7]'
+
+# block argument
+assert_equal '1', %q(def m(&block) mm(&block) end
+ def mm() yield 1 end
+ m {|a| a })
+assert_equal '1', %q(def m(x,&block) mm(x,&block) end
+ def mm(x) yield 1 end
+ m(7) {|a| a })
+assert_equal '1', %q(def m(x,y,&block) mm(x,y,&block) end
+ def mm(x,y) yield 1 end
+ m(7,7) {|a| a })
+
+# recursive call
+assert_equal '1', %q(def m(n) n == 0 ? 1 : m(n-1) end; m(5))
+
+# instance method
+assert_equal '1', %q(class C; def m() 1 end end; C.new.m)
+assert_equal '1', %q(class C; def m(a) a end end; C.new.m(1))
+assert_equal '1', %q(class C; def m(a = 1) a end end; C.new.m)
+assert_equal '[1]', %q(class C; def m(*a) a end end; C.new.m(1).inspect)
+assert_equal '1', %q( class C
+ def m() mm() end
+ def mm() 1 end
+ end
+ C.new.m )
+
+# singleton method (const)
+assert_equal '1', %q(class C; def C.m() 1 end end; C.m)
+assert_equal '1', %q(class C; def C.m(a) a end end; C.m(1))
+assert_equal '1', %q(class C; def C.m(a = 1) a end end; C.m)
+assert_equal '[1]', %q(class C; def C.m(*a) a end end; C.m(1).inspect)
+assert_equal '1', %q(class C; end; def C.m() 1 end; C.m)
+assert_equal '1', %q(class C; end; def C.m(a) a end; C.m(1))
+assert_equal '1', %q(class C; end; def C.m(a = 1) a end; C.m)
+assert_equal '[1]', %q(class C; end; def C.m(*a) a end; C.m(1).inspect)
+assert_equal '1', %q(class C; def m() 7 end end; def C.m() 1 end; C.m)
+assert_equal '1', %q( class C
+ def C.m() mm() end
+ def C.mm() 1 end
+ end
+ C.m )
+
+# singleton method (lvar)
+assert_equal '1', %q(obj = Object.new; def obj.m() 1 end; obj.m)
+assert_equal '1', %q(obj = Object.new; def obj.m(a) a end; obj.m(1))
+assert_equal '1', %q(obj = Object.new; def obj.m(a=1) a end; obj.m)
+assert_equal '[1]', %q(obj = Object.new; def obj.m(*a) a end; obj.m(1))
+assert_equal '1', %q(class C; def m() 7 end; end
+ obj = C.new
+ def obj.m() 1 end
+ obj.m)
+
+# inheritance
+assert_equal '1', %q(class A; def m(a) a end end
+ class B < A; end
+ B.new.m(1))
+assert_equal '1', %q(class A; end
+ class B < A; def m(a) a end end
+ B.new.m(1))
+assert_equal '1', %q(class A; def m(a) a end end
+ class B < A; end
+ class C < B; end
+ C.new.m(1))
+
+# include
+assert_equal '1', %q(class A; def m(a) a end end
+ module M; end
+ class B < A; include M; end
+ B.new.m(1))
+assert_equal '1', %q(class A; end
+ module M; def m(a) a end end
+ class B < A; include M; end
+ B.new.m(1))
+
+# alias
+assert_equal '1', %q( def a() 1 end
+ alias m a
+ m() )
+assert_equal '1', %q( class C
+ def a() 1 end
+ alias m a
+ end
+ C.new.m )
+assert_equal '1', %q( class C
+ def a() 1 end
+ alias :m a
+ end
+ C.new.m )
+assert_equal '1', %q( class C
+ def a() 1 end
+ alias m :a
+ end
+ C.new.m )
+assert_equal '1', %q( class C
+ def a() 1 end
+ alias :m :a
+ end
+ C.new.m )
+assert_equal '1', %q( class C
+ def a() 1 end
+ alias m a
+ undef a
+ end
+ C.new.m )
+
+# undef
+assert_equal '1', %q( class C
+ def m() end
+ undef m
+ end
+ begin C.new.m; rescue NoMethodError; 1 end )
+assert_equal '1', %q( class A
+ def m() end
+ end
+ class C < A
+ def m() end
+ undef m
+ end
+ begin C.new.m; rescue NoMethodError; 1 end )
+assert_equal '1', %q( class A; def a() end end # [yarv-dev:999]
+ class B < A
+ def b() end
+ undef a, b
+ end
+ begin B.new.a; rescue NoMethodError; 1 end )
+assert_equal '1', %q( class A; def a() end end # [yarv-dev:999]
+ class B < A
+ def b() end
+ undef a, b
+ end
+ begin B.new.b; rescue NoMethodError; 1 end )
+
+assert_equal '3', %q{
+ def m1
+ 1
+ end
+ alias m2 m1
+ alias :"#{'m3'}" m1
+ m1 + m2 + m3
+}, '[ruby-dev:32308]'
+assert_equal '1', %q{
+ def foobar
+ end
+ undef :"foo#{:bar}"
+ 1
+}, '[ruby-dev:32308]'
+assert_equal '1', %q{
+ def foobar
+ 1
+ end
+ alias :"bar#{:baz}" :"foo#{:bar}"
+ barbaz
+}, '[ruby-dev:32308]'
+
+# private
+assert_equal '1', %q( class C
+ def m() mm() end
+ def mm() 1 end
+ private :mm
+ end
+ C.new.m )
+assert_equal '1', %q( class C
+ def m() 7 end
+ private :m
+ end
+ begin C.m; rescue NoMethodError; 1 end )
+assert_equal '1', %q( class C
+ def C.m() mm() end
+ def C.mm() 1 end
+ private_class_method :mm
+ end
+ C.m )
+assert_equal '1', %q( class C
+ def C.m() 7 end
+ private_class_method :m
+ end
+ begin C.m; rescue NoMethodError; 1 end )
+assert_equal '1', %q( class C; def m() 1 end end
+ C.new.m # cache
+ class C
+ alias mm m; private :mm
+ end
+ C.new.m
+ begin C.new.mm; 7; rescue NoMethodError; 1 end )
+
+# nested method
+assert_equal '1', %q( class C
+ def m
+ def mm() 1 end
+ end
+ end
+ C.new.m
+ C.new.mm )
+assert_equal '1', %q( class C
+ def m
+ def mm() 1 end
+ end
+ end
+ instance_eval "C.new.m; C.new.mm" )
+
+# method_missing
+assert_equal ':m', %q( class C
+ def method_missing(mid, *args) mid end
+ end
+ C.new.m.inspect )
+assert_equal ':mm', %q( class C
+ def method_missing(mid, *args) mid end
+ end
+ C.new.mm.inspect )
+assert_equal '[1, 2]', %q( class C
+ def method_missing(mid, *args) args end
+ end
+ C.new.m(1,2).inspect )
+assert_equal '1', %q( class C
+ def method_missing(mid, *args) yield 1 end
+ end
+ C.new.m {|a| a })
+assert_equal 'nil', %q( class C
+ def method_missing(mid, *args, &block) block end
+ end
+ C.new.m.inspect )
+
+# send
+assert_equal '1', %q( class C; def m() 1 end end;
+ C.new.__send__(:m) )
+assert_equal '1', %q( class C; def m() 1 end end;
+ C.new.send(:m) )
+assert_equal '1', %q( class C; def m(a) a end end;
+ C.new.send(:m,1) )
+assert_equal '1', %q( class C; def m(a,b) a end end;
+ C.new.send(:m,1,7) )
+assert_equal '1', %q( class C; def m(x,a=1) a end end;
+ C.new.send(:m,7) )
+assert_equal '1', %q( class C; def m(x,a=7) a end end;
+ C.new.send(:m,7,1) )
+assert_equal '[1, 2]', %q( class C; def m(*a) a end end;
+ C.new.send(:m,1,2).inspect )
+assert_equal '1', %q( class C; def m() 7 end; private :m end
+ begin C.new.public_send(:m); rescue NoMethodError; 1 end )
+assert_equal '1', %q( class C; def m() 1 end; private :m end
+ C.new.send(:m) )
+
+# with block
+assert_equal '[[:ok1, :foo], [:ok2, :foo, :bar]]',
+%q{
+ class C
+ def [](a)
+ $ary << [yield, a]
+ end
+ def []=(a, b)
+ $ary << [yield, a, b]
+ end
+ end
+
+ $ary = []
+ C.new[:foo, &lambda{:ok1}]
+ C.new[:foo, &lambda{:ok2}] = :bar
+ $ary
+}
+
+# with
+assert_equal '[:ok1, [:ok2, 11]]', %q{
+ class C
+ def []
+ $ary << :ok1
+ 10
+ end
+ def []=(a)
+ $ary << [:ok2, a]
+ end
+ end
+ $ary = []
+ C.new[]+=1
+ $ary
+}
+
+# splat and block arguments
+assert_equal %q{[[[:x, :y, :z], NilClass], [[1, :x, :y, :z], NilClass], [[1, 2, :x, :y, :z], NilClass], [[:obj], NilClass], [[1, :obj], NilClass], [[1, 2, :obj], NilClass], [[], Proc], [[1], Proc], [[1, 2], Proc], [[], Proc], [[1], Proc], [[1, 2], Proc], [[:x, :y, :z], Proc], [[1, :x, :y, :z], Proc], [[1, 2, :x, :y, :z], Proc]]}, %q{
+def m(*args, &b)
+ $result << [args, b.class]
+end
+$result = []
+ary = [:x, :y, :z]
+obj = :obj
+b = Proc.new{}
+
+m(*ary)
+m(1,*ary)
+m(1,2,*ary)
+m(*obj)
+m(1,*obj)
+m(1,2,*obj)
+m(){}
+m(1){}
+m(1,2){}
+m(&b)
+m(1,&b)
+m(1,2,&b)
+m(*ary,&b)
+m(1,*ary,&b)
+m(1,2,*ary,&b)
+$result
+}
+
+# post test
+assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4)}
+
+assert_equal %q{[1, 2, 3, :o2, [], 4, 5, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5)}
+
+assert_equal %q{[1, 2, 3, 4, [], 5, 6, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6)}
+
+assert_equal %q{[1, 2, 3, 4, [5], 6, 7, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7)}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6], 7, 8, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8)}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6, 7], 8, 9, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8, 9)}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8], 9, 10, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8, 9], 10, 11, NilClass, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)}
+
+assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4){}}
+
+assert_equal %q{[1, 2, 3, :o2, [], 4, 5, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5){}}
+
+assert_equal %q{[1, 2, 3, 4, [], 5, 6, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6){}}
+
+assert_equal %q{[1, 2, 3, 4, [5], 6, 7, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7){}}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6], 7, 8, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8){}}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6, 7], 8, 9, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8, 9){}}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8], 9, 10, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10){}}
+
+assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8, 9], 10, 11, Proc, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, b.class, x, y]
+end
+; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11){}}
+
+assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, x, y]
+end
+; m(1, 2, 3, 4)}
+
+assert_equal %q{[1, 2, 3, :o2, [], 4, 5, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, x, y]
+end
+; m(1, 2, 3, 4, 5)}
+
+assert_equal %q{[1, 2, 3, 4, [], 5, 6, nil, nil]}, %q{
+def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)
+ x, y = :x, :y if $foo
+ [m1, m2, o1, o2, r, p1, p2, x, y]
+end
+; m(1, 2, 3, 4, 5, 6)}
+
+
+#
+# super
+#
+=begin
+# below programs are generated by this program:
+
+BASE = <<EOS__
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; <TEST>; super; end; end
+EOS__
+
+tests = {
+%q{
+ def m
+} => %q{
+ C1.new.m
+},
+#
+%q{
+ def m a
+} => %q{
+ C1.new.m 1
+},
+%q{
+ def m a
+ a = :a
+} => %q{
+ C1.new.m 1
+},
+#
+%q{
+ def m a, o=:o
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+},
+%q{
+ def m a, o=:o
+ a = :a
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+},
+%q{
+ def m a, o=:o
+ o = :x
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+},
+#
+%q{
+ def m a, *r
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+ C1.new.m 1, 2, 3
+},
+%q{
+ def m a, *r
+ r = [:x, :y]
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+ C1.new.m 1, 2, 3
+},
+#
+%q{
+ def m a, o=:o, *r
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+ C1.new.m 1, 2, 3
+ C1.new.m 1, 2, 3, 4
+},
+#
+%q{
+ def m a, o=:o, *r, &b
+} => %q{
+ C1.new.m 1
+ C1.new.m 1, 2
+ C1.new.m 1, 2, 3
+ C1.new.m 1, 2, 3, 4
+ C1.new.m(1){}
+ C1.new.m(1, 2){}
+ C1.new.m(1, 2, 3){}
+ C1.new.m(1, 2, 3, 4){}
+},
+#
+"def m(m1, m2, o1=:o1, o2=:o2, p1, p2)" =>
+%q{
+C1.new.m(1,2,3,4)
+C1.new.m(1,2,3,4,5)
+C1.new.m(1,2,3,4,5,6)
+},
+#
+"def m(m1, m2, *r, p1, p2)" =>
+%q{
+C1.new.m(1,2,3,4)
+C1.new.m(1,2,3,4,5)
+C1.new.m(1,2,3,4,5,6)
+C1.new.m(1,2,3,4,5,6,7)
+C1.new.m(1,2,3,4,5,6,7,8)
+},
+#
+"def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)" =>
+%q{
+C1.new.m(1,2,3,4)
+C1.new.m(1,2,3,4,5)
+C1.new.m(1,2,3,4,5,6)
+C1.new.m(1,2,3,4,5,6,7)
+C1.new.m(1,2,3,4,5,6,7,8)
+C1.new.m(1,2,3,4,5,6,7,8,9)
+},
+
+###
+}
+
+
+tests.each{|setup, methods| setup = setup.dup; setup.strip!
+ setup = BASE.gsub(/<TEST>/){setup}
+ methods.split(/\n/).each{|m| m = m.dup; m.strip!
+ next if m.empty?
+ expr = "#{setup}; #{m}"
+ result = eval(expr)
+ puts "assert_equal %q{#{result.inspect}}, %q{\n#{expr}}"
+ puts
+ }
+}
+
+=end
+
+assert_equal %q{[:C0_m, [1, 2, :o1, :o2, 3, 4]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, p1, p2); super; end; end
+; C1.new.m(1,2,3,4)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, :o2, 4, 5]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6)}
+
+assert_equal %q{[:C0_m, [1, :o]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, 2]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r; super; end; end
+; C1.new.m 1, 2, 3}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r; super; end; end
+; C1.new.m 1, 2, 3, 4}
+
+assert_equal %q{[:C0_m, [:a]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a
+ a = :a; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6,7)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7, 8]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6,7,8)}
+
+assert_equal %q{[:C0_m, [1, :o]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, 2]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m 1, 2, 3}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m 1, 2, 3, 4}
+
+assert_equal %q{[:C0_m, [1, :o]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m(1){}}
+
+assert_equal %q{[:C0_m, [1, 2]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m(1, 2){}}
+
+assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m(1, 2, 3){}}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o, *r, &b; super; end; end
+; C1.new.m(1, 2, 3, 4){}}
+
+assert_equal %q{[:C0_m, [1, :x]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o
+ o = :x; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, :x]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o
+ o = :x; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:C0_m, [:a, :o]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o
+ a = :a; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [:a, 2]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o
+ a = :a; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:C0_m, [1]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, :x, :y]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, *r
+ r = [:x, :y]; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, :x, :y]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, *r
+ r = [:x, :y]; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:C0_m, [1, :x, :y]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, *r
+ r = [:x, :y]; super; end; end
+; C1.new.m 1, 2, 3}
+
+assert_equal %q{[:C0_m, [1, 2, :o1, :o2, 3, 4]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, :o2, 4, 5]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6,7)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7, 8]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6,7,8)}
+
+assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7, 8, 9]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
+; C1.new.m(1,2,3,4,5,6,7,8,9)}
+
+assert_equal %q{[:C0_m, [1]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, *r; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, 2]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, *r; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, *r; super; end; end
+; C1.new.m 1, 2, 3}
+
+assert_equal %q{[:C0_m, []]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m; super; end; end
+; C1.new.m}
+
+assert_equal %q{[:C0_m, [1, :o]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o; super; end; end
+; C1.new.m 1}
+
+assert_equal %q{[:C0_m, [1, 2]]}, %q{
+class C0; def m *args; [:C0_m, args]; end; end
+class C1 < C0; def m a, o=:o; super; end; end
+; C1.new.m 1, 2}
+
+assert_equal %q{[:ok, :ok, :ok, :ok, :ok, :ok, :ng, :ng]}, %q{
+ $ans = []
+ class Foo
+ def m
+ end
+ end
+
+ c1 = c2 = nil
+
+ lambda{
+ $SAFE = 4
+ c1 = Class.new{
+ def m
+ end
+ }
+ c2 = Class.new(Foo){
+ alias mm m
+ }
+ }.call
+
+ def test
+ begin
+ yield
+ rescue SecurityError
+ $ans << :ok
+ else
+ $ans << :ng
+ end
+ end
+
+ o1 = c1.new
+ o2 = c2.new
+
+ test{o1.m}
+ test{o2.mm}
+ test{o1.send :m}
+ test{o2.send :mm}
+ test{o1.public_send :m}
+ test{o2.public_send :mm}
+ test{o1.method(:m).call}
+ test{o2.method(:mm).call}
+ $ans
+}
+
+assert_equal 'ok', %q{
+ class C
+ def x=(n)
+ end
+ def m
+ self.x = :ok
+ end
+ end
+ C.new.m
+}
+
+assert_equal 'ok', %q{
+ proc{
+ $SAFE = 1
+ class C
+ def m
+ :ok
+ end
+ end
+ }.call
+ C.new.m
+}, '[ruby-core:11998]'
+
+assert_equal 'ok', %q{
+ proc{
+ $SAFE = 2
+ class C
+ def m
+ :ok
+ end
+ end
+ }.call
+ C.new.m
+}, '[ruby-core:11998]'
+
+assert_equal 'ok', %q{
+ proc{
+ $SAFE = 3
+ class C
+ def m
+ :ng
+ end
+ end
+ }.call
+ begin
+ C.new.m
+ rescue SecurityError
+ :ok
+ end
+}, '[ruby-core:11998]'
+
+assert_equal 'ok', %q{
+ class B
+ def m() :fail end
+ end
+ class C < B
+ undef m
+ begin
+ remove_method :m
+ rescue NameError
+ end
+ end
+ begin
+ C.new.m
+ rescue NameError
+ :ok
+ end
+}, '[ruby-dev:31816], [ruby-dev:31817]'
+
+assert_normal_exit %q{
+ begin
+ Process.setrlimit(Process::RLIMIT_STACK, 4_202_496)
+ # FreeBSD fails this less than 4M + 8K bytes.
+ rescue Exception
+ exit
+ end
+ class C
+ attr "a" * (10*1024*1024)
+ end
+}, '[ruby-dev:31818]'
+
+assert_equal 'ok', %q{
+ class Module
+ def define_method2(name, &block)
+ define_method(name, &block)
+ end
+ end
+ class C
+ define_method2(:m) {|x, y| :fail }
+ end
+ begin
+ C.new.m([1,2])
+ rescue ArgumentError
+ :ok
+ end
+}
+
+assert_not_match /method_missing/, %q{
+ STDERR.reopen(STDOUT)
+ variable_or_mehtod_not_exist
+}
+
+assert_equal '[false, false, false, false, true, true]', %q{
+ class C
+ define_method(:foo) {
+ block_given?
+ }
+ end
+
+ C.new.foo {}
+
+ class D
+ def foo
+ D.module_eval{
+ define_method(:m1){
+ block_given?
+ }
+ }
+ end
+ def bar
+ D.module_eval{
+ define_method(:m2){
+ block_given?
+ }
+ }
+ end
+ end
+
+ D.new.foo
+ D.new.bar{}
+ [C.new.foo, C.new.foo{}, D.new.m1, D.new.m1{}, D.new.m2, D.new.m2{}]
+}, '[ruby-core:14813]'
+
+assert_equal 'ok', %q{
+ class Foo
+ define_method(:foo) do |&b|
+ b.call
+ end
+ end
+ Foo.new.foo do
+ break :ok
+ end
+}, '[ruby-dev:36028]'
+
+assert_equal '[1, 2, [3, 4]]', %q{
+ def regular(a, b, *c)
+ [a, b, c]
+ end
+ regular(*[], 1, *[], *[2, 3], *[], 4)
+}, '[ruby-core:19413]'
+
+assert_equal '[1, [:foo, 3, 4, :foo]]', %q{
+ def regular(a, *b)
+ [a, b]
+ end
+ a = b = [:foo]
+ regular(1, *a, *[3, 4], *b)
+}
+
+assert_equal '["B", "A"]', %q{
+ class A
+ def m
+ 'A'
+ end
+ end
+
+ class B < A
+ define_method(:m) do
+ ['B', super()]
+ end
+ end
+
+ class C < B
+ end
+
+ C.new.m
+}
+
+assert_equal 'ok', %q{
+ module Foo
+ def foo
+ begin
+ super
+ rescue NoMethodError
+ :ok
+ end
+ end
+ module_function :foo
+ end
+ Foo.foo
+}, '[ruby-dev:37587]'
+
+assert_equal 'Object#foo', %q{
+ class Object
+ def self.foo
+ "Object.foo"
+ end
+ def foo
+ "Object#foo"
+ end
+ end
+
+ module Foo
+ def foo
+ begin
+ super
+ rescue NoMethodError
+ :ok
+ end
+ end
+ module_function :foo
+ end
+ Foo.foo
+}, '[ruby-dev:37587]'
+
+assert_normal_exit %q{
+ class BasicObject
+ remove_method :method_missing
+ end
+ begin
+ "a".lalala!
+ rescue NoMethodError => e
+ e.message == "undefined method `lalala!' for \"a\":String" ? :ok : :ng
+ end
+}, '[ruby-core:22298]'
+
+assert_equal 'ok', %q{
+ "hello"[0] ||= "H"
+ "ok"
+}
+
+assert_equal 'ok', %q{
+ "hello"[0, 1] ||= "H"
+ "ok"
+}
+
+assert_equal 'ok', %q{
+ class C
+ define_method(:foo) do
+ C.class_eval { remove_method(:foo) }
+ super()
+ end
+ end
+ begin
+ C.new.foo
+ rescue NoMethodError
+ 'ok'
+ end
+}
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_objectspace.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_objectspace.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_objectspace.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,34 @@
+assert_normal_exit %q{
+ eval("", TOPLEVEL_BINDING)
+ minobj = ObjectSpace.to_enum(:each_object).min_by {|a| a.object_id }
+ maxobj = ObjectSpace.to_enum(:each_object).max_by {|a| a.object_id }
+ (((minobj.object_id-100)..(minobj.object_id+100))+
+ ((maxobj.object_id-100)..(maxobj.object_id+100))).each {|id|
+ begin
+ o = ObjectSpace._id2ref(id)
+ rescue RangeError
+ next
+ end
+ o.inspect if defined?(o.inspect)
+ }
+}, '[ruby-dev:31911]'
+
+assert_normal_exit %q{
+ ary = (1..10).to_a
+ ary.permutation(2) {|x|
+ if x == [1,2]
+ ObjectSpace.each_object(String) {|s|
+ s.clear if !s.frozen? && (s.length == 40 || s.length == 80)
+ }
+ end
+ }
+}, '[ruby-dev:31982]'
+
+assert_normal_exit %q{
+ ary = (1..100).to_a
+ ary.permutation(2) {|x|
+ if x == [1,2]
+ ObjectSpace.each_object(Array) {|o| o.clear if o == ary && o.object_id != ary.object_id }
+ end
+ }
+}, '[ruby-dev:31985]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_proc.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_proc.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_proc.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,431 @@
+assert_equal %q{[1, 2, 3]}, %q{
+ def getproc &b
+ b
+ end
+
+ def m
+ yield
+ end
+
+ m{
+ i = 1
+ m{
+ j = 2
+ m{
+ k = 3
+ getproc{
+ [i, j, k]
+ }
+ }
+ }
+ }.call
+}
+assert_equal %q{7}, %q{
+ def make_proc(&b)
+ b
+ end
+
+ def make_closure
+ a = 0
+ make_proc{
+ a+=1
+ }
+ end
+
+ cl = make_closure
+ cl.call + cl.call * cl.call
+}
+assert_equal %q{ok}, %q{
+ class C
+ def foo
+ :ok
+ end
+ end
+
+ def block
+ C.method(:new).to_proc
+ end
+ b = block()
+ b.call.foo
+}
+assert_equal %q{[0, 1, :last, 0, 2, :last]}, %q{
+ def proc &b
+ b
+ end
+
+ pr = []
+ proc{|i_b|
+ p3 = proc{|j_b|
+ pr << proc{|k_b|
+ [i_b, j_b, k_b]
+ }
+ }
+ p3.call(1)
+ p3.call(2)
+ }.call(0)
+
+ pr[0].call(:last).concat pr[1].call(:last)
+}
+assert_equal %q{12}, %q{
+ def iter
+ yield
+ end
+
+ def getproc &b
+ b
+ end
+
+ iter{
+ bvar = 3
+ getproc{
+ bvar2 = 4
+ bvar * bvar2
+ }
+ }.call
+}
+assert_equal %q{200}, %q{
+ def iter
+ yield
+ end
+
+ def getproc &b
+ b
+ end
+
+ loc1 = 0
+ pr1 = iter{
+ bl1 = 1
+ getproc{
+ loc1 += 1
+ bl1 += 1
+ loc1 + bl1
+ }
+ }
+
+ pr2 = iter{
+ bl1 = 1
+ getproc{
+ loc1 += 1
+ bl1 += 1
+ loc1 + bl1
+ }
+ }
+
+ pr1.call; pr2.call
+ pr1.call; pr2.call
+ pr1.call; pr2.call
+ (pr1.call + pr2.call) * loc1
+}
+assert_equal %q{[1, 2]}, %q{
+ def proc(&pr)
+ pr
+ end
+
+ def m
+ a = 1
+ m2{
+ a
+ }
+ end
+
+ def m2
+ b = 2
+ proc{
+ [yield, b]
+ }
+ end
+
+ pr = m
+ x = ['a', 1,2,3,4,5,6,7,8,9,0,
+ 1,2,3,4,5,6,7,8,9,0,
+ 1,2,3,4,5,6,7,8,9,0,
+ 1,2,3,4,5,6,7,8,9,0,
+ 1,2,3,4,5,6,7,8,9,0,]
+ pr.call
+}
+assert_equal %q{1}, %q{
+ def proc(&pr)
+ pr
+ end
+
+ def m
+ a = 1
+ m2{
+ a
+ }
+ end
+
+ def m2
+ b = 2
+ proc{
+ [yield, b]
+ }
+ 100000.times{|x|
+ "#{x}"
+ }
+ yield
+ end
+ m
+}
+assert_equal %q{[:C, :C]}, %q{
+ Const = :top
+ class C
+ Const = :C
+ $pr = proc{
+ (1..2).map{
+ Const
+ }
+ }
+ end
+ $pr.call
+}
+assert_equal %q{top}, %q{
+ Const = :top
+ class C
+ Const = :C
+ end
+ pr = proc{
+ Const
+ }
+ C.class_eval %q{
+ pr.call
+ }
+}
+assert_equal %q{1}, %q{
+ def m(&b)
+ b
+ end
+
+ m{|e_proctest| e_proctest}.call(1)
+}
+assert_equal %q{12}, %q{
+ def m(&b)
+ b
+ end
+
+ m{|e_proctest1, e_proctest2|
+ a = e_proctest1 * e_proctest2 * 2
+ a * 3
+ }.call(1, 2)
+}
+assert_equal %q{[[], [1], [1, 2], [1, 2, 3]]}, %q{
+ [
+ Proc.new{|*args| args}.call(),
+ Proc.new{|*args| args}.call(1),
+ Proc.new{|*args| args}.call(1, 2),
+ Proc.new{|*args| args}.call(1, 2, 3),
+ ]
+}
+assert_equal %q{[[nil, []], [1, []], [1, [2]], [1, [2, 3]]]}, %q{
+ [
+ Proc.new{|a, *b| [a, b]}.call(),
+ Proc.new{|a, *b| [a, b]}.call(1),
+ Proc.new{|a, *b| [a, b]}.call(1, 2),
+ Proc.new{|a, *b| [a, b]}.call(1, 2, 3),
+ ]
+}
+assert_equal %q{0}, %q{
+ pr = proc{
+ $SAFE
+ }
+ $SAFE = 1
+ pr.call
+}
+assert_equal %q{[1, 0]}, %q{
+ pr = proc{
+ $SAFE += 1
+ }
+ [pr.call, $SAFE]
+}
+assert_equal %q{1}, %q{
+ def m(&b)
+ b
+ end
+ m{1}.call
+}
+assert_equal %q{3}, %q{
+ def m(&b)
+ b
+ end
+
+ m{
+ a = 1
+ a + 2
+ }.call
+}
+assert_equal %Q{ok\n}, %q{
+ class A; def get_block; proc {puts "ok"} end end
+ block = A.new.get_block
+ GC.start
+ block.call
+}, '[ruby-core:14885]'
+
+assert_equal 'ok', %q{
+ a = lambda {|x, y, &b| b }
+ b = a.curry[1]
+ if b.call(2){} == nil
+ :ng
+ else
+ :ok
+ end
+}, '[ruby-core:15551]'
+
+assert_equal 'ok', %q{
+ lambda {
+ break :ok
+ :ng
+ }.call
+}, '[ruby-dev:34646]'
+
+assert_equal %q{[:bar, :foo]}, %q{
+ def foo
+ klass = Class.new do
+ define_method(:bar) do
+ return :bar
+ end
+ end
+ [klass.new.bar, :foo]
+ end
+ foo
+}, "[ ruby-Bugs-19304 ]"
+
+assert_equal 'ok', %q{
+ $x = :ok
+ def def7(x, y)
+ x[y]
+ $x = :ng
+ end
+ def test_def7
+ def7(lambda {|x| x.call}, Proc.new {return})
+ $x = :ng
+ end
+ test_def7
+ $x
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ lambda { a = lambda { return }; $x = :ng; a[]; $x = :ok }.call
+ $x
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ lambda { a = lambda { break }; $x = :ng; a[]; $x = :ok }.call
+ $x
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ def def8
+ $x = :ng
+ lambda { a = Proc.new { return }; a[]}.call
+ $x = :ok
+ end
+ def8
+ $x
+}, '[ruby-core:17164]'
+
+
+assert_equal 'ok', %q{
+ def def9
+ lambda {|a| $x = :ok; a[]; $x = :ng }.call(Proc.new { return })
+ $x = :ng
+ end
+ def9
+ $x
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ def def10
+ $x = :ng
+ lambda { 1.times { return } }.call
+ $x = :ok
+ end
+ $x = :ok
+ def10
+ $x
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ def def11
+ yield
+ end
+ begin
+ lambda { def11 { return } }.call
+ rescue LocalJumpError
+ :ng
+ else
+ :ok
+ end
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ def def12
+ b = Proc.new { $x = :ng; lambda { return }.call; $x = :ok }.call
+ end
+ def12
+ $x
+}, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+ def m
+ pr = proc{
+ proc{
+ return :ok
+ }
+ }.call
+ pr.call
+ :ng
+ end
+ m()
+}
+
+assert_equal 'ok', %q{
+ class Foo
+ def call_it
+ p = Proc.new
+ p.call
+ end
+ end
+
+ def give_it
+ proc { :ok }
+ end
+
+ f = Foo.new
+ a_proc = give_it
+ f.call_it(&give_it())
+}, '[ruby-core:15711]'
+
+assert_equal 'foo!', %q{
+ class FooProc < Proc
+ def initialize
+ @foo = "foo!"
+ end
+
+ def bar
+ @foo
+ end
+ end
+
+ def bar
+ FooProc.new &lambda{
+ p 1
+ }
+ end
+
+ fp = bar(&lambda{
+ p 2
+ })
+
+ fp.bar
+}, 'Subclass of Proc'
+
+assert_equal 'ok', %q{
+ o = Object.new
+ def o.write(s); end
+ $stderr = o
+ at_exit{
+ print $!.message
+ }
+ raise "ok"
+}
+
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_struct.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_struct.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_struct.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,5 @@
+assert_equal 'Struct::Foo', %q{
+ Struct.instance_eval { const_set(:Foo, nil) }
+ Struct.new("Foo")
+ Struct::Foo
+}
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_syntax.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_syntax.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_syntax.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,902 @@
+assert_equal %q{4}, %q{1 && 2 && 3 && 4}
+assert_equal %q{}, %q{1 && nil && 3 && 4}
+assert_equal %q{}, %q{1 && 2 && 3 && nil}
+assert_equal %q{false}, %q{1 && 2 && 3 && false}
+assert_equal %q{4}, %q{1 and 2 and 3 and 4}
+assert_equal %q{}, %q{1 and nil and 3 and 4}
+assert_equal %q{}, %q{1 and 2 and 3 and nil}
+assert_equal %q{false}, %q{1 and 2 and 3 and false}
+assert_equal %q{}, %q{nil && true}
+assert_equal %q{false}, %q{false && true}
+assert_equal %q{}, %q{
+ case 1
+ when 2
+ :ng
+ end}
+assert_equal %q{ok}, %q{
+ case 1
+ when 10,20,30
+ :ng1
+ when 1,2,3
+ :ok
+ when 100,200,300
+ :ng2
+ else
+ :elseng
+ end}
+assert_equal %q{elseok}, %q{
+ case 123
+ when 10,20,30
+ :ng1
+ when 1,2,3
+ :ng2
+ when 100,200,300
+ :ng3
+ else
+ :elseok
+ end
+}
+assert_equal %q{ok}, %q{
+ case 'test'
+ when /testx/
+ :ng1
+ when /test/
+ :ok
+ when /tetxx/
+ :ng2
+ else
+ :ng_else
+ end
+}
+assert_equal %q{ok}, %q{
+ case Object.new
+ when Object
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ case Object
+ when Object.new
+ :ng
+ else
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ case 'test'
+ when 'tes'
+ :ng
+ when 'te'
+ :ng
+ else
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ case 'test'
+ when 'tes'
+ :ng
+ when 'te'
+ :ng
+ when 'test'
+ :ok
+ end
+}
+assert_equal %q{ng}, %q{
+ case 'test'
+ when 'tes'
+ :ng
+ when /te/
+ :ng
+ else
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ case 'test'
+ when 'tes'
+ :ng
+ when /test/
+ :ok
+ else
+ :ng
+ end
+}
+assert_equal %q{100}, %q{
+ def test(arg)
+ case 1
+ when 2
+ 3
+ end
+ return arg
+ end
+
+ test(100)
+}
+assert_equal %q{ok}, %q{
+ ary = [1, 2]
+ case 1
+ when *ary
+ :ok
+ else
+ :ng
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [1, 2]
+ case 3
+ when *ary
+ :ng
+ else
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [1, 2]
+ case 1
+ when :x, *ary
+ :ok
+ when :z
+ :ng1
+ else
+ :ng2
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [1, 2]
+ case 3
+ when :x, *ary
+ :ng1
+ when :z
+ :ng2
+ else
+ :ok
+ end
+}
+assert_equal %q{[:false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep]}, %q{
+
+ def make_perm ary, num
+ if num == 1
+ ary.map{|e| [e]}
+ else
+ base = make_perm(ary, num-1)
+ res = []
+ base.each{|b|
+ ary.each{|e|
+ res << [e] + b
+ }
+ }
+ res
+ end
+ end
+
+ def each_test
+ conds = make_perm(['fv', 'tv'], 3)
+ bangs = make_perm(['', '!'], 3)
+ exprs = make_perm(['and', 'or'], 3)
+ ['if', 'unless'].each{|syn|
+ conds.each{|cs|
+ bangs.each{|bs|
+ exprs.each{|es|
+ yield(syn, cs, bs, es)
+ }
+ }
+ }
+ }
+ end
+
+ fv = false
+ tv = true
+
+ $ans = []
+ each_test{|syn, conds, bangs, exprs|
+ c1, c2, c3 = conds
+ bang1, bang2, bang3 = bangs
+ e1, e2 = exprs
+ eval %Q{
+ #{syn} #{bang1}#{c1} #{e1} #{bang2}#{c2} #{e2} #{bang3}#{c3}
+ $ans << :then
+ else
+ $ans << :false
+ end
+ }
+ }
+
+ each_test{|syn, conds, bangs, exprs|
+ c1, c2, c3 = conds
+ bang1, bang2, bang3 = bangs
+ e1, e2 = exprs
+ eval %Q{
+ #{syn} #{bang1}#{c1} #{e1} #{bang2}#{c2} #{e2} #{bang3}#{c3}
+ $ans << :then
+ end
+ $ans << :sep
+ }
+ }
+ $ans
+}
+assert_equal %q{}, %q{
+ defined?(m)
+}
+assert_equal %q{method}, %q{
+ def m
+ end
+ defined?(m)
+}
+assert_equal %q{}, %q{
+ defined?(a.class)
+}
+assert_equal %q{method}, %q{
+ a = 1
+ defined?(a.class)
+}
+assert_equal %q{["method", "method", "method", "method", nil, nil, "method", "method", "method", nil]}, %q{
+ class C
+ def test
+ [defined?(m1()), defined?(self.m1), defined?(C.new.m1),
+ defined?(m2()), defined?(self.m2), defined?(C.new.m2),
+ defined?(m3()), defined?(self.m3), defined?(C.new.m3)]
+ end
+ def m1
+ end
+ private
+ def m2
+ end
+ protected
+ def m3
+ end
+ end
+ C.new.test + [defined?(C.new.m3)]
+}
+assert_equal %q{[nil, nil, nil, nil, "global-variable", "global-variable", nil, nil]}, %q{
+ $ans = [defined?($1), defined?($2), defined?($3), defined?($4)]
+ /(a)(b)/ =~ 'ab'
+ $ans + [defined?($1), defined?($2), defined?($3), defined?($4)]
+}
+assert_equal %q{nilselftruefalse}, %q{
+ defined?(nil) + defined?(self) +
+ defined?(true) + defined?(false)
+}
+assert_equal %q{}, %q{
+ defined?(@a)
+}
+assert_equal %q{instance-variable}, %q{
+ @a = 1
+ defined?(@a)
+}
+assert_equal %q{}, %q{
+ defined?(@@a)
+}
+assert_equal %q{class variable}, %q{
+ @@a = 1
+ defined?(@@a)
+}
+assert_equal %q{}, %q{
+ defined?($a)
+}
+assert_equal %q{global-variable}, %q{
+ $a = 1
+ defined?($a)
+}
+assert_equal %q{}, %q{
+ defined?(C_definedtest)
+}
+assert_equal %q{constant}, %q{
+ C_definedtest = 1
+ defined?(C_definedtest)
+}
+assert_equal %q{}, %q{
+ defined?(::C_definedtest)
+}
+assert_equal %q{constant}, %q{
+ C_definedtest = 1
+ defined?(::C_definedtest)
+}
+assert_equal %q{}, %q{
+ defined?(C_definedtestA::C_definedtestB::C_definedtestC)
+}
+assert_equal %q{constant}, %q{
+ class C_definedtestA
+ class C_definedtestB
+ C_definedtestC = 1
+ end
+ end
+ defined?(C_definedtestA::C_definedtestB::C_definedtestC)
+}
+assert_equal %q{30}, %q{
+ sum = 0
+ 30.times{|ib|
+ if ib % 10 == 0 .. true
+ sum += ib
+ end
+ }
+ sum
+}
+assert_equal %q{63}, %q{
+ sum = 0
+ 30.times{|ib|
+ if ib % 10 == 0 ... true
+ sum += ib
+ end
+ }
+ sum
+}
+assert_equal %q{[["NUM", "Type: NUM\n"], ["NUM", "123\n"], ["NUM", "456\n"], ["NUM", "Type: ARP\n"], ["NUM", "aaa\n"], ["NUM", "bbb\n"], ["NUM", "\f\n"], ["ARP", "Type: ARP\n"], ["ARP", "aaa\n"], ["ARP", "bbb\n"]]}, %q{
+ t = nil
+ unless ''.respond_to? :lines
+ class String
+ def lines
+ self
+ end
+ end
+ end
+ ary = []
+"this must not print
+Type: NUM
+123
+456
+Type: ARP
+aaa
+bbb
+\f
+this must not print
+hoge
+Type: ARP
+aaa
+bbb
+".lines.each{|l|
+ if (t = l[/^Type: (.*)/, 1])..(/^\f/ =~ l)
+ ary << [t, l]
+ end
+ }
+ ary
+}
+assert_equal %q{1}, %q{if true then 1 ; end}
+assert_equal %q{}, %q{if false then 1 ; end}
+assert_equal %q{1}, %q{if true then 1 ; else; 2; end}
+assert_equal %q{2}, %q{if false then 1 ; else; 2; end}
+assert_equal %q{}, %q{if true then ; elsif true then ; 1 ; end}
+assert_equal %q{1}, %q{if false then ; elsif true then ; 1 ; end}
+assert_equal %q{}, %q{unless true then 1 ; end}
+assert_equal %q{1}, %q{unless false then 1 ; end}
+assert_equal %q{2}, %q{unless true then 1 ; else; 2; end}
+assert_equal %q{1}, %q{unless false then 1 ; else; 2; end}
+assert_equal %q{1}, %q{1 if true}
+assert_equal %q{}, %q{1 if false}
+assert_equal %q{}, %q{1 if nil}
+assert_equal %q{}, %q{1 unless true}
+assert_equal %q{1}, %q{1 unless false}
+assert_equal %q{1}, %q{1 unless nil}
+assert_equal %q{1}, %q{1 || 2 || 3 || 4}
+assert_equal %q{1}, %q{1 || false || 3 || 4}
+assert_equal %q{2}, %q{nil || 2 || 3 || 4}
+assert_equal %q{2}, %q{false || 2 || 3 || 4}
+assert_equal %q{false}, %q{nil || false || nil || false}
+assert_equal %q{1}, %q{1 or 2 or 3 or 4}
+assert_equal %q{1}, %q{1 or false or 3 or 4}
+assert_equal %q{2}, %q{nil or 2 or 3 or 4}
+assert_equal %q{2}, %q{false or 2 or 3 or 4}
+assert_equal %q{false}, %q{nil or false or nil or false}
+assert_equal %q{elseng}, %q{
+ case
+ when 1==2, 2==3
+ :ng1
+ when false, 4==5
+ :ok
+ when false
+ :ng2
+ else
+ :elseng
+ end
+}
+assert_equal %q{ok}, %q{
+ case
+ when nil, nil
+ :ng1
+ when 1,2,3
+ :ok
+ when false, false
+ :ng2
+ else
+ :elseng
+ end
+}
+assert_equal %q{elseok}, %q{
+ case
+ when nil
+ :ng1
+ when false
+ :ng2
+ else
+ :elseok
+ end}
+assert_equal %q{}, %q{
+ case
+ when 1
+ end
+}
+assert_equal %q{ok}, %q{
+ r = nil
+ ary = []
+ case
+ when false
+ r = :ng1
+ when false, false
+ r = :ng2
+ when *ary
+ r = :ng3
+ when false, *ary
+ r = :ng4
+ when true, *ary
+ r = :ok
+ end
+ r
+}
+assert_equal %q{ok}, %q{
+ ary = []
+ case
+ when false, *ary
+ :ng
+ else
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [false, nil]
+ case
+ when *ary
+ :ng
+ else
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [false, nil]
+ case
+ when *ary
+ :ng
+ when true
+ :ok
+ else
+ :ng2
+ end
+}
+assert_equal %q{ng}, %q{
+ ary = [false, nil]
+ case
+ when *ary
+ :ok
+ else
+ :ng
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [false, true]
+ case
+ when *ary
+ :ok
+ else
+ :ng
+ end
+}
+assert_equal %q{ok}, %q{
+ ary = [false, true]
+ case
+ when false, false
+ when false, *ary
+ :ok
+ else
+ :ng
+ end
+}
+assert_equal %q{}, %q{
+ i = 0
+ while i < 10
+ i+=1
+ end}
+assert_equal %q{10}, %q{
+ i = 0
+ while i < 10
+ i+=1
+ end; i}
+assert_equal %q{}, %q{
+ i = 0
+ until i > 10
+ i+=1
+ end}
+assert_equal %q{11}, %q{
+ i = 0
+ until i > 10
+ i+=1
+ end; i}
+assert_equal %q{1}, %q{
+ i = 0
+ begin
+ i+=1
+ end while false
+ i
+}
+assert_equal %q{1}, %q{
+ i = 0
+ begin
+ i+=1
+ end until true
+ i
+}
+def assert_syntax_error expected, code, message = ''
+ assert_equal "#{expected}",
+ "begin eval(%q{#{code}}, nil, '', 0)"'; rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end', message
+end
+assert_syntax_error "unterminated string meets end of file", '().."', '[ruby-dev:29732]'
+assert_equal %q{[]}, %q{$&;[]}, '[ruby-dev:31068]'
+assert_syntax_error "syntax error, unexpected tSTAR, expecting '}'", %q{{*0}}, '[ruby-dev:31072]'
+assert_syntax_error "`@0' is not allowed as an instance variable name", %q{@0..0}, '[ruby-dev:31095]'
+assert_syntax_error "identifier $00 is not valid to get", %q{$00..0}, '[ruby-dev:31100]'
+assert_syntax_error "identifier $00 is not valid to set", %q{0..$00=1}
+assert_equal %q{0}, %q{[*0];0}, '[ruby-dev:31102]'
+assert_syntax_error "syntax error, unexpected ')'", %q{v0,(*,v1,) = 0}, '[ruby-dev:31104]'
+assert_equal %q{1}, %q{
+ class << (ary=[]); def []; 0; end; def []=(x); super(0,x);end;end; ary[]+=1
+}, '[ruby-dev:31110]'
+assert_syntax_error "Can't set variable $1", %q{0..$1=1}, '[ruby-dev:31118]'
+assert_valid_syntax %q{1.times{1+(1&&next)}}, '[ruby-dev:31119]'
+assert_valid_syntax %q{x=-1;loop{x+=1&&redo if (x+=1).zero?}}, '[ruby-dev:31119]'
+assert_syntax_error %q{syntax error, unexpected $end}, %q{!}, '[ruby-dev:31243]'
+assert_equal %q{[nil]}, %q{[()]}, '[ruby-dev:31252]'
+assert_equal %q{true}, %q{!_=()}, '[ruby-dev:31263]'
+assert_equal 'ok', %q{while true; redo; end if 1 == 2; :ok}, '[ruby-dev:31360]'
+assert_equal 'ok', %q{
+ 1.times {
+ begin
+ ensure
+ next
+ end
+ }; :ok
+}, '[ruby-dev:31373]'
+assert_equal 'ok', %q{
+ flag = false
+ 1.times {
+ next if flag
+ flag = true
+ begin
+ ensure
+ redo
+ end
+ }; :ok
+}, '[ruby-dev:31373]'
+
+assert_equal 'ok', %q{
+ 1.times{
+ p(1, (next; 2))
+ }; :ok
+}
+assert_equal '3', %q{
+ i = 0
+ 1 + (while true
+ break 2 if (i+=1) > 1
+ next
+ end)
+}
+assert_equal '3', %q{
+ i = 0
+ 1 + (while true
+ break 2 if (i+=1) > 1
+ p(1, (next; 2))
+ end)
+}
+# redo
+assert_equal 'ok', %q{
+ i = 0
+ 1.times{
+ break if i>1
+ i+=1
+ p(1, (redo; 2))
+ }; :ok
+}
+assert_equal '3', %q{
+ i = 0
+ 1 + (while true
+ break 2 if (i+=1) > 1
+ redo
+ end)
+}
+assert_equal '3', %q{
+ i = 0
+ 1 + (while true
+ break 2 if (i+=1) > 1
+ p(1, (redo; 2))
+ end)
+}
+assert_equal '1', %q{
+ a = [0]
+ a[*a]+=1
+}
+assert_equal '2', %q{
+ ary = [0]
+ case 1
+ when *ary, 1
+ 1
+ end +
+ case
+ when *ary
+ 1
+ end
+}
+
+assert_match /invalid multibyte char/, %q{
+ STDERR.reopen(STDOUT)
+ eval("\"\xf0".force_encoding("utf-8"))
+}, '[ruby-dev:32429]'
+
+# method ! and !=
+assert_equal 'true', %q{!false}
+assert_equal 'true', %q{1 == 1}
+assert_equal 'true', %q{1 != 2}
+assert_equal 'true', %q{
+ class C; def !=(obj); true; end; end
+ C.new != 1
+}
+assert_equal 'true', %q{
+ class C; def !@; true; end; end
+ !C.new
+}
+assert_normal_exit %q{
+ eval "while true; return; end rescue p $!"
+}, '[ruby-dev:31663]'
+assert_equal '1', %q{
+ def bar
+ raise
+ end
+
+ def foo
+ 1.times{
+ begin
+ return bar
+ rescue
+ :ok
+ end
+ }
+ end
+
+ foo
+}
+
+assert_equal 'ok', %q{
+ counter = 2
+ while true
+ counter -= 1
+ next if counter != 0
+ break
+ end
+ :ok
+}, '[ruby-core:14385]'
+
+assert_equal 'ok', %q{
+ counter = 2
+ while true
+ counter -= 1
+ next if counter != 0
+ break :ok
+ end # direct
+}, '[ruby-core:14385]'
+
+assert_equal 'ok', %q{
+ counter = 2
+ while true
+ counter -= 1
+ break if counter == 0
+ "#{next}"
+ end
+ :ok
+}, 'reported by Yusuke ENDOH'
+
+assert_equal 'ok', %q{
+ counter = 2
+ while true
+ counter -= 1
+ break if counter == 0
+ next
+ redo
+ end
+ :ok
+}, 'reported by Yusuke ENDOH'
+
+assert_equal 'ok', %q{
+ counter = 2
+ while true
+ counter -= 1
+ break if counter == 0
+ next
+ "#{ redo }"
+ end
+ :ok
+}, 'reported by Yusuke ENDOH'
+
+assert_normal_exit %q{
+ begin
+ raise
+ rescue
+ counter = 2
+ while true
+ counter -= 1
+ break if counter == 0
+ next
+ retry
+ end
+ end
+}, 'reported by Yusuke ENDOH'
+
+assert_normal_exit %q{
+ counter = 2
+ while true
+ counter -= 1
+ break if counter == 0
+ next
+ "#{ break }"
+ end
+}, 'reported by Yusuke ENDOH'
+
+assert_normal_exit %q{
+ counter = 2
+ while true
+ counter -= 1
+ next if counter != 0
+ "#{ break }"
+ end
+}, 'reported by Yusuke ENDOH'
+
+assert_equal 'ok', %q{
+ 1.times do
+ [
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ begin
+ false ? next : p
+ break while true
+ end
+ ]
+ end
+ :ok
+}, '[ruby-dev:32882]'
+
+assert_equal "1\n2\n", %q{
+ i = 0
+ while i<2
+ i += 1
+ next p(i)
+ end
+}
+
+assert_valid_syntax('1.times {|i|print (42),1;}', '[ruby-list:44479]')
+
+assert_equal 'ok', %q{
+ def a() end
+ begin
+ if defined?(a(1).a)
+ :ng
+ else
+ :ok
+ end
+ rescue
+ :ng
+ end
+}, '[ruby-core:16010]'
+
+assert_equal 'ok', %q{
+ def a() end
+ begin
+ if defined?(a::B)
+ :ng
+ else
+ :ok
+ end
+ rescue
+ :ng
+ end
+}, '[ruby-core:16010]'
+
+assert_normal_exit %q{
+ defined? C && 0
+}
+
+assert_normal_exit %q{
+ class C
+ def m
+ defined?(super())
+ end
+ end
+ C.new.m
+}
+
+assert_equal 'ok', %q{
+ class X < RuntimeError;end
+ x = [X]
+ begin
+ raise X
+ rescue *x
+ :ok
+ end
+}, '[ruby-core:14537]'
+
+assert_equal 'ok', %q{
+ a = [false]
+ (a[0] &&= true) == false ? :ok : :ng
+}, '[ruby-dev:34679]'
+
+assert_normal_exit %q{
+ a = []
+ 100.times {|i| a << i << nil << nil }
+ p a.compact!
+}
+
+assert_equal 'ok', %q{
+ "#{}""#{}ok"
+}, '[ruby-dev:38968]'
+
+
+assert_equal 'ok', %q{
+ "o" "#{}k"
+}, '[ruby-dev:38980]'
+
+bug2415 = '[ruby-core:26961]'
+assert_normal_exit %q{
+ 0.times do
+ 0.times do
+ def x(a=1, b, *rest); nil end
+ end
+ end
+}, bug2415
+
+assert_normal_exit %q{
+ 0.times do
+ 0.times do
+ def x@; nil end
+ end
+ end
+}, bug2415
+
+assert_normal_exit %q{
+ 0.times do
+ 0.times do
+ def x(a = 0.times do
+ def y(a=1, b, *rest); nil; end
+ end)
+ nil
+ end
+ end
+ end
+}, bug2415
+
+assert_normal_exit %q{
+ 0.times do
+ 0.times do
+ def x(a = 0.times do
+ def x@; nil; end
+ end)
+ nil
+ end
+ end
+ end
+}, bug2415
+
+assert_normal_exit %q{
+ a {
+ b {|c.d| }
+ e
+ }
+}, '[ruby-dev:39861]'
+
+bug1240 = '[ruby-core:22637]'
+assert_valid_syntax('x y { "#{}".z { } }', bug1240)
+assert_valid_syntax('x y { "#{}".z do end }', bug1240)
+
+assert_valid_syntax('y "#{a 1}" do end', '[ruby-core:29579]')
+assert_normal_exit %q{
+ def foo(&block)
+ yield
+ end
+
+ foo do
+ s = defined?(raise + 1)
+ Class
+ end
+}, '[ruby-core:30293]'
Added: MacRuby/trunk/test/test-mri/bootstraptest/test_thread.rb
===================================================================
--- MacRuby/trunk/test/test-mri/bootstraptest/test_thread.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/bootstraptest/test_thread.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,454 @@
+# Thread and Fiber
+
+assert_equal %q{ok}, %q{
+ Thread.new{
+ }.join
+ :ok
+}
+assert_equal %q{ok}, %q{
+ Thread.new{
+ :ok
+ }.value
+}
+assert_equal %q{20100}, %q{
+ v = 0
+ (1..200).map{|i|
+ Thread.new{
+ i
+ }
+ }.each{|t|
+ v += t.value
+ }
+ v
+}
+assert_equal %q{5000}, %q{
+ 5000.times{|e|
+ (1..2).map{
+ Thread.new{
+ }
+ }.each{|e|
+ e.join()
+ }
+ }
+}
+assert_equal %q{5000}, %q{
+ 5000.times{|e|
+ (1..2).map{
+ Thread.new{
+ }
+ }.each{|e|
+ e.join(1000000000)
+ }
+ }
+}
+assert_equal %q{5000}, %q{
+ 5000.times{
+ t = Thread.new{}
+ while t.alive?
+ Thread.pass
+ end
+ }
+}
+assert_equal %q{100}, %q{
+ 100.times{
+ Thread.new{loop{Thread.pass}}
+ }
+}
+assert_equal %q{ok}, %q{
+ Thread.new{
+ :ok
+ }.join.value
+}
+assert_equal %q{ok}, %q{
+ begin
+ Thread.new{
+ raise "ok"
+ }.join
+ rescue => e
+ e
+ end
+}
+assert_equal %q{ok}, %q{
+ ans = nil
+ t = Thread.new{
+ begin
+ sleep 0.5
+ ensure
+ ans = :ok
+ end
+ }
+ Thread.pass
+ t.kill
+ t.join
+ ans
+}
+assert_equal %q{ok}, %q{
+ t = Thread.new{
+ sleep
+ }
+ sleep 0.1
+ t.raise
+ begin
+ t.join
+ :ng
+ rescue
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ t = Thread.new{
+ loop{}
+ }
+ Thread.pass
+ t.raise
+ begin
+ t.join
+ :ng
+ rescue
+ :ok
+ end
+}
+assert_equal %q{ok}, %q{
+ t = Thread.new{
+ }
+ Thread.pass
+ t.join
+ t.raise # raise to exited thread
+ begin
+ t.join
+ :ok
+ rescue
+ :ng
+ end
+}
+assert_equal %q{run}, %q{
+ t = Thread.new{
+ loop{}
+ }
+ st = t.status
+ t.kill
+ st
+}
+assert_equal %q{sleep}, %q{
+ t = Thread.new{
+ sleep
+ }
+ sleep 0.1
+ st = t.status
+ t.kill
+ st
+}
+assert_equal %q{false}, %q{
+ t = Thread.new{
+ }
+ t.kill
+ sleep 0.1
+ t.status
+}
+assert_equal %q{[ThreadGroup, true]}, %q{
+ ptg = Thread.current.group
+ Thread.new{
+ ctg = Thread.current.group
+ [ctg.class, ctg == ptg]
+ }.value
+}
+assert_equal %q{[1, 1]}, %q{
+ thg = ThreadGroup.new
+
+ t = Thread.new{
+ thg.add Thread.current
+ sleep
+ }
+ sleep 0.1
+ [thg.list.size, ThreadGroup::Default.list.size]
+}
+assert_equal %q{true}, %q{
+ thg = ThreadGroup.new
+
+ t = Thread.new{sleep 5}
+ thg.add t
+ thg.list.include?(t)
+}
+assert_equal %q{[true, nil, true]}, %q{
+ /a/ =~ 'a'
+ $a = $~
+ Thread.new{
+ $b = $~
+ /b/ =~ 'b'
+ $c = $~
+ }.join
+ $d = $~
+ [$a == $d, $b, $c != $d]
+}
+assert_equal %q{11}, %q{
+ Thread.current[:a] = 1
+ Thread.new{
+ Thread.current[:a] = 10
+ Thread.pass
+ Thread.current[:a]
+ }.value + Thread.current[:a]
+}
+assert_normal_exit %q{
+begin
+ 100.times do |i|
+ begin
+ th = Thread.start(Thread.current) {|u| u.raise }
+ raise
+ rescue
+ ensure
+ th.join
+ end
+ end
+rescue
+end
+}, '[ruby-dev:31371]'
+
+assert_equal 'true', %{
+ t = Thread.new { loop {} }
+ begin
+ pid = fork {
+ exit t.status != "run"
+ }
+ Process.wait pid
+ $?.success?
+ rescue NotImplementedError
+ true
+ end
+}
+
+assert_equal 'ok', %{
+ open("zzz.rb", "w") do |f|
+ f.puts <<-END
+ begin
+ Thread.new { fork { GC.start } }.join
+ pid, status = Process.wait2
+ $result = status.success? ? :ok : :ng
+ rescue NotImplementedError
+ $result = :ok
+ end
+ END
+ end
+ require "./zzz.rb"
+ $result
+}
+
+assert_finish 3, %{
+ th = Thread.new {sleep 2}
+ th.join(1)
+ th.join
+}
+
+assert_finish 3, %{
+ require 'timeout'
+ th = Thread.new {sleep 2}
+ begin
+ Timeout.timeout(1) {th.join}
+ rescue Timeout::Error
+ end
+ th.join
+}
+
+assert_normal_exit %q{
+ STDERR.reopen(STDOUT)
+ exec "/"
+}
+
+assert_normal_exit %q{
+ (0..10).map {
+ Thread.new {
+ 10000.times {
+ Object.new.to_s
+ }
+ }
+ }.each {|t|
+ t.join
+ }
+}
+
+assert_equal 'ok', %q{
+ def m
+ t = Thread.new { while true do // =~ "" end }
+ sleep 0.1
+ 10.times {
+ if /((ab)*(ab)*)*(b)/ =~ "ab"*7
+ return :ng if !$4
+ return :ng if $~.size != 5
+ end
+ }
+ :ok
+ ensure
+ Thread.kill t
+ end
+ m
+}, '[ruby-dev:34492]'
+
+assert_normal_exit %q{
+ at_exit { Fiber.new{}.resume }
+}
+
+assert_normal_exit %q{
+ g = enum_for(:local_variables)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ g = enum_for(:block_given?)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ g = enum_for(:binding)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ g = "abc".enum_for(:scan, /./)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ g = Module.enum_for(:new)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ Fiber.new(&Object.method(:class_eval)).resume("foo")
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ Thread.new("foo", &Object.method(:class_eval)).join
+}, '[ruby-dev:34128]'
+
+assert_equal 'ok', %q{
+ begin
+ Thread.new { Thread.stop }
+ Thread.stop
+ :ng
+ rescue Exception
+ :ok
+ end
+}
+
+assert_equal 'ok', %q{
+ begin
+ m1, m2 = Mutex.new, Mutex.new
+ Thread.new { m1.lock; sleep 1; m2.lock }
+ m2.lock; sleep 1; m1.lock
+ :ng
+ rescue Exception
+ :ok
+ end
+}
+
+assert_equal 'ok', %q{
+ m = Mutex.new
+ Thread.new { m.lock }; sleep 1; m.lock
+ :ok
+}
+
+assert_equal 'ok', %q{
+ m = Mutex.new
+ Thread.new { m.lock }; m.lock
+ :ok
+}
+
+assert_equal 'ok', %q{
+ m = Mutex.new
+ Thread.new { m.lock }.join; m.lock
+ :ok
+}
+
+assert_equal 'ok', %q{
+ m = Mutex.new
+ Thread.new { m.lock; sleep 2 }
+ sleep 1; m.lock
+ :ok
+}
+
+assert_equal 'ok', %q{
+ m = Mutex.new
+ Thread.new { m.lock; sleep 2; m.unlock }
+ sleep 1; m.lock
+ :ok
+}
+
+assert_equal 'ok', %q{
+ t = Thread.new {`echo`}
+ t.join
+ $? ? :ng : :ok
+}, '[ruby-dev:35414]'
+
+assert_equal 'ok', %q{
+ begin
+ 10000.times { Thread.new(true) {|x| x == false } }
+ rescue NoMemoryError, StandardError
+ end
+ :ok
+}
+
+assert_equal 'ok', %{
+ open("zzz.rb", "w") do |f|
+ f.puts <<-END
+ begin
+ m = Mutex.new
+ Thread.new { m.lock; sleep 1 }
+ sleep 0.3
+ parent = Thread.current
+ Thread.new do
+ sleep 0.3
+ begin
+ fork { GC.start }
+ rescue Exception
+ parent.raise $!
+ end
+ end
+ m.lock
+ pid, status = Process.wait2
+ $result = status.success? ? :ok : :ng
+ rescue NotImplementedError
+ $result = :ok
+ end
+ END
+ end
+ require "./zzz.rb"
+ $result
+}
+
+assert_finish 3, %q{
+ require 'thread'
+
+ lock = Mutex.new
+ cond = ConditionVariable.new
+ t = Thread.new do
+ lock.synchronize do
+ cond.wait(lock)
+ end
+ end
+
+ begin
+ pid = fork do
+ # Child
+ STDOUT.write "This is the child process.\n"
+ STDOUT.write "Child process exiting.\n"
+ end
+ Process.waitpid(pid)
+ rescue NotImplementedError
+ end
+}, '[ruby-core:23572]'
+
+assert_equal 'ok', %q{
+ begin
+ Process.waitpid2(fork {sleep 1})[1].success? ? 'ok' : 'ng'
+ rescue NotImplementedError
+ 'ok'
+ end
+}
+
+assert_equal 'foo', %q{
+ f = proc {|s| /#{ sleep 1; s }/o }
+ [ Thread.new { f.call("foo"); nil },
+ Thread.new { sleep 0.5; f.call("bar"); nil },
+ ].each {|t| t.join }
+ GC.start
+ f.call.source
+}
Added: MacRuby/trunk/test/test-mri/require_relative.rb
===================================================================
--- MacRuby/trunk/test/test-mri/require_relative.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/require_relative.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,10 @@
+module Kernel
+ unless(defined? require_relative)
+ def require_relative(path)
+ require File.join(File.dirname(caller(0)[1]), path.to_str)
+ end
+ end
+end
+
+
+print "\n----------------------------------------\n"
Added: MacRuby/trunk/test/test-mri/test/-ext-/test_bug-3662.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/-ext-/test_bug-3662.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/-ext-/test_bug-3662.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,10 @@
+require '-test-/bug-3662/bug'
+
+class Test_BUG_3662 < Test::Unit::TestCase
+ def test_funcall_notimplement
+ bug3662 = '[ruby-dev:41953]'
+ assert_raise(NotImplementedError, bug3662) {
+ Bug.funcall(:notimplement)
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/base64/test_base64.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/base64/test_base64.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/base64/test_base64.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,99 @@
+require "test/unit"
+require "base64"
+
+class TestBase64 < Test::Unit::TestCase
+ def test_sample
+ assert_equal("U2VuZCByZWluZm9yY2VtZW50cw==\n", Base64.encode64('Send reinforcements'))
+ assert_equal('Send reinforcements', Base64.decode64("U2VuZCByZWluZm9yY2VtZW50cw==\n"))
+ assert_equal(
+ "Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g\nUnVieQ==\n",
+ Base64.encode64("Now is the time for all good coders\nto learn Ruby"))
+ assert_equal(
+ "Now is the time for all good coders\nto learn Ruby",
+ Base64.decode64("Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g\nUnVieQ==\n"))
+ assert_equal(
+ "VGhpcyBpcyBsaW5lIG9uZQpUaGlzIGlzIGxpbmUgdHdvClRoaXMgaXMgbGlu\nZSB0aHJlZQpBbmQgc28gb24uLi4K\n",
+ Base64.encode64("This is line one\nThis is line two\nThis is line three\nAnd so on...\n"))
+ assert_equal(
+ "This is line one\nThis is line two\nThis is line three\nAnd so on...\n",
+ Base64.decode64("VGhpcyBpcyBsaW5lIG9uZQpUaGlzIGlzIGxpbmUgdHdvClRoaXMgaXMgbGluZSB0aHJlZQpBbmQgc28gb24uLi4K"))
+ end
+
+ def test_encode64
+ assert_equal("", Base64.encode64(""))
+ assert_equal("AA==\n", Base64.encode64("\0"))
+ assert_equal("AAA=\n", Base64.encode64("\0\0"))
+ assert_equal("AAAA\n", Base64.encode64("\0\0\0"))
+ assert_equal("/w==\n", Base64.encode64("\377"))
+ assert_equal("//8=\n", Base64.encode64("\377\377"))
+ assert_equal("////\n", Base64.encode64("\377\377\377"))
+ assert_equal("/+8=\n", Base64.encode64("\xff\xef"))
+ end
+
+ def test_decode64
+ assert_equal("", Base64.decode64(""))
+ assert_equal("\0", Base64.decode64("AA==\n"))
+ assert_equal("\0\0", Base64.decode64("AAA=\n"))
+ assert_equal("\0\0\0", Base64.decode64("AAAA\n"))
+ assert_equal("\377", Base64.decode64("/w==\n"))
+ assert_equal("\377\377", Base64.decode64("//8=\n"))
+ assert_equal("\377\377\377", Base64.decode64("////\n"))
+ assert_equal("\xff\xef", Base64.decode64("/+8=\n"))
+ end
+
+ def test_strict_encode64
+ assert_equal("", Base64.strict_encode64(""))
+ assert_equal("AA==", Base64.strict_encode64("\0"))
+ assert_equal("AAA=", Base64.strict_encode64("\0\0"))
+ assert_equal("AAAA", Base64.strict_encode64("\0\0\0"))
+ assert_equal("/w==", Base64.strict_encode64("\377"))
+ assert_equal("//8=", Base64.strict_encode64("\377\377"))
+ assert_equal("////", Base64.strict_encode64("\377\377\377"))
+ assert_equal("/+8=", Base64.strict_encode64("\xff\xef"))
+ end
+
+ def test_strict_decode64
+ assert_equal("", Base64.strict_decode64(""))
+ assert_equal("\0", Base64.strict_decode64("AA=="))
+ assert_equal("\0\0", Base64.strict_decode64("AAA="))
+ assert_equal("\0\0\0", Base64.strict_decode64("AAAA"))
+ assert_equal("\377", Base64.strict_decode64("/w=="))
+ assert_equal("\377\377", Base64.strict_decode64("//8="))
+ assert_equal("\377\377\377", Base64.strict_decode64("////"))
+ assert_equal("\xff\xef", Base64.strict_decode64("/+8="))
+
+ assert_raise(ArgumentError) { Base64.strict_decode64("^") }
+ assert_raise(ArgumentError) { Base64.strict_decode64("A") }
+ assert_raise(ArgumentError) { Base64.strict_decode64("A^") }
+ assert_raise(ArgumentError) { Base64.strict_decode64("AA") }
+ assert_raise(ArgumentError) { Base64.strict_decode64("AA=") }
+ assert_raise(ArgumentError) { Base64.strict_decode64("AA===") }
+ assert_raise(ArgumentError) { Base64.strict_decode64("AA=x") }
+ assert_raise(ArgumentError) { Base64.strict_decode64("AAA") }
+ assert_raise(ArgumentError) { Base64.strict_decode64("AAA^") }
+ assert_raise(ArgumentError) { Base64.strict_decode64("AB==") }
+ assert_raise(ArgumentError) { Base64.strict_decode64("AAB=") }
+ end
+
+ def test_urlsafe_encode64
+ assert_equal("", Base64.urlsafe_encode64(""))
+ assert_equal("AA==", Base64.urlsafe_encode64("\0"))
+ assert_equal("AAA=", Base64.urlsafe_encode64("\0\0"))
+ assert_equal("AAAA", Base64.urlsafe_encode64("\0\0\0"))
+ assert_equal("_w==", Base64.urlsafe_encode64("\377"))
+ assert_equal("__8=", Base64.urlsafe_encode64("\377\377"))
+ assert_equal("____", Base64.urlsafe_encode64("\377\377\377"))
+ assert_equal("_-8=", Base64.urlsafe_encode64("\xff\xef"))
+ end
+
+ def test_urlsafe_decode64
+ assert_equal("", Base64.urlsafe_decode64(""))
+ assert_equal("\0", Base64.urlsafe_decode64("AA=="))
+ assert_equal("\0\0", Base64.urlsafe_decode64("AAA="))
+ assert_equal("\0\0\0", Base64.urlsafe_decode64("AAAA"))
+ assert_equal("\377", Base64.urlsafe_decode64("_w=="))
+ assert_equal("\377\377", Base64.urlsafe_decode64("__8="))
+ assert_equal("\377\377\377", Base64.urlsafe_decode64("____"))
+ assert_equal("\xff\xef", Base64.urlsafe_decode64("_+8="))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/benchmark/test_benchmark.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/benchmark/test_benchmark.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/benchmark/test_benchmark.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,10 @@
+require "test/unit"
+require "benchmark"
+
+class TestBenchmark < Test::Unit::TestCase
+ def test_add!
+ assert_nothing_raised("[ruby-dev:40906]") do
+ Benchmark::Tms.new.add! {}
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/bigdecimal/test_bigdecimal.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/bigdecimal/test_bigdecimal.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/bigdecimal/test_bigdecimal.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,712 @@
+require_relative "testbase"
+
+class TestBigDecimal < Test::Unit::TestCase
+ include TestBigDecimalBase
+
+ def test_version
+ assert_equal("1.0.1", BigDecimal.ver)
+ end
+
+ def test_global_new
+ assert_equal(1, BigDecimal("1"))
+ assert_equal(1, BigDecimal("1", 1))
+ assert_raise(ArgumentError) { BigDecimal("1", -1) }
+ end
+
+ def test_new
+ assert_equal(1, BigDecimal.new("1"))
+ assert_equal(1, BigDecimal.new("1", 1))
+ assert_equal(1, BigDecimal.new(" 1 "))
+ assert_equal(111, BigDecimal.new("1_1_1_"))
+ assert_equal(0, BigDecimal.new("_1_1_1"))
+
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ assert_equal( 1, BigDecimal.new("Infinity").infinite?)
+ assert_equal(-1, BigDecimal.new("-Infinity").infinite?)
+ assert_equal(true, BigDecimal.new("NaN").nan?)
+ assert_equal( 1, BigDecimal.new("1E11111111111").infinite?)
+ end
+
+ def _test_mode(type)
+ BigDecimal.mode(type, true)
+ assert_raise(FloatDomainError) { yield }
+
+ BigDecimal.mode(type, false)
+ assert_nothing_raised { yield }
+ end
+
+ def test_mode
+ assert_raise(TypeError) { BigDecimal.mode(BigDecimal::EXCEPTION_ALL, 1) }
+ assert_raise(TypeError) { BigDecimal.mode(BigDecimal::ROUND_MODE, 256) }
+ assert_raise(TypeError) { BigDecimal.mode(0xf000, true) }
+ end
+
+ def test_exception_nan
+ _test_mode(BigDecimal::EXCEPTION_NaN) { BigDecimal.new("NaN") }
+ end
+
+ def test_exception_infinity
+ _test_mode(BigDecimal::EXCEPTION_INFINITY) { BigDecimal.new("Infinity") }
+ end
+
+ def test_exception_underflow
+ _test_mode(BigDecimal::EXCEPTION_UNDERFLOW) do
+ x = BigDecimal.new("0.1")
+ 100.times do
+ x *= x
+ end
+ end
+ end
+
+ def test_exception_overflow
+ _test_mode(BigDecimal::EXCEPTION_OVERFLOW) do
+ x = BigDecimal.new("10")
+ 100.times do
+ x *= x
+ end
+ end
+ end
+
+ def test_exception_zerodivide
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ _test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { 1 / BigDecimal.new("0") }
+ _test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { -1 / BigDecimal.new("0") }
+ end
+
+ def test_round_up
+ n4 = BigDecimal.new("4") # n4 / 9 = 0.44444...
+ n5 = BigDecimal.new("5") # n5 / 9 = 0.55555...
+ n6 = BigDecimal.new("6") # n6 / 9 = 0.66666...
+ m4, m5, m6 = -n4, -n5, -n6
+ n2h = BigDecimal.new("2.5")
+ n3h = BigDecimal.new("3.5")
+ m2h, m3h = -n2h, -n3h
+
+ BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP)
+ assert_operator(n4, :<, n4 / 9 * 9)
+ assert_operator(n5, :<, n5 / 9 * 9)
+ assert_operator(n6, :<, n6 / 9 * 9)
+ assert_operator(m4, :>, m4 / 9 * 9)
+ assert_operator(m5, :>, m5 / 9 * 9)
+ assert_operator(m6, :>, m6 / 9 * 9)
+ assert_equal(3, n2h.round)
+ assert_equal(4, n3h.round)
+ assert_equal(-3, m2h.round)
+ assert_equal(-4, m3h.round)
+
+ BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_DOWN)
+ assert_operator(n4, :>, n4 / 9 * 9)
+ assert_operator(n5, :>, n5 / 9 * 9)
+ assert_operator(n6, :>, n6 / 9 * 9)
+ assert_operator(m4, :<, m4 / 9 * 9)
+ assert_operator(m5, :<, m5 / 9 * 9)
+ assert_operator(m6, :<, m6 / 9 * 9)
+ assert_equal(2, n2h.round)
+ assert_equal(3, n3h.round)
+ assert_equal(-2, m2h.round)
+ assert_equal(-3, m3h.round)
+
+ BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
+ assert_operator(n4, :>, n4 / 9 * 9)
+ assert_operator(n5, :<, n5 / 9 * 9)
+ assert_operator(n6, :<, n6 / 9 * 9)
+ assert_operator(m4, :<, m4 / 9 * 9)
+ assert_operator(m5, :>, m5 / 9 * 9)
+ assert_operator(m6, :>, m6 / 9 * 9)
+ assert_equal(3, n2h.round)
+ assert_equal(4, n3h.round)
+ assert_equal(-3, m2h.round)
+ assert_equal(-4, m3h.round)
+
+ BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_DOWN)
+ assert_operator(n4, :>, n4 / 9 * 9)
+ assert_operator(n5, :>, n5 / 9 * 9)
+ assert_operator(n6, :<, n6 / 9 * 9)
+ assert_operator(m4, :<, m4 / 9 * 9)
+ assert_operator(m5, :<, m5 / 9 * 9)
+ assert_operator(m6, :>, m6 / 9 * 9)
+ assert_equal(2, n2h.round)
+ assert_equal(3, n3h.round)
+ assert_equal(-2, m2h.round)
+ assert_equal(-3, m3h.round)
+
+ BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
+ assert_operator(n4, :>, n4 / 9 * 9)
+ assert_operator(n5, :<, n5 / 9 * 9)
+ assert_operator(n6, :<, n6 / 9 * 9)
+ assert_operator(m4, :<, m4 / 9 * 9)
+ assert_operator(m5, :>, m5 / 9 * 9)
+ assert_operator(m6, :>, m6 / 9 * 9)
+ assert_equal(2, n2h.round)
+ assert_equal(4, n3h.round)
+ assert_equal(-2, m2h.round)
+ assert_equal(-4, m3h.round)
+
+ BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_CEILING)
+ assert_operator(n4, :<, n4 / 9 * 9)
+ assert_operator(n5, :<, n5 / 9 * 9)
+ assert_operator(n6, :<, n6 / 9 * 9)
+ assert_operator(m4, :<, m4 / 9 * 9)
+ assert_operator(m5, :<, m5 / 9 * 9)
+ assert_operator(m6, :<, m6 / 9 * 9)
+ assert_equal(3, n2h.round)
+ assert_equal(4, n3h.round)
+ assert_equal(-2, m2h.round)
+ assert_equal(-3, m3h.round)
+
+ BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
+ assert_operator(n4, :>, n4 / 9 * 9)
+ assert_operator(n5, :>, n5 / 9 * 9)
+ assert_operator(n6, :>, n6 / 9 * 9)
+ assert_operator(m4, :>, m4 / 9 * 9)
+ assert_operator(m5, :>, m5 / 9 * 9)
+ assert_operator(m6, :>, m6 / 9 * 9)
+ assert_equal(2, n2h.round)
+ assert_equal(3, n3h.round)
+ assert_equal(-3, m2h.round)
+ assert_equal(-4, m3h.round)
+ end
+
+ def test_zero_p
+ assert_equal(true, BigDecimal.new("0").zero?)
+ assert_equal(false, BigDecimal.new("1").zero?)
+ assert_equal(true, BigDecimal.new("0E200000000000000").zero?)
+ end
+
+ def test_nonzero_p
+ assert_equal(nil, BigDecimal.new("0").nonzero?)
+ assert_equal(BigDecimal.new("1"), BigDecimal.new("1").nonzero?)
+ end
+
+ def test_double_fig
+ assert_kind_of(Integer, BigDecimal.double_fig)
+ end
+
+ def test_cmp
+ n1 = BigDecimal.new("1")
+ n2 = BigDecimal.new("2")
+ assert_equal( 0, n1 <=> n1)
+ assert_equal( 1, n2 <=> n1)
+ assert_equal(-1, n1 <=> n2)
+ assert_operator(n1, :==, n1)
+ assert_operator(n1, :!=, n2)
+ assert_operator(n1, :<, n2)
+ assert_operator(n1, :<=, n1)
+ assert_operator(n1, :<=, n2)
+ assert_operator(n2, :>, n1)
+ assert_operator(n2, :>=, n1)
+ assert_operator(n1, :>=, n1)
+
+ assert_operator(BigDecimal.new("-0"), :==, BigDecimal.new("0"))
+ assert_operator(BigDecimal.new("0"), :<, BigDecimal.new("1"))
+ assert_operator(BigDecimal.new("1"), :>, BigDecimal.new("0"))
+ assert_operator(BigDecimal.new("1"), :>, BigDecimal.new("-1"))
+ assert_operator(BigDecimal.new("-1"), :<, BigDecimal.new("1"))
+ assert_operator(BigDecimal.new((2**100).to_s), :>, BigDecimal.new("1"))
+ assert_operator(BigDecimal.new("1"), :<, BigDecimal.new((2**100).to_s))
+
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ inf = BigDecimal.new("Infinity")
+ assert_operator(inf, :>, 1)
+ assert_operator(1, :<, inf)
+ end
+
+ def test_cmp_nan
+ n1 = BigDecimal.new("1")
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ assert_equal(nil, BigDecimal.new("NaN") <=> n1)
+ assert_equal(false, BigDecimal.new("NaN") > n1)
+ end
+
+ def test_cmp_failing_coercion
+ n1 = BigDecimal.new("1")
+ assert_equal(nil, n1 <=> nil)
+ assert_raise(ArgumentError){n1 > nil}
+ end
+
+ def test_cmp_coerce
+ n1 = BigDecimal.new("1")
+ n2 = BigDecimal.new("2")
+ o1 = Object.new; def o1.coerce(x); [x, BigDecimal.new("1")]; end
+ o2 = Object.new; def o2.coerce(x); [x, BigDecimal.new("2")]; end
+ assert_equal( 0, n1 <=> o1)
+ assert_equal( 1, n2 <=> o1)
+ assert_equal(-1, n1 <=> o2)
+ assert_operator(n1, :==, o1)
+ assert_operator(n1, :!=, o2)
+ assert_operator(n1, :<, o2)
+ assert_operator(n1, :<=, o1)
+ assert_operator(n1, :<=, o2)
+ assert_operator(n2, :>, o1)
+ assert_operator(n2, :>=, o1)
+ assert_operator(n1, :>=, 1)
+ end
+
+ def test_cmp_bignum
+ assert_operator(BigDecimal.new((2**100).to_s), :==, 2**100)
+ end
+
+ def test_cmp_data
+ d = Time.now; def d.coerce(x); [x, x]; end
+ assert_operator(BigDecimal.new((2**100).to_s), :==, d)
+ end
+
+ def test_precs
+ a = BigDecimal.new("1").precs
+ assert_instance_of(Array, a)
+ assert_equal(2, a.size)
+ assert_kind_of(Integer, a[0])
+ assert_kind_of(Integer, a[1])
+ end
+
+ def test_hash
+ a = []
+ b = BigDecimal.new("1")
+ 10.times { a << b *= 10 }
+ h = {}
+ a.each_with_index {|x, i| h[x] = i }
+ a.each_with_index do |x, i|
+ assert_equal(i, h[x])
+ end
+ end
+
+ def test_marshal
+ s = Marshal.dump(BigDecimal("1", 1))
+ assert_equal(BigDecimal("1", 1), Marshal.load(s))
+
+ # corrupt data
+ s = s.gsub(/BigDecimal.*\z/m) {|x| x.gsub(/\d/m, "-") }
+ assert_raise(TypeError) { Marshal.load(s) }
+ end
+
+ def test_finite_infinite_nan
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
+
+ x = BigDecimal.new("0")
+ assert_equal(true, x.finite?)
+ assert_equal(nil, x.infinite?)
+ assert_equal(false, x.nan?)
+ y = 1 / x
+ assert_equal(false, y.finite?)
+ assert_equal(1, y.infinite?)
+ assert_equal(false, y.nan?)
+ y = -1 / x
+ assert_equal(false, y.finite?)
+ assert_equal(-1, y.infinite?)
+ assert_equal(false, y.nan?)
+
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ y = 0 / x
+ assert_equal(false, y.finite?)
+ assert_equal(nil, y.infinite?)
+ assert_equal(true, y.nan?)
+ end
+
+ def test_to_i
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+
+ x = BigDecimal.new("0")
+ assert_kind_of(Integer, x.to_i)
+ assert_equal(0, x.to_i)
+ assert_raise(FloatDomainError){( 1 / x).to_i}
+ assert_raise(FloatDomainError){(-1 / x).to_i}
+ assert_raise(FloatDomainError) {( 0 / x).to_i}
+ x = BigDecimal.new("1")
+ assert_equal(1, x.to_i)
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal(2**100, x.to_i)
+ end
+
+ def test_to_f
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
+
+ x = BigDecimal.new("0")
+ assert_instance_of(Float, x.to_f)
+ assert_equal(0.0, x.to_f)
+ assert_equal( 1.0 / 0.0, ( 1 / x).to_f)
+ assert_equal(-1.0 / 0.0, (-1 / x).to_f)
+ assert_equal(true, ( 0 / x).to_f.nan?)
+ x = BigDecimal.new("1")
+ assert_equal(1.0, x.to_f)
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal((2**100).to_f, x.to_f)
+ x = BigDecimal.new("1" + "0" * 10000)
+ assert_equal(0, BigDecimal.new("-0").to_f)
+
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true)
+ assert_raise(FloatDomainError) { x.to_f }
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ assert_kind_of(Float, x .to_f)
+ assert_kind_of(Float, (-x).to_f)
+ end
+
+ def test_coerce
+ a, b = BigDecimal.new("1").coerce(1.0)
+ assert_instance_of(Float, a)
+ assert_instance_of(Float, b)
+ assert_equal(2, 1 + BigDecimal.new("1"), '[ruby-core:25697]')
+ end
+
+ def test_uplus
+ x = BigDecimal.new("1")
+ assert_equal(x, x.send(:+@))
+ end
+
+ def test_add
+ x = BigDecimal.new("1")
+ assert_equal(BigDecimal.new("2"), x + x)
+ assert_equal(1, BigDecimal.new("0") + 1)
+ assert_equal(1, x + 0)
+
+ assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("0") + 0).sign)
+ assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("-0") + 0).sign)
+ assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-0") + BigDecimal.new("-0")).sign)
+
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal(BigDecimal.new((2**100+1).to_s), x + 1)
+ end
+
+ def test_sub
+ x = BigDecimal.new("1")
+ assert_equal(BigDecimal.new("0"), x - x)
+ assert_equal(-1, BigDecimal.new("0") - 1)
+ assert_equal(1, x - 0)
+
+ assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("0") - 0).sign)
+ assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-0") - 0).sign)
+ assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("-0") - BigDecimal.new("-0")).sign)
+
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal(BigDecimal.new((2**100-1).to_s), x - 1)
+ end
+
+ def test_mult
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal(BigDecimal.new((2**100 * 3).to_s), (x * 3).to_i)
+ assert_equal(x, (x * 1).to_i)
+ assert_equal(x, (BigDecimal("1") * x).to_i)
+ assert_equal(BigDecimal.new((2**200).to_s), (x * x).to_i)
+ end
+
+ def test_div
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal(BigDecimal.new((2**100 / 3).to_s), (x / 3).to_i)
+ assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("0") / 1).sign)
+ assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-0") / 1).sign)
+ assert_equal(2, BigDecimal.new("2") / 1)
+ assert_equal(-2, BigDecimal.new("2") / -1)
+ end
+
+ def test_mod
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal(1, x % 3)
+ assert_equal(2, (-x) % 3)
+ assert_equal(-2, x % -3)
+ assert_equal(-1, (-x) % -3)
+ end
+
+ def test_remainder
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal(1, x.remainder(3))
+ assert_equal(-1, (-x).remainder(3))
+ assert_equal(1, x.remainder(-3))
+ assert_equal(-1, (-x).remainder(-3))
+ end
+
+ def test_divmod
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal([(x / 3).floor, 1], x.divmod(3))
+ assert_equal([(-x / 3).floor, 2], (-x).divmod(3))
+
+ assert_equal([0, 0], BigDecimal.new("0").divmod(2))
+
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ assert_raise(ZeroDivisionError){BigDecimal.new("0").divmod(0)}
+ end
+
+ def test_add_bigdecimal
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal(3000000000000000000000000000000, x.add(x, 1))
+ assert_equal(2500000000000000000000000000000, x.add(x, 2))
+ assert_equal(2540000000000000000000000000000, x.add(x, 3))
+ end
+
+ def test_sub_bigdecimal
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal(1000000000000000000000000000000, x.sub(1, 1))
+ assert_equal(1300000000000000000000000000000, x.sub(1, 2))
+ assert_equal(1270000000000000000000000000000, x.sub(1, 3))
+ end
+
+ def test_mult_bigdecimal
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal(4000000000000000000000000000000, x.mult(3, 1))
+ assert_equal(3800000000000000000000000000000, x.mult(3, 2))
+ assert_equal(3800000000000000000000000000000, x.mult(3, 3))
+ end
+
+ def test_div_bigdecimal
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal(422550200076076467165567735125, x.div(3))
+ assert_equal(400000000000000000000000000000, x.div(3, 1))
+ assert_equal(420000000000000000000000000000, x.div(3, 2))
+ assert_equal(423000000000000000000000000000, x.div(3, 3))
+ end
+
+ def test_abs_bigdecimal
+ x = BigDecimal.new((2**100).to_s)
+ assert_equal(1267650600228229401496703205376, x.abs)
+ x = BigDecimal.new("-" + (2**100).to_s)
+ assert_equal(1267650600228229401496703205376, x.abs)
+ x = BigDecimal.new("0")
+ assert_equal(0, x.abs)
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ x = BigDecimal.new("NaN")
+ assert_equal(true, x.abs.nan?)
+ end
+
+ def test_sqrt_bigdecimal
+ x = BigDecimal.new("0.09")
+ assert_in_delta(0.3, x.sqrt(1), 0.001)
+ x = BigDecimal.new((2**100).to_s)
+ y = BigDecimal("1125899906842624")
+ e = y.exponent
+ assert_equal(true, (x.sqrt(100) - y).abs < BigDecimal("1E#{e-100}"))
+ assert_equal(true, (x.sqrt(200) - y).abs < BigDecimal("1E#{e-200}"))
+ assert_equal(true, (x.sqrt(300) - y).abs < BigDecimal("1E#{e-300}"))
+ x = BigDecimal.new("-" + (2**100).to_s)
+ assert_raise(FloatDomainError) { x.sqrt(1) }
+ x = BigDecimal.new((2**200).to_s)
+ assert_equal(2**100, x.sqrt(1))
+
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ assert_raise(FloatDomainError) { BigDecimal.new("NaN").sqrt(1) }
+
+ assert_equal(0, BigDecimal.new("0").sqrt(1))
+ assert_equal(1, BigDecimal.new("1").sqrt(1))
+ end
+
+ def test_fix
+ x = BigDecimal.new("1.1")
+ assert_equal(1, x.fix)
+ end
+
+ def test_frac
+ x = BigDecimal.new("1.1")
+ assert_equal(0.1, x.frac)
+ assert_equal(0.1, BigDecimal.new("0.1").frac)
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ assert_equal(true, BigDecimal.new("NaN").frac.nan?)
+ end
+
+ def test_round
+ assert_equal(3, BigDecimal.new("3.14159").round)
+ assert_equal(9, BigDecimal.new("8.7").round)
+ assert_equal(3.142, BigDecimal.new("3.14159").round(3))
+ assert_equal(13300.0, BigDecimal.new("13345.234").round(-2))
+
+ x = BigDecimal.new("111.111")
+ assert_equal(111 , x.round)
+ assert_equal(111.1 , x.round(1))
+ assert_equal(111.11 , x.round(2))
+ assert_equal(111.111, x.round(3))
+ assert_equal(111.111, x.round(4))
+ assert_equal(110 , x.round(-1))
+ assert_equal(100 , x.round(-2))
+ assert_equal( 0 , x.round(-3))
+ assert_equal( 0 , x.round(-4))
+
+ x = BigDecimal.new("2.5")
+ assert_equal(3, x.round(0, BigDecimal::ROUND_UP))
+ assert_equal(2, x.round(0, BigDecimal::ROUND_DOWN))
+ assert_equal(3, x.round(0, BigDecimal::ROUND_HALF_UP))
+ assert_equal(2, x.round(0, BigDecimal::ROUND_HALF_DOWN))
+ assert_equal(2, x.round(0, BigDecimal::ROUND_HALF_EVEN))
+ assert_equal(3, x.round(0, BigDecimal::ROUND_CEILING))
+ assert_equal(2, x.round(0, BigDecimal::ROUND_FLOOR))
+ assert_raise(TypeError) { x.round(0, 256) }
+ end
+
+ def test_truncate
+ assert_equal(3, BigDecimal.new("3.14159").truncate)
+ assert_equal(8, BigDecimal.new("8.7").truncate)
+ assert_equal(3.141, BigDecimal.new("3.14159").truncate(3))
+ assert_equal(13300.0, BigDecimal.new("13345.234").truncate(-2))
+ end
+
+ def test_floor
+ assert_equal(3, BigDecimal.new("3.14159").floor)
+ assert_equal(-10, BigDecimal.new("-9.1").floor)
+ assert_equal(3.141, BigDecimal.new("3.14159").floor(3))
+ assert_equal(13300.0, BigDecimal.new("13345.234").floor(-2))
+ end
+
+ def test_ceil
+ assert_equal(4, BigDecimal.new("3.14159").ceil)
+ assert_equal(-9, BigDecimal.new("-9.1").ceil)
+ assert_equal(3.142, BigDecimal.new("3.14159").ceil(3))
+ assert_equal(13400.0, BigDecimal.new("13345.234").ceil(-2))
+ end
+
+ def test_to_s
+ assert_equal('-123.45678 90123 45678 9', BigDecimal.new('-123.45678901234567890').to_s('5F'))
+ assert_equal('+123.45678901 23456789', BigDecimal.new('123.45678901234567890').to_s('+8F'))
+ assert_equal(' 123.4567890123456789', BigDecimal.new('123.45678901234567890').to_s(' F'))
+ assert_equal('0.1234567890123456789E3', BigDecimal.new('123.45678901234567890').to_s)
+ assert_equal('0.12345 67890 12345 6789E3', BigDecimal.new('123.45678901234567890').to_s(5))
+ end
+
+ def test_split
+ x = BigDecimal.new('-123.45678901234567890')
+ assert_equal([-1, "1234567890123456789", 10, 3], x.split)
+ assert_equal([1, "0", 10, 0], BigDecimal.new("0").split)
+ assert_equal([-1, "0", 10, 0], BigDecimal.new("-0").split)
+
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ assert_equal([0, "NaN", 10, 0], BigDecimal.new("NaN").split)
+ assert_equal([1, "Infinity", 10, 0], BigDecimal.new("Infinity").split)
+ assert_equal([-1, "Infinity", 10, 0], BigDecimal.new("-Infinity").split)
+ end
+
+ def test_exponent
+ x = BigDecimal.new('-123.45678901234567890')
+ assert_equal(3, x.exponent)
+ end
+
+ def test_inspect
+ x = BigDecimal.new("1234.5678")
+ prec, maxprec = x.precs
+ assert_match(/^#<BigDecimal:[0-9a-f]+,'0.12345678E4',#{prec}\(#{maxprec}\)>$/, x.inspect)
+ end
+
+ def test_power
+ x = BigDecimal.new("3")
+ assert_equal(81, x ** 4)
+ assert_equal(1.0/81, x ** -4)
+ assert_equal(1, x ** 0)
+ assert_raise(TypeError) { x ** x }
+ assert_equal(0, BigDecimal.new("0") ** 4)
+ assert_equal(1, BigDecimal.new("0") ** 0)
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ assert_equal(BigDecimal.new("Infinity"), BigDecimal.new("0") ** -1)
+ assert_equal(BigDecimal.new("-Infinity"), BigDecimal.new("-0") ** -1)
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ assert_equal(true, (BigDecimal.new("NaN") ** 1).nan?)
+
+ assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, (BigDecimal.new("Infinity") ** 2).sign)
+ assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, (BigDecimal.new("Infinity") ** 1).sign)
+ assert_equal(1, BigDecimal.new("Infinity") ** 0)
+ assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("Infinity") ** -1).sign)
+ assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("Infinity") ** -2).sign)
+
+ assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, (BigDecimal.new("-Infinity") ** 2).sign)
+ assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, (BigDecimal.new("-Infinity") ** 1).sign)
+ assert_equal(1, BigDecimal.new("-Infinity") ** 0)
+ assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-Infinity") ** -1).sign)
+ assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("-Infinity") ** -2).sign)
+ end
+
+ def test_limit
+ BigDecimal.limit(1)
+ x = BigDecimal.new("3")
+ assert_equal(90, x ** 4) # OK? must it be 80?
+ # 3 * 3 * 3 * 3 = 10 * 3 * 3 = 30 * 3 = 90 ???
+ assert_raise(ArgumentError) { BigDecimal.limit(-1) }
+ end
+
+ def test_sign
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
+
+ assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal.new("0").sign)
+ assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal.new("-0").sign)
+ assert_equal(BigDecimal::SIGN_POSITIVE_FINITE, BigDecimal.new("1").sign)
+ assert_equal(BigDecimal::SIGN_NEGATIVE_FINITE, BigDecimal.new("-1").sign)
+ assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, (BigDecimal.new("1") / 0).sign)
+ assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, (BigDecimal.new("-1") / 0).sign)
+ assert_equal(BigDecimal::SIGN_NaN, (BigDecimal.new("0") / 0).sign)
+ end
+
+ def test_inf
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ inf = BigDecimal.new("Infinity")
+
+ assert_equal(inf, inf + inf)
+ assert_equal(true, (inf + (-inf)).nan?)
+ assert_equal(true, (inf - inf).nan?)
+ assert_equal(inf, inf - (-inf))
+ assert_equal(inf, inf * inf)
+ assert_equal(true, (inf / inf).nan?)
+
+ assert_equal(inf, inf + 1)
+ assert_equal(inf, inf - 1)
+ assert_equal(inf, inf * 1)
+ assert_equal(true, (inf * 0).nan?)
+ assert_equal(inf, inf / 1)
+
+ assert_equal(inf, 1 + inf)
+ assert_equal(-inf, 1 - inf)
+ assert_equal(inf, 1 * inf)
+ assert_equal(-inf, -1 * inf)
+ assert_equal(true, (0 * inf).nan?)
+ assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (1 / inf).sign)
+ assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (-1 / inf).sign)
+ end
+
+ def test_to_special_string
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+ nan = BigDecimal.new("NaN")
+ assert_equal("NaN", nan.to_s)
+ inf = BigDecimal.new("Infinity")
+ assert_equal("Infinity", inf.to_s)
+ assert_equal(" Infinity", inf.to_s(" "))
+ assert_equal("+Infinity", inf.to_s("+"))
+ assert_equal("-Infinity", (-inf).to_s)
+ pzero = BigDecimal.new("0")
+ assert_equal("0.0", pzero.to_s)
+ assert_equal(" 0.0", pzero.to_s(" "))
+ assert_equal("+0.0", pzero.to_s("+"))
+ assert_equal("-0.0", (-pzero).to_s)
+ end
+
+ def test_to_string
+ assert_equal("0.01", BigDecimal("0.01").to_s("F"))
+ s = "0." + "0" * 100 + "1"
+ assert_equal(s, BigDecimal(s).to_s("F"))
+ s = "1" + "0" * 100 + ".0"
+ assert_equal(s, BigDecimal(s).to_s("F"))
+ end
+
+ def test_ctov
+ assert_equal(0.1, BigDecimal.new("1E-1"))
+ assert_equal(10, BigDecimal.new("1E+1"))
+ assert_equal(1, BigDecimal.new("+1"))
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+
+ assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, BigDecimal.new("1E1" + "0" * 10000).sign)
+ assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, BigDecimal.new("-1E1" + "0" * 10000).sign)
+ assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal.new("1E-1" + "0" * 10000).sign)
+ assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal.new("-1E-1" + "0" * 10000).sign)
+ end
+
+ def test_gc
+ bug3258 = '[ruby-dev:41213]'
+ stress, GC.stress = GC.stress, true
+ 10.upto(20) do |i|
+ b = BigDecimal.new("1"+"0"*i)
+ assert_equal([1, "1", 10, i+1], b.split, bug3258)
+ end
+ ensure
+ GC.stress = stress
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/bigdecimal/test_bigmath.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/bigdecimal/test_bigmath.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/bigdecimal/test_bigmath.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,80 @@
+require_relative "testbase"
+require "bigdecimal/math"
+
+class TestBigMath < Test::Unit::TestCase
+ include TestBigDecimalBase
+ include BigMath
+ N = 20
+ PINF = BigDecimal("+Infinity")
+ MINF = BigDecimal("-Infinity")
+ NAN = BigDecimal("NaN")
+
+ def test_const
+ assert_in_delta(Math::PI, PI(N))
+ assert_in_delta(Math::E, E(N))
+ end
+
+ def test_sqrt
+ assert_in_delta(2**0.5, sqrt(BigDecimal("2"), N))
+ assert_equal(10, sqrt(BigDecimal("100"), N))
+ assert_equal(0.0, sqrt(BigDecimal("0"), N))
+ assert_equal(0.0, sqrt(BigDecimal("-0"), N))
+ assert_raise(FloatDomainError) {sqrt(BigDecimal("-1.0"), N)}
+ assert_raise(FloatDomainError) {sqrt(NAN, N)}
+ assert_raise(FloatDomainError) {sqrt(PINF, N)}
+ end
+
+ def test_sin
+ assert_in_delta(0.0, sin(BigDecimal("0.0"), N))
+ assert_in_delta(Math.sqrt(2.0) / 2, sin(PI(N) / 4, N))
+ assert_in_delta(1.0, sin(PI(N) / 2, N))
+ assert_in_delta(0.0, sin(PI(N) * 2, N))
+ assert_in_delta(0.0, sin(PI(N), N))
+ assert_in_delta(-1.0, sin(PI(N) / -2, N))
+ assert_in_delta(0.0, sin(PI(N) * -2, N))
+ assert_in_delta(0.0, sin(-PI(N), N))
+ assert_in_delta(0.0, sin(PI(N) * 21, N))
+ assert_in_delta(0.0, sin(PI(N) * 30, N))
+ assert_in_delta(-1.0, sin(PI(N) * BigDecimal("301.5"), N))
+ end
+
+ def test_cos
+ assert_in_delta(1.0, cos(BigDecimal("0.0"), N))
+ assert_in_delta(Math.sqrt(2.0) / 2, cos(PI(N) / 4, N))
+ assert_in_delta(0.0, cos(PI(N) / 2, N))
+ assert_in_delta(1.0, cos(PI(N) * 2, N))
+ assert_in_delta(-1.0, cos(PI(N), N))
+ assert_in_delta(0.0, cos(PI(N) / -2, N))
+ assert_in_delta(1.0, cos(PI(N) * -2, N))
+ assert_in_delta(-1.0, cos(-PI(N), N))
+ assert_in_delta(-1.0, cos(PI(N) * 21, N))
+ assert_in_delta(1.0, cos(PI(N) * 30, N))
+ assert_in_delta(0.0, cos(PI(N) * BigDecimal("301.5"), N))
+ end
+
+ def test_atan
+ assert_equal(0.0, atan(BigDecimal("0.0"), N))
+ assert_in_delta(Math::PI/4, atan(BigDecimal("1.0"), N))
+ assert_in_delta(Math::PI/6, atan(sqrt(BigDecimal("3.0"), N) / 3, N))
+ assert_in_delta(Math::PI/2, atan(PINF, N))
+ assert_equal(BigDecimal("0.823840753418636291769355073102514088959345624027952954058347023122539489"),
+ atan(BigDecimal("1.08"), 72).round(72), '[ruby-dev:41257]')
+ end
+
+ def test_exp
+ assert_in_epsilon(Math::E, exp(BigDecimal("1"), N))
+ assert_in_epsilon(Math.exp(N), exp(BigDecimal("20"), N))
+ assert_in_epsilon(Math.exp(40), exp(BigDecimal("40"), N))
+ assert_in_epsilon(Math.exp(-N), exp(BigDecimal("-20"), N))
+ assert_in_epsilon(Math.exp(-40), exp(BigDecimal("-40"), N))
+ end
+
+ def test_log
+ assert_in_delta(0.0, log(BigDecimal("1"), N))
+ assert_in_delta(1.0, log(E(N), N))
+ assert_in_delta(Math.log(2.0), log(BigDecimal("2"), N))
+ assert_in_delta(2.0, log(E(N)*E(N), N))
+ assert_in_delta(Math.log(42.0), log(BigDecimal("42"), N))
+ assert_in_delta(Math.log(1e-42), log(BigDecimal("1e-42"), N))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/bigdecimal/testbase.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/bigdecimal/testbase.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/bigdecimal/testbase.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,20 @@
+require "test/unit"
+require "bigdecimal"
+
+module TestBigDecimalBase
+ def setup
+ @mode = BigDecimal.mode(BigDecimal::EXCEPTION_ALL)
+ BigDecimal.mode(BigDecimal::EXCEPTION_ALL, true)
+ BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true)
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true)
+ BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
+ BigDecimal.limit(0)
+ end
+
+ def teardown
+ [BigDecimal::EXCEPTION_INFINITY, BigDecimal::EXCEPTION_NaN,
+ BigDecimal::EXCEPTION_UNDERFLOW, BigDecimal::EXCEPTION_OVERFLOW].each do |mode|
+ BigDecimal.mode(mode, !(@mode & mode).zero?)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/cgi/test_cgi_cookie.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/cgi/test_cgi_cookie.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/cgi/test_cgi_cookie.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,110 @@
+require 'test/unit'
+require 'cgi'
+require 'stringio'
+
+
+class CGICookieTest < Test::Unit::TestCase
+
+
+ def setup
+ ENV['REQUEST_METHOD'] = 'GET'
+ @str1="\xE3\x82\x86\xE3\x82\x93\xE3\x82\x86\xE3\x82\x93"
+ @str1.force_encoding("UTF-8") if defined?(::Encoding)
+ end
+
+ def teardown
+ %W[REQUEST_METHOD SCRIPT_NAME].each do |name|
+ ENV.delete(name)
+ end
+ end
+
+
+ def test_cgi_cookie_new_simple
+ cookie = CGI::Cookie.new('name1', 'val1', '&<>"', @str1)
+ assert_equal('name1', cookie.name)
+ assert_equal(['val1', '&<>"', @str1], cookie.value)
+ assert_nil(cookie.domain)
+ assert_nil(cookie.expires)
+ assert_equal('', cookie.path)
+ assert_equal(false, cookie.secure)
+ assert_equal("name1=val1&%26%3C%3E%22&%E3%82%86%E3%82%93%E3%82%86%E3%82%93; path=", cookie.to_s)
+ end
+
+
+ def test_cgi_cookie_new_complex
+ t = Time.gm(2030, 12, 31, 23, 59, 59)
+ value = ['val1', '&<>"', "\xA5\xE0\xA5\xB9\xA5\xAB"]
+ value[2].force_encoding("EUC-JP") if defined?(::Encoding)
+ cookie = CGI::Cookie.new('name'=>'name1',
+ 'value'=>value,
+ 'path'=>'/cgi-bin/myapp/',
+ 'domain'=>'www.example.com',
+ 'expires'=>t,
+ 'secure'=>true
+ )
+ assert_equal('name1', cookie.name)
+ assert_equal(value, cookie.value)
+ assert_equal('www.example.com', cookie.domain)
+ assert_equal(t, cookie.expires)
+ assert_equal('/cgi-bin/myapp/', cookie.path)
+ assert_equal(true, cookie.secure)
+ assert_equal('name1=val1&%26%3C%3E%22&%A5%E0%A5%B9%A5%AB; domain=www.example.com; path=/cgi-bin/myapp/; expires=Tue, 31 Dec 2030 23:59:59 GMT; secure', cookie.to_s)
+ end
+
+
+ def test_cgi_cookie_scriptname
+ cookie = CGI::Cookie.new('name1', 'value1')
+ assert_equal('', cookie.path)
+ cookie = CGI::Cookie.new('name'=>'name1', 'value'=>'value1')
+ assert_equal('', cookie.path)
+ ## when ENV['SCRIPT_NAME'] is set, cookie.path is set automatically
+ ENV['SCRIPT_NAME'] = '/cgi-bin/app/example.cgi'
+ cookie = CGI::Cookie.new('name1', 'value1')
+ assert_equal('/cgi-bin/app/', cookie.path)
+ cookie = CGI::Cookie.new('name'=>'name1', 'value'=>'value1')
+ assert_equal('/cgi-bin/app/', cookie.path)
+ end
+
+
+ def test_cgi_cookie_parse
+ ## ';' separator
+ cookie_str = 'name1=val1&val2; name2=val2&%26%3C%3E%22&%E3%82%86%E3%82%93%E3%82%86%E3%82%93;_session_id=12345'
+ cookies = CGI::Cookie.parse(cookie_str)
+ list = [
+ ['name1', ['val1', 'val2']],
+ ['name2', ['val2', '&<>"', at str1]],
+ ['_session_id', ['12345']],
+ ]
+ list.each do |name, value|
+ cookie = cookies[name]
+ assert_equal(name, cookie.name)
+ assert_equal(value, cookie.value)
+ end
+ ## ',' separator
+ cookie_str = 'name1=val1&val2, name2=val2&%26%3C%3E%22&%E3%82%86%E3%82%93%E3%82%86%E3%82%93,_session_id=12345'
+ cookies = CGI::Cookie.parse(cookie_str)
+ list.each do |name, value|
+ cookie = cookies[name]
+ assert_equal(name, cookie.name)
+ assert_equal(value, cookie.value)
+ end
+ end
+
+
+ def test_cgi_cookie_arrayinterface
+ cookie = CGI::Cookie.new('name1', 'a', 'b', 'c')
+ assert_equal('a', cookie[0])
+ assert_equal('c', cookie[2])
+ assert_nil(cookie[3])
+ assert_equal('a', cookie.first)
+ assert_equal('c', cookie.last)
+ assert_equal(['A', 'B', 'C'], cookie.collect{|e| e.upcase})
+ end
+
+
+
+ instance_methods.each do |method|
+ private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
+ end if ENV['TEST']
+
+end
Added: MacRuby/trunk/test/test-mri/test/cgi/test_cgi_core.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/cgi/test_cgi_core.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/cgi/test_cgi_core.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,363 @@
+require 'test/unit'
+require 'cgi'
+require 'stringio'
+
+
+class CGICoreTest < Test::Unit::TestCase
+
+
+ def setup
+ #@environ = {
+ # 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ # 'REQUEST_METHOD' => 'GET',
+ # 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ #}
+ #ENV.update(@environ)
+ end
+
+
+ def teardown
+ @environ.each do |key, val| ENV.delete(key) end
+ $stdout = STDOUT
+ end
+
+ def test_cgi_parse_illegal_query
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ 'QUERY_STRING' => 'a=111&&b=222&c&d=',
+ 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ ENV.update(@environ)
+ cgi = CGI.new
+ assert_equal(["a","b","c","d"],cgi.keys.sort) if RUBY_VERSION>="1.9"
+ assert_equal("",cgi["d"])
+ end
+
+ def test_cgi_core_params_GET
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ 'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
+ 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ ENV.update(@environ)
+ cgi = CGI.new
+ ## cgi[]
+ assert_equal('123', cgi['id'])
+ assert_equal('@h =~ /^$/', cgi['str'])
+ ## cgi[][], cgi[].first, cgi[].to_ary (obsolete 1.9)
+ if RUBY_VERSION<"1.9"
+ $stderr = StringIO.new
+ begin
+ assert_equal('123', cgi['id'][0])
+ assert_equal('456', cgi['id'][1])
+ assert_equal('', cgi['id'][2])
+ assert_nil(cgi['id'][3])
+ assert_equal('@h =~ /^$/', cgi['str'][0])
+ assert_nil(cgi['str'][1])
+ assert_equal('123', cgi['id'].first)
+ assert_equal('123', cgi['id'].last) # should be '' ?
+ id1, id2, id3 = cgi['id']
+ assert_equal(['123', '456', ''], [id1, id2, id3])
+ str1, = cgi['str']
+ assert_equal('@h =~ /^$/', str1)
+ assert_not_same(str1, cgi['str']) # necessary?
+ ensure
+ $stderr = STDERR
+ end
+ end
+ ## cgi.params
+ assert_equal(['123', '456', ''], cgi.params['id'])
+ assert_equal(['@h =~ /^$/'], cgi.params['str'])
+ ## cgi.keys
+ assert_equal(['id', 'str'], cgi.keys.sort)
+ ## cgi.key?, cgi.has_key?, cgi.include?
+ assert_equal(true, cgi.key?('id'))
+ assert_equal(true, cgi.has_key?('id'))
+ assert_equal(true, cgi.include?('id'))
+ assert_equal(false, cgi.key?('foo'))
+ assert_equal(false, cgi.has_key?('foo'))
+ assert_equal(false, cgi.include?('foo'))
+ ## invalid parameter name
+ assert_equal('', cgi['*notfound*']) # [ruby-dev:30740]
+ assert_equal([], cgi.params['*notfound*'])
+ end
+
+
+ def test_cgi_core_params_POST
+ query_str = 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F'
+ @environ = {
+ 'REQUEST_METHOD' => 'POST',
+ 'CONTENT_LENGTH' => query_str.length.to_s,
+ 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ ENV.update(@environ)
+ $stdin = StringIO.new
+ $stdin << query_str
+ $stdin.rewind
+ cgi = CGI.new
+ ## cgi[]
+ assert_equal('123', cgi['id'])
+ assert_equal('@h =~ /^$/', cgi['str'])
+ ## cgi.params
+ assert_equal(['123', '456', ''], cgi.params['id'])
+ assert_equal(['@h =~ /^$/'], cgi.params['str'])
+ ## invalid parameter name
+ assert_equal('', cgi['*notfound*'])
+ assert_equal([], cgi.params['*notfound*'])
+ end
+
+ def test_cgi_core_params_encoding_check
+ query_str = 'str=%BE%BE%B9%BE'
+ @environ = {
+ 'REQUEST_METHOD' => 'POST',
+ 'CONTENT_LENGTH' => query_str.length.to_s,
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ ENV.update(@environ)
+ $stdin = StringIO.new
+ $stdin << query_str
+ $stdin.rewind
+ if defined?(::Encoding)
+ hash={}
+ cgi = CGI.new(:accept_charset=>"UTF-8"){|key,val|hash[key]=val}
+ ## cgi[]
+ assert_equal("\xBE\xBE\xB9\xBE".force_encoding("UTF-8"), cgi['str'])
+ ## cgi.params
+ assert_equal(["\xBE\xBE\xB9\xBE".force_encoding("UTF-8")], cgi.params['str'])
+ ## accept-charset error
+ assert_equal({"str"=>"\xBE\xBE\xB9\xBE".force_encoding("UTF-8")},hash)
+
+ $stdin.rewind
+ assert_raise(CGI::InvalidEncoding) do
+ cgi = CGI.new(:accept_charset=>"UTF-8")
+ end
+
+ $stdin.rewind
+ cgi = CGI.new(:accept_charset=>"EUC-JP")
+ ## cgi[]
+ assert_equal("\xBE\xBE\xB9\xBE".force_encoding("EUC-JP"), cgi['str'])
+ ## cgi.params
+ assert_equal(["\xBE\xBE\xB9\xBE".force_encoding("EUC-JP")], cgi.params['str'])
+ else
+ assert(true)
+ end
+ end
+
+
+ def test_cgi_core_cookie
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ 'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
+ 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ ENV.update(@environ)
+ cgi = CGI.new
+ assert_not_equal(nil,cgi.cookies)
+ [ ['_session_id', ['12345'], ],
+ ['name1', ['val1', 'val2'], ],
+ ].each do |key, expected|
+ cookie = cgi.cookies[key]
+ assert_kind_of(CGI::Cookie, cookie)
+ assert_equal(expected, cookie.value)
+ assert_equal(false, cookie.secure)
+ assert_nil(cookie.expires)
+ assert_nil(cookie.domain)
+ assert_equal('', cookie.path)
+ end
+ end
+
+
+ def test_cgi_core_maxcontentlength
+ @environ = {
+ 'REQUEST_METHOD' => 'POST',
+ 'CONTENT_LENGTH' => (64 * 1024 * 1024).to_s
+ }
+ ENV.update(@environ)
+ ex = assert_raise(StandardError) do
+ cgi = CGI.new
+ end
+ assert_equal("too large post data.", ex.message)
+ end if CGI.const_defined?(:MAX_CONTENT_LENGTH)
+
+
+ def test_cgi_core_out
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ 'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
+ 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ ENV.update(@environ)
+ cgi = CGI.new
+ ## jis, euc, sjis string
+ jis_str = "\e$B8+$m!\"?M$,%4%_$N$h$&$@\e(B"
+ euc_str = "\270\253\244\355\241\242\277\315\244\254\245\264\245\337\244\316\244\350\244\246\244\300"
+ sjis_str = "\214\251\202\353\201A\220l\202\252\203S\203~\202\314\202\346\202\244\202\276"
+ if RUBY_VERSION<"1.9"
+ ## iso-2022-jp
+ options = { 'charset'=>'iso-2022-jp' }
+ $stdout = StringIO.new
+ cgi.out(options) { euc_str }
+ assert_equal('ja', options['language'])
+ actual = $stdout.string
+ expected = "Content-Type: text/html; charset=iso-2022-jp\r\n" +
+ "Content-Length: 28\r\n" +
+ "Content-Language: ja\r\n" +
+ "\r\n" +
+ jis_str
+ assert_equal(expected,actual)
+ ## euc-jp
+ options = { 'charset'=>'EUC-JP' }
+ $stdout = StringIO.new
+ cgi.out(options) { euc_str }
+ assert_equal('ja', options['language'])
+ actual = $stdout.string
+ expected = "Content-Type: text/html; charset=EUC-JP\r\n" +
+ "Content-Length: 22\r\n" +
+ "Content-Language: ja\r\n" +
+ "\r\n" +
+ euc_str
+ assert_equal(expected, actual)
+ ## shift_jis
+ options = { 'charset'=>'Shift_JIS' }
+ $stdout = StringIO.new
+ cgi.out(options) { euc_str }
+ assert_equal('ja', options['language'])
+ actual = $stdout.string
+ expected = "Content-Type: text/html; charset=Shift_JIS\r\n" +
+ "Content-Length: 22\r\n" +
+ "Content-Language: ja\r\n" +
+ "\r\n" +
+ sjis_str
+ assert_equal(expected, actual)
+ end
+ ## utf8 (not converted)
+ options = { 'charset'=>'utf8' }
+ $stdout = StringIO.new
+ cgi.out(options) { euc_str }
+ assert_nil(options['language'])
+ actual = $stdout.string
+ expected = "Content-Type: text/html; charset=utf8\r\n" +
+ "Content-Length: 22\r\n" +
+ "\r\n" +
+ euc_str
+ if defined?(::Encoding)
+ actual.force_encoding("ASCII-8BIT")
+ expected.force_encoding("ASCII-8BIT")
+ end
+ assert_equal(expected, actual)
+ ## language is keeped
+ options = { 'charset'=>'Shift_JIS', 'language'=>'en' }
+ $stdout = StringIO.new
+ cgi.out(options) { euc_str }
+ assert_equal('en', options['language'])
+ ## HEAD method
+ ENV['REQUEST_METHOD'] = 'HEAD'
+ options = { 'charset'=>'utf8' }
+ $stdout = StringIO.new
+ cgi.out(options) { euc_str }
+ actual = $stdout.string
+ expected = "Content-Type: text/html; charset=utf8\r\n" +
+ "Content-Length: 22\r\n" +
+ "\r\n"
+ assert_equal(expected, actual)
+ end
+
+
+ def test_cgi_core_print
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ }
+ ENV.update(@environ)
+ cgi = CGI.new
+ $stdout = StringIO.new
+ str = "foobar"
+ cgi.print(str)
+ expected = str
+ actual = $stdout.string
+ assert_equal(expected, actual)
+ end
+
+
+ def test_cgi_core_environs
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ }
+ ENV.update(@environ)
+ cgi = CGI.new
+ ##
+ list1 = %w[ AUTH_TYPE CONTENT_TYPE GATEWAY_INTERFACE PATH_INFO
+ PATH_TRANSLATED QUERY_STRING REMOTE_ADDR REMOTE_HOST
+ REMOTE_IDENT REMOTE_USER REQUEST_METHOD SCRIPT_NAME
+ SERVER_NAME SERVER_PROTOCOL SERVER_SOFTWARE
+ HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
+ HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM HTTP_HOST
+ HTTP_NEGOTIATE HTTP_PRAGMA HTTP_REFERER HTTP_USER_AGENT
+ ]
+ list2 = %w[ CONTENT_LENGTH SERVER_PORT ]
+ ## string expected
+ list1.each do |name|
+ @environ[name] = "**#{name}**"
+ end
+ ENV.update(@environ)
+ list1.each do |name|
+ method = name.sub(/\AHTTP_/, '').downcase
+ actual = cgi.__send__ method
+ expected = "**#{name}**"
+ assert_equal(expected, actual)
+ end
+ ## integer expected
+ ENV['CONTENT_LENGTH'] = '123'
+ ENV['SERVER_PORT'] = '8080'
+ assert_equal(123, cgi.content_length)
+ assert_equal(8080, cgi.server_port)
+ ## raw cookie
+ ENV['HTTP_COOKIE'] = 'name1=val1'
+ ENV['HTTP_COOKIE2'] = 'name2=val2'
+ assert_equal('name1=val1', cgi.raw_cookie)
+ assert_equal('name2=val2', cgi.raw_cookie2)
+ end
+
+
+ def test_cgi_core_htmltype
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ }
+ ENV.update(@environ)
+ ## no htmltype
+ cgi = CGI.new
+ assert_raise(NoMethodError) do cgi.doctype end
+ ## html3
+ cgi = CGI.new('html3')
+ expected = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">'
+ assert_equal(expected, cgi.doctype)
+ ## html4
+ cgi = CGI.new('html4')
+ expected = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'
+ assert_equal(expected, cgi.doctype)
+ ## html4 transitional
+ cgi = CGI.new('html4Tr')
+ expected = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
+ assert_equal(expected, cgi.doctype)
+ ## html4 frameset
+ cgi = CGI.new('html4Fr')
+ expected = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'
+ assert_equal(expected, cgi.doctype)
+ end
+
+
+ instance_methods.each do |method|
+ private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
+ end if ENV['TEST']
+
+end
Added: MacRuby/trunk/test/test-mri/test/cgi/test_cgi_header.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/cgi/test_cgi_header.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/cgi/test_cgi_header.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,177 @@
+require 'test/unit'
+require 'cgi'
+
+
+class CGIHeaderTest < Test::Unit::TestCase
+
+
+ def setup
+ @environ = {
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ 'REQUEST_METHOD' => 'GET',
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ }
+ ENV.update(@environ)
+ end
+
+
+ def teardown
+ @environ.each do |key, val| ENV.delete(key) end
+ end
+
+
+ def test_cgi_header_simple
+ cgi = CGI.new
+ ## default content type
+ expected = "Content-Type: text/html\r\n\r\n"
+ actual = cgi.header
+ assert_equal(expected, actual)
+ ## content type specified as string
+ expected = "Content-Type: text/xhtml; charset=utf8\r\n\r\n"
+ actual = cgi.header('text/xhtml; charset=utf8')
+ assert_equal(expected, actual)
+ ## content type specified as hash
+ expected = "Content-Type: image/png\r\n\r\n"
+ actual = cgi.header('type'=>'image/png')
+ assert_equal(expected, actual)
+ ## charset specified
+ expected = "Content-Type: text/html; charset=utf8\r\n\r\n"
+ actual = cgi.header('charset'=>'utf8')
+ assert_equal(expected, actual)
+ end
+
+
+ def test_cgi_header_complex
+ cgi = CGI.new
+ options = {
+ 'type' => 'text/xhtml',
+ 'charset' => 'utf8',
+ 'status' => 'REDIRECT',
+ 'server' => 'webrick',
+ 'connection' => 'close',
+ 'length' => 123,
+ 'language' => 'ja',
+ 'expires' => Time.gm(2000, 1, 23, 12, 34, 56),
+ 'location' => 'http://www.ruby-lang.org/',
+ }
+ expected = "Status: 302 Found\r\n"
+ expected << "Server: webrick\r\n"
+ expected << "Connection: close\r\n"
+ expected << "Content-Type: text/xhtml; charset=utf8\r\n"
+ expected << "Content-Length: 123\r\n"
+ expected << "Content-Language: ja\r\n"
+ expected << "Expires: Sun, 23 Jan 2000 12:34:56 GMT\r\n"
+ expected << "location: http://www.ruby-lang.org/\r\n"
+ expected << "\r\n"
+ actual = cgi.header(options)
+ assert_equal(expected, actual)
+ end
+
+
+ def test_cgi_header_argerr
+ cgi = CGI.new
+ #expected = NoMethodError # must be ArgumentError
+ if RUBY_VERSION>="1.9.0"
+ expected = ArgumentError # for CGIAlt
+ else
+ expected = NoMethodError # for Ruby1.8
+ end
+ ex = assert_raise(expected) do
+ cgi.header(nil)
+ end
+ end
+
+
+ def test_cgi_header_cookie
+ cgi = CGI.new
+ cookie1 = CGI::Cookie.new('name1', 'abc', '123')
+ cookie2 = CGI::Cookie.new('name'=>'name2', 'value'=>'value2', 'secure'=>true)
+ ctype = "Content-Type: text/html\r\n"
+ sep = "\r\n"
+ c1 = "Set-Cookie: name1=abc&123; path=\r\n"
+ c2 = "Set-Cookie: name2=value2; path=; secure\r\n"
+ ## CGI::Cookie object
+ actual = cgi.header('cookie'=>cookie1)
+ expected = ctype + c1 + sep
+ assert_equal(expected, actual)
+ ## String
+ actual = cgi.header('cookie'=>cookie2.to_s)
+ expected = ctype + c2 + sep
+ assert_equal(expected, actual)
+ ## Array
+ actual = cgi.header('cookie'=>[cookie1, cookie2])
+ expected = ctype + c1 + c2 + sep
+ assert_equal(expected, actual)
+ ## Hash
+ actual = cgi.header('cookie'=>{'name1'=>cookie1, 'name2'=>cookie2})
+ expected = ctype + c1 + c2 + sep
+ assert_equal(expected, actual)
+ end
+
+
+ def test_cgi_header_output_cookies
+ cgi = CGI.new
+ ## output cookies
+ cookies = [ CGI::Cookie.new('name1', 'abc', '123'),
+ CGI::Cookie.new('name'=>'name2', 'value'=>'value2', 'secure'=>true),
+ ]
+ cgi.instance_variable_set('@output_cookies', cookies)
+ expected = "Content-Type: text/html; charset=utf8\r\n"
+ expected << "Set-Cookie: name1=abc&123; path=\r\n"
+ expected << "Set-Cookie: name2=value2; path=; secure\r\n"
+ expected << "\r\n"
+ ## header when string
+ actual = cgi.header('text/html; charset=utf8')
+ assert_equal(expected, actual)
+ ## _header_for_string
+ actual = cgi.header('type'=>'text/html', 'charset'=>'utf8')
+ assert_equal(expected, actual)
+ end
+
+
+ def test_cgi_header_nph
+ cgi = CGI.new
+ ## 'nph' is true
+ ENV['SERVER_SOFTWARE'] = 'Apache 2.2.0'
+ actual1 = cgi.header('nph'=>true)
+ ## when old IIS, NPH-mode is forced
+ ENV['SERVER_SOFTWARE'] = 'IIS/4.0'
+ actual2 = cgi.header
+ actual3 = cgi.header('status'=>'REDIRECT', 'location'=>'http://www.example.com/')
+ ## newer IIS doesn't require NPH-mode ## [ruby-dev:30537]
+ ENV['SERVER_SOFTWARE'] = 'IIS/5.0'
+ actual4 = cgi.header
+ actual5 = cgi.header('status'=>'REDIRECT', 'location'=>'http://www.example.com/')
+ ## assertion
+ now = Time.now
+ expected = "HTTP/1.1 200 OK\r\n"
+ expected << "Date: #{CGI.rfc1123_date(now)}\r\n"
+ expected << "Server: Apache 2.2.0\r\n"
+ expected << "Connection: close\r\n"
+ expected << "Content-Type: text/html\r\n"
+ expected << "\r\n"
+ assert_equal(expected, actual1)
+ expected.sub!(/^Server: .*?\r\n/, "Server: IIS/4.0\r\n")
+ assert_equal(expected, actual2)
+ expected.sub!(/^HTTP\/1.1 200 OK\r\n/, "HTTP/1.1 302 Found\r\n")
+ expected.sub!(/\r\n\r\n/, "\r\nlocation: http://www.example.com/\r\n\r\n")
+ assert_equal(expected, actual3)
+ expected = "Content-Type: text/html\r\n"
+ expected << "\r\n"
+ assert_equal(expected, actual4)
+ expected = "Status: 302 Found\r\n"
+ expected << "Content-Type: text/html\r\n"
+ expected << "location: http://www.example.com/\r\n"
+ expected << "\r\n"
+ assert_equal(expected, actual5)
+ ensure
+ ENV.delete('SERVER_SOFTWARE')
+ end
+
+
+
+ instance_methods.each do |method|
+ private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
+ end if ENV['TEST']
+
+end
Added: MacRuby/trunk/test/test-mri/test/cgi/test_cgi_modruby.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/cgi/test_cgi_modruby.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/cgi/test_cgi_modruby.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,145 @@
+require 'test/unit'
+require 'cgi'
+
+
+class CGIModrubyTest < Test::Unit::TestCase
+
+
+ def setup
+ @environ = {
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ 'REQUEST_METHOD' => 'GET',
+ #'QUERY_STRING' => 'a=foo&b=bar',
+ }
+ ENV.update(@environ)
+ CGI.class_eval { const_set(:MOD_RUBY, true) }
+ Apache._reset()
+ #@cgi = CGI.new
+ #@req = Apache.request
+ end
+
+
+ def teardown
+ @environ.each do |key, val| ENV.delete(key) end
+ CGI.class_eval { remove_const(:MOD_RUBY) }
+ end
+
+
+ def test_cgi_modruby_simple
+ req = Apache.request
+ cgi = CGI.new
+ assert(req._setup_cgi_env_invoked?)
+ assert(! req._send_http_header_invoked?)
+ actual = cgi.header
+ assert_equal('', actual)
+ assert_equal('text/html', req.content_type)
+ assert(req._send_http_header_invoked?)
+ end
+
+
+ def test_cgi_modruby_complex
+ req = Apache.request
+ cgi = CGI.new
+ options = {
+ 'status' => 'FORBIDDEN',
+ 'location' => 'http://www.example.com/',
+ 'type' => 'image/gif',
+ 'content-encoding' => 'deflate',
+ 'cookie' => [ CGI::Cookie.new('name1', 'abc', '123'),
+ CGI::Cookie.new('name'=>'name2', 'value'=>'value2', 'secure'=>true),
+ ],
+ }
+ assert(req._setup_cgi_env_invoked?)
+ assert(! req._send_http_header_invoked?)
+ actual = cgi.header(options)
+ assert_equal('', actual)
+ assert_equal('image/gif', req.content_type)
+ assert_equal('403 Forbidden', req.status_line)
+ assert_equal(403, req.status)
+ assert_equal('deflate', req.content_encoding)
+ assert_equal('http://www.example.com/', req.headers_out['location'])
+ assert_equal(["name1=abc&123; path=", "name2=value2; path=; secure"],
+ req.headers_out['Set-Cookie'])
+ assert(req._send_http_header_invoked?)
+ end
+
+
+ def test_cgi_modruby_location
+ req = Apache.request
+ cgi = CGI.new
+ options = {
+ 'status' => '200 OK',
+ 'location' => 'http://www.example.com/',
+ }
+ actual = cgi.header(options)
+ assert_equal('200 OK', req.status_line) # should be '302 Found' ?
+ assert_equal(302, req.status)
+ assert_equal('http://www.example.com/', req.headers_out['location'])
+ end
+
+
+ def test_cgi_modruby_requestparams
+ req = Apache.request
+ req.args = 'a=foo&b=bar'
+ cgi = CGI.new
+ assert_equal('foo', cgi['a'])
+ assert_equal('bar', cgi['b'])
+ end
+
+
+ instance_methods.each do |method|
+ private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
+ end if ENV['TEST']
+
+end
+
+
+
+## dummy class for mod_ruby
+class Apache #:nodoc:
+
+ def self._reset
+ @request = Request.new
+ end
+
+ def self.request
+ return @request
+ end
+
+ class Request
+
+ def initialize
+ hash = {}
+ def hash.add(name, value)
+ (self[name] ||= []) << value
+ end
+ @headers_out = hash
+ @status_line = nil
+ @status = nil
+ @content_type = nil
+ @content_encoding = nil
+ end
+ attr_accessor :headers_out, :status_line, :status, :content_type, :content_encoding
+
+ attr_accessor :args
+ #def args
+ # return ENV['QUERY_STRING']
+ #end
+
+ def send_http_header
+ @http_header = '*invoked*'
+ end
+ def _send_http_header_invoked?
+ @http_header ? true : false
+ end
+
+ def setup_cgi_env
+ @cgi_env = '*invoked*'
+ end
+ def _setup_cgi_env_invoked?
+ @cgi_env ? true : false
+ end
+
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/cgi/test_cgi_multipart.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/cgi/test_cgi_multipart.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/cgi/test_cgi_multipart.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,312 @@
+require 'test/unit'
+require 'cgi'
+require 'tempfile'
+require 'stringio'
+
+
+##
+## usage:
+## boundary = 'foobar1234' # or nil
+## multipart = MultiPart.new(boundary)
+## multipart.append('name1', 'value1')
+## multipart.append('file1', File.read('file1.html'), 'file1.html')
+## str = multipart.close()
+## str.each_line {|line| p line }
+## ## output:
+## # "--foobar1234\r\n"
+## # "Content-Disposition: form-data: name=\"name1\"\r\n"
+## # "\r\n"
+## # "value1\r\n"
+## # "--foobar1234\r\n"
+## # "Content-Disposition: form-data: name=\"file1\"; filename=\"file1.html\"\r\n"
+## # "Content-Type: text/html\r\n"
+## # "\r\n"
+## # "<html>\n"
+## # "<body><p>Hello</p></body>\n"
+## # "</html>\n"
+## # "\r\n"
+## # "--foobar1234--\r\n"
+##
+class MultiPart
+
+ def initialize(boundary=nil)
+ @boundary = boundary || create_boundary()
+ @buf = ''
+ @buf.force_encoding(::Encoding::ASCII_8BIT) if defined?(::Encoding)
+ end
+ attr_reader :boundary
+
+ def append(name, value, filename=nil, content_type=nil)
+ content_type = detect_content_type(filename) if filename && content_type.nil?
+ s = filename ? "; filename=\"#{filename}\"" : ''
+ buf = @buf
+ buf << "--#{boundary}\r\n"
+ buf << "Content-Disposition: form-data: name=\"#{name}\"#{s}\r\n"
+ buf << "Content-Type: #{content_type}\r\n" if content_type
+ buf << "\r\n"
+ value = value.dup.force_encoding(::Encoding::ASCII_8BIT) if defined?(::Encoding)
+ buf << value
+ buf << "\r\n"
+ return self
+ end
+
+ def close
+ buf = @buf
+ @buf = ''
+ return buf << "--#{boundary}--\r\n"
+ end
+
+ def create_boundary() #:nodoc:
+ return "--boundary#{rand().to_s[2..-1]}"
+ end
+
+ def detect_content_type(filename) #:nodoc:
+ filename =~ /\.(\w+)\z/
+ return MIME_TYPES[$1] || 'application/octet-stream'
+ end
+
+ MIME_TYPES = {
+ 'gif' => 'image/gif',
+ 'jpg' => 'image/jpeg',
+ 'jpeg' => 'image/jpeg',
+ 'png' => 'image/png',
+ 'bmp' => 'image/bmp',
+ 'tif' => 'image/tiff',
+ 'tiff' => 'image/tiff',
+ 'htm' => 'text/html',
+ 'html' => 'text/html',
+ 'xml' => 'text/xml',
+ 'txt' => 'text/plain',
+ 'text' => 'text/plain',
+ 'css' => 'text/css',
+ 'mpg' => 'video/mpeg',
+ 'mpeg' => 'video/mpeg',
+ 'mov' => 'video/quicktime',
+ 'avi' => 'video/x-msvideo',
+ 'mp3' => 'audio/mpeg',
+ 'mid' => 'audio/midi',
+ 'wav' => 'audio/x-wav',
+ 'zip' => 'application/zip',
+ #'tar.gz' => 'application/gtar',
+ 'gz' => 'application/gzip',
+ 'bz2' => 'application/bzip2',
+ 'rtf' => 'application/rtf',
+ 'pdf' => 'application/pdf',
+ 'ps' => 'application/postscript',
+ 'js' => 'application/x-javascript',
+ 'xls' => 'application/vnd.ms-excel',
+ 'doc' => 'application/msword',
+ 'ppt' => 'application/vnd.ms-powerpoint',
+ }
+
+end
+
+
+
+class CGIMultipartTest < Test::Unit::TestCase
+
+ def setup
+ ENV['REQUEST_METHOD'] = 'POST'
+ end
+
+ def teardown
+ %w[ REQUEST_METHOD CONTENT_TYPE CONTENT_LENGTH REQUEST_METHOD ].each do |name|
+ ENV.delete(name)
+ end
+ $stdin.close() if $stdin.is_a?(Tempfile)
+ $stdin = STDIN
+ end
+
+ def _prepare(data)
+ ## create multipart input
+ multipart = MultiPart.new(@boundary)
+ data.each do |hash|
+ multipart.append(hash[:name], hash[:value], hash[:filename])
+ end
+ input = multipart.close()
+ input = yield(input) if block_given?
+ #$stderr.puts "*** debug: input=\n#{input.collect{|line| line.inspect}.join("\n")}"
+ @boundary ||= multipart.boundary
+ ## set environment
+ ENV['CONTENT_TYPE'] = "multipart/form-data; boundary=#{@boundary}"
+ ENV['CONTENT_LENGTH'] = input.length.to_s
+ ENV['REQUEST_METHOD'] = 'POST'
+ ## set $stdin
+ tmpfile = Tempfile.new('test_cgi_multipart')
+ tmpfile.binmode
+ tmpfile << input
+ tmpfile.rewind()
+ $stdin = tmpfile
+ end
+
+ def _test_multipart
+ caller(0).find {|s| s =~ /in `test_(.*?)'/ }
+ testname = $1
+ #$stderr.puts "*** debug: testname=#{testname.inspect}"
+ _prepare(@data)
+ cgi = RUBY_VERSION>="1.9" ? CGI.new(:accept_charset=>"UTF-8") : CGI.new
+ expected_names = @data.collect{|hash| hash[:name] }.sort
+ assert_equal(expected_names, cgi.params.keys.sort)
+ threshold = 1024*10
+ @data.each do |hash|
+ name = hash[:name]
+ expected = hash[:value]
+ if RUBY_VERSION>="1.9"
+ if hash[:filename] #if file
+ expected_class = @expected_class || (hash[:value].length < threshold ? StringIO : Tempfile)
+ assert(cgi.files.keys.member?(hash[:name]))
+ else
+ expected_class = String
+ assert_equal(expected, cgi[name])
+ assert_equal(false,cgi.files.keys.member?(hash[:name]))
+ end
+ else
+ expected_class = @expected_class || (hash[:value].length < threshold ? StringIO : Tempfile)
+ end
+ assert_kind_of(expected_class, cgi[name])
+ assert_equal(expected, cgi[name].read())
+ assert_equal(hash[:filename] || '', cgi[name].original_filename) #if hash[:filename]
+ assert_equal(hash[:content_type] || '', cgi[name].content_type) #if hash[:content_type]
+ end
+ end
+
+
+ def _read(basename)
+ filename = File.join(File.dirname(__FILE__), 'testdata', basename)
+ s = File.open(filename, 'rb') {|f| f.read() }
+
+ return s
+ end
+
+
+ def test_cgi_multipart_stringio
+ @boundary = '----WebKitFormBoundaryAAfvAII+YL9102cX'
+ @data = [
+ {:name=>'hidden1', :value=>'foobar'},
+ {:name=>'text1', :value=>"\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A"},
+ {:name=>'file1', :value=>_read('file1.html'),
+ :filename=>'file1.html', :content_type=>'text/html'},
+ {:name=>'image1', :value=>_read('small.png'),
+ :filename=>'small.png', :content_type=>'image/png'}, # small image
+ ]
+ @data[1][:value].force_encoding(::Encoding::UTF_8) if defined?(::Encoding)
+ @expected_class = StringIO
+ _test_multipart()
+ end
+
+
+ def test_cgi_multipart_tempfile
+ @boundary = '----WebKitFormBoundaryAAfvAII+YL9102cX'
+ @data = [
+ {:name=>'hidden1', :value=>'foobar'},
+ {:name=>'text1', :value=>"\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A"},
+ {:name=>'file1', :value=>_read('file1.html'),
+ :filename=>'file1.html', :content_type=>'text/html'},
+ {:name=>'image1', :value=>_read('large.png'),
+ :filename=>'large.png', :content_type=>'image/png'}, # large image
+ ]
+ @data[1][:value].force_encoding(::Encoding::UTF_8) if defined?(::Encoding)
+ @expected_class = Tempfile
+ _test_multipart()
+ end
+
+
+ def _set_const(klass, name, value)
+ old = nil
+ klass.class_eval do
+ old = const_get(name)
+ remove_const(name)
+ const_set(name, value)
+ end
+ return old
+ end
+
+
+ def test_cgi_multipart_maxmultipartlength
+ @data = [
+ {:name=>'image1', :value=>_read('large.png'),
+ :filename=>'large.png', :content_type=>'image/png'}, # large image
+ ]
+ original = _set_const(CGI, :MAX_MULTIPART_LENGTH, 2 * 1024)
+ begin
+ ex = assert_raise(StandardError) do
+ _test_multipart()
+ end
+ assert_equal("too large multipart data.", ex.message)
+ ensure
+ _set_const(CGI, :MAX_MULTIPART_LENGTH, original)
+ end
+ end if CGI.const_defined?(:MAX_MULTIPART_LENGTH)
+
+
+ def test_cgi_multipart_maxmultipartcount
+ @data = [
+ {:name=>'file1', :value=>_read('file1.html'),
+ :filename=>'file1.html', :content_type=>'text/html'},
+ ]
+ item = @data.first
+ 500.times { @data << item }
+ #original = _set_const(CGI, :MAX_MULTIPART_COUNT, 128)
+ begin
+ ex = assert_raise(StandardError) do
+ _test_multipart()
+ end
+ assert_equal("too many parameters.", ex.message)
+ ensure
+ #_set_const(CGI, :MAX_MULTIPART_COUNT, original)
+ end
+ end if CGI.const_defined?(:MAX_MULTIPART_COUNT)
+
+
+ def test_cgi_multipart_badbody ## [ruby-dev:28470]
+ @data = [
+ {:name=>'file1', :value=>_read('file1.html'),
+ :filename=>'file1.html', :content_type=>'text/html'},
+ ]
+ _prepare(@data) do |input|
+ input2 = input.sub(/--(\r\n)?\z/, "\r\n")
+ assert input2 != input
+ #p input2
+ input2
+ end
+ ex = assert_raise(EOFError) do
+ cgi = RUBY_VERSION>="1.9" ? CGI.new(:accept_charset=>"UTF-8") : CGI.new
+ end
+ assert_equal("bad boundary end of body part", ex.message)
+ #
+ _prepare(@data) do |input|
+ input2 = input.sub(/--(\r\n)?\z/, "")
+ assert input2 != input
+ #p input2
+ input2
+ end
+ ex = assert_raise(EOFError) do
+ cgi = RUBY_VERSION>="1.9" ? CGI.new(:accept_charset=>"UTF-8") : CGI.new
+ end
+ assert_equal("bad content body", ex.message)
+ end
+
+
+ def test_cgi_multipart_quoteboundary ## [JVN#84798830]
+ @boundary = '(.|\n)*'
+ @data = [
+ {:name=>'hidden1', :value=>'foobar'},
+ {:name=>'text1', :value=>"\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A"},
+ {:name=>'file1', :value=>_read('file1.html'),
+ :filename=>'file1.html', :content_type=>'text/html'},
+ {:name=>'image1', :value=>_read('small.png'),
+ :filename=>'small.png', :content_type=>'image/png'}, # small image
+ ]
+ @data[1][:value].force_encoding("UTF-8") if RUBY_VERSION>="1.9"
+ _prepare(@data)
+ cgi = RUBY_VERSION>="1.9" ? CGI.new(:accept_charset=>"UTF-8") : CGI.new
+ assert_equal('file1.html', cgi['file1'].original_filename)
+ end
+
+ ###
+
+ self.instance_methods.each do |method|
+ private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
+ end if ENV['TEST']
+
+end
Added: MacRuby/trunk/test/test-mri/test/cgi/test_cgi_session.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/cgi/test_cgi_session.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/cgi/test_cgi_session.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,173 @@
+require 'test/unit'
+require 'cgi'
+require 'cgi/session'
+require 'cgi/session/pstore'
+require 'stringio'
+require 'tmpdir'
+
+class CGISessionTest < Test::Unit::TestCase
+ def setup
+ @session_dir = File.join(File.dirname(__FILE__), 'session_dir')
+ FileUtils.mkdir_p @session_dir
+ end
+
+ def teardown
+ @environ.each do |key, val| ENV.delete(key) end
+ $stdout = STDOUT
+ FileUtils.rm_rf(@session_dir)
+ end
+
+ def test_cgi_session_filestore
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ # 'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
+ # 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ value1="value1"
+ value2="\x8F\xBC\x8D]"
+ value2.force_encoding("SJIS") if defined?(::Encoding)
+ ENV.update(@environ)
+ cgi = CGI.new
+ session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
+ session["key1"]=value1
+ session["key2"]=value2
+ assert_equal(value1,session["key1"])
+ assert_equal(value2,session["key2"])
+ session.close
+ $stdout = StringIO.new
+ cgi.out{""}
+
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ # 'HTTP_COOKIE' => "_session_id=#{session_id}",
+ 'QUERY_STRING' => "_session_id=#{session.session_id}",
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ ENV.update(@environ)
+ cgi = CGI.new
+ session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
+ $stdout = StringIO.new
+ assert_equal(value1,session["key1"])
+ assert_equal(value2,session["key2"])
+ session.close
+
+ end
+ def test_cgi_session_pstore
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ # 'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
+ # 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ value1="value1"
+ value2="\x8F\xBC\x8D]"
+ value2.force_encoding("SJIS") if defined?(::Encoding)
+ ENV.update(@environ)
+ cgi = CGI.new
+ session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"database_manager"=>CGI::Session::PStore)
+ session["key1"]=value1
+ session["key2"]=value2
+ assert_equal(value1,session["key1"])
+ assert_equal(value2,session["key2"])
+ session.close
+ $stdout = StringIO.new
+ cgi.out{""}
+
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ # 'HTTP_COOKIE' => "_session_id=#{session_id}",
+ 'QUERY_STRING' => "_session_id=#{session.session_id}",
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ ENV.update(@environ)
+ cgi = CGI.new
+ session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"database_manager"=>CGI::Session::PStore)
+ $stdout = StringIO.new
+ assert_equal(value1,session["key1"])
+ assert_equal(value2,session["key2"])
+ session.close
+ end
+ def test_cgi_session_specify_session_id
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ # 'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
+ # 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ value1="value1"
+ value2="\x8F\xBC\x8D]"
+ value2.force_encoding("SJIS") if defined?(::Encoding)
+ ENV.update(@environ)
+ cgi = CGI.new
+ session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"session_id"=>"foo")
+ session["key1"]=value1
+ session["key2"]=value2
+ assert_equal(value1,session["key1"])
+ assert_equal(value2,session["key2"])
+ assert_equal("foo",session.session_id)
+ session_id=session.session_id
+ session.close
+ $stdout = StringIO.new
+ cgi.out{""}
+
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ # 'HTTP_COOKIE' => "_session_id=#{session_id}",
+ 'QUERY_STRING' => "_session_id=#{session.session_id}",
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ ENV.update(@environ)
+ cgi = CGI.new
+ session = CGI::Session.new(cgi,"tmpdir"=>@session_dir)
+ $stdout = StringIO.new
+ assert_equal(value1,session["key1"])
+ assert_equal(value2,session["key2"])
+ assert_equal("foo",session.session_id)
+ session.close
+ end
+ def test_cgi_session_specify_session_key
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ # 'QUERY_STRING' => 'id=123&id=456&id=&str=%40h+%3D%7E+%2F%5E%24%2F',
+ # 'HTTP_COOKIE' => '_session_id=12345; name1=val1&val2;',
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ value1="value1"
+ value2="\x8F\xBC\x8D]"
+ value2.force_encoding("SJIS") if defined?(::Encoding)
+ ENV.update(@environ)
+ cgi = CGI.new
+ session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"session_key"=>"bar")
+ session["key1"]=value1
+ session["key2"]=value2
+ assert_equal(value1,session["key1"])
+ assert_equal(value2,session["key2"])
+ session_id=session.session_id
+ session.close
+ $stdout = StringIO.new
+ cgi.out{""}
+
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ 'HTTP_COOKIE' => "bar=#{session_id}",
+ # 'QUERY_STRING' => "bar=#{session.session_id}",
+ 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ }
+ ENV.update(@environ)
+ cgi = CGI.new
+ session = CGI::Session.new(cgi,"tmpdir"=>@session_dir,"session_key"=>"bar")
+ $stdout = StringIO.new
+ assert_equal(value1,session["key1"])
+ assert_equal(value2,session["key2"])
+ session.close
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/cgi/test_cgi_tag_helper.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/cgi/test_cgi_tag_helper.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/cgi/test_cgi_tag_helper.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,341 @@
+require 'test/unit'
+require 'cgi'
+require 'stringio'
+
+
+class CGITagHelperTest < Test::Unit::TestCase
+
+
+ def setup
+ #@environ = {
+ # 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ # 'REQUEST_METHOD' => 'GET',
+ # 'SERVER_SOFTWARE' => 'Apache 2.2.0',
+ #}
+ #ENV.update(@environ)
+ end
+
+
+ def teardown
+ @environ.each do |key, val| ENV.delete(key) end
+ $stdout = STDOUT
+ end
+
+
+ def test_cgi_tag_helper_html3
+ @environ = {
+ 'REQUEST_METHOD' => 'GET',
+ }
+ ENV.update(@environ)
+ ## html3
+ cgi = CGI.new('html3')
+ assert_equal('<A HREF=""></A>',cgi.a)
+ assert_equal('<A HREF="bar"></A>',cgi.a('bar'))
+ assert_equal('<A HREF="">foo</A>',cgi.a{'foo'})
+ assert_equal('<A HREF="bar">foo</A>',cgi.a('bar'){'foo'})
+ assert_equal('<TT></TT>',cgi.tt)
+ assert_equal('<TT></TT>',cgi.tt('bar'))
+ assert_equal('<TT>foo</TT>',cgi.tt{'foo'})
+ assert_equal('<TT>foo</TT>',cgi.tt('bar'){'foo'})
+ assert_equal('<I></I>',cgi.i)
+ assert_equal('<I></I>',cgi.i('bar'))
+ assert_equal('<I>foo</I>',cgi.i{'foo'})
+ assert_equal('<I>foo</I>',cgi.i('bar'){'foo'})
+ assert_equal('<B></B>',cgi.b)
+ assert_equal('<B></B>',cgi.b('bar'))
+ assert_equal('<B>foo</B>',cgi.b{'foo'})
+ assert_equal('<B>foo</B>',cgi.b('bar'){'foo'})
+ assert_equal('<U></U>',cgi.u)
+ assert_equal('<U></U>',cgi.u('bar'))
+ assert_equal('<U>foo</U>',cgi.u{'foo'})
+ assert_equal('<U>foo</U>',cgi.u('bar'){'foo'})
+ assert_equal('<STRIKE></STRIKE>',cgi.strike)
+ assert_equal('<STRIKE></STRIKE>',cgi.strike('bar'))
+ assert_equal('<STRIKE>foo</STRIKE>',cgi.strike{'foo'})
+ assert_equal('<STRIKE>foo</STRIKE>',cgi.strike('bar'){'foo'})
+ assert_equal('<BIG></BIG>',cgi.big)
+ assert_equal('<BIG></BIG>',cgi.big('bar'))
+ assert_equal('<BIG>foo</BIG>',cgi.big{'foo'})
+ assert_equal('<BIG>foo</BIG>',cgi.big('bar'){'foo'})
+ assert_equal('<SMALL></SMALL>',cgi.small)
+ assert_equal('<SMALL></SMALL>',cgi.small('bar'))
+ assert_equal('<SMALL>foo</SMALL>',cgi.small{'foo'})
+ assert_equal('<SMALL>foo</SMALL>',cgi.small('bar'){'foo'})
+ assert_equal('<SUB></SUB>',cgi.sub)
+ assert_equal('<SUB></SUB>',cgi.sub('bar'))
+ assert_equal('<SUB>foo</SUB>',cgi.sub{'foo'})
+ assert_equal('<SUB>foo</SUB>',cgi.sub('bar'){'foo'})
+ assert_equal('<SUP></SUP>',cgi.sup)
+ assert_equal('<SUP></SUP>',cgi.sup('bar'))
+ assert_equal('<SUP>foo</SUP>',cgi.sup{'foo'})
+ assert_equal('<SUP>foo</SUP>',cgi.sup('bar'){'foo'})
+ assert_equal('<EM></EM>',cgi.em)
+ assert_equal('<EM></EM>',cgi.em('bar'))
+ assert_equal('<EM>foo</EM>',cgi.em{'foo'})
+ assert_equal('<EM>foo</EM>',cgi.em('bar'){'foo'})
+ assert_equal('<STRONG></STRONG>',cgi.strong)
+ assert_equal('<STRONG></STRONG>',cgi.strong('bar'))
+ assert_equal('<STRONG>foo</STRONG>',cgi.strong{'foo'})
+ assert_equal('<STRONG>foo</STRONG>',cgi.strong('bar'){'foo'})
+ assert_equal('<DFN></DFN>',cgi.dfn)
+ assert_equal('<DFN></DFN>',cgi.dfn('bar'))
+ assert_equal('<DFN>foo</DFN>',cgi.dfn{'foo'})
+ assert_equal('<DFN>foo</DFN>',cgi.dfn('bar'){'foo'})
+ assert_equal('<CODE></CODE>',cgi.code)
+ assert_equal('<CODE></CODE>',cgi.code('bar'))
+ assert_equal('<CODE>foo</CODE>',cgi.code{'foo'})
+ assert_equal('<CODE>foo</CODE>',cgi.code('bar'){'foo'})
+ assert_equal('<SAMP></SAMP>',cgi.samp)
+ assert_equal('<SAMP></SAMP>',cgi.samp('bar'))
+ assert_equal('<SAMP>foo</SAMP>',cgi.samp{'foo'})
+ assert_equal('<SAMP>foo</SAMP>',cgi.samp('bar'){'foo'})
+ assert_equal('<KBD></KBD>',cgi.kbd)
+ assert_equal('<KBD></KBD>',cgi.kbd('bar'))
+ assert_equal('<KBD>foo</KBD>',cgi.kbd{'foo'})
+ assert_equal('<KBD>foo</KBD>',cgi.kbd('bar'){'foo'})
+ assert_equal('<VAR></VAR>',cgi.var)
+ assert_equal('<VAR></VAR>',cgi.var('bar'))
+ assert_equal('<VAR>foo</VAR>',cgi.var{'foo'})
+ assert_equal('<VAR>foo</VAR>',cgi.var('bar'){'foo'})
+ assert_equal('<CITE></CITE>',cgi.cite)
+ assert_equal('<CITE></CITE>',cgi.cite('bar'))
+ assert_equal('<CITE>foo</CITE>',cgi.cite{'foo'})
+ assert_equal('<CITE>foo</CITE>',cgi.cite('bar'){'foo'})
+ assert_equal('<FONT></FONT>',cgi.font)
+ assert_equal('<FONT></FONT>',cgi.font('bar'))
+ assert_equal('<FONT>foo</FONT>',cgi.font{'foo'})
+ assert_equal('<FONT>foo</FONT>',cgi.font('bar'){'foo'})
+ assert_equal('<ADDRESS></ADDRESS>',cgi.address)
+ assert_equal('<ADDRESS></ADDRESS>',cgi.address('bar'))
+ assert_equal('<ADDRESS>foo</ADDRESS>',cgi.address{'foo'})
+ assert_equal('<ADDRESS>foo</ADDRESS>',cgi.address('bar'){'foo'})
+ assert_equal('<DIV></DIV>',cgi.div)
+ assert_equal('<DIV></DIV>',cgi.div('bar'))
+ assert_equal('<DIV>foo</DIV>',cgi.div{'foo'})
+ assert_equal('<DIV>foo</DIV>',cgi.div('bar'){'foo'})
+ assert_equal('<CENTER></CENTER>',cgi.center)
+ assert_equal('<CENTER></CENTER>',cgi.center('bar'))
+ assert_equal('<CENTER>foo</CENTER>',cgi.center{'foo'})
+ assert_equal('<CENTER>foo</CENTER>',cgi.center('bar'){'foo'})
+ assert_equal('<MAP></MAP>',cgi.map)
+ assert_equal('<MAP></MAP>',cgi.map('bar'))
+ assert_equal('<MAP>foo</MAP>',cgi.map{'foo'})
+ assert_equal('<MAP>foo</MAP>',cgi.map('bar'){'foo'})
+ assert_equal('<APPLET></APPLET>',cgi.applet)
+ assert_equal('<APPLET></APPLET>',cgi.applet('bar'))
+ assert_equal('<APPLET>foo</APPLET>',cgi.applet{'foo'})
+ assert_equal('<APPLET>foo</APPLET>',cgi.applet('bar'){'foo'})
+ assert_equal('<PRE></PRE>',cgi.pre)
+ assert_equal('<PRE></PRE>',cgi.pre('bar'))
+ assert_equal('<PRE>foo</PRE>',cgi.pre{'foo'})
+ assert_equal('<PRE>foo</PRE>',cgi.pre('bar'){'foo'})
+ assert_equal('<XMP></XMP>',cgi.xmp)
+ assert_equal('<XMP></XMP>',cgi.xmp('bar'))
+ assert_equal('<XMP>foo</XMP>',cgi.xmp{'foo'})
+ assert_equal('<XMP>foo</XMP>',cgi.xmp('bar'){'foo'})
+ assert_equal('<LISTING></LISTING>',cgi.listing)
+ assert_equal('<LISTING></LISTING>',cgi.listing('bar'))
+ assert_equal('<LISTING>foo</LISTING>',cgi.listing{'foo'})
+ assert_equal('<LISTING>foo</LISTING>',cgi.listing('bar'){'foo'})
+ assert_equal('<DL></DL>',cgi.dl)
+ assert_equal('<DL></DL>',cgi.dl('bar'))
+ assert_equal('<DL>foo</DL>',cgi.dl{'foo'})
+ assert_equal('<DL>foo</DL>',cgi.dl('bar'){'foo'})
+ assert_equal('<OL></OL>',cgi.ol)
+ assert_equal('<OL></OL>',cgi.ol('bar'))
+ assert_equal('<OL>foo</OL>',cgi.ol{'foo'})
+ assert_equal('<OL>foo</OL>',cgi.ol('bar'){'foo'})
+ assert_equal('<UL></UL>',cgi.ul)
+ assert_equal('<UL></UL>',cgi.ul('bar'))
+ assert_equal('<UL>foo</UL>',cgi.ul{'foo'})
+ assert_equal('<UL>foo</UL>',cgi.ul('bar'){'foo'})
+ assert_equal('<DIR></DIR>',cgi.dir)
+ assert_equal('<DIR></DIR>',cgi.dir('bar'))
+ assert_equal('<DIR>foo</DIR>',cgi.dir{'foo'})
+ assert_equal('<DIR>foo</DIR>',cgi.dir('bar'){'foo'})
+ assert_equal('<MENU></MENU>',cgi.menu)
+ assert_equal('<MENU></MENU>',cgi.menu('bar'))
+ assert_equal('<MENU>foo</MENU>',cgi.menu{'foo'})
+ assert_equal('<MENU>foo</MENU>',cgi.menu('bar'){'foo'})
+ assert_equal('<SELECT></SELECT>',cgi.select)
+ assert_equal('<SELECT></SELECT>',cgi.select('bar'))
+ assert_equal('<SELECT>foo</SELECT>',cgi.select{'foo'})
+ assert_equal('<SELECT>foo</SELECT>',cgi.select('bar'){'foo'})
+ assert_equal('<TABLE></TABLE>',cgi.table)
+ assert_equal('<TABLE></TABLE>',cgi.table('bar'))
+ assert_equal('<TABLE>foo</TABLE>',cgi.table{'foo'})
+ assert_equal('<TABLE>foo</TABLE>',cgi.table('bar'){'foo'})
+ assert_equal('<TITLE></TITLE>',cgi.title)
+ assert_equal('<TITLE></TITLE>',cgi.title('bar'))
+ assert_equal('<TITLE>foo</TITLE>',cgi.title{'foo'})
+ assert_equal('<TITLE>foo</TITLE>',cgi.title('bar'){'foo'})
+ assert_equal('<STYLE></STYLE>',cgi.style)
+ assert_equal('<STYLE></STYLE>',cgi.style('bar'))
+ assert_equal('<STYLE>foo</STYLE>',cgi.style{'foo'})
+ assert_equal('<STYLE>foo</STYLE>',cgi.style('bar'){'foo'})
+ assert_equal('<SCRIPT></SCRIPT>',cgi.script)
+ assert_equal('<SCRIPT></SCRIPT>',cgi.script('bar'))
+ assert_equal('<SCRIPT>foo</SCRIPT>',cgi.script{'foo'})
+ assert_equal('<SCRIPT>foo</SCRIPT>',cgi.script('bar'){'foo'})
+ assert_equal('<H1></H1>',cgi.h1)
+ assert_equal('<H1></H1>',cgi.h1('bar'))
+ assert_equal('<H1>foo</H1>',cgi.h1{'foo'})
+ assert_equal('<H1>foo</H1>',cgi.h1('bar'){'foo'})
+ assert_equal('<H2></H2>',cgi.h2)
+ assert_equal('<H2></H2>',cgi.h2('bar'))
+ assert_equal('<H2>foo</H2>',cgi.h2{'foo'})
+ assert_equal('<H2>foo</H2>',cgi.h2('bar'){'foo'})
+ assert_equal('<H3></H3>',cgi.h3)
+ assert_equal('<H3></H3>',cgi.h3('bar'))
+ assert_equal('<H3>foo</H3>',cgi.h3{'foo'})
+ assert_equal('<H3>foo</H3>',cgi.h3('bar'){'foo'})
+ assert_equal('<H4></H4>',cgi.h4)
+ assert_equal('<H4></H4>',cgi.h4('bar'))
+ assert_equal('<H4>foo</H4>',cgi.h4{'foo'})
+ assert_equal('<H4>foo</H4>',cgi.h4('bar'){'foo'})
+ assert_equal('<H5></H5>',cgi.h5)
+ assert_equal('<H5></H5>',cgi.h5('bar'))
+ assert_equal('<H5>foo</H5>',cgi.h5{'foo'})
+ assert_equal('<H5>foo</H5>',cgi.h5('bar'){'foo'})
+ assert_equal('<H6></H6>',cgi.h6)
+ assert_equal('<H6></H6>',cgi.h6('bar'))
+ assert_equal('<H6>foo</H6>',cgi.h6{'foo'})
+ assert_equal('<H6>foo</H6>',cgi.h6('bar'){'foo'})
+ assert_match(/^<TEXTAREA .*><\/TEXTAREA>$/,cgi.textarea)
+ assert_match(/COLS="70"/,cgi.textarea)
+ assert_match(/ROWS="10"/,cgi.textarea)
+ assert_match(/NAME=""/,cgi.textarea)
+ assert_match(/^<TEXTAREA .*><\/TEXTAREA>$/,cgi.textarea("bar"))
+ assert_match(/COLS="70"/,cgi.textarea("bar"))
+ assert_match(/ROWS="10"/,cgi.textarea("bar"))
+ assert_match(/NAME="bar"/,cgi.textarea("bar"))
+ assert_match(/^<TEXTAREA .*>foo<\/TEXTAREA>$/,cgi.textarea{"foo"})
+ assert_match(/COLS="70"/,cgi.textarea{"foo"})
+ assert_match(/ROWS="10"/,cgi.textarea{"foo"})
+ assert_match(/NAME=""/,cgi.textarea{"foo"})
+ assert_match(/^<TEXTAREA .*>foo<\/TEXTAREA>$/,cgi.textarea("bar"){"foo"})
+ assert_match(/COLS="70"/,cgi.textarea("bar"){"foo"})
+ assert_match(/ROWS="10"/,cgi.textarea("bar"){"foo"})
+ assert_match(/NAME="bar"/,cgi.textarea("bar"){"foo"})
+ assert_match(/^<FORM .*><\/FORM>$/,cgi.form)
+ assert_match(/METHOD="post"/,cgi.form)
+ assert_match(/ENCTYPE="application\/x-www-form-urlencoded"/,cgi.form)
+ assert_match(/^<FORM .*><\/FORM>$/,cgi.form("bar"))
+ assert_match(/METHOD="bar"/,cgi.form("bar"))
+ assert_match(/ENCTYPE="application\/x-www-form-urlencoded"/,cgi.form("bar"))
+ assert_match(/^<FORM .*>foo<\/FORM>$/,cgi.form{"foo"})
+ assert_match(/METHOD="post"/,cgi.form{"foo"})
+ assert_match(/ENCTYPE="application\/x-www-form-urlencoded"/,cgi.form{"foo"})
+ assert_match(/^<FORM .*>foo<\/FORM>$/,cgi.form("bar"){"foo"})
+ assert_match(/METHOD="bar"/,cgi.form("bar"){"foo"})
+ assert_match(/ENCTYPE="application\/x-www-form-urlencoded"/,cgi.form("bar"){"foo"})
+ assert_equal('<BLOCKQUOTE></BLOCKQUOTE>',cgi.blockquote)
+ assert_equal('<BLOCKQUOTE CITE="bar"></BLOCKQUOTE>',cgi.blockquote('bar'))
+ assert_equal('<BLOCKQUOTE>foo</BLOCKQUOTE>',cgi.blockquote{'foo'})
+ assert_equal('<BLOCKQUOTE CITE="bar">foo</BLOCKQUOTE>',cgi.blockquote('bar'){'foo'})
+ assert_equal('<CAPTION></CAPTION>',cgi.caption)
+ assert_equal('<CAPTION ALIGN="bar"></CAPTION>',cgi.caption('bar'))
+ assert_equal('<CAPTION>foo</CAPTION>',cgi.caption{'foo'})
+ assert_equal('<CAPTION ALIGN="bar">foo</CAPTION>',cgi.caption('bar'){'foo'})
+ assert_equal('<IMG SRC="" ALT="">',cgi.img)
+ assert_equal('<IMG SRC="bar" ALT="">',cgi.img('bar'))
+ assert_equal('<IMG SRC="" ALT="">',cgi.img{'foo'})
+ assert_equal('<IMG SRC="bar" ALT="">',cgi.img('bar'){'foo'})
+ assert_equal('<BASE HREF="">',cgi.base)
+ assert_equal('<BASE HREF="bar">',cgi.base('bar'))
+ assert_equal('<BASE HREF="">',cgi.base{'foo'})
+ assert_equal('<BASE HREF="bar">',cgi.base('bar'){'foo'})
+ assert_equal('<BASEFONT>',cgi.basefont)
+ assert_equal('<BASEFONT>',cgi.basefont('bar'))
+ assert_equal('<BASEFONT>',cgi.basefont{'foo'})
+ assert_equal('<BASEFONT>',cgi.basefont('bar'){'foo'})
+ assert_equal('<BR>',cgi.br)
+ assert_equal('<BR>',cgi.br('bar'))
+ assert_equal('<BR>',cgi.br{'foo'})
+ assert_equal('<BR>',cgi.br('bar'){'foo'})
+ assert_equal('<AREA>',cgi.area)
+ assert_equal('<AREA>',cgi.area('bar'))
+ assert_equal('<AREA>',cgi.area{'foo'})
+ assert_equal('<AREA>',cgi.area('bar'){'foo'})
+ assert_equal('<LINK>',cgi.link)
+ assert_equal('<LINK>',cgi.link('bar'))
+ assert_equal('<LINK>',cgi.link{'foo'})
+ assert_equal('<LINK>',cgi.link('bar'){'foo'})
+ assert_equal('<PARAM>',cgi.param)
+ assert_equal('<PARAM>',cgi.param('bar'))
+ assert_equal('<PARAM>',cgi.param{'foo'})
+ assert_equal('<PARAM>',cgi.param('bar'){'foo'})
+ assert_equal('<HR>',cgi.hr)
+ assert_equal('<HR>',cgi.hr('bar'))
+ assert_equal('<HR>',cgi.hr{'foo'})
+ assert_equal('<HR>',cgi.hr('bar'){'foo'})
+ assert_equal('<INPUT>',cgi.input)
+ assert_equal('<INPUT>',cgi.input('bar'))
+ assert_equal('<INPUT>',cgi.input{'foo'})
+ assert_equal('<INPUT>',cgi.input('bar'){'foo'})
+ assert_equal('<ISINDEX>',cgi.isindex)
+ assert_equal('<ISINDEX>',cgi.isindex('bar'))
+ assert_equal('<ISINDEX>',cgi.isindex{'foo'})
+ assert_equal('<ISINDEX>',cgi.isindex('bar'){'foo'})
+ assert_equal('<META>',cgi.meta)
+ assert_equal('<META>',cgi.meta('bar'))
+ assert_equal('<META>',cgi.meta{'foo'})
+ assert_equal('<META>',cgi.meta('bar'){'foo'})
+ assert_equal('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML>',cgi.html)
+ assert_equal('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML>foo</HTML>',cgi.html{'foo'})
+ assert_equal('<HEAD>',cgi.head)
+ assert_equal('<HEAD>foo</HEAD>',cgi.head{'foo'})
+ assert_equal('<BODY>',cgi.body)
+ assert_equal('<BODY>foo</BODY>',cgi.body{'foo'})
+ assert_equal('<P>',cgi.p)
+ assert_equal('<P>foo</P>',cgi.p{'foo'})
+ assert_equal('<PLAINTEXT>',cgi.plaintext)
+ assert_equal('<PLAINTEXT>foo</PLAINTEXT>',cgi.plaintext{'foo'})
+ assert_equal('<DT>',cgi.dt)
+ assert_equal('<DT>foo</DT>',cgi.dt{'foo'})
+ assert_equal('<DD>',cgi.dd)
+ assert_equal('<DD>foo</DD>',cgi.dd{'foo'})
+ assert_equal('<LI>',cgi.li)
+ assert_equal('<LI>foo</LI>',cgi.li{'foo'})
+ assert_equal('<OPTION>',cgi.option)
+ assert_equal('<OPTION>foo</OPTION>',cgi.option{'foo'})
+ assert_equal('<TR>',cgi.tr)
+ assert_equal('<TR>foo</TR>',cgi.tr{'foo'})
+ assert_equal('<TH>',cgi.th)
+ assert_equal('<TH>foo</TH>',cgi.th{'foo'})
+ assert_equal('<TD>',cgi.td)
+ assert_equal('<TD>foo</TD>',cgi.td{'foo'})
+ str=cgi.checkbox_group("foo",["aa","bb"],["cc","dd"])
+ assert_match(/^<INPUT .*VALUE="aa".*>bb<INPUT .*VALUE="cc".*>dd$/,str)
+ assert_match(/^<INPUT .*TYPE="checkbox".*>bb<INPUT .*TYPE="checkbox".*>dd$/,str)
+ assert_match(/^<INPUT .*NAME="foo".*>bb<INPUT .*NAME="foo".*>dd$/,str)
+ str=cgi.radio_group("foo",["aa","bb"],["cc","dd"])
+ assert_match(/^<INPUT .*VALUE="aa".*>bb<INPUT .*VALUE="cc".*>dd$/,str)
+ assert_match(/^<INPUT .*TYPE="radio".*>bb<INPUT .*TYPE="radio".*>dd$/,str)
+ assert_match(/^<INPUT .*NAME="foo".*>bb<INPUT .*NAME="foo".*>dd$/,str)
+ str=cgi.checkbox_group("foo",["aa","bb"],["cc","dd",true])
+ assert_match(/^<INPUT .*VALUE="aa".*>bb<INPUT .*VALUE="cc".*>dd$/,str)
+ assert_match(/^<INPUT .*TYPE="checkbox".*>bb<INPUT .*TYPE="checkbox".*>dd$/,str)
+ assert_match(/^<INPUT .*NAME="foo".*>bb<INPUT .*NAME="foo".*>dd$/,str)
+ assert_match(/^<INPUT .*>bb<INPUT .*CHECKED.*>dd$/,str)
+ assert_match(/<INPUT .*TYPE="text".*>/,cgi.text_field(:name=>"name",:value=>"value")) if RUBY_VERSION>="1.9"
+ if RUBY_VERSION>="1.9"
+ str=cgi.radio_group("foo",["aa","bb"],["cc","dd",false])
+ assert_match(/^<INPUT .*VALUE="aa".*>bb<INPUT .*VALUE="cc".*>dd$/,str)
+ assert_match(/^<INPUT .*TYPE="radio".*>bb<INPUT .*TYPE="radio".*>dd$/,str)
+ assert_match(/^<INPUT .*NAME="foo".*>bb<INPUT .*NAME="foo".*>dd$/,str)
+ end
+ end
+
+=begin
+ def test_cgi_tag_helper_html4
+ ## html4
+ cgi = CGI.new('html4')
+ ## html4 transitional
+ cgi = CGI.new('html4Tr')
+ ## html4 frameset
+ cgi = CGI.new('html4Fr')
+ end
+=end
+
+end
Added: MacRuby/trunk/test/test-mri/test/cgi/test_cgi_util.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/cgi/test_cgi_util.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/cgi/test_cgi_util.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,37 @@
+require 'test/unit'
+require 'cgi'
+require 'stringio'
+
+
+class CGIUtilTest < Test::Unit::TestCase
+
+
+ def setup
+ ENV['REQUEST_METHOD'] = 'GET'
+ @str1="&<>\" \xE3\x82\x86\xE3\x82\x93\xE3\x82\x86\xE3\x82\x93"
+ @str1.force_encoding("UTF-8") if defined?(::Encoding)
+ end
+
+ def teardown
+ %W[REQUEST_METHOD SCRIPT_NAME].each do |name|
+ ENV.delete(name)
+ end
+ end
+
+
+ def test_cgi_escape
+ assert_equal('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93', CGI::escape(@str1))
+ assert_equal('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93'.ascii_only?, CGI::escape(@str1).ascii_only?) if defined?(::Encoding)
+ end
+
+ def test_cgi_unescape
+ assert_equal(@str1, CGI::unescape('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93'))
+ assert_equal(@str1.encoding, CGI::unescape('%26%3C%3E%22+%E3%82%86%E3%82%93%E3%82%86%E3%82%93').encoding) if defined?(::Encoding)
+ end
+
+ def test_cgi_pretty
+ assert_equal("<HTML>\n <BODY>\n </BODY>\n</HTML>\n",CGI::pretty("<HTML><BODY></BODY></HTML>"))
+ assert_equal("<HTML>\n\t<BODY>\n\t</BODY>\n</HTML>\n",CGI::pretty("<HTML><BODY></BODY></HTML>","\t"))
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/cgi/testdata/file1.html
===================================================================
--- MacRuby/trunk/test/test-mri/test/cgi/testdata/file1.html (rev 0)
+++ MacRuby/trunk/test/test-mri/test/cgi/testdata/file1.html 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <title>ムスカ大佐のひとりごと</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF8">
+ </head>
+ <body>
+ <p>バカどもにはちょうどいい目くらましだ。</p>
+ </body>
+</html>
Added: MacRuby/trunk/test/test-mri/test/cgi/testdata/large.png
===================================================================
--- MacRuby/trunk/test/test-mri/test/cgi/testdata/large.png (rev 0)
+++ MacRuby/trunk/test/test-mri/test/cgi/testdata/large.png 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1068 @@
+\x89PNG
+
+
+IHDR v \xBB\xB7֦ 9iCCPICC Profile x\x9C\x95Wy4\xD4o\xFB\xBE?\xB3ZǾ\x84j\x92-\xFB\x92\x84d;\xD9\xF75\xCB`\x981\xD3{JRZDD\xA8eɒHQ\xF66I\xF2\x95*\xA9("!\xA5D\xF3\xFB\xA3\xBE}\xCF\xF9\xBD\xE7}\xDF\xF3\xDE]\xCF}\xAE\xEB\xBE\xEE\xE79\xCF9\xF7\xB9\xF8\xA7*
+ h\x91,\xA6\x93\x85 \xD1\xC3Ӌ\x88\xDC \xFC\xC0 ZAQc[\xF8\xB7\xF1\xF5) \x83*ut\xC5V\xEB\x99^\xAAE#!W5\xDDS\xFE\xDF\xEB \x80\xC0\xF4\xF0\xF4@\x94@8\xF46 \xE1\xC0_\xD8 \x84cY \xC2Aa\xC1 \xC8^ Pf\xBA8\x91 \x90J \x84\xFE\xC2\xCD @\xFC\x85\xEF !&(\x94\x80\xE0#\x83)\x91 \xF8Y \xDC\xCE`rT A \x82\x83\xA3\x82h \x84\x93 \xC8O\x8D
\xC0 \x82L 3 \xA8xxz\xB5
\xC0\xD0\xC9\xC0\xA3\xFF\xC9\xD1\xCE Կ\x90\xAA\xFE''\xDF ZP\xFBO\xEE\xB3 \x80\x88\xF6G\x85hi \xC2c\x80
c\xB3?\xCB\xE0\xB3ֲ\xD8\xEC\xA5l\xF6\xDA \xF4\x80NjP43\xE6\xF7{!H\xC0;\xFF\xBA\xF3\xEF@# ( \xB0C0\xC8N\xE4(2\x89RB\x85\xA3\xEAQl\xF4t\xFA\x86\x85\xC3\xD2p\xEBp+
b\x9C\xFB\xB8ey\xF9\xF8,r\x84\xBE\x88Z\x89kJ\xF0I\xADO߸\x9D8(
\xBC\xF9\xA3\xEC
\xB9e\x85dE^\xA5l\xE5IUA5\xF5H\x8DR͑\xAD\xE2\xDAn\xDBN\xE9\xFC\xA5ˣG\xD2O\xDC\xD1l\xF0\xCDP\xD7(\xC2\xF8\xB4\xC9MҰ\xE9\xBC9\x87\xD1R\xD7\xCA\xCB:٦\xD0\xF6\xE4.\x8A\x9D\xB1\xBD\x94\xFD\xB2Ðc\xA3S\x8E3\xD3\xC5\xCEU\xDEu\xCDm\xC0\xBD\xC6#\xC73\xCD+ћ\xE5C\xF3\x8D\xF0\xA3\xFA\x87\xEF r \xB6#W\x85\x8A\x84\xED\xA7LEXRKh\xB3tUF\xE8\x9ELf}Tk4\xFAm\xCCT째\x95l"\xFF^\xA9$\xB9}j\xFB\xB5\x92\xB5\xA8\xA6\xC8
\x94N\xD59\xE4|\x98\x9Av\xE0H\xD6ѢcW\x8E\xDFNqb-S\xFE\xA4WVn\xF6\xE5S\xB59չ\xB5\xA7\xEB\xF2\x9A\xF2\xDB
+n\x9D\xB9{\xB6\xFB\xDC\xDD¶\xA2\xC6\xF3U\xC5C%\xDF.\\x94)S+\xD8V\xB9\xEDҶ*\xFDjR\x8DC\xAD\xC7eR\x9DD݇+m\xF5Y
+䫺\x8D\x84\xC6W\xD7j\xAF\xC766\xA3\x9Bo\xDF8pӸ\xDB\xF2\xB05\xBF-\xB4]\xA7\x83\xB3\xE3ygUW\xDC-\xB3\xDB\xD2w\xEE\xDAܣu\xB9\xAE\xA7\xF6AK\xEF\xFD\x87\xA3}\xFD|ix?4|\xC2\xFDdt\xA8\xEA\xE9\xDEg\xC3\xD2Ë#]\xA3ǟ;\xBD}1\xF2\xB2o\xAC\xFBU\xDBx\xF5\xEBSo\xE2\xDF\xFANOʽ\xE3}\xB7\xFA~n\xEA\xFD\xF4\xFD'f\xECg\x85fG?^\x98\xA3~\xDA6\xF3\xDD\xC7w}\xE6\xFDܻt\xEA\x8B\xFFW\xF5e\xFC\xF2\xE4\xB7\xDFW\xCA\x9CY=\xB9v\xF4g*ە\xCD w\x84\xB1F\x8APh\x94#\xAA
+͍\xF6C\xDF\xC0\x88c\x98\x98\xC7X\xECc\
+ޏ#\x9E\xF3 \xF7Qޓ|\x8F5\x853D{\xC5g$\x96\xA4>l\xE8#\x9E\x93\xF6\x96ᑽ(\xAF\xABЭ\xE8\xAC\xF4F%J\x95\xADn\xA7\xAByV\xEB\xD6֏\xDBDtH\xDB\xC3u3\xF4j\xF4\xEF\xED5\x985\xC4\xA9\xBB\x9BĒ2M\x8B\xCDj͛,\xBA,Z=\xB7\x9E\xB7\xE5\xDE%o\xB7ў\xDB~\xD9\xE1\x9D\xE3S\xA7\xFB\xCE7]j\\xDCR\xDDi
Ξ^\xAFO\xDEC>\xED\xBEU~\xFE\xBB\xEC
+d\x85\xEF&;\x84X\x85S8ã"^\xD2vF\x9E\xA5O\xEFQg2\xA2γz\xA2\xA7c\xD1qb\xF1[\x8C}\xF6\xC6%\xE5\x{DEFE}(\xF9s
+\xE1\xA0l\xAA\xCE!\xB3\xC3\xEEi9G
C
WOw=\x95\x91\x91Y~\xB2#k4{5G.\xD7\xEE\xB4_\x9E[\xBEM\x81\xE9\xE3\xB3\xC6\xE7L
+IE\xA4\xF3&ņ%\xBA\xA5j\xB6^\xF4*;\~\xA9\xE2V\xE5\xE0\xA5WU\xEF\xAAgjjW\xEA8\xAEH\xD6+4l\xBC\x8A\xB9:\xD1x\xFFZ\xED\xF5즄\xE6\x807\xB7\xB4p\xB6\xBCo\xEDj\xCBi\xED\xD8\xD1)\xD49\xDB\xD5s\xAB\xE2v\xCA
\xBF\xBB\xDB\xEF\xF1\xDD{\xD3}\xF5\xFE\xB1\x9E\xC4 \xBD\xB1i}~\x8Fl\xFBu\xFE\x92
x\x8C~\xBC6\xB8:C\x8BO۞\xA5\xEFy;Z\xFF<\xE9\x85\xD5K\x81\x97\xCF\xC6
+^y\x8Co_y=\xFE\xE6\xF6ۢ ֤\xE5;\x89w3\xEF;\xA6NO3?8\xCFh\xCDr\xCCv~\x8C\x9BӘ\x9B\xFDT9\xB2\xB0y\xE1\xF5\xE2\xD9\xCF.K\Km_\xE8_\xA5\xBF/gs\xF8.\xF8}d\xA5\xECk\xD5lMlm\xE6g;\x8C\xCD \xF8\x86"\xD9\xC8w\x94\xEA
jm\x87.\xC7\xE00\x91\x98\x97X*N7\x8A\xBF\xC6Q\xCD\xD9ŵ\xC2λ\xCCW-@\xB2\xD9 \xDA(NZ\xD7.\xA9*\x95\xB9~f\xA3.1yӽ\xCD|2^\xB2\x97\xE4\xBE*\x88mURQSS\x95PW\xD0\xC0i|Ӝ\xD0z\xB4\xB5U\xFBʶ2\x9D\x9C퉺\xBEz\xFA\xFA\x82\xFA3;\xEE\xEF\xDColdm\x8C6n4 " \x93\xBAM\xF7\x9Ai\x9AM\x9BY8[\xE2,\xAF[\x91\xAD\xAC\xBBl\x98\xB6\xB2\xB6#\xBB2\xEC\xCC\xECV\xED
B
\xC5
\xBB\x9D\xA2\x9C%\x9D\xBB\B\]\xBBܘ\xEE2\xEEC
i\x9E:\x9E\xAF\xBDҼe\xBD[}
|ؾ5~\xAE~_\xFCswk\xEF
8\xA8\x84z\xDCC~\x8A\x84iQ\xC3\xD3#iKt1\x86\xE1\x9Epfa\xD4P4O\xCC\xE6\xD8
+q\xE2\xF1\x92 \x8A\x89F{\x93\x8E\xEEk\xD8\xFF\xF2 6E\xEE\xA0q\xAA\xFB\xA1\xBD\x87\xD2^\xE5:\xA6t\xDC4\xDD\xE9\x84{\x86S\xA6\xC9I\xC5,\x9E\xAC\xD9ݧ\xEAr\xAE\xE4֞.\xCAK\xCE\xF7)P/`\x9Fyp6\xFB\x9CW\xE1\xA6\xC2领\xF3\xB9\xC5q%\x8E\xA5ҥs\xAE_\x8C/\xD3+[-o\xAFH\xA9\xB4\xBA\xB4\xBE
+\xAAf\xAAՔ\xD5W\x87\xAE\xEB\xBFr\xA1>\xB9\x81v\x95ژt\xAD\xF0\xFAզ\xD6\xE6\xF6]7;ZZZ\xDBj\xDB+:\xCEw\x9E\xEE:q+\xFDv靾\xBBݢ\xF7\xB7\xF7x>H\xEC-}\xF8\xA0o\xAD_\xFB/\xD6\xC0\xB5ǣ\x83O
\xBDz\xBA<\xBCq\xC4e4\xE7\xF9\xEB\x97c\xE7\xC7q\xAF\xE9o\x86'H\x93M\xEFwO+\xCDT\xFB\xBF\x88,=[\x9E\xFC!\xFES\x9B\xCD\xF85\xFB p\xDB \xF2\xFD<D\x9C\x952\xAB \xA8 "\xBB
x\t\xC5\xE7(Ua@\xFE\xCC.0\x80D
)A\xE6Q\xAA\xA8 \xD4 T#j\xB5\x82\x96B\xEB\xA1=\xD01\xE8
t\xBA=\x87\xE1\xC5(c\x9C0\x89\x98\x8B\x98~\xCC*V\xEB\x85M\xC7v`\x97p\xCA82\xAE\xF7/\x81\xF7\xC4\xE7\xE3\x879\xC49<9\xCEpLp\xEAp\xE6p.p\xD9qUssq\x87q\xDF\xE3\x91\xE3I\xE3\xF9\xC0k\xC7\xDBHXOH#,\xF0y\xF3\xDD\xE3\xD7\xE4\xBF( !\x90#((\x98#$!T"\xBCE\xF8\xAA\x88\x9EH\x97\xA8\xB9\xE8\xA4X\x89x\xE0:\xE9u\xE5\x92)
+\xA9\xB5\xF5\x8F6\x94o<@\xB4\xDF$\xBCiD\xBAps\xA0\x8C\xAC̔l\x9D\\x8C\xBC\x89\x82\x80\xC2ԖEG\xC5I\xA5xe>\xE52C\x95\x97\xAAIj2j\xEA)\xBA?4;\xB52\xB6j\xEF\xDC&\xAD\x83י\xDEާ[\xAF\x97\xA7\xBF\xC5\xC0}\xA7\xAD\xA1\xB9\x91\x85\xB1\xBD\x89I\xD9T\xC41[4\x9F\xB2xk\xF9\xDC\xEA\x89u\x8FM\x8BmŮ;\x86\xBD\xBD\x83\xA5\xA3\xBFS\xBCs\x96K\x95k\xBB\xDBS\xF7yO\x82\x97\x9A\xB7\x8BO\xAAo\x93\xFF\xA7\xDD_qA\x82
+\xC9a!\xA1\xFD|\xB8a\x93ZJ\xEB\xA7s2\x98\Q\xB9\xD1cj\xE3\xF4\xE3\xFBI\xFB\xFA\x93O\xA7\xA7*\x9AM+9\xEA|
\x93ޘA;\xA9\x985w\x8A\x9CS\x99\xFB>O5?\xA9`\xE8\xAC湜\xC2\xE5\xF3n\xC5
+\xA5\xB8\xCEϔ}\xACH\xBED\xAE6\xAB\x95\xBD̾\xB1\xE6zEs\xDD\xCD\xCE\xD6\xD0v|G]\xE5\xB6\xC6
\xF6\xBD\x81\xFB\xA5\xA2
j\xF7-\xF6\x97
+
l\x9A5x<v|\xBC\xFD\xCDڤ\xF5\xFB\xA2\xE9\xC73?\xE6\x84\xE6%\x85\x97\xE0˫\xE5\xB6\xEFy?hk\xA6l6 p\x82\xEC\x83\x88
+R\x82\xBCE\x89\xA1LQTT&\xAAՇ\x9AA\xE3ћцhot
:}=\x88^b\xF40\xFE\x98C\x98Z\xCC\xB0JXO\xEC\xEC
+\xEC,\x8E\x88\xF3\xC0e\xE1z\xF1x\xBC)>\xDF\xC5
F
8\xEEp\x8Ap28\xFB\xB9Ը2\xB9\xE6\xB9]\xB8\x9Bx6\xF0\xA4\xF1,\xF1\xF3>#\xD8\xEE\xF3\xF2]\xE1\x97\xE5/\x908/(+xE\xC8@\xA8W\xD8KxJ$ZD3Ĵ\xC5&\xC5sי\xAD\xFB*qI\xD2WJLjh}\xDE\xFF\x8D\xEADqh\xD3Ei\xE6f#n\x99!\xD9R9\xBA\xBC\x91\x82\x90\xC2ܖ.E\xC5Y\xA5\xCAbʵ**\xAA\xD5\xD4\xD5hl\xD5XЬ\xDBj\xAE\xBDN{a[\xAFN\xC9\xF6][=i\xBD\xEF\xFA;\xAA
+\x8E\xEC\xA4\xDA\xE9+\x9A\x88\x98\x8C\x91.\x9B
4\xF31\x90\xB6\xE4\xB3d[}\xB6\x9E\xB2yi\xFBhW\x8B]\x99}\xAEC\xB1\xE3=\xA7i.\xD7-nf\xEEA
=˽z\xBD\xBF\xF8\xCA\xFB\xF9\xF8\xB3v\xD3\xF6\xEE
+\xCA
+\xAE#\x86B\x98:%0\xFCTDu*\x92\x8FnŨan\x8C:\xC1Z\x89\xA1\xC4>\x8D7Khݫ\x9FԱ\xDF.y&%=uˡ\xDBi
G>
;\x92.s\xA2731kk\xF6\x9B
\xD7ܮ<\x9D\xFCg\xCCΎ2\xCEc\x8BsK%/\x94\xCA\xF3*\xF7UE\xD6\xF8\6\xBF\xA2\xD6 \xD5(t]\xB4Y\xEE\xA6Y+\xB1\xEDmG]\xD7\xC9\xDB\xFBﲺ=\xA1\xBD
}\xFA\xFDb
\x83nCUϖG\x8D^
{\xFAZ\xEDm\xDE;\xFE\xA9\xCC\xD4ǰO-\x8B\xA8%ݯa\xDFN\xAFt\xAD~d\xB3\x80t\xE1 L \xA6H:\xF2Ł2D1Q\xA5\xA8>\xD42\x9A\x88\xB6 at G\xA2sѭ\xE87.\x8C&& \x93\x8D\xB9\x83Y\xC1j`#\xB0\x95\xD8\xF78
+[\xC3[\xE0\xB3\xF1c
\x8A
\xB1
ݜr\x9C\xD9\\xC0\xC95\xC6\xED\xC8}\x97ǀ\xE7&\xAF>o'\xC1\x960\xCA·\xC0@`\x9D@\xB3\xA0\xAF\xA7P\x93p\xA8\x88\x98\xC8
Q\x86\x98\xAD\xB8\xDE:y aI\xB4\xE4\x92\xD4\xEC\xFA\x89\xC8&\x82\xB4\xE4fE]Y\xB9`\xF9\xC3
+W\xB7\xCC)i)G\xAA\x94\xAB\x8E\xA9Kh\xF8j6lݬݠ\x83\xDAN\xD1}\xAFO\xD91\xBEs\xBB!\xDD\xE8\xA8\xF11
+i\x87\xA9\x88\xE9'\xB3G\xE6
+g,S\xAD\xE8֞6ƶ
+\xBB\xB8v\xCD\xDA\xF5\xD8\xD7;\xB4:\x8E;\xAD\xBA\xADw\xF7\xF4\xE4\xF1\xC2z\x83\xE2\xCB\xE9'[5 at .P&H!X\x8Blz4\xAC\x8Dp\xA26F\xE9y6\xD38\xEA\xEBm\x8C{\xECp<=Qho\xA8d\xF9\xE3ɩ3\x87\x8F18\xCA>\xDE\xA2"39\xCB\xFD\x94l\xD3.ysg
+\xDDΫ/\xBD|Ѹ\xECF\x85d%\xED\xD2`\xB5UM\xEF\xE5]u#\xF5a
+\xECƼ\xEBjMoP[\xAD\xA5\xED\xFC
\x9D\xB7\xB6\xDD.\xB9K\xB8\x97\xD4=\xD3\xE3\xF4\xA0\xED\xA1D_\xF4\xA3\xD6\xD0O<)zj\xF9\xEC\xCD}t\xEA\x85\xEB\xCB\xEB\xAF㾯\x8B\x9E\xD80\xE9\xF1.\xFB}\xDF4\xE7\xD2L\xD2l\xEDǖ\xB9\xF6O\xCD\xF3\x95\xB9\x8B\x8C\xCFKBKϿ\xE4\xB5\xF9\xFAs\xB9\xE4\x9Bɷ7\xDF\xE3V+l\xFDqg\xD5e\xF5\xEDڞ5\xF6\xCFwl6\xC0\xAF} \xB8Ht*\x9DI\xB4%\x99\xFE\x97\xE5\xEE
+5\xFAo> ࡰ\xAC\ @ \xEE\x840͝ \xC0 \x86#\xED\xEC@ \x91 G\x999\xFF\xC6\xCA!s+ \xE0@v2X. \x80\xD8%\x84\xB9\xB8 \xB0v\xF8\x8DY\x91T;[ @R\x82ɦf\xBF\xB5\xF9t' \xE0@*ɑ\xAE\xD7o\x8C\x8Aq\xFE\x9Bs/8\xC0\xD4 \xA4 \x90\xA7 a$\xBB\xDF\xFCE\xB0\x98\x82\x80T\xA0(\xD0A\xC0\x84 \x88"\x8C\x82\x80 \x88@4\xC4\xA8@\x81=
+2D\xFD\xD6G\xC8
+L0\x87 `B(\x90A\xE5\xB7ÿ\xFA\xB8\xC10\x81\xF2\xBA?%\x85Ik\x89ɧ\xC7빅\xA9W\xABO\xAB\xAF\xF17\xDB\xE6\x8F#"\xFFT\xFA\xE5
\xF8\xF7\xF9\xD1l\xD3\xEC\xE9Ou\xE2\xF60!\xF4\xFF\xF5\xA1! L\x882DA\xBC&\xD0\xFC))\xFF\xE8\xE0\xD7\xEE
+ \x80\xE38\xE7 \xD0is\xEC_\xFE \x8B
\xC7 \xD1\xF1LJh\x8Bh\xCC`P\xC9D\x9Dƈf\x91\x99\xCAD\xAB\xC8 Ue\xA2\xA6\xBA\xBA6 \xC0\xFF\xF4\x8Da6s`\xD0 IDATx\x9C\xEC\xBD{|
W}\xFF\xFD9\xB3\xBB3gVZ\xED\xCAw)\xC9 ؉C@\x8E\xFC\x834,hj\xFA\xA3VJ\x9A\x94\xF6P$n\xAFף<\xB4\xE1 X~\xD2\x9A\x944j\xC0\xEF\xB1
.\xA2- IS"C\x88 C\xAE\xDED \xC4\xC6!\x89Wv"ɲ\xAD\x9D\xD5J;gfw\xE7<\x9C\xDD\xD1h/\xB2dK\xB6.\xE7\xFD\xDA\xD7xv.\xE7\x9C9+K\x9F\xFD\xDEY\xBFe;\xCAC@\xA69;8\xE7\x80\xC39\xE7\x9C\xE7\xDE{\x8E\xF7\xB2$w\x8Cs\x9E\xBF\x9Esγ\x8E\xE3\xC0\xC9\xF0l&\x93\xC98\xD9L6\x9B\x8E
~\xE9,G\xB5\xB4!\xE4l?\xB5\xB9%\xF7\xD1\xA1(\xCA9
\xC9\xF9e\xB6\x9F\xCB\}\x8E\xE5\xE6\xB6\xFD\xCE\xF7\xF8g\xDB\xEF\
/G\xB9\xCF\xF9~\xAEٶ#\xF0\xF9|3křU\xA7\xE5~x8\x9F];\xE5 \x98\x9B\xF1̞r\xFD\x96>\xEE8\xB3|^Rz\x9C\xDEqf\xCFR\xBA_\xCEg\xFB\xCBan>/\xC9ydU\xED\xC5\xE7\xF7\xFB\xFD\xC4\xE7\x87\xE2W\x85\x88\x8B"\xFE\xE1
+!\xF0\x89\x9F4Nr\xE7\x85B\x80\xA9G\xCE\x8E\xE9~\x8C\xFDg\xDF\xC1\xC2a\xB6\xF35w\xBF\xAD\xE6\x97r\xCFUn\xFCMb.UΗ\xE4\x9Ao\xA6\x84:\xF7\xFD\xCEv\xFA\xE7j<\x8A\xF2\x83/-\xC0g+=y\x99v\xCAI\xCF\xD9\xFE2\x9C+\xDC\xEF\xC3
\x95\x{DDCC}\x9C\xFE\xEFqɞK
\xD3\xE0\xED]\xEC/\xEA6\xC9\xD2cII\xCCٲ\xD8\xFF7.\x96\xF1/\xC9?\xBDX<\xE3_\xECRx\xFE\xA5d\xB9vf\xF7n\xA1͛D"\x91\x9C_\x96\xB5Ĝ-\xF2O\xB1X\xACq\xF3\xCDr\x9B\x87\xB9\xEAw\xB1K\xB7\xF35\x89Dr~Y\xD6s\xB1\xFC\xE9\x92\xF13c\xBE\xE7g\xBE}sM.\xB4\xE7=_\xD6S\x89D"\x91̄E)1\xFD\xFEE9\xEC3\xE6|9:K\xACj9\x96\xAA\x83\xBE
\xE7K\xA2\xCDw\xBF\xE5\xD2\xC2\xCEW\xECf\xB9̉\xF9N?\x92_5%\xC9\xE2bYh5\xF9+\xF8̐\xF3vf\xC8y,\xD5yX\xAA\xCF%\x91H$sˢ\x94\x98\xD2A6\xB7H+\xE6\xE2b\xA1\xC5\xF6-\x96\xCC\xF1\xD92\xDB4 \x89D"\x91x\x91\xF3<\xB4\xBF\xD0X\xAAϻ\xD0bZ\xFB\x8B%|\xAE\x98\xEF\xF1,\xD5\xFFG\x89DrfH\x89y
\xDA_,,\xB7\xD2\xE8s\xC5r\xFB\xF9\x9C\xEFąV$h\xB1\xF4[^\xAE\xA0\xFC\xEC\xEAY\x96\xCCܸD\xCA]]\xB6WQhzu"g\xFB\xCBm!\x96.w\x9F\x8Es\xBE\xD0~-H$\x90\xF3\xBC\xB4?ߜ\xAF\xD5\$\x82\xF3\xF5\xF39W\x9F\xFBlY\xEC\xD6\xC1\xB9Z\xDA`\xBE\xE7\xB1\xAEH$\x92\xE5Ʋ\x90\x98\xE7\xEBO\xEFba\xA9>\xAF|\xAE\x85\xD9\xCEB+N4\xFB~\xA5ԓH$\x92ӳ(%\xE6lY\xAARc\xBEY\xEC\xF3\xB6X\xEA;.U\xDA<,\xB4\xF1H$\xC9\xD2fQJL\xF9\xA7bz\xE4\xFCLO\xB9\xD3\xF3\xE5\x88\h\xD6\xC4\xF9\xAE\xBF\xB8\xF8ӌJ\xCF\xCF\\xC5.\xCB\xFF\xBF\x89di\xB0(%\xE6|#\xC5K#\x8BEJ$\x89d9 %\xA6\xA4,Rj\x9C_Z\xBDR)a%\x89D2s\xA5Ĕ\xA2$\xF3\xC1\xC2K+\x99\x9B\xEBg\xDB\xCE\IX)I%\x89d9\xB3(%\xE6|#\xFF\xA4 \x96\xDB<,\xF6\xE7]hE\x88\x8Bd_\x9A̲\xCEe\xB9\xEF\x9C\xCFU=\xC82\xBBO{Oq\x9DK\xCC\xF8\xC3\xCD\xFF\x94\xE9\xE3\xE5\xE7a\x96\xC8\\xB9ʍ\xB3\xDC<,\xC4\xFA\x9D\x92eˢ\x94\x98\xB2.\xA6\xE4lXh\x9F\xEF\\xA5\xDD\xCCU1\xAF\x856?s\xC5\=\x97,O)\x91H$3aQJLɹa\xB1K\x8D\xC5^\xAAz\xA1Ϳt|K$\x89d\xE6H\x89)\x91\xE4\x90\xD2gn\x91\xF3)\x91H$˙E)1e\x8C\xD7\xDC2W\xE1Gm!Jiu\x9B\x9E\x85V\xC7q\xA1\xB5S\xEE\xE7\xAE\xE6m\xB6,\xB4
+\x89D2=\x8BRb\xCEKU:\xCC9\x89D"\x91H\xE6\x96e-1%s\x8B\x94\xAAs\x8B\x9C\xCF\xF3\x8B\\xA3\"\x91HΆE)1\xBB\xE3u\xA1!
m˓\xA5\xFA\xF3,\x91H$\x92\x85\xC0\xA2\x94\x98s\x85\xFC+Xh1p\x92Ņ\xFC\xDC"\xBCL\xC0h\x99z\x99\xE5?\xC4\xD2\xED̾^f\xB9 \xD6\xE9\xDA\xF1\x8EJ\xEC\xCF\xFE\xFB\xF0\xECgI\x99\xF9\x99\x8F\xF5\xE6\xE7\xBB\xFD\x99̳D2O,J\x89y\xBE$\xD1R\xB5\xF6I\x890=r~\xCE
+r\x9E%\x89d)\xB1(%\xA6da"3^\xE7)\xB9\xCE/2S"\x91HΆ\xF3S}C"\x91H$\x89D\xB2\x84Y\x94V\xCCE\x94\xEE\xC8f\xD9\xE8(l\xA6 \x8B\xD9K\xCDp{"@\xB5R\x96\x93\x971d\xB5\xB4²\xA65f\xF2\xAC
+@\xF3\xA9&\xA5\x8A\xAE\xAF\xB9\xF2\x8A\xE0\x85u\xFF\xA2\xFC\xA4K\xD5\xB7X\x9Ek\xB1/\xB8\xBA\xD0\xEAS.\xB4p\xB73
+R\x94H$\x92\xF9e\x97E\x81ŝ\xEC\xE8\xC8\xD8K/`x\x84\x9F\x8A['N 5\xE6F\x96\x99ʰ\xE1K%\x98\xE20\xC7\xE1Y\xCBJÉ\x9B\xD0`̰ \xA8\xB9\xFC\xF2\xE0{\xDE\xF3\xB6\xF7\xFD\xF1\xDA?\xDD\xEE_\xB3\xE6\xBC>\x8DD"\x91H$ɌX\x94s\xC1Z\x8F\xB2i\x9B\xC1\xF0\x9031
+@\xA9X\x81\x8B\xEB*\xDE\xD1\xE0T\xAD\xFC\x97\xC4\xCCh\xABa\x9D\x80\xC0@\xA6\xDA@M
+c\xD04XX\xA3[i'\xACS\x91 c
Ɔ
¡C\xAFwwW\xBF\xE7=\x97|\xF2\x93\x8D\xF37\x8Bڢ)\x91̖\xFB\xFF]"\x91H$\xD3 \xC5\xCA
\x90\xB1
\x9Ax\xFAi\xFB\xC5gҿ?\x92\xD5\xE2T`㻂\xDB\xDFO?\xF9\xE9\xEA?\xDDn\xFCl\x8EZ\xA4:\xCC\xF0\xC0g\x9AZ \xA0VZ\x8C\xB3#ܲU
\xA7\x94P
+\x800\xE60v\xF4\xD9g\x8F>\xFB\xECι?\xFB\xF2핗]~^\x9FX"\x91H$\x89d:\xC8\xFA-ۧ;\x8D\xB3\xB5p\xCE\x87s\x9E\xCA\xED\xE4\x8E\xF7\xB2$w\x8Cs\x9E\xBF\x9Esγ\x8E\xE3\xC0\xC9\xF0l&\x93\xC98\xD9L6\x9BN\x8C
=\xCBQ\xCD ٴ\xCD_z)\xFE\xF8\xBE\xD4ӽc\xCF
pN% LO\xB9\x92o\xDE\\xF3\xCF\xDF\xE4
+\x9B\x8D\xFF\xFC\xB1s$f'\xC6a$\x91\xC80\xA6\x8FXvv\xE2\xD8\xE8б\x91\x84\xA1\xAA T\xCB*\xEC\x89*`\x8E\xADif"atӦOuuU]}\xF59yJIY\xA4uM\xB0\x88b\xA3\xE7\x99\xF3Yzp\xA6\xB1\x98e\xEA>\xCEUw\xB3\xAF\x97Y2\xCBɜ}(j\xB9\xF6O\xD3oAG\xB3\xEE\x97\xCCeȬ\xB7w\xB1_\xFE?\x85\xAC\x8B\xB9\xE8YU\xBBE\xF1\xF9\xFD~?\xF1\xF9\xA1\xF8E!\xC4⢈\xB8B|\xB9m\x92;(\x84L=r\xD6\xF0i+lH\x89y&d\xD3\xF6\xC4S\xBF2
~8\xF1\xE3\x84\xB2tQt\xD0\x90ךH\xE5\x8EӋ.Z\xFB\xF0\xC3\xEC\xD2K\xE2?\xF9\x89}\x80;{\xEAd\xF2\xCDcx\xE5\xF5! a\xAC\\x8F\xE2D\x9A\xD2 \xC3 @7m\xFA\xF4\x83H[\xE6\xF9e\xE1I\x9C\xD2\xCC\xD58\xCB\xFD5\x953\x8F\x94\x98Rb\x9E)1%g\xCAb\x94\x98\x8B\xD2Q~
\xFF\xB4dl\xCB|\xE1\xF9\xB7\xBE\xBD\xDB\xF8\xC9Ol\xCBP P\xF4\xDC4\xE6\xCD \x95\x80` \x90;vl\xE0\xEB;\xD7\xFDǃ\xD57ܐ\xA0:~\xF3\xE4\xC9\xE3\xA3C\xFEa\xE8\xE7\xAAk\xB9\x92*\xFF;+\xC5XE$\x92b\xEC\xF8\xC1\x83?\xFA\xE2\xDF}\xEA\xE1\x9F\xF8Um\xFE
V"Y,<))\x91H$\x92\xD3#\xEBb\xCE\xEB\xC8ko|嫯\{ݫ\xF7\xDF?fY \xA8\x83\xC2\xD6\xC1 \xC7 \xE6\x9F\xDC9\xA1 !4\xF9+\xAD\xAF\x97F\xAA\xD7\xDEr߶\xEDȾ'~;4R-b\xDB \x82\x84 Hi$X\xFEjH1\xC6U\x95Rz\xE4\xB1Ǟ\xFD\xFE\xE6\xEFa%\x89D"\x91HΘEi\xC5,\xC7\xFCY;\xD2\x8B\xFF\xC7\xFF\xF5\xBB\x87b1
+P@\xA5p\x80\x87j+q\x91\xEE\xA8\xE6\xE4-\xA9\xBC\xD3<\x95\xCE;͓Icp8 X\xF7\xD1[6\xD9ܺ\xE3\xEFGG͠\xA6\xAD\xE0\xDC$DXBS\x9A\xADC#\x96\xC55\x8D\xB8q\x99\x9C_yHض\xA6\xAA\x8C\xB1\xFD\xDF\xFE\xF6\xE6\x8F|\xA4\xE2\xC2\xE7\xE9\xA9/\xBE\xF8b2\x99|\xF5\xD5W݃\xBD\xBD\xBD \xDA\xDB\xDB\xFF\xFC\xCF\xFF|\xFE\xBA\x96V4A\xB9y\x90\xF3#\x91H$\x92b\x96\x94Ĝ'\xEC\x97_z\xF9\xAE\x8E\xB7~\xFC\xDF\xA0\xE2\x85\xCD
+\xCA`SG\xB5s\xC6`[\x87We9\xA79\x80T \xC14{\xDD=u\xC9-U]W\xFF\xEB\xDBn>x\x84\xE8Ber\xAE#`}\xC95
+ \xB1,\x9DR\xB0)\xA1\x9A\x94R\xE3СW}t\xF3\xDF\xFE\xED|>\xFDB\xE1\x8B_\xFCb___\xC9SMMM\xF3*1%\x89D"\x91\xCC\xE9(\x9F\x8E\xB4Ŏ~o\xF7S\xD7}\xF0u\xAF\xBEX\xFE
+\xA3Pl\xD5\x90\xE2 `듷\xBB\xAE\xF3T:\x97cn\xC6
+o\xFB\xD5\xEF}o\xD3\xFD\xF7_\xD2\xDC\xC0$$hY&!&! tι\xA6\xE9\x9C\xE0\x9A\x968\xA5\x86\xAA\xA6)\xE5\xAAj+
+\xA1\x94Sz\xB8\xAFO\xB1\xED\xF9\x9D\x85\x85\xC1=\xF7ܳ{\xF7\xEE\x9D;w\xD6\xD5՝\xEF\xB1H$\x89D"9
+ҊY\xFB\xE8\xD1W\xBE\xF1\x8D\xA3]]\xC2v\xA8\xD2\^w\xFE_\x80A\xA5p((潅ŶL \xA9 T\xE9\xB4\xE0x\xE8\xE2\x8B\xDF{\xEF?\xBF\xBAi\xE3\xB3_\xBF\x9A\xA6s\xCEl\x9B\xAA*\xB3mh\x9Aؚ\xB0 `\xF3\x80n\xDB\xAA
+`\xDCq*%\xC9\xD8`\xBF\xC1X\x95\xAA\xCE\xFC\xB9\xBE\xFB\xDD\xEF\xDEw\xDF}\xB3\x9B`\xE3ƍ555MMM\xEF\xFF\xFBg{y\xF3\xE6͛7\xF8\xDA\xF6\x81|\xA0\x9CES2s\xA4\x83["\x91H$\xA5\xE1\xB9\xE8\xEDw?\xFE8 \x95Ba\xB9\x92\x94\x82\xB1ɭ
+P\x876R<\xA72)\xC0t \x85B3\x98\xAB\xAA`\x99).\x82,S&l;\xAD(>\xDDVP\x9F\xF9\xD7o\x9E\x8A\x9BAM\x83(?aY\xB9-綦9\x96e\xAA*\xB1m\x8B\xD2
+\xC6\xC6U5Di<
g/\xBCP\xD5\xD44\xF3G
<}&nٵkW8
\xBE馛n\xBF\xFD\xF6\x8B/\xBEx\xB6\x8D\xCC
۶m;_\xBDK$\x8B^\xC6s5\xCBbF忟\x94>>\xDB\xE2>\xE5\xAE.\xDBk\xD1B\xED\xA7+\xE23[\xDEB,\xFA\xE3>
\xE7\~c\x94,@\x96\x94Ĝ\xAB\xFFc\xC9'\x9E\xF8\xF5g>\xF5\xE6k!W_\xE6\xB7\xF0\xA8L\xA3\xA0l\xF2\xF7U\x8AO\xF9-\xE8\x98Pt0?
\xA0\xEA\x92K X\xAF\xBĊ\x87\x98,\x80\x8F\xC4I at Y\xB7\xE1\xED[?\xF9\xB9\xA7~\xF0\x9D\xD1Q\x84\xE8\xAA:iΤ\x8Aì4\xA5:c\xA6\xAArƄ-\xD3QU\x9Fi\xBEz\xE8\xD0\xDA\xD9譝;w\xB6\xB4\xB4\xF4\xF7\xF7?\xF2\xC8#]]]g\xEF\xBD\xF7ކ\x86\xEF\x91\xDE\xDE{\xF7F\xA3Q\xF16\x91Htuu=\xF0\xC0w\xDF}\xF7\xA7?\xFD\xE9\x99\xF7;\x87lݺ\xB5\xE0Hɏ~\xF6\xA5\xF2$\x89D"\x91\xCC
+KJb\xCE \x89\x9E\x9E'>\xC4J
+`R_
+e W_\xB2\xBC˜
+\x95\xE9 `&\x82\xFA\xA49Sx̅\xCA@*T߆K\xD8\xE0\xE0ģ\x8Fò \xF0\xACmgl\xEA()6n>\xF7\xFC\x8A\xFAK\xAF\xF9\xF0\xF5/>\xFA\xB3\xB7N&\\x95\xE9
\x88mJ\xE18\x8Am)
w
gxx\xB6\xCFXWWWWW\xB7cǎ\xED۷_\xFD\xF5\xDES
+
+
+n\xEB֭;w\xEEܳgOKKK"\x91\xAB3\x9FH$\xDA\xDA\xDA \x9C/\x95)\x91H$\x89d!#%\xE6\x86\xEF\xFBA\xEF\xC7?\x95
+\xF4\xA5C\x8Fܫ/=*~EIqG\x941\xF2kN\x8A\xCCU\xD4ڋ\xAD\x9E\xED\xB1\xA2j2(Ӵ,c \xDE:vl\xE544nV_>x|h\xC4$\x9A\x80ER\xCF\xDF%\xF4e\xA5\xA2\x9C0\xA6\xA4͊
;v\xCC\xFC\xCA}\xFB\xF6mٲ\xC5{\xB0\xAD\xADmÆ
+\xC56E\x89D"\x91H$˜E)1e^\xE1\x8F\xFC\xEF\xEF<\xFB\xF9/$\x81\x90\x9B\xF9\xF2\xFBe\x81\xCAT\xF3\x8C \xD8\xEAd\xA3\x8C\xA5\xA8 4\xF9\xD4r\xF5\xBAkhm\xED\xE0\xD7\xF1dMQYfH\x9Bܯؾ\x94\x93
V\xBC\xADv\xB5>6\x9B\x98(\xE1\x84㨀\xAD( 8cPU\xCE\xE6\xDA#\\xAE\xB5͛7\xEFܹs]ރ\x9D\x9D\x9D\xE7+\xC8ˬf`\xBE\x83\x96dP\x94D"\x91H$\x8BRb\xCE\xFFrﳷ~Q\xD8/\xA6\x81Z9&+\xCA\xF2\xF1\xAAL;\xAF2\x85!s\x9C:"H\xB5[u`)nI\xF6\xC8\xF5׳C\x87\xC8\xCF~\xA6v\xCA\xF1Y\x96\x92
W|\x95>\xD3\xE4\x87a\xA5\xCD1\x8C\xAAIu\xED\xAAp84::ʹʘM\xA9\xC3\xA1\x943\xA6+ \x8BҊ\xB11 +\xC6\xC7\xCF\xD9,\xB5\xB4\xB4H\xCC={\xF6\x9C\xB3\xDE%\x89D"\x91,\xA4\xC4\x80\xDF\xFF˽\xFDy}i\x8B\xCADy}\x89i\xF5\xA5\xAB2\xC5>\xA3P\x91\xCB
+\xCA8\x8E\xD8\xFA\x811`\xC5\xE5\x97W\\xF3\xFE\xA1oݣ\xC4\xDE2/\\xC7ù\xC5t<\x93\xE6\%\xCCq\x80\xDC\x92J\x8D!5\xA6k\xFA\xFA\xB0F\x86\x8DA\x88R\x9C6\xCB܂?\x8C!_>in\xCDfӴ&\x828\xBC\xF5\xAB_\x9Dw_\xB94
J$\x89D\xB2\xA0\x90G\xFE\xF7w\x84\xBE\xCC\xF9\xC7=\xF6K\x87"\xC8N\xA3/\xB66e`\x9ETtf\xC0\x9AO\xFD
+\x80\x89\x87a at P%f\xDAr\x9A" \xAC \xD04g\x80g\xFC<\x93\xB4( \
\xD1`XK\x8D\\xF4\xA9VU\x9D\x9B\x89\xD4\xD7\xD7H\xCCE\x87ԣ\x89D"\x91\xCC7\xCB]b\xDF\xF77\xFE\xB2\x85y+\xADO\xE2]\xE9\xA7\x80\xC2F\xEE"
+h\xABVU\xDF\xF8\x97\xF1\xA7\x9FaO?
+\xC0H\x99 L'\xFE\xCF$\xAA;\xCC`8
+\xD2P\xC7v@Q㦭)\xAA\x85uU:\xC6Lw\xE9Ʉ\xB7wJW\xAD\x97\xAB\xDDH$\x92\xA9̲\xCEe\xB9hf\xCE\xE7\xAA
d\xE9v\xA6\xFF\xB6W\\xE73\xFE~\x98\xFF&Yn\x{253D77C7}Yƻ\x93\xB9\x8A\x8F/7\xCEr\xF3\xB0\xEBwJ\x96-\xCBZb\x8E\xFDlϓ\x9F\xFE\xC2\xF8T}\xE95a*E\xE2\xD2K9\xA1\x99ӥ\xF9ڙX\xFF\x89\x8F\xD3\xFAz\xE3\x9F\xFEi\xA8\x8Ah`\xA6\xED(\xAA˞ 'n*\x9A\xE2X\x8E\xA2\xC1\xB1
\x80\x98\xE0\xDA\xB1`\x83\xD01\xAC\xA1 \xC3\xC1\xA2N5U
+V\x85\xCF~*f\xCExQ\xE8gA
\xCDr\x88\xE2\xED3q\xA9\xC4b\xB1P(t\xD5UW\xCDvx===\xBD\xBD\xBD\x86a ظq\xE3\xF6\xED\xDBg\x9E8/\x91H$\x89dNX\xBE3}v\xDF\xC7[\xC6M\xB3\xA4\xFD\xF2̘\xD4,\xB7e\xC0\x9A.X\xF7\xB9\xFF3y\xF4\xE8\x9BO>\xC0v \x8Em2\xAE )i6@\x80\xB1\xFC\xFD\xA0\x96\xB8\x9D@\xD6xa\xAA\xCA\\xAB(Z\xFD\xFAs\x8B \xC0\xAD\xC1.\xA8\xAB\xAB\x8BD"ŗ555!/+\xBD<\xF9\xE4\x93MS\xD7"jkk;|\xF8p\xBF[t\xD3e\xE6\x96BH,kii)豯\xAF\xAF\xAB\xAB+
\xDF}\xF7ݭ\xAD\xADŃ\x9C~\xA1\xA3\xE2\xD1N39\xB2һD"\x91H$.\xF3R\xFDg\xE1c\xBE\xFE\xEAs\x9F\xFF\xEC\x91D"4\xD5X`\xC2tJ%\xFAlQ\\xD2\xC8\x9F \xE0\x92\xCF|\x86\xD6ן\x8A
Hz\x95\xCC6\x99m\xDA6\xB1l۲\xC0 &\xB2w\xC0XN\x98\xBA\xFA\xD2\xDD@\xB8
+C\xDC \xA1j\xBD\xEA\xE2\xCEټ\xF5\xF4\xF4
iii)w\xF1\x97\xA9\xAC\xA9\xA9)\xB6\x8CΖ\xAE\xAE\xAE\x86\x86\x86r=\x8AB\xF1\xCD\xCD\xCD\xC6\xD4\xA2\xCD\xCD\xCDuu\xA5\xC3Di\xFA\xFA\xFA\xFA\x82\xE3;w\xEElll,8\x87\x8B\xF5\xABD"\x91H$˙E)1\xC9YbYO\xFF?\xFF\xF8\xC6s\xFD\xB5B_y\xBB\xBD*sz}Yz \xAF/nl\xAC\xFE\xE4'\xBFy2\xA7n\xBCj\xD2#K╪4\xAF2\xDF\xBC
TЈ\xE2\x9F;3\xEC\xE9\xE8\xEC\xEC\xF4\xBE
+\x87\xC3\xED\xED\xED%\xAF\xEC\xED\xED\xE5\x9C\xDF{ァm\xB3\xA3\xA3\xE3\xC0\x81\x86a\xEC\xFB\xCCF\xB5w\xEF\xB6\xB6H$\xB2{\xF7\xEE#G\x8Ep\xCE9\xE7
عsg8<\xF9
bϞ=\xFC\xE0\xBD7\xB6\xB7\xB7\xC7b\xB1\x87~\xD8{\x80\xD6\xD6\xD6X,\xD6\xD3\xD3S,1\xC5h\xBD\xB7\xECر#\x8B\x9D\xF1\xE0%\x89D"Y\x92,J\x89y\x96\xC4\xFE\xFD\xAFwwH\xB9b\x90B%PI\x89\xF8\xCBT\x99\xA2E\xD3l\x9D\xBCf\xA5\xC0\x85
\xB7\xD3\xDAZ68xr\xFF\xAFˍ\xA7dn\xBA8^\xBCc x;\xB0\x8A\xAABU\xE7v~\xCA\xD1\xD9\xD9\xE95\x86\xC3\xE1}\xFB\xF6\x95\x{112EF4}\xB7\xB7\xB7\xB6\xB6\xB8r\xB4\xB6\xB6\x9EY\xF1\xA3h4*Dakk\xAB+
+;::\xF6\xED\xDB\xE7\xED=\x8D\x8Au/\xBD477Xg\x8F?>}\x8F\xCD\xCD\xCD"u\xEB֭===\xD3O\x82D"\x91H$ːe'1S\xAF
~\xE1\xEFo\xE0Ӑ\xB5\xF2* `k
+
\xE5J\xA9\xA2E嶩|S.\xFF\xDC\xE7"\xD7n`<\xFBl\xF2\xB9~Z\xA4 K\xD6>B\xDE-.\xB6\xEE\xEBp8
^ \xAC\x82\xABW#\xA8\x9F\x83y\xEB\xEC\xEC\xBC\xF5\xD6[ݷuuu\xFB\xF6\xED+vs\xF3\xCD7Y\x96\xA3 \xF0q\x86\xB4\xB6\xB6\x963"666\xA8̮\xAE\xAE\xDE\xDE\xDE\xE2~\xBDϲgϞX,6}\xA7\xFD\xFD\xFD :::\xCE`\xC0\x89D"\x91,y\x96\x97\xC4dF\xFC\xF9\xAF\xED<\x92H \xC8Z \xB4&u\xA1j\x95V\x99tƶL\x9B\xA1\xA6\xBE\xBE\xFE+_\xD1\xF4\xA0e\xA6\x86\xF3\x84\xAB
\xE1ю\xF0H\xC9y)^I\xE0
+`0\xFFz
H#\xC0`\xE6_!@Y\xBDr\x9A\xF2IsBOOOSS\x93\xAB/\xC3\xE1\xF0Ν;\xFB\xFB\xFBg\xA2/\xCF
+555Ӝmll,\xF0\xE6\x97ԅ\xC1\x94\xDD\xDD\xDDӴ\xD9\xD5ՕH$\xCFLK$\x89D\xB2\xE4Y^\xE5\xC6\xE3\x8F
\xBE\xFF\xEF\x91$\xB2\xA0\x92\x9C\xB8Ts+\xE7LQ\x99)\x9A/\x90Y\x84P\x9FA \x95W\xEBN~I\xC9w\xF7[\xB4\xB6V\v\xEA\xD4x\xD2\xD3#J\xED\x97$\x94\xBFF\xCFoM@\xCFe\xA8\x85\xA9\x9E\xC1\xA3ϔ\xBF\x{3EFFAEC}\xACt\xDFz=㍍\x8D\xFF\xF8\xC7[ZZ\x9D_\xB8\xBD\xBD\xBD\xB3\xB3\xD35\xA6\xF6\xF5\xF5\xC5b\xB1\x828ˏ}\xECc\xB7\xDDv\x9B{Mww\xF74\xCA\xFB\xEE\xBBE\xAAT"Y@\xF02惢z\x99\xAF\xFC\xEE\x95y\x8CD236l\x9C\xCC^}\xF5\xF0[\xE7q$\xF3\x8D\xF7I\x970\xCBHb\xB2X\xEC\xF9\xAF\xFD\xC31\xE0"\xCFA\x9FX\xB0E\xD2M l-'4\x8BSˋ\xCC\xC5\xF2?\xA9\xFC5 at n\xFDɫ\xBErg\xF0\xDA?]hz\xF0\x82-\x8D\xAFOk+I\xA8\xCCq\xD0\xF2g}\xA19\xC4,\xA8I\xE4\x87w\xEFp,\x97\xB3"\x89\xDCt\xD3M]]]\x9E\x9E\xD3f\xC15\xA2\xBEfsssqk\xB1X\xAC\xAF\xAFOf\x91K\x96\xEFxnjJ\xDBJ$\xF3\xCA\xEF~\xD7_pd\xE5\xBC{\xE9\xCE\xA7NM[s{ \xB1\x8C
\xE5o\xFC[\xF7K\x87Mc\x8E\xF2H\xDE]\x8E"\x95\x9C\xAA5\xBD6N\xA1/\x86$\xF0Λo\xAE\xF9\xC2\xE7\xBD-\xAFm\xD8\\x91\xB7\xFC\x85\xF2개\x82,\xC0{\x99Yt\x9C\xE7\xB8\xEEzkk\xEB\xCE<\xDEFQ\xF7\xA7\xA0\xE8\xCF"\xA2@
\x87c\xB8\xFD\xF6۽o\xD2\xE7]\xBE\xF1\x8Do (\x97J/\x91H$\x89\xCBNJi\xBC\xF8\xC2\xF3\xDF\xF9 \xBB\xA0\x85\x94\x86\xA0 6\x83
+ZNk\xDB2S
\xAD\xE9U\x96.'\x80\xC6\xC6Ƌ\xFF\xF1i\xA4\xDA2S \xB8eM\xF3_tQզMCO=\xB5ڭg)|\xF4E\xDB\xBCG̼\xA3
y\xBF9 \xAA,\xBC\xE7\xEC\xB8\xF9\xE6\x9B\xDD\xF8¦\xA6\xA6m۶\xB9\xA7\xA2\xD1藾\xF4\xA5EZ\x9DgÆ
+o\xBE\xF9f\xF15\xF5\xF5\xF5[\xB7nucJ\xFA\xD3<\xF0\xC0\x98\xB6 \xA8D"\x91H$\x92\xE5b\xC5\xFCm\xF7_;neV
+\xA0\xE5"-m\x9A\x98ԗv\x99\x8A\x93^\xB7\x9A6\xC3)\x86
+\xF5\xF5\x97u7t\xF1\xC5̈\xB37\xDEȼ\xFE\xAA\xFD\xDA\xE1\xD4/ߪ\xAA\xBB\xA8\xE0\xC6P\xD1E
+\xB8\xE0\xADYt<\xBCru\xD9g>k\x9A\x9A\x9Av\xEE\xDC\xE9=\xD2\xD5\xD5\xE5u7/"
+\xF2r\xCA\xC5\xDCr\xCB-\xC2`\xE9E$\xFA\x94\xAC\xCA.Y
8\xE5_\xF3?
\xF3ڻD"\x91\x9C\xCBBb\x8E
x湇r\xB1\xD8^\x98`a4\xAF&&\xF5\xA50gzM\x95S\x8Ai\xB9\xAD͑j#\x91\xAB\xE2
+\xA9\xD7[O=\xCD_\xFD\xC3\xF8\xCB\xCDW\xDF \x87\xB3\xA1\xE15A\xD1BAh\x89w$ņL\xF7\xAD\xD7E\xAE{$f\x96\xCEo\xA8JGGGA\xAD\xCA\xDBn\xBB\xAD\x9C>[\xB4\xB6\xB6z\xD7\xFBy\xE0\x81
+bD\xA2\x8F\xF4\x92K$\xC9B!\x9B
x\xE3\xD8ЩdȦ\xD3\xD9\xF9\xEB+=\xD8\xD3\xF5\xFD\xAE\xDC\xDF\xF5\xED\xEF\xFF\xFB\xFEc\xF3\xD7\xCF\xD2`Y8ʏ\xFC\xF7^\xF3\xD8 \xF2\xAE@ƹՋ4\xBF\h\xA6\xA1Mf\x9A\xBB\xCE\xF1\xDC*\xE2 $-\xD4F"\xEF\xE8!z\xF5\x8D
xf\xE2\xB9(\x90o%e\x9A at ptTW\xF5\x90X\x85k\xF9\xB8^r\xEF[AI}\x89\xA9\xA6ME\x9F\xF7\xA2\x98b\x917\xD5Ze>\xFE\xF8\xE3\x8B.\xAF|\x86\xB4\xB4\xB4\xECڵK\xEC'\x89|\xD0M\xEB\x89F\xA3}}}uuu\xB2V\x91D"\x91,N
\xFA\xCD=q8
+T\xAD\xA8
\x8D \xF4ퟺ\xF9\x92y2\xBFj\xFF\xF4\xC6\xF7=\xFC\xE3\x{6301E65F}.\x96Kߊ\xC9b\xB17\xFF{\xAF\xE8\xE5\x8B\xA5<q\xAFT\xAD\xC9\xD0LWY*,\x976\xCE X\x80\x85\xDA\xDA5\xD7<tյ\xD7&\xF6\xF6\x8C>\xF8 \xF3(\x86\x86\xF9\xC9k\xF8Mk\xEC\x9454\x948\xA2)\xAD\S\\xB1\xC8\xDD&\xA7\xCA\xDFr\xFA\xD2k\xC2\xE4\xBAN\xC3\xF3\xAE\xF3"\x91H\xC1\xE27"(S\x9B.=
+\x82,\xBD\x81b_\x9A0%\x89d!\x90=\xF5ʏ\x9F8\x9C\x86\xFF\xEA\xBF\xF8뿾\xF9\xFA\xCF\xA6yS \xBFo>;\xA5+\xEB\xEB\xAA泃%\xC4җ\x98Ƌ/\xB2\xC3/\x85 J\x89{\xB0\xC0%\x9D\xB5\xF2\xF2N\x9B|\xD9
6ؤ\xC7\xDC\xE6\x80\xE6\xB9& \x84j\xD7\xFC\xF1\x83V\\xF3\xFE\xA1\xEFo\xF4\x81\x9DT\x8A$\xC7\xCD\xF8\x88u\xE2\x8F'pr\xA6aMJj\xA2R
+\xBA=\x96\xCB\xEFqϖ\xC3k\xC2\xD4j"\xB4\xFA\\x98\x9B\x9A\x9A
+
+\xF4tuu=\xF2\xD8/\xCEA\xD7sE\x81\xBF{\x9A\x95*\xEB\xEB\xEBw\xEC\xD8ᾍF\xA3"0 \x8Buuu\x85\xC3a\x99\xE8#\x91H$\x81t\xAE\xE4t T ߊ\xF7_w%\x90\x99\xE2(\xCF:\xE9t\xFA\xAC\xBBrғ\xFEw7\xF0ZHY';\x8F\x8E\xF9\xC5\xCDw\x94[f*\xBE\xBF\xBA*\xAC\x8D\x92t\x80\xA5\xBC\xB6\xC3B \xAC)G(\xC04\x80\xC1ί\xF9\xE8z\xCCm\x86$p\xE1\xDB\xEA\xFE\xA8\xFBG\xF4\x8AM\xA3\xF7\xFCs\xEA\xE9^\xDFڵ$5nIJ (\x8C9\x94*\x8C`@\xB5\xAE#/.g\xA8/\xA71aP\xB5\x88\xAA\x98\xC14\xCC\xBBw\xEFvŖ\xA0\xA5\xA5\xA5\xBF\xBF\xB1d\xBD\x88\xF5
]6n\xDC8\xCD\xC5---{\xF6\xECq\xDFvuu\xED[\xAC\xF7s\xD3M7-\xD5\x89D"Y\x9C\x98\xBF\xBC\xFF\xD9my[͊\xC0\x9Awn\xAA\xCAa'\x9E\xEA\xFD\xF5\x8B\xAF\xC7 \xDA\xF4\x9E\xF7n{W-\x80So\xBC\xB4\xFF7\xDF3\xC5\xF1w\xBE\xAF\xE9}\x97G^z\xF4у\xE3\x809\xCE\xFCk\xAF\xB80\xD3\xFF\xF2\x9B\xE9`\xFD
+\xFF@
+\xD1_\xFF&zp8
+ z\xDD\xE6w_wͅ\xB9\xF6\xB3\xF1\xDF\xED\xEF\xEF{y\xC0\x8A\x8D\xEF\xB9\xFE\x83W,\xCD2\x9Eg\xC1\xB7b\xF2\xB8\xC1^}U\xD3u\xB5B[U\xA1T\xD82ͩ"\xCF'B*\xA7y\xFEŦf\x94\xE7l\x99l\x86A\xE0·\xD5m}\xB8G\xBFb\xD3\xF0W\xBE:\xF6\x93\x9F(\x91\xB7,\x92Hd\x8Fw\xC31\x8Cc\xE9\xE1!ˈ[F\x9C'J\xA9+\xA7ї\xEE5f\xD1\xD9کoUͪ\xE7b\x81r\xC1\xEEݻ*e~\xF4\xA3=g\xBD\x9F%s\xFB\xF6\xED\xD3\\xDC\xDC\xDC\\x9C\xF4#\xCAd\xCAr\xEB\x89D\xB2@\x84#\xB1\x97z\xF3\x89==]\xFF\xEF\xBFݿ\xF7@݇?| ҃}\xEF\xA7/\xBE
ߴ\xFD/?\xFF\xD7\xD7\xD2Ƀ\xBF~t\xEF\xA1Dz\xE8\xF9?}k\xCC\xDC\xF8?\xFF\xAA\xE5C\x97"\x9D|\xF9\x89\xC7X`\xD3\xD5W\x8E\x9F
3S\xA3\xB1\xE7_~3
+ \xFB\xFD\x9B\xC7\xF6v\xFD\xD73\x87\xF5Mh\xB9\xA10^\xEC{q$g
;\xFC\xECo\xADu\x9B/
+=\xFC\xEC\xF3oZ\xE5ƹlY\xE2\x93
v\x86\x87W\x83\x95jAu\x85\xA6iT\xAE\xC0Q\xEE\xAA\xCCܪ\xE5\xF9m\xEE\x95 \x9B@\x8Aax\x9A
y\xCC\xE9\x86\xE1\xFF\xEBξ\xBD\xFE\x9A\x8EaA\x99ef&adFfh\x94\xC7M唡\x9C22'\xE3\xA6\xA7\xB3_\xBAg\xC4㚢+\x9D\x8A\x8A\x80\xFF\xDC١\xD6T\x8CF\xA3mmm\xE7l g\x83\xB7\xD6z]]]\xC9e{\xBCx\xBD\xE1\x89D\xA2\xB9\xB9Y,J\xBEH\xD77\x92H$\x92\xA5\x87/r\xD9'nxϊ\x80{ 3:p\xF8\x91\xFFh\xFF at j\xE8\xF9g\x8F \xB2ɡ7\x8E\xE6\xA5ߊV\xD5o\xBA`\xF5\x8A^\xA0\xB3\x93\xC6 \xE1\xCE
+D\xEA\xAF\xDE\x80\xAA+?\xD5\xFAg\x80\xC0\xBA\xF0\xD1 \xA0oyw}\x85\xAE \xA2\xB9P\xCF\xE0\xC6\xDC\xFC\xC1\xAB\xAE\xB9\xF6j\x99\x99\x91\xFE\xF2"\x96\xB8\xA3\x9C
+
+SU\xCDTU\x89e\xBC\xC7=EL\xEA\xACa\xCC\xD5sBq
+\x95)\x822\x91ߊ\xAA\xEC"(\x98 \xC2H& \xE0\xBD\xDD\xDE\xF0O\xDFA$<\xFC\xF1\x8F\x91_\xFE*\xF3?\xAE\xE4 )\x80\xCF\xC9}\x8F\xF1\x8DMZ!a\xD4Q2ᰮ\x92\xF2\xF2L\x93H.\xF6+"ϝ@{{{OO\x8Fw\xE1\xED۷O\xA3\xD8
+<\xE9\xFD\xFD\xFDӤc
+
+\xCD\xC1(\x8B0\xC3\xEB\xF8\xFE\xF2\x97\xBF|\xDA[\xBCy\xE5ȯ\xD5.M\x98\x89D\xB2p\x8A\xF6
+^\xF4\xBE\x9B[\xAF`c'\x8E\xFE\xE1\xF5h\xF4\xE0h ^\xFB\xC3\xC8\xFA\x9C\xD2\xCF\xC6'5\xB5\xF1\x8F߃L&\xB8v%\xA1+6]0=\xFC\xC4\xFEW00\xB59a\xB2\xC9dX\xDB\xDC\xFAI o\xEEX\x9C\xFA\x80\x8A+>\xF1\xF9˳P|\xB0\x9EG}9\xAD\xB9ą\xD4Y\xB0ĭ\x98H\xA4\xAA"p\xF1\x99`0\xA4\xF9*\xD5`8\xA8\xEA\x94V\xEAz\xB1\xCF:\xEB1r\xA3\xA6P\x9C\xE2xH&\xDE\xFD\xC5/4\xFC?p\xF4\xC6\xFF\x89G\x96\xBE\xE8"e\xD8PGU\xC3P
+\xC37f\xA6\x93q_"\xC1s_ \x98\xE2(l\x9CKs/.\xA5T8FF\xB3 IDAT\xA0/\xD7\xE4jz/\xF3\x85C4R=\xEB99;\xBA\xBB\xBB\xBD\xEEr ---\xD3T\xCA,\x90\x98\xC9\xE9^θ\xAE{\xF7\xE9\xD6\xF7.\xD9\xD8\xD88\xA5X\x90\xF4
\xECc;\x83\xE1I$\x89d>Ȏ
+>ӳ\xA0U\xAB74^}sks\x9DǢ)\xB6k6]\xF5\xEEw_\xD5\xF8\xAE+\xAF\xAC\xA9\xF4\x9Dz\xE9\xE7\xFF\xF9\xCB\xFE\x81\xD1\xF4\xFF\xF5'?qc \xC0\x9F\xCB\xDB\xF1\xE5\xDEy\x8D$\xDF8.\xF4\x81\xE2\x9B81d䓇\xA6JKWqJ\\x96\xBA\xC4xe\xAF\xACR֭Ce\xC4U\x99\ӊUf\x81\xEB\xDCŵnV\xEA\xFA\xE6o\xFD\xAF\x86o\xFE/v\xE4\xC8\xC0
+7d\xF7?嬹\xC0\x97J\xA4Y
\xDC.\x94 \x98\xE3\x9B3\xC7a\x8Ec\xA6M+\x9D\xE6\xFFi\x97&/\xC1\xF2\xAC<\xE9R:\xDBʋ\xA5aA\xCCb1\xF5\xF5\xF5\xEE\xF2D"q\xED\xB5ז\\xF5[\xE0\xD5j}}}%udWWW[[[\x81x\x9D\xA1\xE2
(\xB7\x9E8\x80h4\xEA\x9E
+\x87\xC3=\xF4\xD0L\xDADQ\xF5"\x99\xE8#\x91H$?E\xFA\xF5\xE8y\xA1\xFA\xB2F<\x99\x80\xFAKV\xD6\y\xA5P\x9B\xCF\xFF\xF7/\x8D$\xD9؉\xA7
\xEA\xFE\xD1Oo\x8C
+\xE7x\xC0:9\xF8\xD2\xF3\xAF \x92Ǐ\xA7\x80\xF4\xF1\xC1$ d,\xD7\xD7Xs\xE5&\xD1\xC8\xC1\xC7~qh$96\xF2\xFA\xFD\xDD?}\xF6\x95\x80L\x82e\xD8Y\xA1CO\x9D;\x8F\xBC\xA8\xF0U}\x9A\xD3d\x9A\xB33\xA6xq3\x9Eo\xF2\xE1\x85g\xC5>\xE7
\xDCw
\xC7\xE1\xDC\xE1\xDC\xF9ʗ\xBE8Î\xC7c\xC7\xCC\xE3G\xBF\xAA(\xBE q2h\x8E
+\xF8\xC5a\x9Ch\x84\x90L\xC6 \x88\xAD$\x81K\xE3X6\xF0\xAEw7\xBC\xFFG?\xBE\xE8Ə\x8E\xED\xDBw\xEC\xAF>\xAE\xBF\x81uk2\x84g\x90!\x9C9N\x86\xF3\xE7ۗ橌\x93ϦI<k\xD9٬\x96\xCE\xC51ƙ=\xB5}\xE1\xACw\x8ATf5%%^\xC5 W66\xD6~\xE4#3\x9C\x8AbD$e\x81o\xFA\x99g\x9EY\xB1b\xC5\xF4\x87W_}uoo\xEF\xC0\xC0\x80{IJ\xAC\xFE\xF0\x87CCCW^ye\xB1[\xB7n\xDD\xF8C\xF7\xED{444PJ
+\xC3x\xF4\xD1G?\xF3\x99\xCF|\xEB[\xDFjmm\xFDЇ>\xE4\xF5\xC2\xEF߿Ŋ\x97^z)-Z\xC4\xC8\xEB\xC5\xF0\xD8c\x8F\xD5\xD6\xD6;\x8D\xDEx\xE3\x8DǏ\x87\xF7\xED۷iӦi
\xCD\xCBe\x97]\xD6\xDD\xDD\xED֜衇\xA4Ĕ\x94\xFAm\xB6\xA8 \x85\xE3?1rb͚u\xE7e,\x89\x97\x91\x91ᕫ&N\x9E:\x95O\xE3\x82
;\xFA\xFB\xC3I\xBD\xCA8}\xB1\xFF\x95\xDF>\xF7\xC2\xFA\xA6l߶\xA1Z\xA1\xAB.\xABU\x8E\xBE1dZcG
|\xF1\xE5W\xC7V5\xFE\xE5_l^U\x91y\xF9\xE0\x90\x83\xCC\xE0k\xAF\x8DW\xAD $\xC6,8\x83\x87w\xF4\x9F\xCA @:\xFE\xDB\xE7c\xB5\\xCA\x85\xAEy\xFBZ
{u\xD8rRG
|\xF9\xE0\xC0\x9A\xAB?\xB0\xEAоߎ@:q\xF4\xD8D\xE6\x8D\xDF<+\xF2\x92G_\xB5j7\xD5U\x9D\xDEmn\x9A\xEF\x93ΐ\xBB\xEF\xE9"\x8A\xA2(
+Q\x85B\x88R!P! @r\xE7\x81\xDC)`\xEA\x91y\x86\xAC\xDF2]j\xED\xD9KL\xCE9\xE0L\xAE\xA2\x9B\xDB\xC9
!\xEE1d\x89\xE3.\xB7\x9B\xBF\x9Esγ\x8E\xE3\xC0\xC9\xF0l&\x93\xC98\xD9L6\x9B\x9E
\x9Ca\xEF\xC3O<\x91z\xE2\x97V\xCA"\x96\x95\x8D\xC7\xC9\xE8 \xDFȩ\xF1\xD4X\xD2ʎ\xDB){\xC2%i\xC7H\x8D\xE5ָ)A&\xB0\x8E\xD2\xF7~\xF6\xB3\xEB\xBFv\x8DT?|\xE4ӟг&_\xB1\x929 \x9E\xB5\x88O\xE3Y\x8B\xA7'w\xDBS\xE7\xCDa\xA6Bu\x87\x99A}c"q*\xFF\xA9\xB8:f\xB1 S\xD7A9 0\xBE81Պ\xB9鎯\xBC\xEB\xFF\xFE\x87N\x85\x8B\xF0G\x9Fv\xC8p8\xDC\xD0\xD0p\xCF=\x{1D451B}\xB1Xl\xFD\xFA\xF5\xD3\xDCX`\xD4lkk\x9B\xC6$\x87\xEF\xBE\xFB\xEE\xD6\xD6֎\x8E\x8E\xED(غu\xAB\xB7A\xC30\xAA\xAB\xABݾ\U\xBAcǎ\xF6\xF6v\xEB\x8Bź\xBB\xBB;;;\x85Flllܽ{\xF7l\x93u\xDC\xF1@")b~\xD7(/\xC7ٯN\xFE\xCA+\xBF}\xC7;\xE6d0\xC9\xD9\xF0\xBB\xDF\xF5o\xD8x\x81\xFB\xF6\xD5\xC3o\xAD\9\xC3*@\xCE\xC4X2\xED \x84"\xC1w5\x9BH\xB2,\xA8^Ay\xB7m\xD62\x92, at CTA\xD6\x9B\xB0U\xEF\xD9R\x{DCF1} _EE00\xCE\xF0S\xA7\x98\xF7IgȪ\xDA-\x8A\xCF\xEF\xF7\xFB\x89\xCFů(
+!>\x8F\xC4\xA2\x93p\x85\xF8\x84|\xE4\x93S)\x92\x98ʜHL>\xED\xB7\xEE%
\xA5\xAA\xAF]\xC3V\xAD\xD6N\x9E at P\xB3\x81,\x90\xF2kV\xAA\x95\x80TP_q\xC20#\x91\xD3\xB2&Uf(/.u\xE0]\xD7\\xF3\xFE\xAF|%\xFC\xE1\xFA\xFE\xF7?\xF5\xB7\x8As\xEDZ\x9EΩA+
+\xA4\x85[\xBDPVz߲\x94\xA5*He\x99
+\xB0\xA4G\xC5N7~
\x94Fx `\x9E[V\x8B\xB7\xEBj\xCE`Ng\xB2\xC8x"\x91\xE8\xEB\xEBK&K\xB0\xBE\xBE~\xE7Ν%堸\xB1\xE0\xE0]w݅2\x8E\xEF\xD6\xD6\xD6\xDBo\xBF]\x84l
+3\xA1\x8E\xE2l$ihh\xA8\xAD\x9DR\xAF\xC9\xF5\xE6wtt\xB4\xB7\xB7\xF7\xF6\xF6vvv\xEE\xC9S\xD0~8
nooooo?\xA4\x9B\xF4s\xCB-\xB7\xCC\xF6^\x89D"\x91\x9C\x94\x8A\xAA\xB2ac\xB4"T(T}Z$\xA2\xB9\xFBUU\xA5s$\xBC\xEDӪ\xA2F$3`\xC9Z1\x99wN\x8E(\xAB\xD6$~\xFE\x8892\xCC\xC7Sd\xEC\x9B\xB0\xB3LJmf9\xC3\xC3\xFETj|l,\xA1\xFB\xD9 \xC3$\x84\x99\x86\x91\x8F\xBF\xDA\xCD_\xFC\xD2;?\xFE7\xA8\xA9\xFB\xA7;O\xDD\xF65 X\x97\xFBQf\x8C)T\xA7in\xA4m\xD4
+4\xA5\xED(\xAA\xE5ؚ\xC0\xB1
ES
ˡ ^\xB7\xAC\x92\xAB\xFB\x9B0\xAB)a\x84\xF0\x8DM\xDA/E#x\xFE\xE3\x92[\xFEj&\x9F\xC2!\x8Dvuu
>|X\xBCmjjjii9\x83\xE2\x{DF7D}\xBD۶m+6m>\xF8\xE0\x83\xD1h\xD4m\xE3ƍ۷oojj:c\xB7訮\xAE.\x8B\x9DY\x92e\x83\xB4bJ$g\xC5YX1Ҋ\xB9\xE8a\xAF\xBCl>\xF3t\xD5uzw#\xFBկ5Uc\x80\xAAN\x8F\xDB &\xC6*\xEA\xD8\xC7WGԔ DB\x961 XG\xE9\xC6\xD6\xD6+[\xFE\x8F\xC8\xE6\xAB Xfꍯ|u\xF8\xDE{\xFD\x8A\xE2_S啒3
+GQG)]Y\xE9X\xE0ؚ\xE2\xD8\xE2bͱM0\xAE\x81\xE4\x94\xECi\xF5\xE5\xCA*\xA4Ҝr\x92Js\xAF\\xE8K\xE8zPݴ\xA0\xDE\xEA\xB3o\xA7\xA9\xA9)
\x8F
\x8CD"s^TH$6\xC9E\xC9%\x89D"\x99-KTbqv\xF0 \xEB$\xB0ⳟ\xD5\xEA׳\xD7\xD3\xD5l\\xB3|\xD5\xD5*`\xCAZ\xF8\x8F\x9F\x8F\xB3\xC4\xE8\x98\xC2X\xA8Z_\xB3z\xEBuW\xFD\xED\xDF\xEAWl\xF5\x80\xD8\xE0\xE0\x91\x9D_=\xF9\xFD\xAA\x9A\xA6T\xEB3mGQGl\x99 E\x83\xBB14\xD8&\xA0\x81X\x8E\x9B\xC2C,[C\xCBR\xE9\x8C엺\xC7&\xEE7\xB84%`\\xD8/U
+\xD04
+\xE1\xB3\xCD(_\xBC\x9C\x83̛\xDE\xDE\xBE>\xB9(\xB9D"\x91H$g\xC0Ҕ\x98\xCCH8Gb\xCE\xE8Hj\xDF#\xD57\xDCX\xFDGWOp\xDB:\xFC: m\xA5nZJ\xC5\xD8X&\x99\xAAH\xC6
f\xA6\xAB\xB9\xE2
+\xED\xDD[j?\xF2\xE7\xC2r\xE9\xF2\xEA\x8F\xFE\xED\x99\xEF\xFE\xE0"\xA0J\xCF\xC5S
+eT̔\xA3\x81X\x8E\x95W\x93(! ,kҟ\xCD\xF25-@\xA7\x96^7\x8B2\x8D \xE8:\x828v\xE1\xF1\KD\x87i\xD2\xF5k4\xED\xB4$\x923\xC75a\xCADr\x89D"\x91Hf\xCBҔ\x98\xD9q\xC3:v,\xCBL\xED\xF9\xDFƟ\xD8W\xF3\xC9O\xE1\x9A\xF7\xFB\xD6]H^\xFDCjhP\xE3:;ET
uuX\xA9\xB9\xF8\xC2\xF5\x9B6\xD1+\xDE\xE9-cn\x99) \xF6\x89\x93\xC7~\xF4\xE3$pD\xF1
Z\x8AC\xB8\xBC\xED\xBC\xE3\x84\xB2\xC9\xC5{\xF2\x82\xD2\xDDb\xAA\xE0\xE8SM\x98 `]N_ "\x93ڄ\x8E\xBC
\xA6\xA9ja \xDA\xDAU\xF30y \x8B\xD5\xD5\xD5I/\xB9D"\x91H$g\xC0Ҕ\x98\xE9D"=8\xC0\xE3&\x92\xC9\xD1\xC7\xF7U\xDFp\x8DTkW\xBC\x83^rI$n\xA43 ǁ\xAAҩ\xA9ʖ\x99▕
K&&\x9C\x80\x92z.j\xBF\xF4R(\x9F\x9A\x93\xC0Dڍ\xA5R=\xE6I\xB1\xC9 \xCA"
)\xA0\x98\x9A!`\xA4H_{\xF4% \xCA\xC9[\xA6\xAESn:Z\x98\xAB:ʪ\xE7t\xF5\xC8%IWW\xD7m\xB7ݖH$Z[[\xEF\xBA\xEB.a\xB04C8ǿ\xFC\xE5/K\xA6d\xC9\xF3\xBBߝf\xC1\x89\xE4\xBCp\xEAԌ\\x96,H\x96\xA6\xC4$\x89\x89\xC0\x91!FaFT\xEBد
\xA6[\xAE\xA0\xE9A\xE8\xC1\xF1'd%R\xA6\x93J\xDA\xC9 \xA4\x92$1a\xA4=9\xB9w\xAF[*(TPƒ\xC1\xC0 at Q\xE8\x9F\xFE\xFF\x84\xB7\xF7)\xE4yM\xC9\xA7|J\xB6WJC\x98s\x87\xE7\xE2/\xB3\xC1`\xC0\xBF4?\xBEs\x86aB_\xA9\xEE"E\xBD\xA5\xA5%\x91HlݺU.J\xBE\x8CY\xAC\xE29\xC8L\xC7\xC5;\xAE\x98\xA6_\xCE\xE7j
J\xB73}F\xABwTb\xF69\xB0\xE5\xC6_\xFAx\xF9y\x98\xE5\xE7RT\xE2\xFEL)7\xCEr\xF3p~~n\xE7\x833ȹ\x96,4\x96\xA6F\xE1\x96\xC5c\xA6\xC3C\xC1\x89\xB7\xC6F\xFDTՖ\xAB\xBD\xCBJ\x87\x99ʘi\x99\xA6\xC3L\x92\xB5y\xDA\xE10\x9E\xCA{\x97\xAB21uU\xF1\xF9
\x85|t-\x9B\xC5\xD2\xD3\xDD
++f\xBA%\xC0\x85 \xD3\xC2W\x8E\xF4\xE4e\x84X\x9A\xAE\xAA\xAAhPZ1ϊ\xFE\xFE~w\xF1
}}}\x9D\x9D\x9D\x87
ڳgO8
>\xED\xD2\xE7\x89D"\x91HʱD%\xA6i\x9Ai\xD3J\x80
\xFC\xB6\xEB\xBB+o\xF8h\xE8⋙\xB2\x923\xD3NLp\x96T\xC6Ln\x9A \xEC\x89O;`)\x93\xB0\xAC\xD1\xF8\x88\xF5\xDA \xF2\x92Q\xE8H\xAF\xCAy\x84\xA6wBδ \x8FͲ\xC0\xC0I\x8B\xBC\xE4Ք\x80ñ\xA1\xA8<\x95\xCEIL\xA1/
\x9B\x80\xF0\xACPhDtn\x82֬\x81'xTr\x97\xE4\xBC\xF5\xD6[\x91_j\xF2
+vJ$\x89D",M\x89Ɍ\xB8\x95έ\xAFc\xEA\xFA\xF0\xD0\xD0\xEB=p\xF9g?o\xBFv8\x930|\x96c\xA6\xCD\xCE\xCBJ3 3\xCB\xE2Y\xDB\xCEؚi\x9B<\xA4\x95\xC9W1
+\xEAК\xAC|^\xDAo\x9E'\xE9\x9A\xE2J
+D Vʍ\x9EO\xC2::\xE9\xF5p\xF5%\xA6\xC6b\xA6\xF3\xD7a\xBB\xC9\xC1\xB3\xA5\xBE\xBE\xBE\xB5\xB5\xB5`\xCD!\xA1/g\xBBԤD"\x91H$/KSbb4.
+šۜ\xA7\x81\xB7\xFE\xEDG\x97]vw\xB2\xF6А\xB0V\xB2\x94 \x80\xA7\x92\x8A\x9Da\x8A\x83 \x9B\xDB& +k) K\x8D\x8F
\xF9C2\xAF,K\x86W\x86<ۤ\xE7\xA0\xD8ɻ\xC2\xF5\xBC\xDC\x92еn\x86 \x80G_\x8A\xF8\xCB\xFB\xA57\xA9\xDC\x89T\xF8\xCCl\x80\x94\x8B\xE6\x80ݻw\xDF|\xF3\xCD\xF7\xDF\xBFX\xA8\xB9\xB9\xB9\xA5\xA5\xE5R|\xA2\xD1\xE8O\xFA\xD3%P\xE1(\x8D\xEE߿N\xF2\xE8c\xB1X,\xEB\xEF\xEF\x832\xAAU"\x91H\x96KSb\x9Al±
F,[\xA3&!a` \x8B\xFD\xEC\xD1uW\\xC1GGy*igl \xAE\xACc\xA2
+\xA5\xC2rb\xD22\xE2#LJ\xBDk\xEAL\x93\xC7S`\xC8*S\x98\xCD\xFC\xEB@X\x93w\xA3G\xF2\xDA4(j.\xFE2\xC8-磨\x9C\xDA9\xFB\xA50d\xB2|\xF08S
> \x84V\x9C\xF5<\xD2\xD5\xD55\x8Du"\xBD444477\xCF\xF90\xCE1MMMMMMg\xD9ȝw\xDE)\x96G/\x9E\xA5\xC3\xE8\xEC윏1\xD0\xDB\xDB\xEB]`s\x86݉ihh\x98\x93\xF1\xF4\xF7\xF7\xDFz뭭\xAD\xAD\x96\x99\xD2\xDBbT\x89D"9\x94\xF3=\x80y\xC1JY6\xB1,P\x93\x9DsbY \xFE\xF0\xE4\x93~\x8Bq\xEB\xC4
O\xE0\xE47\x8E#5\xA6\x8C\x8E(\xA91\x851\xC702\x8CYF\x9C'\x8C\xE4[\xC7\x{DF22}\xF4&\x9A\xB2\x84g\xC7\xF5\x89OCH ^ ^^ \x92\xC0E@\xB0j\xB2\xA6c\xE7L\x98\xA9|r#\Q9\xF2\xD9?L5\xA9\xA3 \xE0\x9A\xA6\xAF]y\xF6奣\xA3\xE3\xEB_\xFF\xFA4\xB4\xB7\xB7\xF7\xF6\xF6\xEEڵ+\x89\xFDq\xFD\xF5\xB5\xB5\xCD\xED0)w\xDCq\xC7֭[gbD"---\x9D\x9D\x9D\xBBv\xEDr\xA5m\xDB\xCEl&
+\xC3\xE8\xED\xED5\xA3\xF8TSSSmm\xED\xAE]\xBB\xF6\xEE\xDD۔ghhh]\xD34\xD8\xD0\xD0\x87\xE6`\xD1\xEA\xFA\xFAzQ\xFB\xE9\xF2\xCB/\x97\xFAR"\x91H\x96Kӊ\xE9d\xC6\xC1\xC0\xAEdDz\x8E
+\xBCu\xF0\xF7\xAB֮@jLX+ \x90a\xCC\xB2\xCC\xC0-)\x80#\xA3\xEE\xBD^\xE3%\xF3\xA8\xCCiJ\xB9\xEEroN\x8F+I\xC01`P\xA6\xF4\xE4\xF7 &\xCC\xDC-\xF9XLE\xE5f \xB8\xA6 \xC5LW\xAD;\xC3\xD9)\x850\xADyӫ\x8Bq\xF5\x93p%\xBD"\x9F2r\xF1\xD2K/
\x9F\xE1R\x93\xF5\xF5\xF5\x89D\xA2\xB1\xB1Q\xE8˦\xA6\xA6\xBD{\xF7vuu\x9D\xC1\xBD\xD7_\xFD\x81J~6l \xE0v$\xFAz\xEC\xB1Ǧ\xB1Pvtt\x9C\xD6;s\xFA\xFB\xFB̉`\x95H$\xC9\xE2b Z1-35q\xE2x\x81\xF2[AH\xEA\x89\xE8\xD9S']k\xA5e\xC43 #34\xCA\xE3\xA62l\xA8\x83\xA3\xAAa\x88\x97aƽ\xB7\xD7Q/wP\xE0\xBAν9\xE3Z\xFE\xA05\xDFk\xCD\xC9B\xEBר)\xEC\x97\xEEA
H1 \xE0\x9A6\xE7\xA1/}\xE9KBvD\xA3\xD1i.\xEB\xEFﯫ\xABs\xB5fMM
+\x80d29\xCD-ˁX,\xD6\xD2Ҳ{\xF7\xEEb\x8AI\xF6\x8A\xC2\xCA\xCA\xCA\xF0\xAD8\xDF\xDF\xDF\x87\xCBI|\xA1\xF0
+Ξ\xCBbL\xC2S?\xE71 \xE7\xA5\xCCk~!e\x98uC\)\xFD\x9Ae\xBF\x84(%_\xB3\xB23\x99\xCF)\xE3PE\x99\xC3~K\xBF\xE6l\xFEg\xF0Ds\xD5\xE6T\xCE\xCFϭDR\x92%\xF8\x93\xC7\xE3Fzd\x9C\xC2K\xEE
\xD78?\x8F'\xDF<\xE6\xB3X&aY鋛BS\xFAL\x93\xC6\xE3j6\x9E\x89\xDBS%*+\xBF_Rh\xBA~\xF3\x82 \xBC
X\xED9\xB8\x82\xF1\x90\x99Ӕn\xCC%\xE5ĕ\x9E\xEEqF\xB1\xAC \xA0TU)UU3\x9D\x91\xD3!\x8F05M\xA3c\xB1X"\x91\xF0Z\xA4\x84\xBE \x85BMMM\x84\x90\x8E\x8E\x8Eh4Z__\x89Db\xB1 \xC30\xDA\xDAڶlٲe˖\xA6\xA6&\xAF?7\x8D655\x89S
mmm\xD1hT\O\x8Bf{zz\xC4-===\xA2\x9D-[\xB6tvv
+\xCFrOOO}}=!D\x84
\x8A}a\x87\xEB\xE8\xE8\x88D"\x91HD\xB4 zgc\xB1\x98\xD8\xEA\xC7m\xA4\xC0\x80\xD7\xD1\xD1!\xBA\xAB\xAF\xAF\x9Ffx\xF5\xF5\xF5\xDD\xDDݍ\x8D\x8D\xE2\x82\xE6\xE6\xE6\xFA\xFA\xFA-[\xB6\x94\xD3\xEB\xE2\xF8\xE5\x97_\xEENl__\x9F7æ\xA0_w&\x9B\x9A\x9Aܖ\xC5㈰Φ\xA6\xA6\x92A\xB1\x87
\x82Gb\x8A\xA7khh(\xF9
\xDEϮ\xE4H\xBCs\xE8\xEE(Ȯ\xAE.\xF7cڻw\xAF\xB4pK$\xC9\xF2d JL ƩS t\xCE\xCD\xFC7\xC5\xE7\xAAeY\x84\x9C\x8C
+c4%\x96>\xD3L\xB3\xB8P\x96\x8C\xE4}\xD2\xE9D\xC2*\xDB4\x80|"\x96\xDF/\xA6\xA4LNh\xA1/\xBDwQ]_
+D\x9C\\xB9"\xD7~\xE9\x8AN7FS\xCD@ \x90 Օ+f8\xA7\xE5\xCE;\xEF\xBC뮻\x84P(\x97 \x82"\xA7g4ݳgO{{\xFB\xA5\x97^*\xEE\xEA\xEE\xEE\x8EF\xA3\xD7]w]"\x91\x88\xC5b\x86a\xD4\xD7\xD7766
8p\xE0\xC0\x81\x91HĕA\xD1h\xF4\xDAk\xAF\xBD\xE5\x96[\xC4)\xE1&Zd\xF7\xEE\xDD[\xB7nU\xD0o\xB9\xE5\xB7߮\xAE.a)\xEC\xED\xED}\xFC\xF1\xC7o\xBD\xF5V\x91\xDE\xD4\xD4$\xCCr
\x86a\xC4b\xB1
;v\xECڵ\xAB\xAD\xAD\xAD\xA5\xA5E\xC8b\xA1ü\xE3\xFC\xC5/~\xD1\xD3\xD3s\xEF\xBD\xF7\xF6\xF5\xF5577]\xD5\xD8\xD8\xE8\x8DSlkk\xEB\xEF\xEF\xEF\xE9\xE99p\xE0\xC0\xAAU\xAB\xEE\xBC\xF3\xCEi\x86'\xEC\x97_\xFAҗ.\xBF\xFC\xF2\x9E\x9E
1\xFB\xF7\xEF/9\x93^M\xDF\xDB\xDB\xDB\xD2Ҳs\xE7NWݖ\xECW\xB4\xDC\xDB\xDB\xEB\xB6\xDC\xD8\xD8\xD8\xDBۛH$D\x8C\xAC+ċ;\x8DF\xC5P\xCB=E{{\xBB\x96p%f\xF1H\xBCs\xB8\xFF\xFE\xDE\xDE\xDE\xD6\xD6־\xBE>\xF7\xC7FD\xF4>\xFE\xF8㽽\xBD\xDF\xFC\xE67\xA3Ѩ\x94\x98\x89D\xB2<Y\x823\x9D\xC9h\x81NJɵ\P\xA6\xC3Xlb\xC2I\x9D\xE0\x95\x95\xCCq\x98\xE3\x98iSl\x8D\xB1\xE2\x95
\xA7#9US&=VL\xB0 8P\xE0\xAAb} 0\xC7\xD4(\xAD!4\xE2\xE4D\xA4\xBB\xC0\x8F+.ݤQ\xB1(\xD6\xE6\xAA\xEEzOOOSSS$ \x85B \x86\x86\x86\xCA]\xE9j\xA9\xDE\xDEގ\x8E\x8Ek\xAF\xBDV#\xD7;\xDC\xD0\xD0\xD0\xDA\xDAz\xFC\xF8q\x91/\xD2\xDC\xDC,\x8E\x88\xB3\xED\xED\xED}}}B\xF4\xDCx\xE3\x8D7\xDDt\x93{\xAA\xB2\xB2R\xB7\xA9\xBA\xBA\xBA\xF6\xF6\xF6T*\xA0\xA9\xA9)\x8B\xB5\xB5\xB5\xDD}\xF7\xDD\xDE\xCB6n\xDC\xE8\xBD\xE5\x96[nVH\xB7\xBB\xEE\xBAK\xD8\xE4\\x89\xE3^y\xDDu\xB6\xB6F"qeKK\x8B\x90\xD7^1\xD4\xD5\xD5\xF5\xC0tww{}\xDF\xE5\x86\xE7\xBDKlojj:p\xE0@\xB9\xD2?B
aKKKss\xB3{e\xC9~˵앪%\x89F\xA3\xE1pX$\xFAlٲe\xEDڵ\xD3<E$ ~\xA6\x9F\x81뮻N\x8Ca\xFB\xF6\xED\xEE\xD9X,\xB6k\xD7.\xF710\xD7X+\x91H$\x92e\xC5\x94\x98\xBF\xDFW\xB5* \xE8\x9C3\xDB \xF2c h\xC0\xF0\xB3aBV
+Mɳ\xCFZV\x8CYV\xFA4\x8B\x8C{I\x96*\xBD\xEEn\xCD|\xF0\xE5p\xB0 \xA0\xC0\x89\xA9\xD7;Ԃ\xC5\xE7Z
\xA9\xAEu\x80\xBC\xB5ҍ\xC5t
+\x99\x8CpS \xC8\x82P\xD5\xD9\xCELI:;;\x85VK\xA8\x9F\x92K\x95Ha\xAE\xAD\xAD\xED\xEF\xEFw
+oB\xEB|\xF8\xC3\xD0\xD3\xD3c\x86a}}}\xC2B\xE6%\x99Lvuu
+\xDC~\xFB\xED\xEE\xC1\xFE\xFE~\xAF\xBC\xEB\xEF\xEF\xBF\xEE\xBA\xEB"\x91H{{;缩\xA9\xE9\xDF\xF8F]]\x9D+Ib\x85\xF6\xFD\x93?\xF9w\x9C\x8D\x8D\x8D\xAE\xFEܒ7D
+
>|x\xEB֭b\xFF\xEB_\xFF\xFAM7\xDD$\xE9\xEA\xEA\x8AF\xA3\xAE
+,
\x9E;r!\xDAD-\xF7i\xACw}}}\xC2\xD9\xDB\xDB\x8Bń_D\x94\xEB\xB7d\xCB\xC2JZNb\x8A\xA7\xBB馛\x84\x8Dsǎ
\xD3O2\xF2\x92T\Vn$%'_\xDC.>&wBd\xAE\x8FD"\x91,g\x96\xA0\xC4DPLBh^\x87\xB9~\xED \xC79\x9A`
\xC6ċ\xA79O\xF3D\xC2\xE2?\x80T\xBC\xAC \xB3\xC0TYR\\xBA\xB8\xAD$\x80
+\xC0\xF9a\xB8N
+\xA8
+t]\xD5X \xD6\xAB/\x81 N\xB8\xE3\xC9+w\x9BMǓ>\x9DPhN(ѭh\x87\xBDqx\x88\\x91q\xDC\xDA\xDA\xEA]_\xB18\xE5\xBF\xF8<\xB2\x80\x90P\xA1P(\x8D\xD6\xD5չ\xB7_\xB670\xD1\xFBV\xF0\xD8c\x8F]w\xDDu\x96\x99*\xD9ݡC\x87\xC2\xE1\xB0۠W\xB0\x88\xC8by\xE4\xCD^\xEA\xEB\xEBW\xC6b\xB1\x81\x81\x81\x9A\x9Aah\xFC\xF9\xCF~\xE0\xC0\xF7T\xF1\xF0\\xBA\xBB\xBBEФCYL\xF1\\xB5\xB7\xB7'\x89\xEE\xEE\xEEi\xFA-\xD9r\xC1\x83\xE0\xCD\xF5&[\xB7\xD3rO\xE1\xCA\xF1iFR,\xD3]].>&\xB7\xB5Ŝ\xEB#\x91H$\x92\xB3e JLJu\xE7\xC2ž\xB0bz\x89\xD8\xF6`\xA4LD\xBCcc)[U
\x9EI:\xCC
\xB3\xCAbz\xF2)(\x84Y`\xBC\xF4\xAAԷ\x97\x85lR \xBA\xAE0\xA8ZXuT\xA1/k+*hu5'\x93\xE5\xD6=\xD9\xE5&@\xD2\xA4\x9A\x82\x9E\xAD\xC4+\xAF\xF4zhhh(wqA\xAE\x8F\x97b\xD9488\x88\xA9\x8B\x80?\xF2\xC8#\xC2Bv\xF8\xF0a\xEF\xF1[WIӗ\x90;nmł\xEE\xA2Ѩ{}\x81x*\xC7?\x8A\xA9\xD3=\xE5\xBDR\xE8졡\xA1\xA6\xA6\xA6\x9E\x9E\x9E\x9E\x9E\x9E\xA3]\xB9y>\xFDݻw\x86q\xE3\x8D7N3W^y'ķ$-\xD7oɖ\xBD^LA\xAEOKK\xCBi\x9F\xC2mp\x9A\x91\xCCa__\x9F\x88X@\xFEcr[+0NK$\x89dY\xB1%&(]u\xD1\xB9]U5 Iy\xF2\xCAӔ\xA6{\x83\x81\xA69KY3mGQ&lG\x819\xA9\x93E;\x82bq齠\xC0\xBA\xA6(\xF8
+\x98\xA6\xAA\x85}\xA9\xE9\xBAX|\xDC\xCCfu\x9Fos\xE5J\x9A)V\x95t-\x9A\xE2Y\xF4\xB55\xA0\xD3M\x9A\xDF\xF8\xC67
+\x82\x85V(i~\x9B^Zy]\xCC\xE5x\xEC\xB1\xC7n\xBA\xE9\xA6r-xW\xA77}t\xE7u\x85\x8B\xDB\xDF\xF7\xBE\xF7\xB9o\xBDNsaL\xD3\xEF\xF6\xED\xDBE\x84\xA2\xB8XL\xCB4\xC3\xEB\xE9\xE9\x89F\xA3\x91H\xA4\xB5\xB5\xB5\xBB\xBB\xBB\x9CX/\xA0|\xE4\x91G |\xE4#)\xD7o\xB9\x96\xBD^\xAE#W\xE4\xCB\xFA\x82{\x8B\x8D\x8E%g\xC0;\x87\xE2\x887
Ӌ\x98|\xD7\xF6,\x91H$\x92e\xC5R\x94\x98\x80\xB6v
bYnF\xB9K\x801\xAE\xAAqƌ\xB4\xAD*3\xA1Z3\xC1\x88\xE5X\xCE\xB1Pd\xA7,X\x85
S\xDFz\xA7W_\xEA\xC0\xA5\xC0\xEA\xA2\xE0K g\xBF\x84\xAE#\xAF/U\xE8 H\x80\x88 ]\xD3.[uA
+t`r\xF5H i\x95e2\xE3\xFC\xAC\xD7J\xE9\xED\xED-(\xC2u\xECر\xE2\xEB\x85*'h\xBC\xA6,\x81(B\xEE&\x8B\x9C\xEE\xBB\xEE\xBAK4\xD2\xD7\xD7'Lw\xBD\xBD\xBD\x9D\x9D\x9D^[\x97\x88\xA4,hǎ
{\xF7\xEE\xFB]]]}}}\xDE\xEBQd\xF5\xBAq+++K\x8E\xB3 at 4\x8Bv\x84\x9C1\xEE2\x8F\xB1X\xAC\xB9\xB9y\xE5ʕ\xE5\x86'\xF0\xAEu422\xB2cǎ\x92\x97H\xCC\xCE\xCEN\xB7|}\xB9~K\xB6<M\xEE?\xEE/\xF9\xDE\xA7\x99\xEF
\x8A`PW\xC1\xEFر\xC3m\xA4\xAD\xAD\xAD\xC0\xF6,Y\x8C\xCCw\xBDL\xA5\xE4k\xB6\xE39\xBB\xA7<=J\x9E\x99\xF6\xCBI\xC9\xF70Þ\xA7\xA9\xDF9\xA5\xC3Y\xB4)\x91\x9C#\x96\xA6Ĭ}ϖ J!\xEA\xB1)6\xC4@l{\x84ҡ\xFC"\x8DBVڀM,q\xADW5H\xC9\xE4ԃ(Ue]\xD6\xE4+\xAB\xB3\xA9\xADQ\x80\xEA:L\xBA\xAEq.\xF4\xA5\xAEa\xBFQ\xA1\xD4Q\xB8\xA6\x99\x96v\xEDz5 \x9EW\x99\xB9\xD5\xCCϨL\xB7 at dgo۶\xED\xB5\xD7^kkkF&\xE7'\xAA\xFF\xB4\xB4\xB4x+\xE0\x88\xEB{\xEC1
\xC5\xC5q\x8A\xBD\xE4 \xEA\xEB\xEBw\xEF\xDE\xDD\xDC\xDC,j^\xF6\xF4\xF4\xF4\xF6\xF6
+-\xD2\xDE\xDE\xF7\xF7\xF7\x8B\xA4o\xD7\xD6Uһz\xC7
w\xBC\xF6\xDAk\xA2\xDA"\x80\xBA\xBA\xBA\xBE\xBE\xBE\xB6\xB66\xE1\xEB\xC7T\xA5\xE8\xD5Uo{\xDB\xDBDY"!\xA9Q>\xD7g\xEDڵ\xE1px˖-"\xA5\xE6\xEE\xBB\xEF\xEE\xEFﯯ\xAFI\xDF\xF7\xDCs\x8F\xB0N\xE3\xFCݹsg4mkk\xEB\xE8\xE8\xB8\xEF\xBE\xFB\x8A+\x9C\x8B\xE4}1\xD1r}}}OO\xCF\xC3?\xEC\xAE\xEBS\xB2_\xB7嶶6\xB7e1\x9E\xCE\xCEN\xF1tގ\xC4A b\x96\x8A\x97\x97,i_\xAC\xAD\xAD\xD0\xD2\xD22\xCD\x94\xB4\x8C\xB6\xB4\xB4|\xC7
w\xF4\xF7\x{1CB3E9}\xB5\xB5U\x88T\xF11\x95\x9C1\x89D"\x91,a\xC8\xFA-\xA5\x9D\\xB9\xD38\xDBo\x87\x9Cs\xC0\x99\xFC\x82\x95\xDB\xC9
!\xEE1d\x89\xE3~\xBB\xCB_\xCF9\xE7Y\xC7q\xE0dx6\x93\xC9d\x9Cl&\x9BMO\x8CNߩe\xA6~\xF3ѿ8\xFE\xF3\x9F;\x91\x88 \x9B1\xC7=%\x8ASZ\x94\x86\xBBJ%\x8Emp\xAD\xF3H\xC9b\x87\xB8\xF7T\xB1]H\xCC5ӮW>\x99\xDF㨄X\xC2x\xE9S\x99\xE3\xA3 t\x9FO\xAC\xA9\xE7\xAB,\x9FN\x87\x8D\xA7\xE3q\xE8\xA8\xE6\xC0\xEB\xEA\xFE\xFE\xEF#\x9F\xFB\xDC\xF4\x93\xB0\x88\xC5b\xB1X\xAC\xBE\xBE\xBE %\xC50i\xC6\xFA\xF5\xEB~\xF8ᒕ\xC3K\xDE\x89D\xC4\xFEL\xF2Hf~% \x8D\xEA\xDA\xE4Ľ\xA1Ph\xE6\x85gp\xCB)yPL\xAFw\xCCgI4]\xB9r\xA5\xFBa\xCD\xE4q
+D\xA7\xF7c\xC3[r\xE9>\xCE\xE9/\x99\xE6\xCC at E\xE6f\xFC\xE5\xC6\xC3\xF9ܴOf9ϳ\x9F\x9Frퟦ߂\x8Ef\xDD/\x99KC\xA3\xB7w\xB1_ްz~~n%sȪ\xDA-\x8A\xCF\xEF\xF7\xFB\x89\xCFů(
+!>\x8Fa?g\xDB\xE6
+!\xF0\x89\x9FN\x907x+\x84L=r\xD6pL\xF7#\xBD4%&\x807\xBE\xF3\xED\xC7?\xFF\x85J]7T\xD5\xC9g\xF0\xB8+p3`BUߗN\xAF\xB2\xAC\x93\x8E\xE3\xAE9^4\x99,R\x9C\xC9"߷\x9B\xE2#ĥ۔qСP\x88\xAE:* B,\x87R\xDD4M\xE1T \x8C\x97\xA2\xBE\x92\x90\x98\x81@@\xDC^Y]\xFD\xD6\xC8\xC83\xA3o\x99&t
\x8Dk\xEB\xAF\xFE\xF6\xBF\xD2䴓\xB00\xE9\xED\xEDue\x87\xB0\x8FJ+\x97d\xF1 %& %\xE6\xF7+%\xA6\xE4LY\x8Csi:\xCA\xD46__s\xCD5\xE3\xA6 D?\xFAR\x88?B)\x8078\xCF8\xF5\x88\xCB\xDBd\xA8\xD4N\x89\xD8\xCA\xFCB\x91I\xE0p\xA2TI#\x87BU
U#\x8AFM\xD7)#z(ĩN
\xC5\xBA\xA6\xE8K\xBF\xBF\x92%\xD3\xEBk\xD67]|i5%\xA6\x89\x94\x9F\x93`\xC5
\xCC\xD1\xF9 \x8Dn۶MK\xEA\xEA\xEA\xEA\xEA\xEA:\x97KfK$\x89D"97\xF8\xCF\xF7 \xE6Z[{\xE5\xDF}q膧\xC6C\x87\xE3yC\xA6\x94`\xAAj \x86\xAES\xD3tUf(o\xB0,\xB0Y\x86\xA6\x9E*P\xA2\xA6
H\xE6}\xE5:`"w\xF9\xAA\x96\xC6}\xCBZ,\xA4\x81+\xBA\xCE \x96\xD1tBLdi0H,\xABʓ\x98RAHV\xD73\xB6BC vv\xA2&T\xF3\xC7W\xD7>\xDFMXI3\xE0\xD3\xE6\xE7\x83K/\xBDt\xEB֭\x9D\x9D\x9D{\xF7\xEE\xBD\xF0\xC2\x9F|\xF2\xC9%\xE7H\x95H$\x89D\xB2t%&\x80\xFA\xED\xDE\xF0կF\xFF\xE1F\x89\x8AH$\xC5\xA6\xBA\xB0'T\xF5\x94m_\x8A)\x85\x8ABS\xF7\xD94!\x98\xF9n\x81\xCA\xE2
\xE1\xA6{H\xC7H\xFE\xB0\xC02!4\xA8i(*\x8F \xA1\xAA\xAATL$\xAA\xFAp&\xB0
+\xC8\xEA:\xA5\xFB\x82\x9B/\xBD\xFCx\xE2$\x89\xC7\xCFzz\xCEb\xFD\xC9\xF3=
+\x89D"\x91H$\xF3\xCBR\x96]\xD2y\xCF IDAT\x98\xA0\xB4\xE9\xCE;\xB3o\xBE\xF9tw\xF7\x84a\xA0\xAA
+ l\x80 T\xD8\xF6\x84\xAA
\xA5\xF4\xC6(P\x98s[\xA4,]}\x99S\x99\xA2\x86\xE5T5Y\]\xF7l\xBD\x97y˳\x9B":'
+\x885\xD3m\x80n\x9C\xA9 \xD2 \xB3\xAA\xD2\xEAZE\xA1\xAA\xBAq\xC3ۜ1YkP"\x91H$\xC9\xC2eIKL \xC0\xB5?\xF8\x81\xEF\xC2\xFD\xAF\xFFj\x8D\x8D \x91ȸ\xE3}\xA9\xD8\xF6\xB8\xAA\xC6u\xBD\xC64QʄY\xA0,]˥YJ;\xCEp\xB1\x9DjNJ\xDDR\x81AM\xA0\xAA
+\xF1k \xAA|* uEuu\xD6GU\x95TUD"\x95\xBE\x8A\xB0_Q}\x94RM
d\xC9\xE4+\x87V\x95\xA1\x91H$\xE7\x84r\xF1\xEB\xF3\x9BNQ.0\xD6\xE9&\xBC\xCC\xF8g\x99T>Q`n\xC6Y\xEE경\x8A\xE4\x86Y\xA4\xBF\xCC6a!\xA6˸O\xC79?\xC5A%\x92ٲ\xF4%&\x80\xA6;\xEF\xBCl۶'\xBE\xF7\xBD\xEF\xBB\x86\xE1LJ\x95\xFCڒG8\xAFP*y\l\xD3tr-G!.\x8BդƩ\x8FN\xFEw\x85# \xE2ת|\xAA\xA3\xFB|T _\xD5* z$ @\xF1\xD6\xE8\x95: \xF8u\xA5B \x94\xBA\xEE\xFA=\xA2\'\xA5G\x8Eƕ\x80RQ
\x84G\xA4zN\xE6G"\x91H$\x89dnY\xC0\xBA|\xE0\xC6?\xBA\xFA\x9A\x8F\xDE{\xE1\xC5?\xF9I<
\xB7\xE2q \x8Am\xC7\xF3\xE50\x92xJӔ P\x80`^5j\xC1\x9C\xBC\xAC\xAC\xD4\xF8\xF2\x85W\x85\xD6\xF0\xAD\xD0 (\xFE \x80P\xE5J['\xCB\xEF\xD72 \xB8ع\x94#\xDD!\xDC\xF1\xDB$\xA7)H&'w<r3fO\x8C*\xBF\x96Qk\xD6\xE0\xC4 \xBC\xFE\xE4\xD0\x89D"\x91H$\xCBEb\xD0\xF4\xE0\xBAm\xDBV\T\xBA\xE8"\xE3\xE9\xA7G
::x\xCC81j\xE65eE$\xAA<\xBCRG\xB6j\xD5Z \x81\xAA*\x95j \xA0jA@)\xC9Z\xA6Os\xF4\xF3\x96V5WD\xA6UͶS \xFCZ&\xE4\xF8\x80\xD9a\x95\xFBm\xB2R\xA0:jB\xA1\x9C\xA6\xF4*K\xE4l\x991{\xC2p2T\xE3i5\xE8\xC0\x82
="%\xA6D"\x91H$\x92\x85\xC92\x92\x98\xF1\xDF\xFCf\xF8\xF9gO
\xA0VU\xBD\xFD\x8F\xFF\xC7j\xFDC+\xAA*\xFC&\xAB=1\x9Ae,\xA9 h
+\xAC|\xD4
+\xB7M\xA2\xEA t\xD8&Tn\x9B\xD0#\xD46I6\xC0m\xD3Run\x9B\xAE\xDC\xF4)uf\x8B\xB9Չ_D\xE9\xF0\x81\xC2аjX9=\xD5Tf\xD9TSso\x85\xB2\\xBD\xDA\xF5\x8C\x8B\xE3o \x9B\xA46ᬭRN\x99ZU%cizb\x8CM:\xD3%\x89D"\x91H\xCBCb2\xF6\xC6O\xFE+\xDE\xF7+_H\xAD
+\x87I\xA8\x80\xE3\xF3\xAD\xC8f\xC5\xF9,c>J5d-gR_ \xAA.\xA7 \xA5\xBA\xE5@\x88N\xA2\xEA\x80\xAA\xB3, \x88\xC2\xE9*\xC9 Љ\x9Fh\x94Zi\xA6\xB8ňFᩋ\xC4= \x80Pj2\xA6\xAF1T\x81\xB8\x86\xF8u\x8D1V\xA9Q_\xAC\x94E\xE9[\xC4dY-\xE4K;Z\x80\xD4l\xA2\xA0R\xC3\xF1\x93\xC2\xFA\xF5\xE7b%\x89D"\x91Hf\xC32\x90\x98\x8C
+\xDC\xF7\xA3\xF8\xB3\xCF\xE9\xD4Q\xB7H\xA7m%\x9B\xE0\xF8|f\xFA(\xE5z\x80"`\xC1\xC1\x84Mu\xCAL&\xB6D\xA30*T\xEA(Lq&\xB7&C\x85jf\x88\xEE\xE7f\x86 \xE0\x9AfA`px8\xA4+v\x86\x87*\x89\x9Dq\xD4\xDC<\x9F
++Ŵ\xA0N
\x84R\xB1|:\xF1\xEB<c\xBF\xC0\xA2\x94rE\xECi|
\xA1*\xA4\x9Fh\xC1\xA3*\x85OǨ\x817\xA4ĔH$\x89D\xB2 Y\xFAs\xF8\x89'N>\xFB\xDCʷ]\x88\xC8*L\x98\xA2e \xA0\xBA\xE8\x99\xD7\xA6߯g2L\xF9U\x96\xB1\xD5p%쌻U쌣\xFAU\xC0T w
+P\xFD`\x8A\xA2\x831-\xA8r\xC7&
+ \x8B ' \xCD\xE7W\xB9\xA3\xEB\xC1 q\xCC|\xAD\xA6\xA1i\xB0M\xA2\xB9\x95\x8B\xC0 TVS\xC6!\x9A\xAE \x93簢\x98\xC0\xEA\xACm\xF9*\xB4\xACm\xF9T J\xA0\xE9 F\x83T\xB3q\xE8U\xBC\xAF\xE9
̡D"\x91H$ɬX\xE2\x93\xC5b\xFC\xE9\xA7]}\xC9\xAA\x9E\xB6
U\xB39\xE7i\x9BT\x9A\xB6u\x87\xB0\xA0\xE0\xCF͆\xEAW\xD3#׃\xC8ڮR \x9Fʳ6 W_\x8A\xAD\xC69 'p\xF2\xEBR2E\xA3@\x90\x90T\xBEl\x9BY6E}A>ٲ\xB9be)\xEAW?
WJ$퐀\x8E Ӫ
+S\x80\xA7
+\xA08i-\xE2\xF7#L\xC1\xC614\x88\x9A\xDAs1\x95\xC9\xF2\xE2\xFC\xD4A\x9Cu\x9D\xCBr̲\xCEe\xB9~9\x9F\xABy(\xDD\xCE\xF4\xB5
\x8B\xEB\b\xC6\xD5\xF3u"ˍ\xBF\xF4\xF1\xF2\xF30\xCBυ\xCC\xD1\xE7Xv\x9C\xE5\xE6a!\xD6\xEF\x94,[\x96\xB8Ĵ~H\x85V\xBD\x8C\x99\xAALU\xA0bT \xD5\x95 \xB5tJ\xC4D\x92\x8A\xAA\x89\x891\xE2\x9B4sz\xF7sh\xB1 \x80C\xBAeQ\xCFH\x9C\xF1\\x95\xD4\xFC!+\x93\xD4\xFC\xA2l{Қ/ \xE8\xF0!)=tx*\xA8\xEB\x9E_\xB3\xB4\xB2j\x98d-\x9F\xAAk\x84\xA4,
ֹŵ\xD5\xF2\xB5\x885\xC0JY\x86\xCF\xA1\x95`\xE3
\x92S"\x91H$\xC9BcIKL#HU\x98\x82\x98\x80P\x90v\x94@\xCEaM\xE2Si܀_\xA7\x9Cï\x8B\x97\x94sTT\xA5N\xFB\x9DUˉI\xA6i\x80\x81\xEE\xB7|*\xD2T \xA8P\xAB\xF2\xDBY\xA0\x92*! \x84\xAC\xE4\xC0\xE42\x94\xD2 \xF8s\x92\xB6:L \x8E\\xD5h$\x9DW\xA5'\x8E\x9F\xF1\xF4H$\x89D"\x91\xCCKYb\xA6N\x8E \xA0>͢\xA2B:\x87o\xD2\xCAhR\x9CӪ\x82,S\xE8Y\xD0 \x98V\x8A\xFA \xE13\x83`\xE1\x9A>A\x87\xA72\xA9\xFE\x82 \x9Aí@\x85\xE6pP\xEA.G
\xAC\x80\xE2^i\xB6Oq\xE5\x94 y\x83)\xA1g\xA1\x9A\xD8/\xE8:A}\xE1t\xC1L\xC9e~$\x89D"\x91,4\x96\xB2\xC4T\xC6S6\xA0R\xAA\x9CR\xB7ҹÙI4 \xEB\xB8 \xF5\x97X\xAC\x96\x86\xF4T\x86@0txjE(\x982S
+ѩn2Sly0\xB1\xAE\x83\x98y{\xA4Ѓ$\xA0\xE8>\x95dmݧbj\xC8Q6_\xCCr\xAAD\xB3At\xDDʚ\x84j\xE22\xAE\xE8pL\x9DMEU\xAB+
+\xC6f[\x8E\x86,t:O nH\x89)\x91H$\x89dA\xB1\x94%\xA6\x9D\xB14]\xE7\xA6It\x9D\x9B\xA6
+\x88\x8A\xE7
+\xA1\x93\xAA\x8DV\x96\xBB\xBDʤu3@\xF447\xC3z\x9A\x9B\xE0:\xD5Y\x80\xE8\xD0\xE8Tf'\xA0ԵG\x9AtBq\x92\x8A0\xE7L!\x94\xE0 \xE0\x8A\xAE\xA1
+\x91K\xAE=@ԪS\xFB\xAFȊ\xECu
+\xD5
f\xD2pIg\xE1S\xAC\xAC\xA3\xD1FGe\xE9"\x89D"\x91H$\x8A\xA5,1Պ0\xC3\xD1u b\xD3\xD4t\x9DeM\xE6\xA3a\x93MY\xA7\xB1\xBAi\xE6,\x94>\xAE\x83\xC0\x87\\xBC&\xDC:\x95 \xC0)%\x8C\xF1\xBCm\x92\x9C\x82\x96
+P\xC0\xA7\xB3\xA6\xE9\xCBSM\x9DR-\xA7J\xB3r
r?-\xFD\xA1(\x9A\x96\xB5\xB2\xFEp\xE4\xFFg\xEF\xBE\xE3\x9B(\xFF8\x80\xEEr\x99mڦ\x83\xD2:٥B\xCB
2\x95\xA1 *"""\xA8,\x95!\x88D
\x8A"\xA2(\xCB"?D
\x80\x80L\xA1 at Ye\x94і:ӽ\xB2.\xB9\xDFIڴM۴
+\x94\xE2\xF7\xFD\xE2Eo<\xF7<\xCF].\xC97\xCF=\xF7\x9CQgd\x98\x8CRt*OiI!=\xE6\x87B!w\x95{9Ą\xBB;#-Q&6_\x88\x96ˤR\x95\x83;x\xC8ĂF\xADV&\x93\x9B\xAF\x82ۆ\x92\xB6\x99\x8C\xB1\xB6\x98j\x8D\x99\xC8Ҧ)3\xB7SJ\xA5\xD0\xE9\xA0\xF0(\xDD\xD2M*\x88D6\xF9\xC8`\xA9\xAAT$\xE8\x8C"iY kIX\xA3\xDE$\x92\xC0\xA8IE&\x91D$Ճ\x93\xC2h \x95\xCAQR\x88\xDC
\xBA\xAF\x9CB!w\x8F{9Ĕyz\xEA\xA5RA\xA7c\xA4RA\xA7K\x83N RH\xA4,XEM \x80\*\xD5\xEA\xE4\xB0^m\x87JU:mi\xB5\xC1\xBA) \xC8\xC5
+ Vb\xBE\xD7\xC7B*\x95HYb\xA9\xA8\xE2xf%b\xA9B*2ꌌB\xA3\x9EQ\xC8M\x80\xD8z\xE7\xBB\xE0%\xAEb\x81\xE7%\xAE\x9C\xC0'a\xE5F\xA3FKE.\xAC \xB4\xBA:
!BHU\xECt\xD1p\xBB\xC7
d\xAA\xF7\xB1\xD6\xE32
+UԿ\x8A\xF12\xAB*\xB7\xAA\xE3P\xFB\xF12\xEBr<mke\x9E\xAE\xFD\xB8\xA1U\x95[U\x89\xB5/\xB3\xB6l\xF7\xC8ic\xA0\x96\xD30\xE7-!v\xDD\xCB!&d2\x89\x8BB[P \xB8\xBB\xB0 0R\xF00(\xCCq\x9E\xBC\xD2h\x97v\xF3 \x90\x97\xAB+\xC0J1\x80+\xCC\xFFKY\x91"\x98\xF4`˲2JYb \x8C \x89BL2Nn0drh5BY\xBFM\xC8\xC4\x9D`0\x89$\x8C \xB9\xAB\xF9HĊ \x98\xC4, 1 \x88K\xFF7\x8CX)D\xBC 2\x99\x96ae\x9A\x92z,B!\x84\xA7\xB9\xA7CL@\xE6\xDBT\x93\x90\xA80u\xEE.^\xD0\x97\xB02\xB9 \x90\xCA\!\x97A\xA3u,\xB9>/O\xD0\xE9\xC0Jk\xB3( \xBD\xE5>\xF1\xB2k\xF1&\xC7iysgJ
\x91\x80L,\x81Z\xADV\xA8p\xF7\xB7\xD1$\x92\xC9\xC6\xF2B\x88\xA5b\x83\xCE \x96\x8A\xCD?9Y\xAE\xFCpE \xF4\xE6{\x96\xA0 r9:\xBA\x88B!w\x8F{<Ą\x9F\x9F\xDCC)\x94Kdr\xF3\xE9\xA3I$\xC1\xCDUP(\xB9 x}
+\x99p7 O[di\x89\xF4T1ZM\x89X*\xB1Z\xA3e[\x99H\xA21\x9A\xE4"V\xEF.e /@&\x93-\xD7&\xB4"\xEB\xC5w\x99`*6D"k\xECȱ"\xDEĈY ,'5\xF1:V\xE9ƚL\x96`\xC4\\xF9\xD7Hbi1\x951\xD0
+\xA3\xD0BJ7\xFBB!\xE4\xEEq\xAF\x87\x982\x99\xCC\xD7ɉ:\xADF&\x93]\xE5\x8C\xC1$\x91\xC9\xE1ӄ\xE0h4\x90{@\xA3\xA9\xBC\xA9`2\x96\xCD4m"S\xB3:^'\xE1\xA4\xD0ju\xAE
+9'\xD5
+\x82L\xC8dz^Nj\xBE\xF8\xEDf+ŀ\xD1d\xEE+\xA9e\xAC\xCF\xE2\xD8X\x86\xE1d\xB4b\xA9L\xB4qY\xF7V\xA14O\x8B+\xEC\x87B\xAEP\xA21O\xC84\xAD\.\xD3h\xB4
+W\x99F#\xF3p\x85FC\xAD\x98\x84B\xB9K\xDC\xEB!& 4m\xA2/̗J$0\x9A\xB4R#ce.ʲh\xCC\xDC-\xB2\xB4s\xA4\xB6,֬\xD0\xFB]Ɗ\x8Cٙ\xE0\xB8{\x88\x8C:# \xE3w \xA9\x80L0i\x82I˰\xE6h\xD2E$\xAF\x875\x94\xD4r\xB1H \xE4\x80 H\xAD\xFF\xEB\xEB\xFD\xE3
+9J4\x96\x89\xF2\xB4\xE6\x9B\xD3K\x97\xCB\xE52 at +\x97\xCB \xC8\xE5(\x9D&\x84B\xB9\xDC\xFB!&\xE3\xE2*U\xBA\x9B\xA7e%%Z/\xAFr\xE3\xFBT\x81\xA8\x9A\xD1%=T.\x806/ #\x93\xC3z\x87\x9EBTv\xAF\x8F\xCC\xFA\xBF\x96a\xE4b\x91\xD6`\x94*\xE6PRƊ*f(\x97C\xA3\x81\xB91R.\x875\x88\x94YJX'tR\xA9T\xA7\xD3I\xA52\xF3\xFF\xABLR\x86\x95:\xC1T\xBA\x8AF\xC7$\x84B\xC8]\xE2\xDE1ᡂ\xA7'4%s0\xF0Rq\xA5P\xCFq~\xFE \xBD^n\x93\x89e\xBC\xCC\xF2\xA4%֔\x8A,q$,m\x8D\x95o\x80\xAC
D2\x82 \xC1\x99\j\x8E5\x80\xD4z\xF1]ʰ\xE6U\x90\xD9˟B!\xA4!\xFCBL *\xF0zA\xA1`\xF4<\xE3R鉑Z-P\xEE9 \xC8\xE4v[e\xFE\xFE\xC8\xCB-\xEB\xBBi}h\x90\xFD\xD26M\x85̵\x9A\xD2\xFF-\xF1\xA5`*\x8B\xADA\xA4T\xAE 5\xD7P&\x93V̈Bn\xA3\xDB=^\xA6PE>L\xE38:m\xDC\xD0ZbY\xD6nAU\x96+TQO8g\O\xF3a\xB0-\xDD<]\xF5\xEBEH\xF8o\x84\x98
*x\xA8\xAA|\xE7\x99CI\xC7/1{\xA8*\xDEXS\x87\xFBl*Z]\xF8H\x97\xBF !\x84Ҩ\xD4\xEE\xC9\x84B!\x84ԈBLB!\x84\xE2d\x8D\xF2B\xF9\xEAnB!\x84\x90\xFF\xEF\xC0\x86\xAEA\xADQ+&!\x84Bq\xB2FيY\x8Fa\x87!\x84B\xC8m\xD7(CL1K\x8D\xAF\x84B!w\xAFFbJ\xA9/&!\x84B\xC8]\xACQ\x86\x98j\xC5$\x84B\xB9\x8B5\xCASL\xAD\x98\x84B!w\xB1\xC6bR+&!\x84B\xC8]\xACQ\x86\x98"j\xC5$\x84B\xB9\x8B5\xCE\xB36\xAD\x98\\xF0\xD7m<\xD8vӨ\xD41\x93\xF3\x9D]+B
\xD0\xC2噱]^r}r\x8F[\xD1
+]B!\xE4\xB6i\x9C!\xA6í\x98\xD2\x8E\x9Cr\xA4c`r< `ҺG\xC9T\x87\xB2\xB6\xF6}\xAB\\xD2>xx\xD3\x97n\x9Dp\xC2ɵ\xADnҺ\xC1o\x87\x9F}\xA2K\x8A\xB5Vn\x96*\xFF\x9D\x93\xB2\xF7Ne\xDBu\xC1\xD0\xDF\xC6^\xB6\xF5\xB5\xFA\x95hG\xD7I-\x9F\x94'\xCE\xF9\x82\xAF\xD3֕w\xC1\xC2\
\x8D at Q\x91\xED"\x91+J~\xDB[s%Ǯ\xE8\xF3\x9C2\xE6\x81 \xC5զ\xE2f,{\xFC\x83%\x85h\xBEa\xD3\xE6\xD6O\xF3\xB5(\xF4\x81\xD0#
+7LW\x97\xEE\xEF3ڌ\xF0H\x9C\xFE\xBE\xAEƺ9\x83\xCFk\x9A\xBAe\xA9\x8F\x9F\xCC=\xFE\x9B.\xFE\x8E\xD6U\x8Alcť^"\x9C\xB8C\xB8\x97\x84\x8D\x8D\xF8\xE8\xC1\x947'\xE4\xD4x\xE8\x9C\xF6\x96w\xEC\x8Cm|\xAF\xF2\x81K\x87H\x81\x923\x9BS6\xD6\xEEӇ\x9B\xF1\xBF\x97Fo\xF7\xC0\xFEE\xD8\xEB\x83\xBF&K9\xB0\xAF\xCB(k\x82\xBA^\xF8!'\xFFl?\xA2\xFA\xCFB\xEEB\x8D2\xC4\xE4
m\xC5\xEC\xDCq\\xF8Xр\x81#e DMtE\x95\xB7&\xD7x\xDF!-\x99`\x93v?2Oq\xCB\xD9\xC9;\xB4\xF9w/\xB8\xB1=\xA1\xF2:#·Mv\x91\xD8[\xA3ϸ\xFC\xD8\xF3\x85\x8EU\xBA\x9C\x89\xBB\xAA\x85\xBB\x9B\xC1\xA1s\xFA\xED\x9F*\xE3Unӻ\xFC\xE5ۿ.\xB9\xD5!\xDBS\xF1&\xA5\xF3\xFE]\xF7\x9F\xAAO\x81\x95\xA9^x\xA5\xCB\xD3M\xD8\xCD_Ɨe\xEC\xE0q\xAE\xB4\xCE2\xE0\x95\xE1&Tʏ?\xFB\x98\xD7\xD5\xFD\xD5n:g\xE0\x97\xBC\xB8\xE4\xF8\xAC\xCE\\xF7\xD0\xCAe\xE5\x84\xFA\xE3\xEB\xE2\xE2{\xB6i\x92\x93\x99.Q\xB1l\xAE\xE3\x85\xD1}77䞲
/ŐqQ|K>_\x94\xEA\xC0Ѫ\xAA\xCFt\x87N\xAF+\xA6J\xA5\xC8<sc\xE9&\x9BE\x9DC\x9Fx<\xCC_\x86 `*Tg^:\x9D\xB2g\xF7\xAD_\xBF\xD5ս\xF4\x84\xFD\xB4\xBBS;P\xA6\xB8u\xBFt\x9By\xBBJmPޫ\xF6t\xEE\xEDg\xB0<u\x8Dq0\xF2#\xE1X\xC4ù\xF5\xCC:\xA4{Đ\x91\xE7kJ鬷\xBCcglý\xCAz\xDC\xD8\xD6\\xCF \xF0Х\x9E?;\xB3\xFF\xCD\xEA\xDF\xECFt\x9B2A\x98⤿l\xAA\xE5!\xFA3\xCE\xF0\xC1p\xA9\xDC]ɲvJG\xF6\xF7V\xCAL
+\x83\x8EeK\x8A\xDCW)\x86l\x96\xD2X4ʓ\xD6\xC1VL\xAFo׆\xA9 >\xA2Dz\x807\xF1
\xCBA:\xE1\xEC\xBEs/| 0\xA2З\xBB\xFD2\xD9\xD5|\xC4nb\xC8\xDA\xFFq>\xD8 \xCFC\x8E\xA4\xF7\x9F\xB8\xFES" \x84<\xD4j\xE4p\xAF\x91\xC3\xFD\xD7͎~\xE5\xBBret\xA0\xC8\xD9_b\xFE\xD4
0\xA0Հ\xDE&u\xAA\xCEP\xBE
b\xA5\x9B\x8F< s\xBD\xFAO.\xBB\xAE\xA5\xC03#b\x80\xC4O\xD3n\xBD\xD2!8S#\x8B\xEA\xFC\xF1\xC0Co\xD4!\xBB:d\x9BY\x94\xFF\x87ߋ\x81w\xBBP\xB7 i\xE1\xFE\xDFC
\xAFC˙\xF2\xF9\xE7\x8D\xDF}Wb\x99\xFEx \xE27݈aD\xA5/\xA6\x83ǹ\xF2.8\xCB?\xAF\xFC\xF9\xF8T\xEAB\xA1\x8B\xA9\xAE\xD1S\xCB\xAC\x9E\xE0\xC6'E쐕hI\xA9\x98\xFA\xE1\xD0)m\xAAآ\xF0ܳ\xED\xAE\xEF F\xE4x\xA1:\xB49bJO~\x91\xCE \xFEVab}\x8E at H\xD8\xD3\x9Aى\x84>6\xEFӟl~oĜm\xD7\xF4,
\xF0\x94g\xBF\xBE\xFD\xBB6\xED4\xB8i\xB7\xC1\xDE\xDAN}Uc\xCCRQ\xD0\xEE\xC4\xCE\xDDT\x95\x97\xEBN\xF1\xFB\x80\xA5\xB37\xE7=\x9F\xE7\x8AJ\xED[@Ql\x8D\x9F ^\xAF\xBE\\xF4\xE9W\xF5i\xDFu\xB0\x92\xCE%\xF3T\x98\xF9|\xBE\xC1\x98\xBDA\xDA;\x857\xF3\xA9R:\xB4\xFC
+۳%D\xF1H7\xC4\xFETR\xF1t\xD2[ޱ3\xB6\xE1^eF\xC4 \xCBY\xBF9\xC8\xA3zl;\xCDGvʬ\xE6\xA4.\xD0\xF1\x800\x94\xD4\xFA\xAE\x80\xC4cy\xB9pU7\xC1\xE4\xEE р\xA7<\\xAFe\xEF\x881\xAFw\xEF\xE8 \xF7\xE8\xA2\xCE/
+\x91\xE7\xC7gK$ d\xCDÿ\xFBٽGpҴ\xEEI\xF5\xF8\xE0'\xE4k\x94!\xA6C\xAD\x98\xBE\xEE32\xACp\xE7[\xFBǯ\xB2,\xF6\xF5\x88F\xA6}\xF7\xC0\xC5U\xD6
BZ6
+*\x8A>\x92g \xE4\xC5\xE9!\x91\xB0\xD0C\xD1&0\xCC_
r\x83M\x80\xA4UG</\xB7\xFEw}\x9B \xCB\xDC[\x84\xEC\xE4\x9D\xD2B\xFC?Y\xDF%\xE4\xE4_aO\xE8\xE8h/n\x9Ft\xA3|M\x82\xDF{\xF8\xF4$v\xDBGk\x84\x96mo\xF4\xFD\xA8酧\x92_\x9F\x96\xF1\xF3\x87\x9Br뒭\xCF\xD7E\xF4i%W\xA9,\xBF\xAA\xDEm\x9B\xA8sRn\xA6\xFDu,\xEF\xECѺ\xFC\x9E\x9E{\xFF\xB2\xD7\xE4Ϲ\xF4γ\xD7V\x9D\x96\xCC}\xC3_\x86\xF8\xAF>)\xB7
g{\xBB\xE0\xC1Q\xAE\xED\xA9\x80{\xF9\xE5\x90?\xF2\x88\xFE\xF7\xDF\xF5\xF6\xB6\xF1_\xFF\xBF.\xC3\xDB \xF7\xF4\xE1\x81\xE4\xD8TF\xBFfڞ\xDDnƂ\x82r\xC9O\xE7\xF8\xED\xFD\xB7cTJ\xEE\xEF֔\x8Eʀ\xC4\xEEeE\x88\x80\x83\xA8^mb\x82<c*-\x95\xBCwp\xE8t\xD8}\x95\x8D6\xABlV\xBF \xF2ѣ\xF5?'\xD5\xE1<\xCCٱ9.\xC1\xCDP\xBE\xE9T$U\xEA/\x94?\xAB\xFC^TqS\x8B\xEA\xF5Y\xB2\xE7\xF0\xB0dD\x9F\xF9\xECtm\xEBV\xEBJ:\x95\xFA\xE9\xBEm\xE7_\xDC\xDA;"e\xDDM\xFDZ\xB0DQQ\xF2\xBE\xFEd\xC1+~\xF5urk\xD6\xC4E\xA54\xEF\xF9G߹\xB8
oy\xCF؆{\x95\xF3m\xEC\xFF\xBEE\xFD^\xEC\xB2\xFE_%\x80&\xCA6\xC7kn\xAFM]8>\xE3\x9B)\xE7>< \x9A\xF0u߷\xFB\xB0@\xFA\x97c.X_!qȠ\x9E1\xE3|\x83\x94@\xE1\xADo睙\x9B\xD1\xFE\xE47\x98
+N\xED2FHfm\xEA3-
+\x80\xFA\x9B)\xE7><`\xDE۴\xAB\xEAf\xDD|\xFCG\xBDU4\xE0\xBEV\xF7\xF4\xF4QB\xBD\xFB\xF7\xDFǘ\x83l\xB7\x80& \xF2NnV\x8C;\xD9yB\x98\xED\xEE\xB69Ц\xD7\xED{\x84\x90\xD2(C\xCC;\x8A\x9E\xFC\xB4\xFF\xB2\x91ljla\xCB\xE7;~\xA4\x89\x9D\xBB
@ȼ\xD0Fǯ\xB6\xF9
+]\xA0\xB4\xC9/\x8EHN*\xBF\xFD\x93\xEBWy\xE6\xFCsЦ\xA0\x83\xD7{\xEB\xFF\x8C\xBB\xAFu+ \xC3X~sG\xBE\xA5\xD4
\x891Z\xDA \xE2`FT!7O) ukmbL\x90ݷ\xEF\xAC\xDB\xF6\xF5\xD7_]\xAE\xC7\xEA\x93\xABkX\xDDՐ-\xB1)\xFDb\xC2\x97\xF2\xA2w\xFA|\xD2kLɞ\xE0~6\xE1\x8Em\xE9A~_\xBE\xA7\x94\xAD\xABŮ\xBA[^\xAD\xF8\xB5\x91\xF4Ѿ\xC7\xF3\xA2\xBE|\xAF\xDD{\xFD\xEE4v\xE9\x86ԝW\xD7'Uz)
9\xCEvw\xA1\xBE\xE4S?89\xA2\xAA\xB5\x99k?1\xB7ܷ\xBF\xEB+_vxm\x8CJS\xF2\xEEݑO+\xBC\xBEIg\xF4N \xCC\xC3\xFE\xF7\xC9\xF8\xD3Yw\xA46\x852(\x99sտ}\xAB\x89\xB4r\xCES\xEF\xCF\xFE at Y\xA8ιvE}\xEA\x98zצ\x82\x83I\xFA͛+\x9D\x87\x9D\xFA\xD5\xF3\xAE\xC3>\xEB\xF9\xD07\xEA\xFA\xAF\xFEJ\xDEdY\xCC\xF3\xC4b\xCE\xFEp\xAC\xE6\xF4\xBE\xE05\xF6r\xFC3\xEE\xBEn>\x99\x9Bf\x9F_~\xA6>CO8PI3\xC7\xCE\xFF\xBAx\xB8\xEBۃ\x91{\xE4\xE2\xBB\xEB\xBE#\x91\xDA;\xB9\xB4\xF3\x8E[\x87HQʭ\xBC3c\x8E\x9B\xEE\x9B\xD2qp`\xCAo[̙;\xFF-_\xF3\xDB\xC0\xAF\xB2e3C\x89\x9Eap0Z\xAB\xE5\xA1\xE4 \x88\xC1\x88\xDC\xDC\xDD|T@\xE1\xEE*by\x9BVJ\x95 \xA5\xAF\xBF\x96\xF2XU?K3\xB7*p\xCA
+\xEDY_m\x89L
\xA6\x84O\xDF\xE0\xD1\xCC\xD5\xCD|\xB4\xA7\x8BJ \xE4\xC6+{\x8Dy \x9E\xC3_\xEBn\xADo\xCBF An\xDEr\xA0\xB0\xF8<c\xD4\xFCz=\xB0\x93X\xE8]\xBC\xFBtsA\xEA\xE5ϾUǞ)8\xE8\xD4\xEB6\x84\xDCf\x8D3Ĭ\xBE!\xF0\xF5\xFE\xAB&\xC8r\x8F
\xEA\xF0\x9E\xDF\xFE\xCD-'/\xF3\xEB\xD3\xEB\xF8\xE7\xFA\xD6m8\xF5ڕz\x96-\xFB\xACt\x97p\x90ICX\xD1\xCDrx<\xD4 \xB8\x91w\x98\x95/'eX\xBB \x96
[}7]\x86\xF8c\x8F}l\xA9 Sq\xABr\xCB;.\xB8\xFF\xAF\xE9
+^k\x82}
\x97snh\x87Գ\xE5\xB6\xE5ye脷C'\xBC\x92\xB1sӥ\xE7\xDF\xD2V\xB7\xF3\x8E\xA9)\xDBܩ\x83\xFF-\x9D\xC9<l\xF3\x94?\xF6fA\x8F\xAE\x91\xEEQ=}\x9Ae\x9C6\xC3\xFA\xFD\xE2\xE5ӫ\x9F\xBF\x8A7\xF7h\x92\xA8T,r\xA3^ӜEE\x87מ\xEB\xB0\xF6\xD6\xFB\xBB\x8E\xE0\xD6G\xCF\xC3\xF6\xB5\xB0Q\xC3qvljK\xFFք}\xBB=Q\xBE\xD9\xD1x\xF6\xACr\xF5\xF1
#\xB2v\xB6\x94
\xD8\xC7gʄ\x96c\x86\xBB+\xC1\xC7Gg\xB8u\xF3\xCAO\xAAjG*\x90\xBC\xFEr\xF1ו\x85p\x97\xB0\x90\xB9\x84\x8B'\xDB&f
+\xBAV\xCC\xDD\xC4\xCA\xE7
wc\xDDVU\xDBV\x9E\xAD:\xB7\x8D\xEA\xDDv\xF2k\xD0\xE6f\xFF\xBB%f\xF4[\xE5/q:|2\xD4 \xE9֏\xEBr\xA4z \xD0\xE9\x8C\xCA\xC8\xF0 \xBD\xB5\xD1[/\x9EHK\xA5 X]\x92\xB1Ҏ\x8B
z=r\xE9,$\xAF\xF1\xFD?k5\xEED=Դ˵}\xCB[5\xDD\xF6iY\xE1\x95Y\x8FU\xDE\xD3Z\xC8=zqE\xBE\xF6ԞB\x8C}`\xFDSq\xFDZ\xDD4\x9F>}2\xF0\xB5@>nӥ/Ι\x94\xF3\xDF\xF25\x9F\xB1
+\xFB*[#5e\xA7\xDEgΰMe2\xF3;\x97y\x98u\x84ɒ\x88\xB1,k\xED\xFC\xC4\xD8D\xCC&\xF5\xE9sm\x94>6\xB3]\xEF@\x80\x9C\xF0\xEE\xA1u\xFF\xB6\xFDt0Y\xB3\xB1\xB3\xE2\xC9m\xA1\xC0\xC7\xEFJ\xB1|\x95\xF4i\xB1\xFF\x9B\x96\xE6\xB0T[w.y玌\x9F\xD6j\x93K?\xEBB\x94*\x80\x90ˊ~\xF9\xF8\xDA/\xE6r#b\\xC4\xE9\xA9\xA1\xAF\xE5h*\x844\xB8\xC6bV\xFF\xB3\xF5\xE6'\xA7\xE6\xE7\x9B֮\xD52H
\xD8:\xED\xF5
+\xDD\xE7\x8C\xEC\xB3
+(\x8C\xBE<\xFF\xAFr\xDBވ\x8Eۊ\xDC~\x8El=ԟ\x8F\xFD\xBD\xB8\xDA\xF6\xA1\xC0]{\xC3\x91\xB2tja\xF9dU\xB5VZ\x96\x9F;\x95zh\xBF\xD4PlXT\xB83Ho\x82\x84\x95\xE4\x94ˁ\x85\xF6\xF2\x90\xD6i\xC1\x93[\xBF;3h\xF8d_\xF5\x98\xB4MKbg\xAE\xAD\xEE8\xA0\xFAlE͛\xB3\xC1핑\x9D\xDD:\xB4\xF2h\xC5B\xD6~\xAB\xBA\xBDeS^\xBF\x8F-\xDB\xEBsq\x9D\xC3\xE2\xACيf\xEC8_\x\xAEʟ\xDA\xC5)j\xF3D\xB3\xF7br\xE3:\xA7
\xAE\xA1\x9EU
\xE7w\xA1\xF6n߬\xB8\x8Cy\xA8\xE5\x880\xC4o\xBAu\x981@\xF3\xD7\xFB\xC4̑\xFA\xE4\xD3\x97|\x90\xB2\xF6\xB0\xEF\xBEd\xB1\x83\x9D\x83\xC7E\xCE\xEA\xF5\xEEnڤw\xA0P\xB3\xB1iq\xB1\xC5%ee)\xFC\xDD\xC1\xE7\x8B\xC6Pq\xFB\xFA\xB2\xD7>z8\xE3\xF5\xC3\x96\xE9\xEE3F\xF9\x8Fx̷EP\xA5
\xAF\xDD\xC9P\xB5\x9By_\xCF+\x9Dk\xFEv\xF8\x84\xDEٛ_To\xB0IbS=\xD9\xC8\xD7Cf\xBEм\x8D
+@\xD6ڑq\xDF\xC1\xA1sk\xDA\xE5ڿ\xE5\xC8\xDE\xDE\xD9\xDB\xC8e
E̹\xBA\xD7\xEE\xE6_\xEA\x85@\x87Q&\x80fD7\xE1\xBDjW\xD4\xC8(\xA4\xEE?\xD4gfYGI\xA7\xBF\xE5k>c\xF8U\xB6n\xCC)-\x93\x85\xA7\x8F\xB5~\xDC`S\xA8\xA0+\xB2}#0\xD6w \xFE\xE6Q\xF5\x86
+8кE\xCCd \xC0*\xA4ذ6\xEB\xDD\xC1M\x94Ptx\xD0\xE7\x8Dbs痌Mߙ\xEB\xB8o]\xCB%\xA0\xCD\xDA\xF9u\xEC\xAD\xA1\xDCq3(\xCCl\xB2\xEE\xB8\xE7\xB1\xF7/\xCF\xFFK1n\x9C\xC1nJ\xA0\xD0\xC0ކ\xEB\xA4\x91\xBA\xB5\xD7(C\xCC\xFBB\xE9\xBF\xF9\xA6\xB4\xF3\xBFt|\xF2c\xE9-\xC2
+\xAFN\xC1W\xE8\x94\xB2-\xF5\xE5m(\xC5\xFFϏ=\xB9¸wTYJ\xB3\xC7[\xFF\xBA, PV\xB8{ѕ\xA5\xB1\x93\xD8\xEF+c틹\xFB\xD6ӻkڿ\x8A9H\x83Y\xEE\xE87\xF1~\x93\xF8\xF8[
\x96L\xF7\xEBy\xD9\xBFe\xAB\xC96x[Lh \x98\xB4\x85\xC5)\x99z\xF8\x98No:\xFF\xF9/\xBA\x8BG
+\xB7\xCCu\xB4\xDF7\xCB\xE7\xC1\x96H\xDES\xF18[\x89\xA7\xAD\xEF5g \xB7\xE9\xC83\xF1\x91\xC7\xE7Gl\xBD(
?\xF4\xD6\xEE[\xF6\xEBW\xFDq\xAEi\x9C\xC2痥ޜ\xF6\xFA\xFB\xB3,\xA5\xA7,=\xBFH\x8B\x83_\xC5 DzRX&j\xCA)\xA2ʼn%\x9E\\xE1\xD59㙚\xBA\xB5U,\xD4,e\xE3\x95~mʊ
\x88\xC2#\xC2m\xB8\xCF\xD4\xFC\x95g\xDBg\xCEu\xECD܈.: \x88-\xFE2\xF6ڗ\xAE\xD5\xEFK\xF5'\x83\xE3\xA4S\xFAq\xC8-8h\xEF\x9D\xD5lZ\x97\xE3\xF3\x95
\x90\xF5Չ\xA6 \xEB\x{24BB7BEF}d\x8D\xEC\xEDr\xAD\xDF\xF2\x8A\xB7~\xE9>\xBD\x9B\xF6\xF4\xEEl\xF7\xBE\xAD>\xFD[u\xDFK\xB1o\xFC\xEA\x94\xEA\x99?\x85\xF4\x89)\xD9\xD1W.\x8D\x98e[O\xE7\xBF\xE5ky\xC6\xDE\xF9Wٺ\xBD:ez\xC0\x80 P6u\xBF\x9F\xD5
-K#n˱GK\x83@\xC6\xF6+S,\xE5X\x9E\xD2\xD2zp\xEC\xD1\xE4\xC9M\x86B\xD9-j @{\xF3\xCBX\x8Ee\xF1Vp\x84(Lx\xA9\xE5\x8D_\xAB<\x98
e\x98_
+K&u\x8B_\xEF^z+\x9E\xB2S\xC7
+\x8B.\x8C_\xE0\xF4ߓ\xA41\xB1s[\xDCݮQ\x86\x98\xB5\xF9\xF1\xB4gkpR\x8DL\xDBSckJ\xB3\xA6[\xB6\xB7\x8ER\xE6o}5\xE3_;\x89\xD9^\x8F\xF9\xBD\xFCbp\xFF|֦\xF9g[\xAE& \xCE푉\xBAn2Vf]\xA8՚|\x83X\x80\xAD۽\xCF`\xBB\xED\xB6\xC5\xE7\xB7-f\xEB\xFF|\xA3\x9A\xB2\xCD\xFCh~~q\ў\xA3\xE6\xABEM\xFF\xB9\xD9RQ\xA8\xD9\xF3/j\xEAQ*\xF7\x96\xF3Y\xA9v\xAB\xE7\xF2\xD1o\x9D\xC7wC\xF2\xEE\xE3\xFDg3\xC0\xD9
\xE8xr~\xABo\xD7\xE64\xB8\xC2=\xA15
g\xC7v\xA1\xDEz5\xFF\xE3\xEB\xD0(U\xE1\xCE\xF9)6g\x8E櫯l\x82 [{M IDAT%\xAB\xBE\xD0f\x8F\xB5\xDC\xFA\x85 \x97\xBA\xF4\xB9\x9ANB\xFB\x85V\xD6d\xCBz?\xE3\xA5Q\xA6z\xB5m4sy\xBA4\xE5{\xBBgJ\xFD\xE0K\xCAo"\xE6E~:] Х\xC6\xE7ƜP\xFF\xB55g\xDBъ\x99Ub\xEFd\x88;\xB2\xD1\xC7\xCD\xC0\xDB\xFD\xAA˹\x821\xBD'\x94[\xD9뽨\xC9Hޙ\x93bl\xBF\xB1\xB19\xA27\xE6l\x8B\xD0t\xE0\x84s\xA0\x{195D2A}\xE6\xFCw̠\xA0=˃#T\xBA\xD3\xEB\xA3~h\xA6\xF9cO\x8B\xF1+;yz\x9E\x9D\xFCm]\xF3`9S\x85BF\xC4@\xF7\xE9\xE4\x9FV\xEC\xCF};\xDE\xF2\xB6j8c\xE0U\xB6n_\x98\x900\xF6Ѣ?.\xB5\x8ER\xFE\xED\xD6\xFDY\xD4\xEAa\x8D\xBB\xA5\xB5ҥ\xD3 at Wf\xB7K+o\xCB6\x80\x88\xB1\xBC\xEB@\xC40n\xCFG\x98\xBFD\x85\x9D\x88a\x8AW\xEC\xD2
+\x9F,\xB5Ư\xC5֙\xF7\xD7\xDDM \xB9\xC5\xDB*\xEE \xD1\xB1\xE6Þ\xAC\xC9\xE5\xA1\xE4\xC0'"\xD4_ M\xEC\xEE\xE4\xD3
?X
+N5x\xF2\xFD\xB7\x86]\x9F1"e[\xBF\xC9 \xB9\xFB\xDC\xCB!\xA6\xFC\xA5O۾9F\xC1\xF1iK\x9FHXy\xA1\xBA\xADڻO\x9A
\xF6\xFCp\x87\x9CM\xF3/\xBD\xBA\xC961\xFB\xE8\xBB-_\xEC\xE3\xDCB\xAE\xE4 \x94\x9C\xDE;eJq\x8A\x9Dj\xE0\xFC\xA7/\xF2\xB7S@!S\xC7\xDB}\xC0\x94\xEF dV\xFF+&\xD5g\xCB\xFF\xF6
0\xD6/\xED\xB5Lvhg\xC3T$@:(\xBCt\xD8pcA\xEF0N\xBB3C
\xD1K\xEA\xCD
K\xE7.\xB6\xE7\xF3A\x8B^
+h\xA32\xC4m\x8D0\xDD\xF2
\x93\xB22v\x82̧\xD9q\xBE\xF4
#\x87\x8F\xB3#\xBBPw=U\xD3^
\xDF_dmz5\xAE\xFC\xC9P\x81\xF9\x8B\xA4\xEA\xED\xBD>]\xD8bL71\xB4)K\x9FJ\\xF6o\x95)
-4\xC0\xE5\xA5iAS\xC6z\xFAp%\xBB\xDD\xFA\xAD~}\xFF\xDBO\x8A\xFCt\xB2\xFD#\xA6=-f\xCB\xD8\xEF><\xD9e\xA7\xBCO\xB7\x9E]T]\xA2\x9A\xD3t\xF8\xAC\xD4\x9C>\x98\xB2\xF1\xEB\xECM\xA5]\xF8
:YٚC
ņ\x92
\xDB\x82\xEC\xA3v\9^\xF5\x95\xD9S\xAA8 )\xF9s\xE7\xC2\xFA\xB0\x80 \xA6\xFE?3
\xAE\xA4C\xBB옞>k^
\xDEM^\xBDi\xFE\x95W\xCDWWS҇\x85\xBF_l9|Q\xE4Z\xD9\xF9)+\xEB\xBEK\xB9F\xC8Znܣ\xD8{\x81\x87\x84\xF3\xF4\x94\xFB\xBA\xB7u\xBB\xF1T\x87\x8Cg\xBF\xE5m\xD3\xD7x\xC66ԫl\xD9^,V0\x8Cz\xD8[> +=e\x802*\xF2\x8F\xF7\xA2\xA7\x98G&b\xFD\xFBwM;i\xBB\x91\xC8\xFA\xAEG<\xDF;\xF1y\x91\xCC\xFC
ZxkՇ"\x86\xC1\x85\xAF3\x93\x9Fo
h^\x98\x9B\xFA\xA9\xE5*9\xFE\x8D.Ԏ\xF7\x94F\xDCL,I\xBA\xA1\xCD/\x81X\xC1\xB9\xBBIUM\xA4J>\xFE\x89д\xA4h\xB2
+\xA82%\x9Dӡ7 ]\xEAU\xAD\xDA\xDF \xB9\xA9\x9C\x9B\xBF\xBF\x8B\xA7JĤ\xD4s\xC7 \xB9ce\x88Y\xF3%\xFF \xAD\xF7/R\xB9E\xF1 \xAF\x8F\xC9ܑZ\xED&\xFEA\xEE\xF1\xF3\x81Q}\xFA\xFAkS\xB3\xF6VJ\\xA2\xF4\x88ha\x88?\x9F\xF2\xEB~\xF5W˵\xA9\xA8|- \xBD\x91W'=
\x99u\xB1\xFC\xF2\xF07;\xFE1Z(\xAC\xCB`ܠ"\xC8\xEA8\xE0\x91\xF3\xB25\I\xC7\xF0V\xEElN\xC5]\x9B\xB5\xAER\x8C2|Q\xCF\xE1 {6x\xA8\xF9\xFE\x9B\x80e\x8B\xF9\xACM\xAE\xDC\xA2\xBD\xCBsm_M\x8Fs\x9Dv\xC1aO\x85\x9F\\xAA\xC9\xD1q\xB3G\xE6
\xAF\xE1d\x89e\xAC\xF9zY%\xEC\x84U\x9D
+\x86\xE4#\x97&=Up\xB1\x9A\xAC
,\xF4\xA9\xB67\x96\xBAs at Qrʗ_\xDC\xFC\xE8\xA7\xFA^+\xBC\xF4~\xCC\xE0\xADlnn\xB9X*5U\xF2\xE6ֈ\xB1\xE5/\x82\xA7]\xD2\xFD|I\xFD\xF3jsGZ\xC9#/\xFA<\xFDH\xD3ރۆH\x8E\xFF|ܒơ\x93\xE1R\xC6\xC82P-K\xB9\xFE\xBE\xED\x89pEn\xDC\xD5I\xE4
w\xE8\x85A\xAEkɱ\xF5|.\x8DÕt\xEC\xFCwL\xA1k\x87l\xF2\x91K\xB3\x9F*(d?2Xv\xF0߀\xED\xEA\xF5r\xA7-\xBF\xBC44l\xFC\xA0\x801m\xC1\xF3\x82\x967䔜\xBF\xA0K\xB6`\xEB\xF9\x96\xB7\xAA\xF1\x8Cm\xC0W\xD9ڌ\xA910,\xCBa\xC7\xD5\xD9\xF7wZ9F\x88\xA3&\xB7ztp\xE2\xAF\xC3\xDA=n
\xDAV\xAB/\x92I\ \xFA"\x8Eћ{ęxX\xE3\xCBܴ\xA5\x93\xD4{͕OS\xEF\xBA\xDC|r S\xFC?ٗJ\xF7h\xC7\xF5\xD9
[\xBF\x{1ECECF}L\xD6FQ\xAE"Z\xC6\xFA9&\x82 \x9Fv>cyN\xC0/\xE3=O\xF7 \xDA#/=\xF5\x83\xEF\xAAY\xB9\xEB.5`?Bj\x8B \xE9<\xB4\xBAը\xEF/EA \x93 \x82 X\xE6m\x960\xA5\xCB`d,\xCBA\xB0\xA6A0\x9AL&\x98x\xC1\xC8\xF3<o2\xF2F\xA3\xE1\x80K\x8DmU~\x9E?\xACPf\xEC\xBD\xF9\xDA\xEA\xAAn\xE4,\xA7\xFBh\xF7\xA0\xA4\xFC\xD2/˻G\xBB\xD1M\x9E\xCE{mI\xFD\xE5\xA9W\xB6~SC\xBF\xED\x9B\xF1\xE2\xB4:\x96'\xE3\xB6Uey{\x8E\xC0\x8D\x9E*\xCF:T\xB8\xEF\x92#\x89%\xB8Ɏf\xAD\xDEgoe\xF7&?L\xE4\xFFX\x96\xF3s\xCDY9X\xA8d\xC2.\x9A\x83\xB9wˉ\xEA'i\xFD%羮6\xBAO\xF0\xEE\xAB\xC9Z\xF2\xB3\xE3[\xA8\xBE\xF9S\x95\xBB>\xE1\xB5ZlB\xEC\xAB\xEF[ޢ\xE63\xF6n~\x95\xDB
+\x94\xB7p1^ߡ\xAF\xEA}\xE9\xD7N\xE4\xC6?n\xFB-\xA3\xDAt\xBAEo ꥃo|^qK\xB6\xDD at yז\x9C&\xAD\x8D!+\x89\xBF\x94ħY\x8E2\xFB\xC8L\xBFGB\x8B\xBE\xF9(\xFFx\xFC\xAA\x9E\xED%\xF6V\x9An
\xCE\xFA|\x87\xF3\xF7\x8E46\xB5,+\xE28\x8EcD
X\x8EeY\x86\x81)Ś\xFF,\xC3@\xC40 \x81\xB1\xACX\x86a̿\xAB\xCA-\xA97\xA1ڻ\x90e\x88yX)\xAEg\xAD!\x84'k:#<\xFAU) \xFE\xC2Ű\x8A\xBD\xCC \xA9\x8F~%ht!f\xE3\xBCP~\xE7F$!\x84B
¶\x93\x96\\xB8\xA0\xA7\xD7\xA6Q~\xBF\x92\xBBW\xE3\xB5\xA8Q\xBEX\x99\xAC\xE6D\x84Bȝt\xEC˔'\xBE4O\xD2\xF7q\xB2b\xBBϺ\xBA\xAB5\xCAS\xE4\xE2\xD2\xD0U \x84B\xB9S\xB2)ļ#XW׆\xAE!\x84B\xC8
\x93\xD5\xD0\xA8\xB5\xC6bR+&!\x84B\xC8]\xACQ\x86\x98t\xA1\x9CB!\xE4n\xD6(CL\xBAPN!\x84r7k\x94!&h\xD0"B!\x84\x90\xBBX\xA31v\xEDj\xE8*B!\x84\xDC1\x8D\xEF\xA13\x8D2\xC4|\xA0\xCD\xE8
+\xA3\xD2\xDB\xCE\xDA
\xB0\xBE\x9A\xF4\x8E$\xA8m\xFAa\x8D\x9B\xDF\xE1\xF4f,\xEC\xE7 0
+\x9F\xDEv+g\xA5\xAF\xBC\xB0\x86c(\xD8O/0\x97T\x97I5%Vʿ\xB6ޝ\xE7U㪡#y\x9C\xEFp\xFA\xFF \xAD\xB1\xCE\xC3@Ы\xD5jWWWA\x86aY\xCBCM\x86+}.J\xE5\xDC\xEC|>\x948x\x95,\xC9V(\xB7\x96\xAD2AU%Z\x96l\xC5%Ulu\xEF\xBF\xFB*~Йj̓ F\x80\xDD#f\x93\xC3v3a+\xE6Y\xA1Ċ`\xAB\xD8#\xF3dY\x89\x8C\xC9\xF6\xF5e\x86\x85\xC9ކ\xA6\xB2\xD9#\xD0ذ5'!\x84B!\xA46(\xC4$\x84B!NF!&!\x84Bq2
+1 !\x84B\x88\x93Q\x88I!\x84B\x9C\x8CBLB!\x84\xE2dbB!\x84'\xA3\x93B!\x848\x85\x98\x84B!\xC4\xC9(\xC4$\x84B!NF!&!\x84Bq2
+1 !\x84B\x88\x93Q\x88I!\x84B\x9C\x8CBLB!\x84\xE2dbB!\x84'\xA3\x93B!\x848\x85\x98\x84B!\xC4\xC9(\xC4$\x84B!NF!&!\x84Bq2
+1 !\x84B\x88\x93Q\x88I!\x84B\x9C\x8CBLB!\x84\xE2dbB!\x84'\xA3\x93B!\x848\x85\x98\x84B!\xC4ɸ\x86\xAE !\x84r\x97\xFAa㦆\xAE\xB9w,_4\xAF\xA1\xABpGQ+&!\x84Bq2
+1 !\x84B\x88\x93Q\x88I!\x84B\x9C\x8CBLB!\xE4\xDEףSPxCׁ\xFC\xA7\xD0\xED>\x84BH]<8\xA0E\xEA\xFE\xEB\xCB(G\xF4\xF2D^\xCE\xF6\x8B\x85RΚ=\xB6\xBBD\xBDk\xE7\xB1\xEF\xCBV)\xC7\xF4\xF2<x4)\xB5\xEA\xFC\xC3\xC3[
+\xF7H8uj{B\x95i\xFC{=\xB4\xF5\xA5p\x83:\xF3쩣3~\xBC^Mm\x83{\x8EX\xBA\xD8\xED\xF4\x91\xCB)\xC5P\xB9h\xFE\xB7\xF0\xCF\xED5\xEC!\xF5B\xAD\x98\x84BH]\xF4\xF2\xF9=G\xF7(\x9D\xF5\xF5\x97V.\x9B\x9F\xB4qt\x85\xF6\xC2=\xD3Z\xF7\xB8h\xD9\xFC}\xD3[ \xF0o\xF1\'߾cƝ\xDC\xFDΏO\xFA\xD9$\x94\x8E\xD0\xC2\xDF2\xAD|\xE2\xF1\xD3^\xB5r՛o6\xAD\xB2\xA9G\xFF\{8'\xACm\xBB\x91\xE3\x9E]
Z]m7\xAD\xF8\xE2\xA5mQ\xBD\xBBܵw\xEF\xBE\xCB>\xE9^)\x89\xF2\xB9G;\x8C\xA86B
G!&!\x84R\xB1\xD3\xE1
5\xEFI/\xCB\xFC\xC5\xE3}\xA6\xFC^p<\x9F[>\xE5Ř\xFD\xEBc
+\xB7\x90\xAA\xF1\x9E\xB9xRo.-\xBEH\xD1\xF4 \x9BxT\xDA뉓\x96\xB0\xB5\xF0\xBD\x85kf\xE0P\]5\xBE\xFF\xEDb \xED\xAD\xE8 \xF0W\xDAO\xF6\xE0\xA3#\xE6\xF7Wi\x8B\xB2\xE2\xCE_:}\xFE\x8F\x93i\xE5\xD7KW;wыO\xAF\5\xEB\xC5*r \xA4V(\xC4$\x84B\xEA\xA2G\xB87 \xB1Dޫ݃\xE6E\xC5 \xD7\xC0\x9F6.N\xD9\xFE\xD2s6\xB1\x9AT \xA7\xFE8 \xC7;\xCE\xFBW\xD2
+G_\xFA\xD5~\x9BK\xED\xF8l\xE1\x8ET\xEF\xA8EϷxp耟\x97\xCF\xE8\xEB
+ at 1b\xE1\xE87{U
\xF7kr\x80\xA2\xAB\x97O\x86vع\xFE\xFD\x93\xBF,9\xF6f\x87ʩR\xAF\x9D\x981\xF1\xA3\xD9_
\xBE\x98V\x94q\xE3ʦ\xCDI\xE5\xD7{{\x8B nM|j{$\xB1\x83\xFAbB!u\xE0\xD7\xCAO
+\xA4\xFF\xFCc\x9A\xDB3\xAD[\xF0L\xEA-\xB5\xD8U\xA5\xE0\xDA4\xCC\xB9\x89ٷl\xFAdJ\xC5"\xA0\xE4\xD2뢘\xEDK\xE7\xA4\xFBv\xB1B\xB6\x97bn\x87\x8F\x9E\xB4\xAE(\xE5H\x82B\xE4^\x8E\xB9\x8C\xB6\xD3\xCC\xFD{\x97\x87\xEDT\xA4\xF0VZ
\xEFvr\x95y\xBE$\xF9V\xA6\xED\xFAߞ5\xA6\xF8\xF0\xF7\x99A/}\xDC՟3\xC6_S\xB5\xEC:rd\xCF\xF9O}\xF1}Y
+\xD3.\xA4\xE9"B\xA4 at A\xB2\xBA\xDEdž
+1 !\x84\x90\xBAm\xD1R\x86\xE4\xDD;\xBF\xF0㷃.w\x9F;\xB2\xB5">
M\x93\xFF\xD92\xF1\xA3S\xE5CG\xAF\xCE\xCD\xD0\xC6\xFFks\xE3\xCEg+\xB6V\xCE\xF5\xC57g
+o&\xB2^\xF9\x85\xE7\xFBo\xF6\x86n\xC7[\xE7%\xE0\x9D\xE5\xEFL\xEE6l\xD7\xF3ׇ|\x97Vy+\xB1\xFC\xB5}\x97]Qȋ\xB6_̮\xB0\xF6앂\xF9/\x8CZ@\x9B4\xFF\xA9\x95\xDFb̛\xB3\x96\xF6\x98\xF9J\x87\xEF\x9E+M\x9FR\x88)\xF22OT\xBC[\x89\x90\xBA\xA0\xE5\x84BH\xED\x95x\xE0\xF2Y|\xB7|\xEC\xE0b\xCC\xF1g\xE6\xAD\xFC\xFDcE@~BbŦI\xC0\xE0@\x96=\x9E
?\xBFS\xF5\xAD\@5\xE2\xD1\xEE\xCFuS\xF1\x89G\xE6% \xC0{Nj\x81\x88\x81}\xAAx\x88\xE75'$U\x8E/
\xDB\xFC\xE3\xDA蔢\xBC\xA4\xA5SV\x9A\x9B-\xCF\xC7\xE5 \x90{\xB9\xD9&\xDB~4\x80\xFAʕʕ'\xA4(\xC4$\x84Bj-<2\xCC\x859\xC1\xBD\xBA\xCA\xD2lF\xFF\xE1(<%\x95Ӌ9 /\xA3\xDA\xE8M:\xFE\xE1v\xD0^\xFBT\x88\xBF\xF8XJ\xB6\xAC\xD8cY\x99[\xC8pu\xF7\xB7\xB3a\x91\x80\xA1\x9A V\xF7ނ/Z\x8F^\xF9Y\xBAe\xBEEST\xBA\x8E\x99z2>\xB8y!\xB1\xBA:\xE20
+1 !\x84\x90Zs\xF3r\x94\xA3F\xB7K<r\xC0\x88G\xDA\xF5\x{DB33}\xEBF\xB9A\xF7z1TZymfF\xA5Q0\xFD~\xDD\xF8\x9Au\xB0!\xCF`o\xF0\x89 q)6\xCB@
\xF3\xC7
kL:bP\x84+\xC0g\x95R{\xB8\xFF\xE7\xE53Nn|\xAD\x9B\xB2\xD0\xFB~\xF3\xA1Y\xBD\xBC\xE0\x80\xB6a> 2\x93\xCB_s/\xBCr1+\xEB\xE8!;\x{D804}\xD4\x85\x98\x84BH\xAD%%f\xF0 \x87\x92S{\xB31t\xEC\xCA{\xBBk
+n\xA6e\xF1 \xE7\xDDn\xFE\xAA\xF7O.\xBE\xBF\xC2&\x9C\xB2܅i\xFFN\xDDm\xA5Sn\xCC<Kʹ\xEDdz\xB8\xB6\xBDv~2k\xB0\xB7\x80O\xA7\xFE\xB3,#b\xB6xux\x80\xCCk\xD7J\x83\xD4\xE7f\xCF\xF8\xE5\x8Da\x9D\xFD\xBCV\xA7\xE5W\xEF\xDE\xFD\xFB\xCEY\xF0z\xFC\xC6\xC9o\x86\xDB pm\xF8\xF5
+U \xC6s\xD17m\x97\xF6\xD0ý\xB08r\x94\x9D\xBB\xD1 \xA9
+1 !\x84\x90ZK\x8D\xCF\xD1@Af:z\xF8\xB9]\xDB\xDBcڷ\xBF^\xC9\xE7 \xA0\xA4\xF0\xEF\xD4wVِ\xE9\xD9Wn긐N\xEF>\xA6W\xBBY\xCF<\xB4\xF3\xDB\xF9'?\x86\xF8\xD3\xF6\x97&Z\xB5p[*TQ\xF75ͽ|p\xFE\xAA\x93\xD3\xF3\xF3ҁ\xA6
vm\x9D\xC6A\x9B\xF8.Y\xD3\xFA=78\xE0\x9Fyo\x84\x8D\xFE\xA8\xC7{29\x80Oߴ\xEDt \xF3\x9B\xFE\xFA{\xD7\xD3-^|\xFB\x99(W\xE4\x9E\xDF1\xF5\xA8\xCEf\xB1\x99#B\x82z]\xFD\xEE\x848\x88\xEE('\x84Bj/=\xF9\xAAQ2\x99\xC7\xC4\x8C
\x96\xB2{0 \xA0p\xEB\xBCE3d
{^u!\xBD,\xF9\xB2\xEF\x8F_ܷ۰Ǻ
+\xB3,Ѧ\x9F\x9F=~c\xF9\xA78^\x9F\xB7dK{]\xCAgG\xD3 |<h\xE9\xFB3R\xBA\x80/<\xBD{הe\xA7l\xAE\xB3\xA7
\xB9\xA6\xBF\xF8\x9Dc\xB7J\x9A4\xF3\x96\xC8K\x9E\xB3z\xEB\x9C\xDF\xE2\xF6\xADy\xBA\x8D\xCCU\xD8}4e\xF8\xD0\xD1\xF3{{\xF3\xB7NLz\xEDx\xF95ٱ\x89%Qm\xE0o\xC5V\xFD\xBCJB
DŽt
Z\xDDj0\xF5,@\xC0$\x82 \x96y\x9B%L\xE92\xCB2A\xAC\xE9A\x8C&\x93 &^0\xF2<ϛ\x8C\xBC\xD1hp\xE98\x9Aa\xCAU\xCCv\xB6\xC2*\xBB+\xA7\xA9>Am\xD3\xDF\xEEk\xDC\xFC\xA77ca?\x81i\xF8\xF4\xB6[9+}\xE5\x855
C\xC1~z\x81\xA9\xB8\xA4\xBAL\xAA)\xB1R\xFE\xB5\xCD\xF0\xEE<\xAFW
+
\xC9\xF3\xF6\xE5|\x87\xD37\xF8i\x8Duf\x82^\xADV\xBB\xBA\xBA
+\x82\xC00˲\xE64\xC31V\x95s+]\xF8\xC3\xC6M\x95K,ӴŬH\xC3gY\xC60\xEF
\xD4\xFA\x93Ӫz\xEC\xB8x\xE7\xCF&\xF5\xF4\x93\xC1\xA0\xCD?s\xE0\xC0\x9Cߒ\xAAHh&\x9D5}XkCf\xF4\xC9K\xDF\xC7\xD8\xEB\xA9\xF4{gҀ\x81\xE1M\xC40f݈\xFBf\xF9\x9E\xED\x96\xC1\x86\xA4\xE1J]\xA5Ǥ\xC0\x88\xE7_X9:\xE8\xF4\xEF[\x87\xAF8gg5\xF0`\xA7\xA0ԫIv\xB7%\xF5\xB7|\xD1<˩Ř,\x80a\xA6\xD2d6礩t\xF6\x99#X\xC7q
#\xE2\xC0r,\xCB2\x8C\xA5'1Ú\xFF,\xC3 at T\xFA\xE5b=\xC3Y\x86a`=\xB7˖ԛ \xA1\x9A\xB5b:\x94\xE0n\xFB\xA8\xBD
_-\xDE\xDE*w)\xC4t,}\xE5\x855
s
+1P\xE5\x94<o_\xCEw8}\x83\x90\xD6Xg\xE6v\x87\x98\x8DM\x8FNA\x88I:\xD6\xD0\xD5\xF8\xCF\xFA\xAF\x85\x98t\xA1\x9C \xC0\xB0\xC9\x97l 0eg_>{\xFA\xB5o\xCE\xD6\xEB\xAEBO\xEF.\xC8:\x99\xE3\x94\xDABq\x82c1շ\x9B\xE2Lb\xDE-\x9E\x9E\xFC\xCC\xD4N\x9EbN"\x97\x898\xA9TƉ\x8A\xE2vE\xCE=^\xF3\x96\xCE\xF0\xFB\xDAon\xC6\xDE\xFF\xE9\xB4\xFB\xFD8\x91\xABW\x93.\xBC\xF0\xD7ُS\xEA\x9E\xE1\xA4)\xA3_\x97
\xFC\xF1\xBBY\xBB\xF2\xABL\xE4\xD9\xEC\xA3I\xBDB\xE5F\x8DF\x97\x95\xA9>{<\xF6Ǹ\x92\xBAI!\x84\x90\xBB\xDDQ^i;_\xA9\x9Fk\x95\xFF\x9A\xBAV?$D\xAD\xF9\xFA\xF9\xF8\xFBz\xF9x)]]2N\xE4\xDC\xCC
q\xFE\xF8\x91\xA7\xD6_\xB1\xCE\xE9\xF5\xF5\xCB\xED\xEB\x9FOA\xD4\xF7\x99\xF1\x8B:\x8A\xABJ\xA3j\xA2\xF3\xC6&\xA1\x81\xE1\xE1-\xFB\xF6\xEF9s\xB7\xA9_\xA9\x84B\xB9;P+\xA6]^\xBFly\xBD\x9BkM\xA9x\xBD:=-\xFA\xC0\xC1\x977\xC5տ\xC8\xCF\xDE\xFB\xEC3`ȓ\xA3\x96?ݾ\xA1^\x95\xEC\xD3 \xB9/\xB4V(N\xDD_\x8F&L H8w\xB9\xB8W\xC9C\xE3\xFA~zn\xAF\xDD\xE6\xB9q\x97_\x8D\xBBo\xFB\xEE\xF1\xE6
y\xB0\x9FԐI!\x844~Ԋi\x97>\xF1j\x92:\xAFb\xAC\x93\x9B\x9E\x95\x9A\x9E\x95\x9C\x9E\xAB\xE5 \x9CħYаg\x9EM\xDA8q\\x8D\xF1\xA8cvm#\xA5\x9E
+\x88\xF5a n\x8Bn%\x9F\xAFgN\x8A\x80\xA6. \xDFOxV\x9F47\xDD<4\x9F\xB2\xE9\x8A/ !\x84\x90{\xB5b\xDAU\xF8\xDA[\xAB \xF8\xF5\xE4\xDF\xD7{ZîKc\x9E\xDF`
\xF4V\xF9\xFAkc\xA7\xF5\xB2\xCCy\x84.\xFC\xF2\xA9+~:ጲ\xD3rt\xB0\xF3|\xDB;\xA90\xA3\xDECVxx\xA8,SF\xB7(J\xB8z\xB8\xBE\xA5B!\xE4\xAE@!fu\xD2\xFE9yyF\xCF \x80\xE3\x9A\xD6\xB3\xF0\x93\xA5k20sa_\xCB\xEF\x88\x83\xFExfO#LLs\xC7Ɍ\xA4\x8Cz\xE6\xDE9\xD8ܰ\xAB\x8D\xBF\xB0ֱ\xFB\xCAy\x83\xC0\xFD\x83\xCC\x8C\xA2\x9CC;\xFFY~\xAA\xA0\x9E\xD5 \x84\x90\xFAؾ\xE6݆\xAE\xB9w$\xAA\xF0*e\xA0\xE5\xD5ӗ\xF0e3\xC5\xE5\xD7\xFD\xB0z\xBF\xED\xF8\xBA
\x9E.w\xA4J\xB7S\x8E\xD6
#s\x92*\xEF\xD1qP\xCFp/ \x80~\xD7\xFA\xB2!\xD8\xFA\xBC湈J\x97\xCD-\xC79q\xE0ʅS\x97\x8D\xED\xD0\xDCӽy`\xC8؉}\xEBY B!\x844jŬ\x87\xA2W\xB2\xE0\xEF\xDD\xD0\xD5p\xA2\x92[7\x8B\xE1g7TV\x88Qbp8#E\x87f\xAE \x90}u}\xCAF4\x97(\xBB\xF4\xB4\xF7\xFE\x9E\xCF^9s%\xBB\x9C\x97\x8F{@@@\x84 \xB8\xB6
+\xEFR\x9A\x81N\xBD\xF1\xB3\xDD\xC9u\xDDB!\x844,
+1\xEB\xC3\xC5\xC3\xFE]>\x92Q\xC3:F4u\xF3\xF4p\xF5\x90\xBBz\xB8\xB9\xB8ɋ\xBF\x99\xF7\xBF\x8B x\xBE<\xBA}\x80\x8B\xCC\xD5C\xAErsq\x97\x9BWm\xDAXl/\x83p}c氇#\x83T.\xD0g\x9D<ph\xCAz\xCB\xE5\xFA\xC8\xBD\xA6Fz\xEB
+6
+\xADbY\xD7f\xFCp \xD0\xE4\xDDi\xDD|a\xD4[WI4\xE9k֜\xB4\xFF\xD2 \xBC\xBE,\x9A|\xF8\xA1\x81/=
\xE8"\x82.s\xE5\xFC\xEFW;r\xA7\xB9\xA2isw H8u\xD1v\x9C߃\xBF\xFE\xF2\xD8\xCD
_L\xEESx\xE7ʛ\x8Brr._\xBA\xF6\xCF\xE1\xB8\xCDW\xF2\x9D\xF2\xE0B!\x844
+1\xEB!\xB2\x8B\xA5\x9B& @\x9DS'z\xBE0uD\xF9
\xF5-\xBC\x80" \xA8\xFD\xABcD\x85Uޕ\xAE\xC1 d\x81\xDD\xF6\xFD\xF8X\xA0M\x9B\xA2\xAB\xBBo\xFF\xA3.\xF5\x8E\x9B7y\xF3v\xE0\x81\xC1\xFD\xFA\xB5\xA8<\x82\xA6g\xEF.м\xC5Ⱦ
ʿ\xC0\xE17\xFF8y\xEEV5\xBB\x94w\xFA\x96&\xB2\xB5ܳE\xF0}a9Cu
ҭ\x95O\xE9 \xA0\xD2&Czx\xAF\xFE%\xAB\x9A\xED-T\xDE* П:z\xB3\xA4\x93\xC7F\x9C<ַW\xE4\x83횸\xC0X\xCC\xF3\xC5\xF9\xC5]\xBB\xF7\xF4\x97\ܲ~\xC2\xEF\xF9(\xFF at EB!\x844Fb\xD6B\xF9\xC8\xCAuӺ\x96
\xBE\xF4\x93s\xCB\xEE\xF5I_\xB2\xE8\xA7\xC1\xFD\xBB>\xD1+Ԛ\x807˃\xA4ӯ-\xCDi\xD4\xEA\xF9Q\x91\xAA
+\xAB*\xE1\xDC\xFD\x81\xB4\xB8\xB3\xBF\x85\x80\xE0\xA1\xFD\xDB\xFBp \xC0y\xB5\xF9\xF8\x87\xA75\xCF\xFE\xEF\x93\xF7W<1`\xF2#\xE1\xA5m\xA9 \xFFX\xFCە#晛\xFF>:/sƳC\xB5\xF1 \xA0\xF2\xD9\xE7m\xA8.\xBE\x80\xB6\x9F}\xFC\xF5
\x81=\x86l\xECQi
\x9F\xEARՏ\xEA\xB1|_sW \xC5I;\xEC'8x\xF4\xCC\xC1\xA3e\xCF\xD5\xD3_Bg#!\x84rϠ/u\x87\xF1|z\xE9\xB4o\xDB\xCD>խ\xA9\xB5\xB1(\xE9\xEDW~K\xB7I\xFB\xCF\xF1\xD8\xD1\xE2\xE7\xBF\xF1V7e\xF9\\x8A\xB6
\xBA \8\x8F\x9FG\x85\xD4Td\xDEO\x8BW\xBE}\xD2|\xA1\xFBԢUG~\xFCzjW\xF3]4.-\xBC\xDAnϧ\x97֬ߺ/W\xF4\xC7xK\x9B\xA9R\xAC9r\xB3\xACE4\xFE\xDA\xF5\x99%]n\xE3ݍi\xD3\xF9ׁ\xBD\xCC\xCELK)\x86\xCA&\x9A\xCE\xCDH\xBBt%\xFEp\xF4\xC5\xFF\x9D\xC9s \xE8
\xE6\xA0\xE8V\xF2E @\xB0\xBF\xA2 \xB5$\xB7\xEA\xF4R:
+ !\x8D\x89!5\xB9\x88\xAF\xB0\x8C\x93\xF8\xCBk\xF9d6>#\xB5P\xC7\x80\xD4E\xE1\xEBU\xEDC\xE3\xF4\xF9\xDB~N\xED6\xBA\xAD\xBF\x83\xDAS
+\xD9 \x97xR
!V\xF4\xDD\xEE0\xD7_}\xF4\ \xF7\xF4i\xD3\xCC\xDA }ܑ\xAF|x \xCE^\xC7\xC1sI\xB9\xA8bZU\xFAt\xB2\x93$\xF6\x885\xBE4\xCBxfޮ\xE85C\xCCe\xFB\xF4\xEC\xF3ԧ\x97~\xAE\xEF8p\xE6\xA96\x91R\xF3#\x96]\xDEn\xB3\xCD\xE2\xC7\xDB\xB8\xF2\xFBߎė\xCFL\xF3\xE6\x90`ˌ.\xE7\xE8?'\xD6m9{\xBC j\xD53\xD2\xCDM 7% \xFC\xBBlY\xD2\xF7\xD77\x96~\x94\xE6x\x84r\xD3\xE4}\xF7\xD5Ŋ݀\xDC}\x97\xCEk[\xC5'~U\xF9d\xAF\xF8\xFC\xB2\xBAt\xD6\xC7\xE7\x9D\xE1UG\x90\xDA\xC3\xD4m\x9Eh\xEB\xEF@\xC6 \xFF\x9CYz\xD4s\xE9\x92\xF6\xB5\xAB!NE!\xA6\xE3$a\xF7\xB5*\xBF$幇\xBF\xDA\xC0\xE6\x9E\xE9r\x8A\xAB\xBA\xEEq\xA5WG
\xBD\xE7ƀ\xD1\xC1\xE6O\xA0&\x8F>\xA1\xFA\xE9\x97\ s\xD3\xFE\xD4ȡ\xE6\x8F
\xFFq#\x9BlߚiI\xEF
\xD5/Hd\xFE\xEF\xE7̊YU\xE4\xB2\xF0\x83ɏ\x85\xC9\x80\xCF?\xB0u\xCF\xF4\xDF\xE2\xEBQu#\x80\xEC\xAC
\xA3\x9F\xEC\xC4!\xFDLjULjB\xB9\xCF\xFC%\xFD h/\xBF\xB2:\xE7\x95w{\xB5\x95\xD7)+\x86L\xEC\xF5XK\xB1&1\xFE\x95\xD57\x8F$\xE8\x9ElSU[&\xAB\x80H*\x8C\xBC\xC6\xC8ɫm\xCBq"H\xC5ԄI\x8D\x8B\xE90>\xE3녫>\xD8v\xD5fQ\xC0{s\xDAT\x99\xFE\xF6\xD8s\xCA\xE6\x8Enk\xE7\xF6M'J\xB7\xD4\xDD\xC7:\xFD\xC8\xC8\xCE*@}\xF2ؖ\x9A\xB2}\xF3=K|\x99|\xF2\x9FG\x9EYY\xBF\xF8\xD2B ͟\xEE\xEC\xCA\xC7\xC7\xEF\xAAv\x84r\xD7aa\xDBT\xA3\xCF\xFD~\xE9\xA9\xFD\xC7\xE3\xBF\xFF\xE2\xE8\xEC\xD5\xF1gwD/\xDDa}\x8C\x85F\xBD\xE2\x9D\xE83٦
+\xDBk\xC0@
\xE2\xDF
\x809*\xD4g\xAFY|:A_qZ\xC3\xDF\xFF;5eޑW\xDE>\xB0\xF1x.\x80\xCBU\xC1\xC99s\xB6\x844
+1
\xA6\xCD\xDFs,y\xCD\xD7\xDF]֫0\xB0\xFFص\xFD\xAA\xED=\xE3l\xC5Ee\xCFcl\xDA\xD2Ϻ\xF4\xFC\xF68\x8Deګ\xFD\x9B\xE6\xA9&\xE3\xEEohvm\x8A\xAD>\xCFaό\xD7F\xE8|\xBB\xEA\xA1O\x8FWq\x8BN\xAD\xF4\x86\xA0!]\x9AW\xCE_\xAB>\xA5\xB9+\xEA;\xDC;!\x844,>E]\xF4\xF3\xFE\xFC\xB0>\xA1\xCF\xF5\xF3l\xE1y\xED\xE8\x95\xD8B H8p\xF5<\xDAxU\xFCΕ\x9D \xE0S\xCF\xDE8x[:O\x9A\xAE\xE4\xE9,\xF6\xB6\xD3(T\xF8\xBC3\xB7\xDB[\xA3\xBCm;w&\xCFVEM\x83\xDDP\xBF\xABh\x84\xD4](w\x98\xF5P}\xFEުn?\xCC\xEBmq]4x\xD6\xC4g|\xB5\xE1N\xD5\xE2VNQٌ\xCDP\xE8K;?\xE1\xCDn
\x88\xFA\x8E\xEE\x8A\xD8a\x83{\xB5\x97\x82O9\xB3\xF8&\xAA\xEDH4exs g~\xFAa\xDAߎ\xDE\xD0\xE3\x83\xDE륇C͙\xE3\xC79
+o\xD3rp\x8F\xC0\xD6M\xDC
g\xD0\xF2
\\x84\xDD\x82m\xD9N\xAC !\x84\xDCaZ\x88\xE7̉ji\xB9\x8A\xED:\xDC=\xE5\xE7\xB2#
\xE1~=`\xF8\p\xE5\xCB\xE92`߆\xE8} \x80!\xCFu\xE0o\xF9\xA6Q\xA0\xEC*w\xE9\xB4\xE2я\xF9\x8B\x80έn9v-\xDD\xD9&\xD8n|ͽ\xFD \xB9\xED\xA8\xB3
+\x9F~\x{DDF2}\xDA\\xC0;_
+\xB9ce7\xF3,\xED=[m\xBA\x9D:m
PȵM\xE7\xD1\xC0C\xDB \x88\xFE-\xBA\xA6
\xFD\x9B \xC8>\xFD\x8A\xCD>9\x85\xA2]T_@\x97v\xD8\xF69\x9B!\x9BV\xBC\xB2a\xDE#\xCF\xF4\xEF\xD8%<4\xBCu`\xC7\xA1\xE6+\xFB\xB2\xD0\xFBO~;u\xE3\x8C^\x83T\xF63$\x84\x90\xBB_v\xA9I\xDC\xF7q\xF5\xD1\xEB\xBBw\\xBB\xAFA\xF6:Yj\x81\x81\xCF\xF5X\xB30"
+8|2]c\xB3\x8A3\x96\xA2\xF2_\xD3֦Mk\x83\xFD"8)\xE7
@MH\xA4\x81Q\x88Y'\xD1/}W\xD6)\x93\xEE\xB3\xEFŰ;S\xB2\x8BĦw\xB9:\xFFw\xA2u\xDAk\xFC\xA3\xFA\x88\xA0\xBB\xFE\xFD\xBB*ӡK\xA0+P\x94\x96\xE1\xC4\xF6C)D »\xB7t\x8An$\x9E([\xF2\xCB{\x83Z\xBB\x8B\xF2R\x93\xFE\xFCc\xFF\xC7kv~\xFC\xFD\xDF[\xF6\P\x97\xFE\xE0\xE6\xE4\xAD:u]\xFCٌ\xFFM\xBCӝ\ !\xC4\xE9\x94m\x82\xCA4\xBF
-\xEA>*\xD8\xC3^- \xAF)s[{^Hzk\xC3Mk\x80j8s\xB5P\xAF)>\xB3'I]\xF6MmHK\xD7\xA6Գ \x87 \x8E\x90VU\xEF\xE29vh\xD3;ڋ\x8B\x90J(Ĭ\xA3[\xBF\R:\xF6\xF03\xCB:V\x93\xDCM\xB9\xF9B}
/c\xEA`\x9D\xCC;x\xA0\xDC}\xE2G~\x8A\xB6<ԛGh\x976* \xF9\xF0\xF1\xA35e\x98\x92\x9E\xCF2\x95\xDDO\xBF:\xBAis5\xFF\x{2E72F9D}A\x83;\x86g\xDB8\xE0\xCD_\xE6\xFF|f\xF3\xD1k\x9B\xFF\x89]\xF2㞣\x99\xFA\xF2\x88Z\xF5
\xBAq\x94\xAF\xABD!N'\xB15}\x8D\xBAt\xEF-\F\xDA
>\x88\x95b\x8E \xBF\xD7g\x86\xE0B\xFCg\xA9!Q\x8D\xEC*ݷ!f\xFA\xBB'\xB7&`\xED\xA8\xE5l\xFC\xEAؔ7\xBD\xB7I=d\G\xEBIv\x8AH\x8F\x8E\xFB\xFC\x9B[%\x95\xCA#\xE4N\xA2\x86t\x87U\xEA۲`Φ\xDE\xDB_\xB3
B\xC9\xE3\xEF\xBEt\xE6ѕ\xE5:e\x96\xB58*[t\x90\xE0\xEF\xD2 at J\xF2\xD2\xE0 \xEB\xB4Q_\xC5ǀk\x8BvCp\xBCܽ\xD8>\x9DYF,Bх\xA3_T\xEC\xE2x\xED\x973E\xB3#]\xAD\xAFj\xDE\xEF[oԸ[YǮ\xA9_\x89\xF2\xE8\xB1cR\xDA#__\xA92\x9D¥D\xB3W\x9C<v%\xB6\xA6ϭC\xD3q\xBF\xF9\xEA\xB7\xE6\xF4\xA9\xB2\xB9\x8AE \xD4\xF1\xB6\xA3\xD4#\xB0נa\xFE ګ\xFF\xDC\xFFA\xD6\xD7_\x8C\xEA\xE8 \xAD\xBA\xDF\xB8\xE5\xEF\xE4w\x80B\x88$\xB0\xE5\x9A%-m\xE6}-\xF1)\x9FDsDӼ_D\xA0\xDD\x84$^\xE6\xC1\x8F,s\xFEA˖X\xBE"G\xF6X1H\xA7\xE3ѳ\xDF2 IDAT\xC4Jyi\xEB3gI?\xC0\xA4)4@!\xB5\xE4\xDDN\xA1\xF5Z\xF3P\xDD\xF7\x8B\xA7\xA0\xB3:~=zu(\xED\xFA\xE8\xEA7\xAC-\xA2/ۮ\x8F\xF9\xAB3\xBBfFZ渀\x85\xBF\xCD\xFF\xEC\xC77\xE6\x98\x9C\x8CK\xD1"\xD4\xFC\xF3\xFE\x93\xC6O\xBC\xFA\xF57I\xF0
+j\xFF\xC9\x8F\xF5nV:\xA6\x99\xF2\xF1\xC9]\x96}p\xD2N\xF1\\xE0\x87\xF6\xDE5\xF7\x88u^\xF5\xFD\xE2\xA1\xD6n\x8A\x99\x9F|
Sy\x8B\xB5\x9BO\xBF\xD9\xC7\\xA26\xFE\xF4
+
'į9\x94\xF9n\x9F&\xA1\xBF\xD0;\xFF\xCC髧\xAF\xA7\xAB\xF5ps\x95{\xBB\xBB7\xF1r\xF7n\xE2\xE1\xEB\xED\xE1\xE3b\xAD\xF0\xF8\xB4w\xA7\xFE\xF0k\xB5QfNL\xB2>@i\xBF!\xB3\x8B\xA7\x93\x8A\x9Ez\xF0\xFC\x8F\x9F?t.\xA5P\xE2ծ_\x87\xA6\xE6\xB3P\x9D\x99ܚ4㻥\x9F\x8C\xEF\xDBD\x85\x8B\x9D\xBC !\xA4\xD1\xD0\Kإe_\xE9\xE7U\x87m%J\xA9\xBD\xB1/Y\xB9\xB2\xDC\xF0\xFAA\xC8mńt
Z\xDD\xEAz\x8F\x97-`A˼\xCD\xA6t\x8C\x8Ce\x99 \xD6\xF4\x82 F\x93\xC9/y\x9E\xE7MF\xDEh4\xB8t
]\xE1a3\xB6\xB3v\x9FCSMz{K\x94_|6\xF1~?7E\x85dEy\xB99i\xB1\x93_\xFD\xEB\xB25\xFD\xFC\xA5\xF3'\xB5-\x97L[\x\xFD\xE8\xC3W\ $+\xBE^0\xAC\xA9\xCD*\xADQ&\xB3\xFBc\xD6xbݗO\xFF\x96`\xD6\xC29/G\x94]\xEF\xE0\xB3\xFF\xB7\xF5\xD4u\xF8\x8C\xDB/\xCCŲ\xE8\x9B\xF9_}R~ k\xFD%_|5g\x90\xAF0\xEE\xF9\xE8ә1z\xC7\xF6\xB3\xE7Ly\xA1\x8B\x83\x9FP\xFAͯ}\xB6(\xC5N\x9E\xAC\xCD\xD92w\xF1\xCC'\x83$\xD0%Mya\xCB \xA6\xACľ\x8F?\xF2ɣ-+\xFF\xB2Q_\xFDw\xEC\x96\xE1\xA0\xC6\xFD\x8D\xA9\xF7\xABN\xCD\xFD;\xC36\x8Dm\xFE\xB6\xA5L\xC5%\x95\xD3\xDBn\xE5\xAC\xF4\x95V
2\x82\xFD\xF4SqIu\x99TSb\xA5\xFCk\x9Ba\x8D\x9B\xDF\xE1\x8E\xE4y\xFBr\xBE\xC3\xE9k\x9B\xC0\xE9\xD6Xg\x86a \xE8\xD5j\xB5\xAB\xAB\xAB ð,kN\xC30
cU9\xB7҅#\xFB\xB4\xAE\\xA2\xE3\x8Cz]^ \xEB\xE5q\x87d\xBBEgIT\xEB-\xA7c\xB2L, \x86aX\x9BqLm\xCEIS\xE9\xEC3F\xB0"\x8E\xE38Fā\xE5X\x96eJOb\x865\xFFX\x86\x81\xA8\xF4\xCB\xC5z\x86\xB3\xC3\xC0zn\x97-\xA97B5k\xA9\xD3.I\xBF\xA6>\xF6z'\xBAz\xA8\9o\xDB>5\x8B\xE6\xFC2`\xFB\xB3a6R\xE6\xA2\xF6s \xE8\xA7\xCF\xFA.\xE0\xCB\xF1\x91^\x96\xB0R&\x81/9\xB1\xED\xC7w\xD3{\xFC9= \xCF\xEBy
\xCFC\x9Fg\x89={\x86*݈;\xC77\xED\xD5\xF3
+yvr\xD9\xD3\xCCs\xAF\x9F]\xF0\xDE\xF6=%U\x9D\xFA\x9D\xB1y\x83|\xBD\x90\xF7E\x8C\xBE\x8A4v,[\xBAf_\x8F./m߮YU\x95O\xB55j\x8B\xF5\xB9\xE9qG\xAByܸ\xD5G_\xED\xED\xF0V\xB7[\xB7*\x8C\xE1~\xF0\xD7
]\xFF\xF2\x9E\xF4H\x87\xCE\xC1*\xC7 |Vj\xFA\xC11;o\xD8\xF6C\xC8_\xB2\xFAw\xA7\x9C\xFD\x84ҀD\xA9\x97\x8F\xBFˋ \xA4n(Ĵ+{̘7m\xE7\xED\xFC\xB6.\x9B\x8C0b^\x95?\xBE\x8B
\x9F\xF0\xCE\xC3v\xED\xEA'\xD6\xE9Q\x90\x93\xBE\xF7\xEF\x84+ \xC3\xDC\xEAyl;\x8A\xF5\xD2C%!\xA3\xA5\xC1\xDCY?\xED\xE0\xE3;\xA6sH;_\xC4
S\x92s*\xF6\xB7\xABz\xA0\xBAq.\xB4T\xB8\xF0\xE7\x91\xDA>\x9F\xE7\xFC\xF1SS\x8E\x9F \x85Ko7Nht<t\x86\xAD!SW\x92\x98m\xA8)\xA9\x97Ƽ|\xC9\xFE*M\xD6\xD7?\xEF\xFB\xBA\xEAVIB!\x844vb\xDE \xFC}\xE2\xCFJ!TF\xB1\xDDVƢ\xF9o\xAF\x9C_r\xA936\xFDe\x89B
+\xC2"
+\x92@\x97\xB8fkf\xF5\xE3\xADW\xA7\xA4\xF8||ž\x96B!\xC4qb6n\x91\xBD:=\xD6\xD65\xE5l\xCCژb\xC0e\xF5\xB4n
pe瞿Q\xEF^\xB4\x84B!uE!fcֲ\xEF\xBA\xD9}e \x86\xF6\xED\xBD~\xCDր\xE1\xFD\xBC\x80\xE2\xB8wʬqSB!\x84\x90ۇB\xCCF\xACEs\x8F\xD2ׯ\xEB\xF8)]@\xBFm\xE9\x963
+W%B!\x84\xD0\xD3}\xB5\xEB7\xF3*b\xD3\xF7sc\xA62\x84r\xEFY\xBByMЄ'\xFESh\L\x87\xDCm\xE3ÕNG\xF6\xEA\xF5\xC6Ȉ\xA6
4\x859\xFD\xF6\xE7\x8AS\xC5է\xAFm\xFE\xB5ZR\x9Fq+owzۭh\\xCCZ\xD4\xF9.u\xF2nK_\xB7<o_\xCEw8}\x83\x90\xD6Xg\xA6\xA1\xC7\xC5$\xC4\x8D\x8BI\x933G\x8F>u\xF4(\xE8\x8EoB!\x84\xDCM\xE8B9!\x84Bq2
+1 !\x84B\x88\x93Q\x88I!\x84B\x9C\x8CBLB!\xA4\xCEL\xC9\xF9\xEB\x8CQ\xA39\xF9\xD7\xC53\xA6
+i4\xBE\xE2vw\x90Qo\xAA9!\xCEF!&!\x84RW\xD97|\x97k\x9D\xBB\xF4\xE7\xD9Mg\xF2V\xAF\xBC\x98m\x9BF\xAF~\xEBݘ\xD4:eo\xD4\xF3F\xA3\xC9\xF6\x9F\xBE\xD6\xF1\xA2a\xC7ۇ6_\xD3\x80^\x97\x91\x9A\xB6qõ\xC2:U\x86\x90Z\xA1;\xCA !\x84\x90\xBA\xE1mI\xB0r\xE9Q\xE8Q\x92oP\xF8\xC8=]]Ǎ V\xD0'$i\xC1\xB1(. \xC4\xD9ɹZ\xA3 0\xC9T*\x8015\xFE\xA5\xCFS\xC6N\xED\xD6'Dj7wM\xE2\x95WV\xA7U^>db\xAF\xC7Z\x8A
\xAF\xA5X\x83yJ\x97\xB3\xE2\xF3k
\xEE\xA65\xBC\xE7\xF4S\xD5vo \xA9
+1 !\x84\x90\xBA\xC88rvc\x9A\xCF\xE2\x85m:\x83H!\xBE\xB5?z\xC9\xE5\xA6kf\x99\xD7j\x92n,\xF9&\xAF{{=Щ\xAB\xF8\xD4\xDED\x88\xD9\xF8y\xEA\xAEm\xF4 \xF2{\x9C~\xC1\xEAc\x97\x87GL\xEC\xED%\xB2l\x96\xB1\xE2\xEB\xBCq3Z{ \xE0y\x9Fȶ\x8B\x9E\xF2\xB5-\xF4\xDA\xD6c'\x8C\xB5k\xC84 bN J\xBFY\xA3\xB2~Q{>\xDAQY\xEF\xBD'\xA4bB!\xB5\x96}\xE1\xBA!\xB8\x9C:\x9F?\xB8\xB3
+\xD0
۫>\xD5\xDF6\x8DO\xD7Vύ\xF4\xB1]rr\x{161AED}=Jg}۷]\xF1\xB2\xEC\xFD͙\x85\xBD\xBD\xCCK\xFE\xBE~\xFE
+\xA7VU\xAC\xC4\xCEug\xBDF\x85uo\xAF\xF2\xEA
1ũ\x99R
+1 !\x84\x90\xDA1fߜ\xB7A=av\xEF
R\xF5\x8A\xCF\xFDz\xAA\xF9\xB4\x8E\xF9\x87d~\xCBCl\xAE_M%%\xEE\xF2)<\x9Dh\x8AU\xEE\xB7$0d\xD1
˴>5q\xC9Q\xE3\xD4\xF9!G*\xA1W/z\xFB\xE2M\xFB뤯\xBCۣ\xAD\xBC4%\\x82\xA4綜۸\x81
2*\xFC\xE1\xCE^\xE5OH\xFDP\x88I!\x84Ԏȫ\xF9\x9A%\xCD ~ӗ\xF8
Z}\xE4\xCBm;\xF3>\xB9My˶\x84\x96\xBB\xA76\xE3ȕ\xD32\xBFg\xBD\xEC\xDFh\xABOMz\xF3\xF3\xA4\xA8Q\x9D"
\xBC\x88-\xF1\x9A9\xB7\x9B\xD1\xFE:VaS\x83\xF7\xF7o\xFBX\x97\xFF\xF5\x{1F1EF6}\xB8\xBD\xB50*\x90\xC2Lr\x9BQ\x88I!\x84ԃ&\xFFr"\xA2
\x8B\xEC\xE3_\xFE+U\xC4\xC9E6\xA9\x92\xE3\xEC,;\xBB\xA3
\x95u\xB1\xFB/~\xB9\xB7\xA0\xFDЈ)\x9D
\xEF%\xC9*=\xECdf\x97\x817\x9Co\x9B\xB0\xF9K\x9AŞ-\xF0\xA1\xF8\x92\xDC~bB!u\x94q\xE1ڂ
+)\xED\x87FL\xEF\xEE^e"\xBD\xE6̾\x8B\xAB
+ץ\x8Fo\xD9&;\xFFFZ^ܙ\xF4]4p\xF7\x986\xBBW\x84o\xF9\xFB\xC49N}\xE6\xF2\x943\x97+\xE47\xE4\xBE\xDAUR\xEB
\xE5 \x8D\xE8\xE8SuZB\x9C\x86BLB!\xA4yi+?\xBCr>\xAE˰\xF6.U%˻p\xF1\x8D
+j\xF8\xF8̙\xD5ң\xDC%\xF2\x92\xC4\xC4\xE5[4}\xFA5}c\xB6\xA8\xAF\xFDq\x8B\xDAwm=e\xA4/\xACca\x8A$\xB8\xBA\xE3l|-\xABZ\xA2\x85\xA1\x8A\xEA\x84\xDC>bB!\xB5&R\xBA\xF5~\xAC\xF5\xD3Q~\xD5\xDF;\xE3Ѿ\xF5\xE2\xD7[xyى \xBD:w\ӹ\xBAm\xE5!\xAD\xA7\x87 $e\xB1i\xDBG:\xB7\xADeM\xBE\xDCM퇰\x84\xDC>bB!\xB5'r\x89\xEC^e\xE3\xA5
+\xCE˫a\xBFjY\xAF@e\x9D4 z\x80$!\x84Bq2
+1 !\x84B\x88\x93Q\x88I!\x84B\x9C\x8CBLB!\x84\xE2dbB!\x84'\xA3\x93B!\x848\x85\x98\x84B!\xC4\xC9(\xC4$\x84B\xEC[\xBByMЄ'\xFES\x98\x90\xCEC\xAB[
+\xA6\x9E\x82 \x98A\xC12o\xB3\x84)]#cY&\x825\xBD \x82\xD1d2\xC1\xC4F\x9E\xE7y\x93\x917
+\xC59\xA9\xF5\xAC!\x84\x90\xFF\xFE\xEA\xD5
*\x86 \x96e9 ,\x86a\x86aY\x96a\xAA\xFB\x9A\x8BS{ީz\x92{\xDF}Eu\xDE\xD6ۿ3+\xE28\x8EcD
X\x8EeY\x86Y\xCEc\x86a\xD6\xFCG`"\xF3Y-0\x96\xF5 \xCB0(\xBF\xA4\xDEլ\xA5VLB!\x84\xE2dbB!\x84'\xA3\x93B!\x848\x85\x98\x84B!\xC4\xC9(\xC4$\x84B\xEE^F\xBD鎔c2-\x9A\xEC\xEC\xDF\xBA\x96]\x9B\x8D\xEFT%IcB!&!\x84\xE2\x85\xDF8\xB0\xF9\x82\xC6\xE1\xF4&M\xA1\xA6\xB0P\x97\x97\xA71\xFF\xCB\xCE(,4VHc\xD8\xF1\xF6\xA1\xCD\xD7tu\xAF\x94\xB1\xF0\xF7\xAD\xF1ـ15q\xE3\x81*\xE3F͵\xCB\xEFl\xC9 c\xFE7\xC7\xC6\xDDJ\xF9lkFi+\xEF\xA6M%\xF5\xBA\x8CԴ\x8D\xAEֽ\xC6\xE4
\xC15t!\x84\x90\xC6\xCFX\xB8\xF9\xFD\x98C!AK\xDB\xCB-R\xE3_\xFA<e\xEC\xD4n}B\xA4UlS\xFC\xD3Ҙ\xE3Z\xD6E@\xA4\x80A\xADE\xF71]\x9E\xEB\xE8b\x9BH,\x83\xA1>\xD3
?\xAF
8\xFA\x82\x92\xCB銪R\x898\xD6\xD2\xEA$RM\x9C\xE8\xF7\xD3
+\xB7\xE7\xBA\xD8\xB0\xA9\xD2nV\xAC\xA4.g\xC5\xE7\xD7<\xDCMkx\xCF駪O\xC5IcG!&!\x84R/\x85\x89IKV'"\xB2劧$օ"\xFF\xB0\xF7\xC7\xE9\xAC>vyx\xC4\xC4\xDE^"\xF3RMƊ\xAF\xF3\xC6\xCDh\xED \xCA\xE7\xDE\xEB\xF7\x9C5\xBD\xFE\xDA\xE5\xE9\xDFh
)_0 bNT\x8Fڱ2\x80\xEC\xE6\x91\xF0\xF7\xA9%{K|\xDCE%:C\xB16cv
\x8A\xB5\xA2\xB13ü<*Fvw\xB3b%\x95~\xB3Fe\xFD\xA2\xF6|\xB4\xA3\xB2
u&\xF7
+1 !\x84\x90:2\xE6\xEF\xFD\xED¯\xED\x87w\x98b\xA3\x9Do\xFB\xB6+^\x96\xBD\xBF9\xB3\xB0\xB7\x97 \xE1\xEF\xEB\xE0o\xAF-\xB1\xF0\xFBo2\xBA\x8F\xE9\xE2Ui\x85X\x89\x9D\xEB\xCEz\x8D
+\xEB\xDE^%\xB1\xB3a\x8D\xAA\xEB%٬wĒ.\x90*p\xF6\xC7\xE8\xB8\xFB:\x8C
+\x97El\xDC\xCF'.\xE1_!T\xBF\x9B*\xE9\xD59bJ]\xEAI\xEE5bB!\xB5d4\xA4&gF\xFFsc\xD7C\xFB~a\xA3['g\xF9\xBA\xDAM( Y4\xC72\xADOM\r\xD48u~H\xE5H\xF1\xF2\xD63\xA7\xDDVTj\xC2 =\\x82\xA4綜۸\x81
2*\xFC\xE1\xCE^\x96\xCD\xF5\xEAEo_\xBCi\xBF~\xD2W\xDE\xED\xD1V \xFA\xF4\xBC\x9B\xE0*|\xD9kR3Ҥ^\xA1^\x9CD.\x95\xC8\xB2\x93LAC\$r\xE0s3\xACW\xE6
\xDE\xCD*+I\xFE\xC3(\xC4$\x84Bj\xA9$\xEB\xBB\xD5\xF1!\x84-
\xE0%G\xC2\xD6[i\xC6n\xA9֧&\xBD\xF9yRԨN\x91\x95. g
?\xBB\xFC\x84 \xC8<\x9EX\xB9\xE3\xA6A\x87\xFB\xFB\xB7},\x84ˈ\x8B\xFF\xFA\xFB\xD8][\xDC\xDEZ($^3\xE7v\xABxw\x90\xAB\xB0v\x95\xCCM)vi\xDB\\xD8ܞ\xC3Zw9\xB6O\xA79\xBD-U1f\xDCک\x95\xBF\xE3k \x8C\xF9\x85\xE2v\xD2Z\xEDf\x95\x95$\xFFabB!\xB5\xA4\xF4\x9B\xBFįt\xAE\x8A8\xAFt\xB5.v\xFF\xC5/\xF7\xB41\xA5s\x85 \x93\x8F\xFD+\xE6\xCB\xA6i\xF3\xFB\xA7_\x9B\xB3\xFAX\xFA\x98NOV\xEA\xC5h\xE0\x8D \xE7\xDB&l\xFE\x92f\xB1g|,\xA1\xAB\xF4\x90\xA3\xC5\xEE,\xBA\xA2\xF5\xC6
1 \xE1\xC0\xD9_\xF3}\x96\xF4.-E\xB3uYR\xF3:\xF8[;k`m\xF6\xAC\xCDnVQI\xF2\xDFE!&!\x84\xE2|\x9A\xEC\xFCiyqg\xD2w]\xD0\xC0\xDDc\xDA\xEC^\xBEb\x9B\xF5\xA6\xECĔ\xFF\xAD\x8E\xBF \xF3x\xE3ݎ\xA1r@\xD9z\xF9\xCB\xDC+_\xC5\xF3\x91\xCFuv/M'\x86\xED
\xE5҈\x8E>\x8E\xD7!\xE1\xAF\xF3\xC7\xDD\xFD\x96\xB7 ǖ\xA4d\xED\xFF\xE9\xEA\xCFg\xD8is;{X\x92\xE8\xF6\xAF\x8E\xDE\xE7\xB0\xFCA\x8C\xBC
\x9C\xA4$k\x9FV\xC6ص\xBC\xFAT\x92ܫ(\xC4$\x84B\xEA\x85/1\xE8\xF9\x8AK\x97o\xD1\xF4\xE9\xD7\xF4\x8D\xD9\xFE\xA1\xBE\x95\xC7-\xD2\xECZ\xEF:4|E\xBF\xB2\xF6>y`\xD8҉\xFC\x9Co\x92\xE9
Qz\xDFO\x89\x86\x9AI\xED3\xA6\xC6/9`\x98:\xB7\xA59\,\xC9\xD6\xA7\xE4\x9DZ\xBC0\xC4\xDAS\xB2x\xE3'\xF9\xF8-\x9E\xD3R\xA0D\xFD\xFE\xA2+j\xA0y\xAFp_\x87w\xB3\x9E\x95$\xF70&\xA4\xF3\xD0\xEAV\x83\xA9g\x82 &AA\xB0\xCC\xDB,aJ\x97\xC1\xC8X\x96 \x82`M/\x82`4\x99L0\xF1\x82\x91\xE7y\xDEd\xE4\x8DFCqNj=kE!俁\xBFz\xF5\x82\x87ʅa\x80eY ˂a\x86aX\x96e\x98\xEA\xBE\xE6\xE2\xD4\xF6Ɔ\xACD\x93\x9D_\xA2Pz\xC9o\xC7\xD3LL\xD9\xC9\xF9h\xAA\xAA\xD3\xED3&\x8D\xF2\xB2Z\xF1='/\x9F\x8F&\xAFX\xE4\xE1R\xBĄ\xE7\xF5F\xC8\xE5\x{19B7EA}\xDE\xCD\xFAT\xF2?侀\xA2:o\xEB\xEDߙq
\xC71",Dz,È,\xE71\xC30k\xFE#\xB0\x91\xF9\xAC\xCBz\x80e\x94_Ro\x84j\xD6R+&!\x84R/r/\xF7Z^Xv
\xEBX\xE7\xCCYy\xB9jU\x8C/\xC8=\xCA\xDD\xC3.\x92p\xD5\xECHջY\x9FJ\x92{=@\x92B!\x848\x85\x98\x84B!\xC4\xC9(\xC4$\x84B!NF!&!\x84Bq2
+1 !\x84B\xFE\xCF\xDE\xDBǵU\xDF\xFD\xFF/\xEA $ؤ\x84V\xB0B\xA5\xED*\x87 \xF6UA\xBA
+\xF3+a
+V!݈\xAE\xC0\xBA\xFE\xB8\xD1Y8\xC1\xAB\x91\xEA\xE4\xE6\xC1i\xB8$0+̋\xE0\xB7\xC2:I*T\x85G\x93W\xB2\x96YKf\x89\x906GɁ
\xE5\xF7\xF7(\xADu\x9Bz\x9E\xFF>\xE7s\xF3\xFEܝ\xCF\xFB\xBC?w
\xD7N\xC5\xE4\xE0\xE0\xE0\xE0\xE0\xE0\xE0\xE0\xB8\xC6p*&\xC75\x86S1988888\S\xFDf+\xF7\x83\xFBq
+|\xAF\xE0n\xF7\xE1\xE0\xE0\xE0\xE0\xF8\xF3ϸ݇\x83c5|\xDFn\xF7ᬘ
\xD7N\xC5\xFC\xCE\xC32\xECb\x9B\x8D\xFE\x97\x88\xB2\x96\xB6U%\x95&\xE6\xB2>c\x8F\xF1\xF2\xBE\xBEIX\xC6f\xB51 X\xDAf[R\xA6Kalf\x93\xC5\xF6\xCD\xCBuh\xEB\xBF^\x86\xE5\xF8z\xB21V\xAB\xED\xF2\xD5\xFF\xA9\xC1̽@X X\x86u) K[\xAD\xF3^5\xAE=qpp|g\xE1T\xCC%\xE6\x8E\xC6\xD6
\xEB|KWc\xF3B\x97\xAB\x80eh\x9B\xC5l\xE8\xD2\xD5T\x84\xBB\xF1\xBC\xF3\x82ǔ\xB7\xF7==, [Gs\xB3N\xA7ӵ\xB6\xB6\xB6\xB6\xEAZ[u=\xE6\x851\xD15I\x95\xE1
+\xF4QK\x87\xAA@յʑ\x8457\x89\xFCBOv\xE7lQ\xB4\xCEa-fˢ\xE0֞\xFA\x82\x82\x9F\x89U4\x9B\x97ı\xAAt\x9A\xF3\xC2\xF7\xD4W\xF2a\xD1\xE5\xED9\xB4\xB2\xA6KUz\xFB
\xEE@\xFD\xB7\xB7weߔ#c3\xB7\xAA
+J
+K\xFDP
\xB4幮+\xD5T qss\xAF\xE9\xB9*1d\x86'5\xCFd\x83\xB5\xF6\xA8J
+\xEE\xF1\xF3\xAE욍\x8D\xA5m6z!6\x9B\xFD\xC4b\xE8\xD0u\xCC\xD6\xD5\xE8\xD2\xD7J\xB6)l5{\xC2KZWQ\xD1\xF4)??y\xFF\xF1X\x9BQת\xEB\xE8\xEA\xEA\xEA\xE8\xD0ut4V\xECYȡ\xE5"gM%Iy\x86\xCB}ǰ,\xCB0\x8C\xD5bq\xAD\xD51\x86\xBC\xF0\xA4F\xD3\xCA]\x86e\xE8\xB9Ь\xB9\xA3\xA6\xB1\xE7*\x8A\x99\xA5\xADfcOk}e\x92O\xB4\xEBP\x97\xD1h\xE8\xE9\xE9\xEA\xD057\xAA
+2\x{1F8E79}\xB9\xE55/\x89֪J\x92
\xD2]]?\x9A\x81>u\x9Fw\xB9
+ U$\xAF\xC6\xCC_\xFE\x91\x92bA\xEB\xDC\xDC\xF2\xE6\xAFa\xB2\xB6+\xFD\xFC\x8A\x8C\xB3\x85`\xCA\xE4\xED\xEAb \x80\xB5v\xA9*\x9B\xFF}?}888\xAEĿZ\x80\xEFLW\xE3\xB6\xFF\x90Ƈy\xAD:\x88E\x9B2\xA2
\x8C\x8F\x98s\xFA\xF4\xBD\xE9x\xE7d\x84\xEF\x95&oj.\xD8"U.p"\xA5\x8A䄒\xF6\xEE;o\xDF\xEA?%\xA2\xB1FZ&&) \x91\x91\x92\xD2C*\xA6\xB4ziqiº\xF1\xAC\x9C"H\xEB
M\x81\xFC\xD9ء&\xAD>\xEB\xE1\xEA\xC5\xC0\xAC\xCCWdF-\xC3Ү\xD46ĵ\x8B\xBA\xC3KC&l\x80/\xC0\x9A\x9B\x82R at fh\xD5\xCF&FLI
+߭a#\xCA4anF\xB9\xF4\xE0~\xA7*\xF8J۬\xAD]ZNUt\xFA\x80e\x80\xD3 \x81\x90\xBF \x827Q\xAE\xA9{\xF4ȁ`\xFE2\x91 \x9E\xEB\xC4\xE4\xB8' \xCFuR
yM\xC5\xF7ny\xB5HK\xE2\xF5\xAF=g3jcA\x80
\xA7+\xCBQ\xDAI2\xB4\xCD1\x9BuB\xE8%$ \xB0V\xC3;\xEF
+\xB8\xAFu_\x90\x80\xBB\xFB\xE8\xBByJq\xF7\xA8\xB2ѻ\xF6\xE3\xF4\x88\xC0\xA6kl\xF9t4\xEE\x92%\x8B\x9A\x9A\xF9\xF8k\xD5Ԇ\xBC > \xDFsX\xAF\xF4\x91\x929\xD1\xC5\xD2ɲ@ t\xF7=\xDE\xD1\xD4\xE2\xB8\xC8N{\xEF\xC2
+c>x\xEDٔr\xFD\xF4ci\xC6I\xDCs筁\xFE\xF3\x8A\x8D5\xEA\xDEuޱ3\xCCkU\xF5q\xD9\x9Be\x94
+\xBD0\xDC&\xD7P
+\xBF\xF2\xB4YL\xE7?5N}\xF5\xD3\xD4\xE9JaM\x91[\x94\xA4'w\xF3\xDC\xE69\xE4\xF69ʂF\xCF
\xAD;vAS\xADg(\xA2=;\x95\xE5[\xEB:\xA2\xD69\x9C\xE0 \xD0u0\xB4\x94\xDA >Ѕ\x88\x84 \xDA^+͂ òN'\x84\xD6\xC0\x92\xA4v\xA1wY]_mjȒH\xD0K\xD9\xF7\xAE\xD4eX\xCB;\x82\x80\xC2\xD92:U-\xD7$Ȓ#\\xFA5v\xBC\xA9\xAA~s\x80\xECva\xF4\xEE\xFD\x99\xA9Q3\x91\xDB>\xFA}P\xEC\xAB$(\x89\xB6r\x97\xB3$\xA7l\xD4\xE7&\x9C.*\xB7\xB7<\xB7\xFF'\xA5\xFCՐ\xA5շ\xBC\xE2*\xFB\xABK \xD7o\xFB\xB06
z2˧\xB8\x93
\xB2\xF2\xF4\xAA\xA23\x9DJE]ˉ\x9A\xE6\xA6'\xFA\x80M\x9D\xA7,\xEDvl0*\xBC\x9Fw\xEAdb\x9C;k8\xD7t(\xA5H#V\xD4=\xB4\xA2
\xDF8\xD3%tM\x92H>;\xA4\x88e\xEA_\xFF&]\xBCbgW\x89<'\xADs2,j\xB5\x890\x9Fv\x82|.f\xC1\xEBޓ/&\xC1h\x93q40$p\xF5\xD5\xBC+\xAF\xBF\xEF B$ \xBC\x858\xE9\xFD\xAC\xA6\xBB)lax\xFE\xE9`\xFF.\x9E\xF3\x83\x84\xDD=G\xDF\xDD/\xE3z\xD5'\xF1\xDE\x97=q石rȶWR\xF9 \xC0t5\xBEun\xEDƵ\x9F\xFFY\xCBJ\xAA\x94\x8DI\xDD\xEAs\x91\x91\x8D\xB9U\xEA\xA7S#\xFC\xA7\xC7\xDAl8=O
\x9CN'
\xCFs\xEC\x82\xF8\xA8\xC7p=Ɯ\xD8H 4\xF5\xDFޑ\xF9\xCB.\xED
-\x8B\x9Aѕ\x88\xC0d\xC7h\xFF[\x87\x9F\x92F\x88\xAB(]f \xC3^\xA2Ԇ[^\x99\x8CX^\\xA6\xF1\x998 9\xD1~9s\x8E\xB9\xFDβ\xAA\xAA\xD0O\x9Fe\xA30\xB7\xAB\xDA\xCF)\xF5\x94\xF8p vl\xBA\xF8@\xB4\xBD\xE8\xE8`\xED\x96@!\x81\xE6\xBC\xCC\xC6\xC0\x8A\xE4`\xA7F\xEA-\xD7\xCF\xD4F,ȶ\xB8ʮ\xCB숡0\xE5w\x9B\xA5\xA2E
+h) һH\xAC\xA6\x9E \xFA\xCC\xF3)i\xA2\x8C\xDC͞\xFD\x8D
+\x94W,\xD6\xE9\x9E_K\xCB\x84
+\xAAg\xDDd\xB9\xB9\xE17ޭV\xDF?\xDDȄQ]vx\x8B3\xC8_\\xAC\xFC\xE42\xDDd\xDA:4h\xECҟx\xB3L\x9A#Gݠ3u\xB6I\xB2C
+q E\x80\xBAs(=\xCAay\xD14!\xCE/\xDE\xCB\xC9F\x9F}3\x80̚}\x94\xEA\x80\x8BɭIQ?\x9Dqu|v\x8C"ۆ\xBAb\xBD\xC1\x82 \xDD
\xE5\xA7V\x8Fv\xDD* @`\xB4]\x90w\xC9 ~p\xA2\xAA6Ѱ\xFD\xC2]\xF7T
\x88 j:\xCB\xCBN\xBD\xA7\x9FX7>|\xD8 \x9F\xDBx\x80K\x85 \xE07[:\xE2N\xBBn\xBA\x84\x89\xA0\x8A\xC1\xC1#\x9E\x9E\xBE\x90>!ݒ\xA0\xCFm8\xB2P\xBF\xB4tZykG?\xD4C\xAFR\x96\(*\x92t\x8EfG\xB9\xF8\xE0$\xFCo\xCB\xCE
+Y\xD6]\xA2zL\xA3\xA6
+\x84q\xC3\xFC\xD5m,\x91\x86\xE9\xC5\xEA$\x9D<\x87\xAC\xA8\x8B\xBB\xD4
\x94\x95\xA1\xEET\xA5G\xF0\x8Dɞ\x9C\xCC6V\xEEyo\x9BHW\xBC[! `\xECm'1\xA2\xAF\xAA\xEE\x8D\xADv_\xB7=3b\xAE\x95\xFF\xA4ģ\x9Dnbb\xEE\x98\xF8\xDC\xEB6qT\xB0p\xF5\x89Z\xBA\xBBzFF\xCA\xF3\x8E\x95Sb\x85B\xF1Я\xE3\x93=\xB7\xDE$\xE8\xA4\xC8NU\x95~\xF6HB:X\xAB\xF1M\xF5\xE6S\x90
\xAB|\xF1\x8C\xFAr\xA5\x8EЧ\x90dFq]\xDF\xF0\x91
+c\xA3`\x80+\xEF\xCF\xDFO\xBE\x9C\xF8\xEA:wnʑ\xE3\xDB\xA7b\xBAf\xDCdT\xB4\xC9n\xFF\xFC\xC2\xDF\xF5\xB9<N3\xDC>| f%㢇\xC4\xEB<W\xF0\xB0fȨG\xB2\xC6LO\xA5 2G,\x95\x8A`\xD0ST\xA4[\xFE\x9C:\xB2J\xE8ё1\xF0<
\x8EQ\xC7\xD0\xE8\xA5sF\x94\xD1\xD3N \xCE1\x88\xB6\x86
+A\xFA\xDF\xC85 \xB0\xDBOII\xD5\xF6\xA6\xF4\xD4\xDA\xCE߉x at E\xE7\xA8d:\xC4\xC4\xC8\xC7\xDA?\xB5h\xAA5\xE7n\xDC\xD4R}\xE7\xD6[\x85\xC3}\x9B\xEE\x8B\xC8+\xEA\x8E
L\xF5\xF5\x87\xA2\xE5\x92$ >>\x94~J\xBF\x8A\x95\xEBHP\x88\xAE;\xA9
+B2\xDBn\xFF9\x8F\xB7P\xB5\xE1\xA7U\xBB"\xB3\xEE\xBAe\xDE(L\xDB\xA1Wpja\xD3\x93:\xCE\xF9l\x9Dug\x9DX\xEBy㑩Q\x91RMj\xFBO\xEC\xF2#\x9C\x80@\xC8j\x92\xBC\xE5\x9B\xEFwi
+\xE5 \GBxDGD\xA4\x8008\xFC\xF6\xE0\x89\xF7\xB0\xF5\x91\xBB\xEF$y =d
\xFC\xFB\xFB\x85\xE5ե*\xC0iAi\xE7\xE8W\x8A\xDDsH9>\x9D\xF5\x90\xD4\xDE\xC9T\xD2\xD6$m)\x93\x8C\xF6fO\x87\xE7\xF1 q\xD1\x95E,\x92\x965\xF4V\xE7,t\xA2\xEB\xF7Ejĥ\xFD\xD8+bY|\xBE\xFD}QP\xC2\xF6=\xC5ٳ\xCB\xD8h'! \x9C\x8B\xB2
+\x87\xCD!\xF0\xF2ZZ\xBC|\xA1op\x98opXLjv!m\xB5
+|\xE7\xC9AN\xDA\xEF>\xB4'.:\xA0\xB7\x8E*K
+\x9B}b\xFC\x9F=\xA1'e\x8E\xDA\xE4\x99//\x9B0,sr2\x931\xD6B_o\xD5Ÿ\x9C \x90x^\xF6#\x91H\x81!
+#\xC5\xF2\xBD
+\xC0;IF{.ўǁ\xCD7\xDEt\xF3F\xEF \xEE\xF6\xC1\xD9\xE9'"iY{\xB2\xEF\xFAu"oO\x9E}lL\xE4\x8DW\xA49\xA4捝\xDE`\xA7\xC2\xD9\xEEG\x85 Xs\xEB\xAE- #
+\xAD\xE3`\xE2\xA2\xE2\xB2\xBC\xFF\xDAk\xDDZ\xAD\xE2\x8C\xE0u~\xB4u\xEF\xF7\xC0\xB2,@jP \x95 qFq\xF4X\x91b\xB1<@ W4P\x93g\x8B\xD1z\xE8\x9E\xD0"R=<\x99\xEEC\x93\x9C\xDC/O\x8D\xA6J\x88\x8D
͎\xF0\xA2
+5\xF7\x90e>$\xA5\x95\x92>\x90\xF7\xDCS7\xE1\xC4\xE7\xABN\x85e\xC9\xEF\xC4\xC4\xC4\xF5E\xBF\xDD>O\xBF\x84U\xB7;M#\xCDU\x9C:zt\xF0\xF4\xBCP^\xAEEn\xCBdY\xFC\xEA\xE5\xF1\xD6^:u\x8C\xA2($\xB7bgPJ\xDB\xEE]Wi\xB8\xB1\xEE-iZE]\x89@\x8F|\xFC\x9EiSE\x95\xFA\xE1ڍ\xBB4\xC9i-\xC5o\xBF\xEB\xA0e\x9D\x8E\xDA(> \xB6\xD2-\xE8\xD3\xCEу\xAEzʷ\x94/'\xC6?\xFD\xA8k\x9F[\xF6\x83\xF5jp6\xBE\xEF\xFCَG\xB6z\xB8||\xA1\xD3\xD0D\xFBg\xFEp:\xCDO\xFE\xF4\xD1\xD9-\xB7ݿy\xBA3\xD0\xEB\xA0
\xFC\xEB\x87bAo\xF5\x9A\x9EI\xF9\x92\xFE\xBFM\xC3;
^ox\xE3\x8C(\xED\xBEk*>\xC7\xF7N\xC5\q\x84X 1\x89
\xE0E\xD6}\xF8Ɂ_\xB0\xA6C\xC9O\xDD\xF4Bmj\x88 cn\xDE+\xEF\xFC\xD5;C\xF8\xF0A\xF4\xF7%Ɯ\xA2r=HY]uij\x94\xBF\xA1\xBE \xE7\xBD@\x8D*s\xDA\xCEc\xED\xC8\xDC\xFD\xDB{\x8FԦ\x86\x9D\x97>\xD6 \xFE\xAD\x8F\xF5Q\xF7\x8C9\x9D\xE0\xF1\x8C\xAF\xC9K(=Q\xB4ӋeU3x\xBC\x8C\x94\x9F\x8B #z \xA5\xBF\xDC7\xFD\x9E\xD1\xEC\xA3j3\xC3 ؇\xA4\xDA\xEE\xC7_\x93+Z\xEE\x94\xCBβ\xAC\xADU\xFD\x9A
\xA4\x98\xA4^=\{\xCF&y\x84\xBF b2ƀ\xD9ީ\xF9\xF4\xB9\xA2\xEC\xE9\x9F\xE9x\xBB\x93,8\xEE\xD8\xFF\xAE\xE2\xF0\xA7S\x87\xA5\xD7N\xA6\xD7\xCE\xCAУ\xDA\x99\xA5\x81X\xEDХ/\x80 \xFEܜ\xE3
\xB6\x93G\xF4⪊Y\xB5\x9D57\x8A\x82RȌ\x8A\xEAyT\xD8|u\x9Ei)N\xCB\xD9а/1d\xBAPX\xAB\xEE\x9D'\xDC\xDDwww`bb\x98\x98p\xDF\xF1#\xC9|-\xC8\xD2Q\xB9%\xA5\xBC\xB8m(1\xD8S[G\x99U\xD4\xDDKP\xBD\^P\xB2\xFF\x89]Q\x8Bg\xCB ߰\xC4\xE4\xB0m#\xE2\xC6\xF1\xC4DIR]\xFA\xE2a\xB9\xECw 0\xB95\xAD\xAE\xFD\xBEYqy`\xA9)x\xB1ׁ1\xC0c\x82\xCD?.ʎ\xEF\xB2\xB2\xE5U\xB9V\xD6\xF0\xDBE\xA3\xAE\xD3,\xFA\xD4`)\x89\xAC\xEE\x904M#n><\xD8\xD2\xD5\xE4>@΅\xA4\xA9j\xEF\xC8E\x8A\xE9
\xDD\xF69e\xE6\xB7\xA0cҌ\xB4\x84{wl\x8Fٺ\xC5WH}\x97~_ %\x9A\xBA\xFD2#\xDFx1u\xC6b\xCE\xFE3K+\xAB{a&\xB7\xAB\x92m\xCA\xF9\xC5P9\x80gv\xD3\xEB\xC5U\x9DG3\xA3|\x9B\xF9\xF8\x9B\xAD^>\xE3O\x80R\xD6\xDBk5GX
\x8F \xFB)\xFB at OQE\xA6˲p:\xE1\xEC \x8CI\xF5\xE2\xAB=z\xED\xD9S
+~\xDCB\xBE;\xEFzw8\xC1\xE3\x81?k8&|\xA3\xA6\xBE\xA8hC\xC9
\xB2hz\xCAB\xDC\xED\xCD'\xF8 \Xva\xED\xA9\xD9)'+ڴ\xFBb\xC1\xB0X\xD8C\x83\x9B\xD1Q\xE0\xF6l`ށ̐\x9E\xFA\x92\xDDQ\x91\xFA+ii\xF7聈\xE9~\xD4Z\x90\xA0\xC8\xE2\xB6\xDEB k\xAC)Rn:\xAA;H\xF4\xD4xG\x92\xEBg\xBEc-\xBA\xB2|*\xB7\xBF;\xDD`\x8C\xE8!\xD9( \xAF\x88\xF4\xEEҲHU\xC7>U\xA2p\xEBoQ\x9F" \xFB# IDAT\xCB?\x92\xB91!(NRZ\xE1m\xA2\x86<\xA9?\xE3\xE2\xF9\xC7\xEE\xEA썘\x9D{\xA1U\xBB㨌\x86\xEE\xB2\xE4i\xB9m\xBA\xF2rmC\xEEι
+XE\xA2\xBE\xF1\xA9\xDB\x8A4\xA0<\xDCϝ:JA*͏\x8BH\xD9\xE6\xBD-\xA4Re\xFB\xC3\xC9\xF8\x90\xE4\x82\xF6\xA5\x94\x91$ \x8A\xA2r\xFB'\x95
\xE1\x82\xE8G=s7{\x8E}\xD6[
+q\xFB\xB6o\xBF~91\xA2~\xC9hc\x97\xBE\xFA\xC0:A\xFC]7=\xFBC\xBF\xF5\xD7:
\xF1\x87\xE1|\xECC\xB6
\xF8\xCD\xFE\xFB\xA5\xDD\xF1\xD9\xF8W\xB3\xFF\xD2>\xF1\xD1\xF8\xDA\xEB\xD7 \xF301\xE6\x8F7qa\xA4\xC7\xEA\x91_\xB2\xE3\x96)
s\xE2\xF3N\x8A\x89{\xF6\xB1\xBEO\xAF\xC0P\xC2\xC1\xB12\x9C\x8Ayyl\xA5rC6\x80\xE3R\xABV\x9BT4\xBD\xBC\xCEi\xD4\xE8;\xF7;gf|\xF4\xCAѤ\xBA\xF6\xCE_x8/-:\xC1{\xB8\xFB\xEE\xB0m\xFA4\xF9\xAB\xBB*\x94\xF8\xE8\xA8\xDA_\xAD\x8F\xCE\x9A
\\xC5\xC5w\xF0}C¦\xC7o\xDEf0~W\xAA_KWM\xA6\xCF\xFEg\x94\xB8\xED\xAB\xD0\xE9x\xF3\x80V\xA9`\x97\x91z=\xE5\xCD\xCBBFi]U0
x\xF8\xC63Ց9R5Ք
\x801\xBD\x91CI\xA9\xED\xB3À\xE3\xC34\xF9M\x83\x8FFǗ\x95\xB9\xC0Ԝ\x995\xA4\xAE+\x96\x97\xDA
\xAB\x98c\x8C\xDA
+-\x86κ\x81I\xC3\xFD\xEDUO\xC5F\xE5H+\xDA\xB3c\xA6J\xC1\xD6U\x9D\xA6\x85v(i\xDE:\xC0\x91\xF7\xCE\xDFp\x83\xE7\xD8 at y\xB5\x96\x94\xE5Jn\xFB쳛\xB6\xED\x9AS1\xCD\xCDyA\xD2\xF2\xDC:\xAAP27\x8D\xDBS\xFB,\x85\xD2G\xC2\[\x877{\x9E\x93Fo\xA4U-E\xA9\xF1K<\x89\xA8SͪC\xC7oM| \xF1\xF1;\x9Ds\xEF\xFCu\x9B\xC8y\xF9\xE5\x81\xFD\xB4LY\x9E\xA6m\xBF\xD7\xCB
_tE\xE7\x9Fy:;^\xB0\xC2 \xB0v\xBC\xAA\x84\xB8\xF3\xFE\x95\xD7c\xB8\xA7\xDA㗥!\xFAO\xCE\xD3\xCA-\xAF&(\xA5U\xD4|c\xAD0b\x9FÞ\xB1h\x96\x9C\xE0\xF3\x87u%q\xFA\xA8\xAD\xF3\xB3\xEB\xFDXg[D\xDF\xC7\xEF\xB7\xFD.6K bY龼'\x93\x9BSD,hxlk1\xA9A\xF1\xD0\xF4$\xF2je\x98֒\x84" \x8A\xBA#y x\xAF84zg\x8F\xD5
+\xA4T\xFD\x83c\xFC\xA7\x97\xFF\xE9\xE0\xEE\xB4j\x90$(\x8A O<\x80\xA2(YU;\xA5b\xA2[\xB7G_:C^\xD8~G覿4\x81\xFAk\xDF_\xE0\xC10\xE0\xF3qJH\xC8oP\xE7 \xEBF'S c\xBD(4\xCD8\xC4D\xB8Z\x90\xDBS_\x99\xA6@\xBD\xA7\x99R\xD4\xC9\xED\xD1C\xE6\xEBI\x96\xB7\x94H\xA2 \xF8l\xFEYi\xFB\x91\xAD7\x8BD\x9EL{\xB3uU&(ɖ\xB6'\xE2J>\xFCO\xB9XM\xF9\x88H\xEFS7\x85>\xFB\xD6\xCFu\x99B\xB0\xD4\xDBJ\xF1L
+v\xB6@*\xDB0S\[w\xA6!\xDFH\xAB\xBD\xF8\xBE\x81\x9Ef- Mڹ\xE7;I\x90\xDE\xEBD
\x9E"\xC0s\x9D\xDF:l 7\xF3\xE7*\xBB\xABrO\x96^J
O\x9E]\xE8И
\x87ܖ\xE4\xB9\xC58\xABK\xB6?\xE4 Ȩ?*/\xE9\x94\xCA
\x90l\xBFU\x9B\xA3\xA4h\x81\x82\x84^{kKݭ\xFC\x931>5d\xE4\x93ӊ\x96\xB7\x8A\xEE\xF6sb\xB8\xFC\x9E\xA7>\xA3\x89]\x9Aζ\x8B<\xA7\xD3\xC9\xDBS\xF0\xF2\xD6\xC0o\xBF\x86 w\xAF\xE4\xCC|\xE9\xEE.\xF2\xCE\xFC\xE1Cc\xC4\xF6o\xFEF\xA6\xB3\x9D \x8FXb\x87\x9C\x85w\xDD\xF5\xCEe\xD3\xF5\x8F\xBE\xED\xFF\x8D L\\xFA\xCB'k\xEE\xCE\xFF{\xF0}\xFC\xF8\xF6[\xE6V\x83\xAF\xE1,\xB0B"
W\xA7b.\x83\xFA#\x85{z\x84\xB80\xA4\xD1\xEAŹu?
+\xB0d
\x9BǬ۸
dEwYv\x80\x98pu\xAB&\xF2\xDF3\xC7'?\xAC\x96\xCA\xE5y\xBF\xDFߛ\xEDe\xEBx\xB6\x88\x92\xA9\x8F\x86\xF0`\xF4\x93\xBFb]\x94\xD5l`ߙA\x8D\xE7\\xF9\xD9<\xAC\xA5K\xF3v\x9F\xBBp\xE6\x85A\xAC\x87\xBEIUo\x98Qh\xDA=\xFE\xA7Ɂ|\x8C\x8FH\xDB\xFA\xB2+w\xFC\xCA\xA2\xF6\xDEw\xFC\xB7'\xC1B¤
+\xDFB%L
\xA8\x9D\xCCx\xD9\xEA\x9Cz\xF1\xB3\xC7ɡh\x9Bm\xEB\xC4b\xEFe&\xAB
+\x8DydJyE\xB7]\xE6Y/\xA7\xC6WѪ,\x95\xBB\xE5\xC8\xD0\xEE\xF4\x9F\xEF\x97\xF0
+\x8E)l\x9ALmUu\?\xAD\x81\xB0\x96\xD6\xFB\xA2s\xC4\x9D\x89\xF3}\xF2C
+k\xA7\xAC\xA7\x86\xDEj\xFBK\xEA%S\xC9@@Lf[g\xAE$jn\xA9+kn\x8E\xCCї\xB6u9\xB4\xD9!\xAE\xF8\xAFڦ\x97\x9EoV\x94&DfA\xAAn\xAFH\x8F \xC0Z\xBA^~N\x99_\xAD\xCC\xEA\xD2\x9B\xF7\xC6\xE6\x8F\xE4*$p \xE8\x94\xE5Ti\xE7\xE4\x81kp} NH\x8C Oi~\xCB\xE5˃\xEE\xDA[$\xAE\xE8\x8CZ\xFDڈi|\xE33\xB4\xED\xCF\xB7M\xCBX\xFF\\xA4ݩ\x8B>1\xBEpi\xCD\xD8\xF3\x8APܾ0]aX\x94$,J\x92\x9C\x9E]V\xCBXL\xA7?8\xA6\xD2\xF4\x9C\xD2\xF5\x96\x949\xBAT\xF2%\xEA\xFA\x9E\x9EQ\xEAW+\x9B\xAE$*\xA1u\x94=5LhjU=\x94R\xC0'\xAEm\xA8\xF2.\xFF\xF8\xC4C/\x9D}\x84 at 0\xFAAqP\xDC\xFA\xE6\xAElo\x87\x93\x81,\x82 \xE1\x9F\xB8\x9Ez
+;\x8D\x89\xE0\x9F
\x80$+U
%bX|
+\xE42\x94}'3"\xDE
\xE6\xC0g# \x93\x85\xC6"\x931\xD7(\xE5\xE5\x944\xB7J\xB1\xFF\xA1\xF0 />\x9F`i\xEB\x87\xF8ul\xA8wː3~\xA6e\xB2\xE6\xCA!\xED\xDE*p\xD7#\xA9\xAE>ޫ#+4\xF1\x9F\T\xA9\xD6iĝ\x95\xD3E\x9D \xF98 4U\x8E\xA4
+:^\xA6\xCD(\xAC\x98\x95i\xF4\xBC \xB8mJ\xB2\xA6CG R*\xC6\xE1\xD7\xDF\xBD}{\xA4\xBBLJ\xE4X\xC8\xF6Ȼ.\x8E\x9Fl\xBD4\x95S\xB6\xA7\xE6\xD19Zuߨ\xE7;\x87*\xDDΎ\xB6u\xBC\x9C\xA2w\x8E\xC6\xCFmU\x892Fm>@\xCA\xEEݳ?\xB8\xED\x86PL|\x9EK\xA2\\xB81b_\xB2\x94\x87>\xAEx.3 o\x9DP\x99\xB0ef\xA2, 6
+\xA9\xDC9\xD9X\xBAjd~\xB5G\x9Ce!\xDF\xEE\xF1\xC7\xF9\xF7;\xAE[\x83/&\xEC\xF4\x9A\x8BcN\x93\xF1\x82Ńϲ_\xB1_\xAE\xB9\xF1f/\xC1u \xF0\xE5E[\x8F\xF1\xF3ّ\x96\xEFwC\xD8\xCDˬ\xC8Y
\x9Eo\xD7|\xE4\x93
}\xBB\x97\xFB\x92\xA7\xABT
\xE6\xF3Uj+6\xBE\xA34t\xDE
|$z~\x9F\xFFj\xD9`
_\x83ow\xFF\xB1\xE4])?\xBE\xA5\xB7.\xC0O2\x9A?\x9E\xEBr\x9B[\xC0B\xACt} X\xAA\xA8 at t\x8E\xD6(\x8F\xEE\xFC\xAD
\xD2w \x886\x8Bz\xDE\xDB\xD4\xFA\xD4\xE8;\xF6\xD5O\xE5\xE7h\xA7\xA6\xD5\xE7m\x88\xB8\xA2/|\xD6\xF9\xC59\xF39\x8F\xF53+u.\x9Ep~\xF8\xBCǥ\x87\x8B| x\xFE{\h
\x80\x81\xFB\xC8\xCD\xEC\xEB\xF8\xEF_<e\xB3k(@\xB6\xC7@\xD1ێ\xBCQ\xE80\xC67\xA5\xD5\xD0I \x9B\xAE\xE6u\xD3\xDA5z\xBD\xA2\xDB
\xBFx7\xAE\xB5\xB1`w\x8AR_\xD1>\x94
!\xA4{\xC6W!/\xD3\\x90\x90OI;O$\xBA,\xC7\xE0\xF8\xCC)S
mj\x96n\x91R2\xF5h\xF62\x9B\xA8'\N%\x84W\x88d~ k\x97<H\x8A\x8C\x86\xEC\xE5Ԏ9 a`b\xB6\xCA\xF9\xD8\xFE\x97\xF7\x92\xF2\x96\xEC)\xD3a?w18\xA9T\xAA\xAD\x93h\xA6\x87*AQZ\t7\xEB` \xF1 \xCA\xF3\x96|y\x88\xA0\xFF}M\xF3\x807\xF0y\xAF\xAEWP\xCD\xC1\x9AJ\xEE\x89֒\xA5C\xAE\xB2\xC9[\xB2\xBEp\x811\x89\xF3\xAB\xC4\xDAQ\x9AV\xADh\j\x86]\x8A\xB1\xFE\x99
J\xDC~"f\xBE\xA3\xD5b\x86p\x83\xEF\xF4\xDA\xBEpDr\xB6*\xF92Y\xB06\xEDNQ\xEA\xDA\xFEԐ9m\x95\xB2ݑR֒tG|\x98\xA0\xB9\xC0M\xAA\x94ֵ\xA8K\x9A
\x93I|\x80\xD0=Q\xA4~A8 짚\x9B\xEE\xE7c\xFC\x8B\xA6\x8ES\x97\x92su [\xCA\xA0 \xB1T\x9A&\xBEa~\x90\x8Dw&\xEB\xE3H\xC9)وF\xC0\xB1$g\xA6\xB7r\xE4\xE5\x9B\xDB\xFAO\xDC\xE5m?}擳\xD8\xECE}c\xD2_(\x95WS\xE7\xE8x\xFF\xE9\xCEگ\xD7@\xFAȭ|\x80\xEE\xD9%\x8A\xFCI\x9F#=d\xD1'}\xAA\x8EzBW\xCBHy\xBE\xB8\xA2{v9\xE2P\xCFI\x88\xE3 \x86d\xE0\xD8\xF9QD\xE9\xAE\xDA
J\xDA}\xFFl)2\xA7\xAAQ\xDC\xEEX\xBB*S:\x93\xEBJϟ\xBF\xF7\xF9'o1\xEC*\xCA?T|Z\x8A"\x8B/\xB4صZQE
\xB0\xE6Zyuq\xDB`z\x88\x97\xF1\xCCxN\xA6\xDC\\x94\x97+Z\xAE\x84\M\xA2\xB4j\xB7\\xD1P7\xA2\xA5
X\xE7\xEF7\x90\x92Ҥn\xF9\xF5\xFD\x85\xBA\x94\x9CORZ\x8A\xC9\xEA3\xD1\xF5< p^\xA2m\x83\xC5wm 1\xFAr\xE4>'\x8F\xEF'
hTU\x96e\xE5h at V\xB5
\xDD\xF2m|&>\xEFx\xBB\xD4\xFD:`\x8D\xBB\xBB\xB3\xE7o_m\xDA\xFC\x8F\xB7̀\xFBW\xF4\xE7
\x8Fdy\xDD<\xA5\xFA}9q~\xE8s\x9E\xE7\xB0\xF6\xFE\xA3\xF3&wլ\x8A9a}\xBE\xF0\xAF\xE7\\xC7\xEE\x91\xFB\x9B
\xA1\xB3\xBA\xE8\xAE\xF4\xE8m譫]\x9Fr\xDBw\xFA\xCCW4\xBFt:\xBFp\xCE\xD3\x97yc\\x875\x9B\xEE \xDE\xFB\x9Da\xE4\xBE\xFF\xF8\xFFn\x9C\xAF\x98N|z\xF1
\x88E\xE2\xB0\\xF8\x87\x87\xCF->\xDF\xF6z\xE2\xF8Wµ\x9Eeߓ\x90\x96?\xE81$\x8D\xF2\xEE\xEFJ\xE6\xBC \xE0\x94aa!paӜqp|\xD6<\xB0\xFDf ^Q\x8F\x95\x929\xF2\xDDR\x92ҋK;gWb\xFD:\xAD2\x8B,\xEE\xDC\xCE
$\xBC\xAAn\xA7\x8E\x8B\x8Co\x8C˒z+\xC5u\x9D\x9A\xD4(kW\xA5_ƥ\xBE\xAE\xC2\xC5C\xD5B\xF8\x81\x92\xF3\xE7\xFF\xADʡLŁŶ=z\xF4\xF6\xCCW\xF7t%F~\xACn\xCE\\xE7\xB0v\xE9\x91\x89\x9E\x864\xFA\xCF\xF2\xFC*r\xEC\xF8 \xCCšiP\xB4%\xFA\xA39\xD3[zV\xA1}\xAE\xE8&|\xE2I\xE9\x95 Aʌ\xAA\xFE\x972\x83\x85 XSǛOŦi!k\xE9\xB7\xC7O\xEDK\xBD\x9C>\xD6\xDAX\xB43EI5\xF4\x9D\a\xAD?K[\xDA\xEB_\x8C\xCB*'s\xEBF\xCBR\xBF\xE6\x94c\xD6=\xA7W\xA9\x92/;\x83\x80\xF0
+;\xD04\xF9\xE4̿\xE4\x83!0\xAA^\xAF\x9B2y\x88\xA0L
\x9B\xDA\xE5DQ\xA4\x8Bc\xB0\xA7\xCF\xF4\xAE_\xEF\xA04\xEFN\xE0\\xA6dh\x93\xEE\x97[⪑\xDB\xE78\xE0\xEF\xE2\xF9\xC8'g\xCD>"v\xEE\xD4j\x82 \xEC\xE7G\x96\x91\xDC\xDCz((!_V\xD5y\xD0\xE5\xB9<S\xEEP\xED\x8B\xCD\xD2(Zl\xAFa{\xA6\xE8\x91\xE5'\xDC_T\xE4\x82}\x97UWY\xDA\xDA\xFD\xC7\xDF+Rr\xF4 \xAB\xDA3c\x96MwټB$\xF1 m\xA8\x94*e}\x8E\xDA\xA2'
+
\x84\xE4;v;x<\x82\xCFw\x98E[R\xC4b\xE8\xF5\xC5\xFD\x8E\xC2`\x82eX\xD6\xE9t
+\x84B m6\xFCU[\x94\xA3-\x82bh\xB2\xEC\xE7wC\xF4\xF6C'sM\xA2\xA0\xF1w\x9A2\xF9`\xD9y/>I\xE1h\xFF\xAE\xAE\xB3_xe$(b\xD3\xD7/n \xC1\xA9o\xD8\xE1\xCC\xF5<\xEF4\xA9L\xAA\xD5h\xA5\x9DM\xD9Q\x80\xE3\xC0\x8Ds
m\xCDrmn\xCB>`9ը'\xD5\xC7]tZ\xE1\xD2Ȍ\x96\x8F\xF6\x85\x86>Ԁ,\xD6dO\x86s\xEB\xDE4\x8D\xA2\xA5T Ķ
R\xA9\xF4\xE0\xEE\xEE\xAB\xA3s\xA4jj\xF6\xA5ѥڛ\xA2!ۆw \xE8~\xA3\xAE\xB8\xFA݈\x8F\x9E<>A\xF8\xFF\xBA\xAD\xFD\xFA\xEB\xDDmm9\xA1\xD8\xFF\x83\x89\xA7\xB2q\xBD \xC1e\x93\xD37\xBC\x85$:\x87\xEE\x93\xC4j\x90qd\xE7\xA2ZXM\xA2\xC4\xCE\xEAn\xD16\xE7ޒ\xF7^\xC1\xC9\x89\x91U\xDEtFٔ\xBD\xEFsYS\xCF?\xA8c\x94\xB8\xEC\xDD\xF4\xA9#\xD7x\xEB\x84ʸ\xA0Y+&\xB8\x83:\xD6s\xA9\xA4\xB3\xFF\x95\xA8`\xA7\xC90Dc\xC5Ý\xFE\xEDq\xF7J\x9B\xFB&\xFCB\x95\xFF\x91do\xC4\xD6%\xC5\xEB|6\xFC\xF8\xE1
+S\xBF\xFF\xEE\xC5\xCDk\xE7\xC5\xE0\x93\xA3\x88\xFA\xD2u\xECk<\xE7\xD9:\x9D\xE3\x88\x87\xFEx3q\xC1hzEmhm\xFD\xAA$\xE2\xE65\xF3\x96m/
\x9B\xD59\xD9sgƱ\xCDE\x8C\x9F^d<\xB7=\xF2˭Kن\xBE\xB8>t\x93`\xC1'\xDB^\xD3g\x88\x8D\xFC\xE5=\xDF\xEAJ\xE2\xF8é\x98\xCB3>5\xCDx\xE0\x9D\xBEB\xA5[
mj\x94\xF8\xDD#FV\xA9J
\x96\xB9\xDE\xDAY\x97HgC\xE8O\xEA\xBB\xEEm\xE4}z\xF47\xD1zH_\xBA{\xEA%\xEE+++Ώ+\xA2 n\x93\xCF3S9\xC7$ﺕ\xE9
\x88\xD9\xE6O0\x94\xB9\xC5-\xDD\xE1\xED\x91\xD1 !\x8E^r\x9BX2T\xE0\xE8w
\xBC\x82\xF3 Y\xC0\x95m\x8F\xFA\xE0\x99}\xA1h\x80\xCA~}\x8E\xA6\x91u\xA46\xCA\x9E!br<:,d\xF6\x96
+\x8F\xB5h\x8B\x92 \xB6\xC1jw*\xA3\x84\xC0\xD6\xDB \x85\xB6-\xB0!n\x8B\xE8d\x9F\xA36\x840\x8EMCi\xCB\xE8\x81\xF8թ\x80\x8C\xB1\xE3\x8Dgb\xE5Z\x88\xB5}\xF6Đ\xA5o.\xC6l8m\xFA\xF5\xAE\xB6L\xA9\xA1 \xA9\xBA\xAD\xDF\xE5YQ\xB4\xCDʂ \xC2~q#\x86m4`A\xF8z-\x8A\x96\xE9i|12\xA5uê\xD4+:ntQy;\xC7g\xD8\xC9R\xAA\xF7\xC0\xF4\xFC\xA6\xA1R"[\xB0\xB6\xC1 b\xE3\xCF*~\x98\x9D<?9\x82\xE7\xCC7\xF1\xB2V3uLU,Wj!\xAB|%;Е\xF2+\x95B\xB9\x92N\xBA\xB14\xBF\xB8OZ\xA4\xCD]\xB8\xBF\xDB,m\xEA\xFE\xE3\xA1\xE8\x94j\xA0\xAA}(3f\xA1f\xCBkt:l\xC3C\x9F\xFF\xDA\xF5\xEE\xB1҄X
+ \xC4\xC5U\xB9)\x8ACfΫb\xAD=\x9A߿\xFB\xA1\xAE\xAEZKȭj9\xFAD\xBC\xEFrMt\x95\xB29\xC0\xD3\xE9`\xE11<4$\x82el\xE6!G`\xF0\x945\x93\xE0\x85 l\xC6Vyh\x8A\xB8\xA2[\x97\xBDU\x95$\xDA"8\xDF\xD2\xF7||\x88/\x9F\xCF`n\xCCJ\xA9\x86T\xD1ҽ?>\xC2\x8C1/\xAE<\xB7\xADH\xE0\xF8H `z^~\xF4ݝM\xE6&\xFD\xBD\x82\xA3\xE2\xBD
+%\xF7\xC5\xE9eu\xEF\xB8X\xA7\xCB0u\xB5@\xD6\xD0T\x9B\x8C#]QtMT7^\x8B,Gn\xF8t\xDBg\x8C\xDA|\x88\xBB\xEF\xF6 \xB8~=\xA8\xD7\xDF숼/d#\x9Cc#\xE7\xFA\xBA\xFB\xDCN\x97\x81[\xF2)2\x96\x97\x90\x8A\xBE\x93\x85\xFE c3\xD0\xF2z\Zr\xB4\xF1\xD3u\x92\xFE\x8A\xFAÝq\x91\xD5dn݉\xF40\xDAj>kx\xBF\xF6\xF9\xB4r=\xAA:\x87\xA7V
Ǘ\xF5\xC6=\xEF\xD1\xF0\xE4\xD9>~O}Ը\xC9G\xE08w\x96\xA2ƴZ3
##7\xFExG\xC4\xE2\x83\xCF\xFF\x98ZGߦ\xA8\xD0\xD0]\xC1\x83\xC7\xCC\xBC\x9AD\x83\xA3"\xC0t|\xD0UU.\xAD\xD0&\xFC5#\xB3Q\xBD;ʬ\xFC\x8A\xBEIɧ\x95\x99\xC7Ī\xF40\xE7%\xBA\xB8}\xB80\xC6\xA0+%{\x9C m\x97i\x9A
+\xA7\xAA\xFF\xD4a\xB2\xE5\xA1у\xAE\xCF\xF8\xF61\xF2\xD1\xD9
\xBE\xF7O.3c\xFDՐŹ>t\xBE\xFDq\x8Dp\xFDj'͝\xEC\x97 \xB1!$\xF8ץ7>\xB2\xFB\xE6:\xC1\xF5f\xA2q\x9C={Ժ\xF6W\xB7,\x999\xA1/\x94\xBF;\x9E\xF4\xA4\xCB\xFF❷?\x8F\xF9\xD9\xCCU\xEC\xBC5 >9\xF1\xD1[\x97|K9\xFD\x92\xE3\xEB\xC1\xA9\x98\xAEY\xD0A\xF9!e\xA3\x9D\x9FyG\xC7<\xDD\xEF,{ج8\xB2
\x80LJb\xE6\xF8L\xA0ɉ\x9E\xDE n\xA0Գf \xFF\xED\xBB\xC4(\xD2\xE7\xE6\xC6\xCES:\x83 \x84o\xFE\xC9U\xB2\x84-\xBC\xA9~Y\xFB\xD0\xCE\xFF\xF8ѡ<!?\xEC`W\x9FC\xBA%y\xDBhS\xFAe\xDF\xC7\xC6\xE6\xCA
\xB7\xFB
+\xEB\xE1\xC2\xCE\xC5In\xD2%\x83\xED\xE2վ\[\x86\xD5\xC1\xF3\xDA\x82\xD3J=\x85}\x97\xA2
\xE7\xCF\xDD\xF8\xC0o$\x87\xC5' \xBC\xC4j-j\x94J\xA1\xD5RȠvI\xC2\x87oL0\xF0\xCCYG\xE6p2\x98Vq\xC0\x9A[w%\xE8\xA9\xA2n\xB0(ե:\xE6t"I\x81\xCC-\xDE\xD7N\xC5\xEF[\xEEXPZ}\x9F_μ
+\xA5[f^\x8Ed\xC5܉? k\xD1\xED
+\x88\xD3\xC5
+\x94"9l\x85\xB6\xCERz\xE8\x97}\xCC\xDA\xD4\xC0\xDF\xF4\xB8\xD1 \x80\xE7!\xA2rH\xB7\xA9Z\xA0 \x9E\xB5bRw\xB2\x80j\xF6\xDCIJ\xB9U\xA5\xA2\xB0\xF1G@\xD3ھ3(\x8E\x82\xAC\xAE\xBD?5f\xB9->\xBC
+dե
+[T\\x8C!3\xEA\xF0\xFCz\xA6\x84\x80\xB4\x81N[Y\x91\xB6\x94\xF0\x8A \xA9BݯHv5\x82\xDF\xD7?\xD8\xD7?8J\x92\x98}PE[M\xA7\xFEt\xAC2MZt\xB2a\xB26y\xC6\xCFM9u\x9B\x8B\xF7\xB5(Y\xE1\xFC\xF5\xD5\xCB&$wWȂH\xEFj $INm\xE82\xFA\x9C\xAA\xAC\xCD\xF4nۻ\xFF[\x92UM!WݩL\x8F \x90\xD9d\xBF\xB5\xA6(6\xD4\xA4\xAC"/\xE5\xE9\x8F\xEF/\xE8z)\xD8_0\xA6\xAE\xFA\xBD\xD1izE\x8BS\xE2\xC5\xF6 \xD4_{MF\x93*\xE0\xB6\xEE\xB9TY\xB3\xEA\x89Y\xD5dU\x83\xEA\xD4\xE5\x8C\xDC\xC1 ҴX7
+)\x93A\xE8\xA3#IY)5\xFA\xE4̺M\xE6\xADg\xE4\xC8m\x99\xEA\xF2^Q?oW_\xDCK\xA6\xCD+
\x9E\xCAcX\xAAs\xF4>\xB3\x9D\xE8K
%\xE1\xB1E \xADj\xEB˔\xCC?h\xD37]\xD5+\xFB/v긣\x8E\xAA\xC4\xD8"*\xB7\xB4\xAE\xEF\xE8C!\xBE\x8Bd\xC2z\xBA\xEB7\xDC
\xEE4:1\xB4\xE9\xF6\xDBo\x9F\x98 \xC6ϼ\xD9A\xA6\xC6,1\x8E\xF3C\xA6\xDE*\x9B
V%\xCFo{\xABK\xD4 \xE1f\xF4\xEAE\x89ڇv\xAC\xDF\xF6đ\x84\xC8j\xA9\xA2X\xA6\xCF)\xAB\xC4X\x8Eg\xCA\xE0\x94Gw>slj\xF7\x9B\xF4\xF6{ \x8Chr
+\xB6\xFF\xEC\xF6&>;%/G\xDD\xFE+^\x92\xF8\xEF\xC9\xC8\xC7}\xBF\xBF\x98\x96s\xCF\xE5\xF23\xFE\xC9\xC0u\xE4M\x97\x9D\xE8qo\xC1Qc
a?pُ\x9CgO_z{$\xFEg;n^\xB8`\x93\xB6\x9C\xAB\xA80y\xDF\xBB\xC1Ů\xA0OZ\xA8\xCEu7\x96o\xE5 \xB1fl\xE83\xDDg\x8E\xFEe\xCD~ŝ\xD7|k<\xC7\xF7
+\xB7\xCDw&\xAC\xF4n_3\x81\xC9\xC9I\xE0\xAB\xC9\xC9\xC9\xC9)ud\xFAǴ\x8B۬\xBEt\x9Bv\x9B\x9C\x9C\x9C\xF1?999\xF9\xE5W_}\x85\xAF\xD8\xC9/Y\x96e\xBF\xFA\x92\xFD\xF2K\xE7\xA3\x96\x95\xFD\xC6ah+\xCD\xF0\x85\xBEK\x8F\xE2a\xDAF\xB3B\xDF\x9B,\xAD% Eu\xFD\x8E\xD4; \xB3itC\xF0\xF4\x89\xCBm\xA3V\xE8\xBBx \xC0\x9A\x9A\x9F\xAEGqa\xE2e\xBF(-]\x8D\x9A\xE3}\xE3\xC0\xBA\xE0\xFB\xE4\xA91\xAE\xFD3=I\x82\xB2gmP\x87\xFE\xCCk<
\xCF\xE9tb\xE2\xF3\xCFݷ퐄,x\xD9,Ə\x8D\\xEF\xFB\x8A\x9AĴ\xA8֞\xA6n\xFC\x9F\xF8\xA5g\xA4\xD3]\x8Dzϻv\x85->`z\xA1h\xC3_zZ\xCC\xD5\xC3\xBB\xBA\xB7F]~>\x8E\xB1t\x9D\xB95f\x99\xAD\xE6\x8C!\xEFG\xB2^\xF9Eiz\x94\xBF\xA1fO\xCE9\xF9\xD1\xFDw\x80e \xBF\xB2\xF7\xB7늚2# Fw\xA8x4Q\x91\xBC\xD0 at k\xE9in<9xܾ\xEBɼ
+ȴ\xD5\xCAsU\xDDWml~\xFF\x928~U\x9B\x85\x8B\xE9\x82 \xD0\xC59\x98+\xC3\xD2\x84W~\xD6\xC1\xC9\x80\xB1Y\x86.؝ \x8F'\x89DB/!j\x91\x98\xAD'\xF3\xBE\xE2\xE0\xFC\xEC\xDDJW(m\xE9\xF8c\xE3oS\x9A
<\x9E8\xF3a2u\xA4\x80\xA2\xAE\xBB85\x82 \xC0\x98*\xBF\xD1\xF5!@\\xF4\xB2"b\xCE\xE2\xCAt\xD4\xFC\x8F\x8D|p\xF66\xA9D3\xCF~z\xC9\xE9\xE9\xE9\xE9sS\xD0\xC2}H`m\x96a\xC2\xCF\xDFņ\xAA\x95\xA3\xB4\x9AG\x89@\xFF\xAB7\xE6u
\xDA\xF3ގ_\xED\xB0\xF5\\x98p\xE0\xEE\xEE\xEE|>1\xB8c\xE2\xF3\xB5a?\x8C_N\xADgW\xD5\xFA\xE8\xAE$\xE9q\xD9n\xC7\xC8\xF2
\x9AP\xFB\xED75TH\x8A
+&`\xAD/؛vl3u\xB2,L\x88\x9Eʤ\xDAmGʢLy\xF2j\x81$\xE5\xE9\xECDG\x8F\xEE\xF8\xA9\x8F\xED\xE3`\xE0\xB5\xF3GQW|Q\xD7\xD59\xF3\xF1z\xAF\xEB\xDD\xDC&\x815k\xD6 ֬\x81\x9B\x9B\x9B\x9B\x9Bۚ5k\xDC\xDCV\xE6\x8CV\xEF\xE5:\xFEX\xD9\xF5\xD6vg\xED\x90lv\xB1\xE4\xDA1\xF0\xB7ܪ,u0\xEB\xEE\xFF\xB3y\xF5\xBA\xA6\xF3\xCD\xFC\xF7\x9D\xF2
i!ˮ\xEA\xBE\xF0珊.\x82\xBF6=\xFD\xB6
\x9B躧jO\xFC\xEEcD?&\xBF\xC7\xC5i\x97_ZL\xFB*\x86\xB2\xF7ܱ~
+\x80\x91?T\xD0pq\xEB\xFF(p\xB3\xCFҍE
_2\xE0\xF3\xAB{\x83\xFF\x9Dk\xAE#\x82p\xBB\x8E\xC0b͚5nn\xD7M\xB7c777\xB75S&\xB9ẩV=\xE96\xFD
X\xE3\xE6\xE677`\xA1\xCB\xD7fK,M\xF3\xE0T\xCC\x96\xB7\x80"\xA9\xDAޔ\xCE\xCD:ppp|\xDBa\x96\xFF2\xBE9\xFF>2\xEE\xE5\xB3\xE1\x9B}\xB35\xF2\xF7K\xD8赒\xCE7\xE1\xB0\xD8\xD6\xF8op\xA1\x83~Iq\xE1r\xA7}\xE5p@ \x98}\xCA:&\xA7\~c|\xDFT\xCCo\xD1k\xE2[\xE3\xD8TZ\xDA\xF2\xF0Ü~\xC9\xC1\xC1\xF1
\xE0[\xA5_~\xB3\xAC\xBF\xF9\x9Fp\xCE\x9F\x9B/g\xE7v\xF8op\xFD\xE4:\xE1\xF5+\x8A\xB8F\xB0\xC0\xE8\xC9\xE9\x97
\xD7\xEEM\xF1\xCD\xC3N?p\xE0_-\xC7?\x8Fo\xE4*\x8E\xEF3\x9C\x8A\xC9\xC1\xC1\xC1\xC1\xC1\xC1\xC1\xC1q\x8D\xE1TL\x8Ek\xA7brpppppppp\c8\xF3\xEB\xC22ð
\x96
=\xFEO\x92\x85\xB6U%\x95&\xE6\xB2>c\x8F\xF1\xF2\xBE\xBEIX\xC6f\xB51 X\xDAf[E\x8916\xB3\xC9b\xFB\xE6\xE5\xE2\xB8&06\xBD\xDC3\x96\xB1Yl\xB3\xAD\x8F\xB1Zm\xCBT\xFF\x82\xAE\xC4\xD24\xFD\xAF\xEAX\\xCF\xE2\xE0\xE0\xE0\xB8r\xB8
\xE5\x97\xC5V\xB3\xE7\xBEsiͅ\xCB\\xFALUFE\x8EWON\xDF\xC9\x8FB\xE1\x98̾&Gj[:T\x87O\xFF\xA083j5\xF5Ě\x9BDA)2)\xB2ۜe\xF1 \xB0\xF3\xB0_\xA0\xFF\xFC\xE0֞\xFA\xB2F\xD3ie\xD1f\xED`Y\xE2eo\xB2v\x91Ns^dC\xF8\xD1\xDA\xF4\x90e}XtO\xE7\xFFy\xFF+\x82\x97/\xAA\xD2;r\xBCs\xB20\x8A\xFAo\xEFHP\x93\xC2 06\xF3\x897U\xA7|
+L^|\xCD\xE0\xC5Aqc-\x93\xAA\xF8+\xF8*\xB2@\xBAN\xFB\x84G͝O\x9B\xBBN;£V\xBE+~
+S\x81d\x8BRO\xAA\xBBO\xA4GL5\xB2\x8Aa\x9A\xF66\x8Cxz.v\xF3\x91
9\x98, \xBA1oϑ\x88 \xBB0r_º?\xBD7\xE0\xE9\xE3\xED-\xC0\xE8\xE8(\x80\xB1\xCF\xC6~\xF8\xAB\x97\x92]\xDC̹:XSI\xF2\xE1\xA47\xCA_&t\xD8>\xF0\xF6\xCE\xEB\xB6\xF7F\xB8\x92\x85\xFE\xE0ŀw&\xC6 \xA0
+\xD5~\xA4\x8Er4\x85\xF1\xC1\xB2\xD3\xF7\xCA\xCCD\xD2.\xF0~\xBEۡ\x9B:ǿ\xBDH\x94B\xF5f\xBA\xBC\x92\xAEI\x92\x8E\x97h3\x979;)\ϚeŞ\xF5o\xD0,988\xBE\xB5pV\xCCe`l\x8B\x95\xA6Y\xDA\xD4&\xD7P\xA1A\x9E6\x8B\xC9У\xABW\xD5/\xB2dx\xAE\xF3!l\x8D\x95\x955\xF5\xF5G^\xD7M\xD55\xF555*U}\xC7״g`Vfu9\xB9\xB2\xB4\xCD솸\x96b\xB1\xB9\xA5!SF \xD6\xDC\xC0\xCFl\xEE\x99;\xAC\xDEwk؈\xB2H\x98\x9BQ.=h\xBA
+\xB3\x90\xAD]ZNm\xF5\x99\xB2\xDF2M/\xB1\x94\xBC\x89rM\xDDgN\x97\xE1\xA7\xF1\'&\xD7y\xF0\'E\xDDk\xAAʒ\xA4p7\x81wP\xC2ёMޞ\xB3\xB5\xDAl6M[\xBA*\xCBQ\xFA8\xC9\xCC\xCF\xFA<\xA3\x96\xA5\xA3&\xAF\xA0\xA0\xA4`\x8A\xBC\xBC\xBC\xBC\x82\x82\xBĈz\xEB\xD5e\x81>MFG\x9F\x9A\xAB=\xFA\xEC\xD1\xE8\xE8\xFF
\x9A狵\x9A\x9B[\xA1\xD3\xD5<\xA4w\x8Fv> \xAF\xFD\xF8J
+\x84\x9E\x9C!\x97=\xBE\x84\x8C\x8C\xE4\xED3\x83\xB3\xE0\xAE̒#/\xBC\xF0\xC2/T\xFC*\xF5\xAE(\xF1㙏?\xB8\xED|Q\xD1\xE8\x83{
߳g\x8FL\xBE\xFB\xF6ٻ\x8AY\x96a\xDAf\xB3Z-f\x93\xC9h4=
\xAD\x8D\xF5:\xD32\xF6EB m\xAF\x95f\xA7\xC3\xD2_\xA3\xF1
+\xD7K\xC5Ol]F\xA9\xFAn\xAF\xBF
\xC0\xBC}(В7777
\x8F\x97\xD7l\x9A\xF2\xC3д\xA1\xED(\xEF\xE3\xB0\xD1,\xC0+˱o\xBBm\xB3Y\xADV\xABն@8v\xA8I\xAB\xDCxJ׳V׳\xAEu\xB3\xFCR\xFDf+\xF7\x83\xFBq
+|\xAF\xE0n\xF7q
+mP\x89ȬE\x8E\xA4XLnM\xFAME\xF6\x94 \x81\xB5t\xBD\xDA\xF8\x91Y\x97\xA5\xB4\xE7V\xFDl\xBBM\x8F{x\x8C\x9Fy=G\x89R\xF5O\xFC\xC6\xEDv\xE1
\xA913\xF7CZ\x87\xCE\xFFr\xEA\xC3\xF7{\xBD\x9D\x94\x9E\xA2@\x8A\xFBr\xF7\xFF4q\xD6TF\x9B
+\xA7G\xE0Ƀ\xD3\xE9\xC0\xE3y\x8E\xFDM\x9D\x82\xF6\xEEǯǘ## \x80\xEE9$\x8A\xCC_Fpi\xE7hSԼcz\x9B\xE9\xAD\xC3O\xA5i\xC5U\x94n\xC6DՆ[2R\x97^\xF3xY\x98\xC6LAJ\xF5"\xC7\xDC~gق\xCB\xE0\x98
\x89\xE0\x97J\xBB\xCE奁\x8C\xB9\xB5X\xD5~N\xA9Ԉ3\x8A\x93vl\xBA\xD4$\xD7o\xAE˽?d[\xE8\xD6-\x81B\xCDy\x99\xFB+\x92\x83\x9D5\x91|\xF9\x9B\xC3!\xAE\xB2\xEB2\xA7R05W\xBEڋ\x8D~
\x80\x87\x87\xC7Zw{JZ\xA4jW\xBB\xAF"L\x8FD\xF0˗f\xECg hC\xA5H{o\xF6l\x86c}T\xE8\xEF6KE\x8B"\xD0j) \xAB\xA9?\xA4\x87y͏p\xB9\x99jl\xA4X\xBC\xCC \xC9#z=U\xD1m\x97\xF3\xEAEdI\x92 (\x8A\xAAhi\xBF
\xCE\xCF\xCDG\xA5Yж\xEDv\x9F\xE0\x91;c\xFC \xB4J"\xCAZPn$0w\xA7{nC_YrXSA\xE4%\x85\xE5w.#\xF0Rc\x8D T>\x9DI\x92 E\x81zj6\x85*ʞ\xB9uX\xF5b\xFD\xF0hwQ\xEF\x86\xD2\xDD\xEC\xBCu026\xA7\xA2s8;\xCA\xD7֣\xF2\x8E<\xD2>\xDC\xE3\xB0\xC6L^h5HTP\x8Edž~ \xE5Kdc\xBA\xDF:\xB7v\xE3\xDA\xCF\xFF\x9C\x90\x92/S\xD3\xCAƤn\xF5\xB9\xC8\xC8\xC6\xDC*\xF5ө\xFE\xD3\xD2s=\xEB*z\xAEq\xB3\xFC\xF2\xB5n\xF7Y\xC4ʞ\x97{zu\xA1\xBE\xFES\x8E\xEF\xDC\xED>\xDF
\x84a\x99\x93\x93\x99\x8C\xB1F\xFAz\xFB\xA8.\xC6\xE5\xDD
+<\x9E\xC7\xF4}]c\xE3\xD8\xF8Hf\xAA`\xEB\xCEQboz\xBA\xC0\xB2\xCB0\xF0\x82\x94 \xB14#^'\xFE\xB1\\xE9\xB5~\xE2B\xF7\xA8Y IDAT\xF5[\xA94 +\xA3ϡ\x9A\x9A
\xD4\x8A\x96k\xA6^ր\x8F\xA5\x9Fb\xE5:\xA2\xEBN\xAA\x85\x80\x90̶\xDB\xCE\xE3-\xBC\xE2\x96O\x9CV\xED\x8A̺\xEB\x96y\xA2\xD26F\xE8\x9CZ\xD8\xF4ä\x8Es>[g\xDDY\xE7\xD6z^\xC5t\xA8\xA9Q\x91RMj\xFBO\xEC\xF2#\x9C\x80@\xC8j\x92\xBC\xE5\x9B\xEFwy\xD90o\xCB\xE1
!\x90\xC2\xE0\xF0ۃ'\xDE\xC0\xD6G\xE4\xF4\x90y\xF0\xEF\xEF\x96W\x97\xA8 \xA7}\xA5\x9D\xA3\xA2\\x94>\xDDsH9>\xFBopb\xF6\xC1\xC4y\x8F\xCD\xCD \xD4%/
+\xB9\xFA,8\x9D\xC0\xFC2Z\xA8\x8D\xF1CR{'S\x97
+f\xAAI\xDAR&\xED\xCD^\x9A\xF4r"\xDC\xFA\xC8\xE0\xE0\x8A X\x88\x84B"u\xA8\xE7\x8C\xE1M \x82I]\xFFv~Q\xB54\xB7\xF4\xBF\x9F\x95S4SV\x82\x9D/u\xF7\xF9l\xF4 \x85\x9FOX:*bsr\xAB\xEE\\xFBi{U\x93\xE5 @$-kO\xF6]\xBFN\xE4\xE3\xEDɳ\x8F\x8D\x89\xBC\xF1\x8A4\x87Լ\xB1\xD3,\xE0tB\xB8j\xB3 ?聾\xBE>
\x8F\xC1\xC8s\x91@\xA1\xAA\xE8A8
\x9CN\xA7O\x90s\xEB\xF6P\xF3\xA1"\xE8\xA5\xE3\xE1\xE5\x91YzEinN\xF4\x93w\xF4\xE5\xB5Dfeh\xFBc\xA6\xEE\xD3&nK;\xB5MQB\xF4T\xEEyw\xE0\xF8\x93\xD2\xF2\xBA~g\xEAt%ѕ\x92= @L\x8C|\xAC\xFDS\x8B\xA6Zq\xEE\xF6\xC0MA-\xD5wn\xBDU8ܷ\xE9\xE0\xBEȀ,\xB1\xA2\xEE\xE8\xC1T_\xAEg]UϺ\xD6͒\x83\x83\xE3{\xA7b\xAE\x80\xE5\xC5P9\x80gv\xD3\xEB\xC5U\x9DG3\xA3|\x9B\xF9\xF8\x9B\xAD^>\xE3O\xBE\xE9\x99F
\xED
xl\xE3ao\xB7\xB8ِ\xDEnӶ\x90\xD2\xEE\xD1\xA4
+
+\xD2;\xEE
+\xF6_8\xF6D\xC48c\xF2x[\x9E\xF9\x9F\xFDM\x99a \xC2\xD2k'\xD3kg\xF7\xA8\xF6Dfi V;t\xE9|\xA1p\xE9(f;yD/\xAE\xAA\xF0\x9D\xF9\x9F57\x8A\x82RȌ\x8A\xEAyTX\x8C\xEF\x9CO\xA6\xA58-gCþĐ\xE9\xEAg\xAD\xBAw>\x9Cpw\xDC\xDD݁\x89\x89 `b\xC2}Ǐ$\xBE\xF3\x88\xA5\xA3rKJyq\xDBPb\xB0\xA6\xB4/[G\x99U\xD4\xDDK\xCBN\xBD\^P\xB2\xFF\x89]Q\x8B\x97\x8D\xBEa\x89\xC9a\xDBFč㉉\x926\xA4\xBA\xF4\xC5\xC3r\xD9\xEF `"rkZ]\xFB}\xB3\xE2\xF2\xC0RS\xF0b\xAFc\x80'\xC6\x9B\\x94
\xDE
+㸭R.\x85\xAC\xEE\xD1%+\xF3\xAE(W\x85\xE5U\xB9V\xD6\xF0ۥ#\xEA
+\xBEW`\xA0\x97A\xB5\x87\xCC\xD2,\x8DQZ\xD1ݔ
1\xF5\xFB\xC4o
J\xA3@%\xE9\x9B,;P\xE8\xFBA\xD1 at Iف0\xC0\xE3բa\xCF)Ճ\x8E\x88\x98
+n\xEBQ\xC4権\xD1\xF40a\xFD
^\xD9
+\x9F\x9C\xE8\x9A
\xE9\xC1\xBEQ_ \xA0
+%{\xC8"\xED\x94wq\xB77\x9F\xE0\x83 \xF8W\xA4(\xF1}CB\xA6\xEB̪{\xBD H\xE8\xB3:\xEC?M_\xB0~\xD57&>\xEED \xADc{CC\xDB+ɒ\xE0d\x84G\x86FB\xD6\xE0L\x9E\xF1\xC6 <=\x86\xF2\xA5R2\xB74\xEC\xF3\x93\xE9\x81\xDEXDL\xE6\xC10\xDB;5\x9F>W\x94=\xFD!\xC8t\xBC\xDDI
w\xECWq\xF8\xD3)\Ϻ\x9A\x9Eu\x8D\x9B%\xC7\xF7N\xC5\\xA6\xB5$\xA1\x80\xA2\xEEH^\xDE+\x8D\xDE\xD9#C\xB5\x86)U\xFF\xE0\xC1\xFF\x9F"}\xE9o>\x900:99\xABX0\x86JɌN
\x98r\x89JNv\x9D\xFC\x90\xFB/\x8D-}bj\xCCR\xD7\xCBK펅\xD64\xD7\xE2\xB59Z
\x9D\x8B;0i\xB8\xBF\xBD\xEA\xA9\xD8\xE8\xA0
iE{cv\xCCTeۺ\xAAӴ\xD0%\xCD\xD5=;\xF2~C\xC3\xF9n\xF0
(\xAF֒\xB2\\xC9
+c\x9F}vӶ]s\xA1\xB99/HZ\x9E[GJf3\x8E\x9E\xDAg)\x94>\xB2\xCC
\x8B͞\xE7\xA4\xD1[ iUKQj\xFCҍ"\xEAT\xB3\xEA\xD0\xF1[H|\xFC\xC0N\xE7\xDC\xFA\xB2u\x9B\xC8y\xF9\xE5\x81\xFD\xB4LY\x9E\xA6m\xBF\xD7\xCB
_tE\xE7\x9Fy:;^\xB0\xFCr4c\xFD39zi\xFBp\xEA\xA2B\xBB\x82,8\x9D#\xD0_\xA0Y\x89!V\x85\xB5\xE3U%ĝ\xF7\xBB|\xBAr\x81l}\xE8\xF9\xFE\x9D\xCF\x8B{$O\xBF\x99߂\xFB~\xA5\xEE
\x9B\xB2\xB2\x8D
\xDF# \xD5\xE8h%IRh)\x80\x98Ԕ*}\xFE~\xCB\xE1Ȭ\\xED\xE0Ԕ}\xEA\x91\xCE7E\x87\xB3\xBA\xFB"\xE6\xCAƠ\xCE)֍N\xA6\xC6zQh\x9Aq\x88\x89Xa/\xC9e\xB1\xB4\xFA\xC5\xD5u\xB6\x9C:\xFC\xE9\xE3\xF2sd\xE8\xDEH{\xED\xFC\xD2eL-E \xC4ReZ\xCF\xD0d\xB2\xA9\xB522\x9F\x92\xE5fP\xE5)\xF2\xB0\x86ҟ'\xFB
оV\xA9\xEA\xF3C\xEFёҶ\xFEo\x95\xC4;h<x\xB20`.\x8D̏\xF0\x8D
JJm\x9F\xED|\x8E\xD3\xE47
+>
_V\xE6B@\xAEgͰ\xAA\x9E\xF5\xCD4K\x8E\xEF\x9C\x8A\xE9]ITB\xEA({j\x98\xD0Ԫz(\xA5
\x80O\\xDBP\xE5]\xFE^\xD3oi\x966\xBF\x{31E31F2}\xB4\x80T \xF9\x9D\xB7[\xA9T\xEC3\xA0 \x8A\xA2 x\xBB\xE5Wu\xDB3]\xC6\xF6\xA1dݺE\xAE\x86\xC6<2\xA5\xBC\xA2\xDB.\xF3\xAC\x97S㫨$K\xE5n92\xB4;,z"|\x83c
+\x9B&S[U
\xD7OO\xB8\xB1\x96\xD6\xFB\xA2s\xC4\x9D\x89\xF3}\xF2C
+k\xA7l<\x86\xDEj\xFBK겈%I\xC4d\xB6u\xE6J\xA2\xE6\xF6ɲ\xE6\xE6\xC8
}i\xFBQ\x97s`v\x88+\xFE\xAB\xB6\xE9\xA5\xE7\x9B\xD5\xA5 \x91Y\x90\xAA\xDB+\xD2c\xB0\x96\xAE\x97\x9FS\xE6Wk\x81\xB3\xBA\xF4\xC6潱\xF9#\xB9
+
\x80 :e9U\xDA9y j~l>'$Ƅ\x80\xA74\xBFe\x85\x82\xA0
+5\xA1iՀNf\x91\xFEpYl\xCA/\xAD\xB8i\x9E^I[?\xB9\xF12[8讽\xB1E\xE2\x8AN\x97\xEB\xE4V(\x90)\xCE
;Hʫg&sg\xA0(\xB2\xAA\xBB6s\xCA\\xC4R͵\xBC(\xC0\xE1p\xDC\xF8\xE0\x81WC\x80 X\x96*\x82e
,\xE9\#\xC8j\xF1L*¨\xA6\xC9\xC0Ɍ\x88\xB7\x87y\xF0\xD9\xC0d\xA1q\xD5*&ݳ' \x81,\xEDN\x8Děԙ\xADE\x83\x8CGm\xB0\xBBp\xD6\xFAx\xE2\xF0\xEF\xC42ix\\xF6\xDD\xE1ynJ m}\x92-\xA3\x8F?\xB0\x8F\x94\xE4C\xAA\xA8{\xA5\xF8A\x80\xF4\'\\xBBP\xFC\xF5~\x800\xF3h[\x96_l\xE3O&\x937\x9Ck\xA4컦\xE3c\x8F\x92C\xD16o\xBC`\x9DX\xEC\xBD\xCCd5׳\xAE\xB4g}#͒\x83\x83\xE3\xFB\xA7b\xBA掔\xB2\x96\xA4;\xE2\xC3\xCDnR\xA5\xB4\xAEE]\x9A\xD0\xF4\x98L\xB2`\xA0>U\xD5\xF4\x8Fp1\xB0\xFB\x85\x83\x99[
{P\xD3\xF4\xF1\xC6#\x88{wYh\xA8\xC1\xFD7mXA\xBFd\xBBj\x9E\xC9\xEE\xDE2\xCF\xD1\xDAX\xB0;E\xA9\xAFhʎ\xD2=\xE3ˆ\x9E\x83i.Hȧ\xA4\x9D']Vgp|\xE6\x94U\x8D65K\xB7H)\x99z4{\xB1\x9E1\x93\x80\xD3,\x91\x9A\xF0
+\x91\xCCd\xED\x92I\x91ѐ=\x9Ep!c@\x98\x98\xADr>\xB6\xFF彤\xBC%{j t\xD8\xCF]N*\x95j\xEB$\x9A\x83\xE9a\x86\xCACP\x94\xDD\xCD:XB@<\x88\xF2\xBC%FC\xF4\xBF\xAFi
\xF0>\xEF\xD5\xC2c\xB9m\x86zoR.\xAB\xD2J\x87\xCBcU\x9DÙQs\xE2]A\xFF\xD4\xD9\xF3\xCB\xE5Oj%Ⱥ\x95&\xFCXS\xC9=\xD1Z\xB2th\xB9\xB2]\xBE@\xA6\xB8I|\xA0\xAF\xEF\xC0\xA2u\x80p:\x9D\x82
+\xB3b\xED\xDF}a\xEE\xEE\xEEk\xB7ņ:\x9F\x8E\xDCR>o\x85(\x99\xDB\xD0U\xB6\xF0\xBC
\xA0&V\xD8xg\xB2>\x8E\x94\x9C\x92\x8Dh4 o\xB2X\xDA\xDC\xFD\xD1\xDFy\xFE!\xC1\xCB\xD65 X\xBB\xF6\xF8Ekr\xEC"\xC0tp\x82H\xAE
\xAA\x90\xF1
\xD4\xE8\xC10/\xD8z*\xCA\xC3;\xDB7\xFE\xCB\xF5\xDB\xF7\x94\xA3\xBC\xA8\ߔ\xB7;\x87\xA20\xA5\xC4HI\xB1a^;\x8E͏\xFE45\x8A\x8F\xFF\xB0\xBC\xD9\xE4d\xC0W\xD2Y\x8A\xE8_7O\xAA7\xCFn at a\x8CoJ\xAB\xA1
\x92 6]\xCD+\xEA\xA6 \xB4k\xF4zE\xB79~\xF1)c\Ϻ\x9A\x9E\xF5\x8D4K\x8E\xEF\x9C\x8A\xE9\xAFI<@*\xA5JY\x9F\xA36\x84\xE8I\x83\xFC\xE2\xC2\x82NnjJ6\xAAzw_\xBAA\xFE\xEEEq \xD86X\xE8
\xB0$\x82\xFD]*\x98,C\x9BϞ\xAA?W\xA4Ai\xDB`5u\xBC\xF9Tl\x9A\xB2\x96~{|\xB0X\xC5-km,ڙ\xA2\xA4\xFAN\xAE\xB0\xA4\x9E\xA5-\xED\xF5/\xC6e\x95\x93\xB9u\xA3e\xA9_s\xED=c\xD6=\xA7W\xA9\x92Wc\xEF"|\xC34M>9\xF3\xAF0$\xF9`\x8C\xAA\xD7\xEB.9\xC0Ce\x82\xE8ؔ\x8AAQ\xA4\x8Bc\xB0\xA7\xCF\xF4\xAE_\xEF\xA04\xEFN\xE0\\26]ev\\x8EFV\xD5Y\x9B\xFC\xA8\xD3O
\xED7\xDC2\xE8\xF2@\xD3+ʂ\xA1^\x91\xA6!̼ۖ\xCFB\x9Bt\xBF\xDCW\x8D\xDC>\xC7\xFFe\xFC\xCCgQ\x81L\xF1Ֆ8%)\x95\xFA\xD8\xED3N"\xB4Z\xBD\xB4\xCE\xD14\x954}|\xBF\xF4\xAF\xFB\xEA\xEE
?%\xA7\xBC{H\xF9\x8A
O{;\x9D\xE0\xF1FO\xBDkq\x94-\xB4\xDC\x9E$\xF0[uǎ\x99\xC9ܥ\xF8K
+G\xFBwu\x9D\xFD\xC2+#A\x9B\xB8~a.m]\xBB\xBC\xA3\xF5R1\xB4zE\xCB\xE0\xC1eN\x87\x9D\xDAQD**\x8Aϕ\x88\xDCR\xA6\xC5w\xCB \xABhP\x87\xA7\x90\xDE\xCAҶ\xC1\xEC\x90;\xEAڒ\xC3\xD77]B`D\xA2\x827\xA8\xF7V\xEAfΔ\x{DA54}\xC8\xF1Xz|`\xC3\xD4Z\xC1\x85De\xC3\xB4d\xFC-B \xE6\xE2\xD04(\xDA\xFDќ\xE9-=\xAB\xD0>Wt>\xF1\xA4\xF4ʄ eFU\xFFK\x99\xC1Bp=\xEB\xEB\xF4\xACo\xA4Yrpp|?\xE0T\xCCq2\x80\xA7\xD3\xC1\xC2+bxhH(\xCB\xD8\xCCC\x8E\xC0\xE09k\xA6s
S\xE3\x950$\xD5N\xD1"21i\xB27\x8B7 k>$\x97\xD7i\xF4SO\xC4\xA5\xED\xFD?\x8F \xCE>=
\x9B\x86Җ\xD1\xF1\xAB\xA8c\xC7\xCF\xC4ʵk\xFB\xEC\x89.N6f̆Ӧ\xBFQ\xEFj˔
+\x90\xAA\xDB\xFA\xD3%.\x96 \xD26+ \xFB\xC5\x8C\\xB6\xD1,X\x80\xE1\xEB\xB5(Z\xA6\xA7\xF1\xC5Ȕ"d\xD4
+\xABRW4j-fQSs\x8E\xCF\xFE\xB0\x93\xA5T\xEF\x81\xE9\xA5Z\x86J\x89l\xC1\x99\x87NV\xD1\xF0\xC3\xEC\xE4\xF9\xC9<`*
+\xDA\xD0\xFA\x87\xC2\xB9\xA4\xBA}p\xC6.HDe\xD6v\x91 Ah\xE9/\x8C\x9F\x9F\xEB\xD5g\x81\xB5\x9A\xBA(#\xA7\x9A\xCA\xD5\xF6K\xe\xADfꘪX\xAE\xD4BV1\xF8Jv\xE0\x95\xA4\x8B
+d\xFDzi
\xB6\xD0\xD9X)i\x9E\xB7_\xC6G\x9A\x99\x99\x81\x88\xDF\xE5< >\xEB6\xF0\xF9|>\x80\xC0w\xDD\xD28A\x84\xBC\xDCY\xE5
\xCB{5C]\xB2;\xF2\xB6\xB00W\x96H\xAF\xE0\xA8xoC\xC9}qzY\xDD;\xD7\xFF\xD1g\x8E\xEBs\xDB&\xCB$\xAC\xE1\xAF\xF0\xFD\xA2x\xD7Y\xFAW\xB5+2cXk\xF2OJy\x9E\x8Ew?\xD4{\xE4\xDD\xFD>N\xBBS\xE0\xEF\xE5\xAF\xFE"x\xDF?0\xD5t\xD7t;\x9C<\xE64
\xA6\xAD} !i\xF9\x8B\x82h\x9CVj%\xDD3\xD9\xE2\xFB\xFA\xCC\xE9?\xEB\xA77#mx\xACE\xFBX\x94\xB0
+V\xA3\xB8S\x91%\xB6\xDE(\xB4m\x81
+q[D'\xFB
\xB5!׳\x80\xAB\xE9Y\xC07\xD4,988\xBEp}%\x84\xE4\xEE
+Y\xE9]
+\x80$Ij\xFA\x8C\xBF\x8C>\xA7*\x84 \xC0X,>\xD5S3+\xE4\x85a\x99C\xD4\xCE\xCD} 7/\x8E\x8E|X\xBE\xEF&\xE9\x81\xE0\xFFغmk\xA0a\xE1\xC1e\x93KΗr2\x98\xDE^\xBB \xD6ܺ+(AHu\x83E\xA9\xAE\x87}\xE6t"I\x81\xCC-\xDE\xD7N\xC5\xEF\\xA6\xB2i\xF5}~9\xF3b\xE9\xEF\xE9_d\xC5\xFC\xC3wX\x8BnW@\x9C
(n\xA0\xC9a+4
f\x90\xD2c\xF9c\xF7X\x9B\x81\xF8ۀ
7:\xF0<DT9\xBD\x9F(\x88gm-Ɲ,\xE0\x9F\x9A=\xB7_\xCAܪRQ\xD8\xF8\x8F# \xF7 xC\xED\xAF\xDBu\x83\x8A\xD4\xC0\x85\xA3vD\xA6\xBAm\x98\xCAk7Ϫ\x98\xAB\xCF`9
\x90ORE\xD5\xE6\xCA:im\xDFGAV\xD7ޟ\xE3z\x8BϪ
+d*\xEB\x90#K>E\x82\x9E=](\xA5Ar\xFB\xCC\xFF\x84\x87H.!\xA1\xA7 x\x9E\xFA\x9C(I\xD3Ԭ\xF1\x88^q\xD5Ҧ\xE2\x95\xE9
\xBE\xEBͪ\xC3i\xD28\xA0tv\xDA
\xACY\xF5\x8BĬj
+\xB2\xAAA\xF5bK-o\xDD&\x94W\xB6>\xEE?\xFAZ>yW\xE7r*\xB408\xB10 _\xFF@ \xCC<6\xF8zya*5"&}\xDEY\xAD\x92\xB7N\x9F^G\x80(=5mfc\x9B\xB4\x88\xD7\xEE\xBCwo\xE3i\xE5\xC0E\x825\xD7i]\xBB-\xB0\xF7P\xBEx% ~X\xFC\xD4QU^b\xB5\x8C\x8C5J\xA5\xD0j)dP\xBB$a\x89\xC37&\xF8 \xB8\x9Euu=\xF8ƚ%\xC7\xF7N\xC5\"0\xBBv2\xA3\xD22t\xC1\xEEx<\x81H$z \xA7\x95C\xE6l~ \xA9\x81X\xDD}\xCBl?\xD1YP\xB4
\xA4\xA2\xE1\xE8R\xEBG\xB0$y%Md \x82M;Z\xB0t x\xB7\xB2A\xEBy0\xFF\xE5\xEDf\xFC\x88.\x87\x83\xF9\xB3g\x84ٽ\x93ٗ\xF3\x80\xF0\x8F=\xD2\xD9)\xB85*p\x85\xF5\xA5S)\xED\xEAl\xA7n]\xCE{\xFE\xB5_\xCA{E\xB2\xBCG7\x80\x87P\\xDCvt\xFF
`Y\x82\xC0ǯ\xEC\xFD\xED\xF4\x920\xDE\x{D94A}\xD1u\x8B\x9B(\xCF\xEFƍ\xFCAl\xDE\xD7v\xF4\x91)=#\xFE\xA0n\x99\xE3\xFBIao\xEFUe\xF0\xFFy3\x95\xC8
+q\xBD\xD8 \xE0+99<\xCC\xF3\xF5\xBDl_\xA6@ \x80\xF9[\xCF at n\xFE\xE1̰\xF5\xF3v\xF4\xF2\xC6\xFEvC\xB4\xC6D#f:\xA8P\xA6=\xFAr\x8C\xC0x\xB8\xFC\xB4\x8F +\xAA_ɼ,@\\xFA\xAB*\xF25\x97\xFD\x99\xF0
+K-T\xA5\xAA\\xA7Ll\xB8u\xC7>m惉.\xD4h~\x88\xAC\xBBa\xF8\x97d\xA8(Wݼ\xFC2\xD3\xC58&\xEC\x94\xE9</WE3\xFA\x89
\xF7\x80s\\x9C۠)\xB8\xCB9\xE6\xE4yCөޔ\xA5n %\xFE@\xA4z\xC8Fx \xE1\xE9Θ\x8F\xFD\xEFID\xD7i\x9EX\xBC=9,\xBDvtׯ>6Z\xA0x\xE1\xF6\xC8/\x80o\xE2\xF2\xD6@\xAEg\xAD\xA2g\xE1m\x96
\xDFy\xB8\xDB}88888\xBE\xC3p\xB7\xFBp|\xF86\xDE\xEE\xC3\xDDQ\xCE\xC1\xC1\xC1\xC1\xC1\xC1\xC1\xC1q\x8D\xE1TL\x8Ek\xA7brpppppppp\c8\x93\x83\x83\x83\x83\x83\x83\x83\x83\xE3é\x98
\xD7N\xC5\xE4\xE0\xE0\xE0\xE0\xE0\xE0\xE0\xE0\xB8\xC6p*&ǿ'\x8C\x8D\xFE\xB7>\xB2\x9A\xA5\xFF\xBD\xE5\xFB
\xC2.\xA9\x86\xFE7oE
\xDFa8\xF3\xDA`n.p\xCBld.\xEF X\x96e\xC6j\xB1p/\xFFo\xC6f\xB1ئ\xB3撤\xBC
zE\xFF\xDFtM\x92De\xB8\ڬ\xA5\xFEP\xA5aZ^\xB6\xA7QUY\xB2\xD7[\xF4\xB4\xE9\xCA[\x88\xB9\xA3\xB1\xB5\xC7:\xDF\xC5\xD2\xD5ؼ\xD0e>\x8C\xA9\xD1\xCDm\x8F\xC1u\xDBe\x8D
\xBA
\xB3m\xBE\x93YWS\xAF\xEB\xA89t\xE8i\xA9\xE8\x8D\xE6ű\x99\x9B\x93\xC2\xF3\x96\x89
+V\x83\xAE\xC3hs\xFDl\x9B\xAE\xB1~\x86\xC6\xE6\xE6\xB9\xEA\xEBuօbj,(h4^.BVW\x92Y\xD9*\x98`=\x9415&\xED\xA9_\xA1\xCB3掚F\x9D\xC9bc.S\x89\x97o!\xB4A\xE5\xE6\xDEj\xCC\xCD{$I\x99\x99\x99yyyy\x99\x99\x99{$I\xF5F \x98
oW\xD7\xC2h,'\x94\xF7\xFDR\x99
^\xB3|\xB8\xB6X:T\xAA.\xEE\xC5\xC6\xC1\xC1N\xC5\ \x96e\x86\xB6٬V\x8B\xD9d2\x8DCOGGGkc\xBD\xCE4\xF3"gl6`\xC4x7m \xCBX-\xE6\x9E.]͡\xBC\x82Â\xD8C\xD2\xCC\xA9<
O \xF8\xEC{\xD3\xC5\xE8H\xDB,f\xB3\xC5j\xB5]\xBB\xD74\xD3\xD9X\xD3j^\xF2\xFBj\x82w5֬\xA0\xAF\5,\xF3\xF9\xFC\x91\xD8\xDC\xD5x\xE8СJU\xB3\x85u\xF1\xEF\xE5\x84 \xF3\xF1g^\x9C9\xA3\xA4Q\xDB\xEB\xE2.\x97lV\x8B\xD9l\xB1\xDAV\xF9\x8Dp%\xB0CMZ}\xE0\xC6\xCB]\xDBB8\xDF\xCB\xCFi\x98jW\x84\x8F\xBB1\xA7\xC8S!.\xDF\xFB\xEA\xBCV\xB4\x9A \x8B*6\xE5Ϗ͏\xFB\xD3\xF7R\xA4\xC7>Y.e\xBE\xDF&)\xB6\xF9\xB8\xBE\xAA\xC6\xF6zl\\xE3\xDF\xFAȟ\xCBJ\xFF\xEC\xF4\xBE\xD8\xDA\x9EQ\x9Drи\xB0F\xF8\x81wFR\xE5\xBF?5\xA5G\xB2\x93y\x9E\x96Fˉ\xDB\xFF\xDE\xF9\xA5ɰ̼ʧ\xCF䥤\xB5\x9C\xA7'\xE8 \xFA\xFC\x9F\xA4\xD2#\xE7i\x9A\xA6\xE9 \xFA|i\xDA\xF3Fǂ\x80c\x96c\xC7>[
ݒ\xE8?.\xAA\xFE\xECr\x9EV\xDFC\xA7p^\xFAD\xAB\xF9̱\xDCc\xE0\x82\xE9/e)q[\xFE\xF6\xCE? \xAA*\xFD\xFFojFf\xC8
4\xD0 \xD1\xB2\xB9\xE4\x82&\xE4\x80k\xB0&CY0nL~\xD6u\xF9\xE1&4|c\xFA} \xB4\xE2ǺS\x86%P
+\xB5mA&\x8C\xA1&|\x8A\x8B
+\xA9\x93B
+\xC2\xE8\e.\xCCm\xF9\xFE\xC1\xAF\x99᧶m\x9F\xB6\xFB\xFA\xE6\xDEs\xCF}\xEE9Ͻ\xF7\xB9\xCF9\xE7y\x9Cl\xF9\++\xAB\xE5˭\xFC\xF7MhGN\xAF!\xDDo\xCAb@\x90A\xF3\xBB\xE7\xAFL\xC8P&$nsm\xCC\xF8\x84\xFFpBbB\xE2k
+\xEF\xF9\xE6\x9A͌93\xF9s]\xDDֽz A\xEE\xB5q\xCC"
+m9Z\x9C\xB0)$$$$\xC4\xDFSr~\x9DvK\x9DmFL\xDD\xCD\xC2\xC2\xC2\xF2\xEB\x81\xCD\xEC5!T\xBE\xBF0\xC6,0\x8C%\x8E/i\xF6ws@\x9F;hKČl\xF6\xE3+@"\x8D\xF2\xF1r\xF3!\xEC̪\xE4\xB8䴷ﱱ\xE1\xF3\x9C\xAE#\xD2%A\x9A\xF8\x92=\xE1\xEE\xA6E\x98-^J\xF5\xD8I\xBBS#}t'1u\xA9\xF2xىA\xB1\x83\xF9\xFFtu\xFE\xAE\xEF\xEE\xFBC\xA4\xAF\xF3\x8C7֥\xC9\xE3"j='M\xCD7%Ծ\xA1\m\xB6\x89Ȭm\x8C\xE5z\xF2\xBD\x9A2O&\xFA h-OX"\xCD
\xDA\xF9`x\xB0Ac\xF6s\x92\x84\x8E\xA6B\x80\xF3\xEFeXr\xA8E\xE9D7}\xD3\xE2
+\xCD\xF3\xF2\xE8\xA566\x9E\xEB7=\xEC9jPu\xD6'EE\x8E\xF6\xAD$J\x9D\xF3J\xB0\xF8\xF6\xAE\xCE\xBA\xAE\x{1232F3}̾\xF1\x95d\xA5\xE5e\x94\x86\xD4\\xF4\xF2*\x8D\xCF+\xD8\xEEiyN\xBF\x93\xA1\x90l\x87\xA7\x80s\xF0\xAE\xC5\x84\x9EOX:\xD453UHЗkA\xBClޡ6< .@\xB5\xB6\xF4:\xBB;s \x86a8\x9C\xB5\xA2o\xEA\x899\xA6F\xCA\xD8^\xEA\xC2'\x90\xA8
0k
+\x9B9v\xE8w\xDE\xF1\xA2歁\xFA5\xF6
\xA5\xA3\xC0C3\xA3\xC1-
\xDB^ே2C\xB5\xFAF\xEF\xA1k\xA5Ͻ\xA7A\xD2[K\x87/R\xA9\xD0\xEB\xD5
+@\xD4\xE8\x87\xD3r\xB9v \xE4\xF2g\xFDD<\xE8\xEE9P\xF4\x95ls\xB4\xC3p8]]\xBE
C\xD7\xDA\xD4v\xBD\xEF\xE4i\x92T
\xEEN\x9CT
u\xDA\xD6+\xFA\xCE\xCB at F\xD97\xB1b_ at WW\xAE\xFE\xE0\x93\xB6+e\xF1\x91\xBEf}0\x83;\xD4\xFEw\x82hn7\x86\xEA\xEC\xA2
\xEDMoUg\xFF\xD8\xC6\xC1X\x86\xA6\xBA\xAEt\xF5\xF4\\x{DE24}[\xBAд\x99g\xAA!u\xB9[\x92\x88\xA2\xC1\xFDᥛ\xAC
\x82\xFA\xA7mk\x9F\xADրtj\xAE=\xDA\xDBU\x91\x9E
\xE0q\xCC0\xC5\xFE\xDC\xF34\xE6\xB6I \xA09C\x89=1SE@\xB5\xA4I=\x94INAH\xB5<\x8E\xC8)
+\xB8^\xE1\xE3UP\x9B9\x9CJ\x94\xD26\x9D\xE9\x81
+F\xA3 \x97k\xD3w\xC5 \xB4}\xD3\xD0t\xFA\x8CX\xE0\xE59Yw\x96\xFF|\xD8\xDBB\xF8k_\xABo\xB6[`'\xF8|
\x8F\xD3y4\xD7\xC9/.>\xAF\xE4Q\xE7ٗk\xF2\xCA:\xAF\x95㉣\x8D\xC6g\xC1\xE1\x9CH=\xB1\xAE \xD1[h\xD3B\xD2\xD7\xC5'z[\x98
\x81\xB3\xB3 \xA3\xAD\\xB7$\xA8G\xA16\xA4\x9By\x8E\xAD\xD2\xC1+\xB2\x82\x8Am\xBEK\xE7\\xEF<{\xEC\xA3\xEC8\xF9\x89
\x91\xBE\xA2}=\xD6vXc=k\xFC\xFF\xE7\xF6(\xF7l\x89\xF4\xBD\xB5\xC3%<\xEEmKүd\x99\xEAw \xC0\xC0\xC0\xC0\xECŋ\xC1\xCC.)\xC2o\x86R\xBD3u\xEFdCQaL\xE4\x80a\xC0
4\xFB9#!P]W\xE7\x90{\xE5 ijN\x81ǽf\xF5\x92\xD9R\xAF=\x8A\xAA\xC6t \xDA\xCA4\x97 %\xA4\x8A
+\xD53K\xE7q;O\xD7\xA6ȥe\xB2A\x93\xE9<\xFAF\xE1E\xD9\xF6p\xC7I\xEE\x95I
+pzN\xA9?\xAF(TB\xBF\xC2y\x91K\x85ꡥ\xF7 \xBA\x9A\xA5o\xF5r\x8A\x91(\x8A\xA4\x9B\xA6\xD0\xE6<$;\xF8-"\xC5 \xDD\xDA\xF0兞>\xF79N\xF6\x82\xA1Jg\xAA\x90tG\x8B\xA1\x85"\xD0
+\xB9|\xAF8\x89T*\x84\xBE\xADMC\x92^VI\x80$O_
\x8D\x86\\xA1W\x9C\xC5U\xD8Z\x99mɬ\xEFM\xF4
\xD6;.LkeF\xF1\xD9En\xF3fa\xE0TE\xA9<\x8E$eE
P\xF5\xABm}Ƭt\x89\xA4\xAAԿ\xA0\xBE9\xD9\xD5\xC5\xC9<M\xB9\xCCәp6쩿\xAF\xF3\x9Aq \xB8\x8B\xAB\xCCəc\xB7\xC04=\xB7d\x80Ø5\xE6\xC4M\xF9WZ?ҽ\xEA\xBFY\x90٩AD-4\xEAZ\x8Bw\xEF\x8CP\xAA \x80\x90\xA9^ \xF7
6\xCD\xC6-\x89i# H\xE7̢:\x8Fnu\xF2+\x84,\xAF@
#\xF7[\xE4c\x88t7n\xDA;\xD4
\x8E\xEDB\x82\x94>
R֦ \x90\xD9;\x98hy\xAB2\x8C\xC1\xC8pm\x84v\\xE1¥"\x91\xC0TEf\xA4!-;C\xFC\x92Ԉ\xF2/\xDEWL-"\x90\xF1v\xE9՞3\xE2Em\xCD_n\xC2x\xE3D at J\x854X\xCCo\xADNݙ\xAB\x81\xE6\xA2\x95\xD2\xD7\xCEw-\xE0p\xF9hy+\xA8p\xF0<
\xC0\xCCP\x91\x80=\x94DA\xD7`\xA4=\x9A\xCA\xE4\xC46y\xB8\xB7 \\xBA>\xC0\xD6\xCBg\xD1\xEB)Ю\xD9\xE9#/$ `gGj\x86\xCCW?y5>E\xC7\xF2\xA7ͻ\xCE\xC2\xC2\xF2kbN\xC7\xCD\xD3s\xF4\x87\xAE!\xDF\xC9/\xAE\x80\xEC\x8D\x8A7q\xB3\xE6)\xEC\xE2|\xF6\xAD7D\xBA\xF1 p8<\x801\xA2-)J\xDE\xE4\x8A}\x9BFC\xE2\xB3\xE8塞\xE3\xDFO\xDD
+\xFB\xD6zɉ\x9C*\xF5V?\xD0x&\xED\xCF\xF4\x9CU\xB9\x91\xFE" ps\xF7\xF4
+\x8EJ\xA5\x86\xBCI\xE5\xC9[?\xE1\xAFv\xBBt I\xA5\x81$\xAA䵄E-%\x8A\xA5\x90\xC6\xE4dD:\xF3 Е;\xB7$\x92$ "J\x91\x90\xA8
\x92qB\xE8\xF2\xB4\xA7cH NR\x{DA87}מv\xB4\xE7\xCE\xFCp h(N{>\xF3\xEC\xD6{B\xDDo\xE1="Y
h\xE1
\xA2.\x9C$g\xAF\xF6\xA3\xA5T\xA1\xD4;C\xCF\xECt}*'z\xD6\xFB\xA6?\xB3\xC2Š\xB5Ż^\x8CP\x90\xC82_{c\xBB\xA7\xBD\xB9\xD3M\xD1|B E\xB3>\xDDD\xBA@\x89[\xBFЧ\xA0E\xE9\xEFnlx1H\x89\xA8"}~\xF8\xD0~77w\xDF\xE0\xA7_\xEA4\x9AVf\xB8\xFCuR\xD2\xDEG\xFE>\x89\xF7t\xB2
\xDF\xE8t_\xD0+j/\xBF\xAC\x8C
\xFEL\xA0\x8F~\K$2l;\xAC\xD8}٢
\xB7߅!"%9\xEDx\x862\x80$J\xE1~\x9D\x86:`\xA6
+i\xBC~\x98# x\xF7=\xD3L\xAE\xEE3\xC1嶼#\xCF\\x9FyD\xB9V4\xA4oĦ\x8E\xF6P\xAE
+ 8\x9C\xCBU\xA9DXvNM\xBB\xFC~\x9B\xA1\xE1jc\x9F\x91\xEF$@\x9D\xFB\x82D\xC8R
8B\x9C\xBC\xD8z\xDD\xDA\xDAڠ'\x95W\x90\xE8\xEA\xE24\xAC
\xAF:\x83
g\xC45Z\xB7s\xB9O\xD3l\xC2\xDD̃E\xB7\x93b\x85 \xC7\xD1\xDD\xD3qR\xFF \xF4\x90\x90\xC6j1@C\xC8\xF2c\xA5\x8D\xB1
`\xF2\xFDCoD\x96
+F\x82))<\xB8\xB0Uf\xA1\x91*Ե\xE4C\x8B\x84-\x87\xB2|\Z\xAB:R\xFC
At\xD9`4\xE8|\xFF\xDF_\x9FW't\x8A\x8B*\xA85FzsЭ\x95'u\xF5F\x9Aw\x8C\xA9\xEE\xD0qP \x82b3V\xA5\xCD\xDA\xD9\xD9ڊ\xC6\xFA\x9F\xD1\xEE\xCB\xC8.+\xCDV\x93\xE6H3\xCF\x908rO\xCDHC܂\xF5\xC1i\xD7ζ\xDD f{f\xB6\xF27y
kX\x85\xB9 \xD0\xDF\xBB\xD5 8B{O\xCF\xFB \xF5\xBD\x8F\xF8Ϳ\xF4\xA1\x83אQ.\xAB\xA8ZA\xD6\xF60\xF2O\x9B'\x97&:sf\xAAH\x9D\xD5YId\xFC\xF9\xFAH{\x80n\xF9R\xFF| yF\xD6gfy\xE5ݚ\xCCđ\xFB#\xF7\x8FVؐ\xBF\xC9+\xA6\x92Cu\xE4\x94O\x8E_\xBFy"\xF7\xE7\x81\xE5?\x87\xB6<\xFFs\x8B\xF0o\x8551\xA7\xA5s\xB7WL\xBC\xBA=R,\xBE\xA7\xF6\xA0pwL}\xB3\xD7\xC8\xEB\xBA\xA6\xE45D Yf\xCA\xFF\xDB\xF8\x9B\xA2'Jq6̋O\xA46ץ\x98zI\x8A\x93\xBD"2 \x90{
+\x87|FD\x94\xFA\xC0\xAB\xC1\xEECo\xAE \xC8\x90;\x97Į\xBA\xDFy\xC1|\x91H\xC0\xBF\xB6\xBE?S\xA8RF\xE5\xA8\xEB\xEB\xF7˃¼T at TQU틗D\xC8+|\xF6\x87\xBB\xC6ܛ\x90Y\xE3\xE3\xE2h\xEC\xAEK\xF1\x8BXb\xB05fO\xD2Ǽ\x87Bb\xA2J\xD5*bslԃ0\xDE5\x9Fg<;\xD3ù \xAAw\x86$\xA9S+\xCEߒ} !4\xEF\xE5[;\xA3 \xD0\xDF/xP\xEEk\xD7^\x98]\xB8ySb\xE0=N\xAE\x8DB\x86**$Vv\xFF]\xF6\x9C\xB8f?\x81\xCE4\xBE\x8BR\x92Zs\xBEÝs\xF9\xFDt//\x87k\xED\x83\xE9fü\x852u\xCDK\xEB|
9M\xFE\\xA2\x93651A\xE9\xC0"!ԙc\x85 at N\xF4s\xE9y\x8E\x8Ef/G\xBE\x8D5\xE0j3\xF9<\xCE)
+ЭđRrŨo\xCBp"B\xBE\xB0\xFDiO\xB7\xC0\xAC,\xF3\xA2Tk\xEEv)\x80ڳ\xA1\xEA\xDAf\x89\x97\xBB`\xD2[s\x85\x94\xA4>( \xC0\xB3w\xF1\xC5r]\xED@;\x88F\xAD%\x8E\xC8\xD1y\xCC\xDDv\xB1\xA7@ٙ\x9EX\xDFq'\xEEHS\xD8{F\xA7\x9B&-s*\xAB\xFBWy\xBA\x9B69\x877\9CS#\xF8^[
+d\xB6^Q])\xBEc\x8EZc\x9F~lH\x96j\xAD<ٷ\xC6_<\x81!bD4Dht\xFC|\x9B\xBE\xBEF5\xD9#\x8F>m }*\x8D\xBEƬ\xA8\x81\xD2C\xADT\xE6ԴW\x8F\xCC
+p\x8C\xCCjF\xF2n\xBF\xF5 IDAT\x9BGBi|c\xAC`\xB4Fh\x92"495
\xB1\xBE\x8E \xA0k\xF9\x84j\xA9\xA5\xCFq\xBA;\xD4=\xECV\xAC\xF2\x9E\xE8\xD0u\xF6ꪤ
+\xA5\xA7\x87\xAB\xD3|\x9F\xC7\xE1\x80\xEA\xACS:\xF9lQ\xAD\xAD\x8E
3\xF2\xA6\xD5\xC6n`\xEF\xEE/
\xEEu\xB0\xEE\xEFף\xFFF\xB5\x93 [\xBD6h\xD5\\xA3\x91\x8B\x9BsM? \x8E\xBD8t3$1\xB5!\xE1\x81
+\xA4$\xB3\xBE:\x91\xC8\xF5\x97\xDF\xE5\xFC\xA0̵\xF5\xD2\xC9R\xEEϱԨ)\x89!?ΐ\xE4\x91n
h\xAF\xAD\x80T6\xE4\xF0\xA5k#\x90\xD4B\xE5[4Jky\x82WLGAQ\xAA<S?\x81\xF1\xCE\xC2\xC2\xF2\xEB\x8351\xA7\x83\xBAX
+B%y\xA1
+\xBC\xCB\xBDM\xF66l\xB2\xF5\xA2\xF2\xAA*\xBAr\xCF\x85\xBA۔+!\xA9\xCFI\xF7\xCCO/w\xF8\x9F\x84\xEFu Z\xBBO,\xCF&\xA5\xF1y\x8AmO,w\xF1x
\x86\xEA>\xF1\xE1\x8B~
\xB6
\xC6 at Gx\xE2\xDC\xF3U\x8B\xFE\x920R\xBB$\xA7b\xCF\xD6 at w =\x88\x9C\xFA\xFCXO \xAE\xAA\xCCl\x9F\xCAZ}\xBE\xB7 \xC0{\xAE\xADx'*:[H\xF2\xEC7\xA8\xF9\xA0\xB1\x9D&gw\xAFYi\x87s\xAB%\xFE\xBE\xE2\xA1-3>\xBC\xA3|g\x9C4\xA9\xA7\xA8\xBE7\xDC\xF3և\xF1\xDB\xCE44\xF6`H侾\x85\x8E\xEB \xC0CsWn\xABVJp\xCEsT*\xB3\x9FTS\xBE\xC8|1\xEC
\xE8{\xBBտS@\x95\xD1ܙ\xEA\xEChz\x91o\xF0\xD0\xD8\xFF\xD2?Hp\xB8\xA5\xD3\xF1\x93\xAD
\xEF\xB9\xE6\xFD\xFESq\x85QE͎ m#$ޮ\xDA\xC7t]\xB1ꋫ\xE0t[5\xA0ޝ\x91\xBBl\xE8\xEB\xF4C\x88\xF5w\xE6͠ \xE6\xD0N9U&&\x8EDbk3\xEE\xE5\xDB}4\xC4\xC1O-ͬ\xEF\x88\xF5t\x9C\xEE\xD5<\xA5B\xF6^8\x8D9\xDE\xDD\xDAV\xCCw\xB3\xA9\x89k
+L\xBA\x90I\xBB?F\x93YRP\x96\xDA\xF0l\xD9\x8Ew\xD2\xD6
\xEFY
82\xDD\xD1\xD8\xD0\xC6q\xE5t\x95\xB9\xA9Aq\xD9f\xDB\xFC\xB6\xAF\xEB\xDD\xEF=\xAA \\x80 EQ|\xFF\xB0rI\xD0\xD5"\xFD\x84&\xA6`\xE9\x81\xFA\xFA>o^ V\xD8\xD8\\xDA
4\xD7\xD8.6\xCAlV\x8Cu]\x99&\x8D\xD1 \xB3\xA6+\xD6\xD7l*\xA6\x8B\x97\xBF\xC9\xF4B\xB4\x94f\xC4h\x90W\xDF=\xA2\xABT\xDB \xA1\x8BM{~&w\xA8S<;9Ή\xFB\xF7[l8zGH=\xDE#\xA9Xϑ3\xCF at C\xB8s\x97\xFB\xB8\xB7\xBC#\xFDrU\x89{\xC2
+\x84U6\x85e\xDF\xDBek0\x80o\xA8'4R\x99\x80\xE0py=\xAD-\xDAN\xB4i\xE0Ϳj9\xA1FNm\xAFeSO\xA5H\x99\x8D\x90z \x80\xEEP\x96:*%g\xF4\xF0\xDEK\xAD\xC02\x8BʚJ\x88\xB0\xEC\x9Cz\xBD̦XN\xF6\xB3\xEF\xB0+ʧ\x87\xCBȁIv\xB6~\x96U(-*\x8D\xF6w\xB2\xD0ך\xF27J\xA59\x9E< \xF6\xC1[%\x85\xCD\xC3\xCBX[?\x8A\x93g\xBBV\x9D\xEF\xFD@Ƚz\xE1\\x80#\xB0\xF7\x8D|5 //\xD2\xB9\xF9\xA7\x975
+\xBD]
͵\xA9RM\\xD0\xC6#1^FWql\xE6`ȑ Ʊ]\xBA\x86h+\xAE\x93\x87W\xDE'\xC7/]\xED\xB7 \xEB)\x9F\xF5\xC6~ \xFD#\xE6\xC2\xCC\xB7B$M\xD2 >\xEBv\xECK=$[\xD3\xF2\xB3\xF2\x87ٿ?%\xD4b\xC4\xD4\*\xF3\x9F\\xAE5\x80\xA2W\xB6ʷlݺE\xFE|\xE1\xA9TvC?\xD9V\x9E\xCF\xA4\x91NO\xBE\xAE\xFE\xC3\xDDړ_\xB4A\Qߑ\xEE\x8E!\xA74um\xAF\x90
\xA0\xFBi\x9Aư\xB3\xB5\xCF@\x83\xA6\xFB03-@\xB7
\x94\xAA\xA0\xDE\xE6\xE8\xAA\xF7\xED\xDC\xB2i\xD3\xEFc4\x9A\x9Az\x8B@?Le\xBA\x9FZVb(K\x9C\xC44
+)\x9C\xEF&\xBC\xFC\xC5\x97--\xBA\xB527d\xB9\x95\x95\x95\x95G\x8C\x86\xBCvi\xC2XA\xDA\xF2\xF4l(䡑iQj\xAF\xD4J\xCB\xDDF\xC0\xAE\xEB\xE3t\x9F\xBC\x96\x9E\xD1m}t \x93\xA9N^\x87\xAA\xE6\x83\xD188h4\xE8{\xCF\xA3$\xD0\xE9i\xB3\xDApr\xABPZ\xD6t"/o\x84O\xE2\xFDf\xA5f]\xE2\xA8Tw\x89=\xF9\xAA\xA4\x9E\xDEޞv\xAD~\xEF_n^]q?H\xA9\xC0\x9Bk\xD9h\x86kׁ\xA11\xA6\xA98\xC1#,\x90\xAE\xB8oLW\xCF
\xAB\x84b\x8D=\xC0\xE8Z[uf|\x87\xE8l(OjV\xAE\x97\x9Ac\x87f
\xFA\x819U\xA5&\x89ѫ\x9E\x89\x86p\xEC\xC5\xC1\xC1\xC1A\xAB\xA4\xAB\x82BC\x83C\xA4\xAB {\xF4\xC9B\x9Ey晰\x90\xA7C\x88a8\!4NJ\xF7\xA5\xBD}\xBD\xCD\xE9/\xE7\xF7ůX\xE4ບ \x88\xCCg\xBC\xC7ݪS)\x92\xC0=
+\xA7/\xF5\xA0\xEA\xF6Ǒ\xD2\xE8GG\x9D\xD6\xF4\xC9R4\xA9\xAE\xBB4ٟ\xCBΩ\xE9\x88\xF5\xFA\xFA'\xA8\x8F\x85\x85\xE5W \xFB\xB59
x\xBD\xE0\xE8\xCA\xD8 Vv_\xBF\xD0\xF5\xDC\xC0u\xA0\x92\xFCHr\xBA"\x87|oT\xED\x8D$d\xD8t\xFF@\xFF\x8F\xAF-\xE6\xDAFHeRu\xA1Z\x9AS[\xEB
+\xBE\xEE 0Tg\xED\xE0l\xCF\x87'\xB2w\xD9;*\xD2\xF2\x94\xDBt\xBE\xA2u\xD5vL\xA2\xA6\xB7qhZW\xAB\xB0:;k\xBAc Xso\xE9\xF0~=\x95W\xF1\x886("`\x93{\xED\xFEho \xDDu\xB9Q\xD7-&\xFC\xFB\xF4 2TZ.!\xBE1ay'/\xC8?\xA3\xB2\x83#\x83\xCDw \x96\xAE\x96qYn\xDAi\xF2\xBE\xA4;;
+\x8E\x8E"\xDF\xC8\xC4!G(\xD3b\xAD\xCCFbj\xA2جx\xD3ЦzD at Q\xEC\x88\xF2h[\xE99\x85\xFAe\xE5B\\xB0!5A.Qy\xE7_\x8Bv\xB65\xA8\xB3و\xAFX5Ӗ\x9BR!9s\xE7\xA83b\x88\xD4\xDA\xCC!~\xD0ނr\x8F\x9B\xB0\xE5\xE3\xF4\x80\xA9m\x86\xA4\xA8\xB60\xDC{\xCC\xDFK\xB5\x94\xBAHU\x99\xB5]\xF6@\xF0\xAB5\x84\xAD_Ȃ!\xB5
\x81k
+\x8D2F##sF?Z\xDFI"Sk\x9B\x9F\x96:\x95Af\x92\xF5\xFE\xEE\xC3\xF1"7\xCF\xE0\xFCj\xF3&\xE7Z\x83,TKKJ=\xE6\xEEz{(؏\xBA\xF3\xA8n\x8Ak/\xE2`\xB4Uqj\x9B\xF3s\xDFA\x87Q\xE0\x9E\xDE[\xB3ܖHs\xEBP\xACXS$\x8Bp\xC9L\xF1\xF4\xA7\xAAe\xB5\xBD\xB9\xADO\xDA^2\x9A\x9Bx\xBA\xBAX?%\x91Y#@\x93\xB2\x88\xEC\xA2\xE6\xF3/\xFC\xF7M\xE3\xD8\xD8- \xE6\xCEP\xBF{\x89jS\xBCgr\x87\xA0[\x8B\x9D\xBC"ͯ{\xE0\xEA\xF1\x8D>qR\xAF8 SMnO}\x976\x95*\xC3
+QԼtd\xC3\xCC5F F\x8A6\xD2\xE8\x87TaÑ]\xB8\x8E9s\xFAO\x921 0\xBA\xA6O+Ԁ:⽢ڂ\xA0\xC5\xCC\xD7'\x8E~\xFC\xCE{\xBB\xF6\xA0\x8D\x91\xFA\x88=\xA8N
\xD7\xD1t\xED\xD5T\x8AĹw\xA5T*M\xDFX\xFFx\x81O\x9C\xB4\x80
\xF5\xBB\xD6\xE5o +$\xAA\xBAVu[\xEBу\xF1\x8BPCVq^8$\xEE\xED/\xFCE\xB2l\x81
n\xDE8M\xFD2\xEB\x95^\xCE\xFAz\xED\xE9\x9F[\x96_\xAC\x899
\xF77j\xF3
|\xFC\xB8{\xA3
+\xD26z-\x8B\xDDL\xAD\x9B
Uɡm\xAER\xE4jHR\xCFW\xC7\xB9F
+_X"\xD7H\xAA#\xC5xZ\xEB* +)\xDB\x8A=u\xFEB\x9F}\xDE\xF5x\xC7+\xF1痋 \xCE\xECu\xF1Q\xC6g<\xB1\xD6\xCB\xD1\xCE\xE6zk]V@\x90\xEA)( =\xE3D\xB3\x84\x80<Ru\xD4q\x85\xFD9\xCD{Ar5$A\xA3;M7\xFD_s\xA0\xAC\xEE.\xBA\xFB
3=\\xE2\xB9*0<\x9AD\xE1\xD4\xEE\x8F\xF6\xDD+Q\x80\xF0\xE0\xCE\xD3ݦ\xD3)M\x83\xA6\xFAh\xF7\xC0\xCDa\xCA]N^\xBEb\xFE\x8C.ܷ.
r\xD8TT\x95\xE0\xED6\xE7\xFAw_\xE7oS?wl\xFF\xD0\xFA\xFD\xF15\\xBC đݻ
\xEDlj%\xF0|\xBD$^
&\xB7\xA5.V(B\x96\xCE\xE3^՞\xFA !,{}\xCD`\xFA\xD8{\x83\xB1\xD0\xF7\x80ɖ\xFBL\`\xFE3\xEAg\xBC\xFD]\xBB
+\xA9\xB5\x8A`o\xB0t\xA0PW9\x97,
k6\xECw\xE7ygJ\xE2\x82d\xCB+2$\xC4b!\x9F\xC0`\xD0_nm\xBC\x84\xE5\xC1\xE3\xE3IM\xAD\x90\xC6~ \xA1\xEB\xEE\xE3\xF4\xD4\xEB}W\x8A
94\xA9U!\xB5\xA2~y\x8D\x97O\x90\xBB\xA1qh4\xBC\xB5:wI@\x9C4\xA76\xD1\xDB
D\xBEǚK\x84
>\xCB/\x97
N
+
j-\x81\xCB@\xA3\x90\x8F\x8C\xE4R\xA5 KT\x88o\xF7\xB50\xF0\xF9\xF3\xA4\x88ع'(s\x93\x87\xA3\x88д\xEEʹ\xAF\xDF\xDB}x\xFDk\xE9\xA3\xD6 \xD7\xC6\x804\xE4~\xC7=#/\xCA\xC7CAH\xA4\xAEB\xFDВ\xEC\xD4\xDA\xC1o\x80.KCf\xBD\x9Bm \x97\x88|\x8F4\x93\x8C\x94\xFC\xADA\xE7k$K\xFCJ\xC3
+\xA1n\xCE\xE9\x8D\xFB\xAA\xAE<.\xBF\xBB2\xD9!\xA9's\xEBJ\x9C\x95\xC7d@\x92پ\xDD xDE{\xAF\xA33gg\xE5f"\xAE\x91\xEE![돖\x97\xF9)Qr~9\x80\x99ܡ \x8C\xD7/\x8A\x84\xC8@{ \xB6ߑ\x90\xD4\xEB?\xE5jvR"I\x9A\xD3Q;~8\x9D\xA1u\xE7\x8F\xBE\xA7\x90fh\x90Y\xD5
>6/x\xE6\xF0\xE6\xB7~\xA2\xE4+\xB3eE\xE7=\x8B\x98\x80\xD3EU\x8F|\xA1RԞ\xDF"\xDEX\xE3\x95\xE4ZPӾ~\xAEƁp\x88\xF8̤
+1\x82b \x95\x90J\xF5\xD15_\xF8m\x9Bch\x8C
\xB31\xA7T$\xF7ȷ
+N\xAC
+\xF0R\xF1EG"\xC5T\xB7\xF6\\xD3\xF1\xFD\xAFDdk\x90W\xDB\xE5?\xA4\x8Cv\xB7_2+z|ԋ_$|?z\xF7\xB1\xD9\xC0g\xA9;{7=\xB7\xA0\xFA\x93\x92\x8E[\xEBYt\xFF 0keX\xB0Ծ\xFB\xBF\xFF\xB2\xB7\xC0bi\xDF\x9FS\xEF>.\xC0P
+\xB5
+\x9F~t\xF4\xCD\xD3fc)\x8E\xAF\xFB\xE09\xF7\xEF\xBF\xF9\xFA\xED}G?\x9FA\xC6 LJ\xFF\xE1\xD6e\xC6\xEE\xAEo\xBE:
[x~\x8A\x92.\xAB\xA4\xAF\xA5\x8E5w܄\xE8.Cqڧ\xEA)J\xB3\xB0\xFChXsz콣\x8D]\xAB\xE6펐X\x84&!\xE4\x8A\x8D^A(\xF2\xAA\xF6G\xFBS\x95;\x97%\x91 $\xF15
\xBE\xE6f\x8D[P\x944\xC2Ϫ\x90\x90ɠ4>^\x84,\x93\xEC\xDD>\xB4oH^$\xF9\xE8t6B\x96I\xE6nu:\xB9Z\x9B\xFA\x84\xA3\xFFY\x8F\xFC+\xF0-\x88\xDA+\xF3S\x90Ȣ$P \xAD1\xD1\xE1#\xFF6\xBC\x9C\xE3\xE7\xE3\xA1$\xB5\xBD\x853<|qx~\xFD\x80\x8D\x97\xDC\xC7FМ.N\xAFk6\xF0=\x96\x84\xDE\xDB[9\xC5\xFB\xC6\xDA P\xC5\xA8ƶH2k\xAB\xC5\xCB,Oamq\xD8\xC8?<\xF7]]\xF5\xB6\xDB\xE5^CYN\xF2\xC8R\x9B\xF1BB\xB0(\xF8{}W`\xA0\xA3\xE5.\xC0-4\xEB|\x95\xFB_b\x82\xD4\xCA\xE1ڤ\xF1\xEAg\xEE7-\xC3\xE5:J$>\xF3&\xF7\xCDLR\x80'
\xF2\xE1\x89$2\xC2GX*\x95B\xAD&E\xAE\xF3w\xDD
\xD42\xBA`\xCC;\xF1\xC3
+^jR\x90\x8Fܼ
+"\xAAH2~ Δ
+\xC9_\xE0`\xF9"\xC714O\xB4\x84\x9B \x90\xD5t\xAC\xF5t\xEC\xEDH\xF0\xA0k\xA9\xDE\xF5B@\x86\x8A2=T<\xD6T\xF6\xAA\xA7]
2\x88\xBC\x9A\x8Ah_G\xF0\xE7-$Ab Lwݟ
|T\x90T\xB4g\x8C3{yO\xBDUi\xBB\x9Cp2\x8B|D\xC8r\xFE`\xB2
+\x8A紘 VN \xBC\xA3\xF3\xF5N\x92g0{\xD6]\x8A
\xFB]\x9C \xD0-\x88\xDA^O\xA0\xD5\x9A\xFC7\xF6\xADw_0{6ν\x97\xA7\xCDn\xBE\xA9\x84\xE2\xF0\xB9P\xB7a\xB1i\xFDF\xA3\xFD\xDAhuBe\xE3ٳg\xC1/\xAA"\x9F\x9B\xE2\xC9qt\x81\xAAK"\xDBjM[\x9C&\xF5\x90\xFA\xA9$\xB5
\xA1&A\xA6\xBEC\x96E\x81p\xB0ʐJ%j\xB5\xD2
;>\xCF98\xC5\xD8\xF1\xB0|\xEBW㞦t\xF1&~D! \xC8R\xC8O\x8B\xEDM]շ\xA0!\xA0\xAF,\\xF3֠1\xB5\xF3\xFCɄ\xB5\x90d&?\xE5\xEF\xF4p\xC5۪ E\xB1gA|{̐(\xE0`\x9E\xEC\xEA}\xDA^\xC4\xD3\xD6\xCB}b\xEC2\xAB\xAA\xFD\x8AC\xB8~~\x90\xE6\xD4[xʧP$\xC0>2\xBFQ\xF6\xB7\xE1\xA9G\xF3\x82\xFD\x94d|fQ\xF3\x81'\xDCG\xAF\x82\xE3\x9658h\xA9Fc\xB3E\xFE\xF31\xB8v\xA6\xC9\xF5\xB1\xE7]E\xDDR\x99dޝ\xBAKWE\xE7\xE9\xCEu\x96\x8A8\xC5\xC5>T\x90\xFC\x95\xF9A\ \xB8q&rǷ\xBB\xDF|\xDCs\xF5\x929\x99\x87\x9BϜQ\x8FX\xA2\x9D\xC7}\xFA\xA8\xE7\x9F{lu\xA0\xF8\xF9\xF5{ޟN\x86\xCE㟪\xC4w\xBF\xF2\xF8}n
n7\xBET&O\x9Af\xEF\xFF5\xB7\xCF\xBB\xE7\xF1\xDF\xAD8{hW\xAFzG\xADy\x81<dq/٨\x9E\xBC\x96\x99c\xE5\xFAP\xD0T\xBBa\xF5#O088\xFCspppp\xE8a4\xFC\xCF\xF0\xAB\xD1m\xF8\xC1jx\xDB\xE0\xE0\xE0H\xF9\xC1\xC1\xC1\xC1\xFE\xF9\xCF\xE2\x9F\xCC\xE0\xC30\xFF\xFC\x81\xF9\xE1\xE3\xCD\xDEΩO\xFAsAk\xEB\xFE\xD1x\xF3\xFE\x87
tw\x9C\xCCʢ\xB5-\xE7._7\xDA\xD8\xD8\xD8-tq\x8D
e\x86\x92
+s\xF8\xC1\x94S&\x83\xD2u\xD3\xE0ً&\xA1u#\x9F?|\xB6[>ܴ\xA6\xD6\xF2
\xC5HM \xFE7D£)\x9D\x81\x99I#\xD1G\xF7\xA9t^\xCFL
M\x9D\xA6t\xE6\xF6\xDB|Zt\x9D-\xA7Z:q\x97\xE3\xFD^\xEES\xCCz`z(\xF2'\x87\xC3\xE3ܦ \xB4\xB6\xB5w\xBE\xDB\xF0\xA4N\x9A\xD2Q4#\xB073mhme\\xFA\xD9m\xAFD\x99[<\xA3Bt\x96f\xECF\x98b(P \xC3\xD0\xE0\xF08 \x98\xEE\xF2\xC2\xCF]\xA5\xE1\xE2\xC9? h]\xF7\x95^=8
\xAE\x8D\xD0V$זLwg\xCF\xC1q\xF2\xC5\xF2 \x9D\xCE \xB4
-\xFF\xE4D\xE3\xE5k sܻR\xB2\xCEW\xEC0&\xC6LC\xF9A\xE3COxO3\x87\xB5\xBB|\xDF\xC9B'\x8Bljq\xD3ܡ\xD5B~\xD3\xD9u\x93\xEB\xB0t\x85\xE7\xD4A\xBD\xA0kmh3\xDA-]\xE2<\xE5%\xD3hS\x99
z6t\xACgW\xB4Ւ\xBE\xBC\xAA=\xD1\xFE÷\x98\xAE)\xEDIB\xB9T=\x98o1
+\x84\xAAܩ$ݣ\x83\xDD@א
\xBB\xED+#\xD1~B\x98z<8\xC1ʱ\x9F\xE6\xEC\xD9SsEwYY
+w\xDCq\xC0
w`(\x93\xD3
w\xDCae5\xD5kn\xAA\xA0E\xCB\xFC\xBF}\xE3\xD1\xD94u\x83'\x98ʹ\xBE\xF6n\xFF\xF3\x9B\xEF\xD3쯺S\xC0e
+\xB9`\x85+\xD0\xFF\xC1\x9Fv\xBDz\xD3\xEE\x99\xA2\xBE\xEBC3\x98\xE0\xF0\xDB7\xE2W\xF1\xE8\x8EW\xA2\xBD\xB0\xE3Yk\xE0\xE0\xAAj{\xEE˧\x87\xDC
\xFD\x9F<\x91\xF4[(ճ\xAF\xBCl\xDFl"\xF8|\xFB\xEE\xE3\xB3\xE9֭R\x95p\xA0s"\xF7\xE7\xEFB\xA4\xE9\xCF<`\xCB\xE9k\xBF\xD0u\xD5\xC0\9u,\xF6\xA0\xE9\xD4p뼽/mXx'p\xF9\x95Ь7\x9E\x8C\xBB\xFF\xE1\xFC\x98\xA0E\xF3
\xBA\xE3N\x87ñ\xBA\x93\x83;8w\xDCq\x87\x95՝\xB0厡?\x83wXY\xE1\xCE!\xAD
\xB4\xDE\xDCaee++\xC0|ˏf\xE3\xBE3M`ML\x96\xFF`~\xF3\x8F/l\x8D~p\x81\xFD\k 7._>\xDB|\xDA(\xF0\x9E\xA7{-\xF9\xC8\xE6\xF4\xC7\xF2\xCBwO7o\xF69\x96\xB9+\xE6ʲ\x8F\xFF컈\xDFA{\xC5W\xE8\xE8\xED1\xF8\xA1\x95\xFC\xF6{3\xC7\xC1\x81\xDB۩ex\xB3ڏ\xCB\xDE
\xE6^\xF9\xD4\xE6\xD2\xCD\xF7\xD2\xE7>s\xDBV=\xA3K,?QnK\xFEC\xF2\xA6>\xFF\xA5'=X\xA7)^\xF9j\xA3E\xA9e\xCB\xEE~\xD7\xEB\xB0\xE2\xC1\x80\x9CpM\xFB\xFE;_\x9D0\xDBw\xA5:^\xCCЧ\xFA\xE3\xCB/\xB3\x8E̟\x80_\x9B\x89ɮ(gaaaaa\xB95\xDE|u\xCF\xFF\xF5\xA9\xC0
+\xF27\xCFf
\xB7[\xE9=
+\xDE\xCD\xEA\xE0r{b\xD5\xF3\x9B\xC1\xFAw\xC1\xE0t톘\xBCo9\x96;\xF3\x8E\xEC)z"^\xD3
+ w~\xBF\xEFݍ\xCA\xF2\xEB\xA2\xEE\xCB
/\xAB?\xB5/G\xE9\xF8\xB6u\xA6\xD2P\x97\xBE\xBF\x86\xD9\xC4c'\xDF\xF7\`
+\xF4}w\xA9\xCBt\xFFSj\xB6?\xF4\xDBW\xE5~\x90\xBA')\xF8\x81\xC5\xF7H7\x86\x95~+7r\xFA\xFE\xD4\xF7CnT\xFDwݷ\xD5(,,\xE6\xB0s1YXXXXXn\x9E뉢\xF4{f_\xFA\xEB\xF6=\xEF\xCD\xDF\xD8\xF1\xAE'p\xF5\xDD\xECO.Z\xE7\xF4\xFF^\xC5\xD0H4\xB5qO}\x87\xF2\xB7/\xEE\xDD|~\xF3\xE9\xA1\xF7\xEE\xEA?\xAEK\xB8\xB4l\xF5\\x80\xBEk\xF5\x93\x8F,\xAB?d\xB1ֻO7Yt\xB2 \xE0\xF2\xC0\x9C\xAB\xFA\xAF7\xBE\xB5\xE1\xDFP\x9F\xB6\\xFA\xF8ͷ\xFA7\x87\xBD\x80־\xF8\xF4\x9E
+ϼ\x90\xF0\x9A\xC4).~yAژ\xB3\xB3\xB5\x83\x82\xAB5\xAEu\xFD/;J\xCE\xF2\xAF\x80\xF5b\xB2\xB0\xB0\xB0\xB0\xB0\xDC\x82\x97\xB6G|\x9C\xE1+ \xC0\xDC3\xEFΖ\xC3\xC7?\xFE\xCE\xFA\x91{\xED 4
\xF8{\xF2\xB1\x9B?\xFE\xF8\x9F\xE3\x9F\xDA\xE65\xB2V\xF1\xF8\x91\xE0܉\x9B M\xDDX\xF0\xBCD\xD4\xF0\xD9\xDF\xD7I_\xF1K\xB6\xB4/\x81ζ\xF5ޒLc\xF8\xFC\x82v\xBC} \xE0\xC4\xC1BU]Ǎk\xDAע\xF7P @\xB6\xF4\xE0\xDB M\x8B\xA9\x8F\xA0\xFB\xDBo\xD9\xC0F,\xFFX/&\xCB-A \xEE]\xE6\xE9z' \k}\xFF\xD8\xF5\xFB\xEF\xB9\xFF\xF5\xBCp\xF1<0\x80x㖓
\xE4Ŏ3u]\xD6n\xAB\xDCP Г^\xF4\xBF;\x9E\xC9\xD8`\xE0\xC6\xC5\xCFN/z\xD2\xEB\xE6\xA7o\xD5Nb\xCF1=\xDFOns\xE5b\xC1\x89\xE3}\x8C7\x8C \x8C\xE3\xD3n\x8D\xD2\xFF\xB22\xF7e\x93\xDFK܅q@\xE7\xC9V
</\x9Ej\x9B\xBC
\x96[\x8051YXXXXXn\x8D\xAB\xEB\xFFf\xF6\xBD\xAB\xEF\xF1~\xF8\xF0\xAF\x9E\xF2\xF6\xFEF<\x92Mh\x8Bw7\xBF;u\xD2q\xC1\xDDY\xF5\xFB\x95\xF7\xBB-\xB0\xA1\xAFR \xC0c\xDE\xFB\x8BG\xBD
{\xB1\xF4\xC5\xE5o\xEE\x8D)\xFB~&'}!\xFD\x85\xA7\x99\x8A\x94cC\xDB+\xFD}\xE3\x83\l/t\xE4\x8B}\xBC`[{\xB4.\xEB\xF8\xF4Q\x86=\xDC\xECt}g~^\xEA\xDB\xD3W\xAF~]3\x93 \xC5,,\xD3\xC3\x94\xB3\xB0\xB0\xB0\xB0\xB0\xDC'~\xF8\xC4[\xDFr\xFAb\xDB \xE0\x8F/\xECذК\xA6 \xD0\xF0\xF7*\xFDBb\xCFg\xE9'vmL\x97-\xDFq\xF2\xDD\xF8??\xFE[\xB7\xD6u\xF6\xB8ET\xEA px\xFAG\xF3\xEA)@\xB0\xE1\x8F\xF1\xADE[sC\xEE
\xAB}֝ \xD0gr\xBE\xC5\xF7\xEEM\xFF\xB3W\xA6\x89})\xDF
[\x9A\xF4\xD8Cw\xDB0t?\xCD \xB3策<\xF2\xBC2\xB1\xB5(\xEA\x85e\xB1\x85-\xB8\xFB\xE1\xC56\xC0\x8DuM\xB7\xAE\xF4_9\x87\xBA\xF9`\xD8\xF2\xDD<,, kb\xDE:\xD5ݒ\x9F\x96\xDBJO[\x92nih\x99\xBE\xD4O C\xEB\xBAu4 \x86\xD2\xE9\xE8\xE9\xC3!\xD3:mk焹\xAC\xFF\xADP\xDD?\xBF\x93\xF1\xE3dctݓf\xB4\xA6\xA9Iz\x88\xA1\xA8\x9FW\x8D~6ڤI\x8A\xA2~=\xBDY~90\xE33\xCFE\xBD(\x99\xD7\xF4\xF7\xB7\x82\xF3N\xC0\xE5\x91o\x9E\xF0\x8C\xF8ݒ\xABǚ\xE0F\xC7\xFB\xD9\xF9\xDB\xDE\xD1b\x99 8Y\xC99\x9F]\xFE oނ\xD9[\xDCs\xA2\xED
+\xEB\xE7r\xB6\xE6\xCA|\xD3\xFF\xFCde\xDE
o>+Y\xD8\xFF~\xB2i$\xF6\xBB\xE5\x8F:i\x92\x93\xDC6\xBE\xBAr\xF3\xA1.\xC0\~\xFF\xEF
+7 \xDE<\xB7?'N\x94mb\x84?\xA6\xC8<gCG\x96\xC7
7
\x8B\xB7K\x8E\xBB:\xAF~lc\xFA\xE2I\x8Fea\x999\xAC\x89yk0\xDA2\xA1\x83DZ\xFA\xB8%\x8Aʑ\xF7
ө\xED\xB4x\xF7u7''\xEFz\xC1\xCBCQ\xAE
Wnj\xCES\x9E\xB0|Ӿ\x96\xA9JtV'l\xDA9\xB5\xA5K\xE6\xDA:\xECn@\xBEik\x9B\xDB<\xB4\x91\xD6i+\xF3\x93\xD3J\x9BƗ\xFF2\xD5e\xC9\xCBu\xB7(jk\xB2\xBF\x95\x95\xD5\xF2}
+\xB7e{\xD1M\xD1\xCBC\xCAG.\x83\xE9n\xC8OK^\xED`\x9B[7ZC\xE9t\x949:\xDD\xC6Fg\xD3\xD1\xEA\xBA&m\xF7Ll\xE9\x95lC\xE8\xF6mZ\x9EV9\x83\x8E\xA6I[\xDB\xFA\x89\xBB\x8C\xCA\xF2\xF7\xB6\xE8tږ\x96֖\x86\xBA\xBA\xA3Օ\xFBr\xD36\xF9/\xB7\xE2
+\x85[\x8A'>\x88iMIh\x9A\xCE e\x86\xA6\xE9\xEE\xCE\xCEe\xA21\xDA\xDC\xE8\x84J\xEDL\xACݩ\x84i\xAA,-.
Oqie\x93\x99\x80\xBA>]\xC3\xC8 k\x94\xC2\xD5{'Pڙ\xCA\xC6tW\x97\xB7Lj\xE1\xFF\xD4Е;\x93K[f\xB0Lwf}:\xFD\xF9\xB4\xE5\xD1\xC9\xE5\xD3VC\xB7\xEC[
\xB2\xEFV3S}\xF1Э\xE5\xD1 \xF9\xDA_ŗ\x80u\xFA\xAE
ڽ\xC1\xB3\x81\xD9\xC4c\xAF=\xF2\xC3kە\x81y\xE7\x85
\xEE\xEC٧\xCB\xDE]\x97\xF9E\xF7\x8D\xCB\xD9\xDB><\xED\xEBo}\xA1J/h]\xB2\xE6\x90:\xB3\xE3\x8DGE xw \xA8\xE7\x9E\xCD\xF8\xB0\xF9jÁ7\x9F+3\x9E>^Y\xD2Lq\xE6:?\xB9\xE9\xB1g\xFB\xAD\xD8U\x84
\xAA\xED/?_oj~\xEC\\xBF$\xFD\xA5{w\xB4~~\x80k\xDF=\x9Fw\xE07\xCF\xB7\xD0 o\xF6dI\x96m|q\xF5<\xE6\xD2\xFFn\xB1L\xED\xD3\xD3\xD4\xD6 ̥&6(&˿v.\xE6$'ٱ\x84??\xA0"UT\xBF<\xD3}@\xD8\x8C\xB6\xCC\xC9%D\x94\xBA\xE0\xA5`\xCF\xE1\xEFF\xFB\xA5➌A|T\xB64}\x9B1ڴݖ\xE8j\xA4\xD9dN\xAD݈\xC7h\xDF"\xF1\x87;\x90]X\xF4\xF4\x9E\xC4)\x8C\xD8̑\xFD6 l\xE6H\xB1\xE7\x9D|\x9Em\xC5^\xA5\x9A$Q/ڌ^\xA8\x8E
\x8E\xE1Ln62k\x89\xA1T7#\xA7\x88C\xB9]\x9A>\xFD\xA2m\xD6\xECYf'\x985\xAB\xF7pB\x86\xA4\xBE7\xA3\xD4v\xFF\xA9HO_ at W]Zqy\xC2P\xB3\x85\xFA[<\xF5\xB4\x87\xDEQ\x91\xF3\x9CxJ:dz\xE9\xD2d\xD8I\x898\x9FT\xE9`\x963 \xAA~\xB5\xADiYQ\xABo\xF46\x8B\xE8F\xF9\xCEKaٚ\xE1\xDDҨ\xCD!\xEBW\xFB>t\x9F\xB3\xA3I\xB31-Շ\x8D\xAEO\x91`g\xE6\xB2Ѻ\xCE^F \xA1\xABJ^H\x96\xFC?]g\xEB\xA5\xCBڦ\x93\x97\xBD\x9F
+\xE9\xAA\xB5\xA5|> \xB8\xD0_"\x80\x8B紋\x84\x9A\x96\xCFB\x97\xA1\x84|\\x9ED\xB6\xCA]t6m\x8D\x8F\x92\x94\xC4Gi\xB2UH-\xAA\xDF\xF3QD\xF9_\x8A
\xC4w2\x87uc7ŀ\x9Aa\x8CF#\xE9\xA6>a\x91\x80XVԼ?\xDC\xDDlݲS\xF1\x9E\xC3
+\x9F{\x88\xB8\xDCY\xB3f\xE1\xA6\xEE⩓=\xEBvD\xBB[\x9C\x92cs]\x95}\xF29e\xE0dbf\xD4 \x9A\xA4\xB08\xBB\xA8T\x89\x9D\xC10\xBA\x91o8\xA3\xCCV\xE7\xF4'\xA2)\xEA\\xD5 \xD0Π\xA38"Zr\xB3\xB1\xB5ގ\xD2\xE9h\x868{\x93\xC4;\xD3\xCA\xC0p!(BZ\xD55\xE8>i\x89!\x86fFM3ƾ>c0\x8Dׯ_\xBBy\xE5ʍ\xF9+\x82\xBD\x9D0\xBA\xA6m\xEB7\x8F\xCF{oQ\xCEh\x96\xA6\xB3I\xD7\xD9\x80\xA6\xBA\xDB\xDB/\xCF\xF7\x98D
+\xA7\xE8\xD3[\x81j\xADU}\xE2\xFCZ:\xA6>\xB8\xA3\xA1\x8C\x9C3v'14\xC5p\xCC
5t\xD3&>Qh~T
\xA9\x8FO\x90\xC3\xEḂ)\xAA\xEC\x88W\xB2nC\xDE_
\xFD\xC9;v]L}\xE1EoQ\xA7\xE6\xDD\xAF\x9E\xDE<4\xC0
+ 8]\xFD\xE9՟\xFD\xFFy٧\x9F\xA8\xF7Ϳ
+
xq\xF5\|WO~>\\x90\x8A\x8D\xDF5\xBE\xFE\xE7\xE3_\xA9\xEA\xF7!\xF7\x8B\x8CF\xFA\xF2\xB7\xCDo
<3>\xE3H\xB2\xE2\xCD\xFE-\xFE\xCB
\xBA.u\moy;\xFB \n\x90\xB6,\xF4O\xB8\x8AH\xFA\xDC\xE6=\x9D\xFEQ\xBCᯖ\x81\xD9$ǿ\xAC\xF1r\xEE<\xABeW\x94\xB3\xFCK`\xB3\xFBLհS\xE8\x954\xC9Nimo\x99\xB7\x89\xADD\xEBZ?\xDA\xFD\x97\xA5Z\x92GVGgO\xA6\x9AJ\x9AG\x85\xDFF"5\xBA4\x9A\xA6\xB2\xD8ޘef\xAA\xD2
+\xFE\xFC\xE73\xF4\xD5\xDE\xA5k\xA4\xB5\x95\xA9\xF9532
+%Q\xA9!+]/\x93k\\x8B\xE2u\xBF\xD7c(\x9D]yB\xF4\xC0\xB6\x9CP7\xE3>\xA1\3\xB9,\x92<}u\xB4 \xA0[\x8A\xBD=\xDEv\x95
+-\xF6\xB7\xA9\xD5$ H
+\xC8#\xC5"Pu\xFEBaT\xBC\xAB\x8Dy\xB9\xBE\xB6lU\x9B\xA5]H5lzY\xBC\xBDd\xF1\xF1\xF3\xEE~8~ˣ\xCE#I,i\x8AƸ\xE1<\xDE\xC4\xEDJS\xDD
\xED-u\x9A#\xF7*\xD5$\x8Aڍ\xE1\xCE#\xAD\xC6hӸ.J\xA0\xA0\xB6#\xD2\xDB\xD1\xE20\x8A#0\xCB\xF27\x9DlTS\xBE\x90\x88\xB18;!\x91KC\xFE;'vآ\xA26\xF1\xBD
+ $ \xC0\xB0\xA9LI\x82 H\x92D
\xA9¨\xF9\xE8d\xFB\xB1={\xE7E$<\xB7e}\xBD|-^\xAF_z\xC7Ɩ\xE7\xAA&[\xD9:\xBDљ\xD6d\xAF%\xE3\xCCm$\xB5\xA3\xFA\xC0Pڎ^\xAE\x8D
+\x9F'\xE0t
\x91. \xD2ė\xE8\xB3B-\x95\x85\xD1\xBF\x91\xB2\xB5\xE7j_\x9F\x8D
+\xA5R\xA9@\x92y\xFEP\xE2\xF8\xEF\xA2\xEAd\xAB\x84\xB9\x{14D25E}\x9E{F
+ T\xEEr!\xC6Z\xD8z\xAD\xF9VK\xFA\xF5\x83\xB1 LK4\xD7C\x85\xE1\x86\xCB!
+\xCFt(
\x82\xB2'\xBE\xD2\xC8Ls\xBF \x96"\x8CQO\xB6\xF1E\xCDY\xE1\xEE~8@?\x98hRs4W\xAE¶\xFD\xB1\xDEc'l\xCA\xE71 \x82 @\x92\xA6=G\x94\x9C\xAFu\xE3\xDDZ\x9F\xCE\xBAigj\xC5C\xA1A\xBD\xA5\xB24~ֱ
R
WB7\xF3d\xA1M\xC5\xC9)_\xC0\xDF\xD3\xF9rEL\x86Z\x9A\x99\xE9\xF5}\xEB\xD9\xC6\xDAB
+ \xA4\xD6\xA6\x8C]]K\xF3\xAE
+\x97÷\xB51|\xBDeI\x80:\xAA\xA8+?|\xA2|\xAC\xDA+~UG\xBA\xFF#\xB4??YIV.
8q\xA1\xDF|\xB4\xA8\xA9^Q\xC12P\xA7\xA6\xC0\x93+\xBD\x9CQ\xAF=1}A\x96\x9F\x84_[v91"V\xAF\xFF#\x97kn\xDA\xF08g\xF2\xD7yŬZlb_R:Z rO)\xFB]\xC8ыvKG\xB73\xC6̶\xB9
+\xFFCk\xA9"LE\xA8\xCFY\xE7\xC01|Sb+w}tBW(\x97?q%
'OO\xBE\xB8-\xBF\xDFm\xE0x\x96>\xF5\xF0C\xA0:\xB4\xED\xDF
O\xC9Ve&\xE7F}2k{\xBD'T\xA1v
+\xBD\x86\x9F\x9E<\xF7\xF0\xC6\xC1\xF0 \xA4\xDD\xB2$˿\xB71v\xF8x.\x90(\xFF\x96\xE5i!-\xD3Ԩ\x8A\xB3\xA8\xBEx\xABW\xA1$\xF3\xFC\x87[\x84\x8F\xA7?.t Z\xB1
+q\xD0 IDAT)5\xD6s\xE4\x8D\xCA\xD0:\xCA\xC8\xE1\xB18\xB80\xE8|\xD1)\xDEy{7\xB1\xBD\x9B\xD87<6\x85\xEA\xEE\xE6\x9B:\x9A8\xCE)\x83\xFA\x87wn
+\xF0qj,"\xB3\xC2ţ{Z\xDE\xDD\xE4qLf\xD8:R\xE1\xF4\xB2 \xC4у\x83\xD1t\xCB>\xBE\xC7{5\xBDվJ\xF1<\xF7\xEE\xFB\xDD\xE4o\x97c\xAC\x9B7Nw P$\xE6mF\xDB\xD7f\xCD'#\x9E\xD8[\x9B\xC9\xD7$\xED\xDC*Ғ\xEEs\xA7=\x84Ҭ\x9AP\xFB\xB9s\x84v\xB66\}_\x9F\xD0oI\xE3\x88\xC2\xD6ڂ\x8CFFm\x8E\xC0\xD9Y \x80\xD1V\xAE[ԣP҃'\xD0F\x8Esxbz8 \xE8\xF6E۪ -\xAA\xCD \xF7v\x9E\xE8b\xE0\xEEO&\x9D\xA4=y\xB4\xAE\xE9˪\xDD i\xCBTGbG4gF
+ \xB0\xB6Á\x92\xE2\xFBWؚ8\xBBg\xDD +@\x8C|\xEEr\x9C\x96I\xA4\xB5\xEA2or7
n;\xB4]\x9A]t\xDE>|P\xB9\xFE\x9B,
\xE5S\xCB63\xF8\x8F(j\xEA_u\`g+\xF0\xF9<
\xD5T\xBC\x86\x88pM-z}\xDBn\xA6\xBA\xC6偰8\x96\xF3\x80$\xA0\x90\xF0 X\xA7\x8Ft\xEE\x9E8ڠ\x8A\xA2
+}}F.\xF4{]T\x9C߱\xD6\xD9<\xFD\xFC\xAD\xF4\xE9L\xE0\xD8-\x9E{-\xF7yB\xAD T\x804\xAF\xBE,\xDA\xCC\xF8^\xE8\xF4\xD4\xC0E\xEA\xE2\xC15y!ֳ\xBB\xAFx⹄=\xF3\xEC\xE6;8\x99W(r\xF2,\xD3M \xFC uT\x91>?|B\x89\xA8\xA6\xCAlȚ\xFD\xFE\xAFٗ?)\xD4 \xCB\xE5\xF1[\xC6D\xFD\x8C>\xC2\xF5\xB77w\x8B\x85\xE5v`M\xCCI\xE0\xF0&\x9F\xD2
ۣ\x91\xE4\xE5\x8C~\xC13\xDAR\xA1K\x95\xA3J\x96{\x8B}M\xBE\xEC\xE9\x8AԈ\xB8\xF9%[\x83݇\x9B\x98\xE9\xAE\xFE\xF4\xC4\xC0\xACY\xC0\xACY\xB3\x80\x81\x81```\xD6\xCA\xDF\xFB\x9BZA\x9DGs\x97\x84e\xA7Vu\xBB\x89 \xF0 \xE8\x8Ef\xA9\x91G><^F!4ryrڶ\xCD\xEB\xBC-G\xCB9\xF6\xE2\xE0P\xF1\xBD=\x92\xD2\xFE\xE0`w\xC6]\x95\xB9k\xB7\\xF66 \xF4 at H,\x8D(\xAAY3*.\x97t\xEEK\xDE\xD5h@`\x83>\xBE\xEB\xE3\xCA\xD8 at p\xA7\xB5\x90;\xF7\xCAղ\x92\xD7-\xDE\xE4F`\xF1b,\x8CD\xA6z\xA74\xA2PRӕ\xE86rpg]
+\xBF\x9E;\x92"U\xB6^\x86\xE99\xF5\xFA1c\xDAd+\x97O\xA4QA\x8F\xAC\\xE1\xE9\xBEt\x89\xBD\x80#\xB0\xEFj\xF8'\x96\xD5;D{}Ѷ+|\xC4ң\x9B\xFE'F-+zu\xE4jg$\xDB\xD0\xE6]
r /=i\xA5\xD1H\xF2jD{\xDB\xD3:\x{D843}\x95\xA2
+\x9B}
9 \xC0t\xD7
n\xDD5\\xE8Nj\xA0\xA9\xF8\xF4h\xDF\xFCY7\xEEY\xE1\xEB, {\xCF\xE0hO\xBA\xFF\xC0IIl\xE4º\xD2\xFD\xCB2%\xAA\xC5g9EE\xF7R
+
+\xFA/|ղ\xC2\xCF
{o{ \xA0\x9A\xD26\xCAa\x9B\xA4ޖ\xC7\xE1\x81\x8Cw\xECv7\xEC[\xEB%'r\xAA\xD4[\xFD at 3\xE0Mq\xBF\xF3\xBD6V\xB5\xE7\xF8O1\xD4\xEC\xE8\xBDd\xC0\x96\xE8\x8AB\x95@Tj\xCE\xFDs,\x8A̠A \xCD>\x9B\xB1\x81r>\xBF\xEF\x8Cv\xA3#*\x80!\x8DuG\x92TJ\xC4g\x8A?,\xD4n\x8Ft\x9E\xE4
+f ۴pܽ}G0\x9D\x95\xB6DDjU{\x8A\xFF8\x83\xDB\x90\x97)s
\x88#k3\xB3|6HG?\xB7@\x9F;\xF9u\xDF\\xFBys\x84\\x8E.]>w\xF2\xF0\xD7_\x9F<\xBEWc\xFBѡ7n\xA3O\xA7\xBB\xC7\xD0\xC4\xF4\xD0\xC4\xD4\xFC\xE5\xDC몉?
\x88\xDC}\xC3\xDD\xC14Q1J\xAF
ё\xD3[⺆[\xAFjE\x89>}\x9C#|\xE6\xF8;1Df\xBD;\xFBJaaa\x81}
\xDCt\x8B:\x8ED\xC5\x8F\xD1-
琮\xF35y\xF1\xF3q\x89\x93\xE6Ԕ\xC6\xFA5\xA8\xAEN\xA1\x86\xBA#\xC4d
`\xCF\xF1\x92\x92K\xF3\xE6\xD9\xF4\xB5e\xABԄ,\xDE^\xDFի\xEF]7fbj\xCB\\xA4\xD9\xF1Ed\x8A\xC9HS\xC3\xFE\x97Hd>5\xD1\xCC' \xAE6\xA5>K i^\x852<\xD0s\!!y\xB2<\xE7\xA1\xFB\x82\xD7?\x97\xB8\xD6$0\xEF\x9CE\x84\xA9[\xCC嬌\xECu\xCD#\xA2Y\xB8Y\xE7\x93tvGl \x8A8\xBE \x80\xEE\xA3{3 \xA9}\xD4m\x9Ar\xE3\x8E\xCB\xDF\xE4SH\x94\x9C?fb\x95w\xEE
+ʐ摦\xCEZ\x81\xE7V\x83>\xCAb\x94\x9C\xC3\xE3uU\xA79h\xBC\x97\x9A^\xAE\xED3\xB5U\x9Eͧ\x8EW\xBD\xED\xA3 \x89,sk\xC2\xF6PKw* \xCF\xC8\xFC\xC1\xC8\xD1_Le*Q\x88Ԏ\xE1I\x8A3\x95
+\xA0+ӂ\x94 E{\x82\xF0E\xAA\x87\xCF\xDAT\x85$i\xC1|
\x80\xE99TT\xA0),\xD4 Q
+\x85"U\xF1\xBD\xA6\xE2\x9D\xEA \x85ِ\xA2(\x94-/\xB4#W\xCFu
+/otG?\xFA\xFB\x81\xFE\xAEf-\xE5\xEC6|\xBDMqJAQ\xEF`8\xA7\xA5X\xE8\xD1\xD2A{N4!\xB7\xA18\xD9+" \xB97\xA0p\xC8P'\xA2\xD4^
+v7\xB3(t-
+W\xEC\xEEs\xB7\xE7\x89\xFD\xFD\xC7W2\xD6L\xDD
+ \xC0ο\xA6y\xCFJw\xC7q
+;\xB3\xFA{\x90s\xE0o\xB1\xC6H\xAB\xB3j\xC9\xE8\x80#\xC7\xEAwr\xF3\x9B
\xD0x\xA0'\xB3\xEA|\xA2\xBFm\xBE\xBF\xADK\xBF\xDB`\x8A/@_7\xDB7\xD9&\xBD,\x9D\x8E\x99\xC8Nʂ\x88\x9C\xDA \xECK@\xB0ԛ@\xD4E*\xDD\xD1\xFC~\xF3\xFE\xA3J\x92䳿A>\xFA\xE5\xD3v\xBC [\xD3 \xE8ѐ \xDE+\xB2\xF1\xB9\xD7\xD5yE\xE6\x8B\xEE\xB6\xE6uΰO\xA7\x85n=\xFAѹ\xBB\xD6x\;@J^\xBEW \x86\xA1\xD0\xED\xC5Ye\xF7mS\xF8\x9A5\xF3\xE9\xEEYA=\xBA[\xAAO\x9C\xED\xBDq\xB3=\xB8r\x85Ő: F[\xED\xE5@ę\xC2\xD5Va$$\x8A\x9C\xF8m[\x83\xCD*\xA3ȼl\xB8F\xE5/\xB7R\x91\xD2\xD4\xE6R,\xE7\xFC\xFA`M̙ә\xBBQ\x8E(\xF5Z\xB3'+\xC7\xDE\xCD7\xA5l0\xBC2\xFF\xE8]\xC3\xD3Y\xB9\xC6'N\x92Sk\xF6湧\xEC2mjT\xE9_+7\x948\xF9FW\xD5\xC6\xFB\x9BS2\xDAr\xAF8Mf́ \xDDzHr\xFE\xB6\xBF\xEC\xB5W\xCAҥA^1\x90\xD4\xE4D\xFA:`:\xEB\xDEx9#I\xA5ڴ\x99w\x97o\xF1K\xEA\x89W\xF8\xC3 \xF0Q\x9D\x91Mf\xD6&z\x9B\xD6fIP\xB0\xAF l\xA4IӷU\xB7\xC5O)ɩ\xBD\x85\x89b\xC3\xD8F\xA9k^Y\xE7k\xE21k)~Y i\xBD\xC9\xE05 \x80\xC3\x8CWQ]i\x82\xA95\xE6\xE7\x88\xBD\xFD\xC5\xDE\xFE\xA1\x91\xB1Y\xFB\xE9\xCE\xD63_~\x92_\xD8pi{\xE8\xE4\x93\xF3 u\xF9\xF2\xA05\xEF\xB1\xF5f*[u\x9Aw\x90E\xA4>\,h\xAD\xCC",\x80]@UG\xEE*GS\x93\x85瞲\xCA+R+\x97\xB4\x8D \xE9\xFE\xF6 \xE8\xD2\xE8\x95\x8F:uľ\xD4V\xE7đ@jIm\xD8o\xD0\xFE\xED\xA1\x89k\xDDf
+Op\x8EM\x890\xD2=\x92b \xBB Z;)X\x98#\xB4v\x9F"X\x9EMJ\xE3\xF3۞X\xEE$\xE2\xF18\xD5}\xE2\xC3\xFD<l+:\x8C\x81#\x9A\xC9h\xCBm=\xA4\xF1\xEA\xF6\xAC\xE0\x89LJ\x8BuV\xAFs
+\xD0D\xE55\xB8\xD9}\x92\xC5R3m\xC0\xDAǾ8\xDC\xD4\xE7`\xF2 ýF6\x80XfR\x8A\xB0\x99#\x98=|\x90\xBC\xB9\x80 \xFA at U\x8C\x83_\xE9C\xE7_,%\xF5\xEBnE\xB6\xC9/\xACYnK\x844\x8F\x8DnC\x9F+\xD3YzOr \xBB\xA1?\xBA\x96\xBAKv^\xE2\xA1\xCFD\x81\xF7˩\xF0+=\xEB9d\xAC\xF3\x82S\xF6\xA7P\xBD\xFClB\x81\xA5a=\xC2\xF4}:3\xAEh\xBF~;(. \xA0\xB1
\xFE8˫o_\xCAW\xFA\xCD\xE9j\x8C
\xFBn\xEA\xAEIQ\x81TyY\x94\xCF"\xBB\x8B\xB5aRė4g\x85\x8E͓\xED\xAE۷\xD6GN\xD2̢\xBF\xAC\xF5\xBCg\xCF
\xC3ů\xF2\xA3\xA4N{sLk\xEB<Y\xAAP\xBB\xB0\x96\xACU>%'cR\x86>\xD1\xE8\xD6\xF2#}\xBF\xB3o\x96_!\xEC\x8D?C\xE8\xF2\xE4\xA0$RZ{$x\xC2&s\x8C
r\xE5Q\xAD\xE5\xD2%RRV\xD0;\xC9\xFB\x896b¡d\x80#r\xF77=\xA8\xBBN\xEE"ETI\xAC\xEFDs\xEB }@\xE0
\x9Bo|f\xDB[yE쐉i\xD0_\xBC\xE6\x92)U\xF9\xA6G\x8A\x9BrwB\x91\x99\xAA|\x9810
>g\xB2ƭ\xA0B\xF3\xFE\xBE\xF26[\xE0F\xA3S\x87\xED\x98ִ\xD5>j"\xB3c\xA2\xCB\xE4\x8E[\x9Dc\x81\xB3\xAF\x99E\xD3}4\xD7#B\xA5\xA8h\xEF\x86
OK\xF1q\xA4\xA4戯\xE9\xC6\xEEN-\xF3\xED\x87\xE76\xF0
\xDD<Cc\xF3C\xA7\xB9\x84\xEER\xE5ư\x8DB}>\xDC\xC4\xE52C\xD9
˪y0P\xCC/O\xB6\x92fH\x8B*
+2\x83ʞ\x91\xF9O\xEC at s%
+ \x87\x84\xE6\xDE䳻
\xC2T\x8Av\xE3\x98"q\xEFrI\xAB\xA9\xA9\xDD\xF6\xFA\xFAǼ\xDDyp1~\x90\xF2\xA4 \xEC \x8D\x86$\xD4\xED\xF5b\x93\xE9
+\xD5\xFE'e=\x85\x85 \xE3\xCE\xD6\xFAQ\x9C<۵\xEA\xFC\x91U\xB6\xFA3g/\x9Cýb7G`\xEF\xF9j\xA6\E^\xA4
\x87\xBFYgK\x89Ԛ\xA9\xEDK 5\xBB4Q%\xC6\xFC\xD0)\x9E3ok!
+cvR\xE6K\xC7\xF4mj\xD8\xE5\x8D\xFCb\xFA\xE1\xFA\xF4\xB3\xE1\xDE<\xFC\xA6\xF3`\x99\x91 {\xFF\xDAL\xF8\xBCX>X\xE0jw\x8B\xB2M\x86\xAE\xBEB
+i\x9A\xCB8\xB53\xF6\xB5a\xFC\xB3\x8BC\xA19tF\xE7\xED-:\xF5\x9E\x8Fl}\xCC\xFD\xEBR\xE1\xF3U\xF7Ч \xAA\xB58{\xE7ۥ\xB5= I\x92҅\xD7m\xDE\xE0\xEE8\x81\x96Oۧ\xA5\xAD\xFF\xE6;\xAE\xA3\xBB\xA7ۤO \xCE\xFE\xB1Ճ\xB1\xA0\xEA\xFC\x85\xEC\xD1g8\xC1\xC8\xE5\xF2y<\xEE\xAB%\x94Q\xA8X\xFB\x91\x937}\x94KBRP\xB3\xE7i\xDFQ\xEDO\xCF<\x9A\xE6\xE4\xF7\xC2s\x86\xB2\xA1tK\xBE\x83O\x8C4S}x\xBB\xC9\xF2y\xC7\xE0\xAC#5ٶ\xDBLj\xA3>\xCE\xCD R\xDBS\x9C\x819y\x8F\x86ML\xEA\x9C4(i\\xFC\x96_\xAC\x899\x98\xEER\xE5ڰ\xB2\xA4\xF9\xD8\xEB\xAA\xB3\xA6xW at L6_ԛ~K
+\xC6Ck\xAB\x9Fv PKr:\xF2Cg\xE2\xCD\xE0؋\xCB\xB7\x8F\xFC\xB8\x87\xA6\xBB\xA3%\xFF\xBD\xA2\xEBF \xB0"#H\xF8 A Ck[\xA59\x965\xE8\x813g\xE7ε\x90\x99\xF00N\xF2\x8E\xA5Z\xAB\x9F_\xA0B|\xB3!q\xA2\xB9\xFD=\xCEi\xED\x843\xF9\x88\xC3\xD1_\x9A,%\x99\xB6r\xA7KP\x92,\xAF6=pC\xA0\x8E\xE6o\xF5\x8B)TT\xB4\x9B\xAD&\xA1\x9B\xB68
+\xE8\x91ŧ=\xBA\xC6\xDB\xEB7\xFBI\xDFi\xD5]\xFF\xD9\xFB\x8A\xB08
+\x88\xBC\x9A\xF6h\xDFI\xCF;\x85l"w\xFF@\x80jʕfȚ
+\xFB\xDD9
+\x90_\x9B\xE8\xCBaqdYI\x95\x95\x87m6 !\x8D\xE9\xA6s
+
\xBD\x83\x83A\xB5\xDB\xE1\xA6\xE0\xE9T\xCF\xADˎ(\xA8\xDB\xD2g\xAB\xC1\xE6\x95\xE63
\xFDSzϯ\xAB;wS\xA4\xF0\x8Bp\x9Ek\xA9 n\xE1\xE8\x9F\xE2\xF1\xB5\xC5\\xDB\xA9L\xAA.TKsj\xCBb\xBD\xC3\xF7\x80I
+J\xDBwMv\xF9\xA3\xC5\xCE}\xC9\xD6\xFB\xA7~X̼A\xF4m\xC8!?\x8D5\xC4Ĵ\xE4s=\xCC22sǝ\xCF;\xB6\xAB\xF6\xA0\xAAA.
1nf" \x8D=\xE81[$D5\xC4\xFA$\x99\xB5D\x84,\x8E \xB9mwe]J\xE0Dw\x9F\xFD\xC3
+\xEC>\xAA\xF0^^\x98\x81<\xF2\xBE\xD1
\xA2Eˁ\x94T\xA2\xBD \x80.w\xF5\x928\x9F\x9C\x9A\xC2\xC4{\xECи\xF7 \xA92B\xAD\x9Fw 5\xDA\xC2m:M\x9F\xEA\xEA\xD6\xD9\xFAh\xA4\xA85\x8A\x8A\xF6\xDC) \xC0\xF0\xA31\x8B\x8C\x96\x81\xC4\xC4ѥ\x86\xCD
\x8Bٹ\xB6\xF6\x8B \x8D\xD184
+
\xBC%O\xD5\xD7zz\x8E;\x9D\xC1,4,ө\x89Q\xA3\xA0y\xC7P\xB9\xBE~\xBC\xE1\x88G\xF3\x92 MZ\xCEڗ,,\xBFJXsj薣\xBC\xE0'WC\xA2n\xD6\xBB\x8FR\xD2ڦ3\xADߒ\x87\xD5Y\x85$ -\xA8:\xE9?\xC1\xDCDJ\xD7̀p8\xFAk=\xE8\xB9ҥ\xA30 \x8E\xBDȢZ\xBA\xA1t\x97W\x98\x93\x99\x8B\xEE4\xF6\x8F\xFE\xA3'2\xC9\xC6\xC4\xE1\xA1ަ\\x99Y\xF8d#8\xFE+\xA7\xE4w\xB1\xA1\xA6\xA7\xE3p\xADӷ>ӭ%?\xC9O\x95g\xA8!\xCBi+v¥!B\x90a\x84\xCBD\xD2I-7Н延J\x95\xEAx\xF3\xF5\xDD\xC0P\xAD\xF5\x9F\xED\xF4 Sy5
Ѿ\xE6\x96-O\j4\xE8\xBA:.\xB4\x9C\xAE;\xFCIf\x90\xDFP
\xA5Լ\xF8\xB0
+\x92Q\xA7\xD3\xDDP\xF8\xFE\xE1\xD5E*5 >\xAF\xE2\xC0\xE6\xC0IC\xCEP6#
+\xD8
+D\x9E]
Z\xA7\xED08\xBB\x999\xEF\xE8\xF2\xFE'\xA2\xB2\xF8x2;\x9BM\xABJ\xDB\xEC'\xB6t\xF0\xDD\xC5G\xEB>y\O\x81q0\xB2l\x93\x95? \x905c\xC7\xEB\x80\xC8\xCD;ж)mM\x80FV\xF4\xE9\xF3tyZ\xEB* +)\xDB\x8A=u\xFEB\x9F}\xDE\xF5x\xC7+\xF1痏\x9A\xE7\x82
+/\xA6\xC6xYUDe\xAD\h7{\xD6\xC0@\xCF\xD5K-'\x8B\xB2\xC9\xCDcQ x$I\xE1\x91f\xAD^\xEF\xB3\xCCNȇ\xD1h\xD0\xF7t\xB6\x91\xA7zݶF\xFA\x9A]\xC5\xC4\xD0vt\xD0.\xB6&\xE1W9\xFA\xCE.\xA3+t8B\xA1\xFA\xF9?%\xFB\xD8\xE1L\x86ڿ~\xE4P\x9E\xBD=@\x9F\xF9J3\xB6fƲ \xAC\xF9Rv\xF9\x81
\xBF\xB7\xE7q(\xED\xD1\xE7]\xFC
+\xA18?\xF1h\x83\xFD\x9B\x8B\x92<\x82\xF8\xA5\xB2\xBC\xF9\xAA\xC5bsߡB\xE1\xC4-\x88\x9C^\xD3\xF6w\\xD7\xD5%\xFE\xBAa\xAE\x9C$\x91W(\xF7 \x9D\xBA\x94L\xAD\xE9R\xB8_\xCC\xD8\xE8\xE5!\x8C)\xA8\xED\x8A\xF46\xABs\x8A>\xA5\xCE
\xD2\xC4W
+f\xF93M;\xB9)ǧ\x8C\xFF \xE0\xDA\x91\xFDb\xFEoE\xFB\xF2 Zע\x92\xFB\x91\xC8\d\xAE)gʊ\xAF-\xF6~p\xA9\x93\x80\xCFaԹo\xD4q~r(*\xC6V\xB5qD\x9E\x9E\xA2\x86};O.X\xBB\xC1{\xA9\x83\x80\xCF0T\xFBɊ\xAD~\x88*5
\xC9\xD2lH
+\x9E4
+ \xAB\xBF\xD4\xCA]\xF4\x9A?%Y at n\xF8EO\xCBT\xE7\xFF\xF7\xCF-\xCB7~n\xFE\xAD\xB0&\xE6\xA40\xDA\xCAu.A@\xAA(jW\x86O\xFCP\xA7\xCF^$\x88\xF8ԭ5d\xE0J\xF1d^\xA9\x825q&\xD1\xEF\xA4KF\xA6\xFB9&\xEF\xF2\x91\x89e at j \xA9\x9Dj\xDDNj0y at KF\xD7D\xB6}ۦ\xC1\xDDF \k!GX
+\xFA$ \x92Q/&\x89~#8\x86ǎ
+,k+\xF3\xF3I,\xF8~\x88\xADcuvu !+\xAA9\xEE;\xD9\xEE|"\x8A\xAC˷\xF4\xD1M\xD1mLܢCB at ZBv\x85\x8A\xA76\xA4;ӸNJ@\xAA(8\xAF\x88t\x9B\xC8#\xC2\xE1\xF0\xEC
\xDD\xEC
ݼ\xFD\x83c\xD3\xF3\xA9\xEE֓\x9F\x92!U
+\xDC:R\xE6fY\\x91k\xEA\xD6
+\xC5#\xDE^SMۛ\xB9lbc\x8E̅\xB0Ua8\xDA\xE5PG5\xF3\xDD9`t-e\xCB\xD5\x92
+5\x80,\xB5\xA6]\xEF\xEB, at j|i\xF6\x8B\x84@ħn\xDD\xF2\x84\xFFR\x8E\xB6\xA3\xED2\xF4\x87\xF7&'Ũ3+\xFE\xF2\xE9\xCE\xE8\xB0BH\xE3\xE3\xF5\xD9\xD9
\xEBl
+\xE2e\x92\x95+\x9CG\xD7a0\xDA\xFC?ǨH\xC8\xF2\xDA\xC2'{\xBBEI#\xFC\xAC
+ \x99@\xE3\xE3E\xC82\xC9\xDE\xED\xA6s\xFC
\xFDSzϯ\xAF:|\xF8xCW(\x81@`3o\x91ۊ\xAD%\xF2GL\x9B\xD9=\xFC\xAD\xFA\xD9+\xB2\xB2S\x94r%&\xE9\xFA\xB9\xC5\xC2\xEA)dWd-\xC9/\xB1dd\xA0\x9Cn/S#P\xBD\xF6\x91\xF9\xDCg2ڮр \x8C\xB6xO\xE5\xEC{\x9Dw&I\xB6\x92\xA3'\x9D\xB1lΊ\xE6\xA9\x87\xD4A9r\xB6\xF8\x82\xF6]\x93.Q\xB8\x87{\xBD\xBE\xB5;", \xC8\xEC
L4\x97\xB0\xAC\xA8-\xD9{\xA8s\xDD\xE6(\xF3\xF1
+\x9E\xFDh7q\xDC\xF2d^\x840f8$\xAA\xAC\xCAMı\xB7O\xA9\xD6/OS\xCC3\xD7\xE3)\xFB\x94;g\xB2s+\x9Fs\xEC}'\x89XU;\xBD\xC5\xC6\x90%k?\xFEh\xA0RIj}\xAFŘs\xA9\xE1miX\x84\xE9&EA\x95:\xD2ߢI\xEC &\xC8\xCB4\xE4i|NŇ\xB1#\xFE]\xA65?N\xA5.\xBD
\xCFM\xAFE\xC5y\xB9c "\xAF\xA6#r\x92\xA5\x8A,,,\xFF\xF1\xB0\xA1ק\x80\xAA+\xD5جZ'v\x9C\xEA\x91N\xD3\xF4da\xC0o\xA6\xA5\xAE\x9E\x9F\xB7\xF3\xB4\x8Fe\xBA\xB3\xEEd\xCF}\xBE\x93<\xBF馄\xDF\xCB\x85\xC4\x99\x91ގM\xFB6\xC5]\x94\xD8\xF6 \x86\xC3\xC1\xA9\xB7\xB6\xBC>GY\xED \xD0\xD5;S{\x83\xA1\xE6\xDAΆ\xF2\xD2c\xED\x80\xF5\xFD\xEB\x9E\xF27Y\x80Luws\xEDǭ8\xBD=\xA8\x96\xF2\xE3\xD7%\x813\x9A\xA3Ew\xB6^\xE1;9O\xB0\xF2wj\x8A\x86`\xAAH=\xFF\xD9 кΎ+z#\xC0\xE5\xF2\x85B\xA1@$\x8E}\xC8hs\xFF\x94\x8EG6\xAE\xFF\xDD*˅\xBATg\xDD\xF1C\xE4\x9Dx4'g-\xF7\xC8:\xA7 \xC8\x92E\xB7\xA0
+\xA7\xB6\x9CY_\xA0\xDC\x{1A49E3} \x8C\xAE\xEEӃ\xD2\x81Yb
\xFA\xE8\xBEwuĆ\xD1lRS\x88\xA6m9w\xF9\xBA\xD1\xC6\xC6\xC6n\xA1\x8B\xE3-7\xE0m2i\x83 U\xBCI:\x90\xA8\xB6\xB0<\xA8\x96}\xD2\xFF\x81z\xA4 t\x95\xFB\xAA\x88\xC8PG\x80\xD1u\xEA8\xF6\xD0]\xBA3\xEB\xF3\xB0z)5|\xE6\x8B\xC6͡:\xB5\xBD|\xDB\xF93n
+\x86\xA6\x99۾\xC7i]g\xFB\xA5
#l\<\xDC&X\xBAfRp\xCA>eJ\xDFx>,I_\x90\x939\x9Ds\xF4 ]k\xF3%#\x97˷sr\x9Et\xDECQC3\xE0\xF0\x86yM&Ehz\xC2b\xAD3p,\xB6\xD2e\xE4\xA6\xBC\xE2?*\xF4zK\xB7\xED{YXn \xC2\xE9\x{1BD63F}\xC4\xD0묉\xC9\xC2\xC2\xC2\xC2\xF2kb\xB2\xFC_\xE1\xD7fb\xDE\xF1\xE3O\xC0\xC2\xC2\xC2\xC2\xC2\xC2\xC2\xC2\xC2b
+kb\xB2\xB0\xB0\xB0\xB0\xB0\xDC&?\xFCs\xDA2\xE3\xFFQ&g&B\xB2\xB0\xFC\xCBaML\x96\xDB\xC3X\x9ERs\xF0\? \xF4_\xE9\xFC\xBEh\xFF9j\\x99C\xAF
/o\x9B.[\xDA̸\xF0yC\xD1W\xE3\xCE0s!YX\xFE\x8D\xB0&&\xCBm\xC2
]}\xD5\xDF\xFBלs\xDF_\xEC\xC8?\xA2\xB3(r\x9F\x97\xF5\xA5\x8E\x8A\xBA\xD0\xD2\xF1Y\xF9\xB9\xEF,\xA3\x94Μ\x9B\x9F\xD6\xDB̙5\xFA\xFB\x87\xCE\xD6褚\x9A\xB6i\xCCG\xEE/:p\xCB/\xD6\xC4daaaaa\xB9M\x8C \x97s' \xEEN
\\xBA遡\xF5\xFB\xFF\xFC\xEE\xED?\xCAO\xE7\xE7\x9E\xC8<\xDE\xEA\xE3\xC6\xF8\xD7ȏ\x8E\\xB9Νuם\xB7P\xFF\x95چ褆\xE6
u\xEA\\xE6\xAF]:\x96}\xEDNG\xB7\xD4M\xF6Ey'\xF2\x8F\xF5\x8C\x8D\xC5\xAE\xFC5\xF7\xDBk
+\xC9\xC2\xF2o\xE4\xFFFL \x96_ \>\xDE\xF7\x8D]\x98\x9B\xCF\xFD"\xBB\x87\xC4\xD1&\xBBnv\xDF0
+g\xFBm\xB8'\x84\xB9\xAC,\xFC\xE7__\xFEͬq\x87\xFFpM\xD7\xD0rc\xF4U\xCCs\x98'\xBE\x87oZ`\xBE\x91\xC44g\xEE<\xE6\xE4|\xA3\xE2Z\x80|\xA5E \xAA\xF9\xF7{\xFC\xF5O\xBCԃ]\xD4j\xBB\xB9 \x80\x9F\x9F?G\x9BI\x84
/\xCBO\xEB\xC5\xFC\xC2\xE8t\xB7:Ef\xA65ӌ\xF9\x9A\xA2\xCC\xD2\xF30\xBA\xCEn\xFFr\xDA\xF2\xC4\xFF\x87\xA0\xBAu\xD3\xFA\x99\xF8 ec\xA8\xEEn5c\xFE\xEFv˯\x82\xDC\xE5l\xDDX\xD2\xF8礚\xBFe\x9A\xA4\xF4\x8F\xDF-{|\x8D\xB3\x87\xAB`\xFER\xDBE\xF4\xB5o\xAF\xDC\xFC\xEE\xDC\xF7'\x8E4\xFF5\xAF\xF9ʨ\xCB\xF1\x87\x81K
7\xAEt\xF7]\xD1\xF5\x9D:Һ\xFBK\xFD\xB8p\xAF\xE7\xBF\xF8\x9B\xE6
+m\xAC}L\\x98\xA3̺\xC7\xF5\x95\xE7=\x86\xECˁζ\xCC\xE3?\xC4\xC8]\xCDL\xC9I\x85da\xF9 a\xBD\x98@\xB7{o\xB9TQ\x9D\xE8ȴ\xA4\x85\xBEp\xD6\xD5u\x9Fo0\xF4\xF4\xF5\xC1\xC6\xC6}W\xFB\x96E\xFD-v87
\xA3-\xF5r9\xFE\x911\xCB\xCDpb\x8D\xED\x89c\x83\x89\x82\xEEꐵ\x87_\xAFOw\xFB\xAD\xCB\xD0\xD5\xDB{\xE9bk}\xDDᬸ\xA9\xED\x83)\xA3\xA9\x82\x9BT\xAB\x89ә\x83\xF9\x81#\xA5I['\xAFZà\xF7\xC4n\xE8҄\xDF7?Z\x988.\xAA3\xA3\xCDݑ~\xF9n\xB7\xB9\xE8\xBFv
+s\xE7Z_k\xFD\xDE'a\xC7\xFCS_- \x9E\xDF\xFC\x9F\x80e^\x93ۤ5\xD9I\x86\x86(\xA8?\xE9y\xEB\xF5\xD1M\xD1\xDE)\xEB?\xFA ؍\x80\xE9n؛W\xBAG\x99\xB1\xB9\xB67v8m<C\xE9(p\xCCZ\x9Ca0>Ltg\xD3і\xBE\xB9n\x8B\xCE\x89\xFE?{\xEF\xD7F\x95\xEF\xFF\xBFRHФ
+\xAD`\x90\xD2
+U\xEC#\xB44\xA1[A\xAF+l]H\xAF\xA0\xB7\xC0\xA7\xB7~\xB8\xAE\xB0+얥\xBA\xF2\xE3\xD1\xED%\xB8v \xAC\xB5\xACK\xF0ۅ\xF5\xB6\x89\x84G\x94I-ٶ\xB2-\xB1\x92Bڌ\x92\xD0L\x9B\xEF P\xAAu\xEF^w\x9E\xFF@Μ\x99s\xE6\x9C3s^\xF3>?\xDE_cS\xF6\xAF\x957 \xB0;\xE4\xA8ߟ\xB2\xB0\x8AhS\xDF!e\x9F\xF7J=\x87\xB7\xB7\xB7\x97.]\xBBg\xBE$\x84\xC0\xDCS
\x98h-\xF0C\x82\xF8\x86\\xCE\xEEgmj\xB4\xB9\xEF\xF5?|\xF1\xA3\xFC\x94\xAF_Y\xB4\xA1*\xED`꛵
|v300,\x82c
+\xF1\xE2\xC8'\xC3\xD8_\xE8
+\xAF)t\xDDG\xFFU\xF3=/ \xD7M\xFAQݰu\xC4\xF8\xE5߆m__=\xB9.L\xB0!de\xDC\xD6U\xB3&\xC6;\xFC\xD7<\xF9\xD4\xD7\xFF\xB7M\xE0{wyL勿]2\xC3;.\xCC\xF1˲O~V\xF5@\xD0"\xA6ȫ&\xE3O\xEB\x8D1\xE9\xB1?\x98k\xEA\<\x93\xDF"\x8C\xC4\xF4 7\xE4\x91\xE7
\x9Ch\xEDx:\xE3W\xBF\x9A4u\x89%\xA5\xAD={c\xBC^\x8F\x8C\xAB\x86\xB4k\xE8~\x97\xF3\xB3q\xD4\xC1\xF9\xFE\xE3H__!
}\xFE\xC4\xE5Q\xB3\xE1\xC4\xCEDU\x98\xE2\xD7\x93a\x92\xE2\xEE\x9B\xD6\xF7\xBE%ozk\x98\xACV~\xDCν\xB9\xEEn|\x9De\xEB\xA5s\xFD\xEA\xD2Ҵ䪞\xFE\x96\x87\x94\xD98\xA6?P \xD5P`{s\xF3 at Gv\xB5\x8A @\x88\xE3EH\x92l$\xAD\xB9s\\xA7p\xB7\x88\xA3\xD3K\xDA\xFF\xFD\xA1]\xB6\xB3\x9FhoxmEK~ \xB0\xE2
;\xBB~\x9DX\xB2F\xD1\xF3\xA45!\xB9\xA0\xE6\xC8\xF1\x83\xA1\xDCY\xB7\xF9\xDFR\x82\xC1\xC5\xFC&r\x93[\xA0ͺ?\x9F\xF6\xBAk\xEE\xAB\xCB\xCBk\xE2XQ\xB5\xB8\xA2\xBAݯ\xE5TVL<`Q\xB7w]\xF4\xF8)\xED\xB569M2O'\xDF}\xA3\x89\S\xCC@\xE0\xFA\x8Ci\xAA\xFD\xA5DA\\xA5\xD4Y\x80\xEA\xDF\xEAGο\xA1\xB5\xCEu\xD1c\xFF\xF0\x8D\x9F\xA5\xD7ifJ7\xE7\xB9\xD4Ƿ\xC6?\xB81$\xC8Mn\xD2z\xF51\xC7\xB6E-\xE1b\xF2\x96\xF2 \xA0ڦ\xA3!\xAF\xEC\x87'\xFDv\xD5>e\xF7\xC6B\x89\xE9=\xF6QmI\x93eM\xEAL\x88EQT]\xD3o[\xA3/\xF5\xFBE\xB4C-\x8B\xE3\xFCY\xDD\xF9\x8E\xE9Jqi\xEB\x8E7A\xDBi\xDAa\xB3\xD9iۤ\xD5fs8
\x8E\xC9˗\xBF\xFA\xEA\x8B\xF3^?xB\xE2\xD9'\xAAA3E\x83
+;M;
\xE0\xF3\xB1\xC9\xC0ps
\xF45\x80\xBDF\xFEb\xCD=\xBAO\xAC\xD3\xEF\xBFk\xE7>\x9F\xF4_\xB9%qm\xDAڻ\xCE
\xE9;\xBF\xF9G\x9C\xC5/s}\xD4\xE4X\xE9A\xF7}\xF1W]ő\xF1\xAC\xE76\xAF\xB9.ly\xFF\xA5\xF2O*\xF7?\xB0f\xDE\xD4\xCAkS:\xF5\xA7\x8FY\xEFO\x8E\xCA}\xD0\xC3\xBEH&\xBEE\x89\xE9 vP\xFE\xBBC\x9Fr"_\xE8\xD7\xC7rF\x90|\xA4\xB2;=3\xE1(@B|D[\xC1\xA1i\x80m'w\x86\xC6jiNNa\xE1\xF8\x91\x92\x9F\xFBDK\xF0\xCB\xE7\xEEQ\x98\x83\xE3?ٖ\xAD"\xC5Z\xABzZ\xE2P\xFA*id\x85F\\xAFHUg\xF5\xAD\x89W\xBA\xE2B\xF3rZy\x96ȕl\xF8\xF6\xA2sCϱ<Ϗ\x8F\x93\xB1~?S\xF6w\xCC\xF3Sn\xFC`hr\x9D\xB4\xB1é\xDAȎ\xAD#
+k)\x9B\xEACApQ\xD7\xC8\xFB\x8F\xF8\xC1f\xB7\xB3}\xF9\x80\xCB(\xF5\x93~>0j
\xD6h \x84
+
+\xB1,m\xA7\xACx1}9\x9A\x9F\xE0\xF8XL؉\xF8G
\x88\xCD'\xF1,\\x81\x97K0\xB9\xB3\x8C[\xA0\xC7u\xE5\xE9\xBF
+\x93
+\xE6\x9D:\xAC"\x81X\xBF
+\xB1\x82\xDC ԙ_\xA4g
+r
+\xC3|\xE6ƛ
\xAEk\x9E\xAF\xA9\x81\xA5u "yM\xB3a\xB2\xC2\xC2\xE8\xBBR(
\x9D\xD6p|Q\x9FՆo\xEFn\xFF\xB8i\xB5jg-\xEC\x94ytDߧy\xEF\xADZiA6ZG
\xB3Ϊ\xE9\xD1#\x89\xC9\x80B;\x9A%\x9Ak\xF7\xB5S{\xAES\xBC\x9B\xE6ͮ;P\xD9\xF5`Z\xF2ı\xA3DZ\xAD˵\xA2M\xEA\xEEO\x92
_\
??뮼\xE8\xA7J\xB4\xD8W\x9C\xCBh\xB3\xFE-\xC5/KHȎ6\xBC|F
+M]\xB5\x9A֤DNe\xEB\xD0ء5\x93\xB0\J.\xE4\xCDq_\xEF\xF2\x91=M\xE1\x91!I\xB8\xB4\xA1,v}\xF5U\x8E\xC0\xD9Btk\xBD\x8B\xC0ܶ#\xF2\x8Ez `\xF6H\xC2\xD3\xCC
\xB9\xD7\xFB\xE8\xD0\xE5E`Q\xA6>\xBE\x83\xB8g\xEE[\xEC\x9A\xED\xA3#\xCD_\xCB*غy\xCD
+`\xC5\xE6]\x9B
]&\xEF}i\xBF2\xF2\xF9e\xFD\xC7\xBBOٰr\xD5\xDE\xE7\x8AZ\xE3A\xC5.\x9EI\x86oFb.[X?1\xC1\xF5eˣy\xFE95\xA9I9\x84\xE6l\iM\xF8\xAA\xA17\xD2\xEB\x92&\x9Cž\x87D\xFF\xFB\x8A\xCBm-\xA7\xA6\xEE\xBE\xDB w\xDF
+p\xB9\\xEF'^\xA9/\x96\xF2d3v:\x84b̙ ]G6\xB17;C\xC4ϐ>\x9E\xE8w1\x91\xE3\x80\x9A\x9F\xC7\xC7f\x9B\xB0\x8DN\9Ob\G\xEA}|\xE0 \xE0\x98\x84 B\xC2I\xAA\xEDWL\xC6\xD6f\xABH\xFF
k.\xDE)\xD4J\xFD5 \x92\xB3\xA5R\x8CG\x94\xBC/\xCF \xF8\xA5\x96\x96>\xEE\xE3\xE3\xC3\xF1\xF1_\xE3\xA7oy*\xE1\xD3\xC2~y
+m1\xBC\x{35924D1}%\xE4\x83\xFA\x9D\x80\xC8 IJJ !\x90Yi\xA1`\x8Dh~\x89,\xEB\xB8Ag\xC6\xC2\xE244\xA7\xAE\xAF\x95L\xE6O\x9B'9
@\\xF1\x9Bژ\xF9ގu\x83Ms\x83\xA8\xB6=\xB1Jq?\xEE\xD04\xD8\\xAE\xF5Ah\xF2\xA6]\x95\xF913\xF2\x87\xB6[(\x9B7\xE7%
+
\xD8,6\x9E\xAF_\xD4\~@xT at +/G\x89 IDATxT|F~9e6\xF3\xDCm\xCD\xEC\x90r\xA7\xF5\xA1\xBB\xE3\x82[\xC9ڌ\xA8\xD9#\xFA\xDF\xED\x8A|_fkI\x9B\xB9\xE02\xF2\xC6\xF6\xBFw\xD5\xE5\x86\x95@\xA2\xA0 \xA4\x8D\xFD
\xB91\xF3\xB2\xA4k\xDEEd+g\xCAɖ\xDC(\x9Bc
+$
\xB0\x8D\x9F:aXWߨXͿk\xEDveZfW\xE5;\xC7l\x94Lkkq\xD0
+\xACЋډ\xFD"\xFE\xB6W\xFA\x87\xFC\xD7\xFA\xF8|
\x8F\xCBe\x9Bz\x82
+
+\x8F<r\xD7Ş\xC6\xD3 \x80 at Zۓ\xB0j\xA5\xC0\xDFχc\x9D\x9C\xF8\xE15i\xA1|s\x9Bh\xC0\xE1 \x9Fї7cҎ\xE5\xEC\xAB\xEE|\x97Ys\xF9j\xCA
\xEB\xA1m\xF8o\x85\x8D\x9F\xBBG\xEB\xF9\xF9{ \x9E\xC8{\xE8\xDF\xC28\x80\xEDO\x95}\xDD\xFC\x80\xFF\xFA\xF9}nK\x80\xBC\x92\xC3n\xA4><\wĖ\xF0\xC8ڒ\xE7\x83\xEE]\xE3a\xB2\xCD-e\x92\x81\xE1\xF6\xC2H\xCCE\xE1\xFA\xFA\xFC!۹\xF3\xA9m\xBD\x9F\xB6bsrJl\x80\xE3r`\xFB\xA0 \xF8\xF7
i\xACZK\xBF\x90W\x90ڥ\xDD\xE6\xEBR8
\xCEW\xEF\xC7&\xFEB\xB4C\xF1\xF5\xE5B> \x98Ե%d\xE1\xB9\xFE\xAC \xC0\xAE\xFFP\xC9Z
\xF8\xC6d\xF5\xD7\xD4\xC6\xCA{\xF7\xC8S\xD8\xC0Ȼ\xB5D\xF6Y\xB1 0\xAEP\xF3\xC2
L\xFF\xDEC\xB6\xE4F\x88\xC9\xFAYNv0Js~]\xDD\xFDZ\xD1\xDE~\xE1$\x87\x83\xAA\xE9\;&
+\xA7\xBFa\xD9l \x8E\xC9I\xF3W\xA3\xA7.}:\x8E&)\xA7 \xC49\xF5\xAF= \xFC\xA8\\xA73C
-\xB8\xA2\xB0\xA7\xA39\xD9M\xD6A\xDF\\xC6\xDAvun\xE3X\xE6-,\x82\xE9\xF5l\x95\xECȯ\xE7
+;l\xC0<C\xCF\x89\xB4\xFA\x804S)\xEE+\x9F9\xD9\xD4\xD7>N\xDC8\x93"\x9B\xFCb\xE7 \xD3\xD4\xF7[o>\xCBX\xA1G\xA59\x99\xC9o\xDE#\x8CX\xC0g\xF3~\xD0\xF3%\xC5
\xFD\x81\xB9\xB1'\x86_Θ\xB1#\xDBu\xBF\xCCS\xC9Z5\xA3/\x97\x957\xB0\x83Ҋ\xF7\xA7Wʣ9W\x9A&\x8AE\x8BN\x95t\x8CQ\xA5]#\x8F\xF8\x81\x8D\xABEW\xE6o\xD4\xCC\xA6\x95\xFDp 4\xBD\x96 \x90$Yx\xCEY\xDD͋{ڧ0\xCCg\xF2\xD2`\xC4=|\x84\xC7\xDCЯ\x96ypB\x81\x82\x9CȊ\xE2\xB7\xED\xE2Ԯ.\xF5/\x88k~ܖ
\x92 \xA5\xAB\xDAET\xA8\\xD1\xC5\xFD~\6l`\x86\x85ܑ\xF8\x9F\xD1X\xBB\xA8\xB6\x9B\x85w\xCF=YO\xD0\xF3\xB7yaߗ\xD7|\x89\x93\x9E\xAC\xD8\xFA\xE4
Ku\xD3\xFE> \xF0\xB6e\x92\x81\xE1\xF6\xC2HL\xE8\xE4\xA9D\x9E
+\x90
+\xD9\xF1\xE5\xC0\x89ށ\x83gɳ>\x9D\x98Z\x89+$\xEE \xA4\xE5\xA6\xC0\xDE7|zfH \xF0\xF2\xF2\xC2իWa\xFD7$#\xDF5\x8AK\x93\xEFT\x8BI\xD7\xEA\x9Fm\xA4\xB253\xB1-%zJ\x9E\xE2DeɝY\xB3\xB9\xD0KX{\xEA\xD5\xEA\xA89Ye\xECk\x93\x976\x85\x98TU'\xAB\xAA@,\x8F\x8F\x8F\xFB\x87\xF9\x8FkH\x8A!k\x96\x90\xFB\xC8\xAA\xABϯY\xB3\xDA\xFF\x9E\xBB\xD7F>y\xF0H\xF8\xAF\xD3Kbǜ\xE5\xEE\x92ʮ'\x8F\x94\x92\xB9\xA0\xE1\x80oѹ\xB7\xD9l\xD8\\xB9\xBF\x95[\xF0\x88\xB9\xF7\xF5j\x88\xB5\x8F\x86\xDFb=\x98\xE5\xBB\xF3\x94đs\xEF\xC7\xDFȱ\xE9\xF5\xE4j\xE9LN\\xF0c\xF6ج9\xF3F\xC9\xD9\*8Q#\x8Ap\x97\xB1~?\xD6
\x8F:\xF5\xC1\xF1\xDF&\xB8ƒŲ\x9A=Eϧ\xCD7\xA7\x88\x99S
tw%\xA1D\xE5h\x86\xF0\x96\xF2f7\xF4\xBE}\xF6\xCEG"/&\xC5/m\xE0\x83\xA6)\x9B
+\xF6\x91\xB6ڎ\x8D{K\xE3\x83\xE6$\xCB\xF3p\xB9| +\xC5\xF0\xB4A\xC0\xF8g\xA7K\xBBޮx(Ё\xB1\xBA\xAD?\xB9D\xB1\xB7+\xB5\xC7/_\xE58
ή\xB2W#B\xE6ׁ\xE9`l^\xA1j$+\xCA@\xC6!\xED[\x82\x83y\xFDC\xB1\xC17\xF4\xA3NQP\xC1o\x9Dpf\xB0\xF5m\x82\xC8L\xFD\xA8=&\x9CQ\x97\xCBd\x85\xFF\xF7\x96\xB7Ď\xB7r\xF3͵\xE0\x96ԗ\xCBfٙd`\xB8\xAD0\xD3\x91ϴ؞\x99xYT0 \\xA4\xF7E\x84\xAF5\x98\xB8$>\xF0\xC0\x9A\xAB\x96)\xA2\xDB-67Z\xD9s\xDC\xEC \xBE\xFCk\xA2Tw\xE4x\xB6\xBEw\xFC\xF8\xDEhw+[
R\xFBC \x96wkU9\xE5\xF5\xB3}\xF8\xC4p \xDAԧ|gȋ?3\x8AB\x9D\xD2@\xD3!o\xD3\xCD\\x87\xA2\xBC\x92\x9EI\x8C\xF4Hm\xAC
\x9AHT\xE4(\xB3\x9B\xD0H\x8E>\xD0\xFF\xEEj\xA9\xB8\xF7\xA0\xE6\xF1\xD5Xp8 \xC0\x8D\xDA\xDF\xD1\x802G/Z
'\xF0Y\xD2\xE7\xDB\xD2[\xA6u`\xEE},2S\xD6:\xC5\xEC
4\xE4\xA01Fh\x8A\xE6\xAC'\xC8Zy˾\xCFP}\xBB*\xC4\xF5\xDA[\x9F\xD5\x90\x94\xA3\xEA\xF9\xC5\xF6\xF8\x90\x8AG\xDF\xF6R\xA4\xFD\xF3\x847\x9B;\xE18 K{Q*{\xE6\xA6ˏI\xA2D\x92\xB4\xAC\xFC\xDA\xBB\xC9p\xFAãr\xE5\xC0\x85\xE7\xD3\xE6[ϣO\x9E\x9D\\x8D֡}3s3\x97\x9B\xB7/\x8C\xFF6\xB9 \xA0\xF1\x9BV\xC1\x8D\xFD#\xBC\x8A\x84\xE4\x95c\x83\xF9\xEErߛ3=\xC6\xF1\x86G\x89\xC9YɯN^?\xB3"L\x96
+\x8B\x92\xA8\xDE\xE6\xEC\x88L}Ͳ\xC0\x96C\x8EZᜩ\xA2\xE7\xDBA4\x89g
\xF1E
\xCE\xF93
\xF6q\xF1\xA6(_ \xFEkL\x89\xC9\xC0\xC0\xC0\xC0\xF0\x8Da$\xA6\\x82e\xA5? x\xAAOS\x81ã$\xA5\xD7yO\xC0:Lbf*\x8C]_\xF6؞\xD3\xD7\xEA+0\xAElP \x80_4l<\xF4\xE6~! _\x98\x83\xA3&ç\xFAZ
+Hi\xFF\xA3\xB3\xEB\x8C\xED'\x8F4\xA1\xB2\xC7\xB0;\xBE:o<\xEF\xBDjf,\xE3\xF2y \xC6.x_\x99 \xB8̥ߘ
\xD1\xF2ʵ;\x93\xE3\xDE9\xFC\x8BҮ\xE3\xDBB\xFD/\xFE2\xFB\xF7{G#_QK\xEC\x93m\xEF\xEAB\xE0\xB4D\xA0\xDD{\xD6'+\xB1T\xC1\xC7\xD4( \x90\x99\x91R\x91-\xCD%#\xEE\xAF\xEE:\xBE\x9A\xF07\x9B\xCD\xC0=\xAF
+
\x8C\xAC\x8B
\xABX\x8B\xF0\xB7\x87\xC8+\x93XG\xB8v\xB0Y\xD6-x\x806Tm\x8DS5\xA3\xF9\xE6vbZ /AH|J\x88\xDBOsoCdfSi\xD7H\xCC2Ԫ\xBE\xED\xA7\xA4\xB8\xE7\xBD9\xCBh\xCC&#\xF8k\xA6Js\x83\xC2c\xD2\xF2\xE5iK_\x886\xB7W\xECL\xAF֔\xAA\xCEeoh\xAFe\xE6-D\x92\xAFv\xE6\x83\xEA\x93\xDE<d\xAD\x86\x83\xC3\xE1q\xB9ll\xD49\x9FQ\xF93\xF19+QRYpy\xA3? m\xB5\x86\xAC\xF1\xE0\xD1\xD8q\x85*=>R\xB9e
+\xD8\xAF\xC6\xEEqp\xB8\x81\xD2\xE1vyCm^\x81Dc\xD7\xE1\xF5\xF3
h \x97\xDEo\xED\x83i\x9ADBrR6\xAETӦ\xEB9@\xFB?\xF9;'H\xCE,`````X.\x8C\xC4\\x9Cqp\xAB㨯ߗ\xC5Սuul\xCBϊa[\x8Cků\xCF.ĝ\xD4j4\xFF\xD1?\xF2\x88?\xC7a\xFD\xD0:<PQ\xBF\xD7\x80\xF5\xBDP\xE2\xB7W\\xCB4\xC0ްY*\x95\xEE\xDF\xD9\xFF\xA4"\xAE@\xAA gUH\x9F|w\xBA\x928>\xB6 7DR\xBE_▼\xAE\xBBz4\xB7\xB4x\xC1\x82\x98\x91\xE3M\xE7ӟ\\x8B\xB0\xE8M\xC3oܹe\xBF\xBD$\xC4\xEB\xF8>\xF8;\xC0>D\x98h`Tێd\xB2\xF2\xB8\xAD\\xE2f\x95\xB2\x9BL\xB6\xA0\xA0\xD9 _Ѷ\xA0]\x9C@\xA5[
+D`\xDD̿\xD2~kG \xB9\xB70ʠ~a}b
+\x87l\xC56\xE40\xFE\xD9Y\xA3\xBF\x80\xBE\xB1w8\x9BͶ^\xF7X\x80\xB1\xFB at hr\x89\xACQ\xBB?)d\x91(7R\xEE\x95\xEFI\xC8S\x96v\x8DĻ+_\xBBnw0\xE1\x9As(+\xACL~\xF4Q\xEC\xE1\x8B\xCAU\x9A2\xF7\xFF\xE5\xA5\xE9\x8D=#\xB9̼\xF1\xF8\\xFE\xEC\x9EE\x8E\xF9\xC2\xCFq\xC5*\xDD"K~\xD0\xCFl۶\xED\x95\xF0\x8D\xAF\xC0YɯN\x9D\xB5b\x92\x80ȣW\xAA\xB4\xE7^\x85;\xBAQ
+!\xEE7\xC4\xF6!\x80_+z7\xCFl㺐 I\xF9Ĺ\xED}g\xBF\xF2\xCDI.M\xC8Y5ׄi\xE9\xDB\xEE\xA7\x91\x8A\xA1Ҕv\x8D,\xA3\xF0 ƻ\xCFb\xE8\xDB+
+H\xD5\xC1\xB7ޛ\x8A\x93\xAE\xF6a\xB7\xAC\x83\x83ֿ\xF5TJID\xA6\xFB\xB6cb\xE1Ɛ\xA0\x90\xA0\x90\x88u\xAC\x8D
+
+\x89\x8A\xBB]M\x98\xF5\x9A"G\x9B\x9BL\xB6*\xB2\xA2(\xB3q@\xDDV$a\xC5\xE5)\xB5\xC7$\x9Ezp-\x88\x99eo\xBD/\xD0{k~\xB0\x85\xFA\xAC\xB9\xAFa/\x99\xB3)\x88+\xE0ÅA\x91
\xFC\xF2G\xAE\xB8S\x80\xFFJwS!m1\x8D|\xF8N\x97\xC1}\x96-lq\xCEBJ\xC5\xF5\x8E?;f\xA5\xE4\xAD\xDCm64\x97\xA5
+\xD6'6\xC9\xEAGl\xB5BO\xE3\xAE\x90\xE9Dhh\xE8\xFA\x84\x86\x86R\xF37<\x82\xDD\xD4Y\x95\x9A\R\xD8J\xB6\xE4z\xB0\x86\xBA\xA5L\xFA\xDAsY\x82\x84<ec\xCF\xE8|=čjw\xD8\xC6F\xCFi\x8F\xAB6\xF1.\xD4$'\xAC\xB0X\x92*y\xA7\xDEt\xC3_m
hn8\x90\x9B\xCDƥD7v\x8D9\xCB\xCC\xC7G\x80\xBA彮\x82\xB7[\xF4
+\xBBHd\xAEskF\xFE\xC4\xE4\xEFL\x8D\x97L\xC2\xE6\xEF\xC2\xE4\xB8BU\xF6\x8C9\x9DN\xA7\xD3Z/\xA6
e\x95)\xE5\xE5)\xA2p.\xF0\xC9AB\xFE\xC9\\xAFBl\xE1\xAB\xDAFUA':\xB7\xB9S\xAD3\x98=\xE6\xCE7\\x94$
+xwo\xA6F\xD6\xFA̜
UA\x9DyWSx\xDC١v\x905Ս|
\xA4\xBE\x9B0VL\xA8\xAB\xA2+º\xFA\x8F\xFF%61\xE2\xC2{]
+_\xED\x85{\xBCȶC֩\xA4̴\xCFu
+\xAFv\x87'\x85\xC0\xE1\xD0@\xE3pY+]\xEB\xC9A\xB7\xED\xE2d\x92 \xA4n\xFA K>(\xFB
+\xCDf\xB3\xF46\xA6$T\x90\x855\xADC\x87w\xE6\xEB/}g\xC3\xEF\xF5\xDE\xF7\x8Ei\xE0\xC1\xA2g\xEC=\xAC\x89\xD8\xE9\xE7s\x96\xB2c\xD3\xEE\xFF:]W'\xD3N$\x81
\x87\xA6\xAB\xB3\xF3\xF3\xB2\xF4\xB8k\xAA%\xFF\xC7
+\xC5\xEB\xB1 \xBC\x80\x8B1\xAE!I
+\x87\x9E\x99\xDEW\xC8n\xE8\xDC\xFD\x93#\xAB\xC3VO_}rP\xA5\xD1d
+\xCF\xFCƥ\xE1I\xE9\xAF^I\xF2o\xE1\xCC=\xDBBI\xC8Z{\xCEe\xC4/\xB6ć\xB3\x86\xC8!\xFB\xE4\xF3
\xC9\xD8u\xB9\xA2\x83>n\xE72\xD2#\xE4XZ\xD4\xD2\xB5\xA6*Np -U\x9C+\xCD\xF2\xBC\xB98\x9B
.\x92\xA4\xE4\xEF\x97Sf\xC3\xC9\xFF9ڐ)\xADx\xFF\x88\xB3%m&\xCEW
\xADa\x95{\xBAJ\xC5
+\x97\xD8\xFD\xF2ƍR\x90G
!xy3!\xE2\xCA\xFE\x899\xC6ݐ\xA47K>\xBA\xC8 \xE2\xFCm\xB8\xDB}\x83Ro/.\xEC\xC6\xDE\xF7>\xE8\xD0X\xB7W\x94m\xFA\x8F\xFBW_\xBDt2\xBB\xAD{\xE7x7 \xCAu\x8Cmy\xAB\xF1`\xA64\xA8\xF1ૉ6\xCA\xFF3%\xAF\x89\x84\xACqD\x911\xAFB8+ס\xAE\xA1\xFB٠\x897J\x88-Zf\x92&\xC32a\x85=\x98\xBC\xD4a\xB0\xBEaN\xA7\xB8M\xFFva͆\xE1\xEB\xFA\xAC\xF1l&\xBE\xD3\xE9t^\xBB~\xFD:\xAE\xD3\xCEk4M\xD3ׯ\xD19\xBE\x9A0}\xC3\-\x8Dy\xA0[\xEF\xFFH|\xB0u\x83\x83\xBAO\xF4\x86\xB1)o\xEF\x95\.\xBC\xBD\xBD\xBD\xBD\xBD\xE1El\xDF\xC4m\xD1M\x84F\x85sXԒ\xA7N\xA9\xD4\xF90\x9B&&
\xC1\x9A 2\xDE
S_\xBB\xF2ݡ)`e\xF8#\xD9\xF1\x94m\x9BR\x97\xED<\x95\xF6\xC7\xED\xE4S?
\xABWG\xF9\xB0t\xFE\xEE\xA8ֈ\x90\x84\xBD\xB9I7dMύ\\xBC2 pV\xAE\xF6\xF7\x9C\x9D\x89 \xB4E\xACw\xC4\xCB\xF7N\x8E8\xC0\xE1p 8
p p8\x8E\xAF,WC7oz\xB4\xB3.e6sh\xE7\xAF\xA5\xEF\xFC\xE0\x8A8iY\x8B\x85\xEC&\xC3\xBC\xE0\x90[.v\x9A\xB2\x83\xFF5\xBCI\xDEJ\xDE \x80\xB6\x86.88
\x9Ep\xC8\xE2\xF4 \>?\xD3\xD5\xE3 \xD9\xD3\xF4r\xAEȕ\xB9\x81\x86Ԗ
+\x87jE\x86\xA2\xEC&\x9E$}_~\x8Am@\xFD\xEE\xC9S\xD6)\xD8\xE1-m{L\xF45\xBC\x96\xDA{\x9Bg!\x9EH\x89\xF14\x9D\xF4@\xFB\xAB/\xA4\x97
+\xF5\xD5Y!\x8C\xC6d\xF8\xBF}\xE6̩U\xBEw\xB2XN`Ŋl +V\x80\xC5b\xB1X\xAC+V\xB0XKusz\xB3\xDF?*\x9F\xDF}\x88\xE0/\xBF\x{1B9AC3}
\q\x9B\xCDf\xB3\xEE`c{Ŋ,\xD6
\xD3\xED\x98\xC5b\xB1V\xB8\xFE8W\xB0X\xB8\xC3ժ\x9D\xAC\xE9\xE3\xC0
+\x8B\x98\xF2\x8Dq¹\xC4QFb20000|\x87a$&\xC3?\xFFj\x93\x99\x8B\xC9\xC0\xC0\xC0\xC0\xC0\xE0\x99\xA6\xB7\xBA\x99\x98n\xE3?\xFFR0VL\x86\xEF0\x8C\x93\xE1\x9FƊ\xC9\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xF0\x8D`$&\xC3m\x86\x91\x98\xB7Fb200000000\xDCf\x89\xC9\xC0\xC0\xC0\xC0\xC0\xF0O\xC2\xF5˧/|\xF8˾\x8FO;\xFE\xB7s\xC2\xC0\xF0Ma\xBC\xFB000000|
.\xF7\x9D;m\xB8\xEE5\xEB\x90\xCCA\xDF\xBE\xEEKyc\xA0z\x9F\xFC\xF8\x8E\xF2M[b\xE6;\xE2\x9Aa\xC6&F\xCE8P\xF3\xB7\xF0\xDF\xDD/XF\x97\xDF;\xF5\xD7+Aۤ\xD3+\xDF/\xAA\xC8\xCF7F\xFE \x82\xB3\xE0\xCA\xFFh\x89\xC9\xC0\xC0\xC0\xC0\xC0\xF0u`\xFB\xF9\xAC\xB4\xD2w\xDC\xD0\xD79~\x8B\xF7\xAAר\x9F\xFD\xF8\xFC\x83\xDF{rF_\x9A\xFF\x87\xEC\xFD\xCBԝ<\xDCp\xCB]\xC1\xB6Ӂ;6<,
+\xE4,/\x89\xAFF.\x8F!\xF0F"ۗ\xB6\xEB\xDF\xF4\xC6n\x8C\xC4d`````\xB8u\xAE]\xF7\x89\xBA/b^\xE8\xF5랦\xA0\xD9\xCE\xFE\xBD\xABx\xC9\xEB\xD3s\x82f\xE5\xA2\xE0\xFE\xEF\x89B\xAF\xDFq#֊;`\xED-
\xF9\xFE\x9E՜\xE5'\xE1u\xFB*3\xE7\x8D\xE1\x9FFb200000\xDC2\xDF\xEEW\xB7\xD9\x86s\xD37\xEE\xC8X=\xFB\xF3\xBA\xD5:\xF8\xBBO\x87\xD4\xFF=ģ?\\xE5
\xD3\xFB\xEEU\xC1\xF3N\xFE|U\xEB\xEE^\xB1\xFC$\xEEXx\x98\x81\xE1\x9FFb200000\xDC2k\xD37e\xA4\xCF\xFB\xEA\xBD'\xFBy\xAC\x80k\x8E\xF1\xCF\xCC\xE7TF\xC3\xFF\x8C{\xEF\xE8\xFC\x97\xC1w\xDE\xF4\x9Ag߸\xC0_\xB0\xCC$ :\xE8\xABn#\xE3^\xB7~'\xDF\x8Cu\x9D\x81\x81\x81\x81\x81\xE16`\xFD\xE0\xAC \x81\xC4F |5\xFEA\xF1gW#B\xFEM\x99\xF0h\xFA=\x81\xABW\\xA3o2E\xF2ˁ\xD3'\xFF\xEA\xBD%e)\x97\x95s\x92 ܝ
\xFBX\xAA\xEF̯k\xE3S\xDF\xEC&n\x8C\x93\x81\x81\x81\x81\x81\xE1\x9Bb;\xFB\xD9\xFF\xF7\x8A\xF5\xFEW\xA3\xA6\xD7\xF2֦\xFCi\xED\xEC\xD1k\xCB8\xBD\xB3\xEA҆_\x8A\xD6z/; \xC0\x8A;\xEF\5c
\x9D:}\xF6\x94\xE1\xCE~\xF1K00\xFCa$&\xC37`\xEA+\xFDN
+\xA8\xA6\xC2\xCBc\x89\xB0[\x9Fym\xCA\xF0\x{1A9FB6}\xAF\xC2\xCBcܸ\x88:\xBCy\x8E\xD1\xFF\xF9ۉC\xE1\xBF0
+\x93\xE1\x9FFb200000|M.\xBFG\xFE\xB9\xFE2\xFB\xC1@\xC9\xEF6\xAC,:\xF7\xEC:\xE5\xB8F{
U\x91'\x9A\xAD\xB8{U\xBC\xFC\xA1u\x81\x9E\xE5\xE9M\x93\xB8\xFC\xF9\xE7W.CpǵM\xC2F`2\xFC\xB3\xC0HL\x86\xAFɪ\xF8\xEF\xFF\xB1B\xE0w\x93\xAD\xCEw+\xEF\gE\xE0\xE6\xEFm\xD9\xE8
\xB1\xD4J\xA0\x9B&\xB1\xEA\xC1\x88G\xAD\xF0\xBF\x9B\x97\xFF\0\x93\x81\x81\x81\x81\x81\xE1\xEBr\x87\xB7`\xA9\xF59\xD3x
+<
+ at N\xA0_h\xA0\xA7\xB7\x94\x847\xCF\xFF\xEE\x9B灁\xE1\xB3\xA2\x9C\xE1b\xB7\x98\xA9|\xA2f3\xE5a\xD0\xE9\xEBASf\xF7[\xA0ora\x9A2\xBF\xAD[\xB6[\xBE\xDEmQf\x93\xD9~\xBB3\xC3\xF0O\xC1\xB7\xD9\xDE\xBEE+\xE6\xFF&\xC6\xDE\xF6\xA1;N\x8A \x98
+1\xF5\xB5\xFF\x95\xF3p\x8A[ \xD0v;\xD8\xAA\x8A\xA6\xC1\xE5.\xAC@\xBB\xBE\xECiyZKm\xCCnr\x97mR\xEF+\xF9\xEB\xDEù\x8BƱ\xF4V\xFA5\xC59[R \x94~\xE0\xF4 \xAC\xBC7Z\xC0`\xD1\xF7
?\xF3\x95\xDF]^\xC0իWqu\xE2\xE2\xE7\xD4\xE0\xCD烢\xA6 \xC0;dGVR \xEC\x9DU\xBB\xEB\xFA\xA9`>E\x85=\xFB\xE6\xCB\xD1
+i\x82\xCF\xE7\xA0(H\xEA\xF9!l \xA0
+o\xAE?~\xCE\xD1\xCEh\x9A\xA2\xC6F\x87
+'\xDF{+\xAFBU\xDA\xE5؟tK\xCD\xDA\xDCS
\x98h-\xF0C\x82\xF8\x86\\xCE\xEEgmj\xB4\xB9\xEF\xF5?|\xF1\xA3\xFC߹\xF1-'\xF7\x87 m\x83\xB9\x8B\x97
+՜*\x9D\xAAR\xE5F-Y\xB4\xA9\xED\xD5\xF6\xA8\xDD\xF9Q\xBE \xE8\x81\xF6\xD7\xDFz\xBF\xA0b\xF59Gm\xF8\xCC
+\x98uj=\xE7\xF1Bߥ\xAE\x98O\xD6'jK\xE3\xFCV\xAD\xE02\x96LM\xC1\xDB{\xEAs݄\xF8\xE7\xD5)\xD3UH\xAB\xAB\xFE\xF3b\xEA+Kg\xEC\xDA\xD8\xF0\x9Fuʪ\x93B<-\xAD\xEB~\xEBC\xA3g\xB1\xE5\xED
+\xF8m\x91\xA5D͔\x9C]\xD7\xFB!G\xB8\xC5\xD5\xE8\xDA>\\x93\x96\xB4D\xFA\xE6^\xF9\x8B\xEF\xDD\xFDJy\x8A\xC7\xD2\xD1ww^\x89\x88\x85ߤ.\x96\x826\xB6
\xEA\xBE*\xF0\xF0\xBD8\xA9D\xE8sY\xA11C;
g\xAC\xA1\xA2pO /\xA3\xBD\xDDj6UiS߬\x8D\xFA\xC6W\xB4;\x9FN\xD1T\xF5-u\xA9\xDBPn\xFF7a\xAC\x98\xB7{_{s\xB7\xCEr+\xA7\x98\xE4 \xE9\xBA0\xE9
t\xF1D\xBA\xF4\xE8g\xF3\xE2
+\xBC*\xE2q\xC2\xBD\xDA\xE7\xE1\xAA\\x9E\xAA\xEE\xFD\x91EmZ\xA6\xDE梲\xB2\xAA2EEEEeeE\xB9em\xE61ٜ\xABu\xCA\xD6K\x8E\xA5\xEE\xE1\xC2\xC7Z\xF8\5
+#\xFB\xE9=\xB1q\xD5o\xBC\x91\xB7S1\xE8\x8A`5\x9D\xFE@\xF3\xA7\xC4\xC4\xC4\xC4_\xFC\x89455\xD9z\xF8\xFB{\x9F\xC9\xCC\xEC\x80\xFF\xDD\xFE\xDEƼ\xEC?\x8D\xD3 l#25\xEF'{\xF7\xEEݛ\xB7E\xA5\xFE\xDCA[?T\xAD\xC9+ݻ7g\xEF\xDEL\xC90i\xCCȇ\xA1c
Dᦶ\xECh\x8B\xC5\xE2p~\xC1\x91/4\x9D\xF3~\xB6\x87
\xDD\xF7\xD0\}I\xEB{ۊv\xA5\xA6\xA6\xA6\xA6J$\xBB\xCA\xE4}\xF35\x8AEQT]\xD3_\xBDF_,m\xA6#\xC6\xF9\xB3\xBA\xF6\xAA]\x9C\xC0\xB8\xC3\xBF\hT\xF4
+\x93fnZ\xAAw\xA6G;T\x9A\x90\xB57\x93qllj\x92\x82\xAEaW~\xD8\xFE^\xFA\x82
+\x9FRq\xDD\xEE\xD7u31\xA8\xA3\x89{O\\xF0\x90\x82\xDD\xFE\xC3\xD59\xAD\xAF\xE4&\xC7\xE0\xF2e\xDB\xE7\x96\x94\x94\xB4.\xC3v\xF9\xF3\xCB+\xCD\xD9
8[$\x{1292A6}K7\xC9\xD6?\xBB\xB6\xBD\xB9[76'\x8C\xEDs\xA5\xA9\xEE\xE4E\xBEL 6MI\xE6!\xFD\xDF\xD6\xC1C\xD9R͍\xAA\xA5\x89\x84đ\xE9OhSU4\xAB\xFC\x83O\xF3\x92;\x8D\x8B>\x96\x81\xE6\xC0\x84\xBC\xA6
j
`>\xD1(\x8D[\xEFǒ\xE4\xCA\xDB\xD5:\x83iޅh\x8B\xAEY\xDEi\xBE\xB9
+z
+\x98\xFA(;;\xB1s\x80Y-o"\xEA\x9F\xFA\x9E\xEF*]\xBF\xF5\x80\xC9\xD3 7io4m\xB7\xDB)\x8B\xC5l6
+\xBD^\xAF\xD3
+\xF4\xF6\xF6v\xB7\xB7\xA9
+\x8B\xD8>\xD9<\xA8\xCD=}.\xF5\xF5\xED\xDFܐcɺ?\x9Ct\xBD\xF7h\x93\xC1\xB8\xC0
+\x93rc``\xF8\xC3X1=B5\xA7
+\xB2U3\xBF\xC42ŋ?ϒ\x84/y\x8A\xA3\xAF*\xBB S\xEB\x8C-7\xFBE-\x88\x97\xE2C\xDC\xC3|\xB8b
\x802\xE8'B\x84.\x9B
\x88\xFF\xF7\xDE\xD8nOU\xC5\xF6(b\xB8\xE12\xFC\xB6\xE3\xED\xFBG\xF1ד'?l\xAFSGl-i\xB3]\x94\xCDb\xE5\xF1֮\xF4\xBC\xBD\xBD\xEF\xF2\xB2\xA6g@\xAA\xF8\xD5\xC2+\xF1\xC5\xF0_\xF2
\xA8\xFE\x93\xC1;B\xD3I4Zm\x9B\xE2\xFAvy\xFE\xB9\x98\xB3;\xAFL\xCFL\x91\xE4\xD6Jh\xA1\xBAi\xAA\xFE7\xF9Qt\xC3\xE1.\xD13i"\xAC\x93֮\xCDHK\xE1\xDB\xD7H\xDF\xCC\xC0\xF6\x90]\xE9\xBA\xC8\xE3\xC1\xA6\x81\xFF\xBF\x83
+>\xB4Q\xF9\xF3 \xD8N\x93\xFE\xC9\xD3i҆y\xAA\x92\x91\x96\x87\xFE\xBE!\xB5&\xA2\xCF\xFA\xEC5]N\xF9\xB6\xB6]\x9C#\xE1O\xA5Ļ\x95 \xA5\xAF\x92FVh\xC4\xF5\x8ATuvQߚx\xA5+.4/G\xA1\x95g\x89 \xD0f\xFD[\x8A_\x96\x90\x90
mx\xF9\x8C\x9A\xBAj5
\xACI'\x88\x9C\xCA֡\xB1Ck&'`\xB80\xA8O\\xF8\xF2.//\xC0k\x82<9\xAC\xB3w\xAB\xC7p p\xF5\xAAo\xB4X\xC2\xEC}\xEDo\x9F\xBFk\xED]_\xFEU\xF0k\xAB\xAB\xDBS\xFB\xE7cc\xDB\xFB2b\x82\xE6\xD5W\xF0eP\x92#\x88\x89\x92\xF2\xF2\x91\xD2}H;W1\xD3$\xECg\xAFA\xC9k %\x97\xF2 \x95
+ \xABU\xA5\xD1 D\x8Fup\xFA^-\xBD%M\xE2\xA6\xFA\xE1ą\x8A\xEAj\xB1,\xA70'\xE7\xD2\xE4\xF9\xA0\x9A\x9AN\xEF\xAA\xC8w\xD9-F\xC3V\xD3E\xA0\xBA\xE3\x93\xFC\xA8x\xC0\xD2שz\xF3\xE8G~\x9Be\x85Y\xF1\xB7h՜\xF3\x80\xB2Қ⢤\xA8\x80%O\x99\xDDW\x99](\xFB\xC8\xE5>
+-\xE0\xA1R\x9D.-j\xF1znW\x9A\xE7\xAF`κV>\xB5\xA7\xA0n\xEA\xC63\xC2\xE1\x88!\xF6\x9D6\xF2
V"\xB3?7L ă!\xD3\xD4'\x8E\xCBWv\xFD\xB9<ɓ\x98\xB3\xE8\xFAƟ\xE9p>cֿw\xB4\xB3\xB1*1\x8F\x94\x92\xB6wӝm\xB8+;\xD6\xDC\xF7{\xECm\xC8n\xC2ޖ\xFC\x99w;$#?@<\xBA\xB4g.
+_\xBD\x98X\x8D\xD2#'\xD5\xDD_\xAC\x8CY\$\xB4զp\xB1\xCC\xF6F\xC9%\x82<\x8D{> \x80\x9C\xFDQxdH.m(\x8B]_Mb>\x81\xB3e(\xD6Zբ[h4e\xA1\xC0m\xA7m[x!2\xF7\xFE\x94\xF78*\xAA\x9B Bk
t\xBB\xD4\xCDˍ\x81\x81\xE1;#1=3er\xEA\x8F\xCB\xEE\xFF\xF2\x8B\xBFk\x94\xD9ىʱ\x9E\xB1\xE2\xF8\xA5:Qo\x88W\xFA,? \xFB\xA8^\x834\xA5/\xEC
+\xBC\xD8\xB1T*\x80uxXC\x92\xB1\xAC@\xDChU\xE7\xBA\xDE\xD5l\xBE\xEFM{o\xA3\xBA\xB9\xEE\xF0\xF1A\xADR3ݗdj\xA49\x95[bd5\xC7+"\x84\xEE\xD5
\x9E\x92\xBF߽4vPT=\xB5X\xAF\xCE\xE1-r \x80\xF9d\xB6R:\xE4lY_\xBC\x89S\xEE\xCFcs0n\xB7\x8EŽKxTq<\x96\xEB\xAB č\xB3G\xF9~\xABVysW\xAE\x8A\x80z
+\xB4c\xFEQB\xB8cW\xEC\xBC\xBD\x96\xA1\xE3\x80\xF5\x87B\xF8\x9A\xBAdi
\x80\xCA g\x92\xAEA\x92\xA9\xAC
mq\xFF0\xD8YA(ƜY\xD0ud{\xB33D\xFC\xE9\xE3\x89~\xB1q\xF7\xF91\xBE\xB6\xF1S'\xEB\xEA\xAB\xF9w\xADݮL\xCB\xEC\xAA|瘍\x92im-". \xBA\x81zQ;\xB1_\xE4;\xFE\xD9JՅ\xB0\xD5> \xEB\x94$!\xFD\xCB;\x9F\xBB\x92\xAE\xABC#ّ\xB0\xAF\x8E\x9FR\xFDO\x97\xB2I qᦐu\xA1]MFl\xE4\x8F
+\xADۿ'68O\\xDAzx\x86[U\xB2\x90,K\xEBoȊ솁?\x9F\xAE\xE0\xBBW\x97,&\x84\xB0\x9F8Կ\xD1t\xD9q\xB8\x93SQ_\xBF\xD2m\xC8L\x91\xF4\xB5\xFC\x8C\xEF\xDC\xC8ä\x80\x93\x97&`\xD2ew \ \xD4[\xEB\xF3\x86 ҕ^\x94\xA9wOp\x82\xB2FET^vº8[\x96\xF0ֺ\xFD\xC8\xF9\xB3Gj\xF2\x92\x89\xEA\xD6s\xB6\x8C%fT,\xC0\xDB\x8Fx\xCFwu'L($KNڋc\xB8v\x8B\xEE\xC3\xE3\x8B\xAA\xEEkz/\xDF]q~e8\xA6l\xD2\xFB\xACv?\xEB\xD2dX\x8E M\x8B/\xCC:\xD7\xCE\xDB
\xE4\xE1\x85g\xEFk.\x88\xCBn\x9A\xFD\xF0\xF0\x80\xB9\x8F\x88+\xD1ZE¤,aRV\xB1\xDDNs\xE7\xDD+\x87\xBB \xECĉJ".q\xBB5K\xE8\xAA-\xAA\xFB@\xC5_.C]\xAD" \x9C\xE6\xAF),-
?\x94\x90\x88\xFA\xD6=\xC7{T\x8Ai\xC3.kqy퍷\xED\x95\xFE!\xFF\xB5\xFE>\x9F\xC7\xE3r٦ކ\xE0\x84\x82\xC2\xC6#\x8F\x86\xDCu\xB1\xA7\xB1\xC3t \x90\xD6\xF6\xA4\xACZ)\xF0\xF7\xF3\xE1X''~xMZ@(\xDF\xDC\xE6p8\xC0\xBF\xA5/\xAA\xAB_ܬd\x8B\xC5 \x9B\xDA%\x8A\xFE\xA1\xB2\xB0\xD0`_\xF7bYN\xB9100|wa$梈cĒ\xF8( )\xA9\xC40'\xB6\xF5\xA3ϊ\xE3@\xA4\xFD\xE4\x9E_\xB5d\xF9 \xEC\xC6\xCE\xDD\xD9\xDA\xFF\xFA\xF3~!\xDEh\xFF\xA1J_PQ\xA7!km\xAA\xC9\xE9\xDA\xCA
+N\x84(\xE5\xB9Ӗso\xEE\xCE_?|\xA8%C\xC8w\\xB9\xAC\xE4܍?
"\xB7N:
\xE0p\xF4od\xD7<^\xF3^ŶռK\x90M3\x9D\x97X\x98 V\xEB\xF0\xF88 \x80$\xC3\xAD
.%:Ż/\xF9\xC5g\x8B^\xBB7\x82\xA7\xAFNXi\xEB\xC8_\xC6\xCB\xDCҐ-\x85\xAC\xF5\xE9E&\xE7 \xA0\xC9\xCE.\xAB\xDA\xFB\xDCv\x91\xF9\xA0{\xBB\xB0^\xB1㜦C\x9C|\x88=vJ\x85\xF9\xB1\xEC\x86\xEE\xD2\xADjdA\xB6w\xF1\xDE)\xC8z\xAC-\xF1\xE8\x93l=\xF1\xC7\xC1b_\xAA/U:=\xDC?eo}$y[\x90\xA3mGAN\xF99>7\xBC\xBE5\x98\xC8
\xEB?\x97\xE1c
+l\xD5X\xC0ҷ;\xBD \xA8\x90R\xEB<\xF7hÎ\xE4\xD7\xF3s5ʦ\x85/
P\xFF\xA6X2=8\xAA\xAE-!\xCF\xF5g v\xFD\x87H\xD6\xF2 \xC07&\xAB\xBF\xA66VG\x9E\xC2\xA6\x95\xFDp 4\xBD\x96 \x90$Yx\xCEY\xDD͋{ڧ0\xCCg\xF2\xD2`\xC4=|\xD3\xCA;Ҧ\xEFH\x8D\xBA\x88G\xD5&MW\xA9>\xECR\xE7\xF7 \xD8\xF1\xB9\xFB\xE3aߤU^|\xA9"?\xDE%\x8C\xEC\xBD\xEFh\x89\xB2wm{\x8F\x95
\xBC8\xAFp\xC2\x98\x8E\xCC\xF2\xB2\xAA\xAA+\xEA \x88sJ\x85W(̔\xA1}\x84\xD4\x9B\&\xDE aL\x90\xD0C\xD1\xC6θ
+\x88\x9D4`3a\xABW\xAF\xE3\xF1l\xE3\xE3\x93> F\xC7&(\x9A\xC7g\xB3\xF9\xB9
\xCE\\xD8\xE5\x92Ǯ\xAC\xEE\xE4(\xB4\x8E,fcv\xC9ؤ
+*\xEE\xA6\xCC< \x92\x94
[\xC0#j\xFE8\x98Q,\x82\xDD\xD8\xF6\xF2\x8B\x99J bY\xCD+\xAF>\xC0\xA8β=\xDA
+\x99ۼH\xC5[b㳇\xF6K<^3H\xF4\xC8\xC4ݹ]\xCA&\x80\x9C\xCA\xFA\xFBWΉ`\xBF\xF3\x81|y\x8B\x9D\xB2\xD8fd\xD9<_>k\xC0BC\x9D\xE1\xF1\xF1\x9E\x8A\xCFԜ
\x9C\xADDc\xCF\xE8\xD34\xA9\x8Bg\x80̍n\x8F\x88\x87I\xD0\x80\xBCH\xEE?*K[S\xB7S!
\xCCw\xB5ckݥ=]M\xDA
+\xEF\xDD\xEC?\xFE\xAD\xE7 IDAT
\xB5\xB1y\x931\x83ځ\xADm\xF2\xA7m{\x8F\xF7o\x88\xE1c\xD9\xED-<&f6-ˀ<8\xA1 at ANdE\xF1\xDBvqjW\x97\xFA\xC45?n\xCB
+I \x80\xD2U\xED"*\xA6m\xCF\xE2~?.\x9B6p˚\x8F\xDBg\xB3\x81\xCDf\xB3\xA7'\x88\xF7
\x88\x8E\xD3\xDDĚ\xBA\xDCZ\xB9100|wa
\xF8\x9Bc!IP(\ \xB6+\xDD*Uj\xC5t\xFF氎(5ڽ\x8E\x99ZS=\x91\xDAڣ}\xF1\xA3\x83E\x99q\xC9~c\xFDEm\xD0df\xBF\xBEsG\xB9$ @o\xE3\xDE&M\Q\xE8\xF4KW\\xF9> n\x80pf\x90\x91\xE6{\xA0\xEF\x8D1O\\xAC\xEDwp \x80\xC3\xE1L\xEA
+\xE22\xA3\xC70\xE9p pp\xFC]F\xC6I\xEE\x8D^\x9B\xBB\x9D@\xE9i*?\x86C\x99\xBE;o\xF8\xB8\xEF\xEFkr\xB2\xE2v%\xFA\xB6\x9Fh\xA4=cK\xF42a>\xE7\xA5q\xEBicWEF\x92\xDB""soA\x9E
+@ߠ!\xE8\xA4&\xB5x==\xFE\xEEl7\xEFυi\xA0S\xEF\x9F\xB0&b\xC7\xCE\xF4\xC9&%\x91*}8re\xA7U\xD9\xF5N\xFAWԐg\xBA:\xBB\xEF\xFA\xF2\xA4Jsa\x8C\x9FM\x82M\x9B\xA2\xFCF\xD6š"\xBD-w\xE8\xF1c5J\xE4(\xE07a\xE3\xC7 t\xE6Ǎ\x8A\x87\xA7w\xFFOʯ\xCA)\x906I{F\xCF\xEB\xFF\xBD_\xDC\xDE{N\x9E\xD0\xE4;\xD5\xE2FҵnfD\xDB\xA9l\xCDL\xA1Fl\xCBD\x89\x9E\x92\xA7\xF8㟝.\xEDz\xBB\xE2\xA1@\xC6\xEA\xB6\xFE\xE4\xC5ޮ\xD4
\xBF|\x95\xE3p88\xBB\xCA^\x8D\x99o\xDD5P\x87\x98\xDC\xD9b\xA0O\x9D$\xE1f\xFC\xB2\xDE, \xA5\xE4\xA6\xD9\xD3lef\xDF3\xF2tLxRm\xED\xDC+Q\x86\x86\xE7\xA5 \xB4g\xD2T\xDA!q\xAC\x90?\xF7qtLZo\xC8&\xCA\xD0}r\xF2ɼ1F\xEA\xF5l)\x80\xF0\xFEX\xBE+1\x8FP\xD5թ Hs
+\xC3|\xC4\xD0$\x87
+rT#\xF2\xD7\xE0\xBBДdj\xEA{F\xF3]\x8Aʢ?
+\xA2)\xE2-Š\xBF&\x81\xB0\x95>\x80\xA9\x8AZ!\xAE\xEC97*d_\xFC\xC3\xFE\xD8\xD8\xC0\xCB#\xCE\xFD!\xC0秕\xD5\xD5\xCAjqN}\xEA\x96+
\xF7\xF7\xA3\xCD\xD5;\xC0_\xD23th\xB3Г\xCD
\xD0\x8F b5\x84뻋$I\xB1֦\x8E]^V\xEDv\xDA]\xE5P\xA42[\x89\xD6s\x8E\x8C\xF0\xA5ބ\xA3\xFDj\xA22\x94\xA1\xBD\xADMե!\x87\xC7\xFD\xC3\xE2v>\x9B\x9B\x91r\xE3q\xE0G\x88䜧\xF6ϛ
+!\xFAMⒸ\x96\x81\xEC\xFC>@O\xF9K\xF7>\x97$b\xA0\xA2\xD7\x84\xC9r\xF8\xA3r\xBCv\xFF\xB8\xCFڦ\xE1笃1s\xBFI{\x9B\xC1t06\xAFP5\x92\xE5 \xE3\x90\xF6-\xC1\xC1\xBC\xFE\xA1\xD8\xE0\xEDE\xA7(\xA8\xE0\xB7N83\xD8\xFA6Ad\xA6~\xD4
s+Vg7\xD83eH\xDB)\x9B\xBC\xD8\xDD
+\x99_lu\xCEX\xF9\xDCq\x9E\xE5\x94\xC3wf\xB9\xCF"\xA09T\xBE+wT\x89_l\xB6\xB8\xB0\xB5\xEC\xB1 \x98\xDF7zφMYA\xD4\xF7\xD7\xE6gċ$ů)\xC4 \xFFt\xC2ȏzJ!EE\xD1, ,\xBD?\xAB e\x8A"ט\xE4\xC4g\x9Fb\xA5\x97\xD9hp\xDFm\x863\xE74vH\x94(\xC6ETTTl \xF1v\x890*\xCA&\x8A\x9A\xB6
\xD04m\xA7,F\x83\xAE\xB7\xBBS\xFE\xDFo\x90\xD0\xC4
+X,\x9E 8t}\b\xD5\xC9\xF3
\xD6!Q\xBA\xE6\xC8\xCC&\x80ǢS\xF0\xADW\xFD\xA6\xC5i
Qկ\xC9K\x8E\xB0R\x9B{\x8D\xAECƏ\xDE
/\xED\x99R\xC4\xEDHW\xCA\xC4Q졮p \xF0挓u\x89Gΰ}\xC3\xE3%\xDBcD\x89\xFFM\xFA\xE0\xBF7\xAE\xBD4r\xE6\xC2\x80\xBA0rf\xE4\xD2\xCAzœ\xB3\xEBx
\xA0\x87\xFBƴ\xB6\xD6_\x88\x8D|\x81[Ҫ\x88\xB1
\xD3~F\xD3p\xA9\xF8\xC7M\xBC_\xF1t0\xEAd[.\x8BŊ\x8EfI\x9B \xA8\xF6sXO\x95
+\xC4DS\xFA\xFAv\x83
\xA0\xC8:\xA4n
+ XޭU\xE5\xC8n,\x98\x98\xB8`\x985\xDAqV\xF2\xAB\x93\xD7\xF3\x81`}\xC9\xF7\x81EIT\xAF\x8A\x8F\x8F\x97H\x84^dv`\x85~\xDE\xF2\xD3G\x90n \x9D\xED"m&\x92tk\xF4\xBB\xB2Q\x9A\xEF\xA6y+\xC5b?\x9F}\xB9\xB97U\xB0\xBE\x80\xAA\xE9\xB5\xA9[\xCASD\xF3\xF5% p EѠ\xBB+\xD6'+tV^\xF13\x94\xA3#\x8AzPSW\xE1C\x88\xC3"
/\x95\x8A\xEB+\xA5\xE0\xDF'D\x93k\x9E\xDE=wM\xE7O\xDF^\x9D\xA7Ac\xFFD\xFE\x8CŎ\xFE\x88Dڽ_\xA3\xC3@\xD3\xD5\xD1\xDC\xD6\xDCp\xA0\x88*%\x91S\x95E\xE9ީ j^L\xFF
\xAC\xE3\xB4\xFF\xD6\x96\xD5C& \xAC *\x8F;\xD5\xF2\xFC\xFC\xE2\xF2\_;\xB4I\xBD=0\xB6"\xA2qh\xC2Ѳ??\xBEt\xE1\x88뭃.\xAC\xF5b\xC1U`Y[=\xD1\xFA\xDD<N\xBB\xE1Fk\xE7Gl\x93\x99?yU\xBF\xE4\xA6@\x8E)+Y\x91(\xAC\xAF\x804\xEF%\x85\xA2\xA9\xF8G\xF7
\x96\xC6
+r\xDB\xE7\x9E7=q٢\xEF\xD3\xCD.\xFC\xE1\x8B^\xAADA\xFBI \xB0whTq\x9ChI\xB4\xA4A}\xDA;LFv\xB4\xC8[\xEA\xA5\xE2=-r\xB9\xBC\xE3\xB0\xF6\xF97r\x93\xF66u\xBE
\xC4\xD3\xE2\x99Y\xBC|Q\x87\xB3%)fv== 8\xEC\xE3\xE2MQ\xBE \xDF- \x83\xE9\x9Bl\x84d\xE9n(b\xB18<\x81@ \xE0p\xFCb\x95 at E\xC2\xF3}s_3\xCB.\xB7j\x9A\xDE\xEAf\xFEa\xFE\xB9\x8D\xFF\xFCK\xC1
+{0y\xA9\xC3`}\xC3\x9CN'p\xDD\xE9t:\x9D\xCE\xE9\xDFn!\xAC\xD90\cM\x879\x9DΙ\xF8N\xA7\xD3y\xED\xFA\xF5\xEB\xB8N;\xAF\xD14M_\xBFF_\xBB\xE6\xF8j\xC2\xE3\xCA\xCB\xDB%\x97\xF2\x82kT\x99\xF7\xB6\xA6W(\xA1\x9A\x99\xACf\x90\xF0bSIk~ \xA5\x93\x88\xC3\xFDVu\x9F\x92K\x87S\xFB\xD5\xF91 @\x8A8\xEBՕ=\x83\xE5\xF1\x96\xBE\xBF\xB8Ő5N\xBB+2\xFD\xD6\xD7'\xBC\xA5\xF7 at vP\xDD\xFD\x93\x89?\xF55\xFD\xA4\xA4@\xE52Y\x95\xAA&\xF6\xCF\xDF(g:[
+\x82ؓC\x8E\xE1\x82\xEEW]\xC6J\xAC B,}\
{\xBA\xA2\x82\xDF\xD8\xF3\xEA\x8F
\xE0\xF3\xF9
Ǧ,\xBA6?"S֨\x92\x8EեWh\xB5c\xB9\xA2>\xED\xDE\xD53Kh\xB3\xEE\xD5\xDDD\xC9\xC6\xE3\xCE9\xA3\x9C\xC6"Vh]\xE9q\xE7\xFE\xF0]\xACЭC\xB6\!w\xA0A\xF2^*\xBE\xF8\xB3\x93\xC9,\x8F\xF7(y\xB4\xE0\x8Abl\xB7\xBF\xD5\xCA\xE1q\xC0\xE1XO\xEC\xDC9p\xE8X\x91\xBF\xC3\xE1p\xC0/$\x88K\x83$_t\xF8_\xBC\xDD\xFD\xB9\xB77\xE7k\xB2\xFB\xF7\xB4\xFE\xC8\xFB\xEAU\xAB\xF5.\xE9\x8F\xB8\xB3\xAFA\x9D\xEF\xC0ޗ\xFAX\xDF!\xD5.
mU\xBD,\xCF\xCD\xFD8%\x8A\xB1\xC7/\xBC}6:#\xF4\xE4|wF\xBF3\x97s\xF4\xF1yJ\xD5\xD7 \x88S\xCF;`o\xDF\xC5K\xDF\xD0\xE3,\x8F0p \xB5\xFD\xC1\xFA\xCA-k\xC0\x9Ex5v϶\xBE\xF2\xE9\xADg\x92\x9F;\x9FW\xA0\xD1\xD8u\xF8\xB9$\xF7¦;s9\xD2I\xF7\xE5S\x94<Z0\xD64\xE1Z\xA1b\xF1"3U\xA3Δ \x8B\xBA\xF95ELJ\xE0[\x95JMi\xD7\xC8\xFE$\xF7u]tw'\xF9ҜeX\x9E\xAB;\xFB\xA4\x94
\x95\x91/)\x89\x84\xBC1g\x92\xA79\xB9v]O&=\x8C\xE0\xC8\xDF\xF7\x8FVgǑb11>
&)\xA9߷.%x\xAF\xC26åum\xFB\x88\xCC:@\xDAo눙Iu\xA0A{\xF1%\xE7\xFEx\xDAb0"$\xDCw\x99\xC3\x94<U\x907,-\x94\x84~\xC2M=\xB1Cą]\xDF̋\xCC&\xC4\xE2i\xA9%\xC0\x97\xFD\xEAP\x9As\x9E \xF8\xB2Q\xCC?\x9Cگ)\x98Q\x97\xB1Ǐ8\xE4i\x8B\xE7\x80j\x88\xD8\xB6bb05\xF6\x84b\xB0\xD8 ,
+\x92lџ;\xA2\xCF6\xF0X\x9D\xF93\x95<\xA7\xE9Δ\xA7\{X;\xA1\x9E\xB3\x9A\x88\xD2\x90F\x96h\x88V\xF2\xBD\x8C(Ϗ\x9D<U\x907\\xAA\xED\xAA\xB9U\x97\xB1\x9DZ嶺\xC5\\xC5
+\x84v\xA2\\xE4\xDB[\xC6J\xE0i\x9D\xE5\xD3\xC6FK_\x95_\x9C\xF7\x98\xB38 \xB4\xD98\xEA\xF0\xE1|\xF8b\xB02\xA6+\xB9+\xF9\xF0\x9A\xD28\x9F\xF3\xD5u\xA3\x85\xA5\xE2\xBBygJڣ&\xA6\xEF\xCB\xC5M\xDA\xDB
+\xECѼV\xE7\xEB\xB6L\xEA\xAA\xE0\xC4
+\xB1L6\xAET\x92 at i\xCF\xD8\xFE\xB9FG\x9A2\xF6\xF2wN\x900&|\xE9\xB9ߴ\xBA,6\xB1Zr|hߖ\xF5\x81\6\xEC5z\xB6\xF7\xC0G\x9ET\xBC\xE6\xB6\xE1\xD42\xCB\xED }\xE6̩U\xBEw\xB2XN`Ŋl +V\x80\xC5b\xB1X\xAC+V\xB0X\xB7\xD0\xCD-
y\xB1\xA3_\xEF\xACo~\x94\xE1\xBB\xC4\xEA\xA0W\xDC\xC1f\xB3٬;\xD8X\xC1^\xB1b\x8Bu\xC7t;f\xB1X\xAC\xAE?\xCE,\xEEp5'k\xFA8\xB0\x82\xC5b\x81\xC5\xE6\x86|c\x9Cp.q\x94(_\xF1\xD6䔤\xA8\x94\xA4\xEF\xD1\xD0\xECH\x91߹\xBE\x94p.\xC0 N\xEAF%\x84\x9B\xE6L\x80\xED\xD2 \xF0\xF8\xA6\xEF\xF0\xFD\xB8\x86(\xC8\xDE)%H\x8D\xB8F;;D\xC4^\xB5RU\x9DGTj7\xD1\xEF\xF2\x92_W\xF4\x90\x87\xC2\xFAw\xF6'\xE6I\xFD\xAAŭZe\x86h\xEE\xE40j\xE0\x85\xD8\x94v-ԗ 6\x8D\x8C\xEE\xF3\x{11DD85}
+x\xB7g_\xB93\xC0\xD7\xE3[ܢn\xC8O,P\xCA\xB5-\xB9"\xE01m`v\\\xE0X\xD7H\xF9
4v at Tq\x87\xF3\xF9\xB9\x81\x94NS`\xFC\xEF\xBDm\x87\x95\xA8yU\xC8\xE0\xB3:Z\x93\x99\xA0\x81\xB8+\x97 \xF4\xC4\xA0$6\xB0\x8B\x89q\xF8\xFB\x8Fk4$v\xEE\xD4\xFAc\\xA3\x89\xEB\xB7\xCAg\x8A\xC5gMHȚ@߾\xCAl\xC8\xCB\xDCx\xBC_\x8A1\xF8\xB0q\xC3\xEC\xE1 \xC6\xED|\xBE/\xDFܗ]}\xB4\xBF\xB4T X9\
\x92C\xAFL8\x8B3 6K\xA5\xD2\xFD;\xFB\x9FT\xC4H\xE4l\xB1\xF7\xC9w\xA7+\x89\xE3c\x9B]?9+\xF9Չ\xA1\xD5\xD3e$\xE0\xF2\xE8\xC0\x95*\xED\xB9\xD7D\xE1\x83n\x94\xC2\xEC\xC2\x93\xBAZ\xDAD
Mu\xEB0\xA91\x91\xAEi\x9E0VFf\xA2\xF4xJ:s\xFD\xA4gKU/U܃\xCF|HMurhuN\xE3\xB9Wrg6>\xA4\xCEԡ\xB0k\xCBM\xC6)9\xDE \x95*\xE9\x91\xF6\xC8U\x87\x80\x89q
+3Y\xA1)3\xC5 \xF0\xE5\xBA\xCA\xA4\x95/\xCC=\xF7\xE1\xEB?%\x8CDž\x8D7\xD5eZ\xFD\xBA\x8EM\xBC\xC7\xE7vR\x96Y\xD7:t\xEE\xEAO\xFE\x95\xE3\xC6\xC4K@\xACZ\xA0\xFF\xE0\xFA8hǶ\xF7\xE6\\xEA+\xBF\xF9\xE2+\xC4{\xAAjs\xA3\xDC\xC3
\x93V 5\x87\xD5\xA4\xF0M\x8DV\xD4٣\xEF\xB9y\xEF#>Y\xE2\xC7*\x99\xF9)\xED_\xC5\xE1 \xC6\xE7\x84І\xEA\xD8<\x94
\x9F\xBFZ\x9D/,V[\x89*i2\xE1gP
+\x95\xA7,\x9C\xF1\xCA\xCFmw\xE4.ؗ\xD6n\xFBs\xF6[x\xA8\x89{KE\xD1\xCAj4\x92g\xF8\xAE\x8B\xCA?\xA3\x8A\xF8쀐 ߿O\xB6eS쎇\xB5\xCD\xC0W\x9F
U\xEBM/I\xA8P\xF4\x8F\xB9\xE7\xEEf\xED\xCD
+\xB6\xFCZѻ9?~\xB12\x92\x94O\x9C\xDB\xDEw\xF6+ߜ\xE4҄̐Us\xEB\xD8ҷ\xDD/N#C\xB5\xF0\x8Bh
ԩj\xB2\x86\xEC\x97̼\x89\xB8|\xDF\xF0\x98\xB9:en\xB4e\x96\xC3wf\xA0|q\xA6\Ò!\xC5
*)]\xFF\xB4\xDAD\x83\xBAUe\x8D\\xAD\xD3\xA8\x9Bwy\x80`\xF6\xCD\xFB\x9A>\xBD\xD1h\xE8;\xB0'Ni\xDAC\xAE\xD7t\x80\xAC\xB6\xA4\x86\x84\xF8\xC5l\xB7YT\x8E) i\xDB7\xB2\xC7G\x80\xC7\xE37G\xAD\xB9jlBeW\xBF*.3.y\xC0m\xF8\x9A6\xF7 b\x9B\x90C\x96&y\xCC,? $\xC8\xF7\xC6X\xEBZBB\xB6\x9E\бS\xBA\xEE\xE6T\x96_b\xA9\xE8i\xC9ue\x86-\xCAm\xE9o\x94U$\x87VunZ*szs\xAF\x94\xC8.Ui[\x91\x9D\x909٪\xDD\xE9\x92Z\xA7\xD3\xE9t\xAA\x93B\xB8\xFA\xB6\'\xB4\xC4?\xA7\xF5\xF8\x90\xC3\xE9T\xAB\xD5j\xF5 )7\xF6\xAB\xD5j\xF5\xA0\xD39\xAB/)\xF0DIIk/\xF7\xA8\x88#\xFD=\xA5\xA8\xFE\xC5\xD1\xF3\xE1\x89\xF8
\x8C\xBB\x8F\xE6s9\xA0\xE4;\x93\xC5\xF5\x8A>\xC7
+\xD8
J\xF9U=Q\xF2ȁ^Wa\xD6k\x8A
mbl2YتȊ\xA2\xCC\xC6u[\x91\x84\x97\xA7l\xD4
\x93L߇\xE3
+U\xD93\xE6t:\x9DNk\xBD\x98r \x94U\xA6\x94\x97\xA7\x88¹\xC0' \xF9'Ӄ\xBAΪ\xE0Ċ\x9A\x9Ec\xF7!\\xCAP\xF1:?Wo\xBD\xE6\xC7]*r\x9F\xB0\x8C4\xA1\xB2\xBA4%>&&\xFE\xD1\xFB\x80R\xD5\xF1\xC6ɼ\xF5\x82]\xFA\xE9\x9B\xF0Ո\xEB\x92e\xCD\xDD}F\x93\xD9b\xB1X,\x93\xC98\xD0\xDB\xD993 \xC7\xC7\x804\xF5~6;\xAA\xBA1'3R\xC0\x8A\x96\xA4\xA6\xA6J\xA2Y,\x8E \xF0\xE0\xE0\x8Dl\x88\xBDGz\xE5\xC1\xEB#?\x94\xD5\xC8 at H6\xDD\x88+_ۗ\xE0\xEB\xCB\xC0%\xBAF&2\x84\x81c\xC3s\x85\xC3>N\xFA{;\xAB\xE2*p$#\xDAw\x83\xB8\x91\xBC2\xC3r\x9E\xA7\xE6\x8F\xDB\xF37n/\x92w\xB5\xA9F\xC3 at o{n\x{12EF99}\xC7\xE7\x9F\xEF
\xC2\xB8D\xA6ɋ\xACj\xEE
\xD0\x8C&\x93\xD1h\xD4\xEBԝ\xCD
+ͽ\xF3\xF3BO\x92(
u8l6\x9B\xCDfs8:b\xB8`\xCF\xFB\xDA㭎 Y\xDD\xD6\xEBJ\x9C\xB6諶\xAF\xAF\x86\xAC\xBF\xD4\xE32#~R\xB9\x9Al-\xAC\x90F\xE66x8Φ\xD5\xF2\x86\xCE>\x9D\xC9l\xA1\xECv\xCAl\xECm?\xC0\x8B\xCC&*_\x8Cu\xFB\x88\x93uJ)\x87\xDAD\xD4\xFF\xC8}\xFD\\xD0\xF6\xB1\xB1\xF7v\xB4\xAEC \xF0\x84\xA2\xF8xQ|Ҧ0\xDC-\x8A\xFFa&\xF0\xFB\xF7o쉻\x8C\xF6\xE6\x9EC\xE1\xAB\xDAFUA':\xB7\xB9S\xAD3,\xDC\xE5 |\xC3EI\xA2\x80w\xF7fjd\xAD\xCF\xCC]\xE1G\x9DyWSx\xDC١v\x905Ս,\xB9{%o\xB5%\xE9LW\xD5\xD8\xED\xA3N]\x95[60\xBCrc``\xF8\xAE\xC2X1=3gJ$WX;\xA1\xBD\xE4\x97\xBC\xF6\x89\x97\xF3\xF2\x89: 2)\x81\x99\xDD\xBD\x80\xB2 NY !\xB3\x96\xB3\xA0M\xDBŨ\xD0&\xB8YwxkCD\xAF㳃\xD2e\xC9\xEB9.S\x9A\xACgt[LP\xD2\xC4h\xBA\xA1\xFB\xD2\xE2
+T\x90\xD5
*.\xEF\xD5\xEC*\xD95jϝk\x8E\xE2\x8C\xF6\xFC\xDEZ\xDA:R\x9A2\xF7:1\xB9\x8A\xE3cdQ\x8F\xB1<\xE9ƾ?\xF6R\x839\xDB\xEE\xB9C\xBA\xA5\xEB\x93\xC7+\x8F\xEFO!e\xCC\xEB\x9E\xDD\xE9q\xA1\x99 !\x96k|09\xF9Im\xACiW;\xF4\x910 05\x97\x95\x9D\xE1\xF1x &\xFAU\x9Aኪ1
\xDB\xC4ʄ\xBD\xF9I\x81 ';&H\x95\x90\xAA\x86\xDEK\xFA\xA6\xD9F\xDB*\x83C2m\xF2\xB0[\xD2\xFC0\xEF\x93\xED/\xE4iJG\xD4132\xF0\xCD?v\xBC 0A\x9El͍\xE2Y\xF2A\xD9ohײ\xD7\xDEƔ\x84
+\xB2\xB0\xA6u\xE8\xF0\x8E93\xD4 o/.\xEC\xC6\xDE\xF7>\xE8\xD0X\xB7W\x94m\xFA\x8F\xFBW_\xBDt2\xBB\xAD{y\xB0\x94=[\xADAMk\xE3*j\xA0A[ \x95\xE5\x80lQ\xBFa\xBA0\xB9QI.C\x8E\xAFX!#\xE2\xEDR)T*9\xE4vIT\xCA\xD8\xDD\xC9\xFA\xD9\xD5\xA2\xE2?vq+K\x92\xE3\xB2\xE7\x96*\x91\xD3*\x8E\x9F\xAE
n\xF0\xBD\xB0\x85 ʕ[\x9F(:I\x9E\xB9\x8A\xBB\xBC\xEE,\xADX{Oh\xF0\xF49`|\xCAq\xE7\x86\xD6#]~\xB8\xF8'$YP \x80 \x8E\xBE\xD9~\xF8\xBA\xA0\xF0\x8D\xC2 ~P\x88/\xA8\xBErX\xEB\x96\DJ\x954R\x9A\xD0$VhG\xD3¹@\xD4\xFE\xBE!/r}چ\x89\x8E\xAC%y\xF4\xB6\xAE\xF0\xE5\xB1~\xBF\xE7\xB33\xA7\x97\xDF\xB2\xFA\xB2\x8B[\x98\xF7|\xA3\xBF{\x880\xE3\xB5\xFE\xBB6\xD5֕Wd\xBB\xAD'\xE9\xE3\xE5\xD9s\x96i;\xC0\x8D>6\xBA!\x80\xCD\x9B
+\xD0\x9Dm\x9Fy\xAD\xF5:\xA3\xB6\xDC\xA3\xEC\xF0_h\xE3y3!\xD2r\xA2x \xAFFQ\xB5#~~\xA1ɱ\x93^\xE7Z2\xE6o\x82\xFB\xA5Q-\xCD+p *[\xB5\x85\xA29/Ѐ\xA4.\xED\x91\xD7\xDF5m.gn\xD1q\xA6\x9B\x9CY\xDD~\xE2\xAA\xD7x\x8DF\xBCGߔ[{\xF2jtX\xA5!?V\x89X&\xD3\xC45\x8B\xADY\xF7\x9C]^{\x9BC\x80(\xD71\xB6\xE5\xADƃ\x99\xD2D\xA0f\xC2Y<\xBF\xFAh\xA3\xFC?S\xF2\x9AH\xC8G\xF3W\xF8qV\xAEC]C\xF7\xB3Ao\x94[\xB4KZ\xB1\xB9?z\xAD\xFF\xC2\xF3\xD9D\xB0{\x81\x80\x90\xD5\xFF\xFB\xEB\xEA\xB2ʍ\x81\x81\xE1;
+3\xF3ka\xA7̔\x9D\xCB\xE0/x\xD3v\xCAB\xD1\xFC\x809\xDBÙ\xBA\xAB\x82\x93+l
h7&քOOS\xB2S\xCAN\xF3<\xBC\xDC)\xE3\xC0'&j)\xDFw\xF2ah>Է}O\xC6\x8B&n\x8E\xDD\xD4wr|c\xBC\xE7~\xD9\xDC۰\xBB+\xF4\xCD\xFD)72l\xA7L\xA3#\xE3\xA8e\xE2K\xD7.\xD1k\xEE8^8+\xAB-\xBD\xED\xC7-^^ \xE0\xE5\xE5\x97GI\xE0\xEAU\xAF{N\x8A\xE16\xA7nEU\xD7v\x87_\xB8\xBBA\xBA\xB3,\xBB\;\x97\xF4b}\xB1\x84\xC0\xD2+y\xE4\xE3?\xEEaSl\x97oIy\xB4`Ja͏\xE1\xB0[,l\xDF\xE5\xCE(0Аڲ\xE1P\xAD\xC8P\x94\xDDē\xA4\xEF\xCBO\xB1
+\xA8\xDF=y\xCA:;\xBC\x85\xA2m\x8F\x89\xC2٠\xD4\xCD䈟\x8A\x9F攩\xEF\xFD\x96\x89/\xAFz\xC5<\xBC]\xE8\xA9\xD2,&\xFD)\xBD w\xDD+\"C4mw9Eg\xB3\xB9i\xB3i\x8C\xE4a%\x90\x94\xAEAP\x8E#\x92O\xA9!\x96<\xFC\x88\xF8\xA1\xCDQ!l؍\xBA\x93MW\xC7\xEBձ5\xB3S ̝\xCD'
\x94\xA5-\xDD*hC\xE7\xBE6T.\xE2Gq9\xD8)\x8B\x8Df\xF3\x99\xFCu\xA1\x9AS֊\x89\xFCw\xEDdW\xCB_~G?\xF0\xA2\x9Fxn\xBE\xBBY\xFA\xFC$\xE0\xE3&\\xB05\x80Gt\x9D\x9D
q\xCA"r\xB4\x9D\xB2\xD9h`\xF3}\x97\xAE\x93E\xA0M\xCD/
??\x95^\x9C}\xDF\xE5\xFF\xF9\xF8\xABu\xEB\x83֮\xF5\xF3\xF3s\x95\xB1\xBDh\xFF\x97\xCFʳB\xBFF{[\xF6\xDE\xE6\xDFY\x88'Rb<\xBEI\xE8\x81\xF6W_H/*ꫳ<\xBB\xF0\x9Cw9\x8B\xF9\x8B +\xD8l\x8E\x8F\xC0\xCF\xD7w\xF1\xBA\xFE\xC6\xE5\xF6Ma\xE6b2|\xF8\xBF8\x93\x91\x98\xFF LU\xAC\xE0
+\xA9\xC2ڑŌ1000\xFCca$&\xC3w\x81\xFF\x8B\x93\xAF\xF8\xF6\xB1\xDB\xD6\xD5\xD4t=\xF5\xA3/\xFEE`$\xE6\xB77<\xAB\xB8\xF8;\xFF8\x98\xE5\xB7Fb200000000\xDCf\x89\xC9\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0p\x9Ba$&\xC3m\x86\x91\x98s\xB0ۗ\xE3\xD7\x98\xDE\xC8\xF3[\xCD \x80\xB6/7\x9A\xB2X\xDC
"\xD9)\xF7b\xB7\x98o\xEA̐\xE1\xF6b\xB7P\xCBmTsβ\xCCԔk\xE3Й
+D=ě \xA7,\xD3\xFEf(\xEA\xEB$\xC9\xC0\xC0\xC0\xC0pa$梘u\xEA^\xBDei\xA3\xDE\xF0-\xCBC\x99\x84\xC5bE7\xDC\xC8M\x99M.Ee7\xE9t\xC6\xC5;T\xAA9U"\xD7-+\x83\x94\xAE\x81\xC7{\xD5\xD3=\xD3\xDDE\xAC\xE8\xB2N\xB7\xABPM\xBF\xBA\xC1Eʇ66\xE4uo\x835t\xEC\xF0\x8Az\xF5z\xBD^\xAF\xD3\xE9t:\x83\xD1h0Z`He\xA5\xBA\xFB\xD84v\xEC\xF1{\xEAm\xDA\xFD\xC4ʏ\xE6]\xCD\xD2[\xE9\xF7\xFC\xAC\xBF"J?\xD0\xE7Bo\x9E\xBE\x90E\xDF\xDB\xDE٭V\xAB\xD5\xEA\xEE\xEE\xEE\xEEζf\xB9\.\x977\xB7M\xFF#\x977w\xDF\xF0\xCDg\xB7\x98L3%@\xABR\x8B\xE6;\xD0[s\x9F\xBCY=':m\xB7\xD3Y\xA0\xF9i\x8Bn at g\xB9\xCD\x8Aj\x96\xB0R\x9B\xF57\x89\xB3\x9C\x86D\x9B\xDA4\xE8\xA6K\x85
h\x977T\xED\xF6\xEC[\x96G\xCA9\xA9\x9D|į\xCE vy,\xA7\xD9H\xEB_}\xAC\x9A\xA4A\xA9Y\xAC"\xB7}q\xA9&?\xBF\xBA~Wz\xA6j\xBFG\x8E\x99\xAAW \xF4Xh\xB8i\xD2e?\xCE\xD3\xD8
+\x{DA7B}\xDA\xFE\xDFP_\x83\x9B\xE5\x8DVWIv5\xEB\\xFF\xD3
\x85\xF9L\xCC\xF6],\x89\@/Oe\xE5v/z\xC1\xBB\xCAڗn
\xCBO\x94\x81\x81\xE1_Fb.u\xB4 q\xEF\x89\xCC\xEF\xF4M\xC7B#\xD7Xy\xB7n\x89\x97\xBE^\xDD}S]@\x9Bu\x9D\xED\x9D\xDD\xF3P\xAB\xDB\xCAvT\x8B\xFB'\xB4\x8Fg\xB7\x9C\x9A\x8DL\xFEw`\xF0\xC1A \xD4\xE9\xD7 \xE2\xF0\xA2=?=ڡ҄\xAC]֦\x9C\xFC{\xEE
\xDDz\xB0)\xEB\x97TK\x92\xD3\xF4M\xD0X̋ \xB6ϕ\xA6\xBA\x93m\xCBItI\xEC\xBDJ\xA5\xAC\xD2O\xB9'222\xB2\xFC\xC0\x81\xF2ʃT\xED_\xDAB\xB19VX
7\xBCd\xDB?P* \xB1ߘ\xC9h0) \xF8\xDEMb\x9E\xCB]\xF8X\x9F\xABW\xFB\xE9=\xB1q\xD5o\xBC\x91\xB7S1\xED\xEF\xDBj:\xFD\x81\xE6O\x89\x89\x89\x89\xBF\xF8i4jj\xB2\xF5\xF0\xF7\xF7>\x93\x99\xD9\xFF\xBB\xFD\xBD\x8Dy\xD9\x9F\xA9F\xE3\xBB?
+~yF\xAB\xB1\xC0\x81\x9EghCն\xB8\xBC\xECcn-b\xE0U\x8F\xB3\x9E\xE8վ9\xE7\xDA\xCE\xB1ĩo^\xB4n\xD8
+\xEFdk\xB0\xE5{0
+\xBD^\xAF\xD7
+,\xF8hYfCb;N\x94tM{Bg\xFB{\xE9*|J\xC5u\xBB_\xD7ͻ\x9C\xBE\xB7\xADhWjjjj\xAAD\xB2\xABL\xDEg\x9Cۄyw\x86\x89\xD90\xB7؝\xE7_I\x8F\x9A\xB9\xC1yŮ\xAD\x89\xA5\xAD\x8F\xBE\xD7\xDC9#\xF4y\xDEW\xD3\xEA2I\xB4Dvd\xF2\xCET\xC9\xD6 \x89\x8Fl\x8F\xE6dψ\xFEe?\xCE38\xAE|\xA6R^\xFA\xC6\xC5L\xD3v;EY\xCCf\xB3\xC9\xE8*\]__\xAF\xBA\xB3\xBD\xB3\xCFx\xF3\xB3\xE1fy\xB3\x9D\xAA\xD0DņZ\xFA\xE4,\x87\xC3\xE1\xB0v\xC9=~\x83\xDA\xF5o\xA5+\x89wD\xEE\xC8GSr\xB3\xDE\xE3;\xCCv\xAAD\x895\xFEKfj\xB9\x89200\xFC\xEB\xC0싹\xF6\xB3\xBFנ\xE4\xB5\x80\x92Ky\x90J\x80ժ\xD2h \xA2\xC7:?\xDB\xD5%9mc\xEA\xDF\xEDOL&\xF2rTy\x8A\x872\xA5G\x8F$&W
+\xEDh\x96h\xAE\xF76;E\xB1\xF9.\xAFj\xF4\xB8\xAE<\xFD\xB7aR\xC1\xBC\xB3\x87U$\xEBW!V\x90\xFBf9\1 pV\xC2CE\xDA\xFB\xDA\xDF>\xD7ڻ\xBE\xFC\xAB
+\xE0\xD7V5V\xB7\xA7\xF6+\xCE\xC7ƶ6*\xF6e\xC4\xF11\xE3\xFB \xE4\xB4oh?\x96+ \xA0F;Q,\xF2\xE5\xC4\xD4:\xCEE\xBF~\xEC\xE0vV\xF5\xAC
0ίd\xFA?i\xBF\xB5#\xE6\x86\xFCx\xA8E'\x86\xCBE\xCB\xF2ڷ(\xA6w\xB3U\xB2\xA1\x8Er\xE1s\x91M\xC9\xE3
-\xB9 h]C \xB1@ܚ\xDE\xCDT\x81\xB0
Hnא$*{&JW-\xBC
\xD5RC xGh:\x89F\xABm\x93@\\xDF.\xCF?sv\xE7\x95ig\xD9!\x92\xDCZ -T7M\xD5\xFF&?\x8An8\xDC%z&M\x84u\xD2ڵi)|\xFB\xE9\xEF\xFB\x82g\xCA:\xE4\xB1bֿ\xAB/\xCD
+\xB6\xEB>чA\xF3Bvn\x84\x8FO\xCC㻞I\x89Y\xCCm\xEE\xDBWG\x94\xD9\xF6\x87\xB8U\xF1\xFF\xDE\xDB\xED\xE9\x81d\xCFUu
\x8E\xE2\xF9\xDA\xF9azyG&\x80\xD6\xC4\xC8\x80 \x92$q\xBFU\xEDrɹ\x9C\x86\xE4F\xF0eP\x92#\x88\x89\x92\xF2\xF2\x91\xD2}H;Wr#
+\xA5\xAF\x92FVh\xC4\xF5\x8ATuvQߚx\xA5+.4/G\xA1\x95g\x89 \x98\xFA\xDA\xDB\xFB\x86\xC7\xC7\xEB\x8AUԑ\xE2\xD2\xD2\xD2
/&\xA5\xF9D\xDC\xC3Ӓ\xC45\x97~\x94\x9C\xBBQ\xFD\xB2\xFC
+\x89\xF1\x9F\xD7>\xB7ugц\xA9\x8DF\x92\x9A\x8D0MA]NfjL\xB9\x88p\xE5n\xF9\x8F\xF3\xBC\xB5B\x82\x99\xFEd\xA0)\xD3\xD8\xFF\xCF\xC75U\xFF\xFC5\xDCdC6
d\x80C\x95Q\xA0\x81\xD0A)T2\xF2 X\x90 \xC8ϸ\x98\x8A\xF0\xFA\x8Ab~\xE5\x92`%`*\x99\xC3҄/\xF0%H\x86\xC6T\xA6\xAC`!\xA6La\xB0\x83\xFC\xFE\x97\xD1\xFC\xDE\xF2<<
\xEC\x9C\xF39\x9F\xCF\xFB|>\x9Fs\xCE\xEB\xBC?7\xA5\xB1 \xFBQ
\x97\x8A4OV\x90`\xD8\xC3a\xD95
\x8F\xDD#\xD8F4\xDD\xCF\xEA\xEA\xE7\x86+#2J\xEB\xF8S\x9A?1\xB57\x9Fh\xA6Jt`?!\x8E\xB4\xF6\xE1g]ԧ\xB2]\x84|\xAEu\xA4\x93*\x913\xF8:\x95\x8D\xC0\xF4\xBEU+ iڦ=3\xA2b\x9D4\xF3c\x94\x89\x92\x90\x90<M\x90\xB7\xFF\xF8ڙ\xD1\xEAҽ3\xA4wT\x9D\xC08ZLr\xF2x\xA3\xC9f/$\xB9Ln\xC0f\xBB&\xB6\xBB\xAD\xFE3\xFA2T)ʉ<5\xE5\x93'* \xAAYtw\xEB\xFC\x9D\xAB]
M\xAB\xB2\x85\x89\xDE6}\xA7\x8B\xBEZm}η\xFD\xC0
+:@\xB7\xF2\xAE\xEA\xF6
j\x878\xD3\xD32ѥ\xA5*DS\xAF\xA9\x86\x86 \xB5\xB3\xF9\xB2\xE0t~Vzxaș\x98\xE7\xA7Ϟ6\x83\xD9T3%.\xD8\xDE4\x88\x99}(Λ\xCD\xF5ojZM\xA7\xB7$\xB1,\xEB\x8F\xD4$/\x99\xD4N\x80ʠ\xFE\x9A\xCEw\xDC\xEFV\x8E\xA5TR\x99\xD2\xC2\xED\xEE)\xE3\x8F~\xE2\xC8Qz\xBF\xB9\x89\xA02-\x9F0\xCCq\xA6n\xD3<C\x95\x8A \xF5r\xE1\xFDX9\x87 #ʕ\x9B\xED\xE8Jy\xF5\x853{·\xCFL\xFF)\xE4\xD1'\x91\xB7\x8D\xCFM(\xB5$?\x9F\x870\xC9\xD6e/X>\xE9ho\x9F\xF0\xB9 \xA5U\x9B
@\x88VӬc\xD6\xF6\xCE\xD2
,\xD5e\xE5\xFEY\xFC\x9A\xEE\x96\x9B\xE7Т\x8DT\x9A\x95퀪cXtYGF\xCF[,\xB5\xF2\xE6\xA5\xF6
U4ݞȅ\xBF5\xCB \x97\x9B\x9Ca=}\xF2\xD8a\xDF~o䙪8\x97\xA1W$*\xD8m\xED
\xDFԆ\x8C\xC0A\x85S\x99\xEC!'\xFC(\xDC\xEE
#\x8C\xAC\xEB\x8E\xEBӀ%\xDB)\xCEׂ{\xC4\xD9(+R|\xD4\xDD}W
\xBE
+?@)\xAE\xBCp\xA3\xB9\xCDj\xBC)\xBBmj\xD9\xCE\xD61܌\xA6n?6\xAA\x8F\xF9s\xD7\xFB{;0\xBD\xF9\xAF\xB9\xDA;\xCE䶄\xD8\xD0h\xFAw\xCBO\x85B\xAC\xC8o\xAA\xC3\xCB\xE6\xEEH8\xB3p|J\xF53QG\xB3+,}\x91\xD9\xDB
+ B\xCFdάg\x8A !&O\x9Ff\xD6y\xAF\x85 \xAE\xE1\xC4ɓ\xF1; #c\x93g\xF4\xF5\x88\xFEgܨn\xE7\xFE\xCB0|\x96+\xE4\xBF\xE5y즠H\xFD\xA9\xD5ҽ\xF9Q\xAA/cadq\xC5\x93\xC9F\x86L&\x83A\xA7+\xAAsq},b\xB3\xFF\xB1~\xC7\xE0\xF1\x9Dm\xEDwo\xA2(ieQri\x8B\x9F\x83`\xD7 \x887\xDD)\x8Cw\xD3\xF8\xEE\x91\xE7\xF8[&\x98\x9CXo IDAT\xF13Z\xFD\xFA\x9FE6~2\x8E\xB1,WX5
d\x80,/-\xA3T$.-L/`\xCD\xF2RK\xD3\xED\xCD\xF1\xCE\xC6\x9A\xBA7\xB3-Q\x92\xA7RbjGY',\xE2\xCE1\xA5\xA0\x9AXٙXiFHM\xDD\xC1\xCBO\xDE\xE4fcg\xA7q\xE4T\xA2Oҭ\xEC\xF8\x90\xBE,f\xBAl>Va
h\xF6\xE6'\xDE6=;\x95\xD5 |\xB3w\x8C\xF8\x96\xEE\xF7\xF8
\xF9\x87\xB6\xD7\xDB:\x93\xEA\xE7\xE5\x9CҬ\xC6m1!N곕%\xC7K\xB9Q\xA7\xDA\xD7\xFF\xB9\xA7 \xA8L6\x80\x81w\xB6\xAF\xE5\xDE\xD2\xE4~ ;Z䛽ό\xC9\x93 \x801\xE7\xED\xF0I斌cgN\xB9\x98\xA8_\x8F4c.\xEE\xB2'\xD1\xE9t\xBA6\xEBM
\x96B\xE8\xBA60?+] 6y\xD6\xF8\x91.r(\xF2\xCA\xFD\xFCt Y\x90}\xCDOJ-\xAD[6\xFE\xBC\xB1u9"\x86R\x94鞄\x80 !<\x95ŋM\xB6=\xB4,\xB4\xC8³B3X\xF5\xD1\xA0\xF5\xAE\xB5E\xC7x\xEE{\xA9M\x97l\xBAR\\xB93\xBBPa\xA8\xBF\xEE\xE6\xF5
\xF0-n=\xE0\x842\x97g\xBF\xAD\xDAl\xA0(\xF3\xE4\x97\x80\xB2:\x90\xC1M\xB8\ \x915\xADqV\xFD2ō\xC7\xE9`9f\x88b\\xAC4\xA2\x97\x8BK\xF6\xACu\x8E)7RP7\xC8խ\xC8\\xCD\xF2r\xB9=\x9BF,\xB4\xB6\xDEln \x85\xA9\xAD\xC7\xFF\x90\x95\x99\xFE\xAE1H\xCE6\xFBzg\xEE\x9A
++L\xA8\x80\xA2\xEC\xC3\xA4
+\x97\xF4Z8\xBA\x8A\xA4畕\xF0\x89\x8E\xDA~>>& / \xD2\xEA\xAE\xBDY--L\x8C\x86\xD5V\xF8\xB1\xA5\xE8B\&3 \xC0\xC0ί"!\xD1>\xAD$8̓m\xE7\xE6=\xC7=&Bݱ\xBF\x97\x82Ϗpu\xB8\xBEk\xB3\xE0\xF3\xE3}\xB8ίt\xBB\xB1\xAD\xDC]s\x90\xEA.\xE4\xF1\xB9\xACV.\x84 ;\x8B\x8C\xC0\xB7\xF4XV\xA9 at PW\xD1bg0\xCA\xDBy
+p\xDDC\xE2\xE7m\xCF22244\x92\xFF\x84B\xDE\xD4P\xDF(\x93ݹ\xEF
&M_\xE4\xA0Y\xE0T+\xA7\xFE\xA0\xD2C\xAEO왺h\xB3\xC1\xD1<#\xD9F\xA3\xDD\xE0+\xE8\xFF\xA23|\x96\x87"Q\x83ҎC \xA5$m\xADyP|ƞ\xCF\xCB\xEB\xD0\xD9\xD9 `\xAC\xBE\xBE{$\x82\x82\x8C=\xEF\xD6d\x84X\xD0q\xB7Ì\xE7egXZ\x9F\x86\xB2
+\xB4\xEB\xC7^\xE6:f.T\xF9\xC5Յśo\xCD]\x9E\xB6\x823\xDADIHH\x9E>H\x89\xA9
U[+\x84\xBD
+qAy\xDB"\x9B\xA1OJ\xAA\x89[kSͷ\x89\xC1\xEE\S\x84 \xDA=\xD4a\xD5Y\xFCtd\xD7,t\x8A\x9D_Z\xB7_\xDFQ\xCB\xCDBl\x83\xF7Ho<Y\xC9\xFEx\xF0J\x97p\xEEV\x8Fq\x83'j /\xD39\x9C\x9E\xE6A\xF17\xA1B\xBEpN\x9F:m\xBF\xE8\xE3\xFFl\xDD[v
\xB7\xC4\xC4gq\x96m\xE6\xFBpS\xCA^\xDB\xEC\xC0\x96\x97eD\xC0W\xB8\xAC?E*\xD3\xCC/Mř\xBB_\xFE\xF3^[~(\xB8\@(\F6\x97@(\xFAf\xF4zDYe\xBC\x97+ \xB9\xD7\xEC\x9Dke\xF2\xE8\xF5Lk\xC4\xE0ObAR\x98\xC4v\xEA\xD0:\xE1;\xEA\xF8\xE6\xE5eoY\xFBd
1Jt\xA4Ued \x94\xFFvm\xC8[\x8B\x8F1
o\xF2\xEEk\xE6ch\x90 @Y\x95ؤ\xBC\xC8s\xB3%\xD1|\xAA\xAF\x88\x8D\xE8\x90V\xE6\x89\xF4\x9C\x9C'M[浲-=\x8B\xEB\xC9_h=>\xAF5+\xFF\xF8\xCA\xFB\xA8*^\xCB\xCF+пW.(\xAAo"\xC0\xA4?\xEB+(\xFEp\xB1\x93 \xB5څƕ*5%&\xF2v`
+K]\xF6\x84B,<\xBF?\xD6=^ ^lF\xEA4\xFFC\x93\x9F
\x92\xDE\xE6\xD2
+\x95\xBA\xDB\x8D\xD6V
\xEA\xE8c\x9Bqf\x87=\xBBM\xA5\xA0\xA2=\xAC\x93'Q\x98\xB6\xDF\xC4;Њ (\xAB\xC3
\xB8\x85F\xBC\xE1\xBA\xCE5\xDB
+\xCBm\xE8\xE7\xF8\xDB\xFBge[\xDEb\xFD\xB2\xD6\xDC\xD54\x82\x9F_\xB7\xCF@Y\xC4M\xD8-\xA3\xAFHP\x88S6\xF0\x94^[!(\xAD\xE1\xD9[1\xB6\xCE
+\x8F\xC7\xF3R\x85\xEA\xA6غ\xD2|\xF0}'\xF5\x98\xF6\xB2"D\x8A4ȿ
+\x90\xDCq\xC8{)\xDF\xF75\x9793\xA1\xF1B#\x92\x8B"\xC1\x8C\xFC\xEC?\x9C\xB9y[Uf\xF1\xD5\xE7r]\xBCޝϼ\xE7\xDEy\xF9\xFF_
S\xDF{\x8F\xD9\xD9 \xEB\xE4fL\x8C\xFAv
D+\x8C\xE6\xCCs\xD0\x8E\x90\xA6m
+JR\xB7\x82s\xF9|\xEE\xA4IHO\xCF/\xA1\xEE\xE4f3-\xF1*\xB3|ݹɥOJ_\x8Ed \xA8\x8C\x80\xE4p\x9E\xE6.P\xBB
: \xF1\xF7qAYau\x81\xE5ii\xC5E7\xE3\x93\xBE\x91\xB16ݎ\xF6\xEA\x98xEqmE\xBE\xA5\xBD\xF5'\xDC\xEE87\x8F\xCD\xD1
+K\x85\xBC\xE0,:6\xAFs\xD1tW\x98E\x9D\x894vݹY\x95\xD6۪\xFE\x90DIHH\x9EBH\x8994\x80\x85B\xC1`2~\x8C\xB1t\xBF\x9D\xDD:\xCC;\x89ɶ\xF2\x8B+|mE\xDE\xE9\xFB\xB6=d%\xAB\xB9\xFE\xDC\xD83\xDEV#=[\xCB\xD2\xFC\xDD\xE3\x91]\xB3\xC9d\x84@\x8A\xB2\xB5\xCE1\xBC\xE4R\x87\xC1.ŵ"\xD8\xEC2
r\x824\xCE\xD2Ұ\xA2%\xDA\xCE N\xED\xF4G\xE4
+\xBB\xE3y<C=mV\xD1m\xF6\xE6G\x9A:nXX\xB7\xF9Lj Aݐ\xAB\xA5:\xF9B)\x9BY\xF3\x95\xC5\xF8-\xD7\xD7y\xBF[M\xBE\x97\xAA\xB9\x9De\xC4 \xDA۩\x86\xE6\xEAp\x84\xB4p\xB1\xA9kQ at jͷk\xAC
\xBB\x82\x99\xC565)~?\xEA\xBB1ڼH\x90,\xC8.t6\xA6\x82
\x90\xE8\x9Cy$\xD2oӯa\xB2\xA7\xA9\xBF \x823\xD09\xDF':;{B\x90\xEDa H.
m\x8E,ny[lh\xBD\xF0
\xA0\xD6\xEC\xDC\xCFMHg\xAA]\xC1\xBA\xB4fa\x92\xEB\xA3
\x9C\L\xE5\xE2.\xEFu+3H\xDFN\xBD|\xBB
P\xD4\xD7]\xA3c|r\xC6
\x80\x81\x93\x87\xDAG5\xEDm
~IMN[m\x91\xFAޜ\x8E\xCB\xF9\xA1\xF1Y\xD95&\x80\xBA\xD5>\xE0G\xA6V${ۙ1E)_\xEF\xD52\xA0\x82jf\xE3Я> \xE0-v\xB1\xA9f@V\xB6\xD75(4u\x9E\xB7\x95
+\xF4g\x97E\xE1\x8D\xD5t\xA2s`\xC0\xB1c\xD1ܩ?\x99
+ \x9C7Sj\xED\xE5\x980\x97\xDD->;C\xDC͍d\xABۨ+\x92\xAC\xC4\xD3\xD8Y\xC0O\xA8h\xB13\xD1Z\xF9\xC2$xV\x98 \xE4\xA7\xD1\xC9}\xE1Z\xEA\xC5\xC0L J\x91 \xE0\xFA.\\xBD\xDE
+\x989\xD1\xDA\x9D\xF7¸HbN\xB6@P\xFC\xCE\xCB\xC9\xDB͡\xACL\x8C \x80\xE4\xE2\x9E\xFCkn#\xEB
\xCC LCC\xFD\xF2\xFE\xEF\xD6-=\xD9:\xEA۹\x9Fj.\x959\xCD\xD6\xF3\x8C0\xF9\xC5i\xA6\xF4\x9Epii\xBBSl\x8D\xB7~\xBF\xFC\xC0
+\xCE\xE0\xF0\xCA\xEBNJ\xB8\x89\xDF>n\xD7\xCBG\xB2
+\x80J\xD5̚\xA2Y\x86\xB4V\x80ۻ\x87\xB3"M\xD5
+*`\x97yA|\x92EB\\xB4 T\xC5\xFB\x8E5\xB5\x8B\xEBn\x8F\xE9s\xF0\xA2\x8Cx\xBCW;M
5 up\xB6˚ X\xEE\xF91*\xD1\xCDl4\x89\x92\x90\x90<\x85\x90sT ʃY\xC7|\x85۲\x92\x90\xDF\xE4=\xF2\x93\x92m\xE7\xA1\xEED\xA9\xBCe\xE9.\xE0%7D\xED\x8A\xD7!ˍ\xF1Z_)\xA8
I\x86\xE2\xED
܄\x86\x90\xC1/'\xA5\xE8T<\xB8\xC5\xFDF\xA9\xC7n\x8As\xB7%!\xA0f\x86 \xA5\xE80?
\x82@^\x98\xB9/\xE3\xD80[\xB3\x8A\x8A"+$nnZ\xBC)&nq\x82 \x8A\xA3y\xC2*-
+)ٯ\xD4
X\xC1\x94ENJY1*(\wA\x9D\xCACc\x80@\xF1
ע\x80#\xAA\xB4\xB2n1\xD9l\xFC~\x97\xC5\xAAݗ\xCC\xE1\x98\xD4t2\xAC\xFDߘk\x82\xC65\x86\xFB\xB0\x9D\xE2\xE2Կ\x8C\xA7[ \xBEًM\xA8 \xA8\xE8\xE0\x85M\xCA\xE5\xC6\xF0R\xF3\xF7z$Vy x.\xFEI\x91\x896\x90\xAC\x8E\xD7\xD8\xF6D\xD2q\xA7A\x82X\xF7\xE9 zޣ*\x85\\xD2\xCAY\xBC\xD4
+4Z\xEB\xD9cٕ
\xABV\xA9T*\xD6\xBA\xE3\xDB|\xFF\xA3\xC2\xC8\xD8\xF0mi\xF9\xD9v\x86M~E\x83\x9B\x9D P\xADv\xD7\xD6\xEE6\xE5\xF4\x8D\x94hŅ+\x84EE\xF0\xDD;\xF4\xF3a\xE4\xD59Ǝ\xA1\xBC\x84\xE2\xC0
ף\x81ӊ\xA3:\x93j\xC0\xE9W\xB1n\xEB\xB8Y\x88=\xE3;ȅ9ڊD\xC49|\x8F\xA8;\xD3* '\xEA[`\xC7T\x94
\xF2+\x96\xF4Š,?\x92\x8E\xD8b(Ҽ\xFC#\x8Fd7\xEDob|s\xE5\xCAc\xF9[\x97D'\xAE\xBD\xB12?\x96\x9B~\x8D\xC1GCA\xA4\xBD0\xE1Hꅕw'XژLGQb\xB6\xE9\xB5\x9A[\xA3\x9A)b
+\xAD\xB7\x8E\xFAv\x96V\xE6}\x9D$\xE8\xF1y\x9E;Ui\xF1\xAAݐ%\xA6\x8B\x9FߐSټ5\xBCК\xDB0Db\xAA\xDAn\xF6\xB3?\xC5\xE8l\xD7D&kv0U\xFC\xAA\xAEQ\xFDA\xFB~IJ\xBE\xA1\xA1zC\xD9\xC6\xE2\xFAL\xA5\xE8\xEF\xFC"+\xFE:\xB1 =\x9EH\x85D\x88\xDEqt\x9CpA\x86t\x9A\xE1\xE8%!!y\xDA '-\x9A.\x84Y~\xB0\xA7\xF5\x84V\xA0\xA5YcFB!\x93k\xF1DrIAZ8\xC3\xD2]\x90\xD1T\xA2\xD5E(de\xB9).4\xE3\x95\xF1ͩ\xC5uq
C\xDEF\xBD(ą\x814\xCBaXM\xD9\xE6!Q)\xBE\xD9⏀\xEDs\xD5\xED\x96*\x80\xAB\xCBDy\xDB-W\xA6'dE \x89\xB5\xF6A\xE4\xE4\xBA~}g\xE51\xE1\xC1\Ļ\x9BSӆ\xCE\xE4\xA9
I $
\xF9q\xE8\x82\xF2\x92\x88t\xF8,4\xA0\xF5/\xF2
+\x99
+\xB7:A\xDF<Fc\xFE\xC5\xF5\xE0\xD9\xCD\xE1\xC5"+K\xA1\xD8n\xD7>;\xCAZa\xC0\xE1\x98\xC4Oi\xFE\xE0g/b\x83\xD03 \x884\xDAp,\xC9\xDB\xE4\x9E\xC4+N\xF1\xEEy;\xAA\x94|\xB7wӪZ\xF3\x93\xA7UJ\xEE\xF6W]\x94\xA0\x{1DD2738},$,\xB3\xA2Лh[\xEA\xEC
\x8F9\xCF1 \x80h\xB9D\xD8\x9A[\xFA\xFB\xBA\xBB\xFBzyy\xAD,\xC6{yyy\xF9\xBA\x9B\x9Ao\xFBu`֙ڻ \xE9\x93\xE3\xE1\xB79.1-1ns\x8F\xBE \xB09\xFD\xFArT(*7ڇ"\xD2\xC7j\xC4W3Mm\xA9B\x92\x97h\xC8\xF5\xE1\xC5\xE6\x9F\xDC\xEC4\xD2 C))\\xCDr\xF2\x93\xF3\xA3]\xA6<\x{22A4E16}\x840\x9Fy#^.u\xFA\~:?\xAE\xB0\xB2 \xD81\x94\x9F\xB1\xBDo\x82\xB2\xB4\xB5+\xB3\xB8g\x82\xE6̗\xD3+\xC2]9\xB7\x84w\x9C\xCBx@ѱk\xE3\xDCVG\xFB\xF2\xEE\xFC!\xCC\xF2\xFC\x83\xFC\xECL\xE8\x{1AB2CF}\xAEs\xD5m\xDA\xE4\x92\xEBa\xED\xFE\xE8\xBD \xAE\xE3{\x91 \x8F\xE35\xD6\xD7\xF5L\xBF?\xBA\xDBY)\xCE1\xB5\xE73<jj\xEBjJ\xB3\xB9@(\xDFސFٙW\xFD\xF0\xE9w\xF1\x97\xA1E\xB1\x8B\xA7k9Ĝ\xEA\xE1\xFA=C\xAB\xFC\xE8\xEF\x85G\xB0\x8D\xCA \x89\xE9o\x9DVVo\xB4\xE5%\xAF\xD7R\xA3\xE4%\xFE\xFC\xF4\xB0\xA0\xF9\xEA\xB0ʺK\xEAY-\xCBp\x8D\xE7g\xAC\xEC\xA9\xD0Dc)\xB8s-z\xFAKXy\xF8\xB9pz\xCBo\x90<5\x90 \xED\xD0\xF4\x8C \xF0=gQ\xA9V\xF1\xA9\x8E\xD6,.\x8Fo\xC1jU\x8F\xE1\x8C-\xED\x8Ev B!^\xBA&\xFA\xB5\xE8\xF0\xDE$\x81\xE0g\x9C\xA9\xF1sܷ\x92\x90Uf
\xFC\xF1bav\xBA@ ,5\xFF\xD0\xB7af@!dቴX\xFFx|\x93\xEB\xF6\x85\xED\xDAU\x9D\xB3\xD1_\xC0\xCDoxU
\x8D\xA6a\xD0\xFF\xADޛ\x9E%\x8C<"\xDC\xEC\xA4
\xE59iU\xBE`\x95\x83 \xAFKGli\xA4\x87\x986\x88\x9C1;\xE2j\xC9:W\xD3~\xA0Dž\xAA\x90\xE6}
\xC1\x8F\xC8\xF2M.n\x99S\x95\xEAhm\xC88\xF4\xB5d\x8F\xB30@\xE0Ʀ\x8Ao>\xF0Al\xB1i\xBBTT\xD7(\xC33@\x84
+\xBF\xB0\xC7\xD5\xCA\\xE1\xE4c\xBD]W\xF0\x9A\xE3L#*U{k\xB3\xF4\xA6\xF0r'\xD8ω
+L\xE7E\x82k\xCDh\xAFU\xC5
+\x99
E;\xE2\xDCM\xEEI\xFC\xD2o: Ί\xB48\x800Ϣ\xAC,͜\x9F\x94P\xDC\xE4\xA41*\xAA\xB5\xA3
+`\xBA\x85\xA4\xB9\xF5*\xE1s\xFD#\xA5\xB3N8:\xFB\xF8f\x97z\xA9s\xCA\xCA;\xB1ۻ\xA7G\xA1('\xD0\xDA'
\xBC\x80\xEC3\xE1o\xBA\xF4\xBD\xAB=].\xE4j5\x96i\xEE\xC0E\xA8P\xF6ɣ\xCDi\xA3
+\xF5|F\xE9F\xBA\x8D\xB0\xE8\xC4\xE1\xDC˳"\x92 ?\xA3\xB8\xD6\xCFi\xD8o\x95Q /Ɍu\xF6O\xE2\x86
iI\1dT\xD9\xE8+\x92\x81C/\xD4\xDD\xD76?\x9Eǝ\xCAbP\xB4\xB7\xB76\x8A\xAB\xEAa\xEB\xE1\xD4㭴\xF2ۗq\xF1eW\xFBtnX\xF6O~6
+\x99\xE4z\xF5\xF9\xF9$!\xB5\xB4I=\x81\xC7\xC1\xCA2\x80\xCE \xCAR\x93\xF8\xC9\xF7+\x81\xB9^6\x88\x8AH\xAE\xE9viL <\xC1K\xF3sbC\xF1#p\xE7R\x86P\xBC\\xFF*#\xCB\x87\xE3\x83㦠H\x98\xC4mϮI\xF4\xB6\xE5\x{DB3A}[D\x86\xFB\xB9\xB1\xFE&\xAF\xA2\xF5$\xAD\xE8.\x9F\xC1On\xC8
+\xD1ާ\x98PJ\x84\xA7\xB6\xDA\xF3\xB3x\xC9
+\xF6Z\x9D\xB3\xD7\xD5dGX\xBB3r}S\xA3\xFD\xE7\xBDhc\xC3\xE9\x8A=\xFA{\xE1\xB1lS\x8Aˎ~\xE0\xE8#\xE0%7
+i \x81Bn\xE8\pD\xD0\xEB\x8AV\xB5\xDD\xC5\xC0p҂\xC4\xF8
+\xF9\x8C\x9C\x94L+\xFEb\x9CO+CW?b\xA2\xFF\x83<\xBF,\xE5?m\xC9_\x87\x9B\xDFo\xFCO\x9B\xF0o\x85\x94\x98ڡ\x9BN\xE5\xF3\xB8\xA6
\xD3Z\x97\x86\x97\xAFuB\xEC\xB8\xC8d\xF6\xE4g\xCDM{6%\xDA;\xA7sya>\xE1\xC5;7\xAE\x85J\xBD,4\xDB"68?r\xA1\x83\xFD\x88
e\xC5/\x9B\xBB
+\xE1\x9B]\\xEB\xADM7\x92<\xAEOz\x98\xA0֭7\xA9[
+ \xD7\xF5\xD6T4ht\x80\xA3۸y x\xBE\GV.\x9F\x81@\x88 \xE1b\x8F\xA6g\xDCE\xA6tȫ\xF6}\x99\x91$ 7 \xBF\xA6\xC5\xCD\xCA@}\xBD-\xDF\xD8\xE2\xE5n\x9Eodpx\xF8\xEBz'\x9Cc\x90\xDF\xE2!\xC9 4\xF7I \x813+\
\xDF\xD1\xD1%;;\xC1\xC7\xC71\xE7\xB5vo
\x80\x95\xF7\xBE
+\xFD9\x89I\xD11\xFE\xC2~\xBB\xB9\\xFEk\xD1\xFE \xA0\xD8ĕմ3\xAC-WLo9\xE67\xF2\x8ByYn\xB8\xE3ʤ\xEC\x9AV\xF5XUBV}\xECl\xC3$\xFDkE`\xD1h \x94e\x99\x91\x8E\xFEIaGjz\xE5\xB5\xE2\xBE\xA5{s\xEC\x998x4\x8D}v\xEDJGs\x80\xCB\xE3s\xA7M\xD2C[\xDB-\xA1bFB\xE6\xFA\xF5\xA559X\xB1ifT\xD45\x83\xA0\xA5BPt3f{@{\xCBx\xE7\xF5!nEÜ\xB2\xF8\xAE\xA2\xC9\xCDm}'\x95E\xC2\xAD\xF3 e)+
C\xF0M\xA8ٻ\xD9j\x84n\x8A; b|\xB6\xFBF\xAEɯ\xF8Ǣ?7^WZ\x92b\xEA
+ 9\xBF&\xC4M밳QU$5\x9B\xBFͧ\xC7F\xB8;\xFA\x8C\x82\x90\xCDs\xEAkDe\xFB\xA5U\xF9~FP\xA9T %\xA9
\xCE1°\x84\xEC\x9ACˬ4\xFD\xBD*0-PU\xB8\xD31\x86U\xDC0w\xC2\xF45{\xDD\xED\xD3\xF9\x91\xB1\xBEE\xA1\x89)h\xD5[Y\xA7\xD8ь \xF36\xD6\xD0]\xF2n\xB6 B.kGE\xCC"\xE1\xEAs\x9B\xED\x98\xF5\xED̜\xE6
\xAE1%\x9E\xCF\xE7 E\xE0'1\xE8f
Ѫ\x86\xF9\xFE\xC1?}X\x8A\xF3\xB6[\xF2cԿ\xC3Rϴ\xBAWnL+oU\x8B\xC3\xE1}{|V\xBAj\xCE14\xFA{\xE1m#
+\xB7\xAFp\x8D \xF0M4m\xF6xc(E\x85\xDF\xBB\xFA\xF1S\x9B\xD2V0!\xCB\xDFz\xED\xCE\xEF܄
+\x8D\xCE7\xE2m\xEE\xF1\xFC\xECZZ~a\xA2O\xA8?\x80\x84\xE2\x86\xE1\xA7\xD69Q\x92\xA7\x8A\xC5l\xF7\x91\x83\xF2'\xE8\xEE\xEE
twwwww\xF7lk\xEC\xA1\xF4\xEDC\xA5g_wwwo\xF8\xEE\xEE\xEE\xEE\xAE
\xE0\xD1\xDDE\xF1\xA0\x8B\xE8\xEAR\xDDo\x91\x8E\x9C蓀\x90I\x9B\xE8\xC6&̇\x89pBIP\xE9OR\xA9+d2{\xA4\xC6U\x85\\xCE4\xD0|)\xE5r\x8C8Ӟ\*\xBA,\x92b\x9Cɬ\x81W)\xCE\xDDY\xE5\xB5\xFEmg\xB3!\xD7 at H*\xFC:\xF1;ۿ'{\xD7\xE5\xFC\xD0\xE6\xBD\xC2N)R\x8DYL&\x93N\xED?\xA3$-˂\x9D
ōG\x88\xF36\xE5 6\xDAc$5U\x9D\xC1p\xBA仱\xABvx\xDB\xF4\2!+\x8B\xD9\xFAe3\xC0Y\xF8\xEEo*\xB9\xE1\xC17\x96\xFC}\xB3\xDB E.\xC9
+\x95\xAE>\xD23\x91\x94\xAC$em\xBE\xF97q
\xFD٤TH\xEAĒy\xCB=\xF5\xA0\x98I\xB3:Y\xF5\xBD\xE5%\xB9g\xE4c\xC7\xC0رc\xD1;\xB1Kg\xE7ة\xDD\xEC4ߞʒ\xCCt\xB9\xFD*\x9B\x87\xBFR\x92\xCA넅
G\x9B\x96PH*\xEBhv6ש\x84RI\xD5:S\xD4c \xAF\xCC4-~\xCBM\xFB\xE0\x9C\xA1\xC1\x87\xA9H\x83-\xEC]O\x9CJլ&\x8F\x82\xA2̓\xCA\xBD\xF9\x85\xF0e\x9D\xC6\xEB\xC5G\xD27{:p\xA8\x90\xE5D\xAD\xF59a!<\x97h\xC3\xA0H\xB3eud\xB5#e\xD1 \x95\x99\xEC\xFD\xC1\xF3ݾo\x9FG\x8F\xED\xED\xACn\x97\x906ݧO\x9B\xF30\xF9N\xC8DŢ63\x8E\x85\x99\xC9\xE8ǵJ%1h\xA2\xAF\xD1\xDC\x8Fj\x9BRR\xF6\xD3ozsl\xB4=\xB9\xE1\xABO[}\xB0+P=\xE5<Q]p\xF8\x82\xE4vL^\xF3^\xC1\xD10\x82P\xC8 F\xEF\x88&\x82P\xE2!\x8F\xBA\xFDB\\xBBvy\x82\xC18
+\xA5\xD0\xD1ѡ\xD0\xD1\x85B\xA1P(:::\xCAH\xAF9ҋI\xF2\xF93^̉&\xB3u\xC6P\xA9T*e:T
+eLO=\xA6P(
\xF5\xBFn
+cԵ\xBA\x9B\xD2s
СP(\xA0P\x80\x81{\xFE4\xDD\xE8
\xE1()1IHH\xFEQ* \xFA\xFDx#yZ!%&\xC9O\x9B\xC4$\x87\xFB\x90\x90\x90\xFC7B\xEAK\x92\xBF\x93\xCDֹ\x98\xCD|\x88\xAF^w&s\xC8\xFA\xC0\xFF^\xE6ڛ\xCD\xFC\xCFZ\xF0\x82|\x88\x93\x90\x90\x90\x90\x90\xFC˙9\xDFq\xA9\xF2\x97
\xC3/Y\xFBo\xC4d\xEA3fm\
\xBC8\xD7#\xF0\x8A\xFD3\xA7+\xFE}\xF8U~on\xE5M\xBA~\xF8<\xEB\x9A>\xAB\xE6\xC2/\x82\x83\xB3"<n\xD3F{&\xEEWxe_
16\x93\xF9\x8B\xBFy\xD7\xEA\x8FK\xBF|\x91Yrz\xC8)\xDA¿\xFAm\xF0L\x95\xAC\xE9\xD2\xCF\xE7C\xB2jGi>\x8F\xBF+\x8EUy\xAE\xA6\xE1>Ƶ\xE7l?)xx\xF4$\xDA!\xBD\x98$$$$$$\xFFr\xAE\xDCa\xAD\x8D\x8B-O\xF2Iy\xD7q\x9Dˌu\xEE3\xE6\xFES\xDF\xB7\xA9x\x8BӪ\xF93\xB6\xBC\xFB\xEA\xF1\xD4-埇\xE5~\x9B:\xFF\xB1]\x86\xBA\xCBC\xC2\xC4I\xC3O\xFF<\xA6\xE7\x8B\xF9WQQ\xEF
\xB3f,\xDA\xFBy\xAC8;$\xC5s\xC0
̺4 \xA8\xFE\xA1P\xAD/M\xE6\xBFz<\xD6E\xEDS\xF4\xFF\x9D\xA3\xEF\xCF\xE8)=\xEAd\x83ނ\xD7_\xCF\xFC&x\xD5(\x92\x97\x9E?\x99^\xD2±\x9E\xB1|\xF5\xDBqSG
+y\xF0Ӕ\xE0\xEFZ\xED\xBC\xB4t\xC9K,\xDC\xFD\x89㨯\x91d0\xA4\x93\x84\x84\x84\x84\x84\xE4qX\xF4*\x8E\x9D\xFC\xBC\xCF\xC8dΝ>e\x8E~\xDD\xF9w\xBF
\xE2*\xBBr\xCA)\x96z*f\xE1rknϞ\xF7~\xF5[\xFE\xD5\xE9\xC7N\x9Ei\x99\xBAvb\xEC\xEER) \xE8\xBE2\xDFj\xB9\xE7BGc\xE2d\xFA\x81\xA8\xF3\x83={;\xE2O\xBC\x92\xF5ή\xBE5>\x89\xF9\x9D\xC6?\xEE<ĥ:w\xE63\xADW\xFE\xB8\xA2\xE5HGK{\xDDzI\x96\xCBy\xDFrN\xEAZ\xA3\xFC~3\x9C\xC6q[d\xEFh=\x91\xA8\xBF\xE0\xB1F\xA0>+<6|\xBD\xED\xB8vb\xAC\x81> =\x8F\xA8X/:\x95\x8A1 \xE8M\x97\xAF[\xF6˱\xC4 \x93\x9F\xE1a"m \xBDq\xFEe\xF6\x8B\xE3\xEC
8\xA7~X\xF4\xDBM\x85\x89\xC5D*f
\xBF\xB5s\xE9\xE1\x9E5\x84\xBF\xFE\xE9\xFA:\x87\x97\xA8T\xC3铁Q\xB8c3\x8E]\xD9\xF2\xC6t}e}\xD9
+ 0aB\xAA\xCD\xFD\xF9\x8A'+\xCF at y\xEFvݍ\xA6\xDB\xEDĭˏ\xE0\xA9%)1IHHHHH
\x87;z3w}\xE5\xF8n\xA3\x82\xA1\xCF4\xD0\xD7\xF0:\xCC(7Ι\xB3\xA3jPx\xE9\x{14F359C}Y\xE5\xFE\xD2k.6\xB3\x9Ec\xB3\xF5
+gM\xC6\xE9\xC7n\xADV\xFC\xDE9\xFD\xDD\xF2<\x94J\xD0\xE9c\xFAv\xBF\xB3zN\xD4\xF9\xC2!\x81u\xE5G̝j\xD4\xDAv\xEFJc\xAF\xB2d\xBD2\xB5\xF3\xF4\x8Da[\x9A
\xBD\xDE\xD9\xE8\xA0w\xEE\xD0\xD7^C3\xD1\xE8=cn\x88\xC2\xDF;\xA7.ۻ\xBB\xBF\x97%\xF5٩\xCEL\Q \xC0
\x95NE\xD3\x8D\xF52\xB6\x8D\x85\x9E\x81>P\xF3Ü\xB0B)\xB0\xEA\xFD\xF0]\xAFO\xDDb\x9B\xB1\xA3\xCA\xE5\xAB\xFE\x9C1,k= \x86\xB3_\xFBh\xF2D kym \xEE O\xCE\xDD\xF4\xCB\xD1oc
\xA8\xE2\x94^} \xC0l\xE2*\xA0\xBC~a\xDB(3\xF0~{\x80k5\xE5Sm\x8F\xB8\xDCn\xB2\xEEoE9s\x87\x96\xD1\xF5\x86\xBCW`<\xE7E\xD7LqGr\xF0\xB0D[\$\xA3\x82\x94\x98$$$$$$\x8F\xC3\xC1\xDDY\x9E\xF6\xEF/\x98l \xBB)>~\xE2J\xD9U\xC9?\xCF\xDFLݴ\xDCB\xD7\xC4\xDA(_&;\x95\xFFc\xFA\xEE\xA0\xFD\xF3K旌/S\x8A>\xFF\xA2\xEE\xDC\xC9
\xC3t\x9A\xEC \x8A\x97nX\xF6\xEA\xF4\xF1*\xA5\xB2\xAD\xED\xBE\xEC\xB6LR\xEBB\xB1f\xBAFq\xEFO\xCB\xFE\xB4\xF4
+tgN54\xDE\xD4\xC6\xCCx2\x9Bmfn<I\x9Fi0A\xC0\xBD\xEBgy\xEBOj\x9F\xA8E\xD5\xE8.\xF0Z\xFCʗ\xB5\xBD\xAD3X\xE8\xF2\xD3'\xFF \xB2\xFE\x93\xB1\xFB?\:Y^t\xBC\xE4ȩ+\x82^ͺ*\xE8\x9D\xD0Y\xCC{\xB7\xEBk\xEAx\xA6wŁ\xDF`\xF9M\xAA\xD5ݖ\xFBУ`\xF3\xBC/\xE9\xD1^\x88ٟ\x84\xC7m\xDDh?\xE6\xB3wR\xE6\x8A\xE5M\x90\x9F(\xFAc\xF93@\xA3ci \xD0uo\x88\x81
+W\xC5#\xE5\xA4&\x8A\xFA?\xEE\xE09\xEE\xEB埫\xB7\xDB~\xABo\xD2<\xBE.:|\xD5\xFD\x92\x8C&\xB3\xE0\x9D/\x99P\xBB\xC4\xD7ef\xD3^Z\xBE|\xDEַR2F\xD1ݓd(\xA4\xC4|JQ\xC8\xE4L\xF6C\x96\xE9\xF8O1Jۆ\x99ԆP(&\xF3\xA1\xF3\xF2)e\xB2v\xF6k\x90\x90\x90\xFC\x8F\xF0\x87\x97O\xD4\xC0=Fl] ?|\xF5\xFD%\xA7\xE5\xAF\xEC\xCAM\xF8[cC}\x93\xAA\xFAD\x9D\xD4\xDAJ>\x97\xEF\x9B\xE5>\xE6t\xF5]\xF3gM,,&\xEBSQyh\xDFҡ~D P\xEC\xD8\xFDՎ\x91,\xEC\xB4Z\xF4Ʃ\xD7=\x801\x9A{\x89z\xB1\xF0\xB7\x96z\x99\xEEx\xB6\xB1\x81\x810Tb\xF2\x836.Pw\xA0<0\xD8ΩF\x93\xA8\xB8W\xF1\xE3\x8E
\xED\xAB\xF5\xF8\x97A\xC7[x\xF6\xD8\xF7u\xA7:/\xDE\xE8\x8C\xFBd˂\x89zD}\xE5\xE7E
+s}Ƃ7^\xA25\xFD\xB0#\xE5\xA8`\xA0U\xED
?Y\x9FF\x94-ҡ\x8Arm\xF2·\xEA\x85Fq\xFD\xCC{\xBB\xAF\xEA1\xEE \xAE4:z\xE9j\xEB\xD65+?\xA0\x94l}ko\x86\xAB\xB6\x84\xEF♆\x86\xD9fl\xEC\xEC$
+\xE4p\x9F\xE1Qʥ\xD2ޥ\xBA \xC9v\xCF\xF0ʇ~\xC7\xE2\xED\x9E\xE1գ[}\xFBQG\xB9P(\xDB\xCC\xCA!K\x87\x8Feu\xA0\xADg\x9E\xB8\xC7,BV\x99\xB6=j\x81\xB1aJY_l\x84B.WD.W]\x97YZ]RXV-\x91ɕ_\xB3\xF9I\xD9@Y\xB0=<Wԟ\xFBJ\x99\xA80g;\x83\xB1\xB8\xA4\xAF|\x88^\x83Xe\x8A!\xFB\xA7[\xF5\xB2\xF1\xBE\xD1,
+]\xB03J3\xE9a\xF9W= \xC9\xFF* \xB8]^\xAE\xA5\x9Bc\xD4\xFAO\xBE*k4\x98lj\xC3\xE5\xD8\xD8/\xDC7[k\xB3\xCE\xD6M\xE0,\xE5ٍo\x97\x9E\xFF\xF56\x80\xDCg
\xD7
ŲMGDw:d\xF5J\xDAg\xBA$bW\x85\x80\xF0\x87\x83K7\xEDw[\xBFw\xAE\xCF6\x8E\x8F\x96\xE1ۯ\xF8\xAE\xD9\xFBDîu;\xA2*\x86>itt
ϖ}\x99\xB4|.0\x93ٜ8D_\x9066_\xBC\xA1\x8Fy\x87\xAB'\xAB\xB9\xF0\xF9y\xEA\xBA\xD5\x97\xBE\xF1\x92\xA2Fb\xE8\xB0d\xEF瑗\xF6\x8D^\x9E\xA4\xCE\xE6tS& \xABh\xEC\xA4 \xEEK\xEE=\xF4M\xD3u\xEDf\xCB#eA\xB4\x9F\xBE!\xAA/\<\x9C\x95^\xD6p\xEF\x8EdW\xE0^\xB5\xDBR(j\xC00b=R$}\x90^\xCCa\x91\x9C\xDAb\xCE7j\xE8\x8E3\x80\xE6\A\xD5k\x8C\x87\x9DCe at P%S\xA0BI*\xD4\xEE4B^\x9Du\xF8\xE6kk<F^\xFE\x86\x90U\x9F<{s\xAC\xFE\xD8{ǎm\xF91<\x9EW\xD1\x9Fkxಟ\x9D /\xCC\xCDo\xD4\xFA\xE56v\xB2\xFB
+\x97A\xAE9ɩ/Ӆ\x93\xC2M\xE9 t\xBD\xA6\xA2x#>7\xD41\x96ߝh@Q\xB1\xC0\xD0Q88.nik\x95À9̔\xBE\xFCpeRQ\xCFa~\xC0\xCF\xD78͞af\xA2\xE1L$D\x85?\xAA^|\xD9ft˝<\xDC6 D\xDDw1IsW\xC6\xF7\x9DEm\xBD\xEC\xEA\x93 \xE7\xE5\x99\xED\x85~Ti
\xCDT\xD4Խ\x99
+\x80F3\x82Qo@\xC5^KYѪ^EP\x94\xB5E\xD0>c"\x9A\xDBڀ[B\xDC\(\xD6\xF4\x8C\x8C\xF0\xFB\xAF\xF7
q\xDEV\x80Z\x96R\xFB֤\xB9w\xE1& J\x85\xAC\xAE\xAEq\x92\xF50W6Lѓ\x90\x90<]0-\xA6\xEA\x8D7\x83Us\xD5|\xFD\x83\xE7\xFF\x88\x8AI\x8Cb\xF9\xBB\xDB:\xCDz\xE6^e\xC30\xB1Ժ\xBEc\x82)
\xB7u p1d\x85\xC9d]i_\x87\xCB?\xBBz\xFD\xDCg\x86#\x87 t\xC9n\x8F\xE4\xFC[\xB7!x\xEB3 P\xDE-\xBD\xA1%\xC0\xDCy\x96T\xB4\xC1a\x91\x8D\xEAJ\xAB\xBB\xD7\xB3⥩چ\xC5L\x9Eq(\xE1\xADۊ\xBE?\x8B\xE7\xED\xDE\xF7bw\xCE]U\xBE`k|\xAD\xE2\xCF?\xFFܳf\xECg\xCD\xC4\xDF\xD7 \xF4M& \xCA)zl\xC53\x94h\xFEC\x8B\x94\x9F;\x95yQK\xD3{* *\xADK\xF8\xAA\xE9\xD8\x93\xB2Mc\xDBr\xF28\x90:\xE9O at fݰ\x98\xBD\xBA\xD9\x96\xA7D\x91~\xA6\xCA\xEAK"m\xF4\x9C\xA6\xA7g\xF7\xDA\xEAw<\xEC\xE8 q\x94\xBDe\xFCicZ\xEF/^ik\xA1\xED7\xF3\xFD\x83\xD0\xE8\xA1\x88(I\xF1O\xC7\xFA!\xFD\xBB\x9A\xAB\xA3W~a\xC1\xFC\xC1tS \xEC
+cx\xC2M \xA0\xB8\xF6\xD1JV@\x98\x85\xDE\xC0pm7\x93\xD2oօ\x8Aʭ\xFC$ \xF4\xBE}\xBEaa\xB6\xCF\xCC\xCF\xC8X\x85\xCAkn IDATң\xE1\x98e\xAD\xED\xA0aC)\xA4\xAFH,\xECN\x84R!k\xA8\x95\xFDt8\x91\xEA\x8F\xEC:\x95w\xDF\xF2\x93D\xC3W\xF7 \xA3\xB4\xC1\xCFa\xE0Z\x88J\x85\x82\xCA
\xB0\x82\xDFhl\x80\xB6Rp\xDF\xED] \x9B\x90U\xEE\xFF\xF9.\xAD*2\xF8t \x86\x93\xF8\xBC:\xADUY\x97%z\xBE\x83'\xBD\xC8\xF7\xAC\xF9\xF2\xAE_\xCDAӥ\xD2\xD2J\x9Fw\xDF5 at gٗ\xE9J\xF7w\xDA\xF5Se\xCD~7 \x97\xCB \xE0hس5\xB8Gj\xCBVp\xE8\xA3/z\x92\xBF.F\xBB6\xCCؽ\xBBD\xDD\xC4l2\x99if\xA4o>\xCDL\xBD,\xE7\x90v\xE7\xB1ޛ\xCC\xEC\xB0\x8A\xE6\x8CÅ\x87G\x8E\xBCC
\x83\xA9\xA1
\xD0p\xA2p\xA0\x90\x9A\xBA\xF8r\xBC\xF9g\xB1ǥ\xA6\x9AN\xB6x\xD6`\xD2\xC4 Y\xE3\xF4\x98\xBA\xAA.C_O\x9F>F~\xFD\xC2\xDA\xF5\x82\xC1\xEEI\xE6\xF3\xCFO \x88zA\xE1pcɍ\xBEL
+]b\xA1[\xF9ݾ8\xC9\xFC\xDC0\xCEҩ\xB8\xA8Me\xCC7\x96ϸ\xFE\xD5Q\xBDdae \x95\x98̔\xD1j\xAB\xCEɟ\x9B\xFB\xFAB\xA2Q\xFC\x{D873}0\xB7\xE1;p\xA8 \xD7vJ\xFE\x9EOw\xE8\xBE\xB2[?\xFD f\xDAL\xA3CYs\xED
+&O\xA4J*\xF08\xEDe[ⶼE\xE4\xBF\xD3ߴ=\xD7\xC5)\xCC\xE3ũl\x96
\x98\xEAth\x8BaiIY\xE2y-\x8E\xCCAXs\xD8 \x9A~#\x95?&\xA4\xC4
E\xD3\xED\x89\\xF8[\xB3\xFCp\xF9\xB1\xC9\xD6\xD3'\x8Fm&\xF1\xED\xF7F\x9E\xA9\x8AsX\xFC\xC4\xE2\xEC \xE3YF\x86z\xB4ֶ6\x96!\xF6\xF1C\xB9YlP\xA9\xC0T\x8B
\xDCA\xD1S_\xE0\xB9fq
]\xB7\xFAY\xF5(\xBA\x95wU\xB7\xF7PKę\x9E\x96\x89.-U!=\xEEI
+\xE0\xC5|\x96h7\xA8\xF4\x88\xEA\xAA\xF4\xD0A\x91l\x9F\xC5K\xA8\xFDv-\x8B @\xA5\xD3[ϳ\xCC\xDD笎
+\xB1\xEB\x95?\x84R\xAEPQ=\xAD;\xFD\xD0\xD0.ogh[\xFB\x9C\xCEdsl\xD8
'\xEF\x90h\x85L\xC6\xD0\xF4\xCDR͢\xBB[\xE7\xEF\\xED\xEAhZ\x95-L\xF4\xB6\xE9;"\xFAj\xB5\xF59\xDF\xF6+z#|\x98m\x844on\x95\xE4fEi\xA1BG\xE0\xA5g:5\xD9E\xE6\xAB\xD2\xDCzV@\x8F\x8B\x99N\xA0׳1\xC0\xEDl\xC0q\xE0/>\xEB\xEFX\xFEQ\xB4\xB7A\xB30\xEA\x98\xEF\xE0\xC0\x84x\x8Fc\x96\xEB\xE6NOdt\x9B\xC0\xF6\xD67\xCA\xF6\xB66
+\xAD\xFBȯ\xDD\xF4\xB2\xD9\xC0ŶG]\xF4$$$Y:\xA7.|\xBD|\xFE|\xA1Ǟ0p\x82\xC9\xC9qSQ\x94Ys\xDCI\xEE\x9A\xE0\x86w\xDA~\xBBY_s\xF5\xE6\xB5ߛo\xB5\xDE\xF9\xA1P2@\x8CN\xB6\xDC\xF2\xA2|G~\x8F\xFA1\x99<\xE3\xC5)c\xA0$\xA6{\xBAdٱ\xAF\xFF\xF4\xE3\xB6\xC2f \xB8q\xF5\x96\xBE\xEB\xD6\xDDagvݻצR\xA0\x8F\xA1R\xC7 0\x986o\xF9T\xC1 u\xE8\xFFNl\xE0\xB73\xA7\xB4O'δ-\xCE\N\xBBz\xCEoө\xD3
+\xACڰ\xE8\xD2*E/\xD6\xD4+\xC1\xA1S;._Q\\x99p\xCB`\xF5뗒L\xBE\xBB \x81>\xCB\xCC\xD2\xDCƔz:\xFD@\xD4yEȦ\xBD&\xF3g\xBFͪ\xFAb\x9Fjޒ\x97\xDF\xF6z\x9DȮ\xFFZ|U9g\x91\xDDҰ0NJ\xEF_\xEB\xF9\xC4w\xB1\xA2\xA3\xE3\xE0\xBE0
'Q\x81{wZ0\x80\xFA\xAF\xC5\xF78v \xB4i\xEC\x99:#\xEBo\xBE\xBCge\x97\xF4\xEBK\xFF
+!-1Uޑ7\xDD\xEBPL\xBA\xFE\xC4\xBC\x85x\xD7\xDF\xEF\x8B\xFBjǕ\xA6mzf\xFET=\xA0\xAB\xAA\xEC\xF7\xE1Ð\x8C)1\xB5\xA1\xACdp\xD3.@dMk\x9CU\xBF\p\xE3q:X\x8E\xA2+:\xDB\xC1\x85
+ \x8A\xEA\x{DAF9}1=\xB7,\xAFN\xA5\x83\xAA\xE9T\xC2F\xA0\xA9:\x986~\xA5 \x89\x8E^\xFC>\xED\xA8
\xE9~\x81\xEF\x91
+\xA3j
b\xD0=H\xEE\xE4\xFBd\xF1\x8A\x9B6szO\x96\x96a\xAFq\xFB\xCFT\xD3
+\xED \xD3~\x92+Z\xFB\xC5($Q\xF3\xFC \xF7\x85s\xE7\xD8YM\xB3d3\xA9L6{\xC8IL\x97\xCD\xC7*\x8C\xED\xCF\xDE\xFC\xC4ۦ\xA7\x86)\xAB?\xF8f\xEF\xE8͒Q\xD8F4\x97\x9E\xBBi\xC6\xE7ٟH\x84 \x9Ab\x9D\xCF\xEF\xE3:\xCFS
\x8Bn9c\xE8\x9A\xF5v\xBF:o-
+\x8D\xDC~\xD7@{}\x8A\xA27E\xD92\x80\x96!4r\xC5\xC0aC6\x9F\x97\xB7)̓\x80\x882?\xC8\xF2=r\x80\xA3y#(\xAF\x97\xFF\xD26\x81=q<\x8BFU\x81\x8B\xFA\xC6\xEB\xE5?\xFE\xF2K\xF9\xF9\xFDE\x86GOEs\xA8 u\xD4EOBB\xF2\x97E\x9D|\xE1h\xC4<6\xD1&V\xFE\xB3J|妬\xFEN\xA7
}\x9Cɔq\x97d\x83C_\xCCڿB\xEA\xF2\xE1\x9AE6Ӧ?7m\xFA \xC0\x96eg\x9E_\xAA?\xD0\xFD \xBEak}ߺ
+}\xFD\xDE:T\xB3\x80uf xӚ\xCA?\xFA\@\xE2\xBA\xF9\xFB\xE2ֽ\xFA\xE2~>^,:\xDD8@*͜\xFA\xCCK\xE6\xE3\xFE9\xD8\xFB8#\x987\x8D\xFF\\xBE{\x98\xE5mU\xCE\xCB\xFB\xC5\xD9\xF4\xE7\x86\xEF\x83ؠ\xEE\xACߥh\xAE|\xB0\xC6z\x95\xB5]\x80\xB5]\xDF昚\xBE\xFA\x9Aۺ\x89z\x8AƺӇ\xBE+\xAB#
^\x9E\xB7\xFC\xF5 \x88;
+\x97o\xD3^a\xE2\xB4 \xD3{\x81)\xEE]ӟ\xF1_\xF9\xBC>p\xAF\xA1\xA1\xB6c *\xDDp\xEE\xD4)\x95\x8B7o༛
lt\xBC\xFA\x9E\x81\xB1\xDD\xCCi6@\xDB\xC1\xA8\xBD\xFBC=\xE3\xBFĴ(*·\x80\xED\xC5\xBC\x9F#
\x97.}\xC3N"\xE7\xFD\xCDn_\xBF#\xD0>\x94
X\xEDk\xA7\xB90/\xE8\xFCłL\xFF\x8B\x90S\xF4g}\xC5.v2\xA1V\xBBиR\xA5\xA6ĄB\xDELaih\x88\xEA\x8C\xD0fvK\xB77U\x94ò\xF65(\xED8$s\x9A\xBF+\xE2L\x8AB\x87u\xE9\xBC\xC7\x95\xFE2n0\xB2\x92\xFD\xF1\xE0\x95.\xE1<\xE25\xC8\xD2Veq\x8FԞs\xEA\x81\xD2\xFD\xEE\xF1\xFCT\xA1\xA6\xA0b\xDA\xB7\xB7j%\xA7\xD2\xE9M\x85\xDBM]\x8B
\xA6if\xB8\xAA\xF4\x8C]\xCD\xE5\xF3g\xBEp* \x9EoBp\xF8\x86\x83ݩ \xEC\xFCҺ\xFD\xFA\xB6\x88\x82Xnbԝ
Gi\xDD&\xEE@"\xA0Lۋȥs\xD9L\xF6\xCB\xEE<\xB4\xB5.\xA5 \\xC7-߾ȕ\x809cۑ\xEC\xDF;\x8CU\xF7ᱰ\x9Ae\xCDD'8\xD9G\xF2\xD9 \xA4%{\xB3~aO\xFC\xBD\xE9\xD1{^\xB9Ǹ\xD9\\x9F\x95\xB3\xD3\xDF_ \xDFy9\x99\x99\xB7\x9BZgy\xB8\x98\xD1\xDC<\x9F\x91T\xA4\xEE#\xD5\$\xF7\xEBl=\xC7\xE9fs\xB6Z\xBĊ= \xC9_\x98+\x85\x82\xE7\xB59+\xB4\x87\xBFXX\xE8VX8s\xE6\x9F\xA5sx/r\x9E\x9B\xA0\xAB?m\xC1\x87\x93O\xF5\xCF\xEC\xA8\xF8\xF9\xE3\xEF\xECv\xBD\xC1\x91\xBF=!\xBCX%6\xB4\xC8;\xC0dΜ>Ş\x83\xE2\xBE
\x86WJ\x9C\xBD\x86\x9D\xF9\xE8ʍ?\xAEiݎ\xDB\xE3k\xA2\xBF\xF3\xEDp\xA2j \xCCil=\xA0M\xFB\xFA?\x8D\x97\x8A\xEAݗ>\xABv"vl\xFB(\xC3\xDE\xD6\xFF\xAB\xA9,:@\xB4\xB5ޫ8]\xAE(\xC8/,?,\x90\xAF\xB88\xAD{\xF3叼\x98 \xEE5J~\xF8\xEEDȱ\xFE)'M\<Lh\xFC4\xE9\xC3\xFB6\xC7 \xB8y\xE9\xAA\\xD7 }\xCA\xCC0\x9Fg&\xD1BW_ӆ\xF3GjlVY\x9B-_\xDDۯ\xEA^CzLʶ3\xC5\xFFq\xEEz\xC7;q^\xACo3~v"
\xC0\x9D\xDF6\xA6~\xBB\xF1\x98\xE8L\x9A\xB7]\xDF@\xDBPz 3ݽ\xB6.\x98H\xD4\xFFs\xED\xA6\xD2Q\xE5\x896H\x89\xA9'' \xC0\xB4\xB7y\xF8Q$59l\xFD\xB5E\xEA{s:.\xE7\x87\xC6gd\xD7hv3T)\x9Bysl M \x96*\xA0Eg\xF4t\xF5\x93\x8B\xCA\xEA\x8D\xECmԍ\xCBL\x87m\xB1p\xCE-\xB1f.E\xD9Z\xE7^r\xE9\xA3\xF7\xEAc\xBB\x8A?Z\xECd\xD6o\x89(g[\xF8\x8D\xD7 *\x9D9\xB4\xC8s\xC3c[<0]\xA6\x8D\x83\x8B\x8D\x83\xCB
+\xBF\x90\xC4J\xA9\xF8\xD7'Ҳ*\xEB7\xAC\xB0r\xFA \xCA\xD2\xFC\xDD\xE3\x91]\xB3\xA97\xD3Fo \xFB)\xA8\x88W*`ܴ\xFE\x89\x88p=*~˛C\xAD\xCC\xFD\xFD\xBC\xD5j\x95\xA8\xFE¿h\xF5\xEF
\xD9+-ܹ\xBFdC\xA0\xBA4\xD1ѡ\x98\xF2\xF6\xC1\xD8\xBEO ^\x86 at 0\xB6\xA5Eѡ\xF9\x91J\xF7\x88>\xE0ݳQh{-<#\xC4J\xFB\x9D2\xBA\xA2'!!!\xE9\xE7ʕ_\xA3\xAE\xFC
+`\xA6\xFD\x8C\xA5
|=p\xCE˃\xA9\xE9S\x87\x9C\xA3PH+~==\x8Cr
+3=}<\x98U~\xFCC\xA3^LH\x9FU97\xC8\xE4\xF7!\xEEX\xF5Ѡ5۾\x9A:\xB6o\xC2\xCE+U+\x86\xCE죻e\xED2\xBE\xED\xE3\xC9L:\xD1!\xFD\xBD\xFE\x87\xEF\xCE
+N\xFDs\xC8\xEA\xE4̝>\xC6\xA3wT`G~k\xF1\xB7KUW.l;\xAC\x80\xCBm\xE9
\xF6\x8D\xE3Y^Y|\xBDf6n\x94\x83
\xC3>\xAAx\xF3U\xCFY*\x95\xB2\xF1j\xCD\xEEÿՋQ\x91\x9Fw\xACuq\x9Di\xDCT\xDFp\xBBN\xF4E\xD2) h\xACr\xE5\x8Bf2;\xB4-\\xFE\xBBk\xF6z\x99U~\x9F\xB3\xF4Sr\xAE\xA2?)1G\x86\xEE\xF86\xDF\xFF\xA802\xF6|[Z~\xB6\x9Da\x93_\xD1\xE0f7` \xCB\xE4\xD9+\x8A\\xB9.\xE5\xBE\xCDYY ڇFÜ\xBAE\xA7~\x95;8\\xFE\xDAљQ\xDA
\xDD3\xCAg\xD6\xE2X8\xFE,\x8Bs\xDA\xDEB\xBC}\x81\xA3\x80\x9BР1$\xA8ڐ\xD19\x830s\xF2\xD0\\xFCUV\x92b\xED\x93
\x99_7\xBCôQΖP!\xAF\xF8''͝2\xA9\xCCI잁\xD2t\x8E݊\x90\xB4#GD\xC8rc\xBCV\xC6E
+j\xBD\xAD\xFA\xB5\xD7\xE8m\xAB>\xBA\xFC\xF7l\x87\xDA̞#HN}
+\xA2,\xF1\xBE\x93z\x92KB\x8D^\x8AƟ#\xF2\xA7n\xD5\xC4)ds\xCF\xE5T\xA6\xAApQ\xF4\xFB،h?\xB3\xC1\x91+\xC49I;\xBF\xC8-m\x84B!\xFF\xD9Ë\xD7,\xB52ђq-zB!\xA9\xB8\xF4\xCD\xC4ʎ\xA3\xA5\x84IHH\x9Ef\xAET\xFCz\xE5O\xA8\xC6GK\xEBX\xF6\xACc\x8FxJ\xFE!N\xFE\xC7;.V\x8AZ\xC2
?\xF6\xFDٜ\x8D#O\xFD\xA6\xF0]\x93\xD8\xFB[\xA3\xB1\xBEP0\xA7\xD7I\xBCm\xFB~\xADg
<|\xF2\xE0\xC8\xA7l\xBDMˁ\x8E+\xC3\xD5T\xF5\xE3\x8A/%C'r"yTH\x89\xF9L\xED]\xE0\xFF\x83"\xD1\xCD\xC3o\xB3\xC70aL\\xA2[j\x97]\xBFo\xE0
\xE9\xECc6a\xA8\x8B=?\xAE{J"
l\xB3\xE2\x91*\x9C\xD1w\xC0`\x8A-}C\xB1\x99=P\xC0(ą-]\xD3VӾ\xD9dpl \x9Ao\\x97\xB14\xA6}\xA4R\xA9\xAD\xF5\xC3
+\x90\x93\xEC4w\x8F\xF0M-\x8Ds"\xA7\xA3(Ivʊ̯s\xD2\xEC\xFE\xA9\xAC^k\xCAU\xDF\xEB\xBEa\xB1\xEEK9ؿ\xC0a+W \x85\xAC⇃\x91+C\x8B\xC0M-\xAEt6ݑlSV\xEF*\x8A-\xFDV\x9D\xA1ĭE0\xD5\xEB\xD1\xD6L\x8F\xB5R\xA4Z\xCD㏰\xBCo\xDE\x8DZ.ϋZďw\xA9i*M\[\xF3\xE1\xDE\xE7LM\xCD+\x92\x8B\xBF q\xD2(3y\xCA\xCBP\xC7\xE4\xE2\xAC\xCD\xCF\xA1j\xFF2~\x8C\x8F ܰ\xD4C\xB1\x81V\xAF\xF8!E//[l\xE8X\xC4\xE7AP\x99_7\x8A\xCC'!!!\xF9Kq\xE5\xC6\xC3n\xFF\xB7q\xB1\x82\4\xF2\xC9 at N\xBD\xFE\x98\xE6\$ e\x99:\xC1\x80\xE3\xE0\xE6\xC0>\xB5ާ\xC87\xFB
-\xC2\xCB%<\x9F\x9BŧQ\xCCӹ\xC9oj0Y\xDC\xD4tN\xA3=\x9A\x90I*3\xA3<Y\x96\xAE\xE9\xBE\xC9u\xED\x89V\xDA\xDA]Y\xAE䚛\x9B[\xF6cnn\xCE\xE51\xA4w\xB6R\x9A\xB7\xDD\xD3\xDC=",[x P\x8B7\xB4B!.\xCB
+\xA4\xB0\x9C\x83\xB2R\x8B\xEB!\xBAM\xAE\xAA\xBD\xA9\xA1\xB6\xF4\x8C`\xA3>\xC1\xDD\xD9ҘE\xA1\xB8lO\xCBI\xFB\xBF Yef\xCA\xCE at O[\xCB\xD8qe\xA8mj~\x93\xAAjX}\xF90\xDB*\xBF\x8A\xCEBB\x90mk^N\xA1T.+>\xB4
\xBE|km\xD2~\xBF
\x84R\xA9$\xC5}\xA0\xF9\xBEBI(\x95J\xCA\xFB\xFD\xD9
+II8Ő\xEFXђh\xC5ĭ\x9BMLU\xDD\x84:3l\xA3J\xC4}Ӹ\xDF*"u\xBD\xBF\x93
+\xC7\xCCİ.W[ܤj\xAAXQd͢d\x96
+n4\xA1\xE8\xD7N\x85\x9D\xE9>V\xA8&ħ\x9E'\xE7e'!!!!yz %\xE6\xC3`NY|W\xD14RB\x92hK1\xE4\xC6pS\xEB2\xBC\xB5\xF7\xC5c\xBB\xE5\x97
\x89\x8DM.\xCD86\x9C\xCE\xD6\xF4ʊ_6\xB7\xF7\x8Fgf\xD7v1\xD3
m7@\xD8\xDE=\x98va w\x92\x9EF\xBA\xA4`'\x85aʏ\xC1aS\xE2\xD0n\x8E\x90n\xA7\xB1,
Wފ̨m\xEDt\xD2\xE29\xA5R\xE9l\x8E\x83\x8BGH\ZUwwkS\xED\x99lϊ \xBEu\xC4a\xEE\xCDֳ\xCE/\xADiQu'\xBA
+7\xDB\xFC\xC3mSVoĖ\xAEeӉ"WSCc\xD7a\xF6ߖ\x8D\xEF~Gk\xBC\xAB)\x85\xC6`0h4c\xE7"]M4\x83A\xA3;\xC74w\xDC\xA0e\xB2̝\xAB"\x8F4u\xA7\xD9\xA8'\xC0\xA0 \xD5\xCC嘪!\xFB\xB5RgK\xC3\xF0< P\xAD\xC2S}\x83\xB8,
+ŖB1\xFA\xCE\xE7P\xD9vх\xAD\x82\xD80\xFD\x89\xBFF,z\xDA\xF8)HJ)\xA8
\xFE2\x82;\x8F\xEC\xA4IBBBB\xF2A\xB1\x98\xED>\xD2aP\xFEd\xDD\xDD\xDD\xC0\xB5\xEA\xD9\xD6\xD8C\xE9ۇ.ʃ>\xAD\xD4\xBE\xBB\xBB\xBB\xBB\xEB\xC1\x83x at twA<\xE8"\xBA\xBAT\xF7[F7
\xEEɠ,\xC9L\x97ۯ\xF2\xB0\xA1/\x9D\xB2$\xF3+9w\xA9\x87\x9D\xB66\xEDGD!\x93\xD1\xD8\xEC'#G\xA2\xBC\xF3wyn\xA3,\xA4\x94\x8Ao1Lʹ̃92\x84B \xA6\x96\xB5\x80m
+\x99\x94\xC66Q\xA4T*\x86Y1G\x99\xF8\xAA\xF4ݬ`{\xC3\xC1\xABER\xA9\x8A\x8A\xBD^{&\x9E<\xE0M\x87B"V\x9A\xF5u\x88\x94\x97x.\xBF\x98Q\xB8\xB9O\xEE\xCB\xC4b*\xA7o%(\xE5Һ\xFAf\xF4̭9ZFCi\xA4>b\xD1\x95\xB9\xBB7\xAE\x8C`\x85e$\xC7\xFB
+\xF3\xC1 at BB\xF2/\x85\xB8v\xED\xF2\x83qJ7\xA0\xA3\xA3C\xA0\xA3
+\x85B\xA1Pttt(\x94\x91^s\xCF/K\xF9w\xD9I\xF2\xD7\xE7\xE6\xF7\xFB܉&\xB3u\xC6P\xA9T*e:T
+eLO=\xA6P(
\xF5\xBFn
+cԵ\xBA\x9B\xD2s
СP(\xA0P\x80\x81{\xFE4\xDD\xE8
\xE1()1IHHHH\xFE\x93俅\xA7Mb\x92
+\xE5$$$$$$$$$OrD9 \x89vi\xFFO\x9B@\xF2W\xE2\xDEڀ+\xA4\x93\x84\x84\x84\x84\x84\x84\x84\x84\xE4 CJL\x92')1IHHHHHHHH\x9E0\xA4\xC4$!!!!!!!!y\x93\x84\x84\x84\x84\x84\xE4\x9BvEGg\xFF\xD6\xE9\xE5i\x{34CCFEB}\xF3\xC1\xE3\x9CFܩ\xFD֥\xFEq\xF9ƀ\x8F
\xD5\xE5.?tM\xF4Q\xC7&\xAB\xBD|\xB5\xED!\xCB\xF6
+\xA6\xED\xEE
+\x88\xFA\xF2\x9F\xEA\xEF?)\x83\xFE\x9A\x90\x93\x84\x84\x84\x84\x84\xE4 p\xE3te\xF6ϊ\x87\x87\xD3\xE0Viu\xDA\xE9\xFEU\xBCo\x9C\xBE\xF4\xC3Mգ\xA7\xAC\xF8⣋\xA5\xBD\xD1\xD4|[\xB6\xED\xC0\xF5]%\x9D\xA3J\xE2A\xBB\xA2]\xA1\xE8\xB8s\xA7]\xFD\xD7|K\xA1\xACUy\xD1Ň\xAF?\xBA\xC0\xEB\xB8\xED\x9E}_\xFDc\xE9\xA1? \xAD\x97\xF6αxic\x80\xD7\xC6 \xB7U/\xAD\xF0\xDA\xE0\xB5\xCEBoc\xCE\xE5\xC1Qu\xD5\xEF\xF69=\x826m\xBD\xF5[\x9D\xF8j\x9D\xF8F\xEB`3\x89!g)\xCF|\xF1\xD3\xCF\xFBwd]ꉻC\xD9E\x9A
C\xE5\xE7o\xC9/\x98\x9C\xBBճq9\xCD\xE7\x8D7_ݴ\xFB\xC4S\xBDE\xC8I\x8BHHHHHH\xFE<\xF7O\xFF\xD8j\xFC\xDE\xD8G:\xA7\xB5A^ \xE3\xBEͮ\xD6\xF6\xDB
\xFD\xFE\xC2.\xA988\xB9\xC1'\xC8\xC1\xD9Bw\x84Hn\x95^\xBF\x8C\xFD\xA9\xA6QE\xA8 ==}6
\xD6St:\x80\xB1K\xB8\xFFͮ\x8AR\xA5\xCE8:\x801zPɔp\5\xC7\xFF\x85q\x9AI\xD0\xE8x\xE5\xEAXS\xAB\xF1T\xAD?z\xD0
+\xDC\xF7\xCD\xEA\xB9\xC6@ӡ8\x81K\xD4:C\xA0\xB5*q\xDB\xCFj,\xD1x\xF9\x97\xC6\xF6N@k\xABn\xFC\~\x9E\xA5>\x8F\xF1\x8Cͬ\xA9cԿ\xEF^\xFAlݼ̋ `\xF9\x8As\xED\xE9\xE2U\x9F\x9C
+]1G}\xB46\xC7g\xD5ߎ\xB1lV\xE0\x96E& \xB4\x89\xF6/t\xA8\xED
ozk\x96~\xDFf\xE3\x8F{\x8E\xBA\xC7\xF66t\xDC\xED\xF4Y/̶\x82\xBD\xF5\xD8`\xA4\xB2y\xBA!%& \xC9\xE3p\xAB\xB42\xE6;\x84m\xE6ZQ\x97\xAFWbҮi\x8F\xA87hcƩ\x86mN
c]\xDD\x93z\xB1f\xA9\xCD{\x8CzU\xFB\xADO\xF7\xDDY
\xF2\xFC\xF5杆\x98\xEFZ\x97\xAE|\x9ECt\xA9\xB2\x8A+\xD9\xCF\xEC\xDA6\xB7m\xDE\x93 \x98\xFE\xDB\xF9\xF7nt^\xAFy\xFF\x8Bv\x8F\x81\xFA\x80
+\xA0Q\xC7<ҕ\xD5澿j\xD3~ k\xDC\xF3\x80\x96Z\xD1\xE55\xEEy at q\xADk,6N\xFB\xF8B\xAC\xF7T*\xCE|\xF9Q\xC7/\x81\xF6˕\xD7v\xDFѥ\xA3\xE3\xFA'\xE3\xE6\xA9\xD7
\xBC\xF7\xD3҅?\x87\xEF\x9A\xC7\xD2\xED쨩ES\xDDu\xD1\xD8N\xA0\xF5\xFC?m\xCE\xDCg\xB8_\xBE\xF6\x99\xA2\xF2
\xDAn\x8B\xB0W\xF7
\xB2\xEA\xBA\xFA\x99Ջ\xDBh\x97c\xF9SX\xBE\x99}n94m\xD3%\x8E\xB7zQ\xDF.\xF7\xBD9\xCF \xD1:;\xFC\xEC\xE7!s4\x8D\xA5y\x9D\xD3\\x92\xB8\xF9\xA7\xA5k\xF7Df\x9E\x9E\xAE0\xC6\xDD*\x9C\xB7\xE5Чg\xF2\xB1
)G\x9E>H\x89IBBBBB\xF28Lr\xE4F5 ;\xCF9\xBB\x9B\xDD˿\xE3\xEA\xAF!\xECF\xC7CUۤY֟\xFE=\xF6p\x93b\x81\x91ZS\xDE8]{&z\xEA\xC3\xED͟\xC6_\x9F\xB5\xF4\xC5\xD7g\x8FW︓\xBB\xA5\xCFj\x9A\xF1(\xC2P\x91\xF1\xC5-\xC7Us\x8C\x86
\xA01q<\xF3\x92\xD1J\x8E\xE3,\x83A~\xDAɉ\xA8\xC0\xCCW?\xCBp\xE5\xE8k\xEE\xB7\xF0L<\xC7[
\xE6\xFBK\xEC\xF1pû?\xAD\xF7\xBD{<\xD2\xF0\xEEO\xEB}\x89=\xFE\xBEZ\x9CDǜe\xEB\xDEtz\x96\x8A[9s
+Xo\xA2\xB9\xB4e\x9B\xA4\xD7g:w\xE9{\xC1\xC1VT\x80\xB8\xF4\xF3\xD9^\xDEkt\xF6?\xE7\xA9#\xB8\xB8{\xE1\xB8O\xFE\xF9\xDE\xC2\xE7\xD0|\xBA
\x8E\xFET\x80\xFA\xFC\xFF\x95
\x99\xE3(\xD8\xC8g\xA0Ru*\x9D\x8E\xDA3G\xF1\xF1\xB5\xBE
+\xF7/\xC7\xCF~u\xD9\xDE\xCB\xCBNU\xEFhُU[^%\xF5\xE5C!%& \xC9\xE3A\x9D\xBA\xC0&\xCD\xF6\x8F\xAD]\x95A\xF7o\x9A.\xCCN\xD9G\xD1W~\xD7~\x96n\xD8\xDF\xE7Z3 \xA0K\xA5\xBA\xAF\xD2h\xB6\xA6i =\xF69\x8B\x8Fz\x97\xB6\xEE\x94\xDEL8\xDF\xB4\xD5b,\x80\xAE\xBB\x9F\xFE\xBD\xFA\xEE"\xEB\xADz\xF4e\x9B\x99
+\x8C\xBF\xBD8\xC09\x9A$\xD4\xD4|\xFBK\xE5x\xD3O\x87\xB80\xA0\xE3\xCCt\xAB\x8ETe\xD0q[9\xF3\xB5\xD9F\xFDB\x93\xE8\x94^\x95mFC\xA5\x8E\xD17\xBA\xBAT\x8C\xA1\x8Fg0\x9EEŘ\xF1\xC6AW\x97JU\xE7\x94.\xDBvF\xAD\xF0SDž\xF9x+f//\xC7\xD1,K#\x93\x96\x85,6\xEF\x8BGytܿ/\xEF\xE8i\x95\xEE\xB8\xDFۛ\xF3\xDE\xF5K\xFD6\xCC \xBFz\xAE\xF6\xDD\xEA\xDDLg\xE3\xD3\xDF\xEE\x87\xCF\xD2r)\xF7N\xC5nt\xDF{y\xB4\x91\xB8?\xEB\xA5\xE6\x8F\xCF\xEEr\xEFї]
+\xDF}p\xEC\xAD#\x9F<3\xCA\x9EfH\x89IBBBBB\xF2\xF8ܺz[]G\xD5\xC7Q\x97>\xDC\xFE\x82\x89Z|\x8D5
+\x8Dtfx\x8A\x8E
\xA3\xE7\xD7\xD4W\xE7Ķ\xF5\xA95\xE2\xF7k
\x98>lB\x9DRɖd\x89\xDDJ\xFB\xD5^\xCA1\xE3\xDF\xDB:\x97\xC1\xECӵ\xF7\xBF\xD9-\x99\xB6\xF4\xC5\xE7\xFA-G\x99ĭ\xD2KI\xFF| 4\x95\xDE|nh\xD7OU\x9Cx\xD6oXPo\x89\xC4\xFB2\xAA\x8E\xB0\xFE\xB6\xDD \xA0\xCBy\xE3\xE0\xCD7\xB4[\xAC\xD1\xD4\xDCp\xF1\xEC\xB9\xF29Fwϝ\xF5\xEF\xD45\xB5\x96v*\xCCNX:\x8F\xFDꏝ\xF9/\xBFU\xBE\xEEeK6 \x80:\xC7\xF0\x92\xA5 \xBA\\xBA \xD1\xE5Z\xAB] @ܪݵ\xA3P\x9E\xDB\xF3I`\xF8\xFA\xDEt\xEFM\xB5I\xE5\xDA\xDC5\xB17\x9D̙\xAA\xDD\xE0\xA1P\xA7\x86^\x92ꍟл\xFDG\xC6\xF7\xBD\x97\xCDI\xF54
+\xC8L"!!!!!yLn\xFD\
s\xA4\xD9o\x83\xF3\xDCI\xAC\x9C\xDB})6\xEE\x85Ic \xE80'0
z\xFAƸI\xBD\xA1گ_?$\xD3\xFF\xDBTm\xBD9\xBB:\xAA\xAF\xEC\xF9\xB1u\x96\xBBM\xE0\xEC\xFEfpM}\xF9]\y\xB1锤^\x8F\xE6\xA3$AT\xE7W\xEC\xF9\xE9\xC1\xFA\xAD\xCE\xE6\x8D\xD77\xA6^l\e\xFF\xE6\x83\xDB\xFCUD@\x9Dd\xC5ٚ\xF0l\xF5\xA5V\xF6h\xC75u \x80\xAEyH\xD2\xEB\xB7%\xA26Lܞ\xD9\xE3em<\xBF\xD4o\xBB\xFB\x87'\xBF\xFBn\xC2ǧ\xAF\xBD7\x8F\xDD\xD1\xDE:;\xF8\x88\xFB\xA4"\xD7i\xAF.K\xFA%\x92o:q\xE1\xAE#\xC1\xE6\xBA\xC0\xFD\xF2\x8D+\xCE\xC5䇳 t\\xFD&\xB3\x96
+\x80j:ê\xB8\xBEQ\xF9\x9C\xFC\xF3؋\xD1's\xD4(\xDF\xFB\xCA\xCFނ\xA1~J\x91\xE0\xFD՛\xEE\xEE\xFBy{\x94\xB6 4\xF5\xE57ޜ4ό\xB3\xEE\xA3V\xA8O7\xA4\xC4$!!!!!yt\xBA\xDA/
\xA9\xCC\xFC\xA5\xCB/t\xC1\xDCI:\x80\xCE\xDC\xD5sU\xF9R\xDDG\xA3Fu\xFD\x9Ch\xD7\xF1f\xB7\xF7\xE6>\xA7!\xDDڛ\xEF\xD6\xFDqG\xF4Kc\xC1\xE5v\x8C\x9F\xB0~\xC3|\x9BIZڹ;\x9Boe쬩\xB4\x98\xB2+\x883\xBC\xAA՚ă\xE6\x9B
+9\xA9\xE2\xCB\xF4 a*`>\x9F\xF4\xCF*\xEE/\xFA\xCF\xEEW\xAB4h\x8E(y\xA1_\xA4u4\x9C\xFEx\xE37/\xEF\xF8\xCCٌ\xAE%Y]] T\xF6\\xFE\xEAAGس\xDF;u9\xD2`
ʷo\x9E\xE5\xE6\xDB\xB7\xF1\xEE\xDB\xCAE᭄>@u\xD6\xA7\xEE\xF3o> \xD0_\xBFk\xF1"C ;~lb\x83\x907\\xFEa\xEF\xBC\xE4l\xFAN\xF4\x8Af9\xB4J\xCE\x88|%\xF3\xE2[\xFBJ\xBFaPWS*\xEB\xE7ąs'\xF2\xC1\xF14\xCD͎[\xE5\x9F9.<\xE8\x9Dq\xE6c/=-6\x91h\x81\x94\x98$$$$$$\x8FJ\xFBw\xB1eL\xF6\xDF\xFE>\xF3\xB9~Y\xA7\xEB\xECn\xF1\xA8\xDD\xFA\xF9Ȓ;\xA0\xEB\xFB9\xCC
\xD8B\xDDv\xF3fґv\xE7E\x93#6\x98L\x9D\xA4u\xACzG/\xAB\xECܭ\xF7.\x9A4\x9C\xB8
>\x89\xF6\x82L\xB1\xBE\xFB\xCCO\xF5;%\xCFqv\xBDGl\xFC\xE27\x8F\xD96}b\xACM \xD50\xAD\xFE]\xF7\xF3K\xDA*\x93\xB5
\xA3\xD2pqcX\xC0\xD9AM\xD6
+\xBF\x9B}\x98\xBB\xD3j
[\xF7\xD6\xD5\xE3\xBBW\xC7^Xu2\x9A
+h4\xAC\xEBN`
+\xB9\\xADӜ\xBC\z\xD9\xFB>\xF4Y㨗\xD2\xDC\xD6\xEEh\xF1\xFBXp\xEA\xFA+\xEA\xA6^\xF0\xEEa߬\xFA\xF8䙜EZ\xBB`.\xDBrzC\xA0z\xE7¤\xEA\xA2&sӵ\xFE\xE3w\xCE|\xF2֖\xBDū\x92Ζ\xF2\xE7<\xCE\xC4\xD3
+\xC5b\xB6\xFBH\x87A\xF9\x93 tww\xBA\xBB\xBB\xBB\xBB\xBB{\xB65\xF6P\xFA\xF6\xA1\x8Bҳ\xAF\xBB\xBB\xBB7|wwww׃\xF0\x80\xE8\xEE"\x82x\xD0Etu\xA9\xEE\xB7H\xFF\xA4U$$$$$Oĵk\x97'\x8C\xA3P\xBA
*
P(
+\x85\xA2\xA3\xA3C\xA1\x8C\xF4\x9A\xC9\x87=\xD6E`̓p\xD3t\xB6K\xE5:&\xDA\xE4\xC3i\xBEy\xEB\xBE\xFB\xB9 #.\xA4\xF2\xE7\x92
4\xFFv\x93
+\x8C
m\xD2O\xA0\xE3R\xFC\xFBE\xAB\xE2\xFD\xC7\x98U\x93 *k[|\xC0\x97.NZ1_\xEDl
H\xAD|q\x83\xF7,mQ]\xFEl\xE7\xFF\xE8\xC7\xF2 ʶ.\xBAޟ\x98\xBER&*\xBF\xCF~\xD1\xDC\xE8\xCF7\xD7\xF4\xDEc\x9F;\xD1d\xB6\xCE*\x95J\xA5\x8C\xA1B\x87\xAA\xA3\xA3C\xA1\x8C\xE9\xA9\xC7
+\x85\xA2\xA3\xFEC\xA1`\x8C\xBAVwSz\x8E:
+
+0pϟ\xA6\xDD#
%%& \xC9_\x98\x89\xC4\x8C\xF8\xE9_a\xEB\xFF
i \x8B\xFE\xD3&\xFC/\xF1\xB4IL\xB2\xA1\xFC\xBFB.\x95S\x8D\xD9̞r\x91K\xA5Tc\xE6\xF0\xA5D(\xE4\xED\x83\xFCW!\x89
+\xAD8\x8F:o\xDC_BIP\xE9
+\x8E\x90\xCB\xDB
+\xFE\xE3٣\x90\x88\xD4k0&\x99\x9B\xEA\\xA5\x94J\x86flm]\xAE\xFE!\xB2ڜ\xD4S/o
+\xE1<䒔\xA2\xCA:s;\xAB\xFF\xE0\x85J\xB9\xBC\x9D\xC16\xA0
+\xB9\x82\xC64\xA0?\xE4\xB6W\xCA%
+\xED,\x8E\x89\xC1\xBFǼ\xA7
+RZ\x91\x90<r\x8D\xF2Ѡ,\xD8\x95+i\xE5YI^%0W\xF9\xA7:\xBC\xDC\xD4x\xE3I\x99\*K\xE4rQ\x88\xA9\xE9Ɠ\xD52\x99T"\x91\x88\xC5bYO\xD2O\x97\xB4J9\x80\x93
+Y\x9B
+\xD4{+S<\xD9 \xAB.,\xC9\xFF\xACQ\x9AȫSvf\x96T\x8B\xE5\x8Aᮕ\xA8.,\xC9\xAC\xEE*.)\xACW\xEE\xB5\xB6ܘ+~\x92\xF6<.Jq\xAE\xE7\xEA\x9C\xCAK))\xC9\xCC-K\xE5ʡ\xD5@\x91\xE9\xE9\x92V=\xAAU\x89 \xA5B.\x95T\x97f\xA6D\xD9Rh\xDAvɀ\xC3BC\xC3\x95 yI^^aaaaAAAAAaAAa\xA5dhlJI\x9E\xA7mx\xF5\x9F\xAEs\x83Q\xFC\xEAomm\xED\xE5emm
'\xB8R\x91\xB8\xFF\xF2\xA4ߛ\x9Aoh\xE8-\xAF\xAC\xF7\xE7!+\xC8\xC9T\xFAEV\x92\xB8=\xEF\xD1\xD6u
iIZTZ\xD9(- $\xC7X\xC6\xD6\xE7*B-#zO!\xA4\xE9\xA0\xD3e\x959QQ\x9Fl\xB1\xB7\x8E\xCC\xD3R\xA3I'/\xDCvu\xA6h\xA4\xD2\xC2\xF0\xD5;\xC5#\x96\xA60\xC5\xD0xO \xE1熆)5\xEA\x9DJ\xB9\xA4 -j{n\xF5\xD0\xF0b\xCD-\xB7\x95
+\x9F\xE4\xA3֓\xBBeHH \xEA\xB5s\x88\x81եC&*\xBF\xD4\xF6\xB1\x87\xE4_ )1\x87\x81 4k\xFE\xB5\x88\xF8\x9A\xBB \xA5B&\xAA\xAE\xEE,+\xE5r\xB9@\xB3\xE8\x9E\x9DB)\x93J*\xCB
+3w\x86Gejy菌87ҧ\x88\xCBK\xE7\x9A~\xF0\xF7\xD0\xE5˽\xB2\xB8\xBC[I\ccS\x8FЭk-מ\xAES\xBF\x88MV}\xD9Git IDAT\xE0dRM\xC0\xE33!/\xC9=O(J\xFCCٛ_\xD7\xF0\xB2(N\x84\xBA\xAE?[\xAF\xE5\xE2\x94\xFDoB^\x9D\x99\x96'\xDD[\x81ho\xBB[}̙ki\xC8bP(\x8Ag\xDA`e at Hv\xBA\xBA\x9F\xAAo\xD7إ\xF8\xD6\xD95\xFF\xEE\xE4\xD9F\xD7[\xD2W\xEE?\x817\x90\xB247\xB3\xA0\xBAiPڢ\x92\x9C\xF0՞\x9E\x9E\x9E\x9E..\xAB\xA3\xD2\xCA$\xC3\xEA\xD5\xDD\x82\xAC\xDB\xED\xC3
n\x89I\\xE9jijȠQ([[\x8AK\xA6V
I4
\x99M
\xD6\xF5(\xEAkƠ1X\x86\xA6\xE6܀\x94kwͶW4\xB4\x84\x99\xA9/F\x94I\xA1غ\xD8\xDBB{{[\x8A\xE1\xFA/\x93\]]Sʅ\x92k\xE5\xAE\xEE燾\xDA\xE9f\xB3\xED\x85I\xCB՟\x84T,Qhf,A(\x95J\x85\.\x93I%b\xB1H$\xAA\xAE\xAE,)))\xC8\xCD)?DαxɭUU\xDD\xDD\xDDi~6 $\x9FX[\xB2s\x95 \xF2\xC2](\xA6+\x81,K[\x8AKx
\x80\xC2\xED\x8B\xEC\xED\xF7H\xFA\xD2m\xBF\xE1\xEE×\x8F\xE0T\x97Wf;\xA5\xD7\xDF{R\xB2\x84I|P\xD9\xE0\x92%rm\x93\\xF3cyYK\xB0\xEA\xEC\xC9G\xC91SsS\x9Am`^eo
\xF64\x9B\xE6\xF8fX@?\xEEqj\xAF\xBC\x98\x9F$\x9CcmB\xA9T*\x95J\x85b\x88
+\xA3\xD2:\x93\xB2\xB2o\x8F\xB8\xB4\xDEx
w\xBC
\xBD\xF1|d\x99\x96\xB2\xDDӖ\xC204w?\xD4<\xC5P\xAF\xEFBer\xB9\\xAEPH\xCBR\x92\x90\xF0.W\xA9y\xE9\x9AU\xE4\xEB\x89\xDD2-/
\xF8:s\xFFќ\xCC\xC4\xE3~{\xD4HDi/m\xDC\xD0vD\xD9(\xB9Z'\xBEZ'\xBE\xDAx\xEB\xCECb\xE9\xB8\xF1\xCD'{\xEB;F\x97d\xC7\xE5x\xF7͵\xA3\xACB\xD9\xD1\xF1'\xEEZ\xE2\xEA\xC1\xAFowc\xB0\xCF7?\x9E\xBFt\xF6\xC4\xD1\xCC\xC4\xDD\xE1^s\xAC̾(\xA8h퍸N\xF0\xFEƜK\xA3\x88Ny\xD4]\xEF\xCC--F
ɿ\x84\xFF\x91\xD6;ʚ\xFDn\x80\xFFg\xEF\xFD㚸\xB2\xFF\xFF8\x81L0\xA8`hCт\xFC\x85,ԕ\xA0\xC5j\xFBm\x81\xBAʏZ\xA1\xD8B\xB7\xB0JQ+\xA0\xAEK\xB0>\xAC
+\xAD\xB7\xE2j!\x8AZA5\xB0B
+TAI\x802\xC8\xF7\x8F@?\xDB\xF7\xEE>\xDAy>x<\x98ܹs\xE7\xDE;wfΜ{ι<
\x80\x80\x93QT\xDFN^fU\x91\xA7%
\x80\xE2\xEEI#^`\xFFAΌ( \xE0\xFC\x9D
,\x9Dx×\xE0\x8B\x86\xFC\xABu \x89%\x8Do+\x93L\x9C\xEE|\xBE\xFF\xE3\xCC\xF5\xBD\x9B\x9E\xF2\xD6\xCC;FN\x9EqY\xA6\x84\xEAr\x91Me\xD5O\x80t\x9E\xE7InSX at f|\xCC\xF7\xDFGI\x80\xEAK\x9A8\xAElU6\xC5ݯ\xC5?b
+Ȅ.\xAC@,@*\x89\xC5 \xAF at zk1 \xE45\xB9~\x81\x90\xB8kԅ\xBCt\xC0/[ӂ
\x87T\x920u\x8CLˎL\xA9\x90\xB5\xB646KCd+Eեt\xF8|l\xA3\x99\xCC0ࡍf\xE4v" gz]鐥z\xB0\xFCD\xFD\xBD\xE9\xEAj7\xA18edQ\xB4_\x88\xCF\xD5^;\x93\xBEYe\x8C\xC0&J\xCCOL\xF1\xC8\xF7\xE6%f,k\xCBu2\xF4O)\xFAm \xC6t.\x8FW\xDB\xE7J\xCA&\xA6l͛\x81\xE3t\xAB7\x88T\xC8567?\xAE\xBF\xDFj=S3\x88\xA2(\xEB\xBB{\x93\xA7On\xBF.\x98\xF11I\xB1Y
%)\xF7
\xB2B\x92Rvxٛ\xF6\xF5\x80\xE5\xCAЪ\x8A\xCD\x8B\xC1b1Q\xEC`\xF4izI\xB6\xDD\xE0ێn%\xA8\xADZIS\xFE趾\xF4\xC4[\x9D4\xC7\xF0\x98\xED\xE2l\x9F\xCDs\xAF\xF3\xF2\x8Ex\xF59\x90\xB2V\x90
+R\xAE\x94[\x86\xC0{\xEBG\x8CU\x88\x8AMx\x85\xD2[\x8EL\xF4]n\xB1\xE6x\xAA!\xAC"$\xB3\xC2Œ;V\xEF6kH@\x84e\xBC\xBC\x9B
+\xF3\xF3\xDC
\xB3r\xEB\xE5ˍRV\xB0ayJL at dT\xB2\x93Do\xA9n\x8D\xC6_\xDCs\xC9
+EB3\xA7@~t\xEE\x99H\xD7盀\x96Օ\xDDn\x86
+J\xA5 \x8D\xA6\xD7\xF9H\xD4\xDC,-\xD3G\xA7\xD3
\xEC9 \x93\xFC\xC3\xC8!|\x942\x85-\xF1\x8E\xFD\x93\xC9\xC7S\xDER\xF5ݡ\xED3~\x92$?\xC0 \x98v\xFB$\x99)e\xB3\x8E\xF4\xDAO\xBC\x9E\x8A\xAC\x8F\x96v2
H\xA9Rj\xF4 \xA6 \xA3>1ug\xA3\x85\xF7b\xC5\xFE\xA1\xCC\xA1
+0\xD3|^ԉ\xDA4+\x93 at Nh@'\xD1\xD3R\x99.0\xF2Ӹ\xF4"'\xB3A\xCD\xE6'I\xF3\xFA\x86\xE6/֯\xBEe~\x9F\xE8\xBD`6\xAD\x83\xA6\x8E#\xA44b\xA9[\xDD\xFE\x9D\x97I\xEC\xD5\x8Fۚyw\x8F:v\xF74;\xB7\xFA+\xBF \xC3B-v\x94}\xB6t\xC9u\xF5\xCF\xBBN
\x9D9\xAA\xCFJ\xB3\xE8p\xAA\xED\x96-\xA3g\xA0\xB3\xA6\xE0\xBBJ\xF3`]4\x9F*i\x9Bl\xACG#;[\xEBn\xDCd\xAFݡ\xB1$\xD9\xD9\xDC\xD0\xF0\xE0^\xD3\xC3ƶ\x8EnڔY\xF6\xE7\xA9ݴ+\xD3=u\xF6\xFDc\xC0/\xA7\xBD\xF2\xC7[\xD3,쿓\x9A
+\x8E\xA5\xDFy\xFCD\xFA\xA8\xE5ISc'\xD0q\xFEt_C\xB8\xFB\xF2r\xB7\xE86\xCBg\xAE\xF2\xB3\xD0\xD1\xD0\xD9X\xF9\xB3\x8E\xD13ucO8\x9D\xAB9\xA1iءh-\xAA\xEFzg\xB4V\xDC\xFFᰨZ\xD7\xF2E#=Z\xFB\xCDJ\xDB)\xB9G\xEB\x9B~\x92\xE42\xBC!xy<%h\x9E\xAA\xA9^fdƦ\xBC\xC5[(sd\xE8vr\xE9[2\x85\xBC\xB3SI\x83\xF4\xA89\xB9U;\x96s\xE81$\x9BR\xF9\xFF\x81 \xAE\xC6x^]\x99\xE6h\xD4\xC5x\xEC^\xE68A\x9B:S\x97\xC0$~T\xA0\xC3\xF2\x87\xB8\xF8$6&\xBB*Z>\xDFed\xE4-\xF0\xF7\xF7\xF7/\xF17\xA3!Qz+\x88 @\xFEs\xA8_lR^\xC9<}eGk\xD1a^H\x9C`\xA5\xA1`U at G\xB1ò\xF0\x95o\xBA\xB2N\xEDcϡ\xC4\xEA\xC3%\xAF4<Qv\xFA\xB4\xA8\xC4D\xE3\xE9
u
\xBC!u!\xE6\xF0\x97\xA5\x94\xFAr\xCAR4\x94\x9E\xBB~\xDD\xDD\xED\xED͏\xDBڞT\x97\xDCHx=P*\xA5\xE0-\xB2"P&\xDC\xC8;,\xF3w\x9AtJ \xE11\xC2A\x92D\xF5F\xEB\x92\xFE\x89y>\xB6\xED\xF7\xEEf\xC6\xBA\xF1b3\xAA\xE4^ϲ\x86\xD3D\xD7Ku\xD5M{\xD9D\xF1R{}\xD9(\xCB\xF6\xE3m\xF5\xF3rdz V-3rpz\x95\xD7d?\xD4
\x8D0\x9Aɓ6xd\xC4 \x88k\xE9
+\x9A\x89$\xE5J\x92\xA6\xC72\xA6\xB1fZ\xB6x%\xBA\x9B\xCBE\xE7sӓ\xD3\xC1\x99\xC7y\xC1<7y\xAE\xF5+\xCCƊvoq0\xE4Gd\x9C\xD8\xED\xC5d-͝\xA0\xE9\xC9\xE5-\xF2\xFA\x96\xB6{4\x97I*\xF5\xF4\xA0\xA0\xEC˚\xCBa\x82 \xC45\xF3K\x80\xF5&\xB1A\x8A4\xDB\xD7+\xAD\xF0K\x96
+H,lqQ\x8B߲\x92EFNji\x91\xCF\xE7C\x92\x9C\xE5\x92RR\xB1\xD3\xC2ܬ\xDFl\x92\xB1|_I\x85\xF1tc\x93\xC9`\xD0\xE9Dåf\xCE\xC1!I\x99\xE2L~X\x90\x94\xDD\xD0\xF6\xAC\xDE
|!\xE8\xDCxec]\xA3\xF4l\xB6\xC8\xCD̑\xC7$\x89 \xFA\xAD%\x82ڿ{r\x9E\xF3\xA2(J
+v\xF2K
\xED`\x9CԊ\xF78\xF9\xA5\xAB\xBEcc\x89X%_9\xFB\xE5\xF3 \x81S\xC6e!\x87 0yAR\xE9\xFB4\xDA\xE0\x80\x82t\xE2\xB6p\xA5C\xE0\x82Y^֪`ZzEf\xAF\xF0\xB8t\xCF\xD8Z\x9DN*\xBB1Y\xEF9\xE4\xE0u\xC9<QՅ\x95&\x84`0\xC9t#?\x8B?Y\x8E\xD4o\xB4QD2B\xCF\xCC\xC9ޞ! \x98\x96\xB3m-\xBB\xAF\xD4\xC0\xFA\xAD\x85sy4 at V_W\xFB˕Ȅ丝B@)mF\aK\x98\xE3\xF6\x97\xB2\xD2=,\x87\xE7W[\xFD\xEA[\xE6\xF7I\xB2\xB8K\x97
+\xFD^#{\xFA\x96\x9F\xBC\xEAH\xA3+A\xE8]}\x93b\x84\x9En\xEB\xD7֖W?]\xA7\xB96\x8C\xE1ˋ\xAA\xBC\xAFJw,e\x91\xED\xB57\xBE/\xB8;\xD3\xDBk\xE1$ M\xD8~\xBAq\x83\xED\xE4\xCE\xCAK\xDC\xFC\xF2+\xFCޙ3#C\x9B#\xBA\xEE\xF8\xBC\xA7ɮ\xB9\xA1\x8B\xF4\x80\xAB\xCB
]\xD6\xDBE/O\xA5@\xD7\xCF_n\xDB <_`\xEE\x8AͶ\xB6\xB3fLe=\xB8\xB0\xE4#_\xE7\x97\xFF9ߌ \x80.\xDBW\xA7iY\x9B\xBAⳲ\x8B\xDF\xCC\x80.Y[7\xCBb\xF6kӌ\xA7N14F\xD3kΟ\x9E\x9A\xF1\xB17\x9Fm0E\xE8!=\xFD\xC94\x9A\x94\xDD,\xFB7xV3\x88\xB6sq\xB5\xA3C1\x89T\xFAS\xF4\xFA\xFA\xC7Ȍ9\xEA\x87ʌy^bpO\xDE\xD9I\xA2\x80\xA9\xCFi1\xB5\x94ޠ/\xA7\xB1J\xA0\xA3$hQ\x81\xB0&\x82Zv\xFC\xB7\xE5\xF7\xFEx~w\x8BotNaO5`\xD1%x\xB8\xFF\xF0n\xF17n_9*6\xFA\xEE\\xA4\xFA
+At\x80T\xA2&\xDC߯\xCC\xF5\xD2\xB1X\x82\xCC\xF6\x9C\xA8\xBD\xE4
\xC45z\x86\xDE4c \x9D\xF2N <\xA6\x9E\xB11\x80\xB4\xFF\x99A\xA3Y \xA5W.\xC3 ]\x8AHj$E7\xE9 \xA5\x80\x85\xFA-\xAA\xA8\x95\x88y\xF3\xCC \x84)\xD7\xDEt4\xBD\x95\x90<\x94\x9A"1\xD3η0.\xDEi}\x8A\xE0V\x90\xFA-\xF2H\xF2}d\xC2
'\xEB\xA9Ɩ\[\x83\xC1\xE1\xC9\xC4}1\xF8\xE6\x95\xD5\xD7\xF0\xBD7\x80\xCD[+\xB0\xAEV\xA0\xB5\xA6\xBBD\x96\xEC\f\xAD\xE9\xCB·\xE7\xBB,\xB6\\xDC\xD7. \x83\xF7\xED-\xAF0G(\xEA\x8E\xED\xFD\xC4;*
\xDF'n\xDF\xFE\xEC\xD9 \xCBٹ\xA5\xF0%\xEF\xE5:\x92\x94\x93?\xE2\x95M\x87w\xBBh\x9E\xB4!?>\RU\xE2\xCB\x95?\x8A\xE12\x9D \x86\xF6\xBE%q\xF1\xC2K[\x84\xEE\xC3\xBA<\xB7\xA0\xD81,cc##\x8D\x9A\x91u\xA9\xB1 \xD9Y "\xC9\xE0qU\xC7\xC3\xFA\xC5`bq\xC0\xEE\xC5P\xCC+L\xF8YT\xD0bU').\x9D.\xE4\xED<'\xDF\xFACġ\x87\xAA|\xB5\xE7\xE2y~w\xF9| @\xB3@܇[\xFA\xB4U\xCDb\xB3-\x92\xB4 ; \xD2z\x81\xA8d\xD3W~\x95\x89\xB9s\xFD|\xEE\x92d\xEBٔ\xAF\xC4\xE0\xF1y\x92\xA3\x87\xD2\xBD\xE0קe:\xC9\xE5 \x82\xE8\xFB\xD6)\xDA3۩l2\x8F\xAB)\xE9\x96\xF6\xF6\xEA\xAD\xA5B3\xE7\xE0I\x8B\xAF
\xF3\xD8FZ\xFC\xD4\xE3`\xA7\xD4Ur\xDF\xF1ɟ\xB9'>\x8DG\xE63 Rvu\x83\x89\xB3\xB7ȍ+\x89\xB27\x9D\xE0H'R\xFD\xCC\xFCґTP\xB0\xD8t\xAC\x8C
+\xE8cy\xB5\xD8\xF9\xA6\xF5\xFA\xA6\xA9\x96
+7:\xA6\x83\x9F"\xCF\xF7
T'\x82\xCEd\xAFd\xEB\xE5\xC3b~R\xA2Z\x80'\xEB\xB2X\xE6\xEBx\xFE\x89\xC9;\xFD
\xEDk\xE8\xD5\xB9\xD1\xDE\xC1\xD32\xB7\xB8s\xFB*C6培ڭ\xA3\xE8\xE8\xE8 \xDD\xDD\xDD at w\xB7\xCE\xFC7\45{
+\x97X\xADK\x88Ϋw\xB74\x84Jro\xBD/B\x92d\xE1\xF0\xB6\xB0 \xF6\xF3\xDB\xB3u\xF3Jǡ׆`۹{ڽ\xD4\xCC\xCF\xEArww\xE1\x92\xDC丽\x87\xFC|\xBE\x80f\xB0x\xD6\xDEK\xD5ե@C\xEAν\xB7\xE4\xE8\xF4\xD0ɰX\xE4
+گuU\xFAu\xB7\xCC\x93\xFEo||x\xFA\xDCO\xFC\x87\xEF
\xBA\xFA\x93{\xDA~\xA9i7\xB22\xEBS
+Ve\x85
Įs\xBE\xF3
`<\xC7\x82\xE8\x8F\xEF^<v
\xF37l\xDF\xA4\xDE\xD3\xA8bE\xEAq]|\xD1\xFF\xC6\xEE*\xDF\xEF\xF7\xB5{\xCA
+]\x8Dm@9\xF1۾9|@\xC0\x91\xEF.\xB9<u\xD3I\xBC\xAD:]\xC7\xCDX\xCF\xCBS\x93\xE7M#~\xB9^h;\xD7 {Κw\xE6k\xC0$ƫkve\xC6\xCC3\x9F\xA6!\xCEzm,ݴ\xE6\xB3o/'\xAF\xD7\x80\x9A\xD4\xD2ڿ\xCCS\xBBɮq\\xF5\xEC\x9Co\xE8\xCEZ\xEDۯ\x94\xED\xB8\xF9ᢀ\xA8܆\xD5܁\xD2&\xE8\xD5~\xFFm\x95\x9E>:s֝\x88\xBE\x88\xC95\xD7+\xCBBov\xDCk{#>k5w2 t\xF0昏\xD6\xFF\x93\xF4i\xA4\x863_\xA4\xEC\xE7[\xE8\xA0\xFB\xC1\x9D+\xDF\xFA\xE7\x8BG\xFBV \xE8\x98q
+\xF5?\xFFRuK>\x93?\xCFr49\x9EbbP"\xE6\xA8\xD4\II\xAB
\x9A\xC5\xF0\xBE\xCE\xD0szɂ3/\xEE\xEE\xA0 \xADe;\x97\xF2b%\xF0\x89\x8B\xFCx\xFD˙\xE6\xBCf\xFF\x88;\xEB
\xBC芢\xC8 9\xA0*\xBB \xF0,8
L\xB9\xC8h4\x9A\xE0\xBDd\xC11\xD0e4\xF3
\xC8)\\xE6\xBD6\xC7P
\xBAGy\x9D<\xC79\x86ݪ\xA7\xD1 \xB55\x97\xB2S:0;*\xAB>[ܹ\xD4\xC5nxu\x98֎<\xF8ߓ\xED6
\xACvu|?\x99\xEE\x94V\xEAd߷\x83\xE3y\xCBU\xB5\xD9$\xF40\x81 \xA9>;`\x88\x80\xF0P\x92ߌ\x8D C\xCEb\x95\xA9!\xD8ނ\xDC\xAC٣\xF8J\x93\x8Fj$\x80\x85\x81
\xD0\xC30\x8F\xE2GT\xD5s\x89\x87\xDF\xECvp0yRۻ\x9B<\xB8\x9D
\x9B
\xCB\xF7O\xF4XЦk8XEJN\xC7\xF2\x93$*\xA1\xBF\xB60\x9Fi\xFD\xE3\xDAz\xB97\xC2+eB\xF7\xE1Z
)\x8C\xE7-p
\xA1G\x80\xC6;\x8F\x84\xE7F\xD9\xDBX\x98Mc2\xE8YCQ\x94\x99\xD3{\xC9\xCB\xF3\x83\xA47E\xF5\xF1`\x89 at 2O]\xB6\xFC\xAA\xB7\xDF\xCC\xDA
+\xF6\x96\xAE\xF1\xFDE\xD8\xF9
+{}\xD5GT\xBAhmI\xCCϷvF]\x88" R\x9EX,1\xA2\xC2?.#\xC9R\xC694\xE3N\xB2\x83Y\xB0 E\x92\xEDk\xFD\xA9\x90ɕ`8\xBC\x97\xE2c\xE4\xEB\xDF\xB9xDK\x83\x86C\x81!\xA2Z_;C ^\x87O\xB2\x96T8\x98\x8D5.\xA5\xB0\xFCTT\xA62l\xFC\xE0\x93X%m\xBC$0q^^/\xB0`IkDb~\x8A4\xFF\xCD\xE2:\x981"rkw\xBBrF/\x8Flm%
+5<\xD3e\x92t\xBFtdT)\xBDFT\xE5
+к\xDF\xF1\xCD\xF9\x97\xF3\x8FoB\xA0:'\xD4!\xB0>%#\xDA/N*\xAA\x89
E\xA5(X\x82\xDC\xD56\xEA\x82\xE3\xD1XU\x90\xB4\xDD\xD9\xC9<X\x90X\x90\xB4XU\xBF֢doD\xF5
\xD5%\x9B\xAFdfޟ:U\xAF\xB3&!Y\xC4\xF3 q\x99\xDA\xF9\xF8\xF1̗V\x88\x98u9\xA1悄\x90I\xA4\xCB\xC0]R\x9A\xF6\xA9qoٍ\xDC$\xBD{'+@\x90\x94\xE5\xE5j?,KR\x9C#\xDCs\xEE\xF7U\xEE\x9B+,7
+^\xE0i\xB4\x97\xF2a|l\x82\xB7\xA8`\x89\xA1:\x8A\x9C\xC2\xEF\xECre\x8Ci\xE8\xA9nؐ\x8B\xA5ɯ\xBFe~gXy}U\xEC\xF5\xD5\xE0\xB4\xB7\xB04\x9Ek\xA5\xFE-\xAD\xF9\xE7\xDBk>\x8C8U\xB7v\xFB\xE1\xC5O\xDFށ\x94\x9B\xA1\x83
G\xE4\x83ӟZ\xA6\xC2y\xFB\xA2\xCD\xE1;\x93\xD9\xFA\x83n
+}\xA0[\xAE\xF7\xCCLb\xFA\xBE\x94\xC8\xE2\xABV\x92\x80\xAE\xC66 OX\xAE\xA7\xAEG\x91\xE5_\xAE\xF3}m\xF6u)ω\x9F\xEB\xF6\x97\xB5k\xAE\xCD1@\x95\xE8\xA3\xEF\xB0.X\xF5p\xECS\x8F\xA0\xA7\xB98Sܽ\xCEs\xE1\xA0 bb\xC6|\xB7\xC3\xDB˶]\x88\x90\x86.@0\xE6.\x9D[9\xF8I\xAC;'|\xEF\xEAu_])\xDE1\xE8\xEA\xE6\xE1H(ה/ L\x9B\x95\xAB\xCDi:Je\xB7\xD9\xEBk\xD6zn\xCA?\xF4*ڗ\xBCy\xC8I\xBB1\xC8ⳳ\xFE'\xE9\xCB\xE9\xAA^\xEA\x91?\xBCs\xAD\xB1\xD0\xD5\xED\x9A|:6c\xCE\xE7\xDEs\x97l\x8E6\xB3\x98<\xDE\xA0\xA1r\xEF\xA9ct3\xB6\x89\xF5\xB4q\xDD*\xE3\x811G\x83\xEE
\x99\xE6
\xD9\xF7\xE3l\xC0\xEC;\xA1)A\xDCa\xDD%+\xDDh\xE4 K\xCA\xCBm<p\xC7͓\xAB\x97~I\xE2n{a\xA8\xDDl\x93]\xFF\xF4J\xF3\xB4\x9C\xC8I\xA5\xE0;\xBCd=C\xF2\xC3\xD1/)\x9B\x95
\xD1w\xE4
+\xE3y\xB6\xC6
+\xF6Or)\x95\xCD\xC0Ç\xAD\x8F\xBA\x81\xF66H:[
=\xEA\xD0\xDE4Fx\x90\xC9d&\xE3\x87(+\xB7\xC7ґDL \xE87k\xAD,\xBAo\xEC`\xA7zI2
?\x8B\x86sVq\x90\xFD \x95!\xC8\xEA\x9AUB*\xE4C\xE5K 4\xBA1
MMML\xB6F\:0d\xCD3Ĺ٩\xCC\xE9\xFD[\xC1\xE1 \x80\xBA\x97\x9D\xACL\xC4}\xB2\xEEEH\x9BI\xE3E+"\x90
[\xD1\xCD1\xA4\xE0E\xE7݊T\xD7D3\xB4\x98L\x92 \x8FsU\xCEŋ\xFC#էn\xB9_
+\xBC:B\x8B\xC7\xF8',-mH\xD3\xD41 E`\xF3\xB5D\xA6\x96\xB8A\x9E\xDB㇈<\x8D>e\xF0\xF9F\xB3\xA9dCQ\xFA\xE9
+
f\xFF\x84\xBE\xAC\q\xB6\xF0XY2\x99\x8E\xEB\xFF\xE7ɡ\xA3\xABY\x90Wt`}\xF9\x91o
\xDF[z\xEE\x8B\xCB\x96L\xA2Z8\xDBJ\xE2\xD6\x96\xD6뿿I\xA9~+\xB5\x9E=\xED\x9C0\xA8~\xCE\xAClIavTv/\xBCd~\xBF\xFC\xC7t\xCC\xEE}֬4\x8D6\xDB\xC9D\xDD=t3\xBE\xA4\xAA\xC5\xCE\xD2 \xE7\x8C\xFC͖Yf\xA1\xF5\xD23FL:\xE0$\x94
+BeFcȗ Y\xE1g\xC4\xF3\xA80\xBA`Z/\xF7\xBC\xB7\xEF\xB7O\xE3\x8E)>ҍ\xC7;mU\x96\xCA[\x97\x90X"\xF5\xD1;\xE6'\xE9\xC7s\xAD\xE1\xC0z?\xF8\x8B\x96\x9B\xB2`[.\x8E\xCC\xEE\xF5:+\xBC\xA4\xDF'\xFF\x92
+g\x97:\xF3\xDD5sҹ\x91}\x83\xA4\xECV\xB2t_J\xBC\xFD\xB0S\x9A-\xC8+qq
\xE8
\xB2.\xC7!X
Wpb\xC40BR\xF0\xFF\x9E\x96\xBD\xEFo9)\xBBn\x81\xA4$\xFA.\xE6 \x8A\xF6\x9E,j\xEAR\xE2f\xE4\xBC\xE7
\xDE
\xE19\xC0@~l\x82$\xAE\xB07lЕ5\xDF\xCD}\xB1
\xE8 \xC2s\x9F\xDD}U
z\xB14\xFAf\xF4\xA3\xC6{\xCB\xFC\xFEi\xBA\x9F\x8A}y\xB6"\x8E\xE1\x9C-\x97/\xCCX\xB4\x94S\xBA\xF9\x9B\xF8\xBB.\xFF\xD3v\xD0\xE2O\xBE\xDBb\x99i+ʫY1\xE2X\xD7\xBE\xC59 \xD8~\xAAε\x85\xC6)Pt\xA8\xB7;\xE0\xFC\xEE\xE6U3 `\xC9\xFB\xDBSq\xAF}ޜ5\xF3\x84\xA7\xCA\xFF\xE1\xAB\xF7\xF5\xC7\xDBN
\xEF\x8F[\xAE/{p\xB5\x9Ci\x8B"\xAF'n_\xEB\xEEeb\xCBG\xAAz\xEA\xCFx\xD2\xD8\xA0\xB3<-\xA7yɆ%/0_\xF1\xBE\xD5
\xD1\xC3
\xA7k4P\x92\xEF\xBC\xDE\x84\xBDi4
9M\x87
:\xF9s^ꉚ{7/^=\xBD\xFF@#K\x97+ؼF\xFD\xA96$\xD6\xFB\x9D\xAF^\x8B\xB3\xBC\xF6\x8D\xCATw\x96\xABohWGS'\x89\xB2{9\xDB\xD7\xEDX6\xFC
=v j\xF4\xC6+\x86\xED\xD8L\xD9b\xFE\xB6P
\xE5\xA3#\xAB>\xE02{\xF6\xECٳݒ%\xF9\x99'+\x86:HV\xFF+>]\x90\x91\xE0b\xA6\xCBT<)\xAER\xED\xE9 \xD8\xEE[\xF8\xE9\x8F'tBex
\xEB\]\xE6>\x88\x8D\xBD-\xBF\xF7}\xE6\xF7\x8D\xF2{\xB1\xB1\xB8\xBAx\xBA\xBB
+\xA8$\x99\xAF
\xCA̰\xD5ioo\xEFn\xEF\xEE \xEB\xEEnooo\x87eF\xE6\xA1Wԏs%\x80\xE2-,Av\xD9դ\xE4\xEE\xF7\xF9AϜ\xE5 \xF1\xB9ۭ ʿv\xE2%\x95\xA8\xF7خ\x8CF\xEC\xF5&\xCD̊ʘ\x95VQ \x90`\xC3\xD8Y7\x82C!KR\x96nb\xF2I=IV\x9Entqq\xF1\xF0\xE0\x8Bʊo\xCDXSr\xAB\xF8V\xCD\xA3\xA4\x8C\xBCz\xB9Ў M@\xC6߶\xF8\xBD\xB7e\xCB{~\xA6\xDF|ڥ}>\xAC\xC6\xA3\xCD\0\xB9\xFE\xF8\xF7\xFD \xB2\xA2\xB4`\x89 \xE0Oꗺ\xA283ѯ\xA9\xDF\xE8
+\xA59\xA1
\xB3\xB5\xB4\xB4\xB4hb\x88/\x9F+
w\xCC\xB2<O\xC4s\xE5\xA9\xFBPQyR\x90\xD1V\xA05?u\xCFF\x8F\x8D\xDF\x8BJ\xE2ڐʎ{u\xF7\xBB\xE0~\xA3FB_|
\x9A\xA9\x8Bt\x99\xCD2\x91$x\xF9R\xAC2\xB9\xF4\x8F\xBFxl\xDC\xF8^\xA0\xE1>7ntِ\xD4L\xEBx\xF2w.uF^E\xBD\\xA9\xEC\xEDUʥ-U%">Z\xA5#œ\xA1\xD1 I\xF78\x9B\xA8\x82n/\xF4
*4\xE9
+#\x95G\xBC\xC3o\xB0̖g\xB3Eo\xBC1[\x95\xC82\xDF\xF5p\xCC\xF2ZKrE8\x98k\x8C>\xA6}\x9A\xB4"NnÚ}\xAC\xEC\xD7\xD5j\xCA\xDA\xE9\xC2[\x97\x90XPdϔw\x8E\xC7\xDCP\x91\xB3\xD3-\"(\xFC|
+ \x96\xAE\xBE\x8BMȪsV\x9A\xB9I|R\xBE
\xE6\xFA\xD6_\x92\x80r$Gk\xAB)_\xA2\xA9\xC8\xCF\ \xFF̠\x91\xF5\xCD \xD0)\x98
\xF7 \xA1\xB2Q'\xF9\xE5\xF6E\xF8\x92K\xEF=\xB1\xF4\x88\x80\x97\x98\xBE\xDB\xD7ՂD\xC4EGEGEEEGE\xC7G\x807\xF4,\x88\xBFI\xCD\xC9\xC9\xC9\xC99\x96-v\xA2\xD1~\xB1~\xC3[\xE6w\x8F\xB4\xF2\xC4\xBE\x87b~\xD84DX\xD4嬹\xFCC\xCA7\xF1GN
\xEF3dT\xD3q7\xF3\xFC\x86\xBDA#˗ :\x81m\xA7\x8A+\xAF\xBD
+\x88\xCE_\xE6\xD3g+3dy\xA1\xBE5
\x95\xFDw\xFD\xE4\xE5a\xBB\xAE\xB6\xFFtj|."W\xF7\xDBqL\xA4n\x94˚\xCB/\xB6\xBC\xB9\xE2\xE5g\xB7\x8Dl\xBFyl\xD3\xDB\xB7
x\xC7I\x95\xA0\xF7\xC2\xEB\xF8\xEA\x9B\xFB\xC0/\xF9\xAF?\xE9//¡;͚G\x93Qp\xEDNӐ\xF2 at 0
\x8A~\x93\xFD\xCD7\xEF}Y\xF9\xA0\xE2\xE2\x89V\xA7w\xF6\x9E\xBEP\xEE%p\xEE*\xA9\xD5\xF8\x9Ei{ܩ\xA1Sl\xBB\xF7>\xF8S\xBFtH\xFE\xF2\xB5\x97\xDE"ϭ)\xA2\xBF\xF9\xAA\xE07\xD6\xFE\xD4\xF3\xC3\xC6\xE7\x98% =
\xBF\
=\x9E\xFA\xDD/\xE7oV4S\xB7~c(-\xE6h\xB4
Xd\xEC\x94X\x90
\xF6\xA21n
]+\x88\xF2E\x81\x92t":@\xFD\x85\xDF\xF6s\xBD\xFF\xA6\xA5@3\x91\x85;\xF3\xC0Ol\xF4U͂\xCA
+O\x88\xF9
4 MEL\xFC\xDB\xC6;i\xAE\xE8\xCCg\xF3\x91\xAF\xC5b*\xF0X\xFE& \xEBq*\xEA.
8q\xC3d\xE6T
\xE8\x86*\xB9\xBB\xFFy\xD2]\x9D\xB2\xE7\x86\xEDz
4]H\xD2E\x82\xCC,\x9B)\x87\x81\x96f\xD4~@\xA4\xACIFc\xF7M\x87\xB1F`١K\x8E\xB3\xD3c\x91$yE]\xC3f\x91?\xCB\xC2\x{2393545}\xB2x \xFC\xB8
+i\x97V:\x9B\xF1\xE1CC\xBD=t\x81\xF4dAF\x95I\xD5a\x96[vJ^\xAC-j\x9D\xD2OD\xA6G9\xAA\xEC\xF6\xA4\xE0o\x89\x894c\xAC\xEC\x94\x88;\x91\xEF:\xF4<v\xE8\xE2\xA5\xF9\x81`\xF7\xFA\x925)N\xC1\x82\x89ZgR$|o]:/\xAFq~_\xD7U3s\xF0\x8EHɭ\xF8\xC2\x8F\xAF\xACw\xF28q"\xC9\xEEvc\xDF eYQ\xEBґQ\xA1\xF6\xFF\xA8\x8B\xB6\xF1FD\x9E\xBB)r\x8Cw#D\x9FE\xCD\xC4\xCFzq\xAC\x9By\xACRվ K&\xE8
\x97\xC8Af\xA3egc\xEB"j\xBCd-\xB6Gj7\xB9;\x94\xA7\xE4ȥ\x8F\xDB\xE68\xB8\xEB\x95MM?
+\xFBء\xB3
+\xFD3۲\xF2XI\x9C\xA4ĥ\xFFc\x9D\xCE4\xB4\xB4w\xE6\xBBcD=
\xF0Eʥ\xF9\xFDs\xBE\x86n\xBD\xBF\xBE\xF1 \x83\xCE`\xE0\xF6?c
\xFA\xDCi$
\x9FU\x9D9c\xA6\x94\xCBr\x929\xF0U\xA3lF\xF3 \x89VV\xE4+
\xAA?gr\xC3\xF2\xA5\xBC\x81ϨZT\xE9>\xA6\x87\xFB\xA8\x90Nnw\xF6\xC1'\xB7J\xEA\xAA
+\xEA?T\xD6~PSV\xD4\xF2u\xB1\x92̊\xCB#y\xC5\xF4\xE7\x925
ۻ,0\x81\x92\xD1\xEF\xF5+×+\xEA\xF27\x98/\xF1녞\xE3yl\xBB\xB0\xEC\xDE\xFA2\xB9\x9E\xBB\xB9\xA8~\x9DѦ ]b\xDDX߫\xBC\x9C$ \xC3V\x87\x96\xB7\xEFܚ2E@\\xE8\\xA0
\xD23\xE3\xB8X\xBF\xE9-\xF3\xBB\xA6\xEBAAj\xC8\xF6\xCFOo?Y\xED:\x92\xF1\xA9\xAE\xE5\xFA3\xA9\xB7\xDFx+\xC0\xE9\xE6\x89AZL]\x965\x8E\xE7_\xFC`\xF5\+\x96.\x81
\xB2K!k\xBCWo\xC0\x9D\xA3\xF2\xDD\xEE t@\xD7\xF6\x83\xEB\xE7?\x9C\xBBb3D\xE9;VL\x80\x82k\x92_,^\xA1ID__\x87\xBAĂ\xFA\xFBO\xB8\x96\x93\xEF\xFF\x98.\x84s\x8A\xC5 \xAC9\xB6q?\x8E\xFE\xBE\xA9\x95ø\xBB
p^4Ƕ}\xA5\xC5\xC69\xEB\xB7\xED]kB\xEB~RwMT>G\x98\xBCY-ﶖ\x9F_/\xAF\xBD\xF5\xAFo\xB20GJa\xB2\xAD\xDA\xC9\xC0\xF1}\xAF;>\x9E\x8Ac\x9FV\xAA\x95\x94\x86\xCBR\xCFL\xD4\x93]\xE3.q\xE3 \xE1\xFC\x9B\x8B^eO\xE9W\xCA;\xE9\xDE \xBB6>\x98\xBD\xA9\xE0q7ㅗm8/N \xD3_\xA8T\xAD\xC9\xD3M\xBFI=\xFB, m\xE5\xFB\xE7\xAC\xC0G\xE7\xF5\x87^\xE8\xAC\xFC\xF6`\xEB\xC1\xC2\xDC͓\x80r\x83\xBB\xA79\x91s\xEBbVZ
uJ\xB4zΌ\xF1\x94 (·ro\xAC<\xBF\x91\xCFk\xFEl\x89\xDFܣK\xB6d|
\xBAƐ\x92\x8C~#\xA8\x8E
\xF2Q\xB1I\xE9~\x8B\xED\x98@\xAB(K]\xD0\xC1\xBD\xBB\xDE\xC1\x86\x98R\xD8\xE8먒\x83\x9A\x933\xCFm\xB5\x98
\xE9'?\xBA*?\x88
+\x90\xAD\xD5\xE9Y\xF9\x89\xF9y'x _\xE2G\x80gÐW)w?\xC3\xF6\xAC\x9F.\xC0S\xB0z\xE94Z\x8D\x8D$\xC0P\xBF
h\xA0]2Y \xE8\xEAv\xC9YWw\xB7nWW\xD7@ \xA0\xE9x\xD876\xC9\xDFɆ\xE5\xCD\xE3\xF7\xD2I\x80\xE8\xC2\xDE\xC8>ŌKh.\xCFč\x96\xF0[4\xAD\xC4LW66\xF2U\xF2\xA5\xAC\xEE\xD2s\xE7t\x9F\xA4ƴ 6 XxC|\xB1\xB8\xC1q\xB1)\xA9h\xAD\xBAu\x875\xDBє\xD6
9\xB2\xE2b\xDE\xDD\xE0\xE2H\x87\xE2$\x88\xC8Ȝ\xF2\xA5\x93Yp\x95R\xD8\xD7 ]C\xED]\x98\xAF\xAC\xDCL6f\xE4\x85:Z\xB4\xFDrC\xB8U\xB4\xE9r\x9A\xCA7\xBFCQ\xA7p}\x8F\xA4\]\xBE\xCC!\x99\x92q\xC1\xD7N\xD6Tw\xB7\xECJ\xDA\xC4H*lT\xC7)\xDB\xEE\xA1\xBE\xAEl F\xBFH\xC0/\x91\x9E\xA1\x89\xF7\xF2\xBCpAb}V\x90鰫C*Z\xABn]\xFA:B+F\^\xAD\xD7\xC0\xECᴷsEo;\xBA \xAD\xB5Ɉ.\x8Cpwd֯\xA2<N\xE62+\xD6\xE5
+y\xDAЏ
+Pi\xBC+v\xF5?~\xB4%\x9Dɪ\x91 \xF1\x9Fܓ\xC9x8\xCD\xD1z\>\xAF\xCBɎ\xAB)~1\xA6
+\xE0\xBD\xE7\xB0[\xDCFSCP(Zݽ\xF1\xF5\xA1V\xED\xDB=\xC2|$\xC1\xDD_\x98d\xE2\xE4L;\xEA\x9F\xB3\xDE\xE1U;;\xCB \x87@g\x9B\xD2\xC9\xD6\xCA\xF4\x88\xF5~ \xB9%\xB9I\x9B
+\xDC\x9C\xAD\xF2\xA33>\\xCB\xD5\xF4\xF5aN_ɧ 9'v\xBC\xC1\xA6\xB2\xBAK\x9A;\xA7#\xA2jd \xD352_b\xCA\xD8\xDCO)\xFA\xB7\xD8{\xD6\xDDB\xD6
r\xF6F\nK\x98\xEB\xF8\xAC\xC1|\xF2 IDATD at E\xE5\xA5\xE39\xFB\x89\xC0UH\xDDG\x98\xA4Wԕݮ\xFEI\xF2\x83(>6]R\xF2\xAA|]F\xB0u\x91\xB56\x91 \x82\x90>iF\xF3\xA3\xC6V A\xB39V\x94f\xEDuX\xFF\x8CF\xA1ׄzH\xFB\x95jK\x99.)/Nr+\xAC\xEF\xAD쀋\xCF \xB6\xC4\xF4w3Wyj\x9E\x8E\xA0\xE9*\xDEq\\xAC\xDF\xF4\x96\xF9\xDD\xF2\xF0\x87OW\xBF\xB7\xD7\xCAk\xDF773\xACF
\xB4\xEC%\x9F
\xDE\xF2z\xEA\xF9\x9F\xF6yjh
+\x89\x97?\xBAp&iצ\x95\xBE\xE5y7S~А @\xE8:*u\xA5\xF1\xC2]2}\x97
+>3\xFB1ڋ\xBB\xE9\xA3\xD5[\xDE\xE2
\xE6zm@\xFFPa-\xEF3_\xDA~\xB2\xBA_\x96\x9D\xE1\xBCy\xC3\xC1
\xFA\xAB\xBE\xA8>\x81ɜ5\x80\x810\xD3\xF7\xC4\xA7\x85\xA5\xD5JLf\xBF\xF2槂W5\xF5\xA9\xBA\xB4w\xB1残\xF1\xFA\xC4n\xBA\xF1P'4\xE7\x9D7\xF6\xD29\xB9\x97;\xE0\xBDN\xE7.Y:\xA4\xE1z\xDC\xCD/p\x8F%\x84\xAE)\xDFv\xAA\xA1\xDF#\x9E\x86{w\x{DB7A}{\xF8\xB8 \xE3M\x9C\xDF\xFE\xF1M\xBD\xCE:\xBE\xABt:\xD3\xEC\xCCU\xBB\xB6o\xB9\xCC"`\xEE|\xDB\xEBW\xCB\xD7\xEE9O\xA3d\x81o\xA5\xAD\x93\xD77
Ͻ\xBA9\xAD|!W\xFF왹\x87Ӫ
\xA1_\xC4
\xBB \xCAv4\xB7?\xB9w\xF3Z*w\xDC\xF7+8\xAF\x8C\x9D\
\xB9b\x84KH1q(snh\x92\x8F\x8F\xD8S\xD0'\xCFҐ`\xB3#\xF3\xA5\xB3c\xA2\xBA\xA7\xF6=7y~)\xEB
x<^DR^Z\x80\x8B\xEC\xEC\x9E\xD9n\xE1 \xFC\x90\x82\xFA\xD8\xC5l ah\xB7\xBB\xA8Bΰ\xB1\xF2|\xA9%\xDBw
\xEF\xC2G\xA5b\x9A\x9Dh\x99\x8AN\xE8\x85D\xCC(\xAFl`\xD7?o: \xBA\xE9⠰\xC5y\xC9\xD2\xEC\xEC\xCB\xFE\xBE\xBE\xC3?\x9C\xE9f\xB3x\xC0\x9E \xC7 \xA1tuh\xB1\xE4N7&\xEB\xE8G$\xB2\xA7\xCF47\xC8\xCAv\xCD-\xCC<z\xAEa\xE5f\xFF\xC1գ\xAB-*\x8B\x85\xCE\xE9|\xB5| \x80\xB9$\xD1\xC7\xC9Y
u\x8F_"\xCD7\xA5c\x9A\x85\xC0\xB3\x99F\x98.\xDB\xEA\xBFΉ\xA1\xE5
+ \x91H\xBD\xEC\x98k\xABޔ\xA9\xE4ˑ\xE3iй{K\x8C>\xF0\xF3^\xE6\xD0>\x89;\xFB=\xD6-t\x87\xAA\xA74Rؾ\xC2[>'Un֗\x92ܝ\xA3$!q'\xD6r5,B\x99\xD6n\xFE\xE0\x99h\xC5
+|\x91HA\xA21\x83\xCEq\x8FT\xD6/\xF4\xDBr}ح\xA08\xB6\x91\xE1\x9D >\xD1)\x92\xEC-\x9AH\xB7sU)
+\xF9)><'V\x96@ \x91H\xC9J;\xF7\xC6n\x95\x9A
5\x959\xBE\xAEԵ5i\x8F *\x83\xCE\xF5\xCC\xCE\xF7YZOK۟\x8FK\xC2\xDD{C\x8C۱b \xB6\xECls\x92߿7c\xD5_\xC3\xDC-\xFA[GJ\xEE\xE0\xC73\xD6,\x81\xE7\x93\xF8\xCE(q9؎\xCA\xC6'\x93y\x96\x8D
hfL\x9AJ\xB3>\x89^\x97,?"\xA3V\xEE\xC5!J\xF7 at 2s~Z\xBE\xD4Q\xF8\xE1Zo\xF0I\x87\xABf\x849\x99\x81IY~HJ\xED^\xDF1\xD9y\xC5\xD7\x99\xBB9t\xEAT\xA5y\xF5s\xA4B&W2h2\xC5\xBD\xA5a\xDF;ly\\xA5\xC0\xF0\xE9.\xB2\xEE\xECJs71 \x88Ȩ\x8D\xF2⌨KT\xDCv\xE79H\xC0\x89\xDER q\x9Do7Z\xC5e)KM\x825\xBC\xA7V\xFD\x86q\xBC\xC4\x8D dC\xFEJ\xB3eb :S\xE19\x96\xDAOQ+C<\xEAn\xB2\xB5LR\xF3S\x8D3\x94 h\xBA,I0OKu\xEF\xF1 \xF8j-\xA6]J0\xF5
+\xF2T]wV(\x94`\xFA\x83\xC3\xE0m\xD1(\xF4\xD9\xEB7\xBDe~\xB7L_z\xE6\xFA\xB6\xF1\xE4g朷\xE3ڼa\x89z\x9C\xA5$_\xFB`\x84쀮\x{DF9A}\x81\xB9q]Ϊo\xFA\xCE8qyÓ.b2K\x9F\xC0.Uڜ\xE8\x9A\xCEh\x90\x9Dm\xED\xFA\xE0I\xE1\xD1\xE3Kv]\xD3\x93IJ\xDDv\xEE&\xA1\xB2\xCBds\x97\xAE\xE6.
\xF1\xFCz\x96+\xDEÛ@\xFF\xE5
+\x91G߭Qg\xE1\xBB\xF1\xD7\xDEݫ\xE8\xD2p\xC33pضi\x83\xAB\xC2֪\x95e\xA2\x9A\xF2\xBA\xF7\x9F\xF4\xA1\x9CD\xC8^\xFB⮮\xFE\x971cCr\xE7\xCD\xBAH\xE8N\x99\xC1\xF2\xE6 f\xFD\xA5\xA6\xE5\xAD\xFA\x86\xC5_?⼨j2{\xC1\x96A\x9D9v \xA0\xAF\xFE\xBA\xCE\xE2\xCA\xE5\xFB\x9D\x8BN
\xE7\x82\x98t\xADp<M\xA2Zs\xDD\xC6ڍ_\xBBJzoo/\xB7W\xF52\xE8\xDB\xE8K\xD1R\xA7\xA1G\xAB/\xAD\xB7\xB7\xB7?oooo\xCFӧO\xF1\x94\xEC\xED!I\x92|\xDAC\xF6\xF4(;Z\xC6>\xE9o\x85\xA2\xB5\xA1\xF6~\xB3z\xE66\x96\xE3 \xF1\xA6\xA8+\xFA\xE7\xAD۹\xAFq\x87\xADLV\xE7\xEC8\x86\xE8H\xF71>\xEA\xCB\xB8\xEB&\xE6\xD85\xD45\x98p\xD4
+\x82V\xA1\x87Q\xA0\x88-\xFA.\xD2}\xD8\xED\xAE(\xF5p\xCCJ\xBC\xB5{$\x87\xB2\xA9\xA1\x91>\xE6\xE7a\xF8\x9Aڐ55Ȕ4\x83\xCETG\xC0#[++Z\xCC\xECTs\x96dSC}\xA7
F
΄ꠐ\xB5\xCAI\x82\xC1d>k\xE6\x89C\xCA*%7;h&\xD6\xF3\xEC\x9FM\xA5\xB5\xBA\xB4Film\xF5\xECʷ6T\x96W6@\xDF\xD4ց;\xE2KCQV\xFA\xB9\x8A.\xC0\xC0r\xA9\x9F\xD7(
ҊRF|\x8C2ͼ\xEA\x92\xF8N\xC7\xE4\xC9: \x8DFS*\x95\xE8no\xD7yi\xBEw@'\xA5hmz\xD4"A\xD0\xF4XF\x86\xCF\\xAD\xFA\xF9![K\x8F\x9E\xFCy\xC9\xDA?\xF7 \xEB\x8Aҍa\x98\\xA8\x9AK\x955T\xFE+\xEB\x9C\xD1*?\x97A+\xCF\xCB\xEAZ\xE4$F\xD3LG\xF1M
BYN\x8D?\xA0U,z\xF0U\x84\x82Bi\xF6\x84B̒M\xA5\xD9%\xF8\xB3\xEB\xF0\x90a\xB2\xA2,\xB1ނ\x95vc\x86XR(t\xFAo(\x91\x95E%\x8CW
9\xCFl\x82\xA2\xA1\xA8\xB8\xF9\x95ţ\xB8\x9A+\xCAB\xDF\xF0\xB9\xC5\xE2\xBD\xE7\xEBhZ\x96\xBA1\xF8\x9E߉\xAD\xAF\x81$ \xE5G\xDE\xFB\xC2 *;\xC0
P\xE4\xEF\x89nq\x8F\xF0
\xAC;l(\xCDɺ\\xE8ڮ|˅;\xE4\xD1\xF4\xAC\x8B\xF5s\xCB\xFCg!\xEF\xDC)\x9Fb\xA8\xAF\xA5\xD5hkk \xB4\xB5\xA12&\xD6\xD6\xD6\xD6\xD2\xEB5W\xD9d4\xC6\xDE\xFF}:\xCB/Y\x9D\x9AR~\xCDV\xFF\xBF]
+\x80g\xD6\xFE\xECL\xA30\xD5t\xAE\xF6$\x82 \xADI\xB4 mmm-\xADIP/\xA7\xA5\xAD\xFA\xAD\xA5\x85I\xAAQݫշ\xD0\xD6\xD2҂\x9608\xE5WӋa\xDF\xF9P"&\xC5\xEF\x98?\xB4\x88\xD9\xD3\x{16495D}\x8F\x92\x95\xE2?\xC0M\xC4\xFC\xDF\xFAؤ\xA0\xA0\xA0\xA0\xA0\xA0\xF8\xAD\x98\xA4;\x85=\x8E%%)(\xFE/\xA0DL
+
+
+
+
+\x8A\xE7\x82\xFC\xF9\xEFֶ5\x9B"\x97ϟ;s:{2\xD3\xEC\xB5\xCE5ET\L
+
+
+
+
+\x8A\xE7\x82xqca\xB9\xAF3\xB7\xB3\xFA\xFA飱q\xC9\xF9Ͽ<\xC5\xEFJ\x8BIAAAAA\xF1|\xACi\xB3l\xA7Ͳ]H\xF6 \x93\xEA\x95JA1 u?PPPPPPL\x98\x9EGWR
\xCD;v\xBCJ#q{F\xE5\x86/\x8Ez\xC5 JĤ\xA0\xA0\xA0\xA0\xA0\x980$\xA94z\xED\xED\xD8-q3\xA6\xEA\x80\xCE\xEAK\x96\xEF\x98[y\xA0l1)\xFES(Ze\xFF\xA7˿*\x9A4N\xA0hjhR\xFC\xA1V\x9BU4\xB5\x8E\xB4F9\xC5\xFF\xBAfK\xD7z\xAE07c\xEB\xF6Ϗ\xEBq^\xB6B\xCD\xEB\xD9CA1:\x94sLȺIxig\xAC\xEBȋ\x81LEݥ\xE3\xC5\xCA\xC5^33-V\xB6"g\xE7{\x99\xCDzzC\xD3;;\x8D\x87w{\xAA\x96r\xCC
+\xDDx\xB8,@\xCAt\xD8\xE2fp\xFEb\x8D\x9E\xB1\x91--- :w\xAE\xF8x\x9F\xE7s\xAF\xDBFV\xC7x
\xF28
?tQ\xE9\x89\xD2pl\x96\xDD{Av\x86 \xC8Ҭ\xA3\x97+.GM\xADR\xC6k.\xA19\x8EQ\x95F\x92\xFD\xFF\x95J\xB9\xAC\xB1\x85ff9d\xDDEe\xB2\x89MM}o\xBCj\xF5\xB4\xDBInY+/\xEF\x9EP\xCC\xEE碯j\xA4\xBCU6\xFB\xB7<]\xD3%\xE1'f\xEC1V\xBF\xA22\xF4
+\xE1\xA63}ר\xA9\xF4\xECyI\x81\xB7\xDF\xEDi\xF6\xF05$u9\xDC\xC51E\xBF\xEE\x82RPP\x8C\x83\x87WNU\xC1\xF7EU\x90s\xF2\x97\xEF>\xF5\x8F=ֲ=#\x8B\x9A:\xA7\xF8cB\x89\x98cB\xE8\xB5%'o\x8AM\xC4$[\xCB\xD2O֬\xDA\xEC\xCE
GG>\xAA\xBE\xBF.د\xEF\x8F\xE3P\x89\xC8w\xD0r
\xF4ٞ\xFE\x93;t\xF4u\x86
\xDA\xDDM{\xB1?cA@\x8C-h \x94\xA0\xD3:_\xE0\xF2;$\x87\x96\xF9\xE9\xE5\x95l\x9AeǓ'\xECi\xFD\x8B \x92\xA4\x82$\x95r\xB9\x82\x94wJ\xE5r\xA5R\xA9\xEC|\xF2\xA4\xA3\xE3\xD1=\x9D\xD7V^\x91E\xDDdD\xB7\x9Ad$(HR\xA9\x939qلP^\xBE\xBF\xDC\xCFΐ \xC6:\x95\xC1Qz\xFC\x84\xF7\x8En\xCA\xB0\x9BH\x87 \x8A2O4\xB8x\xFF̪\xBF\xD9>~8\xCDѮ\xA5\x92\xDB\xF3\x81 \xA45\x92f\xB1\xE06\x8B@Z#}'}X\xB1π$\xA4\)W(Heg\xA7\x9C\x94+\x95ʶ\xB6'
\x8F
\xB5O\x9B\xE7\xEEط\x94\x92\xC6"4 \x90Q!\xF7\xBA*\xF9JӤ\xB54\xD5\xC49\xFE\x9F\x8FX\xBB\x96; \xE2έ\xEASuH\xBC\xFDnG\xF8\x8B
>\xCCQ
+݇\x8CD:g\xAE\x83D\xF0Mq\x94\xDDbC\x80l\xA8\xAEg\xF6/\xB64\xA1\xD1KAA1]m?_>
\xF1\xD1\xE75.\xA8\x96\xF9~x\xFEЏ\xAF\xEE+\xAC\xC4
\xEE\xDEڻͩ\xBB\x8C\xE2\x8F5\xEAdž\xBD0\xA1k"
G^\xD8Y^\x93\xEBi\x80\xBBFy\xE9\x80_2\xB6\xA69\xC9\xCCq \xBA\xD5D*d\x8D\x8F\x9B\x9B\xD7\xDFo\xB5\x9E9\xB0\xB0\xB4\xACL\xC8\xE2\xF2\xF8|\xE3\x91k\xD2,KK\xA4~\xB4cf\xBC@
\x8F@"\x91$\xE6\xD8B\xD9\xDE\xA0\xB3\xFDISw7\x8D\xB7\xDCŔ \xBA\xB0-z\xACZl\xBD\x8F\x90\xCC
+K.\xC8\xEA\x9DV\xB1\xC5D\xBD\xFC7\xBFP\x9A?qm\xA0\xD9
+\xA4Kjao\x80\xE3\xBE73b<\xABB\xAD\x89ScwHt\x9B\x94\xC6F\x92 \x98L\xA6\xBC*{\xA9\xCD:㐸\x99W\xF6|"*L\x96ln\xBC\xC4@V\xC6\x8ARJ\xAA\xF8 \x82A\xDC:$\xDB\xEF\xDB1\xCFXN\x92\xCA\xCEN\xC6\xF0bGE&\xF4`\x8AF\xDD
\x92Q\xE1\xDEa\xAD\xBDRZ\xDE"&CVe\xB6K\xB9t \xA4\xAC\xA9Q\xC14\xEDӲN\xA045
+EB3\xA7@~t\xEE\x99H\xD7\xC1+Y\x99\xA6\x86\xF8E$\xDDc\xFC}\xF8\xEDdi\xB6\xE3ⰼ\x88\x80_<륯\x98\xF4\xDFϤ\xACU*\xD1\xD62\xDE[?b\xACBTl2\xC0+\x94\xDER]\xD0 \x8D^
+
+\x8Ai\xFA1\xFE
+\xEF\x8F,\xD9"<us\xE3L\x83\xBEt]F\xFD\xF5\xBB\xEE\xE3\xE9SoZ\x8A?$\xD4\xC0\\xE7Ix\xB1"̞\xAEh-\xFB1\xEFPh̫\xC9\x82\xD4'\x8Dސ#\x889\xFCe\xE9<\xA7e+\xA5\xBE\xC3g\xABIR\xAE$iz,ck\xA6\xB5\xA1\xA1\xC6R\xBEL\xEB\xB7jk]Ǫ
+ \x96\x93Ix\xD5W-\x97\xF7%1X\xA8N9v:<*Y\xF7\xA0\xFCJ`pT\aK\x98\xA3!\xC0X\xBE\xAF\xA4\xC2x\xBA1\x8B\xC9d0\xE8t\xA2\xE1\xD23\xE7\xE0\x90\xA4\xCC?q&?,H\xCAnh \xB0\xF1\x9E\xEC),c#=\x9A\xB4\xB3\x93e\x84#\x82`^\xFA\xF1\xE5F \xA5\xCC\xE7\x99\xFE%^s\xF3Yw\xF2'\xF8\xDA\x8A\xEA\xD2n\xEE\xE4\x98\xB1\x87/]<z\x87\xA8\x8B2d\xB3\xA8\xEA\xEF\x93T\x98\xE0\xD8p6\xC6,\x9C\xE1RSR\xA7p\xE5Ы\xB3\xE3\xD3y\x89\x87\xED-o
ؙ\xFE\xEFf \x8F
+\xC55\xB7\xE3;\xCF\xEBxu\xCD\xCE \xBB\xF1\x8Fsƒ\x88\x82\x92\xCFM\xA7\xA9:NVvl)\xCF\xDB":㋭k-/\xE2Lg\xF6\xFD.>
ˋ+Q\xCD\xD1K\xFEa\xE2\xD0U\xD8\xE98\xD1\xD2 \x8A\xA2\xD4`'\xBFd\xFF\x94B\xA1\xEFp!\x8F\xAC\xBD\xFE}R\xD9#Q\xBA|\xFF)\xF4\x97\xE2
+ߙ\xCD \x97\xDD\xC2Ae%\x8B\x8C\x9C\xD4|>\x92\xE4,\x97\x94\x92\x8A\x9D\xE6f\xA7\x9D\xE8襠\xA0{\xF6\x86\xCC\xDE4Ἠ7\xF81c\xB8`Gx\xC3\xC1\xE4C\x8AMv\xB0\xFFKu\xA3\xA0\xF8\xEFB\x89\x98\xCF\xC0\xD4q5$\xCB\xDE\xC8MO\xF0\x8FN\xB45\xD0ح$e\x80\xE6ۘi\xE7[\xEF\xB4>Ep+\xA8O%\xEBRc\xB2\xB3DC\xAA\xE3a\x96\xAAW>ݐ\xC31,n\xE4\xA6\xAF\x86 \xB1$;\xC8^\xB5}\xE1\xAFk\xBD%\xE0\x89KEo|X$\xFBǨ\x9A\x98\xF80;@\xF7hT\xA3\x9EJcGX\xDA۫o-\x9A9\xA7HZ|\xED\x98\xC76\xD2\xE2\xA7F;\xA5\xAE\x92\xFBZ\xB2
]\xD8 +\x8B\xD9ȋ\xEAӷ\xF1K\x8C\xE8
@^>\xCB\xEB\xE0
\xB93\xE6JlT \xBE\xB7M\xF47\x9E\xA0)'\xE6=A\x94()\xAFj\xB3\x8BYSC\x9D\xD2|a\x88q \xE7O\xBBr\xE8h-zo]2\x90Ā\xE2F\xF6\xF7\xF6\x9F\xA5,a\xD3J\x85w/\xCE\xF6u2m*\x8C\xFF\xB4\xF8a\x90\xAB\xA6\x{194535}6\xD6\xDF\xD8\xD4\x{1248FD}
\xD3^Z\xEA\xA89\xBDMp
dm8k\xC4\xF3\x8EΫ\x8Dta:\xBBYYJ«\xFA\x845\x9D\xAF!\xB6M\xA44\xB2!\xD5\xCF\xCC/
I\xF5\x8BMG:\xDD5L\xE8
+\xF2\x98\x8CV
\xF8\xB70W\xF6%a\xA8\xA3S\x82\xBAK\xA4A*cL\xA6C\x91\\x82 \x88>7\x84\xA2=\xB3\x9D\xCA&\xF3\xB8\x9CA7\xFC8G/\xC5\xE8\xCF0\xB7
q\xC7\xE49\x9Es<\xFFõ\xA1\xA0\xF8\x82\xF2(\xB2\xA94\xE6\xCDe `\xECRPQ\xAF\xEC\xEDF\xB9pLkG
\xBE\xBF'z\xA0\xE3\xFB\xC9|IpZ\xE9\xC0\x8E\xC6;\x8F\x84\xE7\x96TԶH\xE5Jeooo\xAF\xB4\xBE0D\xFE^r\xA9\xE6\x81\xD6k\xFFVUU;\x8C\xAAķ\xAD\xFB\xB30\x96~\x9CR\x92\x92\x9E\x9E\x9E.\x91l8\xB7\xD1EK\xCBF\xCF\xC5\xC3\xC3e\xB6\x9F\xE1<F at j\xD9\xE0\xEA4
r\xD5\xFA\xDA\x84\xD7\xE1B\x8B\x84{a%\xAB\xCC$\xAB\xB2\x94\xE0(fFKo\xAF\xB4"W\xD6\xFF:\xF7dY\xF5\x81\x80\xA4\xF0\x8E\x91\xA8\xB0B\xAA\xEC\xCD\xEEv\xB7\xF4%\xFF\xEC!rR\xEC\xD90[\xCBD%px\x99M\x8Babfnn\xB3\xAC\xC6\x97\x8B\xEF(\xA08\xE6\xE7\xD4\xEC\xC2\x80 \x8B9s\xEC\xB9\\xBBɝ\xE2\x996\xAFq\xB9\xDC9<\x8Dg?\xD9 \xF5\xD0Ң\xB1\x8C\xCClx~_
H9\xF5}\xA6\x9B\x93
+\xC3eO\xDD\xC8\xCDU\xA4\xFB\xB8\xF1G\x91/\xC9Ҭ=\xB3\xB5\xB4\xB4X\xBCt\xC0ۊ\xE6\xB2qgNieS\x9C\xB8\xD3'^d\x92t\xBFtdT)G\x91/\xD5\xC5HN\x8A\xC0\xB71J]ndAIUmm}c}mm\xBDO-+t:\x9DNH\x85L&\x93\x91\xEF\xA5\x{92F2FD}ԤY\xD2\xF8G/\xC5D\xA1\xB4\x98\xA3B6\xE4\xAF4[&\xF6O\xAA\xF8v3\xD7p\x8C\x8E\xEA3\x9El\xAD,\xBAo\xEC`\xA7r\x9D`:~
+\xE7\xAC\xE2 { 8aiiCc\x9A:\xA4l\xBE\x96Ȃ\xFC\x80\xEF~\xBF\x9B痬2\xB5
@"\xE1%\x95\xA4\xA8\xB4\x92\xA4$'\xED_O\xC8\xE5\xF2\xABÎ\xD4\xFE\x95 \xD1\xE7ۜH$)\xCBl\xD0\xE1\xB2{Y\xE0%\xF3\xFB%\xA6cv\xEF\xD0IX\xA5\xA2\x99?\xCF\xCE\x80\xF1t \xD5
+2\xD3%\x8E\x97\xA6K
&\xCE"A\I}\x90\xBD\xE9(\x85\x8C\xA7C\xC8fqv\xB1\x91۲\xB8\xBCM斳\xCD\xDD
\xD6\xC1?I\xB2\xF3-\xCE\xC0\xF5X\x9DX\xB5B\xEF\xF1\xEB\x8B \xE8B\xE4\xC4\xD2\xEAۑl \xE0'\x96\xF4\x9F\x94i=\xDB#O\x92\xF8\x9A\xB5\x99ڃ](\xDC`\xB6\xC9'\xFF|3\xCDs\x98"Bq7[̋\xFFvd\xAB\xC4R\xA1\xA7C\xA04SR\x85CV1\x96y?\xF8\x98^=\x97\xE9`#\xFC\x93\xAAe\xE0\x9Df
\xB34 L\xEB\xE5>\x80\xF7\xF6\xFD\xF6iac\xCCQ\xCBn_!$\x91C \x84\xB3O\xC0苉\xB4\x9E=\xED\x9C0(\xCD\xF9\x83\x95-i\x83\xED\x8A\xC71z)(((((&%b\x8EJ\xC1\xA1eb\xFFL\xA5\xD0s\xAC>b\xCE\xF2\x84\xF8\xDC\xEDVGG\xC3j#<خ\x8C\x86\xD3\xF5\xA6\xDD.\xA3[\xE1\x90\xE5y"\x9Ek\x94\xA681\x93VQF\xA3
+ΨT*\xD3\xFA\xE6\xF3\xF9uCGGg\xF2K\xCE6\xCA
V \xD3ͼ\x90̢x\xEE\xA0\xC3i4@\xD2=fc\xA7\xCF\xF5/\xE3\xB9\xFB4\xA7\xA7\x90\xCB@\xCA\xEAJn\xFEB3\xE5\xDA[\x8EmVD\x9E\xDD\xED,\xF2ɔ\xA7yN\D
\xDC!t\xBB\xF8l\xB5\xDAj\xBE\xCE)Cr\xCB\xCBn\xC81L\x8E%S\xF1X\xD69\xE8ߖT.\xAE\xFDnS\xB2U\x84_\xE3g&\xE4J%hj_\xA6\x8B\xAFﰓ\xB2\xF9\x9B\xF9\xC1\x8F\xD30L\xC4Tv\xD6 \xB4a \xEA\xD2EIJOn\xDD\xC6d\x84\xD7:\xB3M w\xDFH\x{1D5CF5}\xCCɁ˒\xF9%'\xBC4\xB7c\x95\xA6\xAA\x9D}\x9A\xB4\xC2N`c\xC3\xCAȐ\\xF0\xB2y\x9A\xFA\xE6\xF7\xC1\x88\xC8\xE3 hȡ\x99 D\xB5Jw\xCE\xF0J\xE6\xEF\\xEA\xEB\x92WQ\xBF\xC0ʄN@!\x93\xD5߽\xB4\xE7\xC3\xCCV\xA9jc\xCC\xF1\x8D\xDEq_z
+
+
+
+
+\x8A\xA8\x89\xF2ѐ\xDD\xFD
|{\xDBg\xC9\xE0\xEC\x85\x88:t\x89D]z,\x92<^Q\xEF0|a6\x90\xF1\xF3蓍eYQ\xEB\xD2\xEEn\xAD\x99xChec\xB3v\xFB\xF6\xF7ؾ\xFD=\x9B\xE0\xDC\xFE\xB9\ٹ\xAD\x82\xF3\xCD\xDDݵb\xC1\xB2-\x92ƶLj\xAE\x95˥R\xA9T.\xAF-\x88\x96$4 =
\xF0Eʥ1\xE2\x9B\xBAD\xB6T\x86y\xFB%d\xF0Δ\xC1\xF2ak\xD1J\x96\xB9\xD3\x9F:X\x99\xEC<[7f\x87\xC8\xEE$ \xC4{\xC1s\xA8 at G\xEC\x8A\xEA \xF0 &_\xF6\xA1\xA0 \xC3WV{?r\xB6rJ\xE7\xBF\xE3̦t:\x93\xC9d\x8Er \xAB\xBF
+G\xAF|i\x84]\xCCYސl=tv\x84YtE\xF3-\xF0\xE7Yթ\xDB\xD3y\x89n}B
yv\xAF \xFE"e\xAFTa\xDDM\xA3\x8F\xB7\xB4\x81<ܰ|in\xB4\xB17\xCF(&\xA7r\xC4ڦG!\xD1s
\x80\xCA\xD3_!\xBAp$\xF9\x80\xAC<V'\xD9\xEB\xC25\xA5@Й\x86\x96\xF6\xEE\xC2\xFC\xB4\xC1\xE1\xB7\xC61z'p\xE9)(((((\xA0\xB4\x98\xA3\xC1\\xEE\xE8m\xA3+Z\xE5\xF4\xAA1\x8B\xA5R.mn\xA8\x91\x94\xB7Xn\xF1]\xAC\xEE8\x97\xD0\\x9E\x89-
\xE0%\xB6h_4]\xD9\xD8\xC8
\x8D\x9BT\xB4Vݺ\xF4u\x84 V\x8C\xB8\xBCZ\xAF\xC1s\xA2S\xA6%YC=\xA0+\xB8\xE4h\xB8\xA4\xBC\xECa\xFFe\xF0G `l0\x8DN\xA7\xD3\xE9 l\xBF\xA8wa\x92\x89\x933\xED\xA8J\xCCz\x87W\xED\xECFRGZ:\xBA\x95\xC5,]&\xF6\xC9838\x8A\xA4\xEC\xCE9qH^o\xBCY\xB6\x87ye\xD40\xA1 `\xE8\xC7v\xF3\x99\x9D\xCB\xE7\xCDb1 r\xB9\xF4a\xF5\xAD\xFB\x98\xED\xBEx3ı;D݄ˇ\xF7Ѭ\xD0
\xE6\x8D\xA5]\x95J\xE7\xCE_ \x88 \xF6\x8B=f\xB8v1{Q\x97T\xD4I\xCE}\xE2 H\xE7'\xD6;\x8C\xA82d\xBF_\x91n\xE3\xC6\xC8\xF2I\x8A\xF4[\xF0\x9AF\xBF\xD1_yW v\xA0iH,I1 \xF2\xD2O\xB7^^\xFD\xF7!.\xDEc\x976\xA6kd\xBE\xC42\x94'\xB0\xB9\x9FR"\xF4\xB5\xD7\xDC\xD7t\xF5X2BjU\x86\xBA@ԡ\x9CUs_0\x86R\xFA\xB0\xFAߒG\xD3|<
`L\xC0{\xCFa\xB7\xB8\x8D6\xA6\x86\xA0P\xB4>\xBA{\xE3\xEBC?\xACڷ[3<\xFB3G\xAF\xACh\x{17782082}\x82\x82b J\xC4
\xAEב\x92\xC9\xF3\xE2"\xA3\xFC4\xE7\xA1y\x82U\x91~\x9AN\xB8l\xD7\xDC\xC2̣\xE7Vn\xF6,\xA7\xD0\xD9C
ű\x8D\xEFt \xF0\x89N\x91\x9C\xD8`7L\xA2 \xD8dz\x98\x99Z\xFD\xC9dB\x92ς\xFE߄.K\xE40ۅ\xB1\x80\xA6'vt\xC9V\x99\xD45\x8B\xC5\xE0'
+\xD7V\xB2
\x94\x8DN&
\xF2,\xE2ZzÆ\x8ATd\x9D\xF0/\xEE\x81\xC9\xF8$զx
+\xA9\xCD\xE0$
8\xBBɴ\xE5\xABpނ±\x85ǰos\xE9\xD1\xE1nN~\x83\xD3y\xFE\xFC\xC5C,\x9F\xDD!\xFD\x9D`87q\xBD\x9BCl_Y\x89-\x9A\xFE\xCE4\xC0XQ[]*\xFE\xABCp:2$\x8Dnze\xD1k\x9DM\xBC\xC1\xF7\x89X\xEFf\xFF\x8A\xFD\x92\xC5\xDCy\xAE:'\xC6J\xA02\xD4DHR\x9E4\xC0e4\xD3G&\xD7K\xD9\xE2x\xF2\xC8!\xEFuC\xFA\x8D\xEEu\xBC\xD6踸\xDDr\xB1\xA7\xBD!\x9AJCM
\xC0U]VE%\x9D`iC\xB1\xF3\x8A\xAF522ws\xE8ԩJ\xF3R\xCF\xE07\xC4;G\xF1\x92$*9\x9D\xEB{D$\xDD-p\xB0Q%\x88\xC8|\xD3S\xF2\x92\xFE֑\x92\xFB\xF8\xF1̂5\x8B\xE5\xF9$\xBE3$B\xE8\xB3F\xEF\x84.=\x85-\x8B\xB9nc\xED\x86\xD6{\xC7Coo/\xB7\xB7\xB7\xB7\xEF\xB7F\x8A\x96:
+=Z}i\xBD\xBD\xBD\xFD\xF9{{{{{\x9E>}\x8A\xA7doI\x92\xE4\xD3
\xB2\xA7G\xD9\xD1\xD2\xF0+k\xF5ߢ\xB5\xBA\xB4Film\xC5!\xFE# (\xB2
\xAF,9`7E9\x90H\xEB\xFCI\xE8\x94>[\x9A\xED\xABZ at R\xB8qˌ\x8F\xF7/fT
J\xB8\xFDNԼ\xDDofm:0$@\xB4\xFD[\xE8\xF0\xD5K\xFD9'\x84\xE2R\xEA\xFFk\xE5\xADv\xB7ѝ\x99,\xCD\xDA\xFF\xE1\xBApVHJb\xAC\xEF8Y$\xA9P-\xAFH\xF4ѼR\x9E\xD5!C+\xD9P]\xDB\xDC\xD6 \xBD\xE9v܁z\x92
+9\x9E[n\xB9\xBDR\x92\x8F/"|Ջ\xB5֕]\xE7f~\xFD\xE3\xB2})\xBE\xF6\xD9TYP\xD9ɱ\xB4\xE0\x98\x8E\xE5\xC65\xA45
+I5\x86\x93\xAC(Gl\xB0؝;\xDE0?c\x97\xD6GYN\x8Dﮩ\xD5U4\xD5\xC9\xE8\x9C\xF1/T\xA9hmz\xD4"A\xD0\xF4XF\x86c\xAE\xD29zU\x9F\xE3\xD2SP\xFC/AS>\xC5P_K\xAB\xD0\xD6\xD6& hkCKKKKKK[[[Kk\xAC\xD7\e\x93\xD1\xAA\x9E\xBFxf\xED\xCF}\xECTӹړ\x82 \xB4&\xD0&\xB4\xB5\xB5\xB5\xB4&\xF5\x8Dc----mտ^m--LR\x8D\xEA^\xAD\xBE\xFD\x80\xB6\x96\x96\xB4\xB4\x80\xC1)\xBF\x9A^\xB2\xC5\xFC\x8Fbhio\xCF
C\x9C\xA2{
+o\xC5{-\xE6\xDAi\xC2u\xF4\x8C\xEF
\x90\x99ii\xEE\\xB6!gqd| \xC7\xD0^\x98\xBF\xDBђciiiiɱw\xDF\xDD\xFB<\xF2% \xFAb߀Q\xE4K \x84\xBDgX~oov\xFC\x84\x82\xA0\xAB\xDD\xEB\xF9\x99
2\xB4\x92\xA6\x96\;{{M\xF9 aꞝ
\xB0;;{\xB7\xAF梘\x86
;w߰\xB4\xFClM\xF9 \xC1\xE6\xBA,\xB6\xB7\x9C\x80| U\xA0\xD1\xF72
\xDD\xC7/_>\xB3\xB4>\xEC\xDC݇X
+\xD0\xD9\x90/\xD0
+\xD9
KK\x87c\xCA~>\xF9\xCFw\xE9)(~7$\x9F<KmP\xBF\xE1\xC6
+J\x8BIAAAA\xF1;\x86\xD2bR\xFC\xAF at i1)(((((((((~\x94\x88IAAAAAAAA\xF1C\x89\x98\xBF1\x94\x88IAAAAAAAA\xF1C\x89\x98\xFF\x97\xF4\xC8+\xCA[{\xFE۵ y\xC5\xCDGO\xFEە\x98]mZ;\xD4џ\xC9\xD6\xFA],\xA1\xA7\xB9\xFCfe\xD33\xB3u\xB6=imnjmnjmk\xC8ζ&\xD5Oi[\xFB\xFF\xE4\xA5\xFC_\x84
+\xBDNAAAAA1q\xBA\x9B\x85\xFB\xFE}\x934\xD3:\xC1\xD8j?k\xC8\x90
I{\xBC+\xCEpp2\xF9\xA8A\xD6E\x80\xAE\xBE\xDE4c\xDD1\xCF\xD5v\xEAD\x83\xE3zS\x9D TP\xD6,k\xED m\xC3\xE9\xCC|Z\x9CV\xFCe\xF9S\xFD\xB2\xEE\xBD_\x984|\xFF(
\xD6\xD5)H \xA0O\x9E6}ڔ\xB1\xF2v\xFD|\xFC\xC0\xD9EA[f\x8Eٲ!H\xFD\xD2\xD2.hF3g\xB1\xD4v=yx\xBF\xB6\xE6NY鹌\xD4\xEC\x82m'\xABW*\xB8c\xB6Ι\xA3\xF8v\x91`n\xF9\xB59\xFA\xA8m[rԊk\xA0\xAA\xB2
\xB0\xB5⢪\xB2
+^Lެ dWIL\xA2K\xCE|\xEF,\xBF0r \xD5i\xBEqHMި>US\xF1\xD1ܶE\xEF,\x96n\x9F\xB3\xC4\xF6\xA3]L<9\xF8yeZᇧ|\xF7\xB1=\x9Ct\xF0\xE4\xE0\xE7E)\xE5gm\xF5'Ш?,\x94\x88IAAAAA1qz\xC8{m\xAC-}\x95I>U%\x84\xE2\xF8_\xCB;T;\x9B\xE5^\x93\xEA1\xB4\xCANл
+.\xD7\xD0ȧ \x94r\xD2\xF4uK;\xBD惉\xCA46\xFBӠWG\x97 \x97ʛ\xB8\x9E6\xA3\xC5.
\x8A\xAC)\xE5\xE0\xBF\xDB @\x9FM\xEBhR\xDA/\xB7yw\xC54
+9Ry5\xEDj\xEA\xBDi q\xB3\xAE%\xA9{_\xA0峣\xEEv\x94}\xB6t\xC9u\xF5\xCF\xBBN
]\x82l
N\xB5\xDD2n\xB3\xED\xE6\xDF\xDF_\x90z \xACV8W\x9D/x{\xEF\xC5`\xCFy\x93 (\xEE~\xFB\xD5?g\xBC\x8A\x8B\x8F\x8Ak\xCE(?\x90q\x87\xB6ڙCL\x9Eo\xA1:Z\xF1\xB01\xE0Tûs\xA6 \xEDǽ6s\x8F\x9C\x98\xA3t\xBF\xEFyY\xA5\xF3\xEC\xAA\xFE\xD6w\xF9f+,:\xDAO\xE3\xEA\xDE\xF0\x96\xD5
\x955\xD7+\xCBcr4*\xF8$\xF7\xADm\x8F3\xAA\xB9>l\xBB\xBA\xBA\x90\xFA M\xD7\xE8RtC\x8C\xAF=\x94\x88IAAAAA\xF1\\xD0
+t
+4
+ݤ\xF6\x83~\xF3\xB3I\xDAz\x82A\xD7&\xE8\xDA\xE5\xA7\xEEu(\xF0]\xA9\xFE\xBB\xF4H\xB4铀I\xDAt\xC0\xF5݅k\xACi\xF2\x9Aꐤ{\x97\xEEz\x8B;\x9A8\xA6\xAD\x87I\xBA:@)\xEF!c\xEB2\xE5\x8F>\xF9[\x85\xCD:\xE1\ma\xB8\xC4%t\xBEuOkJ\xE4\xADx\xFDå \xE4\x8F
|\xBD\xFF\xA7R\x8B\xF6\xED\xB4d ..d\xA4]\xFD0\xBC\xD17p\xCE|\x8B\xA1
+\xD8A4}`\xFB\xE9\xC6
+\xB6\x93;+O,q\xF3˯\xF0{g\xCEh\xBAL\xDA\xD1uR\xD1\xD9C\xD7[\xD0\xEC(~\xCE\x87\xD4\xCA\xE2c\xB4\xFD!o
>\xC1\xED\xF9\xE9\xEF\xDC\xD7>\xA3\x95Gf\xF5\xC0x\x89\xC7e?UW \xD0g\x81e
+\xDA\xE0t\xF1\xCB\xED\xE2JL\xF1\xA4\xE1j
+\xAE\xD3
+hd[\xF1u\xE8 \xA9\xC0LA\xFA\xDD7'\x84\xF4f|x\xC1\xA2\xB8ʹp\xDB\xDBNV\xBAZ\xD1~w1 IDAT\xBBH\xE8 \xD0S\xF7\xAF\x83ؐ\xF9\xFAt\xDDlg\xCFu6Fc \x8E\x93\xA4\xB2k\xF2\x9C\xD9\xF3\xE7Ӕ\xAD\x95\xA8\xB3%P\xB6\x98\xCFE\xD9\xD9T\xFD\xA1\xA7\xBB\xB3\xDF0p\xD2\xB6\xCBR\x8B\xF9N\x9Cy\xAF\xD0\xEB \x80\xE6.\xB3\xB9\x9C\xF9N
\xE7\xA5\xD6S
+ x
+\x80aa\xEA\xF4M\xB9w7w\x97\xFE\xDC=t\x9B\xE5\xF9c\xD7v^\x89\xBC\x90Q\xD8
+\xA0"\xA7h_Σ\xBE\xF3ɛ~Zt\xA3\xF9)\xF0\xB4\xF8\x9B
+\xFAr;\xEF\xB9L<i\xF9 ,\xF6$@\xC7\xD0/\xCC\xE2n\xEE}\xD0p\xF9z\xC8\xFE\xBB:\xB6\xBA\xA8y\xF7i\xC1\x9F|\xF0\xE9\xB5\xEF\xAB`\xFB:+/\xA9( \xA9\xAE\xE8\xAA\xFB~\xBB뺼\xEA\xE2\x84w @\x8F\xEB\xE2\x8B~=UW\xF9~\xAF\xB0\xAA\xAE\xA1\xDB\xFA(ȉ\xDF6\xCF\xDAh W\xEF\xCB~P\x9E\xBA)*\xB5\xB8\xBF\xAC\x9B\xB1n\x9B\x8A\x91 yu\xFF\xFD\xBD\xD7\xDE]\xF2"\x9Aˋ\xE14\x8D t_\xFEKafn\x88H
+@\xF1\xE0\xCEݲk\xC7\xBE\xFBj\xDB\xF5\xAA{\xB5\x8Cx5\xEE\xFE\xBB\xFC\xF6m\xC9mIy\xCAk*%\xB7o\x97ܩ\xBC\xAE\xAAcgU\xA6/\xD7y\xEB;\xFE\xD0Ӿ=_\x8F_\xE2d\xEB\xDF1߹\xEA\xD8_߶6\x{2FB2BE5}e"?\x84\xBEoN \xA0
mm\x8D\x9B\xBA=\x8F|8k\x9A\xB5\xDBnsã涖\x8E\xF1\x8F?<\x94\x93\x82\x82\x82\x82\x82b\xE2L҆\xA2yg\xF4e
+\xAB\xBC\xA7
+\xDD\xD7e\x92\x9F\x8C\xFC\xF7Kk8\xEC\x9B\xDDζ\xB2\xCF\xF6\xDDM\xF8\xD0Z\xAD'\xA4ʮ\xA7 \xD9p\xB3\xB6X\xAF\xAF\x921\x9F\xFE\xD4\xD6\xEE\xDC\xE7Qҿ= dz\xECO#^%\xAB\xAAve\xDEz\x85\xEB\xFC\xAA\x9D\xD1ݤ\x9F\xCA\xF8\xD3\xEC\x98\xF8\xF9rL}\xD7X誩\xD3}\xF3mc Oj\x9B;^6\xEE\xD312\xF5ظ_\x8E\x97
^\xDD\xF7:\x83\xA9\xBF\xE1-\xF2\xE8j\x96M\xD2\xBA\xC8\xEA\x94#5Z\xE8\x96+\xC5\xFD3S\x81\xA6jaY\xB2\xF8ꅕ$\xA0\xAB\xB1M \xC0\x96\xEB\xA9\xEBQd\xF9\x97\xEB|_\x9B}]\xCAs\xE2\xE7\xBA\xFDe\xED\x9AksP%\xFA\xE8;\xAC\x9EF O\xEE\xFE\xB8\xDA\xF7[ \xAD?]\xAEڴ\xA8o9\xDE)fsq\xF0\x97\x8EP\xDBi\xD7z-̻ \xA0k\xCA\xD7%/VV\x93\xF4\xBA ظm-\x97 \x80\xBE\xB0\x99 \x8E?f\x9F'w\xE375H\xAB/\xFC}\xF9q`\xF3\xE1ܭ34\x801#\xFE\xAB>\xFB\xF2\xA7\xEF\xE2s\xF95 \x80+\xFE̷7\x8C\xFD\xBC \xC8=i\x80\xF6\xB6\x98\xBE\xB3w\xD7+ΑC\xCFM12\x94\x88IAAAAA1qz\x9E\x82>-\xE13\x8D\xA9e\xE5\xA9\xDD\xD7?\xBB\xFEu\xA0\xA8\xF0\xF5W\xF7;i\xFF-\xF7\xF1K\x81s}\xCB/\x84\xA4\xE9
\xDC\xC8QMtӁ\xBC\xB4\xA2< \x80\xAB\x9F\xA3\x8Bi\xDFYOÅH\xBD\xAD m\xBD\xC7t0\xF7\xA5e\x99W\xEF>T\xBE\xC65_mPB\xDCl\xE7N|wA\xB9\xCCϜ\xA0\xA7\xF3\xC5S\xBBI Ȣ3O\x9C\xDD_\xEE\xAF- \xB0f00\xA9\xBB]Yt\x97\xAE\xAD\x8F\xA7
+ \xDA\xFA4#<m\xE9\xEA\xE9P<]\xB8\xF0OS\xA0k\xB9曚5#6Z8\xF8\xE7 `\xFB\xA9:W\x8EJ\xC4\xC4\xAC\xB4\xA9\xDE\xEE\x80\xF3\xBB\x9BW\xCD$\x80%\xEFoCLŽ\xF6ys\xD6D\xCC\x9E*\xFF\x87\xAF\xDE\xD7l;u\ \xF9\xA8\xAA\xB2͞ \xA0\xB8|ho@\xE8־\x82\xC8`\x89\x99> \xB4\xFE\xFBe\xFB\x86\x80]\xABu\xBE\xE2\xFEݠ\xFAO\xBAC\xDDm\xA6\xFE\xA1\xBE\xFE\x82\x80\x{2AE7AFC}\xD6/\x99\xB4\x9F\xBE\x88\x83 \xF2I\xED\x8D}\xF5\x96_.\x9C#Rb\x80\x87\xE5\xD7
\xE2\xF1\xB1
߄\x97_\x9B\xA3:ōc\xB9\xD8\xF7\xA1Y\xBF\\xD4.\x9B4mi\xF4?h\xEF\xCF)\x88\xAA\xD9v\xC6\xCD\xD32\xFD\xABy\xC6O\x8E?\xFF\x908(\x93\x82\x82\x82\x82\x82\xE29\xAC\xD0z\xAA\xDEꑵ
?x\xAB\xA0\x8D\xB1\xDA^Q|\xE1I\x8B\xA2\xF3\xE2\xF5{\xDB\xB65\xDBv\xB7\x87oyy\x96
\xC02\xBF\xF9o\xCDjF\x96]*~\xE8\xCA
0\x84$T\x82\xE5\xA4\xC1\xC6l}\xEA̧J\xA8iKֲO\xA7T\xFD\x93\xEE\xC2\xF8]\x95
\xE7\xA4ɖt\xE5\x83\xC7\xE4L\xE9Oߵ\xEF\xB6U\xF9\xF4F\xD6OM\x96L :\xEC\xD0g\xE8hw\xD7\xFC\x92Խ;Ύ\xBC^v\xB2aj\x84\xFBt\x93\xD0y\x86T\xD0 l;\xD5\xF0\x8E\xCD\xFD\xFD\xDC\xD7E\xE7/\xBB\xCFY\xA3\xA7\xAE\xB3\xEA\xD0I\x83K\xE8Q \xCAn@ &/\xDB\xBBf\xFFi\xE8\xE7"\xF2\x9Cʎ\x930{\x85[p\xFF\xA1\xE2\xC5\xD6D_\x8D<s\x8C\xAD\xEA\xDA\xE2\xC3+\xAE{\x89X at W\xDD\xF7+\xBDo\xA6\*\xEB\xBFs\xE4F\xF9&y\xB5\xA1k\x88\x96\xB5\xBE
~w\xAEQZ\x8Ey\xB6\xBD+\x9C;\x85 \xDB/\x86\xBF[G\xF7\xCF\xEF^wjF\xCA錦\xD5ǡ\xA3\x83\xEEnM\x87\xA6\xC32\x83Eu\x97\xE3\xF7\xAE=R\xC9\xEA/Oo2~\xFE!V\xF8թ\xEB(\x8F\xBDY_YP\xE5\xF3z@\xD0
\xA3i\x943\xF9x\xA1l1)(((((\x9E\x8F\xA7= z\x9E\xF6\xF4<\xED\xE9\xF0T\xD9o\x8B\xF9\xE8VM\xCD\xCB/'|\xF2K\xDE-W\xF6t J)%\xF56\xEE\\xF8r\xFB\xF9\xCA
+\x806 \xD01\x88x٨\xBC\xEE\xE3\xB4{\xFD\x957\xEEȺ\xE5
7\xCE\xD55
+\xBC\xA6\x95
vOn\xFE\ \x9A\x9D\x99. &\xD7|]\xFEݕv\xA7u\xE6\xFDN74\xFE\xDB\xD3N$^\xFE0\xA5\xC9\xFB/\c<}\xF2\xA8\xE9TRAR\xF9\x94O7\xF5E&\x9A\xA4\xA3= d\xC1\xB7\\xDF\xE5\xD3^3\x9F|\xE5\xA7\xF8\xF3͓t\xFA$ۮ\xFA\xF3Qoo.\xA8\xD3P\xC8\xF6\xD3\xE8\x80\xAE\xED\xD7ϛ
\xF6\xF7|\x9D\xAEI~\xE9\xEAxP|\xF2\xEB\xEB>\xD7\xF5\xF7\x9F \xE4\xFDӅp\xFE\xFF\xD9;\xF4\xFF7\x96De\xAC\xC1bD\xC1
+\x97\x81:\xB5Z\xB4Z\xC5R\xA8+v\xA4#\x8CR\x97\xB72B\xAB8e\xA9\x8AU\xA3ߊU\xA1* \x82Ӛ
+\xA8\xA0\x80l \x90\x84ܐ\xDFD\xDBN\xE77=\x97\xE4\x9Cs\xEFy\xEE\xBD\xE7\xE6~\xF2\x9C\xF3<\xD7\xD9\xD6 \xC7i\xE1jm\x87\x8E\xFAk&\xC4a\xF8\x97\xA8=['\x9BL\x99\xF3\xC9g\x97W\x9B\x81\xAE-\xBBs\xECNp̆\xD3\xE1ӴIY麤\x83\x8Eu
+%\x86;Z\x9A\xCF\xF8\x8C?¨\x83\x9B\xAC\xEA\xEA\xF1F\xCF1Cu
+\x8C\xF4
+\xF7\xE3\xF47\xD2\xEFg\xC81\xB74\x80\xC0`\xDF]\xB9q\xA1\x8E\xC3l
+0`\xE8[#\xB8\xC3߶\xEEd\xF7ׂ۶\x83\xEA#\xB2<挳j?ҦNJ\xB7\xA6\x86\xED\xDD8g\xCC\xE6\x9B{\xA2\x93\xF8\xE3fƟ\xB9\xF9\x81\xAF{sY\x8D\xD9W\x88\x93@ \x84\xD7G[K.\xAF\xDA\xF4if絘̑ \x8B\x89\xCE xL3\x86\xAA*\xF3\xDAs\xAF\x89\xB6\xAD\xF3\xE3\xA3\xDFu
+\xA0\xB9\x9A0)- 0\xB4qm\xF3\xE6}Eѩ\xAC\xF5\xBE\xC6\xEF\x8E\xD5=\x94\x90\x97\x98\xD9\xEA\xA1\xED9m$}\x99\x95 \xF0Y\xE2\xEA\xA0\xC90d\xE0>Q/\xED\xB2\xF6\x94\xD1/2q
b\xFE1\xB4 L\xB6\x9Eֽ\xEF\xAE\xBC\xA9r\x9Fl\xB7s\xF9#͔\xBB,+\xB5\xE4\xF1\xF3\xBA\xB4*\xA4\xE6\xFF\x94B\xD7(T`i5^\xBE\x97d\xEC\xE2?\x86
+@\xD5\xF0,5\xFB\xDBQ\xF2}/
3e 贺+M'l\xBF\x9A0\x99\xBF\xCD\xF2F\x84w\xE9\xE6\x99\xC1\xEFq c\xFC\xB6\xDBll\x9E\xAAɳ\xB4\xEED\x91\xA3Fy\xF2X\xB6\xF0\xC0\x83^\xE89c\xA7\xE0l\x91_#9ԝX\x9F\xE5\x9F\xD5l\,\x98fL\x80\xD9\xF8\xE0\x85 H*\xEBZ=\xB9\xC6vN
+\xD1u]\x99\x91'
+\xB5\xB9_\xC7b\xBA\x9F\xE6J\xD0\xCDY\xF5\xA0\xEB
+sh3ĝ\xA0\x87\xAF\
\xDA_!ott\xE5\xB9bL \xFE\xF09\xFC\xD6q;:(\x8Du+\xAE\xAE\x99\xB9&{\xD0\xD0\[/}\xF6P\[T\x9CU\xCF\xA1O0l\xC7\xF8\xF6V
+Ư\xEC@\xADV-j\xB5Z\xADVk>w(a\xB4\x97A\xC5Д\xA9\xD5\xEA\xB6\xF6j\xB5Z\xADjiiA\xADV\xD14M\xB7\xA8h\x95J\xD9XS\xFE+\xAD"\xFA\xC1\x91\x91\xB1\x83\xA1\xB4\xB4\xB4( ZZ`0CKK\x8B\xC1\xE8\xED1'\xAE2\xE9\xB1NV}\xFA\xAA|\x86\xAFe\x87B\xF4\xED\xD4"ÉÇu\xC90\xD9\
\x9FX\xB7p\xA9]\xAF \x81:o!U((&[\xAF\xCBLc\x8BL\xAA\x84\xBE\xAEދ\xB5\x9A\x8Aӟf\xFD\xE4>\xF2ᆭ}\xE2\xF6\xB5'\xB4\x91\xA1)G\x87\xA5\xAB\xA3\xAF\xAF\xA3\xAF\xAF\xAD\xA3\xAD\x85\xEA\xC7η\xB5\xAD}\xF5u
+ʐc\xD0\xC5uE7\xD57\xC0\xC0H\xFFEq\xDD1_\x8B[Kn\xEE\xF1s|\xBDs\xA3v<\\xBB}A\xEB\xD4|\xE1\xE5\xC3?\xFC\i5j\xEEL\xCF\xE1U7\xF283}
[=\xB9t\xC9
\xB1\x89\xE7\xC6Ѥ'
+\x98\x8C\xF0\xE5OuҜ0\x85\xE8\xEB]9\x93\x97N3l]\xDF at In
9\xC7\xDBf\xAF\xFB(ʖk\x9BZ\xB9\x90k\x88\xF6\x96\xFB\xF8\xEF\xDB>5\xE74\x90\xE6\x8A
+4^\xDCԱ
\xEBß\xA0\xDFո>\xC1\xB3|\xF3\x85\x9C\xFD-\xC6hiSE1\xB4)hQZZZ\x86\xB6f
3\x86V\xEBj-ڭ\xA3Z\xCD\xD0\xD4Zй\xE4W\xA3\x86\xBA\x97Z"1 \x81\xF0?\xCC\xEF"1\x836]\xFD=l\xFDo v\xE7\xE4\xDFu\xFFM\xA2ϙG\xE3E7\xFF\x8B^\x90S/:u\xBA`j\xC0
Ϋ\x9B\xFE*\xFEl\x93L\x94\x81\xF0z\xFC\xDE:\xAC\x8F\xA8\x9AuMZ\xA6F\xCCW7\xFD\xAFAw\x98\xDF\xF9[\xEF\x9B\xFD\xF7\xE8K \xFD
\xE7\xBC\xA6K\x95\xD0H\xB8\x81 \xB9\xBCCT(][ZZ\xFB\xC7\xD9B \xFE\xBFA\xA5\x90\xABhZE\xD3*Eo\xA9Uբ;\xE2\xAA^\xBC\xBANt\xE3N\xD3K\xC5\xDAꚪ'O;\xB7\x94ז\x89\xEE\xDC\xF9Eѹ\xA5\xAA\xB1N\xD2\xF8\x86\xF9
%\xA5w
+\xCB4\xEE\xB7*Q\xEE\x93\xFA_\x95R[\xD7\xC8\xCC\xD4\xF0\xE5r\x95\xA2\xA1\xA9\xD7\xD3\xA0\xA9\xBE\xAE\xC3q\xD1Or\xAF>\xF9]co\xE8\xAAB\xD1/M$
+\xE6\x9BB$\xE6I\xE9\x8F'/\xE4w\xFA\xDE)\xCF9y6\xBF\x97o"\xF9\x85][N\x8A\xA5\xBF\xBEky\xE9٠-g\xBB \xEC]\xBA?(\xF4BwA\x85}\xEA\xA2\xE8\xE4\x92Г\xBDn,?\xEA
y\xE1\xB7^\xF6@\xD3RiO\xDD\xCA/D\x86v<\x81\xF2*\xF1\x95\xE4H=\xBD\xE9?\xB6\xA9J\xA90\xC1\xC6\xE6\xDD\xE4.\x9Cm\xA5\xED\xFF\xB3g\xCF^\xC8\xE9\xE6\xD4\xCB\xF3\xBD\xDE\xDDU\xF4\xF9\xC9-\xB3\xBD\xDB =)\xA7K#;\xCC=پ\xEF\xF7\x87.
+
+
+
+
+ݲ%442\xA7@\xF9ɣ\xBA*b\xBA\xEAB\xF2Yq\xED\xF6\xBDHӴ\.\xAF*/\x97\xBE\xB9 \xD2{99\xE5
/\xA3\xB44'G\xFC\x86c\xF1\xB7\x86.\xBF\xBAdWQ\xAD\x91\xDE\xF5\xBD\xF7_b\xFA\xCB\xD0E\x91\xB3\xFF\x8B\xCD\xFBo\xA6>wW\xE0\xECM\xC1\xFE\xAB\x86qܹ\x9C\xCCj\xBA0yAT\xEA\xA3-h\x85B\xAE\xA2!y\x98\xB2<\xE5'h\xA0(JX\xB4"\xA1\x8B\xFE\x93T<*)\xFA\xA5\xA4衤KE;\xAA\x82\xED\xFE\xA9\xDD\xDCO\xF2_\x92O\xFFR%>
\xBA:*t\x81\xAB\xAD\xFE\xA2\x99\xB3\xB7o\xBB<\xECT\xE7/ \xFA\xD2r\x8B\xAD2\x91\xEE\xA4\xE4\xEAs\xC3m\xF5\xF9\x8E\xED\xF8\xCF\xD5vu\xC7\xD4\xE6?ō\xBF\xAAy.=M\x98\xF9\xD1s\xAA\x9B\xF9Oq\xEC\xD8\xF5\x82\x87=X\x8F\xC1\xEA\xF5\xC9wz\xAAm\xA5 \xD6\xFBPv\xEF?\xEF\xEDs\xB2\xB8\xD6\xF6>#Q\xAC\xFF\x9C\xF7\xDE\xD9\xF0\xC5\xF7\x9AsF?:{\xBC
+P\x95\x9E\xFEZ 꽯\xEE\xA0U]K\xE4i\x9Fn\xBAz\xEB\xF0g\x89\xAF\xB0\x9C\xD0d\xA2\xFC\xB7B\x9Es\xF2X\xEDp\xBE\xCFH\xE3W\xB7\xD5P
\xEB1\xBFZP\xE2\xE3\xFC\xA2\xE8Y\xC6|\xBE"[\xEDl\x{1A2226}iP\xEDw\xF4\x83MQ\xF5\x9E ȥU%%\xCF\xCC
F\xBF\xD15\x94e\xC7}o\xBDgX\xBD4\xA2\xF4\xEB\xE3\xF6\xE6.
+oO\xAE\xFB
+\xE4\xE2]k\xCF\xCEڷ\x91\xCB \x96\xF5P\xE1\xDE\xF5w#湱{ڀ5\xDEk\xD4\xFCM'ߟ\xB0DVp;\xE3\xE4\xFEk\xC3\xD6hNGU~\xF2\x8E\x84\=\xE0\xE7+{B\xCAԳpv\x94呸\x9A3n]α\xFC\xDE=^b\xE7\xB2CBI\xD0ȗ:\xA6KN\x87\xEF
7?\xEA\xC5!JDS\xFCO\x86\xAC\x80ǻGeWX\xC0\x9D\xEF\xCF\xF0\xC3|\xBE\xF6\xF5EH\x84\xCF ]϶\xF3\xCBH!\xBB
e^\xA8tc\xBF\xD6 \xA7i9M+e29-k\x92\xC8dJ\xA5R\xD9TW\xD7\xD8X\xF1Xg\xF4Lo;6 +ϖ,ض\xCFӈ\xA9\xAC\xCB୪V\xD2\xD5y\x82aۄ\xA1F \x9A\xB2\xAF(o}H\xC5g\xB4b\xD5,3\x94l\xE6\xF9
+\x80\xBB\x83\7b\xD7\xFCM>\x95S\xA5R\xB0\xDB-\x93=\xF4\xF5\xE7\xA7U\xAA_\xF6H\xD3rZ\xA6\x94\xC9崲\xA9IF˔Je}}]cEE\x83\xB9\xEB,7k t\xED\xBD\xC4\xC53\x96\xCD2{\xE5Q\xCB\xEF\xCD\xD6\xE3 :\x97-N\xBA\x9F\xE0\xF7\xC2
+\xBA\xEAމ\xEF\xEF\x9A\xBC\xEC\xC0h\xAE\xA9\xD1\xF1Z8\xEB\xC5@\x93\xFE\xCCswO*\x94\xF9\xD9i\x8A\xA4\xC7\xDD\xDD\xEF*\xEC^w\xC0\xD3\xE5\xB1\x8E\xD81\xA9\xF31\xC8\xC5'\x97o/\xFFg\xFCk\xEA5m(f\xF3\xDEĤ\x851\xED\xFArg\xB0q7\xFD\xAE\xF2W|\xD7J\xEF\xC5rx+\xBB\xAB\xE1\xF1xB\xF0]N\xD2|e\xBCz\xBC\xBD\xA5\xC1\xDD*)
+r\x9AV*\xC1f\xF7\xED~\xFF\xB3Cg\xED\xF7\xBA\x9FO\3\xFC\x90m\xB1\xE7ހo\xC7pnM\x8BM;@\xF3I\xCC\xF4m\xC1)(\x8A\xBE\x98\xFA\xB9\xE54\xDBƆs\xC8ڽ\xA9ff\xA3\xB8\xF8\x96X\x99Z\xFE\xE2}\xDD\xF5w\xBE\xFCp\xFC\xD1, \xB0\x9F\xE6Qx)s\xD1\xF3\\xB5E\xD1\x8D3\x80\xDA\xCCB`\x93_F\xEBFuY5\xF3S\xAF\xCC$\xAB}Z\xAB\xC7ҁ\x99\x93ՙ@\x93TQXEq\xFF]\xF0x~xё\x81) (l\xDC\xFA\xBD\xCCuH\xE3\xB7Y@\xCC\xC7\xE2QF\x96\xC8\xF3\xD3{\x9C4\xB0\xD0\xC4ݺ\xFF\\x98\x89\xAAu6\x87\xD2խ\xFA\xDA7D\xF3\xA3C\xF1\xC9@\xF12\x9DU{\x98\x9F\xFF\xA2\xDCХ\x96h\xCC\xFAd\xB7Gۍa>ҷ\xEC\xFA#`h\xB7'K^\x9BS\xA6x\xBF\xA7S\xD9T_\xA7͒\xDD\xC9\xE9\x8E(\xB9s\xF9f\xFFI3w\xF7B\xF3g\x97\x9Et\xCFĔ)\xEA\x9BC\x8E\xD3.\
t\xAD/R<\xBEt\xA6\xDC'\x8Aڒ\xBC\xD2\xC1\xF4\xF12\xB6Q\x98\xEC\xBF\xE8\x93s/;m\x9E\xAC\xC7\xE8\xA7i\x89\xC7\xC4UO%\xE5ϫ+\xCA
+\xFB\xD5]:W \xB0$n\x98\xA6\xFDҖ\x89\xD9ң\xB39\x81\xEDOK\xAF\xC5\xF1\xFFG\x80\xB7]\xAF\x9B(s"\xD7\xFAg\xABG\xBA\xF5\xB5\xF9\xB3l\xF0\xB6M\xB2\xEEX\xA6\xCF\xF2\xE2\x81 H\x8B\xC45\xD6\k
+\x90\xDF?\xAC\xC7[ \x80\xC7\xE3p7 \xD74\xE7\xA5\xE6\xCCk{\xCAɥUe\xE2۹Y\xD7\xF3\xEF\xDD\xCD\xA6\x85\xE0y\x85\x87\xAC\xFA\xDB,\x8B\xF6G\x86\xFCޮ\x88\xD41\xF3|k.ϛ
+ymyY\x85\x8Cccg\xD6\xEDC\xC5lBB3\x8A\xB7v\xD5t=
PAƦ\xB8\xA7bHsN\xC6GE\xAE\xEE
\x86}{\xFE\xB9¹\xBD\xBA(r<6P&)NO`\xC3Y\xCB\xF3Z<o\xC1\xE2\x8Dsy\xED{c\xF5\xC8
5\xC1\xDA\xE4a\xD4^`\xF1\xA11& k\xD4\xA2N\xE4\x9F r\xEE\xD415\xF8\xE1\xFD\xE83)=}\xD9\xED\xE5\xF6S+\x92澬/\xA0)\xBC\xA5\x96K\xE8\xAA\xFC×\x91\xEF\xBD)\x8B\x9B\xCFg\x90\xE7^\xFD\xF7B\xCF\xFDQ\xFCϢ\xB7r1+\xEF\xAC\x8D#\xDC\xCB\xFB>}\xC0Kw]\xF3$
`v\xB3J\xEB\xCDY\x99ޱ\x84\xD7z[ I\xB9\xEFm\xC7(]NzL\xDC\xC1|}\xA0)\xA6\xA1\xA0\x98l\xC4\xC5
\x84>\x80\xA6\xA1\xE9MGʆ\xEC\xB8M\xFA\x9E\x9EKt~ \xA2L\xF6\xFEa=_\x84\x94\xA87>\xDE?\xCA\xE5p\xA8\xECn\x80\xE6\xC0\x98L/x\xF4\xA6\xA4\xB1\xB39+=V\x87$ݟ\xE5 \xB2\xE2\xD4\xC0\x95\x90\xCD\xEAx\xC4?\xEE\x8Cê\x845\x9D\x87:e\xB3\xAF\xA4$F__\x8FŦ*\xAF\xF2\xED}\xD3CRb\xFC:\xA9\ZR|\xE2\x9Blˮ\x97F*L\x91\xE4.\xB3\xE6\xB6\xCDdz\xC1\x8Bk\xD9\xE1\x98,\xF0\_>\xFF\xAF\x86b\xD6_\x89\xF2Л\xAA\xDE\xE1ݱ\xB8\xE2\xC1\xA5\xC4\xC4\xC1_$\xBC\xBEm \xD8\xBC\xD0k /]z4*\xF6\x81 {\x9C\x8E\xF4\x88
+[\\xF4 \xD3\xD3C
+\xF8[\xC2\xDC^\xAD\xD9_\xA0g㓗\x97\xC7l
dL\xA6>MMJ\x80\xA9\xCF,_\xE70E\xE0=\x88
+\xF4u\xBC\xD1E[\죄\xE8ʀ\xF6\xEC\x95-\xB9\xD2\xF3\xCFBB;Ը\xADDr\xDCmp\xB4h\xA1\xE7\xA0)\xEF\x9C(<\xB1\xF9\x80dz\xC2@
+\xA0\xE5\xCCO,xW\x9B\xA2$w\xA27eNܹ\x8C\xB9\xC9q\xFC\xEAb{\x96\x82\x86.4\xE6~\xE8\xE4\xE9rT\x9C\x9B\xCC\xFC\xC26䝘\xE3\\xD5/_rGoc\x8A"\xF8Cu\xAD\xF9\xB1\xA2\xBAPTõU\x8BoG|j\xA2\x92ӠUrZ\xDB\xC0\xB0\xEA\xFA7qg2
+\xC4\xF5 f\xAB\xBD\xF7.\\x9Ep?~\xAE\xED\xF6'܋^=\xF1\xAB\x9B8\xBA\xB0\x9D\xBA%fb\xC5wcF
\xBD
8\xC6\x80\xB6\xAE\xA1n\xC7\xD1G\xE2\xF2\xB2\xD2_ꕚT\xE6\xB3\xBEJ\xDC&\xE8\xEA\xACd\xEEi\xF1q*\xFB\xD3=\xB72!J\x89\xBC\\xEA\xD14\xC5\xFC)f\xE1O\xB5\xF2v\x89i<|b\xA1\x96d\xC3d\xDDPr\xFB\xFB̂\xC1\xFE~:/KvO\xF1\xF4
+\x99\xBB\xA6oMc\xF8/\xB8\xCC\xF4\x9B\xDA]\xAB\xEA\xAB3\x97;z\xE9-}@Ϡ\xE2\xCA\xF8\xCD\xC7\xA4\xA5
\xEF\xA0\xA3c \xD0\xED\xE0_\xFB\x{1D2BBD}ۖ\xF1
\xA0\xAD*\x8A\xE2\x8E6t>\xF9\x81\xAB\x8F\xA0c\xE1<y\xA2\x9Bchf"\xFF%e\xFE\xA5s\xBE\x9B\xE3}\xED\xAAS\xB3h\x80H\xCCn!\xB3{`ž\xB4Ŏ
+\x8F\xD2\xA7$VfVn\x9Cd\xD6\xCB&\xBA\xA6\xF0\xEA\xF7y\xE4e\xE2t\xCCK4\x86<\xBF\x9E\xCBZ/>\x9FIqq\xBAP\xE8\xC2\xD8x
\x92\ b\xAC\x91A2\xC9{R\xB9\xAC\xA9IɄ\xE4\xB0
+\xA9\x85\xA6Z\xB3:\xDEFt\xE9\xA6M\xABk\xBF\xC2\xC7{\x8Aל\xC0(c\xA3\xE6
+\xE1\xE7|\xBE\xE5\xCA\xF7e\xB1\x9A\xE7#e:Ԩn\xFFz\x9E
\xC0N8 \xF0\xE5ummp=B\x84\x9Br\xE5\x9DY\xF2\xDA{7\xD2\x86F\xBE
wuM\x8F\x8AS/W\xB9x\x8B\x9EC'\xA5
*\x9E\xBFrSv
\xEB]
N-\xCB\xF3Ѽ
\xCDdvX\xD8}}}\xA6\xBE\xA9\xB9\x898\xE1]\x8F\x9FB\xF2bgѵEO$2\xFD\xB8l `\xDBy\xD9\xE1l(\xFCC5 A\xC6 `=u1\xA2V\xBA\x9C\xF5Qβ\xEEp\xF8\x941\xB7\xD5y,\xBF\xAA7E\xB0"I\xEB\xD7\xE9I\x97\x9F=|\xF2niq^\xF6!\x84\xEE
\xE0u(31h\x92i\xE5J\x97\x95a\xA9\xCAX\x9F\xD6\xDD\xE5\xFF;"\xDD+T`ݏ
+\xC1\xE6\xA0 s\xA0"[P|eI\x83]G\xF5\xF2D\x95\xAC\xFA)\x90..\x91;s\xBBh:\xBD\xA9{\xF2\xEE\x9B4\xE5\xB0\xD9zz,U\xFE\xE3~K\x8F\xB5!\x87R\xFEbm\xF8,\xF3Й\xF2zMC o\xDE{3F5\xFAq\x81\xD0\xCA2x\xBD?c\x86 \x80\x86\xBB\xD9_kf\x81\x8CG\xFAݭ\xC80qߋ\xC5\xD95\xD1,l\xAD\xC9|`\xB2j\xEDoA\xA2\xF7}I\xC0븞\xF4<\xC32\xF3>\xB3hj\xD2j\x9C\xF4^\xF2d\x9E\xBFmD\xD2\xE7\xAB\xE6\xDAwv]\xB6\xA5\x9C\xBC\xA6$\xF2ܧL\x97h.\x95\xA6\x98mm\xCD@\x97^\x98n\xEF[
&\x90\xED\x98\xD5\xC5$\x96ݬ3Wf\xE1%\xAA.\xF4\xF8\xEAM\xEEz\xA1T\xA2\x93\x9B\xFDea\xD4'̖\xC7\xEF\xDB\xE4\xF2Ϝ0\xEF\xCAI\x9A~$\x8E\xB7/\xAF\xFD\x96~]\xDB 0{\xC9@#{\xF6Mx\x94{|\x92\xB3\x9Aᘒ\xC2Gss3t \xBD\xEE\xBE\xD7zi\x88\x9B\xD9k\x888\x8Am\xED\xEC\xAC\xF9-J\x97^\x88脭\xF1\xA6 qr\xB4 \x8B\x85Q\xAD繏\xE3\x8DÏΜgfԏcj\xA2ϔ45qL\xF0-/\xF1\xD8TЀR 6ї}\xA3Jt\xEE\xBB#
M\xAB.\x8B\x95\xB4siu,\xE6\xC7T\x8Ae\xBE\x8CƙZ\xE87
\xBB\x95\xF7h\xC71\xE3<
+\x93\xFF\xB1\xE8\xBDc\xF3\xCFU\xCEude}\xE1i\xB0\xFB\xE6\x9EV\xA8\xBE\x94\xF7@
+\xA0\x86\x94\x9D\xE2\xEA.X\xCF\xE5P,\x83z\xD1M\xD1sv?#\xFAy\xD6-q\x81\xF0\xF6uS()\xF6pG\xEE \x83=\x83#&\x8C\xFF\xFA\xF5\x81\x9FyZr\xE9\xDC\xE2m\x87\xAD\xFE\x9B\x94\xBB\xE3\x95O2\xD6q\x9D\xCC)m#\xED\x82\xC5\xF6gv'\xF5\xF7ӈq\x96\xF2\x921s\x9C\x8F\xAB PL\xE0p\xEA)\x93v\xAD\xA6\x8B\x9AS\xC0̶\x8F\xE3\xCC\xE9B\xDB\xC6*# 0cڪբ]\xBE\xAB>`\xCC\xE9\xD7\xE9t\x98:\x80\xF1IAF\xF21\x8C[\xB8n\xE9\x9AN\xB5\x8A~<'\x9B
N\xA4\xA1\xCF\xF6\x9B>_Z\xB4\xB8`o\pS\xEE\xE1\xED\xBEc3\xC4" \x9E\xDBo\xEC\xF1s\x80FQԘw\xE6ƈ\xE6zj\xBC\xA45\x87\xB1h\xF3;\x9D\xC0\x9B\xDF\xE4*\xB6CQ\xBA\x9D\x91\xA20\xED\xB6\xA7\xB5\x9E%]\xAB)~mY<+.-\xF2?\xBA?\xBBi\x9C\xE1\xF5
\xE3
+\xB8\x99\xA7E\x95
\xBBY]J \xB3G\xBC\x9C\xBD\xBC'\x8D0k6\xAF\x98钔\xF5p\xE3$3\xD0E\xBB\xE6\xAD\xFCY\x82\x97
+@^zvy`\xF6'\xE7wpY\xD0\xE5 \xFD\xF8\xB7\x91\xE2\xB5\xE1{\xD3\xC1[\x9C\xB7\xD3\xCF\xCD\xE2^\xF2\x96\xB5։\xB1A\x9A\xE4\xB3U?-\xF8\xDC3&\xC1\x8F\xCBV\xD6?\xFA\xB1ֈE\xF7\x85\x9B\x94J0\x99\xE2#\x81;g\xEC\xBC>\xD5~i\xE4\xB9\xB7\x9B\x8C\xCC\xFA\xF7\xE30)%xx\xF2\xAC \xF7\xF2\xED۹\xD7\xA7\x9B\x9C\xBA\xB8Վ(s~J
+\xF4\xF8Qv\x9D\x9F\x84Γ\x94\x93B\x99\xF6\x9B\xFF\xBD\xEAL\xD0H \xA0,\xE6m\xDC1ocD\xEC(f}\\xCD\xC6W\xB9'-\xDCfB8eyPjb\x9C \xC0\x8A\x88}\x8E\xFDzl\\x92\xF7\xDFk\xDC^7\x87\xA8\x90I\xF4<6}\xEFkxqG9;\xBB]Ɣm畱\xB3(h~c*\x9B\x9A\xAA\xCBD\xF9\xCF\xEE\xFFT\x8D8>3 \xBCV\xEC\xFBjً
\xD6\xE6\xEF\xE7\xEF\xF5ʮ j\xB7\xD2l\xCAb$&\xF2m>ʓ\xC4:wy\xD6懚\xB8\ K\x91\xEC\x98\xD7\xF5IWg_+\xB6\xE6{\xB9|\xBFW"\xA8\x8C\x98\xF4\xEC\xFAW<\x8F\xE0\xF1\xCA3[k\xD2\xC2M\xA6$\xBE/ \xE0\xB2\xE5\xA5g]V
+\xC0\x9B̈́R
+\xDE{\x8BW\xB9Y\xE9\xDF\xDE[p\xDDu\xD5*\xB7~\xCA\xFAygJ^>j\xBA\xA9@j~\x99\xB7\x8B\x9F\x9B\xB2s~!\xDCk\xF3c-=\xD6\xC6kF\xB2\x93\x970\xA3\xFB\x87\x99\xAEu?:C` \xB2\xE6f@&^\xA9\x99o\xB3Y\x96{RC\x9E4@s\xB3m\xEFɠk\xEF\xC5l \xAF\xB7\x8A\xFB3*\xE5\xFD~\xCBK\x9E\xC0\xBDI*}
i at q\xDD&\xBD8\x84\xF2&<\xFF\x88\xB4\x92\xAD\xDE\xD6]*\xE13)\xD0q\xD7\xEC\x91\xD9;\xA3\xDD\xC4\xF3\xEF\xAE\xE92\x80\xAA\xF2\x8FNu \xE4\xEDK{@N\x83o\x98\xDAS\x9B\xF6\xF2vf[\xF4\xD9\xFA\xD7\xC5ؙ\x82\xB5(r\x9B\xD7v\x8Dj\xEFD\xFAو7\xB6\x8D\x83\xF4\xC0\xC0-\x91\xAB\x96Mw\xEBn\xB6\x9C\xC9\xBC\xE6-\xF6s\xEEr\xAA\xFDW\xDEu\xB2\xE9p:\xE9\xAA+糚ut
\xA0\xB9\xB9hn\xD6\xF7\x8Ew\xB7\x8ENY\xB50|-V\x8FΉ
+\xF4
+$ݗ\x8C\xD4t\xDF\xC7\xF1f\xE6\xE6m \xD2{\x91Kx\xE1O\xB6W\x9E \x8Bb\x81Xd\x92\xBCo<I]=g\xBF\xDEW\xD7J\xD7W\x9Dݓ\xA2<\xFE\xC4\xC4\xF1\xEF\x9C\xEF4\xAB9\xEA\xB8m\xEE\xED\x88yK\xBE-^@Rt\xF5˩ǀe1\xA9\xAB\xE91\xBDA\xD1G\xB4\xA0\xAE\xE0\xC6̀\x8F
\xD4\xFEr\xADp\xE9D\xCD\xDDdd9
5\x86:\x80\xA6eϋ\xD3\xD7l۽h{\xD2\xE7_q\x95ϟ\x9C
+L\xF5K\xC9\xDE>\xA3\xD5m\xD6TZ\x96\xF7\xC9\xFC\x99\x8B\xBC\xAD\xABk\xA1\xFF\xF8ɓ~ \xA0\xA8(\xA81\x9F\xE2\xE4;\Q\xF6}МH,\x8D߿\xF1\xDD\xFAs+M4`?m\xD5k<4GB+1\xEE@؆e
\x8F\xCE\xE4\xF6\xCD\xCFi\x8A\x89\xAC\xF5\xDB"Kp\xFF\xE0\x98\xCD\xFF
+r8\xE6;\xE0\x90Y\xD1G\xE3A\xD7\xC0\xB0\xDD\xD3A?=\xF7\xA9\xDDQx\xAC\x9B\xB8lӖ8\xB3\xAE\xA91\xA0\xB9\xF3\xBB6\x9B\xCA~\x91\xD9
+lkYu\xFB,|\xEA\x8An+\xBDޟM\xA0X @?\x8Cr
[\xBD=c\x8F\xAFF_\xAA\xCAN\xAF;\xB30e\xF7\xA0\x8E;T<\xBE\x9BN\x97\x8E\x9BJs\xCBY#\xED\x8D\xC4\xEB\xB9\xE33\xBA\xBF\x923\xE3EǻK\x9F\xD4p1b\xBDo\x8C\xE8\xA54F\xF2[\xF9\x93JǙ\x98\xB0)f\x96xH\x9C\x97\xE8\xCB\xEE!\xF3\xD5\xD4
+\x85 \x84; d\xF5\x82\xD9\xE1\x9A[E))IL\xCF^\xD5\xEEkI\x8F\xAA\x99\x9D\x94\x99\xFD\x{1EC0E1}\xFE\xEE\xBE&\x95yF\xBE\x95\xEExx\xC1ܭ\xDEf ~<\xB4*.\xDD=\xB4\xED\xE31\x9A
+\x80e\xC6
\xA9q\xA60mM!`\xDC\xF9\xC1\|=~oz \xA0:]\xDE7I\xFA\xEEo\xD9Z\xBB\xEE\xFC;\xB7-c\xCBm\xEC\xE6\x86aU\xBD&Q^\xF4\xE3\xA9\x83\xC9uDž^\xDB\xDEb\x83\xA6\xA52\xE4%\xC9\xD1gF\xAC
+\x9Bdѩ_\xBA*?j\xC1 0\xF5μ3\x8Ek\xD1\xFBpQ**၂\x90Y\xF4< Z\x896G\xD4\xF8\xF7\xC1A,\x8D\x9De@^\xF2mT\xD4cs\xF3\xFE\xA6\x83
+
\xE00\xE7`\x8A\xDD\xE7\xF37\xB9T\xAA\xB7v\xF6\xCB\xEB\xD7\xF2\xE3\x85
e\xB0RR\xE6\xB5/5䙯\xA7"\xF5~\x82O\x9B\x8D.\xBD\xE2b3E\xF0~N\x9CȘ/\x84Wؾ\x90U\xC1\xB34\xB3F\xEEH\x88\xE4\xB11\x9B9Όml6\xD5\xD7\x9Ad\x80\xB1w\xF6N\x9E\xFB\xE6\xEF\x9EYxl\x9F\xBFs'n@ H`\xCAu\x86\x82\xBB\xD5\xCFӟKk\xEB\x9B:\x8F\x8C\xEAί\x89 y\xEA\xC1\x93\x8B#Bw~\xF7\x85\xDFƞ\xBD\xDC\xE5]V\x86JF\xF0\x8B\xC9>\xC19\xB82X\x8D,z IDATヒ%\x90)\xC0[0\xBB,tޮb\xF60\xF6\x91]\xAB$\x96\xBCa at AY\xFF\x90\x8Bы\xA3S\x94\x9E
+\xB5\xE1\xEF\xF5\x8AH\xCA9\xC9\xF3\xF0\xB7ܗ8\xF8\x9FS\xFC9;\x932\xF7\x8Cl\xBC\xB6\xCBŒ\xD3e\xE1\xE3Kе\xB5\xB4\xB1\xF1\xCB
+B\x9E\xB8ؗ\xB7/\xBB} \xB0\x87\xB9\xF1\xB0\xE2\xB1t\x87Eg\xF9\xEA\xF6a\x9C\xD7&\xF7\x84\xFC\xC05
\x94~~\xF2\xFF( \xC2\xC3S\xD7 x+\xC7?\x9B\xC5\xED헌\xF4މ\x95BR]:\x95*\x95\xD5H\xAF\x90\xD2h[`\xDAu%\x82\xFC^\xA8WO\xD3\xD5\xE9գ\x849\xD1m\xF2\xCBz\xE1N\xAF#\xCD/^i,N\x8D"bFw\xBE\xC9W\xDBֆ\xAD\xFEc\xBE\xBB=\xC0?\x94\xEE\xE7\xD3\xF9'\x8FR\x99\x8E\xF4FYgm\x94\xE7\xFD \xF8\xEDXHW_OIyҿ\xBF~S\xF1\xDE8oq\x88w\xFF\xA6\xE7\xCF\xBF5\xBD{\x89Yr\xED\xF8#"\L\xF6
+\xBDR\x845\xF3\xB8\xDD\xFE\xAE\xE8e\xBCi\xB8\xBF6\x9C\x9DT\xA3\xF6\xA3\xC4\xC9
q\x99ܹOK O\xDB\xF2U\xBF_\xA8\xAA\x92Dž\xBF\x945
+o\xA8\xADױ\xB1\xFA\xF1#Zg̪K\xFC\xB1\xC3Aו\xDC\xFE\xE1\xC8{\x81\xA9\xF0\xDB <\xDD|\x86\xE7\xC9\xBE\xDD$\xBA\xE9d \xD0\x85\xE2zg
+\x80\xFC\xDA\xC1\xDDA\xA1\xAB4\xBB\xA6OK \xD05w\x9D\xE0j\xAB\xC8\xF9Rj\xFB\xB1\x9F\x93B\x9C\xB0\xCBR\xB6i\xF4ea\xF2\x82E\x9F\x9C,\xC8\xD80
+W\xD7\xC5\xA7n
\xA3\xAF\x93٬g\xEE\xFF\x96\xBDP\x950q\xFEģE\xDFzg\xEE\xFE뺘Lp\xB7\x9E>\xD6i\xA5#\xC5D\xD6\xEA\xF0\xC8_\x8C^ɾ\xCDB\xBC\xC6%\xB0\xEA\xFD\xE0-\xD4m\xEC,`\xB801\xC5u\xCC'\xFC\xE2\xB8\xCA\xEE\xFCViUw*\xD8.\xC5Q\x90V<\xAD\x97\xBC\x92]2\xBA?82z\xA7\xDD\xCDo5\xD9\xD7i\xE1\xF7\x87\xA7\xFC-\xA0+˞\xBA8r:Y8t\xED\x9Dr\xFD~\xED>\x8D\x9F\xE8\xEF#\xB2\xE9|\x83\xD4߷\xF7}_\xE8w/O\xF3\xCC]"\x8E\xF0u\xBFU\xFAR4O+L\xFD\xEE\xD2'\x9E\\x91\xB5\xE1|\xF2\xCBKK\xE5\x95
+\xA7\xB8h\xBE\xECm|\x83mz:`\x91\x98=\xC2Az\xCC\xD6%\xF9lT\x94%
+ҽB\x92\xB6\xBCc
+\xBC\xFC\xA0\xD3m/SH\xC0ۗ\xBD\xC6\xC0\xA4Q\xF1]Ng\x94\xFA\xCC{7\x9E\xFA\x{DABB}k\x8Ck\xFC4\\xB88\xFEx\xEBs\xAD\xE6\xE1O\xE8\xE7VUZ\xF3+!\x99\xBA@\xD7\xD0N֬\xAD \xB3\xB6j>\\xF5 4~
+\xB7\xEF\xAE6+
+\xBC$\x8D'\xAC\xA2\xF4\xF6k\xFD \xE9&\x9A\x839\x94W2L/\xDC÷_\xE5\xDD5\xED"\x89.\xBF2\xDDrJ\xFA\x8AC\xF7\xBF[\xC6\xEDkH\x91@\xEAR\x93\xB0%\xB1 Al\xA5\xB2\xBA\xAD\xA2B\x94^\x9BC\x875rǙ3 \xA4U\xA5e\xCF$J\x809`)\xFC\x8F\x93\xE7wRH\xF2\x92\xB4t,Mt\xE8\xD8\xA8\x96\x98\xB5C_\xBD\xE4Y\x9B`\xA8\xCA9:\xD5=P\xF0w&\xAD\x9B\xEAl#{|+v\xDF\xF2\xF0\xBE\x8EG\x84\xAA\xAB+ӽ\xB2f\x80F\xFE\xB6\xE2\x8DMSN-\x\xB5f!\xF5`\xE1\x85\xD6\xE0A\xA4w\xB8\x8F\xD8wȵt\x97\xCBJ\x9F\xD9T\xBC
E\x9D\xF2O4ք\xBCn\xF3m\xFE\x87k\xBAzVې>> ^\x9CW\x9B\x86c\xBB\x9DQw\\xC8(\xAD\x93R>\xBBO:\\x9F\x9595/\x81Ű\x94\xA5\x95\xC4{XS\xF2\x9C\xD6\xD6\xD37\xEFoɵ \xC0<\xE4U\xE9\xE6\xED=Jă|\xEA\xCCI\xCEl8'T\xCE\xF8Di\xD9kx}?Є7\xFB~\xE7\xD9m \xF2\x823\xE9\xBC\xE8\xEFzYC\xACQq\xB5\xE2\x9C'\xA6.#[\x85\xDBm[<N\xE6\xAEq\xF6 y\xE9ѰY\x81{\x85\xFC\x90Ca\xAB掲4f\xB1(ZZ\x95\xF5\xDD\xDF=
LR˔>=\xFD<\x91\x8B\xD7\xF3V""mV\x97zC6\xED\xDC7\xB8\xC3\xED&\xADz\xDE\xC0n\xD6\xE0\xB9[S\xBCtu\x80\xE6\xAEd::hn6
\xD8a\x97n\xAF\xBC8BZ
ퟸ"\xA5\xB0\xB7\x85/\xBD\xD8 \x90\xC0kߗ g\xF6\xFC\xF3l\xFC\xBE\xAF\xCBJ\xF0\xE33\xF7\xB4/\xAD\xD6\x9A\x9D\x96=\xB4\xEBLzU⦽^
f\xE7\x80\xC5ݚк \xF4\xDE\xDD8ɞ\xF8讎Ϯ\xF3\xBC#\xA3ׄE\xD0\xEC
#\xCF^1\xDE @)\xAF\xF6r
i\xC0t \x80\xA2r)\x88\xC4|M\xAAK\x8A\x9A\x9D:\x87\xED%EE\xE5b\x8A\xA2 \xAD\x81'\x97v\xCC?=(\xFE\R\xD5\xCCc\xD0\xD1As3\x93\xA9\xC3\xD4\xE1X\xC2Vs\xDD(\xCB\xDC\xCC'\xCF\xE4V\xB5\xFF\x8A\xC8\xDAz>\xB9u\й1\xD3n\xF9 :j5Ǡ\x93\xEF\x84z\xAF\x8Ft+;\xD2\xE7H\xBB\xB4\xB2}7)\x97\xFB\xCB\xE8\xB5EY\xB7\x90y+\xF6/\x9F/\xC1\x9A\xE5\x9F\xCC\xFDJ\xEC\xC4`\xF6AA(:\xF3ηV\x97\xAE\x89tB
\xAFq\xBAD\xD2\xD0J`\xD9{\xEF\xAF2j\xF32RT5\x8E\xECy\xD1`\x9C\xCDS#j\xB0
+~ \x98\xFE%~w\x8D\xBC\xB1\xF6yq\xA5\xC6\xC8Ƃ\x94Kw\xC7\xF5\xA6/\x81\xFA\xE7M\xCA\x9F\xAE\xEF<\x82\x8Fo\xB5\xA5\xA2T\x88N\x9E\x99\xB9n\xB7\xAA/-\xF2\xBFt\xBA`r\x97\x8D;\xEA\xCBc~v\xB1\xB3\xE33|\xBB\x88\xBF\xA7\xDF\xE6\x9Fk\xE5\xD4e(l\x88\xC8\xDA~1\xD9
+ \xC7\xF4\xB7{GĂ\xD5K6\xD4uk[\xB7\xDB\xE8d
\xBBS\xB0\x9FKf\xC6\xFB \x91\x98= x\xE3\xE7\xCFz7i>\x80\xF7\x83\xE6v\xF2(0\xBB?o/
*T\xBFQ\xC0\x95\xFB\xE5\x80
?l\xDC\xD7
+ā\xEEٟ\xA7\x83\x9F\xF7\xAEFp\xCC\xED8\xF9\xCBm.\xAC\xAB9/\xB9\xB7n\xD3ZA\xEBR\xB3\xB0'\xB5p\xEE\xE4\xF6\x91%\xEF\xDD\xF5\xF5\xC9\xECj@(\xF2\x9F\x98\xBEl&ע/\xB3\xA2t\xCE\xD1͛\x80\x94 \x{1AD7ED}\xBD\xD7\Q\xAF\x814Ǜs,Fe %\x93\xA9\xC7bQ\x91\xCD_\xF1P\xBA\xA6}\x85X\xE6\xC1)\xE9+R\x94\xB1\xF3^o\x88\xF0\x93&\x8F\xB4\xFB!qʒ)\xE3\xBF\xE2\xE5yF\xB1!/:;k~\HjY\xBB\xC5Ң\xC1\x{1BE240}\xF106*\xA4eB@\xE8\xEF\xC0w\x93\xB5G/AY/\x84W\xA8I\xA7\xFE\xEB\xEA\xABm\x870v@\xEC\x99\xD6\xB98v\x80\xFBJ\xFEN\xC1\xE5\x8F;D=[̊\xBE\x9A\xB9\xD7dU\xC7#\xBAwj\xF8\x8Cz\xF9\xB4\x99\xB9
+\xF6
lB\xB1\x8C\x8D\xD19\xF7\xDB\xEBЎ5A\x80\xE7\x95\xEC\x8C\xCB\xD7\xF9#"s\xA4\xB153\x9E\xEF\xE0\xC5W\xEF\xE8\xC6\x88\xD6iSa\xCF\x85\xD8:\xF2ғ\xF1\x82\xF2g\x8F\xF1\xF3\xE5ģ\xB7\xD2\x9C;
#\xCA_4\x84m\xDA\x9FϾ\xCC\xE1\xBD\xE6pg\xB4\xC6|\xB9p6\xB5x
\x92\\xE9Mb\xD6\xE6\xA5
+\xC0\x8F\xB4y\xE9\xF8\x95M\xC5/\xFFtza\xDA\xD0yH\xBF\xF8s\xAD\x9B\x9B\xB1\xE8w\xBDl\xF5V\x8DXq\x9C
\xF7[U;\xBC̀\xA2Sk\xF7ڦ^
o"\xF9\xF9\xC1\xC3\xBC5\xD2Θb\x9BM
+\xF8lg`\x9C\xF0\xB1\xD4Ǣ[Gf\xE9\xFEw
\xE2V\xE6ݵ\x86\xB2\xF0\xDB\xD8q-\x97\xFCR|xI
4\x9B\xF1\xA4\x9E<\x{1EF03E}\xB5 !\x85\xB3{\xE0\xEBٶ6\x9Ad \xDBz֚X\xE5\xA2U_,\xE7\xA6\xAEy!1\xA9\xB6\xF9\xE8\xE4\xC7.\xDF$\xE4\xE7v\xBF\xEEr% \xE5K\x8E\xCF\xCEm\xEE\xEDZ+\x9C\x979\xE8Y_\xE2\x95\xE3
+ \x8E\x99\x97>\x85睻\xB8:1\x80\xEC\xA5\xB4\xB44\xEF\xCE#\xA6\xD7\xD9\xEE5\x9E\xCD"\xA8AS\xFC\x96\x8F\xBE\xC1\x87B=L\xE5uǯ;,\xE1U\x87\xC5e\xF2q\xBE\xBBr}\xC5
\xFA\xD6#\xA5\x92\x93b>\xB7\xE0^lۅ\xE1_\xA2\xF6L\x9Fl\xE0\xB3˕f\xA0k\xCBD?Č\xFF<y\xC3iq\xA7妊\xC2\xDAFQ\xC6\xB0\xB0\xE6\xF1#U?\xAB\xD6Zm]
+4 & \xDA\xEE_\x90\x90}\xF3Zh\xE4\xF5\x8B\xC5c6g\x84Mm[8Hh(Iv\*\x9A\xA0kP\x94\xA4\xC7@\xCBU\xEBEܡV\xD6V
\xE2 \x8Bq\xEDz\xC8ʸ\x96\xEB\x8A\xFC\xE8\x8Eo-r\x9C\xB7\xA8\xBBZk0\xA2u\xEAr\x86\xE1ؕ\x8C\x8Fg\x8E\xB1\xE7\xE8RP\xD1
+\xB9\xB4\xF2qY?\xAES\xBBw\xC2p\xA0ŷG/|0~ @\xBD\xE8\xA7i\xE1\xDA\xF6Ȭ\xFA1\xF9\x96\xDF\xF6U\x8F c(hPP(\xAA\x8A+쇷\xEFDQ\x91\xFB\xA5\xBB\xE7\xB7~\xF1im\xEF\x90l\xA709\xE4\xE8\xB8\xAD\xB2\x8Fҭ߸\xB0\xF3\xD6\xE8~_\xDD:\xD0\xF7$/ $\xA5\xD7¦
\xCDZ\xF8U\xF6\xFF9u?Eb4%i\xEB;34\xC7\\x9A>\xF6m3S#\xE8\xD3$/f\x8FxM\xF4\x9D\xE53okB\xC9N/:\xB8\x9D\xD5$\xC1cZ\xB9\xF7Z\xA7\xAD_\xF6i\xB6Ȟ\xDFf\xB8Z0v[\xB4\x93\x87\xC0\xFC\x81\xAF\x9Da\xED~.ʨ\x9F jSqD\x94+}\xD1\xDE\xF7\xF0\xEC\x83²\xB2\x92\xB4C+\xC57ax'\xE7\xB4g\x8B\xAC\xDD?\xD1\xDE\xFF\xC9\xDB\xDBO\x9DM=%\x88\xE0 \xC2\xFD
,9\xA3Bc{ɏI˥E\xF7\xAED.a\xBA\xC6\xEDL+\x99g\xDD\xCD\xE3H\x8F\xCDb\xB3٬\xD6Iye\x97瑴\xE0{x9;\xBE\xF6O[\xACw\x97\xA5\xB1y\\xD6B\xB8r\xF9\x92Qz\xF6|iQ>\xED\xEB٤\xC9s}\x85i2\xB5\xFAʙ\x84\x843g\xAE\xA8ղ\xB2\xB2\x9Ay
\xFD(z\xFDxH\xBFV\xD0\xE1 \xAB\xAE\xAC
+z\xBB\xD8t\xEC\x90e\xFF^^^ə\x8D/eՑuί&\xBF\xB7kezD\x98okt\xC5\xC3tX\xEAk.{֚ \xE7\xEE<\xB5\xD2\xF4\x95KBCC\x978\xD2K\xA52\xB0;\xE3\xDC;\xBA<P\xC0\xCF\x99\x80\x81(\x9B\xA0\xE4\xEE\xAF \xA5\xCF>\x8F\xFF\xB1\xE74\x91\xFAC\x91\xFF\x9C(4he5\x94p
+~\xCB\xC6\\x9Fj\xBD\xECe\xE7e2\xA5Z]\x93\xCD\x92
+%ju\xE5N "\xB3L\xADT\xCAd\x92\xCA\xE3
"\x9C\x94\xCAjTw\xBA\xA2\xD2\xFC5\xEE\x9Bx;\xC3F\xBE\xEC\xA8b\xF5\x87p\xD5\xC1=$F4\x9B\x86\xF0\x83?\xD2(M\x8C¡\xD9//$=\x94\x80\x9D\xDF1\x89\xF2\x8CR\xF5Ll"F\xF1\xECMf\xEFo\xF5\xBFʞv\xBF[H\x8B\xAE1l֦/ή\xDC\xF1\xCA<D\xF7\x92\xC3\xFCyi_\xF8\xFDj?\x9B\xF4\xE4\xDFpa\x920\xA2\x97N_\xCB6 \x94\xD9ȍg\xD4\xCA
=\x8AQ\x80\xCEOuY)\x88H\x8B\xE9\xC9\xD3\xDD\xA4'\xC3x\x89{\xBFC\xA0/\xE3
+\xDE[k
+\xB37\xFA\xC6e&y\xD6F\x9DOmm\xCEt\x8E\x8D\xFB矺\xD8\xD8r\xA1\xF4\x8D-\xFE_\x86\xAEg
^d\xCBE\xCCmS \xF2\xE6\xDAcwn\xDC)]MX\xFDT\xF6\xE2\xDC7\xE2\xF0\x95\xCB\xE73/\x9E\xBBz\xF1T\xE6勹
\x96\xDB;g\x8B\xCA\xD3D\x92)v\x86wb\xFF:}\xE2\x8A\xEA\xB7\xB6\xB5Nd\xAB\xEAf\x9E\x8C \xF7\xD5\xF7t_\xA1\xE33\xBB\xB8\xE9b\xEA\xBB\xD77p\xDDm\xC7~\x9Bp\xA7\xB4\x8A\x86g\xC5%\x8Fo|\xED7\xB6q\xF3\xBB\xF2\xFCKiY\xC5Ս\xB8u\xE6_\xA7._RQ\xD7֏\xD1\xD8\xED\x8E\xC1\x8E\xFA\xAE\xD8z%-v\xBD\xEFX\xD7a&)\xA2\xB67R\xCCF\xF1'Sl;\xE6\xC5
\xF0yV}[D9\xCAp\xAE\xEA\xF9\x93\xFA\xCAs\xB7J \xAA\xEA;i\x97\xAF\xE6\xA6\xEE\x88\xC5\xDBV\x87(5|\xF3\xD5\xF3ϓ\x96Nw4q\xC6q\xE7\x9Ax:Yϟy\xB8\xBAC\x8E\xCF\xC13\xB6\xAFC\xD0[\xFD\xFDƺ:\x8DU\xEC\xCEHrm\xAB|\x94\xB0\xFC\xE0\xBA%\xE3 \xE8r\xDF\xFD<\xB4`\x8E#\xC7Ֆ3\x91k1\xC7\xF7p\xB5fz\xBB.m\xB7\xCFDwO\xEC\xCD\xC8\xA0\x8B\xBBTUz|\xD1'\xC51\xFE֪;+*
+Ϭ\xBF\xA1t^|\xBC\x99\xD8=OK\xA7L\x9E\xA6\xF8\xEB\xF9\xB4\xE2#N\xE6=\xDE\xF9f\xE3\xC3\xD2.\x9F\x97^\x9D9\xC6"IT\xD7S3\x88\xB37\xAD^}\xEB\x8D\xE7\xEF?\xD5s\xE0\xDB/L+;\xE9ma3\xD1+w\xC6\x8E2\xAAʎ\x9E\xB2\xE0\xB7o\x91~-=Ǔ3\x90\xF9\xEC\xF8?\xDC\xD3\xC1\xDF3\xA1եa\xB68:bӔp!\xBC\xD2;LW) \xE6MAU\xE7 3&\x8DiAɅ\xA5q\x88H\xCD\x95\xE9\xE2\xEE˕\xDDuftE\xAE\x87'\x8Dd\xB5\x82\x93\xCC\xCA0\xEE\xE3\xA8.\x9C\x95\xF1ٕn
\x93h\x96\xEE
+LJLo\xF5\x87z\xADؙY\xF8ᤗ\x93\xE11\xF59\xD8\xFB\xF7ع_Mb\xF2Zq\\xA0\x87;\x87\xBCh\xC8\xF6ܴx\xA5\xBFC\xA4\xAE`\x86\xFBۦ
=(\x952Iuy\xB1PTc
0\xA9\xDBq32\xE8\xA2DJ\xA0,\xBC\xFF\x91\xB48\xD1_\xB83~\xD3`
\x93\x8D;'\x8C\xEC\xECsU \xA6\xFD:\xEAs\xBA\xB6\xBC\xE4ƹ\xFC\xD1\xF3{!2)<w^\xF0[\xF7\xBF\xF0\xE1\x9A\xC9\xCBs\xD6ZN\xF2-钍\x882vv6\xCE?\xBA+w\xE0ԙn\xC3\xB0\xF5hZZ\x92\x9B\xEC\xE1\x8F)\xED>\xCB\xFCoM\xC4\xCE\xCAQ\x92\xB3ɷ\xC7\xF8\x8E\x8F\xC4\xE2\xAD\xBD أ\xF6 \xF3$`K\x96l
h\xC1|\xD6A>\xD29\xB1\x81\xEE+\xE5մ)\x8B\xAD5\x99\xE9&
}TF\xFBu\x95 \xF7\x8B\xECC\xDC=\x98\x87W\xC4G.py{\xE4\xC8N\x9E!i3\xCBl\x92\xCF\xF4;\xBB\xB03|\x85\xB73U\xC0\x83\xC2w\xAE\xCFH\xE8|Tk\xB4\xC5bQ\x90_9\xB8B\xC8;4ӎ
+\x80\xC5\xCB\xC8Ţ\x98qnz\xBA\x89m\xA9@\xD9g@\xF8\xE9\xC77\xBCcƢ\xA4\xA5?\xAE\xB7\xF1HDX\xE1\x9Ang\xC3\xCD>\xBC\x9F\xB4\xC9\xC1W\xEF\xE4\xE2C[Ǐ\xEEb\xBCCSy|\x99\x89 o_MǓo1\xBD\xB2ҫ\xCDI\xCCbS(\xCAI\xC5\xE2\x943 \xF3\x93\xE3\xCDq?ꖇ#.{R8\xAA\xA3\x81\xAE*~%\xC0\xE2}\x85_\xAD\xE9uz\x96\xAE*\xCA\xFBv\xB5q\xC2A\xE1Kn\xC1\xD7C^\x95\xBF{\x81Kx:/徤\x87%\x8C\xAFe[W\xBA\xFF2\xA5\xE5\xA5«{}\xF7
+\xB1/\xB3dͤ\xAE\x81C\xD2\xDA*@Q\x92\xBAjTWT\xD6Ji\xD0
+\xCA\xCC\xF8\x85\x91\xB5E?\xEE^\xEE\x95\xEE\x95V\xA7\xBC\x93)\xBD\x8F7
+\xC6vn>&\xF7"'OI_\x9Ct\xBE\xF3m%}p1=$M
\xEDM\xDF\xDB\xC5\xDCz\xBDϩq\xFFL4\xA4\x9Dy\xF4\xF1\xD5rW\xEB\xD69\\xA3\xE9QI3S\xBFW`\xD8ћ(\xFF\xA0\\x96
\x98\xFC\xD7i\x86\xAD\x9A\x93\x92V\x9E\xEB\xB8\xD8^\xDB\xC0\xA8U09]\xC8
+\xEAԃ6\x9Aʫu\xE7F\x8B?\xE5jܖ\xC6\xDCa\xA9M\x95\xDEɸ\x90*\xA1)ų\x8C\x98\xFD\xD7FLv2wi\xD1\xC1\x95
+\xCFh\xD1́h*\xBBs\xE1Hԉ\xBA\xB0\x8F\xE7i\x92_r\xFD\x8Ed\xBF\xFBE\xD5\xF3\x9A\xA6tW\xE8E뷅O\xAB]6\xA7|
4\xA3\x83_\xB0!3\xF6\x8D\x91\xBA\x837\x9D\xB8\xED\xE4:
\xBE5^\xF5 \xA0\xCD\xD2kz\x92^,\xB1\x89?\xFA\xB7\xF6)w}\xEB\xC9\xC7\xDD\xFC\xB8\x97\xD3E
+Z\xD7\xF4N\xF5S
+]\xA3A\x9D'\xEB\xADV\xDE*\xD5ּ\xEF\xC7\xC8c͑\xDC5GT4\xB4;\xDDQF\xBC\x99\x91)KGۘvs\x9Fi[\xBF\x9B!zW\xBF-r\xC8\xCC3,C\xBCM\xBF\xBB̚\xBD3xFL\x86ϑ\xBElȱ\x9B\xFCQ\xF4͏\xA2_\xBB\x8B?\xDB1\xBE\xBDU\xE3%]\xADV-j\xB5Z\xADVk>w(a\xB4\x97A\xC5Д\xA9\xD5\xEA\xB6\xF6j\xB5Z\xADjiiA\xADV\xD14M\xB7\xA8h\x95J\xD9X\xF3[\xBF\xA6+ңޜof\xE7]iK\x8Eڜ%&\xEE\x89)TF\xEBe\xC5Zzh\xD2 /\xE6\xF3\xB6y\x923\xCE\xECΩ4\xE1\x95"\xFCn^{vi\x8E7\xC7==D\xA0\x8C\x9E\xD5~\xD0\xE5g\x99\x96|A\x99z\x96Ey\xECߕ\x89\xAD\xB2pqfY\xFC$\xAA\xB6\xBC\x8Am\xA1q\xCC\xE5\xC7.qY\x99ؖ\xE5nqZY\xBC\xB7H\xCFF\x867\xFBE\xCD\xEB\xFC,\xBAr2\xA7\xC6\xD0n\xF8\xB0\xB7\x86Y\xF7
\xCF[{\xEF\xE4d\xDE\xFCI`\xBC"\xF2\xBE\xDB\xDAyz^\x9E6.z\xEF\xE16\xBD
+ \xE0\xF1\xF83\xB6&\xBC
\xB2݉\xAA\x93[̏Jߗ]\xB9ƭ{Q\xD0w,\xC0\xF3\xF2Bu\xBAP \xBC\x90\xFB9ѝ04\xBB\xD2t\xBExߩ\x985\xDDf\x8F.\xBD\xB0\xCB\xC6wSǒ\x90}\xA9\xE1k|4$\xBF\xE7\xAD\xC7\xF3ʮ\xD9\xEAVʰ\xDF H\xBA/\xF1{YgHsf\xF3\xEF$\\xF4\\xC2t\xB4\xE5"mE(a%\xEA
\x96\xB5\xF9Qﺄ\xA7#>\xAF2\xC0\xB9\xD3\xCAK/\xBCc\xE3\x9B\xDEv\xBB웮\xBAw\xE2\xD0A\xFF\xF08`g\x8Dzc\xDBɮ\xDD\xEF\xBD\xC6MS\xCE\xF1ݻ\xB3R\xBD\xD1\xD2]2\xA76\xD45\xE7N\xE1\xEB֨7ӵ\xF7\xB2Rwy\xF8'"D(\x89
\xC9Fk
\xC4T\x9F\x940\xCF!\xB5\xF7\xBE\x81\xDFgK\xEE\xB6'告O\xF2
\xE6\xB7ϫ{\x85\xC4\xC7\xEF\xE8Η\xDDf[mщ\xAF\xFAo\xDA\xDB\xD96
+\xE59'_,\x9F\xBEl\x85\x9BE\xAFJ\xA3\xF6\xC7\xD9&
\xF0/Fb\xA2 o\xF1\xCE\xC4\xFDwz= ]Ĵ\x8F?>\xF3\xF3\x80I\xBDOU\x97\xEFe\xB9I\xF0\xC3R#W\xF9\x8C\xFCU\xE7\xA5g\xB7\xD8\xF0\xA3\xE0\x96w<¹\xA7\x9C\x94}\xB6M.>\xAA\xE7\x98-Q\xBF*$}6\x88ɏ\x83C\xFB>[\xD6\xDDk\xA4\xFBGq\xD6v\x9B\x8C\x89\xB7\xAF\xA6-`\xBF(9\xC8\xDE?\xFCa\xFC־\xBFۡ\x87\xF1\xD6^]\xFBѬ\x95qB,>T\xD4el\xC8\xC5G\xF5
Τ
+?\xAB9\xE2\xB0sP\xF6ݍ}N\xF7\xFB\xDF\xFD\xE0\x81\xC8\xC8\xC1PZZZ --0\x83\xA1\xA5\xA5\xC5`\xF4\xF6\x98W\x99\xF4RK \xBC<ˆW7\xEA\x81\xFEc\xB4\xB4)\x8A\xA2\xDA\xB4(---C[3\x8EC\xAB\xF5?\xB5\x83\xED\xD6Q\xADfh\xEA-\x83\xE8\\xF2\xABQC\xDDK-\x91\x98o\x84\Z%\x95\xB3\xD8f/\xBF\x83\x96Kk\xA54۬S\xE0n\xF9\x85HK\xDF\xF0\x8E\xAF*i\xDDKiQ\x8Dy[\x9A!\xB9\xB4V*\xA7\xD9f\xDD\xE7@\x97ז\x97<\xA9VB\xDF\xC6\xC1\xEE\xF5\xDE.\xD3tm\xD1\xFD'J&S\xCF\xD4\xD2\xFAu\xB2\xF4\xBD\x8Aڳ\xBBb֪\xDE\xE3\x88AKKK\x9E\xD57\xCC~\xFDMM\x98ws6 \xF2\xDA\xF2
+\x89R\x9Fcn\xD6M4t\xE7\x96R\xA9L.\xC5bw=IҪr\xA6Y۩\x96K{z\x83\x89\xBC(Yo\xAET\x9275|\xFA\xAE\x99\xF1\xFF
\xADߞf\x83B\xD3\xED\xBF^=\xBF\x83+\xCB\xDF\x98\xE05\xA9[\xBDU\x9B\xB9\xE6\xE4\xF4\xFD;\xFA\x96\xAE
\x804v\xF6\xEB\x98x\xE3\xAB\xE6\xB4V\xC9J\xDF;{B9nZe\xFC\x8E\xD3Ex{\xC6\xD25\xB3FB.us at pjx\x90O\xFB\x8E\xAB\xF2OF\xC7^z\xDC\xD4\xFD!\xFC\xC5A\xF3&uqoI\xCBKkd4\xF4L\xCC-^u\xEAڠ\xE5r\x9A\xF5\xAB\xF2\xD6\xC8K\xC5\xCF\xEA\x95\xFA\xFA\xFA\xA6\x83m\xBA헖\xD6\xD2\xEC>$-\xBDWƴ\xE9۲\xE3W\xDBu\xE5\x86d\xBCw7+\xDE\xC46yyNn\xF5\x88I\xDD\xE7\xF7\xBCHʶ\xFB\x95\x87 at W\xDD+T:\xBC*\xA5\xC3k"\xFF\xF1\xE8\xBFky3g9w\xAB\xDD\xE9\xFC\x93_\xAC\x9F\xBF\x89\xBF/*\xE0\xFFs&\x91\x98\x84\xFF\x88\xC4\xEC\M$\xE6o at y$\xC32\x9C/9@R\xC2\x96\xFF\x8CĤ\x9Bi\xFD^ߩE \xFC\xD9$& \xF7\xF9\xFD\x91ˆ\xECܙ\xFA\xF9\xBBD_\xC2\xFF&\xB4h\x9D\xE3\xBF\xAFnG \xFC\x89 \xE1>\xBF?,\xBB\x80\x8D\xFFh#\x81\xF0\xDBAW\xE5^\xBAR\xDD\xD8\xDC\xD4,m\x96*\x9A%o!\xE7\xCB\xDDu\xBA\x90U\x94/\xFD,\xCC\xE6\xF5\xC3M\x84\xFF1\x88\xC4$\xE15QI\x9FUT3ͭ\x87Xs\x99
\xFB+z\xDEs\xFD\x8C\xA0\x94˘&$Y"\x81@$&\x81@ \xAF\x8D\xEEЙ\xC1 ĂO\xB7
ʁ8\xB3
\xEC\x86\xDF%\x81\xD0Y\x8BI \xC2ј\xBB-D\x9Dz\xE1\xDB[{\Lc
\x93@ \x847\xE6y]uÓ\xDBgq\xAC\x97\xD7)B\x88\xC4$\xE1\x8D0
3l\xDB\xEF\xB8\xF4F\xC0\x83\xEE\xA81\xE9G\xA7>\xF1q\xB5
{\xECƣ?\xCC<\xE1\x85HL\x81@ \xDE\xCA\xDE7\xEC\xDB\xE2s\xAD\xCA\xE1\xB7\xDA\xC1\xE0EųKo\xBC\xBD'[|\xA4\xD8w qo\xFE\x94\x89I \xC2R\x92\xB3Ȗ\xB3<oֹm3:Ƒ\xEB\xF6\xD3++*x\xFA\xA4\xE0LH`-\xE1O \xF8\x81@ \xBC!&\x83G|xZ\xEC\xE1dե\xDCx\xFC\x86M\xE5\xE2ʗ^\xDD`\xF6\x87XF \xFC\xD1\x89I \xC2±\x9B\xEC\xD1}\x8D\xA1Ӽ0\xA7y\xFFYk\x84\xFF&\xC8D9\x81@ \xE17\x86HL\x81@ \xC2o\x91\x98\x81@ \x84\xDF"1 \x81@ \xBF1Db\x81@ ~c\x88\xC4$\x81@ \xFC\xC6\x89I \x81@\xF8\x8D!\x93@ \x84\xEE\x89;q\x81\xFCA\xFE\xF8
+\xFF\xF8S\xC1\xB0
\xE3\xDB[5\xBF\xB2\xB5Z
+\xB4\xA8\xD5j\xB5Z\xAD\xF9ܡ\x84\xD1^CS\xA6V\xAB\xDBګ\xD5j\xB5\xAA\xA5\xA5-\xB4ZE\xD34ݢ\xA2U*ecM\xF9\xAF\xB4\x8A@ \xE8DF\xC6\x86\xD0\xD2Ң hi\x81\xC1`0---\xA3\xB7ǜ\xB8\xCA\xE4?e'\xE1\x9Ee\xC3o\xDB\xDFb\x8C\x966EQC\x9B\x82\xA5\xA5\xA5\xC5`hk\xC61\x83\xC1`h\xB5\xFE\xA7\xD6b0\xA0\xDD:\xAA\xD5M=\xA0\xC5`0\xC0` \x9DK~5j\xA8{\xA9%^L\x81@ \xC2o\x91\x98\x81@ \x84\xDF"1 \x81@ \xBF1Db\x81@ ~c\x88\xC4$\xE1\xF7ARS\xF4\xB3\xACsQK]\xC1s\x89\x80JR\xD9Z\xA5j\xA8Q(*\xA5\xA2\xA5EբT\xA8\x94
+\x95R\xF5\xD2\xD2(khl\xF9\x8Dw\xFAF(\xEB$\xF5u\x92\xFA:I\xA3
\xA0\x9B\xEA\xDB>\xD67\xA8 @\xDE\xD4Hwl\xFFLtG\xF2\xC7X
+\x95\x82~u#B\xCFP\xB4\x81@ \xFC\x86\xA2\xE0\xC1w+Y\x83\xB4[?\xD2O\x95Ĥ @\x8B~\xAA0p\x{11D122}\x82\xE6滅w\xAF\x9Bh\xAF5\x8B\xA5][W\x92U\xFD\x{13A306}\x9Ek\x8C1\x87SuyC\xCDȹ-\xF5\xFD9\xB2\xAC\xBA\xA6g\x8D
+\xA8\x8AZ\xA8A\xBA\xACF\x85\xEE\ǿ\xF0M \xD4]ݪ\xB7\x98\xCA\xD7\xB6?\x9F\x8Ep=\x8C\xF9\xBA\xEDͽ?z\xF4\xACw\xD8}\xDEB\xFE\xAC\xB4TN \xCB\xD0|\xA0\xB9Q\xAF\xA7\xE3\xE1\xB1\xFD&\xAE
\xAC\xFB\xAA\xBD*\xEE|\xE28\xDEv\xF3v6\xEA|\xF68!\xFB\xC3\xD3{\xCCf\xBB\xEB\xE0\xE9\x81τ\xF1\xA2u\xA9\x9Ec\xE3Eg\xFA\xFF\x9C\xF6S=\xF4\x99
+\xA9\x81V{S\xDE6\x80R\xD9<\xC0ٗk\xCEjߙ\xA4\xE2QM\x83`\x9A
\xCA\xE9\xD2ucn\xF8\xF2\xDC\xF5\xC9\xC1
\xA8;\xB6\xE2c\xC7\xE8#\x8E\xBDX\xF6\xE8k[\xAEΉ\xD2\xF7]\xCD\xDAJR\xB8\x9Aϕ\xBF\xEF\xD8۱\xF7fß
"1 \x81 at x=t\x87\xBD\xE5wlHU\xB9\x80\xD5|\xEF\xEF\xFA\xADt\xB0b\xA3`\x9A\xB2\x8D8\xDA-\x92\xE7>{P\xEF=x\xFC\xE2\x86\x91\x85\x8E\x9B\xEE\xA9
\xB1}\xF8\xE8
+
+\xB4\xA0QK\xD7JK\xD5\xD8\xDCܯE\xDB\xDAb\xDAj\xB6\xA4\xBC\xEA\xE2\xC7%\xA378\x9Ah\xD0k\x{DA31}\xA4\xAE\xDA\xFBU\xD5\xCAd/\x9C\x91-\x8F
[S>j\x97\xEB\xDB\xC3zS7-\x95\x8Fro\xF2\xA2\xAB?\x83T
+jć#\x86\x98\xF4:\x8D\xD9xo\xDBd\xCF[\xED\xA7m?} \xB4gY-\x889\xEA\xDC\x89Ipl\xFD\xD3
\x98\xBAƭ\xBAO\xE8@\xDBr\xCE\xC5$\xF1t\xC7\xE0ώ\xBE\xCB\x940\xB4\xF7[ج\xD9X\x87j\xD7,\xF5w\xBE\xFCp\xFC\xD1, \xB0\x9F\xE6Qx)s\xD1\xF3\\xB5\xDB;\xD2e6բ\xCD
{\xD3;\xF4\xA3ofrc\xFD\x92\xD2^\xE8K \xD0ᢹ\xA7M\xFAbß
"1 \x81 at xmEŗ>it0h \xD1\xF3Gh.xV\xCAy\xEB\xBD\xB48\xFD\xA7\xEFp.\x9Dc\xC9m1\xF4
\xC8s\xA3J8Ͷ#:\xFB\xB9ڦе
+\xF0\xF4\xAC0\xAF\xB6߰\x80\x81\xF5\xB7\x8As\x93\xEB\xC6'N\xB4i\x95^:\xDATs\x8FZPk\xC8\xD0w\xB66\x9Fߘ\xF34\xD8\xD1{Z\x9Bfl\xAC\xFCᳺ \x91ojZ5^*\xE9`?v\xABZ:\xD2g\x97"\x9F\xAB\xA8W-\x93\xA3\x98\xC0\xBAs\x95
+\x9B\xC4\xC7=}\xAF\xDC|ߩ'
\xD3&,]\x80\x967\xA9X\xFA\xAF\x9A\xB6\x83Z\xF4\xD3\xE9o1M+\x86\xC3l\xEDl\x94\x8DO\xED!n\xAD6
\xBF!\xE5ܣ!Ú\xF6F\xEA\x8E\xE6V\x8B\xC0\xA2\x80\xF8\x9A|\xEEQ_ 4\xE6~\xE8\xE4\xE9rT\x9C\x9B\xCC\xFC\xC26䝘\xE3\\xD5/_rGoc\x8A"\xF8CE\xC7CV\xC5A\x86\xB8\xE6\x93\xAD\xFB,\xCB:'\`T[\xFFN\xF4ə\Î\xD6H\xC4\xDFo\xF2\x9D\x8F\xD0\xF3\xD7\xD6L\xEEbx3\xA0C\xB1\xD0-\xBD\xDA\xD0\xFB\xF1\xFFy k1 \x81 at x\xB4 \xA6\xB6\xBE\x96\xB6>\xA5-iil\x86\x93\xD2\xD6\xD5f\xE9h\xA8:'ec\xA5<\xF5\xE7\x945\xE5
+\xA9N\xFF\xD2 \xA9\xFC\xEDZ\xF2\x9C\xCC\xE49\x99ߧ<\xEF\xB2/m\xA66Z\x9Ai(A\x81\xD9\xEE {\xA5K\xCCș;\xFF+\xC9\x95Mm%\xCFE\xD5\xD0iSK
+\xE1ּ\xC7c\xAC|\xF9f\xC3L,\x87\xE9J1\xC6ʊ\xD3V]\xFA\xFD:\x9F\xF9iEݤoZ\xBD\x8E\xFA\\xEF \xB4\xB9\xA4\xA2/\xFC6*\xBA\xFEm\x80̳ѫ]\x87\x99xr\xF5\xBF\xBE\xFC \xD1ѥ\xE1Gs\xDB\xF6u'\xCAwin
+(\x81C\x86;\xE9?J\xBA\xFC\xA1\xA3\xA5\xEB\xB3Ȍ\xBA\x8E\xC3G\xD34\xA5U4l
\x87j\xD32\x85!\x97;\xD6\xC9\xCA\xDC\xD6\xCA\xC1i\xA4\xB7\xB0\xB8Z t\xD6\x9E\xBBo~\xE0i\x85jQ.\xDC\xCD)@w\xF8G\xD9)\xA9! \xA0;\xF8/\x9F
\x8A۴)h\xD7we\xE4\xDE\xF5\x9F\xEE\xDE\xB9u\xCA8\x8F\xC2wz(\xCE\xD3\xF6\x85\xBET\xD5?<\xB7\xDBg\x8A\xEF|\xAB\x98\xDB\xFFzI_\xD0\x82\xCFC7\xA4\xE5\xFE\xA2\xE8Z\xF3
+\xAD\x89I \xC2\xE1hh\xE9hfi\xA3\x83A&NS\xCC\x8E4
\xC4գ\xD1\xC0l\xCA\xDB\xEF
\x9B8k\xB3&\xD8\xCF?=~\xC6?\xAC
+\x93A\xF4\x8B IDAT
+\xE0\xFF{\xA2'_w\xC86\xB7\xF3\xFBw\xDEQ\x8BJ\xA9e\xE1>\xD0~\x92\x85\xFD\xA4
_(\xA4jV\xD2\xCD
\xC2tt\xBA\xB1\x82ik3w\x8F\xC65\xA7|\r%E\xE5\xB6\xC1\xA6u\xB5\xA6x{\x8EHf1\xE7\x9B\xB6\x87\xBD$k_\xA3\x83\x9F\xE5\x8Bg?\xDD\\xFEK\xA9\xB2\xBB\x833 \x9AeJ@\xFE\xE4F\xCAQ` \xBB՟G\xE7f]\x95k\xC2`:\xFE\x8D:\x8E\xCF\xE9[\xA5)G\xB7\xC6.\x9D[Ms\xF7J\xDD\xF6ѝz (l>\x85 o\x9BS 0\xCE\xC9~\x9EK\xFA!f\xE3)\xC1\xE1o\x93QU,\xA6\xBD\xED:
+4P"\xD8\xE2>\x8C\xE3\xEA\x97\xD0D1uͬ,ۚ\x9B\x98X\xD8ZXX\xD9\xF6\xD3Ppcf\x80\xAF#\x80\xDA_\xAE.u4n-6\xB2
\x83
5\xBAF\x83\xAD\xAD\xCC6\x80\xB9\x85\xF9\xA0\x81\x96Vf\xA6\xCCGY0b5\xD0ڊ\xA3\xD0
+O\xC4W\x8FE\xFA\xB8;9\x8A,\xD7E.\xF5\xB0
b\xD9\xED\xE5E\xEC\xC7[\xDC=\xD1v\xEC\xB1Q\xA1\xF9* \xC8D9\x81@ oDDU?\x9F\x93\xAB$\xB2\xFA\xA7
+\xD1qZZ\xAA\x87\x8C
\xA0*\xED\xA7\xF4\xFF\x93\xD1O\x95@]\xCA\xC3\xC7c
+\xA0\xDF\xF9\x81\xDB铖6SY\xF0MQ\xA51\x80\x96j`x[Š\xF9.\xEF4\xB6\xEBJUu\xBE\xA2m)c7(?:\xBD\xE6р\xF5\xA3\xEDڜ\x94\xDC\xF5\xE3\xECt\x99m\xC1A-Eqw\xAA
\xAD\xBCm;,Y\xB4\x9B\xF3m\xF1\x9Cn\xF7\xA6
x\xCF\xFA `\xDD\xE9Rk͔\xB1^h\xE0\xF6\xBF\xE1\xF1\xC1\xB2\x83)\xC0\xF3\xC3Ո\xBC\xFF\xB8\xC1\xD5iNظ\xA0\xD8Ӣ\xE8\xF3I\xE6\xEA\xD3\xC7\xF45) \x8E\x{DD2D})\xD3r\xE6Ϲ\xF3\xD5U\xAB\xB6ڀ\x82\xB2 l\xF8\xBBr}毟-\xD4\xD65\xE1T]?\x9F\xFCK\xF9}\xE4\xC9%(
\xE6\xFD\x81 \xBA\xA2P\\xEFL\x90_;\xB8;(t\x95f\xAFt#\xE0i\xD9
\xD0CC\xDF\xF5\xAB\x92T\x81\xBD\xAA\xF1\xEE^ߍ\xDCݻ.\x98\xA00\xF6\xEB't\xF7\x91\xE3͵\xE0\xCF]\xB85,\xF0\xCE\xF1=s\xC6~\x8EU)\xE2]6\xBA}\xB6\xE1O\x91\x98\x81@ \xBC6\xBA#\xB8\xDD\xF6\xE0\xFF>oq[̬\x84\xB9LJ\x83\xA0jݢe\xA0\xC0\xEC
\xA7\xF7\xA6<?\xB1\xF0g0\x9Ch=Χ\xE5j3:M\xC56\xD2\xD4[\x86,f\xAB˫E٨=\xEC}+6\xB4Y\xCD9\xB7
\xB4\xE7,\xD2200j\x93,\x8A\x9FDEӆw\xB7\xD4Q\xA5(\xF9\xBF\xFB7\x8EJL\x97;N\x9D\xD0!l\xBC\x83\xBE,I\xCE\xC9I5\xF0>f\xD3\xC7p\xF4&`\xF5\xE9\xF2\xF7
\x9E|\xC1
+\xB8tm\x96Ӝ6\x8DM؍vg \xA1j\xD5\xCAf\x8D\xB3\xD5p\xEA\xC6\xEDQs\xBE8\x83Tl\xBDض\x8ES\xDF\xA5Y\xC7\xBF\xA8_q\xC0\xF20,\xB2m\xE4L\fh\xDE.͘\xFAC*\xF33\xB2̧\xFFe\xB085\xA5\x8A\xB7]\xEC\\x94\x8D\xCF\xEE\x95ɝ,-Gp3\x9F<\x93[\xD5\xFE+"k\xEB\xF9\xE4\xD6
:7f\xDA-?\xA7\xDDd\xD7\xD6?K\xCE\xED\xB95\xFB\xFD\x81<\xFD&\xEC)\xBE\xD9\xFE\xA9\xF7\xBCDʹ
`
+tZ\xB0\xA7\xF8/wn\x94h=\xF7T\xDFl\xF8\xD3C$&\x81@ o\x80\x87\xC7u
\x99\x99\x8B\xF5vz\x9D\x94\x9B\xF2i\xF9\xB9\xE0\xC2A|N\x93\xC1 {\x9D\x9A\xAC\xD54\xDAr;6\x90\x95\xD4(\x8C-\x98\xCA \xA5Vw\x93\xD7{s\xAEH\xFA\xF9ٛw\xF5\x84)\xCB.\xFD\x92Sc\xB7\xDDͬ\x83\xC2TTJ*\x9Fԕ_\xAF(\xBA"\xC3 \xA3\xF11\xE3lu' \xD2[\xFF\xBC\xFD@\xC4\xF1Nt\xD8Y\xA0*\xCA.m_l\xEAg_zXw\x8Dkit(@\xD7\xF1\xE3[\x97֏\x99\xB6\x82\xC4
+Ӵ \xF3\xA6\xF0\x91\xED\xA6P\xF0\xCD-\xF4kk\x9EY\xF6\xA4\x8Ekg\xF8\xE4Fb,<\xE2m\x8D p\x9C\xAE\xE6~\xB1
+G\xC5\xC6m\xED\x9A
\xC3aj螩u\xE7B\xF4By\x8FR1=:\xDAќ>\x96\xB0_Ӡ\xF8^\xEA\xA5Ӯ\xFE_:8\xEAQ\xCC\xFA\xA2\x84z\xABaos٠i\xBA\x9F\xC0_\xA2\xF6L\x9Fl\xE0\xB3˕f\xA0k\xCBD?Č\xFF<y\xC3i\xAE҅\x97#m(\x8E\xB95\xE3
+\xBDu\xD01\xA2\xDC\xC8i\xBCS\xDB߆\xAFcß"1 ]\xA1\xCDrP\x86\xBAݬӥ\xE9\xEA\x95q\x88\x81\xF0?\x8FJ%\xABo|\x92V\x92{\x9Di\xB7\xDCLw;9N\xD7f\xAE\xB9\x85-ǀ\xAD\xA5e` Q\xCD\xC0ͮ\xAE&\xA5\xE7\xD2u\xECVX}>by\xC75\x96(H\xAE\xE9\xBFt\xB8\xE5WKɳ\xD4=A=\xF5\x9F\xBCz\x84t`n\xC6\xFFU\x96\x8F1\xB6\xB3\xD5\xE4-\xAA\xBB.<\xBF\xA7
\xE7]\xAE\xDC\xCEɉ%?\xEE\x91
+\xF13\xF7\x8E4pP\xF7\x81\xDCu\xD7E\xE7\xF7\xBC\xADf\x9D\xB61|\xA9V\xD5\xF0,5\xFB\xDBQ\xF2}/\xD5P\xEDY\x82L'l\xBF\x9A0\x99\xBF\xCD\xF2F\x84w\xE9\xE6\x99\xC1\xEFq c\xFC\xA2MF\x98\x9B\xA7Z\xB4n\xB9\xEED\x91\xA3Fy\xF2X\xB6\xF0\xC0\x83\xAC^\xECظ>?5jMp䢽7\xC3\xF8\x8EM3\xBE_\xE7α\x8A9oV[@|r\xF5\x92
+\x8D\x911\xFF\xF8\xC8u\xF3\xEAI\xCE%Y\x99K\x9E\xF6\xAFo\xA8\xAF|\xDAT͙\xEB9\xD4\xD8)8[\xE4\xD7C\x8Eu'\xD6g\xF9g5\xDB\xA6wQ4\xD5\xD7\xC3\xC7LK\xC5\xC2\xFDW3]M\xBB\xBF\x8C hI\xB1\xA2۵\xA8@\x83\xCD=89\xFBjß\x86\xED\xDFު\xC1\xF8\x95
\xA8\xD5j\xA0E\xADV\xAB\xD5j\xCD\xE7%\x8C\xF62\xA8\x9A2\xB5Z\xDD\xD6^\xADV\xABU---h\xA1\xD5*\x9A\xA6\xE9\xADR)k\xCA\xA5U\x84\x9Ei>\x9C\xF6e5\xA0k\xAE\xFD7\x9B\x86\xB5%=\xBC\x905?\xBE\xFA\xDA\xC6`\xAE\xFADŽ\xD9\xD6\xDD-; \xC8˞\x9C\xBD\xA75\xDDǢ\xA7\xFCn)
\xBBxT\xC4Lr?\x84\xDF\xFA\xC1\x91\x91\xB1\x83\xA1\xB4\xB4\xB4( ZZ`0CKK\x8B\xC1\xE8\xED1'\xAE2鶼!\xFF糑\xCF\xF0\xAD\xC6̷i\x9D\xC8nx\xFC\xFCI\xFE\xF3'"\xA9\xE4=0\x987\xDE\xCD \x80\xB2\xB80C\xD8\xAAW\xD3\xD5S\xF0\xB0\xD0\x9E\xA5\xDCy\xF2\xB6Ø\xBA\xB2\xA7\xD5 \x8E\xA16 EQJAq-g\xC2
+\xABVQ)\xC9/\xBC)6\x9C\xEA7PәBV]\xA3eڃ\x82|%-iu\xA3\x8Eٛn\xDE-\x8A\xFA:e\xC81\xE8\xF2\xFDM7\xD57\xC0\xC0\xA8âӺc\xBE\xB7\x96\xDC\xDC\xE3\x80T!\xFAz\xC1\xBB\xC1i\x98\x99\xB5{j\xABs\xBF\x8EIQpyo\xD9\x88\xAE\xD6\xDBN\xB6\xEF4V\x89\xEF\xDE,(y&\x9A0ut8\xB6]\xB9f\xE8+tUi9\xC7ڪ\xF7#o\xAAx\xD8hhe\xD6\xF5X \xD0UEE<\xDC\xEC\xB7;s<\xCBn"\xF7\xFBH\x8B1Z\xDAEQm
+Z\x94\x96\x96\x83\xA1\xAD\xC7\x83\xA1\xD5\xFA\x9FZ\x8B\xC1\x80v\xEB\xA8V34\xF5\x80\x83\xC1 \x83t.\xF9ը\xA1H\xCC?\x9An\xA1U-4M\xCB\xE4-LC\x96Qw^\xC3\xFF\xACA\xF2\xC7-C,\xA9\xC4ui\xD1O \xE8,\xFF\xC8y\xA5G\xFB\xE4\xEE
K_vZ\xC0\xFA\xED!{\xD695h\xB8t\xA1\xC6\xD5\xC7\xEAe
Y\x97{{ʞg\x80\xCE\xF2ӹz\x9D\x97\xBAhAZ\xB9>\xB2\xB0\xB4\xF5\x93\xFD\x903\xE1\x8EC\xC8\xC2\xEF\xC5\xEF"1\x93\xE7d\xFE.\xC6\xFEg\xF1;\xED\xF1\xBB\xEE\xBFI\xE39\xF3h\xBC\xE8f\xAF\xAF\xD5\xF9\xF1g\x93\x98ą\xF4\xD0 y~\xFA\xB8c\x89\xF14\xE7\xCB\x98\xFF.}\xD57T\xD6)d\xB2%\xDD\xC2\xD4c
+\xC863\xE8^\xCB>θ=;\xAE\xEE\xC5\xE7\xC1\x83:\xE8K zm\x99\xDA\xE6\xFE\xCDq\xA8A\xCB\xF9\x9D7\xB6\xE6\xABp\xB6:%z\xF4\xD0\xCE\x91b\xB7.j\xFE*\xEE\xEEu{\xC8;\xBDmנ\x9F\x8E\xF5\xDB
'S\xAEP\xD5T\xD6d7\xE1\xF6\xE8%\x84\xFFB~oq\xF6\xBF\x81\xEE0\xBF\xF3\xB7\xDE7#\xFA\xF2\xCF
+\x91\x98\xDD\xF08\xF3\xD6\xDAc\xD2Ɲ\xD7\xEC\xCAU\x8D\xD06`\xA9\xA1=Č\xED\xE4l>\xC9\xC5b\xD0\xDD9\xACA桞\xF5\xD1/\xF2\xB3\xFA\xAD%\x96\xBC\xA2\xFA\xC2E\xDF|_]\xFAR\x95\xF5\xDBfk\xFDGx\xDA\xE9w)\xAF\xAE\x92w\xFA,kPWT\xB2\xF9\x9F\xF7\xF5X\xF6\xC6\xC8-\xD44\x88\xFEG\xFA\x90\xFFܚ\xE7\xB7\xFA\xD9\xFC\xF7\xAF\xA7$M\xDA\xDDP\xF1\x9E{»\xC6]K\xAB\x9F\xAC\xFEyP\xE0\xE8p\x9F\xBE\xCFw\xC2\xFF,\xAA\xC6* \x8C\x8D\xBB\x99\xABmoP\xEC\xEFM\xF6^/\xCA}l\xEE\xEA\xD8\xF1\xFB\x96~&i\xDB:\x99\xE9ʫ*\xA4f\xE6f\x80\xBC\xB6Z\xAEo\xC8(J\xB4\x8A m\x96n\xDF:TT\x88\x8A\xE56\kͺ\xAA\xDA\xD2_\xE8\x81\xC3\xCDt\xA1\xADk\xD4\xF7Yf\x95\xA2A\x96~\xAF]*rJ\x97\xF5\xFB\xC7\xD3\xD0M\x8D\xB4\xBEA\xEF\xF5!\xF4"1\xBBCO\xDFZ\xAF&\xB3\xB0\x93\xE4\xB2~\xDBȺ^\x9AY\xA8\xF0sa\xE3Y\xCFv\xE2\xEE\xFB\x8D_\xEBѯ\x87\xBD\xF4\xD5\xCFlq\xB0\xD9p\x9D\xF4\x95\x97\xE4\xAFn\xFD\xDA\xC8\xCF}s\xEB\xA5F \xD6o[
\xF2\x98\xBA%_\xE092'xpmYŹ\x94\x9F\xBF̪\xFAxK\xC6O\xFB/\x82\x87u\xFC\xCAaB\x80\xF1\xDB3Q\xF1\xCDO*#\xFF\xC2\xCD\xD5\xF1\xD5p\xB6?\xF3\xC1 \x8AV\xE5
͉\xCCW\xE0/\xB1|4\x8B\xA6J\x9BEA.GO\x9CN+8cf\x8A\xA6\xF6\xBC\xC1Z:\x90}
\xFF\xB8ȍ\xBFu\xFCG\xEB\xDBG\x99I \xFE?\xE5\xD9\xE5\xA8亙\xCF\xD3,4,<\xF9\xE9}\xC7
+]\xDEO\xD8n\xEE\xB0\xFEn\xACxߪ\x87z\xFA\xD2r\x8B'\xCB?p2\xE8&ZuX\x93\xF8\xB0\xA7o\xEC\x98q\x9A\xA9\xFC\xBA\xACL\x8C\xF30\x80~uY\xE7\x86\xED\xBE\xF9\xA9n\xFER\xDFt+tsꢯ"FC\xAF?U\xFDSv\xE6iG\x8Eb\xE1\xFEk1fFy\xE17\xDF_&jƫɼY\xF58\xA75\x97D\xF6\xE3fZ֞3]v3l\x9E#\xA2\xA8\xD9\xDF\xCC?\xB3˾\xB1\xD8\xF0Ӓ\xA9\x91ߊ\x8F\xDB\xEB\xB4h\xCB\xE4\xB1\xEF\xDF\xFA\xED\xDDy@\xCC\xF9\xFF\xF0\xE7ԧf:&MQQ*+\x8C\xE4\xC8ʱٲȹH\xFCr\xC5ƶ\xCAb\xB3\xBF\xF2\xA5\xC5:vsf\xB5K\xAD#\xEBX\xB4v7\xE4\xD8bѦ\x86f)\x95\x88\xA4{\xA6f\xEAS\xF3\xFBc*ӹY\xF6\xB7\xEC\xF7\xF5\xF8\x83\x99\xF7\xFB\xFD9\xE63\x9Ff^\xF3>\xCB\xFF$\xB8TH\xAB\xB9\xFA\xEA\xC1\xE2\xFD\xBD\xA3~\xE9\xF3\xB3\xBFs\xCB\xDF \x8A\xE4e\xB6;V\xDD\xDFo\xD9r\xE4R\x9A\xF7\xB0PZh\x99[\xFC\xE5.X\xACx\xB9\xE8\xF2\xB6L?\xEA\xC3\xF5\x8A(\xC4lFg\x87\x9E!=\x9F\\xFCm\X}E\xA3^\xF0\xEA!\xBDH?\xFC\xC4\xFFNݒX8\xB0\xFB\xA6C\xAFю-Uk\x85\xAE\xFE\xDF\xF0KLQ\xB4\xD9/\xE1h m\xBF\x80A\x9E\xF6\xFA\x80\xFC\x961 .\x90\xC2\hf2o\x99\x89\xDB\xF1\xB8\x8D9wc\xD3]3\xAA.~ٳ\xAE'eM\xEE\xD3* Ewr\xA8\xD2s>J $\xA5\xF9\xA3\xD3J\xC7v\xDD,xH\x920\xB7t2\xD1\x80\x82\xDC\xFD\xBF\xD6xL1o\xF1\xB7^EUa\xBEUjKS at c\xCE\\x8B\x94%\xE6\xDBk\xCB W \xF4GLy;g\x9C:\x82w\xFD랲\x92<\xF9\x8B\xBE\xE7\xD5\xD9G\x8F\xF8\xF2\x8B\xE8\xF3\xA3m[\xFA \xD5y?\xFBF\xE5\xBBv\xA7@(\xE4\x82\xF1\xFE+D\xC6\x80\x{128541}?W8t\x96
\x89B\xFD%Rql\xBC\xD8y͵\xAD^\xF6 tm\xE7'J&d=*\xC00\xA5Q\x8B\x97tY\xB9\xBD/,\xC0k\xFF]\xC7v\xBC\xEA\x92\xE4\xE8Y.\xD1>\xE1\xDF\xF8\xDE]\xF8\xC1\xD8\xE0\xC3\xE1Q^\xE7f\x9E\xF9\xDF)\xFE\xA1U\x9DL[h˭\x92>\x91Vj[OZ\xB9\xD2/\xFFQ\xE2\xE3\x98\xCF|\x83\xB7\xD9\xE8\xEF22(ό;)\xB1\xFC\x98\x8B\xFC\xC4S\xB7J\xF4\x8Du\xB5\xD8\xF2\xA2\xECߓ\x85\x93W\x8C\xB6\xD6+/\x95ɹ\xEE\xA1>s\x8F$
\xF2\xEA\x91:\xEF\xA6\xDF/_\xB6\x93\x97\x96ȹz\x86\xF5\x95\x92\xD5%\xD22\xD1\xCDފ6\xEB\xDA?G\xCC\xCD
qm\xAB\x87=\x80\xF2\x92bM^Er\x82\x98\xDB3+\xF9\xF6\xC3\xDF7o\xF8\xBDP]\xF2 Gڡ2\x8B\x87\xED\xC4 `\x9B\x89^J\x92w\xE8 6.N\xE91q3\xB7\xC4~<\xD5A \xFB\xE4\xE2\xA1\xEF%\xF9OJs\x9F\xE4\xE5\xCA\xF4\xDBǜQ}\xBF\xD9\xF8D
Z\xE1\xA2\xC9\xE6'\xC6\*\x90U\x96W\x96U\x96)*K\xDC\xC4\xF5\xDD[\x8A\xB9\xA8\xC8\xCB\xCC\xFB"\xC0\x92\xBE\xA7\xFE
+1[\xC47\xD1\xEAC\xCC\xEAr\xC0@߬K\xF0\xC7\xCF\\xB7\xE7ץW\xA6\xE4\xC8
\x8Dߐ\xEAt\xE9\xF6\xDA\xF8Rog\xE80Gc
+ (xv\xBE 0~\xCEv\xB2
\x9F[2-\xBC\x8F\xB2מ\xED\xE2\xAAjȮ̸W h\xAE
+e\x85\xDD>Z \xE8\xEF\x{3F3B07C}t\xB7\xAA\x80\xA2`\xB5\xCF\xEDs\xC0\xEE\xA4\xE2\x9F֊:5w+9\x8C\xEB9\xAFIC\xF9\x93k\xBF\xDF)\xEEپ\xFD
\x9Fn/\xFDc\x9FB\xDE
\#E\x8B\x99kZL?s\xAC`\xBC\x9B\xE9\xCC\xD0\xBB\x89j?\x85e\x89\xFF7eq\xC8\xFC\xBAO\xC6'ყ\xB9m\xF9e\x9E\xA8\xBD
Z\xBC\xB2\x8B\xD3>\x88p[\xA0\xCA\xEB\xFA\xEE\xEA\xD0ay?\xE8\xEB\xF1\xFB\xDCf 4\xB9\xFA\xEA-\xC9\xE5\xF7M\x9F\xB4e$P\x96 \xF9\xF4!K\xDB\xD5n\xF7_\xCDv\xF6\x9FEo\xCD?߽G\xCFJg\xBFXWG\x9D\xB6DV
+>\xD0\xEBV;\xD4\xD6\xC3\xFD\xFC\xBF}>\xD4c\xCBGO\xAEG\xF8~v\xEA\xF1
+{=\x80U\xF0\xA6ȴ\xF0,C\xFC\xD0\xE6\x8A\x86uo\xCF\xA0ȎZ\xB5\xF4\xA4^g@*J\x8Fw^z7%pv\xD9\xE4\xB3G\x96S26\xE4Dm\x9DnI\xE2*{\xE7غ\x90\x8EW~7"g\xBC\xF3O\x91\xE9S\xECm\xB8Ҹ\xCDc#\xC5 \xE8\xEFA\xFF\xF1
\xEF6\xBE\x92lqڮ\xA2X \x80\x97\xDB\xDEt\x898 \xFA\xD9d\xF5\xDAbY\xE2\x87\xF6\xCE\xFD#$\x89\x91Z_u]66\xF4\xA8m\xF5\xBBm\xFB\xAE\xD5\xAFs\xB7Bu\xB4M\xFB\x8D&\xE4\xE8\x8D\xE4
\x9Fs\xC6\xED\xD3p7\xEB\x82\xE8x)hV\x97=\xCD+\xD02\xB1\xE8la\xAB\xF0``sIg\xD4dCT\xC9+\xB4\x8Ch\xA2˿\x8AB̖1
+>8\xEA\x9F,\xDA\xF9j\xC5j\xFF\x97\xCB*\xE5,[%\xAF\x91˫\xCA+*Y-~/k]VQ)\x97\xD7T\xB0,+\xAF\xAE\x90\xB3\xA5\xB0\xB456lr\xD5\xF5\xF4@\x9E\x9C\xF84\xAB at Q \xE6\x9D
\x9D\xEC-t@!R\xDCxV.
C}C.\xA4Ҳ\xFA
\x86\xE9d̻\xF3}ҁ \xF0\xDB\xE0X_9ɏ\xB3\xB4ԏi\xE5*r?z-\xAA
q\xE1\xA9wF:\xF5\xE2\x8A\x92\xE4\xC0\xDC|\xB2}\xC7\xEFun\x80Q;K^\xC9T\xFF;0\xD66\xA8\xA8.\x8A\xCAkG\xED\xEC^\xF3\xEBes-\xD9#ymG\xCF\xF4\x9Cq\xBE\x88
+5\x8D\x8F%o.2De\xDDpmMH\x8B\x8F\xC6\xCB܍Mw\x8E-\xFA\xE9\xE8\xC0N\xCD\zBy\xFC\xE97hG\x9F\xAB:-\xDBW\xEAV\xBB\x8Cu\xFA\xF1\xC0\x93XTW\xF1Y|\xD6\xCFz\xAF\xC7ᄩ#TaL\xFE\x85]\xF0Xӻ\xAE\x{35667A1}\xE6\xFD={\x9Bӛ2\xB7\x9F\xB2f\xDD3yֵ(\x89\xD6WU\xAB:h\xAF\xA5\xA7
+\xF0u%\xE2<l\xFAU<#3\xAE\x80\xAC\xA8\x95Ӗ\xED0,\x80\xE8\xC3\xA3\x9B\x92\xB8\xF9n\xE91 \xB7\xF5\xD7ֹ7|9z\xEDu\x9F+dR\x856`\x83\xAE\xAAW\xF7\xF0f\x82h\x80' \xA1\xFD\xA49\xF6h\x84k=\xFD\xB3\x8D\xE6\x8ChhG$2\xE7\xD6\xFA\xC8A\x9F\xB9ŭ\xF3\xE1*\x9E\xA4?\xE7ۘ\xA9\xBE\xF2\xCCp\x96\xAD\xBF\x91\xE8a\xFCmW\xEB\xA5\xC2\xD8=^kj\xFDf\xEA<\xD4 \xF4]\xD7\xDFp\xF5\x8F\x99\xE9y[\x98Oy\xE2\xBE\xF5nc%b \xCE\xEBk\xAB9\xB9\xEFo\xCD,ϊ\x98\xBE_\xB0n\x9D{\xF7\xC6'6\xFE+g\xBD-78wAAL"\xCFe \xA6\xFB\x92\x84\xE3\x83\xA3>q\xF73\xE0v\xEDQ\xD7 !/f欈
\xE5C\xF4\xFBP\xAEgwJ\xFCl\x86\xC8j\xBC\x97 IԚ\xB5__\x87$.
;{X7\xBB\x8Cy b\xBE\xB4\xA2\xEC\xF5\xA7\xFA: \xC8r\xC7ͻ]\xA4\x9E\xA1k\xFA[x\xAF\x889\xBFi\xB0\xB5\xE6\xD7\xFB\xC784\xB9\xEA\x89\xC7n\xBC{j\x9B߳\xE8g\xB5wU\xF7\xC7\xE3\xE6\xC7T7.\xED\xD2\xEF\xD6\xE3}>W\xA8\xEFv[\xCF
\xA7d CzyZ\xD7@
\xF3K1\x80\x9E\xBD
+\xC6z\xB6\xA6\x88J \xFB=\xB3\xB2\x97\xAD\xB6\xFCiq"\xB0p\xB6\xB6n1\x83*[\xDC\xD1^\x87\xD7`:\xC3C\xFC\xBE\xDF>\x8D\x95\x98\xFE\xB1\xA3\xFF@=\xB9\x82eY\x8D\xE6\xEB#\xCD
+\xF56l(\xAAz\xA0\xA1\x85\xCA\xEBg
+}\xD7\H\xB7!!\xE4-\xC4*\xE2\xD2է\xEDn.$\xE1ZO\xDAV\xFBX\x91}j\xE6\xDA\xC2\xD0\xE4I\xAA\x82q\x9F\x99\xCA\xF6^\x99TWM\xF6\xE0ۅ\xFB\x82.l\xA9\xAF5S<\xFEyѤ`\xCC߱rJ\xC9\xEF\x99Ì ظ,]\xE0\xAB6\x9E}bo\x91\xDD\x94\xA5^\xE8\xE1\xEA\xACH\xB5\xEDb
V\xB0t
+\x8A\x95lP\xDC
+
sq\xE4\xD5\xC0a\xD5yW\x83\xFC&\xAC\x8B\xF4y\xB8w\xFA\xD5A{\xD8B\x96\xF8b?\xA8b\xABt
\x9CF\xF7h1(\xC8Z\x9B\w\xE0\xEB\xEA \xA8.H<~\xB9r\xDAԡ\x8D*\xF5\xA4\xC9\xC1k\x93\xB7\xF1\x80j(\xAA\x81\xA7g\x97\xCD|\x90\xB8\xC8
(>\xFB\x99\xC5\xCE\xCE{c=D Hn<\xB4
\xA4c\xDDԡ\xEA;\xC9\xFF\xFDG\xB8\xCD\xE0\x8A\x83=6\xA8=\x9F\xC0Զ\xA6G\x85\xDC\xD4Sbb^\x95\xFF\xF8AI\x98³\xFBov\xFB\xCCׅ \xD2\xFB\xD7\xC6{\xF9\x8B \xFDq5}ް\xDAbC\xB3\xD8\xF9P\xE6\xA76e\x92\xFCl\xA0\xFB\xB0\xC3\xD9CL ]:A\xD29ld}m\xA8,q\x{DC8A}\x90̳
bf8\x92\xA3\x98\xDFZ\xF7S\xD2\xF4\xDD\xDEF\x9AZ\xAA[M\x96\xB2]\xAD
+\xD3\xC6j\xAA*\x9E\xD3\xEB\xD8\xE3\xDBдsuYF\x9A,\x98_
+쑐\xE1\xAC>U\xAB\xC56Cwnyԝ\xDA /;\xE9\x81\xEB&\xE6\xFA2\xA7\x9D\x82\xDF?:\xA66\x97\x90K\xEFL ,
+\xDC)<iS|%t
+w\xFE\xA7o\xB7\xBC?\xEE\x80v\xE0\xEC
\xC6\xF3\xD3v?\x80\xF7\xEC\xB5V3}\xFA\xE9!]@\xCA\xD6 Ⱦ\x99cO{
PY;\xBA\xBD\xA2\xBA\xACD\x9E\xF3\xFB\xFD=Wt\xBFY\xDF]\xBD+@-ժZ\xA6\xEC\xC9/\xAFI\xDF0ϾAW\x9EVmT\xEA\xE0h\xE9\xEC\xD0dDy\x9D\xC4q\xC1?\xCBp4w߶\x81\xF6/=h\x8AB\xFEa\xDD<3\xCEH\xEB\x97g];\xFB\xBD-Vd\xFF\xEC5b\xD6\xCC\x89C\xDDǝSг\xAB\\xFD\xBA0\x86M\xDC!:9\xF1\xB0\xBFu\xFD\xC7i\xFE\xC1aӆEd
q\xC4m\xB7<4\xB6\x81\xA7N4짨\xC0\xE9\xCFv}\xA4(\xB9
/\xD69Pą\x8E"m\x9C= d\x9D]p4%=>\xD82,m\xBC\x97\xB3=\xF4~\xD46\xB4\xAD\xC2\xC8\xD0]b! \xD9I`Lm\xBA^ٓx1_\x84\x817\x8D\xB7\xCFh\xF2\xBAl\xA7Bt\xB2hf\xFD
\xDB\M\xFF\xB4,\xF3\xCB{
+Id`\xE4\xD23\xF7g\xCEsE\xEB\x92c?\xB1\xF8\x894v\xAB\x97C\xDD&l\xCA\xCF\xFBF\xFFO0\xC0>{\xFC\\xBF\xBF\xA8\xD1H\x9Dv\xDD&\xC5E\xED\x8Fӓ\xEF\xFD\xF62\xC0\xB3\x9F\xBBr\x92\xCD,\xEB\x9F\xC7<\x9Bl\xAB6/]Rҏ \xBF\xBAk\xCB"\xBF\xA5u{\x95\xCEf
+&~\x91?\x93\xCEݿvD\x91\xA5\x9B\x8Fe\xE3W\xF3\xBC\xB8@\xCA\xFE\xFEc:\xBEg\xB1\xBF\xC9k%/\x87B\xCC6\x92]\xB8\xF00[\xF6\xEC\xDBc\xF9\xF5\xD3 98\xBF\xF3\x85O\xFD\x87c%\xB2\\xE9\xF9\xE4\xDC\xF6\xBAp\xB0,`hf\xEC<\x85\xEBt\xECJ\xEB\xB3\xF4Z8\xF7:\xE9\xD3\x80\xA7j
\x95\xA4{?=\xB7\x988eP\xF0\x9Ds\x81wj\xD3\xB9\xAA7\x8D\xD7N`\xAE \xAB\xFE3\xC8\xD1B\xE3N|! \x80\xD7\xFEEubɞ\xADO@\xB7\xE3{\x8D'\x9E\xACy\x9A\xD7`\xC1,\xADN\xE6\xB6\xA8zF\xB2\xD2
+ @A\xEED\xEF\ ='\xF5\x90\x88s\xCB+j
+\xA0FKG\xE3VRm睐\xE0 \x90\xFB|\x89\xA3\xF7\x92\x9B\xB3\x9Duy\xDA(~\xAC:$
KޜLJ\xB6&\xB7\xB2Z\xA1v8\xAE\xB6\xA4\x85\xE2\xE5 P^0\xDF;:\xF8+\x97\xB1ft7B\xDE&\x9Az\x9D:\xD6E0\xE5\xE2\xFD\x811\xF3\x8F\xEFlnd[\x9C|z\xC3\xC2\xBB&o\xBB\xE1\xEF\xAC6l\-\xBEL\x8E\xE72\xFF\x88d\x92Zp%\p\xBF
\xF7\x99\xC1\x91.1W\xC5\xDA\xCBDW\xC5^\xBA\xA2\x8F~9\xC5
\xA0\xF5mk\x96\xF8;\x83e\xC1.e\xF4\x85 ,\xDD7qM\x9Ei\xEB\x988\x8F\xF1\x9D;\xBEj\xBB
+:bJe:\xA2n\xDAi \x80*\xB9L\xC7\xC3g~_>^)"\x97\xA8\xBAb1|D\xF8\xB8\x9F\xBA\x81\xD8\xC2){\x9A6Rz}\xDCm]\xAE\xA6
+0\xD6 \xDD\xCE\xDC\xCCؐ\xBDL \x80k\xEB
+at\xD5?\xDD\xDB9l\xDF\xD8(\xE8\x90\xFE\xCB\xCA\xE9B.\xA0\x9F8=~\xF9C\xC4̜s\xEA\xFE\x88FG\xDAu\xB5\xED_|0\xD6v\xF5N\xFB\xBA\xEE\xB8f\xFC\xAF\xAA\xEEb\x8CYO۸GO\xE5]\x8A\xF6\xAC\x8B\xFC%RA\xB2\x89\xA1.7=\xA2\xEEJ;\xFE\xFB\xE4\xFB;l\x9B\xE9\xD8\xE8\xF5
+\xED8`T7\xE0IJj\xD5\xD2\xECÓk\xBC7F.?|b\x86cK\xFFIc\xF4\xA5\xDEV\xC2\xEF\xA8?\x9D
0r\xA5}\xE3Q>\x8CxQ\xE3Xwq\xB5\xFB\x9B#\xEEQk;\xD73\xAA\xBD\x91\xAD\{O?z\xE5hym\xFA&\xCE13\xFF\x9D@\xFF{\xAA\x94\xA2;\xE9'2\xBAzZ3\x90\xE5\x84\x8D\xD5
+ \xB5\xA3q;\xB3\xBA?\x89?~G \xDE\xF3\xB4j2 \x9B\x93Q\xA9\xFEܪ\xA7\xD8\xCBw7\xDF~~>IV\xD7^\xAF\xE9\xEEbT\x94Yw*m~\xA2\xC1\xF4
\xBA\xDC\xCA\xEA\x92\xCA\x9E6\xD2kKX\xF42
c\xA9\xA5\xA8\xACVd\x95Ȼ3\xBD
L:w\xD1\xD3\xD3\xD5(\x96(Υ\x97\x80\x8D\xD10\xA7\x8E\xC5 \xE2\xC0\xD8\xEA\xE0 \x91aU
+ ]\xAD\x8A\xF9\xD3\xED%\x99q\xAB\xE4U\xE5U5Ƽzq#B\xF9\x8B\xA4\x92蝳}\x82\x97\x9F\xC9Uz\\x9E\xF7\xE0\xC1\xC34\xF1\xAF?|\xFA=\x86\xAC\xF8\xE6\xEA3{\xB3\xE6"\xC5Ó\x9F\xDAn<\xBD\xF4\x88\xB8\xC9\xC4@ iV\xA4h\x9Ex(W\xAFx\xD1a
\xAC\xBC\x9A\xA9\x9F\x92\xDA\xFB\xECp\xD4\xF5\xF1\x81W\xC4R\xBD\xFBW<\xFEuٰ\xB1\xA3?]j\xC7\xFB\xAE\xF6\x8D\xF0\xAF\x8E<\xEC\xA6^\xA0\xF4A|A\xFB\xF1\xBCJY%\x80*\xAD.C\x9D\xE7\x8E\xE8\xEB\xEC\xB346t\x97\xDB\xFA_\xACT\xC1\\xA5pf/\x92\x8E\xE9:\xDB~\xFAG[&wЪ,ξ%\xB6\xDF6_ՙrҡ\xECj&+V\xFA\x94\xCBe \x85\xA1ʹS\x9F\x8B\xEA\xCFP\xB7is\xB3\x9E(\xE0\xBE\xC4l\xBC\xED\xB7 NΝ\xF2\xAFD\xDE\xF4X`\xC3@\x91\xFF@\xC1\x82\x81B!\xCD\xCF\xCCӳ\xE9^7)
\xCF\xDA1\xEE\xE4\x85?\xECU}1K\xC4\xC7מ\xE9
\xBD \xA0\xFF\xDEƭcF\xF8\xE2\xC23!آ\xC7\xE2s\xA1\x8E_F\xAE8%qiجo8\xFAp\xE0\xD8\xF1
*Cc\xC6\xEC%46l\x98\xCBظ
\xC9\\x91\xBCw\\xB4\xC7G=Ԫ?\x9F\xC6\xEC\xBA\xD6kk\x82\x9Bm\xB7d\xDD\xDF\xD9ʬID
]\xA76Ҟ\xEE\xC2;\xF3b\xB2\xF4\xA3ai\xB3C\xFB\xBE\xB6\xA1*/\xE2=mS#\xA0\xBCA&c\xD65\xB8_F`Rm\xA7̐\xFD3\xD6wx)\xF3.\xB0dfWU\x9Ck#\xE2T
+\xF2\xB3\xB0\xE7B\x9E}\xDF\xE3\x98\xEAl
+87i\x84\x96]\xADy\xB5
+ \xD2\xFB\xFE\xE1
+\x97\xE546]\xB9@\xC4\x92\xBF\x8F\x9BJ\xF6ĺ\xFD\xE2Yݺ\xB7\xD3 \xF0\x87I\x9C\xC71\x80q\xF4\x9Bg\xFB\xE2\x9AWׂ"\xE7\x9E*г\xB7\xA9\xA3H\x88\xAEU_Ť\xF2;\x8C\xB5f <8{C\xF5\x9Aw\x87\xA5\xA6\xBA\xBC\xB3f\x81uk\xF3yB\xC8\xECi\xEC\x9A\xF1^[`;\xFF\xCB\xE8l\xA7\x86\x93\xC9$\xDF\xCD\xF5\x92,Z?\xE3\xC8կl̚\xFF\x9C{\xBBq\xBCW\xF0 \x9F\xC3\xE73'\xB5Щ\xC8p\xE0z\xD1l\x91\xEE \x97\xF9\xDD:\xE3P\xF0\xF5X\x89x\xF9\x99g3D\xFA`\xE5\xA5%\xB9w\xCE}\xE7\xBB\xDFi\xF9\xB6Y\xB9_\xD8:|1\xFE\xA3\xF93\xECl\xBA\xF2\xB5}3\xA4\xC49\x9C=\xDD\xE8\xF8\xB2\xF3\x86\xBE3\xAE\xAC\xF8lf\x82H}\xD7 \xB6\xF3\xFD\xC8V\xB4߶䷍\x9BS\xEF\xE0\x86\xAC_\xB5\xC2o\x81\xD9\xF3\xD9?\xA8\x97\x83\xB5\xB0\x83\xFD$\xA0\x9D`\xEEu\xF4\x97\xC1\xBF&$eTA_\xD8s\xCA\xF7^@V\x{11A003}\x92n&z\x90\x89c\xE3\xC5K=p3
\xE5\xA1\xF3u\xCBe\xE5yb\xD3\xE9\xFD\x9B\x9D `\xBẢV}\xD5=<\xB8p\xD7\xF2\xE8 \\xDB)_\xFA\xF9O\xD5\xD7<.="\xD9\?\xEFr?\x9F\xD8\xFA:,srv)\x8C\x8DO\xDErͽ\xAE\xA5\xC0\xDE'A졚\x9D>y\xAF\xEB\xC2/
+\xBD\xD6G\x9D\xBF\xEF\xD2t\xCEf\xA1c\xC0\xC5C\xEE\xF2\xEF#\xFE\xE8L\xEE
Q\x83\xF7%+64\xC0\xEB\x93t\x97\xADgB\xDFW\x8F>\xB9\xEDt
\xFF\xE4
\xC2\xE8\xAF\xCD\xFF߉.Ui\xB9{
+\xE9+\xBD\xF0i|\xDD\xE0\x9B\x82\xA7\xB3\xB7e\x9D]\xF6\xDA\xCChwG\xB5!\xA7\xAA\xC3i\x8C\xF1\xB4L\xAA\xAD\xC8D\xFA\x83\x9F$F\xD9'Kal:YT\xDB\xAE/\xB2Zh\x9E\xF3\xCD#\xF9w\xE7\xF3m\xFAU|\xB8\xB2\xB6\xA6\xD1}IϦ\xEB\xEE$\xFFp\xB7\xAE\x8F\xB7\xD0\xCDV\x80\xBEm\x97\xF7\x90{k\xD4
]\xF0 \xFB\x97$^\xDE
\xFB .\xF6\x81\xBB\xF7\xC0\xA0\xD1\xC6l]{%\xDB\xDC\xE4d [?\xBE\xA7\xB2 \xF4:.\xED\x95\xBC\xFAz\xDFC-\x85\xD7\xF6L\xED\xD9\xCBP\xA7@\x9A\xA7\x80!u\xA9&\x84\xBC\x9D:^zꪟys\xA4\xD0ymb\xE6\x9Fl.\xB4\x9Fu\xFCꇖ-\xA0*\xB6
\xFB\xA6|\x95\xFF\xBC\x90e\xAE\xB7\xCE:C\x81j\xEA\xF5\xA2\xDF\xF7\x8C\xF9\x9F
>#^\xDBQp\x9F=7;95\xF1ڥ\xE3g\xEE'\xE5 \x9F\xE30Pd\xF0\xBB\x99\xEA\xA0\xE45a 0|#
\xABM\xF4\xA0]\xAFw{\xC5]\xC9u\xBD\xF9\xBE \xF4\xD8\xFF\xC0\xDF7 \xABIDATK\xB7\x83\xAF\xDCs\xB0\x88>:\x9F̨\x9Aׅ\xB6#\xC6ێP?\xB7\xCENKw\xF4c\x80e\xBF\x8Du\xA9,˂X\x86\xD7b_|5]\xDF\xCC\xD6T\xB5\xB2\xC3\xD0\xC9w\xA2\xEF\xFEj\x9AM\xBE[4\x8D
2\xE7f\xE7\xB2\xB4\xB3K\xA3>\x9Az\x86\xAA\xC8\xD4~\xD1\xD9\xC4E\xAD
\xCF\xC0zĒ\x90KB\x9A\xC922\xEF\xF9\xE1)\x89\x93}\xE3\xA6p\x81\xE3\x8AU\xB9;\xC3v\xC9\xE7\xFD\xBA\x82\x96i;
+1ۨ\xBAT\xA1\xE1\xB2l\xD0շbŧٶ\xDB\xE0ږ?\xA1\x97P\xA5ւ\xAD\x87\xDA\xDFQ\x8D*2\x83\xD7\xDC0}\xA1z\xFD\x9F\xEE\xE2ս\xCE\xFB܉;t\xD3\xF9P]\x9Aqg\xDF&\x8B\xB1\x8F3>\xF9\xB9vU!\xF7%\xDDj+b\xC1.\x9A\xE7r\xAD/u=\xF6ٹM\xE9\xC0\x8B\x9B\x83\xF7\xC1\xC2λ\xD7\xE4 \x88:\xF4\xC8\xF4_\x98h\x9Eq\xFD\xC0"xM\xF6\x9C9\xD1 M'g\xF3Slz\x99\xD0\xD2䄐\xB7
Whn\xF6\xD6l\xD7Ų
+\x83
5\xB9\x86
\x9B\x84\xA1\xBF\xC4L\xBF)\xF6N\xF6NS\x9E\xA0\xF5lk ݗ\xD4^6
\x9Bm fVu\xA5
<
Զ:\xCC\xF6W=g\xF4-\x9F\xA1\xA6\x9E\xF0 \xD75n
\xB65\x8D/\xEB\xF0:ZX\xB5\x94\xF7\xEA\xACG\xB4\xB0\xF6\xBC\xBE\xFD\xD4 \xFB\xA9\xCD瑖P\xB8\xB6\xD2\x80v\xFE\x9F\xBF\xA3
Q\x9EO8$Q է\xB0\xD4yqm\xD5J\xFC\xE9\xAE\xF2\xF1\x8B\xE2\x9D\xCD\xEA\xBB{j\x8C\xF1\xB4nX\xD2p\xAAc\xC3n=\xC6\xE6\xFA\xA9\xEF_\xFB\xAB`Q\xA3\xCF$6\xEF\xD1R\xFF{\xAAޖ\x82!=V\xAB\xA0\xF6\xB3\x87
\x9F\xDF`\xA5MV\xB5Է\xB5\x9A\xAE\xFA
+\xAB\xD3\xF2~s\xF4\xEAZx6f\xEFէژ\xAF\xF4\xEEI\xF1%!\x84\xF2/F!f\x8B\xC5R\xAA\xC6a\xC6\xCC:ln\x83\xB0-d\xCDo1y\xB5\xED\xC2<\xBEZ\xC5\xFD\xA3\xA2\xB4\x82\x80M>\x9B\xBC\xFB\xC5Xy\xAE\xB4\x99c\xC9*\xEBڞ\x9F\xE0\xA8a7JƬk\xB0Z\xE9\xE0\xF9N\x93\x9Fr\xA3\xEAjn\xEEܰ\xC2\xF1I\xF2]W\xDFTU\xB9\x85s\x8F\x9F\xB5\xF2su\xAD̴4\xFA\xE9\xCE^h\xDA\xD3\xC6x皞\xBC\xC6s\xD27\xA3\xA2\xAC\xB6\xB65\xF1X\xCA\xE6\xD0\xF8\xC9s\xA3\xFBϺvN\x97\xD7S\xA7\xA6g\x8F\x9B={\xDD\xCD\xD3\xD7\xF2\x9E\x944\x9EX\x9EB!\xFF\xD4Pތ\xE2\x8C\xDC_\xEF\xC6F稥\xC9\x82\xE2=\\xCCƿ\xDB\xC5ʵ\xBFߕ\x8B!\xE9/\xB2>\xF5\xBD\xF0\xFB$\x8Ba\x8E֝\xA6#\xFDhmz\xE9b\x9Fs\xA0\xC1|\xEC\xA8\xF4\xBD(\xFE\xA0\xBB\xEFs\xF5\xD4옻\xFB\xFB\xF0=\xDEaw\xACM\xAB/\xEFطa7J\x8D1\x9E]\x93T\xD6[<\xAA\x99k\xA1C\x9F\xE3ƒR\xA6o\xD3Nj\x8DҼ\xFCc)\xBB\x93*@W\xCFϧ\xB7g\xCB\xD3U6CQ}\xA3jho\xFDG7\xEE\xD3\xD2(\xBCS\xD5\\xA1\xCAӛ~ە]UT\xA0>W\xBC\xFCh\xAC
Ɔ\x81ێ\xB30(\xDF\xFFY\xEC\xEEt \xB8{'\xFF\xEE\x9D| \xD0ն\xD0њ\xB3|\xF0Dk\xAA\xD7$\x84B\xFE%(\xC4lF^rz\xF01Y\xA3ĢGŻ\xC3\xE5\xFD\x86w2ڞ\xFE\xBD\xCF\xF9\xA4\xDE}\x91Y}\xF4ԃT-#Gk\xA1\xCF\xE6wRWޫ\xCF*/0\xA0g\xE1\xC1\xA4ݏ h
+t5
+\x8C\x90\x9A^\xC1U\x95U
\,J\x9F\xED\xDEzmw\xFD\xFE̍w\xFA\xF7sl2O$c\xD65\xB0Wz\xF0
X\xBCoc\xDF|\xF7
++\xFB.
+j7\xAB\xDF8W\xE8\xF2\xA6\xBFo5r\xA8Y_k\xFD\xD6\xDEuEɭ\xA6\xF3+q\xF9.\xAE\xA6\xB7\x92s
z1-(аc \xB4-;\xA1(\xA9\xC1ZDCL\xE7\x8C\xEF\xE6h]?\x9B\xEE\xBC\xF5\xA3\xAD$\xF8\xFF\xACvy\xCB+\xD1\xC7r\xA8ŗ\x84Bȿ\xA7\xEB \xB7ֲ\xC1y\xC5(\x95J\xA0F\xA9T*\x95\xCA\xDA\xE7j)\x9C\xFA4TsjӔJe]y\xA5R\xA9\xAC\xAE\xA9\xA9A
+\xAB\xACfY\x96\xAD\xA9f\xAB\xAB\xABd\x85\xB9\xAD\xF4\xC6V>\xC8.\xAB tx\S3}
\xC0*XVS\x83\xC74\xE8\x96P\x9C\xF1\xF0\xD7\xC7z\x9D\x8C\xB02\xF9\x93\xE7\xB2Ҋ ~g\xF57\xD9'\xD9%\xA5\xD0\xE9n\xA1 f\xD3\xF9O\x934\xBF
+
\xED\xDC\xD6Q7l~^\xA5\x8E!O\x9F۶N\xB2\xDC\xC9\xF3ng\xD05\xBDާ\xC9(G\xE9\xF6\xB9W\xD4x\xE2\xEDu\xAE_
\x80T,v\xCE`ac8\xF9=\x8B\xF7u\xB6p\xD0\xE2\xEC\x87;vH\xA2
U\x80y\xE7\xD8/\x9B\x9D\x97B^
{\xEF\x9E\xD8P\xA0\xC7\xE1(
+
+
+\x80\x868
\x87\xC3\xD1\xD0\xD0\xE0pZ\xFB\x9A\x93\xE4\xFD\x9D'\xF9\xF7\xB33k\xAE\xAB\۴7
\xA0\xA1\xC90\xC3\xD1d\xA0\xC1hhhp8\x9A\xB5\xF71\x87\xC3\xE1h\xA8\xFESjp8\xD0T\xDD\xD5JNm>\xA0\xC1\xE1p\xC0\xE1
+S^\x99\xCAVr\xA9\xF3o\xC0h[Y7 .\xD3\xF4BZw\x99X7\x80\x87\xD1\xE3u\xD6k<\x91; \x80=\xBD.&\xF8 X8\xBF\xEC \xFD4\xA9\xDA¥g\x9B\xE3K \x8C\xD0\xE4e\xDEe\xAE\xDEdgû\x95\x9A&\x9D\x8D\x9B;!\xFD\xC9;\x97$WYY\x8F
ޥSÚT}\xDBN\xC8\xB6v\xB4g\xE3ń3\xB4\xE8\xF4e\xDF켟br\xF4\x87\xD9P|I!\x84\xFC\xCBP-\xE6\x9BM\x91\xBFz\xF1\xCDs
+fb7\x88<0\xB4\xFB\x9B:\x91$\xAB`\xD1\<M!\xFF\xAA\xC5$o\x8A\xFF\xB6ZLQ\xFEf\xE3\xF2\xBB\xE8\xA8?\xD7\xDE<荍/\xD1B}-!\x84\xBC\xA5\x9D\xA5\xF4\xE05>\xF8\xAFB\xB5\x98o:\xB6\xA4\xE0\xFB\xC3\xF7n=G'K\xA3\xF7\xDF\xEF\xD6˘~BH۽R-f#\xADn)\xF7\xAFm\xF5\xEA\xB9\xE4\xDF\xE4m\xACŤ*\xA77
\xD3\xCE\xD8\xD3g\x88\xE7?}\x84B!mGUb\x84B!\xE45\xA3\x93B!\x84\xBCfbB!\x84\x90BLB!\x84\xF2\x9AQ\x88I!\x84B^3
+1 !\x84B\xC8kF!&!\x84By\xCD(\xC4$\x84B!\xAF\x85\x98\x84B!\xE45\xA3\x93B!\x84\xBCfbB!\x84\x90BLB!\x84\xF2\x9AQ\x88I!\x84B^3
+1 !\x84B\xC8kF!&!\x84By\xCD(\xC4$\x84B!\xAF\x85\x98\x84B!\xE45\xA3\x93\xFC\xBD\xE4r\xB6\xAD%ˊ\xCA\xE4\xEB\xB9B!\xE4\xFF \x85\x98o 6[\x92Q\xF6\xF7
"c\xF5(\x87\xD3'"\xA9\xE8\xC5Q\xCB\xF2s\x8B\xE4 \xCFMM\xCDn90,\x8B\x988joj\x9BN\xB0,u\x87\x8E\xCEWE\xCD\xE4\xB0g\xFD8}V\xFF\xA8\xB6\x97\xB20\xA3m\xB7\x9B+K!\x84\x90\xB7
+\xF3O\x9F i"\xF7\x82e7`\xE4\xD7\xD1\xDB\xFFǵ7\xAF\xF9B\xAC\xE4҅\xAA\xBE\xEF\xF6\xB4\xF6\xB2\xF9\xA9\xBF\xC4fj\xEBk7H\xD5\xD6.\xBC\xE0\xB7q\xE4\xAD'\x8C\x8A\xBD\xFA
+W%\xA7\xEC\xE9\xD0_\x91\xA0
Tvw\x9F]n\xA1r\xA5\xA0\xF9\x9D>>
uy\xF17\xFC\xB6\xBC\xBE\xB9h\xA4\x9D\xB8\xB9
f\xC4\xEA[\xA3:\xF47H\xD8\xFE\xF8\xBC\xAF)\x80\xC0m\xCBN !\x84\xF2ƣ\xF3\xCDcꪬxv\xE9\xBB
+\xA3\xDD\xEC{GU\xED\x9D\xD0̛\xC4>>>\xDA-Ox\xEC5ȴA\x96\xBC\xAC\x8C\xE1\xF3 `R\xA7}\xDB\xD5ݠ\xD1֙Q)@\xA3\xA0\x91\xE1)+\xEA\xB5x#\xED\xA0 Z\xED\xD0̝!\xBF~\xE2d\x8E~G}\xE9\xCD(\x80\xFC\xF5\xC6o\x85\xE7\xF4\xEFb\xD9\xD7\xE1+<\xFA\x99\xF2\x94%\xED0\xE8\xFF1 \xD8\xD9!%E\xB5\xA5G\x95\xA4 \xC0\xA6\x84\x83<a\xBF\x90\xAA\xF4>\xFB.\xEC\xC3\xD9x\xB9\xEE \x83\x8DV\xD5>r\xBFUz\xBA_\x9B\xE2XB!\x84\xBCq(\xC4|\xE3\xE5 \x84\xC2Q\x8BB*\g\xDFE\xCF\xFAwH.\x898\xDFy\x8B\xEFp c\xA8,
\xBAy\xF6\xE8\xC1f\xB7\xA7\x84x\xF4\xAE\xDF\\xF2\xDD\xEC
W=+N\xE5<[\x8F\xDBJ\x8F\xA6\x87Ȉ\x98h2\xAA\xF0\xB6\xAFz=e՟\x9CSY \x8E\x8A\x89>v#\x979Xt\xB6\x8CЭ'\xFFYZ\xE7
+>\xFD\xCD\x8F8|t\x83\x87\xD0n\xEE\xB3g\xB3y\xBC\xC2m6\x8F\x8E\xA7mϤ\x82\xA3\xC3\xDC
+s\xBC\xCF5\xAB\xF4C\xB9\x9C\xE1r/\xBB\xEDhw\xF2{_\xAFE\xD6r\x8FV\xB0\x8C\x8EN\xE1
K\\xCCZ\xE1hTUŲ,ç\xF8\x92BykQ_̿Wii\xE9֭[\xB7n\xDDZYYٖ\xF2l\xEEY\xA3F\x9CQ~gSsy\xFD\xFAYԷ\x93\xB3\xE7Cfm\xBB\x94\xA3\xD6E\x92?j\xE5\xE9[\xE1\xDE\xDBb3_$\xCAS\xD7/\x8E\xF2t\xB5м\xAE\x92\xBBon\x94g\xE0\xFB͵\x83\xB7g2\xC3m8\xB8\xF7\x9B\xEDvX\xE4\xBB\xC8k\x82\xEB S>\x92c\xECV\x9F\xAFH\x8F\xEESQ _(\xF0\xF9\xD6
\x87=\xC3B\xC0>O
\xFB\xF1e\xCFUS,\xF8|\x81P\xC8硃\xC3
?\x93\x8FmtF]\xCAey|\x81@\xC0\xE7\xF1L:+4\xE1\xF1\xF8|\xBE@ \xE0ӯB!\xE4\xED\xC5\xE9:\xC0\xAD\xB5lp^\xF1 J\xA5\xA8Q*\x95J\xA5\xB2\xF6\xB9Z
+\xA7>
+՜\xDA4\xA5RYW^\xA9T*\xABkjjP\xC3*\xABY\x96ek\xAA\xD9\xEA\xEA*Ya\xEE+\x9E\xD5\xFF\x8F\xCA\xCAJ.\x97\xCB\xE3\xF1X\x96eY\xB6\xA4\xA4\xC4\xC0\xA0q\x9BuSe\xF9\x92B|\xE6n\xBC\x8CeQ!T\xC1bYj\x84\x81\xDD\xDC\xC3i
\xB6\xADD\x8F\xEC\xD9\xD5Zn\xD7=V\x9A\xB6\(\xFFJp\xA7\xCB \xA5\x975\xA8&,\x8Bep\xD1'\xFD\xE0T\xEB\xB2\xD4
v(U\xFA\xAA\xF2\xF332x\xD6֪\xC7\xF2\x8C
\x9B\xD3)\xA7뺈m\xE6\x99gUxX49+y\xEAD
;DŽg+ \x8B\xAEo6\x9C\x9ARq\xB0a\xC7R\xF6Jľ"#E\xA0\xFBǰ\xB3RT\xED\xEAvvv RRR<\xC3Sz\xF5n\xBC[By9\xEC\xBD{bC\x81
\x87\xA3444 \xE0p8
GCC\x83\xC3y\x89\xAF\xB9\xD6\xB7\x94\xFBz\xF5\\xF2o\xD2\xDEt\x80\x86&\xC30G\x93\x81\xA3\xA1\xA1\xC1\xE1h\xD6\xDE\xC7
\x87\xA3\xA1\xFAO\xA9\xC1\xE1 at Suc(9\xB5\xF9\x80\x87\xC3\x874LyeJ([ɥ\xAA\xA2\xBF\xD1Ν;\x86\x91\xCB\xE5 x<^XX\xD8'\x9F|\xF2\xA7[\xF1\x85\xB6^.\xBD?\xF5\xC7Y\x9Fڐ,\xFF\xCAl\xBB\xB9v\xEB.\xB6_\xE2\xFAnq8mE+\xF1%ʮ/t
+\xB9=aP\xE3f\xE8\xB2{\x97\xD1{k\x87&\xE4n\xB0\xB11\xBAU\xD8O \xB0\xE77\xCFE\xC0E\xB5HQ\xA7\xDDȑF\xBA͝\xAFwht\x80\xD9`笕\xDF^\xE5
\x95\xD5d\xE03\xDCk\xE4\xF9\xBD\xD2\xDEgt
\x9E\xF0t\xDA\xE7\x9A=\xBD\xAA\xA0\xC2\xC0X\x87\xAD\xA8`\x8C,[y
\x84By\x93Q\x88\xF9\xF7b\x86eY \xAA\xDBN\xD8o\x82\xAA\xA5<\xE3\xEC\xB7\xA8\x91\xDB\x8Ej\xB14\x9B"h\xFA\xB4\x8D\x97\xA2\xD2[Cٌ\xE0a\x83\xA3\xEC6=\xF6
\xD4(G.9\xBFvq]_\x9E\xAA\xD3\xCD8\xB1v\xBC\xD3z
+ \xC8%\xC7\xDC\xC3\xF5xPt)\xE2\x9B\xF0\xD3\xD7\xC0/=t\xF9r\xC0\xADlWW\x8B\xA6G3u\xDD\xE5\xCDlyˢ\xAA&4S\xE0\xEC"\xCEa\x97\xF4\x83S\xAD\xF9\xE5ӗ\xBD7
\xB5չűs\x8Bʪ\x9A`Mw&!\x84\xF2\xA3\xBE\x98\xA3\x85\xCA\xE5r\x86aTm徾\xBE/\xB59[\x94}v\xAF\x9F\x8E\x8D[\x94w\xF8\xB3K\xBE\xCD\xD6M\xB2e\xF9\xD7O\xEC\xA5\xD5a\xDAƂ\xAF\xE3\xB26L\xB0nioe\x97i\xD9\xA5,K\xBB\xBE\xB2ɮʾ\xFFt.\xBC\x83\x87\xA8\xBAgVv\> \xF91\xD8fZئ\xB8\xCFmy \xB2\xD7\x{158140}\x8BL\xF1\xE3"\xA3\xD1\x8A\xA7-\xF2\xF3\xF6\xF1\xB6\xC3F7K\xBDMg\xF2,\xCB8{< \xB0\xED\xF8I\x93 /\x8B\xAE\xAC
+\xC3,g \xF2\x8C\x93s/{\xFA\xBD+\x84\xC05+j\x99\xBBePv[/!\x84B\xDEDb\xFE\x8D
+\xC5_|\xF1\xF9矗\x94\x94hkk\xFF\xF96l\x99$\xE9ʏ\x91{\xFD&\xF6\xD12\xB2t[\x9C~1M\xB9\xD7KبT~RĎ͋&\xF6\xD12\xE80x\xDA\xC7}\xBE\x8E~Vu{\xD1\xF0fj
+6?;)b\xF5D\x9B\xD1a\x9E۳*B\x9A\xD6r\xA6F~27\xCA.z\xCDXU͡\x96)\x8B\x97\xCC\xEE\xD3\xC3=(\xE0x\xCA\xCA᪃\x9B̌\x8EJY1
+(\xCA
+ú\x8D\x86\xF7\xEB7\xFC\xBD^@@\xD4ů\xCB\xDB̖ԯ\xCDS\x96\xFB\xE3\xE6\xD96n\xD8
W\xA1\xACH\xF8Z\x87\xD1\xC4\xE0Ȍ\xA2\xAB\xF7\\xD9\xE5\x94\xE2
\xE5*d\x80\xB2\xEF\x97\xCF\xC2:o\xB3\x8A\Ij\xD2Ct6\xCE\xDDq\xBD
+\x98B!o(j\x8E\xFC{ikk/_\xBE\xFCe\xB6x\xD2\xDF)\xCCn\xE4\xB2Y~q_\x8Cbk\xDA\xEC;\xC40\xB2\xD3\xEE\xBA\xCE':\xC0yP\xDB\xD6\xE6_Ϗ{\xD7rt
+<ǥ{o\xA6\x8E\x93\xCD\xFE\xD1nVز\xA8tC\xE5=\xCEp_w\xFE\xAD\xC7\xDE\xFDL\xEBR^o\xD7 \xC1\xC8pO\xBB\xC1'\xDC\xDD\x95\xEF\x941\xA3zOx\xD6\xC9Mb\xC6CQ\xEA\xD9o\xF6\xBDj[켣\xD3
+]m -\xDA[\xE8<\xE9\xD3\xE9n6A\xE9\xE0\xE3\xE77N\xF7g\xA7 DNȎ\d9+ \xA2\x9C\x82`7\xD2}\xF0\xE0Q\x87o\x9A5kp\xE4\xFB
֭\x8E\x8C'\x84Bț\x8AF\x94\xBFqX9\xCB\xF0^g\xE8_\x96\x9F\xAF%\xB6\xAC\x95\xF1\xEASɋ\x8A \xB4\xDE\xE5JĒ\虊\xB8\xF2\x8C?\xDE|{\xFA\xD29N\xBD-\x9A\xBC6;\xE9\x90S}\xFE\xB3}B\x87\xAC\xC8s\xE5
S\xFB\xC9\xF33\xB2Jc#>\x9F\xCFc^lqe\xEFL\xF6.\xA4\x9F@\x84\x90WD#\xCAɿ\xC1\xDB8\xA2\x9CBLB!\xFFbb\x92\x83\xB71Ĥ\xBE\x98\x84B!\xE45\xA3\x93B!\x84\xBCfbB!\xE4\x9F&/\xC9\xC9ɓ\xFFy\xB9\x97)I\xFEQbB!\xA4Y\x8A+G\xBE\xFB\xEE\xC7\xF8\x9C\xE2\x97[=䥱\xD9&yoڴz\xF2\x8A\xB3;\xB6\xBDd\xDB\xB0\xB7"\xD6\xCC[\xF1ݭ
\xD9+\xEC&\xEFL\xC4W\xEE潆3\xFA\xA1\x93Bi
+WH\xA5
+\xB9\!\x97+\xA4R\x99T\xAE\x90Jm\x89\xB6\xE4\xF7\x9A0|\x96\x87\x87\xF7\x84\xE1\xE3}\xFC\xF1'\x95\xA9\x9E\xB6\xF1\xA0n\xDF\xC1\xE6G7\xAE\x9B\xEE\xB6\xE8\xCA\xD3W>\x85\xE6W\xB9S<\xCD|\xFC\xFCI\xAE|ز]\xBB\xBE[\x91#}\xA9\x92/w\xB2\xCC{\xD9\xC5R\xB5\x9D\xB3y_~0+\xBE\xA3\xAB\xBE\xFF\xE8\x83\xC8\xE2\x97\xDDa=\xC6ľs\xF6\xAA\xF9^ӷ\xC6\xFDC\xEFԛ\x88&\x85!\x84B\x9Aw?j݇\xA1\xE2&\xC9}'\xCD\xF8\xE4\xC3q\xE6-\xCF\xED\xC6\xEB\xE6\xB6\xAD\xCA{\xD9\xFEb\xA0\xA2\xCD\xF1\xE1\xBDSk\xBCw\xA56\x9B\xE5\xB5\xE7\xC8\xC2>\xEDڸ\x9F\xD7H\xBF\xEB\xB0\xD9=\xB6\xEEL\x93ʪ^uW\xC5\xC9\xE1\xFE\xF1\xA2\xCD3\xADʞ\xE5\xE7=\xCF˔H\x92\x92~K\xAB\x9B"\xC6\xD0\xE0\xE6[\xBE\xAE\xFD˔̉;rL"p\x9B0\xBCgG\xAE\*+\x96J\xF3\xF2\x9EH\xE2Nݖ\xFB~\xBE\xDA\xF5
\xB5\x8B\xC6\xE0\xC1\xB9\xAD\x81\x91\xE9\x86\xFD]\x82V-\xDCY\x8C\xD9\xF2\xB0Oƺu\xF4X\xF0\xD1r\xD3W\x99\x8A\xB9\xECY
\x80\x9C\xBCb)+˽v\xE5v\xB9\xF9$W\xD1\xF9\xDC\xCE\xFF\xC4+2\xD0\xE5o\xB0 IEND\xAEB`\x82
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/cgi/testdata/small.png
===================================================================
--- MacRuby/trunk/test/test-mri/test/cgi/testdata/small.png (rev 0)
+++ MacRuby/trunk/test/test-mri/test/cgi/testdata/small.png 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,5 @@
+\x89PNG
+
+
+IHDR \xB4Э IDAT(\x91c\xFC\xFF\xFF?\x89\x80\x89T
+\xA3zF\xF5\x8C\xEA\x81 \x8Ah\xEE,\x99 IEND\xAEB`\x82
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/csv/line_endings.gz
===================================================================
--- MacRuby/trunk/test/test-mri/test/csv/line_endings.gz (rev 0)
+++ MacRuby/trunk/test/test-mri/test/csv/line_endings.gz 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+\x8B){QG line_endings.csv \xCB\xCFK\xD5))\xCF\xD7)\xC9(JM\xE5\xE52\xD41\xD21\xE6\xE5 {Γ\x9D
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/csv/test_csv_parsing.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/csv/test_csv_parsing.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/csv/test_csv_parsing.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,220 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+
+# tc_csv_parsing.rb
+#
+# Created by James Edward Gray II on 2005-10-31.
+# Copyright 2005 James Edward Gray II. You can redistribute or modify this code
+# under the terms of Ruby's license.
+
+require "test/unit"
+require "timeout"
+
+require "csv"
+
+#
+# Following tests are my interpretation of the
+# {CSV RCF}[http://www.ietf.org/rfc/rfc4180.txt]. I only deviate from that
+# document in one place (intentionally) and that is to make the default row
+# separator <tt>$/</tt>.
+#
+class TestCSVParsing < Test::Unit::TestCase
+ BIG_DATA = "123456789\n" * 1024
+
+ def test_mastering_regex_example
+ ex = %Q{Ten Thousand,10000, 2710 ,,"10,000","It's ""10 Grand"", baby",10K}
+ assert_equal( [ "Ten Thousand", "10000", " 2710 ", nil, "10,000",
+ "It's \"10 Grand\", baby", "10K" ],
+ CSV.parse_line(ex) )
+ end
+
+ # Old Ruby 1.8 CSV library tests.
+ def test_std_lib_csv
+ [ ["\t", ["\t"]],
+ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
+ ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
+ ["\"\"\"\n\",\"\"\"\n\"", ["\"\n", "\"\n"]],
+ ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
+ ["\"\"", [""]],
+ ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
+ ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
+ ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
+ ["foo,\"\",baz", ["foo", "", "baz"]],
+ ["\",\"", [","]],
+ ["foo", ["foo"]],
+ [",,", [nil, nil, nil]],
+ [",", [nil, nil]],
+ ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
+ ["foo,,baz", ["foo", nil, "baz"]],
+ ["\"\"\"\r\",\"\"\"\r\"", ["\"\r", "\"\r"]],
+ ["\",\",\",\"", [",", ","]],
+ ["foo,bar,", ["foo", "bar", nil]],
+ [",foo,bar", [nil, "foo", "bar"]],
+ ["foo,bar", ["foo", "bar"]],
+ [";", [";"]],
+ ["\t,\t", ["\t", "\t"]],
+ ["foo,\"\r\n\r\",baz", ["foo", "\r\n\r", "baz"]],
+ ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
+ ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
+ [";,;", [";", ";"]] ].each do |csv_test|
+ assert_equal(csv_test.last, CSV.parse_line(csv_test.first))
+ end
+
+ [ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
+ ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
+ ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
+ ["\"\"", [""]],
+ ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
+ ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
+ ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
+ ["foo,\"\",baz", ["foo", "", "baz"]],
+ ["foo", ["foo"]],
+ [",,", [nil, nil, nil]],
+ [",", [nil, nil]],
+ ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
+ ["foo,,baz", ["foo", nil, "baz"]],
+ ["foo,bar", ["foo", "bar"]],
+ ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
+ ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]] ].each do |csv_test|
+ assert_equal(csv_test.last, CSV.parse_line(csv_test.first))
+ end
+ end
+
+ # From: http://ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-core/6496
+ def test_aras_edge_cases
+ [ [%Q{a,b}, ["a", "b"]],
+ [%Q{a,"""b"""}, ["a", "\"b\""]],
+ [%Q{a,"""b"}, ["a", "\"b"]],
+ [%Q{a,"b"""}, ["a", "b\""]],
+ [%Q{a,"\nb"""}, ["a", "\nb\""]],
+ [%Q{a,"""\nb"}, ["a", "\"\nb"]],
+ [%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
+ [%Q{a,"""\nb\n""",\nc}, ["a", "\"\nb\n\"", nil]],
+ [%Q{a,,,}, ["a", nil, nil, nil]],
+ [%Q{,}, [nil, nil]],
+ [%Q{"",""}, ["", ""]],
+ [%Q{""""}, ["\""]],
+ [%Q{"""",""}, ["\"",""]],
+ [%Q{,""}, [nil,""]],
+ [%Q{,"\r"}, [nil,"\r"]],
+ [%Q{"\r\n,"}, ["\r\n,"]],
+ [%Q{"\r\n,",}, ["\r\n,", nil]] ].each do |edge_case|
+ assert_equal(edge_case.last, CSV.parse_line(edge_case.first))
+ end
+ end
+
+ def test_james_edge_cases
+ # A read at eof? should return nil.
+ assert_equal(nil, CSV.parse_line(""))
+ #
+ # With Ruby 1.8 CSV it's impossible to tell an empty line from a line
+ # containing a single +nil+ field. The old CSV library returns
+ # <tt>[nil]</tt> in these cases, but <tt>Array.new</tt> makes more sense to
+ # me.
+ #
+ assert_equal(Array.new, CSV.parse_line("\n1,2,3\n"))
+ end
+
+ def test_rob_edge_cases
+ [ [%Q{"a\nb"}, ["a\nb"]],
+ [%Q{"\n\n\n"}, ["\n\n\n"]],
+ [%Q{a,"b\n\nc"}, ['a', "b\n\nc"]],
+ [%Q{,"\r\n"}, [nil,"\r\n"]],
+ [%Q{,"\r\n."}, [nil,"\r\n."]],
+ [%Q{"a\na","one newline"}, ["a\na", 'one newline']],
+ [%Q{"a\n\na","two newlines"}, ["a\n\na", 'two newlines']],
+ [%Q{"a\r\na","one CRLF"}, ["a\r\na", 'one CRLF']],
+ [%Q{"a\r\n\r\na","two CRLFs"}, ["a\r\n\r\na", 'two CRLFs']],
+ [%Q{with blank,"start\n\nfinish"\n}, ['with blank', "start\n\nfinish"]],
+ ].each do |edge_case|
+ assert_equal(edge_case.last, CSV.parse_line(edge_case.first))
+ end
+ end
+
+ def test_non_regex_edge_cases
+ # An early version of the non-regex parser fails this test
+ [ [ "foo,\"foo,bar,baz,foo\",\"foo\"",
+ ["foo", "foo,bar,baz,foo", "foo"] ] ].each do |edge_case|
+ assert_equal(edge_case.last, CSV.parse_line(edge_case.first))
+ end
+
+ assert_raise(CSV::MalformedCSVError) do
+ CSV.parse_line("1,\"23\"4\"5\", 6")
+ end
+ end
+
+ def test_malformed_csv
+ assert_raise(CSV::MalformedCSVError) do
+ CSV.parse_line("1,2\r,3", row_sep: "\n")
+ end
+
+ bad_data = <<-END_DATA.gsub(/^ +/, "")
+ line,1,abc
+ line,2,"def\nghi"
+
+ line,4,some\rjunk
+ line,5,jkl
+ END_DATA
+ lines = bad_data.lines.to_a
+ assert_equal(6, lines.size)
+ assert_match(/\Aline,4/, lines.find { |l| l =~ /some\rjunk/ })
+
+ csv = CSV.new(bad_data)
+ begin
+ loop do
+ assert_not_nil(csv.shift)
+ assert_send([csv.lineno, :<, 4])
+ end
+ rescue CSV::MalformedCSVError
+ assert_equal( "Unquoted fields do not allow \\r or \\n (line 4).",
+ $!.message )
+ end
+
+ assert_raise(CSV::MalformedCSVError) { CSV.parse_line('1,2,"3...') }
+
+ bad_data = <<-END_DATA.gsub(/^ +/, "")
+ line,1,abc
+ line,2,"def\nghi"
+
+ line,4,8'10"
+ line,5,jkl
+ END_DATA
+ lines = bad_data.lines.to_a
+ assert_equal(6, lines.size)
+ assert_match(/\Aline,4/, lines.find { |l| l =~ /8'10"/ })
+
+ csv = CSV.new(bad_data)
+ begin
+ loop do
+ assert_not_nil(csv.shift)
+ assert_send([csv.lineno, :<, 4])
+ end
+ rescue CSV::MalformedCSVError
+ assert_equal("Illegal quoting on line 4.", $!.message)
+ end
+ end
+
+ def test_the_parse_fails_fast_when_it_can_for_unquoted_fields
+ assert_parse_errors_out('valid,fields,bad start"' + BIG_DATA)
+ end
+
+ def test_the_parse_fails_fast_when_it_can_for_unescaped_quotes
+ assert_parse_errors_out('valid,fields,"bad start"unescaped' + BIG_DATA)
+ end
+
+ def test_field_size_limit_controls_lookahead
+ assert_parse_errors_out( 'valid,fields,"' + BIG_DATA + '"',
+ field_size_limit: 2048 )
+ end
+
+ private
+
+ def assert_parse_errors_out(*args)
+ assert_raise(CSV::MalformedCSVError) do
+ Timeout.timeout(0.2) do
+ CSV.parse(*args)
+ fail("Parse didn't error out")
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/csv/test_csv_writing.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/csv/test_csv_writing.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/csv/test_csv_writing.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,97 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+
+# tc_csv_writing.rb
+#
+# Created by James Edward Gray II on 2005-10-31.
+# Copyright 2005 James Edward Gray II. You can redistribute or modify this code
+# under the terms of Ruby's license.
+
+require "test/unit"
+
+require "csv"
+
+class TestCSVWriting < Test::Unit::TestCase
+ def test_writing
+ [ ["\t", ["\t"]],
+ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
+ ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
+ ["\"\"\"\n\",\"\"\"\n\"", ["\"\n", "\"\n"]],
+ ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
+ ["\"\"", [""]],
+ ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
+ ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
+ ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
+ ["foo,\"\",baz", ["foo", "", "baz"]],
+ ["\",\"", [","]],
+ ["foo", ["foo"]],
+ [",,", [nil, nil, nil]],
+ [",", [nil, nil]],
+ ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
+ ["foo,,baz", ["foo", nil, "baz"]],
+ ["\"\"\"\r\",\"\"\"\r\"", ["\"\r", "\"\r"]],
+ ["\",\",\",\"", [",", ","]],
+ ["foo,bar,", ["foo", "bar", nil]],
+ [",foo,bar", [nil, "foo", "bar"]],
+ ["foo,bar", ["foo", "bar"]],
+ [";", [";"]],
+ ["\t,\t", ["\t", "\t"]],
+ ["foo,\"\r\n\r\",baz", ["foo", "\r\n\r", "baz"]],
+ ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
+ ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
+ [";,;", [";", ";"]],
+ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
+ ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
+ ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
+ ["\"\"", [""]],
+ ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
+ ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
+ ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
+ ["foo,\"\",baz", ["foo", "", "baz"]],
+ ["foo", ["foo"]],
+ [",,", [nil, nil, nil]],
+ [",", [nil, nil]],
+ ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
+ ["foo,,baz", ["foo", nil, "baz"]],
+ ["foo,bar", ["foo", "bar"]],
+ ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
+ ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
+ [%Q{a,b}, ["a", "b"]],
+ [%Q{a,"""b"""}, ["a", "\"b\""]],
+ [%Q{a,"""b"}, ["a", "\"b"]],
+ [%Q{a,"b"""}, ["a", "b\""]],
+ [%Q{a,"\nb"""}, ["a", "\nb\""]],
+ [%Q{a,"""\nb"}, ["a", "\"\nb"]],
+ [%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
+ [%Q{a,"""\nb\n""",}, ["a", "\"\nb\n\"", nil]],
+ [%Q{a,,,}, ["a", nil, nil, nil]],
+ [%Q{,}, [nil, nil]],
+ [%Q{"",""}, ["", ""]],
+ [%Q{""""}, ["\""]],
+ [%Q{"""",""}, ["\"",""]],
+ [%Q{,""}, [nil,""]],
+ [%Q{,"\r"}, [nil,"\r"]],
+ [%Q{"\r\n,"}, ["\r\n,"]],
+ [%Q{"\r\n,",}, ["\r\n,", nil]] ].each do |test_case|
+ assert_equal(test_case.first + $/, CSV.generate_line(test_case.last))
+ end
+ end
+
+ def test_col_sep
+ assert_equal( "a;b;;c\n", CSV.generate_line( ["a", "b", nil, "c"],
+ col_sep: ";" ) )
+ assert_equal( "a\tb\t\tc\n", CSV.generate_line( ["a", "b", nil, "c"],
+ col_sep: "\t" ) )
+ end
+
+ def test_row_sep
+ assert_equal( "a,b,,c\r\n", CSV.generate_line( ["a", "b", nil, "c"],
+ row_sep: "\r\n" ) )
+ end
+
+ def test_force_quotes
+ assert_equal( %Q{"1","b","","already ""quoted"""\n},
+ CSV.generate_line( [1, "b", nil, %Q{already "quoted"}],
+ force_quotes: true ) )
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/csv/test_data_converters.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/csv/test_data_converters.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/csv/test_data_converters.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,261 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+
+# tc_data_converters.rb
+#
+# Created by James Edward Gray II on 2005-10-31.
+# Copyright 2005 James Edward Gray II. You can redistribute or modify this code
+# under the terms of Ruby's license.
+
+require "test/unit"
+
+require "csv"
+
+class TestDataConverters < Test::Unit::TestCase
+ def setup
+ @data = "Numbers,:integer,1,:float,3.015"
+ @parser = CSV.new(@data)
+
+ @custom = lambda { |field| field =~ /\A:(\S.*?)\s*\Z/ ? $1.to_sym : field }
+
+ @win_safe_time_str = Time.now.strftime("%a %b %d %H:%M:%S %Y")
+ end
+
+ def test_builtin_integer_converter
+ # does convert
+ [-5, 1, 10000000000].each do |n|
+ assert_equal(n, CSV::Converters[:integer][n.to_s])
+ end
+
+ # does not convert
+ (%w{junk 1.0} + [""]).each do |str|
+ assert_equal(str, CSV::Converters[:integer][str])
+ end
+ end
+
+ def test_builtin_float_converter
+ # does convert
+ [-5.1234, 0, 2.3e-11].each do |n|
+ assert_equal(n, CSV::Converters[:float][n.to_s])
+ end
+
+ # does not convert
+ (%w{junk 1..0 .015F} + [""]).each do |str|
+ assert_equal(str, CSV::Converters[:float][str])
+ end
+ end
+
+ def test_builtin_date_converter
+ # does convert
+ assert_instance_of(
+ Date,
+ CSV::Converters[:date][@win_safe_time_str.sub(/\d+:\d+:\d+ /, "")]
+ )
+
+ # does not convert
+ assert_instance_of(String, CSV::Converters[:date]["junk"])
+ end
+
+ def test_builtin_date_time_converter
+ # does convert
+ assert_instance_of( DateTime,
+ CSV::Converters[:date_time][@win_safe_time_str] )
+
+ # does not convert
+ assert_instance_of(String, CSV::Converters[:date_time]["junk"])
+ end
+
+ def test_convert_with_builtin
+ # setup parser...
+ assert(@parser.respond_to?(:convert))
+ assert_nothing_raised(Exception) { @parser.convert(:integer) }
+
+ # and use
+ assert_equal(["Numbers", ":integer", 1, ":float", "3.015"], @parser.shift)
+
+ setup # reset
+
+ # setup parser...
+ assert_nothing_raised(Exception) { @parser.convert(:float) }
+
+ # and use
+ assert_equal(["Numbers", ":integer", 1.0, ":float", 3.015], @parser.shift)
+ end
+
+ def test_convert_order
+ # floats first, then integers...
+ assert_nothing_raised(Exception) do
+ @parser.convert(:float)
+ @parser.convert(:integer)
+ end
+
+ # gets us nothing but floats
+ assert_equal( [String, String, Float, String, Float],
+ @parser.shift.map { |field| field.class } )
+
+ setup # reset
+
+ # integers have precendance...
+ assert_nothing_raised(Exception) do
+ @parser.convert(:integer)
+ @parser.convert(:float)
+ end
+
+ # gives us proper number conversion
+ assert_equal( [String, String, Fixnum, String, Float],
+ @parser.shift.map { |field| field.class } )
+ end
+
+ def test_builtin_numeric_combo_converter
+ # setup parser...
+ assert_nothing_raised(Exception) { @parser.convert(:numeric) }
+
+ # and use
+ assert_equal( [String, String, Fixnum, String, Float],
+ @parser.shift.map { |field| field.class } )
+ end
+
+ def test_builtin_all_nested_combo_converter
+ # setup parser...
+ @data << ",#{@win_safe_time_str}" # add a DateTime field
+ @parser = CSV.new(@data) # reset parser
+ assert_nothing_raised(Exception) { @parser.convert(:all) }
+
+ # and use
+ assert_equal( [String, String, Fixnum, String, Float, DateTime],
+ @parser.shift.map { |field| field.class } )
+ end
+
+ def test_convert_with_custom_code
+ # define custom converter...
+ assert_nothing_raised(Exception) do
+ @parser.convert { |field| field =~ /\A:(\S.*?)\s*\Z/ ? $1.to_sym : field }
+ end
+
+ # and use
+ assert_equal(["Numbers", :integer, "1", :float, "3.015"], @parser.shift)
+
+ setup # reset
+
+ # mix built-in and custom...
+ assert_nothing_raised(Exception) { @parser.convert(:numeric) }
+ assert_nothing_raised(Exception) { @parser.convert(&@custom) }
+
+ # and use
+ assert_equal(["Numbers", :integer, 1, :float, 3.015], @parser.shift)
+ end
+
+ def test_convert_with_custom_code_using_field_info
+ # define custom converter that uses field information...
+ assert_nothing_raised(Exception) do
+ @parser.convert do |field, info|
+ assert_equal(1, info.line)
+ info.index == 4 ? Float(field).floor : field
+ end
+ end
+
+ # and use
+ assert_equal(["Numbers", ":integer", "1", ":float", 3], @parser.shift)
+ end
+
+ def test_convert_with_custom_code_using_field_info_header
+ @parser = CSV.new(@data, headers: %w{one two three four five})
+
+ # define custom converter that uses field header information...
+ assert_nothing_raised(Exception) do
+ @parser.convert do |field, info|
+ info.header == "three" ? Integer(field) * 100 : field
+ end
+ end
+
+ # and use
+ assert_equal( ["Numbers", ":integer", 100, ":float", "3.015"],
+ @parser.shift.fields )
+ end
+
+ def test_shortcut_interface
+ assert_equal( ["Numbers", ":integer", 1, ":float", 3.015],
+ CSV.parse_line(@data, converters: :numeric) )
+
+ assert_equal( ["Numbers", ":integer", 1, ":float", 3.015],
+ CSV.parse_line(@data, converters: [:integer, :float]) )
+
+ assert_equal( ["Numbers", :integer, 1, :float, 3.015],
+ CSV.parse_line(@data, converters: [:numeric, @custom]) )
+ end
+
+ def test_unconverted_fields
+ [ [ @data,
+ ["Numbers", :integer, 1, :float, 3.015],
+ %w{Numbers :integer 1 :float 3.015} ],
+ ["\n", Array.new, Array.new] ].each do |test, fields, unconverted|
+ row = nil
+ assert_nothing_raised(Exception) do
+ row = CSV.parse_line( test,
+ converters: [:numeric, @custom],
+ unconverted_fields: true )
+ end
+ assert_not_nil(row)
+ assert_equal(fields, row)
+ assert_respond_to(row, :unconverted_fields)
+ assert_equal(unconverted, row.unconverted_fields)
+ end
+
+ data = <<-END_CSV.gsub(/^\s+/, "")
+ first,second,third
+ 1,2,3
+ END_CSV
+ row = nil
+ assert_nothing_raised(Exception) do
+ row = CSV.parse_line( data,
+ converters: :numeric,
+ unconverted_fields: true,
+ headers: :first_row )
+ end
+ assert_not_nil(row)
+ assert_equal([["first", 1], ["second", 2], ["third", 3]], row.to_a)
+ assert_respond_to(row, :unconverted_fields)
+ assert_equal(%w{1 2 3}, row.unconverted_fields)
+
+ assert_nothing_raised(Exception) do
+ row = CSV.parse_line( data,
+ converters: :numeric,
+ unconverted_fields: true,
+ headers: :first_row,
+ return_headers: true )
+ end
+ assert_not_nil(row)
+ assert_equal( [%w{first first}, %w{second second}, %w{third third}],
+ row.to_a )
+ assert_respond_to(row, :unconverted_fields)
+ assert_equal(%w{first second third}, row.unconverted_fields)
+
+ assert_nothing_raised(Exception) do
+ row = CSV.parse_line( data,
+ converters: :numeric,
+ unconverted_fields: true,
+ headers: :first_row,
+ return_headers: true,
+ header_converters: :symbol )
+ end
+ assert_not_nil(row)
+ assert_equal( [[:first, "first"], [:second, "second"], [:third, "third"]],
+ row.to_a )
+ assert_respond_to(row, :unconverted_fields)
+ assert_equal(%w{first second third}, row.unconverted_fields)
+
+ assert_nothing_raised(Exception) do
+ row = CSV.parse_line( data,
+ converters: :numeric,
+ unconverted_fields: true,
+ headers: %w{my new headers},
+ return_headers: true,
+ header_converters: :symbol )
+ end
+ assert_not_nil(row)
+ assert_equal( [[:my, "my"], [:new, "new"], [:headers, "headers"]],
+ row.to_a )
+ assert_respond_to(row, :unconverted_fields)
+ assert_equal(Array.new, row.unconverted_fields)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/csv/test_encodings.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/csv/test_encodings.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/csv/test_encodings.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,260 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+
+# tc_encodings.rb
+#
+# Created by James Edward Gray II on 2008-09-13.
+# Copyright 2008 James Edward Gray II. You can redistribute or modify this code
+# under the terms of Ruby's license.
+
+require "test/unit"
+
+require "csv"
+
+class TestEncodings < Test::Unit::TestCase
+ def setup
+ @temp_csv_path = File.join(File.dirname(__FILE__), "temp.csv")
+ end
+
+ def teardown
+ File.unlink(@temp_csv_path) if File.exist? @temp_csv_path
+ end
+
+ ########################################
+ ### Hand Test Some Popular Encodings ###
+ ########################################
+
+ def test_parses_utf8_encoding
+ assert_parses( [ %w[ one two … ],
+ %w[ 1 … 3 ],
+ %w[ … 5 6 ] ], "UTF-8" )
+ end
+
+ def test_parses_latin1_encoding
+ assert_parses( [ %w[ one two Résumé ],
+ %w[ 1 Résumé 3 ],
+ %w[ Résumé 5 6 ] ], "ISO-8859-1" )
+ end
+
+ def test_parses_utf16be_encoding
+ assert_parses( [ %w[ one two … ],
+ %w[ 1 … 3 ],
+ %w[ … 5 6 ] ], "UTF-16BE" )
+ end
+
+ def test_parses_shift_jis_encoding
+ assert_parses( [ %w[ 一 二 三 ],
+ %w[ 四 五 六 ],
+ %w[ 七 八 九 ] ], "Shift_JIS" )
+ end
+
+ ###########################################################
+ ### Try Simple Reading for All Non-dummy Ruby Encodings ###
+ ###########################################################
+
+ def test_reading_with_most_encodings
+ each_encoding do |encoding|
+ begin
+ assert_parses( [ %w[ abc def ],
+ %w[ ghi jkl ] ], encoding )
+ rescue Encoding::ConverterNotFoundError
+ fail("Failed to support #{encoding.name}.")
+ end
+ end
+ end
+
+ def test_regular_expression_escaping
+ each_encoding do |encoding|
+ begin
+ assert_parses( [ %w[ abc def ],
+ %w[ ghi jkl ] ], encoding, col_sep: "|" )
+ rescue Encoding::ConverterNotFoundError
+ fail("Failed to properly escape #{encoding.name}.")
+ end
+ end
+ end
+
+ #######################################################################
+ ### Stress Test ASCII Compatible and Non-ASCII Compatible Encodings ###
+ #######################################################################
+
+ def test_auto_line_ending_detection
+ # arrange data to place a \r at the end of CSV's read ahead point
+ encode_for_tests([["a" * 509]], row_sep: "\r\n") do |data|
+ assert_equal("\r\n".encode(data.encoding), CSV.new(data).row_sep)
+ end
+ end
+
+ def test_csv_chars_are_transcoded
+ encode_for_tests([%w[abc def]]) do |data|
+ %w[col_sep row_sep quote_char].each do |csv_char|
+ assert_equal( "|".encode(data.encoding),
+ CSV.new(data, csv_char.to_sym => "|").send(csv_char) )
+ end
+ end
+ end
+
+ def test_parser_works_with_encoded_headers
+ encode_for_tests([%w[one two three], %w[1 2 3]]) do |data|
+ parsed = CSV.parse(data, headers: true)
+ assert( parsed.headers.all? { |h| h.encoding == data.encoding },
+ "Wrong data encoding." )
+ parsed.each do |row|
+ assert( row.fields.all? { |f| f.encoding == data.encoding },
+ "Wrong data encoding." )
+ end
+ end
+ end
+
+ def test_built_in_converters_transcode_to_utf_8_then_convert
+ encode_for_tests([%w[one two three], %w[1 2 3]]) do |data|
+ parsed = CSV.parse(data, converters: :integer)
+ assert( parsed[0].all? { |f| f.encoding == data.encoding },
+ "Wrong data encoding." )
+ assert_equal([1, 2, 3], parsed[1])
+ end
+ end
+
+ def test_built_in_header_converters_transcode_to_utf_8_then_convert
+ encode_for_tests([%w[one two three], %w[1 2 3]]) do |data|
+ parsed = CSV.parse( data, headers: true,
+ header_converters: :downcase )
+ assert( parsed.headers.all? { |h| h.encoding.name == "UTF-8" },
+ "Wrong data encoding." )
+ assert( parsed[0].fields.all? { |f| f.encoding == data.encoding },
+ "Wrong data encoding." )
+ end
+ end
+
+ def test_open_allows_you_to_set_encodings
+ encode_for_tests([%w[abc def]]) do |data|
+ # read and write in encoding
+ File.open(@temp_csv_path, "wb:#{data.encoding.name}") { |f| f << data }
+ CSV.open(@temp_csv_path, "rb:#{data.encoding.name}") do |csv|
+ csv.each do |row|
+ assert( row.all? { |f| f.encoding == data.encoding },
+ "Wrong data encoding." )
+ end
+ end
+
+ # read and write with transcoding
+ File.open(@temp_csv_path, "wb:UTF-32BE:#{data.encoding.name}") do |f|
+ f << data
+ end
+ CSV.open(@temp_csv_path, "rb:UTF-32BE:#{data.encoding.name}") do |csv|
+ csv.each do |row|
+ assert( row.all? { |f| f.encoding == data.encoding },
+ "Wrong data encoding." )
+ end
+ end
+ end
+ end
+
+ def test_foreach_allows_you_to_set_encodings
+ encode_for_tests([%w[abc def]]) do |data|
+ # read and write in encoding
+ File.open(@temp_csv_path, "wb:#{data.encoding.name}") { |f| f << data }
+ CSV.foreach(@temp_csv_path, encoding: data.encoding.name) do |row|
+ assert( row.all? { |f| f.encoding == data.encoding },
+ "Wrong data encoding." )
+ end
+
+ # read and write with transcoding
+ File.open(@temp_csv_path, "wb:UTF-32BE:#{data.encoding.name}") do |f|
+ f << data
+ end
+ CSV.foreach( @temp_csv_path,
+ encoding: "UTF-32BE:#{data.encoding.name}" ) do |row|
+ assert( row.all? { |f| f.encoding == data.encoding },
+ "Wrong data encoding." )
+ end
+ end
+ end
+
+ def test_read_allows_you_to_set_encodings
+ encode_for_tests([%w[abc def]]) do |data|
+ # read and write in encoding
+ File.open(@temp_csv_path, "wb:#{data.encoding.name}") { |f| f << data }
+ rows = CSV.read(@temp_csv_path, encoding: data.encoding.name)
+ assert( rows.flatten.all? { |f| f.encoding == data.encoding },
+ "Wrong data encoding." )
+
+ # read and write with transcoding
+ File.open(@temp_csv_path, "wb:UTF-32BE:#{data.encoding.name}") do |f|
+ f << data
+ end
+ rows = CSV.read( @temp_csv_path,
+ encoding: "UTF-32BE:#{data.encoding.name}" )
+ assert( rows.flatten.all? { |f| f.encoding == data.encoding },
+ "Wrong data encoding." )
+ end
+ end
+
+ #################################
+ ### Write CSV in any Encoding ###
+ #################################
+
+ def test_can_write_csv_in_any_encoding
+ each_encoding do |encoding|
+ # test generate_line with encoding hint
+ begin
+ csv = %w[abc d|ef].map { |f| f.encode(encoding) }.
+ to_csv(col_sep: "|", encoding: encoding.name)
+ rescue Encoding::ConverterNotFoundError
+ next
+ end
+ assert_equal(encoding, csv.encoding)
+
+ # test generate_line with encoding guessing from fields
+ csv = %w[abc d|ef].map { |f| f.encode(encoding) }.to_csv(col_sep: "|")
+ assert_equal(encoding, csv.encoding)
+
+ # writing to files
+ data = encode_ary([%w[abc d,ef], %w[123 456 ]], encoding)
+ CSV.open(@temp_csv_path, "wb:#{encoding.name}") do |f|
+ data.each { |row| f << row }
+ end
+ assert_equal(data, CSV.read(@temp_csv_path, encoding: encoding.name))
+ end
+ end
+
+ private
+
+ def assert_parses(fields, encoding, options = { })
+ encoding = Encoding.find(encoding) unless encoding.is_a? Encoding
+ fields = encode_ary(fields, encoding)
+ parsed = CSV.parse(ary_to_data(fields, options), options)
+ assert_equal(fields, parsed)
+ parsed.flatten.each_with_index do |field, i|
+ assert_equal(encoding, field.encoding, "Field[#{i + 1}] was transcoded.")
+ end
+ end
+
+ def encode_ary(ary, encoding)
+ ary.map { |row| row.map { |field| field.encode(encoding) } }
+ end
+
+ def ary_to_data(ary, options = { })
+ encoding = ary.flatten.first.encoding
+ quote_char = (options[:quote_char] || '"').encode(encoding)
+ col_sep = (options[:col_sep] || ",").encode(encoding)
+ row_sep = (options[:row_sep] || "\n").encode(encoding)
+ ary.map { |row|
+ row.map { |field|
+ [quote_char, field.encode(encoding), quote_char].join
+ }.join(col_sep) + row_sep
+ }.join.encode(encoding)
+ end
+
+ def encode_for_tests(data, options = { })
+ yield ary_to_data(encode_ary(data, "UTF-8"), options)
+ yield ary_to_data(encode_ary(data, "UTF-16BE"), options)
+ end
+
+ def each_encoding
+ Encoding.list.each do |encoding|
+ next if encoding.dummy? # skip "dummy" encodings
+ yield encoding
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/csv/test_features.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/csv/test_features.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/csv/test_features.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,267 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+
+# tc_features.rb
+#
+# Created by James Edward Gray II on 2005-10-31.
+# Copyright 2005 James Edward Gray II. You can redistribute or modify this code
+# under the terms of Ruby's license.
+
+require "test/unit"
+require "zlib"
+
+require "csv"
+
+class TestCSVFeatures < Test::Unit::TestCase
+ TEST_CASES = [ [%Q{a,b}, ["a", "b"]],
+ [%Q{a,"""b"""}, ["a", "\"b\""]],
+ [%Q{a,"""b"}, ["a", "\"b"]],
+ [%Q{a,"b"""}, ["a", "b\""]],
+ [%Q{a,"\nb"""}, ["a", "\nb\""]],
+ [%Q{a,"""\nb"}, ["a", "\"\nb"]],
+ [%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
+ [%Q{a,"""\nb\n""",\nc}, ["a", "\"\nb\n\"", nil]],
+ [%Q{a,,,}, ["a", nil, nil, nil]],
+ [%Q{,}, [nil, nil]],
+ [%Q{"",""}, ["", ""]],
+ [%Q{""""}, ["\""]],
+ [%Q{"""",""}, ["\"",""]],
+ [%Q{,""}, [nil,""]],
+ [%Q{,"\r"}, [nil,"\r"]],
+ [%Q{"\r\n,"}, ["\r\n,"]],
+ [%Q{"\r\n,",}, ["\r\n,", nil]] ]
+
+ def setup
+ @sample_data = <<-END_DATA.gsub(/^ +/, "")
+ line,1,abc
+ line,2,"def\nghi"
+
+ line,4,jkl
+ END_DATA
+ @csv = CSV.new(@sample_data)
+ end
+
+ def test_col_sep
+ [";", "\t"].each do |sep|
+ TEST_CASES.each do |test_case|
+ assert_equal( test_case.last.map { |t| t.tr(",", sep) unless t.nil? },
+ CSV.parse_line( test_case.first.tr(",", sep),
+ col_sep: sep ) )
+ end
+ end
+ assert_equal([",,,", nil], CSV.parse_line(",,,;", col_sep: ";"))
+ end
+
+ def test_row_sep
+ assert_raise(CSV::MalformedCSVError) do
+ CSV.parse_line("1,2,3\n,4,5\r\n", row_sep: "\r\n")
+ end
+ assert_equal( ["1", "2", "3\n", "4", "5"],
+ CSV.parse_line(%Q{1,2,"3\n",4,5\r\n}, row_sep: "\r\n"))
+ end
+
+ def test_quote_char
+ TEST_CASES.each do |test_case|
+ assert_equal( test_case.last.map { |t| t.tr('"', "'") unless t.nil? },
+ CSV.parse_line( test_case.first.tr('"', "'"),
+ quote_char: "'" ) )
+ end
+ end
+
+ def test_csv_char_readers
+ %w[col_sep row_sep quote_char].each do |reader|
+ csv = CSV.new("abc,def", reader.to_sym => "|")
+ assert_equal("|", csv.send(reader))
+ end
+ end
+
+ def test_row_sep_auto_discovery
+ ["\r\n", "\n", "\r"].each do |line_end|
+ data = "1,2,3#{line_end}4,5#{line_end}"
+ discovered = CSV.new(data).row_sep
+ assert_equal(line_end, discovered)
+ end
+
+ assert_equal("\n", CSV.new("\n\r\n\r").row_sep)
+
+ assert_equal($/, CSV.new("").row_sep)
+
+ assert_equal($/, CSV.new(STDERR).row_sep)
+ end
+
+ def test_lineno
+ assert_equal(5, @sample_data.lines.to_a.size)
+
+ 4.times do |line_count|
+ assert_equal(line_count, @csv.lineno)
+ assert_not_nil(@csv.shift)
+ assert_equal(line_count + 1, @csv.lineno)
+ end
+ assert_nil(@csv.shift)
+ end
+
+ def test_readline
+ test_lineno
+
+ @csv.rewind
+
+ test_lineno
+ end
+
+ def test_unknown_options
+ assert_raise(ArgumentError) { CSV.new(String.new, unknown: :error) }
+ end
+
+ def test_skip_blanks
+ assert_equal(4, @csv.to_a.size)
+
+ @csv = CSV.new(@sample_data, skip_blanks: true)
+
+ count = 0
+ @csv.each do |row|
+ count += 1
+ assert_equal("line", row.first)
+ end
+ assert_equal(3, count)
+ end
+
+ def test_csv_behavior_readers
+ %w[ unconverted_fields return_headers write_headers
+ skip_blanks force_quotes ].each do |behavior|
+ assert( !CSV.new("abc,def").send("#{behavior}?"),
+ "Behavior defaulted to on." )
+ csv = CSV.new("abc,def", behavior.to_sym => true)
+ assert(csv.send("#{behavior}?"), "Behavior change now registered.")
+ end
+ end
+
+ def test_converters_reader
+ # no change
+ assert_equal( [:integer],
+ CSV.new("abc,def", converters: [:integer]).converters )
+
+ # just one
+ assert_equal( [:integer],
+ CSV.new("abc,def", converters: :integer).converters )
+
+ # expanded
+ assert_equal( [:integer, :float],
+ CSV.new("abc,def", converters: :numeric).converters )
+
+ # custom
+ csv = CSV.new("abc,def", converters: [:integer, lambda { }])
+ assert_equal(2, csv.converters.size)
+ assert_equal(:integer, csv.converters.first)
+ assert_instance_of(Proc, csv.converters.last)
+ end
+
+ def test_header_converters_reader
+ # no change
+ hc = :header_converters
+ assert_equal([:downcase], CSV.new("abc,def", hc => [:downcase]).send(hc))
+
+ # just one
+ assert_equal([:downcase], CSV.new("abc,def", hc => :downcase).send(hc))
+
+ # custom
+ csv = CSV.new("abc,def", hc => [:symbol, lambda { }])
+ assert_equal(2, csv.send(hc).size)
+ assert_equal(:symbol, csv.send(hc).first)
+ assert_instance_of(Proc, csv.send(hc).last)
+ end
+
+ # reported by Kev Jackson
+ def test_failing_to_escape_col_sep_bug_fix
+ assert_nothing_raised(Exception) { CSV.new(String.new, col_sep: "|") }
+ end
+
+ # reported by Chris Roos
+ def test_failing_to_reset_headers_in_rewind_bug_fix
+ csv = CSV.new("forename,surname", headers: true, return_headers: true)
+ csv.each { |row| assert row.header_row? }
+ csv.rewind
+ csv.each { |row| assert row.header_row? }
+ end
+
+ # reported by Dave Burt
+ def test_leading_empty_fields_with_multibyte_col_sep_bug_fix
+ data = <<-END_DATA.gsub(/^\s+/, "")
+ <=><=>A<=>B<=>C
+ 1<=>2<=>3
+ END_DATA
+ parsed = CSV.parse(data, col_sep: "<=>")
+ assert_equal([[nil, nil, "A", "B", "C"], ["1", "2", "3"]], parsed)
+ end
+
+ def test_gzip_reader_bug_fix
+ zipped = nil
+ assert_nothing_raised(NoMethodError) do
+ zipped = CSV.new(
+ Zlib::GzipReader.open(
+ File.join(File.dirname(__FILE__), "line_endings.gz")
+ )
+ )
+ end
+ assert_equal("\r\n", zipped.row_sep)
+ end
+
+ def test_gzip_writer_bug_fix
+ file = File.join(File.dirname(__FILE__), "temp.gz")
+ zipped = nil
+ assert_nothing_raised(NoMethodError) do
+ zipped = CSV.new(Zlib::GzipWriter.open(file))
+ end
+ zipped << %w[one two three]
+ zipped << [1, 2, 3]
+ zipped.close
+
+ assert( Zlib::GzipReader.open(file) { |f| f.read }.
+ include?($INPUT_RECORD_SEPARATOR),
+ "@row_sep did not default" )
+ File.unlink(file)
+ end
+
+ def test_inspect_is_smart_about_io_types
+ str = CSV.new("string,data").inspect
+ assert(str.include?("io_type:StringIO"), "IO type not detected.")
+
+ str = CSV.new($stderr).inspect
+ assert(str.include?("io_type:$stderr"), "IO type not detected.")
+
+ path = File.join(File.dirname(__FILE__), "temp.csv")
+ File.open(path, "w") { |csv| csv << "one,two,three\n1,2,3\n" }
+ str = CSV.open(path) { |csv| csv.inspect }
+ assert(str.include?("io_type:File"), "IO type not detected.")
+ File.unlink(path)
+ end
+
+ def test_inspect_shows_key_attributes
+ str = @csv.inspect
+ %w[lineno col_sep row_sep quote_char].each do |attr_name|
+ assert_match(/\b#{attr_name}:[^\s>]+/, str)
+ end
+ end
+
+ def test_inspect_shows_headers_when_available
+ CSV.new("one,two,three\n1,2,3\n", headers: true) do |csv|
+ assert(csv.inspect.include?("headers:true"), "Header hint not shown.")
+ csv.shift # load headers
+ assert_match(/headers:\[[^\]]+\]/, csv.inspect)
+ end
+ end
+
+ def test_inspect_encoding_is_ascii_compatible
+ CSV.new("one,two,three\n1,2,3\n".encode("UTF-16BE")) do |csv|
+ assert( Encoding.compatible?( Encoding.find("US-ASCII"),
+ csv.inspect.encoding ),
+ "inspect() was not ASCII compatible." )
+ end
+ end
+
+ def test_version
+ assert_not_nil(CSV::VERSION)
+ assert_instance_of(String, CSV::VERSION)
+ assert(CSV::VERSION.frozen?)
+ assert_match(/\A\d\.\d\.\d\Z/, CSV::VERSION)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/csv/test_headers.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/csv/test_headers.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/csv/test_headers.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,288 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+
+# tc_headers.rb
+#
+# Created by James Edward Gray II on 2005-10-31.
+# Copyright 2005 James Edward Gray II. You can redistribute or modify this code
+# under the terms of Ruby's license.
+
+require "test/unit"
+
+require "csv"
+
+class TestCSVHeaders < Test::Unit::TestCase
+ def setup
+ @data = <<-END_CSV.gsub(/^\s+/, "")
+ first,second,third
+ A,B,C
+ 1,2,3
+ END_CSV
+ end
+
+ def test_first_row
+ [:first_row, true].each do |setting| # two names for the same setting
+ # activate headers
+ csv = nil
+ assert_nothing_raised(Exception) do
+ csv = CSV.parse(@data, headers: setting)
+ end
+
+ # first data row - skipping headers
+ row = csv[0]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([%w{first A}, %w{second B}, %w{third C}], row.to_a)
+
+ # second data row
+ row = csv[1]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([%w{first 1}, %w{second 2}, %w{third 3}], row.to_a)
+
+ # empty
+ assert_nil(csv[2])
+ end
+ end
+
+ def test_array_of_headers
+ # activate headers
+ csv = nil
+ assert_nothing_raised(Exception) do
+ csv = CSV.parse(@data, headers: [:my, :new, :headers])
+ end
+
+ # first data row - skipping headers
+ row = csv[0]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal( [[:my, "first"], [:new, "second"], [:headers, "third"]],
+ row.to_a )
+
+ # second data row
+ row = csv[1]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([[:my, "A"], [:new, "B"], [:headers, "C"]], row.to_a)
+
+ # third data row
+ row = csv[2]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([[:my, "1"], [:new, "2"], [:headers, "3"]], row.to_a)
+
+ # empty
+ assert_nil(csv[3])
+
+ # with return and convert
+ assert_nothing_raised(Exception) do
+ csv = CSV.parse( @data, headers: [:my, :new, :headers],
+ return_headers: true,
+ header_converters: lambda { |h| h.to_s } )
+ end
+ row = csv[0]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([["my", :my], ["new", :new], ["headers", :headers]], row.to_a)
+ assert(row.header_row?)
+ assert(!row.field_row?)
+ end
+
+ def test_csv_header_string
+ # activate headers
+ csv = nil
+ assert_nothing_raised(Exception) do
+ csv = CSV.parse(@data, headers: "my,new,headers")
+ end
+
+ # first data row - skipping headers
+ row = csv[0]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([%w{my first}, %w{new second}, %w{headers third}], row.to_a)
+
+ # second data row
+ row = csv[1]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([%w{my A}, %w{new B}, %w{headers C}], row.to_a)
+
+ # third data row
+ row = csv[2]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([%w{my 1}, %w{new 2}, %w{headers 3}], row.to_a)
+
+ # empty
+ assert_nil(csv[3])
+
+ # with return and convert
+ assert_nothing_raised(Exception) do
+ csv = CSV.parse( @data, headers: "my,new,headers",
+ return_headers: true,
+ header_converters: :symbol )
+ end
+ row = csv[0]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([[:my, "my"], [:new, "new"], [:headers, "headers"]], row.to_a)
+ assert(row.header_row?)
+ assert(!row.field_row?)
+ end
+
+ def test_csv_header_string_inherits_separators
+ # parse with custom col_sep
+ csv = nil
+ assert_nothing_raised(Exception) do
+ csv = CSV.parse( @data.tr(",", "|"), col_sep: "|",
+ headers: "my|new|headers" )
+ end
+
+ # verify headers were recognized
+ row = csv[0]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([%w{my first}, %w{new second}, %w{headers third}], row.to_a)
+ end
+
+ def test_return_headers
+ # activate headers and request they are returned
+ csv = nil
+ assert_nothing_raised(Exception) do
+ csv = CSV.parse(@data, headers: true, return_headers: true)
+ end
+
+ # header row
+ row = csv[0]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal( [%w{first first}, %w{second second}, %w{third third}],
+ row.to_a )
+ assert(row.header_row?)
+ assert(!row.field_row?)
+
+ # first data row - skipping headers
+ row = csv[1]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([%w{first A}, %w{second B}, %w{third C}], row.to_a)
+ assert(!row.header_row?)
+ assert(row.field_row?)
+
+ # second data row
+ row = csv[2]
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([%w{first 1}, %w{second 2}, %w{third 3}], row.to_a)
+ assert(!row.header_row?)
+ assert(row.field_row?)
+
+ # empty
+ assert_nil(csv[3])
+ end
+
+ def test_converters
+ # create test data where headers and fields look alike
+ data = <<-END_MATCHING_CSV.gsub(/^\s+/, "")
+ 1,2,3
+ 1,2,3
+ END_MATCHING_CSV
+
+ # normal converters do not affect headers
+ csv = CSV.parse( data, headers: true,
+ return_headers: true,
+ converters: :numeric )
+ assert_equal([%w{1 1}, %w{2 2}, %w{3 3}], csv[0].to_a)
+ assert_equal([["1", 1], ["2", 2], ["3", 3]], csv[1].to_a)
+ assert_nil(csv[2])
+
+ # header converters do affect headers (only)
+ assert_nothing_raised(Exception) do
+ csv = CSV.parse( data, headers: true,
+ return_headers: true,
+ converters: :numeric,
+ header_converters: :symbol )
+ end
+ assert_equal([[:"1", "1"], [:"2", "2"], [:"3", "3"]], csv[0].to_a)
+ assert_equal([[:"1", 1], [:"2", 2], [:"3", 3]], csv[1].to_a)
+ assert_nil(csv[2])
+ end
+
+ def test_builtin_downcase_converter
+ csv = CSV.parse( "One,TWO Three", headers: true,
+ return_headers: true,
+ header_converters: :downcase )
+ assert_equal(%w{one two\ three}, csv.headers)
+ end
+
+ def test_builtin_symbol_converter
+ csv = CSV.parse( "One,TWO Three", headers: true,
+ return_headers: true,
+ header_converters: :symbol )
+ assert_equal([:one, :two_three], csv.headers)
+ end
+
+ def test_custom_converter
+ converter = lambda { |header| header.tr(" ", "_") }
+ csv = CSV.parse( "One,TWO Three",
+ headers: true,
+ return_headers: true,
+ header_converters: converter )
+ assert_equal(%w{One TWO_Three}, csv.headers)
+ end
+
+ def test_table_support
+ csv = nil
+ assert_nothing_raised(Exception) do
+ csv = CSV.parse(@data, headers: true)
+ end
+
+ assert_instance_of(CSV::Table, csv)
+ end
+
+ def test_skip_blanks
+ @data = <<-END_CSV.gsub(/^ +/, "")
+
+
+ A,B,C
+
+ 1,2,3
+
+
+
+ END_CSV
+
+ expected = [%w[1 2 3]]
+ CSV.parse(@data, headers: true, skip_blanks: true) do |row|
+ assert_equal(expected.shift, row.fields)
+ end
+
+ expected = [%w[A B C], %w[1 2 3]]
+ CSV.parse( @data,
+ headers: true,
+ return_headers: true,
+ skip_blanks: true ) do |row|
+ assert_equal(expected.shift, row.fields)
+ end
+ end
+
+ def test_headers_reader
+ # no headers
+ assert_nil(CSV.new(@data).headers)
+
+ # headers
+ csv = CSV.new(@data, headers: true)
+ assert_equal(true, csv.headers) # before headers are read
+ csv.shift # set headers
+ assert_equal(%w[first second third], csv.headers) # after headers are read
+ end
+
+ def test_blank_row_bug_fix
+ @data += "\n#{@data}" # add a blank row
+
+ # ensure that everything returned is a Row object
+ CSV.parse(@data, headers: true) do |row|
+ assert_instance_of(CSV::Row, row)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/csv/test_interface.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/csv/test_interface.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/csv/test_interface.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,309 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+
+# tc_interface.rb
+#
+# Created by James Edward Gray II on 2005-10-31.
+# Copyright 2005 James Edward Gray II. You can redistribute or modify this code
+# under the terms of Ruby's license.
+
+require "test/unit"
+
+require "csv"
+
+class TestCSVInterface < Test::Unit::TestCase
+ def setup
+ @path = File.join(File.dirname(__FILE__), "temp_test_data.csv")
+
+ File.open(@path, "wb") do |file|
+ file << "1\t2\t3\r\n"
+ file << "4\t5\r\n"
+ end
+
+ @expected = [%w{1 2 3}, %w{4 5}]
+ end
+
+ def teardown
+ File.unlink(@path)
+ end
+
+ ### Test Read Interface ###
+
+ def test_foreach
+ CSV.foreach(@path, col_sep: "\t", row_sep: "\r\n") do |row|
+ assert_equal(@expected.shift, row)
+ end
+ end
+
+ def test_open_and_close
+ csv = CSV.open(@path, "r+", col_sep: "\t", row_sep: "\r\n")
+ assert_not_nil(csv)
+ assert_instance_of(CSV, csv)
+ assert_equal(false, csv.closed?)
+ csv.close
+ assert(csv.closed?)
+
+ ret = CSV.open(@path) do |new_csv|
+ csv = new_csv
+ assert_instance_of(CSV, new_csv)
+ "Return value."
+ end
+ assert(csv.closed?)
+ assert_equal("Return value.", ret)
+ end
+
+ def test_parse
+ data = File.binread(@path)
+ assert_equal( @expected,
+ CSV.parse(data, col_sep: "\t", row_sep: "\r\n") )
+
+ CSV.parse(data, col_sep: "\t", row_sep: "\r\n") do |row|
+ assert_equal(@expected.shift, row)
+ end
+ end
+
+ def test_parse_line
+ row = CSV.parse_line("1;2;3", col_sep: ";")
+ assert_not_nil(row)
+ assert_instance_of(Array, row)
+ assert_equal(%w{1 2 3}, row)
+
+ # shortcut interface
+ row = "1;2;3".parse_csv(col_sep: ";")
+ assert_not_nil(row)
+ assert_instance_of(Array, row)
+ assert_equal(%w{1 2 3}, row)
+ end
+
+ def test_parse_line_with_empty_lines
+ assert_equal(nil, CSV.parse_line("")) # to signal eof
+ assert_equal(Array.new, CSV.parse_line("\n1,2,3"))
+ end
+
+ def test_read_and_readlines
+ assert_equal( @expected,
+ CSV.read(@path, col_sep: "\t", row_sep: "\r\n") )
+ assert_equal( @expected,
+ CSV.readlines(@path, col_sep: "\t", row_sep: "\r\n") )
+
+
+ data = CSV.open(@path, col_sep: "\t", row_sep: "\r\n") do |csv|
+ csv.read
+ end
+ assert_equal(@expected, data)
+ data = CSV.open(@path, col_sep: "\t", row_sep: "\r\n") do |csv|
+ csv.readlines
+ end
+ assert_equal(@expected, data)
+ end
+
+ def test_table
+ table = CSV.table(@path, col_sep: "\t", row_sep: "\r\n")
+ assert_instance_of(CSV::Table, table)
+ assert_equal([[:"1", :"2", :"3"], [4, 5, nil]], table.to_a)
+ end
+
+ def test_shift # aliased as gets() and readline()
+ CSV.open(@path, "rb+", col_sep: "\t", row_sep: "\r\n") do |csv|
+ assert_equal(@expected.shift, csv.shift)
+ assert_equal(@expected.shift, csv.shift)
+ assert_equal(nil, csv.shift)
+ end
+ end
+
+ ### Test Write Interface ###
+
+ def test_generate
+ str = CSV.generate do |csv| # default empty String
+ assert_instance_of(CSV, csv)
+ assert_equal(csv, csv << [1, 2, 3])
+ assert_equal(csv, csv << [4, nil, 5])
+ end
+ assert_not_nil(str)
+ assert_instance_of(String, str)
+ assert_equal("1,2,3\n4,,5\n", str)
+
+ CSV.generate(str) do |csv| # appending to a String
+ assert_equal(csv, csv << ["last", %Q{"row"}])
+ end
+ assert_equal(%Q{1,2,3\n4,,5\nlast,"""row"""\n}, str)
+ end
+
+ def test_generate_line
+ line = CSV.generate_line(%w{1 2 3}, col_sep: ";")
+ assert_not_nil(line)
+ assert_instance_of(String, line)
+ assert_equal("1;2;3\n", line)
+
+ # shortcut interface
+ line = %w{1 2 3}.to_csv(col_sep: ";")
+ assert_not_nil(line)
+ assert_instance_of(String, line)
+ assert_equal("1;2;3\n", line)
+ end
+
+ def test_write_header_detection
+ File.unlink(@path)
+
+ headers = %w{a b c}
+ CSV.open(@path, "w", headers: true) do |csv|
+ csv << headers
+ csv << %w{1 2 3}
+ assert_equal(headers, csv.instance_variable_get(:@headers))
+ end
+ end
+
+ def test_write_lineno
+ File.unlink(@path)
+
+ CSV.open(@path, "w") do |csv|
+ lines = 20
+ lines.times { csv << %w{a b c} }
+ assert_equal(lines, csv.lineno)
+ end
+ end
+
+ def test_write_hash
+ File.unlink(@path)
+
+ lines = [{a: 1, b: 2, c: 3}, {a: 4, b: 5, c: 6}]
+ CSV.open( @path, "wb", headers: true,
+ header_converters: :symbol ) do |csv|
+ csv << lines.first.keys
+ lines.each { |line| csv << line }
+ end
+ CSV.open( @path, "rb", headers: true,
+ converters: :all,
+ header_converters: :symbol ) do |csv|
+ csv.each { |line| assert_equal(lines.shift, line.to_hash) }
+ end
+ end
+
+ def test_write_hash_with_headers_array
+ File.unlink(@path)
+
+ lines = [{a: 1, b: 2, c: 3}, {a: 4, b: 5, c: 6}]
+ CSV.open(@path, "wb", headers: [:b, :a, :c]) do |csv|
+ lines.each { |line| csv << line }
+ end
+
+ # test writing fields in the correct order
+ File.open(@path, "rb") do |f|
+ assert_equal("2,1,3", f.gets.strip)
+ assert_equal("5,4,6", f.gets.strip)
+ end
+
+ # test reading CSV with headers
+ CSV.open( @path, "rb", headers: [:b, :a, :c],
+ converters: :all ) do |csv|
+ csv.each { |line| assert_equal(lines.shift, line.to_hash) }
+ end
+ end
+
+ def test_write_hash_with_headers_string
+ File.unlink(@path)
+
+ lines = [{"a" => 1, "b" => 2, "c" => 3}, {"a" => 4, "b" => 5, "c" => 6}]
+ CSV.open(@path, "wb", headers: "b|a|c", col_sep: "|") do |csv|
+ lines.each { |line| csv << line }
+ end
+
+ # test writing fields in the correct order
+ File.open(@path, "rb") do |f|
+ assert_equal("2|1|3", f.gets.strip)
+ assert_equal("5|4|6", f.gets.strip)
+ end
+
+ # test reading CSV with headers
+ CSV.open( @path, "rb", headers: "b|a|c",
+ col_sep: "|",
+ converters: :all ) do |csv|
+ csv.each { |line| assert_equal(lines.shift, line.to_hash) }
+ end
+ end
+
+ def test_write_headers
+ File.unlink(@path)
+
+ lines = [{"a" => 1, "b" => 2, "c" => 3}, {"a" => 4, "b" => 5, "c" => 6}]
+ CSV.open( @path, "wb", headers: "b|a|c",
+ write_headers: true,
+ col_sep: "|" ) do |csv|
+ lines.each { |line| csv << line }
+ end
+
+ # test writing fields in the correct order
+ File.open(@path, "rb") do |f|
+ assert_equal("b|a|c", f.gets.strip)
+ assert_equal("2|1|3", f.gets.strip)
+ assert_equal("5|4|6", f.gets.strip)
+ end
+
+ # test reading CSV with headers
+ CSV.open( @path, "rb", headers: true,
+ col_sep: "|",
+ converters: :all ) do |csv|
+ csv.each { |line| assert_equal(lines.shift, line.to_hash) }
+ end
+ end
+
+ def test_append # aliased add_row() and puts()
+ File.unlink(@path)
+
+ CSV.open(@path, "wb", col_sep: "\t", row_sep: "\r\n") do |csv|
+ @expected.each { |row| csv << row }
+ end
+
+ test_shift
+
+ # same thing using CSV::Row objects
+ File.unlink(@path)
+
+ CSV.open(@path, "wb", col_sep: "\t", row_sep: "\r\n") do |csv|
+ @expected.each { |row| csv << CSV::Row.new(Array.new, row) }
+ end
+
+ test_shift
+ end
+
+ ### Test Read and Write Interface ###
+
+ def test_filter
+ assert_respond_to(CSV, :filter)
+
+ expected = [[1, 2, 3], [4, 5]]
+ CSV.filter( "1;2;3\n4;5\n", (result = String.new),
+ in_col_sep: ";", out_col_sep: ",",
+ converters: :all ) do |row|
+ assert_equal(row, expected.shift)
+ row.map! { |n| n * 2 }
+ row << "Added\r"
+ end
+ assert_equal("2,4,6,\"Added\r\"\n8,10,\"Added\r\"\n", result)
+ end
+
+ def test_instance
+ csv = String.new
+
+ first = nil
+ assert_nothing_raised(Exception) do
+ first = CSV.instance(csv, col_sep: ";")
+ first << %w{a b c}
+ end
+
+ assert_equal("a;b;c\n", csv)
+
+ second = nil
+ assert_nothing_raised(Exception) do
+ second = CSV.instance(csv, col_sep: ";")
+ second << [1, 2, 3]
+ end
+
+ assert_equal(first.object_id, second.object_id)
+ assert_equal("a;b;c\n1;2;3\n", csv)
+
+ # shortcuts
+ assert_equal(STDOUT, CSV.instance.instance_eval { @io })
+ assert_equal(STDOUT, CSV { |new_csv| new_csv.instance_eval { @io } })
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/csv/test_row.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/csv/test_row.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/csv/test_row.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,312 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+
+# tc_row.rb
+#
+# Created by James Edward Gray II on 2005-10-31.
+# Copyright 2005 James Edward Gray II. You can redistribute or modify this code
+# under the terms of Ruby's license.
+
+require "test/unit"
+
+require "csv"
+
+class TestCSVRow < Test::Unit::TestCase
+ def setup
+ @row = CSV::Row.new(%w{A B C A A}, [1, 2, 3, 4])
+ end
+
+ def test_initialize
+ # basic
+ row = CSV::Row.new(%w{A B C}, [1, 2, 3])
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([["A", 1], ["B", 2], ["C", 3]], row.to_a)
+
+ # missing headers
+ row = CSV::Row.new(%w{A}, [1, 2, 3])
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([["A", 1], [nil, 2], [nil, 3]], row.to_a)
+
+ # missing fields
+ row = CSV::Row.new(%w{A B C}, [1, 2])
+ assert_not_nil(row)
+ assert_instance_of(CSV::Row, row)
+ assert_equal([["A", 1], ["B", 2], ["C", nil]], row.to_a)
+ end
+
+ def test_row_type
+ # field rows
+ row = CSV::Row.new(%w{A B C}, [1, 2, 3]) # implicit
+ assert(!row.header_row?)
+ assert(row.field_row?)
+ row = CSV::Row.new(%w{A B C}, [1, 2, 3], false) # explicit
+ assert(!row.header_row?)
+ assert(row.field_row?)
+
+ # header row
+ row = CSV::Row.new(%w{A B C}, [1, 2, 3], true)
+ assert(row.header_row?)
+ assert(!row.field_row?)
+ end
+
+ def test_headers
+ assert_equal(%w{A B C A A}, @row.headers)
+ end
+
+ def test_field
+ # by name
+ assert_equal(2, @row.field("B"))
+ assert_equal(2, @row["B"]) # alias
+
+ # by index
+ assert_equal(3, @row.field(2))
+
+ # missing
+ assert_nil(@row.field("Missing"))
+ assert_nil(@row.field(10))
+
+ # minimum index
+ assert_equal(1, @row.field("A"))
+ assert_equal(1, @row.field("A", 0))
+ assert_equal(4, @row.field("A", 1))
+ assert_equal(4, @row.field("A", 2))
+ assert_equal(4, @row.field("A", 3))
+ assert_equal(nil, @row.field("A", 4))
+ assert_equal(nil, @row.field("A", 5))
+ end
+
+ def test_set_field
+ # set field by name
+ assert_equal(100, @row["A"] = 100)
+
+ # set field by index
+ assert_equal(300, @row[3] = 300)
+
+ # set field by name and minimum index
+ assert_equal([:a, :b, :c], @row["A", 4] = [:a, :b, :c])
+
+ # verify the changes
+ assert_equal( [ ["A", 100],
+ ["B", 2],
+ ["C", 3],
+ ["A", 300],
+ ["A", [:a, :b, :c]] ], @row.to_a )
+
+ # assigning an index past the end
+ assert_equal("End", @row[10] = "End")
+ assert_equal( [ ["A", 100],
+ ["B", 2],
+ ["C", 3],
+ ["A", 300],
+ ["A", [:a, :b, :c]],
+ [nil, nil],
+ [nil, nil],
+ [nil, nil],
+ [nil, nil],
+ [nil, nil],
+ [nil, "End"] ], @row.to_a )
+
+ # assigning a new field by header
+ assert_equal("New", @row[:new] = "New")
+ assert_equal( [ ["A", 100],
+ ["B", 2],
+ ["C", 3],
+ ["A", 300],
+ ["A", [:a, :b, :c]],
+ [nil, nil],
+ [nil, nil],
+ [nil, nil],
+ [nil, nil],
+ [nil, nil],
+ [nil, "End"],
+ [:new, "New"] ], @row.to_a )
+ end
+
+ def test_append
+ # add a value
+ assert_equal(@row, @row << "Value")
+ assert_equal( [ ["A", 1],
+ ["B", 2],
+ ["C", 3],
+ ["A", 4],
+ ["A", nil],
+ [nil, "Value"] ], @row.to_a )
+
+ # add a pair
+ assert_equal(@row, @row << %w{Header Field})
+ assert_equal( [ ["A", 1],
+ ["B", 2],
+ ["C", 3],
+ ["A", 4],
+ ["A", nil],
+ [nil, "Value"],
+ %w{Header Field} ], @row.to_a )
+
+ # a pair with Hash syntax
+ assert_equal(@row, @row << {key: :value})
+ assert_equal( [ ["A", 1],
+ ["B", 2],
+ ["C", 3],
+ ["A", 4],
+ ["A", nil],
+ [nil, "Value"],
+ %w{Header Field},
+ [:key, :value] ], @row.to_a )
+
+ # multiple fields at once
+ assert_equal(@row, @row.push(100, 200, [:last, 300]))
+ assert_equal( [ ["A", 1],
+ ["B", 2],
+ ["C", 3],
+ ["A", 4],
+ ["A", nil],
+ [nil, "Value"],
+ %w{Header Field},
+ [:key, :value],
+ [nil, 100],
+ [nil, 200],
+ [:last, 300] ], @row.to_a )
+ end
+
+ def test_delete
+ # by index
+ assert_equal(["B", 2], @row.delete(1))
+
+ # by header
+ assert_equal(["C", 3], @row.delete("C"))
+
+ # using a block
+ assert_equal(@row, @row.delete_if { |h, f| h == "A" and not f.nil? })
+ assert_equal([["A", nil]], @row.to_a)
+ end
+
+ def test_fields
+ # all fields
+ assert_equal([1, 2, 3, 4, nil], @row.fields)
+
+ # by header
+ assert_equal([1, 3], @row.fields("A", "C"))
+
+ # by index
+ assert_equal([2, 3, nil], @row.fields(1, 2, 10))
+
+ # by both
+ assert_equal([2, 3, 4], @row.fields("B", "C", 3))
+
+ # with minimum indices
+ assert_equal([2, 3, 4], @row.fields("B", "C", ["A", 3]))
+
+ # by header range
+ assert_equal([2, 3], @row.values_at("B".."C"))
+ end
+
+ def test_index
+ # basic usage
+ assert_equal(0, @row.index("A"))
+ assert_equal(1, @row.index("B"))
+ assert_equal(2, @row.index("C"))
+ assert_equal(nil, @row.index("Z"))
+
+ # with minimum index
+ assert_equal(0, @row.index("A"))
+ assert_equal(0, @row.index("A", 0))
+ assert_equal(3, @row.index("A", 1))
+ assert_equal(3, @row.index("A", 2))
+ assert_equal(3, @row.index("A", 3))
+ assert_equal(4, @row.index("A", 4))
+ assert_equal(nil, @row.index("A", 5))
+ end
+
+ def test_queries
+ # headers
+ assert(@row.header?("A"))
+ assert(@row.header?("C"))
+ assert(!@row.header?("Z"))
+ assert(@row.include?("A")) # alias
+
+ # fields
+ assert(@row.field?(4))
+ assert(@row.field?(nil))
+ assert(!@row.field?(10))
+ end
+
+ def test_each
+ # array style
+ ary = @row.to_a
+ @row.each do |pair|
+ assert_equal(ary.first.first, pair.first)
+ assert_equal(ary.shift.last, pair.last)
+ end
+
+ # hash style
+ ary = @row.to_a
+ @row.each do |header, field|
+ assert_equal(ary.first.first, header)
+ assert_equal(ary.shift.last, field)
+ end
+
+ # verify that we can chain the call
+ assert_equal(@row, @row.each { })
+ end
+
+ def test_enumerable
+ assert_equal( [["A", 1], ["A", 4], ["A", nil]],
+ @row.select { |pair| pair.first == "A" } )
+
+ assert_equal(10, @row.inject(0) { |sum, (header, n)| sum + (n || 0) })
+ end
+
+ def test_to_a
+ row = CSV::Row.new(%w{A B C}, [1, 2, 3]).to_a
+ assert_instance_of(Array, row)
+ row.each do |pair|
+ assert_instance_of(Array, pair)
+ assert_equal(2, pair.size)
+ end
+ assert_equal([["A", 1], ["B", 2], ["C", 3]], row)
+ end
+
+ def test_to_hash
+ assert_equal({"A" => nil, "B" => 2, "C" => 3}, @row.to_hash)
+ end
+
+ def test_to_csv
+ # normal conversion
+ assert_equal("1,2,3,4,\n", @row.to_csv)
+ assert_equal("1,2,3,4,\n", @row.to_s) # alias
+
+ # with options
+ assert_equal( "1|2|3|4|\r\n",
+ @row.to_csv(col_sep: "|", row_sep: "\r\n") )
+ end
+
+ def test_array_delegation
+ assert(!@row.empty?, "Row was empty.")
+
+ assert_equal([@row.headers.size, @row.fields.size].max, @row.size)
+ end
+
+ def test_inspect_shows_header_field_pairs
+ str = @row.inspect
+ @row.each do |header, field|
+ assert( str.include?("#{header.inspect}:#{field.inspect}"),
+ "Header field pair not found." )
+ end
+ end
+
+ def test_inspect_encoding_is_ascii_compatible
+ assert( Encoding.compatible?( Encoding.find("US-ASCII"),
+ @row.inspect.encoding ),
+ "inspect() was not ASCII compatible." )
+ end
+
+ def test_inspect_shows_symbol_headers_as_bare_attributes
+ str = CSV::Row.new(@row.headers.map { |h| h.to_sym }, @row.fields).inspect
+ @row.each do |header, field|
+ assert( str.include?("#{header}:#{field.inspect}"),
+ "Header field pair not found." )
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/csv/test_serialization.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/csv/test_serialization.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/csv/test_serialization.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,156 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+
+# tc_serialization.rb
+#
+# Created by James Edward Gray II on 2005-10-31.
+# Copyright 2005 James Edward Gray II. You can redistribute or modify this code
+# under the terms of Ruby's license.
+
+require "test/unit"
+
+require "csv"
+
+# An example of how to provide custom CSV serialization.
+class Hash
+ def self.csv_load( meta, headers, fields )
+ self[*headers.zip(fields).to_a.flatten.map { |e| eval(e) }]
+ end
+
+ def csv_headers
+ keys.map { |key| key.inspect }
+ end
+
+ def csv_dump( headers )
+ headers.map { |header| fetch(eval(header)).inspect }
+ end
+end
+
+class TestSerialization < Test::Unit::TestCase
+
+ ### Classes Used to Test Serialization ###
+
+ class ReadOnlyName
+ def initialize( first, last )
+ @first, @last = first, last
+ end
+
+ attr_reader :first, :last
+
+ def ==( other )
+ %w{first last}.all? { |att| send(att) == other.send(att) }
+ end
+ end
+
+ Name = Struct.new(:first, :last)
+
+ class FullName < Name
+ def initialize( first, last, suffix = nil )
+ super(first, last)
+
+ @suffix = suffix
+ end
+
+ attr_accessor :suffix
+
+ def ==( other )
+ %w{first last suffix}.all? { |att| send(att) == other.send(att) }
+ end
+ end
+
+ ### Tests ###
+
+ def test_class_dump
+ @names = [ %w{James Gray},
+ %w{Dana Gray},
+ %w{Greg Brown} ].map do |first, last|
+ ReadOnlyName.new(first, last)
+ end
+
+ assert_nothing_raised(Exception) do
+ @data = CSV.dump(@names)
+ end
+ assert_equal(<<-END_CLASS_DUMP.gsub(/^\s*/, ""), @data)
+ class,TestSerialization::ReadOnlyName
+ @first, at last
+ James,Gray
+ Dana,Gray
+ Greg,Brown
+ END_CLASS_DUMP
+ end
+
+ def test_struct_dump
+ @names = [ %w{James Gray},
+ %w{Dana Gray},
+ %w{Greg Brown} ].map do |first, last|
+ Name.new(first, last)
+ end
+
+ assert_nothing_raised(Exception) do
+ @data = CSV.dump(@names)
+ end
+ assert_equal(<<-END_STRUCT_DUMP.gsub(/^\s*/, ""), @data)
+ class,TestSerialization::Name
+ first=,last=
+ James,Gray
+ Dana,Gray
+ Greg,Brown
+ END_STRUCT_DUMP
+ end
+
+ def test_inherited_struct_dump
+ @names = [ %w{James Gray II},
+ %w{Dana Gray},
+ %w{Greg Brown} ].map do |first, last, suffix|
+ FullName.new(first, last, suffix)
+ end
+
+ assert_nothing_raised(Exception) do
+ @data = CSV.dump(@names)
+ end
+ assert_equal(<<-END_STRUCT_DUMP.gsub(/^\s*/, ""), @data)
+ class,TestSerialization::FullName
+ @suffix,first=,last=
+ II,James,Gray
+ ,Dana,Gray
+ ,Greg,Brown
+ END_STRUCT_DUMP
+ end
+
+ def test_load
+ %w{ test_class_dump
+ test_struct_dump
+ test_inherited_struct_dump }.each do |test|
+ send(test)
+ CSV.load(@data).each do |loaded|
+ assert_instance_of(@names.first.class, loaded)
+ assert_equal(@names.shift, loaded)
+ end
+ end
+ end
+
+ def test_io
+ test_class_dump
+
+ data_file = File.join(File.dirname(__FILE__), "temp_test_data.csv")
+ CSV.dump(@names, File.open(data_file, "wb"))
+
+ assert(File.exist?(data_file))
+ assert_equal(<<-END_IO_DUMP.gsub(/^\s*/, ""), File.read(data_file))
+ class,TestSerialization::ReadOnlyName
+ @first, at last
+ James,Gray
+ Dana,Gray
+ Greg,Brown
+ END_IO_DUMP
+
+ assert_equal(@names, CSV.load(File.open(data_file)))
+
+ File.unlink(data_file)
+ end
+
+ def test_custom_dump_and_load
+ obj = {1 => "simple", test: Hash}
+ assert_equal(obj, CSV.load(CSV.dump([obj])).first)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/csv/test_table.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/csv/test_table.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/csv/test_table.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,416 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+
+# tc_table.rb
+#
+# Created by James Edward Gray II on 2005-10-31.
+# Copyright 2005 James Edward Gray II. You can redistribute or modify this code
+# under the terms of Ruby's license.
+
+require "test/unit"
+
+require "csv"
+
+class TestCSVTable < Test::Unit::TestCase
+ def setup
+ @rows = [ CSV::Row.new(%w{A B C}, [1, 2, 3]),
+ CSV::Row.new(%w{A B C}, [4, 5, 6]),
+ CSV::Row.new(%w{A B C}, [7, 8, 9]) ]
+ @table = CSV::Table.new(@rows)
+
+ @header_table = CSV::Table.new(
+ [CSV::Row.new(%w{A B C}, %w{A B C}, true)] + @rows
+ )
+ end
+
+ def test_initialze
+ assert_not_nil(@table)
+ assert_instance_of(CSV::Table, @table)
+ end
+
+ def test_modes
+ assert_equal(:col_or_row, @table.mode)
+
+ # non-destructive changes, intended for one shot calls
+ cols = @table.by_col
+ assert_equal(:col_or_row, @table.mode)
+ assert_equal(:col, cols.mode)
+ assert_equal(@table, cols)
+
+ rows = @table.by_row
+ assert_equal(:col_or_row, @table.mode)
+ assert_equal(:row, rows.mode)
+ assert_equal(@table, rows)
+
+ # destructive mode changing calls
+ assert_equal(@table, @table.by_row!)
+ assert_equal(:row, @table.mode)
+ assert_equal(@table, @table.by_col_or_row!)
+ assert_equal(:col_or_row, @table.mode)
+ end
+
+ def test_headers
+ assert_equal(@rows.first.headers, @table.headers)
+ end
+
+ def test_index
+ ##################
+ ### Mixed Mode ###
+ ##################
+ # by row
+ @rows.each_index { |i| assert_equal(@rows[i], @table[i]) }
+ assert_equal(nil, @table[100]) # empty row
+
+ # by col
+ @rows.first.headers.each do |header|
+ assert_equal(@rows.map { |row| row[header] }, @table[header])
+ end
+ assert_equal([nil] * @rows.size, @table["Z"]) # empty col
+
+ # by cell, row then col
+ assert_equal(2, @table[0][1])
+ assert_equal(6, @table[1]["C"])
+
+ # by cell, col then row
+ assert_equal(5, @table["B"][1])
+ assert_equal(9, @table["C"][2])
+
+ # with headers (by col)
+ assert_equal(["B", 2, 5, 8], @header_table["B"])
+
+ ###################
+ ### Column Mode ###
+ ###################
+ @table.by_col!
+
+ assert_equal([2, 5, 8], @table[1])
+ assert_equal([2, 5, 8], @table["B"])
+
+ ################
+ ### Row Mode ###
+ ################
+ @table.by_row!
+
+ assert_equal(@rows[1], @table[1])
+ assert_raise(TypeError) { @table["B"] }
+
+ ############################
+ ### One Shot Mode Change ###
+ ############################
+ assert_equal(@rows[1], @table[1])
+ assert_equal([2, 5, 8], @table.by_col[1])
+ assert_equal(@rows[1], @table[1])
+ end
+
+ def test_set_row_or_column
+ ##################
+ ### Mixed Mode ###
+ ##################
+ # set row
+ @table[2] = [10, 11, 12]
+ assert_equal([%w[A B C], [1, 2, 3], [4, 5, 6], [10, 11, 12]], @table.to_a)
+
+ @table[3] = CSV::Row.new(%w[A B C], [13, 14, 15])
+ assert_equal( [%w[A B C], [1, 2, 3], [4, 5, 6], [10, 11, 12], [13, 14, 15]],
+ @table.to_a )
+
+ # set col
+ @table["Type"] = "data"
+ assert_equal( [ %w[A B C Type],
+ [1, 2, 3, "data"],
+ [4, 5, 6, "data"],
+ [10, 11, 12, "data"],
+ [13, 14, 15, "data"] ],
+ @table.to_a )
+
+ @table["Index"] = [1, 2, 3]
+ assert_equal( [ %w[A B C Type Index],
+ [1, 2, 3, "data", 1],
+ [4, 5, 6, "data", 2],
+ [10, 11, 12, "data", 3],
+ [13, 14, 15, "data", nil] ],
+ @table.to_a )
+
+ @table["B"] = [100, 200]
+ assert_equal( [ %w[A B C Type Index],
+ [1, 100, 3, "data", 1],
+ [4, 200, 6, "data", 2],
+ [10, nil, 12, "data", 3],
+ [13, nil, 15, "data", nil] ],
+ @table.to_a )
+
+ # verify resulting table
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
+ A,B,C,Type,Index
+ 1,100,3,data,1
+ 4,200,6,data,2
+ 10,,12,data,3
+ 13,,15,data,
+ END_RESULT
+
+ # with headers
+ @header_table["Type"] = "data"
+ assert_equal(%w[Type data data data], @header_table["Type"])
+
+ ###################
+ ### Column Mode ###
+ ###################
+ @table.by_col!
+
+ @table[1] = [2, 5, 11, 14]
+ assert_equal( [ %w[A B C Type Index],
+ [1, 2, 3, "data", 1],
+ [4, 5, 6, "data", 2],
+ [10, 11, 12, "data", 3],
+ [13, 14, 15, "data", nil] ],
+ @table.to_a )
+
+ @table["Extra"] = "new stuff"
+ assert_equal( [ %w[A B C Type Index Extra],
+ [1, 2, 3, "data", 1, "new stuff"],
+ [4, 5, 6, "data", 2, "new stuff"],
+ [10, 11, 12, "data", 3, "new stuff"],
+ [13, 14, 15, "data", nil, "new stuff"] ],
+ @table.to_a )
+
+ ################
+ ### Row Mode ###
+ ################
+ @table.by_row!
+
+ @table[1] = (1..6).to_a
+ assert_equal( [ %w[A B C Type Index Extra],
+ [1, 2, 3, "data", 1, "new stuff"],
+ [1, 2, 3, 4, 5, 6],
+ [10, 11, 12, "data", 3, "new stuff"],
+ [13, 14, 15, "data", nil, "new stuff"] ],
+ @table.to_a )
+
+ assert_raise(TypeError) { @table["Extra"] = nil }
+ end
+
+ def test_each
+ ######################
+ ### Mixed/Row Mode ###
+ ######################
+ i = 0
+ @table.each do |row|
+ assert_equal(@rows[i], row)
+ i += 1
+ end
+
+ # verify that we can chain the call
+ assert_equal(@table, @table.each { })
+
+ ###################
+ ### Column Mode ###
+ ###################
+ @table.by_col!
+
+ headers = @table.headers
+ @table.each do |header, column|
+ assert_equal(headers.shift, header)
+ assert_equal(@table[header], column)
+ end
+
+ ############################
+ ### One Shot Mode Change ###
+ ############################
+ @table.by_col_or_row!
+
+ @table.each { |row| assert_instance_of(CSV::Row, row) }
+ @table.by_col.each { |tuple| assert_instance_of(Array, tuple) }
+ @table.each { |row| assert_instance_of(CSV::Row, row) }
+ end
+
+ def test_enumerable
+ assert_equal( @rows.values_at(0, 2),
+ @table.select { |row| (row["B"] % 2).zero? } )
+
+ assert_equal(@rows[1], @table.find { |row| row["C"] > 5 })
+ end
+
+ def test_to_a
+ assert_equal([%w[A B C], [1, 2, 3], [4, 5, 6], [7, 8, 9]], @table.to_a)
+
+ # with headers
+ assert_equal( [%w[A B C], [1, 2, 3], [4, 5, 6], [7, 8, 9]],
+ @header_table.to_a )
+ end
+
+ def test_to_csv
+ csv = <<-END_CSV.gsub(/^\s+/, "")
+ A,B,C
+ 1,2,3
+ 4,5,6
+ 7,8,9
+ END_CSV
+
+ # normal conversion
+ assert_equal(csv, @table.to_csv)
+ assert_equal(csv, @table.to_s) # alias
+
+ # with options
+ assert_equal( csv.gsub(",", "|").gsub("\n", "\r\n"),
+ @table.to_csv(col_sep: "|", row_sep: "\r\n") )
+ assert_equal( csv.lines.to_a[1..-1].join,
+ @table.to_csv(:write_headers => false) )
+
+ # with headers
+ assert_equal(csv, @header_table.to_csv)
+ end
+
+ def test_append
+ # verify that we can chain the call
+ assert_equal(@table, @table << [10, 11, 12])
+
+ # Array append
+ assert_equal(CSV::Row.new(%w[A B C], [10, 11, 12]), @table[-1])
+
+ # Row append
+ assert_equal(@table, @table << CSV::Row.new(%w[A B C], [13, 14, 15]))
+ assert_equal(CSV::Row.new(%w[A B C], [13, 14, 15]), @table[-1])
+ end
+
+ def test_delete
+ ##################
+ ### Mixed Mode ###
+ ##################
+ # delete a row
+ assert_equal(@rows[1], @table.delete(1))
+
+ # delete a col
+ assert_equal(@rows.map { |row| row["A"] }, @table.delete("A"))
+
+ # verify resulting table
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
+ B,C
+ 2,3
+ 8,9
+ END_RESULT
+
+ ###################
+ ### Column Mode ###
+ ###################
+ setup
+ @table.by_col!
+
+ assert_equal(@rows.map { |row| row[0] }, @table.delete(0))
+ assert_equal(@rows.map { |row| row["C"] }, @table.delete("C"))
+
+ # verify resulting table
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
+ B
+ 2
+ 5
+ 8
+ END_RESULT
+
+ ################
+ ### Row Mode ###
+ ################
+ setup
+ @table.by_row!
+
+ assert_equal(@rows[1], @table.delete(1))
+ assert_raise(TypeError) { @table.delete("C") }
+
+ # verify resulting table
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
+ A,B,C
+ 1,2,3
+ 7,8,9
+ END_RESULT
+ end
+
+ def test_delete_with_blank_rows
+ data = "col1,col2\nra1,ra2\n\nrb1,rb2"
+ table = CSV.parse(data, :headers => true)
+ assert_equal(["ra2", nil, "rb2"], table.delete("col2"))
+ end
+
+ def test_delete_if
+ ######################
+ ### Mixed/Row Mode ###
+ ######################
+ # verify that we can chain the call
+ assert_equal(@table, @table.delete_if { |row| (row["B"] % 2).zero? })
+
+ # verify resulting table
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
+ A,B,C
+ 4,5,6
+ END_RESULT
+
+ ###################
+ ### Column Mode ###
+ ###################
+ setup
+ @table.by_col!
+
+ assert_equal(@table, @table.delete_if { |h, v| h > "A" })
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
+ A
+ 1
+ 4
+ 7
+ END_RESULT
+ end
+
+ def test_values_at
+ ##################
+ ### Mixed Mode ###
+ ##################
+ # rows
+ assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
+ assert_equal(@rows.values_at(1..2), @table.values_at(1..2))
+
+ # cols
+ assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at("A", "C"))
+ assert_equal([[2, 3], [5, 6], [8, 9]], @table.values_at("B".."C"))
+
+ ###################
+ ### Column Mode ###
+ ###################
+ @table.by_col!
+
+ assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at(0, 2))
+ assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at("A", "C"))
+
+ ################
+ ### Row Mode ###
+ ################
+ @table.by_row!
+
+ assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
+ assert_raise(TypeError) { @table.values_at("A", "C") }
+
+ ############################
+ ### One Shot Mode Change ###
+ ############################
+ assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
+ assert_equal([[1, 3], [4, 6], [7, 9]], @table.by_col.values_at(0, 2))
+ assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
+ end
+
+ def test_array_delegation
+ assert(!@table.empty?, "Table was empty.")
+
+ assert_equal(@rows.size, @table.size)
+ end
+
+ def test_inspect_shows_current_mode
+ str = @table.inspect
+ assert(str.include?("mode:#{@table.mode}"), "Mode not shown.")
+
+ @table.by_col!
+ str = @table.inspect
+ assert(str.include?("mode:#{@table.mode}"), "Mode not shown.")
+ end
+
+ def test_inspect_encoding_is_ascii_compatible
+ assert( Encoding.compatible?( Encoding.find("US-ASCII"),
+ @table.inspect.encoding ),
+ "inspect() was not ASCII compatible." )
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/csv/ts_all.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/csv/ts_all.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/csv/ts_all.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,21 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+
+# ts_all.rb
+#
+# Created by James Edward Gray II on 2005-10-31.
+# Copyright 2005 James Edward Gray II. You can redistribute or modify this code
+# under the terms of Ruby's license.
+
+require "test/unit"
+
+require "test_csv_parsing"
+require "test_features"
+require "test_interface"
+require "test_csv_writing"
+require "test_data_converters"
+require "test_row"
+require "test_table"
+require "test_headers"
+require "test_serialization"
+require "test_encodings"
Added: MacRuby/trunk/test/test-mri/test/date/test_date.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/date/test_date.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/date/test_date.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,144 @@
+require 'test/unit'
+require 'date'
+
+class DateSub < Date; end
+class DateTimeSub < DateTime; end
+
+class TestDate < Test::Unit::TestCase
+
+ def test__const
+ assert_nil(Date::MONTHNAMES[0])
+ assert_equal('January', Date::MONTHNAMES[1])
+ assert_equal(13, Date::MONTHNAMES.size)
+ assert_equal('Sunday', Date::DAYNAMES[0])
+ assert_equal(7, Date::DAYNAMES.size)
+
+ assert_nil(Date::ABBR_MONTHNAMES[0])
+ assert_equal('Jan', Date::ABBR_MONTHNAMES[1])
+ assert_equal(13, Date::ABBR_MONTHNAMES.size)
+ assert_equal('Sun', Date::ABBR_DAYNAMES[0])
+ assert_equal(7, Date::ABBR_DAYNAMES.size)
+
+ assert(Date::MONTHNAMES.frozen?)
+ assert(!Date::MONTHNAMES[0].frozen?)
+ assert(Date::MONTHNAMES[1].frozen?)
+ assert(Date::DAYNAMES.frozen?)
+ assert(Date::DAYNAMES[0].frozen?)
+
+ assert(Date::ABBR_MONTHNAMES.frozen?)
+ assert(Date::ABBR_MONTHNAMES[1].frozen?)
+ assert(Date::ABBR_DAYNAMES.frozen?)
+ assert(Date::ABBR_DAYNAMES[0].frozen?)
+ end
+
+ def test_sub
+ d = DateSub.new
+ dt = DateTimeSub.new
+
+ assert_instance_of(DateSub, d)
+ assert_instance_of(DateTimeSub, dt)
+
+ assert_instance_of(DateSub, DateSub.today)
+ assert_instance_of(DateTimeSub, DateTimeSub.now)
+
+ assert_equal('#<DateSub: -4712-01-01 (-1/2,0,2299161)>', d.inspect)
+ assert_equal('-4712-01-01', d.to_s)
+ assert_equal('#<DateTimeSub: -4712-01-01T00:00:00+00:00 (-1/2,0,2299161)>', dt.inspect)
+ assert_equal('-4712-01-01T00:00:00+00:00', dt.to_s)
+
+ d2 = d + 1
+ assert_instance_of(DateSub, d2)
+ d2 = d - 1
+ assert_instance_of(DateSub, d2)
+ d2 = d >> 1
+ assert_instance_of(DateSub, d2)
+ d2 = d << 1
+ assert_instance_of(DateSub, d2)
+ d2 = d.succ
+ assert_instance_of(DateSub, d2)
+ d2 = d.next
+ assert_instance_of(DateSub, d2)
+ d2 = d.italy
+ assert_instance_of(DateSub, d2)
+ d2 = d.england
+ assert_instance_of(DateSub, d2)
+ d2 = d.julian
+ assert_instance_of(DateSub, d2)
+ d2 = d.gregorian
+ assert_instance_of(DateSub, d2)
+ s = Marshal.dump(d)
+ d2 = Marshal.load(s)
+ assert_equal(d2, d)
+ assert_instance_of(DateSub, d2)
+
+ dt2 = dt + 1
+ assert_instance_of(DateTimeSub, dt2)
+ dt2 = dt - 1
+ assert_instance_of(DateTimeSub, dt2)
+ dt2 = dt >> 1
+ assert_instance_of(DateTimeSub, dt2)
+ dt2 = dt << 1
+ assert_instance_of(DateTimeSub, dt2)
+ dt2 = dt.succ
+ assert_instance_of(DateTimeSub, dt2)
+ dt2 = dt.next
+ assert_instance_of(DateTimeSub, dt2)
+ dt2 = dt.italy
+ assert_instance_of(DateTimeSub, dt2)
+ dt2 = dt.england
+ assert_instance_of(DateTimeSub, dt2)
+ dt2 = dt.julian
+ assert_instance_of(DateTimeSub, dt2)
+ dt2 = dt.gregorian
+ assert_instance_of(DateTimeSub, dt2)
+ s = Marshal.dump(dt)
+ dt2 = Marshal.load(s)
+ assert_equal(dt2, dt)
+ assert_instance_of(DateTimeSub, dt2)
+ end
+
+ def test_eql_p
+ d = Date.jd(0)
+ d2 = Date.jd(0)
+ dt = DateTime.jd(0)
+ dt2 = DateTime.jd(0)
+
+ assert_equal(d, d2)
+ assert_not_equal(d, 0)
+
+ assert_equal(dt, dt2)
+ assert_not_equal(dt, 0)
+
+ assert_equal(d, dt)
+ assert_equal(d2, dt2)
+ end
+
+ def test_hash
+ h = {}
+ h[Date.new(1999,5,23)] = 0
+ h[Date.new(1999,5,24)] = 1
+ h[Date.new(1999,5,25)] = 2
+ h[Date.new(1999,5,25)] = 9
+ assert_equal(3, h.size)
+ assert_equal(9, h[Date.new(1999,5,25)])
+ assert_equal(9, h[DateTime.new(1999,5,25)])
+
+ h = {}
+ h[DateTime.new(1999,5,23)] = 0
+ h[DateTime.new(1999,5,24)] = 1
+ h[DateTime.new(1999,5,25)] = 2
+ h[DateTime.new(1999,5,25)] = 9
+ assert_equal(3, h.size)
+ assert_equal(9, h[Date.new(1999,5,25)])
+ assert_equal(9, h[DateTime.new(1999,5,25)])
+ end
+
+ def test_freeze
+ d = Date.new
+ d.freeze
+ assert_equal(true, d.frozen?)
+ assert_instance_of(Fixnum, d.yday)
+ assert_instance_of(String, d.to_s)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/date/test_date_arith.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/date/test_date_arith.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/date/test_date_arith.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,286 @@
+require 'test/unit'
+require 'date'
+
+class TestDateArith < Test::Unit::TestCase
+
+ def new_offset
+ d = DateTime.new(2002, 3, 14)
+ assert_equal(Rational(9, 24), d.new_offset(Rational(9, 24)).offset)
+ assert_equal(Rational(9, 24), d.new_offset('+0900').offset)
+ end
+
+ def test__plus
+ d = Date.new(2000,2,29) + -1
+ assert_equal([2000, 2, 28], [d.year, d.mon, d.mday])
+ d = Date.new(2000,2,29) + 0
+ assert_equal([2000, 2, 29], [d.year, d.mon, d.mday])
+ d = Date.new(2000,2,29) + 1
+ assert_equal([2000, 3, 1], [d.year, d.mon, d.mday])
+
+ d = DateTime.new(2000,2,29) + 1.to_r/2
+ assert_equal([2000, 2, 29, 12, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ end
+
+ def test__plus__ex
+ e = TypeError
+ assert_raise(e) do
+ Date.new(2000,2,29) + 'foo'
+ end
+ assert_raise(e) do
+ DateTime.new(2000,2,29) + 'foo'
+ end
+ assert_raise(e) do
+ Date.new(2000,2,29) + Time.mktime(2000,2,29)
+ end
+ assert_raise(e) do
+ DateTime.new(2000,2,29) + Time.mktime(2000,2,29)
+ end
+ end
+
+ def test__minus
+ d = Date.new(2000,3,1) - -1
+ assert_equal([2000, 3, 2], [d.year, d.mon, d.mday])
+ d = Date.new(2000,3,1) - 0
+ assert_equal([2000, 3, 1], [d.year, d.mon, d.mday])
+ d = Date.new(2000,3,1) - 1
+ assert_equal([2000, 2, 29], [d.year, d.mon, d.mday])
+
+ d = Date.new(2000,3,1) - Date.new(2000,2,29)
+ assert_equal(1, d)
+ d = Date.new(2000,2,29) - Date.new(2000,3,1)
+ assert_equal(-1, d)
+
+ d = DateTime.new(2000,3,1) - 1.to_r/2
+ assert_equal([2000, 2, 29, 12, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ end
+
+ def test__minus__ex
+ e = TypeError
+ assert_raise(e) do
+ Date.new(2000,2,29) - 'foo'
+ end
+ assert_raise(e) do
+ DateTime.new(2000,2,29) - 'foo'
+ end
+ assert_raise(e) do
+ Date.new(2000,2,29) - Time.mktime(2000,2,29)
+ end
+ assert_raise(e) do
+ DateTime.new(2000,2,29) - Time.mktime(2000,2,29)
+ end
+ end
+
+ def test__compare
+ assert_equal(0, (Date.new(2000,1,1) <=> Date.new(2000,1,1)))
+ assert_equal(-1, (Date.new(2000,1,1) <=> Date.new(2000,1,2)))
+ assert_equal(1, (Date.new(2000,1,2) <=> Date.new(2000,1,1)))
+ assert_equal(0, (Date.new(2001,1,4,Date::JULIAN) <=>
+ Date.new(2001,1,17, Date::GREGORIAN)))
+ assert_equal(0, (DateTime.new(2001,1,4,0,0,0,0,Date::JULIAN) <=>
+ DateTime.new(2001,1,17,0,0,0,0,Date::GREGORIAN)))
+ end
+
+ def test_prev
+ d = Date.new(2000,1,1)
+ assert_raise(NoMethodError) do
+ d.prev
+ end
+ end
+
+ def test_prev_day
+ d = Date.new(2001,1,1).prev_day
+ assert_equal([2000, 12, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2001,1,1).prev_day(2)
+ assert_equal([2000, 12, 30], [d.year, d.mon, d.mday])
+ d = Date.new(2000,12,31).prev_day(-2)
+ assert_equal([2001, 1, 2], [d.year, d.mon, d.mday])
+
+ d = DateTime.new(2000,3,1).prev_day(1.to_r/2)
+ assert_equal([2000, 2, 29, 12, 0, 0], [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ end
+
+ def test_prev_month
+ d = Date.new(2000,1,31) << -1
+ assert_equal([2000, 2, 29], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31) << 1
+ assert_equal([1999, 12, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31) << 12
+ assert_equal([1999, 1, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31) << 14
+ assert_equal([1998, 11, 30], [d.year, d.mon, d.mday])
+
+ end
+
+ def test_prev_month__2
+ d = Date.new(2000,1,31).prev_month(-1)
+ assert_equal([2000, 2, 29], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31).prev_month
+ assert_equal([1999, 12, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31).prev_month(12)
+ assert_equal([1999, 1, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31).prev_month(14)
+ assert_equal([1998, 11, 30], [d.year, d.mon, d.mday])
+ end
+
+ def test_prev_year
+ d = Date.new(2000,1,31).prev_year(-1)
+ assert_equal([2001, 1, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31).prev_year
+ assert_equal([1999, 1, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31).prev_year(10)
+ assert_equal([1990, 1, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31).prev_year(100)
+ assert_equal([1900, 1, 31], [d.year, d.mon, d.mday])
+ end
+
+ def test_next
+ d = Date.new(2000,12,31).next
+ assert_equal([2001, 1, 1], [d.year, d.mon, d.mday])
+ d = Date.new(2000,12,31).succ
+ assert_equal([2001, 1, 1], [d.year, d.mon, d.mday])
+
+ d = Date.today
+ d2 = d.next
+ assert_equal(d, (d2 - 1))
+ d = Date.today
+ d2 = d.succ
+ assert_equal(d, (d2 - 1))
+
+ d = DateTime.now
+ d2 = d.next
+ assert_equal(d, (d2 - 1))
+ d = DateTime.now
+ d2 = d.succ
+ assert_equal(d, (d2 - 1))
+ end
+
+ def test_next_day
+ d = Date.new(2000,12,31).next_day
+ assert_equal([2001, 1, 1], [d.year, d.mon, d.mday])
+ d = Date.new(2000,12,31).next_day(2)
+ assert_equal([2001, 1, 2], [d.year, d.mon, d.mday])
+ d = Date.new(2001,1,1).next_day(-2)
+ assert_equal([2000, 12, 30], [d.year, d.mon, d.mday])
+
+ d = DateTime.new(2000,2,29).next_day(1.to_r/2)
+ assert_equal([2000, 2, 29, 12, 0, 0], [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ end
+
+ def test_next_month
+ d = Date.new(2000,1,31) >> -1
+ assert_equal([1999, 12, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31) >> 1
+ assert_equal([2000, 2, 29], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31) >> 12
+ assert_equal([2001, 1, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31) >> 13
+ assert_equal([2001, 2, 28], [d.year, d.mon, d.mday])
+ end
+
+ def test_next_month__2
+ d = Date.new(2000,1,31).next_month(-1)
+ assert_equal([1999, 12, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31).next_month
+ assert_equal([2000, 2, 29], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31).next_month(12)
+ assert_equal([2001, 1, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31).next_month(13)
+ assert_equal([2001, 2, 28], [d.year, d.mon, d.mday])
+ end
+
+ def test_next_year
+ d = Date.new(2000,1,31).next_year(-1)
+ assert_equal([1999, 1, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31).next_year
+ assert_equal([2001, 1, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31).next_year(10)
+ assert_equal([2010, 1, 31], [d.year, d.mon, d.mday])
+ d = Date.new(2000,1,31).next_year(100)
+ assert_equal([2100, 1, 31], [d.year, d.mon, d.mday])
+ end
+
+ def test_downto
+ p = Date.new(2001,1,14)
+ q = Date.new(2001,1,7)
+ i = 0
+ p.downto(q) do |d|
+ i += 1
+ end
+ assert_equal(8, i)
+ end
+
+ def test_downto__noblock
+ p = Date.new(2001,1,14)
+ q = Date.new(2001,1,7)
+ e = p.downto(q)
+ assert_equal(8, e.to_a.size)
+ end
+
+ def test_upto
+ p = Date.new(2001,1,14)
+ q = Date.new(2001,1,21)
+ i = 0
+ p.upto(q) do |d|
+ i += 1
+ end
+ assert_equal(8, i)
+ end
+
+ def test_upto__noblock
+ p = Date.new(2001,1,14)
+ q = Date.new(2001,1,21)
+ e = p.upto(q)
+ assert_equal(8, e.to_a.size)
+ end
+
+ def test_step
+ p = Date.new(2001,1,14)
+ q = Date.new(2001,1,21)
+ i = 0
+ p.step(q, 2) do |d|
+ i += 1
+ end
+ assert_equal(4, i)
+
+ i = 0
+ p.step(q) do |d|
+ i += 1
+ end
+ assert_equal(8, i)
+ end
+
+ def test_step__noblock
+ p = Date.new(2001,1,14)
+ q = Date.new(2001,1,21)
+ e = p.step(q, 2)
+ assert_equal(4, e.to_a.size)
+
+ e = p.step(q)
+ assert_equal(8, e.to_a.size)
+ end
+
+=begin
+ def test_step__inf
+ p = Date.new(2001,1,14)
+ q = Date.new(2001,1,21)
+ inf = 1.0/0
+
+ if inf.infinite?
+ [p, q].each do |a|
+ [p, q].each do |b|
+ [inf, -inf].each do |c|
+ i = 0
+ a.step(b, c) do |d|
+ i += 1
+ end
+ assert_equal(0, i)
+ end
+ end
+ end
+ end
+ end
+=end
+
+end
Added: MacRuby/trunk/test/test-mri/test/date/test_date_attr.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/date/test_date_attr.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/date/test_date_attr.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,109 @@
+require 'test/unit'
+require 'date'
+
+class TestDateAttr < Test::Unit::TestCase
+
+ def test__attr
+ date = Date.new(1965, 5, 23)
+ datetime = DateTime.new(1965, 5, 23, 22, 31, 59)
+
+ [date, datetime].each_with_index do |d, i|
+ if i == 0
+ assert_match(/\#<Date\d?: 1965-05-23 \(4877807\/2,0,2299161\)>/,
+ d.inspect)
+ else
+ assert_match(/\#<DateTime\d?: 1965-05-23T22:31:59\+00:00 \(210721343519\/86400,0,2299161\)>/,
+ d.inspect)
+ end
+
+ if i == 0
+ assert_equal('1965-05-23', d.to_s)
+ else
+ assert_equal('1965-05-23T22:31:59+00:00', d.to_s)
+ end
+
+ assert_equal('', d.inspect.gsub!(/./,''))
+ assert_equal('', d.to_s.gsub!(/./,''))
+
+ assert_equal(2438904, d.jd)
+
+ if i == 0
+ assert_equal(0, d.day_fraction)
+ else
+ assert_equal(22.to_r/24 + 31.to_r/1440 + 59.to_r/86400, d.day_fraction)
+ end
+
+ assert_equal(38903, d.mjd)
+ assert_equal(139744, d.ld)
+
+ assert_equal(1965, d.year)
+ assert_equal(143, d.yday)
+ assert_equal(5, d.mon)
+ assert_equal(d.mon, d.month)
+ assert_equal(23, d.mday)
+ assert_equal(d.mday, d.day)
+
+ if i == 0
+ assert_equal(false, d.respond_to?(:hour))
+ assert_equal(false, d.respond_to?(:min))
+ assert_equal(false, d.respond_to?(:sec))
+ assert_equal(false, d.respond_to?(:sec_fraction))
+ assert_equal(false, d.respond_to?(:zone))
+ assert_equal(false, d.respond_to?(:offset))
+ else
+ assert_equal(22, d.hour)
+ assert_equal(31, d.min)
+ assert_equal(59, d.sec)
+ assert_equal(0, d.sec_fraction)
+ assert_equal('+00:00', d.zone)
+ assert_equal(0, d.offset)
+ end
+
+ assert_equal(1965, d.cwyear)
+ assert_equal(20, d.cweek)
+ assert_equal(7, d.cwday)
+
+ assert_equal(0, d.wday)
+ assert_equal(false, d.leap?)
+ assert_equal(false, d.julian?)
+ assert_equal(true, d.gregorian?)
+
+ assert_equal(Date::ITALY, d.start)
+ assert_equal(d.start, d.start)
+ end
+
+ d = DateTime.new(1965, 5, 23, 22, 31, 59) + 1.to_r/(86400*2)
+ assert_equal(1.to_r/2, d.sec_fraction)
+ end
+
+ def test__wday_predicate
+ d = Date.new(2005, 10, 23)
+ assert_equal(true, d.sunday?)
+ assert_equal(false, d.monday?)
+ assert_equal(false, d.tuesday?)
+ assert_equal(false, d.wednesday?)
+ assert_equal(false, d.thursday?)
+ assert_equal(false, d.friday?)
+ assert_equal(false, d.saturday?)
+
+ d = Date.new(2005, 10, 30)
+ 14.times do |i|
+ assert((d + i).__send__(%w(sunday? monday? tuesday? wednesday?
+ thursday? friday? saturday?)[i % 7]))
+ end
+ end
+
+ def test_nth_kday
+ assert_equal(false, Date.new(2001,1,14).__send__(:nth_kday?, 1,0))
+ assert_equal(true, Date.new(2001,1,14).__send__(:nth_kday?, 2,0))
+ assert_equal(false, Date.new(2001,1,14).__send__(:nth_kday?, 3,0))
+ assert_equal(false, Date.new(2001,1,14).__send__(:nth_kday?, 4,0))
+ assert_equal(false, Date.new(2001,1,14).__send__(:nth_kday?, 5,0))
+ assert_equal(false, Date.new(2001,1,14).__send__(:nth_kday?, -1,0))
+ assert_equal(false, Date.new(2001,1,14).__send__(:nth_kday?, -2,0))
+ assert_equal(true, Date.new(2001,1,14).__send__(:nth_kday?, -3,0))
+ assert_equal(false, Date.new(2001,1,14).__send__(:nth_kday?, -4,0))
+ assert_equal(false, Date.new(2001,1,14).__send__(:nth_kday?, -5,0))
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/date/test_date_base.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/date/test_date_base.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/date/test_date_base.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,435 @@
+require 'test/unit'
+require 'date'
+
+begin
+ require 'calendar'
+ include Calendar
+rescue LoadError
+end
+
+class TestDateBase < Test::Unit::TestCase
+
+ def setup
+ if defined?(Calendar)
+ @from ||= julian_day_number_from_absolute(absolute_from_julian(1, 1, 1601))
+ @to ||= julian_day_number_from_absolute(absolute_from_julian(12, 31, 2400))
+ @from4t ||= julian_day_number_from_absolute(absolute_from_julian(1, 1, 1970))
+ @to4t ||= julian_day_number_from_absolute(absolute_from_julian(12, 31, 2037))
+ end
+ end
+
+ def test__inf
+ assert_equal(0, Date::Infinity.new(-1) <=> Date::Infinity.new(-1))
+ assert_equal(-1, Date::Infinity.new(-1) <=> Date::Infinity.new(+1))
+ assert_equal(-1, Date::Infinity.new(-1) <=> 0)
+
+ assert_equal(1, Date::Infinity.new(+1) <=> Date::Infinity.new(-1))
+ assert_equal(0, Date::Infinity.new(+1) <=> Date::Infinity.new(+1))
+ assert_equal(1, Date::Infinity.new(+1) <=> 0)
+
+ assert_equal(1, 0 <=> Date::Infinity.new(-1))
+ assert_equal(-1, 0 <=> Date::Infinity.new(+1))
+ assert_equal(0, 0 <=> 0)
+
+ assert_equal(0, Date::ITALY <=> Date::ITALY)
+ assert_equal(-1, Date::ITALY <=> Date::ENGLAND)
+ assert_equal(-1, Date::ITALY <=> Date::JULIAN)
+ assert_equal(1, Date::ITALY <=> Date::GREGORIAN)
+
+ assert_equal(1, Date::ENGLAND <=> Date::ITALY)
+ assert_equal(0, Date::ENGLAND <=> Date::ENGLAND)
+ assert_equal(-1, Date::ENGLAND <=> Date::JULIAN)
+ assert_equal(1, Date::ENGLAND <=> Date::GREGORIAN)
+
+ assert_equal(1, Date::JULIAN <=> Date::ITALY)
+ assert_equal(1, Date::JULIAN <=> Date::ENGLAND)
+ assert_equal(0, Date::JULIAN <=> Date::JULIAN)
+ assert_equal(1, Date::JULIAN <=> Date::GREGORIAN)
+
+ assert_equal(-1, Date::GREGORIAN <=> Date::ITALY)
+ assert_equal(-1, Date::GREGORIAN <=> Date::ENGLAND)
+ assert_equal(-1, Date::GREGORIAN <=> Date::JULIAN)
+ assert_equal(0, Date::GREGORIAN <=> Date::GREGORIAN)
+ end
+
+ def test_ordinal__julian
+ unless defined?(Calendar)
+ return
+ end
+ for j in @from.. at to
+ m, d, y = julian_from_absolute(absolute_from_julian_day_number(j))
+ j0 = julian_day_number_from_absolute(absolute_from_julian(12, 31, y - 1))
+ j2 = julian_day_number_from_absolute(absolute_from_julian(m, d, y))
+ assert_equal(j, j2)
+ oy, od = Date.__send__(:jd_to_ordinal, j, Date::JULIAN)
+ assert_equal(y, oy)
+ assert_equal(j2 - j0, od)
+ oj = Date.__send__(:ordinal_to_jd, oy, od, Date::JULIAN)
+ assert_equal(j, oj)
+ end
+ end
+
+ def test_ordinal__gregorian
+ unless defined?(Calendar)
+ return
+ end
+ for j in @from.. at to
+ m, d, y = gregorian_from_absolute(absolute_from_julian_day_number(j))
+ j0 =
+ julian_day_number_from_absolute(absolute_from_gregorian(12, 31, y - 1))
+ j2 = julian_day_number_from_absolute(absolute_from_gregorian(m, d, y))
+ assert_equal(j, j2)
+ oy, od = Date.__send__(:jd_to_ordinal, j, Date::GREGORIAN)
+ assert_equal(y, oy)
+ assert_equal(j2 - j0, od)
+ oj = Date.__send__(:ordinal_to_jd, oy, od, Date::GREGORIAN)
+ assert_equal(j, oj)
+ end
+ end
+
+ def test_civil__julian
+ unless defined?(Calendar)
+ return
+ end
+ for j in @from.. at to
+ m, d, y = julian_from_absolute(absolute_from_julian_day_number(j))
+ j2 = julian_day_number_from_absolute(absolute_from_julian(m, d, y))
+ assert_equal(j2, j)
+ cy, cm, cd = Date.__send__(:jd_to_civil, j, Date::JULIAN)
+ assert_equal(y, cy)
+ assert_equal(m, cm)
+ assert_equal(d, cd)
+ cj = Date.__send__(:civil_to_jd, cy, cm, cd, Date::JULIAN)
+ assert_equal(j, cj)
+ end
+ end
+
+ def test_civil__gregorian
+ unless defined?(Calendar)
+ return
+ end
+ for j in @from.. at to
+ m, d, y = gregorian_from_absolute(absolute_from_julian_day_number(j))
+ j2 = julian_day_number_from_absolute(absolute_from_gregorian(m, d, y))
+ assert_equal(j2, j)
+ cy, cm, cd = Date.__send__(:jd_to_civil, j, Date::GREGORIAN)
+ assert_equal(y, cy)
+ assert_equal(m, cm)
+ assert_equal(d, cd)
+ cj = Date.__send__(:civil_to_jd, cy, cm, cd, Date::GREGORIAN)
+ assert_equal(j, cj)
+ end
+ end
+
+ def test_commercial__gregorian
+ unless defined?(Calendar)
+ return
+ end
+ for j in @from.. at to
+ w, d, y = iso_from_absolute(absolute_from_julian_day_number(j))
+ j2 = julian_day_number_from_absolute(absolute_from_iso(w, d, y))
+ assert_equal(j2, j)
+ cy, cw, cd = Date.__send__(:jd_to_commercial, j, Date::GREGORIAN)
+ assert_equal(y, cy)
+ assert_equal(w, cw)
+ assert_equal(d, cd)
+ cj = Date.__send__(:commercial_to_jd, cy, cw, cd, Date::GREGORIAN)
+ assert_equal(j, cj)
+ end
+ end
+
+ def test_weeknum
+ unless defined?(Calendar)
+ return
+ end
+ for j in @from.. at to
+ for k in 0..1
+ wy, ww, wd = Date.__send__(:jd_to_weeknum, j, k, Date::GREGORIAN)
+ wj = Date.__send__(:weeknum_to_jd, wy, ww, wd, k, Date::GREGORIAN)
+ assert_equal(j, wj)
+ end
+ end
+ end
+
+ def test_weeknum__2
+ unless defined?(Calendar)
+ return
+ end
+ for j in @from4t.. at to4t
+ d = Date.jd(j)
+ t = Time.mktime(d.year, d.mon, d.mday)
+ [
+ '%Y %U %w',
+ '%Y %U %u',
+ '%Y %W %w',
+ '%Y %W %u'
+ ].each do |fmt|
+ s = t.strftime(fmt)
+ d2 = Date.strptime(s, fmt)
+ assert_equal(j, d2.jd)
+ end
+ end
+ end
+
+ def test_nth_kday
+ unless defined?(Calendar)
+ return
+ end
+ for y in 1601..2401
+ for m in 1..12
+ for n in -5..5
+ next if n == 0
+ for k in 0..6
+ j = julian_day_number_from_absolute(Nth_Kday(n, k, m, y))
+ j2 = Date.__send__(:nth_kday_to_jd, y, m, n, k, Date::GREGORIAN)
+ assert_equal(j, j2)
+
+ d1 = Date.__send__(:jd_to_nth_kday, j2, Date::GREGORIAN)
+ j3 = Date.__send__(:nth_kday_to_jd, *d1)
+ assert_equal(j, j3)
+ end
+ end
+ end
+ end
+ end
+
+ def test_mjd
+ jd = Date.__send__(:mjd_to_jd, 51321)
+ mjd = Date.__send__(:jd_to_mjd, jd)
+ assert_equal(51321, mjd)
+ end
+
+ def test_ld
+ jd = Date.__send__(:ld_to_jd, 152162)
+ ld = Date.__send__(:jd_to_ld, jd)
+ assert_equal(152162, ld)
+ end
+
+ def test_wday
+ assert_equal(4, Date.__send__(:jd_to_wday, 3))
+ assert_equal(3, Date.__send__(:jd_to_wday, 2))
+ assert_equal(2, Date.__send__(:jd_to_wday, 1))
+ assert_equal(1, Date.__send__(:jd_to_wday, 0))
+ assert_equal(0, Date.__send__(:jd_to_wday, -1))
+ assert_equal(6, Date.__send__(:jd_to_wday, -2))
+ assert_equal(5, Date.__send__(:jd_to_wday, -3))
+ end
+
+ def test_leap?
+ assert_equal(true, Date.julian_leap?(1900))
+ assert_equal(false, Date.julian_leap?(1999))
+ assert_equal(true, Date.julian_leap?(2000))
+
+ assert_equal(false, Date.gregorian_leap?(1900))
+ assert_equal(false, Date.gregorian_leap?(1999))
+ assert_equal(true, Date.gregorian_leap?(2000))
+
+ assert_equal(Date.leap?(1990), Date.gregorian_leap?(1900))
+ assert_equal(Date.leap?(1999), Date.gregorian_leap?(1999))
+ assert_equal(Date.leap?(2000), Date.gregorian_leap?(2000))
+ end
+
+ def test_valid_jd
+ valid_jd_p = :_valid_jd?
+ assert_equal(-1, Date.__send__(valid_jd_p, -1))
+ assert_equal(0, Date.__send__(valid_jd_p, 0))
+ assert_equal(1, Date.__send__(valid_jd_p, 1))
+ assert_equal(2452348, Date.__send__(valid_jd_p, 2452348))
+ end
+
+ def test_valid_ordinal
+ valid_ordinal_p = :_valid_ordinal?
+ assert_nil(Date.__send__(valid_ordinal_p, 1999,366))
+ assert_equal(2451910, Date.__send__(valid_ordinal_p, 2000,366))
+ assert_nil(Date.__send__(valid_ordinal_p, 1999,-366))
+ assert_equal(2451545, Date.__send__(valid_ordinal_p, 2000,-366))
+ assert_equal(2452275, Date.__send__(valid_ordinal_p, 2001,365))
+ assert_nil(Date.__send__(valid_ordinal_p, 2001,366))
+ assert_equal(Date.__send__(valid_ordinal_p, 2001,1),
+ Date.__send__(valid_ordinal_p, 2001,-365))
+ assert_nil(Date.__send__(valid_ordinal_p, 2001,-366))
+ assert_equal(2452348, Date.__send__(valid_ordinal_p, 2002,73))
+ end
+
+ def test_valid_ordinal__edge
+ valid_ordinal_p = :_valid_ordinal?
+ (1601..2400).each do |y|
+ d = if Date.leap?(y) then 366 else 365 end
+ assert_not_nil(Date.__send__(valid_ordinal_p, y,d))
+ assert_nil(Date.__send__(valid_ordinal_p, y,d + 1))
+ assert_not_nil(Date.__send__(valid_ordinal_p, y,-d))
+ assert_nil(Date.__send__(valid_ordinal_p, y,-(d + 1)))
+ end
+ end
+
+ # October 1582
+ # S M Tu W Th F S
+ # 274 275 276 277 288 289
+ # 290 291 292 293 294 295 296
+ # 297 298 299 300 301 302 303
+ # 304
+
+ # October 1582
+ # S M Tu W Th F S
+ # -92 -91 -90 -89 -78 -77
+ # -76 -75 -74 -73 -72 -71 -70
+ # -69 -68 -67 -66 -65 -64 -63
+ # -62
+
+ def test_valid_ordinal__italy
+ valid_ordinal_p = :_valid_ordinal?
+ (1..355).each do |d|
+ assert_not_nil(Date.__send__(valid_ordinal_p, 1582,d,Date::ITALY))
+ end
+ (356..365).each do |d|
+ assert_nil(Date.__send__(valid_ordinal_p, 1582,d,Date::ITALY))
+ end
+ end
+
+ # September 1752
+ # S M Tu W Th F S
+ # 245 246 258 259 260
+ # 261 262 263 264 265 266 267
+ # 268 269 270 271 272 273 274
+
+ def test_valid_ordinal__england
+ valid_ordinal_p = :_valid_ordinal?
+ (1..355).each do |d|
+ assert_not_nil(Date.__send__(valid_ordinal_p, 1752,d,Date::ENGLAND))
+ end
+ (356..366).each do |d|
+ assert_nil(Date.__send__(valid_ordinal_p, 1752,d,Date::ENGLAND))
+ end
+ end
+
+ def test_valid_civil
+ valid_civil_p = :_valid_civil?
+ assert_nil(Date.__send__(valid_civil_p, 1999,2,29))
+ assert_equal(2451604, Date.__send__(valid_civil_p, 2000,2,29))
+ assert_nil(Date.__send__(valid_civil_p, 1999,2,-29))
+ assert_equal(2451576, Date.__send__(valid_civil_p, 2000,2,-29))
+ assert_equal(2451941, Date.__send__(valid_civil_p, 2001,1,31))
+ assert_nil(Date.__send__(valid_civil_p, 2001,1,32))
+ assert_equal(Date.__send__(valid_civil_p, 2001,1,1),
+ Date.__send__(valid_civil_p, 2001,1,-31))
+ assert_nil(Date.__send__(valid_civil_p, 2001,1,-32))
+ assert_equal(2452348, Date.__send__(valid_civil_p, 2002,3,14))
+ end
+
+ def test_valid_civil__edge
+ valid_civil_p = :_valid_civil?
+ (1601..2400).each do |y|
+ d = if Date.leap?(y) then 29 else 28 end
+ assert_not_nil(Date.__send__(valid_civil_p, y,2,d))
+ assert_nil(Date.__send__(valid_civil_p, y,2,d + 1))
+ assert_not_nil(Date.__send__(valid_civil_p, y,2,-d))
+ assert_nil(Date.__send__(valid_civil_p, y,2,-(d + 1)))
+ end
+ end
+
+ # October 1582
+ # S M Tu W Th F S
+ # 1 2 3 4 15 16
+ # 17 18 19 20 21 22 23
+ # 24 25 26 27 28 29 30
+ # 31
+
+ def test_valid_civil__italy
+ valid_civil_p = :_valid_civil?
+ (1..4).each do |d|
+ assert_not_nil(Date.__send__(valid_civil_p, 1582,10,d,Date::ITALY))
+ end
+ (5..14).each do |d|
+ assert_nil(Date.__send__(valid_civil_p, 1582,10,d,Date::ITALY))
+ end
+ (15..31).each do |d|
+ assert_not_nil(Date.__send__(valid_civil_p, 1582,10,d,Date::ITALY))
+ end
+ (32..100).each do |d|
+ assert_nil(Date.__send__(valid_civil_p, 1582,10,d,Date::ITALY))
+ end
+ (-31..-22).each do |d|
+ assert_nil(Date.__send__(valid_civil_p, 1582,10,d,Date::ITALY))
+ end
+ (-21..-1).each do |d|
+ assert_not_nil(Date.__send__(valid_civil_p, 1582,10,d,Date::ITALY))
+ end
+ end
+
+ # September 1752
+ # S M Tu W Th F S
+ # 1 2 14 15 16
+ # 17 18 19 20 21 22 23
+ # 24 25 26 27 28 29 30
+
+ def test_valid_civil__england
+ valid_civil_p = :_valid_civil?
+ (1..2).each do |d|
+ assert_not_nil(Date.__send__(valid_civil_p, 1752,9,d,Date::ENGLAND))
+ end
+ (3..13).each do |d|
+ assert_nil(Date.__send__(valid_civil_p, 1752,9,d,Date::ENGLAND))
+ end
+ (14..30).each do |d|
+ assert_not_nil(Date.__send__(valid_civil_p, 1752,9,d,Date::ENGLAND))
+ end
+ (31..100).each do |d|
+ assert_nil(Date.__send__(valid_civil_p, 1752,9,d,Date::ENGLAND))
+ end
+ (-31..-20).each do |d|
+ assert_nil(Date.__send__(valid_civil_p, 1752,9,d,Date::ENGLAND))
+ end
+ (-19..-1).each do |d|
+ assert_not_nil(Date.__send__(valid_civil_p, 1752,9,d,Date::ENGLAND))
+ end
+ end
+
+ def test_valid_commercial
+ valid_commercial_p = :_valid_commercial?
+ assert_nil(Date.__send__(valid_commercial_p, 1999,53,1))
+ assert_equal(2453367, Date.__send__(valid_commercial_p, 2004,53,1))
+ assert_nil(Date.__send__(valid_commercial_p, 1999,-53,-1))
+ assert_equal(2453009, Date.__send__(valid_commercial_p, 2004,-53,-1))
+ assert_equal(2452348, Date.__send__(valid_commercial_p, 2002,11,4))
+ end
+
+ def test_valid_weeknum
+ valid_weeknum_p = :_valid_weeknum?
+ assert_nil(Date.__send__(valid_weeknum_p, 1999,53,0, 0))
+ assert_equal(2454101, Date.__send__(valid_weeknum_p, 2006,53,0, 0))
+ assert_nil(Date.__send__(valid_weeknum_p, 1999,-53,-1, 0))
+ assert_equal(2453743, Date.__send__(valid_weeknum_p, 2006,-53,-1, 0))
+ assert_equal(2452355, Date.__send__(valid_weeknum_p, 2002,11,4, 0))
+ assert_nil(Date.__send__(valid_weeknum_p, 1999,53,0, 1))
+ assert_equal(2454101, Date.__send__(valid_weeknum_p, 2006,52,6, 1))
+ assert_nil(Date.__send__(valid_weeknum_p, 1999,-53,-1, 1))
+ assert_equal(2453743, Date.__send__(valid_weeknum_p, 2006,-52,-2, 1))
+ assert_equal(2452355, Date.__send__(valid_weeknum_p, 2002,11,3, 1))
+ end
+
+ def test_valid_nth_kday
+ valid_nth_kday_p = :_valid_nth_kday?
+ assert_nil(Date.__send__(valid_nth_kday_p, 1992,2, 5,0))
+ assert_equal(2448682, Date.__send__(valid_nth_kday_p, 1992,2, 5,6))
+ assert_equal(2448682, Date.__send__(valid_nth_kday_p, 1992,2, 5,-1))
+ assert_equal(2448682, Date.__send__(valid_nth_kday_p, 1992,2, -1,6))
+ assert_equal(2448682, Date.__send__(valid_nth_kday_p, 1992,2, -1,-1))
+ end
+
+ def test_valid_time
+ valid_time_p = :_valid_time?
+ assert_equal(Rational(0), DateTime.__send__(valid_time_p, 0,0,0))
+ assert_nil(DateTime.__send__(valid_time_p, 25,59,59))
+ assert_nil(DateTime.__send__(valid_time_p, 23,60,59))
+ assert_nil(DateTime.__send__(valid_time_p, 23,59,60))
+ assert_equal(Rational(86399, 86400),
+ DateTime.__send__(valid_time_p, 23,59,59))
+ assert_equal(Rational(86399, 86400),
+ DateTime.__send__(valid_time_p, -1,-1,-1))
+ assert_equal(Rational(1), DateTime.__send__(valid_time_p, 24,0,0))
+ assert_nil(DateTime.__send__(valid_time_p, 24,0,1))
+ assert_nil(DateTime.__send__(valid_time_p, 24,1,0))
+ assert_nil(DateTime.__send__(valid_time_p, 24,1,1))
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/date/test_date_compat.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/date/test_date_compat.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/date/test_date_compat.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,21 @@
+require 'test/unit'
+require 'date'
+
+class TestDateCompat < Test::Unit::TestCase
+
+ def test_compat
+ assert_equal(DateTime.new, Date.new)
+ assert_equal(DateTime.new(2002,3,19), Date.new(2002,3,19))
+ assert_equal(DateTime.new(2002,3,19, 0,0,0), Date.new(2002,3,19))
+ assert_equal(DateTime.new(2002,3,19, 0,0,0, 0), Date.new(2002,3,19))
+ assert_equal(DateTime.new(2002,3,19, 0,0,0, 0.to_r), Date.new(2002,3,19))
+ assert_equal(DateTime.new(2002,3,19, 0,0,0, 0, Date::GREGORIAN), Date.new(2002,3,19, Date::GREGORIAN))
+ assert_equal(DateTime.new(2002,3,19, 0,0,0, 0, Date::JULIAN), Date.new(2002,3,19, Date::JULIAN))
+
+ assert(Date.new(2002,3,19) != DateTime.new(2002,3,19, 12,0,0))
+ assert(Date.new(2002,3,19) != DateTime.new(2002,3,19, 0,0,1))
+ assert(Date.new(2002,3,19) === DateTime.new(2002,3,19, 12,0,0))
+ assert(Date.new(2002,3,19) === DateTime.new(2002,3,19, 0,0,1))
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/date/test_date_conv.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/date/test_date_conv.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/date/test_date_conv.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,137 @@
+require 'test/unit'
+require 'date'
+
+class TestDateConv < Test::Unit::TestCase
+
+ def test_to_class
+ [Time.now, Date.today, DateTime.now].each do |o|
+ assert_instance_of(Time, o.to_time)
+ assert_instance_of(Date, o.to_date)
+ assert_instance_of(DateTime, o.to_datetime)
+ end
+ end
+
+ def test_to_time__from_time
+ t = Time.mktime(2004, 9, 19, 1, 2, 3, 456789)
+ t2 = t.to_time
+ assert_equal([2004, 9, 19, 1, 2, 3, 456789],
+ [t2.year, t2.mon, t2.mday, t2.hour, t2.min, t2.sec, t2.usec])
+
+ t = Time.utc(2004, 9, 19, 1, 2, 3, 456789)
+ t2 = t.to_time.utc
+ assert_equal([2004, 9, 19, 1, 2, 3, 456789],
+ [t2.year, t2.mon, t2.mday, t2.hour, t2.min, t2.sec, t2.usec])
+ end
+
+ def test_to_time__from_date
+ d = Date.new(2004, 9, 19)
+ t = d.to_time
+ assert_equal([2004, 9, 19, 0, 0, 0, 0],
+ [t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.usec])
+ end
+
+ def test_to_time__from_datetime
+ d = DateTime.new(2004, 9, 19, 1, 2, 3, 9.to_r/24) + 456789.to_r/86400000000
+ t = d.to_time
+ if t.utc_offset == 9*60*60
+ assert_equal([2004, 9, 19, 1, 2, 3, 456789],
+ [t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.usec])
+ end
+
+ d = DateTime.new(2004, 9, 19, 1, 2, 3, 0) + 456789.to_r/86400000000
+ t = d.to_time.utc
+ assert_equal([2004, 9, 19, 1, 2, 3, 456789],
+ [t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.usec])
+
+ if Time.allocate.respond_to?(:nsec)
+ d = DateTime.new(2004, 9, 19, 1, 2, 3, 0) + 456789123.to_r/86400000000000
+ t = d.to_time.utc
+ assert_equal([2004, 9, 19, 1, 2, 3, 456789123],
+ [t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.nsec])
+ end
+
+ if Time.allocate.respond_to?(:subsec)
+ d = DateTime.new(2004, 9, 19, 1, 2, 3, 0) + 456789123456789123.to_r/86400000000000000000000
+ t = d.to_time.utc
+ assert_equal([2004, 9, 19, 1, 2, 3, Rational(456789123456789123,1000000000000000000)],
+ [t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.subsec])
+ end
+ end
+
+ def test_to_date__from_time
+ t = Time.mktime(2004, 9, 19, 1, 2, 3, 456789)
+ d = t.to_date
+ assert_equal([2004, 9, 19, 0], [d.year, d.mon, d.mday, d.day_fraction])
+
+ t = Time.utc(2004, 9, 19, 1, 2, 3, 456789)
+ d = t.to_date
+ assert_equal([2004, 9, 19, 0], [d.year, d.mon, d.mday, d.day_fraction])
+ end
+
+ def test_to_date__from_date
+ d = Date.new(2004, 9, 19) + 1.to_r/2
+ d2 = d.to_date
+ assert_equal([2004, 9, 19, 1.to_r/2],
+ [d2.year, d2.mon, d2.mday, d2.day_fraction])
+ end
+
+ def test_to_date__from_datetime
+ d = DateTime.new(2004, 9, 19, 1, 2, 3, 9.to_r/24) + 456789.to_r/86400000000
+ d2 = d.to_date
+ assert_equal([2004, 9, 19, 0], [d2.year, d2.mon, d2.mday, d2.day_fraction])
+
+ d = DateTime.new(2004, 9, 19, 1, 2, 3, 0) + 456789.to_r/86400000000
+ d2 = d.to_date
+ assert_equal([2004, 9, 19, 0], [d2.year, d2.mon, d2.mday, d2.day_fraction])
+ end
+
+ def test_to_datetime__from_time
+ t = Time.mktime(2004, 9, 19, 1, 2, 3, 456789)
+ d = t.to_datetime
+ assert_equal([2004, 9, 19, 1, 2, 3,
+ 456789.to_r/1000000,
+ t.utc_offset.to_r/86400],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec,
+ d.sec_fraction, d.offset])
+
+ t = Time.utc(2004, 9, 19, 1, 2, 3, 456789)
+ d = t.to_datetime
+ assert_equal([2004, 9, 19, 1, 2, 3,
+ 456789.to_r/1000000,
+ 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec,
+ d.sec_fraction, d.offset])
+
+ t = Time.now
+ d = t.to_datetime
+ require 'time'
+ assert_equal(t.iso8601(10), d.iso8601(10))
+ end
+
+ def test_to_datetime__from_date
+ d = Date.new(2004, 9, 19) + 1.to_r/2
+ d2 = d.to_datetime
+ assert_equal([2004, 9, 19, 0, 0, 0, 0, 0],
+ [d2.year, d2.mon, d2.mday, d2.hour, d2.min, d2.sec,
+ d2.sec_fraction, d2.offset])
+ end
+
+ def test_to_datetime__from_datetime
+ d = DateTime.new(2004, 9, 19, 1, 2, 3, 9.to_r/24) + 456789.to_r/86400000000
+ d2 = d.to_datetime
+ assert_equal([2004, 9, 19, 1, 2, 3,
+ 456789.to_r/1000000,
+ 9.to_r/24],
+ [d2.year, d2.mon, d2.mday, d2.hour, d2.min, d2.sec,
+ d2.sec_fraction, d2.offset])
+
+ d = DateTime.new(2004, 9, 19, 1, 2, 3, 0) + 456789.to_r/86400000000
+ d2 = d.to_datetime
+ assert_equal([2004, 9, 19, 1, 2, 3,
+ 456789.to_r/1000000,
+ 0],
+ [d2.year, d2.mon, d2.mday, d2.hour, d2.min, d2.sec,
+ d2.sec_fraction, d2.offset])
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/date/test_date_marshal.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/date/test_date_marshal.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/date/test_date_marshal.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,29 @@
+require 'test/unit'
+require 'date'
+
+class TestDateMarshal < Test::Unit::TestCase
+
+ def test_marshal
+ d = Date.new
+ m = Marshal.dump(d)
+ d2 = Marshal.load(m)
+ assert_equal(d, d2)
+ assert_equal(d.start, d2.start)
+ assert_instance_of(String, d2.to_s)
+
+ d = Date.today
+ m = Marshal.dump(d)
+ d2 = Marshal.load(m)
+ assert_equal(d, d2)
+ assert_equal(d.start, d2.start)
+ assert_instance_of(String, d2.to_s)
+
+ d = DateTime.now
+ m = Marshal.dump(d)
+ d2 = Marshal.load(m)
+ assert_equal(d, d2)
+ assert_equal(d.start, d2.start)
+ assert_instance_of(String, d2.to_s)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/date/test_date_new.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/date/test_date_new.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/date/test_date_new.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,278 @@
+require 'test/unit'
+require 'date'
+
+class TestDateNew < Test::Unit::TestCase
+
+ def test_jd
+ d = Date.jd
+ dt = DateTime.jd
+ assert_equal([-4712, 1, 1], [d.year, d.mon, d.mday])
+ assert_equal([-4712, 1, 1], [dt.year, dt.mon, dt.mday])
+ assert_equal([0, 0, 0], [dt.hour, dt.min, dt.sec])
+
+ d2 = Date.jd
+ dt2 = DateTime.jd
+ assert_equal(d, d2)
+ assert_equal(dt, dt2)
+
+ d = Date.jd(0)
+ assert_equal([-4712, 1, 1], [d.year, d.mon, d.mday])
+ d = DateTime.jd(0, 0,0,0, 0)
+ assert_equal([-4712, 1, 1, 0, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ d = DateTime.jd(0, 0,0,0, '+0900')
+ assert_equal([-4712, 1, 1, 0, 0, 0, 9.to_r/24],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ end
+
+ def test_jd__ex
+ assert_raise(ArgumentError) do
+ DateTime.jd(0, 23,59,60,0)
+ end
+ end
+
+ def test_ordinal
+ d = Date.ordinal
+ dt = DateTime.ordinal
+ assert_equal([-4712, 1, 1], [d.year, d.mon, d.mday])
+ assert_equal([-4712, 1, 1], [dt.year, dt.mon, dt.mday])
+ assert_equal([0, 0, 0], [dt.hour, dt.min, dt.sec])
+
+ d2 = Date.ordinal
+ dt2 = DateTime.ordinal
+ assert_equal(d, d2)
+ assert_equal(dt, dt2)
+
+ d = Date.ordinal(-4712,1)
+ assert_equal([-4712, 1, 1], [d.year, d.mon, d.mday])
+
+ d = Date.ordinal(-4712,1.0)
+ assert_equal([-4712, 1, 1], [d.year, d.mon, d.mday])
+
+ d = DateTime.ordinal(-4712,1, 0,0,0, 0)
+ assert_equal([-4712, 1, 1, 0, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ d = DateTime.ordinal(-4712,1, 0,0,0, '+0900')
+ assert_equal([-4712, 1, 1, 0, 0, 0, 9.to_r/24],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ end
+
+ def test_ordinal__neg
+ d = Date.ordinal(-1,-1)
+ assert_equal([-1, 365], [d.year, d.yday])
+
+ d = DateTime.ordinal(-1,-1, -1,-1,-1, 0)
+ assert_equal([-1, 365, 23, 59, 59, 0],
+ [d.year, d.yday, d.hour, d.min, d.sec, d.offset])
+ end
+
+ def test_ordinal__ex
+ assert_raise(ArgumentError) do
+ Date.ordinal(2001,1.1)
+ end
+ assert_raise(ArgumentError) do
+ Date.ordinal(2001,366)
+ end
+ assert_raise(ArgumentError) do
+ DateTime.ordinal(2001,365, 23,59,60, 0)
+ end
+ end
+
+ def test_civil
+ d = Date.civil
+ dt = DateTime.civil
+ assert_equal([-4712, 1, 1], [d.year, d.mon, d.mday])
+ assert_equal([-4712, 1, 1], [dt.year, dt.mon, dt.mday])
+ assert_equal([0, 0, 0], [dt.hour, dt.min, dt.sec])
+
+ d2 = Date.civil
+ dt2 = DateTime.civil
+ assert_equal(d, d2)
+ assert_equal(dt, dt2)
+
+ d = Date.civil(-4712,1,1)
+ assert_equal([-4712, 1, 1], [d.year, d.mon, d.mday])
+
+ d = Date.civil(-4712,1,1.0)
+ assert_equal([-4712, 1, 1], [d.year, d.mon, d.mday])
+
+ d = DateTime.civil(-4712,1,1, 0,0,0, 0)
+ assert_equal([-4712, 1, 1, 0, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ d = DateTime.civil(-4712,1,1, 0,0,0, '+0900')
+ assert_equal([-4712, 1, 1, 0, 0, 0, 9.to_r/24],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+
+
+ d = DateTime.civil(2001,2,3 + 1.to_r/2)
+ assert_equal([2001, 2, 3, 12, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ d = DateTime.civil(2001,2,3, 4 + 1.to_r/2)
+ assert_equal([2001, 2, 3, 4, 30, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ d = DateTime.civil(2001,2,3, 4,5 + 1.to_r/2)
+ assert_equal([2001, 2, 3, 4, 5, 30, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ d = DateTime.civil(2001,2,3, 4,5,6 + 1.to_r/2)
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ assert_equal(1.to_r/2, d.sec_fraction)
+ end
+
+ def test_civil__neg
+ d = Date.civil(-1,-1,-1)
+ assert_equal([-1, 12, 31], [d.year, d.mon, d.mday])
+
+ d = DateTime.civil(-1,-1,-1, -1,-1,-1, 0)
+ assert_equal([-1, 12, 31, 23, 59, 59, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ end
+
+ def test_civil__ex
+ assert_raise(ArgumentError) do
+ Date.civil(2001,2,1.1)
+ end
+ assert_raise(ArgumentError) do
+ Date.civil(2001,2,29)
+ end
+ assert_raise(ArgumentError) do
+ DateTime.civil(2001,2,28, 23,59,60, 0)
+ end
+ assert_raise(ArgumentError) do
+ DateTime.civil(2001,2,28, 24,59,59, 0)
+ end
+ end
+
+ def test_civil__reform
+ d = Date.jd(Date::ENGLAND, Date::ENGLAND)
+ dt = DateTime.jd(Date::ENGLAND, 0,0,0,0, Date::ENGLAND)
+ assert_equal([1752, 9, 14], [d.year, d.mon, d.mday])
+ assert_equal([1752, 9, 14], [dt.year, dt.mon, dt.mday])
+ d -= 1
+ dt -= 1
+ assert_equal([1752, 9, 2], [d.year, d.mon, d.mday])
+ assert_equal([1752, 9, 2], [dt.year, dt.mon, dt.mday])
+
+ d = Date.jd(Date::ITALY, Date::ITALY)
+ dt = DateTime.jd(Date::ITALY, 0,0,0,0, Date::ITALY)
+ assert_equal([1582, 10, 15], [d.year, d.mon, d.mday])
+ assert_equal([1582, 10, 15], [dt.year, dt.mon, dt.mday])
+ d -= 1
+ dt -= 1
+ assert_equal([1582, 10, 4], [d.year, d.mon, d.mday])
+ assert_equal([1582, 10, 4], [dt.year, dt.mon, dt.mday])
+ end
+
+ def test_commercial
+ d = Date.commercial
+ dt = DateTime.commercial
+ assert_equal([-4712, 1, 1], [d.year, d.mon, d.mday])
+ assert_equal([-4712, 1, 1], [dt.year, dt.mon, dt.mday])
+ assert_equal([0, 0, 0], [dt.hour, dt.min, dt.sec])
+
+ d2 = Date.commercial
+ dt2 = DateTime.commercial
+ assert_equal(d, d2)
+ assert_equal(dt, dt2)
+
+ d = Date.commercial(1582,40,5)
+ assert_equal([1582, 10, 15], [d.year, d.mon, d.mday])
+
+ d = Date.commercial(1582,40,5.0)
+ assert_equal([1582, 10, 15], [d.year, d.mon, d.mday])
+
+ d = DateTime.commercial(1582,40,5, 0,0,0, 0)
+ assert_equal([1582, 10, 15, 0, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ d = DateTime.commercial(1582,40,5, 0,0,0, '+0900')
+ assert_equal([1582, 10, 15, 0, 0, 0, 9.to_r/24],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ end
+
+ def test_commercial__neg
+ d = Date.commercial(1998,-1,-1)
+ assert_equal([1999, 1, 3], [d.year, d.mon, d.mday])
+
+ d = DateTime.commercial(1998,-1,-1, -1,-1,-1, 0)
+ assert_equal([1999, 1, 3, 23, 59, 59, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset])
+ end
+
+ def test_commercial__ex
+ assert_raise(ArgumentError) do
+ Date.commercial(1997,1,1.1)
+ end
+ assert_raise(ArgumentError) do
+ Date.commercial(1997,53,1)
+ end
+ assert_raise(ArgumentError) do
+ DateTime.commercial(1997,52,1, 23,59,60, 0)
+ end
+ end
+
+ def test_weeknum
+ d = Date.__send__(:weeknum)
+ dt = DateTime.__send__(:weeknum)
+ assert_equal([-4712, 1, 1], [d.year, d.mon, d.mday])
+ assert_equal([-4712, 1, 1], [dt.year, dt.mon, dt.mday])
+ assert_equal([0, 0, 0], [dt.hour, dt.min, dt.sec])
+
+ d = Date.__send__(:weeknum, 2002,11,4, 0)
+ assert_equal(2452355, d.jd)
+
+ d = DateTime.__send__(:weeknum, 2002,11,4, 0, 11,22,33)
+ assert_equal(2452355, d.jd)
+ assert_equal([11,22,33], [d.hour, d.min, d.sec])
+
+ assert_raise(ArgumentError) do
+ Date.__send__(:weeknum, 1999,53,0, 0)
+ end
+ assert_raise(ArgumentError) do
+ Date.__send__(:weeknum, 1999,-53,-1, 0)
+ end
+ end
+
+ def test_nth_kday
+ d = Date.__send__(:nth_kday)
+ dt = DateTime.__send__(:nth_kday)
+ assert_equal([-4712, 1, 1], [d.year, d.mon, d.mday])
+ assert_equal([-4712, 1, 1], [dt.year, dt.mon, dt.mday])
+ assert_equal([0, 0, 0], [dt.hour, dt.min, dt.sec])
+
+ d = Date.__send__(:nth_kday, 1992,2, 5,6)
+ assert_equal(2448682, d.jd)
+
+ d = DateTime.__send__(:nth_kday, 1992,2, 5,6, 11,22,33)
+ assert_equal(2448682, d.jd)
+ assert_equal([11,22,33], [d.hour, d.min, d.sec])
+
+ assert_raise(ArgumentError) do
+ Date.__send__(:nth_kday, 2006,5, 5,0)
+ end
+ assert_raise(ArgumentError) do
+ Date.__send__(:nth_kday, 2006,5, -5,0)
+ end
+ end
+
+ def test_today
+ z = Time.now
+ d = Date.today
+ t = Time.now
+ t2 = Time.utc(t.year, t.mon, t.mday)
+ t3 = Time.utc(d.year, d.mon, d.mday)
+ assert_in_delta(t2, t3, t - z + 2)
+
+ assert_equal(false, DateTime.respond_to?(:today))
+ end
+
+ def test_now
+ assert_equal(false, Date.respond_to?(:now))
+
+ z = Time.now
+ d = DateTime.now
+ t = Time.now
+ t2 = Time.local(d.year, d.mon, d.mday, d.hour, d.min, d.sec)
+ assert_in_delta(t, t2, t - z + 2)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/date/test_date_parse.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/date/test_date_parse.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/date/test_date_parse.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,985 @@
+require 'test/unit'
+require 'date'
+
+class TestDateParse < Test::Unit::TestCase
+
+ def test__parse
+ [
+ # ctime(3), asctime(3)
+ [['Sat Aug 28 02:55:50 1999',false],[1999,8,28,2,55,50,nil,nil,6]],
+ [['Sat Aug 28 02:55:50 02',false],[2,8,28,2,55,50,nil,nil,6]],
+ [['Sat Aug 28 02:55:50 02',true],[2002,8,28,2,55,50,nil,nil,6]],
+ [['Sat Aug 28 02:55:50 0002',false],[2,8,28,2,55,50,nil,nil,6]],
+ [['Sat Aug 28 02:55:50 0002',true],[2,8,28,2,55,50,nil,nil,6]],
+
+ # date(1)
+ [['Sat Aug 28 02:29:34 JST 1999',false],[1999,8,28,2,29,34,'JST',9*3600,6]],
+ [['Sat Aug 28 02:29:34 MET DST 1999',false],[1999,8,28,2,29,34,'MET DST',2*3600,6]],
+ [['Sat Aug 28 02:29:34 AMT 1999',false],[1999,8,28,2,29,34,'AMT',nil,6]],
+ [['Sat Aug 28 02:29:34 PMT 1999',false],[1999,8,28,2,29,34,'PMT',nil,6]],
+ [['Sat Aug 28 02:29:34 PMT -1999',false],[-1999,8,28,2,29,34,'PMT',nil,6]],
+
+ [['Sat Aug 28 02:29:34 JST 02',false],[2,8,28,2,29,34,'JST',9*3600,6]],
+ [['Sat Aug 28 02:29:34 JST 02',true],[2002,8,28,2,29,34,'JST',9*3600,6]],
+ [['Sat Aug 28 02:29:34 JST 0002',false],[2,8,28,2,29,34,'JST',9*3600,6]],
+ [['Sat Aug 28 02:29:34 JST 0002',true],[2,8,28,2,29,34,'JST',9*3600,6]],
+
+ [['Sat Aug 28 02:29:34 GMT+09 0002',false],[2,8,28,2,29,34,'GMT+09',9*3600,6]],
+ [['Sat Aug 28 02:29:34 GMT+0900 0002',false],[2,8,28,2,29,34,'GMT+0900',9*3600,6]],
+ [['Sat Aug 28 02:29:34 GMT+09:00 0002',false],[2,8,28,2,29,34,'GMT+09:00',9*3600,6]],
+ [['Sat Aug 28 02:29:34 GMT-09 0002',false],[2,8,28,2,29,34,'GMT-09',-9*3600,6]],
+ [['Sat Aug 28 02:29:34 GMT-0900 0002',false],[2,8,28,2,29,34,'GMT-0900',-9*3600,6]],
+ [['Sat Aug 28 02:29:34 GMT-09:00 0002',false],[2,8,28,2,29,34,'GMT-09:00',-9*3600,6]],
+ [['Sat Aug 28 02:29:34 GMT-090102 0002',false],[2,8,28,2,29,34,'GMT-090102',-9*3600-60-2,6]],
+ [['Sat Aug 28 02:29:34 GMT-09:01:02 0002',false],[2,8,28,2,29,34,'GMT-09:01:02',-9*3600-60-2,6]],
+
+ [['Sat Aug 28 02:29:34 GMT Standard Time 2000',false],[2000,8,28,2,29,34,'GMT Standard Time',0*3600,6]],
+ [['Sat Aug 28 02:29:34 Mountain Standard Time 2000',false],[2000,8,28,2,29,34,'Mountain Standard Time',-7*3600,6]],
+ [['Sat Aug 28 02:29:34 Mountain Daylight Time 2000',false],[2000,8,28,2,29,34,'Mountain Daylight Time',-6*3600,6]],
+ [['Sat Aug 28 02:29:34 Mexico Standard Time 2000',false],[2000,8,28,2,29,34,'Mexico Standard Time',-6*3600,6]],
+# [['Sat Aug 28 02:29:34 Mexico Standard Time 2 2000',false],[2000,8,28,2,29,34,'Mexico Standard Time 2',-7*3600,6]], # cp
+ [['Sat Aug 28 02:29:34 E. Australia Standard Time 2000',false],[2000,8,28,2,29,34,'E. Australia Standard Time',10*3600,6]],
+
+ # part of iso 8601
+ [['1999-05-23 23:55:21',false],[1999,5,23,23,55,21,nil,nil,nil]],
+ [['1999-05-23 23:55:21+0900',false],[1999,5,23,23,55,21,'+0900',9*3600,nil]],
+ [['1999-05-23 23:55:21-0900',false],[1999,5,23,23,55,21,'-0900',-9*3600,nil]],
+ [['1999-05-23 23:55:21+09:00',false],[1999,5,23,23,55,21,'+09:00',9*3600,nil]],
+ [['1999-05-23T23:55:21-09:00',false],[1999,5,23,23,55,21,'-09:00',-9*3600,nil]],
+ [['1999-05-23 23:55:21Z',false],[1999,5,23,23,55,21,'Z',0,nil]],
+ [['1999-05-23T23:55:21Z',false],[1999,5,23,23,55,21,'Z',0,nil]],
+ [['-1999-05-23T23:55:21Z',false],[-1999,5,23,23,55,21,'Z',0,nil]],
+ [['-1999-05-23T23:55:21Z',true],[-1999,5,23,23,55,21,'Z',0,nil]],
+ [['19990523T23:55:21Z',false],[1999,5,23,23,55,21,'Z',0,nil]],
+
+ [['+011985-04-12',false],[11985,4,12,nil,nil,nil,nil,nil,nil]],
+ [['+011985-04-12T10:15:30',false],[11985,4,12,10,15,30,nil,nil,nil]],
+ [['-011985-04-12',false],[-11985,4,12,nil,nil,nil,nil,nil,nil]],
+ [['-011985-04-12T10:15:30',false],[-11985,4,12,10,15,30,nil,nil,nil]],
+
+ [['02-04-12',false],[2,4,12,nil,nil,nil,nil,nil,nil]],
+ [['02-04-12',true],[2002,4,12,nil,nil,nil,nil,nil,nil]],
+ [['0002-04-12',false],[2,4,12,nil,nil,nil,nil,nil,nil]],
+ [['0002-04-12',true],[2,4,12,nil,nil,nil,nil,nil,nil]],
+
+ [['19990523',true],[1999,5,23,nil,nil,nil,nil,nil,nil]],
+ [['-19990523',true],[-1999,5,23,nil,nil,nil,nil,nil,nil]],
+ [['990523',true],[1999,5,23,nil,nil,nil,nil,nil,nil]],
+ [['0523',false],[nil,5,23,nil,nil,nil,nil,nil,nil]],
+ [['23',false],[nil,nil,23,nil,nil,nil,nil,nil,nil]],
+
+ [['19990523 235521',true],[1999,5,23,23,55,21,nil,nil,nil]],
+ [['990523 235521',true],[1999,5,23,23,55,21,nil,nil,nil]],
+ [['0523 2355',false],[nil,5,23,23,55,nil,nil,nil,nil]],
+ [['23 2355',false],[nil,nil,23,23,55,nil,nil,nil,nil]],
+
+ [['19990523T235521',true],[1999,5,23,23,55,21,nil,nil,nil]],
+ [['990523T235521',true],[1999,5,23,23,55,21,nil,nil,nil]],
+ [['19990523T235521.99',true],[1999,5,23,23,55,21,nil,nil,nil]],
+ [['990523T235521.99',true],[1999,5,23,23,55,21,nil,nil,nil]],
+ [['0523T2355',false],[nil,5,23,23,55,nil,nil,nil,nil]],
+
+ [['19990523T235521+0900',true],[1999,5,23,23,55,21,'+0900',9*3600,nil]],
+ [['990523T235521-0900',true],[1999,5,23,23,55,21,'-0900',-9*3600,nil]],
+ [['19990523T235521.99+0900',true],[1999,5,23,23,55,21,'+0900',9*3600,nil]],
+ [['990523T235521.99-0900',true],[1999,5,23,23,55,21,'-0900',-9*3600,nil]],
+ [['0523T2355Z',false],[nil,5,23,23,55,nil,'Z',0,nil]],
+
+ [['19990523235521.123456+0900',true],[1999,5,23,23,55,21,'+0900',9*3600,nil]],
+ [['19990523235521.123456-0900',true],[1999,5,23,23,55,21,'-0900',-9*3600,nil]],
+ [['19990523235521,123456+0900',true],[1999,5,23,23,55,21,'+0900',9*3600,nil]],
+ [['19990523235521,123456-0900',true],[1999,5,23,23,55,21,'-0900',-9*3600,nil]],
+
+ [['990523235521,123456-0900',false],[99,5,23,23,55,21,'-0900',-9*3600,nil]],
+ [['0523235521,123456-0900',false],[nil,5,23,23,55,21,'-0900',-9*3600,nil]],
+ [['23235521,123456-0900',false],[nil,nil,23,23,55,21,'-0900',-9*3600,nil]],
+ [['235521,123456-0900',false],[nil,nil,nil,23,55,21,'-0900',-9*3600,nil]],
+ [['5521,123456-0900',false],[nil,nil,nil,nil,55,21,'-0900',-9*3600,nil]],
+ [['21,123456-0900',false],[nil,nil,nil,nil,nil,21,'-0900',-9*3600,nil]],
+
+ [['3235521,123456-0900',false],[nil,nil,3,23,55,21,'-0900',-9*3600,nil]],
+ [['35521,123456-0900',false],[nil,nil,nil,3,55,21,'-0900',-9*3600,nil]],
+ [['521,123456-0900',false],[nil,nil,nil,nil,5,21,'-0900',-9*3600,nil]],
+
+ # reversed iso 8601 (?)
+ [['23-05-1999',false],[1999,5,23,nil,nil,nil,nil,nil,nil]],
+ [['23-05-1999 23:55:21',false],[1999,5,23,23,55,21,nil,nil,nil]],
+ [['23-05--1999 23:55:21',false],[-1999,5,23,23,55,21,nil,nil,nil]],
+ [["23-05-'99",false],[99,5,23,nil,nil,nil,nil,nil,nil]],
+ [["23-05-'99",true],[1999,5,23,nil,nil,nil,nil,nil,nil]],
+
+ # broken iso 8601 (?)
+# [['1999-05-23T235521Z',false],[1999,5,23,23,55,21,'Z',0,nil]], # cp
+ [['19990523T23:55:21Z',false],[1999,5,23,23,55,21,'Z',0,nil]],
+ [['19990523235521.1234-100',true],[1999,5,23,23,55,21,'-100',-1*3600,nil]],
+ [['19990523235521.1234-10',true],[1999,5,23,23,55,21,'-10',-10*3600,nil]],
+
+ # part of jis x0301
+ [['M11.05.23',false],[1878,5,23,nil,nil,nil,nil,nil,nil]],
+ [['T11.05.23 23:55:21+0900',false],[1922,5,23,23,55,21,'+0900',9*3600,nil]],
+ [['S11.05.23 23:55:21-0900',false],[1936,5,23,23,55,21,'-0900',-9*3600,nil]],
+ [['S40.05.23 23:55:21+09:00',false],[1965,5,23,23,55,21,'+09:00',9*3600,nil]],
+ [['S40.05.23T23:55:21-09:00',false],[1965,5,23,23,55,21,'-09:00',-9*3600,nil]],
+ [['H11.05.23 23:55:21Z',false],[1999,5,23,23,55,21,'Z',0,nil]],
+ [['H11.05.23T23:55:21Z',false],[1999,5,23,23,55,21,'Z',0,nil]],
+
+ # ofx date
+ [['19990523235521',false],[1999,5,23,23,55,21,nil,nil,nil]],
+ [['19990523235521.123',false],[1999,5,23,23,55,21,nil,nil,nil]],
+ [['19990523235521.123[-9]',false],[1999,5,23,23,55,21,'-9',-(9*3600),nil]],
+ [['19990523235521.123[+9]',false],[1999,5,23,23,55,21,'+9',+(9*3600),nil]],
+ [['19990523235521.123[9]',false],[1999,5,23,23,55,21,'9',+(9*3600),nil]],
+ [['19990523235521.123[-9.50]',false],[1999,5,23,23,55,21,'-9.50',-(9*3600+30*60),nil]],
+ [['19990523235521.123[+9.50]',false],[1999,5,23,23,55,21,'+9.50',+(9*3600+30*60),nil]],
+ [['19990523235521.123[-5:EST]',false],[1999,5,23,23,55,21,'EST',-5*3600,nil]],
+ [['19990523235521.123[+9:JST]',false],[1999,5,23,23,55,21,'JST',9*3600,nil]],
+ [['19990523235521.123[+12:XXX YYY ZZZ]',false],[1999,5,23,23,55,21,'XXX YYY ZZZ',12*3600,nil]],
+# [['235521',false],[nil,nil,nil,23,55,21,nil,nil,nil]], # cp
+ [['235521.123',false],[nil,nil,nil,23,55,21,nil,nil,nil]],
+ [['235521.123[-9]',false],[nil,nil,nil,23,55,21,'-9',-9*3600,nil]],
+ [['235521.123[+9]',false],[nil,nil,nil,23,55,21,'+9',+9*3600,nil]],
+ [['235521.123[-5:EST]',false],[nil,nil,nil,23,55,21,'EST',-5*3600,nil]],
+ [['235521.123[+9:JST]',false],[nil,nil,nil,23,55,21,'JST',+9*3600,nil]],
+
+ # rfc 2822
+ [['Sun, 22 Aug 1999 00:45:29 -0400',false],[1999,8,22,0,45,29,'-0400',-4*3600,0]],
+ [['Sun, 22 Aug 1999 00:45:29 -9959',false],[1999,8,22,0,45,29,'-9959',-(99*3600+59*60),0]],
+ [['Sun, 22 Aug 1999 00:45:29 +9959',false],[1999,8,22,0,45,29,'+9959',+(99*3600+59*60),0]],
+ [['Sun, 22 Aug 05 00:45:29 -0400',true],[2005,8,22,0,45,29,'-0400',-4*3600,0]],
+ [['Sun, 22 Aug 49 00:45:29 -0400',true],[2049,8,22,0,45,29,'-0400',-4*3600,0]],
+# [['Sun, 22 Aug 50 00:45:29 -0400',true],[1950,8,22,0,45,29,'-0400',-4*3600,0]],
+# [['Sun, 22 Aug 111 00:45:29 -0400',true],[2011,8,22,0,45,29,'-0400',-4*3600,0]],
+ [['Sun, 22 Aug 1999 00:45:29 GMT',false],[1999,8,22,0,45,29,'GMT',0,0]],
+ [["Sun,\00022\r\nAug\r\n1999\r\n00:45:29\r\nGMT",false],[1999,8,22,0,45,29,'GMT',0,0]],
+ [['Sun, 22 Aug 1999 00:45 GMT',false],[1999,8,22,0,45,nil,'GMT',0,0]],
+ [['Sun, 22 Aug -1999 00:45 GMT',false],[-1999,8,22,0,45,nil,'GMT',0,0]],
+ [['Sun, 22 Aug 99 00:45:29 UT',true],[1999,8,22,0,45,29,'UT',0,0]],
+ [['Sun, 22 Aug 0099 00:45:29 UT',true],[99,8,22,0,45,29,'UT',0,0]],
+
+ # rfc 850, obsoleted by rfc 1036
+ [['Tuesday, 02-Mar-99 11:20:32 GMT',true],[1999,3,2,11,20,32,'GMT',0,2]],
+
+ # W3C Working Draft - XForms - 4.8 Time
+ [['2000-01-31 13:20:00-5',false],[2000,1,31,13,20,0,'-5',-5*3600,nil]],
+
+ # [-+]\d+.\d+
+ [['2000-01-31 13:20:00-5.5',false],[2000,1,31,13,20,0,'-5.5',-5*3600-30*60,nil]],
+ [['2000-01-31 13:20:00-5,5',false],[2000,1,31,13,20,0,'-5,5',-5*3600-30*60,nil]],
+ [['2000-01-31 13:20:00+3.5',false],[2000,1,31,13,20,0,'+3.5',3*3600+30*60,nil]],
+ [['2000-01-31 13:20:00+3,5',false],[2000,1,31,13,20,0,'+3,5',3*3600+30*60,nil]],
+
+ # mil
+ [['2000-01-31 13:20:00 Z',false],[2000,1,31,13,20,0,'Z',0*3600,nil]],
+ [['2000-01-31 13:20:00 H',false],[2000,1,31,13,20,0,'H',8*3600,nil]],
+ [['2000-01-31 13:20:00 M',false],[2000,1,31,13,20,0,'M',12*3600,nil]],
+ [['2000-01-31 13:20 M',false],[2000,1,31,13,20,nil,'M',12*3600,nil]],
+ [['2000-01-31 13:20:00 S',false],[2000,1,31,13,20,0,'S',-6*3600,nil]],
+ [['2000-01-31 13:20:00 A',false],[2000,1,31,13,20,0,'A',1*3600,nil]],
+ [['2000-01-31 13:20:00 P',false],[2000,1,31,13,20,0,'P',-3*3600,nil]],
+
+ # dot
+ [['1999.5.2',false],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+ [['1999.05.02',false],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+ [['-1999.05.02',false],[-1999,5,2,nil,nil,nil,nil,nil,nil]],
+# [['05.02',false],[nil,5,2,nil,nil,nil,nil,nil,nil]], # not support
+# [[' 5. 2',false],[nil,5,2,nil,nil,nil,nil,nil,nil]], # not support
+
+ [['0099.5.2',false],[99,5,2,nil,nil,nil,nil,nil,nil]],
+ [['0099.5.2',true],[99,5,2,nil,nil,nil,nil,nil,nil]],
+
+ [["'99.5.2",false],[99,5,2,nil,nil,nil,nil,nil,nil]],
+ [["'99.5.2",true],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+
+ # reversed dot
+ [['2.5.1999',false],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+ [['02.05.1999',false],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+ [['02.05.-1999',false],[-1999,5,2,nil,nil,nil,nil,nil,nil]],
+
+ [['2.5.0099',false],[99,5,2,nil,nil,nil,nil,nil,nil]],
+ [['2.5.0099',true],[99,5,2,nil,nil,nil,nil,nil,nil]],
+
+ [["2.5.'99",false],[99,5,2,nil,nil,nil,nil,nil,nil]],
+ [["2.5.'99",true],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+
+ # vms
+ [['08-DEC-1988',false],[1988,12,8,nil,nil,nil,nil,nil,nil]],
+ [['31-JAN-1999',false],[1999,1,31,nil,nil,nil,nil,nil,nil]],
+ [['31-JAN--1999',false],[-1999,1,31,nil,nil,nil,nil,nil,nil]],
+
+ [['08-DEC-88',false],[88,12,8,nil,nil,nil,nil,nil,nil]],
+ [['08-DEC-88',true],[1988,12,8,nil,nil,nil,nil,nil,nil]],
+ [['08-DEC-0088',false],[88,12,8,nil,nil,nil,nil,nil,nil]],
+ [['08-DEC-0088',true],[88,12,8,nil,nil,nil,nil,nil,nil]],
+
+ # swaped vms
+ [['DEC-08-1988',false],[1988,12,8,nil,nil,nil,nil,nil,nil]],
+ [['JAN-31-1999',false],[1999,1,31,nil,nil,nil,nil,nil,nil]],
+ [['JAN-31--1999',false],[-1999,1,31,nil,nil,nil,nil,nil,nil]],
+ [['JAN-1999',false],[1999,1,nil,nil,nil,nil,nil,nil,nil]],
+ [['JAN--1999',false],[-1999,1,nil,nil,nil,nil,nil,nil,nil]],
+
+ # reversed vms
+ [['1988-DEC-08',false],[1988,12,8,nil,nil,nil,nil,nil,nil]],
+ [['1999-JAN-31',false],[1999,1,31,nil,nil,nil,nil,nil,nil]],
+ [['-1999-JAN-31',false],[-1999,1,31,nil,nil,nil,nil,nil,nil]],
+
+ [['0088-DEC-08',false],[88,12,8,nil,nil,nil,nil,nil,nil]],
+ [['0088-DEC-08',true],[88,12,8,nil,nil,nil,nil,nil,nil]],
+
+ [["'88/12/8",false],[88,12,8,nil,nil,nil,nil,nil,nil]],
+ [["'88/12/8",true],[1988,12,8,nil,nil,nil,nil,nil,nil]],
+
+ # non-spaced eu
+ [['08/dec/1988',false],[1988,12,8,nil,nil,nil,nil,nil,nil]],
+ [['31/jan/1999',false],[1999,1,31,nil,nil,nil,nil,nil,nil]],
+ [['31/jan/-1999',false],[-1999,1,31,nil,nil,nil,nil,nil,nil]],
+ [['08.dec.1988',false],[1988,12,8,nil,nil,nil,nil,nil,nil]],
+ [['31.jan.1999',false],[1999,1,31,nil,nil,nil,nil,nil,nil]],
+ [['31.jan.-1999',false],[-1999,1,31,nil,nil,nil,nil,nil,nil]],
+
+ # non-spaced us
+ [['dec/08/1988',false],[1988,12,8,nil,nil,nil,nil,nil,nil]],
+ [['jan/31/1999',false],[1999,1,31,nil,nil,nil,nil,nil,nil]],
+ [['jan/31/-1999',false],[-1999,1,31,nil,nil,nil,nil,nil,nil]],
+ [['jan/31',false],[nil,1,31,nil,nil,nil,nil,nil,nil]],
+ [['jan/1988',false],[1988,1,nil,nil,nil,nil,nil,nil,nil]],
+ [['dec.08.1988',false],[1988,12,8,nil,nil,nil,nil,nil,nil]],
+ [['jan.31.1999',false],[1999,1,31,nil,nil,nil,nil,nil,nil]],
+ [['jan.31.-1999',false],[-1999,1,31,nil,nil,nil,nil,nil,nil]],
+ [['jan.31',false],[nil,1,31,nil,nil,nil,nil,nil,nil]],
+ [['jan.1988',false],[1988,1,nil,nil,nil,nil,nil,nil,nil]],
+
+ # month and day of month
+ [['Jan 1',false],[nil,1,1,nil,nil,nil,nil,nil,nil]],
+ [['Jul 11',false],[nil,7,11,nil,nil,nil,nil,nil,nil]],
+ [['July 11',false],[nil,7,11,nil,nil,nil,nil,nil,nil]],
+ [['Sept 23',false],[nil,9,23,nil,nil,nil,nil,nil,nil]],
+ [['Sep. 23',false],[nil,9,23,nil,nil,nil,nil,nil,nil]],
+ [['Sept. 23',false],[nil,9,23,nil,nil,nil,nil,nil,nil]],
+ [['September 23',false],[nil,9,23,nil,nil,nil,nil,nil,nil]],
+ [['October 1st',false],[nil,10,1,nil,nil,nil,nil,nil,nil]],
+ [['October 23rd',false],[nil,10,23,nil,nil,nil,nil,nil,nil]],
+ [['October 25th 1999',false],[1999,10,25,nil,nil,nil,nil,nil,nil]],
+ [['October 25th -1999',false],[-1999,10,25,nil,nil,nil,nil,nil,nil]],
+ [['october 25th 1999',false],[1999,10,25,nil,nil,nil,nil,nil,nil]],
+ [['OCTOBER 25th 1999',false],[1999,10,25,nil,nil,nil,nil,nil,nil]],
+ [['oCtoBer 25th 1999',false],[1999,10,25,nil,nil,nil,nil,nil,nil]],
+ [['aSep 23',false],[nil,nil,23,nil,nil,nil,nil,nil,nil]],
+
+ # month and year
+ [['Sept 1990',false],[1990,9,nil,nil,nil,nil,nil,nil,nil]],
+ [["Sept '90",false],[90,9,nil,nil,nil,nil,nil,nil,nil]],
+ [["Sept '90",true],[1990,9,nil,nil,nil,nil,nil,nil,nil]],
+ [['1990/09',false],[1990,9,nil,nil,nil,nil,nil,nil,nil]],
+ [['09/1990',false],[1990,9,nil,nil,nil,nil,nil,nil,nil]],
+ [["aSep '90",false],[90,nil,nil,nil,nil,nil,nil,nil,nil]],
+
+ # year
+ [["'90",false],[90,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [["'90",true],[1990,nil,nil,nil,nil,nil,nil,nil,nil]],
+
+ # month
+ [['Jun',false],[nil,6,nil,nil,nil,nil,nil,nil,nil]],
+ [['June',false],[nil,6,nil,nil,nil,nil,nil,nil,nil]],
+ [['Sep',false],[nil,9,nil,nil,nil,nil,nil,nil,nil]],
+ [['Sept',false],[nil,9,nil,nil,nil,nil,nil,nil,nil]],
+ [['September',false],[nil,9,nil,nil,nil,nil,nil,nil,nil]],
+ [['aSep',false],[nil,nil,nil,nil,nil,nil,nil,nil,nil]],
+
+ # day of month
+ [['1st',false],[nil,nil,1,nil,nil,nil,nil,nil,nil]],
+ [['2nd',false],[nil,nil,2,nil,nil,nil,nil,nil,nil]],
+ [['3rd',false],[nil,nil,3,nil,nil,nil,nil,nil,nil]],
+ [['4th',false],[nil,nil,4,nil,nil,nil,nil,nil,nil]],
+ [['29th',false],[nil,nil,29,nil,nil,nil,nil,nil,nil]],
+ [['31st',false],[nil,nil,31,nil,nil,nil,nil,nil,nil]],
+ [['1sta',false],[nil,nil,nil,nil,nil,nil,nil,nil,nil]],
+
+ # era
+ [['Sat Aug 28 02:29:34 GMT CE 2000',false],[2000,8,28,2,29,34,'GMT',0,6]],
+ [['Sat Aug 28 02:29:34 GMT C.E. 2000',false],[2000,8,28,2,29,34,'GMT',0,6]],
+ [['Sat Aug 28 02:29:34 GMT BCE 2000',false],[-1999,8,28,2,29,34,'GMT',0,6]],
+ [['Sat Aug 28 02:29:34 GMT B.C.E. 2000',false],[-1999,8,28,2,29,34,'GMT',0,6]],
+ [['Sat Aug 28 02:29:34 GMT AD 2000',false],[2000,8,28,2,29,34,'GMT',0,6]],
+ [['Sat Aug 28 02:29:34 GMT A.D. 2000',false],[2000,8,28,2,29,34,'GMT',0,6]],
+ [['Sat Aug 28 02:29:34 GMT BC 2000',false],[-1999,8,28,2,29,34,'GMT',0,6]],
+ [['Sat Aug 28 02:29:34 GMT B.C. 2000',false],[-1999,8,28,2,29,34,'GMT',0,6]],
+ [['Sat Aug 28 02:29:34 GMT 2000 BC',false],[-1999,8,28,2,29,34,'GMT',0,6]],
+ [['Sat Aug 28 02:29:34 GMT 2000 BCE',false],[-1999,8,28,2,29,34,'GMT',0,6]],
+ [['Sat Aug 28 02:29:34 GMT 2000 B.C.',false],[-1999,8,28,2,29,34,'GMT',0,6]],
+ [['Sat Aug 28 02:29:34 GMT 2000 B.C.E.',false],[-1999,8,28,2,29,34,'GMT',0,6]],
+
+ # collection
+# [['le ler juillet 1982',false],[1982,7,1,nil,nil,nil,nil,nil,nil]], # bih 1982
+# [['30 June 1982 , 23h 59m 59s',false],[1982,6,30,23,59,59,nil,nil,nil]], # bih 1982
+ [['Tuesday, May 18, 1999 Published at 13:36 GMT 14:36 UK',false],[1999,5,18,13,36,nil,'GMT',0,2]], # bbc.co.uk
+ [['July 20, 2000 Web posted at: 3:37 p.m. EDT (1937 GMT)',false],[2000,7,20,15,37,nil,'EDT',-4*3600,nil]], # cnn.com
+ [['12:54 p.m. EDT, September 11, 2006',false],[2006,9,11,12,54,nil,'EDT',-4*3600,nil]], # cnn.com
+ [['February 04, 2001 at 10:59 AM PST',false],[2001,2,4,10,59,nil,'PST',-8*3600,nil]], # old amazon.com
+ [['Monday May 08, @01:55PM',false],[nil,5,8,13,55,nil,nil,nil,1]], # slashdot.org
+ [['06.June 2005',false],[2005,6,6,nil,nil,nil,nil,nil,nil]], # dhl.com
+
+ # etc.
+ [['8:00 pm lt',false],[nil,nil,nil,20,0,nil,'lt',nil,nil]],
+ [['4:00 AM, Jan. 12, 1990',false],[1990,1,12,4,0,nil,nil,nil,nil]],
+ [['Jan. 12 4:00 AM 1990',false],[1990,1,12,4,0,nil,nil,nil,nil]],
+# [['Jan. 12 4:00 -1990',false],[-1990,1,12,4,0,nil,nil,nil,nil]], # cp
+ [['1990-01-12 04:00:00+00',false],[1990,1,12,4,0,0,'+00',0,nil]],
+ [['1990-01-11 20:00:00-08',false],[1990,1,11,20,0,0,'-08',-8*3600,nil]],
+ [['1990/01/12 04:00:00',false],[1990,1,12,4,0,0,nil,nil,nil]],
+# [['Thu Jan 11 20:00:00 1990 LT',false], [1990,1,11,20,0,0,'LT',nil,4]], # cp
+ [['Thu Jan 11 20:00:00 PST 1990',false],[1990,1,11,20,0,0,'PST',-8*3600,4]],
+ [['Fri Jan 12 04:00:00 GMT 1990',false],[1990,1,12,4,0,0,'GMT',0,5]],
+ [['Thu, 11 Jan 1990 20:00:00 -0800',false],[1990,1,11,20,0,0,'-0800',-8*3600,4]],
+ [['12-January-1990, 04:00 WET',false],[1990,1,12,4,0,nil,'WET',0*3600,nil]],
+ [['jan 2 3 am +4 5',false],[5,1,2,3,nil,nil,'+4',4*3600,nil]],
+ [['jan 2 3 am +4 5',true],[2005,1,2,3,nil,nil,'+4',4*3600,nil]],
+ [['fri1feb3bc4pm+5',false],[-2,2,1,16,nil,nil,'+5',5*3600,5]],
+ [['fri1feb3bc4pm+5',true],[-2,2,1,16,nil,nil,'+5',5*3600,5]],
+ [['03 feb 1st',false],[03,2,1,nil,nil,nil,nil,nil,nil]],
+
+ # apostrophe
+ [["July 4, '79",true],[1979,7,4,nil,nil,nil,nil,nil,nil]],
+ [["4th July '79",true],[1979,7,4,nil,nil,nil,nil,nil,nil]],
+
+ # day of week
+ [['Sunday',false],[nil,nil,nil,nil,nil,nil,nil,nil,0]],
+ [['Mon',false],[nil,nil,nil,nil,nil,nil,nil,nil,1]],
+ [['Tue',false],[nil,nil,nil,nil,nil,nil,nil,nil,2]],
+ [['Wed',false],[nil,nil,nil,nil,nil,nil,nil,nil,3]],
+ [['Thurs',false],[nil,nil,nil,nil,nil,nil,nil,nil,4]],
+ [['Friday',false],[nil,nil,nil,nil,nil,nil,nil,nil,5]],
+ [['Sat.',false],[nil,nil,nil,nil,nil,nil,nil,nil,6]],
+ [['sat.',false],[nil,nil,nil,nil,nil,nil,nil,nil,6]],
+ [['SAT.',false],[nil,nil,nil,nil,nil,nil,nil,nil,6]],
+ [['sAt.',false],[nil,nil,nil,nil,nil,nil,nil,nil,6]],
+# [['su',false],[nil,nil,nil,nil,nil,nil,nil,nil,0]],
+# [['mo',false],[nil,nil,nil,nil,nil,nil,nil,nil,1]],
+
+ # time
+ [['09:55',false],[nil,nil,nil,9,55,nil,nil,nil,nil]],
+ [['09:55:30',false],[nil,nil,nil,9,55,30,nil,nil,nil]],
+ [['09:55:30am',false],[nil,nil,nil,9,55,30,nil,nil,nil]],
+ [['09:55:30pm',false],[nil,nil,nil,21,55,30,nil,nil,nil]],
+ [['09:55:30a.m.',false],[nil,nil,nil,9,55,30,nil,nil,nil]],
+ [['09:55:30p.m.',false],[nil,nil,nil,21,55,30,nil,nil,nil]],
+ [['09:55:30pm GMT',false],[nil,nil,nil,21,55,30,'GMT',0,nil]],
+ [['09:55:30p.m. GMT',false],[nil,nil,nil,21,55,30,'GMT',0,nil]],
+ [['09:55+0900',false],[nil,nil,nil,9,55,nil,'+0900',9*3600,nil]],
+ [['09 AM',false],[nil,nil,nil,9,nil,nil,nil,nil,nil]],
+ [['09am',false],[nil,nil,nil,9,nil,nil,nil,nil,nil]],
+ [['09 A.M.',false],[nil,nil,nil,9,nil,nil,nil,nil,nil]],
+ [['09 PM',false],[nil,nil,nil,21,nil,nil,nil,nil,nil]],
+ [['09pm',false],[nil,nil,nil,21,nil,nil,nil,nil,nil]],
+ [['09 P.M.',false],[nil,nil,nil,21,nil,nil,nil,nil,nil]],
+
+ [['9h22m23s',false],[nil,nil,nil,9,22,23,nil,nil,nil]],
+ [['9h 22m 23s',false],[nil,nil,nil,9,22,23,nil,nil,nil]],
+ [['9h22m',false],[nil,nil,nil,9,22,nil,nil,nil,nil]],
+ [['9h 22m',false],[nil,nil,nil,9,22,nil,nil,nil,nil]],
+ [['9h',false],[nil,nil,nil,9,nil,nil,nil,nil,nil]],
+ [['9h 22m 23s am',false],[nil,nil,nil,9,22,23,nil,nil,nil]],
+ [['9h 22m 23s pm',false],[nil,nil,nil,21,22,23,nil,nil,nil]],
+ [['9h 22m am',false],[nil,nil,nil,9,22,nil,nil,nil,nil]],
+ [['9h 22m pm',false],[nil,nil,nil,21,22,nil,nil,nil,nil]],
+ [['9h am',false],[nil,nil,nil,9,nil,nil,nil,nil,nil]],
+ [['9h pm',false],[nil,nil,nil,21,nil,nil,nil,nil,nil]],
+
+ [['00:00',false],[nil,nil,nil,0,0,nil,nil,nil,nil]],
+ [['01:00',false],[nil,nil,nil,1,0,nil,nil,nil,nil]],
+ [['11:00',false],[nil,nil,nil,11,0,nil,nil,nil,nil]],
+ [['12:00',false],[nil,nil,nil,12,0,nil,nil,nil,nil]],
+ [['13:00',false],[nil,nil,nil,13,0,nil,nil,nil,nil]],
+ [['23:00',false],[nil,nil,nil,23,0,nil,nil,nil,nil]],
+ [['24:00',false],[nil,nil,nil,24,0,nil,nil,nil,nil]],
+
+ [['00:00 AM',false],[nil,nil,nil,0,0,nil,nil,nil,nil]],
+ [['12:00 AM',false],[nil,nil,nil,0,0,nil,nil,nil,nil]],
+ [['01:00 AM',false],[nil,nil,nil,1,0,nil,nil,nil,nil]],
+ [['11:00 AM',false],[nil,nil,nil,11,0,nil,nil,nil,nil]],
+ [['00:00 PM',false],[nil,nil,nil,12,0,nil,nil,nil,nil]],
+ [['12:00 PM',false],[nil,nil,nil,12,0,nil,nil,nil,nil]],
+ [['01:00 PM',false],[nil,nil,nil,13,0,nil,nil,nil,nil]],
+ [['11:00 PM',false],[nil,nil,nil,23,0,nil,nil,nil,nil]],
+
+ # pick up the rest
+ [['2000-01-02 1',false],[2000,1,2,1,nil,nil,nil,nil,nil]],
+ [['2000-01-02 23',false],[2000,1,2,23,nil,nil,nil,nil,nil]],
+ [['2000-01-02 24',false],[2000,1,2,24,nil,nil,nil,nil,nil]],
+ [['1 03:04:05',false],[nil,nil,1,3,4,5,nil,nil,nil]],
+ [['02 03:04:05',false],[nil,nil,2,3,4,5,nil,nil,nil]],
+ [['31 03:04:05',false],[nil,nil,31,3,4,5,nil,nil,nil]],
+
+ # null, space
+ [['',false],[nil,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [["\s",false],[nil,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [["\s" * 10, true],[nil,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [["\t",false],[nil,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [["\n",false],[nil,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [["\v",false],[nil,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [["\f",false],[nil,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [["\r",false],[nil,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [["\t\n\v\f\r\s",false],[nil,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [["1999-05-23\t\n\v\f\r\s21:34:56",false],[1999,5,23,21,34,56,nil,nil,nil]],
+ [["1999-05-23\n\n\n\n\n\n21:34:56",false],[1999,5,23,21,34,56,nil,nil,nil]],
+ ].each do |x,y|
+ h = Date._parse(*x)
+ a = h.values_at(:year,:mon,:mday,:hour,:min,:sec,:zone,:offset,:wday)
+ if y[1] == -1
+ a[1] = -1
+ a[2] = h[:yday]
+ end
+ assert_equal(y, a, [x, y, a].inspect)
+ end
+ end
+
+ def test__parse_slash_exp
+ [
+ # little
+ [['2/5/1999',false],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+ [['02/05/1999',false],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+ [['02/05/-1999',false],[-1999,5,2,nil,nil,nil,nil,nil,nil]],
+ [['05/02',false],[nil,5,2,nil,nil,nil,nil,nil,nil]],
+ [[' 5/ 2',false],[nil,5,2,nil,nil,nil,nil,nil,nil]],
+
+ [["2/5/'99",true],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+ [['2/5/0099',false],[99,5,2,nil,nil,nil,nil,nil,nil]],
+ [['2/5/0099',true],[99,5,2,nil,nil,nil,nil,nil,nil]],
+
+ [['2/5 1999',false],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+ [['2/5-1999',false],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+ [['2/5--1999',false],[-1999,5,2,nil,nil,nil,nil,nil,nil]],
+
+ # big
+ [['99/5/2',false],[99,5,2,nil,nil,nil,nil,nil,nil]],
+ [['99/5/2',true],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+
+ [['1999/5/2',false],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+ [['1999/05/02',false],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+ [['-1999/05/02',false],[-1999,5,2,nil,nil,nil,nil,nil,nil]],
+
+ [['0099/5/2',false],[99,5,2,nil,nil,nil,nil,nil,nil]],
+ [['0099/5/2',true],[99,5,2,nil,nil,nil,nil,nil,nil]],
+
+ [["'99/5/2",false],[99,5,2,nil,nil,nil,nil,nil,nil]],
+ [["'99/5/2",true],[1999,5,2,nil,nil,nil,nil,nil,nil]],
+ ].each do |x,y|
+ h = Date._parse(*x)
+ a = h.values_at(:year,:mon,:mday,:hour,:min,:sec,:zone,:offset,:wday)
+ if y[1] == -1
+ a[1] = -1
+ a[2] = h[:yday]
+ end
+ assert_equal(y, a, [x, y, a].inspect)
+ end
+ end
+
+ def test__parse__2
+ h = Date._parse('22:45:59.5')
+ assert_equal([22, 45, 59, 5.to_r/10**1], h.values_at(:hour, :min, :sec, :sec_fraction))
+ h = Date._parse('22:45:59.05')
+ assert_equal([22, 45, 59, 5.to_r/10**2], h.values_at(:hour, :min, :sec, :sec_fraction))
+ h = Date._parse('22:45:59.005')
+ assert_equal([22, 45, 59, 5.to_r/10**3], h.values_at(:hour, :min, :sec, :sec_fraction))
+ h = Date._parse('22:45:59.0123')
+ assert_equal([22, 45, 59, 123.to_r/10**4], h.values_at(:hour, :min, :sec, :sec_fraction))
+
+ h = Date._parse('224559.5')
+ assert_equal([22, 45, 59, 5.to_r/10**1], h.values_at(:hour, :min, :sec, :sec_fraction))
+ h = Date._parse('224559.05')
+ assert_equal([22, 45, 59, 5.to_r/10**2], h.values_at(:hour, :min, :sec, :sec_fraction))
+ h = Date._parse('224559.005')
+ assert_equal([22, 45, 59, 5.to_r/10**3], h.values_at(:hour, :min, :sec, :sec_fraction))
+ h = Date._parse('224559.0123')
+ assert_equal([22, 45, 59, 123.to_r/10**4], h.values_at(:hour, :min, :sec, :sec_fraction))
+
+ h = Date._parse('2006-w15-5')
+ assert_equal([2006, 15, 5], h.values_at(:cwyear, :cweek, :cwday))
+ h = Date._parse('2006w155')
+ assert_equal([2006, 15, 5], h.values_at(:cwyear, :cweek, :cwday))
+ h = Date._parse('06w155', false)
+ assert_equal([6, 15, 5], h.values_at(:cwyear, :cweek, :cwday))
+ h = Date._parse('06w155', true)
+ assert_equal([2006, 15, 5], h.values_at(:cwyear, :cweek, :cwday))
+
+ h = Date._parse('2006-w15')
+ assert_equal([2006, 15, nil], h.values_at(:cwyear, :cweek, :cwday))
+ h = Date._parse('2006w15')
+ assert_equal([2006, 15, nil], h.values_at(:cwyear, :cweek, :cwday))
+
+ h = Date._parse('-w15-5')
+ assert_equal([nil, 15, 5], h.values_at(:cwyear, :cweek, :cwday))
+ h = Date._parse('-w155')
+ assert_equal([nil, 15, 5], h.values_at(:cwyear, :cweek, :cwday))
+
+ h = Date._parse('-w15')
+ assert_equal([nil, 15, nil], h.values_at(:cwyear, :cweek, :cwday))
+ h = Date._parse('-w15')
+ assert_equal([nil, 15, nil], h.values_at(:cwyear, :cweek, :cwday))
+
+ h = Date._parse('-w-5')
+ assert_equal([nil, nil, 5], h.values_at(:cwyear, :cweek, :cwday))
+
+ h = Date._parse('--11-29')
+ assert_equal([nil, 11, 29], h.values_at(:year, :mon, :mday))
+ h = Date._parse('--1129')
+ assert_equal([nil, 11, 29], h.values_at(:year, :mon, :mday))
+ h = Date._parse('--11')
+ assert_equal([nil, 11, nil], h.values_at(:year, :mon, :mday))
+ h = Date._parse('---29')
+ assert_equal([nil, nil, 29], h.values_at(:year, :mon, :mday))
+ h = Date._parse('-333')
+ assert_equal([nil, 333], h.values_at(:year, :yday))
+
+ h = Date._parse('2006-333')
+ assert_equal([2006, 333], h.values_at(:year, :yday))
+ h = Date._parse('2006333')
+ assert_equal([2006, 333], h.values_at(:year, :yday))
+ h = Date._parse('06333', false)
+ assert_equal([6, 333], h.values_at(:year, :yday))
+ h = Date._parse('06333', true)
+ assert_equal([2006, 333], h.values_at(:year, :yday))
+ h = Date._parse('333')
+ assert_equal([nil, 333], h.values_at(:year, :yday))
+ end
+
+ def test_parse
+ assert_equal(Date.new, Date.parse)
+ assert_equal(Date.new(2002,3,14), Date.parse('2002-03-14'))
+
+ assert_equal(DateTime.new(2002,3,14,11,22,33, 0),
+ DateTime.parse('2002-03-14T11:22:33Z'))
+ assert_equal(DateTime.new(2002,3,14,11,22,33, 9.to_r/24),
+ DateTime.parse('2002-03-14T11:22:33+09:00'))
+ assert_equal(DateTime.new(2002,3,14,11,22,33, -9.to_r/24),
+ DateTime.parse('2002-03-14T11:22:33-09:00'))
+ assert_equal(DateTime.new(2002,3,14,11,22,33, -9.to_r/24) + 123456789.to_r/1000000000/86400,
+ DateTime.parse('2002-03-14T11:22:33.123456789-09:00'))
+ end
+
+ def test_parse__2
+ d1 = DateTime.parse('2004-03-13T22:45:59.5')
+ d2 = DateTime.parse('2004-03-13T22:45:59')
+ assert_equal(d2 + 5.to_r/10**1/86400, d1)
+ d1 = DateTime.parse('2004-03-13T22:45:59.05')
+ d2 = DateTime.parse('2004-03-13T22:45:59')
+ assert_equal(d2 + 5.to_r/10**2/86400, d1)
+ d1 = DateTime.parse('2004-03-13T22:45:59.005')
+ d2 = DateTime.parse('2004-03-13T22:45:59')
+ assert_equal(d2 + 5.to_r/10**3/86400, d1)
+ d1 = DateTime.parse('2004-03-13T22:45:59.0123')
+ d2 = DateTime.parse('2004-03-13T22:45:59')
+ assert_equal(d2 + 123.to_r/10**4/86400, d1)
+ d1 = DateTime.parse('2004-03-13T22:45:59.5')
+ d1 += 1.to_r/2/86400
+ d2 = DateTime.parse('2004-03-13T22:46:00')
+ assert_equal(d2, d1)
+ end
+
+ require 'time'
+
+ def test_parse__time
+ methods = [:to_s, :asctime, :iso8601, :rfc2822, :httpdate, :xmlschema]
+
+ t = Time.utc(2001,2,3,4,5,6)
+ methods.each do |m|
+ d = DateTime.parse(t.__send__(m))
+ assert_equal([2001, 2, 3, 4, 5, 6],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec],
+ [m, t.__send__(m)].inspect)
+ end
+
+ t = Time.mktime(2001,2,3,4,5,6)
+ methods.each do |m|
+ next if m == :httpdate
+ d = DateTime.parse(t.__send__(m))
+ assert_equal([2001, 2, 3, 4, 5, 6],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec],
+ [m, t.__send__(m)].inspect)
+ end
+ end
+
+ def test_parse__comp
+ n = DateTime.now
+
+ d = DateTime.parse('073')
+ assert_equal([n.year, 73, 0, 0, 0],
+ [d.year, d.yday, d.hour, d.min, d.sec])
+ d = DateTime.parse('13')
+ assert_equal([n.year, n.mon, 13, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+
+ d = DateTime.parse('Mar 13')
+ assert_equal([n.year, 3, 13, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ d = DateTime.parse('Mar 2004')
+ assert_equal([2004, 3, 1, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ d = DateTime.parse('23:55')
+ assert_equal([n.year, n.mon, n.mday, 23, 55, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ d = DateTime.parse('23:55:30')
+ assert_equal([n.year, n.mon, n.mday, 23, 55, 30],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+
+ d = DateTime.parse('Sun 23:55')
+ d2 = d - d.wday
+ assert_equal([d2.year, d2.mon, d2.mday, 23, 55, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ d = DateTime.parse('Aug 23:55')
+ assert_equal([n.year, 8, 1, 23, 55, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ end
+
+ def test_parse__d_to_s
+ d = Date.new(2002,3,14)
+ assert_equal(d, Date.parse(d.to_s))
+
+ d = DateTime.new(2002,3,14,11,22,33, 9.to_r/24)
+ assert_equal(d, DateTime.parse(d.to_s))
+ end
+
+ def test_parse_utf8
+ h = DateTime._parse("Sun\u{3000}Aug 16 01:02:03 \u{65e5}\u{672c} 2009")
+ assert_equal(2009, h[:year])
+ assert_equal(8, h[:mon])
+ assert_equal(16, h[:mday])
+ assert_equal(0, h[:wday])
+ assert_equal(1, h[:hour])
+ assert_equal(2, h[:min])
+ assert_equal(3, h[:sec])
+ assert_equal("\u{65e5}\u{672c}", h[:zone])
+ end
+
+ def test_parse__ex
+ assert_raise(ArgumentError) do
+ Date.parse('')
+ end
+ assert_raise(ArgumentError) do
+ Date.parse('2001-02-29')
+ end
+ assert_raise(ArgumentError) do
+ DateTime.parse('2001-02-29T23:59:60')
+ end
+ assert_raise(ArgumentError) do
+ Date.parse('23:55')
+ end
+ end
+
+ def test__iso8601
+ h = Date._iso8601('01-02-03')
+ assert_equal([2001, 2, 3, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('2001-02-03')
+ assert_equal([2001, 2, 3, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('--02-03')
+ assert_equal([nil, 2, 3, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._iso8601('2001-02-03T04:05')
+ assert_equal([2001, 2, 3, 4, 5, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('2001-02-03T04:05:06')
+ assert_equal([2001, 2, 3, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('2001-02-03T04:05:06,07')
+ assert_equal([2001, 2, 3, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('2001-02-03T04:05:06Z')
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('2001-02-03T04:05:06.07+01:00')
+ assert_equal([2001, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._iso8601('010203')
+ assert_equal([2001, 2, 3, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('20010203')
+ assert_equal([2001, 2, 3, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('--0203')
+ assert_equal([nil, 2, 3, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._iso8601('010203T0405')
+ assert_equal([2001, 2, 3, 4, 5, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('20010203T0405')
+ assert_equal([2001, 2, 3, 4, 5, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('20010203T040506')
+ assert_equal([2001, 2, 3, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('20010203T040506,07')
+ assert_equal([2001, 2, 3, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('20010203T040506Z')
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('20010203T040506.07+0100')
+ assert_equal([2001, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._iso8601('200102030405')
+ assert_equal([2001, 2, 3, 4, 5, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('20010203040506')
+ assert_equal([2001, 2, 3, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('20010203040506,07')
+ assert_equal([2001, 2, 3, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('20010203040506Z')
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('20010203040506.07+0100')
+ assert_equal([2001, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._iso8601('01-023')
+ assert_equal([2001, 23, nil, nil, nil, nil],
+ h.values_at(:year, :yday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('2001-023')
+ assert_equal([2001, 23, nil, nil, nil, nil],
+ h.values_at(:year, :yday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('-023')
+ assert_equal([nil, 23, nil, nil, nil, nil],
+ h.values_at(:year, :yday, :hour, :min, :sec, :offset))
+
+ h = Date._iso8601('04:05')
+ assert_equal([nil, nil, nil, 4, 5, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('04:05:06')
+ assert_equal([nil, nil, nil, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('04:05:06,07')
+ assert_equal([nil, nil, nil, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('04:05:06Z')
+ assert_equal([nil, nil, nil, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('04:05:06.07+01:00')
+ assert_equal([nil, nil, nil, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._iso8601('040506,07')
+ assert_equal([nil, nil, nil, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('040506.07+0100')
+ assert_equal([nil, nil, nil, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._iso8601('01-w02-3')
+ assert_equal([2001, 2, 3, nil, nil, nil, nil],
+ h.values_at(:cwyear, :cweek, :cwday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('2001-w02-3')
+ assert_equal([2001, 2, 3, nil, nil, nil, nil],
+ h.values_at(:cwyear, :cweek, :cwday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('2001w023')
+ assert_equal([2001, 2, 3, nil, nil, nil, nil],
+ h.values_at(:cwyear, :cweek, :cwday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('-w02-3')
+ assert_equal([nil, 2, 3, nil, nil, nil, nil],
+ h.values_at(:cwyear, :cweek, :cwday, :hour, :min, :sec, :offset))
+ h = Date._iso8601('-w-3')
+ assert_equal([nil, nil, 3, nil, nil, nil, nil],
+ h.values_at(:cwyear, :cweek, :cwday, :hour, :min, :sec, :offset))
+ end
+
+ def test__rfc3339
+ h = Date._rfc3339('2001-02-03T04:05:06Z')
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._rfc3339('2001-02-03 04:05:06Z')
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._rfc3339('2001-02-03T04:05:06.07+01:00')
+ assert_equal([2001, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ end
+
+ def test__xmlschema
+ h = Date._xmlschema('2001-02-03')
+ assert_equal([2001, 2, 3, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('2001-02-03Z')
+ assert_equal([2001, 2, 3, nil, nil, nil, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('2001-02-03+01:00')
+ assert_equal([2001, 2, 3, nil, nil, nil, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._xmlschema('2001-02-03T04:05:06')
+ assert_equal([2001, 2, 3, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('2001-02-03T04:05:06.07')
+ assert_equal([2001, 2, 3, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('2001-02-03T04:05:06.07Z')
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('2001-02-03T04:05:06.07+01:00')
+ assert_equal([2001, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._xmlschema('04:05:06')
+ assert_equal([nil, nil, nil, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('04:05:06Z')
+ assert_equal([nil, nil, nil, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('04:05:06+01:00')
+ assert_equal([nil, nil, nil, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._xmlschema('2001-02')
+ assert_equal([2001, 2, nil, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('2001-02Z')
+ assert_equal([2001, 2, nil, nil, nil, nil, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('2001-02+01:00')
+ assert_equal([2001, 2, nil, nil, nil, nil, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('2001-02-01:00')
+ assert_equal([2001, 2, nil, nil, nil, nil, -3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._xmlschema('2001')
+ assert_equal([2001, nil, nil, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('2001Z')
+ assert_equal([2001, nil, nil, nil, nil, nil, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('2001+01:00')
+ assert_equal([2001, nil, nil, nil, nil, nil, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('2001-01:00')
+ assert_equal([2001, nil, nil, nil, nil, nil, -3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._xmlschema('--02')
+ assert_equal([nil, 2, nil, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('--02Z')
+ assert_equal([nil, 2, nil, nil, nil, nil, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._xmlschema('--02+01:00')
+ assert_equal([nil, 2, nil, nil, nil, nil, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._xmlschema('92001-02-03T04:05:06.07+01:00')
+ assert_equal([92001, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._xmlschema('-92001-02-03T04:05:06.07+01:00')
+ assert_equal([-92001, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ end
+
+ def test__rfc2822
+ h = Date._rfc2822('Sat, 3 Feb 2001 04:05:06 UT')
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._rfc2822('Sat, 3 Feb 2001 04:05:06 EST')
+ assert_equal([2001, 2, 3, 4, 5, 6, -5*3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._rfc2822('Sat, 3 Feb 2001 04:05:06 +0000')
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._rfc2822('Sat, 3 Feb 2001 04:05:06 +0100')
+ assert_equal([2001, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._rfc2822('Sat, 03 Feb 50 04:05:06 +0100')
+ assert_equal([1950, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._rfc2822('Sat, 03 Feb 49 04:05:06 +0100')
+ assert_equal([2049, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._rfc2822('Sat, 03 Feb 100 04:05:06 +0100')
+ assert_equal([2000, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h1 = Date._rfc2822('Sat, 3 Feb 2001 04:05:06 UT')
+ h2 = Date._rfc822('Sat, 3 Feb 2001 04:05:06 UT')
+ assert_equal(h1, h2)
+ end
+
+ def test__httpdate
+ h = Date._httpdate('Sat, 03 Feb 2001 04:05:06 GMT')
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._httpdate('Saturday, 03-Feb-01 04:05:06 GMT')
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._httpdate('Sat Feb 3 04:05:06 2001')
+ assert_equal([2001, 2, 3, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._httpdate('Sat Feb 03 04:05:06 2001')
+ assert_equal([2001, 2, 3, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ end
+
+ def test__jisx0301
+ h = Date._jisx0301('13.02.03')
+ assert_equal([2001, 2, 3, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._jisx0301('H13.02.03')
+ assert_equal([2001, 2, 3, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._jisx0301('S63.02.03')
+ assert_equal([1988, 2, 3, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+
+ h = Date._jisx0301('H13.02.03T04:05:06')
+ assert_equal([2001, 2, 3, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._jisx0301('H13.02.03T04:05:06,07')
+ assert_equal([2001, 2, 3, 4, 5, 6, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._jisx0301('H13.02.03T04:05:06Z')
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ h = Date._jisx0301('H13.02.03T04:05:06.07+0100')
+ assert_equal([2001, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ end
+
+ def test_iso8601
+ assert_instance_of(Date, Date.iso8601)
+ assert_instance_of(DateTime, DateTime.iso8601)
+ end
+
+ def test_rfc3339
+ assert_instance_of(Date, Date.rfc3339)
+ assert_instance_of(DateTime, DateTime.rfc3339)
+ end
+
+ def test_xmlschema
+ assert_instance_of(Date, Date.xmlschema)
+ assert_instance_of(DateTime, DateTime.xmlschema)
+ end
+
+ def test_rfc2822
+ assert_instance_of(Date, Date.rfc2822)
+ assert_instance_of(DateTime, DateTime.rfc2822)
+ assert_instance_of(Date, Date.rfc822)
+ assert_instance_of(DateTime, DateTime.rfc822)
+ end
+
+ def test_httpdate
+ assert_instance_of(Date, Date.httpdate)
+ assert_instance_of(DateTime, DateTime.httpdate)
+ end
+
+ def test_jisx0301
+ assert_instance_of(Date, Date.jisx0301)
+ assert_instance_of(DateTime, DateTime.jisx0301)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/date/test_date_strftime.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/date/test_date_strftime.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/date/test_date_strftime.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,388 @@
+require 'test/unit'
+require 'date'
+
+class TestDateStrftime < Test::Unit::TestCase
+
+ STRFTIME_2001_02_03 = {
+ '%A'=>['Saturday',{:wday=>6}],
+ '%a'=>['Sat',{:wday=>6}],
+ '%B'=>['February',{:mon=>2}],
+ '%b'=>['Feb',{:mon=>2}],
+ '%c'=>['Sat Feb 3 00:00:00 2001',
+ {:wday=>6,:mon=>2,:mday=>3,:hour=>0,:min=>0,:sec=>0,:year=>2001}],
+ '%d'=>['03',{:mday=>3}],
+ '%e'=>[' 3',{:mday=>3}],
+ '%H'=>['00',{:hour=>0}],
+ '%I'=>['12',{:hour=>0}],
+ '%j'=>['034',{:yday=>34}],
+ '%M'=>['00',{:min=>0}],
+ '%m'=>['02',{:mon=>2}],
+ '%p'=>['AM',{}],
+ '%S'=>['00',{:sec=>0}],
+ '%U'=>['04',{:wnum0=>4}],
+ '%W'=>['05',{:wnum1=>5}],
+ '%X'=>['00:00:00',{:hour=>0,:min=>0,:sec=>0}],
+ '%x'=>['02/03/01',{:mon=>2,:mday=>3,:year=>2001}],
+ '%Y'=>['2001',{:year=>2001}],
+ '%y'=>['01',{:year=>2001}],
+ '%Z'=>['+00:00',{:zone=>'+00:00',:offset=>0}],
+ '%%'=>['%',{}],
+ '%C'=>['20',{}],
+ '%D'=>['02/03/01',{:mon=>2,:mday=>3,:year=>2001}],
+ '%F'=>['2001-02-03',{:year=>2001,:mon=>2,:mday=>3}],
+ '%G'=>['2001',{:cwyear=>2001}],
+ '%g'=>['01',{:cwyear=>2001}],
+ '%h'=>['Feb',{:mon=>2}],
+ '%k'=>[' 0',{:hour=>0}],
+ '%L'=>['000',{:sec_fraction=>0}],
+ '%l'=>['12',{:hour=>0}],
+ '%N'=>['000000000',{:sec_fraction=>0}],
+ '%n'=>["\n",{}],
+ '%P'=>['am',{}],
+ '%Q'=>['981158400000',{:seconds=>981158400.to_r}],
+ '%R'=>['00:00',{:hour=>0,:min=>0}],
+ '%r'=>['12:00:00 AM',{:hour=>0,:min=>0,:sec=>0}],
+ '%s'=>['981158400',{:seconds=>981158400}],
+ '%T'=>['00:00:00',{:hour=>0,:min=>0,:sec=>0}],
+ '%t'=>["\t",{}],
+ '%u'=>['6',{:cwday=>6}],
+ '%V'=>['05',{:cweek=>5}],
+ '%v'=>[' 3-Feb-2001',{:mday=>3,:mon=>2,:year=>2001}],
+ '%z'=>['+0000',{:zone=>'+0000',:offset=>0}],
+ '%+'=>['Sat Feb 3 00:00:00 +00:00 2001',
+ {:wday=>6,:mon=>2,:mday=>3,
+ :hour=>0,:min=>0,:sec=>0,:zone=>'+00:00',:offset=>0,:year=>2001}],
+ }
+
+ STRFTIME_2001_02_03_CVS19 = {
+ }
+
+ STRFTIME_2001_02_03_GNUext = {
+ '%:z'=>['+00:00',{:zone=>'+00:00',:offset=>0}],
+ '%::z'=>['+00:00:00',{:zone=>'+00:00:00',:offset=>0}],
+ '%:::z'=>['+00',{:zone=>'+00',:offset=>0}],
+ }
+
+ STRFTIME_2001_02_03.update(STRFTIME_2001_02_03_CVS19)
+ STRFTIME_2001_02_03.update(STRFTIME_2001_02_03_GNUext)
+
+ def test_strftime
+ d = Date.new(2001,2,3)
+ STRFTIME_2001_02_03.each do |f, s|
+ assert_equal(s[0], d.strftime(f), [f, s].inspect)
+ case f[-1,1]
+ when 'c', 'C', 'x', 'X', 'y', 'Y'
+ f2 = f.sub(/\A%/, '%E')
+ assert_equal(s[0], d.strftime(f2), [f2, s].inspect)
+ else
+ f2 = f.sub(/\A%/, '%E')
+ assert_equal(f2, d.strftime(f2), [f2, s].inspect)
+ end
+ case f[-1,1]
+ when 'd', 'e', 'H', 'I', 'm', 'M', 'S', 'u', 'U', 'V', 'w', 'W', 'y'
+ f2 = f.sub(/\A%/, '%O')
+ assert_equal(s[0], d.strftime(f2), [f2, s].inspect)
+ else
+ f2 = f.sub(/\A%/, '%O')
+ assert_equal(f2, d.strftime(f2), [f2, s].inspect)
+ end
+ end
+ end
+
+ def test_strftime__2
+ d = Date.new(2001,2,3)
+ assert_equal('2001-02-03', d.strftime)
+
+ d = DateTime.new(2001,2,3)
+ assert_equal('2001-02-03T00:00:00+00:00', d.strftime)
+
+ assert_equal('', d.strftime(''))
+ assert_equal("\s"*3, d.strftime("\s"*3))
+ assert_equal("\tfoo\n\000\r", d.strftime("\tfoo\n\000\r"))
+ assert_equal("%\n", d.strftime("%\n")) # gnu
+ assert_equal('Saturday'*1024 + ',', d.strftime('%A'*1024 + ','))
+ assert_equal('%%', d.strftime('%%%'))
+ assert_equal('Anton von Webern', d.strftime('Anton von Webern'))
+
+ d = DateTime.new(2001,2,3, 1,2,3)
+ assert_equal('2001-02-03T01:02:03+00:00', d.strftime)
+ assert_equal('AM', d.strftime('%p'))
+ assert_equal('am', d.strftime('%P'))
+ d = DateTime.new(2001,2,3, 13,14,15)
+ assert_equal('2001-02-03T13:14:15+00:00', d.strftime)
+ assert_equal('PM', d.strftime('%p'))
+ assert_equal('pm', d.strftime('%P'))
+ end
+
+ def test_strftime__3_1
+ (Date.new(1970,1,1)..Date.new(2037,12,31)).each do |d|
+ t = Time.utc(d.year,d.mon,d.mday)
+ assert_equal(t.strftime('%U'), d.strftime('%U'))
+ assert_equal(t.strftime('%W'), d.strftime('%W'))
+ end
+ end
+
+ def test_strftime__3_2
+ s = Time.now.strftime('%G')
+ if s.empty? || s == '%G'
+ return
+ end
+ (Date.new(1970,1,1)..Date.new(2037,12,31)).each do |d|
+ t = Time.utc(d.year,d.mon,d.mday)
+ assert_equal(t.strftime('%G'), d.strftime('%G'))
+ assert_equal(t.strftime('%g'), d.strftime('%g'))
+ assert_equal(t.strftime('%V'), d.strftime('%V'))
+ assert_equal(t.strftime('%u'), d.strftime('%u'))
+ end
+ end
+
+ def test_strftime__4
+ s = '2006-08-08T23:15:33.123456789'
+ f = '%FT%T.%N'
+ d = DateTime.parse(s)
+ assert_equal(s, d.strftime(f))
+ d = DateTime.strptime(s, f)
+ assert_equal(s, d.strftime(f))
+
+ s = '2006-08-08T23:15:33.123456789'
+ f = '%FT%T.%N'
+ d = DateTime.parse(s + '123456789')
+ assert_equal(s, d.strftime(f))
+ d = DateTime.strptime(s + '123456789', f)
+ assert_equal(s, d.strftime(f))
+
+ si = '2006-08-08T23:15:33.9'
+ so = '2006-08-08T23:15:33.900000000'
+ f = '%FT%T.%N'
+ d = DateTime.parse(si)
+ assert_equal(so, d.strftime(f))
+ d = DateTime.strptime(si, f)
+ assert_equal(so, d.strftime(f))
+
+ s = '2006-08-08T23:15:33.123'
+ f = '%FT%T.%L'
+ d = DateTime.parse(s)
+ assert_equal(s, d.strftime(f))
+ d = DateTime.strptime(s, f)
+ assert_equal(s, d.strftime(f))
+
+ s = '2006-08-08T23:15:33.123'
+ f = '%FT%T.%L'
+ d = DateTime.parse(s + '123')
+ assert_equal(s, d.strftime(f))
+ d = DateTime.strptime(s + '123', f)
+ assert_equal(s, d.strftime(f))
+
+ si = '2006-08-08T23:15:33.9'
+ so = '2006-08-08T23:15:33.900'
+ f = '%FT%T.%L'
+ d = DateTime.parse(si)
+ assert_equal(so, d.strftime(f))
+ d = DateTime.strptime(si, f)
+ assert_equal(so, d.strftime(f))
+ end
+
+ def test_strftime__offset
+ s = '2006-08-08T23:15:33'
+ (-24..24).collect{|x| '%+.2d' % x}.each do |hh|
+ %w(00 30).each do |mm|
+ d = DateTime.parse(s + hh + mm)
+ assert_equal(hh + mm, d.strftime('%z'))
+ end
+ end
+ end
+
+ def test_strftime__minus
+ d = DateTime.new(1969, 12, 31, 23, 59, 59)
+ assert_equal('-1', d.strftime('%s'))
+ assert_equal('-1000', d.strftime('%Q'))
+ end
+
+ def test_strftime__gnuext # coreutils
+ d = DateTime.new(2006,8,8,23,15,33,9.to_r/24)
+
+ assert_equal('2006', d.strftime('%-Y'))
+ assert_equal('2006', d.strftime('%-5Y'))
+ assert_equal('02006', d.strftime('%5Y'))
+ assert_equal('2006', d.strftime('%_Y'))
+ assert_equal(' 2006', d.strftime('%_5Y'))
+ assert_equal('02006', d.strftime('%05Y'))
+
+ assert_equal('8', d.strftime('%-d'))
+ assert_equal('8', d.strftime('%-3d'))
+ assert_equal('008', d.strftime('%3d'))
+ assert_equal(' 8', d.strftime('%_d'))
+ assert_equal(' 8', d.strftime('%_3d'))
+ assert_equal('008', d.strftime('%03d'))
+
+ assert_equal('8', d.strftime('%-e'))
+ assert_equal('8', d.strftime('%-3e'))
+ assert_equal(' 8', d.strftime('%3e'))
+ assert_equal(' 8', d.strftime('%_e'))
+ assert_equal(' 8', d.strftime('%_3e'))
+ assert_equal('008', d.strftime('%03e'))
+
+ assert_equal('Tuesday', d.strftime('%-10A'))
+ assert_equal(' Tuesday', d.strftime('%10A'))
+ assert_equal(' Tuesday', d.strftime('%_10A'))
+ assert_equal('000Tuesday', d.strftime('%010A'))
+ assert_equal('TUESDAY', d.strftime('%^A'))
+ assert_equal('TUESDAY', d.strftime('%#A'))
+
+ assert_equal('Tue', d.strftime('%-6a'))
+ assert_equal(' Tue', d.strftime('%6a'))
+ assert_equal(' Tue', d.strftime('%_6a'))
+ assert_equal('000Tue', d.strftime('%06a'))
+ assert_equal('TUE', d.strftime('%^a'))
+ assert_equal('TUE', d.strftime('%#a'))
+ assert_equal(' TUE', d.strftime('%#6a'))
+
+ assert_equal('August', d.strftime('%-10B'))
+ assert_equal(' August', d.strftime('%10B'))
+ assert_equal(' August', d.strftime('%_10B'))
+ assert_equal('0000August', d.strftime('%010B'))
+ assert_equal('AUGUST', d.strftime('%^B'))
+ assert_equal('AUGUST', d.strftime('%#B'))
+
+ assert_equal('Aug', d.strftime('%-6b'))
+ assert_equal(' Aug', d.strftime('%6b'))
+ assert_equal(' Aug', d.strftime('%_6b'))
+ assert_equal('000Aug', d.strftime('%06b'))
+ assert_equal('AUG', d.strftime('%^b'))
+ assert_equal('AUG', d.strftime('%#b'))
+ assert_equal(' AUG', d.strftime('%#6b'))
+
+ assert_equal('Aug', d.strftime('%-6h'))
+ assert_equal(' Aug', d.strftime('%6h'))
+ assert_equal(' Aug', d.strftime('%_6h'))
+ assert_equal('000Aug', d.strftime('%06h'))
+ assert_equal('AUG', d.strftime('%^h'))
+ assert_equal('AUG', d.strftime('%#h'))
+ assert_equal(' AUG', d.strftime('%#6h'))
+
+ assert_equal('PM', d.strftime('%^p'))
+ assert_equal('pm', d.strftime('%#p'))
+ assert_equal('PM', d.strftime('%^P'))
+ assert_equal('PM', d.strftime('%#P'))
+
+ assert_equal('+000900', d.strftime('%7z'))
+ assert_equal(' +900', d.strftime('%_7z'))
+ assert_equal('+09:00', d.strftime('%:z'))
+ assert_equal('+0009:00', d.strftime('%8:z'))
+ assert_equal(' +9:00', d.strftime('%_8:z'))
+ assert_equal('+09:00:00', d.strftime('%::z'))
+ assert_equal('+0009:00:00', d.strftime('%11::z'))
+ assert_equal(' +9:00:00', d.strftime('%_11::z'))
+ assert_equal('+09', d.strftime('%:::z'))
+ assert_equal('+0009', d.strftime('%5:::z'))
+ assert_equal(' +9', d.strftime('%_5:::z'))
+ assert_equal('+9', d.strftime('%-:::z'))
+
+ d = DateTime.new(-200,8,8,23,15,33,9.to_r/24)
+
+ assert_equal('-0200', d.strftime('%Y'))
+ assert_equal('-200', d.strftime('%-Y'))
+ assert_equal('-200', d.strftime('%-5Y'))
+ assert_equal('-0200', d.strftime('%5Y'))
+ assert_equal(' -200', d.strftime('%_Y'))
+ assert_equal(' -200', d.strftime('%_5Y'))
+ assert_equal('-0200', d.strftime('%05Y'))
+
+ d = DateTime.new(-2000,8,8,23,15,33,9.to_r/24)
+
+ assert_equal('-2000', d.strftime('%Y'))
+ assert_equal('-2000', d.strftime('%-Y'))
+ assert_equal('-2000', d.strftime('%-5Y'))
+ assert_equal('-2000', d.strftime('%5Y'))
+ assert_equal('-2000', d.strftime('%_Y'))
+ assert_equal('-2000', d.strftime('%_5Y'))
+ assert_equal('-2000', d.strftime('%05Y'))
+ end
+
+ def test_strftime__gnuext_LN # coreutils
+ d = DateTime.parse('2008-11-25T00:11:22.0123456789')
+ assert_equal('012', d.strftime('%L'))
+ assert_equal('012', d.strftime('%0L'))
+ assert_equal('0', d.strftime('%1L'))
+ assert_equal('01', d.strftime('%2L'))
+ assert_equal('01234567890', d.strftime('%11L'))
+ assert_equal('01234567890', d.strftime('%011L'))
+ assert_equal('01234567890', d.strftime('%_11L'))
+ assert_equal('012345678', d.strftime('%N'))
+ assert_equal('012345678', d.strftime('%0N'))
+ assert_equal('0', d.strftime('%1N'))
+ assert_equal('01', d.strftime('%2N'))
+ assert_equal('01234567890', d.strftime('%11N'))
+ assert_equal('01234567890', d.strftime('%011N'))
+ assert_equal('01234567890', d.strftime('%_11N'))
+ end
+
+ def test_strftime__gnuext_z # coreutils
+ d = DateTime.parse('2006-08-08T23:15:33+09:08:07')
+ assert_equal('+0908', d.strftime('%z'))
+ assert_equal('+09:08', d.strftime('%:z'))
+ assert_equal('+09:08:07', d.strftime('%::z'))
+ assert_equal('+09:08:07', d.strftime('%:::z'))
+ end
+
+ def test__different_format
+ d = Date.new(2001,2,3)
+
+ assert_equal('Sat Feb 3 00:00:00 2001', d.ctime)
+ assert_equal(d.ctime, d.asctime)
+
+ assert_equal('2001-02-03', d.iso8601)
+ assert_equal(d.rfc3339, d.iso8601)
+ assert_equal(d.xmlschema, d.iso8601)
+ assert_equal('Sat, 3 Feb 2001 00:00:00 +0000', d.rfc2822)
+ assert_equal(d.rfc822, d.rfc2822)
+ assert_equal('Sat, 03 Feb 2001 00:00:00 GMT', d.httpdate)
+ assert_equal('H13.02.03', d.jisx0301)
+
+ d = DateTime.new(2001,2,3)
+
+ assert_equal('Sat Feb 3 00:00:00 2001', d.ctime)
+ assert_equal(d.ctime, d.asctime)
+
+ assert_equal('2001-02-03T00:00:00+00:00', d.iso8601)
+ assert_equal(d.rfc3339, d.iso8601)
+ assert_equal(d.xmlschema, d.iso8601)
+ assert_equal('Sat, 3 Feb 2001 00:00:00 +0000', d.rfc2822)
+ assert_equal(d.rfc822, d.rfc2822)
+ assert_equal('Sat, 03 Feb 2001 00:00:00 GMT', d.httpdate)
+ assert_equal('H13.02.03T00:00:00+00:00', d.jisx0301)
+
+ d2 = DateTime.parse('2001-02-03T04:05:06.123456')
+ assert_equal('2001-02-03T04:05:06.123+00:00', d2.iso8601(3))
+ assert_equal('2001-02-03T04:05:06.123+00:00', d2.rfc3339(3))
+ assert_equal('H13.02.03T04:05:06.123+00:00', d2.jisx0301(3))
+ assert_equal('2001-02-03T04:05:06.123456000+00:00', d2.iso8601(9))
+ assert_equal('2001-02-03T04:05:06.123456000+00:00', d2.rfc3339(9))
+ assert_equal('H13.02.03T04:05:06.123456000+00:00', d2.jisx0301(9))
+
+ assert_equal('1868-01-25', Date.parse('1868-01-25').jisx0301)
+ assert_equal('1872-12-31', Date.parse('1872-12-31').jisx0301)
+
+ assert_equal('M06.01.01', Date.parse('1873-01-01').jisx0301)
+ assert_equal('M45.07.29', Date.parse('1912-07-29').jisx0301)
+ assert_equal('T01.07.30', Date.parse('1912-07-30').jisx0301)
+ assert_equal('T15.12.24', Date.parse('1926-12-24').jisx0301)
+ assert_equal('S01.12.25', Date.parse('1926-12-25').jisx0301)
+ assert_equal('S64.01.07', Date.parse('1989-01-07').jisx0301)
+ assert_equal('H01.01.08', Date.parse('1989-01-08').jisx0301)
+ assert_equal('H18.09.01', Date.parse('2006-09-01').jisx0301)
+
+ %w(M06.01.01
+ M45.07.29
+ T01.07.30
+ T15.12.24
+ S01.12.25
+ S64.01.07
+ H01.01.08
+ H18.09.01).each do |s|
+ assert_equal(s, Date.parse(s).jisx0301)
+ end
+
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/date/test_date_strptime.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/date/test_date_strptime.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/date/test_date_strptime.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,469 @@
+require 'test/unit'
+require 'date'
+
+class TestDateStrptime < Test::Unit::TestCase
+
+ STRFTIME_2001_02_03 = {
+ '%A'=>['Saturday',{:wday=>6}],
+ '%a'=>['Sat',{:wday=>6}],
+ '%B'=>['February',{:mon=>2}],
+ '%b'=>['Feb',{:mon=>2}],
+ '%c'=>['Sat Feb 3 00:00:00 2001',
+ {:wday=>6,:mon=>2,:mday=>3,:hour=>0,:min=>0,:sec=>0,:year=>2001}],
+ '%d'=>['03',{:mday=>3}],
+ '%e'=>[' 3',{:mday=>3}],
+ '%H'=>['00',{:hour=>0}],
+ '%I'=>['12',{:hour=>0}],
+ '%j'=>['034',{:yday=>34}],
+ '%M'=>['00',{:min=>0}],
+ '%m'=>['02',{:mon=>2}],
+ '%p'=>['AM',{}],
+ '%S'=>['00',{:sec=>0}],
+ '%U'=>['04',{:wnum0=>4}],
+ '%W'=>['05',{:wnum1=>5}],
+ '%X'=>['00:00:00',{:hour=>0,:min=>0,:sec=>0}],
+ '%x'=>['02/03/01',{:mon=>2,:mday=>3,:year=>2001}],
+ '%Y'=>['2001',{:year=>2001}],
+ '%y'=>['01',{:year=>2001}],
+ '%Z'=>['+00:00',{:zone=>'+00:00',:offset=>0}],
+ '%%'=>['%',{}],
+ '%C'=>['20',{}],
+ '%D'=>['02/03/01',{:mon=>2,:mday=>3,:year=>2001}],
+ '%F'=>['2001-02-03',{:year=>2001,:mon=>2,:mday=>3}],
+ '%G'=>['2001',{:cwyear=>2001}],
+ '%g'=>['01',{:cwyear=>2001}],
+ '%h'=>['Feb',{:mon=>2}],
+ '%k'=>[' 0',{:hour=>0}],
+ '%L'=>['000',{:sec_fraction=>0}],
+ '%l'=>['12',{:hour=>0}],
+ '%N'=>['000000000',{:sec_fraction=>0}],
+ '%n'=>["\n",{}],
+ '%P'=>['am',{}],
+ '%Q'=>['981158400000',{:seconds=>981158400.to_r}],
+ '%R'=>['00:00',{:hour=>0,:min=>0}],
+ '%r'=>['12:00:00 AM',{:hour=>0,:min=>0,:sec=>0}],
+ '%s'=>['981158400',{:seconds=>981158400}],
+ '%T'=>['00:00:00',{:hour=>0,:min=>0,:sec=>0}],
+ '%t'=>["\t",{}],
+ '%u'=>['6',{:cwday=>6}],
+ '%V'=>['05',{:cweek=>5}],
+ '%v'=>[' 3-Feb-2001',{:mday=>3,:mon=>2,:year=>2001}],
+ '%z'=>['+0000',{:zone=>'+0000',:offset=>0}],
+ '%+'=>['Sat Feb 3 00:00:00 +00:00 2001',
+ {:wday=>6,:mon=>2,:mday=>3,
+ :hour=>0,:min=>0,:sec=>0,:zone=>'+00:00',:offset=>0,:year=>2001}],
+ }
+
+ STRFTIME_2001_02_03_CVS19 = {
+ }
+
+ STRFTIME_2001_02_03_GNUext = {
+ '%:z'=>['+00:00',{:zone=>'+00:00',:offset=>0}],
+ '%::z'=>['+00:00:00',{:zone=>'+00:00:00',:offset=>0}],
+ '%:::z'=>['+00',{:zone=>'+00',:offset=>0}],
+ }
+
+ STRFTIME_2001_02_03.update(STRFTIME_2001_02_03_CVS19)
+ STRFTIME_2001_02_03.update(STRFTIME_2001_02_03_GNUext)
+
+ def test__strptime
+ STRFTIME_2001_02_03.each do |f, s|
+ if (f == '%I' and s[0] == '12') or
+ (f == '%l' and s[0] == '12') # hour w/o merid
+ s[1][:hour] = 12
+ end
+ assert_equal(s[1], Date._strptime(s[0], f), [f, s].inspect)
+ case f[-1,1]
+ when 'c', 'C', 'x', 'X', 'y', 'Y'
+ f2 = f.sub(/\A%/, '%E')
+ assert_equal(s[1], Date._strptime(s[0], f2), [f2, s].inspect)
+ else
+ f2 = f.sub(/\A%/, '%E')
+ assert_equal(nil, Date._strptime(s[0], f2), [f2, s].inspect)
+ assert_equal({}, Date._strptime(f2, f2), [f2, s].inspect)
+ end
+ case f[-1,1]
+ when 'd', 'e', 'H', 'I', 'm', 'M', 'S', 'u', 'U', 'V', 'w', 'W', 'y'
+ f2 = f.sub(/\A%/, '%O')
+ assert_equal(s[1], Date._strptime(s[0], f2), [f2, s].inspect)
+ else
+ f2 = f.sub(/\A%/, '%O')
+ assert_equal(nil, Date._strptime(s[0], f2), [f2, s].inspect)
+ assert_equal({}, Date._strptime(f2, f2), [f2, s].inspect)
+ end
+ end
+ end
+
+ def test__strptime__2
+ h = Date._strptime('2001-02-03')
+ assert_equal([2001,2,3], h.values_at(:year,:mon,:mday))
+
+ h = DateTime._strptime('2001-02-03T12:13:14Z')
+ assert_equal([2001,2,3,12,13,14],
+ h.values_at(:year,:mon,:mday,:hour,:min,:sec))
+
+ assert_equal({}, Date._strptime('', ''))
+ assert_equal({:leftover=>"\s"*3}, Date._strptime("\s"*3, ''))
+ assert_equal({:leftover=>'x'}, Date._strptime("\nx", "\n"))
+ assert_equal({}, Date._strptime('', "\s"*3))
+ assert_equal({}, Date._strptime("\s"*3, "\s"*3))
+ assert_equal({}, Date._strptime("\tfoo\n\000\r", "\tfoo\n\000\r"))
+ assert_equal({}, Date._strptime("foo\n\nbar", "foo\sbar"))
+ assert_equal({}, Date._strptime("%\n", "%\n")) # gnu
+ assert_equal({}, Date._strptime('%%', '%%%'))
+ assert_equal({:wday=>6}, Date._strptime('Saturday'*1024 + ',', '%A'*1024 + ','))
+ assert_equal({:wday=>6}, Date._strptime('Saturday'*1024 + ',', '%a'*1024 + ','))
+ assert_equal({}, Date._strptime('Anton von Webern', 'Anton von Webern'))
+ end
+
+ def test__strptime__3
+ [
+ # iso8601
+ [['2001-02-03', '%Y-%m-%d'], [2001,2,3,nil,nil,nil,nil,nil,nil]],
+ [['2001-02-03T23:59:60', '%Y-%m-%dT%H:%M:%S'], [2001,2,3,23,59,60,nil,nil,nil]],
+ [['2001-02-03T23:59:60+09:00', '%Y-%m-%dT%H:%M:%S%Z'], [2001,2,3,23,59,60,'+09:00',9*3600,nil]],
+ [['-2001-02-03T23:59:60+09:00', '%Y-%m-%dT%H:%M:%S%Z'], [-2001,2,3,23,59,60,'+09:00',9*3600,nil]],
+ [['+012345-02-03T23:59:60+09:00', '%Y-%m-%dT%H:%M:%S%Z'], [12345,2,3,23,59,60,'+09:00',9*3600,nil]],
+ [['-012345-02-03T23:59:60+09:00', '%Y-%m-%dT%H:%M:%S%Z'], [-12345,2,3,23,59,60,'+09:00',9*3600,nil]],
+
+ # ctime(3), asctime(3)
+ [['Thu Jul 29 14:47:19 1999', '%c'], [1999,7,29,14,47,19,nil,nil,4]],
+ [['Thu Jul 29 14:47:19 -1999', '%c'], [-1999,7,29,14,47,19,nil,nil,4]],
+
+ # date(1)
+ [['Thu Jul 29 16:39:41 EST 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'EST',-5*3600,4]],
+ [['Thu Jul 29 16:39:41 MET DST 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'MET DST',2*3600,4]],
+ [['Thu Jul 29 16:39:41 AMT 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'AMT',nil,4]],
+ [['Thu Jul 29 16:39:41 AMT -1999', '%a %b %d %H:%M:%S %Z %Y'], [-1999,7,29,16,39,41,'AMT',nil,4]],
+ [['Thu Jul 29 16:39:41 GMT+09 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT+09',9*3600,4]],
+ [['Thu Jul 29 16:39:41 GMT+0908 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT+0908',9*3600+8*60,4]],
+ [['Thu Jul 29 16:39:41 GMT+090807 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT+090807',9*3600+8*60+7,4]],
+ [['Thu Jul 29 16:39:41 GMT-09 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT-09',-9*3600,4]],
+ [['Thu Jul 29 16:39:41 GMT-09:08 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT-09:08',-9*3600-8*60,4]],
+ [['Thu Jul 29 16:39:41 GMT-09:08:07 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT-09:08:07',-9*3600-8*60-7,4]],
+ [['Thu Jul 29 16:39:41 GMT-3.5 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT-3.5',-3*3600-30*60,4]],
+ [['Thu Jul 29 16:39:41 GMT-3,5 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT-3,5',-3*3600-30*60,4]],
+ [['Thu Jul 29 16:39:41 Mountain Daylight Time 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'Mountain Daylight Time',-6*3600,4]],
+ [['Thu Jul 29 16:39:41 E. Australia Standard Time 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'E. Australia Standard Time',10*3600,4]],
+
+ # rfc822
+ [['Thu, 29 Jul 1999 09:54:21 UT', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'UT',0,4]],
+ [['Thu, 29 Jul 1999 09:54:21 GMT', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'GMT',0,4]],
+ [['Thu, 29 Jul 1999 09:54:21 PDT', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'PDT',-7*3600,4]],
+ [['Thu, 29 Jul 1999 09:54:21 z', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'z',0,4]],
+ [['Thu, 29 Jul 1999 09:54:21 +0900', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'+0900',9*3600,4]],
+ [['Thu, 29 Jul 1999 09:54:21 +0430', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'+0430',4*3600+30*60,4]],
+ [['Thu, 29 Jul 1999 09:54:21 -0430', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'-0430',-4*3600-30*60,4]],
+ [['Thu, 29 Jul -1999 09:54:21 -0430', '%a, %d %b %Y %H:%M:%S %Z'], [-1999,7,29,9,54,21,'-0430',-4*3600-30*60,4]],
+
+ # etc
+ [['06-DEC-99', '%d-%b-%y'], [1999,12,6,nil,nil,nil,nil,nil,nil]],
+ [['sUnDay oCtoBer 31 01', '%A %B %d %y'], [2001,10,31,nil,nil,nil,nil,nil,0]],
+ [["October\t\n\v\f\r 15,\t\n\v\f\r99", '%B %d, %y'], [1999,10,15,nil,nil,nil,nil,nil,nil]],
+ [["October\t\n\v\f\r 15,\t\n\v\f\r99", '%B%t%d,%n%y'], [1999,10,15,nil,nil,nil,nil,nil,nil]],
+
+ [['09:02:11 AM', '%I:%M:%S %p'], [nil,nil,nil,9,2,11,nil,nil,nil]],
+ [['09:02:11 A.M.', '%I:%M:%S %p'], [nil,nil,nil,9,2,11,nil,nil,nil]],
+ [['09:02:11 PM', '%I:%M:%S %p'], [nil,nil,nil,21,2,11,nil,nil,nil]],
+ [['09:02:11 P.M.', '%I:%M:%S %p'], [nil,nil,nil,21,2,11,nil,nil,nil]],
+
+ [['12:33:44 AM', '%r'], [nil,nil,nil,0,33,44,nil,nil,nil]],
+ [['01:33:44 AM', '%r'], [nil,nil,nil,1,33,44,nil,nil,nil]],
+ [['11:33:44 AM', '%r'], [nil,nil,nil,11,33,44,nil,nil,nil]],
+ [['12:33:44 PM', '%r'], [nil,nil,nil,12,33,44,nil,nil,nil]],
+ [['01:33:44 PM', '%r'], [nil,nil,nil,13,33,44,nil,nil,nil]],
+ [['11:33:44 PM', '%r'], [nil,nil,nil,23,33,44,nil,nil,nil]],
+
+ [['11:33:44 PM AMT', '%I:%M:%S %p %Z'], [nil,nil,nil,23,33,44,'AMT',nil,nil]],
+ [['11:33:44 P.M. AMT', '%I:%M:%S %p %Z'], [nil,nil,nil,23,33,44,'AMT',nil,nil]],
+
+ [['fri1feb034pm+5', '%a%d%b%y%H%p%Z'], [2003,2,1,16,nil,nil,'+5',5*3600,5]]
+ ].each do |x, y|
+ h = Date._strptime(*x)
+ a = h.values_at(:year,:mon,:mday,:hour,:min,:sec,:zone,:offset,:wday)
+ if y[1] == -1
+ a[1] = -1
+ a[2] = h[:yday]
+ end
+ assert_equal(y, a, [x, y, a].inspect)
+ end
+ end
+
+ def test__strptime__width
+ [
+ [['99', '%y'], [1999,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [['01', '%y'], [2001,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [['19 99', '%C %y'], [1999,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [['20 01', '%C %y'], [2001,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [['1999', '%C%y'], [1999,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [['2001', '%C%y'], [2001,nil,nil,nil,nil,nil,nil,nil,nil]],
+
+ [['20060806', '%Y'], [20060806,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [['20060806', "%Y\s"], [20060806,nil,nil,nil,nil,nil,nil,nil,nil]],
+ [['20060806', '%Y%m%d'], [2006,8,6,nil,nil,nil,nil,nil,nil]],
+ [['2006908906', '%Y9%m9%d'], [2006,8,6,nil,nil,nil,nil,nil,nil]],
+ [['12006 08 06', '%Y %m %d'], [12006,8,6,nil,nil,nil,nil,nil,nil]],
+ [['12006-08-06', '%Y-%m-%d'], [12006,8,6,nil,nil,nil,nil,nil,nil]],
+ [['200608 6', '%Y%m%e'], [2006,8,6,nil,nil,nil,nil,nil,nil]],
+
+ [['2006333', '%Y%j'], [2006,-1,333,nil,nil,nil,nil,nil,nil]],
+ [['20069333', '%Y9%j'], [2006,-1,333,nil,nil,nil,nil,nil,nil]],
+ [['12006 333', '%Y %j'], [12006,-1,333,nil,nil,nil,nil,nil,nil]],
+ [['12006-333', '%Y-%j'], [12006,-1,333,nil,nil,nil,nil,nil,nil]],
+
+ [['232425', '%H%M%S'], [nil,nil,nil,23,24,25,nil,nil,nil]],
+ [['23924925', '%H9%M9%S'], [nil,nil,nil,23,24,25,nil,nil,nil]],
+ [['23 24 25', '%H %M %S'], [nil,nil,nil,23,24,25,nil,nil,nil]],
+ [['23:24:25', '%H:%M:%S'], [nil,nil,nil,23,24,25,nil,nil,nil]],
+ [[' 32425', '%k%M%S'], [nil,nil,nil,3,24,25,nil,nil,nil]],
+ [[' 32425', '%l%M%S'], [nil,nil,nil,3,24,25,nil,nil,nil]],
+
+ [['FriAug', '%a%b'], [nil,8,nil,nil,nil,nil,nil,nil,5]],
+ [['FriAug', '%A%B'], [nil,8,nil,nil,nil,nil,nil,nil,5]],
+ [['FridayAugust', '%A%B'], [nil,8,nil,nil,nil,nil,nil,nil,5]],
+ [['FridayAugust', '%a%b'], [nil,8,nil,nil,nil,nil,nil,nil,5]]
+ ].each do |x, y|
+ h = Date._strptime(*x)
+ a = h.values_at(:year,:mon,:mday,:hour,:min,:sec,:zone,:offset,:wday)
+ if y[1] == -1
+ a[1] = -1
+ a[2] = h[:yday]
+ end
+ assert_equal(y, a, [x, y, a].inspect)
+ end
+ end
+
+ def test__strptime__fail
+ assert_not_nil(Date._strptime('2001.', '%Y.'))
+ assert_not_nil(Date._strptime("2001.\s", '%Y.'))
+ assert_not_nil(Date._strptime('2001.', "%Y.\s"))
+ assert_not_nil(Date._strptime("2001.\s", "%Y.\s"))
+
+ assert_nil(Date._strptime('2001', '%Y.'))
+ assert_nil(Date._strptime("2001\s", '%Y.'))
+ assert_nil(Date._strptime('2001', "%Y.\s"))
+ assert_nil(Date._strptime("2001\s", "%Y.\s"))
+
+ assert_nil(Date._strptime('2001-13-31', '%Y-%m-%d'))
+ assert_nil(Date._strptime('2001-12-00', '%Y-%m-%d'))
+ assert_nil(Date._strptime('2001-12-32', '%Y-%m-%d'))
+ assert_nil(Date._strptime('2001-12-00', '%Y-%m-%e'))
+ assert_nil(Date._strptime('2001-12-32', '%Y-%m-%e'))
+ assert_nil(Date._strptime('2001-12-31', '%y-%m-%d'))
+
+ assert_nil(Date._strptime('2004-000', '%Y-%j'))
+ assert_nil(Date._strptime('2004-367', '%Y-%j'))
+ assert_nil(Date._strptime('2004-366', '%y-%j'))
+
+ assert_not_nil(Date._strptime('24:59:59', '%H:%M:%S'))
+ assert_not_nil(Date._strptime('24:59:59', '%k:%M:%S'))
+ assert_not_nil(Date._strptime('24:59:60', '%H:%M:%S'))
+ assert_not_nil(Date._strptime('24:59:60', '%k:%M:%S'))
+
+ assert_nil(Date._strptime('24:60:59', '%H:%M:%S'))
+ assert_nil(Date._strptime('24:60:59', '%k:%M:%S'))
+ assert_nil(Date._strptime('24:59:61', '%H:%M:%S'))
+ assert_nil(Date._strptime('24:59:61', '%k:%M:%S'))
+ assert_nil(Date._strptime('00:59:59', '%I:%M:%S'))
+ assert_nil(Date._strptime('13:59:59', '%I:%M:%S'))
+ assert_nil(Date._strptime('00:59:59', '%l:%M:%S'))
+ assert_nil(Date._strptime('13:59:59', '%l:%M:%S'))
+
+ assert_not_nil(Date._strptime('0', '%U'))
+ assert_nil(Date._strptime('54', '%U'))
+ assert_not_nil(Date._strptime('0', '%W'))
+ assert_nil(Date._strptime('54', '%W'))
+ assert_nil(Date._strptime('0', '%V'))
+ assert_nil(Date._strptime('54', '%V'))
+ assert_nil(Date._strptime('0', '%u'))
+ assert_not_nil(Date._strptime('7', '%u'))
+ assert_not_nil(Date._strptime('0', '%w'))
+ assert_nil(Date._strptime('7', '%w'))
+
+ assert_nil(Date._strptime('Sanday', '%A'))
+ assert_nil(Date._strptime('Jenuary', '%B'))
+ assert_not_nil(Date._strptime('Sundai', '%A'))
+ assert_not_nil(Date._strptime('Januari', '%B'))
+ assert_nil(Date._strptime('Sundai,', '%A,'))
+ assert_nil(Date._strptime('Januari,', '%B,'))
+ end
+
+ def test_strptime
+ assert_equal(Date.new, Date.strptime)
+ d = Date.new(2002,3,14)
+ assert_equal(d, Date.strptime(d.to_s))
+ assert_equal(Date.new(2002,3,14), Date.strptime('2002-03-14'))
+
+ d = DateTime.new(2002,3,14,11,22,33, 0)
+ assert_equal(d, DateTime.strptime(d.to_s))
+ assert_equal(DateTime.new(2002,3,14,11,22,33, 0),
+ DateTime.strptime('2002-03-14T11:22:33Z'))
+ assert_equal(DateTime.new(2002,3,14,11,22,33, 0),
+ DateTime.strptime('2002-03-14T11:22:33Z', '%Y-%m-%dT%H:%M:%S%Z'))
+ assert_equal(DateTime.new(2002,3,14,11,22,33, 9.to_r/24),
+ DateTime.strptime('2002-03-14T11:22:33+09:00', '%Y-%m-%dT%H:%M:%S%Z'))
+ assert_equal(DateTime.new(2002,3,14,11,22,33, -9.to_r/24),
+ DateTime.strptime('2002-03-14T11:22:33-09:00', '%FT%T%Z'))
+ assert_equal(DateTime.new(2002,3,14,11,22,33, -9.to_r/24) + 123456789.to_r/1000000000/86400,
+ DateTime.strptime('2002-03-14T11:22:33.123456789-09:00', '%FT%T.%N%Z'))
+ end
+
+ def test_strptime__2
+ n = 10**9
+ (Date.new(2006,6,1)..Date.new(2007,6,1)).each do |d|
+ [
+ '%Y %m %d',
+ '%C %y %m %d',
+
+ '%Y %j',
+ '%C %y %j',
+
+ '%G %V %w',
+ '%G %V %u',
+ '%C %g %V %w',
+ '%C %g %V %u',
+
+ '%Y %U %w',
+ '%Y %U %u',
+ '%Y %W %w',
+ '%Y %W %u',
+ '%C %y %U %w',
+ '%C %y %U %u',
+ '%C %y %W %w',
+ '%C %y %W %u',
+ ].each do |fmt|
+ s = d.strftime(fmt)
+ d2 = Date.strptime(s, fmt)
+ assert_equal(d, d2, [fmt, d.to_s, d2.to_s].inspect)
+ end
+
+ [
+ '%Y %m %d %H %M %S',
+ '%Y %m %d %H %M %S %N',
+ '%C %y %m %d %H %M %S',
+ '%C %y %m %d %H %M %S %N',
+
+ '%Y %j %H %M %S',
+ '%Y %j %H %M %S %N',
+ '%C %y %j %H %M %S',
+ '%C %y %j %H %M %S %N',
+
+ '%s',
+ '%s %N',
+ '%Q',
+ '%Q %N',
+ ].each do |fmt|
+ s = d.strftime(fmt)
+ d2 = DateTime.strptime(s, fmt)
+ assert_equal(d, d2, [fmt, d.to_s, d2.to_s].inspect)
+ end
+ end
+ end
+
+ def test_strptime__minus
+ d = DateTime.strptime('-1', '%s')
+ assert_equal([1969, 12, 31, 23, 59, 59],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ d = DateTime.strptime('-86400', '%s')
+ assert_equal([1969, 12, 31, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+
+ d = DateTime.strptime('-999', '%Q')
+ assert_equal([1969, 12, 31, 23, 59, 59, 1.to_r/10**3],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.sec_fraction])
+ d = DateTime.strptime('-1000', '%Q')
+ assert_equal([1969, 12, 31, 23, 59, 59, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.sec_fraction])
+ end
+
+ def test_strptime__comp
+ n = DateTime.now
+
+ d = DateTime.strptime('073', '%j')
+ assert_equal([n.year, 73, 0, 0, 0],
+ [d.year, d.yday, d.hour, d.min, d.sec])
+ d = DateTime.strptime('13', '%d')
+ assert_equal([n.year, n.mon, 13, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+
+ d = DateTime.strptime('Mar', '%b')
+ assert_equal([n.year, 3, 1, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ d = DateTime.strptime('2004', '%Y')
+ assert_equal([2004, 1, 1, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+
+ d = DateTime.strptime('Mar 13', '%b %d')
+ assert_equal([n.year, 3, 13, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ d = DateTime.strptime('Mar 2004', '%b %Y')
+ assert_equal([2004, 3, 1, 0, 0, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ d = DateTime.strptime('23:55', '%H:%M')
+ assert_equal([n.year, n.mon, n.mday, 23, 55, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ d = DateTime.strptime('23:55:30', '%H:%M:%S')
+ assert_equal([n.year, n.mon, n.mday, 23, 55, 30],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+
+ d = DateTime.strptime('Sun 23:55', '%a %H:%M')
+ d2 = d - d.wday
+ assert_equal([d2.year, d2.mon, d2.mday, 23, 55, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+ d = DateTime.strptime('Aug 23:55', '%b %H:%M')
+ assert_equal([n.year, 8, 1, 23, 55, 0],
+ [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
+
+ d = DateTime.strptime('2004', '%G')
+ assert_equal([2004, 1, 1, 0, 0, 0],
+ [d.cwyear, d.cweek, d.cwday, d.hour, d.min, d.sec])
+ d = DateTime.strptime('11', '%V')
+ assert_equal([n.cwyear, 11, 1, 0, 0, 0],
+ [d.cwyear, d.cweek, d.cwday, d.hour, d.min, d.sec])
+ d = DateTime.strptime('6', '%u')
+ assert_equal([n.cwyear, n.cweek, 6, 0, 0, 0],
+ [d.cwyear, d.cweek, d.cwday, d.hour, d.min, d.sec])
+
+ d = DateTime.strptime('11-6', '%V-%u')
+ assert_equal([n.cwyear, 11, 6, 0, 0, 0],
+ [d.cwyear, d.cweek, d.cwday, d.hour, d.min, d.sec])
+ d = DateTime.strptime('2004-11', '%G-%V')
+ assert_equal([2004, 11, 1, 0, 0, 0],
+ [d.cwyear, d.cweek, d.cwday, d.hour, d.min, d.sec])
+
+ d = DateTime.strptime('11-6', '%U-%w')
+ assert_equal([n.year, 11, 6, 0, 0, 0],
+ [d.year, d.strftime('%U').to_i, d.wday, d.hour, d.min, d.sec])
+ d = DateTime.strptime('2004-11', '%Y-%U')
+ assert_equal([2004, 11, 0, 0, 0, 0],
+ [d.year, d.strftime('%U').to_i, d.wday, d.hour, d.min, d.sec])
+
+ d = DateTime.strptime('11-6', '%W-%w')
+ assert_equal([n.year, 11, 6, 0, 0, 0],
+ [d.year, d.strftime('%W').to_i, d.wday, d.hour, d.min, d.sec])
+ d = DateTime.strptime('2004-11', '%Y-%W')
+ assert_equal([2004, 11, 1, 0, 0, 0],
+ [d.year, d.strftime('%W').to_i, d.wday, d.hour, d.min, d.sec])
+ end
+
+ def test_strptime__d_to_s
+ d = Date.new(2002,3,14)
+ assert_equal(d, Date.strptime(d.to_s))
+
+ d = DateTime.new(2002,3,14,11,22,33, 9.to_r/24)
+ assert_equal(d, DateTime.strptime(d.to_s))
+ end
+
+ def test_strptime__ex
+ assert_raise(ArgumentError) do
+ Date.strptime('2001-02-29', '%F')
+ end
+ assert_raise(ArgumentError) do
+ DateTime.strptime('2001-02-29T23:59:60', '%FT%T')
+ end
+ assert_raise(ArgumentError) do
+ Date.strptime('23:55', '%H:%M')
+ end
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/dbm/test_dbm.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/dbm/test_dbm.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/dbm/test_dbm.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,559 @@
+require 'test/unit'
+require 'tmpdir'
+
+begin
+ require 'dbm'
+rescue LoadError
+end
+
+if defined? DBM
+ require 'tmpdir'
+ require 'fileutils'
+
+ class TestDBM < Test::Unit::TestCase
+ def TestDBM.uname_s
+ require 'rbconfig'
+ case RbConfig::CONFIG['target_os']
+ when 'cygwin'
+ require 'Win32API'
+ uname = Win32API.new('cygwin1', 'uname', 'P', 'I')
+ utsname = ' ' * 100
+ raise 'cannot get system name' if uname.call(utsname) == -1
+
+ utsname.unpack('A20' * 5)[0]
+ else
+ RbConfig::CONFIG['target_os']
+ end
+ end
+ SYSTEM = uname_s
+
+ def setup
+ @tmpdir = Dir.mktmpdir("tmptest_dbm")
+ @prefix = "tmptest_dbm_#{$$}"
+ @path = "#{@tmpdir}/#{@prefix}_"
+ assert_instance_of(DBM, @dbm = DBM.new(@path))
+
+ # prepare to make readonly DBM file
+ DBM.open("#{@tmpdir}/#{@prefix}_rdonly") {|dbm|
+ dbm['foo'] = 'FOO'
+ }
+
+ File.chmod(0400, *Dir.glob("#{@tmpdir}/#{@prefix}_rdonly.*"))
+
+ assert_instance_of(DBM, @dbm_rdonly = DBM.new("#{@tmpdir}/#{@prefix}_rdonly", nil))
+ end
+ def teardown
+ assert_nil(@dbm.close)
+ assert_nil(@dbm_rdonly.close)
+ ObjectSpace.each_object(DBM) do |obj|
+ obj.close unless obj.closed?
+ end
+ FileUtils.remove_entry_secure @tmpdir
+ end
+
+ def check_size(expect, dbm=@dbm)
+ assert_equal(expect, dbm.size)
+ n = 0
+ dbm.each { n+=1 }
+ assert_equal(expect, n)
+ if expect == 0
+ assert_equal(true, dbm.empty?)
+ else
+ assert_equal(false, dbm.empty?)
+ end
+ end
+
+ def have_fork?
+ begin
+ fork{}
+ true
+ rescue NotImplementedError
+ false
+ end
+ end
+
+ def test_s_new_has_no_block
+ # DBM.new ignore the block
+ foo = true
+ assert_instance_of(DBM, dbm = DBM.new("#{@tmpdir}/#{@prefix}") { foo = false })
+ assert_equal(foo, true)
+ assert_nil(dbm.close)
+ end
+ def test_s_open_no_create
+ assert_nil(dbm = DBM.open("#{@tmpdir}/#{@prefix}", nil))
+ ensure
+ dbm.close if dbm
+ end
+ def test_s_open_with_block
+ assert_equal(DBM.open("#{@tmpdir}/#{@prefix}") { :foo }, :foo)
+ end
+
+ def test_close
+ assert_instance_of(DBM, dbm = DBM.open("#{@tmpdir}/#{@prefix}"))
+ assert_nil(dbm.close)
+
+ # closed DBM file
+ assert_raise(DBMError) { dbm.close }
+ end
+
+ def test_aref
+ assert_equal('bar', @dbm['foo'] = 'bar')
+ assert_equal('bar', @dbm['foo'])
+
+ assert_nil(@dbm['bar'])
+ end
+
+ def test_fetch
+ assert_equal('bar', @dbm['foo']='bar')
+ assert_equal('bar', @dbm.fetch('foo'))
+
+ # key not found
+ assert_raise(IndexError) {
+ @dbm.fetch('bar')
+ }
+
+ # test for `ifnone' arg
+ assert_equal('baz', @dbm.fetch('bar', 'baz'))
+
+ # test for `ifnone' block
+ assert_equal('foobar', @dbm.fetch('bar') {|key| 'foo' + key })
+ end
+
+ def test_aset
+ num = 0
+ 2.times {|i|
+ assert_equal('foo', @dbm['foo'] = 'foo')
+ assert_equal('foo', @dbm['foo'])
+ assert_equal('bar', @dbm['foo'] = 'bar')
+ assert_equal('bar', @dbm['foo'])
+
+ num += 1 if i == 0
+ assert_equal(num, @dbm.size)
+
+ # assign nil
+ assert_equal('', @dbm['bar'] = '')
+ assert_equal('', @dbm['bar'])
+
+ num += 1 if i == 0
+ assert_equal(num, @dbm.size)
+
+ # empty string
+ assert_equal('', @dbm[''] = '')
+ assert_equal('', @dbm[''])
+
+ num += 1 if i == 0
+ assert_equal(num, @dbm.size)
+
+ # Fixnum
+ assert_equal('200', @dbm['100'] = '200')
+ assert_equal('200', @dbm['100'])
+
+ num += 1 if i == 0
+ assert_equal(num, @dbm.size)
+
+ # Big key and value
+ assert_equal('y' * 100, @dbm['x' * 100] = 'y' * 100)
+ assert_equal('y' * 100, @dbm['x' * 100])
+
+ num += 1 if i == 0
+ assert_equal(num, @dbm.size)
+ }
+ end
+
+ def test_key
+ assert_equal('bar', @dbm['foo'] = 'bar')
+ assert_equal('foo', @dbm.key('bar'))
+ assert_nil(@dbm['bar'])
+ end
+
+ def test_values_at
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+ @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
+ assert_equal(values.reverse, @dbm.values_at(*keys.reverse))
+ end
+
+ def test_select_with_block
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+ @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
+ ret = @dbm.select {|k,v|
+ assert_equal(k.upcase, v)
+ k != "bar"
+ }
+ assert_equal([['baz', 'BAZ'], ['foo', 'FOO']],
+ ret.sort)
+ end
+
+ def test_length
+ num = 10
+ assert_equal(0, @dbm.size)
+ num.times {|i|
+ i = i.to_s
+ @dbm[i] = i
+ }
+ assert_equal(num, @dbm.size)
+
+ @dbm.shift
+
+ assert_equal(num - 1, @dbm.size)
+ end
+
+ def test_empty?
+ assert_equal(true, @dbm.empty?)
+ @dbm['foo'] = 'FOO'
+ assert_equal(false, @dbm.empty?)
+ end
+
+ def test_each_pair
+ n = 0
+ @dbm.each_pair { n += 1 }
+ assert_equal(0, n)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
+
+ n = 0
+ ret = @dbm.each_pair {|key, val|
+ assert_not_nil(i = keys.index(key))
+ assert_equal(val, values[i])
+
+ n += 1
+ }
+ assert_equal(keys.size, n)
+ assert_equal(@dbm, ret)
+ end
+
+ def test_each_value
+ n = 0
+ @dbm.each_value { n += 1 }
+ assert_equal(0, n)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
+
+ n = 0
+ ret = @dbm.each_value {|val|
+ assert_not_nil(key = @dbm.key(val))
+ assert_not_nil(i = keys.index(key))
+ assert_equal(val, values[i])
+
+ n += 1
+ }
+ assert_equal(keys.size, n)
+ assert_equal(@dbm, ret)
+ end
+
+ def test_each_key
+ n = 0
+ @dbm.each_key { n += 1 }
+ assert_equal(0, n)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
+
+ n = 0
+ ret = @dbm.each_key {|key|
+ assert_not_nil(i = keys.index(key))
+ assert_equal(@dbm[key], values[i])
+
+ n += 1
+ }
+ assert_equal(keys.size, n)
+ assert_equal(@dbm, ret)
+ end
+
+ def test_keys
+ assert_equal([], @dbm.keys)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
+
+ assert_equal(keys.sort, @dbm.keys.sort)
+ assert_equal(values.sort, @dbm.values.sort)
+ end
+
+ def test_values
+ test_keys
+ end
+
+ def test_shift
+ assert_nil(@dbm.shift)
+ assert_equal(0, @dbm.size)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
+
+ ret_keys = []
+ ret_values = []
+ while ret = @dbm.shift
+ ret_keys.push ret[0]
+ ret_values.push ret[1]
+
+ assert_equal(keys.size - ret_keys.size, @dbm.size)
+ end
+
+ assert_equal(keys.sort, ret_keys.sort)
+ assert_equal(values.sort, ret_values.sort)
+ end
+
+ def test_delete
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+ key = keys[1]
+
+ assert_nil(@dbm.delete(key))
+ assert_equal(0, @dbm.size)
+
+ @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
+
+ assert_equal('BAR', @dbm.delete(key))
+ assert_nil(@dbm[key])
+ assert_equal(2, @dbm.size)
+
+ assert_nil(@dbm.delete(key))
+
+ if /^CYGWIN_9/ !~ SYSTEM
+ assert_raise(DBMError) {
+ @dbm_rdonly.delete("foo")
+ }
+
+ assert_nil(@dbm_rdonly.delete("bar"))
+ end
+ end
+ def test_delete_with_block
+ key = 'no called block'
+ @dbm[key] = 'foo'
+ assert_equal('foo', @dbm.delete(key) {|k| k.replace 'called block'; :blockval})
+ assert_equal(0, @dbm.size)
+
+ key = 'no called block'
+ assert_equal(:blockval, @dbm.delete(key) {|k| k.replace 'called block'; :blockval})
+ assert_equal(0, @dbm.size)
+ end
+
+ def test_delete_if
+ v = "0"
+ 100.times {@dbm[v] = v; v = v.next}
+
+ ret = @dbm.delete_if {|key, val| key.to_i < 50}
+ assert_equal(@dbm, ret)
+ check_size(50, @dbm)
+
+ ret = @dbm.delete_if {|key, val| key.to_i >= 50}
+ assert_equal(@dbm, ret)
+ check_size(0, @dbm)
+
+ # break
+ v = "0"
+ 100.times {@dbm[v] = v; v = v.next}
+ check_size(100, @dbm)
+ n = 0;
+ @dbm.delete_if {|key, val|
+ break if n > 50
+ n+=1
+ true
+ }
+ assert_equal(51, n)
+ check_size(49, @dbm)
+
+ @dbm.clear
+
+ # raise
+ v = "0"
+ 100.times {@dbm[v] = v; v = v.next}
+ check_size(100, @dbm)
+ n = 0;
+ begin
+ @dbm.delete_if {|key, val|
+ raise "runtime error" if n > 50
+ n+=1
+ true
+ }
+ rescue
+ end
+ assert_equal(51, n)
+ check_size(49, @dbm)
+ end
+
+ def test_reject
+ v = "0"
+ 100.times {@dbm[v] = v; v = v.next}
+
+ hash = @dbm.reject {|key, val| key.to_i < 50}
+ assert_instance_of(Hash, hash)
+ assert_equal(100, @dbm.size)
+
+ assert_equal(50, hash.size)
+ hash.each_pair {|key,val|
+ assert_equal(false, key.to_i < 50)
+ assert_equal(key, val)
+ }
+
+ hash = @dbm.reject {|key, val| key.to_i < 100}
+ assert_instance_of(Hash, hash)
+ assert_equal(true, hash.empty?)
+ end
+
+ def test_clear
+ v = "1"
+ 100.times {v = v.next; @dbm[v] = v}
+
+ assert_equal(@dbm, @dbm.clear)
+
+ # validate DBM#size
+ i = 0
+ @dbm.each { i += 1 }
+ assert_equal(@dbm.size, i)
+ assert_equal(0, i)
+ end
+
+ def test_invert
+ v = "0"
+ 100.times {@dbm[v] = v; v = v.next}
+
+ hash = @dbm.invert
+ assert_instance_of(Hash, hash)
+ assert_equal(100, hash.size)
+ hash.each_pair {|key, val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_update
+ hash = {}
+ v = "0"
+ 100.times {v = v.next; hash[v] = v}
+
+ @dbm["101"] = "101"
+ @dbm.update hash
+ assert_equal(101, @dbm.size)
+ @dbm.each_pair {|key, val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_replace
+ hash = {}
+ v = "0"
+ 100.times {v = v.next; hash[v] = v}
+
+ @dbm["101"] = "101"
+ @dbm.replace hash
+ assert_equal(100, @dbm.size)
+ @dbm.each_pair {|key, val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_haskey?
+ assert_equal('bar', @dbm['foo']='bar')
+ assert_equal(true, @dbm.has_key?('foo'))
+ assert_equal(false, @dbm.has_key?('bar'))
+ end
+
+ def test_has_value?
+ assert_equal('bar', @dbm['foo']='bar')
+ assert_equal(true, @dbm.has_value?('bar'))
+ assert_equal(false, @dbm.has_value?('foo'))
+ end
+
+ def test_to_a
+ v = "0"
+ 100.times {v = v.next; @dbm[v] = v}
+
+ ary = @dbm.to_a
+ assert_instance_of(Array, ary)
+ assert_equal(100, ary.size)
+ ary.each {|key,val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_to_hash
+ v = "0"
+ 100.times {v = v.next; @dbm[v] = v}
+
+ hash = @dbm.to_hash
+ assert_instance_of(Hash, hash)
+ assert_equal(100, hash.size)
+ hash.each {|key,val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+ end
+
+ class TestDBM2 < Test::Unit::TestCase
+ def setup
+ @tmproot = Dir.mktmpdir('ruby-dbm')
+ end
+
+ def teardown
+ FileUtils.remove_entry_secure @tmproot if File.directory?(@tmproot)
+ end
+
+ def test_reader_open_notexist
+ assert_raise(Errno::ENOENT) {
+ DBM.open("#{@tmproot}/a", 0666, DBM::READER)
+ }
+ end
+
+ def test_writer_open_notexist
+ assert_raise(Errno::ENOENT) {
+ DBM.open("#{@tmproot}/a", 0666, DBM::WRITER)
+ }
+ end
+
+ def test_wrcreat_open_notexist
+ v = DBM.open("#{@tmproot}/a", 0666, DBM::WRCREAT)
+ assert_instance_of(DBM, v)
+ v.close
+ end
+
+ def test_newdb_open_notexist
+ v = DBM.open("#{@tmproot}/a", 0666, DBM::NEWDB)
+ assert_instance_of(DBM, v)
+ v.close
+ end
+
+ def test_reader_open
+ DBM.open("#{@tmproot}/a") {} # create a db.
+ v = DBM.open("#{@tmproot}/a", nil, DBM::READER) {|d|
+ # Errno::EPERM is raised on Solaris which use ndbm.
+ # DBMError is raised on Debian which use gdbm.
+ assert_raise(Errno::EPERM, DBMError) { d["k"] = "v" }
+ true
+ }
+ assert(v)
+ end
+
+ def test_newdb_open
+ DBM.open("#{@tmproot}/a") {|dbm|
+ dbm["k"] = "v"
+ }
+ v = DBM.open("#{@tmproot}/a", nil, DBM::NEWDB) {|d|
+ assert_equal(0, d.length)
+ assert_nil(d["k"])
+ true
+ }
+ assert(v)
+ end
+
+ def test_freeze
+ DBM.open("#{@tmproot}/a") {|d|
+ d.freeze
+ assert_raise(RuntimeError) { d["k"] = "v" }
+ }
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/digest/test_digest.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/digest/test_digest.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/digest/test_digest.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,128 @@
+#!/usr/bin/env ruby
+#
+# $RoughId: test.rb,v 1.4 2001/07/13 15:38:27 knu Exp $
+# $Id: test_digest.rb 27586 2010-05-02 05:56:35Z nobu $
+
+require 'test/unit'
+
+require 'digest'
+%w[digest/md5 digest/rmd160 digest/sha1 digest/sha2].each do |lib|
+ begin
+ require lib
+ rescue LoadError
+ end
+end
+
+module TestDigest
+ Data1 = "abc"
+ Data2 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+
+ def test_s_hexdigest
+ self.class::DATA.each do |str, hexdigest|
+ assert_equal(hexdigest, self.class::ALGO.hexdigest(str))
+ end
+ end
+
+ def test_s_base64digest
+ self.class::DATA.each do |str, hexdigest|
+ digest = [hexdigest].pack("H*")
+ assert_equal([digest].pack("m0"), self.class::ALGO.base64digest(str))
+ end
+ end
+
+ def test_s_digest
+ self.class::DATA.each do |str, hexdigest|
+ digest = [hexdigest].pack("H*")
+ assert_equal(digest, self.class::ALGO.digest(str))
+ end
+ end
+
+ def test_update
+ # This test is also for digest() and hexdigest()
+
+ str = "ABC"
+
+ md = self.class::ALGO.new
+ md.update str
+ assert_equal(self.class::ALGO.hexdigest(str), md.hexdigest)
+ assert_equal(self.class::ALGO.digest(str), md.digest)
+ end
+
+ def test_eq
+ # This test is also for clone()
+
+ md1 = self.class::ALGO.new
+ md1 << "ABC"
+
+ assert_equal(md1, md1.clone, self.class::ALGO)
+
+ md2 = self.class::ALGO.new
+ md2 << "A"
+
+ assert_not_equal(md1, md2, self.class::ALGO)
+
+ md2 << "BC"
+
+ assert_equal(md1, md2, self.class::ALGO)
+ end
+
+ def test_instance_eval
+ assert_nothing_raised {
+ self.class::ALGO.new.instance_eval { update "a" }
+ }
+ end
+
+ class TestMD5 < Test::Unit::TestCase
+ include TestDigest
+ ALGO = Digest::MD5
+ DATA = {
+ Data1 => "900150983cd24fb0d6963f7d28e17f72",
+ Data2 => "8215ef0796a20bcaaae116d3876c664a",
+ }
+ end if defined?(Digest::MD5)
+
+ class TestSHA1 < Test::Unit::TestCase
+ include TestDigest
+ ALGO = Digest::SHA1
+ DATA = {
+ Data1 => "a9993e364706816aba3e25717850c26c9cd0d89d",
+ Data2 => "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
+ }
+ end if defined?(Digest::SHA1)
+
+ class TestSHA256 < Test::Unit::TestCase
+ include TestDigest
+ ALGO = Digest::SHA256
+ DATA = {
+ Data1 => "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
+ Data2 => "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
+ }
+ end if defined?(Digest::SHA256)
+
+ class TestSHA384 < Test::Unit::TestCase
+ include TestDigest
+ ALGO = Digest::SHA384
+ DATA = {
+ Data1 => "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7",
+ Data2 => "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b",
+ }
+ end if defined?(Digest::SHA384)
+
+ class TestSHA512 < Test::Unit::TestCase
+ include TestDigest
+ ALGO = Digest::SHA512
+ DATA = {
+ Data1 => "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
+ Data2 => "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445",
+ }
+ end if defined?(Digest::SHA512)
+
+ class TestRMD160 < Test::Unit::TestCase
+ include TestDigest
+ ALGO = Digest::RMD160
+ DATA = {
+ Data1 => "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc",
+ Data2 => "12a053384a9c0c88e405a06c27dcf49ada62eb2b",
+ }
+ end if defined?(Digest::RMD160)
+end
Property changes on: MacRuby/trunk/test/test-mri/test/digest/test_digest.rb
___________________________________________________________________
Added: svn:executable
+ *
Added: MacRuby/trunk/test/test-mri/test/digest/test_digest_extend.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/digest/test_digest_extend.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/digest/test_digest_extend.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,145 @@
+require 'test/unit'
+require 'digest'
+
+class TestDigestExtend < Test::Unit::TestCase
+ class MyDigest < Digest::Class
+ def initialize(*arg)
+ super
+ @buf = []
+ end
+
+ def initialize_copy(org)
+ @buf = org.buf.dup
+ end
+
+ def update(arg)
+ @buf << arg
+ self
+ end
+
+ alias << update
+
+ def finish
+ (@buf.join.length % 256).chr
+ end
+
+ def reset
+ @buf.clear
+ self
+ end
+
+ protected
+
+ def buf
+ @buf
+ end
+ end
+
+ def test_digest_s_hexencode
+ assert_equal('', Digest.hexencode(''))
+ assert_equal('0102', Digest.hexencode("\1\2"))
+ assert_equal(
+ (0..0xff).to_a.map { |c| sprintf("%02x", c ) }.join,
+ Digest.hexencode((0..0xff).to_a.map { |c| c.chr }.join)
+ )
+ end
+
+ def test_class_reset
+ a = Digest::SHA1.new
+ base = a.to_s
+ assert_equal(base, a.reset.to_s)
+ b = a.new
+ assert_equal(base, b.to_s)
+ b.update('1')
+ assert_not_equal(base, b.to_s)
+ assert_equal(base, b.reset.to_s)
+ end
+
+ def test_digest
+ assert_equal("\3", MyDigest.digest("foo"))
+ end
+
+ def test_hexdigest
+ assert_equal("03", MyDigest.hexdigest("foo"))
+ end
+
+ def test_context
+ digester = MyDigest.new
+ digester.update("foo")
+ assert_equal("\3", digester.digest)
+ digester.update("foobar")
+ assert_equal("\t", digester.digest)
+ digester.update("foo")
+ assert_equal("\f", digester.digest)
+ end
+
+ def test_new
+ a = Digest::SHA1.new
+ b = a.new
+ obj = a.to_s
+ assert_equal(obj, a.to_s)
+ assert_equal(obj, b.to_s)
+ a.update('1')
+ assert_not_equal(obj, a.to_s)
+ assert_equal(obj, b.to_s)
+ end
+
+ def test_digest_hexdigest
+ [:digest, :hexdigest].each do |m|
+ exp_1st = "\3"; exp_1st = Digest.hexencode(exp_1st) if m == :hexdigest
+ exp_2nd = "\6"; exp_2nd = Digest.hexencode(exp_2nd) if m == :hexdigest
+ digester = MyDigest.new
+ digester.update("foo")
+ obj = digester.send(m)
+ # digest w/o param does not reset the org digester.
+ assert_equal(exp_1st, obj)
+ digester.update("bar")
+ obj = digester.send(m)
+ assert_equal(exp_2nd, obj)
+ obj = digester.send(m, "baz")
+ # digest with param resets the org digester.
+ assert_equal(exp_1st, obj)
+ end
+ end
+
+ def test_digest_hexdigest_bang
+ [:digest!, :hexdigest!].each do |m|
+ exp_1st = "\3"; exp_1st = Digest.hexencode(exp_1st) if m == :hexdigest!
+ digester = MyDigest.new
+ digester.update("foo")
+ obj = digester.send(m) # digest! always resets the org digester.
+ assert_equal(exp_1st, obj)
+ digester.update("bar")
+ obj = digester.send(m)
+ assert_equal(exp_1st, obj)
+ end
+ end
+
+ def test_to_s
+ digester = MyDigest.new
+ digester.update("foo")
+ assert_equal("03", digester.to_s)
+ end
+
+ def test_length
+ digester = MyDigest.new
+ assert_equal(2, digester.length)
+ assert_equal(2, digester.size)
+ end
+
+ def test_digest_length # breaks MyDigest#digest_length
+ assert_equal(1, MyDigest.new.digest_length)
+ MyDigest.class_eval do
+ def digest_length
+ 2
+ end
+ end
+ assert_equal(2, MyDigest.new.digest_length)
+ end
+
+ def test_block_length
+ assert_raises(RuntimeError) do
+ MyDigest.new.block_length
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/digest/test_digest_hmac.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/digest/test_digest_hmac.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/digest/test_digest_hmac.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,2 @@
+require_relative '../inlinetest.rb'
+InlineTest.loadtest__END__part('digest/hmac.rb')
Added: MacRuby/trunk/test/test-mri/test/dl/test_base.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/dl/test_base.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/dl/test_base.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,102 @@
+require 'test/unit'
+require 'dl'
+require_relative '../ruby/envutil'
+
+libc_so = libm_so = nil
+
+case RUBY_PLATFORM
+when /cygwin/
+ libc_so = "cygwin1.dll"
+ libm_so = "cygwin1.dll"
+when /x86_64-linux/
+ libc_so = "/lib64/libc.so.6"
+ libm_so = "/lib64/libm.so.6"
+when /linux/
+ libdir = '/lib'
+ case [0].pack('L!').size
+ when 4
+ # 32-bit ruby
+ libdir = '/lib32' if File.directory? '/lib32'
+ when 8
+ # 64-bit ruby
+ libdir = '/lib64' if File.directory? '/lib64'
+ end
+ libc_so = File.join(libdir, "libc.so.6")
+ libm_so = File.join(libdir, "libm.so.6")
+when /mingw/, /mswin/
+ require "rbconfig"
+ libc_so = libm_so = RbConfig::CONFIG["RUBY_SO_NAME"].split(/-/, 2)[0] + ".dll"
+when /darwin/
+ libc_so = "/usr/lib/libc.dylib"
+ libm_so = "/usr/lib/libm.dylib"
+when /kfreebsd/
+ libc_so = "/lib/libc.so.0.1"
+ libm_so = "/lib/libm.so.1"
+when /bsd|dragonfly/
+ libc_so = "/usr/lib/libc.so"
+ libm_so = "/usr/lib/libm.so"
+when /solaris/
+ libdir = '/lib'
+ case [0].pack('L!').size
+ when 4
+ # 32-bit ruby
+ libdir = '/lib' if File.directory? '/lib'
+ when 8
+ # 64-bit ruby
+ libdir = '/lib/64' if File.directory? '/lib/64'
+ end
+ libc_so = File.join(libdir, "libc.so.6")
+ libm_so = File.join(libdir, "libm.so.6")
+else
+ libc_so = ARGV[0] if ARGV[0] && ARGV[0][0] == ?/
+ libm_so = ARGV[1] if ARGV[1] && ARGV[1][0] == ?/
+ if( !(libc_so && libm_so) )
+ $stderr.puts("libc and libm not found: #{$0} <libc> <libm>")
+ end
+end
+
+libc_so = nil if !libc_so || (libc_so[0] == ?/ && !File.file?(libc_so))
+libm_so = nil if !libm_so || (libm_so[0] == ?/ && !File.file?(libm_so))
+
+if !libc_so || !libm_so
+ ruby = EnvUtil.rubybin
+ ldd = `ldd #{ruby}`
+ #puts ldd
+ libc_so = $& if !libc_so && %r{/\S*/libc\.so\S*} =~ ldd
+ libm_so = $& if !libm_so && %r{/\S*/libm\.so\S*} =~ ldd
+ #p [libc_so, libm_so]
+end
+
+DL::LIBC_SO = libc_so
+DL::LIBM_SO = libm_so
+
+module DL
+ class TestBase < Test::Unit::TestCase
+ include Math
+ include DL
+
+ def setup
+ @libc = dlopen(LIBC_SO)
+ @libm = dlopen(LIBM_SO)
+ end
+
+ def assert_match(expected, actual, message="")
+ assert_operator(expected, :===, actual, message)
+ end
+
+ def assert_positive(actual)
+ assert_operator(actual, :>, 0)
+ end
+
+ def assert_zero(actual)
+ assert_equal(0, actual)
+ end
+
+ def assert_negative(actual)
+ assert_operator(actual, :<, 0)
+ end
+
+ def test_empty()
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/dl/test_callback.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/dl/test_callback.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/dl/test_callback.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,69 @@
+require_relative 'test_base'
+require_relative '../ruby/envutil'
+require 'dl/callback'
+require 'dl/func'
+
+module DL
+ class TestCallback < TestBase
+ include DL
+
+ def test_remove_callback_failed
+ assert_equal(false, remove_callback(0, TYPE_VOIDP))
+ end
+
+ def test_remove_callback
+ addr = set_callback(TYPE_VOIDP, 1) do |str|
+ str
+ end
+ assert remove_callback(addr, TYPE_VOIDP), 'callback removed'
+ end
+
+ def test_callback_return_value
+ addr = set_callback(TYPE_VOIDP, 1) do |str|
+ str
+ end
+ func = CFunc.new(addr, TYPE_VOIDP, 'test')
+ f = Function.new(func, [TYPE_VOIDP])
+ ptr = CPtr['blah']
+ assert_equal ptr, f.call(ptr)
+ end
+
+ def test_callback_return_arbitrary
+ foo = 'foo'
+ addr = set_callback(TYPE_VOIDP, 1) do |ptr|
+ CPtr[foo].to_i
+ end
+ func = CFunc.new(addr, TYPE_VOIDP, 'test')
+ f = Function.new(func, [TYPE_VOIDP])
+
+ ptr = CPtr['foo']
+ assert_equal 'foo', f.call(ptr).to_s
+ end
+
+ def test_callback_with_string
+ called_with = nil
+ addr = set_callback(TYPE_VOID, 1) do |str|
+ called_with = dlunwrap(str)
+ end
+ func = CFunc.new(addr, TYPE_VOID, 'test')
+ f = Function.new(func, [TYPE_VOIDP])
+
+ f.call(dlwrap('foo'))
+ assert_equal 'foo', called_with
+ end
+
+ def test_call_callback
+ called = false
+
+ addr = set_callback(TYPE_VOID, 1) do |foo|
+ called = true
+ end
+
+ func = CFunc.new(addr, TYPE_VOID, 'test')
+ f = Function.new(func, [TYPE_VOIDP])
+ f.call(nil)
+
+ assert called, 'function should be called'
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/dl/test_cfunc.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/dl/test_cfunc.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/dl/test_cfunc.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,80 @@
+require_relative 'test_base'
+require 'dl/func'
+
+module DL
+ class TestCFunc < TestBase
+ def setup
+ super
+ @name = 'strcpy'
+ @cf = CFunc.new(@libc[@name], TYPE_VOIDP, @name)
+ end
+
+ def test_ptr=
+ @cf.ptr = @libc['malloc']
+ assert_equal @cf.ptr, @libc['malloc']
+ end
+
+ def test_ptr
+ assert_equal @cf.ptr, @libc[@name]
+ end
+
+ def test_set_calltype
+ @cf.calltype = :foo
+ assert_equal :foo, @cf.calltype
+ end
+
+ def test_new_ptr_type_name
+ assert_equal @name, @cf.name
+ assert @cf.name.tainted?, 'name should be tainted'
+ assert_equal :cdecl, @cf.calltype
+ assert_equal TYPE_VOIDP, @cf.ctype
+ end
+
+ def test_new_ptr
+ cf = CFunc.new(@libc['strcpy'])
+ assert_nil cf.name
+ assert_equal :cdecl, cf.calltype
+ assert_equal TYPE_VOID, cf.ctype
+ end
+
+ def test_name_should_be_duped
+ assert_equal @name, @cf.name
+ assert @cf.name.tainted?, 'name should be tainted'
+
+ name = @name.dup
+ @name << 'foo'
+
+ assert_equal name, @cf.name
+ end
+
+ def test_to_s
+ s = @cf.to_s
+ assert s.tainted?, 'to_s should be tainted'
+ assert_match(/ptr=#{sprintf("0x0*%x", @cf.ptr)}/, s)
+ assert_match(/name='#{@cf.name}'/, s)
+ assert_match(/type=#{@cf.ctype}/, s)
+ end
+
+ def test_inspect
+ assert_equal @cf.inspect, @cf.to_s
+ end
+
+ def test_inspect_is_tainted
+ assert @cf.inspect.tainted?, 'inspect is tainted'
+ end
+
+ def test_to_i
+ assert_equal @cf.to_i, @cf.ptr
+ assert_equal @libc[@name], @cf.to_i
+ end
+
+ def test_last_error
+ Thread.new do
+ f = Function.new(@cf, [TYPE_VOIDP, TYPE_VOIDP])
+ assert_nil CFunc.last_error
+ str = f.call("000", "123")
+ assert_not_nil CFunc.last_error
+ end.join
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/dl/test_cparser.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/dl/test_cparser.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/dl/test_cparser.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,13 @@
+require_relative 'test_base'
+
+require 'dl/cparser'
+
+module DL
+ class TestCParser < TestBase
+ include DL::CParser
+
+ def test_uint_ctype
+ assert_equal(-DL::TYPE_INT, parse_ctype('uint'))
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/dl/test_cptr.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/dl/test_cptr.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/dl/test_cptr.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,216 @@
+require_relative 'test_base'
+require_relative '../ruby/envutil'
+
+module DL
+ class TestCPtr < TestBase
+ def test_cptr_to_int
+ null = DL::NULL
+ assert_equal(null.to_i, null.to_int)
+ end
+
+ def test_malloc_free_func_int
+ free = CFunc.new(DL::RUBY_FREE, TYPE_VOID, 'free')
+
+ ptr = CPtr.malloc(10, free.to_i)
+ assert_equal 10, ptr.size
+ assert_equal free.to_i, ptr.free.to_i
+ end
+
+ def test_malloc_free_func
+ free = CFunc.new(DL::RUBY_FREE, TYPE_VOID, 'free')
+
+ ptr = CPtr.malloc(10, free)
+ assert_equal 10, ptr.size
+ assert_equal free.to_i, ptr.free.to_i
+ end
+
+ def test_to_str
+ str = "hello world"
+ ptr = CPtr[str]
+
+ assert_equal 3, ptr.to_str(3).length
+ assert_equal str, ptr.to_str
+
+ ptr[5] = 0
+ assert_equal "hello\0world", ptr.to_str
+ end
+
+ def test_to_s
+ str = "hello world"
+ ptr = CPtr[str]
+
+ assert_equal 3, ptr.to_s(3).length
+ assert_equal str, ptr.to_s
+
+ ptr[5] = 0
+ assert_equal 'hello', ptr.to_s
+ end
+
+ def test_minus
+ str = "hello world"
+ ptr = CPtr[str]
+ assert_equal ptr.to_s, (ptr + 3 - 3).to_s
+ end
+
+ # TODO: what if the pointer size is 0? raise an exception? do we care?
+ def test_plus
+ str = "hello world"
+ ptr = CPtr[str]
+ new_str = ptr + 3
+ assert_equal 'lo world', new_str.to_s
+ end
+
+ def test_inspect
+ ptr = CPtr.new(0)
+ inspect = ptr.inspect
+ assert_match(/size=#{ptr.size}/, inspect)
+ assert_match(/free=#{sprintf("%#x", ptr.free.to_i)}/, inspect)
+ assert_match(/ptr=#{sprintf("%#x", ptr.to_i)}/, inspect)
+ end
+
+ def test_to_ptr_string
+ str = "hello world"
+ ptr = CPtr[str]
+ assert ptr.tainted?, 'pointer should be tainted'
+ assert_equal str.length, ptr.size
+ assert_equal 'hello', ptr[0,5]
+ end
+
+ def test_to_ptr_io
+ buf = CPtr.malloc(10)
+ File.open(__FILE__, 'r') do |f|
+ ptr = CPtr.to_ptr f
+ fread = CFunc.new(@libc['fread'], TYPE_VOID, 'fread')
+ fread.call([buf.to_i, DL::SIZEOF_CHAR, buf.size - 1, ptr.to_i])
+ end
+
+ File.open(__FILE__, 'r') do |f|
+ assert_equal f.read(9), buf.to_s
+ end
+ end
+
+ def test_to_ptr_with_ptr
+ ptr = CPtr.new 0
+ ptr2 = CPtr.to_ptr Struct.new(:to_ptr).new(ptr)
+ assert_equal ptr, ptr2
+
+ assert_raises(DL::DLError) do
+ CPtr.to_ptr Struct.new(:to_ptr).new(nil)
+ end
+ end
+
+ def test_to_ptr_with_num
+ ptr = CPtr.new 0
+ assert_equal ptr, CPtr[0]
+ end
+
+ def test_equals
+ ptr = CPtr.new 0
+ ptr2 = CPtr.new 0
+ assert_equal ptr2, ptr
+ end
+
+ def test_not_equals
+ ptr = CPtr.new 0
+ assert_not_equal 10, ptr, '10 should not equal the pointer'
+ end
+
+ def test_cmp
+ ptr = CPtr.new 0
+ assert_nil(ptr <=> 10, '10 should not be comparable')
+ end
+
+ def test_ref_ptr
+ ary = [0,1,2,4,5]
+ addr = CPtr.new(dlwrap(ary))
+ assert_equal addr.to_i, addr.ref.ptr.to_i
+
+ assert_equal addr.to_i, (+ (- addr)).to_i
+ end
+
+ def test_to_value
+ ary = [0,1,2,4,5]
+ addr = CPtr.new(dlwrap(ary))
+ assert_equal ary, addr.to_value
+ end
+
+ def test_free
+ ptr = CPtr.malloc(4)
+ assert_nil ptr.free
+ end
+
+ def test_free=
+ assert_normal_exit(<<-"End", '[ruby-dev:39269]')
+ require 'dl'
+ DL::LIBC_SO = #{DL::LIBC_SO.dump}
+ DL::LIBM_SO = #{DL::LIBM_SO.dump}
+ include DL
+ @libc = dlopen(LIBC_SO)
+ @libm = dlopen(LIBM_SO)
+ free = CFunc.new(DL::RUBY_FREE, TYPE_VOID, 'free')
+ ptr = CPtr.malloc(4)
+ ptr.free = free
+ free.ptr
+ ptr.free.ptr
+ End
+
+ free = CFunc.new(DL::RUBY_FREE, TYPE_VOID, 'free')
+ ptr = CPtr.malloc(4)
+ ptr.free = free
+
+ assert_equal free.ptr, ptr.free.ptr
+ end
+
+ def test_null?
+ ptr = CPtr.new(0)
+ assert ptr.null?
+ end
+
+ def test_size
+ ptr = CPtr.malloc(4)
+ assert_equal 4, ptr.size
+ DL.free ptr.to_i
+ end
+
+ def test_size=
+ ptr = CPtr.malloc(4)
+ ptr.size = 10
+ assert_equal 10, ptr.size
+ DL.free ptr.to_i
+ end
+
+ def test_aref_aset
+ check = Proc.new{|str,ptr|
+ assert_equal(str.size(), ptr.size())
+ assert_equal(str, ptr.to_s())
+ assert_equal(str[0,2], ptr.to_s(2))
+ assert_equal(str[0,2], ptr[0,2])
+ assert_equal(str[1,2], ptr[1,2])
+ assert_equal(str[1,0], ptr[1,0])
+ assert_equal(str[0].ord, ptr[0])
+ assert_equal(str[1].ord, ptr[1])
+ }
+ str = 'abc'
+ ptr = CPtr[str]
+ check.call(str, ptr)
+
+ str[0] = "c"
+ assert_equal 'c'.ord, ptr[0] = "c".ord
+ check.call(str, ptr)
+
+ str[0,2] = "aa"
+ assert_equal 'aa', ptr[0,2] = "aa"
+ check.call(str, ptr)
+
+ ptr2 = CPtr['cdeeee']
+ str[0,2] = "cd"
+ assert_equal ptr2, ptr[0,2] = ptr2
+ check.call(str, ptr)
+
+ ptr3 = CPtr['vvvv']
+ str[0,2] = "vv"
+ assert_equal ptr3.to_i, ptr[0,2] = ptr3.to_i
+ check.call(str, ptr)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/dl/test_dl2.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/dl/test_dl2.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/dl/test_dl2.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,154 @@
+require_relative 'test_base.rb'
+require 'dl/callback'
+require 'dl/func'
+require 'dl/pack'
+
+module DL
+class TestDL < TestBase
+ def ptr2num(*list)
+ list.pack("p*").unpack(PackInfo::PACK_MAP[TYPE_VOIDP] + "*")
+ end
+
+ # TODO: refactor test repetition
+
+ def test_free_secure
+ assert_raises(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ DL.free(0)
+ end.join
+ end
+ end
+
+ def test_realloc
+ str = "abc"
+ ptr_id = DL.realloc(0, 4)
+ ptr = CPtr.new(ptr_id, 4)
+
+ assert_equal ptr_id, ptr.to_i
+
+ cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy')
+ x = cfunc.call([ptr_id,str].pack("l!p").unpack("l!*"))
+ assert_equal("abc\0", ptr[0,4])
+ DL.free ptr_id
+ end
+
+ def test_realloc_secure
+ assert_raises(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ DL.realloc(0, 4)
+ end.join
+ end
+ end
+
+ def test_malloc
+ str = "abc"
+
+ ptr_id = DL.malloc(4)
+ ptr = CPtr.new(ptr_id, 4)
+
+ assert_equal ptr_id, ptr.to_i
+
+ cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy')
+ x = cfunc.call([ptr_id,str].pack("l!p").unpack("l!*"))
+ assert_equal("abc\0", ptr[0,4])
+ DL.free ptr_id
+ end
+
+ def test_malloc_security
+ assert_raises(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ DL.malloc(4)
+ end.join
+ end
+ end
+
+ def test_call_int()
+ cfunc = CFunc.new(@libc['atoi'], TYPE_INT, 'atoi')
+ x = cfunc.call(["100"].pack("p").unpack("l!*"))
+ assert_equal(100, x)
+
+ cfunc = CFunc.new(@libc['atoi'], TYPE_INT, 'atoi')
+ x = cfunc.call(["-100"].pack("p").unpack("l!*"))
+ assert_equal(-100, x)
+ end
+
+ def test_call_long()
+ cfunc = CFunc.new(@libc['atol'], TYPE_LONG, 'atol')
+ x = cfunc.call(["100"].pack("p").unpack("l!*"))
+ assert_equal(100, x)
+ cfunc = CFunc.new(@libc['atol'], TYPE_LONG, 'atol')
+ x = cfunc.call(["-100"].pack("p").unpack("l!*"))
+ assert_equal(-100, x)
+ end
+
+ def test_call_double()
+ cfunc = CFunc.new(@libc['atof'], TYPE_DOUBLE, 'atof')
+ x = cfunc.call(["0.1"].pack("p").unpack("l!*"))
+ assert_in_delta(0.1, x)
+
+ cfunc = CFunc.new(@libc['atof'], TYPE_DOUBLE, 'atof')
+ x = cfunc.call(["-0.1"].pack("p").unpack("l!*"))
+ assert_in_delta(-0.1, x)
+ end
+
+ def test_sin
+ pi_2 = Math::PI/2
+ cfunc = Function.new(CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin'),
+ [TYPE_DOUBLE])
+ x = cfunc.call(pi_2)
+ assert_equal(Math.sin(pi_2), x)
+
+ cfunc = Function.new(CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin'),
+ [TYPE_DOUBLE])
+ x = cfunc.call(-pi_2)
+ assert_equal(Math.sin(-pi_2), x)
+ end
+
+ def test_strlen()
+ cfunc = CFunc.new(@libc['strlen'], TYPE_INT, 'strlen')
+ x = cfunc.call(["abc"].pack("p").unpack("l!*"))
+ assert_equal("abc".size, x)
+ end
+
+ def test_strcpy()
+ buff = "xxxx"
+ str = "abc"
+ cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy')
+ x = cfunc.call(ptr2num(buff,str))
+ assert_equal("abc\0", buff)
+ assert_equal("abc\0", CPtr.new(x).to_s(4))
+
+ buff = "xxxx"
+ str = "abc"
+ cfunc = CFunc.new(@libc['strncpy'], TYPE_VOIDP, 'strncpy')
+ x = cfunc.call(ptr2num(buff,str) + [3])
+ assert_equal("abcx", buff)
+ assert_equal("abcx", CPtr.new(x).to_s(4))
+
+ ptr = CPtr.malloc(4)
+ str = "abc"
+ cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy')
+ x = cfunc.call([ptr.to_i, *ptr2num(str)])
+ assert_equal("abc\0", ptr[0,4])
+ assert_equal("abc\0", CPtr.new(x).to_s(4))
+ end
+
+ def test_callback()
+ buff = "foobarbaz"
+ cb = set_callback(TYPE_INT,2){|x,y| CPtr.new(x)[0] <=> CPtr.new(y)[0]}
+ cfunc = CFunc.new(@libc['qsort'], TYPE_VOID, 'qsort')
+ cfunc.call(ptr2num(buff) + [buff.size, 1, cb])
+ assert_equal('aabbfoorz', buff)
+ end
+
+ def test_dlwrap()
+ ary = [0,1,2,4,5]
+ addr = dlwrap(ary)
+ ary2 = dlunwrap(addr)
+ assert_equal(ary, ary2)
+ end
+end
+end # module DL
Added: MacRuby/trunk/test/test-mri/test/dl/test_func.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/dl/test_func.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/dl/test_func.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,108 @@
+require_relative 'test_base'
+require 'dl/func'
+
+module DL
+ class TestFunc < TestBase
+ def test_name
+ f = Function.new(CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy'),
+ [TYPE_VOIDP, TYPE_VOIDP])
+ assert_equal 'strcpy', f.name
+ end
+
+ def test_to_i
+ cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy')
+ f = Function.new(cfunc, [TYPE_VOIDP, TYPE_VOIDP])
+ assert_equal cfunc.to_i, f.to_i
+ end
+
+ def test_random
+ f = Function.new(CFunc.new(@libc['srand'], TYPE_VOID, 'srand'),
+ [-TYPE_LONG])
+ assert_nil f.call(10)
+ end
+
+ def test_sinf
+ begin
+ f = Function.new(CFunc.new(@libm['sinf'], TYPE_FLOAT, 'sinf'),
+ [TYPE_FLOAT])
+ rescue DL::DLError
+ skip "libm may not have sinf()"
+ end
+ assert_in_delta 1.0, f.call(90 * Math::PI / 180), 0.0001
+ end
+
+ def test_sin
+ f = Function.new(CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin'),
+ [TYPE_DOUBLE])
+ assert_in_delta 1.0, f.call(90 * Math::PI / 180), 0.0001
+ end
+
+ def test_strcpy()
+ f = Function.new(CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy'),
+ [TYPE_VOIDP, TYPE_VOIDP])
+ buff = "000"
+ str = f.call(buff, "123")
+ assert_equal("123", buff)
+ assert_equal("123", str.to_s)
+ end
+
+ def test_string()
+ stress, GC.stress = GC.stress, true
+ f = Function.new(CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy'),
+ [TYPE_VOIDP, TYPE_VOIDP])
+ buff = "000"
+ str = f.call(buff, "123")
+ assert_equal("123", buff)
+ assert_equal("123", str.to_s)
+ ensure
+ GC.stress = stress
+ end
+
+ def test_isdigit()
+ f = Function.new(CFunc.new(@libc['isdigit'], TYPE_INT, 'isdigit'),
+ [TYPE_INT])
+ r1 = f.call(?1.ord)
+ r2 = f.call(?2.ord)
+ rr = f.call(?r.ord)
+ assert_positive(r1)
+ assert_positive(r2)
+ assert_zero(rr)
+ end
+
+ def test_atof()
+ f = Function.new(CFunc.new(@libc['atof'], TYPE_DOUBLE, 'atof'),
+ [TYPE_VOIDP])
+ r = f.call("12.34")
+ assert_match(12.00..13.00, r)
+ end
+
+ def test_strtod()
+ f = Function.new(CFunc.new(@libc['strtod'], TYPE_DOUBLE, 'strtod'),
+ [TYPE_VOIDP, TYPE_VOIDP])
+ buff1 = CPtr["12.34"]
+ buff2 = buff1 + 4
+ r = f.call(buff1, - buff2)
+ assert_in_delta(12.34, r, 0.001)
+ end
+
+ def test_qsort1()
+ cb = Function.new(CFunc.new(0, TYPE_INT, '<callback>qsort'),
+ [TYPE_VOIDP, TYPE_VOIDP]){|x,y| CPtr.new(x)[0] <=> CPtr.new(y)[0]}
+ qsort = Function.new(CFunc.new(@libc['qsort'], TYPE_VOID, 'qsort'),
+ [TYPE_VOIDP, TYPE_INT, TYPE_INT, TYPE_VOIDP])
+ buff = "9341"
+ qsort.call(buff, buff.size, 1, cb)
+ assert_equal("1349", buff)
+ end
+
+ def test_qsort2()
+ cb = TempFunction.new(CFunc.new(0, TYPE_INT, '<callback>qsort'),
+ [TYPE_VOIDP, TYPE_VOIDP])
+ qsort = Function.new(CFunc.new(@libc['qsort'], TYPE_VOID, 'qsort'),
+ [TYPE_VOIDP, TYPE_INT, TYPE_INT, TYPE_VOIDP])
+ buff = "9341"
+ qsort.call(buff, buff.size, 1, cb){|x,y| CPtr.new(x)[0] <=> CPtr.new(y)[0]}
+ assert_equal("1349", buff)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/dl/test_handle.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/dl/test_handle.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/dl/test_handle.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,174 @@
+require_relative 'test_base'
+
+module DL
+ class TestHandle < TestBase
+ def test_to_i
+ handle = DL::Handle.new(LIBC_SO)
+ assert_kind_of Integer, handle.to_i
+ end
+
+ def test_static_sym_secure
+ assert_raises(SecurityError) do
+ Thread.new do
+ $SAFE = 2
+ DL::Handle.sym('calloc')
+ end.join
+ end
+ end
+
+ def test_static_sym_unknown
+ assert_raises(DL::DLError) { DL::Handle.sym('fooo') }
+ assert_raises(DL::DLError) { DL::Handle['fooo'] }
+ end
+
+ def test_static_sym
+ skip "DL::Handle.sym is not supported" if /mswin|mingw/ =~ RUBY_PLATFORM
+ begin
+ # Linux / Darwin / FreeBSD
+ assert_not_nil DL::Handle.sym('dlopen')
+ assert_equal DL::Handle.sym('dlopen'), DL::Handle['dlopen']
+ rescue
+ # NetBSD
+ require 'objspace'
+ assert_not_nil DL::Handle.sym('Init_objspace')
+ assert_equal DL::Handle.sym('Init_objspace'), DL::Handle['Init_objspace']
+ end
+ end
+
+ def test_sym_closed_handle
+ handle = DL::Handle.new(LIBC_SO)
+ handle.close
+ assert_raises(DL::DLError) { handle.sym("calloc") }
+ assert_raises(DL::DLError) { handle["calloc"] }
+ end
+
+ def test_sym_unknown
+ handle = DL::Handle.new(LIBC_SO)
+ assert_raises(DL::DLError) { handle.sym('fooo') }
+ assert_raises(DL::DLError) { handle['fooo'] }
+ end
+
+ def test_sym_with_bad_args
+ handle = DL::Handle.new(LIBC_SO)
+ assert_raises(TypeError) { handle.sym(nil) }
+ assert_raises(TypeError) { handle[nil] }
+ end
+
+ def test_sym_secure
+ assert_raises(SecurityError) do
+ Thread.new do
+ $SAFE = 2
+ handle = DL::Handle.new(LIBC_SO)
+ handle.sym('calloc')
+ end.join
+ end
+ end
+
+ def test_sym
+ handle = DL::Handle.new(LIBC_SO)
+ assert_not_nil handle.sym('calloc')
+ assert_not_nil handle['calloc']
+ end
+
+ def test_handle_close
+ handle = DL::Handle.new(LIBC_SO)
+ assert_equal 0, handle.close
+ end
+
+ def test_handle_close_twice
+ handle = DL::Handle.new(LIBC_SO)
+ handle.close
+ assert_raises(DL::DLError) do
+ handle.close
+ end
+ end
+
+ def test_dlopen_returns_handle
+ assert_instance_of DL::Handle, dlopen(LIBC_SO)
+ end
+
+ def test_dlopen_safe
+ assert_raises(SecurityError) do
+ Thread.new do
+ $SAFE = 2
+ dlopen(LIBC_SO)
+ end.join
+ end
+ end
+
+ def test_initialize_safe
+ assert_raises(SecurityError) do
+ Thread.new do
+ $SAFE = 2
+ DL::Handle.new(LIBC_SO)
+ end.join
+ end
+ end
+
+ def test_initialize_noargs
+ handle = DL::Handle.new
+ assert_not_nil handle['rb_str_new']
+ end
+
+ def test_initialize_flags
+ handle = DL::Handle.new(LIBC_SO, DL::RTLD_LAZY | DL::RTLD_GLOBAL)
+ assert_not_nil handle['calloc']
+ end
+
+ def test_enable_close
+ handle = DL::Handle.new(LIBC_SO)
+ assert !handle.close_enabled?, 'close is enabled'
+
+ handle.enable_close
+ assert handle.close_enabled?, 'close is not enabled'
+ end
+
+ def test_disable_close
+ handle = DL::Handle.new(LIBC_SO)
+
+ handle.enable_close
+ assert handle.close_enabled?, 'close is enabled'
+ handle.disable_close
+ assert !handle.close_enabled?, 'close is enabled'
+ end
+
+ def test_NEXT
+ skip "DL::Handle::NEXT is not supported" if /mswin|mingw/ =~ RUBY_PLATFORM
+ begin
+ # Linux / Darwin
+ #
+ # There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The former will find
+ # the first occurrence of the desired symbol using the default library search order. The
+ # latter will find the next occurrence of a function in the search order after the current
+ # library. This allows one to provide a wrapper around a function in another shared
+ # library.
+ # --- Ubuntu Linux 8.04 dlsym(3)
+ handle = DL::Handle::NEXT
+ assert_not_nil handle['malloc']
+ rescue
+ # BSD
+ #
+ # If dlsym() is called with the special handle RTLD_NEXT, then the search
+ # for the symbol is limited to the shared objects which were loaded after
+ # the one issuing the call to dlsym(). Thus, if the function is called
+ # from the main program, all the shared libraries are searched. If it is
+ # called from a shared library, all subsequent shared libraries are
+ # searched. RTLD_NEXT is useful for implementing wrappers around library
+ # functions. For example, a wrapper function getpid() could access the
+ # "real" getpid() with dlsym(RTLD_NEXT, "getpid"). (Actually, the dlfunc()
+ # interface, below, should be used, since getpid() is a function and not a
+ # data object.)
+ # --- FreeBSD 8.0 dlsym(3)
+ require 'objspace'
+ handle = DL::Handle::NEXT
+ assert_not_nil handle['Init_objspace']
+ end
+ end
+
+ def test_DEFAULT
+ skip "DL::Handle::DEFAULT is not supported" if /mswin|mingw/ =~ RUBY_PLATFORM
+ handle = DL::Handle::DEFAULT
+ assert_not_nil handle['malloc']
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/dl/test_import.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/dl/test_import.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/dl/test_import.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,154 @@
+require_relative 'test_base'
+require 'dl/import'
+
+module DL
+ module LIBC
+ extend Importer
+ dlload LIBC_SO, LIBM_SO
+
+ typealias 'string', 'char*'
+ typealias 'FILE*', 'void*'
+
+ extern "void *strcpy(char*, char*)"
+ extern "int isdigit(int)"
+ extern "double atof(string)"
+ extern "unsigned long strtoul(char*, char **, int)"
+ extern "int qsort(void*, unsigned long, unsigned long, void*)"
+ extern "int fprintf(FILE*, char*)"
+ extern "int gettimeofday(timeval*, timezone*)" rescue nil
+
+ QsortCallback = bind("void *qsort_callback(void*, void*)", :temp)
+ BoundQsortCallback = bind("void *bound_qsort_callback(void*, void*)"){|ptr1,ptr2| ptr1[0] <=> ptr2[0]}
+ Timeval = struct [
+ "long tv_sec",
+ "long tv_usec",
+ ]
+ Timezone = struct [
+ "int tz_minuteswest",
+ "int tz_dsttime",
+ ]
+ MyStruct = struct [
+ "short num[5]",
+ "char c",
+ "unsigned char buff[7]",
+ ]
+
+ CallCallback = bind("void call_callback(void*, void*)"){|ptr1, ptr2|
+ f = Function.new(CFunc.new(ptr1.to_i, DL::TYPE_VOID, "<anonymous>"), [TYPE_VOIDP])
+ f.call(ptr2)
+ }
+ CarriedFunction = bind("void callback_function(void*)", :carried, 0)
+ end
+
+ class TestImport < TestBase
+ def test_malloc()
+ s1 = LIBC::Timeval.malloc()
+ s2 = LIBC::Timeval.malloc()
+ assert_not_equal(s1.to_ptr.to_i, s2.to_ptr.to_i)
+ end
+
+ def test_sizeof()
+ assert_equal(DL::SIZEOF_VOIDP, LIBC.sizeof("FILE*"))
+ assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(LIBC::MyStruct))
+ end
+
+ def test_unsigned_result()
+ d = (2 ** 31) + 1
+
+ r = LIBC.strtoul(d.to_s, 0, 0)
+ assert_equal(d, r)
+ end
+
+ def test_io()
+ if( RUBY_PLATFORM != DL::BUILD_RUBY_PLATFORM )
+ return
+ end
+ io_in,io_out = IO.pipe()
+ LIBC.fprintf(io_out, "hello")
+ io_out.flush()
+ io_out.close()
+ str = io_in.read()
+ io_in.close()
+ assert_equal("hello", str)
+ end
+
+ def test_value()
+ i = LIBC.value('int', 2)
+ assert_equal(2, i.value)
+
+ d = LIBC.value('double', 2.0)
+ assert_equal(2.0, d.value)
+
+ ary = LIBC.value('int[3]', [0,1,2])
+ assert_equal([0,1,2], ary.value)
+ end
+
+ def test_carried_function()
+ data1 = "data"
+ data2 = nil
+ LIBC.call_callback(LIBC::CarriedFunction, LIBC::CarriedFunction.create_carrier(data1)){|d|
+ data2 = d
+ }
+ assert_equal(data1, data2)
+ end
+
+ def test_struct()
+ s = LIBC::MyStruct.malloc()
+ s.num = [0,1,2,3,4]
+ s.c = ?a.ord
+ s.buff = "012345\377"
+ assert_equal([0,1,2,3,4], s.num)
+ assert_equal(?a.ord, s.c)
+ assert_equal([?0.ord,?1.ord,?2.ord,?3.ord,?4.ord,?5.ord,?\377.ord], s.buff)
+ end
+
+ def test_gettimeofday()
+ if( defined?(LIBC.gettimeofday) )
+ timeval = LIBC::Timeval.malloc()
+ timezone = LIBC::Timezone.malloc()
+ LIBC.gettimeofday(timeval, timezone)
+ cur = Time.now()
+ assert(cur.to_i - 2 <= timeval.tv_sec && timeval.tv_sec <= cur.to_i)
+ end
+ end
+
+ def test_strcpy()
+ buff = "000"
+ str = LIBC.strcpy(buff, "123")
+ assert_equal("123", buff)
+ assert_equal("123", str.to_s)
+ end
+
+ def test_isdigit()
+ r1 = LIBC.isdigit(?1.ord)
+ r2 = LIBC.isdigit(?2.ord)
+ rr = LIBC.isdigit(?r.ord)
+ assert_positive(r1)
+ assert_positive(r2)
+ assert_zero(rr)
+ end
+
+ def test_atof()
+ r = LIBC.atof("12.34")
+ assert_match(12.00..13.00, r)
+ end
+
+ def test_strtod()
+ f = Function.new(CFunc.new(@libc['strtod'], TYPE_DOUBLE, 'strtod'),
+ [TYPE_VOIDP, TYPE_VOIDP])
+ buff1 = "12.34"
+ buff2 = " "
+ r = f.call(buff1, buff2)
+ assert_match(12.00..13.00, r)
+ end
+
+ def test_qsort()
+ buff = "9341"
+ LIBC.qsort(buff, buff.size, 1, LIBC::QsortCallback){|ptr1,ptr2| ptr1[0] <=> ptr2[0]}
+ assert_equal("1349", buff)
+ buff = "9341"
+ LIBC.qsort(buff, buff.size, 1, LIBC::BoundQsortCallback)
+ assert_equal("1349", buff)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/dl/test_win32.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/dl/test_win32.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/dl/test_win32.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,54 @@
+require_relative 'test_base'
+require 'dl/import'
+require 'dl/types'
+
+class DL::TestWin32 < DL::TestBase
+module Win32API
+ extend DL::Importer
+
+ dlload "kernel32.dll"
+
+ include DL::Win32Types
+
+ OSVERSIONINFO = struct [
+ "DWORD dwOSVersionInfoSize",
+ "DWORD dwMajorVersion",
+ "DWORD dwMinorVersion",
+ "DWORD dwBuildNumber",
+ "DWORD dwPlatformId",
+ "UCHAR szCSDVersion[128]",
+ ]
+
+ typealias "POSVERSIONINFO", "OSVERSIONINFO*"
+
+ extern "BOOL GetVersionEx(POSVERSIONINFO)", :stdcall
+
+ def get_version_ex()
+ ptr = OSVERSIONINFO.malloc()
+ ptr.dwOSVersionInfoSize = OSVERSIONINFO.size
+ ret = GetVersionEx(ptr)
+ if( ret )
+ ptr
+ else
+ nil
+ end
+ end
+ module_function :get_version_ex
+rescue DL::DLError
+end
+
+if defined?(Win32API::OSVERSIONINFO)
+ def test_version()
+ platform = Win32API.get_version_ex().dwPlatformId
+ case ENV['OS']
+ when 'Windows_NT'
+ expect = 2
+ when /Windows.+/
+ expect = 1
+ else
+ expect = 0
+ end
+ assert_equal(expect, platform)
+ end
+end
+end
Added: MacRuby/trunk/test/test-mri/test/drb/drbtest.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/drbtest.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/drbtest.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,347 @@
+require 'test/unit'
+require 'drb/drb'
+require 'drb/extservm'
+require 'timeout'
+require 'shellwords'
+require_relative '../ruby/envutil'
+
+class DRbService
+ @@manager = DRb::ExtServManager.new
+ @@ruby = Shellwords.escape(EnvUtil.rubybin)
+ @@ruby += " -d" if $DEBUG
+ def self.add_service_command(nm)
+ dir = File.dirname(File.expand_path(__FILE__))
+ DRb::ExtServManager.command[nm] = "#{@@ruby} \"#{dir}/#{nm}\""
+ end
+
+ %w(ut_drb.rb ut_array.rb ut_port.rb ut_large.rb ut_safe1.rb ut_eval.rb).each do |nm|
+ add_service_command(nm)
+ end
+ @server = @@server = DRb::DRbServer.new('druby://localhost:0', @@manager, {})
+ @@manager.uri = @@server.uri
+ def self.manager
+ @@manager
+ end
+ def self.server
+ @server || @@server
+ end
+ def self.ext_service(name)
+ timeout(100, RuntimeError) do
+ manager.service(name)
+ end
+ end
+end
+
+class Onecky
+ include DRbUndumped
+ def initialize(n)
+ @num = n
+ end
+
+ def to_i
+ @num.to_i
+ end
+
+ def sleep(n)
+ Kernel.sleep(n)
+ to_i
+ end
+end
+
+class FailOnecky < Onecky
+ class OneckyError < RuntimeError; end
+ def to_i
+ raise(OneckyError, @num.to_s)
+ end
+end
+
+class XArray < Array
+ def initialize(ary)
+ ary.each do |x|
+ self.push(x)
+ end
+ end
+end
+
+module DRbCore
+ def setup
+ @ext = DRbService.ext_service('ut_drb.rb')
+ @there = @ext.front
+ end
+
+ def teardown
+ @ext.stop_service if @ext
+ end
+
+ def test_00_DRbObject
+ ro = DRbObject.new(nil, 'druby://localhost:12345')
+ assert_equal('druby://localhost:12345', ro.__drburi)
+ assert_equal(nil, ro.__drbref)
+
+ ro = DRbObject.new_with_uri('druby://localhost:12345')
+ assert_equal('druby://localhost:12345', ro.__drburi)
+ assert_equal(nil, ro.__drbref)
+
+ ro = DRbObject.new_with_uri('druby://localhost:12345?foobar')
+ assert_equal('druby://localhost:12345', ro.__drburi)
+ assert_equal(DRb::DRbURIOption.new('foobar'), ro.__drbref)
+ end
+
+ def test_01
+ assert_equal("hello", @there.hello)
+ onecky = Onecky.new('3')
+ assert_equal(6, @there.sample(onecky, 1, 2))
+ ary = @there.to_a
+ assert_kind_of(DRb::DRbObject, ary)
+
+ assert(@there.respond_to?(:to_a, true))
+ assert(@there.respond_to?(:eval, true))
+ assert(! @there.respond_to?(:eval, false))
+ assert(! @there.respond_to?(:eval))
+ end
+
+ def test_01_02_loop
+ onecky = Onecky.new('3')
+ 50.times do
+ assert_equal(6, @there.sample(onecky, 1, 2))
+ ary = @there.to_a
+ assert_kind_of(DRb::DRbObject, ary)
+ end
+ end
+
+ def test_02_unknown
+ obj = @there.unknown_class
+ assert_kind_of(DRb::DRbUnknown, obj)
+ assert_equal('Unknown2', obj.name)
+
+ obj = @there.unknown_module
+ assert_kind_of(DRb::DRbUnknown, obj)
+ if RUBY_VERSION >= '1.8'
+ assert_equal('DRbEx::', obj.name)
+ else
+ assert_equal('DRbEx', obj.name)
+ end
+
+ assert_raise(DRb::DRbUnknownError) do
+ @there.unknown_error
+ end
+
+ onecky = FailOnecky.new('3')
+
+ assert_raise(FailOnecky::OneckyError) do
+ @there.sample(onecky, 1, 2)
+ end
+ end
+
+ def test_03
+ assert_equal(8, @there.sum(1, 1, 1, 1, 1, 1, 1, 1))
+ assert_raise(DRb::DRbConnError) do
+ @there.sum(1, 1, 1, 1, 1, 1, 1, 1, 1)
+ end
+ assert_raise(DRb::DRbConnError) do
+ @there.sum('1' * 4096)
+ end
+ end
+
+ def test_04
+ assert_respond_to(@there, 'sum')
+ assert(!(@there.respond_to? "foobar"))
+ end
+
+ def test_05_eq
+ a = @there.to_a[0]
+ b = @there.to_a[0]
+ assert(a.object_id != b.object_id)
+ assert(a == b)
+ assert_equal(a, b)
+ assert(a == @there)
+ assert_equal(a.hash, b.hash)
+ assert_equal(a.hash, @there.hash)
+ assert(a.eql?(b))
+ assert(a.eql?(@there))
+ end
+
+ def test_06_timeout
+ ten = Onecky.new(10)
+ assert_raise(TimeoutError) do
+ @there.do_timeout(ten)
+ end
+ assert_raise(TimeoutError) do
+ @there.do_timeout(ten)
+ end
+ end
+
+ def test_07_public_private_protected_missing
+ assert_nothing_raised() {
+ begin
+ @there.method_missing(:eval, 'nil')
+ rescue NoMethodError
+ assert_match(/^private method \`eval\'/, $!.message)
+ end
+ }
+ assert_nothing_raised() {
+ begin
+ @there.call_private_method
+ rescue NoMethodError
+ assert_equal(NoMethodError, $!.class)
+ assert_match(/^private method \`call_private_method\'/, $!.message)
+ end
+ }
+ assert_nothing_raised() {
+ begin
+ @there.call_protected_method
+ rescue NoMethodError
+ assert_equal(NoMethodError, $!.class)
+ assert_match(/^protected method \`call_protected_method\'/, $!.message)
+ end
+ }
+ assert_nothing_raised() {
+ begin
+ @there.method_missing(:undefined_method_test)
+ rescue NoMethodError
+ assert_equal(NoMethodError, $!.class)
+ assert_match(/^undefined method \`undefined_method_test\'/, $!.message)
+ end
+ }
+ assert_raise(DRb::DRbConnError) do
+ @there.method_missing(:__send__, :to_s)
+ end
+ assert_equal(true, @there.missing)
+ end
+
+ def test_08_here
+ ro = DRbObject.new(nil, DRb.uri)
+ assert_kind_of(String, ro.to_s)
+
+ ro = DRbObject.new_with_uri(DRb.uri)
+ assert_kind_of(String, ro.to_s)
+ end
+
+ def uri_concat_option(uri, opt)
+ "#{uri}?#{opt}"
+ end
+
+ def test_09_option
+ uri = uri_concat_option(@there.__drburi, "foo")
+ ro = DRbObject.new_with_uri(uri)
+ assert_equal(ro.__drburi, @there.__drburi)
+ assert_equal(3, ro.size)
+
+ uri = uri_concat_option(@there.__drburi, "")
+ ro = DRbObject.new_with_uri(uri)
+ assert_equal(ro.__drburi, @there.__drburi)
+ assert_equal(DRb::DRbURIOption.new(''), ro.__drbref)
+
+ uri = uri_concat_option(@there.__drburi, "hello?world")
+ ro = DRbObject.new_with_uri(uri)
+ assert_equal(DRb::DRbURIOption.new('hello?world'), ro.__drbref)
+
+ uri = uri_concat_option(@there.__drburi, "?hello?world")
+ ro = DRbObject.new_with_uri(uri)
+ assert_equal(DRb::DRbURIOption.new('?hello?world'), ro.__drbref)
+ end
+
+ def test_10_yield
+ @there.simple_hash.each do |k, v|
+ assert_kind_of(String, k)
+ assert_kind_of(Symbol, v)
+ end
+ end
+
+ def test_10_yield_undumped
+ @there.xarray2_hash.each do |k, v|
+ assert_kind_of(String, k)
+ assert_kind_of(DRbObject, v)
+ end
+ end
+
+ def test_11_remote_no_method_error
+ assert_raise(DRb::DRbRemoteError) do
+ @there.remote_no_method_error
+ end
+ begin
+ @there.remote_no_method_error
+ rescue
+ error = $!
+ assert_match(/^undefined method .*\(NoMethodError\)/, error.message)
+ assert_equal('NoMethodError', error.reason)
+ end
+ end
+end
+
+module DRbAry
+ def setup
+ @ext = DRbService.ext_service('ut_array.rb')
+ @there = @ext.front
+ end
+
+ def teardown
+ @ext.stop_service if @ext
+ end
+
+ def test_01
+ assert_kind_of(DRb::DRbObject, @there)
+ end
+
+ def test_02_collect
+ ary = @there.collect do |x| x + x end
+ assert_kind_of(Array, ary)
+ assert_equal([2, 4, 'IIIIII', 8, 'fivefive', 12], ary)
+ end
+
+ def test_03_redo
+ ary = []
+ count = 0
+ @there.each do |x|
+ count += 1
+ ary.push x
+ redo if count == 3
+ end
+ assert_equal([1, 2, 'III', 'III', 4, 'five', 6], ary)
+ end
+
+ # retry in block is not supported on ruby 1.9
+ #def test_04_retry
+ # retried = false
+ # ary = []
+ # @there.each do |x|
+ # ary.push x
+ # if x == 4 && !retried
+ # retried = true
+ # retry
+ # end
+ # end
+ # assert_equal([1, 2, 'III', 4, 1, 2, 'III', 4, 'five', 6], ary)
+ #end
+
+ def test_05_break
+ ary = []
+ @there.each do |x|
+ ary.push x
+ break if x == 4
+ end
+ assert_equal([1, 2, 'III', 4], ary)
+ end
+
+ def test_06_next
+ ary = []
+ @there.each do |x|
+ next if String === x
+ ary.push x
+ end
+ assert_equal([1, 2, 4, 6], ary)
+ end
+
+ class_eval <<EOS
+ def test_07_break_18
+ ary = []
+ result = @there.each do |x|
+ ary.push x
+ break(:done) if x == 4
+ end
+ assert_equal([1, 2, 'III', 4], ary)
+ assert_equal(:done, result)
+ end
+EOS
+
+end
Added: MacRuby/trunk/test/test-mri/test/drb/ignore_test_drb.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/ignore_test_drb.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/ignore_test_drb.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,24 @@
+require 'drbtest'
+
+class TestDRbReusePort < Test::Unit::TestCase
+ include DRbAry
+
+ def setup
+ @ext = DRbService.ext_service('ut_port.rb')
+ @there = @ext.front
+ end
+
+ def teardown
+ return unless @ext
+ @ext.stop_service
+ while true
+ sleep 0.1
+ begin
+ @ext.alive?
+ rescue DRb::DRbConnError
+ break
+ end
+ end
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/drb/test_acl.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/test_acl.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/test_acl.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,195 @@
+# acltest.rb - ACL unit test
+# Copyright (c) 2000 Masatoshi SEKI
+#
+# acltest.rb is copyrighted free software by Masatoshi SEKI.
+# You can redistribute it and/or modify it under the same terms as Ruby.
+
+require 'test/unit'
+require 'drb/acl'
+
+class SampleHosts
+ def initialize
+ list = %w(127.0.0.1 localhost
+ 192.168.1.1 x68k.linux.or.jp
+ 192.168.1.2 lc630.macos.or.jp
+ 192.168.1.3 lib30.win32.or.jp
+ 192.168.1.4 ns00.linux.or.jp
+ 192.168.1.5 yum.macos.or.jp
+ ::ffff:192.168.1.5 ipv6.macos.or.jp
+ ::192.168.1.5 too.yumipv6.macos.or.jp
+ 192.168.1.254 comstarz.foo.or.jp)
+
+ @hostlist = Array.new(list.size / 2)
+ @hostlist.each_index do |idx|
+ @hostlist[idx] = ["AF_INET", 10000, list[idx * 2 + 1], list[idx * 2]]
+ end
+
+ @hosts = Hash.new
+ @hostlist.each do |h|
+ @hosts[h[2].split('.')[0]] = h
+ end
+ end
+ attr_reader(:hostlist, :hosts)
+end
+
+
+class ACLEntryTest < Test::Unit::TestCase
+ HOSTS = SampleHosts.new
+
+ def setup
+ @hostlist = HOSTS.hostlist
+ @hosts = HOSTS.hosts
+ end
+
+ def test_all
+ a = ACL::ACLEntry.new("*")
+ b = ACL::ACLEntry.new("all")
+ @hostlist.each do |h|
+ assert(a.match(h))
+ assert(b.match(h))
+ end
+ end
+
+ def test_ip_v6
+ a = ACL::ACLEntry.new('::ffff:192.0.0.0/104')
+ assert(! a.match(@hosts['localhost']))
+ assert(a.match(@hosts['yum']))
+ assert(a.match(@hosts['ipv6']))
+ assert(! a.match(@hosts['too']))
+ end
+
+ def test_ip
+ a = ACL::ACLEntry.new('192.0.0.0/8')
+ assert(! a.match(@hosts['localhost']))
+ assert(a.match(@hosts['yum']))
+
+ a = ACL::ACLEntry.new('192.168.0.1/255.255.0.255')
+ assert(! a.match(@hosts['localhost']))
+ assert(! a.match(@hosts['yum']))
+ assert(a.match(@hosts['x68k']))
+
+ a = ACL::ACLEntry.new('192.168.1.0/24')
+ assert(! a.match(@hosts['localhost']))
+ assert(a.match(@hosts['yum']))
+ assert(a.match(@hosts['x68k']))
+
+ a = ACL::ACLEntry.new('92.0.0.0/8')
+ assert(! a.match(@hosts['localhost']))
+ assert(! a.match(@hosts['yum']))
+ assert(! a.match(@hosts['x68k']))
+
+ a = ACL::ACLEntry.new('127.0.0.1/255.0.0.255')
+ assert(a.match(@hosts['localhost']))
+ assert(! a.match(@hosts['yum']))
+ assert(! a.match(@hosts['x68k']))
+ end
+
+ def test_name
+ a = ACL::ACLEntry.new('*.jp')
+ assert(! a.match(@hosts['localhost']))
+ assert(a.match(@hosts['yum']))
+
+ a = ACL::ACLEntry.new('yum.*.jp')
+ assert(a.match(@hosts['yum']))
+ assert(! a.match(@hosts['lc630']))
+
+ a = ACL::ACLEntry.new('*.macos.or.jp')
+ assert(a.match(@hosts['yum']))
+ assert(a.match(@hosts['lc630']))
+ assert(! a.match(@hosts['lib30']))
+ end
+end
+
+class ACLListTest < Test::Unit::TestCase
+ HOSTS = SampleHosts.new
+
+ def setup
+ @hostlist = HOSTS.hostlist
+ @hosts = HOSTS.hosts
+ end
+
+ private
+ def build(list)
+ acl= ACL::ACLList.new
+ list.each do |s|
+ acl.add s
+ end
+ acl
+ end
+
+ public
+ def test_all_1
+ a = build(%w(all))
+ @hostlist.each do |h|
+ assert(a.match(h))
+ end
+ end
+
+ def test_all_2
+ a = build(%w(localhost 127.0.0.0/8 yum.* *))
+ @hostlist.each do |h|
+ assert(a.match(h))
+ end
+ end
+
+ def test_1
+ a = build(%w(192.0.0.1/255.0.0.255 yum.*.jp))
+ assert(a.match(@hosts['yum']))
+ assert(a.match(@hosts['x68k']))
+ assert(! a.match(@hosts['lc630']))
+ end
+
+ def test_2
+ a = build(%w(*.linux.or.jp))
+ assert(!a.match(@hosts['yum']))
+ assert(a.match(@hosts['x68k']))
+ assert(!a.match(@hosts['lc630']))
+ end
+end
+
+class ACLTest < Test::Unit::TestCase
+ HOSTS = SampleHosts.new
+
+ def setup
+ @hostlist = HOSTS.hostlist
+ @hosts = HOSTS.hosts
+ end
+
+ def test_0
+ a = ACL.new
+ @hostlist.each do |h|
+ assert(a.allow_addr?(h))
+ end
+ end
+
+ def test_not_0
+ a = ACL.new([], ACL::ALLOW_DENY)
+ @hostlist.each do |h|
+ assert(! a.allow_addr?(h))
+ end
+ end
+
+ def test_1
+ data = %w(deny all
+ allow localhost
+ allow x68k.*)
+
+ a = ACL.new(data)
+ assert(a.allow_addr?(@hosts['x68k']))
+ assert(a.allow_addr?(@hosts['localhost']))
+ assert(! a.allow_addr?(@hosts['lc630']))
+ end
+
+ def test_not_1
+ data = %w(deny 192.0.0.0/8
+ allow localhost
+ allow x68k.*)
+
+ a = ACL.new(data, ACL::ALLOW_DENY)
+ assert(!a.allow_addr?(@hosts['x68k']))
+ assert(a.allow_addr?(@hosts['localhost']))
+ assert(! a.allow_addr?(@hosts['lc630']))
+ end
+end
+
+
Added: MacRuby/trunk/test/test-mri/test/drb/test_drb.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/test_drb.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/test_drb.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,304 @@
+puts "[BUG : #???] Timeout, MacRuby don't finish #{$0}"
+__END__
+
+require_relative 'drbtest'
+
+class TestDRbCore < Test::Unit::TestCase
+ include DRbCore
+end
+
+class TestDRbYield < Test::Unit::TestCase
+ def setup
+ @ext = DRbService.ext_service('ut_drb.rb')
+ @there = @ext.front
+ end
+
+ def teardown
+ @ext.stop_service if @ext
+ end
+
+ def test_01_one
+ @there.echo_yield_1([]) {|one|
+ assert_equal([], one)
+ }
+
+ @there.echo_yield_1(1) {|one|
+ assert_equal(1, one)
+ }
+
+ @there.echo_yield_1(nil) {|one|
+ assert_equal(nil, one)
+ }
+ end
+
+ def test_02_two
+ @there.echo_yield_2([], []) {|one, two|
+ assert_equal([], one)
+ assert_equal([], two)
+ }
+
+ @there.echo_yield_2(1, 2) {|one, two|
+ assert_equal(1, one)
+ assert_equal(2, two)
+ }
+
+ @there.echo_yield_2(3, nil) {|one, two|
+ assert_equal(3, one)
+ assert_equal(nil, two)
+ }
+
+ @there.echo_yield_1([:key, :value]) {|one, two|
+ assert_equal(:key, one)
+ assert_equal(:value, two)
+ }
+ end
+
+ def test_03_many
+ @there.echo_yield_0 {|*s|
+ assert_equal([], s)
+ }
+ @there.echo_yield(nil) {|*s|
+ assert_equal([nil], s)
+ }
+ @there.echo_yield(1) {|*s|
+ assert_equal([1], s)
+ }
+ @there.echo_yield(1, 2) {|*s|
+ assert_equal([1, 2], s)
+ }
+ @there.echo_yield(1, 2, 3) {|*s|
+ assert_equal([1, 2, 3], s)
+ }
+ @there.echo_yield([], []) {|*s|
+ assert_equal([[], []], s)
+ }
+ @there.echo_yield([]) {|*s|
+ assert_equal([[]], s) # !
+ }
+ end
+
+ def test_04_many_to_one
+ @there.echo_yield_0 {|*s|
+ assert_equal([], s)
+ }
+ @there.echo_yield(nil) {|*s|
+ assert_equal([nil], s)
+ }
+ @there.echo_yield(1) {|*s|
+ assert_equal([1], s)
+ }
+ @there.echo_yield(1, 2) {|*s|
+ assert_equal([1, 2], s)
+ }
+ @there.echo_yield(1, 2, 3) {|*s|
+ assert_equal([1, 2, 3], s)
+ }
+ @there.echo_yield([], []) {|*s|
+ assert_equal([[], []], s)
+ }
+ @there.echo_yield([]) {|*s|
+ assert_equal([[]], s)
+ }
+ end
+
+ def test_05_array_subclass
+ @there.xarray_each {|x| assert_kind_of(XArray, x)}
+ @there.xarray_each {|*x| assert_kind_of(XArray, x[0])}
+ end
+
+ def test_06_taint
+ x = proc {}
+ assert(! x.tainted?)
+ @there.echo_yield(x) {|o|
+ assert_equal(x, o)
+ assert(! x.tainted?)
+ }
+ end
+end
+
+class TestDRbRubyYield < TestDRbYield
+ def echo_yield(*arg)
+ yield(*arg)
+ end
+
+ def echo_yield_0
+ yield
+ end
+
+ def echo_yield_1(a)
+ yield(a)
+ end
+
+ def echo_yield_2(a, b)
+ yield(a, b)
+ end
+
+ def xarray_each
+ xary = [XArray.new([0])]
+ xary.each do |x|
+ yield(x)
+ end
+ end
+
+ def setup
+ @there = self
+ end
+
+ def teardown
+ end
+end
+
+class TestDRbRuby18Yield < TestDRbRubyYield
+ class YieldTest18
+ def echo_yield(*arg, &proc)
+ proc.call(*arg)
+ end
+
+ def echo_yield_0(&proc)
+ proc.call
+ end
+
+ def echo_yield_1(a, &proc)
+ proc.call(a)
+ end
+
+ def echo_yield_2(a, b, &proc)
+ proc.call(a, b)
+ end
+
+ def xarray_each(&proc)
+ xary = [XArray.new([0])]
+ xary.each(&proc)
+ end
+
+ end
+
+ def setup
+ @there = YieldTest18.new
+ end
+end
+
+class TestDRbAry < Test::Unit::TestCase
+ include DRbAry
+end
+
+class TestDRbMServer < Test::Unit::TestCase
+ def setup
+ @ext = DRbService.ext_service('ut_drb.rb')
+ @there = @ext.front
+ @server = (1..3).collect do |n|
+ DRb::DRbServer.new(nil, Onecky.new(n.to_s))
+ end
+ end
+
+ def teardown
+ @server.each do |s|
+ s.stop_service
+ end
+ @ext.stop_service if @ext
+ end
+
+ def test_01
+ assert_equal(6, @there.sample(@server[0].front, @server[1].front, @server[2].front))
+ end
+end
+
+class TestDRbSafe1 < TestDRbAry
+ def setup
+ @ext = DRbService.ext_service('ut_safe1.rb')
+ @there = @ext.front
+ end
+end
+
+class TestDRbEval # < Test::Unit::TestCase
+ def setup
+ super
+ @ext = DRbService.ext_service('ut_eval.rb')
+ @there = @ext.front
+ end
+
+ def teardown
+ @ext.stop_service if @ext
+ end
+
+ def test_01_safe1_safe4_eval
+ assert_raise(SecurityError) do
+ @there.method_missing(:instance_eval, 'ENV.inspect')
+ end
+
+ assert_raise(SecurityError) do
+ @there.method_missing(:send, :eval, 'ENV.inspect')
+ end
+
+ remote_class = @there.remote_class
+
+ assert_raise(SecurityError) do
+ remote_class.class_eval('ENV.inspect')
+ end
+
+ assert_raise(SecurityError) do
+ remote_class.module_eval('ENV.inspect')
+ end
+
+ four = @there.four
+ assert_equal(1, four.method_missing(:send, :eval, '1'))
+
+ remote_class = four.remote_class
+
+ assert_equal(1, remote_class.class_eval('1'))
+
+ assert_equal(1, remote_class.module_eval('1'))
+
+ assert_raise(SecurityError) do
+ remote_class.class_eval('ENV = {}')
+ end
+
+ assert_raise(SecurityError) do
+ remote_class.module_eval('ENV = {}')
+ end
+ end
+end
+
+class TestDRbLarge < Test::Unit::TestCase
+ def setup
+ @ext = DRbService.ext_service('ut_large.rb')
+ @there = @ext.front
+ end
+
+ def teardown
+ @ext.stop_service if @ext
+ end
+
+ def test_01_large_ary
+ ary = [2] * 10240
+ assert_equal(10240, @there.size(ary))
+ assert_equal(20480, @there.sum(ary))
+ end
+
+ def test_02_large_ary
+ ary = ["Hello, World"] * 10240
+ assert_equal(10240, @there.size(ary))
+ end
+
+ def test_03_large_ary
+ ary = [Thread.current] * 10240
+ assert_equal(10240, @there.size(ary))
+ end
+
+ def test_04_many_arg
+ assert_raise(DRb::DRbConnError) {
+ @there.arg_test(1, 2, 3, 4, 5, 6, 7, 8, 9, 0)
+ }
+ end
+
+ def test_05_too_large_ary
+ ary = ["Hello, World"] * 102400
+ exception = nil
+ begin
+ @there.size(ary)
+ rescue StandardError
+ exception = $!
+ end
+ assert_kind_of(StandardError, exception)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/drb/test_drbssl.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/test_drbssl.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/test_drbssl.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,65 @@
+puts "[BUG : #???] Timeout, MacRuby don't finish #{$0}"
+__END__
+
+require_relative 'drbtest'
+
+begin
+ require 'drb/ssl'
+rescue LoadError
+end
+
+if Object.const_defined?("OpenSSL")
+
+
+class DRbSSLService < DRbService
+ %w(ut_drb_drbssl.rb ut_array_drbssl.rb).each do |nm|
+ add_service_command(nm)
+ end
+ config = Hash.new
+
+ config[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
+ config[:SSLVerifyCallback] = lambda{ |ok,x509_store|
+ true
+ }
+ begin
+ data = open("sample.key"){|io| io.read }
+ config[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(data)
+ data = open("sample.crt"){|io| io.read }
+ config[:SSLCertificate] = OpenSSL::X509::Certificate.new(data)
+ rescue
+ # $stderr.puts "Switching to use self-signed certificate"
+ config[:SSLCertName] =
+ [ ["C","JP"], ["O","Foo.DRuby.Org"], ["CN", "Sample"] ]
+ end
+
+ uri = ARGV.shift if $0 == __FILE__
+ @server = DRb::DRbServer.new(uri || 'drbssl://:0', self.manager, config)
+end
+
+class TestDRbSSLCore < Test::Unit::TestCase
+ include DRbCore
+ def setup
+ @ext = DRbSSLService.ext_service('ut_drb_drbssl.rb')
+ @there = @ext.front
+ end
+
+ def test_02_unknown
+ end
+
+ def test_01_02_loop
+ end
+
+ def test_05_eq
+ end
+end
+
+class TestDRbSSLAry < Test::Unit::TestCase
+ include DRbAry
+ def setup
+ @ext = DRbSSLService.ext_service('ut_array_drbssl.rb')
+ @there = @ext.front
+ end
+end
+
+
+end
Added: MacRuby/trunk/test/test-mri/test/drb/test_drbunix.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/test_drbunix.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/test_drbunix.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,49 @@
+puts "[BUG : #???] Timeout, MacRuby don't finish #{$0}"
+__END__
+
+require_relative 'drbtest'
+
+begin
+ require 'drb/unix'
+rescue LoadError
+end
+
+if Object.const_defined?("UNIXServer")
+
+
+class DRbUNIXService < DRbService
+ %w(ut_drb_drbunix.rb ut_array_drbunix.rb).each do |nm|
+ add_service_command(nm)
+ end
+
+ uri = ARGV.shift if $0 == __FILE__
+ @server = DRb::DRbServer.new(uri || 'drbunix:', self.manager, {})
+end
+
+class TestDRbUNIXCore < Test::Unit::TestCase
+ include DRbCore
+ def setup
+ @ext = DRbUNIXService.ext_service('ut_drb_drbunix.rb')
+ @there = @ext.front
+ end
+
+ def test_02_unknown
+ end
+
+ def test_01_02_loop
+ end
+
+ def test_05_eq
+ end
+end
+
+class TestDRbUNIXAry < Test::Unit::TestCase
+ include DRbAry
+ def setup
+ @ext = DRbUNIXService.ext_service('ut_array_drbunix.rb')
+ @there = @ext.front
+ end
+end
+
+
+end
Added: MacRuby/trunk/test/test-mri/test/drb/ut_array.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/ut_array.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/ut_array.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,15 @@
+require 'drb/drb'
+require 'drb/extserv'
+
+if __FILE__ == $0
+ def ARGV.shift
+ it = super()
+ raise "usage: #{$0} <uri> <name>" unless it
+ it
+ end
+
+ DRb.start_service(nil, [1, 2, 'III', 4, "five", 6])
+ es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
+ DRb.thread.join
+end
+
Added: MacRuby/trunk/test/test-mri/test/drb/ut_array_drbssl.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/ut_array_drbssl.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/ut_array_drbssl.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,24 @@
+require 'drb/drb'
+require 'drb/extserv'
+require 'drb/ssl'
+
+if __FILE__ == $0
+ def ARGV.shift
+ it = super()
+ raise "usage: #{$0} <uri> <name>" unless it
+ it
+ end
+
+ config = Hash.new
+ config[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
+ config[:SSLVerifyCallback] = lambda{|ok,x509_store|
+ true
+ }
+ config[:SSLCertName] =
+ [ ["C","JP"], ["O","Foo.DRuby.Org"], ["CN", "Sample"] ]
+
+ DRb.start_service('drbssl://:0', [1, 2, 'III', 4, "five", 6], config)
+ es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
+ DRb.thread.join
+end
+
Added: MacRuby/trunk/test/test-mri/test/drb/ut_array_drbunix.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/ut_array_drbunix.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/ut_array_drbunix.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,15 @@
+require 'drb/drb'
+require 'drb/extserv'
+
+if __FILE__ == $0
+ def ARGV.shift
+ it = super()
+ raise "usage: #{$0} <uri> <name>" unless it
+ it
+ end
+
+ DRb.start_service('drbunix:', [1, 2, 'III', 4, "five", 6])
+ es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
+ DRb.thread.join
+end
+
Added: MacRuby/trunk/test/test-mri/test/drb/ut_drb.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/ut_drb.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/ut_drb.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,160 @@
+require 'drb/drb'
+require 'drb/extserv'
+require 'timeout'
+
+class XArray < Array
+ def initialize(ary)
+ ary.each do |x|
+ self.push(x)
+ end
+ end
+end
+
+class XArray2 < XArray
+ include DRbUndumped
+end
+
+class Unknown2
+ def initialize
+ @foo = 'unknown2'
+ end
+end
+
+class DRbEx
+ include DRbUndumped
+
+ class FooBar
+ def initialize
+ @foo = 'bar'
+ end
+ end
+
+ class UError < RuntimeError; end
+
+ def initialize
+ @hello = 'hello'
+ end
+ attr_reader :hello
+
+ def sample(a, b, c)
+ a.to_i + b.to_i + c.to_i
+ end
+
+ def sum(*a)
+ s = 0
+ a.each do |e|
+ s += e.to_i
+ end
+ s
+ end
+
+ def do_timeout(n)
+ timeout(0.1) do
+ n.sleep(2)
+ end
+ end
+
+ def unknown_module
+ FooBar.new
+ end
+
+ def unknown_class
+ Unknown2.new
+ end
+
+ def unknown_error
+ raise UError
+ end
+
+ def remote_no_method_error
+ invoke_no_method(self)
+ end
+
+ def test_yield
+ yield
+ yield([])
+ yield(*[])
+ end
+
+ def echo_yield(*arg)
+ yield(*arg)
+ nil
+ end
+
+ def echo_yield_0
+ yield
+ nil
+ end
+
+ def echo_yield_1(one)
+ yield(one)
+ nil
+ end
+
+ def echo_yield_2(one, two)
+ yield(one, two)
+ nil
+ end
+
+ def xarray_each
+ xary = [XArray.new([0])]
+ xary.each do |x|
+ yield(x)
+ end
+ nil
+ end
+
+ def xarray2_hash
+ unless @xary2_hash
+ @xary2_hash = { "a" => XArray2.new([0]), "b" => XArray2.new([1]) }
+ end
+ DRbObject.new(@xary2_hash)
+ end
+
+ def simple_hash
+ unless @hash
+ @hash = { 'a'=>:a, 'b'=>:b }
+ end
+ DRbObject.new(@hash)
+ end
+
+ def [](key)
+ key.to_s
+ end
+
+ def to_a
+ [self]
+ end
+
+ def method_missing(msg, *a, &b)
+ if msg == :missing
+ return true
+ else
+ super(msg, *a, &b)
+ end
+ end
+
+ private
+ def call_private_method
+ true
+ end
+
+ protected
+ def call_protected_method
+ true
+ end
+end
+
+if __FILE__ == $0
+ def ARGV.shift
+ it = super()
+ raise "usage: #{$0} <manager-uri> <name>" unless it
+ it
+ end
+
+ DRb::DRbServer.default_argc_limit(8)
+ DRb::DRbServer.default_load_limit(4096)
+ DRb.start_service('druby://localhost:0', DRbEx.new)
+ es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
+ DRb.thread.join
+end
Added: MacRuby/trunk/test/test-mri/test/drb/ut_drb_drbssl.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/ut_drb_drbssl.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/ut_drb_drbssl.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,25 @@
+require "#{File.dirname(File.expand_path(__FILE__))}/ut_drb"
+require 'drb/ssl'
+
+if __FILE__ == $0
+ def ARGV.shift
+ it = super()
+ raise "usage: #{$0} <manager-uri> <name>" unless it
+ it
+ end
+
+ config = Hash.new
+ config[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
+ config[:SSLVerifyCallback] = lambda{|ok,x509_store|
+ true
+ }
+ config[:SSLCertName] =
+ [ ["C","JP"], ["O","Foo.DRuby.Org"], ["CN", "Sample"] ]
+
+ DRb::DRbServer.default_argc_limit(8)
+ DRb::DRbServer.default_load_limit(4096)
+ DRb.start_service('drbssl://localhost:0', DRbEx.new, config)
+ es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
+ DRb.thread.join
+end
+
Added: MacRuby/trunk/test/test-mri/test/drb/ut_drb_drbunix.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/ut_drb_drbunix.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/ut_drb_drbunix.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,16 @@
+require "#{File.dirname(File.expand_path(__FILE__))}/ut_drb"
+
+if __FILE__ == $0
+ def ARGV.shift
+ it = super()
+ raise "usage: #{$0} <manager-uri> <name>" unless it
+ it
+ end
+
+ DRb::DRbServer.default_argc_limit(8)
+ DRb::DRbServer.default_load_limit(4096)
+ DRb.start_service('drbunix:', DRbEx.new)
+ es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
+ DRb.thread.join
+end
+
Added: MacRuby/trunk/test/test-mri/test/drb/ut_eval.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/ut_eval.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/ut_eval.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,31 @@
+require 'drb/drb'
+require 'drb/extserv'
+
+class EvalAttack
+ def initialize
+ @four = DRb::DRbServer.new('druby://localhost:0', self, {:safe_level => 4})
+ end
+
+ def four
+ DRbObject.new_with_uri(@four.uri)
+ end
+
+ def remote_class
+ DRbObject.new(self.class)
+ end
+end
+
+
+if __FILE__ == $0
+ def ARGV.shift
+ it = super()
+ raise "usage: #{$0} <uri> <name>" unless it
+ it
+ end
+
+ $SAFE = 1
+
+ DRb.start_service('druby://localhost:0', EvalAttack.new, {:safe_level => 2})
+ es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
+ DRb.thread.join
+end
Added: MacRuby/trunk/test/test-mri/test/drb/ut_large.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/ut_large.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/ut_large.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,38 @@
+require 'drb/drb'
+require 'drb/extserv'
+require 'timeout'
+
+class DRbLarge
+ include DRbUndumped
+
+ def size(ary)
+ ary.size
+ end
+
+ def sum(ary)
+ sum = 0
+ ary.each do |e|
+ sum += e.to_i
+ end
+ sum
+ end
+
+ def arg_test(*arg)
+ # nop
+ end
+end
+
+if __FILE__ == $0
+ def ARGV.shift
+ it = super()
+ raise "usage: #{$0} <manager-uri> <name>" unless it
+ it
+ end
+
+ DRb::DRbServer.default_argc_limit(3)
+ DRb::DRbServer.default_load_limit(100000)
+ DRb.start_service('druby://localhost:0', DRbLarge.new)
+ es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
+ DRb.thread.join
+end
+
Added: MacRuby/trunk/test/test-mri/test/drb/ut_port.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/ut_port.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/ut_port.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,14 @@
+require 'drb/drb'
+require 'drb/extserv'
+
+if __FILE__ == $0
+ def ARGV.shift
+ it = super()
+ raise "usage: #{$0} <uri> <name>" unless it
+ it
+ end
+
+ DRb.start_service('druby://:8473', [1, 2, 'III', 4, "five", 6])
+ es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
+ DRb.thread.join
+end
Added: MacRuby/trunk/test/test-mri/test/drb/ut_safe1.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/ut_safe1.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/ut_safe1.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,15 @@
+require 'drb/drb'
+require 'drb/extserv'
+
+if __FILE__ == $0
+ def ARGV.shift
+ it = super()
+ raise "usage: #{$0} <uri> <name>" unless it
+ it
+ end
+
+ DRb.start_service('druby://localhost:0', [1, 2, 'III', 4, "five", 6],
+ {:safe_level => 1})
+ es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
+ DRb.thread.join
+end
Added: MacRuby/trunk/test/test-mri/test/drb/ut_timerholder.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/drb/ut_timerholder.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/drb/ut_timerholder.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,49 @@
+require 'runit/testcase'
+require 'runit/cui/testrunner'
+require 'timerholder'
+
+class TimerHolderTest < RUNIT::TestCase
+ def do_test(timeout, keeper_sleep = nil)
+ holder = TimerHolder.new(timeout)
+ holder.keeper_sleep = keeper_sleep if keeper_sleep
+ key = holder.add(self)
+ sleep(timeout * 0.5)
+ assert_equal(holder.peek(key), self)
+ holder.delete(key)
+ assert(!holder.include?(key))
+ key = holder.add(self)
+ sleep(timeout+0.5)
+ assert_equal(holder.fetch(key), nil)
+ key = holder.add(self)
+ assert_equal(holder.fetch(key), self)
+ holder.store(key, true)
+ assert_equal(holder.fetch(key), true)
+ assert_equal(holder.include?(key), true)
+ sleep(timeout+0.5)
+ assert_exception(TimerHolder::InvalidIndexError) do
+ holder.store(key, 1)
+ end
+ assert_equal(holder.include?(key), false)
+ key = holder.add(self)
+ sleep(timeout * 0.5)
+ assert(holder.include?(key))
+ holder.extend(key, timeout)
+ sleep(timeout * 0.5)
+ assert(holder.include?(key))
+ sleep(timeout * 0.6)
+ assert(!holder.include?(key))
+ holder.delete(key)
+ end
+
+ def test_00
+ do_test(0.5)
+ end
+
+ def test_01
+ do_test(1, 0.5)
+ end
+end
+
+if __FILE__ == $0
+ RUNIT::CUI::TestRunner.run(TimerHolderTest.suite)
+end
Added: MacRuby/trunk/test/test-mri/test/erb/hello.erb
===================================================================
--- MacRuby/trunk/test/test-mri/test/erb/hello.erb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/erb/hello.erb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,4 @@
+= hello
+<% 3.times do |n| %>
+* <%= n %>
+<% end %>
Added: MacRuby/trunk/test/test-mri/test/erb/test_erb.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/erb/test_erb.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/erb/test_erb.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,464 @@
+require 'test/unit'
+require 'erb'
+
+class TestERB < Test::Unit::TestCase
+ class MyError < RuntimeError ; end
+
+ def test_without_filename
+ erb = ERB.new("<% raise ::TestERB::MyError %>")
+ e = assert_raise(MyError) {
+ erb.result
+ }
+ assert_match(/\A\(erb\):1\b/, e.backtrace[0])
+ end
+
+ def test_with_filename
+ erb = ERB.new("<% raise ::TestERB::MyError %>")
+ erb.filename = "test filename"
+ e = assert_raise(MyError) {
+ erb.result
+ }
+ assert_match(/\Atest filename:1\b/, e.backtrace[0])
+ end
+
+ def test_without_filename_with_safe_level
+ erb = ERB.new("<% raise ::TestERB::MyError %>", 1)
+ e = assert_raise(MyError) {
+ erb.result
+ }
+ assert_match(/\A\(erb\):1\b/, e.backtrace[0])
+ end
+
+ def test_with_filename_and_safe_level
+ erb = ERB.new("<% raise ::TestERB::MyError %>", 1)
+ erb.filename = "test filename"
+ e = assert_raise(MyError) {
+ erb.result
+ }
+ assert_match(/\Atest filename:1\b/, e.backtrace[0])
+ end
+end
+
+class TestERBCore < Test::Unit::TestCase
+ def setup
+ @erb = ERB
+ end
+
+ def test_core
+ _test_core(nil)
+ _test_core(0)
+ _test_core(1)
+ _test_core(2)
+ _test_core(3)
+ end
+
+ def _test_core(safe)
+ erb = @erb.new("hello")
+ assert_equal("hello", erb.result)
+
+ erb = @erb.new("hello", safe, 0)
+ assert_equal("hello", erb.result)
+
+ erb = @erb.new("hello", safe, 1)
+ assert_equal("hello", erb.result)
+
+ erb = @erb.new("hello", safe, 2)
+ assert_equal("hello", erb.result)
+
+ src = <<EOS
+%% hi
+= hello
+<% 3.times do |n| %>
+% n=0
+* <%= n %>
+<% end %>
+EOS
+
+ ans = <<EOS
+%% hi
+= hello
+
+% n=0
+* 0
+
+% n=0
+* 1
+
+% n=0
+* 2
+
+EOS
+ erb = @erb.new(src)
+ assert_equal(ans, erb.result)
+ erb = @erb.new(src, safe, 0)
+ assert_equal(ans, erb.result)
+ erb = @erb.new(src, safe, '')
+ assert_equal(ans, erb.result)
+
+ ans = <<EOS
+%% hi
+= hello
+% n=0
+* 0% n=0
+* 1% n=0
+* 2
+EOS
+ erb = @erb.new(src, safe, 1)
+ assert_equal(ans.chomp, erb.result)
+ erb = @erb.new(src, safe, '>')
+ assert_equal(ans.chomp, erb.result)
+
+ ans = <<EOS
+%% hi
+= hello
+% n=0
+* 0
+% n=0
+* 1
+% n=0
+* 2
+EOS
+
+ erb = @erb.new(src, safe, 2)
+ assert_equal(ans, erb.result)
+ erb = @erb.new(src, safe, '<>')
+ assert_equal(ans, erb.result)
+
+ ans = <<EOS
+% hi
+= hello
+
+* 0
+
+* 0
+
+* 0
+
+EOS
+ erb = @erb.new(src, safe, '%')
+ assert_equal(ans, erb.result)
+
+ ans = <<EOS
+% hi
+= hello
+* 0* 0* 0
+EOS
+ erb = @erb.new(src, safe, '%>')
+ assert_equal(ans.chomp, erb.result)
+
+ ans = <<EOS
+% hi
+= hello
+* 0
+* 0
+* 0
+EOS
+ erb = @erb.new(src, safe, '%<>')
+ assert_equal(ans, erb.result)
+ end
+
+ def test_safe_04
+ skip("[BUG : #842] SecurityError Level 4")
+
+ erb = @erb.new('<%=$SAFE%>', 4)
+ assert_equal('4', erb.result(TOPLEVEL_BINDING.taint))
+ end
+
+ class Foo; end
+
+ def test_def_class
+ erb = @erb.new('hello')
+ cls = erb.def_class
+ assert_equal(Object, cls.superclass)
+ assert(cls.new.respond_to?('result'))
+ cls = erb.def_class(Foo)
+ assert_equal(Foo, cls.superclass)
+ assert(cls.new.respond_to?('result'))
+ cls = erb.def_class(Object, 'erb')
+ assert_equal(Object, cls.superclass)
+ assert(cls.new.respond_to?('erb'))
+ end
+
+ def test_percent
+ src = <<EOS
+%n = 1
+<%= n%>
+EOS
+ assert_equal("1\n", ERB.new(src, nil, '%').result)
+
+ src = <<EOS
+<%
+%>
+EOS
+ ans = "\n"
+ assert_equal(ans, ERB.new(src, nil, '%').result)
+
+ src = "<%\n%>"
+ # ans = "\n"
+ ans = ""
+ assert_equal(ans, ERB.new(src, nil, '%').result)
+
+ src = <<EOS
+<%
+n = 1
+%><%= n%>
+EOS
+ assert_equal("1\n", ERB.new(src, nil, '%').result)
+
+ src = <<EOS
+%n = 1
+%% <% n = 2
+n.times do |i|%>
+%% %%><%%<%= i%><%
+end%>
+%%%
+EOS
+ ans = <<EOS
+%
+% %%><%0
+% %%><%1
+%%
+EOS
+ assert_equal(ans, ERB.new(src, nil, '%').result)
+ end
+
+ def test_def_erb_method
+ klass = Class.new
+ klass.module_eval do
+ extend ERB::DefMethod
+ fname = File.join(File.dirname(File.expand_path(__FILE__)), 'hello.erb')
+ def_erb_method('hello', fname)
+ end
+ assert(klass.new.respond_to?('hello'))
+
+ assert(! klass.new.respond_to?('hello_world'))
+ erb = @erb.new('hello, world')
+ klass.module_eval do
+ def_erb_method('hello_world', erb)
+ end
+ assert(klass.new.respond_to?('hello_world'))
+ end
+
+ def test_def_method_without_filename
+ klass = Class.new
+ erb = ERB.new("<% raise ::TestERB::MyError %>")
+ erb.filename = "test filename"
+ assert(! klass.new.respond_to?('my_error'))
+ erb.def_method(klass, 'my_error')
+ e = assert_raise(::TestERB::MyError) {
+ klass.new.my_error
+ }
+ assert_match(/\A\(ERB\):1\b/, e.backtrace[0])
+ end
+
+ def test_def_method_with_fname
+ klass = Class.new
+ erb = ERB.new("<% raise ::TestERB::MyError %>")
+ erb.filename = "test filename"
+ assert(! klass.new.respond_to?('my_error'))
+ erb.def_method(klass, 'my_error', 'test fname')
+ e = assert_raise(::TestERB::MyError) {
+ klass.new.my_error
+ }
+ assert_match(/\Atest fname:1\b/, e.backtrace[0])
+ end
+
+ def test_escape
+ src = <<EOS
+1.<%% : <%="<%%"%>
+2.%%> : <%="%%>"%>
+3.
+% x = "foo"
+<%=x%>
+4.
+%% print "foo"
+5.
+%% <%="foo"%>
+6.<%="
+% print 'foo'
+"%>
+7.<%="
+%% print 'foo'
+"%>
+EOS
+ ans = <<EOS
+1.<% : <%%
+2.%%> : %>
+3.
+foo
+4.
+% print "foo"
+5.
+% foo
+6.
+% print 'foo'
+
+7.
+%% print 'foo'
+
+EOS
+ assert_equal(ans, ERB.new(src, nil, '%').result)
+ end
+
+ def test_keep_lineno
+ src = <<EOS
+Hello,
+% x = "World"
+<%= x%>
+% raise("lineno")
+EOS
+
+ erb = ERB.new(src, nil, '%')
+ begin
+ erb.result
+ assert(false)
+ rescue
+ assert_match(/\A\(erb\):4\b/, $@[0].to_s)
+ end
+
+ src = <<EOS
+%>
+Hello,
+<% x = "World%%>
+"%>
+<%= x%>
+EOS
+
+ ans = <<EOS
+%>Hello,
+World%>
+EOS
+ assert_equal(ans, ERB.new(src, nil, '>').result)
+
+ ans = <<EOS
+%>
+Hello,
+
+World%>
+EOS
+ assert_equal(ans, ERB.new(src, nil, '<>').result)
+
+ ans = <<EOS
+%>
+Hello,
+
+World%>
+
+EOS
+ assert_equal(ans, ERB.new(src).result)
+
+ src = <<EOS
+Hello,
+<% x = "World%%>
+"%>
+<%= x%>
+<% raise("lineno") %>
+EOS
+
+ erb = ERB.new(src)
+ begin
+ erb.result
+ assert(false)
+ rescue
+ assert_match(/\A\(erb\):5\b/, $@[0].to_s)
+ end
+
+ erb = ERB.new(src, nil, '>')
+ begin
+ erb.result
+ assert(false)
+ rescue
+ assert_match(/\A\(erb\):5\b/, $@[0].to_s)
+ end
+
+ erb = ERB.new(src, nil, '<>')
+ begin
+ erb.result
+ assert(false)
+ rescue
+ assert_match(/\A\(erb\):5\b/, $@[0].to_s)
+ end
+
+ src = <<EOS
+% y = 'Hello'
+<%- x = "World%%>
+"-%>
+<%= x %><%- x = nil -%>
+<% raise("lineno") %>
+EOS
+
+ erb = ERB.new(src, nil, '-')
+ begin
+ erb.result
+ assert(false)
+ rescue
+ assert_match(/\A\(erb\):5\b/, $@[0].to_s)
+ end
+
+ erb = ERB.new(src, nil, '%-')
+ begin
+ erb.result
+ assert(false)
+ rescue
+ assert_match(/\A\(erb\):5\b/, $@[0].to_s)
+ end
+ end
+
+ def test_explicit
+ src = <<EOS
+<% x = %w(hello world) -%>
+NotSkip <%- y = x -%> NotSkip
+<% x.each do |w| -%>
+ <%- up = w.upcase -%>
+ * <%= up %>
+<% end -%>
+ <%- z = nil -%> NotSkip <%- z = x %>
+ <%- z.each do |w| -%>
+ <%- down = w.downcase -%>
+ * <%= down %>
+ <%- up = w.upcase -%>
+ * <%= up %>
+ <%- end -%>
+KeepNewLine <%- z = nil -%>
+EOS
+
+ ans = <<EOS
+NotSkip NotSkip
+ * HELLO
+ * WORLD
+ NotSkip
+ * hello
+ * HELLO
+ * world
+ * WORLD
+KeepNewLine
+EOS
+ assert_equal(ans, ERB.new(src, nil, '-').result)
+ assert_equal(ans, ERB.new(src, nil, '-%').result)
+ end
+
+ def test_url_encode
+ assert_equal("Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide",
+ ERB::Util.url_encode("Programming Ruby: The Pragmatic Programmer's Guide"))
+
+ assert_equal("%A5%B5%A5%F3%A5%D7%A5%EB",
+ ERB::Util.url_encode("\xA5\xB5\xA5\xF3\xA5\xD7\xA5\xEB".force_encoding("EUC-JP")))
+ end
+
+ def test_percent_after_etag
+ assert_equal("1%", @erb.new("<%= 1 %>%", nil, "%").result)
+ end
+end
+
+class TestERBCoreWOStrScan < TestERBCore
+ def setup
+ @save_map = ERB::Compiler::Scanner.instance_variable_get('@scanner_map')
+ map = {[nil, false]=>ERB::Compiler::SimpleScanner}
+ ERB::Compiler::Scanner.instance_variable_set('@scanner_map', map)
+ super
+ end
+
+ def teardown
+ ERB::Compiler::Scanner.instance_variable_set('@scanner_map', @save_map)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/erb/test_erb_m17n.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/erb/test_erb_m17n.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/erb/test_erb_m17n.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,123 @@
+# -*- coding: UTF-8 -*-
+require 'test/unit'
+require 'erb'
+
+class TestERB < Test::Unit::TestCase
+ def test_result_encoding
+ erb = ERB.new("hello")
+ assert_equal __ENCODING__, erb.result.encoding
+
+ erb = ERB.new("こんにちは".encode("EUC-JP"))
+ assert_equal Encoding::EUC_JP, erb.result.encoding
+
+ erb = ERB.new("\xC4\xE3\xBA\xC3".force_encoding("EUC-CN"))
+ assert_equal Encoding::EUC_CN, erb.result.encoding
+
+ erb = ERB.new("γεια σας".encode("ISO-8859-7"))
+ assert_equal Encoding::ISO_8859_7, erb.result.encoding
+
+ assert_raise(ArgumentError, /ASCII compatible/) {
+ ERB.new("こんにちは".force_encoding("ISO-2022-JP")) # dummy encoding
+ }
+ end
+
+ def test_generate_magic_comment
+ erb = ERB.new("hello")
+ assert_match(/#coding:UTF-8/, erb.src)
+
+ erb = ERB.new("hello".force_encoding("EUC-JP"))
+ assert_match(/#coding:EUC-JP/, erb.src)
+
+ erb = ERB.new("hello".force_encoding("ISO-8859-9"))
+ assert_match(/#coding:ISO-8859-9/, erb.src)
+ end
+
+ def test_literal_encoding
+ erb = ERB.new("literal encoding is <%= 'hello'.encoding %>")
+ assert_match(/literal encoding is UTF-8/, erb.result)
+
+ erb = ERB.new("literal encoding is <%= 'こんにちは'.encoding %>".encode("EUC-JP"))
+ assert_match(/literal encoding is EUC-JP/, erb.result)
+
+ erb = ERB.new("literal encoding is <%= '\xC4\xE3\xBA\xC3'.encoding %>".force_encoding("EUC-CN"))
+ assert_match(/literal encoding is GB2312/, erb.result)
+ end
+
+ def test___ENCODING__
+ erb = ERB.new("__ENCODING__ is <%= __ENCODING__ %>")
+ assert_match(/__ENCODING__ is UTF-8/, erb.result)
+
+ erb = ERB.new("__ENCODING__ is <%= __ENCODING__ %>".force_encoding("EUC-JP"))
+ assert_match(/__ENCODING__ is EUC-JP/, erb.result)
+
+ erb = ERB.new("__ENCODING__ is <%= __ENCODING__ %>".force_encoding("Big5"))
+ assert_match(/__ENCODING__ is Big5/, erb.result)
+ end
+
+ def test_recognize_magic_comment
+ erb = ERB.new(<<-EOS.encode("EUC-KR"))
+<%# -*- coding: EUC-KR -*- %>
+안녕하세요
+ EOS
+ assert_match(/#coding:EUC-KR/, erb.src)
+ assert_equal Encoding::EUC_KR, erb.result.encoding
+
+ erb = ERB.new(<<-EOS.encode("EUC-KR").force_encoding("ASCII-8BIT"))
+<%#-*- coding: EUC-KR -*-%>
+안녕하세요
+ EOS
+ assert_match(/#coding:EUC-KR/, erb.src)
+ assert_equal Encoding::EUC_KR, erb.result.encoding
+
+ erb = ERB.new(<<-EOS.encode("EUC-KR").force_encoding("ASCII-8BIT"))
+<%# vim: tabsize=8 encoding=EUC-KR shiftwidth=2 expandtab %>
+안녕하세요
+ EOS
+ assert_match(/#coding:EUC-KR/, erb.src)
+ assert_equal Encoding::EUC_KR, erb.result.encoding
+
+ erb = ERB.new(<<-EOS.encode("EUC-KR").force_encoding("ASCII-8BIT"))
+<%#coding:EUC-KR %>
+안녕하세요
+ EOS
+ assert_match(/#coding:EUC-KR/, erb.src)
+ assert_equal Encoding::EUC_KR, erb.result.encoding
+
+ erb = ERB.new(<<-EOS.encode("EUC-KR").force_encoding("EUC-JP"))
+<%#coding:EUC-KR %>
+안녕하세요
+ EOS
+ assert_match(/#coding:EUC-KR/, erb.src)
+ assert_equal Encoding::EUC_KR, erb.result.encoding
+ end
+
+ module M; end
+ def test_method_with_encoding
+ obj = Object.new
+ obj.extend(M)
+
+ erb = ERB.new(<<-EOS.encode("EUC-JP").force_encoding("ASCII-8BIT"))
+<%#coding:EUC-JP %>
+literal encoding is <%= 'こんにちは'.encoding %>
+__ENCODING__ is <%= __ENCODING__ %>
+ EOS
+ erb.def_method(M, :m_from_magic_comment)
+
+ result = obj.m_from_magic_comment
+ assert_equal Encoding::EUC_JP, result.encoding
+ assert_match(/literal encoding is EUC-JP/, result)
+ assert_match(/__ENCODING__ is EUC-JP/, result)
+
+ erb = ERB.new(<<-EOS.encode("EUC-KR"))
+literal encoding is <%= '안녕하세요'.encoding %>
+__ENCODING__ is <%= __ENCODING__ %>
+EOS
+ erb.def_method(M, :m_from_eval_encoding)
+ result = obj.m_from_eval_encoding
+ assert_equal Encoding::EUC_KR, result.encoding
+ assert_match(/literal encoding is EUC-KR/, result)
+ assert_match(/__ENCODING__ is EUC-KR/, result)
+ end
+end
+
+# vim:fileencoding=UTF-8
Added: MacRuby/trunk/test/test-mri/test/etc/test_etc.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/etc/test_etc.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/etc/test_etc.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,101 @@
+require "test/unit"
+require "etc"
+
+class TestEtc < Test::Unit::TestCase
+ def test_getlogin
+ s = Etc.getlogin
+ assert(s.is_a?(String) || s == nil, "getlogin must return a String or nil")
+ end
+
+ def test_passwd
+ Etc.passwd do |s|
+ assert_instance_of(String, s.name)
+ assert_instance_of(String, s.passwd) if s.respond_to?(:passwd)
+ assert_kind_of(Integer, s.uid)
+ assert_kind_of(Integer, s.gid)
+ assert_instance_of(String, s.gecos) if s.respond_to?(:gecos)
+ assert_instance_of(String, s.dir)
+ assert_instance_of(String, s.shell)
+ assert_kind_of(Integer, s.change) if s.respond_to?(:change)
+ assert_kind_of(Integer, s.quota) if s.respond_to?(:quota)
+ assert(s.age.is_a?(Integer) || s.age.is_a?(String)) if s.respond_to?(:age)
+ assert_instance_of(String, s.uclass) if s.respond_to?(:uclass)
+ assert_instance_of(String, s.comment) if s.respond_to?(:comment)
+ assert_kind_of(Integer, s.expire) if s.respond_to?(:expire)
+ end
+
+ Etc.passwd { assert_raise(RuntimeError) { Etc.passwd { } }; break }
+ end
+
+ def test_getpwuid
+ passwd = {}
+ Etc.passwd {|s| passwd[s.uid] ||= s }
+ passwd.each_value do |s|
+ assert_equal(s, Etc.getpwuid(s.uid))
+ assert_equal(s, Etc.getpwuid) if Process.euid == s.uid
+ end
+ end
+
+ def test_getpwnam
+ passwd = {}
+ Etc.passwd {|s| passwd[s.name] ||= s }
+ passwd.each_value do |s|
+ assert_equal(s, Etc.getpwnam(s.name))
+ end
+ end
+
+ def test_passwd_with_low_level_api
+ a = []
+ Etc.passwd {|s| a << s }
+ b = []
+ Etc.setpwent
+ while s = Etc.getpwent
+ b << s
+ end
+ Etc.endpwent
+ assert_equal(a, b)
+ end
+
+ def test_group
+ Etc.group do |s|
+ assert_instance_of(String, s.name)
+ assert_instance_of(String, s.passwd) if s.respond_to?(:passwd)
+ assert_kind_of(Integer, s.gid)
+ end
+
+ Etc.group { assert_raise(RuntimeError) { Etc.group { } }; break }
+ end
+
+ def test_getgrgid
+ groups = {}
+ Etc.group do |s|
+ groups[s.gid] ||= s
+ end
+ groups.each_value do |s|
+ assert_equal(s, Etc.getgrgid(s.gid))
+ assert_equal(s, Etc.getgrgid) if Process.egid == s.gid
+ end
+ end
+
+ def test_getgrnam
+ groups = {}
+ Etc.group do |s|
+ groups[s.name] ||= s
+ end
+ groups.each_value do |s|
+ assert_equal(s, Etc.getgrnam(s.name))
+ end
+ end
+
+ def test_group_with_low_level_api
+ a = []
+ Etc.group {|s| a << s }
+ b = []
+ Etc.setgrent
+ while s = Etc.getgrent
+ b << s
+ end
+ Etc.endgrent
+ assert_equal(a, b)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/fiddle/helper.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/fiddle/helper.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/fiddle/helper.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,71 @@
+require 'minitest/autorun'
+require 'dl'
+require 'fiddle'
+
+# FIXME: this is stolen from DL and needs to be refactored.
+require_relative '../ruby/envutil'
+
+libc_so = libm_so = nil
+
+case RUBY_PLATFORM
+when /cygwin/
+ libc_so = "cygwin1.dll"
+ libm_so = "cygwin1.dll"
+when /x86_64-linux/
+ libc_so = "/lib64/libc.so.6"
+ libm_so = "/lib64/libm.so.6"
+when /linux/
+ libdir = '/lib'
+ case [0].pack('L!').size
+ when 4
+ # 32-bit ruby
+ libdir = '/lib32' if File.directory? '/lib32'
+ when 8
+ # 64-bit ruby
+ libdir = '/lib64' if File.directory? '/lib64'
+ end
+ libc_so = File.join(libdir, "libc.so.6")
+ libm_so = File.join(libdir, "libm.so.6")
+when /mingw/, /mswin/
+ require "rbconfig"
+ libc_so = libm_so = RbConfig::CONFIG["RUBY_SO_NAME"].split(/-/, 2)[0] + ".dll"
+when /darwin/
+ libc_so = "/usr/lib/libc.dylib"
+ libm_so = "/usr/lib/libm.dylib"
+when /kfreebsd/
+ libc_so = "/lib/libc.so.0.1"
+ libm_so = "/lib/libm.so.1"
+when /bsd|dragonfly/
+ libc_so = "/usr/lib/libc.so"
+ libm_so = "/usr/lib/libm.so"
+else
+ libc_so = ARGV[0] if ARGV[0] && ARGV[0][0] == ?/
+ libm_so = ARGV[1] if ARGV[1] && ARGV[1][0] == ?/
+ if( !(libc_so && libm_so) )
+ $stderr.puts("libc and libm not found: #{$0} <libc> <libm>")
+ end
+end
+
+libc_so = nil if !libc_so || (libc_so[0] == ?/ && !File.file?(libc_so))
+libm_so = nil if !libm_so || (libm_so[0] == ?/ && !File.file?(libm_so))
+
+if !libc_so || !libm_so
+ ruby = EnvUtil.rubybin
+ ldd = `ldd #{ruby}`
+ #puts ldd
+ libc_so = $& if !libc_so && %r{/\S*/libc\.so\S*} =~ ldd
+ libm_so = $& if !libm_so && %r{/\S*/libm\.so\S*} =~ ldd
+ #p [libc_so, libm_so]
+end
+
+Fiddle::LIBC_SO = libc_so
+Fiddle::LIBM_SO = libm_so
+
+module Fiddle
+ class TestCase < MiniTest::Unit::TestCase
+ def setup
+ @libc = DL.dlopen(LIBC_SO)
+ @libm = DL.dlopen(LIBM_SO)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/fiddle/test_closure.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/fiddle/test_closure.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/fiddle/test_closure.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,49 @@
+require_relative 'helper'
+
+module Fiddle
+ class TestClosure < Fiddle::TestCase
+ def test_argument_errors
+ assert_raises(TypeError) do
+ Closure.new(TYPE_INT, TYPE_INT)
+ end
+
+ assert_raises(TypeError) do
+ Closure.new('foo', [TYPE_INT])
+ end
+
+ assert_raises(TypeError) do
+ Closure.new(TYPE_INT, ['meow!'])
+ end
+ end
+
+ def test_call
+ closure = Class.new(Closure) {
+ def call
+ 10
+ end
+ }.new(TYPE_INT, [])
+
+ func = Function.new(closure, [], TYPE_INT)
+ assert_equal 10, func.call
+ end
+
+ def test_returner
+ closure = Class.new(Closure) {
+ def call thing
+ thing
+ end
+ }.new(TYPE_INT, [TYPE_INT])
+
+ func = Function.new(closure, [TYPE_INT], TYPE_INT)
+ assert_equal 10, func.call(10)
+ end
+
+ def test_block_caller
+ cb = Closure::BlockCaller.new(TYPE_INT, [TYPE_INT]) do |one|
+ one
+ end
+ func = Function.new(cb, [TYPE_INT], TYPE_INT)
+ assert_equal 11, func.call(11)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/fiddle/test_fiddle.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/fiddle/test_fiddle.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/fiddle/test_fiddle.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,19 @@
+require_relative 'helper'
+
+class TestFiddle < Fiddle::TestCase
+ def test_constants_match
+ [
+ :TYPE_VOID,
+ :TYPE_VOIDP,
+ :TYPE_CHAR,
+ :TYPE_SHORT,
+ :TYPE_INT,
+ :TYPE_LONG,
+ :TYPE_LONG_LONG,
+ :TYPE_FLOAT,
+ :TYPE_DOUBLE,
+ ].each do |name|
+ assert_equal(DL.const_get(name), Fiddle.const_get(name))
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/fiddle/test_function.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/fiddle/test_function.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/fiddle/test_function.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,66 @@
+require_relative 'helper'
+
+module Fiddle
+ class TestFunction < Fiddle::TestCase
+ def setup
+ super
+ Fiddle.last_error = nil
+ end
+
+ def test_default_abi
+ func = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE)
+ assert_equal Function::DEFAULT, func.abi
+ end
+
+ def test_argument_errors
+ assert_raises(TypeError) do
+ Function.new(@libm['sin'], TYPE_DOUBLE, TYPE_DOUBLE)
+ end
+
+ assert_raises(TypeError) do
+ Function.new(@libm['sin'], ['foo'], TYPE_DOUBLE)
+ end
+
+ assert_raises(TypeError) do
+ Function.new(@libm['sin'], [TYPE_DOUBLE], 'foo')
+ end
+ end
+
+ def test_call
+ func = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE)
+ assert_in_delta 1.0, func.call(90 * Math::PI / 180), 0.0001
+ end
+
+ def test_argument_count
+ closure = Class.new(Closure) {
+ def call one
+ 10 + one
+ end
+ }.new(TYPE_INT, [TYPE_INT])
+ func = Function.new(closure, [TYPE_INT], TYPE_INT)
+
+ assert_raises(ArgumentError) do
+ func.call(1,2,3)
+ end
+ assert_raises(ArgumentError) do
+ func.call
+ end
+ end
+
+ def test_last_error
+ func = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
+
+ assert_nil Fiddle.last_error
+ str = func.call("000", "123")
+ refute_nil Fiddle.last_error
+ end
+
+ def test_strcpy
+ f = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
+ buff = "000"
+ str = f.call(buff, "123")
+ assert_equal("123", buff)
+ assert_equal("123", str.to_s)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/fileutils/fileasserts.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/fileutils/fileasserts.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/fileutils/fileasserts.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,104 @@
+# $Id: fileasserts.rb 25189 2009-10-02 12:04:37Z akr $
+
+module Test
+ module Unit
+ module Assertions # redefine
+
+ def _wrap_assertion
+ yield
+ end
+
+ def assert_same_file(from, to)
+ _wrap_assertion {
+ assert_block("file #{from} != #{to}") {
+ File.read(from) == File.read(to)
+ }
+ }
+ end
+
+ def assert_same_entry(from, to)
+ a = File.stat(from)
+ b = File.stat(to)
+ assert_equal a.mode, b.mode, "mode #{a.mode} != #{b.mode}"
+ #assert_equal a.atime, b.atime
+ assert_equal_timestamp a.mtime, b.mtime, "mtime #{a.mtime} != #{b.mtime}"
+ assert_equal a.uid, b.uid, "uid #{a.uid} != #{b.uid}"
+ assert_equal a.gid, b.gid, "gid #{a.gid} != #{b.gid}"
+ end
+
+ def assert_file_exist(path)
+ _wrap_assertion {
+ assert_block("file not exist: #{path}") {
+ File.exist?(path)
+ }
+ }
+ end
+
+ def assert_file_not_exist(path)
+ _wrap_assertion {
+ assert_block("file not exist: #{path}") {
+ not File.exist?(path)
+ }
+ }
+ end
+
+ def assert_directory(path)
+ _wrap_assertion {
+ assert_block("is not directory: #{path}") {
+ File.directory?(path)
+ }
+ }
+ end
+
+ def assert_symlink(path)
+ _wrap_assertion {
+ assert_block("is not a symlink: #{path}") {
+ File.symlink?(path)
+ }
+ }
+ end
+
+ def assert_not_symlink(path)
+ _wrap_assertion {
+ assert_block("is a symlink: #{path}") {
+ not File.symlink?(path)
+ }
+ }
+ end
+
+ def assert_equal_time(expected, actual, message=nil)
+ _wrap_assertion {
+ expected_str = expected.to_s
+ actual_str = actual.to_s
+ if expected_str == actual_str
+ expected_str << " (nsec=#{expected.nsec})"
+ actual_str << " (nsec=#{actual.nsec})"
+ end
+ full_message = build_message(message, <<EOT)
+<#{expected_str}> expected but was
+<#{actual_str}>.
+EOT
+ assert_block(full_message) { expected == actual }
+ }
+ end
+
+ def assert_equal_timestamp(expected, actual, message=nil)
+ _wrap_assertion {
+ expected_str = expected.to_s
+ actual_str = actual.to_s
+ if expected_str == actual_str
+ expected_str << " (nsec=#{expected.nsec})"
+ actual_str << " (nsec=#{actual.nsec})"
+ end
+ full_message = build_message(message, <<EOT)
+<#{expected_str}> expected but was
+<#{actual_str}>.
+EOT
+ # subsecond timestamp is not portable.
+ assert_block(full_message) { expected.tv_sec == actual.tv_sec }
+ }
+ end
+
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/fileutils/test_dryrun.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/fileutils/test_dryrun.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/fileutils/test_dryrun.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,25 @@
+# $Id: test_dryrun.rb 26417 2010-01-25 22:08:29Z akr $
+
+require 'test/unit'
+require 'fileutils'
+
+class TestFileUtilsDryRun < Test::Unit::TestCase
+
+ include FileUtils::DryRun
+
+ def test_visibility
+ FileUtils::METHODS.each do |m|
+ assert_equal true, FileUtils::DryRun.respond_to?(m, true),
+ "FileUtils::DryRun.#{m} not defined"
+ assert_equal true, FileUtils::DryRun.respond_to?(m, false),
+ "FileUtils::DryRun.#{m} not public"
+ end
+ FileUtils::METHODS.each do |m|
+ assert_equal true, respond_to?(m, true),
+ "FileUtils::DryRun\##{m} is not defined"
+ assert_equal true, FileUtils::DryRun.private_method_defined?(m),
+ "FileUtils::DryRun\##{m} is not private"
+ end
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/fileutils/test_fileutils.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/fileutils/test_fileutils.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/fileutils/test_fileutils.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1120 @@
+# $Id: test_fileutils.rb 28743 2010-07-24 10:38:16Z yugui $
+
+require 'fileutils'
+require_relative 'fileasserts'
+require 'pathname'
+require 'tmpdir'
+require 'test/unit'
+
+class TestFileUtils < Test::Unit::TestCase
+ TMPROOT = "#{Dir.tmpdir}/fileutils.rb.#{$$}"
+end
+
+prevdir = Dir.pwd
+tmproot = TestFileUtils::TMPROOT
+Dir.mkdir tmproot unless File.directory?(tmproot)
+Dir.chdir tmproot
+
+def have_drive_letter?
+ /mswin(?!ce)|mingw|bcc|emx/ =~ RUBY_PLATFORM
+end
+
+def have_file_perm?
+ /mswin|mingw|bcc|emx/ !~ RUBY_PLATFORM
+end
+
+$fileutils_rb_have_symlink = nil
+
+def have_symlink?
+ if $fileutils_rb_have_symlink == nil
+ $fileutils_rb_have_symlink = check_have_symlink?
+ end
+ $fileutils_rb_have_symlink
+end
+
+def check_have_symlink?
+ File.symlink nil, nil
+rescue NotImplementedError
+ return false
+rescue
+ return true
+end
+
+$fileutils_rb_have_hardlink = nil
+
+def have_hardlink?
+ if $fileutils_rb_have_hardlink == nil
+ $fileutils_rb_have_hardlink = check_have_hardlink?
+ end
+ $fileutils_rb_have_hardlink
+end
+
+def check_have_hardlink?
+ File.link nil, nil
+rescue NotImplementedError
+ return false
+rescue
+ return true
+end
+
+begin
+ Dir.mkdir("\n")
+ Dir.rmdir("\n")
+ def lf_in_path_allowed?
+ true
+ end
+rescue
+ def lf_in_path_allowed?
+ false
+ end
+end
+
+Dir.chdir prevdir
+Dir.rmdir tmproot
+
+class TestFileUtils
+
+ include FileUtils
+
+ def check_singleton(name)
+ assert_respond_to ::FileUtils, name
+ end
+
+ def my_rm_rf(path)
+ if File.exist?('/bin/rm')
+ system %Q[/bin/rm -rf "#{path}"]
+ else
+ FileUtils.rm_rf path
+ end
+ end
+
+ def mymkdir(path)
+ Dir.mkdir path
+ File.chown nil, Process.gid, path if have_file_perm?
+ end
+
+ def setup
+ @prevdir = Dir.pwd
+ tmproot = TMPROOT
+ mymkdir tmproot unless File.directory?(tmproot)
+ Dir.chdir tmproot
+ my_rm_rf 'data'; mymkdir 'data'
+ my_rm_rf 'tmp'; mymkdir 'tmp'
+ prepare_data_file
+ end
+
+ def teardown
+ tmproot = Dir.pwd
+ Dir.chdir @prevdir
+ my_rm_rf tmproot
+ end
+
+
+ TARGETS = %w( data/a data/all data/random data/zero )
+
+ def prepare_data_file
+ File.open('data/a', 'w') {|f|
+ 32.times do
+ f.puts 'a' * 50
+ end
+ }
+
+ all_chars = (0..255).map {|n| n.chr }.join('')
+ File.open('data/all', 'w') {|f|
+ 32.times do
+ f.puts all_chars
+ end
+ }
+
+ random_chars = (0...50).map { rand(256).chr }.join('')
+ File.open('data/random', 'w') {|f|
+ 32.times do
+ f.puts random_chars
+ end
+ }
+
+ File.open('data/zero', 'w') {|f|
+ ;
+ }
+ end
+
+ BIGFILE = 'data/big'
+
+ def prepare_big_file
+ File.open('data/big', 'w') {|f|
+ (4 * 1024 * 1024 / 256).times do # 4MB
+ f.print "aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa\n"
+ end
+ }
+ end
+
+ def prepare_time_data
+ File.open('data/old', 'w') {|f| f.puts 'dummy' }
+ File.open('data/newer', 'w') {|f| f.puts 'dummy' }
+ File.open('data/newest', 'w') {|f| f.puts 'dummy' }
+ t = Time.now
+ File.utime t-8, t-8, 'data/old'
+ File.utime t-4, t-4, 'data/newer'
+ end
+
+ def each_srcdest
+ TARGETS.each do |path|
+ yield path, "tmp/#{File.basename(path)}"
+ end
+ end
+
+ #
+ # Test Cases
+ #
+
+ def test_pwd
+ check_singleton :pwd
+
+ assert_equal Dir.pwd, pwd()
+
+ cwd = Dir.pwd
+ root = have_drive_letter? ? 'C:/' : '/'
+ cd(root) {
+ assert_equal root, pwd()
+ }
+ assert_equal cwd, pwd()
+ end
+
+ def test_cmp
+ check_singleton :cmp
+
+ TARGETS.each do |fname|
+ assert cmp(fname, fname), 'not same?'
+ end
+ assert_raise(ArgumentError) {
+ cmp TARGETS[0], TARGETS[0], :undefinedoption => true
+ }
+
+ # pathname
+ touch 'tmp/cmptmp'
+ assert_nothing_raised {
+ cmp Pathname.new('tmp/cmptmp'), 'tmp/cmptmp'
+ cmp 'tmp/cmptmp', Pathname.new('tmp/cmptmp')
+ cmp Pathname.new('tmp/cmptmp'), Pathname.new('tmp/cmptmp')
+ }
+ end
+
+ def test_cp
+ check_singleton :cp
+
+ each_srcdest do |srcpath, destpath|
+ cp srcpath, destpath
+ assert_same_file srcpath, destpath
+
+ cp srcpath, File.dirname(destpath)
+ assert_same_file srcpath, destpath
+
+ cp srcpath, File.dirname(destpath) + '/'
+ assert_same_file srcpath, destpath
+
+ cp srcpath, destpath, :preserve => true
+ assert_same_file srcpath, destpath
+ assert_same_entry srcpath, destpath
+ end
+
+ assert_raise(Errno::ENOENT) {
+ cp 'tmp/cptmp', 'tmp/cptmp_new'
+ }
+ assert_file_not_exist('tmp/cptmp_new')
+
+ # src==dest (1) same path
+ touch 'tmp/cptmp'
+ assert_raise(ArgumentError) {
+ cp 'tmp/cptmp', 'tmp/cptmp'
+ }
+ end
+
+ def test_cp_symlink
+ touch 'tmp/cptmp'
+ # src==dest (2) symlink and its target
+ File.symlink 'cptmp', 'tmp/cptmp_symlink'
+ assert_raise(ArgumentError) {
+ cp 'tmp/cptmp', 'tmp/cptmp_symlink'
+ }
+ assert_raise(ArgumentError) {
+ cp 'tmp/cptmp_symlink', 'tmp/cptmp'
+ }
+ # src==dest (3) looped symlink
+ File.symlink 'symlink', 'tmp/symlink'
+ assert_raise(Errno::ELOOP) {
+ cp 'tmp/symlink', 'tmp/symlink'
+ }
+ end if have_symlink?
+
+ def test_cp_pathname
+ # pathname
+ touch 'tmp/cptmp'
+ assert_nothing_raised {
+ cp 'tmp/cptmp', Pathname.new('tmp/tmpdest')
+ cp Pathname.new('tmp/cptmp'), 'tmp/tmpdest'
+ cp Pathname.new('tmp/cptmp'), Pathname.new('tmp/tmpdest')
+ mkdir 'tmp/tmpdir'
+ cp ['tmp/cptmp', 'tmp/tmpdest'], Pathname.new('tmp/tmpdir')
+ }
+ end
+
+ def test_cp_r
+ check_singleton :cp_r
+
+ cp_r 'data', 'tmp'
+ TARGETS.each do |fname|
+ assert_same_file fname, "tmp/#{fname}"
+ end
+
+ cp_r 'data', 'tmp2', :preserve => true
+ TARGETS.each do |fname|
+ assert_same_entry fname, "tmp2/#{File.basename(fname)}"
+ assert_same_file fname, "tmp2/#{File.basename(fname)}"
+ end
+
+ # a/* -> b/*
+ mkdir 'tmp/cpr_src'
+ mkdir 'tmp/cpr_dest'
+ File.open('tmp/cpr_src/a', 'w') {|f| f.puts 'a' }
+ File.open('tmp/cpr_src/b', 'w') {|f| f.puts 'b' }
+ File.open('tmp/cpr_src/c', 'w') {|f| f.puts 'c' }
+ mkdir 'tmp/cpr_src/d'
+ cp_r 'tmp/cpr_src/.', 'tmp/cpr_dest'
+ assert_same_file 'tmp/cpr_src/a', 'tmp/cpr_dest/a'
+ assert_same_file 'tmp/cpr_src/b', 'tmp/cpr_dest/b'
+ assert_same_file 'tmp/cpr_src/c', 'tmp/cpr_dest/c'
+ assert_directory 'tmp/cpr_dest/d'
+ my_rm_rf 'tmp/cpr_src'
+ my_rm_rf 'tmp/cpr_dest'
+
+ bug3588 = '[ruby-core:31360]'
+ assert_nothing_raised(ArgumentError, bug3588) do
+ cp_r 'tmp', 'tmp2'
+ end
+ assert_directory 'tmp2/tmp'
+ assert_raise(ArgumentError, bug3588) do
+ cp_r 'tmp2', 'tmp2/new_tmp2'
+ end
+ end
+
+ def test_cp_r_symlink
+ # symlink in a directory
+ mkdir 'tmp/cpr_src'
+ ln_s 'SLdest', 'tmp/cpr_src/symlink'
+ cp_r 'tmp/cpr_src', 'tmp/cpr_dest'
+ assert_symlink 'tmp/cpr_dest/symlink'
+ assert_equal 'SLdest', File.readlink('tmp/cpr_dest/symlink')
+
+ # root is a symlink
+ ln_s 'cpr_src', 'tmp/cpr_src2'
+ cp_r 'tmp/cpr_src2', 'tmp/cpr_dest2'
+ assert_directory 'tmp/cpr_dest2'
+ assert_not_symlink 'tmp/cpr_dest2'
+ assert_symlink 'tmp/cpr_dest2/symlink'
+ assert_equal 'SLdest', File.readlink('tmp/cpr_dest2/symlink')
+ end if have_symlink?
+
+ def test_cp_r_pathname
+ # pathname
+ touch 'tmp/cprtmp'
+ assert_nothing_raised {
+ cp_r Pathname.new('tmp/cprtmp'), 'tmp/tmpdest'
+ cp_r 'tmp/cprtmp', Pathname.new('tmp/tmpdest')
+ cp_r Pathname.new('tmp/cprtmp'), Pathname.new('tmp/tmpdest')
+ }
+ end
+
+ def test_mv
+ check_singleton :mv
+
+ mkdir 'tmp/dest'
+ TARGETS.each do |fname|
+ cp fname, 'tmp/mvsrc'
+ mv 'tmp/mvsrc', 'tmp/mvdest'
+ assert_same_file fname, 'tmp/mvdest'
+
+ mv 'tmp/mvdest', 'tmp/dest/'
+ assert_same_file fname, 'tmp/dest/mvdest'
+
+ mv 'tmp/dest/mvdest', 'tmp'
+ assert_same_file fname, 'tmp/mvdest'
+ end
+
+ mkdir 'tmp/tmpdir'
+ mkdir_p 'tmp/dest2/tmpdir'
+ assert_raise(Errno::EEXIST) {
+ mv 'tmp/tmpdir', 'tmp/dest2'
+ }
+ mkdir 'tmp/dest2/tmpdir/junk'
+ assert_raise(Errno::EEXIST, "[ruby-talk:124368]") {
+ mv 'tmp/tmpdir', 'tmp/dest2'
+ }
+
+ # src==dest (1) same path
+ touch 'tmp/cptmp'
+ assert_raise(ArgumentError) {
+ mv 'tmp/cptmp', 'tmp/cptmp'
+ }
+ end
+
+ def test_mv_symlink
+ touch 'tmp/cptmp'
+ # src==dest (2) symlink and its target
+ File.symlink 'cptmp', 'tmp/cptmp_symlink'
+ assert_raise(ArgumentError) {
+ mv 'tmp/cptmp', 'tmp/cptmp_symlink'
+ }
+ assert_raise(ArgumentError) {
+ mv 'tmp/cptmp_symlink', 'tmp/cptmp'
+ }
+ # src==dest (3) looped symlink
+ File.symlink 'symlink', 'tmp/symlink'
+ assert_raise(Errno::ELOOP) {
+ mv 'tmp/symlink', 'tmp/symlink'
+ }
+ end if have_symlink?
+
+ def test_mv_pathname
+ # pathname
+ assert_nothing_raised {
+ touch 'tmp/mvtmpsrc'
+ mv Pathname.new('tmp/mvtmpsrc'), 'tmp/mvtmpdest'
+ touch 'tmp/mvtmpsrc'
+ mv 'tmp/mvtmpsrc', Pathname.new('tmp/mvtmpdest')
+ touch 'tmp/mvtmpsrc'
+ mv Pathname.new('tmp/mvtmpsrc'), Pathname.new('tmp/mvtmpdest')
+ }
+ end
+
+ def test_rm
+ check_singleton :rm
+
+ TARGETS.each do |fname|
+ cp fname, 'tmp/rmsrc'
+ rm 'tmp/rmsrc'
+ assert_file_not_exist 'tmp/rmsrc'
+ end
+
+ # pathname
+ touch 'tmp/rmtmp1'
+ touch 'tmp/rmtmp2'
+ touch 'tmp/rmtmp3'
+ assert_nothing_raised {
+ rm Pathname.new('tmp/rmtmp1')
+ rm [Pathname.new('tmp/rmtmp2'), Pathname.new('tmp/rmtmp3')]
+ }
+ assert_file_not_exist 'tmp/rmtmp1'
+ assert_file_not_exist 'tmp/rmtmp2'
+ assert_file_not_exist 'tmp/rmtmp3'
+ end
+
+ def test_rm_f
+ check_singleton :rm_f
+
+ TARGETS.each do |fname|
+ cp fname, 'tmp/rmsrc'
+ rm_f 'tmp/rmsrc'
+ assert_file_not_exist 'tmp/rmsrc'
+ end
+ end
+
+ def test_rm_symlink
+ File.open('tmp/lnf_symlink_src', 'w') {|f| f.puts 'dummy' }
+ File.symlink 'tmp/lnf_symlink_src', 'tmp/lnf_symlink_dest'
+ rm_f 'tmp/lnf_symlink_dest'
+ assert_file_not_exist 'tmp/lnf_symlink_dest'
+ assert_file_exist 'tmp/lnf_symlink_src'
+
+ rm_f 'notexistdatafile'
+ rm_f 'tmp/notexistdatafile'
+ my_rm_rf 'tmpdatadir'
+ Dir.mkdir 'tmpdatadir'
+ # rm_f 'tmpdatadir'
+ Dir.rmdir 'tmpdatadir'
+ end if have_symlink?
+
+ def test_rm_f_2
+ Dir.mkdir 'tmp/tmpdir'
+ File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' }
+ File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' }
+ rm_f ['tmp/tmpdir/a', 'tmp/tmpdir/b', 'tmp/tmpdir/c']
+ assert_file_not_exist 'tmp/tmpdir/a'
+ assert_file_not_exist 'tmp/tmpdir/c'
+ Dir.rmdir 'tmp/tmpdir'
+ end
+
+ def test_rm_pathname
+ # pathname
+ touch 'tmp/rmtmp1'
+ touch 'tmp/rmtmp2'
+ touch 'tmp/rmtmp3'
+ touch 'tmp/rmtmp4'
+ assert_nothing_raised {
+ rm_f Pathname.new('tmp/rmtmp1')
+ rm_f [Pathname.new('tmp/rmtmp2'), Pathname.new('tmp/rmtmp3')]
+ }
+ assert_file_not_exist 'tmp/rmtmp1'
+ assert_file_not_exist 'tmp/rmtmp2'
+ assert_file_not_exist 'tmp/rmtmp3'
+ assert_file_exist 'tmp/rmtmp4'
+
+ # [ruby-dev:39345]
+ touch 'tmp/[rmtmp]'
+ FileUtils.rm_f 'tmp/[rmtmp]'
+ assert_file_not_exist 'tmp/[rmtmp]'
+ end
+
+ def test_rm_r
+ check_singleton :rm_r
+
+ my_rm_rf 'tmpdatadir'
+
+ Dir.mkdir 'tmpdatadir'
+ rm_r 'tmpdatadir'
+ assert_file_not_exist 'tmpdatadir'
+
+ Dir.mkdir 'tmpdatadir'
+ rm_r 'tmpdatadir/'
+ assert_file_not_exist 'tmpdatadir'
+
+ Dir.mkdir 'tmp/tmpdir'
+ rm_r 'tmp/tmpdir/'
+ assert_file_not_exist 'tmp/tmpdir'
+ assert_file_exist 'tmp'
+
+ Dir.mkdir 'tmp/tmpdir'
+ rm_r 'tmp/tmpdir'
+ assert_file_not_exist 'tmp/tmpdir'
+ assert_file_exist 'tmp'
+
+ Dir.mkdir 'tmp/tmpdir'
+ File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' }
+ File.open('tmp/tmpdir/b', 'w') {|f| f.puts 'dummy' }
+ File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' }
+ rm_r 'tmp/tmpdir'
+ assert_file_not_exist 'tmp/tmpdir'
+ assert_file_exist 'tmp'
+
+ Dir.mkdir 'tmp/tmpdir'
+ File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' }
+ File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' }
+ rm_r ['tmp/tmpdir/a', 'tmp/tmpdir/b', 'tmp/tmpdir/c'], :force => true
+ assert_file_not_exist 'tmp/tmpdir/a'
+ assert_file_not_exist 'tmp/tmpdir/c'
+ Dir.rmdir 'tmp/tmpdir'
+ end
+
+ def test_rm_r_symlink
+ # [ruby-talk:94635] a symlink to the directory
+ Dir.mkdir 'tmp/tmpdir'
+ File.symlink '..', 'tmp/tmpdir/symlink_to_dir'
+ rm_r 'tmp/tmpdir'
+ assert_file_not_exist 'tmp/tmpdir'
+ assert_file_exist 'tmp'
+ end if have_symlink?
+
+ def test_rm_r_pathname
+ # pathname
+ Dir.mkdir 'tmp/tmpdir1'; touch 'tmp/tmpdir1/tmp'
+ Dir.mkdir 'tmp/tmpdir2'; touch 'tmp/tmpdir2/tmp'
+ Dir.mkdir 'tmp/tmpdir3'; touch 'tmp/tmpdir3/tmp'
+ assert_nothing_raised {
+ rm_r Pathname.new('tmp/tmpdir1')
+ rm_r [Pathname.new('tmp/tmpdir2'), Pathname.new('tmp/tmpdir3')]
+ }
+ assert_file_not_exist 'tmp/tmpdir1'
+ assert_file_not_exist 'tmp/tmpdir2'
+ assert_file_not_exist 'tmp/tmpdir3'
+ end
+
+ def test_remove_entry_secure
+ check_singleton :remove_entry_secure
+
+ my_rm_rf 'tmpdatadir'
+
+ Dir.mkdir 'tmpdatadir'
+ remove_entry_secure 'tmpdatadir'
+ assert_file_not_exist 'tmpdatadir'
+
+ Dir.mkdir 'tmpdatadir'
+ remove_entry_secure 'tmpdatadir/'
+ assert_file_not_exist 'tmpdatadir'
+
+ Dir.mkdir 'tmp/tmpdir'
+ remove_entry_secure 'tmp/tmpdir/'
+ assert_file_not_exist 'tmp/tmpdir'
+ assert_file_exist 'tmp'
+
+ Dir.mkdir 'tmp/tmpdir'
+ remove_entry_secure 'tmp/tmpdir'
+ assert_file_not_exist 'tmp/tmpdir'
+ assert_file_exist 'tmp'
+
+ Dir.mkdir 'tmp/tmpdir'
+ File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' }
+ File.open('tmp/tmpdir/b', 'w') {|f| f.puts 'dummy' }
+ File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' }
+ remove_entry_secure 'tmp/tmpdir'
+ assert_file_not_exist 'tmp/tmpdir'
+ assert_file_exist 'tmp'
+
+ Dir.mkdir 'tmp/tmpdir'
+ File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' }
+ File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' }
+ remove_entry_secure 'tmp/tmpdir/a', true
+ remove_entry_secure 'tmp/tmpdir/b', true
+ remove_entry_secure 'tmp/tmpdir/c', true
+ assert_file_not_exist 'tmp/tmpdir/a'
+ assert_file_not_exist 'tmp/tmpdir/c'
+ Dir.rmdir 'tmp/tmpdir'
+ end
+
+ def test_remove_entry_secure_symlink
+ # [ruby-talk:94635] a symlink to the directory
+ Dir.mkdir 'tmp/tmpdir'
+ File.symlink '..', 'tmp/tmpdir/symlink_to_dir'
+ remove_entry_secure 'tmp/tmpdir'
+ assert_file_not_exist 'tmp/tmpdir'
+ assert_file_exist 'tmp'
+ end if have_symlink?
+
+ def test_remove_entry_secure_pathname
+ # pathname
+ Dir.mkdir 'tmp/tmpdir1'; touch 'tmp/tmpdir1/tmp'
+ assert_nothing_raised {
+ remove_entry_secure Pathname.new('tmp/tmpdir1')
+ }
+ assert_file_not_exist 'tmp/tmpdir1'
+ end
+
+ def test_with_big_file
+ prepare_big_file
+
+ cp BIGFILE, 'tmp/cpdest'
+ assert_same_file BIGFILE, 'tmp/cpdest'
+ assert cmp(BIGFILE, 'tmp/cpdest'), 'orig != copied'
+
+ mv 'tmp/cpdest', 'tmp/mvdest'
+ assert_same_file BIGFILE, 'tmp/mvdest'
+ assert_file_not_exist 'tmp/cpdest'
+
+ rm 'tmp/mvdest'
+ assert_file_not_exist 'tmp/mvdest'
+ end
+
+ def test_ln
+ TARGETS.each do |fname|
+ ln fname, 'tmp/lndest'
+ assert_same_file fname, 'tmp/lndest'
+ File.unlink 'tmp/lndest'
+ end
+
+ ln TARGETS, 'tmp'
+ TARGETS.each do |fname|
+ assert_same_file fname, 'tmp/' + File.basename(fname)
+ end
+ TARGETS.each do |fname|
+ File.unlink 'tmp/' + File.basename(fname)
+ end
+
+ # src==dest (1) same path
+ touch 'tmp/cptmp'
+ assert_raise(Errno::EEXIST) {
+ ln 'tmp/cptmp', 'tmp/cptmp'
+ }
+ end if have_hardlink?
+
+ def test_ln_symlink
+ touch 'tmp/cptmp'
+ # src==dest (2) symlink and its target
+ File.symlink 'cptmp', 'tmp/symlink'
+ assert_raise(Errno::EEXIST) {
+ ln 'tmp/cptmp', 'tmp/symlink' # normal file -> symlink
+ }
+ assert_raise(Errno::EEXIST) {
+ ln 'tmp/symlink', 'tmp/cptmp' # symlink -> normal file
+ }
+ # src==dest (3) looped symlink
+ File.symlink 'cptmp_symlink', 'tmp/cptmp_symlink'
+ begin
+ ln 'tmp/cptmp_symlink', 'tmp/cptmp_symlink'
+ rescue => err
+ assert_kind_of SystemCallError, err
+ end
+ end if have_symlink?
+
+ def test_ln_pathname
+ # pathname
+ touch 'tmp/lntmp'
+ assert_nothing_raised {
+ ln Pathname.new('tmp/lntmp'), 'tmp/lndesttmp1'
+ ln 'tmp/lntmp', Pathname.new('tmp/lndesttmp2')
+ ln Pathname.new('tmp/lntmp'), Pathname.new('tmp/lndesttmp3')
+ }
+ end if have_hardlink?
+
+ def test_ln_s
+ check_singleton :ln_s
+
+ TARGETS.each do |fname|
+ ln_s fname, 'tmp/lnsdest'
+ assert FileTest.symlink?('tmp/lnsdest'), 'not symlink'
+ assert_equal fname, File.readlink('tmp/lnsdest')
+ rm_f 'tmp/lnsdest'
+ end
+ assert_nothing_raised {
+ ln_s 'symlink', 'tmp/symlink'
+ }
+ assert_symlink 'tmp/symlink'
+
+ # pathname
+ touch 'tmp/lnsdest'
+ assert_nothing_raised {
+ ln_s Pathname.new('lnsdest'), 'tmp/symlink_tmp1'
+ ln_s 'lnsdest', Pathname.new('tmp/symlink_tmp2')
+ ln_s Pathname.new('lnsdest'), Pathname.new('tmp/symlink_tmp3')
+ }
+ end if have_symlink?
+
+ def test_ln_sf
+ check_singleton :ln_sf
+
+ TARGETS.each do |fname|
+ ln_sf fname, 'tmp/lnsdest'
+ assert FileTest.symlink?('tmp/lnsdest'), 'not symlink'
+ assert_equal fname, File.readlink('tmp/lnsdest')
+ ln_sf fname, 'tmp/lnsdest'
+ ln_sf fname, 'tmp/lnsdest'
+ end
+ assert_nothing_raised {
+ ln_sf 'symlink', 'tmp/symlink'
+ }
+
+ # pathname
+ touch 'tmp/lns_dest'
+ assert_nothing_raised {
+ ln_sf Pathname.new('lns_dest'), 'tmp/symlink_tmp1'
+ ln_sf 'lns_dest', Pathname.new('tmp/symlink_tmp2')
+ ln_sf Pathname.new('lns_dest'), Pathname.new('tmp/symlink_tmp3')
+ }
+ end if have_symlink?
+
+ def test_mkdir
+ check_singleton :mkdir
+
+ my_rm_rf 'tmpdatadir'
+ mkdir 'tmpdatadir'
+ assert_directory 'tmpdatadir'
+ Dir.rmdir 'tmpdatadir'
+
+ mkdir 'tmpdatadir/'
+ assert_directory 'tmpdatadir'
+ Dir.rmdir 'tmpdatadir'
+
+ mkdir 'tmp/mkdirdest'
+ assert_directory 'tmp/mkdirdest'
+ Dir.rmdir 'tmp/mkdirdest'
+
+ mkdir 'tmp/tmp', :mode => 0700
+ assert_directory 'tmp/tmp'
+ assert_equal 0700, (File.stat('tmp/tmp').mode & 0777) if have_file_perm?
+ Dir.rmdir 'tmp/tmp'
+ end
+
+ def test_mkdir_file_perm
+ mkdir 'tmp/tmp', :mode => 07777
+ assert_directory 'tmp/tmp'
+ assert_equal 07777, (File.stat('tmp/tmp').mode & 07777)
+ Dir.rmdir 'tmp/tmp'
+ end if have_file_perm?
+
+ def test_mkdir_lf_in_path
+ mkdir "tmp-first-line\ntmp-second-line"
+ assert_directory "tmp-first-line\ntmp-second-line"
+ Dir.rmdir "tmp-first-line\ntmp-second-line"
+ end if lf_in_path_allowed?
+
+ def test_mkdir_pathname
+ # pathname
+ assert_nothing_raised {
+ mkdir Pathname.new('tmp/tmpdirtmp')
+ mkdir [Pathname.new('tmp/tmpdirtmp2'), Pathname.new('tmp/tmpdirtmp3')]
+ }
+ end
+
+ def test_mkdir_p
+ check_singleton :mkdir_p
+
+ dirs = %w(
+ tmpdir/dir/
+ tmpdir/dir/./
+ tmpdir/dir/./.././dir/
+ tmpdir/a
+ tmpdir/a/
+ tmpdir/a/b
+ tmpdir/a/b/
+ tmpdir/a/b/c/
+ tmpdir/a/b/c
+ tmpdir/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a
+ tmpdir/a/a
+ )
+ my_rm_rf 'tmpdir'
+ dirs.each do |d|
+ mkdir_p d
+ assert_directory d
+ assert_file_not_exist "#{d}/a"
+ assert_file_not_exist "#{d}/b"
+ assert_file_not_exist "#{d}/c"
+ my_rm_rf 'tmpdir'
+ end
+ dirs.each do |d|
+ mkdir_p d
+ assert_directory d
+ end
+ rm_rf 'tmpdir'
+ dirs.each do |d|
+ mkdir_p "#{Dir.pwd}/#{d}"
+ assert_directory d
+ end
+ rm_rf 'tmpdir'
+
+ mkdir_p 'tmp/tmp/tmp', :mode => 0700
+ assert_directory 'tmp/tmp'
+ assert_directory 'tmp/tmp/tmp'
+ assert_equal 0700, (File.stat('tmp/tmp').mode & 0777) if have_file_perm?
+ assert_equal 0700, (File.stat('tmp/tmp/tmp').mode & 0777) if have_file_perm?
+ rm_rf 'tmp/tmp'
+
+ mkdir_p 'tmp/tmp', :mode => 0
+ assert_directory 'tmp/tmp'
+ assert_equal 0, (File.stat('tmp/tmp').mode & 0777) if have_file_perm?
+ # DO NOT USE rm_rf here.
+ # (rm(1) try to chdir to parent directory, it fails to remove directory.)
+ Dir.rmdir 'tmp/tmp'
+ Dir.rmdir 'tmp'
+ end
+
+ def test_mkdir_p_file_perm
+ mkdir_p 'tmp/tmp/tmp', :mode => 07777
+ assert_directory 'tmp/tmp/tmp'
+ assert_equal 07777, (File.stat('tmp/tmp/tmp').mode & 07777)
+ Dir.rmdir 'tmp/tmp/tmp'
+ Dir.rmdir 'tmp/tmp'
+ end if have_file_perm?
+
+ def test_mkdir_p_pathname
+ # pathname
+ assert_nothing_raised {
+ mkdir_p Pathname.new('tmp/tmp/tmp')
+ }
+ end
+
+ def test_install
+ check_singleton :install
+
+ File.open('tmp/aaa', 'w') {|f| f.puts 'aaa' }
+ File.open('tmp/bbb', 'w') {|f| f.puts 'bbb' }
+ install 'tmp/aaa', 'tmp/bbb', :mode => 0600
+ assert_equal "aaa\n", File.read('tmp/bbb')
+ assert_equal 0600, (File.stat('tmp/bbb').mode & 0777) if have_file_perm?
+
+ t = File.mtime('tmp/bbb')
+ install 'tmp/aaa', 'tmp/bbb'
+ assert_equal "aaa\n", File.read('tmp/bbb')
+ assert_equal 0600, (File.stat('tmp/bbb').mode & 0777) if have_file_perm?
+ assert_equal_time t, File.mtime('tmp/bbb')
+
+ File.unlink 'tmp/aaa'
+ File.unlink 'tmp/bbb'
+
+ # src==dest (1) same path
+ touch 'tmp/cptmp'
+ assert_raise(ArgumentError) {
+ install 'tmp/cptmp', 'tmp/cptmp'
+ }
+ end
+
+ def test_install_symlink
+ touch 'tmp/cptmp'
+ # src==dest (2) symlink and its target
+ File.symlink 'cptmp', 'tmp/cptmp_symlink'
+ assert_raise(ArgumentError) {
+ install 'tmp/cptmp', 'tmp/cptmp_symlink'
+ }
+ assert_raise(ArgumentError) {
+ install 'tmp/cptmp_symlink', 'tmp/cptmp'
+ }
+ # src==dest (3) looped symlink
+ File.symlink 'symlink', 'tmp/symlink'
+ assert_raise(Errno::ELOOP) {
+ # File#install invokes open(2), always ELOOP must be raised
+ install 'tmp/symlink', 'tmp/symlink'
+ }
+ end if have_symlink?
+
+ def test_install_pathname
+ # pathname
+ assert_nothing_raised {
+ rm_f 'tmp/a'; touch 'tmp/a'
+ install 'tmp/a', Pathname.new('tmp/b')
+ rm_f 'tmp/a'; touch 'tmp/a'
+ install Pathname.new('tmp/a'), 'tmp/b'
+ rm_f 'tmp/a'; touch 'tmp/a'
+ install Pathname.new('tmp/a'), Pathname.new('tmp/b')
+ rm_f 'tmp/a'
+ touch 'tmp/a'
+ touch 'tmp/b'
+ mkdir 'tmp/dest'
+ install [Pathname.new('tmp/a'), Pathname.new('tmp/b')], 'tmp/dest'
+ my_rm_rf 'tmp/dest'
+ mkdir 'tmp/dest'
+ install [Pathname.new('tmp/a'), Pathname.new('tmp/b')], Pathname.new('tmp/dest')
+ }
+ end
+
+ def test_chmod
+ check_singleton :chmod
+
+ touch 'tmp/a'
+ chmod 0700, 'tmp/a'
+ assert_equal 0700, File.stat('tmp/a').mode & 0777
+ chmod 0500, 'tmp/a'
+ assert_equal 0500, File.stat('tmp/a').mode & 0777
+ end if have_file_perm?
+
+ def test_chmod_R
+ check_singleton :chmod_R
+
+ mkdir_p 'tmp/dir/dir'
+ touch %w( tmp/dir/file tmp/dir/dir/file )
+ chmod_R 0700, 'tmp/dir'
+ assert_equal 0700, File.stat('tmp/dir').mode & 0777
+ assert_equal 0700, File.stat('tmp/dir/file').mode & 0777
+ assert_equal 0700, File.stat('tmp/dir/dir').mode & 0777
+ assert_equal 0700, File.stat('tmp/dir/dir/file').mode & 0777
+ chmod_R 0500, 'tmp/dir'
+ assert_equal 0500, File.stat('tmp/dir').mode & 0777
+ assert_equal 0500, File.stat('tmp/dir/file').mode & 0777
+ assert_equal 0500, File.stat('tmp/dir/dir').mode & 0777
+ assert_equal 0500, File.stat('tmp/dir/dir/file').mode & 0777
+ chmod_R 0700, 'tmp/dir' # to remove
+ end if have_file_perm?
+
+ # FIXME: How can I test this method?
+ def test_chown
+ check_singleton :chown
+ end if have_file_perm?
+
+ # FIXME: How can I test this method?
+ def test_chown_R
+ check_singleton :chown_R
+ end if have_file_perm?
+
+ def test_copy_entry
+ check_singleton :copy_entry
+
+ each_srcdest do |srcpath, destpath|
+ copy_entry srcpath, destpath
+ assert_same_file srcpath, destpath
+ assert_equal File.stat(srcpath).ftype, File.stat(destpath).ftype
+ end
+ end
+
+ def test_copy_entry_symlink
+ # root is a symlink
+ File.symlink 'somewhere', 'tmp/symsrc'
+ copy_entry 'tmp/symsrc', 'tmp/symdest'
+ assert_symlink 'tmp/symdest'
+ assert_equal 'somewhere', File.readlink('tmp/symdest')
+
+ # content is a symlink
+ mkdir 'tmp/dir'
+ File.symlink 'somewhere', 'tmp/dir/sym'
+ copy_entry 'tmp/dir', 'tmp/dirdest'
+ assert_directory 'tmp/dirdest'
+ assert_not_symlink 'tmp/dirdest'
+ assert_symlink 'tmp/dirdest/sym'
+ assert_equal 'somewhere', File.readlink('tmp/dirdest/sym')
+ end if have_symlink?
+
+ def test_copy_file
+ check_singleton :copy_file
+
+ each_srcdest do |srcpath, destpath|
+ copy_file srcpath, destpath
+ assert_same_file srcpath, destpath
+ end
+ end
+
+ def test_copy_stream
+ check_singleton :copy_stream
+ # IO
+ each_srcdest do |srcpath, destpath|
+ File.open(srcpath, 'rb') {|src|
+ File.open(destpath, 'wb') {|dest|
+ copy_stream src, dest
+ }
+ }
+ assert_same_file srcpath, destpath
+ end
+ end
+
+ def test_copy_stream_duck
+ check_singleton :copy_stream
+ # duck typing test [ruby-dev:25369]
+ each_srcdest do |srcpath, destpath|
+ File.open(srcpath, 'rb') {|src|
+ File.open(destpath, 'wb') {|dest|
+ copy_stream Stream.new(src), Stream.new(dest)
+ }
+ }
+ assert_same_file srcpath, destpath
+ end
+ end
+
+ def test_remove_file
+ check_singleton :remove_file
+ File.open('data/tmp', 'w') {|f| f.puts 'dummy' }
+ remove_file 'data/tmp'
+ assert_file_not_exist 'data/tmp'
+ end
+
+ def test_remove_file_file_perm
+ File.open('data/tmp', 'w') {|f| f.puts 'dummy' }
+ File.chmod 0, 'data/tmp'
+ remove_file 'data/tmp'
+ assert_file_not_exist 'data/tmp'
+ end if have_file_perm?
+
+ def test_remove_dir
+ check_singleton :remove_dir
+ Dir.mkdir 'data/tmpdir'
+ File.open('data/tmpdir/a', 'w') {|f| f.puts 'dummy' }
+ remove_dir 'data/tmpdir'
+ assert_file_not_exist 'data/tmpdir'
+ end
+
+ def test_remove_dir_file_perm
+ Dir.mkdir 'data/tmpdir'
+ File.chmod 0555, 'data/tmpdir'
+ remove_dir 'data/tmpdir'
+ assert_file_not_exist 'data/tmpdir'
+ end if have_file_perm?
+
+ def test_compare_file
+ check_singleton :compare_file
+ # FIXME
+ end
+
+ def test_compare_stream
+ check_singleton :compare_stream
+ # FIXME
+ end
+
+ class Stream
+ def initialize(f)
+ @f = f
+ end
+
+ def read(*args)
+ @f.read(*args)
+ end
+
+ def write(str)
+ @f.write str
+ end
+ end
+
+ def test_uptodate?
+ check_singleton :uptodate?
+ prepare_time_data
+ Dir.chdir('data') {
+ assert( uptodate?('newest', %w(old newer notexist)) )
+ assert( ! uptodate?('newer', %w(old newest notexist)) )
+ assert( ! uptodate?('notexist', %w(old newest newer)) )
+ }
+
+ # pathname
+ touch 'tmp/a'
+ touch 'tmp/b'
+ touch 'tmp/c'
+ assert_nothing_raised {
+ uptodate? Pathname.new('tmp/a'), ['tmp/b', 'tmp/c']
+ uptodate? 'tmp/a', [Pathname.new('tmp/b'), 'tmp/c']
+ uptodate? 'tmp/a', ['tmp/b', Pathname.new('tmp/c')]
+ uptodate? Pathname.new('tmp/a'), [Pathname.new('tmp/b'), Pathname.new('tmp/c')]
+ }
+ end
+
+ def test_cd
+ check_singleton :cd
+ end
+
+ def test_chdir
+ check_singleton :chdir
+ end
+
+ def test_getwd
+ check_singleton :getwd
+ end
+
+ def test_identical?
+ check_singleton :identical?
+ end
+
+ def test_link
+ check_singleton :link
+ end
+
+ def test_makedirs
+ check_singleton :makedirs
+ end
+
+ def test_mkpath
+ check_singleton :mkpath
+ end
+
+ def test_move
+ check_singleton :move
+ end
+
+ def test_rm_rf
+ check_singleton :rm_rf
+ end
+
+ def test_rmdir
+ check_singleton :rmdir
+ end
+
+ def test_rmtree
+ check_singleton :rmtree
+ end
+
+ def test_safe_unlink
+ check_singleton :safe_unlink
+ end
+
+ def test_symlink
+ check_singleton :symlink
+ end
+
+ def test_touch
+ check_singleton :touch
+ end
+
+ def test_collect_methods
+ end
+
+ def test_commands
+ end
+
+ def test_have_option?
+ end
+
+ def test_options
+ end
+
+ def test_options_of
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/fileutils/test_nowrite.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/fileutils/test_nowrite.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/fileutils/test_nowrite.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,99 @@
+# $Id: test_nowrite.rb 25189 2009-10-02 12:04:37Z akr $
+
+require 'fileutils'
+require_relative 'fileasserts'
+require 'tmpdir'
+require 'test/unit'
+
+class TestFileUtilsNoWrite < Test::Unit::TestCase
+
+ include FileUtils::NoWrite
+
+ def test_visibility
+ FileUtils::METHODS.each do |m|
+ assert_equal true, FileUtils::NoWrite.respond_to?(m, true),
+ "FileUtils::NoWrite.#{m} is not defined"
+ assert_equal true, FileUtils::NoWrite.respond_to?(m, false),
+ "FileUtils::NoWrite.#{m} is not public"
+ end
+ FileUtils::METHODS.each do |m|
+ assert_equal true, respond_to?(m, true),
+ "FileUtils::NoWrite\##{m} is not defined"
+ assert_equal true, FileUtils::NoWrite.private_method_defined?(m),
+ "FileUtils::NoWrite\##{m} is not private"
+ end
+ end
+
+ def my_rm_rf(path)
+ if File.exist?('/bin/rm')
+ system %Q[/bin/rm -rf "#{path}"]
+ else
+ FileUtils.rm_rf path
+ end
+ end
+
+ SRC = 'data/src'
+ COPY = 'data/copy'
+
+ def setup
+ @prevdir = Dir.pwd
+ tmproot = "#{Dir.tmpdir}/fileutils.rb.#{$$}"
+ Dir.mkdir tmproot unless File.directory?(tmproot)
+ Dir.chdir tmproot
+ my_rm_rf 'data'; Dir.mkdir 'data'
+ my_rm_rf 'tmp'; Dir.mkdir 'tmp'
+ File.open(SRC, 'w') {|f| f.puts 'dummy' }
+ File.open(COPY, 'w') {|f| f.puts 'dummy' }
+ end
+
+ def teardown
+ tmproot = Dir.pwd
+ Dir.chdir @prevdir
+ my_rm_rf tmproot
+ end
+
+ def test_cp
+ cp SRC, 'tmp/cp'
+ check 'tmp/cp'
+ end
+
+ def test_mv
+ mv SRC, 'tmp/mv'
+ check 'tmp/mv'
+ end
+
+ def check(dest)
+ assert_file_not_exist dest
+ assert_file_exist SRC
+ assert_same_file SRC, COPY
+ end
+
+ def test_rm
+ rm SRC
+ assert_file_exist SRC
+ assert_same_file SRC, COPY
+ end
+
+ def test_rm_f
+ rm_f SRC
+ assert_file_exist SRC
+ assert_same_file SRC, COPY
+ end
+
+ def test_rm_rf
+ rm_rf SRC
+ assert_file_exist SRC
+ assert_same_file SRC, COPY
+ end
+
+ def test_mkdir
+ mkdir 'dir'
+ assert_file_not_exist 'dir'
+ end
+
+ def test_mkdir_p
+ mkdir 'dir/dir/dir'
+ assert_file_not_exist 'dir'
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/fileutils/test_verbose.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/fileutils/test_verbose.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/fileutils/test_verbose.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,25 @@
+# $Id: test_verbose.rb 25189 2009-10-02 12:04:37Z akr $
+
+require 'test/unit'
+require 'fileutils'
+
+class TestFileUtilsVerbose < Test::Unit::TestCase
+
+ include FileUtils::Verbose
+
+ def test_visibility
+ FileUtils::METHODS.each do |m|
+ assert_equal true, FileUtils::Verbose.respond_to?(m, true),
+ "FileUtils::Verbose.#{m} is not defined"
+ assert_equal true, FileUtils::Verbose.respond_to?(m, false),
+ "FileUtils::Verbose.#{m} is not public"
+ end
+ FileUtils::METHODS.each do |m|
+ assert_equal true, respond_to?(m, true),
+ "FileUtils::Verbose.#{m} is not defined"
+ assert_equal true, FileUtils::Verbose.private_method_defined?(m),
+ "FileUtils::Verbose.#{m} is not private"
+ end
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/gdbm/test_gdbm.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/gdbm/test_gdbm.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/gdbm/test_gdbm.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,715 @@
+require 'test/unit'
+require 'tmpdir'
+
+begin
+ require 'gdbm'
+rescue LoadError
+end
+
+if defined? GDBM
+ require 'tmpdir'
+ require 'fileutils'
+
+ class TestGDBM < Test::Unit::TestCase
+ def TestGDBM.uname_s
+ require 'rbconfig'
+ case RbConfig::CONFIG['target_os']
+ when 'cygwin'
+ require 'Win32API'
+ uname = Win32API.new('cygwin1', 'uname', 'P', 'I')
+ utsname = ' ' * 100
+ raise 'cannot get system name' if uname.call(utsname) == -1
+
+ utsname.unpack('A20' * 5)[0]
+ else
+ RbConfig::CONFIG['target_os']
+ end
+ end
+ SYSTEM = uname_s
+
+ def setup
+ @tmpdir = Dir.mktmpdir("tmptest_gdbm")
+ @prefix = "tmptest_gdbm_#{$$}"
+ @path = "#{@tmpdir}/#{@prefix}_"
+ assert_instance_of(GDBM, @gdbm = GDBM.new(@path))
+
+ # prepare to make readonly GDBM file
+ GDBM.open("#{@tmpdir}/#{@prefix}_rdonly", 0400) {|gdbm|
+ gdbm['foo'] = 'FOO'
+ }
+ assert_instance_of(GDBM, @gdbm_rdonly = GDBM.new("#{@tmpdir}/#{@prefix}_rdonly", nil))
+ end
+ def teardown
+ assert_nil(@gdbm.close)
+ assert_nil(@gdbm_rdonly.close)
+ ObjectSpace.each_object(GDBM) do |obj|
+ obj.close unless obj.closed?
+ end
+ FileUtils.remove_entry_secure @tmpdir
+ end
+
+ def check_size(expect, gdbm=@gdbm)
+ assert_equal(expect, gdbm.size)
+ n = 0
+ gdbm.each { n+=1 }
+ assert_equal(expect, n)
+ if expect == 0
+ assert_equal(true, gdbm.empty?)
+ else
+ assert_equal(false, gdbm.empty?)
+ end
+ end
+
+ def have_fork?
+ begin
+ fork{}
+ true
+ rescue NotImplementedError
+ false
+ end
+ end
+
+ def test_s_new_has_no_block
+ # GDBM.new ignore the block
+ foo = true
+ assert_instance_of(GDBM, gdbm = GDBM.new("#{@tmpdir}/#{@prefix}") { foo = false })
+ assert_equal(foo, true)
+ assert_nil(gdbm.close)
+ end
+ def test_s_open_create_new
+ return if /^CYGWIN_9/ =~ SYSTEM
+
+ save_mask = File.umask(0)
+ begin
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}"))
+ gdbm.close
+ assert_equal(File.stat("#{@tmpdir}/#{@prefix}").mode & 0777, 0666) unless /mswin|mignw/ =~ RUBY_PLATFORM
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}2", 0644))
+ gdbm.close
+ assert_equal(File.stat("#{@tmpdir}/#{@prefix}2").mode & 0777, 0644)
+ ensure
+ File.umask save_mask
+ end
+ end
+ def test_s_open_no_create
+ assert_nil(gdbm = GDBM.open("#{@tmpdir}/#{@prefix}", nil),
+ "this test is failed on libgdbm 1.8.0")
+ ensure
+ gdbm.close if gdbm
+ end
+ def test_s_open_3rd_arg
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}", 0644,
+ GDBM::FAST))
+ gdbm.close
+
+ # gdbm 1.8.0 specific
+ if defined? GDBM::SYNC
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}", 0644,
+ GDBM::SYNC))
+ gdbm.close
+ end
+ # gdbm 1.8.0 specific
+ if defined? GDBM::NOLOCK
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}", 0644,
+ GDBM::NOLOCK))
+ gdbm.close
+ end
+ end
+ def test_s_open_with_block
+ assert_equal(GDBM.open("#{@tmpdir}/#{@prefix}") { :foo }, :foo)
+ end
+ def test_s_open_lock
+ return unless have_fork? # snip this test
+ pid = fork() {
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}", 0644))
+ sleep 2
+ }
+ begin
+ sleep 1
+ assert_raise(Errno::EWOULDBLOCK) {
+ begin
+ assert_instance_of(GDBM, gdbm2 = GDBM.open("#{@tmpdir}/#{@prefix}", 0644))
+ rescue Errno::EAGAIN, Errno::EACCES
+ raise Errno::EWOULDBLOCK
+ end
+ }
+ ensure
+ Process.wait pid
+ end
+ end
+
+=begin
+ # Is it guaranteed on many OS?
+ def test_s_open_lock_one_process
+ # locking on one process
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}", 0644))
+ assert_raise(Errno::EWOULDBLOCK) {
+ begin
+ GDBM.open("#{@tmpdir}/#{@prefix}", 0644)
+ rescue Errno::EAGAIN
+ raise Errno::EWOULDBLOCK
+ end
+ }
+ end
+=end
+
+ def test_s_open_nolock
+ # gdbm 1.8.0 specific
+ if not defined? GDBM::NOLOCK
+ return
+ end
+ return unless have_fork? # snip this test
+
+ pid = fork() {
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}", 0644,
+ GDBM::NOLOCK))
+ sleep 2
+ }
+ sleep 1
+ begin
+ gdbm2 = nil
+ assert_nothing_raised(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
+ assert_instance_of(GDBM, gdbm2 = GDBM.open("#{@tmpdir}/#{@prefix}", 0644))
+ }
+ ensure
+ Process.wait pid
+ gdbm2.close if gdbm2
+ end
+
+ p Dir.glob("#{@tmpdir}/#{@prefix}*") if $DEBUG
+
+ pid = fork() {
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}", 0644))
+ sleep 2
+ }
+ begin
+ sleep 1
+ gdbm2 = nil
+ assert_nothing_raised(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
+ # this test is failed on Cygwin98 (???)
+ assert_instance_of(GDBM, gdbm2 = GDBM.open("#{@tmpdir}/#{@prefix}", 0644,
+ GDBM::NOLOCK))
+ }
+ ensure
+ Process.wait pid
+ gdbm2.close if gdbm2
+ end
+ end
+
+ def test_s_open_error
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}", 0))
+ assert_raise(Errno::EACCES, Errno::EWOULDBLOCK) {
+ GDBM.open("#{@tmpdir}/#{@prefix}", 0)
+ }
+ gdbm.close
+ end
+
+ def test_close
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}"))
+ assert_nil(gdbm.close)
+
+ # closed GDBM file
+ assert_raise(RuntimeError) { gdbm.close }
+ end
+
+ def test_aref
+ assert_equal('bar', @gdbm['foo'] = 'bar')
+ assert_equal('bar', @gdbm['foo'])
+
+ assert_nil(@gdbm['bar'])
+ end
+
+ def test_fetch
+ assert_equal('bar', @gdbm['foo']='bar')
+ assert_equal('bar', @gdbm.fetch('foo'))
+
+ # key not found
+ assert_raise(IndexError) {
+ @gdbm.fetch('bar')
+ }
+
+ # test for `ifnone' arg
+ assert_equal('baz', @gdbm.fetch('bar', 'baz'))
+
+ # test for `ifnone' block
+ assert_equal('foobar', @gdbm.fetch('bar') {|key| 'foo' + key })
+ end
+
+ def test_aset
+ num = 0
+ 2.times {|i|
+ assert_equal('foo', @gdbm['foo'] = 'foo')
+ assert_equal('foo', @gdbm['foo'])
+ assert_equal('bar', @gdbm['foo'] = 'bar')
+ assert_equal('bar', @gdbm['foo'])
+
+ num += 1 if i == 0
+ assert_equal(num, @gdbm.size)
+
+ # assign nil
+ assert_equal('', @gdbm['bar'] = '')
+ assert_equal('', @gdbm['bar'])
+
+ num += 1 if i == 0
+ assert_equal(num, @gdbm.size)
+
+ # empty string
+ assert_equal('', @gdbm[''] = '')
+ assert_equal('', @gdbm[''])
+
+ num += 1 if i == 0
+ assert_equal(num, @gdbm.size)
+
+ # Fixnum
+ assert_equal('200', @gdbm['100'] = '200')
+ assert_equal('200', @gdbm['100'])
+
+ num += 1 if i == 0
+ assert_equal(num, @gdbm.size)
+
+ # Big key and value
+ assert_equal('y' * 100, @gdbm['x' * 100] = 'y' * 100)
+ assert_equal('y' * 100, @gdbm['x' * 100])
+
+ num += 1 if i == 0
+ assert_equal(num, @gdbm.size)
+ }
+ end
+
+ def test_key
+ assert_equal('bar', @gdbm['foo'] = 'bar')
+ assert_equal('foo', @gdbm.key('bar'))
+ assert_nil(@gdbm['bar'])
+ end
+
+ def test_values_at
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+ @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
+ assert_equal(values.reverse, @gdbm.values_at(*keys.reverse))
+ end
+
+ def test_select_with_block
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+ @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
+ ret = @gdbm.select {|k,v|
+ assert_equal(k.upcase, v)
+ k != "bar"
+ }
+ assert_equal([['baz', 'BAZ'], ['foo', 'FOO']],
+ ret.sort)
+ end
+
+ def test_length
+ num = 10
+ assert_equal(0, @gdbm.size)
+ num.times {|i|
+ i = i.to_s
+ @gdbm[i] = i
+ }
+ assert_equal(num, @gdbm.size)
+
+ @gdbm.shift
+
+ assert_equal(num - 1, @gdbm.size)
+ end
+
+ def test_empty?
+ assert_equal(true, @gdbm.empty?)
+ @gdbm['foo'] = 'FOO'
+ assert_equal(false, @gdbm.empty?)
+ end
+
+ def test_each_pair
+ n = 0
+ @gdbm.each_pair { n += 1 }
+ assert_equal(0, n)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
+
+ n = 0
+ ret = @gdbm.each_pair {|key, val|
+ assert_not_nil(i = keys.index(key))
+ assert_equal(val, values[i])
+
+ n += 1
+ }
+ assert_equal(keys.size, n)
+ assert_equal(@gdbm, ret)
+ end
+
+ def test_each_value
+ n = 0
+ @gdbm.each_value { n += 1 }
+ assert_equal(0, n)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
+
+ n = 0
+ ret = @gdbm.each_value {|val|
+ assert_not_nil(key = @gdbm.key(val))
+ assert_not_nil(i = keys.index(key))
+ assert_equal(val, values[i])
+
+ n += 1
+ }
+ assert_equal(keys.size, n)
+ assert_equal(@gdbm, ret)
+ end
+
+ def test_each_key
+ n = 0
+ @gdbm.each_key { n += 1 }
+ assert_equal(0, n)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
+
+ n = 0
+ ret = @gdbm.each_key {|key|
+ assert_not_nil(i = keys.index(key))
+ assert_equal(@gdbm[key], values[i])
+
+ n += 1
+ }
+ assert_equal(keys.size, n)
+ assert_equal(@gdbm, ret)
+ end
+
+ def test_keys
+ assert_equal([], @gdbm.keys)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
+
+ assert_equal(keys.sort, @gdbm.keys.sort)
+ assert_equal(values.sort, @gdbm.values.sort)
+ end
+
+ def test_values
+ test_keys
+ end
+
+ def test_shift
+ assert_nil(@gdbm.shift)
+ assert_equal(0, @gdbm.size)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
+
+ ret_keys = []
+ ret_values = []
+ while ret = @gdbm.shift
+ ret_keys.push ret[0]
+ ret_values.push ret[1]
+
+ assert_equal(keys.size - ret_keys.size, @gdbm.size)
+ end
+
+ assert_equal(keys.sort, ret_keys.sort)
+ assert_equal(values.sort, ret_values.sort)
+ end
+
+ def test_delete
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+ key = keys[1]
+
+ assert_nil(@gdbm.delete(key))
+ assert_equal(0, @gdbm.size)
+
+ @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
+
+ assert_equal('BAR', @gdbm.delete(key))
+ assert_nil(@gdbm[key])
+ assert_equal(2, @gdbm.size)
+
+ assert_nil(@gdbm.delete(key))
+
+ if /^CYGWIN_9/ !~ SYSTEM
+ assert_raise(GDBMError) {
+ @gdbm_rdonly.delete("foo")
+ }
+
+ assert_nil(@gdbm_rdonly.delete("bar"))
+ end
+ end
+ def test_delete_with_block
+ key = 'no called block'
+ @gdbm[key] = 'foo'
+ assert_equal('foo', @gdbm.delete(key) {|k| k.replace 'called block'})
+ assert_equal('no called block', key)
+ assert_equal(0, @gdbm.size)
+
+ key = 'no called block'
+ assert_equal(:blockval,
+ @gdbm.delete(key) {|k| k.replace 'called block'; :blockval})
+ assert_equal('called block', key)
+ assert_equal(0, @gdbm.size)
+ end
+
+ def test_delete_if
+ v = "0"
+ 100.times {@gdbm[v] = v; v = v.next}
+
+ ret = @gdbm.delete_if {|key, val| key.to_i < 50}
+ assert_equal(@gdbm, ret)
+ check_size(50, @gdbm)
+
+ ret = @gdbm.delete_if {|key, val| key.to_i >= 50}
+ assert_equal(@gdbm, ret)
+ check_size(0, @gdbm)
+
+ # break
+ v = "0"
+ 100.times {@gdbm[v] = v; v = v.next}
+ check_size(100, @gdbm)
+ n = 0;
+ @gdbm.delete_if {|key, val|
+ break if n > 50
+ n+=1
+ true
+ }
+ assert_equal(51, n)
+ check_size(49, @gdbm)
+
+ @gdbm.clear
+
+ # raise
+ v = "0"
+ 100.times {@gdbm[v] = v; v = v.next}
+ check_size(100, @gdbm)
+ n = 0;
+ begin
+ @gdbm.delete_if {|key, val|
+ raise "runtime error" if n > 50
+ n+=1
+ true
+ }
+ rescue
+ end
+ assert_equal(51, n)
+ check_size(49, @gdbm)
+ end
+
+ def test_reject
+ v = "0"
+ 100.times {@gdbm[v] = v; v = v.next}
+
+ hash = @gdbm.reject {|key, val| key.to_i < 50}
+ assert_instance_of(Hash, hash)
+ assert_equal(100, @gdbm.size)
+
+ assert_equal(50, hash.size)
+ hash.each_pair {|key,val|
+ assert_equal(false, key.to_i < 50)
+ assert_equal(key, val)
+ }
+
+ hash = @gdbm.reject {|key, val| key.to_i < 100}
+ assert_instance_of(Hash, hash)
+ assert_equal(true, hash.empty?)
+ end
+
+ def test_clear
+ v = "1"
+ 100.times {v = v.next; @gdbm[v] = v}
+
+ assert_equal(@gdbm, @gdbm.clear)
+
+ # validate GDBM#size
+ i = 0
+ @gdbm.each { i += 1 }
+ assert_equal(@gdbm.size, i)
+ assert_equal(0, i)
+ end
+
+ def test_invert
+ v = "0"
+ 100.times {@gdbm[v] = v; v = v.next}
+
+ hash = @gdbm.invert
+ assert_instance_of(Hash, hash)
+ assert_equal(100, hash.size)
+ hash.each_pair {|key, val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_update
+ hash = {}
+ v = "0"
+ 100.times {v = v.next; hash[v] = v}
+
+ @gdbm["101"] = "101"
+ @gdbm.update hash
+ assert_equal(101, @gdbm.size)
+ @gdbm.each_pair {|key, val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_replace
+ hash = {}
+ v = "0"
+ 100.times {v = v.next; hash[v] = v}
+
+ @gdbm["101"] = "101"
+ @gdbm.replace hash
+ assert_equal(100, @gdbm.size)
+ @gdbm.each_pair {|key, val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_reorganize
+ size1 = File.size(@path)
+ i = "1"
+ 1000.times {i = i.next; @gdbm[i] = i}
+ @gdbm.clear
+ @gdbm.sync
+
+ size2 = File.size(@path)
+ @gdbm.reorganize
+ size3 = File.size(@path)
+
+ # p [size1, size2, size3]
+ assert_equal(true, size1 < size2)
+ # this test is failed on Cygwin98. `GDBM version 1.8.0, as of May 19, 1999'
+ assert_equal(true, size3 < size2)
+ assert_equal(size1, size3)
+ end
+
+ def test_sync
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}", 0666, GDBM::FAST))
+ assert_equal(gdbm.sync, gdbm)
+ gdbm.close
+ assert_instance_of(GDBM, gdbm = GDBM.open("#{@tmpdir}/#{@prefix}", 0666))
+ assert_equal(gdbm.sync, gdbm)
+ gdbm.close
+ end
+
+ def test_cachesize=
+ assert_equal(@gdbm.cachesize = 1024, 1024)
+ end
+
+ def test_fastmode=
+ assert_equal(@gdbm.fastmode = true, true)
+ end
+
+ def test_syncmode=
+ assert_equal(@gdbm.syncmode = true, true)
+ end
+
+ def test_haskey?
+ assert_equal('bar', @gdbm['foo']='bar')
+ assert_equal(true, @gdbm.has_key?('foo'))
+ assert_equal(false, @gdbm.has_key?('bar'))
+ end
+
+ def test_has_value?
+ assert_equal('bar', @gdbm['foo']='bar')
+ assert_equal(true, @gdbm.has_value?('bar'))
+ assert_equal(false, @gdbm.has_value?('foo'))
+ end
+
+ def test_to_a
+ v = "0"
+ 100.times {v = v.next; @gdbm[v] = v}
+
+ ary = @gdbm.to_a
+ assert_instance_of(Array, ary)
+ assert_equal(100, ary.size)
+ ary.each {|key,val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_to_hash
+ v = "0"
+ 100.times {v = v.next; @gdbm[v] = v}
+
+ hash = @gdbm.to_hash
+ assert_instance_of(Hash, hash)
+ assert_equal(100, hash.size)
+ hash.each {|key,val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+ end
+
+ class TestGDBM2 < Test::Unit::TestCase
+ def setup
+ @tmproot = Dir.mktmpdir('ruby-gdbm')
+ end
+
+ def teardown
+ FileUtils.remove_entry_secure @tmproot if File.directory?(@tmproot)
+ end
+
+ def test_reader_open_notexist
+ assert_raise(Errno::ENOENT) {
+ GDBM.open("#{@tmproot}/a", 0666, GDBM::READER)
+ }
+ end
+
+ def test_writer_open_notexist
+ assert_raise(Errno::ENOENT) {
+ GDBM.open("#{@tmproot}/a", 0666, GDBM::WRITER)
+ }
+ end
+
+ def test_wrcreat_open_notexist
+ v = GDBM.open("#{@tmproot}/a", 0666, GDBM::WRCREAT)
+ assert_instance_of(GDBM, v)
+ v.close
+ end
+
+ def test_newdb_open_notexist
+ v = GDBM.open("#{@tmproot}/a", 0666, GDBM::NEWDB)
+ assert_instance_of(GDBM, v)
+ v.close
+ end
+
+ def test_reader_open
+ GDBM.open("#{@tmproot}/a.dbm") {} # create a db.
+ v = GDBM.open("#{@tmproot}/a.dbm", nil, GDBM::READER) {|d|
+ assert_raise(GDBMError) { d["k"] = "v" }
+ true
+ }
+ assert(v)
+ end
+
+ def test_newdb_open
+ GDBM.open("#{@tmproot}/a.dbm") {|dbm|
+ dbm["k"] = "v"
+ }
+ v = GDBM.open("#{@tmproot}/a.dbm", nil, GDBM::NEWDB) {|d|
+ assert_equal(0, d.length)
+ assert_nil(d["k"])
+ true
+ }
+ assert(v)
+ end
+
+ def test_freeze
+ GDBM.open("#{@tmproot}/a.dbm") {|d|
+ d.freeze
+ assert_raise(RuntimeError) { d["k"] = "v" }
+ }
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/iconv/test_basic.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/iconv/test_basic.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/iconv/test_basic.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,59 @@
+require File.expand_path("../utils.rb", __FILE__)
+
+class TestIconv::Basic < TestIconv
+ def test_euc2sjis
+ iconv = Iconv.open('SHIFT_JIS', 'EUC-JP')
+ str = iconv.iconv(EUCJ_STR)
+ str << iconv.iconv(nil)
+ assert_equal(SJIS_STR, str)
+ iconv.close
+ end
+
+ def test_close
+ iconv = Iconv.new('Shift_JIS', 'EUC-JP')
+ output = ""
+ begin
+ output += iconv.iconv(EUCJ_STR)
+ output += iconv.iconv(nil)
+ ensure
+ assert_respond_to(iconv, :close)
+ assert_equal("", iconv.close)
+ assert_equal(SJIS_STR, output)
+ end
+ end
+
+ def test_open_without_block
+ assert_respond_to(Iconv, :open)
+ iconv = Iconv.open('SHIFT_JIS', 'EUC-JP')
+ str = iconv.iconv(EUCJ_STR)
+ str << iconv.iconv(nil)
+ assert_equal(SJIS_STR, str )
+ iconv.close
+ end
+
+ def test_open_with_block
+ input = "#{EUCJ_STR}\n"*2
+ output = ""
+ Iconv.open("Shift_JIS", "EUC-JP") do |cd|
+ input.each_line do |s|
+ output << cd.iconv(s)
+ end
+ output << cd.iconv(nil)
+ end
+ assert_equal("#{SJIS_STR}\n"*2, output)
+ end
+
+ def test_invalid_arguments
+ assert_raise(TypeError) { Iconv.new(nil, 'Shift_JIS') }
+ assert_raise(TypeError) { Iconv.new('Shift_JIS', nil) }
+ assert_raise(TypeError) { Iconv.open(nil, 'Shift_JIS') }
+ assert_raise(TypeError) { Iconv.open('Shift_JIS', nil) }
+ end
+
+ def test_unknown_encoding
+ assert_raise(Iconv::InvalidEncoding) { Iconv.iconv("utf-8", "X-UKNOWN", "heh") }
+ assert_raise(Iconv::InvalidEncoding, '[ruby-dev:39487]') {
+ Iconv.iconv("X-UNKNOWN-1", "X-UNKNOWN-2") {break}
+ }
+ end
+end if defined?(TestIconv)
Added: MacRuby/trunk/test/test-mri/test/iconv/test_option.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/iconv/test_option.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/iconv/test_option.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,43 @@
+require File.expand_path("../utils.rb", __FILE__)
+
+class TestIconv::Option < TestIconv
+ def test_ignore_option
+ begin
+ iconv = Iconv.new('SHIFT_JIS', 'EUC-JP')
+ iconv.transliterate?
+ rescue NotImplementedError
+ return
+ end
+ iconv = Iconv.new('SHIFT_JIS', 'EUC-JP//ignore')
+ str = iconv.iconv(EUCJ_STR)
+ str << iconv.iconv(nil)
+ assert_equal(SJIS_STR, str)
+ iconv.close
+
+ iconv = Iconv.new('SHIFT_JIS//IGNORE', 'EUC-JP//ignore')
+ str = iconv.iconv(EUCJ_STR)
+ str << iconv.iconv(nil)
+ assert_equal(SJIS_STR, str)
+ iconv.close
+ end
+
+ def test_translit_option
+ begin
+ iconv = Iconv.new('SHIFT_JIS', 'EUC-JP')
+ iconv.transliterate?
+ rescue NotImplementedError
+ return
+ end
+ iconv = Iconv.new('SHIFT_JIS', 'EUC-JP//ignore')
+ str = iconv.iconv(EUCJ_STR)
+ str << iconv.iconv(nil)
+ assert_equal(SJIS_STR, str)
+ iconv.close
+
+ iconv = Iconv.new('SHIFT_JIS//TRANSLIT', 'EUC-JP//translit//ignore')
+ str = iconv.iconv(EUCJ_STR)
+ str << iconv.iconv(nil)
+ assert_equal(SJIS_STR, str)
+ iconv.close
+ end
+end if false and defined?(TestIconv)
Added: MacRuby/trunk/test/test-mri/test/iconv/test_partial.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/iconv/test_partial.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/iconv/test_partial.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,41 @@
+require File.expand_path("../utils.rb", __FILE__)
+
+class TestIconv::Partial < TestIconv
+ def test_partial_ascii
+ c = Iconv.open(ASCII, ASCII)
+ ref = '[ruby-core:17092]'
+ rescue
+ return
+ else
+ assert_equal("abc", c.iconv("abc"))
+ assert_equal("c", c.iconv("abc", 2), "#{ref}: with start")
+ assert_equal("c", c.iconv("abc", 2, 1), "#{ref}: with start, length")
+ assert_equal("c", c.iconv("abc", 2, 5), "#{ref}: with start, longer length")
+ assert_equal("bc", c.iconv("abc", -2), "#{ref}: with nagative start")
+ assert_equal("b", c.iconv("abc", -2, 1), "#{ref}: with nagative start, length")
+ assert_equal("bc", c.iconv("abc", -2, 5), "#{ref}: with nagative start, longer length")
+ assert_equal("", c.iconv("abc", 5), "#{ref}: with OOB")
+ assert_equal("", c.iconv("abc", 5, 2), "#{ref}: with OOB, length")
+ ensure
+ c.close if c
+ end
+
+ def test_partial_euc2sjis
+ c = Iconv.open('SHIFT_JIS', 'EUC-JP')
+ rescue
+ return
+ else
+ assert_equal(SJIS_STR[0, 2], c.iconv(EUCJ_STR, 0, 2))
+ assert_equal(SJIS_STR, c.iconv(EUCJ_STR, 0, 20))
+ assert_equal(SJIS_STR[2..-1], c.iconv(EUCJ_STR, 2))
+ assert_equal(SJIS_STR[2, 2], c.iconv(EUCJ_STR, 2, 2))
+ assert_equal(SJIS_STR[2..-1], c.iconv(EUCJ_STR, 2, 20))
+ assert_equal(SJIS_STR[-4..-1], c.iconv(EUCJ_STR, -4))
+ assert_equal(SJIS_STR[-4, 2], c.iconv(EUCJ_STR, -4, 2))
+ assert_equal(SJIS_STR[-4..-1], c.iconv(EUCJ_STR, -4, 20))
+ assert_equal("", c.iconv(EUCJ_STR, 20))
+ assert_equal("", c.iconv(EUCJ_STR, 20, 2))
+ ensure
+ c.close
+ end
+end if defined?(TestIconv)
Added: MacRuby/trunk/test/test-mri/test/iconv/utils.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/iconv/utils.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/iconv/utils.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,26 @@
+begin
+ require 'iconv'
+rescue LoadError
+else
+ require 'test/unit'
+end
+
+class TestIconv < ::Test::Unit::TestCase
+ if defined?(::Encoding) and String.method_defined?(:force_encoding)
+ def self.encode(str, enc)
+ str.force_encoding(enc)
+ end
+ else
+ def self.encode(str, enc)
+ str
+ end
+ end
+
+ def default_test
+ self.class == TestIconv or super
+ end
+
+ ASCII = "ascii"
+ EUCJ_STR = encode("\xa4\xa2\xa4\xa4\xa4\xa6\xa4\xa8\xa4\xaa", "EUC-JP").freeze
+ SJIS_STR = encode("\x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8", "Shift_JIS").freeze
+end if defined?(::Iconv)
Added: MacRuby/trunk/test/test-mri/test/inlinetest.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/inlinetest.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/inlinetest.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,55 @@
+module InlineTest
+ def eval_part(libname, sep, part)
+ path = libpath(libname)
+ program = File.open(path) { |f| f.read }
+ mainpart, endpart = program.split(sep)
+ if endpart.nil?
+ raise RuntimeError.new("No #{part} part in the library '#{path}'")
+ end
+ eval(endpart, TOPLEVEL_BINDING, path, mainpart.count("\n")+1)
+ end
+ module_function :eval_part
+
+ def loadtest(libname)
+ require(libname)
+ in_critical do
+ in_progname(libpath(libname)) do
+ eval_part(libname, /^(?=if\s+(?:\$0\s*==\s*__FILE__|__FILE__\s*==\s*\$0)(?:[\#\s]|$))/, '$0 == __FILE__')
+ end
+ end
+ end
+ module_function :loadtest
+
+ def loadtest__END__part(libname)
+ require(libname)
+ eval_part(libname, /^__END__\r?$/, '__END__')
+ end
+ module_function :loadtest__END__part
+
+ @mutex = Mutex.new
+
+ def self.in_critical(&block)
+ @mutex.synchronize(&block)
+ end
+
+ def self.in_progname(progname)
+ $program_name = progname
+ alias $0 $program_name
+ begin
+ yield
+ ensure
+ alias $0 $PROGRAM_NAME
+ end
+ end
+
+ def self.libpath(libname)
+ libpath = nil
+ $:.find do |path|
+ File.file?(testname = File.join(path, libname)) && libpath = testname
+ end
+ if libpath.nil?
+ raise RuntimeError.new("'#{libname}' not found")
+ end
+ libpath
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/io/nonblock/test_flush.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/io/nonblock/test_flush.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/io/nonblock/test_flush.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,45 @@
+require 'test/unit'
+require 'timeout'
+begin
+ require 'io/nonblock'
+rescue LoadError
+end
+
+class TestIONonblock < Test::Unit::TestCase
+ def test_flush
+ flush_test(*IO.pipe) or
+ (require 'socket'; flush_test(*Socket.pair(:INET, :STREAM))) or
+ skip "nonblocking IO did not work"
+ end
+
+ def flush_test(r, w)
+ begin
+ w.nonblock = true
+ rescue Errno::EBADF
+ return false
+ end
+ w.sync = false
+ w << "b"
+ w.flush
+ w << "a" * 4096
+ result = ""
+ timeout(10) {
+ Thread.new {
+ Thread.pass
+ w.close
+ }
+ t = Thread.new {
+ while (Thread.pass; s = r.read(4096))
+ result << s
+ end
+ }
+ begin
+ w.flush # assert_raise(IOError, "[ruby-dev:24985]") {w.flush}
+ rescue Errno::EBADF, IOError
+ # ignore [ruby-dev:35638]
+ end
+ assert_nothing_raised {t.join}
+ }
+ assert_equal(4097, result.size)
+ end
+end if IO.method_defined?(:nonblock)
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail1.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail1.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail1.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+"A JSON payload should be an object or array, not a string."
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail10.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail10.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail10.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+{"Extra value after close": true} "misplaced quoted value"
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail11.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail11.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail11.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+{"Illegal expression": 1 + 2}
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail12.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail12.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail12.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+{"Illegal invocation": alert()}
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail13.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail13.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail13.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+{"Numbers cannot have leading zeroes": 013}
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail14.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail14.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail14.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+{"Numbers cannot be hex": 0x14}
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail18.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail18.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail18.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail19.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail19.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail19.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+{"Missing colon" null}
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail2.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail2.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail2.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+["Unclosed array"
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail20.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail20.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail20.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+{"Double colon":: null}
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail21.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail21.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail21.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+{"Comma instead of colon", null}
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail22.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail22.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail22.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+["Colon instead of comma": false]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail23.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail23.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail23.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+["Bad value", truth]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail24.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail24.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail24.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+['single quote']
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail25.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail25.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail25.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+["tab character in string "]
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail27.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail27.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail27.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,2 @@
+["line
+break"]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail28.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail28.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail28.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,2 @@
+["line\
+break"]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail3.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail3.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail3.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+{unquoted_key: "keys must be quoted"}
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail4.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail4.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail4.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+["extra comma",]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail5.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail5.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail5.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+["double extra comma",,]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail6.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail6.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail6.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+[ , "<-- missing value"]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail7.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail7.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail7.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+["Comma after the close"],
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail8.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail8.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail8.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+["Extra close"]]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/fail9.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/fail9.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/fail9.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+{"Extra comma": true,}
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/pass1.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/pass1.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/pass1.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,56 @@
+[
+ "JSON Test Pattern pass1",
+ {"object with 1 member":["array with 1 element"]},
+ {},
+ [],
+ -42,
+ true,
+ false,
+ null,
+ {
+ "integer": 1234567890,
+ "real": -9876.543210,
+ "e": 0.123456789e-12,
+ "E": 1.234567890E+34,
+ "": 23456789012E666,
+ "zero": 0,
+ "one": 1,
+ "space": " ",
+ "quote": "\"",
+ "backslash": "\\",
+ "controls": "\b\f\n\r\t",
+ "slash": "/ & \/",
+ "alpha": "abcdefghijklmnopqrstuvwyz",
+ "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
+ "digit": "0123456789",
+ "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
+ "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
+ "true": true,
+ "false": false,
+ "null": null,
+ "array":[ ],
+ "object":{ },
+ "address": "50 St. James Street",
+ "url": "http://www.JSON.org/",
+ "comment": "// /* <!-- --",
+ "# -- --> */": " ",
+ " s p a c e d " :[1,2 , 3
+
+,
+
+4 , 5 , 6 ,7 ],
+ "compact": [1,2,3,4,5,6,7],
+ "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
+ "quotes": "" \u0022 %22 0x22 034 "",
+ "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
+: "A key can be any string"
+ },
+ 0.5 ,98.6
+,
+99.44
+,
+
+1066
+
+
+,"rosebud"]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/pass15.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/pass15.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/pass15.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+["Illegal backslash escape: \x15"]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/pass16.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/pass16.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/pass16.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+["Illegal backslash escape: \'"]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/pass17.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/pass17.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/pass17.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+["Illegal backslash escape: \017"]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/pass2.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/pass2.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/pass2.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/pass26.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/pass26.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/pass26.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+["tab\ character\ in\ string\ "]
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/json/fixtures/pass3.json
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/fixtures/pass3.json (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/fixtures/pass3.json 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,6 @@
+{
+ "JSON Test Pattern pass3": {
+ "The outermost value": "must be an object or array.",
+ "In this test": "It is an object."
+ }
+}
Added: MacRuby/trunk/test/test-mri/test/json/test_json.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/test_json.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/test_json.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,340 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+
+require 'test/unit'
+case ENV['JSON']
+when 'pure' then require 'json/pure'
+when 'ext' then require 'json/ext'
+else require 'json'
+end
+require 'stringio'
+
+unless Array.method_defined?(:permutation)
+ begin
+ require 'enumerator'
+ require 'permutation'
+ class Array
+ def permutation
+ Permutation.for(self).to_enum.map { |x| x.project }
+ end
+ end
+ rescue LoadError
+ warn "Skipping permutation tests."
+ end
+end
+
+class TC_JSON < Test::Unit::TestCase
+ include JSON
+
+ def setup
+ @ary = [1, "foo", 3.14, 4711.0, 2.718, nil, [1,-2,3], false, true].map do
+ |x| [x]
+ end
+ @ary_to_parse = ["1", '"foo"', "3.14", "4711.0", "2.718", "null",
+ "[1,-2,3]", "false", "true"].map do
+ |x| "[#{x}]"
+ end
+ @hash = {
+ 'a' => 2,
+ 'b' => 3.141,
+ 'c' => 'c',
+ 'd' => [ 1, "b", 3.14 ],
+ 'e' => { 'foo' => 'bar' },
+ 'g' => "\"\0\037",
+ 'h' => 1000.0,
+ 'i' => 0.001
+ }
+ @json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\
+ '"g":"\\"\\u0000\\u001f","h":1.0E3,"i":1.0E-3}'
+ end
+
+ def test_construction
+ parser = JSON::Parser.new('test')
+ assert_equal 'test', parser.source
+ end
+
+ def assert_equal_float(expected, is)
+ assert_in_delta(expected.first, is.first, 1e-2)
+ end
+
+ def test_parse_simple_arrays
+ assert_equal([], parse('[]'))
+ assert_equal([], parse(' [ ] '))
+ assert_equal([nil], parse('[null]'))
+ assert_equal([false], parse('[false]'))
+ assert_equal([true], parse('[true]'))
+ assert_equal([-23], parse('[-23]'))
+ assert_equal([23], parse('[23]'))
+ assert_equal([0.23], parse('[0.23]'))
+ assert_equal([0.0], parse('[0e0]'))
+ assert_raises(JSON::ParserError) { parse('[+23.2]') }
+ assert_raises(JSON::ParserError) { parse('[+23]') }
+ assert_raises(JSON::ParserError) { parse('[.23]') }
+ assert_raises(JSON::ParserError) { parse('[023]') }
+ assert_equal_float [3.141], parse('[3.141]')
+ assert_equal_float [-3.141], parse('[-3.141]')
+ assert_equal_float [3.141], parse('[3141e-3]')
+ assert_equal_float [3.141], parse('[3141.1e-3]')
+ assert_equal_float [3.141], parse('[3141E-3]')
+ assert_equal_float [3.141], parse('[3141.0E-3]')
+ assert_equal_float [-3.141], parse('[-3141.0e-3]')
+ assert_equal_float [-3.141], parse('[-3141e-3]')
+ assert_raises(ParserError) { parse('[NaN]') }
+ assert parse('[NaN]', :allow_nan => true).first.nan?
+ assert_raises(ParserError) { parse('[Infinity]') }
+ assert_equal [1.0/0], parse('[Infinity]', :allow_nan => true)
+ assert_raises(ParserError) { parse('[-Infinity]') }
+ assert_equal [-1.0/0], parse('[-Infinity]', :allow_nan => true)
+ assert_equal([""], parse('[""]'))
+ assert_equal(["foobar"], parse('["foobar"]'))
+ assert_equal([{}], parse('[{}]'))
+ end
+
+ def test_parse_simple_objects
+ assert_equal({}, parse('{}'))
+ assert_equal({}, parse(' { } '))
+ assert_equal({ "a" => nil }, parse('{ "a" : null}'))
+ assert_equal({ "a" => nil }, parse('{"a":null}'))
+ assert_equal({ "a" => false }, parse('{ "a" : false } '))
+ assert_equal({ "a" => false }, parse('{"a":false}'))
+ assert_raises(JSON::ParserError) { parse('{false}') }
+ assert_equal({ "a" => true }, parse('{"a":true}'))
+ assert_equal({ "a" => true }, parse(' { "a" : true } '))
+ assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
+ assert_equal({ "a" => -23 }, parse(' { "a" : -23 } '))
+ assert_equal({ "a" => 23 }, parse('{"a":23 } '))
+ assert_equal({ "a" => 23 }, parse(' { "a" : 23 } '))
+ assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
+ assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
+ end
+
+ if Array.method_defined?(:permutation)
+ def test_parse_more_complex_arrays
+ a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
+ a.permutation.each do |perm|
+ json = pretty_generate(perm)
+ assert_equal perm, parse(json)
+ end
+ end
+
+ def test_parse_complex_objects
+ a = [ nil, false, true, "foßbar", [ "n€st€d", true ], { "nested" => true, "n€ßt€ð2" => {} }]
+ a.permutation.each do |perm|
+ s = "a"
+ orig_obj = perm.inject({}) { |h, x| h[s.dup] = x; s = s.succ; h }
+ json = pretty_generate(orig_obj)
+ assert_equal orig_obj, parse(json)
+ end
+ end
+ end
+
+ def test_parse_arrays
+ assert_equal([1,2,3], parse('[1,2,3]'))
+ assert_equal([1.2,2,3], parse('[1.2,2,3]'))
+ assert_equal([[],[[],[]]], parse('[[],[[],[]]]'))
+ end
+
+ def test_parse_values
+ assert_equal([""], parse('[""]'))
+ assert_equal(["\\"], parse('["\\\\"]'))
+ assert_equal(['"'], parse('["\""]'))
+ assert_equal(['\\"\\'], parse('["\\\\\\"\\\\"]'))
+ assert_equal(["\"\b\n\r\t\0\037"],
+ parse('["\"\b\n\r\t\u0000\u001f"]'))
+ for i in 0 ... @ary.size
+ assert_equal(@ary[i], parse(@ary_to_parse[i]))
+ end
+ end
+
+ def test_parse_array
+ assert_equal([], parse('[]'))
+ assert_equal([], parse(' [ ] '))
+ assert_equal([1], parse('[1]'))
+ assert_equal([1], parse(' [ 1 ] '))
+ assert_equal(@ary,
+ parse('[[1],["foo"],[3.14],[47.11e+2],[2718.0E-3],[null],[[1,-2,3]]'\
+ ',[false],[true]]'))
+ assert_equal(@ary, parse(%Q{ [ [1] , ["foo"] , [3.14] \t , [47.11e+2]
+ , [2718.0E-3 ],\r[ null] , [[1, -2, 3 ]], [false ],[ true]\n ] }))
+ end
+
+ class SubArray < Array; end
+
+ def test_parse_array_custom_class
+ res = parse('[]', :array_class => SubArray)
+ assert_equal([], res)
+ assert_equal(SubArray, res.class)
+ end
+
+ def test_parse_object
+ assert_equal({}, parse('{}'))
+ assert_equal({}, parse(' { } '))
+ assert_equal({'foo'=>'bar'}, parse('{"foo":"bar"}'))
+ assert_equal({'foo'=>'bar'}, parse(' { "foo" : "bar" } '))
+ end
+
+ class SubHash < Hash; end
+
+ def test_parse_object_custom_class
+ res = parse('{}', :object_class => SubHash)
+ assert_equal({}, res)
+ assert_equal(SubHash, res.class)
+ end
+
+ def test_parser_reset
+ parser = Parser.new(@json)
+ assert_equal(@hash, parser.parse)
+ assert_equal(@hash, parser.parse)
+ end
+
+ def test_comments
+ json = <<EOT
+{
+ "key1":"value1", // eol comment
+ "key2":"value2" /* multi line
+ * comment */,
+ "key3":"value3" /* multi line
+ // nested eol comment
+ * comment */
+}
+EOT
+ assert_equal(
+ { "key1" => "value1", "key2" => "value2", "key3" => "value3" },
+ parse(json))
+ json = <<EOT
+{
+ "key1":"value1" /* multi line
+ // nested eol comment
+ /* illegal nested multi line comment */
+ * comment */
+}
+EOT
+ assert_raises(ParserError) { parse(json) }
+ json = <<EOT
+{
+ "key1":"value1" /* multi line
+ // nested eol comment
+ closed multi comment */
+ and again, throw an Error */
+}
+EOT
+ assert_raises(ParserError) { parse(json) }
+ json = <<EOT
+{
+ "key1":"value1" /*/*/
+}
+EOT
+ assert_equal({ "key1" => "value1" }, parse(json))
+ end
+
+ def test_backslash
+ data = [ '\\.(?i:gif|jpe?g|png)$' ]
+ json = '["\\\\.(?i:gif|jpe?g|png)$"]'
+ assert_equal json, JSON.generate(data)
+ assert_equal data, JSON.parse(json)
+ #
+ data = [ '\\"' ]
+ json = '["\\\\\""]'
+ assert_equal json, JSON.generate(data)
+ assert_equal data, JSON.parse(json)
+ #
+ json = '["/"]'
+ data = JSON.parse(json)
+ assert_equal ['/'], data
+ assert_equal json, JSON.generate(data)
+ #
+ json = '["\""]'
+ data = JSON.parse(json)
+ assert_equal ['"'], data
+ assert_equal json, JSON.generate(data)
+ json = '["\\\'"]'
+ data = JSON.parse(json)
+ assert_equal ["'"], data
+ assert_equal '["\'"]', JSON.generate(data)
+ end
+
+ def test_wrong_inputs
+ assert_raises(ParserError) { JSON.parse('"foo"') }
+ assert_raises(ParserError) { JSON.parse('123') }
+ assert_raises(ParserError) { JSON.parse('[] bla') }
+ assert_raises(ParserError) { JSON.parse('[] 1') }
+ assert_raises(ParserError) { JSON.parse('[] []') }
+ assert_raises(ParserError) { JSON.parse('[] {}') }
+ assert_raises(ParserError) { JSON.parse('{} []') }
+ assert_raises(ParserError) { JSON.parse('{} {}') }
+ assert_raises(ParserError) { JSON.parse('[NULL]') }
+ assert_raises(ParserError) { JSON.parse('[FALSE]') }
+ assert_raises(ParserError) { JSON.parse('[TRUE]') }
+ assert_raises(ParserError) { JSON.parse('[07] ') }
+ assert_raises(ParserError) { JSON.parse('[0a]') }
+ assert_raises(ParserError) { JSON.parse('[1.]') }
+ assert_raises(ParserError) { JSON.parse(' ') }
+ end
+
+ def test_nesting
+ assert_raises(JSON::NestingError) { JSON.parse '[[]]', :max_nesting => 1 }
+ assert_raises(JSON::NestingError) { JSON.parser.new('[[]]', :max_nesting => 1).parse }
+ assert_equal [[]], JSON.parse('[[]]', :max_nesting => 2)
+ too_deep = '[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]'
+ too_deep_ary = eval too_deep
+ assert_raises(JSON::NestingError) { JSON.parse too_deep }
+ assert_raises(JSON::NestingError) { JSON.parser.new(too_deep).parse }
+ assert_raises(JSON::NestingError) { JSON.parse too_deep, :max_nesting => 19 }
+ ok = JSON.parse too_deep, :max_nesting => 20
+ assert_equal too_deep_ary, ok
+ ok = JSON.parse too_deep, :max_nesting => nil
+ assert_equal too_deep_ary, ok
+ ok = JSON.parse too_deep, :max_nesting => false
+ assert_equal too_deep_ary, ok
+ ok = JSON.parse too_deep, :max_nesting => 0
+ assert_equal too_deep_ary, ok
+ assert_raises(JSON::NestingError) { JSON.generate [[]], :max_nesting => 1 }
+ assert_equal '[[]]', JSON.generate([[]], :max_nesting => 2)
+ assert_raises(JSON::NestingError) { JSON.generate too_deep_ary }
+ assert_raises(JSON::NestingError) { JSON.generate too_deep_ary, :max_nesting => 19 }
+ ok = JSON.generate too_deep_ary, :max_nesting => 20
+ assert_equal too_deep, ok
+ ok = JSON.generate too_deep_ary, :max_nesting => nil
+ assert_equal too_deep, ok
+ ok = JSON.generate too_deep_ary, :max_nesting => false
+ assert_equal too_deep, ok
+ ok = JSON.generate too_deep_ary, :max_nesting => 0
+ assert_equal too_deep, ok
+ end
+
+ def test_symbolize_names
+ assert_equal({ "foo" => "bar", "baz" => "quux" },
+ JSON.parse('{"foo":"bar", "baz":"quux"}'))
+ assert_equal({ :foo => "bar", :baz => "quux" },
+ JSON.parse('{"foo":"bar", "baz":"quux"}', :symbolize_names => true))
+ end
+
+ def test_load_dump
+ too_deep = '[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]'
+ assert_equal too_deep, JSON.dump(eval(too_deep))
+ assert_kind_of String, Marshal.dump(eval(too_deep))
+ assert_raises(ArgumentError) { JSON.dump(eval(too_deep), 19) }
+ assert_raises(ArgumentError) { Marshal.dump(eval(too_deep), 19) }
+ assert_equal too_deep, JSON.dump(eval(too_deep), 20)
+ assert_kind_of String, Marshal.dump(eval(too_deep), 20)
+ output = StringIO.new
+ JSON.dump(eval(too_deep), output)
+ assert_equal too_deep, output.string
+ output = StringIO.new
+ JSON.dump(eval(too_deep), output, 20)
+ assert_equal too_deep, output.string
+ end
+
+ def test_big_integers
+ json1 = JSON([orig = (1 << 31) - 1])
+ assert_equal orig, JSON[json1][0]
+ json2 = JSON([orig = 1 << 31])
+ assert_equal orig, JSON[json2][0]
+ json3 = JSON([orig = (1 << 62) - 1])
+ assert_equal orig, JSON[json3][0]
+ json4 = JSON([orig = 1 << 62])
+ assert_equal orig, JSON[json4][0]
+ json5 = JSON([orig = 1 << 64])
+ assert_equal orig, JSON[json5][0]
+ end
+end
Property changes on: MacRuby/trunk/test/test-mri/test/json/test_json.rb
___________________________________________________________________
Added: svn:executable
+ *
Added: MacRuby/trunk/test/test-mri/test/json/test_json_addition.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/test_json_addition.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/test_json_addition.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,162 @@
+#!/usr/bin/env ruby
+# -*- coding:utf-8 -*-
+
+require 'test/unit'
+case ENV['JSON']
+when 'pure' then require 'json/pure'
+when 'ext' then require 'json/ext'
+else require 'json'
+end
+require 'json/add/core'
+require 'date'
+
+class TC_JSONAddition < Test::Unit::TestCase
+ include JSON
+
+ class A
+ def initialize(a)
+ @a = a
+ end
+
+ attr_reader :a
+
+ def ==(other)
+ a == other.a
+ end
+
+ def self.json_create(object)
+ new(*object['args'])
+ end
+
+ def to_json(*args)
+ {
+ 'json_class' => self.class.name,
+ 'args' => [ @a ],
+ }.to_json(*args)
+ end
+ end
+
+ class B
+ def self.json_creatable?
+ false
+ end
+
+ def to_json(*args)
+ {
+ 'json_class' => self.class.name,
+ }.to_json(*args)
+ end
+ end
+
+ class C
+ def self.json_creatable?
+ false
+ end
+
+ def to_json(*args)
+ {
+ 'json_class' => 'TC_JSONAddition::Nix',
+ }.to_json(*args)
+ end
+ end
+
+ def test_extended_json
+ a = A.new(666)
+ assert A.json_creatable?
+ json = generate(a)
+ a_again = JSON.parse(json)
+ assert_kind_of a.class, a_again
+ assert_equal a, a_again
+ end
+
+ def test_extended_json_disabled
+ a = A.new(666)
+ assert A.json_creatable?
+ json = generate(a)
+ a_again = JSON.parse(json, :create_additions => true)
+ assert_kind_of a.class, a_again
+ assert_equal a, a_again
+ a_hash = JSON.parse(json, :create_additions => false)
+ assert_kind_of Hash, a_hash
+ assert_equal(
+ {"args"=>[666], "json_class"=>"TC_JSONAddition::A"}.sort_by { |k,| k },
+ a_hash.sort_by { |k,| k }
+ )
+ end
+
+ def test_extended_json_fail1
+ b = B.new
+ assert !B.json_creatable?
+ json = generate(b)
+ assert_equal({ "json_class"=>"TC_JSONAddition::B" }, JSON.parse(json))
+ end
+
+ def test_extended_json_fail2
+ c = C.new
+ assert !C.json_creatable?
+ json = generate(c)
+ assert_raises(ArgumentError, NameError) { JSON.parse(json) }
+ end
+
+ def test_raw_strings
+ raw = ''
+ raw.respond_to?(:encode!) and raw.encode!(Encoding::ASCII_8BIT)
+ raw_array = []
+ for i in 0..255
+ raw << i
+ raw_array << i
+ end
+ json = raw.to_json_raw
+ json_raw_object = raw.to_json_raw_object
+ hash = { 'json_class' => 'String', 'raw'=> raw_array }
+ assert_equal hash, json_raw_object
+ assert_match /\A\{.*\}\Z/, json
+ assert_match /"json_class":"String"/, json
+ assert_match /"raw":\[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255\]/, json
+ raw_again = JSON.parse(json)
+ assert_equal raw, raw_again
+ end
+
+ MyJsonStruct = Struct.new 'MyJsonStruct', :foo, :bar
+
+ def test_core
+ t = Time.now
+ assert_equal t.inspect, JSON(JSON(t)).inspect
+ d = Date.today
+ assert_equal d, JSON(JSON(d))
+ d = DateTime.civil(2007, 6, 14, 14, 57, 10, Rational(1, 12), 2299161)
+ assert_equal d, JSON(JSON(d))
+ assert_equal 1..10, JSON(JSON(1..10))
+ assert_equal 1...10, JSON(JSON(1...10))
+ assert_equal "a".."c", JSON(JSON("a".."c"))
+ assert_equal "a"..."c", JSON(JSON("a"..."c"))
+ s = MyJsonStruct.new 4711, 'foot'
+ assert_equal s, JSON(JSON(s))
+ struct = Struct.new :foo, :bar
+ s = struct.new 4711, 'foot'
+ assert_raises(JSONError) { JSON(s) }
+ begin
+ raise TypeError, "test me"
+ rescue TypeError => e
+ e_json = JSON.generate e
+ e_again = JSON e_json
+ assert_kind_of TypeError, e_again
+ assert_equal e.message, e_again.message
+ assert_equal e.backtrace, e_again.backtrace
+ end
+ assert_equal(/foo/, JSON(JSON(/foo/)))
+ assert_equal(/foo/i, JSON(JSON(/foo/i)))
+ end
+
+ def test_utc_datetime
+ now = Time.now
+ d = DateTime.parse(now.to_s) # usual case
+ assert_equal d, JSON.parse(d.to_json)
+ d = DateTime.parse(now.utc.to_s) # of = 0
+ assert_equal d, JSON.parse(d.to_json)
+ d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(1,24))
+ assert_equal d, JSON.parse(d.to_json)
+ d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(12,24))
+ assert_equal d, JSON.parse(d.to_json)
+ end
+end
Property changes on: MacRuby/trunk/test/test-mri/test/json/test_json_addition.rb
___________________________________________________________________
Added: svn:executable
+ *
Added: MacRuby/trunk/test/test-mri/test/json/test_json_encoding.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/test_json_encoding.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/test_json_encoding.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,68 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+
+require 'test/unit'
+case ENV['JSON']
+when 'pure' then require 'json/pure'
+when 'ext' then require 'json/ext'
+else require 'json'
+end
+require 'iconv'
+
+class TC_JSONEncoding < Test::Unit::TestCase
+ include JSON
+
+ def setup
+ @utf_8 = '["© ≠ €!"]'
+ @parsed = [ "© ≠ €!" ]
+ @utf_16_data = Iconv.iconv('utf-16be', 'utf-8', @parsed.first)
+ @generated = '["\u00a9 \u2260 \u20ac!"]'
+ if defined?(::Encoding)
+ @utf_8_ascii_8bit = @utf_8.dup.force_encoding(Encoding::ASCII_8BIT)
+ @utf_16be, = Iconv.iconv('utf-16be', 'utf-8', @utf_8)
+ @utf_16be_ascii_8bit = @utf_16be.dup.force_encoding(Encoding::ASCII_8BIT)
+ @utf_16le, = Iconv.iconv('utf-16le', 'utf-8', @utf_8)
+ @utf_16le_ascii_8bit = @utf_16le.dup.force_encoding(Encoding::ASCII_8BIT)
+ @utf_32be, = Iconv.iconv('utf-32be', 'utf-8', @utf_8)
+ @utf_32be_ascii_8bit = @utf_32be.dup.force_encoding(Encoding::ASCII_8BIT)
+ @utf_32le, = Iconv.iconv('utf-32le', 'utf-8', @utf_8)
+ @utf_32le_ascii_8bit = @utf_32le.dup.force_encoding(Encoding::ASCII_8BIT)
+ else
+ @utf_8_ascii_8bit = @utf_8.dup
+ @utf_16be, = Iconv.iconv('utf-16be', 'utf-8', @utf_8)
+ @utf_16be_ascii_8bit = @utf_16be.dup
+ @utf_16le, = Iconv.iconv('utf-16le', 'utf-8', @utf_8)
+ @utf_16le_ascii_8bit = @utf_16le.dup
+ @utf_32be, = Iconv.iconv('utf-32be', 'utf-8', @utf_8)
+ @utf_32be_ascii_8bit = @utf_32be.dup
+ @utf_32le, = Iconv.iconv('utf-32le', 'utf-8', @utf_8)
+ @utf_32le_ascii_8bit = @utf_32le.dup
+ end
+ end
+
+ def test_parse
+ assert_equal @parsed, JSON.parse(@utf_8)
+ assert_equal @parsed, JSON.parse(@utf_16be)
+ assert_equal @parsed, JSON.parse(@utf_16le)
+ assert_equal @parsed, JSON.parse(@utf_32be)
+ assert_equal @parsed, JSON.parse(@utf_32le)
+ end
+
+ def test_parse_ascii_8bit
+ assert_equal @parsed, JSON.parse(@utf_8_ascii_8bit)
+ assert_equal @parsed, JSON.parse(@utf_16be_ascii_8bit)
+ assert_equal @parsed, JSON.parse(@utf_16le_ascii_8bit)
+ assert_equal @parsed, JSON.parse(@utf_32be_ascii_8bit)
+ assert_equal @parsed, JSON.parse(@utf_32le_ascii_8bit)
+ end
+
+ def test_generate
+ assert_equal @generated, JSON.generate(@parsed, :ascii_only => true)
+ if defined?(::Encoding)
+ assert_equal @generated, JSON.generate(@utf_16_data, :ascii_only => true)
+ else
+ # XXX checking of correct utf8 data is not as strict (yet?) without :ascii_only
+ assert_raises(JSON::GeneratorError) { JSON.generate(@utf_16_data, :ascii_only => true) }
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/json/test_json_fixtures.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/test_json_fixtures.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/test_json_fixtures.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,34 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+
+require 'test/unit'
+case ENV['JSON']
+when 'pure' then require 'json/pure'
+when 'ext' then require 'json/ext'
+else require 'json'
+end
+
+class TC_JSONFixtures < Test::Unit::TestCase
+ def setup
+ fixtures = File.join(File.dirname(__FILE__), 'fixtures/*.json')
+ passed, failed = Dir[fixtures].partition { |f| f['pass'] }
+ @passed = passed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
+ @failed = failed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
+ end
+
+ def test_passing
+ for name, source in @passed
+ assert JSON.parse(source),
+ "Did not pass for fixture '#{name}'"
+ end
+ end
+
+ def test_failing
+ for name, source in @failed
+ assert_raises(JSON::ParserError, JSON::NestingError,
+ "Did not fail for fixture '#{name}'") do
+ JSON.parse(source)
+ end
+ end
+ end
+end
Property changes on: MacRuby/trunk/test/test-mri/test/json/test_json_fixtures.rb
___________________________________________________________________
Added: svn:executable
+ *
Added: MacRuby/trunk/test/test-mri/test/json/test_json_generate.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/test_json_generate.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/test_json_generate.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,122 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+
+require 'test/unit'
+case ENV['JSON']
+when 'pure' then require 'json/pure'
+when 'ext' then require 'json/ext'
+else require 'json'
+end
+
+class TC_JSONGenerate < Test::Unit::TestCase
+ include JSON
+
+ def setup
+ @hash = {
+ 'a' => 2,
+ 'b' => 3.141,
+ 'c' => 'c',
+ 'd' => [ 1, "b", 3.14 ],
+ 'e' => { 'foo' => 'bar' },
+ 'g' => "\"\0\037",
+ 'h' => 1000.0,
+ 'i' => 0.001
+ }
+ @json2 = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},' +
+ '"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
+ @json3 = <<'EOT'.chomp
+{
+ "a": 2,
+ "b": 3.141,
+ "c": "c",
+ "d": [
+ 1,
+ "b",
+ 3.14
+ ],
+ "e": {
+ "foo": "bar"
+ },
+ "g": "\"\u0000\u001f",
+ "h": 1000.0,
+ "i": 0.001
+}
+EOT
+ end
+
+ def test_generate
+ json = generate(@hash)
+ assert_equal(JSON.parse(@json2), JSON.parse(json))
+ parsed_json = parse(json)
+ assert_equal(@hash, parsed_json)
+ json = generate({1=>2})
+ assert_equal('{"1":2}', json)
+ parsed_json = parse(json)
+ assert_equal({"1"=>2}, parsed_json)
+ assert_raise(GeneratorError) { generate(666) }
+ end
+
+ def test_generate_pretty
+ json = pretty_generate(@hash)
+ assert_equal(JSON.parse(@json3), JSON.parse(json))
+ parsed_json = parse(json)
+ assert_equal(@hash, parsed_json)
+ json = pretty_generate({1=>2})
+ assert_equal(<<'EOT'.chomp, json)
+{
+ "1": 2
+}
+EOT
+ parsed_json = parse(json)
+ assert_equal({"1"=>2}, parsed_json)
+ assert_raise(GeneratorError) { pretty_generate(666) }
+ end
+
+ def test_fast_generate
+ json = fast_generate(@hash)
+ assert_equal(JSON.parse(@json2), JSON.parse(json))
+ parsed_json = parse(json)
+ assert_equal(@hash, parsed_json)
+ json = fast_generate({1=>2})
+ assert_equal('{"1":2}', json)
+ parsed_json = parse(json)
+ assert_equal({"1"=>2}, parsed_json)
+ assert_raise(GeneratorError) { fast_generate(666) }
+ end
+
+ def test_states
+ json = generate({1=>2}, nil)
+ assert_equal('{"1":2}', json)
+ s = JSON.state.new
+ assert s.check_circular?
+ assert s[:check_circular?]
+ h = { 1=>2 }
+ h[3] = h
+ assert_raises(JSON::NestingError) { generate(h) }
+ assert_raises(JSON::NestingError) { generate(h, s) }
+ s = JSON.state.new
+ a = [ 1, 2 ]
+ a << a
+ assert_raises(JSON::NestingError) { generate(a, s) }
+ assert s.check_circular?
+ assert s[:check_circular?]
+ end
+
+ def test_allow_nan
+ assert_raises(GeneratorError) { generate([JSON::NaN]) }
+ assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true)
+ assert_raises(GeneratorError) { fast_generate([JSON::NaN]) }
+ assert_raises(GeneratorError) { pretty_generate([JSON::NaN]) }
+ assert_equal "[\n NaN\n]", pretty_generate([JSON::NaN], :allow_nan => true)
+ assert_raises(GeneratorError) { generate([JSON::Infinity]) }
+ assert_equal '[Infinity]', generate([JSON::Infinity], :allow_nan => true)
+ assert_raises(GeneratorError) { fast_generate([JSON::Infinity]) }
+ assert_raises(GeneratorError) { pretty_generate([JSON::Infinity]) }
+ assert_equal "[\n Infinity\n]", pretty_generate([JSON::Infinity], :allow_nan => true)
+ assert_raises(GeneratorError) { generate([JSON::MinusInfinity]) }
+ assert_equal '[-Infinity]', generate([JSON::MinusInfinity], :allow_nan => true)
+ assert_raises(GeneratorError) { fast_generate([JSON::MinusInfinity]) }
+ assert_raises(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
+ assert_equal "[\n -Infinity\n]", pretty_generate([JSON::MinusInfinity], :allow_nan => true)
+ end
+end
Property changes on: MacRuby/trunk/test/test-mri/test/json/test_json_generate.rb
___________________________________________________________________
Added: svn:executable
+ *
Added: MacRuby/trunk/test/test-mri/test/json/test_json_rails.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/test_json_rails.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/test_json_rails.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,152 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+
+require 'test/unit'
+case ENV['JSON']
+when 'pure' then require 'json/pure'
+when 'ext' then require 'json/ext'
+else require 'json'
+end
+require 'json/add/rails'
+require 'date'
+
+class TC_JSONRails < Test::Unit::TestCase
+ include JSON
+
+ def setup
+ Symbol.class_eval do
+ def to_json(*a)
+ to_s.to_json(*a)
+ end
+ end
+ end
+
+ class A
+ def initialize(a)
+ @a = a
+ end
+
+ attr_reader :a
+
+ def ==(other)
+ a == other.a
+ end
+
+ def self.json_create(object)
+ new(*object['args'])
+ end
+
+ def to_json(*args)
+ {
+ 'json_class' => self.class.name,
+ 'args' => [ @a ],
+ }.to_json(*args)
+ end
+ end
+
+ class B
+ def self.json_creatable?
+ false
+ end
+
+ def to_json(*args)
+ {
+ 'json_class' => self.class.name,
+ }.to_json(*args)
+ end
+ end
+
+ class C
+ def to_json(*args)
+ {
+ 'json_class' => 'TC_JSONRails::Nix',
+ }.to_json(*args)
+ end
+ end
+
+ class D
+ def initialize
+ @foo = 666
+ end
+
+ attr_reader :foo
+
+ def ==(other)
+ foo == other.foo
+ end
+ end
+
+ def test_extended_json
+ a = A.new(666)
+ assert A.json_creatable?
+ assert_equal 666, a.a
+ json = generate(a)
+ a_again = JSON.parse(json)
+ assert_kind_of a.class, a_again
+ assert_equal a, a_again
+ assert_equal 666, a_again.a
+ end
+
+ def test_extended_json_generic_object
+ d = D.new
+ assert D.json_creatable?
+ assert_equal 666, d.foo
+ json = generate(d)
+ d_again = JSON.parse(json)
+ assert_kind_of d.class, d_again
+ assert_equal d, d_again
+ assert_equal 666, d_again.foo
+ end
+
+ def test_extended_json_disabled
+ a = A.new(666)
+ assert A.json_creatable?
+ json = generate(a)
+ a_again = JSON.parse(json, :create_additions => true)
+ assert_kind_of a.class, a_again
+ assert_equal a, a_again
+ a_hash = JSON.parse(json, :create_additions => false)
+ assert_kind_of Hash, a_hash
+ assert_equal(
+ {"args"=>[666], "json_class"=>"TC_JSONRails::A"}.sort_by { |k,| k },
+ a_hash.sort_by { |k,| k }
+ )
+ end
+
+ def test_extended_json_fail1
+ b = B.new
+ assert !B.json_creatable?
+ json = generate(b)
+ assert_equal({ 'json_class' => B.name }, JSON.parse(json))
+ end
+
+ def test_extended_json_fail2
+ c = C.new # with rails addition all objects are theoretically creatable
+ assert C.json_creatable?
+ json = generate(c)
+ assert_raises(ArgumentError, NameError) { JSON.parse(json) }
+ end
+
+ def test_raw_strings
+ raw = ''
+ raw.respond_to?(:encode!) and raw.encode!(Encoding::ASCII_8BIT)
+ raw_array = []
+ for i in 0..255
+ raw << i
+ raw_array << i
+ end
+ json = raw.to_json_raw
+ json_raw_object = raw.to_json_raw_object
+ hash = { 'json_class' => 'String', 'raw'=> raw_array }
+ assert_equal hash, json_raw_object
+ assert_match /\A\{.*\}\Z/, json
+ assert_match /"json_class":"String"/, json
+ assert_match /"raw":\[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255\]/, json
+ raw_again = JSON.parse(json)
+ assert_equal raw, raw_again
+ end
+
+ def test_symbol
+ assert_equal '"foo"', :foo.to_json # we don't want an object here
+ end
+end
Property changes on: MacRuby/trunk/test/test-mri/test/json/test_json_rails.rb
___________________________________________________________________
Added: svn:executable
+ *
Added: MacRuby/trunk/test/test-mri/test/json/test_json_unicode.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/json/test_json_unicode.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/json/test_json_unicode.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,76 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+
+require 'test/unit'
+case ENV['JSON']
+when 'pure' then require 'json/pure'
+when 'ext' then require 'json/ext'
+else require 'json'
+end
+
+class TC_JSONUnicode < Test::Unit::TestCase
+ include JSON
+
+ def test_unicode
+ assert_equal '""', ''.to_json
+ assert_equal '"\\b"', "\b".to_json
+ assert_equal '"\u0001"', 0x1.chr.to_json
+ assert_equal '"\u001f"', 0x1f.chr.to_json
+ assert_equal '" "', ' '.to_json
+ assert_equal "\"#{0x7f.chr}\"", 0x7f.chr.to_json
+ utf8 = [ "© ≠ €! \01" ]
+ json = '["© ≠ €! \u0001"]'
+ assert_equal json, utf8.to_json(:ascii_only => false)
+ assert_equal utf8, parse(json)
+ json = '["\u00a9 \u2260 \u20ac! \u0001"]'
+ assert_equal json, utf8.to_json(:ascii_only => true)
+ assert_equal utf8, parse(json)
+ utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
+ json = "[\"\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212\"]"
+ assert_equal utf8, parse(json)
+ assert_equal json, utf8.to_json(:ascii_only => false)
+ utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
+ assert_equal utf8, parse(json)
+ json = "[\"\\u3042\\u3044\\u3046\\u3048\\u304a\"]"
+ assert_equal json, utf8.to_json(:ascii_only => true)
+ assert_equal utf8, parse(json)
+ utf8 = ['საქართველო']
+ json = '["საქართველო"]'
+ assert_equal json, utf8.to_json(:ascii_only => false)
+ json = "[\"\\u10e1\\u10d0\\u10e5\\u10d0\\u10e0\\u10d7\\u10d5\\u10d4\\u10da\\u10dd\"]"
+ assert_equal json, utf8.to_json(:ascii_only => true)
+ assert_equal utf8, parse(json)
+ assert_equal '["Ã"]', JSON.generate(["Ã"], :ascii_only => false)
+ assert_equal '["\\u00c3"]', JSON.generate(["Ã"], :ascii_only => true)
+ assert_equal ["€"], JSON.parse('["\u20ac"]')
+ utf8 = ["\xf0\xa0\x80\x81"]
+ json = "[\"\xf0\xa0\x80\x81\"]"
+ assert_equal json, JSON.generate(utf8, :ascii_only => false)
+ assert_equal utf8, JSON.parse(json)
+ json = '["\ud840\udc01"]'
+ assert_equal json, JSON.generate(utf8, :ascii_only => true)
+ assert_equal utf8, JSON.parse(json)
+ end
+
+ def test_chars
+ (0..0x7f).each do |i|
+ json = '["\u%04x"]' % i
+ if RUBY_VERSION >= "1.9."
+ i = i.chr
+ end
+ assert_equal i, JSON.parse(json).first[0]
+ if i == ?\b
+ generated = JSON.generate(["" << i])
+ assert '["\b"]' == generated || '["\10"]' == generated
+ elsif [?\n, ?\r, ?\t, ?\f].include?(i)
+ assert_equal '[' << ('' << i).dump << ']', JSON.generate(["" << i])
+ elsif i.chr < 0x20.chr
+ assert_equal json, JSON.generate(["" << i])
+ end
+ end
+ assert_raise(JSON::GeneratorError) do
+ JSON.generate(["\x80"], :ascii_only => true)
+ end
+ assert_equal "\302\200", JSON.parse('["\u0080"]').first
+ end
+end
Property changes on: MacRuby/trunk/test/test-mri/test/json/test_json_unicode.rb
___________________________________________________________________
Added: svn:executable
+ *
Added: MacRuby/trunk/test/test-mri/test/logger/test_logger.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/logger/test_logger.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/logger/test_logger.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,527 @@
+require 'test/unit'
+require 'logger'
+require 'tempfile'
+
+
+class TestLoggerSeverity < Test::Unit::TestCase
+ def test_enum
+ logger_levels = Logger.constants
+ levels = ["WARN", "UNKNOWN", "INFO", "FATAL", "DEBUG", "ERROR"]
+ Logger::Severity.constants.each do |level|
+ assert(levels.include?(level.to_s))
+ assert(logger_levels.include?(level))
+ end
+ assert_equal(levels.size, Logger::Severity.constants.size)
+ end
+end
+
+
+class TestLogger < Test::Unit::TestCase
+ include Logger::Severity
+
+ def setup
+ @logger = Logger.new(nil)
+ @filename = __FILE__ + ".#{$$}"
+ end
+
+ def teardown
+ unless $DEBUG
+ File.unlink(@filename) if File.exist?(@filename)
+ end
+ end
+
+ class Log
+ attr_reader :label, :datetime, :pid, :severity, :progname, :msg
+ def initialize(line)
+ /\A(\w+), \[([^#]*)#(\d+)\]\s+(\w+) -- (\w*): ([\x0-\xff]*)/ =~ line
+ @label, @datetime, @pid, @severity, @progname, @msg = $1, $2, $3, $4, $5, $6
+ end
+ end
+
+ def log_add(logger, severity, msg, progname = nil, &block)
+ log(logger, :add, severity, msg, progname, &block)
+ end
+
+ def log(logger, msg_id, *arg, &block)
+ Log.new(log_raw(logger, msg_id, *arg, &block))
+ end
+
+ def log_raw(logger, msg_id, *arg, &block)
+ logdev = Tempfile.new(File.basename(__FILE__) + '.log')
+ logger.instance_eval { @logdev = Logger::LogDevice.new(logdev) }
+ logger.__send__(msg_id, *arg, &block)
+ logdev.open
+ msg = logdev.read
+ logdev.close
+ msg
+ end
+
+ def test_level
+ @logger.level = UNKNOWN
+ assert_equal(UNKNOWN, @logger.level)
+ @logger.level = INFO
+ assert_equal(INFO, @logger.level)
+ @logger.sev_threshold = ERROR
+ assert_equal(ERROR, @logger.sev_threshold)
+ @logger.sev_threshold = WARN
+ assert_equal(WARN, @logger.sev_threshold)
+ assert_equal(WARN, @logger.level)
+
+ @logger.level = DEBUG
+ assert(@logger.debug?)
+ assert(@logger.info?)
+ @logger.level = INFO
+ assert(!@logger.debug?)
+ assert(@logger.info?)
+ assert(@logger.warn?)
+ @logger.level = WARN
+ assert(!@logger.info?)
+ assert(@logger.warn?)
+ assert(@logger.error?)
+ @logger.level = ERROR
+ assert(!@logger.warn?)
+ assert(@logger.error?)
+ assert(@logger.fatal?)
+ @logger.level = FATAL
+ assert(!@logger.error?)
+ assert(@logger.fatal?)
+ @logger.level = UNKNOWN
+ assert(!@logger.error?)
+ assert(!@logger.fatal?)
+ end
+
+ def test_progname
+ assert_nil(@logger.progname)
+ @logger.progname = "name"
+ assert_equal("name", @logger.progname)
+ end
+
+ def test_datetime_format
+ dummy = STDERR
+ logger = Logger.new(dummy)
+ log = log_add(logger, INFO, "foo")
+ assert_match(/^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\s*\d+ $/, log.datetime)
+ logger.datetime_format = "%d%b%Y@%H:%M:%S"
+ log = log_add(logger, INFO, "foo")
+ assert_match(/^\d\d\w\w\w\d\d\d\d@\d\d:\d\d:\d\d$/, log.datetime)
+ logger.datetime_format = ""
+ log = log_add(logger, INFO, "foo")
+ assert_match(/^$/, log.datetime)
+ end
+
+ def test_formatter
+ dummy = STDERR
+ logger = Logger.new(dummy)
+ # default
+ log = log(logger, :info, "foo")
+ assert_equal("foo\n", log.msg)
+ # config
+ logger.formatter = proc { |severity, timestamp, progname, msg|
+ "#{severity}:#{msg}\n\n"
+ }
+ line = log_raw(logger, :info, "foo")
+ assert_equal("INFO:foo\n\n", line)
+ # recover
+ logger.formatter = nil
+ log = log(logger, :info, "foo")
+ assert_equal("foo\n", log.msg)
+ # again
+ o = Object.new
+ def o.call(severity, timestamp, progname, msg)
+ "<<#{severity}-#{msg}>>\n"
+ end
+ logger.formatter = o
+ line = log_raw(logger, :info, "foo")
+ assert_equal("<<INFO-foo>>\n", line)
+ end
+
+ def test_initialize
+ logger = Logger.new(STDERR)
+ assert_nil(logger.progname)
+ assert_equal(DEBUG, logger.level)
+ assert_nil(logger.datetime_format)
+ end
+
+ def test_add
+ logger = Logger.new(nil)
+ logger.progname = "my_progname"
+ assert(logger.add(INFO))
+ log = log_add(logger, nil, "msg")
+ assert_equal("ANY", log.severity)
+ assert_equal("my_progname", log.progname)
+ logger.level = WARN
+ assert(logger.log(INFO))
+ assert_nil(log_add(logger, INFO, "msg").msg)
+ log = log_add(logger, WARN, nil) { "msg" }
+ assert_equal("msg\n", log.msg)
+ log = log_add(logger, WARN, "") { "msg" }
+ assert_equal("\n", log.msg)
+ assert_equal("my_progname", log.progname)
+ log = log_add(logger, WARN, nil, "progname?")
+ assert_equal("progname?\n", log.msg)
+ assert_equal("my_progname", log.progname)
+ end
+
+ def test_level_log
+ logger = Logger.new(nil)
+ logger.progname = "my_progname"
+ log = log(logger, :debug, "custom_progname") { "msg" }
+ assert_equal("msg\n", log.msg)
+ assert_equal("custom_progname", log.progname)
+ assert_equal("DEBUG", log.severity)
+ assert_equal("D", log.label)
+ #
+ log = log(logger, :debug) { "msg_block" }
+ assert_equal("msg_block\n", log.msg)
+ assert_equal("my_progname", log.progname)
+ log = log(logger, :debug, "msg_inline")
+ assert_equal("msg_inline\n", log.msg)
+ assert_equal("my_progname", log.progname)
+ #
+ log = log(logger, :info, "custom_progname") { "msg" }
+ assert_equal("msg\n", log.msg)
+ assert_equal("custom_progname", log.progname)
+ assert_equal("INFO", log.severity)
+ assert_equal("I", log.label)
+ #
+ log = log(logger, :warn, "custom_progname") { "msg" }
+ assert_equal("msg\n", log.msg)
+ assert_equal("custom_progname", log.progname)
+ assert_equal("WARN", log.severity)
+ assert_equal("W", log.label)
+ #
+ log = log(logger, :error, "custom_progname") { "msg" }
+ assert_equal("msg\n", log.msg)
+ assert_equal("custom_progname", log.progname)
+ assert_equal("ERROR", log.severity)
+ assert_equal("E", log.label)
+ #
+ log = log(logger, :fatal, "custom_progname") { "msg" }
+ assert_equal("msg\n", log.msg)
+ assert_equal("custom_progname", log.progname)
+ assert_equal("FATAL", log.severity)
+ assert_equal("F", log.label)
+ #
+ log = log(logger, :unknown, "custom_progname") { "msg" }
+ assert_equal("msg\n", log.msg)
+ assert_equal("custom_progname", log.progname)
+ assert_equal("ANY", log.severity)
+ assert_equal("A", log.label)
+ end
+
+ def test_close
+ r, w = IO.pipe
+ assert(!w.closed?)
+ logger = Logger.new(w)
+ logger.close
+ assert(w.closed?)
+ r.close
+ end
+
+ class MyError < StandardError
+ end
+
+ class MyMsg
+ def inspect
+ "my_msg"
+ end
+ end
+
+ def test_format
+ logger = Logger.new(nil)
+ log = log_add(logger, INFO, "msg\n")
+ assert_equal("msg\n\n", log.msg)
+ begin
+ raise MyError.new("excn")
+ rescue MyError => e
+ log = log_add(logger, INFO, e)
+ assert_match(/^excn \(TestLogger::MyError\)/, log.msg)
+ # expects backtrace is dumped across multi lines. 10 might be changed.
+ assert(log.msg.split(/\n/).size >= 10)
+ end
+ log = log_add(logger, INFO, MyMsg.new)
+ assert_equal("my_msg\n", log.msg)
+ end
+
+ def test_lshift
+ r, w = IO.pipe
+ logger = Logger.new(w)
+ logger << "msg"
+ read_ready, = IO.select([r], nil, nil, 0.1)
+ w.close
+ msg = r.read
+ r.close
+ assert_equal("msg", msg)
+ #
+ r, w = IO.pipe
+ logger = Logger.new(w)
+ logger << "msg2\n\n"
+ read_ready, = IO.select([r], nil, nil, 0.1)
+ w.close
+ msg = r.read
+ r.close
+ assert_equal("msg2\n\n", msg)
+ end
+end
+
+class TestLogDevice < Test::Unit::TestCase
+ class LogExcnRaiser
+ def write(*arg)
+ raise 'disk is full'
+ end
+
+ def close
+ end
+
+ def stat
+ Object.new
+ end
+ end
+
+ def setup
+ @filename = __FILE__ + ".#{$$}"
+ end
+
+ def teardown
+ unless $DEBUG
+ File.unlink(@filename) if File.exist?(@filename)
+ end
+ end
+
+ def d(log, opt = {})
+ Logger::LogDevice.new(log, opt)
+ end
+
+ def test_initialize
+ logdev = d(STDERR)
+ assert_equal(STDERR, logdev.dev)
+ assert_nil(logdev.filename)
+ assert_raises(TypeError) do
+ d(nil)
+ end
+ #
+ logdev = d(@filename)
+ begin
+ assert(File.exist?(@filename))
+ assert(logdev.dev.sync)
+ assert_equal(@filename, logdev.filename)
+ logdev.write('hello')
+ ensure
+ logdev.close
+ end
+ # create logfile whitch is already exist.
+ logdev = d(@filename)
+ begin
+ logdev.write('world')
+ logfile = File.read(@filename)
+ assert_equal(2, logfile.split(/\n/).size)
+ assert_match(/^helloworld$/, logfile)
+ ensure
+ logdev.close
+ end
+ end
+
+ def test_write
+ r, w = IO.pipe
+ logdev = d(w)
+ logdev.write("msg2\n\n")
+ read_ready, = IO.select([r], nil, nil, 0.1)
+ w.close
+ msg = r.read
+ r.close
+ assert_equal("msg2\n\n", msg)
+ #
+ logdev = d(LogExcnRaiser.new)
+ class << (stderr = '')
+ alias write <<
+ end
+ $stderr, stderr = stderr, $stderr
+ begin
+ assert_nothing_raised do
+ logdev.write('hello')
+ end
+ ensure
+ logdev.close
+ $stderr, stderr = stderr, $stderr
+ end
+ assert_equal "log writing failed. disk is full\n", stderr
+ end
+
+ def test_close
+ r, w = IO.pipe
+ logdev = d(w)
+ logdev.write("msg2\n\n")
+ read_ready, = IO.select([r], nil, nil, 0.1)
+ assert(!w.closed?)
+ logdev.close
+ assert(w.closed?)
+ r.close
+ end
+
+ def test_shifting_size
+ logfile = File.basename(__FILE__) + '_1.log'
+ logfile0 = logfile + '.0'
+ logfile1 = logfile + '.1'
+ logfile2 = logfile + '.2'
+ logfile3 = logfile + '.3'
+ File.unlink(logfile) if File.exist?(logfile)
+ File.unlink(logfile0) if File.exist?(logfile0)
+ File.unlink(logfile1) if File.exist?(logfile1)
+ File.unlink(logfile2) if File.exist?(logfile2)
+ logger = Logger.new(logfile, 4, 100)
+ logger.error("0" * 15)
+ assert(File.exist?(logfile))
+ assert(!File.exist?(logfile0))
+ logger.error("0" * 15)
+ assert(File.exist?(logfile0))
+ assert(!File.exist?(logfile1))
+ logger.error("0" * 15)
+ assert(File.exist?(logfile1))
+ assert(!File.exist?(logfile2))
+ logger.error("0" * 15)
+ assert(File.exist?(logfile2))
+ assert(!File.exist?(logfile3))
+ logger.error("0" * 15)
+ assert(!File.exist?(logfile3))
+ logger.error("0" * 15)
+ assert(!File.exist?(logfile3))
+ logger.close
+ File.unlink(logfile)
+ File.unlink(logfile0)
+ File.unlink(logfile1)
+ File.unlink(logfile2)
+
+ logfile = File.basename(__FILE__) + '_2.log'
+ logfile0 = logfile + '.0'
+ logfile1 = logfile + '.1'
+ logfile2 = logfile + '.2'
+ logfile3 = logfile + '.3'
+ logger = Logger.new(logfile, 4, 150)
+ logger.error("0" * 15)
+ assert(File.exist?(logfile))
+ assert(!File.exist?(logfile0))
+ logger.error("0" * 15)
+ assert(!File.exist?(logfile0))
+ logger.error("0" * 15)
+ assert(File.exist?(logfile0))
+ assert(!File.exist?(logfile1))
+ logger.error("0" * 15)
+ assert(!File.exist?(logfile1))
+ logger.error("0" * 15)
+ assert(File.exist?(logfile1))
+ assert(!File.exist?(logfile2))
+ logger.error("0" * 15)
+ assert(!File.exist?(logfile2))
+ logger.error("0" * 15)
+ assert(File.exist?(logfile2))
+ assert(!File.exist?(logfile3))
+ logger.error("0" * 15)
+ assert(!File.exist?(logfile3))
+ logger.error("0" * 15)
+ assert(!File.exist?(logfile3))
+ logger.error("0" * 15)
+ assert(!File.exist?(logfile3))
+ logger.close
+ File.unlink(logfile)
+ File.unlink(logfile0)
+ File.unlink(logfile1)
+ File.unlink(logfile2)
+ end
+
+ def test_shifting_age_variants
+ logger = Logger.new(@filename, 'daily')
+ logger.info('daily')
+ logger.close
+ logger = Logger.new(@filename, 'weekly')
+ logger.info('weekly')
+ logger.close
+ logger = Logger.new(@filename, 'monthly')
+ logger.info('monthly')
+ logger.close
+ end
+
+ def test_shifting_age
+ # shift_age other than 'daily', 'weekly', and 'monthly' means 'everytime'
+ yyyymmdd = Time.now.strftime("%Y%m%d")
+ filename1 = @filename + ".#{yyyymmdd}"
+ filename2 = @filename + ".#{yyyymmdd}.1"
+ filename3 = @filename + ".#{yyyymmdd}.2"
+ begin
+ logger = Logger.new(@filename, 'now')
+ assert(File.exist?(@filename))
+ assert(!File.exist?(filename1))
+ assert(!File.exist?(filename2))
+ assert(!File.exist?(filename3))
+ logger.info("0" * 15)
+ assert(File.exist?(@filename))
+ assert(File.exist?(filename1))
+ assert(!File.exist?(filename2))
+ assert(!File.exist?(filename3))
+ logger.warn("0" * 15)
+ assert(File.exist?(@filename))
+ assert(File.exist?(filename1))
+ assert(File.exist?(filename2))
+ assert(!File.exist?(filename3))
+ logger.error("0" * 15)
+ assert(File.exist?(@filename))
+ assert(File.exist?(filename1))
+ assert(File.exist?(filename2))
+ assert(File.exist?(filename3))
+ ensure
+ logger.close if logger
+ [filename1, filename2, filename3].each do |filename|
+ File.unlink(filename) if File.exist?(filename)
+ end
+ end
+ end
+end
+
+
+class TestLoggerApplication < Test::Unit::TestCase
+ def setup
+ @app = Logger::Application.new('appname')
+ @filename = __FILE__ + ".#{$$}"
+ end
+
+ def teardown
+ unless $DEBUG
+ File.unlink(@filename) if File.exist?(@filename)
+ end
+ end
+
+ def test_initialize
+ app = Logger::Application.new('appname')
+ assert_equal('appname', app.appname)
+ end
+
+ def test_start
+ @app.set_log(@filename)
+ begin
+ @app.level = Logger::UNKNOWN
+ @app.start # logs FATAL log
+ assert_equal(1, File.read(@filename).split(/\n/).size)
+ ensure
+ @app.logger.close
+ end
+ end
+
+ def test_logger
+ @app.level = Logger::WARN
+ @app.set_log(@filename)
+ begin
+ assert_equal(Logger::WARN, @app.logger.level)
+ ensure
+ @app.logger.close
+ end
+ @app.logger = logger = Logger.new(STDOUT)
+ assert_equal(logger, @app.logger)
+ assert_equal(Logger::WARN, @app.logger.level)
+ @app.log = @filename
+ begin
+ assert(logger != @app.logger)
+ assert_equal(Logger::WARN, @app.logger.level)
+ ensure
+ @app.logger.close
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/matrix/test_matrix.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/matrix/test_matrix.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/matrix/test_matrix.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,427 @@
+require 'test/unit'
+require 'matrix'
+
+class TestMatrix < Test::Unit::TestCase
+ def setup
+ @m1 = Matrix[[1,2,3], [4,5,6]]
+ @m2 = Matrix[[1,2,3], [4,5,6]]
+ @m3 = @m1.clone
+ @m4 = Matrix[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]
+ @n1 = Matrix[[2,3,4], [5,6,7]]
+ end
+
+ def test_matrix
+ assert_equal(1, @m1[0, 0])
+ assert_equal(2, @m1[0, 1])
+ assert_equal(3, @m1[0, 2])
+ assert_equal(4, @m1[1, 0])
+ assert_equal(5, @m1[1, 1])
+ assert_equal(6, @m1[1, 2])
+ end
+
+ def test_identity
+ assert_same @m1, @m1
+ assert_not_same @m1, @m2
+ assert_not_same @m1, @m3
+ assert_not_same @m1, @m4
+ assert_not_same @m1, @n1
+ end
+
+ def test_equality
+ assert_equal @m1, @m1
+ assert_equal @m1, @m2
+ assert_equal @m1, @m3
+ assert_equal @m1, @m4
+ assert_not_equal @m1, @n1
+ end
+
+ def test_hash_equality
+ assert @m1.eql?(@m1)
+ assert @m1.eql?(@m2)
+ assert @m1.eql?(@m3)
+ assert !@m1.eql?(@m4)
+ assert !@m1.eql?(@n1)
+
+ hash = { @m1 => :value }
+ assert hash.key?(@m1)
+ assert hash.key?(@m2)
+ assert hash.key?(@m3)
+ assert !hash.key?(@m4)
+ assert !hash.key?(@n1)
+ end
+
+ def test_hash
+ assert_equal @m1.hash, @m1.hash
+ assert_equal @m1.hash, @m2.hash
+ assert_equal @m1.hash, @m3.hash
+ end
+
+ def test_rank
+ [
+ [[0]],
+ [[0], [0]],
+ [[0, 0], [0, 0]],
+ [[0, 0], [0, 0], [0, 0]],
+ [[0, 0, 0]],
+ [[0, 0, 0], [0, 0, 0]],
+ [[0, 0, 0], [0, 0, 0], [0, 0, 0]],
+ [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
+ ].each do |rows|
+ assert_equal 0, Matrix[*rows].rank
+ end
+
+ [
+ [[1], [0]],
+ [[1, 0], [0, 0]],
+ [[1, 0], [1, 0]],
+ [[0, 0], [1, 0]],
+ [[1, 0], [0, 0], [0, 0]],
+ [[0, 0], [1, 0], [0, 0]],
+ [[0, 0], [0, 0], [1, 0]],
+ [[1, 0], [1, 0], [0, 0]],
+ [[0, 0], [1, 0], [1, 0]],
+ [[1, 0], [1, 0], [1, 0]],
+ [[1, 0, 0]],
+ [[1, 0, 0], [0, 0, 0]],
+ [[0, 0, 0], [1, 0, 0]],
+ [[1, 0, 0], [1, 0, 0]],
+ [[1, 0, 0], [1, 0, 0]],
+ [[1, 0, 0], [0, 0, 0], [0, 0, 0]],
+ [[0, 0, 0], [1, 0, 0], [0, 0, 0]],
+ [[0, 0, 0], [0, 0, 0], [1, 0, 0]],
+ [[1, 0, 0], [1, 0, 0], [0, 0, 0]],
+ [[0, 0, 0], [1, 0, 0], [1, 0, 0]],
+ [[1, 0, 0], [0, 0, 0], [1, 0, 0]],
+ [[1, 0, 0], [1, 0, 0], [1, 0, 0]],
+ [[1, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
+ [[1, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
+ [[1, 0, 0], [1, 0, 0], [0, 0, 0], [0, 0, 0]],
+ [[1, 0, 0], [0, 0, 0], [1, 0, 0], [0, 0, 0]],
+ [[1, 0, 0], [0, 0, 0], [0, 0, 0], [1, 0, 0]],
+ [[1, 0, 0], [1, 0, 0], [1, 0, 0], [0, 0, 0]],
+ [[1, 0, 0], [0, 0, 0], [1, 0, 0], [1, 0, 0]],
+ [[1, 0, 0], [1, 0, 0], [0, 0, 0], [1, 0, 0]],
+ [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]],
+
+ [[1]],
+ [[1], [1]],
+ [[1, 1]],
+ [[1, 1], [1, 1]],
+ [[1, 1], [1, 1], [1, 1]],
+ [[1, 1, 1]],
+ [[1, 1, 1], [1, 1, 1]],
+ [[1, 1, 1], [1, 1, 1], [1, 1, 1]],
+ [[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]],
+ ].each do |rows|
+ matrix = Matrix[*rows]
+ assert_equal 1, matrix.rank
+ assert_equal 1, matrix.transpose.rank
+ end
+
+ [
+ [[1, 0], [0, 1]],
+ [[1, 0], [0, 1], [0, 0]],
+ [[1, 0], [0, 1], [0, 1]],
+ [[1, 0], [0, 1], [1, 1]],
+ [[1, 0, 0], [0, 1, 0]],
+ [[1, 0, 0], [0, 0, 1]],
+ [[1, 0, 0], [0, 1, 0], [0, 0, 0]],
+ [[1, 0, 0], [0, 0, 1], [0, 0, 0]],
+
+ [[1, 0, 0], [0, 0, 0], [0, 1, 0]],
+ [[1, 0, 0], [0, 0, 0], [0, 0, 1]],
+
+ [[1, 0], [1, 1]],
+ [[1, 2], [1, 1]],
+ [[1, 2], [0, 1], [1, 1]],
+ ].each do |rows|
+ m = Matrix[*rows]
+ assert_equal 2, m.rank
+ assert_equal 2, m.transpose.rank
+ end
+
+ [
+ [[1, 0, 0], [0, 1, 0], [0, 0, 1]],
+ [[1, 1, 0], [0, 1, 1], [1, 0, 1]],
+ [[1, 1, 0], [0, 1, 1], [1, 0, 1]],
+ [[1, 1, 0], [0, 1, 1], [1, 0, 1], [0, 0, 0]],
+ [[1, 1, 0], [0, 1, 1], [1, 0, 1], [1, 1, 1]],
+ [[1, 1, 1], [1, 1, 2], [1, 3, 1], [4, 1, 1]],
+ ].each do |rows|
+ m = Matrix[*rows]
+ assert_equal 3, m.rank
+ assert_equal 3, m.transpose.rank
+ end
+ end
+
+ def test_inverse
+ assert_equal(Matrix[[-1, 1], [0, -1]], Matrix[[-1, -1], [0, -1]].inverse)
+ end
+
+ def test_determinant
+ assert_equal(45, Matrix[[7,6], [3,9]].determinant)
+ assert_equal(-18, Matrix[[2,0,1],[0,-2,2],[1,2,3]].determinant)
+ end
+
+ def test_new_matrix
+ assert_raise(TypeError) { Matrix[Object.new] }
+ o = Object.new
+ def o.to_ary; [1,2,3]; end
+ assert_equal(@m1, Matrix[o, [4,5,6]])
+ end
+
+ def test_rows
+ assert_equal(@m1, Matrix.rows([[1, 2, 3], [4, 5, 6]]))
+ end
+
+ def test_columns
+ assert_equal(@m1, Matrix.columns([[1, 4], [2, 5], [3, 6]]))
+ end
+
+ def test_diagonal
+ assert_equal(Matrix[[3,0,0],[0,2,0],[0,0,1]], Matrix.diagonal(3, 2, 1))
+ assert_equal(Matrix[[4,0,0,0],[0,3,0,0],[0,0,2,0],[0,0,0,1]], Matrix.diagonal(4, 3, 2, 1))
+ end
+
+ def test_scalar
+ assert_equal(Matrix[[2,0,0],[0,2,0],[0,0,2]], Matrix.scalar(3, 2))
+ assert_equal(Matrix[[2,0,0,0],[0,2,0,0],[0,0,2,0],[0,0,0,2]], Matrix.scalar(4, 2))
+ end
+
+ def test_identity2
+ assert_equal(Matrix[[1,0,0],[0,1,0],[0,0,1]], Matrix.identity(3))
+ assert_equal(Matrix[[1,0,0],[0,1,0],[0,0,1]], Matrix.unit(3))
+ assert_equal(Matrix[[1,0,0],[0,1,0],[0,0,1]], Matrix.I(3))
+ assert_equal(Matrix[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]], Matrix.identity(4))
+ end
+
+ def test_zero
+ assert_equal(Matrix[[0,0,0],[0,0,0],[0,0,0]], Matrix.zero(3))
+ assert_equal(Matrix[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]], Matrix.zero(4))
+ assert_equal(Matrix[[0]], Matrix.zero(1))
+ end
+
+ def test_row_vector
+ assert_equal(Matrix[[1,2,3,4]], Matrix.row_vector([1,2,3,4]))
+ end
+
+ def test_column_vector
+ assert_equal(Matrix[[1],[2],[3],[4]], Matrix.column_vector([1,2,3,4]))
+ end
+
+ def test_empty
+ m = Matrix.empty(2, 0)
+ assert_equal(Matrix[ [], [] ], m)
+ n = Matrix.empty(0, 3)
+ assert_equal(Matrix.columns([ [], [], [] ]), n)
+ assert_equal(Matrix[[0, 0, 0], [0, 0, 0]], m * n)
+ end
+
+ def test_row
+ assert_equal(Vector[1, 2, 3], @m1.row(0))
+ assert_equal(Vector[4, 5, 6], @m1.row(1))
+ a = []; @m1.row(0) {|x| a << x }
+ assert_equal([1, 2, 3], a)
+ end
+
+ def test_column
+ assert_equal(Vector[1, 4], @m1.column(0))
+ assert_equal(Vector[2, 5], @m1.column(1))
+ assert_equal(Vector[3, 6], @m1.column(2))
+ a = []; @m1.column(0) {|x| a << x }
+ assert_equal([1, 4], a)
+ end
+
+ def test_collect
+ assert_equal(Matrix[[1, 4, 9], [16, 25, 36]], @m1.collect {|x| x ** 2 })
+ end
+
+ def test_minor
+ assert_equal(Matrix[[1, 2], [4, 5]], @m1.minor(0..1, 0..1))
+ assert_equal(Matrix[[2], [5]], @m1.minor(0..1, 1..1))
+ assert_equal(Matrix[[4, 5]], @m1.minor(1..1, 0..1))
+ assert_equal(Matrix[[1, 2], [4, 5]], @m1.minor(0, 2, 0, 2))
+ assert_equal(Matrix[[4, 5]], @m1.minor(1, 1, 0, 2))
+ assert_equal(Matrix[[2], [5]], @m1.minor(0, 2, 1, 1))
+ assert_raise(ArgumentError) { @m1.minor(0) }
+ end
+
+ def test_regular?
+ assert(Matrix[[1, 0], [0, 1]].regular?)
+ assert(Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]].regular?)
+ assert(!Matrix[[1, 0, 0], [0, 0, 1], [0, 0, 1]].regular?)
+ end
+
+ def test_singular?
+ assert(!Matrix[[1, 0], [0, 1]].singular?)
+ assert(!Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]].singular?)
+ assert(Matrix[[1, 0, 0], [0, 0, 1], [0, 0, 1]].singular?)
+ end
+
+ def test_square?
+ assert(Matrix[[1, 0], [0, 1]].square?)
+ assert(Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]].square?)
+ assert(Matrix[[1, 0, 0], [0, 0, 1], [0, 0, 1]].square?)
+ assert(!Matrix[[1, 0, 0], [0, 1, 0]].square?)
+ end
+
+ def test_mul
+ assert_equal(Matrix[[2,4],[6,8]], Matrix[[2,4],[6,8]] * Matrix.I(2))
+ assert_equal(Matrix[[4,8],[12,16]], Matrix[[2,4],[6,8]] * 2)
+ assert_equal(Matrix[[4,8],[12,16]], 2 * Matrix[[2,4],[6,8]])
+ assert_equal(Matrix[[14,32],[32,77]], @m1 * @m1.transpose)
+ assert_equal(Matrix[[17,22,27],[22,29,36],[27,36,45]], @m1.transpose * @m1)
+ assert_equal(Vector[14,32], @m1 * Vector[1,2,3])
+ o = Object.new
+ def o.coerce(m)
+ [m, m.transpose]
+ end
+ assert_equal(Matrix[[14,32],[32,77]], @m1 * o)
+ end
+
+ def test_add
+ assert_equal(Matrix[[6,0],[-4,12]], Matrix.scalar(2,5) + Matrix[[1,0],[-4,7]])
+ assert_equal(Matrix[[3,5,7],[9,11,13]], @m1 + @n1)
+ assert_equal(Matrix[[3,5,7],[9,11,13]], @n1 + @m1)
+ assert_equal(Matrix[[2],[4],[6]], Matrix[[1],[2],[3]] + Vector[1,2,3])
+ assert_raise(Matrix::ErrOperationNotDefined) { @m1 + 1 }
+ o = Object.new
+ def o.coerce(m)
+ [m, m]
+ end
+ assert_equal(Matrix[[2,4,6],[8,10,12]], @m1 + o)
+ end
+
+ def test_sub
+ assert_equal(Matrix[[4,0],[4,-2]], Matrix.scalar(2,5) - Matrix[[1,0],[-4,7]])
+ assert_equal(Matrix[[-1,-1,-1],[-1,-1,-1]], @m1 - @n1)
+ assert_equal(Matrix[[1,1,1],[1,1,1]], @n1 - @m1)
+ assert_equal(Matrix[[0],[0],[0]], Matrix[[1],[2],[3]] - Vector[1,2,3])
+ assert_raise(Matrix::ErrOperationNotDefined) { @m1 - 1 }
+ o = Object.new
+ def o.coerce(m)
+ [m, m]
+ end
+ assert_equal(Matrix[[0,0,0],[0,0,0]], @m1 - o)
+ end
+
+ def test_div
+ assert_equal(Matrix[[0,1,1],[2,2,3]], @m1 / 2)
+ assert_equal(Matrix[[1,1],[1,1]], Matrix[[2,2],[2,2]] / Matrix.scalar(2,2))
+ o = Object.new
+ def o.coerce(m)
+ [m, Matrix.scalar(2,2)]
+ end
+ assert_equal(Matrix[[1,1],[1,1]], Matrix[[2,2],[2,2]] / o)
+ end
+
+ def test_exp
+ assert_equal(Matrix[[67,96],[48,99]], Matrix[[7,6],[3,9]] ** 2)
+ assert_equal(Matrix.I(5), Matrix.I(5) ** -1)
+ assert_raise(Matrix::ErrOperationNotImplemented) { Matrix.I(5) ** 1.0 }
+ assert_raise(Matrix::ErrOperationNotDefined) { Matrix.I(5) ** Object.new }
+ end
+
+ def test_det
+ assert_equal(45, Matrix[[7,6],[3,9]].det)
+ assert_equal(0, Matrix[[0,0],[0,0]].det)
+ assert_equal(-7, Matrix[[0,0,1],[0,7,6],[1,3,9]].det)
+ assert_equal(42, Matrix[[7,0,1,0,12],[8,1,1,9,1],[4,0,0,-7,17],[-1,0,0,-4,8],[10,1,1,8,6]].det)
+ end
+
+ def test_rank2
+ assert_equal(2, Matrix[[7,6],[3,9]].rank)
+ assert_equal(0, Matrix[[0,0],[0,0]].rank)
+ assert_equal(3, Matrix[[0,0,1],[0,7,6],[1,3,9]].rank)
+ assert_equal(1, Matrix[[0,1],[0,1],[0,1]].rank)
+ assert_equal(2, @m1.rank)
+ end
+
+ def test_trace
+ assert_equal(1+5+9, Matrix[[1,2,3],[4,5,6],[7,8,9]].trace)
+ end
+
+ def test_transpose
+ assert_equal(Matrix[[1,4],[2,5],[3,6]], @m1.transpose)
+ end
+
+ def test_row_vectors
+ assert_equal([Vector[1,2,3], Vector[4,5,6]], @m1.row_vectors)
+ end
+
+ def test_column_vectors
+ assert_equal([Vector[1,4], Vector[2,5], Vector[3,6]], @m1.column_vectors)
+ end
+
+ def test_to_s
+ assert_equal("Matrix[[1, 2, 3], [4, 5, 6]]", @m1.to_s)
+ assert_equal("Matrix.empty(0, 0)", Matrix[].to_s)
+ assert_equal("Matrix.empty(1, 0)", Matrix[[]].to_s)
+ end
+
+ def test_inspect
+ assert_equal("Matrix[[1, 2, 3], [4, 5, 6]]", @m1.inspect)
+ assert_equal("Matrix.empty(0, 0)", Matrix[].inspect)
+ assert_equal("Matrix.empty(1, 0)", Matrix[[]].inspect)
+ end
+
+ def test_scalar_add
+ s1 = @m1.coerce(1).first
+ assert_equal(Matrix[[1]], (s1 + 0) * Matrix[[1]])
+ assert_raise(Matrix::ErrOperationNotDefined) { s1 + Vector[0] }
+ assert_raise(Matrix::ErrOperationNotDefined) { s1 + Matrix[[0]] }
+ o = Object.new
+ def o.coerce(x)
+ [1, 1]
+ end
+ assert_equal(2, s1 + o)
+ end
+
+ def test_scalar_sub
+ s1 = @m1.coerce(1).first
+ assert_equal(Matrix[[1]], (s1 - 0) * Matrix[[1]])
+ assert_raise(Matrix::ErrOperationNotDefined) { s1 - Vector[0] }
+ assert_raise(Matrix::ErrOperationNotDefined) { s1 - Matrix[[0]] }
+ o = Object.new
+ def o.coerce(x)
+ [1, 1]
+ end
+ assert_equal(0, s1 - o)
+ end
+
+ def test_scalar_mul
+ s1 = @m1.coerce(1).first
+ assert_equal(Matrix[[1]], (s1 * 1) * Matrix[[1]])
+ assert_equal(Vector[2], s1 * Vector[2])
+ assert_equal(Matrix[[2]], s1 * Matrix[[2]])
+ o = Object.new
+ def o.coerce(x)
+ [1, 1]
+ end
+ assert_equal(1, s1 * o)
+ end
+
+ def test_scalar_div
+ s1 = @m1.coerce(1).first
+ assert_equal(Matrix[[1]], (s1 / 1) * Matrix[[1]])
+ assert_raise(Matrix::ErrOperationNotDefined) { s1 / Vector[0] }
+ assert_equal(Matrix[[Rational(1,2)]], s1 / Matrix[[2]])
+ o = Object.new
+ def o.coerce(x)
+ [1, 1]
+ end
+ assert_equal(1, s1 / o)
+ end
+
+ def test_scalar_pow
+ s1 = @m1.coerce(1).first
+ assert_equal(Matrix[[1]], (s1 ** 1) * Matrix[[1]])
+ assert_raise(Matrix::ErrOperationNotDefined) { s1 ** Vector[0] }
+ assert_raise(Matrix::ErrOperationNotImplemented) { s1 ** Matrix[[1]] }
+ o = Object.new
+ def o.coerce(x)
+ [1, 1]
+ end
+ assert_equal(1, s1 ** o)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/matrix/test_vector.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/matrix/test_vector.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/matrix/test_vector.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,134 @@
+require 'test/unit'
+require 'matrix'
+
+class TestVector < Test::Unit::TestCase
+ def setup
+ @v1 = Vector[1,2,3]
+ @v2 = Vector[1,2,3]
+ @v3 = @v1.clone
+ @v4 = Vector[1.0, 2.0, 3.0]
+ @w1 = Vector[2,3,4]
+ end
+
+ def test_identity
+ assert_same @v1, @v1
+ assert_not_same @v1, @v2
+ assert_not_same @v1, @v3
+ assert_not_same @v1, @v4
+ assert_not_same @v1, @w1
+ end
+
+ def test_equality
+ assert_equal @v1, @v1
+ assert_equal @v1, @v2
+ assert_equal @v1, @v3
+ assert_equal @v1, @v4
+ assert_not_equal @v1, @w1
+ end
+
+ def test_hash_equality
+ assert @v1.eql?(@v1)
+ assert @v1.eql?(@v2)
+ assert @v1.eql?(@v3)
+ assert !@v1.eql?(@v4)
+ assert !@v1.eql?(@w1)
+
+ hash = { @v1 => :value }
+ assert hash.key?(@v1)
+ assert hash.key?(@v2)
+ assert hash.key?(@v3)
+ assert !hash.key?(@v4)
+ assert !hash.key?(@w1)
+ end
+
+ def test_hash
+ assert_equal @v1.hash, @v1.hash
+ assert_equal @v1.hash, @v2.hash
+ assert_equal @v1.hash, @v3.hash
+ end
+
+ def test_aref
+ assert_equal(1, @v1[0])
+ assert_equal(2, @v1[1])
+ assert_equal(3, @v1[2])
+ assert_equal(3, @v1[-1])
+ assert_equal(nil, @v1[3])
+ end
+
+ def test_size
+ assert_equal(3, @v1.size)
+ end
+
+ def test_each2
+ a = []
+ @v1.each2(@v4) {|x, y| a << [x, y] }
+ assert_equal([[1,1.0],[2,2.0],[3,3.0]], a)
+ end
+
+ def test_collect
+ a = @v1.collect {|x| x + 1 }
+ assert_equal(Vector[2,3,4], a)
+ end
+
+ def test_collect2
+ a = @v1.collect2(@v4) {|x, y| x + y }
+ assert_equal([2.0,4.0,6.0], a)
+ end
+
+ def test_map2
+ a = @v1.map2(@v4) {|x, y| x + y }
+ assert_equal(Vector[2.0,4.0,6.0], a)
+ end
+
+ def test_mul
+ assert_equal(Vector[2,4,6], @v1 * 2)
+ assert_equal(Matrix[[1, 4, 9], [2, 8, 18], [3, 12, 27]], @v1 * Matrix[[1,4,9]])
+ assert_raise(Matrix::ErrOperationNotDefined) { @v1 * Vector[1,4,9] }
+ o = Object.new
+ def o.coerce(x)
+ [1, 1]
+ end
+ assert_equal(1, Vector[1, 2, 3] * o)
+ end
+
+ def test_add
+ assert_equal(Vector[2,4,6], @v1 + @v1)
+ assert_equal(Matrix[[2],[6],[12]], @v1 + Matrix[[1],[4],[9]])
+ o = Object.new
+ def o.coerce(x)
+ [1, 1]
+ end
+ assert_equal(2, Vector[1, 2, 3] + o)
+ end
+
+ def test_sub
+ assert_equal(Vector[0,0,0], @v1 - @v1)
+ assert_equal(Matrix[[0],[-2],[-6]], @v1 - Matrix[[1],[4],[9]])
+ o = Object.new
+ def o.coerce(x)
+ [1, 1]
+ end
+ assert_equal(0, Vector[1, 2, 3] - o)
+ end
+
+ def test_inner_product
+ assert_equal(1+4+9, @v1.inner_product(@v1))
+ end
+
+ def test_r
+ assert_equal(5, Vector[3, 4].r)
+ end
+
+ def test_covector
+ assert_equal(Matrix[[1,2,3]], @v1.covector)
+ end
+
+ def test_to_s
+ assert_equal("Vector[1, 2, 3]", @v1.to_s)
+ end
+
+ def test_inspect
+ assert_equal("Vector[1, 2, 3]", @v1.inspect)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/minitest/test_mini_mock.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/minitest/test_mini_mock.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/minitest/test_mini_mock.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,83 @@
+############################################################
+# This file is imported from a different project.
+# DO NOT make modifications in this repo.
+# File a patch instead and assign it to Ryan Davis
+############################################################
+
+require 'minitest/mock'
+require 'minitest/unit'
+
+MiniTest::Unit.autorun
+
+class TestMiniMock < MiniTest::Unit::TestCase
+ def setup
+ @mock = MiniTest::Mock.new.expect(:foo, nil)
+ @mock.expect(:meaning_of_life, 42)
+ end
+
+ def test_should_create_stub_method
+ assert_nil @mock.foo
+ end
+
+ def test_should_allow_return_value_specification
+ assert_equal 42, @mock.meaning_of_life
+ end
+
+ def test_should_blow_up_if_not_called
+ @mock.foo
+
+ util_verify_bad
+ end
+
+ def test_should_not_blow_up_if_everything_called
+ @mock.foo
+ @mock.meaning_of_life
+
+ assert @mock.verify
+ end
+
+ def test_should_allow_expectations_to_be_added_after_creation
+ @mock.expect(:bar, true)
+ assert @mock.bar
+ end
+
+ def test_should_not_verify_if_new_expected_method_is_not_called
+ @mock.foo
+ @mock.meaning_of_life
+ @mock.expect(:bar, true)
+
+ util_verify_bad
+ end
+
+ def test_should_not_verify_if_unexpected_method_is_called
+ assert_raises NoMethodError do
+ @mock.unexpected
+ end
+ end
+
+ def test_should_blow_up_on_wrong_number_of_arguments
+ @mock.foo
+ @mock.meaning_of_life
+ @mock.expect(:sum, 3, [1, 2])
+
+ assert_raises ArgumentError do
+ @mock.sum
+ end
+ end
+
+ def test_should_blow_up_on_wrong_arguments
+ @mock.foo
+ @mock.meaning_of_life
+ @mock.expect(:sum, 3, [1, 2])
+
+ @mock.sum(2, 4)
+
+ util_verify_bad
+ end
+
+ def util_verify_bad
+ assert_raises MockExpectationError do
+ @mock.verify
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/minitest/test_mini_spec.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/minitest/test_mini_spec.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/minitest/test_mini_spec.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,172 @@
+############################################################
+# This file is imported from a different project.
+# DO NOT make modifications in this repo.
+# File a patch instead and assign it to Ryan Davis
+############################################################
+
+require 'minitest/spec'
+
+MiniTest::Unit.autorun
+
+describe MiniTest::Spec do
+ before do
+ @assertion_count = 4
+ end
+
+ after do
+ self._assertions.must_equal @assertion_count
+ end
+
+ # TODO: figure out how the hell to write a test for this
+ # it "will skip if there is no block"
+
+ it "needs to have all methods named well" do
+ @assertion_count = 2
+
+ methods = Object.public_instance_methods.find_all { |n| n =~ /^must|^wont/ }
+ methods.map! { |m| m.to_s } if Symbol === methods.first
+
+ musts, wonts = methods.sort.partition { |m| m =~ /^must/ }
+
+ expected_musts = %w(must_be
+ must_be_close_to
+ must_be_empty
+ must_be_instance_of
+ must_be_kind_of
+ must_be_nil
+ must_be_same_as
+ must_be_within_delta
+ must_be_within_epsilon
+ must_equal
+ must_include
+ must_match
+ must_raise
+ must_respond_to
+ must_send
+ must_throw)
+
+ expected_wonts = expected_musts.map { |m| m.sub(/^must/, 'wont') }
+ expected_wonts.reject! { |m| m =~ /wont_(not|raise|throw|send)/ }
+
+ musts.must_equal expected_musts
+ wonts.must_equal expected_wonts
+ end
+
+ it "needs to verify equality" do
+ (6 * 7).must_equal(42).must_equal true
+ proc { (6 * 9).must_equal(42) }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify floats within a delta" do
+ (6.0 * 7).must_be_close_to(42.0).must_equal true
+ proc { 42.002.must_be_close_to 42.0 }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify types of objects" do
+ (6 * 7).must_be_instance_of(Fixnum).must_equal true
+ proc { (6 * 7).must_be_instance_of String }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify kinds of objects" do
+ @assertion_count = 6
+
+ (6 * 7).must_be_kind_of(Fixnum).must_equal true
+ (6 * 7).must_be_kind_of(Numeric).must_equal true
+ proc { (6 * 7).must_be_kind_of String }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify regexp matches" do
+ @assertion_count = 6
+
+ "blah".must_match(/\w+/).must_equal true
+ proc { "blah".must_match(/\d+/) }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify nil" do
+ nil.must_be_nil.must_equal true
+ proc { 42.must_be_nil }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify using any operator" do
+ 41.must_be(:<, 42).must_equal true
+ proc { 42.must_be(:<, 41) }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to catch an expected exception" do
+ @assertion_count = 2
+
+ proc { raise "blah" }.must_raise RuntimeError
+ proc { raise MiniTest::Assertion }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to catch an unexpected exception" do
+ @assertion_count = 2
+
+ proc {
+ proc { raise MiniTest::Assertion }.must_raise(RuntimeError)
+ }.must_raise MiniTest::Assertion
+ end
+
+ it "needs raise if an expected exception is not raised" do
+ @assertion_count = 2
+
+ proc { proc { 42 }.must_raise(RuntimeError) }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to be able to catch a MiniTest::Assertion exception" do
+ @assertion_count = 2
+
+ proc { 1.wont_equal 1 }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify using respond_to" do
+ 42.must_respond_to(:+).must_equal true
+ proc { 42.must_respond_to(:clear) }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify identity" do
+ 1.must_be_same_as(1).must_equal true
+ proc { 1.must_be_same_as 2 }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify throw" do
+ @assertion_count = 6
+
+ proc { throw :blah }.must_throw(:blah).must_equal true
+ proc { proc { }.must_throw(:blah) }.must_raise MiniTest::Assertion
+ proc { proc { throw :xxx }.must_throw(:blah) }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify inequality" do
+ 42.wont_equal(6 * 9).must_equal false
+ proc { 1.wont_equal 1 }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify mismatch" do
+ @assertion_count = 6
+ "blah".wont_match(/\d+/).must_equal false
+ proc { "blah".wont_match(/\w+/) }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify non-nil" do
+ 42.wont_be_nil.must_equal false
+ proc { nil.wont_be_nil }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to verify non-identity" do
+ 1.wont_be_same_as(2).must_equal false
+ proc { 1.wont_be_same_as 1 }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to be sensible about must_include order" do
+ @assertion_count = 6
+ [1, 2, 3].must_include(2).must_equal true
+ proc { [1, 2, 3].must_include 5 }.must_raise MiniTest::Assertion
+ end
+
+ it "needs to be sensible about wont_include order" do
+ @assertion_count = 6
+ [1, 2, 3].wont_include(5).must_equal false
+ proc { [1, 2, 3].wont_include 2 }.must_raise MiniTest::Assertion
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/minitest/test_mini_test.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/minitest/test_mini_test.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/minitest/test_mini_test.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1020 @@
+############################################################
+# This file is imported from a different project.
+# DO NOT make modifications in this repo.
+# File a patch instead and assign it to Ryan Davis
+############################################################
+
+require 'stringio'
+require 'pathname'
+require 'minitest/unit'
+
+MiniTest::Unit.autorun
+
+module M; end
+class E < StandardError; include M; end
+
+class TestMiniTest < MiniTest::Unit::TestCase
+ def setup
+ srand 42
+ MiniTest::Unit::TestCase.reset
+ @tu = MiniTest::Unit.new
+ @output = StringIO.new("")
+ MiniTest::Unit.output = @output
+ assert_equal [0, 0], @tu.run_test_suites
+ end
+
+ def teardown
+ MiniTest::Unit.output = $stdout
+ Object.send :remove_const, :ATestCase if defined? ATestCase
+ end
+
+ pwd = Pathname.new(File.expand_path(Dir.pwd))
+ basedir = Pathname.new(File.expand_path(MiniTest::MINI_DIR)) + 'mini'
+ basedir = basedir.relative_path_from(pwd).to_s
+ MINITEST_BASE_DIR = basedir[/\A\./] ? basedir : "./#{basedir}"
+ BT_MIDDLE = ["#{MINITEST_BASE_DIR}/test.rb:165:in `run_test_suites'",
+ "#{MINITEST_BASE_DIR}/test.rb:161:in `each'",
+ "#{MINITEST_BASE_DIR}/test.rb:161:in `run_test_suites'",
+ "#{MINITEST_BASE_DIR}/test.rb:158:in `each'",
+ "#{MINITEST_BASE_DIR}/test.rb:158:in `run_test_suites'",
+ "#{MINITEST_BASE_DIR}/test.rb:139:in `run'",
+ "#{MINITEST_BASE_DIR}/test.rb:106:in `run'"]
+
+ def test_filter_backtrace
+ # this is a semi-lame mix of relative paths.
+ # I cheated by making the autotest parts not have ./
+ bt = (["lib/autotest.rb:571:in `add_exception'",
+ "test/test_autotest.rb:62:in `test_add_exception'",
+ "#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
+ BT_MIDDLE +
+ ["#{MINITEST_BASE_DIR}/test.rb:29",
+ "test/test_autotest.rb:422"])
+ bt = util_expand_bt bt
+
+ ex = ["lib/autotest.rb:571:in `add_exception'",
+ "test/test_autotest.rb:62:in `test_add_exception'"]
+ ex = util_expand_bt ex
+
+ fu = MiniTest::filter_backtrace(bt)
+
+ assert_equal ex, fu
+ end
+
+ def util_expand_bt bt
+ if RUBY_VERSION =~ /^1\.9/ then
+ bt.map { |f| (f =~ /^\./) ? File.expand_path(f) : f }
+ else
+ bt
+ end
+ end
+
+ def test_filter_backtrace_all_unit
+ bt = (["#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
+ BT_MIDDLE +
+ ["#{MINITEST_BASE_DIR}/test.rb:29"])
+ ex = bt.clone
+ fu = MiniTest::filter_backtrace(bt)
+ assert_equal ex, fu
+ end
+
+ def test_filter_backtrace_unit_starts
+ bt = (["#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
+ BT_MIDDLE +
+ ["#{MINITEST_BASE_DIR}/mini/test.rb:29",
+ "-e:1"])
+
+ bt = util_expand_bt bt
+
+ ex = ["-e:1"]
+ fu = MiniTest::filter_backtrace(bt)
+ assert_equal ex, fu
+ end
+
+ def test_class_puke_with_assertion_failed
+ exception = MiniTest::Assertion.new "Oh no!"
+ exception.set_backtrace ["unhappy"]
+ assert_equal 'F', @tu.puke('SomeClass', 'method_name', exception)
+ assert_equal 1, @tu.failures
+ assert_match(/^Failure.*Oh no!/m, @tu.report.first)
+ assert_match("method_name(SomeClass) [unhappy]", @tu.report.first)
+ end
+
+ def test_class_puke_with_failure_and_flunk_in_backtrace
+ exception = begin
+ MiniTest::Unit::TestCase.new('fake tc').flunk
+ rescue MiniTest::Assertion => failure
+ failure
+ end
+ assert_equal 'F', @tu.puke('SomeClass', 'method_name', exception)
+ refute @tu.report.any?{|line| line =~ /in .flunk/}
+ end
+
+ def test_class_puke_with_assertion_failed_and_long_backtrace
+ bt = (["test/test_some_class.rb:615:in `method_name'",
+ "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raises'",
+ "test/test_some_class.rb:615:in `each'",
+ "test/test_some_class.rb:614:in `test_method_name'",
+ "#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
+ BT_MIDDLE +
+ ["#{MINITEST_BASE_DIR}/test.rb:29"])
+ bt = util_expand_bt bt
+
+ ex_location = util_expand_bt(["test/test_some_class.rb:615"]).first
+
+ exception = MiniTest::Assertion.new "Oh no!"
+ exception.set_backtrace bt
+ assert_equal 'F', @tu.puke('TestSomeClass', 'test_method_name', exception)
+ assert_equal 1, @tu.failures
+ assert_match(/^Failure.*Oh no!/m, @tu.report.first)
+ assert_match("test_method_name(TestSomeClass) [#{ex_location}]", @tu.report.first)
+ end
+
+ def test_class_puke_with_assertion_failed_and_user_defined_assertions
+ bt = (["lib/test/my/util.rb:16:in `another_method_name'",
+ "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raises'",
+ "lib/test/my/util.rb:15:in `block in assert_something'",
+ "lib/test/my/util.rb:14:in `each'",
+ "lib/test/my/util.rb:14:in `assert_something'",
+ "test/test_some_class.rb:615:in `each'",
+ "test/test_some_class.rb:614:in `test_method_name'",
+ "#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
+ BT_MIDDLE +
+ ["#{MINITEST_BASE_DIR}/test.rb:29"])
+ bt = util_expand_bt bt
+
+ ex_location = util_expand_bt(["test/test_some_class.rb:615"]).first
+
+ exception = MiniTest::Assertion.new "Oh no!"
+ exception.set_backtrace bt
+ assert_equal 'F', @tu.puke('TestSomeClass', 'test_method_name', exception)
+ assert_equal 1, @tu.failures
+ assert_match(/^Failure.*Oh no!/m, @tu.report.first)
+ assert_match("test_method_name(TestSomeClass) [#{ex_location}]", @tu.report.first)
+ end
+
+ def test_class_puke_with_flunk_and_user_defined_assertions
+ bt = (["lib/test/my/util.rb:16:in `flunk'",
+ "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raises'",
+ "lib/test/my/util.rb:15:in `block in assert_something'",
+ "lib/test/my/util.rb:14:in `each'",
+ "lib/test/my/util.rb:14:in `assert_something'",
+ "test/test_some_class.rb:615:in `each'",
+ "test/test_some_class.rb:614:in `test_method_name'",
+ "#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
+ BT_MIDDLE +
+ ["#{MINITEST_BASE_DIR}/test.rb:29"])
+ bt = util_expand_bt bt
+
+ ex_location = util_expand_bt(["test/test_some_class.rb:615"]).first
+
+ exception = MiniTest::Assertion.new "Oh no!"
+ exception.set_backtrace bt
+ assert_equal 'F', @tu.puke('TestSomeClass', 'test_method_name', exception)
+ assert_equal 1, @tu.failures
+ assert_match(/^Failure.*Oh no!/m, @tu.report.first)
+ assert_match("test_method_name(TestSomeClass) [#{ex_location}]", @tu.report.first)
+ end
+
+ def test_class_puke_with_non_failure_exception
+ exception = Exception.new("Oh no again!")
+ assert_equal 'E', @tu.puke('SomeClass', 'method_name', exception)
+ assert_equal 1, @tu.errors
+ assert_match(/^Exception.*Oh no again!/m, @tu.report.first)
+ end
+
+ def test_class_run_test_suites
+ tc = Class.new(MiniTest::Unit::TestCase) do
+ def test_something
+ assert true
+ end
+ end
+
+ Object.const_set(:ATestCase, tc)
+
+ assert_equal [1, 1], @tu.run_test_suites
+ end
+
+ def test_run_failing # TODO: add error test
+ tc = Class.new(MiniTest::Unit::TestCase) do
+ def test_something
+ assert true
+ end
+
+ def test_failure
+ assert false
+ end
+ end
+
+ Object.const_set(:ATestCase, tc)
+
+ @tu.run %w[-s 42]
+
+ expected = "Loaded suite blah
+Started
+F.
+Finished in 0.00
+
+ 1) Failure:
+test_failure(ATestCase) [FILE:LINE]:
+Failed assertion, no message given.
+
+2 tests, 2 assertions, 1 failures, 0 errors, 0 skips
+
+Test run options: --seed 42
+"
+ util_assert_report expected
+ end
+
+ def test_run_error
+ tc = Class.new(MiniTest::Unit::TestCase) do
+ def test_something
+ assert true
+ end
+
+ def test_error
+ raise "unhandled exception"
+ end
+ end
+
+ Object.const_set(:ATestCase, tc)
+
+ @tu.run %w[-s 42]
+
+ expected = "Loaded suite blah
+Started
+E.
+Finished in 0.00
+
+ 1) Error:
+test_error(ATestCase):
+RuntimeError: unhandled exception
+ FILE:LINE:in `test_error'
+
+2 tests, 1 assertions, 0 failures, 1 errors, 0 skips
+
+Test run options: --seed 42
+"
+ util_assert_report expected
+ end
+
+ def test_run_error_teardown
+ tc = Class.new(MiniTest::Unit::TestCase) do
+ def test_something
+ assert true
+ end
+
+ def teardown
+ raise "unhandled exception"
+ end
+ end
+
+ Object.const_set(:ATestCase, tc)
+
+ @tu.run %w[-s 42]
+
+ expected = "Loaded suite blah
+Started
+E
+Finished in 0.00
+
+ 1) Error:
+test_something(ATestCase):
+RuntimeError: unhandled exception
+ FILE:LINE:in `teardown'
+
+1 tests, 1 assertions, 0 failures, 1 errors, 0 skips
+
+Test run options: --seed 42
+"
+ util_assert_report expected
+ end
+
+ def test_run_skip
+ tc = Class.new(MiniTest::Unit::TestCase) do
+ def test_something
+ assert true
+ end
+
+ def test_skip
+ skip "not yet"
+ end
+ end
+
+ Object.const_set(:ATestCase, tc)
+
+ @tu.run %w[-s 42]
+
+ expected = "Loaded suite blah
+Started
+S.
+Finished in 0.00
+
+ 1) Skipped:
+test_skip(ATestCase) [FILE:LINE]:
+not yet
+
+2 tests, 1 assertions, 0 failures, 0 errors, 1 skips
+
+Test run options: --seed 42
+"
+ util_assert_report expected
+ end
+
+ def util_assert_report expected = nil
+ expected ||= "Loaded suite blah
+Started
+.
+Finished in 0.00
+
+1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
+
+Test run options: --seed 42
+"
+ output = @output.string.sub(/Finished in .*/, "Finished in 0.00")
+ output.sub!(/Loaded suite .*/, 'Loaded suite blah')
+ output.sub!(/^(\s+)(?:#{Regexp.union(__FILE__, File.expand_path(__FILE__))}):\d+:/o, '\1FILE:LINE:')
+ output.sub!(/\[(?:#{Regexp.union(__FILE__, File.expand_path(__FILE__))}):\d+\]/o, '[FILE:LINE]')
+ assert_equal(expected, output)
+ end
+
+ def test_run_failing_filtered
+ tc = Class.new(MiniTest::Unit::TestCase) do
+ def test_something
+ assert true
+ end
+
+ def test_failure
+ assert false
+ end
+ end
+
+ Object.const_set(:ATestCase, tc)
+
+ @tu.run %w[-n /something/ -s 42]
+
+ expected = "Loaded suite blah
+Started
+.
+Finished in 0.00
+
+1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
+
+Test run options: --seed 42 --name \"/something/\"
+"
+ util_assert_report expected
+ end
+
+ def test_run_passing
+ tc = Class.new(MiniTest::Unit::TestCase) do
+ def test_something
+ assert true
+ end
+ end
+
+ Object.const_set(:ATestCase, tc)
+
+ @tu.run %w[-s 42]
+
+ util_assert_report
+ end
+end
+
+class TestMiniTestTestCase < MiniTest::Unit::TestCase
+ def setup
+ MiniTest::Unit::TestCase.reset
+
+ @tc = MiniTest::Unit::TestCase.new 'fake tc'
+ @zomg = "zomg ponies!"
+ @assertion_count = 1
+ end
+
+ def teardown
+ assert_equal(@assertion_count, @tc._assertions,
+ "expected #{@assertion_count} assertions to be fired during the test, not #{@tc._assertions}") if @tc._assertions
+ Object.send :remove_const, :ATestCase if defined? ATestCase
+ end
+
+ def test_class_inherited
+ @assertion_count = 0
+
+ Object.const_set(:ATestCase, Class.new(MiniTest::Unit::TestCase))
+
+ assert_equal [ATestCase], MiniTest::Unit::TestCase.test_suites
+ end
+
+ def test_class_test_suites
+ @assertion_count = 0
+
+ Object.const_set(:ATestCase, Class.new(MiniTest::Unit::TestCase))
+
+ assert_equal 1, MiniTest::Unit::TestCase.test_suites.size
+ assert_equal [ATestCase], MiniTest::Unit::TestCase.test_suites
+ end
+
+ def test_class_asserts_match_refutes
+ @assertion_count = 0
+
+ methods = MiniTest::Assertions.public_instance_methods
+ methods.map! { |m| m.to_s } if Symbol === methods.first
+
+ ignores = %w(assert_block assert_no_match assert_not_equal assert_not_nil
+ assert_not_same assert_nothing_thrown assert_raise
+ assert_nothing_raised assert_raises assert_throws assert_send)
+ asserts = methods.grep(/^assert/).sort - ignores
+ refutes = methods.grep(/^refute/).sort - ignores
+
+ assert_empty refutes.map { |n| n.sub(/^refute/, 'assert') } - asserts
+ assert_empty asserts.map { |n| n.sub(/^assert/, 'refute') } - refutes
+ end
+
+ def test_assert
+ @assertion_count = 2
+
+ @tc.assert_equal true, @tc.assert(true), "returns true on success"
+ end
+
+ def test_assert__triggered
+ util_assert_triggered "Failed assertion, no message given." do
+ @tc.assert false
+ end
+ end
+
+ def test_assert__triggered_message
+ util_assert_triggered @zomg do
+ @tc.assert false, @zomg
+ end
+ end
+
+ def test_assert_block
+ @tc.assert_block do
+ true
+ end
+ end
+
+ def test_assert_block_triggered
+ util_assert_triggered 'Expected block to return true value.' do
+ @tc.assert_block do
+ false
+ end
+ end
+ end
+
+ def test_assert_empty
+ @assertion_count = 2
+
+ @tc.assert_empty []
+ end
+
+ def test_assert_empty_triggered
+ @assertion_count = 2
+
+ util_assert_triggered "Expected [1] to be empty." do
+ @tc.assert_empty [1]
+ end
+ end
+
+ def test_assert_equal
+ @tc.assert_equal 1, 1
+ end
+
+ def test_assert_equal_different
+ util_assert_triggered "Expected 1, not 2." do
+ @tc.assert_equal 1, 2
+ end
+ end
+
+ def test_assert_in_delta
+ @tc.assert_in_delta 0.0, 1.0 / 1000, 0.1
+ end
+
+ def test_assert_in_delta_triggered
+ util_assert_triggered 'Expected 0.0 - 0.001 (0.001) to be < 1.0e-06.' do
+ @tc.assert_in_delta 0.0, 1.0 / 1000, 0.000001
+ end
+ end
+
+ def test_assert_in_epsilon
+ @assertion_count = 8
+
+ @tc.assert_in_epsilon 10000, 9991
+ @tc.assert_in_epsilon 9991, 10000
+ @tc.assert_in_epsilon 1.0, 1.001
+ @tc.assert_in_epsilon 1.001, 1.0
+
+ @tc.assert_in_epsilon 10000, 9999.1, 0.0001
+ @tc.assert_in_epsilon 9999.1, 10000, 0.0001
+ @tc.assert_in_epsilon 1.0, 1.0001, 0.0001
+ @tc.assert_in_epsilon 1.0001, 1.0, 0.0001
+ end
+
+ def test_assert_in_epsilon_triggered
+ util_assert_triggered 'Expected 10000 - 9990 (10) to be < 9.99.' do
+ @tc.assert_in_epsilon 10000, 9990
+ end
+ end
+
+ def test_assert_includes
+ @assertion_count = 2
+
+ @tc.assert_includes [true], true
+ end
+
+ def test_assert_includes_triggered
+ @assertion_count = 3
+
+ e = @tc.assert_raises MiniTest::Assertion do
+ @tc.assert_includes [true], false
+ end
+
+ expected = "Expected [true] to include false."
+ assert_equal expected, e.message
+ end
+
+ def test_assert_instance_of
+ @tc.assert_instance_of String, "blah"
+ end
+
+ def test_assert_instance_of_triggered
+ util_assert_triggered 'Expected "blah" to be an instance of Array, not String.' do
+ @tc.assert_instance_of Array, "blah"
+ end
+ end
+
+ def test_assert_kind_of
+ @tc.assert_kind_of String, "blah"
+ end
+
+ def test_assert_kind_of_triggered
+ util_assert_triggered 'Expected "blah" to be a kind of Array, not String.' do
+ @tc.assert_kind_of Array, "blah"
+ end
+ end
+
+ def test_assert_match
+ @assertion_count = 2
+ @tc.assert_match(/\w+/, "blah blah blah")
+ end
+
+ def test_assert_match_object
+ @assertion_count = 2
+
+ pattern = Object.new
+ def pattern.=~(other) true end
+
+ @tc.assert_match pattern, 5
+ end
+
+ def test_assert_match_object_triggered
+ @assertion_count = 2
+
+ pattern = Object.new
+ def pattern.=~(other) false end
+ def pattern.inspect; "<<Object>>" end
+
+ util_assert_triggered 'Expected <<Object>> to match 5.' do
+ @tc.assert_match pattern, 5
+ end
+ end
+
+ def test_assert_match_triggered
+ @assertion_count = 2
+ util_assert_triggered 'Expected /\d+/ to match "blah blah blah".' do
+ @tc.assert_match(/\d+/, "blah blah blah")
+ end
+ end
+
+ def test_assert_nil
+ @tc.assert_nil nil
+ end
+
+ def test_assert_nil_triggered
+ util_assert_triggered 'Expected 42 to be nil.' do
+ @tc.assert_nil 42
+ end
+ end
+
+ def test_assert_operator
+ @tc.assert_operator 2, :>, 1
+ end
+
+ def test_assert_operator_triggered
+ util_assert_triggered "Expected 2 to be < 1." do
+ @tc.assert_operator 2, :<, 1
+ end
+ end
+
+ def test_assert_raises
+ @tc.assert_raises RuntimeError do
+ raise "blah"
+ end
+ end
+
+ def test_assert_raises_module
+ @tc.assert_raises M do
+ raise E
+ end
+ end
+
+ def test_assert_raises_triggered_different
+ e = assert_raises MiniTest::Assertion do
+ @tc.assert_raises RuntimeError do
+ raise SyntaxError, "icky"
+ end
+ end
+
+ expected = "[RuntimeError] exception expected, not
+Class: <SyntaxError>
+Message: <\"icky\">
+---Backtrace---
+FILE:LINE:in `test_assert_raises_triggered_different'
+---------------"
+
+ actual = e.message.gsub(/^.+:\d+/, 'FILE:LINE')
+ actual.gsub!(/block \(\d+ levels\) in /, '') if RUBY_VERSION =~ /^1\.9/
+
+ assert_equal expected, actual
+ end
+
+ def test_assert_raises_triggered_different_msg
+ e = assert_raises MiniTest::Assertion do
+ @tc.assert_raises RuntimeError, "XXX" do
+ raise SyntaxError, "icky"
+ end
+ end
+
+ expected = "XXX
+[RuntimeError] exception expected, not
+Class: <SyntaxError>
+Message: <\"icky\">
+---Backtrace---
+FILE:LINE:in `test_assert_raises_triggered_different_msg'
+---------------"
+
+ actual = e.message.gsub(/^.+:\d+/, 'FILE:LINE')
+ actual.gsub!(/block \(\d+ levels\) in /, '') if RUBY_VERSION =~ /^1\.9/
+
+ assert_equal expected, actual
+ end
+
+ def test_assert_raises_triggered_none
+ e = assert_raises MiniTest::Assertion do
+ @tc.assert_raises MiniTest::Assertion do
+ # do nothing
+ end
+ end
+
+ expected = "MiniTest::Assertion expected but nothing was raised."
+
+ assert_equal expected, e.message
+ end
+
+ def test_assert_raises_triggered_none_msg
+ e = assert_raises MiniTest::Assertion do
+ @tc.assert_raises MiniTest::Assertion, "XXX" do
+ # do nothing
+ end
+ end
+
+ expected = "XXX\nMiniTest::Assertion expected but nothing was raised."
+
+ assert_equal expected, e.message
+ end
+
+ def test_assert_raises_triggered_subclass
+ e = assert_raises MiniTest::Assertion do
+ @tc.assert_raises StandardError do
+ raise E
+ end
+ end
+
+ expected = "[StandardError] exception expected, not
+Class: <E>
+Message: <\"E\">
+---Backtrace---
+FILE:LINE:in `test_assert_raises_triggered_subclass'
+---------------"
+
+ actual = e.message.gsub(/^.+:\d+/, 'FILE:LINE')
+ actual.gsub!(/block \(\d+ levels\) in /, '') if RUBY_VERSION =~ /^1\.9/
+
+ assert_equal expected, actual
+ end
+
+ def test_assert_respond_to
+ @tc.assert_respond_to "blah", :empty?
+ end
+
+ def test_assert_respond_to_triggered
+ util_assert_triggered 'Expected "blah" (String) to respond to #rawr!.' do
+ @tc.assert_respond_to "blah", :rawr!
+ end
+ end
+
+ def test_assert_same
+ @assertion_count = 3
+
+ o = "blah"
+ @tc.assert_same 1, 1
+ @tc.assert_same :blah, :blah
+ @tc.assert_same o, o
+ end
+
+ def test_assert_same_triggered
+ @assertion_count = 2
+
+ util_assert_triggered 'Expected 2 (oid=N) to be the same as 1 (oid=N).' do
+ @tc.assert_same 1, 2
+ end
+
+ s1 = "blah"
+ s2 = "blah"
+
+ util_assert_triggered 'Expected "blah" (oid=N) to be the same as "blah" (oid=N).' do
+ @tc.assert_same s1, s2
+ end
+ end
+
+ def test_assert_send
+ @tc.assert_send [1, :<, 2]
+ end
+
+ def test_assert_send_bad
+ util_assert_triggered "Expected 1.>(*[2]) to return true." do
+ @tc.assert_send [1, :>, 2]
+ end
+ end
+
+ def test_assert_throws
+ @tc.assert_throws(:blah) do
+ throw :blah
+ end
+ end
+
+ def test_assert_throws_different
+ util_assert_triggered 'Expected :blah to have been thrown, not :not_blah.' do
+ @tc.assert_throws(:blah) do
+ throw :not_blah
+ end
+ end
+ end
+
+ def test_assert_throws_unthrown
+ util_assert_triggered 'Expected :blah to have been thrown.' do
+ @tc.assert_throws(:blah) do
+ # do nothing
+ end
+ end
+ end
+
+ def test_capture_io
+ @assertion_count = 0
+
+ out, err = capture_io do
+ puts 'hi'
+ warn 'bye!'
+ end
+
+ assert_equal "hi\n", out
+ assert_equal "bye!\n", err
+ end
+
+ def test_flunk
+ util_assert_triggered 'Epic Fail!' do
+ @tc.flunk
+ end
+ end
+
+ def test_flunk_message
+ util_assert_triggered @zomg do
+ @tc.flunk @zomg
+ end
+ end
+
+ def test_message
+ @assertion_count = 0
+
+ assert_equal "blah2.", @tc.message { "blah2" }.call
+ assert_equal "blah2.", @tc.message("") { "blah2" }.call
+ assert_equal "blah1.\nblah2.", @tc.message("blah1") { "blah2" }.call
+ end
+
+ def test_pass
+ @tc.pass
+ end
+
+ def test_test_methods_sorted
+ @assertion_count = 0
+
+ sample_test_case = Class.new(MiniTest::Unit::TestCase) do
+ def self.test_order; :sorted end
+ def test_test3; assert "does not matter" end
+ def test_test2; assert "does not matter" end
+ def test_test1; assert "does not matter" end
+ end
+
+ expected = %w(test_test1 test_test2 test_test3)
+ assert_equal expected, sample_test_case.test_methods
+ end
+
+ def test_test_methods_random
+ @assertion_count = 0
+
+ sample_test_case = Class.new(MiniTest::Unit::TestCase) do
+ def test_test1; assert "does not matter" end
+ def test_test2; assert "does not matter" end
+ def test_test3; assert "does not matter" end
+ end
+
+ srand 42
+ expected = %w(test_test2 test_test1 test_test3)
+ assert_equal expected, sample_test_case.test_methods
+ end
+
+ def test_refute
+ @assertion_count = 2
+
+ @tc.assert_equal false, @tc.refute(false), "returns false on success"
+ end
+
+ def test_refute_empty
+ @assertion_count = 2
+
+ @tc.refute_empty [1]
+ end
+
+ def test_refute_empty_triggered
+ @assertion_count = 2
+
+ util_assert_triggered "Expected [] to not be empty." do
+ @tc.refute_empty []
+ end
+ end
+
+ def test_refute_equal
+ @tc.refute_equal "blah", "yay"
+ end
+
+ def test_refute_equal_triggered
+ util_assert_triggered 'Expected "blah" to not be equal to "blah".' do
+ @tc.refute_equal "blah", "blah"
+ end
+ end
+
+ def test_refute_in_delta
+ @tc.refute_in_delta 0.0, 1.0 / 1000, 0.000001
+ end
+
+ def test_refute_in_delta_triggered
+ util_assert_triggered 'Expected 0.0 - 0.001 (0.001) to not be < 0.1.' do
+ @tc.refute_in_delta 0.0, 1.0 / 1000, 0.1
+ end
+ end
+
+ def test_refute_in_epsilon
+ @tc.refute_in_epsilon 10000, 9990
+ end
+
+ def test_refute_in_epsilon_triggered
+ util_assert_triggered 'Expected 10000 - 9991 (9) to not be < 10.0.' do
+ @tc.refute_in_epsilon 10000, 9991
+ fail
+ end
+ end
+
+ def test_refute_includes
+ @assertion_count = 2
+
+ @tc.refute_includes [true], false
+ end
+
+ def test_refute_includes_triggered
+ @assertion_count = 3
+
+ e = @tc.assert_raises MiniTest::Assertion do
+ @tc.refute_includes [true], true
+ end
+
+ expected = "Expected [true] to not include true."
+ assert_equal expected, e.message
+ end
+
+ def test_refute_instance_of
+ @tc.refute_instance_of Array, "blah"
+ end
+
+ def test_refute_instance_of_triggered
+ util_assert_triggered 'Expected "blah" to not be an instance of String.' do
+ @tc.refute_instance_of String, "blah"
+ end
+ end
+
+ def test_refute_kind_of
+ @tc.refute_kind_of Array, "blah"
+ end
+
+ def test_refute_kind_of_triggered
+ util_assert_triggered 'Expected "blah" to not be a kind of String.' do
+ @tc.refute_kind_of String, "blah"
+ end
+ end
+
+ def test_refute_match
+ @assertion_count = 2
+ @tc.refute_match(/\d+/, "blah blah blah")
+ end
+
+ def test_refute_match_object
+ @assertion_count = 2
+ @tc.refute_match Object.new, 5 # default #=~ returns false
+ end
+
+ def test_assert_object_triggered
+ @assertion_count = 2
+
+ pattern = Object.new
+ def pattern.=~(other) false end
+ def pattern.inspect; "<<Object>>" end
+
+ util_assert_triggered 'Expected <<Object>> to match 5.' do
+ @tc.assert_match pattern, 5
+ end
+ end
+
+ def test_refute_match_object_triggered
+ @assertion_count = 2
+
+ pattern = Object.new
+ def pattern.=~(other) true end
+ def pattern.inspect; "<<Object>>" end
+
+ util_assert_triggered 'Expected <<Object>> to not match 5.' do
+ @tc.refute_match pattern, 5
+ end
+ end
+
+ def test_refute_match_triggered
+ @assertion_count = 2
+ util_assert_triggered 'Expected /\w+/ to not match "blah blah blah".' do
+ @tc.refute_match(/\w+/, "blah blah blah")
+ end
+ end
+
+ def test_refute_nil
+ @tc.refute_nil 42
+ end
+
+ def test_refute_nil_triggered
+ util_assert_triggered 'Expected nil to not be nil.' do
+ @tc.refute_nil nil
+ end
+ end
+
+ def test_refute_operator
+ @tc.refute_operator 2, :<, 1
+ end
+
+ def test_refute_operator_triggered
+ util_assert_triggered "Expected 2 to not be > 1." do
+ @tc.refute_operator 2, :>, 1
+ end
+ end
+
+ def test_refute_respond_to
+ @tc.refute_respond_to "blah", :rawr!
+ end
+
+ def test_refute_respond_to_triggered
+ util_assert_triggered 'Expected "blah" to not respond to empty?.' do
+ @tc.refute_respond_to "blah", :empty?
+ end
+ end
+
+ def test_refute_same
+ @tc.refute_same 1, 2
+ end
+
+ def test_refute_same_triggered
+ util_assert_triggered 'Expected 1 (oid=N) to not be the same as 1 (oid=N).' do
+ @tc.refute_same 1, 1
+ end
+ end
+
+ def test_skip
+ @assertion_count = 0
+
+ util_assert_triggered "haha!", MiniTest::Skip do
+ @tc.skip "haha!"
+ end
+ end
+
+ def util_assert_triggered expected, klass = MiniTest::Assertion
+ e = assert_raises(klass) do
+ yield
+ end
+
+ msg = e.message.sub(/(---Backtrace---).*/m, '\1')
+ msg.gsub!(/\(oid=[-0-9]+\)/, '(oid=N)')
+
+ assert_equal expected, msg
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/mkmf/base.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/mkmf/base.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/mkmf/base.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,34 @@
+require 'test/unit'
+require 'mkmf'
+require 'tmpdir'
+
+$extout = '$(topdir)/'+RbConfig::CONFIG["EXTOUT"]
+RbConfig::CONFIG['topdir'] = CONFIG['topdir'] = File.expand_path(CONFIG['topdir'])
+RbConfig::CONFIG["extout"] = CONFIG["extout"] = $extout
+$INCFLAGS << " -I."
+$extout_prefix = "$(extout)$(target_prefix)/"
+
+class TestMkmf < Test::Unit::TestCase
+ def setup
+ @tmpdir = Dir.mktmpdir
+ @curdir = Dir.pwd
+ @mkmfobj = Object.new
+ Dir.chdir(@tmpdir)
+ class << (@output = "")
+ def flush; end
+ def reopen(*) end
+ alias write <<
+ end
+ $stdout = @output
+ end
+
+ def teardown
+ $stdout = STDOUT
+ Dir.chdir(@curdir)
+ FileUtils.rm_rf(@tmpdir)
+ end
+
+ def mkmf(*args, &block)
+ @mkmfobj.instance_eval(*args, &block)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/mkmf/test_find_executable.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/mkmf/test_find_executable.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/mkmf/test_find_executable.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,36 @@
+require_relative 'base'
+
+class TestMkmf
+ class TestFindExecutable < TestMkmf
+ class F
+ def do_find_executable(name)
+ find_executable(name)
+ end
+ end
+
+ def test_find_executable
+ bug2669 = '[ruby-core:27912]'
+ path, ENV["PATH"] = ENV["PATH"], path
+ ENV["PATH"] = @tmpdir
+ f = F.new
+ name = "foobar#{$$}#{rand(1000)}"
+ if /mswin\d|mingw|cygwin/ =~ RUBY_PLATFORM
+ exts = %w[.exe .com .cmd .bat]
+ else
+ exts = [""]
+ end
+ exts.each do |ext|
+ full = name+ext
+ begin
+ open(full, "w") {|ff| ff.chmod(0755)}
+ result = f.do_find_executable(name)
+ ensure
+ File.unlink(full)
+ end
+ assert_equal("#{@tmpdir}/#{name}#{ext}", result, bug2669)
+ end
+ ensure
+ ENV["PATH"] = path
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/mkmf/test_sizeof.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/mkmf/test_sizeof.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/mkmf/test_sizeof.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,12 @@
+require_relative 'base'
+
+class TestMkmf
+ class TestSizeof < TestMkmf
+ def test_sizeof
+ open("confdefs.h", "w") {|f|
+ f.puts "typedef struct {char x;} test1_t;"
+ }
+ assert_equal(1, mkmf {size = check_sizeof("test1_t", "confdefs.h")})
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/monitor/test_monitor.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/monitor/test_monitor.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/monitor/test_monitor.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,190 @@
+require "monitor"
+require "thread"
+
+require "test/unit"
+
+class TestMonitor < Test::Unit::TestCase
+ def setup
+ @monitor = Monitor.new
+ end
+
+ def test_enter
+ ary = []
+ queue = Queue.new
+ th = Thread.start {
+ queue.pop
+ @monitor.enter
+ for i in 6 .. 10
+ ary.push(i)
+ Thread.pass
+ end
+ @monitor.exit
+ }
+ @monitor.enter
+ queue.enq(nil)
+ for i in 1 .. 5
+ ary.push(i)
+ Thread.pass
+ end
+ @monitor.exit
+ th.join
+ assert_equal((1..10).to_a, ary)
+ end
+
+ def test_synchronize
+ ary = []
+ queue = Queue.new
+ th = Thread.start {
+ queue.pop
+ @monitor.synchronize do
+ for i in 6 .. 10
+ ary.push(i)
+ Thread.pass
+ end
+ end
+ }
+ @monitor.synchronize do
+ queue.enq(nil)
+ for i in 1 .. 5
+ ary.push(i)
+ Thread.pass
+ end
+ end
+ th.join
+ assert_equal((1..10).to_a, ary)
+ end
+
+ def test_killed_thread_in_synchronize
+ ary = []
+ queue = Queue.new
+ t1 = Thread.start {
+ queue.pop
+ @monitor.synchronize {
+ ary << :t1
+ }
+ }
+ t2 = Thread.start {
+ queue.pop
+ @monitor.synchronize {
+ ary << :t2
+ }
+ }
+ @monitor.synchronize do
+ queue.enq(nil)
+ queue.enq(nil)
+ assert_equal([], ary)
+ t1.kill
+ t2.kill
+ ary << :main
+ end
+ assert_equal([:main], ary)
+ end
+
+ def test_try_enter
+ queue1 = Queue.new
+ queue2 = Queue.new
+ th = Thread.start {
+ queue1.deq
+ @monitor.enter
+ queue2.enq(nil)
+ queue1.deq
+ @monitor.exit
+ queue2.enq(nil)
+ }
+ assert_equal(true, @monitor.try_enter)
+ @monitor.exit
+ queue1.enq(nil)
+ queue2.deq
+ assert_equal(false, @monitor.try_enter)
+ queue1.enq(nil)
+ queue2.deq
+ assert_equal(true, @monitor.try_enter)
+ end
+
+ def test_cond
+ cond = @monitor.new_cond
+
+ a = "foo"
+ queue1 = Queue.new
+ Thread.start do
+ queue1.deq
+ @monitor.synchronize do
+ a = "bar"
+ cond.signal
+ end
+ end
+ @monitor.synchronize do
+ queue1.enq(nil)
+ assert_equal("foo", a)
+ result1 = cond.wait
+ assert_equal(true, result1)
+ assert_equal("bar", a)
+ end
+ end
+
+ def test_timedwait
+ cond = @monitor.new_cond
+ b = "foo"
+ queue2 = Queue.new
+ Thread.start do
+ queue2.deq
+ @monitor.synchronize do
+ b = "bar"
+ cond.signal
+ end
+ end
+ @monitor.synchronize do
+ queue2.enq(nil)
+ assert_equal("foo", b)
+ result2 = cond.wait(0.1)
+ assert_equal(true, result2)
+ assert_equal("bar", b)
+ end
+
+ c = "foo"
+ queue3 = Queue.new
+ Thread.start do
+ queue3.deq
+ @monitor.synchronize do
+ c = "bar"
+ cond.signal
+ end
+ end
+ @monitor.synchronize do
+ assert_equal("foo", c)
+ result3 = cond.wait(0.1)
+ assert_equal(true, result3) # wait always returns true in Ruby 1.9
+ assert_equal("foo", c)
+ queue3.enq(nil)
+ result4 = cond.wait
+ assert_equal(true, result4)
+ assert_equal("bar", c)
+ end
+
+# d = "foo"
+# cumber_thread = Thread.start {
+# loop do
+# @monitor.synchronize do
+# d = "foo"
+# end
+# end
+# }
+# queue3 = Queue.new
+# Thread.start do
+# queue3.pop
+# @monitor.synchronize do
+# d = "bar"
+# cond.signal
+# end
+# end
+# @monitor.synchronize do
+# queue3.enq(nil)
+# assert_equal("foo", d)
+# result5 = cond.wait
+# assert_equal(true, result5)
+# # this thread has priority over cumber_thread
+# assert_equal("bar", d)
+# end
+# cumber_thread.kill
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/net/http/test_http.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/net/http/test_http.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/net/http/test_http.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,374 @@
+# $Id: test_http.rb 27605 2010-05-03 23:42:26Z mame $
+
+require 'test/unit'
+require 'net/http'
+require 'stringio'
+require File.expand_path("utils", File.dirname(__FILE__))
+
+module TestNetHTTP_version_1_1_methods
+
+ def test_s_get
+ assert_equal $test_net_http_data,
+ Net::HTTP.get(config('host'), '/', config('port'))
+ end
+
+ def test_head
+ start {|http|
+ res = http.head('/')
+ assert_kind_of Net::HTTPResponse, res
+ assert_equal $test_net_http_data_type, res['Content-Type']
+ unless self.is_a?(TestNetHTTP_v1_2_chunked)
+ assert_equal $test_net_http_data.size, res['Content-Length'].to_i
+ end
+ }
+ end
+
+ def test_get
+ start {|http|
+ _test_get__get http
+ _test_get__iter http
+ _test_get__chunked http
+ }
+ end
+
+ def _test_get__get(http)
+ res, body = http.get('/')
+ assert_kind_of Net::HTTPResponse, res
+ assert_kind_of String, res.body
+ assert_kind_of String, body
+ unless self.is_a?(TestNetHTTP_v1_2_chunked)
+ assert_not_nil res['content-length']
+ assert_equal $test_net_http_data.size, res['content-length'].to_i
+ end
+ assert_equal $test_net_http_data_type, res['Content-Type']
+ assert_equal $test_net_http_data.size, body.size
+ assert_equal $test_net_http_data, body
+ assert_equal $test_net_http_data.size, res.body.size
+ assert_equal $test_net_http_data, res.body
+ end
+
+ def _test_get__iter(http)
+ buf = ''
+ res, body = http.get('/') {|s| buf << s }
+ assert_kind_of Net::HTTPResponse, res
+ # assert_kind_of String, res.body
+ # assert_kind_of String, body
+ unless self.is_a?(TestNetHTTP_v1_2_chunked)
+ assert_not_nil res['content-length']
+ assert_equal $test_net_http_data.size, res['content-length'].to_i
+ end
+ assert_equal $test_net_http_data_type, res['Content-Type']
+ assert_equal $test_net_http_data.size, buf.size
+ assert_equal $test_net_http_data, buf
+ # assert_equal $test_net_http_data.size, res.body.size
+ # assert_equal $test_net_http_data, res.body
+ end
+
+ def _test_get__chunked(http)
+ buf = ''
+ res, body = http.get('/') {|s| buf << s }
+ assert_kind_of Net::HTTPResponse, res
+ # assert_kind_of String, res.body
+ # assert_kind_of String, body
+ unless self.is_a?(TestNetHTTP_v1_2_chunked)
+ assert_not_nil res['content-length']
+ assert_equal $test_net_http_data.size, res['content-length'].to_i
+ end
+ assert_equal $test_net_http_data_type, res['Content-Type']
+ assert_equal $test_net_http_data.size, buf.size
+ assert_equal $test_net_http_data, buf
+ # assert_equal $test_net_http_data.size, res.body.size
+ # assert_equal $test_net_http_data, res.body
+ end
+
+ def test_get__break
+ i = 0
+ start {|http|
+ http.get('/') do |str|
+ i += 1
+ break
+ end
+ }
+ assert_equal 1, i
+ end
+
+ def test_get__implicit_start
+ res, body = new().get('/')
+ assert_kind_of Net::HTTPResponse, res
+ assert_kind_of String, body
+ assert_kind_of String, res.body
+ unless self.is_a?(TestNetHTTP_v1_2_chunked)
+ assert_not_nil res['content-length']
+ end
+ assert_equal $test_net_http_data_type, res['Content-Type']
+ assert_equal $test_net_http_data.size, res.body.size
+ assert_equal $test_net_http_data, res.body
+ end
+
+ def test_get2
+ start {|http|
+ http.get2('/') {|res|
+ assert_kind_of Net::HTTPResponse, res
+ assert_kind_of Net::HTTPResponse, res.header
+ unless self.is_a?(TestNetHTTP_v1_2_chunked)
+ assert_not_nil res['content-length']
+ end
+ assert_equal $test_net_http_data_type, res['Content-Type']
+ assert_kind_of String, res.body
+ assert_kind_of String, res.entity
+ assert_equal $test_net_http_data.size, res.body.size
+ assert_equal $test_net_http_data, res.body
+ assert_equal $test_net_http_data, res.entity
+ }
+ }
+ end
+
+ def test_post
+ start {|http|
+ _test_post__base http
+ _test_post__file http
+ }
+ end
+
+ def _test_post__base(http)
+ uheader = {}
+ uheader['Accept'] = 'application/octet-stream'
+ data = 'post data'
+ res, body = http.post('/', data)
+ assert_kind_of Net::HTTPResponse, res
+ assert_kind_of String, body
+ assert_kind_of String, res.body
+ assert_equal data, body
+ assert_equal data, res.body
+ assert_equal data, res.entity
+ end
+
+ def _test_post__file(http)
+ data = 'post data'
+ f = StringIO.new
+ http.post('/', data, nil, f)
+ assert_equal data, f.string
+ end
+
+ def test_s_post_form
+ res = Net::HTTP.post_form(
+ URI.parse("http://#{config('host')}:#{config('port')}/"),
+ "a" => "x")
+ assert_equal ["a=x"], res.body.split(/[;&]/).sort
+
+ res = Net::HTTP.post_form(
+ URI.parse("http://#{config('host')}:#{config('port')}/"),
+ "a" => "x",
+ "b" => "y")
+ assert_equal ["a=x", "b=y"], res.body.split(/[;&]/).sort
+
+ res = Net::HTTP.post_form(
+ URI.parse("http://#{config('host')}:#{config('port')}/"),
+ "a" => ["x1", "x2"],
+ "b" => "y")
+ assert_equal ["a=x1", "a=x2", "b=y"], res.body.split(/[;&]/).sort
+ end
+
+end
+
+
+module TestNetHTTP_version_1_2_methods
+
+ def test_request
+ start {|http|
+ _test_request__GET http
+ _test_request__file http
+ # _test_request__range http # WEBrick does not support Range: header.
+ _test_request__HEAD http
+ _test_request__POST http
+ _test_request__stream_body http
+ }
+ end
+
+ def _test_request__GET(http)
+ req = Net::HTTP::Get.new('/')
+ http.request(req) {|res|
+ assert_kind_of Net::HTTPResponse, res
+ assert_kind_of String, res.body
+ unless self.is_a?(TestNetHTTP_v1_2_chunked)
+ assert_not_nil res['content-length']
+ assert_equal $test_net_http_data.size, res['content-length'].to_i
+ end
+ assert_equal $test_net_http_data.size, res.body.size
+ assert_equal $test_net_http_data, res.body
+ }
+ end
+
+ def _test_request__file(http)
+ req = Net::HTTP::Get.new('/')
+ http.request(req) {|res|
+ assert_kind_of Net::HTTPResponse, res
+ unless self.is_a?(TestNetHTTP_v1_2_chunked)
+ assert_not_nil res['content-length']
+ assert_equal $test_net_http_data.size, res['content-length'].to_i
+ end
+ f = StringIO.new("".force_encoding("ASCII-8BIT"))
+ res.read_body f
+ assert_equal $test_net_http_data.bytesize, f.string.bytesize
+ assert_equal $test_net_http_data.encoding, f.string.encoding
+ assert_equal $test_net_http_data, f.string
+ }
+ end
+
+ def _test_request__range(http)
+ req = Net::HTTP::Get.new('/')
+ req['range'] = 'bytes=0-5'
+ assert_equal $test_net_http_data[0,6], http.request(req).body
+ end
+
+ def _test_request__HEAD(http)
+ req = Net::HTTP::Head.new('/')
+ http.request(req) {|res|
+ assert_kind_of Net::HTTPResponse, res
+ unless self.is_a?(TestNetHTTP_v1_2_chunked)
+ assert_not_nil res['content-length']
+ assert_equal $test_net_http_data.size, res['content-length'].to_i
+ end
+ assert_nil res.body
+ }
+ end
+
+ def _test_request__POST(http)
+ data = 'post data'
+ req = Net::HTTP::Post.new('/')
+ req['Accept'] = $test_net_http_data_type
+ http.request(req, data) {|res|
+ assert_kind_of Net::HTTPResponse, res
+ unless self.is_a?(TestNetHTTP_v1_2_chunked)
+ assert_equal data.size, res['content-length'].to_i
+ end
+ assert_kind_of String, res.body
+ assert_equal data, res.body
+ }
+ end
+
+ def _test_request__stream_body(http)
+ req = Net::HTTP::Post.new('/')
+ data = $test_net_http_data
+ req.content_length = data.size
+ req.body_stream = StringIO.new(data)
+ res = http.request(req)
+ assert_kind_of Net::HTTPResponse, res
+ assert_kind_of String, res.body
+ assert_equal data.size, res.body.size
+ assert_equal data, res.body
+ end
+
+ def test_send_request
+ start {|http|
+ _test_send_request__GET http
+ _test_send_request__POST http
+ }
+ end
+
+ def _test_send_request__GET(http)
+ res = http.send_request('GET', '/')
+ assert_kind_of Net::HTTPResponse, res
+ unless self.is_a?(TestNetHTTP_v1_2_chunked)
+ assert_equal $test_net_http_data.size, res['content-length'].to_i
+ end
+ assert_kind_of String, res.body
+ assert_equal $test_net_http_data, res.body
+ end
+
+ def _test_send_request__POST(http)
+ data = 'aaabbb cc ddddddddddd lkjoiu4j3qlkuoa'
+ res = http.send_request('POST', '/', data)
+ assert_kind_of Net::HTTPResponse, res
+ assert_kind_of String, res.body
+ assert_equal data.size, res.body.size
+ assert_equal data, res.body
+ end
+end
+
+class TestNetHTTP_version_1_1 < Test::Unit::TestCase
+ CONFIG = {
+ 'host' => '127.0.0.1',
+ 'port' => 10081,
+ 'proxy_host' => nil,
+ 'proxy_port' => nil,
+ }
+
+ include TestNetHTTPUtils
+ include TestNetHTTP_version_1_1_methods
+
+ def new
+ Net::HTTP.version_1_1
+ super
+ end
+end
+
+class TestNetHTTP_v1_2 < Test::Unit::TestCase
+ CONFIG = {
+ 'host' => '127.0.0.1',
+ 'port' => 10081,
+ 'proxy_host' => nil,
+ 'proxy_port' => nil,
+ }
+
+ include TestNetHTTPUtils
+ include TestNetHTTP_version_1_1_methods
+ include TestNetHTTP_version_1_2_methods
+
+ def new
+ Net::HTTP.version_1_2
+ super
+ end
+end
+
+class TestNetHTTP_v1_2_chunked < Test::Unit::TestCase
+ CONFIG = {
+ 'host' => '127.0.0.1',
+ 'port' => 10081,
+ 'proxy_host' => nil,
+ 'proxy_port' => nil,
+ 'chunked' => true,
+ }
+
+ include TestNetHTTPUtils
+ include TestNetHTTP_version_1_1_methods
+ include TestNetHTTP_version_1_2_methods
+
+ def new
+ Net::HTTP.version_1_2
+ super
+ end
+
+ def test_chunked_break
+ i = 0
+ assert_nothing_raised("[ruby-core:29229]") {
+ start {|http|
+ http.request_get('/') {|res|
+ res.read_body {|chunk|
+ break
+ }
+ }
+ }
+ }
+ end
+end
+
+=begin
+class TestNetHTTP_proxy < Test::Unit::TestCase
+ CONFIG = {
+ 'host' => '127.0.0.1',
+ 'port' => 10081,
+ 'proxy_host' => '127.0.0.1',
+ 'proxy_port' => 10082,
+ }
+
+ include TestNetHTTPUtils
+ include TestNetHTTP_version_1_1_methods
+ include TestNetHTTP_version_1_2_methods
+
+ def new
+ Net::HTTP.version_1_2
+ super
+ end
+end
+=end
Added: MacRuby/trunk/test/test-mri/test/net/http/test_httpheader.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/net/http/test_httpheader.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/net/http/test_httpheader.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,317 @@
+require 'net/http'
+require 'test/unit'
+
+class HTTPHeaderTest < Test::Unit::TestCase
+
+ class C
+ include Net::HTTPHeader
+ def initialize
+ initialize_http_header({})
+ end
+ attr_accessor :body
+ end
+
+ def setup
+ @c = C.new
+ end
+
+ def test_size
+ assert_equal 0, @c.size
+ @c['a'] = 'a'
+ assert_equal 1, @c.size
+ @c['b'] = 'b'
+ assert_equal 2, @c.size
+ @c['b'] = 'b'
+ assert_equal 2, @c.size
+ @c['c'] = 'c'
+ assert_equal 3, @c.size
+ end
+
+ def test_ASET
+ @c['My-Header'] = 'test string'
+ @c['my-Header'] = 'test string'
+ @c['My-header'] = 'test string'
+ @c['my-header'] = 'test string'
+ @c['MY-HEADER'] = 'test string'
+ assert_equal 1, @c.size
+
+ @c['AaA'] = 'aaa'
+ @c['aaA'] = 'aaa'
+ @c['AAa'] = 'aaa'
+ assert_equal 2, @c.length
+ end
+
+ def test_AREF
+ @c['My-Header'] = 'test string'
+ assert_equal 'test string', @c['my-header']
+ assert_equal 'test string', @c['MY-header']
+ assert_equal 'test string', @c['my-HEADER']
+
+ @c['Next-Header'] = 'next string'
+ assert_equal 'next string', @c['next-header']
+ end
+
+ def test_add_field
+ @c.add_field 'My-Header', 'a'
+ assert_equal 'a', @c['My-Header']
+ assert_equal ['a'], @c.get_fields('My-Header')
+ @c.add_field 'My-Header', 'b'
+ assert_equal 'a, b', @c['My-Header']
+ assert_equal ['a', 'b'], @c.get_fields('My-Header')
+ @c.add_field 'My-Header', 'c'
+ assert_equal 'a, b, c', @c['My-Header']
+ assert_equal ['a', 'b', 'c'], @c.get_fields('My-Header')
+ @c.add_field 'My-Header', 'd, d'
+ assert_equal 'a, b, c, d, d', @c['My-Header']
+ assert_equal ['a', 'b', 'c', 'd, d'], @c.get_fields('My-Header')
+ end
+
+ def test_get_fields
+ @c['My-Header'] = 'test string'
+ assert_equal ['test string'], @c.get_fields('my-header')
+ assert_equal ['test string'], @c.get_fields('My-header')
+ assert_equal ['test string'], @c.get_fields('my-Header')
+
+ assert_nil @c.get_fields('not-found')
+ assert_nil @c.get_fields('Not-Found')
+
+ @c.get_fields('my-header').push 'junk'
+ assert_equal ['test string'], @c.get_fields('my-header')
+ @c.get_fields('my-header').clear
+ assert_equal ['test string'], @c.get_fields('my-header')
+ end
+
+ def test_delete
+ @c['My-Header'] = 'test'
+ assert_equal 'test', @c['My-Header']
+ assert_nil @c['not-found']
+ @c.delete 'My-Header'
+ assert_nil @c['My-Header']
+ assert_nil @c['not-found']
+ @c.delete 'My-Header'
+ @c.delete 'My-Header'
+ assert_nil @c['My-Header']
+ assert_nil @c['not-found']
+ end
+
+ def test_each
+ @c['My-Header'] = 'test'
+ @c.each do |k, v|
+ assert_equal 'my-header', k
+ assert_equal 'test', v
+ end
+ @c.each do |k, v|
+ assert_equal 'my-header', k
+ assert_equal 'test', v
+ end
+ end
+
+ def test_each_key
+ @c['My-Header'] = 'test'
+ @c.each_key do |k|
+ assert_equal 'my-header', k
+ end
+ @c.each_key do |k|
+ assert_equal 'my-header', k
+ end
+ end
+
+ def test_each_value
+ @c['My-Header'] = 'test'
+ @c.each_value do |v|
+ assert_equal 'test', v
+ end
+ @c.each_value do |v|
+ assert_equal 'test', v
+ end
+ end
+
+ def test_canonical_each
+ @c['my-header'] = ['a', 'b']
+ @c.canonical_each do |k,v|
+ assert_equal 'My-Header', k
+ assert_equal 'a, b', v
+ end
+ end
+
+ def test_each_capitalized
+ @c['my-header'] = ['a', 'b']
+ @c.each_capitalized do |k,v|
+ assert_equal 'My-Header', k
+ assert_equal 'a, b', v
+ end
+ end
+
+ def test_key?
+ @c['My-Header'] = 'test'
+ assert_equal true, @c.key?('My-Header')
+ assert_equal true, @c.key?('my-header')
+ assert_equal false, @c.key?('Not-Found')
+ assert_equal false, @c.key?('not-found')
+ assert_equal false, @c.key?('')
+ assert_equal false, @c.key?('x' * 1024)
+ end
+
+ def test_to_hash
+ end
+
+ def test_range
+ try_range(1..5, '1-5')
+ try_range(234..567, '234-567')
+ try_range(-5..-1, '-5')
+ try_range(1..-1, '1-')
+ end
+
+ def try_range(r, s)
+ @c['range'] = "bytes=#{s}"
+ assert_equal r, Array(@c.range)[0]
+ end
+
+ def test_range=
+ @c.range = 0..499
+ assert_equal 'bytes=0-499', @c['range']
+ @c.range = 0...500
+ assert_equal 'bytes=0-499', @c['range']
+ @c.range = 300
+ assert_equal 'bytes=0-299', @c['range']
+ @c.range = -400
+ assert_equal 'bytes=-400', @c['range']
+ @c.set_range 0, 500
+ assert_equal 'bytes=0-499', @c['range']
+ end
+
+ def test_content_range
+ end
+
+ def test_range_length
+ @c['Content-Range'] = "bytes 0-499/1000"
+ assert_equal 500, @c.range_length
+ @c['Content-Range'] = "bytes 1-500/1000"
+ assert_equal 500, @c.range_length
+ @c['Content-Range'] = "bytes 1-1/1000"
+ assert_equal 1, @c.range_length
+ end
+
+ def test_chunked?
+ try_chunked true, 'chunked'
+ try_chunked true, ' chunked '
+ try_chunked true, '(OK)chunked'
+
+ try_chunked false, 'not-chunked'
+ try_chunked false, 'chunked-but-not-chunked'
+ end
+
+ def try_chunked(bool, str)
+ @c['transfer-encoding'] = str
+ assert_equal bool, @c.chunked?
+ end
+
+ def test_content_length
+ @c.delete('content-length')
+ assert_nil @c['content-length']
+
+ try_content_length 500, '500'
+ try_content_length 10000_0000_0000, '1000000000000'
+ try_content_length 123, ' 123'
+ try_content_length 1, '1 23'
+ try_content_length 500, '(OK)500'
+ assert_raise(Net::HTTPHeaderSyntaxError, 'here is no digit, but') {
+ @c['content-length'] = 'no digit'
+ @c.content_length
+ }
+ end
+
+ def try_content_length(len, str)
+ @c['content-length'] = str
+ assert_equal len, @c.content_length
+ end
+
+ def test_content_length=
+ @c.content_length = 0
+ assert_equal 0, @c.content_length
+ @c.content_length = 1
+ assert_equal 1, @c.content_length
+ @c.content_length = 999
+ assert_equal 999, @c.content_length
+ @c.content_length = 10000000000000
+ assert_equal 10000000000000, @c.content_length
+ end
+
+ def test_content_type
+ assert_nil @c.content_type
+ @c.content_type = 'text/html'
+ assert_equal 'text/html', @c.content_type
+ @c.content_type = 'application/pdf'
+ assert_equal 'application/pdf', @c.content_type
+ @c.set_content_type 'text/html', {'charset' => 'iso-2022-jp'}
+ assert_equal 'text/html', @c.content_type
+ @c.content_type = 'text'
+ assert_equal 'text', @c.content_type
+ end
+
+ def test_main_type
+ assert_nil @c.main_type
+ @c.content_type = 'text/html'
+ assert_equal 'text', @c.main_type
+ @c.content_type = 'application/pdf'
+ assert_equal 'application', @c.main_type
+ @c.set_content_type 'text/html', {'charset' => 'iso-2022-jp'}
+ assert_equal 'text', @c.main_type
+ @c.content_type = 'text'
+ assert_equal 'text', @c.main_type
+ end
+
+ def test_sub_type
+ assert_nil @c.sub_type
+ @c.content_type = 'text/html'
+ assert_equal 'html', @c.sub_type
+ @c.content_type = 'application/pdf'
+ assert_equal 'pdf', @c.sub_type
+ @c.set_content_type 'text/html', {'charset' => 'iso-2022-jp'}
+ assert_equal 'html', @c.sub_type
+ @c.content_type = 'text'
+ assert_nil @c.sub_type
+ end
+
+ def test_type_params
+ assert_equal({}, @c.type_params)
+ @c.content_type = 'text/html'
+ assert_equal({}, @c.type_params)
+ @c.content_type = 'application/pdf'
+ assert_equal({}, @c.type_params)
+ @c.set_content_type 'text/html', {'charset' => 'iso-2022-jp'}
+ assert_equal({'charset' => 'iso-2022-jp'}, @c.type_params)
+ @c.content_type = 'text'
+ assert_equal({}, @c.type_params)
+ end
+
+ def test_set_content_type
+ end
+
+ def test_form_data=
+ @c.form_data = {"cmd"=>"search", "q"=>"ruby", "max"=>"50"}
+ assert_equal 'application/x-www-form-urlencoded', @c.content_type
+ assert_equal %w( cmd=search max=50 q=ruby ), @c.body.split('&').sort
+ end
+
+ def test_set_form_data
+ @c.set_form_data "cmd"=>"search", "q"=>"ruby", "max"=>"50"
+ assert_equal 'application/x-www-form-urlencoded', @c.content_type
+ assert_equal %w( cmd=search max=50 q=ruby ), @c.body.split('&').sort
+
+ @c.set_form_data "cmd"=>"search", "q"=>"ruby", "max"=>50
+ assert_equal 'application/x-www-form-urlencoded', @c.content_type
+ assert_equal %w( cmd=search max=50 q=ruby ), @c.body.split('&').sort
+
+ @c.set_form_data({"cmd"=>"search", "q"=>"ruby", "max"=>"50"}, ';')
+ assert_equal 'application/x-www-form-urlencoded', @c.content_type
+ assert_equal %w( cmd=search max=50 q=ruby ), @c.body.split(';').sort
+ end
+
+ def test_basic_auth
+ end
+
+ def test_proxy_basic_auth
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/net/http/test_httpresponse.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/net/http/test_httpresponse.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/net/http/test_httpresponse.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,40 @@
+require 'net/http'
+require 'test/unit'
+require 'stringio'
+
+class HTTPResponseTest < Test::Unit::TestCase
+ def test_singleline_header
+ io = dummy_io(<<EOS.gsub(/\n/, "\r\n"))
+HTTP/1.1 200 OK
+Content-Length: 5
+Connection: close
+
+hello
+EOS
+ res = Net::HTTPResponse.read_new(io)
+ assert_equal('5', res.header['content-length'])
+ assert_equal('close', res.header['connection'])
+ end
+
+ def test_multiline_header
+ io = dummy_io(<<EOS.gsub(/\n/, "\r\n"))
+HTTP/1.1 200 OK
+X-Foo: XXX
+ YYY
+X-Bar:
+ XXX
+\tYYY
+
+hello
+EOS
+ res = Net::HTTPResponse.read_new(io)
+ assert_equal('XXX YYY', res.header['x-foo'])
+ assert_equal('XXX YYY', res.header['x-bar'])
+ end
+
+private
+
+ def dummy_io(str)
+ Net::BufferedIO.new(StringIO.new(str))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/net/http/test_https.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/net/http/test_https.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/net/http/test_https.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,97 @@
+require "test/unit"
+begin
+ require 'net/https'
+ require 'stringio'
+ require File.expand_path("../../openssl/utils", File.dirname(__FILE__))
+ require File.expand_path("utils", File.dirname(__FILE__))
+rescue LoadError
+ # should skip this test
+end
+
+class TestNetHTTPS < Test::Unit::TestCase
+ include TestNetHTTPUtils
+
+ subject = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
+ exts = [
+ ["keyUsage", "keyEncipherment,digitalSignature", true],
+ ]
+ key = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ cert = OpenSSL::TestUtils.issue_cert(
+ subject, key, 1, Time.now, Time.now + 3600, exts,
+ nil, nil, OpenSSL::Digest::SHA1.new
+ )
+
+ CONFIG = {
+ 'host' => '127.0.0.1',
+ 'port' => 10081,
+ 'proxy_host' => nil,
+ 'proxy_port' => nil,
+ 'ssl_enable' => true,
+ 'ssl_certificate' => cert,
+ 'ssl_private_key' => key,
+ }
+
+ def test_get
+ http = Net::HTTP.new("localhost", config("port"))
+ http.use_ssl = true
+ http.verify_callback = Proc.new do |preverify_ok, store_ctx|
+ store_ctx.current_cert.to_der == config('ssl_certificate').to_der
+ end
+ http.request_get("/") {|res|
+ assert_equal($test_net_http_data, res.body)
+ }
+ end
+
+ def test_post
+ http = Net::HTTP.new("localhost", config("port"))
+ http.use_ssl = true
+ http.verify_callback = Proc.new do |preverify_ok, store_ctx|
+ store_ctx.current_cert.to_der == config('ssl_certificate').to_der
+ end
+ data = config('ssl_private_key').to_der
+ http.request_post("/", data) {|res|
+ assert_equal(data, res.body)
+ }
+ end
+
+ if ENV["RUBY_OPENSSL_TEST_ALL"]
+ def test_verify
+ http = Net::HTTP.new("ssl.netlab.jp", 443)
+ http.use_ssl = true
+ assert(
+ (http.request_head("/"){|res| } rescue false),
+ "The system may not have default CA certificate store."
+ )
+ end
+ end
+
+ def test_verify_none
+ http = Net::HTTP.new("localhost", config("port"))
+ http.use_ssl = true
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ http.request_get("/") {|res|
+ assert_equal($test_net_http_data, res.body)
+ }
+ end
+
+ def test_certificate_verify_failure
+ http = Net::HTTP.new("localhost", config("port"))
+ http.use_ssl = true
+ ex = assert_raise(OpenSSL::SSL::SSLError){
+ http.request_get("/") {|res| }
+ }
+ assert_match(/certificate verify failed/, ex.message)
+ end
+
+ def test_identity_verify_failure
+ http = Net::HTTP.new("127.0.0.1", config("port"))
+ http.use_ssl = true
+ http.verify_callback = Proc.new do |preverify_ok, store_ctx|
+ store_ctx.current_cert.to_der == config('ssl_certificate').to_der
+ end
+ ex = assert_raise(OpenSSL::SSL::SSLError){
+ http.request_get("/") {|res| }
+ }
+ assert_match(/hostname was not match/, ex.message)
+ end
+end if defined?(OpenSSL)
Added: MacRuby/trunk/test/test-mri/test/net/http/test_https_proxy.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/net/http/test_https_proxy.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/net/http/test_https_proxy.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,37 @@
+begin
+ require 'net/https'
+rescue LoadError
+end
+require 'test/unit'
+
+class HTTPSProxyTest < Test::Unit::TestCase
+ def test_https_proxy_authentication
+ t = nil
+ TCPServer.open("127.0.0.1", 0) {|serv|
+ _, port, _, _ = serv.addr
+ t = Thread.new {
+ proxy = Net::HTTP.Proxy("127.0.0.1", port, 'user', 'password')
+ http = proxy.new("foo.example.org", 8000)
+ http.use_ssl = true
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ begin
+ http.start
+ rescue EOFError
+ end
+ }
+ sock = serv.accept
+ proxy_request = sock.gets("\r\n\r\n")
+ assert_equal(
+ "CONNECT foo.example.org:8000 HTTP/1.1\r\n" +
+ "Host: foo.example.org:8000\r\n" +
+ "Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA==\r\n" +
+ "\r\n",
+ proxy_request,
+ "[ruby-dev:25673]")
+ sock.close
+ }
+ ensure
+ t.join if t
+ end
+end if defined?(OpenSSL)
+
Added: MacRuby/trunk/test/test-mri/test/net/http/utils.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/net/http/utils.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/net/http/utils.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,104 @@
+require 'webrick'
+begin
+ require "webrick/https"
+rescue LoadError
+ # SSL features cannot be tested
+end
+require 'webrick/httpservlet/abstract'
+
+module TestNetHTTPUtils
+ def start(&block)
+ new().start(&block)
+ end
+
+ def new
+ klass = Net::HTTP::Proxy(config('proxy_host'), config('proxy_port'))
+ http = klass.new(config('host'), config('port'))
+ http.set_debug_output logfile()
+ http
+ end
+
+ def config(key)
+ self.class::CONFIG[key]
+ end
+
+ def logfile
+ $DEBUG ? $stderr : NullWriter.new
+ end
+
+ def setup
+ spawn_server
+ end
+
+ def teardown
+ @server.shutdown
+ until @server.status == :Stop
+ sleep 0.1
+ end
+ # resume global state
+ Net::HTTP.version_1_2
+ end
+
+ def spawn_server
+ server_config = {
+ :BindAddress => config('host'),
+ :Port => config('port'),
+ :Logger => WEBrick::Log.new(NullWriter.new),
+ :AccessLog => [],
+ :ShutdownSocketWithoutClose => true,
+ :ServerType => Thread,
+ }
+ server_config[:OutputBufferSize] = 4 if config('chunked')
+ if defined?(OpenSSL) and config('ssl_enable')
+ server_config.update({
+ :SSLEnable => true,
+ :SSLCertificate => config('ssl_certificate'),
+ :SSLPrivateKey => config('ssl_private_key'),
+ })
+ end
+ @server = WEBrick::HTTPServer.new(server_config)
+ @server.mount('/', Servlet, config('chunked'))
+ @server.start
+ n_try_max = 5
+ begin
+ TCPSocket.open(config('host'), config('port')).close
+ rescue Errno::ECONNREFUSED
+ sleep 0.2
+ n_try_max -= 1
+ raise 'cannot spawn server; give up' if n_try_max < 0
+ retry
+ end
+ end
+
+ $test_net_http = nil
+# Comment out because Encoding::CompatibilityError occurs.
+# $test_net_http_data = (0...256).to_a.map {|i| i.chr }.join('') * 64
+# $test_net_http_data.force_encoding("ASCII-8BIT")
+ $test_net_http_data_type = 'application/octet-stream'
+
+ class Servlet < WEBrick::HTTPServlet::AbstractServlet
+ def initialize(this, chunked = false)
+ @chunked = chunked
+ end
+
+ def do_GET(req, res)
+ res['Content-Type'] = $test_net_http_data_type
+ res.body = $test_net_http_data
+ res.chunked = @chunked
+ end
+
+ # echo server
+ def do_POST(req, res)
+ res['Content-Type'] = req['Content-Type']
+ res.body = req.body
+ res.chunked = @chunked
+ end
+ end
+
+ class NullWriter
+ def <<(s) end
+ def puts(*args) end
+ def print(*args) end
+ def printf(*args) end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/net/imap/cacert.pem
===================================================================
--- MacRuby/trunk/test/test-mri/test/net/imap/cacert.pem (rev 0)
+++ MacRuby/trunk/test/test-mri/test/net/imap/cacert.pem 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,62 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ d2:9c:5c:81:a3:b0:3b:ec
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=JP, ST=Shimane, O=Ruby Core Team, CN=Ruby Test CA
+ Validity
+ Not Before: Dec 22 08:35:19 2007 GMT
+ Not After : Dec 21 08:35:19 2010 GMT
+ Subject: C=JP, ST=Shimane, O=Ruby Core Team, CN=Ruby Test CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:ee:b1:1a:06:25:1f:29:80:a1:59:ef:0f:0d:8b:
+ 5a:88:40:73:56:95:d9:db:b4:71:3c:36:7f:b4:fc:
+ 68:51:54:8b:8d:9e:41:27:fb:31:d1:7a:6c:5c:21:
+ 30:3d:22:f6:7a:92:c3:fa:b3:85:36:44:76:22:6c:
+ 08:82:78:89:7d:c3:19:d4:ec:7d:05:5b:75:cd:38:
+ 1c:89:03:ef:02:aa:7e:6d:5b:36:ea:ad:e2:0b:ec:
+ 4b:e2:36:bf:c0:49:44:93:a6:cc:da:40:be:5f:c0:
+ 75:3b:be:c0:28:db:42:57:90:3b:83:af:2d:60:9a:
+ c6:b1:bc:5c:68:12:2d:70:25
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ AE:F5:39:FE:D2:35:A2:2C:1E:CB:0E:08:4C:0E:5A:DC:44:99:E2:9C
+ X509v3 Authority Key Identifier:
+ keyid:AE:F5:39:FE:D2:35:A2:2C:1E:CB:0E:08:4C:0E:5A:DC:44:99:E2:9C
+ DirName:/C=JP/ST=Shimane/O=Ruby Core Team/CN=Ruby Test CA
+ serial:D2:9C:5C:81:A3:B0:3B:EC
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: sha1WithRSAEncryption
+ 9e:28:89:81:83:55:1b:38:cb:85:86:ec:ee:cc:f4:cf:f0:47:
+ 61:72:07:f2:2e:ca:67:f7:c8:29:b5:3c:34:d2:cf:c2:f7:9c:
+ 4d:ce:8d:37:24:57:85:c1:0e:27:86:81:15:99:ec:af:05:ae:
+ 09:96:f6:f7:5a:c0:d2:a4:82:ed:d6:d3:26:e9:3d:50:50:0c:
+ 71:c2:6e:9a:50:30:73:8a:94:0d:c1:9c:1a:da:76:80:b8:8b:
+ 46:ec:10:93:6c:8d:cb:ab:eb:12:5d:e0:6f:1a:5a:ac:5c:34:
+ 12:df:7b:a7:dc:b6:0f:d6:3e:ac:2f:69:db:11:aa:1d:c4:90:
+ f6:fa
+-----BEGIN CERTIFICATE-----
+MIICzjCCAjegAwIBAgIJANKcXIGjsDvsMA0GCSqGSIb3DQEBBQUAME8xCzAJBgNV
+BAYTAkpQMRAwDgYDVQQIEwdTaGltYW5lMRcwFQYDVQQKEw5SdWJ5IENvcmUgVGVh
+bTEVMBMGA1UEAxMMUnVieSBUZXN0IENBMB4XDTA3MTIyMjA4MzUxOVoXDTEwMTIy
+MTA4MzUxOVowTzELMAkGA1UEBhMCSlAxEDAOBgNVBAgTB1NoaW1hbmUxFzAVBgNV
+BAoTDlJ1YnkgQ29yZSBUZWFtMRUwEwYDVQQDEwxSdWJ5IFRlc3QgQ0EwgZ8wDQYJ
+KoZIhvcNAQEBBQADgY0AMIGJAoGBAO6xGgYlHymAoVnvDw2LWohAc1aV2du0cTw2
+f7T8aFFUi42eQSf7MdF6bFwhMD0i9nqSw/qzhTZEdiJsCIJ4iX3DGdTsfQVbdc04
+HIkD7wKqfm1bNuqt4gvsS+I2v8BJRJOmzNpAvl/AdTu+wCjbQleQO4OvLWCaxrG8
+XGgSLXAlAgMBAAGjgbEwga4wHQYDVR0OBBYEFK71Of7SNaIsHssOCEwOWtxEmeKc
+MH8GA1UdIwR4MHaAFK71Of7SNaIsHssOCEwOWtxEmeKcoVOkUTBPMQswCQYDVQQG
+EwJKUDEQMA4GA1UECBMHU2hpbWFuZTEXMBUGA1UEChMOUnVieSBDb3JlIFRlYW0x
+FTATBgNVBAMTDFJ1YnkgVGVzdCBDQYIJANKcXIGjsDvsMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQEFBQADgYEAniiJgYNVGzjLhYbs7sz0z/BHYXIH8i7KZ/fIKbU8
+NNLPwvecTc6NNyRXhcEOJ4aBFZnsrwWuCZb291rA0qSC7dbTJuk9UFAMccJumlAw
+c4qUDcGcGtp2gLiLRuwQk2yNy6vrEl3gbxparFw0Et97p9y2D9Y+rC9p2xGqHcSQ
+9vo=
+-----END CERTIFICATE-----
Added: MacRuby/trunk/test/test-mri/test/net/imap/server.crt
===================================================================
--- MacRuby/trunk/test/test-mri/test/net/imap/server.crt (rev 0)
+++ MacRuby/trunk/test/test-mri/test/net/imap/server.crt 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIB0jCCATsCAQIwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UEBhMCSlAxEDAOBgNV
+BAgTB1NoaW1hbmUxFzAVBgNVBAoTDlJ1YnkgQ29yZSBUZWFtMRUwEwYDVQQDEwxS
+dWJ5IFRlc3QgQ0EwHhcNMDcxMjIyMDg0MDA1WhcNMTcxMjE5MDg0MDA1WjAUMRIw
+EAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANt1
+0EXesd+/caAOsKXmvPQcneUlZ2TFe8vxr8a+mqrqfg/MBa/vQGkGsskTnX7rogbi
+6n0Hx8eZx/vVuOtjd2IrGBLDU1jQ9cdADAHRJoI0Fgnj3GX03LtdpUFg56l0utdM
+tqOcxYyJr8vonwX+6v5kJL/n7eP20PzW6/wGghD7AgMBAAEwDQYJKoZIhvcNAQEF
+BQADgYEA2zl2U40/ogkC3k1ccoO4n/szaGW/wfxFREjn9BCvSB8iGRYNCGO/MdZ6
+maaSuAPdIw6RdFncL6dC3xf5IrriCyOmdZM/O8hgC/sNOnWtRAA/+XJqs0UnZ/A2
+f06bSqE1BTSiUU5wY4UraN2aDgnbFonCrY5RipZgLYaWyEbRtF8=
+-----END CERTIFICATE-----
Added: MacRuby/trunk/test/test-mri/test/net/imap/server.key
===================================================================
--- MacRuby/trunk/test/test-mri/test/net/imap/server.key (rev 0)
+++ MacRuby/trunk/test/test-mri/test/net/imap/server.key 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDbddBF3rHfv3GgDrCl5rz0HJ3lJWdkxXvL8a/Gvpqq6n4PzAWv
+70BpBrLJE51+66IG4up9B8fHmcf71bjrY3diKxgSw1NY0PXHQAwB0SaCNBYJ49xl
+9Ny7XaVBYOepdLrXTLajnMWMia/L6J8F/ur+ZCS/5+3j9tD81uv8BoIQ+wIDAQAB
+AoGAGtYHR+P5gFDaxiXFuCPFC1zMeg7e29XCU6gURIteQnQ2QhxCvcbV64HkLu51
+HeYWhB0Pa4aeCWxmpgb2e+JH4MEoIjeJSGyZQeqwkQLgWJDdvkgWx5am58QzA60I
+ipkZ9QHcPffSs5RiGx4yfr58KqAmwFphGCY8W7v4LqaENdECQQD9H5VTW9g4gj1c
+j3uNYvSI/D7a9P7gfI+ziczuwMm5xsBx3D/t5TAr3SJKNne3sl1E6ZERCUbzxf+C
+k58EiHx1AkEA3fRLGqDOq7EcQhbjTcA/v/t5MwlGEUsS9+XrqOWn50YuoIwRZJ3v
+qHRQzfQfFNklGtfBvwQ4md3irXjMeGVprwJBAMEAuwiDiHuV+xm/ofKtmE13IKot
+ksYy1BOOp/8IawhHXueyi+BmF/PqOkIiA+jCjNGF0oIN89beizPSQbbgJx0CQG/K
+qL1bu1ys0y/SeWBi8XkP/0aeaCUzq/UiYCTsrzoEll2UzvnftqMhGsXxLGqCyHaR
+r2s3hA6zvIVlL4+AfM8CQQClq+WDrC5VKciLYakZNWJjV1m+H2Ut/0fXdUjKHajE
+FWLcsrOhADf6bkTb71GwPxnKRkkRmud5upP0ZYYTqM4X
+-----END RSA PRIVATE KEY-----
Added: MacRuby/trunk/test/test-mri/test/net/imap/test_imap.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/net/imap/test_imap.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/net/imap/test_imap.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,440 @@
+require "net/imap"
+require "test/unit"
+
+class IMAPTest < Test::Unit::TestCase
+ CA_FILE = File.expand_path("cacert.pem", File.dirname(__FILE__))
+ SERVER_KEY = File.expand_path("server.key", File.dirname(__FILE__))
+ SERVER_CERT = File.expand_path("server.crt", File.dirname(__FILE__))
+
+ SERVER_ADDR = "127.0.0.1"
+
+ def setup
+ @do_not_reverse_lookup = Socket.do_not_reverse_lookup
+ Socket.do_not_reverse_lookup = true
+ end
+
+ def teardown
+ Socket.do_not_reverse_lookup = @do_not_reverse_lookup
+ end
+
+ def test_encode_utf7
+ utf8 = "\357\274\241\357\274\242\357\274\243".force_encoding("UTF-8")
+ s = Net::IMAP.encode_utf7(utf8)
+ assert_equal("&,yH,Iv8j-".force_encoding("UTF-8"), s)
+
+ utf8 = "\343\201\202&".force_encoding("UTF-8")
+ s = Net::IMAP.encode_utf7(utf8)
+ assert_equal("&MEI-&-".force_encoding("UTF-8"), s)
+ end
+
+ def test_decode_utf7
+ s = Net::IMAP.decode_utf7("&,yH,Iv8j-")
+ utf8 = "\357\274\241\357\274\242\357\274\243".force_encoding("UTF-8")
+ assert_equal(utf8, s)
+ end
+
+ def test_format_date
+ time = Time.mktime(2009, 7, 24)
+ s = Net::IMAP.format_date(time)
+ assert_equal("24-Jul-2009", s)
+ end
+
+ def test_format_datetime
+ time = Time.mktime(2009, 7, 24, 1, 23, 45)
+ s = Net::IMAP.format_datetime(time)
+ assert_match(/\A24-Jul-2009 01:23 [+\-]\d{4}\z/, s)
+ end
+
+ def test_imaps_unknown_ca
+ if defined?(OpenSSL)
+ assert_raise(OpenSSL::SSL::SSLError) do
+ imaps_test do |port|
+ Net::IMAP.new("localhost",
+ :port => port,
+ :ssl => true)
+ end
+ end
+ end
+ end
+
+ def test_imaps_with_ca_file
+ if defined?(OpenSSL)
+ assert_nothing_raised do
+ imaps_test do |port|
+ Net::IMAP.new("localhost",
+ :port => port,
+ :ssl => { :ca_file => CA_FILE })
+ end
+ end
+ end
+ end
+
+ def test_imaps_verify_none
+ if defined?(OpenSSL)
+ assert_nothing_raised do
+ imaps_test do |port|
+ Net::IMAP.new("localhost",
+ :port => port,
+ :ssl => { :verify_mode => OpenSSL::SSL::VERIFY_NONE })
+ end
+ end
+ end
+ end
+
+ def test_imaps_post_connection_check
+ if defined?(OpenSSL)
+ assert_raise(OpenSSL::SSL::SSLError) do
+ imaps_test do |port|
+ # SERVER_ADDR is different from the hostname in the certificate,
+ # so the following code should raise a SSLError.
+ Net::IMAP.new(SERVER_ADDR,
+ :port => port,
+ :ssl => { :ca_file => CA_FILE })
+ end
+ end
+ end
+ end
+
+ def test_starttls
+ imap = nil
+ if defined?(OpenSSL)
+ starttls_test do |port|
+ imap = Net::IMAP.new("localhost", :port => port)
+ imap.starttls(:ca_file => CA_FILE)
+ imap
+ end
+ end
+ ensure
+ if imap && !imap.disconnected?
+ imap.disconnect
+ end
+ end
+
+ def test_unexpected_eof
+ server = create_tcp_server
+ port = server.addr[1]
+ Thread.start do
+ begin
+ sock = server.accept
+ begin
+ sock.print("* OK test server\r\n")
+ sock.gets
+# sock.print("* BYE terminating connection\r\n")
+# sock.print("RUBY0001 OK LOGOUT completed\r\n")
+ ensure
+ sock.close
+ end
+ rescue
+ end
+ end
+ begin
+ begin
+ imap = Net::IMAP.new("localhost", :port => port)
+ assert_raise(EOFError) do
+ imap.logout
+ end
+ ensure
+ imap.disconnect if imap
+ end
+ ensure
+ server.close
+ end
+ end
+
+ def test_idle
+ server = create_tcp_server
+ port = server.addr[1]
+ requests = []
+ Thread.start do
+ begin
+ sock = server.accept
+ begin
+ sock.print("* OK test server\r\n")
+ requests.push(sock.gets)
+ sock.print("+ idling\r\n")
+ sock.print("* 3 EXISTS\r\n")
+ sock.print("* 2 EXPUNGE\r\n")
+ requests.push(sock.gets)
+ sock.print("RUBY0001 OK IDLE terminated\r\n")
+ sock.gets
+ sock.print("* BYE terminating connection\r\n")
+ sock.print("RUBY0002 OK LOGOUT completed\r\n")
+ ensure
+ sock.close
+ end
+ rescue
+ end
+ end
+ begin
+ begin
+ imap = Net::IMAP.new("localhost", :port => port)
+ responses = []
+ imap.idle do |res|
+ responses.push(res)
+ if res.name == "EXPUNGE"
+ imap.idle_done
+ end
+ end
+ assert_equal(3, responses.length)
+ assert_instance_of(Net::IMAP::ContinuationRequest, responses[0])
+ assert_equal("EXISTS", responses[1].name)
+ assert_equal(3, responses[1].data)
+ assert_equal("EXPUNGE", responses[2].name)
+ assert_equal(2, responses[2].data)
+ assert_equal(2, requests.length)
+ assert_equal("RUBY0001 IDLE\r\n", requests[0])
+ assert_equal("DONE\r\n", requests[1])
+ imap.logout
+ ensure
+ imap.disconnect if imap
+ end
+ ensure
+ server.close
+ end
+ end
+
+ def test_exception_during_idle
+ server = create_tcp_server
+ port = server.addr[1]
+ requests = []
+ Thread.start do
+ begin
+ sock = server.accept
+ begin
+ sock.print("* OK test server\r\n")
+ requests.push(sock.gets)
+ sock.print("+ idling\r\n")
+ sock.print("* 3 EXISTS\r\n")
+ sock.print("* 2 EXPUNGE\r\n")
+ requests.push(sock.gets)
+ sock.print("RUBY0001 OK IDLE terminated\r\n")
+ sock.gets
+ sock.print("* BYE terminating connection\r\n")
+ sock.print("RUBY0002 OK LOGOUT completed\r\n")
+ ensure
+ sock.close
+ end
+ rescue
+ end
+ end
+ begin
+ begin
+ imap = Net::IMAP.new("localhost", :port => port)
+ begin
+ th = Thread.current
+ m = Monitor.new
+ in_idle = false
+ exception_raised = false
+ c = m.new_cond
+ Thread.start do
+ m.synchronize do
+ until in_idle
+ c.wait(0.1)
+ end
+ end
+ th.raise(Interrupt)
+ exception_raised = true
+ end
+ imap.idle do |res|
+ m.synchronize do
+ in_idle = true
+ c.signal
+ until exception_raised
+ c.wait(0.1)
+ end
+ end
+ end
+ rescue Interrupt
+ end
+ assert_equal(2, requests.length)
+ assert_equal("RUBY0001 IDLE\r\n", requests[0])
+ assert_equal("DONE\r\n", requests[1])
+ imap.logout
+ ensure
+ imap.disconnect if imap
+ end
+ ensure
+ server.close
+ end
+ end
+
+ def test_idle_done_not_during_idle
+ server = create_tcp_server
+ port = server.addr[1]
+ requests = []
+ Thread.start do
+ begin
+ sock = server.accept
+ begin
+ sock.print("* OK test server\r\n")
+ ensure
+ sock.close
+ end
+ rescue
+ end
+ end
+ begin
+ begin
+ imap = Net::IMAP.new("localhost", :port => port)
+ assert_raise(Net::IMAP::Error) do
+ imap.idle_done
+ end
+ ensure
+ imap.disconnect if imap
+ end
+ ensure
+ server.close
+ end
+ end
+
+ def test_unexpected_bye
+ server = create_tcp_server
+ port = server.addr[1]
+ Thread.start do
+ begin
+ sock = server.accept
+ begin
+ sock.print("* OK Gimap ready for requests from 75.101.246.151 33if2752585qyk.26\r\n")
+ sock.gets
+ sock.print("* BYE System Error 33if2752585qyk.26\r\n")
+ ensure
+ sock.close
+ end
+ rescue
+ end
+ end
+ begin
+ begin
+ imap = Net::IMAP.new("localhost", :port => port)
+ assert_raise(Net::IMAP::ByeResponseError) do
+ imap.login("user", "password")
+ end
+ end
+ ensure
+ server.close
+ end
+ end
+
+ def test_exception_during_shutdown
+ server = create_tcp_server
+ port = server.addr[1]
+ Thread.start do
+ begin
+ sock = server.accept
+ begin
+ sock.print("* OK test server\r\n")
+ sock.gets
+ sock.print("* BYE terminating connection\r\n")
+ sock.print("RUBY0001 OK LOGOUT completed\r\n")
+ ensure
+ sock.close
+ end
+ rescue
+ end
+ end
+ begin
+ begin
+ imap = Net::IMAP.new("localhost", :port => port)
+ imap.instance_eval do
+ def @sock.shutdown(*args)
+ super
+ ensure
+ raise "error"
+ end
+ end
+ imap.logout
+ ensure
+ assert_raise(RuntimeError) do
+ imap.disconnect
+ end
+ end
+ ensure
+ server.close
+ end
+ end
+
+ private
+
+ def imaps_test
+ server = create_tcp_server
+ port = server.addr[1]
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.ca_file = CA_FILE
+ ctx.key = File.open(SERVER_KEY) { |f|
+ OpenSSL::PKey::RSA.new(f)
+ }
+ ctx.cert = File.open(SERVER_CERT) { |f|
+ OpenSSL::X509::Certificate.new(f)
+ }
+ ssl_server = OpenSSL::SSL::SSLServer.new(server, ctx)
+ Thread.start do
+ begin
+ sock = ssl_server.accept
+ begin
+ sock.print("* OK test server\r\n")
+ sock.gets
+ sock.print("* BYE terminating connection\r\n")
+ sock.print("RUBY0001 OK LOGOUT completed\r\n")
+ ensure
+ sock.close
+ end
+ rescue
+ end
+ end
+ begin
+ begin
+ imap = yield(port)
+ imap.logout
+ ensure
+ imap.disconnect if imap
+ end
+ ensure
+ ssl_server.close
+ end
+ end
+
+ def starttls_test
+ server = create_tcp_server
+ port = server.addr[1]
+ Thread.start do
+ begin
+ sock = server.accept
+ sock.print("* OK test server\r\n")
+ sock.gets
+ sock.print("RUBY0001 OK completed\r\n")
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.ca_file = CA_FILE
+ ctx.key = File.open(SERVER_KEY) { |f|
+ OpenSSL::PKey::RSA.new(f)
+ }
+ ctx.cert = File.open(SERVER_CERT) { |f|
+ OpenSSL::X509::Certificate.new(f)
+ }
+ sock = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ begin
+ sock.accept
+ sock.gets
+ sock.print("* BYE terminating connection\r\n")
+ sock.print("RUBY0002 OK LOGOUT completed\r\n")
+ ensure
+ sock.close
+ end
+ rescue
+ end
+ end
+ begin
+ begin
+ imap = yield(port)
+ imap.logout
+ ensure
+ imap.disconnect if imap
+ end
+ ensure
+ server.close
+ end
+ end
+
+ def create_tcp_server
+ return TCPServer.new(SERVER_ADDR, 0)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/net/imap/test_imap_response_parser.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/net/imap/test_imap_response_parser.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/net/imap/test_imap_response_parser.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,66 @@
+require "net/imap"
+require "test/unit"
+
+class IMAPResponseParserTest < Test::Unit::TestCase
+ def setup
+ @do_not_reverse_lookup = Socket.do_not_reverse_lookup
+ Socket.do_not_reverse_lookup = true
+ if Net::IMAP.respond_to?(:max_flag_count)
+ @max_flag_count = Net::IMAP.max_flag_count
+ Net::IMAP.max_flag_count = 3
+ end
+ end
+
+ def teardown
+ Socket.do_not_reverse_lookup = @do_not_reverse_lookup
+ if Net::IMAP.respond_to?(:max_flag_count)
+ Net::IMAP.max_flag_count = @max_flag_count
+ end
+ end
+
+ def test_flag_list_safe
+ parser = Net::IMAP::ResponseParser.new
+ response = lambda {
+ $SAFE = 1
+ parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
+* LIST (\\HasChildren) "." "INBOX"
+EOF
+ }.call
+ assert_equal [:Haschildren], response.data.attr
+ end
+
+ def test_flag_list_too_many_flags
+ parser = Net::IMAP::ResponseParser.new
+ assert_nothing_raised do
+ 3.times do |i|
+ parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
+* LIST (\\Foo#{i}) "." "INBOX"
+EOF
+ end
+ end
+ assert_raise(Net::IMAP::FlagCountError) do
+ parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
+* LIST (\\Foo3) "." "INBOX"
+EOF
+ end
+ end
+
+ def test_flag_list_many_same_flags
+ parser = Net::IMAP::ResponseParser.new
+ assert_nothing_raised do
+ 100.times do
+ parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
+* LIST (\\Foo) "." "INBOX"
+EOF
+ end
+ end
+ end
+
+ def test_resp_text_code
+ parser = Net::IMAP::ResponseParser.new
+ response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
+* OK [CLOSED] Previous mailbox closed.
+EOF
+ assert_equal "CLOSED", response.data.code.name
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/net/pop/test_pop.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/net/pop/test_pop.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/net/pop/test_pop.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,132 @@
+require 'net/pop'
+require 'test/unit'
+require 'digest/md5'
+
+class TestPOP < Test::Unit::TestCase
+ def setup
+ @users = {'user' => 'pass' }
+ @ok_user = 'user'
+ @stamp_base = "#{$$}.#{Time.now.to_i}@localhost"
+ end
+
+ def test_pop_auth_ok
+ pop_test(false) do |pop|
+ assert_instance_of Net::POP3, pop
+ assert_nothing_raised do
+ pop.start(@ok_user, @users[@ok_user])
+ end
+ end
+ end
+
+ def test_pop_auth_ng
+ pop_test(false) do |pop|
+ assert_instance_of Net::POP3, pop
+ assert_raise Net::POPAuthenticationError do
+ pop.start(@ok_user, 'bad password')
+ end
+ end
+ end
+
+ def test_apop_ok
+ pop_test(@stamp_base) do |pop|
+ assert_instance_of Net::APOP, pop
+ assert_nothing_raised do
+ pop.start(@ok_user, @users[@ok_user])
+ end
+ end
+ end
+
+ def test_apop_ng
+ pop_test(@stamp_base) do |pop|
+ assert_instance_of Net::APOP, pop
+ assert_raise Net::POPAuthenticationError do
+ pop.start(@ok_user, 'bad password')
+ end
+ end
+ end
+
+ def test_apop_invalid
+ pop_test("\x80"+ at stamp_base) do |pop|
+ assert_instance_of Net::APOP, pop
+ assert_raise Net::POPAuthenticationError do
+ pop.start(@ok_user, @users[@ok_user])
+ end
+ end
+ end
+
+ def test_apop_invalid_at
+ pop_test(@stamp_base.sub('@', '.')) do |pop|
+ assert_instance_of Net::APOP, pop
+ e = assert_raise Net::POPAuthenticationError do
+ pop.start(@ok_user, @users[@ok_user])
+ end
+ end
+ end
+
+ def pop_test(apop=false)
+ host = 'localhost'
+ server = TCPServer.new(host, 0)
+ port = server.addr[1]
+ thread = Thread.start do
+ sock = server.accept
+ begin
+ pop_server_loop(sock, apop)
+ ensure
+ sock.close
+ end
+ end
+ begin
+ pop = Net::POP3::APOP(apop).new(host, port)
+ #pop.set_debug_output $stderr
+ yield pop
+ ensure
+ begin
+ pop.finish
+ rescue IOError
+ raise unless $!.message == "POP session not yet started"
+ end
+ end
+ ensure
+ server.close
+ thread.value
+ end
+
+ def pop_server_loop(sock, apop)
+ if apop
+ sock.print "+OK ready <#{apop}>\r\n"
+ else
+ sock.print "+OK ready\r\n"
+ end
+ user = nil
+ while line = sock.gets
+ case line
+ when /^USER (.+)\r\n/
+ user = $1
+ if @users.key?(user)
+ sock.print "+OK\r\n"
+ else
+ sock.print "-ERR unknown user\r\n"
+ end
+ when /^PASS (.+)\r\n/
+ if @users[user] == $1
+ sock.print "+OK\r\n"
+ else
+ sock.print "-ERR invalid password\r\n"
+ end
+ when /^APOP (.+) (.+)\r\n/
+ user = $1
+ if apop && Digest::MD5.hexdigest("<#{apop}>#{@users[user]}") == $2
+ sock.print "+OK\r\n"
+ else
+ sock.print "-ERR authentication failed\r\n"
+ end
+ when /^QUIT/
+ sock.print "+OK bye\r\n"
+ return
+ else
+ sock.print "-ERR command not recognized\r\n"
+ return
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/nkf/test_kconv.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/nkf/test_kconv.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/nkf/test_kconv.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,74 @@
+require 'test/unit'
+require 'kconv'
+
+class TestKconv < Test::Unit::TestCase
+ def setup
+ @euc_str = "\
+\xa5\xaa\xa5\xd6\xa5\xb8\xa5\xa7\xa5\xaf\xa5\xc8\xbb\xd8\xb8\xfe\
+\xa5\xd7\xa5\xed\xa5\xb0\xa5\xe9\xa5\xdf\xa5\xf3\xa5\xb0\xb8\xc0\xb8\xec
+\x52\x75\x62\x79".force_encoding('EUC-JP')
+ @utf8_str = "\
+\xe3\x82\xaa\xe3\x83\x96\xe3\x82\xb8\xe3\x82\xa7\
+\xe3\x82\xaf\xe3\x83\x88\xe6\x8c\x87\xe5\x90\x91\
+\xe3\x83\x97\xe3\x83\xad\xe3\x82\xb0\xe3\x83\xa9\xe3\x83\x9f\
+\xe3\x83\xb3\xe3\x82\xb0\xe8\xa8\x80\xe8\xaa\x9e
+\x52\x75\x62\x79".force_encoding('UTF-8')
+ @sjis_str = "\
+\x83\x49\x83\x75\x83\x57\x83\x46\x83\x4e\x83\x67\x8e\x77\x8c\xfc\
+\x83\x76\x83\x8d\x83\x4f\x83\x89\x83\x7e\x83\x93\x83\x4f\x8c\xbe\x8c\xea
+\x52\x75\x62\x79".force_encoding('Shift_JIS')
+ @jis_str = "\
+\x1b\x24\x42\x25\x2a\x25\x56\x25\x38\x25\x27\x25\x2f\x25\x48\x3b\x58\x38\x7e\
+\x25\x57\x25\x6d\x25\x30\x25\x69\x25\x5f\x25\x73\x25\x30\x38\x40\x38\x6c\x1b\x28\x42
+\x52\x75\x62\x79".force_encoding('ISO-2022-JP')
+ end
+
+
+ def test_eucjp
+ assert(@euc_str.iseuc)
+ assert_equal(::Kconv::EUC, Kconv.guess(@euc_str))
+ assert_equal(@euc_str, @euc_str.toeuc)
+ assert_equal(@euc_str, @sjis_str.toeuc)
+ assert_equal(@euc_str, @utf8_str.toeuc)
+ assert_equal(@euc_str, @jis_str.toeuc)
+ assert_equal(@euc_str, @euc_str.kconv(::NKF::EUC))
+ assert_equal(@euc_str, @sjis_str.kconv(::NKF::EUC))
+ assert_equal(@euc_str, @utf8_str.kconv(::NKF::EUC))
+ assert_equal(@euc_str, @jis_str.kconv(::NKF::EUC))
+ end
+ def test_shiftjis
+ assert(@sjis_str.issjis)
+ assert_equal(::Kconv::SJIS, Kconv.guess(@sjis_str))
+ assert_equal(@sjis_str, @euc_str.tosjis)
+ assert_equal(@sjis_str, @sjis_str.tosjis)
+ assert_equal(@sjis_str, @utf8_str.tosjis)
+ assert_equal(@sjis_str, @jis_str.tosjis)
+ assert_equal(@sjis_str, @euc_str.kconv(::NKF::SJIS))
+ assert_equal(@sjis_str, @sjis_str.kconv(::NKF::SJIS))
+ assert_equal(@sjis_str, @utf8_str.kconv(::NKF::SJIS))
+ assert_equal(@sjis_str, @jis_str.kconv(::NKF::SJIS))
+ end
+ def test_utf8
+ assert(@utf8_str.isutf8)
+ assert_equal(::Kconv::UTF8, Kconv.guess(@utf8_str))
+ assert_equal(@utf8_str, @euc_str.toutf8)
+ assert_equal(@utf8_str, @sjis_str.toutf8)
+ assert_equal(@utf8_str, @utf8_str.toutf8)
+ assert_equal(@utf8_str, @jis_str.toutf8)
+ assert_equal(@utf8_str, @euc_str.kconv(::NKF::UTF8))
+ assert_equal(@utf8_str, @sjis_str.kconv(::NKF::UTF8))
+ assert_equal(@utf8_str, @utf8_str.kconv(::NKF::UTF8))
+ assert_equal(@utf8_str, @jis_str.kconv(::NKF::UTF8))
+ end
+ def test_jis
+ assert_equal(::Kconv::JIS, Kconv.guess(@jis_str))
+ assert_equal(@jis_str, @euc_str.tojis)
+ assert_equal(@jis_str, @sjis_str.tojis)
+ assert_equal(@jis_str, @utf8_str.tojis)
+ assert_equal(@jis_str, @jis_str.tojis)
+ assert_equal(@jis_str, @euc_str.kconv(::NKF::JIS))
+ assert_equal(@jis_str, @sjis_str.kconv(::NKF::JIS))
+ assert_equal(@jis_str, @utf8_str.kconv(::NKF::JIS))
+ assert_equal(@jis_str, @jis_str.kconv(::NKF::JIS))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/nkf/test_nkf.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/nkf/test_nkf.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/nkf/test_nkf.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,22 @@
+require 'test/unit'
+require 'nkf'
+
+class TestNKF < Test::Unit::TestCase
+ EUC_STR = "\xa5\xaa\xa5\xd6\xa5\xb8\xa5\xa7\xa5\xaf\xa5\xc8\xbb\xd8\xb8\xfe\
+\xa5\xb9\xa5\xaf\xa5\xea\xa5\xd7\xa5\xc8\xb8\xc0\xb8\xec\
+Ruby"
+
+ def test_guess
+ str_euc = EUC_STR
+ str_jis = NKF.nkf('-j', str_euc)
+ assert_equal(::NKF::JIS, NKF.guess(str_jis))
+ assert_equal(::NKF::EUC, NKF.guess(str_euc))
+ end
+
+ def test_ruby_dev_36909
+ assert_nothing_raised do
+ 1000.times { NKF.nkf("--oc=eucJP-nkf", "foo") }
+ end
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/open-uri/test_open-uri.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/open-uri/test_open-uri.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/open-uri/test_open-uri.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,731 @@
+require 'test/unit'
+require 'open-uri'
+require 'webrick'
+require 'webrick/httpproxy'
+require 'zlib'
+
+class TestOpenURI < Test::Unit::TestCase
+
+ NullLog = Object.new
+ def NullLog.<<(arg)
+ end
+
+ def with_http
+ Dir.mktmpdir {|dr|
+ srv = WEBrick::HTTPServer.new({
+ :DocumentRoot => dr,
+ :ServerType => Thread,
+ :Logger => WEBrick::Log.new(NullLog),
+ :AccessLog => [[NullLog, ""]],
+ :BindAddress => '127.0.0.1',
+ :Port => 0})
+ _, port, _, host = srv.listeners[0].addr
+ begin
+ th = srv.start
+ yield srv, dr, "http://#{host}:#{port}"
+ ensure
+ srv.shutdown
+ end
+ }
+ end
+
+ def with_env(h)
+ begin
+ old = {}
+ h.each_key {|k| old[k] = ENV[k] }
+ h.each {|k, v| ENV[k] = v }
+ yield
+ ensure
+ h.each_key {|k| ENV[k] = old[k] }
+ end
+ end
+
+ def setup
+ @proxies = %w[http_proxy HTTP_PROXY ftp_proxy FTP_PROXY no_proxy]
+ @old_proxies = @proxies.map {|k| ENV[k] }
+ @proxies.each {|k| ENV[k] = nil }
+ end
+
+ def teardown
+ @proxies.each_with_index {|k, i| ENV[k] = @old_proxies[i] }
+ end
+
+ def test_200
+ with_http {|srv, dr, url|
+ open("#{dr}/foo200", "w") {|f| f << "foo200" }
+ open("#{url}/foo200") {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("foo200", f.read)
+ }
+ }
+ end
+
+ def test_200big
+ with_http {|srv, dr, url|
+ content = "foo200big"*10240
+ open("#{dr}/foo200big", "w") {|f| f << content }
+ open("#{url}/foo200big") {|f|
+ assert_equal("200", f.status[0])
+ assert_equal(content, f.read)
+ }
+ }
+ end
+
+ def test_404
+ with_http {|srv, dr, url|
+ exc = assert_raise(OpenURI::HTTPError) { open("#{url}/not-exist") {} }
+ assert_equal("404", exc.io.status[0])
+ }
+ end
+
+ def test_open_uri
+ with_http {|srv, dr, url|
+ open("#{dr}/foo_ou", "w") {|f| f << "foo_ou" }
+ u = URI("#{url}/foo_ou")
+ open(u) {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("foo_ou", f.read)
+ }
+ }
+ end
+
+ def test_open_too_many_arg
+ assert_raise(ArgumentError) { open("http://192.0.2.1/tma", "r", 0666, :extra) {} }
+ end
+
+ def test_read_timeout
+ TCPServer.open("127.0.0.1", 0) {|serv|
+ port = serv.addr[1]
+ th = Thread.new {
+ sock = serv.accept
+ begin
+ req = sock.gets("\r\n\r\n")
+ assert_match(%r{\AGET /foo/bar }, req)
+ sock.print "HTTP/1.0 200 OK\r\n"
+ sock.print "Content-Length: 4\r\n\r\n"
+ sleep 1
+ sock.print "ab\r\n"
+ ensure
+ sock.close
+ end
+ }
+ begin
+ assert_raise(Timeout::Error) { URI("http://127.0.0.1:#{port}/foo/bar").read(:read_timeout=>0.01) }
+ ensure
+ Thread.kill(th)
+ th.join
+ end
+ }
+ end
+
+ def test_invalid_option
+ assert_raise(ArgumentError) { open("http://127.0.0.1/", :invalid_option=>true) {} }
+ end
+
+ def test_mode
+ with_http {|srv, dr, url|
+ open("#{dr}/mode", "w") {|f| f << "mode" }
+ open("#{url}/mode", "r") {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("mode", f.read)
+ }
+ open("#{url}/mode", "r", 0600) {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("mode", f.read)
+ }
+ assert_raise(ArgumentError) { open("#{url}/mode", "a") {} }
+ open("#{url}/mode", "r:us-ascii") {|f|
+ assert_equal(Encoding::US_ASCII, f.read.encoding)
+ }
+ open("#{url}/mode", "r:utf-8") {|f|
+ assert_equal(Encoding::UTF_8, f.read.encoding)
+ }
+ assert_raise(ArgumentError) { open("#{url}/mode", "r:invalid-encoding") {} }
+ }
+ end
+
+ def test_without_block
+ with_http {|srv, dr, url|
+ open("#{dr}/without_block", "w") {|g| g << "without_block" }
+ begin
+ f = open("#{url}/without_block")
+ assert_equal("200", f.status[0])
+ assert_equal("without_block", f.read)
+ ensure
+ f.close
+ end
+ }
+ end
+
+ def test_header
+ myheader1 = 'barrrr'
+ myheader2 = nil
+ with_http {|srv, dr, url|
+ srv.mount_proc("/h/") {|req, res| myheader2 = req['myheader']; res.body = "foo" }
+ open("#{url}/h/", 'MyHeader'=>myheader1) {|f|
+ assert_equal("foo", f.read)
+ assert_equal(myheader1, myheader2)
+ }
+ }
+ end
+
+ def test_multi_proxy_opt
+ assert_raise(ArgumentError) {
+ open("http://127.0.0.1/", :proxy_http_basic_authentication=>true, :proxy=>true) {}
+ }
+ end
+
+ def test_non_http_proxy
+ assert_raise(RuntimeError) {
+ open("http://127.0.0.1/", :proxy=>URI("ftp://127.0.0.1/")) {}
+ }
+ end
+
+ def test_proxy
+ with_http {|srv, dr, url|
+ log = ''
+ proxy = WEBrick::HTTPProxyServer.new({
+ :ServerType => Thread,
+ :Logger => WEBrick::Log.new(NullLog),
+ :AccessLog => [[NullLog, ""]],
+ :ProxyAuthProc => lambda {|req, res|
+ log << req.request_line
+ },
+ :BindAddress => '127.0.0.1',
+ :Port => 0})
+ _, proxy_port, _, proxy_host = proxy.listeners[0].addr
+ proxy_url = "http://#{proxy_host}:#{proxy_port}/"
+ begin
+ th = proxy.start
+ open("#{dr}/proxy", "w") {|f| f << "proxy" }
+ open("#{url}/proxy", :proxy=>proxy_url) {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("proxy", f.read)
+ }
+ assert_match(/#{Regexp.quote url}/, log); log.clear
+ open("#{url}/proxy", :proxy=>URI(proxy_url)) {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("proxy", f.read)
+ }
+ assert_match(/#{Regexp.quote url}/, log); log.clear
+ open("#{url}/proxy", :proxy=>nil) {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("proxy", f.read)
+ }
+ assert_equal("", log); log.clear
+ assert_raise(ArgumentError) {
+ open("#{url}/proxy", :proxy=>:invalid) {}
+ }
+ assert_equal("", log); log.clear
+ with_env("http_proxy"=>proxy_url) {
+ # should not use proxy for 127.0.0.0/8.
+ open("#{url}/proxy") {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("proxy", f.read)
+ }
+ }
+ assert_equal("", log); log.clear
+ ensure
+ proxy.shutdown
+ end
+ }
+ end
+
+ def test_proxy_http_basic_authentication
+ with_http {|srv, dr, url|
+ log = ''
+ proxy = WEBrick::HTTPProxyServer.new({
+ :ServerType => Thread,
+ :Logger => WEBrick::Log.new(NullLog),
+ :AccessLog => [[NullLog, ""]],
+ :ProxyAuthProc => lambda {|req, res|
+ log << req.request_line
+ if req["Proxy-Authorization"] != "Basic #{['user:pass'].pack('m').chomp}"
+ raise WEBrick::HTTPStatus::ProxyAuthenticationRequired
+ end
+ },
+ :BindAddress => '127.0.0.1',
+ :Port => 0})
+ _, proxy_port, _, proxy_host = proxy.listeners[0].addr
+ proxy_url = "http://#{proxy_host}:#{proxy_port}/"
+ begin
+ th = proxy.start
+ open("#{dr}/proxy", "w") {|f| f << "proxy" }
+ exc = assert_raise(OpenURI::HTTPError) { open("#{url}/proxy", :proxy=>proxy_url) {} }
+ assert_equal("407", exc.io.status[0])
+ assert_match(/#{Regexp.quote url}/, log); log.clear
+ open("#{url}/proxy",
+ :proxy_http_basic_authentication=>[proxy_url, "user", "pass"]) {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("proxy", f.read)
+ }
+ assert_match(/#{Regexp.quote url}/, log); log.clear
+ assert_raise(ArgumentError) {
+ open("#{url}/proxy",
+ :proxy_http_basic_authentication=>[true, "user", "pass"]) {}
+ }
+ assert_equal("", log); log.clear
+ ensure
+ proxy.shutdown
+ end
+ }
+ end
+
+ def test_redirect
+ with_http {|srv, dr, url|
+ srv.mount_proc("/r1/") {|req, res| res.status = 301; res["location"] = "#{url}/r2"; res.body = "r1" }
+ srv.mount_proc("/r2/") {|req, res| res.body = "r2" }
+ srv.mount_proc("/to-file/") {|req, res| res.status = 301; res["location"] = "file:///foo" }
+ open("#{url}/r1/") {|f|
+ assert_equal("#{url}/r2", f.base_uri.to_s)
+ assert_equal("r2", f.read)
+ }
+ assert_raise(OpenURI::HTTPRedirect) { open("#{url}/r1/", :redirect=>false) {} }
+ assert_raise(RuntimeError) { open("#{url}/to-file/") {} }
+ }
+ end
+
+ def test_redirect_loop
+ with_http {|srv, dr, url|
+ srv.mount_proc("/r1/") {|req, res| res.status = 301; res["location"] = "#{url}/r2"; res.body = "r1" }
+ srv.mount_proc("/r2/") {|req, res| res.status = 301; res["location"] = "#{url}/r1"; res.body = "r2" }
+ assert_raise(RuntimeError) { open("#{url}/r1/") {} }
+ }
+ end
+
+ def test_redirect_relative
+ TCPServer.open("127.0.0.1", 0) {|serv|
+ port = serv.addr[1]
+ th = Thread.new {
+ sock = serv.accept
+ begin
+ req = sock.gets("\r\n\r\n")
+ assert_match(%r{\AGET /foo/bar }, req)
+ sock.print "HTTP/1.0 302 Found\r\n"
+ sock.print "Location: ../baz\r\n\r\n"
+ ensure
+ sock.close
+ end
+ sock = serv.accept
+ begin
+ req = sock.gets("\r\n\r\n")
+ assert_match(%r{\AGET /baz }, req)
+ sock.print "HTTP/1.0 200 OK\r\n"
+ sock.print "Content-Length: 4\r\n\r\n"
+ sock.print "ab\r\n"
+ ensure
+ sock.close
+ end
+ }
+ begin
+ content = URI("http://127.0.0.1:#{port}/foo/bar").read
+ assert_equal("ab\r\n", content)
+ ensure
+ Thread.kill(th)
+ th.join
+ end
+ }
+ end
+
+ def test_redirect_invalid
+ TCPServer.open("127.0.0.1", 0) {|serv|
+ port = serv.addr[1]
+ th = Thread.new {
+ sock = serv.accept
+ begin
+ req = sock.gets("\r\n\r\n")
+ assert_match(%r{\AGET /foo/bar }, req)
+ sock.print "HTTP/1.0 302 Found\r\n"
+ sock.print "Location: ::\r\n\r\n"
+ ensure
+ sock.close
+ end
+ }
+ begin
+ assert_raise(OpenURI::HTTPError) {
+ URI("http://127.0.0.1:#{port}/foo/bar").read
+ }
+ ensure
+ Thread.kill(th)
+ th.join
+ end
+ }
+ end
+
+ def test_redirect_auth
+ with_http {|srv, dr, url|
+ srv.mount_proc("/r1/") {|req, res| res.status = 301; res["location"] = "#{url}/r2" }
+ srv.mount_proc("/r2/") {|req, res|
+ if req["Authorization"] != "Basic #{['user:pass'].pack('m').chomp}"
+ raise WEBrick::HTTPStatus::Unauthorized
+ end
+ res.body = "r2"
+ }
+ exc = assert_raise(OpenURI::HTTPError) { open("#{url}/r2/") {} }
+ assert_equal("401", exc.io.status[0])
+ open("#{url}/r2/", :http_basic_authentication=>['user', 'pass']) {|f|
+ assert_equal("r2", f.read)
+ }
+ exc = assert_raise(OpenURI::HTTPError) { open("#{url}/r1/", :http_basic_authentication=>['user', 'pass']) {} }
+ assert_equal("401", exc.io.status[0])
+ }
+ end
+
+ def test_userinfo
+ if "1.9.0" <= RUBY_VERSION
+ assert_raise(ArgumentError) { open("http://user:pass@127.0.0.1/") {} }
+ end
+ end
+
+ def test_progress
+ with_http {|srv, dr, url|
+ content = "a" * 100000
+ srv.mount_proc("/data/") {|req, res| res.body = content }
+ length = []
+ progress = []
+ open("#{url}/data/",
+ :content_length_proc => lambda {|n| length << n },
+ :progress_proc => lambda {|n| progress << n }
+ ) {|f|
+ assert_equal(1, length.length)
+ assert_equal(content.length, length[0])
+ assert(progress.length>1,"maybe test is wrong")
+ assert(progress.sort == progress,"monotone increasing expected but was\n#{progress.inspect}")
+ assert_equal(content.length, progress[-1])
+ assert_equal(content, f.read)
+ }
+ }
+ end
+
+ def test_progress_chunked
+ with_http {|srv, dr, url|
+ content = "a" * 100000
+ srv.mount_proc("/data/") {|req, res| res.body = content; res.chunked = true }
+ length = []
+ progress = []
+ open("#{url}/data/",
+ :content_length_proc => lambda {|n| length << n },
+ :progress_proc => lambda {|n| progress << n }
+ ) {|f|
+ assert_equal(1, length.length)
+ assert_equal(nil, length[0])
+ assert(progress.length>1,"maybe test is worng")
+ assert(progress.sort == progress,"monotone increasing expected but was\n#{progress.inspect}")
+ assert_equal(content.length, progress[-1])
+ assert_equal(content, f.read)
+ }
+ }
+ end
+
+ def test_uri_read
+ with_http {|srv, dr, url|
+ open("#{dr}/uriread", "w") {|f| f << "uriread" }
+ data = URI("#{url}/uriread").read
+ assert_equal("200", data.status[0])
+ assert_equal("uriread", data)
+ }
+ end
+
+ def test_encoding
+ with_http {|srv, dr, url|
+ content_u8 = "\u3042"
+ content_ej = "\xa2\xa4".force_encoding("euc-jp")
+ srv.mount_proc("/u8/") {|req, res| res.body = content_u8; res['content-type'] = 'text/plain; charset=utf-8' }
+ srv.mount_proc("/ej/") {|req, res| res.body = content_ej; res['content-type'] = 'TEXT/PLAIN; charset=EUC-JP' }
+ srv.mount_proc("/nc/") {|req, res| res.body = "aa"; res['content-type'] = 'Text/Plain' }
+ open("#{url}/u8/") {|f|
+ assert_equal(content_u8, f.read)
+ assert_equal("text/plain", f.content_type)
+ assert_equal("utf-8", f.charset)
+ }
+ open("#{url}/ej/") {|f|
+ assert_equal(content_ej, f.read)
+ assert_equal("text/plain", f.content_type)
+ assert_equal("euc-jp", f.charset)
+ }
+ open("#{url}/nc/") {|f|
+ assert_equal("aa", f.read)
+ assert_equal("text/plain", f.content_type)
+ assert_equal("iso-8859-1", f.charset)
+ assert_equal("unknown", f.charset { "unknown" })
+ }
+ }
+ end
+
+ def test_quoted_attvalue
+ with_http {|srv, dr, url|
+ content_u8 = "\u3042"
+ srv.mount_proc("/qu8/") {|req, res| res.body = content_u8; res['content-type'] = 'text/plain; charset="utf\-8"' }
+ open("#{url}/qu8/") {|f|
+ assert_equal(content_u8, f.read)
+ assert_equal("text/plain", f.content_type)
+ assert_equal("utf-8", f.charset)
+ }
+ }
+ end
+
+ def test_last_modified
+ with_http {|srv, dr, url|
+ srv.mount_proc("/data/") {|req, res| res.body = "foo"; res['last-modified'] = 'Fri, 07 Aug 2009 06:05:04 GMT' }
+ open("#{url}/data/") {|f|
+ assert_equal("foo", f.read)
+ assert_equal(Time.utc(2009,8,7,6,5,4), f.last_modified)
+ }
+ }
+ end
+
+ def test_content_encoding
+ with_http {|srv, dr, url|
+ content = "abc" * 10000
+ Zlib::GzipWriter.wrap(StringIO.new(content_gz="".force_encoding("ascii-8bit"))) {|z| z.write content }
+ srv.mount_proc("/data/") {|req, res| res.body = content_gz; res['content-encoding'] = 'gzip' }
+ srv.mount_proc("/data2/") {|req, res| res.body = content_gz; res['content-encoding'] = 'gzip'; res.chunked = true }
+ srv.mount_proc("/noce/") {|req, res| res.body = content_gz }
+ open("#{url}/data/") {|f|
+ assert_equal ['gzip'], f.content_encoding
+ assert_equal(content_gz, f.read.force_encoding("ascii-8bit"))
+ }
+ open("#{url}/data2/") {|f|
+ assert_equal ['gzip'], f.content_encoding
+ assert_equal(content_gz, f.read.force_encoding("ascii-8bit"))
+ }
+ open("#{url}/noce/") {|f|
+ assert_equal [], f.content_encoding
+ assert_equal(content_gz, f.read.force_encoding("ascii-8bit"))
+ }
+ }
+ end
+
+ # 192.0.2.0/24 is TEST-NET. [RFC3330]
+
+ def test_find_proxy
+ assert_nil(URI("http://192.0.2.1/").find_proxy)
+ assert_nil(URI("ftp://192.0.2.1/").find_proxy)
+ with_env('http_proxy'=>'http://127.0.0.1:8080') {
+ assert_equal(URI('http://127.0.0.1:8080'), URI("http://192.0.2.1/").find_proxy)
+ assert_nil(URI("ftp://192.0.2.1/").find_proxy)
+ }
+ with_env('ftp_proxy'=>'http://127.0.0.1:8080') {
+ assert_nil(URI("http://192.0.2.1/").find_proxy)
+ assert_equal(URI('http://127.0.0.1:8080'), URI("ftp://192.0.2.1/").find_proxy)
+ }
+ with_env('REQUEST_METHOD'=>'GET') {
+ assert_nil(URI("http://192.0.2.1/").find_proxy)
+ }
+ with_env('CGI_HTTP_PROXY'=>'http://127.0.0.1:8080', 'REQUEST_METHOD'=>'GET') {
+ assert_equal(URI('http://127.0.0.1:8080'), URI("http://192.0.2.1/").find_proxy)
+ }
+ with_env('http_proxy'=>'http://127.0.0.1:8080', 'no_proxy'=>'192.0.2.2') {
+ assert_equal(URI('http://127.0.0.1:8080'), URI("http://192.0.2.1/").find_proxy)
+ assert_nil(URI("http://192.0.2.2/").find_proxy)
+ }
+ end
+
+ def test_find_proxy_case_sensitive_env
+ skip "environment variable name is not case sensitive on Windows" if RUBY_PLATFORM =~ /mswin|mingw/
+ with_env('http_proxy'=>'http://127.0.0.1:8080', 'REQUEST_METHOD'=>'GET') {
+ assert_equal(URI('http://127.0.0.1:8080'), URI("http://192.0.2.1/").find_proxy)
+ }
+ with_env('HTTP_PROXY'=>'http://127.0.0.1:8081', 'REQUEST_METHOD'=>'GET') {
+ assert_nil(nil, URI("http://192.0.2.1/").find_proxy)
+ }
+ with_env('http_proxy'=>'http://127.0.0.1:8080', 'HTTP_PROXY'=>'http://127.0.0.1:8081', 'REQUEST_METHOD'=>'GET') {
+ assert_equal(URI('http://127.0.0.1:8080'), URI("http://192.0.2.1/").find_proxy)
+ }
+ end
+
+ def test_ftp_invalid_request
+ assert_raise(ArgumentError) { URI("ftp://127.0.0.1/").read }
+ assert_raise(ArgumentError) { URI("ftp://127.0.0.1/a%0Db").read }
+ assert_raise(ArgumentError) { URI("ftp://127.0.0.1/a%0Ab").read }
+ assert_raise(ArgumentError) { URI("ftp://127.0.0.1/a%0Db/f").read }
+ assert_raise(ArgumentError) { URI("ftp://127.0.0.1/a%0Ab/f").read }
+ assert_raise(URI::InvalidComponentError) { URI("ftp://127.0.0.1/d/f;type=x") }
+ end
+
+ def test_ftp
+ TCPServer.open("127.0.0.1", 0) {|serv|
+ _, port, _, host = serv.addr
+ th = Thread.new {
+ s = serv.accept
+ begin
+ s.print "220 Test FTP Server\r\n"
+ assert_equal("USER anonymous\r\n", s.gets); s.print "331 name ok\r\n"
+ assert_match(/\APASS .*\r\n\z/, s.gets); s.print "230 logged in\r\n"
+ assert_equal("TYPE I\r\n", s.gets); s.print "200 type set to I\r\n"
+ assert_equal("CWD foo\r\n", s.gets); s.print "250 CWD successful\r\n"
+ assert_equal("PASV\r\n", s.gets)
+ TCPServer.open("127.0.0.1", 0) {|data_serv|
+ _, data_serv_port, _, data_serv_host = data_serv.addr
+ hi = data_serv_port >> 8
+ lo = data_serv_port & 0xff
+ s.print "227 Entering Passive Mode (127,0,0,1,#{hi},#{lo}).\r\n"
+ assert_equal("RETR bar\r\n", s.gets); s.print "150 file okay\r\n"
+ data_sock = data_serv.accept
+ begin
+ data_sock << "content"
+ ensure
+ data_sock.close
+ end
+ s.print "226 transfer complete\r\n"
+ assert_nil(s.gets)
+ }
+ ensure
+ s.close if s
+ end
+ }
+ begin
+ content = URI("ftp://#{host}:#{port}/foo/bar").read
+ assert_equal("content", content)
+ ensure
+ Thread.kill(th)
+ th.join
+ end
+ }
+ end
+
+ def test_ftp_active
+ TCPServer.open("127.0.0.1", 0) {|serv|
+ _, port, _, host = serv.addr
+ th = Thread.new {
+ s = serv.accept
+ begin
+ content = "content"
+ s.print "220 Test FTP Server\r\n"
+ assert_equal("USER anonymous\r\n", s.gets); s.print "331 name ok\r\n"
+ assert_match(/\APASS .*\r\n\z/, s.gets); s.print "230 logged in\r\n"
+ assert_equal("TYPE I\r\n", s.gets); s.print "200 type set to I\r\n"
+ assert_equal("CWD foo\r\n", s.gets); s.print "250 CWD successful\r\n"
+ assert(m = /\APORT 127,0,0,1,(\d+),(\d+)\r\n\z/.match(s.gets))
+ active_port = m[1].to_i << 8 | m[2].to_i
+ TCPSocket.open("127.0.0.1", active_port) {|data_sock|
+ s.print "200 data connection opened\r\n"
+ assert_equal("RETR bar\r\n", s.gets); s.print "150 file okay\r\n"
+ begin
+ data_sock << content
+ ensure
+ data_sock.close
+ end
+ s.print "226 transfer complete\r\n"
+ assert_nil(s.gets)
+ }
+ ensure
+ s.close if s
+ end
+ }
+ begin
+ content = URI("ftp://#{host}:#{port}/foo/bar").read(:ftp_active_mode=>true)
+ assert_equal("content", content)
+ ensure
+ Thread.kill(th)
+ th.join
+ end
+ }
+ end
+
+ def test_ftp_ascii
+ TCPServer.open("127.0.0.1", 0) {|serv|
+ _, port, _, host = serv.addr
+ th = Thread.new {
+ s = serv.accept
+ begin
+ content = "content"
+ s.print "220 Test FTP Server\r\n"
+ assert_equal("USER anonymous\r\n", s.gets); s.print "331 name ok\r\n"
+ assert_match(/\APASS .*\r\n\z/, s.gets); s.print "230 logged in\r\n"
+ assert_equal("TYPE I\r\n", s.gets); s.print "200 type set to I\r\n"
+ assert_equal("CWD /foo\r\n", s.gets); s.print "250 CWD successful\r\n"
+ assert_equal("TYPE A\r\n", s.gets); s.print "200 type set to A\r\n"
+ assert_equal("SIZE bar\r\n", s.gets); s.print "213 #{content.bytesize}\r\n"
+ assert_equal("PASV\r\n", s.gets)
+ TCPServer.open("127.0.0.1", 0) {|data_serv|
+ _, data_serv_port, _, data_serv_host = data_serv.addr
+ hi = data_serv_port >> 8
+ lo = data_serv_port & 0xff
+ s.print "227 Entering Passive Mode (127,0,0,1,#{hi},#{lo}).\r\n"
+ assert_equal("RETR bar\r\n", s.gets); s.print "150 file okay\r\n"
+ data_sock = data_serv.accept
+ begin
+ data_sock << content
+ ensure
+ data_sock.close
+ end
+ s.print "226 transfer complete\r\n"
+ assert_nil(s.gets)
+ }
+ ensure
+ s.close if s
+ end
+ }
+ begin
+ length = []
+ progress = []
+ content = URI("ftp://#{host}:#{port}/%2Ffoo/b%61r;type=a").read(
+ :content_length_proc => lambda {|n| length << n },
+ :progress_proc => lambda {|n| progress << n })
+ assert_equal("content", content)
+ assert_equal([7], length)
+ assert_equal(7, progress.inject(&:+))
+ ensure
+ Thread.kill(th)
+ th.join
+ end
+ }
+ end
+
+ def test_ftp_over_http_proxy
+ TCPServer.open("127.0.0.1", 0) {|proxy_serv|
+ proxy_port = proxy_serv.addr[1]
+ th = Thread.new {
+ proxy_sock = proxy_serv.accept
+ begin
+ req = proxy_sock.gets("\r\n\r\n")
+ assert_match(%r{\AGET ftp://192.0.2.1/foo/bar }, req)
+ proxy_sock.print "HTTP/1.0 200 OK\r\n"
+ proxy_sock.print "Content-Length: 4\r\n\r\n"
+ proxy_sock.print "ab\r\n"
+ ensure
+ proxy_sock.close
+ end
+ }
+ begin
+ with_env('ftp_proxy'=>"http://127.0.0.1:#{proxy_port}") {
+ content = URI("ftp://192.0.2.1/foo/bar").read
+ assert_equal("ab\r\n", content)
+ }
+ ensure
+ Thread.kill(th)
+ th.join
+ end
+ }
+ end
+
+ def test_ftp_over_http_proxy_auth
+ TCPServer.open("127.0.0.1", 0) {|proxy_serv|
+ proxy_port = proxy_serv.addr[1]
+ th = Thread.new {
+ proxy_sock = proxy_serv.accept
+ begin
+ req = proxy_sock.gets("\r\n\r\n")
+ assert_match(%r{\AGET ftp://192.0.2.1/foo/bar }, req)
+ assert_match(%r{Proxy-Authorization: Basic #{['proxy-user:proxy-password'].pack('m').chomp}\r\n}, req)
+ proxy_sock.print "HTTP/1.0 200 OK\r\n"
+ proxy_sock.print "Content-Length: 4\r\n\r\n"
+ proxy_sock.print "ab\r\n"
+ ensure
+ proxy_sock.close
+ end
+ }
+ begin
+ content = URI("ftp://192.0.2.1/foo/bar").read(
+ :proxy_http_basic_authentication => ["http://127.0.0.1:#{proxy_port}", "proxy-user", "proxy-password"])
+ assert_equal("ab\r\n", content)
+ ensure
+ Thread.kill(th)
+ th.join
+ end
+ }
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/open-uri/test_ssl.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/open-uri/test_ssl.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/open-uri/test_ssl.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,314 @@
+require 'test/unit'
+require 'open-uri'
+require 'openssl'
+require 'stringio'
+require 'webrick'
+require 'webrick/https'
+require 'webrick/httpproxy'
+
+class TestOpenURISSL < Test::Unit::TestCase
+
+ NullLog = Object.new
+ def NullLog.<<(arg)
+ end
+
+ def with_https
+ Dir.mktmpdir {|dr|
+ srv = WEBrick::HTTPServer.new({
+ :DocumentRoot => dr,
+ :ServerType => Thread,
+ :Logger => WEBrick::Log.new(NullLog),
+ :AccessLog => [[NullLog, ""]],
+ :SSLEnable => true,
+ :SSLCertificate => OpenSSL::X509::Certificate.new(SERVER_CERT),
+ :SSLPrivateKey => OpenSSL::PKey::RSA.new(SERVER_KEY),
+ :BindAddress => '127.0.0.1',
+ :Port => 0})
+ _, port, _, host = srv.listeners[0].addr
+ begin
+ th = srv.start
+ yield srv, dr, "https://#{host}:#{port}"
+ ensure
+ srv.shutdown
+ end
+ }
+ end
+
+ def setup
+ @proxies = %w[http_proxy HTTP_PROXY https_proxy HTTPS_PROXY ftp_proxy FTP_PROXY no_proxy]
+ @old_proxies = @proxies.map {|k| ENV[k] }
+ @proxies.each {|k| ENV[k] = nil }
+ end
+
+ def teardown
+ @proxies.each_with_index {|k, i| ENV[k] = @old_proxies[i] }
+ end
+
+ def test_validation
+ with_https {|srv, dr, url|
+ cacert_filename = "#{dr}/cacert.pem"
+ open(cacert_filename, "w") {|f| f << CA_CERT }
+ open("#{dr}/data", "w") {|f| f << "ddd" }
+ open("#{url}/data", :ssl_ca_cert => cacert_filename) {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("ddd", f.read)
+ }
+ open("#{url}/data", :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE) {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("ddd", f.read)
+ }
+ assert_raise(OpenSSL::SSL::SSLError) { open("#{url}/data") {} }
+ }
+ end
+
+ def test_proxy
+ with_https {|srv, dr, url|
+ cacert_filename = "#{dr}/cacert.pem"
+ open(cacert_filename, "w") {|f| f << CA_CERT }
+ cacert_directory = "#{dr}/certs"
+ Dir.mkdir cacert_directory
+ hashed_name = "%08x.0" % OpenSSL::X509::Certificate.new(CA_CERT).subject.hash
+ open("#{cacert_directory}/#{hashed_name}", "w") {|f| f << CA_CERT }
+ prxy = WEBrick::HTTPProxyServer.new({
+ :ServerType => Thread,
+ :Logger => WEBrick::Log.new(NullLog),
+ :AccessLog => [[sio=StringIO.new, WEBrick::AccessLog::COMMON_LOG_FORMAT]],
+ :BindAddress => '127.0.0.1',
+ :Port => 0})
+ _, p_port, _, p_host = prxy.listeners[0].addr
+ begin
+ th = prxy.start
+ open("#{dr}/proxy", "w") {|f| f << "proxy" }
+ open("#{url}/proxy", :proxy=>"http://#{p_host}:#{p_port}/", :ssl_ca_cert => cacert_filename) {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("proxy", f.read)
+ }
+ assert_match(%r[CONNECT #{url.sub(%r{\Ahttps://}, '')} ], sio.string)
+ sio.truncate(0); sio.rewind
+ open("#{url}/proxy", :proxy=>"http://#{p_host}:#{p_port}/", :ssl_ca_cert => cacert_directory) {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("proxy", f.read)
+ }
+ assert_match(%r[CONNECT #{url.sub(%r{\Ahttps://}, '')} ], sio.string)
+ sio.truncate(0); sio.rewind
+ ensure
+ prxy.shutdown
+ end
+ }
+ end
+
+end
+
+# mkdir demoCA demoCA/private demoCA/newcerts
+# touch demoCA/index.txt
+# echo 00 > demoCA/serial
+# openssl req -new -keyout demoCA/private/cakey.pem -out demoCA/careq.pem
+# openssl ca -out demoCA/cacert.pem -startdate 090101000000Z -enddate 491231235959Z -batch -keyfile demoCA/private/cakey.pem -selfsign -infiles demoCA/careq.pem
+
+# cp /etc/ssl/openssl.cnf openssl-server.cnf # Debian
+# vi openssl-server.cnf # enable "nsCertType = server"
+# mkdir server
+# openssl genrsa -des3 -out server/server.key 1024
+# openssl rsa -in server/server.key -out server/servernopass.key
+# openssl req -new -days 365 -key server/servernopass.key -out server/csr.pem
+# openssl ca -config openssl-server.cnf -startdate 090101000000Z -enddate 491231235959Z -in server/csr.pem -keyfile demoCA/private/cakey.pem -cert demoCA/cacert.pem -out server/cert.pem
+
+# demoCA/cacert.pem => TestOpenURISSL::CA_CERT
+# server/cert.pem => TestOpenURISSL::SERVER_CERT
+# server/servernopass.key => TestOpenURISSL::SERVER_KEY
+
+TestOpenURISSL::CA_CERT = <<'End'
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 0 (0x0)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=JP, ST=Tokyo, O=RubyTest, CN=Ruby Test CA
+ Validity
+ Not Before: Jan 1 00:00:00 2009 GMT
+ Not After : Dec 31 23:59:59 2049 GMT
+ Subject: C=JP, ST=Tokyo, O=RubyTest, CN=Ruby Test CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:9f:58:19:39:bc:ea:0c:b8:c3:5d:12:a7:d8:20:
+ 6c:53:ac:91:34:c8:b4:db:3f:56:f6:75:b6:6c:23:
+ 80:23:6a:5f:b3:f6:9a:3e:00:b4:16:19:1c:9c:2c:
+ 8d:e8:53:d5:0b:f1:52:3f:7b:60:93:86:ae:89:ab:
+ 20:82:9a:b6:72:14:3c:4d:a9:0b:6c:34:79:9e:d3:
+ 14:82:6d:c9:3b:90:d9:5e:68:6f:8c:b5:d8:09:f4:
+ 6f:3b:22:9f:5e:81:9c:37:df:cf:90:36:65:57:dc:
+ ad:31:ca:8b:48:92:a7:3c:1e:42:e9:1c:4e:1e:cb:
+ 36:c1:44:4e:ab:9a:b2:73:6d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 24:6F:03:A3:EE:06:51:75:B2:BA:FC:3A:38:59:BF:ED:87:CD:E8:7F
+ X509v3 Authority Key Identifier:
+ keyid:24:6F:03:A3:EE:06:51:75:B2:BA:FC:3A:38:59:BF:ED:87:CD:E8:7F
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 13:eb:db:ca:cd:90:f2:09:9e:d9:72:70:5e:42:5d:11:84:ce:
+ 00:1d:c4:2f:41:d2:3e:16:e5:d4:97:1f:43:a9:a7:9c:fa:60:
+ c4:35:96:f2:f6:0d:13:6d:0f:36:dd:59:03:08:ee:2e:a6:df:
+ 9e:d8:6d:ca:72:8f:02:c2:2b:53:7b:12:7f:55:81:6c:9e:7d:
+ e7:40:7e:f8:f5:75:0d:4b:a0:8d:ee:a4:d9:e8:5f:06:c9:86:
+ 66:71:70:6c:41:81:6a:dd:a4:4f:a3:c1:ac:70:d4:78:1b:23:
+ 30:2f:a5:ef:98:ee:d4:62:80:fd:bf:d4:7a:9b:8e:2d:18:e5:
+ 00:46
+-----BEGIN CERTIFICATE-----
+MIICfzCCAeigAwIBAgIBADANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJKUDEO
+MAwGA1UECBMFVG9reW8xETAPBgNVBAoTCFJ1YnlUZXN0MRUwEwYDVQQDEwxSdWJ5
+IFRlc3QgQ0EwHhcNMDkwMTAxMDAwMDAwWhcNNDkxMjMxMjM1OTU5WjBHMQswCQYD
+VQQGEwJKUDEOMAwGA1UECBMFVG9reW8xETAPBgNVBAoTCFJ1YnlUZXN0MRUwEwYD
+VQQDEwxSdWJ5IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ9Y
+GTm86gy4w10Sp9ggbFOskTTItNs/VvZ1tmwjgCNqX7P2mj4AtBYZHJwsjehT1Qvx
+Uj97YJOGromrIIKatnIUPE2pC2w0eZ7TFIJtyTuQ2V5ob4y12An0bzsin16BnDff
+z5A2ZVfcrTHKi0iSpzweQukcTh7LNsFETquasnNtAgMBAAGjezB5MAkGA1UdEwQC
+MAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl
+MB0GA1UdDgQWBBQkbwOj7gZRdbK6/Do4Wb/th83ofzAfBgNVHSMEGDAWgBQkbwOj
+7gZRdbK6/Do4Wb/th83ofzANBgkqhkiG9w0BAQUFAAOBgQAT69vKzZDyCZ7ZcnBe
+Ql0RhM4AHcQvQdI+FuXUlx9Dqaec+mDENZby9g0TbQ823VkDCO4upt+e2G3Kco8C
+witTexJ/VYFsnn3nQH749XUNS6CN7qTZ6F8GyYZmcXBsQYFq3aRPo8GscNR4GyMw
+L6XvmO7UYoD9v9R6m44tGOUARg==
+-----END CERTIFICATE-----
+End
+
+TestOpenURISSL::SERVER_CERT = <<'End'
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=JP, ST=Tokyo, O=RubyTest, CN=Ruby Test CA
+ Validity
+ Not Before: Jan 1 00:00:00 2009 GMT
+ Not After : Dec 31 23:59:59 2049 GMT
+ Subject: C=JP, ST=Tokyo, O=RubyTest, CN=127.0.0.1
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:bb:bd:74:69:53:58:50:24:79:f2:eb:db:8b:97:
+ e4:69:a4:dd:48:0c:40:35:62:42:b3:35:8c:96:2a:
+ 62:76:98:b5:2a:e0:f8:78:33:b6:ff:f8:55:bf:44:
+ 69:21:d7:b5:0e:bd:8a:dd:31:1b:88:d5:b4:5e:7a:
+ 82:e0:ba:99:6c:04:76:e9:ff:e6:f8:f5:06:8e:7e:
+ a4:db:db:eb:43:44:12:a7:ca:ca:2b:aa:5f:83:10:
+ e2:9e:35:55:e8:e8:af:be:c8:7d:bb:c2:d4:aa:c1:
+ 1c:57:0b:c0:0c:3a:1d:6e:23:a9:03:26:7c:ea:8c:
+ f0:86:61:ce:f1:ff:42:c7:23
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Cert Type:
+ SSL Server
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 7F:17:5A:58:88:96:E1:1F:44:EA:FF:AD:C6:2E:90:E2:95:32:DD:F0
+ X509v3 Authority Key Identifier:
+ keyid:24:6F:03:A3:EE:06:51:75:B2:BA:FC:3A:38:59:BF:ED:87:CD:E8:7F
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 9a:34:99:ea:76:a2:ed:f0:f7:a7:75:3b:81:fb:75:57:93:c1:
+ 27:b6:1e:7a:38:67:95:be:58:42:9a:0a:dd:2b:23:fb:85:42:
+ 80:34:bf:b9:0e:9c:5e:5a:dc:2d:25:8c:68:02:a2:c7:7f:c0:
+ eb:f3:e0:61:e2:05:e5:7e:c1:e0:33:1c:76:65:23:2c:25:08:
+ f6:5a:11:b9:d4:f7:e3:80:bb:b0:ce:76:1a:56:22:af:e2:4a:
+ e1:7e:a4:60:f3:fd:9c:53:46:51:57:32:6b:05:53:80:5c:a5:
+ 61:93:87:ae:06:a8:a2:ba:4d:a1:b7:1b:0f:8f:82:0a:e8:b3:
+ ea:63
+-----BEGIN CERTIFICATE-----
+MIICkTCCAfqgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJKUDEO
+MAwGA1UECBMFVG9reW8xETAPBgNVBAoTCFJ1YnlUZXN0MRUwEwYDVQQDEwxSdWJ5
+IFRlc3QgQ0EwHhcNMDkwMTAxMDAwMDAwWhcNNDkxMjMxMjM1OTU5WjBEMQswCQYD
+VQQGEwJKUDEOMAwGA1UECBMFVG9reW8xETAPBgNVBAoTCFJ1YnlUZXN0MRIwEAYD
+VQQDEwkxMjcuMC4wLjEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALu9dGlT
+WFAkefLr24uX5Gmk3UgMQDViQrM1jJYqYnaYtSrg+Hgztv/4Vb9EaSHXtQ69it0x
+G4jVtF56guC6mWwEdun/5vj1Bo5+pNvb60NEEqfKyiuqX4MQ4p41Vejor77IfbvC
+1KrBHFcLwAw6HW4jqQMmfOqM8IZhzvH/QscjAgMBAAGjgY8wgYwwCQYDVR0TBAIw
+ADARBglghkgBhvhCAQEEBAMCBkAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2Vu
+ZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBR/F1pYiJbhH0Tq/63GLpDilTLd
+8DAfBgNVHSMEGDAWgBQkbwOj7gZRdbK6/Do4Wb/th83ofzANBgkqhkiG9w0BAQUF
+AAOBgQCaNJnqdqLt8PendTuB+3VXk8Enth56OGeVvlhCmgrdKyP7hUKANL+5Dpxe
+WtwtJYxoAqLHf8Dr8+Bh4gXlfsHgMxx2ZSMsJQj2WhG51PfjgLuwznYaViKv4krh
+fqRg8/2cU0ZRVzJrBVOAXKVhk4euBqiiuk2htxsPj4IK6LPqYw==
+-----END CERTIFICATE-----
+End
+
+TestOpenURISSL::SERVER_KEY = <<'End'
+Private-Key: (1024 bit)
+modulus:
+ 00:bb:bd:74:69:53:58:50:24:79:f2:eb:db:8b:97:
+ e4:69:a4:dd:48:0c:40:35:62:42:b3:35:8c:96:2a:
+ 62:76:98:b5:2a:e0:f8:78:33:b6:ff:f8:55:bf:44:
+ 69:21:d7:b5:0e:bd:8a:dd:31:1b:88:d5:b4:5e:7a:
+ 82:e0:ba:99:6c:04:76:e9:ff:e6:f8:f5:06:8e:7e:
+ a4:db:db:eb:43:44:12:a7:ca:ca:2b:aa:5f:83:10:
+ e2:9e:35:55:e8:e8:af:be:c8:7d:bb:c2:d4:aa:c1:
+ 1c:57:0b:c0:0c:3a:1d:6e:23:a9:03:26:7c:ea:8c:
+ f0:86:61:ce:f1:ff:42:c7:23
+publicExponent: 65537 (0x10001)
+privateExponent:
+ 00:af:3a:ec:17:0a:f5:d9:07:d2:d3:4c:15:c5:3b:
+ 66:b4:bc:6e:d5:ba:a9:8b:aa:45:3b:63:f5:ee:8b:
+ 6d:0f:e9:04:e0:1a:cf:8f:d2:25:32:d1:a5:a7:3a:
+ c1:2e:17:5a:25:82:00:c4:e7:fb:1d:42:ea:71:6c:
+ c4:0f:e1:db:23:ff:1e:d6:c8:d6:60:ca:2d:06:fc:
+ 54:3c:03:d4:09:96:bb:38:7a:22:a1:61:2c:f7:d0:
+ d0:90:6c:9f:61:ba:61:30:5a:aa:64:ad:43:3a:53:
+ 38:e8:ba:cc:8c:51:3e:68:3e:3a:6a:0f:5d:5d:e0:
+ d6:df:f2:54:93:d3:14:22:a1
+prime1:
+ 00:e8:ec:11:fe:e6:2b:23:21:29:d5:40:a6:11:ec:
+ 4c:ae:4d:08:2a:71:18:ac:d1:3e:40:2f:12:41:59:
+ 12:09:e2:f7:c2:d7:6b:0a:96:0a:06:e3:90:6a:4e:
+ b2:eb:25:b7:09:68:e9:13:ab:d0:5a:29:7a:e4:72:
+ 1a:ee:46:a0:8b
+prime2:
+ 00:ce:57:5e:31:e9:c9:a8:5b:1f:55:af:67:e2:49:
+ 2a:af:90:b6:02:c0:32:2f:ca:ae:1e:de:47:81:73:
+ a8:f8:37:53:70:93:24:62:77:d4:b8:80:30:9f:65:
+ 26:20:46:ae:5a:65:6e:6d:af:68:4c:8d:e8:3c:f3:
+ d1:d1:d9:6e:c9
+exponent1:
+ 03:f1:02:b8:f2:82:26:5d:08:4d:30:83:de:e7:c5:
+ c0:69:53:4b:0c:90:e3:53:c3:1e:e8:ed:01:28:15:
+ b3:0f:21:2c:2d:e3:04:d1:d7:27:98:b0:37:ec:4f:
+ 00:c5:a9:9c:42:27:37:8a:ff:c2:96:d3:1a:8c:87:
+ c2:22:75:d3
+exponent2:
+ 6f:17:32:ab:84:c7:01:51:2d:e9:9f:ea:3a:36:52:
+ 38:fb:9c:42:96:df:6e:43:9c:c3:19:c1:3d:bc:db:
+ 77:e7:b1:90:a6:67:ac:6b:ff:a6:e5:bd:47:d3:d9:
+ 56:ff:36:d7:8c:4c:8b:d9:28:3a:2f:1c:9d:d4:57:
+ 5e:b7:c5:a1
+coefficient:
+ 45:50:47:66:56:e9:21:d9:40:0e:af:3f:f2:05:77:
+ ab:e7:08:40:97:88:2a:51:b3:7e:86:b0:b2:03:2e:
+ 6d:36:3f:46:42:97:7d:5a:a2:93:6c:05:c2:8b:8b:
+ 2d:af:d5:7d:75:e9:70:f0:2d:21:e3:b9:cf:4d:9a:
+ c4:97:e2:79
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQC7vXRpU1hQJHny69uLl+RppN1IDEA1YkKzNYyWKmJ2mLUq4Ph4
+M7b/+FW/RGkh17UOvYrdMRuI1bReeoLguplsBHbp/+b49QaOfqTb2+tDRBKnysor
+ql+DEOKeNVXo6K++yH27wtSqwRxXC8AMOh1uI6kDJnzqjPCGYc7x/0LHIwIDAQAB
+AoGBAK867BcK9dkH0tNMFcU7ZrS8btW6qYuqRTtj9e6LbQ/pBOAaz4/SJTLRpac6
+wS4XWiWCAMTn+x1C6nFsxA/h2yP/HtbI1mDKLQb8VDwD1AmWuzh6IqFhLPfQ0JBs
+n2G6YTBaqmStQzpTOOi6zIxRPmg+OmoPXV3g1t/yVJPTFCKhAkEA6OwR/uYrIyEp
+1UCmEexMrk0IKnEYrNE+QC8SQVkSCeL3wtdrCpYKBuOQak6y6yW3CWjpE6vQWil6
+5HIa7kagiwJBAM5XXjHpyahbH1WvZ+JJKq+QtgLAMi/Krh7eR4FzqPg3U3CTJGJ3
+1LiAMJ9lJiBGrlplbm2vaEyN6Dzz0dHZbskCQAPxArjygiZdCE0wg97nxcBpU0sM
+kONTwx7o7QEoFbMPISwt4wTR1yeYsDfsTwDFqZxCJzeK/8KW0xqMh8IiddMCQG8X
+MquExwFRLemf6jo2Ujj7nEKW325DnMMZwT2823fnsZCmZ6xr/6blvUfT2Vb/NteM
+TIvZKDovHJ3UV163xaECQEVQR2ZW6SHZQA6vP/IFd6vnCECXiCpRs36GsLIDLm02
+P0ZCl31aopNsBcKLiy2v1X116XDwLSHjuc9NmsSX4nk=
+-----END RSA PRIVATE KEY-----
+End
Added: MacRuby/trunk/test/test-mri/test/openssl/ssl_server.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/ssl_server.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/ssl_server.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,81 @@
+require "socket"
+require "thread"
+require "openssl"
+require File.join(File.dirname(__FILE__), "utils.rb")
+
+def get_pem(io=$stdin)
+ buf = ""
+ while line = io.gets
+ if /^-----BEGIN / =~ line
+ buf << line
+ break
+ end
+ end
+ while line = io.gets
+ buf << line
+ if /^-----END / =~ line
+ break
+ end
+ end
+ return buf
+end
+
+def make_key(pem)
+ begin
+ return OpenSSL::PKey::RSA.new(pem)
+ rescue
+ return OpenSSL::PKey::DSA.new(pem)
+ end
+end
+
+ca_cert = OpenSSL::X509::Certificate.new(get_pem)
+ssl_cert = OpenSSL::X509::Certificate.new(get_pem)
+ssl_key = make_key(get_pem)
+port = Integer(ARGV.shift)
+verify_mode = Integer(ARGV.shift)
+start_immediately = (/yes/ =~ ARGV.shift)
+
+store = OpenSSL::X509::Store.new
+store.add_cert(ca_cert)
+store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
+ctx = OpenSSL::SSL::SSLContext.new
+ctx.cert_store = store
+#ctx.extra_chain_cert = [ ca_cert ]
+ctx.cert = ssl_cert
+ctx.key = ssl_key
+ctx.verify_mode = verify_mode
+
+Socket.do_not_reverse_lookup = true
+tcps = nil
+100.times{|i|
+ begin
+ tcps = TCPServer.new("0.0.0.0", port+i)
+ port = port + i
+ break
+ rescue Errno::EADDRINUSE
+ next
+ end
+}
+ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
+ssls.start_immediately = start_immediately
+
+$stdout.sync = true
+$stdout.puts Process.pid
+$stdout.puts port
+
+loop do
+ ssl = ssls.accept rescue next
+ Thread.start{
+ q = Queue.new
+ th = Thread.start{ ssl.write(q.shift) while true }
+ while line = ssl.gets
+ if line =~ /^STARTTLS$/
+ ssl.accept
+ next
+ end
+ q.push(line)
+ end
+ th.kill if q.empty?
+ ssl.close
+ }
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_asn1.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_asn1.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_asn1.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,197 @@
+begin
+ require "openssl"
+ require_relative 'utils'
+rescue LoadError
+end
+require 'test/unit'
+
+class OpenSSL::TestASN1 < Test::Unit::TestCase
+ def test_decode
+ subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA")
+ key = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ now = Time.at(Time.now.to_i) # suppress usec
+ s = 0xdeadbeafdeadbeafdeadbeafdeadbeaf
+ exts = [
+ ["basicConstraints","CA:TRUE,pathlen:1",true],
+ ["keyUsage","keyCertSign, cRLSign",true],
+ ["subjectKeyIdentifier","hash",false],
+ ]
+ dgst = OpenSSL::Digest::SHA1.new
+ cert = OpenSSL::TestUtils.issue_cert(
+ subj, key, s, now, now+3600, exts, nil, nil, dgst)
+
+
+ asn1 = OpenSSL::ASN1.decode(cert)
+ assert_equal(OpenSSL::ASN1::Sequence, asn1.class)
+ assert_equal(3, asn1.value.size)
+ tbs_cert, sig_alg, sig_val = *asn1.value
+
+ assert_equal(OpenSSL::ASN1::Sequence, tbs_cert.class)
+ assert_equal(8, tbs_cert.value.size)
+
+ version = tbs_cert.value[0]
+ assert_equal(:CONTEXT_SPECIFIC, version.tag_class)
+ assert_equal(0, version.tag)
+ assert_equal(1, version.value.size)
+ assert_equal(OpenSSL::ASN1::Integer, version.value[0].class)
+ assert_equal(2, version.value[0].value)
+
+ serial = tbs_cert.value[1]
+ assert_equal(OpenSSL::ASN1::Integer, serial.class)
+ assert_equal(0xdeadbeafdeadbeafdeadbeafdeadbeaf, serial.value)
+
+ sig = tbs_cert.value[2]
+ assert_equal(OpenSSL::ASN1::Sequence, sig.class)
+ assert_equal(2, sig.value.size)
+ assert_equal(OpenSSL::ASN1::ObjectId, sig.value[0].class)
+ assert_equal("1.2.840.113549.1.1.5", sig.value[0].oid)
+ assert_equal(OpenSSL::ASN1::Null, sig.value[1].class)
+
+ dn = tbs_cert.value[3] # issuer
+ assert_equal(subj.hash, OpenSSL::X509::Name.new(dn).hash)
+ assert_equal(OpenSSL::ASN1::Sequence, dn.class)
+ assert_equal(3, dn.value.size)
+ assert_equal(OpenSSL::ASN1::Set, dn.value[0].class)
+ assert_equal(OpenSSL::ASN1::Set, dn.value[1].class)
+ assert_equal(OpenSSL::ASN1::Set, dn.value[2].class)
+ assert_equal(1, dn.value[0].value.size)
+ assert_equal(1, dn.value[1].value.size)
+ assert_equal(1, dn.value[2].value.size)
+ assert_equal(OpenSSL::ASN1::Sequence, dn.value[0].value[0].class)
+ assert_equal(OpenSSL::ASN1::Sequence, dn.value[1].value[0].class)
+ assert_equal(OpenSSL::ASN1::Sequence, dn.value[2].value[0].class)
+ assert_equal(2, dn.value[0].value[0].value.size)
+ assert_equal(2, dn.value[1].value[0].value.size)
+ assert_equal(2, dn.value[2].value[0].value.size)
+ oid, value = *dn.value[0].value[0].value
+ assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
+ assert_equal("0.9.2342.19200300.100.1.25", oid.oid)
+ assert_equal(OpenSSL::ASN1::IA5String, value.class)
+ assert_equal("org", value.value)
+ oid, value = *dn.value[1].value[0].value
+ assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
+ assert_equal("0.9.2342.19200300.100.1.25", oid.oid)
+ assert_equal(OpenSSL::ASN1::IA5String, value.class)
+ assert_equal("ruby-lang", value.value)
+ oid, value = *dn.value[2].value[0].value
+ assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
+ assert_equal("2.5.4.3", oid.oid)
+ assert_equal(OpenSSL::ASN1::UTF8String, value.class)
+ assert_equal("TestCA", value.value)
+
+ validity = tbs_cert.value[4]
+ assert_equal(OpenSSL::ASN1::Sequence, validity.class)
+ assert_equal(2, validity.value.size)
+ assert_equal(OpenSSL::ASN1::UTCTime, validity.value[0].class)
+ assert_equal(now, validity.value[0].value)
+ assert_equal(OpenSSL::ASN1::UTCTime, validity.value[1].class)
+ assert_equal(now+3600, validity.value[1].value)
+
+ dn = tbs_cert.value[5] # subject
+ assert_equal(subj.hash, OpenSSL::X509::Name.new(dn).hash)
+ assert_equal(OpenSSL::ASN1::Sequence, dn.class)
+ assert_equal(3, dn.value.size)
+ assert_equal(OpenSSL::ASN1::Set, dn.value[0].class)
+ assert_equal(OpenSSL::ASN1::Set, dn.value[1].class)
+ assert_equal(OpenSSL::ASN1::Set, dn.value[2].class)
+ assert_equal(1, dn.value[0].value.size)
+ assert_equal(1, dn.value[1].value.size)
+ assert_equal(1, dn.value[2].value.size)
+ assert_equal(OpenSSL::ASN1::Sequence, dn.value[0].value[0].class)
+ assert_equal(OpenSSL::ASN1::Sequence, dn.value[1].value[0].class)
+ assert_equal(OpenSSL::ASN1::Sequence, dn.value[2].value[0].class)
+ assert_equal(2, dn.value[0].value[0].value.size)
+ assert_equal(2, dn.value[1].value[0].value.size)
+ assert_equal(2, dn.value[2].value[0].value.size)
+ oid, value = *dn.value[0].value[0].value
+ assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
+ assert_equal("0.9.2342.19200300.100.1.25", oid.oid)
+ assert_equal(OpenSSL::ASN1::IA5String, value.class)
+ assert_equal("org", value.value)
+ oid, value = *dn.value[1].value[0].value
+ assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
+ assert_equal("0.9.2342.19200300.100.1.25", oid.oid)
+ assert_equal(OpenSSL::ASN1::IA5String, value.class)
+ assert_equal("ruby-lang", value.value)
+ oid, value = *dn.value[2].value[0].value
+ assert_equal(OpenSSL::ASN1::ObjectId, oid.class)
+ assert_equal("2.5.4.3", oid.oid)
+ assert_equal(OpenSSL::ASN1::UTF8String, value.class)
+ assert_equal("TestCA", value.value)
+
+ pkey = tbs_cert.value[6]
+ assert_equal(OpenSSL::ASN1::Sequence, pkey.class)
+ assert_equal(2, pkey.value.size)
+ assert_equal(OpenSSL::ASN1::Sequence, pkey.value[0].class)
+ assert_equal(2, pkey.value[0].value.size)
+ assert_equal(OpenSSL::ASN1::ObjectId, pkey.value[0].value[0].class)
+ assert_equal("1.2.840.113549.1.1.1", pkey.value[0].value[0].oid)
+ assert_equal(OpenSSL::ASN1::BitString, pkey.value[1].class)
+ assert_equal(0, pkey.value[1].unused_bits)
+ spkey = OpenSSL::ASN1.decode(pkey.value[1].value)
+ assert_equal(OpenSSL::ASN1::Sequence, spkey.class)
+ assert_equal(2, spkey.value.size)
+ assert_equal(OpenSSL::ASN1::Integer, spkey.value[0].class)
+ assert_equal(143085709396403084580358323862163416700436550432664688288860593156058579474547937626086626045206357324274536445865308750491138538454154232826011964045825759324933943290377903384882276841880081931690695505836279972214003660451338124170055999155993192881685495391496854691199517389593073052473319331505702779271, spkey.value[0].value)
+ assert_equal(OpenSSL::ASN1::Integer, spkey.value[1].class)
+ assert_equal(65537, spkey.value[1].value)
+
+ extensions = tbs_cert.value[7]
+ assert_equal(:CONTEXT_SPECIFIC, extensions.tag_class)
+ assert_equal(3, extensions.tag)
+ assert_equal(1, extensions.value.size)
+ assert_equal(OpenSSL::ASN1::Sequence, extensions.value[0].class)
+ assert_equal(3, extensions.value[0].value.size)
+
+ ext = extensions.value[0].value[0] # basicConstraints
+ assert_equal(OpenSSL::ASN1::Sequence, ext.class)
+ assert_equal(3, ext.value.size)
+ assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)
+ assert_equal("2.5.29.19", ext.value[0].oid)
+ assert_equal(OpenSSL::ASN1::Boolean, ext.value[1].class)
+ assert_equal(true, ext.value[1].value)
+ assert_equal(OpenSSL::ASN1::OctetString, ext.value[2].class)
+ extv = OpenSSL::ASN1.decode(ext.value[2].value)
+ assert_equal(OpenSSL::ASN1::Sequence, extv.class)
+ assert_equal(2, extv.value.size)
+ assert_equal(OpenSSL::ASN1::Boolean, extv.value[0].class)
+ assert_equal(true, extv.value[0].value)
+ assert_equal(OpenSSL::ASN1::Integer, extv.value[1].class)
+ assert_equal(1, extv.value[1].value)
+
+ ext = extensions.value[0].value[1] # keyUsage
+ assert_equal(OpenSSL::ASN1::Sequence, ext.class)
+ assert_equal(3, ext.value.size)
+ assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)
+ assert_equal("2.5.29.15", ext.value[0].oid)
+ assert_equal(OpenSSL::ASN1::Boolean, ext.value[1].class)
+ assert_equal(true, ext.value[1].value)
+ assert_equal(OpenSSL::ASN1::OctetString, ext.value[2].class)
+ extv = OpenSSL::ASN1.decode(ext.value[2].value)
+ assert_equal(OpenSSL::ASN1::BitString, extv.class)
+ str = "\000"; str[0] = 0b00000110.chr
+ assert_equal(str, extv.value)
+
+ ext = extensions.value[0].value[2] # subjetKeyIdentifier
+ assert_equal(OpenSSL::ASN1::Sequence, ext.class)
+ assert_equal(2, ext.value.size)
+ assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)
+ assert_equal("2.5.29.14", ext.value[0].oid)
+ assert_equal(OpenSSL::ASN1::OctetString, ext.value[1].class)
+ extv = OpenSSL::ASN1.decode(ext.value[1].value)
+ assert_equal(OpenSSL::ASN1::OctetString, extv.class)
+ sha1 = OpenSSL::Digest::SHA1.new
+ sha1.update(pkey.value[1].value)
+ assert_equal(sha1.digest, extv.value)
+
+ assert_equal(OpenSSL::ASN1::Sequence, sig_alg.class)
+ assert_equal(2, sig_alg.value.size)
+ assert_equal(OpenSSL::ASN1::ObjectId, pkey.value[0].value[0].class)
+ assert_equal("1.2.840.113549.1.1.1", pkey.value[0].value[0].oid)
+ assert_equal(OpenSSL::ASN1::Null, pkey.value[0].value[1].class)
+
+ assert_equal(OpenSSL::ASN1::BitString, sig_val.class)
+ cululated_sig = key.sign(OpenSSL::Digest::SHA1.new, tbs_cert.to_der)
+ assert_equal(cululated_sig, sig_val.value)
+ end
+end if defined?(OpenSSL)
Added: MacRuby/trunk/test/test-mri/test/openssl/test_cipher.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_cipher.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_cipher.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,95 @@
+begin
+ require "openssl"
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(OpenSSL)
+
+class OpenSSL::TestCipher < Test::Unit::TestCase
+ def setup
+ @c1 = OpenSSL::Cipher::Cipher.new("DES-EDE3-CBC")
+ @c2 = OpenSSL::Cipher::DES.new(:EDE3, "CBC")
+ @key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ @iv = "\0\0\0\0\0\0\0\0"
+ @hexkey = "0000000000000000000000000000000000000000000000"
+ @hexiv = "0000000000000000"
+ @data = "DATA"
+ end
+
+ def teardown
+ @c1 = @c2 = nil
+ end
+
+ def test_crypt
+ @c1.encrypt.pkcs5_keyivgen(@key, @iv)
+ @c2.encrypt.pkcs5_keyivgen(@key, @iv)
+ s1 = @c1.update(@data) + @c1.final
+ s2 = @c2.update(@data) + @c2.final
+ assert_equal(s1, s2, "encrypt")
+
+ @c1.decrypt.pkcs5_keyivgen(@key, @iv)
+ @c2.decrypt.pkcs5_keyivgen(@key, @iv)
+ assert_equal(@data, @c1.update(s1)+ at c1.final, "decrypt")
+ assert_equal(@data, @c2.update(s2)+ at c2.final, "decrypt")
+ end
+
+ def test_info
+ assert_equal("DES-EDE3-CBC", @c1.name, "name")
+ assert_equal("DES-EDE3-CBC", @c2.name, "name")
+ assert_kind_of(Fixnum, @c1.key_len, "key_len")
+ assert_kind_of(Fixnum, @c1.iv_len, "iv_len")
+ end
+
+ def test_dup
+ assert_equal(@c1.name, @c1.dup.name, "dup")
+ assert_equal(@c1.name, @c1.clone.name, "clone")
+ @c1.encrypt
+ @c1.key = @key
+ @c1.iv = @iv
+ tmpc = @c1.dup
+ s1 = @c1.update(@data) + @c1.final
+ s2 = tmpc.update(@data) + tmpc.final
+ assert_equal(s1, s2, "encrypt dup")
+ end
+
+ def test_reset
+ @c1.encrypt
+ @c1.key = @key
+ @c1.iv = @iv
+ s1 = @c1.update(@data) + @c1.final
+ @c1.reset
+ s2 = @c1.update(@data) + @c1.final
+ assert_equal(s1, s2, "encrypt reset")
+ end
+
+ def test_empty_data
+ @c1.encrypt
+ assert_raise(ArgumentError){ @c1.update("") }
+ end
+
+ if OpenSSL::OPENSSL_VERSION_NUMBER > 0x00907000
+ def test_ciphers
+ OpenSSL::Cipher.ciphers.each{|name|
+ assert(OpenSSL::Cipher::Cipher.new(name).is_a?(OpenSSL::Cipher::Cipher))
+ }
+ end
+
+ def test_AES
+ pt = File.read(__FILE__)
+ %w(ECB CBC CFB OFB).each{|mode|
+ c1 = OpenSSL::Cipher::AES256.new(mode)
+ c1.encrypt
+ c1.pkcs5_keyivgen("passwd")
+ ct = c1.update(pt) + c1.final
+
+ c2 = OpenSSL::Cipher::AES256.new(mode)
+ c2.decrypt
+ c2.pkcs5_keyivgen("passwd")
+ assert_equal(pt, c2.update(ct) + c2.final)
+ }
+ end
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_config.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_config.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_config.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,16 @@
+require 'openssl'
+require "test/unit"
+
+class OpenSSL::TestConfig < Test::Unit::TestCase
+ def test_freeze
+ skip "need an argument for OpenSSL::Config.new on Windows" if /mswin|mingw/ =~ RUBY_PLATFORM
+ c = OpenSSL::Config.new
+ c['foo'] = [['key', 'value']]
+ c.freeze
+
+ # [ruby-core:18377]
+ assert_raise(RuntimeError, /frozen/) do
+ c['foo'] = [['key', 'wrong']]
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_digest.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_digest.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_digest.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,88 @@
+begin
+ require "openssl"
+rescue LoadError
+end
+require "digest/md5"
+require "test/unit"
+
+if defined?(OpenSSL)
+
+class OpenSSL::TestDigest < Test::Unit::TestCase
+ def setup
+ @d1 = OpenSSL::Digest::Digest::new("MD5")
+ @d2 = OpenSSL::Digest::MD5.new
+ @md = Digest::MD5.new
+ @data = "DATA"
+ end
+
+ def teardown
+ @d1 = @d2 = @md = nil
+ end
+
+ def test_digest
+ assert_equal(@md.digest, @d1.digest)
+ assert_equal(@md.hexdigest, @d1.hexdigest)
+ @d1 << @data
+ @d2 << @data
+ @md << @data
+ assert_equal(@md.digest, @d1.digest)
+ assert_equal(@md.hexdigest, @d1.hexdigest)
+ assert_equal(@d1.digest, @d2.digest)
+ assert_equal(@d1.hexdigest, @d2.hexdigest)
+ assert_equal(@md.digest, OpenSSL::Digest::MD5.digest(@data))
+ assert_equal(@md.hexdigest, OpenSSL::Digest::MD5.hexdigest(@data))
+ end
+
+ def test_eql
+ assert(@d1 == @d2, "==")
+ d = @d1.clone
+ assert(d == @d1, "clone")
+ end
+
+ def test_info
+ assert_equal("MD5", @d1.name, "name")
+ assert_equal("MD5", @d2.name, "name")
+ assert_equal(16, @d1.size, "size")
+ end
+
+ def test_dup
+ @d1.update(@data)
+ assert_equal(@d1.name, @d1.dup.name, "dup")
+ assert_equal(@d1.name, @d1.clone.name, "clone")
+ assert_equal(@d1.digest, @d1.clone.digest, "clone .digest")
+ end
+
+ def test_reset
+ @d1.update(@data)
+ dig1 = @d1.digest
+ @d1.reset
+ @d1.update(@data)
+ dig2 = @d1.digest
+ assert_equal(dig1, dig2, "reset")
+ end
+
+ if OpenSSL::OPENSSL_VERSION_NUMBER > 0x00908000
+ def encode16(str)
+ str.unpack("H*").first
+ end
+
+ def test_098_features
+ sha224_a = "abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5"
+ sha256_a = "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
+ sha384_a = "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31"
+ sha512_a = "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75"
+
+ assert_equal(sha224_a, OpenSSL::Digest::SHA224.hexdigest("a"))
+ assert_equal(sha256_a, OpenSSL::Digest::SHA256.hexdigest("a"))
+ assert_equal(sha384_a, OpenSSL::Digest::SHA384.hexdigest("a"))
+ assert_equal(sha512_a, OpenSSL::Digest::SHA512.hexdigest("a"))
+
+ assert_equal(sha224_a, encode16(OpenSSL::Digest::SHA224.digest("a")))
+ assert_equal(sha256_a, encode16(OpenSSL::Digest::SHA256.digest("a")))
+ assert_equal(sha384_a, encode16(OpenSSL::Digest::SHA384.digest("a")))
+ assert_equal(sha512_a, encode16(OpenSSL::Digest::SHA512.digest("a")))
+ end
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_ec.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_ec.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_ec.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,128 @@
+begin
+ require "openssl"
+ require File.join(File.dirname(__FILE__), "utils.rb")
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(OpenSSL::PKey::EC)
+
+class OpenSSL::TestEC < Test::Unit::TestCase
+ def setup
+ @data1 = 'foo'
+ @data2 = 'bar' * 1000 # data too long for DSA sig
+
+ @group1 = OpenSSL::PKey::EC::Group.new('secp112r1')
+ @group2 = OpenSSL::PKey::EC::Group.new('sect163k1')
+
+ @key1 = OpenSSL::PKey::EC.new
+ @key1.group = @group1
+ @key1.generate_key
+
+ @key2 = OpenSSL::PKey::EC.new(@group2.curve_name)
+ @key2.generate_key
+
+ @groups = [@group1, @group2]
+ @keys = [@key1, @key2]
+ end
+
+ def compare_keys(k1, k2)
+ assert_equal(k1.to_pem, k2.to_pem)
+ end
+
+ def test_curve_names
+ @groups.each_with_index do |group, idx|
+ key = @keys[idx]
+ assert_equal(group.curve_name, key.group.curve_name)
+ end
+ end
+
+ def test_check_key
+ for key in @keys
+ assert_equal(key.check_key, true)
+ assert_equal(key.private_key?, true)
+ assert_equal(key.public_key?, true)
+ end
+ end
+
+ def test_encoding
+ for group in @groups
+ for meth in [:to_der, :to_pem]
+ txt = group.send(meth)
+ gr = OpenSSL::PKey::EC::Group.new(txt)
+ assert_equal(txt, gr.send(meth))
+
+ assert_equal(group.generator.to_bn, gr.generator.to_bn)
+ assert_equal(group.cofactor, gr.cofactor)
+ assert_equal(group.order, gr.order)
+ assert_equal(group.seed, gr.seed)
+ assert_equal(group.degree, gr.degree)
+ end
+ end
+
+ for key in @keys
+ group = key.group
+
+ for meth in [:to_der, :to_pem]
+ txt = key.send(meth)
+ assert_equal(txt, OpenSSL::PKey::EC.new(txt).send(meth))
+ end
+
+ bn = key.public_key.to_bn
+ assert_equal(bn, OpenSSL::PKey::EC::Point.new(group, bn).to_bn)
+ end
+ end
+
+ def test_set_keys
+ for key in @keys
+ k = OpenSSL::PKey::EC.new
+ k.group = key.group
+ k.private_key = key.private_key
+ k.public_key = key.public_key
+
+ compare_keys(key, k)
+ end
+ end
+
+ def test_dsa_sign_verify
+ for key in @keys
+ sig = key.dsa_sign_asn1(@data1)
+ assert(key.dsa_verify_asn1(@data1, sig))
+ end
+ end
+
+ def test_dsa_sign_asn1_FIPS186_3
+ for key in @keys
+ size = key.group.order.num_bits / 8 + 1
+ dgst = (1..size).to_a.pack('C*')
+ begin
+ sig = key.dsa_sign_asn1(dgst)
+ # dgst is auto-truncated according to FIPS186-3 after openssl-0.9.8m
+ assert(key.dsa_verify_asn1(dgst + "garbage", sig))
+ rescue OpenSSL::PKey::ECError => e
+ # just an exception for longer dgst before openssl-0.9.8m
+ assert_equal('ECDSA_sign: data too large for key size', e.message)
+ # no need to do following tests
+ return
+ end
+ end
+ end
+
+ def test_dh_compute_key
+ for key in @keys
+ k = OpenSSL::PKey::EC.new(key.group)
+ k.generate_key
+
+ puba = key.public_key
+ pubb = k.public_key
+ a = key.dh_compute_key(pubb)
+ b = k.dh_compute_key(puba)
+ assert_equal(a, b)
+ end
+ end
+
+# test Group: asn1_flag, point_conversion
+
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_hmac.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_hmac.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_hmac.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,36 @@
+begin
+ require "openssl"
+rescue LoadError
+end
+require "test/unit"
+
+class OpenSSL::TestHMAC < Test::Unit::TestCase
+ def setup
+ @digest = OpenSSL::Digest::MD5
+ @key = "KEY"
+ @data = "DATA"
+ @h1 = OpenSSL::HMAC.new(@key, @digest.new)
+ @h2 = OpenSSL::HMAC.new(@key, "MD5")
+ end
+
+ def teardown
+ end
+
+ def test_hmac
+ @h1.update(@data)
+ @h2.update(@data)
+ assert_equal(@h1.digest, @h2.digest)
+
+ assert_equal(OpenSSL::HMAC.digest(@digest.new, @key, @data), @h1.digest, "digest")
+ assert_equal(OpenSSL::HMAC.hexdigest(@digest.new, @key, @data), @h1.hexdigest, "hexdigest")
+
+ assert_equal(OpenSSL::HMAC.digest("MD5", @key, @data), @h2.digest, "digest")
+ assert_equal(OpenSSL::HMAC.hexdigest("MD5", @key, @data), @h2.hexdigest, "hexdigest")
+ end
+
+ def test_dup
+ @h1.update(@data)
+ h = @h1.dup
+ assert_equal(@h1.digest, h.digest, "dup digest")
+ end
+end if defined?(OpenSSL)
Added: MacRuby/trunk/test/test-mri/test/openssl/test_ns_spki.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_ns_spki.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_ns_spki.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,59 @@
+begin
+ require "openssl"
+ require_relative 'utils'
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(OpenSSL)
+
+
+class OpenSSL::TestNSSPI < Test::Unit::TestCase
+ def setup
+ # This request data is adopt from the specification of
+ # "Netscape Extensions for User Key Generation".
+ # -- http://wp.netscape.com/eng/security/comm4-keygen.html
+ @b64 = "MIHFMHEwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAnX0TILJrOMUue+PtwBRE6XfV"
+ @b64 << "WtKQbsshxk5ZhcUwcwyvcnIq9b82QhJdoACdD34rqfCAIND46fXKQUnb0mvKzQID"
+ @b64 << "AQABFhFNb3ppbGxhSXNNeUZyaWVuZDANBgkqhkiG9w0BAQQFAANBAAKv2Eex2n/S"
+ @b64 << "r/7iJNroWlSzSMtTiQTEB+ADWHGj9u1xrUrOilq/o2cuQxIfZcNZkYAkWP4DubqW"
+ @b64 << "i0//rgBvmco="
+ end
+
+ def teardown
+ end
+
+ def test_build_data
+ key1 = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ key2 = OpenSSL::TestUtils::TEST_KEY_RSA2048
+ spki = OpenSSL::Netscape::SPKI.new
+ spki.challenge = "RandomString"
+ spki.public_key = key1.public_key
+ spki.sign(key1, OpenSSL::Digest::SHA1.new)
+ assert(spki.verify(spki.public_key))
+ assert(spki.verify(key1.public_key))
+ assert(!spki.verify(key2.public_key))
+
+ der = spki.to_der
+ spki = OpenSSL::Netscape::SPKI.new(der)
+ assert_equal("RandomString", spki.challenge)
+ assert_equal(key1.public_key.to_der, spki.public_key.to_der)
+ assert(spki.verify(spki.public_key))
+ end
+
+ def test_decode_data
+ spki = OpenSSL::Netscape::SPKI.new(@b64)
+ assert_equal(@b64, spki.to_pem)
+ assert_equal(@b64.unpack("m").first, spki.to_der)
+ assert_equal("MozillaIsMyFriend", spki.challenge)
+ assert_equal(OpenSSL::PKey::RSA, spki.public_key.class)
+
+ spki = OpenSSL::Netscape::SPKI.new(@b64.unpack("m").first)
+ assert_equal(@b64, spki.to_pem)
+ assert_equal(@b64.unpack("m").first, spki.to_der)
+ assert_equal("MozillaIsMyFriend", spki.challenge)
+ assert_equal(OpenSSL::PKey::RSA, spki.public_key.class)
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_pair.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_pair.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_pair.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,250 @@
+begin
+ require "openssl"
+rescue LoadError
+end
+require 'test/unit'
+
+if defined?(OpenSSL)
+
+require 'socket'
+require_relative '../ruby/ut_eof'
+
+module SSLPair
+ def server
+ host = "127.0.0.1"
+ port = 0
+ ctx = OpenSSL::SSL::SSLContext.new()
+ ctx.ciphers = "ADH"
+ tcps = TCPServer.new(host, port)
+ ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
+ return ssls
+ end
+
+ def client(port)
+ host = "127.0.0.1"
+ ctx = OpenSSL::SSL::SSLContext.new()
+ ctx.ciphers = "ADH"
+ s = TCPSocket.new(host, port)
+ ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)
+ ssl.connect
+ ssl.sync_close = true
+ ssl
+ end
+
+ def ssl_pair
+ ssls = server
+ th = Thread.new {
+ ns = ssls.accept
+ ssls.close
+ ns
+ }
+ port = ssls.to_io.addr[1]
+ c = client(port)
+ s = th.value
+ if block_given?
+ begin
+ yield c, s
+ ensure
+ c.close unless c.closed?
+ s.close unless s.closed?
+ end
+ else
+ return c, s
+ end
+ ensure
+ if th && th.alive?
+ th.kill
+ th.join
+ end
+ end
+end
+
+class OpenSSL::TestEOF1 < Test::Unit::TestCase
+ include TestEOF
+ include SSLPair
+
+ def open_file(content)
+ s1, s2 = ssl_pair
+ Thread.new { s2 << content; s2.close }
+ yield s1
+ end
+end
+
+class OpenSSL::TestEOF2 < Test::Unit::TestCase
+ include TestEOF
+ include SSLPair
+
+ def open_file(content)
+ s1, s2 = ssl_pair
+ Thread.new { s1 << content; s1.close }
+ yield s2
+ end
+end
+
+class OpenSSL::TestPair < Test::Unit::TestCase
+ include SSLPair
+
+ def test_getc
+ ssl_pair {|s1, s2|
+ s1 << "a"
+ assert_equal(?a, s2.getc)
+ }
+ end
+
+ def test_readpartial
+ ssl_pair {|s1, s2|
+ s2.write "a\nbcd"
+ assert_equal("a\n", s1.gets)
+ assert_equal("bcd", s1.readpartial(10))
+ s2.write "efg"
+ assert_equal("efg", s1.readpartial(10))
+ s2.close
+ assert_raise(EOFError) { s1.readpartial(10) }
+ assert_raise(EOFError) { s1.readpartial(10) }
+ assert_equal("", s1.readpartial(0))
+ }
+ end
+
+ def test_readall
+ ssl_pair {|s1, s2|
+ s2.close
+ assert_equal("", s1.read)
+ }
+ end
+
+ def test_readline
+ ssl_pair {|s1, s2|
+ s2.close
+ assert_raise(EOFError) { s1.readline }
+ }
+ end
+
+ def test_puts_meta
+ ssl_pair {|s1, s2|
+ begin
+ old = $/
+ $/ = '*'
+ s1.puts 'a'
+ ensure
+ $/ = old
+ end
+ s1.close
+ assert_equal("a\n", s2.read)
+ }
+ end
+
+ def test_puts_empty
+ ssl_pair {|s1, s2|
+ s1.puts
+ s1.close
+ assert_equal("\n", s2.read)
+ }
+ end
+
+ def test_read_nonblock
+ ssl_pair {|s1, s2|
+ err = nil
+ assert_raise(OpenSSL::SSL::SSLError) {
+ begin
+ s2.read_nonblock(10)
+ ensure
+ err = $!
+ end
+ }
+ assert_kind_of(IO::WaitReadable, err)
+ s1.write "abc\ndef\n"
+ IO.select([s2])
+ assert_equal("ab", s2.read_nonblock(2))
+ assert_equal("c\n", s2.gets)
+ ret = nil
+ assert_nothing_raised("[ruby-core:20298]") { ret = s2.read_nonblock(10) }
+ assert_equal("def\n", ret)
+ }
+ end
+
+ def test_write_nonblock
+ ssl_pair {|s1, s2|
+ n = 0
+ begin
+ n += s1.write_nonblock("a" * 100000)
+ n += s1.write_nonblock("b" * 100000)
+ n += s1.write_nonblock("c" * 100000)
+ n += s1.write_nonblock("d" * 100000)
+ n += s1.write_nonblock("e" * 100000)
+ n += s1.write_nonblock("f" * 100000)
+ rescue IO::WaitWritable
+ end
+ s1.close
+ assert_equal(n, s2.read.length)
+ }
+ end
+
+ def test_write_nonblock_with_buffered_data
+ ssl_pair {|s1, s2|
+ s1.write "foo"
+ s1.write_nonblock("bar")
+ s1.write "baz"
+ s1.close
+ assert_equal("foobarbaz", s2.read)
+ }
+ end
+
+ def test_connect_accept_nonblock
+ host = "127.0.0.1"
+ port = 0
+ ctx = OpenSSL::SSL::SSLContext.new()
+ ctx.ciphers = "ADH"
+ serv = TCPServer.new(host, port)
+ ssls = OpenSSL::SSL::SSLServer.new(serv, ctx)
+
+ port = serv.connect_address.ip_port
+
+ sock1 = TCPSocket.new(host, port)
+ sock2 = serv.accept
+ serv.close
+
+ th = Thread.new {
+ s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx)
+ s2.sync_close = true
+ begin
+ sleep 0.2
+ s2.accept_nonblock
+ rescue IO::WaitReadable
+ IO.select([s2])
+ retry
+ rescue IO::WaitWritable
+ IO.select(nil, [s2])
+ retry
+ end
+ s2
+ }
+
+ sleep 0.1
+ ctx = OpenSSL::SSL::SSLContext.new()
+ ctx.ciphers = "ADH"
+ s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx)
+ begin
+ sleep 0.2
+ s1.connect_nonblock
+ rescue IO::WaitReadable
+ IO.select([s1])
+ retry
+ rescue IO::WaitWritable
+ IO.select(nil, [s1])
+ retry
+ end
+ s1.sync_close = true
+
+ s2 = th.value
+
+ s1.print "a\ndef"
+ assert_equal("a\n", s2.gets)
+ ensure
+ serv.close if serv && !serv.closed?
+ sock1.close if sock1 && !sock1.closed?
+ sock2.close if sock2 && !sock2.closed?
+ end
+
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_pkcs7.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_pkcs7.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_pkcs7.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,154 @@
+begin
+ require "openssl"
+ require_relative 'utils'
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(OpenSSL)
+
+class OpenSSL::TestPKCS7 < Test::Unit::TestCase
+ def setup
+ @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
+ ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
+ ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
+ ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2")
+
+ now = Time.now
+ ca_exts = [
+ ["basicConstraints","CA:TRUE",true],
+ ["keyUsage","keyCertSign, cRLSign",true],
+ ["subjectKeyIdentifier","hash",false],
+ ["authorityKeyIdentifier","keyid:always",false],
+ ]
+ @ca_cert = issue_cert(ca, @rsa2048, 1, Time.now, Time.now+3600, ca_exts,
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ ee_exts = [
+ ["keyUsage","Non Repudiation, Digital Signature, Key Encipherment",true],
+ ["authorityKeyIdentifier","keyid:always",false],
+ ["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false],
+ ]
+ @ee1_cert = issue_cert(ee1, @rsa1024, 2, Time.now, Time.now+1800, ee_exts,
+ @ca_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ @ee2_cert = issue_cert(ee2, @rsa1024, 3, Time.now, Time.now+1800, ee_exts,
+ @ca_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ end
+
+ def issue_cert(*args)
+ OpenSSL::TestUtils.issue_cert(*args)
+ end
+
+ def test_signed
+ store = OpenSSL::X509::Store.new
+ store.add_cert(@ca_cert)
+ ca_certs = [@ca_cert]
+
+ data = "aaaaa\r\nbbbbb\r\nccccc\r\n"
+ tmp = OpenSSL::PKCS7.sign(@ee1_cert, @rsa1024, data, ca_certs)
+ p7 = OpenSSL::PKCS7.new(tmp.to_der)
+ certs = p7.certificates
+ signers = p7.signers
+ assert(p7.verify([], store))
+ assert_equal(data, p7.data)
+ assert_equal(2, certs.size)
+ assert_equal(@ee1_cert.subject.to_s, certs[0].subject.to_s)
+ assert_equal(@ca_cert.subject.to_s, certs[1].subject.to_s)
+ assert_equal(1, signers.size)
+ assert_equal(@ee1_cert.serial, signers[0].serial)
+ assert_equal(@ee1_cert.issuer.to_s, signers[0].issuer.to_s)
+
+ # Normaly OpenSSL tries to translate the supplied content into canonical
+ # MIME format (e.g. a newline character is converted into CR+LF).
+ # If the content is a binary, PKCS7::BINARY flag should be used.
+
+ data = "aaaaa\nbbbbb\nccccc\n"
+ flag = OpenSSL::PKCS7::BINARY
+ tmp = OpenSSL::PKCS7.sign(@ee1_cert, @rsa1024, data, ca_certs, flag)
+ p7 = OpenSSL::PKCS7.new(tmp.to_der)
+ certs = p7.certificates
+ signers = p7.signers
+ assert(p7.verify([], store))
+ assert_equal(data, p7.data)
+ assert_equal(2, certs.size)
+ assert_equal(@ee1_cert.subject.to_s, certs[0].subject.to_s)
+ assert_equal(@ca_cert.subject.to_s, certs[1].subject.to_s)
+ assert_equal(1, signers.size)
+ assert_equal(@ee1_cert.serial, signers[0].serial)
+ assert_equal(@ee1_cert.issuer.to_s, signers[0].issuer.to_s)
+
+ # A signed-data which have multiple signatures can be created
+ # through the following steps.
+ # 1. create two signed-data
+ # 2. copy signerInfo and certificate from one to another
+
+ tmp1 = OpenSSL::PKCS7.sign(@ee1_cert, @rsa1024, data, [], flag)
+ tmp2 = OpenSSL::PKCS7.sign(@ee2_cert, @rsa1024, data, [], flag)
+ tmp1.add_signer(tmp2.signers[0])
+ tmp1.add_certificate(@ee2_cert)
+
+ p7 = OpenSSL::PKCS7.new(tmp1.to_der)
+ certs = p7.certificates
+ signers = p7.signers
+ assert(p7.verify([], store))
+ assert_equal(data, p7.data)
+ assert_equal(2, certs.size)
+ assert_equal(2, signers.size)
+ assert_equal(@ee1_cert.serial, signers[0].serial)
+ assert_equal(@ee1_cert.issuer.to_s, signers[0].issuer.to_s)
+ assert_equal(@ee2_cert.serial, signers[1].serial)
+ assert_equal(@ee2_cert.issuer.to_s, signers[1].issuer.to_s)
+ end
+
+ def test_detached_sign
+ store = OpenSSL::X509::Store.new
+ store.add_cert(@ca_cert)
+ ca_certs = [@ca_cert]
+
+ data = "aaaaa\nbbbbb\nccccc\n"
+ flag = OpenSSL::PKCS7::BINARY|OpenSSL::PKCS7::DETACHED
+ tmp = OpenSSL::PKCS7.sign(@ee1_cert, @rsa1024, data, ca_certs, flag)
+ p7 = OpenSSL::PKCS7.new(tmp.to_der)
+ a1 = OpenSSL::ASN1.decode(p7)
+
+ certs = p7.certificates
+ signers = p7.signers
+ assert(!p7.verify([], store))
+ assert(p7.verify([], store, data))
+ assert_equal(data, p7.data)
+ assert_equal(2, certs.size)
+ assert_equal(@ee1_cert.subject.to_s, certs[0].subject.to_s)
+ assert_equal(@ca_cert.subject.to_s, certs[1].subject.to_s)
+ assert_equal(1, signers.size)
+ assert_equal(@ee1_cert.serial, signers[0].serial)
+ assert_equal(@ee1_cert.issuer.to_s, signers[0].issuer.to_s)
+ end
+
+ def test_enveloped
+ if OpenSSL::OPENSSL_VERSION_NUMBER <= 0x0090704f
+ # PKCS7_encrypt() of OpenSSL-0.9.7d goes to SEGV.
+ # http://www.mail-archive.com/openssl-dev@openssl.org/msg17376.html
+ return
+ end
+
+ certs = [@ee1_cert, @ee2_cert]
+ cipher = OpenSSL::Cipher::AES.new("128-CBC")
+ data = "aaaaa\nbbbbb\nccccc\n"
+
+ tmp = OpenSSL::PKCS7.encrypt(certs, data, cipher, OpenSSL::PKCS7::BINARY)
+ p7 = OpenSSL::PKCS7.new(tmp.to_der)
+ recip = p7.recipients
+ assert_equal(:enveloped, p7.type)
+ assert_equal(2, recip.size)
+
+ assert_equal(@ca_cert.subject.to_s, recip[0].issuer.to_s)
+ assert_equal(2, recip[0].serial)
+ assert_equal(data, p7.decrypt(@rsa1024, @ee1_cert))
+
+ assert_equal(@ca_cert.subject.to_s, recip[1].issuer.to_s)
+ assert_equal(3, recip[1].serial)
+ assert_equal(data, p7.decrypt(@rsa1024, @ee2_cert))
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_pkey_rsa.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_pkey_rsa.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_pkey_rsa.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,49 @@
+begin
+ require "openssl"
+ require File.join(File.dirname(__FILE__), "utils.rb")
+rescue LoadError
+end
+require 'test/unit'
+
+if defined?(OpenSSL)
+
+class OpenSSL::TestPKeyRSA < Test::Unit::TestCase
+ def test_padding
+ key = OpenSSL::PKey::RSA.new(512, 3)
+
+ # Need right size for raw mode
+ plain0 = "x" * (512/8)
+ cipher = key.private_encrypt(plain0, OpenSSL::PKey::RSA::NO_PADDING)
+ plain1 = key.public_decrypt(cipher, OpenSSL::PKey::RSA::NO_PADDING)
+ assert_equal(plain0, plain1)
+
+ # Need smaller size for pkcs1 mode
+ plain0 = "x" * (512/8 - 11)
+ cipher1 = key.private_encrypt(plain0, OpenSSL::PKey::RSA::PKCS1_PADDING)
+ plain1 = key.public_decrypt(cipher1, OpenSSL::PKey::RSA::PKCS1_PADDING)
+ assert_equal(plain0, plain1)
+
+ cipherdef = key.private_encrypt(plain0) # PKCS1_PADDING is default
+ plain1 = key.public_decrypt(cipherdef)
+ assert_equal(plain0, plain1)
+ assert_equal(cipher1, cipherdef)
+
+ # Failure cases
+ assert_raise(ArgumentError){ key.private_encrypt() }
+ assert_raise(ArgumentError){ key.private_encrypt("hi", 1, nil) }
+ assert_raise(OpenSSL::PKey::RSAError){ key.private_encrypt(plain0, 666) }
+ end
+
+ def test_private
+ key = OpenSSL::PKey::RSA.new(512, 3)
+ assert(key.private?)
+ key2 = OpenSSL::PKey::RSA.new(key.to_der)
+ assert(key2.private?)
+ key3 = key.public_key
+ assert(!key3.private?)
+ key4 = OpenSSL::PKey::RSA.new(key3.to_der)
+ assert(!key4.private?)
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_ssl.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_ssl.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_ssl.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,613 @@
+begin
+ require "openssl"
+ require_relative "utils.rb"
+rescue LoadError
+end
+require "rbconfig"
+require "socket"
+require "test/unit"
+require_relative '../ruby/envutil'
+
+if defined?(OpenSSL)
+
+class OpenSSL::TestSSL < Test::Unit::TestCase
+ RUBY = EnvUtil.rubybin
+ SSL_SERVER = File.join(File.dirname(__FILE__), "ssl_server.rb")
+ PORT = 20443
+ ITERATIONS = ($0 == __FILE__) ? 100 : 10
+
+ def setup
+ @ca_key = OpenSSL::TestUtils::TEST_KEY_RSA2048
+ @svr_key = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ @cli_key = OpenSSL::TestUtils::TEST_KEY_DSA256
+ @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
+ @svr = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
+ @cli = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
+
+ now = Time.at(Time.now.to_i)
+ ca_exts = [
+ ["basicConstraints","CA:TRUE",true],
+ ["keyUsage","cRLSign,keyCertSign",true],
+ ]
+ ee_exts = [
+ ["keyUsage","keyEncipherment,digitalSignature",true],
+ ]
+ @ca_cert = issue_cert(@ca, @ca_key, 1, now, now+3600, ca_exts,
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ @svr_cert = issue_cert(@svr, @svr_key, 2, now, now+1800, ee_exts,
+ @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
+ @cli_cert = issue_cert(@cli, @cli_key, 3, now, now+1800, ee_exts,
+ @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
+ @server = nil
+ end
+
+ def teardown
+ end
+
+ def issue_cert(*arg)
+ OpenSSL::TestUtils.issue_cert(*arg)
+ end
+
+ def issue_crl(*arg)
+ OpenSSL::TestUtils.issue_crl(*arg)
+ end
+
+ def readwrite_loop(ctx, ssl)
+ while line = ssl.gets
+ if line =~ /^STARTTLS$/
+ ssl.accept
+ next
+ end
+ ssl.write(line)
+ end
+ rescue OpenSSL::SSL::SSLError
+ rescue IOError
+ ensure
+ ssl.close rescue nil
+ end
+
+ def server_loop(ctx, ssls, server_proc)
+ loop do
+ ssl = nil
+ begin
+ ssl = ssls.accept
+ rescue OpenSSL::SSL::SSLError
+ retry
+ end
+
+ Thread.start do
+ Thread.current.abort_on_exception = true
+ server_proc.call(ctx, ssl)
+ end
+ end
+ rescue Errno::EBADF, IOError, Errno::EINVAL, Errno::ECONNABORTED, Errno::ENOTSOCK
+ end
+
+ def start_server(port0, verify_mode, start_immediately, args = {}, &block)
+ ctx_proc = args[:ctx_proc]
+ server_proc = args[:server_proc]
+ server_proc ||= method(:readwrite_loop)
+
+ store = OpenSSL::X509::Store.new
+ store.add_cert(@ca_cert)
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.cert_store = store
+ #ctx.extra_chain_cert = [ ca_cert ]
+ ctx.cert = @svr_cert
+ ctx.key = @svr_key
+ ctx.verify_mode = verify_mode
+ ctx_proc.call(ctx) if ctx_proc
+
+ Socket.do_not_reverse_lookup = true
+ tcps = nil
+ port = port0
+ begin
+ tcps = TCPServer.new("127.0.0.1", port)
+ rescue Errno::EADDRINUSE
+ port += 1
+ retry
+ end
+
+ ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
+ ssls.start_immediately = start_immediately
+
+ begin
+ server = Thread.new do
+ Thread.current.abort_on_exception = true
+ server_loop(ctx, ssls, server_proc)
+ end
+
+ $stderr.printf("%s started: pid=%d port=%d\n", SSL_SERVER, pid, port) if $DEBUG
+
+ block.call(server, port.to_i)
+ ensure
+ begin
+ begin
+ tcps.shutdown
+ rescue Errno::ENOTCONN
+ # when `Errno::ENOTCONN: Socket is not connected' on some platforms,
+ # call #close instead of #shutdown.
+ tcps.close
+ tcps = nil
+ end if (tcps)
+ if (server)
+ server.join(5)
+ if server.alive?
+ server.kill
+ server.join
+ flunk("TCPServer was closed and SSLServer is still alive") unless $!
+ end
+ end
+ ensure
+ tcps.close if (tcps)
+ end
+ end
+ end
+
+ def starttls(ssl)
+ ssl.puts("STARTTLS")
+
+ sleep 1 # When this line is eliminated, process on Cygwin blocks
+ # forever at ssl.connect. But I don't know why it does.
+
+ ssl.connect
+ end
+
+ def test_ctx_setup
+ ctx = OpenSSL::SSL::SSLContext.new
+ assert_equal(ctx.setup, true)
+ assert_equal(ctx.setup, nil)
+ end
+
+ def test_ssl_read_nonblock
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) { |server, port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ ssl.sync_close = true
+ ssl.connect
+ assert_raise(IO::WaitReadable) { ssl.read_nonblock(100) }
+ ssl.write("abc\n")
+ IO.select [ssl]
+ assert_equal('a', ssl.read_nonblock(1))
+ assert_equal("bc\n", ssl.read_nonblock(100))
+ assert_raise(IO::WaitReadable) { ssl.read_nonblock(100) }
+ }
+ end
+
+ def test_connect_and_close
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ assert(ssl.connect)
+ ssl.close
+ assert(!sock.closed?)
+ sock.close
+
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ ssl.sync_close = true # !!
+ assert(ssl.connect)
+ ssl.close
+ assert(sock.closed?)
+ }
+ end
+
+ def test_read_and_write
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ ssl.sync_close = true
+ ssl.connect
+
+ # syswrite and sysread
+ ITERATIONS.times{|i|
+ str = "x" * 100 + "\n"
+ ssl.syswrite(str)
+ assert_equal(str, ssl.sysread(str.size))
+
+ str = "x" * i * 100 + "\n"
+ buf = ""
+ ssl.syswrite(str)
+ assert_equal(buf.object_id, ssl.sysread(str.size, buf).object_id)
+ assert_equal(str, buf)
+ }
+
+ # puts and gets
+ ITERATIONS.times{
+ str = "x" * 100 + "\n"
+ ssl.puts(str)
+ assert_equal(str, ssl.gets)
+
+ str = "x" * 100
+ ssl.puts(str)
+ assert_equal(str, ssl.gets("\n", 100))
+ assert_equal("\n", ssl.gets)
+ }
+
+ # read and write
+ ITERATIONS.times{|i|
+ str = "x" * 100 + "\n"
+ ssl.write(str)
+ assert_equal(str, ssl.read(str.size))
+
+ str = "x" * i * 100 + "\n"
+ buf = ""
+ ssl.write(str)
+ assert_equal(buf.object_id, ssl.read(str.size, buf).object_id)
+ assert_equal(str, buf)
+ }
+
+ ssl.close
+ }
+ end
+
+ def test_client_auth
+ vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
+ start_server(PORT, vflag, true){|server, port|
+ assert_raise(OpenSSL::SSL::SSLError, Errno::ECONNRESET){
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ ssl.connect
+ }
+
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.key = @cli_key
+ ctx.cert = @cli_cert
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ ssl.sync_close = true
+ ssl.connect
+ ssl.puts("foo")
+ assert_equal("foo\n", ssl.gets)
+ ssl.close
+
+ called = nil
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.client_cert_cb = Proc.new{ |sslconn|
+ called = true
+ [@cli_cert, @cli_key]
+ }
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ ssl.sync_close = true
+ ssl.connect
+ assert(called)
+ ssl.puts("foo")
+ assert_equal("foo\n", ssl.gets)
+ ssl.close
+ }
+ end
+
+ def test_starttls
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, false){|server, port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ ssl.sync_close = true
+ str = "x" * 1000 + "\n"
+
+ ITERATIONS.times{
+ ssl.puts(str)
+ assert_equal(str, ssl.gets)
+ }
+
+ starttls(ssl)
+
+ ITERATIONS.times{
+ ssl.puts(str)
+ assert_equal(str, ssl.gets)
+ }
+
+ ssl.close
+ }
+ end
+
+ def test_parallel
+ GC.start
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+ ssls = []
+ 10.times{
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ ssl.connect
+ ssl.sync_close = true
+ ssls << ssl
+ }
+ str = "x" * 1000 + "\n"
+ ITERATIONS.times{
+ ssls.each{|ssl|
+ ssl.puts(str)
+ assert_equal(str, ssl.gets)
+ }
+ }
+ ssls.each{|ssl| ssl.close }
+ }
+ end
+
+ def test_verify_result
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.set_params
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }
+ assert_equal(OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN, ssl.verify_result)
+
+ sock = TCPSocket.new("127.0.0.1", port)
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.set_params(
+ :verify_callback => Proc.new do |preverify_ok, store_ctx|
+ store_ctx.error = OpenSSL::X509::V_OK
+ true
+ end
+ )
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ ssl.connect
+ assert_equal(OpenSSL::X509::V_OK, ssl.verify_result)
+
+ sock = TCPSocket.new("127.0.0.1", port)
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.set_params(
+ :verify_callback => Proc.new do |preverify_ok, store_ctx|
+ store_ctx.error = OpenSSL::X509::V_ERR_APPLICATION_VERIFICATION
+ false
+ end
+ )
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }
+ assert_equal(OpenSSL::X509::V_ERR_APPLICATION_VERIFICATION, ssl.verify_result)
+ }
+ end
+
+ def test_sslctx_set_params
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.set_params
+ assert_equal(OpenSSL::SSL::VERIFY_PEER, ctx.verify_mode)
+ assert_equal(OpenSSL::SSL::OP_ALL, ctx.options)
+ ciphers = ctx.ciphers
+ ciphers_versions = ciphers.collect{|_, v, _, _| v }
+ ciphers_names = ciphers.collect{|v, _, _, _| v }
+ assert(ciphers_names.all?{|v| /ADH/ !~ v })
+ assert(ciphers_versions.all?{|v| /SSLv2/ !~ v })
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }
+ assert_equal(OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN, ssl.verify_result)
+ }
+ end
+
+ def test_post_connection_check
+ sslerr = OpenSSL::SSL::SSLError
+
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ ssl.connect
+ assert_raise(sslerr){ssl.post_connection_check("localhost.localdomain")}
+ assert_raise(sslerr){ssl.post_connection_check("127.0.0.1")}
+ assert(ssl.post_connection_check("localhost"))
+ assert_raise(sslerr){ssl.post_connection_check("foo.example.com")}
+
+ cert = ssl.peer_cert
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain"))
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1"))
+ assert(OpenSSL::SSL.verify_certificate_identity(cert, "localhost"))
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "foo.example.com"))
+ }
+
+ now = Time.now
+ exts = [
+ ["keyUsage","keyEncipherment,digitalSignature",true],
+ ["subjectAltName","DNS:localhost.localdomain",false],
+ ["subjectAltName","IP:127.0.0.1",false],
+ ]
+ @svr_cert = issue_cert(@svr, @svr_key, 4, now, now+1800, exts,
+ @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ ssl.connect
+ assert(ssl.post_connection_check("localhost.localdomain"))
+ assert(ssl.post_connection_check("127.0.0.1"))
+ assert_raise(sslerr){ssl.post_connection_check("localhost")}
+ assert_raise(sslerr){ssl.post_connection_check("foo.example.com")}
+
+ cert = ssl.peer_cert
+ assert(OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain"))
+ assert(OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1"))
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "localhost"))
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "foo.example.com"))
+ }
+
+ now = Time.now
+ exts = [
+ ["keyUsage","keyEncipherment,digitalSignature",true],
+ ["subjectAltName","DNS:*.localdomain",false],
+ ]
+ @svr_cert = issue_cert(@svr, @svr_key, 5, now, now+1800, exts,
+ @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
+ ssl.connect
+ assert(ssl.post_connection_check("localhost.localdomain"))
+ assert_raise(sslerr){ssl.post_connection_check("127.0.0.1")}
+ assert_raise(sslerr){ssl.post_connection_check("localhost")}
+ assert_raise(sslerr){ssl.post_connection_check("foo.example.com")}
+ cert = ssl.peer_cert
+ assert(OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain"))
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1"))
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "localhost"))
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "foo.example.com"))
+ }
+ end
+
+ def test_client_session
+ last_session = nil
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port|
+ 2.times do
+ sock = TCPSocket.new("127.0.0.1", port)
+ # Debian's openssl 0.9.8g-13 failed at assert(ssl.session_reused?),
+ # when use default SSLContext. [ruby-dev:36167]
+ ctx = OpenSSL::SSL::SSLContext.new("TLSv1")
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ ssl.sync_close = true
+ ssl.session = last_session if last_session
+ ssl.connect
+
+ session = ssl.session
+ if last_session
+ assert(ssl.session_reused?)
+
+ if session.respond_to?(:id)
+ assert_equal(session.id, last_session.id)
+ end
+ assert_equal(session.to_pem, last_session.to_pem)
+ assert_equal(session.to_der, last_session.to_der)
+ # Older version of OpenSSL may not be consistent. Look up which versions later.
+ assert_equal(session.to_text, last_session.to_text)
+ else
+ assert(!ssl.session_reused?)
+ end
+ last_session = session
+
+ str = "x" * 100 + "\n"
+ ssl.puts(str)
+ assert_equal(str, ssl.gets)
+
+ ssl.close
+ end
+ end
+ end
+
+ def test_server_session
+ connections = 0
+ saved_session = nil
+
+ ctx_proc = Proc.new do |ctx, ssl|
+# add test for session callbacks here
+ end
+
+ server_proc = Proc.new do |ctx, ssl|
+ session = ssl.session
+ stats = ctx.session_cache_stats
+
+ case connections
+ when 0
+ assert_equal(stats[:cache_num], 1)
+ assert_equal(stats[:cache_hits], 0)
+ assert_equal(stats[:cache_misses], 0)
+ assert(!ssl.session_reused?)
+ when 1
+ assert_equal(stats[:cache_num], 1)
+ assert_equal(stats[:cache_hits], 1)
+ assert_equal(stats[:cache_misses], 0)
+ assert(ssl.session_reused?)
+ ctx.session_remove(session)
+ saved_session = session
+ when 2
+ assert_equal(stats[:cache_num], 1)
+ assert_equal(stats[:cache_hits], 1)
+ assert_equal(stats[:cache_misses], 1)
+ assert(!ssl.session_reused?)
+ ctx.session_add(saved_session)
+ when 3
+ assert_equal(stats[:cache_num], 2)
+ assert_equal(stats[:cache_hits], 2)
+ assert_equal(stats[:cache_misses], 1)
+ assert(ssl.session_reused?)
+ ctx.flush_sessions(Time.now + 5000)
+ when 4
+ assert_equal(stats[:cache_num], 1)
+ assert_equal(stats[:cache_hits], 2)
+ assert_equal(stats[:cache_misses], 2)
+ assert(!ssl.session_reused?)
+ ctx.session_add(saved_session)
+ end
+ connections += 1
+
+ readwrite_loop(ctx, ssl)
+ end
+
+ first_session = nil
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc, :server_proc => server_proc) do |server, port|
+ 10.times do |i|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ctx = OpenSSL::SSL::SSLContext.new
+ if defined?(OpenSSL::SSL::OP_NO_TICKET)
+ # disable RFC4507 support
+ ctx.options = OpenSSL::SSL::OP_NO_TICKET
+ end
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ ssl.sync_close = true
+ ssl.session = first_session if first_session
+ ssl.connect
+
+ session = ssl.session
+ if first_session
+ case i
+ when 1; assert(ssl.session_reused?)
+ when 2; assert(!ssl.session_reused?)
+ when 3; assert(ssl.session_reused?)
+ when 4; assert(!ssl.session_reused?)
+ when 5..10; assert(ssl.session_reused?)
+ end
+ end
+ first_session ||= session
+
+ str = "x" * 100 + "\n"
+ ssl.puts(str)
+ assert_equal(str, ssl.gets)
+
+ ssl.close
+ end
+ end
+ end
+
+ def test_tlsext_hostname
+ return unless OpenSSL::SSL::SSLSocket.instance_methods.include?(:hostname)
+
+ ctx_proc = Proc.new do |ctx, ssl|
+ foo_ctx = ctx.dup
+
+ ctx.servername_cb = Proc.new do |ssl2, hostname|
+ case hostname
+ when 'foo.example.com'
+ foo_ctx
+ when 'bar.example.com'
+ nil
+ else
+ raise "unknown hostname #{hostname.inspect}"
+ end
+ end
+ end
+
+ server_proc = Proc.new do |ctx, ssl|
+ readwrite_loop(ctx, ssl)
+ end
+
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc, :server_proc => server_proc) do |server, port|
+ 2.times do |i|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ctx = OpenSSL::SSL::SSLContext.new
+ if defined?(OpenSSL::SSL::OP_NO_TICKET)
+ # disable RFC4507 support
+ ctx.options = OpenSSL::SSL::OP_NO_TICKET
+ end
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ ssl.sync_close = true
+ ssl.hostname = (i & 1 == 0) ? 'foo.example.com' : 'bar.example.com'
+ ssl.connect
+
+ str = "x" * 100 + "\n"
+ ssl.puts(str)
+ assert_equal(str, ssl.gets)
+
+ ssl.close
+ end
+ end
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_x509cert.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_x509cert.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_x509cert.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,180 @@
+begin
+ require "openssl"
+ require_relative "utils"
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(OpenSSL)
+
+class OpenSSL::TestX509Certificate < Test::Unit::TestCase
+ def setup
+ @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
+ @dsa256 = OpenSSL::TestUtils::TEST_KEY_DSA256
+ @dsa512 = OpenSSL::TestUtils::TEST_KEY_DSA512
+ @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
+ @ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
+ @ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2")
+ end
+
+ def teardown
+ end
+
+ def issue_cert(*args)
+ OpenSSL::TestUtils.issue_cert(*args)
+ end
+
+ def test_serial
+ [1, 2**32, 2**100].each{|s|
+ cert = issue_cert(@ca, @rsa2048, s, Time.now, Time.now+3600, [],
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ assert_equal(s, cert.serial)
+ cert = OpenSSL::X509::Certificate.new(cert.to_der)
+ assert_equal(s, cert.serial)
+ }
+ end
+
+ def test_public_key
+ exts = [
+ ["basicConstraints","CA:TRUE",true],
+ ["subjectKeyIdentifier","hash",false],
+ ["authorityKeyIdentifier","keyid:always",false],
+ ]
+
+ sha1 = OpenSSL::Digest::SHA1.new
+ dss1 = OpenSSL::Digest::DSS1.new
+ [
+ [@rsa1024, sha1], [@rsa2048, sha1], [@dsa256, dss1], [@dsa512, dss1],
+ ].each{|pk, digest|
+ cert = issue_cert(@ca, pk, 1, Time.now, Time.now+3600, exts,
+ nil, nil, digest)
+ assert_equal(cert.extensions[1].value,
+ OpenSSL::TestUtils.get_subject_key_id(cert))
+ cert = OpenSSL::X509::Certificate.new(cert.to_der)
+ assert_equal(cert.extensions[1].value,
+ OpenSSL::TestUtils.get_subject_key_id(cert))
+ }
+ end
+
+ def test_validity
+ now = Time.now until now && now.usec != 0
+ cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ assert_not_equal(now, cert.not_before)
+ assert_not_equal(now+3600, cert.not_after)
+
+ now = Time.at(now.to_i)
+ cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ assert_equal(now.getutc, cert.not_before)
+ assert_equal((now+3600).getutc, cert.not_after)
+
+ now = Time.at(0)
+ cert = issue_cert(@ca, @rsa2048, 1, now, now, [],
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ assert_equal(now.getutc, cert.not_before)
+ assert_equal(now.getutc, cert.not_after)
+
+ now = Time.at(0x7fffffff)
+ cert = issue_cert(@ca, @rsa2048, 1, now, now, [],
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ assert_equal(now.getutc, cert.not_before)
+ assert_equal(now.getutc, cert.not_after)
+ end
+
+ def test_extension
+ ca_exts = [
+ ["basicConstraints","CA:TRUE",true],
+ ["keyUsage","keyCertSign, cRLSign",true],
+ ["subjectKeyIdentifier","hash",false],
+ ["authorityKeyIdentifier","keyid:always",false],
+ ]
+ ca_cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, ca_exts,
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ ca_cert.extensions.each_with_index{|ext, i|
+ assert_equal(ca_exts[i].first, ext.oid)
+ assert_equal(ca_exts[i].last, ext.critical?)
+ }
+
+ ee1_exts = [
+ ["keyUsage","Non Repudiation, Digital Signature, Key Encipherment",true],
+ ["subjectKeyIdentifier","hash",false],
+ ["authorityKeyIdentifier","keyid:always",false],
+ ["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false],
+ ["subjectAltName","email:ee1 at ruby-lang.org",false],
+ ]
+ ee1_cert = issue_cert(@ee1, @rsa1024, 2, Time.now, Time.now+1800, ee1_exts,
+ ca_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ assert_equal(ca_cert.subject.to_der, ee1_cert.issuer.to_der)
+ ee1_cert.extensions.each_with_index{|ext, i|
+ assert_equal(ee1_exts[i].first, ext.oid)
+ assert_equal(ee1_exts[i].last, ext.critical?)
+ }
+
+ ee2_exts = [
+ ["keyUsage","Non Repudiation, Digital Signature, Key Encipherment",true],
+ ["subjectKeyIdentifier","hash",false],
+ ["authorityKeyIdentifier","issuer:always",false],
+ ["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false],
+ ["subjectAltName","email:ee2 at ruby-lang.org",false],
+ ]
+ ee2_cert = issue_cert(@ee2, @rsa1024, 3, Time.now, Time.now+1800, ee2_exts,
+ ca_cert, @rsa2048, OpenSSL::Digest::MD5.new)
+ assert_equal(ca_cert.subject.to_der, ee2_cert.issuer.to_der)
+ ee2_cert.extensions.each_with_index{|ext, i|
+ assert_equal(ee2_exts[i].first, ext.oid)
+ assert_equal(ee2_exts[i].last, ext.critical?)
+ }
+
+ end
+
+ def test_sign_and_verify
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ assert_equal(false, cert.verify(@rsa1024))
+ assert_equal(true, cert.verify(@rsa2048))
+ assert_equal(false, certificate_error_returns_false { cert.verify(@dsa256) })
+ assert_equal(false, certificate_error_returns_false { cert.verify(@dsa512) })
+ cert.serial = 2
+ assert_equal(false, cert.verify(@rsa2048))
+
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
+ nil, nil, OpenSSL::Digest::MD5.new)
+ assert_equal(false, cert.verify(@rsa1024))
+ assert_equal(true, cert.verify(@rsa2048))
+
+ assert_equal(false, certificate_error_returns_false { cert.verify(@dsa256) })
+ assert_equal(false, certificate_error_returns_false { cert.verify(@dsa512) })
+ cert.subject = @ee1
+ assert_equal(false, cert.verify(@rsa2048))
+
+ cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
+ nil, nil, OpenSSL::Digest::DSS1.new)
+ assert_equal(false, certificate_error_returns_false { cert.verify(@rsa1024) })
+ assert_equal(false, certificate_error_returns_false { cert.verify(@rsa2048) })
+ assert_equal(false, cert.verify(@dsa256))
+ assert_equal(true, cert.verify(@dsa512))
+ cert.not_after = Time.now
+ assert_equal(false, cert.verify(@dsa512))
+
+ assert_raise(OpenSSL::X509::CertificateError){
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
+ nil, nil, OpenSSL::Digest::DSS1.new)
+ }
+ assert_raise(OpenSSL::X509::CertificateError){
+ cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
+ nil, nil, OpenSSL::Digest::MD5.new)
+ }
+ end
+
+ private
+
+ def certificate_error_returns_false
+ yield
+ rescue OpenSSL::X509::CertificateError
+ false
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_x509crl.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_x509crl.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_x509crl.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,226 @@
+begin
+ require "openssl"
+ require_relative "utils"
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(OpenSSL)
+
+class OpenSSL::TestX509CRL < Test::Unit::TestCase
+ def setup
+ @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
+ @dsa256 = OpenSSL::TestUtils::TEST_KEY_DSA256
+ @dsa512 = OpenSSL::TestUtils::TEST_KEY_DSA512
+ @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
+ @ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
+ @ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2")
+ end
+
+ def teardown
+ end
+
+ def issue_crl(*args)
+ OpenSSL::TestUtils.issue_crl(*args)
+ end
+
+ def issue_cert(*args)
+ OpenSSL::TestUtils.issue_cert(*args)
+ end
+
+ def test_basic
+ now = Time.at(Time.now.to_i)
+
+ cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ crl = issue_crl([], 1, now, now+1600, [],
+ cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ assert_equal(1, crl.version)
+ assert_equal(cert.issuer.to_der, crl.issuer.to_der)
+ assert_equal(now, crl.last_update)
+ assert_equal(now+1600, crl.next_update)
+
+ crl = OpenSSL::X509::CRL.new(crl.to_der)
+ assert_equal(1, crl.version)
+ assert_equal(cert.issuer.to_der, crl.issuer.to_der)
+ assert_equal(now, crl.last_update)
+ assert_equal(now+1600, crl.next_update)
+ end
+
+ def test_revoked
+
+ # CRLReason ::= ENUMERATED {
+ # unspecified (0),
+ # keyCompromise (1),
+ # cACompromise (2),
+ # affiliationChanged (3),
+ # superseded (4),
+ # cessationOfOperation (5),
+ # certificateHold (6),
+ # removeFromCRL (8),
+ # privilegeWithdrawn (9),
+ # aACompromise (10) }
+
+ now = Time.at(Time.now.to_i)
+ revoke_info = [
+ [1, Time.at(0), 1],
+ [2, Time.at(0x7fffffff), 2],
+ [3, now, 3],
+ [4, now, 4],
+ [5, now, 5],
+ ]
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [],
+ cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ revoked = crl.revoked
+ assert_equal(5, revoked.size)
+ assert_equal(1, revoked[0].serial)
+ assert_equal(2, revoked[1].serial)
+ assert_equal(3, revoked[2].serial)
+ assert_equal(4, revoked[3].serial)
+ assert_equal(5, revoked[4].serial)
+
+ assert_equal(Time.at(0), revoked[0].time)
+ assert_equal(Time.at(0x7fffffff), revoked[1].time)
+ assert_equal(now, revoked[2].time)
+ assert_equal(now, revoked[3].time)
+ assert_equal(now, revoked[4].time)
+
+ assert_equal("CRLReason", revoked[0].extensions[0].oid)
+ assert_equal("CRLReason", revoked[1].extensions[0].oid)
+ assert_equal("CRLReason", revoked[2].extensions[0].oid)
+ assert_equal("CRLReason", revoked[3].extensions[0].oid)
+ assert_equal("CRLReason", revoked[4].extensions[0].oid)
+
+ assert_equal("Key Compromise", revoked[0].extensions[0].value)
+ assert_equal("CA Compromise", revoked[1].extensions[0].value)
+ assert_equal("Affiliation Changed", revoked[2].extensions[0].value)
+ assert_equal("Superseded", revoked[3].extensions[0].value)
+ assert_equal("Cessation Of Operation", revoked[4].extensions[0].value)
+
+ assert_equal(false, revoked[0].extensions[0].critical?)
+ assert_equal(false, revoked[1].extensions[0].critical?)
+ assert_equal(false, revoked[2].extensions[0].critical?)
+ assert_equal(false, revoked[3].extensions[0].critical?)
+ assert_equal(false, revoked[4].extensions[0].critical?)
+
+ crl = OpenSSL::X509::CRL.new(crl.to_der)
+ assert_equal("Key Compromise", revoked[0].extensions[0].value)
+ assert_equal("CA Compromise", revoked[1].extensions[0].value)
+ assert_equal("Affiliation Changed", revoked[2].extensions[0].value)
+ assert_equal("Superseded", revoked[3].extensions[0].value)
+ assert_equal("Cessation Of Operation", revoked[4].extensions[0].value)
+
+ revoke_info = (1..1000).collect{|i| [i, now, 0] }
+ crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [],
+ cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ revoked = crl.revoked
+ assert_equal(1000, revoked.size)
+ assert_equal(1, revoked[0].serial)
+ assert_equal(1000, revoked[999].serial)
+ end
+
+ def test_extension
+ cert_exts = [
+ ["basicConstraints", "CA:TRUE", true],
+ ["subjectKeyIdentifier", "hash", false],
+ ["authorityKeyIdentifier", "keyid:always", false],
+ ["subjectAltName", "email:xyzzy at ruby-lang.org", false],
+ ["keyUsage", "cRLSign, keyCertSign", true],
+ ]
+ crl_exts = [
+ ["authorityKeyIdentifier", "keyid:always", false],
+ ["issuerAltName", "issuer:copy", false],
+ ]
+
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, cert_exts,
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ crl = issue_crl([], 1, Time.now, Time.now+1600, crl_exts,
+ cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ exts = crl.extensions
+ assert_equal(3, exts.size)
+ assert_equal("1", exts[0].value)
+ assert_equal("crlNumber", exts[0].oid)
+ assert_equal(false, exts[0].critical?)
+
+ assert_equal("authorityKeyIdentifier", exts[1].oid)
+ keyid = OpenSSL::TestUtils.get_subject_key_id(cert)
+ assert_match(/^keyid:#{keyid}/, exts[1].value)
+ assert_equal(false, exts[1].critical?)
+
+ assert_equal("issuerAltName", exts[2].oid)
+ assert_equal("email:xyzzy at ruby-lang.org", exts[2].value)
+ assert_equal(false, exts[2].critical?)
+
+ crl = OpenSSL::X509::CRL.new(crl.to_der)
+ exts = crl.extensions
+ assert_equal(3, exts.size)
+ assert_equal("1", exts[0].value)
+ assert_equal("crlNumber", exts[0].oid)
+ assert_equal(false, exts[0].critical?)
+
+ assert_equal("authorityKeyIdentifier", exts[1].oid)
+ keyid = OpenSSL::TestUtils.get_subject_key_id(cert)
+ assert_match(/^keyid:#{keyid}/, exts[1].value)
+ assert_equal(false, exts[1].critical?)
+
+ assert_equal("issuerAltName", exts[2].oid)
+ assert_equal("email:xyzzy at ruby-lang.org", exts[2].value)
+ assert_equal(false, exts[2].critical?)
+ end
+
+ def test_crlnumber
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ crl = issue_crl([], 1, Time.now, Time.now+1600, [],
+ cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ assert_match(1.to_s, crl.extensions[0].value)
+ assert_match(/X509v3 CRL Number:\s+#{1}/m, crl.to_text)
+
+ crl = issue_crl([], 2**32, Time.now, Time.now+1600, [],
+ cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ assert_match((2**32).to_s, crl.extensions[0].value)
+ assert_match(/X509v3 CRL Number:\s+#{2**32}/m, crl.to_text)
+
+ crl = issue_crl([], 2**100, Time.now, Time.now+1600, [],
+ cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ assert_match(/X509v3 CRL Number:\s+#{2**100}/m, crl.to_text)
+ assert_match((2**100).to_s, crl.extensions[0].value)
+ end
+
+ def test_sign_and_verify
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ crl = issue_crl([], 1, Time.now, Time.now+1600, [],
+ cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ assert_equal(false, crl.verify(@rsa1024))
+ assert_equal(true, crl.verify(@rsa2048))
+ assert_equal(false, crl_error_returns_false { crl.verify(@dsa256) })
+ assert_equal(false, crl_error_returns_false { crl.verify(@dsa512) })
+ crl.version = 0
+ assert_equal(false, crl.verify(@rsa2048))
+
+ cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
+ nil, nil, OpenSSL::Digest::DSS1.new)
+ crl = issue_crl([], 1, Time.now, Time.now+1600, [],
+ cert, @dsa512, OpenSSL::Digest::DSS1.new)
+ assert_equal(false, crl_error_returns_false { crl.verify(@rsa1024) })
+ assert_equal(false, crl_error_returns_false { crl.verify(@rsa2048) })
+ assert_equal(false, crl.verify(@dsa256))
+ assert_equal(true, crl.verify(@dsa512))
+ crl.version = 0
+ assert_equal(false, crl.verify(@dsa512))
+ end
+
+ private
+
+ def crl_error_returns_false
+ yield
+ rescue OpenSSL::X509::CRLError
+ false
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_x509ext.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_x509ext.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_x509ext.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,74 @@
+begin
+ require "openssl"
+ require File.join(File.dirname(__FILE__), "utils.rb")
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(OpenSSL)
+
+class OpenSSL::TestX509Extension < Test::Unit::TestCase
+ def setup
+ @basic_constraints_value = OpenSSL::ASN1::Sequence([
+ OpenSSL::ASN1::Boolean(true), # CA
+ OpenSSL::ASN1::Integer(2) # pathlen
+ ])
+ @basic_constraints = OpenSSL::ASN1::Sequence([
+ OpenSSL::ASN1::ObjectId("basicConstraints"),
+ OpenSSL::ASN1::Boolean(true),
+ OpenSSL::ASN1::OctetString(@basic_constraints_value.to_der),
+ ])
+ end
+
+ def teardown
+ end
+
+ def test_new
+ ext = OpenSSL::X509::Extension.new(@basic_constraints.to_der)
+ assert_equal("basicConstraints", ext.oid)
+ assert_equal(true, ext.critical?)
+ assert_equal("CA:TRUE, pathlen:2", ext.value)
+
+ ext = OpenSSL::X509::Extension.new("2.5.29.19",
+ @basic_constraints_value.to_der, true)
+ assert_equal(@basic_constraints.to_der, ext.to_der)
+ end
+
+ def test_create_by_factory
+ ef = OpenSSL::X509::ExtensionFactory.new
+
+ bc = ef.create_extension("basicConstraints", "critical, CA:TRUE, pathlen:2")
+ assert_equal(@basic_constraints.to_der, bc.to_der)
+
+ bc = ef.create_extension("basicConstraints", "CA:TRUE, pathlen:2", true)
+ assert_equal(@basic_constraints.to_der, bc.to_der)
+
+ begin
+ ef.config = OpenSSL::Config.parse(<<-_end_of_cnf_)
+ [crlDistPts]
+ URI.1 = http://www.example.com/crl
+ URI.2 = ldap://ldap.example.com/cn=ca?certificateRevocationList;binary
+ _end_of_cnf_
+ rescue NotImplementedError
+ return
+ end
+
+ cdp = ef.create_extension("crlDistributionPoints", "@crlDistPts")
+ assert_equal(false, cdp.critical?)
+ assert_equal("crlDistributionPoints", cdp.oid)
+ assert_match(%{URI:http://www\.example\.com/crl}, cdp.value)
+ assert_match(
+ %r{URI:ldap://ldap\.example\.com/cn=ca\?certificateRevocationList;binary},
+ cdp.value)
+
+ cdp = ef.create_extension("crlDistributionPoints", "critical, @crlDistPts")
+ assert_equal(true, cdp.critical?)
+ assert_equal("crlDistributionPoints", cdp.oid)
+ assert_match(%{URI:http://www.example.com/crl}, cdp.value)
+ assert_match(
+ %r{URI:ldap://ldap.example.com/cn=ca\?certificateRevocationList;binary},
+ cdp.value)
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_x509name.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_x509name.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_x509name.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,266 @@
+begin
+ require "openssl"
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(OpenSSL)
+
+class OpenSSL::TestX509Name < Test::Unit::TestCase
+ OpenSSL::ASN1::ObjectId.register(
+ "1.2.840.113549.1.9.1", "emailAddress", "emailAddress")
+ OpenSSL::ASN1::ObjectId.register(
+ "2.5.4.5", "serialNumber", "serialNumber")
+
+ def setup
+ @obj_type_tmpl = Hash.new(OpenSSL::ASN1::PRINTABLESTRING)
+ @obj_type_tmpl.update(OpenSSL::X509::Name::OBJECT_TYPE_TEMPLATE)
+ end
+
+ def teardown
+ end
+
+ def test_s_new
+ dn = [ ["C", "JP"], ["O", "example"], ["CN", "www.example.jp"] ]
+ name = OpenSSL::X509::Name.new(dn)
+ ary = name.to_a
+ assert_equal("/C=JP/O=example/CN=www.example.jp", name.to_s)
+ assert_equal("C", ary[0][0])
+ assert_equal("O", ary[1][0])
+ assert_equal("CN", ary[2][0])
+ assert_equal("JP", ary[0][1])
+ assert_equal("example", ary[1][1])
+ assert_equal("www.example.jp", ary[2][1])
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2])
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[1][2])
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
+
+ dn = [
+ ["countryName", "JP"],
+ ["organizationName", "example"],
+ ["commonName", "www.example.jp"]
+ ]
+ name = OpenSSL::X509::Name.new(dn)
+ ary = name.to_a
+ assert_equal("/C=JP/O=example/CN=www.example.jp", name.to_s)
+ assert_equal("C", ary[0][0])
+ assert_equal("O", ary[1][0])
+ assert_equal("CN", ary[2][0])
+ assert_equal("JP", ary[0][1])
+ assert_equal("example", ary[1][1])
+ assert_equal("www.example.jp", ary[2][1])
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2])
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[1][2])
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
+
+ name = OpenSSL::X509::Name.new(dn, @obj_type_tmpl)
+ ary = name.to_a
+ assert_equal("/C=JP/O=example/CN=www.example.jp", name.to_s)
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2])
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[1][2])
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2])
+
+ dn = [
+ ["countryName", "JP", OpenSSL::ASN1::PRINTABLESTRING],
+ ["organizationName", "example", OpenSSL::ASN1::PRINTABLESTRING],
+ ["commonName", "www.example.jp", OpenSSL::ASN1::PRINTABLESTRING]
+ ]
+ name = OpenSSL::X509::Name.new(dn)
+ ary = name.to_a
+ assert_equal("/C=JP/O=example/CN=www.example.jp", name.to_s)
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2])
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[1][2])
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2])
+
+ dn = [
+ ["DC", "org"],
+ ["DC", "ruby-lang"],
+ ["CN", "GOTOU Yuuzou"],
+ ["emailAddress", "gotoyuzo at ruby-lang.org"],
+ ["serialNumber", "123"],
+ ]
+ name = OpenSSL::X509::Name.new(dn)
+ ary = name.to_a
+ assert_equal("/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou/emailAddress=gotoyuzo at ruby-lang.org/serialNumber=123", name.to_s)
+ assert_equal("DC", ary[0][0])
+ assert_equal("DC", ary[1][0])
+ assert_equal("CN", ary[2][0])
+ assert_equal("emailAddress", ary[3][0])
+ assert_equal("serialNumber", ary[4][0])
+ assert_equal("org", ary[0][1])
+ assert_equal("ruby-lang", ary[1][1])
+ assert_equal("GOTOU Yuuzou", ary[2][1])
+ assert_equal("gotoyuzo at ruby-lang.org", ary[3][1])
+ assert_equal("123", ary[4][1])
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[3][2])
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[4][2])
+
+ name_from_der = OpenSSL::X509::Name.new(name.to_der)
+ assert_equal(name_from_der.to_s, name.to_s)
+ assert_equal(name_from_der.to_a, name.to_a)
+ assert_equal(name_from_der.to_der, name.to_der)
+ end
+
+ def test_s_parse
+ dn = "/DC=org/DC=ruby-lang/CN=www.ruby-lang.org"
+ name = OpenSSL::X509::Name.parse(dn)
+ assert_equal(dn, name.to_s)
+ ary = name.to_a
+ assert_equal("DC", ary[0][0])
+ assert_equal("DC", ary[1][0])
+ assert_equal("CN", ary[2][0])
+ assert_equal("org", ary[0][1])
+ assert_equal("ruby-lang", ary[1][1])
+ assert_equal("www.ruby-lang.org", ary[2][1])
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
+
+ dn2 = "DC=org, DC=ruby-lang, CN=www.ruby-lang.org"
+ name = OpenSSL::X509::Name.parse(dn)
+ ary = name.to_a
+ assert_equal(dn, name.to_s)
+ assert_equal("org", ary[0][1])
+ assert_equal("ruby-lang", ary[1][1])
+ assert_equal("www.ruby-lang.org", ary[2][1])
+
+ name = OpenSSL::X509::Name.parse(dn, @obj_type_tmpl)
+ ary = name.to_a
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2])
+ end
+
+ def test_s_parse_rfc2253
+ scanner = OpenSSL::X509::Name::RFC2253DN.method(:scan)
+
+ assert_equal([["C", "JP"]], scanner.call("C=JP"))
+ assert_equal([
+ ["DC", "org"],
+ ["DC", "ruby-lang"],
+ ["CN", "GOTOU Yuuzou"],
+ ["emailAddress", "gotoyuzo at ruby-lang.org"],
+ ],
+ scanner.call(
+ "emailAddress=gotoyuzo at ruby-lang.org,CN=GOTOU Yuuzou,"+
+ "DC=ruby-lang,DC=org")
+ )
+
+ u8 = OpenSSL::ASN1::UTF8STRING
+ assert_equal([
+ ["DC", "org"],
+ ["DC", "ruby-lang"],
+ ["O", ",=+<>#;"],
+ ["O", ",=+<>#;"],
+ ["OU", ""],
+ ["OU", ""],
+ ["L", "aaa=\"bbb, ccc\""],
+ ["L", "aaa=\"bbb, ccc\""],
+ ["CN", "\345\276\214\350\227\244\350\243\225\350\224\265"],
+ ["CN", "\345\276\214\350\227\244\350\243\225\350\224\265"],
+ ["CN", "\345\276\214\350\227\244\350\243\225\350\224\265"],
+ ["CN", "\345\276\214\350\227\244\350\243\225\350\224\265", u8],
+ ["2.5.4.3", "GOTOU, Yuuzou"],
+ ["2.5.4.3", "GOTOU, Yuuzou"],
+ ["2.5.4.3", "GOTOU, Yuuzou"],
+ ["2.5.4.3", "GOTOU, Yuuzou"],
+ ["CN", "GOTOU \"gotoyuzo\" Yuuzou"],
+ ["CN", "GOTOU \"gotoyuzo\" Yuuzou"],
+ ["1.2.840.113549.1.9.1", "gotoyuzo at ruby-lang.org"],
+ ["emailAddress", "gotoyuzo at ruby-lang.org"],
+ ],
+ scanner.call(
+ "emailAddress=gotoyuzo at ruby-lang.org," +
+ "1.2.840.113549.1.9.1=gotoyuzo at ruby-lang.org," +
+ 'CN=GOTOU \"gotoyuzo\" Yuuzou,' +
+ 'CN="GOTOU \"gotoyuzo\" Yuuzou",' +
+ '2.5.4.3=GOTOU\,\20Yuuzou,' +
+ '2.5.4.3=GOTOU\, Yuuzou,' +
+ '2.5.4.3="GOTOU, Yuuzou",' +
+ '2.5.4.3="GOTOU\, Yuuzou",' +
+ "CN=#0C0CE5BE8CE897A4E8A395E894B5," +
+ 'CN=\E5\BE\8C\E8\97\A4\E8\A3\95\E8\94\B5,' +
+ "CN=\"\xE5\xBE\x8C\xE8\x97\xA4\xE8\xA3\x95\xE8\x94\xB5\"," +
+ "CN=\xE5\xBE\x8C\xE8\x97\xA4\xE8\xA3\x95\xE8\x94\xB5," +
+ 'L=aaa\=\"bbb\, ccc\",' +
+ 'L="aaa=\"bbb, ccc\"",' +
+ 'OU=,' +
+ 'OU="",' +
+ 'O=\,\=\+\<\>\#\;,' +
+ 'O=",=+<>#;",' +
+ "DC=ruby-lang," +
+ "DC=org")
+ )
+
+ [
+ "DC=org+DC=jp",
+ "DC=org,DC=ruby-lang+DC=rubyist,DC=www"
+ ].each{|dn|
+ ex = scanner.call(dn) rescue $!
+ dn_r = Regexp.escape(dn)
+ assert_match(/^multi-valued RDN is not supported: #{dn_r}/, ex.message)
+ }
+
+ [
+ ["DC=org,DC=exapmle,CN", "CN"],
+ ["DC=org,DC=example,", ""],
+ ["DC=org,DC=exapmle,CN=www.example.org;", "CN=www.example.org;"],
+ ["DC=org,DC=exapmle,CN=#www.example.org", "CN=#www.example.org"],
+ ["DC=org,DC=exapmle,CN=#777777.example.org", "CN=#777777.example.org"],
+ ["DC=org,DC=exapmle,CN=\"www.example\".org", "CN=\"www.example\".org"],
+ ["DC=org,DC=exapmle,CN=www.\"example.org\"", "CN=www.\"example.org\""],
+ ["DC=org,DC=exapmle,CN=www.\"example\".org", "CN=www.\"example\".org"],
+ ].each{|dn, msg|
+ ex = scanner.call(dn) rescue $!
+ assert_match(/^malformed RDN: .*=>#{Regexp.escape(msg)}/, ex.message)
+ }
+
+ dn = "CN=www.ruby-lang.org,DC=ruby-lang,DC=org"
+ name = OpenSSL::X509::Name.parse_rfc2253(dn)
+ assert_equal(dn, name.to_s(OpenSSL::X509::Name::RFC2253))
+ ary = name.to_a
+ assert_equal("DC", ary[0][0])
+ assert_equal("DC", ary[1][0])
+ assert_equal("CN", ary[2][0])
+ assert_equal("org", ary[0][1])
+ assert_equal("ruby-lang", ary[1][1])
+ assert_equal("www.ruby-lang.org", ary[2][1])
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
+ end
+
+ def test_add_entry
+ dn = [
+ ["DC", "org"],
+ ["DC", "ruby-lang"],
+ ["CN", "GOTOU Yuuzou"],
+ ["emailAddress", "gotoyuzo at ruby-lang.org"],
+ ["serialNumber", "123"],
+ ]
+ name = OpenSSL::X509::Name.new
+ dn.each{|attr| name.add_entry(*attr) }
+ ary = name.to_a
+ assert_equal("/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou/emailAddress=gotoyuzo at ruby-lang.org/serialNumber=123", name.to_s)
+ assert_equal("DC", ary[0][0])
+ assert_equal("DC", ary[1][0])
+ assert_equal("CN", ary[2][0])
+ assert_equal("emailAddress", ary[3][0])
+ assert_equal("serialNumber", ary[4][0])
+ assert_equal("org", ary[0][1])
+ assert_equal("ruby-lang", ary[1][1])
+ assert_equal("GOTOU Yuuzou", ary[2][1])
+ assert_equal("gotoyuzo at ruby-lang.org", ary[3][1])
+ assert_equal("123", ary[4][1])
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[3][2])
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[4][2])
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_x509req.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_x509req.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_x509req.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,146 @@
+begin
+ require "openssl"
+ require_relative "utils"
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(OpenSSL)
+
+class OpenSSL::TestX509Request < Test::Unit::TestCase
+ def setup
+ @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
+ @dsa256 = OpenSSL::TestUtils::TEST_KEY_DSA256
+ @dsa512 = OpenSSL::TestUtils::TEST_KEY_DSA512
+ @dn = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou")
+ end
+
+ def issue_csr(ver, dn, key, digest)
+ req = OpenSSL::X509::Request.new
+ req.version = ver
+ req.subject = dn
+ req.public_key = key.public_key
+ req.sign(key, digest)
+ req
+ end
+
+ def test_public_key
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
+ assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
+ req = OpenSSL::X509::Request.new(req.to_der)
+ assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
+
+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest::DSS1.new)
+ assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
+ req = OpenSSL::X509::Request.new(req.to_der)
+ assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
+ end
+
+ def test_version
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
+ assert_equal(0, req.version)
+ req = OpenSSL::X509::Request.new(req.to_der)
+ assert_equal(0, req.version)
+
+ req = issue_csr(1, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
+ assert_equal(1, req.version)
+ req = OpenSSL::X509::Request.new(req.to_der)
+ assert_equal(1, req.version)
+ end
+
+ def test_subject
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
+ assert_equal(@dn.to_der, req.subject.to_der)
+ req = OpenSSL::X509::Request.new(req.to_der)
+ assert_equal(@dn.to_der, req.subject.to_der)
+ end
+
+ def create_ext_req(exts)
+ ef = OpenSSL::X509::ExtensionFactory.new
+ exts = exts.collect{|e| ef.create_extension(*e) }
+ return OpenSSL::ASN1::Set([OpenSSL::ASN1::Sequence(exts)])
+ end
+
+ def get_ext_req(ext_req_value)
+ set = OpenSSL::ASN1.decode(ext_req_value)
+ seq = set.value[0]
+ seq.value.collect{|asn1ext|
+ OpenSSL::X509::Extension.new(asn1ext).to_a
+ }
+ end
+
+ def test_attr
+ exts = [
+ ["keyUsage", "Digital Signature, Key Encipherment", true],
+ ["subjectAltName", "email:gotoyuzo at ruby-lang.org", false],
+ ]
+ attrval = create_ext_req(exts)
+ attrs = [
+ OpenSSL::X509::Attribute.new("extReq", attrval),
+ OpenSSL::X509::Attribute.new("msExtReq", attrval),
+ ]
+
+ req0 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
+ attrs.each{|attr| req0.add_attribute(attr) }
+ req1 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
+ req1.attributes = attrs
+ assert_equal(req0.to_der, req1.to_der)
+
+ attrs = req0.attributes
+ assert_equal(2, attrs.size)
+ assert_equal("extReq", attrs[0].oid)
+ assert_equal("msExtReq", attrs[1].oid)
+ assert_equal(exts, get_ext_req(attrs[0].value))
+ assert_equal(exts, get_ext_req(attrs[1].value))
+
+ req = OpenSSL::X509::Request.new(req0.to_der)
+ attrs = req.attributes
+ assert_equal(2, attrs.size)
+ assert_equal("extReq", attrs[0].oid)
+ assert_equal("msExtReq", attrs[1].oid)
+ assert_equal(exts, get_ext_req(attrs[0].value))
+ assert_equal(exts, get_ext_req(attrs[1].value))
+ end
+
+ def test_sign_and_verify
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
+ assert_equal(true, req.verify(@rsa1024))
+ assert_equal(false, req.verify(@rsa2048))
+ assert_equal(false, request_error_returns_false { req.verify(@dsa256) })
+ assert_equal(false, request_error_returns_false { req.verify(@dsa512) })
+ req.version = 1
+ assert_equal(false, req.verify(@rsa1024))
+
+ req = issue_csr(0, @dn, @rsa2048, OpenSSL::Digest::MD5.new)
+ assert_equal(false, req.verify(@rsa1024))
+ assert_equal(true, req.verify(@rsa2048))
+ assert_equal(false, request_error_returns_false { req.verify(@dsa256) })
+ assert_equal(false, request_error_returns_false { req.verify(@dsa512) })
+ req.subject = OpenSSL::X509::Name.parse("/C=JP/CN=FooBar")
+ assert_equal(false, req.verify(@rsa2048))
+
+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest::DSS1.new)
+ assert_equal(false, request_error_returns_false { req.verify(@rsa1024) })
+ assert_equal(false, request_error_returns_false { req.verify(@rsa2048) })
+ assert_equal(false, req.verify(@dsa256))
+ assert_equal(true, req.verify(@dsa512))
+ req.public_key = @rsa1024.public_key
+ assert_equal(false, req.verify(@dsa512))
+
+ assert_raise(OpenSSL::X509::RequestError){
+ issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::DSS1.new) }
+ assert_raise(OpenSSL::X509::RequestError){
+ issue_csr(0, @dn, @dsa512, OpenSSL::Digest::MD5.new) }
+ end
+
+ private
+
+ def request_error_returns_false
+ yield
+ rescue OpenSSL::X509::RequestError
+ false
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/test_x509store.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/test_x509store.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/test_x509store.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,218 @@
+begin
+ require "openssl"
+ require_relative "utils"
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(OpenSSL)
+
+class OpenSSL::TestX509Store < Test::Unit::TestCase
+ def setup
+ @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
+ @dsa256 = OpenSSL::TestUtils::TEST_KEY_DSA256
+ @dsa512 = OpenSSL::TestUtils::TEST_KEY_DSA512
+ @ca1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA1")
+ @ca2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA2")
+ @ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
+ @ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2")
+ end
+
+ def teardown
+ end
+
+ def issue_cert(*args)
+ OpenSSL::TestUtils.issue_cert(*args)
+ end
+
+ def issue_crl(*args)
+ OpenSSL::TestUtils.issue_crl(*args)
+ end
+
+ def test_verify
+ now = Time.at(Time.now.to_i)
+ ca_exts = [
+ ["basicConstraints","CA:TRUE",true],
+ ["keyUsage","cRLSign,keyCertSign",true],
+ ]
+ ee_exts = [
+ ["keyUsage","keyEncipherment,digitalSignature",true],
+ ]
+ ca1_cert = issue_cert(@ca1, @rsa2048, 1, now, now+3600, ca_exts,
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ ca2_cert = issue_cert(@ca2, @rsa1024, 2, now, now+1800, ca_exts,
+ ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ ee1_cert = issue_cert(@ee1, @dsa256, 10, now, now+1800, ee_exts,
+ ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
+ ee2_cert = issue_cert(@ee2, @dsa512, 20, now, now+1800, ee_exts,
+ ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
+ ee3_cert = issue_cert(@ee2, @dsa512, 30, now-100, now-1, ee_exts,
+ ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
+ ee4_cert = issue_cert(@ee2, @dsa512, 40, now+1000, now+2000, ee_exts,
+ ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
+
+ revoke_info = []
+ crl1 = issue_crl(revoke_info, 1, now, now+1800, [],
+ ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ revoke_info = [ [2, now, 1], ]
+ crl1_2 = issue_crl(revoke_info, 2, now, now+1800, [],
+ ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ revoke_info = [ [20, now, 1], ]
+ crl2 = issue_crl(revoke_info, 1, now, now+1800, [],
+ ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
+ revoke_info = []
+ crl2_2 = issue_crl(revoke_info, 2, now-100, now-1, [],
+ ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
+
+ assert_equal(true, ca1_cert.verify(ca1_cert.public_key)) # self signed
+ assert_equal(true, ca2_cert.verify(ca1_cert.public_key)) # issued by ca1
+ assert_equal(true, ee1_cert.verify(ca2_cert.public_key)) # issued by ca2
+ assert_equal(true, ee2_cert.verify(ca2_cert.public_key)) # issued by ca2
+ assert_equal(true, ee3_cert.verify(ca2_cert.public_key)) # issued by ca2
+ assert_equal(true, crl1.verify(ca1_cert.public_key)) # issued by ca1
+ assert_equal(true, crl1_2.verify(ca1_cert.public_key)) # issued by ca1
+ assert_equal(true, crl2.verify(ca2_cert.public_key)) # issued by ca2
+ assert_equal(true, crl2_2.verify(ca2_cert.public_key)) # issued by ca2
+
+ store = OpenSSL::X509::Store.new
+ assert_equal(false, store.verify(ca1_cert))
+ assert_not_equal(OpenSSL::X509::V_OK, store.error)
+
+ assert_equal(false, store.verify(ca2_cert))
+ assert_not_equal(OpenSSL::X509::V_OK, store.error)
+
+ store.add_cert(ca1_cert)
+ assert_equal(true, store.verify(ca2_cert))
+ assert_equal(OpenSSL::X509::V_OK, store.error)
+ assert_equal("ok", store.error_string)
+ chain = store.chain
+ assert_equal(2, chain.size)
+ assert_equal(@ca2.to_der, chain[0].subject.to_der)
+ assert_equal(@ca1.to_der, chain[1].subject.to_der)
+
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
+ assert_equal(false, store.verify(ca2_cert))
+ assert_not_equal(OpenSSL::X509::V_OK, store.error)
+
+ store.purpose = OpenSSL::X509::PURPOSE_CRL_SIGN
+ assert_equal(true, store.verify(ca2_cert))
+ assert_equal(OpenSSL::X509::V_OK, store.error)
+
+ store.add_cert(ca2_cert)
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
+ assert_equal(true, store.verify(ee1_cert))
+ assert_equal(true, store.verify(ee2_cert))
+ assert_equal(OpenSSL::X509::V_OK, store.error)
+ assert_equal("ok", store.error_string)
+ chain = store.chain
+ assert_equal(3, chain.size)
+ assert_equal(@ee2.to_der, chain[0].subject.to_der)
+ assert_equal(@ca2.to_der, chain[1].subject.to_der)
+ assert_equal(@ca1.to_der, chain[2].subject.to_der)
+ assert_equal(false, store.verify(ee3_cert))
+ assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)
+ assert_match(/expire/i, store.error_string)
+ assert_equal(false, store.verify(ee4_cert))
+ assert_equal(OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID, store.error)
+ assert_match(/not yet valid/i, store.error_string)
+
+ store = OpenSSL::X509::Store.new
+ store.add_cert(ca1_cert)
+ store.add_cert(ca2_cert)
+ store.time = now + 1500
+ assert_equal(true, store.verify(ca1_cert))
+ assert_equal(true, store.verify(ca2_cert))
+ assert_equal(true, store.verify(ee4_cert))
+ store.time = now + 1900
+ assert_equal(true, store.verify(ca1_cert))
+ assert_equal(false, store.verify(ca2_cert))
+ assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)
+ assert_equal(false, store.verify(ee4_cert))
+ assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)
+ store.time = now + 4000
+ assert_equal(false, store.verify(ee1_cert))
+ assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)
+ assert_equal(false, store.verify(ee4_cert))
+ assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)
+
+ # the underlying X509 struct caches the result of the last
+ # verification for signature and not-before. so the following code
+ # rebuilds new objects to avoid site effect.
+ store.time = Time.now - 4000
+ assert_equal(false, store.verify(OpenSSL::X509::Certificate.new(ca2_cert)))
+ assert_equal(OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID, store.error)
+ assert_equal(false, store.verify(OpenSSL::X509::Certificate.new(ee1_cert)))
+ assert_equal(OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID, store.error)
+
+ return unless defined?(OpenSSL::X509::V_FLAG_CRL_CHECK)
+
+ store = OpenSSL::X509::Store.new
+ store.purpose = OpenSSL::X509::PURPOSE_ANY
+ store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK
+ store.add_cert(ca1_cert)
+ store.add_crl(crl1) # revoke no cert
+ store.add_crl(crl2) # revoke ee2_cert
+ assert_equal(true, store.verify(ca1_cert))
+ assert_equal(true, store.verify(ca2_cert))
+ assert_equal(true, store.verify(ee1_cert, [ca2_cert]))
+ assert_equal(false, store.verify(ee2_cert, [ca2_cert]))
+
+ store = OpenSSL::X509::Store.new
+ store.purpose = OpenSSL::X509::PURPOSE_ANY
+ store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK
+ store.add_cert(ca1_cert)
+ store.add_crl(crl1_2) # revoke ca2_cert
+ store.add_crl(crl2) # revoke ee2_cert
+ assert_equal(true, store.verify(ca1_cert))
+ assert_equal(false, store.verify(ca2_cert))
+ assert_equal(true, store.verify(ee1_cert, [ca2_cert]),
+ "This test is expected to be success with OpenSSL 0.9.7c or later.")
+ assert_equal(false, store.verify(ee2_cert, [ca2_cert]))
+
+ store.flags =
+ OpenSSL::X509::V_FLAG_CRL_CHECK|OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
+ assert_equal(true, store.verify(ca1_cert))
+ assert_equal(false, store.verify(ca2_cert))
+ assert_equal(false, store.verify(ee1_cert, [ca2_cert]))
+ assert_equal(false, store.verify(ee2_cert, [ca2_cert]))
+
+ store = OpenSSL::X509::Store.new
+ store.purpose = OpenSSL::X509::PURPOSE_ANY
+ store.flags =
+ OpenSSL::X509::V_FLAG_CRL_CHECK|OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
+ store.add_cert(ca1_cert)
+ store.add_cert(ca2_cert)
+ store.add_crl(crl1)
+ store.add_crl(crl2_2) # issued by ca2 but expired.
+ assert_equal(true, store.verify(ca1_cert))
+ assert_equal(true, store.verify(ca2_cert))
+ assert_equal(false, store.verify(ee1_cert))
+ assert_equal(OpenSSL::X509::V_ERR_CRL_HAS_EXPIRED, store.error)
+ assert_equal(false, store.verify(ee2_cert))
+ end
+
+ def test_set_errors
+ now = Time.now
+ ca1_cert = issue_cert(@ca1, @rsa2048, 1, now, now+3600, [],
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ store = OpenSSL::X509::Store.new
+ store.add_cert(ca1_cert)
+ assert_raise(OpenSSL::X509::StoreError){
+ store.add_cert(ca1_cert) # add same certificate twice
+ }
+
+ revoke_info = []
+ crl1 = issue_crl(revoke_info, 1, now, now+1800, [],
+ ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ revoke_info = [ [2, now, 1], ]
+ crl2 = issue_crl(revoke_info, 2, now+1800, now+3600, [],
+ ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
+ store.add_crl(crl1)
+ assert_raise(OpenSSL::X509::StoreError){
+ store.add_crl(crl2) # add CRL issued by same CA twice.
+ }
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/openssl/utils.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/openssl/utils.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/openssl/utils.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,135 @@
+require "openssl"
+require "test/unit"
+
+module OpenSSL::TestUtils
+ TEST_KEY_RSA1024 = OpenSSL::PKey::RSA.new <<-_end_of_pem_
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDLwsSw1ECnPtT+PkOgHhcGA71nwC2/nL85VBGnRqDxOqjVh7Cx
+aKPERYHsk4BPCkE3brtThPWc9kjHEQQ7uf9Y1rbCz0layNqHyywQEVLFmp1cpIt/
+Q3geLv8ZD9pihowKJDyMDiN6ArYUmZczvW4976MU3+l54E6lF/JfFEU5hwIDAQAB
+AoGBAKSl/MQarye1yOysqX6P8fDFQt68VvtXkNmlSiKOGuzyho0M+UVSFcs6k1L0
+maDE25AMZUiGzuWHyaU55d7RXDgeskDMakD1v6ZejYtxJkSXbETOTLDwUWTn618T
+gnb17tU1jktUtU67xK/08i/XodlgnQhs6VoHTuCh3Hu77O6RAkEA7+gxqBuZR572
+74/akiW/SuXm0SXPEviyO1MuSRwtI87B02D0qgV8D1UHRm4AhMnJ8MCs1809kMQE
+JiQUCrp9mQJBANlt2ngBO14us6NnhuAseFDTBzCHXwUUu1YKHpMMmxpnGqaldGgX
+sOZB3lgJsT9VlGf3YGYdkLTNVbogQKlKpB8CQQDiSwkb4vyQfDe8/NpU5Not0fII
+8jsDUCb+opWUTMmfbxWRR3FBNu8wnym/m19N4fFj8LqYzHX4KY0oVPu6qvJxAkEA
+wa5snNekFcqONLIE4G5cosrIrb74sqL8GbGb+KuTAprzj5z1K8Bm0UW9lTjVDjDi
+qRYgZfZSL+x1P/54+xTFSwJAY1FxA/N3QPCXCjPh5YqFxAMQs2VVYTfg+t0MEcJD
+dPMQD5JX6g5HKnHFg2mZtoXQrWmJSn7p8GJK8yNTopEErA==
+-----END RSA PRIVATE KEY-----
+ _end_of_pem_
+
+ TEST_KEY_RSA2048 = OpenSSL::PKey::RSA.new <<-_end_of_pem_
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAuV9ht9J7k4NBs38jOXvvTKY9gW8nLICSno5EETR1cuF7i4pN
+s9I1QJGAFAX0BEO4KbzXmuOvfCpD3CU+Slp1enenfzq/t/e/1IRW0wkJUJUFQign
+4CtrkJL+P07yx18UjyPlBXb81ApEmAB5mrJVSrWmqbjs07JbuS4QQGGXLc+Su96D
+kYKmSNVjBiLxVVSpyZfAY3hD37d60uG+X8xdW5v68JkRFIhdGlb6JL8fllf/A/bl
+NwdJOhVr9mESHhwGjwfSeTDPfd8ZLE027E5lyAVX9KZYcU00mOX+fdxOSnGqS/8J
+DRh0EPHDL15RcJjV2J6vZjPb0rOYGDoMcH+94wIDAQABAoIBAAzsamqfYQAqwXTb
+I0CJtGg6msUgU7HVkOM+9d3hM2L791oGHV6xBAdpXW2H8LgvZHJ8eOeSghR8+dgq
+PIqAffo4x1Oma+FOg3A0fb0evyiACyrOk+EcBdbBeLo/LcvahBtqnDfiUMQTpy6V
+seSoFCwuN91TSCeGIsDpRjbG1vxZgtx+uI+oH5+ytqJOmfCksRDCkMglGkzyfcl0
+Xc5CUhIJ0my53xijEUQl19rtWdMnNnnkdbG8PT3LZlOta5Do86BElzUYka0C6dUc
+VsBDQ0Nup0P6rEQgy7tephHoRlUGTYamsajGJaAo1F3IQVIrRSuagi7+YpSpCqsW
+wORqorkCgYEA7RdX6MDVrbw7LePnhyuaqTiMK+055/R1TqhB1JvvxJ1CXk2rDL6G
+0TLHQ7oGofd5LYiemg4ZVtWdJe43BPZlVgT6lvL/iGo8JnrncB9Da6L7nrq/+Rvj
+XGjf1qODCK+LmreZWEsaLPURIoR/Ewwxb9J2zd0CaMjeTwafJo1CZvcCgYEAyCgb
+aqoWvUecX8VvARfuA593Lsi50t4MEArnOXXcd1RnXoZWhbx5rgO8/ATKfXr0BK/n
+h2GF9PfKzHFm/4V6e82OL7gu/kLy2u9bXN74vOvWFL5NOrOKPM7Kg+9I131kNYOw
+Ivnr/VtHE5s0dY7JChYWE1F3vArrOw3T00a4CXUCgYEA0SqY+dS2LvIzW4cHCe9k
+IQqsT0yYm5TFsUEr4sA3xcPfe4cV8sZb9k/QEGYb1+SWWZ+AHPV3UW5fl8kTbSNb
+v4ng8i8rVVQ0ANbJO9e5CUrepein2MPL0AkOATR8M7t7dGGpvYV0cFk8ZrFx0oId
+U0PgYDotF/iueBWlbsOM430CgYEAqYI95dFyPI5/AiSkY5queeb8+mQH62sdcCCr
+vd/w/CZA/K5sbAo4SoTj8dLk4evU6HtIa0DOP63y071eaxvRpTNqLUOgmLh+D6gS
+Cc7TfLuFrD+WDBatBd5jZ+SoHccVrLR/4L8jeodo5FPW05A+9gnKXEXsTxY4LOUC
+9bS4e1kCgYAqVXZh63JsMwoaxCYmQ66eJojKa47VNrOeIZDZvd2BPVf30glBOT41
+gBoDG3WMPZoQj9pb7uMcrnvs4APj2FIhMU8U15LcPAj59cD6S6rWnAxO8NFK7HQG
+4Jxg3JNNf8ErQoCHb1B3oVdXJkmbJkARoDpBKmTCgKtP8ADYLmVPQw==
+-----END RSA PRIVATE KEY-----
+ _end_of_pem_
+
+ TEST_KEY_DSA256 = OpenSSL::PKey::DSA.new <<-_end_of_pem_
+-----BEGIN DSA PRIVATE KEY-----
+MIH3AgEAAkEAhk2libbY2a8y2Pt21+YPYGZeW6wzaW2yfj5oiClXro9XMR7XWLkE
+9B7XxLNFCS2gmCCdMsMW1HulaHtLFQmB2wIVAM43JZrcgpu6ajZ01VkLc93gu/Ed
+AkAOhujZrrKV5CzBKutKLb0GVyVWmdC7InoNSMZEeGU72rT96IjM59YzoqmD0pGM
+3I1o4cGqg1D1DfM1rQlnN1eSAkBq6xXfEDwJ1mLNxF6q8Zm/ugFYWR5xcX/3wFiT
+b4+EjHP/DbNh9Vm5wcfnDBJ1zKvrMEf2xqngYdrV/3CiGJeKAhRvL57QvJZcQGvn
+ISNX5cMzFHRW3Q==
+-----END DSA PRIVATE KEY-----
+ _end_of_pem_
+
+ TEST_KEY_DSA512 = OpenSSL::PKey::DSA.new <<-_end_of_pem_
+-----BEGIN DSA PRIVATE KEY-----
+MIH4AgEAAkEA5lB4GvEwjrsMlGDqGsxrbqeFRh6o9OWt6FgTYiEEHaOYhkIxv0Ok
+RZPDNwOG997mDjBnvDJ1i56OmS3MbTnovwIVAJgub/aDrSDB4DZGH7UyarcaGy6D
+AkB9HdFw/3td8K4l1FZHv7TCZeJ3ZLb7dF3TWoGUP003RCqoji3/lHdKoVdTQNuR
+S/m6DlCwhjRjiQ/lBRgCLCcaAkEAjN891JBjzpMj4bWgsACmMggFf57DS0Ti+5++
+Q1VB8qkJN7rA7/2HrCR3gTsWNb1YhAsnFsoeRscC+LxXoXi9OAIUBG98h4tilg6S
+55jreJD3Se3slps=
+-----END DSA PRIVATE KEY-----
+ _end_of_pem_
+
+ module_function
+
+ def issue_cert(dn, key, serial, not_before, not_after, extensions,
+ issuer, issuer_key, digest)
+ cert = OpenSSL::X509::Certificate.new
+ issuer = cert unless issuer
+ issuer_key = key unless issuer_key
+ cert.version = 2
+ cert.serial = serial
+ cert.subject = dn
+ cert.issuer = issuer.subject
+ cert.public_key = key.public_key
+ cert.not_before = not_before
+ cert.not_after = not_after
+ ef = OpenSSL::X509::ExtensionFactory.new
+ ef.subject_certificate = cert
+ ef.issuer_certificate = issuer
+ extensions.each{|oid, value, critical|
+ cert.add_extension(ef.create_extension(oid, value, critical))
+ }
+ cert.sign(issuer_key, digest)
+ cert
+ end
+
+ def issue_crl(revoke_info, serial, lastup, nextup, extensions,
+ issuer, issuer_key, digest)
+ crl = OpenSSL::X509::CRL.new
+ crl.issuer = issuer.subject
+ crl.version = 1
+ crl.last_update = lastup
+ crl.next_update = nextup
+ revoke_info.each{|rserial, time, reason_code|
+ revoked = OpenSSL::X509::Revoked.new
+ revoked.serial = rserial
+ revoked.time = time
+ enum = OpenSSL::ASN1::Enumerated(reason_code)
+ ext = OpenSSL::X509::Extension.new("CRLReason", enum)
+ revoked.add_extension(ext)
+ crl.add_revoked(revoked)
+ }
+ ef = OpenSSL::X509::ExtensionFactory.new
+ ef.issuer_certificate = issuer
+ ef.crl = crl
+ crlnum = OpenSSL::ASN1::Integer(serial)
+ crl.add_extension(OpenSSL::X509::Extension.new("crlNumber", crlnum))
+ extensions.each{|oid, value, critical|
+ crl.add_extension(ef.create_extension(oid, value, critical))
+ }
+ crl.sign(issuer_key, digest)
+ crl
+ end
+
+ def get_subject_key_id(cert)
+ asn1_cert = OpenSSL::ASN1.decode(cert)
+ tbscert = asn1_cert.value[0]
+ pkinfo = tbscert.value[6]
+ publickey = pkinfo.value[1]
+ pkvalue = publickey.value
+ OpenSSL::Digest::SHA1.hexdigest(pkvalue).scan(/../).join(":").upcase
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/optparse/test_getopts.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/optparse/test_getopts.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/optparse/test_getopts.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,32 @@
+require 'test/unit'
+require 'optparse'
+
+class TestOptionParserGetopts < Test::Unit::TestCase
+ def setup
+ @opt = OptionParser.new
+ end
+
+ def test_short_noarg
+ o = @opt.getopts(%w[-a], "ab")
+ assert_equal(true, o['a'])
+ assert_equal(false, o['b'])
+ end
+
+ def test_short_arg
+ o = @opt.getopts(%w[-a1], "a:b:")
+ assert_equal("1", o['a'])
+ assert_equal(nil, o['b'])
+ end
+
+ def test_long_noarg
+ o = @opt.getopts(%w[--foo], "", "foo", "bar")
+ assert_equal(true, o['foo'])
+ assert_equal(false, o['bar'])
+ end
+
+ def test_long_arg
+ o = @opt.getopts(%w[--bar ZOT], "", "foo:FOO", "bar:BAR")
+ assert_equal("FOO", o['foo'])
+ assert_equal("ZOT", o['bar'])
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/optparse/test_noarg.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/optparse/test_noarg.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/optparse/test_noarg.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,59 @@
+require_relative 'test_optparse'
+
+module TestOptionParser::NoArg
+ class Def1 < TestOptionParser
+ include NoArg
+ def setup
+ super
+ @opt.def_option("-x") {|x| @flag = x}
+ @opt.def_option("--option") {|x| @flag = x}
+ end
+ end
+ class Def2 < TestOptionParser
+ include NoArg
+ def setup
+ super
+ @opt.def_option("-x", "--option") {|x| @flag = x}
+ end
+ end
+
+ def test_short
+ assert_raise(OptionParser::InvalidOption) {@opt.parse!(%w"-xq")}
+ assert_equal(%w"", no_error {@opt.parse!(%w"-x")})
+ assert_equal(true, @flag)
+ @flag = nil
+ assert_equal(%w"foo", no_error {@opt.parse!(%w"-x foo")})
+ assert_equal(true, @flag)
+ end
+
+ def test_abbrev
+ assert_raise(OptionParser::InvalidOption) {@opt.parse!(%w"-oq")}
+ assert_equal(%w"", no_error {@opt.parse!(%w"-o")})
+ assert_equal(true, @flag)
+ @flag = nil
+ assert_raise(OptionParser::InvalidOption) {@opt.parse!(%w"-O")}
+ assert_nil(@flag)
+ @flag = nil
+ assert_equal(%w"foo", no_error {@opt.parse!(%w"-o foo")})
+ assert_equal(true, @flag)
+ end
+
+ def test_long
+ assert_raise(OptionParser::NeedlessArgument) {@opt.parse!(%w"--option=x")}
+ assert_equal(%w"", no_error {@opt.parse!(%w"--opt")})
+ assert_equal(true, @flag)
+ @flag = nil
+ assert_equal(%w"foo", no_error {@opt.parse!(%w"--opt foo")})
+ assert_equal(true, @flag)
+ end
+
+ def test_ambiguous
+ skip("[BUG : #860] Assert")
+
+ @opt.def_option("--open") {|x|}
+ assert_raise(OptionParser::AmbiguousOption) {@opt.parse!(%w"--op")}
+ assert_raise(OptionParser::AmbiguousOption) {@opt.parse!(%w"-o")}
+ assert_equal(%w"", no_error {@opt.parse!(%w"--opt")})
+ assert_equal(true, @flag)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/optparse/test_optarg.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/optparse/test_optarg.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/optparse/test_optarg.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,44 @@
+require_relative 'test_optparse'
+
+class TestOptionParser::OptArg < TestOptionParser
+ def setup
+ super
+ @opt.def_option("-x[VAL]") {|x| @flag = x}
+ @opt.def_option("--option[=VAL]") {|x| @flag = x}
+ end
+
+ def test_short
+ assert_equal(%w"", no_error {@opt.parse!(%w"-x")})
+ assert_equal(nil, @flag)
+ @flag = false
+ assert_equal(%w"foo", no_error {@opt.parse!(%w"-x foo")})
+ assert_equal(nil, @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"-xfoo")})
+ assert_equal("foo", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"-x=")})
+ assert_equal("=", @flag)
+ end
+
+ def test_abbrev
+ assert_equal(%w"", no_error {@opt.parse!(%w"-o")})
+ assert_equal(nil, @flag)
+ @flag = false
+ assert_equal(%w"foo", no_error {@opt.parse!(%w"-o foo")})
+ assert_equal(nil, @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"-ofoo")})
+ assert_equal("foo", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"-o=")})
+ assert_equal("=", @flag)
+ end
+
+ def test_long
+ assert_equal(%w"", no_error {@opt.parse!(%w"--opt")})
+ assert_equal(nil, @flag)
+ assert_equal(%w"foo", no_error {@opt.parse!(%w"--opt= foo")})
+ assert_equal("", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"--opt=foo")})
+ assert_equal("foo", @flag)
+ assert_equal(%w"foo", no_error {@opt.parse!(%w"--opt foo")})
+ assert_equal(nil, @flag)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/optparse/test_optparse.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/optparse/test_optparse.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/optparse/test_optparse.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,48 @@
+require 'test/unit'
+require 'optparse'
+
+class TestOptionParser < Test::Unit::TestCase
+ def setup
+ @opt = OptionParser.new
+ @flag = self.class # cannot set by option
+ end
+ def no_error(*args)
+ assert_nothing_raised(*args) {return yield}
+ ensure
+ $!.backtrace.delete_if {|e| /\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}/o =~ e} if $!
+ end
+
+ def test_permute
+ assert_equal(%w"", no_error {@opt.permute!(%w"")})
+ assert_equal(self.class, @flag)
+ assert_equal(%w"foo bar", no_error {@opt.permute!(%w"foo bar")})
+ assert_equal(self.class, @flag)
+ assert_equal(%w"- foo bar", no_error {@opt.permute!(%w"- foo bar")})
+ assert_equal(self.class, @flag)
+ assert_equal(%w"foo bar", no_error {@opt.permute!(%w"-- foo bar")})
+ assert_equal(self.class, @flag)
+ assert_equal(%w"foo - bar", no_error {@opt.permute!(%w"foo - bar")})
+ assert_equal(self.class, @flag)
+ assert_equal(%w"foo bar", no_error {@opt.permute!(%w"foo -- bar")})
+ assert_equal(self.class, @flag)
+ assert_equal(%w"foo --help bar", no_error {@opt.permute!(%w"foo -- --help bar")})
+ assert_equal(self.class, @flag)
+ end
+
+ def test_order
+ assert_equal(%w"", no_error {@opt.order!(%w"")})
+ assert_equal(self.class, @flag)
+ assert_equal(%w"foo bar", no_error {@opt.order!(%w"foo bar")})
+ assert_equal(self.class, @flag)
+ assert_equal(%w"- foo bar", no_error {@opt.order!(%w"- foo bar")})
+ assert_equal(self.class, @flag)
+ assert_equal(%w"foo bar", no_error {@opt.permute!(%w"-- foo bar")})
+ assert_equal(self.class, @flag)
+ assert_equal(%w"foo - bar", no_error {@opt.order!(%w"foo - bar")})
+ assert_equal(self.class, @flag)
+ assert_equal(%w"foo -- bar", no_error {@opt.order!(%w"foo -- bar")})
+ assert_equal(self.class, @flag)
+ assert_equal(%w"foo -- --help bar", no_error {@opt.order!(%w"foo -- --help bar")})
+ assert_equal(self.class, @flag)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/optparse/test_placearg.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/optparse/test_placearg.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/optparse/test_placearg.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,53 @@
+require_relative 'test_optparse'
+
+class TestOptionParser::PlaceArg < TestOptionParser
+ def setup
+ super
+ @opt.def_option("-x [VAL]") {|x| @flag = x}
+ @opt.def_option("--option [VAL]") {|x| @flag = x}
+ @opt.def_option("-T [level]", /^[0-4]$/, Integer) {|x| @topt = x}
+ @opt.def_option("-n") {}
+ end
+
+ def test_short
+ assert_equal(%w"", no_error {@opt.parse!(%w"-x -n")})
+ assert_equal(nil, @flag)
+ @flag = false
+ assert_equal(%w"", no_error {@opt.parse!(%w"-x foo")})
+ assert_equal("foo", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"-xbar")})
+ assert_equal("bar", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"-x=")})
+ assert_equal("=", @flag)
+ end
+
+ def test_abbrev
+ assert_equal(%w"", no_error {@opt.parse!(%w"-o -n")})
+ assert_equal(nil, @flag)
+ @flag = false
+ assert_equal(%w"", no_error {@opt.parse!(%w"-o foo")})
+ assert_equal("foo", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"-obar")})
+ assert_equal("bar", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"-o=")})
+ assert_equal("=", @flag)
+ end
+
+ def test_long
+ assert_equal(%w"", no_error {@opt.parse!(%w"--opt -n")})
+ assert_equal(nil, @flag)
+ assert_equal(%w"foo", no_error {@opt.parse!(%w"--opt= foo")})
+ assert_equal("", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"--opt=foo")})
+ assert_equal("foo", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"--opt bar")})
+ assert_equal("bar", @flag)
+ end
+
+ def test_conv
+ assert_equal(%w"te.rb", no_error('[ruby-dev:38333]') {@opt.parse!(%w"-T te.rb")})
+ assert_nil(@topt)
+ assert_equal(%w"te.rb", no_error('[ruby-dev:38333]') {@opt.parse!(%w"-T1 te.rb")})
+ assert_equal(1, @topt)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/optparse/test_reqarg.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/optparse/test_reqarg.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/optparse/test_reqarg.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,75 @@
+require_relative 'test_optparse'
+
+module TestOptionParser::ReqArg
+ class Def1 < TestOptionParser
+ include ReqArg
+ def setup
+ super
+ @opt.def_option("-xVAL") {|x| @flag = x}
+ @opt.def_option("--option=VAL") {|x| @flag = x}
+ end
+ end
+ class Def2 < TestOptionParser
+ include ReqArg
+ def setup
+ super
+ @opt.def_option("-x", "--option=VAL") {|x| @flag = x}
+ end
+ end
+ class Def3 < TestOptionParser
+ include ReqArg
+ def setup
+ super
+ @opt.def_option("--option=VAL", "-x") {|x| @flag = x}
+ end
+ end
+ class Def4 < TestOptionParser
+ include ReqArg
+ def setup
+ super
+ @opt.def_option("-xVAL", "--option=VAL") {|x| @flag = x}
+ end
+ end
+
+ def test_short
+ assert_raise(OptionParser::MissingArgument) {@opt.parse!(%w"-x")}
+ assert_equal(%w"", no_error {@opt.parse!(%w"-x foo")})
+ assert_equal("foo", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"-xbar")})
+ assert_equal("bar", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"-x=")})
+ assert_equal("=", @flag)
+ end
+
+ def test_abbrev
+ assert_raise(OptionParser::MissingArgument) {@opt.parse!(%w"-o")}
+ assert_equal(%w"", no_error {@opt.parse!(%w"-o foo")})
+ assert_equal("foo", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"-obar")})
+ assert_equal("bar", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"-o=")})
+ assert_equal("=", @flag)
+ end
+
+ def test_long
+ assert_raise(OptionParser::MissingArgument) {@opt.parse!(%w"--opt")}
+ assert_equal(%w"", no_error {@opt.parse!(%w"--opt foo")})
+ assert_equal("foo", @flag)
+ assert_equal(%w"foo", no_error {@opt.parse!(%w"--opt= foo")})
+ assert_equal("", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"--opt=foo")})
+ assert_equal("foo", @flag)
+ end
+
+ class TestOptionParser::WithPattern < TestOptionParser
+ def test_pattern
+ pat = num = nil
+ @opt.def_option("--pattern=VAL", /(\w+)(?:\s*:\s*(\w+))?/) {|x, y, z| pat = [x, y, z]}
+ @opt.def_option("-T NUM", /\A[1-4]\z/) {|n| num = n}
+ no_error {@opt.parse!(%w"--pattern=key:val")}
+ assert_equal(%w"key:val key val", pat, '[ruby-list:45645]')
+ no_error {@opt.parse!(%w"-T 4")}
+ assert_equal("4", num, '[ruby-dev:37514]')
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/optparse/test_summary.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/optparse/test_summary.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/optparse/test_summary.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,21 @@
+require_relative 'test_optparse'
+
+class TestOptionParser::SummaryTest < TestOptionParser
+ def test_short_clash
+ r = nil
+ o = OptionParser.new do |opts|
+ opts.on("-f", "--first-option", "description 1", "description 2"){r = "first-option"}
+ opts.on("-t", "--test-option"){r = "test-option"}
+ opts.on("-t", "--another-test-option"){r = "another-test-option"}
+ opts.separator "this is\nseparator"
+ opts.on("-l", "--last-option"){r = "last-option"}
+ end
+ s = o.summarize
+ o.parse("-t")
+ assert_match(/--#{r}/, s.grep(/^\s*-t,/)[0])
+ assert_match(/first-option/, s[0])
+ assert_match(/description 1/, s[0])
+ assert_match(/description 2/, s[1])
+ assert_match(/last-option/, s[-1])
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ostruct/test_ostruct.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ostruct/test_ostruct.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ostruct/test_ostruct.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,51 @@
+require 'test/unit'
+require 'ostruct'
+
+class TC_OpenStruct < Test::Unit::TestCase
+ def test_equality
+ o1 = OpenStruct.new
+ o2 = OpenStruct.new
+ assert_equal(o1, o2)
+
+ o1.a = 'a'
+ assert_not_equal(o1, o2)
+
+ o2.a = 'a'
+ assert_equal(o1, o2)
+
+ o1.a = 'b'
+ assert_not_equal(o1, o2)
+
+ o2 = Object.new
+ o2.instance_eval{@table = {:a => 'b'}}
+ assert_not_equal(o1, o2)
+ end
+
+ def test_inspect
+ foo = OpenStruct.new
+ assert_equal("#<OpenStruct>", foo.inspect)
+ foo.bar = 1
+ foo.baz = 2
+ assert_equal("#<OpenStruct bar=1, baz=2>", foo.inspect)
+
+ foo = OpenStruct.new
+ foo.bar = OpenStruct.new
+ assert_equal('#<OpenStruct bar=#<OpenStruct>>', foo.inspect)
+ foo.bar.foo = foo
+ assert_equal('#<OpenStruct bar=#<OpenStruct foo=#<OpenStruct ...>>>', foo.inspect)
+ end
+
+ def test_frozen
+ o = OpenStruct.new
+ o.a = 'a'
+ o.freeze
+ assert_raise(TypeError) {o.b = 'b'}
+ assert_not_respond_to(o, :b)
+ assert_raise(TypeError) {o.a = 'z'}
+ assert_equal('a', o.a)
+ o = OpenStruct.new :a => 42
+ def o.frozen?; nil end
+ o.freeze
+ assert_raise(TypeError, '[ruby-core:22559]') {o.a = 1764}
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/pathname/test_pathname.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/pathname/test_pathname.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/pathname/test_pathname.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,608 @@
+#!/usr/bin/env ruby
+
+require 'test/unit'
+require 'pathname'
+
+require 'fileutils'
+require 'tmpdir'
+require 'enumerator'
+
+class TestPathname < Test::Unit::TestCase
+ def self.define_assertion(name, &block)
+ @defassert_num ||= {}
+ @defassert_num[name] ||= 0
+ @defassert_num[name] += 1
+ define_method("test_#{name}_#{@defassert_num[name]}", &block)
+ end
+
+ def self.defassert(name, result, *args)
+ define_assertion(name) {
+ assert_equal(result, self.send(name, *args), "#{name}(#{args.map {|a| a.inspect }.join(', ')})")
+ }
+ end
+
+ DOSISH = File::ALT_SEPARATOR != nil
+ DOSISH_DRIVE_LETTER = File.dirname("A:") == "A:."
+ DOSISH_UNC = File.dirname("//") == "//"
+
+ def cleanpath_aggressive(path)
+ Pathname.new(path).cleanpath.to_s
+ end
+
+ defassert(:cleanpath_aggressive, '/', '/')
+ defassert(:cleanpath_aggressive, '.', '')
+ defassert(:cleanpath_aggressive, '.', '.')
+ defassert(:cleanpath_aggressive, '..', '..')
+ defassert(:cleanpath_aggressive, 'a', 'a')
+ defassert(:cleanpath_aggressive, '/', '/.')
+ defassert(:cleanpath_aggressive, '/', '/..')
+ defassert(:cleanpath_aggressive, '/a', '/a')
+ defassert(:cleanpath_aggressive, '.', './')
+ defassert(:cleanpath_aggressive, '..', '../')
+ defassert(:cleanpath_aggressive, 'a', 'a/')
+ defassert(:cleanpath_aggressive, 'a/b', 'a//b')
+ defassert(:cleanpath_aggressive, 'a', 'a/.')
+ defassert(:cleanpath_aggressive, 'a', 'a/./')
+ defassert(:cleanpath_aggressive, '.', 'a/..')
+ defassert(:cleanpath_aggressive, '.', 'a/../')
+ defassert(:cleanpath_aggressive, '/a', '/a/.')
+ defassert(:cleanpath_aggressive, '..', './..')
+ defassert(:cleanpath_aggressive, '..', '../.')
+ defassert(:cleanpath_aggressive, '..', './../')
+ defassert(:cleanpath_aggressive, '..', '.././')
+ defassert(:cleanpath_aggressive, '/', '/./..')
+ defassert(:cleanpath_aggressive, '/', '/../.')
+ defassert(:cleanpath_aggressive, '/', '/./../')
+ defassert(:cleanpath_aggressive, '/', '/.././')
+ defassert(:cleanpath_aggressive, 'a/b/c', 'a/b/c')
+ defassert(:cleanpath_aggressive, 'b/c', './b/c')
+ defassert(:cleanpath_aggressive, 'a/c', 'a/./c')
+ defassert(:cleanpath_aggressive, 'a/b', 'a/b/.')
+ defassert(:cleanpath_aggressive, '.', 'a/../.')
+ defassert(:cleanpath_aggressive, '/a', '/../.././../a')
+ defassert(:cleanpath_aggressive, '../../d', 'a/b/../../../../c/../d')
+
+ if DOSISH_UNC
+ defassert(:cleanpath_aggressive, '//a/b/c', '//a/b/c/')
+ else
+ defassert(:cleanpath_aggressive, '/', '///')
+ defassert(:cleanpath_aggressive, '/a', '///a')
+ defassert(:cleanpath_aggressive, '/', '///..')
+ defassert(:cleanpath_aggressive, '/', '///.')
+ defassert(:cleanpath_aggressive, '/', '///a/../..')
+ end
+
+ def cleanpath_conservative(path)
+ Pathname.new(path).cleanpath(true).to_s
+ end
+
+ defassert(:cleanpath_conservative, '/', '/')
+ defassert(:cleanpath_conservative, '.', '')
+ defassert(:cleanpath_conservative, '.', '.')
+ defassert(:cleanpath_conservative, '..', '..')
+ defassert(:cleanpath_conservative, 'a', 'a')
+ defassert(:cleanpath_conservative, '/', '/.')
+ defassert(:cleanpath_conservative, '/', '/..')
+ defassert(:cleanpath_conservative, '/a', '/a')
+ defassert(:cleanpath_conservative, '.', './')
+ defassert(:cleanpath_conservative, '..', '../')
+ defassert(:cleanpath_conservative, 'a/', 'a/')
+ defassert(:cleanpath_conservative, 'a/b', 'a//b')
+ defassert(:cleanpath_conservative, 'a/.', 'a/.')
+ defassert(:cleanpath_conservative, 'a/.', 'a/./')
+ defassert(:cleanpath_conservative, 'a/..', 'a/../')
+ defassert(:cleanpath_conservative, '/a/.', '/a/.')
+ defassert(:cleanpath_conservative, '..', './..')
+ defassert(:cleanpath_conservative, '..', '../.')
+ defassert(:cleanpath_conservative, '..', './../')
+ defassert(:cleanpath_conservative, '..', '.././')
+ defassert(:cleanpath_conservative, '/', '/./..')
+ defassert(:cleanpath_conservative, '/', '/../.')
+ defassert(:cleanpath_conservative, '/', '/./../')
+ defassert(:cleanpath_conservative, '/', '/.././')
+ defassert(:cleanpath_conservative, 'a/b/c', 'a/b/c')
+ defassert(:cleanpath_conservative, 'b/c', './b/c')
+ defassert(:cleanpath_conservative, 'a/c', 'a/./c')
+ defassert(:cleanpath_conservative, 'a/b/.', 'a/b/.')
+ defassert(:cleanpath_conservative, 'a/..', 'a/../.')
+ defassert(:cleanpath_conservative, '/a', '/../.././../a')
+ defassert(:cleanpath_conservative, 'a/b/../../../../c/../d', 'a/b/../../../../c/../d')
+
+ if DOSISH_UNC
+ defassert(:cleanpath_conservative, '//', '//')
+ else
+ defassert(:cleanpath_conservative, '/', '//')
+ end
+
+ # has_trailing_separator?(path) -> bool
+ def has_trailing_separator?(path)
+ Pathname.allocate.__send__(:has_trailing_separator?, path)
+ end
+
+ defassert(:has_trailing_separator?, false, "/")
+ defassert(:has_trailing_separator?, false, "///")
+ defassert(:has_trailing_separator?, false, "a")
+ defassert(:has_trailing_separator?, true, "a/")
+
+ def add_trailing_separator(path)
+ Pathname.allocate.__send__(:add_trailing_separator, path)
+ end
+
+ def del_trailing_separator(path)
+ Pathname.allocate.__send__(:del_trailing_separator, path)
+ end
+
+ defassert(:del_trailing_separator, "/", "/")
+ defassert(:del_trailing_separator, "/a", "/a")
+ defassert(:del_trailing_separator, "/a", "/a/")
+ defassert(:del_trailing_separator, "/a", "/a//")
+ defassert(:del_trailing_separator, ".", ".")
+ defassert(:del_trailing_separator, ".", "./")
+ defassert(:del_trailing_separator, ".", ".//")
+
+ if DOSISH_DRIVE_LETTER
+ defassert(:del_trailing_separator, "A:", "A:")
+ defassert(:del_trailing_separator, "A:/", "A:/")
+ defassert(:del_trailing_separator, "A:/", "A://")
+ defassert(:del_trailing_separator, "A:.", "A:.")
+ defassert(:del_trailing_separator, "A:.", "A:./")
+ defassert(:del_trailing_separator, "A:.", "A:.//")
+ end
+
+ if DOSISH_UNC
+ defassert(:del_trailing_separator, "//", "//")
+ defassert(:del_trailing_separator, "//a", "//a")
+ defassert(:del_trailing_separator, "//a", "//a/")
+ defassert(:del_trailing_separator, "//a", "//a//")
+ defassert(:del_trailing_separator, "//a/b", "//a/b")
+ defassert(:del_trailing_separator, "//a/b", "//a/b/")
+ defassert(:del_trailing_separator, "//a/b", "//a/b//")
+ defassert(:del_trailing_separator, "//a/b/c", "//a/b/c")
+ defassert(:del_trailing_separator, "//a/b/c", "//a/b/c/")
+ defassert(:del_trailing_separator, "//a/b/c", "//a/b/c//")
+ else
+ defassert(:del_trailing_separator, "/", "///")
+ defassert(:del_trailing_separator, "///a", "///a/")
+ end
+
+ if DOSISH
+ defassert(:del_trailing_separator, "a", "a\\")
+ require 'Win32API'
+ if Win32API.new('kernel32', 'GetACP', nil, 'L').call == 932
+ defassert(:del_trailing_separator, "\225\\", "\225\\\\") # SJIS
+ end
+ end
+
+ def plus(path1, path2) # -> path
+ (Pathname.new(path1) + Pathname.new(path2)).to_s
+ end
+
+ defassert(:plus, '/', '/', '/')
+ defassert(:plus, 'a/b', 'a', 'b')
+ defassert(:plus, 'a', 'a', '.')
+ defassert(:plus, 'b', '.', 'b')
+ defassert(:plus, '.', '.', '.')
+ defassert(:plus, '/b', 'a', '/b')
+
+ defassert(:plus, '/', '/', '..')
+ defassert(:plus, '.', 'a', '..')
+ defassert(:plus, 'a', 'a/b', '..')
+ defassert(:plus, '../..', '..', '..')
+ defassert(:plus, '/c', '/', '../c')
+ defassert(:plus, 'c', 'a', '../c')
+ defassert(:plus, 'a/c', 'a/b', '../c')
+ defassert(:plus, '../../c', '..', '../c')
+
+ defassert(:plus, 'a//b/d//e', 'a//b/c', '../d//e')
+
+ def relative?(path)
+ Pathname.new(path).relative?
+ end
+
+ defassert(:relative?, false, '/')
+ defassert(:relative?, false, '/a')
+ defassert(:relative?, false, '/..')
+ defassert(:relative?, true, 'a')
+ defassert(:relative?, true, 'a/b')
+
+ if DOSISH_DRIVE_LETTER
+ defassert(:relative?, false, 'A:')
+ defassert(:relative?, false, 'A:/')
+ defassert(:relative?, false, 'A:/a')
+ end
+
+ if File.dirname('//') == '//'
+ defassert(:relative?, false, '//')
+ defassert(:relative?, false, '//a')
+ defassert(:relative?, false, '//a/')
+ defassert(:relative?, false, '//a/b')
+ defassert(:relative?, false, '//a/b/')
+ defassert(:relative?, false, '//a/b/c')
+ end
+
+ def relative_path_from(dest_directory, base_directory)
+ Pathname.new(dest_directory).relative_path_from(Pathname.new(base_directory)).to_s
+ end
+
+ defassert(:relative_path_from, "../a", "a", "b")
+ defassert(:relative_path_from, "../a", "a", "b/")
+ defassert(:relative_path_from, "../a", "a/", "b")
+ defassert(:relative_path_from, "../a", "a/", "b/")
+ defassert(:relative_path_from, "../a", "/a", "/b")
+ defassert(:relative_path_from, "../a", "/a", "/b/")
+ defassert(:relative_path_from, "../a", "/a/", "/b")
+ defassert(:relative_path_from, "../a", "/a/", "/b/")
+
+ defassert(:relative_path_from, "../b", "a/b", "a/c")
+ defassert(:relative_path_from, "../a", "../a", "../b")
+
+ defassert(:relative_path_from, "a", "a", ".")
+ defassert(:relative_path_from, "..", ".", "a")
+
+ defassert(:relative_path_from, ".", ".", ".")
+ defassert(:relative_path_from, ".", "..", "..")
+ defassert(:relative_path_from, "..", "..", ".")
+
+ defassert(:relative_path_from, "c/d", "/a/b/c/d", "/a/b")
+ defassert(:relative_path_from, "../..", "/a/b", "/a/b/c/d")
+ defassert(:relative_path_from, "../../../../e", "/e", "/a/b/c/d")
+ defassert(:relative_path_from, "../b/c", "a/b/c", "a/d")
+
+ defassert(:relative_path_from, "../a", "/../a", "/b")
+ defassert(:relative_path_from, "../../a", "../a", "b")
+ defassert(:relative_path_from, ".", "/a/../../b", "/b")
+ defassert(:relative_path_from, "..", "a/..", "a")
+ defassert(:relative_path_from, ".", "a/../b", "b")
+
+ defassert(:relative_path_from, "a", "a", "b/..")
+ defassert(:relative_path_from, "b/c", "b/c", "b/..")
+
+ def self.defassert_raise(name, exc, *args)
+ define_assertion(name) {
+ message = "#{name}(#{args.map {|a| a.inspect }.join(', ')})"
+ assert_raise(exc, message) { self.send(name, *args) }
+ }
+ end
+
+ defassert_raise(:relative_path_from, ArgumentError, "/", ".")
+ defassert_raise(:relative_path_from, ArgumentError, ".", "/")
+ defassert_raise(:relative_path_from, ArgumentError, "a", "..")
+ defassert_raise(:relative_path_from, ArgumentError, ".", "..")
+
+ def with_tmpchdir(base=nil)
+ Dir.mktmpdir(base) {|d|
+ d = Pathname.new(d).realpath.to_s
+ Dir.chdir(d) {
+ yield d
+ }
+ }
+ end
+
+ def has_symlink?
+ begin
+ File.symlink(nil, nil)
+ rescue NotImplementedError
+ return false
+ rescue TypeError
+ end
+ return true
+ end
+
+ def realpath(path, basedir=nil)
+ Pathname.new(path).realpath(basedir).to_s
+ end
+
+ def test_realpath
+ return if !has_symlink?
+ with_tmpchdir('rubytest-pathname') {|dir|
+ assert_raise(Errno::ENOENT) { realpath("#{dir}/not-exist") }
+ File.symlink("not-exist-target", "#{dir}/not-exist")
+ assert_raise(Errno::ENOENT) { realpath("#{dir}/not-exist") }
+
+ File.symlink("loop", "#{dir}/loop")
+ assert_raise(Errno::ELOOP) { realpath("#{dir}/loop") }
+ assert_raise(Errno::ELOOP) { realpath("#{dir}/loop", dir) }
+
+ File.symlink("../#{File.basename(dir)}/./not-exist-target", "#{dir}/not-exist2")
+ assert_raise(Errno::ENOENT) { realpath("#{dir}/not-exist2") }
+
+ File.open("#{dir}/exist-target", "w") {}
+ File.symlink("../#{File.basename(dir)}/./exist-target", "#{dir}/exist2")
+ assert_nothing_raised { realpath("#{dir}/exist2") }
+
+ File.symlink("loop-relative", "loop-relative")
+ assert_raise(Errno::ELOOP) { realpath("#{dir}/loop-relative") }
+
+ Dir.mkdir("exist")
+ assert_equal("#{dir}/exist", realpath("exist"))
+ assert_raise(Errno::ELOOP) { realpath("../loop", "#{dir}/exist") }
+
+ File.symlink("loop1/loop1", "loop1")
+ assert_raise(Errno::ELOOP) { realpath("#{dir}/loop1") }
+
+ File.symlink("loop2", "loop3")
+ File.symlink("loop3", "loop2")
+ assert_raise(Errno::ELOOP) { realpath("#{dir}/loop2") }
+
+ Dir.mkdir("b")
+
+ File.symlink("b", "c")
+ assert_equal("#{dir}/b", realpath("c"))
+ assert_equal("#{dir}/b", realpath("c/../c"))
+ assert_equal("#{dir}/b", realpath("c/../c/../c/."))
+
+ File.symlink("..", "b/d")
+ assert_equal("#{dir}/b", realpath("c/d/c/d/c"))
+
+ File.symlink("#{dir}/b", "e")
+ assert_equal("#{dir}/b", realpath("e"))
+
+ Dir.mkdir("f")
+ Dir.mkdir("f/g")
+ File.symlink("f/g", "h")
+ assert_equal("#{dir}/f/g", realpath("h"))
+ File.chmod(0000, "f")
+ assert_raise(Errno::EACCES) { realpath("h") }
+ File.chmod(0755, "f")
+ }
+ end
+
+ def realdirpath(path)
+ Pathname.new(path).realdirpath.to_s
+ end
+
+ def test_realdirpath
+ return if !has_symlink?
+ Dir.mktmpdir('rubytest-pathname') {|dir|
+ rdir = realpath(dir)
+ assert_equal("#{rdir}/not-exist", realdirpath("#{dir}/not-exist"))
+ assert_raise(Errno::ENOENT) { realdirpath("#{dir}/not-exist/not-exist-child") }
+ File.symlink("not-exist-target", "#{dir}/not-exist")
+ assert_equal("#{rdir}/not-exist-target", realdirpath("#{dir}/not-exist"))
+ File.symlink("../#{File.basename(dir)}/./not-exist-target", "#{dir}/not-exist2")
+ assert_equal("#{rdir}/not-exist-target", realdirpath("#{dir}/not-exist2"))
+ File.open("#{dir}/exist-target", "w") {}
+ File.symlink("../#{File.basename(dir)}/./exist-target", "#{dir}/exist")
+ assert_equal("#{rdir}/exist-target", realdirpath("#{dir}/exist"))
+ File.symlink("loop", "#{dir}/loop")
+ assert_raise(Errno::ELOOP) { realdirpath("#{dir}/loop") }
+ }
+ end
+
+ def descend(path)
+ Pathname.new(path).enum_for(:descend).map {|v| v.to_s }
+ end
+
+ defassert(:descend, %w[/ /a /a/b /a/b/c], "/a/b/c")
+ defassert(:descend, %w[a a/b a/b/c], "a/b/c")
+ defassert(:descend, %w[. ./a ./a/b ./a/b/c], "./a/b/c")
+ defassert(:descend, %w[a/], "a/")
+
+ def ascend(path)
+ Pathname.new(path).enum_for(:ascend).map {|v| v.to_s }
+ end
+
+ defassert(:ascend, %w[/a/b/c /a/b /a /], "/a/b/c")
+ defassert(:ascend, %w[a/b/c a/b a], "a/b/c")
+ defassert(:ascend, %w[./a/b/c ./a/b ./a .], "./a/b/c")
+ defassert(:ascend, %w[a/], "a/")
+
+ def test_initialize
+ p1 = Pathname.new('a')
+ assert_equal('a', p1.to_s)
+ p2 = Pathname.new(p1)
+ assert_equal(p1, p2)
+ end
+
+ def test_initialize_nul
+ assert_raise(ArgumentError) { Pathname.new("a\0") }
+ end
+
+ class AnotherStringLike # :nodoc:
+ def initialize(s) @s = s end
+ def to_str() @s end
+ def ==(other) @s == other end
+ end
+
+ def test_equality
+ obj = Pathname.new("a")
+ str = "a"
+ sym = :a
+ ano = AnotherStringLike.new("a")
+ assert_equal(false, obj == str)
+ assert_equal(false, str == obj)
+ assert_equal(false, obj == ano)
+ assert_equal(false, ano == obj)
+ assert_equal(false, obj == sym)
+ assert_equal(false, sym == obj)
+
+ obj2 = Pathname.new("a")
+ assert_equal(true, obj == obj2)
+ assert_equal(true, obj === obj2)
+ assert_equal(true, obj.eql?(obj2))
+ end
+
+ def test_hashkey
+ h = {}
+ h[Pathname.new("a")] = 1
+ h[Pathname.new("a")] = 2
+ assert_equal(1, h.size)
+ end
+
+ def assert_pathname_cmp(e, s1, s2)
+ p1 = Pathname.new(s1)
+ p2 = Pathname.new(s2)
+ r = p1 <=> p2
+ assert(e == r,
+ "#{p1.inspect} <=> #{p2.inspect}: <#{e}> expected but was <#{r}>")
+ end
+ def test_comparison
+ assert_pathname_cmp( 0, "a", "a")
+ assert_pathname_cmp( 1, "b", "a")
+ assert_pathname_cmp(-1, "a", "b")
+ ss = %w(
+ a
+ a/
+ a/b
+ a.
+ a0
+ )
+ s1 = ss.shift
+ ss.each {|s2|
+ assert_pathname_cmp(-1, s1, s2)
+ s1 = s2
+ }
+ end
+
+ def test_comparison_string
+ assert_equal(nil, Pathname.new("a") <=> "a")
+ assert_equal(nil, "a" <=> Pathname.new("a"))
+ end
+
+ def pathsub(path, pat, repl) Pathname.new(path).sub(pat, repl).to_s end
+ defassert(:pathsub, "a.o", "a.c", /\.c\z/, ".o")
+
+ def pathsubext(path, repl) Pathname.new(path).sub_ext(repl).to_s end
+ defassert(:pathsubext, 'a.o', 'a.c', '.o')
+ defassert(:pathsubext, 'a.o', 'a.c++', '.o')
+ defassert(:pathsubext, 'a.png', 'a.gif', '.png')
+ defassert(:pathsubext, 'ruby.tar.bz2', 'ruby.tar.gz', '.bz2')
+ defassert(:pathsubext, 'd/a.o', 'd/a.c', '.o')
+ defassert(:pathsubext, 'foo', 'foo.exe', '')
+ defassert(:pathsubext, 'lex.yy.o', 'lex.yy.c', '.o')
+ defassert(:pathsubext, 'fooaa.o', 'fooaa', '.o')
+ defassert(:pathsubext, 'd.e/aa.o', 'd.e/aa', '.o')
+
+ def test_sub_matchdata
+ result = Pathname("abc.gif").sub(/\..*/) {
+ assert_not_nil($~)
+ assert_equal(".gif", $~[0])
+ ".png"
+ }
+ assert_equal("abc.png", result.to_s)
+ end
+
+ def root?(path)
+ Pathname.new(path).root?
+ end
+
+ defassert(:root?, true, "/")
+ defassert(:root?, true, "//")
+ defassert(:root?, true, "///")
+ defassert(:root?, false, "")
+ defassert(:root?, false, "a")
+
+ def test_destructive_update
+ path = Pathname.new("a")
+ path.to_s.replace "b"
+ assert_equal(Pathname.new("a"), path)
+ end
+
+ def test_null_character
+ assert_raise(ArgumentError) { Pathname.new("\0") }
+ end
+
+ def test_taint
+ obj = Pathname.new("a"); assert_same(obj, obj.taint)
+ obj = Pathname.new("a"); assert_same(obj, obj.untaint)
+
+ assert_equal(false, Pathname.new("a" ) .tainted?)
+ assert_equal(false, Pathname.new("a" ) .to_s.tainted?)
+ assert_equal(true, Pathname.new("a" ).taint .tainted?)
+ assert_equal(true, Pathname.new("a" ).taint.to_s.tainted?)
+ assert_equal(true, Pathname.new("a".taint) .tainted?)
+ assert_equal(true, Pathname.new("a".taint) .to_s.tainted?)
+ assert_equal(true, Pathname.new("a".taint).taint .tainted?)
+ assert_equal(true, Pathname.new("a".taint).taint.to_s.tainted?)
+
+ str = "a"
+ path = Pathname.new(str)
+ str.taint
+ assert_equal(false, path .tainted?)
+ assert_equal(false, path.to_s.tainted?)
+ end
+
+ def test_untaint
+ obj = Pathname.new("a"); assert_same(obj, obj.untaint)
+
+ assert_equal(false, Pathname.new("a").taint.untaint .tainted?)
+ assert_equal(false, Pathname.new("a").taint.untaint.to_s.tainted?)
+
+ str = "a".taint
+ path = Pathname.new(str)
+ str.untaint
+ assert_equal(true, path .tainted?)
+ assert_equal(true, path.to_s.tainted?)
+ end
+
+ def test_freeze
+ obj = Pathname.new("a"); assert_same(obj, obj.freeze)
+
+ assert_equal(false, Pathname.new("a" ) .frozen?)
+ assert_equal(false, Pathname.new("a".freeze) .frozen?)
+ assert_equal(true, Pathname.new("a" ).freeze .frozen?)
+ assert_equal(true, Pathname.new("a".freeze).freeze .frozen?)
+ assert_equal(false, Pathname.new("a" ) .to_s.frozen?)
+ assert_equal(false, Pathname.new("a".freeze) .to_s.frozen?)
+ assert_equal(false, Pathname.new("a" ).freeze.to_s.frozen?)
+ assert_equal(false, Pathname.new("a".freeze).freeze.to_s.frozen?)
+ end
+
+ def test_to_s
+ str = "a"
+ obj = Pathname.new(str)
+ assert_equal(str, obj.to_s)
+ assert_not_same(str, obj.to_s)
+ assert_not_same(obj.to_s, obj.to_s)
+ end
+
+ def test_kernel_open
+ count = 0
+ result = Kernel.open(Pathname.new(__FILE__)) {|f|
+ assert(File.identical?(__FILE__, f))
+ count += 1
+ 2
+ }
+ assert_equal(1, count)
+ assert_equal(2, result)
+ end
+
+ def test_each_filename
+ result = []
+ Pathname.new("/usr/bin/ruby").each_filename {|f| result << f }
+ assert_equal(%w[usr bin ruby], result)
+ assert_equal(%w[usr bin ruby], Pathname.new("/usr/bin/ruby").each_filename.to_a)
+ end
+
+ def test_kernel_pathname
+ assert_equal(Pathname.new("a"), Pathname("a"))
+ end
+
+ def test_file_basename
+ assert_equal("bar", File.basename(Pathname.new("foo/bar")))
+ end
+
+ def test_file_dirname
+ assert_equal("foo", File.dirname(Pathname.new("foo/bar")))
+ end
+
+ def test_file_split
+ assert_equal(["foo", "bar"], File.split(Pathname.new("foo/bar")))
+ end
+
+ def test_file_extname
+ assert_equal(".baz", File.extname(Pathname.new("bar.baz")))
+ end
+
+ def test_file_fnmatch
+ assert(File.fnmatch("*.*", Pathname.new("bar.baz")))
+ end
+
+ def test_file_join
+ assert_equal("foo/bar", File.join(Pathname.new("foo"), Pathname.new("bar")))
+ lambda {
+ $SAFE = 1
+ assert_equal("foo/bar", File.join(Pathname.new("foo"), Pathname.new("bar").taint))
+ }.call
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/helper.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/helper.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/helper.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,63 @@
+require 'minitest/autorun'
+require 'stringio'
+require 'tempfile'
+require 'date'
+
+module Psych
+ class TestCase < MiniTest::Unit::TestCase
+ #
+ # Convert between Psych and the object to verify correct parsing and
+ # emitting
+ #
+ def assert_to_yaml( obj, yaml )
+ assert_equal( obj, Psych::load( yaml ) )
+ assert_equal( obj, Psych::parse( yaml ).transform )
+ assert_equal( obj, Psych::load( obj.psych_to_yaml ) )
+ assert_equal( obj, Psych::parse( obj.psych_to_yaml ).transform )
+ assert_equal( obj, Psych::load(
+ obj.psych_to_yaml(
+ :UseVersion => true, :UseHeader => true, :SortKeys => true
+ )
+ ))
+ end
+
+ #
+ # Test parser only
+ #
+ def assert_parse_only( obj, yaml )
+ assert_equal( obj, Psych::load( yaml ) )
+ assert_equal( obj, Psych::parse( yaml ).transform )
+ end
+
+ def assert_cycle( obj )
+ v = Visitors::YAMLTree.new
+ v << obj
+ assert_equal(obj, Psych.load(v.tree.to_yaml))
+ assert_equal( obj, Psych::load(Psych.dump(obj)))
+ assert_equal( obj, Psych::load( obj.psych_to_yaml ) )
+ end
+
+ #
+ # Make a time with the time zone
+ #
+ def mktime( year, mon, day, hour, min, sec, usec, zone = "Z" )
+ usec = Rational(usec.to_s) * 1000000
+ val = Time::utc( year.to_i, mon.to_i, day.to_i, hour.to_i, min.to_i, sec.to_i, usec )
+ if zone != "Z"
+ hour = zone[0,3].to_i * 3600
+ min = zone[3,2].to_i * 60
+ ofs = (hour + min)
+ val = Time.at( val.tv_sec - ofs, val.tv_nsec / 1000.0 )
+ end
+ return val
+ end
+ end
+end
+
+require 'psych'
+
+# FIXME: remove this when syck is removed
+o = Object.new
+a = o.method(:psych_to_yaml)
+b = o.method(:to_yaml)
+raise "psych should define to_yaml" unless a == b
Added: MacRuby/trunk/test/test-mri/test/psych/test_alias_and_anchor.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_alias_and_anchor.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_alias_and_anchor.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,26 @@
+require_relative 'helper'
+
+module Psych
+ class TestAliasAndAnchor < TestCase
+ def test_mri_compatibility
+ yaml = <<EOYAML
+---
+- &id001 !ruby/object {}
+
+- *id001
+- *id001
+EOYAML
+ result = Psych.load yaml
+ result.each {|el| assert_same(result[0], el) }
+ end
+
+ def test_anchor_alias_round_trip
+ o = Object.new
+ original = [o,o,o]
+
+ yaml = Psych.dump original
+ result = Psych.load yaml
+ result.each {|el| assert_same(result[0], el) }
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_array.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_array.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_array.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,19 @@
+require_relative 'helper'
+
+module Psych
+ class TestArray < TestCase
+ def setup
+ super
+ @list = [{ :a => 'b' }, 'foo']
+ end
+
+ def test_self_referential
+ @list << @list
+ assert_cycle(@list)
+ end
+
+ def test_cycle
+ assert_cycle(@list)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_boolean.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_boolean.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_boolean.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,36 @@
+require_relative 'helper'
+
+module Psych
+ ###
+ # Test booleans from YAML spec:
+ # http://yaml.org/type/bool.html
+ class TestBoolean < TestCase
+ %w{ yes Yes YES true True TRUE on On ON }.each do |truth|
+ define_method(:"test_#{truth}") do
+ assert_equal true, Psych.load("--- #{truth}")
+ end
+ end
+
+ %w{ no No NO false False FALSE off Off OFF }.each do |truth|
+ define_method(:"test_#{truth}") do
+ assert_equal false, Psych.load("--- #{truth}")
+ end
+ end
+
+ ###
+ # YAML spec says "y" and "Y" may be used as true, but Syck treats them
+ # as literal strings
+ def test_y
+ assert_equal "y", Psych.load("--- y")
+ assert_equal "Y", Psych.load("--- Y")
+ end
+
+ ###
+ # YAML spec says "n" and "N" may be used as false, but Syck treats them
+ # as literal strings
+ def test_n
+ assert_equal "n", Psych.load("--- n")
+ assert_equal "N", Psych.load("--- N")
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_class.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_class.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_class.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,17 @@
+require_relative 'helper'
+
+module Psych
+ class TestClass < TestCase
+ def test_cycle
+ assert_raises(::TypeError) do
+ assert_cycle(TestClass)
+ end
+ end
+
+ def test_dump
+ assert_raises(::TypeError) do
+ Psych.dump TestClass
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_coder.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_coder.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_coder.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,169 @@
+require_relative 'helper'
+
+module Psych
+ class TestCoder < TestCase
+ class InitApi
+ attr_accessor :implicit
+ attr_accessor :style
+ attr_accessor :tag
+ attr_accessor :a, :b, :c
+
+ def initialize
+ @a = 1
+ @b = 2
+ @c = 3
+ end
+
+ def init_with coder
+ @a = coder['aa']
+ @b = coder['bb']
+ @implicit = coder.implicit
+ @tag = coder.tag
+ @style = coder.style
+ end
+
+ def encode_with coder
+ coder['aa'] = @a
+ coder['bb'] = @b
+ end
+ end
+
+ class TaggingCoder < InitApi
+ def encode_with coder
+ super
+ coder.tag = coder.tag.sub(/!/, '!hello')
+ coder.implicit = false
+ coder.style = Psych::Nodes::Mapping::FLOW
+ end
+ end
+
+ class ScalarCoder
+ def encode_with coder
+ coder.scalar = "foo"
+ end
+ end
+
+ class Represent
+ yaml_tag 'foo'
+ def encode_with coder
+ coder.represent_scalar 'foo', 'bar'
+ end
+ end
+
+ class RepresentWithInit
+ yaml_tag name
+ attr_accessor :str
+
+ def init_with coder
+ @str = coder.scalar
+ end
+
+ def encode_with coder
+ coder.represent_scalar self.class.name, 'bar'
+ end
+ end
+
+ class RepresentWithSeq
+ yaml_tag name
+ attr_accessor :seq
+
+ def init_with coder
+ @seq = coder.seq
+ end
+
+ def encode_with coder
+ coder.represent_seq self.class.name, %w{ foo bar }
+ end
+ end
+
+ class RepresentWithMap
+ yaml_tag name
+ attr_accessor :map
+
+ def init_with coder
+ @map = coder.map
+ end
+
+ def encode_with coder
+ coder.represent_map self.class.name, { 'a' => 'b' }
+ end
+ end
+
+ def test_map_takes_block
+ coder = Psych::Coder.new 'foo'
+ tag = coder.tag
+ style = coder.style
+ coder.map { |map| map.add 'foo', 'bar' }
+ assert_equal 'bar', coder['foo']
+ assert_equal tag, coder.tag
+ assert_equal style, coder.style
+ end
+
+ def test_map_with_tag
+ coder = Psych::Coder.new 'foo'
+ coder.map('hello') { |map| map.add 'foo', 'bar' }
+ assert_equal 'bar', coder['foo']
+ assert_equal 'hello', coder.tag
+ end
+
+ def test_map_with_tag_and_style
+ coder = Psych::Coder.new 'foo'
+ coder.map('hello', 'world') { |map| map.add 'foo', 'bar' }
+ assert_equal 'bar', coder['foo']
+ assert_equal 'hello', coder.tag
+ assert_equal 'world', coder.style
+ end
+
+ def test_represent_map
+ thing = Psych.load(Psych.dump(RepresentWithMap.new))
+ assert_equal({ 'a' => 'b' }, thing.map)
+ end
+
+ def test_represent_sequence
+ thing = Psych.load(Psych.dump(RepresentWithSeq.new))
+ assert_equal %w{ foo bar }, thing.seq
+ end
+
+ def test_represent_with_init
+ thing = Psych.load(Psych.dump(RepresentWithInit.new))
+ assert_equal 'bar', thing.str
+ end
+
+ def test_represent!
+ assert_match(/foo/, Psych.dump(Represent.new))
+ assert_instance_of(Represent, Psych.load(Psych.dump(Represent.new)))
+ end
+
+ def test_scalar_coder
+ foo = Psych.load(Psych.dump(ScalarCoder.new))
+ assert_equal 'foo', foo
+ end
+
+ def test_load_dumped_tagging
+ foo = InitApi.new
+ bar = Psych.load(Psych.dump(foo))
+ assert_equal false, bar.implicit
+ assert_equal "!ruby/object:Psych::TestCoder::InitApi", bar.tag
+ assert_equal Psych::Nodes::Mapping::BLOCK, bar.style
+ end
+
+ def test_dump_with_tag
+ foo = TaggingCoder.new
+ assert_match(/hello/, Psych.dump(foo))
+ assert_match(/\{aa/, Psych.dump(foo))
+ end
+
+ def test_dump_encode_with
+ foo = InitApi.new
+ assert_match(/aa/, Psych.dump(foo))
+ end
+
+ def test_dump_init_with
+ foo = InitApi.new
+ bar = Psych.load(Psych.dump(foo))
+ assert_equal foo.a, bar.a
+ assert_equal foo.b, bar.b
+ assert_nil bar.c
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_date_time.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_date_time.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_date_time.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,23 @@
+require_relative 'helper'
+require 'date'
+
+module Psych
+ class TestDateTime < TestCase
+ def test_string_tag
+ dt = DateTime.now
+ yaml = Psych.dump dt
+ assert_match(/DateTime/, yaml)
+ end
+
+ def test_round_trip
+ dt = DateTime.now
+ assert_cycle dt
+ end
+
+ def test_round_trip_with_offset
+ dt = DateTime.now
+ dt = dt.new_offset(Rational(3671, 60 * 60 * 24))
+ assert_cycle dt
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_deprecated.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_deprecated.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_deprecated.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,210 @@
+require_relative 'helper'
+
+module Psych
+ class TestDeprecated < TestCase
+ def teardown
+ Psych.domain_types.clear
+ end
+
+ class QuickEmitter
+ attr_reader :name
+ attr_reader :value
+
+ def initialize
+ @name = 'hello!!'
+ @value = 'Friday!'
+ end
+
+ def to_yaml opts = {}
+ Psych.quick_emit object_id, opts do |out|
+ out.map taguri, to_yaml_style do |map|
+ map.add 'name', @name
+ map.add 'value', nil
+ end
+ end
+ end
+ end
+
+ def setup
+ @qe = QuickEmitter.new
+ end
+
+ def test_quick_emit
+ qe2 = Psych.load @qe.to_yaml
+ assert_equal @qe.name, qe2.name
+ assert_instance_of QuickEmitter, qe2
+ assert_nil qe2.value
+ end
+
+ def test_recursive_quick_emit
+ hash = { :qe => @qe }
+ hash2 = Psych.load Psych.dump hash
+ qe = hash2[:qe]
+
+ assert_equal @qe.name, qe.name
+ assert_instance_of QuickEmitter, qe
+ assert_nil qe.value
+ end
+
+ class QuickEmitterEncodeWith
+ attr_reader :name
+ attr_reader :value
+
+ def initialize
+ @name = 'hello!!'
+ @value = 'Friday!'
+ end
+
+ def encode_with coder
+ coder.map do |map|
+ map.add 'name', @name
+ map.add 'value', nil
+ end
+ end
+
+ def to_yaml opts = {}
+ raise
+ end
+ end
+
+ ###
+ # An object that defines both to_yaml and encode_with should only call
+ # encode_with.
+ def test_recursive_quick_emit_encode_with
+ qeew = QuickEmitterEncodeWith.new
+ hash = { :qe => qeew }
+ hash2 = Psych.load Psych.dump hash
+ qe = hash2[:qe]
+
+ assert_equal qeew.name, qe.name
+ assert_instance_of QuickEmitterEncodeWith, qe
+ assert_nil qe.value
+ end
+
+ class YamlInit
+ attr_reader :name
+ attr_reader :value
+
+ def initialize
+ @name = 'hello!!'
+ @value = 'Friday!'
+ end
+
+ def yaml_initialize tag, vals
+ vals.each { |ivar, val| instance_variable_set "@#{ivar}", 'TGIF!' }
+ end
+ end
+
+ def test_yaml_initialize
+ hash = { :yi => YamlInit.new }
+ hash2 = Psych.load Psych.dump hash
+ yi = hash2[:yi]
+
+ assert_equal 'TGIF!', yi.name
+ assert_equal 'TGIF!', yi.value
+ assert_instance_of YamlInit, yi
+ end
+
+ class YamlInitAndInitWith
+ attr_reader :name
+ attr_reader :value
+
+ def initialize
+ @name = 'shaners'
+ @value = 'Friday!'
+ end
+
+ def init_with coder
+ coder.map.each { |ivar, val| instance_variable_set "@#{ivar}", 'TGIF!' }
+ end
+
+ def yaml_initialize tag, vals
+ raise
+ end
+ end
+
+ ###
+ # An object that implements both yaml_initialize and init_with should not
+ # receive the yaml_initialize call.
+ def test_yaml_initialize_and_init_with
+ hash = { :yi => YamlInitAndInitWith.new }
+ hash2 = Psych.load Psych.dump hash
+ yi = hash2[:yi]
+
+ assert_equal 'TGIF!', yi.name
+ assert_equal 'TGIF!', yi.value
+ assert_instance_of YamlInitAndInitWith, yi
+ end
+
+ def test_coder_scalar
+ coder = Psych::Coder.new 'foo'
+ coder.scalar('tag', 'some string', :plain)
+ assert_equal 'tag', coder.tag
+ assert_equal 'some string', coder.scalar
+ assert_equal :scalar, coder.type
+ end
+
+ class YamlAs
+ yaml_as 'helloworld'
+ end
+
+ def test_yaml_as
+ assert_match(/helloworld/, Psych.dump(YamlAs.new))
+ end
+
+ def test_ruby_type
+ types = []
+ appender = lambda { |*args| types << args }
+
+ Psych.add_ruby_type('foo', &appender)
+ Psych.load <<-eoyml
+- !ruby.yaml.org,2002/foo bar
+ eoyml
+
+ assert_equal [["tag:ruby.yaml.org,2002:foo", "bar"]], types
+ end
+
+ def test_detect_implicit
+ assert_equal '', Psych.detect_implicit(nil)
+ assert_equal '', Psych.detect_implicit(Object.new)
+ assert_equal '', Psych.detect_implicit(1.2)
+ assert_equal 'null', Psych.detect_implicit('')
+ assert_equal 'string', Psych.detect_implicit('foo')
+ end
+
+ def test_private_type
+ types = []
+ Psych.add_private_type('foo') { |*args| types << args }
+ Psych.load <<-eoyml
+- !x-private:foo bar
+ eoyml
+
+ assert_equal [["x-private:foo", "bar"]], types
+ end
+
+ def test_tagurize
+ assert_nil Psych.tagurize nil
+ assert_equal Psych, Psych.tagurize(Psych)
+ assert_equal 'tag:yaml.org,2002:foo', Psych.tagurize('foo')
+ end
+
+ def test_read_type_class
+ things = Psych.read_type_class 'tag:yaml.org,2002:int:Psych::TestDeprecated::QuickEmitter', Object
+ assert_equal 'int', things.first
+ assert_equal Psych::TestDeprecated::QuickEmitter, things.last
+ end
+
+ def test_read_type_class_no_class
+ things = Psych.read_type_class 'tag:yaml.org,2002:int', Object
+ assert_equal 'int', things.first
+ assert_equal Object, things.last
+ end
+
+ def test_object_maker
+ thing = Psych.object_maker(Object, { 'a' => 'b', 'c' => 'd' })
+ assert_instance_of(Object, thing)
+ assert_equal 'b', thing.instance_variable_get(:@a)
+ assert_equal 'd', thing.instance_variable_get(:@c)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_document.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_document.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_document.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,46 @@
+require_relative 'helper'
+
+module Psych
+ class TestDocument < TestCase
+ def setup
+ super
+ @stream = Psych.parse_stream(<<-eoyml)
+%YAML 1.1
+%TAG ! tag:tenderlovemaking.com,2009:
+--- !fun
+ eoyml
+ @doc = @stream.children.first
+ end
+
+ def test_parse_tag
+ assert_equal([['!', 'tag:tenderlovemaking.com,2009:']],
+ @doc.tag_directives)
+ end
+
+ def test_emit_tag
+ assert_match('%TAG ! tag:tenderlovemaking.com,2009:', @stream.to_yaml)
+ end
+
+ def test_emit_multitag
+ @doc.tag_directives << ['!!', 'foo.com,2009:']
+ yaml = @stream.to_yaml
+ assert_match('%TAG ! tag:tenderlovemaking.com,2009:', yaml)
+ assert_match('%TAG !! foo.com,2009:', yaml)
+ end
+
+ def test_emit_bad_tag
+ assert_raises(RuntimeError) do
+ @doc.tag_directives = [['!']]
+ @stream.to_yaml
+ end
+ end
+
+ def test_parse_version
+ assert_equal([1,1], @doc.version)
+ end
+
+ def test_emit_version
+ assert_match('%YAML 1.1', @stream.to_yaml)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_emitter.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_emitter.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_emitter.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+
+require_relative 'helper'
+
+module Psych
+ class TestEmitter < TestCase
+ def setup
+ super
+ @out = StringIO.new('')
+ @emitter = Psych::Emitter.new @out
+ end
+
+ def test_set_canonical
+ @emitter.canonical = true
+ assert_equal true, @emitter.canonical
+
+ @emitter.canonical = false
+ assert_equal false, @emitter.canonical
+ end
+
+ def test_indentation_set
+ assert_equal 2, @emitter.indentation
+ @emitter.indentation = 5
+ assert_equal 5, @emitter.indentation
+ end
+
+ def test_emit_utf_8
+ @emitter.start_stream Psych::Nodes::Stream::UTF8
+ @emitter.start_document [], [], false
+ @emitter.scalar '日本語', nil, nil, false, true, 1
+ @emitter.end_document true
+ @emitter.end_stream
+ assert_match('日本語', @out.string)
+ end
+
+ def test_start_stream_arg_error
+ assert_raises(TypeError) do
+ @emitter.start_stream 'asdfasdf'
+ end
+ end
+
+ def test_start_doc_arg_error
+ @emitter.start_stream Psych::Nodes::Stream::UTF8
+
+ [
+ [nil, [], false],
+ [[nil, nil], [], false],
+ [[], 'foo', false],
+ [[], ['foo'], false],
+ [[], [nil,nil], false],
+ ].each do |args|
+ assert_raises(TypeError) do
+ @emitter.start_document(*args)
+ end
+ end
+ end
+
+ def test_scalar_arg_error
+ @emitter.start_stream Psych::Nodes::Stream::UTF8
+ @emitter.start_document [], [], false
+
+ [
+ [:foo, nil, nil, false, true, 1],
+ ['foo', Object.new, nil, false, true, 1],
+ ['foo', nil, Object.new, false, true, 1],
+ ['foo', nil, nil, false, true, :foo],
+ ].each do |args|
+ assert_raises(TypeError) do
+ @emitter.scalar(*args)
+ end
+ end
+ end
+
+ def test_start_sequence_arg_error
+ @emitter.start_stream Psych::Nodes::Stream::UTF8
+ @emitter.start_document [], [], false
+
+ assert_raises(TypeError) do
+ @emitter.start_sequence(nil, Object.new, true, 1)
+ end
+
+ assert_raises(TypeError) do
+ @emitter.start_sequence(nil, nil, true, :foo)
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_encoding.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_encoding.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_encoding.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,107 @@
+# -*- coding: utf-8 -*-
+
+require_relative 'helper'
+
+module Psych
+ class TestEncoding < TestCase
+ class EncodingCatcher < Handler
+ attr_reader :strings
+ def initialize
+ @strings = []
+ end
+
+ (Handler.instance_methods(true) -
+ Object.instance_methods).each do |m|
+ class_eval %{
+ def #{m} *args
+ @strings += args.flatten.find_all { |a|
+ String === a
+ }
+ end
+ }
+ end
+ end
+
+ def setup
+ super
+ @handler = EncodingCatcher.new
+ @parser = Psych::Parser.new @handler
+ @utf8 = Encoding.find('UTF-8')
+ end
+
+ def test_default_internal
+ before = Encoding.default_internal
+
+ Encoding.default_internal = 'EUC-JP'
+
+ str = "壁に耳あり、障子に目あり"
+ yaml = "--- #{str}"
+ assert_equal @utf8, str.encoding
+
+ @parser.parse str
+ assert_encodings Encoding.find('EUC-JP'), @handler.strings
+ assert_equal str, @handler.strings.first.encode('UTF-8')
+ ensure
+ Encoding.default_internal = before
+ end
+
+ def test_scalar
+ @parser.parse("--- a")
+ assert_encodings @utf8, @handler.strings
+ end
+
+ def test_alias
+ @parser.parse(<<-eoyml)
+%YAML 1.1
+---
+!!seq [
+ !!str "Without properties",
+ &A !!str "Anchored",
+ !!str "Tagged",
+ *A,
+ !!str "",
+]
+ eoyml
+ assert_encodings @utf8, @handler.strings
+ end
+
+ def test_list_anchor
+ list = %w{ a b }
+ list << list
+ @parser.parse(Psych.dump(list))
+ assert_encodings @utf8, @handler.strings
+ end
+
+ def test_map_anchor
+ h = {}
+ h['a'] = h
+ @parser.parse(Psych.dump(h))
+ assert_encodings @utf8, @handler.strings
+ end
+
+ def test_map_tag
+ @parser.parse(<<-eoyml)
+%YAML 1.1
+---
+!!map { a : b }
+ eoyml
+ assert_encodings @utf8, @handler.strings
+ end
+
+ def test_doc_tag
+ @parser.parse(<<-eoyml)
+%YAML 1.1
+%TAG ! tag:tenderlovemaking.com,2009:
+--- !fun
+ eoyml
+ assert_encodings @utf8, @handler.strings
+ end
+
+ private
+ def assert_encodings encoding, strings
+ strings.each do |str|
+ assert_equal encoding, str.encoding, str
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_engine_manager.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_engine_manager.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_engine_manager.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,57 @@
+require_relative 'helper'
+require 'yaml'
+
+module Psych
+ class TestEngineManager < TestCase
+ def teardown
+ YAML::ENGINE.yamler = 'syck'
+ end
+
+ def test_bad_engine
+ assert_raises(ArgumentError) do
+ YAML::ENGINE.yamler = 'foooo'
+ end
+ end
+
+ def test_set_psych
+ YAML::ENGINE.yamler = 'psych'
+ assert_equal Psych, YAML
+ assert_equal 'psych', YAML::ENGINE.yamler
+ end
+
+ def test_set_syck
+ YAML::ENGINE.yamler = 'syck'
+ assert_equal Syck, YAML
+ assert_equal 'syck', YAML::ENGINE.yamler
+ end
+
+ A = Struct.new(:name)
+
+ def test_dump_types
+ YAML::ENGINE.yamler = 'psych'
+
+ assert_to_yaml ::Object.new
+ assert_to_yaml Time.now
+ assert_to_yaml Date.today
+ assert_to_yaml('a' => 'b')
+ assert_to_yaml A.new('foo')
+ assert_to_yaml %w{a b}
+ assert_to_yaml Exception.new('foo')
+ assert_to_yaml "hello!"
+ assert_to_yaml :fooo
+ assert_to_yaml(1..10)
+ assert_to_yaml(/hello!~/)
+ assert_to_yaml 1
+ assert_to_yaml 1.2
+ assert_to_yaml Rational(1, 2)
+ assert_to_yaml Complex(1, 2)
+ assert_to_yaml true
+ assert_to_yaml false
+ assert_to_yaml nil
+ end
+
+ def assert_to_yaml obj
+ assert obj.to_yaml, "#{obj.class} to_yaml works"
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_exception.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_exception.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_exception.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,39 @@
+require_relative 'helper'
+
+module Psych
+ class TestException < TestCase
+ class Wups < Exception
+ attr_reader :foo, :bar
+ def initialize *args
+ super
+ @foo = 1
+ @bar = 2
+ end
+ end
+
+ def setup
+ super
+ @wups = Wups.new
+ end
+
+ def test_convert
+ w = Psych.load(Psych.dump(@wups))
+ assert_equal @wups, w
+ assert_equal 1, w.foo
+ assert_equal 2, w.bar
+ end
+
+ def test_to_yaml_properties
+ class << @wups
+ def to_yaml_properties
+ [:@foo]
+ end
+ end
+
+ w = Psych.load(Psych.dump(@wups))
+ assert_equal @wups, w
+ assert_equal 1, w.foo
+ assert_nil w.bar
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_hash.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_hash.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_hash.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,30 @@
+require_relative 'helper'
+
+module Psych
+ class TestHash < TestCase
+ def setup
+ super
+ @hash = { :a => 'b' }
+ end
+
+ def test_self_referential
+ @hash['self'] = @hash
+ assert_cycle(@hash)
+ end
+
+ def test_cycles
+ assert_cycle(@hash)
+ end
+
+ def test_ref_append
+ hash = Psych.load(<<-eoyml)
+---
+foo: &foo
+ hello: world
+bar:
+ <<: *foo
+eoyml
+ assert_equal({"foo"=>{"hello"=>"world"}, "bar"=>{"hello"=>"world"}}, hash)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_json_tree.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_json_tree.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_json_tree.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,43 @@
+require_relative 'helper'
+
+module Psych
+ class TestJSONTree < TestCase
+ def test_string
+ assert_match(/(['"])foo\1/, Psych.to_json("foo"))
+ end
+
+ def test_symbol
+ assert_match(/(['"])foo\1/, Psych.to_json(:foo))
+ end
+
+ def test_nil
+ assert_match(/^null/, Psych.to_json(nil))
+ end
+
+ def test_int
+ assert_match(/^10/, Psych.to_json(10))
+ end
+
+ def test_float
+ assert_match(/^1.2/, Psych.to_json(1.2))
+ end
+
+ def test_hash
+ hash = { 'one' => 'two' }
+ json = Psych.to_json(hash)
+ assert_match(/}$/, json)
+ assert_match(/^\{/, json)
+ assert_match(/['"]one['"]/, json)
+ assert_match(/['"]two['"]/, json)
+ end
+
+ def test_list_to_json
+ list = %w{ one two }
+ json = Psych.to_json(list)
+ assert_match(/]$/, json)
+ assert_match(/^\[/, json)
+ assert_match(/['"]one['"]/, json)
+ assert_match(/['"]two['"]/, json)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_null.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_null.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_null.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,19 @@
+require_relative 'helper'
+
+module Psych
+ ###
+ # Test null from YAML spec:
+ # http://yaml.org/type/null.html
+ class TestNull < TestCase
+ def test_null_list
+ assert_equal [nil] * 5, Psych.load(<<-eoyml)
+---
+- ~
+- null
+-
+- Null
+- NULL
+ eoyml
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_object.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_object.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_object.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,27 @@
+require_relative 'helper'
+
+module Psych
+ class Tagged
+ yaml_tag '!foo'
+
+ attr_accessor :baz
+
+ def initialize
+ @baz = 'bar'
+ end
+ end
+
+ class TestObject < TestCase
+ def test_dump_with_tag
+ tag = Tagged.new
+ assert_match('foo', Psych.dump(tag))
+ end
+
+ def test_tag_round_trip
+ tag = Tagged.new
+ tag2 = Psych.load(Psych.dump(tag))
+ assert_equal tag.baz, tag2.baz
+ assert_instance_of(Tagged, tag2)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_omap.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_omap.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_omap.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,68 @@
+require_relative 'helper'
+
+module Psych
+ class TestOmap < TestCase
+ def test_self_referential
+ map = Psych::Omap.new
+ map['foo'] = 'bar'
+ map['self'] = map
+ assert_equal(map, Psych.load(Psych.dump(map)))
+ end
+
+ def test_keys
+ map = Psych::Omap.new
+ map['foo'] = 'bar'
+ assert_equal 'bar', map['foo']
+ end
+
+ def test_order
+ map = Psych::Omap.new
+ map['a'] = 'b'
+ map['b'] = 'c'
+ assert_equal [%w{a b}, %w{b c}], map.to_a
+ end
+
+ def test_square
+ list = [["a", "b"], ["b", "c"]]
+ map = Psych::Omap[*list.flatten]
+ assert_equal list, map.to_a
+ assert_equal 'b', map['a']
+ assert_equal 'c', map['b']
+ end
+
+ def test_dump
+ map = Psych::Omap['a', 'b', 'c', 'd']
+ yaml = Psych.dump(map)
+ assert_match('!omap', yaml)
+ assert_match('- a: b', yaml)
+ assert_match('- c: d', yaml)
+ end
+
+ def test_round_trip
+ list = [["a", "b"], ["b", "c"]]
+ map = Psych::Omap[*list.flatten]
+ assert_cycle(map)
+ end
+
+ def test_load
+ list = [["a", "b"], ["c", "d"]]
+ map = Psych.load(<<-eoyml)
+--- !omap
+- a: b
+- c: d
+ eoyml
+ assert_equal list, map.to_a
+ end
+
+ # NOTE: This test will not work with Syck
+ def test_load_shorthand
+ list = [["a", "b"], ["c", "d"]]
+ map = Psych.load(<<-eoyml)
+--- !!omap
+- a: b
+- c: d
+ eoyml
+ assert_equal list, map.to_a
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_parser.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_parser.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_parser.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,188 @@
+require_relative 'helper'
+
+module Psych
+ class TestParser < TestCase
+ class EventCatcher < Handler
+ attr_reader :calls
+ def initialize
+ @calls = []
+ end
+
+ (Handler.instance_methods(true) -
+ Object.instance_methods).each do |m|
+ class_eval %{
+ def #{m} *args
+ super
+ @calls << [:#{m}, args]
+ end
+ }
+ end
+ end
+
+ def setup
+ super
+ @parser = Psych::Parser.new EventCatcher.new
+ end
+
+ def test_bogus_io
+ o = Object.new
+ def o.read len; self end
+
+ assert_raises(TypeError) do
+ @parser.parse o
+ end
+ end
+
+ def test_parse_io
+ @parser.parse StringIO.new("--- a")
+ assert_called :start_stream
+ assert_called :scalar
+ assert_called :end_stream
+ end
+
+ def test_syntax_error
+ assert_raises(Psych::SyntaxError) do
+ @parser.parse("---\n\"foo\"\n\"bar\"\n")
+ end
+ end
+
+ def test_mapping_end
+ @parser.parse("---\n!!map { key: value }")
+ assert_called :end_mapping
+ end
+
+ def test_mapping_tag
+ @parser.parse("---\n!!map { key: value }")
+ assert_called :start_mapping, ["tag:yaml.org,2002:map", false, Nodes::Mapping::FLOW]
+ end
+
+ def test_mapping_anchor
+ @parser.parse("---\n&A { key: value }")
+ assert_called :start_mapping, ['A', true, Nodes::Mapping::FLOW]
+ end
+
+ def test_mapping_block
+ @parser.parse("---\n key: value")
+ assert_called :start_mapping, [true, Nodes::Mapping::BLOCK]
+ end
+
+ def test_mapping_start
+ @parser.parse("---\n{ key: value }")
+ assert_called :start_mapping
+ assert_called :start_mapping, [true, Nodes::Mapping::FLOW]
+ end
+
+ def test_sequence_end
+ @parser.parse("---\n&A [1, 2]")
+ assert_called :end_sequence
+ end
+
+ def test_sequence_start_anchor
+ @parser.parse("---\n&A [1, 2]")
+ assert_called :start_sequence, ["A", true, Nodes::Sequence::FLOW]
+ end
+
+ def test_sequence_start_tag
+ @parser.parse("---\n!!seq [1, 2]")
+ assert_called :start_sequence, ["tag:yaml.org,2002:seq", false, Nodes::Sequence::FLOW]
+ end
+
+ def test_sequence_start_flow
+ @parser.parse("---\n[1, 2]")
+ assert_called :start_sequence, [true, Nodes::Sequence::FLOW]
+ end
+
+ def test_sequence_start_block
+ @parser.parse("---\n - 1\n - 2")
+ assert_called :start_sequence, [true, Nodes::Sequence::BLOCK]
+ end
+
+ def test_literal_scalar
+ @parser.parse(<<-eoyml)
+%YAML 1.1
+---
+"literal\n\
+ \ttext\n"
+ eoyml
+ assert_called :scalar, ['literal text ', false, true, Nodes::Scalar::DOUBLE_QUOTED]
+ end
+
+ def test_scalar
+ @parser.parse("--- foo\n")
+ assert_called :scalar, ['foo', true, false, Nodes::Scalar::PLAIN]
+ end
+
+ def test_scalar_with_tag
+ @parser.parse("---\n!!str foo\n")
+ assert_called :scalar, ['foo', 'tag:yaml.org,2002:str', false, false, Nodes::Scalar::PLAIN]
+ end
+
+ def test_scalar_with_anchor
+ @parser.parse("---\n&A foo\n")
+ assert_called :scalar, ['foo', 'A', true, false, Nodes::Scalar::PLAIN]
+ end
+
+ def test_scalar_plain_implicit
+ @parser.parse("---\n&A foo\n")
+ assert_called :scalar, ['foo', 'A', true, false, Nodes::Scalar::PLAIN]
+ end
+
+ def test_alias
+ @parser.parse(<<-eoyml)
+%YAML 1.1
+---
+!!seq [
+ !!str "Without properties",
+ &A !!str "Anchored",
+ !!str "Tagged",
+ *A,
+ !!str "",
+]
+ eoyml
+ assert_called :alias, ['A']
+ end
+
+ def test_end_stream
+ @parser.parse("--- foo\n")
+ assert_called :end_stream
+ end
+
+ def test_start_stream
+ @parser.parse("--- foo\n")
+ assert_called :start_stream
+ end
+
+ def test_end_document_implicit
+ @parser.parse("\"foo\"\n")
+ assert_called :end_document, [true]
+ end
+
+ def test_end_document_explicit
+ @parser.parse("\"foo\"\n...")
+ assert_called :end_document, [false]
+ end
+
+ def test_start_document_version
+ @parser.parse("%YAML 1.1\n---\n\"foo\"\n")
+ assert_called :start_document, [[1,1], [], false]
+ end
+
+ def test_start_document_tag
+ @parser.parse("%TAG !yaml! tag:yaml.org,2002\n---\n!yaml!str \"foo\"\n")
+ assert_called :start_document, [[], [['!yaml!', 'tag:yaml.org,2002']], false]
+ end
+
+ def assert_called call, with = nil, parser = @parser
+ if with
+ call = parser.handler.calls.find { |x|
+ x.first == call && x.last.compact == with
+ }
+ assert(call,
+ "#{[call,with].inspect} not in #{parser.handler.calls.inspect}"
+ )
+ else
+ assert parser.handler.calls.any? { |x| x.first == call }
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_psych.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_psych.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_psych.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,133 @@
+require_relative 'helper'
+
+require 'stringio'
+require 'tempfile'
+
+class TestPsych < Psych::TestCase
+ def teardown
+ Psych.domain_types.clear
+ end
+
+ def test_load_argument_error
+ assert_raises(TypeError) do
+ Psych.load nil
+ end
+ end
+
+ def test_non_existing_class_on_deserialize
+ e = assert_raises(ArgumentError) do
+ Psych.load("--- !ruby/object:NonExistent\nfoo: 1")
+ end
+ assert_equal 'undefined class/module NonExistent', e.message
+ end
+
+ def test_dump_stream
+ things = [22, "foo \n", {}]
+ stream = Psych.dump_stream(*things)
+ assert_equal things, Psych.load_stream(stream)
+ end
+
+ def test_dump_file
+ hash = {'hello' => 'TGIF!'}
+ Tempfile.open('fun.yml') do |io|
+ assert_equal io, Psych.dump(hash, io)
+ io.rewind
+ assert_equal Psych.dump(hash), io.read
+ end
+ end
+
+ def test_dump_io
+ hash = {'hello' => 'TGIF!'}
+ stringio = StringIO.new ''
+ assert_equal stringio, Psych.dump(hash, stringio)
+ assert_equal Psych.dump(hash), stringio.string
+ end
+
+ def test_simple
+ assert_equal 'foo', Psych.load("--- foo\n")
+ end
+
+ def test_libyaml_version
+ assert Psych.libyaml_version
+ assert_equal Psych.libyaml_version.join('.'), Psych::LIBYAML_VERSION
+ end
+
+ def test_load_documents
+ docs = Psych.load_documents("--- foo\n...\n--- bar\n...")
+ assert_equal %w{ foo bar }, docs
+ end
+
+ def test_parse_stream
+ docs = Psych.parse_stream("--- foo\n...\n--- bar\n...")
+ assert_equal %w{ foo bar }, docs.children.map { |x| x.transform }
+ end
+
+ def test_add_builtin_type
+ got = nil
+ Psych.add_builtin_type 'omap', do |type, val|
+ got = val
+ end
+ Psych.load('--- !!omap hello')
+ assert_equal 'hello', got
+ ensure
+ Psych.remove_type 'omap'
+ end
+
+ def test_domain_types
+ got = nil
+ Psych.add_domain_type 'foo.bar,2002', 'foo' do |type, val|
+ got = val
+ end
+
+ Psych.load('--- !foo.bar,2002/foo hello')
+ assert_equal 'hello', got
+
+ Psych.load("--- !foo.bar,2002/foo\n- hello\n- world")
+ assert_equal %w{ hello world }, got
+
+ Psych.load("--- !foo.bar,2002/foo\nhello: world")
+ assert_equal({ 'hello' => 'world' }, got)
+ end
+
+ def test_load_file
+ t = Tempfile.new(['yikes', 'yml'])
+ t.binmode
+ t.write('--- hello world')
+ t.close
+ assert_equal 'hello world', Psych.load_file(t.path)
+ t.close(true)
+ end
+
+ def test_parse_file
+ t = Tempfile.new(['yikes', 'yml'])
+ t.binmode
+ t.write('--- hello world')
+ t.close
+ assert_equal 'hello world', Psych.parse_file(t.path).transform
+ t.close(true)
+ end
+
+ def test_degenerate_strings
+ assert_equal false, Psych.load(' ')
+ assert_equal false, Psych.parse(' ')
+ assert_equal false, Psych.load('')
+ assert_equal false, Psych.parse('')
+ end
+
+ def test_callbacks
+ types = []
+ appender = lambda { |*args| types << args }
+
+ Psych.add_builtin_type('foo', &appender)
+ Psych.add_domain_type('example.com,2002', 'foo', &appender)
+ Psych.load <<-eoyml
+- !tag:yaml.org,2002:foo bar
+- !tag:example.com,2002:foo bar
+ eoyml
+
+ assert_equal [
+ ["tag:yaml.org,2002:foo", "bar"],
+ ["tag:example.com,2002:foo", "bar"]
+ ], types
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_scalar.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_scalar.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_scalar.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+
+require_relative 'helper'
+
+module Psych
+ class TestScalar < TestCase
+ def test_utf_8
+ assert_equal "日本語", Psych.load("--- 日本語")
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_scalar_scanner.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_scalar_scanner.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_scalar_scanner.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,70 @@
+require_relative 'helper'
+
+module Psych
+ class TestScalarScanner < TestCase
+ def test_scan_time
+ [ '2001-12-15T02:59:43.1Z',
+ '2001-12-14t21:59:43.10-05:00',
+ '2001-12-14 21:59:43.10 -5',
+ '2010-01-06 00:00:00 -08:00',
+ '2001-12-15 2:59:43.10',
+ ].each do |time|
+ ss = Psych::ScalarScanner.new
+ assert_instance_of Time, ss.tokenize(time)
+ end
+ end
+
+ attr_reader :ss
+
+ def setup
+ super
+ @ss = Psych::ScalarScanner.new
+ end
+
+ def test_scan_date
+ date = '1980-12-16'
+ token = @ss.tokenize date
+ assert_equal 1980, token.year
+ assert_equal 12, token.month
+ assert_equal 16, token.day
+ end
+
+ def test_scan_inf
+ assert_equal(1 / 0.0, ss.tokenize('.inf'))
+ end
+
+ def test_scan_minus_inf
+ assert_equal(-1 / 0.0, ss.tokenize('-.inf'))
+ end
+
+ def test_scan_nan
+ assert ss.tokenize('.nan').nan?
+ end
+
+ def test_scan_null
+ assert_equal nil, ss.tokenize('null')
+ assert_equal nil, ss.tokenize('~')
+ assert_equal nil, ss.tokenize('')
+ end
+
+ def test_scan_symbol
+ assert_equal :foo, ss.tokenize(':foo')
+ end
+
+ def test_scan_sexagesimal_float
+ assert_equal 685230.15, ss.tokenize('190:20:30.15')
+ end
+
+ def test_scan_sexagesimal_int
+ assert_equal 685230, ss.tokenize('190:20:30')
+ end
+
+ def test_scan_float
+ assert_equal 1.2, ss.tokenize('1.2')
+ end
+
+ def test_scan_true
+ assert_equal true, ss.tokenize('true')
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_serialize_subclasses.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_serialize_subclasses.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_serialize_subclasses.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,38 @@
+require_relative 'helper'
+
+module Psych
+ class TestSerializeSubclasses < TestCase
+ class SomeObject
+ def initialize one, two
+ @one = one
+ @two = two
+ end
+
+ def == other
+ @one == other.instance_eval { @one } &&
+ @two == other.instance_eval { @two }
+ end
+ end
+
+ def test_some_object
+ so = SomeObject.new('foo', [1,2,3])
+ assert_equal so, Psych.load(Psych.dump(so))
+ end
+
+ class StructSubclass < Struct.new(:foo)
+ def initialize foo, bar
+ super(foo)
+ @bar = bar
+ end
+
+ def == other
+ super(other) && @bar == other.instance_eval{ @bar }
+ end
+ end
+
+ def test_struct_subclass
+ so = StructSubclass.new('foo', [1,2,3])
+ assert_equal so, Psych.load(Psych.dump(so))
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_set.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_set.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_set.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,49 @@
+require_relative 'helper'
+
+module Psych
+ class TestSet < TestCase
+ def setup
+ super
+ @set = Psych::Set.new
+ @set['foo'] = 'bar'
+ @set['bar'] = 'baz'
+ end
+
+ def test_dump
+ assert_match(/!set/, Psych.dump(@set))
+ end
+
+ def test_roundtrip
+ assert_cycle(@set)
+ end
+
+ ###
+ # FIXME: Syck should also support !!set as shorthand
+ def test_load_from_yaml
+ loaded = Psych.load(<<-eoyml)
+--- !set
+foo: bar
+bar: baz
+ eoyml
+ assert_equal(@set, loaded)
+ end
+
+ def test_loaded_class
+ assert_instance_of(Psych::Set, Psych.load(Psych.dump(@set)))
+ end
+
+ def test_set_shorthand
+ loaded = Psych.load(<<-eoyml)
+--- !!set
+foo: bar
+bar: baz
+ eoyml
+ assert_instance_of(Psych::Set, loaded)
+ end
+
+ def test_set_self_reference
+ @set['self'] = @set
+ assert_cycle(@set)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_string.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_string.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_string.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,49 @@
+require_relative 'helper'
+
+module Psych
+ class TestString < TestCase
+ def test_binary_string_null
+ string = "\x00"
+ yml = Psych.dump string
+ assert_match(/binary/, yml)
+ assert_equal string, Psych.load(yml)
+ end
+
+ def test_binary_string
+ string = binary_string
+ yml = Psych.dump string
+ assert_match(/binary/, yml)
+ assert_equal string, Psych.load(yml)
+ end
+
+ def test_non_binary_string
+ string = binary_string(0.29)
+ yml = Psych.dump string
+ refute_match(/binary/, yml)
+ assert_equal string, Psych.load(yml)
+ end
+
+ def test_string_with_ivars
+ food = "is delicious"
+ ivar = "on rock and roll"
+ food.instance_variable_set(:@we_built_this_city, ivar)
+
+ str = Psych.load Psych.dump food
+ assert_equal ivar, food.instance_variable_get(:@we_built_this_city)
+ end
+
+ def test_binary
+ string = [0, 123,22, 44, 9, 32, 34, 39].pack('C*')
+ assert_cycle string
+ end
+
+ def binary_string percentage = 0.31, length = 100
+ string = ''
+ (percentage * length).to_i.times do |i|
+ string << "\b"
+ end
+ string << 'a' * (length - string.length)
+ string
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_struct.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_struct.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_struct.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,51 @@
+require_relative 'helper'
+
+class PsychStructWithIvar < Struct.new(:foo)
+ attr_reader :bar
+ def initialize *args
+ super
+ @bar = 'hello'
+ end
+end
+
+module Psych
+ class TestStruct < TestCase
+ class StructSubclass < Struct.new(:foo)
+ def initialize foo, bar
+ super(foo)
+ @bar = bar
+ end
+ end
+
+ def test_self_referential_struct
+ ss = StructSubclass.new(nil, 'foo')
+ ss.foo = ss
+
+ loaded = Psych.load(Psych.dump(ss))
+ assert_instance_of(StructSubclass, loaded.foo)
+
+ # FIXME: This seems to cause an infinite loop. wtf. Must report a bug
+ # in ruby.
+ # assert_equal(ss, loaded)
+ end
+
+ def test_roundtrip
+ thing = PsychStructWithIvar.new('bar')
+ struct = Psych.load(Psych.dump(thing))
+
+ assert_equal 'hello', struct.bar
+ assert_equal 'bar', struct.foo
+ end
+
+ def test_load
+ obj = Psych.load(<<-eoyml)
+--- !ruby/struct:PsychStructWithIvar
+:foo: bar
+:@bar: hello
+ eoyml
+
+ assert_equal 'hello', obj.bar
+ assert_equal 'bar', obj.foo
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_symbol.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_symbol.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_symbol.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,17 @@
+require_relative 'helper'
+
+module Psych
+ class TestSymbol < TestCase
+ def test_cycle
+ assert_cycle :a
+ end
+
+ def test_stringy
+ assert_cycle :"1"
+ end
+
+ def test_load_quoted
+ assert_equal :"1", Psych.load("--- :'1'\n")
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_to_yaml_properties.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_to_yaml_properties.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_to_yaml_properties.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,63 @@
+require_relative 'helper'
+
+module Psych
+ class TestToYamlProperties < MiniTest::Unit::TestCase
+ class Foo
+ attr_accessor :a, :b, :c
+ def initialize
+ @a = 1
+ @b = 2
+ @c = 3
+ end
+
+ def to_yaml_properties
+ [:@a, :@b]
+ end
+ end
+
+ def test_object_dump_yaml_properties
+ foo = Psych.load(Psych.dump(Foo.new))
+ assert_equal 1, foo.a
+ assert_equal 2, foo.b
+ assert_nil foo.c
+ end
+
+ class Bar < Struct.new(:foo, :bar)
+ attr_reader :baz
+ def initialize *args
+ super
+ @baz = 'hello'
+ end
+
+ def to_yaml_properties
+ []
+ end
+ end
+
+ def test_struct_dump_yaml_properties
+ bar = Psych.load(Psych.dump(Bar.new('a', 'b')))
+ assert_equal 'a', bar.foo
+ assert_equal 'b', bar.bar
+ assert_nil bar.baz
+ end
+
+ def test_string_dump
+ string = "okonomiyaki"
+ class << string
+ def to_yaml_properties
+ [:@tastes]
+ end
+ end
+
+ string.instance_variable_set(:@tastes, 'delicious')
+ v = Psych.load Psych.dump string
+ assert_equal 'delicious', v.instance_variable_get(:@tastes)
+ end
+
+ def test_string_load_syck
+ str = Psych.load("--- !str \nstr: okonomiyaki\n:@tastes: delicious\n")
+ assert_equal 'okonomiyaki', str
+ assert_equal 'delicious', str.instance_variable_get(:@tastes)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_tree_builder.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_tree_builder.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_tree_builder.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,79 @@
+require_relative 'helper'
+
+module Psych
+ class TestTreeBuilder < TestCase
+ def setup
+ super
+ @parser = Psych::Parser.new TreeBuilder.new
+ @parser.parse(<<-eoyml)
+%YAML 1.1
+---
+- foo
+- {
+ bar : &A !!str baz,
+ boo : *A
+}
+- *A
+ eoyml
+ @tree = @parser.handler.root
+ end
+
+ def test_stream
+ assert_instance_of Nodes::Stream, @tree
+ end
+
+ def test_documents
+ assert_equal 1, @tree.children.length
+ assert_instance_of Nodes::Document, @tree.children.first
+ doc = @tree.children.first
+
+ assert_equal [1,1], doc.version
+ assert_equal [], doc.tag_directives
+ assert_equal false, doc.implicit
+ end
+
+ def test_sequence
+ doc = @tree.children.first
+ assert_equal 1, doc.children.length
+
+ seq = doc.children.first
+ assert_instance_of Nodes::Sequence, seq
+ assert_nil seq.anchor
+ assert_nil seq.tag
+ assert_equal true, seq.implicit
+ assert_equal Nodes::Sequence::BLOCK, seq.style
+ end
+
+ def test_scalar
+ doc = @tree.children.first
+ seq = doc.children.first
+
+ assert_equal 3, seq.children.length
+ scalar = seq.children.first
+ assert_instance_of Nodes::Scalar, scalar
+ assert_equal 'foo', scalar.value
+ assert_nil scalar.anchor
+ assert_nil scalar.tag
+ assert_equal true, scalar.plain
+ assert_equal false, scalar.quoted
+ assert_equal Nodes::Scalar::PLAIN, scalar.style
+ end
+
+ def test_mapping
+ doc = @tree.children.first
+ seq = doc.children.first
+ map = seq.children[1]
+
+ assert_instance_of Nodes::Mapping, map
+ end
+
+ def test_alias
+ doc = @tree.children.first
+ seq = doc.children.first
+ assert_equal 3, seq.children.length
+ al = seq.children[2]
+ assert_instance_of Nodes::Alias, al
+ assert_equal 'A', al.anchor
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/test_yaml.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/test_yaml.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/test_yaml.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1251 @@
+# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*-
+# vim:sw=4:ts=4
+# $Id$
+#
+require_relative 'helper'
+
+# [ruby-core:01946]
+module Psych_Tests
+ StructTest = Struct::new( :c )
+end
+
+class Psych_Unit_Tests < Psych::TestCase
+ def teardown
+ Psych.domain_types.clear
+ end
+ #
+ # Tests modified from 00basic.t in Psych.pm
+ #
+ def test_basic_map
+ # Simple map
+ assert_parse_only(
+ { 'one' => 'foo', 'three' => 'baz', 'two' => 'bar' }, <<EOY
+one: foo
+two: bar
+three: baz
+EOY
+ )
+ end
+
+ def test_basic_strings
+ # Common string types
+ assert_cycle("x")
+ assert_cycle(":x")
+ assert_cycle(":")
+ assert_parse_only(
+ { 1 => 'simple string', 2 => 42, 3 => '1 Single Quoted String',
+ 4 => 'Psych\'s Double "Quoted" String', 5 => "A block\n with several\n lines.\n",
+ 6 => "A \"chomped\" block", 7 => "A folded\n string\n", 8 => ": started string" },
+ <<EOY
+1: simple string
+2: 42
+3: '1 Single Quoted String'
+4: "Psych's Double \\\"Quoted\\\" String"
+5: |
+ A block
+ with several
+ lines.
+6: |-
+ A "chomped" block
+7: >
+ A
+ folded
+ string
+8: ": started string"
+EOY
+ )
+ end
+
+ #
+ # Test the specification examples
+ # - Many examples have been changes because of whitespace problems that
+ # caused the two to be inequivalent, or keys to be sorted wrong
+ #
+
+ def test_spec_simple_implicit_sequence
+ # Simple implicit sequence
+ assert_to_yaml(
+ [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ], <<EOY
+- Mark McGwire
+- Sammy Sosa
+- Ken Griffey
+EOY
+ )
+ end
+
+ def test_spec_simple_implicit_map
+ # Simple implicit map
+ assert_to_yaml(
+ { 'hr' => 65, 'avg' => 0.278, 'rbi' => 147 }, <<EOY
+avg: 0.278
+hr: 65
+rbi: 147
+EOY
+ )
+ end
+
+ def test_spec_simple_map_with_nested_sequences
+ # Simple mapping with nested sequences
+ assert_to_yaml(
+ { 'american' =>
+ [ 'Boston Red Sox', 'Detroit Tigers', 'New York Yankees' ],
+ 'national' =>
+ [ 'New York Mets', 'Chicago Cubs', 'Atlanta Braves' ] }, <<EOY
+american:
+ - Boston Red Sox
+ - Detroit Tigers
+ - New York Yankees
+national:
+ - New York Mets
+ - Chicago Cubs
+ - Atlanta Braves
+EOY
+ )
+ end
+
+ def test_spec_simple_sequence_with_nested_map
+ # Simple sequence with nested map
+ assert_to_yaml(
+ [
+ {'name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278},
+ {'name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288}
+ ], <<EOY
+-
+ avg: 0.278
+ hr: 65
+ name: Mark McGwire
+-
+ avg: 0.288
+ hr: 63
+ name: Sammy Sosa
+EOY
+ )
+ end
+
+ def test_spec_sequence_of_sequences
+ # Simple sequence with inline sequences
+ assert_parse_only(
+ [
+ [ 'name', 'hr', 'avg' ],
+ [ 'Mark McGwire', 65, 0.278 ],
+ [ 'Sammy Sosa', 63, 0.288 ]
+ ], <<EOY
+- [ name , hr , avg ]
+- [ Mark McGwire , 65 , 0.278 ]
+- [ Sammy Sosa , 63 , 0.288 ]
+EOY
+ )
+ end
+
+ def test_spec_mapping_of_mappings
+ # Simple map with inline maps
+ assert_parse_only(
+ { 'Mark McGwire' =>
+ { 'hr' => 65, 'avg' => 0.278 },
+ 'Sammy Sosa' =>
+ { 'hr' => 63, 'avg' => 0.288 }
+ }, <<EOY
+Mark McGwire: {hr: 65, avg: 0.278}
+Sammy Sosa: {hr: 63,
+ avg: 0.288}
+EOY
+ )
+ end
+
+ def test_ambiguous_comments
+ # [ruby-talk:88012]
+ assert_to_yaml( "Call the method #dave", <<EOY )
+--- "Call the method #dave"
+EOY
+ end
+
+ def test_spec_nested_comments
+ # Map and sequences with comments
+ assert_parse_only(
+ { 'hr' => [ 'Mark McGwire', 'Sammy Sosa' ],
+ 'rbi' => [ 'Sammy Sosa', 'Ken Griffey' ] }, <<EOY
+hr: # 1998 hr ranking
+ - Mark McGwire
+ - Sammy Sosa
+rbi:
+ # 1998 rbi ranking
+ - Sammy Sosa
+ - Ken Griffey
+EOY
+ )
+ end
+
+ def test_spec_anchors_and_aliases
+ # Anchors and aliases
+ assert_parse_only(
+ { 'hr' =>
+ [ 'Mark McGwire', 'Sammy Sosa' ],
+ 'rbi' =>
+ [ 'Sammy Sosa', 'Ken Griffey' ] }, <<EOY
+hr:
+ - Mark McGwire
+ # Name "Sammy Sosa" scalar SS
+ - &SS Sammy Sosa
+rbi:
+ # So it can be referenced later.
+ - *SS
+ - Ken Griffey
+EOY
+ )
+
+ assert_to_yaml(
+ [{"arrival"=>"EDI", "departure"=>"LAX", "fareref"=>"DOGMA", "currency"=>"GBP"}, {"arrival"=>"MEL", "departure"=>"SYD", "fareref"=>"MADF", "currency"=>"AUD"}, {"arrival"=>"MCO", "departure"=>"JFK", "fareref"=>"DFSF", "currency"=>"USD"}], <<EOY
+ -
+ &F fareref: DOGMA
+ &C currency: GBP
+ &D departure: LAX
+ &A arrival: EDI
+ - { *F: MADF, *C: AUD, *D: SYD, *A: MEL }
+ - { *F: DFSF, *C: USD, *D: JFK, *A: MCO }
+EOY
+ )
+
+ assert_to_yaml(
+ {"ALIASES"=>["fareref", "currency", "departure", "arrival"], "FARES"=>[{"arrival"=>"EDI", "departure"=>"LAX", "fareref"=>"DOGMA", "currency"=>"GBP"}, {"arrival"=>"MEL", "departure"=>"SYD", "fareref"=>"MADF", "currency"=>"AUD"}, {"arrival"=>"MCO", "departure"=>"JFK", "fareref"=>"DFSF", "currency"=>"USD"}]}, <<EOY
+---
+ALIASES: [&f fareref, &c currency, &d departure, &a arrival]
+FARES:
+- *f: DOGMA
+ *c: GBP
+ *d: LAX
+ *a: EDI
+
+- *f: MADF
+ *c: AUD
+ *d: SYD
+ *a: MEL
+
+- *f: DFSF
+ *c: USD
+ *d: JFK
+ *a: MCO
+
+EOY
+ )
+
+ end
+
+ def test_spec_mapping_between_sequences
+ # Complex key #1
+ dj = Date.new( 2001, 7, 23 )
+ assert_parse_only(
+ { [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ],
+ [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ] }, <<EOY
+? # PLAY SCHEDULE
+ - Detroit Tigers
+ - Chicago Cubs
+:
+ - 2001-07-23
+
+? [ New York Yankees,
+ Atlanta Braves ]
+: [ 2001-07-02, 2001-08-12,
+ 2001-08-14 ]
+EOY
+ )
+
+ # Complex key #2
+ assert_parse_only(
+ { [ 'New York Yankees', 'Atlanta Braves' ] =>
+ [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ),
+ Date.new( 2001, 8, 14 ) ],
+ [ 'Detroit Tigers', 'Chicago Cubs' ] =>
+ [ Date.new( 2001, 7, 23 ) ]
+ }, <<EOY
+?
+ - New York Yankees
+ - Atlanta Braves
+:
+ - 2001-07-02
+ - 2001-08-12
+ - 2001-08-14
+?
+ - Detroit Tigers
+ - Chicago Cubs
+:
+ - 2001-07-23
+EOY
+ )
+ end
+
+ def test_spec_sequence_key_shortcut
+ # Shortcut sequence map
+ assert_parse_only(
+ { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ),
+ 'bill-to' => 'Chris Dumars', 'product' =>
+ [ { 'item' => 'Super Hoop', 'quantity' => 1 },
+ { 'item' => 'Basketball', 'quantity' => 4 },
+ { 'item' => 'Big Shoes', 'quantity' => 1 } ] }, <<EOY
+invoice: 34843
+date : 2001-01-23
+bill-to: Chris Dumars
+product:
+ - item : Super Hoop
+ quantity: 1
+ - item : Basketball
+ quantity: 4
+ - item : Big Shoes
+ quantity: 1
+EOY
+ )
+ end
+
+ def test_spec_sequence_in_sequence_shortcut
+ # Seq-in-seq
+ assert_parse_only( [ [ [ 'one', 'two', 'three' ] ] ], <<EOY )
+- - - one
+ - two
+ - three
+EOY
+ end
+
+ def test_spec_sequence_shortcuts
+ # Sequence shortcuts combined
+ assert_parse_only(
+[
+ [
+ [ [ 'one' ] ],
+ [ 'two', 'three' ],
+ { 'four' => nil },
+ [ { 'five' => [ 'six' ] } ],
+ [ 'seven' ]
+ ],
+ [ 'eight', 'nine' ]
+], <<EOY )
+- - - - one
+ - - two
+ - three
+ - four:
+ - - five:
+ - six
+ - - seven
+- - eight
+ - nine
+EOY
+ end
+
+ def test_spec_single_literal
+ # Literal scalar block
+ assert_parse_only( [ "\\/|\\/|\n/ | |_\n" ], <<EOY )
+- |
+ \\/|\\/|
+ / | |_
+EOY
+ end
+
+ def test_spec_single_folded
+ # Folded scalar block
+ assert_parse_only(
+ [ "Mark McGwire's year was crippled by a knee injury.\n" ], <<EOY
+- >
+ Mark McGwire\'s
+ year was crippled
+ by a knee injury.
+EOY
+ )
+ end
+
+ def test_spec_preserve_indent
+ # Preserve indented spaces
+ assert_parse_only(
+ "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n", <<EOY
+--- >
+ Sammy Sosa completed another
+ fine season with great stats.
+
+ 63 Home Runs
+ 0.288 Batting Average
+
+ What a year!
+EOY
+ )
+ end
+
+ def test_spec_indentation_determines_scope
+ assert_parse_only(
+ { 'name' => 'Mark McGwire', 'accomplishment' => "Mark set a major league home run record in 1998.\n",
+ 'stats' => "65 Home Runs\n0.278 Batting Average\n" }, <<EOY
+name: Mark McGwire
+accomplishment: >
+ Mark set a major league
+ home run record in 1998.
+stats: |
+ 65 Home Runs
+ 0.278 Batting Average
+EOY
+ )
+ end
+
+ def test_spec_multiline_scalars
+ # Multiline flow scalars
+ assert_parse_only(
+ { 'plain' => 'This unquoted scalar spans many lines.',
+ 'quoted' => "So does this quoted scalar.\n" }, <<EOY
+plain: This unquoted
+ scalar spans
+ many lines.
+quoted: "\\
+ So does this quoted
+ scalar.\\n"
+EOY
+ )
+ end
+
+ def test_spec_type_int
+ assert_parse_only(
+ { 'canonical' => 12345, 'decimal' => 12345, 'octal' => '014'.oct, 'hexadecimal' => '0xC'.hex }, <<EOY
+canonical: 12345
+decimal: +12,345
+octal: 014
+hexadecimal: 0xC
+EOY
+ )
+ assert_parse_only(
+ { 'canonical' => 685230, 'decimal' => 685230, 'octal' => 02472256, 'hexadecimal' => 0x0A74AE, 'sexagesimal' => 685230 }, <<EOY)
+canonical: 685230
+decimal: +685,230
+octal: 02472256
+hexadecimal: 0x0A,74,AE
+sexagesimal: 190:20:30
+EOY
+ end
+
+ def test_spec_type_float
+ assert_parse_only(
+ { 'canonical' => 1230.15, 'exponential' => 1230.15, 'fixed' => 1230.15,
+ 'negative infinity' => -1.0/0.0 }, <<EOY)
+canonical: 1.23015e+3
+exponential: 12.3015e+02
+fixed: 1,230.15
+negative infinity: -.inf
+EOY
+ nan = Psych::load( <<EOY )
+not a number: .NaN
+EOY
+ assert( nan['not a number'].nan? )
+ end
+
+ def test_spec_type_misc
+ assert_parse_only(
+ { nil => nil, true => true, false => false, 'string' => '12345' }, <<EOY
+null: ~
+true: yes
+false: no
+string: '12345'
+EOY
+ )
+ end
+
+ def test_spec_complex_invoice
+ # Complex invoice type
+ id001 = { 'given' => 'Chris', 'family' => 'Dumars', 'address' =>
+ { 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak',
+ 'state' => 'MI', 'postal' => 48046 } }
+ assert_parse_only(
+ { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ),
+ 'bill-to' => id001, 'ship-to' => id001, 'product' =>
+ [ { 'sku' => 'BL394D', 'quantity' => 4,
+ 'description' => 'Basketball', 'price' => 450.00 },
+ { 'sku' => 'BL4438H', 'quantity' => 1,
+ 'description' => 'Super Hoop', 'price' => 2392.00 } ],
+ 'tax' => 251.42, 'total' => 4443.52,
+ 'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n" }, <<EOY
+invoice: 34843
+date : 2001-01-23
+bill-to: &id001
+ given : Chris
+ family : !str Dumars
+ address:
+ lines: |
+ 458 Walkman Dr.
+ Suite #292
+ city : Royal Oak
+ state : MI
+ postal : 48046
+ship-to: *id001
+product:
+ - !map
+ sku : BL394D
+ quantity : 4
+ description : Basketball
+ price : 450.00
+ - sku : BL4438H
+ quantity : 1
+ description : Super Hoop
+ price : 2392.00
+tax : 251.42
+total: 4443.52
+comments: >
+ Late afternoon is best.
+ Backup contact is Nancy
+ Billsmer @ 338-4338.
+EOY
+ )
+ end
+
+ def test_spec_log_file
+ doc_ct = 0
+ Psych::load_documents( <<EOY
+---
+Time: 2001-11-23 15:01:42 -05:00
+User: ed
+Warning: >
+ This is an error message
+ for the log file
+---
+Time: 2001-11-23 15:02:31 -05:00
+User: ed
+Warning: >
+ A slightly different error
+ message.
+---
+Date: 2001-11-23 15:03:17 -05:00
+User: ed
+Fatal: >
+ Unknown variable "bar"
+Stack:
+ - file: TopClass.py
+ line: 23
+ code: |
+ x = MoreObject("345\\n")
+ - file: MoreClass.py
+ line: 58
+ code: |-
+ foo = bar
+EOY
+ ) { |doc|
+ case doc_ct
+ when 0
+ assert_equal( doc, { 'Time' => mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ),
+ 'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } )
+ when 1
+ assert_equal( doc, { 'Time' => mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ),
+ 'User' => 'ed', 'Warning' => "A slightly different error message.\n" } )
+ when 2
+ assert_equal( doc, { 'Date' => mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ),
+ 'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n",
+ 'Stack' => [
+ { 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" },
+ { 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } )
+ end
+ doc_ct += 1
+ }
+ assert_equal( doc_ct, 3 )
+ end
+
+ def test_spec_root_fold
+ y = Psych::load( <<EOY
+---
+This Psych stream contains a single text value.
+The next stream is a log file - a sequence of
+log entries. Adding an entry to the log is a
+simple matter of appending it at the end.
+EOY
+ )
+ assert_equal( y, "This Psych stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end." )
+ end
+
+ def test_spec_root_mapping
+ y = Psych::load( <<EOY
+# This stream is an example of a top-level mapping.
+invoice : 34843
+date : 2001-01-23
+total : 4443.52
+EOY
+ )
+ assert_equal( y, { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ), 'total' => 4443.52 } )
+ end
+
+ def test_spec_oneline_docs
+ doc_ct = 0
+ Psych::load_documents( <<EOY
+# The following is a sequence of three documents.
+# The first contains an empty mapping, the second
+# an empty sequence, and the last an empty string.
+--- {}
+--- [ ]
+--- ''
+EOY
+ ) { |doc|
+ case doc_ct
+ when 0
+ assert_equal( doc, {} )
+ when 1
+ assert_equal( doc, [] )
+ when 2
+ assert_equal( doc, '' )
+ end
+ doc_ct += 1
+ }
+ assert_equal( doc_ct, 3 )
+ end
+
+ def test_spec_domain_prefix
+ customer_proc = proc { |type, val|
+ if Hash === val
+ scheme, domain, type = type.split( ':', 3 )
+ val['type'] = "domain #{type}"
+ val
+ else
+ raise ArgumentError, "Not a Hash in domain.tld,2002/invoice: " + val.inspect
+ end
+ }
+ Psych.add_domain_type( "domain.tld,2002", 'invoice', &customer_proc )
+ Psych.add_domain_type( "domain.tld,2002", 'customer', &customer_proc )
+ assert_parse_only( { "invoice"=> { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } }, <<EOY
+# 'http://domain.tld,2002/invoice' is some type family.
+invoice: !domain.tld,2002/invoice
+ # 'seq' is shorthand for 'http://yaml.org/seq'.
+ # This does not effect '^customer' below
+ # because it is does not specify a prefix.
+ customers: !seq
+ # '^customer' is shorthand for the full
+ # notation 'http://domain.tld,2002/customer'.
+ - !customer
+ given : Chris
+ family : Dumars
+EOY
+ )
+ end
+
+ def test_spec_throwaway
+ assert_parse_only(
+ {"this"=>"contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n"}, <<EOY
+### These are four throwaway comment ###
+
+### lines (the second line is empty). ###
+this: | # Comments may trail lines.
+ contains three lines of text.
+ The third one starts with a
+ # character. This isn't a comment.
+
+# These are three throwaway comment
+# lines (the first line is empty).
+EOY
+ )
+ end
+
+ def test_spec_force_implicit
+ # Force implicit
+ assert_parse_only(
+ { 'integer' => 12, 'also int' => 12, 'string' => '12' }, <<EOY
+integer: 12
+also int: ! "12"
+string: !str 12
+EOY
+ )
+ end
+
+ ###
+ # Commenting out this test. This line:
+ #
+ # - !domain.tld,2002/type\\x30 value
+ #
+ # Is invalid according to the YAML spec:
+ #
+ # http://yaml.org/spec/1.1/#id896876
+ #
+# def test_spec_url_escaping
+# Psych.add_domain_type( "domain.tld,2002", "type0" ) { |type, val|
+# "ONE: #{val}"
+# }
+# Psych.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val|
+# "TWO: #{val}"
+# }
+# assert_parse_only(
+# { 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value' ] }, <<EOY
+#same:
+# - !domain.tld,2002/type\\x30 value
+# - !domain.tld,2002/type0 value
+#different: # As far as the Psych parser is concerned
+# - !domain.tld,2002/type%30 value
+#EOY
+# )
+# end
+
+ def test_spec_override_anchor
+ # Override anchor
+ a001 = "The alias node below is a repeated use of this value.\n"
+ assert_parse_only(
+ { 'anchor' => 'This scalar has an anchor.', 'override' => a001, 'alias' => a001 }, <<EOY
+anchor : &A001 This scalar has an anchor.
+override : &A001 >
+ The alias node below is a
+ repeated use of this value.
+alias : *A001
+EOY
+ )
+ end
+
+ def test_spec_explicit_families
+ Psych.add_domain_type( "somewhere.com,2002", 'type' ) { |type, val|
+ "SOMEWHERE: #{val}"
+ }
+ assert_parse_only(
+ { 'not-date' => '2002-04-28', 'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;", 'hmm' => "SOMEWHERE: family above is short for\nhttp://somewhere.com/type\n" }, <<EOY
+not-date: !str 2002-04-28
+picture: !binary |
+ R0lGODlhDAAMAIQAAP//9/X
+ 17unp5WZmZgAAAOfn515eXv
+ Pz7Y6OjuDg4J+fn5OTk6enp
+ 56enmleECcgggoBADs=
+
+hmm: !somewhere.com,2002/type |
+ family above is short for
+ http://somewhere.com/type
+EOY
+ )
+ end
+
+ def test_spec_application_family
+ # Testing the clarkevans.com graphs
+ Psych.add_domain_type( "clarkevans.com,2002", 'graph/shape' ) { |type, val|
+ if Array === val
+ val << "Shape Container"
+ val
+ else
+ raise ArgumentError, "Invalid graph of type #{val.class}: " + val.inspect
+ end
+ }
+ one_shape_proc = Proc.new { |type, val|
+ if Hash === val
+ type = type.split( /:/ )
+ val['TYPE'] = "Shape: #{type[2]}"
+ val
+ else
+ raise ArgumentError, "Invalid graph of type #{val.class}: " + val.inspect
+ end
+ }
+ Psych.add_domain_type( "clarkevans.com,2002", 'graph/circle', &one_shape_proc )
+ Psych.add_domain_type( "clarkevans.com,2002", 'graph/line', &one_shape_proc )
+ Psych.add_domain_type( "clarkevans.com,2002", 'graph/text', &one_shape_proc )
+ # MODIFIED to remove invalid Psych
+ assert_parse_only(
+ [[{"radius"=>7, "center"=>{"x"=>73, "y"=>129}, "TYPE"=>"Shape: graph/circle"}, {"finish"=>{"x"=>89, "y"=>102}, "TYPE"=>"Shape: graph/line", "start"=>{"x"=>73, "y"=>129}}, {"TYPE"=>"Shape: graph/text", "value"=>"Pretty vector drawing.", "start"=>{"x"=>73, "y"=>129}, "color"=>16772795}, "Shape Container"]], <<EOY
+- !clarkevans.com,2002/graph/shape
+ - !/graph/circle
+ center: &ORIGIN {x: 73, y: 129}
+ radius: 7
+ - !/graph/line # !clarkevans.com,2002/graph/line
+ start: *ORIGIN
+ finish: { x: 89, y: 102 }
+ - !/graph/text
+ start: *ORIGIN
+ color: 0xFFEEBB
+ value: Pretty vector drawing.
+EOY
+ )
+ end
+
+ def test_spec_float_explicit
+ assert_parse_only(
+ [ 10.0, 10.0, 10.0, 10.0 ], <<EOY
+# All entries in the sequence
+# have the same type and value.
+- 10.0
+- !float 10
+- !yaml.org,2002/float '10'
+- !yaml.org,2002/float "\\
+ 1\\
+ 0"
+EOY
+ )
+ end
+
+ def test_spec_builtin_seq
+ # Assortment of sequences
+ assert_parse_only(
+ { 'empty' => [], 'in-line' => [ 'one', 'two', 'three', 'four', 'five' ],
+ 'nested' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ],
+ "A multi-line sequence entry\n", 'Sixth item in top sequence' ] }, <<EOY
+empty: []
+in-line: [ one, two, three # May span lines,
+ , four, # indentation is
+ five ] # mostly ignored.
+nested:
+ - First item in top sequence
+ -
+ - Subordinate sequence entry
+ - >
+ A multi-line
+ sequence entry
+ - Sixth item in top sequence
+EOY
+ )
+ end
+
+ def test_spec_builtin_map
+ # Assortment of mappings
+ assert_parse_only(
+ { 'empty' => {}, 'in-line' => { 'one' => 1, 'two' => 2 },
+ 'spanning' => { 'one' => 1, 'two' => 2 },
+ 'nested' => { 'first' => 'First entry', 'second' =>
+ { 'key' => 'Subordinate mapping' }, 'third' =>
+ [ 'Subordinate sequence', {}, 'Previous mapping is empty.',
+ { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' },
+ 'The previous entry is equal to the following one.',
+ { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ],
+ 12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.',
+ "\a" => 'This key had to be escaped.',
+ "This is a multi-line folded key\n" => "Whose value is also multi-line.\n",
+ [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } }, <<EOY
+
+empty: {}
+in-line: { one: 1, two: 2 }
+spanning: { one: 1,
+ two: 2 }
+nested:
+ first : First entry
+ second:
+ key: Subordinate mapping
+ third:
+ - Subordinate sequence
+ - { }
+ - Previous mapping is empty.
+ - A key: value pair in a sequence.
+ A second: key:value pair.
+ - The previous entry is equal to the following one.
+ -
+ A key: value pair in a sequence.
+ A second: key:value pair.
+ !float 12 : This key is a float.
+ ? >
+ ?
+ : This key had to be protected.
+ "\\a" : This key had to be escaped.
+ ? >
+ This is a
+ multi-line
+ folded key
+ : >
+ Whose value is
+ also multi-line.
+ ?
+ - This key
+ - is a sequence
+ :
+ - With a sequence value.
+# The following parses correctly,
+# but Ruby 1.6.* fails the comparison!
+# ?
+# This: key
+# is a: mapping
+# :
+# with a: mapping value.
+EOY
+ )
+ end
+
+ def test_spec_builtin_literal_blocks
+ # Assortment of literal scalar blocks
+ assert_parse_only(
+ {"both are equal to"=>" This has no newline.", "is equal to"=>"The \\ ' \" characters may be\nfreely used. Leading white\n space is significant.\n\nLine breaks are significant.\nThus this value contains one\nempty line and ends with a\nsingle line break, but does\nnot start with one.\n", "also written as"=>" This has no newline.", "indented and chomped"=>" This has no newline.", "empty"=>"", "literal"=>"The \\ ' \" characters may be\nfreely used. Leading white\n space is significant.\n\nLine breaks are significant.\nThus this value contains one\nempty line and ends with a\nsingle line break, but does\nnot start with one.\n"}, <<EOY
+empty: |
+
+literal: |
+ The \\\ ' " characters may be
+ freely used. Leading white
+ space is significant.
+
+ Line breaks are significant.
+ Thus this value contains one
+ empty line and ends with a
+ single line break, but does
+ not start with one.
+
+is equal to: "The \\\\ ' \\" characters may \\
+ be\\nfreely used. Leading white\\n space \\
+ is significant.\\n\\nLine breaks are \\
+ significant.\\nThus this value contains \\
+ one\\nempty line and ends with a\\nsingle \\
+ line break, but does\\nnot start with one.\\n"
+
+# Comments may follow a nested
+# scalar value. They must be
+# less indented.
+
+# Modifiers may be combined in any order.
+indented and chomped: |2-
+ This has no newline.
+
+also written as: |-2
+ This has no newline.
+
+both are equal to: " This has no newline."
+EOY
+ )
+
+ str1 = "This has one newline.\n"
+ str2 = "This has no newline."
+ str3 = "This has two newlines.\n\n"
+ assert_parse_only(
+ { 'clipped' => str1, 'same as "clipped" above' => str1,
+ 'stripped' => str2, 'same as "stripped" above' => str2,
+ 'kept' => str3, 'same as "kept" above' => str3 }, <<EOY
+clipped: |
+ This has one newline.
+
+same as "clipped" above: "This has one newline.\\n"
+
+stripped: |-
+ This has no newline.
+
+same as "stripped" above: "This has no newline."
+
+kept: |+
+ This has two newlines.
+
+same as "kept" above: "This has two newlines.\\n\\n"
+
+EOY
+ )
+ end
+
+ def test_spec_span_single_quote
+ assert_parse_only( {"third"=>"a single quote ' must be escaped.", "second"=>"! : \\ etc. can be used freely.", "is same as"=>"this contains six spaces\nand one line break", "empty"=>"", "span"=>"this contains six spaces\nand one line break"}, <<EOY
+empty: ''
+second: '! : \\ etc. can be used freely.'
+third: 'a single quote '' must be escaped.'
+span: 'this contains
+ six spaces
+
+ and one
+ line break'
+is same as: "this contains six spaces\\nand one line break"
+EOY
+ )
+ end
+
+ def test_spec_span_double_quote
+ assert_parse_only( {"is equal to"=>"this contains four spaces", "third"=>"a \" or a \\ must be escaped.", "second"=>"! : etc. can be used freely.", "empty"=>"", "fourth"=>"this value ends with an LF.\n", "span"=>"this contains four spaces"}, <<EOY
+empty: ""
+second: "! : etc. can be used freely."
+third: "a \\\" or a \\\\ must be escaped."
+fourth: "this value ends with an LF.\\n"
+span: "this contains
+ four \\
+ spaces"
+is equal to: "this contains four spaces"
+EOY
+ )
+ end
+
+ def test_spec_builtin_time
+ # Time
+ assert_parse_only(
+ { "space separated" => mktime( 2001, 12, 14, 21, 59, 43, ".10", "-05:00" ),
+ "canonical" => mktime( 2001, 12, 15, 2, 59, 43, ".10" ),
+ "date (noon UTC)" => Date.new( 2002, 12, 14),
+ "valid iso8601" => mktime( 2001, 12, 14, 21, 59, 43, ".10", "-05:00" ) }, <<EOY
+canonical: 2001-12-15T02:59:43.1Z
+valid iso8601: 2001-12-14t21:59:43.10-05:00
+space separated: 2001-12-14 21:59:43.10 -05:00
+date (noon UTC): 2002-12-14
+EOY
+ )
+ end
+
+ def test_spec_builtin_binary
+ arrow_gif = "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371!\376\016Made with GIMP\000,\000\000\000\000\f\000\f\000\000\005, \216\2010\236\343@\024\350i\020\304\321\212\010\034\317\200M$z\357\3770\205p\270\2601f\r\e\316\001\303\001\036\020' \202\n\001\000;"
+ assert_parse_only(
+ { 'canonical' => arrow_gif, 'base64' => arrow_gif,
+ 'description' => "The binary value above is a tiny arrow encoded as a gif image.\n" }, <<EOY
+canonical: !binary "\\
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOf\\
+ n515eXvPz7Y6OjuDg4J+fn5OTk6enp56enmlpaW\\
+ NjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++\\
+ f/++f/++f/++f/++f/++f/++f/++SH+Dk1hZGUg\\
+ d2l0aCBHSU1QACwAAAAADAAMAAAFLCAgjoEwnuN\\
+ AFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84Bww\\
+ EeECcgggoBADs="
+base64: !binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOf
+ n515eXvPz7Y6OjuDg4J+fn5OTk6enp56enmlpaW
+ NjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++
+ f/++f/++f/++f/++f/++f/++f/++SH+Dk1hZGUg
+ d2l0aCBHSU1QACwAAAAADAAMAAAFLCAgjoEwnuN
+ AFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84Bww
+ EeECcgggoBADs=
+description: >
+ The binary value above is a tiny arrow
+ encoded as a gif image.
+EOY
+ )
+ end
+ def test_ruby_regexp
+ # Test Ruby regular expressions
+ assert_to_yaml(
+ { 'simple' => /a.b/, 'complex' => %r'\A"((?:[^"]|\")+)"',
+ 'case-insensitive' => /George McFly/i }, <<EOY
+case-insensitive: !ruby/regexp "/George McFly/i"
+complex: !ruby/regexp "/\\\\A\\"((?:[^\\"]|\\\\\\")+)\\"/"
+simple: !ruby/regexp "/a.b/"
+EOY
+ )
+ end
+
+ #
+ # Test of Ranges
+ #
+ def test_ranges
+
+ # Simple numeric
+ assert_to_yaml( 1..3, <<EOY )
+--- !ruby/range 1..3
+EOY
+
+ # Simple alphabetic
+ assert_to_yaml( 'a'..'z', <<EOY )
+--- !ruby/range a..z
+EOY
+
+ # Float
+ assert_to_yaml( 10.5...30.3, <<EOY )
+--- !ruby/range 10.5...30.3
+EOY
+
+ end
+
+ def test_ruby_struct
+ # Ruby structures
+ book_struct = Struct::new( "MyBookStruct", :author, :title, :year, :isbn )
+ assert_to_yaml(
+ [ book_struct.new( "Yukihiro Matsumoto", "Ruby in a Nutshell", 2002, "0-596-00214-9" ),
+ book_struct.new( [ 'Dave Thomas', 'Andy Hunt' ], "The Pickaxe", 2002,
+ book_struct.new( "This should be the ISBN", "but I have another struct here", 2002, "None" )
+ ) ], <<EOY
+- !ruby/struct:MyBookStruct
+ author: Yukihiro Matsumoto
+ title: Ruby in a Nutshell
+ year: 2002
+ isbn: 0-596-00214-9
+- !ruby/struct:MyBookStruct
+ author:
+ - Dave Thomas
+ - Andy Hunt
+ title: The Pickaxe
+ year: 2002
+ isbn: !ruby/struct:MyBookStruct
+ author: This should be the ISBN
+ title: but I have another struct here
+ year: 2002
+ isbn: None
+EOY
+ )
+
+ assert_to_yaml( Psych_Tests::StructTest.new( 123 ), <<EOY )
+--- !ruby/struct:Psych_Tests::StructTest
+c: 123
+EOY
+
+ end
+
+ def test_ruby_rational
+ assert_to_yaml( Rational(1, 2), <<EOY )
+--- !ruby/object:Rational
+numerator: 1
+denominator: 2
+EOY
+
+ # Read Psych dumped by the ruby 1.8.3.
+ assert_to_yaml( Rational(1, 2), "!ruby/object:Rational 1/2\n" )
+ assert_raises( ArgumentError ) { Psych.load("!ruby/object:Rational INVALID/RATIONAL\n") }
+ end
+
+ def test_ruby_complex
+ assert_to_yaml( Complex(3, 4), <<EOY )
+--- !ruby/object:Complex
+image: 4
+real: 3
+EOY
+
+ # Read Psych dumped by the ruby 1.8.3.
+ assert_to_yaml( Complex(3, 4), "!ruby/object:Complex 3+4i\n" )
+ assert_raises( ArgumentError ) { Psych.load("!ruby/object:Complex INVALID+COMPLEXi\n") }
+ end
+
+ def test_emitting_indicators
+ assert_to_yaml( "Hi, from Object 1. You passed: please, pretty please", <<EOY
+--- "Hi, from Object 1. You passed: please, pretty please"
+EOY
+ )
+ end
+
+ ##
+ ## Test the Psych::Stream class -- INACTIVE at the moment
+ ##
+ #def test_document
+ # y = Psych::Stream.new( :Indent => 2, :UseVersion => 0 )
+ # y.add(
+ # { 'hi' => 'hello', 'map' =>
+ # { 'good' => 'two' },
+ # 'time' => Time.now,
+ # 'try' => /^po(.*)$/,
+ # 'bye' => 'goodbye'
+ # }
+ # )
+ # y.add( { 'po' => 'nil', 'oper' => 90 } )
+ # y.add( { 'hi' => 'wow!', 'bye' => 'wow!' } )
+ # y.add( { [ 'Red Socks', 'Boston' ] => [ 'One', 'Two', 'Three' ] } )
+ # y.add( [ true, false, false ] )
+ #end
+
+ #
+ # Test YPath choices parsing
+ #
+ #def test_ypath_parsing
+ # assert_path_segments( "/*/((one|three)/name|place)|//place",
+ # [ ["*", "one", "name"],
+ # ["*", "three", "name"],
+ # ["*", "place"],
+ # ["/", "place"] ]
+ # )
+ #end
+
+ #
+ # Tests from Tanaka Akira on [ruby-core]
+ #
+ def test_akira
+
+ # Commas in plain scalars [ruby-core:1066]
+ assert_to_yaml(
+ {"A"=>"A,","B"=>"B"}, <<EOY
+A: "A,"
+B: B
+EOY
+ )
+
+ # Double-quoted keys [ruby-core:1069]
+ assert_to_yaml(
+ {"1"=>2, "2"=>3}, <<EOY
+'1': 2
+"2": 3
+EOY
+ )
+
+ # Anchored mapping [ruby-core:1071]
+ assert_to_yaml(
+ [{"a"=>"b"}] * 2, <<EOY
+- &id001
+ a: b
+- *id001
+EOY
+ )
+
+ # Stress test [ruby-core:1071]
+ # a = []; 1000.times { a << {"a"=>"b", "c"=>"d"} }
+ # Psych::load( a.to_yaml )
+
+ end
+
+ #
+ # Test Time.now cycle
+ #
+ def test_time_now_cycle
+ #
+ # From Minero Aoki [ruby-core:2305]
+ #
+ #require 'yaml'
+ t = Time.now
+ t = Time.at(t.tv_sec, t.tv_usec)
+ 5.times do
+ assert_cycle(t)
+ end
+ end
+
+ #
+ # Test Range cycle
+ #
+ def test_range_cycle
+ #
+ # From Minero Aoki [ruby-core:02306]
+ #
+ assert_cycle("a".."z")
+
+ #
+ # From Nobu Nakada [ruby-core:02311]
+ #
+ assert_cycle(0..1)
+ assert_cycle(1.0e20 .. 2.0e20)
+ assert_cycle("0".."1")
+ assert_cycle(".."..."...")
+ assert_cycle(".rb"..".pl")
+ assert_cycle(".rb"...".pl")
+ assert_cycle('"'...".")
+ assert_cycle("'"...".")
+ end
+
+ #
+ # Circular references
+ #
+ def test_circular_references
+ a = []; a[0] = a; a[1] = a
+ inspect_str = "[[...], [...]]"
+ assert_equal( inspect_str, Psych::load(Psych.dump(a)).inspect )
+ end
+
+ #
+ # Test Symbol cycle
+ #
+ def test_symbol_cycle
+ #
+ # From Aaron Schrab [ruby-Bugs:2535]
+ #
+ assert_cycle(:"^foo")
+ end
+
+ #
+ # Test Numeric cycle
+ #
+ class NumericTest < Numeric
+ def initialize(value)
+ @value = value
+ end
+ def ==(other)
+ @value == other.instance_eval{ @value }
+ end
+ end
+ def test_numeric_cycle
+ assert_cycle(1) # Fixnum
+ assert_cycle(111111111111111111111111111111111) # Bignum
+ assert_cycle(NumericTest.new(3)) # Subclass of Numeric
+ end
+
+ #
+ # Test empty map/seq in map cycle
+ #
+ def test_empty_map_key
+ #
+ # empty seq as key
+ #
+ assert_cycle({[]=>""})
+
+ #
+ # empty map as key
+ #
+ assert_cycle({{}=>""})
+ end
+
+ #
+ # contributed by riley lynch [ruby-Bugs-8548]
+ #
+ def test_object_id_collision
+ omap = Psych::Omap.new
+ 1000.times { |i| omap["key_#{i}"] = { "value" => i } }
+ raise "id collision in ordered map" if Psych.dump(omap) =~ /id\d+/
+ end
+
+ def test_date_out_of_range
+ Psych::load('1900-01-01T00:00:00+00:00')
+ end
+
+ def test_normal_exit
+ Psych.load("2000-01-01 00:00:00.#{"0"*1000} +00:00\n")
+ # '[ruby-core:13735]'
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/visitors/test_emitter.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/visitors/test_emitter.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/visitors/test_emitter.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,124 @@
+require_relative '../helper'
+
+module Psych
+ module Visitors
+ class TestEmitter < TestCase
+ def setup
+ super
+ @io = StringIO.new
+ @visitor = Visitors::Emitter.new @io
+ end
+
+ def test_stream
+ s = Nodes::Stream.new
+ @visitor.accept s
+ assert_equal '', @io.string
+ end
+
+ def test_document
+ s = Nodes::Stream.new
+ doc = Nodes::Document.new [1,1]
+ scalar = Nodes::Scalar.new 'hello world'
+
+ doc.children << scalar
+ s.children << doc
+
+ @visitor.accept s
+
+ assert_match(/1.1/, @io.string)
+ assert_equal @io.string, s.to_yaml
+ end
+
+ def test_document_implicit_end
+ s = Nodes::Stream.new
+ doc = Nodes::Document.new
+ mapping = Nodes::Mapping.new
+ mapping.children << Nodes::Scalar.new('key')
+ mapping.children << Nodes::Scalar.new('value')
+ doc.children << mapping
+ s.children << doc
+
+ @visitor.accept s
+
+ assert_match(/key: value/, @io.string)
+ assert_equal @io.string, s.to_yaml
+ assert(/\.\.\./ !~ s.to_yaml)
+ end
+
+ def test_scalar
+ s = Nodes::Stream.new
+ doc = Nodes::Document.new
+ scalar = Nodes::Scalar.new 'hello world'
+
+ doc.children << scalar
+ s.children << doc
+
+ @visitor.accept s
+
+ assert_match(/hello/, @io.string)
+ assert_equal @io.string, s.to_yaml
+ end
+
+ def test_scalar_with_tag
+ s = Nodes::Stream.new
+ doc = Nodes::Document.new
+ scalar = Nodes::Scalar.new 'hello world', nil, '!str', false, false, 5
+
+ doc.children << scalar
+ s.children << doc
+
+ @visitor.accept s
+
+ assert_match(/str/, @io.string)
+ assert_match(/hello/, @io.string)
+ assert_equal @io.string, s.to_yaml
+ end
+
+ def test_sequence
+ s = Nodes::Stream.new
+ doc = Nodes::Document.new
+ scalar = Nodes::Scalar.new 'hello world'
+ seq = Nodes::Sequence.new
+
+ seq.children << scalar
+ doc.children << seq
+ s.children << doc
+
+ @visitor.accept s
+
+ assert_match(/- hello/, @io.string)
+ assert_equal @io.string, s.to_yaml
+ end
+
+ def test_mapping
+ s = Nodes::Stream.new
+ doc = Nodes::Document.new
+ mapping = Nodes::Mapping.new
+ mapping.children << Nodes::Scalar.new('key')
+ mapping.children << Nodes::Scalar.new('value')
+ doc.children << mapping
+ s.children << doc
+
+ @visitor.accept s
+
+ assert_match(/key: value/, @io.string)
+ assert_equal @io.string, s.to_yaml
+ end
+
+ def test_alias
+ s = Nodes::Stream.new
+ doc = Nodes::Document.new
+ mapping = Nodes::Mapping.new
+ mapping.children << Nodes::Scalar.new('key', 'A')
+ mapping.children << Nodes::Alias.new('A')
+ doc.children << mapping
+ s.children << doc
+
+ @visitor.accept s
+
+ assert_match(/&A key: \*A/, @io.string)
+ assert_equal @io.string, s.to_yaml
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/visitors/test_to_ruby.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/visitors/test_to_ruby.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/visitors/test_to_ruby.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,325 @@
+require_relative '../helper'
+
+module Psych
+ module Visitors
+ class TestToRuby < TestCase
+ def setup
+ super
+ @visitor = ToRuby.new
+ end
+
+ def test_object
+ mapping = Nodes::Mapping.new nil, "!ruby/object"
+ mapping.children << Nodes::Scalar.new('foo')
+ mapping.children << Nodes::Scalar.new('bar')
+
+ o = mapping.to_ruby
+ assert_equal 'bar', o.instance_variable_get(:@foo)
+ end
+
+ def test_awesome
+ Psych.load('1900-01-01T00:00:00+00:00')
+ end
+
+ def test_legacy_struct
+ foo = Struct.new('AWESOME', :bar)
+ assert_equal foo.new('baz'), Psych.load(<<-eoyml)
+!ruby/struct:AWESOME
+ bar: baz
+ eoyml
+ end
+
+ def test_binary
+ gif = "GIF89a\f\x00\f\x00\x84\x00\x00\xFF\xFF\xF7\xF5\xF5\xEE\xE9\xE9\xE5fff\x00\x00\x00\xE7\xE7\xE7^^^\xF3\xF3\xED\x8E\x8E\x8E\xE0\xE0\xE0\x9F\x9F\x9F\x93\x93\x93\xA7\xA7\xA7\x9E\x9E\x9Eiiiccc\xA3\xA3\xA3\x84\x84\x84\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9!\xFE\x0EMade with GIMP\x00,\x00\x00\x00\x00\f\x00\f\x00\x00\x05, \x8E\x810\x9E\xE3@\x14\xE8i\x10\xC4\xD1\x8A\b\x1C\xCF\x80M$z\xEF\xFF0\x85p\xB8\xB01f\r\e\xCE\x01\xC3\x01\x1E\x10' \x82\n\x01\x00;"
+
+ hash = Psych.load(<<-'eoyaml')
+canonical: !!binary "\
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs="
+generic: !binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+description:
+ The binary value above is a tiny arrow encoded as a gif image.
+ eoyaml
+ assert_equal gif, hash['canonical']
+ assert_equal gif, hash['generic']
+ end
+
+ A = Struct.new(:foo)
+
+ def test_struct
+ s = A.new('bar')
+
+ mapping = Nodes::Mapping.new nil, "!ruby/struct:#{s.class}"
+ mapping.children << Nodes::Scalar.new('foo')
+ mapping.children << Nodes::Scalar.new('bar')
+
+ ruby = mapping.to_ruby
+
+ assert_equal s.class, ruby.class
+ assert_equal s.foo, ruby.foo
+ assert_equal s, ruby
+ end
+
+ def test_anon_struct_legacy
+ s = Struct.new(:foo).new('bar')
+
+ mapping = Nodes::Mapping.new nil, '!ruby/struct:'
+ mapping.children << Nodes::Scalar.new('foo')
+ mapping.children << Nodes::Scalar.new('bar')
+
+ assert_equal s.foo, mapping.to_ruby.foo
+ end
+
+ def test_anon_struct
+ s = Struct.new(:foo).new('bar')
+
+ mapping = Nodes::Mapping.new nil, '!ruby/struct'
+ mapping.children << Nodes::Scalar.new('foo')
+ mapping.children << Nodes::Scalar.new('bar')
+
+ assert_equal s.foo, mapping.to_ruby.foo
+ end
+
+ def test_exception
+ exc = Exception.new 'hello'
+
+ mapping = Nodes::Mapping.new nil, '!ruby/exception'
+ mapping.children << Nodes::Scalar.new('message')
+ mapping.children << Nodes::Scalar.new('hello')
+
+ ruby = mapping.to_ruby
+
+ assert_equal exc.class, ruby.class
+ assert_equal exc.message, ruby.message
+ end
+
+ def test_regexp
+ node = Nodes::Scalar.new('/foo/', nil, '!ruby/regexp')
+ assert_equal(/foo/, node.to_ruby)
+
+ node = Nodes::Scalar.new('/foo/m', nil, '!ruby/regexp')
+ assert_equal(/foo/m, node.to_ruby)
+
+ node = Nodes::Scalar.new('/foo/ix', nil, '!ruby/regexp')
+ assert_equal(/foo/ix, node.to_ruby)
+ end
+
+ def test_time
+ now = Time.now
+ zone = now.strftime('%z')
+ zone = " #{zone[0,3]}:#{zone[3,5]}"
+
+ formatted = now.strftime("%Y-%m-%d %H:%M:%S.%9N") + zone
+
+ assert_equal now, Nodes::Scalar.new(formatted).to_ruby
+ end
+
+ def test_time_utc
+ now = Time.now.utc
+ formatted = now.strftime("%Y-%m-%d %H:%M:%S") +
+ ".%09dZ" % [now.nsec]
+
+ assert_equal now, Nodes::Scalar.new(formatted).to_ruby
+ end
+
+ def test_time_utc_no_z
+ now = Time.now.utc
+ formatted = now.strftime("%Y-%m-%d %H:%M:%S") +
+ ".%09d" % [now.nsec]
+
+ assert_equal now, Nodes::Scalar.new(formatted).to_ruby
+ end
+
+ def test_date
+ d = '1980-12-16'
+ actual = Date.strptime(d, '%Y-%m-%d')
+
+ date = Nodes::Scalar.new(d, nil, 'tag:yaml.org,2002:timestamp', false)
+
+ assert_equal actual, date.to_ruby
+ end
+
+ def test_rational
+ mapping = Nodes::Mapping.new nil, '!ruby/object:Rational'
+ mapping.children << Nodes::Scalar.new('denominator')
+ mapping.children << Nodes::Scalar.new('2')
+ mapping.children << Nodes::Scalar.new('numerator')
+ mapping.children << Nodes::Scalar.new('1')
+
+ assert_equal Rational(1,2), mapping.to_ruby
+ end
+
+ def test_complex
+ mapping = Nodes::Mapping.new nil, '!ruby/object:Complex'
+ mapping.children << Nodes::Scalar.new('image')
+ mapping.children << Nodes::Scalar.new('2')
+ mapping.children << Nodes::Scalar.new('real')
+ mapping.children << Nodes::Scalar.new('1')
+
+ assert_equal Complex(1,2), mapping.to_ruby
+ end
+
+ if RUBY_VERSION >= '1.9'
+ def test_complex_string
+ node = Nodes::Scalar.new '3+4i', nil, "!ruby/object:Complex"
+ assert_equal Complex(3, 4), node.to_ruby
+ end
+
+ def test_rational_string
+ node = Nodes::Scalar.new '1/2', nil, "!ruby/object:Rational"
+ assert_equal Rational(1, 2), node.to_ruby
+ end
+ end
+
+ def test_range_string
+ node = Nodes::Scalar.new '1..2', nil, "!ruby/range"
+ assert_equal 1..2, node.to_ruby
+ end
+
+ def test_range_string_triple
+ node = Nodes::Scalar.new '1...3', nil, "!ruby/range"
+ assert_equal 1...3, node.to_ruby
+ end
+
+ def test_integer
+ i = Nodes::Scalar.new('1', nil, 'tag:yaml.org,2002:int')
+ assert_equal 1, i.to_ruby
+
+ assert_equal 1, Nodes::Scalar.new('1').to_ruby
+
+ i = Nodes::Scalar.new('-1', nil, 'tag:yaml.org,2002:int')
+ assert_equal(-1, i.to_ruby)
+
+ assert_equal(-1, Nodes::Scalar.new('-1').to_ruby)
+ assert_equal 1, Nodes::Scalar.new('+1').to_ruby
+ end
+
+ def test_int_ignore
+ ['1,000', '1_000'].each do |num|
+ i = Nodes::Scalar.new(num, nil, 'tag:yaml.org,2002:int')
+ assert_equal 1000, i.to_ruby
+
+ assert_equal 1000, Nodes::Scalar.new(num).to_ruby
+ end
+ end
+
+ def test_float_ignore
+ ['1,000.3', '1_000.3'].each do |num|
+ i = Nodes::Scalar.new(num, nil, 'tag:yaml.org,2002:float')
+ assert_equal 1000.3, i.to_ruby
+
+ i = Nodes::Scalar.new(num, nil, '!float')
+ assert_equal 1000.3, i.to_ruby
+
+ assert_equal 1000.3, Nodes::Scalar.new(num).to_ruby
+ end
+ end
+
+ # http://yaml.org/type/bool.html
+ def test_boolean_true
+ %w{ yes Yes YES true True TRUE on On ON }.each do |t|
+ i = Nodes::Scalar.new(t, nil, 'tag:yaml.org,2002:bool')
+ assert_equal true, i.to_ruby
+ assert_equal true, Nodes::Scalar.new(t).to_ruby
+ end
+ end
+
+ # http://yaml.org/type/bool.html
+ def test_boolean_false
+ %w{ no No NO false False FALSE off Off OFF }.each do |t|
+ i = Nodes::Scalar.new(t, nil, 'tag:yaml.org,2002:bool')
+ assert_equal false, i.to_ruby
+ assert_equal false, Nodes::Scalar.new(t).to_ruby
+ end
+ end
+
+ def test_float
+ i = Nodes::Scalar.new('12', nil, 'tag:yaml.org,2002:float')
+ assert_equal 12.0, i.to_ruby
+
+ i = Nodes::Scalar.new('1.2', nil, 'tag:yaml.org,2002:float')
+ assert_equal 1.2, i.to_ruby
+
+ i = Nodes::Scalar.new('1.2')
+ assert_equal 1.2, i.to_ruby
+
+ assert_equal 1, Nodes::Scalar.new('.Inf').to_ruby.infinite?
+ assert_equal 1, Nodes::Scalar.new('.inf').to_ruby.infinite?
+ assert_equal 1, Nodes::Scalar.new('.Inf', nil, 'tag:yaml.org,2002:float').to_ruby.infinite?
+
+ assert_equal(-1, Nodes::Scalar.new('-.inf').to_ruby.infinite?)
+ assert_equal(-1, Nodes::Scalar.new('-.Inf').to_ruby.infinite?)
+ assert_equal(-1, Nodes::Scalar.new('-.Inf', nil, 'tag:yaml.org,2002:float').to_ruby.infinite?)
+
+ assert Nodes::Scalar.new('.NaN').to_ruby.nan?
+ assert Nodes::Scalar.new('.NaN', nil, 'tag:yaml.org,2002:float').to_ruby.nan?
+ end
+
+ def test_exp_float
+ exp = 1.2e+30
+
+ i = Nodes::Scalar.new(exp.to_s, nil, 'tag:yaml.org,2002:float')
+ assert_equal exp, i.to_ruby
+
+ assert_equal exp, Nodes::Scalar.new(exp.to_s).to_ruby
+ end
+
+ def test_scalar
+ scalar = Nodes::Scalar.new('foo')
+ assert_equal 'foo', @visitor.accept(scalar)
+ assert_equal 'foo', scalar.to_ruby
+ end
+
+ def test_sequence
+ seq = Nodes::Sequence.new
+ seq.children << Nodes::Scalar.new('foo')
+ seq.children << Nodes::Scalar.new('bar')
+
+ assert_equal %w{ foo bar }, seq.to_ruby
+ end
+
+ def test_mapping
+ mapping = Nodes::Mapping.new
+ mapping.children << Nodes::Scalar.new('foo')
+ mapping.children << Nodes::Scalar.new('bar')
+ assert_equal({'foo' => 'bar'}, mapping.to_ruby)
+ end
+
+ def test_document
+ doc = Nodes::Document.new
+ doc.children << Nodes::Scalar.new('foo')
+ assert_equal 'foo', doc.to_ruby
+ end
+
+ def test_stream
+ a = Nodes::Document.new
+ a.children << Nodes::Scalar.new('foo')
+
+ b = Nodes::Document.new
+ b.children << Nodes::Scalar.new('bar')
+
+ stream = Nodes::Stream.new
+ stream.children << a
+ stream.children << b
+
+ assert_equal %w{ foo bar }, stream.to_ruby
+ end
+
+ def test_alias
+ seq = Nodes::Sequence.new
+ seq.children << Nodes::Scalar.new('foo', 'A')
+ seq.children << Nodes::Alias.new('A')
+
+ list = seq.to_ruby
+ assert_equal %w{ foo foo }, list
+ assert_equal list[0].object_id, list[1].object_id
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/psych/visitors/test_yaml_tree.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/psych/visitors/test_yaml_tree.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/psych/visitors/test_yaml_tree.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,149 @@
+require_relative '../helper'
+
+module Psych
+ module Visitors
+ class TestYAMLTree < TestCase
+ def setup
+ super
+ @v = Visitors::YAMLTree.new
+ end
+
+ def test_binary_formatting
+ gif = "GIF89a\f\x00\f\x00\x84\x00\x00\xFF\xFF\xF7\xF5\xF5\xEE\xE9\xE9\xE5fff\x00\x00\x00\xE7\xE7\xE7^^^\xF3\xF3\xED\x8E\x8E\x8E\xE0\xE0\xE0\x9F\x9F\x9F\x93\x93\x93\xA7\xA7\xA7\x9E\x9E\x9Eiiiccc\xA3\xA3\xA3\x84\x84\x84\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9\xFF\xFE\xF9!\xFE\x0EMade with GIMP\x00,\x00\x00\x00\x00\f\x00\f\x00\x00\x05, \x8E\x810\x9E\xE3@\x14\xE8i\x10\xC4\xD1\x8A\b\x1C\xCF\x80M$z\xEF\xFF0\x85p\xB8\xB01f\r\e\xCE\x01\xC3\x01\x1E\x10' \x82\n\x01\x00;"
+ @v << gif
+ scalar = @v.tree.children.first.children.first
+ assert_equal Psych::Nodes::Scalar::LITERAL, scalar.style
+ end
+
+ def test_object_has_no_class
+ yaml = Psych.dump(Object.new)
+ assert(Psych.dump(Object.new) !~ /Object/, yaml)
+ end
+
+ def test_struct_const
+ foo = Struct.new("Foo", :bar)
+ assert_cycle foo.new('bar')
+ Struct.instance_eval { remove_const(:Foo) }
+ end
+
+ A = Struct.new(:foo)
+
+ def test_struct
+ assert_cycle A.new('bar')
+ end
+
+ def test_struct_anon
+ s = Struct.new(:foo).new('bar')
+ obj = Psych.load(Psych.dump(s))
+ assert_equal s.foo, obj.foo
+ end
+
+ def test_exception
+ ex = Exception.new 'foo'
+ loaded = Psych.load(Psych.dump(ex))
+
+ assert_equal ex.message, loaded.message
+ assert_equal ex.class, loaded.class
+ end
+
+ def test_regexp
+ assert_cycle(/foo/)
+ assert_cycle(/foo/i)
+ assert_cycle(/foo/mx)
+ end
+
+ def test_time
+ t = Time.now
+ assert_equal t, Psych.load(Psych.dump(t))
+ end
+
+ def test_date
+ date = Date.strptime('2002-12-14', '%Y-%m-%d')
+ assert_cycle date
+ end
+
+ def test_rational
+ assert_cycle Rational(1,2)
+ end
+
+ def test_complex
+ assert_cycle Complex(1,2)
+ end
+
+ def test_scalar
+ assert_cycle 'foo'
+ assert_cycle ':foo'
+ assert_cycle ''
+ assert_cycle ':'
+ end
+
+ def test_boolean
+ assert_cycle true
+ assert_cycle 'true'
+ assert_cycle false
+ assert_cycle 'false'
+ end
+
+ def test_range_inclusive
+ assert_cycle 1..2
+ end
+
+ def test_range_exclusive
+ assert_cycle 1...2
+ end
+
+ def test_anon_class
+ assert_raises(TypeError) do
+ @v.accept Class.new
+ end
+
+ assert_raises(TypeError) do
+ Psych.dump(Class.new)
+ end
+ end
+
+ def test_hash
+ assert_cycle('a' => 'b')
+ end
+
+ def test_list
+ assert_cycle(%w{ a b })
+ assert_cycle([1, 2.2])
+ end
+
+ def test_symbol
+ assert_cycle :foo
+ end
+
+ def test_int
+ assert_cycle 1
+ assert_cycle(-1)
+ assert_cycle '1'
+ assert_cycle '-1'
+ end
+
+ def test_float
+ assert_cycle 1.2
+ assert_cycle '1.2'
+
+ assert Psych.load(Psych.dump(0.0 / 0.0)).nan?
+ assert_equal 1, Psych.load(Psych.dump(1 / 0.0)).infinite?
+ assert_equal(-1, Psych.load(Psych.dump(-1 / 0.0)).infinite?)
+ end
+
+ # http://yaml.org/type/null.html
+ def test_nil
+ assert_cycle nil
+ assert_equal nil, Psych.load('null')
+ assert_equal nil, Psych.load('Null')
+ assert_equal nil, Psych.load('NULL')
+ assert_equal nil, Psych.load('~')
+ assert_equal({'foo' => nil}, Psych.load('foo: '))
+
+ assert_cycle 'null'
+ assert_cycle 'nUll'
+ assert_cycle '~'
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/capture_stdout.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/capture_stdout.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/capture_stdout.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,24 @@
+require 'stringio'
+
+# Mix-in for capturing standard output.
+module CaptureStdout
+ def capture_stdout
+ s = StringIO.new
+ oldstdout = $stdout
+ $stdout = s
+ yield
+ s.string
+ ensure
+ $stdout = oldstdout
+ end
+
+ def capture_stderr
+ s = StringIO.new
+ oldstderr = $stderr
+ $stderr = s
+ yield
+ s.string
+ ensure
+ $stderr = oldstderr
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/check_expansion.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/check_expansion.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/check_expansion.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,5 @@
+if ARGV[0] != ARGV[1]
+ exit 1
+else
+ exit 0
+end
Added: MacRuby/trunk/test/test-mri/test/rake/check_no_expansion.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/check_no_expansion.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/check_no_expansion.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,5 @@
+if ARGV[0] != ARGV[1]
+ exit 0
+else
+ exit 1
+end
Added: MacRuby/trunk/test/test-mri/test/rake/contrib/test_ftp.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/contrib/test_ftp.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/contrib/test_ftp.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,55 @@
+require 'date'
+require 'time'
+require 'test/unit'
+require 'rake/contrib/ftptools'
+
+class Rake::TestFtpFile < Test::Unit::TestCase
+ class FakeDate
+ def self.today
+ Date.new(2003,10,3)
+ end
+ def self.now
+ Time.local(2003,10,3,12,00,00)
+ end
+ end
+
+ def setup
+ Rake::FtpFile.class_eval { @date_class = FakeDate; @time_class = FakeDate }
+ end
+
+ def test_general
+ file = Rake::FtpFile.new("here", "-rw-r--r-- 1 a279376 develop 121770 Mar 6 14:50 wiki.pl")
+ assert_equal "wiki.pl", file.name
+ assert_equal "here/wiki.pl", file.path
+ assert_equal "a279376", file.owner
+ assert_equal "develop", file.group
+ assert_equal 0644, file.mode
+ assert_equal 121770, file.size
+ assert_equal Time.mktime(2003,3,6,14,50,0,0), file.time
+ assert ! file.directory?
+ assert ! file.symlink?
+ end
+
+ def test_far_date
+ file = Rake::FtpFile.new(".", "drwxr-xr-x 3 a279376 develop 4096 Nov 26 2001 vss")
+ assert_equal Time.mktime(2001,11,26,0,0,0,0), file.time
+ end
+
+ def test_close_date
+ file = Rake::FtpFile.new(".", "drwxr-xr-x 3 a279376 develop 4096 Nov 26 15:35 vss")
+ assert_equal Time.mktime(2002,11,26,15,35,0,0), file.time
+ end
+
+ def test_directory
+ file = Rake::FtpFile.new(".", "drwxrwxr-x 9 a279376 develop 4096 Mar 13 14:32 working")
+ assert file.directory?
+ assert !file.symlink?
+ end
+
+ def test_symlink
+ file = Rake::FtpFile.new(".", "lrwxrwxrwx 1 a279376 develop 64 Mar 26 2002 xtrac -> /home/a279376/working/ics/development/java/com/fmr/fwp/ics/xtrac")
+ assert_equal 'xtrac', file.name
+ assert file.symlink?
+ assert !file.directory?
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/data/chains/Rakefile
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/chains/Rakefile (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/chains/Rakefile 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,15 @@
+# -*- ruby -*-
+
+task :default => "play.app"
+
+file "play.scpt" => "base" do |t|
+ cp t.prerequisites.first, t.name
+end
+
+rule ".app" => ".scpt" do |t|
+ cp t.source, t.name
+end
+
+file 'base' do
+ touch 'base'
+end
Added: MacRuby/trunk/test/test-mri/test/rake/data/default/Rakefile
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/default/Rakefile (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/default/Rakefile 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,19 @@
+#!/usr/bin/env ruby
+
+if ENV['TESTTOPSCOPE']
+ puts "TOPSCOPE"
+end
+
+task :default do
+ puts "DEFAULT"
+end
+
+task :other => [:default] do
+ puts "OTHER"
+end
+
+task :task_scope do
+ if ENV['TESTTASKSCOPE']
+ puts "TASKSCOPE"
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/data/dryrun/Rakefile
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/dryrun/Rakefile (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/dryrun/Rakefile 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,22 @@
+#
+
+task :default => ["temp_main"]
+
+file "temp_main" => [:all_apps] do touch "temp_main" end
+
+task :all_apps => [:one, :two]
+task :one => ["temp_one"]
+task :two => ["temp_two"]
+
+file "temp_one" do |t|
+ touch "temp_one"
+end
+file "temp_two" do |t|
+ touch "temp_two"
+end
+
+task :clean do
+ ["temp_one", "temp_two", "temp_main"].each do |file|
+ rm_f file
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/data/file_creation_task/Rakefile
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/file_creation_task/Rakefile (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/file_creation_task/Rakefile 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,33 @@
+#!/usr/bin/env ruby
+
+N = 2
+
+task :default => :run
+
+BUILD_DIR = 'build'
+task :clean do
+ rm_rf 'build'
+ rm_rf 'src'
+end
+
+task :run
+
+TARGET_DIR = 'build/copies'
+
+FileList['src/*'].each do |src|
+ directory TARGET_DIR
+ target = File.join TARGET_DIR, File.basename(src)
+ file target => [src, TARGET_DIR] do
+ cp src, target
+ # sleep 3 if src !~ /foo#{N-1}$/ # I'm commenting out this sleep, it doesn't seem to do anything.
+ end
+ task :run => target
+end
+
+task :prep => :clean do
+ mkdir_p 'src'
+ N.times do |n|
+ puts "DBG: Touching src/foo#{n}"
+ touch "src/foo#{n}"
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/data/imports/Rakefile
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/imports/Rakefile (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/imports/Rakefile 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,19 @@
+# -*- ruby -*-
+
+require 'rake/loaders/makefile'
+
+task :default
+
+task :other do
+ puts "OTHER"
+end
+
+file "dynamic_deps" do |t|
+ open(t.name, "w") do |f| f.puts "puts 'DYNAMIC'" end
+end
+
+import "dynamic_deps"
+import "static_deps"
+import "static_deps"
+import "deps.mf"
+puts "FIRST"
Added: MacRuby/trunk/test/test-mri/test/rake/data/imports/deps.mf
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/imports/deps.mf (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/imports/deps.mf 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+default: other
Added: MacRuby/trunk/test/test-mri/test/rake/data/multidesc/Rakefile
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/multidesc/Rakefile (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/multidesc/Rakefile 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,17 @@
+#!/usr/bin/env ruby
+
+task :b
+
+desc "A"
+task :a
+
+desc "B"
+task :b
+
+desc "A2"
+task :a
+
+task :c
+
+desc "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+task :d
Added: MacRuby/trunk/test/test-mri/test/rake/data/namespace/Rakefile
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/namespace/Rakefile (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/namespace/Rakefile 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,57 @@
+#!/usr/bin/env ruby
+
+desc "copy"
+task :copy do
+ puts "COPY"
+end
+
+namespace "nest" do
+ desc "nest copy"
+ task :copy do
+ puts "NEST COPY"
+ end
+ task :xx => :copy
+end
+
+anon_ns = namespace do
+ desc "anonymous copy task"
+ task :copy do
+ puts "ANON COPY"
+ end
+end
+
+desc "Top level task to run the anonymous version of copy"
+task :anon => anon_ns[:copy]
+
+namespace "very" do
+ namespace "nested" do
+ task "run" => "rake:copy"
+ end
+end
+
+namespace "a" do
+ desc "Run task in the 'a' namespace"
+ task "run" do
+ puts "IN A"
+ end
+end
+
+namespace "b" do
+ desc "Run task in the 'b' namespace"
+ task "run" => "a:run" do
+ puts "IN B"
+ end
+end
+
+namespace "file1" do
+ file "xyz.rb" do
+ puts "XYZ1"
+ end
+end
+
+namespace "file2" do
+ file "xyz.rb" do
+ puts "XYZ2"
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/rake/data/rakelib/test1.rake
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/rakelib/test1.rake (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/rakelib/test1.rake 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,3 @@
+task :default do
+ puts "TEST1"
+end
Added: MacRuby/trunk/test/test-mri/test/rake/data/rbext/rakefile.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/rbext/rakefile.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/rbext/rakefile.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,3 @@
+task :default do
+ puts "OK"
+end
Added: MacRuby/trunk/test/test-mri/test/rake/data/sample.mf
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/sample.mf (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/sample.mf 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,14 @@
+# Comments
+a: a1 a2 a3 a4
+b: b1 b2 b3 \
+ b4 b5 b6\
+# Mid: Comment
+b7
+
+ a : a5 a6 a7
+c: c1
+d: d1 d2 \
+
+e f : e1 f1
+
+g\ 0: g1 g\ 2 g\ 3 g4
Added: MacRuby/trunk/test/test-mri/test/rake/data/statusreturn/Rakefile
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/statusreturn/Rakefile (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/statusreturn/Rakefile 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,8 @@
+#!/usr/bin/env ruby
+
+task :exit5 do
+ exit(5)
+end
+
+task :normal do
+end
Added: MacRuby/trunk/test/test-mri/test/rake/data/unittest/Rakefile
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/unittest/Rakefile (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/unittest/Rakefile 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+# Empty Rakefile for Unit Test
Added: MacRuby/trunk/test/test-mri/test/rake/data/unittest/subdir/.gitignore
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/data/unittest/subdir/.gitignore (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/data/unittest/subdir/.gitignore 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,2 @@
+*
+!.gitignore
Added: MacRuby/trunk/test/test-mri/test/rake/filecreation.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/filecreation.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/filecreation.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,30 @@
+module FileCreation
+ OLDFILE = "testdata/old"
+ NEWFILE = "testdata/new"
+
+ def create_timed_files(oldfile, *newfiles)
+ return if File.exist?(oldfile) && newfiles.all? { |newfile| File.exist?(newfile) }
+ old_time = create_file(oldfile)
+ newfiles.each do |newfile|
+ while create_file(newfile) <= old_time
+ sleep(0.1)
+ File.delete(newfile) rescue nil
+ end
+ end
+ end
+
+ def create_dir(dirname)
+ FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
+ File.stat(dirname).mtime
+ end
+
+ def create_file(name)
+ create_dir(File.dirname(name))
+ FileUtils.touch(name) unless File.exist?(name)
+ File.stat(name).mtime
+ end
+
+ def delete_file(name)
+ File.delete(name) rescue nil
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/in_environment.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/in_environment.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/in_environment.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,30 @@
+module InEnvironment
+ private
+
+ # Create an environment for a test. At the completion of the yielded
+ # block, the environment is restored to its original conditions.
+ def in_environment(settings)
+ original_settings = set_env(settings)
+ yield
+ ensure
+ set_env(original_settings) if original_settings
+ end
+
+ # Set the environment according to the settings hash.
+ def set_env(settings) # :nodoc:
+ result = {}
+ settings.each do |k, v|
+ result[k] = ENV[k]
+ if k == 'PWD'
+ result[k] = Dir.pwd
+ Dir.chdir(v)
+ elsif v.nil?
+ ENV.delete(k)
+ else
+ ENV[k] = v
+ end
+ end
+ result
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/rake/rake_test_setup.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/rake_test_setup.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/rake_test_setup.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,9 @@
+# Common setup for all test files.
+
+# require 'flexmock/test_unit'
+
+module TestMethods
+ def assert_exception(ex, msg=nil, &block)
+ assert_raise(ex, msg, &block)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/reqfile.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/reqfile.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/reqfile.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,3 @@
+# For --require testing
+
+TESTING_REQUIRE << 1
Added: MacRuby/trunk/test/test-mri/test/rake/reqfile2.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/reqfile2.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/reqfile2.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,3 @@
+# For --require testing
+
+TESTING_REQUIRE << 2
Added: MacRuby/trunk/test/test-mri/test/rake/reqfile3.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/reqfile3.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/reqfile3.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,3 @@
+# For --require testing
+
+TESTING_REQUIRE << 3
Added: MacRuby/trunk/test/test-mri/test/rake/shellcommand.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/shellcommand.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/shellcommand.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,3 @@
+#!/usr/bin/env ruby
+
+exit((ARGV[0] || "0").to_i)
Property changes on: MacRuby/trunk/test/test-mri/test/rake/shellcommand.rb
___________________________________________________________________
Added: svn:executable
+ *
Added: MacRuby/trunk/test/test-mri/test/rake/test_application.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_application.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_application.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,687 @@
+require 'test/unit'
+require 'rake'
+require_relative 'capture_stdout'
+require_relative 'in_environment'
+
+TESTING_REQUIRE = [ ]
+
+######################################################################
+class Rake::TestApplication < Test::Unit::TestCase
+ include CaptureStdout
+ include InEnvironment
+ BASEDIR = File.dirname(__FILE__)
+
+ def defmock(*names, &block)
+ class << (@mock ||= Object.new); self; end.class_eval do
+ names.each do |name|
+ define_method(name, block)
+ end
+ end
+ @mock
+ end
+
+ def setup
+ @app = Rake::Application.new
+ @app.options.rakelib = []
+ end
+
+ def test_constant_warning
+ err = capture_stderr do @app.instance_eval { const_warning("Task") } end
+ assert_match(/warning/i, err)
+ assert_match(/deprecated/i, err)
+ assert_match(/Task/i, err)
+ end
+
+ def test_display_tasks
+ @app.options.show_task_pattern = //
+ @app.last_description = "COMMENT"
+ @app.define_task(Rake::Task, "t")
+ out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
+ assert_match(/^rake t/, out)
+ assert_match(/# COMMENT/, out)
+ end
+
+ def test_display_tasks_with_long_comments
+ in_environment('RAKE_COLUMNS' => '80') do
+ @app.options.show_task_pattern = //
+ @app.last_description = "1234567890" * 8
+ @app.define_task(Rake::Task, "t")
+ out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
+ assert_match(/^rake t/, out)
+ assert_match(/# 12345678901234567890123456789012345678901234567890123456789012345\.\.\./, out)
+ end
+ end
+
+ def test_display_tasks_with_task_name_wider_than_tty_display
+ in_environment('RAKE_COLUMNS' => '80') do
+ @app.options.show_task_pattern = //
+ description = "something short"
+ task_name = "task name" * 80
+ @app.last_description = "something short"
+ @app.define_task(Rake::Task, task_name )
+ out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
+ # Ensure the entire task name is output and we end up showing no description
+ assert_match(/rake #{task_name} # .../, out)
+ end
+ end
+
+ def test_display_tasks_with_very_long_task_name_to_a_non_tty_shows_name_and_comment
+ @app.options.show_task_pattern = //
+ @app.tty_output = false
+ description = "something short"
+ task_name = "task name" * 80
+ @app.last_description = "something short"
+ @app.define_task(Rake::Task, task_name )
+ out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
+ # Ensure the entire task name is output and we end up showing no description
+ assert_match(/rake #{task_name} # #{description}/, out)
+ end
+
+ def test_display_tasks_with_long_comments_to_a_non_tty_shows_entire_comment
+ @app.options.show_task_pattern = //
+ @app.tty_output = false
+ @app.last_description = "1234567890" * 8
+ @app.define_task(Rake::Task, "t")
+ out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
+ assert_match(/^rake t/, out)
+ assert_match(/# #{@app.last_description}/, out)
+ end
+
+ def test_display_tasks_with_long_comments_to_a_non_tty_with_columns_set_truncates_comments
+ in_environment("RAKE_COLUMNS" => '80') do
+ @app.options.show_task_pattern = //
+ @app.tty_output = false
+ @app.last_description = "1234567890" * 8
+ @app.define_task(Rake::Task, "t")
+ out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
+ assert_match(/^rake t/, out)
+ assert_match(/# 12345678901234567890123456789012345678901234567890123456789012345\.\.\./, out)
+ end
+ end
+
+ def test_display_tasks_with_full_descriptions
+ @app.options.show_task_pattern = //
+ @app.options.full_description = true
+ @app.last_description = "COMMENT"
+ @app.define_task(Rake::Task, "t")
+ out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end
+ assert_match(/^rake t$/, out)
+ assert_match(/^ {4}COMMENT$/, out)
+ end
+
+ def test_finding_rakefile
+ in_environment("PWD" => File.join(BASEDIR, "data/unittest")) do
+ assert_match(/Rakefile/i, @app.instance_eval { have_rakefile })
+ end
+ end
+
+ def test_not_finding_rakefile
+ @app.instance_eval { @rakefiles = ['NEVER_FOUND'] }
+ assert( ! @app.instance_eval do have_rakefile end )
+ assert_nil @app.rakefile
+ end
+
+ def test_load_rakefile
+ in_environment("PWD" => File.join(BASEDIR, "data/unittest")) do
+ @app.instance_eval do
+ handle_options
+ options.silent = true
+ load_rakefile
+ end
+ assert_equal "rakefile", @app.rakefile.downcase
+ assert_match(%r(unittest$), Dir.pwd)
+ end
+ end
+
+ def test_load_rakefile_from_subdir
+ in_environment("PWD" => File.join(BASEDIR, "data/unittest/subdir")) do
+ @app.instance_eval do
+ handle_options
+ options.silent = true
+ load_rakefile
+ end
+ assert_equal "rakefile", @app.rakefile.downcase
+ assert_match(%r(unittest$), Dir.pwd)
+ end
+ end
+
+ def test_load_rakefile_not_found
+ in_environment("PWD" => "/", "RAKE_SYSTEM" => 'not_exist') do
+ @app.instance_eval do
+ handle_options
+ options.silent = true
+ end
+ ex = assert_raise(RuntimeError) do
+ @app.instance_eval do raw_load_rakefile end
+ end
+ assert_match(/no rakefile found/i, ex.message)
+ end
+ end
+
+ def test_load_from_system_rakefile
+ system_dir = File.expand_path('../data/default', __FILE__)
+ in_environment('RAKE_SYSTEM' => system_dir) do
+ @app.options.rakelib = []
+ @app.instance_eval do
+ handle_options
+ options.silent = true
+ options.load_system = true
+ options.rakelib = []
+ load_rakefile
+ end
+ assert_equal system_dir, @app.system_dir
+ assert_nil @app.rakefile
+ end
+ end
+
+ def test_windows
+ assert ! (@app.windows? && @app.unix?)
+ end
+
+ def test_loading_imports
+ args = []
+ mock = defmock(:load) {|*a| args << a}
+ @app.instance_eval do
+ add_loader("dummy", mock)
+ add_import("x.dummy")
+ load_imports
+ end
+ assert_equal([["x.dummy"]], args)
+ end
+
+ def test_building_imported_files_on_demand
+ args = []
+ callback = false
+ mock = defmock(:load) {|*a| args << a}
+ @app.instance_eval do
+ intern(Rake::Task, "x.dummy").enhance do callback = true end
+ add_loader("dummy", mock)
+ add_import("x.dummy")
+ load_imports
+ end
+ assert_equal([["x.dummy"]], args)
+ assert(callback)
+ end
+
+ def test_handle_options_should_strip_options_from_ARGV
+ assert !@app.options.trace
+
+ valid_option = '--trace'
+ ARGV.clear
+ ARGV << valid_option
+
+ @app.handle_options
+
+ assert !ARGV.include?(valid_option)
+ assert @app.options.trace
+ end
+
+ def test_good_run
+ ran = false
+ ARGV.clear
+ ARGV << '--rakelib=""'
+ @app.options.silent = true
+ @app.instance_eval do
+ intern(Rake::Task, "default").enhance { ran = true }
+ end
+ in_environment("PWD" => File.join(BASEDIR, "data/default")) do
+ @app.run
+ end
+ assert ran
+ end
+
+ def test_display_task_run
+ ran = false
+ ARGV.clear
+ ARGV << '-f' << '-s' << '--tasks' << '--rakelib=""'
+ @app.last_description = "COMMENT"
+ @app.define_task(Rake::Task, "default")
+ out = capture_stdout { @app.run }
+ assert @app.options.show_tasks
+ assert ! ran
+ assert_match(/rake default/, out)
+ assert_match(/# COMMENT/, out)
+ end
+
+ def test_display_prereqs
+ ran = false
+ ARGV.clear
+ ARGV << '-f' << '-s' << '--prereqs' << '--rakelib=""'
+ @app.last_description = "COMMENT"
+ t = @app.define_task(Rake::Task, "default")
+ t.enhance([:a, :b])
+ @app.define_task(Rake::Task, "a")
+ @app.define_task(Rake::Task, "b")
+ out = capture_stdout { @app.run }
+ assert @app.options.show_prereqs
+ assert ! ran
+ assert_match(/rake a$/, out)
+ assert_match(/rake b$/, out)
+ assert_match(/rake default\n( *(a|b)\n){2}/m, out)
+ end
+
+ def test_bad_run
+ @app.intern(Rake::Task, "default").enhance { fail }
+ ARGV.clear
+ ARGV << '-f' << '-s' << '--rakelib=""'
+ assert_raise(SystemExit) {
+ err = capture_stderr { @app.run }
+ assert_match(/see full trace/, err)
+ }
+ ensure
+ ARGV.clear
+ end
+
+ def test_bad_run_with_trace
+ @app.intern(Rake::Task, "default").enhance { fail }
+ ARGV.clear
+ ARGV << '-f' << '-s' << '-t'
+ assert_raise(SystemExit) {
+ err = capture_stderr { capture_stdout { @app.run } }
+ assert_no_match(/see full trace/, err)
+ }
+ ensure
+ ARGV.clear
+ end
+
+ def test_run_with_bad_options
+ @app.intern(Rake::Task, "default").enhance { fail }
+ ARGV.clear
+ ARGV << '-f' << '-s' << '--xyzzy'
+ assert_raise(SystemExit) {
+ err = capture_stderr { capture_stdout { @app.run } }
+ }
+ ensure
+ ARGV.clear
+ end
+end
+
+
+######################################################################
+class Rake::TestApplicationOptions < Test::Unit::TestCase
+ include CaptureStdout
+
+ def setup
+ clear_argv
+ RakeFileUtils.verbose_flag = false
+ RakeFileUtils.nowrite_flag = false
+ TESTING_REQUIRE.clear
+ end
+
+ def teardown
+ clear_argv
+ RakeFileUtils.verbose_flag = false
+ RakeFileUtils.nowrite_flag = false
+ end
+
+ def clear_argv
+ while ! ARGV.empty?
+ ARGV.pop
+ end
+ end
+
+ def test_default_options
+ opts = command_line
+ assert_nil opts.classic_namespace
+ assert_nil opts.dryrun
+ assert_nil opts.full_description
+ assert_nil opts.ignore_system
+ assert_nil opts.load_system
+ assert_nil opts.nosearch
+ assert_equal ['rakelib'], opts.rakelib
+ assert_nil opts.show_prereqs
+ assert_nil opts.show_task_pattern
+ assert_nil opts.show_tasks
+ assert_nil opts.silent
+ assert_nil opts.trace
+ assert_equal ['rakelib'], opts.rakelib
+ assert ! RakeFileUtils.verbose_flag
+ assert ! RakeFileUtils.nowrite_flag
+ end
+
+ def test_dry_run
+ flags('--dry-run', '-n') do |opts|
+ assert opts.dryrun
+ assert opts.trace
+ assert RakeFileUtils.verbose_flag
+ assert RakeFileUtils.nowrite_flag
+ end
+ end
+
+ def test_describe
+ flags('--describe') do |opts|
+ assert opts.full_description
+ assert opts.show_tasks
+ assert_equal(//.to_s, opts.show_task_pattern.to_s)
+ end
+ end
+
+ def test_describe_with_pattern
+ flags('--describe=X') do |opts|
+ assert opts.full_description
+ assert opts.show_tasks
+ assert_equal(/X/.to_s, opts.show_task_pattern.to_s)
+ end
+ end
+
+ def test_execute
+ $xyzzy = 0
+ flags('--execute=$xyzzy=1', '-e $xyzzy=1') do |opts|
+ assert_equal 1, $xyzzy
+ assert_equal :exit, @exit
+ $xyzzy = 0
+ end
+ end
+
+ def test_execute_and_continue
+ $xyzzy = 0
+ flags('--execute-continue=$xyzzy=1', '-E $xyzzy=1') do |opts|
+ assert_equal 1, $xyzzy
+ assert_not_equal :exit, @exit
+ $xyzzy = 0
+ end
+ end
+
+ def test_execute_and_print
+ $xyzzy = 0
+ flags('--execute-print=$xyzzy="pugh"', '-p $xyzzy="pugh"') do |opts|
+ assert_equal 'pugh', $xyzzy
+ assert_equal :exit, @exit
+ assert_match(/^pugh$/, @out)
+ $xyzzy = 0
+ end
+ end
+
+ def test_help
+ flags('--help', '-H', '-h') do |opts|
+ assert_match(/\Arake/, @out)
+ assert_match(/\boptions\b/, @out)
+ assert_match(/\btargets\b/, @out)
+ assert_equal :exit, @exit
+ assert_equal :exit, @exit
+ end
+ end
+
+ def test_libdir
+ flags(['--libdir', 'xx'], ['-I', 'xx'], ['-Ixx']) do |opts|
+ $:.include?('xx')
+ end
+ ensure
+ $:.delete('xx')
+ end
+
+ def test_rakefile
+ flags(['--rakefile', 'RF'], ['--rakefile=RF'], ['-f', 'RF'], ['-fRF']) do |opts|
+ assert_equal ['RF'], @app.instance_eval { @rakefiles }
+ end
+ end
+
+ def test_rakelib
+ flags(['--rakelibdir', 'A:B:C'], ['--rakelibdir=A:B:C'], ['-R', 'A:B:C'], ['-RA:B:C']) do |opts|
+ assert_equal ['A', 'B', 'C'], opts.rakelib
+ end
+ end
+
+ def test_require
+ flags(['--require', File.expand_path('../reqfile', __FILE__)],
+ "-r#{File.expand_path('../reqfile2', __FILE__)}",
+ "-r#{File.expand_path('../reqfile3', __FILE__)}") do |opts|
+ end
+ assert TESTING_REQUIRE.include?(1)
+ assert TESTING_REQUIRE.include?(2)
+ assert TESTING_REQUIRE.include?(3)
+ assert_equal 3, TESTING_REQUIRE.size
+ end
+
+ def test_missing_require
+ ex = assert_raise(LoadError) do
+ flags(['--require', File.expand_path('../missing', __FILE__)]) do |opts|
+ end
+ end
+ assert_match(/no such file/, ex.message)
+ assert_match(/#{File.basename(File.dirname(__FILE__))}\/missing/, ex.message)
+ end
+
+ def test_prereqs
+ flags('--prereqs', '-P') do |opts|
+ assert opts.show_prereqs
+ end
+ end
+
+ def test_quiet
+ flags('--quiet', '-q') do |opts|
+ assert ! RakeFileUtils.verbose_flag
+ assert ! opts.silent
+ end
+ end
+
+ def test_no_search
+ flags('--nosearch', '--no-search', '-N') do |opts|
+ assert opts.nosearch
+ end
+ end
+
+ def test_silent
+ flags('--silent', '-s') do |opts|
+ assert ! RakeFileUtils.verbose_flag
+ assert opts.silent
+ end
+ end
+
+ def test_system
+ flags('--system', '-g') do |opts|
+ assert opts.load_system
+ end
+ end
+
+ def test_no_system
+ flags('--no-system', '-G') do |opts|
+ assert opts.ignore_system
+ end
+ end
+
+ def test_trace
+ flags('--trace', '-t') do |opts|
+ assert opts.trace
+ assert RakeFileUtils.verbose_flag
+ assert ! RakeFileUtils.nowrite_flag
+ end
+ end
+
+ def test_trace_rules
+ flags('--rules') do |opts|
+ assert opts.trace_rules
+ end
+ end
+
+ def test_tasks
+ flags('--tasks', '-T') do |opts|
+ assert opts.show_tasks
+ assert_equal(//.to_s, opts.show_task_pattern.to_s)
+ end
+ flags(['--tasks', 'xyz'], ['-Txyz']) do |opts|
+ assert opts.show_tasks
+ assert_equal(/xyz/, opts.show_task_pattern)
+ end
+ end
+
+ def test_verbose
+ flags('--verbose', '-V') do |opts|
+ assert RakeFileUtils.verbose_flag
+ assert ! opts.silent
+ end
+ end
+
+ def test_version
+ flags('--version', '-V') do |opts|
+ assert_match(/\bversion\b/, @out)
+ assert_match(/\b#{RAKEVERSION}\b/, @out)
+ assert_equal :exit, @exit
+ end
+ end
+
+ def test_classic_namespace
+ flags(['--classic-namespace'], ['-C', '-T', '-P', '-n', '-s', '-t']) do |opts|
+ assert opts.classic_namespace
+ assert_equal opts.show_tasks, $show_tasks
+ assert_equal opts.show_prereqs, $show_prereqs
+ assert_equal opts.trace, $trace
+ assert_equal opts.dryrun, $dryrun
+ assert_equal opts.silent, $silent
+ end
+ end
+
+ def test_bad_option
+ capture_stderr do
+ ex = assert_raise(OptionParser::InvalidOption) do
+ flags('--bad-option')
+ end
+ if ex.message =~ /^While/ # Ruby 1.9 error message
+ assert_match(/while parsing/i, ex.message)
+ else # Ruby 1.8 error message
+ assert_match(/(invalid|unrecognized) option/i, ex.message)
+ assert_match(/--bad-option/, ex.message)
+ end
+ end
+ end
+
+ def test_task_collection
+ command_line("a", "b")
+ assert_equal ["a", "b"], @tasks.sort
+ end
+
+ def test_default_task_collection
+ command_line()
+ assert_equal ["default"], @tasks
+ end
+
+ def test_environment_definition
+ ENV.delete('TESTKEY')
+ command_line("a", "TESTKEY=12")
+ assert_equal ["a"], @tasks.sort
+ assert '12', ENV['TESTKEY']
+ end
+
+ private
+
+ def flags(*sets)
+ sets.each do |set|
+ ARGV.clear
+ @out = capture_stdout {
+ @exit = catch(:system_exit) { opts = command_line(*set) }
+ }
+ yield(@app.options) if block_given?
+ end
+ end
+
+ def command_line(*options)
+ options.each do |opt| ARGV << opt end
+ @app = Rake::Application.new
+ def @app.exit(*args)
+ throw :system_exit, :exit
+ end
+ @app.instance_eval do
+ handle_options
+ collect_tasks
+ end
+ @tasks = @app.top_level_tasks
+ @app.options
+ end
+end
+
+class Rake::TestTaskArgumentParsing < Test::Unit::TestCase
+ def setup
+ @app = Rake::Application.new
+ end
+
+ def test_name_only
+ name, args = @app.parse_task_string("name")
+ assert_equal "name", name
+ assert_equal [], args
+ end
+
+ def test_empty_args
+ name, args = @app.parse_task_string("name[]")
+ assert_equal "name", name
+ assert_equal [], args
+ end
+
+ def test_one_argument
+ name, args = @app.parse_task_string("name[one]")
+ assert_equal "name", name
+ assert_equal ["one"], args
+ end
+
+ def test_two_arguments
+ name, args = @app.parse_task_string("name[one,two]")
+ assert_equal "name", name
+ assert_equal ["one", "two"], args
+ end
+
+ def test_can_handle_spaces_between_args
+ name, args = @app.parse_task_string("name[one, two,\tthree , \tfour]")
+ assert_equal "name", name
+ assert_equal ["one", "two", "three", "four"], args
+ end
+
+ def test_keeps_embedded_spaces
+ name, args = @app.parse_task_string("name[a one ana, two]")
+ assert_equal "name", name
+ assert_equal ["a one ana", "two"], args
+ end
+
+end
+
+class Rake::TestTaskArgumentParsing < Test::Unit::TestCase
+ include InEnvironment
+
+ def test_terminal_width_using_env
+ app = Rake::Application.new
+ in_environment('RAKE_COLUMNS' => '1234') do
+ assert_equal 1234, app.terminal_width
+ end
+ end
+
+ def test_terminal_width_using_stty
+ app = Rake::Application.new
+ def app.unix?() true end
+ def app.dynamic_width_stty() 1235 end
+ def app.dynamic_width_tput() 0 end
+ in_environment('RAKE_COLUMNS' => nil) do
+ assert_equal 1235, app.terminal_width
+ end
+ end
+
+ def test_terminal_width_using_tput
+ app = Rake::Application.new
+ def app.unix?() true end
+ def app.dynamic_width_stty() 0 end
+ def app.dynamic_width_tput() 1236 end
+ in_environment('RAKE_COLUMNS' => nil) do
+ assert_equal 1236, app.terminal_width
+ end
+ end
+
+ def test_terminal_width_using_hardcoded_80
+ app = Rake::Application.new
+ def app.unix?() false end
+ in_environment('RAKE_COLUMNS' => nil) do
+ assert_equal 80, app.terminal_width
+ end
+ end
+
+ def test_terminal_width_with_failure
+ app = Rake::Application.new
+ called = false
+ class << app; self; end.class_eval do
+ define_method(:unix?) {|*a|
+ called = a
+ raise RuntimeError
+ }
+ end
+ in_environment('RAKE_COLUMNS' => nil) do
+ assert_equal 80, app.terminal_width
+ end
+ assert_equal([], called)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_clean.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_clean.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_clean.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,12 @@
+require 'test/unit'
+require 'rake/clean'
+
+class Rake::TestClean < Test::Unit::TestCase
+ include Rake
+ def test_clean
+ assert Task['clean'], "Should define clean"
+ assert Task['clobber'], "Should define clobber"
+ assert Task['clobber'].prerequisites.include?("clean"),
+ "Clobber should require clean"
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_definitions.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_definitions.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_definitions.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,81 @@
+require 'test/unit'
+require 'fileutils'
+require 'rake'
+require_relative 'filecreation'
+
+######################################################################
+class Rake::TestDefinitions < Test::Unit::TestCase
+ include Rake
+
+ EXISTINGFILE = "testdata/existing"
+
+ def setup
+ Task.clear
+ end
+
+ def test_task
+ done = false
+ task :one => [:two] do done = true end
+ task :two
+ task :three => [:one, :two]
+ check_tasks(:one, :two, :three)
+ assert done, "Should be done"
+ end
+
+ def test_file_task
+ done = false
+ file "testdata/one" => "testdata/two" do done = true end
+ file "testdata/two"
+ file "testdata/three" => ["testdata/one", "testdata/two"]
+ check_tasks("testdata/one", "testdata/two", "testdata/three")
+ assert done, "Should be done"
+ end
+
+ def check_tasks(n1, n2, n3)
+ t = Task[n1]
+ assert Task === t, "Should be a Task"
+ assert_equal n1.to_s, t.name
+ assert_equal [n2.to_s], t.prerequisites.collect{|n| n.to_s}
+ t.invoke
+ t2 = Task[n2]
+ assert_equal FileList[], t2.prerequisites
+ t3 = Task[n3]
+ assert_equal [n1.to_s, n2.to_s], t3.prerequisites.collect{|n|n.to_s}
+ end
+
+ def test_incremental_definitions
+ runs = []
+ task :t1 => [:t2] do runs << "A"; 4321 end
+ task :t1 => [:t3] do runs << "B"; 1234 end
+ task :t1 => [:t3]
+ task :t2
+ task :t3
+ Task[:t1].invoke
+ assert_equal ["A", "B"], runs
+ assert_equal ["t2", "t3"], Task[:t1].prerequisites
+ end
+
+ def test_missing_dependencies
+ task :x => ["testdata/missing"]
+ assert_raise(RuntimeError) { Task[:x].invoke }
+ end
+
+ def test_implicit_file_dependencies
+ runs = []
+ create_existing_file
+ task :y => [EXISTINGFILE] do |t| runs << t.name end
+ Task[:y].invoke
+ assert_equal runs, ['y']
+ end
+
+ private # ----------------------------------------------------------
+
+ def create_existing_file
+ Dir.mkdir File.dirname(EXISTINGFILE) unless
+ File.exist?(File.dirname(EXISTINGFILE))
+ open(EXISTINGFILE, "w") do |f| f.puts "HI" end unless
+ File.exist?(EXISTINGFILE)
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rake/test_earlytime.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_earlytime.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_earlytime.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,33 @@
+require 'test/unit'
+require 'rake'
+
+class Rake::TestEarlyTime < Test::Unit::TestCase
+ def test_create
+ early = Rake::EarlyTime.instance
+ time = Time.mktime(1970, 1, 1, 0, 0, 0)
+ assert early <= Time.now
+ assert early < Time.now
+ assert early != Time.now
+ assert Time.now > early
+ assert Time.now >= early
+ assert Time.now != early
+ end
+
+ def test_equality
+ early = Rake::EarlyTime.instance
+ assert_equal early, early, "two early times should be equal"
+ end
+
+ def test_original_time_compare_is_not_messed_up
+ t1 = Time.mktime(1970, 1, 1, 0, 0, 0)
+ t2 = Time.now
+ assert t1 < t2
+ assert t2 > t1
+ assert t1 == t1
+ assert t2 == t2
+ end
+
+ def test_to_s
+ assert_equal "<EARLY TIME>", Rake::EARLY.to_s
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_extension.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_extension.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_extension.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,61 @@
+require 'test/unit'
+require 'rake'
+require 'stringio'
+
+######################################################################
+class Rake::TestExtension < Test::Unit::TestCase
+
+ module Redirect
+ def error_redirect
+ old_err = $stderr
+ result = StringIO.new
+ $stderr = result
+ yield
+ result
+ ensure
+ $stderr = old_err
+ end
+ end
+
+ class Sample
+ extend Redirect
+
+ def duplicate_method
+ :original
+ end
+
+ OK_ERRS = error_redirect do
+ rake_extension("a") do
+ def ok_method
+ end
+ end
+ end
+
+
+ DUP_ERRS = error_redirect do
+ rake_extension("duplicate_method") do
+ def duplicate_method
+ :override
+ end
+ end
+ end
+ end
+
+ def test_methods_actually_exist
+ sample = Sample.new
+ sample.ok_method
+ sample.duplicate_method
+ end
+
+ def test_no_warning_when_defining_ok_method
+ assert_equal "", Sample::OK_ERRS.string
+ end
+
+ def test_extension_complains_when_a_method_that_is_present
+ assert_match(/warning:/i, Sample::DUP_ERRS.string)
+ assert_match(/already exists/i, Sample::DUP_ERRS.string)
+ assert_match(/duplicate_method/i, Sample::DUP_ERRS.string)
+ assert_equal :original, Sample.new.duplicate_method
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_file_creation_task.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_file_creation_task.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_file_creation_task.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,60 @@
+require 'test/unit'
+require 'fileutils'
+require 'rake'
+require_relative 'filecreation'
+
+######################################################################
+class Rake::TestFileCreationTask < Test::Unit::TestCase
+ include Rake
+ include FileCreation
+
+ DUMMY_DIR = 'testdata/dummy_dir'
+
+ def setup
+ Task.clear
+ end
+
+ def teardown
+ FileUtils.rm_rf DUMMY_DIR
+ end
+
+ def test_file_needed
+ create_dir DUMMY_DIR
+ fc_task = Task[DUMMY_DIR]
+ assert_equal DUMMY_DIR, fc_task.name
+ FileUtils.rm_rf fc_task.name
+ assert fc_task.needed?, "file should be needed"
+ FileUtils.mkdir fc_task.name
+ assert_equal nil, fc_task.prerequisites.collect{|n| Task[n].timestamp}.max
+ assert ! fc_task.needed?, "file should not be needed"
+ end
+
+ def test_directory
+ directory DUMMY_DIR
+ fc_task = Task[DUMMY_DIR]
+ assert_equal DUMMY_DIR, fc_task.name
+ assert FileCreationTask === fc_task
+ end
+
+ def test_no_retriggers_on_filecreate_task
+ create_timed_files(OLDFILE, NEWFILE)
+ t1 = Rake.application.intern(FileCreationTask, OLDFILE).enhance([NEWFILE])
+ t2 = Rake.application.intern(FileCreationTask, NEWFILE)
+ assert ! t2.needed?, "Should not need to build new file"
+ assert ! t1.needed?, "Should not need to rebuild old file because of new"
+ end
+
+ def test_no_retriggers_on_file_task
+ create_timed_files(OLDFILE, NEWFILE)
+ t1 = Rake.application.intern(FileCreationTask, OLDFILE).enhance([NEWFILE])
+ t2 = Rake.application.intern(FileCreationTask, NEWFILE)
+ assert ! t2.needed?, "Should not need to build new file"
+ assert ! t1.needed?, "Should not need to rebuild old file because of new"
+ end
+
+ def test_very_early_timestamp
+ t1 = Rake.application.intern(FileCreationTask, OLDFILE)
+ assert t1.timestamp < Time.now
+ assert t1.timestamp < Time.now - 1000000
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_file_task.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_file_task.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_file_task.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,139 @@
+require 'test/unit'
+require 'fileutils'
+require 'rake'
+require_relative 'filecreation'
+
+######################################################################
+class Rake::TestFileTask < Test::Unit::TestCase
+ include Rake
+ include FileCreation
+
+ def setup
+ Task.clear
+ @runs = Array.new
+ FileUtils.rm_f NEWFILE
+ FileUtils.rm_f OLDFILE
+ end
+
+ def test_file_need
+ name = "testdata/dummy"
+ file name
+ ftask = Task[name]
+ assert_equal name.to_s, ftask.name
+ File.delete(ftask.name) rescue nil
+ assert ftask.needed?, "file should be needed"
+ open(ftask.name, "w") { |f| f.puts "HI" }
+ assert_equal nil, ftask.prerequisites.collect{|n| Task[n].timestamp}.max
+ assert ! ftask.needed?, "file should not be needed"
+ File.delete(ftask.name) rescue nil
+ end
+
+ def test_file_times_new_depends_on_old
+ create_timed_files(OLDFILE, NEWFILE)
+
+ t1 = Rake.application.intern(FileTask, NEWFILE).enhance([OLDFILE])
+ t2 = Rake.application.intern(FileTask, OLDFILE)
+ assert ! t2.needed?, "Should not need to build old file"
+ assert ! t1.needed?, "Should not need to rebuild new file because of old"
+ end
+
+ def test_file_times_old_depends_on_new
+ create_timed_files(OLDFILE, NEWFILE)
+
+ t1 = Rake.application.intern(FileTask,OLDFILE).enhance([NEWFILE])
+ t2 = Rake.application.intern(FileTask, NEWFILE)
+ assert ! t2.needed?, "Should not need to build new file"
+ preq_stamp = t1.prerequisites.collect{|t| Task[t].timestamp}.max
+ assert_equal t2.timestamp, preq_stamp
+ assert t1.timestamp < preq_stamp, "T1 should be older"
+ assert t1.needed?, "Should need to rebuild old file because of new"
+ end
+
+ def test_file_depends_on_task_depend_on_file
+ create_timed_files(OLDFILE, NEWFILE)
+
+ file NEWFILE => [:obj] do |t| @runs << t.name end
+ task :obj => [OLDFILE] do |t| @runs << t.name end
+ file OLDFILE do |t| @runs << t.name end
+
+ Task[:obj].invoke
+ Task[NEWFILE].invoke
+ assert ! @runs.include?(NEWFILE)
+ end
+
+ def test_existing_file_depends_on_non_existing_file
+ create_file(OLDFILE)
+ delete_file(NEWFILE)
+ file NEWFILE
+ file OLDFILE => NEWFILE
+ assert_nothing_raised do Task[OLDFILE].invoke end
+ end
+
+ # I have currently disabled this test. I'm not convinced that
+ # deleting the file target on failure is always the proper thing to
+ # do. I'm willing to hear input on this topic.
+ def ztest_file_deletes_on_failure
+ task :obj
+ file NEWFILE => [:obj] do |t|
+ FileUtils.touch NEWFILE
+ fail "Ooops"
+ end
+ assert Task[NEWFILE]
+ begin
+ Task[NEWFILE].invoke
+ rescue Exception
+ end
+ assert( ! File.exist?(NEWFILE), "NEWFILE should be deleted")
+ end
+
+end
+
+######################################################################
+class Rake::TestDirectoryTask < Test::Unit::TestCase
+ include Rake
+
+ def setup
+ rm_rf "testdata", :verbose=>false
+ end
+
+ def teardown
+ rm_rf "testdata", :verbose=>false
+ end
+
+ def test_directory
+ desc "DESC"
+ directory "testdata/a/b/c"
+ assert_equal FileCreationTask, Task["testdata"].class
+ assert_equal FileCreationTask, Task["testdata/a"].class
+ assert_equal FileCreationTask, Task["testdata/a/b/c"].class
+ assert_nil Task["testdata"].comment
+ assert_equal "DESC", Task["testdata/a/b/c"].comment
+ assert_nil Task["testdata/a/b"].comment
+ verbose(false) {
+ Task['testdata/a/b'].invoke
+ }
+ assert File.exist?("testdata/a/b")
+ assert ! File.exist?("testdata/a/b/c")
+ end
+
+ if Rake::Win32.windows?
+ def test_directory_win32
+ desc "WIN32 DESC"
+ FileUtils.mkdir_p("testdata")
+ Dir.chdir("testdata") do
+ directory 'c:/testdata/a/b/c'
+ assert_equal FileCreationTask, Task['c:/testdata'].class
+ assert_equal FileCreationTask, Task['c:/testdata/a'].class
+ assert_equal FileCreationTask, Task['c:/testdata/a/b/c'].class
+ assert_nil Task['c:/testdata'].comment
+ assert_equal "WIN32 DESC", Task['c:/testdata/a/b/c'].comment
+ assert_nil Task['c:/testdata/a/b'].comment
+ verbose(false) {
+ Task['c:/testdata/a/b'].invoke
+ }
+ assert File.exist?('c:/testdata/a/b')
+ assert ! File.exist?('c:/testdata/a/b/c')
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_filelist.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_filelist.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_filelist.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,625 @@
+require 'test/unit'
+require 'tmpdir'
+require 'rake'
+
+require_relative 'capture_stdout'
+
+class Rake::TestFileList < Test::Unit::TestCase
+ FileList = Rake::FileList
+ include CaptureStdout
+
+ def setup
+ @oldwd = Dir.pwd
+ @tmpwd = Dir.mktmpdir
+ Dir.chdir(@tmpwd)
+ create_test_data
+ end
+
+ def teardown
+# FileList.select_default_ignore_patterns
+ FileUtils.rm_rf("testdata")
+ Dir.chdir(@oldwd)
+ FileUtils.rm_rf(@tmpwd)
+ end
+
+ def test_delgating_methods_do_not_include_to_a_or_to_ary
+ assert ! FileList::DELEGATING_METHODS.include?("to_a"), "should not include to_a"
+ assert ! FileList::DELEGATING_METHODS.include?(:to_a), "should not include to_a"
+ assert ! FileList::DELEGATING_METHODS.include?("to_ary"), "should not include to_ary"
+ assert ! FileList::DELEGATING_METHODS.include?(:to_ary), "should not include to_ary"
+ end
+
+ def test_create
+ fl = FileList.new
+ assert_equal 0, fl.size
+ end
+
+ def test_create_with_args
+ fl = FileList.new("testdata/*.c", "x")
+ assert_equal ["testdata/abc.c", "testdata/x.c", "testdata/xyz.c", "x"].sort,
+ fl.sort
+ end
+
+ def test_create_with_block
+ fl = FileList.new { |f| f.include("x") }
+ assert_equal ["x"], fl.resolve
+ end
+
+ def test_create_with_brackets
+ fl = FileList["testdata/*.c", "x"]
+ assert_equal ["testdata/abc.c", "testdata/x.c", "testdata/xyz.c", "x"].sort,
+ fl.sort
+ end
+
+ def test_create_with_brackets_and_filelist
+ fl = FileList[FileList["testdata/*.c", "x"]]
+ assert_equal ["testdata/abc.c", "testdata/x.c", "testdata/xyz.c", "x"].sort,
+ fl.sort
+ end
+
+ def test_include_with_another_array
+ fl = FileList.new.include(["x", "y", "z"])
+ assert_equal ["x", "y", "z"].sort, fl.sort
+ end
+
+ def test_include_with_another_filelist
+ fl = FileList.new.include(FileList["testdata/*.c", "x"])
+ assert_equal ["testdata/abc.c", "testdata/x.c", "testdata/xyz.c", "x"].sort,
+ fl.sort
+ end
+
+ def test_append
+ fl = FileList.new
+ fl << "a.rb" << "b.rb"
+ assert_equal ['a.rb', 'b.rb'], fl
+ end
+
+ def test_add_many
+ fl = FileList.new
+ fl.include %w(a d c)
+ fl.include('x', 'y')
+ assert_equal ['a', 'd', 'c', 'x', 'y'], fl
+ assert_equal ['a', 'd', 'c', 'x', 'y'], fl.resolve
+ end
+
+ def test_add_return
+ f = FileList.new
+ g = f << "x"
+ assert_equal f.object_id, g.object_id
+ h = f.include("y")
+ assert_equal f.object_id, h.object_id
+ end
+
+ def test_match
+ fl = FileList.new
+ fl.include(File.expand_path('../test*.rb', __FILE__))
+ assert fl.include?(__FILE__)
+ assert fl.size > 3
+ fl.each { |fn| assert_match(/\.rb$/, fn) }
+ end
+
+ def test_add_matching
+ fl = FileList.new
+ fl << "a.java"
+ fl.include(File.dirname(__FILE__)+"/*.rb")
+ assert_equal "a.java", fl[0]
+ assert fl.size > 2
+ assert fl.include?(__FILE__)
+ end
+
+ def test_multiple_patterns
+ create_test_data
+ fl = FileList.new
+ fl.include('*.c', '*xist*')
+ assert_equal [], fl
+ fl.include('testdata/*.c', 'testdata/*xist*')
+ assert_equal [
+ 'testdata/x.c', 'testdata/xyz.c', 'testdata/abc.c', 'testdata/existing'
+ ].sort, fl.sort
+ end
+
+ def test_square_bracket_pattern
+ fl = FileList.new
+ fl.include("testdata/abc.[ch]")
+ assert fl.size == 2
+ assert fl.include?("testdata/abc.c")
+ assert fl.include?("testdata/abc.h")
+ end
+
+ def test_curly_bracket_pattern
+ fl = FileList.new
+ fl.include("testdata/abc.{c,h}")
+ assert fl.size == 2
+ assert fl.include?("testdata/abc.c")
+ assert fl.include?("testdata/abc.h")
+ end
+
+ def test_reject
+ fl = FileList.new
+ fl.include %w(testdata/x.c testdata/abc.c testdata/xyz.c testdata/existing)
+ fl.reject! { |fn| fn =~ %r{/x} }
+ assert_equal [
+ 'testdata/abc.c', 'testdata/existing'
+ ], fl
+ end
+
+ def test_exclude
+ fl = FileList['testdata/x.c', 'testdata/abc.c', 'testdata/xyz.c', 'testdata/existing']
+ fl.each { |fn| touch fn, :verbose => false }
+ x = fl.exclude(%r{/x.+\.})
+ assert_equal FileList, x.class
+ assert_equal %w(testdata/x.c testdata/abc.c testdata/existing), fl
+ assert_equal fl.object_id, x.object_id
+ fl.exclude('testdata/*.c')
+ assert_equal ['testdata/existing'], fl
+ fl.exclude('testdata/existing')
+ assert_equal [], fl
+ end
+
+ def test_excluding_via_block
+ fl = FileList['testdata/a.c', 'testdata/b.c', 'testdata/xyz.c']
+ fl.exclude { |fn| fn.pathmap('%n') == 'xyz' }
+ assert fl.exclude?("xyz.c"), "Should exclude xyz.c"
+ assert_equal ['testdata/a.c', 'testdata/b.c'], fl
+ end
+
+ def test_exclude_return_on_create
+ fl = FileList['testdata/*'].exclude(/.*\.[hcx]$/)
+ assert_equal ['testdata/existing', 'testdata/cfiles'].sort, fl.sort
+ assert_equal FileList, fl.class
+ end
+
+ def test_exclude_with_string_return_on_create
+ fl = FileList['testdata/*'].exclude('testdata/abc.c')
+ assert_equal %w(testdata/existing testdata/cfiles testdata/x.c testdata/abc.h testdata/abc.x testdata/xyz.c).sort, fl.sort
+ assert_equal FileList, fl.class
+ end
+
+ def test_default_exclude
+ fl = FileList.new
+ fl.clear_exclude
+ fl.include("**/*~", "**/*.bak", "**/core")
+ assert fl.member?("testdata/core"), "Should include core"
+ assert fl.member?("testdata/x.bak"), "Should include .bak files"
+ end
+
+ def test_unique
+ fl = FileList.new
+ fl << "x.c" << "a.c" << "b.rb" << "a.c"
+ assert_equal ['x.c', 'a.c', 'b.rb', 'a.c'], fl
+ fl.uniq!
+ assert_equal ['x.c', 'a.c', 'b.rb'], fl
+ end
+
+ def test_to_string
+ fl = FileList.new
+ fl << "a.java" << "b.java"
+ assert_equal "a.java b.java", fl.to_s
+ assert_equal "a.java b.java", "#{fl}"
+ end
+
+ def test_to_array
+ fl = FileList['a.java', 'b.java']
+ assert_equal ['a.java', 'b.java'], fl.to_a
+ assert_equal Array, fl.to_a.class
+ assert_equal ['a.java', 'b.java'], fl.to_ary
+ assert_equal Array, fl.to_ary.class
+ end
+
+ def test_to_s_pending
+ fl = FileList['testdata/abc.*']
+ result = fl.to_s
+ assert_match(%r{testdata/abc\.c}, result)
+ assert_match(%r{testdata/abc\.h}, result)
+ assert_match(%r{testdata/abc\.x}, result)
+ assert_match(%r{(testdata/abc\..\b ?){2}}, result)
+ end
+
+ def test_inspect_pending
+ fl = FileList['testdata/abc.*']
+ result = fl.inspect
+ assert_match(%r{"testdata/abc\.c"}, result)
+ assert_match(%r{"testdata/abc\.h"}, result)
+ assert_match(%r{"testdata/abc\.x"}, result)
+ assert_match(%r|^\[("testdata/abc\..", ){2}"testdata/abc\.."\]$|, result)
+ end
+
+ def test_sub
+ fl = FileList["testdata/*.c"]
+ f2 = fl.sub(/\.c$/, ".o")
+ assert_equal FileList, f2.class
+ assert_equal ["testdata/abc.o", "testdata/x.o", "testdata/xyz.o"].sort,
+ f2.sort
+ f3 = fl.gsub(/\.c$/, ".o")
+ assert_equal FileList, f3.class
+ assert_equal ["testdata/abc.o", "testdata/x.o", "testdata/xyz.o"].sort,
+ f3.sort
+ end
+
+ def test_claim_to_be_a_kind_of_array
+ fl = FileList['testdata/*.c']
+ assert fl.is_a?(Array)
+ assert fl.kind_of?(Array)
+ end
+
+ def test_claim_to_be_a_kind_of_filelist
+ fl = FileList['testdata/*.c']
+ assert fl.is_a?(FileList)
+ assert fl.kind_of?(FileList)
+ end
+
+ def test_claim_to_be_a_filelist_instance
+ fl = FileList['testdata/*.c']
+ assert fl.instance_of?(FileList)
+ end
+
+ def test_dont_claim_to_be_an_array_instance
+ fl = FileList['testdata/*.c']
+ assert ! fl.instance_of?(Array)
+ end
+
+ def test_sub!
+ f = "x/a.c"
+ fl = FileList[f, "x/b.c"]
+ res = fl.sub!(/\.c$/, ".o")
+ assert_equal ["x/a.o", "x/b.o"].sort, fl.sort
+ assert_equal "x/a.c", f
+ assert_equal fl.object_id, res.object_id
+ end
+
+ def test_sub_with_block
+ fl = FileList["src/org/onestepback/a.java", "src/org/onestepback/b.java"]
+# The block version doesn't work the way I want it to ...
+# f2 = fl.sub(%r{^src/(.*)\.java$}) { |x| "classes/" + $1 + ".class" }
+ f2 = fl.sub(%r{^src/(.*)\.java$}, "classes/\\1.class")
+ assert_equal [
+ "classes/org/onestepback/a.class",
+ "classes/org/onestepback/b.class"
+ ].sort,
+ f2.sort
+ end
+
+ def test_string_ext
+ assert_equal "one.net", "one.two".ext("net")
+ assert_equal "one.net", "one.two".ext(".net")
+ assert_equal "one.net", "one".ext("net")
+ assert_equal "one.net", "one".ext(".net")
+ assert_equal "one.two.net", "one.two.c".ext(".net")
+ assert_equal "one/two.net", "one/two.c".ext(".net")
+ assert_equal "one.x/two.net", "one.x/two.c".ext(".net")
+ assert_equal "one.x/two.net", "one.x/two".ext(".net")
+ assert_equal ".onerc.net", ".onerc.dot".ext("net")
+ assert_equal ".onerc.net", ".onerc".ext("net")
+ assert_equal ".a/.onerc.net", ".a/.onerc".ext("net")
+ assert_equal "one", "one.two".ext('')
+ assert_equal "one", "one.two".ext
+ assert_equal ".one", ".one.two".ext
+ assert_equal ".one", ".one".ext
+ assert_equal ".", ".".ext("c")
+ assert_equal "..", "..".ext("c")
+ # These only need to work in windows
+ if Rake::Win32.windows?
+ assert_equal "one.x\\two.net", "one.x\\two.c".ext(".net")
+ assert_equal "one.x\\two.net", "one.x\\two".ext(".net")
+ end
+ end
+
+ def test_filelist_ext
+ assert_equal FileList['one.c', '.one.c'],
+ FileList['one.net', '.one'].ext('c')
+ end
+
+ def test_gsub
+ create_test_data
+ fl = FileList["testdata/*.c"]
+ f2 = fl.gsub(/a/, "A")
+ assert_equal ["testdAtA/Abc.c", "testdAtA/x.c", "testdAtA/xyz.c"].sort,
+ f2.sort
+ end
+
+ def test_gsub!
+ create_test_data
+ f = FileList["testdata/*.c"]
+ f.gsub!(/a/, "A")
+ assert_equal ["testdAtA/Abc.c", "testdAtA/x.c", "testdAtA/xyz.c"].sort,
+ f.sort
+ end
+
+ def test_egrep_with_output
+ files = FileList[File.expand_path('../test*.rb', __FILE__)]
+ the_line_number = __LINE__ + 1
+ out = capture_stdout do files.egrep(/PUGH/) end
+ assert_match(/:#{the_line_number}:/, out)
+ end
+
+ def test_egrep_with_block
+ files = FileList[File.expand_path('../test*.rb', __FILE__)]
+ found = false
+ the_line_number = __LINE__ + 1
+ files.egrep(/XYZZY/) do |fn, ln, line |
+ assert_equal __FILE__, fn
+ assert_equal the_line_number, ln
+ assert_match(/files\.egrep/, line)
+ found = true
+ end
+ assert found, "should have found a matching line"
+ end
+
+ def test_existing
+ fl = FileList['testdata/abc.c', 'testdata/notthere.c']
+ assert_equal ["testdata/abc.c"], fl.existing
+ assert fl.existing.is_a?(FileList)
+ end
+
+ def test_existing!
+ fl = FileList['testdata/abc.c', 'testdata/notthere.c']
+ result = fl.existing!
+ assert_equal ["testdata/abc.c"], fl
+ assert_equal fl.object_id, result.object_id
+ end
+
+ def test_ignore_special
+ f = FileList['testdata/*']
+ assert ! f.include?("testdata/CVS"), "Should not contain CVS"
+ assert ! f.include?("testdata/.svn"), "Should not contain .svn"
+ assert ! f.include?("testdata/.dummy"), "Should not contain dot files"
+ assert ! f.include?("testdata/x.bak"), "Should not contain .bak files"
+ assert ! f.include?("testdata/x~"), "Should not contain ~ files"
+ assert ! f.include?("testdata/core"), "Should not contain core files"
+ end
+
+ def test_clear_ignore_patterns
+ f = FileList['testdata/*', 'testdata/.svn']
+ f.clear_exclude
+ assert f.include?("testdata/abc.c")
+ assert f.include?("testdata/xyz.c")
+ assert f.include?("testdata/CVS")
+ assert f.include?("testdata/.svn")
+ assert f.include?("testdata/x.bak")
+ assert f.include?("testdata/x~")
+ end
+
+ def test_exclude_with_alternate_file_seps
+ fl = FileList.new
+ assert fl.exclude?("x/CVS/y")
+ assert fl.exclude?("x\\CVS\\y")
+ assert fl.exclude?("x/.svn/y")
+ assert fl.exclude?("x\\.svn\\y")
+ assert fl.exclude?("x/core")
+ assert fl.exclude?("x\\core")
+ end
+
+ def test_add_default_exclude_list
+ fl = FileList.new
+ fl.exclude(/~\d+$/)
+ assert fl.exclude?("x/CVS/y")
+ assert fl.exclude?("x\\CVS\\y")
+ assert fl.exclude?("x/.svn/y")
+ assert fl.exclude?("x\\.svn\\y")
+ assert fl.exclude?("x/core")
+ assert fl.exclude?("x\\core")
+ assert fl.exclude?("x/abc~1")
+ end
+
+ def test_basic_array_functions
+ f = FileList['b', 'c', 'a']
+ assert_equal 'b', f.first
+ assert_equal 'b', f[0]
+ assert_equal 'a', f.last
+ assert_equal 'a', f[2]
+ assert_equal 'a', f[-1]
+ assert_equal ['a', 'b', 'c'], f.sort
+ f.sort!
+ assert_equal ['a', 'b', 'c'], f
+ end
+
+ def test_flatten
+ assert_equal ['a', 'testdata/x.c', 'testdata/xyz.c', 'testdata/abc.c'].sort,
+ ['a', FileList['testdata/*.c']].flatten.sort
+ end
+
+ def test_clone_and_dup
+ a = FileList['a', 'b', 'c']
+ c = a.clone
+ d = a.dup
+ a << 'd'
+ assert_equal ['a', 'b', 'c', 'd'], a
+ assert_equal ['a', 'b', 'c'], c
+ assert_equal ['a', 'b', 'c'], d
+ end
+
+ def test_dup_and_clone_replicate_taint
+ a = FileList['a', 'b', 'c']
+ a.taint
+ c = a.clone
+ d = a.dup
+ assert c.tainted?, "Clone should be tainted"
+ assert d.tainted?, "Dup should be tainted"
+ end
+
+ def test_duped_items_will_thaw
+ a = FileList['a', 'b', 'c']
+ a.freeze
+ d = a.dup
+ d << 'more'
+ assert_equal ['a', 'b', 'c', 'more'], d
+ end
+
+ def test_cloned_items_stay_frozen
+ a = FileList['a', 'b', 'c']
+ a.freeze
+ c = a.clone
+ assert_raise(TypeError, RuntimeError) do
+ c << 'more'
+ end
+ end
+
+ def test_array_comparisons
+ fl = FileList['b', 'b']
+ a = ['b', 'a']
+ b = ['b', 'b']
+ c = ['b', 'c']
+ assert_equal( 1, fl <=> a )
+ assert_equal( 0, fl <=> b )
+ assert_equal( -1, fl <=> c )
+ assert_equal( -1, a <=> fl )
+ assert_equal( 0, b <=> fl )
+ assert_equal( 1, c <=> fl )
+ end
+
+ def test_array_equality
+ a = FileList['a', 'b']
+ b = ['a', 'b']
+ assert a == b
+ assert b == a
+# assert a.eql?(b)
+# assert b.eql?(a)
+ assert ! a.equal?(b)
+ assert ! b.equal?(a)
+ end
+
+ def test_enumeration_methods
+ a = FileList['a', 'b']
+ b = a.collect { |it| it.upcase }
+ assert_equal ['A', 'B'], b
+ assert_equal FileList, b.class
+
+ b = a.map { |it| it.upcase }
+ assert_equal ['A', 'B'], b
+ assert_equal FileList, b.class
+
+ b = a.sort
+ assert_equal ['a', 'b'], b
+ assert_equal FileList, b.class
+
+ b = a.sort_by { |it| it }
+ assert_equal ['a', 'b'], b
+ assert_equal FileList, b.class
+
+ b = a.find_all { |it| it == 'b'}
+ assert_equal ['b'], b
+ assert_equal FileList, b.class
+
+ b = a.select { |it| it.size == 1 }
+ assert_equal ['a', 'b'], b
+ assert_equal FileList, b.class
+
+ b = a.reject { |it| it == 'b' }
+ assert_equal ['a'], b
+ assert_equal FileList, b.class
+
+ b = a.grep(/./)
+ assert_equal ['a', 'b'], b
+ assert_equal FileList, b.class
+
+ b = a.partition { |it| it == 'b' }
+ assert_equal [['b'], ['a']], b
+ assert_equal Array, b.class
+ assert_equal FileList, b[0].class
+ assert_equal FileList, b[1].class
+
+ b = a.zip(['x', 'y']).to_a
+ assert_equal [['a', 'x'], ['b', 'y']], b
+ assert_equal Array, b.class
+ assert_equal Array, b[0].class
+ assert_equal Array, b[1].class
+ end
+
+ def test_array_operators
+ a = ['a', 'b']
+ b = ['c', 'd']
+ f = FileList['x', 'y']
+ g = FileList['w', 'z']
+
+ r = f + g
+ assert_equal ['x', 'y', 'w', 'z'], r
+ assert_equal FileList, r.class
+
+ r = a + g
+ assert_equal ['a', 'b', 'w', 'z'], r
+ assert_equal Array, r.class
+
+ r = f + b
+ assert_equal ['x', 'y', 'c', 'd'], r
+ assert_equal FileList, r.class
+
+ r = FileList['w', 'x', 'y', 'z'] - f
+ assert_equal ['w', 'z'], r
+ assert_equal FileList, r.class
+
+ r = FileList['w', 'x', 'y', 'z'] & f
+ assert_equal ['x', 'y'], r
+ assert_equal FileList, r.class
+
+ r = f * 2
+ assert_equal ['x', 'y', 'x', 'y'], r
+ assert_equal FileList, r.class
+
+ r = f * ','
+ assert_equal 'x,y', r
+ assert_equal String, r.class
+
+ r = f | ['a', 'x']
+ assert_equal ['a', 'x', 'y'].sort, r.sort
+ assert_equal FileList, r.class
+ end
+
+ def test_other_array_returning_methods
+ f = FileList['a', nil, 'b']
+ r = f.compact
+ assert_equal ['a', 'b'], r
+ assert_equal FileList, r.class
+
+ f = FileList['a', 'b']
+ r = f.concat(['x', 'y'])
+ assert_equal ['a', 'b', 'x', 'y'], r
+ assert_equal FileList, r.class
+
+ f = FileList['a', ['b', 'c'], FileList['d', 'e']]
+ r = f.flatten
+ assert_equal ['a', 'b', 'c', 'd', 'e'], r
+ assert_equal FileList, r.class
+
+ f = FileList['a', 'b', 'a']
+ r = f.uniq
+ assert_equal ['a', 'b'], r
+ assert_equal FileList, r.class
+
+ f = FileList['a', 'b', 'c', 'd']
+ r = f.values_at(1,3)
+ assert_equal ['b', 'd'], r
+ assert_equal FileList, r.class
+ end
+
+ def test_file_utils_can_use_filelists
+ cfiles = FileList['testdata/*.c']
+
+ cp cfiles, @cdir, :verbose => false
+
+ assert File.exist?(File.join(@cdir, 'abc.c'))
+ assert File.exist?(File.join(@cdir, 'xyz.c'))
+ assert File.exist?(File.join(@cdir, 'x.c'))
+ end
+
+ def create_test_data
+ verbose(false) do
+
+ mkdir "testdata" unless File.exist? "testdata"
+ mkdir "testdata/CVS" rescue nil
+ mkdir "testdata/.svn" rescue nil
+ @cdir = "testdata/cfiles"
+ mkdir @cdir rescue nil
+ touch "testdata/.dummy"
+ touch "testdata/x.bak"
+ touch "testdata/x~"
+ touch "testdata/core"
+ touch "testdata/x.c"
+ touch "testdata/xyz.c"
+ touch "testdata/abc.c"
+ touch "testdata/abc.h"
+ touch "testdata/abc.x"
+ touch "testdata/existing"
+ end
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_fileutils.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_fileutils.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_fileutils.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,262 @@
+require 'rake'
+require 'test/unit'
+require_relative 'filecreation'
+require 'fileutils'
+require 'stringio'
+
+class Rake::TestFileUtils < Test::Unit::TestCase
+ include FileCreation
+ BASEDIR = File.dirname(__FILE__)
+ ShellCommand = "#{BASEDIR}/shellcommand.rb"
+ ENV_RUBY = ENV['RUBY']
+
+ def setup
+ if ruby = ENV_RUBY
+ @oldruby = FileUtils.class_eval {remove_const :RUBY}
+ FileUtils.class_eval {const_set(:RUBY, ruby)}
+ else
+ @oldruby = nil
+ end
+ end
+
+ def teardown
+ FileUtils.rm_rf("testdata")
+ FileUtils::LN_SUPPORTED[0] = true
+ if @oldruby
+ ruby = @oldruby
+ FileUtils.class_eval {remove_const :RUBY}
+ FileUtils.class_eval {const_set(:RUBY, ruby)}
+ end
+ end
+
+ def test_rm_one_file
+ create_file("testdata/a")
+ FileUtils.rm_rf "testdata/a"
+ assert ! File.exist?("testdata/a")
+ end
+
+ def test_rm_two_files
+ create_file("testdata/a")
+ create_file("testdata/b")
+ FileUtils.rm_rf ["testdata/a", "testdata/b"]
+ assert ! File.exist?("testdata/a")
+ assert ! File.exist?("testdata/b")
+ end
+
+ def test_rm_filelist
+ list = Rake::FileList.new << "testdata/a" << "testdata/b"
+ list.each { |fn| create_file(fn) }
+ FileUtils.rm_r list
+ assert ! File.exist?("testdata/a")
+ assert ! File.exist?("testdata/b")
+ end
+
+ def test_ln
+ create_dir("testdata")
+ open("testdata/a", "w") { |f| f.puts "TEST_LN" }
+ RakeFileUtils.safe_ln("testdata/a", "testdata/b", :verbose => false)
+ assert_equal "TEST_LN\n", open("testdata/b") { |f| f.read }
+ end
+
+ class BadLink
+ include RakeFileUtils
+ attr_reader :cp_args
+ def initialize(klass)
+ @failure_class = klass
+ end
+ def cp(*args)
+ @cp_args = args
+ end
+ def ln(*args)
+ fail @failure_class, "ln not supported"
+ end
+ public :safe_ln
+ end
+
+ def test_safe_ln_failover_to_cp_on_standard_error
+ FileUtils::LN_SUPPORTED[0] = true
+ c = BadLink.new(StandardError)
+ c.safe_ln "a", "b"
+ assert_equal ['a', 'b'], c.cp_args
+ c.safe_ln "x", "y"
+ assert_equal ['x', 'y'], c.cp_args
+ end
+
+ def test_safe_ln_failover_to_cp_on_not_implemented_error
+ FileUtils::LN_SUPPORTED[0] = true
+ c = BadLink.new(NotImplementedError)
+ c.safe_ln "a", "b"
+ assert_equal ['a', 'b'], c.cp_args
+ end
+
+ def test_safe_ln_fails_on_script_error
+ FileUtils::LN_SUPPORTED[0] = true
+ c = BadLink.new(ScriptError)
+ assert_raise(ScriptError) do c.safe_ln "a", "b" end
+ end
+
+ def test_verbose
+ verbose true
+ assert_equal true, verbose
+ verbose false
+ assert_equal false, verbose
+ verbose(true) {
+ assert_equal true, verbose
+ }
+ assert_equal false, verbose
+ end
+
+ def test_nowrite
+ nowrite true
+ assert_equal true, nowrite
+ nowrite false
+ assert_equal false, nowrite
+ nowrite(true){
+ assert_equal true, nowrite
+ }
+ assert_equal false, nowrite
+ end
+
+ def test_file_utils_methods_are_available_at_top_level
+ create_file("testdata/a")
+ verbose(false) do
+ rm_rf "testdata/a"
+ end
+ assert ! File.exist?("testdata/a")
+ end
+
+ def test_fileutils_methods_dont_leak
+ obj = Object.new
+ assert_raise(NoMethodError) { obj.copy } # from FileUtils
+ assert_raise(NoMethodError) { obj.ruby } # from RubyFileUtils
+ end
+
+ def test_sh
+ verbose(false) { sh %{#{RUBY} #{ShellCommand}} }
+ assert true, "should not fail"
+ end
+
+ # If the :sh method is invoked directly from a test unit instance
+ # (under mini/test), the mini/test version of fail is invoked rather
+ # than the kernel version of fail. So we run :sh from within a
+ # non-test class to avoid the problem.
+ class Sh
+ include FileUtils
+ def run(*args)
+ sh(*args)
+ end
+ def self.run(*args)
+ new.run(*args)
+ end
+ end
+
+ def test_sh_with_a_single_string_argument
+ ENV['RAKE_TEST_SH'] = 'someval'
+ verbose(false) {
+ sh %{#{RUBY} #{BASEDIR}/check_expansion.rb #{env_var} someval}
+ }
+ end
+
+ def test_sh_with_multiple_arguments
+ ENV['RAKE_TEST_SH'] = 'someval'
+ verbose(false) {
+ Sh.run RUBY, File.expand_path('../check_no_expansion.rb', __FILE__), env_var, 'someval'
+ }
+ end
+
+ def test_sh_failure
+ assert_raise(RuntimeError) {
+ verbose(false) { Sh.run "#{RUBY} #{File.expand_path('../shellcommand.rb', __FILE__)} 1" }
+ }
+ end
+
+ def test_sh_special_handling
+ count = 0
+ verbose(false) {
+ sh(%{#{RUBY} #{ShellCommand}}) do |ok, res|
+ assert(ok)
+ assert_equal 0, res.exitstatus
+ count += 1
+ end
+ sh(%{#{RUBY} #{ShellCommand} 1}) do |ok, res|
+ assert(!ok)
+ assert_equal 1, res.exitstatus
+ count += 1
+ end
+ }
+ assert_equal 2, count, "Block count should be 2"
+ end
+
+ def test_sh_noop
+ verbose(false) { sh %{#{ShellCommand} 1}, :noop=>true }
+ assert true, "should not fail"
+ end
+
+ def test_sh_bad_option
+ ex = assert_raise(ArgumentError) {
+ verbose(false) { sh %{#{ShellCommand}}, :bad_option=>true }
+ }
+ assert_match(/bad_option/, ex.message)
+ end
+
+ def test_sh_verbose
+ out = redirect_stderr {
+ verbose(true) {
+ sh %{#{ShellCommand}}, :noop=>true
+ }
+ }
+ assert_match(/^#{Regexp.quote(ShellCommand)}$/o, out)
+ end
+
+ def test_sh_no_verbose
+ out = redirect_stderr {
+ verbose(false) {
+ sh %{#{ShellCommand}}, :noop=>true
+ }
+ }
+ assert_equal '', out
+ end
+
+ def test_ruby_with_a_single_string_argument
+ ENV['RAKE_TEST_SH'] = 'someval'
+ verbose(false) {
+ ruby %{#{BASEDIR}/check_expansion.rb #{env_var} someval}
+ }
+ end
+
+ def test_ruby_with_multiple_arguments
+ ENV['RAKE_TEST_SH'] = 'someval'
+ verbose(false) {
+ ruby "#{BASEDIR}/check_no_expansion.rb", env_var, 'someval'
+ }
+ end
+
+ def test_split_all
+ assert_equal ['a'], RakeFileUtils.split_all('a')
+ assert_equal ['..'], RakeFileUtils.split_all('..')
+ assert_equal ['/'], RakeFileUtils.split_all('/')
+ assert_equal ['a', 'b'], RakeFileUtils.split_all('a/b')
+ assert_equal ['/', 'a', 'b'], RakeFileUtils.split_all('/a/b')
+ assert_equal ['..', 'a', 'b'], RakeFileUtils.split_all('../a/b')
+ end
+
+ private
+
+ def redirect_stderr
+ old_err = $stderr
+ $stderr = StringIO.new
+ yield
+ $stderr.string
+ ensure
+ $stderr = old_err
+ end
+
+ def windows?
+ ! File::ALT_SEPARATOR.nil?
+ end
+
+ def env_var
+ windows? ? '%RAKE_TEST_SH%' : '$RAKE_TEST_SH'
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_invocation_chain.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_invocation_chain.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_invocation_chain.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,75 @@
+require 'test/unit'
+require 'rake'
+
+######################################################################
+class Rake::TestAnEmptyInvocationChain < Test::Unit::TestCase
+
+ def setup
+ @empty = Rake::InvocationChain::EMPTY
+ end
+
+ def test_should_be_able_to_add_members
+ assert_nothing_raised do
+ @empty.append("A")
+ end
+ end
+
+ def test_to_s
+ assert_equal "TOP", @empty.to_s
+ end
+end
+
+######################################################################
+class Rake::TestAnInvocationChainWithOneMember < Test::Unit::TestCase
+
+ def setup
+ @empty = Rake::InvocationChain::EMPTY
+ @first_member = "A"
+ @chain = @empty.append(@first_member)
+ end
+
+ def test_should_report_first_member_as_a_member
+ assert @chain.member?(@first_member)
+ end
+
+ def test_should_fail_when_adding_original_member
+ ex = assert_raise RuntimeError do
+ @chain.append(@first_member)
+ end
+ assert_match(/circular +dependency/i, ex.message)
+ assert_match(/A.*=>.*A/, ex.message)
+ end
+
+ def test_to_s
+ assert_equal "TOP => A", @chain.to_s
+ end
+
+end
+
+######################################################################
+class Rake::TestAnInvocationChainWithMultipleMember < Test::Unit::TestCase
+
+ def setup
+ @first_member = "A"
+ @second_member = "B"
+ ch = Rake::InvocationChain::EMPTY.append(@first_member)
+ @chain = ch.append(@second_member)
+ end
+
+ def test_should_report_first_member_as_a_member
+ assert @chain.member?(@first_member)
+ end
+
+ def test_should_report_second_member_as_a_member
+ assert @chain.member?(@second_member)
+ end
+
+ def test_should_fail_when_adding_original_member
+ ex = assert_raise RuntimeError do
+ @chain.append(@first_member)
+ end
+ assert_match(/A.*=>.*B.*=>.*A/, ex.message)
+ end
+end
+
+
Added: MacRuby/trunk/test/test-mri/test/rake/test_makefile_loader.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_makefile_loader.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_makefile_loader.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,24 @@
+require 'test/unit'
+require 'rake'
+require 'rake/loaders/makefile'
+
+class Rake::TestMakefileLoader < Test::Unit::TestCase
+ include Rake
+
+ def test_parse
+ Task.clear
+ loader = Rake::MakefileLoader.new
+ loader.load("#{File.dirname(__FILE__)}/data/sample.mf")
+ %w(a b c d).each do |t|
+ assert Task.task_defined?(t), "#{t} should be a defined task"
+ end
+ assert_equal %w(a1 a2 a3 a4 a5 a6 a7).sort, Task['a'].prerequisites.sort
+ assert_equal %w(b1 b2 b3 b4 b5 b6 b7).sort, Task['b'].prerequisites.sort
+ assert_equal %w(c1).sort, Task['c'].prerequisites.sort
+ assert_equal %w(d1 d2).sort, Task['d'].prerequisites.sort
+ assert_equal %w(e1 f1).sort, Task['e'].prerequisites.sort
+ assert_equal %w(e1 f1).sort, Task['f'].prerequisites.sort
+ assert_equal ["g1", "g 2", "g 3", "g4"].sort, Task['g 0'].prerequisites.sort
+ assert_equal 7, Task.tasks.size
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_multitask.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_multitask.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_multitask.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,43 @@
+require 'test/unit'
+require 'rake'
+
+######################################################################
+class Rake::TestMultiTask < Test::Unit::TestCase
+ include Rake
+
+ def setup
+ Task.clear
+ @runs = Array.new
+ end
+
+ def test_running_multitasks
+ task :a do 3.times do |i| @runs << "A#{i}"; sleep 0.01; end end
+ task :b do 3.times do |i| @runs << "B#{i}"; sleep 0.01; end end
+ multitask :both => [:a, :b]
+ Task[:both].invoke
+ assert_equal 6, @runs.size
+ assert @runs.index("A0") < @runs.index("A1")
+ assert @runs.index("A1") < @runs.index("A2")
+ assert @runs.index("B0") < @runs.index("B1")
+ assert @runs.index("B1") < @runs.index("B2")
+ end
+
+ def test_all_multitasks_wait_on_slow_prerequisites
+ task :slow do 3.times do |i| @runs << "S#{i}"; sleep 0.05 end end
+ task :a => [:slow] do 3.times do |i| @runs << "A#{i}"; sleep 0.01 end end
+ task :b => [:slow] do 3.times do |i| @runs << "B#{i}"; sleep 0.01 end end
+ multitask :both => [:a, :b]
+ Task[:both].invoke
+ assert_equal 9, @runs.size
+ assert @runs.index("S0") < @runs.index("S1")
+ assert @runs.index("S1") < @runs.index("S2")
+ assert @runs.index("S2") < @runs.index("A0")
+ assert @runs.index("S2") < @runs.index("B0")
+ assert @runs.index("A0") < @runs.index("A1")
+ assert @runs.index("A1") < @runs.index("A2")
+ assert @runs.index("B0") < @runs.index("B1")
+ assert @runs.index("B1") < @runs.index("B2")
+ end
+end
+
+
Added: MacRuby/trunk/test/test-mri/test/rake/test_namespace.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_namespace.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_namespace.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,44 @@
+require 'test/unit'
+require 'rake'
+
+class Rake::TestNameSpace < Test::Unit::TestCase
+
+ class TM
+ include Rake::TaskManager
+ end
+
+ def test_namespace_creation
+ mgr = TM.new
+ ns = Rake::NameSpace.new(mgr, [])
+ assert_not_nil ns
+ end
+
+ def test_namespace_lookup
+ mgr = TM.new
+ ns = mgr.in_namespace("n") do
+ mgr.define_task(Rake::Task, "t")
+ end
+
+ assert_not_nil ns["t"]
+ assert_equal mgr["n:t"], ns["t"]
+ end
+
+ def test_namespace_reports_tasks_it_owns
+ mgr = TM.new
+ nns = nil
+ ns = mgr.in_namespace("n") do
+ mgr.define_task(Rake::Task, :x)
+ mgr.define_task(Rake::Task, :y)
+ nns = mgr.in_namespace("nn") do
+ mgr.define_task(Rake::Task, :z)
+ end
+ end
+ mgr.in_namespace("m") do
+ mgr.define_task(Rake::Task, :x)
+ end
+
+ assert_equal ["n:nn:z", "n:x", "n:y"],
+ ns.tasks.map { |tsk| tsk.name }
+ assert_equal ["n:nn:z"], nns.tasks.map {|t| t.name}
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_package_task.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_package_task.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_package_task.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,115 @@
+require 'tmpdir'
+require 'fileutils'
+require 'test/unit'
+require 'rake/packagetask'
+
+class Rake::TestPackageTask < Test::Unit::TestCase
+ include Rake
+
+ def test_create
+ pwd = Dir.pwd
+ tmpdir = Dir.mktmpdir("rake")
+ Dir.chdir(tmpdir)
+ Dir.mkdir("bin")
+ open("bin/rake", "wb") {}
+ pkg = Rake::PackageTask.new("pkgr", "1.2.3") { |p|
+ p.package_files << "install.rb"
+ p.package_files.include(
+ '[A-Z]*',
+ 'bin/**/*',
+ 'lib/**/*.rb',
+ 'test/**/*.rb',
+ 'doc/**/*',
+ 'build/rubyapp.rb',
+ '*.blurb')
+ p.package_files.exclude(/\bCVS\b/)
+ p.package_files.exclude(/~$/)
+ p.package_dir = 'pkg'
+ p.need_tar = true
+ p.need_tar_gz = true
+ p.need_tar_bz2 = true
+ p.need_zip = true
+ }
+ assert_equal "pkg", pkg.package_dir
+ assert pkg.package_files.include?("bin/rake")
+ assert "pkgr", pkg.name
+ assert "1.2.3", pkg.version
+ assert Task[:package]
+ assert Task['pkg/pkgr-1.2.3.tgz']
+ assert Task['pkg/pkgr-1.2.3.tar.gz']
+ assert Task['pkg/pkgr-1.2.3.tar.bz2']
+ assert Task['pkg/pkgr-1.2.3.zip']
+ assert Task["pkg/pkgr-1.2.3"]
+ assert Task[:clobber_package]
+ assert Task[:repackage]
+ ensure
+ Dir.chdir(pwd)
+ FileUtils.rm_rf(tmpdir)
+ end
+
+ def test_missing_version
+ assert_raise(RuntimeError) {
+ pkg = Rake::PackageTask.new("pkgr") { |p| }
+ }
+ end
+
+ def test_no_version
+ pkg = Rake::PackageTask.new("pkgr", :noversion) { |p| }
+ assert "pkgr", pkg.send(:package_name)
+ end
+
+ def test_clone
+ pkg = Rake::PackageTask.new("x", :noversion)
+ p2 = pkg.clone
+ pkg.package_files << "y"
+ p2.package_files << "x"
+ assert_equal ["y"], pkg.package_files
+ assert_equal ["x"], p2.package_files
+ end
+end
+
+
+require 'rake/gempackagetask'
+
+class Rake::TestGemPackageTask < Test::Unit::TestCase
+ def test_gem_package
+ gem = Gem::Specification.new do |g|
+ g.name = "pkgr"
+ g.version = "1.2.3"
+ g.files = FileList["x"].resolve
+ end
+ pkg = Rake::GemPackageTask.new(gem) do |p|
+ p.package_files << "y"
+ end
+ assert_equal ["x", "y"], pkg.package_files
+ assert_equal "pkgr-1.2.3.gem", pkg.gem_file
+ end
+
+ def test_gem_package_with_current_platform
+ gem = Gem::Specification.new do |g|
+ g.name = "pkgr"
+ g.version = "1.2.3"
+ g.files = FileList["x"].resolve
+ g.platform = Gem::Platform::CURRENT
+ end
+ pkg = Rake::GemPackageTask.new(gem) do |p|
+ p.package_files << "y"
+ end
+ assert_equal ["x", "y"], pkg.package_files
+ assert_match(/^pkgr-1\.2\.3-(\S+)\.gem$/, pkg.gem_file)
+ end
+
+ def test_gem_package_with_ruby_platform
+ gem = Gem::Specification.new do |g|
+ g.name = "pkgr"
+ g.version = "1.2.3"
+ g.files = FileList["x"].resolve
+ g.platform = Gem::Platform::RUBY
+ end
+ pkg = Rake::GemPackageTask.new(gem) do |p|
+ p.package_files << "y"
+ end
+ assert_equal ["x", "y"], pkg.package_files
+ assert_equal "pkgr-1.2.3.gem", pkg.gem_file
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_pathmap.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_pathmap.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_pathmap.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,207 @@
+require 'test/unit'
+require 'rake'
+
+# ====================================================================
+class Rake::TestPathMap < Test::Unit::TestCase
+
+ def test_returns_self_with_no_args
+ assert_equal "abc.rb", "abc.rb".pathmap
+ end
+
+ def test_s_returns_file_separator
+ sep = File::ALT_SEPARATOR || File::SEPARATOR
+ assert_equal sep, "abc.rb".pathmap("%s")
+ assert_equal sep, "".pathmap("%s")
+ assert_equal "a#{sep}b", "a/b".pathmap("%d%s%f")
+ end
+
+ def test_f_returns_basename
+ assert_equal "abc.rb", "abc.rb".pathmap("%f")
+ assert_equal "abc.rb", "this/is/a/dir/abc.rb".pathmap("%f")
+ assert_equal "abc.rb", "/this/is/a/dir/abc.rb".pathmap("%f")
+ end
+
+ def test_n_returns_basename_without_extension
+ assert_equal "abc", "abc.rb".pathmap("%n")
+ assert_equal "abc", "abc".pathmap("%n")
+ assert_equal "abc", "this/is/a/dir/abc.rb".pathmap("%n")
+ assert_equal "abc", "/this/is/a/dir/abc.rb".pathmap("%n")
+ assert_equal "abc", "/this/is/a/dir/abc".pathmap("%n")
+ end
+
+ def test_d_returns_dirname
+ assert_equal ".", "abc.rb".pathmap("%d")
+ assert_equal "/", "/abc".pathmap("%d")
+ assert_equal "this/is/a/dir", "this/is/a/dir/abc.rb".pathmap("%d")
+ assert_equal "/this/is/a/dir", "/this/is/a/dir/abc.rb".pathmap("%d")
+ end
+
+ def test_9d_returns_partial_dirname
+ assert_equal "this/is", "this/is/a/dir/abc.rb".pathmap("%2d")
+ assert_equal "this", "this/is/a/dir/abc.rb".pathmap("%1d")
+ assert_equal ".", "this/is/a/dir/abc.rb".pathmap("%0d")
+ assert_equal "dir", "this/is/a/dir/abc.rb".pathmap("%-1d")
+ assert_equal "a/dir", "this/is/a/dir/abc.rb".pathmap("%-2d")
+ assert_equal "this/is/a/dir", "this/is/a/dir/abc.rb".pathmap("%100d")
+ assert_equal "this/is/a/dir", "this/is/a/dir/abc.rb".pathmap("%-100d")
+ end
+
+ def test_x_returns_extension
+ assert_equal "", "abc".pathmap("%x")
+ assert_equal ".rb", "abc.rb".pathmap("%x")
+ assert_equal ".rb", "abc.xyz.rb".pathmap("%x")
+ assert_equal "", ".depends".pathmap("%x")
+ assert_equal "", "dir/.depends".pathmap("%x")
+ end
+
+ def test_X_returns_everything_but_extension
+ assert_equal "abc", "abc".pathmap("%X")
+ assert_equal "abc", "abc.rb".pathmap("%X")
+ assert_equal "abc.xyz", "abc.xyz.rb".pathmap("%X")
+ assert_equal "ab.xyz", "ab.xyz.rb".pathmap("%X")
+ assert_equal "a.xyz", "a.xyz.rb".pathmap("%X")
+ assert_equal "abc", "abc.rb".pathmap("%X")
+ assert_equal "ab", "ab.rb".pathmap("%X")
+ assert_equal "a", "a.rb".pathmap("%X")
+ assert_equal ".depends", ".depends".pathmap("%X")
+ assert_equal "a/dir/.depends", "a/dir/.depends".pathmap("%X")
+ assert_equal "/.depends", "/.depends".pathmap("%X")
+ end
+
+ def test_p_returns_entire_pathname
+ assert_equal "abc.rb", "abc.rb".pathmap("%p")
+ assert_equal "this/is/a/dir/abc.rb", "this/is/a/dir/abc.rb".pathmap("%p")
+ assert_equal "/this/is/a/dir/abc.rb", "/this/is/a/dir/abc.rb".pathmap("%p")
+ end
+
+ def test_dash_returns_empty_string
+ assert_equal "", "abc.rb".pathmap("%-")
+ assert_equal "abc.rb", "abc.rb".pathmap("%X%-%x")
+ end
+
+ def test_percent_percent_returns_percent
+ assert_equal "a%b", "".pathmap("a%%b")
+ end
+
+ def test_undefined_percent_causes_error
+ ex = assert_raise(ArgumentError) {
+ "dir/abc.rb".pathmap("%z")
+ }
+ end
+
+ def test_pattern_returns_substitutions
+ assert_equal "bin/org/osb",
+ "src/org/osb/Xyz.java".pathmap("%{src,bin}d")
+ end
+
+ def test_pattern_can_use_backreferences
+ assert_equal "dir/hi/is", "dir/this/is".pathmap("%{t(hi)s,\\1}p")
+ end
+
+ def test_pattern_with_star_replacement_string_uses_block
+ assert_equal "src/ORG/osb",
+ "src/org/osb/Xyz.java".pathmap("%{/org,*}d") { |d| d.upcase }
+ assert_equal "Xyz.java",
+ "src/org/osb/Xyz.java".pathmap("%{.*,*}f") { |f| f.capitalize }
+ end
+
+ def test_pattern_with_no_replacement_nor_block_substitutes_empty_string
+ assert_equal "bc.rb", "abc.rb".pathmap("%{a}f")
+ end
+
+ def test_pattern_works_with_certain_valid_operators
+ assert_equal "dir/xbc.rb", "dir/abc.rb".pathmap("%{a,x}p")
+ assert_equal "d1r", "dir/abc.rb".pathmap("%{i,1}d")
+ assert_equal "xbc.rb", "dir/abc.rb".pathmap("%{a,x}f")
+ assert_equal ".Rb", "dir/abc.rb".pathmap("%{r,R}x")
+ assert_equal "xbc", "dir/abc.rb".pathmap("%{a,x}n")
+ end
+
+ def test_multiple_patterns
+ assert_equal "this/is/b/directory/abc.rb",
+ "this/is/a/dir/abc.rb".pathmap("%{a,b;dir,\\0ectory}p")
+ end
+
+ def test_partial_directory_selection_works_with_patterns
+ assert_equal "this/is/a/long",
+ "this/is/a/really/long/path/ok.rb".pathmap("%{/really/,/}5d")
+ end
+
+ def test_pattern_with_invalid_operator
+ ex = assert_raise(ArgumentError) do
+ "abc.xyz".pathmap("%{src,bin}z")
+ end
+ assert_match(/unknown.*pathmap.*spec.*z/i, ex.message)
+ end
+
+ def test_works_with_windows_separators
+ if File::ALT_SEPARATOR
+ assert_equal "abc", 'dir\abc.rb'.pathmap("%n")
+ assert_equal 'this\is\a\dir',
+ 'this\is\a\dir\abc.rb'.pathmap("%d")
+ end
+ end
+
+ def test_complex_patterns
+ sep = "".pathmap("%s")
+ assert_equal "dir/abc.rb", "dir/abc.rb".pathmap("%d/%n%x")
+ assert_equal "./abc.rb", "abc.rb".pathmap("%d/%n%x")
+ assert_equal "Your file extension is '.rb'",
+ "dir/abc.rb".pathmap("Your file extension is '%x'")
+ assert_equal "bin/org/onstepback/proj/A.class",
+ "src/org/onstepback/proj/A.java".pathmap("%{src,bin}d/%n.class")
+ assert_equal "src_work/bin/org/onstepback/proj/A.class",
+ "src_work/src/org/onstepback/proj/A.java".pathmap('%{\bsrc\b,bin}X.class')
+ assert_equal ".depends.bak", ".depends".pathmap("%X.bak")
+ assert_equal "d#{sep}a/b/c#{sep}file.txt", "a/b/c/d/file.txt".pathmap("%-1d%s%3d%s%f")
+ end
+end
+
+class Rake::TestPathMapExplode < Test::Unit::TestCase
+ def setup
+ String.class_eval { public :pathmap_explode }
+ end
+
+ def teardown
+ String.class_eval { protected :pathmap_explode }
+ end
+
+ def test_explode
+ assert_equal ['a'], 'a'.pathmap_explode
+ assert_equal ['a', 'b'], 'a/b'.pathmap_explode
+ assert_equal ['a', 'b', 'c'], 'a/b/c'.pathmap_explode
+ assert_equal ['/', 'a'], '/a'.pathmap_explode
+ assert_equal ['/', 'a', 'b'], '/a/b'.pathmap_explode
+ assert_equal ['/', 'a', 'b', 'c'], '/a/b/c'.pathmap_explode
+ if File::ALT_SEPARATOR
+ assert_equal ['c:.', 'a'], 'c:a'.pathmap_explode
+ assert_equal ['c:.', 'a', 'b'], 'c:a/b'.pathmap_explode
+ assert_equal ['c:.', 'a', 'b', 'c'], 'c:a/b/c'.pathmap_explode
+ assert_equal ['c:/', 'a'], 'c:/a'.pathmap_explode
+ assert_equal ['c:/', 'a', 'b'], 'c:/a/b'.pathmap_explode
+ assert_equal ['c:/', 'a', 'b', 'c'], 'c:/a/b/c'.pathmap_explode
+ end
+ end
+end
+
+class Rake::TestPathMapPartial < Test::Unit::TestCase
+ def test_pathmap_partial
+ @path = "1/2/file"
+ def @path.call(n)
+ pathmap_partial(n)
+ end
+ assert_equal("1", @path.call(1))
+ assert_equal("1/2", @path.call(2))
+ assert_equal("1/2", @path.call(3))
+ assert_equal(".", @path.call(0))
+ assert_equal("2", @path.call(-1))
+ assert_equal("1/2", @path.call(-2))
+ assert_equal("1/2", @path.call(-3))
+ end
+end
+
+class Rake::TestFileListPathMap < Test::Unit::TestCase
+ def test_file_list_supports_pathmap
+ assert_equal ['a', 'b'], FileList['dir/a.rb', 'dir/b.rb'].pathmap("%n")
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_pseudo_status.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_pseudo_status.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_pseudo_status.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,23 @@
+require 'test/unit'
+require 'rake'
+
+require_relative 'capture_stdout'
+
+class Rake::TestPseudoStatus < Test::Unit::TestCase
+ def test_with_zero_exit_status
+ s = Rake::PseudoStatus.new
+ assert_equal 0, s.exitstatus
+ assert_equal 0, s.to_i
+ assert_equal 0, s >> 8
+ assert ! s.stopped?
+ assert s.exited?
+ end
+ def test_with_99_exit_status
+ s = Rake::PseudoStatus.new(99)
+ assert_equal 99, s.exitstatus
+ assert_equal 25344, s.to_i
+ assert_equal 99, s >> 8
+ assert ! s.stopped?
+ assert s.exited?
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_rake.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_rake.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_rake.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,39 @@
+require 'test/unit'
+require 'rake'
+
+class Rake::TestRake < Test::Unit::TestCase
+ def test_each_dir_parent
+ assert_equal ['a'], alldirs('a')
+ assert_equal ['a/b', 'a'], alldirs('a/b')
+ assert_equal ['/a/b', '/a', '/'], alldirs('/a/b')
+ if File.dirname("c:/foo") == "c:"
+ # Under Unix
+ assert_equal ['c:/a/b', 'c:/a', 'c:'], alldirs('c:/a/b')
+ assert_equal ['c:a/b', 'c:a'], alldirs('c:a/b')
+ else
+ # Under Windows
+ assert_equal ['c:/a/b', 'c:/a', 'c:/'], alldirs('c:/a/b')
+ assert_equal ['c:a/b', 'c:a'], alldirs('c:a/b')
+ end
+ end
+
+ def alldirs(fn)
+ result = []
+ Rake.each_dir_parent(fn) { |d| result << d }
+ result
+ end
+
+ def test_can_override_application
+ old_app = Rake.application
+ fake_app = Object.new
+ Rake.application = fake_app
+ assert_equal fake_app, Rake.application
+ ensure
+ Rake.application = old_app
+ end
+
+ def test_original_dir_reports_current_dir
+ assert_equal Dir.pwd, Rake.original_dir
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_rdoc_task.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_rdoc_task.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_rdoc_task.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,84 @@
+require 'test/unit'
+require 'rake/rdoctask'
+
+class Rake::TestRDocTask < Test::Unit::TestCase
+ include Rake
+
+ def setup
+ Task.clear
+ end
+
+ def test_tasks_creation
+ Rake::RDocTask.new
+ assert Task[:rdoc]
+ assert Task[:clobber_rdoc]
+ assert Task[:rerdoc]
+ end
+
+ def test_tasks_creation_with_custom_name_symbol
+ rd = Rake::RDocTask.new(:rdoc_dev)
+ assert Task[:rdoc_dev]
+ assert Task[:clobber_rdoc_dev]
+ assert Task[:rerdoc_dev]
+ assert_equal :rdoc_dev, rd.name
+ end
+
+ def test_tasks_creation_with_custom_name_string
+ rd = Rake::RDocTask.new("rdoc_dev")
+ assert Task[:rdoc_dev]
+ assert Task[:clobber_rdoc_dev]
+ assert Task[:rerdoc_dev]
+ assert_equal "rdoc_dev", rd.name
+ end
+
+ def test_tasks_creation_with_custom_name_hash
+ options = { :rdoc => "rdoc", :clobber_rdoc => "rdoc:clean", :rerdoc => "rdoc:force" }
+ rd = Rake::RDocTask.new(options)
+ assert Task[:"rdoc"]
+ assert Task[:"rdoc:clean"]
+ assert Task[:"rdoc:force"]
+ assert_raises(RuntimeError) { Task[:clobber_rdoc] }
+ assert_equal options, rd.name
+ end
+
+ def test_tasks_creation_with_custom_name_hash_will_use_default_if_an_option_isnt_given
+ rd = Rake::RDocTask.new(:clobber_rdoc => "rdoc:clean")
+ assert Task[:rdoc]
+ assert Task[:"rdoc:clean"]
+ assert Task[:rerdoc]
+ end
+
+ def test_tasks_creation_with_custom_name_hash_raises_exception_if_invalid_option_given
+ assert_raises(ArgumentError) do
+ Rake::RDocTask.new(:foo => "bar")
+ end
+
+ begin
+ Rake::RDocTask.new(:foo => "bar")
+ rescue ArgumentError => e
+ assert_match(/foo/, e.message)
+ end
+ end
+
+ def test_inline_source_is_enabled_by_default
+ rd = Rake::RDocTask.new
+ assert rd.option_list.include?('--inline-source')
+ end
+
+ def test_inline_source_option_is_only_appended_if_option_not_already_given
+ rd = Rake::RDocTask.new
+ rd.options << '--inline-source'
+ assert_equal 1, rd.option_list.grep('--inline-source').size
+
+ rd = Rake::RDocTask.new
+ rd.options << '-S'
+ assert_equal 1, rd.option_list.grep('-S').size
+ assert_equal 0, rd.option_list.grep('--inline-source').size
+ end
+
+ def test_inline_source_option_can_be_disabled
+ rd = Rake::RDocTask.new
+ rd.inline_source = false
+ assert !rd.option_list.include?('--inline-source')
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_require.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_require.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_require.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,32 @@
+require 'test/unit'
+require 'rake'
+
+# ====================================================================
+class Rake::TestRequire < Test::Unit::TestCase
+ RakeLibDir = File.dirname(__FILE__) + '/data/rakelib'
+
+ def test_can_load_rake_library
+ app = Rake::Application.new
+ assert app.instance_eval {
+ rake_require("test1", [RakeLibDir], [])
+ }
+ end
+
+ def test_wont_reload_rake_library
+ app = Rake::Application.new
+ assert ! app.instance_eval {
+ rake_require("test2", [RakeLibDir], ['test2'])
+ }
+ end
+
+ def test_throws_error_if_library_not_found
+ app = Rake::Application.new
+ ex = assert_raise(LoadError) {
+ assert app.instance_eval {
+ rake_require("testx", [RakeLibDir], [])
+ }
+ }
+ assert_match(/x/, ex.message)
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/rake/test_rules.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_rules.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_rules.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,352 @@
+require 'test/unit'
+require 'tmpdir'
+require 'fileutils'
+require 'rake'
+require_relative 'filecreation'
+
+######################################################################
+class Rake::TestRules < Test::Unit::TestCase
+ include Rake
+ include FileCreation
+
+ SRCFILE = "testdata/abc.c"
+ SRCFILE2 = "testdata/xyz.c"
+ FTNFILE = "testdata/abc.f"
+ OBJFILE = "testdata/abc.o"
+ FOOFILE = "testdata/foo"
+ DOTFOOFILE = "testdata/.foo"
+
+ def setup
+ @oldpwd = Dir.pwd
+ @tmpdir = Dir.mktmpdir("rake")
+ Dir.chdir(@tmpdir)
+ Dir.mkdir("testdata")
+ Task.clear
+ @runs = []
+ end
+
+ def teardown
+ FileList['testdata/{*,.[^.]*,}'].uniq.each do |f| rm_r(f, :verbose=>false) end
+ Dir.chdir(@oldpwd)
+ Dir.rmdir(@tmpdir)
+ end
+
+ def test_multiple_rules1
+ create_file(FTNFILE)
+ delete_file(SRCFILE)
+ delete_file(OBJFILE)
+ rule(/\.o$/ => ['.c']) do @runs << :C end
+ rule(/\.o$/ => ['.f']) do @runs << :F end
+ t = Task[OBJFILE]
+ t.invoke
+ Task[OBJFILE].invoke
+ assert_equal [:F], @runs
+ end
+
+ def test_multiple_rules2
+ create_file(FTNFILE)
+ delete_file(SRCFILE)
+ delete_file(OBJFILE)
+ rule(/\.o$/ => ['.f']) do @runs << :F end
+ rule(/\.o$/ => ['.c']) do @runs << :C end
+ Task[OBJFILE].invoke
+ assert_equal [:F], @runs
+ end
+
+ def test_create_with_source
+ create_file(SRCFILE)
+ rule(/\.o$/ => ['.c']) do |t|
+ @runs << t.name
+ assert_equal OBJFILE, t.name
+ assert_equal SRCFILE, t.source
+ end
+ Task[OBJFILE].invoke
+ assert_equal [OBJFILE], @runs
+ end
+
+ def test_single_dependent
+ create_file(SRCFILE)
+ rule(/\.o$/ => '.c') do |t|
+ @runs << t.name
+ end
+ Task[OBJFILE].invoke
+ assert_equal [OBJFILE], @runs
+ end
+
+ def test_rule_can_be_created_by_string
+ create_file(SRCFILE)
+ rule '.o' => ['.c'] do |t|
+ @runs << t.name
+ end
+ Task[OBJFILE].invoke
+ assert_equal [OBJFILE], @runs
+ end
+
+ def test_rule_prereqs_can_be_created_by_string
+ create_file(SRCFILE)
+ rule '.o' => '.c' do |t|
+ @runs << t.name
+ end
+ Task[OBJFILE].invoke
+ assert_equal [OBJFILE], @runs
+ end
+
+ def test_plain_strings_as_dependents_refer_to_files
+ create_file(SRCFILE)
+ rule '.o' => SRCFILE do |t|
+ @runs << t.name
+ end
+ Task[OBJFILE].invoke
+ assert_equal [OBJFILE], @runs
+ end
+
+ def test_file_names_beginning_with_dot_can_be_tricked_into_refering_to_file
+ verbose(false) do
+ chdir("testdata") do
+ create_file('.foo')
+ rule '.o' => "./.foo" do |t|
+ @runs << t.name
+ end
+ Task[OBJFILE].invoke
+ assert_equal [OBJFILE], @runs
+ end
+ end
+ end
+
+ def test_file_names_beginning_with_dot_can_be_wrapped_in_lambda
+ verbose(false) do
+ chdir("testdata") do
+ create_file(".foo")
+ rule '.o' => lambda{".foo"} do |t|
+ @runs << "#{t.name} - #{t.source}"
+ end
+ Task[OBJFILE].invoke
+ assert_equal ["#{OBJFILE} - .foo"], @runs
+ end
+ end
+ end
+
+ def test_file_names_containing_percent_can_be_wrapped_in_lambda
+ verbose(false) do
+ chdir("testdata") do
+ create_file("foo%x")
+ rule '.o' => lambda{"foo%x"} do |t|
+ @runs << "#{t.name} - #{t.source}"
+ end
+ Task[OBJFILE].invoke
+ assert_equal ["#{OBJFILE} - foo%x"], @runs
+ end
+ end
+ end
+
+ def test_non_extension_rule_name_refers_to_file
+ verbose(false) do
+ chdir("testdata") do
+ create_file("abc.c")
+ rule "abc" => '.c' do |t|
+ @runs << t.name
+ end
+ Task["abc"].invoke
+ assert_equal ["abc"], @runs
+ end
+ end
+ end
+
+ def test_pathmap_automatically_applies_to_name
+ verbose(false) do
+ chdir("testdata") do
+ create_file("zzabc.c")
+ rule ".o" => 'zz%{x,a}n.c' do |t|
+ @runs << "#{t.name} - #{t.source}"
+ end
+ Task["xbc.o"].invoke
+ assert_equal ["xbc.o - zzabc.c"], @runs
+ end
+ end
+ end
+
+ def test_plain_strings_are_just_filenames
+ verbose(false) do
+ chdir("testdata") do
+ create_file("plainname")
+ rule ".o" => 'plainname' do |t|
+ @runs << "#{t.name} - #{t.source}"
+ end
+ Task["xbc.o"].invoke
+ assert_equal ["xbc.o - plainname"], @runs
+ end
+ end
+ end
+
+ def test_rule_runs_when_explicit_task_has_no_actions
+ create_file(SRCFILE)
+ create_file(SRCFILE2)
+ delete_file(OBJFILE)
+ rule '.o' => '.c' do |t|
+ @runs << t.source
+ end
+ file OBJFILE => [SRCFILE2]
+ Task[OBJFILE].invoke
+ assert_equal [SRCFILE], @runs
+ end
+
+ def test_close_matches_on_name_do_not_trigger_rule
+ create_file("testdata/x.c")
+ rule '.o' => ['.c'] do |t|
+ @runs << t.name
+ end
+ assert_raise(RuntimeError) { Task['testdata/x.obj'].invoke }
+ assert_raise(RuntimeError) { Task['testdata/x.xyo'].invoke }
+ end
+
+ def test_rule_rebuilds_obj_when_source_is_newer
+ create_timed_files(OBJFILE, SRCFILE)
+ rule(/\.o$/ => ['.c']) do
+ @runs << :RULE
+ end
+ Task[OBJFILE].invoke
+ assert_equal [:RULE], @runs
+ end
+
+ def test_rule_with_two_sources_runs_if_both_sources_are_present
+ create_timed_files(OBJFILE, SRCFILE, SRCFILE2)
+ rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
+ @runs << :RULE
+ end
+ Task[OBJFILE].invoke
+ assert_equal [:RULE], @runs
+ end
+
+ def test_rule_with_two_sources_but_one_missing_does_not_run
+ create_timed_files(OBJFILE, SRCFILE)
+ delete_file(SRCFILE2)
+ rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
+ @runs << :RULE
+ end
+ Task[OBJFILE].invoke
+ assert_equal [], @runs
+ end
+
+ def test_rule_with_two_sources_builds_both_sources
+ task 'x.aa'
+ task 'x.bb'
+ rule '.a' => '.aa' do
+ @runs << "A"
+ end
+ rule '.b' => '.bb' do
+ @runs << "B"
+ end
+ rule ".c" => ['.a', '.b'] do
+ @runs << "C"
+ end
+ Task["x.c"].invoke
+ assert_equal ["A", "B", "C"], @runs.sort
+ end
+
+ def test_second_rule_runs_when_first_rule_doesnt
+ create_timed_files(OBJFILE, SRCFILE)
+ delete_file(SRCFILE2)
+ rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
+ @runs << :RULE1
+ end
+ rule OBJFILE => [lambda{SRCFILE}] do
+ @runs << :RULE2
+ end
+ Task[OBJFILE].invoke
+ assert_equal [:RULE2], @runs
+ end
+
+ def test_second_rule_doest_run_if_first_triggers
+ create_timed_files(OBJFILE, SRCFILE, SRCFILE2)
+ rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
+ @runs << :RULE1
+ end
+ rule OBJFILE => [lambda{SRCFILE}] do
+ @runs << :RULE2
+ end
+ Task[OBJFILE].invoke
+ assert_equal [:RULE1], @runs
+ end
+
+ def test_second_rule_doest_run_if_first_triggers_with_reversed_rules
+ create_timed_files(OBJFILE, SRCFILE, SRCFILE2)
+ rule OBJFILE => [lambda{SRCFILE}] do
+ @runs << :RULE1
+ end
+ rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
+ @runs << :RULE2
+ end
+ Task[OBJFILE].invoke
+ assert_equal [:RULE1], @runs
+ end
+
+ def test_rule_with_proc_dependent_will_trigger
+ ran = false
+ mkdir_p("testdata/src/jw")
+ create_file("testdata/src/jw/X.java")
+ rule %r(classes/.*\.class) => [
+ proc { |fn| fn.pathmap("%{classes,testdata/src}d/%n.java") }
+ ] do |task|
+ assert_equal task.name, 'classes/jw/X.class'
+ assert_equal task.source, 'testdata/src/jw/X.java'
+ @runs << :RULE
+ end
+ Task['classes/jw/X.class'].invoke
+ assert_equal [:RULE], @runs
+ ensure
+ rm_r("testdata/src", :verbose=>false) rescue nil
+ end
+
+ def test_proc_returning_lists_are_flattened_into_prereqs
+ ran = false
+ mkdir_p("testdata/flatten")
+ create_file("testdata/flatten/a.txt")
+ task 'testdata/flatten/b.data' do |t|
+ ran = true
+ touch t.name, :verbose => false
+ end
+ rule '.html' =>
+ proc { |fn|
+ [
+ fn.ext("txt"),
+ "testdata/flatten/b.data"
+ ]
+ } do |task|
+ end
+ Task['testdata/flatten/a.html'].invoke
+ assert ran, "Should have triggered flattened dependency"
+ ensure
+ rm_r("testdata/flatten", :verbose=>false) rescue nil
+ end
+
+ def test_recursive_rules_will_work_as_long_as_they_terminate
+ actions = []
+ create_file("testdata/abc.xml")
+ rule '.y' => '.xml' do actions << 'y' end
+ rule '.c' => '.y' do actions << 'c'end
+ rule '.o' => '.c' do actions << 'o'end
+ rule '.exe' => '.o' do actions << 'exe'end
+ Task["testdata/abc.exe"].invoke
+ assert_equal ['y', 'c', 'o', 'exe'], actions
+ end
+
+ def test_recursive_rules_that_dont_terminate_will_overflow
+ create_file("testdata/a.a")
+ prev = 'a'
+ ('b'..'z').each do |letter|
+ rule ".#{letter}" => ".#{prev}" do |t| puts "#{t.name}" end
+ prev = letter
+ end
+ ex = assert_raise(Rake::RuleRecursionOverflowError) {
+ Task["testdata/a.z"].invoke
+ }
+ assert_match(/a\.z => testdata\/a.y/, ex.message)
+ end
+
+ def test_rules_with_bad_dependents_will_fail
+ rule "a" => [ 1 ] do |t| puts t.name end
+ assert_raise(RuntimeError) do Task['a'].invoke end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rake/test_task_arguments.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_task_arguments.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_task_arguments.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,92 @@
+require 'test/unit'
+require 'rake'
+
+######################################################################
+class Rake::TestTaskArguments < Test::Unit::TestCase
+ def setup
+ @backup = ENV.to_hash
+ ENV.clear
+ end
+
+ def teardown
+ ENV.clear
+ @backup.each {|k, v| ENV[k] = v }
+ end
+
+ def test_empty_arg_list_is_empty
+ ta = Rake::TaskArguments.new([], [])
+ assert_equal({}, ta.to_hash)
+ end
+
+ def test_multiple_values_in_args
+ ta = Rake::TaskArguments.new([:a, :b, :c], [:one, :two, :three])
+ assert_equal({:a => :one, :b => :two, :c => :three}, ta.to_hash)
+ end
+
+ def test_to_s
+ ta = Rake::TaskArguments.new([:a, :b, :c], [1, 2, 3])
+ assert_equal ta.to_hash.inspect, ta.to_s
+ assert_equal ta.to_hash.inspect, ta.inspect
+ end
+
+ def test_enumerable_behavior
+ ta = Rake::TaskArguments.new([:a, :b, :c], [1, 2 ,3])
+ assert_equal [10, 20, 30], ta.collect { |k,v| v * 10 }.sort
+ end
+
+ def test_named_args
+ ta = Rake::TaskArguments.new(["aa", "bb"], [1, 2])
+ assert_equal 1, ta.aa
+ assert_equal 1, ta[:aa]
+ assert_equal 1, ta["aa"]
+ assert_equal 2, ta.bb
+ assert_nil ta.cc
+ end
+
+ def test_args_knows_its_names
+ ta = Rake::TaskArguments.new(["aa", "bb"], [1, 2])
+ assert_equal ["aa", "bb"], ta.names
+ end
+
+ def test_extra_names_are_nil
+ ta = Rake::TaskArguments.new(["aa", "bb", "cc"], [1, 2])
+ assert_nil ta.cc
+ end
+
+ def test_args_can_reference_env_values
+ ta = Rake::TaskArguments.new(["aa"], [1])
+ ENV['rev'] = "1.2"
+ ENV['VER'] = "2.3"
+ assert_equal "1.2", ta.rev
+ assert_equal "2.3", ta.ver
+ end
+
+ def test_creating_new_argument_scopes
+ parent = Rake::TaskArguments.new(['p'], [1])
+ child = parent.new_scope(['c', 'p'])
+ assert_equal({:p=>1}, child.to_hash)
+ assert_equal 1, child.p
+ assert_equal 1, child["p"]
+ assert_equal 1, child[:p]
+ assert_nil child.c
+ end
+
+ def test_child_hides_parent_arg_names
+ parent = Rake::TaskArguments.new(['aa'], [1])
+ child = Rake::TaskArguments.new(['aa'], [2], parent)
+ assert_equal 2, child.aa
+ end
+
+ def test_default_arguments_values_can_be_merged
+ ta = Rake::TaskArguments.new(["aa", "bb"], [nil, "original_val"])
+ ta.with_defaults({ :aa => 'default_val' })
+ assert_equal 'default_val', ta[:aa]
+ assert_equal 'original_val', ta[:bb]
+ end
+
+ def test_default_arguements_that_dont_match_names_are_ignored
+ ta = Rake::TaskArguments.new(["aa", "bb"], [nil, "original_val"])
+ ta.with_defaults({ "cc" => "default_val" })
+ assert_nil ta[:cc]
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_task_manager.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_task_manager.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_task_manager.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,181 @@
+require 'test/unit'
+require 'fileutils'
+require 'tmpdir'
+require 'rake'
+
+class Rake::TestTaskManager < Test::Unit::TestCase
+ class TaskManager
+ include Rake::TaskManager
+ end
+
+ def setup
+ @oldpwd = Dir.pwd
+ @tmpdir = Dir.mktmpdir("rake")
+ Dir.chdir(@tmpdir)
+ @tm = TaskManager.new
+ open("README", "wb") {}
+ end
+
+ def teardown
+ Dir.chdir(@oldpwd)
+ FileUtils.rm_rf(@tmpdir)
+ end
+
+ def test_create_task_manager
+ assert_not_nil @tm
+ assert_equal [], @tm.tasks
+ end
+
+ def test_define_task
+ t = @tm.define_task(Rake::Task, :t)
+ assert_equal "t", t.name
+ assert_equal @tm, t.application
+ end
+
+ def test_name_lookup
+ t = @tm.define_task(Rake::Task, :t)
+ assert_equal t, @tm[:t]
+ end
+
+ def test_namespace_task_create
+ @tm.in_namespace("x") do
+ t = @tm.define_task(Rake::Task, :t)
+ assert_equal "x:t", t.name
+ end
+ assert_equal ["x:t"], @tm.tasks.collect { |t| t.name }
+ end
+
+ def test_anonymous_namespace
+ anon_ns = @tm.in_namespace(nil) do
+ t = @tm.define_task(Rake::Task, :t)
+ assert_equal "_anon_1:t", t.name
+ end
+ task = anon_ns[:t]
+ assert_equal "_anon_1:t", task.name
+ end
+
+ def test_create_filetask_in_namespace
+ @tm.in_namespace("x") do
+ t = @tm.define_task(Rake::FileTask, "fn")
+ assert_equal "fn", t.name
+ end
+ assert_equal ["fn"], @tm.tasks.collect { |t| t.name }
+ end
+
+ def test_namespace_yields_same_namespace_as_returned
+ yielded_namespace = nil
+ returned_namespace = @tm.in_namespace("x") do |ns|
+ yielded_namespace = ns
+ end
+ assert_equal returned_namespace, yielded_namespace
+ end
+
+ def test_name_lookup_with_implicit_file_tasks
+ t = @tm["README"]
+ assert_equal "README", t.name
+ assert Rake::FileTask === t
+ end
+
+ def test_name_lookup_with_nonexistent_task
+ assert_raise(RuntimeError) {
+ t = @tm["DOES NOT EXIST"]
+ }
+ end
+
+ def test_name_lookup_in_multiple_scopes
+ aa = nil
+ bb = nil
+ xx = @tm.define_task(Rake::Task, :xx)
+ top_z = @tm.define_task(Rake::Task, :z)
+ @tm.in_namespace("a") do
+ aa = @tm.define_task(Rake::Task, :aa)
+ mid_z = @tm.define_task(Rake::Task, :z)
+ @tm.in_namespace("b") do
+ bb = @tm.define_task(Rake::Task, :bb)
+ bot_z = @tm.define_task(Rake::Task, :z)
+
+ assert_equal ["a", "b"], @tm.current_scope
+
+ assert_equal bb, @tm["a:b:bb"]
+ assert_equal aa, @tm["a:aa"]
+ assert_equal xx, @tm["xx"]
+ assert_equal bot_z, @tm["z"]
+ assert_equal mid_z, @tm["^z"]
+ assert_equal top_z, @tm["^^z"]
+ assert_equal top_z, @tm["rake:z"]
+ end
+
+ assert_equal ["a"], @tm.current_scope
+
+ assert_equal bb, @tm["a:b:bb"]
+ assert_equal aa, @tm["a:aa"]
+ assert_equal xx, @tm["xx"]
+ assert_equal bb, @tm["b:bb"]
+ assert_equal aa, @tm["aa"]
+ assert_equal mid_z, @tm["z"]
+ assert_equal top_z, @tm["^z"]
+ assert_equal top_z, @tm["rake:z"]
+ end
+
+ assert_equal [], @tm.current_scope
+
+ assert_equal [], xx.scope
+ assert_equal ['a'], aa.scope
+ assert_equal ['a', 'b'], bb.scope
+ end
+
+ def test_lookup_with_explicit_scopes
+ t1, t2, t3, s = (0...4).collect { nil }
+ t1 = @tm.define_task(Rake::Task, :t)
+ @tm.in_namespace("a") do
+ t2 = @tm.define_task(Rake::Task, :t)
+ s = @tm.define_task(Rake::Task, :s)
+ @tm.in_namespace("b") do
+ t3 = @tm.define_task(Rake::Task, :t)
+ end
+ end
+ assert_equal t1, @tm[:t, []]
+ assert_equal t2, @tm[:t, ["a"]]
+ assert_equal t3, @tm[:t, ["a", "b"]]
+ assert_equal s, @tm[:s, ["a", "b"]]
+ assert_equal s, @tm[:s, ["a"]]
+ end
+
+ def test_correctly_scoped_prerequisites_are_invoked
+ values = []
+ @tm = Rake::Application.new
+ @tm.define_task(Rake::Task, :z) do values << "top z" end
+ @tm.in_namespace("a") do
+ @tm.define_task(Rake::Task, :z) do values << "next z" end
+ @tm.define_task(Rake::Task, :x => :z)
+ end
+
+ @tm["a:x"].invoke
+ assert_equal ["next z"], values
+ end
+
+end
+
+class Rake::TestTaskManagerArgumentResolution < Test::Unit::TestCase
+ TaskManager = Rake::TestTaskManager::TaskManager
+
+ def test_good_arg_patterns
+ assert_equal [:t, [], []], task(:t)
+ assert_equal [:t, [], [:x]], task(:t => :x)
+ assert_equal [:t, [], [:x, :y]], task(:t => [:x, :y])
+
+ assert_equal [:t, [:a, :b], []], task(:t, :a, :b)
+ assert_equal [:t, [], [:x]], task(:t, :needs => :x)
+ assert_equal [:t, [:a, :b], [:x]], task(:t, :a, :b, :needs => :x)
+ assert_equal [:t, [:a, :b], [:x, :y]], task(:t, :a, :b, :needs => [:x, :y])
+
+ assert_equal [:t, [:a, :b], []], task(:t, [:a, :b])
+ assert_equal [:t, [:a, :b], [:x]], task(:t, [:a, :b] => :x)
+ assert_equal [:t, [:a, :b], [:x, :y]], task(:t, [:a, :b] => [:x, :y])
+ end
+
+ def task(*args)
+ tm = TaskManager.new
+ tm.resolve_args(args)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_tasklib.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_tasklib.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_tasklib.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,10 @@
+require 'test/unit'
+require 'rake/tasklib'
+
+
+class Rake::TestTaskLib < Test::Unit::TestCase
+ def test_paste
+ tl = Rake::TaskLib.new
+ assert_equal :ab, tl.paste(:a, :b)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_tasks.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_tasks.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_tasks.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,369 @@
+require 'test/unit'
+require 'fileutils'
+require 'rake'
+require_relative 'filecreation'
+require_relative 'capture_stdout'
+
+######################################################################
+class Rake::TestTasks < Test::Unit::TestCase
+ include CaptureStdout
+ include Rake
+
+ def setup
+ Task.clear
+ end
+
+ def test_create
+ arg = nil
+ t = task(:name) { |task| arg = task; 1234 }
+ assert_equal "name", t.name
+ assert_equal [], t.prerequisites
+ assert t.needed?
+ t.execute(0)
+ assert_equal t, arg
+ assert_nil t.source
+ assert_equal [], t.sources
+ end
+
+ def test_inspect
+ t = task(:foo, :needs => [:bar, :baz])
+ assert_equal "<Rake::Task foo => [bar, baz]>", t.inspect
+ end
+
+ def test_invoke
+ runlist = []
+ t1 = task(:t1 => [:t2, :t3]) { |t| runlist << t.name; 3321 }
+ t2 = task(:t2) { |t| runlist << t.name }
+ t3 = task(:t3) { |t| runlist << t.name }
+ assert_equal ["t2", "t3"], t1.prerequisites
+ t1.invoke
+ assert_equal ["t2", "t3", "t1"], runlist
+ end
+
+ def test_invoke_with_circular_dependencies
+ runlist = []
+ t1 = task(:t1 => [:t2]) { |t| runlist << t.name; 3321 }
+ t2 = task(:t2 => [:t1]) { |t| runlist << t.name }
+ assert_equal ["t2"], t1.prerequisites
+ assert_equal ["t1"], t2.prerequisites
+ ex = assert_raise RuntimeError do
+ t1.invoke
+ end
+ assert_match(/circular dependency/i, ex.message)
+ assert_match(/t1 => t2 => t1/, ex.message)
+ end
+
+ def test_dry_run_prevents_actions
+ Rake.application.options.dryrun = true
+ runlist = []
+ t1 = task(:t1) { |t| runlist << t.name; 3321 }
+ out = capture_stdout { t1.invoke }
+ assert_match(/execute .*t1/i, out)
+ assert_match(/dry run/i, out)
+ assert_no_match(/invoke/i, out)
+ assert_equal [], runlist
+ ensure
+ Rake.application.options.dryrun = false
+ end
+
+ def test_tasks_can_be_traced
+ Rake.application.options.trace = true
+ t1 = task(:t1)
+ out = capture_stdout {
+ t1.invoke
+ }
+ assert_match(/invoke t1/i, out)
+ assert_match(/execute t1/i, out)
+ ensure
+ Rake.application.options.trace = false
+ end
+
+ def test_no_double_invoke
+ runlist = []
+ t1 = task(:t1 => [:t2, :t3]) { |t| runlist << t.name; 3321 }
+ t2 = task(:t2 => [:t3]) { |t| runlist << t.name }
+ t3 = task(:t3) { |t| runlist << t.name }
+ t1.invoke
+ assert_equal ["t3", "t2", "t1"], runlist
+ end
+
+ def test_can_double_invoke_with_reenable
+ runlist = []
+ t1 = task(:t1) { |t| runlist << t.name }
+ t1.invoke
+ t1.reenable
+ t1.invoke
+ assert_equal ["t1", "t1"], runlist
+ end
+
+ def test_clear
+ t = task("t" => "a") { }
+ t.clear
+ assert t.prerequisites.empty?, "prerequisites should be empty"
+ assert t.actions.empty?, "actions should be empty"
+ end
+
+ def test_clear_prerequisites
+ t = task("t" => ["a", "b"])
+ assert_equal ['a', 'b'], t.prerequisites
+ t.clear_prerequisites
+ assert_equal [], t.prerequisites
+ end
+
+ def test_clear_actions
+ t = task("t") { }
+ t.clear_actions
+ assert t.actions.empty?, "actions should be empty"
+ end
+
+ def test_find
+ task :tfind
+ assert_equal "tfind", Task[:tfind].name
+ ex = assert_raise(RuntimeError) { Task[:leaves] }
+ assert_equal "Don't know how to build task 'leaves'", ex.message
+ end
+
+ def test_defined
+ assert ! Task.task_defined?(:a)
+ task :a
+ assert Task.task_defined?(:a)
+ end
+
+ def test_multi_invocations
+ runs = []
+ p = proc do |t| runs << t.name end
+ task({:t1=>[:t2,:t3]}, &p)
+ task({:t2=>[:t3]}, &p)
+ task(:t3, &p)
+ Task[:t1].invoke
+ assert_equal ["t1", "t2", "t3"], runs.sort
+ end
+
+ def test_task_list
+ task :t2
+ task :t1 => [:t2]
+ assert_equal ["t1", "t2"], Task.tasks.collect {|t| t.name}
+ end
+
+ def test_task_gives_name_on_to_s
+ task :abc
+ assert_equal "abc", Task[:abc].to_s
+ end
+
+ def test_symbols_can_be_prerequisites
+ task :a => :b
+ assert_equal ["b"], Task[:a].prerequisites
+ end
+
+ def test_strings_can_be_prerequisites
+ task :a => "b"
+ assert_equal ["b"], Task[:a].prerequisites
+ end
+
+ def test_arrays_can_be_prerequisites
+ task :a => ["b", "c"]
+ assert_equal ["b", "c"], Task[:a].prerequisites
+ end
+
+ def test_filelists_can_be_prerequisites
+ task :a => FileList.new.include("b", "c")
+ assert_equal ["b", "c"], Task[:a].prerequisites
+ end
+
+ def test_investigation_output
+ t1 = task(:t1 => [:t2, :t3]) { |t| runlist << t.name; 3321 }
+ task(:t2)
+ task(:t3)
+ out = t1.investigation
+ assert_match(/class:\s*Rake::Task/, out)
+ assert_match(/needed:\s*true/, out)
+ assert_match(/pre-requisites:\s*--t[23]/, out)
+ end
+
+
+ def test_extended_comments
+ desc %{
+ This is a comment.
+
+ And this is the extended comment.
+ name -- Name of task to execute.
+ rev -- Software revision to use.
+ }
+ t = task(:t, :name, :rev)
+ assert_equal "[name,rev]", t.arg_description
+ assert_equal "This is a comment.", t.comment
+ assert_match(/^\s*name -- Name/, t.full_comment)
+ assert_match(/^\s*rev -- Software/, t.full_comment)
+ assert_match(/\A\s*This is a comment\.$/, t.full_comment)
+ end
+
+ def test_multiple_comments
+ desc "line one"
+ t = task(:t)
+ desc "line two"
+ task(:t)
+ assert_equal "line one / line two", t.comment
+ end
+
+ def test_settable_comments
+ t = task(:t)
+ t.comment = "HI"
+ assert_equal "HI", t.comment
+ end
+end
+
+######################################################################
+class Rake::TestTaskWithArguments < Test::Unit::TestCase
+ include CaptureStdout
+ include Rake
+
+ def setup
+ Task.clear
+ end
+
+ def test_no_args_given
+ t = task :t
+ assert_equal [], t.arg_names
+ end
+
+ def test_args_given
+ t = task :t, :a, :b
+ assert_equal [:a, :b], t.arg_names
+ end
+
+ def test_name_and_needs
+ t = task(:t => [:pre])
+ assert_equal "t", t.name
+ assert_equal [], t.arg_names
+ assert_equal ["pre"], t.prerequisites
+ end
+
+ def test_name_and_explicit_needs
+ t = task(:t, :needs => [:pre])
+ assert_equal "t", t.name
+ assert_equal [], t.arg_names
+ assert_equal ["pre"], t.prerequisites
+ end
+
+ def test_name_args_and_explicit_needs
+ t = task(:t, :x, :y, :needs => [:pre])
+ assert_equal "t", t.name
+ assert_equal [:x, :y], t.arg_names
+ assert_equal ["pre"], t.prerequisites
+ end
+
+ def test_illegal_keys_in_task_name_hash
+ assert_raise RuntimeError do
+ t = task(:t, :x, :y => 1, :needs => [:pre])
+ end
+ end
+
+ def test_arg_list_is_empty_if_no_args_given
+ t = task(:t) { |tt, args| assert_equal({}, args.to_hash) }
+ t.invoke(1, 2, 3)
+ end
+
+ def test_tasks_can_access_arguments_as_hash
+ t = task :t, :a, :b, :c do |tt, args|
+ assert_equal({:a => 1, :b => 2, :c => 3}, args.to_hash)
+ assert_equal 1, args[:a]
+ assert_equal 2, args[:b]
+ assert_equal 3, args[:c]
+ assert_equal 1, args.a
+ assert_equal 2, args.b
+ assert_equal 3, args.c
+ end
+ t.invoke(1, 2, 3)
+ end
+
+ def test_actions_of_various_arity_are_ok_with_args
+ notes = []
+ t = task(:t, :x) do
+ notes << :a
+ end
+ t.enhance do | |
+ notes << :b
+ end
+ t.enhance do |task|
+ notes << :c
+ assert_kind_of Task, task
+ end
+ t.enhance do |t2, args|
+ notes << :d
+ assert_equal t, t2
+ assert_equal({:x => 1}, args.to_hash)
+ end
+ assert_nothing_raised do t.invoke(1) end
+ assert_equal [:a, :b, :c, :d], notes
+ end
+
+ def test_arguments_are_passed_to_block
+ t = task(:t, :a, :b) { |tt, args|
+ assert_equal( { :a => 1, :b => 2 }, args.to_hash )
+ }
+ t.invoke(1, 2)
+ end
+
+ def test_extra_parameters_are_ignored
+ t = task(:t, :a) { |tt, args|
+ assert_equal 1, args.a
+ assert_nil args.b
+ }
+ t.invoke(1, 2)
+ end
+
+ def test_arguments_are_passed_to_all_blocks
+ counter = 0
+ t = task :t, :a
+ task :t do |tt, args|
+ assert_equal 1, args.a
+ counter += 1
+ end
+ task :t do |tt, args|
+ assert_equal 1, args.a
+ counter += 1
+ end
+ t.invoke(1)
+ assert_equal 2, counter
+ end
+
+ def test_block_with_no_parameters_is_ok
+ t = task(:t) { }
+ t.invoke(1, 2)
+ end
+
+ def test_name_with_args
+ desc "T"
+ t = task(:tt, :a, :b)
+ assert_equal "tt", t.name
+ assert_equal "T", t.comment
+ assert_equal "[a,b]", t.arg_description
+ assert_equal "tt[a,b]", t.name_with_args
+ assert_equal [:a, :b],t.arg_names
+ end
+
+ def test_named_args_are_passed_to_prereqs
+ value = nil
+ pre = task(:pre, :rev) { |t, args| value = args.rev }
+ t = task(:t, :name, :rev, :needs => [:pre])
+ t.invoke("bill", "1.2")
+ assert_equal "1.2", value
+ end
+
+ def test_args_not_passed_if_no_prereq_names
+ pre = task(:pre) { |t, args|
+ assert_equal({}, args.to_hash)
+ assert_equal "bill", args.name
+ }
+ t = task(:t, :name, :rev, :needs => [:pre])
+ t.invoke("bill", "1.2")
+ end
+
+ def test_args_not_passed_if_no_arg_names
+ pre = task(:pre, :rev) { |t, args|
+ assert_equal({}, args.to_hash)
+ }
+ t = task(:t, :needs => [:pre])
+ t.invoke("bill", "1.2")
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_test_task.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_test_task.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_test_task.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,81 @@
+require 'tmpdir'
+require 'test/unit'
+require 'rake/testtask'
+
+class Rake::TestTestTask < Test::Unit::TestCase
+ include Rake
+
+ def setup
+ @oldwd = Dir.pwd
+ @tmpwd = Dir.mktmpdir
+ Dir.chdir(@tmpwd)
+ Task.clear
+ ENV.delete('TEST')
+ open('install.rb', 'w') {}
+ end
+
+ def teardown
+ FileUtils.rm_rf("testdata")
+ Dir.chdir(@oldwd)
+ FileUtils.rm_rf(@tmpwd)
+ end
+
+ def test_no_task
+ assert ! Task.task_defined?(:test)
+ end
+
+ def test_defaults
+ tt = Rake::TestTask.new do |t| end
+ assert_not_nil tt
+ assert_equal :test, tt.name
+ assert_equal ['lib'], tt.libs
+ assert_equal 'test/test*.rb', tt.pattern
+ assert_equal false, tt.verbose
+ assert Task.task_defined?(:test)
+ end
+
+ def test_non_defaults
+ tt = Rake::TestTask.new(:example) do |t|
+ t.libs = ['src', 'ext']
+ t.pattern = 'test/tc_*.rb'
+ t.verbose = true
+ end
+ assert_not_nil tt
+ assert_equal :example, tt.name
+ assert_equal ['src', 'ext'], tt.libs
+ assert_equal 'test/tc_*.rb', tt.pattern
+ assert_equal true, tt.verbose
+ assert Task.task_defined?(:example)
+ end
+
+ def test_pattern
+ tt = Rake::TestTask.new do |t|
+ t.pattern = '*.rb'
+ end
+ assert_equal ['install.rb'], tt.file_list.to_a
+ end
+
+ def test_env_test
+ ENV['TEST'] = 'testfile.rb'
+ tt = Rake::TestTask.new do |t|
+ t.pattern = '*'
+ end
+ assert_equal ["testfile.rb"], tt.file_list.to_a
+ end
+
+ def test_test_files
+ tt = Rake::TestTask.new do |t|
+ t.test_files = FileList['a.rb', 'b.rb']
+ end
+ assert_equal ["a.rb", 'b.rb'], tt.file_list.to_a
+ end
+
+ def test_both_pattern_and_test_files
+ tt = Rake::TestTask.new do |t|
+ t.test_files = FileList['a.rb', 'b.rb']
+ t.pattern = '*.rb'
+ end
+ assert_equal ['a.rb', 'b.rb', 'install.rb'], tt.file_list.to_a
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_top_level_functions.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_top_level_functions.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_top_level_functions.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,91 @@
+require 'test/unit'
+require_relative 'capture_stdout'
+require 'rake'
+
+class Rake::TestTopLevelFunctions < Test::Unit::TestCase
+ include CaptureStdout
+
+ def setup
+ super
+ @app = Rake.application
+ Rake.application = @mock = Object.new
+ end
+
+ def teardown
+ Rake.application = @app
+ super
+ end
+
+ def defmock(sym, &block)
+ class << @mock; self; end.class_eval do
+ define_method(sym, block)
+ end
+ end
+
+ def test_namespace
+ args = []
+ defmock(:in_namespace) {|a, *| args << a}
+ namespace "xyz" do end
+ assert_equal(["xyz"], args)
+ end
+
+ def test_import
+ args = []
+ defmock(:add_import) {|a| args << a}
+ import('x', 'y', 'z')
+ assert_equal(['x', 'y', 'z'], args)
+ end
+
+ def test_when_writing
+ out = capture_stdout do
+ when_writing("NOTWRITING") do
+ puts "WRITING"
+ end
+ end
+ assert_equal "WRITING\n", out
+ end
+
+ def test_when_not_writing
+ RakeFileUtils.nowrite_flag = true
+ out = capture_stdout do
+ when_writing("NOTWRITING") do
+ puts "WRITING"
+ end
+ end
+ assert_equal "DRYRUN: NOTWRITING\n", out
+ ensure
+ RakeFileUtils.nowrite_flag = false
+ end
+
+ def test_missing_constants_task
+ args = []
+ defmock(:const_warning) {|a| args << a}
+ Object.const_missing(:Task)
+ assert_equal([:Task], args)
+ end
+
+ def test_missing_constants_file_task
+ args = []
+ defmock(:const_warning) {|a| args << a}
+ Object.const_missing(:FileTask)
+ assert_equal([:FileTask], args)
+ end
+
+ def test_missing_constants_file_creation_task
+ args = []
+ defmock(:const_warning) {|a| args << a}
+ Object.const_missing(:FileCreationTask)
+ assert_equal([:FileCreationTask], args)
+ end
+
+ def test_missing_constants_rake_app
+ args = []
+ defmock(:const_warning) {|a| args << a}
+ Object.const_missing(:RakeApp)
+ assert_equal([:RakeApp], args)
+ end
+
+ def test_missing_other_constant
+ assert_raise(NameError) do Object.const_missing(:Xyz) end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rake/test_win32.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rake/test_win32.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rake/test_win32.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,45 @@
+require 'test/unit'
+require_relative 'in_environment'
+
+require 'rake'
+
+class Rake::TestWin32 < Test::Unit::TestCase
+ include InEnvironment
+
+ Win32 = Rake::Win32
+
+ def test_win32_system_dir_uses_home_if_defined
+ in_environment('RAKE_SYSTEM' => nil,
+ 'HOME' => "C:\\HP",
+ 'APPDATA' => nil
+ ) do
+ assert_equal "C:/HP/Rake", Win32.win32_system_dir
+ end
+ end
+
+ def test_win32_system_dir_uses_appdata_if_defined
+ in_environment(
+ 'RAKE_SYSTEM' => nil,
+ 'HOME' => "C:\\HP",
+ 'APPDATA' => "C:\\Documents and Settings\\HP\\Application Data"
+ ) do
+ assert_equal "C:/Documents and Settings/HP/Application Data/Rake", Win32.win32_system_dir
+ end
+ end
+
+ def test_win32_system_dir_nil_of_no_env_vars
+ in_environment(
+ 'RAKE_SYSTEM' => nil,
+ 'HOME' => nil,
+ 'HOMEDRIVE' => nil,
+ "HOMEPATH" => nil,
+ 'APPDATA' => nil,
+ 'USERPROFILE' => "C:\\Documents and Settings\\HP"
+ ) do
+ assert_raise(ArgumentError) do
+ Win32.win32_system_dir
+ end
+ end
+ end
+
+end if Rake::Win32.windows?
Added: MacRuby/trunk/test/test-mri/test/rdoc/README
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/README (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/README 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+you don't have to
Added: MacRuby/trunk/test/test-mri/test/rdoc/binary.dat
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/binary.dat (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/binary.dat 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,12 @@
+\x8B /H \xEC=kw\xDB6\xB2\xFD\xFE
+4I{\xAD\xC4zڲy\x95\xB3\xB4D\xDB\xDC\xEAU\x91J\x9Cn\xF6\xE8Pls+\x91Z\x92\xF2c\xBB\xBD\xBF}g \x90)ɖ?ڮx\x9B\x9C\xC1\xCC 3\x83\xC1 \xE1\xB1w}sN\xDD|\xB9P-\xEC\xBFy\x94\xAB\xD7~\xB5\xCA\xEF\xA5\x8B\xEB\x9Br\xB9T\xDE\xD9+Ww\xCB{\xDF\xC0]i\xF7R}\x9C꤯yZ>!ߌ\x9D\xA9\xFA\xCE\xCArw\xE1\xFF\xA0\xD78ek<\xF6\xDC\xF7\x82\xFB\xDB~\x967\xF6\x8Ak\x99\xFD6\x9D\xCC,?\xA0\xFE\x83\xF8\xC2Z\xF6/\xED\xEE\xED\xEE\x97+\xFB\x95]\xB0\xFF^u\xA7\xB2\xB1\xFFS\wٿ \xF83gB\xBFFxoww\x85\xFD\xCB\xD5\xCA\xEE~\xDA\xFE\x95R\xA5
+\xFD\xBF\xF4P\x8D\xBC\xED\xFA\xB7\xFF+Y\x98\x94\x95B\xB9\x92\xAF\x80Iʕ\xD2;Ey\x95\xB8KyE\x8E\xA9K}kBl\xCF=s\xCE\xE7\xBE:\x9EK\xBC\xFE
+
VX\xAF\xDF\xFD\x9B\xD60\x87
\xB5\xAD\x91\xE4\xAAɵ\x93B\x83\xF6\xA1֗
+)݁\xD9\x98æ\xDE|\xB7\xFFI"\xB7#dK\xED
\xD4c-!\xD3\xDC\xF3\x89\(ک\xD9W\x81\xAF\xDAj\x91\x94\xF0O\x9A#{}\xFD\x83jjˑ\x86\xA9\x9Azce\xAB\xDBP[\xC3FK5͈\x90'zS:\xCDnc\xD8ְ9\x86\xA0\xECte\L\xE1\xFB\xBAv$H\x86M\xCDh\xC8\xFBZOS\xCD!+\xB3\xD0\xB5\xF5Q\xFDd \x8D\xA9\xEA-\xAD94\xB4F\xCCU\xEF\xB4\xF4\x8E6\xD4;'Z_7\x89\xEEh\xD0j
+{\xAAyc$Lg\x98}\xBD7<\xEAw۬\x84d\xBDcj\xFD\xB4Za\xC8U\x89\xA9]he\xA3\xDBnk
\xD3H\xAA\xD9P
+
+\xEAց\x9F\xB2<\x8E4N\xBA}3]\x8F\xB4F\xB7\x97%\xDC\xADjO4\xB5\xE9Zb\xFA\x9A\xDEh
+\x80\xC1\xE8Ɛ\x90S?\xA8hu`v%\xBD
+\xAD1ue\x9A(c\x95
u\x9D\xCA\xC0fDFL\xA89\xB2\xA9\xA3\x82\xA66<\xEEw=,\x894\xD5á\xA1\xFF,\xF7N\xF8\x83r\xACu\xB4>x\xE8\xD0\xEC6\xBB-\xE0!\xF3L\x90\x9Aa\xAED
\x8E\\xEC6\xBAj\xA4\xD5-L\xACu\xD4C\xE1H\xA6\xDE\xED$\x8DP\xDA\xEA)4\7u \xFE\x9A\x88\x9A`\x9E\xBFSR\xBA=\xB0@\x87\xA2[
u\xFB\xC3F\xE4h\x89\x81<3\xC4y\xE0\xE0\xB64\xA8\x9FN\xAC\x90\x8EI\xE8\x91+\xCBw
\xF7\x9CX\xEE\x98\xCC|\xEFܧA@\xA6\xF0\xC3:\xA7
\xFD~蚙հ\xD0\xC9G\xB5\xDF\xD1;\xC7Yp\x9D r\xA8\xF1`1\xC0\x9E\xA45\xD3HPo[5Ӕ
\xD3\xEA
\xA3\x96Ә\xA7VrxA\x89\xE3\xCE\xE6!\xC1\xED\x81ժw\xC0\xC1\x96\xA9\xD5q\xED\xC9|Ll?.U\xA9 \xF5\xA6p\xC1\xB41\xE8\xFA-K
+F\xD1NY\xB4X\xD6)8&˕a\xD4v\x8F\xCB;\xC9\xD2Ę4\x99\xBA\xF0\xE8ӆ\xC1,\xCBM\xC4^ֱ\xF4\x96)\x8D\x92\xC3aC\xA3;\xE87\xA4X\xC7\xF8=\xB5\xE9o\xEE۔\x8C|\xEF*\x80~\xF6\xB0\xF2E\xFBݏF*U\x90B3/cHH\xD0B_;\xD2\xFAZ\xA71\xE8\xF0轥bl\x8B\xC7W\x814y\xAE\xF8\x84]ǚ\xCC.\xAC
+
Ӵ\x89\xCAq\xC7\xF4\xFAa+\xA3\xB6z'\xEA\xA1\x8C\xE7z\xA7\xA9\x9D&\xFAjt[\xC0\x86
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/rdoc/hidden.zip.txt
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/hidden.zip.txt (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/hidden.zip.txt 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+PK
Added: MacRuby/trunk/test/test-mri/test/rdoc/parsers/.gitignore
===================================================================
Added: MacRuby/trunk/test/test-mri/test/rdoc/test.ja.rdoc
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test.ja.rdoc (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test.ja.rdoc 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,8 @@
+こんにちは!
+
+初めまして。アーロンと申します。
+
+どんな食べ物が好きですか?私はフランスの料理が大好きです。
+日本の料理も大好きです。
+
+食べ物を食べるのが大好きだけど、お皿を洗うのが大嫌いです。
Added: MacRuby/trunk/test/test-mri/test/rdoc/test.ja.txt
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test.ja.txt (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test.ja.txt 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,8 @@
+こんにちは!
+
+初めまして。アーロンと申します。
+
+どんな食べ物が好きですか?私はフランスの料理が大好きです。
+日本の料理も大好きです。
+
+食べ物を食べるのが大好きだけど、お皿を洗うのが大嫌いです。
Added: MacRuby/trunk/test/test-mri/test/rdoc/test.txt
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test.txt (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test.txt 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+test file
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_attribute_manager.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_attribute_manager.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_attribute_manager.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,69 @@
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc'
+require 'rdoc/markup'
+require 'rdoc/markup/attribute_manager'
+
+class TestAttributeManager < MiniTest::Unit::TestCase
+
+ def setup
+ @am = RDoc::Markup::AttributeManager.new
+ @klass = RDoc::Markup::AttributeManager
+ end
+
+ def test_initial_word_pairs
+ word_pairs = @am.matching_word_pairs
+ assert word_pairs.is_a?(Hash)
+ assert_equal(3, word_pairs.size)
+ end
+
+ def test_initial_html
+ html_tags = @am.html_tags
+ assert html_tags.is_a?(Hash)
+ assert_equal(5, html_tags.size)
+ end
+
+ def test_add_matching_word_pair
+ @am.add_word_pair("x","x", :TEST)
+ word_pairs = @am.matching_word_pairs
+ assert_equal(4,word_pairs.size)
+ assert(word_pairs.has_key?("x"))
+ end
+
+ def test_add_invalid_word_pair
+ assert_raises ArgumentError do
+ @am.add_word_pair("<", "<", :TEST)
+ end
+ end
+
+ def test_add_word_pair_map
+ @am.add_word_pair("x", "y", :TEST)
+ word_pair_map = @am.word_pair_map
+ assert_equal(1,word_pair_map.size)
+ assert_equal(word_pair_map. keys.first.source, "(x)(\\S+)(y)")
+ end
+
+ def test_add_html_tag
+ @am.add_html("Test", :TEST)
+ tags = @am.html_tags
+ assert_equal(6, tags.size)
+ assert(tags.has_key?("test"))
+ end
+
+ def test_add_special
+ @am.add_special("WikiWord", :WIKIWORD)
+ specials = @am.special
+ assert_equal(1,specials.size)
+ assert(specials.has_key?("WikiWord"))
+ end
+
+ def silently(&block)
+ warn_level = $VERBOSE
+ $VERBOSE = nil
+ result = block.call
+ $VERBOSE = warn_level
+ result
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_any_method.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_any_method.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_any_method.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,85 @@
+require File.expand_path '../xref_test_case', __FILE__
+
+class RDocAnyMethodTest < XrefTestCase
+
+ def test_aref
+ m = RDoc::AnyMethod.new nil, 'method?'
+
+ assert_equal 'method-i-method%3F', m.aref
+
+ m.singleton = true
+
+ assert_equal 'method-c-method%3F', m.aref
+ end
+
+ def test_arglists
+ m = RDoc::AnyMethod.new nil, 'method'
+
+ assert_nil m.arglists
+
+ m.params = "(a, b)"
+ m.block_params = "c, d"
+
+ assert_equal "method(a, b) { |c, d| ... }", m.arglists
+
+ call_seq = <<-SEQ
+method(a) { |c| ... }
+method(a, b) { |c, d| ... }
+ SEQ
+
+ m.call_seq = call_seq.dup
+
+ assert_equal call_seq, m.arglists
+ end
+
+ def test_full_name
+ assert_equal 'C1::m', @c1.method_list.first.full_name
+ end
+
+ def test_marshal_load
+ instance_method = Marshal.load Marshal.dump(@c1.method_list.last)
+
+ assert_equal 'C1#m', instance_method.full_name
+ assert_equal 'C1', instance_method.parent_name
+ assert_equal '(foo)', instance_method.params
+
+ class_method = Marshal.load Marshal.dump(@c1.method_list.first)
+
+ assert_equal 'C1::m', class_method.full_name
+ assert_equal 'C1', class_method.parent_name
+ assert_equal '()', class_method.params
+ end
+
+ def test_name
+ m = RDoc::AnyMethod.new nil, nil
+
+ assert_nil m.name
+ end
+
+ def test_param_seq
+ m = RDoc::AnyMethod.new nil, 'method'
+ m.parent = @c1
+ m.params = 'a'
+
+ assert_equal '(a)', m.param_seq
+
+ m.params = '(a)'
+
+ assert_equal '(a)', m.param_seq
+
+ m.params = "(a,\n b)"
+
+ assert_equal '(a, b)', m.param_seq
+
+ m.block_params = "c,\n d"
+
+ assert_equal '(a, b) { |c, d| ... }', m.param_seq
+ end
+
+ def test_parent_name
+ assert_equal 'C1', @c1.method_list.first.parent_name
+ assert_equal 'C1', @c1.method_list.last.parent_name
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_attr.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_attr.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_attr.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,48 @@
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/rdoc'
+
+class TestRDocAttr < MiniTest::Unit::TestCase
+
+ def setup
+ @a = RDoc::Attr.new nil, 'attr', 'RW', ''
+ end
+
+ def test_arglists
+ assert_nil @a.arglists
+ end
+
+ def test_block_params
+ assert_nil @a.block_params
+ end
+
+ def test_call_seq
+ assert_nil @a.call_seq
+ end
+
+ def test_full_name
+ assert_equal '(unknown)#attr', @a.full_name
+ end
+
+ def test_params
+ assert_nil @a.params
+ end
+
+ def test_singleton
+ refute @a.singleton
+ end
+
+ def test_type
+ assert_equal 'attr_accessor', @a.type
+
+ @a.rw = 'R'
+
+ assert_equal 'attr_reader', @a.type
+
+ @a.rw = 'W'
+
+ assert_equal 'attr_writer', @a.type
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_class_module.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_class_module.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_class_module.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,100 @@
+require File.expand_path '../xref_test_case', __FILE__
+
+class TestRDocClassModule < XrefTestCase
+
+ def setup
+ super
+
+ @RM = RDoc::Markup
+ end
+
+ def test_comment_equals
+ cm = RDoc::ClassModule.new 'Klass'
+ cm.comment = '# comment 1'
+
+ assert_equal 'comment 1', cm.comment
+
+ cm.comment = '# comment 2'
+
+ assert_equal "comment 1\n---\ncomment 2", cm.comment
+
+ cm.comment = "# * comment 3"
+
+ assert_equal "comment 1\n---\ncomment 2\n---\n* comment 3", cm.comment
+ end
+
+ # handle making a short module alias of yourself
+
+ def test_find_class_named
+ @c2.classes_hash['C2'] = @c2
+
+ assert_nil @c2.find_class_named('C1')
+ end
+
+ def test_merge
+ cm1 = RDoc::ClassModule.new 'Klass'
+ cm1.comment = 'klass 1'
+ cm1.add_attribute RDoc::Attr.new(nil, 'a1', 'RW', '')
+ cm1.add_attribute RDoc::Attr.new(nil, 'a3', 'R', '')
+ cm1.add_constant RDoc::Constant.new('C1', nil, '')
+ cm1.add_include RDoc::Include.new('I1', '')
+ cm1.add_method RDoc::AnyMethod.new(nil, 'm1')
+
+ cm2 = RDoc::ClassModule.new 'Klass'
+ cm2.instance_variable_set(:@comment,
+ @RM::Document.new(
+ @RM::Paragraph.new('klass 2')))
+ cm2.add_attribute RDoc::Attr.new(nil, 'a2', 'RW', '')
+ cm2.add_attribute RDoc::Attr.new(nil, 'a3', 'W', '')
+ cm2.add_constant RDoc::Constant.new('C2', nil, '')
+ cm2.add_include RDoc::Include.new('I2', '')
+ cm2.add_method RDoc::AnyMethod.new(nil, 'm2')
+
+ cm1.merge cm2
+
+ document = @RM::Document.new(
+ @RM::Paragraph.new('klass 2'),
+ @RM::Paragraph.new('klass 1'))
+
+ assert_equal document, cm1.comment
+
+ expected = [
+ RDoc::Attr.new(nil, 'a1', 'RW', ''),
+ RDoc::Attr.new(nil, 'a2', 'RW', ''),
+ RDoc::Attr.new(nil, 'a3', 'RW', ''),
+ ]
+
+ expected.each do |a| a.parent = cm1 end
+ assert_equal expected, cm1.attributes.sort
+
+ expected = [
+ RDoc::Constant.new('C1', nil, ''),
+ RDoc::Constant.new('C2', nil, ''),
+ ]
+
+ expected.each do |c| c.parent = cm1 end
+ assert_equal expected, cm1.constants.sort
+
+ expected = [
+ RDoc::Include.new('I1', ''),
+ RDoc::Include.new('I2', ''),
+ ]
+
+ expected.each do |i| i.parent = cm1 end
+ assert_equal expected, cm1.includes.sort
+
+ expected = [
+ RDoc::AnyMethod.new(nil, 'm1'),
+ RDoc::AnyMethod.new(nil, 'm2'),
+ ]
+
+ expected.each do |m| m.parent = cm1 end
+ assert_equal expected, cm1.method_list.sort
+ end
+
+ def test_superclass
+ assert_equal @c3_h1, @c3_h2.superclass
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_code_object.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_code_object.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_code_object.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,108 @@
+require 'rubygems'
+require 'minitest/autorun'
+require File.expand_path '../xref_test_case', __FILE__
+require 'rdoc/code_object'
+
+class TestRDocCodeObject < XrefTestCase
+
+ def setup
+ super
+
+ @co = RDoc::CodeObject.new
+ end
+
+ def test_initialize
+ assert @co.document_self, 'document_self'
+ assert @co.document_children, 'document_children'
+ refute @co.force_documentation, 'force_documentation'
+ refute @co.done_documenting, 'done_documenting'
+ assert_equal '', @co.comment, 'comment is empty'
+ end
+
+ def test_comment_equals
+ @co.comment = ''
+
+ assert_equal '', @co.comment
+
+ @co.comment = 'I am a comment'
+
+ assert_equal 'I am a comment', @co.comment
+ end
+
+ def test_document_children_equals
+ @co.document_children = false
+ refute @co.document_children
+
+ @c2.document_children = false
+ assert_empty @c2.classes
+ end
+
+ def test_document_self_equals
+ @co.document_self = false
+ refute @co.document_self
+
+ @c1.document_self = false
+ assert_empty @c1.method_list
+ end
+
+ def test_documented_eh
+ refute @co.documented?
+
+ @co.comment = 'hi'
+
+ assert @co.documented?
+
+ @co.comment.replace ''
+
+ refute @co.documented?
+
+ @co.document_self = false
+
+ assert @co.documented?
+ end
+
+ def test_metadata
+ assert_empty @co.metadata
+
+ @co.metadata['markup'] = 'not_rdoc'
+
+ expected = { 'markup' => 'not_rdoc' }
+
+ assert_equal expected, @co.metadata
+
+ assert_equal 'not_rdoc', @co.metadata['markup']
+ end
+
+ def test_parent_file_name
+ assert_equal '(unknown)', @co.parent_file_name
+ assert_equal 'xref_data.rb', @c1.parent_file_name
+ end
+
+ def test_parent_name
+ assert_equal '(unknown)', @co.parent_name
+ assert_equal 'xref_data.rb', @c1.parent_name
+ assert_equal 'C2', @c2_c3.parent_name
+ end
+
+ def test_start_doc
+ @co.document_self = false
+ @co.document_children = false
+
+ @co.start_doc
+
+ assert @co.document_self
+ assert @co.document_children
+ end
+
+ def test_stop_doc
+ @co.document_self = true
+ @co.document_children = true
+
+ @co.stop_doc
+
+ refute @co.document_self
+ refute @co.document_children
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_constant.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_constant.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_constant.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,15 @@
+require File.expand_path '../xref_test_case', __FILE__
+
+class TestRDocConstant < XrefTestCase
+
+ def setup
+ super
+
+ @const = @c1.constants.first
+ end
+
+ def test_path
+ assert_equal 'C1.html#CONST', @const.path
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_context.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_context.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_context.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,305 @@
+require 'rubygems'
+require 'minitest/autorun'
+require File.expand_path '../xref_test_case', __FILE__
+
+class TestRDocContext < XrefTestCase
+
+ def setup
+ super
+
+ @context = RDoc::Context.new
+ end
+
+ def test_initialize
+ assert_empty @context.in_files
+ assert_equal 'unknown', @context.name
+ assert_equal '', @context.comment
+ assert_equal nil, @context.parent
+ assert_equal :public, @context.visibility
+ assert_equal 1, @context.sections.length
+
+ assert_empty @context.classes_hash
+ assert_empty @context.modules_hash
+
+ assert_empty @context.method_list
+ assert_empty @context.attributes
+ assert_empty @context.aliases
+ assert_empty @context.requires
+ assert_empty @context.includes
+ assert_empty @context.constants
+ end
+
+ def test_add_alias
+ as = RDoc::Alias.new nil, 'old_name', 'new_name', 'comment'
+
+ @context.add_alias as
+
+ assert_equal [as], @context.aliases
+ assert_equal [as], @context.unmatched_alias_lists['old_name']
+ end
+
+ def test_add_alias_method
+ meth = RDoc::AnyMethod.new nil, 'old_name'
+ as = RDoc::Alias.new nil, 'old_name', 'new_name', 'comment'
+ as.parent = @context
+
+ @context.add_method meth
+ @context.add_alias as
+
+ assert_empty @context.aliases
+ assert_empty @context.unmatched_alias_lists
+ assert_equal %w[old_name new_name], @context.method_list.map { |m| m.name }
+ end
+
+ def test_add_alias_impl
+ meth = RDoc::AnyMethod.new nil, 'old_name'
+ meth.comment = 'old comment'
+ meth.singleton = false
+ meth.visibility = :private
+
+ alas = RDoc::Alias.new nil, 'old_name', 'new_name', 'new comment'
+
+ @context.add_alias_impl alas, meth
+
+ assert_equal 1, @context.method_list.length
+
+ alas_meth = @context.method_list.first
+ assert_equal 'new_name', alas_meth.name
+ assert_equal 'new comment', alas_meth.comment
+ assert_equal false, alas_meth.singleton
+ assert_equal meth, alas_meth.is_alias_for
+ assert_equal :private, alas_meth.visibility
+
+ assert_equal [alas_meth], meth.aliases
+ end
+
+ def test_add_class
+ @c1.add_class RDoc::NormalClass, 'Klass', 'Object'
+
+ assert_includes @c1.classes.map { |k| k.full_name }, 'C1::Klass'
+ assert_includes RDoc::TopLevel.classes.map { |k| k.full_name }, 'C1::Klass'
+ end
+
+ def test_add_class_superclass
+ @c1.add_class RDoc::NormalClass, 'Klass', 'Object'
+ @c1.add_class RDoc::NormalClass, 'Klass', 'Other'
+ @c1.add_class RDoc::NormalClass, 'Klass', 'Object'
+
+ klass = @c1.find_module_named 'Klass'
+ assert_equal 'Other', klass.superclass
+ end
+
+ def test_add_class_upgrade
+ @c1.add_module RDoc::NormalModule, 'Klass'
+ @c1.add_class RDoc::NormalClass, 'Klass', nil
+
+ assert_includes @c1.classes.map { |k| k.full_name }, 'C1::Klass',
+ 'c1 classes'
+ refute_includes @c1.modules.map { |k| k.full_name }, 'C1::Klass',
+ 'c1 modules'
+
+ assert_includes RDoc::TopLevel.classes.map { |k| k.full_name }, 'C1::Klass',
+ 'TopLevel classes'
+ refute_includes RDoc::TopLevel.modules.map { |k| k.full_name }, 'C1::Klass',
+ 'TopLevel modules'
+ end
+
+ def test_add_constant
+ const = RDoc::Constant.new 'NAME', 'value', 'comment'
+ @context.add_constant const
+
+ assert_equal [const], @context.constants
+ end
+
+ def test_add_include
+ incl = RDoc::Include.new 'Name', 'comment'
+ @context.add_include incl
+
+ assert_equal [incl], @context.includes
+ end
+
+ def test_add_method
+ meth = RDoc::AnyMethod.new nil, 'old_name'
+ meth.visibility = nil
+
+ @context.add_method meth
+
+ assert_equal [meth], @context.method_list
+ assert_equal :public, meth.visibility
+ end
+
+ def test_add_method_alias
+ as = RDoc::Alias.new nil, 'old_name', 'new_name', 'comment'
+ meth = RDoc::AnyMethod.new nil, 'old_name'
+
+ @context.add_alias as
+ refute_empty @context.aliases
+
+ @context.add_method meth
+
+ assert_empty @context.aliases
+ assert_empty @context.unmatched_alias_lists
+ assert_equal %w[old_name new_name], @context.method_list.map { |m| m.name }
+ end
+
+ def test_add_module
+ @c1.add_module RDoc::NormalModule, 'Mod'
+
+ assert_includes @c1.modules.map { |m| m.full_name }, 'C1::Mod'
+ end
+
+ def test_add_module_alias
+ c3_c4 = @c2.add_module_alias @c2_c3, 'C4'
+
+ assert_equal @c2.find_module_named('C4'), c3_c4
+ end
+
+ def test_add_module_class
+ k = @c1.add_class RDoc::NormalClass, 'Klass', nil
+ m = @c1.add_module RDoc::NormalModule, 'Klass'
+
+ assert_equal k, m, 'returns class'
+ assert_empty @c1.modules
+ end
+
+ def test_add_require
+ req = RDoc::Require.new 'require', 'comment'
+ @c1.add_require req
+
+ assert_empty @c1.requires
+ assert_includes @c1.top_level.requires, req
+ end
+
+ def test_add_to
+ incl = RDoc::Include.new 'Name', 'comment'
+ arr = []
+ @context.add_to arr, incl
+
+ assert_includes arr, incl
+ assert_equal @context, incl.parent
+ assert_equal @context.current_section, incl.section
+ end
+
+ def test_add_to_no_document_self
+ incl = RDoc::Include.new 'Name', 'comment'
+ arr = []
+ @context.document_self = false
+ @context.add_to arr, incl
+
+ refute_includes arr, incl
+ end
+
+ def test_add_to_done_documenting
+ incl = RDoc::Include.new 'Name', 'comment'
+ arr = []
+ @context.done_documenting = true
+ @context.add_to arr, incl
+
+ refute_includes arr, incl
+ end
+
+ def test_child_name
+ assert_equal 'C1::C1', @c1.child_name('C1')
+ end
+
+ def test_classes
+ assert_equal %w[C2::C3], @c2.classes.map { |k| k.full_name }
+ assert_equal %w[C3::H1 C3::H2], @c3.classes.map { |k| k.full_name }
+ end
+
+ def test_defined_in_eh
+ assert @c1.defined_in?(@c1.top_level)
+
+ refute @c1.defined_in?(RDoc::TopLevel.new('name.rb'))
+ end
+
+ def test_equals2
+ assert_equal @c3, @c3
+ refute_equal @c2, @c3
+ refute_equal @c2_c3, @c3
+ end
+
+ def test_find_attribute_named
+ assert_equal nil, @c1.find_attribute_named('none')
+ assert_equal 'R', @c1.find_attribute_named('attr').rw
+ assert_equal 'R', @c1.find_attribute_named('attr_reader').rw
+ assert_equal 'W', @c1.find_attribute_named('attr_writer').rw
+ assert_equal 'RW', @c1.find_attribute_named('attr_accessor').rw
+ end
+
+ def test_find_class_method_named
+ assert_equal nil, @c1.find_class_method_named('none')
+
+ m = @c1.find_class_method_named('m')
+ assert_instance_of RDoc::AnyMethod, m
+ assert m.singleton
+ end
+
+ def test_find_constant_named
+ assert_equal nil, @c1.find_constant_named('NONE')
+ assert_equal ':const', @c1.find_constant_named('CONST').value
+ end
+
+ def test_find_enclosing_module_named
+ assert_equal nil, @c2_c3.find_enclosing_module_named('NONE')
+ assert_equal @c1, @c2_c3.find_enclosing_module_named('C1')
+ assert_equal @c2, @c2_c3.find_enclosing_module_named('C2')
+ end
+
+ def test_find_file_named
+ assert_equal nil, @c1.find_file_named('nonexistent.rb')
+ assert_equal @xref_data, @c1.find_file_named(@file_name)
+ end
+
+ def test_find_instance_method_named
+ assert_equal nil, @c1.find_instance_method_named('none')
+
+ m = @c1.find_instance_method_named('m')
+ assert_instance_of RDoc::AnyMethod, m
+ refute m.singleton
+ end
+
+ def test_find_local_symbol
+ assert_equal true, @c1.find_local_symbol('m').singleton
+ assert_equal ':const', @c1.find_local_symbol('CONST').value
+ assert_equal 'R', @c1.find_local_symbol('attr').rw
+ assert_equal @xref_data, @c1.find_local_symbol(@file_name)
+ assert_equal @c2_c3, @c2.find_local_symbol('C3')
+ end
+
+ def test_find_method_named
+ assert_equal true, @c1.find_method_named('m').singleton
+ end
+
+ def test_find_module_named
+ assert_equal @c2_c3, @c2.find_module_named('C3')
+ assert_equal @c2, @c2.find_module_named('C2')
+ assert_equal @c1, @c2.find_module_named('C1')
+
+ assert_equal 'C2::C3', @c2.find_module_named('C3').full_name
+ end
+
+ def test_find_symbol
+ c3 = @xref_data.find_module_named('C3')
+ assert_equal c3, @xref_data.find_symbol('C3')
+ assert_equal c3, @c2.find_symbol('::C3')
+ assert_equal @c2_c3, @c2.find_symbol('C3')
+ end
+
+ def test_find_symbol_method
+ assert_equal @c1__m, @c1.find_symbol('m')
+ assert_equal @c1_m, @c1.find_symbol('#m')
+ assert_equal @c1__m, @c1.find_symbol('::m')
+ end
+
+ def test_spaceship
+ assert_equal(-1, @c2.<=>(@c3))
+ assert_equal 0, @c2.<=>(@c2)
+ assert_equal 1, @c3.<=>(@c2)
+
+ assert_equal 1, @c2_c3.<=>(@c2)
+ assert_equal(-1, @c2_c3.<=>(@c3))
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_generator_ri.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_generator_ri.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_generator_ri.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,56 @@
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/rdoc'
+require 'tmpdir'
+require 'fileutils'
+
+class TestRDocGeneratorRI < MiniTest::Unit::TestCase
+
+ def setup
+ @pwd = Dir.pwd
+ RDoc::TopLevel.reset
+
+ @tmpdir = File.join Dir.tmpdir, "test_rdoc_generator_ri_#{$$}"
+ FileUtils.mkdir_p @tmpdir
+ Dir.chdir @tmpdir
+ options = RDoc::Options.new
+
+ @g = RDoc::Generator::RI.new options
+
+ @top_level = RDoc::TopLevel.new 'file.rb'
+ @klass = @top_level.add_class RDoc::NormalClass, 'Object'
+ @meth = RDoc::AnyMethod.new nil, 'method'
+ @meth_bang = RDoc::AnyMethod.new nil, 'method!'
+ @attr = RDoc::Attr.new nil, 'attr', 'RW', ''
+
+ @klass.add_method @meth
+ @klass.add_method @meth_bang
+ @klass.add_attribute @attr
+ end
+
+ def teardown
+ Dir.chdir @pwd
+ FileUtils.rm_rf @tmpdir
+ end
+
+ def assert_file path
+ assert File.file?(path), "#{path} is not a file"
+ end
+
+ def test_generate
+ top_level = RDoc::TopLevel.new 'file.rb'
+ top_level.add_class @klass.class, @klass.name
+
+ @g.generate nil
+
+ assert_file File.join(@tmpdir, 'cache.ri')
+
+ assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri')
+
+ assert_file File.join(@tmpdir, 'Object', 'attr-i.ri')
+ assert_file File.join(@tmpdir, 'Object', 'method-i.ri')
+ assert_file File.join(@tmpdir, 'Object', 'method%21-i.ri')
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_include.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_include.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_include.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,17 @@
+require File.expand_path '../xref_test_case', __FILE__
+
+class TestRDocInclude < XrefTestCase
+
+ def setup
+ super
+
+ @inc = RDoc::Include.new 'M1', 'comment'
+ end
+
+ def test_module
+ assert_equal @m1, @inc.module
+ assert_equal 'Unknown', RDoc::Include.new('Unknown', 'comment').module
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,37 @@
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/markup'
+require 'rdoc/markup/to_test'
+
+class TestRDocMarkup < MiniTest::Unit::TestCase
+
+ def test_convert
+ str = <<-STR
+now is
+the time
+
+ hello
+ dave
+
+1. l1
+2. l2
+ STR
+
+ m = RDoc::Markup.new
+ out = m.convert str, RDoc::Markup::ToTest.new
+
+ expected = [
+ "now is the time",
+ "\n",
+ " hello\n dave\n",
+ "1: ",
+ "l1",
+ "1: ",
+ "l2",
+ ]
+
+ assert_equal expected, out
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_attribute_manager.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_attribute_manager.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_attribute_manager.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,240 @@
+require "rubygems"
+require "minitest/autorun"
+require 'rdoc'
+require 'rdoc/markup'
+require "rdoc/markup/inline"
+require "rdoc/markup/to_html_crossref"
+
+class TestRDocMarkupAttributeManager < MiniTest::Unit::TestCase
+
+ def setup
+ @am = RDoc::Markup::AttributeManager.new
+
+ @bold_on = @am.changed_attribute_by_name([], [:BOLD])
+ @bold_off = @am.changed_attribute_by_name([:BOLD], [])
+
+ @tt_on = @am.changed_attribute_by_name([], [:TT])
+ @tt_off = @am.changed_attribute_by_name([:TT], [])
+
+ @em_on = @am.changed_attribute_by_name([], [:EM])
+ @em_off = @am.changed_attribute_by_name([:EM], [])
+
+ @bold_em_on = @am.changed_attribute_by_name([], [:BOLD] | [:EM])
+ @bold_em_off = @am.changed_attribute_by_name([:BOLD] | [:EM], [])
+
+ @em_then_bold = @am.changed_attribute_by_name([:EM], [:EM] | [:BOLD])
+
+ @em_to_bold = @am.changed_attribute_by_name([:EM], [:BOLD])
+
+ @am.add_word_pair("{", "}", :WOMBAT)
+ @wombat_on = @am.changed_attribute_by_name([], [:WOMBAT])
+ @wombat_off = @am.changed_attribute_by_name([:WOMBAT], [])
+ end
+
+ def crossref(text)
+ crossref_bitmap = RDoc::Markup::Attribute.bitmap_for(:_SPECIAL_) |
+ RDoc::Markup::Attribute.bitmap_for(:CROSSREF)
+
+ [ @am.changed_attribute_by_name([], [:CROSSREF, :_SPECIAL_]),
+ RDoc::Markup::Special.new(crossref_bitmap, text),
+ @am.changed_attribute_by_name([:CROSSREF, :_SPECIAL_], [])
+ ]
+ end
+
+ def test_adding
+ assert_equal(["cat ", @wombat_on, "and", @wombat_off, " dog" ],
+ @am.flow("cat {and} dog"))
+ #assert_equal(["cat {and} dog" ], @am.flow("cat \\{and} dog"))
+ end
+
+ def test_add_word_pair
+ @am.add_word_pair '%', '&', 'percent and'
+
+ assert @am.word_pair_map.include?(/(%)(\S+)(&)/)
+ assert @am.protectable.include?('%')
+ assert !@am.protectable.include?('&')
+ end
+
+ def test_add_word_pair_angle
+ e = assert_raises ArgumentError do
+ @am.add_word_pair '<', '>', 'angles'
+ end
+
+ assert_equal "Word flags may not start with '<'", e.message
+ end
+
+ def test_add_word_pair_matching
+ @am.add_word_pair '^', '^', 'caret'
+
+ assert @am.matching_word_pairs.include?('^')
+ assert @am.protectable.include?('^')
+ end
+
+ def test_basic
+ assert_equal(["cat"], @am.flow("cat"))
+
+ assert_equal(["cat ", @bold_on, "and", @bold_off, " dog"],
+ @am.flow("cat *and* dog"))
+
+ assert_equal(["cat ", @bold_on, "AND", @bold_off, " dog"],
+ @am.flow("cat *AND* dog"))
+
+ assert_equal(["cat ", @em_on, "And", @em_off, " dog"],
+ @am.flow("cat _And_ dog"))
+
+ assert_equal(["cat *and dog*"], @am.flow("cat *and dog*"))
+
+ assert_equal(["*cat and* dog"], @am.flow("*cat and* dog"))
+
+ assert_equal(["cat *and ", @bold_on, "dog", @bold_off],
+ @am.flow("cat *and *dog*"))
+
+ assert_equal(["cat ", @em_on, "and", @em_off, " dog"],
+ @am.flow("cat _and_ dog"))
+
+ assert_equal(["cat_and_dog"],
+ @am.flow("cat_and_dog"))
+
+ assert_equal(["cat ", @tt_on, "and", @tt_off, " dog"],
+ @am.flow("cat +and+ dog"))
+
+ assert_equal(["cat ", @bold_on, "a_b_c", @bold_off, " dog"],
+ @am.flow("cat *a_b_c* dog"))
+
+ assert_equal(["cat __ dog"],
+ @am.flow("cat __ dog"))
+
+ assert_equal(["cat ", @em_on, "_", @em_off, " dog"],
+ @am.flow("cat ___ dog"))
+ end
+
+ def test_bold
+ assert_equal [@bold_on, 'bold', @bold_off],
+ @am.flow("*bold*")
+
+ assert_equal [@bold_on, 'Bold:', @bold_off],
+ @am.flow("*Bold:*")
+
+ assert_equal [@bold_on, '\\bold', @bold_off],
+ @am.flow("*\\bold*")
+ end
+
+ def test_bold_html_escaped
+ assert_equal ['cat <b>dog</b>'], @am.flow('cat \<b>dog</b>')
+ end
+
+ def test_combined
+ assert_equal(["cat ", @em_on, "and", @em_off, " ", @bold_on, "dog", @bold_off],
+ @am.flow("cat _and_ *dog*"))
+
+ assert_equal(["cat ", @em_on, "a__nd", @em_off, " ", @bold_on, "dog", @bold_off],
+ @am.flow("cat _a__nd_ *dog*"))
+ end
+
+ def test_convert_attrs
+ str = '+foo+'
+ attrs = RDoc::Markup::AttrSpan.new str.length
+
+ @am.convert_attrs str, attrs
+
+ assert_equal "\000foo\000", str
+
+ str = '+:foo:+'
+ attrs = RDoc::Markup::AttrSpan.new str.length
+
+ @am.convert_attrs str, attrs
+
+ assert_equal "\000:foo:\000", str
+
+ str = '+x-y+'
+ attrs = RDoc::Markup::AttrSpan.new str.length
+
+ @am.convert_attrs str, attrs
+
+ assert_equal "\000x-y\000", str
+ end
+
+ def test_html_like_em_bold
+ assert_equal ["cat ", @em_on, "and ", @em_to_bold, "dog", @bold_off],
+ @am.flow("cat <i>and </i><b>dog</b>")
+ end
+
+ def test_html_like_em_bold_SGML
+ assert_equal ["cat ", @em_on, "and ", @em_to_bold, "dog", @bold_off],
+ @am.flow("cat <i>and <b></i>dog</b>")
+ end
+
+ def test_html_like_em_bold_nested_1
+ assert_equal(["cat ", @bold_em_on, "and", @bold_em_off, " dog"],
+ @am.flow("cat <i><b>and</b></i> dog"))
+ end
+
+ def test_html_like_em_bold_nested_2
+ assert_equal ["cat ", @em_on, "and ", @em_then_bold, "dog", @bold_em_off],
+ @am.flow("cat <i>and <b>dog</b></i>")
+ end
+
+ def test_html_like_em_bold_nested_mixed_case
+ assert_equal ["cat ", @em_on, "and ", @em_then_bold, "dog", @bold_em_off],
+ @am.flow("cat <i>and <B>dog</B></I>")
+ end
+
+ def test_html_like_em_bold_mixed_case
+ assert_equal ["cat ", @em_on, "and", @em_off, " ", @bold_on, "dog", @bold_off],
+ @am.flow("cat <i>and</i> <B>dog</b>")
+ end
+
+ def test_html_like_teletype
+ assert_equal ["cat ", @tt_on, "dog", @tt_off],
+ @am.flow("cat <tt>dog</Tt>")
+ end
+
+ def test_html_like_teletype_em_bold_SGML
+ assert_equal [@tt_on, "cat", @tt_off, " ", @em_on, "and ", @em_to_bold, "dog", @bold_off],
+ @am.flow("<tt>cat</tt> <i>and <b></i>dog</b>")
+ end
+
+ def test_protect
+ assert_equal(['cat \\ dog'],
+ @am.flow('cat \\ dog'))
+
+ assert_equal(["cat <tt>dog</Tt>"],
+ @am.flow("cat \\<tt>dog</Tt>"))
+
+ assert_equal(["cat ", @em_on, "and", @em_off, " <B>dog</b>"],
+ @am.flow("cat <i>and</i> \\<B>dog</b>"))
+
+ assert_equal(["*word* or <b>text</b>"],
+ @am.flow("\\*word* or \\<b>text</b>"))
+
+ assert_equal(["_cat_", @em_on, "dog", @em_off],
+ @am.flow("\\_cat_<i>dog</i>"))
+ end
+
+ def test_special
+ @am.add_special(RDoc::Markup::ToHtmlCrossref::CROSSREF_REGEXP, :CROSSREF)
+
+ #
+ # The apostrophes in "cats'" and "dogs'" suppress the flagging of these
+ # words as potential cross-references, which is necessary for the unit
+ # tests. Unfortunately, the markup engine right now does not actually
+ # check whether a cross-reference is valid before flagging it.
+ #
+ assert_equal(["cats'"], @am.flow("cats'"))
+
+ assert_equal(["cats' ", crossref("#fred"), " dogs'"].flatten,
+ @am.flow("cats' #fred dogs'"))
+
+ assert_equal([crossref("#fred"), " dogs'"].flatten,
+ @am.flow("#fred dogs'"))
+
+ assert_equal(["cats' ", crossref("#fred")].flatten, @am.flow("cats' #fred"))
+ end
+
+ def test_tt_html
+ assert_equal [@tt_on, '"\n"', @tt_off],
+ @am.flow('<tt>"\n"</tt>')
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_document.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_document.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_document.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,51 @@
+require 'pp'
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/markup'
+
+class TestRDocMarkupDocument < MiniTest::Unit::TestCase
+
+ def setup
+ @RM = RDoc::Markup
+ @d = @RM::Document.new
+ end
+
+ def mu_pp obj
+ s = ''
+ s = PP.pp obj, s
+ s.force_encoding Encoding.default_external if defined? Encoding
+ s.chomp
+ end
+
+ def test_append
+ @d << @RM::Paragraph.new('hi')
+
+ expected = @RM::Document.new @RM::Paragraph.new('hi')
+
+ assert_equal expected, @d
+ end
+
+ def test_append_document
+ @d << @RM::Document.new
+
+ assert_empty @d
+
+ @d << @RM::Document.new(@RM::Paragraph.new('hi'))
+
+ expected = @RM::Document.new @RM::Paragraph.new('hi'), @RM::BlankLine.new
+
+ assert_equal expected, @d
+ end
+
+ def test_append_string
+ @d << ''
+
+ assert_empty @d
+
+ assert_raises ArgumentError do
+ @d << 'hi'
+ end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_paragraph.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_paragraph.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_paragraph.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,9 @@
+require 'pp'
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/markup'
+
+class TestRDocMarkupParagraph < MiniTest::Unit::TestCase
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_parser.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_parser.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_parser.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1345 @@
+require 'pp'
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/markup'
+require 'rdoc/markup/to_test'
+
+class TestRDocMarkupParser < MiniTest::Unit::TestCase
+
+ def setup
+ @RM = RDoc::Markup
+ @RMP = @RM::Parser
+ end
+
+ def mu_pp(obj)
+ s = ''
+ s = PP.pp obj, s
+ s = s.force_encoding(Encoding.default_external) if defined? Encoding
+ s.chomp
+ end
+
+ def test_build_heading
+ parser = @RMP.new
+
+ parser.tokens.replace [
+ [:TEXT, 'heading three', 4, 0],
+ [:NEWLINE, "\n", 17, 0],
+ ]
+
+ assert_equal @RM::Heading.new(3, 'heading three'), parser.build_heading(3)
+ end
+
+ def test_get
+ parser = util_parser
+
+ assert_equal [:HEADER, 1, 0, 0], parser.get
+
+ assert_equal 7, parser.tokens.length
+ end
+
+ def test_parse_bullet
+ str = <<-STR
+* l1
+* l2
+ STR
+
+ expected = [
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1')),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_bullet_verbatim_heading
+ str = <<-STR
+* l1
+ v
+
+= H
+ STR
+
+ expected = [
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1'),
+ @RM::Verbatim.new(' ', 'v', "\n"))]),
+ @RM::Heading.new(1, 'H')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_bullet_heading
+ str = <<-STR
+* = l1
+ STR
+
+ expected = [
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Heading.new(1, 'l1'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_bullet_indent
+ str = <<-STR
+* l1
+ * l1.1
+* l2
+ STR
+
+ expected = [
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1'),
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1.1'))])),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_bullet_paragraph
+ str = <<-STR
+now is
+* l1
+* l2
+the time
+ STR
+
+ expected = [
+ @RM::Paragraph.new('now is'),
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1')),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2')),
+ ]),
+ @RM::Paragraph.new('the time'),
+ ]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_bullet_multiline
+ str = <<-STR
+* l1
+ l1+
+* l2
+ STR
+
+ expected = [
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1', 'l1+')),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2')),
+ ]),
+ ]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_bullet_multiparagraph
+ str = <<-STR
+* l1
+
+ l1+
+ STR
+
+ expected = [
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1'),
+ @RM::BlankLine.new,
+ @RM::Paragraph.new('l1+')),
+ ]),
+ ]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_bullet_indent_verbatim
+ str = <<-STR
+* l1
+ * l1.1
+ text
+ code
+ code
+
+ text
+* l2
+ STR
+
+ expected = [
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1'),
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1.1', 'text'),
+ @RM::Verbatim.new(' ', 'code', "\n",
+ ' ', 'code', "\n"),
+ @RM::Paragraph.new('text'))])),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_dash
+ str = <<-STR
+- one
+- two
+ STR
+
+ expected = [
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('one')),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('two'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_heading
+ str = '= heading one'
+
+ expected = [
+ @RM::Heading.new(1, 'heading one')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_heading_three
+ str = '=== heading three'
+
+ expected = [
+ @RM::Heading.new(3, 'heading three')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_heading_bullet
+ str = '= * heading one'
+
+ expected = [
+ @RM::Heading.new(1, '* heading one')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_heading_heading
+ str = '= ='
+
+ expected = [
+ @RM::Heading.new(1, '=')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_heading_lalpha
+ str = '= b. heading one'
+
+ expected = [
+ @RM::Heading.new(1, 'b. heading one')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_heading_label
+ str = '= [heading one]'
+
+ expected = [
+ @RM::Heading.new(1, '[heading one]')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_heading_note
+ str = '= heading one::'
+
+ expected = [
+ @RM::Heading.new(1, 'heading one::')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_heading_number
+ str = '= 5. heading one'
+
+ expected = [
+ @RM::Heading.new(1, '5. heading one')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_heading_ualpha
+ str = '= B. heading one'
+
+ expected = [
+ @RM::Heading.new(1, 'B. heading one')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_label
+ str = <<-STR
+[one] item one
+[two] item two
+ STR
+
+ expected = [
+ @RM::List.new(:LABEL, *[
+ @RM::ListItem.new('one',
+ @RM::Paragraph.new('item one')),
+ @RM::ListItem.new('two',
+ @RM::Paragraph.new('item two'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_label_bullet
+ str = <<-STR
+[cat] l1
+ * l1.1
+[dog] l2
+ STR
+
+ expected = [
+ @RM::List.new(:LABEL, *[
+ @RM::ListItem.new('cat',
+ @RM::Paragraph.new('l1'),
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1.1'))])),
+ @RM::ListItem.new('dog',
+ @RM::Paragraph.new('l2'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_label_multiline
+ str = <<-STR
+[cat] l1
+ continuation
+[dog] l2
+ STR
+
+ expected = [
+ @RM::List.new(:LABEL, *[
+ @RM::ListItem.new('cat',
+ @RM::Paragraph.new('l1', 'continuation')),
+ @RM::ListItem.new('dog',
+ @RM::Paragraph.new('l2'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_label_newline
+ str = <<-STR
+[one]
+ item one
+[two]
+ item two
+ STR
+
+ expected = [
+ @RM::List.new(:LABEL, *[
+ @RM::ListItem.new('one',
+ @RM::Paragraph.new('item one')),
+ @RM::ListItem.new('two',
+ @RM::Paragraph.new('item two')),
+ ])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_lalpha
+ str = <<-STR
+a. l1
+b. l2
+ STR
+
+ expected = [
+ @RM::List.new(:LALPHA, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1')),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_lalpha_ualpha
+ str = <<-STR
+a. l1
+b. l2
+A. l3
+A. l4
+ STR
+
+ expected = [
+ @RM::List.new(:LALPHA, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1')),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2'))]),
+ @RM::List.new(:UALPHA, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l3')),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l4'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_list_verbatim
+ str = <<-STR
+* one
+ verb1
+ verb2
+* two
+ STR
+
+ expected = [
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('one'),
+ @RM::Verbatim.new(' ', 'verb1', "\n",
+ ' ', 'verb2', "\n")),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('two'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_lists
+ str = <<-STR
+now is
+* l1
+1. n1
+2. n2
+* l2
+the time
+ STR
+
+ expected = [
+ @RM::Paragraph.new('now is'),
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1'))]),
+ @RM::List.new(:NUMBER, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('n1')),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('n2'))]),
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2'))]),
+ @RM::Paragraph.new('the time')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_note
+ str = <<-STR
+one:: item one
+two:: item two
+ STR
+
+ expected = [
+ @RM::List.new(:NOTE, *[
+ @RM::ListItem.new('one',
+ @RM::Paragraph.new('item one')),
+ @RM::ListItem.new('two',
+ @RM::Paragraph.new('item two'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_note_empty
+ str = <<-STR
+one::
+two::
+ STR
+
+ expected = [
+ @RM::List.new(:NOTE, *[
+ @RM::ListItem.new('one',
+ @RM::BlankLine.new),
+ @RM::ListItem.new('two',
+ @RM::BlankLine.new)])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_note_note
+ str = <<-STR
+one:: two::
+ STR
+
+ expected = [
+ @RM::List.new(:NOTE, *[
+ @RM::ListItem.new('one',
+ @RM::List.new(:NOTE, *[
+ @RM::ListItem.new('two',
+ @RM::BlankLine.new)]))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_number_bullet
+ str = <<-STR
+1. l1
+ * l1.1
+2. l2
+ STR
+
+ expected = [
+ @RM::List.new(:NUMBER, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1'),
+ @RM::List.new(:BULLET, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1.1'))])),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_paragraph
+ str = <<-STR
+now is the time
+
+for all good men
+ STR
+
+ expected = [
+ @RM::Paragraph.new('now is the time'),
+ @RM::BlankLine.new,
+ @RM::Paragraph.new('for all good men')]
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_paragraph_multiline
+ str = "now is the time\nfor all good men"
+
+ expected = @RM::Paragraph.new 'now is the time for all good men'
+ assert_equal [expected], @RMP.parse(str).parts
+ end
+
+ def test_parse_paragraph_verbatim
+ str = <<-STR
+now is the time
+ code _line_ here
+for all good men
+ STR
+
+ expected = [
+ @RM::Paragraph.new('now is the time'),
+ @RM::Verbatim.new(' ', 'code _line_ here', "\n"),
+ @RM::Paragraph.new('for all good men'),
+ ]
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_ualpha
+ str = <<-STR
+A. l1
+B. l2
+ STR
+
+ expected = [
+ @RM::List.new(:UALPHA, *[
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1')),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2'))])]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim
+ str = <<-STR
+now is
+ code
+the time
+ STR
+
+ expected = [
+ @RM::Paragraph.new('now is'),
+ @RM::Verbatim.new(' ', 'code', "\n"),
+ @RM::Paragraph.new('the time'),
+ ]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_bullet
+ str = <<-STR
+ * blah
+ STR
+
+ expected = [
+ @RM::Verbatim.new(' ', '*', ' ', 'blah', "\n")]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_fold
+ str = <<-STR
+now is
+ code
+
+
+ code1
+
+the time
+ STR
+
+ expected = [
+ @RM::Paragraph.new('now is'),
+ @RM::Verbatim.new(' ', 'code', "\n",
+ "\n",
+ ' ', 'code1', "\n"),
+ @RM::Paragraph.new('the time'),
+ ]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_heading
+ str = <<-STR
+text
+ === heading three
+ STR
+
+ expected = [
+ @RM::Paragraph.new('text'),
+ @RM::Verbatim.new(' ', '===', ' ', 'heading three', "\n")]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_heading2
+ str = "text\n code\n=== heading three"
+
+ expected = [
+ @RM::Paragraph.new('text'),
+ @RM::Verbatim.new(' ', 'code', "\n"),
+ @RM::Heading.new(3, 'heading three')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_label
+ str = <<-STR
+ [blah] blah
+ STR
+
+ expected = [
+ @RM::Verbatim.new(' ', '[blah]', ' ', 'blah', "\n")]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_lalpha
+ str = <<-STR
+ b. blah
+ STR
+
+ expected = [
+ @RM::Verbatim.new(' ', 'b.', ' ', 'blah', "\n")]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_markup_example
+ str = <<-STR
+text
+ code
+ === heading three
+ STR
+
+ expected = [
+ @RM::Paragraph.new('text'),
+ @RM::Verbatim.new(' ', 'code', "\n",
+ ' ', '===', ' ', 'heading three', "\n")]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_merge
+ str = <<-STR
+now is
+ code
+
+ code1
+the time
+ STR
+
+ expected = [
+ @RM::Paragraph.new('now is'),
+ @RM::Verbatim.new(' ', 'code', "\n",
+ "\n",
+ ' ', 'code1', "\n"),
+ @RM::Paragraph.new('the time'),
+ ]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_merge2
+ str = <<-STR
+now is
+ code
+
+ code1
+
+ code2
+the time
+ STR
+
+ expected = [
+ @RM::Paragraph.new('now is'),
+ @RM::Verbatim.new(' ', 'code', "\n",
+ "\n",
+ ' ', 'code1', "\n",
+ "\n",
+ ' ', 'code2', "\n"),
+ @RM::Paragraph.new('the time'),
+ ]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_multiline
+ str = <<-STR
+now is
+ code
+ code1
+the time
+ STR
+
+ expected = [
+ @RM::Paragraph.new('now is'),
+ @RM::Verbatim.new(' ', 'code', "\n",
+ ' ', 'code1', "\n"),
+ @RM::Paragraph.new('the time'),
+ ]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_multilevel
+ str = <<-STR
+now is the time
+ code
+ more code
+for all good men
+ STR
+
+ expected = [
+ @RM::Paragraph.new('now is the time'),
+ @RM::Verbatim.new(' ', 'code', "\n",
+ ' ', 'more code', "\n"),
+ @RM::Paragraph.new('for all good men'),
+ ]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_note
+ str = <<-STR
+ blah:: blah
+ STR
+
+ expected = [
+ @RM::Verbatim.new(' ', 'blah::', ' ', 'blah', "\n")]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_number
+ str = <<-STR
+ 2. blah
+ STR
+
+ expected = [
+ @RM::Verbatim.new(' ', '2.', ' ', 'blah', "\n")]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_rule
+ str = <<-STR
+text
+
+ --- lib/blah.rb.orig
+ +++ lib/blah.rb
+ STR
+
+ expected = [
+ @RM::Paragraph.new('text'),
+ @RM::BlankLine.new,
+ @RM::Verbatim.new(' ', '---', ' ', 'lib/blah.rb.orig', "\n",
+ ' ', '+++', ' ', 'lib/blah.rb', "\n")]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_rule2
+ str = <<-STR.chomp
+text
+
+ ---
+ STR
+
+ expected = [
+ @RM::Paragraph.new('text'),
+ @RM::BlankLine.new,
+ @RM::Verbatim.new(' ', '---', '')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_trim
+ str = <<-STR
+now is
+ code
+
+ code1
+
+the time
+ STR
+
+ expected = [
+ @RM::Paragraph.new('now is'),
+ @RM::Verbatim.new(' ', 'code', "\n",
+ "\n",
+ ' ', 'code1', "\n"),
+ @RM::Paragraph.new('the time'),
+ ]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_verbatim_ualpha
+ str = <<-STR
+ B. blah
+ STR
+
+ expected = [
+ @RM::Verbatim.new(' ', 'B.', ' ', 'blah', "\n")]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_whitespace
+ expected = [
+ @RM::Paragraph.new('hello'),
+ ]
+
+ assert_equal expected, @RMP.parse('hello').parts
+
+ expected = [
+ @RM::Verbatim.new(' ', 'hello '),
+ ]
+
+ assert_equal expected, @RMP.parse(' hello ').parts
+
+ expected = [
+ @RM::Verbatim.new(' ', 'hello '),
+ ]
+
+ assert_equal expected, @RMP.parse(" hello ").parts
+
+ expected = [
+ @RM::Paragraph.new('1'),
+ @RM::Verbatim.new(' ', '2', "\n",
+ ' ', '3'),
+ ]
+
+ assert_equal expected, @RMP.parse("1\n 2\n 3").parts
+
+ expected = [
+ @RM::Verbatim.new(' ', '1', "\n",
+ ' ', '2', "\n",
+ ' ', '3'),
+ ]
+
+ assert_equal expected, @RMP.parse(" 1\n 2\n 3").parts
+
+ expected = [
+ @RM::Paragraph.new('1'),
+ @RM::Verbatim.new(' ', '2', "\n",
+ ' ', '3', "\n"),
+ @RM::Paragraph.new('1'),
+ @RM::Verbatim.new(' ', '2'),
+ ]
+
+ assert_equal expected, @RMP.parse("1\n 2\n 3\n1\n 2").parts
+
+ expected = [
+ @RM::Verbatim.new(' ', '1', "\n",
+ ' ', '2', "\n",
+ ' ', '3', "\n",
+ ' ', '1', "\n",
+ ' ', '2'),
+ ]
+
+ assert_equal expected, @RMP.parse(" 1\n 2\n 3\n 1\n 2").parts
+
+ expected = [
+ @RM::Verbatim.new(' ', '1', "\n",
+ ' ', '2', "\n",
+ "\n",
+ ' ', '3'),
+ ]
+
+ assert_equal expected, @RMP.parse(" 1\n 2\n\n 3").parts
+ end
+
+ def test_peek_token
+ parser = util_parser
+
+ assert_equal [:HEADER, 1, 0, 0], parser.peek_token
+
+ assert_equal 8, parser.tokens.length
+ end
+
+ def test_skip
+ parser = util_parser
+
+ assert_equal [:HEADER, 1, 0, 0], parser.skip(:HEADER)
+
+ assert_equal [:TEXT, 'Heading', 2, 0], parser.get
+
+ assert_equal [:NEWLINE, "\n", 9, 0], parser.peek_token
+
+ assert_raises RDoc::Markup::Parser::ParseError do
+ parser.skip :NONE
+ end
+
+ assert_equal [:NEWLINE, "\n", 9, 0], parser.peek_token
+
+ assert_equal nil, parser.skip(:NONE, false)
+
+ assert_equal [:NEWLINE, "\n", 9, 0], parser.peek_token
+ end
+
+ def test_tokenize_bullet
+ str = <<-STR
+* l1
+ STR
+
+ expected = [
+ [:BULLET, :BULLET, 0, 0],
+ [:SPACE, 2, 0, 0],
+ [:TEXT, 'l1', 2, 0],
+ [:NEWLINE, "\n", 4, 0],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_bullet_indent
+ str = <<-STR
+* l1
+ * l1.1
+ STR
+
+ expected = [
+ [:BULLET, :BULLET, 0, 0],
+ [:SPACE, 2, 0, 0],
+ [:TEXT, 'l1', 2, 0],
+ [:NEWLINE, "\n", 4, 0],
+ [:INDENT, 2, 0, 1],
+ [:BULLET, :BULLET, 2, 1],
+ [:SPACE, 2, 2, 1],
+ [:TEXT, 'l1.1', 4, 1],
+ [:NEWLINE, "\n", 8, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_heading
+ str = <<-STR
+= Heading
+== Heading 2
+ STR
+
+ expected = [
+ [:HEADER, 1, 0, 0],
+ [:TEXT, 'Heading', 2, 0],
+ [:NEWLINE, "\n", 9, 0],
+ [:HEADER, 2, 0, 1],
+ [:TEXT, 'Heading 2', 3, 1],
+ [:NEWLINE, "\n", 12, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_heading_heading
+ str = <<-STR
+= =
+ STR
+
+ expected = [
+ [:HEADER, 1, 0, 0],
+ [:TEXT, '=', 2, 0],
+ [:NEWLINE, "\n", 3, 0],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_heading_no_space
+ str = <<-STR
+=Heading
+==Heading 2
+ STR
+
+ expected = [
+ [:HEADER, 1, 0, 0],
+ [:TEXT, 'Heading', 1, 0],
+ [:NEWLINE, "\n", 8, 0],
+ [:HEADER, 2, 0, 1],
+ [:TEXT, 'Heading 2', 2, 1],
+ [:NEWLINE, "\n", 11, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_label
+ str = <<-STR
+[cat] l1
+[dog] l1.1
+ STR
+
+ expected = [
+ [:LABEL, 'cat', 0, 0],
+ [:SPACE, 6, 0, 0],
+ [:TEXT, 'l1', 6, 0],
+ [:NEWLINE, "\n", 8, 0],
+ [:LABEL, 'dog', 0, 1],
+ [:SPACE, 6, 0, 1],
+ [:TEXT, 'l1.1', 6, 1],
+ [:NEWLINE, "\n", 10, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_label_note
+ str = <<-STR
+[label]
+ note::
+ STR
+
+ expected = [
+ [:LABEL, 'label', 0, 0],
+ [:SPACE, 7, 0, 0],
+ [:NEWLINE, "\n", 7, 0],
+ [:INDENT, 2, 0, 1],
+ [:NOTE, 'note', 2, 1],
+ [:SPACE, 6, 2, 1],
+ [:NEWLINE, "\n", 8, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_lalpha
+ str = <<-STR
+a. l1
+b. l1.1
+ STR
+
+ expected = [
+ [:LALPHA, 'a', 0, 0],
+ [:SPACE, 3, 0, 0],
+ [:TEXT, 'l1', 3, 0],
+ [:NEWLINE, "\n", 5, 0],
+ [:LALPHA, 'b', 0, 1],
+ [:SPACE, 3, 0, 1],
+ [:TEXT, 'l1.1', 3, 1],
+ [:NEWLINE, "\n", 7, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_note
+ str = <<-STR
+cat:: l1
+dog:: l1.1
+ STR
+
+ expected = [
+ [:NOTE, 'cat', 0, 0],
+ [:SPACE, 6, 0, 0],
+ [:TEXT, 'l1', 6, 0],
+ [:NEWLINE, "\n", 8, 0],
+ [:NOTE, 'dog', 0, 1],
+ [:SPACE, 6, 0, 1],
+ [:TEXT, 'l1.1', 6, 1],
+ [:NEWLINE, "\n", 10, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_note_empty
+ str = <<-STR
+cat::
+dog::
+ STR
+
+ expected = [
+ [:NOTE, 'cat', 0, 0],
+ [:SPACE, 5, 0, 0],
+ [:NEWLINE, "\n", 5, 0],
+ [:NOTE, 'dog', 0, 1],
+ [:SPACE, 5, 0, 1],
+ [:NEWLINE, "\n", 5, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_note_not
+ str = <<-STR
+Cat::Dog
+ STR
+
+ expected = [
+ [:TEXT, 'Cat::Dog', 0, 0],
+ [:NEWLINE, "\n", 8, 0],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_number
+ str = <<-STR
+1. l1
+2. l1.1
+ STR
+
+ expected = [
+ [:NUMBER, '1', 0, 0],
+ [:SPACE, 3, 0, 0],
+ [:TEXT, 'l1', 3, 0],
+ [:NEWLINE, "\n", 5, 0],
+ [:NUMBER, '2', 0, 1],
+ [:SPACE, 3, 0, 1],
+ [:TEXT, 'l1.1', 3, 1],
+ [:NEWLINE, "\n", 7, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_number_period
+ str = <<-STR
+1. blah blah blah
+ l.
+2. blah blah blah blah
+ d.
+ STR
+
+ expected = [
+ [:NUMBER, "1", 0, 0],
+ [:SPACE, 3, 0, 0],
+ [:TEXT, "blah blah blah", 3, 0],
+ [:NEWLINE, "\n", 17, 0],
+
+ [:INDENT, 3, 0, 1],
+ [:TEXT, "l.", 3, 1],
+ [:NEWLINE, "\n", 5, 1],
+
+ [:NUMBER, "2", 0, 2],
+ [:SPACE, 3, 0, 2],
+ [:TEXT, "blah blah blah blah", 3, 2],
+ [:NEWLINE, "\n", 22, 2],
+
+ [:INDENT, 3, 0, 3],
+ [:TEXT, "d.", 3, 3],
+ [:NEWLINE, "\n", 5, 3]
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_number_period_continue
+ str = <<-STR
+1. blah blah blah
+ l. more stuff
+2. blah blah blah blah
+ d. other stuff
+ STR
+
+ expected = [
+ [:NUMBER, "1", 0, 0],
+ [:SPACE, 3, 0, 0],
+ [:TEXT, "blah blah blah", 3, 0],
+ [:NEWLINE, "\n", 17, 0],
+
+ [:INDENT, 3, 0, 1],
+ [:LALPHA, "l", 3, 1],
+ [:SPACE, 4, 3, 1],
+ [:TEXT, "more stuff", 7, 1],
+ [:NEWLINE, "\n", 17, 1],
+
+ [:NUMBER, "2", 0, 2],
+ [:SPACE, 3, 0, 2],
+ [:TEXT, "blah blah blah blah", 3, 2],
+ [:NEWLINE, "\n", 22, 2],
+
+ [:INDENT, 3, 0, 3],
+ [:LALPHA, "d", 3, 3],
+ [:SPACE, 3, 3, 3],
+ [:TEXT, "other stuff", 6, 3],
+ [:NEWLINE, "\n", 17, 3]
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_paragraphs
+ str = <<-STR
+now is
+the time
+
+for all
+ STR
+
+ expected = [
+ [:TEXT, 'now is', 0, 0],
+ [:NEWLINE, "\n", 6, 0],
+ [:TEXT, 'the time', 0, 1],
+ [:NEWLINE, "\n", 8, 1],
+ [:NEWLINE, "\n", 0, 2],
+ [:TEXT, 'for all', 0, 3],
+ [:NEWLINE, "\n", 7, 3],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_rule
+ str = <<-STR
+---
+
+--- blah ---
+ STR
+
+ expected = [
+ [:RULE, 1, 0, 0],
+ [:NEWLINE, "\n", 4, 0],
+ [:NEWLINE, "\n", 0, 1],
+ [:TEXT, "--- blah ---", 0, 2],
+ [:NEWLINE, "\n", 12, 2],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_ualpha
+ str = <<-STR
+A. l1
+B. l1.1
+ STR
+
+ expected = [
+ [:UALPHA, 'A', 0, 0],
+ [:SPACE, 3, 0, 0],
+ [:TEXT, 'l1', 3, 0],
+ [:NEWLINE, "\n", 5, 0],
+ [:UALPHA, 'B', 0, 1],
+ [:SPACE, 3, 0, 1],
+ [:TEXT, 'l1.1', 3, 1],
+ [:NEWLINE, "\n", 7, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_verbatim_heading
+ str = <<-STR
+Example heading:
+
+ === heading three
+ STR
+
+ expected = [
+ [:TEXT, 'Example heading:', 0, 0],
+ [:NEWLINE, "\n", 16, 0],
+ [:NEWLINE, "\n", 0, 1],
+ [:INDENT, 3, 0, 2],
+ [:HEADER, 3, 3, 2],
+ [:TEXT, 'heading three', 7, 2],
+ [:NEWLINE, "\n", 20, 2],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ # HACK move to Verbatim test case
+ def test_verbatim_normalize
+ v = @RM::Verbatim.new ' ', 'foo', "\n", "\n", "\n", ' ', 'bar', "\n"
+
+ v.normalize
+
+ assert_equal [' ', 'foo', "\n", "\n", ' ', 'bar', "\n"], v.parts
+
+ v = @RM::Verbatim.new ' ', 'foo', "\n", "\n"
+
+ v.normalize
+
+ assert_equal [' ', 'foo', "\n"], v.parts
+ end
+
+ def test_unget
+ parser = util_parser
+
+ parser.get
+
+ parser.unget
+
+ assert_equal [:HEADER, 1, 0, 0], parser.peek_token
+
+ assert_raises @RMP::Error do
+ parser.unget
+ end
+
+ assert_equal 8, parser.tokens.length
+ end
+
+ def util_parser
+ str = <<-STR
+= Heading
+
+Some text here
+some more text over here
+ STR
+
+ @parser = @RMP.new
+ @parser.tokenize str
+ @parser
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_pre_process.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_pre_process.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_pre_process.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,181 @@
+require 'tempfile'
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/markup/preprocess'
+require 'rdoc/code_objects'
+
+class TestRDocMarkupPreProcess < MiniTest::Unit::TestCase
+
+ def setup
+ RDoc::Markup::PreProcess.registered.clear
+
+ @tempfile = Tempfile.new 'test_rdoc_markup_pre_process'
+ @tempfile.binmode
+ @name = File.basename @tempfile.path
+ @dir = File.dirname @tempfile.path
+
+ @pp = RDoc::Markup::PreProcess.new __FILE__, [@dir]
+ end
+
+ def teardown
+ @tempfile.close
+ end
+
+ def test_include_file
+ @tempfile.write <<-INCLUDE
+# -*- mode: rdoc; coding: utf-8; fill-column: 74; -*-
+
+Regular expressions (<i>regexp</i>s) are patterns which describe the
+contents of a string.
+ INCLUDE
+
+ @tempfile.flush
+ @tempfile.rewind
+
+ content = @pp.include_file @name, ''
+
+ expected = <<-EXPECTED
+Regular expressions (<i>regexp</i>s) are patterns which describe the
+contents of a string.
+ EXPECTED
+
+ assert_equal expected, content
+ end
+
+ def test_handle
+ text = "# :x: y\n"
+ out = @pp.handle text
+
+ assert_same out, text
+ assert_equal "# :x: y\n", text
+ end
+
+ def test_handle_block
+ text = "# :x: y\n"
+
+ @pp.handle text do |directive, param|
+ false
+ end
+
+ assert_equal "# :x: y\n", text
+
+ @pp.handle text do |directive, param|
+ ''
+ end
+
+ assert_equal "", text
+ end
+
+ def test_handle_code_object
+ cd = RDoc::CodeObject.new
+ text = "# :x: y\n"
+ @pp.handle text, cd
+
+ assert_equal "# :x: y\n", text
+ assert_equal 'y', cd.metadata['x']
+
+ cd.metadata.clear
+ text = "# :x:\n"
+ @pp.handle text, cd
+
+ assert_equal "# :x: \n", text
+ assert_includes cd.metadata, 'x'
+ end
+
+ def test_handle_code_object_block
+ cd = RDoc::CodeObject.new
+ text = "# :x: y\n"
+ @pp.handle text, cd do
+ false
+ end
+
+ assert_equal "# :x: y\n", text
+ assert_empty cd.metadata
+
+ @pp.handle text, cd do
+ nil
+ end
+
+ assert_equal "# :x: y\n", text
+ assert_equal 'y', cd.metadata['x']
+
+ cd.metadata.clear
+
+ @pp.handle text, cd do
+ ''
+ end
+
+ assert_equal '', text
+ assert_empty cd.metadata
+ end
+
+ def test_handle_registered
+ RDoc::Markup::PreProcess.register 'x'
+ text = "# :x: y\n"
+ @pp.handle text
+
+ assert_equal '', text
+
+ text = "# :x: y\n"
+
+ @pp.handle text do |directive, param|
+ false
+ end
+
+ assert_equal "# :x: y\n", text
+
+ text = "# :x: y\n"
+
+ @pp.handle text do |directive, param|
+ ''
+ end
+
+ assert_equal "", text
+ end
+
+ def test_handle_registered_block
+ called = nil
+ RDoc::Markup::PreProcess.register 'x' do |directive, param|
+ called = [directive, param]
+ 'blah'
+ end
+
+ text = "# :x: y\n"
+ @pp.handle text
+
+ assert_equal 'blah', text
+ assert_equal %w[x y], called
+ end
+
+ def test_handle_registered_code_object
+ RDoc::Markup::PreProcess.register 'x'
+ cd = RDoc::CodeObject.new
+
+ text = "# :x: y\n"
+ @pp.handle text, cd
+
+ assert_equal '', text
+ assert_equal 'y', cd.metadata['x']
+
+ cd.metadata.clear
+ text = "# :x: y\n"
+
+ @pp.handle text do |directive, param|
+ false
+ end
+
+ assert_equal "# :x: y\n", text
+ assert_empty cd.metadata
+
+ text = "# :x: y\n"
+
+ @pp.handle text do |directive, param|
+ ''
+ end
+
+ assert_equal "", text
+ assert_empty cd.metadata
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_raw.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_raw.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_raw.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,27 @@
+require 'pp'
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/markup'
+
+class TestRDocMarkupRaw < MiniTest::Unit::TestCase
+
+ def setup
+ @RM = RDoc::Markup
+ @p = @RM::Raw.new
+ end
+
+ def mu_pp obj
+ s = ''
+ s = PP.pp obj, s
+ s.force_encoding Encoding.default_external if defined? Encoding
+ s.chomp
+ end
+
+ def test_push
+ @p.push 'hi', 'there'
+
+ assert_equal @RM::Raw.new('hi', 'there'), @p
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_ansi.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_ansi.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_ansi.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,438 @@
+require 'rubygems'
+require 'rdoc/markup/formatter_test_case'
+require 'rdoc/markup/to_ansi'
+require 'minitest/autorun'
+
+class TestRDocMarkupToAnsi < RDoc::Markup::FormatterTestCase
+
+ add_visitor_tests
+
+ def setup
+ super
+
+ @to = RDoc::Markup::ToAnsi.new
+ end
+
+ def accept_blank_line
+ assert_equal "\e[0m\n", @to.res.join
+ end
+
+ def accept_heading
+ assert_equal "\e[0mHello\n", @to.res.join
+ end
+
+ def accept_list_end_bullet
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_label
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_lalpha
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_note
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_number
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_ualpha
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_item_end_bullet
+ assert_equal 0, @to.indent, 'indent'
+ end
+
+ def accept_list_item_end_label
+ assert_equal "\e[0m\n", @to.res.join
+ assert_equal 0, @to.indent, 'indent'
+ end
+
+ def accept_list_item_end_lalpha
+ assert_equal 0, @to.indent, 'indent'
+ assert_equal 'b', @to.list_index.last
+ end
+
+ def accept_list_item_end_note
+ assert_equal "\e[0m\n", @to.res.join
+ assert_equal 0, @to.indent, 'indent'
+ end
+
+ def accept_list_item_end_number
+ assert_equal 0, @to.indent, 'indent'
+ assert_equal 2, @to.list_index.last
+ end
+
+ def accept_list_item_end_ualpha
+ assert_equal 0, @to.indent, 'indent'
+ assert_equal 'B', @to.list_index.last
+ end
+
+ def accept_list_item_start_bullet
+ assert_equal %W"\e[0m", @to.res
+ assert_equal '* ', @to.prefix
+ end
+
+ def accept_list_item_start_label
+ assert_equal %W"\e[0m", @to.res
+ assert_equal "cat:\n ", @to.prefix
+
+ assert_equal 2, @to.indent
+ end
+
+ def accept_list_item_start_lalpha
+ assert_equal %W"\e[0m", @to.res
+ assert_equal 'a. ', @to.prefix
+
+ assert_equal 'a', @to.list_index.last
+ assert_equal 3, @to.indent
+ end
+
+ def accept_list_item_start_note
+ assert_equal %W"\e[0m", @to.res
+ assert_equal "cat:\n ", @to.prefix
+
+ assert_equal 2, @to.indent
+ end
+
+ def accept_list_item_start_number
+ assert_equal %W"\e[0m", @to.res
+ assert_equal '1. ', @to.prefix
+
+ assert_equal 1, @to.list_index.last
+ assert_equal 3, @to.indent
+ end
+
+ def accept_list_item_start_ualpha
+ assert_equal %W"\e[0m", @to.res
+ assert_equal 'A. ', @to.prefix
+
+ assert_equal 'A', @to.list_index.last
+ assert_equal 3, @to.indent
+ end
+
+ def accept_list_start_bullet
+ assert_equal "\e[0m", @to.res.join
+ assert_equal [nil], @to.list_index
+ assert_equal [:BULLET], @to.list_type
+ assert_equal [1], @to.list_width
+ end
+
+ def accept_list_start_label
+ assert_equal "\e[0m", @to.res.join
+ assert_equal [nil], @to.list_index
+ assert_equal [:LABEL], @to.list_type
+ assert_equal [2], @to.list_width
+ end
+
+ def accept_list_start_lalpha
+ assert_equal "\e[0m", @to.res.join
+ assert_equal ['a'], @to.list_index
+ assert_equal [:LALPHA], @to.list_type
+ assert_equal [1], @to.list_width
+ end
+
+ def accept_list_start_note
+ assert_equal "\e[0m", @to.res.join
+ assert_equal [nil], @to.list_index
+ assert_equal [:NOTE], @to.list_type
+ assert_equal [2], @to.list_width
+ end
+
+ def accept_list_start_number
+ assert_equal "\e[0m", @to.res.join
+ assert_equal [1], @to.list_index
+ assert_equal [:NUMBER], @to.list_type
+ assert_equal [1], @to.list_width
+ end
+
+ def accept_list_start_ualpha
+ assert_equal "\e[0m", @to.res.join
+ assert_equal ['A'], @to.list_index
+ assert_equal [:UALPHA], @to.list_type
+ assert_equal [1], @to.list_width
+ end
+
+ def accept_paragraph
+ assert_equal "\e[0mhi\n", @to.res.join
+ end
+
+ def accept_raw
+ raw = <<-RAW.rstrip
+\e[0m<table>
+<tr><th>Name<th>Count
+<tr><td>a<td>1
+<tr><td>b<td>2
+</table>
+ RAW
+
+ assert_equal raw, @to.res.join
+ end
+
+ def accept_rule
+ assert_equal "\e[0m#{'-' * 78}\n", @to.res.join
+ end
+
+ def accept_verbatim # FormatterTestCase doesn't set indent for ToAnsi
+ assert_equal "\e[0m hi\n world\n\n", @to.res.join
+ end
+
+ def end_accepting
+ assert_equal "\e[0mhi", @to.end_accepting
+ end
+
+ def start_accepting
+ assert_equal 0, @to.indent
+ assert_equal %W"\e[0m", @to.res
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def test_accept_heading_1
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(1, 'Hello')
+
+ assert_equal "\e[0m\e[1;32mHello\e[m\n", @to.end_accepting
+ end
+
+ def test_accept_heading_2
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(2, 'Hello')
+
+ assert_equal "\e[0m\e[4;32mHello\e[m\n", @to.end_accepting
+ end
+
+ def test_accept_heading_3
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(3, 'Hello')
+
+ assert_equal "\e[0m\e[32mHello\e[m\n", @to.end_accepting
+ end
+
+ def test_accept_heading_4
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(4, 'Hello')
+
+ assert_equal "\e[0mHello\n", @to.end_accepting
+ end
+
+ def test_accept_heading_indent
+ @to.start_accepting
+ @to.indent = 3
+ @to.accept_heading @RM::Heading.new(1, 'Hello')
+
+ assert_equal "\e[0m \e[1;32mHello\e[m\n", @to.end_accepting
+ end
+
+ def test_accept_heading_b
+ @to.start_accepting
+ @to.indent = 3
+ @to.accept_heading @RM::Heading.new(1, '*Hello*')
+
+ assert_equal "\e[0m \e[1;32m\e[1mHello\e[m\e[m\n", @to.end_accepting
+ end
+
+ def test_accept_list_item_start_note_2
+ list = @RM::List.new(:NOTE,
+ @RM::ListItem.new('<tt>teletype</tt>',
+ @RM::Paragraph.new('teletype description')))
+
+ @to.start_accepting
+
+ list.accept @to
+
+ expected = "\e[0m\e[7mteletype\e[m:\n teletype description\n\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_b
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('reg <b>bold words</b> reg')
+
+ expected = "\e[0mreg \e[1mbold words\e[m reg\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_i
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('reg <em>italic words</em> reg')
+
+ expected = "\e[0mreg \e[4mitalic words\e[m reg\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_indent
+ @to.start_accepting
+ @to.indent = 3
+ @to.accept_paragraph @RM::Paragraph.new('words ' * 30)
+
+ expected = <<-EXPECTED
+\e[0m words words words words words words words words words words words words
+ words words words words words words words words words words words words
+ words words words words words words
+ EXPECTED
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_plus
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('regular +teletype+ regular')
+
+ expected = "\e[0mregular \e[7mteletype\e[m regular\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_star
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('regular *bold* regular')
+
+ expected = "\e[0mregular \e[1mbold\e[m regular\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_underscore
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('regular _italic_ regular')
+
+ expected = "\e[0mregular \e[4mitalic\e[m regular\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_wrap
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('words ' * 30)
+
+ expected = <<-EXPECTED
+\e[0mwords words words words words words words words words words words words words
+words words words words words words words words words words words words words
+words words words words
+ EXPECTED
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_rule_indent
+ @to.start_accepting
+ @to.indent = 3
+
+ @to.accept_rule @RM::Rule.new(1)
+
+ assert_equal "\e[0m #{'-' * 75}\n", @to.end_accepting
+ end
+
+ def test_accept_verbatim_indent
+ @to.start_accepting
+
+ @to.indent = 2
+
+ @to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
+ ' ', 'world', "\n")
+
+ assert_equal "\e[0m hi\n world\n\n", @to.end_accepting
+ end
+
+ def test_accept_verbatim_big_indent
+ @to.start_accepting
+
+ @to.indent = 2
+
+ @to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
+ ' ', 'world', "\n")
+
+ assert_equal "\e[0m hi\n world\n\n", @to.end_accepting
+ end
+
+ def test_attributes
+ assert_equal 'Dog', @to.attributes("\\Dog")
+ end
+
+ def test_list_nested
+ doc = @RM::Document.new(
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1'),
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1.1')))),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2'))))
+
+ output = doc.accept @to
+
+ expected = <<-EXPECTED
+\e[0m* l1
+ * l1.1
+* l2
+ EXPECTED
+
+ assert_equal expected, output
+ end
+
+ def test_list_verbatim # HACK overblown
+ doc = @RM::Document.new(
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('list', 'stuff'),
+ @RM::BlankLine.new(),
+ @RM::Verbatim.new(' ', '*', ' ', 'list', "\n",
+ ' ', 'with', "\n",
+ "\n",
+ ' ', 'second', "\n",
+ "\n",
+ ' ', '1.', ' ', 'indented', "\n",
+ ' ', '2.', ' ', 'numbered', "\n",
+ "\n",
+ ' ', 'third', "\n",
+ "\n",
+ ' ', '*', ' ', 'second', "\n"))))
+
+ output = doc.accept @to
+
+ expected = <<-EXPECTED
+\e[0m* list stuff
+
+ * list
+ with
+
+ second
+
+ 1. indented
+ 2. numbered
+
+ third
+
+ * second
+
+ EXPECTED
+
+ assert_equal expected, output
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_bs.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_bs.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_bs.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,455 @@
+require 'rubygems'
+require 'rdoc/markup/formatter_test_case'
+require 'rdoc/markup/to_bs'
+require 'minitest/autorun'
+
+class TestRDocMarkupToBs < RDoc::Markup::FormatterTestCase
+
+ add_visitor_tests
+
+ def setup
+ super
+
+ @to = RDoc::Markup::ToBs.new
+ end
+
+ def accept_blank_line
+ assert_equal "\n", @to.res.join
+ end
+
+ def accept_heading
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ assert_equal "===== H\bHe\bel\bll\blo\bo\n", @to.res.join
+ end
+
+ def accept_list_end_bullet
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_label
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_lalpha
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_note
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_number
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_ualpha
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_item_end_bullet
+ assert_equal 0, @to.indent, 'indent'
+ end
+
+ def accept_list_item_end_label
+ assert_equal 0, @to.indent, 'indent'
+ end
+
+ def accept_list_item_end_lalpha
+ assert_equal 0, @to.indent, 'indent'
+ assert_equal 'b', @to.list_index.last
+ end
+
+ def accept_list_item_end_note
+ assert_equal 0, @to.indent, 'indent'
+ end
+
+ def accept_list_item_end_number
+ assert_equal 0, @to.indent, 'indent'
+ assert_equal 2, @to.list_index.last
+ end
+
+ def accept_list_item_end_ualpha
+ assert_equal 0, @to.indent, 'indent'
+ assert_equal 'B', @to.list_index.last
+ end
+
+ def accept_list_item_start_bullet
+ assert_equal [''], @to.res
+ assert_equal '* ', @to.prefix
+ end
+
+ def accept_list_item_start_label
+ assert_equal [''], @to.res
+ assert_equal "cat:\n ", @to.prefix
+
+ assert_equal 2, @to.indent
+ end
+
+ def accept_list_item_start_lalpha
+ assert_equal [''], @to.res
+ assert_equal 'a. ', @to.prefix
+
+ assert_equal 'a', @to.list_index.last
+ assert_equal 3, @to.indent
+ end
+
+ def accept_list_item_start_note
+ assert_equal [''], @to.res
+ assert_equal "cat:\n ", @to.prefix
+
+ assert_equal 2, @to.indent
+ end
+
+ def accept_list_item_start_number
+ assert_equal [''], @to.res
+ assert_equal '1. ', @to.prefix
+
+ assert_equal 1, @to.list_index.last
+ assert_equal 3, @to.indent
+ end
+
+ def accept_list_item_start_ualpha
+ assert_equal [''], @to.res
+ assert_equal 'A. ', @to.prefix
+
+ assert_equal 'A', @to.list_index.last
+ assert_equal 3, @to.indent
+ end
+
+ def accept_list_start_bullet
+ assert_equal "", @to.res.join
+ assert_equal [nil], @to.list_index
+ assert_equal [:BULLET], @to.list_type
+ assert_equal [1], @to.list_width
+ end
+
+ def accept_list_start_label
+ assert_equal "", @to.res.join
+ assert_equal [nil], @to.list_index
+ assert_equal [:LABEL], @to.list_type
+ assert_equal [2], @to.list_width
+ end
+
+ def accept_list_start_lalpha
+ assert_equal "", @to.res.join
+ assert_equal ['a'], @to.list_index
+ assert_equal [:LALPHA], @to.list_type
+ assert_equal [1], @to.list_width
+ end
+
+ def accept_list_start_note
+ assert_equal "", @to.res.join
+ assert_equal [nil], @to.list_index
+ assert_equal [:NOTE], @to.list_type
+ assert_equal [2], @to.list_width
+ end
+
+ def accept_list_start_number
+ assert_equal "", @to.res.join
+ assert_equal [1], @to.list_index
+ assert_equal [:NUMBER], @to.list_type
+ assert_equal [1], @to.list_width
+ end
+
+ def accept_list_start_ualpha
+ assert_equal "", @to.res.join
+ assert_equal ['A'], @to.list_index
+ assert_equal [:UALPHA], @to.list_type
+ assert_equal [1], @to.list_width
+ end
+
+ def accept_paragraph
+ assert_equal "hi\n", @to.res.join
+ end
+
+ def accept_raw
+ raw = <<-RAW.rstrip
+<table>
+<tr><th>Name<th>Count
+<tr><td>a<td>1
+<tr><td>b<td>2
+</table>
+ RAW
+
+ assert_equal raw, @to.res.join
+ end
+
+ def accept_rule
+ assert_equal "#{'-' * 78}\n", @to.res.join
+ end
+
+ def accept_verbatim # FormatterTestCase doesn't set indent for ToAnsi
+ assert_equal " hi\n world\n\n", @to.res.join
+ end
+
+ def end_accepting
+ assert_equal "hi", @to.end_accepting
+ end
+
+ def start_accepting
+ assert_equal 0, @to.indent
+ assert_equal [''], @to.res
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def test_accept_heading_1
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(1, 'Hello')
+
+ assert_equal "= H\bHe\bel\bll\blo\bo\n", @to.end_accepting
+ end
+
+ def test_accept_heading_2
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(2, 'Hello')
+
+ assert_equal "== H\bHe\bel\bll\blo\bo\n", @to.end_accepting
+ end
+
+ def test_accept_heading_3
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(3, 'Hello')
+
+ assert_equal "=== H\bHe\bel\bll\blo\bo\n", @to.end_accepting
+ end
+
+ def test_accept_heading_4
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(4, 'Hello')
+
+ assert_equal "==== H\bHe\bel\bll\blo\bo\n", @to.end_accepting
+ end
+
+ def test_accept_heading_indent
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ @to.start_accepting
+ @to.indent = 3
+ @to.accept_heading @RM::Heading.new(1, 'Hello')
+
+ assert_equal " = H\bHe\bel\bll\blo\bo\n", @to.end_accepting
+ end
+
+ def test_accept_heading_b
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ @to.start_accepting
+ @to.indent = 3
+ @to.accept_heading @RM::Heading.new(1, '*Hello*')
+
+ assert_equal " = H\bHe\bel\bll\blo\bo\n", @to.end_accepting
+ end
+
+ def test_accept_heading_suppressed_crossref
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(1, '\\Hello')
+
+ assert_equal "= H\bHe\bel\bll\blo\bo\n", @to.end_accepting
+ end
+
+ def test_accept_list_item_start_note_2
+ list = @RM::List.new(:NOTE,
+ @RM::ListItem.new('<tt>teletype</tt>',
+ @RM::Paragraph.new('teletype description')))
+
+ @to.start_accepting
+
+ list.accept @to
+
+ expected = "teletype:\n teletype description\n\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_b
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('reg <b>bold words</b> reg')
+
+ expected = "reg b\bbo\bol\bld\bd \b w\bwo\bor\brd\bds\bs reg\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_i
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('reg <em>italic words</em> reg')
+
+ expected = "reg _\bi_\bt_\ba_\bl_\bi_\bc_\b _\bw_\bo_\br_\bd_\bs reg\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_indent
+ @to.start_accepting
+ @to.indent = 3
+ @to.accept_paragraph @RM::Paragraph.new('words ' * 30)
+
+ expected = <<-EXPECTED
+ words words words words words words words words words words words words
+ words words words words words words words words words words words words
+ words words words words words words
+ EXPECTED
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_plus
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('regular +teletype+ regular')
+
+ expected = "regular teletype regular\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_star
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('regular *bold* regular')
+
+ expected = "regular b\bbo\bol\bld\bd regular\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_underscore
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('regular _italic_ regular')
+
+ expected = "regular _\bi_\bt_\ba_\bl_\bi_\bc regular\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_wrap
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('words ' * 30)
+
+ expected = <<-EXPECTED
+words words words words words words words words words words words words words
+words words words words words words words words words words words words words
+words words words words
+ EXPECTED
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_rule_indent
+ @to.start_accepting
+ @to.indent = 3
+
+ @to.accept_rule @RM::Rule.new(1)
+
+ assert_equal " #{'-' * 75}\n", @to.end_accepting
+ end
+
+ def test_accept_verbatim_indent
+ @to.start_accepting
+
+ @to.indent = 2
+
+ @to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
+ ' ', 'world', "\n")
+
+ assert_equal " hi\n world\n\n", @to.end_accepting
+ end
+
+ def test_accept_verbatim_big_indent
+ @to.start_accepting
+
+ @to.indent = 2
+
+ @to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
+ ' ', 'world', "\n")
+
+ assert_equal " hi\n world\n\n", @to.end_accepting
+ end
+
+ def test_attributes
+ assert_equal 'Dog', @to.attributes("\\Dog")
+ end
+
+ def test_list_nested
+ doc = @RM::Document.new(
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1'),
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1.1')))),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2'))))
+
+ output = doc.accept @to
+
+ expected = <<-EXPECTED
+* l1
+ * l1.1
+* l2
+ EXPECTED
+
+ assert_equal expected, output
+ end
+
+ def test_list_verbatim # HACK overblown
+ doc = @RM::Document.new(
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('list', 'stuff'),
+ @RM::BlankLine.new(),
+ @RM::Verbatim.new(' ', '*', ' ', 'list', "\n",
+ ' ', 'with', "\n",
+ "\n",
+ ' ', 'second', "\n",
+ "\n",
+ ' ', '1.', ' ', 'indented', "\n",
+ ' ', '2.', ' ', 'numbered', "\n",
+ "\n",
+ ' ', 'third', "\n",
+ "\n",
+ ' ', '*', ' ', 'second', "\n"))))
+
+ output = doc.accept @to
+
+ expected = <<-EXPECTED
+* list stuff
+
+ * list
+ with
+
+ second
+
+ 1. indented
+ 2. numbered
+
+ third
+
+ * second
+
+ EXPECTED
+
+ assert_equal expected, output
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_html.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_html.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_html.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,258 @@
+require 'rubygems'
+require 'rdoc/markup/formatter_test_case'
+require 'rdoc/markup/to_html'
+require 'minitest/autorun'
+
+class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
+
+ add_visitor_tests
+
+ def setup
+ super
+
+ @to = RDoc::Markup::ToHtml.new
+ end
+
+ def test_class_gen_relative_url
+ def gen(from, to)
+ RDoc::Markup::ToHtml.gen_relative_url from, to
+ end
+
+ assert_equal 'a.html', gen('a.html', 'a.html')
+ assert_equal 'b.html', gen('a.html', 'b.html')
+
+ assert_equal 'd.html', gen('a/c.html', 'a/d.html')
+ assert_equal '../a.html', gen('a/c.html', 'a.html')
+ assert_equal 'a/c.html', gen('a.html', 'a/c.html')
+ end
+
+ def accept_blank_line
+ assert_empty @to.res.join
+ end
+
+ def accept_heading
+ assert_equal "<h5>Hello</h5>\n", @to.res.join
+ end
+
+ def accept_list_end_bullet
+ assert_equal [], @to.list
+ assert_equal [], @to.in_list_entry
+
+ assert_equal "<ul>\n</ul>\n", @to.res.join
+ end
+
+ def accept_list_end_label
+ assert_equal [], @to.list
+ assert_equal [], @to.in_list_entry
+
+ assert_equal "<dl>\n</dl>\n", @to.res.join
+ end
+
+ def accept_list_end_lalpha
+ assert_equal [], @to.list
+ assert_equal [], @to.in_list_entry
+
+ assert_equal "<ol style=\"display: lower-alpha\">\n</ol>\n", @to.res.join
+ end
+
+ def accept_list_end_number
+ assert_equal [], @to.list
+ assert_equal [], @to.in_list_entry
+
+ assert_equal "<ol>\n</ol>\n", @to.res.join
+ end
+
+ def accept_list_end_note
+ assert_equal [], @to.list
+ assert_equal [], @to.in_list_entry
+
+ assert_equal "<table>\n</table>\n", @to.res.join
+ end
+
+ def accept_list_end_ualpha
+ assert_equal [], @to.list
+ assert_equal [], @to.in_list_entry
+
+ assert_equal "<ol style=\"display: upper-alpha\">\n</ol>\n", @to.res.join
+ end
+
+ def accept_list_item_end_bullet
+ assert_equal %w[</li>], @to.in_list_entry
+ end
+
+ def accept_list_item_end_label
+ assert_equal %w[</dd>], @to.in_list_entry
+ end
+
+ def accept_list_item_end_lalpha
+ assert_equal %w[</li>], @to.in_list_entry
+ end
+
+ def accept_list_item_end_note
+ assert_equal %w[</td></tr>], @to.in_list_entry
+ end
+
+ def accept_list_item_end_number
+ assert_equal %w[</li>], @to.in_list_entry
+ end
+
+ def accept_list_item_end_ualpha
+ assert_equal %w[</li>], @to.in_list_entry
+ end
+
+ def accept_list_item_start_bullet
+ assert_equal "<ul>\n<li>", @to.res.join
+ end
+
+ def accept_list_item_start_label
+ assert_equal "<dl>\n<dt>cat</dt><dd>", @to.res.join
+ end
+
+ def accept_list_item_start_lalpha
+ assert_equal "<ol style=\"display: lower-alpha\">\n<li>", @to.res.join
+ end
+
+ def accept_list_item_start_note
+ assert_equal "<table>\n<tr><td valign=\"top\">cat</td><td>", @to.res.join
+ end
+
+ def accept_list_item_start_number
+ assert_equal "<ol>\n<li>", @to.res.join
+ end
+
+ def accept_list_item_start_ualpha
+ assert_equal "<ol style=\"display: upper-alpha\">\n<li>", @to.res.join
+ end
+
+ def accept_list_start_bullet
+ assert_equal [:BULLET], @to.list
+ assert_equal [false], @to.in_list_entry
+
+ assert_equal "<ul>\n", @to.res.join
+ end
+
+ def accept_list_start_label
+ assert_equal [:LABEL], @to.list
+ assert_equal [false], @to.in_list_entry
+
+ assert_equal "<dl>\n", @to.res.join
+ end
+
+ def accept_list_start_lalpha
+ assert_equal [:LALPHA], @to.list
+ assert_equal [false], @to.in_list_entry
+
+ assert_equal "<ol style=\"display: lower-alpha\">\n", @to.res.join
+ end
+
+ def accept_list_start_note
+ assert_equal [:NOTE], @to.list
+ assert_equal [false], @to.in_list_entry
+
+ assert_equal "<table>\n", @to.res.join
+ end
+
+ def accept_list_start_number
+ assert_equal [:NUMBER], @to.list
+ assert_equal [false], @to.in_list_entry
+
+ assert_equal "<ol>\n", @to.res.join
+ end
+
+ def accept_list_start_ualpha
+ assert_equal [:UALPHA], @to.list
+ assert_equal [false], @to.in_list_entry
+
+ assert_equal "<ol style=\"display: upper-alpha\">\n", @to.res.join
+ end
+
+ def accept_paragraph
+ assert_equal "<p>\nhi\n</p>\n", @to.res.join
+ end
+
+ def accept_raw
+ raw = <<-RAW.rstrip
+<table>
+<tr><th>Name<th>Count
+<tr><td>a<td>1
+<tr><td>b<td>2
+</table>
+ RAW
+
+ assert_equal raw, @to.res.join
+ end
+
+ def accept_rule
+ assert_equal '<hr style="height: 4px"></hr>', @to.res.join
+ end
+
+ def accept_verbatim
+ assert_equal "<pre>\n hi\n world\n</pre>\n", @to.res.join
+ end
+
+ def end_accepting
+ assert_equal 'hi', @to.end_accepting
+ end
+
+ def start_accepting
+ assert_equal [], @to.res
+ assert_equal [], @to.in_list_entry
+ assert_equal [], @to.list
+ end
+
+ def test_list_verbatim
+ str = "* one\n verb1\n verb2\n* two\n"
+
+ expected = <<-EXPECTED
+<ul>
+<li><p>
+one
+</p>
+<pre>
+ verb1
+ verb2
+</pre>
+</li>
+<li><p>
+two
+</p>
+</li>
+</ul>
+ EXPECTED
+
+ assert_equal expected, @m.convert(str, @to)
+ end
+
+ def test_tt_formatting
+ assert_equal "<p>\n<tt>--</tt> — <tt>cats'</tt> cats’\n</p>\n",
+ util_format("<tt>--</tt> -- <tt>cats'</tt> cats'")
+
+ assert_equal "<p>\n<b>—</b>\n</p>\n", util_format("<b>--</b>")
+ end
+
+ def test_convert_string_fancy
+ #
+ # The HTML typesetting is broken in a number of ways, but I have fixed
+ # the most glaring issues for single and double quotes. Note that
+ # "strange" symbols (periods or dashes) need to be at the end of the
+ # test case strings in order to suppress cross-references.
+ #
+ assert_equal "<p>\n“cats”.\n</p>\n", util_format("\"cats\".")
+ assert_equal "<p>\n‘cats’.\n</p>\n", util_format("\'cats\'.")
+ assert_equal "<p>\ncat’s-\n</p>\n", util_format("cat\'s-")
+ end
+
+ def util_paragraph(text)
+ RDoc::Markup::Paragraph.new text
+ end
+
+ def util_format(text)
+ paragraph = util_paragraph text
+
+ @to.start_accepting
+ @to.accept_paragraph paragraph
+ @to.end_accepting
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_html_crossref.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_html_crossref.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_html_crossref.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,162 @@
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/rdoc'
+require 'rdoc/code_objects'
+require 'rdoc/markup/to_html_crossref'
+require File.expand_path '../xref_test_case', __FILE__
+
+class TestRDocMarkupToHtmlCrossref < XrefTestCase
+
+ def setup
+ super
+
+ @xref = RDoc::Markup::ToHtmlCrossref.new 'index.html', @c1, true
+ end
+
+ def assert_ref(path, ref)
+ assert_equal "<p>\n<a href=\"#{path}\">#{ref}</a>\n</p>\n",
+ @xref.convert(ref)
+ end
+
+ def refute_ref(body, ref)
+ assert_equal "<p>\n#{body}\n</p>\n", @xref.convert(ref)
+ end
+
+ def test_handle_special_CROSSREF_C2
+ @xref = RDoc::Markup::ToHtmlCrossref.new 'classes/C2.html', @c2, true
+
+ refute_ref '#m', '#m'
+
+ assert_ref '../C1.html#method-c-m', 'C1::m'
+ assert_ref '../C2/C3.html', 'C2::C3'
+ assert_ref '../C2/C3.html#method-i-m', 'C2::C3#m'
+ assert_ref '../C2/C3/H1.html', 'C3::H1'
+ assert_ref '../C4.html', 'C4'
+
+ assert_ref '../C3/H2.html', 'C3::H2'
+ refute_ref 'H1', 'H1'
+ end
+
+ def test_handle_special_CROSSREF_C2_C3
+ @xref = RDoc::Markup::ToHtmlCrossref.new 'classes/C2/C3.html', @c2_c3, true
+
+ assert_ref '../../C2/C3.html#method-i-m', '#m'
+
+ assert_ref '../../C2/C3.html', 'C3'
+ assert_ref '../../C2/C3.html#method-i-m', 'C3#m'
+
+ assert_ref '../../C2/C3/H1.html', 'H1'
+ assert_ref '../../C2/C3/H1.html', 'C3::H1'
+
+ assert_ref '../../C4.html', 'C4'
+
+ assert_ref '../../C3/H2.html', 'C3::H2'
+ end
+
+ def test_handle_special_CROSSREF_C3
+ @xref = RDoc::Markup::ToHtmlCrossref.new 'classes/C3.html', @c3, true
+
+ assert_ref '../C3.html', 'C3'
+
+ refute_ref '#m', '#m'
+ refute_ref 'C3#m', 'C3#m'
+
+ assert_ref '../C3/H1.html', 'H1'
+
+ assert_ref '../C3/H1.html', 'C3::H1'
+ assert_ref '../C3/H2.html', 'C3::H2'
+
+ assert_ref '../C4.html', 'C4'
+ end
+
+ def test_handle_special_CROSSREF_C4
+ @xref = RDoc::Markup::ToHtmlCrossref.new 'classes/C4.html', @c4, true
+
+ # C4 ref inside a C4 containing a C4 should resolve to the contained class
+ assert_ref '../C4/C4.html', 'C4'
+ end
+
+ def test_handle_special_CROSSREF_C4_C4
+ @xref = RDoc::Markup::ToHtmlCrossref.new 'classes/C4/C4.html', @c4_c4, true
+
+ # A C4 reference inside a C4 class contained within a C4 class should
+ # resolve to the inner C4 class.
+ assert_ref '../../C4/C4.html', 'C4'
+ end
+
+ def test_handle_special_CROSSREF_class
+ assert_ref 'C1.html', 'C1'
+ refute_ref 'H1', 'H1'
+
+ assert_ref 'C2.html', 'C2'
+ assert_ref 'C2/C3.html', 'C2::C3'
+ assert_ref 'C2/C3/H1.html', 'C2::C3::H1'
+
+ assert_ref 'C3.html', '::C3'
+ assert_ref 'C3/H1.html', '::C3::H1'
+
+ assert_ref 'C4/C4.html', 'C4::C4'
+ end
+
+ def test_handle_special_CROSSREF_file
+ assert_ref 'xref_data_rb.html', 'xref_data.rb'
+ end
+
+ def test_handle_special_CROSSREF_method
+ refute_ref 'm', 'm'
+ assert_ref 'C1.html#method-i-m', '#m'
+ assert_ref 'C1.html#method-c-m', '::m'
+
+ assert_ref 'C1.html#method-i-m', 'C1#m'
+ assert_ref 'C1.html#method-i-m', 'C1.m'
+ assert_ref 'C1.html#method-c-m', 'C1::m'
+
+ assert_ref 'C1.html#method-i-m', 'C1#m'
+ assert_ref 'C1.html#method-i-m', 'C1#m()'
+ assert_ref 'C1.html#method-i-m', 'C1#m(*)'
+
+ assert_ref 'C1.html#method-i-m', 'C1.m'
+ assert_ref 'C1.html#method-i-m', 'C1.m()'
+ assert_ref 'C1.html#method-i-m', 'C1.m(*)'
+
+ assert_ref 'C1.html#method-c-m', 'C1::m'
+ assert_ref 'C1.html#method-c-m', 'C1::m()'
+ assert_ref 'C1.html#method-c-m', 'C1::m(*)'
+
+ assert_ref 'C2/C3.html#method-i-m', 'C2::C3#m'
+
+ assert_ref 'C2/C3.html#method-i-m', 'C2::C3.m'
+
+ assert_ref 'C2/C3/H1.html#method-i-m%3F', 'C2::C3::H1#m?'
+
+ assert_ref 'C2/C3.html#method-i-m', '::C2::C3#m'
+ assert_ref 'C2/C3.html#method-i-m', '::C2::C3#m()'
+ assert_ref 'C2/C3.html#method-i-m', '::C2::C3#m(*)'
+ end
+
+ def test_handle_special_CROSSREF_no_ref
+ assert_equal '', @xref.convert('')
+
+ refute_ref 'bogus', 'bogus'
+ refute_ref 'bogus', '\bogus'
+ refute_ref '\bogus', '\\\bogus'
+
+ refute_ref '#n', '\#n'
+ refute_ref '#n()', '\#n()'
+ refute_ref '#n(*)', '\#n(*)'
+
+ refute_ref 'C1', '\C1'
+ refute_ref '::C3', '\::C3'
+
+ refute_ref '::C3::H1#n', '::C3::H1#n'
+ refute_ref '::C3::H1#n(*)', '::C3::H1#n(*)'
+ refute_ref '::C3::H1#n', '\::C3::H1#n'
+ end
+
+ def test_handle_special_CROSSREF_special
+ assert_equal "<p>\n<a href=\"C2/C3.html\">C2::C3</a>;method(*)\n</p>\n",
+ @xref.convert('C2::C3;method(*)')
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_rdoc.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_rdoc.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_markup_to_rdoc.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,438 @@
+require 'rubygems'
+require 'rdoc/markup/formatter_test_case'
+require 'rdoc/markup/to_rdoc'
+require 'minitest/autorun'
+
+class TestRDocMarkupToRdoc < RDoc::Markup::FormatterTestCase
+
+ add_visitor_tests
+
+ def setup
+ super
+
+ @to = RDoc::Markup::ToRdoc.new
+ end
+
+ def accept_blank_line
+ assert_equal "\n", @to.res.join
+ end
+
+ def accept_heading
+ assert_equal "===== Hello\n", @to.res.join
+ end
+
+ def accept_list_end_bullet
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_label
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_lalpha
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_note
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_number
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_ualpha
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_item_end_bullet
+ assert_equal 0, @to.indent, 'indent'
+ end
+
+ def accept_list_item_end_label
+ assert_equal "\n", @to.res.join
+ assert_equal 0, @to.indent, 'indent'
+ end
+
+ def accept_list_item_end_lalpha
+ assert_equal 0, @to.indent, 'indent'
+ assert_equal 'b', @to.list_index.last
+ end
+
+ def accept_list_item_end_note
+ assert_equal "\n", @to.res.join
+ assert_equal 0, @to.indent, 'indent'
+ end
+
+ def accept_list_item_end_number
+ assert_equal 0, @to.indent, 'indent'
+ assert_equal 2, @to.list_index.last
+ end
+
+ def accept_list_item_end_ualpha
+ assert_equal 0, @to.indent, 'indent'
+ assert_equal 'B', @to.list_index.last
+ end
+
+ def accept_list_item_start_bullet
+ assert_equal [""], @to.res
+ assert_equal '* ', @to.prefix
+ end
+
+ def accept_list_item_start_label
+ assert_equal [""], @to.res
+ assert_equal "cat:\n ", @to.prefix
+
+ assert_equal 2, @to.indent
+ end
+
+ def accept_list_item_start_lalpha
+ assert_equal [""], @to.res
+ assert_equal 'a. ', @to.prefix
+
+ assert_equal 'a', @to.list_index.last
+ assert_equal 3, @to.indent
+ end
+
+ def accept_list_item_start_note
+ assert_equal [""], @to.res
+ assert_equal "cat:\n ", @to.prefix
+
+ assert_equal 2, @to.indent
+ end
+
+ def accept_list_item_start_number
+ assert_equal [""], @to.res
+ assert_equal '1. ', @to.prefix
+
+ assert_equal 1, @to.list_index.last
+ assert_equal 3, @to.indent
+ end
+
+ def accept_list_item_start_ualpha
+ assert_equal [""], @to.res
+ assert_equal 'A. ', @to.prefix
+
+ assert_equal 'A', @to.list_index.last
+ assert_equal 3, @to.indent
+ end
+
+ def accept_list_start_bullet
+ assert_equal "", @to.res.join
+ assert_equal [nil], @to.list_index
+ assert_equal [:BULLET], @to.list_type
+ assert_equal [1], @to.list_width
+ end
+
+ def accept_list_start_label
+ assert_equal "", @to.res.join
+ assert_equal [nil], @to.list_index
+ assert_equal [:LABEL], @to.list_type
+ assert_equal [2], @to.list_width
+ end
+
+ def accept_list_start_lalpha
+ assert_equal "", @to.res.join
+ assert_equal ['a'], @to.list_index
+ assert_equal [:LALPHA], @to.list_type
+ assert_equal [1], @to.list_width
+ end
+
+ def accept_list_start_note
+ assert_equal "", @to.res.join
+ assert_equal [nil], @to.list_index
+ assert_equal [:NOTE], @to.list_type
+ assert_equal [2], @to.list_width
+ end
+
+ def accept_list_start_number
+ assert_equal "", @to.res.join
+ assert_equal [1], @to.list_index
+ assert_equal [:NUMBER], @to.list_type
+ assert_equal [1], @to.list_width
+ end
+
+ def accept_list_start_ualpha
+ assert_equal "", @to.res.join
+ assert_equal ['A'], @to.list_index
+ assert_equal [:UALPHA], @to.list_type
+ assert_equal [1], @to.list_width
+ end
+
+ def accept_paragraph
+ assert_equal "hi\n", @to.res.join
+ end
+
+ def accept_raw
+ raw = <<-RAW.rstrip
+<table>
+<tr><th>Name<th>Count
+<tr><td>a<td>1
+<tr><td>b<td>2
+</table>
+ RAW
+
+ assert_equal raw, @to.res.join
+ end
+
+ def accept_rule
+ assert_equal "#{'-' * 78}\n", @to.res.join
+ end
+
+ def accept_verbatim # FormatterTestCase doesn't set indent for ToAnsi
+ assert_equal " hi\n world\n\n", @to.res.join
+ end
+
+ def end_accepting
+ assert_equal "hi", @to.end_accepting
+ end
+
+ def start_accepting
+ assert_equal 0, @to.indent
+ assert_equal [""], @to.res
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def test_accept_heading_1
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(1, 'Hello')
+
+ assert_equal "= Hello\n", @to.end_accepting
+ end
+
+ def test_accept_heading_2
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(2, 'Hello')
+
+ assert_equal "== Hello\n", @to.end_accepting
+ end
+
+ def test_accept_heading_3
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(3, 'Hello')
+
+ assert_equal "=== Hello\n", @to.end_accepting
+ end
+
+ def test_accept_heading_4
+ @to.start_accepting
+ @to.accept_heading @RM::Heading.new(4, 'Hello')
+
+ assert_equal "==== Hello\n", @to.end_accepting
+ end
+
+ def test_accept_heading_indent
+ @to.start_accepting
+ @to.indent = 3
+ @to.accept_heading @RM::Heading.new(1, 'Hello')
+
+ assert_equal " = Hello\n", @to.end_accepting
+ end
+
+ def test_accept_heading_b
+ @to.start_accepting
+ @to.indent = 3
+ @to.accept_heading @RM::Heading.new(1, '*Hello*')
+
+ assert_equal " = <b>Hello</b>\n", @to.end_accepting
+ end
+
+ def test_accept_list_item_start_note_2
+ list = @RM::List.new(:NOTE,
+ @RM::ListItem.new('<tt>teletype</tt>',
+ @RM::Paragraph.new('teletype description')))
+
+ @to.start_accepting
+
+ list.accept @to
+
+ expected = "<tt>teletype</tt>:\n teletype description\n\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_b
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('reg <b>bold words</b> reg')
+
+ expected = "reg <b>bold words</b> reg\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_i
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('reg <em>italic words</em> reg')
+
+ expected = "reg <em>italic words</em> reg\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_indent
+ @to.start_accepting
+ @to.indent = 3
+ @to.accept_paragraph @RM::Paragraph.new('words ' * 30)
+
+ expected = <<-EXPECTED
+ words words words words words words words words words words words words
+ words words words words words words words words words words words words
+ words words words words words words
+ EXPECTED
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_plus
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('regular +teletype+ regular')
+
+ expected = "regular <tt>teletype</tt> regular\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_star
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('regular *bold* regular')
+
+ expected = "regular <b>bold</b> regular\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_underscore
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('regular _italic_ regular')
+
+ expected = "regular <em>italic</em> regular\n"
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_paragraph_wrap
+ @to.start_accepting
+ @to.accept_paragraph @RM::Paragraph.new('words ' * 30)
+
+ expected = <<-EXPECTED
+words words words words words words words words words words words words words
+words words words words words words words words words words words words words
+words words words words
+ EXPECTED
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def test_accept_rule_indent
+ @to.start_accepting
+ @to.indent = 3
+
+ @to.accept_rule @RM::Rule.new(1)
+
+ assert_equal " #{'-' * 75}\n", @to.end_accepting
+ end
+
+ def test_accept_verbatim_indent
+ @to.start_accepting
+
+ @to.indent = 2
+
+ @to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
+ ' ', 'world', "\n")
+
+ assert_equal " hi\n world\n\n", @to.end_accepting
+ end
+
+ def test_accept_verbatim_big_indent
+ @to.start_accepting
+
+ @to.indent = 2
+
+ @to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
+ ' ', 'world', "\n")
+
+ assert_equal " hi\n world\n\n", @to.end_accepting
+ end
+
+ def test_attributes
+ assert_equal 'Dog', @to.attributes("\\Dog")
+ end
+
+ def test_list_nested
+ doc = @RM::Document.new(
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1'),
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l1.1')))),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('l2'))))
+
+ output = doc.accept @to
+
+ expected = <<-EXPECTED
+* l1
+ * l1.1
+* l2
+ EXPECTED
+
+ assert_equal expected, output
+ end
+
+ def test_list_verbatim # HACK overblown
+ doc = @RM::Document.new(
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new('list', 'stuff'),
+ @RM::BlankLine.new(),
+ @RM::Verbatim.new(' ', '*', ' ', 'list', "\n",
+ ' ', 'with', "\n",
+ "\n",
+ ' ', 'second', "\n",
+ "\n",
+ ' ', '1.', ' ', 'indented', "\n",
+ ' ', '2.', ' ', 'numbered', "\n",
+ "\n",
+ ' ', 'third', "\n",
+ "\n",
+ ' ', '*', ' ', 'second', "\n"))))
+
+ output = doc.accept @to
+
+ expected = <<-EXPECTED
+* list stuff
+
+ * list
+ with
+
+ second
+
+ 1. indented
+ 2. numbered
+
+ third
+
+ * second
+
+ EXPECTED
+
+ assert_equal expected, output
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_normal_class.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_normal_class.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_normal_class.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,17 @@
+require File.expand_path '../xref_test_case', __FILE__
+
+class TestRDocNormalClass < XrefTestCase
+
+ def test_ancestors_class
+ top_level = RDoc::TopLevel.new 'file.rb'
+ klass = top_level.add_class RDoc::NormalClass, 'Klass'
+ incl = RDoc::Include.new 'Incl', ''
+
+ sub_klass = klass.add_class RDoc::NormalClass, 'SubClass', 'Klass'
+ sub_klass.add_include incl
+
+ assert_equal [incl, klass], sub_klass.ancestors
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_normal_module.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_normal_module.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_normal_module.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,26 @@
+require File.expand_path '../xref_test_case', __FILE__
+
+class TestRDocNormalModule < XrefTestCase
+
+ def setup
+ super
+
+ @mod = RDoc::NormalModule.new 'Mod'
+ end
+
+ def test_ancestors_module
+ top_level = RDoc::TopLevel.new 'file.rb'
+ mod = top_level.add_module RDoc::NormalModule, 'Mod'
+ incl = RDoc::Include.new 'Incl', ''
+
+ mod.add_include incl
+
+ assert_equal [incl], mod.ancestors
+ end
+
+ def test_module_eh
+ assert @mod.module?
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_options.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_options.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_options.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,74 @@
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/options'
+
+class TestRDocOptions < MiniTest::Unit::TestCase
+
+ def setup
+ @options = RDoc::Options.new
+ end
+
+ def test_parse_ignore_invalid
+ out, err = capture_io do
+ @options.parse %w[--ignore-invalid --bogus]
+ end
+
+ refute_match %r%^Usage: %, err
+ assert_match %r%^invalid options: --bogus%, err
+ end
+
+ def test_parse_ignore_invalid_default
+ out, err = capture_io do
+ @options.parse %w[--bogus --main BLAH]
+ end
+
+ refute_match %r%^Usage: %, err
+ assert_match %r%^invalid options: --bogus%, err
+
+ assert_equal 'BLAH', @options.main_page
+ end
+
+ def test_parse_ignore_invalid_no
+ out, err = capture_io do
+ assert_raises SystemExit do
+ @options.parse %w[--no-ignore-invalid --bogus]
+ end
+ end
+
+ assert_match %r%^Usage: %, err
+ assert_match %r%^invalid option: --bogus%, err
+ end
+
+ def test_parse_main
+ out, err = capture_io do
+ @options.parse %w[--main MAIN]
+ end
+
+ assert_empty out
+ assert_empty err
+
+ assert_equal 'MAIN', @options.main_page
+ end
+
+ def test_parse_dash_p
+ out, err = capture_io do
+ @options.parse %w[-p]
+ end
+
+ assert @options.pipe
+ refute_match %r%^Usage: %, err
+ refute_match %r%^invalid options%, err
+ end
+
+ def test_parse_dash_p_files
+ out, err = capture_io do
+ @options.parse %w[-p README]
+ end
+
+ refute @options.pipe
+ refute_match %r%^Usage: %, err
+ assert_match %r%^invalid options: -p .with files.%, err
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,81 @@
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/parser'
+require 'rdoc/parser/ruby'
+require 'tmpdir'
+
+class TestRDocParser < MiniTest::Unit::TestCase
+
+ def setup
+ @RP = RDoc::Parser
+ @binary_dat = File.expand_path '../binary.dat', __FILE__
+ end
+
+ def test_class_binary_eh_erb
+ erb = File.join Dir.tmpdir, "test_rdoc_parser_#{$$}.erb"
+ open erb, 'wb' do |io|
+ io.write 'blah blah <%= stuff %> <% more stuff %>'
+ end
+
+ assert @RP.binary?(erb)
+
+ erb_rb = File.join Dir.tmpdir, "test_rdoc_parser_#{$$}.erb.rb"
+ open erb_rb, 'wb' do |io|
+ io.write 'blah blah <%= stuff %>'
+ end
+
+ refute @RP.binary?(erb_rb)
+ ensure
+ File.unlink erb
+ File.unlink erb_rb if erb_rb
+ end
+
+ def test_class_binary_eh_marshal
+ marshal = File.join Dir.tmpdir, "test_rdoc_parser_#{$$}.marshal"
+ open marshal, 'wb' do |io|
+ io.write Marshal.dump('')
+ io.write 'lots of text ' * 500
+ end
+
+ assert @RP.binary?(marshal)
+ ensure
+ File.unlink marshal
+ end
+
+ def test_class_can_parse
+ assert_equal @RP.can_parse(__FILE__), @RP::Ruby
+
+ readme_file_name = File.expand_path '../test.txt', __FILE__
+
+ assert_equal @RP::Simple, @RP.can_parse(readme_file_name)
+
+ assert_nil @RP.can_parse(@binary_dat)
+
+ jtest_file_name = File.expand_path '../test.ja.txt', __FILE__
+ assert_equal @RP::Simple, @RP.can_parse(jtest_file_name)
+
+ jtest_rdoc_file_name = File.expand_path '../test.ja.rdoc', __FILE__
+ assert_equal @RP::Simple, @RP.can_parse(jtest_rdoc_file_name)
+
+ readme_file_name = File.expand_path '../README', __FILE__
+ assert_equal @RP::Simple, @RP.can_parse(readme_file_name)
+ end
+
+ ##
+ # Selenium hides a .jar file using a .txt extension.
+
+ def test_class_can_parse_zip
+ hidden_zip = File.expand_path '../hidden.zip.txt', __FILE__
+ assert_nil @RP.can_parse(hidden_zip)
+ end
+
+ def test_class_for_binary
+ rp = @RP.dup
+
+ def rp.can_parse(*args) nil end
+
+ assert_nil @RP.for(nil, @binary_dat, nil, nil, nil)
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_c.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_c.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_c.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,487 @@
+require 'stringio'
+require 'tempfile'
+require 'rubygems'
+require 'minitest/unit'
+require 'rdoc/options'
+require 'rdoc/parser/c'
+
+class RDoc::Parser::C
+ attr_accessor :classes
+
+ public :do_classes, :do_constants
+end
+
+class TestRDocParserC < MiniTest::Unit::TestCase
+
+ def setup
+ @tempfile = Tempfile.new self.class.name
+ filename = @tempfile.path
+
+ @top_level = RDoc::TopLevel.new filename
+ @fn = filename
+ @options = RDoc::Options.new
+ @stats = RDoc::Stats.new 0
+
+ RDoc::Parser::C.reset
+ RDoc::TopLevel.reset
+ end
+
+ def teardown
+ @tempfile.close
+ end
+
+ def test_do_classes_boot_class
+ content = <<-EOF
+/* Document-class: Foo
+ * this is the Foo boot class
+ */
+VALUE cFoo = boot_defclass("Foo", rb_cObject);
+ EOF
+
+ klass = util_get_class content, 'cFoo'
+ assert_equal "this is the Foo boot class", klass.comment
+ assert_equal 'Object', klass.superclass
+ end
+
+ def test_do_classes_boot_class_nil
+ content = <<-EOF
+/* Document-class: Foo
+ * this is the Foo boot class
+ */
+VALUE cFoo = boot_defclass("Foo", 0);
+ EOF
+
+ klass = util_get_class content, 'cFoo'
+ assert_equal "this is the Foo boot class", klass.comment
+ assert_equal nil, klass.superclass
+ end
+
+ def test_do_classes_class
+ content = <<-EOF
+/* Document-class: Foo
+ * this is the Foo class
+ */
+VALUE cFoo = rb_define_class("Foo", rb_cObject);
+ EOF
+
+ klass = util_get_class content, 'cFoo'
+ assert_equal "this is the Foo class", klass.comment
+ end
+
+ def test_do_classes_class_under
+ content = <<-EOF
+/* Document-class: Kernel::Foo
+ * this is the Foo class under Kernel
+ */
+VALUE cFoo = rb_define_class_under(rb_mKernel, "Foo", rb_cObject);
+ EOF
+
+ klass = util_get_class content, 'cFoo'
+ assert_equal "this is the Foo class under Kernel", klass.comment
+ end
+
+ def test_do_classes_module
+ content = <<-EOF
+/* Document-module: Foo
+ * this is the Foo module
+ */
+VALUE mFoo = rb_define_module("Foo");
+ EOF
+
+ klass = util_get_class content, 'mFoo'
+ assert_equal "this is the Foo module", klass.comment
+ end
+
+ def test_do_classes_module_under
+ content = <<-EOF
+/* Document-module: Kernel::Foo
+ * this is the Foo module under Kernel
+ */
+VALUE mFoo = rb_define_module_under(rb_mKernel, "Foo");
+ EOF
+
+ klass = util_get_class content, 'mFoo'
+ assert_equal "this is the Foo module under Kernel", klass.comment
+ end
+
+ def test_do_constants
+ content = <<-EOF
+#include <ruby.h>
+
+void Init_foo(){
+ VALUE cFoo = rb_define_class("Foo", rb_cObject);
+
+ /* 300: The highest possible score in bowling */
+ rb_define_const(cFoo, "PERFECT", INT2FIX(300));
+
+ /* Huzzah!: What you cheer when you roll a perfect game */
+ rb_define_const(cFoo, "CHEER", rb_str_new2("Huzzah!"));
+
+ /* TEST\:TEST: Checking to see if escaped colon works */
+ rb_define_const(cFoo, "TEST", rb_str_new2("TEST:TEST"));
+
+ /* \\: The file separator on MS Windows */
+ rb_define_const(cFoo, "MSEPARATOR", rb_str_new2("\\"));
+
+ /* /: The file separator on Unix */
+ rb_define_const(cFoo, "SEPARATOR", rb_str_new2("/"));
+
+ /* C:\\Program Files\\Stuff: A directory on MS Windows */
+ rb_define_const(cFoo, "STUFF", rb_str_new2("C:\\Program Files\\Stuff"));
+
+ /* Default definition */
+ rb_define_const(cFoo, "NOSEMI", INT2FIX(99));
+
+ rb_define_const(cFoo, "NOCOMMENT", rb_str_new2("No comment"));
+
+ /*
+ * Multiline comment goes here because this comment spans multiple lines.
+ * Multiline comment goes here because this comment spans multiple lines.
+ */
+ rb_define_const(cFoo, "MULTILINE", INT2FIX(1));
+
+ /*
+ * 1: Multiline comment goes here because this comment spans multiple lines.
+ * Multiline comment goes here because this comment spans multiple lines.
+ */
+ rb_define_const(cFoo, "MULTILINE_VALUE", INT2FIX(1));
+
+ /* Multiline comment goes here because this comment spans multiple lines.
+ * Multiline comment goes here because this comment spans multiple lines.
+ */
+ rb_define_const(cFoo, "MULTILINE_NOT_EMPTY", INT2FIX(1));
+
+}
+ EOF
+
+ @parser = util_parser content
+
+ @parser.do_classes
+ @parser.do_constants
+
+ klass = @parser.classes['cFoo']
+ assert klass
+
+ constants = klass.constants
+ assert !klass.constants.empty?
+
+ constants = constants.map { |c| [c.name, c.value, c.comment] }
+
+ assert_equal ['PERFECT', '300', 'The highest possible score in bowling '],
+ constants.shift
+ assert_equal ['CHEER', 'Huzzah!',
+ 'What you cheer when you roll a perfect game '],
+ constants.shift
+ assert_equal ['TEST', 'TEST:TEST',
+ 'Checking to see if escaped colon works '],
+ constants.shift
+ assert_equal ['MSEPARATOR', '\\',
+ 'The file separator on MS Windows '],
+ constants.shift
+ assert_equal ['SEPARATOR', '/',
+ 'The file separator on Unix '],
+ constants.shift
+ assert_equal ['STUFF', 'C:\\Program Files\\Stuff',
+ 'A directory on MS Windows '],
+ constants.shift
+ assert_equal ['NOSEMI', 'INT2FIX(99)',
+ 'Default definition '],
+ constants.shift
+ assert_equal ['NOCOMMENT', 'rb_str_new2("No comment")', ''],
+ constants.shift
+
+ comment = <<-EOF.chomp
+Multiline comment goes here because this comment spans multiple lines.
+Multiline comment goes here because this comment spans multiple lines.
+ EOF
+ assert_equal ['MULTILINE', 'INT2FIX(1)', comment], constants.shift
+ assert_equal ['MULTILINE_VALUE', '1', comment], constants.shift
+ assert_equal ['MULTILINE_NOT_EMPTY', 'INT2FIX(1)', comment], constants.shift
+
+ assert constants.empty?, constants.inspect
+ end
+
+ def test_find_class_comment_include
+ @options.rdoc_include << File.dirname(__FILE__)
+
+ content = <<-EOF
+/*
+ * a comment for class Foo
+ *
+ * :include: test.txt
+ */
+void
+Init_Foo(void) {
+ VALUE foo = rb_define_class("Foo", rb_cObject);
+}
+ EOF
+
+ klass = util_get_class content, 'foo'
+
+ assert_equal "a comment for class Foo\n\ntest file", klass.comment
+ end
+
+ def test_find_class_comment_init
+ content = <<-EOF
+/*
+ * a comment for class Foo
+ */
+void
+Init_Foo(void) {
+ VALUE foo = rb_define_class("Foo", rb_cObject);
+}
+ EOF
+
+ klass = util_get_class content, 'foo'
+
+ assert_equal "a comment for class Foo", klass.comment
+ end
+
+ def test_find_class_comment_define_class
+ content = <<-EOF
+/*
+ * a comment for class Foo
+ */
+VALUE foo = rb_define_class("Foo", rb_cObject);
+ EOF
+
+ klass = util_get_class content, 'foo'
+
+ assert_equal "a comment for class Foo", klass.comment
+ end
+
+ def test_find_class_comment_define_class_Init_Foo
+ content = <<-EOF
+/*
+ * a comment for class Foo on Init
+ */
+void
+Init_Foo(void) {
+ /*
+ * a comment for class Foo on rb_define_class
+ */
+ VALUE foo = rb_define_class("Foo", rb_cObject);
+}
+ EOF
+
+ klass = util_get_class content, 'foo'
+
+ assert_equal "a comment for class Foo on Init", klass.comment
+ end
+
+ def test_find_class_comment_define_class_Init_Foo_no_void
+ content = <<-EOF
+/*
+ * a comment for class Foo on Init
+ */
+void
+Init_Foo() {
+ /*
+ * a comment for class Foo on rb_define_class
+ */
+ VALUE foo = rb_define_class("Foo", rb_cObject);
+}
+ EOF
+
+ klass = util_get_class content, 'foo'
+
+ assert_equal "a comment for class Foo on Init", klass.comment
+ end
+
+ def test_find_class_comment_define_class_bogus_comment
+ content = <<-EOF
+/*
+ * a comment for other_function
+ */
+void
+other_function() {
+}
+
+void
+Init_Foo(void) {
+ VALUE foo = rb_define_class("Foo", rb_cObject);
+}
+ EOF
+
+ klass = util_get_class content, 'foo'
+
+ assert_equal '', klass.comment
+ end
+
+ def test_find_body
+ content = <<-EOF
+/*
+ * a comment for other_function
+ */
+VALUE
+other_function() {
+}
+
+void
+Init_Foo(void) {
+ VALUE foo = rb_define_class("Foo", rb_cObject);
+
+ rb_define_method(foo, "my_method", other_function, 0);
+}
+ EOF
+
+ klass = util_get_class content, 'foo'
+ other_function = klass.method_list.first
+
+ assert_equal 'my_method', other_function.name
+ assert_equal "a comment for other_function",
+ other_function.comment
+ assert_equal '()', other_function.params
+
+ code = other_function.token_stream.first.text
+
+ assert_equal "VALUE\nother_function() ", code
+ end
+
+ def test_find_body_define
+ content = <<-EOF
+/*
+ * a comment for other_function
+ */
+#define other_function rb_other_function
+
+/* */
+VALUE
+rb_other_function() {
+}
+
+void
+Init_Foo(void) {
+ VALUE foo = rb_define_class("Foo", rb_cObject);
+
+ rb_define_method(foo, "my_method", other_function, 0);
+}
+ EOF
+
+ klass = util_get_class content, 'foo'
+ other_function = klass.method_list.first
+
+ assert_equal 'my_method', other_function.name
+ assert_equal "a comment for other_function",
+ other_function.comment
+ assert_equal '()', other_function.params
+
+ code = other_function.token_stream.first.text
+
+ assert_equal "#define other_function rb_other_function", code
+ end
+
+ def test_find_body_document_method
+ content = <<-EOF
+/*
+ * Document-method: bar
+ * Document-method: baz
+ *
+ * a comment for bar
+ */
+VALUE
+bar() {
+}
+
+void
+Init_Foo(void) {
+ VALUE foo = rb_define_class("Foo", rb_cObject);
+
+ rb_define_method(foo, "bar", bar, 0);
+ rb_define_method(foo, "baz", bar, 0);
+}
+ EOF
+
+ klass = util_get_class content, 'foo'
+ assert_equal 2, klass.method_list.length
+
+ methods = klass.method_list.sort
+
+ bar = methods.first
+ assert_equal 'Foo#bar', bar.full_name
+ assert_equal "a comment for bar", bar.comment
+
+ baz = methods.last
+ assert_equal 'Foo#baz', baz.full_name
+ assert_equal "a comment for bar", bar.comment
+ end
+
+ def test_look_for_directives_in
+ parser = util_parser ''
+
+ comment = "# :markup: not_rdoc\n"
+
+ parser.look_for_directives_in @top_level, comment
+
+ assert_equal "# :markup: not_rdoc\n", comment
+ assert_equal 'not_rdoc', @top_level.metadata['markup']
+ end
+
+ def test_define_method
+ content = <<-EOF
+/*Method Comment! */
+static VALUE
+rb_io_s_read(argc, argv, io)
+ int argc;
+ VALUE *argv;
+ VALUE io;
+{
+}
+
+void
+Init_IO(void) {
+ /*
+ * a comment for class Foo on rb_define_class
+ */
+ VALUE rb_cIO = rb_define_class("IO", rb_cObject);
+ rb_define_singleton_method(rb_cIO, "read", rb_io_s_read, -1);
+}
+ EOF
+
+ klass = util_get_class content, 'rb_cIO'
+ read_method = klass.method_list.first
+ assert_equal "read", read_method.name
+ assert_equal "Method Comment! ", read_method.comment
+ end
+
+ def test_define_method_private
+ content = <<-EOF
+/*Method Comment! */
+static VALUE
+rb_io_s_read(argc, argv, io)
+ int argc;
+ VALUE *argv;
+ VALUE io;
+{
+}
+
+void
+Init_IO(void) {
+ /*
+ * a comment for class Foo on rb_define_class
+ */
+ VALUE rb_cIO = rb_define_class("IO", rb_cObject);
+ rb_define_private_method(rb_cIO, "read", rb_io_s_read, -1);
+}
+ EOF
+
+ klass = util_get_class content, 'rb_cIO'
+ read_method = klass.method_list.first
+ assert_equal 'IO#read', read_method.full_name
+ assert_equal :private, read_method.visibility
+ assert_equal "Method Comment! ", read_method.comment
+ end
+
+ def util_get_class(content, name)
+ @parser = util_parser content
+ @parser.scan
+ @parser.classes[name]
+ end
+
+ def util_parser(content)
+ RDoc::Parser::C.new @top_level, @fn, content, @options, @stats
+ end
+
+end
+
+MiniTest::Unit.autorun
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_perl.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_perl.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_perl.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,73 @@
+require 'stringio'
+require 'tempfile'
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/options'
+require 'rdoc/parser/perl'
+
+class TestRdocParserPerlPOD < MiniTest::Unit::TestCase
+
+ def setup
+ @tempfile = Tempfile.new self.class.name
+ filename = @tempfile.path
+
+ @top_level = RDoc::TopLevel.new filename
+ @fn = filename
+ @options = RDoc::Options.new
+ @stats = RDoc::Stats.new 0
+ end
+
+ def teardown
+ @tempfile.close
+ end
+
+ def test_uncommented_perl
+ content = <<-EOF
+while (<>) {
+ tr/a-z/A-Z;
+ print
+}
+ EOF
+
+ comment = util_get_comment content
+ assert_equal "", comment
+ end
+
+ def test_perl_without_pod
+ content = <<-EOF
+#!/usr/local/bin/perl
+#
+#This is a pointless perl program because it does -p.
+#
+while(<>) {print;}:
+ EOF
+
+ comment = util_get_comment content
+ assert_equal "", comment
+ end
+
+ def test_simple_pod_no_structure
+ content = <<-EOF
+=begin pod
+
+This just contains plain old documentation
+
+=end
+ EOF
+ comment = util_get_comment content
+ assert_equal 'This just contains plain old documentation', comment
+ end
+
+ # Get the comment of the @top_level when it has processed the input.
+ def util_get_comment(content)
+ parser = util_parser content
+ parser.scan.comment
+ end
+
+ # create a new parser with the supplied content.
+ def util_parser(content)
+ RDoc::Parser::PerlPOD.new @top_level, @fn, content, @options, @stats
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_ruby.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_ruby.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_ruby.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1334 @@
+# coding: utf-8
+
+require 'stringio'
+require 'tempfile'
+require 'rubygems'
+require 'minitest/autorun'
+
+require 'rdoc/options'
+require 'rdoc/parser/ruby'
+require 'rdoc/stats'
+
+class TestRDocParserRuby < MiniTest::Unit::TestCase
+
+ def setup
+ @tempfile = Tempfile.new self.class.name
+ @filename = @tempfile.path
+
+ # Some tests need two paths.
+ @tempfile2 = Tempfile.new self.class.name
+ @filename2 = @tempfile2.path
+
+ util_top_level
+ @options = RDoc::Options.new
+ @options.quiet = true
+ @stats = RDoc::Stats.new 0
+ end
+
+ def teardown
+ @tempfile.close
+ @tempfile2.close
+ end
+
+ def test_look_for_directives_in_attr
+ util_parser ""
+
+ comment = "# :attr: my_attr\n"
+
+ @parser.look_for_directives_in @top_level, comment
+
+ assert_equal "# :attr: my_attr\n", comment
+
+ comment = "# :attr_reader: my_method\n"
+
+ @parser.look_for_directives_in @top_level, comment
+
+ assert_equal "# :attr_reader: my_method\n", comment
+
+ comment = "# :attr_writer: my_method\n"
+
+ @parser.look_for_directives_in @top_level, comment
+
+ assert_equal "# :attr_writer: my_method\n", comment
+ end
+
+ def test_look_for_directives_in_commented
+ util_parser ""
+
+ comment = "# how to make a section:\n# # :section: new section\n"
+
+ @parser.look_for_directives_in @top_level, comment
+
+ section = @top_level.current_section
+ assert_equal nil, section.title
+ assert_equal nil, section.comment
+
+ assert_equal "# how to make a section:\n# # :section: new section\n",
+ comment
+ end
+
+ def test_look_for_directives_in_enddoc
+ util_parser ""
+
+ assert_throws :enddoc do
+ @parser.look_for_directives_in @top_level, "# :enddoc:\n"
+ end
+ end
+
+ def test_look_for_directives_in_main
+ util_parser ""
+
+ @parser.look_for_directives_in @top_level, "# :main: new main page\n"
+
+ assert_equal 'new main page', @options.main_page
+ end
+
+ def test_look_for_directives_in_method
+ util_parser ""
+
+ comment = "# :method: my_method\n"
+
+ @parser.look_for_directives_in @top_level, comment
+
+ assert_equal "# :method: my_method\n", comment
+
+ comment = "# :singleton-method: my_method\n"
+
+ @parser.look_for_directives_in @top_level, comment
+
+ assert_equal "# :singleton-method: my_method\n", comment
+ end
+
+ def test_look_for_directives_in_startdoc
+ util_parser ""
+
+ @top_level.stop_doc
+ assert !@top_level.document_self
+ assert !@top_level.document_children
+ assert !@top_level.force_documentation
+
+ @parser.look_for_directives_in @top_level, "# :startdoc:\n"
+
+ assert @top_level.document_self
+ assert @top_level.document_children
+ assert @top_level.force_documentation
+ end
+
+ def test_look_for_directives_in_stopdoc
+ util_parser ""
+
+ assert @top_level.document_self
+ assert @top_level.document_children
+
+ @parser.look_for_directives_in @top_level, "# :stopdoc:\n"
+
+ assert !@top_level.document_self
+ assert !@top_level.document_children
+ end
+
+ def test_look_for_directives_in_section
+ util_parser ""
+
+ comment = "# :section: new section\n# woo stuff\n"
+
+ @parser.look_for_directives_in @top_level, comment
+
+ section = @top_level.current_section
+ assert_equal 'new section', section.title
+ assert_equal "# woo stuff\n", section.comment
+
+ assert_equal '', comment
+ end
+
+ def test_look_for_directives_in_title
+ util_parser ""
+
+ @parser.look_for_directives_in @top_level, "# :title: new title\n"
+
+ assert_equal 'new title', @options.title
+ end
+
+ def test_look_for_directives_in_unhandled
+ util_parser ""
+
+ @parser.look_for_directives_in @top_level, "# :unhandled: blah\n"
+
+ assert_equal 'blah', @top_level.metadata['unhandled']
+ end
+
+ def test_parse_alias
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ util_parser "alias :next= :bar"
+
+ tk = @parser.get_tk
+
+ alas = @parser.parse_alias klass, RDoc::Parser::Ruby::NORMAL, tk, 'comment'
+
+ assert_equal 'bar', alas.old_name
+ assert_equal 'next=', alas.new_name
+ assert_equal klass, alas.parent
+ assert_equal 'comment', alas.comment
+ end
+
+ def test_parse_alias_meta
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ util_parser "alias m.chop m"
+
+ tk = @parser.get_tk
+
+ alas = @parser.parse_alias klass, RDoc::Parser::Ruby::NORMAL, tk, 'comment'
+
+ assert_nil alas
+ end
+
+ def test_parse_attr
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# my attr\n"
+
+ util_parser "attr :foo, :bar"
+
+ tk = @parser.get_tk
+
+ @parser.parse_attr klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ assert_equal 1, klass.attributes.length
+
+ foo = klass.attributes.first
+ assert_equal 'foo', foo.name
+ assert_equal 'my attr', foo.comment
+ end
+
+ def test_parse_attr_accessor
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# my attr\n"
+
+ util_parser "attr_accessor :foo, :bar"
+
+ tk = @parser.get_tk
+
+ @parser.parse_attr_accessor klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ assert_equal 2, klass.attributes.length
+
+ foo = klass.attributes.first
+ assert_equal 'foo', foo.name
+ assert_equal 'RW', foo.rw
+ assert_equal 'my attr', foo.comment
+
+ bar = klass.attributes.last
+ assert_equal 'bar', bar.name
+ assert_equal 'RW', bar.rw
+ assert_equal 'my attr', bar.comment
+ end
+
+ def test_parse_attr_accessor_writer
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# my attr\n"
+
+ util_parser "attr_writer :foo, :bar"
+
+ tk = @parser.get_tk
+
+ @parser.parse_attr_accessor klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ assert_equal 2, klass.attributes.length
+
+ foo = klass.attributes.first
+ assert_equal 'foo', foo.name
+ assert_equal 'W', foo.rw
+ assert_equal "my attr", foo.comment
+
+ bar = klass.attributes.last
+ assert_equal 'bar', bar.name
+ assert_equal 'W', bar.rw
+ assert_equal "my attr", bar.comment
+ end
+
+ def test_parse_meta_attr
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# :attr: \n# my method\n"
+
+ util_parser "add_my_method :foo, :bar"
+
+ tk = @parser.get_tk
+
+ @parser.parse_meta_attr klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ assert_equal 2, klass.attributes.length
+ foo = klass.attributes.first
+ assert_equal 'foo', foo.name
+ assert_equal 'RW', foo.rw
+ assert_equal "my method", foo.comment
+ end
+
+ def test_parse_meta_attr_accessor
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# :attr_accessor: \n# my method\n"
+
+ util_parser "add_my_method :foo, :bar"
+
+ tk = @parser.get_tk
+
+ @parser.parse_meta_attr klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ assert_equal 2, klass.attributes.length
+ foo = klass.attributes.first
+ assert_equal 'foo', foo.name
+ assert_equal 'RW', foo.rw
+ assert_equal 'my method', foo.comment
+ end
+
+ def test_parse_meta_attr_named
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# :attr: foo\n# my method\n"
+
+ util_parser "add_my_method :foo, :bar"
+
+ tk = @parser.get_tk
+
+ @parser.parse_meta_attr klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ assert_equal 1, klass.attributes.length
+ foo = klass.attributes.first
+ assert_equal 'foo', foo.name
+ assert_equal 'RW', foo.rw
+ assert_equal 'my method', foo.comment
+ end
+
+ def test_parse_meta_attr_reader
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# :attr_reader: \n# my method\n"
+
+ util_parser "add_my_method :foo, :bar"
+
+ tk = @parser.get_tk
+
+ @parser.parse_meta_attr klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.attributes.first
+ assert_equal 'foo', foo.name
+ assert_equal 'R', foo.rw
+ assert_equal 'my method', foo.comment
+ end
+
+ def test_parse_meta_attr_writer
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# :attr_writer: \n# my method\n"
+
+ util_parser "add_my_method :foo, :bar"
+
+ tk = @parser.get_tk
+
+ @parser.parse_meta_attr klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.attributes.first
+ assert_equal 'foo', foo.name
+ assert_equal 'W', foo.rw
+ assert_equal "my method", foo.comment
+ end
+
+ def test_parse_class
+ comment = "##\n# my method\n"
+
+ util_parser 'class Foo; end'
+
+ tk = @parser.get_tk
+
+ @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = @top_level.classes.first
+ assert_equal 'Foo', foo.full_name
+ assert_equal 'my method', foo.comment
+ end
+
+ def test_parse_class_ghost_method
+ util_parser <<-CLASS
+class Foo
+ ##
+ # :method: blah
+ # my method
+end
+ CLASS
+
+ tk = @parser.get_tk
+
+ @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
+
+ foo = @top_level.classes.first
+ assert_equal 'Foo', foo.full_name
+
+ blah = foo.method_list.first
+ assert_equal 'Foo#blah', blah.full_name
+ end
+
+ def test_parse_class_nested_superclass
+ foo = RDoc::NormalModule.new 'Foo'
+ foo.parent = @top_level
+
+ util_parser "class Bar < Super\nend"
+
+ tk = @parser.get_tk
+
+ @parser.parse_class foo, RDoc::Parser::Ruby::NORMAL, tk, ''
+
+ bar = foo.classes.first
+ assert_equal 'Super', bar.superclass
+ end
+
+ def test_parse_module
+ comment = "##\n# my module\n"
+
+ util_parser 'module Foo; end'
+
+ tk = @parser.get_tk
+
+ @parser.parse_module @top_level, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = @top_level.modules.first
+ assert_equal 'Foo', foo.full_name
+ assert_equal 'my module', foo.comment
+ end
+
+ def test_parse_class_colon3
+ code = <<-CODE
+class A
+ class ::B
+ end
+end
+ CODE
+
+ util_parser code
+
+ @parser.parse_class @top_level, false, @parser.get_tk, ''
+
+ assert_equal %w[A B], RDoc::TopLevel.classes.map { |c| c.full_name }
+ end
+
+ def test_parse_class_single
+ code = <<-CODE
+class A
+ class << B
+ end
+end
+ CODE
+
+ util_parser code
+
+ @parser.parse_class @top_level, false, @parser.get_tk, ''
+
+ assert_equal %w[A], RDoc::TopLevel.classes.map { |c| c.full_name }
+ assert_equal %w[A::B], RDoc::TopLevel.modules.map { |c| c.full_name }
+ end
+
+ def test_parse_class_mistaken_for_module
+ # The code below is not strictly legal Ruby (Foo must have been defined
+ # before Foo::Bar is encountered), but RDoc might encounter Foo::Bar
+ # before Foo if they live in different files.
+
+ code = <<-EOF
+class Foo::Bar
+end
+
+module Foo::Baz
+end
+
+class Foo
+end
+ EOF
+
+ util_parser code
+
+ @parser.scan
+
+ assert_equal %w[Foo::Baz], RDoc::TopLevel.modules_hash.keys
+ assert_empty @top_level.modules
+
+ foo = @top_level.classes.first
+ assert_equal 'Foo', foo.full_name
+
+ bar = foo.classes.first
+ assert_equal 'Foo::Bar', bar.full_name
+
+ baz = foo.modules.first
+ assert_equal 'Foo::Baz', baz.full_name
+ end
+
+ def test_parse_class_definition_encountered_after_class_reference
+ # The code below is not strictly legal Ruby (Foo must have been defined
+ # before Foo.bar is encountered), but RDoc might encounter Foo.bar before
+ # Foo if they live in different files.
+
+ code = <<-EOF
+def Foo.bar
+end
+
+class Foo < IO
+end
+ EOF
+
+ util_parser code
+
+ @parser.scan
+
+ assert_empty RDoc::TopLevel.modules_hash
+ # HACK why does it fail?
+ #assert_empty @top_level.modules
+
+ foo = @top_level.classes.first
+ assert_equal 'Foo', foo.full_name
+ assert_equal 'IO', foo.superclass
+
+ bar = foo.method_list.first
+ assert_equal 'bar', bar.name
+ end
+
+ def test_parse_module_relative_to_top_level_namespace
+ comment = <<-EOF
+#
+# Weirdly named module
+#
+EOF
+
+ code = comment + <<-EOF
+module ::Foo
+ class Helper
+ end
+end
+EOF
+
+ util_parser code
+ @parser.scan()
+
+ foo = @top_level.modules.first
+ assert_equal 'Foo', foo.full_name
+ assert_equal 'Weirdly named module', foo.comment
+
+ helper = foo.classes.first
+ assert_equal 'Foo::Helper', helper.full_name
+ end
+
+ def test_parse_comment_attr
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# :attr: foo\n# my attr\n"
+
+ util_parser "\n"
+
+ tk = @parser.get_tk
+
+ @parser.parse_comment klass, tk, comment
+
+ foo = klass.attributes.first
+ assert_equal 'foo', foo.name
+ assert_equal 'RW', foo.rw
+ assert_equal 'my attr', foo.comment
+
+ assert_equal nil, foo.viewer
+ assert_equal true, foo.document_children
+ assert_equal true, foo.document_self
+ assert_equal false, foo.done_documenting
+ assert_equal false, foo.force_documentation
+ assert_equal klass, foo.parent
+ assert_equal :public, foo.visibility
+ assert_equal "\n", foo.text
+ assert_equal klass.current_section, foo.section
+ end
+
+ def test_parse_comment_method
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# :method: foo\n# my method\n"
+
+ util_parser "\n"
+
+ tk = @parser.get_tk
+
+ @parser.parse_comment klass, tk, comment
+
+ foo = klass.method_list.first
+ assert_equal 'foo', foo.name
+ assert_equal 'my method', foo.comment
+
+ assert_equal [], foo.aliases
+ assert_equal nil, foo.block_params
+ assert_equal nil, foo.call_seq
+ assert_equal nil, foo.is_alias_for
+ assert_equal nil, foo.viewer
+ assert_equal true, foo.document_children
+ assert_equal true, foo.document_self
+ assert_equal '', foo.params
+ assert_equal false, foo.done_documenting
+ assert_equal false, foo.dont_rename_initialize
+ assert_equal false, foo.force_documentation
+ assert_equal klass, foo.parent
+ assert_equal false, foo.singleton
+ assert_equal :public, foo.visibility
+ assert_equal "\n", foo.text
+ assert_equal klass.current_section, foo.section
+
+ stream = [
+ tk(:COMMENT, 1, 1, nil, "# File #{@top_level.absolute_name}, line 1"),
+ RDoc::Parser::Ruby::NEWLINE_TOKEN,
+ tk(:SPACE, 1, 1, nil, ''),
+ ]
+
+ assert_equal stream, foo.token_stream
+ end
+
+ def test_parse_constant_alias
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+ cB = klass.add_class RDoc::NormalClass, 'B'
+
+ util_parser "A = B"
+
+ tk = @parser.get_tk
+
+ @parser.parse_constant klass, tk, ''
+
+ assert_equal cB, klass.find_module_named('A')
+ end
+
+ def test_parse_constant_alias_same_name
+ foo = @top_level.add_class RDoc::NormalClass, 'Foo'
+ top_bar = @top_level.add_class RDoc::NormalClass, 'Bar'
+ bar = foo.add_class RDoc::NormalClass, 'Bar'
+
+ assert RDoc::TopLevel.find_class_or_module('::Bar')
+
+ util_parser "A = ::Bar"
+
+ tk = @parser.get_tk
+
+ @parser.parse_constant foo, tk, ''
+
+ assert_equal top_bar, bar.find_module_named('A')
+ end
+
+ def test_parse_meta_method
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# my method\n"
+
+ util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
+
+ tk = @parser.get_tk
+
+ @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.method_list.first
+ assert_equal 'foo', foo.name
+ assert_equal 'my method', foo.comment
+
+ assert_equal [], foo.aliases
+ assert_equal nil, foo.block_params
+ assert_equal nil, foo.call_seq
+ assert_equal true, foo.document_children
+ assert_equal true, foo.document_self
+ assert_equal false, foo.done_documenting
+ assert_equal false, foo.dont_rename_initialize
+ assert_equal false, foo.force_documentation
+ assert_equal nil, foo.is_alias_for
+ assert_equal '', foo.params
+ assert_equal klass, foo.parent
+ assert_equal false, foo.singleton
+ assert_equal 'add_my_method :foo', foo.text
+ assert_equal nil, foo.viewer
+ assert_equal :public, foo.visibility
+ assert_equal klass.current_section, foo.section
+
+ stream = [
+ tk(:COMMENT, 1, 1, nil, "# File #{@top_level.absolute_name}, line 1"),
+ RDoc::Parser::Ruby::NEWLINE_TOKEN,
+ tk(:SPACE, 1, 1, nil, ''),
+ tk(:IDENTIFIER, 1, 0, 'add_my_method', 'add_my_method'),
+ tk(:SPACE, 1, 13, nil, ' '),
+ tk(:SYMBOL, 1, 14, nil, ':foo'),
+ tk(:COMMA, 1, 18, nil, ','),
+ tk(:SPACE, 1, 19, nil, ' '),
+ tk(:SYMBOL, 1, 20, nil, ':bar'),
+ tk(:NL, 1, 24, nil, "\n"),
+ ]
+
+ assert_equal stream, foo.token_stream
+ end
+
+ def test_parse_meta_method_name
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# :method: woo_hoo!\n# my method\n"
+
+ util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
+
+ tk = @parser.get_tk
+
+ @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.method_list.first
+ assert_equal 'woo_hoo!', foo.name
+ assert_equal 'my method', foo.comment
+ end
+
+ def test_parse_meta_method_singleton
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# :singleton-method:\n# my method\n"
+
+ util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
+
+ tk = @parser.get_tk
+
+ @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.method_list.first
+ assert_equal 'foo', foo.name
+ assert_equal true, foo.singleton, 'singleton method'
+ assert_equal 'my method', foo.comment
+ end
+
+ def test_parse_meta_method_singleton_name
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# :singleton-method: woo_hoo!\n# my method\n"
+
+ util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
+
+ tk = @parser.get_tk
+
+ @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.method_list.first
+ assert_equal 'woo_hoo!', foo.name
+ assert_equal true, foo.singleton, 'singleton method'
+ assert_equal 'my method', foo.comment
+ end
+
+ def test_parse_meta_method_string_name
+ klass = RDoc::NormalClass.new 'Foo'
+ comment = "##\n# my method\n"
+
+ util_parser "add_my_method 'foo'"
+
+ tk = @parser.get_tk
+
+ @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.method_list.first
+ assert_equal 'foo', foo.name
+ assert_equal 'my method', foo.comment
+ end
+
+ def test_parse_meta_method_unknown
+ klass = RDoc::NormalClass.new 'Foo'
+ comment = "##\n# my method\n"
+
+ util_parser "add_my_method ('foo')"
+
+ tk = @parser.get_tk
+
+ @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.method_list.first
+ assert_equal 'unknown', foo.name
+ assert_equal 'my method', foo.comment
+ end
+
+ def test_parse_method
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# my method\n"
+
+ util_parser "def foo() :bar end"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.method_list.first
+ assert_equal 'foo', foo.name
+ assert_equal 'my method', foo.comment
+
+ assert_equal [], foo.aliases
+ assert_equal nil, foo.block_params
+ assert_equal nil, foo.call_seq
+ assert_equal nil, foo.is_alias_for
+ assert_equal nil, foo.viewer
+ assert_equal true, foo.document_children
+ assert_equal true, foo.document_self
+ assert_equal '()', foo.params
+ assert_equal false, foo.done_documenting
+ assert_equal false, foo.dont_rename_initialize
+ assert_equal false, foo.force_documentation
+ assert_equal klass, foo.parent
+ assert_equal false, foo.singleton
+ assert_equal :public, foo.visibility
+ assert_equal 'def foo', foo.text
+ assert_equal klass.current_section, foo.section
+
+ stream = [
+ tk(:COMMENT, 1, 1, nil, "# File #{@top_level.absolute_name}, line 1"),
+ RDoc::Parser::Ruby::NEWLINE_TOKEN,
+ tk(:SPACE, 1, 1, nil, ''),
+ tk(:DEF, 1, 0, 'def', 'def'),
+ tk(:SPACE, 1, 3, nil, ' '),
+ tk(:IDENTIFIER, 1, 4, 'foo', 'foo'),
+ tk(:LPAREN, 1, 7, nil, '('),
+ tk(:RPAREN, 1, 8, nil, ')'),
+ tk(:SPACE, 1, 9, nil, ' '),
+ tk(:COLON, 1, 10, nil, ':'),
+ tk(:IDENTIFIER, 1, 11, 'bar', 'bar'),
+ tk(:SPACE, 1, 14, nil, ' '),
+ tk(:END, 1, 15, 'end', 'end'),
+ ]
+
+ assert_equal stream, foo.token_stream
+ end
+
+ def test_parse_method_alias
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ util_parser "def m() alias a b; end"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+
+ assert klass.aliases.empty?
+ end
+
+ def test_parse_method_utf8
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# my method\n"
+
+ method = "def ω() end"
+
+ assert_equal Encoding::UTF_8, method.encoding if defined? ::Encoding
+
+ util_parser method
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ omega = klass.method_list.first
+ assert_equal "def \317\211", omega.text
+ end
+
+ def test_parse_method_funky
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# my method\n"
+
+ util_parser "def (blah).foo() :bar end"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ assert klass.method_list.empty?
+ end
+
+ def test_parse_method_internal_ivar
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ util_parser "def foo() def @blah.bar() end end"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+
+ assert_equal 1, klass.method_list.length
+ end
+
+ def test_parse_method_internal_lvar
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ util_parser "def foo() def blah.bar() end end"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+
+ assert_equal 1, klass.method_list.length
+ end
+
+ def test_parse_method_no_parens
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# my method\n"
+
+ util_parser "def foo arg1, arg2\nend"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.method_list.first
+ assert_equal '(arg1, arg2)', foo.params
+ end
+
+ def test_parse_method_parameters_comment
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# my method\n"
+
+ util_parser "def foo arg1, arg2 # some useful comment\nend"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.method_list.first
+ assert_equal '(arg1, arg2)', foo.params
+ end
+
+ def test_parse_method_parameters_comment_continue
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ comment = "##\n# my method\n"
+
+ util_parser "def foo arg1, arg2, # some useful comment\narg3\nend"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.method_list.first
+ assert_equal '(arg1, arg2, arg3)', foo.params
+ end
+
+ def test_parse_method_toplevel
+ klass = @top_level
+
+ comment = "##\n# my method\n"
+
+ util_parser "def foo arg1, arg2\nend"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ object = RDoc::TopLevel.find_class_named 'Object'
+
+ foo = object.method_list.first
+ assert_equal 'Object#foo', foo.full_name
+ end
+
+ def test_parse_method_toplevel_class
+ klass = @top_level
+
+ util_parser "def Object.foo arg1, arg2\nend"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+
+ object = RDoc::TopLevel.find_class_named 'Object'
+
+ foo = object.method_list.first
+ assert_equal 'Object::foo', foo.full_name
+ end
+
+ def test_parse_statements_class_if
+ comment = "##\n# my method\n"
+
+ util_parser <<-CODE
+module Foo
+ X = if TRUE then
+ ''
+ end
+
+ def blah
+ end
+end
+ CODE
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ foo = @top_level.modules.first
+ assert_equal 'Foo', foo.full_name, 'module Foo'
+
+ methods = foo.method_list
+ assert_equal 1, methods.length
+ assert_equal 'Foo#blah', methods.first.full_name
+ end
+
+ def test_parse_statements_class_nested
+ comment = "##\n# my method\n"
+
+ util_parser "module Foo\n#{comment}class Bar\nend\nend"
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ foo = @top_level.modules.first
+ assert_equal 'Foo', foo.full_name, 'module Foo'
+
+ bar = foo.classes.first
+ assert_equal 'Foo::Bar', bar.full_name, 'class Foo::Bar'
+ assert_equal 'my method', bar.comment
+ end
+
+ def test_parse_statements_identifier_meta_method
+ content = <<-EOF
+class Foo
+ ##
+ # this is my method
+ add_my_method :foo
+end
+ EOF
+
+ util_parser content
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ foo = @top_level.classes.first.method_list.first
+ assert_equal 'foo', foo.name
+ end
+
+ def test_parse_statements_identifier_alias_method
+ content = "class Foo def foo() end; alias_method :foo2, :foo end"
+
+ util_parser content
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ foo = @top_level.classes.first.method_list[0]
+ assert_equal 'foo', foo.name
+
+ foo2 = @top_level.classes.first.method_list.last
+ assert_equal 'foo2', foo2.name
+ assert_equal 'foo', foo2.is_alias_for.name
+ assert @top_level.classes.first.aliases.empty?
+ end
+
+ def test_parse_statements_identifier_alias_method_before_original_method
+ # This is not strictly legal Ruby code, but it simulates finding an alias
+ # for a method before finding the original method, which might happen
+ # to rdoc if the alias is in a different file than the original method
+ # and rdoc processes the alias' file first.
+ content = <<-EOF
+class Foo
+ alias_method :foo2, :foo
+
+ alias_method :foo3, :foo
+
+ def foo()
+ end
+
+ alias_method :foo4, :foo
+
+ alias_method :foo5, :unknown
+end
+EOF
+
+ util_parser content
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ foo = @top_level.classes.first.method_list[0]
+ assert_equal 'foo', foo.name
+
+ foo2 = @top_level.classes.first.method_list[1]
+ assert_equal 'foo2', foo2.name
+ assert_equal 'foo', foo2.is_alias_for.name
+
+ foo3 = @top_level.classes.first.method_list[2]
+ assert_equal 'foo3', foo3.name
+ assert_equal 'foo', foo3.is_alias_for.name
+
+ foo4 = @top_level.classes.first.method_list.last
+ assert_equal 'foo4', foo4.name
+ assert_equal 'foo', foo4.is_alias_for.name
+
+ assert_equal 'unknown', @top_level.classes.first.aliases[0].old_name
+ end
+
+ def test_parse_statements_identifier_constant
+ content = <<-EOF
+class Foo
+ FIRST_CONSTANT = 5
+
+ SECOND_CONSTANT = [
+ 1,
+ 2,
+ 3
+ ]
+
+ THIRD_CONSTANT = {
+ :foo => 'bar',
+ :x => 'y'
+ }
+
+ FOURTH_CONSTANT = SECOND_CONSTANT.map do |element|
+ element + 1
+ element + 2
+ end
+
+ FIFTH_CONSTANT = SECOND_CONSTANT.map { |element| element + 1 }
+end
+EOF
+
+ util_parser content
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ constants = @top_level.classes.first.constants
+
+ constant = constants[0]
+ assert_equal 'FIRST_CONSTANT', constant.name
+ assert_equal '5', constant.value
+
+ constant = constants[1]
+ assert_equal 'SECOND_CONSTANT', constant.name
+ assert_equal '[ 1, 2, 3 ]', constant.value
+
+ constant = constants[2]
+ assert_equal 'THIRD_CONSTANT', constant.name
+ assert_equal "{ :foo => 'bar', :x => 'y' }", constant.value
+
+ constant = constants[3]
+ assert_equal 'FOURTH_CONSTANT', constant.name
+ assert_equal 'SECOND_CONSTANT.map do |element| element + 1 element + 2 end', constant.value
+
+ constant = constants.last
+ assert_equal 'FIFTH_CONSTANT', constant.name
+ assert_equal 'SECOND_CONSTANT.map { |element| element + 1 }', constant.value
+ end
+
+ def test_parse_statements_identifier_attr
+ content = "class Foo; attr :foo; end"
+
+ util_parser content
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ foo = @top_level.classes.first.attributes.first
+ assert_equal 'foo', foo.name
+ assert_equal 'R', foo.rw
+ end
+
+ def test_parse_statements_identifier_attr_accessor
+ content = "class Foo; attr_accessor :foo; end"
+
+ util_parser content
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ foo = @top_level.classes.first.attributes.first
+ assert_equal 'foo', foo.name
+ assert_equal 'RW', foo.rw
+ end
+
+ def test_parse_statements_identifier_include
+ content = "class Foo; include Bar; end"
+
+ util_parser content
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ foo = @top_level.classes.first
+ assert_equal 'Foo', foo.name
+ assert_equal 1, foo.includes.length
+ end
+
+ def test_parse_statements_identifier_module_function
+ content = "module Foo def foo() end; module_function :foo; end"
+
+ util_parser content
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ foo, s_foo = @top_level.modules.first.method_list
+ assert_equal 'foo', foo.name, 'instance method name'
+ assert_equal :private, foo.visibility, 'instance method visibility'
+ assert_equal false, foo.singleton, 'instance method singleton'
+
+ assert_equal 'foo', s_foo.name, 'module function name'
+ assert_equal :public, s_foo.visibility, 'module function visibility'
+ assert_equal true, s_foo.singleton, 'module function singleton'
+ end
+
+ def test_parse_statements_identifier_private
+ content = "class Foo private; def foo() end end"
+
+ util_parser content
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ foo = @top_level.classes.first.method_list.first
+ assert_equal 'foo', foo.name
+ assert_equal :private, foo.visibility
+ end
+
+ def test_parse_statements_identifier_require
+ content = "require 'bar'"
+
+ util_parser content
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ assert_equal 1, @top_level.requires.length
+ end
+
+ def test_parse_statements_while_begin
+ util_parser <<-RUBY
+class A
+ def a
+ while begin a; b end
+ end
+ end
+
+ def b
+ end
+end
+ RUBY
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+
+ c_a = @top_level.classes.first
+ assert_equal 'A', c_a.full_name
+
+ assert_equal 1, @top_level.classes.length
+
+ m_a = c_a.method_list.first
+ m_b = c_a.method_list.last
+
+ assert_equal 'A#a', m_a.full_name
+ assert_equal 'A#b', m_b.full_name
+ end
+
+ def test_parse_top_level_statements_alias_method
+ content = <<-CONTENT
+class A
+ alias_method :a, :[] unless c
+end
+
+B = A
+
+class C
+end
+ CONTENT
+
+ util_parser content
+
+ @parser.parse_statements @top_level
+ end
+
+ def test_sanity_integer
+ util_parser '1'
+ assert_equal '1', @parser.get_tk.text
+
+ util_parser '1.0'
+ assert_equal '1.0', @parser.get_tk.text
+ end
+
+ def test_sanity_interpolation
+ last_tk = nil
+ util_parser 'class A; B = "#{c}"; end'
+
+ while tk = @parser.get_tk do last_tk = tk end
+
+ assert_equal "\n", last_tk.text
+ end
+
+ # If you're writing code like this you're doing it wrong
+
+ def test_sanity_interpolation_crazy
+ last_tk = nil
+ util_parser '"#{"#{"a")}" if b}"'
+
+ assert_equal '"#{"#{"a")}" if b}"', @parser.get_tk.text
+ assert_equal RDoc::RubyToken::TkNL, @parser.get_tk.class
+ end
+
+ def test_sanity_interpolation_curly
+ last_tk = nil
+ util_parser '%{ #{} }'
+
+ assert_equal '%{ #{} }', @parser.get_tk.text
+ assert_equal RDoc::RubyToken::TkNL, @parser.get_tk.class
+ end
+
+ def test_sanity_interpolation_format
+ util_parser '"#{stftime("%m-%d")}"'
+
+ while tk = @parser.get_tk do end
+ end
+
+ def test_sanity_symbol_interpolation
+ util_parser ':"#{bar}="'
+
+ while tk = @parser.get_tk do end
+ end
+
+ def tk(klass, line, char, name, text)
+ klass = RDoc::RubyToken.const_get "Tk#{klass.to_s.upcase}"
+
+ token = if klass.instance_method(:initialize).arity == 3 then
+ raise ArgumentError, "name not used for #{klass}" unless name.nil?
+ klass.new nil, line, char
+ else
+ klass.new nil, line, char, name
+ end
+
+ token.set_text text
+
+ token
+ end
+
+ def util_parser(content)
+ @parser = RDoc::Parser::Ruby.new @top_level, @filename, content, @options,
+ @stats
+ end
+
+ def util_two_parsers(first_file_content, second_file_content)
+ util_parser first_file_content
+
+ @parser2 = RDoc::Parser::Ruby.new @top_level2, @filename,
+ second_file_content, @options, @stats
+ end
+
+ def util_top_level
+ RDoc::TopLevel.reset
+ @top_level = RDoc::TopLevel.new @filename
+ @top_level2 = RDoc::TopLevel.new @filename2
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_simple.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_simple.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_parser_simple.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,75 @@
+require 'tempfile'
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/options'
+require 'rdoc/parser'
+
+class TestRDocParserSimple < MiniTest::Unit::TestCase
+
+ def setup
+ @tempfile = Tempfile.new self.class.name
+ filename = @tempfile.path
+
+ @top_level = RDoc::TopLevel.new filename
+ @fn = filename
+ @options = RDoc::Options.new
+ @stats = RDoc::Stats.new 0
+
+ RDoc::TopLevel.reset
+ end
+
+ def teardown
+ @tempfile.close
+ end
+
+ def test_initialize_metadata
+ parser = util_parser ":unhandled: \n"
+
+ assert_includes @top_level.metadata, 'unhandled'
+
+ assert_equal ":unhandled: \n", parser.content
+ end
+
+ def test_remove_coding_comment
+ parser = util_parser <<-TEXT
+# -*- mode: rdoc; coding: utf-8; fill-column: 74; -*-
+
+Regular expressions (<i>regexp</i>s) are patterns which describe the
+contents of a string.
+ TEXT
+
+ parser.scan
+
+ expected = <<-TEXT.strip
+
+Regular expressions (<i>regexp</i>s) are patterns which describe the
+contents of a string.
+ TEXT
+
+ assert_equal expected, @top_level.comment
+ end
+
+ def test_remove_private_comments
+ parser = util_parser ''
+ text = "foo\n\n--\nbar\n++\n\nbaz\n"
+
+ expected = "foo\n\n\n\nbaz\n"
+
+ assert_equal expected, parser.remove_private_comments(text)
+ end
+
+ def test_remove_private_comments_star
+ parser = util_parser ''
+
+ text = "* foo\n* bar\n"
+ expected = text.dup
+
+ assert_equal expected, parser.remove_private_comments(text)
+ end
+
+ def util_parser(content)
+ RDoc::Parser::Simple.new @top_level, @fn, content, @options, @stats
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_rdoc.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_rdoc.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_rdoc.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,165 @@
+require 'tempfile'
+require 'tmpdir'
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/rdoc'
+
+class TestRDocRDoc < MiniTest::Unit::TestCase
+
+ def setup
+ @rdoc = RDoc::RDoc.new
+ @tempfile = Tempfile.new 'test_rdoc_rdoc'
+ @tempfile.binmode
+ end
+
+ def teardown
+ @tempfile.close rescue nil # HACK for 1.8.6
+ end
+
+ def test_gather_files
+ file = File.expand_path __FILE__
+ assert_equal [file], @rdoc.gather_files([file, file])
+ end
+
+ def test_normalized_file_list
+ files = @rdoc.normalized_file_list [__FILE__]
+
+ files = files.map { |file| File.expand_path file }
+
+ assert_equal [File.expand_path(__FILE__)], files
+ end
+
+ def test_normalized_file_list_not_modified
+ files = [__FILE__]
+
+ @rdoc.last_modified[__FILE__] = File.stat(__FILE__).mtime
+
+ files = @rdoc.normalized_file_list [__FILE__]
+
+ assert_empty files
+ end
+
+ def test_read_file_contents
+ @tempfile.write "hi everybody"
+ @tempfile.flush
+
+ assert_equal "hi everybody", @rdoc.read_file_contents(@tempfile.path)
+ end
+
+ def test_read_file_contents_encoding
+ skip "Encoding not implemented" unless defined? ::Encoding
+
+ @tempfile.write "# coding: utf-8\nhi everybody"
+ @tempfile.flush
+
+ contents = @rdoc.read_file_contents @tempfile.path
+ assert_equal "# coding: utf-8\nhi everybody", contents
+ assert_equal Encoding::UTF_8, contents.encoding
+ end
+
+ def test_read_file_contents_encoding_fancy
+ skip "Encoding not implemented" unless defined? ::Encoding
+
+ @tempfile.write "# -*- coding: utf-8; fill-column: 74 -*-\nhi everybody"
+ @tempfile.flush
+
+ contents = @rdoc.read_file_contents @tempfile.path
+ assert_equal("# -*- coding: utf-8; fill-column: 74 -*-\nhi everybody",
+ contents)
+ assert_equal Encoding::UTF_8, contents.encoding
+ end
+
+ def test_read_file_contents_encoding_with_signature
+ skip "Encoding not implemented" unless defined? ::Encoding
+
+ @tempfile.write "\xEF\xBB\xBF""hi everybody"
+ @tempfile.flush
+
+ bug3360 = '[ruby-dev:41452]'
+ contents = @rdoc.read_file_contents @tempfile.path
+ assert_equal "hi everybody", contents, bug3360
+ assert_equal Encoding::UTF_8, contents.encoding, bug3360
+ end
+
+ def test_remove_unparsable
+ file_list = %w[
+ blah.class
+ blah.eps
+ blah.erb
+ blah.scpt.txt
+ blah.ttf
+ blah.yml
+ ]
+
+ assert_empty @rdoc.remove_unparseable file_list
+ end
+
+ def test_setup_output_dir
+ skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
+
+ Dir.mktmpdir {|d|
+ path = File.join(d, 'testdir')
+
+ last = @rdoc.setup_output_dir path, false
+
+ assert_empty last
+
+ assert File.directory? path
+ }
+ end
+
+ def test_setup_output_dir_exists
+ skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
+
+ Dir.mktmpdir {|path|
+ open @rdoc.output_flag_file(path), 'w' do |io|
+ io.puts Time.at 0
+ io.puts "./lib/rdoc.rb\t#{Time.at 86400}"
+ end
+
+ last = @rdoc.setup_output_dir path, false
+
+ assert_equal 1, last.size
+ assert_equal Time.at(86400), last['./lib/rdoc.rb']
+ }
+ end
+
+ def test_setup_output_dir_exists_empty_created_rid
+ skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
+
+ Dir.mktmpdir {|path|
+ open @rdoc.output_flag_file(path), 'w' do end
+
+ e = assert_raises RDoc::Error do
+ @rdoc.setup_output_dir path, false
+ end
+
+ assert_match %r%Directory #{Regexp.escape path} already exists%, e.message
+ }
+ end
+
+ def test_setup_output_dir_exists_file
+ path = @tempfile.path
+
+ e = assert_raises RDoc::Error do
+ @rdoc.setup_output_dir path, false
+ end
+
+ assert_match(%r%#{Regexp.escape path} exists and is not a directory%,
+ e.message)
+ end
+
+ def test_setup_output_dir_exists_not_rdoc
+ skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
+
+ Dir.mktmpdir do |dir|
+ e = assert_raises RDoc::Error do
+ @rdoc.setup_output_dir dir, false
+ end
+
+ assert_match %r%Directory #{Regexp.escape dir} already exists%, e.message
+ end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_require.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_require.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_require.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,25 @@
+require File.expand_path '../xref_test_case', __FILE__
+
+class TestRDocRequire < XrefTestCase
+
+ def setup
+ super
+
+ @req = RDoc::Require.new 'foo', 'comment'
+ end
+
+ def test_initialize
+ assert_equal 'foo', @req.name
+
+ req = RDoc::Require.new '"foo"', ''
+ assert_equal 'foo', @req.name
+
+ req = RDoc::Require.new '\'foo\'', ''
+ assert_equal 'foo', @req.name
+
+ req = RDoc::Require.new '|foo|', ''
+ assert_equal 'foo', @req.name, 'for fortran?'
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_ri_driver.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_ri_driver.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_ri_driver.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,832 @@
+require 'pp'
+require 'rubygems'
+require 'minitest/autorun'
+require 'tmpdir'
+require 'fileutils'
+require 'rdoc/ri/driver'
+
+class TestRDocRIDriver < MiniTest::Unit::TestCase
+
+ def setup
+ @RM = RDoc::Markup
+
+ @tmpdir = File.join Dir.tmpdir, "test_rdoc_ri_driver_#{$$}"
+ @home_ri = File.join @tmpdir, 'dot_ri'
+
+ FileUtils.mkdir_p @tmpdir
+ FileUtils.mkdir_p @home_ri
+
+ @orig_ri = ENV['RI']
+ @orig_home = ENV['HOME']
+ ENV['HOME'] = @tmpdir
+ ENV.delete 'RI'
+
+ options = RDoc::RI::Driver.process_args []
+ options[:home] = @tmpdir
+ options[:use_stdout] = true
+ options[:formatter] = @RM::ToRdoc
+ @driver = RDoc::RI::Driver.new options
+ end
+
+ def teardown
+ ENV['HOME'] = @orig_home
+ ENV['RI'] = @orig_ri
+ FileUtils.rm_rf @tmpdir
+ end
+
+ DUMMY_PAGER = ":;\n"
+
+ def with_dummy_pager
+ pager_env, ENV['RI_PAGER'] = ENV['RI_PAGER'], DUMMY_PAGER
+ yield
+ ensure
+ ENV['RI_PAGER'] = pager_env
+ end
+
+ def mu_pp(obj)
+ s = ''
+ s = PP.pp obj, s
+ s = s.force_encoding(Encoding.default_external) if defined? Encoding
+ s.chomp
+ end
+
+ def test_self_dump
+ util_store
+
+ out, err = capture_io do
+ RDoc::RI::Driver.dump @store.cache_path
+ end
+
+ assert_match %r%:class_methods%, out
+ assert_match %r%:modules%, out
+ assert_match %r%:instance_methods%, out
+ assert_match %r%:ancestors%, out
+ end
+
+ def test_add_also_in_empty
+ out = @RM::Document.new
+
+ @driver.add_also_in out, []
+
+ assert_empty out
+ end
+
+ def test_add_also_in
+ util_multi_store
+ @store1.type = :system
+ @store2.type = :home
+
+ out = @RM::Document.new
+
+ @driver.add_also_in out, [@store1, @store2]
+
+ expected = @RM::Document.new(
+ @RM::Rule.new(1),
+ @RM::Paragraph.new('Also found in:'),
+ @RM::Verbatim.new(' ', 'ruby core', "\n",
+ ' ', '~/.ri', "\n"))
+
+ assert_equal expected, out
+ end
+
+ def test_add_class
+ util_multi_store
+
+ out = @RM::Document.new
+
+ @driver.add_class out, 'Bar', [@cBar]
+
+ expected = @RM::Document.new(
+ @RM::Heading.new(1, 'Bar < Foo'),
+ @RM::BlankLine.new)
+
+ assert_equal expected, out
+ end
+
+ def test_add_from
+ util_store
+ @store.type = :system
+
+ out = @RM::Document.new
+
+ @driver.add_from out, @store
+
+ expected = @RM::Document.new @RM::Paragraph.new("(from ruby core)")
+
+ assert_equal expected, out
+ end
+
+ def test_add_includes_empty
+ out = @RM::Document.new
+
+ @driver.add_includes out, []
+
+ assert_empty out
+ end
+
+ def test_add_includes_many
+ util_store
+
+ out = @RM::Document.new
+
+ enum = RDoc::Include.new 'Enumerable', nil
+ @cFoo.add_include enum
+
+ @driver.add_includes out, [[[@cFooInc, enum], @store]]
+
+ expected = @RM::Document.new(
+ @RM::Rule.new(1),
+ @RM::Heading.new(1, "Includes:"),
+ @RM::Paragraph.new("(from #{@store.friendly_path})"),
+ @RM::BlankLine.new,
+ @RM::Paragraph.new("Inc"),
+ @RM::BlankLine.new,
+ @RM::Paragraph.new("Include thingy"),
+ @RM::BlankLine.new,
+ @RM::Verbatim.new(' ', 'Enumerable', "\n"))
+
+ assert_equal expected, out
+ end
+
+ def test_add_includes_many_no_doc
+ util_store
+
+ out = @RM::Document.new
+
+ enum = RDoc::Include.new 'Enumerable', nil
+ @cFoo.add_include enum
+ @cFooInc.instance_variable_set :@comment, ''
+
+ @driver.add_includes out, [[[@cFooInc, enum], @store]]
+
+ expected = @RM::Document.new(
+ @RM::Rule.new(1),
+ @RM::Heading.new(1, "Includes:"),
+ @RM::Paragraph.new("(from #{@store.friendly_path})"),
+ @RM::Verbatim.new(' ', 'Inc', "\n",
+ ' ', 'Enumerable', "\n"))
+
+ assert_equal expected, out
+ end
+
+ def test_add_includes_one
+ util_store
+
+ out = @RM::Document.new
+
+ @driver.add_includes out, [[[@cFooInc], @store]]
+
+ expected = @RM::Document.new(
+ @RM::Rule.new(1),
+ @RM::Heading.new(1, "Includes:"),
+ @RM::Paragraph.new("Inc (from #{@store.friendly_path})"),
+ @RM::BlankLine.new,
+ @RM::Paragraph.new("Include thingy"),
+ @RM::BlankLine.new)
+
+ assert_equal expected, out
+ end
+
+ def test_add_method_list
+ out = @RM::Document.new
+
+ @driver.add_method_list out, %w[new], 'Class methods'
+
+ expected = @RM::Document.new(
+ @RM::Heading.new(1, 'Class methods:'),
+ @RM::BlankLine.new,
+ @RM::Verbatim.new(' ', 'new'),
+ @RM::BlankLine.new)
+
+ assert_equal expected, out
+ end
+
+ def test_add_method_list_none
+ out = @RM::Document.new
+
+ @driver.add_method_list out, nil, 'Class'
+
+ assert_equal @RM::Document.new, out
+ end
+
+ def test_ancestors_of
+ util_ancestors_store
+
+ assert_equal %w[X Mixin Object Foo], @driver.ancestors_of('Foo::Bar')
+ end
+
+ def test_classes
+ util_multi_store
+
+ expected = {
+ 'Ambiguous' => [@store1, @store2],
+ 'Bar' => [@store2],
+ 'Foo' => [@store1],
+ 'Foo::Bar' => [@store1],
+ 'Foo::Baz' => [@store1, @store2],
+ 'Inc' => [@store1],
+ }
+
+ assert_equal expected, @driver.classes
+ end
+
+ def test_complete
+ store = RDoc::RI::Store.new @home_ri
+ store.cache[:ancestors] = {
+ 'Foo' => %w[Object],
+ 'Foo::Bar' => %w[Object],
+ }
+ store.cache[:class_methods] = {
+ 'Foo' => %w[bar]
+ }
+ store.cache[:instance_methods] = {
+ 'Foo' => %w[Bar]
+ }
+ store.cache[:modules] = %w[
+ Foo
+ Foo::Bar
+ ]
+
+ @driver.stores = [store]
+
+ assert_equal %w[Foo Foo::Bar], @driver.complete('F')
+ assert_equal %w[ Foo::Bar], @driver.complete('Foo::B')
+
+ assert_equal %w[Foo#Bar], @driver.complete('Foo#'), 'Foo#'
+ assert_equal %w[Foo#Bar Foo::bar], @driver.complete('Foo.'), 'Foo.'
+ assert_equal %w[Foo::Bar Foo::bar], @driver.complete('Foo::'), 'Foo::'
+ end
+
+ def test_complete_ancestor
+ util_ancestors_store
+
+ assert_equal %w[Foo::Bar#i_method], @driver.complete('Foo::Bar#')
+
+ assert_equal %w[Foo::Bar#i_method Foo::Bar::c_method Foo::Bar::new],
+ @driver.complete('Foo::Bar.')
+ end
+
+ def test_complete_classes
+ util_store
+
+ assert_equal %w[Foo Foo::Bar Foo::Baz], @driver.complete('F')
+ assert_equal %w[Foo:: Foo::Bar Foo::Baz], @driver.complete('Foo::')
+ assert_equal %w[ Foo::Bar Foo::Baz], @driver.complete('Foo::B')
+ end
+
+ def test_complete_multistore
+ util_multi_store
+
+ assert_equal %w[Bar], @driver.complete('B')
+ assert_equal %w[Foo Foo::Bar Foo::Baz], @driver.complete('F')
+ end
+
+ def test_display
+ doc = @RM::Document.new(
+ @RM::Paragraph.new('hi'))
+
+ out, err = capture_io do
+ @driver.display doc
+ end
+
+ assert_equal "hi\n", out
+ end
+
+ def test_display_class
+ util_store
+
+ out, err = capture_io do
+ @driver.display_class 'Foo::Bar'
+ end
+
+ assert_match %r%^= Foo::Bar%, out
+ assert_match %r%^\(from%, out # )
+
+ assert_match %r%^= Class methods:%, out
+ assert_match %r%^ new%, out
+ assert_match %r%^= Instance methods:%, out
+ assert_match %r%^ blah%, out
+ assert_match %r%^= Attributes:%, out
+ assert_match %r%^ attr_accessor attr%, out
+
+ assert_equal 1, out.scan(/-\n/).length
+ end
+
+ def test_display_class_ambiguous
+ util_multi_store
+
+ out, err = capture_io do
+ @driver.display_class 'Ambiguous'
+ end
+
+ assert_match %r%^= Ambiguous < Object$%, out
+ end
+
+ def test_display_class_multi_no_doc
+ util_multi_store
+
+ out, err = capture_io do
+ @driver.display_class 'Foo::Baz'
+ end
+
+ assert_match %r%^= Foo::Baz%, out
+ assert_match %r%-\n%, out
+ assert_match %r%Also found in:%, out
+ assert_match %r%#{Regexp.escape @home_ri}%, out
+ assert_match %r%#{Regexp.escape @home_ri2}%, out
+ end
+
+ def test_display_class_superclass
+ util_multi_store
+
+ out, err = capture_io do
+ @driver.display_class 'Bar'
+ end
+
+ assert_match %r%^= Bar < Foo%, out
+ end
+
+ def test_display_class_module
+ util_store
+
+ out, err = capture_io do
+ @driver.display_class 'Inc'
+ end
+
+ assert_match %r%^= Inc$%, out
+ end
+
+ def test_display_method
+ util_store
+
+ out, err = capture_io do
+ @driver.display_method 'Foo::Bar#blah'
+ end
+
+ assert_match %r%Foo::Bar#blah%, out
+ assert_match %r%blah.5%, out
+ assert_match %r%blah.6%, out
+ end
+
+ def test_display_method_attribute
+ util_store
+
+ out, err = capture_io do
+ @driver.display_method 'Foo::Bar#attr'
+ end
+
+ assert_match %r%Foo::Bar#attr%, out
+ refute_match %r%Implementation from%, out
+ end
+
+ def test_display_method_inherited
+ util_multi_store
+
+ out, err = capture_io do
+ @driver.display_method 'Bar#inherit'
+ end
+
+ assert_match %r%^= Bar#inherit%, out
+ assert_match %r%^=== Implementation from Foo%, out
+ end
+
+ def test_display_name_not_found_class
+ util_store
+
+ out, err = capture_io do
+ assert_equal false, @driver.display_name('Foo::B')
+ end
+
+ expected = <<-EXPECTED
+Foo::B not found, maybe you meant:
+
+Foo::Bar
+Foo::Baz
+ EXPECTED
+
+ assert_equal expected, out
+ end
+
+ def test_display_name_not_found_method
+ util_store
+
+ out, err = capture_io do
+ assert_equal false, @driver.display_name('Foo::Bar#b')
+ end
+
+ expected = <<-EXPECTED
+Foo::Bar#b not found, maybe you meant:
+
+Foo::Bar#blah
+Foo::Bar#bother
+ EXPECTED
+
+ assert_equal expected, out
+ end
+
+ def test_display_method_params
+ util_store
+
+ out, err = capture_io do
+ @driver.display_method 'Foo::Bar#bother'
+ end
+
+ assert_match %r%things.*stuff%, out
+ end
+
+ def test_expand_class
+ util_store
+
+ assert_equal 'Foo', @driver.expand_class('F')
+ assert_equal 'Foo::Bar', @driver.expand_class('F::Bar')
+
+ assert_raises RDoc::RI::Driver::NotFoundError do
+ @driver.expand_class 'F::B'
+ end
+ end
+
+ def test_expand_name
+ util_store
+
+ assert_equal '.b', @driver.expand_name('b')
+ assert_equal 'Foo', @driver.expand_name('F')
+ assert_equal 'Foo::Bar#', @driver.expand_name('F::Bar#')
+
+ e = assert_raises RDoc::RI::Driver::NotFoundError do
+ @driver.expand_name 'Z'
+ end
+
+ assert_equal 'Z', e.name
+ end
+
+ def test_find_methods
+ util_store
+
+ items = []
+
+ @driver.find_methods 'Foo::Bar.' do |store, klass, ancestor, types, method|
+ items << [store, klass, ancestor, types, method]
+ end
+
+ expected = [
+ [@store, 'Foo::Bar', 'Foo::Bar', :both, nil],
+ ]
+
+ assert_equal expected, items
+ end
+
+ def test_find_methods_method
+ util_store
+
+ items = []
+
+ @driver.find_methods '.blah' do |store, klass, ancestor, types, method|
+ items << [store, klass, ancestor, types, method]
+ end
+
+ expected = [
+ [@store, 'Ambiguous', 'Ambiguous', :both, 'blah'],
+ [@store, 'Foo', 'Foo', :both, 'blah'],
+ [@store, 'Foo::Bar', 'Foo::Bar', :both, 'blah'],
+ [@store, 'Foo::Baz', 'Foo::Baz', :both, 'blah'],
+ [@store, 'Inc', 'Inc', :both, 'blah'],
+ ]
+
+ assert_equal expected, items
+ end
+
+ def test_formatter
+ driver = RDoc::RI::Driver.new
+
+ io = Object.new
+ def io.tty?; true; end
+
+ assert_instance_of @RM::ToAnsi, driver.formatter(io)
+
+ driver.instance_variable_set :@paging, true
+
+ assert_instance_of @RM::ToBs, driver.formatter(io)
+
+ driver.instance_variable_set :@formatter_klass, @RM::ToHtml
+
+ assert_instance_of @RM::ToHtml, driver.formatter(io)
+ end
+
+ def test_method_type
+ assert_equal :both, @driver.method_type(nil)
+ assert_equal :both, @driver.method_type('.')
+ assert_equal :instance, @driver.method_type('#')
+ assert_equal :class, @driver.method_type('::')
+ end
+
+ def test_list_known_classes
+ util_store
+
+ out, err = capture_io do
+ @driver.list_known_classes
+ end
+
+ assert_equal "Ambiguous\nFoo\nFoo::Bar\nFoo::Baz\nInc\n", out
+ end
+
+ def test_list_methods_matching
+ util_store
+
+ assert_equal %w[Foo::Bar#attr Foo::Bar#blah Foo::Bar#bother Foo::Bar::new],
+ @driver.list_methods_matching('Foo::Bar.')
+ end
+
+ def test_load_method
+ util_store
+
+ method = @driver.load_method(@store, :instance_methods, 'Foo', '#',
+ 'inherit')
+
+ assert_equal @inherit, method
+ end
+
+ def test_load_method_inherited
+ util_multi_store
+
+ method = @driver.load_method(@store2, :instance_methods, 'Bar', '#',
+ 'inherit')
+
+ assert_equal nil, method
+ end
+
+ def test_load_methods_matching
+ util_store
+
+ expected = [[@store, [@inherit]]]
+
+ assert_equal expected, @driver.load_methods_matching('Foo#inherit')
+
+ expected = [[@store, [@blah]]]
+
+ assert_equal expected, @driver.load_methods_matching('.blah')
+
+ assert_empty @driver.load_methods_matching('.b')
+ end
+
+ def test_load_methods_matching_inherited
+ util_multi_store
+
+ expected = [[@store1, [@inherit]]]
+
+ assert_equal expected, @driver.load_methods_matching('Bar#inherit')
+ end
+
+ def _test_page # this test doesn't do anything anymore :(
+ @driver.use_stdout = false
+
+ with_dummy_pager do
+ @driver.page do |io|
+ skip "couldn't find a standard pager" if io == $stdout
+
+ assert @driver.paging?
+ end
+ end
+
+ refute @driver.paging?
+ end
+
+ def test_page_stdout
+ @driver.use_stdout = true
+
+ @driver.page do |io|
+ assert_equal $stdout, io
+ end
+
+ refute @driver.paging?
+ end
+
+ def test_parse_name_method
+ klass, type, meth = @driver.parse_name 'foo'
+
+ assert_equal '', klass, 'foo class'
+ assert_equal '.', type, 'foo type'
+ assert_equal 'foo', meth, 'foo method'
+
+ klass, type, meth = @driver.parse_name '#foo'
+
+ assert_equal '', klass, '#foo class'
+ assert_equal '#', type, '#foo type'
+ assert_equal 'foo', meth, '#foo method'
+
+ klass, type, meth = @driver.parse_name '::foo'
+
+ assert_equal '', klass, '::foo class'
+ assert_equal '::', type, '::foo type'
+ assert_equal 'foo', meth, '::foo method'
+ end
+
+ def test_parse_name_single_class
+ klass, type, meth = @driver.parse_name 'Foo'
+
+ assert_equal 'Foo', klass, 'Foo class'
+ assert_equal nil, type, 'Foo type'
+ assert_equal nil, meth, 'Foo method'
+
+ klass, type, meth = @driver.parse_name 'Foo#'
+
+ assert_equal 'Foo', klass, 'Foo# class'
+ assert_equal '#', type, 'Foo# type'
+ assert_equal nil, meth, 'Foo# method'
+
+ klass, type, meth = @driver.parse_name 'Foo::'
+
+ assert_equal 'Foo', klass, 'Foo:: class'
+ assert_equal '::', type, 'Foo:: type'
+ assert_equal nil, meth, 'Foo:: method'
+
+ klass, type, meth = @driver.parse_name 'Foo.'
+
+ assert_equal 'Foo', klass, 'Foo. class'
+ assert_equal '.', type, 'Foo. type'
+ assert_equal nil, meth, 'Foo. method'
+
+ klass, type, meth = @driver.parse_name 'Foo#Bar'
+
+ assert_equal 'Foo', klass, 'Foo#Bar class'
+ assert_equal '#', type, 'Foo#Bar type'
+ assert_equal 'Bar', meth, 'Foo#Bar method'
+
+ klass, type, meth = @driver.parse_name 'Foo.Bar'
+
+ assert_equal 'Foo', klass, 'Foo.Bar class'
+ assert_equal '.', type, 'Foo.Bar type'
+ assert_equal 'Bar', meth, 'Foo.Bar method'
+
+ klass, type, meth = @driver.parse_name 'Foo::bar'
+
+ assert_equal 'Foo', klass, 'Foo::bar class'
+ assert_equal '::', type, 'Foo::bar type'
+ assert_equal 'bar', meth, 'Foo::bar method'
+ end
+
+ def test_parse_name_namespace
+ klass, type, meth = @driver.parse_name 'Foo::Bar'
+
+ assert_equal 'Foo::Bar', klass, 'Foo::Bar class'
+ assert_equal nil, type, 'Foo::Bar type'
+ assert_equal nil, meth, 'Foo::Bar method'
+
+ klass, type, meth = @driver.parse_name 'Foo::Bar#'
+
+ assert_equal 'Foo::Bar', klass, 'Foo::Bar# class'
+ assert_equal '#', type, 'Foo::Bar# type'
+ assert_equal nil, meth, 'Foo::Bar# method'
+
+ klass, type, meth = @driver.parse_name 'Foo::Bar#baz'
+
+ assert_equal 'Foo::Bar', klass, 'Foo::Bar#baz class'
+ assert_equal '#', type, 'Foo::Bar#baz type'
+ assert_equal 'baz', meth, 'Foo::Bar#baz method'
+ end
+
+ def _test_setup_pager # this test doesn't do anything anymore :(
+ @driver.use_stdout = false
+
+ pager = with_dummy_pager do @driver.setup_pager end
+
+ skip "couldn't find a standard pager" unless pager
+
+ assert @driver.paging?
+ ensure
+ pager.close if pager
+ end
+
+ def util_ancestors_store
+ store1 = RDoc::RI::Store.new @home_ri
+ store1.cache[:ancestors] = {
+ 'Foo' => %w[Object],
+ 'Foo::Bar' => %w[Foo],
+ }
+ store1.cache[:class_methods] = {
+ 'Foo' => %w[c_method new],
+ 'Foo::Bar' => %w[new],
+ }
+ store1.cache[:instance_methods] = {
+ 'Foo' => %w[i_method],
+ }
+ store1.cache[:modules] = %w[
+ Foo
+ Foo::Bar
+ ]
+
+ store2 = RDoc::RI::Store.new @home_ri
+ store2.cache[:ancestors] = {
+ 'Foo' => %w[Mixin Object],
+ 'Mixin' => %w[],
+ 'Object' => %w[X Object],
+ 'X' => %w[Object],
+ }
+ store2.cache[:class_methods] = {
+ 'Foo' => %w[c_method new],
+ 'Mixin' => %w[],
+ 'X' => %w[],
+ 'Object' => %w[],
+ }
+ store2.cache[:instance_methods] = {
+ 'Foo' => %w[i_method],
+ 'Mixin' => %w[],
+ }
+ store2.cache[:modules] = %w[
+ Foo
+ Mixin
+ Object
+ X
+ ]
+
+ @driver.stores = store1, store2
+ end
+
+ def util_multi_store
+ util_store
+ @store1 = @store
+
+ @home_ri2 = "#{@home_ri}2"
+ @store2 = RDoc::RI::Store.new @home_ri2
+
+ # as if seen in a namespace like class Ambiguous::Other
+ @mAmbiguous = RDoc::NormalModule.new 'Ambiguous'
+
+ @cFoo = RDoc::NormalClass.new 'Foo'
+ @cBar = RDoc::NormalClass.new 'Bar'
+ @cBar.superclass = 'Foo'
+ @cFoo_Baz = RDoc::NormalClass.new 'Baz'
+ @cFoo_Baz.parent = @cFoo
+
+ @baz = RDoc::AnyMethod.new nil, 'baz'
+ @cBar.add_method @baz
+
+ @store2.save_class @mAmbiguous
+ @store2.save_class @cBar
+ @store2.save_class @cFoo_Baz
+
+ @store2.save_method @cBar, @baz
+
+ @store2.save_cache
+
+ @driver.stores = [@store1, @store2]
+ end
+
+ def util_store
+ @store = RDoc::RI::Store.new @home_ri
+
+ @cFoo = RDoc::NormalClass.new 'Foo'
+ @mInc = RDoc::NormalModule.new 'Inc'
+ @cAmbiguous = RDoc::NormalClass.new 'Ambiguous'
+
+ doc = @RM::Document.new @RM::Paragraph.new('Include thingy')
+
+ @cFooInc = RDoc::Include.new 'Inc', doc
+ @cFoo.add_include @cFooInc
+
+ @cFoo_Bar = RDoc::NormalClass.new 'Bar'
+ @cFoo_Bar.parent = @cFoo
+
+ @blah = RDoc::AnyMethod.new nil, 'blah'
+ @blah.call_seq = "blah(5) => 5\nblah(6) => 6\n"
+
+ @bother = RDoc::AnyMethod.new nil, 'bother'
+ @bother.params = "(things)"
+ @bother.block_params = "stuff"
+
+ @new = RDoc::AnyMethod.new nil, 'new'
+ @new.singleton = true
+
+ @cFoo_Bar.add_method @blah
+ @cFoo_Bar.add_method @bother
+ @cFoo_Bar.add_method @new
+
+ @attr = RDoc::Attr.new nil, 'attr', 'RW', ''
+
+ @cFoo_Bar.add_attribute @attr
+
+ @cFoo_Baz = RDoc::NormalClass.new 'Baz'
+ @cFoo_Baz.parent = @cFoo
+
+ @inherit = RDoc::AnyMethod.new nil, 'inherit'
+ @cFoo.add_method @inherit
+
+ @store.save_class @cFoo
+ @store.save_class @cFoo_Bar
+ @store.save_class @cFoo_Baz
+ @store.save_class @mInc
+ @store.save_class @cAmbiguous
+
+ @store.save_method @cFoo_Bar, @blah
+ @store.save_method @cFoo_Bar, @bother
+ @store.save_method @cFoo_Bar, @new
+ @store.save_method @cFoo_Bar, @attr
+
+ @store.save_method @cFoo, @inherit
+
+ @store.save_cache
+
+ @driver.stores = [@store]
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_ri_paths.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_ri_paths.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_ri_paths.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,43 @@
+require 'rubygems'
+require 'minitest/autorun'
+require 'tmpdir'
+require 'fileutils'
+require 'rdoc/ri/paths'
+
+class TestRDocRIPaths < MiniTest::Unit::TestCase
+
+ def setup
+ RDoc::RI::Paths.instance_variable_set :@gemdirs, %w[/nonexistent/gemdir]
+ end
+
+ def teardown
+ RDoc::RI::Paths.instance_variable_set :@gemdirs, nil
+ end
+
+ def test_class_path_nonexistent
+ path = RDoc::RI::Paths.path true, true, true, true, '/nonexistent'
+
+ refute_includes path, '/nonexistent'
+ end
+
+ def test_class_raw_path
+ path = RDoc::RI::Paths.raw_path true, true, true, true
+
+ assert_equal RDoc::RI::Paths::SYSDIR, path.shift
+ assert_equal RDoc::RI::Paths::SITEDIR, path.shift
+ assert_equal RDoc::RI::Paths::HOMEDIR, path.shift
+ assert_equal '/nonexistent/gemdir', path.shift
+ end
+
+ def test_class_raw_path_extra_dirs
+ path = RDoc::RI::Paths.raw_path true, true, true, true, '/nonexistent'
+
+ assert_equal '/nonexistent', path.shift
+ assert_equal RDoc::RI::Paths::SYSDIR, path.shift
+ assert_equal RDoc::RI::Paths::SITEDIR, path.shift
+ assert_equal RDoc::RI::Paths::HOMEDIR, path.shift
+ assert_equal '/nonexistent/gemdir', path.shift
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_ri_store.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_ri_store.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_ri_store.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,309 @@
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/ri'
+require 'rdoc/markup'
+require 'tmpdir'
+require 'fileutils'
+
+class TestRDocRIStore < MiniTest::Unit::TestCase
+
+ def setup
+ RDoc::TopLevel.reset
+
+ @tmpdir = File.join Dir.tmpdir, "test_rdoc_ri_store_#{$$}"
+ @s = RDoc::RI::Store.new @tmpdir
+
+ @top_level = RDoc::TopLevel.new 'file.rb'
+
+ @klass = @top_level.add_class RDoc::NormalClass, 'Object'
+ @klass.comment = 'original'
+
+ @cmeth = RDoc::AnyMethod.new nil, 'cmethod'
+ @cmeth.singleton = true
+
+ @meth = RDoc::AnyMethod.new nil, 'method'
+ @meth_bang = RDoc::AnyMethod.new nil, 'method!'
+
+ @attr = RDoc::Attr.new nil, 'attr', 'RW', ''
+
+ @klass.add_method @cmeth
+ @klass.add_method @meth
+ @klass.add_method @meth_bang
+ @klass.add_attribute @attr
+
+ @nest_klass = @klass.add_class RDoc::NormalClass, 'SubClass'
+ @nest_meth = RDoc::AnyMethod.new nil, 'method'
+ @nest_incl = RDoc::Include.new 'Incl', ''
+
+ @nest_klass.add_method @nest_meth
+ @nest_klass.add_include @nest_incl
+
+ @RM = RDoc::Markup
+ end
+
+ def teardown
+ FileUtils.rm_rf @tmpdir
+ end
+
+ def assert_cache imethods, cmethods, attrs, modules, ancestors = {}
+ expected = {
+ :class_methods => cmethods,
+ :instance_methods => imethods,
+ :attributes => attrs,
+ :modules => modules,
+ :ancestors => ancestors
+ }
+
+ assert_equal expected, @s.cache
+ end
+
+ def assert_directory path
+ assert File.directory?(path), "#{path} is not a directory"
+ end
+
+ def assert_file path
+ assert File.file?(path), "#{path} is not a file"
+ end
+
+ def test_attributes
+ @s.cache[:attributes]['Object'] = %w[attr]
+
+ expected = { 'Object' => %w[attr] }
+
+ assert_equal expected, @s.attributes
+ end
+
+ def test_class_file
+ assert_equal File.join(@tmpdir, 'Object', 'cdesc-Object.ri'),
+ @s.class_file('Object')
+ assert_equal File.join(@tmpdir, 'Object', 'SubClass', 'cdesc-SubClass.ri'),
+ @s.class_file('Object::SubClass')
+ end
+
+ def test_class_methods
+ @s.cache[:class_methods]['Object'] = %w[method]
+
+ expected = { 'Object' => %w[method] }
+
+ assert_equal expected, @s.class_methods
+ end
+
+ def test_class_path
+ assert_equal File.join(@tmpdir, 'Object'), @s.class_path('Object')
+ assert_equal File.join(@tmpdir, 'Object', 'SubClass'),
+ @s.class_path('Object::SubClass')
+ end
+
+ def test_friendly_path
+ @s.path = @tmpdir
+ @s.type = nil
+ assert_equal @s.path, @s.friendly_path
+
+ @s.type = :extra
+ assert_equal @s.path, @s.friendly_path
+
+ @s.type = :system
+ assert_equal "ruby core", @s.friendly_path
+
+ @s.type = :site
+ assert_equal "ruby site", @s.friendly_path
+
+ @s.type = :home
+ assert_equal "~/.ri", @s.friendly_path
+
+ @s.type = :gem
+ @s.path = "#{@tmpdir}/gem_repository/doc/gem_name-1.0/ri"
+ assert_equal "gem gem_name-1.0", @s.friendly_path
+ end
+
+ def test_instance_methods
+ @s.cache[:instance_methods]['Object'] = %w[method]
+
+ expected = { 'Object' => %w[method] }
+
+ assert_equal expected, @s.instance_methods
+ end
+
+ def test_load_cache
+ cache = {
+ :methods => %w[Object#method],
+ :modules => %w[Object],
+ }
+
+ Dir.mkdir @tmpdir
+
+ open File.join(@tmpdir, 'cache.ri'), 'wb' do |io|
+ Marshal.dump cache, io
+ end
+
+ @s.load_cache
+
+ assert_equal cache, @s.cache
+ end
+
+ def test_load_cache_no_cache
+ cache = {
+ :ancestors => {},
+ :attributes => {},
+ :class_methods => {},
+ :instance_methods => {},
+ :modules => [],
+ }
+
+ @s.load_cache
+
+ assert_equal cache, @s.cache
+ end
+
+ def test_load_class
+ @s.save_class @klass
+
+ assert_equal @klass, @s.load_class('Object')
+ end
+
+ def test_load_method_bang
+ @s.save_method @klass, @meth_bang
+
+ meth = @s.load_method('Object', '#method!')
+ assert_equal @meth_bang, meth
+ end
+
+ def test_method_file
+ assert_equal File.join(@tmpdir, 'Object', 'method-i.ri'),
+ @s.method_file('Object', 'Object#method')
+
+ assert_equal File.join(@tmpdir, 'Object', 'method%21-i.ri'),
+ @s.method_file('Object', 'Object#method!')
+
+ assert_equal File.join(@tmpdir, 'Object', 'SubClass', 'method%21-i.ri'),
+ @s.method_file('Object::SubClass', 'Object::SubClass#method!')
+
+ assert_equal File.join(@tmpdir, 'Object', 'method-c.ri'),
+ @s.method_file('Object', 'Object::method')
+ end
+
+ def test_save_cache
+ @s.save_class @klass
+ @s.save_method @klass, @meth
+ @s.save_method @klass, @cmeth
+ @s.save_class @nest_klass
+
+ @s.save_cache
+
+ assert_file File.join(@tmpdir, 'cache.ri')
+
+ expected = {
+ :attributes => { 'Object' => ['attr_accessor attr'] },
+ :class_methods => { 'Object' => %w[cmethod] },
+ :instance_methods => { 'Object' => %w[method] },
+ :modules => %w[Object Object::SubClass],
+ :ancestors => {
+ 'Object' => %w[Object],
+ 'Object::SubClass' => %w[Incl Object],
+ },
+ }
+
+ open File.join(@tmpdir, 'cache.ri'), 'rb' do |io|
+ cache = Marshal.load io.read
+
+ assert_equal expected, cache
+ end
+ end
+
+ def test_save_cache_duplicate_methods
+ @s.save_method @klass, @meth
+ @s.save_method @klass, @meth
+
+ @s.save_cache
+
+ assert_cache({ 'Object' => %w[method] }, {}, {}, [])
+ end
+
+ def test_save_class
+ @s.save_class @klass
+
+ assert_directory File.join(@tmpdir, 'Object')
+ assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri')
+
+ assert_cache({}, {}, { 'Object' => ['attr_accessor attr'] }, %w[Object],
+ 'Object' => %w[Object])
+
+ assert_equal @klass, @s.load_class('Object')
+ end
+
+ def test_save_class_basic_object
+ @klass.instance_variable_set :@superclass, nil
+
+ @s.save_class @klass
+
+ assert_directory File.join(@tmpdir, 'Object')
+ assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri')
+
+ assert_cache({}, {}, { 'Object' => ['attr_accessor attr'] }, %w[Object],
+ 'Object' => %w[])
+
+ assert_equal @klass, @s.load_class('Object')
+ end
+
+ def test_save_class_merge
+ @s.save_class @klass
+
+ klass = RDoc::NormalClass.new 'Object'
+ klass.comment = 'new class'
+
+ s = RDoc::RI::Store.new @tmpdir
+ s.save_class klass
+
+ s = RDoc::RI::Store.new @tmpdir
+
+ document = @RM::Document.new(
+ @RM::Paragraph.new('original'),
+ @RM::Paragraph.new('new class'))
+
+ assert_equal document, s.load_class('Object').comment
+ end
+
+ def test_save_class_methods
+ @s.save_class @klass
+
+ assert_directory File.join(@tmpdir, 'Object')
+ assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri')
+
+ assert_cache({}, {}, { 'Object' => ['attr_accessor attr'] }, %w[Object],
+ 'Object' => %w[Object])
+
+ assert_equal @klass, @s.load_class('Object')
+ end
+
+ def test_save_class_nested
+ @s.save_class @nest_klass
+
+ assert_directory File.join(@tmpdir, 'Object', 'SubClass')
+ assert_file File.join(@tmpdir, 'Object', 'SubClass', 'cdesc-SubClass.ri')
+
+ assert_cache({}, {}, {}, %w[Object::SubClass],
+ 'Object::SubClass' => %w[Incl Object])
+ end
+
+ def test_save_method
+ @s.save_method @klass, @meth
+
+ assert_directory File.join(@tmpdir, 'Object')
+ assert_file File.join(@tmpdir, 'Object', 'method-i.ri')
+
+ assert_cache({ 'Object' => %w[method] }, {}, {}, [])
+
+ assert_equal @meth, @s.load_method('Object', '#method')
+ end
+
+ def test_save_method_nested
+ @s.save_method @nest_klass, @nest_meth
+
+ assert_directory File.join(@tmpdir, 'Object', 'SubClass')
+ assert_file File.join(@tmpdir, 'Object', 'SubClass', 'method-i.ri')
+
+ assert_cache({ 'Object::SubClass' => %w[method] }, {}, {}, [])
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_task.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_task.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_task.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,64 @@
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc/task'
+
+class TestRDocTask < MiniTest::Unit::TestCase
+
+ def setup
+ Rake::Task.clear
+ end
+
+ def test_tasks_creation
+ RDoc::Task.new
+ assert Rake::Task[:rdoc]
+ assert Rake::Task[:clobber_rdoc]
+ assert Rake::Task[:rerdoc]
+ end
+
+ def test_tasks_creation_with_custom_name_symbol
+ rd = RDoc::Task.new(:rdoc_dev)
+ assert Rake::Task[:rdoc_dev]
+ assert Rake::Task[:clobber_rdoc_dev]
+ assert Rake::Task[:rerdoc_dev]
+ assert_equal :rdoc_dev, rd.name
+ end
+
+ def test_tasks_creation_with_custom_name_string
+ rd = RDoc::Task.new("rdoc_dev")
+ assert Rake::Task[:rdoc_dev]
+ assert Rake::Task[:clobber_rdoc_dev]
+ assert Rake::Task[:rerdoc_dev]
+ assert_equal "rdoc_dev", rd.name
+ end
+
+ def test_tasks_creation_with_custom_name_hash
+ options = { :rdoc => "rdoc", :clobber_rdoc => "rdoc:clean", :rerdoc => "rdoc:force" }
+ rd = RDoc::Task.new(options)
+ assert Rake::Task[:"rdoc"]
+ assert Rake::Task[:"rdoc:clean"]
+ assert Rake::Task[:"rdoc:force"]
+ assert_raises(RuntimeError) { Rake::Task[:clobber_rdoc] }
+ assert_equal options, rd.name
+ end
+
+ def test_tasks_creation_with_custom_name_hash_will_use_default_if_an_option_isnt_given
+ rd = RDoc::Task.new(:clobber_rdoc => "rdoc:clean")
+ assert Rake::Task[:rdoc]
+ assert Rake::Task[:"rdoc:clean"]
+ assert Rake::Task[:rerdoc]
+ end
+
+ def test_tasks_creation_with_custom_name_hash_raises_exception_if_invalid_option_given
+ assert_raises(ArgumentError) do
+ RDoc::Task.new(:foo => "bar")
+ end
+
+ begin
+ RDoc::Task.new(:foo => "bar")
+ rescue ArgumentError => e
+ assert_match(/foo/, e.message)
+ end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_text.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_text.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_text.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,157 @@
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc'
+require 'rdoc/text'
+require 'rdoc/markup'
+require 'rdoc/markup/formatter'
+
+class TestRDocText < MiniTest::Unit::TestCase
+
+ include RDoc::Text
+
+ def test_expand_tabs
+ assert_equal("hello\n dave",
+ expand_tabs("hello\n dave"), 'spaces')
+
+ assert_equal("hello\n dave",
+ expand_tabs("hello\n\tdave"), 'tab')
+
+ assert_equal("hello\n dave",
+ expand_tabs("hello\n \tdave"), '1 space tab')
+
+ assert_equal("hello\n dave",
+ expand_tabs("hello\n \tdave"), '2 space tab')
+
+ assert_equal("hello\n dave",
+ expand_tabs("hello\n \tdave"), '3 space tab')
+
+ assert_equal("hello\n dave",
+ expand_tabs("hello\n \tdave"), '4 space tab')
+
+ assert_equal("hello\n dave",
+ expand_tabs("hello\n \tdave"), '5 space tab')
+
+ assert_equal("hello\n dave",
+ expand_tabs("hello\n \tdave"), '6 space tab')
+
+ assert_equal("hello\n dave",
+ expand_tabs("hello\n \tdave"), '7 space tab')
+
+ assert_equal("hello\n dave",
+ expand_tabs("hello\n \tdave"), '8 space tab')
+
+ assert_equal('. .',
+ expand_tabs(".\t\t."), 'dot tab tab dot')
+ end
+
+ def test_flush_left
+ text = <<-TEXT
+
+ we don't worry too much.
+
+ The comments associated with
+ TEXT
+
+ expected = <<-EXPECTED
+
+we don't worry too much.
+
+The comments associated with
+ EXPECTED
+
+ assert_equal expected, flush_left(text)
+ end
+
+ def test_markup
+ def formatter() RDoc::Markup::ToHtml.new end
+
+ assert_equal "<p>\nhi\n</p>\n", markup('hi')
+ end
+
+ def test_normalize_comment
+ text = <<-TEXT
+##
+# we don't worry too much.
+#
+# The comments associated with
+ TEXT
+
+ expected = <<-EXPECTED.rstrip
+we don't worry too much.
+
+The comments associated with
+ EXPECTED
+
+ assert_equal expected, normalize_comment(text)
+ end
+
+ def test_parse
+ assert_kind_of RDoc::Markup::Document, parse('hi')
+ end
+
+ def test_parse_document
+ assert_equal RDoc::Markup::Document.new, parse(RDoc::Markup::Document.new)
+ end
+
+ def test_parse_empty
+ assert_equal RDoc::Markup::Document.new, parse('')
+ end
+
+ def test_parse_empty_newline
+ assert_equal RDoc::Markup::Document.new, parse("#\n")
+ end
+
+ def test_parse_newline
+ assert_equal RDoc::Markup::Document.new, parse("\n")
+ end
+
+ def test_strip_hashes
+ text = <<-TEXT
+##
+# we don't worry too much.
+#
+# The comments associated with
+ TEXT
+
+ expected = <<-EXPECTED
+
+ we don't worry too much.
+
+ The comments associated with
+ EXPECTED
+
+ assert_equal expected, strip_hashes(text)
+ end
+
+ def test_strip_newlines
+ assert_equal ' ', strip_newlines("\n \n")
+
+ assert_equal 'hi', strip_newlines("\n\nhi")
+
+ assert_equal 'hi', strip_newlines( "hi\n\n")
+
+ assert_equal 'hi', strip_newlines("\n\nhi\n\n")
+ end
+
+ def test_strip_stars
+ text = <<-TEXT
+/*
+ * * we don't worry too much.
+ *
+ * The comments associated with
+ */
+ TEXT
+
+ expected = <<-EXPECTED
+
+ * we don't worry too much.
+
+ The comments associated with
+
+ EXPECTED
+
+ assert_equal expected, strip_stars(text)
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_top_level.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_top_level.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/test_rdoc_top_level.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,111 @@
+require 'rubygems'
+require 'minitest/autorun'
+require File.expand_path '../xref_test_case', __FILE__
+
+class TestRDocTopLevel < XrefTestCase
+
+ def setup
+ super
+
+ @top_level = RDoc::TopLevel.new 'path/top_level.rb'
+ end
+
+ def test_class_all_classes_and_modules
+ expected = %w[
+ C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 M1 M1::M2
+ ]
+
+ assert_equal expected,
+ RDoc::TopLevel.all_classes_and_modules.map { |m| m.full_name }.sort
+ end
+
+ def test_class_classes
+ expected = %w[
+ C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1
+ ]
+
+ assert_equal expected, RDoc::TopLevel.classes.map { |m| m.full_name }.sort
+ end
+
+ def test_class_files
+ assert_equal %w[path/top_level.rb xref_data.rb],
+ RDoc::TopLevel.files.map { |m| m.full_name }.sort
+ end
+
+ def test_class_find_class_named
+ assert_equal @c1, RDoc::TopLevel.find_class_named('C1')
+
+ assert_equal @c2_c3, RDoc::TopLevel.find_class_named('C2::C3')
+ end
+
+ def test_class_find_class_named_from
+ assert_equal @c5_c1, RDoc::TopLevel.find_class_named_from('C1', 'C5')
+
+ assert_equal @c1, RDoc::TopLevel.find_class_named_from('C1', 'C4')
+ end
+
+ def test_class_find_class_or_module
+ assert_equal @m1, RDoc::TopLevel.find_class_or_module('M1')
+ assert_equal @c1, RDoc::TopLevel.find_class_or_module('C1')
+
+ assert_equal @m1, RDoc::TopLevel.find_class_or_module('::M1')
+ assert_equal @c1, RDoc::TopLevel.find_class_or_module('::C1')
+ end
+
+ def test_class_find_file_named
+ assert_equal @xref_data, RDoc::TopLevel.find_file_named(@file_name)
+ end
+
+ def test_class_find_module_named
+ assert_equal @m1, RDoc::TopLevel.find_module_named('M1')
+ assert_equal @m1_m2, RDoc::TopLevel.find_module_named('M1::M2')
+ end
+
+ def test_class_modules
+ assert_equal %w[M1 M1::M2],
+ RDoc::TopLevel.modules.map { |m| m.full_name }.sort
+ end
+
+ def test_class_reset
+ RDoc::TopLevel.reset
+
+ assert_empty RDoc::TopLevel.classes
+ assert_empty RDoc::TopLevel.modules
+ assert_empty RDoc::TopLevel.files
+ end
+
+ def test_base_name
+ assert_equal 'top_level.rb', @top_level.base_name
+ end
+
+ def test_find_class_or_module
+ assert_equal @c1, @xref_data.find_class_or_module('C1')
+ assert_equal @c2_c3, @xref_data.find_class_or_module('C2::C3')
+ assert_equal @c4, @xref_data.find_class_or_module('C4')
+ assert_equal @m1_m2, @xref_data.find_class_or_module('M1::M2')
+ end
+
+ def test_full_name
+ assert_equal 'path/top_level.rb', @top_level.full_name
+ end
+
+ def test_http_url
+ assert_equal 'prefix/path/top_level_rb.html', @top_level.http_url('prefix')
+ end
+
+ def test_last_modified
+ assert_equal 'Unknown', @top_level.last_modified
+
+ stat = Object.new
+ def stat.mtime() 0 end
+ @top_level.file_stat = stat
+
+ assert_equal '0', @top_level.last_modified
+ end
+
+ def test_name
+ assert_equal 'top_level.rb', @top_level.name
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/xref_data.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/xref_data.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/xref_data.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,54 @@
+XREF_DATA = <<-XREF_DATA
+class C1
+
+ attr :attr
+ attr_reader :attr_reader
+ attr_writer :attr_writer
+ attr_accessor :attr_accessor
+
+ CONST = :const
+
+ def self.m
+ end
+
+ def m foo
+ end
+end
+
+class C2
+ class C3
+ def m
+ end
+
+ class H1
+ def m?
+ end
+ end
+ end
+end
+
+class C3
+ class H1
+ end
+
+ class H2 < H1
+ end
+end
+
+class C4
+ class C4
+ end
+end
+
+class C5
+ class C1
+ end
+end
+
+module M1
+end
+
+module M1::M2
+end
+XREF_DATA
+
Added: MacRuby/trunk/test/test-mri/test/rdoc/xref_test_case.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rdoc/xref_test_case.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rdoc/xref_test_case.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,55 @@
+ENV['RDOC_TEST'] = 'yes'
+
+require 'rubygems'
+require 'minitest/autorun'
+require 'rdoc'
+require 'rdoc/stats'
+require 'rdoc/options'
+require 'rdoc/code_objects'
+require 'rdoc/parser/ruby'
+require File.expand_path '../xref_data', __FILE__
+
+class XrefTestCase < MiniTest::Unit::TestCase
+
+ def setup
+ RDoc::TopLevel.reset
+
+ @file_name = 'xref_data.rb'
+ @xref_data = RDoc::TopLevel.new @file_name
+
+ @options = RDoc::Options.new
+ @options.quiet = true
+
+ stats = RDoc::Stats.new 0
+
+ parser = RDoc::Parser::Ruby.new @xref_data, @file_name, XREF_DATA, @options,
+ stats
+ @top_levels = []
+ @top_levels.push parser.scan
+
+ generator = Object.new
+ def generator.class_dir() nil end
+ def generator.file_dir() nil end
+ rdoc = RDoc::RDoc.new
+ RDoc::RDoc.current = rdoc
+ rdoc.generator = generator
+
+ @c1 = @xref_data.find_module_named 'C1'
+ @c1_m = @c1.method_list.last # C1#m
+ @c1__m = @c1.method_list.first # C1::m
+
+ @c2 = @xref_data.find_module_named 'C2'
+ @c2_c3 = @xref_data.find_module_named 'C2::C3'
+ @c3 = @xref_data.find_module_named 'C3'
+ @c4 = @xref_data.find_module_named 'C4'
+ @c4_c4 = @xref_data.find_module_named 'C4::C4'
+ @c5_c1 = @xref_data.find_module_named 'C5::C1'
+ @c3_h1 = @xref_data.find_module_named 'C3::H1'
+ @c3_h2 = @xref_data.find_module_named 'C3::H2'
+
+ @m1 = @xref_data.find_module_named 'M1'
+ @m1_m2 = @xref_data.find_module_named 'M1::M2'
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/readline/test_readline.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/readline/test_readline.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/readline/test_readline.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,310 @@
+begin
+ require "readline"
+=begin
+ class << Readline
+ [
+ "line_buffer",
+ "point",
+ "set_screen_size",
+ "get_screen_size",
+ "vi_editing_mode",
+ "emacs_editing_mode",
+ "completion_append_character=",
+ "completion_append_character",
+ "basic_word_break_characters=",
+ "basic_word_break_characters",
+ "completer_word_break_characters=",
+ "completer_word_break_characters",
+ "basic_quote_characters=",
+ "basic_quote_characters",
+ "completer_quote_characters=",
+ "completer_quote_characters",
+ "filename_quote_characters=",
+ "filename_quote_characters",
+ "refresh_line",
+ ].each do |method_name|
+ define_method(method_name.to_sym) do |*args|
+ raise NotImplementedError
+ end
+ end
+ end
+=end
+rescue LoadError
+else
+ require "test/unit"
+ require "tempfile"
+end
+
+class TestReadline < Test::Unit::TestCase
+ def teardown
+ Readline.instance_variable_set("@completion_proc", nil)
+ end
+
+ def test_safe_level_4
+ method_args =
+ [
+ ["readline"],
+ ["input=", $stdin],
+ ["output=", $stdout],
+ ["completion_proc=", proc {}],
+ ["completion_proc"],
+ ["completion_case_fold=", true],
+ ["completion_case_fold"],
+ ["vi_editing_mode"],
+ ["vi_editing_mode?"],
+ ["emacs_editing_mode"],
+ ["emacs_editing_mode?"],
+ ["completion_append_character=", "s"],
+ ["completion_append_character"],
+ ["basic_word_break_characters=", "s"],
+ ["basic_word_break_characters"],
+ ["completer_word_break_characters=", "s"],
+ ["completer_word_break_characters"],
+ ["basic_quote_characters=", "\\"],
+ ["basic_quote_characters"],
+ ["completer_quote_characters=", "\\"],
+ ["completer_quote_characters"],
+ ["filename_quote_characters=", "\\"],
+ ["filename_quote_characters"],
+ ["line_buffer"],
+ ["point"],
+ ["set_screen_size", 1, 1],
+ ["get_screen_size"],
+ ]
+ method_args.each do |method_name, *args|
+ assert_raise(SecurityError, NotImplementedError,
+ "method=<#{method_name}>") do
+ Thread.start {
+ $SAFE = 4
+ Readline.send(method_name.to_sym, *args)
+ assert(true)
+ }.join
+ end
+ end
+ end
+
+ if !/EditLine/n.match(Readline::VERSION)
+ def test_readline
+ stdin = Tempfile.new("test_readline_stdin")
+ stdout = Tempfile.new("test_readline_stdout")
+ begin
+ stdin.write("hello\n")
+ stdin.close
+ stdout.close
+ line = replace_stdio(stdin.path, stdout.path) {
+ Readline.readline("> ", true)
+ }
+ assert_equal("hello", line)
+ assert_equal(true, line.tainted?)
+ stdout.open
+ assert_equal("> ", stdout.read(2))
+ assert_equal(1, Readline::HISTORY.length)
+ assert_equal("hello", Readline::HISTORY[0])
+ assert_raise(SecurityError) do
+ Thread.start {
+ $SAFE = 1
+ replace_stdio(stdin.path, stdout.path) do
+ Readline.readline("> ".taint)
+ end
+ }.join
+ end
+ assert_raise(SecurityError) do
+ Thread.start {
+ $SAFE = 4
+ replace_stdio(stdin.path, stdout.path) { Readline.readline("> ") }
+ }.join
+ end
+ ensure
+ stdin.close(true)
+ stdout.close(true)
+ end
+ end
+
+ # line_buffer
+ # point
+ def test_line_buffer__point
+ begin
+ Readline.line_buffer
+ Readline.point
+ rescue NotImplementedError
+ return
+ end
+
+ stdin = Tempfile.new("test_readline_stdin")
+ stdout = Tempfile.new("test_readline_stdout")
+ begin
+ actual_text = nil
+ actual_line_buffer = nil
+ actual_point = nil
+ Readline.completion_proc = proc { |text|
+ actual_text = text
+ actual_point = Readline.point
+ actual_buffer_line = Readline.line_buffer
+ stdin.write(" finish\n")
+ stdin.close
+ stdout.close
+ return ["complete"]
+ }
+ stdin.write("first second\t")
+ stdin.flush
+ line = replace_stdio(stdin.path, stdout.path) {
+ Readline.readline("> ", false)
+ }
+ assert_equal("first second", actual_line_buffer)
+ assert_equal(12, actual_point)
+ assert_equal("first complete finish", Readline.line_buffer)
+ assert_equal(21, Readline.point)
+ ensure
+ stdin.close(true)
+ stdout.close(true)
+ end
+ end
+ end
+
+ def test_input=
+ assert_raise(TypeError) do
+ Readline.input = "This is not a file."
+ end
+ end
+
+ def test_output=
+ assert_raise(TypeError) do
+ Readline.output = "This is not a file."
+ end
+ end
+
+ def test_completion_proc
+ expected = proc { |input| input }
+ Readline.completion_proc = expected
+ assert_equal(expected, Readline.completion_proc)
+
+ assert_raise(ArgumentError) do
+ Readline.completion_proc = "This does not have call method."
+ end
+ end
+
+ def test_completion_case_fold
+ expected = [true, false, "string", {"a" => "b"}]
+ expected.each do |e|
+ Readline.completion_case_fold = e
+ assert_equal(e, Readline.completion_case_fold)
+ end
+ end
+
+ def test_get_screen_size
+ begin
+ res = Readline.get_screen_size
+ assert(res.is_a?(Array))
+ rows, columns = *res
+ assert(rows.is_a?(Integer))
+ assert(rows >= 0)
+ assert(columns.is_a?(Integer))
+ assert(columns >= 0)
+ rescue NotImplementedError
+ end
+ end
+
+ # vi_editing_mode
+ # emacs_editing_mode
+ def test_editing_mode
+ begin
+ assert_equal(false, Readline.vi_editing_mode?)
+ assert_equal(true, Readline.emacs_editing_mode?)
+
+ assert_equal(nil, Readline.vi_editing_mode)
+ assert_equal(true, Readline.vi_editing_mode?)
+ assert_equal(false, Readline.emacs_editing_mode?)
+ assert_equal(nil, Readline.vi_editing_mode)
+ assert_equal(true, Readline.vi_editing_mode?)
+ assert_equal(false, Readline.emacs_editing_mode?)
+
+ assert_equal(nil, Readline.emacs_editing_mode)
+ assert_equal(false, Readline.vi_editing_mode?)
+ assert_equal(true, Readline.emacs_editing_mode?)
+ assert_equal(nil, Readline.emacs_editing_mode)
+ assert_equal(false, Readline.vi_editing_mode?)
+ assert_equal(true, Readline.emacs_editing_mode?)
+ rescue NotImplementedError
+ end
+ end
+
+ def test_completion_append_character
+ begin
+ enc = get_default_internal_encoding
+ data_expected = [
+ ["x", "x"],
+ ["xyx", "x"],
+ [" ", " "],
+ ["\t", "\t"],
+ ]
+ data_expected.each do |(data, expected)|
+ Readline.completion_append_character = data
+ assert_equal(expected, Readline.completion_append_character)
+ assert_equal(enc, Readline.completion_append_character.encoding)
+ end
+ Readline.completion_append_character = ""
+ assert_equal(nil, Readline.completion_append_character)
+ rescue NotImplementedError
+ end
+ end
+
+ # basic_word_break_characters
+ # completer_word_break_characters
+ # basic_quote_characters
+ # completer_quote_characters
+ # filename_quote_characters
+ def test_some_characters_methods
+ method_names = [
+ "basic_word_break_characters",
+ "completer_word_break_characters",
+ "basic_quote_characters",
+ "completer_quote_characters",
+ "filename_quote_characters",
+ ]
+ method_names.each do |method_name|
+ begin
+ begin
+ enc = get_default_internal_encoding
+ saved = Readline.send(method_name.to_sym)
+ expecteds = [" ", " .,|\t", ""]
+ expecteds.each do |e|
+ Readline.send((method_name + "=").to_sym, e)
+ res = Readline.send(method_name.to_sym)
+ assert_equal(e, res)
+ assert_equal(enc, res.encoding)
+ end
+ ensure
+ Readline.send((method_name + "=").to_sym, saved) if saved
+ end
+ rescue NotImplementedError
+ end
+ end
+ end
+
+ private
+
+ def replace_stdio(stdin_path, stdout_path)
+ open(stdin_path, "r"){|stdin|
+ open(stdout_path, "w"){|stdout|
+ orig_stdin = STDIN.dup
+ orig_stdout = STDOUT.dup
+ STDIN.reopen(stdin)
+ STDOUT.reopen(stdout)
+ begin
+ Readline.input = STDIN
+ Readline.output = STDOUT
+ yield
+ ensure
+ STDIN.reopen(orig_stdin)
+ STDOUT.reopen(orig_stdout)
+ orig_stdin.close
+ orig_stdout.close
+ end
+ }
+ }
+ end
+
+ def get_default_internal_encoding
+ return Encoding.default_internal || Encoding.find("locale")
+ end
+end if defined?(::Readline)
Added: MacRuby/trunk/test/test-mri/test/readline/test_readline_history.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/readline/test_readline_history.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/readline/test_readline_history.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,327 @@
+begin
+ require "readline"
+=begin
+ class << Readline::HISTORY
+ def []=(index, str)
+ raise NotImplementedError
+ end
+
+ def pop
+ raise NotImplementedError
+ end
+
+ def shift
+ raise NotImplementedError
+ end
+
+ def delete_at(index)
+ raise NotImplementedError
+ end
+ end
+=end
+
+=begin
+ class << Readline::HISTORY
+ def clear
+ raise NotImplementedError
+ end
+ end
+=end
+rescue LoadError
+else
+ require "test/unit"
+end
+
+class Readline::TestHistory < Test::Unit::TestCase
+ include Readline
+
+ def setup
+ HISTORY.clear
+ end
+
+ def test_safe_level_4
+ method_args =
+ [
+ ["[]", [0]],
+ ["[]=", [0, "s"]],
+ ["\<\<", ["s"]],
+ ["push", ["s"]],
+ ["pop", []],
+ ["shift", []],
+ ["length", []],
+ ["delete_at", [0]],
+ ["clear", []],
+ ]
+ method_args.each do |method_name, args|
+ assert_raise(SecurityError, NotImplementedError,
+ "method=<#{method_name}>") do
+ Thread.start {
+ $SAFE = 4
+ HISTORY.send(method_name.to_sym, *args)
+ assert(true)
+ }.join
+ end
+ end
+
+ assert_raise(SecurityError, NotImplementedError,
+ "method=<each>") do
+ Thread.start {
+ $SAFE = 4
+ HISTORY.each { |s|
+ assert(true)
+ }
+ }.join
+ end
+ end
+
+ def test_to_s
+ expected = "HISTORY"
+ assert_equal(expected, HISTORY.to_s)
+ end
+
+ def test_get
+ lines = push_history(5)
+ lines.each_with_index do |s, i|
+ assert_external_string_equal(s, HISTORY[i])
+ end
+ end
+
+ def test_get__negative
+ lines = push_history(5)
+ (1..5).each do |i|
+ assert_equal(lines[-i], HISTORY[-i])
+ end
+ end
+
+ def test_get__out_of_range
+ lines = push_history(5)
+ invalid_indexes = [5, 6, 100, -6, -7, -100]
+ invalid_indexes.each do |i|
+ assert_raise(IndexError, "i=<#{i}>") do
+ HISTORY[i]
+ end
+ end
+
+ invalid_indexes = [100_000_000_000_000_000_000,
+ -100_000_000_000_000_000_000]
+ invalid_indexes.each do |i|
+ assert_raise(RangeError, "i=<#{i}>") do
+ HISTORY[i]
+ end
+ end
+ end
+
+ def test_set
+ begin
+ lines = push_history(5)
+ 5.times do |i|
+ expected = "set: #{i}"
+ HISTORY[i] = expected
+ assert_external_string_equal(expected, HISTORY[i])
+ end
+ rescue NotImplementedError
+ end
+ end
+
+ def test_set__out_of_range
+ assert_raise(IndexError, NotImplementedError, "index=<0>") do
+ HISTORY[0] = "set: 0"
+ end
+
+ lines = push_history(5)
+ invalid_indexes = [5, 6, 100, -6, -7, -100]
+ invalid_indexes.each do |i|
+ assert_raise(IndexError, NotImplementedError, "index=<#{i}>") do
+ HISTORY[i] = "set: #{i}"
+ end
+ end
+
+ invalid_indexes = [100_000_000_000_000_000_000,
+ -100_000_000_000_000_000_000]
+ invalid_indexes.each do |i|
+ assert_raise(RangeError, NotImplementedError, "index=<#{i}>") do
+ HISTORY[i] = "set: #{i}"
+ end
+ end
+ end
+
+ def test_push
+ 5.times do |i|
+ s = i.to_s
+ assert_equal(HISTORY, HISTORY.push(s))
+ assert_external_string_equal(s, HISTORY[i])
+ end
+ assert_equal(5, HISTORY.length)
+ end
+
+ def test_push__operator
+ 5.times do |i|
+ s = i.to_s
+ assert_equal(HISTORY, HISTORY << s)
+ assert_external_string_equal(s, HISTORY[i])
+ end
+ assert_equal(5, HISTORY.length)
+ end
+
+ def test_push__plural
+ assert_equal(HISTORY, HISTORY.push("0", "1", "2", "3", "4"))
+ (0..4).each do |i|
+ assert_external_string_equal(i.to_s, HISTORY[i])
+ end
+ assert_equal(5, HISTORY.length)
+
+ assert_equal(HISTORY, HISTORY.push("5", "6", "7", "8", "9"))
+ (5..9).each do |i|
+ assert_external_string_equal(i.to_s, HISTORY[i])
+ end
+ assert_equal(10, HISTORY.length)
+ end
+
+ def test_pop
+ begin
+ assert_equal(nil, HISTORY.pop)
+
+ lines = push_history(5)
+ (1..5).each do |i|
+ assert_external_string_equal(lines[-i], HISTORY.pop)
+ assert_equal(lines.length - i, HISTORY.length)
+ end
+
+ assert_equal(nil, HISTORY.pop)
+ rescue NotImplementedError
+ end
+ end
+
+ def test_shift
+ begin
+ assert_equal(nil, HISTORY.shift)
+
+ lines = push_history(5)
+ (0..4).each do |i|
+ assert_external_string_equal(lines[i], HISTORY.shift)
+ assert_equal(lines.length - (i + 1), HISTORY.length)
+ end
+
+ assert_equal(nil, HISTORY.shift)
+ rescue NotImplementedError
+ end
+ end
+
+ def test_each
+ e = HISTORY.each do |s|
+ assert(false) # not reachable
+ end
+ assert_equal(HISTORY, e)
+ lines = push_history(5)
+ i = 0
+ e = HISTORY.each do |s|
+ assert_external_string_equal(HISTORY[i], s)
+ assert_external_string_equal(lines[i], s)
+ i += 1
+ end
+ assert_equal(HISTORY, e)
+ end
+
+ def test_each__enumerator
+ e = HISTORY.each
+ assert_instance_of(Enumerator, e)
+ end
+
+ def test_length
+ assert_equal(0, HISTORY.length)
+ push_history(1)
+ assert_equal(1, HISTORY.length)
+ push_history(4)
+ assert_equal(5, HISTORY.length)
+ HISTORY.clear
+ assert_equal(0, HISTORY.length)
+ end
+
+ def test_empty_p
+ 2.times do
+ assert(HISTORY.empty?)
+ HISTORY.push("s")
+ assert_equal(false, HISTORY.empty?)
+ HISTORY.clear
+ assert(HISTORY.empty?)
+ end
+ end
+
+ def test_delete_at
+ begin
+ lines = push_history(5)
+ (0..4).each do |i|
+ assert_external_string_equal(lines[i], HISTORY.delete_at(0))
+ end
+ assert(HISTORY.empty?)
+
+ lines = push_history(5)
+ (1..5).each do |i|
+ assert_external_string_equal(lines[lines.length - i], HISTORY.delete_at(-1))
+ end
+ assert(HISTORY.empty?)
+
+ lines = push_history(5)
+ assert_external_string_equal(lines[0], HISTORY.delete_at(0))
+ assert_external_string_equal(lines[4], HISTORY.delete_at(3))
+ assert_external_string_equal(lines[1], HISTORY.delete_at(0))
+ assert_external_string_equal(lines[3], HISTORY.delete_at(1))
+ assert_external_string_equal(lines[2], HISTORY.delete_at(0))
+ assert(HISTORY.empty?)
+ rescue NotImplementedError
+ end
+ end
+
+ def test_delete_at__out_of_range
+ assert_raise(IndexError, NotImplementedError, "index=<0>") do
+ HISTORY.delete_at(0)
+ end
+
+ lines = push_history(5)
+ invalid_indexes = [5, 6, 100, -6, -7, -100]
+ invalid_indexes.each do |i|
+ assert_raise(IndexError, NotImplementedError, "index=<#{i}>") do
+ HISTORY.delete_at(i)
+ end
+ end
+
+ invalid_indexes = [100_000_000_000_000_000_000,
+ -100_000_000_000_000_000_000]
+ invalid_indexes.each do |i|
+ assert_raise(RangeError, NotImplementedError, "index=<#{i}>") do
+ HISTORY.delete_at(i)
+ end
+ end
+ end
+
+ private
+
+ def push_history(num)
+ lines = []
+ num.times do |i|
+ s = "a"
+ i.times do
+ s = s.succ
+ end
+ lines.push("#{i + 1}:#{s}")
+ end
+ HISTORY.push(*lines)
+ return lines
+ end
+
+ def assert_external_string_equal(expected, actual)
+ assert_equal(expected, actual)
+ assert_equal(get_default_internal_encoding, actual.encoding)
+ end
+
+ def get_default_internal_encoding
+ return Encoding.default_internal || Encoding.find("locale")
+ end
+end if defined?(::Readline) && defined?(::Readline::HISTORY) &&
+ (
+ begin
+ Readline::HISTORY.clear
+ rescue NotImplementedError
+ false
+ end
+ )
Added: MacRuby/trunk/test/test-mri/test/resolv/test_addr.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/resolv/test_addr.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/resolv/test_addr.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,16 @@
+require 'test/unit'
+require 'resolv'
+require 'socket'
+
+class TestResolvAddr < Test::Unit::TestCase
+ def test_invalid_ipv4_address
+ assert_not_match(Resolv::IPv4::Regex, "1.2.3.256", "[ruby-core:29501]")
+ 1000.times {|i|
+ if i < 256
+ assert_match(Resolv::IPv4::Regex, "#{i}.#{i}.#{i}.#{i}")
+ else
+ assert_not_match(Resolv::IPv4::Regex, "#{i}.#{i}.#{i}.#{i}")
+ end
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/resolv/test_dns.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/resolv/test_dns.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/resolv/test_dns.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,107 @@
+require 'test/unit'
+require 'resolv'
+require 'socket'
+
+class TestResolvDNS < Test::Unit::TestCase
+ def setup
+ @save_do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup
+ BasicSocket.do_not_reverse_lookup = true
+ end
+
+ def teardown
+ BasicSocket.do_not_reverse_lookup = @save_do_not_reverse_lookup
+ end
+
+ def with_udp(host, port)
+ u = UDPSocket.new
+ begin
+ u.bind(host, port)
+ yield u
+ ensure
+ u.close
+ end
+ end
+
+ def test_query_ipv4_address
+ with_udp('127.0.0.1', 0) {|u|
+ _, server_port, _, server_address = u.addr
+ begin
+ th = Thread.new {
+ Resolv::DNS.open(:nameserver_port => [[server_address, server_port]]) {|dns|
+ dns.getresources("foo.example.org", Resolv::DNS::Resource::IN::A)
+ }
+ }
+ msg, (af, client_port, _, client_address) = u.recvfrom(4096)
+ id, word2, qdcount, ancount, nscount, arcount = msg.unpack("nnnnnn")
+ qr = (word2 & 0x8000) >> 15
+ opcode = (word2 & 0x7800) >> 11
+ aa = (word2 & 0x0400) >> 10
+ tc = (word2 & 0x0200) >> 9
+ rd = (word2 & 0x0100) >> 8
+ ra = (word2 & 0x0080) >> 7
+ z = (word2 & 0x0070) >> 4
+ rcode = word2 & 0x000f
+ rest = msg[12..-1]
+ assert_equal(0, qr) # 0:query 1:response
+ assert_equal(0, opcode) # 0:QUERY 1:IQUERY 2:STATUS
+ assert_equal(0, aa) # Authoritative Answer
+ assert_equal(0, tc) # TrunCation
+ assert_equal(1, rd) # Recursion Desired
+ assert_equal(0, ra) # Recursion Available
+ assert_equal(0, z) # Reserved for future use
+ assert_equal(0, rcode) # 0:No-error 1:Format-error 2:Server-failure 3:Name-Error 4:Not-Implemented 5:Refused
+ assert_equal(1, qdcount) # number of entries in the question section.
+ assert_equal(0, ancount) # number of entries in the answer section.
+ assert_equal(0, nscount) # number of entries in the authority records section.
+ assert_equal(0, arcount) # number of entries in the additional records section.
+ name = [3, "foo", 7, "example", 3, "org", 0].pack("Ca*Ca*Ca*C")
+ assert_operator(rest, :start_with?, name)
+ rest = rest[name.length..-1]
+ assert_equal(4, rest.length)
+ qtype, qclass = rest.unpack("nn")
+ assert_equal(1, qtype) # A
+ assert_equal(1, qtype) # IN
+ id = id
+ qr = 1
+ opcode = opcode
+ aa = 0
+ tc = 0
+ rd = rd
+ ra = 1
+ z = 0
+ rcode = 0
+ qdcount = 0
+ ancount = 1
+ nscount = 0
+ arcount = 0
+ word2 = (qr << 15) |
+ (opcode << 11) |
+ (aa << 10) |
+ (tc << 9) |
+ (rd << 8) |
+ (ra << 7) |
+ (z << 4) |
+ rcode
+ msg = [id, word2, qdcount, ancount, nscount, arcount].pack("nnnnnn")
+ type = 1
+ klass = 1
+ ttl = 3600
+ rdlength = 4
+ rdata = [192,0,2,1].pack("CCCC") # 192.0.2.1 (TEST-NET address) RFC 3330
+ rr = [name, type, klass, ttl, rdlength, rdata].pack("a*nnNna*")
+ msg << rr
+ u.send(msg, 0, client_address, client_port)
+ result = th.value
+ assert_instance_of(Array, result)
+ assert_equal(1, result.length)
+ rr = result[0]
+ assert_instance_of(Resolv::DNS::Resource::IN::A, rr)
+ assert_instance_of(Resolv::IPv4, rr.address)
+ assert_equal("192.0.2.1", rr.address.to_s)
+ assert_equal(3600, rr.ttl)
+ ensure
+ th.join
+ end
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rexml/test_document.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rexml/test_document.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rexml/test_document.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+
+require "rexml/document"
+require "test/unit"
+
+class REXML::TestDocument < Test::Unit::TestCase
+ def test_version_attributes_to_s
+ doc = REXML::Document.new(<<-eoxml)
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
+ <svg id="svg2"
+ xmlns:sodipodi="foo"
+ xmlns:inkscape="bar"
+ sodipodi:version="0.32"
+ inkscape:version="0.44.1"
+ >
+ </svg>
+ eoxml
+
+ string = doc.to_s
+ assert_match('xmlns:sodipodi', string)
+ assert_match('xmlns:inkscape', string)
+ assert_match('sodipodi:version', string)
+ assert_match('inkscape:version', string)
+ end
+
+ def test_new
+ doc = REXML::Document.new(<<EOF)
+<?xml version="1.0" encoding="UTF-8"?>
+<message>Hello world!</message>
+EOF
+ assert_equal("Hello world!", doc.root.children.first.value)
+ end
+
+ XML_WITH_NESTED_ENTITY = <<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE member [
+ <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
+ <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
+ <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
+ <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
+ <!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
+ <!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
+ <!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
+]>
+<member>
+&a;
+</member>
+EOF
+
+ XML_WITH_4_ENTITY_EXPANSION = <<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE member [
+ <!ENTITY a "a">
+ <!ENTITY a2 "&a; &a;">
+]>
+<member>
+&a;
+&a2;
+<
+</member>
+EOF
+
+ def test_entity_expansion_limit
+ doc = REXML::Document.new(XML_WITH_NESTED_ENTITY)
+ assert_raise(RuntimeError) do
+ doc.root.children.first.value
+ end
+ REXML::Document.entity_expansion_limit = 100
+ assert_equal(100, REXML::Document.entity_expansion_limit)
+ doc = REXML::Document.new(XML_WITH_NESTED_ENTITY)
+ assert_raise(RuntimeError) do
+ doc.root.children.first.value
+ end
+ assert_equal(101, doc.entity_expansion_count)
+
+ REXML::Document.entity_expansion_limit = 4
+ doc = REXML::Document.new(XML_WITH_4_ENTITY_EXPANSION)
+ assert_equal("\na\na a\n<\n", doc.root.children.first.value)
+ REXML::Document.entity_expansion_limit = 3
+ doc = REXML::Document.new(XML_WITH_4_ENTITY_EXPANSION)
+ assert_raise(RuntimeError) do
+ doc.root.children.first.value
+ end
+ ensure
+ REXML::Document.entity_expansion_limit = 10000
+ end
+
+ def test_tag_in_cdata_with_not_ascii_only_but_ascii8bit_encoding_source
+ tag = "<b>...</b>"
+ message = "こんにちは、世界!" # Hello world! in Japanese
+ xml = <<EOX
+<?xml version="1.0" encoding="UTF-8"?>
+<message><![CDATA[#{tag}#{message}]]></message>
+EOX
+ xml.force_encoding(Encoding::ASCII_8BIT)
+ doc = REXML::Document.new(xml)
+ assert_equal("#{tag}#{message}", doc.root.children.first.value)
+ end
+
+ def test_xml_declaration_standalone
+ bug2539 = '[ruby-core:27345]'
+ doc = REXML::Document.new('<?xml version="1.0" standalone="no" ?>')
+ assert_equal('no', doc.stand_alone?, bug2539)
+ doc = REXML::Document.new('<?xml version="1.0" standalone= "no" ?>')
+ assert_equal('no', doc.stand_alone?, bug2539)
+ doc = REXML::Document.new('<?xml version="1.0" standalone= "no" ?>')
+ assert_equal('no', doc.stand_alone?, bug2539)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rinda/test_rinda.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rinda/test_rinda.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rinda/test_rinda.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,553 @@
+require 'test/unit'
+
+require 'drb/drb'
+require 'drb/eq'
+require 'rinda/tuplespace'
+
+require 'singleton'
+
+module Rinda
+
+class MockClock
+ include Singleton
+
+ class MyTS < Rinda::TupleSpace
+ def keeper_thread
+ nil
+ end
+ end
+
+ def initialize
+ @now = 2
+ @reso = 1
+ @ts = MyTS.new
+ @ts.write([2, :now])
+ @inf = 2**31 - 1
+ end
+
+ def now
+ @now.to_f
+ end
+
+ def at(n)
+ n
+ end
+
+ def _forward(n=nil)
+ now ,= @ts.take([nil, :now])
+ @now = now + n
+ n = @reso if n.nil?
+ @ts.write([@now, :now])
+ end
+
+ def forward(n)
+ while n > 0
+ _forward(@reso)
+ n -= @reso
+ Thread.pass
+ end
+ end
+
+ def rewind
+ now ,= @ts.take([nil, :now])
+ @ts.write([@inf, :now])
+ @ts.take([nil, :now])
+ @now = 2
+ @ts.write([2, :now])
+ end
+
+ def sleep(n=nil)
+ now ,= @ts.read([nil, :now])
+ @ts.read([(now + n).. at inf, :now])
+ 0
+ end
+end
+
+module Time
+ def sleep(n)
+ @m.sleep(n)
+ end
+ module_function :sleep
+
+ def at(n)
+ n
+ end
+ module_function :at
+
+ def now
+ @m ? @m.now : 2
+ end
+ module_function :now
+
+ def rewind
+ @m.rewind
+ end
+ module_function :rewind
+
+ def forward(n)
+ @m.forward(n)
+ end
+ module_function :forward
+
+ @m = MockClock.instance
+end
+
+class TupleSpace
+ def sleep(n)
+ Time.sleep(n)
+ end
+end
+
+module TupleSpaceTestModule
+ def sleep(n)
+ if Thread.current == Thread.main
+ Time.forward(n)
+ else
+ Time.sleep(n)
+ end
+ end
+
+ def thread_join(th)
+ while th.alive?
+ Kernel.sleep(0.1)
+ sleep(1)
+ end
+ th.value
+ end
+
+ def test_00_tuple
+ tuple = Rinda::TupleEntry.new([1,2,3])
+ assert(!tuple.canceled?)
+ assert(!tuple.expired?)
+ assert(tuple.alive?)
+ end
+
+ def test_00_template
+ tmpl = Rinda::Template.new([1,2,3])
+ assert_equal(3, tmpl.size)
+ assert_equal(3, tmpl[2])
+ assert(tmpl.match([1,2,3]))
+ assert(!tmpl.match([1,nil,3]))
+
+ tmpl = Rinda::Template.new([/^rinda/i, nil, :hello])
+ assert_equal(3, tmpl.size)
+ assert(tmpl.match(['Rinda', 2, :hello]))
+ assert(!tmpl.match(['Rinda', 2, Symbol]))
+ assert(!tmpl.match([1, 2, :hello]))
+ assert(tmpl.match([/^rinda/i, 2, :hello]))
+
+ tmpl = Rinda::Template.new([Symbol])
+ assert_equal(1, tmpl.size)
+ assert(tmpl.match([:hello]))
+ assert(tmpl.match([Symbol]))
+ assert(!tmpl.match(['Symbol']))
+
+ tmpl = Rinda::Template.new({"message"=>String, "name"=>String})
+ assert_equal(2, tmpl.size)
+ assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
+ assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
+ assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
+ assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
+
+ assert_raise(Rinda::InvalidHashTupleKey) do
+ tmpl = Rinda::Template.new({:message=>String, "name"=>String})
+ end
+ tmpl = Rinda::Template.new({"name"=>String})
+ assert_equal(1, tmpl.size)
+ assert(tmpl.match({"name"=>"Foo"}))
+ assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
+ assert(!tmpl.match({"message"=>:symbol, "name"=>"Foo", "1"=>2}))
+ assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
+ assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
+
+ tmpl = Rinda::Template.new({"message"=>String, "name"=>String})
+ assert_equal(2, tmpl.size)
+ assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
+ assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
+ assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
+ assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
+
+ tmpl = Rinda::Template.new({"message"=>String})
+ assert_equal(1, tmpl.size)
+ assert(tmpl.match({"message"=>"Hello"}))
+ assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
+ assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
+ assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
+ assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
+
+ tmpl = Rinda::Template.new({"message"=>String, "name"=>nil})
+ assert_equal(2, tmpl.size)
+ assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
+ assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
+ assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
+ assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
+
+ assert_raise(Rinda::InvalidHashTupleKey) do
+ @ts.write({:message=>String, "name"=>String})
+ end
+
+ @ts.write([1, 2, 3])
+ assert_equal([1, 2, 3], @ts.take([1, 2, 3]))
+
+ @ts.write({'1'=>1, '2'=>2, '3'=>3})
+ assert_equal({'1'=>1, '2'=>2, '3'=>3}, @ts.take({'1'=>1, '2'=>2, '3'=>3}))
+
+ entry = @ts.write(['1'=>1, '2'=>2, '3'=>3])
+ assert_raise(Rinda::RequestExpiredError) do
+ assert_equal({'1'=>1, '2'=>2, '3'=>3}, @ts.read({'1'=>1}, 0))
+ end
+ entry.cancel
+ end
+
+ def test_00_DRbObject
+ ro = DRbObject.new(nil, "druby://host:1234")
+ tmpl = Rinda::DRbObjectTemplate.new
+ assert(tmpl === ro)
+
+ tmpl = Rinda::DRbObjectTemplate.new("druby://host:1234")
+ assert(tmpl === ro)
+
+ tmpl = Rinda::DRbObjectTemplate.new("druby://host:12345")
+ assert(!(tmpl === ro))
+
+ tmpl = Rinda::DRbObjectTemplate.new(/^druby:\/\/host:/)
+ assert(tmpl === ro)
+
+ ro = DRbObject.new_with(12345, 1234)
+ assert(!(tmpl === ro))
+
+ ro = DRbObject.new_with("druby://foo:12345", 1234)
+ assert(!(tmpl === ro))
+
+ tmpl = Rinda::DRbObjectTemplate.new(/^druby:\/\/(foo|bar):/)
+ assert(tmpl === ro)
+
+ ro = DRbObject.new_with("druby://bar:12345", 1234)
+ assert(tmpl === ro)
+
+ ro = DRbObject.new_with("druby://baz:12345", 1234)
+ assert(!(tmpl === ro))
+ end
+
+ def test_inp_rdp
+ assert_raise(Rinda::RequestExpiredError) do
+ @ts.take([:empty], 0)
+ end
+
+ assert_raise(Rinda::RequestExpiredError) do
+ @ts.read([:empty], 0)
+ end
+ end
+
+ def test_ruby_talk_264062
+ th = Thread.new { @ts.take([:empty], 1) }
+ sleep(10)
+ assert_raise(Rinda::RequestExpiredError) do
+ thread_join(th)
+ end
+
+ th = Thread.new { @ts.read([:empty], 1) }
+ sleep(10)
+ assert_raise(Rinda::RequestExpiredError) do
+ thread_join(th)
+ end
+ end
+
+ def test_symbol_tuple
+ @ts.write([:symbol, :symbol])
+ @ts.write(['string', :string])
+ assert_equal([[:symbol, :symbol]], @ts.read_all([:symbol, nil]))
+ assert_equal([[:symbol, :symbol]], @ts.read_all([Symbol, nil]))
+ assert_equal([], @ts.read_all([:nil, nil]))
+ end
+
+ def test_core_01
+ 5.times do |n|
+ @ts.write([:req, 2])
+ end
+
+ assert_equal([[:req, 2], [:req, 2], [:req, 2], [:req, 2], [:req, 2]],
+ @ts.read_all([nil, nil]))
+
+ taker = Thread.new do
+ s = 0
+ while true
+ begin
+ tuple = @ts.take([:req, Integer], 1)
+ assert_equal(2, tuple[1])
+ s += tuple[1]
+ rescue Rinda::RequestExpiredError
+ break
+ end
+ end
+ @ts.write([:ans, s])
+ s
+ end
+
+ assert_equal(10, thread_join(taker))
+ tuple = @ts.take([:ans, nil])
+ assert_equal(10, tuple[1])
+ end
+
+ def test_core_02
+ taker = Thread.new do
+ s = 0
+ while true
+ begin
+ tuple = @ts.take([:req, Integer], 1)
+ assert_equal(2, tuple[1])
+ s += tuple[1]
+ rescue Rinda::RequestExpiredError
+ break
+ end
+ end
+ @ts.write([:ans, s])
+ s
+ end
+
+ 5.times do |n|
+ @ts.write([:req, 2])
+ end
+
+ assert_equal(10, thread_join(taker))
+ tuple = @ts.take([:ans, nil])
+ assert_equal(10, tuple[1])
+ assert_equal([], @ts.read_all([nil, nil]))
+ end
+
+ def test_core_03_notify
+ notify1 = @ts.notify(nil, [:req, Integer])
+ notify2 = @ts.notify(nil, [:ans, Integer], 8)
+ notify3 = @ts.notify(nil, {"message"=>String, "name"=>String}, 8)
+
+ @ts.write({"message"=>"first", "name"=>"3"}, 3)
+ @ts.write({"message"=>"second", "name"=>"1"}, 1)
+ @ts.write({"message"=>"third", "name"=>"0"})
+ @ts.take({"message"=>"third", "name"=>"0"})
+
+ listener1 = Thread.new do
+ lv = 0
+ n = 0
+ notify1.each do |ev, tuple|
+ n += 1
+ if ev == 'write'
+ lv = lv + 1
+ elsif ev == 'take'
+ lv = lv - 1
+ else
+ break
+ end
+ assert(lv >= 0)
+ assert_equal([:req, 2], tuple)
+ end
+ [lv, n]
+ end
+
+ listener2 = Thread.new do
+ result = nil
+ lv = 0
+ n = 0
+ notify2.each do |ev, tuple|
+ n += 1
+ if ev == 'write'
+ lv = lv + 1
+ elsif ev == 'take'
+ lv = lv - 1
+ elsif ev == 'close'
+ result = [lv, n]
+ break
+ end
+ assert(lv >= 0)
+ assert_equal([:ans, 10], tuple)
+ end
+ result
+ end
+
+ taker = Thread.new do
+ s = 0
+ while true
+ begin
+ tuple = @ts.take([:req, Integer], 1)
+ s += tuple[1]
+ rescue Rinda::RequestExpiredError
+ break
+ end
+ end
+ @ts.write([:ans, s])
+ s
+ end
+
+ 5.times do |n|
+ @ts.write([:req, 2])
+ end
+
+ @ts.take({"message"=>"first", "name"=>"3"})
+
+ sleep(4)
+ assert_equal(10, thread_join(taker))
+ # notify2 must not expire until this @ts.take.
+ # sleep(4) might be short enough for the timeout of notify2 (8 secs)
+ tuple = @ts.take([:ans, nil])
+ assert_equal(10, tuple[1])
+ assert_equal([], @ts.read_all([nil, nil]))
+
+ notify1.cancel
+ sleep(7) # notify2 expired (sleep(4)+sleep(7) > 8)
+
+ assert_equal([0, 11], thread_join(listener1))
+ assert_equal([0, 3], thread_join(listener2))
+
+ ary = []
+ ary.push(["write", {"message"=>"first", "name"=>"3"}])
+ ary.push(["write", {"message"=>"second", "name"=>"1"}])
+ ary.push(["write", {"message"=>"third", "name"=>"0"}])
+ ary.push(["take", {"message"=>"third", "name"=>"0"}])
+ ary.push(["take", {"message"=>"first", "name"=>"3"}])
+ ary.push(["delete", {"message"=>"second", "name"=>"1"}])
+ ary.push(["close"])
+
+ notify3.each do |ev|
+ assert_equal(ary.shift, ev)
+ end
+ assert_equal([], ary)
+ end
+
+ def test_cancel_01
+ entry = @ts.write([:removeme, 1])
+ assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
+ entry.cancel
+ assert_equal([], @ts.read_all([nil, nil]))
+
+ template = nil
+ taker = Thread.new do
+ @ts.take([:take, nil], 10) do |t|
+ template = t
+ Thread.new do
+ template.cancel
+ end
+ end
+ end
+
+ sleep(2)
+
+ assert_raise(Rinda::RequestCanceledError) do
+ assert_nil(thread_join(taker))
+ end
+
+ assert(template.canceled?)
+
+ @ts.write([:take, 1])
+
+ assert_equal([[:take, 1]], @ts.read_all([nil, nil]))
+ end
+
+ def test_cancel_02
+ entry = @ts.write([:removeme, 1])
+ assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
+ entry.cancel
+ assert_equal([], @ts.read_all([nil, nil]))
+
+ template = nil
+ reader = Thread.new do
+ @ts.read([:take, nil], 10) do |t|
+ template = t
+ Thread.new do
+ template.cancel
+ end
+ end
+ end
+
+ sleep(2)
+
+ assert_raise(Rinda::RequestCanceledError) do
+ assert_nil(thread_join(reader))
+ end
+
+ assert(template.canceled?)
+
+ @ts.write([:take, 1])
+
+ assert_equal([[:take, 1]], @ts.read_all([nil, nil]))
+ end
+
+ class SimpleRenewer
+ def initialize(sec, n = 1)
+ @sec = sec
+ @n = n
+ end
+
+ def renew
+ return -1 if @n <= 0
+ @n -= 1
+ return @sec
+ end
+ end
+
+ def test_00_renewer
+ tuple = Rinda::TupleEntry.new([1,2,3], true)
+ assert(!tuple.canceled?)
+ assert(tuple.expired?)
+ assert(!tuple.alive?)
+
+ tuple = Rinda::TupleEntry.new([1,2,3], 1)
+ assert(!tuple.canceled?)
+ assert(!tuple.expired?)
+ assert(tuple.alive?)
+ sleep(2)
+ assert(tuple.expired?)
+ assert(!tuple.alive?)
+
+ @renewer = SimpleRenewer.new(1,2)
+ tuple = Rinda::TupleEntry.new([1,2,3], @renewer)
+ assert(!tuple.canceled?)
+ assert(!tuple.expired?)
+ assert(tuple.alive?)
+ sleep(1)
+ assert(!tuple.canceled?)
+ assert(!tuple.expired?)
+ assert(tuple.alive?)
+ sleep(2)
+ assert(tuple.expired?)
+ assert(!tuple.alive?)
+ end
+end
+
+class TupleSpaceTest < Test::Unit::TestCase
+ include TupleSpaceTestModule
+
+ def setup
+ ThreadGroup.new.add(Thread.current)
+ @ts = Rinda::TupleSpace.new(1)
+ end
+ def teardown
+ # implementation-dependent
+ @ts.instance_eval{@keeper.kill if @keeper}
+ end
+end
+
+class TupleSpaceProxyTest < Test::Unit::TestCase
+ include TupleSpaceTestModule
+
+ def setup
+ ThreadGroup.new.add(Thread.current)
+ @ts_base = Rinda::TupleSpace.new(1)
+ @ts = Rinda::TupleSpaceProxy.new(@ts_base)
+ end
+ def teardown
+ # implementation-dependent
+ @ts_base.instance_eval{@keeper.kill if @keeper}
+ end
+
+ def test_remote_array_and_hash
+ @ts.write(DRbObject.new([1, 2, 3]))
+ assert_equal([1, 2, 3], @ts.take([1, 2, 3], 0))
+ @ts.write(DRbObject.new({'head' => 1, 'tail' => 2}))
+ assert_equal({'head' => 1, 'tail' => 2},
+ @ts.take({'head' => 1, 'tail' => 2}, 0))
+ end
+
+ @server = DRb.primary_server || DRb.start_service
+end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rinda/test_tuplebag.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rinda/test_tuplebag.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rinda/test_tuplebag.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,172 @@
+require 'test/unit'
+require 'rinda/tuplespace'
+
+class TestTupleBag < Test::Unit::TestCase
+
+ def setup
+ @tb = Rinda::TupleBag.new
+ end
+
+ def test_delete
+ assert_nothing_raised do
+ val = @tb.delete tup(:val, 1)
+ assert_equal nil, val
+ end
+
+ t = tup(:val, 1)
+ @tb.push t
+
+ val = @tb.delete t
+
+ assert_equal t, val
+
+ assert_equal [], @tb.find_all(tem(:val, 1))
+
+ t1 = tup(:val, 1)
+ t2 = tup(:val, 1)
+ @tb.push t1
+ @tb.push t2
+
+ val = @tb.delete t1
+
+ assert_equal t1, val
+
+ assert_equal [t2], @tb.find_all(tem(:val, 1))
+ end
+
+ def test_delete_unless_alive
+ assert_equal [], @tb.delete_unless_alive
+
+ t1 = tup(:val, nil)
+ t2 = tup(:val, nil)
+
+ @tb.push t1
+ @tb.push t2
+
+ assert_equal [], @tb.delete_unless_alive
+
+ t1.cancel
+
+ assert_equal [t1], @tb.delete_unless_alive, 'canceled'
+
+ t2.renew Object.new
+
+ assert_equal [t2], @tb.delete_unless_alive, 'expired'
+ end
+
+ def test_find
+ template = tem(:val, nil)
+
+ assert_equal nil, @tb.find(template)
+
+ t1 = tup(:other, 1)
+ @tb.push t1
+
+ assert_equal nil, @tb.find(template)
+
+ t2 = tup(:val, 1)
+ @tb.push t2
+
+ assert_equal t2, @tb.find(template)
+
+ t2.cancel
+
+ assert_equal nil, @tb.find(template), 'canceled'
+
+ t3 = tup(:val, 3)
+ @tb.push t3
+
+ assert_equal t3, @tb.find(template)
+
+ t3.renew Object.new
+
+ assert_equal nil, @tb.find(template), 'expired'
+ end
+
+ def test_find_all
+ template = tem(:val, nil)
+
+ t1 = tup(:other, 1)
+ @tb.push t1
+
+ assert_equal [], @tb.find_all(template)
+
+ t2 = tup(:val, 2)
+ t3 = tup(:val, 3)
+
+ @tb.push t2
+ @tb.push t3
+
+ assert_equal [t2, t3], @tb.find_all(template)
+
+ t2.cancel
+
+ assert_equal [t3], @tb.find_all(template), 'canceled'
+
+ t3.renew Object.new
+
+ assert_equal [], @tb.find_all(template), 'expired'
+ end
+
+ def test_find_all_template
+ tuple = tup(:val, 1)
+
+ t1 = tem(:other, nil)
+ @tb.push t1
+
+ assert_equal [], @tb.find_all_template(tuple)
+
+ t2 = tem(:val, nil)
+ t3 = tem(:val, nil)
+
+ @tb.push t2
+ @tb.push t3
+
+ assert_equal [t2, t3], @tb.find_all_template(tuple)
+
+ t2.cancel
+
+ assert_equal [t3], @tb.find_all_template(tuple), 'canceled'
+
+ t3.renew Object.new
+
+ assert_equal [], @tb.find_all_template(tuple), 'expired'
+ end
+
+ def test_has_expires_eh
+ assert !@tb.has_expires?
+
+ t = tup(:val, 1)
+ @tb.push t
+
+ assert @tb.has_expires?
+
+ t.renew Object.new
+
+ assert !@tb.has_expires?
+ end
+
+ def test_push
+ t = tup(:val, 1)
+
+ @tb.push t
+
+ assert_equal t, @tb.find(tem(:val, 1))
+ end
+
+ ##
+ # Create a tuple with +ary+ for its contents
+
+ def tup(*ary)
+ Rinda::TupleEntry.new ary
+ end
+
+ ##
+ # Create a template with +ary+ for its contents
+
+ def tem(*ary)
+ Rinda::TemplateEntry.new ary
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/ripper/dummyparser.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ripper/dummyparser.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ripper/dummyparser.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,190 @@
+#
+# dummyparser.rb
+#
+
+require 'ripper'
+
+class Node
+ def initialize(name, *nodes)
+ @name = name
+ @children = nodes
+ end
+
+ attr_reader :children
+
+ def to_s
+ "#{@name}(#{Node.trim_nil(@children).map {|n| n.to_s }.join(',')})"
+ end
+
+ def self.trim_nil(list)
+ if !list.empty? and list.last.nil?
+ list = list[0...-1]
+ list.pop while !list.empty? and list.last.nil?
+ end
+ list
+ end
+end
+
+class NodeList
+ def initialize
+ @list = []
+ end
+
+ attr_reader :list
+
+ def push(item)
+ @list.push item
+ self
+ end
+
+ def prepend(items)
+ @list.unshift items
+ end
+
+ def to_s
+ "[#{@list.join(',')}]"
+ end
+end
+
+class DummyParser < Ripper
+ def hook(name)
+ class << self; self; end.class_eval do
+ define_method(name) do |*a, &b|
+ result = super(*a, &b)
+ yield(*a)
+ result
+ end
+ end
+ self
+ end
+
+ def on_program(stmts)
+ stmts
+ end
+
+ def on_stmts_new
+ NodeList.new
+ end
+
+ def on_stmts_add(stmts, st)
+ stmts.push st
+ stmts
+ end
+
+ def on_void_stmt
+ Node.new('void')
+ end
+
+ def on_var_ref(name)
+ Node.new('ref', name)
+ end
+
+ def on_var_alias(a, b)
+ Node.new('valias', a, b)
+ end
+
+ def on_alias_error(a)
+ Node.new('aliaserr', a)
+ end
+
+ def on_arg_paren(args)
+ args
+ end
+
+ def on_args_new
+ NodeList.new
+ end
+
+ def on_args_add(list, arg)
+ list.push(arg)
+ end
+
+ def on_args_add_block(list, blk)
+ if blk
+ list.push('&' + blk.to_s)
+ else
+ list
+ end
+ end
+
+ def on_args_add_star(list, arg)
+ list.push('*' + arg.to_s)
+ end
+
+ def on_args_prepend(list, args)
+ list.prepend args
+ list
+ end
+
+ def on_method_add_arg(m, arg)
+ if arg == nil
+ arg = on_args_new
+ end
+ m.children.push arg
+ m
+ end
+
+ def on_method_add_block(m, b)
+ on_args_add_block(m.children, b)
+ m
+ end
+
+ def on_paren(params)
+ params
+ end
+
+ def on_brace_block(params, code)
+ Node.new('block', params, code)
+ end
+
+ def on_block_var(params, shadow)
+ params
+ end
+
+ def on_rest_param(var)
+ "*#{var}"
+ end
+
+ def on_blockarg(var)
+ "&#{var}"
+ end
+
+ def on_params(required, optional, rest, more, block)
+ args = NodeList.new
+
+ required.each do |req|
+ args.push(req)
+ end if required
+
+ optional.each do |var, val|
+ args.push("#{var}=#{val}")
+ end if optional
+
+ args.push(rest) if rest
+
+ more.each do |m|
+ args.push(m)
+ end if more
+
+ args.push(block) if block
+ args
+ end
+
+ def on_assoc_new(a, b)
+ Node.new('assoc', a, b)
+ end
+
+ def on_bare_assoc_hash(assoc_list)
+ Node.new('assocs', *assoc_list)
+ end
+
+ def on_assoclist_from_args(a)
+ Node.new('assocs', *a)
+ end
+
+ (Ripper::PARSER_EVENTS.map(&:to_s) - instance_methods(false).map {|n|n.to_s.sub(/^on_/, '')}).each do |event|
+ define_method(:"on_#{event}") do |*args|
+ Node.new(event, *args)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ripper/test_files.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ripper/test_files.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ripper/test_files.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,27 @@
+begin
+ require 'ripper'
+ require 'find'
+ require 'test/unit'
+ ripper_test = true
+ module TestRipper; end
+rescue LoadError
+end
+
+class TestRipper::Generic < Test::Unit::TestCase
+ SRCDIR = File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))
+
+ class Parser < Ripper
+ PARSER_EVENTS.each {|n| eval "def on_#{n}(*args) r = [:#{n}, *args]; r.inspect; Object.new end" }
+ SCANNER_EVENTS.each {|n| eval "def on_#{n}(*args) r = [:#{n}, *args]; r.inspect; Object.new end" }
+ end
+
+ TEST_RATIO = 0.05
+
+ def test_parse_files
+ Find.find("#{SRCDIR}/lib", "#{SRCDIR}/ext", "#{SRCDIR}/sample", "#{SRCDIR}/test") {|n|
+ next if /\.rb\z/ !~ n || !File.file?(n)
+ next if TEST_RATIO < rand
+ assert_nothing_raised("ripper failed to parse: #{n.inspect}") { Parser.new(File.read(n)).parse }
+ }
+ end
+end if ripper_test
Added: MacRuby/trunk/test/test-mri/test/ripper/test_filter.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ripper/test_filter.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ripper/test_filter.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,83 @@
+begin
+ require 'ripper'
+ require 'test/unit'
+ ripper_test = true
+ module TestRipper; end
+rescue LoadError
+end
+
+class TestRipper::Filter < Test::Unit::TestCase
+
+ class Filter < Ripper::Filter
+ def on_default(event, token, data)
+ if data.empty?
+ data[:filename] = filename rescue nil
+ data[:lineno] = lineno
+ data[:column] = column
+ data[:token] = token
+ end
+ data
+ end
+ end
+
+ def filename
+ File.expand_path(__FILE__)
+ end
+
+ def test_filter_filename_unset
+ data = {}
+ filter = Filter.new(File.read(filename))
+ filter.parse(data)
+ assert_equal('-', data[:filename], "[ruby-dev:37856]")
+ assert_equal('-', filter.filename)
+ end
+
+ def test_filter_filename
+ data = {}
+ filter = Filter.new(File.read(filename), filename)
+ assert_equal(filename, filter.filename)
+ filter.parse(data)
+ assert_equal(filename, data[:filename])
+ assert_equal(filename, filter.filename)
+ end
+
+ def test_filter_lineno
+ data = {}
+ src = File.read(filename)
+ src_lines = src.count("\n")
+ filter = Filter.new(src)
+ assert_equal(nil, filter.lineno)
+ filter.parse(data)
+ assert_equal(1, data[:lineno])
+ assert_equal(src_lines, filter.lineno)
+ end
+
+ def test_filter_lineno_set
+ data = {}
+ src = File.read(filename)
+ src_lines = src.count("\n")
+ filter = Filter.new(src, '-', 100)
+ assert_equal(nil, filter.lineno)
+ filter.parse(data)
+ assert_equal(100, data[:lineno])
+ assert_equal(src_lines+100-1, filter.lineno)
+ end
+
+ def test_filter_column
+ data = {}
+ src = File.read(filename)
+ last_columns = src[/(.*)\Z/].size
+ filter = Filter.new(src)
+ assert_equal(nil, filter.column)
+ filter.parse(data)
+ assert_equal(0, data[:column])
+ assert_equal(last_columns, filter.column)
+ end
+
+ def test_filter_token
+ data = {}
+ filter = Filter.new(File.read(filename))
+ filter.parse(data)
+ assert_equal("begin", data[:token])
+ end
+end if ripper_test
Added: MacRuby/trunk/test/test-mri/test/ripper/test_parser_events.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ripper/test_parser_events.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ripper/test_parser_events.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1110 @@
+begin
+ require_relative 'dummyparser'
+ require_relative '../ruby/envutil'
+ require 'test/unit'
+ ripper_test = true
+ module TestRipper; end
+rescue LoadError
+end
+
+class TestRipper::ParserEvents < Test::Unit::TestCase
+
+ # should be enabled
+ def test_event_coverage
+ dispatched = Ripper::PARSER_EVENTS.map {|event,*| event }
+ dispatched.each do |e|
+ assert_equal true, respond_to?("test_#{e}", true),
+ "event not tested: #{e.inspect}"
+ end
+ end
+
+ def parse(str, nm = nil, &bl)
+ dp = DummyParser.new(str)
+ dp.hook(nm, &bl) if nm
+ dp.parse.to_s
+ end
+
+ def test_program
+ thru_program = false
+ assert_equal '[void()]', parse('', :on_program) {thru_program = true}
+ assert_equal true, thru_program
+ end
+
+ def test_stmts_new
+ assert_equal '[void()]', parse('')
+ end
+
+ def test_stmts_add
+ assert_equal '[ref(nil)]', parse('nil')
+ assert_equal '[ref(nil),ref(nil)]', parse('nil;nil')
+ assert_equal '[ref(nil),ref(nil),ref(nil)]', parse('nil;nil;nil')
+ end
+
+ def test_void_stmt
+ assert_equal '[void()]', parse('')
+ assert_equal '[void()]', parse('; ;')
+ end
+
+ def test_var_ref
+ assert_equal '[ref(a)]', parse('a')
+ assert_equal '[ref(nil)]', parse('nil')
+ assert_equal '[ref(true)]', parse('true')
+ end
+
+ def test_BEGIN
+ assert_equal '[BEGIN([void()])]', parse('BEGIN{}')
+ assert_equal '[BEGIN([ref(nil)])]', parse('BEGIN{nil}')
+ end
+
+ def test_END
+ assert_equal '[END([void()])]', parse('END{}')
+ assert_equal '[END([ref(nil)])]', parse('END{nil}')
+ end
+
+ def test_alias
+ assert_equal '[alias(symbol_literal(a),symbol_literal(b))]', parse('alias a b')
+ end
+
+ def test_var_alias
+ assert_equal '[valias($a,$g)]', parse('alias $a $g')
+ end
+
+ def test_alias_error
+ assert_equal '[aliaserr(valias($a,$1))]', parse('alias $a $1')
+ end
+
+ def test_arglist
+ assert_equal '[fcall(m,[])]', parse('m()')
+ assert_equal '[fcall(m,[1])]', parse('m(1)')
+ assert_equal '[fcall(m,[1,2])]', parse('m(1,2)')
+ assert_equal '[fcall(m,[*ref(r)])]', parse('m(*r)')
+ assert_equal '[fcall(m,[1,*ref(r)])]', parse('m(1,*r)')
+ assert_equal '[fcall(m,[1,2,*ref(r)])]', parse('m(1,2,*r)')
+ assert_equal '[fcall(m,[&ref(r)])]', parse('m(&r)')
+ assert_equal '[fcall(m,[1,&ref(r)])]', parse('m(1,&r)')
+ assert_equal '[fcall(m,[1,2,&ref(r)])]', parse('m(1,2,&r)')
+ assert_equal '[fcall(m,[*ref(a),&ref(b)])]', parse('m(*a,&b)')
+ assert_equal '[fcall(m,[1,*ref(a),&ref(b)])]', parse('m(1,*a,&b)')
+ assert_equal '[fcall(m,[1,2,*ref(a),&ref(b)])]', parse('m(1,2,*a,&b)')
+ end
+
+ def test_args_add
+ thru_args_add = false
+ parse('m(a)', :on_args_add) {thru_args_add = true}
+ assert_equal true, thru_args_add
+ end
+
+ def test_args_add_block
+ thru_args_add_block = false
+ parse('m(&b)', :on_args_add_block) {thru_args_add_block = true}
+ assert_equal true, thru_args_add_block
+ end
+
+ def test_args_add_star
+ thru_args_add_star = false
+ parse('m(*a)', :on_args_add_star) {thru_args_add_star = true}
+ assert_equal true, thru_args_add_star
+ thru_args_add_star = false
+ parse('m(*a, &b)', :on_args_add_star) {thru_args_add_star = true}
+ assert_equal true, thru_args_add_star
+ end
+
+ def test_args_new
+ thru_args_new = false
+ parse('m()', :on_args_new) {thru_args_new = true}
+ assert_equal true, thru_args_new
+ end
+
+ def test_arg_paren
+ # FIXME
+ end
+
+ def test_aref
+ assert_equal '[aref(ref(v),[1])]', parse('v[1]')
+ assert_equal '[aref(ref(v),[1,2])]', parse('v[1,2]')
+ end
+
+ def test_assoclist_from_args
+ thru_assoclist_from_args = false
+ parse('{a=>b}', :on_assoclist_from_args) {thru_assoclist_from_args = true}
+ assert_equal true, thru_assoclist_from_args
+ end
+
+ def test_assocs
+ assert_equal '[fcall(m,[assocs(assoc(1,2))])]', parse('m(1=>2)')
+ assert_equal '[fcall(m,[assocs(assoc(1,2),assoc(3,4))])]', parse('m(1=>2,3=>4)')
+ assert_equal '[fcall(m,[3,assocs(assoc(1,2))])]', parse('m(3,1=>2)')
+ end
+
+ def test_assoc_new
+ thru_assoc_new = false
+ parse('{a=>b}', :on_assoc_new) {thru_assoc_new = true}
+ assert_equal true, thru_assoc_new
+ end
+
+ def test_aref_field
+ assert_equal '[assign(aref_field(ref(a),[1]),2)]', parse('a[1]=2')
+ end
+
+ def test_arg_ambiguous
+ thru_arg_ambiguous = false
+ parse('m //', :on_arg_ambiguous) {thru_arg_ambiguous = true}
+ assert_equal true, thru_arg_ambiguous
+ end
+
+ def test_operator_ambiguous
+ thru_operator_ambiguous = false
+ parse('a=1; a %[]', :on_operator_ambiguous) {thru_operator_ambiguous = true}
+ assert_equal true, thru_operator_ambiguous
+ end
+
+ def test_array # array literal
+ assert_equal '[array([1,2,3])]', parse('[1,2,3]')
+ end
+
+ def test_assign # generic assignment
+ assert_equal '[assign(var_field(v),1)]', parse('v=1')
+ end
+
+ def test_assign_error
+ thru_assign_error = false
+ parse('$` = 1', :on_assign_error) {thru_assign_error = true}
+ assert_equal true, thru_assign_error
+ thru_assign_error = false
+ parse('$`, _ = 1', :on_assign_error) {thru_assign_error = true}
+ assert_equal true, thru_assign_error
+
+ thru_assign_error = false
+ parse('self::X = 1', :on_assign_error) {thru_assign_error = true}
+ assert_equal false, thru_assign_error
+ parse('def m\n self::X = 1\nend', :on_assign_error) {thru_assign_error = true}
+ assert_equal true, thru_assign_error
+
+ thru_assign_error = false
+ parse('X = 1', :on_assign_error) {thru_assign_error = true}
+ assert_equal false, thru_assign_error
+ parse('def m\n X = 1\nend', :on_assign_error) {thru_assign_error = true}
+ assert_equal true, thru_assign_error
+
+ thru_assign_error = false
+ parse('::X = 1', :on_assign_error) {thru_assign_error = true}
+ assert_equal false, thru_assign_error
+ parse('def m\n ::X = 1\nend', :on_assign_error) {thru_assign_error = true}
+ assert_equal true, thru_assign_error
+ end
+
+ def test_bare_assoc_hash
+ thru_bare_assoc_hash = false
+ parse('x[a=>b]', :on_bare_assoc_hash) {thru_bare_assoc_hash = true}
+ assert_equal true, thru_bare_assoc_hash
+ thru_bare_assoc_hash = false
+ parse('x[1, a=>b]', :on_bare_assoc_hash) {thru_bare_assoc_hash = true}
+ assert_equal true, thru_bare_assoc_hash
+ thru_bare_assoc_hash = false
+ parse('x(a=>b)', :on_bare_assoc_hash) {thru_bare_assoc_hash = true}
+ assert_equal true, thru_bare_assoc_hash
+ thru_bare_assoc_hash = false
+ parse('x(1, a=>b)', :on_bare_assoc_hash) {thru_bare_assoc_hash = true}
+ assert_equal true, thru_bare_assoc_hash
+ end
+
+ def test_begin
+ thru_begin = false
+ parse('begin end', :on_begin) {thru_begin = true}
+ assert_equal true, thru_begin
+ end
+
+ def test_binary
+ thru_binary = nil
+ %w"and or + - * / % ** | ^ & <=> > >= < <= == === != =~ !~ << >> && ||".each do |op|
+ thru_binary = false
+ parse("a #{op} b", :on_binary) {thru_binary = true}
+ assert_equal true, thru_binary
+ end
+ end
+
+ def test_blockarg
+ thru_blockarg = false
+ parse("def a(&b) end", :on_blockarg) {thru_blockarg = true}
+ assert_equal true, thru_blockarg
+ thru_blockarg = false
+ parse("def a(x, &b) end", :on_blockarg) {thru_blockarg = true}
+ assert_equal true, thru_blockarg
+
+ thru_blockarg = false
+ parse("proc{|&b|}", :on_blockarg) {thru_blockarg = true}
+ assert_equal true, thru_blockarg
+ thru_blockarg = false
+ parse("proc{|x, &b|}", :on_blockarg) {thru_blockarg = true}
+ assert_equal true, thru_blockarg
+ thru_blockarg = false
+ parse("proc{|&b;y|}", :on_blockarg) {thru_blockarg = true}
+ assert_equal true, thru_blockarg
+ thru_blockarg = false
+ parse("proc{|&b,x;y|}", :on_blockarg) {thru_blockarg = true}
+ assert_equal true, thru_blockarg
+
+ thru_blockarg = false
+ parse("proc do |&b| end", :on_blockarg) {thru_blockarg = true}
+ assert_equal true, thru_blockarg
+ thru_blockarg = false
+ parse("proc do |&b, x| end", :on_blockarg) {thru_blockarg = true}
+ assert_equal true, thru_blockarg
+ thru_blockarg = false
+ parse("proc do |&b;y| end", :on_blockarg) {thru_blockarg = true}
+ assert_equal true, thru_blockarg
+ thru_blockarg = false
+ parse("proc do |&b, x;y| end", :on_blockarg) {thru_blockarg = true}
+ assert_equal true, thru_blockarg
+ end
+
+ def test_block_var
+ thru_block_var = false
+ parse("proc{||}", :on_block_var) {thru_block_var = true}
+ assert_equal true, thru_block_var
+ thru_block_var = false
+ parse("proc{| |}", :on_block_var) {thru_block_var = true}
+ assert_equal true, thru_block_var
+ thru_block_var = false
+ parse("proc{|x|}", :on_block_var) {thru_block_var = true}
+ assert_equal true, thru_block_var
+ thru_block_var = false
+ parse("proc{|;y|}", :on_block_var) {thru_block_var = true}
+ assert_equal true, thru_block_var
+ thru_block_var = false
+ parse("proc{|x;y|}", :on_block_var) {thru_block_var = true}
+ assert_equal true, thru_block_var
+
+ thru_block_var = false
+ parse("proc do || end", :on_block_var) {thru_block_var = true}
+ assert_equal true, thru_block_var
+ thru_block_var = false
+ parse("proc do | | end", :on_block_var) {thru_block_var = true}
+ assert_equal true, thru_block_var
+ thru_block_var = false
+ parse("proc do |x| end", :on_block_var) {thru_block_var = true}
+ assert_equal true, thru_block_var
+ thru_block_var = false
+ parse("proc do |;y| end", :on_block_var) {thru_block_var = true}
+ assert_equal true, thru_block_var
+ thru_block_var = false
+ parse("proc do |x;y| end", :on_block_var) {thru_block_var = true}
+ assert_equal true, thru_block_var
+ end
+
+ def test_block_var_add_block
+ # not used
+ end
+
+ def test_block_var_add_star
+ # not used
+ end
+
+ def test_bodystmt
+ thru_bodystmt = false
+ parse("class X\nend", :on_bodystmt) {thru_bodystmt = true}
+ assert_equal true, thru_bodystmt
+ end
+
+ def test_call
+ bug2233 = '[ruby-core:26165]'
+ tree = nil
+
+ thru_call = false
+ assert_nothing_raised {
+ tree = parse("self.foo", :on_call) {thru_call = true}
+ }
+ assert_equal true, thru_call
+ assert_equal "[call(ref(self),.,foo)]", tree
+ thru_call = false
+ assert_nothing_raised(bug2233) {
+ tree = parse("foo.()", :on_call) {thru_call = true}
+ }
+ assert_equal true, thru_call
+ assert_equal "[call(ref(foo),.,call,[])]", tree
+ end
+
+ def test_excessed_comma
+ thru_excessed_comma = false
+ parse("proc{|x,|}", :on_excessed_comma) {thru_excessed_comma = true}
+ assert_equal true, thru_excessed_comma
+ thru_excessed_comma = false
+ parse("proc{|x,y,|}", :on_excessed_comma) {thru_excessed_comma = true}
+ assert_equal true, thru_excessed_comma
+
+ thru_excessed_comma = false
+ parse("proc do |x,| end", :on_excessed_comma) {thru_excessed_comma = true}
+ assert_equal true, thru_excessed_comma
+ thru_excessed_comma = false
+ parse("proc do |x,y,| end", :on_excessed_comma) {thru_excessed_comma = true}
+ assert_equal true, thru_excessed_comma
+ end
+
+ def test_heredoc
+ bug1921 = '[ruby-core:24855]'
+ thru_heredoc_beg = false
+ tree = parse("<<EOS\nheredoc\nEOS\n", :on_heredoc_beg) {thru_heredoc_beg = true}
+ assert_equal true, thru_heredoc_beg
+ assert_match(/string_content\(\),heredoc\n/, tree, bug1921)
+ heredoc = nil
+ parse("<<EOS\nheredoc1\nheredoc2\nEOS\n", :on_string_add) {|n, s| heredoc = s}
+ assert_equal("heredoc1\nheredoc2\n", heredoc, bug1921)
+ heredoc = nil
+ parse("<<-EOS\nheredoc1\nheredoc2\n\tEOS\n", :on_string_add) {|n, s| heredoc = s}
+ assert_equal("heredoc1\nheredoc2\n", heredoc, bug1921)
+ end
+
+ def test_massign
+ thru_massign = false
+ parse("a, b = 1, 2", :on_massign) {thru_massign = true}
+ assert_equal true, thru_massign
+ end
+
+ def test_mlhs_add
+ thru_mlhs_add = false
+ parse("a, b = 1, 2", :on_mlhs_add) {thru_mlhs_add = true}
+ assert_equal true, thru_mlhs_add
+ end
+
+ def test_mlhs_add_star
+ bug2232 = '[ruby-core:26163]'
+
+ thru_mlhs_add_star = false
+ tree = parse("a, *b = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true}
+ assert_equal true, thru_mlhs_add_star
+ assert_match(/mlhs_add_star\(mlhs_add\(mlhs_new\(\),a\),b\)/, tree)
+ thru_mlhs_add_star = false
+ tree = parse("a, *b, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true}
+ assert_equal true, thru_mlhs_add_star
+ assert_match(/mlhs_add\(mlhs_add_star\(mlhs_add\(mlhs_new\(\),a\),b\),mlhs_add\(mlhs_new\(\),c\)\)/, tree, bug2232)
+ end
+
+ def test_mlhs_new
+ thru_mlhs_new = false
+ parse("a, b = 1, 2", :on_mlhs_new) {thru_mlhs_new = true}
+ assert_equal true, thru_mlhs_new
+ end
+
+ def test_mlhs_paren
+ thru_mlhs_paren = false
+ parse("a, b = 1, 2", :on_mlhs_paren) {thru_mlhs_paren = true}
+ assert_equal false, thru_mlhs_paren
+ thru_mlhs_paren = false
+ parse("(a, b) = 1, 2", :on_mlhs_paren) {thru_mlhs_paren = true}
+ assert_equal true, thru_mlhs_paren
+ end
+
+ def test_brace_block
+ thru_brace_block = false
+ parse('proc {}', :on_brace_block) {thru_brace_block = true}
+ assert_equal true, thru_brace_block
+ end
+
+ def test_break
+ thru_break = false
+ parse('proc {break}', :on_break) {thru_break = true}
+ assert_equal true, thru_break
+ end
+
+ def test_case
+ thru_case = false
+ parse('case foo when true; end', :on_case) {thru_case = true}
+ assert_equal true, thru_case
+ end
+
+ def test_class
+ thru_class = false
+ parse('class Foo; end', :on_class) {thru_class = true}
+ assert_equal true, thru_class
+ end
+
+ def test_class_name_error
+ thru_class_name_error = false
+ parse('class foo; end', :on_class_name_error) {thru_class_name_error = true}
+ assert_equal true, thru_class_name_error
+ end
+
+ def test_command
+ thru_command = false
+ parse('foo a b', :on_command) {thru_command = true}
+ assert_equal true, thru_command
+ end
+
+ def test_command_call
+ thru_command_call = false
+ parse('foo.bar a, b', :on_command_call) {thru_command_call = true}
+ assert_equal true, thru_command_call
+ end
+
+ def test_const_ref
+ thru_const_ref = false
+ parse('class A;end', :on_const_ref) {thru_const_ref = true}
+ assert_equal true, thru_const_ref
+ thru_const_ref = false
+ parse('module A;end', :on_const_ref) {thru_const_ref = true}
+ assert_equal true, thru_const_ref
+ end
+
+ def test_const_path_field
+ thru_const_path_field = false
+ parse('foo::X = 1', :on_const_path_field) {thru_const_path_field = true}
+ assert_equal true, thru_const_path_field
+ end
+
+ def test_const_path_ref
+ thru_const_path_ref = false
+ parse('foo::X', :on_const_path_ref) {thru_const_path_ref = true}
+ assert_equal true, thru_const_path_ref
+ end
+
+ def test_def
+ thru_def = false
+ parse('def foo; end', :on_def) {
+ thru_def = true
+ }
+ assert_equal true, thru_def
+ assert_equal '[def(foo,[],bodystmt([void()]))]', parse('def foo ;end')
+ end
+
+ def test_defined
+ thru_defined = false
+ parse('defined?(x)', :on_defined) {thru_defined = true}
+ assert_equal true, thru_defined
+ end
+
+ def test_defs
+ thru_defs = false
+ parse('def foo.bar; end', :on_defs) {thru_defs = true}
+ assert_equal true, thru_defs
+ end
+
+ def test_do_block
+ thru_do_block = false
+ parse('proc do end', :on_do_block) {thru_do_block = true}
+ assert_equal true, thru_do_block
+ end
+
+ def test_dot2
+ thru_dot2 = false
+ parse('a..b', :on_dot2) {thru_dot2 = true}
+ assert_equal true, thru_dot2
+ end
+
+ def test_dot3
+ thru_dot3 = false
+ parse('a...b', :on_dot3) {thru_dot3 = true}
+ assert_equal true, thru_dot3
+ end
+
+ def test_dyna_symbol
+ thru_dyna_symbol = false
+ parse(':"#{foo}"', :on_dyna_symbol) {thru_dyna_symbol = true}
+ assert_equal true, thru_dyna_symbol
+ end
+
+ def test_else
+ thru_else = false
+ parse('if foo; bar else zot end', :on_else) {thru_else = true}
+ assert_equal true, thru_else
+ end
+
+ def test_elsif
+ thru_elsif = false
+ parse('if foo; bar elsif qux; zot end', :on_elsif) {thru_elsif = true}
+ assert_equal true, thru_elsif
+ end
+
+ def test_ensure
+ thru_ensure = false
+ parse('begin foo ensure bar end', :on_ensure) {thru_ensure = true}
+ assert_equal true, thru_ensure
+ end
+
+ def test_fcall
+ thru_fcall = false
+ parse('foo()', :on_fcall) {thru_fcall = true}
+ assert_equal true, thru_fcall
+ end
+
+ def test_field
+ thru_field = false
+ parse('foo.x = 1', :on_field) {thru_field = true}
+ assert_equal true, thru_field
+ end
+
+ def test_for
+ thru_for = false
+ parse('for i in foo; end', :on_for) {thru_for = true}
+ assert_equal true, thru_for
+ end
+
+ def test_hash
+ thru_hash = false
+ parse('{1=>2}', :on_hash) {thru_hash = true}
+ assert_equal true, thru_hash
+ thru_hash = false
+ parse('{a: 2}', :on_hash) {thru_hash = true}
+ assert_equal true, thru_hash
+ end
+
+ def test_if
+ thru_if = false
+ parse('if false; end', :on_if) {thru_if = true}
+ assert_equal true, thru_if
+ end
+
+ def test_if_mod
+ thru_if_mod = false
+ parse('nil if nil', :on_if_mod) {thru_if_mod = true}
+ assert_equal true, thru_if_mod
+ end
+
+ def test_ifop
+ thru_ifop = false
+ parse('a ? b : c', :on_ifop) {thru_ifop = true}
+ assert_equal true, thru_ifop
+ end
+
+ def test_lambda
+ thru_lambda = false
+ parse('->{}', :on_lambda) {thru_lambda = true}
+ assert_equal true, thru_lambda
+ end
+
+ def test_magic_comment
+ thru_magic_comment = false
+ parse('# -*- foo:bar -*-', :on_magic_comment) {thru_magic_comment = true}
+ assert_equal true, thru_magic_comment
+ end
+
+ def test_method_add_block
+ thru_method_add_block = false
+ parse('a {}', :on_method_add_block) {thru_method_add_block = true}
+ assert_equal true, thru_method_add_block
+ thru_method_add_block = false
+ parse('a do end', :on_method_add_block) {thru_method_add_block = true}
+ assert_equal true, thru_method_add_block
+ end
+
+ def test_method_add_arg
+ thru_method_add_arg = false
+ parse('a()', :on_method_add_arg) {thru_method_add_arg = true}
+ assert_equal true, thru_method_add_arg
+ thru_method_add_arg = false
+ parse('a {}', :on_method_add_arg) {thru_method_add_arg = true}
+ assert_equal true, thru_method_add_arg
+ thru_method_add_arg = false
+ parse('a.b(1)', :on_method_add_arg) {thru_method_add_arg = true}
+ assert_equal true, thru_method_add_arg
+ thru_method_add_arg = false
+ parse('a::b(1)', :on_method_add_arg) {thru_method_add_arg = true}
+ assert_equal true, thru_method_add_arg
+ end
+
+ def test_module
+ thru_module = false
+ parse('module A; end', :on_module) {thru_module = true}
+ assert_equal true, thru_module
+ end
+
+ def test_mrhs_add
+ thru_mrhs_add = false
+ parse('a = a, b', :on_mrhs_add) {thru_mrhs_add = true}
+ assert_equal true, thru_mrhs_add
+ end
+
+ def test_mrhs_add_star
+ thru_mrhs_add_star = false
+ parse('a = a, *b', :on_mrhs_add_star) {thru_mrhs_add_star = true}
+ assert_equal true, thru_mrhs_add_star
+ end
+
+ def test_mrhs_new
+ thru_mrhs_new = false
+ parse('a = *a', :on_mrhs_new) {thru_mrhs_new = true}
+ assert_equal true, thru_mrhs_new
+ end
+
+ def test_mrhs_new_from_args
+ thru_mrhs_new_from_args = false
+ parse('a = a, b', :on_mrhs_new_from_args) {thru_mrhs_new_from_args = true}
+ assert_equal true, thru_mrhs_new_from_args
+ end
+
+ def test_next
+ thru_next = false
+ parse('a {next}', :on_next) {thru_next = true}
+ assert_equal true, thru_next
+ end
+
+ def test_opassign
+ thru_opassign = false
+ parse('a += b', :on_opassign) {thru_opassign = true}
+ assert_equal true, thru_opassign
+ thru_opassign = false
+ parse('a -= b', :on_opassign) {thru_opassign = true}
+ assert_equal true, thru_opassign
+ thru_opassign = false
+ parse('a *= b', :on_opassign) {thru_opassign = true}
+ assert_equal true, thru_opassign
+ thru_opassign = false
+ parse('a /= b', :on_opassign) {thru_opassign = true}
+ assert_equal true, thru_opassign
+ thru_opassign = false
+ parse('a %= b', :on_opassign) {thru_opassign = true}
+ assert_equal true, thru_opassign
+ thru_opassign = false
+ parse('a **= b', :on_opassign) {thru_opassign = true}
+ assert_equal true, thru_opassign
+ thru_opassign = false
+ parse('a &= b', :on_opassign) {thru_opassign = true}
+ assert_equal true, thru_opassign
+ thru_opassign = false
+ parse('a |= b', :on_opassign) {thru_opassign = true}
+ assert_equal true, thru_opassign
+ thru_opassign = false
+ parse('a <<= b', :on_opassign) {thru_opassign = true}
+ assert_equal true, thru_opassign
+ thru_opassign = false
+ parse('a >>= b', :on_opassign) {thru_opassign = true}
+ assert_equal true, thru_opassign
+ thru_opassign = false
+ parse('a &&= b', :on_opassign) {thru_opassign = true}
+ assert_equal true, thru_opassign
+ thru_opassign = false
+ parse('a ||= b', :on_opassign) {thru_opassign = true}
+ assert_equal true, thru_opassign
+ end
+
+ def test_param_error
+ thru_param_error = false
+ parse('def foo(A) end', :on_param_error) {thru_param_error = true}
+ assert_equal true, thru_param_error
+ thru_param_error = false
+ parse('def foo($a) end', :on_param_error) {thru_param_error = true}
+ assert_equal true, thru_param_error
+ thru_param_error = false
+ parse('def foo(@a) end', :on_param_error) {thru_param_error = true}
+ assert_equal true, thru_param_error
+ thru_param_error = false
+ parse('def foo(@@a) end', :on_param_error) {thru_param_error = true}
+ assert_equal true, thru_param_error
+ end
+
+ def test_params
+ thru_params = false
+ parse('a {||}', :on_params) {thru_params = true}
+ assert_equal true, thru_params
+ thru_params = false
+ parse('a {|x|}', :on_params) {thru_params = true}
+ assert_equal true, thru_params
+ thru_params = false
+ parse('a {|*x|}', :on_params) {thru_params = true}
+ assert_equal true, thru_params
+ end
+
+ def test_paren
+ thru_paren = false
+ parse('()', :on_paren) {thru_paren = true}
+ assert_equal true, thru_paren
+ end
+
+ def test_parse_error
+ thru_parse_error = false
+ parse('<>', :on_parse_error) {thru_parse_error = true}
+ assert_equal true, thru_parse_error
+ end
+
+ def test_qwords_add
+ thru_qwords_add = false
+ parse('%w[a]', :on_qwords_add) {thru_qwords_add = true}
+ assert_equal true, thru_qwords_add
+ end
+
+ def test_qwords_new
+ thru_qwords_new = false
+ parse('%w[]', :on_qwords_new) {thru_qwords_new = true}
+ assert_equal true, thru_qwords_new
+ end
+
+ def test_redo
+ thru_redo = false
+ parse('redo', :on_redo) {thru_redo = true}
+ assert_equal true, thru_redo
+ end
+
+ def test_regexp_add
+ thru_regexp_add = false
+ parse('/foo/', :on_regexp_add) {thru_regexp_add = true}
+ assert_equal true, thru_regexp_add
+ end
+
+ def test_regexp_literal
+ thru_regexp_literal = false
+ parse('//', :on_regexp_literal) {thru_regexp_literal = true}
+ assert_equal true, thru_regexp_literal
+ end
+
+ def test_regexp_new
+ thru_regexp_new = false
+ parse('//', :on_regexp_new) {thru_regexp_new = true}
+ assert_equal true, thru_regexp_new
+ end
+
+ def test_rescue
+ thru_rescue = false
+ parse('begin; rescue; end', :on_rescue) {thru_rescue = true}
+ assert_equal true, thru_rescue
+ end
+
+ def test_rescue_mod
+ thru_rescue_mod = false
+ parse('nil rescue nil', :on_rescue_mod) {thru_rescue_mod = true}
+ assert_equal true, thru_rescue_mod
+ end
+
+ def test_rest_param
+ thru_rest_param = false
+ parse('def a(*) end', :on_rest_param) {thru_rest_param = true}
+ assert_equal true, thru_rest_param
+ thru_rest_param = false
+ parse('def a(*x) end', :on_rest_param) {thru_rest_param = true}
+ assert_equal true, thru_rest_param
+ end
+
+ def test_retry
+ thru_retry = false
+ parse('retry', :on_retry) {thru_retry = true}
+ assert_equal true, thru_retry
+ end
+
+ def test_return
+ thru_return = false
+ parse('return a', :on_return) {thru_return = true}
+ assert_equal true, thru_return
+ end
+
+ def test_return0
+ thru_return0 = false
+ parse('return', :on_return0) {thru_return0 = true}
+ assert_equal true, thru_return0
+ end
+
+ def test_sclass
+ thru_sclass = false
+ parse('class << a; end', :on_sclass) {thru_sclass = true}
+ assert_equal true, thru_sclass
+ end
+
+ def test_string_add
+ thru_string_add = false
+ parse('"aa"', :on_string_add) {thru_string_add = true}
+ assert_equal true, thru_string_add
+ end
+
+ def test_string_concat
+ thru_string_concat = false
+ parse('"a" "b"', :on_string_concat) {thru_string_concat = true}
+ assert_equal true, thru_string_concat
+ end
+
+ def test_string_content
+ thru_string_content = false
+ parse('""', :on_string_content) {thru_string_content = true}
+ assert_equal true, thru_string_content
+ thru_string_content = false
+ parse('"a"', :on_string_content) {thru_string_content = true}
+ assert_equal true, thru_string_content
+ thru_string_content = false
+ parse('%[a]', :on_string_content) {thru_string_content = true}
+ assert_equal true, thru_string_content
+ thru_string_content = false
+ parse('\'a\'', :on_string_content) {thru_string_content = true}
+ assert_equal true, thru_string_content
+ thru_string_content = false
+ parse('%<a>', :on_string_content) {thru_string_content = true}
+ assert_equal true, thru_string_content
+ thru_string_content = false
+ parse('%!a!', :on_string_content) {thru_string_content = true}
+ assert_equal true, thru_string_content
+ thru_string_content = false
+ parse('%q!a!', :on_string_content) {thru_string_content = true}
+ assert_equal true, thru_string_content
+ thru_string_content = false
+ parse('%Q!a!', :on_string_content) {thru_string_content = true}
+ assert_equal true, thru_string_content
+ end
+
+ def test_string_dvar
+ thru_string_dvar = false
+ parse('"#$a"', :on_string_dvar) {thru_string_dvar = true}
+ assert_equal true, thru_string_dvar
+ thru_string_dvar = false
+ parse('\'#$a\'', :on_string_dvar) {thru_string_dvar = true}
+ assert_equal false, thru_string_dvar
+ thru_string_dvar = false
+ parse('"#@a"', :on_string_dvar) {thru_string_dvar = true}
+ assert_equal true, thru_string_dvar
+ thru_string_dvar = false
+ parse('\'#@a\'', :on_string_dvar) {thru_string_dvar = true}
+ assert_equal false, thru_string_dvar
+ thru_string_dvar = false
+ parse('"#@@a"', :on_string_dvar) {thru_string_dvar = true}
+ assert_equal true, thru_string_dvar
+ thru_string_dvar = false
+ parse('\'#@@a\'', :on_string_dvar) {thru_string_dvar = true}
+ assert_equal false, thru_string_dvar
+ thru_string_dvar = false
+ parse('"#$1"', :on_string_dvar) {thru_string_dvar = true}
+ assert_equal true, thru_string_dvar
+ thru_string_dvar = false
+ parse('\'#$1\'', :on_string_dvar) {thru_string_dvar = true}
+ assert_equal false, thru_string_dvar
+ end
+
+ def test_string_embexpr
+ thru_string_embexpr = false
+ parse('"#{}"', :on_string_embexpr) {thru_string_embexpr = true}
+ assert_equal true, thru_string_embexpr
+ thru_string_embexpr = false
+ parse('\'#{}\'', :on_string_embexpr) {thru_string_embexpr = true}
+ assert_equal false, thru_string_embexpr
+ end
+
+ def test_string_literal
+ thru_string_literal = false
+ parse('""', :on_string_literal) {thru_string_literal = true}
+ assert_equal true, thru_string_literal
+ end
+
+ def test_super
+ thru_super = false
+ parse('super()', :on_super) {thru_super = true}
+ assert_equal true, thru_super
+ end
+
+ def test_symbol
+ thru_symbol = false
+ parse(':a', :on_symbol) {thru_symbol = true}
+ assert_equal true, thru_symbol
+ thru_symbol = false
+ parse(':$a', :on_symbol) {thru_symbol = true}
+ assert_equal true, thru_symbol
+ thru_symbol = false
+ parse(':@a', :on_symbol) {thru_symbol = true}
+ assert_equal true, thru_symbol
+ thru_symbol = false
+ parse(':@@a', :on_symbol) {thru_symbol = true}
+ assert_equal true, thru_symbol
+ thru_symbol = false
+ parse(':==', :on_symbol) {thru_symbol = true}
+ assert_equal true, thru_symbol
+ end
+
+ def test_symbol_literal
+ thru_symbol_literal = false
+ parse(':a', :on_symbol_literal) {thru_symbol_literal = true}
+ assert_equal true, thru_symbol_literal
+ end
+
+ def test_top_const_field
+ thru_top_const_field = false
+ parse('::A=1', :on_top_const_field) {thru_top_const_field = true}
+ assert_equal true, thru_top_const_field
+ end
+
+ def test_top_const_ref
+ thru_top_const_ref = false
+ parse('::A', :on_top_const_ref) {thru_top_const_ref = true}
+ assert_equal true, thru_top_const_ref
+ end
+
+ def test_unary
+ thru_unary = false
+ parse('not a 1, 2', :on_unary) {thru_unary = true}
+ assert_equal true, thru_unary
+ thru_unary = false
+ parse('not (a)', :on_unary) {thru_unary = true}
+ assert_equal true, thru_unary
+ thru_unary = false
+ parse('!a', :on_unary) {thru_unary = true}
+ assert_equal true, thru_unary
+ thru_unary = false
+ parse('-10', :on_unary) {thru_unary = true}
+ assert_equal true, thru_unary
+ thru_unary = false
+ parse('-10*2', :on_unary) {thru_unary = true}
+ assert_equal true, thru_unary
+ thru_unary = false
+ parse('-10.1', :on_unary) {thru_unary = true}
+ assert_equal true, thru_unary
+ thru_unary = false
+ parse('-10.1*2', :on_unary) {thru_unary = true}
+ assert_equal true, thru_unary
+ thru_unary = false
+ parse('-a', :on_unary) {thru_unary = true}
+ assert_equal true, thru_unary
+ thru_unary = false
+ parse('+a', :on_unary) {thru_unary = true}
+ assert_equal true, thru_unary
+ thru_unary = false
+ parse('~a', :on_unary) {thru_unary = true}
+ assert_equal true, thru_unary
+ thru_unary = false
+ parse('not()', :on_unary) {thru_unary = true}
+ assert_equal true, thru_unary
+ end
+
+ def test_undef
+ thru_undef = false
+ parse('undef a', :on_undef) {thru_undef = true}
+ assert_equal true, thru_undef
+ thru_undef = false
+ parse('undef <=>', :on_undef) {thru_undef = true}
+ assert_equal true, thru_undef
+ thru_undef = false
+ parse('undef a, b', :on_undef) {thru_undef = true}
+ assert_equal true, thru_undef
+ end
+
+ def test_unless
+ thru_unless = false
+ parse('unless a; end', :on_unless) {thru_unless = true}
+ assert_equal true, thru_unless
+ end
+
+ def test_unless_mod
+ thru_unless_mod = false
+ parse('nil unless a', :on_unless_mod) {thru_unless_mod = true}
+ assert_equal true, thru_unless_mod
+ end
+
+ def test_until
+ thru_until = false
+ parse('until a; end', :on_until) {thru_until = true}
+ assert_equal true, thru_until
+ end
+
+ def test_until_mod
+ thru_until_mod = false
+ parse('nil until a', :on_until_mod) {thru_until_mod = true}
+ assert_equal true, thru_until_mod
+ end
+
+ def test_var_field
+ thru_var_field = false
+ parse('a = 1', :on_var_field) {thru_var_field = true}
+ assert_equal true, thru_var_field
+ thru_var_field = false
+ parse('a += 1', :on_var_field) {thru_var_field = true}
+ assert_equal true, thru_var_field
+ end
+
+ def test_when
+ thru_when = false
+ parse('case a when b; end', :on_when) {thru_when = true}
+ assert_equal true, thru_when
+ thru_when = false
+ parse('case when a; end', :on_when) {thru_when = true}
+ assert_equal true, thru_when
+ end
+
+ def test_while
+ thru_while = false
+ parse('while a; end', :on_while) {thru_while = true}
+ assert_equal true, thru_while
+ end
+
+ def test_while_mod
+ thru_while_mod = false
+ parse('nil while a', :on_while_mod) {thru_while_mod = true}
+ assert_equal true, thru_while_mod
+ end
+
+ def test_word_add
+ thru_word_add = false
+ parse('%W[a]', :on_word_add) {thru_word_add = true}
+ assert_equal true, thru_word_add
+ end
+
+ def test_word_new
+ thru_word_new = false
+ parse('%W[a]', :on_word_new) {thru_word_new = true}
+ assert_equal true, thru_word_new
+ end
+
+ def test_words_add
+ thru_words_add = false
+ parse('%W[a]', :on_words_add) {thru_words_add = true}
+ assert_equal true, thru_words_add
+ end
+
+ def test_words_new
+ thru_words_new = false
+ parse('%W[]', :on_words_new) {thru_words_new = true}
+ assert_equal true, thru_words_new
+ end
+
+ def test_xstring_add
+ thru_xstring_add = false
+ parse('`x`', :on_xstring_add) {thru_xstring_add = true}
+ assert_equal true, thru_xstring_add
+ end
+
+ def test_xstring_literal
+ thru_xstring_literal = false
+ parse('``', :on_xstring_literal) {thru_xstring_literal = true}
+ assert_equal true, thru_xstring_literal
+ end
+
+ def test_xstring_new
+ thru_xstring_new = false
+ parse('``', :on_xstring_new) {thru_xstring_new = true}
+ assert_equal true, thru_xstring_new
+ end
+
+ def test_yield
+ thru_yield = false
+ parse('yield a', :on_yield) {thru_yield = true}
+ assert_equal true, thru_yield
+ end
+
+ def test_yield0
+ thru_yield0 = false
+ parse('yield', :on_yield0) {thru_yield0 = true}
+ assert_equal true, thru_yield0
+ end
+
+ def test_zsuper
+ thru_zsuper = false
+ parse('super', :on_zsuper) {thru_zsuper = true}
+ assert_equal true, thru_zsuper
+ end
+
+ def test_local_variables
+ cmd = 'command(w,[regexp_literal(regexp_add(regexp_new(),25 # ),/)])'
+ div = 'binary(ref(w),/,25)'
+ var = '[w]'
+ bug1939 = '[ruby-core:24923]'
+
+ assert_equal("[#{cmd}]", parse('w /25 # /'), bug1939)
+ assert_equal("[assign(var_field(w),1),#{div}]", parse("w = 1; w /25 # /"), bug1939)
+ assert_equal("[fcall(p,[],&block([w],[#{div}]))]", parse("p{|w|w /25 # /\n}"), bug1939)
+ assert_equal("[def(p,[w],bodystmt([#{div}]))]", parse("def p(w)\nw /25 # /\nend"), bug1939)
+ end
+
+ def test_block_variables
+ assert_equal("[fcall(proc,[],&block([],[void()]))]", parse("proc{|;y|}"))
+ if defined?(Process::RLIMIT_AS)
+ assert_in_out_err(["-I#{File.dirname(__FILE__)}", "-rdummyparser"],
+ 'Process.setrlimit(Process::RLIMIT_AS,102400); puts DummyParser.new("proc{|;y|}").parse',
+ ["[fcall(proc,[],&block([],[void()]))]"], [], '[ruby-dev:39423]')
+ end
+ end
+
+ def test_unterminated_regexp
+ compile_error = false
+ parse('/', :compile_error) {|msg| compile_error = msg}
+ assert_equal("unterminated regexp meets end of file", compile_error)
+ end
+end if ripper_test
Added: MacRuby/trunk/test/test-mri/test/ripper/test_scanner_events.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ripper/test_scanner_events.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ripper/test_scanner_events.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,812 @@
+#
+# test_scanner_events.rb
+#
+begin
+ require 'ripper'
+ require 'test/unit'
+ ripper_test = true
+ module TestRipper; end
+rescue LoadError
+end
+
+class TestRipper::ScannerEvents < Test::Unit::TestCase
+
+ def test_event_coverage
+ dispatched = Ripper::SCANNER_EVENTS.map {|event,_| event }
+ dispatched.each do |e|
+ assert_equal true, respond_to?("test_#{e}", true), "event not tested: #{e}"
+ end
+ end
+
+ def scan(target, str)
+ sym = "on_#{target}".intern
+ Ripper.lex(str).select {|_1,type,_2| type == sym }.map {|_1,_2,tok| tok }
+ end
+
+ def test_tokenize
+ assert_equal [],
+ Ripper.tokenize('')
+ assert_equal ['a'],
+ Ripper.tokenize('a')
+ assert_equal ['1'],
+ Ripper.tokenize('1')
+ assert_equal ['1', ';', 'def', ' ', 'm', '(', 'arg', ')', 'end'],
+ Ripper.tokenize("1;def m(arg)end")
+ assert_equal ['print', '(', '<<EOS', ')', "\n", "heredoc\n", "EOS\n"],
+ Ripper.tokenize("print(<<EOS)\nheredoc\nEOS\n")
+ assert_equal ['print', '(', ' ', '<<EOS', ')', "\n", "heredoc\n", "EOS\n"],
+ Ripper.tokenize("print( <<EOS)\nheredoc\nEOS\n")
+ assert_equal ["\#\n", "\n", "\#\n", "\n", "nil", "\n"],
+ Ripper.tokenize("\#\n\n\#\n\nnil\n")
+ end
+
+ def test_lex
+ assert_equal [],
+ Ripper.lex('')
+ assert_equal [[[1,0], :on_ident, "a"]],
+ Ripper.lex('a')
+ assert_equal [[[1, 0], :on_kw, "nil"]],
+ Ripper.lex("nil")
+ assert_equal [[[1, 0], :on_kw, "def"],
+ [[1, 3], :on_sp, " "],
+ [[1, 4], :on_ident, "m"],
+ [[1, 5], :on_lparen, "("],
+ [[1, 6], :on_ident, "a"],
+ [[1, 7], :on_rparen, ")"],
+ [[1, 8], :on_kw, "end"]],
+ Ripper.lex("def m(a)end")
+ assert_equal [[[1, 0], :on_int, "1"],
+ [[1, 1], :on_nl, "\n"],
+ [[2, 0], :on_int, "2"],
+ [[2, 1], :on_nl, "\n"],
+ [[3, 0], :on_int, "3"]],
+ Ripper.lex("1\n2\n3")
+ assert_equal [[[1, 0], :on_heredoc_beg, "<<EOS"],
+ [[1, 5], :on_nl, "\n"],
+ [[2, 0], :on_tstring_content, "heredoc\n"],
+ [[3, 0], :on_heredoc_end, "EOS"]],
+ Ripper.lex("<<EOS\nheredoc\nEOS")
+ assert_equal [[[1, 0], :on_regexp_beg, "/"],
+ [[1, 1], :on_tstring_content, "foo\n"],
+ [[2, 0], :on_tstring_content, "bar"],
+ [[2, 3], :on_regexp_end, "/"]],
+ Ripper.lex("/foo\nbar/")
+ end
+
+ def test_location
+ validate_location ""
+ validate_location " "
+ validate_location "@"
+ validate_location "\n"
+ validate_location "\r\n"
+ validate_location "\n\n\n\n\n\r\n\n\n"
+ validate_location "\n;\n;\n;\n;\n"
+ validate_location "nil"
+ validate_location "@ivar"
+ validate_location "1;2;3"
+ validate_location "1\n2\n3"
+ validate_location "1\n2\n3\n"
+ validate_location "def m(a) nil end"
+ validate_location "if true then false else nil end"
+ validate_location "BEGIN{print nil}"
+ validate_location "%w(a b\nc\r\nd \ne )"
+ validate_location %Q["a\nb\r\nc"]
+ validate_location "print(<<EOS)\nheredoc\nEOS\n"
+ validate_location "print(<<-\"EOS\")\nheredoc\n EOS\n"
+ end
+
+ def validate_location(src)
+ buf = ''
+ Ripper.lex(src).each do |pos, type, tok|
+ line, col = *pos
+ assert_equal buf.count("\n") + 1, line,
+ "wrong lineno: #{tok.inspect} (#{type}) [#{line}:#{col}]"
+ assert_equal buf.sub(/\A.*\n/m, '').size, col,
+ "wrong column: #{tok.inspect} (#{type}) [#{line}:#{col}]"
+ buf << tok
+ end
+ assert_equal src, buf
+ end
+
+ def test_backref
+ assert_equal ["$`", "$&", "$'", '$1', '$2', '$3'],
+ scan('backref', %q[m($~, $`, $&, $', $1, $2, $3)])
+ end
+
+ def test_backtick
+ assert_equal ["`"],
+ scan('backtick', %q[p `make all`])
+ end
+
+ def test_comma
+ assert_equal [','] * 6,
+ scan('comma', %q[ m(0,1,2,3,4,5,6) ])
+ assert_equal [],
+ scan('comma', %q[".,.,.,.,.,.,.."])
+ assert_equal [],
+ scan('comma', "<<EOS\n,,,,,,,,,,\nEOS")
+ end
+
+ def test_period
+ assert_equal [],
+ scan('period', '')
+ assert_equal ['.'],
+ scan('period', 'a.b')
+ assert_equal ['.'],
+ scan('period', 'Object.new')
+ assert_equal [],
+ scan('period', '"."')
+ assert_equal [],
+ scan('period', '1..2')
+ assert_equal [],
+ scan('period', '1...3')
+ end
+
+ def test_const
+ assert_equal ['CONST'],
+ scan('const', 'CONST')
+ assert_equal ['C'],
+ scan('const', 'C')
+ assert_equal ['CONST_A'],
+ scan('const', 'CONST_A')
+ assert_equal ['Const', 'Const2', 'Const3'],
+ scan('const', 'Const; Const2; Const3')
+ assert_equal ['Const'],
+ scan('const', 'Const(a)')
+ assert_equal ['M', 'A', 'A2'],
+ scan('const', 'M(A,A2)')
+ assert_equal [],
+ scan('const', '')
+ assert_equal [],
+ scan('const', 'm(lvar, @ivar, @@cvar, $gvar)')
+ end
+
+ def test_cvar
+ assert_equal [],
+ scan('cvar', '')
+ assert_equal ['@@cvar'],
+ scan('cvar', '@@cvar')
+ assert_equal ['@@__cvar__'],
+ scan('cvar', '@@__cvar__')
+ assert_equal ['@@CVAR'],
+ scan('cvar', '@@CVAR')
+ assert_equal ['@@cvar'],
+ scan('cvar', ' @@cvar#comment')
+ assert_equal ['@@cvar'],
+ scan('cvar', ':@@cvar')
+ assert_equal ['@@cvar'],
+ scan('cvar', 'm(lvar, @ivar, @@cvar, $gvar)')
+ assert_equal [],
+ scan('cvar', '"@@cvar"')
+ end
+
+ def test_embexpr_beg
+ assert_equal [],
+ scan('embexpr_beg', '')
+ assert_equal ['#{'],
+ scan('embexpr_beg', '"#{expr}"')
+ assert_equal [],
+ scan('embexpr_beg', '%q[#{expr}]')
+ assert_equal ['#{'],
+ scan('embexpr_beg', '%Q[#{expr}]')
+ assert_equal ['#{'],
+ scan('embexpr_beg', "m(<<EOS)\n\#{expr}\nEOS")
+ end
+
+ def test_embexpr_end
+=begin
+ # currently detected as "rbrace"
+ assert_equal [],
+ scan('embexpr_end', '')
+ assert_equal ['}'],
+ scan('embexpr_end', '"#{expr}"')
+ assert_equal [],
+ scan('embexpr_end', '%q[#{expr}]')
+ assert_equal ['}'],
+ scan('embexpr_end', '%Q[#{expr}]')
+ assert_equal ['}'],
+ scan('embexpr_end', "m(<<EOS)\n\#{expr}\nEOS")
+=end
+ end
+
+ def test_embvar
+ assert_equal [],
+ scan('embvar', '')
+ assert_equal ['#'],
+ scan('embvar', '"#$gvar"')
+ assert_equal ['#'],
+ scan('embvar', '"#@ivar"')
+ assert_equal ['#'],
+ scan('embvar', '"#@@cvar"')
+ assert_equal [],
+ scan('embvar', '"#lvar"')
+ assert_equal [],
+ scan('embvar', '"#"')
+ assert_equal [],
+ scan('embvar', '"\#$gvar"')
+ assert_equal [],
+ scan('embvar', '"\#@ivar"')
+ assert_equal [],
+ scan('embvar', '%q[#@ivar]')
+ assert_equal ['#'],
+ scan('embvar', '%Q[#@ivar]')
+ end
+
+ def test_float
+ assert_equal [],
+ scan('float', '')
+ assert_equal ['1.000'],
+ scan('float', '1.000')
+ assert_equal ['123.456'],
+ scan('float', '123.456')
+ assert_equal ['1.2345678901234567890123456789'],
+ scan('float', '1.2345678901234567890123456789')
+ assert_equal ['1.000'],
+ scan('float', ' 1.000# comment')
+ assert_equal ['1.234e5'],
+ scan('float', '1.234e5')
+ assert_equal ['1.234e1234567890'],
+ scan('float', '1.234e1234567890')
+ assert_equal ['1.0'],
+ scan('float', 'm(a,b,1.0,c,d)')
+ end
+
+ def test_gvar
+ assert_equal [],
+ scan('gvar', '')
+ assert_equal ['$a'],
+ scan('gvar', '$a')
+ assert_equal ['$A'],
+ scan('gvar', '$A')
+ assert_equal ['$gvar'],
+ scan('gvar', 'm(lvar, @ivar, @@cvar, $gvar)')
+ assert_equal %w($_ $~ $* $$ $? $! $@ $/ $\\ $; $, $. $= $: $< $> $"),
+ scan('gvar', 'm($_, $~, $*, $$, $?, $!, $@, $/, $\\, $;, $,, $., $=, $:, $<, $>, $")')
+ end
+
+ def test_ident
+ assert_equal [],
+ scan('ident', '')
+ assert_equal ['lvar'],
+ scan('ident', 'lvar')
+ assert_equal ['m', 'lvar'],
+ scan('ident', 'm(lvar, @ivar, @@cvar, $gvar)')
+ end
+
+ def test_int
+ assert_equal [],
+ scan('int', '')
+ assert_equal ['1', '10', '100000000000000'],
+ scan('int', 'm(1,10,100000000000000)')
+ end
+
+ def test_ivar
+ assert_equal [],
+ scan('ivar', '')
+ assert_equal ['@ivar'],
+ scan('ivar', '@ivar')
+ assert_equal ['@__ivar__'],
+ scan('ivar', '@__ivar__')
+ assert_equal ['@IVAR'],
+ scan('ivar', '@IVAR')
+ assert_equal ['@ivar'],
+ scan('ivar', 'm(lvar, @ivar, @@cvar, $gvar)')
+ end
+
+ def test_kw
+ assert_equal [],
+ scan('kw', '')
+ assert_equal %w(not),
+ scan('kw', 'not 1')
+ assert_equal %w(and),
+ scan('kw', '1 and 2')
+ assert_equal %w(or),
+ scan('kw', '1 or 2')
+ assert_equal %w(if then else end),
+ scan('kw', 'if 1 then 2 else 3 end')
+ assert_equal %w(if then elsif else end),
+ scan('kw', 'if 1 then 2 elsif 3 else 4 end')
+ assert_equal %w(unless then end),
+ scan('kw', 'unless 1 then end')
+ assert_equal %w(if true),
+ scan('kw', '1 if true')
+ assert_equal %w(unless false),
+ scan('kw', '2 unless false')
+ assert_equal %w(case when when else end),
+ scan('kw', 'case n; when 1; when 2; else 3 end')
+ assert_equal %w(while do nil end),
+ scan('kw', 'while 1 do nil end')
+ assert_equal %w(until do nil end),
+ scan('kw', 'until 1 do nil end')
+ assert_equal %w(while),
+ scan('kw', '1 while 2')
+ assert_equal %w(until),
+ scan('kw', '1 until 2')
+ assert_equal %w(while break next retry end),
+ scan('kw', 'while 1; break; next; retry end')
+ assert_equal %w(for in next break end),
+ scan('kw', 'for x in obj; next 1; break 2 end')
+ assert_equal %w(begin rescue retry end),
+ scan('kw', 'begin 1; rescue; retry; end')
+ assert_equal %w(rescue),
+ scan('kw', '1 rescue 2')
+ assert_equal %w(def redo return end),
+ scan('kw', 'def m() redo; return end')
+ assert_equal %w(def yield yield end),
+ scan('kw', 'def m() yield; yield 1 end')
+ assert_equal %w(def super super super end),
+ scan('kw', 'def m() super; super(); super(1) end')
+ assert_equal %w(alias),
+ scan('kw', 'alias a b')
+ assert_equal %w(undef),
+ scan('kw', 'undef public')
+ assert_equal %w(class end),
+ scan('kw', 'class A < Object; end')
+ assert_equal %w(module end),
+ scan('kw', 'module M; end')
+ assert_equal %w(class end),
+ scan('kw', 'class << obj; end')
+ assert_equal %w(BEGIN),
+ scan('kw', 'BEGIN { }')
+ assert_equal %w(END),
+ scan('kw', 'END { }')
+ assert_equal %w(self),
+ scan('kw', 'self.class')
+ assert_equal %w(nil true false),
+ scan('kw', 'p(nil, true, false)')
+ assert_equal %w(__FILE__ __LINE__),
+ scan('kw', 'p __FILE__, __LINE__')
+ assert_equal %w(defined?),
+ scan('kw', 'defined?(Object)')
+ end
+
+ def test_lbrace
+ assert_equal [],
+ scan('lbrace', '')
+ assert_equal ['{'],
+ scan('lbrace', '3.times{ }')
+ assert_equal ['{'],
+ scan('lbrace', '3.times { }')
+ assert_equal ['{'],
+ scan('lbrace', '3.times{}')
+ assert_equal [],
+ scan('lbrace', '"{}"')
+ assert_equal ['{'],
+ scan('lbrace', '{1=>2}')
+ end
+
+ def test_rbrace
+ assert_equal [],
+ scan('rbrace', '')
+ assert_equal ['}'],
+ scan('rbrace', '3.times{ }')
+ assert_equal ['}'],
+ scan('rbrace', '3.times { }')
+ assert_equal ['}'],
+ scan('rbrace', '3.times{}')
+ assert_equal [],
+ scan('rbrace', '"{}"')
+ assert_equal ['}'],
+ scan('rbrace', '{1=>2}')
+ end
+
+ def test_lbracket
+ assert_equal [],
+ scan('lbracket', '')
+ assert_equal ['['],
+ scan('lbracket', '[]')
+ assert_equal ['['],
+ scan('lbracket', 'a[1]')
+ assert_equal [],
+ scan('lbracket', 'm(%q[])')
+ end
+
+ def test_rbracket
+ assert_equal [],
+ scan('rbracket', '')
+ assert_equal [']'],
+ scan('rbracket', '[]')
+ assert_equal [']'],
+ scan('rbracket', 'a[1]')
+ assert_equal [],
+ scan('rbracket', 'm(%q[])')
+ end
+
+ def test_lparen
+ assert_equal [],
+ scan('lparen', '')
+ assert_equal ['('],
+ scan('lparen', '()')
+ assert_equal ['('],
+ scan('lparen', 'm()')
+ assert_equal ['('],
+ scan('lparen', 'm (a)')
+ assert_equal [],
+ scan('lparen', '"()"')
+ assert_equal [],
+ scan('lparen', '"%w()"')
+ end
+
+ def test_rparen
+ assert_equal [],
+ scan('rparen', '')
+ assert_equal [')'],
+ scan('rparen', '()')
+ assert_equal [')'],
+ scan('rparen', 'm()')
+ assert_equal [')'],
+ scan('rparen', 'm (a)')
+ assert_equal [],
+ scan('rparen', '"()"')
+ assert_equal [],
+ scan('rparen', '"%w()"')
+ end
+
+ def test_op
+ assert_equal [],
+ scan('op', '')
+ assert_equal ['|'],
+ scan('op', '1 | 1')
+ assert_equal ['^'],
+ scan('op', '1 ^ 1')
+ assert_equal ['&'],
+ scan('op', '1 & 1')
+ assert_equal ['<=>'],
+ scan('op', '1 <=> 1')
+ assert_equal ['=='],
+ scan('op', '1 == 1')
+ assert_equal ['==='],
+ scan('op', '1 === 1')
+ assert_equal ['=~'],
+ scan('op', '1 =~ 1')
+ assert_equal ['>'],
+ scan('op', '1 > 1')
+ assert_equal ['>='],
+ scan('op', '1 >= 1')
+ assert_equal ['<'],
+ scan('op', '1 < 1')
+ assert_equal ['<='],
+ scan('op', '1 <= 1')
+ assert_equal ['<<'],
+ scan('op', '1 << 1')
+ assert_equal ['>>'],
+ scan('op', '1 >> 1')
+ assert_equal ['+'],
+ scan('op', '1 + 1')
+ assert_equal ['-'],
+ scan('op', '1 - 1')
+ assert_equal ['*'],
+ scan('op', '1 * 1')
+ assert_equal ['/'],
+ scan('op', '1 / 1')
+ assert_equal ['%'],
+ scan('op', '1 % 1')
+ assert_equal ['**'],
+ scan('op', '1 ** 1')
+ assert_equal ['~'],
+ scan('op', '~1')
+ assert_equal ['-'],
+ scan('op', '-a')
+ assert_equal ['+'],
+ scan('op', '+a')
+ assert_equal ['[]'],
+ scan('op', ':[]')
+ assert_equal ['[]='],
+ scan('op', ':[]=')
+ assert_equal [],
+ scan('op', %q[`make all`])
+ end
+
+ def test_symbeg
+ assert_equal [],
+ scan('symbeg', '')
+ assert_equal [':'],
+ scan('symbeg', ':sym')
+ assert_equal [':'],
+ scan('symbeg', '[1,2,3,:sym]')
+ assert_equal [],
+ scan('symbeg', '":sym"')
+ assert_equal [],
+ scan('symbeg', 'a ? b : c')
+ end
+
+ def test_tstring_beg
+ assert_equal [],
+ scan('tstring_beg', '')
+ assert_equal ['"'],
+ scan('tstring_beg', '"abcdef"')
+ assert_equal ['%q['],
+ scan('tstring_beg', '%q[abcdef]')
+ assert_equal ['%Q['],
+ scan('tstring_beg', '%Q[abcdef]')
+ end
+
+ def test_tstring_content
+ assert_equal [],
+ scan('tstring_content', '')
+ assert_equal ['abcdef'],
+ scan('tstring_content', '"abcdef"')
+ assert_equal ['abcdef'],
+ scan('tstring_content', '%q[abcdef]')
+ assert_equal ['abcdef'],
+ scan('tstring_content', '%Q[abcdef]')
+ assert_equal ['abc', 'def'],
+ scan('tstring_content', '"abc#{1}def"')
+ assert_equal ['sym'],
+ scan('tstring_content', ':"sym"')
+ end
+
+ def test_tstring_end
+ assert_equal [],
+ scan('tstring_end', '')
+ assert_equal ['"'],
+ scan('tstring_end', '"abcdef"')
+ assert_equal [']'],
+ scan('tstring_end', '%q[abcdef]')
+ assert_equal [']'],
+ scan('tstring_end', '%Q[abcdef]')
+ end
+
+ def test_regexp_beg
+ assert_equal [],
+ scan('regexp_beg', '')
+ assert_equal ['/'],
+ scan('regexp_beg', '/re/')
+ assert_equal ['%r<'],
+ scan('regexp_beg', '%r<re>')
+ assert_equal [],
+ scan('regexp_beg', '5 / 5')
+ end
+
+ def test_regexp_end
+ assert_equal [],
+ scan('regexp_end', '')
+ assert_equal ['/'],
+ scan('regexp_end', '/re/')
+ assert_equal ['>'],
+ scan('regexp_end', '%r<re>')
+ end
+
+ def test_words_beg
+ assert_equal [],
+ scan('words_beg', '')
+ assert_equal ['%W('],
+ scan('words_beg', '%W()')
+ assert_equal ['%W('],
+ scan('words_beg', '%W(w w w)')
+ assert_equal ['%W( '],
+ scan('words_beg', '%W( w w w )')
+ end
+
+ def test_qwords_beg
+ assert_equal [],
+ scan('qwords_beg', '')
+ assert_equal ['%w('],
+ scan('qwords_beg', '%w()')
+ assert_equal ['%w('],
+ scan('qwords_beg', '%w(w w w)')
+ assert_equal ['%w( '],
+ scan('qwords_beg', '%w( w w w )')
+ end
+
+ # FIXME: Close paren must not present (`words_end' scanner event?).
+ def test_words_sep
+ assert_equal [],
+ scan('words_sep', '')
+ assert_equal [')'],
+ scan('words_sep', '%w()')
+ assert_equal [' ', ' ', ')'],
+ scan('words_sep', '%w(w w w)')
+ assert_equal [' ', ' ', ' )'],
+ scan('words_sep', '%w( w w w )')
+ assert_equal ["\n", ' ', ' )'],
+ scan('words_sep', "%w( w\nw w )")
+ end
+
+ def test_heredoc_beg
+ assert_equal [],
+ scan('heredoc_beg', '')
+ assert_equal ['<<EOS'],
+ scan('heredoc_beg', "<<EOS\nheredoc\nEOS")
+ assert_equal ['<<EOS'],
+ scan('heredoc_beg', "<<EOS\nheredoc\nEOS\n")
+ assert_equal ['<<EOS'],
+ scan('heredoc_beg', "<<EOS\nheredoc\nEOS \n")
+ assert_equal ['<<-EOS'],
+ scan('heredoc_beg', "<<-EOS\nheredoc\n\tEOS \n")
+ assert_equal ['<<"EOS"'],
+ scan('heredoc_beg', '<<"EOS"'"\nheredoc\nEOS")
+ assert_equal ["<<'EOS'"],
+ scan('heredoc_beg', "<<'EOS'\nheredoc\nEOS")
+ assert_equal ['<<`EOS`'],
+ scan('heredoc_beg', "<<`EOS`\nheredoc\nEOS")
+ assert_equal ['<<" "'],
+ scan('heredoc_beg', '<<" "'"\nheredoc\nEOS")
+ end
+
+ def test_tstring_content_HEREDOC
+ assert_equal [],
+ scan('tstring_content', '')
+ assert_equal ["heredoc\n"],
+ scan('tstring_content', "<<EOS\nheredoc\nEOS")
+ assert_equal ["heredoc\n"],
+ scan('tstring_content', "<<EOS\nheredoc\nEOS\n")
+ assert_equal ["here\ndoc \nEOS \n"],
+ scan('tstring_content', "<<EOS\nhere\ndoc \nEOS \n")
+ assert_equal ["heredoc\n\tEOS \n"],
+ scan('tstring_content', "<<-EOS\nheredoc\n\tEOS \n")
+ end
+
+ def test_heredoc_end
+ assert_equal [],
+ scan('heredoc_end', '')
+ assert_equal ["EOS"],
+ scan('heredoc_end', "<<EOS\nheredoc\nEOS")
+ assert_equal ["EOS\n"],
+ scan('heredoc_end', "<<EOS\nheredoc\nEOS\n")
+ assert_equal [],
+ scan('heredoc_end', "<<EOS\nheredoc\nEOS \n")
+ assert_equal [],
+ scan('heredoc_end', "<<-EOS\nheredoc\n\tEOS \n")
+ end
+
+ def test_semicolon
+ assert_equal [],
+ scan('semicolon', '')
+ assert_equal %w(;),
+ scan('semicolon', ';')
+ assert_equal %w(; ;),
+ scan('semicolon', '; ;')
+ assert_equal %w(; ; ;),
+ scan('semicolon', 'nil;nil;nil;')
+ assert_equal %w(; ; ;),
+ scan('semicolon', 'nil;nil;nil;nil')
+ assert_equal [],
+ scan('semicolon', '";"')
+ assert_equal [],
+ scan('semicolon', '%w(;)')
+ assert_equal [],
+ scan('semicolon', '/;/')
+ end
+
+ def test_comment
+ assert_equal [],
+ scan('comment', '')
+ assert_equal ['# comment'],
+ scan('comment', '# comment')
+ assert_equal ["# comment\n"],
+ scan('comment', "# comment\n")
+ assert_equal ["# comment\n"],
+ scan('comment', "# comment\n1 + 1")
+ assert_equal ["# comment\n"],
+ scan('comment', "1 + 1 + 1# comment\n1 + 1")
+ end
+
+ def test_embdoc_beg
+ assert_equal [],
+ scan('embdoc_beg', '')
+ assert_equal ["=begin\n"],
+ scan('embdoc_beg', "=begin\ndoc\n=end")
+ assert_equal ["=begin \n"],
+ scan('embdoc_beg', "=begin \ndoc\n=end\n")
+ assert_equal ["=begin comment\n"],
+ scan('embdoc_beg', "=begin comment\ndoc\n=end\n")
+ end
+
+ def test_embdoc
+ assert_equal [],
+ scan('embdoc', '')
+ assert_equal ["doc\n"],
+ scan('embdoc', "=begin\ndoc\n=end")
+ assert_equal ["doc\n"],
+ scan('embdoc', "=begin\ndoc\n=end\n")
+ end
+
+ def test_embdoc_end
+ assert_equal [],
+ scan('embdoc_end', '')
+ assert_equal ["=end"],
+ scan('embdoc_end', "=begin\ndoc\n=end")
+ assert_equal ["=end\n"],
+ scan('embdoc_end', "=begin\ndoc\n=end\n")
+ end
+
+ def test_sp
+ assert_equal [],
+ scan('sp', '')
+ assert_equal [' '],
+ scan('sp', ' ')
+ assert_equal [' '],
+ scan('sp', ' 1')
+ assert_equal [],
+ scan('sp', "\n")
+ assert_equal [' '],
+ scan('sp', " \n")
+ assert_equal [' ', ' '],
+ scan('sp', "1 + 1")
+ assert_equal [],
+ scan('sp', "' '")
+ assert_equal [],
+ scan('sp', "%w( )")
+ assert_equal [],
+ scan('sp', "%w( w )")
+ assert_equal [],
+ scan('sp', "p(/ /)")
+ end
+
+ # `nl' event always means End-Of-Statement.
+ def test_nl
+ assert_equal [],
+ scan('nl', '')
+ assert_equal [],
+ scan('nl', "\n")
+ assert_equal ["\n"],
+ scan('nl', "1 + 1\n")
+ assert_equal ["\n", "\n"],
+ scan('nl', "1 + 1\n2 + 2\n")
+ assert_equal [],
+ scan('nl', "1 +\n1")
+ assert_equal [],
+ scan('nl', "1;\n")
+ assert_equal ["\r\n"],
+ scan('nl', "1 + 1\r\n")
+ assert_equal [],
+ scan('nl', "1;\r\n")
+ end
+
+ def test_ignored_nl
+ assert_equal [],
+ scan('ignored_nl', '')
+ assert_equal ["\n"],
+ scan('ignored_nl', "\n")
+ assert_equal [],
+ scan('ignored_nl', "1 + 1\n")
+ assert_equal [],
+ scan('ignored_nl', "1 + 1\n2 + 2\n")
+ assert_equal ["\n"],
+ scan('ignored_nl', "1 +\n1")
+ assert_equal ["\n"],
+ scan('ignored_nl', "1;\n")
+ assert_equal [],
+ scan('ignored_nl', "1 + 1\r\n")
+ assert_equal ["\r\n"],
+ scan('ignored_nl', "1;\r\n")
+ end
+
+ def test___end__
+ assert_equal [],
+ scan('__end__', "")
+ assert_equal ["__END__"],
+ scan('__end__', "__END__")
+ assert_equal ["__END__\n"],
+ scan('__end__', "__END__\n")
+ assert_equal ["__END__\n"],
+ Ripper.tokenize("__END__\njunk junk junk")
+ assert_equal ["__END__"],
+ scan('__end__', "1\n__END__")
+ assert_equal [],
+ scan('__end__', "print('__END__')")
+ end
+
+ def test_CHAR
+ assert_equal [],
+ scan('CHAR', "")
+ assert_equal ["@"],
+ scan('CHAR', "@")
+ assert_equal [],
+ scan('CHAR', "@ivar")
+ end
+
+ def test_label
+ end
+
+ def test_tlambda
+ end
+
+ def test_tlambeg
+ end
+
+ def test_tlambda_arg
+ end
+
+end if ripper_test
Added: MacRuby/trunk/test/test-mri/test/rss/dot.png
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/dot.png (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/dot.png 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,4 @@
+\x89PNG
+
+
+IHDR \x90wS\xDE pHYs H H F\xC9k> vpAg Ǖ_\xED IDAT\xD7c\xF8\xFF\xFF? \xFE\xFE\xDC\xCCY\xE7 IEND\xAEB`\x82
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/rss/rss-assertions.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/rss-assertions.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/rss-assertions.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,2090 @@
+require 'erb'
+
+module RSS
+ module Assertions
+ def _wrap_assertion
+ yield
+ end
+
+ def assert_parse(rss, assert_method, *args)
+ __send__("assert_#{assert_method}", *args) do
+ ::RSS::Parser.parse(rss)
+ end
+ __send__("assert_#{assert_method}", *args) do
+ ::RSS::Parser.parse(rss, false).validate
+ end
+ end
+
+ def assert_ns(prefix, uri)
+ _wrap_assertion do
+ begin
+ yield
+ flunk("Not raise NSError")
+ rescue ::RSS::NSError => e
+ assert_equal(prefix, e.prefix)
+ assert_equal(uri, e.uri)
+ end
+ end
+ end
+
+ def assert_missing_tag(tag, parent)
+ _wrap_assertion do
+ begin
+ yield
+ flunk("Not raise MissingTagError")
+ rescue ::RSS::MissingTagError => e
+ assert_equal(tag, e.tag)
+ assert_equal(parent, e.parent)
+ end
+ end
+ end
+
+ def assert_too_much_tag(tag, parent)
+ _wrap_assertion do
+ begin
+ yield
+ flunk("Not raise TooMuchTagError")
+ rescue ::RSS::TooMuchTagError => e
+ assert_equal(tag, e.tag)
+ assert_equal(parent, e.parent)
+ end
+ end
+ end
+
+ def assert_missing_attribute(tag, attrname)
+ _wrap_assertion do
+ begin
+ yield
+ flunk("Not raise MissingAttributeError")
+ rescue ::RSS::MissingAttributeError => e
+ assert_equal(tag, e.tag)
+ assert_equal(attrname, e.attribute)
+ end
+ end
+ end
+
+ def assert_not_expected_tag(tag, uri, parent)
+ _wrap_assertion do
+ begin
+ yield
+ flunk("Not raise NotExpectedTagError")
+ rescue ::RSS::NotExpectedTagError => e
+ assert_equal(tag, e.tag)
+ assert_equal(uri, e.uri)
+ assert_equal(parent, e.parent)
+ end
+ end
+ end
+
+ def assert_not_available_value(tag, value, attribute=nil)
+ _wrap_assertion do
+ begin
+ yield
+ flunk("Not raise NotAvailableValueError")
+ rescue ::RSS::NotAvailableValueError => e
+ assert_equal(tag, e.tag)
+ assert_equal(value, e.value)
+ assert_equal(attribute, e.attribute)
+ end
+ end
+ end
+
+ def assert_not_set_error(name, variables)
+ _wrap_assertion do
+ begin
+ yield
+ flunk("Not raise NotSetError")
+ rescue ::RSS::NotSetError => e
+ assert_equal(name, e.name)
+ assert_kind_of(Array, variables)
+ assert_equal(variables.sort, e.variables.sort)
+ end
+ end
+ end
+
+ def assert_xml_declaration(version, encoding, standalone, rss)
+ _wrap_assertion do
+ assert_equal(version, rss.version)
+ assert_equal(encoding, rss.encoding)
+ assert_equal(standalone, rss.standalone)
+ end
+ end
+
+ def assert_xml_stylesheet_attrs(attrs, xsl)
+ _wrap_assertion do
+ n_attrs = normalized_attrs(attrs)
+ ::RSS::XMLStyleSheet::ATTRIBUTES.each do |name|
+ assert_equal(n_attrs[name], xsl.__send__(name))
+ end
+ end
+ end
+
+ def assert_xml_stylesheet(target, attrs, xsl)
+ _wrap_assertion do
+ if attrs.has_key?(:href)
+ if !attrs.has_key?(:type) and attrs.has_key?(:guess_type)
+ attrs[:type] = attrs[:guess_type]
+ end
+ assert_equal("xml-stylesheet", target)
+ assert_xml_stylesheet_attrs(attrs, xsl)
+ else
+ assert_nil(target)
+ assert_equal("", xsl.to_s)
+ end
+ end
+ end
+
+ def assert_xml_stylesheet_pis(attrs_ary, rss=nil)
+ _wrap_assertion do
+ if rss.nil?
+ rss = ::RSS::RDF.new
+ setup_rss10(rss)
+ end
+ xss_strs = []
+ attrs_ary.each do |attrs|
+ xss = ::RSS::XMLStyleSheet.new(attrs)
+ xss_strs.push(xss.to_s)
+ rss.xml_stylesheets.push(xss)
+ end
+ pi_str = rss.to_s.gsub(/<\?xml .*\n/, "").gsub(/\s*<[^\?].*\z/m, "")
+ assert_equal(xss_strs.join("\n"), pi_str)
+ end
+ end
+
+ def assert_xml_stylesheets(attrs, xss)
+ _wrap_assertion do
+ xss.each_with_index do |xs, i|
+ assert_xml_stylesheet_attrs(attrs[i], xs)
+ end
+ end
+ end
+
+
+ def assert_atom_person(tag_name, generator)
+ _wrap_assertion do
+ name = "Mark Pilgrim"
+ uri = "http://example.org/"
+ email = "f8dy at example.com"
+
+ assert_parse(generator.call(<<-EOA), :missing_tag, "name", tag_name)
+ <#{tag_name}/>
+EOA
+
+ assert_parse(generator.call(<<-EOA), :missing_tag, "name", tag_name)
+ <#{tag_name}>
+ <uri>#{uri}</uri>
+ <email>#{email}</email>
+ </#{tag_name}>
+EOA
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <#{tag_name}>
+ <name>#{name}</name>
+ </#{tag_name}>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <#{tag_name}>
+ <name>#{name}</name>
+ <uri>#{uri}</uri>
+ <email>#{email}</email>
+ </#{tag_name}>
+EOA
+
+ person = yield(feed)
+ assert_not_nil(person)
+ assert_equal(name, person.name.content)
+ assert_equal(uri, person.uri.content)
+ assert_equal(email, person.email.content)
+ end
+ end
+
+ def assert_atom_category(generator)
+ _wrap_assertion do
+ term = "Music"
+ scheme = "http://xmlns.com/wordnet/1.6/"
+ label = "music"
+
+ missing_args = [:missing_attribute, "category", "term"]
+ assert_parse(generator.call(<<-EOA), *missing_args)
+ <category/>
+EOA
+
+ assert_parse(generator.call(<<-EOA), *missing_args)
+ <category scheme="#{scheme}" label="#{label}"/>
+EOA
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <category term="#{term}"/>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <category term="#{term}" scheme="#{scheme}" label="#{label}"/>
+EOA
+
+ category = yield(feed)
+ assert_not_nil(category)
+ assert_equal(term, category.term)
+ assert_equal(scheme, category.scheme)
+ assert_equal(label, category.label)
+ end
+ end
+
+ def assert_atom_link(generator)
+ _wrap_assertion do
+ href = "http://example.org/feed.atom"
+ rel = "self"
+ type = "application/atom+xml"
+ hreflang = "en"
+ title = "Atom"
+ length = "1024"
+
+ assert_parse(generator.call(<<-EOA), :missing_attribute, "link", "href")
+ <link/>
+EOA
+
+ assert_parse(generator.call(<<-EOA), :missing_attribute, "link", "href")
+ <link rel="#{rel}" type="#{type}" hreflang="#{hreflang}"
+ title="#{title}" length="#{length}"/>
+EOA
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <link href="#{href}"/>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <link href="#{href}" rel="#{rel}" type="#{type}" hreflang="#{hreflang}"
+ title="#{title}" length="#{length}"/>
+EOA
+
+ link = yield(feed)
+ assert_not_nil(link)
+ assert_equal(href, link.href)
+ assert_equal(rel, link.rel)
+ assert_equal(type, link.type)
+ assert_equal(hreflang, link.hreflang)
+ assert_equal(title, link.title)
+ assert_equal(length, link.length)
+
+
+ href = "http://example.org/index.html.ja"
+ parent = link.parent.tag_name
+ return if parent == "source"
+
+ optional_attributes = %w(hreflang="ja" type="text/html")
+ 0.upto(optional_attributes.size) do |i|
+ combination(optional_attributes, i).each do |attributes|
+ attrs = attributes.join(" ")
+ assert_parse(generator.call(<<-EOA), :too_much_tag, "link", parent)
+ <link rel="alternate" #{attrs} href="#{href}"/>
+ <link rel="alternate" #{attrs} href="#{href}"/>
+EOA
+ end
+ end
+ end
+ end
+
+ def assert_atom_generator(generator)
+ _wrap_assertion do
+ uri = "http://www.example.com/"
+ version = "1.0"
+ content = "Example Toolkit"
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <generator/>
+EOA
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <generator uri="#{uri}" version="#{version}"/>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <generator uri="#{uri}" version="#{version}">#{content}</generator>
+EOA
+
+ gen = yield(feed)
+ assert_not_nil(gen)
+ assert_equal(uri, gen.uri)
+ assert_equal(version, gen.version)
+ assert_equal(content, gen.content)
+ end
+ end
+
+ def assert_atom_icon(generator)
+ _wrap_assertion do
+ content = "http://www.example.com/example.png"
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <icon/>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <icon>#{content}</icon>
+EOA
+
+ icon = yield(feed)
+ assert_not_nil(icon)
+ assert_equal(content, icon.content)
+ end
+ end
+
+ def assert_atom_text_construct(tag_name, generator)
+ _wrap_assertion do
+ [nil, "text", "html"].each do |type|
+ attr = ""
+ attr = " type=\"#{type}\""if type
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <#{tag_name}#{attr}/>
+EOA
+ end
+
+ assert_parse(generator.call(<<-EOA), :missing_tag, "div", tag_name)
+ <#{tag_name} type="xhtml"/>
+EOA
+
+ args = ["x", Atom::URI, tag_name]
+ assert_parse(generator.call(<<-EOA), :not_expected_tag, *args)
+ <#{tag_name} type="xhtml"><x/></#{tag_name}>
+EOA
+
+ invalid_value = "invalid"
+ args = ["type", invalid_value]
+ assert_parse(generator.call(<<-EOA), :not_available_value, *args)
+ <#{tag_name} type="#{invalid_value}"/>
+EOA
+
+ [
+ [nil, "A lot of effort went into making this effortless"],
+ ["text", "A lot of effort went into making this effortless"],
+ ["html", "A <em>lot</em> of effort went into making this effortless"],
+ ].each do |type, content|
+ attr = ""
+ attr = " type=\"#{type}\"" if type
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <#{tag_name}#{attr}>#{h content}</#{tag_name}>
+EOA
+
+ element = yield(feed)
+ assert_not_nil(element)
+ assert_equal(type, element.type)
+ assert_equal(content, element.content)
+ end
+
+ [false, true].each do |with_space|
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
+ xhtml_content = "<div xmlns=\"#{xhtml_uri}\">abc</div>"
+ xhtml_element = RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri},
+ ["abc"])
+ content = xhtml_content
+ content = " #{content} " if with_space
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <#{tag_name} type="xhtml">#{content}</#{tag_name}>
+EOA
+
+ element = yield(feed)
+ assert_not_nil(element)
+ assert_equal("xhtml", element.type)
+ assert_equal(xhtml_content, element.content)
+ assert_equal(xhtml_element, element.xhtml)
+ end
+ end
+ end
+
+ def assert_atom_date_construct(tag_name, generator)
+ _wrap_assertion do
+ args = [tag_name, ""]
+ assert_parse(generator.call(<<-EOR), :not_available_value, *args)
+ <#{tag_name}/>
+EOR
+
+ [
+ ["xxx", false],
+ ["2007", false],
+ ["2007/02/09", true],
+ ].each do |invalid_value, can_parse|
+ assert_not_available_value(tag_name, invalid_value) do
+ RSS::Parser.parse(generator.call(<<-EOR))
+ <#{tag_name}>#{invalid_value}</#{tag_name}>
+EOR
+ end
+
+ feed = RSS::Parser.parse(generator.call(<<-EOR), false)
+ <#{tag_name}>#{invalid_value}</#{tag_name}>
+EOR
+ value = yield(feed).content
+ if can_parse
+ assert_equal(Time.parse(invalid_value), value)
+ else
+ assert_nil(value)
+ end
+ end
+
+ [
+ "2003-12-13T18:30:02Z",
+ "2003-12-13T18:30:02.25Z",
+ "2003-12-13T18:30:02+01:00",
+ "2003-12-13T18:30:02.25+01:00",
+ ].each do |valid_value|
+ assert_parse(generator.call(<<-EOR), :nothing_raised)
+ <#{tag_name}>#{valid_value}</#{tag_name}>
+EOR
+
+ feed = RSS::Parser.parse(generator.call(<<-EOR))
+ <#{tag_name}>#{valid_value}</#{tag_name}>
+EOR
+ assert_equal(Time.parse(valid_value), yield(feed).content)
+ end
+ end
+ end
+
+ def assert_atom_logo(generator)
+ _wrap_assertion do
+ content = "http://www.example.com/example.png"
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <logo/>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <logo>#{content}</logo>
+EOA
+
+ logo = yield(feed)
+ assert_not_nil(logo)
+ assert_equal(content, logo.content)
+ end
+ end
+
+ def assert_atom_content(generator, &getter)
+ _wrap_assertion do
+ assert_atom_content_inline_text(generator, &getter)
+ assert_atom_content_inline_xhtml(generator, &getter)
+ assert_atom_content_inline_other(generator, &getter)
+ assert_atom_content_out_of_line(generator, &getter)
+ end
+ end
+
+ def assert_atom_content_inline_text(generator)
+ _wrap_assertion do
+ [nil, "text", "html"].each do |type|
+ content = "<content"
+ content << " type='#{type}'" if type
+
+ suffix = "/>"
+ assert_parse(generator.call(content + suffix), :nothing_raised)
+ suffix = ">xxx</content>"
+ assert_parse(generator.call(content + suffix), :nothing_raised)
+ end
+
+ [
+ ["text", "sample content"],
+ ["text/plain", "sample content"],
+ ["html", "<em>sample</em> content"]
+ ].each do |type, content_content|
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <content type="#{type}">#{h content_content}</content>
+EOA
+ content = yield(feed)
+ assert_equal(type, content.type)
+ if %w(text html).include?(type)
+ assert(content.inline_text?)
+ else
+ assert(!content.inline_text?)
+ end
+ if type == "html"
+ assert(content.inline_html?)
+ else
+ assert(!content.inline_html?)
+ end
+ assert(!content.inline_xhtml?)
+ if type == "text/plain"
+ assert(content.inline_other?)
+ assert(content.inline_other_text?)
+ else
+ assert(!content.inline_other?)
+ assert(!content.inline_other_text?)
+ end
+ assert(!content.inline_other_xml?)
+ assert(!content.inline_other_base64?)
+ assert(!content.out_of_line?)
+ assert(!content.have_xml_content?)
+ assert_equal(content_content, content.content)
+ end
+ end
+ end
+
+ def assert_atom_content_inline_xhtml(generator)
+ _wrap_assertion do
+ args = ["div", "content"]
+ assert_parse(generator.call(<<-EOA), :missing_tag, *args)
+ <content type="xhtml"/>
+EOA
+
+ args = ["x", Atom::URI, "content"]
+ assert_parse(generator.call(<<-EOA), :not_expected_tag, *args)
+ <content type="xhtml"><x/></content>
+EOA
+
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
+ xhtml_content = "<div xmlns=\"#{xhtml_uri}\">abc</div>"
+ xhtml_element = RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri},
+ ["abc"])
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <content type="xhtml">#{xhtml_content}</content>
+EOA
+
+ content = yield(feed)
+ assert_not_nil(content)
+ assert_equal("xhtml", content.type)
+ assert(!content.inline_text?)
+ assert(!content.inline_html?)
+ assert(content.inline_xhtml?)
+ assert(!content.inline_other?)
+ assert(!content.inline_other_text?)
+ assert(!content.inline_other_xml?)
+ assert(!content.inline_other_base64?)
+ assert(!content.out_of_line?)
+ assert(content.have_xml_content?)
+ assert_equal(xhtml_content, content.content)
+ assert_equal(xhtml_element, content.xhtml)
+ end
+ end
+
+ def assert_atom_content_inline_other(generator, &getter)
+ _wrap_assertion do
+ assert_atom_content_inline_other_text(generator, &getter)
+ assert_atom_content_inline_other_xml(generator, &getter)
+ end
+ end
+
+ def assert_atom_content_inline_other_text(generator)
+ _wrap_assertion do
+ type = "image/png"
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <content type="#{type}"/>
+EOA
+
+ png_file = File.join(File.dirname(__FILE__), "dot.png")
+ png = File.open(png_file, "rb") do |file|
+ file.read.force_encoding("binary")
+ end
+ base64_content = [png].pack("m").delete("\n")
+
+ [false, true].each do |with_space|
+ xml_content = base64_content
+ xml_content = " #{base64_content}" if with_space
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <content type="#{type}">#{xml_content}</content>
+EOA
+
+ content = yield(feed)
+ assert_not_nil(content)
+ assert_equal(type, content.type)
+ assert(!content.inline_text?)
+ assert(!content.inline_html?)
+ assert(!content.inline_xhtml?)
+ assert(content.inline_other?)
+ assert(!content.inline_other_text?)
+ assert(!content.inline_other_xml?)
+ assert(content.inline_other_base64?)
+ assert(!content.out_of_line?)
+ assert(!content.have_xml_content?)
+ assert_equal(png, content.content)
+
+ xml = REXML::Document.new(content.to_s).root
+ assert_rexml_element([], {"type" => type}, base64_content, xml)
+ end
+ end
+ end
+
+ def assert_atom_content_inline_other_xml(generator)
+ _wrap_assertion do
+ type = "image/svg+xml"
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <content type="#{type}"/>
+EOA
+
+ svg_uri = "http://www.w3.org/2000/svg"
+ svg_width = "50pt"
+ svg_height = "20pt"
+ svg_version = "1.0"
+ text_x = "15"
+ text_y = "15"
+ text = "text"
+ svg_content = <<-EOS
+<svg
+ xmlns="#{svg_uri}"
+ width="#{svg_width}"
+ height="#{svg_height}"
+ version="#{svg_version}"
+><text x="#{text_x}" y="#{text_y}">#{text}</text
+></svg>
+EOS
+
+ text_element = RSS::XML::Element.new("text", nil, svg_uri,
+ {
+ "x" => text_x,
+ "y" => text_y,
+ },
+ [text])
+ svg_element = RSS::XML::Element.new("svg", nil, svg_uri,
+ {
+ "xmlns" => svg_uri,
+ "width" => svg_width,
+ "height" => svg_height,
+ "version" => svg_version,
+ },
+ [text_element])
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <content type="#{type}">#{svg_content}</content>
+EOA
+
+ content = yield(feed)
+ assert_not_nil(content)
+ assert_equal(type, content.type)
+ assert(!content.inline_text?)
+ assert(!content.inline_html?)
+ assert(!content.inline_xhtml?)
+ assert(content.inline_other?)
+ assert(!content.inline_other_text?)
+ assert(content.inline_other_xml?)
+ assert(!content.inline_other_base64?)
+ assert(!content.out_of_line?)
+ assert(content.have_xml_content?)
+ assert_equal(REXML::Document.new(svg_content).to_s.chomp,
+ REXML::Document.new(content.content).to_s.chomp)
+ assert_equal(svg_element, content.xml)
+ assert_nil(content.xhtml)
+ end
+ end
+
+ def assert_atom_content_out_of_line(generator)
+ _wrap_assertion do
+ text_type = "text/plain"
+ text_src = "http://example.com/README.txt"
+
+ missing_args = [:missing_attribute, "content", "type"]
+ # RSS Parser raises error even if this is "should" not "must".
+ assert_parse(generator.call(<<-EOA), *missing_args)
+ <content src="#{text_src}"/>
+EOA
+
+ content_content = "xxx"
+ not_available_value_args = [:not_available_value,
+ "content", content_content]
+ assert_parse(generator.call(<<-EOA), *not_available_value_args)
+ <content type="#{text_type}" src="#{text_src}">#{content_content}</content>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <content type="#{text_type}" src="#{text_src}"/>
+EOA
+ content = yield(feed)
+ assert_not_nil(content)
+ assert_equal(text_type, content.type)
+ assert_equal(text_src, content.src)
+ assert(!content.inline_text?)
+ assert(!content.inline_html?)
+ assert(!content.inline_xhtml?)
+ assert(!content.inline_other?)
+ assert(!content.inline_other_text?)
+ assert(!content.inline_other_xml?)
+ assert(!content.inline_other_base64?)
+ assert(content.out_of_line?)
+ assert(!content.have_xml_content?)
+ assert_nil(content.xml)
+ assert_nil(content.xhtml)
+ assert_equal("", content.content)
+ end
+ end
+
+ def assert_atom_source(generator, &getter)
+ _wrap_assertion do
+ assert_atom_source_author(generator, &getter)
+ assert_atom_source_category(generator, &getter)
+ assert_atom_source_contributor(generator, &getter)
+ assert_atom_source_generator(generator, &getter)
+ assert_atom_source_icon(generator, &getter)
+ assert_atom_source_id(generator, &getter)
+ assert_atom_source_link(generator, &getter)
+ assert_atom_source_logo(generator, &getter)
+ assert_atom_source_rights(generator, &getter)
+ assert_atom_source_subtitle(generator, &getter)
+ assert_atom_source_title(generator, &getter)
+ assert_atom_source_updated(generator, &getter)
+ end
+ end
+
+ def assert_atom_source_author(generator)
+ assert_atom_person("author", generator) do |feed|
+ source = yield(feed)
+ assert_equal(1, source.authors.size)
+ source.author
+ end
+ end
+
+ def assert_atom_source_category(generator)
+ assert_atom_category(generator) do |feed|
+ source = yield(feed)
+ assert_equal(1, source.categories.size)
+ source.category
+ end
+ end
+
+ def assert_atom_source_contributor(generator)
+ assert_atom_person("contributor", generator) do |feed|
+ source = yield(feed)
+ assert_equal(1, source.contributors.size)
+ source.contributor
+ end
+ end
+
+ def assert_atom_source_generator(generator)
+ assert_atom_generator(generator) do |feed|
+ yield(feed).generator
+ end
+ end
+
+ def assert_atom_source_icon(generator)
+ assert_atom_icon(generator) do |feed|
+ yield(feed).icon
+ end
+ end
+
+ def assert_atom_source_id(generator)
+ id_content = "urn:uuid:a2fb588b-5674-4898-b420-265a734fea69"
+ id = "<id>#{id_content}</id>"
+ feed = RSS::Parser.parse(generator.call(id))
+ assert_equal(id_content, yield(feed).id.content)
+ end
+
+ def assert_atom_source_link(generator)
+ assert_atom_link(generator) do |feed|
+ source = yield(feed)
+ assert_equal(1, source.links.size)
+ source.link
+ end
+ end
+
+ def assert_atom_source_logo(generator)
+ assert_atom_logo(generator) do |feed|
+ yield(feed).logo
+ end
+ end
+
+ def assert_atom_source_rights(generator)
+ assert_atom_text_construct("rights", generator) do |feed|
+ yield(feed).rights
+ end
+ end
+
+ def assert_atom_source_subtitle(generator)
+ assert_atom_text_construct("subtitle", generator) do |feed|
+ yield(feed).subtitle
+ end
+ end
+
+ def assert_atom_source_title(generator)
+ assert_atom_text_construct("title", generator) do |feed|
+ yield(feed).title
+ end
+ end
+
+ def assert_atom_source_updated(generator)
+ assert_atom_date_construct("updated", generator) do |feed|
+ yield(feed).updated
+ end
+ end
+
+ def assert_dublin_core(elems, target)
+ _wrap_assertion do
+ elems.each do |name, value|
+ assert_equal(value, target.__send__("dc_#{name}"))
+ end
+ end
+ end
+
+ def assert_multiple_dublin_core(elems, target)
+ _wrap_assertion do
+ elems.each do |name, values, plural|
+ plural ||= "#{name}s"
+ actual = target.__send__("dc_#{plural}").collect{|x| x.value}
+ assert_equal(values, actual)
+ end
+ end
+ end
+
+ def assert_syndication(elems, target)
+ _wrap_assertion do
+ elems.each do |name, value|
+ meth = "sy_#{name}"
+ value = value.to_i if meth == "sy_updateFrequency"
+ assert_equal(value, target.__send__(meth ))
+ end
+ end
+ end
+
+ def assert_content(elems, target)
+ _wrap_assertion do
+ elems.each do |name, value|
+ assert_equal(value, target.__send__("content_#{name}"))
+ end
+ end
+ end
+
+ def assert_trackback(attrs, target)
+ _wrap_assertion do
+ n_attrs = normalized_attrs(attrs)
+ if n_attrs["ping"]
+ assert_equal(n_attrs["ping"], target.trackback_ping)
+ end
+ if n_attrs["abouts"]
+ n_attrs["abouts"].each_with_index do |about, i|
+ assert_equal(about, target.trackback_abouts[i].value)
+ end
+ end
+ end
+ end
+
+ def assert_taxo_topic(topics, target)
+ _wrap_assertion do
+ topics.each_with_index do |topic, i|
+ taxo_topic = target.taxo_topics[i]
+ topic.each do |name, value|
+ case name
+ when :link
+ assert_equal(value, taxo_topic.about)
+ assert_equal(value, taxo_topic.taxo_link)
+ when :topics
+ assert_equal(value, taxo_topic.taxo_topics.resources)
+ else
+ assert_equal(value, taxo_topic.__send__("dc_#{name}"))
+ end
+ end
+ end
+ end
+ end
+
+
+ def assert_attributes(attrs, names, target)
+ _wrap_assertion do
+ n_attrs = normalized_attrs(attrs)
+ names.each do |info|
+ if info.is_a?(String)
+ name = info
+ type = nil
+ else
+ name, type = info
+ end
+ value = n_attrs[name]
+ if value.is_a?(Time)
+ actual = target.__send__(name)
+ assert_instance_of(Time, actual)
+ assert_equal(value.to_i, actual.to_i)
+ elsif value
+ case type
+ when :integer
+ value = value.to_i
+ when :boolean
+ value = value == "true" if value.is_a?(String)
+ end
+ assert_equal(value, target.__send__(name))
+ end
+ end
+ end
+ end
+
+ def assert_rexml_element(children, attrs, text, element, text_type=nil)
+ _wrap_assertion do
+ if children
+ children_info = element.elements.collect {|e| [e.namespace, e.name]}
+ assert_equal(children.collect {|uri, name| [uri, name]}.sort,
+ children_info.sort)
+ end
+ if attrs
+ assert_equal(attrs.collect {|k, v| [k, v]}.sort,
+ element.attributes.collect {|k, v| [k, v]}.sort)
+ end
+ case text_type
+ when :time
+ assert_not_nil(element.text)
+ assert_equal(Time.parse(text).to_s, Time.parse(element.text).to_s)
+ else
+ assert_equal(text, element.text)
+ end
+ end
+ end
+
+ def _assert_maker_atom_persons(feed_type, maker_readers, feed_readers)
+ _wrap_assertion do
+ persons = []
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ targets.each do |target|
+ person = {
+ :name => target.name,
+ :uri => target.uri,
+ :email => target.email,
+ }
+ persons << person if person[:name]
+ end
+ end
+
+ actual_persons = chain_reader(feed, feed_readers) || []
+ actual_persons = actual_persons.collect do |person|
+ {
+ :name => person.name ? person.name.content : nil,
+ :uri => person.uri ? person.uri.content : nil,
+ :email => person.email ? person.email.content : nil,
+ }
+ end
+ assert_equal(persons, actual_persons)
+ end
+ end
+
+ def assert_maker_atom_persons(feed_type, maker_readers, feed_readers,
+ not_set_error_name=nil,
+ parent_not_set_error_name=nil,
+ parent_not_set_variable=nil)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ args = [feed_type, maker_readers, feed_readers]
+ if parent_not_set_error_name or parent_not_set_variable
+ assert_not_set_error(parent_not_set_error_name,
+ parent_not_set_variable) do
+ _assert_maker_atom_persons(*args) do |maker|
+ yield maker
+ end
+ end
+ else
+ _assert_maker_atom_persons(*args) do |maker|
+ yield maker
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(name)) do
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(name)) do
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.uri = "http://example.com/~me/"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(name)) do
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.email = "me at example.com"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(name)) do
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.uri = "http://example.com/~me/"
+ target.email = "me at example.com"
+ end
+ end
+
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.name = "me"
+ end
+
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.name = "me"
+ target.uri = "http://example.com/~me/"
+ end
+
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.name = "me"
+ target.email = "me at example.com"
+ end
+
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.name = "me"
+ target.uri = "http://example.com/~me/"
+ target.email = "me at example.com"
+ end
+
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+
+ target = targets.new_child
+ target.name = "me"
+ target.uri = "http://example.com/~me/"
+ target.email = "me at example.com"
+
+ target = targets.new_child
+ target.name = "you"
+ target.uri = "http://example.com/~you/"
+ target.email = "you at example.com"
+ end
+
+ assert_not_set_error(not_set_error_name, %w(name)) do
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+
+ target = targets.new_child
+ target.name = "me"
+ target.uri = "http://example.com/~me/"
+ target.email = "me at example.com"
+
+ target = targets.new_child
+ end
+ end
+ end
+ end
+
+ def _assert_maker_atom_text_construct(feed_type, maker_readers,
+ feed_readers, &block)
+ maker_extractor = Proc.new do |target|
+ text = {
+ :type => target.type,
+ :content => target.content,
+ :xml_content => target.xml_content,
+ }
+ if text[:type] == "xhtml"
+ if text[:xml_content]
+ xml_content = text[:xml_content]
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
+ unless xml_content.is_a?(RSS::XML::Element) and
+ ["div", xhtml_uri] == [xml_content.name, xml_content.uri]
+ children = xml_content
+ children = [children] unless children.is_a?(Array)
+ xml_content = RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri},
+ children)
+ text[:xml_content] = xml_content
+ end
+ text
+ else
+ nil
+ end
+ else
+ text[:content] ? text : nil
+ end
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :type => target.type,
+ :content => target.content,
+ :xml_content => target.xhtml,
+ }
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_text_construct(feed_type, maker_readers, feed_readers,
+ parent_not_set_error_name=nil,
+ parent_not_set_variable=nil,
+ not_set_error_name=nil)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ args = [feed_type, maker_readers, feed_readers]
+ if parent_not_set_error_name or parent_not_set_variable
+ assert_not_set_error(parent_not_set_error_name,
+ parent_not_set_variable) do
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ end
+ end
+ else
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(content)) do
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers) {|x| x}
+ target.type = "text"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(content)) do
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers) {|x| x}
+ target.type = "html"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers) {|x| x}
+ target.type = "xhtml"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers) {|x| x}
+ target.type = "xhtml"
+ target.content = "Content"
+ end
+ end
+
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers) {|x| x}
+ target.type = "text"
+ target.content = "Content"
+ end
+
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers) {|x| x}
+ target.type = "html"
+ target.content = "<em>Content</em>"
+ end
+
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers) {|x| x}
+ target.type = "xhtml"
+ target.xml_content = "text only"
+ end
+
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers) {|x| x}
+ target.type = "xhtml"
+ target.xml_content = RSS::XML::Element.new("unknown")
+ end
+ end
+ end
+
+ def _assert_maker_atom_date_construct(feed_type, maker_readers,
+ feed_readers, &block)
+ maker_extractor = Proc.new do |target|
+ date = {
+ :content => target,
+ }
+ date[:content] ? date : nil
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :content => target.content,
+ }
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_date_construct(feed_type, maker_readers, feed_readers,
+ parent_not_set_error_name=nil,
+ parent_not_set_variable=nil)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ if parent_not_set_error_name or parent_not_set_variable
+ assert_not_set_error(parent_not_set_error_name,
+ parent_not_set_variable) do
+ _assert_maker_atom_date_construct(*args) do |maker|
+ yield maker
+ end
+ end
+ else
+ _assert_maker_atom_date_construct(*args) do |maker|
+ yield maker
+ end
+ end
+
+ maker_readers = maker_readers.dup
+ writer = "#{maker_readers.pop}="
+ _assert_maker_atom_date_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.__send__(writer, Time.now)
+ end
+ end
+ end
+
+ def _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor)
+ _wrap_assertion do
+ element = nil
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers) {|x| x}
+ element = maker_extractor.call(target)
+ end
+
+ target = chain_reader(feed, feed_readers)
+ if target
+ actual_element = feed_extractor.call(target)
+ else
+ actual_element = nil
+ end
+ assert_equal(element, actual_element)
+ end
+ end
+
+ def _assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ invalid_feed_checker=nil)
+ _wrap_assertion do
+ elements = []
+ invalid_feed_exception = nil
+ feed = nil
+ begin
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ targets.each do |target|
+ element = maker_extractor.call(target)
+ elements << element if element
+ end
+ if invalid_feed_checker
+ invalid_feed_exception = invalid_feed_checker.call(targets)
+ end
+ end
+ rescue RSS::Error
+ if invalid_feed_exception.is_a?(RSS::TooMuchTagError)
+ assert_too_much_tag(invalid_feed_exception.tag,
+ invalid_feed_exception.parent) do
+ raise
+ end
+ else
+ raise
+ end
+ end
+
+ if invalid_feed_exception.nil?
+ actual_elements = chain_reader(feed, feed_readers) || []
+ actual_elements = actual_elements.collect do |target|
+ feed_extractor.call(target)
+ end
+ assert_equal(elements, actual_elements)
+ end
+ end
+ end
+
+ def assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ setup_target, optional_variables,
+ required_variable, assert_method_name,
+ not_set_error_name=nil,
+ *additional_args)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ 0.upto(optional_variables.size) do |i|
+ combination(optional_variables, i).each do |names|
+ have = {}
+ names.each do |name|
+ have[name.intern] = true
+ end
+ have_required_variable_too =
+ have.merge({required_variable.intern => true})
+
+ assert_not_set_error(not_set_error_name, [required_variable]) do
+ __send__(assert_method_name, feed_type, maker_readers,
+ feed_readers, *additional_args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers) {|x| x}
+ setup_target.call(target, have)
+ end
+ end
+
+ __send__(assert_method_name, feed_type, maker_readers, feed_readers,
+ *additional_args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers) {|x| x}
+ setup_target.call(target, have_required_variable_too)
+ end
+ end
+ end
+ end
+ end
+
+ def assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
+ setup_target, optional_variables,
+ required_variable, assert_method_name,
+ not_set_error_name=nil,
+ *additional_args)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ 0.upto(optional_variables.size) do |i|
+ combination(optional_variables, i).each do |names|
+ have = {}
+ names.each do |name|
+ have[name.intern] = true
+ end
+ have_required_variable_too =
+ have.merge({required_variable.intern => true})
+
+ assert_not_set_error(not_set_error_name, [required_variable]) do
+ __send__(assert_method_name, feed_type, maker_readers,
+ feed_readers, *additional_args) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ setup_target.call(targets, have)
+ end
+ end
+
+ __send__(assert_method_name, feed_type, maker_readers, feed_readers,
+ *additional_args) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ setup_target.call(targets, have_required_variable_too)
+ end
+
+ __send__(assert_method_name, feed_type, maker_readers, feed_readers,
+ *additional_args) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ setup_target.call(targets, have_required_variable_too)
+ setup_target.call(targets, have_required_variable_too)
+ end
+
+ assert_not_set_error(not_set_error_name, [required_variable]) do
+ __send__(assert_method_name, feed_type, maker_readers, feed_readers,
+ *additional_args) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ setup_target.call(targets, have_required_variable_too)
+ setup_target.call(targets, have)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ def _assert_maker_atom_categories(feed_type, maker_readers,
+ feed_readers, &block)
+ maker_extractor = Proc.new do |target|
+ category = {
+ :term => target.term,
+ :scheme => target.scheme,
+ :label => target.label,
+ }
+ category[:term] ? category : nil
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :term => target.term,
+ :scheme => target.scheme,
+ :label => target.label,
+ }
+ end
+ _assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor, &block)
+ end
+
+ def assert_maker_atom_categories(feed_type, maker_readers, feed_readers,
+ not_set_error_name=nil, &block)
+ _wrap_assertion do
+ _assert_maker_atom_categories(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ end
+
+ setup_target = Proc.new do |targets, have|
+ target = targets.new_child
+ target.term = "music" if have[:term]
+ target.scheme = "http://example.com/category/music" if have[:scheme]
+ target.label = "Music" if have[:label]
+ end
+
+ optional_variables = %w(scheme label)
+
+ assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
+ setup_target, optional_variables,
+ "term", :_assert_maker_atom_categories,
+ not_set_error_name, &block)
+ end
+ end
+
+ def _assert_maker_atom_generator(feed_type, maker_readers,
+ feed_readers, &block)
+ maker_extractor = Proc.new do |target|
+ generator = {
+ :uri => target.uri,
+ :version => target.version,
+ :content => target.content,
+ }
+ generator[:content] ? generator : nil
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :uri => target.uri,
+ :version => target.version,
+ :content => target.content,
+ }
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_generator(feed_type, maker_readers, feed_readers,
+ not_set_error_name=nil, &block)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ _assert_maker_atom_generator(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ end
+
+ setup_target = Proc.new do |target, have|
+ target.content = "RSS Maker" if have[:content]
+ target.uri = "http://example.com/rss/maker" if have[:uri]
+ target.version = "0.0.1" if have[:version]
+ end
+
+ optional_variables = %w(uri version)
+
+ assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ setup_target, optional_variables,
+ "content", :_assert_maker_atom_generator,
+ not_set_error_name, &block)
+ end
+ end
+
+ def _assert_maker_atom_icon(feed_type, maker_readers, feed_readers,
+ accessor_base, &block)
+ maker_extractor = Proc.new do |target|
+ icon = {
+ :content => target.__send__(accessor_base),
+ }
+ icon[:content] ? icon : nil
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :content => target.content,
+ }
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_icon(feed_type, maker_readers, feed_readers,
+ accessor_base=nil, not_set_error_name=nil)
+ _wrap_assertion do
+ accessor_base ||= "url"
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ _assert_maker_atom_icon(feed_type, maker_readers, feed_readers,
+ accessor_base) do |maker|
+ yield maker
+ end
+
+ _assert_maker_atom_icon(feed_type, maker_readers, feed_readers,
+ accessor_base) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.__send__("#{accessor_base}=", "http://example.com/icon.png")
+ end
+ end
+ end
+
+ def _assert_maker_atom_links(feed_type, maker_readers, feed_readers,
+ allow_duplication=false, &block)
+ maker_extractor = Proc.new do |target|
+ link = {
+ :href => target.href,
+ :rel => target.rel,
+ :type => target.type,
+ :hreflang => target.hreflang,
+ :title => target.title,
+ :length => target.length,
+ }
+ link[:href] ? link : nil
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :href => target.href,
+ :rel => target.rel,
+ :type => target.type,
+ :hreflang => target.hreflang,
+ :title => target.title,
+ :length => target.length,
+ }
+ end
+
+ if feed_readers.first == "entries"
+ parent = "entry"
+ else
+ parent = feed_type
+ end
+ invalid_feed_checker = Proc.new do |targets|
+ infos = {}
+ invalid_exception = nil
+ targets.each do |target|
+ key = [target.hreflang, target.type]
+ if infos.has_key?(key)
+ invalid_exception = RSS::TooMuchTagError.new("link", parent)
+ break
+ end
+ infos[key] = true if target.rel.nil? or target.rel == "alternate"
+ end
+ invalid_exception
+ end
+ invalid_feed_checker = nil if allow_duplication
+ _assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ invalid_feed_checker,
+ &block)
+ end
+
+ def assert_maker_atom_links(feed_type, maker_readers, feed_readers,
+ not_set_error_name=nil, allow_duplication=false,
+ &block)
+ _wrap_assertion do
+ _assert_maker_atom_links(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ end
+
+ langs = %(ja en fr zh po)
+ setup_target = Proc.new do |targets, have|
+ target = targets.new_child
+ lang = langs[targets.size % langs.size]
+ target.href = "http://example.com/index.html.#{lang}" if have[:href]
+ target.rel = "alternate" if have[:rel]
+ target.type = "text/xhtml" if have[:type]
+ target.hreflang = lang if have[:hreflang]
+ target.title = "FrontPage(#{lang})" if have[:title]
+ target.length = 1024 if have[:length]
+ end
+
+ optional_variables = %w(rel type hreflang title length)
+
+ assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
+ setup_target, optional_variables,
+ "href", :_assert_maker_atom_links,
+ not_set_error_name, allow_duplication,
+ &block)
+ end
+ end
+
+ def _assert_maker_atom_logo(feed_type, maker_readers, feed_readers,
+ accessor_base, &block)
+ maker_extractor = Proc.new do |target|
+ logo = {
+ :uri => target.__send__(accessor_base),
+ }
+ logo[:uri] ? logo : nil
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :uri => target.content,
+ }
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_logo(feed_type, maker_readers, feed_readers,
+ accessor_base=nil, not_set_error_name=nil)
+ _wrap_assertion do
+ accessor_base ||= "uri"
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ _assert_maker_atom_logo(feed_type, maker_readers, feed_readers,
+ accessor_base) do |maker|
+ yield maker
+ end
+
+ _assert_maker_atom_logo(feed_type, maker_readers, feed_readers,
+ accessor_base) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.__send__("#{accessor_base}=", "http://example.com/logo.png")
+ end
+ end
+ end
+
+ def _assert_maker_atom_id(feed_type, maker_readers, feed_readers, &block)
+ maker_extractor = Proc.new do |target|
+ id = {
+ :uri => target.id,
+ }
+ id[:uri] ? id : nil
+ end
+ feed_extractor = Proc.new do |target|
+ if target.id
+ {
+ :uri => target.id.content,
+ }
+ else
+ nil
+ end
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_id(feed_type, maker_readers, feed_readers,
+ not_set_error_name=nil)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ args = [feed_type, maker_readers, feed_readers]
+ _assert_maker_atom_id(*args) do |maker|
+ yield maker
+ end
+
+ _assert_maker_atom_id(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.id = "http://example.com/id/1"
+ end
+ end
+ end
+
+ def _assert_maker_atom_content(feed_type, maker_readers,
+ feed_readers, &block)
+ maker_extractor = Proc.new do |target|
+ content = {
+ :type => target.type,
+ :src => target.src,
+ :content => target.content,
+ :xml => target.xml,
+ :inline_text => target.inline_text?,
+ :inline_html => target.inline_html?,
+ :inline_xhtml => target.inline_xhtml?,
+ :inline_other => target.inline_other?,
+ :inline_other_text => target.inline_other_text?,
+ :inline_other_xml => target.inline_other_xml?,
+ :inline_other_base64 => target.inline_other_base64?,
+ :out_of_line => target.out_of_line?,
+ }
+ content[:src] = nil if content[:src] and content[:content]
+ if content[:type] or content[:content]
+ content
+ else
+ nil
+ end
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :type => target.type,
+ :src => target.src,
+ :content => target.content,
+ :xml => target.xml,
+ :inline_text => target.inline_text?,
+ :inline_html => target.inline_html?,
+ :inline_xhtml => target.inline_xhtml?,
+ :inline_other => target.inline_other?,
+ :inline_other_text => target.inline_other_text?,
+ :inline_other_xml => target.inline_other_xml?,
+ :inline_other_base64 => target.inline_other_base64?,
+ :out_of_line => target.out_of_line?,
+ }
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_content(feed_type, maker_readers, feed_readers,
+ not_set_error_name=nil, &block)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+ args = [feed_type, maker_readers, feed_readers, not_set_error_name]
+ assert_maker_atom_content_inline_text(*args, &block)
+ assert_maker_atom_content_inline_xhtml(*args, &block)
+ assert_maker_atom_content_inline_other(*args, &block)
+ assert_maker_atom_content_out_of_line(*args, &block)
+ end
+ end
+
+ def assert_maker_atom_content_inline_text(feed_type, maker_readers,
+ feed_readers, not_set_error_name)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ end
+
+ assert_not_set_error(not_set_error_name, %w(content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "text"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "html"
+ end
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.content = ""
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "text"
+ target.content = "example content"
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "html"
+ target.content = "<em>text</em>"
+ end
+ end
+ end
+
+ def assert_maker_atom_content_inline_xhtml(feed_type, maker_readers,
+ feed_readers, not_set_error_name)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.content = "dummy"
+ end
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml_content = "text"
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml = "text"
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml_content =
+ RSS::XML::Element.new("em", nil, nil, {}, ["text"])
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml = RSS::XML::Element.new("em", nil, nil, {}, ["text"])
+ end
+
+
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
+ em = RSS::XML::Element.new("em", nil, nil, {}, ["text"])
+ em_with_xhtml_uri =
+ RSS::XML::Element.new("em", nil, xhtml_uri, {}, ["text"])
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml = em
+ end
+ assert_equal(RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri},
+ [em_with_xhtml_uri]),
+ chain_reader(feed, feed_readers).xml)
+
+ div = RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri,
+ "class" => "sample"},
+ ["text"])
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml = div
+ end
+ assert_equal(div, chain_reader(feed, feed_readers).xml)
+ end
+ end
+
+ def assert_maker_atom_content_inline_other(*args, &block)
+ _wrap_assertion do
+ assert_maker_atom_content_inline_other_xml(*args, &block)
+ assert_maker_atom_content_inline_other_text(*args, &block)
+ assert_maker_atom_content_inline_other_base64(*args, &block)
+ end
+ end
+
+ def assert_maker_atom_content_inline_other_xml(feed_type, maker_readers,
+ feed_readers,
+ not_set_error_name)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "application/xml"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "svg/image+xml"
+ end
+ end
+
+ svg_uri = "http://www.w3.org/2000/svg"
+ rect = RSS::XML::Element.new("rect", nil, svg_uri,
+ {"x" => "0.5cm",
+ "y" => "0.5cm",
+ "width" => "2cm",
+ "height" => "1cm"})
+ svg = RSS::XML::Element.new("svg", nil, svg_uri,
+ {"xmlns" => svg_uri,
+ "version" => "1.1",
+ "width" => "5cm",
+ "height" => "4cm"},
+ [rect])
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/svg+xml"
+ target.xml = svg
+ end
+
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/svg+xml"
+ target.xml = svg
+ end
+ assert_equal(svg, chain_reader(feed, feed_readers).xml)
+ end
+ end
+
+ def assert_maker_atom_content_inline_other_text(feed_type, maker_readers,
+ feed_readers,
+ not_set_error_name)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ assert_not_set_error(not_set_error_name, %w(content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "text/plain"
+ end
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "text/plain"
+ target.content = "text"
+ end
+ end
+ end
+
+ def assert_maker_atom_content_inline_other_base64(feed_type, maker_readers,
+ feed_readers,
+ not_set_error_name)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ content = "\211PNG\r\n\032\n"
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/png"
+ target.content = content
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/png"
+ target.src = "http://example.com/logo.png"
+ target.content = content
+ end
+
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/png"
+ target.src = "http://example.com/logo.png"
+ target.content = content
+ end
+ target = chain_reader(feed, feed_readers)
+ assert_nil(target.src)
+ assert_equal(content, target.content)
+ end
+ end
+
+ def assert_maker_atom_content_out_of_line(feed_type, maker_readers,
+ feed_readers, not_set_error_name)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ assert_not_set_error(not_set_error_name, %w(content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/png"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(type)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.src = "http://example.com/logo.png"
+ end
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/png"
+ target.src = "http://example.com/logo.png"
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/png"
+ target.content = "\211PNG\r\n\032\n"
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "application/xml"
+ target.src = "http://example.com/sample.xml"
+ end
+
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "text/plain"
+ target.src = "http://example.com/README.txt"
+ end
+ end
+ end
+
+ def assert_slash_elements(expected, target)
+ assert_equal(expected,
+ {
+ "section" => target.slash_section,
+ "department" => target.slash_department,
+ "comments" => target.slash_comments,
+ "hit_parades" => target.slash_hit_parades,
+ })
+ assert_equal(expected["hit_parades"].join(","),
+ target.slash_hit_parade)
+ end
+
+ def chain_reader(target, readers, &block)
+ readers.inject(target) do |result, reader|
+ return nil if result.nil?
+ result.__send__(reader, &block)
+ end
+ end
+
+ def normalized_attrs(attrs)
+ n_attrs = {}
+ attrs.each do |name, value|
+ n_attrs[name.to_s] = value
+ end
+ n_attrs
+ end
+
+ def combination(elements, n)
+ if n <= 0 or elements.size < n
+ []
+ elsif n == 1
+ elements.collect {|element| [element]}
+ else
+ first, *rest = elements
+ combination(rest, n - 1).collect do |sub_elements|
+ [first, *sub_elements]
+ end + combination(rest, n)
+ end
+ end
+
+ def tag(name, content=nil, attributes={})
+ attributes = attributes.collect do |key, value|
+ "#{ERB::Util.h(key)}=\"#{ERB::Util.h(value)}\""
+ end.join(" ")
+ begin_tag = "<#{name}"
+ begin_tag << " #{attributes}" unless attributes.empty?
+ if content
+ "#{begin_tag}>#{content}</#{name}>\n"
+ else
+ "#{begin_tag}/>\n"
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/rss-testcase.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/rss-testcase.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/rss-testcase.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,478 @@
+require "erb"
+
+require "test/unit"
+require 'rss-assertions'
+
+require "rss"
+
+module RSS
+ class TestCase < Test::Unit::TestCase
+ include ERB::Util
+
+ include RSS
+ include Assertions
+
+ XMLDECL_VERSION = "1.0"
+ XMLDECL_ENCODING = "UTF-8"
+ XMLDECL_STANDALONE = "no"
+
+ RDF_ABOUT = "http://www.xml.com/xml/news.rss"
+ RDF_RESOURCE = "http://xml.com/universal/images/xml_tiny.gif"
+ TITLE_VALUE = "XML.com"
+ LINK_VALUE = "http://xml.com/pub"
+ URL_VALUE = "http://xml.com/universal/images/xml_tiny.gif"
+ NAME_VALUE = "hogehoge"
+ LANGUAGE_VALUE = "ja"
+ DESCRIPTION_VALUE = "
+ XML.com features a rich mix of information and services
+ for the XML community.
+ "
+ RESOURCES = [
+ "http://xml.com/pub/2000/08/09/xslt/xslt.html",
+ "http://xml.com/pub/2000/08/09/rdfdb/index.html",
+ ]
+
+ CLOUD_DOMAIN = "data.ourfavoritesongs.com"
+ CLOUD_PORT = "80"
+ CLOUD_PATH = "/RPC2"
+ CLOUD_REGISTER_PROCEDURE = "ourFavoriteSongs.rssPleaseNotify"
+ CLOUD_PROTOCOL = "xml-rpc"
+
+ ENCLOSURE_URL = "http://www.scripting.com/mp3s/weatherReportSuite.mp3"
+ ENCLOSURE_LENGTH = "12216320"
+ ENCLOSURE_TYPE = "audio/mpeg"
+
+ CATEGORY_DOMAIN = "http://www.superopendirectory.com/"
+
+ FEED_TITLE = "dive into mark"
+ FEED_UPDATED = "2003-12-13T18:30:02Z"
+ FEED_AUTHOR_NAME = "John Doe"
+ FEED_ID = "urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6"
+
+ ENTRY_TITLE = "Atom-Powered Robots Run Amok"
+ ENTRY_LINK = "http://example.org/2003/12/13/atom03"
+ ENTRY_ID = "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a"
+ ENTRY_UPDATED = "2003-12-13T18:30:02Z"
+ ENTRY_SUMMARY = "Some text."
+
+ t = Time.iso8601("2000-01-01T12:00:05+00:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+
+ DC_ELEMENTS = {
+ :title => "hoge",
+ :description =>
+ " XML is placing increasingly heavy loads on
+ the existing technical infrastructure of the Internet.",
+ :creator => "Rael Dornfest (mailto:rael at oreilly.com)",
+ :subject => "XML",
+ :publisher => "The O'Reilly Network",
+ :contributor => "hogehoge",
+ :type => "fugafuga",
+ :format => "hohoho",
+ :identifier => "fufufu",
+ :source => "barbar",
+ :language => "ja",
+ :relation => "cococo",
+ :rights => "Copyright (c) 2000 O'Reilly & Associates, Inc.",
+ :date => t,
+ }
+
+ DC_NODES = DC_ELEMENTS.collect do |name, value|
+ "<#{DC_PREFIX}:#{name}>#{value}</#{DC_PREFIX}:#{name}>"
+ end.join("\n")
+
+ def default_test
+ # This class isn't tested
+ end
+
+ private
+ def make_xmldecl(v=XMLDECL_VERSION, e=XMLDECL_ENCODING, s=XMLDECL_STANDALONE)
+ rv = "<?xml version='#{v}'"
+ rv << " encoding='#{e}'" if e
+ rv << " standalone='#{s}'" if s
+ rv << "?>"
+ rv
+ end
+
+ def make_RDF(content=nil, xmlns=[])
+ <<-EORSS
+#{make_xmldecl}
+<rdf:RDF xmlns="#{URI}" xmlns:rdf="#{RDF::URI}"
+#{xmlns.collect {|pre, uri| "xmlns:#{pre}='#{uri}'"}.join(' ')}>
+#{block_given? ? yield : content}
+</rdf:RDF>
+EORSS
+ end
+
+ def make_channel(content=nil)
+ <<-EOC
+<channel rdf:about="#{RDF_ABOUT}">
+ <title>#{TITLE_VALUE}</title>
+ <link>#{LINK_VALUE}</link>
+ <description>#{DESCRIPTION_VALUE}</description>
+
+ <image rdf:resource="#{RDF_RESOURCE}" />
+
+ <items>
+ <rdf:Seq>
+#{RESOURCES.collect do |res| '<rdf:li resource="' + res + '" />' end.join("\n")}
+ </rdf:Seq>
+ </items>
+
+ <textinput rdf:resource="#{RDF_RESOURCE}" />
+
+#{block_given? ? yield : content}
+</channel>
+EOC
+ end
+
+ def make_image(content=nil)
+ <<-EOI
+<image rdf:about="#{RDF_ABOUT}">
+ <title>#{TITLE_VALUE}</title>
+ <url>#{URL_VALUE}</url>
+ <link>#{LINK_VALUE}</link>
+#{block_given? ? yield : content}
+</image>
+EOI
+ end
+
+ def make_item(content=nil)
+ <<-EOI
+<item rdf:about="#{RDF_ABOUT}">
+ <title>#{TITLE_VALUE}</title>
+ <link>#{LINK_VALUE}</link>
+ <description>#{DESCRIPTION_VALUE}</description>
+#{block_given? ? yield : content}
+</item>
+EOI
+ end
+
+ def make_textinput(content=nil)
+ <<-EOT
+<textinput rdf:about="#{RDF_ABOUT}">
+ <title>#{TITLE_VALUE}</title>
+ <description>#{DESCRIPTION_VALUE}</description>
+ <name>#{NAME_VALUE}</name>
+ <link>#{LINK_VALUE}</link>
+#{block_given? ? yield : content}
+</textinput>
+EOT
+ end
+
+ def make_sample_RDF
+ make_RDF(<<-EOR)
+#{make_channel}
+#{make_image}
+#{make_item}
+#{make_textinput}
+EOR
+ end
+
+ def make_rss20(content=nil, xmlns=[])
+ <<-EORSS
+#{make_xmldecl}
+<rss version="2.0"
+#{xmlns.collect {|pre, uri| "xmlns:#{pre}='#{uri}'"}.join(' ')}>
+#{block_given? ? yield : content}
+</rss>
+EORSS
+ end
+
+ def make_sample_items20
+ RESOURCES.collect do |res|
+ elems = ["<link>#{res}</link>"]
+ elems << "<title>title of #{res}</title>"
+ elems = elems.join("\n")
+ item = "<item>\n#{elems}\n</item>"
+ end.join("\n")
+ end
+
+ def make_channel20(content=nil)
+ <<-EOC
+<channel>
+ <title>#{TITLE_VALUE}</title>
+ <link>#{LINK_VALUE}</link>
+ <description>#{DESCRIPTION_VALUE}</description>
+ <language>#{LANGUAGE_VALUE}</language>
+
+ <image>
+ <url>#{RDF_RESOURCE}</url>
+ <title>#{TITLE_VALUE}</title>
+ <link>#{LINK_VALUE}</link>
+ </image>
+
+#{make_sample_items20}
+
+ <textInput>
+ <title>#{TITLE_VALUE}</title>
+ <description>#{DESCRIPTION_VALUE}</description>
+ <name>#{NAME_VALUE}</name>
+ <link>#{RDF_RESOURCE}</link>
+ </textInput>
+
+#{block_given? ? yield : content}
+</channel>
+EOC
+ end
+
+ def make_item20(content=nil)
+ <<-EOI
+<item>
+ <title>#{TITLE_VALUE}</title>
+ <link>#{LINK_VALUE}</link>
+ <description>#{DESCRIPTION_VALUE}</description>
+#{block_given? ? yield : content}
+</item>
+EOI
+ end
+
+ def make_cloud20
+ <<-EOC
+<cloud
+ domain="#{CLOUD_DOMAIN}"
+ port="#{CLOUD_PORT}"
+ path="#{CLOUD_PATH}"
+ registerProcedure="#{CLOUD_REGISTER_PROCEDURE}"
+ protocol="#{CLOUD_PROTOCOL}" />
+EOC
+ end
+
+ def make_sample_rss20
+ make_rss20(<<-EOR)
+#{make_channel20}
+EOR
+ end
+
+ def make_feed_without_entry(content=nil, xmlns=[])
+ <<-EOA
+<feed xmlns="#{Atom::URI}"
+#{xmlns.collect {|pre, uri| "xmlns:#{pre}='#{uri}'"}.join(' ')}>
+ <id>#{FEED_ID}</id>
+ <title>#{FEED_TITLE}</title>
+ <updated>#{FEED_UPDATED}</updated>
+ <author>
+ <name>#{FEED_AUTHOR_NAME}</name>
+ </author>
+#{block_given? ? yield : content}
+</feed>
+EOA
+ end
+
+ def make_entry(content=nil)
+ <<-EOA
+ <entry>
+ <title>#{ENTRY_TITLE}</title>
+ <id>#{ENTRY_ID}</id>
+ <updated>#{ENTRY_UPDATED}</updated>
+#{block_given? ? yield : content}
+ </entry>
+EOA
+ end
+
+ def make_feed_with_open_entry(content=nil, xmlns=[], &block)
+ make_feed_without_entry(<<-EOA, xmlns)
+#{make_entry(content, &block)}
+EOA
+ end
+
+ def make_feed_with_open_entry_source(content=nil, xmlns=[])
+ make_feed_with_open_entry(<<-EOA, xmlns)
+ <source>
+#{block_given? ? yield : content}
+ </source>
+EOA
+ end
+
+ def make_feed(content=nil, xmlns=[])
+ make_feed_without_entry(<<-EOA, xmlns)
+ <entry>
+ <title>#{ENTRY_TITLE}</title>
+ <link href="#{ENTRY_LINK}"/>
+ <id>#{ENTRY_ID}</id>
+ <updated>#{ENTRY_UPDATED}</updated>
+ <summary>#{ENTRY_SUMMARY}</summary>
+ </entry>
+#{block_given? ? yield : content}
+EOA
+ end
+
+ def make_entry_document(content=nil, xmlns=[])
+ <<-EOA
+<entry xmlns="#{Atom::URI}"
+#{xmlns.collect {|pre, uri| "xmlns:#{pre}='#{uri}'"}.join(' ')}>
+ <id>#{ENTRY_ID}</id>
+ <title>#{ENTRY_TITLE}</title>
+ <updated>#{ENTRY_UPDATED}</updated>
+ <author>
+ <name>#{FEED_AUTHOR_NAME}</name>
+ </author>
+#{block_given? ? yield : content}
+</entry>
+EOA
+ end
+
+ def make_entry_document_with_open_source(content=nil, xmlns=[])
+ make_entry_document(<<-EOA, xmlns)
+ <source>
+#{block_given? ? yield : content}
+ </source>
+EOA
+ end
+
+ def make_element(elem_name, attrs, contents)
+ attrs_str = attrs.collect do |name, value|
+ "#{h name}='#{h value}'"
+ end.join(" ")
+ attrs_str = " #{attrs_str}" unless attrs_str.empty?
+
+ if contents.is_a?(String)
+ contents_str = h(contents)
+ else
+ contents_str = contents.collect do |name, value|
+ "#{Element::INDENT}<#{h name}>#{h value}</#{h name}>"
+ end.join("\n")
+ contents_str = "\n#{contents_str}\n"
+ end
+
+ "<#{h elem_name}#{attrs_str}>#{contents_str}</#{h elem_name}>"
+ end
+
+ def xmlns_container(xmlns_decls, content)
+ attributes = xmlns_decls.collect do |prefix, uri|
+ "xmlns:#{h prefix}=\"#{h uri}\""
+ end.join(" ")
+ "<dummy #{attributes}>#{content}</dummy>"
+ end
+
+ private
+ def setup_rss10(rdf)
+ assert_equal("", rdf.to_s)
+
+ channel = RDF::Channel.new
+ assert_equal("", channel.to_s)
+ channel.about = "http://example.com/index.rdf"
+ channel.title = "title"
+ channel.link = "http://example.com/"
+ channel.description = "description"
+ assert_equal("", channel.to_s)
+
+ item_title = "item title"
+ item_link = "http://example.com/item"
+ channel.items = RDF::Channel::Items.new
+ channel.items.Seq.lis << RDF::Channel::Items::Seq::Li.new(item_link)
+ assert_not_equal("", channel.to_s)
+
+ rdf.channel = channel
+ assert_equal("", rdf.to_s)
+
+ item = RDF::Item.new
+ item.title = item_title
+ item.link = item_link
+ item.about = item_link
+ rdf.items << item
+ assert_not_equal("", rdf.to_s)
+ end
+
+ def setup_rss20(rss)
+ assert_equal("", rss.to_s)
+
+ channel = Rss::Channel.new
+ assert_equal("", channel.to_s)
+ channel.title = "title"
+ channel.link = "http://example.com/"
+ channel.description = "description"
+ assert_not_equal("", channel.to_s)
+
+ rss.channel = channel
+ assert_not_equal("", rss.to_s)
+ end
+
+ def setup_dummy_channel(maker)
+ about = "http://hoge.com"
+ title = "fugafuga"
+ link = "http://hoge.com/feed.xml"
+ description = "fugafugafugafuga"
+ language = "ja"
+
+ maker.channel.about = about
+ maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+ maker.channel.language = language
+ end
+
+ def setup_dummy_channel_atom(maker)
+ updated = Time.now
+ author = "Foo"
+
+ setup_dummy_channel(maker)
+ maker.channel.links.first.rel = "self"
+ maker.channel.links.first.type = "application/atom+xml"
+ maker.channel.updated = updated
+ maker.channel.author = author
+ end
+
+ def setup_dummy_image(maker)
+ title = "fugafuga"
+ link = "http://hoge.com"
+ url = "http://hoge.com/hoge.png"
+
+ maker.channel.link = link if maker.channel.link.nil?
+
+ maker.image.title = title
+ maker.image.url = url
+ end
+
+ def setup_dummy_textinput(maker)
+ title = "fugafuga"
+ description = "text hoge fuga"
+ name = "hoge"
+ link = "http://hoge.com/search.cgi"
+
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
+
+ def setup_dummy_item(maker)
+ title = "TITLE"
+ link = "http://hoge.com/"
+
+ item = maker.items.new_item
+ item.title = title
+ item.link = link
+ end
+
+ def setup_dummy_item_atom(maker)
+ setup_dummy_item(maker)
+
+ item = maker.items.first
+ item.id = "http://example.net/xxx"
+ item.updated = Time.now
+ end
+
+ def setup_taxo_topic(target, topics)
+ topics.each do |topic|
+ taxo_topic = target.taxo_topics.new_taxo_topic
+ topic.each do |name, value|
+ case name
+ when :link
+ taxo_topic.taxo_link = value
+ when :topics
+ value.each do |t|
+ taxo_topic.taxo_topics << t
+ end
+ else
+ dc_elems = taxo_topic.__send__("dc_#{name}s")
+ dc_elem = dc_elems.__send__("new_#{name}")
+ dc_elem.value = value
+ end
+ end
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_1.0.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_1.0.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_1.0.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,296 @@
+require "rexml/document"
+
+require "rss-testcase"
+
+require "rss/1.0"
+
+module RSS
+ class TestRSS10Core < TestCase
+
+ def setup
+ @rdf_prefix = "rdf"
+ @rdf_uri = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ @uri = "http://purl.org/rss/1.0/"
+ end
+
+ def test_RDF
+ version = "1.0"
+ encoding = "UTF-8"
+ standalone = false
+
+ rdf = RDF.new(version, encoding, standalone)
+ setup_rss10(rdf)
+ doc = REXML::Document.new(rdf.to_s)
+
+ xmldecl = doc.xml_decl
+
+ %w(version encoding).each do |x|
+ assert_equal(instance_eval(x), xmldecl.__send__(x))
+ end
+ assert_equal(standalone, !xmldecl.standalone.nil?)
+
+ assert_equal(@rdf_uri, doc.root.namespace)
+ end
+
+ def test_not_displayed_xml_stylesheets
+ rdf = RDF.new()
+ plain_rdf = rdf.to_s
+ 3.times do
+ rdf.xml_stylesheets.push(XMLStyleSheet.new)
+ assert_equal(plain_rdf, rdf.to_s)
+ end
+ end
+
+ def test_xml_stylesheets
+ [
+ [{:href => "a.xsl", :type => "text/xsl"}],
+ [
+ {:href => "a.xsl", :type => "text/xsl"},
+ {:href => "a.css", :type => "text/css"},
+ ],
+ ].each do |attrs_ary|
+ assert_xml_stylesheet_pis(attrs_ary)
+ end
+ end
+
+ def test_channel
+ about = "http://hoge.com"
+ title = "fugafuga"
+ link = "http://hoge.com"
+ description = "fugafugafugafuga"
+ resource = "http://hoge.com/hoge.png"
+
+ item_title = "item title"
+ item_link = "http://hoge.com/item"
+
+ image = RDF::Channel::Image.new(resource)
+ items = RDF::Channel::Items.new
+ items.Seq.lis << items.class::Seq::Li.new(item_link)
+ textinput = RDF::Channel::Textinput.new(resource)
+
+ rss_item = RDF::Item.new
+ rss_item.title = item_title
+ rss_item.link = item_link
+ rss_item.about = item_link
+
+ channel = RDF::Channel.new(about)
+ %w(title link description image items textinput).each do |x|
+ channel.__send__("#{x}=", instance_eval(x))
+ end
+
+ doc = REXML::Document.new(make_RDF(<<-EOR))
+#{channel}
+<items>
+#{rss_item}
+</items>
+EOR
+ c = doc.root.elements[1]
+
+ assert_equal(about, c.attributes["about"])
+ %w(title link description image textinput).each do |x|
+ elem = c.elements[x]
+ assert_equal(x, elem.name)
+ assert_equal(@uri, elem.namespace)
+ if x == "image" or x == "textinput"
+ excepted = resource
+ res = elem.attributes.get_attribute("resource")
+ assert_equal(@rdf_uri, res.namespace)
+ value = res.value
+ else
+ excepted = instance_eval(x)
+ value = elem.text
+ end
+ assert_equal(excepted, value)
+ end
+ assert_equal(@uri, c.elements["items"].namespace)
+ assert_equal("items", c.elements["items"].name)
+ end
+
+ def test_channel_image
+ resource = "http://hoge.com/hoge.png"
+ image = RDF::Channel::Image.new(resource)
+
+ doc = REXML::Document.new(make_RDF(image.to_s))
+ i = doc.root.elements[1]
+
+ assert_equal("image", i.name)
+ assert_equal(@uri, i.namespace)
+
+ res = i.attributes.get_attribute("resource")
+
+ assert_equal(@rdf_uri, res.namespace)
+ assert_equal(resource, res.value)
+ end
+
+ def test_channel_textinput
+ resource = "http://hoge.com/hoge.png"
+ textinput = RDF::Channel::Textinput.new(resource)
+
+ doc = REXML::Document.new(make_RDF(textinput.to_s))
+ t = doc.root.elements[1]
+
+ assert_equal("textinput", t.name)
+ assert_equal(@uri, t.namespace)
+
+ res = t.attributes.get_attribute("resource")
+
+ assert_equal(@rdf_uri, res.namespace)
+ assert_equal(resource, res.value)
+ end
+
+ def test_channel_items
+ item_link = "http://example.com/item"
+
+ items = RDF::Channel::Items.new
+ li = items.Seq.class::Li.new(item_link)
+ items.Seq.lis << li
+
+ doc = REXML::Document.new(make_RDF(items.to_s))
+ i = doc.root.elements[1]
+
+ assert_equal("items", i.name)
+ assert_equal(@uri, i.namespace)
+
+ assert_equal(1, i.elements.size)
+ seq = i.elements[1]
+ assert_equal("Seq", seq.name)
+ assert_equal(@rdf_uri, seq.namespace)
+
+ assert_equal(1, seq.elements.size)
+ l = seq.elements[1]
+ assert_equal("li", l.name)
+ assert_equal(@rdf_uri, l.namespace)
+ assert_equal(item_link, l.attributes["resource"])
+ end
+
+ def test_seq
+ item_link = "http://example.com/item"
+ seq = RDF::Seq.new
+ li = seq.class::Li.new(item_link)
+ seq.lis << li
+
+ doc = REXML::Document.new(make_RDF(seq.to_s))
+ s = doc.root.elements[1]
+
+ assert_equal("Seq", s.name)
+ assert_equal(@rdf_uri, s.namespace)
+
+ assert_equal(1, s.elements.size)
+ l = s.elements[1]
+ assert_equal("li", l.name)
+ assert_equal(@rdf_uri, l.namespace)
+ assert_equal(item_link, l.attributes["resource"])
+ end
+
+ def test_li
+ resource = "http://hoge.com/"
+ li = RDF::Li.new(resource)
+
+ doc = REXML::Document.new(make_RDF(li.to_s))
+ l = doc.root.elements[1]
+
+ assert_equal("li", l.name)
+ assert_equal(@rdf_uri, l.namespace(l.prefix))
+
+ res = l.attributes.get_attribute("resource")
+
+ assert_equal('', res.instance_eval("@prefix"))
+ assert_equal(resource, res.value)
+ end
+
+ def test_image
+ about = "http://hoge.com"
+ title = "fugafuga"
+ url = "http://hoge.com/hoge"
+ link = "http://hoge.com/fuga"
+
+ image = RDF::Image.new(about)
+ %w(title url link).each do |x|
+ image.__send__("#{x}=", instance_eval(x))
+ end
+
+ doc = REXML::Document.new(make_RDF(image.to_s))
+ i = doc.root.elements[1]
+
+ assert_equal(about, i.attributes["about"])
+ %w(title url link).each do |x|
+ elem = i.elements[x]
+ assert_equal(x, elem.name)
+ assert_equal(@uri, elem.namespace)
+ assert_equal(instance_eval(x), elem.text)
+ end
+ end
+
+ def test_item
+ about = "http://hoge.com"
+ title = "fugafuga"
+ link = "http://hoge.com/fuga"
+ description = "hogehogehoge"
+
+ item = RDF::Item.new(about)
+ %w(title link description).each do |x|
+ item.__send__("#{x}=", instance_eval(x))
+ end
+
+ doc = REXML::Document.new(make_RDF(item.to_s))
+ i = doc.root.elements[1]
+
+ assert_equal(about, i.attributes["about"])
+ %w(title link description).each do |x|
+ elem = i.elements[x]
+ assert_equal(x, elem.name)
+ assert_equal(@uri, elem.namespace)
+ assert_equal(instance_eval(x), elem.text)
+ end
+ end
+
+ def test_textinput
+ about = "http://hoge.com"
+ title = "fugafuga"
+ link = "http://hoge.com/fuga"
+ name = "foo"
+ description = "hogehogehoge"
+
+ textinput = RDF::Textinput.new(about)
+ %w(title link name description).each do |x|
+ textinput.__send__("#{x}=", instance_eval(x))
+ end
+
+ doc = REXML::Document.new(make_RDF(textinput.to_s))
+ t = doc.root.elements[1]
+
+ assert_equal(about, t.attributes["about"])
+ %w(title link name description).each do |x|
+ elem = t.elements[x]
+ assert_equal(x, elem.name)
+ assert_equal(@uri, elem.namespace)
+ assert_equal(instance_eval(x), elem.text)
+ end
+ end
+
+ def test_to_xml
+ rss = RSS::Parser.parse(make_sample_RDF)
+ assert_equal(rss.to_s, rss.to_xml)
+ assert_equal(rss.to_s, rss.to_xml("1.0"))
+ rss09 = rss.to_xml("0.91") do |maker|
+ maker.channel.language = "en-us"
+ end
+ rss09 = RSS::Parser.parse(rss09)
+ assert_equal("0.91", rss09.rss_version)
+ assert_equal(["rss", "0.91", nil], rss09.feed_info)
+ rss20 = RSS::Parser.parse(rss.to_xml("2.0"))
+ assert_equal("2.0", rss20.rss_version)
+ assert_equal(["rss", "2.0", nil], rss20.feed_info)
+
+ atom_xml = rss.to_xml("atom") do |maker|
+ maker.channel.author = "Alice"
+ maker.channel.updated ||= Time.now
+ maker.items.each do |item|
+ item.updated ||= Time.now
+ end
+ end
+ atom = RSS::Parser.parse(atom_xml)
+ assert_equal(["atom", "1.0", "feed"], atom.feed_info)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_2.0.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_2.0.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_2.0.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,410 @@
+require "rexml/document"
+
+require "rss-testcase"
+
+module RSS
+ class TestRSS20Core < TestCase
+
+ def setup
+ @rss_version = "2.0"
+ end
+
+ def test_Rss
+ version = "1.0"
+ encoding = "UTF-8"
+ standalone = false
+
+ rss = Rss.new(@rss_version, version, encoding, standalone)
+ setup_rss20(rss)
+
+ doc = REXML::Document.new(rss.to_s(false))
+
+ xmldecl = doc.xml_decl
+
+ %w(version encoding).each do |x|
+ assert_equal(instance_eval(x), xmldecl.__send__(x))
+ end
+ assert_equal(standalone, !xmldecl.standalone.nil?)
+
+ assert_equal("", doc.root.namespace)
+ assert_equal(@rss_version, doc.root.attributes["version"])
+ end
+
+ def test_not_displayed_xml_stylesheets
+ rss = Rss.new(@rss_version)
+ plain_rss = rss.to_s
+ 3.times do
+ rss.xml_stylesheets.push(XMLStyleSheet.new)
+ assert_equal(plain_rss, rss.to_s)
+ end
+ end
+
+ def test_xml_stylesheets
+ [
+ [{:href => "a.xsl", :type => "text/xsl"}],
+ [
+ {:href => "a.xsl", :type => "text/xsl"},
+ {:href => "a.css", :type => "text/css"},
+ ],
+ ].each do |attrs_ary|
+ rss = Rss.new(@rss_version)
+ setup_rss20(rss)
+ assert_xml_stylesheet_pis(attrs_ary, rss)
+ end
+ end
+
+ def test_channel
+ title = "fugafuga"
+ link = "http://hoge.com"
+ description = "fugafugafugafuga"
+
+ language = "en-us"
+ copyright = "Copyright 2002, Spartanburg Herald-Journal"
+ managingEditor = "geo at herald.com (George Matesky)"
+ webMaster = "betty at herald.com (Betty Guernsey)"
+ pubDate = Time.parse("Sat, 07 Sep 2002 00:00:01 GMT")
+ lastBuildDate = Time.parse("Sat, 07 Sep 2002 09:42:31 GMT")
+ categories = [
+ {
+ :content => "Newspapers",
+ },
+ {
+ :domain => "Syndic8",
+ :content => "1765",
+ }
+ ]
+ generator = "MightyInHouse Content System v2.3"
+ docs = "http://blogs.law.harvard.edu/tech/rss"
+
+ ttl = "60"
+
+ rating = '(PICS-1.1 "http://www.rsac.org/ratingsv01.html" l gen true comment "RSACi North America Server" for "http://www.rsac.org" on "1996.04.16T08:15-0500" r (n 0 s 0 v 0 l 0))'
+
+ channel = Rss::Channel.new
+
+ elems = %w(title link description language copyright
+ managingEditor webMaster pubDate lastBuildDate
+ generator docs ttl rating)
+ elems.each do |x|
+ value = instance_eval(x)
+ value = value.rfc822 if %w(pubDate lastBuildDate).include?(x)
+ channel.__send__("#{x}=", value)
+ end
+ categories.each do |cat|
+ channel.categories << Rss::Channel::Category.new(cat[:domain],
+ cat[:content])
+ end
+
+ doc = REXML::Document.new(make_rss20(channel.to_s))
+ c = doc.root.elements[1]
+
+ elems.each do |x|
+ elem = c.elements[x]
+ assert_equal(x, elem.name)
+ assert_equal("", elem.namespace)
+ expected = instance_eval(x)
+ case x
+ when "pubDate", "lastBuildDate"
+ assert_equal(expected, Time.parse(elem.text))
+ when "ttl"
+ expected = channel.__send__(x)
+ assert_equal(expected, elem.text.to_i)
+ else
+ assert_equal(expected, elem.text)
+ end
+ end
+ categories.each_with_index do |cat, i|
+ cat = cat.dup
+ cat[:domain] ||= nil
+ category = c.elements["category[#{i+1}]"]
+ actual = {
+ :domain => category.attributes["domain"],
+ :content => category.text,
+ }
+ assert_equal(cat, actual)
+ end
+ end
+
+ def test_channel_cloud
+ cloud_params = {
+ :domain => "rpc.sys.com",
+ :port => "80",
+ :path => "/RPC2",
+ :registerProcedure => "myCloud.rssPleaseNotify",
+ :protocol => "xml-rpc",
+ }
+ cloud = Rss::Channel::Cloud.new(cloud_params[:domain],
+ cloud_params[:port],
+ cloud_params[:path],
+ cloud_params[:registerProcedure],
+ cloud_params[:protocol])
+ cloud_params[:port] = cloud.port
+
+ doc = REXML::Document.new(cloud.to_s)
+ cloud_elem = doc.root
+
+ actual = {}
+ cloud_elem.attributes.each do |name, value|
+ value = value.to_i if name == "port"
+ actual[name.intern] = value
+ end
+ assert_equal(cloud_params, actual)
+ end
+
+ def test_channel_image
+ image_params = {
+ :url => "http://hoge.com/hoge.png",
+ :title => "fugafuga",
+ :link => "http://hoge.com",
+ :width => "144",
+ :height => "400",
+ :description => "an image",
+ }
+ image = Rss::Channel::Image.new(image_params[:url],
+ image_params[:title],
+ image_params[:link],
+ image_params[:width],
+ image_params[:height],
+ image_params[:description])
+
+ doc = REXML::Document.new(image.to_s)
+ image_elem = doc.root
+
+ image_params.each do |name, value|
+ value = image.__send__(name)
+ actual = image_elem.elements[name.to_s].text
+ actual = actual.to_i if [:width, :height].include?(name)
+ assert_equal(value, actual)
+ end
+ end
+
+ def test_channel_textInput
+ textInput_params = {
+ :title => "fugafuga",
+ :description => "text hoge fuga",
+ :name => "hoge",
+ :link => "http://hoge.com",
+ }
+ textInput = Rss::Channel::TextInput.new(textInput_params[:title],
+ textInput_params[:description],
+ textInput_params[:name],
+ textInput_params[:link])
+
+ doc = REXML::Document.new(textInput.to_s)
+ input_elem = doc.root
+
+ textInput_params.each do |name, value|
+ actual = input_elem.elements[name.to_s].text
+ assert_equal(value, actual)
+ end
+ end
+
+ def test_channel_skip_days
+ skipDays_values = [
+ "Sunday",
+ "Monday",
+ ]
+ skipDays = Rss::Channel::SkipDays.new
+ skipDays_values.each do |value|
+ skipDays.days << Rss::Channel::SkipDays::Day.new(value)
+ end
+
+ doc = REXML::Document.new(skipDays.to_s)
+ days_elem = doc.root
+
+ skipDays_values.each_with_index do |value, i|
+ assert_equal(value, days_elem.elements[i + 1].text)
+ end
+ end
+
+ def test_channel_skip_hours
+ skipHours_values = [
+ "0",
+ "13",
+ ]
+ skipHours = Rss::Channel::SkipHours.new
+ skipHours_values.each do |value|
+ skipHours.hours << Rss::Channel::SkipHours::Hour.new(value)
+ end
+
+ doc = REXML::Document.new(skipHours.to_s)
+ hours_elem = doc.root
+
+ skipHours_values.each_with_index do |value, i|
+ expected = skipHours.hours[i].content
+ assert_equal(expected, hours_elem.elements[i + 1].text.to_i)
+ end
+ end
+
+ def test_item
+ title = "fugafuga"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+ author = "oprah at oxygen.net"
+ categories = [
+ {
+ :content => "Newspapers",
+ },
+ {
+ :domain => "Syndic8",
+ :content => "1765",
+ }
+ ]
+ comments = "http://www.myblog.org/cgi-local/mt/mt-comments.cgi?entry_id=290"
+ pubDate = Time.parse("Sat, 07 Sep 2002 00:00:01 GMT")
+
+ channel = Rss::Channel.new
+ channel.title = "title"
+ channel.link = "http://example.com/"
+ channel.description = "description"
+
+ item = Rss::Channel::Item.new
+ channel.items << item
+
+ elems = %w(title link description author comments pubDate)
+ elems.each do |x|
+ value = instance_eval(x)
+ value = value.rfc822 if x == "pubDate"
+ item.__send__("#{x}=", value)
+ end
+ categories.each do |cat|
+ item.categories << Rss::Channel::Category.new(cat[:domain],
+ cat[:content])
+ end
+
+ doc = REXML::Document.new(channel.to_s)
+ channel_elem = doc.root
+
+ item_elem = channel_elem.elements["item[1]"]
+ elems.each do |x|
+ elem = item_elem.elements[x]
+ assert_equal(x, elem.name)
+ assert_equal("", elem.namespace)
+ expected = instance_eval(x)
+ case x
+ when "pubDate"
+ assert_equal(expected, Time.parse(elem.text))
+ else
+ assert_equal(expected, elem.text)
+ end
+ end
+ categories.each_with_index do |cat, i|
+ cat = cat.dup
+ cat[:domain] ||= nil
+ category = item_elem.elements["category[#{i+1}]"]
+ actual = {
+ :domain => category.attributes["domain"],
+ :content => category.text,
+ }
+ assert_equal(cat, actual)
+ end
+ end
+
+ def test_item_enclosure
+ enclosure_params = {
+ :url => "http://www.scripting.com/mp3s/weatherReportSuite.mp3",
+ :length => "12216320",
+ :type => "audio/mpeg",
+ }
+
+ enclosure = Rss::Channel::Item::Enclosure.new(enclosure_params[:url],
+ enclosure_params[:length],
+ enclosure_params[:type])
+ enclosure_params[:length] = enclosure.length
+
+ doc = REXML::Document.new(enclosure.to_s)
+ enclosure_elem = doc.root
+
+ actual = {}
+ enclosure_elem.attributes.each do |name, value|
+ value = value.to_i if name == "length"
+ actual[name.intern] = value
+ end
+ assert_equal(enclosure_params, actual)
+ end
+
+ def test_item_guid
+ test_params = [
+ {
+ :content => "http://some.server.com/weblogItem3207",
+ },
+ {
+ :isPermaLink => "true",
+ :content => "http://inessential.com/2002/09/01.php#a2",
+ },
+ ]
+
+ test_params.each do |guid_params|
+ guid = Rss::Channel::Item::Guid.new(guid_params[:isPermaLink],
+ guid_params[:content])
+ if guid_params.has_key?(:isPermaLink)
+ guid_params[:isPermaLink] = guid.isPermaLink
+ end
+ if guid.isPermaLink.nil?
+ assert_equal(true, guid.PermaLink?)
+ else
+ assert_equal(guid.isPermaLink, guid.PermaLink?)
+ end
+
+ doc = REXML::Document.new(guid.to_s)
+ guid_elem = doc.root
+
+ actual = {}
+ actual[:content] = guid_elem.text if guid_elem.text
+ guid_elem.attributes.each do |name, value|
+ value = value == "true" if name == "isPermaLink"
+ actual[name.intern] = value
+ end
+ assert_equal(guid_params, actual)
+ end
+ end
+
+ def test_item_source
+ source_params = {
+ :url => "http://www.tomalak.org/links2.xml",
+ :content => "Tomalak's Realm",
+ }
+
+ source = Rss::Channel::Item::Source.new(source_params[:url],
+ source_params[:content])
+
+ doc = REXML::Document.new(source.to_s)
+ source_elem = doc.root
+
+ actual = {}
+ actual[:content] = source_elem.text
+ source_elem.attributes.each do |name, value|
+ actual[name.intern] = value
+ end
+ assert_equal(source_params, actual)
+ end
+
+ def test_to_xml
+ rss = RSS::Parser.parse(make_sample_rss20)
+ assert_equal(rss.to_s, rss.to_xml)
+ assert_equal(rss.to_s, rss.to_xml("2.0"))
+ rss09_xml = rss.to_xml("0.91") do |maker|
+ setup_dummy_image(maker)
+ end
+ rss09 = RSS::Parser.parse(rss09_xml)
+ assert_equal("0.91", rss09.rss_version)
+ rss10 = rss.to_xml("1.0") do |maker|
+ maker.channel.about = "http://www.example.com/index.rdf"
+ end
+ rss10 = RSS::Parser.parse(rss10)
+ assert_equal("1.0", rss10.rss_version)
+
+ atom_xml = rss.to_xml("atom1.0") do |maker|
+ maker.channel.id = "http://www.example.com/atom.xml"
+ maker.channel.author = "Alice"
+ maker.channel.updated = Time.now
+ maker.items.each do |item|
+ item.author = "Bob"
+ item.updated = Time.now
+ end
+ end
+ atom = RSS::Parser.parse(atom_xml)
+ assert_equal(["atom", "1.0", "feed"], atom.feed_info)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_accessor.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_accessor.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_accessor.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,103 @@
+require "rss-testcase"
+
+require "rss/1.0"
+require "rss/2.0"
+require "rss/syndication"
+require "rss/image"
+
+module RSS
+ class TestAccessor < TestCase
+ def test_date
+ channel = Rss::Channel.new
+ channel.pubDate = nil
+ assert_nil(channel.pubDate)
+
+ time = Time.now
+ channel.pubDate = time
+ assert_equal(time, channel.pubDate)
+
+ time = Time.parse(Time.now.rfc822)
+ channel.pubDate = time.rfc822
+ assert_equal(time, channel.pubDate)
+
+ time = Time.parse(Time.now.iso8601)
+ value = time.iso8601
+ assert_not_available_value("pubDate", value) do
+ channel.pubDate = value
+ end
+
+ channel.do_validate = false
+ time = Time.parse(Time.now.iso8601)
+ value = time.iso8601
+ channel.pubDate = value
+ assert_equal(time, channel.pubDate)
+
+ channel.pubDate = nil
+ assert_nil(channel.pubDate)
+ end
+
+ def test_integer
+ image_item = RDF::Item::ImageItem.new
+
+ image_item.width = nil
+ assert_nil(image_item.width)
+
+ width = 10
+ image_item.width = width
+ assert_equal(width, image_item.width)
+
+ width = 10.0
+ image_item.width = width
+ assert_equal(width, image_item.width)
+
+ width = "10"
+ image_item.width = width
+ assert_equal(width.to_i, image_item.width)
+
+ width = "10.0"
+ assert_not_available_value("image:width", width) do
+ image_item.width = width
+ end
+
+ image_item.do_validate = false
+ width = "10.0"
+ image_item.width = width
+ assert_equal(width.to_i, image_item.width)
+
+ image_item.width = nil
+ assert_nil(image_item.width)
+ end
+
+ def test_positive_integer
+ channel = RDF::Channel.new
+
+ channel.sy_updateFrequency = nil
+ assert_nil(channel.sy_updateFrequency)
+
+ freq = 10
+ channel.sy_updateFrequency = freq
+ assert_equal(freq, channel.sy_updateFrequency)
+
+ freq = 10.0
+ channel.sy_updateFrequency = freq
+ assert_equal(freq, channel.sy_updateFrequency)
+
+ freq = "10"
+ channel.sy_updateFrequency = freq
+ assert_equal(freq.to_i, channel.sy_updateFrequency)
+
+ freq = "10.0"
+ assert_not_available_value("sy:updateFrequency", freq) do
+ channel.sy_updateFrequency = freq
+ end
+
+ channel.do_validate = false
+ freq = "10.0"
+ channel.sy_updateFrequency = freq
+ assert_equal(freq.to_i, channel.sy_updateFrequency)
+
+ channel.sy_updateFrequency = nil
+ assert_nil(channel.sy_updateFrequency)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_atom.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_atom.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_atom.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,683 @@
+require "rexml/document"
+
+require "rss-testcase"
+
+require "rss/atom"
+
+module RSS
+ class TestAtomCore < TestCase
+ def setup
+ @uri = "http://www.w3.org/2005/Atom"
+ @xhtml_uri = "http://www.w3.org/1999/xhtml"
+ end
+
+ def test_feed
+ version = "1.0"
+ encoding = "UTF-8"
+ standalone = false
+
+ feed = Atom::Feed.new(version, encoding, standalone)
+ assert_equal("", feed.to_s)
+
+ author = feed.class::Author.new
+ name = feed.class::Author::Name.new
+ name.content = "an author"
+ author.name = name
+ assert_not_equal("", author.to_s)
+ feed.authors << author
+ assert_equal("", feed.to_s)
+
+ id = feed.class::Id.new
+ id.content = "http://example.com/atom.xml"
+ assert_not_equal("", id.to_s)
+ feed.id = id
+ assert_equal("", feed.to_s)
+
+ title = feed.class::Title.new
+ title.content = "a title"
+ assert_not_equal("", title.to_s)
+ feed.title = title
+ assert_equal("", feed.to_s)
+
+ updated = feed.class::Updated.new
+ updated.content = Time.now
+ assert_not_equal("", updated.to_s)
+ feed.updated = updated
+ assert_not_equal("", feed.to_s)
+
+
+ feed.authors.clear
+ assert_equal("", feed.to_s)
+ entry = Atom::Feed::Entry.new
+ setup_entry(entry)
+ assert_not_equal("", entry.to_s)
+
+ author = entry.authors.first
+ entry.authors.clear
+ assert_equal("", entry.to_s)
+ entry.parent = feed
+ assert_equal("", entry.to_s)
+ feed.authors << author
+ assert_not_equal("", entry.to_s)
+ feed.authors.clear
+ feed.entries << entry
+ assert_equal("", feed.to_s)
+ entry.authors << author
+ assert_not_equal("", entry.to_s)
+ assert_not_equal("", feed.to_s)
+
+ doc = REXML::Document.new(feed.to_s)
+ xmldecl = doc.xml_decl
+
+ %w(version encoding).each do |x|
+ assert_equal(instance_eval(x), xmldecl.__send__(x))
+ end
+ assert_equal(standalone, !xmldecl.standalone.nil?)
+
+ assert_equal(@uri, doc.root.namespace)
+ end
+
+ def test_entry
+ version = "1.0"
+ encoding = "UTF-8"
+ standalone = false
+
+ entry = Atom::Entry.new(version, encoding, standalone)
+ setup_entry(entry)
+
+ author = entry.authors.first
+ entry.authors.clear
+ assert_equal("", entry.to_s)
+ source = Atom::Entry::Source.new
+ source.authors << author
+ entry.source = source
+ assert_not_equal("", entry.to_s)
+
+ doc = REXML::Document.new(entry.to_s)
+ xmldecl = doc.xml_decl
+
+ %w(version encoding).each do |x|
+ assert_equal(instance_eval(x), xmldecl.__send__(x))
+ end
+ assert_equal(standalone, !xmldecl.standalone.nil?)
+
+ assert_equal(@uri, doc.root.namespace)
+ end
+
+ def test_not_displayed_xml_stylesheets
+ feed = Atom::Feed.new
+ plain_feed = feed.to_s
+ 3.times do
+ feed.xml_stylesheets.push(XMLStyleSheet.new)
+ assert_equal(plain_feed, feed.to_s)
+ end
+ end
+
+ def test_atom_author
+ assert_atom_person_to_s(Atom::Feed::Author)
+ assert_atom_person_to_s(Atom::Feed::Entry::Author)
+ assert_atom_person_to_s(Atom::Entry::Author)
+ assert_atom_person_to_s(Atom::Feed::Entry::Source::Author)
+ assert_atom_person_to_s(Atom::Entry::Source::Author)
+ end
+
+ def test_atom_category
+ assert_atom_category_to_s(Atom::Feed::Category)
+ assert_atom_category_to_s(Atom::Feed::Entry::Category)
+ assert_atom_category_to_s(Atom::Entry::Category)
+ assert_atom_category_to_s(Atom::Feed::Entry::Source::Category)
+ assert_atom_category_to_s(Atom::Entry::Source::Category)
+ end
+
+ def test_atom_contributor
+ assert_atom_person_to_s(Atom::Feed::Contributor)
+ assert_atom_person_to_s(Atom::Feed::Entry::Contributor)
+ assert_atom_person_to_s(Atom::Entry::Contributor)
+ assert_atom_person_to_s(Atom::Feed::Entry::Source::Contributor)
+ assert_atom_person_to_s(Atom::Entry::Source::Contributor)
+ end
+
+ def test_atom_generator
+ assert_atom_generator_to_s(Atom::Feed::Generator)
+ assert_atom_generator_to_s(Atom::Feed::Entry::Source::Generator)
+ assert_atom_generator_to_s(Atom::Entry::Source::Generator)
+ end
+
+ def test_atom_icon
+ assert_atom_icon_to_s(Atom::Feed::Icon)
+ assert_atom_icon_to_s(Atom::Feed::Entry::Source::Icon)
+ assert_atom_icon_to_s(Atom::Entry::Source::Icon)
+ end
+
+ def test_atom_id
+ assert_atom_id_to_s(Atom::Feed::Id)
+ assert_atom_id_to_s(Atom::Feed::Entry::Id)
+ assert_atom_id_to_s(Atom::Entry::Id)
+ assert_atom_id_to_s(Atom::Feed::Entry::Source::Id)
+ assert_atom_id_to_s(Atom::Entry::Source::Id)
+ end
+
+ def test_atom_link
+ assert_atom_link_to_s(Atom::Feed::Link)
+ assert_atom_link_to_s(Atom::Feed::Entry::Link)
+ assert_atom_link_to_s(Atom::Entry::Link)
+ assert_atom_link_to_s(Atom::Feed::Entry::Source::Link)
+ assert_atom_link_to_s(Atom::Entry::Source::Link)
+ end
+
+ def test_atom_logo
+ assert_atom_logo_to_s(Atom::Feed::Logo)
+ assert_atom_logo_to_s(Atom::Feed::Entry::Source::Logo)
+ assert_atom_logo_to_s(Atom::Entry::Source::Logo)
+ end
+
+ def test_atom_rights
+ assert_atom_text_construct_to_s(Atom::Feed::Rights)
+ assert_atom_text_construct_to_s(Atom::Feed::Entry::Rights)
+ assert_atom_text_construct_to_s(Atom::Entry::Rights)
+ assert_atom_text_construct_to_s(Atom::Feed::Entry::Source::Rights)
+ assert_atom_text_construct_to_s(Atom::Entry::Source::Rights)
+ end
+
+ def test_atom_subtitle
+ assert_atom_text_construct_to_s(Atom::Feed::Subtitle)
+ assert_atom_text_construct_to_s(Atom::Feed::Entry::Source::Subtitle)
+ assert_atom_text_construct_to_s(Atom::Entry::Source::Subtitle)
+ end
+
+ def test_atom_title
+ assert_atom_text_construct_to_s(Atom::Feed::Title)
+ assert_atom_text_construct_to_s(Atom::Feed::Entry::Title)
+ assert_atom_text_construct_to_s(Atom::Entry::Title)
+ assert_atom_text_construct_to_s(Atom::Feed::Entry::Source::Title)
+ assert_atom_text_construct_to_s(Atom::Entry::Source::Title)
+ end
+
+ def test_atom_updated
+ assert_atom_date_construct_to_s(Atom::Feed::Updated)
+ assert_atom_date_construct_to_s(Atom::Feed::Entry::Updated)
+ assert_atom_date_construct_to_s(Atom::Entry::Updated)
+ assert_atom_date_construct_to_s(Atom::Feed::Entry::Source::Updated)
+ assert_atom_date_construct_to_s(Atom::Entry::Source::Updated)
+ end
+
+ def test_atom_content
+ assert_atom_content_to_s(Atom::Feed::Entry::Content)
+ assert_atom_content_to_s(Atom::Entry::Content)
+ end
+
+ def test_atom_published
+ assert_atom_date_construct_to_s(Atom::Feed::Entry::Published)
+ assert_atom_date_construct_to_s(Atom::Entry::Published)
+ end
+
+ def test_atom_summary
+ assert_atom_text_construct_to_s(Atom::Feed::Entry::Summary)
+ assert_atom_text_construct_to_s(Atom::Entry::Summary)
+ end
+
+
+ def test_to_xml(with_convenience_way=true)
+ atom = RSS::Parser.parse(make_feed)
+ assert_equal(atom.to_s, atom.to_xml)
+ assert_equal(atom.to_s, atom.to_xml("atom"))
+ assert_equal(atom.to_s, atom.to_xml("atom1.0"))
+ assert_equal(atom.to_s, atom.to_xml("atom1.0:feed"))
+ assert_equal(atom.to_s, atom.to_xml("atom:feed"))
+
+ rss09_xml = atom.to_xml("0.91") do |maker|
+ maker.channel.language = "en-us"
+ maker.channel.link = "http://example.com/"
+ if with_convenience_way
+ maker.channel.description = atom.title.content
+ else
+ maker.channel.description {|d| d.content = atom.title.content}
+ end
+
+ maker.image.url = "http://example.com/logo.png"
+ maker.image.title = "Logo"
+ end
+ rss09 = RSS::Parser.parse(rss09_xml)
+ assert_equal(["rss", "0.91", nil], rss09.feed_info)
+
+ rss20_xml = atom.to_xml("2.0") do |maker|
+ maker.channel.link = "http://example.com/"
+ if with_convenience_way
+ maker.channel.description = atom.title.content
+ else
+ maker.channel.description {|d| d.content = atom.title.content}
+ end
+ end
+ rss20 = RSS::Parser.parse(rss20_xml)
+ assert_equal("2.0", rss20.rss_version)
+ assert_equal(["rss", "2.0", nil], rss20.feed_info)
+ end
+
+ def test_to_xml_with_new_api_since_018
+ test_to_xml(false)
+ end
+
+ private
+ def setup_entry(entry)
+ _wrap_assertion do
+ assert_equal("", entry.to_s)
+
+ author = entry.class::Author.new
+ name = entry.class::Author::Name.new
+ name.content = "an author"
+ author.name = name
+ assert_not_equal("", author.to_s)
+ entry.authors << author
+ assert_equal("", entry.to_s)
+
+ id = entry.class::Id.new
+ id.content = "http://example.com/atom.xml"
+ assert_not_equal("", id.to_s)
+ entry.id = id
+ assert_equal("", entry.to_s)
+
+ title = entry.class::Title.new
+ title.content = "a title"
+ assert_not_equal("", title.to_s)
+ entry.title = title
+ assert_equal("", entry.to_s)
+
+ updated = entry.class::Updated.new
+ updated.content = Time.now
+ assert_not_equal("", updated.to_s)
+ entry.updated = updated
+ assert_not_equal("", entry.to_s)
+ end
+ end
+
+
+ def assert_atom_person_to_s(target_class)
+ _wrap_assertion do
+ name = "A person"
+ uri = "http://example.com/person/"
+ email = "person at example.com"
+
+ target = target_class.new
+ assert_equal("", target.to_s)
+
+ target = target_class.new
+ person_name = target_class::Name.new
+ person_name.content = name
+ target.name = person_name
+ xml_target = REXML::Document.new(target.to_s).root
+ assert_equal(["name"], xml_target.elements.collect {|e| e.name})
+ assert_equal([name], xml_target.elements.collect {|e| e.text})
+
+ person_uri = target_class::Uri.new
+ person_uri.content = uri
+ target.uri = person_uri
+ xml_target = REXML::Document.new(target.to_s).root
+ assert_equal(["name", "uri"], xml_target.elements.collect {|e| e.name})
+ assert_equal([name, uri], xml_target.elements.collect {|e| e.text})
+
+ person_email = target_class::Email.new
+ person_email.content = email
+ target.email = person_email
+ xml_target = REXML::Document.new(target.to_s).root
+ assert_equal(["name", "uri", "email"],
+ xml_target.elements.collect {|e| e.name})
+ assert_equal([name, uri, email],
+ xml_target.elements.collect {|e| e.text})
+ end
+ end
+
+ def assert_atom_category_to_s(target_class)
+ _wrap_assertion do
+ term = "music"
+ scheme = "http://example.com/music"
+ label = "Music"
+
+ category = target_class.new
+ assert_equal("", category.to_s)
+
+ category = target_class.new
+ category.scheme = scheme
+ assert_equal("", category.to_s)
+
+ category = target_class.new
+ category.label = label
+ assert_equal("", category.to_s)
+
+ category = target_class.new
+ category.scheme = scheme
+ category.label = label
+ assert_equal("", category.to_s)
+
+ category = target_class.new
+ category.term = term
+ xml = REXML::Document.new(category.to_s).root
+ assert_rexml_element([], {"term" => term}, nil, xml)
+
+ category = target_class.new
+ category.term = term
+ category.scheme = scheme
+ xml = REXML::Document.new(category.to_s).root
+ assert_rexml_element([], {"term" => term, "scheme" => scheme}, nil, xml)
+
+ category = target_class.new
+ category.term = term
+ category.label = label
+ xml = REXML::Document.new(category.to_s).root
+ assert_rexml_element([], {"term" => term, "label" => label}, nil, xml)
+
+ category = target_class.new
+ category.term = term
+ category.scheme = scheme
+ category.label = label
+ xml = REXML::Document.new(category.to_s).root
+ attrs = {"term" => term, "scheme" => scheme, "label" => label}
+ assert_rexml_element([], attrs, nil, xml)
+ end
+ end
+
+ def assert_atom_generator_to_s(target_class)
+ _wrap_assertion do
+ content = "Feed generator"
+ uri = "http://example.com/generator"
+ version = "0.0.1"
+
+ generator = target_class.new
+ assert_equal("", generator.to_s)
+
+ generator = target_class.new
+ generator.uri = uri
+ assert_equal("", generator.to_s)
+
+ generator = target_class.new
+ generator.version = version
+ assert_equal("", generator.to_s)
+
+ generator = target_class.new
+ generator.uri = uri
+ generator.version = version
+ assert_equal("", generator.to_s)
+
+ generator = target_class.new
+ generator.content = content
+ xml = REXML::Document.new(generator.to_s).root
+ assert_rexml_element([], {}, content, xml)
+
+ generator = target_class.new
+ generator.content = content
+ generator.uri = uri
+ xml = REXML::Document.new(generator.to_s).root
+ assert_rexml_element([], {"uri" => uri}, content, xml)
+
+ generator = target_class.new
+ generator.content = content
+ generator.version = version
+ xml = REXML::Document.new(generator.to_s).root
+ assert_rexml_element([], {"version" => version}, content, xml)
+
+ generator = target_class.new
+ generator.content = content
+ generator.uri = uri
+ generator.version = version
+ xml = REXML::Document.new(generator.to_s).root
+ assert_rexml_element([], {"uri" => uri, "version" => version},
+ content, xml)
+ end
+ end
+
+ def assert_atom_icon_to_s(target_class)
+ _wrap_assertion do
+ content = "http://example.com/icon.png"
+
+ icon = target_class.new
+ assert_equal("", icon.to_s)
+
+ icon = target_class.new
+ icon.content = content
+ xml = REXML::Document.new(icon.to_s).root
+ assert_rexml_element([], {}, content, xml)
+ end
+ end
+
+ def assert_atom_id_to_s(target_class)
+ _wrap_assertion do
+ content = "http://example.com/1"
+
+ id = target_class.new
+ assert_equal("", id.to_s)
+
+ id = target_class.new
+ id.content = content
+ xml = REXML::Document.new(id.to_s).root
+ assert_rexml_element([], {}, content, xml)
+ end
+ end
+
+ def assert_atom_link_to_s(target_class)
+ _wrap_assertion do
+ href = "http://example.com/atom.xml"
+ rel = "self"
+ type = "application/atom+xml"
+ hreflang = "ja"
+ title = "Atom Feed"
+ length = "801"
+
+ link = target_class.new
+ assert_equal("", link.to_s)
+
+ link = target_class.new
+ link.href = href
+ xml = REXML::Document.new(link.to_s).root
+ assert_rexml_element([], {"href" => href}, nil, xml)
+
+ optional_arguments = %w(rel type hreflang title length)
+ optional_arguments.each do |name|
+ rest = optional_arguments.reject {|x| x == name}
+
+ link = target_class.new
+ link.__send__("#{name}=", eval(name))
+ assert_equal("", link.to_s)
+
+ rest.each do |n|
+ link.__send__("#{n}=", eval(n))
+ assert_equal("", link.to_s)
+ end
+
+ link = target_class.new
+ link.href = href
+ link.__send__("#{name}=", eval(name))
+ attrs = [["href", href], [name, eval(name)]]
+ xml = REXML::Document.new(link.to_s).root
+ assert_rexml_element([], attrs, nil, xml)
+
+ rest.each do |n|
+ link.__send__("#{n}=", eval(n))
+ attrs << [n, eval(n)]
+ xml = REXML::Document.new(link.to_s).root
+ assert_rexml_element([], attrs, nil, xml)
+ end
+ end
+ end
+ end
+
+ def assert_atom_logo_to_s(target_class)
+ _wrap_assertion do
+ content = "http://example.com/logo.png"
+
+ logo = target_class.new
+ assert_equal("", logo.to_s)
+
+ logo = target_class.new
+ logo.content = content
+ xml = REXML::Document.new(logo.to_s).root
+ assert_rexml_element([], {}, content, xml)
+ end
+ end
+
+ def assert_atom_text_construct_to_s(target_class)
+ _wrap_assertion do
+ text_content = "plain text"
+ html_content = "<em>#{text_content}</em>"
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
+ xhtml_em = RSS::XML::Element.new("em", nil, xhtml_uri, {}, text_content)
+ xhtml_content = RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri},
+ [xhtml_em])
+
+ text = target_class.new
+ assert_equal("", text.to_s)
+
+ text = target_class.new
+ text.type = "text"
+ assert_equal("", text.to_s)
+
+ text = target_class.new
+ text.content = text_content
+ xml = REXML::Document.new(text.to_s).root
+ assert_rexml_element([], {}, text_content, xml)
+
+ text = target_class.new
+ text.type = "text"
+ text.content = text_content
+ xml = REXML::Document.new(text.to_s).root
+ assert_rexml_element([], {"type" => "text"}, text_content, xml)
+
+ text = target_class.new
+ text.type = "html"
+ text.content = html_content
+ xml = REXML::Document.new(text.to_s).root
+ assert_rexml_element([], {"type" => "html"}, html_content, xml)
+
+ text = target_class.new
+ text.type = "xhtml"
+ text.content = xhtml_content
+ assert_equal("", text.to_s)
+
+ text = target_class.new
+ text.type = "xhtml"
+ text.__send__(target_class.xml_setter, xhtml_content)
+ xml = REXML::Document.new(text.to_s).root
+ assert_rexml_element([[xhtml_uri, "div"]], {"type" => "xhtml"},
+ nil, xml)
+ assert_rexml_element([[xhtml_uri, "em"]], nil, nil, xml.elements[1])
+ assert_rexml_element([], {}, text_content, xml.elements[1].elements[1])
+
+ text = target_class.new
+ text.type = "xhtml"
+ text.__send__(target_class.xml_setter, xhtml_em)
+ xml = REXML::Document.new(text.to_s).root
+ assert_rexml_element([[xhtml_uri, "div"]], {"type" => "xhtml"},
+ nil, xml)
+ assert_rexml_element([[xhtml_uri, "em"]], nil, nil, xml.elements[1])
+ assert_rexml_element([], {}, text_content, xml.elements[1].elements[1])
+ end
+ end
+
+ def assert_atom_date_construct_to_s(target_class)
+ _wrap_assertion do
+ date = target_class.new
+ assert_equal("", date.to_s)
+
+ [
+ "2003-12-13T18:30:02Z",
+ "2003-12-13T18:30:02.25Z",
+ "2003-12-13T18:30:02+01:00",
+ "2003-12-13T18:30:02.25+01:00",
+ ].each do |content|
+ date = target_class.new
+ date.content = content
+ xml = REXML::Document.new(date.to_s).root
+ assert_rexml_element([], {}, content, xml, :time)
+
+ date = target_class.new
+ date.content = Time.parse(content)
+ xml = REXML::Document.new(date.to_s).root
+ assert_rexml_element([], {}, content, xml, :time)
+ end
+ end
+ end
+
+ def assert_atom_content_to_s(target_class)
+ _wrap_assertion do
+ assert_atom_text_construct_to_s(target_class)
+ assert_atom_content_inline_other_xml_to_s(target_class)
+ assert_atom_content_inline_other_text_to_s(target_class)
+ assert_atom_content_inline_other_base64_to_s(target_class)
+ assert_atom_content_out_of_line_to_s(target_class)
+ end
+ end
+
+ def assert_atom_content_inline_other_xml_to_s(target_class)
+ _wrap_assertion do
+ content = target_class.new
+ content.type = "text/xml"
+ assert_equal("", content.to_s)
+
+ content = target_class.new
+ content.type = "text/xml"
+ content.xml = RSS::XML::Element.new("em")
+ xml = REXML::Document.new(content.to_s).root
+ assert_rexml_element([["", "em"]], {"type" => "text/xml"}, nil, xml)
+ end
+ end
+
+ def assert_atom_content_inline_other_text_to_s(target_class)
+ _wrap_assertion do
+ content = target_class.new
+ content.type = "text/plain"
+ assert_equal("", content.to_s)
+
+ content = target_class.new
+ content.type = "text/plain"
+ content.xml = RSS::XML::Element.new("em")
+ assert_equal("", content.to_s)
+
+ content = target_class.new
+ content.type = "text/plain"
+ content.content = "content"
+ xml = REXML::Document.new(content.to_s).root
+ assert_rexml_element([], {"type" => "text/plain"}, "content", xml)
+ end
+ end
+
+ def assert_atom_content_inline_other_base64_to_s(target_class)
+ _wrap_assertion do
+ type = "image/png"
+ png_file = File.join(File.dirname(__FILE__), "dot.png")
+ original_content = File.open(png_file, "rb") do |file|
+ file.read.force_encoding("binary")
+ end
+
+ content = target_class.new
+ content.type = type
+ content.content = original_content
+ xml = REXML::Document.new(content.to_s).root
+ assert_rexml_element([], {"type" => type},
+ [original_content].pack("m").delete("\n"),
+ xml)
+ end
+ end
+
+ def assert_atom_content_out_of_line_to_s(target_class)
+ _wrap_assertion do
+ type = "application/zip"
+ src = "http://example.com/xxx.zip"
+
+ content = target_class.new
+ assert(!content.out_of_line?)
+ content.src = src
+ assert(content.out_of_line?)
+ xml = REXML::Document.new(content.to_s).root
+ assert_rexml_element([], {"src" => src}, nil, xml)
+
+ content = target_class.new
+ assert(!content.out_of_line?)
+ content.type = type
+ assert(!content.out_of_line?)
+ content.src = src
+ assert(content.out_of_line?)
+ xml = REXML::Document.new(content.to_s).root
+ assert_rexml_element([], {"type" => type, "src" => src}, nil, xml)
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_content.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_content.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_content.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,104 @@
+require "cgi"
+require "rexml/document"
+
+require "rss-testcase"
+
+require "rss/content"
+
+module RSS
+ class TestContent < TestCase
+ def setup
+ @prefix = "content"
+ @uri = "http://purl.org/rss/1.0/modules/content/"
+
+ @elems = {
+ :encoded => "<em>ATTENTION</em>",
+ }
+
+ @content_nodes = @elems.collect do |name, value|
+ "<#{@prefix}:#{name}>#{CGI.escapeHTML(value.to_s)}</#{@prefix}:#{name}>"
+ end.join("\n")
+
+ @rss10_source = make_RDF(<<-EOR, {@prefix => @uri})
+#{make_channel()}
+#{make_image()}
+#{make_item(@content_nodes)}
+#{make_textinput()}
+EOR
+
+ @rss10 = Parser.parse(@rss10_source)
+
+
+ @rss20_source = make_rss20(<<-EOR, {@prefix => @uri})
+#{make_channel20(make_item20(@content_nodes))}
+EOR
+
+ @rss20 = Parser.parse(@rss20_source)
+ end
+
+ def test_parser
+ assert_nothing_raised do
+ Parser.parse(@rss10_source)
+ end
+
+ assert_nothing_raised do
+ Parser.parse(@rss20_source)
+ end
+
+ @elems.each do |tag, value|
+ tag_name = "#{@prefix}:#{tag}"
+ content_encodes = make_element(tag_name, {}, value) * 2
+
+ assert_too_much_tag(tag.to_s, "item") do
+ Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))
+#{make_channel}
+#{make_item(content_encodes)}
+EOR
+ end
+
+ assert_too_much_tag(tag.to_s, "item") do
+ Parser.parse(make_rss20(<<-EOR, {@prefix => @uri}))
+#{make_channel20(make_item20(content_encodes))}
+EOR
+ end
+ end
+ end
+
+ def test_accessor
+ new_value = {
+ :encoded => "<![CDATA[<it>hoge</it>]]>",
+ }
+
+ @elems.each do |name, value|
+ [@rss10, @rss20].each do |rss|
+ meth = "#{RSS::CONTENT_PREFIX}_#{name}"
+ parent = rss.items.last
+ assert_equal(value, parent.__send__(meth))
+ parent.__send__("#{meth}=", new_value[name].to_s)
+ assert_equal(new_value[name], parent.__send__(meth))
+ end
+ end
+ end
+
+ def test_to_s
+ @elems.each do |name, value|
+ excepted = make_element("#{@prefix}:#{name}", {}, value)
+ meth = "#{RSS::CONTENT_PREFIX}_#{name}_element"
+ [@rss10, @rss20].each do |rss|
+ assert_equal(excepted, rss.items.last.__send__(meth))
+ end
+ end
+
+ [@rss10_source, @rss20_source].each do |source|
+ REXML::Document.new(source).root.each_element do |parent|
+ next unless parent.name != "item"
+ parent.each_element do |elem|
+ if elem.namespace == @uri
+ assert_equal(elem.text, @elems[elem.name.intern].to_s)
+ end
+ end
+ end
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_dublincore.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_dublincore.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_dublincore.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,279 @@
+require "cgi"
+require "rexml/document"
+
+require "rss-testcase"
+
+require "rss/1.0"
+require "rss/dublincore"
+
+module RSS
+ class TestDublinCore < TestCase
+ def setup
+ @rss10_parents = [%w(channel), %w(image), %w(item), %w(textinput)]
+
+ @rss10_source = make_RDF(<<-EOR, {DC_PREFIX => DC_URI})
+#{make_channel(DC_NODES)}
+#{make_image(DC_NODES)}
+#{make_item(DC_NODES)}
+#{make_textinput(DC_NODES)}
+EOR
+
+ @rss20_parents = [%w(channel), %w(items last)]
+
+ @rss20_source = make_rss20(<<-EOR, {DC_PREFIX => DC_URI})
+#{make_channel20(DC_NODES + make_item20(DC_NODES))}
+EOR
+
+ @atom_feed_parents = [[], %w(entries last)]
+
+ @atom_feed_source = make_feed(<<-EOR, {DC_PREFIX => DC_URI})
+#{DC_NODES}
+#{make_entry(DC_NODES)}
+EOR
+
+ @atom_entry_parents = [[]]
+
+ @atom_entry_source = make_entry_document(<<-EOR, {DC_PREFIX => DC_URI})
+#{DC_NODES}
+EOR
+ end
+
+ def test_parser
+ rss10_maker = Proc.new do |content, xmlns|
+ make_RDF(<<-EOR, xmlns)
+#{make_channel(content)}
+#{make_image(content)}
+#{make_item(content)}
+#{make_textinput(content)}
+EOR
+ end
+ assert_dc_parse(@rss10_source, @rss10_parents, false, &rss10_maker)
+ assert_dc_parse(@rss10_source, @rss10_parents, true, &rss10_maker)
+
+ rss20_maker = Proc.new do |content, xmlns|
+ make_rss20(<<-EOR, xmlns)
+#{make_channel20(content + make_item20(content))}
+EOR
+ end
+ assert_dc_parse(@rss20_source, @rss20_parents, false, &rss20_maker)
+ assert_dc_parse(@rss20_source, @rss20_parents, true, &rss20_maker)
+
+ atom_feed_maker = Proc.new do |content, xmlns|
+ make_feed(<<-EOR, xmlns)
+#{content}
+#{make_entry(content)}
+EOR
+ end
+ assert_dc_parse(@atom_feed_source, @atom_feed_parents, false,
+ &atom_feed_maker)
+ assert_dc_parse(@atom_feed_source, @atom_feed_parents, true,
+ &atom_feed_maker)
+
+ atom_entry_maker = Proc.new do |content, xmlns|
+ make_entry_document(<<-EOR, xmlns)
+#{content}
+EOR
+ end
+ assert_dc_parse(@atom_entry_source, @atom_entry_parents, false,
+ &atom_entry_maker)
+ assert_dc_parse(@atom_entry_source, @atom_entry_parents, true,
+ &atom_entry_maker)
+ end
+
+ def test_singular_accessor
+ assert_dc_singular_accessor(@rss10_source, @rss10_parents)
+ assert_dc_singular_accessor(@rss20_source, @rss20_parents)
+ assert_dc_singular_accessor(@atom_feed_source, @atom_feed_parents)
+ assert_dc_singular_accessor(@atom_entry_source, @atom_entry_parents)
+ end
+
+ def test_plural_accessor
+ assert_dc_plural_accessor(@rss10_source, @rss10_parents, false)
+ assert_dc_plural_accessor(@rss10_source, @rss10_parents, true)
+
+ assert_dc_plural_accessor(@rss20_source, @rss20_parents, false)
+ assert_dc_plural_accessor(@rss20_source, @rss20_parents, true)
+
+ assert_dc_plural_accessor(@atom_feed_source, @atom_feed_parents, false)
+ assert_dc_plural_accessor(@atom_feed_source, @atom_feed_parents, true)
+
+ assert_dc_plural_accessor(@atom_entry_source, @atom_entry_parents, false)
+ assert_dc_plural_accessor(@atom_entry_source, @atom_entry_parents, true)
+ end
+
+ def test_to_s
+ assert_dc_to_s(@rss10_source, @rss10_parents, false)
+ assert_dc_to_s(@rss10_source, @rss10_parents, true)
+
+ targets = ["channel", "channel/item[3]"]
+ assert_dc_to_s(@rss20_source, @rss20_parents, false, targets)
+ assert_dc_to_s(@rss20_source, @rss20_parents, true, targets)
+
+ targets = [".", "entry"]
+ assert_dc_to_s(@atom_feed_source, @atom_feed_parents, false, targets)
+ assert_dc_to_s(@atom_feed_source, @atom_feed_parents, true, targets)
+
+ targets = ["."]
+ assert_dc_to_s(@atom_entry_source, @atom_entry_parents, false, targets)
+ assert_dc_to_s(@atom_entry_source, @atom_entry_parents, true, targets)
+ end
+
+ private
+ def dc_plural_suffix(name, check_backward_compatibility)
+ if name == :rights
+ if check_backward_compatibility
+ "es"
+ else
+ "_list"
+ end
+ else
+ "s"
+ end
+ end
+
+ def assert_dc_parse(source, parents, check_backward_compatibility, &maker)
+ assert_nothing_raised do
+ Parser.parse(source)
+ end
+
+ DC_ELEMENTS.each do |name, value|
+ parents.each do |parent_readers|
+ feed = nil
+ assert_nothing_raised do
+ tag = "#{DC_PREFIX}:#{name}"
+ dc_content = "<#{tag}>#{value}</#{tag}>\n"
+ dc_content *= 2
+ feed = Parser.parse(maker.call(dc_content, {DC_PREFIX => DC_URI}))
+ end
+ parent = chain_reader(feed, parent_readers)
+
+ plural_suffix = dc_plural_suffix(name, check_backward_compatibility)
+ plural_reader = "dc_#{name}#{plural_suffix}"
+ values = parent.__send__(plural_reader).collect do |x|
+ val = x.value
+ if val.kind_of?(String)
+ CGI.escapeHTML(val)
+ else
+ val
+ end
+ end
+ assert_equal([value, value], values)
+ end
+ end
+ end
+
+ def assert_dc_singular_accessor(source, parents)
+ feed = Parser.parse(source)
+ new_value = "hoge"
+
+ parents.each do |parent_readers|
+ parent = chain_reader(feed, parent_readers)
+ DC_ELEMENTS.each do |name, value|
+ parsed_value = parent.__send__("dc_#{name}")
+ if parsed_value.kind_of?(String)
+ parsed_value = CGI.escapeHTML(parsed_value)
+ end
+ assert_equal(value, parsed_value)
+ if name == :date
+ t = Time.iso8601("2003-01-01T02:30:23+09:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+ parent.__send__("dc_#{name}=", t.iso8601)
+ assert_equal(t, parent.__send__("dc_#{name}"))
+ if parent.class.method_defined?(:date_without_dc_date=)
+ assert_nil(parent.date)
+ else
+ assert_equal(t, parent.date)
+ end
+
+ parent.date = value
+ assert_equal(value, parent.date)
+ assert_equal(value, parent.__send__("dc_#{name}"))
+ else
+ parent.__send__("dc_#{name}=", new_value)
+ assert_equal(new_value, parent.__send__("dc_#{name}"))
+ end
+ end
+ end
+ end
+
+ def assert_dc_plural_accessor(source, parents, check_backward_compatibility)
+ feed = Parser.parse(source)
+ new_value = "hoge"
+
+ DC_ELEMENTS.each do |name, value|
+ parents.each do |parent_readers|
+ parent = chain_reader(feed, parent_readers)
+ parsed_value = parent.__send__("dc_#{name}")
+ if parsed_value.kind_of?(String)
+ parsed_value = CGI.escapeHTML(parsed_value)
+ end
+ assert_equal(value, parsed_value)
+
+ plural_suffix = dc_plural_suffix(name, check_backward_compatibility)
+ plural_reader = "dc_#{name}#{plural_suffix}"
+ klass_name = "DublinCore#{Utils.to_class_name(name.to_s)}"
+ klass = DublinCoreModel.const_get(klass_name)
+ if name == :date
+ t = Time.iso8601("2003-01-01T02:30:23+09:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+ elems = parent.__send__(plural_reader)
+ elems << klass.new(t.iso8601)
+ new_elems = parent.__send__(plural_reader)
+ values = new_elems.collect{|x| x.value}
+ assert_equal([parent.__send__("dc_#{name}"), t], values)
+ else
+ elems = parent.__send__(plural_reader)
+ elems << klass.new(new_value)
+ new_elems = parent.__send__(plural_reader)
+ values = new_elems.collect{|x| x.value}
+ assert_equal([parent.__send__("dc_#{name}"), new_value],
+ values)
+ end
+ end
+ end
+ end
+
+ def assert_dc_to_s(source, parents, check_backward_compatibility,
+ targets=nil)
+ feed = Parser.parse(source)
+
+ DC_ELEMENTS.each do |name, value|
+ excepted = "<#{DC_PREFIX}:#{name}>#{value}</#{DC_PREFIX}:#{name}>"
+ parents.each do |parent_readers|
+ parent = chain_reader(feed, parent_readers)
+ assert_equal(excepted, parent.__send__("dc_#{name}_elements"))
+ end
+
+ plural_suffix = dc_plural_suffix(name, check_backward_compatibility)
+ reader = "dc_#{name}#{plural_suffix}"
+ excepted = Array.new(2, excepted).join("\n")
+ parents.each do |parent_readers|
+ parent = chain_reader(feed, parent_readers)
+ elems = parent.__send__(reader)
+ klass_name = "DublinCore#{Utils.to_class_name(name.to_s)}"
+ klass = DublinCoreModel.const_get(klass_name)
+ elems << klass.new(parent.__send__("dc_#{name}"))
+ assert_equal(excepted, parent.__send__("dc_#{name}_elements"))
+ end
+ end
+
+ targets ||= parents.collect do |parent_readers|
+ parent_readers.first
+ end
+ feed_root = REXML::Document.new(source).root
+ targets.each do |target_xpath|
+ parent = feed_root.elements[target_xpath]
+ parent.each_element do |elem|
+ if elem.namespace == DC_URI
+ assert_equal(CGI.escapeHTML(elem.text),
+ DC_ELEMENTS[elem.name.intern].to_s)
+ end
+ end
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_image.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_image.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_image.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,214 @@
+require "cgi"
+require "rexml/document"
+
+require "rss-testcase"
+
+require "rss/1.0"
+require "rss/image"
+
+module RSS
+ class TestImage < TestCase
+
+ def setup
+ @prefix = "image"
+ @uri = "http://purl.org/rss/1.0/modules/image/"
+
+ @favicon_attrs = {
+ "rdf:about" => "http://www.kuro5hin.org/favicon.ico",
+ "#{@prefix}:size" => "small",
+ }
+ @favicon_contents = {"dc:title" => "Kuro5hin",}
+ @items = [
+ [
+ {
+ "rdf:about" => "http://www.example.org/item.png",
+ "rdf:resource" => "http://www.example.org/item",
+ },
+ {
+ "dc:title" => "Example Image",
+ "#{@prefix}:width" => "100",
+ "#{@prefix}:height" => "65",
+ },
+ ],
+ [
+ {
+ "rdf:about" => "http://www.kuro5hin.org/images/topics/culture.jpg",
+ },
+ {
+ "dc:title" => "Culture",
+ "#{@prefix}:width" => "80",
+ "#{@prefix}:height" => "50",
+ },
+ ]
+ ]
+
+
+ @channel_nodes = make_element("#{@prefix}:favicon",
+ @favicon_attrs,
+ @favicon_contents)
+ items = ""
+ @items.each do |attrs, contents|
+ image_item = make_element("#{@prefix}:item", attrs, contents)
+ items << make_item(image_item)
+ end
+
+ @ns = {
+ @prefix => @uri,
+ DC_PREFIX => DC_URI,
+ }
+ @rss_source = make_RDF(<<-EOR, @ns)
+#{make_channel(@channel_nodes)}
+#{make_image}
+#{items}
+#{make_textinput}
+EOR
+
+ @rss = Parser.parse(@rss_source)
+ end
+
+ def test_parser
+ assert_nothing_raised do
+ Parser.parse(@rss_source)
+ end
+
+ assert_too_much_tag("favicon", "channel") do
+ Parser.parse(make_RDF(<<-EOR, @ns))
+#{make_channel(@channel_nodes * 2)}
+#{make_item}
+EOR
+ end
+
+ attrs = {"rdf:about" => "http://www.example.org/item.png"}
+ contents = [["#{@prefix}:width", "80"]] * 5
+ image_item = make_element("#{@prefix}:item", attrs, contents)
+ assert_too_much_tag("width", "item") do
+ Parser.parse(make_RDF(<<-EOR, @ns))
+#{make_channel}
+#{make_item(image_item)}
+EOR
+ end
+ end
+
+ def test_favicon_accessor
+ favicon = @rss.channel.image_favicon
+ [
+ %w(about rdf:about http://example.com/favicon.ico),
+ %w(size image:size large),
+ %w(image_size image:size medium),
+ ].each do |name, full_name, new_value|
+ assert_equal(@favicon_attrs[full_name], favicon.__send__(name))
+ favicon.__send__("#{name}=", new_value)
+ assert_equal(new_value, favicon.__send__(name))
+ favicon.__send__("#{name}=", @favicon_attrs[full_name])
+ assert_equal(@favicon_attrs[full_name], favicon.__send__(name))
+ end
+
+ %w(small medium large).each do |value|
+ assert_nothing_raised do
+ favicon.size = value
+ favicon.image_size = value
+ end
+ end
+
+ %w(aaa AAA SMALL MEDIUM LARGE).each do |value|
+ args = ["#{@prefix}:favicon", value, "#{@prefix}:size"]
+ assert_not_available_value(*args) do
+ favicon.size = value
+ end
+ assert_not_available_value(*args) do
+ favicon.image_size = value
+ end
+ end
+
+ [
+ %w(dc_title dc:title sample-favicon),
+ ].each do |name, full_name, new_value|
+ assert_equal(@favicon_contents[full_name], favicon.__send__(name))
+ favicon.__send__("#{name}=", new_value)
+ assert_equal(new_value, favicon.__send__(name))
+ favicon.__send__("#{name}=", @favicon_contents[full_name])
+ assert_equal(@favicon_contents[full_name], favicon.__send__(name))
+ end
+ end
+
+ def test_item_accessor
+ @rss.items.each_with_index do |item, i|
+ image_item = item.image_item
+ attrs, contents = @items[i]
+ [
+ %w(about rdf:about http://example.com/image.png),
+ %w(resource rdf:resource http://example.com/),
+ ].each do |name, full_name, new_value|
+ assert_equal(attrs[full_name], image_item.__send__(name))
+ image_item.__send__("#{name}=", new_value)
+ assert_equal(new_value, image_item.__send__(name))
+ image_item.__send__("#{name}=", attrs[full_name])
+ assert_equal(attrs[full_name], image_item.__send__(name))
+ end
+
+ [
+ ["width", "image:width", "111"],
+ ["image_width", "image:width", "44"],
+ ["height", "image:height", "222"],
+ ["image_height", "image:height", "88"],
+ ].each do |name, full_name, new_value|
+ assert_equal(contents[full_name].to_i, image_item.__send__(name))
+ image_item.__send__("#{name}=", new_value)
+ assert_equal(new_value.to_i, image_item.__send__(name))
+ image_item.__send__("#{name}=", contents[full_name])
+ assert_equal(contents[full_name].to_i, image_item.__send__(name))
+ end
+
+ [
+ ["dc_title", "dc:title", "sample-image"],
+ ].each do |name, full_name, new_value|
+ assert_equal(contents[full_name], image_item.__send__(name))
+ image_item.__send__("#{name}=", new_value)
+ assert_equal(new_value, image_item.__send__(name))
+ image_item.__send__("#{name}=", contents[full_name])
+ assert_equal(contents[full_name], image_item.__send__(name))
+ end
+ end
+ end
+
+ def test_favicon_to_s
+ favicon = @rss.channel.image_favicon
+ expected_xml = image_xmlns_container(make_element("#{@prefix}:favicon",
+ @favicon_attrs,
+ @favicon_contents))
+ expected = REXML::Document.new(expected_xml)
+ actual_xml = image_xmlns_container(favicon.to_s(false, ""))
+ actual = REXML::Document.new(actual_xml)
+ assert_equal(expected.to_s, actual.to_s)
+ end
+
+ def test_item_to_s
+ @rss.items.each_with_index do |item, i|
+ attrs, contents = @items[i]
+ expected_xml = make_element("#{@prefix}:item", attrs, contents)
+ expected_xml = image_xmlns_container(expected_xml)
+ expected = REXML::Document.new(expected_xml)
+ actual_xml = image_xmlns_container(item.image_item.to_s(false, ""))
+ actual = REXML::Document.new(actual_xml)
+
+ assert_equal(expected[0].attributes, actual[0].attributes)
+
+ %w(image:height image:width dc:title).each do |name|
+ actual_target = actual.elements["//#{name}"]
+ expected_target = expected.elements["//#{name}"]
+ assert_equal(expected_target.to_s, actual_target.to_s)
+ end
+ end
+ end
+
+ private
+ def image_xmlns_container(content)
+ xmlns_container({
+ @prefix => @uri,
+ "dc" => "http://purl.org/dc/elements/1.1/",
+ "rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
+ },
+ content)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_inherit.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_inherit.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_inherit.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,40 @@
+require "rss-testcase"
+
+require "rss/1.0"
+
+module RSS
+ class TestInherit < TestCase
+
+ class InheritedImage < RSS::RDF::Image
+ def self.indent_size; 1; end
+ def self.tag_name; 'image'; end
+ end
+
+ def setup
+ @rss = make_RDF(<<-EOR)
+#{make_channel}
+#{make_image}
+#{make_item}
+#{make_textinput}
+EOR
+ end
+
+ def test_inherit
+ rss = RSS::Parser.parse(@rss)
+ orig_image = rss.image
+ prefix = "[INHERIT]"
+ image = InheritedImage.new("#{prefix} #{orig_image.about}")
+ image.title = "#{prefix} #{orig_image.title}"
+ image.url = "#{prefix} #{orig_image.url}"
+ image.link = "#{prefix} #{orig_image.link}"
+ rss.image = image
+
+ new_rss = RSS::Parser.parse(rss.to_s)
+ new_image = new_rss.image
+ assert_equal("#{prefix} #{orig_image.about}", new_image.about)
+ assert_equal("#{prefix} #{orig_image.title}", new_image.title)
+ assert_equal("#{prefix} #{orig_image.url}", new_image.url)
+ assert_equal("#{prefix} #{orig_image.link}", new_image.link)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_itunes.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_itunes.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_itunes.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,347 @@
+require "cgi"
+require "rexml/document"
+
+require "rss-testcase"
+
+require "rss/2.0"
+require "rss/itunes"
+
+module RSS
+ class TestITunes < TestCase
+ def test_author
+ assert_itunes_author(%w(channel)) do |content, xmlns|
+ make_rss20(make_channel20(content), xmlns)
+ end
+
+ assert_itunes_author(%w(items last)) do |content, xmlns|
+ make_rss20(make_channel20(make_item20(content)), xmlns)
+ end
+ end
+
+ def test_block
+ assert_itunes_block(%w(items last)) do |content, xmlns|
+ make_rss20(make_channel20(make_item20(content)), xmlns)
+ end
+ end
+
+ def test_category
+ assert_itunes_category(%w(channel)) do |content, xmlns|
+ make_rss20(make_channel20(content), xmlns)
+ end
+ end
+
+ def test_image
+ assert_itunes_image(%w(channel)) do |content, xmlns|
+ make_rss20(make_channel20(content), xmlns)
+ end
+ end
+
+ def test_duration
+ assert_itunes_duration(%w(items last)) do |content, xmlns|
+ make_rss20(make_channel20(make_item20(content)), xmlns)
+ end
+ end
+
+ def test_explicit
+ assert_itunes_explicit(%w(channel)) do |content, xmlns|
+ make_rss20(make_channel20(content), xmlns)
+ end
+
+ assert_itunes_explicit(%w(items last)) do |content, xmlns|
+ make_rss20(make_channel20(make_item20(content)), xmlns)
+ end
+ end
+
+ def test_keywords
+ assert_itunes_keywords(%w(channel)) do |content, xmlns|
+ make_rss20(make_channel20(content), xmlns)
+ end
+
+ assert_itunes_keywords(%w(items last)) do |content, xmlns|
+ make_rss20(make_channel20(make_item20(content)), xmlns)
+ end
+ end
+
+ def test_new_feed_url
+ assert_itunes_new_feed_url(%w(channel)) do |content, xmlns|
+ make_rss20(make_channel20(content), xmlns)
+ end
+ end
+
+ def test_owner
+ assert_itunes_owner(%w(channel)) do |content, xmlns|
+ make_rss20(make_channel20(content), xmlns)
+ end
+ end
+
+ def test_subtitle
+ assert_itunes_subtitle(%w(channel)) do |content, xmlns|
+ make_rss20(make_channel20(content), xmlns)
+ end
+
+ assert_itunes_subtitle(%w(items last)) do |content, xmlns|
+ make_rss20(make_channel20(make_item20(content)), xmlns)
+ end
+ end
+
+ def test_summary
+ assert_itunes_summary(%w(channel)) do |content, xmlns|
+ make_rss20(make_channel20(content), xmlns)
+ end
+
+ assert_itunes_summary(%w(items last)) do |content, xmlns|
+ make_rss20(make_channel20(make_item20(content)), xmlns)
+ end
+ end
+
+ private
+ def itunes_rss20_parse(content, &maker)
+ xmlns = {"itunes" => "http://www.itunes.com/dtds/podcast-1.0.dtd"}
+ rss20_xml = maker.call(content, xmlns)
+ ::RSS::Parser.parse(rss20_xml)
+ end
+
+ def assert_itunes_author(readers, &rss20_maker)
+ _wrap_assertion do
+ author = "John Lennon"
+ rss20 = itunes_rss20_parse(tag("itunes:author", author), &rss20_maker)
+ target = chain_reader(rss20, readers)
+ assert_equal(author, target.itunes_author)
+ end
+ end
+
+ def _assert_itunes_block(value, boolean_value, readers, &rss20_maker)
+ rss20 = itunes_rss20_parse(tag("itunes:block", value), &rss20_maker)
+ target = chain_reader(rss20, readers)
+ assert_equal(value, target.itunes_block)
+ assert_equal(boolean_value, target.itunes_block?)
+ end
+
+ def assert_itunes_block(readers, &rss20_maker)
+ _wrap_assertion do
+ _assert_itunes_block("yes", true, readers, &rss20_maker)
+ _assert_itunes_block("Yes", true, readers, &rss20_maker)
+ _assert_itunes_block("no", false, readers, &rss20_maker)
+ _assert_itunes_block("", false, readers, &rss20_maker)
+ end
+ end
+
+ def _assert_itunes_category(categories, readers, &rss20_maker)
+ cats = categories.collect do |category|
+ if category.is_a?(Array)
+ category, sub_category = category
+ tag("itunes:category",
+ tag("itunes:category", nil, {"text" => sub_category}),
+ {"text" => category})
+ else
+ tag("itunes:category", nil, {"text" => category})
+ end
+ end.join
+ rss20 = itunes_rss20_parse(cats, &rss20_maker)
+ target = chain_reader(rss20, readers)
+ actual_categories = target.itunes_categories.collect do |category|
+ cat = category.text
+ if category.itunes_categories.empty?
+ cat
+ else
+ [cat, *category.itunes_categories.collect {|c| c.text}]
+ end
+ end
+ assert_equal(categories, actual_categories)
+ end
+
+ def assert_itunes_category(readers, &rss20_maker)
+ _wrap_assertion do
+ _assert_itunes_category(["Audio Blogs"], readers, &rss20_maker)
+ _assert_itunes_category([["Arts & Entertainment", "Games"]],
+ readers, &rss20_maker)
+ _assert_itunes_category([["Arts & Entertainment", "Games"],
+ ["Technology", "Computers"],
+ "Audio Blogs"],
+ readers, &rss20_maker)
+ end
+ end
+
+ def assert_itunes_image(readers, &rss20_maker)
+ _wrap_assertion do
+ url = "http://example.com/podcasts/everything/AllAboutEverything.jpg"
+ content = tag("itunes:image", nil, {"href" => url})
+ rss20 = itunes_rss20_parse(content, &rss20_maker)
+ target = chain_reader(rss20, readers)
+ assert_not_nil(target.itunes_image)
+ assert_equal(url, target.itunes_image.href)
+
+ assert_missing_attribute("image", "href") do
+ content = tag("itunes:image")
+ itunes_rss20_parse(content, &rss20_maker)
+ end
+ end
+ end
+
+ def _assert_itunes_duration(hour, minute, second, value,
+ readers, &rss20_maker)
+ content = tag("itunes:duration", value)
+ rss20 = itunes_rss20_parse(content, &rss20_maker)
+ duration = chain_reader(rss20, readers).itunes_duration
+ assert_equal(value, duration.content)
+ assert_equal(hour, duration.hour)
+ assert_equal(minute, duration.minute)
+ assert_equal(second, duration.second)
+ end
+
+ def _assert_itunes_duration_not_available_value(value, &rss20_maker)
+ assert_not_available_value("duration", value) do
+ content = tag("itunes:duration", value)
+ itunes_rss20_parse(content, &rss20_maker)
+ end
+ end
+
+ def assert_itunes_duration(readers, &rss20_maker)
+ _wrap_assertion do
+ _assert_itunes_duration(7, 14, 5, "07:14:05", readers, &rss20_maker)
+ _assert_itunes_duration(7, 14, 5, "7:14:05", readers, &rss20_maker)
+ _assert_itunes_duration(0, 4, 55, "04:55", readers, &rss20_maker)
+ _assert_itunes_duration(0, 4, 5, "4:05", readers, &rss20_maker)
+
+ _assert_itunes_duration_not_available_value("5", &rss20_maker)
+ _assert_itunes_duration_not_available_value("09:07:14:05", &rss20_maker)
+ _assert_itunes_duration_not_available_value("10:5", &rss20_maker)
+ _assert_itunes_duration_not_available_value("10:03:5", &rss20_maker)
+ _assert_itunes_duration_not_available_value("10:3:05", &rss20_maker)
+
+ _assert_itunes_duration_not_available_value("xx:xx:xx", &rss20_maker)
+ end
+ end
+
+ def _assert_itunes_explicit(explicit, value, readers, &rss20_maker)
+ content = tag("itunes:explicit", value)
+ rss20 = itunes_rss20_parse(content, &rss20_maker)
+ target = chain_reader(rss20, readers)
+ assert_equal(value, target.itunes_explicit)
+ assert_equal(explicit, target.itunes_explicit?)
+ end
+
+ def assert_itunes_explicit(readers, &rss20_maker)
+ _wrap_assertion do
+ _assert_itunes_explicit(true, "yes", readers, &rss20_maker)
+ _assert_itunes_explicit(false, "clean", readers, &rss20_maker)
+ _assert_itunes_explicit(nil, "no", readers, &rss20_maker)
+ end
+ end
+
+ def _assert_itunes_keywords(keywords, value, readers, &rss20_maker)
+ content = tag("itunes:keywords", value)
+ rss20 = itunes_rss20_parse(content, &rss20_maker)
+ target = chain_reader(rss20, readers)
+ assert_equal(keywords, target.itunes_keywords)
+ end
+
+ def assert_itunes_keywords(readers, &rss20_maker)
+ _wrap_assertion do
+ _assert_itunes_keywords(["salt"], "salt", readers, &rss20_maker)
+ _assert_itunes_keywords(["salt"], " salt ", readers, &rss20_maker)
+ _assert_itunes_keywords(["salt", "pepper", "shaker", "exciting"],
+ "salt, pepper, shaker, exciting",
+ readers, &rss20_maker)
+ _assert_itunes_keywords(["metric", "socket", "wrenches", "toolsalt"],
+ "metric, socket, wrenches, toolsalt",
+ readers, &rss20_maker)
+ _assert_itunes_keywords(["olitics", "red", "blue", "state"],
+ "olitics, red, blue, state",
+ readers, &rss20_maker)
+ end
+ end
+
+ def assert_itunes_new_feed_url(readers, &rss20_maker)
+ _wrap_assertion do
+ url = "http://newlocation.com/example.rss"
+ content = tag("itunes:new-feed-url", url)
+ rss20 = itunes_rss20_parse(content, &rss20_maker)
+ target = chain_reader(rss20, readers)
+ assert_equal(url, target.itunes_new_feed_url)
+ end
+ end
+
+ def _assert_itunes_owner(name, email, readers, &rss20_maker)
+ content = tag("itunes:owner",
+ tag("itunes:name", name) + tag("itunes:email", email))
+ rss20 = itunes_rss20_parse(content, &rss20_maker)
+ owner = chain_reader(rss20, readers).itunes_owner
+ assert_equal(name, owner.itunes_name)
+ assert_equal(email, owner.itunes_email)
+ end
+
+ def assert_itunes_owner(readers, &rss20_maker)
+ _wrap_assertion do
+ _assert_itunes_owner("John Doe", "john.doe at example.com",
+ readers, &rss20_maker)
+
+ assert_missing_tag("name", "owner") do
+ content = tag("itunes:owner")
+ itunes_rss20_parse(content, &rss20_maker)
+ end
+
+ assert_missing_tag("name", "owner") do
+ content = tag("itunes:owner",
+ tag("itunes:email", "john.doe at example.com"))
+ itunes_rss20_parse(content, &rss20_maker)
+ end
+
+ assert_missing_tag("email", "owner") do
+ content = tag("itunes:owner", tag("itunes:name", "John Doe"))
+ itunes_rss20_parse(content, &rss20_maker)
+ end
+ end
+ end
+
+ def _assert_itunes_subtitle(value, readers, &rss20_maker)
+ content = tag("itunes:subtitle", value)
+ rss20 = itunes_rss20_parse(content, &rss20_maker)
+ target = chain_reader(rss20, readers)
+ assert_equal(value, target.itunes_subtitle)
+ end
+
+ def assert_itunes_subtitle(readers, &rss20_maker)
+ _wrap_assertion do
+ _assert_itunes_subtitle("A show about everything", readers, &rss20_maker)
+ _assert_itunes_subtitle("A short primer on table spices",
+ readers, &rss20_maker)
+ _assert_itunes_subtitle("Comparing socket wrenches is fun!",
+ readers, &rss20_maker)
+ _assert_itunes_subtitle("Red + Blue != Purple", readers, &rss20_maker)
+ end
+ end
+
+ def _assert_itunes_summary(value, readers, &rss20_maker)
+ content = tag("itunes:summary", value)
+ rss20 = itunes_rss20_parse(content, &rss20_maker)
+ target = chain_reader(rss20, readers)
+ assert_equal(value, target.itunes_summary)
+ end
+
+ def assert_itunes_summary(readers, &rss20_maker)
+ _wrap_assertion do
+ _assert_itunes_summary("All About Everything is a show about " +
+ "everything. Each week we dive into any " +
+ "subject known to man and talk about it as " +
+ "much as we can. Look for our Podcast in " +
+ "the iTunes Music Store",
+ readers, &rss20_maker)
+ _assert_itunes_summary("This week we talk about salt and pepper " +
+ "shakers, comparing and contrasting pour " +
+ "rates, construction materials, and overall " +
+ "aesthetics. Come and join the party!",
+ readers, &rss20_maker)
+ _assert_itunes_summary("This week we talk about metric vs. old " +
+ "english socket wrenches. Which one is " +
+ "better? Do you really need both? Get all " +
+ "of your answers here.",
+ readers, &rss20_maker)
+ _assert_itunes_summary("This week we talk about surviving in a " +
+ "Red state if you're a Blue person. Or " +
+ "vice versa.",
+ readers, &rss20_maker)
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_0.9.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_0.9.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_0.9.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,474 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMaker09 < TestCase
+ def test_supported?
+ assert(RSS::Maker.supported?("0.9"))
+ assert(RSS::Maker.supported?("rss0.9"))
+ assert(RSS::Maker.supported?("0.91"))
+ assert(RSS::Maker.supported?("rss0.91"))
+ assert(RSS::Maker.supported?("0.92"))
+ assert(RSS::Maker.supported?("rss0.92"))
+ assert(!RSS::Maker.supported?("0.93"))
+ assert(!RSS::Maker.supported?("rss0.93"))
+ end
+
+ def test_find_class
+ assert_equal(RSS::Maker::RSS091, RSS::Maker["0.91"])
+ assert_equal(RSS::Maker::RSS091, RSS::Maker["rss0.91"])
+ assert_equal(RSS::Maker::RSS092, RSS::Maker["0.9"])
+ assert_equal(RSS::Maker::RSS092, RSS::Maker["0.92"])
+ assert_equal(RSS::Maker::RSS092, RSS::Maker["rss0.92"])
+ end
+
+ def test_rss
+ assert_raise(LocalJumpError) do
+ RSS::Maker.make("0.91")
+ end
+
+ rss = RSS::Maker.make("0.9") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+ end
+ assert_equal("0.92", rss.rss_version)
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+ end
+ assert_equal("0.91", rss.rss_version)
+
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+
+ maker.encoding = "EUC-JP"
+ end
+ assert_equal("0.91", rss.rss_version)
+ assert_equal("EUC-JP", rss.encoding)
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+
+ maker.standalone = "yes"
+ end
+ assert_equal("0.91", rss.rss_version)
+ assert_equal("yes", rss.standalone)
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+
+ maker.encoding = "EUC-JP"
+ maker.standalone = "yes"
+ end
+ assert_equal("0.91", rss.rss_version)
+ assert_equal("EUC-JP", rss.encoding)
+ assert_equal("yes", rss.standalone)
+ end
+
+ def test_channel
+ title = "fugafuga"
+ link = "http://hoge.com"
+ description = "fugafugafugafuga"
+ language = "ja"
+ copyright = "foo"
+ managingEditor = "bar"
+ webMaster = "web master"
+ rating = '(PICS-1.1 "http://www.rsac.org/ratingsv01.html" l gen true comment "RSACi North America Server" for "http://www.rsac.org" on "1996.04.16T08:15-0500" r (n 0 s 0 v 0 l 0))'
+ docs = "http://foo.com/doc"
+ skipDays = [
+ "Sunday",
+ "Monday",
+ ]
+ skipHours = [
+ "0",
+ "13",
+ ]
+ pubDate = Time.now
+ lastBuildDate = Time.now
+
+ image_url = "http://example.com/logo.png"
+ image_title = "Logo"
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+ maker.channel.language = language
+ maker.channel.copyright = copyright
+ maker.channel.managingEditor = managingEditor
+ maker.channel.webMaster = webMaster
+ maker.channel.rating = rating
+ maker.channel.docs = docs
+ maker.channel.pubDate = pubDate
+ maker.channel.lastBuildDate = lastBuildDate
+
+ skipDays.each do |day|
+ maker.channel.skipDays.new_day do |new_day|
+ new_day.content = day
+ end
+ end
+ skipHours.each do |hour|
+ maker.channel.skipHours.new_hour do |new_hour|
+ new_hour.content = hour
+ end
+ end
+
+ maker.image.url = image_url
+ maker.image.title = image_title
+ end
+ channel = rss.channel
+
+ assert_equal(title, channel.title)
+ assert_equal(link, channel.link)
+ assert_equal(description, channel.description)
+ assert_equal(language, channel.language)
+ assert_equal(copyright, channel.copyright)
+ assert_equal(managingEditor, channel.managingEditor)
+ assert_equal(webMaster, channel.webMaster)
+ assert_equal(rating, channel.rating)
+ assert_equal(docs, channel.docs)
+ assert_equal(pubDate, channel.pubDate)
+ assert_equal(pubDate, channel.date)
+ assert_equal(lastBuildDate, channel.lastBuildDate)
+
+ skipDays.each_with_index do |day, i|
+ assert_equal(day, channel.skipDays.days[i].content)
+ end
+ skipHours.each_with_index do |hour, i|
+ assert_equal(hour.to_i, channel.skipHours.hours[i].content)
+ end
+
+ assert(channel.items.empty?)
+
+ assert_equal(image_url, channel.image.url)
+ assert_equal(image_title, channel.image.title)
+ assert_equal(link, channel.image.link)
+
+ assert_nil(channel.textInput)
+ end
+
+ def test_not_valid_channel
+ title = "fugafuga"
+ link = "http://hoge.com"
+ description = "fugafugafugafuga"
+ language = "ja"
+
+ assert_not_set_error("maker.channel", %w(title)) do
+ RSS::Maker.make("0.91") do |maker|
+ # maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+ maker.channel.language = language
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(link)) do
+ RSS::Maker.make("0.91") do |maker|
+ maker.channel.title = title
+ # maker.channel.link = link
+ maker.channel.link = nil
+ maker.channel.description = description
+ maker.channel.language = language
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(description)) do
+ RSS::Maker.make("0.91") do |maker|
+ maker.channel.title = title
+ maker.channel.link = link
+ # maker.channel.description = description
+ maker.channel.language = language
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(language)) do
+ RSS::Maker.make("0.91") do |maker|
+ maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+ # maker.channel.language = language
+ end
+ end
+ end
+
+ def test_image
+ title = "fugafuga"
+ link = "http://hoge.com"
+ url = "http://hoge.com/hoge.png"
+ width = "144"
+ height = "400"
+ description = "an image"
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.title = title
+ maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
+ image = rss.image
+ assert_equal(title, image.title)
+ assert_equal(link, image.link)
+ assert_equal(url, image.url)
+ assert_equal(width.to_i, image.width)
+ assert_equal(height.to_i, image.height)
+ assert_equal(description, image.description)
+
+ assert_not_set_error("maker.channel", %w(description title language)) do
+ RSS::Maker.make("0.91") do |maker|
+ # setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.title = title
+ maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
+ end
+ end
+
+ def test_not_valid_image
+ title = "fugafuga"
+ link = "http://hoge.com"
+ url = "http://hoge.com/hoge.png"
+ width = "144"
+ height = "400"
+ description = "an image"
+
+ assert_not_set_error("maker.image", %w(title)) do
+ RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ # maker.image.title = title
+ maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(link)) do
+ RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ # maker.channel.link = link
+ maker.channel.link = nil
+
+ maker.image.title = title
+ maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
+ end
+
+ assert_not_set_error("maker.image", %w(url)) do
+ RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.title = title
+ # maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
+ end
+ end
+
+ def test_items(with_convenience_way=true)
+ title = "TITLE"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+ end
+ assert(rss.channel.items.empty?)
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.items.new_item do |item|
+ item.title = title
+ item.link = link
+ # item.description = description
+ end
+
+ setup_dummy_image(maker)
+ end
+ assert_equal(1, rss.channel.items.size)
+ item = rss.channel.items.first
+ assert_equal(title, item.title)
+ assert_equal(link, item.link)
+ assert_nil(item.description)
+
+
+ item_size = 5
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |_item|
+ _item.title = "#{title}#{i}"
+ _item.link = "#{link}#{i}"
+ _item.description = "#{description}#{i}"
+ end
+ end
+ maker.items.do_sort = true
+
+ setup_dummy_image(maker)
+ end
+ assert_equal(item_size, rss.items.size)
+ rss.channel.items.each_with_index do |_item, i|
+ assert_equal("#{title}#{i}", _item.title)
+ assert_equal("#{link}#{i}", _item.link)
+ assert_equal("#{description}#{i}", _item.description)
+ end
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |_item|
+ _item.title = "#{title}#{i}"
+ _item.link = "#{link}#{i}"
+ _item.description = "#{description}#{i}"
+ end
+ end
+ maker.items.do_sort = Proc.new do |x, y|
+ if with_convenience_way
+ y.title[-1] <=> x.title[-1]
+ else
+ y.title {|t| t.content[-1]} <=> x.title {|t| t.content[-1]}
+ end
+ end
+
+ setup_dummy_image(maker)
+ end
+ assert_equal(item_size, rss.items.size)
+ rss.channel.items.reverse.each_with_index do |_item, i|
+ assert_equal("#{title}#{i}", _item.title)
+ assert_equal("#{link}#{i}", _item.link)
+ assert_equal("#{description}#{i}", _item.description)
+ end
+ end
+
+ def test_items_with_new_api_since_018
+ test_items(false)
+ end
+
+ def test_textInput
+ title = "fugafuga"
+ description = "text hoge fuga"
+ name = "hoge"
+ link = "http://hoge.com"
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
+ textInput = rss.channel.textInput
+ assert_equal(title, textInput.title)
+ assert_equal(description, textInput.description)
+ assert_equal(name, textInput.name)
+ assert_equal(link, textInput.link)
+
+ assert_not_set_error("maker.channel",
+ %w(link language description title)) do
+ RSS::Maker.make("0.91") do |maker|
+ # setup_dummy_channel(maker)
+
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
+ end
+ end
+
+ def test_not_valid_textInput
+ title = "fugafuga"
+ description = "text hoge fuga"
+ name = "hoge"
+ link = "http://hoge.com"
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+
+ # maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
+ assert_nil(rss.channel.textInput)
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+
+ maker.textinput.title = title
+ # maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
+ assert_nil(rss.channel.textInput)
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+
+ maker.textinput.title = title
+ maker.textinput.description = description
+ # maker.textinput.name = name
+ maker.textinput.link = link
+ end
+ assert_nil(rss.channel.textInput)
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ # maker.textinput.link = link
+ end
+ assert_nil(rss.channel.textInput)
+ end
+
+ def test_date_in_string
+ date = Time.now
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+
+ maker.items.new_item do |item|
+ item.title = "The first item"
+ item.link = "http://example.com/blog/1.html"
+ item.date = date.rfc822
+ end
+ end
+
+ assert_equal(date.iso8601, rss.items[0].date.iso8601)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_1.0.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_1.0.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_1.0.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,516 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMaker10 < TestCase
+ def test_supported?
+ assert(RSS::Maker.supported?("1.0"))
+ assert(RSS::Maker.supported?("rss1.0"))
+ assert(!RSS::Maker.supported?("1.1"))
+ assert(!RSS::Maker.supported?("rss1.1"))
+ end
+
+ def test_find_class
+ assert_equal(RSS::Maker::RSS10, RSS::Maker["1.0"])
+ assert_equal(RSS::Maker::RSS10, RSS::Maker["rss1.0"])
+ end
+
+ def test_rdf
+ assert_raise(LocalJumpError) do
+ RSS::Maker.make("1.0")
+ end
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+ end
+ assert_equal("1.0", rss.rss_version)
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.encoding = "EUC-JP"
+
+ setup_dummy_item(maker)
+ end
+ assert_equal("1.0", rss.rss_version)
+ assert_equal("EUC-JP", rss.encoding)
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.standalone = "yes"
+
+ setup_dummy_item(maker)
+ end
+ assert_equal("1.0", rss.rss_version)
+ assert_equal("yes", rss.standalone)
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.encoding = "EUC-JP"
+ maker.standalone = "yes"
+
+ setup_dummy_item(maker)
+ end
+ assert_equal("1.0", rss.rss_version)
+ assert_equal("EUC-JP", rss.encoding)
+ assert_equal("yes", rss.standalone)
+ end
+
+ def test_channel
+ about = "http://hoge.com"
+ title = "fugafuga"
+ link = "http://hoge.com"
+ description = "fugafugafugafuga"
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ maker.channel.about = about
+ maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+
+ setup_dummy_item(maker)
+ end
+ channel = rss.channel
+ assert_equal(about, channel.about)
+ assert_equal(title, channel.title)
+ assert_equal(link, channel.link)
+ assert_equal(description, channel.description)
+ assert_equal(1, channel.items.Seq.lis.size)
+ assert_nil(channel.image)
+ assert_nil(channel.textinput)
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ maker.channel.about = about
+ maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+
+ setup_dummy_image(maker)
+
+ setup_dummy_textinput(maker)
+
+ setup_dummy_item(maker)
+ end
+ channel = rss.channel
+ assert_equal(about, channel.about)
+ assert_equal(title, channel.title)
+ assert_equal(link, channel.link)
+ assert_equal(description, channel.description)
+ assert_equal(1, channel.items.Seq.lis.size)
+ assert_equal(rss.image.about, channel.image.resource)
+ assert_equal(rss.textinput.about, channel.textinput.resource)
+ end
+
+ def test_channel_language
+ about = "http://hoge.com"
+ title = "fugafuga"
+ link = "http://hoge.com"
+ description = "fugafugafugafuga"
+ language = "ja"
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ maker.channel.about = about
+ maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+ maker.channel.language = language
+
+ setup_dummy_item(maker)
+ end
+ channel = rss.channel
+ assert_equal(language, channel.dc_language)
+ end
+
+ def test_not_valid_channel
+ about = "http://hoge.com"
+ title = "fugafuga"
+ link = "http://hoge.com"
+ description = "fugafugafugafuga"
+
+ assert_not_set_error("maker.channel", %w(about)) do
+ RSS::Maker.make("1.0") do |maker|
+ # maker.channel.about = about
+ maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(title)) do
+ RSS::Maker.make("1.0") do |maker|
+ maker.channel.about = about
+ # maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(link)) do
+ RSS::Maker.make("1.0") do |maker|
+ maker.channel.about = about
+ maker.channel.title = title
+ # maker.channel.link = link
+ maker.channel.description = description
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(description)) do
+ RSS::Maker.make("1.0") do |maker|
+ maker.channel.about = about
+ maker.channel.title = title
+ maker.channel.link = link
+ # maker.channel.description = description
+ end
+ end
+ end
+
+
+ def test_image
+ title = "fugafuga"
+ link = "http://hoge.com"
+ url = "http://hoge.com/hoge.png"
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.title = title
+ maker.image.url = url
+
+ setup_dummy_item(maker)
+ end
+ image = rss.image
+ assert_equal(url, image.about)
+ assert_equal(url, rss.channel.image.resource)
+ assert_equal(title, image.title)
+ assert_equal(link, image.link)
+ assert_equal(url, image.url)
+
+ assert_not_set_error("maker.channel", %w(about title description)) do
+ RSS::Maker.make("1.0") do |maker|
+ # setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.title = title
+ maker.image.url = url
+ end
+ end
+ end
+
+ def test_not_valid_image
+ title = "fugafuga"
+ link = "http://hoge.com"
+ url = "http://hoge.com/hoge.png"
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ # maker.image.url = url
+ maker.image.title = title
+
+ setup_dummy_item(maker)
+ end
+ assert_nil(rss.channel.image)
+ assert_nil(rss.image)
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.url = url
+ # maker.image.title = title
+
+ setup_dummy_item(maker)
+ end
+ assert_nil(rss.channel.image)
+ assert_nil(rss.image)
+
+ assert_not_set_error("maker.channel", %w(link)) do
+ RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ # maker.channel.link = link
+ maker.channel.link = nil
+
+ maker.image.url = url
+ maker.image.title = title
+
+ setup_dummy_item(maker)
+ end
+ end
+ end
+
+ def test_items(with_convenience_way=true)
+ title = "TITLE"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+
+ assert_not_set_error("maker", %w(items)) do
+ RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ end
+ end
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.items.new_item do |item|
+ item.title = title
+ item.link = link
+ # item.description = description
+ end
+ end
+ assert_equal(1, rss.items.size)
+ item = rss.items.first
+ assert_equal(link, item.about)
+ assert_equal(title, item.title)
+ assert_equal(link, item.link)
+ assert_nil(item.description)
+
+
+ item_size = 5
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |_item|
+ _item.title = "#{title}#{i}"
+ _item.link = "#{link}#{i}"
+ _item.description = "#{description}#{i}"
+ end
+ end
+ maker.items.do_sort = true
+ end
+ assert_equal(item_size, rss.items.size)
+ rss.items.each_with_index do |_item, i|
+ assert_equal("#{link}#{i}", _item.about)
+ assert_equal("#{title}#{i}", _item.title)
+ assert_equal("#{link}#{i}", _item.link)
+ assert_equal("#{description}#{i}", _item.description)
+ end
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |_item|
+ _item.title = "#{title}#{i}"
+ _item.link = "#{link}#{i}"
+ _item.description = "#{description}#{i}"
+ end
+ end
+ maker.items.do_sort = Proc.new do |x, y|
+ if with_convenience_way
+ y.title[-1] <=> x.title[-1]
+ else
+ y.title {|t| t.content[-1]} <=> x.title {|t| t.content[-1]}
+ end
+ end
+ end
+ assert_equal(item_size, rss.items.size)
+ rss.items.reverse.each_with_index do |_item, i|
+ assert_equal("#{link}#{i}", _item.about)
+ assert_equal("#{title}#{i}", _item.title)
+ assert_equal("#{link}#{i}", _item.link)
+ assert_equal("#{description}#{i}", _item.description)
+ end
+
+ max_size = item_size / 2
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |_item|
+ _item.title = "#{title}#{i}"
+ _item.link = "#{link}#{i}"
+ _item.description = "#{description}#{i}"
+ end
+ end
+ maker.items.max_size = max_size
+ end
+ assert_equal(max_size, rss.items.size)
+ rss.items.each_with_index do |_item, i|
+ assert_equal("#{link}#{i}", _item.about)
+ assert_equal("#{title}#{i}", _item.title)
+ assert_equal("#{link}#{i}", _item.link)
+ assert_equal("#{description}#{i}", _item.description)
+ end
+
+ max_size = 0
+ assert_not_set_error("maker", %w(items)) do
+ RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |_item|
+ _item.title = "#{title}#{i}"
+ _item.link = "#{link}#{i}"
+ _item.description = "#{description}#{i}"
+ end
+ end
+ maker.items.max_size = max_size
+ end
+ end
+
+ max_size = -2
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |_item|
+ _item.title = "#{title}#{i}"
+ _item.link = "#{link}#{i}"
+ _item.description = "#{description}#{i}"
+ end
+ end
+ maker.items.max_size = max_size
+ end
+ assert_equal(item_size + max_size + 1, rss.items.size)
+ rss.items.each_with_index do |_item, i|
+ assert_equal("#{link}#{i}", _item.about)
+ assert_equal("#{title}#{i}", _item.title)
+ assert_equal("#{link}#{i}", _item.link)
+ assert_equal("#{description}#{i}", _item.description)
+ end
+ end
+
+ def test_items_with_new_api_since_018
+ test_items(false)
+ end
+
+ def test_not_valid_items
+ title = "TITLE"
+ link = "http://hoge.com/"
+
+ assert_not_set_error("maker.item", %w(title)) do
+ RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.items.new_item do |item|
+ # item.title = title
+ item.link = link
+ end
+ end
+ end
+
+ assert_not_set_error("maker.item", %w(link)) do
+ RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.items.new_item do |item|
+ item.title = title
+ # item.link = link
+ end
+ end
+ end
+
+ assert_not_set_error("maker.item", %w(title link)) do
+ RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.items.new_item do |item|
+ # item.title = title
+ # item.link = link
+ end
+ end
+ end
+ end
+
+ def test_textinput
+ title = "fugafuga"
+ description = "text hoge fuga"
+ name = "hoge"
+ link = "http://hoge.com"
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.textinput.link = link
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+
+ setup_dummy_item(maker)
+ end
+ textinput = rss.textinput
+ assert_equal(link, textinput.about)
+ assert_equal(link, rss.channel.textinput.resource)
+ assert_equal(title, textinput.title)
+ assert_equal(name, textinput.name)
+ assert_equal(description, textinput.description)
+ assert_equal(link, textinput.link)
+
+ assert_not_set_error("maker.channel", %w(about link description title)) do
+ RSS::Maker.make("1.0") do |maker|
+ # setup_dummy_channel(maker)
+
+ maker.textinput.link = link
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ end
+ end
+ end
+
+ def test_not_valid_textinput
+ title = "fugafuga"
+ description = "text hoge fuga"
+ name = "hoge"
+ link = "http://hoge.com"
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ # maker.textinput.link = link
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+
+ setup_dummy_item(maker)
+ end
+ assert_nil(rss.channel.textinput)
+ assert_nil(rss.textinput)
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.textinput.link = link
+ # maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+
+ setup_dummy_item(maker)
+ end
+ assert_nil(rss.channel.textinput)
+ assert_nil(rss.textinput)
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.textinput.link = link
+ maker.textinput.title = title
+ # maker.textinput.description = description
+ maker.textinput.name = name
+
+ setup_dummy_item(maker)
+ end
+ assert_nil(rss.channel.textinput)
+ assert_nil(rss.textinput)
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.textinput.link = link
+ maker.textinput.title = title
+ maker.textinput.description = description
+ # maker.textinput.name = name
+
+ setup_dummy_item(maker)
+ end
+ assert_nil(rss.channel.textinput)
+ assert_nil(rss.textinput)
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_2.0.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_2.0.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_2.0.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,757 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMaker20 < TestCase
+ def test_supported?
+ assert(RSS::Maker.supported?("2.0"))
+ assert(RSS::Maker.supported?("rss2.0"))
+ assert(!RSS::Maker.supported?("2.2"))
+ assert(!RSS::Maker.supported?("rss2.2"))
+ end
+
+ def test_find_class
+ assert_equal(RSS::Maker::RSS20, RSS::Maker["2.0"])
+ assert_equal(RSS::Maker::RSS20, RSS::Maker["rss2.0"])
+ end
+
+ def test_rss
+ assert_raise(LocalJumpError) do
+ RSS::Maker.make("2.0")
+ end
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ end
+ assert_equal("2.0", rss.rss_version)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.encoding = "EUC-JP"
+ end
+ assert_equal("2.0", rss.rss_version)
+ assert_equal("EUC-JP", rss.encoding)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.standalone = "yes"
+ end
+ assert_equal("2.0", rss.rss_version)
+ assert_equal("yes", rss.standalone)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.encoding = "EUC-JP"
+ maker.standalone = "yes"
+ end
+ assert_equal("2.0", rss.rss_version)
+ assert_equal("EUC-JP", rss.encoding)
+ assert_equal("yes", rss.standalone)
+ end
+
+ def test_channel
+ title = "fugafuga"
+ link = "http://hoge.com"
+ description = "fugafugafugafuga"
+ language = "ja"
+ copyright = "foo"
+ managingEditor = "bar"
+ webMaster = "web master"
+ rating = '(PICS-1.1 "http://www.rsac.org/ratingsv01.html" l gen true comment "RSACi North America Server" for "http://www.rsac.org" on "1996.04.16T08:15-0500" r (n 0 s 0 v 0 l 0))'
+ docs = "http://foo.com/doc"
+ skipDays = [
+ "Sunday",
+ "Monday",
+ ]
+ skipHours = [
+ "0",
+ "13",
+ ]
+ pubDate = Time.now
+ lastBuildDate = Time.now
+ categories = [
+ "Nespapers",
+ "misc",
+ ]
+ generator = "RSS Maker"
+ ttl = "60"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+ maker.channel.language = language
+ maker.channel.copyright = copyright
+ maker.channel.managingEditor = managingEditor
+ maker.channel.webMaster = webMaster
+ maker.channel.rating = rating
+ maker.channel.docs = docs
+ maker.channel.pubDate = pubDate
+ maker.channel.lastBuildDate = lastBuildDate
+
+ skipDays.each do |day|
+ maker.channel.skipDays.new_day do |new_day|
+ new_day.content = day
+ end
+ end
+ skipHours.each do |hour|
+ maker.channel.skipHours.new_hour do |new_hour|
+ new_hour.content = hour
+ end
+ end
+
+ categories.each do |category|
+ maker.channel.categories.new_category do |new_category|
+ new_category.content = category
+ end
+ end
+
+ maker.channel.generator = generator
+ maker.channel.ttl = ttl
+ end
+ channel = rss.channel
+
+ assert_equal(title, channel.title)
+ assert_equal(link, channel.link)
+ assert_equal(description, channel.description)
+ assert_equal(language, channel.language)
+ assert_equal(copyright, channel.copyright)
+ assert_equal(managingEditor, channel.managingEditor)
+ assert_equal(webMaster, channel.webMaster)
+ assert_equal(rating, channel.rating)
+ assert_equal(docs, channel.docs)
+ assert_equal(pubDate, channel.pubDate)
+ assert_equal(pubDate, channel.date)
+ assert_equal(lastBuildDate, channel.lastBuildDate)
+
+ skipDays.each_with_index do |day, i|
+ assert_equal(day, channel.skipDays.days[i].content)
+ end
+ skipHours.each_with_index do |hour, i|
+ assert_equal(hour.to_i, channel.skipHours.hours[i].content)
+ end
+
+ channel.categories.each_with_index do |category, i|
+ assert_equal(categories[i], category.content)
+ end
+
+ assert_equal(generator, channel.generator)
+ assert_equal(ttl.to_i, channel.ttl)
+
+ assert(channel.items.empty?)
+ assert_nil(channel.image)
+ assert_nil(channel.textInput)
+ end
+
+ def test_not_valid_channel
+ title = "fugafuga"
+ link = "http://hoge.com"
+ description = "fugafugafugafuga"
+ language = "ja"
+
+ assert_not_set_error("maker.channel", %w(title)) do
+ RSS::Maker.make("2.0") do |maker|
+ # maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+ maker.channel.language = language
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(link)) do
+ RSS::Maker.make("2.0") do |maker|
+ maker.channel.title = title
+ # maker.channel.link = link
+ maker.channel.description = description
+ maker.channel.language = language
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(description)) do
+ RSS::Maker.make("2.0") do |maker|
+ maker.channel.title = title
+ maker.channel.link = link
+ # maker.channel.description = description
+ maker.channel.language = language
+ end
+ end
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+ # maker.channel.language = language
+ end
+ assert_not_nil(rss)
+ end
+
+
+ def test_cloud
+ domain = "rpc.sys.com"
+ port = "80"
+ path = "/RPC2"
+ registerProcedure = "myCloud.rssPleaseNotify"
+ protocol = "xml-rpc"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.channel.cloud.domain = domain
+ maker.channel.cloud.port = port
+ maker.channel.cloud.path = path
+ maker.channel.cloud.registerProcedure = registerProcedure
+ maker.channel.cloud.protocol = protocol
+ end
+ cloud = rss.channel.cloud
+ assert_equal(domain, cloud.domain)
+ assert_equal(port.to_i, cloud.port)
+ assert_equal(path, cloud.path)
+ assert_equal(registerProcedure, cloud.registerProcedure)
+ assert_equal(protocol, cloud.protocol)
+ end
+
+ def test_not_valid_cloud
+ domain = "rpc.sys.com"
+ port = "80"
+ path = "/RPC2"
+ registerProcedure = "myCloud.rssPleaseNotify"
+ protocol = "xml-rpc"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ # maker.channel.cloud.domain = domain
+ maker.channel.cloud.port = port
+ maker.channel.cloud.path = path
+ maker.channel.cloud.registerProcedure = registerProcedure
+ maker.channel.cloud.protocol = protocol
+ end
+ assert_nil(rss.channel.cloud)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.channel.cloud.domain = domain
+ # maker.channel.cloud.port = port
+ maker.channel.cloud.path = path
+ maker.channel.cloud.registerProcedure = registerProcedure
+ maker.channel.cloud.protocol = protocol
+ end
+ assert_nil(rss.channel.cloud)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.channel.cloud.domain = domain
+ maker.channel.cloud.port = port
+ # maker.channel.cloud.path = path
+ maker.channel.cloud.registerProcedure = registerProcedure
+ maker.channel.cloud.protocol = protocol
+ end
+ assert_nil(rss.channel.cloud)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.channel.cloud.domain = domain
+ maker.channel.cloud.port = port
+ maker.channel.cloud.path = path
+ # maker.channel.cloud.registerProcedure = registerProcedure
+ maker.channel.cloud.protocol = protocol
+ end
+ assert_nil(rss.channel.cloud)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.channel.cloud.domain = domain
+ maker.channel.cloud.port = port
+ maker.channel.cloud.path = path
+ maker.channel.cloud.registerProcedure = registerProcedure
+ # maker.channel.cloud.protocol = protocol
+ end
+ assert_nil(rss.channel.cloud)
+ end
+
+
+ def test_image
+ title = "fugafuga"
+ link = "http://hoge.com"
+ url = "http://hoge.com/hoge.png"
+ width = "144"
+ height = "400"
+ description = "an image"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.title = title
+ maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
+ image = rss.image
+ assert_equal(title, image.title)
+ assert_equal(link, image.link)
+ assert_equal(url, image.url)
+ assert_equal(width.to_i, image.width)
+ assert_equal(height.to_i, image.height)
+ assert_equal(description, image.description)
+
+ assert_not_set_error("maker.channel", %w(title description)) do
+ RSS::Maker.make("2.0") do |maker|
+ # setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.title = title
+ maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
+ end
+ end
+
+ def test_not_valid_image
+ title = "fugafuga"
+ link = "http://hoge.com"
+ url = "http://hoge.com/hoge.png"
+ width = "144"
+ height = "400"
+ description = "an image"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ # maker.image.title = title
+ maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
+ assert_nil(rss.image)
+
+ assert_not_set_error("maker.channel", %w(link)) do
+ RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ # maker.channel.link = link
+ maker.channel.link = nil
+
+ maker.image.title = title
+ maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
+ end
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.title = title
+ # maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
+ assert_nil(rss.image)
+ end
+
+ def test_items(with_convenience_way=true)
+ title = "TITLE"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+ author = "oprah at oxygen.net"
+ comments = "http://www.myblog.org/cgi-local/mt/mt-comments.cgi?entry_id=290"
+ pubDate = Time.now
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ end
+ assert(rss.channel.items.empty?)
+
+ item_size = 5
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ item.author = "#{author}#{i}"
+ item.comments = "#{comments}#{i}"
+ item.date = pubDate
+ end
+ end
+ maker.items.do_sort = true
+ end
+ assert_equal(item_size, rss.items.size)
+ rss.channel.items.each_with_index do |item, i|
+ assert_equal("#{title}#{i}", item.title)
+ assert_equal("#{link}#{i}", item.link)
+ assert_equal("#{description}#{i}", item.description)
+ assert_equal("#{author}#{i}", item.author)
+ assert_equal("#{comments}#{i}", item.comments)
+ assert_equal(pubDate, item.pubDate)
+ assert_equal(pubDate, item.date)
+ end
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ item.author = "#{author}#{i}"
+ item.comments = "#{comments}#{i}"
+ item.date = pubDate
+ end
+ end
+ maker.items.do_sort = Proc.new do |x, y|
+ if with_convenience_way
+ y.title[-1] <=> x.title[-1]
+ else
+ y.title {|t| t.content[-1]} <=> x.title {|t| t.content[-1]}
+ end
+ end
+ end
+ assert_equal(item_size, rss.items.size)
+ rss.channel.items.reverse.each_with_index do |item, i|
+ assert_equal("#{title}#{i}", item.title)
+ assert_equal("#{link}#{i}", item.link)
+ assert_equal("#{description}#{i}", item.description)
+ assert_equal("#{author}#{i}", item.author)
+ assert_equal("#{comments}#{i}", item.comments)
+ assert_equal(pubDate, item.pubDate)
+ assert_equal(pubDate, item.date)
+ end
+ end
+
+ def test_items_with_new_api_since_018
+ test_items(false)
+ end
+
+ def test_pubDate_without_description
+ title = "TITLE"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+ author = "oprah at oxygen.net"
+ pubDate = Time.now
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.items.new_item do |item|
+ item.title = title
+ item.link = link
+ # item.description = description
+ item.author = author
+ item.pubDate = pubDate
+ end
+ end
+ assert_equal(1, rss.items.size)
+ rss.channel.items.each_with_index do |item, i|
+ assert_equal(title, item.title)
+ assert_equal(link, item.link)
+ # assert_equal(description, item.description)
+ assert_equal(author, item.author)
+ assert_equal(pubDate, item.pubDate)
+ assert_equal(pubDate, item.date)
+ end
+ end
+
+ def test_guid
+ isPermaLink = "true"
+ content = "http://inessential.com/2002/09/01.php#a2"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ guid = maker.items.last.guid
+ guid.isPermaLink = isPermaLink
+ guid.content = content
+ end
+ guid = rss.channel.items.last.guid
+ assert_equal(isPermaLink == "true", guid.isPermaLink)
+ assert_equal(content, guid.content)
+ end
+
+ def test_guid_permanent_link
+ content = "http://inessential.com/2002/09/01.php#a2"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ guid = maker.items.last.guid
+ assert_equal(nil, guid.permanent_link?)
+ assert_equal(guid.isPermaLink, guid.permanent_link?)
+ guid.permanent_link = true
+ assert_equal(true, guid.permanent_link?)
+ assert_equal(guid.isPermaLink, guid.permanent_link?)
+ guid.content = content
+ end
+ guid = rss.channel.items.last.guid
+ assert_equal(true, guid.isPermaLink)
+ assert_equal(content, guid.content)
+ end
+
+ def test_guid_permanent_link_false
+ content = "http://inessential.com/2002/09/01.php#a2"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ guid = maker.items.last.guid
+ assert_equal(nil, guid.permanent_link?)
+ assert_equal(guid.isPermaLink, guid.permanent_link?)
+ guid.permanent_link = false
+ assert_equal(false, guid.permanent_link?)
+ assert_equal(guid.isPermaLink, guid.permanent_link?)
+ guid.content = content
+ end
+ guid = rss.channel.items.last.guid
+ assert_equal(false, guid.isPermaLink)
+ assert_equal(content, guid.content)
+ end
+
+ def test_not_valid_guid
+ content = "http://inessential.com/2002/09/01.php#a2"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ guid = maker.items.last.guid
+ # guid.content = content
+ end
+ assert_nil(rss.channel.items.last.guid)
+ end
+
+ def test_enclosure
+ url = "http://www.scripting.com/mp3s/weatherReportSuite.mp3"
+ length = "12216320"
+ type = "audio/mpeg"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ enclosure = maker.items.last.enclosure
+ enclosure.url = url
+ enclosure.length = length
+ enclosure.type = type
+ end
+ enclosure = rss.channel.items.last.enclosure
+ assert_equal(url, enclosure.url)
+ assert_equal(length.to_i, enclosure.length)
+ assert_equal(type, enclosure.type)
+ end
+
+ def test_not_valid_enclosure
+ url = "http://www.scripting.com/mp3s/weatherReportSuite.mp3"
+ length = "12216320"
+ type = "audio/mpeg"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ enclosure = maker.items.last.enclosure
+ # enclosure.url = url
+ enclosure.length = length
+ enclosure.type = type
+ end
+ assert_nil(rss.channel.items.last.enclosure)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ enclosure = maker.items.last.enclosure
+ enclosure.url = url
+ # enclosure.length = length
+ enclosure.type = type
+ end
+ assert_nil(rss.channel.items.last.enclosure)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ enclosure = maker.items.last.enclosure
+ enclosure.url = url
+ enclosure.length = length
+ # enclosure.type = type
+ end
+ assert_nil(rss.channel.items.last.enclosure)
+ end
+
+
+ def test_source
+ url = "http://static.userland.com/tomalak/links2.xml"
+ content = "Tomalak's Realm"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ source = maker.items.last.source
+ source.url = url
+ source.content = content
+ end
+ source = rss.channel.items.last.source
+ assert_equal(url, source.url)
+ assert_equal(content, source.content)
+ end
+
+ def test_not_valid_source
+ url = "http://static.userland.com/tomalak/links2.xml"
+ content = "Tomalak's Realm"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ source = maker.items.last.source
+ # source.url = url
+ source.content = content
+ end
+ assert_nil(rss.channel.items.last.source)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ source = maker.items.last.source
+ source.url = url
+ # source.content = content
+ end
+ assert_nil(rss.channel.items.last.source)
+ end
+
+ def test_category
+ domain = "http://www.fool.com/cusips"
+ content = "MSFT"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ maker.items.last.categories.new_category do |category|
+ category.domain = domain
+ category.content = content
+ end
+ end
+ category = rss.channel.items.last.categories.last
+ assert_equal(domain, category.domain)
+ assert_equal(content, category.content)
+ end
+
+ def test_not_valid_category
+ content = "Grateful Dead"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ maker.items.last.categories.new_category do |category|
+ # category.content = content
+ end
+ end
+ assert(rss.channel.items.last.categories.empty?)
+ end
+
+ def test_textInput
+ title = "fugafuga"
+ description = "text hoge fuga"
+ name = "hoge"
+ link = "http://hoge.com"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
+ textInput = rss.channel.textInput
+ assert_equal(title, textInput.title)
+ assert_equal(description, textInput.description)
+ assert_equal(name, textInput.name)
+ assert_equal(link, textInput.link)
+
+ assert_not_set_error("maker.channel", %w(link description title)) do
+ RSS::Maker.make("2.0") do |maker|
+ # setup_dummy_channel(maker)
+
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
+ end
+ end
+
+ def test_not_valid_textInput
+ title = "fugafuga"
+ description = "text hoge fuga"
+ name = "hoge"
+ link = "http://hoge.com"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ # maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
+ assert_nil(rss.channel.textInput)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.textinput.title = title
+ # maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
+ assert_nil(rss.channel.textInput)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.textinput.title = title
+ maker.textinput.description = description
+ # maker.textinput.name = name
+ maker.textinput.link = link
+ end
+ assert_nil(rss.channel.textInput)
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ # maker.textinput.link = link
+ end
+ assert_nil(rss.channel.textInput)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_atom_entry.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_atom_entry.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_atom_entry.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,393 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerAtomEntry < TestCase
+ def test_supported?
+ assert(RSS::Maker.supported?("atom:entry"))
+ assert(RSS::Maker.supported?("atom1.0:entry"))
+ assert(!RSS::Maker.supported?("atom2.0:entry"))
+ end
+
+ def test_find_class
+ assert_equal(RSS::Maker::Atom::Entry, RSS::Maker["atom:entry"])
+ assert_equal(RSS::Maker::Atom::Entry, RSS::Maker["atom1.0:entry"])
+ end
+
+ def test_root_element
+ entry = Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ assert_equal(["atom", "1.0", "entry"], entry.feed_info)
+
+ entry = Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.encoding = "EUC-JP"
+ end
+ assert_equal(["atom", "1.0", "entry"], entry.feed_info)
+ assert_equal("EUC-JP", entry.encoding)
+
+ entry = Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.standalone = "yes"
+ end
+ assert_equal(["atom", "1.0", "entry"], entry.feed_info)
+ assert_equal("yes", entry.standalone)
+
+ entry = Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.encoding = "EUC-JP"
+ maker.standalone = "yes"
+ end
+ assert_equal(["atom", "1.0", "entry"], entry.feed_info)
+ assert_equal("EUC-JP", entry.encoding)
+ assert_equal("yes", entry.standalone)
+ end
+
+ def test_invalid_feed
+ assert_not_set_error("maker.item", %w(id title author updated)) do
+ Maker.make("atom:entry") do |maker|
+ end
+ end
+
+ assert_not_set_error("maker.item", %w(id title updated)) do
+ Maker.make("atom:entry") do |maker|
+ maker.channel.author = "foo"
+ end
+ end
+
+ assert_not_set_error("maker.item", %w(title updated)) do
+ Maker.make("atom:entry") do |maker|
+ maker.channel.author = "foo"
+ maker.channel.id = "http://example.com"
+ end
+ end
+
+ assert_not_set_error("maker.item", %w(updated)) do
+ Maker.make("atom:entry") do |maker|
+ maker.channel.author = "foo"
+ maker.channel.id = "http://example.com"
+ maker.channel.title = "Atom Feed"
+ end
+ end
+
+ assert_not_set_error("maker.item", %w(author)) do
+ Maker.make("atom:entry") do |maker|
+ maker.channel.id = "http://example.com"
+ maker.channel.title = "Atom Feed"
+ maker.channel.updated = Time.now
+ end
+ end
+
+ entry = Maker.make("atom:entry") do |maker|
+ maker.channel.author = "Foo"
+ maker.channel.id = "http://example.com"
+ maker.channel.title = "Atom Feed"
+ maker.channel.updated = Time.now
+ end
+ assert_not_nil(entry)
+ end
+
+ def test_author
+ assert_maker_atom_persons("entry",
+ ["channel", "authors"],
+ ["authors"],
+ "maker.channel.author") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_persons("entry",
+ ["items", "first", "authors"],
+ ["authors"],
+ "maker.item.author",
+ "maker.item", ["author"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.authors.clear
+ maker.items.first.authors.clear
+ end
+
+ assert_maker_atom_persons("entry",
+ ["items", "first", "source", "authors"],
+ ["source", "authors"],
+ "maker.item.source.author") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_category
+ assert_maker_atom_categories("entry",
+ ["channel", "categories"],
+ ["categories"],
+ "maker.channel.category") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_categories("entry",
+ ["items", "first", "categories"],
+ ["categories"],
+ "maker.item.category") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_categories("entry",
+ ["items", "first", "source", "categories"],
+ ["source", "categories"],
+ "maker.item.source.category") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_content
+ assert_maker_atom_content("entry",
+ ["items", "first", "content"],
+ ["content"],
+ "maker.item.content") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_contributor
+ assert_maker_atom_persons("entry",
+ ["channel", "contributors"],
+ ["contributors"],
+ "maker.channel.contributor") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_persons("entry",
+ ["items", "first", "contributors"],
+ ["contributors"],
+ "maker.item.contributor") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_persons("entry",
+ ["items", "first", "source", "contributors"],
+ ["source", "contributors"],
+ "maker.item.source.contributor") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_link
+ assert_maker_atom_links("entry",
+ ["channel", "links"],
+ ["links"],
+ "maker.channel.link") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.links.clear
+ maker.items.first.links.clear
+ end
+
+ assert_maker_atom_links("entry",
+ ["items", "first", "links"],
+ ["links"],
+ "maker.item.link") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.links.clear
+ maker.items.first.links.clear
+ end
+
+ assert_maker_atom_links("entry",
+ ["items", "first", "source", "links"],
+ ["source", "links"],
+ "maker.item.source.link", true) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_published
+ assert_maker_atom_date_construct("entry",
+ ["items", "first", "published"],
+ ["published"]
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_rights
+ assert_maker_atom_text_construct("entry",
+ ["channel", "copyright"],
+ ["rights"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_text_construct("entry",
+ ["items", "first", "rights"],
+ ["rights"],
+ nil, nil, "maker.item.rights"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_text_construct("entry",
+ ["items", "first", "source", "rights"],
+ ["source", "rights"],
+ nil, nil, "maker.item.source.rights"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+
+ def test_source_generator
+ assert_maker_atom_generator("entry",
+ ["items", "first", "source", "generator"],
+ ["source", "generator"],
+ "maker.item.source.generator") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_source_icon
+ assert_maker_atom_icon("entry",
+ ["items", "first", "source", "icon"],
+ ["source", "icon"],
+ nil, "maker.item.source.icon") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_source_id
+ assert_maker_atom_id("entry",
+ ["items", "first", "source"],
+ ["source"],
+ "maker.item.source") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_source_logo
+ assert_maker_atom_logo("entry",
+ ["items", "first", "source", "logo"],
+ ["source", "logo"],
+ nil,
+ "maker.item.source.logo") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_source_subtitle
+ assert_maker_atom_text_construct("entry",
+ ["items", "first", "source", "subtitle"],
+ ["source", "subtitle"],
+ nil, nil,
+ "maker.item.source.subtitle") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_summary
+ assert_maker_atom_text_construct("entry",
+ ["items", "first", "description"],
+ ["summary"],
+ nil, nil, "maker.item.description"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_title
+ assert_maker_atom_text_construct("entry",
+ ["channel", "title"], ["title"],
+ "maker.item", ["title"],
+ "maker.channel.title") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.title = nil
+ maker.items.first.title = nil
+ end
+
+ assert_maker_atom_text_construct("entry",
+ ["items", "first", "title"],
+ ["title"],
+ "maker.item", ["title"],
+ "maker.item.title") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.title = nil
+ maker.items.first.title = nil
+ end
+
+ assert_maker_atom_text_construct("entry",
+ ["items", "first", "source", "title"],
+ ["source", "title"],
+ nil, nil, "maker.item.source.title"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_updated
+ assert_maker_atom_date_construct("entry",
+ ["channel", "updated"], ["updated"],
+ "maker.item", ["updated"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.updated = nil
+ maker.items.first.updated = nil
+ end
+
+ assert_maker_atom_date_construct("entry",
+ ["items", "first", "updated"],
+ ["updated"],
+ "maker.item", ["updated"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.updated = nil
+ maker.items.first.updated = nil
+ end
+
+ assert_maker_atom_date_construct("entry",
+ ["items", "first", "source", "updated"],
+ ["source", "updated"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_date
+ date = Time.parse("2004/11/1 10:10")
+ feed = Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.channel.date = nil
+ maker.items.new_item do |item|
+ item.link = "http://example.com/article.html"
+ item.title = "Sample Article"
+ item.date = date
+ end
+ end
+ assert_equal(date, feed.items[0].updated.content)
+ assert_equal([date], feed.items[0].dc_dates.collect {|_date| _date.value})
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_atom_feed.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_atom_feed.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_atom_feed.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,454 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerAtomFeed < TestCase
+ def test_supported?
+ assert(RSS::Maker.supported?("atom"))
+ assert(RSS::Maker.supported?("atom:feed"))
+ assert(RSS::Maker.supported?("atom1.0"))
+ assert(RSS::Maker.supported?("atom1.0:feed"))
+ assert(!RSS::Maker.supported?("atom2.0"))
+ assert(!RSS::Maker.supported?("atom2.0:feed"))
+ end
+
+ def test_find_class
+ assert_equal(RSS::Maker::Atom::Feed, RSS::Maker["atom"])
+ assert_equal(RSS::Maker::Atom::Feed, RSS::Maker["atom:feed"])
+ assert_equal(RSS::Maker::Atom::Feed, RSS::Maker["atom1.0"])
+ assert_equal(RSS::Maker::Atom::Feed, RSS::Maker["atom1.0:feed"])
+ end
+
+ def test_root_element
+ feed = Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+ assert_equal(["atom", "1.0", "feed"], feed.feed_info)
+
+ feed = Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.encoding = "EUC-JP"
+ end
+ assert_equal(["atom", "1.0", "feed"], feed.feed_info)
+ assert_equal("EUC-JP", feed.encoding)
+
+ feed = Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.standalone = "yes"
+ end
+ assert_equal(["atom", "1.0", "feed"], feed.feed_info)
+ assert_equal("yes", feed.standalone)
+
+ feed = Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.encoding = "EUC-JP"
+ maker.standalone = "yes"
+ end
+ assert_equal(["atom", "1.0", "feed"], feed.feed_info)
+ assert_equal("EUC-JP", feed.encoding)
+ assert_equal("yes", feed.standalone)
+ end
+
+ def test_invalid_feed
+ assert_not_set_error("maker.channel", %w(id title author updated)) do
+ Maker.make("atom") do |maker|
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(id title updated)) do
+ Maker.make("atom") do |maker|
+ maker.channel.author = "foo"
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(title updated)) do
+ Maker.make("atom") do |maker|
+ maker.channel.author = "foo"
+ maker.channel.id = "http://example.com"
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(updated)) do
+ Maker.make("atom") do |maker|
+ maker.channel.author = "foo"
+ maker.channel.id = "http://example.com"
+ maker.channel.title = "Atom Feed"
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(author)) do
+ Maker.make("atom") do |maker|
+ maker.channel.id = "http://example.com"
+ maker.channel.title = "Atom Feed"
+ maker.channel.updated = Time.now
+ end
+ end
+
+ feed = Maker.make("atom") do |maker|
+ maker.channel.author = "Foo"
+ maker.channel.id = "http://example.com"
+ maker.channel.title = "Atom Feed"
+ maker.channel.updated = Time.now
+ end
+ assert_not_nil(feed)
+ end
+
+ def test_author
+ assert_maker_atom_persons("feed",
+ ["channel", "authors"],
+ ["authors"],
+ "maker.channel.author") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_not_set_error("maker.channel", %w(author)) do
+ RSS::Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.authors.clear
+ end
+ end
+
+ assert_maker_atom_persons("feed",
+ ["items", "first", "authors"],
+ ["entries", "first", "authors"],
+ "maker.item.author") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_persons("feed",
+ ["items", "first", "source", "authors"],
+ ["entries", "first", "source", "authors"],
+ "maker.item.source.author") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_category
+ assert_maker_atom_categories("feed",
+ ["channel", "categories"],
+ ["categories"],
+ "maker.channel.category") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_categories("feed",
+ ["items", "first", "categories"],
+ ["entries", "first", "categories"],
+ "maker.item.category") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_categories("feed",
+ ["items", "first", "source", "categories"],
+ ["entries", "first", "source", "categories"],
+ "maker.item.source.category") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_contributor
+ assert_maker_atom_persons("feed",
+ ["channel", "contributors"],
+ ["contributors"],
+ "maker.channel.contributor") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_persons("feed",
+ ["items", "first", "contributors"],
+ ["entries", "first", "contributors"],
+ "maker.item.contributor") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_persons("feed",
+ ["items", "first", "source", "contributors"],
+ ["entries", "first", "source", "contributors"],
+ "maker.item.source.contributor") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_generator
+ assert_maker_atom_generator("feed",
+ ["channel", "generator"],
+ ["generator"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_generator("feed",
+ ["items", "first", "source", "generator"],
+ ["entries", "first", "source", "generator"],
+ "maker.item.source.generator") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_icon
+ assert_maker_atom_icon("feed", ["channel"], ["icon"], "icon") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_icon("feed",
+ ["items", "first", "source", "icon"],
+ ["entries", "first", "source", "icon"],
+ nil, "maker.item.source.icon") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_link
+ assert_maker_atom_links("feed",
+ ["channel", "links"],
+ ["links"],
+ "maker.channel.link") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_links("feed",
+ ["items", "first", "links"],
+ ["entries", "first", "links"],
+ "maker.item.link") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_links("feed",
+ ["items", "first", "source", "links"],
+ ["entries", "first", "source", "links"],
+ "maker.item.source.link", true) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_logo
+ assert_maker_atom_logo("feed", ["channel"], ["logo"], "logo") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_logo("feed", ["image"], ["logo"], "url") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_logo("feed",
+ ["items", "first", "source", "logo"],
+ ["entries", "first", "source", "logo"],
+ nil, "maker.item.source.logo") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_rights
+ assert_maker_atom_text_construct("feed",
+ ["channel", "copyright"],
+ ["rights"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_text_construct("feed",
+ ["items", "first", "rights"],
+ ["entries", "first", "rights"],
+ nil, nil, "maker.item.rights"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_text_construct("feed",
+ ["items", "first", "source", "rights"],
+ ["entries", "first", "source", "rights"],
+ nil, nil, "maker.item.source.rights"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_subtitle
+ assert_maker_atom_text_construct("feed",
+ ["channel", "subtitle"],
+ ["subtitle"],
+ nil, nil,
+ "maker.channel.description") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.channel.description = nil
+ end
+
+ assert_maker_atom_text_construct("feed",
+ ["channel", "subtitle"],
+ ["subtitle"],
+ nil, nil,
+ "maker.channel.description") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.channel.description {|d| d.content = nil}
+ end
+
+ assert_maker_atom_text_construct("feed",
+ ["items", "first", "source", "subtitle"],
+ ["entries", "first",
+ "source", "subtitle"],
+ nil, nil,
+ "maker.item.source.subtitle") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_title
+ assert_maker_atom_text_construct("feed",
+ ["channel", "title"], ["title"],
+ "maker.channel", ["title"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.channel.title = nil
+ end
+
+ assert_maker_atom_text_construct("feed",
+ ["items", "first", "title"],
+ ["entries", "first", "title"],
+ "maker.item", ["title"],
+ "maker.item.title") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.items.first.title = nil
+ end
+
+ assert_maker_atom_text_construct("feed",
+ ["items", "first", "source", "title"],
+ ["entries", "first", "source", "title"],
+ nil, nil, "maker.item.source.title"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_updated
+ assert_maker_atom_date_construct("feed",
+ ["channel", "updated"], ["updated"],
+ "maker.channel", ["updated"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.channel.updated = nil
+ end
+
+ assert_maker_atom_date_construct("feed",
+ ["items", "first", "updated"],
+ ["entries", "first", "updated"],
+ "maker.item", ["updated"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.items.first.updated = nil
+ end
+
+ assert_maker_atom_date_construct("feed",
+ ["items", "first", "source", "updated"],
+ ["entries", "first", "source", "updated"]
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_published
+ assert_maker_atom_date_construct("feed",
+ ["items", "first", "published"],
+ ["entries", "first", "published"]
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_summary
+ assert_maker_atom_text_construct("feed",
+ ["items", "first", "description"],
+ ["entries", "first", "summary"],
+ nil, nil, "maker.item.description"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_content
+ assert_maker_atom_content("feed",
+ ["items", "first", "content"],
+ ["entries", "first", "content"],
+ "maker.item.content") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_id
+ assert_maker_atom_id("feed",
+ ["items", "first", "source"],
+ ["entries", "first", "source"],
+ "maker.item.source") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_language
+ language = "ja"
+ feed = Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.channel.language = "ja"
+ end
+ assert_equal(language, feed.dc_language)
+ end
+
+ def test_date
+ date = Time.parse("2004/11/1 10:10")
+ feed = Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.items.new_item do |item|
+ item.link = "http://example.com/article.html"
+ item.title = "sample article"
+ item.date = date
+ end
+ end
+ assert_equal(date, feed.items[0].updated.content)
+ assert_equal([date], feed.items[0].dc_dates.collect {|_date| _date.value})
+ end
+
+ def test_channel_dc_date
+ date = Time.parse("2004/11/1 10:10")
+ feed = Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.channel.updated = nil
+ maker.channel.dc_date = date
+ setup_dummy_item_atom(maker)
+ end
+ assert_equal(date, feed.updated.content)
+ assert_equal([date], feed.dc_dates.collect {|_date| _date.value})
+ end
+
+ def test_item_dc_date
+ date = Time.parse("2004/11/1 10:10")
+ feed = Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.items.new_item do |item|
+ item.link = "http://example.com/article.html"
+ item.title = "sample article"
+ item.dc_date = date
+ end
+ end
+ assert_equal(date, feed.items[0].updated.content)
+ assert_equal([date], feed.items[0].dc_dates.collect {|_date| _date.value})
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_content.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_content.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_content.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,47 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerContent < TestCase
+
+ def setup
+ @uri = "http://purl.org/rss/1.0/modules/content/"
+
+ @elements = {
+ :encoded => "<em>ATTENTION</em>",
+ }
+ end
+
+ def test_rss10
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ setup_dummy_item(maker)
+ item = maker.items.last
+ @elements.each do |name, value|
+ item.__send__("#{accessor_name(name)}=", value)
+ end
+ end
+ assert_content(@elements, rss.items.last)
+ end
+
+ def test_rss20
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ setup_dummy_item(maker)
+ item = maker.items.last
+ @elements.each do |name, value|
+ item.__send__("#{accessor_name(name)}=", value)
+ end
+ end
+ assert_content(@elements, rss.items.last)
+ end
+
+ private
+ def accessor_name(name)
+ "content_#{name}"
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_dc.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_dc.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_dc.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,149 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerDublinCore < TestCase
+
+ def setup
+ @uri = "http://purl.org/dc/elements/1.1/"
+
+ t = Time.iso8601("2000-01-01T12:00:05+00:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+
+ @elements = {
+ :title => "hoge",
+ :description =>
+ " XML is placing increasingly heavy loads on
+ the existing technical infrastructure of the Internet.",
+ :creator => "Rael Dornfest (mailto:rael at oreilly.com)",
+ :subject => "XML",
+ :publisher => "The O'Reilly Network",
+ :contributor => "hogehoge",
+ :type => "fugafuga",
+ :format => "hohoho",
+ :identifier => "fufufu",
+ :source => "barbar",
+ :language => "ja",
+ :relation => "cococo",
+ :rights => "Copyright (c) 2000 O'Reilly & Associates, Inc.",
+ :date => t,
+ }
+ end
+
+ def test_rss10
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ set_elements(maker.channel)
+
+ setup_dummy_image(maker)
+ set_elements(maker.image)
+
+ setup_dummy_item(maker)
+ item = maker.items.last
+ @elements.each do |name, value|
+ item.__send__("#{accessor_name(name)}=", value)
+ end
+
+ setup_dummy_textinput(maker)
+ set_elements(maker.textinput)
+ end
+ assert_dublin_core(@elements, rss.channel)
+ assert_dublin_core(@elements, rss.image)
+ assert_dublin_core(@elements, rss.items.last)
+ assert_dublin_core(@elements, rss.textinput)
+ end
+
+ def test_rss10_multiple
+ assert_multiple_dublin_core_rss10("_list")
+ assert_multiple_dublin_core_rss10("es")
+ end
+
+ def assert_multiple_dublin_core_rss10(multiple_rights_suffix)
+ elems = []
+ @elements.each do |name, value|
+ plural = name.to_s + (name == :rights ? multiple_rights_suffix : "s")
+ values = [value]
+ if name == :date
+ values << value + 60
+ else
+ values << value * 2
+ end
+ elems << [name, values, plural]
+ end
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ set_multiple_elements(maker.channel, elems)
+
+ setup_dummy_image(maker)
+ set_multiple_elements(maker.image, elems)
+
+ setup_dummy_item(maker)
+ item = maker.items.last
+ elems.each do |name, values, plural|
+ dc_elems = item.__send__("dc_#{plural}")
+ values.each do |value|
+ elem = dc_elems.__send__("new_#{name}")
+ elem.value = value
+ end
+ end
+
+ setup_dummy_textinput(maker)
+ set_multiple_elements(maker.textinput, elems)
+ end
+ assert_multiple_dublin_core(elems, rss.channel)
+ assert_multiple_dublin_core(elems, rss.image)
+ assert_multiple_dublin_core(elems, rss.items.last)
+ assert_multiple_dublin_core(elems, rss.textinput)
+ end
+
+ def test_date
+ t1 = Time.iso8601("2000-01-01T12:00:05+00:00")
+ t2 = Time.iso8601("2005-01-01T12:00:05+00:00")
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.date = t1
+ maker.channel.dc_dates.new_date do |date|
+ date.value = t2
+ end
+
+ setup_dummy_item(maker)
+ item = maker.items.last
+ item.date = t2
+ item.dc_dates.new_date do |date|
+ date.value = t1
+ end
+ end
+ assert_equal([t1, t2], rss.channel.dc_dates.collect{|x| x.value})
+ assert_equal([t2, t1], rss.items.last.dc_dates.collect{|x| x.value})
+ end
+
+ private
+ def accessor_name(name)
+ "dc_#{name}"
+ end
+
+ def set_elements(target, elems=@elements)
+ elems.each do |name, value|
+ target.__send__("#{accessor_name(name)}=", value)
+ end
+ end
+
+ def set_multiple_elements(target, elems)
+ elems.each do |name, values, plural|
+ plural ||= "#{name}s"
+ dc_elems = target.__send__("dc_#{plural}")
+ values.each do |value|
+ dc_elems.__send__("new_#{name}") do |new_dc_elem|
+ new_dc_elem.value = value
+ end
+ end
+ end
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_image.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_image.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_image.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,62 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerImage < TestCase
+
+ def setup
+ @uri = "http://web.resource.org/rss/1.0/modules/image/"
+
+ @favicon_infos = {
+ "about" => "http://www.kuro5hin.org/favicon.ico",
+ "image_size" => "small",
+ "dc_title" => "example",
+ }
+ @item_infos = {
+ "about" => "http://www.example.org/item.png",
+ "resource" => "http://www.example.org/item",
+ "dc_title" => "Example Image",
+ "image_width" => "100",
+ "image_height" => "65",
+ }
+ end
+
+ def test_rss10
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ @favicon_infos.each do |name, value|
+ maker.channel.image_favicon.__send__("#{name}=", value)
+ end
+
+ setup_dummy_image(maker)
+
+ setup_dummy_item(maker)
+ item = maker.items.last
+ @item_infos.each do |name, value|
+ item.image_item.__send__("#{name}=", value)
+ end
+
+ setup_dummy_textinput(maker)
+ end
+
+ setup_rss = RSS::Maker.make("1.0") do |maker|
+ rss.setup_maker(maker)
+ end
+
+ [rss, setup_rss].each_with_index do |target, i|
+ favicon = target.channel.image_favicon
+ assert_equal(@favicon_infos["about"], favicon.about)
+ assert_equal(@favicon_infos["image_size"], favicon.image_size)
+ assert_equal(@favicon_infos["dc_title"], favicon.dc_title)
+
+ item = target.items.last.image_item
+ assert_equal(@item_infos["about"], item.about)
+ assert_equal(@item_infos["resource"], item.resource)
+ assert_equal(@item_infos["image_width"].to_i, item.image_width)
+ assert_equal(@item_infos["image_height"].to_i, item.image_height)
+ assert_equal(@item_infos["dc_title"], item.dc_title)
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_itunes.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_itunes.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_itunes.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,471 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerITunes < TestCase
+ def test_author
+ assert_maker_itunes_author(%w(channel))
+ assert_maker_itunes_author(%w(items last))
+ end
+
+ def test_block
+ assert_maker_itunes_block(%w(channel))
+ assert_maker_itunes_block(%w(items last))
+ end
+
+ def test_category
+ assert_maker_itunes_category(%w(channel))
+ end
+
+ def test_image
+ assert_maker_itunes_image(%w(channel))
+ end
+
+ def test_duration
+ assert_maker_itunes_duration(%w(items last))
+ end
+
+ def test_explicit
+ assert_maker_itunes_explicit(%w(channel))
+ assert_maker_itunes_explicit(%w(items last))
+ end
+
+ def test_keywords
+ assert_maker_itunes_keywords(%w(channel))
+ assert_maker_itunes_keywords(%w(items last))
+ end
+
+ def test_new_feed_url
+ assert_maker_itunes_new_feed_url(%w(channel))
+ end
+
+ def test_owner
+ assert_maker_itunes_owner(%w(channel))
+ end
+
+ def test_subtitle
+ assert_maker_itunes_subtitle(%w(channel))
+ assert_maker_itunes_subtitle(%w(items last))
+ end
+
+ def test_summary
+ assert_maker_itunes_summary(%w(channel))
+ assert_maker_itunes_summary(%w(items last))
+ end
+
+ private
+
+ def assert_maker_itunes_author(maker_readers, feed_readers=nil)
+ _wrap_assertion do
+ feed_readers ||= maker_readers
+ author = "John Doe"
+ rss20 = ::RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ target = chain_reader(maker, maker_readers)
+ target.itunes_author = author
+ end
+ target = chain_reader(rss20, feed_readers)
+ assert_equal(author, target.itunes_author)
+ end
+ end
+
+ def _assert_maker_itunes_block(value, boolean_value, maker_readers,
+ feed_readers)
+ rss20 = ::RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ target = chain_reader(maker, maker_readers)
+ target.itunes_block = value
+ assert_equal(value, target.itunes_block)
+ assert_equal(boolean_value, target.itunes_block?)
+ end
+ target = chain_reader(rss20, feed_readers)
+ if [true, false].include?(value)
+ feed_expected_value = value = value ? "yes" : "no"
+ else
+ feed_expected_value = value
+ end
+ assert_equal(value, target.itunes_block)
+ assert_equal(boolean_value, target.itunes_block?)
+ end
+
+ def assert_maker_itunes_block(maker_readers, feed_readers=nil)
+ _wrap_assertion do
+ feed_readers ||= maker_readers
+ _assert_maker_itunes_block("yes", true, maker_readers, feed_readers)
+ _assert_maker_itunes_block("Yes", true, maker_readers, feed_readers)
+ _assert_maker_itunes_block("no", false, maker_readers, feed_readers)
+ _assert_maker_itunes_block("", false, maker_readers, feed_readers)
+ _assert_maker_itunes_block(true, true, maker_readers, feed_readers)
+ _assert_maker_itunes_block(false, false, maker_readers, feed_readers)
+ _assert_maker_itunes_block(nil, false, maker_readers, feed_readers)
+ end
+ end
+
+ def _assert_maker_itunes_category(categories, maker_readers, feed_readers)
+ rss20 = ::RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ target = chain_reader(maker, maker_readers)
+ categories.each do |category|
+ sub_target = target.itunes_categories
+ if category.is_a?(Array)
+ category.each do |sub_category|
+ sub_target = sub_target.new_category
+ sub_target.text = sub_category
+ end
+ else
+ sub_target.new_category.text = category
+ end
+ end
+ end
+
+ target = chain_reader(rss20, feed_readers)
+ actual_categories = target.itunes_categories.collect do |category|
+ cat = category.text
+ if category.itunes_categories.empty?
+ cat
+ else
+ [cat, *category.itunes_categories.collect {|c| c.text}]
+ end
+ end
+ assert_equal(categories, actual_categories)
+ end
+
+ def assert_maker_itunes_category(maker_readers, feed_readers=nil)
+ _wrap_assertion do
+ feed_readers ||= maker_readers
+ _assert_maker_itunes_category(["Audio Blogs"],
+ maker_readers, feed_readers)
+ _assert_maker_itunes_category([["Arts & Entertainment", "Games"]],
+ maker_readers, feed_readers)
+ _assert_maker_itunes_category([["Arts & Entertainment", "Games"],
+ ["Technology", "Computers"],
+ "Audio Blogs"],
+ maker_readers, feed_readers)
+ end
+ end
+
+ def assert_maker_itunes_image(maker_readers, feed_readers=nil)
+ _wrap_assertion do
+ feed_readers ||= maker_readers
+ url = "http://example.com/podcasts/everything/AllAboutEverything.jpg"
+
+ rss20 = ::RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ target = chain_reader(maker, maker_readers)
+ target.itunes_image = url
+ end
+
+ target = chain_reader(rss20, feed_readers)
+ assert_not_nil(target.itunes_image)
+ assert_equal(url, target.itunes_image.href)
+ end
+ end
+
+ def _assert_maker_itunes_duration(hour, minute, second, value,
+ maker_readers, feed_readers)
+ _assert_maker_itunes_duration_by_value(hour, minute, second, value,
+ maker_readers, feed_readers)
+ _assert_maker_itunes_duration_by_hour_minute_second(hour, minute, second,
+ value,
+ maker_readers,
+ feed_readers)
+ end
+
+ def _assert_maker_itunes_duration_by(hour, minute, second, value,
+ maker_readers, feed_readers)
+ expected_value = nil
+ rss20 = ::RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ target = chain_reader(maker, maker_readers)
+ expected_value = yield(target)
+ assert_equal(expected_value, target.itunes_duration)
+ target.itunes_duration do |duration|
+ assert_equal([hour, minute, second, expected_value],
+ [duration.hour, duration.minute,
+ duration.second, duration.content])
+ end
+ end
+ target = chain_reader(rss20, feed_readers)
+ duration = target.itunes_duration
+ assert_not_nil(duration)
+ assert_equal([hour, minute, second, expected_value],
+ [duration.hour, duration.minute,
+ duration.second, duration.content])
+ end
+
+ def _assert_maker_itunes_duration_by_value(hour, minute, second, value,
+ maker_readers, feed_readers)
+ _assert_maker_itunes_duration_by(hour, minute, second, value,
+ maker_readers, feed_readers) do |target|
+ target.itunes_duration = value
+ value
+ end
+ end
+
+ def _assert_maker_itunes_duration_by_hour_minute_second(hour, minute, second,
+ value,
+ maker_readers,
+ feed_readers)
+ _assert_maker_itunes_duration_by(hour, minute, second, value,
+ maker_readers, feed_readers) do |target|
+ target.itunes_duration do |duration|
+ duration.hour = hour
+ duration.minute = minute
+ duration.second = second
+ end
+ value.split(":").collect {|v| "%02d" % v.to_i}.join(":")
+ end
+ end
+
+ def _assert_maker_itunes_duration_invalid_value(value, maker_readers)
+ assert_raise(ArgumentError) do
+ ::RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ target = chain_reader(maker, maker_readers)
+ target.itunes_duration = value
+ end
+ end
+ end
+
+ def assert_maker_itunes_duration(maker_readers, feed_readers=nil)
+ _wrap_assertion do
+ feed_readers ||= maker_readers
+ _assert_maker_itunes_duration(7, 14, 5, "07:14:05", maker_readers,
+ feed_readers)
+ _assert_maker_itunes_duration(7, 14, 5, "7:14:05", maker_readers,
+ feed_readers)
+ _assert_maker_itunes_duration(0, 4, 55, "04:55", maker_readers,
+ feed_readers)
+ _assert_maker_itunes_duration(0, 4, 5, "4:05", maker_readers,
+ feed_readers)
+
+ _assert_maker_itunes_duration_invalid_value("5", maker_readers)
+ _assert_maker_itunes_duration_invalid_value("09:07:14:05", maker_readers)
+ _assert_maker_itunes_duration_invalid_value("10:5", maker_readers)
+ _assert_maker_itunes_duration_invalid_value("10:03:5", maker_readers)
+ _assert_maker_itunes_duration_invalid_value("10:3:05", maker_readers)
+
+ _assert_maker_itunes_duration_invalid_value("xx:xx:xx", maker_readers)
+ end
+ end
+
+ def _assert_maker_itunes_explicit(explicit, value,
+ maker_readers, feed_readers)
+ rss20 = ::RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ target = chain_reader(maker, maker_readers)
+ target.itunes_explicit = value
+ assert_equal(explicit, target.itunes_explicit?)
+ end
+ target = chain_reader(rss20, feed_readers)
+ assert_equal(value, target.itunes_explicit)
+ assert_equal(explicit, target.itunes_explicit?)
+ end
+
+ def assert_maker_itunes_explicit(maker_readers, feed_readers=nil)
+ _wrap_assertion do
+ feed_readers ||= maker_readers
+ _assert_maker_itunes_explicit(true, "yes", maker_readers, feed_readers)
+ _assert_maker_itunes_explicit(false, "clean",
+ maker_readers, feed_readers)
+ _assert_maker_itunes_explicit(nil, "no", maker_readers, feed_readers)
+ end
+ end
+
+ def _assert_maker_itunes_keywords(keywords, value,
+ maker_readers, feed_readers)
+ _assert_maker_itunes_keywords_by_value(keywords, value,
+ maker_readers, feed_readers)
+ _assert_maker_itunes_keywords_by_keywords(keywords, maker_readers,
+ feed_readers)
+ end
+
+ def _assert_maker_itunes_keywords_by(keywords, maker_readers, feed_readers)
+ rss20 = ::RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ target = chain_reader(maker, maker_readers)
+ yield(target)
+ end
+ assert_nothing_raised do
+ rss20 = ::RSS::Parser.parse(rss20.to_s)
+ end
+ target = chain_reader(rss20, feed_readers)
+ assert_equal(keywords, target.itunes_keywords)
+ end
+
+ def _assert_maker_itunes_keywords_by_value(keywords, value,
+ maker_readers, feed_readers)
+ _assert_maker_itunes_keywords_by(keywords, maker_readers,
+ feed_readers) do |target|
+ target.itunes_keywords = value
+ end
+ end
+
+ def _assert_maker_itunes_keywords_by_keywords(keywords,
+ maker_readers, feed_readers)
+ _assert_maker_itunes_keywords_by(keywords, maker_readers,
+ feed_readers) do |target|
+ target.itunes_keywords = keywords
+ end
+ end
+
+ def assert_maker_itunes_keywords(maker_readers, feed_readers=nil)
+ _wrap_assertion do
+ feed_readers ||= maker_readers
+ _assert_maker_itunes_keywords(["salt"], "salt",
+ maker_readers, feed_readers)
+ _assert_maker_itunes_keywords(["salt"], " salt ",
+ maker_readers, feed_readers)
+ _assert_maker_itunes_keywords(["salt", "pepper", "shaker", "exciting"],
+ "salt, pepper, shaker, exciting",
+ maker_readers, feed_readers)
+ _assert_maker_itunes_keywords(["metric", "socket", "wrenches",
+ "toolsalt"],
+ "metric, socket, wrenches, toolsalt",
+ maker_readers, feed_readers)
+ _assert_maker_itunes_keywords(["olitics", "red", "blue", "state"],
+ "olitics, red, blue, state",
+ maker_readers, feed_readers)
+ end
+ end
+
+ def assert_maker_itunes_new_feed_url(maker_readers, feed_readers=nil)
+ feed_readers ||= maker_readers
+ url = "http://newlocation.com/example.rss"
+
+ rss20 = ::RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ target = chain_reader(maker, maker_readers)
+ target.itunes_new_feed_url = url
+ end
+ target = chain_reader(rss20, feed_readers)
+ assert_equal(url, target.itunes_new_feed_url)
+ end
+
+ def _assert_maker_itunes_owner(name, email, maker_readers, feed_readers)
+ rss20 = ::RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ target = chain_reader(maker, maker_readers)
+ owner = target.itunes_owner
+ owner.itunes_name = name
+ owner.itunes_email = email
+ end
+ owner = chain_reader(rss20, feed_readers).itunes_owner
+ if name.nil? and email.nil?
+ assert_nil(owner)
+ else
+ assert_not_nil(owner)
+ assert_equal(name, owner.itunes_name)
+ assert_equal(email, owner.itunes_email)
+ end
+ end
+
+ def assert_maker_itunes_owner(maker_readers, feed_readers=nil)
+ _wrap_assertion do
+ feed_readers ||= maker_readers
+ _assert_maker_itunes_owner("John Doe", "john.doe at example.com",
+ maker_readers, feed_readers)
+
+ not_set_name = (["maker"] + maker_readers + ["itunes_owner"]).join(".")
+ assert_not_set_error(not_set_name, ["itunes_name"]) do
+ _assert_maker_itunes_owner(nil, "john.doe at example.com",
+ maker_readers, feed_readers)
+ end
+ assert_not_set_error(not_set_name, ["itunes_email"]) do
+ _assert_maker_itunes_owner("John Doe", nil,
+ maker_readers, feed_readers)
+ end
+
+ _assert_maker_itunes_owner(nil, nil, maker_readers, feed_readers)
+ end
+ end
+
+ def _assert_maker_itunes_subtitle(subtitle, maker_readers, feed_readers)
+ rss20 = ::RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ target = chain_reader(maker, maker_readers)
+ target.itunes_subtitle = subtitle
+ end
+
+ target = chain_reader(rss20, feed_readers)
+ assert_equal(subtitle, target.itunes_subtitle)
+ end
+
+ def assert_maker_itunes_subtitle(maker_readers, feed_readers=nil)
+ _wrap_assertion do
+ feed_readers ||= maker_readers
+ _assert_maker_itunes_subtitle("A show about everything",
+ maker_readers, feed_readers)
+ _assert_maker_itunes_subtitle("A short primer on table spices",
+ maker_readers, feed_readers)
+ _assert_maker_itunes_subtitle("Comparing socket wrenches is fun!",
+ maker_readers, feed_readers)
+ _assert_maker_itunes_subtitle("Red + Blue != Purple",
+ maker_readers, feed_readers)
+ end
+ end
+
+ def _assert_maker_itunes_summary(summary, maker_readers, feed_readers)
+ rss20 = ::RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ target = chain_reader(maker, maker_readers)
+ target.itunes_summary = summary
+ end
+
+ target = chain_reader(rss20, feed_readers)
+ assert_equal(summary, target.itunes_summary)
+ end
+
+ def assert_maker_itunes_summary(maker_readers, feed_readers=nil)
+ _wrap_assertion do
+ feed_readers ||= maker_readers
+ _assert_maker_itunes_summary("All About Everything is a show about " +
+ "everything. Each week we dive into any " +
+ "subject known to man and talk about it " +
+ "as much as we can. Look for our Podcast " +
+ "in the iTunes Music Store",
+ maker_readers, feed_readers)
+ _assert_maker_itunes_summary("This week we talk about salt and pepper " +
+ "shakers, comparing and contrasting pour " +
+ "rates, construction materials, and " +
+ "overall aesthetics. Come and join the " +
+ "party!",
+ maker_readers, feed_readers)
+ _assert_maker_itunes_summary("This week we talk about metric vs. old " +
+ "english socket wrenches. Which one is " +
+ "better? Do you really need both? Get " +
+ "all of your answers here.",
+ maker_readers, feed_readers)
+ _assert_maker_itunes_summary("This week we talk about surviving in a " +
+ "Red state if you're a Blue person. Or " +
+ "vice versa.",
+ maker_readers, feed_readers)
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_slash.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_slash.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_slash.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,37 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerSlash < TestCase
+ def setup
+ @elements = {
+ "section" => "articles",
+ "department" => "not-an-ocean-unless-there-are-lobsters",
+ "comments" => 177,
+ "hit_parades" => [177, 155, 105, 33, 6, 3, 0],
+ }
+ end
+
+ def test_rss10
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ setup_dummy_item(maker)
+ item = maker.items.last
+ @elements.each do |name, value|
+ item.send("slash_#{name}=", value)
+ end
+ end
+
+ item = rss.items.last
+ assert_not_nil(item)
+ assert_slash_elements(item)
+ end
+
+ private
+ def assert_slash_elements(target)
+ super(@elements, target)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_sy.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_sy.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_sy.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,44 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerSyndication < TestCase
+
+ def setup
+ @uri = "http://purl.org/rss/1.0/modules/syndication/"
+
+ t = Time.iso8601("2000-01-01T12:00:05+00:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+
+ @elements = {
+ :updatePeriod => "hourly",
+ :updateFrequency => "2",
+ :updateBase => t,
+ }
+ end
+
+ def test_rss10
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ set_elements(maker.channel)
+ setup_dummy_item(maker)
+ end
+ assert_syndication(@elements, rss.channel)
+ end
+
+ private
+ def accessor_name(name)
+ "sy_#{name}"
+ end
+
+ def set_elements(target)
+ @elements.each do |name, value|
+ target.__send__("#{accessor_name(name)}=", value)
+ end
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_taxo.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_taxo.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_taxo.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,81 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerTaxonomy < TestCase
+
+ def setup
+ @uri = "http://purl.org/rss/1.0/modules/taxonomy/"
+
+ @resources = [
+ "http://meerkat.oreillynet.com/?c=cat23",
+ "http://meerkat.oreillynet.com/?c=47",
+ "http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/",
+ ]
+
+ @topics = [
+ {
+ :link => "http://meerkat.oreillynet.com/?c=cat23",
+ :title => "Data: XML",
+ :description => "A Meerkat channel",
+ },
+ {
+ :link => "http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/",
+ :title => "XML",
+ :subject => "XML",
+ :description => "DMOZ category",
+ :topics => [
+ "http://meerkat.oreillynet.com/?c=cat23",
+ "http://dmoz.org/Computers/Data_Formats/Markup_Languages/SGML/",
+ "http://dmoz.org/Computers/Programming/Internet/",
+ ]
+ },
+ ]
+ end
+
+ def test_rss10
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ set_topics(maker.channel)
+
+ setup_dummy_item(maker)
+ set_topics(maker.items.last)
+
+ setup_taxo_topic(maker, @topics)
+ end
+ assert_equal(@resources, rss.channel.taxo_topics.resources)
+ assert_equal(@resources, rss.items.last.taxo_topics.resources)
+ assert_taxo_topic(@topics, rss)
+ end
+
+ def _test_date
+ t1 = Time.iso8601("2000-01-01T12:00:05+00:00")
+ t2 = Time.iso8601("2005-01-01T12:00:05+00:00")
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.date = t1
+ maker.channel.dc_dates.new_date do |date|
+ date.value = t2
+ end
+
+ setup_dummy_item(maker)
+ item = maker.items.last
+ item.date = t2
+ item.dc_dates.new_date do |date|
+ date.value = t1
+ end
+ end
+ assert_equal([t1, t2], rss.channel.dc_dates.collect{|x| x.value})
+ assert_equal([t2, t1], rss.items.last.dc_dates.collect{|x| x.value})
+ end
+
+ private
+ def set_topics(target, resources=@resources)
+ resources.each do |value|
+ target.taxo_topics << value
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_trackback.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_trackback.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_trackback.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,41 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerTrackBack < TestCase
+
+ def setup
+ @uri = "http://madskills.com/public/xml/rss/module/trackback/"
+
+ @elements = {
+ :ping => "http://bar.com/tb.cgi?tb_id=rssplustrackback",
+ :abouts => [
+ "http://foo.com/trackback/tb.cgi?tb_id=20020923",
+ "http://bar.com/trackback/tb.cgi?tb_id=20041114",
+ ],
+ }
+ end
+
+ def test_rss10
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ setup_dummy_item(maker)
+ item = maker.items.last
+ item.trackback_ping = @elements[:ping]
+ @elements[:abouts].each do |about|
+ item.trackback_abouts.new_about do |new_about|
+ new_about.value = about
+ end
+ end
+ end
+ assert_trackback(@elements, rss.items.last)
+ end
+
+ private
+ def accessor_name(name)
+ "trackback_#{name}"
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_maker_xml-stylesheet.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_maker_xml-stylesheet.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_maker_xml-stylesheet.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,83 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerXMLStyleSheet < TestCase
+
+ def test_xml_stylesheet
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+ end
+
+ xss = rss.xml_stylesheets.first
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+
+
+ href = 'http://example.com/index.xsl'
+ type = 'text/xsl'
+ rss = RSS::Maker.make("1.0") do |maker|
+ maker.xml_stylesheets.new_xml_stylesheet do |_xss|
+ _xss.href = href
+ end
+
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+ end
+
+ xss = rss.xml_stylesheets.first
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ end
+
+ def test_not_valid_xml_stylesheet
+ href = 'xss.XXX'
+ type = "text/xsl"
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ # xss.href = href
+ xss.type = type
+ end
+
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+ end
+ assert(rss.xml_stylesheets.empty?)
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ # xss.type = type
+ end
+
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+ end
+ assert(rss.xml_stylesheets.empty?)
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_parser.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_parser.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_parser.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,62 @@
+require "fileutils"
+
+require "rss-testcase"
+
+require "rss/1.0"
+require "rss/dublincore"
+
+module RSS
+ class TestParser < TestCase
+ def setup
+ @_default_parser = Parser.default_parser
+ @rss10 = make_RDF(<<-EOR)
+#{make_channel}
+#{make_item}
+#{make_textinput}
+#{make_image}
+EOR
+ @rss_file = "rss10.rdf"
+ File.open(@rss_file, "w") {|f| f.print(@rss10)}
+ end
+
+ def teardown
+ Parser.default_parser = @_default_parser
+ FileUtils.rm_f(@rss_file)
+ end
+
+ def test_default_parser
+ assert_nothing_raised do
+ Parser.default_parser = RSS::AVAILABLE_PARSERS.first
+ end
+
+ assert_raise(RSS::NotValidXMLParser) do
+ Parser.default_parser = RSS::Parser
+ end
+ end
+
+ def test_parse
+ assert_not_nil(RSS::Parser.parse(@rss_file))
+
+ garbage_rss_file = @rss_file + "-garbage"
+ if RSS::Parser.default_parser.name == "RSS::XMLParserParser"
+ assert_raise(RSS::NotWellFormedError) do
+ RSS::Parser.parse(garbage_rss_file)
+ end
+ else
+ assert_nil(RSS::Parser.parse(garbage_rss_file))
+ end
+ end
+
+ def test_parse_tag_includes_hyphen
+ assert_nothing_raised do
+ RSS::Parser.parse(make_RDF(<<-EOR))
+<xCal:x-calconnect-venue xmlns:xCal="urn:ietf:params:xml:ns:xcal" />
+#{make_channel}
+#{make_item}
+#{make_textinput}
+#{make_image}
+EOR
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_parser_1.0.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_parser_1.0.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_parser_1.0.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,528 @@
+require "rss-testcase"
+
+require "rss/1.0"
+require "rss/dublincore"
+
+module RSS
+ class TestParser10 < TestCase
+ def test_RDF
+ assert_ns("", RDF::URI) do
+ Parser.parse(<<-EOR)
+#{make_xmldecl}
+<RDF/>
+EOR
+ end
+
+ assert_ns("", RDF::URI) do
+ Parser.parse(<<-EOR)
+#{make_xmldecl}
+<RDF xmlns="hoge"/>
+EOR
+ end
+
+ assert_ns("rdf", RDF::URI) do
+ Parser.parse(<<-EOR)
+#{make_xmldecl}
+<rdf:RDF xmlns:rdf="hoge"/>
+EOR
+ end
+
+ assert_parse(<<-EOR, :missing_tag, "channel", "RDF")
+#{make_xmldecl}
+<rdf:RDF xmlns:rdf="#{RSS::RDF::URI}"/>
+EOR
+
+ assert_parse(<<-EOR, :missing_tag, "channel", "RDF")
+#{make_xmldecl}
+<RDF xmlns="#{RSS::RDF::URI}"/>
+EOR
+
+ assert_parse(<<-EOR, :missing_tag, "channel", "RDF")
+#{make_xmldecl}
+<RDF xmlns="#{RSS::RDF::URI}"/>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
+#{make_channel}
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
+#{make_channel}
+#{make_image}
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
+#{make_channel}
+#{make_textinput}
+EOR
+
+ assert_too_much_tag("image", "RDF") do
+ Parser.parse(make_RDF(<<-EOR))
+#{make_channel}
+#{make_image}
+#{make_image}
+#{make_item}
+#{make_textinput}
+EOR
+ end
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_item}
+#{make_image}
+#{make_textinput}
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_item}
+#{make_textinput}
+#{make_image}
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_image}
+#{make_item}
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_image}
+#{make_item}
+#{make_textinput}
+EOR
+
+ 1.step(15, 3) do |i|
+ rss = make_RDF() do
+ res = make_channel
+ i.times { res << make_item }
+ res
+ end
+ assert_parse(rss, :nothing_raised)
+ end
+ end
+
+ def test_undefined_entity
+ return unless RSS::Parser.default_parser.raise_for_undefined_entity?
+ assert_parse(make_RDF(<<-EOR), :raises, RSS::NotWellFormedError)
+#{make_channel}
+#{make_image}
+<item rdf:about="#{RDF_ABOUT}">
+ <title>#{TITLE_VALUE} &UNKNOWN_ENTITY;</title>
+ <link>#{LINK_VALUE}</link>
+ <description>#{DESCRIPTION_VALUE}</description>
+</item>
+#{make_textinput}
+EOR
+ end
+
+ def test_channel
+ assert_parse(make_RDF(<<-EOR), :missing_attribute, "channel", "rdf:about")
+<channel />
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "channel")
+<channel rdf:about="http://example.com/"/>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "channel")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+</channel>
+EOR
+
+ assert_parse(make_RDF(<<EOR), :missing_tag, "description", "channel")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+</channel>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "items", "channel")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+</channel>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_attribute, "image", "rdf:resource")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image/>
+</channel>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "items", "channel")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image rdf:resource="http://example.com/hoge.png" />
+</channel>
+EOR
+
+ rss = make_RDF(<<-EOR)
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image rdf:resource="http://example.com/hoge.png" />
+ <items/>
+</channel>
+EOR
+
+ assert_missing_tag("Seq", "items") do
+ Parser.parse(rss)
+ end
+
+ assert_missing_tag("item", "RDF") do
+ Parser.parse(rss, false).validate
+ end
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image rdf:resource="http://example.com/hoge.png" />
+ <items>
+ <rdf:Seq>
+ </rdf:Seq>
+ </items>
+</channel>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_attribute, "textinput", "rdf:resource")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image rdf:resource="http://example.com/hoge.png" />
+ <items>
+ <rdf:Seq>
+ </rdf:Seq>
+ </items>
+ <textinput/>
+</channel>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image rdf:resource="http://example.com/hoge.png" />
+ <items>
+ <rdf:Seq>
+ </rdf:Seq>
+ </items>
+ <textinput rdf:resource="http://example.com/search" />
+</channel>
+EOR
+ end
+
+ def test_rdf_li
+ rss = make_RDF(<<-EOR)
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image rdf:resource="http://example.com/hoge.png" />
+ <items>
+ <rdf:Seq>
+ <rdf:li \#{rdf_li_attr}/>
+ </rdf:Seq>
+ </items>
+ <textinput rdf:resource="http://example.com/search" />
+</channel>
+#{make_item}
+EOR
+
+ source = Proc.new do |rdf_li_attr|
+ eval(%Q[%Q[#{rss}]], binding)
+ end
+
+ attr = %q[resource="http://example.com/hoge"]
+ assert_parse(source.call(attr), :nothing_raised)
+
+ attr = %q[rdf:resource="http://example.com/hoge"]
+ assert_parse(source.call(attr), :nothing_raised)
+
+ assert_parse(source.call(""), :missing_attribute, "li", "resource")
+ end
+
+ def test_image
+ assert_parse(make_RDF(<<-EOR), :missing_attribute, "image", "rdf:about")
+#{make_channel}
+<image>
+</image>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "image")
+#{make_channel}
+<image rdf:about="http://example.com/hoge.png">
+</image>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "url", "image")
+#{make_channel}
+<image rdf:about="http://example.com/hoge.png">
+ <title>hoge</title>
+</image>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "image")
+#{make_channel}
+<image rdf:about="http://example.com/hoge.png">
+ <title>hoge</title>
+ <url>http://example.com/hoge.png</url>
+</image>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
+#{make_channel}
+<image rdf:about="http://example.com/hoge.png">
+ <title>hoge</title>
+ <url>http://example.com/hoge.png</url>
+ <link>http://example.com/</link>
+</image>
+EOR
+
+ rss = make_RDF(<<-EOR)
+#{make_channel}
+<image rdf:about="http://example.com/hoge.png">
+ <link>http://example.com/</link>
+ <url>http://example.com/hoge.png</url>
+ <title>hoge</title>
+</image>
+EOR
+
+ assert_missing_tag("item", "RDF") do
+ Parser.parse(rss)
+ end
+
+ assert_missing_tag("item", "RDF") do
+ Parser.parse(rss, false).validate
+ end
+ end
+
+ def test_item
+ assert_parse(make_RDF(<<-EOR), :missing_attribute, "item", "rdf:about")
+#{make_channel}
+#{make_image}
+<item>
+</item>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "item")
+#{make_channel}
+#{make_image}
+<item rdf:about="http://example.com/hoge.html">
+</item>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "item")
+#{make_channel}
+#{make_image}
+<item rdf:about="http://example.com/hoge.html">
+ <title>hoge</title>
+</item>
+EOR
+
+ assert_too_much_tag("title", "item") do
+ Parser.parse(make_RDF(<<-EOR))
+#{make_channel}
+#{make_image}
+<item rdf:about="http://example.com/hoge.html">
+ <title>hoge</title>
+ <title>hoge</title>
+ <link>http://example.com/hoge.html</link>
+</item>
+EOR
+ end
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_image}
+<item rdf:about="http://example.com/hoge.html">
+ <title>hoge</title>
+ <link>http://example.com/hoge.html</link>
+</item>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_image}
+<item rdf:about="http://example.com/hoge.html">
+ <title>hoge</title>
+ <link>http://example.com/hoge.html</link>
+ <description>hogehoge</description>
+</item>
+EOR
+ end
+
+ def test_textinput
+ assert_parse(make_RDF(<<-EOR), :missing_attribute, "textinput", "rdf:about")
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput>
+</textinput>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "textinput")
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput rdf:about="http://example.com/search.html">
+</textinput>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "description", "textinput")
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput rdf:about="http://example.com/search.html">
+ <title>hoge</title>
+</textinput>
+EOR
+
+ assert_too_much_tag("title", "textinput") do
+ Parser.parse(make_RDF(<<-EOR))
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput rdf:about="http://example.com/search.html">
+ <title>hoge</title>
+ <title>hoge</title>
+ <description>hogehoge</description>
+</textinput>
+EOR
+ end
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "name", "textinput")
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput rdf:about="http://example.com/search.html">
+ <title>hoge</title>
+ <description>hogehoge</description>
+</textinput>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "textinput")
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput rdf:about="http://example.com/search.html">
+ <title>hoge</title>
+ <description>hogehoge</description>
+ <name>key</name>
+</textinput>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput rdf:about="http://example.com/search.html">
+ <title>hoge</title>
+ <description>hogehoge</description>
+ <name>key</name>
+ <link>http://example.com/search.html</link>
+</textinput>
+EOR
+ end
+
+ def test_ignore
+ name = "a"
+ rss = make_RDF(<<-EOR)
+#{make_channel}
+#{make_item}
+<#{name}/>
+EOR
+ assert_not_expected_tag(name, ::RSS::URI, "RDF") do
+ Parser.parse(rss, true, false)
+ end
+
+ uri = ""
+ name = "a"
+ rss = make_RDF(<<-EOR)
+#{make_channel}
+#{make_item}
+<#{name} xmlns=""/>
+EOR
+ assert_parse(rss, :nothing_raised)
+ assert_not_expected_tag(name, uri, "RDF") do
+ Parser.parse(rss, true, false)
+ end
+
+ uri = "http://example.com/"
+ name = "a"
+ rss = make_RDF(<<-EOR)
+#{make_channel}
+#{make_item}
+<x:#{name} xmlns:x="#{uri}"/>
+EOR
+ assert_parse(rss, :nothing_raised)
+ assert_not_expected_tag(name, uri, "RDF") do
+ Parser.parse(rss, true, false)
+ end
+
+ uri = ::RSS::URI
+ name = "a"
+ rss = make_RDF(<<-EOR)
+#{make_channel}
+#{make_item}
+#{make_image("<#{name}/>")}
+EOR
+ assert_parse(rss, :nothing_raised)
+ assert_not_expected_tag(name, uri, "image") do
+ Parser.parse(rss, true, false)
+ end
+
+ uri = CONTENT_URI
+ name = "encoded"
+ elem = "<#{name} xmlns='#{uri}'/>"
+ rss = make_RDF(<<-EOR)
+#{make_channel}
+#{make_item}
+#{make_image(elem)}
+EOR
+ assert_parse(rss, :nothing_raised)
+ assert_not_expected_tag(name, uri, "image") do
+ Parser.parse(rss, true, false)
+ end
+ end
+
+ def test_unknown_duplicated_element
+ xmlns = {"test" => "http://localhost/test"}
+ assert_parse(make_RDF(<<-EOR, xmlns), :nothing_raised)
+ #{make_channel("<test:string/>")}
+ #{make_item}
+ #{make_image}
+ EOR
+ end
+
+ def test_unknown_case_insensitive_duplicated_element
+ xmlns = {
+ "foaf" => "http://xmlns.com/foaf/0.1/",
+ "dc" => "http://purl.org/dc/elements/1.1/",
+ }
+ assert_parse(make_RDF(<<-EOR, xmlns), :nothing_raised)
+ #{make_channel}
+ #{make_item}
+ #{make_image}
+ <foaf:Image rdf:about="http://example.com/myself.png">
+ <dc:title>Myself</dc:title>
+ <dc:link>http://example.com/</dc:link>
+ </foaf:Image>
+ EOR
+ end
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/rss/test_parser_2.0.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_parser_2.0.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_parser_2.0.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,122 @@
+require "rss-testcase"
+
+require "rss/2.0"
+
+module RSS
+ class TestParser20 < TestCase
+ def test_rss20
+ assert_parse(make_rss20(<<-EOR), :missing_tag, "channel", "rss")
+EOR
+
+ assert_parse(make_rss20(<<-EOR), :nothing_raised)
+#{make_channel20("")}
+EOR
+ end
+
+ def test_cloud20
+ attrs = [
+ ["domain", CLOUD_DOMAIN],
+ ["port", CLOUD_PORT],
+ ["path", CLOUD_PATH],
+ ["registerProcedure", CLOUD_REGISTER_PROCEDURE],
+ ["protocol", CLOUD_PROTOCOL],
+ ]
+
+ (attrs.size + 1).times do |i|
+ missing_attr = attrs[i]
+ if missing_attr
+ meth = :missing_attribute
+ args = ["cloud", missing_attr[0]]
+ else
+ meth = :nothing_raised
+ args = []
+ end
+
+ cloud_attrs = []
+ attrs.each_with_index do |attr, j|
+ unless i == j
+ cloud_attrs << %Q[#{attr[0]}="#{attr[1]}"]
+ end
+ end
+
+ assert_parse(make_rss20(<<-EOR), meth, *args)
+#{make_channel20(%Q[<cloud #{cloud_attrs.join("\n")}/>])}
+EOR
+ end
+ end
+
+ def test_source20
+ assert_parse(make_rss20(<<-EOR), :missing_attribute, "source", "url")
+#{make_channel20(make_item20(%Q[<source>Example</source>]))}
+EOR
+
+ assert_parse(make_rss20(<<-EOR), :nothing_raised)
+#{make_channel20(make_item20(%Q[<source url="http://example.com/" />]))}
+EOR
+
+ assert_parse(make_rss20(<<-EOR), :nothing_raised)
+#{make_channel20(make_item20(%Q[<source url="http://example.com/">Example</source>]))}
+EOR
+ end
+
+ def test_enclosure20
+ attrs = [
+ ["url", ENCLOSURE_URL],
+ ["length", ENCLOSURE_LENGTH],
+ ["type", ENCLOSURE_TYPE],
+ ]
+
+ (attrs.size + 1).times do |i|
+ missing_attr = attrs[i]
+ if missing_attr
+ meth = :missing_attribute
+ args = ["enclosure", missing_attr[0]]
+ else
+ meth = :nothing_raised
+ args = []
+ end
+
+ enclosure_attrs = []
+ attrs.each_with_index do |attr, j|
+ unless i == j
+ enclosure_attrs << %Q[#{attr[0]}="#{attr[1]}"]
+ end
+ end
+
+ assert_parse(make_rss20(<<-EOR), meth, *args)
+#{make_channel20(%Q[
+#{make_item20(%Q[
+<enclosure
+ #{enclosure_attrs.join("\n")} />
+ ])}
+ ])}
+EOR
+ end
+ end
+
+ def test_category20
+ values = [nil, CATEGORY_DOMAIN]
+ values.each do |value|
+ domain = ""
+ domain << %Q[domain="#{value}"] if value
+
+ ["", "Example Text"].each do |text|
+ rss_src = make_rss20(<<-EOR)
+#{make_channel20(%Q[
+#{make_item20(%Q[
+<category #{domain}>#{text}</category>
+ ])}
+ ])}
+EOR
+ assert_parse(rss_src, :nothing_raised)
+
+ rss = RSS::Parser.parse(rss_src)
+ category = rss.items.last.categories.first
+ assert_equal(value, category.domain)
+ assert_equal(text, category.content)
+ end
+ end
+ end
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/rss/test_parser_atom_entry.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_parser_atom_entry.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_parser_atom_entry.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,163 @@
+require "rss-testcase"
+
+require "rss/atom"
+
+module RSS
+ class TestParserAtom < TestCase
+ def test_entry_validation
+ assert_ns("", Atom::URI) do
+ Parser.parse(<<-EOA)
+<entry/>
+EOA
+ end
+
+ assert_ns("", Atom::URI) do
+ Parser.parse(<<-EOA)
+<entry xmlns="hoge"/>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "id", "entry") do
+<entry xmlns="#{Atom::URI}"/>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "title", "entry") do
+<entry xmlns="#{Atom::URI}">
+ <id>urn:uuid:506e336c-a26e-4457-917b-b89dca7ae746</id>
+</entry>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "updated", "entry") do
+<entry xmlns="#{Atom::URI}">
+ <id>urn:uuid:506e336c-a26e-4457-917b-b89dca7ae746</id>
+ <title>Example Entry</title>
+</entry>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "author", "entry") do
+<entry xmlns="#{Atom::URI}">
+ <id>urn:uuid:506e336c-a26e-4457-917b-b89dca7ae746</id>
+ <title>Example Entry</title>
+ <updated>2003-10-10T18:30:02Z</updated>
+</entry>
+EOA
+ end
+
+ assert_parse(<<-EOA, :nothing_raised) do
+<entry xmlns="#{Atom::URI}">
+ <id>urn:uuid:506e336c-a26e-4457-917b-b89dca7ae746</id>
+ <title>Example Entry</title>
+ <updated>2003-10-10T18:30:02Z</updated>
+ <author>
+ <name>A person</name>
+ </author>
+</entry>
+EOA
+ end
+ end
+
+ def test_entry
+ entry = RSS::Parser.parse(<<-EOA)
+<?xml version="1.0" encoding="utf-8"?>
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <author>
+ <name>A person</name>
+ </author>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+</entry>
+EOA
+ assert_not_nil(entry)
+ assert_equal("Atom-Powered Robots Run Amok", entry.title.content)
+ assert_equal("http://example.org/2003/12/13/atom03", entry.link.href)
+ assert_equal("urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a",
+ entry.id.content)
+ assert_equal(Time.parse("2003-12-13T18:30:02Z"), entry.updated.content)
+ assert_equal("Some text.", entry.summary.content)
+ end
+
+ def test_entry_author
+ assert_atom_person("author", method(:make_entry_document)) do |entry|
+ assert_equal(2, entry.authors.size)
+ entry.authors.last
+ end
+ end
+
+ def test_entry_category
+ assert_atom_category(method(:make_entry_document)) do |entry|
+ assert_equal(1, entry.categories.size)
+ entry.category
+ end
+ end
+
+ def test_entry_content_text
+ assert_atom_content(method(:make_entry_document)) do |entry|
+ entry.content
+ end
+ end
+
+ def test_entry_contributor
+ assert_atom_person("contributor", method(:make_entry_document)) do |entry|
+ assert_equal(1, entry.contributors.size)
+ entry.contributor
+ end
+ end
+
+ def test_entry_id
+ entry = RSS::Parser.parse(make_entry_document)
+ assert_equal(ENTRY_ID, entry.id.content)
+ end
+
+ def test_entry_link
+ assert_atom_link(method(:make_entry_document)) do |entry|
+ assert_equal(1, entry.links.size)
+ entry.link
+ end
+ end
+
+ def test_published
+ generator = method(:make_entry_document)
+ assert_atom_date_construct("published", generator) do |entry|
+ entry.published
+ end
+ end
+
+ def test_entry_rights
+ generator = method(:make_entry_document)
+ assert_atom_text_construct("rights", generator) do |entry|
+ entry.rights
+ end
+ end
+
+ def test_entry_source
+ generator = method(:make_entry_document_with_open_source)
+ assert_atom_source(generator) do |entry|
+ assert_not_nil(entry.source)
+ entry.source
+ end
+ end
+
+ def test_entry_summary
+ generator = method(:make_entry_document)
+ assert_atom_text_construct("summary", generator) do |entry|
+ entry.summary
+ end
+ end
+
+ def test_entry_title
+ entry = RSS::Parser.parse(make_entry_document)
+ assert_equal(ENTRY_TITLE, entry.title.content)
+ end
+
+ def test_entry_updated
+ entry = RSS::Parser.parse(make_entry_document)
+ assert_equal(Time.parse(ENTRY_UPDATED), entry.updated.content)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_parser_atom_feed.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_parser_atom_feed.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_parser_atom_feed.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,276 @@
+require "rss-testcase"
+
+require "rss/atom"
+
+module RSS
+ class TestParserAtomFeed < TestCase
+ def test_feed_validation
+ assert_ns("", Atom::URI) do
+ Parser.parse(<<-EOA)
+<feed/>
+EOA
+ end
+
+ assert_ns("", Atom::URI) do
+ Parser.parse(<<-EOA)
+<feed xmlns="hoge"/>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "id", "feed") do
+<feed xmlns="#{Atom::URI}"/>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "title", "feed") do
+<feed xmlns="#{Atom::URI}">
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+</feed>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "updated", "feed") do
+<feed xmlns="#{Atom::URI}">
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <title>Example Feed</title>
+</feed>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "author", "feed") do
+<feed xmlns="#{Atom::URI}">
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <title>Example Feed</title>
+ <updated>2003-12-13T18:30:02Z</updated>
+</feed>
+EOA
+ end
+
+ assert_parse(<<-EOA, :nothing_raised) do
+<feed xmlns="#{Atom::URI}">
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <title>Example Feed</title>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>A person</name>
+ </author>
+</feed>
+EOA
+ end
+ end
+
+ def test_lang
+ feed = RSS::Parser.parse(<<-EOA)
+<feed xmlns="#{Atom::URI}" xml:lang="ja">
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <title xml:lang="en">Example Feed</title>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author xml:lang="en">
+ <name>A person</name>
+ </author>
+</feed>
+EOA
+
+ assert_equal("ja", feed.lang)
+ assert_equal("ja", feed.id.lang)
+ assert_equal("en", feed.title.lang)
+ assert_equal("ja", feed.updated.lang)
+ assert_equal("en", feed.author.lang)
+ assert_equal("en", feed.author.name.lang)
+ end
+
+ def test_base
+ feed = RSS::Parser.parse(<<-EOA)
+<feed xmlns="#{Atom::URI}" xml:base="http://example.com/">
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <title xml:lang="en">Example Feed</title>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <generator uri="generator">Generator</generator>
+ <link hreflang="ja" href="http://example.org/link1"/>
+ <link hreflang="en" href="link2"/>
+ <link hreflang="fr" xml:base="http://example.net/" href="link3"/>
+ <author>
+ <name>A person</name>
+ <uri>person</uri>
+ </author>
+</feed>
+EOA
+
+ assert_equal("http://example.com/", feed.base)
+ assert_equal("http://example.com/", feed.id.base)
+ assert_equal("http://example.com/", feed.title.base)
+ assert_equal("http://example.com/", feed.updated.base)
+ assert_equal("http://example.com/", feed.generator.base)
+ assert_equal("http://example.com/generator", feed.generator.uri)
+
+ assert_equal("http://example.com/", feed.links[0].base)
+ assert_equal("http://example.org/link1", feed.links[0].href)
+ assert_equal("http://example.com/", feed.links[1].base)
+ assert_equal("http://example.com/link2", feed.links[1].href)
+ assert_equal("http://example.net/", feed.links[2].base)
+ assert_equal("http://example.net/link3", feed.links[2].href)
+ assert_equal("http://example.com/person", feed.author.uri.content)
+ end
+
+ def test_feed_author
+ assert_atom_person("author", method(:make_feed)) do |feed|
+ assert_equal(2, feed.authors.size)
+ feed.authors[1]
+ end
+ end
+
+ def test_entry_author
+ generator = method(:make_feed_with_open_entry)
+ assert_atom_person("author", generator) do |feed|
+ assert_equal(1, feed.entries.size)
+ assert_equal(1, feed.entry.authors.size)
+ feed.entry.author
+ end
+ end
+
+ def test_feed_category
+ assert_atom_category(method(:make_feed)) do |feed|
+ assert_equal(1, feed.categories.size)
+ feed.category
+ end
+ end
+
+ def test_entry_category
+ assert_atom_category(method(:make_feed_with_open_entry)) do |feed|
+ assert_equal(1, feed.entries.size)
+ assert_equal(1, feed.entry.categories.size)
+ feed.entry.category
+ end
+ end
+
+ def test_entry_content
+ assert_atom_content(method(:make_feed_with_open_entry)) do |feed|
+ assert_equal(1, feed.entries.size)
+ feed.entry.content
+ end
+ end
+
+ def test_feed_contributor
+ assert_atom_person("contributor", method(:make_feed)) do |feed|
+ assert_equal(1, feed.contributors.size)
+ feed.contributor
+ end
+ end
+
+ def test_entry_contributor
+ generator = method(:make_feed_with_open_entry)
+ assert_atom_person("contributor", generator) do |feed|
+ assert_equal(1, feed.entries.size)
+ assert_equal(1, feed.entry.contributors.size)
+ feed.entry.contributor
+ end
+ end
+
+ def test_feed_generator
+ assert_atom_generator(method(:make_feed)) do |feed|
+ feed.generator
+ end
+ end
+
+ def test_feed_icon
+ assert_atom_icon(method(:make_feed)) do |feed|
+ feed.icon
+ end
+ end
+
+ def test_feed_id
+ feed = RSS::Parser.parse(make_feed(''))
+ assert_equal(FEED_ID, feed.id.content)
+ end
+
+ def test_entry_id
+ feed = RSS::Parser.parse(make_feed(''))
+ assert_equal(ENTRY_ID, feed.entry.id.content)
+ end
+
+ def test_feed_link
+ assert_atom_link(method(:make_feed)) do |feed|
+ assert_equal(1, feed.links.size)
+ feed.link
+ end
+ end
+
+ def test_entry_link
+ assert_atom_link(method(:make_feed_with_open_entry)) do |feed|
+ assert_equal(1, feed.entries.size)
+ assert_equal(1, feed.entry.links.size)
+ feed.entry.link
+ end
+ end
+
+ def test_feed_logo
+ assert_atom_logo(method(:make_feed)) do |feed|
+ feed.logo
+ end
+ end
+
+ def test_feed_rights
+ assert_atom_text_construct("rights", method(:make_feed)) do |feed|
+ feed.rights
+ end
+ end
+
+ def test_entry_rights
+ generator = method(:make_feed_with_open_entry)
+ assert_atom_text_construct("rights", generator) do |feed|
+ assert_equal(1, feed.entries.size)
+ feed.entry.rights
+ end
+ end
+
+ def test_entry_source
+ assert_atom_source(method(:make_feed_with_open_entry_source)) do |feed|
+ assert_equal(1, feed.entries.size)
+ assert_not_nil(feed.entry.source)
+ feed.entry.source
+ end
+ end
+
+ def test_feed_subtitle
+ assert_atom_text_construct("subtitle", method(:make_feed)) do |feed|
+ feed.subtitle
+ end
+ end
+
+ def test_feed_title
+ feed = RSS::Parser.parse(make_feed(''))
+ assert_equal(FEED_TITLE, feed.title.content)
+ end
+
+ def test_entry_title
+ feed = RSS::Parser.parse(make_feed(''))
+ assert_equal(ENTRY_TITLE, feed.entry.title.content)
+ end
+
+ def test_feed_updated
+ feed = RSS::Parser.parse(make_feed(''))
+ assert_equal(Time.parse(FEED_UPDATED), feed.updated.content)
+ end
+
+ def test_entry_updated
+ feed = RSS::Parser.parse(make_feed(''))
+ assert_equal(Time.parse(ENTRY_UPDATED), feed.entry.updated.content)
+ end
+
+ def test_entry_published
+ generator = method(:make_feed_with_open_entry)
+ assert_atom_date_construct("published", generator) do |feed|
+ assert_equal(1, feed.entries.size)
+ feed.entry.published
+ end
+ end
+
+ def test_entry_summary
+ generator = method(:make_feed_with_open_entry)
+ assert_atom_text_construct("summary", generator) do |feed|
+ assert_equal(1, feed.entries.size)
+ feed.entry.summary
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_0.9.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_0.9.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_0.9.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,246 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestSetupMaker09 < TestCase
+
+ def test_setup_maker_channel
+ title = "fugafuga"
+ link = "http://hoge.com"
+ description = "fugafugafugafuga"
+ language = "ja"
+ copyright = "foo"
+ managingEditor = "bar"
+ webMaster = "web master"
+ rating = '(PICS-1.1 "http://www.rsac.org/ratingsv01.html" l gen true comment "RSACi North America Server" for "http://www.rsac.org" on "1996.04.16T08:15-0500" r (n 0 s 0 v 0 l 0))'
+ docs = "http://foo.com/doc"
+ skipDays = [
+ "Sunday",
+ "Monday",
+ ]
+ skipHours = [
+ "0",
+ "13",
+ ]
+ pubDate = Time.now
+ lastBuildDate = Time.now
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+ maker.channel.language = language
+ maker.channel.copyright = copyright
+ maker.channel.managingEditor = managingEditor
+ maker.channel.webMaster = webMaster
+ maker.channel.rating = rating
+ maker.channel.docs = docs
+ maker.channel.pubDate = pubDate
+ maker.channel.lastBuildDate = lastBuildDate
+
+ skipDays.each do |day|
+ maker.channel.skipDays.new_day do |new_day|
+ new_day.content = day
+ end
+ end
+ skipHours.each do |hour|
+ maker.channel.skipHours.new_hour do |new_hour|
+ new_hour.content = hour
+ end
+ end
+
+ setup_dummy_image(maker)
+ end
+
+ assert_not_set_error("maker.image", %w(title url)) do
+ RSS::Maker.make("0.91") do |maker|
+ rss.channel.setup_maker(maker)
+ end
+ end
+
+ new_rss = RSS::Maker.make("0.91") do |maker|
+ rss.channel.setup_maker(maker)
+ setup_dummy_image(maker)
+ end
+ channel = new_rss.channel
+
+ assert_equal(title, channel.title)
+ assert_equal(link, channel.link)
+ assert_equal(description, channel.description)
+ assert_equal(language, channel.language)
+ assert_equal(copyright, channel.copyright)
+ assert_equal(managingEditor, channel.managingEditor)
+ assert_equal(webMaster, channel.webMaster)
+ assert_equal(rating, channel.rating)
+ assert_equal(docs, channel.docs)
+ assert_equal(pubDate, channel.pubDate)
+ assert_equal(lastBuildDate, channel.lastBuildDate)
+
+ skipDays.each_with_index do |day, i|
+ assert_equal(day, channel.skipDays.days[i].content)
+ end
+ skipHours.each_with_index do |hour, i|
+ assert_equal(hour.to_i, channel.skipHours.hours[i].content)
+ end
+
+ assert(channel.items.empty?)
+ assert_nil(channel.textInput)
+ end
+
+ def test_setup_maker_image
+ title = "fugafuga"
+ link = "http://hoge.com"
+ url = "http://hoge.com/hoge.png"
+ width = "144"
+ height = "400"
+ description = "an image"
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.title = title
+ maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
+
+ new_rss = RSS::Maker.make("0.91") do |maker|
+ rss.channel.setup_maker(maker)
+ rss.image.setup_maker(maker)
+ end
+
+ image = new_rss.image
+ assert_equal(title, image.title)
+ assert_equal(link, image.link)
+ assert_equal(url, image.url)
+ assert_equal(width.to_i, image.width)
+ assert_equal(height.to_i, image.height)
+ assert_equal(description, image.description)
+ end
+
+ def test_setup_maker_textinput
+ title = "fugafuga"
+ description = "text hoge fuga"
+ name = "hoge"
+ link = "http://hoge.com"
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
+
+ new_rss = RSS::Maker.make("0.91") do |maker|
+ rss.channel.setup_maker(maker)
+ rss.image.setup_maker(maker)
+ rss.textinput.setup_maker(maker)
+ end
+
+ textInput = new_rss.channel.textInput
+ assert_equal(title, textInput.title)
+ assert_equal(description, textInput.description)
+ assert_equal(name, textInput.name)
+ assert_equal(link, textInput.link)
+ end
+
+ def test_setup_maker_items(for_backward_compatibility=false)
+ title = "TITLE"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+
+ item_size = 5
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ end
+ end
+
+ setup_dummy_image(maker)
+ end
+
+ new_rss = RSS::Maker.make("0.91") do |maker|
+ rss.channel.setup_maker(maker)
+
+ rss.items.each do |item|
+ if for_backward_compatibility
+ item.setup_maker(maker)
+ else
+ item.setup_maker(maker.items)
+ end
+ end
+
+ rss.image.setup_maker(maker)
+ end
+
+ assert_equal(item_size, new_rss.items.size)
+ new_rss.items.each_with_index do |item, i|
+ assert_equal("#{title}#{i}", item.title)
+ assert_equal("#{link}#{i}", item.link)
+ assert_equal("#{description}#{i}", item.description)
+ end
+ end
+
+ def test_setup_maker_items_backward_compatibility
+ test_setup_maker_items(true)
+ end
+
+ def test_setup_maker
+ encoding = "EUC-JP"
+ standalone = true
+
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ rss = RSS::Maker.make("0.91") do |maker|
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ setup_dummy_channel(maker)
+ setup_dummy_image(maker)
+ end
+
+ new_rss = RSS::Maker.make("0.91") do |maker|
+ rss.setup_maker(maker)
+ end
+
+ assert_equal("0.91", new_rss.rss_version)
+ assert_equal(encoding, new_rss.encoding)
+ assert_equal(standalone, new_rss.standalone)
+
+ xss = rss.xml_stylesheets.first
+ assert_equal(1, rss.xml_stylesheets.size)
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_1.0.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_1.0.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_1.0.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,550 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestSetupMaker10 < TestCase
+
+ def setup
+ t = Time.iso8601("2000-01-01T12:00:05+00:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+
+ @dc_elems = {
+ :title => "hoge",
+ :description =>
+ " XML is placing increasingly heavy loads on
+ the existing technical infrastructure of the Internet.",
+ :creator => "Rael Dornfest (mailto:rael at oreilly.com)",
+ :subject => "XML",
+ :publisher => "The O'Reilly Network",
+ :contributor => "hogehoge",
+ :type => "fugafuga",
+ :format => "hohoho",
+ :identifier => "fufufu",
+ :source => "barbar",
+ :language => "ja",
+ :relation => "cococo",
+ :rights => "Copyright (c) 2000 O'Reilly & Associates, Inc.",
+ :date => t,
+ }
+
+ @sy_elems = {
+ :updatePeriod => "hourly",
+ :updateFrequency => "2",
+ :updateBase => t,
+ }
+
+ @content_elems = {
+ :encoded => "<em>ATTENTION</em>",
+ }
+
+ @trackback_elems = {
+ :ping => "http://bar.com/tb.cgi?tb_id=rssplustrackback",
+ :about => [
+ "http://foo.com/trackback/tb.cgi?tb_id=20020923",
+ "http://foo.com/trackback/tb.cgi?tb_id=20021010",
+ ],
+ }
+
+ @taxo_topic_elems = [
+ {
+ :link => "http://meerkat.oreillynet.com/?c=cat23",
+ :title => "Data: XML",
+ :description => "A Meerkat channel",
+ },
+ {
+ :link => "http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/",
+ :title => "XML",
+ :subject => "XML",
+ :description => "DMOZ category",
+ :topics => [
+ "http://meerkat.oreillynet.com/?c=cat23",
+ "http://dmoz.org/Computers/Data_Formats/Markup_Languages/SGML/",
+ "http://dmoz.org/Computers/Programming/Internet/",
+ ]
+ },
+ ]
+ end
+
+ def test_setup_maker_channel
+ about = "http://hoge.com"
+ title = "fugafuga"
+ link = "http://hoge.com"
+ description = "fugafugafugafuga"
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ maker.channel.about = about
+ maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+
+ @dc_elems.each do |var, value|
+ maker.channel.__send__("dc_#{var}=", value)
+ end
+
+ @sy_elems.each do |var, value|
+ maker.channel.__send__("sy_#{var}=", value)
+ end
+
+ setup_dummy_item(maker)
+ end
+
+ new_rss = RSS::Maker.make("1.0") do |maker|
+ rss.channel.setup_maker(maker)
+ rss.items.each do |item|
+ item.setup_maker(maker)
+ end
+ end
+ channel = new_rss.channel
+
+ assert_equal(about, channel.about)
+ assert_equal(title, channel.title)
+ assert_equal(link, channel.link)
+ assert_equal(description, channel.description)
+ assert_equal(1, channel.items.Seq.lis.size)
+ assert_nil(channel.image)
+ assert_nil(channel.textinput)
+
+ @dc_elems.each do |var, value|
+ assert_equal(value, channel.__send__("dc_#{var}"))
+ end
+
+ @sy_elems.each do |var, value|
+ value = value.to_i if var == :updateFrequency
+ assert_equal(value, channel.__send__("sy_#{var}"))
+ end
+
+ end
+
+ def test_setup_maker_image
+ title = "fugafuga"
+ link = "http://hoge.com"
+ url = "http://hoge.com/hoge.png"
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.title = title
+ maker.image.url = url
+
+ @dc_elems.each do |var, value|
+ maker.image.__send__("dc_#{var}=", value)
+ end
+
+ setup_dummy_item(maker)
+ end
+
+ new_rss = RSS::Maker.make("1.0") do |maker|
+ rss.channel.setup_maker(maker)
+ rss.image.setup_maker(maker)
+ rss.items.each do |item|
+ item.setup_maker(maker)
+ end
+ end
+
+ image = new_rss.image
+ assert_equal(url, image.about)
+ assert_equal(url, new_rss.channel.image.resource)
+ assert_equal(title, image.title)
+ assert_equal(link, image.link)
+ assert_equal(url, image.url)
+
+ @dc_elems.each do |var, value|
+ assert_equal(image.__send__("dc_#{var}"), value)
+ end
+ end
+
+ def test_setup_maker_textinput
+ title = "fugafuga"
+ description = "text hoge fuga"
+ name = "hoge"
+ link = "http://hoge.com"
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.textinput.link = link
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+
+ @dc_elems.each do |var, value|
+ maker.textinput.__send__("dc_#{var}=", value)
+ end
+
+ setup_dummy_item(maker)
+ end
+
+ new_rss = RSS::Maker.make("1.0") do |maker|
+ rss.channel.setup_maker(maker)
+ rss.textinput.setup_maker(maker)
+ rss.items.each do |item|
+ item.setup_maker(maker)
+ end
+ end
+
+ textinput = new_rss.textinput
+ assert_equal(link, textinput.about)
+ assert_equal(link, new_rss.channel.textinput.resource)
+ assert_equal(title, textinput.title)
+ assert_equal(name, textinput.name)
+ assert_equal(description, textinput.description)
+ assert_equal(link, textinput.link)
+
+ @dc_elems.each do |var, value|
+ assert_equal(textinput.__send__("dc_#{var}"), value)
+ end
+ end
+
+ def test_setup_maker_items(for_backward_compatibility=false)
+ title = "TITLE"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+
+ item_size = 5
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+
+ @dc_elems.each do |var, value|
+ item.__send__("dc_#{var}=", value)
+ end
+
+ @content_elems.each do |var, value|
+ item.__send__("content_#{var}=", value)
+ end
+
+ item.trackback_ping = @trackback_elems[:ping]
+ @trackback_elems[:about].each do |value|
+ item.trackback_abouts.new_about do |new_about|
+ new_about.value = value
+ end
+ end
+ end
+ end
+ end
+
+ new_rss = RSS::Maker.make("1.0") do |maker|
+ rss.channel.setup_maker(maker)
+
+ rss.items.each do |item|
+ if for_backward_compatibility
+ item.setup_maker(maker)
+ else
+ item.setup_maker(maker.items)
+ end
+ end
+ end
+
+ assert_equal(item_size, new_rss.items.size)
+ new_rss.items.each_with_index do |item, i|
+ assert_equal("#{link}#{i}", item.about)
+ assert_equal("#{title}#{i}", item.title)
+ assert_equal("#{link}#{i}", item.link)
+ assert_equal("#{description}#{i}", item.description)
+
+ @dc_elems.each do |var, value|
+ assert_equal(item.__send__("dc_#{var}"), value)
+ end
+
+ @content_elems.each do |var, value|
+ assert_equal(item.__send__("content_#{var}"), value)
+ end
+
+ assert_equal(@trackback_elems[:ping], item.trackback_ping)
+ assert_equal(@trackback_elems[:about].size, item.trackback_abouts.size)
+ item.trackback_abouts.each_with_index do |about, j|
+ assert_equal(@trackback_elems[:about][j], about.value)
+ end
+ end
+ end
+
+ def test_setup_maker_items_sort
+ title = "TITLE"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+
+ item_size = 5
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ item = RSS::RDF::Item.new("#{link}#{i}")
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ item.dc_date = Time.now + i * 60
+ item.setup_maker(maker.items)
+ end
+ maker.items.do_sort = false
+ end
+ assert_equal(item_size, rss.items.size)
+ rss.items.each_with_index do |item, i|
+ assert_equal("#{link}#{i}", item.about)
+ assert_equal("#{title}#{i}", item.title)
+ assert_equal("#{link}#{i}", item.link)
+ assert_equal("#{description}#{i}", item.description)
+ end
+
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ item = RSS::RDF::Item.new("#{link}#{i}")
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ item.dc_date = Time.now + i * 60
+ item.setup_maker(maker.items)
+ end
+ maker.items.do_sort = true
+ end
+ assert_equal(item_size, rss.items.size)
+ rss.items.reverse.each_with_index do |item, i|
+ assert_equal("#{link}#{i}", item.about)
+ assert_equal("#{title}#{i}", item.title)
+ assert_equal("#{link}#{i}", item.link)
+ assert_equal("#{description}#{i}", item.description)
+ end
+ end
+
+ def test_setup_maker_items_backward_compatibility
+ test_setup_maker_items(true)
+ end
+
+ def test_setup_maker
+ encoding = "EUC-JP"
+ standalone = true
+
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+ end
+
+ new_rss = RSS::Maker.make("1.0") do |maker|
+ rss.setup_maker(maker)
+ end
+
+ assert_equal("1.0", new_rss.rss_version)
+ assert_equal(encoding, new_rss.encoding)
+ assert_equal(standalone, new_rss.standalone)
+
+ xss = new_rss.xml_stylesheets.first
+ assert_equal(1, new_rss.xml_stylesheets.size)
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+ end
+
+ def test_setup_maker_full
+ encoding = "EUC-JP"
+ standalone = true
+
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ channel_about = "http://hoge.com"
+ channel_title = "fugafuga"
+ channel_link = "http://hoge.com"
+ channel_description = "fugafugafugafuga"
+
+ image_title = "fugafuga"
+ image_url = "http://hoge.com/hoge.png"
+
+ textinput_title = "fugafuga"
+ textinput_description = "text hoge fuga"
+ textinput_name = "hoge"
+ textinput_link = "http://hoge.com"
+
+ item_title = "TITLE"
+ item_link = "http://hoge.com/"
+ item_description = "text hoge fuga"
+
+ item_size = 5
+
+ rss = RSS::Maker.make("1.0") do |maker|
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ maker.channel.about = channel_about
+ maker.channel.title = channel_title
+ maker.channel.link = channel_link
+ maker.channel.description = channel_description
+ @dc_elems.each do |var, value|
+ maker.channel.__send__("dc_#{var}=", value)
+ end
+ @sy_elems.each do |var, value|
+ maker.channel.__send__("sy_#{var}=", value)
+ end
+
+ maker.image.title = image_title
+ maker.image.url = image_url
+ @dc_elems.each do |var, value|
+ maker.image.__send__("dc_#{var}=", value)
+ end
+
+ maker.textinput.link = textinput_link
+ maker.textinput.title = textinput_title
+ maker.textinput.description = textinput_description
+ maker.textinput.name = textinput_name
+ @dc_elems.each do |var, value|
+ maker.textinput.__send__("dc_#{var}=", value)
+ end
+
+ item_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{item_title}#{i}"
+ item.link = "#{item_link}#{i}"
+ item.description = "#{item_description}#{i}"
+
+ @dc_elems.each do |var, value|
+ item.__send__("dc_#{var}=", value)
+ end
+
+ @content_elems.each do |var, value|
+ item.__send__("content_#{var}=", value)
+ end
+
+ item.trackback_ping = @trackback_elems[:ping]
+ @trackback_elems[:about].each do |value|
+ item.trackback_abouts.new_about do |new_about|
+ new_about.value = value
+ end
+ end
+ end
+ end
+
+ setup_taxo_topic(maker, @taxo_topic_elems)
+ end
+
+ new_rss = RSS::Maker.make("1.0") do |maker|
+ rss.setup_maker(maker)
+ end
+
+ assert_equal("1.0", new_rss.rss_version)
+ assert_equal(encoding, new_rss.encoding)
+ assert_equal(standalone, new_rss.standalone)
+
+ xss = new_rss.xml_stylesheets.first
+ assert_equal(1, new_rss.xml_stylesheets.size)
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+
+ channel = new_rss.channel
+ assert_equal(channel_about, channel.about)
+ assert_equal(channel_title, channel.title)
+ assert_equal(channel_link, channel.link)
+ assert_equal(channel_description, channel.description)
+ item_resources = []
+ item_size.times do |i|
+ item_resources << "#{item_link}#{i}"
+ end
+ assert_equal(item_resources, channel.items.resources)
+ assert_equal(image_url, channel.image.resource)
+ assert_equal(textinput_link, channel.textinput.resource)
+ @dc_elems.each do |var, value|
+ assert_equal(value, channel.__send__("dc_#{var}"))
+ end
+ @sy_elems.each do |var, value|
+ value = value.to_i if var == :updateFrequency
+ assert_equal(value, channel.__send__("sy_#{var}"))
+ end
+
+ image = new_rss.image
+ assert_equal(image_url, image.about)
+ assert_equal(image_url, new_rss.channel.image.resource)
+ assert_equal(image_title, image.title)
+ assert_equal(channel_link, image.link)
+ assert_equal(image_url, image.url)
+ @dc_elems.each do |var, value|
+ assert_equal(image.__send__("dc_#{var}"), value)
+ end
+
+ textinput = new_rss.textinput
+ assert_equal(textinput_link, textinput.about)
+ assert_equal(textinput_link, new_rss.channel.textinput.resource)
+ assert_equal(textinput_title, textinput.title)
+ assert_equal(textinput_name, textinput.name)
+ assert_equal(textinput_description, textinput.description)
+ assert_equal(textinput_link, textinput.link)
+ @dc_elems.each do |var, value|
+ assert_equal(textinput.__send__("dc_#{var}"), value)
+ end
+
+ assert_equal(item_size, new_rss.items.size)
+ new_rss.items.each_with_index do |item, i|
+ assert_equal("#{item_link}#{i}", item.about)
+ assert_equal("#{item_title}#{i}", item.title)
+ assert_equal("#{item_link}#{i}", item.link)
+ assert_equal("#{item_description}#{i}", item.description)
+
+ @dc_elems.each do |var, value|
+ assert_equal(item.__send__("dc_#{var}"), value)
+ end
+
+ @content_elems.each do |var, value|
+ assert_equal(item.__send__("content_#{var}"), value)
+ end
+
+ assert_equal(@trackback_elems[:ping], item.trackback_ping)
+ assert_equal(@trackback_elems[:about].size, item.trackback_abouts.size)
+ item.trackback_abouts.each_with_index do |about, j|
+ assert_equal(@trackback_elems[:about][j], about.value)
+ end
+ end
+
+ assert_taxo_topic(@taxo_topic_elems, new_rss)
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_2.0.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_2.0.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_2.0.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,308 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestSetupMaker20 < TestCase
+
+ def test_setup_maker_channel
+ title = "fugafuga"
+ link = "http://hoge.com"
+ description = "fugafugafugafuga"
+ language = "ja"
+ copyright = "foo"
+ managingEditor = "bar"
+ webMaster = "web master"
+ rating = '(PICS-1.1 "http://www.rsac.org/ratingsv01.html" l gen true comment "RSACi North America Server" for "http://www.rsac.org" on "1996.04.16T08:15-0500" r (n 0 s 0 v 0 l 0))'
+ docs = "http://foo.com/doc"
+ skipDays = [
+ "Sunday",
+ "Monday",
+ ]
+ skipHours = [
+ "0",
+ "13",
+ ]
+ pubDate = Time.now
+ lastBuildDate = Time.now
+ categories = [
+ "Nespapers",
+ "misc",
+ ]
+ generator = "RSS Maker"
+ ttl = "60"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ maker.channel.title = title
+ maker.channel.link = link
+ maker.channel.description = description
+ maker.channel.language = language
+ maker.channel.copyright = copyright
+ maker.channel.managingEditor = managingEditor
+ maker.channel.webMaster = webMaster
+ maker.channel.rating = rating
+ maker.channel.docs = docs
+ maker.channel.pubDate = pubDate
+ maker.channel.lastBuildDate = lastBuildDate
+
+ skipDays.each do |day|
+ maker.channel.skipDays.new_day do |new_day|
+ new_day.content = day
+ end
+ end
+ skipHours.each do |hour|
+ maker.channel.skipHours.new_hour do |new_hour|
+ new_hour.content = hour
+ end
+ end
+
+
+ categories.each do |category|
+ maker.channel.categories.new_category do |new_category|
+ new_category.content = category
+ end
+ end
+
+ maker.channel.generator = generator
+ maker.channel.ttl = ttl
+ end
+
+ new_rss = RSS::Maker.make("2.0") do |maker|
+ rss.channel.setup_maker(maker)
+ end
+ channel = new_rss.channel
+
+ assert_equal(title, channel.title)
+ assert_equal(link, channel.link)
+ assert_equal(description, channel.description)
+ assert_equal(language, channel.language)
+ assert_equal(copyright, channel.copyright)
+ assert_equal(managingEditor, channel.managingEditor)
+ assert_equal(webMaster, channel.webMaster)
+ assert_equal(rating, channel.rating)
+ assert_equal(docs, channel.docs)
+ assert_equal(pubDate, channel.pubDate)
+ assert_equal(lastBuildDate, channel.lastBuildDate)
+
+ skipDays.each_with_index do |day, i|
+ assert_equal(day, channel.skipDays.days[i].content)
+ end
+ skipHours.each_with_index do |hour, i|
+ assert_equal(hour.to_i, channel.skipHours.hours[i].content)
+ end
+
+
+ channel.categories.each_with_index do |category, i|
+ assert_equal(categories[i], category.content)
+ end
+
+ assert_equal(generator, channel.generator)
+ assert_equal(ttl.to_i, channel.ttl)
+
+
+ assert(channel.items.empty?)
+ assert_nil(channel.image)
+ assert_nil(channel.textInput)
+ end
+
+ def test_setup_maker_image
+ title = "fugafuga"
+ link = "http://hoge.com"
+ url = "http://hoge.com/hoge.png"
+ width = "144"
+ height = "400"
+ description = "an image"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.title = title
+ maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
+
+ new_rss = RSS::Maker.make("2.0") do |maker|
+ rss.channel.setup_maker(maker)
+ rss.image.setup_maker(maker)
+ end
+
+ image = new_rss.image
+ assert_equal(title, image.title)
+ assert_equal(link, image.link)
+ assert_equal(url, image.url)
+ assert_equal(width.to_i, image.width)
+ assert_equal(height.to_i, image.height)
+ assert_equal(description, image.description)
+ end
+
+ def test_setup_maker_textinput
+ title = "fugafuga"
+ description = "text hoge fuga"
+ name = "hoge"
+ link = "http://hoge.com"
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
+
+ new_rss = RSS::Maker.make("2.0") do |maker|
+ rss.channel.setup_maker(maker)
+ rss.textinput.setup_maker(maker)
+ end
+
+ textInput = new_rss.channel.textInput
+ assert_equal(title, textInput.title)
+ assert_equal(description, textInput.description)
+ assert_equal(name, textInput.name)
+ assert_equal(link, textInput.link)
+ end
+
+ def test_setup_maker_items(for_backward_compatibility=false)
+ title = "TITLE"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+ author = "oprah at oxygen.net"
+ comments = "http://www.myblog.org/cgi-local/mt/mt-comments.cgi?entry_id=290"
+ pubDate = Time.now
+
+ guid_isPermaLink = "true"
+ guid_content = "http://inessential.com/2002/09/01.php#a2"
+
+ enclosure_url = "http://www.scripting.com/mp3s/weatherReportSuite.mp3"
+ enclosure_length = "12216320"
+ enclosure_type = "audio/mpeg"
+
+ source_url = "http://static.userland.com/tomalak/links2.xml"
+ source_content = "Tomalak's Realm"
+
+ category_domain = "http://www.fool.com/cusips"
+ category_content = "MSFT"
+
+ item_size = 5
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ item.author = "#{author}#{i}"
+ item.comments = "#{comments}#{i}"
+ item.date = pubDate
+
+ item.guid.isPermaLink = guid_isPermaLink
+ item.guid.content = guid_content
+
+ item.enclosure.url = enclosure_url
+ item.enclosure.length = enclosure_length
+ item.enclosure.type = enclosure_type
+
+ item.source.url = source_url
+ item.source.content = source_content
+
+ category = item.categories.new_category
+ category.domain = category_domain
+ category.content = category_content
+ end
+ end
+ end
+
+ new_rss = RSS::Maker.make("2.0") do |maker|
+ rss.channel.setup_maker(maker)
+
+ rss.items.each do |item|
+ if for_backward_compatibility
+ item.setup_maker(maker)
+ else
+ item.setup_maker(maker.items)
+ end
+ end
+ end
+
+ assert_equal(item_size, new_rss.items.size)
+ new_rss.items.each_with_index do |item, i|
+ assert_equal("#{title}#{i}", item.title)
+ assert_equal("#{link}#{i}", item.link)
+ assert_equal("#{description}#{i}", item.description)
+ assert_equal("#{author}#{i}", item.author)
+ assert_equal("#{comments}#{i}", item.comments)
+ assert_equal(pubDate, item.pubDate)
+
+ assert_equal(guid_isPermaLink == "true", item.guid.isPermaLink)
+ assert_equal(guid_content, item.guid.content)
+
+ assert_equal(enclosure_url, item.enclosure.url)
+ assert_equal(enclosure_length.to_i, item.enclosure.length)
+ assert_equal(enclosure_type, item.enclosure.type)
+
+ assert_equal(source_url, item.source.url)
+ assert_equal(source_content, item.source.content)
+
+ assert_equal(1, item.categories.size)
+ assert_equal(category_domain, item.category.domain)
+ assert_equal(category_content, item.category.content)
+ end
+
+ end
+
+ def test_setup_maker_items_backward_compatibility
+ test_setup_maker_items(true)
+ end
+
+ def test_setup_maker
+ encoding = "EUC-JP"
+ standalone = true
+
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ rss = RSS::Maker.make("2.0") do |maker|
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ setup_dummy_channel(maker)
+ end
+
+ new_rss = RSS::Maker.make("2.0") do |maker|
+ rss.setup_maker(maker)
+ end
+
+ assert_equal("2.0", new_rss.rss_version)
+ assert_equal(encoding, new_rss.encoding)
+ assert_equal(standalone, new_rss.standalone)
+
+ xss = rss.xml_stylesheets.first
+ assert_equal(1, rss.xml_stylesheets.size)
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_atom_entry.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_atom_entry.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_atom_entry.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,409 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestSetupMakerAtomEntry < TestCase
+ def setup
+ t = Time.iso8601("2000-01-01T12:00:05+00:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+
+ @dc_elems = {
+ :title => "hoge",
+ :description =>
+ " XML is placing increasingly heavy loads on
+ the existing technical infrastructure of the Internet.",
+ :creator => "Rael Dornfest (mailto:rael at oreilly.com)",
+ :subject => "XML",
+ :publisher => "The O'Reilly Network",
+ :contributor => "hogehoge",
+ :type => "fugafuga",
+ :format => "hohoho",
+ :identifier => "fufufu",
+ :source => "barbar",
+ :language => "ja",
+ :relation => "cococo",
+ :rights => "Copyright (c) 2000 O'Reilly & Associates, Inc.",
+ :date => t,
+ }
+ end
+
+ def test_setup_maker_entry(with_dc=true)
+ authors = [
+ {
+ :name => "Bob",
+ :uri => "http://example.com/~bob/",
+ :email => "bob at example.com",
+ },
+ {
+ :name => "Alice",
+ :uri => "http://example.com/~alice/",
+ :email => "alice at example.com",
+ },
+ ]
+ categories = [
+ {
+ :term => "music",
+ :label => "Music",
+ },
+ {
+ :term => "book",
+ :scheme => "http://example.com/category/book/",
+ :label => "Book",
+ },
+ ]
+ contributors = [
+ {
+ :name => "Chris",
+ :email => "chris at example.com",
+ },
+ {
+ :name => "Eva",
+ :uri => "http://example.com/~eva/",
+ },
+ ]
+ id = "urn:uuid:8b105336-7e20-45fc-bb78-37fb3e1db25a"
+ link = "http://hoge.com"
+ published = Time.now - 60 * 3600
+ rights = "Copyrights (c) 2007 Alice and Bob"
+ description = "fugafugafugafuga"
+ title = "fugafuga"
+ updated = Time.now
+
+ feed = RSS::Maker.make("atom:entry") do |maker|
+ maker.items.new_item do |item|
+ authors.each do |author_info|
+ item.authors.new_author do |author|
+ author_info.each do |key, value|
+ author.__send__("#{key}=", value)
+ end
+ end
+ end
+
+ categories.each do |category_info|
+ item.categories.new_category do |category|
+ category_info.each do |key, value|
+ category.__send__("#{key}=", value)
+ end
+ end
+ end
+
+ contributors.each do |contributor_info|
+ item.contributors.new_contributor do |contributor|
+ contributor_info.each do |key, value|
+ contributor.__send__("#{key}=", value)
+ end
+ end
+ end
+
+ item.id = id
+ item.link = link
+ item.published = published
+ item.rights = rights
+ item.description = description
+ item.title = title
+ item.updated = updated
+
+ if with_dc
+ @dc_elems.each do |var, value|
+ if var == :date
+ item.new_dc_date(value)
+ else
+ item.__send__("dc_#{var}=", value)
+ end
+ end
+ end
+ end
+ end
+ assert_not_nil(feed)
+
+ new_feed = RSS::Maker.make("atom:entry") do |maker|
+ feed.setup_maker(maker)
+ end
+ assert_not_nil(new_feed)
+
+ new_authors = new_feed.authors.collect do |author|
+ {
+ :name => author.name.content,
+ :uri => author.uri.content,
+ :email => author.email.content,
+ }
+ end
+ assert_equal(authors, new_authors)
+
+ new_categories = new_feed.categories.collect do |category|
+ {
+ :term => category.term,
+ :scheme => category.scheme,
+ :label => category.label,
+ }.reject {|key, value| value.nil?}
+ end
+ assert_equal(categories, new_categories)
+
+ new_contributors = new_feed.contributors.collect do |contributor|
+ info = {}
+ info[:name] = contributor.name.content
+ info[:uri] = contributor.uri.content if contributor.uri
+ info[:email] = contributor.email.content if contributor.email
+ info
+ end
+ assert_equal(contributors, new_contributors)
+
+ assert_equal(id, new_feed.id.content)
+ assert_equal(link, new_feed.link.href)
+ assert_equal(published, new_feed.published.content)
+ assert_equal(rights, new_feed.rights.content)
+ assert_equal(description, new_feed.summary.content)
+ assert_equal(title, new_feed.title.content)
+ assert_equal(updated, new_feed.updated.content)
+
+ if with_dc
+ @dc_elems.each do |var, value|
+ if var == :date
+ assert_equal([updated, value],
+ new_feed.dc_dates.collect {|date| date.value})
+ else
+ assert_equal(value, new_feed.__send__("dc_#{var}"))
+ end
+ end
+ end
+
+ assert_equal(1, new_feed.items.size)
+ end
+
+ def test_setup_maker_entry_without_dc
+ test_setup_maker_entry(false)
+ end
+
+ def test_setup_maker_items(for_backward_compatibility=false)
+ title = "TITLE"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+ updated = Time.now
+
+ item_size = 5
+ feed = RSS::Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ item.updated = updated + i * 60
+ end
+ end
+ end
+
+ new_feed = RSS::Maker.make("atom:entry") do |maker|
+ feed.items.each do |item|
+ if for_backward_compatibility
+ item.setup_maker(maker)
+ else
+ item.setup_maker(maker.items)
+ end
+ end
+
+ feed.items.clear
+ feed.setup_maker(maker)
+ end
+
+ assert_equal(1, new_feed.items.size)
+ new_feed.items[0..1].each_with_index do |item, i|
+ assert_equal("#{title}#{i}", item.title.content)
+ assert_equal("#{link}#{i}", item.link.href)
+ assert_equal("#{description}#{i}", item.summary.content)
+ assert_equal(updated + i * 60, item.updated.content)
+ end
+ end
+
+ def test_setup_maker_items_sort
+ title = "TITLE"
+ link = "http://hoge.com/"
+ summary = "text hoge fuga"
+ updated = Time.now
+
+ feed_size = 5
+ feed = RSS::Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+
+ feed_size.times do |i|
+ entry_class = RSS::Atom::Entry
+ entry = entry_class.new
+ entry.title = entry_class::Title.new(:content => "#{title}#{i}")
+ entry.links << entry_class::Link.new(:href => "#{link}#{i}")
+ entry.summary = entry_class::Summary.new(:content => "#{summary}#{i}")
+ entry.updated = entry_class::Updated.new(:content => updated + i * 60)
+ entry.setup_maker(maker.items)
+ end
+ maker.items.do_sort = false
+ end
+ assert_equal(1, feed.items.size)
+
+ assert_equal("#{title}0", feed.title.content)
+ assert_equal("#{link}0", feed.link.href)
+ assert_equal("#{summary}0", feed.summary.content)
+
+
+ feed = RSS::Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+
+ feed_size.times do |i|
+ entry_class = RSS::Atom::Entry
+ entry = entry_class.new
+ entry.title = entry_class::Title.new(:content => "#{title}#{i}")
+ entry.links << entry_class::Link.new(:href => "#{link}#{i}")
+ entry.summary = entry_class::Summary.new(:content => "#{summary}#{i}")
+ entry.updated = entry_class::Updated.new(:content => updated + i * 60)
+ entry.setup_maker(maker.items)
+ end
+ maker.items.do_sort = true
+ end
+ assert_equal(1, feed.items.size)
+
+ assert_equal("#{title}#{feed_size - 1}", feed.title.content)
+ assert_equal("#{link}#{feed_size - 1}", feed.link.href)
+ assert_equal("#{summary}#{feed_size - 1}", feed.summary.content)
+ end
+
+ def test_setup_maker_items_backward_compatibility
+ test_setup_maker_items(true)
+ end
+
+ def test_setup_maker
+ encoding = "EUC-JP"
+ standalone = true
+
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ feed = RSS::Maker.make("atom:entry") do |maker|
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ assert_not_nil(feed)
+
+ new_feed = RSS::Maker.make("atom:entry") do |maker|
+ feed.setup_maker(maker)
+ end
+
+ assert_equal(["atom", "1.0", "entry"], new_feed.feed_info)
+ assert_equal(encoding, new_feed.encoding)
+ assert_equal(standalone, new_feed.standalone)
+
+ xss = new_feed.xml_stylesheets.first
+ assert_equal(1, new_feed.xml_stylesheets.size)
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+ end
+
+ def test_setup_maker_full
+ encoding = "EUC-JP"
+ standalone = true
+
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ channel_about = "http://hoge.com"
+ channel_title = "fugafuga"
+ channel_link = "http://hoge.com"
+ channel_description = "fugafugafugafuga"
+ channel_author = "Bob"
+
+ image_url = "http://hoge.com/hoge.png"
+
+ item_title = "TITLE"
+ item_link = "http://hoge.com/"
+ item_description = "text hoge fuga"
+
+ entry_size = 5
+ feed = RSS::Maker.make("atom:entry") do |maker|
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ maker.channel.about = channel_about
+ maker.channel.title = channel_title
+ maker.channel.link = channel_link
+ maker.channel.description = channel_description
+ maker.channel.author = channel_author
+ @dc_elems.each do |var, value|
+ maker.channel.__send__("dc_#{var}=", value)
+ end
+
+ maker.image.url = image_url
+
+ entry_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{item_title}#{i}"
+ item.link = "#{item_link}#{i}"
+ item.description = "#{item_description}#{i}"
+
+ @dc_elems.each do |var, value|
+ item.__send__("dc_#{var}=", value)
+ end
+ end
+ end
+ end
+
+ new_feed = RSS::Maker.make("atom:entry") do |maker|
+ feed.setup_maker(maker)
+ end
+
+ assert_equal(["atom", "1.0", "entry"], new_feed.feed_info)
+ assert_equal(encoding, new_feed.encoding)
+ assert_equal(standalone, new_feed.standalone)
+
+ xss = new_feed.xml_stylesheets.first
+ assert_equal(1, new_feed.xml_stylesheets.size)
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+
+ assert_equal("#{item_title}0", new_feed.title.content)
+ assert_equal("#{item_link}0", new_feed.link.href)
+ assert_equal("#{item_description}0", new_feed.summary.content)
+ @dc_elems.each do |var, value|
+ assert_equal(value, new_feed.__send__("dc_#{var}"))
+ end
+ assert_equal(1, new_feed.items.size)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_atom_feed.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_atom_feed.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_atom_feed.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,445 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestSetupMakerAtomFeed < TestCase
+ def setup
+ t = Time.iso8601("2000-01-01T12:00:05+00:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+
+ @dc_elems = {
+ :title => "hoge",
+ :description =>
+ " XML is placing increasingly heavy loads on
+ the existing technical infrastructure of the Internet.",
+ :creator => "Rael Dornfest (mailto:rael at oreilly.com)",
+ :subject => "XML",
+ :publisher => "The O'Reilly Network",
+ :contributor => "hogehoge",
+ :type => "fugafuga",
+ :format => "hohoho",
+ :identifier => "fufufu",
+ :source => "barbar",
+ :language => "ja",
+ :relation => "cococo",
+ :rights => "Copyright (c) 2000 O'Reilly & Associates, Inc.",
+ :date => t,
+ }
+ end
+
+ def test_setup_maker_feed(with_dc=true)
+ authors = [
+ {
+ :name => "Bob",
+ :uri => "http://example.com/~bob/",
+ :email => "bob at example.com",
+ },
+ {
+ :name => "Alice",
+ :uri => "http://example.com/~alice/",
+ :email => "alice at example.com",
+ },
+ ]
+ categories = [
+ {
+ :term => "music",
+ :label => "Music",
+ },
+ {
+ :term => "book",
+ :scheme => "http://example.com/category/book/",
+ :label => "Book",
+ },
+ ]
+ contributors = [
+ {
+ :name => "Chris",
+ :email => "chris at example.com",
+ },
+ {
+ :name => "Eva",
+ :uri => "http://example.com/~eva/",
+ },
+ ]
+ generator = {
+ :uri => "http://example.com/generator/",
+ :version => "0.0.1",
+ :content => "Feed Generator",
+ }
+ icon = "http://example.com/icon.png"
+ about = "http://hoge.com"
+ title = "fugafuga"
+ link = "http://hoge.com"
+ logo = "http://example.com/logo.png"
+ rights = "Copyrights (c) 2007 Alice and Bob"
+ description = "fugafugafugafuga"
+ updated = Time.now
+
+ feed = RSS::Maker.make("atom") do |maker|
+ authors.each do |author_info|
+ maker.channel.authors.new_author do |author|
+ author_info.each do |key, value|
+ author.__send__("#{key}=", value)
+ end
+ end
+ end
+
+ categories.each do |category_info|
+ maker.channel.categories.new_category do |category|
+ category_info.each do |key, value|
+ category.__send__("#{key}=", value)
+ end
+ end
+ end
+
+ contributors.each do |contributor_info|
+ maker.channel.contributors.new_contributor do |contributor|
+ contributor_info.each do |key, value|
+ contributor.__send__("#{key}=", value)
+ end
+ end
+ end
+
+ generator.each do |key, value|
+ maker.channel.generator do |g|
+ g.__send__("#{key}=", value)
+ end
+ end
+
+ maker.channel.icon = icon
+
+ maker.channel.about = about
+ maker.channel.link = link
+ maker.channel.logo = logo
+ maker.channel.rights = rights
+ maker.channel.title = title
+ maker.channel.description = description
+ maker.channel.updated = updated
+
+ if with_dc
+ @dc_elems.each do |var, value|
+ if var == :date
+ maker.channel.new_dc_date(value)
+ else
+ maker.channel.__send__("dc_#{var}=", value)
+ end
+ end
+ end
+
+ setup_dummy_item_atom(maker)
+ end
+ assert_not_nil(feed)
+
+ new_feed = RSS::Maker.make("atom") do |maker|
+ feed.setup_maker(maker)
+ end
+ assert_not_nil(new_feed)
+
+ new_authors = new_feed.authors.collect do |author|
+ {
+ :name => author.name.content,
+ :uri => author.uri.content,
+ :email => author.email.content,
+ }
+ end
+ assert_equal(authors, new_authors)
+
+ new_categories = new_feed.categories.collect do |category|
+ {
+ :term => category.term,
+ :scheme => category.scheme,
+ :label => category.label,
+ }.reject {|key, value| value.nil?}
+ end
+ assert_equal(categories, new_categories)
+
+ new_contributors = new_feed.contributors.collect do |contributor|
+ info = {}
+ info[:name] = contributor.name.content
+ info[:uri] = contributor.uri.content if contributor.uri
+ info[:email] = contributor.email.content if contributor.email
+ info
+ end
+ assert_equal(contributors, new_contributors)
+
+ new_generator = {
+ :uri => new_feed.generator.uri,
+ :version => new_feed.generator.version,
+ :content => new_feed.generator.content,
+ }
+ assert_equal(generator, new_generator)
+
+ assert_equal(icon, new_feed.icon.content)
+ assert_equal(about, new_feed.id.content)
+ assert_equal(link, new_feed.link.href)
+ assert_equal(logo, new_feed.logo.content)
+ assert_equal(rights, new_feed.rights.content)
+ assert_equal(description, new_feed.subtitle.content)
+ assert_equal(title, new_feed.title.content)
+ assert_equal(updated, new_feed.updated.content)
+
+ if with_dc
+ @dc_elems.each do |var, value|
+ if var == :date
+ assert_equal([updated, value],
+ new_feed.dc_dates.collect {|date| date.value})
+ else
+ assert_equal(value, new_feed.__send__("dc_#{var}"))
+ end
+ end
+ end
+
+ assert_equal(1, new_feed.items.size)
+ end
+
+ def test_setup_maker_feed_without_dc
+ test_setup_maker_feed(false)
+ end
+
+ def test_setup_maker_items(for_backward_compatibility=false)
+ title = "TITLE"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+ updated = Time.now
+
+ item_size = 5
+ feed = RSS::Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ item.updated = updated + i * 60
+ end
+ end
+ end
+
+ new_feed = RSS::Maker.make("atom") do |maker|
+ feed.items.each do |item|
+ if for_backward_compatibility
+ item.setup_maker(maker)
+ else
+ item.setup_maker(maker.items)
+ end
+ end
+
+ feed.items.clear
+ feed.setup_maker(maker)
+ end
+
+ assert_equal(item_size, new_feed.items.size)
+ new_feed.items.each_with_index do |item, i|
+ assert_equal("#{title}#{i}", item.title.content)
+ assert_equal("#{link}#{i}", item.link.href)
+ assert_equal("#{description}#{i}", item.summary.content)
+ assert_equal(updated + i * 60, item.updated.content)
+ end
+ end
+
+ def test_setup_maker_items_sort
+ title = "TITLE"
+ link = "http://hoge.com/"
+ summary = "text hoge fuga"
+ updated = Time.now
+
+ feed_size = 5
+ feed = RSS::Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+
+ feed_size.times do |i|
+ entry_class = RSS::Atom::Feed::Entry
+ entry = entry_class.new
+ entry.title = entry_class::Title.new(:content => "#{title}#{i}")
+ entry.links << entry_class::Link.new(:href => "#{link}#{i}")
+ entry.summary = entry_class::Summary.new(:content => "#{summary}#{i}")
+ entry.updated = entry_class::Updated.new(:content => updated + i * 60)
+ entry.setup_maker(maker.items)
+ end
+ maker.items.do_sort = false
+ end
+ assert_equal(feed_size, feed.entries.size)
+ feed.entries.each_with_index do |entry, i|
+ assert_equal("#{title}#{i}", entry.title.content)
+ assert_equal("#{link}#{i}", entry.link.href)
+ assert_equal("#{summary}#{i}", entry.summary.content)
+ end
+
+
+ feed = RSS::Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+
+ feed_size.times do |i|
+ entry_class = RSS::Atom::Feed::Entry
+ entry = entry_class.new
+ entry.title = entry_class::Title.new(:content => "#{title}#{i}")
+ entry.links << entry_class::Link.new(:href => "#{link}#{i}")
+ entry.summary = entry_class::Summary.new(:content => "#{summary}#{i}")
+ entry.updated = entry_class::Updated.new(:content => updated + i * 60)
+ entry.setup_maker(maker.items)
+ end
+ maker.items.do_sort = true
+ end
+ assert_equal(feed_size, feed.entries.size)
+ feed.entries.reverse.each_with_index do |entry, i|
+ assert_equal("#{title}#{i}", entry.title.content)
+ assert_equal("#{link}#{i}", entry.link.href)
+ assert_equal("#{summary}#{i}", entry.summary.content)
+ end
+ end
+
+ def test_setup_maker_items_backward_compatibility
+ test_setup_maker_items(true)
+ end
+
+ def test_setup_maker
+ encoding = "EUC-JP"
+ standalone = true
+
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ feed = RSS::Maker.make("atom") do |maker|
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ assert_not_nil(feed)
+
+ new_feed = RSS::Maker.make("atom") do |maker|
+ feed.setup_maker(maker)
+ end
+
+ assert_equal(["atom", "1.0", "feed"], new_feed.feed_info)
+ assert_equal(encoding, new_feed.encoding)
+ assert_equal(standalone, new_feed.standalone)
+
+ xss = new_feed.xml_stylesheets.first
+ assert_equal(1, new_feed.xml_stylesheets.size)
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+ end
+
+ def test_setup_maker_full
+ encoding = "EUC-JP"
+ standalone = true
+
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ channel_about = "http://hoge.com"
+ channel_title = "fugafuga"
+ channel_link = "http://hoge.com"
+ channel_description = "fugafugafugafuga"
+ channel_author = "Bob"
+
+ image_url = "http://hoge.com/hoge.png"
+
+ item_title = "TITLE"
+ item_link = "http://hoge.com/"
+ item_description = "text hoge fuga"
+
+ entry_size = 5
+ feed = RSS::Maker.make("atom") do |maker|
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ maker.channel.about = channel_about
+ maker.channel.title = channel_title
+ maker.channel.link = channel_link
+ maker.channel.description = channel_description
+ maker.channel.author = channel_author
+ @dc_elems.each do |var, value|
+ maker.channel.__send__("dc_#{var}=", value)
+ end
+
+ maker.image.url = image_url
+
+ entry_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{item_title}#{i}"
+ item.link = "#{item_link}#{i}"
+ item.description = "#{item_description}#{i}"
+
+ @dc_elems.each do |var, value|
+ item.__send__("dc_#{var}=", value)
+ end
+ end
+ end
+ end
+
+ new_feed = RSS::Maker.make("atom") do |maker|
+ feed.setup_maker(maker)
+ end
+
+ assert_equal(["atom", "1.0", "feed"], new_feed.feed_info)
+ assert_equal(encoding, new_feed.encoding)
+ assert_equal(standalone, new_feed.standalone)
+
+ xss = new_feed.xml_stylesheets.first
+ assert_equal(1, new_feed.xml_stylesheets.size)
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+
+ assert_equal(channel_title, new_feed.title.content)
+ assert_equal(channel_link, new_feed.link.href)
+ assert_equal(channel_description, new_feed.subtitle.content)
+ assert_equal(channel_author, new_feed.author.name.content)
+ assert_equal(image_url, new_feed.logo.content)
+ @dc_elems.each do |var, value|
+ assert_equal(value, new_feed.__send__("dc_#{var}"))
+ end
+
+ assert_equal(entry_size, new_feed.entries.size)
+ new_feed.entries.each_with_index do |entry, i|
+ assert_equal("#{item_title}#{i}", entry.title.content)
+ assert_equal("#{item_link}#{i}", entry.link.href)
+ assert_equal("#{item_description}#{i}", entry.summary.content)
+
+ @dc_elems.each do |var, value|
+ assert_equal(value, entry.__send__("dc_#{var}"))
+ end
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_itunes.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_itunes.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_itunes.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,144 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestSetupMakerITunes < TestCase
+ def test_setup_maker_simple
+ author = "John Doe"
+ block = true
+ categories = ["Audio Blogs"]
+ image = "http://example.com/podcasts/everything/AllAboutEverything.jpg"
+ duration = "4:05"
+ duration_components = [0, 4, 5]
+ explicit = true
+ keywords = ["salt", "pepper", "shaker", "exciting"]
+ new_feed_url = "http://newlocation.com/example.rss"
+ owner = {:name => "John Doe", :email => "john.doe at example.com"}
+ subtitle = "A show about everything"
+ summary = "All About Everything is a show about " +
+ "everything. Each week we dive into any " +
+ "subject known to man and talk about it " +
+ "as much as we can. Look for our Podcast " +
+ "in the iTunes Music Store"
+
+ feed = RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ channel = maker.channel
+ channel.itunes_author = author
+ channel.itunes_block = block
+ categories.each do |category|
+ channel.itunes_categories.new_category.text = category
+ end
+ channel.itunes_image = image
+ channel.itunes_explicit = explicit
+ channel.itunes_keywords = keywords
+ channel.itunes_owner.itunes_name = owner[:name]
+ channel.itunes_owner.itunes_email = owner[:email]
+ channel.itunes_subtitle = subtitle
+ channel.itunes_summary = summary
+
+ item = maker.items.last
+ item.itunes_author = author
+ item.itunes_block = block
+ item.itunes_duration = duration
+ item.itunes_explicit = explicit
+ item.itunes_keywords = keywords
+ item.itunes_subtitle = subtitle
+ item.itunes_summary = summary
+ end
+ assert_not_nil(feed)
+
+ new_feed = RSS::Maker.make("rss2.0") do |maker|
+ feed.setup_maker(maker)
+ end
+ assert_not_nil(new_feed)
+
+ channel = new_feed.channel
+ item = new_feed.items.last
+
+ assert_equal(author, channel.itunes_author)
+ assert_equal(author, item.itunes_author)
+
+ assert_equal(block, channel.itunes_block?)
+ assert_equal(block, item.itunes_block?)
+
+ assert_equal(categories,
+ collect_itunes_categories(channel.itunes_categories))
+
+ assert_equal(image, channel.itunes_image.href)
+
+ assert_equal(duration_components,
+ [item.itunes_duration.hour,
+ item.itunes_duration.minute,
+ item.itunes_duration.second])
+
+ assert_equal(explicit, channel.itunes_explicit?)
+ assert_equal(explicit, item.itunes_explicit?)
+
+ assert_equal(keywords, channel.itunes_keywords)
+ assert_equal(keywords, item.itunes_keywords)
+
+ assert_equal(owner,
+ {
+ :name => channel.itunes_owner.itunes_name,
+ :email => channel.itunes_owner.itunes_email
+ })
+
+ assert_equal(subtitle, channel.itunes_subtitle)
+ assert_equal(subtitle, item.itunes_subtitle)
+
+ assert_equal(summary, channel.itunes_summary)
+ assert_equal(summary, item.itunes_summary)
+ end
+
+ def test_setup_maker_with_nested_categories
+ categories = [["Arts & Entertainment", "Games"],
+ ["Technology", "Computers"],
+ "Audio Blogs"]
+
+ feed = RSS::Maker.make("rss2.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ channel = maker.channel
+ categories.each do |category|
+ target = channel.itunes_categories
+ if category.is_a?(Array)
+ category.each do |sub_category|
+ target = target.new_category
+ target.text = sub_category
+ end
+ else
+ target.new_category.text = category
+ end
+ end
+ end
+ assert_not_nil(feed)
+
+ new_feed = RSS::Maker.make("rss2.0") do |maker|
+ feed.setup_maker(maker)
+ end
+ assert_not_nil(new_feed)
+
+ channel = new_feed.channel
+
+ assert_equal(categories,
+ collect_itunes_categories(channel.itunes_categories))
+ end
+
+ private
+ def collect_itunes_categories(categories)
+ categories.collect do |c|
+ rest = collect_itunes_categories(c.itunes_categories)
+ if rest.empty?
+ c.text
+ else
+ [c.text, *rest]
+ end
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_slash.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_slash.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_setup_maker_slash.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,38 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestSetupMakerSlash < TestCase
+ def test_setup_maker
+ elements = {
+ "section" => "articles",
+ "department" => "not-an-ocean-unless-there-are-lobsters",
+ "comments" => 177,
+ "hit_parades" => [177, 155, 105, 33, 6, 3, 0],
+ }
+
+ rss = RSS::Maker.make("rss1.0") do |maker|
+ setup_dummy_channel(maker)
+ setup_dummy_item(maker)
+
+ item = maker.items.last
+ item.slash_section = elements["section"]
+ item.slash_department = elements["department"]
+ item.slash_comments = elements["comments"]
+ item.slash_hit_parade = elements["hit_parades"].join(",")
+ end
+ assert_not_nil(rss)
+
+ new_rss = RSS::Maker.make("rss1.0") do |maker|
+ rss.setup_maker(maker)
+ end
+ assert_not_nil(new_rss)
+
+ item = new_rss.items.last
+ assert_not_nil(item)
+
+ assert_slash_elements(elements, item)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_slash.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_slash.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_slash.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,64 @@
+require "cgi"
+require "rexml/document"
+
+require "rss-testcase"
+
+require "rss/1.0"
+require "rss/slash"
+
+module RSS
+ class TestSlash < TestCase
+ def setup
+ @elements = {
+ "section" => "articles",
+ "department" => "not-an-ocean-unless-there-are-lobsters",
+ "comments" => 177,
+ "hit_parades" => [177, 155, 105, 33, 6, 3, 0],
+ }
+
+ slash_nodes = @elements.collect do |name, value|
+ if name == "hit_parades"
+ name = "hit_parade"
+ value = value.join(",")
+ end
+ "<slash:#{name}>#{value}</slash:#{name}>"
+ end.join("\n")
+
+ slash_ns = {"slash" => "http://purl.org/rss/1.0/modules/slash/"}
+ @source = make_RDF(<<-EOR, slash_ns)
+#{make_channel}
+#{make_image}
+#{make_item(slash_nodes)}
+#{make_textinput}
+EOR
+ end
+
+ def test_parser
+ rss = RSS::Parser.parse(@source)
+
+ assert_not_nil(rss)
+
+ item = rss.items[0]
+ assert_not_nil(item)
+
+ assert_slash_elements(item)
+ end
+
+ def test_to_s
+ rss = RSS::Parser.parse(@source)
+ rss = RSS::Parser.parse(rss.to_s)
+
+ assert_not_nil(rss)
+
+ item = rss.items[0]
+ assert_not_nil(item)
+
+ assert_slash_elements(item)
+ end
+
+ private
+ def assert_slash_elements(target)
+ super(@elements, target)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_syndication.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_syndication.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_syndication.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,125 @@
+require "cgi"
+require "rexml/document"
+
+require "rss-testcase"
+
+require "rss/1.0"
+require "rss/syndication"
+
+module RSS
+ class TestSyndication < TestCase
+
+ def setup
+ @prefix = "sy"
+ @uri = "http://purl.org/rss/1.0/modules/syndication/"
+
+ @parents = %w(channel)
+
+ t = Time.iso8601("2000-01-01T12:00:05+00:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+
+ @elems = {
+ :updatePeriod => "hourly",
+ :updateFrequency => "2",
+ :updateBase => t,
+ }
+
+ @sy_nodes = @elems.collect do |name, value|
+ "<#{@prefix}:#{name}>#{CGI.escapeHTML(value.to_s)}</#{@prefix}:#{name}>"
+ end.join("\n")
+
+ @rss_source = make_RDF(<<-EOR, {@prefix => @uri})
+#{make_channel(@sy_nodes)}
+#{make_image()}
+#{make_item()}
+#{make_textinput()}
+EOR
+
+ @rss = Parser.parse(@rss_source)
+ end
+
+ def test_parser
+
+ assert_nothing_raised do
+ Parser.parse(@rss_source)
+ end
+
+ @elems.each do |tag, value|
+ assert_too_much_tag(tag.to_s, "channel") do
+ Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))
+#{make_channel(("<" + @prefix + ":" + tag.to_s + ">" +
+ CGI.escapeHTML(value.to_s) +
+ "</" + @prefix + ":" + tag.to_s + ">") * 2)}
+#{make_item}
+EOR
+ end
+ end
+
+ end
+
+ def test_accessor
+
+ t = Time.iso8601("2003-01-01T12:00:23+09:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+
+ new_value = {
+ :updatePeriod => "daily",
+ :updateFrequency => "11",
+ :updateBase => t,
+ }
+
+ @elems.each do |name, value|
+ value = value.to_i if name == :updateFrequency
+ @parents.each do |parent|
+ assert_equal(value, @rss.__send__(parent).__send__("sy_#{name}"))
+ @rss.__send__(parent).__send__("sy_#{name}=", new_value[name])
+ new_val = new_value[name]
+ new_val = new_val.to_i if name == :updateFrequency
+ assert_equal(new_val, @rss.__send__(parent).__send__("sy_#{name}"))
+ end
+ end
+
+ %w(hourly daily weekly monthly yearly).each do |x|
+ @parents.each do |parent|
+ assert_nothing_raised do
+ @rss.__send__(parent).sy_updatePeriod = x
+ end
+ end
+ end
+
+ %w(-2 0.3 -0.4).each do |x|
+ @parents.each do |parent|
+ assert_not_available_value("sy:updateBase", x) do
+ @rss.__send__(parent).sy_updateBase = x
+ end
+ end
+ end
+
+ end
+
+ def test_to_s
+
+ @elems.each do |name, value|
+ excepted = "<#{@prefix}:#{name}>#{value}</#{@prefix}:#{name}>"
+ @parents.each do |parent|
+ assert_equal(excepted,
+ @rss.__send__(parent).__send__("sy_#{name}_element"))
+ end
+ end
+
+ REXML::Document.new(@rss_source).root.each_element do |parent|
+ if @parents.include?(parent.name)
+ parent.each_element do |elem|
+ if elem.namespace == @uri
+ assert_equal(elem.text, @elems[elem.name.intern].to_s)
+ end
+ end
+ end
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_taxonomy.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_taxonomy.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_taxonomy.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,172 @@
+require "cgi"
+
+require "rss-testcase"
+
+require "rss/1.0"
+require "rss/2.0"
+require "rss/taxonomy"
+
+module RSS
+ class TestTaxonomy < TestCase
+
+ def setup
+ @prefix = "taxo"
+ @uri = "http://purl.org/rss/1.0/modules/taxonomy/"
+ @dc_prefix = "dc"
+ @dc_uri = "http://purl.org/dc/elements/1.1/"
+
+ @ns = {
+ @prefix => @uri,
+ @dc_prefix => @dc_uri,
+ }
+
+ @topics_parents = %w(channel item)
+
+ @topics_lis = [
+ "http://meerkat.oreillynet.com/?c=cat23",
+ "http://meerkat.oreillynet.com/?c=47",
+ "http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/",
+ ]
+
+ @topics_node = "<#{@prefix}:topics>\n"
+ @topics_node << " <rdf:Bag>\n"
+ @topics_lis.each do |value|
+ resource = CGI.escapeHTML(value)
+ @topics_node << " <rdf:li resource=\"#{resource}\"/>\n"
+ end
+ @topics_node << " </rdf:Bag>\n"
+ @topics_node << "</#{@prefix}:topics>"
+
+ @topic_topics_lis = \
+ [
+ "http://meerkat.oreillynet.com/?c=cat23",
+ "http://dmoz.org/Computers/Data_Formats/Markup_Languages/SGML/",
+ "http://dmoz.org/Computers/Programming/Internet/",
+ ]
+
+ @topic_contents = \
+ [
+ {
+ :link => "http://meerkat.oreillynet.com/?c=cat23",
+ :title => "Data: XML",
+ :description => "A Meerkat channel",
+ },
+ {
+ :link => "http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/",
+ :title => "XML",
+ :subject => "XML",
+ :description => "DMOZ category",
+ :topics => @topic_topics_lis,
+ }
+ ]
+
+ @topic_nodes = @topic_contents.collect do |info|
+ link = info[:link]
+ rv = "<#{@prefix}:topic rdf:about=\"#{link}\">\n"
+ info.each do |name, value|
+ case name
+ when :topics
+ rv << " <#{@prefix}:topics>\n"
+ rv << " <rdf:Bag>\n"
+ value.each do |li|
+ resource = CGI.escapeHTML(li)
+ rv << " <rdf:li resource=\"#{resource}\"/>\n"
+ end
+ rv << " </rdf:Bag>\n"
+ rv << " </#{@prefix}:topics>\n"
+ else
+ prefix = (name == :link ? @prefix : @dc_prefix)
+ rv << " <#{prefix}:#{name}>#{value}</#{prefix}:#{name}>\n"
+ end
+ end
+ rv << "</#{@prefix}:topic>"
+ end
+
+ @rss_source = make_RDF(<<-EOR, @ns)
+#{make_channel(@topics_node)}
+#{make_image()}
+#{make_item(@topics_node)}
+#{make_textinput()}
+#{@topic_nodes.join("\n")}
+EOR
+
+ @rss = Parser.parse(@rss_source)
+ end
+
+ def test_parser
+ assert_nothing_raised do
+ Parser.parse(@rss_source)
+ end
+
+ assert_too_much_tag("topics", "channel") do
+ Parser.parse(make_RDF(<<-EOR, @ns))
+#{make_channel(@topics_node * 2)}
+#{make_item()}
+EOR
+ end
+
+ assert_too_much_tag("topics", "item") do
+ Parser.parse(make_RDF(<<-EOR, @ns))
+#{make_channel()}
+#{make_item(@topics_node * 2)}
+EOR
+ end
+ end
+
+ def test_accessor
+ topics = @rss.channel.taxo_topics
+ assert_equal(@topics_lis.sort,
+ topics.Bag.lis.collect {|li| li.resource}.sort)
+ assert_equal(@topics_lis.sort, topics.resources.sort)
+
+ assert_equal(@rss.taxo_topics.first, @rss.taxo_topic)
+
+ @topic_contents.each_with_index do |info, i|
+ topic = @rss.taxo_topics[i]
+ info.each do |name, value|
+ case name
+ when :link
+ assert_equal(value, topic.about)
+ assert_equal(value, topic.taxo_link)
+ when :topics
+ assert_equal(value.sort, topic.taxo_topics.resources.sort)
+ else
+ assert_equal(value, topic.__send__("dc_#{name}"))
+ end
+ end
+ end
+ end
+
+ def test_to_s
+ @topics_parents.each do |parent|
+ meth = "taxo_topics_element"
+ assert_equal(@topics_node, @rss.__send__(parent).__send__(meth))
+ end
+
+ @topic_nodes.each_with_index do |node, i|
+ expected_xml = taxo_xmlns_container(node)
+ expected = REXML::Document.new(expected_xml).root.elements[1]
+ actual_xml = taxo_xmlns_container(@rss.taxo_topics[i].to_s(true, ""))
+ actual = REXML::Document.new(actual_xml).root.elements[1]
+ expected_elems = expected.reject {|x| x.is_a?(REXML::Text)}
+ actual_elems = actual.reject {|x| x.is_a?(REXML::Text)}
+ expected_elems.sort! {|x, y| x.name <=> y.name}
+ actual_elems.sort! {|x, y| x.name <=> y.name}
+ assert_equal(expected_elems.collect {|x| x.to_s},
+ actual_elems.collect {|x| x.to_s})
+ assert_equal(expected.attributes.sort, actual.attributes.sort)
+ end
+ end
+
+ private
+ def taxo_xmlns_container(content)
+ xmlns_container({
+ @prefix => @uri,
+ "dc" => "http://purl.org/dc/elements/1.1/",
+ "rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
+ },
+ content)
+ end
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/rss/test_to_s.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_to_s.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_to_s.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,670 @@
+require "rexml/document"
+
+require "rss-testcase"
+
+require "rss/maker"
+require "rss/1.0"
+require "rss/2.0"
+require "rss/content"
+require "rss/dublincore"
+require "rss/syndication"
+require "rss/trackback"
+
+module RSS
+ class TestToS < TestCase
+ def setup
+ @image_url = "http://example.com/foo.png"
+ @textinput_link = "http://example.com/search.cgi"
+ @item_links = [
+ "http://example.com/1",
+ "http://example.com/2",
+ ]
+
+ setup_xml_declaration_info
+ setup_xml_stylesheet_infos
+ setup_channel_info
+ setup_item_infos
+ setup_image_info
+ setup_textinput_info
+
+ setup_dublin_core_info
+ setup_syndication_info
+ setup_content_info
+ setup_trackback_info
+ end
+
+ def test_to_s_10
+ rss = RSS::Maker.make("1.0") do |maker|
+ setup_full(maker)
+ end
+
+ assert_xml_declaration(@version, @encoding, @standalone, rss)
+ assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)
+ assert_channel10(@channel_info, rss.channel)
+ assert_items10(@item_infos, rss.items)
+ rss.items.each do |item|
+ assert_trackback(@trackback_info, item)
+ end
+ assert_image10(@image_info, rss.image)
+ assert_textinput10(@textinput_info, rss.textinput)
+
+ rss = RSS::Parser.parse(rss.to_s)
+
+ assert_xml_declaration(@version, @encoding, @standalone, rss)
+ assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)
+ assert_channel10(@channel_info, rss.channel)
+ assert_items10(@item_infos, rss.items)
+ assert_image10(@image_info, rss.image)
+ assert_textinput10(@textinput_info, rss.textinput)
+ end
+
+ def test_to_s_09
+ rss = RSS::Maker.make("0.91") do |maker|
+ setup_full(maker)
+ end
+
+ assert_xml_declaration(@version, @encoding, @standalone, rss)
+ assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)
+ assert_channel09(@channel_info, rss.channel)
+ assert_items09(@item_infos, rss.items)
+ assert_image09(@image_info, rss.image)
+ assert_textinput09(@textinput_info, rss.textinput)
+
+ rss = RSS::Parser.parse(rss.to_s)
+
+ assert_xml_declaration(@version, @encoding, @standalone, rss)
+ assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)
+ assert_channel09(@channel_info, rss.channel)
+ assert_items09(@item_infos, rss.items)
+ assert_image09(@image_info, rss.image)
+ assert_textinput09(@textinput_info, rss.textinput)
+ end
+
+ def test_to_s_20
+ rss = RSS::Maker.make("2.0") do |maker|
+ setup_full(maker)
+ end
+
+ assert_xml_declaration(@version, @encoding, @standalone, rss)
+ assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)
+ assert_channel20(@channel_info, rss.channel)
+ assert_items20(@item_infos, rss.items)
+ assert_image20(@image_info, rss.image)
+ assert_textinput20(@textinput_info, rss.textinput)
+
+ rss = RSS::Parser.parse(rss.to_s)
+
+ assert_xml_declaration(@version, @encoding, @standalone, rss)
+ assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)
+ assert_channel20(@channel_info, rss.channel)
+ assert_items20(@item_infos, rss.items)
+ assert_image20(@image_info, rss.image)
+ assert_textinput20(@textinput_info, rss.textinput)
+ end
+
+ private
+ def setup_xml_declaration_info
+ @version = "1.0"
+ @encoding = "UTF-8"
+ @standalone = false
+ end
+
+ def setup_xml_stylesheet_infos
+ @xs_infos = [
+ {
+ "href" => "XXX.xsl",
+ "type" => "text/xsl",
+ "title" => "XXX",
+ "media" => "print",
+ "alternate" => "no",
+ },
+ {
+ "href" => "YYY.css",
+ "type" => "text/css",
+ "title" => "YYY",
+ "media" => "all",
+ "alternate" => "no",
+ },
+ ]
+ end
+
+ def setup_channel_info
+ @channel_info = {
+ "about" => "http://example.com/index.rdf",
+ "title" => "Sample RSS",
+ "link" => "http://example.com/",
+ "description" => "Sample\n\n\n\n\nSite",
+ "language" => "en",
+ "copyright" => "FDL",
+ "managingEditor" => "foo at example.com",
+ "webMaster" => "webmaster at example.com",
+ "rating" => '(PICS-1.1 "http://www.rsac.org/ratingsv01.html" l gen true comment "RSACi North America Server" for "http://www.rsac.org" on "1996.04.16T08:15-0500" r (n 0 s 0 v 0 l 0))',
+ "docs" => "http://backend.userland.com/rss091",
+ "skipDays" => [
+ "Monday",
+ "Friday",
+ ],
+ "skipHours" => [
+ "12",
+ "23",
+ ],
+ "date" => Time.now,
+ "lastBuildDate" => Time.now - 3600,
+ "generator" => "RSS Maker",
+ "ttl" => "60",
+ "cloud" => {
+ "domain" => "rpc.sys.com",
+ "port" => "80",
+ "path" => "/RPC2",
+ "registerProcedure" => "myCloud.rssPleaseNotify",
+ "protocol" => "xml-rpc",
+ },
+ "category" => {
+ "domain" => "http://example.com/misc/",
+ "content" => "misc",
+ },
+
+ "image" => {
+ "resource" => @image_url,
+ },
+
+ "textinput" => {
+ "resource" => @textinput_link,
+ },
+
+ "items" => @item_links.collect{|link| {"resource" => link}},
+ }
+ end
+
+ def setup_item_infos
+ @item_infos = [
+ {
+ "title" => "Sample item1",
+ "link" => @item_links[0],
+ "description" => "Sample description1",
+ "date" => Time.now - 3600,
+ "author" => "foo at example.com",
+ "comments" => "http://example.com/1/comments",
+ "guid" => {
+ "isPermaLink" => "true",
+ "content" => "http://example.com/1",
+ },
+ "enclosure" => {
+ "url" => "http://example.com/1.mp3",
+ "length" => "100",
+ "type" => "audio/mpeg",
+ },
+ "source" => {
+ "url" => "http:/example.com/",
+ "content" => "Sample site",
+ },
+ "category" => {
+ "domain" => "http://example.com/misc/",
+ "content" => "misc",
+ },
+ },
+
+ {
+ "title" => "Sample item2",
+ "link" => @item_links[1],
+ "description" => "Sample description2",
+ "date" => Time.now - 7200,
+ "author" => "foo at example.com",
+ "comments" => "http://example.com/2/comments",
+ "guid" => {
+ "isPermaLink" => "false",
+ "content" => "http://example.com/2",
+ },
+ "enclosure" => {
+ "url" => "http://example.com/2.mp3",
+ "length" => "200",
+ "type" => "audio/mpeg",
+ },
+ "source" => {
+ "url" => "http:/example.com/",
+ "content" => "Sample site",
+ },
+ "category" => {
+ "domain" => "http://example.com/misc/",
+ "content" => "misc",
+ },
+ },
+ ]
+ end
+
+ def setup_image_info
+ @image_info = {
+ "title" => "Sample image",
+ "url" => @image_url,
+ "width" => "88",
+ "height" => "31",
+ "description" => "Sample",
+ }
+ end
+
+ def setup_textinput_info
+ @textinput_info = {
+ "title" => "Sample textinput",
+ "description" => "Search",
+ "name" => "key",
+ "link" => @textinput_link,
+ }
+ end
+
+ def setup_dublin_core_info
+ @dc_info = {
+ "title" => "DC title",
+ "description" => "DC desc",
+ "creator" => "DC creator",
+ "subject" => "DC subject",
+ "publisher" => "DC publisher",
+ "contributor" => "DC contributor",
+ "type" => "DC type",
+ "format" => "DC format",
+ "identifier" => "DC identifier",
+ "source" => "DC source",
+ "language" => "ja",
+ "relation" => "DC relation",
+ "coverage" => "DC coverage",
+ "rights" => "DC rights",
+ "date" => Time.now - 60,
+ }
+ end
+
+ def setup_syndication_info
+ @sy_info = {
+ "updatePeriod" => "hourly",
+ "updateFrequency" => "2",
+ "updateBase" => Time.now - 3600,
+ }
+ end
+
+ def setup_content_info
+ @content_info = {
+ "encoded" => "<p>p</p>",
+ }
+ end
+
+ def setup_trackback_info
+ @trackback_info = {
+ "ping" => "http://example.com/tb.cgi?tb_id=XXX",
+ "abouts" => [
+ "http://example.net/tb.cgi?tb_id=YYY",
+ "http://example.org/tb.cgi?tb_id=ZZZ",
+ ]
+ }
+ end
+
+
+ def setup_full(maker)
+ setup_xml_declaration(maker)
+ setup_xml_stylesheets(maker)
+ setup_channel(maker)
+ setup_image(maker)
+ setup_items(maker)
+ setup_textinput(maker)
+ end
+
+ def setup_xml_declaration(maker)
+ %w(version encoding standalone).each do |name|
+ maker.__send__("#{name}=", instance_eval("@#{name}"))
+ end
+ end
+
+ def setup_xml_stylesheets(maker)
+ @xs_infos.each do |info|
+ xs = maker.xml_stylesheets.new_xml_stylesheet
+ info.each do |name, value|
+ xs.__send__("#{name}=", value)
+ end
+ end
+ end
+
+ def setup_channel(maker)
+ channel = maker.channel
+ info = @channel_info
+
+ %w(about title link description language copyright
+ managingEditor webMaster rating docs date
+ lastBuildDate generator ttl).each do |name|
+ channel.__send__("#{name}=", info[name])
+ end
+
+ skipDays = channel.skipDays
+ info["skipDays"].each do |day|
+ new_day = skipDays.new_day
+ new_day.content = day
+ end
+
+ skipHours = channel.skipHours
+ info["skipHours"].each do |hour|
+ new_hour = skipHours.new_hour
+ new_hour.content = hour
+ end
+
+ cloud = channel.cloud
+ %w(domain port path registerProcedure protocol).each do |name|
+ cloud.__send__("#{name}=", info["cloud"][name])
+ end
+
+ category = channel.categories.new_category
+ %w(domain content).each do |name|
+ category.__send__("#{name}=", info["category"][name])
+ end
+ end
+
+ def setup_image(maker)
+ image = maker.image
+ info = @image_info
+
+ %w(title url width height description).each do |name|
+ image.__send__("#{name}=", info[name])
+ end
+ end
+
+ def setup_items(maker)
+ items = maker.items
+
+ @item_infos.each do |info|
+ item = items.new_item
+ %w(title link description date author comments).each do |name|
+ item.__send__("#{name}=", info[name])
+ end
+
+ guid = item.guid
+ %w(isPermaLink content).each do |name|
+ guid.__send__("#{name}=", info["guid"][name])
+ end
+
+ enclosure = item.enclosure
+ %w(url length type).each do |name|
+ enclosure.__send__("#{name}=", info["enclosure"][name])
+ end
+
+ source = item.source
+ %w(url content).each do |name|
+ source.__send__("#{name}=", info["source"][name])
+ end
+
+ category = item.categories.new_category
+ %w(domain content).each do |name|
+ category.__send__("#{name}=", info["category"][name])
+ end
+
+ setup_trackback(item)
+ end
+ end
+
+ def setup_textinput(maker)
+ textinput = maker.textinput
+ info = @textinput_info
+
+ %w(title description name link).each do |name|
+ textinput.__send__("#{name}=", info[name])
+ end
+ end
+
+ def setup_content(target)
+ prefix = "content"
+ %w(encoded).each do |name|
+ target.__send__("#{prefix}_#{name}=", @content_info[name])
+ end
+ end
+
+ def setup_dublin_core(target)
+ prefix = "dc"
+ %w(title description creator subject publisher
+ contributor type format identifier source language
+ relation coverage rights).each do |name|
+ target.__send__("#{prefix}_#{name}=", @dc_info[name])
+ end
+ end
+
+ def setup_syndicate(target)
+ prefix = "sy"
+ %w(updatePeriod updateFrequency updateBase).each do |name|
+ target.__send__("#{prefix}_#{name}=", @sy_info[name])
+ end
+ end
+
+ def setup_trackback(target)
+ target.trackback_ping = @trackback_info["ping"]
+ @trackback_info["abouts"].each do |about|
+ new_about = target.trackback_abouts.new_about
+ new_about.value = about
+ end
+ end
+
+
+ def assert_channel10(attrs, channel)
+ _wrap_assertion do
+ n_attrs = normalized_attrs(attrs)
+
+ names = %w(about title link description)
+ assert_attributes(attrs, names, channel)
+
+ %w(image items textinput).each do |name|
+ value = n_attrs[name]
+ if value
+ target = channel.__send__(name)
+ __send__("assert_channel10_#{name}", value, target)
+ end
+ end
+ end
+ end
+
+ def assert_channel10_image(attrs, image)
+ _wrap_assertion do
+ assert_attributes(attrs, %w(resource), image)
+ end
+ end
+
+ def assert_channel10_textinput(attrs, textinput)
+ _wrap_assertion do
+ assert_attributes(attrs, %w(resource), textinput)
+ end
+ end
+
+ def assert_channel10_items(attrs, items)
+ _wrap_assertion do
+ assert_equal(items.resources, items.Seq.lis.collect {|x| x.resource})
+ items.Seq.lis.each_with_index do |li, i|
+ assert_attributes(attrs[i], %w(resource), li)
+ end
+ end
+ end
+
+ def assert_image10(attrs, image)
+ _wrap_assertion do
+ names = %w(about title url link)
+ assert_attributes(attrs, names, image)
+ end
+ end
+
+ def assert_items10(attrs, items)
+ _wrap_assertion do
+ names = %w(about title link description)
+ items.each_with_index do |item, i|
+ assert_attributes(attrs[i], names, item)
+ end
+ end
+ end
+
+ def assert_textinput10(attrs, textinput)
+ _wrap_assertion do
+ names = %w(about title description name link)
+ assert_attributes(attrs, names, textinput)
+ end
+ end
+
+
+ def assert_channel09(attrs, channel)
+ _wrap_assertion do
+ n_attrs = normalized_attrs(attrs)
+
+ names = %w(title description link language rating
+ copyright pubDate lastBuildDate docs
+ managingEditor webMaster)
+ assert_attributes(attrs, names, channel)
+
+ %w(skipHours skipDays).each do |name|
+ value = n_attrs[name]
+ if value
+ target = channel.__send__(name)
+ __send__("assert_channel09_#{name}", value, target)
+ end
+ end
+ end
+ end
+
+ def assert_channel09_skipDays(contents, skipDays)
+ _wrap_assertion do
+ days = skipDays.days
+ contents.each_with_index do |content, i|
+ assert_equal(content, days[i].content)
+ end
+ end
+ end
+
+ def assert_channel09_skipHours(contents, skipHours)
+ _wrap_assertion do
+ hours = skipHours.hours
+ contents.each_with_index do |content, i|
+ assert_equal(content.to_i, hours[i].content)
+ end
+ end
+ end
+
+ def assert_image09(attrs, image)
+ _wrap_assertion do
+ names = %w(url link title description)
+ names << ["width", :integer]
+ names << ["height", :integer]
+ assert_attributes(attrs, names, image)
+ end
+ end
+
+ def assert_items09(attrs, items)
+ _wrap_assertion do
+ names = %w(title link description)
+ items.each_with_index do |item, i|
+ assert_attributes(attrs[i], names, item)
+ end
+ end
+ end
+
+ def assert_textinput09(attrs, textinput)
+ _wrap_assertion do
+ names = %w(title description name link)
+ assert_attributes(attrs, names, textinput)
+ end
+ end
+
+
+ def assert_channel20(attrs, channel)
+ _wrap_assertion do
+ n_attrs = normalized_attrs(attrs)
+
+ names = %w(title link description language copyright
+ managingEditor webMaster pubDate
+ lastBuildDate generator docs rating)
+ names << ["ttl", :integer]
+ assert_attributes(attrs, names, channel)
+
+ %w(cloud categories skipHours skipDays).each do |name|
+ value = n_attrs[name]
+ if value
+ target = channel.__send__(name)
+ __send__("assert_channel20_#{name}", value, target)
+ end
+ end
+ end
+ end
+
+ def assert_channel20_skipDays(contents, skipDays)
+ assert_channel09_skipDays(contents, skipDays)
+ end
+
+ def assert_channel20_skipHours(contents, skipHours)
+ assert_channel09_skipHours(contents, skipHours)
+ end
+
+ def assert_channel20_cloud(attrs, cloud)
+ _wrap_assertion do
+ names = %w(domain path registerProcedure protocol)
+ names << ["port", :integer]
+ assert_attributes(attrs, names, cloud)
+ end
+ end
+
+ def assert_channel20_categories(attrs, categories)
+ _wrap_assertion do
+ names = %w(domain content)
+ categories.each_with_index do |category, i|
+ assert_attributes(attrs[i], names, category)
+ end
+ end
+ end
+
+ def assert_image20(attrs, image)
+ _wrap_assertion do
+ names = %w(url link title description)
+ names << ["width", :integer]
+ names << ["height", :integer]
+ assert_attributes(attrs, names, image)
+ end
+ end
+
+ def assert_items20(attrs, items)
+ _wrap_assertion do
+ names = %w(about title link description)
+ items.each_with_index do |item, i|
+ assert_attributes(attrs[i], names, item)
+
+ n_attrs = normalized_attrs(attrs[i])
+
+ %w(source enclosure categories guid).each do |name|
+ value = n_attrs[name]
+ if value
+ target = item.__send__(name)
+ __send__("assert_items20_#{name}", value, target)
+ end
+ end
+ end
+ end
+ end
+
+ def assert_items20_source(attrs, source)
+ _wrap_assertion do
+ assert_attributes(attrs, %w(url content), source)
+ end
+ end
+
+ def assert_items20_enclosure(attrs, enclosure)
+ _wrap_assertion do
+ names = ["url", ["length", :integer], "type"]
+ assert_attributes(attrs, names, enclosure)
+ end
+ end
+
+ def assert_items20_categories(attrs, categories)
+ _wrap_assertion do
+ assert_channel20_categories(attrs, categories)
+ end
+ end
+
+ def assert_items20_guid(attrs, guid)
+ _wrap_assertion do
+ names = [["isPermaLink", :boolean], ["content"]]
+ assert_attributes(attrs, names, guid)
+ end
+ end
+
+ def assert_textinput20(attrs, textinput)
+ _wrap_assertion do
+ names = %w(title description name link)
+ assert_attributes(attrs, names, textinput)
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_trackback.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_trackback.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_trackback.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,135 @@
+require "cgi"
+require "rexml/document"
+
+require "rss-testcase"
+
+require "rss/1.0"
+require "rss/2.0"
+require "rss/trackback"
+
+module RSS
+ class TestTrackBack < TestCase
+
+ def setup
+ @prefix = "trackback"
+ @uri = "http://madskills.com/public/xml/rss/module/trackback/"
+
+ @parents = %w(item)
+
+ @elems = {
+ :ping => "http://bar.com/tb.cgi?tb_id=rssplustrackback",
+ :about => "http://foo.com/trackback/tb.cgi?tb_id=20020923",
+ }
+
+ @content_nodes = @elems.collect do |name, value|
+ "<#{@prefix}:#{name} rdf:resource=\"#{CGI.escapeHTML(value.to_s)}\"/>"
+ end.join("\n")
+
+ @content_nodes2 = @elems.collect do |name, value|
+ "<#{@prefix}:#{name}>#{CGI.escapeHTML(value.to_s)}</#{@prefix}:#{name}>"
+ end.join("\n")
+
+ @rss_source = make_RDF(<<-EOR, {@prefix => @uri})
+#{make_channel()}
+#{make_image()}
+#{make_item(@content_nodes)}
+#{make_textinput()}
+EOR
+
+ @rss = Parser.parse(@rss_source)
+
+ @rss20_source = make_rss20(nil, {@prefix => @uri}) do
+ make_channel20(nil) do
+ make_item20(@content_nodes2)
+ end
+ end
+
+ @rss20 = Parser.parse(@rss20_source, false)
+ end
+
+ def test_parser
+
+ assert_nothing_raised do
+ Parser.parse(@rss_source)
+ end
+
+ @elems.find_all{|k, v| k == :ping}.each do |tag, value|
+ assert_too_much_tag(tag.to_s, "item") do
+ Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))
+#{make_channel()}
+#{make_item(("<" + @prefix + ":" + tag.to_s + " rdf:resource=\"" +
+ CGI.escapeHTML(value.to_s) +
+ "\"/>") * 2)}
+EOR
+ end
+ end
+
+ @elems.find_all{|k, v| k == :about}.each do |tag, value|
+ assert_missing_tag("trackback:ping", "item") do
+ Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))
+#{make_channel()}
+#{make_item(("<" + @prefix + ":" + tag.to_s + " rdf:resource=\"" +
+ CGI.escapeHTML(value.to_s) +
+ "\"/>") * 2)}
+EOR
+ end
+
+ end
+
+ end
+
+ def test_accessor
+
+ new_value = {
+ :ping => "http://baz.com/trackback/tb.cgi?tb_id=20030808",
+ :about => "http://hoge.com/trackback/tb.cgi?tb_id=90030808",
+ }
+
+ @elems.each do |name, value|
+ @parents.each do |parent|
+ accessor = "#{RSS::TRACKBACK_PREFIX}_#{name}"
+ target = @rss.__send__(parent)
+ target20 = @rss20.channel.__send__(parent, -1)
+ assert_equal(value, target.__send__(accessor))
+ assert_equal(value, target20.__send__(accessor))
+ if name == :about
+ # abount is zero or more
+ target.__send__("#{accessor}=", 0, new_value[name].to_s)
+ target20.__send__("#{accessor}=", 0, new_value[name].to_s)
+ else
+ target.__send__("#{accessor}=", new_value[name].to_s)
+ target20.__send__("#{accessor}=", new_value[name].to_s)
+ end
+ assert_equal(new_value[name], target.__send__(accessor))
+ assert_equal(new_value[name], target20.__send__(accessor))
+ end
+ end
+
+ end
+
+ def test_to_s
+
+ @elems.each do |name, value|
+ excepted = %Q!<#{@prefix}:#{name} rdf:resource="#{CGI.escapeHTML(value)}"/>!
+ @parents.each do |parent|
+ meth = "#{RSS::TRACKBACK_PREFIX}_#{name}_element"
+ meth << "s" if name == :about
+ assert_equal(excepted, @rss.__send__(parent).__send__(meth))
+ end
+ end
+
+ REXML::Document.new(@rss_source).root.each_element do |parent|
+ if @parents.include?(parent.name)
+ parent.each_element do |elem|
+ if elem.namespace == @uri
+ assert_equal(elem.attributes["resource"], @elems[elem.name.intern])
+ end
+ end
+ end
+ end
+
+ end
+
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/rss/test_version.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_version.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_version.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,9 @@
+require "rss-testcase"
+
+module RSS
+ class TestVersion < TestCase
+ def test_version
+ assert_equal("0.2.7", ::RSS::VERSION)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rss/test_xml-stylesheet.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rss/test_xml-stylesheet.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rss/test_xml-stylesheet.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,108 @@
+require "rexml/document"
+
+require "rss-testcase"
+
+require "rss/1.0"
+require "rss/xml-stylesheet"
+
+module RSS
+ class TestXMLStyleSheet < TestCase
+
+ def test_accessor
+ [
+ {:href => "a.xsl", :type => "text/xsl"},
+ {:media => "print", :title => "FOO"},
+ {:charset => "UTF-8", :alternate => "yes"},
+ ].each do |attrs|
+ assert_xml_stylesheet_attrs(attrs, XMLStyleSheet.new(attrs))
+ end
+ end
+
+ def test_to_s
+ [
+ {:href => "a.xsl", :type => "text/xsl"},
+ {:type => "text/xsl"},
+ {:href => "a.xsl", :guess_type => "text/xsl"},
+ {:href => "a.css", :type => "text/css"},
+ {:href => "a.css", :type => "text/xsl",
+ :guess_type => "text/css"},
+ {:href => "a.xsl", :type => "text/xsl",
+ :title => "sample", :media => "printer",
+ :charset => "UTF-8", :alternate => "yes"},
+ {:href => "a.css", :guess_type => "text/css",
+ :alternate => "no"},
+ {:type => "text/xsl", :title => "sample",
+ :media => "printer", :charset => "UTF-8",
+ :alternate => "yes"},
+ ].each do |attrs|
+ target, contents = parse_pi(XMLStyleSheet.new(attrs).to_s)
+ assert_xml_stylesheet(target, attrs, XMLStyleSheet.new(contents))
+ end
+ end
+
+ def test_bad_alternate
+ %w(a ___ ??? BAD_ALTERNATE).each do |value|
+ xss = XMLStyleSheet.new
+ assert_raise(NotAvailableValueError) do
+ xss.alternate = value
+ end
+ xss.do_validate = false
+ assert_nothing_raised do
+ xss.alternate = value
+ end
+ assert_nil(xss.alternate)
+ end
+ end
+
+ def test_parse
+ [
+ [{:href => "a.xsl", :type => "text/xsl"},],
+ [{:media => "print", :title => "FOO"},],
+ [{:charset => "UTF-8", :alternate => "yes"},],
+ [{:href => "a.xsl", :type => "text/xsl"},
+ {:type => "text/xsl"},
+ {:href => "a.xsl", :guess_type => "text/xsl"},
+ {:href => "a.css", :type => "text/css"},
+ {:href => "a.css", :type => "text/xsl",
+ :guess_type => "text/css"},
+ {:href => "a.xsl", :type => "text/xsl",
+ :title => "sample", :media => "printer",
+ :charset => "UTF-8", :alternate => "yes"},
+ {:href => "a.css", :guess_type => "text/css",
+ :alternate => "no"},
+ {:type => "text/xsl", :title => "sample",
+ :media => "printer", :charset => "UTF-8",
+ :alternate => "yes"},],
+ ].each do |xsss|
+ doc = REXML::Document.new(make_sample_RDF)
+ root = doc.root
+ xsss.each do |xss|
+ content = xss.collect do |key, name|
+ %Q[#{key}="#{name}"]
+ end.join(" ")
+ pi = REXML::Instruction.new("xml-stylesheet", content)
+ root.previous_sibling = pi
+ end
+ rss = Parser.parse(doc.to_s)
+ have_href_xsss = xsss.find_all {|xss| xss.has_key?(:href)}
+ assert_equal(have_href_xsss.size, rss.xml_stylesheets.size)
+ rss.xml_stylesheets.each_with_index do |stylesheet, i|
+ target, = parse_pi(stylesheet.to_s)
+ assert_xml_stylesheet(target, have_href_xsss[i], stylesheet)
+ end
+ end
+ end
+
+ def parse_pi(pi)
+ /\A\s*<\?(\S+)([^?]*\?+(?:[^?>][^?]*\?+)*)>\s*\z/ =~ pi
+ target = $1
+ dummy = REXML::Document.new("<dummy #{$2.to_s.chop}/>").root
+ contents = {}
+ dummy.attributes.each do |name, value|
+ contents[name] = value
+ end
+ [target, contents]
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/allpairs.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/allpairs.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/allpairs.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,103 @@
+module AllPairs
+ module_function
+
+ def make_prime(v)
+ return 2 if v < 2
+ ary = [true] * (v*2)
+ 2.upto(Math.sqrt(ary.length).ceil) {|i|
+ return i if ary[i] && v <= i
+ (i*2).step(ary.length, i) {|j|
+ ary[j] = false
+ }
+ }
+ v.upto(ary.length-1) {|i|
+ return i if ary[i]
+ }
+ raise "[bug] prime not found greater than #{v}"
+ end
+
+ def make_basic_block(prime)
+ prime.times {|i|
+ prime.times {|j|
+ row = [i]
+ 0.upto(prime-1) {|m|
+ row << (i*m + j) % prime
+ }
+ yield row
+ }
+ }
+ end
+
+ def combine_block(tbl1, tbl2)
+ result = []
+ tbl2.each {|row|
+ result << row * tbl1.first.length
+ }
+ tbl1.each_with_index {|row, k|
+ next if k == 0
+ result << row.map {|i| [i] * tbl2.first.length }.flatten
+ }
+ result
+ end
+
+ def make_large_block(v, prime)
+ if prime <= v+1
+ make_basic_block(v) {|row|
+ yield row
+ }
+ else
+ tbl = []
+ make_basic_block(v) {|row|
+ tbl << row
+ }
+ tbls = [tbl]
+ while tbl.first.length ** 2 < prime
+ tbl = combine_block(tbl, tbl)
+ tbls << tbl
+ end
+ tbl1 = tbls.find {|t| prime <= t.first.length * tbl.first.length }
+ tbl = combine_block(tbl, tbl1)
+ tbl.each {|row|
+ yield row
+ }
+ end
+ end
+
+ def each_index(*vs)
+ n = vs.length
+ max_v = vs.max
+ prime = make_prime(max_v)
+ h = {}
+ make_large_block(max_v, n) {|row|
+ row = vs.zip(row).map {|v, i| i % v }
+ next if h[row]
+ h[row] = true
+ yield row
+ }
+ end
+
+ # generate all pairs test.
+ def each(*args)
+ args.map! {|a| a.to_a }
+ each_index(*args.map {|a| a.length}) {|is|
+ yield is.zip(args).map {|i, a| a[i] }
+ }
+ end
+
+ # generate all combination in cartesian product. (not all-pairs test)
+ def exhaustive_each(*args)
+ args = args.map {|a| a.to_a }
+ i = 0
+ while true
+ n = i
+ as = []
+ args.reverse_each {|a|
+ n, m = n.divmod(a.length)
+ as.unshift a[m]
+ }
+ break if 0 < n
+ yield as
+ i += 1
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/beginmainend.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/beginmainend.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/beginmainend.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,80 @@
+errout = ARGV.shift
+
+BEGIN {
+ puts "b1"
+ local_begin1 = "local_begin1"
+ $global_begin1 = "global_begin1"
+ ConstBegin1 = "ConstBegin1"
+}
+
+BEGIN {
+ puts "b2"
+
+ BEGIN {
+ puts "b2-1"
+ }
+}
+
+# for scope check
+#raise if defined?(local_begin1)
+raise unless defined?($global_begin1)
+raise unless defined?(::ConstBegin1)
+local_for_end2 = "e2"
+$global_for_end1 = "e1"
+
+puts "main"
+
+END {
+ puts local_for_end2 # e2
+}
+
+eval <<EOE
+ BEGIN {
+ puts "b3"
+
+ BEGIN {
+ puts "b3-1"
+ }
+ }
+
+ BEGIN {
+ puts "b4"
+ }
+
+ END {
+ puts "e3"
+ }
+
+ END {
+ puts "e4"
+
+ END {
+ puts "e4-1"
+
+ END {
+ puts "e4-1-1"
+ }
+ }
+
+ END {
+ puts "e4-2"
+ }
+ }
+EOE
+
+END {
+ exit
+ puts "should not be dumped"
+
+ END {
+ puts "not reached"
+ }
+}
+
+END {
+ puts $global_for_end1 # e1
+
+ END {
+ puts "e1-1"
+ }
+}
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_big5.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_big5.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_big5.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestBig5 < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("big5")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\xa1\xa1").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0xa1a1, s("\xa1\xa1").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\xa1\xa1"), 0xa1a1.chr("big5"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\xa1\xa1)\\1"), "i")
+ assert_match(r, s("\xa1\xa1\xa1\xa1"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\xa1\xa1"), s("\xa1\xa1\xa1\xa1").chop)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_cp949.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_cp949.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_cp949.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestCP949 < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("cp949")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\xa1\xa1").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0xa1a1, s("\xa1\xa1").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\xa1\xa1"), 0xa1a1.chr("cp949"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\xa1\xa1)\\1"), "i")
+ assert_match(r, s("\xa1\xa1\xa1\xa1"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\xa1\xa1"), s("\xa1\xa1\xa1\xa1").chop)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_emoji.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_emoji.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_emoji.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,442 @@
+require 'test/unit'
+
+module Emoji
+
+ class TestRenameSJIS < Test::Unit::TestCase
+ def test_shift_jis
+ assert_raise(ArgumentError) { "".force_encoding("Shift_JIS-DoCoMo") }
+ assert_raise(ArgumentError) { "".force_encoding("Shift_JIS-KDDI") }
+ assert_raise(ArgumentError) { "".force_encoding("Shift_JIS-SoftBank") }
+ end
+ end
+
+ class TestUTF8_BLACK_SUN_WITH_RAYS < Test::Unit::TestCase
+ include Emoji
+
+ def setup
+ @codes = {
+ "UTF8-DoCoMo" => utf8_docomo("\u{E63E}"),
+ "UTF8-KDDI" => utf8_kddi("\u{E488}"),
+ "UTF8-SoftBank" => utf8_softbank("\u{E04A}"),
+ "UTF-8" => "\u{2600}",
+ }
+ end
+
+ def test_convert
+ @codes.each do |from_enc, from_str|
+ @codes.each do |to_enc, to_str|
+ next if from_enc == to_enc
+ assert_equal to_str, from_str.encode(to_enc), "convert from #{from_enc} to #{to_enc}"
+ end
+ end
+ end
+ end
+
+ class TestDoCoMo < Test::Unit::TestCase
+ include Emoji
+
+ def setup
+ setup_instance_variable(self)
+ end
+
+ def test_encoding_name
+ %w(UTF8-DoCoMo
+ SJIS-DoCoMo).each do |n|
+ assert Encoding.name_list.include?(n), "encoding not found: #{n}"
+ end
+ end
+
+ def test_comparison
+ assert_not_equal Encoding::UTF_8, Encoding::UTF8_DoCoMo
+ assert_not_equal Encoding::Windows_31J, Encoding::SJIS_DoCoMo
+ end
+
+ def test_from_utf8
+ assert_nothing_raised { assert_equal utf8_docomo(@aiueo_utf8), to_utf8_docomo(@aiueo_utf8) }
+ assert_nothing_raised { assert_equal sjis_docomo(@aiueo_sjis), to_sjis_docomo(@aiueo_utf8) }
+ end
+
+ def test_from_sjis
+ assert_nothing_raised { assert_equal utf8_docomo(@aiueo_utf8), to_utf8_docomo(@aiueo_sjis) }
+ assert_nothing_raised { assert_equal sjis_docomo(@aiueo_sjis), to_sjis_docomo(@aiueo_sjis) }
+ end
+
+ def test_to_utf8
+ assert_nothing_raised { assert_equal @utf8, to_utf8(@utf8_docomo) }
+ assert_nothing_raised { assert_equal @utf8, to_utf8(@sjis_docomo) }
+ end
+
+ def test_to_sjis
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis(@utf8_docomo) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis(@sjis_docomo) }
+ end
+
+ def test_to_eucjp
+ assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@utf8_docomo) }
+ assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@sjis_docomo) }
+ end
+
+ def test_docomo
+ assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@sjis_docomo) }
+ assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_docomo) }
+ end
+
+ def test_to_kddi
+ assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@utf8_docomo) }
+ assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@utf8_docomo) }
+ assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@utf8_docomo) }
+
+ assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@sjis_docomo) }
+ assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@sjis_docomo) }
+ assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@sjis_docomo) }
+
+ assert_raise(Encoding::UndefinedConversionError) { to_utf8_kddi(@utf8_docomo_only) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis_kddi(@utf8_docomo_only) }
+ assert_raise(Encoding::UndefinedConversionError) { to_iso2022jp_kddi(@utf8_docomo_only) }
+
+ assert_raise(Encoding::UndefinedConversionError) { to_utf8_kddi(@sjis_docomo_only) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis_kddi(@sjis_docomo_only) }
+ assert_raise(Encoding::UndefinedConversionError) { to_iso2022jp_kddi(@sjis_docomo_only) }
+ end
+
+ def test_to_softbank
+ assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_docomo) }
+ assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_docomo) }
+
+ assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@sjis_docomo) }
+ assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@sjis_docomo) }
+
+ assert_raise(Encoding::UndefinedConversionError) { to_utf8_softbank(@utf8_docomo_only) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis_softbank(@utf8_docomo_only) }
+
+ assert_raise(Encoding::UndefinedConversionError) { to_utf8_softbank(@sjis_docomo_only) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis_softbank(@sjis_docomo_only) }
+ end
+ end
+
+ class TestKDDI < Test::Unit::TestCase
+ include Emoji
+
+ def setup
+ setup_instance_variable(self)
+ end
+
+ def test_encoding_name
+ %w(UTF8-KDDI
+ SJIS-KDDI
+ ISO-2022-JP-KDDI
+ stateless-ISO-2022-JP-KDDI).each do |n|
+ assert Encoding.name_list.include?(n), "encoding not found: #{n}"
+ end
+ end
+
+ def test_comparison
+ assert_not_equal Encoding::UTF_8, Encoding::UTF8_KDDI
+ assert_not_equal Encoding::Windows_31J, Encoding::SJIS_KDDI
+ assert_not_equal Encoding::ISO_2022_JP, Encoding::ISO_2022_JP_KDDI
+ assert_not_equal Encoding::Stateless_ISO_2022_JP, Encoding::Stateless_ISO_2022_JP_KDDI
+ end
+
+ def test_from_utf8
+ assert_nothing_raised { assert_equal utf8_kddi(@aiueo_utf8), to_utf8_kddi(@aiueo_utf8) }
+ assert_nothing_raised { assert_equal sjis_kddi(@aiueo_sjis), to_sjis_kddi(@aiueo_utf8) }
+ assert_nothing_raised { assert_equal iso2022jp_kddi(@aiueo_iso2022jp), to_iso2022jp_kddi(@aiueo_utf8) }
+ end
+
+ def test_from_sjis
+ assert_nothing_raised { assert_equal utf8_kddi(@aiueo_utf8), to_utf8_kddi(@aiueo_sjis) }
+ assert_nothing_raised { assert_equal sjis_kddi(@aiueo_sjis), to_sjis_kddi(@aiueo_sjis) }
+ assert_nothing_raised { assert_equal iso2022jp_kddi(@aiueo_iso2022jp), to_iso2022jp_kddi(@aiueo_sjis) }
+ end
+
+ def test_from_iso2022jp
+ assert_nothing_raised { assert_equal utf8_kddi(@aiueo_utf8), to_utf8_kddi(@aiueo_iso2022jp) }
+ assert_nothing_raised { assert_equal sjis_kddi(@aiueo_sjis), to_sjis_kddi(@aiueo_iso2022jp) }
+ assert_nothing_raised { assert_equal iso2022jp_kddi(@aiueo_iso2022jp), to_iso2022jp_kddi(@aiueo_iso2022jp) }
+ end
+
+ def test_to_utf8
+ assert_nothing_raised { assert_equal @utf8, to_utf8(@utf8_kddi) }
+ assert_nothing_raised { assert_equal @utf8, to_utf8(@utf8_undoc_kddi) }
+ assert_nothing_raised { assert_equal @utf8, to_utf8(@sjis_kddi) }
+ assert_nothing_raised { assert_equal @utf8, to_utf8(@iso2022jp_kddi) }
+ end
+
+ def test_to_sjis
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis(@utf8_kddi) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis(@utf8_undoc_kddi) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis(@sjis_kddi) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis(@iso2022jp_kddi) }
+ end
+
+ def test_to_eucjp
+ assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@utf8_kddi) }
+ assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@utf8_undoc_kddi) }
+ assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@sjis_kddi) }
+ assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@iso2022jp_kddi) }
+ end
+
+ def test_kddi
+ assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@sjis_kddi) }
+ assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@iso2022jp_kddi) }
+ assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@sjis_kddi) }
+ assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@utf8_undoc_kddi) }
+ assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@iso2022jp_kddi) }
+ assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@sjis_kddi) }
+ assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@utf8_undoc_kddi) }
+ assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@iso2022jp_kddi) }
+ end
+
+ def test_to_docomo
+ assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_kddi) }
+ assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_kddi) }
+
+ assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_undoc_kddi) }
+ assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_undoc_kddi) }
+
+ assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@sjis_kddi) }
+ assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@sjis_kddi) }
+
+ assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@iso2022jp_kddi) }
+ assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@iso2022jp_kddi) }
+
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_kddi_only) }
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_kddi_only) }
+
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_undoc_kddi_only) }
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_undoc_kddi_only) }
+
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_docomo, to_utf8_docomo(@sjis_kddi_only) }
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_docomo, to_sjis_docomo(@sjis_kddi_only) }
+
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_docomo, to_utf8_docomo(@iso2022jp_kddi_only) }
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_docomo, to_sjis_docomo(@iso2022jp_kddi_only) }
+ end
+
+ def test_to_softbank
+ assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_kddi) }
+ assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_kddi) }
+
+ assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_undoc_kddi) }
+ assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_undoc_kddi) }
+
+ assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@sjis_kddi) }
+ assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@sjis_kddi) }
+
+ assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@iso2022jp_kddi) }
+ assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@iso2022jp_kddi) }
+
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_kddi_only) }
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_kddi_only) }
+
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_softbank, to_utf8_softbank(@utf8_undoc_kddi_only) }
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_undoc_kddi_only) }
+
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_softbank, to_utf8_softbank(@sjis_kddi_only) }
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_softbank, to_sjis_softbank(@sjis_kddi_only) }
+
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @utf8_softbank, to_utf8_softbank(@iso2022jp_kddi_only) }
+ assert_raise(Encoding::UndefinedConversionError) { assert_equal @sjis_softbank, to_sjis_softbank(@iso2022jp_kddi_only) }
+ end
+ end
+
+ class TestSoftBank < Test::Unit::TestCase
+ include Emoji
+
+ def setup
+ setup_instance_variable(self)
+ end
+
+ def test_encoding_name
+ %w(UTF8-SoftBank
+ SJIS-SoftBank).each do |n|
+ assert Encoding.name_list.include?(n), "encoding not found: #{n}"
+ end
+ end
+
+ def test_comparison
+ assert_not_equal Encoding::UTF_8, Encoding::UTF8_SoftBank
+ assert_not_equal Encoding::Windows_31J, Encoding::SJIS_SoftBank
+ end
+
+ def test_from_utf8
+ assert_nothing_raised { assert_equal utf8_softbank(@aiueo_utf8), to_utf8_softbank(@aiueo_utf8) }
+ assert_nothing_raised { assert_equal sjis_softbank(@aiueo_sjis), to_sjis_softbank(@aiueo_utf8) }
+ end
+
+ def test_from_sjis
+ assert_nothing_raised { assert_equal utf8_softbank(@aiueo_utf8), to_utf8_softbank(@aiueo_sjis) }
+ assert_nothing_raised { assert_equal sjis_softbank(@aiueo_sjis), to_sjis_softbank(@aiueo_sjis) }
+ end
+
+ def test_to_utf8
+ assert_nothing_raised { assert_equal @utf8, to_utf8(@utf8_softbank) }
+ assert_nothing_raised { assert_equal @utf8, to_utf8(@sjis_softbank) }
+ end
+
+ def test_to_sjis
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis(@utf8_softbank) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis(@sjis_softbank) }
+ end
+
+ def test_to_eucjp
+ assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@utf8_softbank) }
+ assert_raise(Encoding::UndefinedConversionError) { to_eucjp(@sjis_softbank) }
+ end
+
+ def test_softbank
+ assert_nothing_raised { assert_equal @utf8_softbank, to_utf8_softbank(@sjis_softbank) }
+ assert_nothing_raised { assert_equal @sjis_softbank, to_sjis_softbank(@utf8_softbank) }
+ end
+
+ def test_to_docomo
+ assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@utf8_softbank) }
+ assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@utf8_softbank) }
+
+ assert_nothing_raised { assert_equal @utf8_docomo, to_utf8_docomo(@sjis_softbank) }
+ assert_nothing_raised { assert_equal @sjis_docomo, to_sjis_docomo(@sjis_softbank) }
+
+ assert_raise(Encoding::UndefinedConversionError) { to_utf8_docomo(@utf8_softbank_only) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis_docomo(@utf8_softbank_only) }
+
+ assert_raise(Encoding::UndefinedConversionError) { to_utf8_docomo(@sjis_softbank_only) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis_docomo(@sjis_softbank_only) }
+ end
+
+ def test_to_kddi
+ assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@utf8_softbank) }
+ assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@utf8_softbank) }
+ assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@utf8_softbank) }
+
+ assert_nothing_raised { assert_equal @utf8_kddi, to_utf8_kddi(@sjis_softbank) }
+ assert_nothing_raised { assert_equal @sjis_kddi, to_sjis_kddi(@sjis_softbank) }
+ assert_nothing_raised { assert_equal @iso2022jp_kddi, to_iso2022jp_kddi(@sjis_softbank) }
+
+ assert_raise(Encoding::UndefinedConversionError) { to_utf8_kddi(@utf8_softbank_only) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis_kddi(@utf8_softbank_only) }
+ assert_raise(Encoding::UndefinedConversionError) { to_iso2022jp_kddi(@utf8_softbank_only) }
+
+ assert_raise(Encoding::UndefinedConversionError) { to_utf8_kddi(@sjis_softbank_only) }
+ assert_raise(Encoding::UndefinedConversionError) { to_sjis_kddi(@sjis_softbank_only) }
+ assert_raise(Encoding::UndefinedConversionError) { to_iso2022jp_kddi(@sjis_softbank_only) }
+ end
+ end
+
+ private
+
+ def setup_instance_variable(obj)
+ obj.instance_eval do
+ @aiueo_utf8 = "\u{3042}\u{3044}\u{3046}\u{3048}\u{304A}"
+ @aiueo_sjis = to_sjis(@aiueo_utf8)
+ @aiueo_iso2022jp = to_iso2022jp(@aiueo_utf8)
+
+ @utf8 = "\u{2600}"
+
+ @utf8_docomo = utf8_docomo("\u{E63E}")
+ @sjis_docomo = sjis_docomo("\xF8\x9F")
+ @utf8_docomo_only = utf8_docomo("\u{E6B1}")
+ @sjis_docomo_only = sjis_docomo("\xF9\x55")
+
+ @utf8_kddi = utf8_kddi("\u{E488}")
+ @utf8_undoc_kddi = utf8_kddi("\u{EF60}")
+ @sjis_kddi = sjis_kddi("\xF6\x60")
+ @iso2022jp_kddi = iso2022jp_kddi("\x1B$B\x75\x41\x1B(B")
+ @stateless_iso2022jp_kddi = stateless_iso2022jp_kddi("\x92\xF5\xC1")
+ @utf8_kddi_only = utf8_kddi("\u{E5B3}")
+ @utf8_undoc_kddi_only = utf8_kddi("\u{F0D0}")
+ @sjis_kddi_only = sjis_kddi("\xF7\xD0")
+ @iso2022jp_kddi_only = iso2022jp_kddi("\x1B$B\x78\x52\x1B(B")
+ @stateless_iso2022jp_kddi_only = stateless_iso2022jp_kddi("\x92\xF8\xD2")
+
+ @utf8_softbank = utf8_softbank("\u{E04A}")
+ @sjis_softbank = sjis_softbank("\xF9\x8B")
+ @utf8_softbank_only = utf8_softbank("\u{E524}")
+ @sjis_softbank_only = sjis_softbank("\xFB\xC4")
+ end
+ end
+
+ def utf8(str)
+ str.force_encoding("UTF-8")
+ end
+
+ def to_utf8(str)
+ str.encode("UTF-8")
+ end
+
+ def to_sjis(str)
+ str.encode("Windows-31J")
+ end
+
+ def to_eucjp(str)
+ str.encode("eucJP-ms")
+ end
+
+ def to_iso2022jp(str)
+ str.encode("ISO-2022-JP")
+ end
+
+ def utf8_docomo(str)
+ str.force_encoding("UTF8-DoCoMo")
+ end
+
+ def to_utf8_docomo(str)
+ str.encode("UTF8-DoCoMo")
+ end
+
+ def utf8_kddi(str)
+ str.force_encoding("UTF8-KDDI")
+ end
+
+ def to_utf8_kddi(str)
+ str.encode("UTF8-KDDI")
+ end
+
+ def utf8_softbank(str)
+ str.force_encoding("UTF8-SoftBank")
+ end
+
+ def to_utf8_softbank(str)
+ str.encode("UTF8-SoftBank")
+ end
+
+ def sjis_docomo(str)
+ str.force_encoding("SJIS-DoCoMo")
+ end
+
+ def to_sjis_docomo(str)
+ str.encode("SJIS-DoCoMo")
+ end
+
+ def sjis_kddi(str)
+ str.force_encoding("SJIS-KDDI")
+ end
+
+ def to_sjis_kddi(str)
+ str.encode("SJIS-KDDI")
+ end
+
+ def sjis_softbank(str)
+ str.force_encoding("SJIS-SoftBank")
+ end
+
+ def to_sjis_softbank(str)
+ str.encode("SJIS-SoftBank")
+ end
+
+ def iso2022jp_kddi(str)
+ str.force_encoding("ISO-2022-JP-KDDI")
+ end
+
+ def to_iso2022jp_kddi(str)
+ str.encode("ISO-2022-JP-KDDI")
+ end
+
+ def stateless_iso2022jp_kddi(str)
+ str.force_encoding("stateless-ISO-2022-JP-KDDI")
+ end
+
+ def to_stateless_iso2022jp_kddi(str)
+ str.encode("stateless-ISO-2022-JP-KDDI")
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_euc_jp.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_euc_jp.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_euc_jp.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,24 @@
+# vim: set fileencoding=euc-jp
+
+require "test/unit"
+
+class TestEUC_JP < Test::Unit::TestCase
+ def test_mbc_case_fold
+ assert_match(/(\xA3\xE1)(a)\1\2/i, "\xA3\xE1a\xA3\xE1A")
+ assert_no_match(/(\xA3\xE1)(a)\1\2/i, "\xA3\xE1a\xA3\xC1A")
+ end
+
+ def test_property
+ assert_match(/\xA4\xA2{0}\p{Hiragana}{4}/, "\xA4Ҥ餬\xA4\xCA")
+ assert_no_match(/\xA4\xA2{0}\p{Hiragana}{4}/, "\xA5\xAB\xA5\xBF\xA5\xAB\xA5\xCA")
+ assert_no_match(/\xA4\xA2{0}\p{Hiragana}{4}/, "\xB4\xC1\xBB\xFA\xB4\xC1\xBB\xFA")
+ assert_no_match(/\xA4\xA2{0}\p{Katakana}{4}/, "\xA4Ҥ餬\xA4\xCA")
+ assert_match(/\xA4\xA2{0}\p{Katakana}{4}/, "\xA5\xAB\xA5\xBF\xA5\xAB\xA5\xCA")
+ assert_no_match(/\xA4\xA2{0}\p{Katakana}{4}/, "\xB4\xC1\xBB\xFA\xB4\xC1\xBB\xFA")
+ assert_raise(RegexpError) { Regexp.new('\xA4\xA2{0}\p{foobarbaz}') }
+ end
+
+ def test_charboundary
+ assert_nil(/\xA2\xA2/ =~ "\xA1\xA2\xA2\xA3")
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_euc_kr.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_euc_kr.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_euc_kr.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestEucKr < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("euc-kr")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\xa1\xa1").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0xa1a1, s("\xa1\xa1").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\xa1\xa1"), 0xa1a1.chr("euc-kr"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\xa1\xa1)\\1"), "i")
+ assert_match(r, s("\xa1\xa1\xa1\xa1"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\xa1\xa1"), s("\xa1\xa1\xa1\xa1").chop)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_euc_tw.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_euc_tw.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_euc_tw.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestEucTw < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("euc-tw")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\xa1\xa1").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0xa1a1, s("\xa1\xa1").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\xa1\xa1"), 0xa1a1.chr("euc-tw"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\xa1\xa1)\\1"), "i")
+ assert_match(r, s("\xa1\xa1\xa1\xa1"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\xa1\xa1"), s("\xa1\xa1\xa1\xa1").chop)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_gb18030.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_gb18030.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_gb18030.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,126 @@
+require "test/unit"
+
+class TestGB18030 < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("gb18030")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\x81\x40").size)
+ assert_equal(1, s("\x81\x30\x81\x30").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0x8140, s("\x81\x40").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\x81\x40"), 0x8140.chr("gb18030"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\x81\x40)\\1"), "i")
+ assert_match(r, s("\x81\x40\x81\x40"))
+ end
+
+ def scheck(c, i)
+ assert_equal(s(c.reverse.take(c.size - i).join), s(c.reverse.join).chop)
+ end
+
+ def fcheck(c)
+ c = s(c.reverse.join)
+ assert_raise(ArgumentError, c) { c.chop }
+ end
+
+ def test_left_adjust_char_head
+ # C1: 00-2f, 3a-3f, 7f, ff
+ # C2: 40-7e, 80
+ # C4: 30-39
+ # CM: 81-fe
+ c1 = "\x2f"
+ c2 = "\x40"
+ c4 = "\x30"
+ cm = "\x81"
+
+ # S_START-c1
+ # S_START-c2-S_one_C2-0
+ # S_START-c2-S_one_C2-c1
+ # S_START-c2-S_one_C2-cm-S_odd_CM_one_CX-c1
+ # S_START-c2-S_one_C2-cm-S_odd_CM_one_CX-cm-S_even_CM_one_CX-c1
+ # S_START-c2-S_one_C2-cm-S_odd_CM_one_CX-cm-S_even_CM_one_CX-cm-S_odd_CM_one_CX(rec)
+ # S_START-c4-S_one_C4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-c4-S_one_C4_odd_CMC4(rec)
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-cm-S_odd_CM_odd_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-cm-S_odd_CM_odd_CMC4-cm-S_even_CM_odd_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-cm-S_odd_CM_odd_CMC4-cm-S_even_CM_odd_CMC4-cm-S_odd_CM_odd_CMC4(rec)
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-cm-S_odd_CM_even_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-cm-S_odd_CM_even_CMC4-cm-S_even_CM_even_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-cm-S_odd_CM_even_CMC4-cm-S_even_CM_even_CMC4-cm-S_odd_CM_even_CMC4(rec)
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-cm-S_even_CM_one_CX(rec)
+ # S_START-cm-S_one_CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-c4-S_odd_C4CM(rec)
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-cm-S_even_CM_even_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-cm-S_even_CM_even_C4CM-cm-S_odd_CM_even_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-cm-S_even_CM_even_C4CM-cm-S_odd_CM_even_C4CM-cm-S_even_CM_even_C4CM(rec)
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-cm-S_even_CM_odd_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-cm-S_even_CM_odd_C4CM-cm-S_odd_CM_odd_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-cm-S_even_CM_odd_C4CM-cm-S_odd_CM_odd_C4CM-cm-S_even_CM_odd_C4CM(rec)
+ # S_START-cm-S_one_CM-cm-S_odd_CM_one_CX(rec)
+
+ scheck([c1], 1)
+ scheck([c2], 1)
+ scheck([c2, c1], 1)
+ scheck([c2, cm, c1], 2)
+ scheck([c2, cm, cm, c1], 1)
+ scheck([c2, cm, cm, cm], 2)
+ scheck([c4], 1)
+ scheck([c4, c1], 1)
+ scheck([c4, cm], 2)
+ scheck([c4, cm, c1], 2)
+ scheck([c4, cm, c4, c1], 2)
+ scheck([c4, cm, c4, cm], 4)
+ scheck([c4, cm, c4, cm, c1], 4)
+ scheck([c4, cm, c4, cm, c4], 4)
+ scheck([c4, cm, c4, cm, c4, c1], 4)
+ scheck([c4, cm, c4, cm, c4, cm], 2)
+ scheck([c4, cm, c4, cm, c4, cm, c1], 2)
+ scheck([c4, cm, c4, cm, c4, cm, c4], 2)
+ scheck([c4, cm, c4, cm, c4, cm, cm, c1], 4)
+ scheck([c4, cm, c4, cm, c4, cm, cm, cm], 2)
+ scheck([c4, cm, c4, cm, c4, cm, cm, cm, c1], 2)
+ scheck([c4, cm, c4, cm, c4, cm, cm, cm, cm], 4)
+ scheck([c4, cm, c4, cm, cm, c1], 2)
+ scheck([c4, cm, c4, cm, cm, cm], 4)
+ scheck([c4, cm, c4, cm, cm, cm, c1], 4)
+ scheck([c4, cm, c4, cm, cm, cm, cm], 2)
+ scheck([c4, cm, cm], 1)
+ scheck([cm], 1)
+ scheck([cm, c1], 1)
+ scheck([cm, c4, c1], 1)
+ scheck([cm, c4, cm], 3)
+ scheck([cm, c4, cm, c1], 3)
+ scheck([cm, c4, cm, c4], 3)
+ scheck([cm, c4, cm, c4, c1], 3)
+ scheck([cm, c4, cm, c4, cm], 1)
+ scheck([cm, c4, cm, c4, cm, c1], 1)
+ scheck([cm, c4, cm, c4, cm, c4], 1)
+ scheck([cm, c4, cm, c4, cm, cm, c1], 3)
+ scheck([cm, c4, cm, c4, cm, cm, cm], 1)
+ scheck([cm, c4, cm, c4, cm, cm, cm, c1], 1)
+ scheck([cm, c4, cm, c4, cm, cm, cm, cm], 3)
+ scheck([cm, c4, cm, cm, c1], 1)
+ scheck([cm, c4, cm, cm, cm], 3)
+ scheck([cm, c4, cm, cm, cm, c1], 3)
+ scheck([cm, c4, cm, cm, cm, cm], 1)
+ scheck([cm, cm], 2)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_gbk.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_gbk.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_gbk.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestGBK < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("gbk")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\x81\x40").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0x8140, s("\x81\x40").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\x81\x40"), 0x8140.chr("gbk"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\x81\x40)\\1"), "i")
+ assert_match(r, s("\x81\x40\x81\x40"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\x81\x40"), s("\x81\x40\x81\x40").chop)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_iso_8859.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_iso_8859.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_iso_8859.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,163 @@
+require 'test/unit'
+
+class TestISO8859 < Test::Unit::TestCase
+ ASSERTS = %q(
+ assert_match(/^(\xdf)\1$/i, "\xdf\xdf")
+ assert_match(/^(\xdf)\1$/i, "ssss")
+ # assert_match(/^(\xdf)\1$/i, "\xdfss") # this must be bug...
+ assert_match(/^[\xdfz]+$/i, "sszzsszz")
+ assert_match(/^SS$/i, "\xdf")
+ assert_match(/^Ss$/i, "\xdf")
+ ((0xc0..0xde).to_a - [0xd7]).each do |c|
+ c1 = c.chr("ENCODING")
+ c2 = (c + 0x20).chr("ENCODING")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ assert_match(/^\xff$/i, "\xff")
+ )
+
+ def test_iso_8859_1
+ eval("# encoding: iso8859-1\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-1"))
+ end
+
+ def test_iso_8859_2
+ eval("# encoding: iso8859-2\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-2"))
+ end
+
+ def test_iso_8859_3
+ eval(%q(# encoding: iso8859-3
+ assert_match(/^(\xdf)\1$/i, "\xdf\xdf")
+ assert_match(/^(\xdf)\1$/i, "ssss")
+ assert_match(/^[\xdfz]+$/i, "sszzsszz")
+ assert_match(/^SS$/i, "\xdf")
+ assert_match(/^Ss$/i, "\xdf")
+ [0xa1, 0xa6, *(0xa9..0xac), 0xaf].each do |c|
+ c1 = c.chr("iso8859-3")
+ c2 = (c + 0x10).chr("iso8859-3")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ([*(0xc0..0xde)] - [0xc3, 0xd0, 0xd7]).each do |c|
+ c1 = c.chr("iso8859-3")
+ c2 = (c + 0x20).chr("iso8859-3")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ))
+ end
+
+ def test_iso_8859_4
+ eval("# encoding: iso8859-4\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-4"))
+ end
+
+ def test_iso_8859_5
+ eval(%q(# encoding: iso8859-5
+ (0xb0..0xcf).each do |c|
+ c1 = c.chr("iso8859-5")
+ c2 = (c + 0x20).chr("iso8859-5")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ((0xa1..0xaf).to_a - [0xad]).each do |c|
+ c1 = c.chr("iso8859-5")
+ c2 = (c + 0x50).chr("iso8859-5")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ))
+ end
+
+ def test_iso_8859_6
+ eval(%q(# encoding: iso8859-6
+ [0xa4, 0xac, 0xbb, 0xbf, *(0xc1..0xda), *(0xe0..0xf2)].each do |c|
+ c1 = c.chr("iso8859-6")
+ assert_match(/^(#{ c1 })\1$/i, c1 * 2)
+ end
+ ))
+ end
+
+ def test_iso_8859_7
+ eval(%q(# encoding: iso8859-7
+ ((0xa0..0xfe).to_a - [0xae, 0xd2]).each do |c|
+ c1 = c.chr("iso8859-7")
+ assert_match(/^(#{ c1 })\1$/i, c1 * 2)
+ end
+ ((0xc1..0xd9).to_a - [0xd2]).each do |c|
+ c1 = c.chr("iso8859-7")
+ c2 = (c + 0x20).chr("iso8859-7")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ))
+ end
+
+ def test_iso_8859_8
+ eval(%q(# encoding: iso8859-8
+ [0xa0, *(0xa2..0xbe), *(0xdf..0xfa), 0xfc, 0xfd].each do |c|
+ c1 = c.chr("iso8859-8")
+ assert_match(/^(#{ c1 })\1$/i, c1 * 2)
+ end
+ ))
+ end
+
+ def test_iso_8859_9
+ eval(%q(# encoding: iso8859-9
+ assert_match(/^(\xdf)\1$/i, "\xdf\xdf")
+ assert_match(/^(\xdf)\1$/i, "ssss")
+ assert_match(/^[\xdfz]+$/i, "sszzsszz")
+ assert_match(/^SS$/i, "\xdf")
+ assert_match(/^Ss$/i, "\xdf")
+ ([*(0xc0..0xdc)] - [0xd7]).each do |c|
+ c1 = c.chr("iso8859-9")
+ c2 = (c + 0x20).chr("iso8859-9")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ))
+ end
+
+ def test_iso_8859_10
+ eval("# encoding: iso8859-10\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-10"))
+ end
+
+ def test_iso_8859_11
+ eval(%q(# encoding: iso8859-11
+ [*(0xa0..0xda), *(0xdf..0xfb)].each do |c|
+ c1 = c.chr("iso8859-11")
+ assert_match(/^(#{ c1 })\1$/i, c1 * 2)
+ end
+ ))
+ end
+
+ def test_iso_8859_13
+ eval("# encoding: iso8859-13\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-13"))
+ end
+
+ def test_iso_8859_14
+ eval("# encoding: iso8859-14\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-14"))
+ end
+
+ def test_iso_8859_15
+ eval("# encoding: iso8859-15\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-15"))
+ end
+
+ def test_iso_8859_16
+ eval("# encoding: iso8859-16\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-16"))
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_koi8.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_koi8.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_koi8.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,22 @@
+require "test/unit"
+
+class TestKOI8 < Test::Unit::TestCase
+ ASSERTS = %q(
+ (0xc0..0xdf).each do |c|
+ c1 = c.chr("ENCODING")
+ c2 = (c + 0x20).chr("ENCODING")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ )
+
+ def test_koi8_r
+ eval("# encoding: koi8-r\n" + ASSERTS.gsub("ENCODING", "koi8-r"))
+ end
+
+ def test_koi8_u
+ eval("# encoding: koi8-u\n" + ASSERTS.gsub("ENCODING", "koi8-u"))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_shift_jis.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_shift_jis.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_shift_jis.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,27 @@
+# vim: set fileencoding=shift_jis
+
+require "test/unit"
+
+class TestShiftJIS < Test::Unit::TestCase
+ def test_mbc_case_fold
+ assert_match(/(\x82\x81)(a)\1\2/i, "\x82\x81a\x82\x81A")
+ assert_no_match(/(\x82\x81)(a)\1\2/i, "\x82\x81a\x82`A")
+ end
+
+ def test_property
+ assert_match(/\x82\xA0{0}\p{Hiragana}{4}/, "\x82Ђ炪\x82\xC8")
+ assert_no_match(/\x82\xA0{0}\p{Hiragana}{4}/, "\x83J\x83^\x83J\x83i")
+ assert_no_match(/\x82\xA0{0}\p{Hiragana}{4}/, "\x8A\xBF\x8E\x9A\x8A\xBF\x8E\x9A")
+ assert_no_match(/\x82\xA0{0}\p{Katakana}{4}/, "\x82Ђ炪\x82\xC8")
+ assert_match(/\x82\xA0{0}\p{Katakana}{4}/, "\x83J\x83^\x83J\x83i")
+ assert_no_match(/\x82\xA0{0}\p{Katakana}{4}/, "\x8A\xBF\x8E\x9A\x8A\xBF\x8E\x9A")
+ assert_raise(RegexpError) { Regexp.new('\x82\xA0{0}\p{foobarbaz}') }
+ end
+
+ def test_code_to_mbclen
+ s = "\x82\xA0\x82\xA2\x82\xA4\x82\xA6\x82\xA8"
+ s << 0x82a9
+ assert_equal("\x82\xA0\x82\xA2\x82\xA4\x82\xA6\x82\xA8\x82\xA9", s)
+ assert_raise(ArgumentError) { s << 0x82 }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_utf16.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_utf16.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_utf16.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,384 @@
+require 'test/unit'
+
+class TestUTF16 < Test::Unit::TestCase
+ def encdump(obj)
+ case obj
+ when String
+ d = obj.dump
+ if /\.force_encoding\("[A-Za-z0-9.:_+-]*"\)\z/ =~ d
+ d
+ else
+ "#{d}.force_encoding(#{obj.encoding.name.dump})"
+ end
+ when Regexp
+ "Regexp.new(#{encdump(obj.source)}, #{obj.options})"
+ else
+ raise Argument, "unexpected: #{obj.inspect}"
+ end
+ end
+
+ def enccall(recv, meth, *args)
+ desc = ''
+ if String === recv
+ desc << encdump(recv)
+ else
+ desc << recv.inspect
+ end
+ desc << '.' << meth.to_s
+ if !args.empty?
+ desc << '('
+ args.each_with_index {|a, i|
+ desc << ',' if 0 < i
+ if String === a
+ desc << encdump(a)
+ else
+ desc << a.inspect
+ end
+ }
+ desc << ')'
+ end
+ result = nil
+ assert_nothing_raised(desc) {
+ result = recv.send(meth, *args)
+ }
+ result
+ end
+
+ def assert_str_equal(expected, actual, message=nil)
+ full_message = build_message(message, <<EOT)
+#{encdump expected} expected but not equal to
+#{encdump actual}.
+EOT
+ assert_block(full_message) { expected == actual }
+ end
+
+ # tests start
+
+ def test_utf16be_valid_encoding
+ [
+ "\x00\x00",
+ "\xd7\xff",
+ "\xd8\x00\xdc\x00",
+ "\xdb\xff\xdf\xff",
+ "\xe0\x00",
+ "\xff\xff",
+ ].each {|s|
+ s.force_encoding("utf-16be")
+ assert_equal(true, s.valid_encoding?, "#{encdump s}.valid_encoding?")
+ }
+ [
+ "\x00",
+ "\xd7",
+ "\xd8\x00",
+ "\xd8\x00\xd8\x00",
+ "\xdc\x00",
+ "\xdc\x00\xd8\x00",
+ "\xdc\x00\xdc\x00",
+ "\xe0",
+ "\xff",
+ ].each {|s|
+ s.force_encoding("utf-16be")
+ assert_equal(false, s.valid_encoding?, "#{encdump s}.valid_encoding?")
+ }
+ end
+
+ def test_utf16le_valid_encoding
+ [
+ "\x00\x00",
+ "\xff\xd7",
+ "\x00\xd8\x00\xdc",
+ "\xff\xdb\xff\xdf",
+ "\x00\xe0",
+ "\xff\xff",
+ ].each {|s|
+ s.force_encoding("utf-16le")
+ assert_equal(true, s.valid_encoding?, "#{encdump s}.valid_encoding?")
+ }
+ [
+ "\x00",
+ "\xd7",
+ "\x00\xd8",
+ "\x00\xd8\x00\xd8",
+ "\x00\xdc",
+ "\x00\xdc\x00\xd8",
+ "\x00\xdc\x00\xdc",
+ "\xe0",
+ "\xff",
+ ].each {|s|
+ s.force_encoding("utf-16le")
+ assert_equal(false, s.valid_encoding?, "#{encdump s}.valid_encoding?")
+ }
+ end
+
+ def test_strftime
+ s = "aa".force_encoding("utf-16be")
+ assert_raise(ArgumentError, "Time.now.strftime(#{encdump s})") { Time.now.strftime(s) }
+ end
+
+ def test_intern
+ s = "aaaa".force_encoding("utf-16be")
+ assert_equal(s.encoding, s.intern.to_s.encoding, "#{encdump s}.intern.to_s.encoding")
+ end
+
+ def test_sym_eq
+ s = "aa".force_encoding("utf-16le")
+ assert(s.intern != :aa, "#{encdump s}.intern != :aa")
+ end
+
+ def test_compatible
+ s1 = "aa".force_encoding("utf-16be")
+ s2 = "z".force_encoding("us-ascii")
+ assert_nil(Encoding.compatible?(s1, s2), "Encoding.compatible?(#{encdump s1}, #{encdump s2})")
+ end
+
+ def test_casecmp
+ s1 = "aa".force_encoding("utf-16be")
+ s2 = "AA"
+ assert_not_equal(0, s1.casecmp(s2), "#{encdump s1}.casecmp(#{encdump s2})")
+ end
+
+ def test_end_with
+ s1 = "ab".force_encoding("utf-16be")
+ s2 = "b".force_encoding("utf-16be")
+ assert_equal(false, s1.end_with?(s2), "#{encdump s1}.end_with?(#{encdump s2})")
+ end
+
+ def test_hex
+ assert_raise(Encoding::CompatibilityError) {
+ "ff".encode("utf-16le").hex
+ }
+ assert_raise(Encoding::CompatibilityError) {
+ "ff".encode("utf-16be").hex
+ }
+ end
+
+ def test_oct
+ assert_raise(Encoding::CompatibilityError) {
+ "77".encode("utf-16le").oct
+ }
+ assert_raise(Encoding::CompatibilityError) {
+ "77".encode("utf-16be").oct
+ }
+ end
+
+ def test_count
+ s1 = "aa".force_encoding("utf-16be")
+ s2 = "aa"
+ assert_raise(Encoding::CompatibilityError, "#{encdump s1}.count(#{encdump s2})") {
+ s1.count(s2)
+ }
+ end
+
+ def test_plus
+ s1 = "a".force_encoding("us-ascii")
+ s2 = "aa".force_encoding("utf-16be")
+ assert_raise(Encoding::CompatibilityError, "#{encdump s1} + #{encdump s2}") {
+ s1 + s2
+ }
+ end
+
+ def test_encoding_find
+ assert_raise(ArgumentError) {
+ Encoding.find("utf-8".force_encoding("utf-16be"))
+ }
+ end
+
+ def test_interpolation
+ s = "aa".force_encoding("utf-16be")
+ assert_raise(Encoding::CompatibilityError, "\"a\#{#{encdump s}}\"") {
+ "a#{s}"
+ }
+ end
+
+ def test_slice!
+ enccall("aa".force_encoding("UTF-16BE"), :slice!, -1)
+ end
+
+ def test_plus_empty1
+ s1 = ""
+ s2 = "aa".force_encoding("utf-16be")
+ assert_nothing_raised("#{encdump s1} << #{encdump s2}") {
+ s1 + s2
+ }
+ end
+
+ def test_plus_empty2
+ s1 = "aa"
+ s2 = "".force_encoding("utf-16be")
+ assert_nothing_raised("#{encdump s1} << #{encdump s2}") {
+ s1 + s2
+ }
+ end
+
+ def test_plus_nonempty
+ s1 = "aa"
+ s2 = "bb".force_encoding("utf-16be")
+ assert_raise(Encoding::CompatibilityError, "#{encdump s1} << #{encdump s2}") {
+ s1 + s2
+ }
+ end
+
+ def test_concat_empty1
+ s1 = ""
+ s2 = "aa".force_encoding("utf-16be")
+ assert_nothing_raised("#{encdump s1} << #{encdump s2}") {
+ s1 << s2
+ }
+ end
+
+ def test_concat_empty2
+ s1 = "aa"
+ s2 = "".force_encoding("utf-16be")
+ assert_nothing_raised("#{encdump s1} << #{encdump s2}") {
+ s1 << s2
+ }
+ end
+
+ def test_concat_nonempty
+ s1 = "aa"
+ s2 = "bb".force_encoding("utf-16be")
+ assert_raise(Encoding::CompatibilityError, "#{encdump s1} << #{encdump s2}") {
+ s1 << s2
+ }
+ end
+
+ def test_chomp
+ s = "\1\n".force_encoding("utf-16be")
+ assert_equal(s, s.chomp, "#{encdump s}.chomp")
+ s = "\0\n".force_encoding("utf-16be")
+ assert_equal("", s.chomp, "#{encdump s}.chomp")
+ s = "\0\r\0\n".force_encoding("utf-16be")
+ assert_equal("", s.chomp, "#{encdump s}.chomp")
+ end
+
+ def test_succ
+ s = "\xff\xff".force_encoding("utf-16be")
+ assert(s.succ.valid_encoding?, "#{encdump s}.succ.valid_encoding?")
+
+ s = "\xdb\xff\xdf\xff".force_encoding("utf-16be")
+ assert(s.succ.valid_encoding?, "#{encdump s}.succ.valid_encoding?")
+ end
+
+ def test_regexp_union
+ enccall(Regexp, :union, "aa".force_encoding("utf-16be"), "bb".force_encoding("utf-16be"))
+ end
+
+ def test_empty_regexp
+ s = "".force_encoding("utf-16be")
+ assert_equal(Encoding.find("utf-16be"), Regexp.new(s).encoding,
+ "Regexp.new(#{encdump s}).encoding")
+ end
+
+ def test_regexp_match
+ assert_raise(Encoding::CompatibilityError) { Regexp.new("aa".force_encoding("utf-16be")) =~ "aa" }
+ end
+
+ def test_gsub
+ s = "abcd".force_encoding("utf-16be")
+ assert_nothing_raised {
+ s.gsub(Regexp.new(".".encode("utf-16be")), "xy")
+ }
+ s = "ab\0\ncd".force_encoding("utf-16be")
+ assert_raise(Encoding::CompatibilityError) {
+ s.gsub(Regexp.new(".".encode("utf-16be")), "xy")
+ }
+ end
+
+ def test_split_awk
+ s = " ab cd ".encode("utf-16be")
+ r = s.split(" ".encode("utf-16be"))
+ assert_equal(2, r.length)
+ assert_str_equal("ab".encode("utf-16be"), r[0])
+ assert_str_equal("cd".encode("utf-16be"), r[1])
+ end
+
+ def test_count2
+ e = "abc".count("^b")
+ assert_equal(e, "abc".encode("utf-16be").count("^b".encode("utf-16be")))
+ assert_equal(e, "abc".encode("utf-16le").count("^b".encode("utf-16le")))
+ end
+
+ def test_header
+ assert_raise(ArgumentError) { eval("# encoding:utf-16le\nfoo") }
+ assert_raise(ArgumentError) { eval("# encoding:utf-16be\nfoo") }
+ end
+
+
+ def test_is_mbc_newline
+ sl = "f\0o\0o\0\n\0b\0a\0r\0\n\0b\0a\0z\0\n\0".force_encoding("utf-16le")
+ sb = "\0f\0o\0o\0\n\0b\0a\0r\0\n\0b\0a\0z\0\n".force_encoding("utf-16be")
+ al = sl.lines.to_a
+ ab = sb.lines.to_a
+ assert_equal("f\0o\0o\0\n\0".force_encoding("utf-16le"), al.shift)
+ assert_equal("b\0a\0r\0\n\0".force_encoding("utf-16le"), al.shift)
+ assert_equal("b\0a\0z\0\n\0".force_encoding("utf-16le"), al.shift)
+ assert_equal("\0f\0o\0o\0\n".force_encoding("utf-16be"), ab.shift)
+ assert_equal("\0b\0a\0r\0\n".force_encoding("utf-16be"), ab.shift)
+ assert_equal("\0b\0a\0z\0\n".force_encoding("utf-16be"), ab.shift)
+
+ sl = "f\0o\0o\0\n\0".force_encoding("utf-16le")
+ sb = "\0f\0o\0o\0\n".force_encoding("utf-16be")
+ sl2 = "f\0o\0o\0".force_encoding("utf-16le")
+ sb2 = "\0f\0o\0o".force_encoding("utf-16be")
+ assert_equal(sl2, sl.chomp)
+ assert_equal(sl2, sl.chomp.chomp)
+ assert_equal(sb2, sb.chomp)
+ assert_equal(sb2, sb.chomp.chomp)
+
+ sl = "f\0o\0o\0\n".force_encoding("utf-16le")
+ sb = "\0f\0o\0o\n".force_encoding("utf-16be")
+ assert_equal(sl, sl.chomp)
+ assert_equal(sb, sb.chomp)
+ end
+
+ def test_code_to_mbc
+ assert_equal("a\0".force_encoding("utf-16le"), "a".ord.chr("utf-16le"))
+ assert_equal("\0a".force_encoding("utf-16be"), "a".ord.chr("utf-16be"))
+ end
+
+ def utf8_to_utf16(s, e)
+ s.chars.map {|c| c.ord.chr(e) }.join
+ end
+
+ def test_mbc_case_fold
+ rl = Regexp.new(utf8_to_utf16("^(\u3042)(a)\\1\\2$", "utf-16le"), "i")
+ rb = Regexp.new(utf8_to_utf16("^(\u3042)(a)\\1\\2$", "utf-16be"), "i")
+ assert_equal(Encoding.find("utf-16le"), rl.encoding)
+ assert_equal(Encoding.find("utf-16be"), rb.encoding)
+ assert_match(rl, utf8_to_utf16("\u3042a\u3042a", "utf-16le"))
+ assert_match(rb, utf8_to_utf16("\u3042a\u3042a", "utf-16be"))
+ end
+
+ def test_surrogate_pair
+ sl = "\x42\xd8\xb7\xdf".force_encoding("utf-16le")
+ sb = "\xd8\x42\xdf\xb7".force_encoding("utf-16be")
+
+ assert_equal(1, sl.size)
+ assert_equal(1, sb.size)
+ assert_equal(0x20bb7, sl.ord)
+ assert_equal(0x20bb7, sb.ord)
+ assert_equal(sl, 0x20bb7.chr("utf-16le"))
+ assert_equal(sb, 0x20bb7.chr("utf-16be"))
+ assert_equal("", sl.chop)
+ assert_equal("", sb.chop)
+ end
+
+ def test_regexp_escape
+ s = "\0*".force_encoding("UTF-16BE")
+ r = Regexp.new(Regexp.escape(s))
+ assert(r =~ s, "#{encdump(r)} =~ #{encdump(s)}")
+ end
+
+ def test_casecmp2
+ assert_equal(0, "\0A".force_encoding("UTF-16BE").casecmp("\0a".force_encoding("UTF-16BE")))
+ assert_not_equal(0, "\0A".force_encoding("UTF-16LE").casecmp("\0a".force_encoding("UTF-16LE")))
+ assert_not_equal(0, "A\0".force_encoding("UTF-16BE").casecmp("a\0".force_encoding("UTF-16BE")))
+ assert_equal(0, "A\0".force_encoding("UTF-16LE").casecmp("a\0".force_encoding("UTF-16LE")))
+
+ ary = ["01".force_encoding("UTF-16LE"),
+ "10".force_encoding("UTF-16LE")]
+ e = ary.sort {|x,y| x <=> y }
+ a = ary.sort {|x,y| x.casecmp(y) }
+ assert_equal(e, a)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_utf32.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_utf32.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_utf32.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,93 @@
+require 'test/unit'
+
+class TestUTF32 < Test::Unit::TestCase
+ def encdump(str)
+ d = str.dump
+ if /\.force_encoding\("[A-Za-z0-9.:_+-]*"\)\z/ =~ d
+ d
+ else
+ "#{d}.force_encoding(#{str.encoding.name.dump})"
+ end
+ end
+
+ def assert_str_equal(expected, actual, message=nil)
+ full_message = build_message(message, <<EOT)
+#{encdump expected} expected but not equal to
+#{encdump actual}.
+EOT
+ assert_block(full_message) { expected == actual }
+ end
+
+ def test_substr
+ assert_str_equal(
+ "abcdefgh".force_encoding("utf-32le"),
+ "abcdefgh".force_encoding("utf-32le")[0,3])
+ assert_str_equal(
+ "abcdefgh".force_encoding("utf-32be"),
+ "abcdefgh".force_encoding("utf-32be")[0,3])
+ end
+
+ def test_mbc_len
+ al = "abcdefghijkl".force_encoding("utf-32le").each_char.to_a
+ ab = "abcdefghijkl".force_encoding("utf-32be").each_char.to_a
+ assert_equal("abcd".force_encoding("utf-32le"), al.shift)
+ assert_equal("efgh".force_encoding("utf-32le"), al.shift)
+ assert_equal("ijkl".force_encoding("utf-32le"), al.shift)
+ assert_equal("abcd".force_encoding("utf-32be"), ab.shift)
+ assert_equal("efgh".force_encoding("utf-32be"), ab.shift)
+ assert_equal("ijkl".force_encoding("utf-32be"), ab.shift)
+ end
+
+ def ascii_to_utf16le(s)
+ s.unpack("C*").map {|x| [x,0,0,0] }.flatten.pack("C*").force_encoding("utf-32le")
+ end
+
+ def ascii_to_utf16be(s)
+ s.unpack("C*").map {|x| [0,0,0,x] }.flatten.pack("C*").force_encoding("utf-32be")
+ end
+
+ def test_mbc_newline
+ al = ascii_to_utf16le("foo\nbar\nbaz\n").lines.to_a
+ ab = ascii_to_utf16be("foo\nbar\nbaz\n").lines.to_a
+
+ assert_equal(ascii_to_utf16le("foo\n"), al.shift)
+ assert_equal(ascii_to_utf16le("bar\n"), al.shift)
+ assert_equal(ascii_to_utf16le("baz\n"), al.shift)
+ assert_equal(ascii_to_utf16be("foo\n"), ab.shift)
+ assert_equal(ascii_to_utf16be("bar\n"), ab.shift)
+ assert_equal(ascii_to_utf16be("baz\n"), ab.shift)
+
+ sl = "a\0".force_encoding("utf-32le")
+ sb = "a\0".force_encoding("utf-32be")
+ assert_equal(sl, sl.chomp)
+ assert_equal(sb, sb.chomp)
+ end
+
+ def test_mbc_to_code
+ sl = "a\0\0\0".force_encoding("utf-32le")
+ sb = "\0\0\0a".force_encoding("utf-32be")
+ assert_equal("a".ord, sl.ord)
+ assert_equal("a".ord, sb.ord)
+ end
+
+ def utf8_to_utf32(s, e)
+ s.chars.map {|c| c.ord.chr(e) }.join
+ end
+
+ def test_mbc_case_fold
+ rl = Regexp.new(utf8_to_utf32("^(\u3042)(a)\\1\\2$", "utf-32le"), "i")
+ rb = Regexp.new(utf8_to_utf32("^(\u3042)(a)\\1\\2$", "utf-32be"), "i")
+ assert_equal(Encoding.find("utf-32le"), rl.encoding)
+ assert_equal(Encoding.find("utf-32be"), rb.encoding)
+ assert_match(rl, utf8_to_utf32("\u3042a\u3042a", "utf-32le"))
+ assert_match(rb, utf8_to_utf32("\u3042a\u3042a", "utf-32be"))
+ end
+
+ def test_code_to_mbc
+ sl = "a\0\0\0".force_encoding("utf-32le")
+ sb = "\0\0\0a".force_encoding("utf-32be")
+ assert_equal(sl, "a".ord.chr("utf-32le"))
+ assert_equal(sb, "a".ord.chr("utf-32be"))
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/ruby/enc/test_windows_1251.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/enc/test_windows_1251.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/enc/test_windows_1251.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,16 @@
+# encoding:windows-1251
+
+require "test/unit"
+
+class TestWindows1251 < Test::Unit::TestCase
+ def test_windows_1251
+ (0xc0..0xdf).each do |c|
+ c1 = c.chr("windows-1251")
+ c2 = (c + 0x20).chr("windows-1251")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/endblockwarn_rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/endblockwarn_rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/endblockwarn_rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,12 @@
+def end1
+ END {}
+end
+
+end1
+
+eval <<EOE
+ def end2
+ END {}
+ end
+EOE
+
Added: MacRuby/trunk/test/test-mri/test/ruby/envutil.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/envutil.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/envutil.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,213 @@
+require "open3"
+require "timeout"
+
+TIMEOUT = 5
+
+module EnvUtil
+ def rubybin
+ "/usr/local/bin/macruby"
+ end
+ module_function :rubybin
+
+ LANG_ENVS = %w"LANG LC_ALL LC_CTYPE"
+
+ def rubyexec(*args)
+ ruby = "/usr/local/bin/macruby"
+ c = "C"
+ env = {}
+ LANG_ENVS.each {|lc| env[lc], ENV[lc] = ENV[lc], c}
+ stdin = stdout = stderr = nil
+ Timeout.timeout(TIMEOUT) do
+ stdin, stdout, stderr = Open3.popen3(*([ruby] + args))
+ env.each_pair {|lc, v|
+ if v
+ ENV[lc] = v
+ else
+ ENV.delete(lc)
+ end
+ }
+ env = nil
+ yield(stdin, stdout, stderr)
+ end
+
+ ensure
+ env.each_pair {|lc, v|
+ if v
+ ENV[lc] = v
+ else
+ ENV.delete(lc)
+ end
+ } if env
+ stdin .close unless !stdin || stdin .closed?
+ stdout.close unless !stdout || stdout.closed?
+ stderr.close unless !stderr || stderr.closed?
+ end
+ module_function :rubyexec
+
+ def invoke_ruby(args, stdin_data="", capture_stdout=false, capture_stderr=false, opt={})
+ args = [args] if args.kind_of?(String)
+ begin
+ in_c, in_p = IO.pipe
+ out_p, out_c = IO.pipe if capture_stdout
+ err_p, err_c = IO.pipe if capture_stderr
+ opt = opt.dup
+ opt[:in] = in_c
+ opt[:out] = out_c if capture_stdout
+ opt[:err] = err_c if capture_stderr
+ if enc = opt.delete(:encoding)
+ out_p.set_encoding(enc) if out_p
+ err_p.set_encoding(enc) if err_p
+ end
+ c = "C"
+ child_env = {}
+ LANG_ENVS.each {|lc| child_env[lc] = c}
+ case args.first
+ when Hash
+ child_env.update(args.shift)
+ end
+ pid = spawn(child_env, EnvUtil.rubybin, *args, opt)
+ in_c.close
+ out_c.close if capture_stdout
+ err_c.close if capture_stderr
+ th_stdout = Thread.new { out_p.read } if capture_stdout
+ th_stderr = Thread.new { err_p.read } if capture_stderr
+ in_p.write stdin_data.to_str
+ in_p.close
+ if (!capture_stdout || th_stdout.join(TIMEOUT)) && (!capture_stderr || th_stderr.join(TIMEOUT))
+ stdout = th_stdout.value if capture_stdout
+ stderr = th_stderr.value if capture_stderr
+ else
+ raise Timeout::Error
+ end
+ out_p.close if capture_stdout
+ err_p.close if capture_stderr
+ Process.wait pid
+ status = $?
+ ensure
+ in_c.close if in_c && !in_c.closed?
+ in_p.close if in_p && !in_p.closed?
+ out_c.close if out_c && !out_c.closed?
+ out_p.close if out_p && !out_p.closed?
+ err_c.close if err_c && !err_c.closed?
+ err_p.close if err_p && !err_p.closed?
+ (th_stdout.kill; th_stdout.join) if th_stdout
+ (th_stderr.kill; th_stderr.join) if th_stderr
+ end
+ return stdout, stderr, status
+ end
+ module_function :invoke_ruby
+
+ def verbose_warning
+ class << (stderr = "")
+ alias write <<
+ end
+ stderr, $stderr, verbose, $VERBOSE = $stderr, stderr, $VERBOSE, true
+ yield stderr
+ ensure
+ stderr, $stderr, $VERBOSE = $stderr, stderr, verbose
+ return stderr
+ end
+ module_function :verbose_warning
+
+ def under_gc_stress
+ stress, GC.stress = GC.stress, true
+ yield
+ ensure
+ GC.stress = stress
+ end
+ module_function :under_gc_stress
+end
+
+module Test
+ module Unit
+ module Assertions
+ public
+ def assert_normal_exit(testsrc, message = '')
+ in_c, in_p = IO.pipe
+ out_p, out_c = IO.pipe
+ pid = spawn(EnvUtil.rubybin, '-W0', STDIN=>in_c, STDOUT=>out_c, STDERR=>out_c)
+ in_c.close
+ out_c.close
+ in_p.write testsrc
+ in_p.close
+ msg = out_p.read
+ out_p.close
+ Process.wait pid
+ status = $?
+ faildesc = nil
+ if status.signaled?
+ signo = status.termsig
+ signame = Signal.list.invert[signo]
+ sigdesc = "signal #{signo}"
+ if signame
+ sigdesc = "SIG#{signame} (#{sigdesc})"
+ end
+ if status.coredump?
+ sigdesc << " (core dumped)"
+ end
+ full_message = ''
+ if !message.empty?
+ full_message << message << "\n"
+ end
+ if msg.empty?
+ full_message << "pid #{pid} killed by #{sigdesc}"
+ else
+ msg << "\n" if /\n\z/ !~ msg
+ full_message << "pid #{pid} killed by #{sigdesc}\n#{msg.gsub(/^/, '| ')}"
+ end
+ end
+ assert_block(full_message) { !status.signaled? }
+ ensure
+ in_c.close if in_c && !in_c.closed?
+ in_p.close if in_p && !in_p.closed?
+ out_c.close if out_c && !out_c.closed?
+ out_p.close if out_p && !out_p.closed?
+ end
+
+ def assert_in_out_err(args, test_stdin = "", test_stdout = [], test_stderr = [], message = nil, opt={})
+ stdout, stderr, status = EnvUtil.invoke_ruby(args, test_stdin, true, true, opt)
+ if block_given?
+ yield(stdout.lines.map {|l| l.chomp }, stderr.lines.map {|l| l.chomp })
+ else
+ if test_stdout.is_a?(Regexp)
+ assert_match(test_stdout, stdout, message)
+ else
+ assert_equal(test_stdout, stdout.lines.map {|l| l.chomp }, message)
+ end
+ if test_stderr.is_a?(Regexp)
+ assert_match(test_stderr, stderr, message)
+ else
+ assert_equal(test_stderr, stderr.lines.map {|l| l.chomp }, message)
+ end
+ status
+ end
+ end
+
+ def assert_ruby_status(args, test_stdin="", message=nil, opt={})
+ stdout, stderr, status = EnvUtil.invoke_ruby(args, test_stdin, false, false, opt)
+ m = message ? "#{message} (#{status.inspect})" : "ruby exit status is not success: #{status.inspect}"
+ assert(status.success?, m)
+ end
+
+ end
+ end
+end
+
+begin
+ require 'rbconfig'
+rescue LoadError
+else
+ module RbConfig
+ @ruby = EnvUtil.rubybin
+ class << self
+ undef ruby if method_defined?(:ruby)
+ attr_reader :ruby
+ end
+ dir = File.dirname(ruby)
+ name = File.basename(ruby, CONFIG['EXEEXT'])
+ CONFIG['bindir'] = dir
+ CONFIG['ruby_install_name'] = name
+ CONFIG['RUBY_INSTALL_NAME'] = name
+ Gem::ConfigMap[:bindir] = dir if defined?(Gem)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/lbtest.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/lbtest.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/lbtest.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,48 @@
+require 'thread'
+
+class LocalBarrier
+ def initialize(n)
+ @wait = Queue.new
+ @done = Queue.new
+ @keeper = begin_keeper(n)
+ end
+
+ def sync
+ @done.push(true)
+ @wait.pop
+ end
+
+ def join
+ @keeper.join
+ end
+
+ private
+ def begin_keeper(n)
+ Thread.start do
+ n.times do
+ @done.pop
+ end
+ n.times do
+ @wait.push(true)
+ end
+ end
+ end
+end
+
+n = 10
+
+lb = LocalBarrier.new(n)
+
+(n - 1).times do |i|
+ Thread.start do
+ sleep((rand(n) + 1) / 10.0)
+ puts "#{i}: done"
+ lb.sync
+ puts "#{i}: cont"
+ end
+end
+
+lb.sync
+puts "#{n-1}: cone"
+
+puts "exit."
Added: MacRuby/trunk/test/test-mri/test/ruby/marshaltestlib.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/marshaltestlib.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/marshaltestlib.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,506 @@
+# coding: utf-8
+module MarshalTestLib
+ # include this module to a Test::Unit::TestCase and definde encode(o) and
+ # decode(s) methods. e.g.
+ #
+ # def encode(o)
+ # SOAPMarshal.dump(o)
+ # end
+ #
+ # def decode(s)
+ # SOAPMarshal.load(s)
+ # end
+
+ NegativeZero = (-1.0 / (1.0 / 0.0))
+
+ module Mod1; end
+ module Mod2; end
+
+ def marshaltest(o1)
+ str = encode(o1)
+ print str.dump, "\n" if $DEBUG
+ o2 = decode(str)
+ o2
+ end
+
+ def marshal_equal(o1, msg = nil)
+ msg = msg ? msg + "(#{ caller[0] })" : caller[0]
+ o2 = marshaltest(o1)
+ assert_equal(o1.class, o2.class, msg)
+ iv1 = o1.instance_variables.sort
+ iv2 = o2.instance_variables.sort
+ assert_equal(iv1, iv2)
+ val1 = iv1.map {|var| o1.instance_eval {eval var.to_s}}
+ val2 = iv1.map {|var| o2.instance_eval {eval var.to_s}}
+ assert_equal(val1, val2, msg)
+ if block_given?
+ assert_equal(yield(o1), yield(o2), msg)
+ else
+ assert_equal(o1, o2, msg)
+ end
+ end
+
+ class MyObject; def initialize(v) @v = v end; attr_reader :v; end
+ def test_object
+ o1 = Object.new
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_object_subclass
+ marshal_equal(MyObject.new(2)) {|o| o.v}
+ end
+
+ def test_object_extend
+ o1 = Object.new
+ o1.extend(Mod1)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ o1.extend(Mod2)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ end
+
+ def test_object_subclass_extend
+ o1 = MyObject.new(2)
+ o1.extend(Mod1)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ o1.extend(Mod2)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ end
+
+ class MyArray < Array
+ def initialize(v, *args)
+ super(args)
+ @v = v
+ end
+ end
+ def test_array
+ marshal_equal(5)
+ marshal_equal([1,2,3])
+ end
+
+ def test_array_subclass
+ marshal_equal(MyArray.new(0, 1, 2, 3))
+ end
+
+ def test_array_ivar
+ o1 = Array.new
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ class MyException < Exception; def initialize(v, *args) super(*args); @v = v; end; attr_reader :v; end
+ def test_exception
+ marshal_equal(Exception.new('foo')) {|o| o.message}
+ marshal_equal(assert_raise(NoMethodError) {no_such_method()}) {|o| o.message}
+ end
+
+ def test_exception_subclass
+ marshal_equal(MyException.new(20, "bar")) {|o| [o.message, o.v]}
+ end
+
+ def test_false
+ marshal_equal(false)
+ end
+
+ class MyHash < Hash; def initialize(v, *args) super(*args); @v = v; end end
+ def test_hash
+ marshal_equal({1=>2, 3=>4})
+ end
+
+ def test_hash_default
+ h = Hash.new(:default)
+ h[5] = 6
+ marshal_equal(h)
+ end
+
+ def test_hash_subclass
+ h = MyHash.new(7, 8)
+ h[4] = 5
+ marshal_equal(h)
+ end
+
+ def test_hash_default_proc
+ h = Hash.new {}
+ assert_raise(TypeError) { marshaltest(h) }
+ end
+
+ def test_hash_ivar
+ o1 = Hash.new
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_hash_extend
+ o1 = Hash.new
+ o1.extend(Mod1)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ o1.extend(Mod2)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ end
+
+ def test_hash_subclass_extend
+ o1 = MyHash.new(2)
+ o1.extend(Mod1)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ o1.extend(Mod2)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ end
+
+ def test_bignum
+ marshal_equal(-0x4000_0000_0000_0001)
+ marshal_equal(-0x4000_0001)
+ marshal_equal(0x4000_0000)
+ marshal_equal(0x4000_0000_0000_0000)
+ end
+
+ def test_fixnum
+ marshal_equal(-0x4000_0000)
+ marshal_equal(-0x3fff_ffff)
+ marshal_equal(-1)
+ marshal_equal(0)
+ marshal_equal(1)
+ marshal_equal(0x3fff_ffff)
+ end
+
+ def test_fixnum_ivar
+ o1 = 1
+ o1.instance_eval { @iv = 2 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ ensure
+ 1.instance_eval { remove_instance_variable("@iv") }
+ end
+
+ def test_fixnum_ivar_self
+ o1 = 1
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ ensure
+ 1.instance_eval { remove_instance_variable("@iv") }
+ end
+
+ def test_float
+ marshal_equal(-1.0)
+ marshal_equal(0.0)
+ marshal_equal(1.0)
+ end
+
+ def test_float_inf_nan
+ marshal_equal(1.0/0.0)
+ marshal_equal(-1.0/0.0)
+ marshal_equal(0.0/0.0) {|o| o.nan?}
+ marshal_equal(NegativeZero) {|o| 1.0/o}
+ end
+
+ def test_float_ivar
+ o1 = 1.23
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_float_ivar_self
+ o1 = 5.5
+ o1.instance_eval { @iv = o1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_float_extend
+ o1 = 0.0/0.0
+ o1.extend(Mod1)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ o1.extend(Mod2)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ end
+
+ class MyRange < Range; def initialize(v, *args) super(*args); @v = v; end end
+ def test_range
+ marshal_equal(1..2)
+ marshal_equal(1...3)
+ end
+
+ def test_range_subclass
+ marshal_equal(MyRange.new(4,5,8, false))
+ end
+
+ class MyRegexp < Regexp; def initialize(v, *args) super(*args); @v = v; end end
+ def test_regexp
+ marshal_equal(/a/)
+ marshal_equal(/A/i)
+ marshal_equal(/A/mx)
+ marshal_equal(/a\u3042/)
+ marshal_equal(/aあ/)
+ assert_equal(Regexp.new("あ".force_encoding("ASCII-8BIT")),
+ Marshal.load("\004\b/\b\343\201\202\000"))
+ assert_equal(/au3042/, Marshal.load("\004\b/\fa\\u3042\000"))
+ #assert_equal(/au3042/u, Marshal.load("\004\b/\fa\\u3042@")) # spec
+ end
+
+ def test_regexp_subclass
+ marshal_equal(MyRegexp.new(10, "a"))
+ end
+
+ class MyString < String; def initialize(v, *args) super(*args); @v = v; end end
+ def test_string
+ marshal_equal("abc")
+ end
+
+ def test_string_ivar
+ o1 = ""
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_string_subclass
+ marshal_equal(MyString.new(10, "a"))
+ end
+
+ def test_string_subclass_cycle
+ str = MyString.new(10, "b")
+ str.instance_eval { @v = str }
+ marshal_equal(str) { |o|
+ assert_equal(o.__id__, o.instance_eval { @v }.__id__)
+ o.instance_eval { @v }
+ }
+ end
+
+ def test_string_subclass_extend
+ o = "abc"
+ o.extend(Mod1)
+ str = MyString.new(o, "c")
+ marshal_equal(str) { |v|
+ assert(v.instance_eval { @v }.kind_of?(Mod1))
+ }
+ end
+
+ MyStruct = Struct.new("MyStruct", :a, :b)
+ if RUBY_VERSION < "1.8.0"
+ # Struct#== is not defined in ruby/1.6
+ class MyStruct
+ def ==(rhs)
+ return true if __id__ == rhs.__id__
+ return false unless rhs.is_a?(::Struct)
+ return false if self.class != rhs.class
+ members.each do |member|
+ return false if self.__send__(member) != rhs.__send__(member)
+ end
+ return true
+ end
+ end
+ end
+ class MySubStruct < MyStruct; def initialize(v, *args) super(*args); @v = v; end end
+ def test_struct
+ marshal_equal(MyStruct.new(1,2))
+ end
+
+ def test_struct_subclass
+ if RUBY_VERSION < "1.8.0"
+ # Substruct instance cannot be dumped in ruby/1.6
+ # ::Marshal.dump(MySubStruct.new(10, 1, 2)) #=> uninitialized struct
+ return false
+ end
+ marshal_equal(MySubStruct.new(10,1,2))
+ end
+
+ def test_struct_ivar
+ o1 = MyStruct.new
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_struct_subclass_extend
+ o1 = MyStruct.new
+ o1.extend(Mod1)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ o1.extend(Mod2)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ end
+
+ def test_symbol
+ marshal_equal(:a)
+ marshal_equal(:a?)
+ marshal_equal(:a!)
+ marshal_equal(:a=)
+ marshal_equal(:|)
+ marshal_equal(:^)
+ marshal_equal(:&)
+ marshal_equal(:<=>)
+ marshal_equal(:==)
+ marshal_equal(:===)
+ marshal_equal(:=~)
+ marshal_equal(:>)
+ marshal_equal(:>=)
+ marshal_equal(:<)
+ marshal_equal(:<=)
+ marshal_equal(:<<)
+ marshal_equal(:>>)
+ marshal_equal(:+)
+ marshal_equal(:-)
+ marshal_equal(:*)
+ marshal_equal(:/)
+ marshal_equal(:%)
+ marshal_equal(:**)
+ marshal_equal(:~)
+ marshal_equal(:+@)
+ marshal_equal(:-@)
+ marshal_equal(:[])
+ marshal_equal(:[]=)
+ marshal_equal(:`) #`
+ marshal_equal("a b".intern)
+ end
+
+ class MyTime < Time; def initialize(v, *args) super(*args); @v = v; end end
+ def test_time
+ # once there was a bug caused by usec overflow. try a little harder.
+ 10.times do
+ t = Time.now
+ marshal_equal(t, t.usec.to_s)
+ end
+ end
+
+ def test_time_subclass
+ marshal_equal(MyTime.new(10))
+ end
+
+ def test_time_ivar
+ o1 = Time.now
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_time_in_array
+ t = Time.now
+ assert_equal([t,t], Marshal.load(Marshal.dump([t, t])), "[ruby-dev:34159]")
+ end
+
+ def test_true
+ marshal_equal(true)
+ end
+
+ def test_nil
+ marshal_equal(nil)
+ end
+
+ def test_share
+ o = [:share]
+ o1 = [o, o]
+ o2 = marshaltest(o1)
+ assert_same(o2.first, o2.last)
+ end
+
+ class CyclicRange < Range
+ def <=>(other); true; end
+ end
+ def test_range_cyclic
+ return unless CyclicRange.respond_to?(:allocate) # test for 1.8
+ o1 = CyclicRange.allocate
+ o1.instance_eval { initialize(o1, o1) }
+ o2 = marshaltest(o1)
+ assert_same(o2, o2.begin)
+ assert_same(o2, o2.end)
+ end
+
+ def test_singleton
+ o = Object.new
+ def o.m() end
+ assert_raise(TypeError) { marshaltest(o) }
+ o = Object.new
+ c = class << o
+ @v = 1
+ class C; self; end
+ end
+ assert_raise(TypeError) { marshaltest(o) }
+ assert_raise(TypeError) { marshaltest(c) }
+ assert_raise(TypeError) { marshaltest(ARGF) }
+ assert_raise(TypeError) { marshaltest(ENV) }
+ end
+
+ def test_extend
+ o = Object.new
+ o.extend Mod1
+ marshal_equal(o) { |obj| obj.kind_of? Mod1 }
+ o = Object.new
+ o.extend Mod1
+ o.extend Mod2
+ marshal_equal(o) {|obj| class << obj; ancestors end}
+ o = Object.new
+ o.extend Module.new
+ assert_raise(TypeError) { marshaltest(o) }
+ end
+
+ def test_extend_string
+ o = ""
+ o.extend Mod1
+ marshal_equal(o) { |obj| obj.kind_of? Mod1 }
+ o = ""
+ o.extend Mod1
+ o.extend Mod2
+ marshal_equal(o) {|obj| class << obj; ancestors end}
+ o = ""
+ o.extend Module.new
+ assert_raise(TypeError) { marshaltest(o) }
+ end
+
+ def test_anonymous
+ c = Class.new
+ assert_raise(TypeError) { marshaltest(c) }
+ o = c.new
+ assert_raise(TypeError) { marshaltest(o) }
+ m = Module.new
+ assert_raise(TypeError) { marshaltest(m) }
+ end
+
+ def test_string_empty
+ marshal_equal("")
+ end
+
+ def test_string_crlf
+ marshal_equal("\r\n")
+ end
+
+ def test_string_escape
+ marshal_equal("\0<;;>\1;;")
+ end
+
+ MyStruct2 = Struct.new(:a, :b)
+ if RUBY_VERSION < "1.8.0"
+ # Struct#== is not defined in ruby/1.6
+ class MyStruct2
+ def ==(rhs)
+ return true if __id__ == rhs.__id__
+ return false unless rhs.is_a?(::Struct)
+ return false if self.class != rhs.class
+ members.each do |member|
+ return false if self.__send__(member) != rhs.__send__(member)
+ end
+ return true
+ end
+ end
+ end
+ def test_struct_toplevel
+ o = MyStruct2.new(1,2)
+ marshal_equal(o)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/sentence.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/sentence.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/sentence.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,668 @@
+# == sentence library
+#
+# = Features
+#
+# * syntax based sentences generation
+# * sentence operations such as substitution.
+#
+# = Example
+#
+# Some arithmetic expressions using "+", "-", "*" and "/" are generated as follows.
+#
+# require 'sentence'
+# Sentence.each({
+# :exp => [["num"],
+# [:exp, "+", :exp],
+# [:exp, "-", :exp],
+# [:exp, "*", :exp],
+# [:exp, "/", :exp]]
+# }, :exp, 2) {|sent| p sent }
+# #=>
+# #<Sentence: "num">
+# #<Sentence: ("num") "+" ("num")>
+# #<Sentence: ("num") "+" (("num") "+" ("num"))>
+# #<Sentence: ("num") "+" (("num") "-" ("num"))>
+# #<Sentence: ("num") "+" (("num") "*" ("num"))>
+# #<Sentence: ("num") "+" (("num") "/" ("num"))>
+# #<Sentence: (("num") "+" ("num")) "+" ("num")>
+# ...
+#
+# Sentence.each takes 3 arguments.
+# The first argument is the syntax for the expressions.
+# The second argument, :exp, is a generating nonterminal.
+# The third argument, 2, limits derivation to restrict results finitely.
+#
+# Some arithmetic expressions including parenthesis can be generated as follows.
+#
+# syntax = {
+# :factor => [["n"],
+# ["(", :exp, ")"]],
+# :term => [[:factor],
+# [:term, "*", :factor],
+# [:term, "/", :factor]],
+# :exp => [[:term],
+# [:exp, "+", :term],
+# [:exp, "-", :term]]
+# }
+# Sentence.each(syntax, :exp, 2) {|sent| p sent }
+# #=>
+# #<Sentence: (("n"))>
+# #<Sentence: (("(" ((("n"))) ")"))>
+# #<Sentence: (("(" ((("(" ((("n"))) ")"))) ")"))>
+# #<Sentence: (("(" (((("n")) "*" ("n"))) ")"))>
+# #<Sentence: (("(" (((("n")) "/" ("n"))) ")"))>
+# #<Sentence: (("(" (((("n"))) "+" (("n"))) ")"))>
+# #<Sentence: (("(" (((("n"))) "-" (("n"))) ")"))>
+# #<Sentence: ((("n")) "*" ("n"))>
+# #<Sentence: ((("n")) "*" ("(" ((("n"))) ")"))>
+# ...
+#
+# Sentence#to_s can be used to concatenate strings
+# in a sentence:
+#
+# Sentence.each(syntax, :exp, 2) {|sent| p sent.to_s }
+# #=>
+# "n"
+# "(n)"
+# "((n))"
+# "(n*n)"
+# "(n/n)"
+# "(n+n)"
+# "(n-n)"
+# "n*n"
+# "n*(n)"
+# ...
+#
+
+# Sentence() instantiates a sentence object.
+#
+# Sentence("foo", "bar")
+# #=> #<Sentence: "foo" "bar">
+#
+# Sentence("foo", ["bar", "baz"])
+# #=> #<Sentence: "foo" ("bar" "baz")>
+#
+def Sentence(*ary)
+ Sentence.new(ary)
+end
+
+# Sentence class represents a tree with string leaves.
+#
+class Sentence
+ # _ary_ represents a tree.
+ # It should be a possibly nested array which contains strings.
+ #
+ # Note that _ary_ is not copied.
+ # Don't modify _ary_ after the sentence object is instantiated.
+ #
+ # Sentence.new(["a", "pen"])
+ # #<Sentence: "a" "pen">
+ #
+ # Sentence.new(["I", "have", ["a", "pen"]])
+ # #<Sentence: "I" "have" ("a" "pen")>
+ #
+ def initialize(ary)
+ @sent = ary
+ end
+
+ # returns a string which is concatenation of all strings.
+ # No separator is used.
+ #
+ # Sentence("2", "+", "3").to_s
+ # "2+3"
+ #
+ # Sentence("2", "+", ["3", "*", "5"]).to_s
+ # "2+3*5"
+ #
+ def to_s
+ @sent.join('')
+ end
+
+ # returns a string which is concatenation of all strings separated by _sep_.
+ # If _sep_ is not given, single space is used.
+ #
+ # Sentence("I", "have", ["a", "pen"]).join
+ # "I have a pen"
+ #
+ # Sentence("I", "have", ["a", "pen"]).join("/")
+ # "I/have/a/pen"
+ #
+ # Sentence("a", [], "b").join("/")
+ # "a/b"
+ #
+ def join(sep=' ')
+ @sent.flatten.join(sep)
+ end
+
+ # returns a tree as a nested array.
+ #
+ # Note that the result is not copied.
+ # Don't modify the result.
+ #
+ # Sentence(["foo", "bar"], "baz").to_a
+ # #=> [["foo", "bar"], "baz"]
+ #
+ def to_a
+ @sent
+ end
+
+ # returns <i>i</i>th element as a sentence or string.
+ #
+ # s = Sentence(["foo", "bar"], "baz")
+ # s #=> #<Sentence: ("foo" "bar") "baz">
+ # s[0] #=> #<Sentence: "foo" "bar">
+ # s[1] #=> "baz"
+ #
+ def [](i)
+ e = @sent[i]
+ e.respond_to?(:to_ary) ? Sentence.new(e) : e
+ end
+
+ # returns the number of top level elements.
+ #
+ # Sentence.new(%w[foo bar]).length
+ # #=> 2
+ #
+ # Sentence(%w[2 * 7], "+", %w[3 * 5]).length
+ # #=> 3
+ #
+ def length
+ @sent.length
+ end
+
+ # iterates over children.
+ #
+ # Sentence(%w[2 * 7], "+", %w[3 * 5]).each {|v| p v }
+ # #=>
+ # #<Sentence: "2" "*" "7">
+ # "+"
+ # #<Sentence: "3" "*" "5">
+ #
+ def each # :yield: element
+ @sent.each_index {|i|
+ yield self[i]
+ }
+ end
+ include Enumerable
+
+ def inspect
+ "#<#{self.class}: #{inner_inspect(@sent, '')}>"
+ end
+
+ # :stopdoc:
+ def inner_inspect(ary, r)
+ first = true
+ ary.each {|obj|
+ r << ' ' if !first
+ first = false
+ if obj.respond_to? :to_ary
+ r << '('
+ inner_inspect(obj, r)
+ r << ')'
+ else
+ r << obj.inspect
+ end
+ }
+ r
+ end
+ # :startdoc:
+
+ # returns new sentence object which
+ # _target_ is substituted by the block.
+ #
+ # Sentence#subst invokes <tt>_target_ === _string_</tt> for each
+ # string in the sentence.
+ # The strings which === returns true are substituted by the block.
+ # The block is invoked with the substituting string.
+ #
+ # Sentence.new(%w[2 + 3]).subst("+") { "*" }
+ # #<Sentence: "2" "*" "3">
+ #
+ # Sentence.new(%w[2 + 3]).subst(/\A\d+\z/) {|s| ((s.to_i)*2).to_s }
+ # #=> #<Sentence: "4" "+" "6">
+ #
+ def subst(target, &b) # :yield: string
+ Sentence.new(subst_rec(@sent, target, &b))
+ end
+
+ # :stopdoc:
+ def subst_rec(obj, target, &b)
+ if obj.respond_to? :to_ary
+ a = []
+ obj.each {|e| a << subst_rec(e, target, &b) }
+ a
+ elsif target === obj
+ yield obj
+ else
+ obj
+ end
+ end
+ # :startdoc:
+
+ # find a subsentence and return it.
+ # The block is invoked for each subsentence in preorder manner.
+ # The first subsentence which the block returns true is returned.
+ #
+ # Sentence(%w[2 * 7], "+", %w[3 * 5]).find_subtree {|s| s[1] == "*" }
+ # #=> #<Sentence: "2" "*" "7">
+ #
+ def find_subtree(&b) # :yield: sentence
+ find_subtree_rec(@sent, &b)
+ end
+
+ # :stopdoc:
+ def find_subtree_rec(obj, &b)
+ if obj.respond_to? :to_ary
+ s = Sentence.new(obj)
+ if b.call s
+ return s
+ else
+ obj.each {|e|
+ r = find_subtree_rec(e, &b)
+ return r if r
+ }
+ end
+ end
+ nil
+ end
+ # :startdoc:
+
+ # returns a new sentence object which expands according to the condition
+ # given by the block.
+ #
+ # The block is invoked for each subsentence.
+ # The subsentences which the block returns true are
+ # expanded into parent.
+ #
+ # s = Sentence(%w[2 * 7], "+", %w[3 * 5])
+ # #=> #<Sentence: ("2" "*" "7") "+" ("3" "*" "5")>
+ #
+ # s.expand { true }
+ # #=> #<Sentence: "2" "*" "7" "+" "3" "*" "5">
+ #
+ # s.expand {|s| s[0] == "3" }
+ # #=> #<Sentence: (("2" "*" "7") "+" "3" "*" "5")>
+ #
+ def expand(&b) # :yield: sentence
+ Sentence.new(expand_rec(@sent, &b))
+ end
+
+ # :stopdoc:
+ def expand_rec(obj, r=[], &b)
+ if obj.respond_to? :to_ary
+ obj.each {|o|
+ s = Sentence.new(o)
+ if b.call s
+ expand_rec(o, r, &b)
+ else
+ a = []
+ expand_rec(o, a, &b)
+ r << a
+ end
+ }
+ else
+ r << obj
+ end
+ r
+ end
+ # :startdoc:
+
+ # Sentence.each generates sentences
+ # by deriving the start symbol _sym_ using _syntax_.
+ # The derivation is restricted by an positive integer _limit_ to
+ # avoid infinite generation.
+ #
+ # Sentence.each yields the block with a generated sentence.
+ #
+ # Sentence.each({
+ # :exp => [["n"],
+ # [:exp, "+", :exp],
+ # [:exp, "*", :exp]]
+ # }, :exp, 1) {|sent| p sent }
+ # #=>
+ # #<Sentence: "n">
+ # #<Sentence: ("n") "+" ("n")>
+ # #<Sentence: ("n") "*" ("n")>
+ #
+ # Sentence.each({
+ # :exp => [["n"],
+ # [:exp, "+", :exp],
+ # [:exp, "*", :exp]]
+ # }, :exp, 2) {|sent| p sent }
+ # #=>
+ # #<Sentence: "n">
+ # #<Sentence: ("n") "+" ("n")>
+ # #<Sentence: ("n") "+" (("n") "+" ("n"))>
+ # #<Sentence: ("n") "+" (("n") "*" ("n"))>
+ # #<Sentence: (("n") "+" ("n")) "+" ("n")>
+ # #<Sentence: (("n") "*" ("n")) "+" ("n")>
+ # #<Sentence: ("n") "*" ("n")>
+ # #<Sentence: ("n") "*" (("n") "+" ("n"))>
+ # #<Sentence: ("n") "*" (("n") "*" ("n"))>
+ # #<Sentence: (("n") "+" ("n")) "*" ("n")>
+ # #<Sentence: (("n") "*" ("n")) "*" ("n")>
+ #
+ def Sentence.each(syntax, sym, limit)
+ Gen.new(syntax).each_tree(sym, limit) {|tree|
+ yield Sentence.new(tree)
+ }
+ end
+
+ # Sentence.expand_syntax returns an expanded syntax:
+ # * No rule derives to empty sequence
+ # * Underivable rule simplified
+ # * No channel rule
+ # * Symbols which has zero or one choices are not appered in rhs.
+ #
+ # Note that the rules which can derive empty and non-empty
+ # sequences are modified to derive only non-empty sequences.
+ #
+ # Sentence.expand_syntax({
+ # :underivable1 => [],
+ # :underivable2 => [[:underivable1]],
+ # :underivable3 => [[:underivable3]],
+ # :empty_only1 => [[]],
+ # :empty_only2 => [[:just_empty1, :just_empty1]],
+ # :empty_or_not => [[], ["foo"]],
+ # :empty_or_not_2 => [[:empty_or_not, :empty_or_not]],
+ # :empty_or_not_3 => [[:empty_or_not, :empty_or_not, :empty_or_not]],
+ # :empty_or_not_4 => [[:empty_or_not_2, :empty_or_not_2]],
+ # :channel1 => [[:channeled_data]],
+ # :channeled_data => [["a", "b"], ["c", "d"]],
+ # :single_choice => [["single", "choice"]],
+ # :single_choice_2 => [[:single_choice, :single_choice]],
+ # })
+ # #=>
+ # {
+ # :underivable1=>[], # underivable rules are simplified to [].
+ # :underivable2=>[],
+ # :underivable3=>[],
+ # :empty_only1=>[], # derivation to empty sequence are removed.
+ # :empty_only2=>[],
+ # :empty_or_not=>[["foo"]], # empty sequences are removed too.
+ # :empty_or_not_2=>[["foo"], ["foo", "foo"]],
+ # :empty_or_not_3=>[["foo"], ["foo", "foo"], ["foo", "foo", "foo"]],
+ # :empty_or_not_4=> [["foo"], ["foo", "foo"], [:empty_or_not_2, :empty_or_not_2]],
+ # :channel1=>[["a", "b"], ["c", "d"]], # channel rules are removed.
+ # :channeled_data=>[["a", "b"], ["c", "d"]],
+ # :single_choice=>[["single", "choice"]], # single choice rules are expanded.
+ # :single_choice_2=>[["single", "choice", "single", "choice"]],
+ # }
+ #
+ # Sentence.expand_syntax({
+ # :factor => [["n"],
+ # ["(", :exp, ")"]],
+ # :term => [[:factor],
+ # [:term, "*", :factor],
+ # [:term, "/", :factor]],
+ # :exp => [[:term],
+ # [:exp, "+", :term],
+ # [:exp, "-", :term]]
+ # })
+ # #=>
+ # {:exp=> [["n"],
+ # ["(", :exp, ")"],
+ # [:exp, "+", :term],
+ # [:exp, "-", :term],
+ # [:term, "*", :factor],
+ # [:term, "/", :factor]],
+ # :factor=> [["n"],
+ # ["(", :exp, ")"]],
+ # :term=> [["n"],
+ # ["(", :exp, ")"],
+ # [:term, "*", :factor],
+ # [:term, "/", :factor]]
+ # }
+ #
+ def Sentence.expand_syntax(syntax)
+ Sentence::Gen.expand_syntax(syntax)
+ end
+
+ # :stopdoc:
+ class Gen
+ def Gen.each_tree(syntax, sym, limit, &b)
+ Gen.new(syntax).each_tree(sym, limit, &b)
+ end
+
+ def Gen.each_string(syntax, sym, limit, &b)
+ Gen.new(syntax).each_string(sym, limit, &b)
+ end
+
+ def initialize(syntax)
+ @syntax = syntax
+ end
+
+ def self.expand_syntax(syntax)
+ syntax = simplify_underivable_rules(syntax)
+ syntax = simplify_emptyonly_rules(syntax)
+ syntax = make_rules_no_empseq(syntax)
+ syntax = expand_channel_rules(syntax)
+
+ syntax = expand_noalt_rules(syntax)
+ syntax = reorder_rules(syntax)
+ end
+
+ def self.simplify_underivable_rules(syntax)
+ deribable_syms = {}
+ changed = true
+ while changed
+ changed = false
+ syntax.each {|sym, rules|
+ next if deribable_syms[sym]
+ rules.each {|rhs|
+ if rhs.all? {|e| String === e || deribable_syms[e] }
+ deribable_syms[sym] = true
+ changed = true
+ break
+ end
+ }
+ }
+ end
+ result = {}
+ syntax.each {|sym, rules|
+ if deribable_syms[sym]
+ rules2 = []
+ rules.each {|rhs|
+ rules2 << rhs if rhs.all? {|e| String === e || deribable_syms[e] }
+ }
+ result[sym] = rules2.uniq
+ else
+ result[sym] = []
+ end
+ }
+ result
+ end
+
+ def self.simplify_emptyonly_rules(syntax)
+ justempty_syms = {}
+ changed = true
+ while changed
+ changed = false
+ syntax.each {|sym, rules|
+ next if justempty_syms[sym]
+ if !rules.empty? && rules.all? {|rhs| rhs.all? {|e| justempty_syms[e] } }
+ justempty_syms[sym] = true
+ changed = true
+ end
+ }
+ end
+ result = {}
+ syntax.each {|sym, rules|
+ result[sym] = rules.map {|rhs| rhs.reject {|e| justempty_syms[e] } }.uniq
+ }
+ result
+ end
+
+ def self.expand_emptyable_syms(rhs, emptyable_syms)
+ if rhs.empty?
+ yield []
+ else
+ first = rhs[0]
+ rest = rhs[1..-1]
+ if emptyable_syms[first]
+ expand_emptyable_syms(rest, emptyable_syms) {|rhs2|
+ yield [first] + rhs2
+ yield rhs2
+ }
+ else
+ expand_emptyable_syms(rest, emptyable_syms) {|rhs2|
+ yield [first] + rhs2
+ }
+ end
+ end
+ end
+
+ def self.make_rules_no_empseq(syntax)
+ emptyable_syms = {}
+ changed = true
+ while changed
+ changed = false
+ syntax.each {|sym, rules|
+ next if emptyable_syms[sym]
+ rules.each {|rhs|
+ if rhs.all? {|e| emptyable_syms[e] }
+ emptyable_syms[sym] = true
+ changed = true
+ break
+ end
+ }
+ }
+ end
+ result = {}
+ syntax.each {|sym, rules|
+ rules2 = []
+ rules.each {|rhs|
+ expand_emptyable_syms(rhs, emptyable_syms) {|rhs2|
+ next if rhs2.empty?
+ rules2 << rhs2
+ }
+ }
+ result[sym] = rules2.uniq
+ }
+ result
+ end
+
+ def self.expand_channel_rules(syntax)
+ channel_rules = {}
+ syntax.each {|sym, rules|
+ channel_rules[sym] = {sym=>true}
+ rules.each {|rhs|
+ if rhs.length == 1 && Symbol === rhs[0]
+ channel_rules[sym][rhs[0]] = true
+ end
+ }
+ }
+ changed = true
+ while changed
+ changed = false
+ channel_rules.each {|sym, set|
+ n1 = set.size
+ set.keys.each {|s|
+ set.update(channel_rules[s])
+ }
+ n2 = set.size
+ changed = true if n1 < n2
+ }
+ end
+ result = {}
+ syntax.each {|sym, rules|
+ rules2 = []
+ channel_rules[sym].each_key {|s|
+ syntax[s].each {|rhs|
+ unless rhs.length == 1 && Symbol === rhs[0]
+ rules2 << rhs
+ end
+ }
+ }
+ result[sym] = rules2.uniq
+ }
+ result
+ end
+
+ def self.expand_noalt_rules(syntax)
+ noalt_syms = {}
+ syntax.each {|sym, rules|
+ if rules.length == 1
+ noalt_syms[sym] = true
+ end
+ }
+ result = {}
+ syntax.each {|sym, rules|
+ rules2 = []
+ rules.each {|rhs|
+ rhs2 = []
+ rhs.each {|e|
+ if noalt_syms[e]
+ rhs2.concat syntax[e][0]
+ else
+ rhs2 << e
+ end
+ }
+ rules2 << rhs2
+ }
+ result[sym] = rules2.uniq
+ }
+ result
+ end
+
+ def self.reorder_rules(syntax)
+ result = {}
+ syntax.each {|sym, rules|
+ result[sym] = rules.sort_by {|rhs|
+ [rhs.find_all {|e| Symbol === e }.length, rhs.length]
+ }
+ }
+ result
+ end
+
+ def each_tree(sym, limit)
+ generate_from_sym(sym, limit) {|_, tree|
+ yield tree
+ }
+ nil
+ end
+
+ def each_string(sym, limit)
+ generate_from_sym(sym, limit) {|_, tree|
+ yield [tree].join('')
+ }
+ nil
+ end
+
+ def generate_from_sym(sym, limit, &b)
+ return if limit < 0
+ if String === sym
+ yield limit, sym
+ else
+ rules = @syntax[sym]
+ raise "undefined rule: #{sym}" if !rules
+ rules.each {|rhs|
+ if rhs.length == 1 || rules.length == 1
+ limit1 = limit
+ else
+ limit1 = limit-1
+ end
+ generate_from_rhs(rhs, limit1, &b)
+ }
+ end
+ nil
+ end
+
+ def generate_from_rhs(rhs, limit)
+ return if limit < 0
+ if rhs.empty?
+ yield limit, []
+ else
+ generate_from_sym(rhs[0], limit) {|limit1, child|
+ generate_from_rhs(rhs[1..-1], limit1) {|limit2, arr|
+ yield limit2, [child, *arr]
+ }
+ }
+ end
+ nil
+ end
+ end
+ # :startdoc:
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/ruby/test_alias.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_alias.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_alias.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,109 @@
+require 'test/unit'
+
+class TestAlias < Test::Unit::TestCase
+ class Alias0
+ def foo
+ "foo"
+ end
+ end
+
+ class Alias1 < Alias0
+ alias bar foo
+
+ def foo
+ "foo+#{super}"
+ end
+ end
+
+ class Alias2 < Alias1
+ alias baz foo
+ undef foo
+ end
+
+ class Alias3 < Alias2
+ def foo
+ super
+ end
+
+ def bar
+ super
+ end
+
+ def quux
+ super
+ end
+ end
+
+ def test_alias
+ x = Alias2.new
+ assert_equal "foo", x.bar
+ assert_equal "foo+foo", x.baz
+ assert_equal "foo+foo", x.baz # test_check for cache
+
+ x = Alias3.new
+ assert_raise(NoMethodError) { x.foo }
+ assert_equal "foo", x.bar
+ assert_raise(NoMethodError) { x.quux }
+ end
+
+ class C
+ def m
+ $SAFE
+ end
+ end
+
+ def test_JVN_83768862
+ skip("[BUG : #842] SecurityError Level 4")
+
+ d = lambda {
+ $SAFE = 4
+ dclass = Class.new(C)
+ dclass.send(:alias_method, :mm, :m)
+ dclass.new
+ }.call
+ assert_raise(SecurityError) { d.mm }
+ end
+
+ def test_nonexistmethod
+ assert_raise(NameError){
+ Class.new{
+ alias_method :foobarxyzzy, :barbaz
+ }
+ }
+ end
+
+ def test_send_alias
+ x = "abc"
+ class << x
+ alias_method :try, :__send__
+ end
+ assert_equal("ABC", x.try(:upcase), '[ruby-dev:38824]')
+ end
+
+ def test_special_const_alias
+ assert_raise(TypeError) do
+ 1.instance_eval do
+ alias to_string to_s
+ end
+ end
+ end
+
+ def test_alias_with_zsuper_method
+ c = Class.new
+ c.class_eval do
+ def foo
+ :ok
+ end
+ def bar
+ :ng
+ end
+ private :foo
+ end
+ d = Class.new(c)
+ d.class_eval do
+ public :foo
+ alias bar foo
+ end
+ assert_equal(:ok, d.new.bar)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_argf.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_argf.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_argf.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,699 @@
+require 'test/unit'
+require 'timeout'
+require 'tmpdir'
+require 'tempfile'
+require_relative 'envutil'
+
+class TestArgf < Test::Unit::TestCase
+ def setup
+ @t1 = Tempfile.new("argf-foo")
+ @t1.binmode
+ @t1.puts "1"
+ @t1.puts "2"
+ @t1.close
+ @t2 = Tempfile.new("argf-bar")
+ @t2.binmode
+ @t2.puts "3"
+ @t2.puts "4"
+ @t2.close
+ @t3 = Tempfile.new("argf-baz")
+ @t3.binmode
+ @t3.puts "5"
+ @t3.puts "6"
+ @t3.close
+ @tmps = [@t1, @t2, @t3]
+ end
+
+ def teardown
+ @tmps.each {|t|
+ bak = t.path + ".bak"
+ File.unlink bak if File.file? bak
+ t.close(true)
+ }
+ end
+
+ def make_tempfile
+ t = Tempfile.new("argf-qux")
+ t.puts "foo"
+ t.puts "bar"
+ t.puts "baz"
+ t.close
+ @tmps << t
+ t
+ end
+
+ def ruby(*args)
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ args = ['-e', '$>.write($<.read)'] if args.empty?
+ ruby = EnvUtil.rubybin
+ f = IO.popen([ruby] + args, 'r+')
+ yield(f)
+ ensure
+ f.close unless !f || f.closed?
+ end
+
+ def no_safe_rename
+ /cygwin|mswin|mingw|bccwin/ =~ RUBY_PLATFORM
+ end
+
+ def assert_src_expected(line, src, args = nil)
+ args ||= [@t1.path, @t2.path, @t3.path]
+ expected = src.split(/^/)
+ ruby('-e', src, *args) do |f|
+ expected.each_with_index do |e, i|
+ /#=> *(.*)/ =~ e or next
+ a = f.gets
+ assert_not_nil(a, "[ruby-dev:34445]: remained")
+ assert_equal($1, a.chomp, "[ruby-dev:34445]: line #{line+i}")
+ end
+ end
+ end
+
+ def test_argf
+ assert_src_expected(__LINE__+1, <<-'SRC')
+ a = ARGF
+ b = a.dup
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["1", 1, "1", 1]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["2", 2, "2", 2]
+ a.rewind
+ b.rewind
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["1", 1, "1", 3]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["2", 2, "2", 4]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["3", 3, "3", 5]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["4", 4, "4", 6]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["5", 5, "5", 7]
+ a.rewind
+ b.rewind
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["5", 5, "5", 8]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["6", 6, "6", 9]
+ SRC
+ end
+
+ def test_lineno
+ assert_src_expected(__LINE__+1, <<-'SRC')
+ a = ARGF
+ a.gets; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 3
+ a.rewind; p $. #=> 3
+ a.gets; p $. #=> 3
+ a.gets; p $. #=> 4
+ a.rewind; p $. #=> 4
+ a.gets; p $. #=> 3
+ a.lineno = 1000; p $. #=> 1000
+ a.gets; p $. #=> 1001
+ a.gets; p $. #=> 1002
+ $. = 2000
+ a.gets; p $. #=> 2001
+ a.gets; p $. #=> 2001
+ SRC
+ end
+
+ def test_lineno2
+ assert_src_expected(__LINE__+1, <<-'SRC')
+ a = ARGF.dup
+ a.gets; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 1
+ a.rewind; p $. #=> 1
+ a.gets; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 1
+ a.lineno = 1000; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 2
+ $. = 2000
+ a.gets; p $. #=> 2000
+ a.gets; p $. #=> 2000
+ SRC
+ end
+
+ def test_lineno3
+ assert_in_out_err(["-", @t1.path, @t2.path], <<-INPUT, %w"1 1 1 2 2 2 3 3 1 4 4 2", [], "[ruby-core:25205]")
+ ARGF.each do |line|
+ puts [$., ARGF.lineno, ARGF.file.lineno]
+ end
+ INPUT
+ end
+
+ def test_inplace
+ assert_in_out_err(["-", @t1.path, @t2.path, @t3.path], <<-INPUT, [], [])
+ ARGF.inplace_mode = '.bak'
+ while line = ARGF.gets
+ puts line.chomp + '.new'
+ end
+ INPUT
+ assert_equal("1.new\n2.new\n", File.read(@t1.path))
+ assert_equal("3.new\n4.new\n", File.read(@t2.path))
+ assert_equal("5.new\n6.new\n", File.read(@t3.path))
+ assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+ assert_equal("3\n4\n", File.read(@t2.path + ".bak"))
+ assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
+ end
+
+ def test_inplace2
+ assert_in_out_err(["-", @t1.path, @t2.path, @t3.path], <<-INPUT, [], [])
+ ARGF.inplace_mode = '.bak'
+ puts ARGF.gets.chomp + '.new'
+ puts ARGF.gets.chomp + '.new'
+ p ARGF.inplace_mode
+ ARGF.inplace_mode = nil
+ puts ARGF.gets.chomp + '.new'
+ puts ARGF.gets.chomp + '.new'
+ p ARGF.inplace_mode
+ ARGF.inplace_mode = '.bak'
+ puts ARGF.gets.chomp + '.new'
+ p ARGF.inplace_mode
+ ARGF.inplace_mode = nil
+ puts ARGF.gets.chomp + '.new'
+ INPUT
+ assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
+ assert_equal("3\n4\n", File.read(@t2.path))
+ assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
+ assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+ assert_equal(false, File.file?(@t2.path + ".bak"))
+ assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
+ end
+
+ def test_inplace3
+ assert_in_out_err(["-i.bak", "-", @t1.path, @t2.path, @t3.path], <<-INPUT, [], [])
+ puts ARGF.gets.chomp + '.new'
+ puts ARGF.gets.chomp + '.new'
+ p $-i
+ $-i = nil
+ puts ARGF.gets.chomp + '.new'
+ puts ARGF.gets.chomp + '.new'
+ p $-i
+ $-i = '.bak'
+ puts ARGF.gets.chomp + '.new'
+ p $-i
+ $-i = nil
+ puts ARGF.gets.chomp + '.new'
+ INPUT
+ assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
+ assert_equal("3\n4\n", File.read(@t2.path))
+ assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
+ assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+ assert_equal(false, File.file?(@t2.path + ".bak"))
+ assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
+ end
+
+ def test_inplace_rename_impossible
+ t = make_tempfile
+
+ assert_in_out_err(["-", t.path], <<-INPUT) do |r, e|
+ ARGF.inplace_mode = '/\\\\'
+ while line = ARGF.gets
+ puts line.chomp + '.new'
+ end
+ INPUT
+ if no_safe_rename
+ assert_equal([], e)
+ assert_equal([], r)
+ assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
+ else
+ assert_match(/Can't rename .* to .*: .*. skipping file/, e.first) #'
+ assert_equal([], r)
+ assert_equal("foo\nbar\nbaz\n", File.read(t.path))
+ end
+ end
+ end
+
+ def test_inplace_no_backup
+ t = make_tempfile
+
+ assert_in_out_err(["-", t.path], <<-INPUT) do |r, e|
+ ARGF.inplace_mode = ''
+ while line = ARGF.gets
+ puts line.chomp + '.new'
+ end
+ INPUT
+ if no_safe_rename
+ assert_match(/Can't do inplace edit without backup/, e.join) #'
+ else
+ assert_equal([], e)
+ assert_equal([], r)
+ assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
+ end
+ end
+ end
+
+ def test_inplace_dup
+ t = make_tempfile
+
+ assert_in_out_err(["-", t.path], <<-INPUT, [], [])
+ ARGF.inplace_mode = '.bak'
+ f = ARGF.dup
+ while line = f.gets
+ puts line.chomp + '.new'
+ end
+ INPUT
+ assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
+ end
+
+ def test_inplace_stdin
+ t = make_tempfile
+
+ assert_in_out_err(["-", "-"], <<-INPUT, [], /Can't do inplace edit for stdio; skipping/)
+ ARGF.inplace_mode = '.bak'
+ f = ARGF.dup
+ while line = f.gets
+ puts line.chomp + '.new'
+ end
+ INPUT
+ end
+
+ def test_inplace_stdin2
+ t = make_tempfile
+
+ assert_in_out_err(["-"], <<-INPUT, [], /Can't do inplace edit for stdio/)
+ ARGF.inplace_mode = '.bak'
+ while line = ARGF.gets
+ puts line.chomp + '.new'
+ end
+ INPUT
+ end
+
+ def test_encoding
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ p ARGF.external_encoding.is_a?(Encoding)
+ p ARGF.internal_encoding.is_a?(Encoding)
+ ARGF.gets
+ p ARGF.external_encoding.is_a?(Encoding)
+ p ARGF.internal_encoding
+ SRC
+ assert_equal("true\ntrue\ntrue\nnil\n", f.read)
+ end
+ end
+
+ def test_tell
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ ARGF.binmode
+ loop do
+ p ARGF.tell
+ p ARGF.gets
+ end
+ rescue ArgumentError
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ [0, 2, 4, 2, 4, 2, 4].map {|i| i.to_s }.
+ zip((1..6).map {|i| '"' + i.to_s + '\n"' } + ["nil"]).flatten.
+ each do |x|
+ assert_equal(x, a.shift)
+ end
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_seek
+ assert_src_expected(__LINE__+1, <<-'SRC')
+ ARGF.seek(4)
+ p ARGF.gets #=> "3\n"
+ ARGF.seek(0, IO::SEEK_END)
+ p ARGF.gets #=> "5\n"
+ ARGF.seek(4)
+ p ARGF.gets #=> nil
+ begin
+ ARGF.seek(0)
+ rescue
+ puts "end" #=> end
+ end
+ SRC
+ end
+
+ def test_set_pos
+ assert_src_expected(__LINE__+1, <<-'SRC')
+ ARGF.pos = 4
+ p ARGF.gets #=> "3\n"
+ ARGF.pos = 4
+ p ARGF.gets #=> "5\n"
+ ARGF.pos = 4
+ p ARGF.gets #=> nil
+ begin
+ ARGF.pos = 4
+ rescue
+ puts "end" #=> end
+ end
+ SRC
+ end
+
+ def test_rewind
+ assert_src_expected(__LINE__+1, <<-'SRC')
+ ARGF.pos = 4
+ ARGF.rewind
+ p ARGF.gets #=> "1\n"
+ ARGF.pos = 4
+ p ARGF.gets #=> "3\n"
+ ARGF.pos = 4
+ p ARGF.gets #=> "5\n"
+ ARGF.pos = 4
+ p ARGF.gets #=> nil
+ begin
+ ARGF.rewind
+ rescue
+ puts "end" #=> end
+ end
+ SRC
+ end
+
+ def test_fileno
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ p ARGF.fileno
+ ARGF.gets
+ ARGF.gets
+ p ARGF.fileno
+ ARGF.gets
+ ARGF.gets
+ p ARGF.fileno
+ ARGF.gets
+ ARGF.gets
+ p ARGF.fileno
+ ARGF.gets
+ begin
+ ARGF.fileno
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ fd1, fd2, fd3, fd4, tag = a
+ assert_match(/^\d+$/, fd1)
+ assert_match(/^\d+$/, fd2)
+ assert_match(/^\d+$/, fd3)
+ assert_match(/^\d+$/, fd4)
+ assert_equal('end', tag)
+ end
+ end
+
+ def test_to_io
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ 8.times do
+ p ARGF.to_io
+ ARGF.gets
+ end
+ SRC
+ a = f.read.split("\n")
+ f11, f12, f13, f21, f22, f31, f32, f4 = a
+ assert_equal(f11, f12)
+ assert_equal(f11, f13)
+ assert_equal(f21, f22)
+ assert_equal(f31, f32)
+ assert_match(/\(closed\)/, f4)
+ f4.sub!(/ \(closed\)/, "")
+ assert_equal(f31, f4)
+ end
+ end
+
+ def test_eof
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ 8.times do
+ p ARGF.eof?
+ ARGF.gets
+ end
+ rescue IOError
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ (%w(false) + (%w(false true) * 3) + %w(end)).each do |x|
+ assert_equal(x, a.shift)
+ end
+ end
+
+ t1 = Tempfile.new("argf-foo")
+ t1.binmode
+ t1.puts "foo"
+ t1.close
+ t2 = Tempfile.new("argf-bar")
+ t2.binmode
+ t2.puts "bar"
+ t2.close
+ ruby('-e', 'STDERR.reopen(STDOUT); ARGF.gets; ARGF.skip; p ARGF.eof?', t1.path, t2.path) do |f|
+ assert_equal(%w(false), f.read.split(/\n/))
+ end
+ end
+
+ def test_read
+ ruby('-e', "p ARGF.read(8)", @t1.path, @t2.path, @t3.path) do |f|
+ assert_equal("\"1\\n2\\n3\\n4\\n\"\n", f.read)
+ end
+ end
+
+ def test_read2
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ ARGF.read(8, s)
+ p s
+ SRC
+ assert_equal("\"1\\n2\\n3\\n4\\n\"\n", f.read)
+ end
+ end
+
+ def test_read3
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ nil while ARGF.gets
+ p ARGF.read
+ p ARGF.read(0, "")
+ SRC
+ assert_equal("nil\n\"\"\n", f.read)
+ end
+ end
+
+ def test_readpartial
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ begin
+ loop do
+ s << ARGF.readpartial(1)
+ t = ""; ARGF.readpartial(1, t); s << t
+ end
+ rescue EOFError
+ puts s
+ end
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_readpartial2
+ ruby('-e', <<-SRC) do |f|
+ s = ""
+ begin
+ loop do
+ s << ARGF.readpartial(1)
+ t = ""; ARGF.readpartial(1, t); s << t
+ end
+ rescue EOFError
+ $stdout.binmode
+ puts s
+ end
+ SRC
+ f.binmode
+ f.puts("foo")
+ f.puts("bar")
+ f.puts("baz")
+ f.close_write
+ assert_equal("foo\nbar\nbaz\n", f.read)
+ end
+ end
+
+ def test_getc
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ while c = ARGF.getc
+ s << c
+ end
+ puts s
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_getbyte
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = []
+ while c = ARGF.getbyte
+ s << c
+ end
+ p s
+ SRC
+ assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
+ end
+ end
+
+ def test_readchar
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ begin
+ while c = ARGF.readchar
+ s << c
+ end
+ rescue EOFError
+ puts s
+ end
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_readbyte
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ s = []
+ while c = ARGF.readbyte
+ s << c
+ end
+ rescue EOFError
+ p s
+ end
+ SRC
+ assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
+ end
+ end
+
+ def test_each_line
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = []
+ ARGF.each_line {|l| s << l }
+ p s
+ SRC
+ assert_equal("[\"1\\n\", \"2\\n\", \"3\\n\", \"4\\n\", \"5\\n\", \"6\\n\"]\n", f.read)
+ end
+ end
+
+ def test_each_line_paragraph
+ assert_in_out_err(['-e', 'ARGF.each_line("") {|para| p para}'], "a\n\nb\n",
+ ["\"a\\n\\n\"", "\"b\\n\""], [])
+ end
+
+ def test_each_byte
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = []
+ ARGF.each_byte {|c| s << c }
+ p s
+ SRC
+ assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
+ end
+ end
+
+ def test_each_char
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ ARGF.each_char {|c| s << c }
+ puts s
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_filename
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ puts ARGF.filename.dump
+ end while ARGF.gets
+ puts ARGF.filename.dump
+ SRC
+ a = f.read.split("\n")
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ end
+ end
+
+ def test_filename2
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ puts $FILENAME.dump
+ end while ARGF.gets
+ puts $FILENAME.dump
+ SRC
+ a = f.read.split("\n")
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ end
+ end
+
+ def test_file
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ puts ARGF.file.path.dump
+ end while ARGF.gets
+ puts ARGF.file.path.dump
+ SRC
+ a = f.read.split("\n")
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ end
+ end
+
+ def test_binmode
+ ruby('-e', "ARGF.binmode; STDOUT.binmode; puts ARGF.read", @t1.path, @t2.path, @t3.path) do |f|
+ f.binmode
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_skip
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.skip
+ puts ARGF.gets
+ ARGF.skip
+ puts ARGF.read
+ SRC
+ assert_equal("1\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_close
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.close
+ puts ARGF.read
+ SRC
+ assert_equal("3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_closed
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ 3.times do
+ p ARGF.closed?
+ ARGF.gets
+ ARGF.gets
+ end
+ p ARGF.closed?
+ ARGF.gets
+ p ARGF.closed?
+ SRC
+ assert_equal("false\nfalse\nfalse\nfalse\ntrue\n", f.read)
+ end
+ end
+
+ def test_argv
+ ruby('-e', "p ARGF.argv; p $*", @t1.path, @t2.path, @t3.path) do |f|
+ assert_equal([@t1.path, @t2.path, @t3.path].inspect, f.gets.chomp)
+ assert_equal([@t1.path, @t2.path, @t3.path].inspect, f.gets.chomp)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_array.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_array.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_array.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,2066 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestArray < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ @cls = Array
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_0_literal
+ assert_equal([1, 2, 3, 4], [1, 2] + [3, 4])
+ assert_equal([1, 2, 1, 2], [1, 2] * 2)
+ assert_equal("1:2", [1, 2] * ":")
+
+ assert_equal([1, 2].hash, [1, 2].hash)
+
+ assert_equal([2,3], [1,2,3] & [2,3,4])
+ assert_equal([1,2,3,4], [1,2,3] | [2,3,4])
+ assert_equal([1,2,3] - [2,3], [1])
+
+ x = [0, 1, 2, 3, 4, 5]
+ assert_equal(2, x[2])
+ assert_equal([1, 2, 3], x[1..3])
+ assert_equal([1, 2, 3], x[1,3])
+
+ x[0, 2] = 10
+ assert(x[0] == 10 && x[1] == 2)
+
+ x[0, 0] = -1
+ assert(x[0] == -1 && x[1] == 10)
+
+ x[-1, 1] = 20
+ assert(x[-1] == 20 && x.pop == 20)
+ end
+
+ def test_array_andor_0
+ assert_equal([2], ([1,2,3]&[2,4,6]))
+ assert_equal([1,2,3,4,6], ([1,2,3]|[2,4,6]))
+ end
+
+ def test_compact_0
+ a = [nil, 1, nil, nil, 5, nil, nil]
+ assert_equal [1, 5], a.compact
+ assert_equal [nil, 1, nil, nil, 5, nil, nil], a
+ a.compact!
+ assert_equal [1, 5], a
+ end
+
+ def test_uniq_0
+ x = [1, 1, 4, 2, 5, 4, 5, 1, 2]
+ x.uniq!
+ assert_equal([1, 4, 2, 5], x)
+ end
+
+ def test_empty_0
+ assert_equal true, [].empty?
+ assert_equal false, [1].empty?
+ assert_equal false, [1, 1, 4, 2, 5, 4, 5, 1, 2].empty?
+ end
+
+ def test_sort_0
+ x = ["it", "came", "to", "pass", "that", "..."]
+ x = x.sort.join(" ")
+ assert_equal("... came it pass that to", x)
+ x = [2,5,3,1,7]
+ x.sort!{|a,b| a<=>b} # sort with condition
+ assert_equal([1,2,3,5,7], x)
+ x.sort!{|a,b| b-a} # reverse sort
+ assert_equal([7,5,3,2,1], x)
+ end
+
+ def test_split_0
+ x = "The Book of Mormon"
+ assert_equal(x.reverse, x.split(//).reverse!.join)
+ assert_equal(x.reverse, x.reverse!)
+ assert_equal("g:n:i:r:t:s: :e:t:y:b: :1", "1 byte string".split(//).reverse.join(":"))
+ x = "a b c d"
+ assert_equal(['a', 'b', 'c', 'd'], x.split)
+ assert_equal(['a', 'b', 'c', 'd'], x.split(' '))
+ end
+
+ def test_misc_0
+ assert(defined? "a".chomp)
+ assert_equal(["a", "b", "c"], "abc".scan(/./))
+ assert_equal([["1a"], ["2b"], ["3c"]], "1a2b3c".scan(/(\d.)/))
+ # non-greedy match
+ assert_equal([["a", "12"], ["b", "22"]], "a=12;b=22".scan(/(.*?)=(\d*);?/))
+
+ x = [1]
+ assert_equal('1:1:1:1:1', (x * 5).join(":"))
+ assert_equal('1', (x * 1).join(":"))
+ assert_equal('', (x * 0).join(":"))
+
+ *x = *(1..7).to_a
+ assert_equal(7, x.size)
+ assert_equal([1, 2, 3, 4, 5, 6, 7], x)
+
+ x = [1,2,3]
+ x[1,0] = x
+ assert_equal([1,1,2,3,2,3], x)
+
+ x = [1,2,3]
+ x[-1,0] = x
+ assert_equal([1,2,1,2,3,3], x)
+
+ x = [1,2,3]
+ x.concat(x)
+ assert_equal([1,2,3,1,2,3], x)
+
+ x = [1,2,3]
+ x.clear
+ assert_equal([], x)
+
+ x = [1,2,3]
+ y = x.dup
+ x << 4
+ y << 5
+ assert_equal([1,2,3,4], x)
+ assert_equal([1,2,3,5], y)
+ end
+
+ def test_beg_end_0
+ x = [1, 2, 3, 4, 5]
+
+ assert_equal(1, x.first)
+ assert_equal([1], x.first(1))
+ assert_equal([1, 2, 3], x.first(3))
+
+ assert_equal(5, x.last)
+ assert_equal([5], x.last(1))
+ assert_equal([3, 4, 5], x.last(3))
+
+ assert_equal(1, x.shift)
+ assert_equal([2, 3, 4], x.shift(3))
+ assert_equal([5], x)
+
+ assert_equal([2, 3, 4, 5], x.unshift(2, 3, 4))
+ assert_equal([1, 2, 3, 4, 5], x.unshift(1))
+ assert_equal([1, 2, 3, 4, 5], x)
+
+ assert_equal(5, x.pop)
+ assert_equal([3, 4], x.pop(2))
+ assert_equal([1, 2], x)
+
+ assert_equal([1, 2, 3, 4], x.push(3, 4))
+ assert_equal([1, 2, 3, 4, 5], x.push(5))
+ assert_equal([1, 2, 3, 4, 5], x)
+ end
+
+ def test_find_all_0
+ assert_respond_to([], :find_all)
+ assert_respond_to([], :select) # Alias
+ assert_equal([], [].find_all{ |obj| obj == "foo"})
+
+ x = ["foo", "bar", "baz", "baz", 1, 2, 3, 3, 4]
+ assert_equal(["baz","baz"], x.find_all{ |obj| obj == "baz" })
+ assert_equal([3,3], x.find_all{ |obj| obj == 3 })
+ end
+
+ def test_fill_0
+ assert_equal([-1, -1, -1, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1))
+ assert_equal([0, 1, 2, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, 3))
+ assert_equal([0, 1, 2, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3, 2))
+ assert_equal([0, 1, 2, -1, -1, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, 3, 5))
+ assert_equal([0, 1, -1, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2, 2))
+ assert_equal([0, 1, -1, -1, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, 2, 5))
+ assert_equal([0, 1, 2, 3, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, -2, 1))
+ assert_equal([0, 1, 2, 3, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, -2, 3))
+ assert_equal([0, 1, 2, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3..4))
+ assert_equal([0, 1, 2, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3...4))
+ assert_equal([0, 1, -1, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2..-2))
+ assert_equal([0, 1, -1, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2...-2))
+ assert_equal([10, 11, 12, 13, 14, 15], [0, 1, 2, 3, 4, 5].fill{|i| i+10})
+ assert_equal([0, 1, 2, 13, 14, 15], [0, 1, 2, 3, 4, 5].fill(3){|i| i+10})
+ assert_equal([0, 1, 2, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(3, 2){|i| i+10})
+ assert_equal([0, 1, 2, 13, 14, 15, 16, 17], [0, 1, 2, 3, 4, 5].fill(3, 5){|i| i+10})
+ assert_equal([0, 1, 2, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(3..4){|i| i+10})
+ assert_equal([0, 1, 2, 13, 4, 5], [0, 1, 2, 3, 4, 5].fill(3...4){|i| i+10})
+ assert_equal([0, 1, 12, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(2..-2){|i| i+10})
+ assert_equal([0, 1, 12, 13, 4, 5], [0, 1, 2, 3, 4, 5].fill(2...-2){|i| i+10})
+ end
+
+ # From rubicon
+
+ def test_00_new
+ a = @cls.new()
+ assert_instance_of(@cls, a)
+ assert_equal(0, a.length)
+ assert_nil(a[0])
+ end
+
+ def test_01_square_brackets
+ a = @cls[ 5, 4, 3, 2, 1 ]
+ assert_instance_of(@cls, a)
+ assert_equal(5, a.length)
+ 5.times { |i| assert_equal(5-i, a[i]) }
+ assert_nil(a[6])
+ end
+
+ def test_AND # '&'
+ assert_equal(@cls[1, 3], @cls[ 1, 1, 3, 5 ] & @cls[ 1, 2, 3 ])
+ assert_equal(@cls[], @cls[ 1, 1, 3, 5 ] & @cls[ ])
+ assert_equal(@cls[], @cls[ ] & @cls[ 1, 2, 3 ])
+ assert_equal(@cls[], @cls[ 1, 2, 3 ] & @cls[ 4, 5, 6 ])
+ end
+
+ def test_MUL # '*'
+ assert_equal(@cls[], @cls[]*3)
+ assert_equal(@cls[1, 1, 1], @cls[1]*3)
+ assert_equal(@cls[1, 2, 1, 2, 1, 2], @cls[1, 2]*3)
+ assert_equal(@cls[], @cls[1, 2, 3] * 0)
+ assert_raise(ArgumentError) { @cls[1, 2]*(-3) }
+
+ assert_equal('1-2-3-4-5', @cls[1, 2, 3, 4, 5] * '-')
+ assert_equal('12345', @cls[1, 2, 3, 4, 5] * '')
+
+ end
+
+ def test_PLUS # '+'
+ assert_equal(@cls[], @cls[] + @cls[])
+ assert_equal(@cls[1], @cls[1] + @cls[])
+ assert_equal(@cls[1], @cls[] + @cls[1])
+ assert_equal(@cls[1, 1], @cls[1] + @cls[1])
+ assert_equal(@cls['cat', 'dog', 1, 2, 3], %w(cat dog) + (1..3).to_a)
+ end
+
+ def test_MINUS # '-'
+ assert_equal(@cls[], @cls[1] - @cls[1])
+ assert_equal(@cls[1], @cls[1, 2, 3, 4, 5] - @cls[2, 3, 4, 5])
+ # Ruby 1.8 feature change
+ #assert_equal(@cls[1], @cls[1, 2, 1, 3, 1, 4, 1, 5] - @cls[2, 3, 4, 5])
+ assert_equal(@cls[1, 1, 1, 1], @cls[1, 2, 1, 3, 1, 4, 1, 5] - @cls[2, 3, 4, 5])
+ a = @cls[]
+ 1000.times { a << 1 }
+ assert_equal(1000, a.length)
+ #assert_equal(@cls[1], a - @cls[2])
+ assert_equal(@cls[1] * 1000, a - @cls[2])
+ #assert_equal(@cls[1], @cls[1, 2, 1] - @cls[2])
+ assert_equal(@cls[1, 1], @cls[1, 2, 1] - @cls[2])
+ assert_equal(@cls[1, 2, 3], @cls[1, 2, 3] - @cls[4, 5, 6])
+ end
+
+ def test_LSHIFT # '<<'
+ a = @cls[]
+ a << 1
+ assert_equal(@cls[1], a)
+ a << 2 << 3
+ assert_equal(@cls[1, 2, 3], a)
+ a << nil << 'cat'
+ assert_equal(@cls[1, 2, 3, nil, 'cat'], a)
+ a << a
+ assert_equal(@cls[1, 2, 3, nil, 'cat', a], a)
+ end
+
+ def test_CMP # '<=>'
+ assert_equal(0, @cls[] <=> @cls[])
+ assert_equal(0, @cls[1] <=> @cls[1])
+ assert_equal(0, @cls[1, 2, 3, 'cat'] <=> @cls[1, 2, 3, 'cat'])
+ assert_equal(-1, @cls[] <=> @cls[1])
+ assert_equal(1, @cls[1] <=> @cls[])
+ assert_equal(-1, @cls[1, 2, 3] <=> @cls[1, 2, 3, 'cat'])
+ assert_equal(1, @cls[1, 2, 3, 'cat'] <=> @cls[1, 2, 3])
+ assert_equal(-1, @cls[1, 2, 3, 'cat'] <=> @cls[1, 2, 3, 'dog'])
+ assert_equal(1, @cls[1, 2, 3, 'dog'] <=> @cls[1, 2, 3, 'cat'])
+ end
+
+ def test_EQUAL # '=='
+ assert(@cls[] == @cls[])
+ assert(@cls[1] == @cls[1])
+ assert(@cls[1, 1, 2, 2] == @cls[1, 1, 2, 2])
+ assert(@cls[1.0, 1.0, 2.0, 2.0] == @cls[1, 1, 2, 2])
+ end
+
+ def test_VERY_EQUAL # '==='
+ assert(@cls[] === @cls[])
+ assert(@cls[1] === @cls[1])
+ assert(@cls[1, 1, 2, 2] === @cls[1, 1, 2, 2])
+ assert(@cls[1.0, 1.0, 2.0, 2.0] === @cls[1, 1, 2, 2])
+ end
+
+ def test_AREF # '[]'
+ a = @cls[*(1..100).to_a]
+
+ assert_equal(1, a[0])
+ assert_equal(100, a[99])
+ assert_nil(a[100])
+ assert_equal(100, a[-1])
+ assert_equal(99, a[-2])
+ assert_equal(1, a[-100])
+ assert_nil(a[-101])
+ assert_nil(a[-101,0])
+ assert_nil(a[-101,1])
+ assert_nil(a[-101,-1])
+ assert_nil(a[10,-1])
+
+ assert_equal(@cls[1], a[0,1])
+ assert_equal(@cls[100], a[99,1])
+ assert_equal(@cls[], a[100,1])
+ assert_equal(@cls[100], a[99,100])
+ assert_equal(@cls[100], a[-1,1])
+ assert_equal(@cls[99], a[-2,1])
+ assert_equal(@cls[], a[-100,0])
+ assert_equal(@cls[1], a[-100,1])
+
+ assert_equal(@cls[10, 11, 12], a[9, 3])
+ assert_equal(@cls[10, 11, 12], a[-91, 3])
+
+ assert_equal(@cls[1], a[0..0])
+ assert_equal(@cls[100], a[99..99])
+ assert_equal(@cls[], a[100..100])
+ assert_equal(@cls[100], a[99..200])
+ assert_equal(@cls[100], a[-1..-1])
+ assert_equal(@cls[99], a[-2..-2])
+
+ assert_equal(@cls[10, 11, 12], a[9..11])
+ assert_equal(@cls[10, 11, 12], a[-91..-89])
+
+ assert_nil(a[10, -3])
+ # Ruby 1.8 feature change:
+ # Array#[size..x] returns [] instead of nil.
+ #assert_nil(a[10..7])
+ assert_equal [], a[10..7]
+
+ assert_raise(TypeError) {a['cat']}
+ end
+
+ def test_ASET # '[]='
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a[0] = 0)
+ assert_equal(@cls[0] + @cls[*(1..99).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a[10,10] = 0)
+ assert_equal(@cls[*(0..9).to_a] + @cls[0] + @cls[*(20..99).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a[-1] = 0)
+ assert_equal(@cls[*(0..98).to_a] + @cls[0], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a[-10, 10] = 0)
+ assert_equal(@cls[*(0..89).to_a] + @cls[0], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a[0,1000] = 0)
+ assert_equal(@cls[0] , a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a[10..19] = 0)
+ assert_equal(@cls[*(0..9).to_a] + @cls[0] + @cls[*(20..99).to_a], a)
+
+ b = @cls[*%w( a b c )]
+ a = @cls[*(0..99).to_a]
+ assert_equal(b, a[0,1] = b)
+ assert_equal(b + @cls[*(1..99).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(b, a[10,10] = b)
+ assert_equal(@cls[*(0..9).to_a] + b + @cls[*(20..99).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(b, a[-1, 1] = b)
+ assert_equal(@cls[*(0..98).to_a] + b, a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(b, a[-10, 10] = b)
+ assert_equal(@cls[*(0..89).to_a] + b, a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(b, a[0,1000] = b)
+ assert_equal(b , a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(b, a[10..19] = b)
+ assert_equal(@cls[*(0..9).to_a] + b + @cls[*(20..99).to_a], a)
+
+ # Ruby 1.8 feature change:
+ # assigning nil does not remove elements.
+=begin
+ a = @cls[*(0..99).to_a]
+ assert_equal(nil, a[0,1] = nil)
+ assert_equal(@cls[*(1..99).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(nil, a[10,10] = nil)
+ assert_equal(@cls[*(0..9).to_a] + @cls[*(20..99).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(nil, a[-1, 1] = nil)
+ assert_equal(@cls[*(0..98).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(nil, a[-10, 10] = nil)
+ assert_equal(@cls[*(0..89).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(nil, a[0,1000] = nil)
+ assert_equal(@cls[] , a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(nil, a[10..19] = nil)
+ assert_equal(@cls[*(0..9).to_a] + @cls[*(20..99).to_a], a)
+=end
+
+ a = @cls[1, 2, 3]
+ a[1, 0] = a
+ assert_equal([1, 1, 2, 3, 2, 3], a)
+
+ a = @cls[1, 2, 3]
+ a[-1, 0] = a
+ assert_equal([1, 2, 1, 2, 3, 3], a)
+ end
+
+ def test_assoc
+ a1 = @cls[*%w( cat feline )]
+ a2 = @cls[*%w( dog canine )]
+ a3 = @cls[*%w( mule asinine )]
+
+ a = @cls[ a1, a2, a3 ]
+
+ assert_equal(a1, a.assoc('cat'))
+ assert_equal(a3, a.assoc('mule'))
+ assert_equal(nil, a.assoc('asinine'))
+ assert_equal(nil, a.assoc('wombat'))
+ assert_equal(nil, a.assoc(1..2))
+ end
+
+ def test_at
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a.at(0))
+ assert_equal(10, a.at(10))
+ assert_equal(99, a.at(99))
+ assert_equal(nil, a.at(100))
+ assert_equal(99, a.at(-1))
+ assert_equal(0, a.at(-100))
+ assert_equal(nil, a.at(-101))
+ assert_raise(TypeError) { a.at('cat') }
+ end
+
+ def test_clear
+ a = @cls[1, 2, 3]
+ b = a.clear
+ assert_equal(@cls[], a)
+ assert_equal(@cls[], b)
+ assert_equal(a.__id__, b.__id__)
+ end
+
+ def test_clone
+ for taint in [ false, true ]
+ for untrust in [ false, true ]
+ for frozen in [ false, true ]
+ a = @cls[*(0..99).to_a]
+ a.taint if taint
+ a.untrust if untrust
+ a.freeze if frozen
+ b = a.clone
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert_equal(a.frozen?, b.frozen?)
+ assert_equal(a.untrusted?, b.untrusted?)
+ assert_equal(a.tainted?, b.tainted?)
+ end
+ end
+ end
+ end
+
+ def test_collect
+ a = @cls[ 1, 'cat', 1..1 ]
+ assert_equal([ Fixnum, String, Range], a.collect {|e| e.class} )
+ assert_equal([ 99, 99, 99], a.collect { 99 } )
+
+ assert_equal([], @cls[].collect { 99 })
+
+ # Ruby 1.9 feature change:
+ # Enumerable#collect without block returns an Enumerator.
+ #assert_equal([1, 2, 3], @cls[1, 2, 3].collect)
+ assert_kind_of Enumerator, @cls[1, 2, 3].collect
+ end
+
+ # also update map!
+ def test_collect!
+ a = @cls[ 1, 'cat', 1..1 ]
+ assert_equal([ Fixnum, String, Range], a.collect! {|e| e.class} )
+ assert_equal([ Fixnum, String, Range], a)
+
+ a = @cls[ 1, 'cat', 1..1 ]
+ assert_equal([ 99, 99, 99], a.collect! { 99 } )
+ assert_equal([ 99, 99, 99], a)
+
+ a = @cls[ ]
+ assert_equal([], a.collect! { 99 })
+ assert_equal([], a)
+ end
+
+ def test_compact
+ a = @cls[ 1, nil, nil, 2, 3, nil, 4 ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact)
+
+ a = @cls[ nil, 1, nil, 2, 3, nil, 4 ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact)
+
+ a = @cls[ 1, nil, nil, 2, 3, nil, 4, nil ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact)
+
+ a = @cls[ 1, 2, 3, 4 ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact)
+ end
+
+ def test_compact!
+ a = @cls[ 1, nil, nil, 2, 3, nil, 4 ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact!)
+ assert_equal(@cls[1, 2, 3, 4], a)
+
+ a = @cls[ nil, 1, nil, 2, 3, nil, 4 ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact!)
+ assert_equal(@cls[1, 2, 3, 4], a)
+
+ a = @cls[ 1, nil, nil, 2, 3, nil, 4, nil ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact!)
+ assert_equal(@cls[1, 2, 3, 4], a)
+
+ a = @cls[ 1, 2, 3, 4 ]
+ assert_equal(nil, a.compact!)
+ assert_equal(@cls[1, 2, 3, 4], a)
+ end
+
+ def test_concat
+ assert_equal(@cls[1, 2, 3, 4], @cls[1, 2].concat(@cls[3, 4]))
+ assert_equal(@cls[1, 2, 3, 4], @cls[].concat(@cls[1, 2, 3, 4]))
+ assert_equal(@cls[1, 2, 3, 4], @cls[1, 2, 3, 4].concat(@cls[]))
+ assert_equal(@cls[], @cls[].concat(@cls[]))
+ assert_equal(@cls[@cls[1, 2], @cls[3, 4]], @cls[@cls[1, 2]].concat(@cls[@cls[3, 4]]))
+
+ a = @cls[1, 2, 3]
+ a.concat(a)
+ assert_equal([1, 2, 3, 1, 2, 3], a)
+
+ assert_raise(TypeError) { [0].concat(:foo) }
+ assert_raise(RuntimeError) { [0].freeze.concat(:foo) }
+ end
+
+ def test_count
+ a = @cls[1, 2, 3, 1, 2]
+ assert_equal(5, a.count)
+ assert_equal(2, a.count(1))
+ assert_equal(3, a.count {|x| x % 2 == 1 })
+ assert_equal(2, a.count(1) {|x| x % 2 == 1 })
+ assert_raise(ArgumentError) { a.count(0, 1) }
+ end
+
+ def test_delete
+ a = @cls[*('cab'..'cat').to_a]
+ assert_equal('cap', a.delete('cap'))
+ assert_equal(@cls[*('cab'..'cao').to_a] + @cls[*('caq'..'cat').to_a], a)
+
+ a = @cls[*('cab'..'cat').to_a]
+ assert_equal('cab', a.delete('cab'))
+ assert_equal(@cls[*('cac'..'cat').to_a], a)
+
+ a = @cls[*('cab'..'cat').to_a]
+ assert_equal('cat', a.delete('cat'))
+ assert_equal(@cls[*('cab'..'cas').to_a], a)
+
+ a = @cls[*('cab'..'cat').to_a]
+ assert_equal(nil, a.delete('cup'))
+ assert_equal(@cls[*('cab'..'cat').to_a], a)
+
+ a = @cls[*('cab'..'cat').to_a]
+ assert_equal(99, a.delete('cup') { 99 } )
+ assert_equal(@cls[*('cab'..'cat').to_a], a)
+ end
+
+ def test_delete_at
+ a = @cls[*(1..5).to_a]
+ assert_equal(3, a.delete_at(2))
+ assert_equal(@cls[1, 2, 4, 5], a)
+
+ a = @cls[*(1..5).to_a]
+ assert_equal(4, a.delete_at(-2))
+ assert_equal(@cls[1, 2, 3, 5], a)
+
+ a = @cls[*(1..5).to_a]
+ assert_equal(nil, a.delete_at(5))
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[*(1..5).to_a]
+ assert_equal(nil, a.delete_at(-6))
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+ end
+
+ # also reject!
+ def test_delete_if
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(a, a.delete_if { false })
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(a, a.delete_if { true })
+ assert_equal(@cls[], a)
+
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(a, a.delete_if { |i| i > 3 })
+ assert_equal(@cls[1, 2, 3], a)
+ end
+
+ def test_dup
+ for taint in [ false, true ]
+ for frozen in [ false, true ]
+ a = @cls[*(0..99).to_a]
+ a.taint if taint
+ a.freeze if frozen
+ b = a.dup
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert_equal(false, b.frozen?)
+ assert_equal(a.tainted?, b.tainted?)
+ end
+ end
+ end
+
+ def test_each
+ a = @cls[*%w( ant bat cat dog )]
+ i = 0
+ a.each { |e|
+ assert_equal(a[i], e)
+ i += 1
+ }
+ assert_equal(4, i)
+
+ a = @cls[]
+ i = 0
+ a.each { |e|
+ assert_equal(a[i], e)
+ i += 1
+ }
+ assert_equal(0, i)
+
+ assert_equal(a, a.each {})
+ end
+
+ def test_each_index
+ a = @cls[*%w( ant bat cat dog )]
+ i = 0
+ a.each_index { |ind|
+ assert_equal(i, ind)
+ i += 1
+ }
+ assert_equal(4, i)
+
+ a = @cls[]
+ i = 0
+ a.each_index { |ind|
+ assert_equal(i, ind)
+ i += 1
+ }
+ assert_equal(0, i)
+
+ assert_equal(a, a.each_index {})
+ end
+
+ def test_empty?
+ assert(@cls[].empty?)
+ assert(!@cls[1].empty?)
+ end
+
+ def test_eql?
+ assert(@cls[].eql?(@cls[]))
+ assert(@cls[1].eql?(@cls[1]))
+ assert(@cls[1, 1, 2, 2].eql?(@cls[1, 1, 2, 2]))
+ assert(!@cls[1.0, 1.0, 2.0, 2.0].eql?(@cls[1, 1, 2, 2]))
+ end
+
+ def test_fill
+ assert_equal(@cls[], @cls[].fill(99))
+ assert_equal(@cls[], @cls[].fill(99, 0))
+ assert_equal(@cls[99], @cls[].fill(99, 0, 1))
+ assert_equal(@cls[99], @cls[].fill(99, 0..0))
+
+ assert_equal(@cls[99], @cls[1].fill(99))
+ assert_equal(@cls[99], @cls[1].fill(99, 0))
+ assert_equal(@cls[99], @cls[1].fill(99, 0, 1))
+ assert_equal(@cls[99], @cls[1].fill(99, 0..0))
+
+ assert_equal(@cls[99, 99], @cls[1, 2].fill(99))
+ assert_equal(@cls[99, 99], @cls[1, 2].fill(99, 0))
+ assert_equal(@cls[99, 99], @cls[1, 2].fill(99, nil))
+ assert_equal(@cls[1, 99], @cls[1, 2].fill(99, 1, nil))
+ assert_equal(@cls[99, 2], @cls[1, 2].fill(99, 0, 1))
+ assert_equal(@cls[99, 2], @cls[1, 2].fill(99, 0..0))
+ end
+
+ def test_first
+ assert_equal(3, @cls[3, 4, 5].first)
+ assert_equal(nil, @cls[].first)
+ end
+
+ def test_flatten
+ a1 = @cls[ 1, 2, 3]
+ a2 = @cls[ 5, 6 ]
+ a3 = @cls[ 4, a2 ]
+ a4 = @cls[ a1, a3 ]
+ assert_equal(@cls[1, 2, 3, 4, 5, 6], a4.flatten)
+ assert_equal(@cls[ a1, a3], a4)
+
+ a5 = @cls[ a1, @cls[], a3 ]
+ assert_equal(@cls[1, 2, 3, 4, 5, 6], a5.flatten)
+ assert_equal(@cls[], @cls[].flatten)
+ assert_equal(@cls[],
+ @cls[@cls[@cls[@cls[], at cls[]], at cls[@cls[]], at cls[]], at cls[@cls[@cls[]]]].flatten)
+
+ assert_raise(TypeError, "[ruby-dev:31197]") { [[]].flatten("") }
+
+ a6 = @cls[[1, 2], 3]
+ a6.taint
+ a6.untrust
+ a7 = a6.flatten
+ assert_equal(true, a7.tainted?)
+ assert_equal(true, a7.untrusted?)
+
+ a8 = @cls[[1, 2], 3]
+ a9 = a8.flatten(0)
+ assert_equal(a8, a9)
+ assert_not_same(a8, a9)
+ end
+
+ def test_flatten!
+ a1 = @cls[ 1, 2, 3]
+ a2 = @cls[ 5, 6 ]
+ a3 = @cls[ 4, a2 ]
+ a4 = @cls[ a1, a3 ]
+ assert_equal(@cls[1, 2, 3, 4, 5, 6], a4.flatten!)
+ assert_equal(@cls[1, 2, 3, 4, 5, 6], a4)
+
+ a5 = @cls[ a1, @cls[], a3 ]
+ assert_equal(@cls[1, 2, 3, 4, 5, 6], a5.flatten!)
+ assert_nil(a5.flatten!(0), '[ruby-core:23382]')
+ assert_equal(@cls[1, 2, 3, 4, 5, 6], a5)
+
+ assert_equal(@cls[], @cls[].flatten)
+ assert_equal(@cls[],
+ @cls[@cls[@cls[@cls[], at cls[]], at cls[@cls[]], at cls[]], at cls[@cls[@cls[]]]].flatten)
+
+ assert_nil(@cls[].flatten!(0), '[ruby-core:23382]')
+ end
+
+ def test_flatten_with_callcc
+ respond_to?(:callcc, true) or require 'continuation'
+ o = Object.new
+ def o.to_ary() callcc {|k| @cont = k; [1,2,3]} end
+ begin
+ assert_equal([10, 20, 1, 2, 3, 30, 1, 2, 3, 40], [10, 20, o, 30, o, 40].flatten)
+ rescue => e
+ else
+ o.instance_eval {@cont}.call
+ end
+ assert_instance_of(RuntimeError, e, '[ruby-dev:34798]')
+ assert_match(/reentered/, e.message, '[ruby-dev:34798]')
+ end
+
+ def test_permutation_with_callcc
+ respond_to?(:callcc, true) or require 'continuation'
+ n = 1000
+ cont = nil
+ ary = [1,2,3]
+ begin
+ ary.permutation {
+ callcc {|k| cont = k} unless cont
+ }
+ rescue => e
+ end
+ n -= 1
+ cont.call if 0 < n
+ assert_instance_of(RuntimeError, e)
+ assert_match(/reentered/, e.message)
+ end
+
+ def test_product_with_callcc
+ respond_to?(:callcc, true) or require 'continuation'
+ n = 1000
+ cont = nil
+ ary = [1,2,3]
+ begin
+ ary.product {
+ callcc {|k| cont = k} unless cont
+ }
+ rescue => e
+ end
+ n -= 1
+ cont.call if 0 < n
+ assert_instance_of(RuntimeError, e)
+ assert_match(/reentered/, e.message)
+ end
+
+ def test_combination_with_callcc
+ respond_to?(:callcc, true) or require 'continuation'
+ n = 1000
+ cont = nil
+ ary = [1,2,3]
+ begin
+ ary.combination(2) {
+ callcc {|k| cont = k} unless cont
+ }
+ rescue => e
+ end
+ n -= 1
+ cont.call if 0 < n
+ assert_instance_of(RuntimeError, e)
+ assert_match(/reentered/, e.message)
+ end
+
+ def test_repeated_permutation_with_callcc
+ respond_to?(:callcc, true) or require 'continuation'
+ n = 1000
+ cont = nil
+ ary = [1,2,3]
+ begin
+ ary.repeated_permutation(2) {
+ callcc {|k| cont = k} unless cont
+ }
+ rescue => e
+ end
+ n -= 1
+ cont.call if 0 < n
+ assert_instance_of(RuntimeError, e)
+ assert_match(/reentered/, e.message)
+ end
+
+ def test_repeated_combination_with_callcc
+ respond_to?(:callcc, true) or require 'continuation'
+ n = 1000
+ cont = nil
+ ary = [1,2,3]
+ begin
+ ary.repeated_combination(2) {
+ callcc {|k| cont = k} unless cont
+ }
+ rescue => e
+ end
+ n -= 1
+ cont.call if 0 < n
+ assert_instance_of(RuntimeError, e)
+ assert_match(/reentered/, e.message)
+ end
+
+ def test_hash
+ a1 = @cls[ 'cat', 'dog' ]
+ a2 = @cls[ 'cat', 'dog' ]
+ a3 = @cls[ 'dog', 'cat' ]
+ assert(a1.hash == a2.hash)
+ assert(a1.hash != a3.hash)
+ end
+
+ def test_include?
+ a = @cls[ 'cat', 99, /a/, @cls[ 1, 2, 3] ]
+ assert(a.include?('cat'))
+ assert(a.include?(99))
+ assert(a.include?(/a/))
+ assert(a.include?([1,2,3]))
+ assert(!a.include?('ca'))
+ assert(!a.include?([1,2]))
+ end
+
+ def test_index
+ a = @cls[ 'cat', 99, /a/, 99, @cls[ 1, 2, 3] ]
+ assert_equal(0, a.index('cat'))
+ assert_equal(1, a.index(99))
+ assert_equal(4, a.index([1,2,3]))
+ assert_nil(a.index('ca'))
+ assert_nil(a.index([1,2]))
+
+ assert_equal(1, a.index(99) {|x| x == 'cat' })
+ end
+
+ def test_values_at
+ a = @cls[*('a'..'j').to_a]
+ assert_equal(@cls['a', 'c', 'e'], a.values_at(0, 2, 4))
+ assert_equal(@cls['j', 'h', 'f'], a.values_at(-1, -3, -5))
+ assert_equal(@cls['h', nil, 'a'], a.values_at(-3, 99, 0))
+ end
+
+ def test_join
+ $, = ""
+ a = @cls[]
+ assert_equal("", a.join)
+ assert_equal("", a.join(','))
+
+ $, = ""
+ a = @cls[1, 2]
+ assert_equal("12", a.join)
+ assert_equal("1,2", a.join(','))
+
+ $, = ""
+ a = @cls[1, 2, 3]
+ assert_equal("123", a.join)
+ assert_equal("1,2,3", a.join(','))
+
+ $, = ":"
+ a = @cls[1, 2, 3]
+ assert_equal("1:2:3", a.join)
+ assert_equal("1,2,3", a.join(','))
+
+ $, = ""
+ a = @cls[1, 2, 3]
+ a.taint
+ a.untrust
+ s = a.join
+ assert_equal(true, s.tainted?)
+ assert_equal(true, s.untrusted?)
+ ensure
+ $, = nil
+ end
+
+ def test_last
+ assert_equal(nil, @cls[].last)
+ assert_equal(1, @cls[1].last)
+ assert_equal(99, @cls[*(3..99).to_a].last)
+ end
+
+ def test_length
+ assert_equal(0, @cls[].length)
+ assert_equal(1, @cls[1].length)
+ assert_equal(2, @cls[1, nil].length)
+ assert_equal(2, @cls[nil, 1].length)
+ assert_equal(234, @cls[*(0..233).to_a].length)
+ end
+
+ # also update collect!
+ def test_map!
+ a = @cls[ 1, 'cat', 1..1 ]
+ assert_equal(@cls[ Fixnum, String, Range], a.map! {|e| e.class} )
+ assert_equal(@cls[ Fixnum, String, Range], a)
+
+ a = @cls[ 1, 'cat', 1..1 ]
+ assert_equal(@cls[ 99, 99, 99], a.map! { 99 } )
+ assert_equal(@cls[ 99, 99, 99], a)
+
+ a = @cls[ ]
+ assert_equal(@cls[], a.map! { 99 })
+ assert_equal(@cls[], a)
+ end
+
+ def test_pack
+ a = @cls[*%w( cat wombat x yy)]
+ assert_equal("catwomx yy ", a.pack("A3A3A3A3"))
+ assert_equal("cat", a.pack("A*"))
+ assert_equal("cwx yy ", a.pack("A3 at 1A3@2A3A3"))
+ assert_equal("catwomx\000\000yy\000", a.pack("a3a3a3a3"))
+ assert_equal("cat", a.pack("a*"))
+ assert_equal("ca", a.pack("a2"))
+ assert_equal("cat\000\000", a.pack("a5"))
+
+ assert_equal("\x61", @cls["01100001"].pack("B8"))
+ assert_equal("\x61", @cls["01100001"].pack("B*"))
+ assert_equal("\x61", @cls["0110000100110111"].pack("B8"))
+ assert_equal("\x61\x37", @cls["0110000100110111"].pack("B16"))
+ assert_equal("\x61\x37", @cls["01100001", "00110111"].pack("B8B8"))
+ assert_equal("\x60", @cls["01100001"].pack("B4"))
+ assert_equal("\x40", @cls["01100001"].pack("B2"))
+
+ assert_equal("\x86", @cls["01100001"].pack("b8"))
+ assert_equal("\x86", @cls["01100001"].pack("b*"))
+ assert_equal("\x86", @cls["0110000100110111"].pack("b8"))
+ assert_equal("\x86\xec", @cls["0110000100110111"].pack("b16"))
+ assert_equal("\x86\xec", @cls["01100001", "00110111"].pack("b8b8"))
+ assert_equal("\x06", @cls["01100001"].pack("b4"))
+ assert_equal("\x02", @cls["01100001"].pack("b2"))
+
+ assert_equal("ABC", @cls[ 65, 66, 67 ].pack("C3"))
+ assert_equal("\377BC", @cls[ -1, 66, 67 ].pack("C*"))
+ assert_equal("ABC", @cls[ 65, 66, 67 ].pack("c3"))
+ assert_equal("\377BC", @cls[ -1, 66, 67 ].pack("c*"))
+
+
+ assert_equal("AB\n\x10", @cls["4142", "0a", "12"].pack("H4H2H1"))
+ assert_equal("AB\n\x02", @cls["1424", "a0", "21"].pack("h4h2h1"))
+
+ assert_equal("abc=02def=\ncat=\n=01=\n",
+ @cls["abc\002def", "cat", "\001"].pack("M9M3M4"))
+
+ assert_equal("aGVsbG8K\n", @cls["hello\n"].pack("m"))
+ assert_equal(",:&5L;&\\*:&5L;&\\*\n", @cls["hello\nhello\n"].pack("u"))
+
+ assert_equal("\u{a9 42 2260}", @cls[0xa9, 0x42, 0x2260].pack("U*"))
+
+
+ format = "c2x5CCxsdils_l_a6";
+ # Need the expression in here to force ary[5] to be numeric. This avoids
+ # test2 failing because ary2 goes str->numeric->str and ary does not.
+ ary = [1, -100, 127, 128, 32767, 987.654321098/100.0,
+ 12345, 123456, -32767, -123456, "abcdef"]
+ x = ary.pack(format)
+ ary2 = x.unpack(format)
+
+ assert_equal(ary.length, ary2.length)
+ assert_equal(ary.join(':'), ary2.join(':'))
+ assert_not_nil(x =~ /def/)
+
+=begin
+ skipping "Not tested:
+ D,d & double-precision float, native format\\
+ E & double-precision float, little-endian byte order\\
+ e & single-precision float, little-endian byte order\\
+ F,f & single-precision float, native format\\
+ G & double-precision float, network (big-endian) byte order\\
+ g & single-precision float, network (big-endian) byte order\\
+ I & unsigned integer\\
+ i & integer\\
+ L & unsigned long\\
+ l & long\\
+
+ N & long, network (big-endian) byte order\\
+ n & short, network (big-endian) byte-order\\
+ P & pointer to a structure (fixed-length string)\\
+ p & pointer to a null-terminated string\\
+ S & unsigned short\\
+ s & short\\
+ V & long, little-endian byte order\\
+ v & short, little-endian byte order\\
+ X & back up a byte\\
+ x & null byte\\
+ Z & ASCII string (null padded, count is width)\\
+"
+=end
+ end
+
+ def test_pop
+ a = @cls[ 'cat', 'dog' ]
+ assert_equal('dog', a.pop)
+ assert_equal(@cls['cat'], a)
+ assert_equal('cat', a.pop)
+ assert_equal(@cls[], a)
+ assert_nil(a.pop)
+ assert_equal(@cls[], a)
+ end
+
+ def test_push
+ a = @cls[1, 2, 3]
+ assert_equal(@cls[1, 2, 3, 4, 5], a.push(4, 5))
+ assert_equal(@cls[1, 2, 3, 4, 5, nil], a.push(nil))
+ # Ruby 1.8 feature:
+ # Array#push accepts any number of arguments.
+ #assert_raise(ArgumentError, "a.push()") { a.push() }
+ a.push
+ assert_equal @cls[1, 2, 3, 4, 5, nil], a
+ a.push 6, 7
+ assert_equal @cls[1, 2, 3, 4, 5, nil, 6, 7], a
+ end
+
+ def test_rassoc
+ a1 = @cls[*%w( cat feline )]
+ a2 = @cls[*%w( dog canine )]
+ a3 = @cls[*%w( mule asinine )]
+ a = @cls[ a1, a2, a3 ]
+
+ assert_equal(a1, a.rassoc('feline'))
+ assert_equal(a3, a.rassoc('asinine'))
+ assert_equal(nil, a.rassoc('dog'))
+ assert_equal(nil, a.rassoc('mule'))
+ assert_equal(nil, a.rassoc(1..2))
+ end
+
+ # also delete_if
+ def test_reject!
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(nil, a.reject! { false })
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(a, a.reject! { true })
+ assert_equal(@cls[], a)
+
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(a, a.reject! { |i| i > 3 })
+ assert_equal(@cls[1, 2, 3], a)
+ end
+
+ def test_replace
+ a = @cls[ 1, 2, 3]
+ a_id = a.__id__
+ assert_equal(@cls[4, 5, 6], a.replace(@cls[4, 5, 6]))
+ assert_equal(@cls[4, 5, 6], a)
+ assert_equal(a_id, a.__id__)
+ assert_equal(@cls[], a.replace(@cls[]))
+
+ fa = a.dup.freeze
+ assert_nothing_raised(RuntimeError) { a.replace(a) }
+ assert_raise(RuntimeError) { fa.replace(fa) }
+ assert_raise(ArgumentError) { fa.replace() }
+ assert_raise(TypeError) { a.replace(42) }
+ assert_raise(RuntimeError) { fa.replace(42) }
+ end
+
+ def test_reverse
+ a = @cls[*%w( dog cat bee ant )]
+ assert_equal(@cls[*%w(ant bee cat dog)], a.reverse)
+ assert_equal(@cls[*%w(dog cat bee ant)], a)
+ assert_equal(@cls[], @cls[].reverse)
+ end
+
+ def test_reverse!
+ a = @cls[*%w( dog cat bee ant )]
+ assert_equal(@cls[*%w(ant bee cat dog)], a.reverse!)
+ assert_equal(@cls[*%w(ant bee cat dog)], a)
+ # Ruby 1.8 feature change:
+ # Array#reverse always returns self.
+ #assert_nil(@cls[].reverse!)
+ assert_equal @cls[], @cls[].reverse!
+ end
+
+ def test_reverse_each
+ a = @cls[*%w( dog cat bee ant )]
+ i = a.length
+ a.reverse_each { |e|
+ i -= 1
+ assert_equal(a[i], e)
+ }
+ assert_equal(0, i)
+
+ a = @cls[]
+ i = 0
+ a.reverse_each { |e|
+ assert(false, "Never get here")
+ }
+ assert_equal(0, i)
+ end
+
+ def test_rindex
+ a = @cls[ 'cat', 99, /a/, 99, [ 1, 2, 3] ]
+ assert_equal(0, a.rindex('cat'))
+ assert_equal(3, a.rindex(99))
+ assert_equal(4, a.rindex([1,2,3]))
+ assert_nil(a.rindex('ca'))
+ assert_nil(a.rindex([1,2]))
+
+ assert_equal(3, a.rindex(99) {|x| x == [1,2,3] })
+ end
+
+ def test_shift
+ a = @cls[ 'cat', 'dog' ]
+ assert_equal('cat', a.shift)
+ assert_equal(@cls['dog'], a)
+ assert_equal('dog', a.shift)
+ assert_equal(@cls[], a)
+ assert_nil(a.shift)
+ assert_equal(@cls[], a)
+ end
+
+ def test_size
+ assert_equal(0, @cls[].size)
+ assert_equal(1, @cls[1].size)
+ assert_equal(100, @cls[*(0..99).to_a].size)
+ end
+
+ def test_slice
+ a = @cls[*(1..100).to_a]
+
+ assert_equal(1, a.slice(0))
+ assert_equal(100, a.slice(99))
+ assert_nil(a.slice(100))
+ assert_equal(100, a.slice(-1))
+ assert_equal(99, a.slice(-2))
+ assert_equal(1, a.slice(-100))
+ assert_nil(a.slice(-101))
+
+ assert_equal(@cls[1], a.slice(0,1))
+ assert_equal(@cls[100], a.slice(99,1))
+ assert_equal(@cls[], a.slice(100,1))
+ assert_equal(@cls[100], a.slice(99,100))
+ assert_equal(@cls[100], a.slice(-1,1))
+ assert_equal(@cls[99], a.slice(-2,1))
+
+ assert_equal(@cls[10, 11, 12], a.slice(9, 3))
+ assert_equal(@cls[10, 11, 12], a.slice(-91, 3))
+
+ assert_nil(a.slice(-101, 2))
+
+ assert_equal(@cls[1], a.slice(0..0))
+ assert_equal(@cls[100], a.slice(99..99))
+ assert_equal(@cls[], a.slice(100..100))
+ assert_equal(@cls[100], a.slice(99..200))
+ assert_equal(@cls[100], a.slice(-1..-1))
+ assert_equal(@cls[99], a.slice(-2..-2))
+
+ assert_equal(@cls[10, 11, 12], a.slice(9..11))
+ assert_equal(@cls[10, 11, 12], a.slice(-91..-89))
+
+ assert_nil(a.slice(-101..-1))
+
+ assert_nil(a.slice(10, -3))
+ # Ruby 1.8 feature change:
+ # Array#slice[size..x] always returns [].
+ #assert_nil(a.slice(10..7))
+ assert_equal @cls[], a.slice(10..7)
+ end
+
+ def test_slice!
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(3, a.slice!(2))
+ assert_equal(@cls[1, 2, 4, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(4, a.slice!(-2))
+ assert_equal(@cls[1, 2, 3, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(@cls[3,4], a.slice!(2,2))
+ assert_equal(@cls[1, 2, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(@cls[4,5], a.slice!(-2,2))
+ assert_equal(@cls[1, 2, 3], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(@cls[3,4], a.slice!(2..3))
+ assert_equal(@cls[1, 2, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(nil, a.slice!(20))
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(nil, a.slice!(-6))
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(nil, a.slice!(-6..4))
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(nil, a.slice!(-6,2))
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ assert_raise(ArgumentError) { @cls[1].slice! }
+ assert_raise(ArgumentError) { @cls[1].slice!(0, 0, 0) }
+ end
+
+ def test_sort
+ a = @cls[ 4, 1, 2, 3 ]
+ assert_equal(@cls[1, 2, 3, 4], a.sort)
+ assert_equal(@cls[4, 1, 2, 3], a)
+
+ assert_equal(@cls[4, 3, 2, 1], a.sort { |x, y| y <=> x} )
+ assert_equal(@cls[4, 1, 2, 3], a)
+
+ assert_equal(@cls[1, 2, 3, 4], a.sort { |x, y| (x - y) * (2**100) })
+
+ a.fill(1)
+ assert_equal(@cls[1, 1, 1, 1], a.sort)
+
+ assert_equal(@cls[], @cls[].sort)
+ end
+
+ def test_sort!
+ a = @cls[ 4, 1, 2, 3 ]
+ assert_equal(@cls[1, 2, 3, 4], a.sort!)
+ assert_equal(@cls[1, 2, 3, 4], a)
+
+ assert_equal(@cls[4, 3, 2, 1], a.sort! { |x, y| y <=> x} )
+ assert_equal(@cls[4, 3, 2, 1], a)
+
+ a.fill(1)
+ assert_equal(@cls[1, 1, 1, 1], a.sort!)
+
+ assert_equal(@cls[1], @cls[1].sort!)
+ assert_equal(@cls[], @cls[].sort!)
+
+ a = @cls[4, 3, 2, 1]
+ a.sort! {|m, n| a.replace([9, 8, 7, 6]); m <=> n }
+ assert_equal([1, 2, 3, 4], a)
+
+ a = @cls[4, 3, 2, 1]
+ a.sort! {|m, n| a.replace([9, 8, 7]); m <=> n }
+ assert_equal([1, 2, 3, 4], a)
+ end
+
+ def test_sort_with_callcc
+ respond_to?(:callcc, true) or require 'continuation'
+ n = 1000
+ cont = nil
+ ary = (1..100).to_a
+ begin
+ ary.sort! {|a,b|
+ callcc {|k| cont = k} unless cont
+ assert_equal(100, ary.size, '[ruby-core:16679]')
+ a <=> b
+ }
+ rescue => e
+ end
+ n -= 1
+ cont.call if 0 < n
+ assert_instance_of(RuntimeError, e, '[ruby-core:16679]')
+ assert_match(/reentered/, e.message, '[ruby-core:16679]')
+ end
+
+ def test_sort_with_replace
+ xary = (1..100).to_a
+ 100.times do
+ ary = (1..100).to_a
+ ary.sort! {|a,b| ary.replace(xary); a <=> b}
+ GC.start
+ assert_equal(xary, ary, '[ruby-dev:34732]')
+ end
+ end
+
+ def test_to_a
+ a = @cls[ 1, 2, 3 ]
+ a_id = a.__id__
+ assert_equal(a, a.to_a)
+ assert_equal(a_id, a.to_a.__id__)
+ end
+
+ def test_to_ary
+ a = [ 1, 2, 3 ]
+ b = @cls[*a]
+
+ a_id = a.__id__
+ assert_equal(a, b.to_ary)
+ if (@cls == Array)
+ assert_equal(a_id, a.to_ary.__id__)
+ end
+
+ o = Object.new
+ def o.to_ary
+ [4, 5]
+ end
+ assert_equal([1, 2, 3, 4, 5], a.concat(o))
+
+ o = Object.new
+ def o.to_ary
+ foo_bar()
+ end
+ assert_match(/foo_bar/, assert_raise(NoMethodError) {a.concat(o)}.message)
+ end
+
+ def test_to_s
+ $, = ""
+ a = @cls[]
+ assert_equal("[]", a.to_s)
+
+ $, = ""
+ a = @cls[1, 2]
+ assert_equal("[1, 2]", a.to_s)
+
+ $, = ""
+ a = @cls[1, 2, 3]
+ assert_equal("[1, 2, 3]", a.to_s)
+
+ $, = ":"
+ a = @cls[1, 2, 3]
+ assert_equal("[1, 2, 3]", a.to_s)
+ ensure
+ $, = nil
+ end
+
+ def test_uniq
+ a = []
+ b = a.uniq
+ assert_equal([], a)
+ assert_equal([], b)
+ assert_not_same(a, b)
+
+ a = [1]
+ b = a.uniq
+ assert_equal([1], a)
+ assert_equal([1], b)
+ assert_not_same(a, b)
+
+ a = [1,1]
+ b = a.uniq
+ assert_equal([1,1], a)
+ assert_equal([1], b)
+ assert_not_same(a, b)
+
+ a = [1,2]
+ b = a.uniq
+ assert_equal([1,2], a)
+ assert_equal([1,2], b)
+ assert_not_same(a, b)
+
+ a = @cls[ 1, 2, 3, 2, 1, 2, 3, 4, nil ]
+ b = a.dup
+ assert_equal(@cls[1, 2, 3, 4, nil], a.uniq)
+ assert_equal(b, a)
+
+ c = @cls["a:def", "a:xyz", "b:abc", "b:xyz", "c:jkl"]
+ d = c.dup
+ assert_equal(@cls[ "a:def", "b:abc", "c:jkl" ], c.uniq {|s| s[/^\w+/]})
+ assert_equal(d, c)
+
+ assert_equal(@cls[1, 2, 3], @cls[1, 2, 3].uniq)
+ end
+
+ def test_uniq_with_block
+ a = []
+ b = a.uniq {|v| v.even? }
+ assert_equal([], a)
+ assert_equal([], b)
+ assert_not_same(a, b)
+
+ a = [1]
+ b = a.uniq {|v| v.even? }
+ assert_equal([1], a)
+ assert_equal([1], b)
+ assert_not_same(a, b)
+
+ a = [1,3]
+ b = a.uniq {|v| v.even? }
+ assert_equal([1,3], a)
+ assert_equal([1], b)
+ assert_not_same(a, b)
+ end
+
+ def test_uniq!
+ a = []
+ b = a.uniq!
+ assert_equal(nil, b)
+
+ a = [1]
+ b = a.uniq!
+ assert_equal(nil, b)
+
+ a = [1,1]
+ b = a.uniq!
+ assert_equal([1], a)
+ assert_equal([1], b)
+ assert_same(a, b)
+
+ a = [1,2]
+ b = a.uniq!
+ assert_equal([1,2], a)
+ assert_equal(nil, b)
+
+ a = @cls[ 1, 2, 3, 2, 1, 2, 3, 4, nil ]
+ assert_equal(@cls[1, 2, 3, 4, nil], a.uniq!)
+ assert_equal(@cls[1, 2, 3, 4, nil], a)
+
+ c = @cls["a:def", "a:xyz", "b:abc", "b:xyz", "c:jkl"]
+ assert_equal(@cls[ "a:def", "b:abc", "c:jkl" ], c.uniq! {|s| s[/^\w+/]})
+ assert_equal(@cls[ "a:def", "b:abc", "c:jkl" ], c)
+
+ c = @cls["a:def", "b:abc", "c:jkl"]
+ assert_equal(nil, c.uniq! {|s| s[/^\w+/]})
+ assert_equal(@cls[ "a:def", "b:abc", "c:jkl" ], c)
+
+ assert_nil(@cls[1, 2, 3].uniq!)
+
+ f = a.dup.freeze
+ assert_raise(ArgumentError) { a.uniq!(1) }
+ assert_raise(ArgumentError) { f.uniq!(1) }
+ assert_raise(RuntimeError) { f.uniq! }
+ end
+
+ def test_uniq_bang_with_block
+ a = []
+ b = a.uniq! {|v| v.even? }
+ assert_equal(nil, b)
+
+ a = [1]
+ b = a.uniq! {|v| v.even? }
+ assert_equal(nil, b)
+
+ a = [1,3]
+ b = a.uniq! {|v| v.even? }
+ assert_equal([1], a)
+ assert_equal([1], b)
+ assert_same(a, b)
+
+ a = [1,2]
+ b = a.uniq! {|v| v.even? }
+ assert_equal([1,2], a)
+ assert_equal(nil, b)
+ end
+
+ def test_unshift
+ a = @cls[]
+ assert_equal(@cls['cat'], a.unshift('cat'))
+ assert_equal(@cls['dog', 'cat'], a.unshift('dog'))
+ assert_equal(@cls[nil, 'dog', 'cat'], a.unshift(nil))
+ assert_equal(@cls[@cls[1,2], nil, 'dog', 'cat'], a.unshift(@cls[1, 2]))
+ end
+
+ def test_OR # '|'
+ assert_equal(@cls[], @cls[] | @cls[])
+ assert_equal(@cls[1], @cls[1] | @cls[])
+ assert_equal(@cls[1], @cls[] | @cls[1])
+ assert_equal(@cls[1], @cls[1] | @cls[1])
+
+ assert_equal(@cls[1,2], @cls[1] | @cls[2])
+ assert_equal(@cls[1,2], @cls[1, 1] | @cls[2, 2])
+ assert_equal(@cls[1,2], @cls[1, 2] | @cls[1, 2])
+ end
+
+ def test_combination
+ assert_equal(@cls[[]], @cls[1,2,3,4].combination(0).to_a)
+ assert_equal(@cls[[1],[2],[3],[4]], @cls[1,2,3,4].combination(1).to_a)
+ assert_equal(@cls[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]], @cls[1,2,3,4].combination(2).to_a)
+ assert_equal(@cls[[1,2,3],[1,2,4],[1,3,4],[2,3,4]], @cls[1,2,3,4].combination(3).to_a)
+ assert_equal(@cls[[1,2,3,4]], @cls[1,2,3,4].combination(4).to_a)
+ assert_equal(@cls[], @cls[1,2,3,4].combination(5).to_a)
+ end
+
+ def test_product
+ assert_equal(@cls[[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]],
+ @cls[1,2,3].product([4,5]))
+ assert_equal(@cls[[1,1],[1,2],[2,1],[2,2]], @cls[1,2].product([1,2]))
+
+ assert_equal(@cls[[1,3,5],[1,3,6],[1,4,5],[1,4,6],
+ [2,3,5],[2,3,6],[2,4,5],[2,4,6]],
+ @cls[1,2].product([3,4],[5,6]))
+ assert_equal(@cls[[1],[2]], @cls[1,2].product)
+ assert_equal(@cls[], @cls[1,2].product([]))
+
+ bug3394 = '[ruby-dev:41540]'
+ acc = []
+ EnvUtil.under_gc_stress {[1,2].product([3,4,5],[6,8]){|array| acc << array}}
+ assert_equal([[1, 3, 6], [1, 3, 8], [1, 4, 6], [1, 4, 8], [1, 5, 6], [1, 5, 8],
+ [2, 3, 6], [2, 3, 8], [2, 4, 6], [2, 4, 8], [2, 5, 6], [2, 5, 8]],
+ acc, bug3394)
+
+ def (o = Object.new).to_ary; GC.start; [3,4] end
+ acc = [1,2].product(*[o]*10)
+ assert_equal([1,2].product([3,4], [3,4], [3,4], [3,4], [3,4], [3,4], [3,4], [3,4], [3,4], [3,4]),
+ acc)
+ end
+
+ def test_permutation
+ a = @cls[1,2,3]
+ assert_equal(@cls[[]], a.permutation(0).to_a)
+ assert_equal(@cls[[1],[2],[3]], a.permutation(1).to_a.sort)
+ assert_equal(@cls[[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]],
+ a.permutation(2).to_a.sort)
+ assert_equal(@cls[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]],
+ a.permutation(3).sort.to_a)
+ assert_equal(@cls[], a.permutation(4).to_a)
+ assert_equal(@cls[], a.permutation(-1).to_a)
+ assert_equal("abcde".each_char.to_a.permutation(5).sort,
+ "edcba".each_char.to_a.permutation(5).sort)
+ assert_equal(@cls[].permutation(0).to_a, @cls[[]])
+
+ a = @cls[1, 2, 3, 4]
+ b = @cls[]
+ a.permutation {|x| b << x; a.replace(@cls[9, 8, 7, 6]) }
+ assert_equal(@cls[9, 8, 7, 6], a)
+ assert_equal(@cls[1, 2, 3, 4].permutation.to_a, b)
+ end
+
+ def test_repeated_permutation
+ a = @cls[1,2]
+ assert_equal(@cls[[]], a.repeated_permutation(0).to_a)
+ assert_equal(@cls[[1],[2]], a.repeated_permutation(1).to_a.sort)
+ assert_equal(@cls[[1,1],[1,2],[2,1],[2,2]],
+ a.repeated_permutation(2).to_a.sort)
+ assert_equal(@cls[[1,1,1],[1,1,2],[1,2,1],[1,2,2],
+ [2,1,1],[2,1,2],[2,2,1],[2,2,2]],
+ a.repeated_permutation(3).to_a.sort)
+ assert_equal(@cls[], a.repeated_permutation(-1).to_a)
+ assert_equal("abcde".each_char.to_a.repeated_permutation(5).sort,
+ "edcba".each_char.to_a.repeated_permutation(5).sort)
+ assert_equal(@cls[].repeated_permutation(0).to_a, @cls[[]])
+ assert_equal(@cls[].repeated_permutation(1).to_a, @cls[])
+
+ a = @cls[1, 2, 3, 4]
+ b = @cls[]
+ a.repeated_permutation(4) {|x| b << x; a.replace(@cls[9, 8, 7, 6]) }
+ assert_equal(@cls[9, 8, 7, 6], a)
+ assert_equal(@cls[1, 2, 3, 4].repeated_permutation(4).to_a, b)
+ end
+
+ def test_repeated_combination
+ a = @cls[1,2,3]
+ assert_equal(@cls[[]], a.repeated_combination(0).to_a)
+ assert_equal(@cls[[1],[2],[3]], a.repeated_combination(1).to_a.sort)
+ assert_equal(@cls[[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]],
+ a.repeated_combination(2).to_a.sort)
+ assert_equal(@cls[[1,1,1],[1,1,2],[1,1,3],[1,2,2],[1,2,3],
+ [1,3,3],[2,2,2],[2,2,3],[2,3,3],[3,3,3]],
+ a.repeated_combination(3).to_a.sort)
+ assert_equal(@cls[[1,1,1,1],[1,1,1,2],[1,1,1,3],[1,1,2,2],[1,1,2,3],
+ [1,1,3,3],[1,2,2,2],[1,2,2,3],[1,2,3,3],[1,3,3,3],
+ [2,2,2,2],[2,2,2,3],[2,2,3,3],[2,3,3,3],[3,3,3,3]],
+ a.repeated_combination(4).to_a.sort)
+ assert_equal(@cls[], a.repeated_combination(-1).to_a)
+ assert_equal("abcde".each_char.to_a.repeated_combination(5).map{|a|a.sort}.sort,
+ "edcba".each_char.to_a.repeated_combination(5).map{|a|a.sort}.sort)
+ assert_equal(@cls[].repeated_combination(0).to_a, @cls[[]])
+ assert_equal(@cls[].repeated_combination(1).to_a, @cls[])
+
+ a = @cls[1, 2, 3, 4]
+ b = @cls[]
+ a.repeated_combination(4) {|x| b << x; a.replace(@cls[9, 8, 7, 6]) }
+ assert_equal(@cls[9, 8, 7, 6], a)
+ assert_equal(@cls[1, 2, 3, 4].repeated_combination(4).to_a, b)
+ end
+
+ def test_take
+ assert_equal([1,2,3], [1,2,3,4,5,0].take(3))
+ assert_raise(ArgumentError, '[ruby-dev:34123]') { [1,2].take(-1) }
+ assert_equal([1,2], [1,2].take(1000000000), '[ruby-dev:34123]')
+ end
+
+ def test_take_while
+ assert_equal([1,2], [1,2,3,4,5,0].take_while {|i| i < 3 })
+ end
+
+ def test_drop
+ assert_equal([4,5,0], [1,2,3,4,5,0].drop(3))
+ assert_raise(ArgumentError, '[ruby-dev:34123]') { [1,2].drop(-1) }
+ assert_equal([], [1,2].drop(1000000000), '[ruby-dev:34123]')
+ end
+
+ def test_drop_while
+ assert_equal([3,4,5,0], [1,2,3,4,5,0].drop_while {|i| i < 3 })
+ end
+
+ def test_modify_check
+ a = []
+ a.freeze
+ assert_raise(RuntimeError) { a.shift }
+ a = [1, 2]
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ a.shift
+ end.value
+ end
+ end
+
+ LONGP = [127, 63, 31, 15, 7].map {|x| 2**x-1 }.find do |x|
+ begin
+ [].first(x)
+ rescue ArgumentError
+ true
+ rescue RangeError
+ false
+ end
+ end
+
+ def test_ary_new
+ assert_raise(ArgumentError) { [].to_enum.first(-1) }
+ assert_raise(ArgumentError) { [].to_enum.first(LONGP) }
+ end
+
+ def test_try_convert
+ assert_equal([1], Array.try_convert([1]))
+ assert_equal(nil, Array.try_convert("1"))
+ end
+
+ def test_initialize
+ assert_nothing_raised { [].instance_eval { initialize } }
+ assert_nothing_raised { Array.new { } }
+ assert_equal([1, 2, 3], Array.new([1, 2, 3]))
+ assert_raise(ArgumentError) { Array.new(-1, 1) }
+ assert_raise(ArgumentError) { Array.new(LONGP, 1) }
+ assert_equal([1, 1, 1], Array.new(3, 1))
+ assert_equal([1, 1, 1], Array.new(3) { 1 })
+ assert_equal([1, 1, 1], Array.new(3, 1) { 1 })
+ end
+
+ def test_aset_error
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ assert_raise(IndexError) { [0][-2] = 1 }
+ assert_raise(IndexError) { [0][LONGP] = 2 }
+ assert_raise(IndexError) { [0][(LONGP + 1) / 2 - 1] = 2 }
+ assert_raise(IndexError) { [0][LONGP..-1] = 2 }
+ a = [0]
+ a[2] = 4
+ assert_equal([0, nil, 4], a)
+ assert_raise(ArgumentError) { [0][0, 0, 0] = 0 }
+ assert_raise(ArgumentError) { [0].freeze[0, 0, 0] = 0 }
+ assert_raise(TypeError) { [0][:foo] = 0 }
+ assert_raise(RuntimeError) { [0].freeze[:foo] = 0 }
+ end
+
+ def test_first2
+ assert_equal([0], [0].first(2))
+ assert_raise(ArgumentError) { [0].first(-1) }
+ end
+
+ def test_shift2
+ assert_equal(0, ([0] * 16).shift)
+ # check
+ a = [0, 1, 2]
+ a[3] = 3
+ a.shift(2)
+ assert_equal([2, 3], a)
+ end
+
+ def test_unshift_error
+ assert_raise(RuntimeError) { [].freeze.unshift('cat') }
+ assert_raise(RuntimeError) { [].freeze.unshift() }
+ end
+
+ def test_aref
+ assert_raise(ArgumentError) { [][0, 0, 0] }
+ end
+
+ def test_fetch
+ assert_equal(1, [].fetch(0, 0) { 1 })
+ assert_equal(1, [0, 1].fetch(-1))
+ assert_raise(IndexError) { [0, 1].fetch(2) }
+ assert_raise(IndexError) { [0, 1].fetch(-3) }
+ assert_equal(2, [0, 1].fetch(2, 2))
+ end
+
+ def test_index2
+ a = [0, 1, 2]
+ assert_equal(a, a.index.to_a)
+ assert_equal(1, a.index {|x| x == 1 })
+ end
+
+ def test_rindex2
+ a = [0, 1, 2]
+ assert_equal([2, 1, 0], a.rindex.to_a)
+ assert_equal(1, a.rindex {|x| x == 1 })
+
+ a = [0, 1]
+ e = a.rindex
+ assert_equal(1, e.next)
+ a.clear
+ assert_raise(StopIteration) { e.next }
+
+ o = Object.new
+ class << o; self; end.class_eval do
+ define_method(:==) {|x| a.clear; false }
+ end
+ a = [nil, o]
+ assert_equal(nil, a.rindex(0))
+ end
+
+ def test_ary_to_ary
+ o = Object.new
+ def o.to_ary; [1, 2, 3]; end
+ a, b, c = o
+ assert_equal([1, 2, 3], [a, b, c])
+ end
+
+ def test_splice
+ a = [0]
+ assert_raise(IndexError) { a[-2, 0] = nil }
+ end
+
+ def test_insert
+ a = [0]
+ assert_equal([0], a.insert(1))
+ assert_equal([0, 1], a.insert(1, 1))
+ assert_raise(ArgumentError) { a.insert }
+ assert_equal([0, 1, 2], a.insert(-1, 2))
+ assert_equal([0, 1, 3, 2], a.insert(-2, 3))
+ assert_raise(RuntimeError) { [0].freeze.insert(0)}
+ assert_raise(ArgumentError) { [0].freeze.insert }
+ end
+
+ def test_join2
+ a = []
+ a << a
+ assert_raise(ArgumentError){a.join}
+
+ def (a = Object.new).to_ary
+ [self]
+ end
+ assert_raise(ArgumentError, '[ruby-core:24150]'){[a].join}
+ assert_equal("12345", [1,[2,[3,4],5]].join)
+ end
+
+ def test_to_a2
+ klass = Class.new(Array)
+ a = klass.new.to_a
+ assert_equal([], a)
+ assert_equal(Array, a.class)
+ end
+
+ def test_values_at2
+ a = [0, 1, 2, 3, 4, 5]
+ assert_equal([1, 2, 3], a.values_at(1..3))
+ assert_equal([], a.values_at(7..8))
+ assert_equal([nil], a.values_at(2**31-1))
+ end
+
+ def test_select
+ assert_equal([0, 2], [0, 1, 2, 3].select {|x| x % 2 == 0 })
+ end
+
+ # also keep_if
+ def test_select!
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(nil, a.select! { true })
+ assert_equal(a, a.keep_if { true })
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(a, a.select! { false })
+ assert_equal(@cls[], a)
+
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(a, a.select! { |i| i > 3 })
+ assert_equal(@cls[4, 5], a)
+ end
+
+ def test_delete2
+ a = [0] * 1024 + [1] + [0] * 1024
+ a.delete(0)
+ assert_equal([1], a)
+ end
+
+ def test_reject
+ assert_equal([1, 3], [0, 1, 2, 3].reject {|x| x % 2 == 0 })
+ end
+
+ def test_zip
+ assert_equal([[1, :a, "a"], [2, :b, "b"], [3, nil, "c"]],
+ [1, 2, 3].zip([:a, :b], ["a", "b", "c", "d"]))
+ a = []
+ [1, 2, 3].zip([:a, :b], ["a", "b", "c", "d"]) {|x| a << x }
+ assert_equal([[1, :a, "a"], [2, :b, "b"], [3, nil, "c"]], a)
+
+ ary = Object.new
+ def ary.to_a; [1, 2]; end
+ assert_raise(NoMethodError){ %w(a b).zip(ary) }
+ def ary.each; [3, 4].each{|e|yield e}; end
+ assert_equal([['a', 3], ['b', 4]], %w(a b).zip(ary))
+ def ary.to_ary; [5, 6]; end
+ assert_equal([['a', 5], ['b', 6]], %w(a b).zip(ary))
+ end
+
+ def test_transpose
+ assert_equal([[1, :a], [2, :b], [3, :c]],
+ [[1, 2, 3], [:a, :b, :c]].transpose)
+ assert_raise(IndexError) { [[1, 2, 3], [:a, :b]].transpose }
+ end
+
+ def test_clear2
+ assert_equal([], ([0] * 1024).clear)
+ end
+
+ def test_fill2
+ assert_raise(ArgumentError) { [].fill(0, 1, LONGP) }
+ end
+
+ def test_times
+ assert_raise(ArgumentError) { [0, 0, 0, 0] * ((LONGP + 1) / 4) }
+ end
+
+ def test_equal
+ o = Object.new
+ def o.to_ary; end
+ def o.==(x); :foo; end
+ assert_equal([0, 1, 2], o)
+ assert_not_equal([0, 1, 2], [0, 1, 3])
+ end
+
+ def test_hash2
+ a = []
+ a << a
+ assert_equal([[a]].hash, a.hash)
+ assert_not_equal([a, a].hash, a.hash) # Implementation dependent
+ end
+
+ def test_flatten_error
+ a = []
+ a << a
+ assert_raise(ArgumentError) { a.flatten }
+
+ f = [].freeze
+ assert_raise(ArgumentError) { a.flatten!(1, 2) }
+ assert_raise(TypeError) { a.flatten!(:foo) }
+ assert_raise(ArgumentError) { f.flatten!(1, 2) }
+ assert_raise(RuntimeError) { f.flatten! }
+ assert_raise(RuntimeError) { f.flatten!(:foo) }
+ end
+
+ def test_shuffle
+ 100.times do
+ assert_equal([0, 1, 2], [2, 1, 0].shuffle.sort)
+ end
+ end
+
+ def test_sample
+ 100.times do
+ assert([0, 1, 2].include?([2, 1, 0].sample))
+ samples = [2, 1, 0].sample(2)
+ samples.each{|sample|
+ assert([0, 1, 2].include?(sample))
+ }
+ end
+
+ srand(0)
+ a = (1..18).to_a
+ (0..20).each do |n|
+ 100.times do
+ b = a.sample(n)
+ assert_equal([n, 18].min, b.uniq.size)
+ assert_equal(a, (a | b).sort)
+ assert_equal(b.sort, (a & b).sort)
+ end
+
+ h = Hash.new(0)
+ 1000.times do
+ a.sample(n).each {|x| h[x] += 1 }
+ end
+ assert_operator(h.values.min * 2, :>=, h.values.max) if n != 0
+ end
+
+ assert_raise(ArgumentError, '[ruby-core:23374]') {[1, 2].sample(-1)}
+ end
+
+ def test_cycle
+ a = []
+ [0, 1, 2].cycle do |i|
+ a << i
+ break if a.size == 10
+ end
+ assert_equal([0, 1, 2, 0, 1, 2, 0, 1, 2, 0], a)
+
+ a = [0, 1, 2]
+ assert_nil(a.cycle { a.clear })
+
+ a = []
+ [0, 1, 2].cycle(3) {|i| a << i }
+ assert_equal([0, 1, 2, 0, 1, 2, 0, 1, 2], a)
+ end
+
+ def test_reverse_each2
+ a = [0, 1, 2, 3, 4, 5]
+ r = []
+ a.reverse_each do |x|
+ r << x
+ a.pop
+ a.pop
+ end
+ assert_equal([5, 3, 1], r)
+ end
+
+ def test_combination2
+ assert_nothing_raised do
+ (0..100).to_a.combination(50) { break }
+ end
+ end
+
+ def test_product2
+ a = (0..100).to_a
+ assert_raise(RangeError) do
+ a.product(a, a, a, a, a, a, a, a, a, a)
+ end
+ assert_nothing_raised(RangeError) do
+ a.product(a, a, a, a, a, a, a, a, a, a) { break }
+ end
+ end
+
+ class Array2 < Array
+ end
+
+ def test_array_subclass
+ assert_equal(Array2, Array2[1,2,3].uniq.class, "[ruby-dev:34581]")
+ assert_equal(Array2, Array2[1,2][0,1].class) # embeded
+ assert_equal(Array2, Array2[*(1..100)][1..99].class) #not embeded
+ end
+
+ def test_inspect
+ a = @cls[1, 2, 3]
+ a.taint
+ a.untrust
+ s = a.inspect
+ assert_equal(true, s.tainted?)
+ assert_equal(true, s.untrusted?)
+ end
+
+ def test_initialize2
+ a = [1] * 1000
+ a.instance_eval { initialize }
+ assert_equal([], a)
+ end
+
+ def test_shift_shared_ary
+ a = (1..100).to_a
+ b = []
+ b.replace(a)
+ assert_equal((1..10).to_a, a.shift(10))
+ assert_equal((11..100).to_a, a)
+ end
+
+ def test_replace_shared_ary
+ a = [1] * 100
+ b = []
+ b.replace(a)
+ a.replace([1, 2, 3])
+ assert_equal([1, 2, 3], a)
+ assert_equal([1] * 100, b)
+ end
+
+ def test_fill_negative_length
+ a = (1..10).to_a
+ a.fill(:foo, 5, -3)
+ assert_equal((1..10).to_a, a)
+ end
+
+ def test_slice_frozen_array
+ a = [1,2,3,4,5].freeze
+ assert_equal([1,2,3,4], a[0,4])
+ assert_equal([2,3,4,5], a[1,4])
+ end
+
+ def test_sort_by!
+ a = [1,3,5,2,4]
+ a.sort_by! {|x| -x }
+ assert_equal([5,4,3,2,1], a)
+ end
+
+ def test_rotate
+ a = [1,2,3,4,5].freeze
+ assert_equal([2,3,4,5,1], a.rotate)
+ assert_equal([5,1,2,3,4], a.rotate(-1))
+ assert_equal([3,4,5,1,2], a.rotate(2))
+ assert_equal([4,5,1,2,3], a.rotate(-2))
+ assert_equal([4,5,1,2,3], a.rotate(13))
+ assert_equal([3,4,5,1,2], a.rotate(-13))
+ a = [1].freeze
+ assert_equal([1], a.rotate)
+ assert_equal([1], a.rotate(2))
+ assert_equal([1], a.rotate(-4))
+ assert_equal([1], a.rotate(13))
+ assert_equal([1], a.rotate(-13))
+ a = [].freeze
+ assert_equal([], a.rotate)
+ assert_equal([], a.rotate(2))
+ assert_equal([], a.rotate(-4))
+ assert_equal([], a.rotate(13))
+ assert_equal([], a.rotate(-13))
+ a = [1,2,3]
+ assert_raise(ArgumentError) { a.rotate(1, 1) }
+ end
+
+ def test_rotate!
+ a = [1,2,3,4,5]
+ assert_equal([2,3,4,5,1], a.rotate!)
+ assert_equal([2,3,4,5,1], a)
+ assert_equal([4,5,1,2,3], a.rotate!(2))
+ assert_equal([5,1,2,3,4], a.rotate!(-4))
+ assert_equal([3,4,5,1,2], a.rotate!(13))
+ assert_equal([5,1,2,3,4], a.rotate!(-13))
+ a = [1]
+ assert_equal([1], a.rotate!)
+ assert_equal([1], a.rotate!(2))
+ assert_equal([1], a.rotate!(-4))
+ assert_equal([1], a.rotate!(13))
+ assert_equal([1], a.rotate!(-13))
+ a = []
+ assert_equal([], a.rotate!)
+ assert_equal([], a.rotate!(2))
+ assert_equal([], a.rotate!(-4))
+ assert_equal([], a.rotate!(13))
+ assert_equal([], a.rotate!(-13))
+ a = [].freeze
+ e = assert_raise(RuntimeError) {a.rotate!}
+ assert_match(/can't modify frozen array/, e.message)
+ a = [1,2,3]
+ assert_raise(ArgumentError) { a.rotate!(1, 1) }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_assignment.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_assignment.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_assignment.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,695 @@
+require 'test/unit'
+
+class TestAssignment < Test::Unit::TestCase
+ def test_assign
+ a=[]; a[0] ||= "bar";
+ assert_equal("bar", a[0])
+ h={}; h["foo"] ||= "bar";
+ assert_equal("bar", h["foo"])
+
+ aa = 5
+ aa ||= 25
+ assert_equal(5, aa)
+ bb ||= 25
+ assert_equal(25, bb)
+ cc &&=33
+ assert_nil(cc)
+ cc = 5
+ cc &&=44
+ assert_equal(44, cc)
+
+ a = nil; assert_nil(a)
+ a = 1; assert_equal(1, a)
+ a = []; assert_equal([], a)
+ a = [1]; assert_equal([1], a)
+ a = [nil]; assert_equal([nil], a)
+ a = [[]]; assert_equal([[]], a)
+ a = [1,2]; assert_equal([1,2], a)
+ a = [*[]]; assert_equal([], a)
+ a = [*[1]]; assert_equal([1], a)
+ a = [*[1,2]]; assert_equal([1,2], a)
+
+ a = *[]; assert_equal([], a)
+ a = *[1]; assert_equal([1], a)
+ a = *[nil]; assert_equal([nil], a)
+ a = *[[]]; assert_equal([[]], a)
+ a = *[1,2]; assert_equal([1,2], a)
+ a = *[*[]]; assert_equal([], a)
+ a = *[*[1]]; assert_equal([1], a)
+ a = *[*[1,2]]; assert_equal([1,2], a)
+
+ *a = nil; assert_equal([nil], a)
+ *a = 1; assert_equal([1], a)
+ *a = []; assert_equal([], a)
+ *a = [1]; assert_equal([1], a)
+ *a = [nil]; assert_equal([nil], a)
+ *a = [[]]; assert_equal([[]], a)
+ *a = [1,2]; assert_equal([1,2], a)
+ *a = [*[]]; assert_equal([], a)
+ *a = [*[1]]; assert_equal([1], a)
+ *a = [*[1,2]]; assert_equal([1,2], a)
+
+ *a = *[]; assert_equal([], a)
+ *a = *[1]; assert_equal([1], a)
+ *a = *[nil]; assert_equal([nil], a)
+ *a = *[[]]; assert_equal([[]], a)
+ *a = *[1,2]; assert_equal([1,2], a)
+ *a = *[*[]]; assert_equal([], a)
+ *a = *[*[1]]; assert_equal([1], a)
+ *a = *[*[1,2]]; assert_equal([1,2], a)
+
+ a,b,*c = nil; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = 1; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = []; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = [1]; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = [nil]; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = [[]]; assert_equal([[],nil,[]], [a,b,c])
+ a,b,*c = [1,2]; assert_equal([1,2,[]], [a,b,c])
+ a,b,*c = [*[]]; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = [*[1]]; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = [*[1,2]]; assert_equal([1,2,[]], [a,b,c])
+
+ a,b,*c = *[]; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = *[1]; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = *[nil]; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = *[[]]; assert_equal([[],nil,[]], [a,b,c])
+ a,b,*c = *[1,2]; assert_equal([1,2,[]], [a,b,c])
+ a,b,*c = *[*[]]; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = *[*[1]]; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = *[*[1,2]]; assert_equal([1,2,[]], [a,b,c])
+
+ bug2050 = '[ruby-core:25629]'
+ a = Hash.new {[]}
+ b = [1, 2]
+ assert_equal([1, 2, 3], a[:x] += [*b, 3], bug2050)
+ assert_equal([1, 2, 3], a[:x], bug2050)
+ assert_equal([1, 2, 3, [1, 2, 3]], a[:x] <<= [*b, 3], bug2050)
+ assert_equal([1, 2, 3, [1, 2, 3]], a[:x], bug2050)
+ end
+
+ def test_yield
+ def f; yield(nil); end; f {|a| assert_nil(a)}; undef f
+ def f; yield(1); end; f {|a| assert_equal(1, a)}; undef f
+ def f; yield([]); end; f {|a| assert_equal([], a)}; undef f
+ def f; yield([1]); end; f {|a| assert_equal([1], a)}; undef f
+ def f; yield([nil]); end; f {|a| assert_equal([nil], a)}; undef f
+ def f; yield([[]]); end; f {|a| assert_equal([[]], a)}; undef f
+ def f; yield([*[]]); end; f {|a| assert_equal([], a)}; undef f
+ def f; yield([*[1]]); end; f {|a| assert_equal([1], a)}; undef f
+ def f; yield([*[1,2]]); end; f {|a| assert_equal([1,2], a)}; undef f
+
+ def f; yield(*[1]); end; f {|a| assert_equal(1, a)}; undef f
+ def f; yield(*[nil]); end; f {|a| assert_equal(nil, a)}; undef f
+ def f; yield(*[[]]); end; f {|a| assert_equal([], a)}; undef f
+ def f; yield(*[*[1]]); end; f {|a| assert_equal(1, a)}; undef f
+
+ def f; yield; end; f {|*a| assert_equal([], a)}; undef f
+ def f; yield(nil); end; f {|*a| assert_equal([nil], a)}; undef f
+ def f; yield(1); end; f {|*a| assert_equal([1], a)}; undef f
+ def f; yield([]); end; f {|*a| assert_equal([[]], a)}; undef f
+ def f; yield([1]); end; f {|*a| assert_equal([[1]], a)}; undef f
+ def f; yield([nil]); end; f {|*a| assert_equal([[nil]], a)}; undef f
+ def f; yield([[]]); end; f {|*a| assert_equal([[[]]], a)}; undef f
+ def f; yield([1,2]); end; f {|*a| assert_equal([[1,2]], a)}; undef f
+ def f; yield([*[]]); end; f {|*a| assert_equal([[]], a)}; undef f
+ def f; yield([*[1]]); end; f {|*a| assert_equal([[1]], a)}; undef f
+ def f; yield([*[1,2]]); end; f {|*a| assert_equal([[1,2]], a)}; undef f
+
+ def f; yield(*[]); end; f {|*a| assert_equal([], a)}; undef f
+ def f; yield(*[1]); end; f {|*a| assert_equal([1], a)}; undef f
+ def f; yield(*[nil]); end; f {|*a| assert_equal([nil], a)}; undef f
+ def f; yield(*[[]]); end; f {|*a| assert_equal([[]], a)}; undef f
+ def f; yield(*[*[]]); end; f {|*a| assert_equal([], a)}; undef f
+ def f; yield(*[*[1]]); end; f {|*a| assert_equal([1], a)}; undef f
+ def f; yield(*[*[1,2]]); end; f {|*a| assert_equal([1,2], a)}; undef f
+
+ def f; yield; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield(nil); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield(1); end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}; undef f
+ def f; yield([]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield([1]); end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}; undef f
+ def f; yield([nil]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield([[]]); end; f {|a,b,*c| assert_equal([[],nil,[]], [a,b,c])}; undef f
+ def f; yield([*[]]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield([*[1]]); end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}; undef f
+ def f; yield([*[1,2]]); end; f {|a,b,*c| assert_equal([1,2,[]], [a,b,c])}; undef f
+
+ def f; yield(*[]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield(*[1]); end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}; undef f
+ def f; yield(*[nil]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield(*[[]]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield(*[*[]]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield(*[*[1]]); end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}; undef f
+ def f; yield(*[*[1,2]]); end; f {|a,b,*c| assert_equal([1,2,[]], [a,b,c])}; undef f
+ end
+
+ def test_return
+ def r; return; end; a = r(); assert_nil(a); undef r
+ def r; return nil; end; a = r(); assert_nil(a); undef r
+ def r; return 1; end; a = r(); assert_equal(1, a); undef r
+ def r; return []; end; a = r(); assert_equal([], a); undef r
+ def r; return [1]; end; a = r(); assert_equal([1], a); undef r
+ def r; return [nil]; end; a = r(); assert_equal([nil], a); undef r
+ def r; return [[]]; end; a = r(); assert_equal([[]], a); undef r
+ def r; return [*[]]; end; a = r(); assert_equal([], a); undef r
+ def r; return [*[1]]; end; a = r(); assert_equal([1], a); undef r
+ def r; return [*[1,2]]; end; a = r(); assert_equal([1,2], a); undef r
+
+ def r; return *[]; end; a = r(); assert_equal([], a); undef r
+ def r; return *[1]; end; a = r(); assert_equal([1], a); undef r
+ def r; return *[nil]; end; a = r(); assert_equal([nil], a); undef r
+ def r; return *[[]]; end; a = r(); assert_equal([[]], a); undef r
+ def r; return *[*[]]; end; a = r(); assert_equal([], a); undef r
+ def r; return *[*[1]]; end; a = r(); assert_equal([1], a); undef r
+ def r; return *[*[1,2]]; end; a = r(); assert_equal([1,2], a); undef r
+
+ def r; return *[[]]; end; a = *r(); assert_equal([[]], a); undef r
+ def r; return *[*[1,2]]; end; a = *r(); assert_equal([1,2], a); undef r
+
+ def r; return; end; *a = r(); assert_equal([nil], a); undef r
+ def r; return nil; end; *a = r(); assert_equal([nil], a); undef r
+ def r; return 1; end; *a = r(); assert_equal([1], a); undef r
+ def r; return []; end; *a = r(); assert_equal([], a); undef r
+ def r; return [1]; end; *a = r(); assert_equal([1], a); undef r
+ def r; return [nil]; end; *a = r(); assert_equal([nil], a); undef r
+ def r; return [[]]; end; *a = r(); assert_equal([[]], a); undef r
+ def r; return [1,2]; end; *a = r(); assert_equal([1,2], a); undef r
+ def r; return [*[]]; end; *a = r(); assert_equal([], a); undef r
+ def r; return [*[1]]; end; *a = r(); assert_equal([1], a); undef r
+ def r; return [*[1,2]]; end; *a = r(); assert_equal([1,2], a); undef r
+
+ def r; return *[]; end; *a = r(); assert_equal([], a); undef r
+ def r; return *[1]; end; *a = r(); assert_equal([1], a); undef r
+ def r; return *[nil]; end; *a = r(); assert_equal([nil], a); undef r
+ def r; return *[[]]; end; *a = r(); assert_equal([[]], a); undef r
+ def r; return *[1,2]; end; *a = r(); assert_equal([1,2], a); undef r
+ def r; return *[*[]]; end; *a = r(); assert_equal([], a); undef r
+ def r; return *[*[1]]; end; *a = r(); assert_equal([1], a); undef r
+ def r; return *[*[1,2]]; end; *a = r(); assert_equal([1,2], a); undef r
+
+ def r; return *[[]]; end; *a = *r(); assert_equal([[]], a); undef r
+ def r; return *[1,2]; end; *a = *r(); assert_equal([1,2], a); undef r
+ def r; return *[*[1,2]]; end; *a = *r(); assert_equal([1,2], a); undef r
+
+ def r; return; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return nil; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return 1; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c]); undef r
+ def r; return []; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return [1]; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c]); undef r
+ def r; return [nil]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return [[]]; end; a,b,*c = r(); assert_equal([[],nil,[]], [a,b,c]); undef r
+ def r; return [1,2]; end; a,b,*c = r(); assert_equal([1,2,[]], [a,b,c]); undef r
+ def r; return [*[]]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return [*[1]]; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c]); undef r
+ def r; return [*[1,2]]; end; a,b,*c = r(); assert_equal([1,2,[]], [a,b,c]); undef r
+
+ def r; return *[]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return *[1]; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c]); undef r
+ def r; return *[nil]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return *[[]]; end; a,b,*c = r(); assert_equal([[],nil,[]], [a,b,c]); undef r
+ def r; return *[1,2]; end; a,b,*c = r(); assert_equal([1,2,[]], [a,b,c]); undef r
+ def r; return *[*[]]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return *[*[1]]; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c]); undef r
+ def r; return *[*[1,2]]; end; a,b,*c = r(); assert_equal([1,2,[]], [a,b,c]); undef r
+
+ def r; return 1, *[]; end; a,b = r(); assert_equal([1,nil], [a,b]); undef r
+ def r; return 1,2,*[1]; end; a,b = r(); assert_equal([1,2], [a,b]); undef r
+ def r; return 1,2,3,*[1,2]; end; a,b = r(); assert_equal([1,2], [a,b]); undef r
+ end
+
+ def test_lambda
+ f = lambda {|r,| assert_equal([], r)}
+ f.call([], *[])
+
+ f = lambda {|r,*l| assert_equal([], r); assert_equal([1], l)}
+ f.call([], *[1])
+
+ f = lambda{|x| x}
+ assert_equal(42, f.call(42))
+ assert_equal([42], f.call([42]))
+ assert_equal([[42]], f.call([[42]]))
+ assert_equal([42,55], f.call([42,55]))
+
+ f = lambda{|x,| x}
+ assert_equal(42, f.call(42))
+ assert_equal([42], f.call([42]))
+ assert_equal([[42]], f.call([[42]]))
+ assert_equal([42,55], f.call([42,55]))
+
+ f = lambda{|*x| x}
+ assert_equal([42], f.call(42))
+ assert_equal([[42]], f.call([42]))
+ assert_equal([[[42]]], f.call([[42]]))
+ assert_equal([[42,55]], f.call([42,55]))
+ assert_equal([42,55], f.call(42,55))
+ end
+
+ def test_multi
+ a,=*[1]
+ assert_equal(1, a)
+ a,=*[[1]]
+ assert_equal([1], a)
+ a,=*[[[1]]]
+ assert_equal([[1]], a)
+
+ x, (y, z) = 1, 2, 3
+ assert_equal([1,2,nil], [x,y,z])
+ x, (y, z) = 1, [2,3]
+ assert_equal([1,2,3], [x,y,z])
+ x, (y, z) = 1, [2]
+ assert_equal([1,2,nil], [x,y,z])
+ end
+
+ def test_break
+ a = loop do break; end; assert_nil(a)
+ a = loop do break nil; end; assert_nil(a)
+ a = loop do break 1; end; assert_equal(1, a)
+ a = loop do break []; end; assert_equal([], a)
+ a = loop do break [1]; end; assert_equal([1], a)
+ a = loop do break [nil]; end; assert_equal([nil], a)
+ a = loop do break [[]]; end; assert_equal([[]], a)
+ a = loop do break [*[]]; end; assert_equal([], a)
+ a = loop do break [*[1]]; end; assert_equal([1], a)
+ a = loop do break [*[1,2]]; end; assert_equal([1,2], a)
+
+ a = loop do break *[]; end; assert_equal([], a)
+ a = loop do break *[1]; end; assert_equal([1], a)
+ a = loop do break *[nil]; end; assert_equal([nil], a)
+ a = loop do break *[[]]; end; assert_equal([[]], a)
+ a = loop do break *[*[]]; end; assert_equal([], a)
+ a = loop do break *[*[1]]; end; assert_equal([1], a)
+ a = loop do break *[*[1,2]]; end; assert_equal([1,2], a)
+
+ *a = loop do break; end; assert_equal([nil], a)
+ *a = loop do break nil; end; assert_equal([nil], a)
+ *a = loop do break 1; end; assert_equal([1], a)
+ *a = loop do break []; end; assert_equal([], a)
+ *a = loop do break [1]; end; assert_equal([1], a)
+ *a = loop do break [nil]; end; assert_equal([nil], a)
+ *a = loop do break [[]]; end; assert_equal([[]], a)
+ *a = loop do break [1,2]; end; assert_equal([1,2], a)
+ *a = loop do break [*[]]; end; assert_equal([], a)
+ *a = loop do break [*[1]]; end; assert_equal([1], a)
+ *a = loop do break [*[1,2]]; end; assert_equal([1,2], a)
+
+ *a = loop do break *[]; end; assert_equal([], a)
+ *a = loop do break *[1]; end; assert_equal([1], a)
+ *a = loop do break *[nil]; end; assert_equal([nil], a)
+ *a = loop do break *[[]]; end; assert_equal([[]], a)
+ *a = loop do break *[1,2]; end; assert_equal([1,2], a)
+ *a = loop do break *[*[]]; end; assert_equal([], a)
+ *a = loop do break *[*[1]]; end; assert_equal([1], a)
+ *a = loop do break *[*[1,2]]; end; assert_equal([1,2], a)
+
+ *a = *loop do break *[[]]; end; assert_equal([[]], a)
+ *a = *loop do break *[1,2]; end; assert_equal([1,2], a)
+ *a = *loop do break *[*[1,2]]; end; assert_equal([1,2], a)
+
+ a,b,*c = loop do break; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break nil; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break 1; end; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = loop do break []; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break [1]; end; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = loop do break [nil]; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break [[]]; end; assert_equal([[],nil,[]], [a,b,c])
+ a,b,*c = loop do break [1,2]; end; assert_equal([1,2,[]], [a,b,c])
+ a,b,*c = loop do break [*[]]; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break [*[1]]; end; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = loop do break [*[1,2]]; end; assert_equal([1,2,[]], [a,b,c])
+
+ a,b,*c = loop do break *[]; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break *[1]; end; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = loop do break *[nil]; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break *[[]]; end; assert_equal([[],nil,[]], [a,b,c])
+ a,b,*c = loop do break *[1,2]; end; assert_equal([1,2,[]], [a,b,c])
+ a,b,*c = loop do break *[*[]]; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break *[*[1]]; end; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = loop do break *[*[1,2]]; end; assert_equal([1,2,[]], [a,b,c])
+ end
+
+ def test_next
+ def r(val); a = yield(); assert_equal(val, a); end
+ r(nil){next}
+ r(nil){next nil}
+ r(1){next 1}
+ r([]){next []}
+ r([1]){next [1]}
+ r([nil]){next [nil]}
+ r([[]]){next [[]]}
+ r([]){next [*[]]}
+ r([1]){next [*[1]]}
+ r([1,2]){next [*[1,2]]}
+
+ r([]){next *[]}
+ r([1]){next *[1]}
+ r([nil]){next *[nil]}
+ r([[]]){next *[[]]}
+ r([]){next *[*[]]}
+ r([1]){next *[*[1]]}
+ r([1,2]){next *[*[1,2]]}
+ undef r
+
+ def r(val); *a = yield(); assert_equal(val, a); end
+ r([nil]){next}
+ r([nil]){next nil}
+ r([1]){next 1}
+ r([]){next []}
+ r([1]){next [1]}
+ r([nil]){next [nil]}
+ r([[]]){next [[]]}
+ r([1,2]){next [1,2]}
+ r([]){next [*[]]}
+ r([1]){next [*[1]]}
+ r([1,2]){next [*[1,2]]}
+ undef r
+
+ def r(val); *a = *yield(); assert_equal(val, a); end
+ r([[]]){next *[[]]}
+ r([1,2]){next *[1,2]}
+ r([1,2]){next *[*[1,2]]}
+ undef r
+
+ def r(val); a,b,*c = yield(); assert_equal(val, [a,b,c]); end
+ r([nil,nil,[]]){next}
+ r([nil,nil,[]]){next nil}
+ r([1,nil,[]]){next 1}
+ r([nil,nil,[]]){next []}
+ r([1,nil,[]]){next [1]}
+ r([nil,nil,[]]){next [nil]}
+ r([[],nil,[]]){next [[]]}
+ r([1,2,[]]){next [1,2]}
+ r([nil,nil,[]]){next [*[]]}
+ r([1,nil,[]]){next [*[1]]}
+ r([1,2,[]]){next [*[1,2]]}
+ undef r
+
+ def r(val); a,b,*c = *yield(); assert_equal(val, [a,b,c]); end
+ r([[],nil,[]]){next *[[]]}
+ r([1,2,[]]){next *[1,2]}
+ r([1,2,[]]){next *[*[1,2]]}
+ undef r
+ end
+
+ def test_massign
+ a = nil
+ assert(defined?(a))
+ assert_nil(a)
+
+ # multiple asignment
+ a, b = 1, 2
+ assert_equal 1, a
+ assert_equal 2, b
+
+ a, b, c = 1, 2, 3
+ assert_equal 1, a
+ assert_equal 2, b
+ assert_equal 3, c
+
+ a = 1
+ b = 2
+ a, b = b, a
+ assert_equal 2, a
+ assert_equal 1, b
+
+ a, = 1, 2
+ assert_equal 1, a
+
+ a, = 1, 2, 3
+ assert_equal 1, a
+
+ a, * = 1, 2, 3
+ assert_equal 1, a
+
+ a, *b = 1, 2, 3
+ assert_equal 1, a
+ assert_equal [2, 3], b
+
+ # not supported yet
+ #a, *b, c = 1, 2, 3, 4
+ #assert_equal 1, a
+ #assert_equal [2,3], b
+ #assert_equal 4, c
+
+ a = 1, 2
+ assert_equal [1, 2], a
+
+ a = [1, 2], [3, 4]
+ assert_equal [[1,2], [3,4]], a
+
+ a, (b, c), d = 1, [2, 3], 4
+ assert_equal 1, a
+ assert_equal 2, b
+ assert_equal 3, c
+ assert_equal 4, d
+
+ *a = 1, 2, 3
+ assert_equal([1, 2, 3], a)
+
+ *a = 4
+ assert_equal([4], a)
+
+ *a = nil
+ assert_equal([nil], a)
+
+ a, b = 1
+ assert_equal 1, a
+ assert_nil b
+
+ a, b = [1, 2]
+ assert_equal 1, a
+ assert_equal 2, b
+ end
+
+ def test_nested_massign
+ (a, b), c = [[1, 2], 3]; assert_equal [1,2,3], [a,b,c]
+ a, (b, c) = [[1, 2], 3]; assert_equal [[1,2], 3, nil], [a,b,c]
+ a, (b, c) = [1, [2, 3]]; assert_equal [1,2,3], [a,b,c]
+ (a, b), *c = [[1, 2], 3]; assert_equal [1,2,[3]], [a,b,c]
+ (a,b),c,(d,e) = [[1,2],3,[4,5]]; assert_equal [1,2,3,4,5],[a,b,c,d,e]
+ (a,*b),c,(d,e,*) = [[1,2],3,[4,5]]; assert_equal [1,[2],3,4,5],[a,b,c,d,e]
+ (a,b),c,(d,*e) = [[1,2,3],4,[5,6,7,8]]; assert_equal [1,2,4,5,[6,7,8]],[a,b,c,d,e]
+ (a,(b1,b2)),c,(d,e) = [[1,2],3,[4,5]]; assert_equal [1,2,nil,3,4,5],[a,b1,b2,c,d,e]
+ (a,(b1,b2)),c,(d,e) = [[1,[21,22]],3,[4,5]]; assert_equal [1,21,22,3,4,5],[a,b1,b2,c,d,e]
+ end
+
+ class MyObj
+ def to_ary
+ [[1,2],[3,4]]
+ end
+ end
+
+ def test_to_ary_splat
+ a, b = MyObj.new
+ assert_equal [[1,2],[3,4]], [a,b]
+ end
+
+ A = 1
+ B = 2
+ X, Y = A, B
+ class Base
+ A = 3
+ B = 4
+ end
+
+ def test_const_massign
+ assert_equal [1,2], [X,Y]
+ a, b = Base::A, Base::B
+ assert_equal [3,4], [a,b]
+ end
+end
+
+require_relative 'sentence'
+class TestAssignmentGen < Test::Unit::TestCase
+ Syntax = {
+ :exp => [["0"],
+ ["nil"],
+ ["false"],
+ ["[]"],
+ ["[",:exps,"]"]],
+ :exps => [[:exp],
+ [:exp,",",:exps]],
+ :arg => [[:exp]],
+ :mrhs => [[:args,",",:arg],
+ [:args,",","*",:arg],
+ ["*",:arg]],
+ :args => [[:arg],
+ ["*",:arg],
+ [:args,",",:arg],
+ [:args,",","*",:arg]],
+ :mlhs => [[:mlhs_basic],
+ ["(",:mlhs_inner,")"]],
+ :mlhs_inner => [[:mlhs_basic],
+ ["(",:mlhs_inner,")"]],
+ :mlhs_basic => [[:mlhs_head],
+ [:mlhs_head,:mlhs_item],
+ [:mlhs_head,"*",:mlhs_node],
+ [:mlhs_head,"*",:mlhs_node,",",:mlhs_post],
+ [:mlhs_head,"*"],
+ [:mlhs_head,"*",",", :mlhs_post],
+ [ "*",:mlhs_node],
+ [ "*",:mlhs_node,",",:mlhs_post],
+ [ "*"],
+ [ "*",",", :mlhs_post]],
+ :mlhs_head => [[:mlhs_item,","],
+ [:mlhs_head,:mlhs_item,","]],
+ :mlhs_post => [[:mlhs_item],
+ [:mlhs_post,",",:mlhs_item]],
+ :mlhs_item => [[:mlhs_node],
+ ["(",:mlhs_inner,")"]],
+ :mlhs_node => [["var"]],
+ :xassign => [["var"," = ",:exp],
+ ["var"," = ",:mrhs],
+ [:mlhs," = ",:exp],
+ [:mlhs," = ",:mrhs]],
+ }
+
+ def rename_var(obj)
+ vars = []
+ r = obj.subst('var') {
+ var = "v#{vars.length}"
+ vars << var
+ var
+ }
+ return r, vars
+ end
+
+ def expand_except_paren(obj)
+ return obj if obj.respond_to? :to_str
+ obj.expand {|s|
+ !(s[0] == '(' && s[-1] == ')') &&
+ !(s[0] == '[' && s[-1] == ']')
+ }
+ end
+
+ def extract_single_element(ary)
+ raise "not a single element array: #{ary.inspect}" if ary.length != 1
+ ary[0]
+ end
+
+ def emu_assign_ary(lhs, rv, h)
+ rv = rv.respond_to?(:to_ary) ? rv : [rv]
+ rv = rv.dup
+ a = [[]]
+ lhs.each {|e|
+ if e == ','
+ a << []
+ else
+ a.last << e
+ end
+ }
+ a.pop if a.last == []
+ pre = []
+ star = post = nil
+ a.each {|e|
+ if post
+ post << e
+ elsif e[0] == '*'
+ star = e
+ post = []
+ else
+ pre << e
+ end
+ }
+ pre.map! {|e| extract_single_element(e) }
+ if star
+ if star == ['*']
+ star = nil
+ else
+ star = extract_single_element(star[1..-1])
+ end
+ end
+ post.map! {|e| extract_single_element(e) } if post
+
+ until pre.empty?
+ emu_assign_single(pre.shift, rv.shift, h)
+ end
+
+ if post
+ if rv.length < post.length
+ until post.empty?
+ emu_assign_single(post.shift, rv.shift, h)
+ end
+ else
+ until post.empty?
+ emu_assign_single(post.pop, rv.pop, h)
+ end
+ end
+ end
+
+ if star
+ emu_assign_single(star, rv, h)
+ end
+ end
+
+ def emu_assign_single(lhs, rv, h={})
+ if lhs.respond_to? :to_str
+ if /\A[a-z0-9]+\z/ =~ lhs
+ h[lhs] = rv
+ else
+ raise "unexpected lhs string: #{lhs.inspect}"
+ end
+ elsif Sentence === lhs
+ if lhs[0] == '(' && lhs[-1] == ')'
+ emu_assign_ary(lhs[1...-1], rv, h)
+ elsif lhs.length == 1 && String === lhs[0] && /\A[a-z0-9]+\z/ =~ lhs[0]
+ h[lhs[0]] = rv
+ else
+ raise "unexpected lhs sentence: #{lhs.inspect}"
+ end
+ else
+ raise "unexpected lhs: #{lhs.inspect}"
+ end
+ h
+ end
+
+ def emu_assign(assign)
+ lhs = expand_except_paren(assign[0])
+ rhs = expand_except_paren(assign[2])
+ lopen = Sentence === lhs && lhs[-1] != ')' && lhs.any? {|e| e == '*' || e == ',' }
+ ropen = Sentence === rhs && rhs[-1] != ']' && rhs.any? {|e| e == '*' || e == ',' }
+ lhs = Sentence.new(['(']+lhs.to_a+[')']) if lopen
+ begin
+ rv = eval((ropen ? ["[",assign[2],"]"] : assign[2]).join(''))
+ rescue Exception
+ rv = $!.message
+ end
+ emu_assign_single(lhs, rv)
+ end
+
+ def do_assign(assign, vars)
+ assign = assign.to_s
+ code1 = "#{assign}; [#{vars.join(",")}]"
+ assign.gsub!(/\bv\d+\b/, "o.a")
+ code2 = "o=[];class << o; self end.send(:define_method,:a=){|v|self << v};#{assign};o"
+ begin
+ vals1 = eval(code1)
+ rescue Exception
+ return {:ex=>$!.message}
+ end
+ begin
+ vals2 = eval(code2)
+ rescue Exception
+ return {:ex=>$!.message}
+ end
+ assert_equal(vals1, vals2, code1)
+ vals = vals1
+ h = {}
+ [vars, vals].transpose.each {|k,v| h[k] = v }
+ h
+ end
+
+ def check(assign)
+ assign, vars = rename_var(assign)
+ sent = assign.to_s
+ bruby = do_assign(assign, vars).to_a.sort
+ bemu = emu_assign(assign).to_a.sort
+ assert_equal(bemu, bruby, sent)
+ end
+
+ def test_assignment
+ syntax = Sentence.expand_syntax(Syntax)
+ Sentence.each(syntax, :xassign, 4) {|assign|
+ check(assign)
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_autoload.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_autoload.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_autoload.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,12 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestAutoload < Test::Unit::TestCase
+ def test_autoload_so
+ # Continuation is always available, unless excluded intentionally.
+ assert_in_out_err([], <<-INPUT, [], [])
+ autoload :Continuation, "continuation"
+ begin Continuation; rescue LoadError; end
+ INPUT
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_basicinstructions.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_basicinstructions.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_basicinstructions.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,680 @@
+require 'test/unit'
+
+ConstTest = 3
+class Class
+ alias _remove_const remove_const
+ public :_remove_const
+end
+
+class TestBasicInstructions < Test::Unit::TestCase
+
+ def test_immediates
+ assert_equal((1==1), true)
+ assert_equal((1==2), false)
+ assert_equal [][0], nil
+ assert_equal "sym".intern, :sym
+ assert_equal "sym".intern, :"sym"
+ assert_equal 1234 + 0, 1234
+ assert_equal 1234, 1_2_3_4
+ assert_equal 41, 0b0101001
+ assert_equal 420, 0644
+ assert_equal 18, 0x12
+ assert_equal 123456789012345678901234567890 + 0,
+ 123456789012345678901234567890
+ assert_equal 1.234 + 0.0, 1.234
+ end
+
+ def test_self
+ assert_equal self, self
+ assert_equal false, (self == false) # Qfalse==0 in C
+ assert_equal false, (self == nil)
+ assert_equal false, (self == 0)
+ end
+
+ def test_string
+ expected = "str" + "ing"
+ assert_equal expected, 'string'
+ assert_equal expected, "string"
+ assert_equal expected, %q(string)
+ assert_equal expected, %Q(string)
+ assert_equal expected, %(string)
+ end
+
+ def test_dstring
+ assert_equal "2", "#{1+1}"
+ s = "OK"
+ assert_equal "OK", "#{s}"
+ assert_equal "OKx", "#{s}x"
+ assert_equal "xOK", "x#{s}"
+ assert_equal "xOKx", "x#{s}x"
+ end
+
+ def test_dsym
+ assert_equal :a3c, :"a#{1+2}c"
+ s = "sym"
+ assert_equal :sym, :"#{s}"
+ assert_equal :sym, :"#{"#{"#{s}"}"}"
+ end
+
+ def test_xstr
+ assert_equal 'hoge', `echo hoge`.chomp
+ assert_equal '3', `echo #{1 + 2}`.chomp
+ hoge = 'huga'
+ assert_equal 'huga', `echo #{hoge}`.chomp
+ end
+
+ def test_regexp
+ assert_equal(/test/, /test/)
+ assert_equal 'test', /test/.source
+ assert_equal 'TEST', /TEST/.source
+ assert_equal true, !!(/test/ =~ 'test')
+ assert_equal false, !!(/test/ =~ 'does not match')
+
+ re = /test/
+ assert_equal re, re
+ assert_equal 'test', re.source
+ assert_equal true, !!(re =~ 'test')
+ assert_equal false, !!(re =~ 'does not match')
+
+ assert_equal(/x#{1+1}x/, /x#{1+1}x/)
+ s = "OK"
+ assert_equal(/x#{s}x/, /x#{s}x/)
+ assert_equal true, !!(/x#{s}x/ =~ "xOKx")
+ assert_equal false, !!(/x#{s}x/ =~ "does not match")
+
+ s = "OK"
+ prev = nil
+ 3.times do
+ assert_equal prev.object_id, (prev ||= /#{s}/o).object_id if prev
+ end
+ end
+
+ def test_array
+ assert_equal [], []
+ assert_equal 0, [].size
+ assert_equal [1, 2, 3], [1, 2, 3]
+ assert_equal [3, 7, 11], [1+2, 3+4, 5+6]
+ assert_equal [[1], [2], [3]], [[1], [2], [3]]
+
+ a = [1, 2, 3]
+ assert_equal 1, a[0]
+ assert_equal 2, a[1]
+ assert_equal 3, a[2]
+ assert_nil a[3]
+
+ a = %w( a b c )
+ assert_equal 'a', a[0]
+ assert_equal 'b', a[1]
+ assert_equal 'c', a[2]
+ assert_nil a[3]
+ end
+
+ def test_hash
+ assert_equal({}, {})
+ assert_equal({1=>2}, {1=>2})
+ assert_equal({1=>2, 3=>4}, {1=>2, 3=>4})
+ assert_equal({1=>2, 3=>4}, {3=>4, 1=>2})
+ # assert_equal({1=>2, 3=>4}, {1,2, 3,4}) # 1.9 doesn't support
+ assert_equal({"key"=>"val"}, {"key"=>"val"})
+ end
+
+ def test_range
+ assert_equal((1..3), (1..3))
+ assert_equal((1...3), (1...3))
+ assert_not_equal((1...3), (1..3))
+ assert_not_equal((1..3), (1...3))
+ assert_equal((1..3), (1..2+1))
+ assert_equal((1...3), (1...2+1))
+ assert_equal(('a'..'z'), ('a'..'z'))
+ end
+
+ def test_not
+ assert_equal true, !nil
+ assert_equal true, !false
+ assert_equal false, !true
+ assert_equal false, !3
+ assert_equal false, !(1+1)
+
+ assert_equal false, !!nil
+ assert_equal false, !!false
+ assert_equal true, !!true
+ assert_equal true, !!3
+ assert_equal true, !!(1+1)
+
+ assert_equal true, (not nil)
+ assert_equal true, (not false)
+ assert_equal false, (not true)
+ assert_equal false, (not 3)
+ assert_equal false, (not (1 + 1))
+
+ assert_equal false, (not not nil)
+ assert_equal false, (not not false)
+ assert_equal true, (not not true)
+ assert_equal true, (not not 3)
+ assert_equal true, (not not (1+1))
+ end
+
+ def test_local_variable
+ a = 7
+ assert_equal 7, a
+ assert_equal a, a
+ b = 17
+ assert_equal 7, a
+ assert_equal 17, b
+ assert_equal a, a
+ assert_equal b, b
+ assert_not_equal a, b
+ assert_not_equal b, a
+ a = b
+ assert_equal 17, a
+ assert_equal 17, b
+ assert_equal a, a
+ assert_equal b, b
+ assert_equal a, b
+ assert_equal b, a
+ c = 28
+ assert_equal 17, a
+ assert_equal 17, b
+ assert_equal 28, c
+ assert_equal a, a
+ assert_equal b, b
+ assert_equal a, b
+ assert_equal c, c
+ assert_not_equal a, c
+ assert_not_equal b, c
+ a = b = c
+ assert_equal 28, a
+ assert_equal 28, b
+ assert_equal 28, c
+ assert_equal a, a
+ assert_equal b, b
+ assert_equal a, b
+ assert_equal b, a
+ assert_equal a, c
+ assert_equal c, a
+ assert_equal b, c
+ assert_equal c, b
+
+ a = 1
+ b = 2
+ c = 3
+ set_lvar_in_another_method
+ assert_equal 1, a
+ assert_equal 2, b
+ assert_equal 3, c
+ end
+
+ def set_lvar_in_another_method
+ assert_raise(NameError) { a }
+ assert_raise(NameError) { b }
+ assert_raise(NameError) { c }
+ a = "NOT OK"
+ b = "NOT OK"
+ c = "NOT OK"
+ end
+
+ class Const
+ $Const = self
+ C = 'Const::C'
+ def self.c() C end
+ def c() C end
+
+ class A
+ C = 'Const::A::C'
+ def self.c() C end
+ def c() C end
+ CC = 'Const::A::CC'
+ def self.cc() CC end
+ def cc() CC end
+
+ class B
+ C = 'Const::A::B::C'
+ def self.c() C end
+ def c() C end
+ def self.cc() CC end
+ def cc() CC end
+ end
+ end
+
+ class AA < A
+ def self.cc() CC end
+ def cc() CC end
+ end
+
+ class AAA < AA
+ def self.cc() CC end
+ def cc() CC end
+ end
+ end
+ C = 0
+
+ def test_const_path
+ do_test_const_path
+ do_test_const_path
+ do_test_const_path
+ end
+
+ def do_test_const_path
+ assert_equal 0, C
+ assert_equal 0, C
+ assert_equal 3, ::ConstTest
+ assert_equal 3, ::ConstTest
+ assert_equal $Const, Const
+
+ assert_equal 'Const::C', Const::C
+ assert_equal 'Const::C', Const::C
+ assert_equal 'Const::A::C', Const::A::C
+ assert_equal 'Const::A::C', Const::A::C
+ assert_equal 'Const::A::B::C', Const::A::B::C
+ assert_equal 'Const::A::B::C', Const::A::B::C
+
+ Const::A::B._remove_const :C
+ assert_equal 'Const::C', Const::C
+ assert_equal 'Const::A::C', Const::A::C
+ assert_raise(NameError) { Const::A::B::C }
+
+ Const::A._remove_const :C
+ assert_equal 'Const::C', Const::C
+ assert_raise(NameError) { Const::A::C }
+ assert_raise(NameError) { Const::A::B::C }
+
+ Const._remove_const :C
+ assert_raise(NameError) { Const::C }
+ assert_raise(NameError) { Const::A::C }
+ assert_raise(NameError) { Const::A::B::C }
+
+ Const::A.const_set :C, 'Const::A::C'
+ assert_raise(NameError) { Const::C }
+ assert_equal 'Const::A::C', Const::A::C
+ assert_raise(NameError) { Const::A::B::C }
+
+ Const::A::B.const_set :C, 'Const::A::B::C'
+ assert_raise(NameError) { Const::C }
+ assert_equal 'Const::A::C', Const::A::C
+ assert_equal 'Const::A::B::C', Const::A::B::C
+
+ Const.const_set :C, 'Const::C'
+ assert_equal 'Const::C', Const::C
+ assert_equal 'Const::A::C', Const::A::C
+ assert_equal 'Const::A::B::C', Const::A::B::C
+ end
+
+ def test_const_cref
+ do_test_const_cref
+ do_test_const_cref
+ do_test_const_cref
+ end
+
+ def do_test_const_cref
+ assert_equal 'Const::C', Const.new.c
+ assert_equal 'Const::A::C', Const::A.new.c
+ assert_equal 'Const::A::B::C', Const::A::B.new.c
+
+ assert_equal 'Const::C', Const.c
+ assert_equal 'Const::A::C', Const::A.c
+ assert_equal 'Const::A::B::C', Const::A::B.c
+
+ Const::A::B._remove_const :C
+ assert_equal 'Const::C', Const.c
+ assert_equal 'Const::A::C', Const::A.c
+ assert_equal 'Const::A::C', Const::A::B.c
+ assert_equal 'Const::C', Const.new.c
+ assert_equal 'Const::A::C', Const::A.new.c
+ assert_equal 'Const::A::C', Const::A::B.new.c
+
+ Const::A._remove_const :C
+ assert_equal 'Const::C', Const.c
+ assert_equal 'Const::C', Const::A.c
+ assert_equal 'Const::C', Const::A::B.c
+ assert_equal 'Const::C', Const.new.c
+ assert_equal 'Const::C', Const::A.new.c
+ assert_equal 'Const::C', Const::A::B.new.c
+
+ Const::A::B.const_set :C, 'Const::A::B::C'
+ assert_equal 'Const::C', Const.c
+ assert_equal 'Const::C', Const::A.c
+ assert_equal 'Const::A::B::C', Const::A::B.c
+ assert_equal 'Const::C', Const.new.c
+ assert_equal 'Const::C', Const::A.new.c
+ assert_equal 'Const::A::B::C', Const::A::B.new.c
+
+ Const::A.const_set :C, 'Const::A::C'
+ assert_equal 'Const::C', Const.c
+ assert_equal 'Const::A::C', Const::A.c
+ assert_equal 'Const::A::B::C', Const::A::B.c
+ assert_equal 'Const::C', Const.new.c
+ assert_equal 'Const::A::C', Const::A.new.c
+ assert_equal 'Const::A::B::C', Const::A::B.new.c
+ ensure
+ # reset
+ Const.const_set :C, 'Const::C' unless Const.const_defined?(:C)
+ Const::A.const_set :C, 'Const::A::C' unless Const::A.const_defined?(:C)
+ Const::A::B.const_set :C, 'Const::A::B::C' unless Const::A::B.const_defined?(:C)
+ end
+
+ def test_const_inherit
+ do_test_const_inherit
+ do_test_const_inherit
+ do_test_const_inherit
+ end
+
+ def do_test_const_inherit
+ assert_equal 'Const::A::CC', Const::A.cc
+ assert_equal 'Const::A::CC', Const::AA.cc
+ assert_equal 'Const::A::CC', Const::AAA.cc
+ assert_equal 'Const::A::CC', Const::A.new.cc
+ assert_equal 'Const::A::CC', Const::AA.new.cc
+ assert_equal 'Const::A::CC', Const::AAA.new.cc
+
+ Const::AA.const_set :CC, 'Const::AA::CC'
+ assert_equal 'Const::A::CC', Const::A.cc
+ assert_equal 'Const::AA::CC', Const::AA.cc
+ assert_equal 'Const::AA::CC', Const::AAA.cc
+ assert_equal 'Const::A::CC', Const::A.new.cc
+ assert_equal 'Const::AA::CC', Const::AA.new.cc
+ assert_equal 'Const::AA::CC', Const::AAA.new.cc
+
+ Const::AAA.const_set :CC, 'Const::AAA::CC'
+ assert_equal 'Const::A::CC', Const::A.cc
+ assert_equal 'Const::AA::CC', Const::AA.cc
+ assert_equal 'Const::AAA::CC', Const::AAA.cc
+ assert_equal 'Const::A::CC', Const::A.new.cc
+ assert_equal 'Const::AA::CC', Const::AA.new.cc
+ assert_equal 'Const::AAA::CC', Const::AAA.new.cc
+
+ Const::AA._remove_const :CC
+ assert_equal 'Const::A::CC', Const::A.cc
+ assert_equal 'Const::A::CC', Const::AA.cc
+ assert_equal 'Const::AAA::CC', Const::AAA.cc
+ assert_equal 'Const::A::CC', Const::A.new.cc
+ assert_equal 'Const::A::CC', Const::AA.new.cc
+ assert_equal 'Const::AAA::CC', Const::AAA.new.cc
+
+ Const::AAA._remove_const :CC
+ assert_equal 'Const::A::CC', Const::A.cc
+ assert_equal 'Const::A::CC', Const::AA.cc
+ assert_equal 'Const::A::CC', Const::AAA.cc
+ assert_equal 'Const::A::CC', Const::A.new.cc
+ assert_equal 'Const::A::CC', Const::AA.new.cc
+ assert_equal 'Const::A::CC', Const::AAA.new.cc
+ end
+
+ def test_global_variable
+ $gvar1 = 1
+ assert_equal 1, $gvar1
+ $gvar1 = 2
+ assert_equal 2, $gvar1
+ $gvar2 = 77
+ assert_equal 2, $gvar1
+ assert_equal 77, $gvar2
+ $gvar2 = $gvar1
+ assert_equal 2, $gvar1
+ assert_equal 2, $gvar2
+ $gvar1 = 1
+ assert_equal 1, $gvar1
+ assert_equal 2, $gvar2
+ set_gvar_in_another_method
+ assert_equal "OK1", $gvar1
+ assert_equal "OK2", $gvar2
+ end
+
+ def set_gvar_in_another_method
+ assert_equal 1, $gvar1
+ assert_equal 2, $gvar2
+ $gvar1 = "OK1"
+ $gvar2 = "OK2"
+ end
+
+ class CVarA
+ @@cv = 'CVarA@@cv'
+ def self.cv() @@cv end
+ def self.cv=(v) @@cv = v end
+ class << self
+ def cv2() @@cv end
+ end
+ def cv() @@cv end
+ def cv=(v) @@cv = v end
+ end
+
+ class CVarB < CVarA
+ def self.cvB() @@cv end
+ def self.cvB=(v) @@cv = v end
+ class << self
+ def cvB2() @@cv end
+ end
+ def cvB() @@cv end
+ def cvB=(v) @@cv = v end
+ end
+
+ def test_class_variable
+ assert_equal 'CVarA@@cv', CVarA.cv
+ assert_equal 'CVarA@@cv', CVarA.cv2
+ assert_equal 'CVarA@@cv', CVarA.new.cv
+ CVarA.cv = 'singleton'
+ assert_equal 'singleton', CVarA.cv
+ assert_equal 'singleton', CVarA.cv2
+ assert_equal 'singleton', CVarA.new.cv
+ CVarA.new.cv = 'instance'
+ assert_equal 'instance', CVarA.cv
+ assert_equal 'instance', CVarA.cv2
+ assert_equal 'instance', CVarA.new.cv
+
+ CVarA.cv = 'CVarA@@cv'
+ CVarB.cv = 'B/singleton'
+ assert_equal 'B/singleton', CVarB.cv
+ assert_equal 'B/singleton', CVarB.cv2
+ assert_equal 'B/singleton', CVarB.new.cv
+ assert_equal 'B/singleton', CVarA.cv
+ assert_equal 'B/singleton', CVarA.cv2
+ assert_equal 'B/singleton', CVarA.new.cv
+ CVarB.new.cv = 'B/instance'
+ assert_equal 'B/instance', CVarB.cv
+ assert_equal 'B/instance', CVarB.cv2
+ assert_equal 'B/instance', CVarB.new.cv
+ assert_equal 'B/instance', CVarA.cv
+ assert_equal 'B/instance', CVarA.cv2
+ assert_equal 'B/instance', CVarA.new.cv
+
+ CVarA.cv = 'CVarA@@cv'
+ assert_equal('CVarA@@cv', CVarB.cvB)
+ assert_equal('CVarA@@cv', CVarB.cvB2)
+ assert_equal('CVarA@@cv', CVarB.new.cvB)
+ CVarB.cvB = 'B/singleton'
+ assert_equal 'B/singleton', CVarB.cvB
+ assert_equal 'B/singleton', CVarB.cvB2
+ assert_equal 'B/singleton', CVarB.new.cvB
+ assert_equal 'B/singleton', CVarA.cv
+ assert_equal 'B/singleton', CVarA.cv2
+ assert_equal 'B/singleton', CVarA.new.cv
+ CVarB.new.cvB = 'B/instance'
+ assert_equal 'B/instance', CVarB.cvB
+ assert_equal 'B/instance', CVarB.cvB2
+ assert_equal 'B/instance', CVarB.new.cvB
+ assert_equal 'B/instance', CVarA.cv
+ assert_equal 'B/instance', CVarA.cv2
+ assert_equal 'B/instance', CVarA.new.cv
+
+ CVarA.cv = 'CVarA@@cv'
+ CVarB.cvB = 'CVarB@@cv'
+ end
+
+ class OP
+ attr_reader :x
+ def x=(x)
+ @x = x
+ :Bug1996
+ end
+ Bug1996 = '[ruby-dev:39163], [ruby-core:25143]'
+ def [](i)
+ @x
+ end
+ def []=(i, x)
+ @x = x
+ :Bug2050
+ end
+ Bug2050 = '[ruby-core:25387]'
+ end
+
+ def test_opassign2_1
+ x = nil
+ assert_equal 1, x ||= 1
+ assert_equal 1, x
+ assert_equal 2, x &&= 2
+ assert_equal 2, x
+ assert_equal 2, x ||= 3
+ assert_equal 2, x
+ assert_equal 4, x &&= 4
+ assert_equal 4, x
+ assert_equal 5, x += 1
+ assert_equal 5, x
+ assert_equal 4, x -= 1
+ assert_equal 4, x
+ end
+
+ def test_opassign2_2
+ y = OP.new
+ y.x = nil
+ assert_equal 1, y.x ||= 1, OP::Bug1996
+ assert_equal 1, y.x
+ assert_equal 2, y.x &&= 2, OP::Bug1996
+ assert_equal 2, y.x
+ assert_equal 2, y.x ||= 3
+ assert_equal 2, y.x
+ assert_equal 4, y.x &&= 4, OP::Bug1996
+ assert_equal 4, y.x
+ assert_equal 5, y.x += 1, OP::Bug1996
+ assert_equal 5, y.x
+ assert_equal 4, y.x -= 1, OP::Bug1996
+ assert_equal 4, y.x
+ end
+
+ def test_opassign2_3
+ z = OP.new
+ z.x = OP.new
+ z.x.x = nil
+ assert_equal 1, z.x.x ||= 1, OP::Bug1996
+ assert_equal 1, z.x.x
+ assert_equal 2, z.x.x &&= 2, OP::Bug1996
+ assert_equal 2, z.x.x
+ assert_equal 2, z.x.x ||= 3
+ assert_equal 2, z.x.x
+ assert_equal 4, z.x.x &&= 4, OP::Bug1996
+ assert_equal 4, z.x.x
+ assert_equal 5, z.x.x += 1, OP::Bug1996
+ assert_equal 5, z.x.x
+ assert_equal 4, z.x.x -= 1, OP::Bug1996
+ assert_equal 4, z.x.x
+ end
+
+ def test_opassign1_1
+ a = []
+ a[0] = nil
+ assert_equal 1, a[0] ||= 1
+ assert_equal 1, a[0]
+ assert_equal 2, a[0] &&= 2
+ assert_equal 2, a[0]
+ assert_equal 2, a[0] ||= 3
+ assert_equal 2, a[0]
+ assert_equal 4, a[0] &&= 4
+ assert_equal 4, a[0]
+ assert_equal 5, a[0] += 1
+ assert_equal 5, a[0]
+ assert_equal 4, a[0] -= 1
+ assert_equal 4, a[0]
+ end
+
+ def test_opassign1_2
+ x = OP.new
+ x[0] = nil
+ assert_equal 1, x[0] ||= 1, OP::Bug2050
+ assert_equal 1, x[0]
+ assert_equal 2, x[0] &&= 2, OP::Bug2050
+ assert_equal 2, x[0]
+ assert_equal 2, x[0] ||= 3, OP::Bug2050
+ assert_equal 2, x[0]
+ assert_equal 4, x[0] &&= 4, OP::Bug2050
+ assert_equal 4, x[0]
+ assert_equal 5, x[0] += 1, OP::Bug2050
+ assert_equal 5, x[0]
+ assert_equal 4, x[0] -= 1, OP::Bug2050
+ assert_equal 4, x[0]
+ end
+
+ def test_backref
+ /re/ =~ 'not match'
+ assert_nil $~
+ assert_nil $`
+ assert_nil $&
+ assert_nil $'
+ assert_nil $+
+ assert_nil $1
+ assert_nil $2
+ assert_nil $3
+ assert_nil $4
+ assert_nil $5
+ assert_nil $6
+ assert_nil $7
+ assert_nil $8
+ assert_nil $9
+
+ /(a)(b)(c)(d)(e)(f)(g)(h)(i)/ =~ 'xabcdefghiy'
+ assert_not_nil $~
+ assert_instance_of MatchData, $~
+ assert_equal 'abcdefghi', $~[0]
+ assert_equal 'a', $~[1]
+ assert_equal 'b', $~[2]
+ assert_equal 'c', $~[3]
+ assert_equal 'd', $~[4]
+ assert_equal 'e', $~[5]
+ assert_equal 'f', $~[6]
+ assert_equal 'g', $~[7]
+ assert_equal 'h', $~[8]
+ assert_equal 'i', $~[9]
+ assert_equal 'x', $`
+ assert_equal 'abcdefghi', $&
+ assert_equal 'y', $'
+ assert_equal 'i', $+
+ assert_equal 'a', $1
+ assert_equal 'b', $2
+ assert_equal 'c', $3
+ assert_equal 'd', $4
+ assert_equal 'e', $5
+ assert_equal 'f', $6
+ assert_equal 'g', $7
+ assert_equal 'h', $8
+ assert_equal 'i', $9
+
+ /re/ =~ 'not match'
+ assert_nil $~
+ assert_nil $`
+ assert_nil $&
+ assert_nil $'
+ assert_nil $+
+ assert_nil $1
+ assert_nil $2
+ assert_nil $3
+ assert_nil $4
+ assert_nil $5
+ assert_nil $6
+ assert_nil $7
+ assert_nil $8
+ assert_nil $9
+ end
+
+ def test_array_splat
+ a = []
+ assert_equal [], [*a]
+ assert_equal [1], [1, *a]
+ a = [2]
+ assert_equal [2], [*a]
+ assert_equal [1, 2], [1, *a]
+ a = [2, 3]
+ assert_equal [2, 3], [*a]
+ assert_equal [1, 2, 3], [1, *a]
+
+ a = nil
+ assert_equal [], [*a]
+ assert_equal [1], [1, *a]
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_beginendblock.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_beginendblock.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_beginendblock.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,127 @@
+require 'test/unit'
+require 'tempfile'
+require 'timeout'
+require_relative 'envutil'
+
+class TestBeginEndBlock < Test::Unit::TestCase
+ DIR = File.dirname(File.expand_path(__FILE__))
+
+ def q(content)
+ "\"#{content}\""
+ end
+
+ def test_beginendblock
+ ruby = EnvUtil.rubybin
+ target = File.join(DIR, 'beginmainend.rb')
+ result = IO.popen([ruby, target]){|io|io.read}
+ assert_equal(%w(b1 b2-1 b2 main b3-1 b3 b4 e1 e4 e3 e2 e4-2 e4-1 e1-1 e4-1-1), result.split)
+
+ input = Tempfile.new(self.class.name)
+ inputpath = input.path
+ input.close
+ result = IO.popen([ruby, "-n", "-eBEGIN{p :begin}", "-eEND{p :end}", inputpath]){|io|io.read}
+ assert_equal(%w(:begin), result.split)
+ result = IO.popen([ruby, "-p", "-eBEGIN{p :begin}", "-eEND{p :end}", inputpath]){|io|io.read}
+ assert_equal(%w(:begin), result.split)
+ input.open
+ input.puts "foo\nbar"
+ input.close
+ result = IO.popen([ruby, "-n", "-eBEGIN{p :begin}", "-eEND{p :end}", inputpath]){|io|io.read}
+ assert_equal(%w(:begin :end), result.split)
+ result = IO.popen([ruby, "-p", "-eBEGIN{p :begin}", "-eEND{p :end}", inputpath]){|io|io.read}
+ assert_equal(%w(:begin foo bar :end), result.split)
+ end
+
+ def test_begininmethod
+ assert_raise(SyntaxError) do
+ eval("def foo; BEGIN {}; end")
+ end
+
+ assert_raise(SyntaxError) do
+ eval('eval("def foo; BEGIN {}; end")')
+ end
+ end
+
+ def test_begininclass
+ assert_raise(SyntaxError) do
+ eval("class TestBeginEndBlock; BEGIN {}; end")
+ end
+ end
+
+ def test_endblockwarn
+ ruby = EnvUtil.rubybin
+ # Use Tempfile to create temporary file path.
+ launcher = Tempfile.new(self.class.name)
+ errout = Tempfile.new(self.class.name)
+
+ launcher << <<EOF
+# -*- coding: #{ruby.encoding.name} -*-
+errout = ARGV.shift
+STDERR.reopen(File.open(errout, "w"))
+STDERR.sync = true
+Dir.chdir(#{q(DIR)})
+system("#{ruby}", "endblockwarn_rb")
+EOF
+ launcher.close
+ launcherpath = launcher.path
+ errout.close
+ erroutpath = errout.path
+ system(ruby, launcherpath, erroutpath)
+ expected = <<EOW
+endblockwarn_rb:2: warning: END in method; use at_exit
+(eval):2: warning: END in method; use at_exit
+EOW
+ assert_equal(expected, File.read(erroutpath))
+ # expecting Tempfile to unlink launcher and errout file.
+ end
+
+ def test_raise_in_at_exit
+ ruby = EnvUtil.rubybin
+ out = IO.popen([ruby, '-e', 'STDERR.reopen(STDOUT)',
+ '-e', 'at_exit{raise %[SomethingBad]}',
+ '-e', 'raise %[SomethingElse]']) {|f|
+ f.read
+ }
+ assert_match(/SomethingBad/, out, "[ruby-core:9675]")
+ assert_match(/SomethingElse/, out, "[ruby-core:9675]")
+ end
+
+ def test_should_propagate_exit_code
+ ruby = EnvUtil.rubybin
+ assert_equal false, system(ruby, '-e', 'at_exit{exit 2}')
+ assert_equal 2, $?.exitstatus
+ assert_nil $?.termsig
+ end
+
+ def test_should_propagate_signaled
+ ruby = EnvUtil.rubybin
+ out = IO.popen(
+ [ruby,
+ '-e', 'STDERR.reopen(STDOUT)',
+ '-e', 'at_exit{Process.kill(:INT, $$); sleep 5 }']) {|f|
+ timeout(10) {
+ f.read
+ }
+ }
+ assert_match(/Interrupt$/, out)
+ Process.kill(0, 0) rescue return # check if signal works
+ assert_nil $?.exitstatus
+ assert_equal Signal.list["INT"], $?.termsig
+ end
+
+ def test_endblock_raise
+ ruby = EnvUtil.rubybin
+ out = IO.popen(
+ [ruby,
+ '-e', 'class C; def write(x); puts x; STDOUT.flush; sleep 0.01; end; end',
+ '-e', '$stderr = C.new',
+ '-e', 'END {raise "e1"}; END {puts "e2"}',
+ '-e', 'END {raise "e3"}; END {puts "e4"}',
+ '-e', 'END {raise "e5"}; END {puts "e6"}']) {|f|
+ Thread.new {sleep 5; Process.kill :KILL, f.pid}
+ f.read
+ }
+ assert_match(/e1/, out)
+ assert_match(/e6/, out)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_bignum.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_bignum.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_bignum.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,437 @@
+require 'test/unit'
+
+class TestBignum < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ @fmax = Float::MAX.to_i
+ @fmax2 = @fmax * 2
+ @big = (1 << 63) - 1
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def fact(n)
+ return 1 if n == 0
+ f = 1
+ while n>0
+ f *= n
+ n -= 1
+ end
+ return f
+ end
+
+ def test_bignum
+ $x = fact(40)
+ assert_equal($x, $x)
+ assert_equal($x, fact(40))
+ assert($x < $x+2)
+ assert($x > $x-2)
+ assert_equal(815915283247897734345611269596115894272000000000, $x)
+ assert_not_equal(815915283247897734345611269596115894272000000001, $x)
+ assert_equal(815915283247897734345611269596115894272000000001, $x+1)
+ assert_equal(335367096786357081410764800000, $x/fact(20))
+ $x = -$x
+ assert_equal(-815915283247897734345611269596115894272000000000, $x)
+ assert_equal(2-(2**32), -(2**32-2))
+ assert_equal(2**32 - 5, (2**32-3)-2)
+
+ for i in 1000..1014
+ assert_equal(2 ** i, 1 << i)
+ end
+
+ n1 = 1 << 1000
+ for i in 1000..1014
+ assert_equal(n1, 1 << i)
+ n1 *= 2
+ end
+
+ n2=n1
+ for i in 1..10
+ n1 = n1 / 2
+ n2 = n2 >> 1
+ assert_equal(n1, n2)
+ end
+
+ for i in 4000..4096
+ n1 = 1 << i;
+ assert_equal(n1-1, (n1**2-1) / (n1+1))
+ end
+ end
+
+ def test_calc
+ b = 10**80
+ a = b * 9 + 7
+ assert_equal(7, a.modulo(b))
+ assert_equal(-b + 7, a.modulo(-b))
+ assert_equal(b + -7, (-a).modulo(b))
+ assert_equal(-7, (-a).modulo(-b))
+ assert_equal(7, a.remainder(b))
+ assert_equal(7, a.remainder(-b))
+ assert_equal(-7, (-a).remainder(b))
+ assert_equal(-7, (-a).remainder(-b))
+
+ assert_equal(10000000000000000000100000000000000000000, 10**40+10**20)
+ assert_equal(100000000000000000000, 10**40/10**20)
+
+ a = 677330545177305025495135714080
+ b = 14269972710765292560
+ assert_equal(0, a % b)
+ assert_equal(0, -a % b)
+ end
+
+ def shift_test(a)
+ b = a / (2 ** 32)
+ c = a >> 32
+ assert_equal(b, c)
+
+ b = a * (2 ** 32)
+ c = a << 32
+ assert_equal(b, c)
+ end
+
+ def test_shift
+ shift_test(-4518325415524767873)
+ shift_test(-0xfffffffffffffffff)
+ end
+
+ def test_to_s
+ assert_equal("fvvvvvvvvvvvv" ,18446744073709551615.to_s(32), "[ruby-core:10686]")
+ assert_equal("g000000000000" ,18446744073709551616.to_s(32), "[ruby-core:10686]")
+ assert_equal("3w5e11264sgsf" ,18446744073709551615.to_s(36), "[ruby-core:10686]")
+ assert_equal("3w5e11264sgsg" ,18446744073709551616.to_s(36), "[ruby-core:10686]")
+ assert_equal("nd075ib45k86f" ,18446744073709551615.to_s(31), "[ruby-core:10686]")
+ assert_equal("nd075ib45k86g" ,18446744073709551616.to_s(31), "[ruby-core:10686]")
+ assert_equal("1777777777777777777777" ,18446744073709551615.to_s(8))
+ assert_equal("-1777777777777777777777" ,-18446744073709551615.to_s(8))
+ end
+
+
+ T_ZERO = (2**32).coerce(0).first
+ T_ONE = (2**32).coerce(1).first
+ T_MONE = (2**32).coerce(-1).first
+ T31 = 2**31 # 2147483648
+ T31P = T31 - 1 # 2147483647
+ T32 = 2**32 # 4294967296
+ T32P = T32 - 1 # 4294967295
+ T64 = 2**64 # 18446744073709551616
+ T64P = T64 - 1 # 18446744073709551615
+
+ def test_big_2comp
+ assert_equal("-4294967296", (~T32P).to_s)
+ assert_equal("..f00000000", "%x" % -T32)
+ end
+
+ def test_int2inum
+ assert_equal([T31P], [T31P].pack("I").unpack("I"))
+ assert_equal([T31P], [T31P].pack("i").unpack("i"))
+ end
+
+ def test_quad_pack
+ assert_equal([ 1], [ 1].pack("q").unpack("q"))
+ assert_equal([- 1], [- 1].pack("q").unpack("q"))
+ assert_equal([ T31P], [ T31P].pack("q").unpack("q"))
+ assert_equal([-T31P], [-T31P].pack("q").unpack("q"))
+ assert_equal([ T64P], [ T64P].pack("Q").unpack("Q"))
+ assert_equal([ 0], [ T64 ].pack("Q").unpack("Q"))
+ end
+
+ def test_str_to_inum
+ assert_equal(1, " +1".to_i)
+ assert_equal(-1, " -1".to_i)
+ assert_equal(0, "++1".to_i)
+ assert_equal(73, "111".oct)
+ assert_equal(273, "0x111".oct)
+ assert_equal(7, "0b111".oct)
+ assert_equal(73, "0o111".oct)
+ assert_equal(111, "0d111".oct)
+ assert_equal(73, "0111".oct)
+ assert_equal(111, Integer("111"))
+ assert_equal(13, "111".to_i(3))
+ assert_raise(ArgumentError) { "111".to_i(37) }
+ assert_equal(1333, "111".to_i(36))
+ assert_equal(1057, "111".to_i(32))
+ assert_equal(0, "00a".to_i)
+ assert_equal(1, Integer("1 "))
+ assert_raise(ArgumentError) { Integer("1_") }
+ assert_raise(ArgumentError) { Integer("1__") }
+ assert_raise(ArgumentError) { Integer("1_0 x") }
+ assert_equal(T31P, "1111111111111111111111111111111".to_i(2))
+ assert_equal(0_2, '0_2'.to_i)
+ assert_equal(00_2, '00_2'.to_i)
+ assert_equal(00_02, '00_02'.to_i)
+ end
+
+ def test_to_s2
+ assert_raise(ArgumentError) { T31P.to_s(37) }
+ assert_equal("9" * 32768, (10**32768-1).to_s)
+ assert_raise(RangeError) { Process.wait(1, T64P) }
+ assert_equal("0", T_ZERO.to_s)
+ assert_equal("1", T_ONE.to_s)
+ end
+
+ def test_to_f
+ assert_nothing_raised { T31P.to_f.to_i }
+ assert_raise(FloatDomainError) { (1024**1024).to_f.to_i }
+ assert_equal(1, (2**50000).to_f.infinite?)
+ assert_equal(-1, (-(2**50000)).to_f.infinite?)
+ end
+
+ def test_cmp
+ assert(T31P > 1)
+ assert(T31P < 2147483648.0)
+ assert(T31P < T64P)
+ assert(T64P > T31P)
+ assert_raise(ArgumentError) { T31P < "foo" }
+ assert(T64 < (1.0/0.0))
+ assert(!(T64 > (1.0/0.0)))
+ end
+
+ def test_eq
+ assert(T31P != 1)
+ assert(T31P == 2147483647.0)
+ assert(T31P != "foo")
+ end
+
+ def test_eql
+ assert(T31P.eql?(T31P))
+ end
+
+ def test_convert
+ assert_equal([255], [T_MONE].pack("C").unpack("C"))
+ assert_equal([0], [T32].pack("C").unpack("C"))
+ assert_raise(RangeError) { 0.to_s(T32) }
+ end
+
+ def test_sub
+ assert_equal(-T31, T32 - (T32 + T31))
+ x = 2**100
+ assert_equal(1, (x+2) - (x+1))
+ assert_equal(-1, (x+1) - (x+2))
+ assert_equal(0, (2**100) - (2.0**100))
+ o = Object.new
+ def o.coerce(x); [x, 2**100+2]; end
+ assert_equal(-1, (2**100+1) - o)
+ assert_equal(-1, T_ONE - 2)
+ end
+
+ def test_plus
+ assert_equal(T32.to_f, T32P + 1.0)
+ assert_raise(TypeError) { T32 + "foo" }
+ assert_equal(1267651809154049016125877911552, (2**100) + (2**80))
+ assert_equal(1267651809154049016125877911552, (2**80) + (2**100))
+ assert_equal(2**101, (2**100) + (2.0**100))
+ o = Object.new
+ def o.coerce(x); [x, 2**80]; end
+ assert_equal(1267651809154049016125877911552, (2**100) + o)
+ end
+
+ def test_minus
+ assert_equal(T32P.to_f, T32 - 1.0)
+ assert_raise(TypeError) { T32 - "foo" }
+ end
+
+ def test_mul
+ assert_equal(T32.to_f, T32 * 1.0)
+ assert_raise(TypeError) { T32 * "foo" }
+ o = Object.new
+ def o.coerce(x); [x, 2**100]; end
+ assert_equal(2**180, (2**80) * o)
+ end
+
+ def test_mul_balance
+ assert_equal(3**7000, (3**5000) * (3**2000))
+ end
+
+ def test_divrem
+ assert_equal(0, T32 / T64)
+ end
+
+ def test_div
+ assert_equal(T32.to_f, T32 / 1.0)
+ assert_raise(TypeError) { T32 / "foo" }
+ assert_equal(0x20000000, 0x40000001.div(2.0), "[ruby-dev:34553]")
+ end
+
+ def test_idiv
+ assert_equal(715827882, 1073741824.div(Rational(3,2)), ' [ruby-dev:34066]')
+ end
+
+ def test_modulo
+ assert_raise(TypeError) { T32 % "foo" }
+ end
+
+ def test_remainder
+ assert_equal(0, T32.remainder(1))
+ assert_raise(TypeError) { T32.remainder("foo") }
+ end
+
+ def test_divmod
+ assert_equal([T32, 0], T32.divmod(1))
+ assert_equal([2, 0], T32.divmod(T31))
+ assert_raise(TypeError) { T32.divmod("foo") }
+ end
+
+ def test_quo
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ assert_equal(T32.to_f, T32.quo(1))
+ assert_equal(T32.to_f, T32.quo(1.0))
+ assert_equal(T32.to_f, T32.quo(T_ONE))
+
+ assert_raise(TypeError) { T32.quo("foo") }
+
+ assert_equal(1024**1024, (1024**1024).quo(1))
+ assert_equal(1024**1024, (1024**1024).quo(1.0))
+ assert_equal(1024**1024*2, (1024**1024*2).quo(1))
+ inf = 1 / 0.0; nan = inf / inf
+
+ assert((1024**1024*2).quo(nan).nan?)
+ end
+
+ def test_pow
+ assert_equal(1.0, T32 ** 0.0)
+ assert_equal(1.0 / T32, T32 ** -1)
+ assert_equal(1, (T32 ** T32).infinite?)
+ assert_equal(1, (T32 ** (2**30-1)).infinite?)
+
+ ### rational changes the behavior of Bignum#**
+ #assert_raise(TypeError) { T32**"foo" }
+ assert_raise(TypeError, ArgumentError) { T32**"foo" }
+ end
+
+ def test_and
+ assert_equal(0, T32 & 1)
+ assert_equal(-T32, (-T32) & (-T31))
+ assert_equal(0, T32 & T64)
+ end
+
+ def test_or
+ assert_equal(T32 + 1, T32 | 1)
+ assert_equal(T32 + T31, T32 | T31)
+ assert_equal(-T31, (-T32) | (-T31))
+ assert_equal(T64 + T32, T32 | T64)
+ end
+
+ def test_xor
+ assert_equal(T32 + 1, T32 ^ 1)
+ assert_equal(T32 + T31, T32 ^ T31)
+ assert_equal(T31, (-T32) ^ (-T31))
+ assert_equal(T64 + T32, T32 ^ T64)
+ end
+
+ def test_shift2
+ assert_equal(2**33, (2**32) << 1)
+ assert_equal(2**31, (2**32) << -1)
+ assert_equal(2**33, (2**32) << 1.0)
+ assert_equal(2**31, (2**32) << -1.0)
+ assert_equal(2**33, (2**32) << T_ONE)
+ assert_equal(2**31, (2**32) << T_MONE)
+ assert_equal(2**31, (2**32) >> 1)
+ assert_equal(2**33, (2**32) >> -1)
+ assert_equal(2**31, (2**32) >> 1.0)
+ assert_equal(2**33, (2**32) >> -1.0)
+ assert_equal(2**31, (2**32) >> T_ONE)
+ assert_equal(2**33, (2**32) >> T_MONE)
+ assert_equal( 0, (2**32) >> (2**32))
+ assert_equal(-1, -(2**32) >> (2**32))
+ assert_equal( 0, (2**32) >> 128)
+ assert_equal(-1, -(2**32) >> 128)
+ assert_equal( 0, (2**31) >> 32)
+ assert_equal(-1, -(2**31) >> 32)
+ end
+
+ def test_aref
+ assert_equal(0, (2**32)[0])
+ assert_equal(0, (2**32)[2**32])
+ assert_equal(0, (2**32)[-(2**32)])
+ assert_equal(0, (2**32)[T_ZERO])
+ assert_equal(0, (-(2**64))[0])
+ assert_equal(1, (-2**256)[256])
+ end
+
+ def test_hash
+ assert_nothing_raised { T31P.hash }
+ end
+
+ def test_coerce
+ assert_equal([T64P, T31P], T31P.coerce(T64P))
+ assert_raise(TypeError) { T31P.coerce(nil) }
+ end
+
+ def test_abs
+ assert_equal(T31P, (-T31P).abs)
+ end
+
+ def test_size
+ assert(T31P.size.is_a?(Integer))
+ end
+
+ def test_odd
+ assert_equal(true, (2**32+1).odd?)
+ assert_equal(false, (2**32).odd?)
+ end
+
+ def test_even
+ assert_equal(false, (2**32+1).even?)
+ assert_equal(true, (2**32).even?)
+ end
+
+ def interrupt
+ time = Time.now
+ start_flag = false
+ end_flag = false
+ thread = Thread.new do
+ start_flag = true
+ yield
+ end_flag = true
+ end
+ sleep 1
+ thread.raise
+ thread.join rescue nil
+ start_flag && !end_flag && Time.now - time < 10
+ end
+
+ def test_interrupt
+ assert(interrupt { (65536 ** 65536).to_s })
+ end
+
+ def test_too_big_to_s
+ if (big = 2**31-1).is_a?(Fixnum)
+ return
+ end
+ e = assert_raise(RangeError) {(1 << big).to_s}
+ assert_match(/too big to convert/, e.message)
+ end
+
+ def test_fix_fdiv
+ assert_not_equal(0, 1.fdiv(@fmax2))
+ assert_in_delta(0.5, 1.fdiv(@fmax2) * @fmax, 0.01)
+ end
+
+ def test_big_fdiv
+ assert_equal(1, @big.fdiv(@big))
+ assert_not_equal(0, @big.fdiv(@fmax2))
+ assert_not_equal(0, @fmax2.fdiv(@big))
+ assert_not_equal(0, @fmax2.fdiv(@fmax2))
+ assert_in_delta(0.5, @fmax.fdiv(@fmax2), 0.01)
+ assert_in_delta(1.0, @fmax2.fdiv(@fmax2), 0.01)
+ end
+
+ def test_float_fdiv
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ b = 1E+300.to_i
+ assert_equal(b, (b ** 2).fdiv(b))
+ assert(@big.fdiv(0.0 / 0.0).nan?)
+ assert_in_delta(1E+300, (10**500).fdiv(1E+200), 1E+285)
+ end
+
+ def test_obj_fdiv
+ o = Object.new
+ def o.coerce(x); [x, 2**100]; end
+ assert_equal((2**200).to_f, (2**300).fdiv(o))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_call.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_call.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_call.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,19 @@
+require 'test/unit'
+
+class TestCall < Test::Unit::TestCase
+ def aaa(a, b=100, *rest)
+ res = [a, b]
+ res += rest if rest
+ return res
+ end
+
+ def test_call
+ assert_raise(ArgumentError) {aaa()}
+ assert_raise(ArgumentError) {aaa}
+
+ assert_equal([1, 100], aaa(1))
+ assert_equal([1, 2], aaa(1, 2))
+ assert_equal([1, 2, 3, 4], aaa(1, 2, 3, 4))
+ assert_equal([1, 2, 3, 4], aaa(1, *[2, 3, 4]))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_case.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_case.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_case.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,87 @@
+require 'test/unit'
+require_relative 'envutil.rb'
+
+class TestCase < Test::Unit::TestCase
+ def test_case
+ case 5
+ when 1, 2, 3, 4, 6, 7, 8
+ assert(false)
+ when 5
+ assert(true)
+ end
+
+ case 5
+ when 5
+ assert(true)
+ when 1..10
+ assert(false)
+ end
+
+ case 5
+ when 1..10
+ assert(true)
+ else
+ assert(false)
+ end
+
+ case 5
+ when 5
+ assert(true)
+ else
+ assert(false)
+ end
+
+ case "foobar"
+ when /^f.*r$/
+ assert(true)
+ else
+ assert(false)
+ end
+
+ case
+ when true
+ assert(true)
+ when false, nil
+ assert(false)
+ else
+ assert(false)
+ end
+
+ case "+"
+ when *%w/. +/
+ assert(true)
+ else
+ assert(false)
+ end
+
+ case
+ when *[], false
+ assert(false)
+ else
+ assert(true)
+ end
+
+ case
+ when *false, []
+ assert(true)
+ else
+ assert(false)
+ end
+
+ assert_raise(NameError) do
+ case
+ when false, *x, false
+ end
+ end
+ end
+
+ def test_deoptimization
+ assert_in_out_err(['-e', <<-EOS], '', %w[42], [])
+ class Symbol; undef ===; def ===(o); p 42; true; end; end; case :foo; when :foo; end
+ EOS
+
+ assert_in_out_err(['-e', <<-EOS], '', %w[42], [])
+ class Fixnum; undef ===; def ===(o); p 42; true; end; end; case 1; when 1; end
+ EOS
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_class.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_class.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_class.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,239 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestClass < Test::Unit::TestCase
+ # ------------------
+ # Various test classes
+ # ------------------
+
+ class ClassOne
+ attr :num_args
+ @@subs = []
+ def initialize(*args)
+ @num_args = args.size
+ @args = args
+ end
+ def [](n)
+ @args[n]
+ end
+ def ClassOne.inherited(klass)
+ @@subs.push klass
+ end
+ def subs
+ @@subs
+ end
+ end
+
+ class ClassTwo < ClassOne
+ end
+
+ class ClassThree < ClassOne
+ end
+
+ class ClassFour < ClassThree
+ end
+
+ # ------------------
+ # Start of tests
+ # ------------------
+
+ def test_s_inherited
+ assert_equal([ClassTwo, ClassThree, ClassFour], ClassOne.new.subs)
+ end
+
+ def test_s_new
+ c = Class.new
+ assert_same(Class, c.class)
+ assert_same(Object, c.superclass)
+
+ c = Class.new(Fixnum)
+ assert_same(Class, c.class)
+ assert_same(Fixnum, c.superclass)
+ end
+
+ def test_00_new_basic
+ a = ClassOne.new
+ assert_equal(ClassOne, a.class)
+ assert_equal(0, a.num_args)
+
+ a = ClassOne.new(1, 2, 3)
+ assert_equal(3, a.num_args)
+ assert_equal(1, a[0])
+ end
+
+ def test_01_new_inherited
+ a = ClassTwo.new
+ assert_equal(ClassTwo, a.class)
+ assert_equal(0, a.num_args)
+
+ a = ClassTwo.new(1, 2, 3)
+ assert_equal(3, a.num_args)
+ assert_equal(1, a[0])
+ end
+
+ def test_superclass
+ assert_equal(ClassOne, ClassTwo.superclass)
+ assert_equal(Object, ClassTwo.superclass.superclass)
+ assert_equal(BasicObject, ClassTwo.superclass.superclass.superclass)
+ end
+
+ def test_class_cmp
+ assert_raise(TypeError) { Class.new <= 1 }
+ assert_raise(TypeError) { Class.new >= 1 }
+ assert_nil(Class.new <=> 1)
+ end
+
+ def test_class_initialize
+ assert_raise(TypeError) do
+ Class.new.instance_eval { initialize }
+ end
+ end
+
+ def test_instanciate_singleton_class
+ c = class << Object.new; self; end
+ assert_raise(TypeError) { c.new }
+ end
+
+ def test_superclass_of_basicobject
+ assert_equal(nil, BasicObject.superclass)
+ end
+
+ def test_module_function
+ c = Class.new
+ assert_raise(TypeError) do
+ Module.instance_method(:module_function).bind(c).call(:foo)
+ end
+ end
+
+ def test_method_redefinition
+ feature2155 = '[ruby-dev:39400]'
+
+ line = __LINE__+4
+ stderr = EnvUtil.verbose_warning do
+ Class.new do
+ def foo; end
+ def foo; end
+ end
+ end
+ assert_match(/:#{line}: warning: method redefined; discarding old foo/, stderr)
+ assert_match(/:#{line-1}: warning: previous definition of foo/, stderr, feature2155)
+
+ stderr = EnvUtil.verbose_warning do
+ Class.new do
+ def foo; end
+ alias bar foo
+ def foo; end
+ end
+ end
+ assert_equal("", stderr)
+
+ stderr = EnvUtil.verbose_warning do
+ Class.new do
+ def foo; end
+ alias bar foo
+ alias bar foo
+ end
+ end
+ assert_equal("", stderr)
+
+ line = __LINE__+4
+ stderr = EnvUtil.verbose_warning do
+ Class.new do
+ define_method(:foo) do end
+ def foo; end
+ end
+ end
+ assert_match(/:#{line}: warning: method redefined; discarding old foo/, stderr)
+ assert_match(/:#{line-1}: warning: previous definition of foo/, stderr, feature2155)
+
+ stderr = EnvUtil.verbose_warning do
+ Class.new do
+ define_method(:foo) do end
+ alias bar foo
+ alias bar foo
+ end
+ end
+ assert_equal("", stderr)
+
+ stderr = EnvUtil.verbose_warning do
+ Class.new do
+ def foo; end
+ undef foo
+ end
+ end
+ assert_equal("", stderr)
+ end
+
+ def test_check_inheritable
+ assert_raise(TypeError) { Class.new(Object.new) }
+
+ o = Object.new
+ c = class << o; self; end
+ assert_raise(TypeError) { Class.new(c) }
+ assert_raise(TypeError) { Class.new(Class) }
+ assert_raise(TypeError) { eval("class Foo < Class; end") }
+ end
+
+ def test_initialize_copy
+ c = Class.new
+ assert_raise(TypeError) { c.instance_eval { initialize_copy(1) } }
+
+ o = Object.new
+ c = class << o; self; end
+ assert_raise(TypeError) { c.dup }
+
+ assert_raise(TypeError) { BasicObject.dup }
+ end
+
+ def test_singleton_class
+ assert_raise(TypeError) { 1.extend(Module.new) }
+ assert_raise(TypeError) { :foo.extend(Module.new) }
+
+ assert_in_out_err([], <<-INPUT, %w(:foo :foo true true), [])
+ module Foo; def foo; :foo; end; end
+ false.extend(Foo)
+ true.extend(Foo)
+ p false.foo
+ p true.foo
+ p FalseClass.include?(Foo)
+ p TrueClass.include?(Foo)
+ INPUT
+ end
+
+ def test_uninitialized
+ assert_raise(TypeError) { Class.allocate.new }
+ assert_raise(TypeError) { Class.allocate.superclass }
+ end
+
+ def test_nonascii_name
+ c = eval("class ::C\u{df}; self; end")
+ assert_equal("C\u{df}", c.name, '[ruby-core:24600]')
+ c = eval("class C\u{df}; self; end")
+ assert_equal("TestClass::C\u{df}", c.name, '[ruby-core:24600]')
+ end
+
+ def test_invalid_jump_from_class_definition
+ assert_raise(SyntaxError) { eval("class C; next; end") }
+ assert_raise(SyntaxError) { eval("class C; break; end") }
+ assert_raise(SyntaxError) { eval("class C; redo; end") }
+ assert_raise(SyntaxError) { eval("class C; retry; end") }
+ assert_raise(SyntaxError) { eval("class C; return; end") }
+ assert_raise(SyntaxError) { eval("class C; yield; end") }
+ end
+
+ def test_clone
+ original = Class.new {
+ def foo
+ return super()
+ end
+ }
+ mod = Module.new {
+ def foo
+ return "mod#foo"
+ end
+ }
+ copy = original.clone
+ copy.send(:include, mod)
+ assert_equal("mod#foo", copy.new.foo)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_clone.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_clone.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_clone.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,28 @@
+require 'test/unit'
+
+class TestClone < Test::Unit::TestCase
+ module M001; end
+ module M002; end
+ module M003; include M002; end
+ module M002; include M001; end
+ module M003; include M002; end
+
+ def test_clone
+ foo = Object.new
+ def foo.test
+ "test"
+ end
+ bar = foo.clone
+ def bar.test2
+ "test2"
+ end
+
+ assert_equal("test2", bar.test2)
+ assert_equal("test", bar.test)
+ assert_equal("test", foo.test)
+
+ assert_raise(NoMethodError) {foo.test2}
+
+ assert_equal([M003, M002, M001], M003.ancestors)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_comparable.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_comparable.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_comparable.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,72 @@
+require 'test/unit'
+
+class TestComparable < Test::Unit::TestCase
+ def setup
+ @o = Object.new
+ @o.extend(Comparable)
+ end
+ def cmp(b)
+ class << @o; self; end.class_eval {
+ undef :<=>
+ define_method(:<=>, b)
+ }
+ end
+
+ def test_equal
+ cmp->(x) do 0; end
+ assert_equal(true, @o == nil)
+ cmp->(x) do 1; end
+ assert_equal(false, @o == nil)
+ cmp->(x) do raise; end
+ assert_equal(false, @o == nil)
+ end
+
+ def test_gt
+ cmp->(x) do 1; end
+ assert_equal(true, @o > nil)
+ cmp->(x) do 0; end
+ assert_equal(false, @o > nil)
+ cmp->(x) do -1; end
+ assert_equal(false, @o > nil)
+ end
+
+ def test_ge
+ cmp->(x) do 1; end
+ assert_equal(true, @o >= nil)
+ cmp->(x) do 0; end
+ assert_equal(true, @o >= nil)
+ cmp->(x) do -1; end
+ assert_equal(false, @o >= nil)
+ end
+
+ def test_lt
+ cmp->(x) do 1; end
+ assert_equal(false, @o < nil)
+ cmp->(x) do 0; end
+ assert_equal(false, @o < nil)
+ cmp->(x) do -1; end
+ assert_equal(true, @o < nil)
+ end
+
+ def test_le
+ cmp->(x) do 1; end
+ assert_equal(false, @o <= nil)
+ cmp->(x) do 0; end
+ assert_equal(true, @o <= nil)
+ cmp->(x) do -1; end
+ assert_equal(true, @o <= nil)
+ end
+
+ def test_between
+ cmp->(x) do 0 <=> x end
+ assert_equal(false, @o.between?(1, 2))
+ assert_equal(false, @o.between?(-2, -1))
+ assert_equal(true, @o.between?(-1, 1))
+ assert_equal(true, @o.between?(0, 0))
+ end
+
+ def test_err
+ assert_raise(ArgumentError) { 1.0 < nil }
+ assert_raise(ArgumentError) { 1.0 < Object.new }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_complex.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_complex.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_complex.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1090 @@
+require 'test/unit'
+
+class ComplexSub < Complex; end
+
+class Complex_Test < Test::Unit::TestCase
+
+ def setup
+ @rational = defined?(Rational)
+ if @rational
+ @keiju = Rational.instance_variables.include?(:@RCS_ID)
+ end
+ seps = [File::SEPARATOR, File::ALT_SEPARATOR].compact.map{|x| Regexp.escape(x)}.join("|")
+ @unify = $".grep(/(?:^|#{seps})mathn(?:\.(?:rb|so))?/).size != 0
+ end
+
+ def test_compsub
+ c = ComplexSub.__send__(:convert, 1)
+
+ assert_kind_of(Numeric, c)
+
+ if @unify
+ assert_instance_of(Fixnum, c)
+ else
+ assert_instance_of(ComplexSub, c)
+
+ c2 = c + 1
+ assert_instance_of(ComplexSub, c2)
+ c2 = c - 1
+ assert_instance_of(ComplexSub, c2)
+
+ c3 = c - c2
+ assert_instance_of(ComplexSub, c3)
+
+ s = Marshal.dump(c)
+ c5 = Marshal.load(s)
+ assert_equal(c, c5)
+ assert_instance_of(ComplexSub, c5)
+ end
+
+ c1 = Complex(1)
+ assert_equal(c1.hash, c.hash, '[ruby-dev:38850]')
+ assert_equal([true, true], [c.eql?(c1), c1.eql?(c)])
+ end
+
+ def test_eql_p
+ c = Complex(0)
+ c2 = Complex(0)
+ c3 = Complex(1)
+
+ assert_equal(true, c.eql?(c2))
+ assert_equal(false, c.eql?(c3))
+
+ if @unify
+ assert_equal(true, c.eql?(0))
+ else
+ assert_equal(false, c.eql?(0))
+ end
+ end
+
+ def test_hash
+ assert_instance_of(Fixnum, Complex(1,2).hash)
+ assert_instance_of(Fixnum, Complex(1.0,2.0).hash)
+
+ h = {}
+ h[Complex(0)] = 0
+ h[Complex(0,1)] = 1
+ h[Complex(1,0)] = 2
+ h[Complex(1,1)] = 3
+
+ assert_equal(4, h.size)
+ assert_equal(2, h[Complex(1,0)])
+
+ h[Complex(0,0)] = 9
+ assert_equal(4, h.size)
+
+ h[Complex(0.0,0.0)] = 9.0
+ assert_equal(5, h.size)
+
+ if (0.0/0).nan? && !((0.0/0).eql?(0.0/0))
+ h = {}
+ 3.times{h[Complex(0.0/0)] = 1}
+ assert_equal(3, h.size)
+ end
+ end
+
+ def test_freeze
+ c = Complex(1)
+ c.freeze
+ unless @unify
+ assert_equal(true, c.frozen?)
+ end
+ assert_instance_of(String, c.to_s)
+ end
+
+ def test_conv
+ c = Complex(0,0)
+ assert_equal(Complex(0,0), c)
+
+ c = Complex(2**32, 2**32)
+ assert_equal(Complex(2**32,2**32), c)
+ assert_equal([2**32,2**32], [c.real,c.imag])
+
+ c = Complex(-2**32, 2**32)
+ assert_equal(Complex(-2**32,2**32), c)
+ assert_equal([-2**32,2**32], [c.real,c.imag])
+
+ c = Complex(2**32, -2**32)
+ assert_equal(Complex(2**32,-2**32), c)
+ assert_equal([2**32,-2**32], [c.real,c.imag])
+
+ c = Complex(-2**32, -2**32)
+ assert_equal(Complex(-2**32,-2**32), c)
+ assert_equal([-2**32,-2**32], [c.real,c.imag])
+
+ c = Complex(Complex(1,2),2)
+ assert_equal(Complex(1,4), c)
+
+ c = Complex(2,Complex(1,2))
+ assert_equal(Complex(0,1), c)
+
+ c = Complex(Complex(1,2),Complex(1,2))
+ assert_equal(Complex(-1,3), c)
+
+ c = Complex::I
+ assert_equal(Complex(0,1), c)
+
+ assert_equal(Complex(1),Complex(1))
+ assert_equal(Complex(1),Complex('1'))
+ assert_equal(Complex(3.0,3.0),Complex('3.0','3.0'))
+ if @rational && !@keiju
+ assert_equal(Complex(1,1),Complex('3/3','3/3'))
+ end
+ assert_raise(TypeError){Complex(nil)}
+ assert_raise(TypeError){Complex(Object.new)}
+ assert_raise(ArgumentError){Complex()}
+ assert_raise(ArgumentError){Complex(1,2,3)}
+
+ if (0.0/0).nan?
+ assert_nothing_raised{Complex(0.0/0)}
+ end
+ if (1.0/0).infinite?
+ assert_nothing_raised{Complex(1.0/0)}
+ end
+ end
+
+ def test_attr
+ c = Complex(4)
+
+ assert_equal(4, c.real)
+ assert_equal(0, c.imag)
+
+ c = Complex(4,5)
+
+ assert_equal(4, c.real)
+ assert_equal(5, c.imag)
+
+ if -0.0.to_s == '-0.0'
+ c = Complex(-0.0,-0.0)
+
+ assert_equal('-0.0', c.real.to_s)
+ assert_equal('-0.0', c.imag.to_s)
+ end
+
+ c = Complex(4)
+
+ assert_equal(4, c.real)
+ assert_equal(0, c.imag)
+ assert_equal(c.imag, c.imaginary)
+
+ c = Complex(4,5)
+
+ assert_equal(4, c.real)
+ assert_equal(5, c.imag)
+ assert_equal(c.imag, c.imaginary)
+
+ if -0.0.to_s == '-0.0'
+ c = Complex(-0.0,-0.0)
+
+ assert_equal('-0.0', c.real.to_s)
+ assert_equal('-0.0', c.imag.to_s)
+ assert_equal(c.imag.to_s, c.imaginary.to_s)
+ end
+
+ c = Complex(4)
+
+ assert_equal(4, c.real)
+ assert_equal(c.imag, c.imaginary)
+ assert_equal(0, c.imag)
+
+ c = Complex(4,5)
+
+ assert_equal(4, c.real)
+ assert_equal(5, c.imag)
+ assert_equal(c.imag, c.imaginary)
+
+ c = Complex(-0.0,-0.0)
+
+ assert_equal('-0.0', c.real.to_s)
+ assert_equal('-0.0', c.imag.to_s)
+ assert_equal(c.imag.to_s, c.imaginary.to_s)
+ end
+
+ def test_attr2
+ c = Complex(1)
+
+ if @unify
+=begin
+ assert_equal(true, c.finite?)
+ assert_equal(false, c.infinite?)
+ assert_equal(false, c.nan?)
+ assert_equal(true, c.integer?)
+ assert_equal(false, c.float?)
+ assert_equal(true, c.rational?)
+=end
+ assert_equal(true, c.real?)
+=begin
+ assert_equal(false, c.complex?)
+ assert_equal(true, c.exact?)
+ assert_equal(false, c.inexact?)
+=end
+ else
+=begin
+ assert_equal(true, c.finite?)
+ assert_equal(false, c.infinite?)
+ assert_equal(false, c.nan?)
+ assert_equal(false, c.integer?)
+ assert_equal(false, c.float?)
+ assert_equal(false, c.rational?)
+=end
+ assert_equal(false, c.real?)
+=begin
+ assert_equal(true, c.complex?)
+ assert_equal(true, c.exact?)
+ assert_equal(false, c.inexact?)
+=end
+ end
+
+=begin
+ assert_equal(0, Complex(0).sign)
+ assert_equal(1, Complex(2).sign)
+ assert_equal(-1, Complex(-2).sign)
+=end
+
+ assert_equal(true, Complex(0).zero?)
+ assert_equal(true, Complex(0,0).zero?)
+ assert_equal(false, Complex(1,0).zero?)
+ assert_equal(false, Complex(0,1).zero?)
+ assert_equal(false, Complex(1,1).zero?)
+
+ assert_equal(nil, Complex(0).nonzero?)
+ assert_equal(nil, Complex(0,0).nonzero?)
+ assert_equal(Complex(1,0), Complex(1,0).nonzero?)
+ assert_equal(Complex(0,1), Complex(0,1).nonzero?)
+ assert_equal(Complex(1,1), Complex(1,1).nonzero?)
+ end
+
+ def test_rect
+ assert_equal([1,2], Complex.rectangular(1,2).rectangular)
+ assert_equal([1,2], Complex.rect(1,2).rect)
+ end
+
+ def test_polar
+ assert_equal([1,2], Complex.polar(1,2).polar)
+ end
+
+ def test_uplus
+ assert_equal(Complex(1), +Complex(1))
+ assert_equal(Complex(-1), +Complex(-1))
+ assert_equal(Complex(1,1), +Complex(1,1))
+ assert_equal(Complex(-1,1), +Complex(-1,1))
+ assert_equal(Complex(1,-1), +Complex(1,-1))
+ assert_equal(Complex(-1,-1), +Complex(-1,-1))
+
+ if -0.0.to_s == '-0.0'
+ c = +Complex(0.0,0.0)
+ assert_equal('0.0', c.real.to_s)
+ assert_equal('0.0', c.imag.to_s)
+
+ c = +Complex(-0.0,-0.0)
+ assert_equal('-0.0', c.real.to_s)
+ assert_equal('-0.0', c.imag.to_s)
+ end
+ end
+
+ def test_negate
+ assert_equal(Complex(-1), -Complex(1))
+ assert_equal(Complex(1), -Complex(-1))
+ assert_equal(Complex(-1,-1), -Complex(1,1))
+ assert_equal(Complex(1,-1), -Complex(-1,1))
+ assert_equal(Complex(-1,1), -Complex(1,-1))
+ assert_equal(Complex(1,1), -Complex(-1,-1))
+
+ if -0.0.to_s == '-0.0'
+ c = -Complex(0.0,0.0)
+ assert_equal('-0.0', c.real.to_s)
+ assert_equal('-0.0', c.imag.to_s)
+
+ c = -Complex(-0.0,-0.0)
+ assert_equal('0.0', c.real.to_s)
+ assert_equal('0.0', c.imag.to_s)
+ end
+
+=begin
+ assert_equal(0, Complex(0).negate)
+ assert_equal(-2, Complex(2).negate)
+ assert_equal(2, Complex(-2).negate)
+=end
+ end
+
+ def test_add
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ assert_equal(Complex(3,5), c + c2)
+
+ assert_equal(Complex(3,2), c + 2)
+ assert_equal(Complex(3.0,2), c + 2.0)
+
+ if @rational
+ assert_equal(Complex(Rational(3,1),Rational(2)), c + Rational(2))
+ assert_equal(Complex(Rational(5,3),Rational(2)), c + Rational(2,3))
+ end
+ end
+
+ def test_sub
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ assert_equal(Complex(-1,-1), c - c2)
+
+ assert_equal(Complex(-1,2), c - 2)
+ assert_equal(Complex(-1.0,2), c - 2.0)
+
+ if @rational
+ assert_equal(Complex(Rational(-1,1),Rational(2)), c - Rational(2))
+ assert_equal(Complex(Rational(1,3),Rational(2)), c - Rational(2,3))
+ end
+ end
+
+ def test_mul
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ assert_equal(Complex(-4,7), c * c2)
+
+ assert_equal(Complex(2,4), c * 2)
+ assert_equal(Complex(2.0,4.0), c * 2.0)
+
+ if @rational
+ assert_equal(Complex(Rational(2,1),Rational(4)), c * Rational(2))
+ assert_equal(Complex(Rational(2,3),Rational(4,3)), c * Rational(2,3))
+ end
+
+ end
+
+ def test_div
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ if @rational
+ assert_equal(Complex(Rational(8,13),Rational(1,13)), c / c2)
+ else
+ r = c / c2
+ assert_in_delta(0.615, r.real, 0.001)
+ assert_in_delta(0.076, r.imag, 0.001)
+ end
+
+ c = Complex(1.0,2.0)
+ c2 = Complex(2.0,3.0)
+
+ r = c / c2
+ assert_in_delta(0.615, r.real, 0.001)
+ assert_in_delta(0.076, r.imag, 0.001)
+
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ if @rational
+ assert_equal(Complex(Rational(1,2),1), c / 2)
+ else
+ assert_equal(Complex(0.5,1.0), c / 2)
+ end
+ assert_equal(Complex(0.5,1.0), c / 2.0)
+
+ if @rational
+ assert_equal(Complex(Rational(1,2),Rational(1)), c / Rational(2))
+ assert_equal(Complex(Rational(3,2),Rational(3)), c / Rational(2,3))
+ end
+ end
+
+ def test_quo
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ if @rational
+ assert_equal(Complex(Rational(8,13),Rational(1,13)), c.quo(c2))
+ else
+ r = c.quo(c2)
+ assert_in_delta(0.615, r.real, 0.001)
+ assert_in_delta(0.076, r.imag, 0.001)
+ end
+
+ c = Complex(1.0,2.0)
+ c2 = Complex(2.0,3.0)
+
+ r = c.quo(c2)
+ assert_in_delta(0.615, r.real, 0.001)
+ assert_in_delta(0.076, r.imag, 0.001)
+
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ if @rational
+ assert_equal(Complex(Rational(1,2),1), c.quo(2))
+ else
+ assert_equal(Complex(0.5,1.0), c.quo(2))
+ end
+ assert_equal(Complex(0.5,1.0), c.quo(2.0))
+
+ if @rational
+ assert_equal(Complex(Rational(1,2),Rational(1)), c / Rational(2))
+ assert_equal(Complex(Rational(3,2),Rational(3)), c / Rational(2,3))
+ end
+ end
+
+ def test_fdiv
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ r = c.fdiv(c2)
+ assert_in_delta(0.615, r.real, 0.001)
+ assert_in_delta(0.076, r.imag, 0.001)
+
+ c = Complex(1.0,2.0)
+ c2 = Complex(2.0,3.0)
+
+ r = c.fdiv(c2)
+ assert_in_delta(0.615, r.real, 0.001)
+ assert_in_delta(0.076, r.imag, 0.001)
+
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ assert_equal(Complex(0.5,1.0), c.fdiv(2))
+ assert_equal(Complex(0.5,1.0), c.fdiv(2.0))
+ end
+
+ def test_expt
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ r = c ** c2
+ assert_in_delta(-0.015, r.real, 0.001)
+ assert_in_delta(-0.179, r.imag, 0.001)
+
+ assert_equal(Complex(-3,4), c ** 2)
+ if @rational && !@keiju
+ assert_equal(Complex(Rational(-3,25),Rational(-4,25)), c ** -2)
+ else
+ r = c ** -2
+ assert_in_delta(-0.12, r.real, 0.001)
+ assert_in_delta(-0.16, r.imag, 0.001)
+ end
+ r = c ** 2.0
+ assert_in_delta(-3.0, r.real, 0.001)
+ assert_in_delta(4.0, r.imag, 0.001)
+
+ r = c ** -2.0
+ assert_in_delta(-0.12, r.real, 0.001)
+ assert_in_delta(-0.16, r.imag, 0.001)
+
+ if @rational && !@keiju
+ assert_equal(Complex(-3,4), c ** Rational(2))
+#=begin
+ assert_equal(Complex(Rational(-3,25),Rational(-4,25)),
+ c ** Rational(-2)) # why failed?
+#=end
+
+ r = c ** Rational(2,3)
+ assert_in_delta(1.264, r.real, 0.001)
+ assert_in_delta(1.150, r.imag, 0.001)
+
+ r = c ** Rational(-2,3)
+ assert_in_delta(0.432, r.real, 0.001)
+ assert_in_delta(-0.393, r.imag, 0.001)
+ end
+ end
+
+ def test_cmp
+ assert_raise(NoMethodError){1 <=> Complex(1,1)}
+ assert_raise(NoMethodError){Complex(1,1) <=> 1}
+ assert_raise(NoMethodError){Complex(1,1) <=> Complex(1,1)}
+ end
+
+ def test_eqeq
+ assert(Complex(1,0) == Complex(1))
+ assert(Complex(-1,0) == Complex(-1))
+
+ assert_equal(false, Complex(2,1) == Complex(1))
+ assert_equal(true, Complex(2,1) != Complex(1))
+ assert_equal(false, Complex(1) == nil)
+ assert_equal(false, Complex(1) == '')
+
+ nan = 0.0 / 0
+ if nan.nan? && nan != nan
+ assert_equal(false, Complex(nan, 0) == Complex(nan, 0))
+ assert_equal(false, Complex(0, nan) == Complex(0, nan))
+ assert_equal(false, Complex(nan, nan) == Complex(nan, nan))
+ end
+ end
+
+ def test_coerce
+ assert_equal([Complex(2),Complex(1)], Complex(1).coerce(2))
+ assert_equal([Complex(2.2),Complex(1)], Complex(1).coerce(2.2))
+ assert_equal([Complex(Rational(2)),Complex(1)],
+ Complex(1).coerce(Rational(2)))
+ assert_equal([Complex(2),Complex(1)], Complex(1).coerce(Complex(2)))
+ end
+
+ def test_unify
+ if @unify
+ assert_instance_of(Fixnum, Complex(1,2) + Complex(-1,-2))
+ assert_instance_of(Fixnum, Complex(1,2) - Complex(1,2))
+ assert_instance_of(Fixnum, Complex(1,2) * 0)
+ assert_instance_of(Fixnum, Complex(1,2) / Complex(1,2))
+# assert_instance_of(Fixnum, Complex(1,2).div(Complex(1,2)))
+ assert_instance_of(Fixnum, Complex(1,2).quo(Complex(1,2)))
+# assert_instance_of(Fixnum, Complex(1,2) ** 0) # mathn's bug
+ end
+ end
+
+ def test_math
+ c = Complex(1,2)
+
+ assert_in_delta(2.236, c.abs, 0.001)
+ assert_in_delta(2.236, c.magnitude, 0.001)
+ assert_equal(5, c.abs2)
+
+ assert_equal(c.abs, Math.sqrt(c * c.conj))
+ assert_equal(c.abs, Math.sqrt(c.real**2 + c.imag**2))
+ assert_equal(c.abs2, c * c.conj)
+ assert_equal(c.abs2, c.real**2 + c.imag**2)
+
+ assert_in_delta(1.107, c.arg, 0.001)
+ assert_in_delta(1.107, c.angle, 0.001)
+ assert_in_delta(1.107, c.phase, 0.001)
+
+ r = c.polar
+ assert_in_delta(2.236, r[0], 0.001)
+ assert_in_delta(1.107, r[1], 0.001)
+ assert_equal(Complex(1,-2), c.conjugate)
+ assert_equal(Complex(1,-2), c.conj)
+# assert_equal(Complex(1,-2), ~c)
+# assert_equal(5, c * ~c)
+
+ assert_equal(Complex(1,2), c.numerator)
+ assert_equal(1, c.denominator)
+ end
+
+ def test_to_s
+ c = Complex(1,2)
+
+ assert_instance_of(String, c.to_s)
+ assert_equal('1+2i', c.to_s)
+
+ assert_equal('0+2i', Complex(0,2).to_s)
+ assert_equal('0-2i', Complex(0,-2).to_s)
+ assert_equal('1+2i', Complex(1,2).to_s)
+ assert_equal('-1+2i', Complex(-1,2).to_s)
+ assert_equal('-1-2i', Complex(-1,-2).to_s)
+ assert_equal('1-2i', Complex(1,-2).to_s)
+ assert_equal('-1-2i', Complex(-1,-2).to_s)
+
+ assert_equal('0+2.0i', Complex(0,2.0).to_s)
+ assert_equal('0-2.0i', Complex(0,-2.0).to_s)
+ assert_equal('1.0+2.0i', Complex(1.0,2.0).to_s)
+ assert_equal('-1.0+2.0i', Complex(-1.0,2.0).to_s)
+ assert_equal('-1.0-2.0i', Complex(-1.0,-2.0).to_s)
+ assert_equal('1.0-2.0i', Complex(1.0,-2.0).to_s)
+ assert_equal('-1.0-2.0i', Complex(-1.0,-2.0).to_s)
+
+ if @rational && !@unify && !@keiju
+ assert_equal('0+2/1i', Complex(0,Rational(2)).to_s)
+ assert_equal('0-2/1i', Complex(0,Rational(-2)).to_s)
+ assert_equal('1+2/1i', Complex(1,Rational(2)).to_s)
+ assert_equal('-1+2/1i', Complex(-1,Rational(2)).to_s)
+ assert_equal('-1-2/1i', Complex(-1,Rational(-2)).to_s)
+ assert_equal('1-2/1i', Complex(1,Rational(-2)).to_s)
+ assert_equal('-1-2/1i', Complex(-1,Rational(-2)).to_s)
+
+ assert_equal('0+2/3i', Complex(0,Rational(2,3)).to_s)
+ assert_equal('0-2/3i', Complex(0,Rational(-2,3)).to_s)
+ assert_equal('1+2/3i', Complex(1,Rational(2,3)).to_s)
+ assert_equal('-1+2/3i', Complex(-1,Rational(2,3)).to_s)
+ assert_equal('-1-2/3i', Complex(-1,Rational(-2,3)).to_s)
+ assert_equal('1-2/3i', Complex(1,Rational(-2,3)).to_s)
+ assert_equal('-1-2/3i', Complex(-1,Rational(-2,3)).to_s)
+ end
+
+ nan = 0.0 / 0
+ inf = 1.0 / 0
+ if nan.nan?
+ assert_equal('NaN+NaN*i', Complex(nan,nan).to_s)
+ end
+ if inf.infinite?
+ assert_equal('Infinity+Infinity*i', Complex(inf,inf).to_s)
+ assert_equal('Infinity-Infinity*i', Complex(inf,-inf).to_s)
+ end
+ end
+
+ def test_inspect
+ c = Complex(1,2)
+
+ assert_instance_of(String, c.inspect)
+ assert_equal('(1+2i)', c.inspect)
+ end
+
+ def test_marshal
+ c = Complex(1,2)
+ c.instance_eval{@ivar = 9}
+
+ s = Marshal.dump(c)
+ c2 = Marshal.load(s)
+ assert_equal(c, c2)
+ assert_equal(9, c2.instance_variable_get(:@ivar))
+ assert_instance_of(Complex, c2)
+
+ if @rational
+ c = Complex(Rational(1,2),Rational(2,3))
+
+ s = Marshal.dump(c)
+ c2 = Marshal.load(s)
+ assert_equal(c, c2)
+ assert_instance_of(Complex, c2)
+ end
+
+ bug3656 = '[ruby-core:31622]'
+ assert_raise(TypeError, bug3656) {
+ Complex(1,2).marshal_load(0)
+ }
+ end
+
+ def test_parse
+ assert_equal(Complex(5), '5'.to_c)
+ assert_equal(Complex(-5), '-5'.to_c)
+ assert_equal(Complex(5,3), '5+3i'.to_c)
+ assert_equal(Complex(-5,3), '-5+3i'.to_c)
+ assert_equal(Complex(5,-3), '5-3i'.to_c)
+ assert_equal(Complex(-5,-3), '-5-3i'.to_c)
+ assert_equal(Complex(0,3), '3i'.to_c)
+ assert_equal(Complex(0,-3), '-3i'.to_c)
+ assert_equal(Complex(5,1), '5+i'.to_c)
+ assert_equal(Complex(0,1), 'i'.to_c)
+ assert_equal(Complex(0,1), '+i'.to_c)
+ assert_equal(Complex(0,-1), '-i'.to_c)
+
+ assert_equal(Complex(5,3), '5+3I'.to_c)
+ assert_equal(Complex(5,3), '5+3j'.to_c)
+ assert_equal(Complex(5,3), '5+3J'.to_c)
+ assert_equal(Complex(0,3), '3I'.to_c)
+ assert_equal(Complex(0,3), '3j'.to_c)
+ assert_equal(Complex(0,3), '3J'.to_c)
+ assert_equal(Complex(0,1), 'I'.to_c)
+ assert_equal(Complex(0,1), 'J'.to_c)
+
+ assert_equal(Complex(5.0), '5.0'.to_c)
+ assert_equal(Complex(-5.0), '-5.0'.to_c)
+ assert_equal(Complex(5.0,3.0), '5.0+3.0i'.to_c)
+ assert_equal(Complex(-5.0,3.0), '-5.0+3.0i'.to_c)
+ assert_equal(Complex(5.0,-3.0), '5.0-3.0i'.to_c)
+ assert_equal(Complex(-5.0,-3.0), '-5.0-3.0i'.to_c)
+ assert_equal(Complex(0.0,3.0), '3.0i'.to_c)
+ assert_equal(Complex(0.0,-3.0), '-3.0i'.to_c)
+
+ assert_equal(Complex(5.0), '5e0'.to_c)
+ assert_equal(Complex(-5.0), '-5e0'.to_c)
+ assert_equal(Complex(5.0,3.0), '5e0+3e0i'.to_c)
+ assert_equal(Complex(-5.0,3.0), '-5e0+3e0i'.to_c)
+ assert_equal(Complex(5.0,-3.0), '5e0-3e0i'.to_c)
+ assert_equal(Complex(-5.0,-3.0), '-5e0-3e0i'.to_c)
+ assert_equal(Complex(0.0,3.0), '3e0i'.to_c)
+ assert_equal(Complex(0.0,-3.0), '-3e0i'.to_c)
+
+ assert_equal(Complex(0.33), '.33'.to_c)
+ assert_equal(Complex(0.33), '0.33'.to_c)
+ assert_equal(Complex(-0.33), '-.33'.to_c)
+ assert_equal(Complex(-0.33), '-0.33'.to_c)
+ assert_equal(Complex(-0.33), '-0.3_3'.to_c)
+
+ assert_equal(Complex.polar(10,10), '10 at 10'.to_c)
+ assert_equal(Complex.polar(-10,-10), '-10 at -10'.to_c)
+ assert_equal(Complex.polar(10.5,10.5), '10.5 at 10.5'.to_c)
+ assert_equal(Complex.polar(-10.5,-10.5), '-10.5 at -10.5'.to_c)
+
+ assert_equal(Complex(5), Complex('5'))
+ assert_equal(Complex(-5), Complex('-5'))
+ assert_equal(Complex(5,3), Complex('5+3i'))
+ assert_equal(Complex(-5,3), Complex('-5+3i'))
+ assert_equal(Complex(5,-3), Complex('5-3i'))
+ assert_equal(Complex(-5,-3), Complex('-5-3i'))
+ assert_equal(Complex(0,3), Complex('3i'))
+ assert_equal(Complex(0,-3), Complex('-3i'))
+ assert_equal(Complex(5,1), Complex('5+i'))
+ assert_equal(Complex(0,1), Complex('i'))
+ assert_equal(Complex(0,1), Complex('+i'))
+ assert_equal(Complex(0,-1), Complex('-i'))
+
+ assert_equal(Complex(5,3), Complex('5+3I'))
+ assert_equal(Complex(5,3), Complex('5+3j'))
+ assert_equal(Complex(5,3), Complex('5+3J'))
+ assert_equal(Complex(0,3), Complex('3I'))
+ assert_equal(Complex(0,3), Complex('3j'))
+ assert_equal(Complex(0,3), Complex('3J'))
+ assert_equal(Complex(0,1), Complex('I'))
+ assert_equal(Complex(0,1), Complex('J'))
+
+ assert_equal(Complex(5.0), Complex('5.0'))
+ assert_equal(Complex(-5.0), Complex('-5.0'))
+ assert_equal(Complex(5.0,3.0), Complex('5.0+3.0i'))
+ assert_equal(Complex(-5.0,3.0), Complex('-5.0+3.0i'))
+ assert_equal(Complex(5.0,-3.0), Complex('5.0-3.0i'))
+ assert_equal(Complex(-5.0,-3.0), Complex('-5.0-3.0i'))
+ assert_equal(Complex(0.0,3.0), Complex('3.0i'))
+ assert_equal(Complex(0.0,-3.0), Complex('-3.0i'))
+
+ assert_equal(Complex(5.0), Complex('5e0'))
+ assert_equal(Complex(-5.0), Complex('-5e0'))
+ assert_equal(Complex(5.0,3.0), Complex('5e0+3e0i'))
+ assert_equal(Complex(-5.0,3.0), Complex('-5e0+3e0i'))
+ assert_equal(Complex(5.0,-3.0), Complex('5e0-3e0i'))
+ assert_equal(Complex(-5.0,-3.0), Complex('-5e0-3e0i'))
+ assert_equal(Complex(0.0,3.0), Complex('3e0i'))
+ assert_equal(Complex(0.0,-3.0), Complex('-3e0i'))
+
+ assert_equal(Complex(0.33), Complex('.33'))
+ assert_equal(Complex(0.33), Complex('0.33'))
+ assert_equal(Complex(-0.33), Complex('-.33'))
+ assert_equal(Complex(-0.33), Complex('-0.33'))
+ assert_equal(Complex(-0.33), Complex('-0.3_3'))
+
+ assert_equal(Complex.polar(10,10), Complex('10 at 10'))
+ assert_equal(Complex.polar(-10,-10), Complex('-10 at -10'))
+ assert_equal(Complex.polar(10.5,10.5), Complex('10.5 at 10.5'))
+ assert_equal(Complex.polar(-10.5,-10.5), Complex('-10.5 at -10.5'))
+
+ assert_equal(Complex(0), ''.to_c)
+ assert_equal(Complex(0), ' '.to_c)
+ assert_equal(Complex(5), "\f\n\r\t\v5\0".to_c)
+ assert_equal(Complex(0), '_'.to_c)
+ assert_equal(Complex(0), '_5'.to_c)
+ assert_equal(Complex(5), '5_'.to_c)
+ assert_equal(Complex(5), '5x'.to_c)
+ assert_equal(Complex(5), '5+_3i'.to_c)
+ assert_equal(Complex(5), '5+3_i'.to_c)
+ assert_equal(Complex(5,3), '5+3i_'.to_c)
+ assert_equal(Complex(5,3), '5+3ix'.to_c)
+ assert_raise(ArgumentError){ Complex('')}
+ assert_raise(ArgumentError){ Complex('_')}
+ assert_raise(ArgumentError){ Complex("\f\n\r\t\v5\0")}
+ assert_raise(ArgumentError){ Complex('_5')}
+ assert_raise(ArgumentError){ Complex('5_')}
+ assert_raise(ArgumentError){ Complex('5x')}
+ assert_raise(ArgumentError){ Complex('5+_3i')}
+ assert_raise(ArgumentError){ Complex('5+3_i')}
+ assert_raise(ArgumentError){ Complex('5+3i_')}
+ assert_raise(ArgumentError){ Complex('5+3ix')}
+
+ if @rational && defined?(''.to_r)
+ assert_equal(Complex(Rational(1,5)), '1/5'.to_c)
+ assert_equal(Complex(Rational(-1,5)), '-1/5'.to_c)
+ assert_equal(Complex(Rational(1,5),3), '1/5+3i'.to_c)
+ assert_equal(Complex(Rational(1,5),-3), '1/5-3i'.to_c)
+ assert_equal(Complex(Rational(-1,5),3), '-1/5+3i'.to_c)
+ assert_equal(Complex(Rational(-1,5),-3), '-1/5-3i'.to_c)
+ assert_equal(Complex(Rational(1,5),Rational(3,2)), '1/5+3/2i'.to_c)
+ assert_equal(Complex(Rational(1,5),Rational(-3,2)), '1/5-3/2i'.to_c)
+ assert_equal(Complex(Rational(-1,5),Rational(3,2)), '-1/5+3/2i'.to_c)
+ assert_equal(Complex(Rational(-1,5),Rational(-3,2)), '-1/5-3/2i'.to_c)
+ assert_equal(Complex(Rational(1,5),Rational(3,2)), '1/5+3/2i'.to_c)
+ assert_equal(Complex(Rational(1,5),Rational(-3,2)), '1/5-3/2i'.to_c)
+ assert_equal(Complex(Rational(-1,5),Rational(3,2)), '-1/5+3/2i'.to_c)
+ assert_equal(Complex(Rational(-1,5),Rational(-3,2)), '-1/5-3/2i'.to_c)
+ assert_equal(Complex.polar(Rational(1,5),Rational(3,2)), Complex('1/5 at 3/2'))
+ assert_equal(Complex.polar(Rational(-1,5),Rational(-3,2)), Complex('-1/5 at -3/2'))
+ end
+
+ end
+
+ def test_respond
+ c = Complex(1,1)
+ assert_equal(false, c.respond_to?(:%))
+ assert_equal(false, c.respond_to?(:<))
+ assert_equal(false, c.respond_to?(:<=))
+ assert_equal(false, c.respond_to?(:<=>))
+ assert_equal(false, c.respond_to?(:>))
+ assert_equal(false, c.respond_to?(:>=))
+ assert_equal(false, c.respond_to?(:between?))
+ assert_equal(false, c.respond_to?(:div))
+ assert_equal(false, c.respond_to?(:divmod))
+ assert_equal(false, c.respond_to?(:floor))
+ assert_equal(false, c.respond_to?(:ceil))
+ assert_equal(false, c.respond_to?(:modulo))
+ assert_equal(false, c.respond_to?(:remainder))
+ assert_equal(false, c.respond_to?(:round))
+ assert_equal(false, c.respond_to?(:step))
+ assert_equal(false, c.respond_to?(:tunrcate))
+
+ assert_equal(false, c.respond_to?(:positive?))
+ assert_equal(false, c.respond_to?(:negative?))
+# assert_equal(false, c.respond_to?(:sign))
+
+ assert_equal(false, c.respond_to?(:quotient))
+ assert_equal(false, c.respond_to?(:quot))
+ assert_equal(false, c.respond_to?(:quotrem))
+
+ assert_equal(false, c.respond_to?(:gcd))
+ assert_equal(false, c.respond_to?(:lcm))
+ assert_equal(false, c.respond_to?(:gcdlcm))
+ end
+
+ def test_to_i
+ assert_equal(3, Complex(3).to_i)
+ assert_equal(3, Integer(Complex(3)))
+ assert_raise(RangeError){Complex(3,2).to_i}
+ assert_raise(RangeError){Integer(Complex(3,2))}
+ end
+
+ def test_to_f
+ assert_equal(3.0, Complex(3).to_f)
+ assert_equal(3.0, Float(Complex(3)))
+ assert_raise(RangeError){Complex(3,2).to_f}
+ assert_raise(RangeError){Float(Complex(3,2))}
+ end
+
+ def test_to_r
+ if @rational && !@keiju
+ assert_equal(Rational(3), Complex(3).to_r)
+ assert_equal(Rational(3), Rational(Complex(3)))
+ assert_raise(RangeError){Complex(3,2).to_r}
+# assert_raise(RangeError){Rational(Complex(3,2))}
+ end
+ end
+
+ def test_to_c
+ c = nil.to_c
+ assert_equal([0,0], [c.real, c.imag])
+
+ c = 0.to_c
+ assert_equal([0,0], [c.real, c.imag])
+
+ c = 1.to_c
+ assert_equal([1,0], [c.real, c.imag])
+
+ c = 1.1.to_c
+ assert_equal([1.1, 0], [c.real, c.imag])
+
+ if @rational
+ c = Rational(1,2).to_c
+ assert_equal([Rational(1,2), 0], [c.real, c.imag])
+ end
+
+ c = Complex(1,2).to_c
+ assert_equal([1, 2], [c.real, c.imag])
+
+ if (0.0/0).nan?
+ assert_nothing_raised{(0.0/0).to_c}
+ end
+ if (1.0/0).infinite?
+ assert_nothing_raised{(1.0/0).to_c}
+ end
+ end
+
+ def test_supp
+ assert_equal(true, 1.real?)
+ assert_equal(true, 1.1.real?)
+
+ assert_equal(1, 1.real)
+ assert_equal(0, 1.imag)
+ assert_equal(0, 1.imaginary)
+
+ assert_equal(1.1, 1.1.real)
+ assert_equal(0, 1.1.imag)
+ assert_equal(0, 1.1.imaginary)
+
+ assert_equal(1, 1.magnitude)
+ assert_equal(1, -1.magnitude)
+ assert_equal(1, 1.0.magnitude)
+ assert_equal(1, -1.0.magnitude)
+
+ assert_equal(4, 2.abs2)
+ assert_equal(4, -2.abs2)
+ assert_equal(4.0, 2.0.abs2)
+ assert_equal(4.0, -2.0.abs2)
+
+ assert_equal(0, 1.arg)
+ assert_equal(0, 1.angle)
+ assert_equal(0, 1.phase)
+
+ assert_equal(0, 1.0.arg)
+ assert_equal(0, 1.0.angle)
+ assert_equal(0, 1.0.phase)
+
+ if (0.0/0).nan?
+ nan = 0.0/0
+ assert(nan.arg.equal?(nan))
+ assert(nan.angle.equal?(nan))
+ assert(nan.phase.equal?(nan))
+ end
+
+ assert_equal(Math::PI, -1.arg)
+ assert_equal(Math::PI, -1.angle)
+ assert_equal(Math::PI, -1.phase)
+
+ assert_equal(Math::PI, -1.0.arg)
+ assert_equal(Math::PI, -1.0.angle)
+ assert_equal(Math::PI, -1.0.phase)
+
+ assert_equal([1,0], 1.rect)
+ assert_equal([-1,0], -1.rect)
+ assert_equal([1,0], 1.rectangular)
+ assert_equal([-1,0], -1.rectangular)
+
+ assert_equal([1.0,0], 1.0.rect)
+ assert_equal([-1.0,0], -1.0.rect)
+ assert_equal([1.0,0], 1.0.rectangular)
+ assert_equal([-1.0,0], -1.0.rectangular)
+
+ assert_equal([1,0], 1.polar)
+ assert_equal([1, Math::PI], -1.polar)
+
+ assert_equal([1.0,0], 1.0.polar)
+ assert_equal([1.0, Math::PI], -1.0.polar)
+
+ assert_equal(1, 1.conjugate)
+ assert_equal(-1, -1.conjugate)
+ assert_equal(1, 1.conj)
+ assert_equal(-1, -1.conj)
+
+ assert_equal(1.1, 1.1.conjugate)
+ assert_equal(-1.1, -1.1.conjugate)
+ assert_equal(1.1, 1.1.conj)
+ assert_equal(-1.1, -1.1.conj)
+
+ if @rational
+ assert_equal(Complex(Rational(1,2),Rational(1)), Complex(1,2).quo(2))
+ else
+ assert_equal(Complex(0.5,1.0), Complex(1,2).quo(2))
+ end
+
+=begin
+ if @rational && !@keiju
+ assert_equal(Complex(Rational(1,2),Rational(1)), Complex(1,2).quo(2))
+ end
+=end
+
+ assert_equal(0.5, 1.fdiv(2))
+ assert_equal(5000000000.0, 10000000000.fdiv(2))
+ assert_equal(0.5, 1.0.fdiv(2))
+ if @rational
+ assert_equal(0.25, Rational(1,2).fdiv(2))
+ end
+ assert_equal(Complex(0.5,1.0), Complex(1,2).quo(2))
+
+ unless $".grep(/(\A|\/)complex/).empty?
+ assert_equal(Complex(0,2), Math.sqrt(-4.0))
+# assert_equal(true, Math.sqrt(-4.0).inexact?)
+ assert_equal(Complex(0,2), Math.sqrt(-4))
+# assert_equal(true, Math.sqrt(-4).exact?)
+ if @rational
+ assert_equal(Complex(0,2), Math.sqrt(Rational(-4)))
+# assert_equal(true, Math.sqrt(Rational(-4)).exact?)
+ end
+
+ assert_equal(Complex(0,3), Math.sqrt(-9.0))
+# assert_equal(true, Math.sqrt(-9.0).inexact?)
+ assert_equal(Complex(0,3), Math.sqrt(-9))
+# assert_equal(true, Math.sqrt(-9).exact?)
+ if @rational
+ assert_equal(Complex(0,3), Math.sqrt(Rational(-9)))
+# assert_equal(true, Math.sqrt(Rational(-9)).exact?)
+ end
+
+ c = Math.sqrt(Complex(1, 2))
+ assert_in_delta(1.272, c.real, 0.001)
+ assert_in_delta(0.786, c.imag, 0.001)
+
+ c = Math.sqrt(-9)
+ assert_in_delta(0.0, c.real, 0.001)
+ assert_in_delta(3.0, c.imag, 0.001)
+
+ c = Math.exp(Complex(1, 2))
+ assert_in_delta(-1.131, c.real, 0.001)
+ assert_in_delta(2.471, c.imag, 0.001)
+
+ c = Math.sin(Complex(1, 2))
+ assert_in_delta(3.165, c.real, 0.001)
+ assert_in_delta(1.959, c.imag, 0.001)
+
+ c = Math.cos(Complex(1, 2))
+ assert_in_delta(2.032, c.real, 0.001)
+ assert_in_delta(-3.051, c.imag, 0.001)
+
+ c = Math.tan(Complex(1, 2))
+ assert_in_delta(0.033, c.real, 0.001)
+ assert_in_delta(1.014, c.imag, 0.001)
+
+ c = Math.sinh(Complex(1, 2))
+ assert_in_delta(-0.489, c.real, 0.001)
+ assert_in_delta(1.403, c.imag, 0.001)
+
+ c = Math.cosh(Complex(1, 2))
+ assert_in_delta(-0.642, c.real, 0.001)
+ assert_in_delta(1.068, c.imag, 0.001)
+
+ c = Math.tanh(Complex(1, 2))
+ assert_in_delta(1.166, c.real, 0.001)
+ assert_in_delta(-0.243, c.imag, 0.001)
+
+ c = Math.log(Complex(1, 2))
+ assert_in_delta(0.804, c.real, 0.001)
+ assert_in_delta(1.107, c.imag, 0.001)
+
+ c = Math.log(Complex(1, 2), Math::E)
+ assert_in_delta(0.804, c.real, 0.001)
+ assert_in_delta(1.107, c.imag, 0.001)
+
+ c = Math.log(-1)
+ assert_in_delta(0.0, c.real, 0.001)
+ assert_in_delta(Math::PI, c.imag, 0.001)
+
+ c = Math.log(8, 2)
+ assert_in_delta(3.0, c.real, 0.001)
+ assert_in_delta(0.0, c.imag, 0.001)
+
+ c = Math.log(-8, -2)
+ assert_in_delta(1.092, c.real, 0.001)
+ assert_in_delta(-0.420, c.imag, 0.001)
+
+ c = Math.log10(Complex(1, 2))
+ assert_in_delta(0.349, c.real, 0.001)
+ assert_in_delta(0.480, c.imag, 0.001)
+
+ c = Math.asin(Complex(1, 2))
+ assert_in_delta(0.427, c.real, 0.001)
+ assert_in_delta(1.528, c.imag, 0.001)
+
+ c = Math.acos(Complex(1, 2))
+ assert_in_delta(1.143, c.real, 0.001)
+ assert_in_delta(-1.528, c.imag, 0.001)
+
+ c = Math.atan(Complex(1, 2))
+ assert_in_delta(1.338, c.real, 0.001)
+ assert_in_delta(0.402, c.imag, 0.001)
+
+ c = Math.atan2(Complex(1, 2), 1)
+ assert_in_delta(1.338, c.real, 0.001)
+ assert_in_delta(0.402, c.imag, 0.001)
+
+ c = Math.asinh(Complex(1, 2))
+ assert_in_delta(1.469, c.real, 0.001)
+ assert_in_delta(1.063, c.imag, 0.001)
+
+ c = Math.acosh(Complex(1, 2))
+ assert_in_delta(1.528, c.real, 0.001)
+ assert_in_delta(1.143, c.imag, 0.001)
+
+ c = Math.atanh(Complex(1, 2))
+ assert_in_delta(0.173, c.real, 0.001)
+ assert_in_delta(1.178, c.imag, 0.001)
+ end
+
+ end
+
+ def test_ruby19
+ assert_raise(NoMethodError){ Complex.new(1) }
+ assert_raise(NoMethodError){ Complex.new!(1) }
+ assert_raise(NoMethodError){ Complex.reduce(1) }
+ end
+
+ def test_fixed_bug
+ if @rational && !@keiju
+ assert_equal(Complex(1), 1 ** Complex(1))
+ end
+ assert_equal('-1.0-0.0i', Complex(-1.0, -0.0).to_s)
+ end
+
+ def test_known_bug
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_complex2.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_complex2.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_complex2.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,736 @@
+require 'test/unit'
+
+class Complex_Test2 < Test::Unit::TestCase
+
+ def test_kumi
+ skip("[BUG : #???] Segfault")
+ return unless defined?(Rational)
+
+ assert_equal(Complex(1, 0), +Complex(1, 0))
+ assert_equal(Complex(-1, 0), -Complex(1, 0))
+ assert_equal(Complex(2, 0),
+ Complex(1, 0) + Complex(1, 0))
+ assert_equal(Complex(0, 0),
+ Complex(1, 0) - Complex(1, 0))
+ assert_equal(Complex(1, 0),
+ Complex(1, 0) * Complex(1, 0))
+ assert_equal(Complex(1, 0),
+ Complex(1, 0) / Complex(1, 0))
+ assert_equal(Complex(1073741790, 0),
+ Complex(1, 0) + Complex(1073741789, 0))
+ assert_equal(Complex(-1073741788, 0),
+ Complex(1, 0) - Complex(1073741789, 0))
+ assert_equal(Complex(1073741789, 0),
+ Complex(1, 0) * Complex(1073741789, 0))
+ assert_equal(Complex(Rational(1, 1073741789), 0),
+ Complex(1, 0) / Complex(1073741789, 0))
+ assert_equal(Complex(1073741828, 0),
+ Complex(1, 0) + Complex(1073741827, 0))
+ assert_equal(Complex(-1073741826, 0),
+ Complex(1, 0) - Complex(1073741827, 0))
+ assert_equal(Complex(1073741827, 0),
+ Complex(1, 0) * Complex(1073741827, 0))
+ assert_equal(Complex(Rational(1, 1073741827), 0),
+ Complex(1, 0) / Complex(1073741827, 0))
+ assert_equal(Complex(1073741790, 1073741789),
+ Complex(1, 0) + Complex(1073741789, 1073741789))
+ assert_equal(Complex(-1073741788, -1073741789),
+ Complex(1, 0) - Complex(1073741789, 1073741789))
+ assert_equal(Complex(1073741789, 1073741789),
+ Complex(1, 0) * Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(1, 2147483578), Rational(-1, 2147483578)),
+ Complex(1, 0) / Complex(1073741789, 1073741789))
+ assert_equal(Complex(1073741790, 1073741827),
+ Complex(1, 0) + Complex(1073741789, 1073741827))
+ assert_equal(Complex(-1073741788, -1073741827),
+ Complex(1, 0) - Complex(1073741789, 1073741827))
+ assert_equal(Complex(1073741789, 1073741827),
+ Complex(1, 0) * Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(1073741789, 2305842940494218450), Rational(-1073741827, 2305842940494218450)),
+ Complex(1, 0) / Complex(1073741789, 1073741827))
+ assert_equal(Complex(1073741828, 1073741827),
+ Complex(1, 0) + Complex(1073741827, 1073741827))
+ assert_equal(Complex(-1073741826, -1073741827),
+ Complex(1, 0) - Complex(1073741827, 1073741827))
+ assert_equal(Complex(1073741827, 1073741827),
+ Complex(1, 0) * Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1, 2147483654), Rational(-1, 2147483654)),
+ Complex(1, 0) / Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(2147483616, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(1, 0) + Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(38, 1073741827), Rational(-1073741789, 1073741827)),
+ Complex(1, 0) - Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(1, 0) * Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1073741827, 2147483578), Rational(-1073741827, 2147483578)),
+ Complex(1, 0) / Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(2147483616, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(1, 0) + Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-38, 1073741789), Rational(-1073741827, 1073741789)),
+ Complex(1, 0) - Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(1, 0) * Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1073741789, 2147483654), Rational(-1073741789, 2147483654)),
+ Complex(1, 0) / Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(2147483616, 1073741827), Rational(1073741827, 1073741789)),
+ Complex(1, 0) + Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(38, 1073741827), Rational(-1073741827, 1073741789)),
+ Complex(1, 0) - Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)),
+ Complex(1, 0) * Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1329227869515035739611240300898290063, 2658455833113515253509575011810600482), Rational(-1329227963598474519442525600436190287, 2658455833113515253509575011810600482)),
+ Complex(1, 0) / Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(1073741789, 0), +Complex(1073741789, 0))
+ assert_equal(Complex(-1073741789, 0), -Complex(1073741789, 0))
+ assert_equal(Complex(1073741790, 0),
+ Complex(1073741789, 0) + Complex(1, 0))
+ assert_equal(Complex(1073741788, 0),
+ Complex(1073741789, 0) - Complex(1, 0))
+ assert_equal(Complex(1073741789, 0),
+ Complex(1073741789, 0) * Complex(1, 0))
+ assert_equal(Complex(1073741789, 0),
+ Complex(1073741789, 0) / Complex(1, 0))
+ assert_equal(Complex(2147483578, 0),
+ Complex(1073741789, 0) + Complex(1073741789, 0))
+ assert_equal(Complex(0, 0),
+ Complex(1073741789, 0) - Complex(1073741789, 0))
+ assert_equal(Complex(1152921429444920521, 0),
+ Complex(1073741789, 0) * Complex(1073741789, 0))
+ assert_equal(Complex(1, 0),
+ Complex(1073741789, 0) / Complex(1073741789, 0))
+ assert_equal(Complex(2147483616, 0),
+ Complex(1073741789, 0) + Complex(1073741827, 0))
+ assert_equal(Complex(-38, 0),
+ Complex(1073741789, 0) - Complex(1073741827, 0))
+ assert_equal(Complex(1152921470247108503, 0),
+ Complex(1073741789, 0) * Complex(1073741827, 0))
+ assert_equal(Complex(Rational(1073741789, 1073741827), 0),
+ Complex(1073741789, 0) / Complex(1073741827, 0))
+ assert_equal(Complex(2147483578, 1073741789),
+ Complex(1073741789, 0) + Complex(1073741789, 1073741789))
+ assert_equal(Complex(0, -1073741789),
+ Complex(1073741789, 0) - Complex(1073741789, 1073741789))
+ assert_equal(Complex(1152921429444920521, 1152921429444920521),
+ Complex(1073741789, 0) * Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(1, 2), Rational(-1, 2)),
+ Complex(1073741789, 0) / Complex(1073741789, 1073741789))
+ assert_equal(Complex(2147483578, 1073741827),
+ Complex(1073741789, 0) + Complex(1073741789, 1073741827))
+ assert_equal(Complex(0, -1073741827),
+ Complex(1073741789, 0) - Complex(1073741789, 1073741827))
+ assert_equal(Complex(1152921429444920521, 1152921470247108503),
+ Complex(1073741789, 0) * Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(1152921429444920521, 2305842940494218450), Rational(-1152921470247108503, 2305842940494218450)),
+ Complex(1073741789, 0) / Complex(1073741789, 1073741827))
+ assert_equal(Complex(2147483616, 1073741827),
+ Complex(1073741789, 0) + Complex(1073741827, 1073741827))
+ assert_equal(Complex(-38, -1073741827),
+ Complex(1073741789, 0) - Complex(1073741827, 1073741827))
+ assert_equal(Complex(1152921470247108503, 1152921470247108503),
+ Complex(1073741789, 0) * Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1073741789, 2147483654), Rational(-1073741789, 2147483654)),
+ Complex(1073741789, 0) / Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1152921471320850292, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(1073741789, 0) + Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921469173366714, 1073741827), Rational(-1073741789, 1073741827)),
+ Complex(1073741789, 0) - Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921429444920521, 1073741827), Rational(1152921429444920521, 1073741827)),
+ Complex(1073741789, 0) * Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1073741827, 2), Rational(-1073741827, 2)),
+ Complex(1073741789, 0) / Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921430518662348, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(1073741789, 0) + Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921428371178694, 1073741789), Rational(-1073741827, 1073741789)),
+ Complex(1073741789, 0) - Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(1073741827, 1073741827),
+ Complex(1073741789, 0) * Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921429444920521, 2147483654), Rational(-1152921429444920521, 2147483654)),
+ Complex(1073741789, 0) / Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921471320850292, 1073741827), Rational(1073741827, 1073741789)),
+ Complex(1073741789, 0) + Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921469173366714, 1073741827), Rational(-1073741827, 1073741789)),
+ Complex(1073741789, 0) - Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921429444920521, 1073741827), 1073741827),
+ Complex(1073741789, 0) * Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1427247510601733037449111325195428279286542707, 2658455833113515253509575011810600482), Rational(-1427247611623052908177132720890654139107803443, 2658455833113515253509575011810600482)),
+ Complex(1073741789, 0) / Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(1073741827, 0), +Complex(1073741827, 0))
+ assert_equal(Complex(-1073741827, 0), -Complex(1073741827, 0))
+ assert_equal(Complex(1073741828, 0),
+ Complex(1073741827, 0) + Complex(1, 0))
+ assert_equal(Complex(1073741826, 0),
+ Complex(1073741827, 0) - Complex(1, 0))
+ assert_equal(Complex(1073741827, 0),
+ Complex(1073741827, 0) * Complex(1, 0))
+ assert_equal(Complex(1073741827, 0),
+ Complex(1073741827, 0) / Complex(1, 0))
+ assert_equal(Complex(2147483616, 0),
+ Complex(1073741827, 0) + Complex(1073741789, 0))
+ assert_equal(Complex(38, 0),
+ Complex(1073741827, 0) - Complex(1073741789, 0))
+ assert_equal(Complex(1152921470247108503, 0),
+ Complex(1073741827, 0) * Complex(1073741789, 0))
+ assert_equal(Complex(Rational(1073741827, 1073741789), 0),
+ Complex(1073741827, 0) / Complex(1073741789, 0))
+ assert_equal(Complex(2147483654, 0),
+ Complex(1073741827, 0) + Complex(1073741827, 0))
+ assert_equal(Complex(0, 0),
+ Complex(1073741827, 0) - Complex(1073741827, 0))
+ assert_equal(Complex(1152921511049297929, 0),
+ Complex(1073741827, 0) * Complex(1073741827, 0))
+ assert_equal(Complex(1, 0),
+ Complex(1073741827, 0) / Complex(1073741827, 0))
+ assert_equal(Complex(2147483616, 1073741789),
+ Complex(1073741827, 0) + Complex(1073741789, 1073741789))
+ assert_equal(Complex(38, -1073741789),
+ Complex(1073741827, 0) - Complex(1073741789, 1073741789))
+ assert_equal(Complex(1152921470247108503, 1152921470247108503),
+ Complex(1073741827, 0) * Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(1073741827, 2147483578), Rational(-1073741827, 2147483578)),
+ Complex(1073741827, 0) / Complex(1073741789, 1073741789))
+ assert_equal(Complex(2147483616, 1073741827),
+ Complex(1073741827, 0) + Complex(1073741789, 1073741827))
+ assert_equal(Complex(38, -1073741827),
+ Complex(1073741827, 0) - Complex(1073741789, 1073741827))
+ assert_equal(Complex(1152921470247108503, 1152921511049297929),
+ Complex(1073741827, 0) * Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(1152921470247108503, 2305842940494218450), Rational(-1152921511049297929, 2305842940494218450)),
+ Complex(1073741827, 0) / Complex(1073741789, 1073741827))
+ assert_equal(Complex(2147483654, 1073741827),
+ Complex(1073741827, 0) + Complex(1073741827, 1073741827))
+ assert_equal(Complex(0, -1073741827),
+ Complex(1073741827, 0) - Complex(1073741827, 1073741827))
+ assert_equal(Complex(1152921511049297929, 1152921511049297929),
+ Complex(1073741827, 0) * Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1, 2), Rational(-1, 2)),
+ Complex(1073741827, 0) / Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1152921512123039718, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(1073741827, 0) + Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921509975556140, 1073741827), Rational(-1073741789, 1073741827)),
+ Complex(1073741827, 0) - Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(1073741789, 1073741789),
+ Complex(1073741827, 0) * Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921511049297929, 2147483578), Rational(-1152921511049297929, 2147483578)),
+ Complex(1073741827, 0) / Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921471320850330, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(1073741827, 0) + Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921469173366676, 1073741789), Rational(-1073741827, 1073741789)),
+ Complex(1073741827, 0) - Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921511049297929, 1073741789), Rational(1152921511049297929, 1073741789)),
+ Complex(1073741827, 0) * Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1073741789, 2), Rational(-1073741789, 2)),
+ Complex(1073741827, 0) / Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921512123039718, 1073741827), Rational(1073741827, 1073741789)),
+ Complex(1073741827, 0) + Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921509975556140, 1073741827), Rational(-1073741827, 1073741789)),
+ Complex(1073741827, 0) - Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(1073741789, Rational(1152921511049297929, 1073741789)),
+ Complex(1073741827, 0) * Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1427247561112392079020469430422559713421565101, 2658455833113515253509575011810600482), Rational(-1427247662133715524919164459706626955683034349, 2658455833113515253509575011810600482)),
+ Complex(1073741827, 0) / Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(1073741789, 1073741789), +Complex(1073741789, 1073741789))
+ assert_equal(Complex(-1073741789, -1073741789), -Complex(1073741789, 1073741789))
+ assert_equal(Complex(1073741790, 1073741789),
+ Complex(1073741789, 1073741789) + Complex(1, 0))
+ assert_equal(Complex(1073741788, 1073741789),
+ Complex(1073741789, 1073741789) - Complex(1, 0))
+ assert_equal(Complex(1073741789, 1073741789),
+ Complex(1073741789, 1073741789) * Complex(1, 0))
+ assert_equal(Complex(1073741789, 1073741789),
+ Complex(1073741789, 1073741789) / Complex(1, 0))
+ assert_equal(Complex(2147483578, 1073741789),
+ Complex(1073741789, 1073741789) + Complex(1073741789, 0))
+ assert_equal(Complex(0, 1073741789),
+ Complex(1073741789, 1073741789) - Complex(1073741789, 0))
+ assert_equal(Complex(1152921429444920521, 1152921429444920521),
+ Complex(1073741789, 1073741789) * Complex(1073741789, 0))
+ assert_equal(Complex(1, 1),
+ Complex(1073741789, 1073741789) / Complex(1073741789, 0))
+ assert_equal(Complex(2147483616, 1073741789),
+ Complex(1073741789, 1073741789) + Complex(1073741827, 0))
+ assert_equal(Complex(-38, 1073741789),
+ Complex(1073741789, 1073741789) - Complex(1073741827, 0))
+ assert_equal(Complex(1152921470247108503, 1152921470247108503),
+ Complex(1073741789, 1073741789) * Complex(1073741827, 0))
+ assert_equal(Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(1073741789, 1073741789) / Complex(1073741827, 0))
+ assert_equal(Complex(2147483578, 2147483578),
+ Complex(1073741789, 1073741789) + Complex(1073741789, 1073741789))
+ assert_equal(Complex(0, 0),
+ Complex(1073741789, 1073741789) - Complex(1073741789, 1073741789))
+ assert_equal(Complex(0, 2305842858889841042),
+ Complex(1073741789, 1073741789) * Complex(1073741789, 1073741789))
+ assert_equal(Complex(1, 0),
+ Complex(1073741789, 1073741789) / Complex(1073741789, 1073741789))
+ assert_equal(Complex(2147483578, 2147483616),
+ Complex(1073741789, 1073741789) + Complex(1073741789, 1073741827))
+ assert_equal(Complex(0, -38),
+ Complex(1073741789, 1073741789) - Complex(1073741789, 1073741827))
+ assert_equal(Complex(-40802187982, 2305842899692029024),
+ Complex(1073741789, 1073741789) * Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(1152921449846014512, 1152921470247109225), Rational(-20401093991, 1152921470247109225)),
+ Complex(1073741789, 1073741789) / Complex(1073741789, 1073741827))
+ assert_equal(Complex(2147483616, 2147483616),
+ Complex(1073741789, 1073741789) + Complex(1073741827, 1073741827))
+ assert_equal(Complex(-38, -38),
+ Complex(1073741789, 1073741789) - Complex(1073741827, 1073741827))
+ assert_equal(Complex(0, 2305842940494217006),
+ Complex(1073741789, 1073741789) * Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1073741789, 1073741827), 0),
+ Complex(1073741789, 1073741789) / Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1152921471320850292, 1073741827), Rational(1152921471320850292, 1073741827)),
+ Complex(1073741789, 1073741789) + Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921469173366714, 1073741827), Rational(1152921469173366714, 1073741827)),
+ Complex(1073741789, 1073741789) - Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(0, Rational(2305842858889841042, 1073741827)),
+ Complex(1073741789, 1073741789) * Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(1073741827, 0),
+ Complex(1073741789, 1073741789) / Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921430518662348, 1073741789), Rational(1152921430518662348, 1073741789)),
+ Complex(1073741789, 1073741789) + Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921428371178694, 1073741789), Rational(1152921428371178694, 1073741789)),
+ Complex(1073741789, 1073741789) - Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(0, 2147483654),
+ Complex(1073741789, 1073741789) * Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921429444920521, 1073741827), 0),
+ Complex(1073741789, 1073741789) / Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921471320850292, 1073741827), Rational(1152921430518662348, 1073741789)),
+ Complex(1073741789, 1073741789) + Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921469173366714, 1073741827), Rational(1152921428371178694, 1073741789)),
+ Complex(1073741789, 1073741789) - Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-81604377408, 1073741827), Rational(2305842940494218450, 1073741827)),
+ Complex(1073741789, 1073741789) * Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1427247561112392972813122023043041209197173075, 1329227916556757626754787505905300241), Rational(-50510659935364010697847612929910630368, 1329227916556757626754787505905300241)),
+ Complex(1073741789, 1073741789) / Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(1073741789, 1073741827), +Complex(1073741789, 1073741827))
+ assert_equal(Complex(-1073741789, -1073741827), -Complex(1073741789, 1073741827))
+ assert_equal(Complex(1073741790, 1073741827),
+ Complex(1073741789, 1073741827) + Complex(1, 0))
+ assert_equal(Complex(1073741788, 1073741827),
+ Complex(1073741789, 1073741827) - Complex(1, 0))
+ assert_equal(Complex(1073741789, 1073741827),
+ Complex(1073741789, 1073741827) * Complex(1, 0))
+ assert_equal(Complex(1073741789, 1073741827),
+ Complex(1073741789, 1073741827) / Complex(1, 0))
+ assert_equal(Complex(2147483578, 1073741827),
+ Complex(1073741789, 1073741827) + Complex(1073741789, 0))
+ assert_equal(Complex(0, 1073741827),
+ Complex(1073741789, 1073741827) - Complex(1073741789, 0))
+ assert_equal(Complex(1152921429444920521, 1152921470247108503),
+ Complex(1073741789, 1073741827) * Complex(1073741789, 0))
+ assert_equal(Complex(1, Rational(1073741827, 1073741789)),
+ Complex(1073741789, 1073741827) / Complex(1073741789, 0))
+ assert_equal(Complex(2147483616, 1073741827),
+ Complex(1073741789, 1073741827) + Complex(1073741827, 0))
+ assert_equal(Complex(-38, 1073741827),
+ Complex(1073741789, 1073741827) - Complex(1073741827, 0))
+ assert_equal(Complex(1152921470247108503, 1152921511049297929),
+ Complex(1073741789, 1073741827) * Complex(1073741827, 0))
+ assert_equal(Complex(Rational(1073741789, 1073741827), 1),
+ Complex(1073741789, 1073741827) / Complex(1073741827, 0))
+ assert_equal(Complex(2147483578, 2147483616),
+ Complex(1073741789, 1073741827) + Complex(1073741789, 1073741789))
+ assert_equal(Complex(0, 38),
+ Complex(1073741789, 1073741827) - Complex(1073741789, 1073741789))
+ assert_equal(Complex(-40802187982, 2305842899692029024),
+ Complex(1073741789, 1073741827) * Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(1073741808, 1073741789), Rational(19, 1073741789)),
+ Complex(1073741789, 1073741827) / Complex(1073741789, 1073741789))
+ assert_equal(Complex(2147483578, 2147483654),
+ Complex(1073741789, 1073741827) + Complex(1073741789, 1073741827))
+ assert_equal(Complex(0, 0),
+ Complex(1073741789, 1073741827) - Complex(1073741789, 1073741827))
+ assert_equal(Complex(-81604377408, 2305842940494217006),
+ Complex(1073741789, 1073741827) * Complex(1073741789, 1073741827))
+ assert_equal(Complex(1, 0),
+ Complex(1073741789, 1073741827) / Complex(1073741789, 1073741827))
+ assert_equal(Complex(2147483616, 2147483654),
+ Complex(1073741789, 1073741827) + Complex(1073741827, 1073741827))
+ assert_equal(Complex(-38, 0),
+ Complex(1073741789, 1073741827) - Complex(1073741827, 1073741827))
+ assert_equal(Complex(-40802189426, 2305842981296406432),
+ Complex(1073741789, 1073741827) * Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1073741808, 1073741827), Rational(19, 1073741827)),
+ Complex(1073741789, 1073741827) / Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1152921471320850292, 1073741827), Rational(1152921512123039718, 1073741827)),
+ Complex(1073741789, 1073741827) + Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921469173366714, 1073741827), Rational(1152921509975556140, 1073741827)),
+ Complex(1073741789, 1073741827) - Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(-40802187982, 1073741827), Rational(2305842899692029024, 1073741827)),
+ Complex(1073741789, 1073741827) * Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921490648203216, 1073741789), Rational(20401094713, 1073741789)),
+ Complex(1073741789, 1073741827) / Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921430518662348, 1073741789), Rational(1152921471320850330, 1073741789)),
+ Complex(1073741789, 1073741827) + Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921428371178694, 1073741789), Rational(1152921469173366676, 1073741789)),
+ Complex(1073741789, 1073741827) - Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-40802189426, 1073741789), Rational(2305842981296406432, 1073741789)),
+ Complex(1073741789, 1073741827) * Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921449846014512, 1073741827), Rational(20401093991, 1073741827)),
+ Complex(1073741789, 1073741827) / Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921471320850292, 1073741827), Rational(1152921471320850330, 1073741789)),
+ Complex(1073741789, 1073741827) + Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921469173366714, 1073741827), Rational(1152921469173366676, 1073741789)),
+ Complex(1073741789, 1073741827) - Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-131433047608170424214, 1152921470247108503), 2147483616),
+ Complex(1073741789, 1073741827) * Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1427247586367724281184137892451027617484788528, 1329227916556757626754787505905300241), Rational(-25255330414578331645234047212843119171, 1329227916556757626754787505905300241)),
+ Complex(1073741789, 1073741827) / Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(1073741827, 1073741827), +Complex(1073741827, 1073741827))
+ assert_equal(Complex(-1073741827, -1073741827), -Complex(1073741827, 1073741827))
+ assert_equal(Complex(1073741828, 1073741827),
+ Complex(1073741827, 1073741827) + Complex(1, 0))
+ assert_equal(Complex(1073741826, 1073741827),
+ Complex(1073741827, 1073741827) - Complex(1, 0))
+ assert_equal(Complex(1073741827, 1073741827),
+ Complex(1073741827, 1073741827) * Complex(1, 0))
+ assert_equal(Complex(1073741827, 1073741827),
+ Complex(1073741827, 1073741827) / Complex(1, 0))
+ assert_equal(Complex(2147483616, 1073741827),
+ Complex(1073741827, 1073741827) + Complex(1073741789, 0))
+ assert_equal(Complex(38, 1073741827),
+ Complex(1073741827, 1073741827) - Complex(1073741789, 0))
+ assert_equal(Complex(1152921470247108503, 1152921470247108503),
+ Complex(1073741827, 1073741827) * Complex(1073741789, 0))
+ assert_equal(Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(1073741827, 1073741827) / Complex(1073741789, 0))
+ assert_equal(Complex(2147483654, 1073741827),
+ Complex(1073741827, 1073741827) + Complex(1073741827, 0))
+ assert_equal(Complex(0, 1073741827),
+ Complex(1073741827, 1073741827) - Complex(1073741827, 0))
+ assert_equal(Complex(1152921511049297929, 1152921511049297929),
+ Complex(1073741827, 1073741827) * Complex(1073741827, 0))
+ assert_equal(Complex(1, 1),
+ Complex(1073741827, 1073741827) / Complex(1073741827, 0))
+ assert_equal(Complex(2147483616, 2147483616),
+ Complex(1073741827, 1073741827) + Complex(1073741789, 1073741789))
+ assert_equal(Complex(38, 38),
+ Complex(1073741827, 1073741827) - Complex(1073741789, 1073741789))
+ assert_equal(Complex(0, 2305842940494217006),
+ Complex(1073741827, 1073741827) * Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(1073741827, 1073741789), 0),
+ Complex(1073741827, 1073741827) / Complex(1073741789, 1073741789))
+ assert_equal(Complex(2147483616, 2147483654),
+ Complex(1073741827, 1073741827) + Complex(1073741789, 1073741827))
+ assert_equal(Complex(38, 0),
+ Complex(1073741827, 1073741827) - Complex(1073741789, 1073741827))
+ assert_equal(Complex(-40802189426, 2305842981296406432),
+ Complex(1073741827, 1073741827) * Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(1152921490648203216, 1152921470247109225), Rational(-20401094713, 1152921470247109225)),
+ Complex(1073741827, 1073741827) / Complex(1073741789, 1073741827))
+ assert_equal(Complex(2147483654, 2147483654),
+ Complex(1073741827, 1073741827) + Complex(1073741827, 1073741827))
+ assert_equal(Complex(0, 0),
+ Complex(1073741827, 1073741827) - Complex(1073741827, 1073741827))
+ assert_equal(Complex(0, 2305843022098595858),
+ Complex(1073741827, 1073741827) * Complex(1073741827, 1073741827))
+ assert_equal(Complex(1, 0),
+ Complex(1073741827, 1073741827) / Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1152921512123039718, 1073741827), Rational(1152921512123039718, 1073741827)),
+ Complex(1073741827, 1073741827) + Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921509975556140, 1073741827), Rational(1152921509975556140, 1073741827)),
+ Complex(1073741827, 1073741827) - Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(0, 2147483578),
+ Complex(1073741827, 1073741827) * Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921511049297929, 1073741789), 0),
+ Complex(1073741827, 1073741827) / Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921471320850330, 1073741789), Rational(1152921471320850330, 1073741789)),
+ Complex(1073741827, 1073741827) + Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921469173366676, 1073741789), Rational(1152921469173366676, 1073741789)),
+ Complex(1073741827, 1073741827) - Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(0, Rational(2305843022098595858, 1073741789)),
+ Complex(1073741827, 1073741827) * Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(1073741789, 0),
+ Complex(1073741827, 1073741827) / Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921512123039718, 1073741827), Rational(1152921471320850330, 1073741789)),
+ Complex(1073741827, 1073741827) + Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921509975556140, 1073741827), Rational(1152921469173366676, 1073741789)),
+ Complex(1073741827, 1073741827) - Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-81604377408, 1073741789), Rational(2305842940494218450, 1073741789)),
+ Complex(1073741827, 1073741827) * Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1427247611623053801969816945064593334552299725, 1329227916556757626754787505905300241), Rational(-50510661722949347514642033621130734624, 1329227916556757626754787505905300241)),
+ Complex(1073741827, 1073741827) / Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)), +Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(-1073741789, 1073741827), Rational(-1073741789, 1073741827)), -Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(2147483616, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) + Complex(1, 0))
+ assert_equal(Complex(Rational(-38, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) - Complex(1, 0))
+ assert_equal(Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) * Complex(1, 0))
+ assert_equal(Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) / Complex(1, 0))
+ assert_equal(Complex(Rational(1152921471320850292, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) + Complex(1073741789, 0))
+ assert_equal(Complex(Rational(-1152921469173366714, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) - Complex(1073741789, 0))
+ assert_equal(Complex(Rational(1152921429444920521, 1073741827), Rational(1152921429444920521, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) * Complex(1073741789, 0))
+ assert_equal(Complex(Rational(1, 1073741827), Rational(1, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) / Complex(1073741789, 0))
+ assert_equal(Complex(Rational(1152921512123039718, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) + Complex(1073741827, 0))
+ assert_equal(Complex(Rational(-1152921509975556140, 1073741827), Rational(1073741789, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) - Complex(1073741827, 0))
+ assert_equal(Complex(1073741789, 1073741789),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) * Complex(1073741827, 0))
+ assert_equal(Complex(Rational(1073741789, 1152921511049297929), Rational(1073741789, 1152921511049297929)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) / Complex(1073741827, 0))
+ assert_equal(Complex(Rational(1152921471320850292, 1073741827), Rational(1152921471320850292, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) + Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(-1152921469173366714, 1073741827), Rational(-1152921469173366714, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) - Complex(1073741789, 1073741789))
+ assert_equal(Complex(0, Rational(2305842858889841042, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) * Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(1, 1073741827), 0),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) / Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(1152921471320850292, 1073741827), Rational(1152921512123039718, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) + Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(-1152921469173366714, 1073741827), Rational(-1152921509975556140, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) - Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(-40802187982, 1073741827), Rational(2305842899692029024, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) * Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(1152921449846014512, 1237940005850657200720054075), Rational(-20401093991, 1237940005850657200720054075)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) / Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(1152921512123039718, 1073741827), Rational(1152921512123039718, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) + Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(-1152921509975556140, 1073741827), Rational(-1152921509975556140, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) - Complex(1073741827, 1073741827))
+ assert_equal(Complex(0, 2147483578),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) * Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1073741789, 1152921511049297929), 0),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) / Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(2147483578, 1073741827), Rational(2147483578, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) + Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(0, 0),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) - Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(0, Rational(2305842858889841042, 1152921511049297929)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) * Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(1, 0),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) / Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(2305842940494218450, 1152921470247108503), Rational(2305842940494218450, 1152921470247108503)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) + Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-81604377408, 1152921470247108503), Rational(-81604377408, 1152921470247108503)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) - Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(0, 2),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) * Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921429444920521, 1152921511049297929), 0),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) / Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(2147483578, 1073741827), Rational(2305842940494218450, 1152921470247108503)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) + Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(0, Rational(-81604377408, 1152921470247108503)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) - Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-81604377408, 1152921511049297929), Rational(2305842940494218450, 1152921511049297929)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) * Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1329227869515036572020512360130906225, 1329227916556757626754787505905300241), Rational(-47041717725097069072123994784, 1329227916556757626754787505905300241)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)) / Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)), +Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-1073741827, 1073741789), Rational(-1073741827, 1073741789)), -Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(2147483616, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) + Complex(1, 0))
+ assert_equal(Complex(Rational(38, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) - Complex(1, 0))
+ assert_equal(Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) * Complex(1, 0))
+ assert_equal(Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) / Complex(1, 0))
+ assert_equal(Complex(Rational(1152921430518662348, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) + Complex(1073741789, 0))
+ assert_equal(Complex(Rational(-1152921428371178694, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) - Complex(1073741789, 0))
+ assert_equal(Complex(1073741827, 1073741827),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) * Complex(1073741789, 0))
+ assert_equal(Complex(Rational(1073741827, 1152921429444920521), Rational(1073741827, 1152921429444920521)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) / Complex(1073741789, 0))
+ assert_equal(Complex(Rational(1152921471320850330, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) + Complex(1073741827, 0))
+ assert_equal(Complex(Rational(-1152921469173366676, 1073741789), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) - Complex(1073741827, 0))
+ assert_equal(Complex(Rational(1152921511049297929, 1073741789), Rational(1152921511049297929, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) * Complex(1073741827, 0))
+ assert_equal(Complex(Rational(1, 1073741789), Rational(1, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) / Complex(1073741827, 0))
+ assert_equal(Complex(Rational(1152921430518662348, 1073741789), Rational(1152921430518662348, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) + Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(-1152921428371178694, 1073741789), Rational(-1152921428371178694, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) - Complex(1073741789, 1073741789))
+ assert_equal(Complex(0, 2147483654),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) * Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(1073741827, 1152921429444920521), 0),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) / Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(1152921430518662348, 1073741789), Rational(1152921471320850330, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) + Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(-1152921428371178694, 1073741789), Rational(-1152921469173366676, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) - Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(-40802189426, 1073741789), Rational(2305842981296406432, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) * Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(1152921490648203216, 1237939962039641331329903525), Rational(-20401094713, 1237939962039641331329903525)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) / Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(1152921471320850330, 1073741789), Rational(1152921471320850330, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) + Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(-1152921469173366676, 1073741789), Rational(-1152921469173366676, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) - Complex(1073741827, 1073741827))
+ assert_equal(Complex(0, Rational(2305843022098595858, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) * Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1, 1073741789), 0),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) / Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(2305842940494218450, 1152921470247108503), Rational(2305842940494218450, 1152921470247108503)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) + Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(81604377408, 1152921470247108503), Rational(81604377408, 1152921470247108503)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) - Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(0, 2),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) * Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921511049297929, 1152921429444920521), 0),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) / Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(2147483654, 1073741789), Rational(2147483654, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) + Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(0, 0),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) - Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(0, Rational(2305843022098595858, 1152921429444920521)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) * Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(1, 0),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) / Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(2305842940494218450, 1152921470247108503), Rational(2147483654, 1073741789)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) + Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(81604377408, 1152921470247108503), 0),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) - Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-81604377408, 1152921429444920521), Rational(2305842940494218450, 1152921429444920521)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) * Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1329227963598475351851856578029295025, 1329227916556757626754787505905300241), Rational(-47041721054734275145774394016, 1329227916556757626754787505905300241)),
+ Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)) / Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)), +Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-1073741789, 1073741827), Rational(-1073741827, 1073741789)), -Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(2147483616, 1073741827), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) + Complex(1, 0))
+ assert_equal(Complex(Rational(-38, 1073741827), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) - Complex(1, 0))
+ assert_equal(Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) * Complex(1, 0))
+ assert_equal(Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) / Complex(1, 0))
+ assert_equal(Complex(Rational(1152921471320850292, 1073741827), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) + Complex(1073741789, 0))
+ assert_equal(Complex(Rational(-1152921469173366714, 1073741827), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) - Complex(1073741789, 0))
+ assert_equal(Complex(Rational(1152921429444920521, 1073741827), 1073741827),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) * Complex(1073741789, 0))
+ assert_equal(Complex(Rational(1, 1073741827), Rational(1073741827, 1152921429444920521)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) / Complex(1073741789, 0))
+ assert_equal(Complex(Rational(1152921512123039718, 1073741827), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) + Complex(1073741827, 0))
+ assert_equal(Complex(Rational(-1152921509975556140, 1073741827), Rational(1073741827, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) - Complex(1073741827, 0))
+ assert_equal(Complex(1073741789, Rational(1152921511049297929, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) * Complex(1073741827, 0))
+ assert_equal(Complex(Rational(1073741789, 1152921511049297929), Rational(1, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) / Complex(1073741827, 0))
+ assert_equal(Complex(Rational(1152921471320850292, 1073741827), Rational(1152921430518662348, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) + Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(-1152921469173366714, 1073741827), Rational(-1152921428371178694, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) - Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(-81604377408, 1073741827), Rational(2305842940494218450, 1073741827)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) * Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(1152921470247109225, 1237939962039640556088331867), Rational(40802188704, 1237939962039640556088331867)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) / Complex(1073741789, 1073741789))
+ assert_equal(Complex(Rational(1152921471320850292, 1073741827), Rational(1152921471320850330, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) + Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(-1152921469173366714, 1073741827), Rational(-1152921469173366676, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) - Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(-131433047608170424214, 1152921470247108503), 2147483616),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) * Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(1237939983945150041266564176, 1329227916556755129526882950667240175), Rational(19, 1152921470247109225)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) / Complex(1073741789, 1073741827))
+ assert_equal(Complex(Rational(1152921512123039718, 1073741827), Rational(1152921471320850330, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) + Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(-1152921509975556140, 1073741827), Rational(-1152921469173366676, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) - Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(-81604377408, 1073741789), Rational(2305842940494218450, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) * Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(1152921470247109225, 1237940005850656425478454981), Rational(40802188704, 1237940005850656425478454981)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) / Complex(1073741827, 1073741827))
+ assert_equal(Complex(Rational(2147483578, 1073741827), Rational(2305842940494218450, 1152921470247108503)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) + Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(0, Rational(81604377408, 1152921470247108503)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) - Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(-81604377408, 1152921511049297929), Rational(2305842940494218450, 1152921511049297929)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) * Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(1152921470247109225, 1152921429444920521), Rational(40802188704, 1152921429444920521)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) / Complex(Rational(1073741789, 1073741827), Rational(1073741789, 1073741827)))
+ assert_equal(Complex(Rational(2305842940494218450, 1152921470247108503), Rational(2147483654, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) + Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-81604377408, 1152921470247108503), 0),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) - Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-81604377408, 1152921429444920521), Rational(2305842940494218450, 1152921429444920521)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) * Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(1152921470247109225, 1152921511049297929), Rational(40802188704, 1152921511049297929)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) / Complex(Rational(1073741827, 1073741789), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(2147483578, 1073741827), Rational(2147483654, 1073741789)),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) + Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(0, 0),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) - Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(Rational(-188166877559662688435796777600, 1329227916556754297117581432254901009), 2),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) * Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ assert_equal(Complex(1, 0),
+ Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)) / Complex(Rational(1073741789, 1073741827), Rational(1073741827, 1073741789)))
+ end
+
+ def test_kumi2
+ assert_equal('0.0+0.0i', (+Complex(+0.0, +0.0)).to_s)
+ assert_equal('-0.0-0.0i', (-Complex(+0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, +0.0) + Complex(+0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, +0.0) - Complex(+0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, +0.0) * Complex(+0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, +0.0) + Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, +0.0) - Complex(-0.0, +0.0)).to_s)
+ assert_equal('-0.0+0.0i', (Complex(+0.0, +0.0) * Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, +0.0) + Complex(+0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, +0.0) - Complex(+0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, +0.0) * Complex(+0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, +0.0) + Complex(-0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, +0.0) - Complex(-0.0, -0.0)).to_s)
+ assert_equal('0.0-0.0i', (Complex(+0.0, +0.0) * Complex(-0.0, -0.0)).to_s)
+ assert_equal('-0.0+0.0i', (+Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0-0.0i', (-Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(-0.0, +0.0) + Complex(+0.0, +0.0)).to_s)
+ assert_equal('-0.0+0.0i', (Complex(-0.0, +0.0) - Complex(+0.0, +0.0)).to_s)
+ assert_equal('-0.0+0.0i', (Complex(-0.0, +0.0) * Complex(+0.0, +0.0)).to_s)
+ assert_equal('-0.0+0.0i', (Complex(-0.0, +0.0) + Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(-0.0, +0.0) - Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0-0.0i', (Complex(-0.0, +0.0) * Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(-0.0, +0.0) + Complex(+0.0, -0.0)).to_s)
+ assert_equal('-0.0+0.0i', (Complex(-0.0, +0.0) - Complex(+0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(-0.0, +0.0) * Complex(+0.0, -0.0)).to_s)
+ assert_equal('-0.0+0.0i', (Complex(-0.0, +0.0) + Complex(-0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(-0.0, +0.0) - Complex(-0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(-0.0, +0.0) * Complex(-0.0, -0.0)).to_s)
+ assert_equal('0.0-0.0i', (+Complex(+0.0, -0.0)).to_s)
+ assert_equal('-0.0+0.0i', (-Complex(+0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, -0.0) + Complex(+0.0, +0.0)).to_s)
+ assert_equal('0.0-0.0i', (Complex(+0.0, -0.0) - Complex(+0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, -0.0) * Complex(+0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, -0.0) + Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0-0.0i', (Complex(+0.0, -0.0) - Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, -0.0) * Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0-0.0i', (Complex(+0.0, -0.0) + Complex(+0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, -0.0) - Complex(+0.0, -0.0)).to_s)
+ assert_equal('0.0-0.0i', (Complex(+0.0, -0.0) * Complex(+0.0, -0.0)).to_s)
+ assert_equal('0.0-0.0i', (Complex(+0.0, -0.0) + Complex(-0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(+0.0, -0.0) - Complex(-0.0, -0.0)).to_s)
+ assert_equal('-0.0+0.0i', (Complex(+0.0, -0.0) * Complex(-0.0, -0.0)).to_s)
+ assert_equal('-0.0-0.0i', (+Complex(-0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (-Complex(-0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(-0.0, -0.0) + Complex(+0.0, +0.0)).to_s)
+ assert_equal('-0.0-0.0i', (Complex(-0.0, -0.0) - Complex(+0.0, +0.0)).to_s)
+ assert_equal('0.0-0.0i', (Complex(-0.0, -0.0) * Complex(+0.0, +0.0)).to_s)
+ assert_equal('-0.0+0.0i', (Complex(-0.0, -0.0) + Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0-0.0i', (Complex(-0.0, -0.0) - Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(-0.0, -0.0) * Complex(-0.0, +0.0)).to_s)
+ assert_equal('0.0-0.0i', (Complex(-0.0, -0.0) + Complex(+0.0, -0.0)).to_s)
+ assert_equal('-0.0+0.0i', (Complex(-0.0, -0.0) - Complex(+0.0, -0.0)).to_s)
+ assert_equal('-0.0+0.0i', (Complex(-0.0, -0.0) * Complex(+0.0, -0.0)).to_s)
+ assert_equal('-0.0-0.0i', (Complex(-0.0, -0.0) + Complex(-0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(-0.0, -0.0) - Complex(-0.0, -0.0)).to_s)
+ assert_equal('0.0+0.0i', (Complex(-0.0, -0.0) * Complex(-0.0, -0.0)).to_s)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_complexrational.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_complexrational.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_complexrational.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,407 @@
+require 'test/unit'
+
+class ComplexRational_Test < Test::Unit::TestCase
+
+ def test_rat_srat
+ return unless defined?(Rational)
+
+ c = SimpleRat(1,3)
+ cc = Rational(3,2)
+
+ assert_kind_of(Numeric, c)
+ assert_kind_of(Numeric, cc)
+
+ assert_instance_of(SimpleRat, c)
+ assert_instance_of(Rational, cc)
+
+ assert_equal(SimpleRat(1,3), +c)
+ assert_equal(SimpleRat(-1,3), -c)
+
+ assert_equal(SimpleRat(7,3), c + 2)
+ assert_equal(SimpleRat(-5,3), c - 2)
+ assert_equal(SimpleRat(2,3), c * 2)
+ assert_equal(SimpleRat(1,6), c / 2)
+ assert_equal(SimpleRat(1,9), c ** 2)
+ assert_equal(-1, c <=> 2)
+
+ assert_equal(SimpleRat(7,3), 2 + c)
+ assert_equal(SimpleRat(5,3), 2 - c)
+ assert_equal(SimpleRat(2,3), 2 * c)
+ assert_equal(SimpleRat(6,1), 2 / c)
+ assert_in_delta(1.2599, 2 ** c, 0.001)
+ assert_equal(1, 2 <=> c)
+
+ assert_equal(SimpleRat(11,6), c + cc)
+ assert_equal(SimpleRat(-7,6), c - cc)
+ assert_equal(SimpleRat(1,2), c * cc)
+ assert_equal(SimpleRat(2,9), c / cc)
+ assert_in_delta(0.1924, c ** cc, 0.001)
+ assert_equal(-1, c <=> cc)
+
+ assert_equal(SimpleRat(11,6), cc + c)
+ assert_equal(SimpleRat(7,6), cc - c)
+ assert_equal(SimpleRat(1,2), cc * c)
+ assert_equal(SimpleRat(9,2), cc / c)
+ assert_in_delta(1.1447, cc ** c, 0.001)
+ assert_equal(1, cc <=> c)
+
+ assert_equal(SimpleRat, (+c).class)
+ assert_equal(SimpleRat, (-c).class)
+
+ assert_equal(SimpleRat, (c + 2).class)
+ assert_equal(SimpleRat, (c - 2).class)
+ assert_equal(SimpleRat, (c * 2).class)
+ assert_equal(SimpleRat, (c / 2).class)
+ assert_equal(SimpleRat, (c ** 2).class)
+
+ assert_equal(SimpleRat, (2 + c).class)
+ assert_equal(SimpleRat, (2 - c).class)
+ assert_equal(SimpleRat, (2 * c).class)
+ assert_equal(SimpleRat, (2 / c).class)
+ assert_equal(Float, (2 ** c).class)
+
+ assert_equal(SimpleRat, (c + cc).class)
+ assert_equal(SimpleRat, (c - cc).class)
+ assert_equal(SimpleRat, (c * cc).class)
+ assert_equal(SimpleRat, (c / cc).class)
+ assert_equal(Float, (c ** cc).class)
+
+ assert_equal(SimpleRat, (cc + c).class)
+ assert_equal(SimpleRat, (cc - c).class)
+ assert_equal(SimpleRat, (cc * c).class)
+ assert_equal(SimpleRat, (cc / c).class)
+ assert_equal(Float, (cc ** c).class)
+
+ assert_equal(0, Rational(2,3) <=> SimpleRat(2,3))
+ assert_equal(0, SimpleRat(2,3) <=> Rational(2,3))
+ assert(Rational(2,3) == SimpleRat(2,3))
+ assert(SimpleRat(2,3) == Rational(2,3))
+
+ assert_equal(SimpleRat, (c + 0).class)
+ assert_equal(SimpleRat, (c - 0).class)
+ assert_equal(SimpleRat, (c * 0).class)
+ assert_equal(SimpleRat, (c * 1).class)
+ assert_equal(SimpleRat, (0 + c).class)
+ assert_equal(SimpleRat, (0 - c).class)
+ assert_equal(SimpleRat, (0 * c).class)
+ assert_equal(SimpleRat, (1 * c).class)
+ end
+
+ def test_comp_srat
+ return unless defined?(Rational)
+
+ c = Complex(SimpleRat(2,3),SimpleRat(1,2))
+ cc = Complex(Rational(3,2),Rational(2,1))
+
+ assert_equal(Complex(SimpleRat(2,3),SimpleRat(1,2)), +c)
+ assert_equal(Complex(SimpleRat(-2,3),SimpleRat(-1,2)), -c)
+
+ assert_equal(Complex(SimpleRat(8,3),SimpleRat(1,2)), c + 2)
+ assert_equal(Complex(SimpleRat(-4,3),SimpleRat(1,2)), c - 2)
+ assert_equal(Complex(SimpleRat(4,3),SimpleRat(1,1)), c * 2)
+ assert_equal(Complex(SimpleRat(1,3),SimpleRat(1,4)), c / 2)
+ assert_equal(Complex(SimpleRat(7,36),SimpleRat(2,3)), c ** 2)
+ assert_raise(NoMethodError){c <=> 2}
+
+ assert_equal(Complex(SimpleRat(8,3),SimpleRat(1,2)), 2 + c)
+ assert_equal(Complex(SimpleRat(4,3),SimpleRat(-1,2)), 2 - c)
+ assert_equal(Complex(SimpleRat(4,3),SimpleRat(1,1)), 2 * c)
+ assert_equal(Complex(SimpleRat(48,25),SimpleRat(-36,25)), 2 / c)
+ r = 2 ** c
+ assert_in_delta(1.4940, r.real, 0.001)
+ assert_in_delta(0.5392, r.imag, 0.001)
+ assert_raise(NoMethodError){2 <=> c}
+
+ assert_equal(Complex(SimpleRat(13,6),SimpleRat(5,2)), c + cc)
+ assert_equal(Complex(SimpleRat(-5,6),SimpleRat(-3,2)), c - cc)
+ assert_equal(Complex(SimpleRat(0,1),SimpleRat(25,12)), c * cc)
+ assert_equal(Complex(SimpleRat(8,25),SimpleRat(-7,75)), c / cc)
+ r = c ** cc
+ assert_in_delta(0.1732, r.real, 0.001)
+ assert_in_delta(0.1186, r.imag, 0.001)
+ assert_raise(NoMethodError){c <=> cc}
+
+ assert_equal(Complex(SimpleRat(13,6),SimpleRat(5,2)), cc + c)
+ assert_equal(Complex(SimpleRat(5,6),SimpleRat(3,2)), cc - c)
+ assert_equal(Complex(SimpleRat(0,1),SimpleRat(25,12)), cc * c)
+ assert_equal(Complex(SimpleRat(72,25),SimpleRat(21,25)), cc / c)
+ r = cc ** c
+ assert_in_delta(0.5498, r.real, 0.001)
+ assert_in_delta(1.0198, r.imag, 0.001)
+ assert_raise(NoMethodError){cc <=> c}
+
+ assert_equal([SimpleRat,SimpleRat],
+ (+c).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (-c).instance_eval{[real.class, imag.class]})
+
+ assert_equal([SimpleRat,SimpleRat],
+ (c + 2).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (c - 2).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (c * 2).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (c / 2).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (c ** 2).instance_eval{[real.class, imag.class]})
+
+ assert_equal([SimpleRat,SimpleRat],
+ (c + cc).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (c - cc).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (c * cc).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (c / cc).instance_eval{[real.class, imag.class]})
+ assert_equal([Float,Float],
+ (c ** cc).instance_eval{[real.class, imag.class]})
+
+ assert_equal([SimpleRat,SimpleRat],
+ (cc + c).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (cc - c).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (cc * c).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (cc / c).instance_eval{[real.class, imag.class]})
+ assert_equal([Float,Float],
+ (cc ** c).instance_eval{[real.class, imag.class]})
+
+ assert(Complex(SimpleRat(2,3),SimpleRat(3,2)) ==
+ Complex(Rational(2,3),Rational(3,2)))
+ assert(Complex(Rational(2,3),Rational(3,2)) ==
+ Complex(SimpleRat(2,3),SimpleRat(3,2)))
+
+ assert_equal([SimpleRat,SimpleRat],
+ (c + 0).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (c - 0).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (c * 0).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (c * 1).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (0 + c).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (0 - c).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (0 * c).instance_eval{[real.class, imag.class]})
+ assert_equal([SimpleRat,SimpleRat],
+ (1 * c).instance_eval{[real.class, imag.class]})
+ end
+
+end
+
+def SimpleRat(*a) SimpleRat.new(*a) end
+
+class SimpleRat < Numeric
+
+ def initialize(num, den = 1)
+ if den == 0
+ raise ZeroDivisionError, "divided by zero"
+ end
+ if den < 0
+ num = -num
+ den = -den
+ end
+ gcd = num.gcd(den)
+ @num = num.div(gcd)
+ @den = den.div(gcd)
+ end
+
+ def numerator() @num end
+ def denominator() @den end
+
+ def +@ () self end
+ def -@ () self.class.new(- at num, @den) end
+
+ def + (o)
+ case o
+ when SimpleRat, Rational
+ a = @num * o.denominator
+ b = o.numerator * @den
+ self.class.new(a + b, @den * o.denominator)
+ when Integer
+ self + self.class.new(o)
+ when Float
+ to_f + o
+ else
+ x, y = o.coerce(self)
+ x + y
+ end
+ end
+
+ def - (o)
+ case o
+ when SimpleRat, Rational
+ a = @num * o.denominator
+ b = o.numerator * @den
+ self.class.new(a - b, @den * o.denominator)
+ when Integer
+ self - self.class.new(o)
+ when Float
+ to_f - o
+ else
+ x, y = o.coerce(self)
+ x - y
+ end
+ end
+
+ def * (o)
+ case o
+ when SimpleRat, Rational
+ a = @num * o.numerator
+ b = @den * o.denominator
+ self.class.new(a, b)
+ when Integer
+ self * self.class.new(o)
+ when Float
+ to_f * o
+ else
+ x, y = o.coerce(self)
+ x * y
+ end
+ end
+
+ def quo(o)
+ case o
+ when SimpleRat, Rational
+ a = @num * o.denominator
+ b = @den * o.numerator
+ self.class.new(a, b)
+ when Integer
+ if o == 0
+ raise raise ZeroDivisionError, "divided by zero"
+ end
+ self.quo(self.class.new(o))
+ when Float
+ to_f.quo(o)
+ else
+ x, y = o.coerce(self)
+ x.quo(y)
+ end
+ end
+
+ alias / quo
+
+ def floor
+ @num.div(@den)
+ end
+
+ def ceil
+ -((- at num).div(@den))
+ end
+
+ def truncate
+ if @num < 0
+ return -((- at num).div(@den))
+ end
+ @num.div(@den)
+ end
+
+ alias to_i truncate
+
+ def round
+ if @num < 0
+ num = - at num
+ num = num * 2 + @den
+ den = @den * 2
+ -(num.div(den))
+ else
+ num = @num * 2 + @den
+ den = @den * 2
+ num.div(den)
+ end
+ end
+
+ def div(o) (self / o).floor end
+ def quot(o) (self / o).truncate end
+
+ def modulo(o)
+ q = div(o)
+ self - o * q
+ end
+
+ def remainder(o)
+ q = quot(o)
+ self - o * q
+ end
+
+ alias % modulo
+
+ def divmod(o) [div(o), modulo(o)] end
+ def quotrem(o) [quot(o), remainder(o)] end
+
+ def ** (o)
+ case o
+ when SimpleRat, Rational
+ Float(self) ** o
+ when Integer
+ if o > 0
+ a = @num ** o
+ b = @den ** o
+ elsif o < 0
+ a = @den ** -o
+ b = @num ** -o
+ else
+ a = b = 1
+ end
+ self.class.new(a, b)
+ when Float
+ to_f ** o
+ else
+ x, y = o.coerce(self)
+ x ** y
+ end
+ end
+
+ def <=> (o)
+ case o
+ when SimpleRat, Rational
+ a = @num * o.denominator
+ b = o.numerator * @den
+ return a <=> b
+ when Integer
+ self <=> self.class.new(o)
+ when Float
+ to_f <=> o
+ else
+ x, y = o.coerce(self)
+ x <=> y
+ end
+ end
+
+ def == (o)
+ begin
+ (self <=> o) == 0
+ rescue
+ false
+ end
+ end
+
+ def coerce(o)
+ case o
+ when Rational
+ [self.class.new(o.numerator, o.denominator), self]
+ when Integer
+ [self.class.new(o), self]
+ when Float
+ [o, self.to_f]
+ else
+ super
+ end
+ end
+
+ def hash() @num.hash ^ @den.hash end
+
+ def to_f() @num.to_f / @den.to_f end
+ def to_r() self end
+ def to_s() format('%s/%s', @num, @den) end
+
+ def inspect() format('#SR(%s)', to_s) end
+
+ def marshal_dump() [@num, @den] end
+ def marshal_load(a) @num, @den = a end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_condition.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_condition.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_condition.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,16 @@
+require 'test/unit'
+
+class TestCondition < Test::Unit::TestCase
+
+ # [should] first test to see if we can run the tests.
+
+ def test_condition
+ $x = '0';
+
+ $x == $x && assert(true)
+ $x != $x && assert(false)
+ $x == $x || assert(false)
+ $x != $x || assert(true)
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_const.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_const.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_const.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,48 @@
+require 'test/unit'
+
+class TestConst < Test::Unit::TestCase
+ TEST1 = 1
+ TEST2 = 2
+
+ module Const
+ TEST3 = 3
+ TEST4 = 4
+ end
+
+ module Const2
+ TEST3 = 6
+ TEST4 = 8
+ end
+
+ def test_const
+ assert defined?(TEST1)
+ assert_equal 1, TEST1
+ assert defined?(TEST2)
+ assert_equal 2, TEST2
+
+ self.class.class_eval {
+ include Const
+ }
+ assert defined?(TEST1)
+ assert_equal 1, TEST1
+ assert defined?(TEST2)
+ assert_equal 2, TEST2
+ assert defined?(TEST3)
+ assert_equal 3, TEST3
+ assert defined?(TEST4)
+ assert_equal 4, TEST4
+
+ self.class.class_eval {
+ include Const2
+ }
+ STDERR.print "intentionally redefines TEST3, TEST4\n" if $VERBOSE
+ assert defined?(TEST1)
+ assert_equal 1, TEST1
+ assert defined?(TEST2)
+ assert_equal 2, TEST2
+ assert defined?(TEST3)
+ assert_equal 6, TEST3
+ assert defined?(TEST4)
+ assert_equal 8, TEST4
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_continuation.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_continuation.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_continuation.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,81 @@
+require 'test/unit'
+require 'continuation'
+require 'fiber'
+require_relative 'envutil'
+
+class TestContinuation < Test::Unit::TestCase
+ def test_create
+ assert_equal(:ok, callcc{:ok})
+ assert_equal(:ok, callcc{|c| c.call :ok})
+ end
+
+ def test_call
+ assert_equal(:ok, callcc{|c| c.call :ok})
+
+ ary = []
+ ary << callcc{|c|
+ @cont = c
+ :a
+ }
+ @cont.call :b if ary.length < 3
+ assert_equal([:a, :b, :b], ary)
+ end
+
+ def test_check_localvars
+ vv = 0
+ @v = 0
+ @ary = []
+ [1, 2, 3].each{|i|
+ callcc {|k| @k = k}
+ @v += 1
+ vv += 1
+ }
+ @ary << [vv, @v]
+ @k.call if @v < 10
+ assert_equal((3..10).map{|e| [e, e]}, @ary)
+ end
+
+ def test_error
+ cont = callcc{|c| c}
+ assert_raise(RuntimeError){
+ Thread.new{cont.call}.join
+ }
+ assert_raise(LocalJumpError){
+ callcc
+ }
+ assert_raise(RuntimeError){
+ c = nil
+ Fiber.new do
+ callcc {|c2| c = c2 }
+ end.resume
+ c.call
+ }
+ end
+
+ def test_ary_flatten
+ assert_normal_exit %q{
+ require 'continuation'
+ n = 0
+ o = Object.new
+ def o.to_ary() callcc {|k| $k = k; [1,2,3]} end
+ [10,20,o,30,o,40].flatten.inspect
+ n += 1
+ $k.call if n < 100
+ }, '[ruby-dev:34798]'
+ end
+
+ def test_marshal_dump
+ assert_normal_exit %q{
+ require 'continuation'
+ n = 0
+ o = Object.new
+ def o.marshal_dump() callcc {|k| $k = k }; "fofof" end
+ a = [1,2,3,o,4,5,6]
+ Marshal.dump(a).inspect
+ n += 1
+ $k.call if n < 100
+ }, '[ruby-dev:34802]'
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/ruby/test_defined.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_defined.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_defined.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,88 @@
+require 'test/unit'
+
+class TestDefined < Test::Unit::TestCase
+ class Foo
+ def foo
+ p :foo
+ end
+ protected :foo
+ def bar(f)
+ yield(defined?(self.foo))
+ yield(defined?(f.foo))
+ end
+ def baz(f)
+ end
+ attr_accessor :attr
+ def attrasgn_test
+ yield(defined?(self.attr = 1))
+ end
+ end
+
+ def defined_test
+ return !defined?(yield)
+ end
+
+ def test_defined
+ $x = nil
+
+ assert(defined?($x)) # global variable
+ assert_equal('global-variable', defined?($x))# returns description
+
+ assert_nil(defined?(foo)) # undefined
+ foo=5
+ assert(defined?(foo)) # local variable
+
+ assert(defined?(Array)) # constant
+ assert(defined?(::Array)) # toplevel constant
+ assert(defined?(File::Constants)) # nested constant
+ assert(defined?(Object.new)) # method
+ assert(defined?(Object::new)) # method
+ assert(!defined?(Object.print)) # private method
+ assert(defined?(1 == 2)) # operator expression
+
+ f = Foo.new
+ assert_nil(defined?(f.foo)) # protected method
+ f.bar(f) { |v| assert(v) }
+ assert_nil(defined?(f.quux)) # undefined method
+ assert_nil(defined?(f.baz(x))) # undefined argument
+ x = 0
+ assert(defined?(f.baz(x)))
+ assert_nil(defined?(f.quux(x)))
+ assert(defined?(print(x)))
+ assert_nil(defined?(quux(x)))
+ assert(defined?(f.attr = 1))
+ f.attrasgn_test { |v| assert(v) }
+
+ assert(defined_test) # not iterator
+ assert(!defined_test{}) # called as iterator
+
+ /a/ =~ ''
+ assert_equal nil, defined?($&)
+ assert_equal nil, defined?($`)
+ assert_equal nil, defined?($')
+ assert_equal nil, defined?($+)
+ assert_equal nil, defined?($1)
+ assert_equal nil, defined?($2)
+ /a/ =~ 'a'
+ assert_equal 'global-variable', defined?($&)
+ assert_equal 'global-variable', defined?($`)
+ assert_equal 'global-variable', defined?($')
+ assert_equal nil, defined?($+)
+ assert_equal nil, defined?($1)
+ assert_equal nil, defined?($2)
+ /(a)/ =~ 'a'
+ assert_equal 'global-variable', defined?($&)
+ assert_equal 'global-variable', defined?($`)
+ assert_equal 'global-variable', defined?($')
+ assert_equal 'global-variable', defined?($+)
+ assert_equal 'global-variable', defined?($1)
+ assert_equal nil, defined?($2)
+ /(a)b/ =~ 'ab'
+ assert_equal 'global-variable', defined?($&)
+ assert_equal 'global-variable', defined?($`)
+ assert_equal 'global-variable', defined?($')
+ assert_equal 'global-variable', defined?($+)
+ assert_equal 'global-variable', defined?($1)
+ assert_equal nil, defined?($2)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_dir.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_dir.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_dir.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,216 @@
+require 'test/unit'
+
+require 'tmpdir'
+require 'fileutils'
+require 'pathname'
+
+class TestDir < Test::Unit::TestCase
+
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ @root = Pathname.new(Dir.mktmpdir('__test_dir__')).realpath.to_s
+ @nodir = File.join(@root, "dummy")
+ for i in ?a..?z
+ if i.ord % 2 == 0
+ FileUtils.touch(File.join(@root, i))
+ else
+ FileUtils.mkdir(File.join(@root, i))
+ end
+ end
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ FileUtils.remove_entry_secure @root if File.directory?(@root)
+ end
+
+ def test_seek
+ dir = Dir.open(@root)
+ begin
+ cache = []
+ loop do
+ pos = dir.tell
+ break unless name = dir.read
+ cache << [pos, name]
+ end
+ for x,y in cache.sort_by {|z| z[0] % 3 } # shuffle
+ dir.seek(x)
+ assert_equal(y, dir.read)
+ end
+ ensure
+ dir.close
+ end
+ end
+
+ def test_JVN_13947696
+ skip("[BUG : #842] SecurityError Level 4")
+
+ b = lambda {
+ d = Dir.open('.')
+ $SAFE = 4
+ d.close
+ }
+ assert_raise(SecurityError) { b.call }
+ end
+
+ def test_nodir
+ assert_raise(Errno::ENOENT) { Dir.open(@nodir) }
+ end
+
+ def test_inspect
+ d = Dir.open(@root)
+ assert_match(/^#<Dir:#{ Regexp.quote(@root) }>$/, d.inspect)
+ assert_match(/^#<Dir:.*>$/, Dir.allocate.inspect)
+ ensure
+ d.close
+ end
+
+ def test_path
+ d = Dir.open(@root)
+ assert_equal(@root, d.path)
+ assert_nil(Dir.allocate.path)
+ ensure
+ d.close
+ end
+
+ def test_set_pos
+ d = Dir.open(@root)
+ loop do
+ i = d.pos
+ break unless x = d.read
+ d.pos = i
+ assert_equal(x, d.read)
+ end
+ ensure
+ d.close
+ end
+
+ def test_rewind
+ d = Dir.open(@root)
+ a = (0..5).map { d.read }
+ d.rewind
+ b = (0..5).map { d.read }
+ assert_equal(a, b)
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ d.rewind
+ end.join
+ end
+ ensure
+ d.close
+ end
+
+ def test_chdir
+ @pwd = Dir.pwd
+ @env_home = ENV["HOME"]
+ @env_logdir = ENV["LOGDIR"]
+ ENV.delete("HOME")
+ ENV.delete("LOGDIR")
+
+ assert_raise(Errno::ENOENT) { Dir.chdir(@nodir) }
+ assert_raise(ArgumentError) { Dir.chdir }
+ ENV["HOME"] = @pwd
+ Dir.chdir do
+ assert_equal(@pwd, Dir.pwd)
+ Dir.chdir(@root)
+ assert_equal(@root, Dir.pwd)
+ end
+
+ ensure
+ begin
+ Dir.chdir(@pwd)
+ rescue
+ abort("cannot return the original directory: #{ @pwd }")
+ end
+ if @env_home
+ ENV["HOME"] = @env_home
+ else
+ ENV.delete("HOME")
+ end
+ if @env_logdir
+ ENV["LOGDIR"] = @env_logdir
+ else
+ ENV.delete("LOGDIR")
+ end
+ end
+
+ def test_chroot_nodir
+ assert_raise(NotImplementedError, Errno::ENOENT, Errno::EPERM
+ ) { Dir.chroot(File.join(@nodir, "")) }
+ end
+
+ def test_close
+ d = Dir.open(@root)
+ d.close
+ assert_raise(IOError) { d.read }
+ end
+
+ def test_glob
+ assert_equal((%w(. ..) + (?a..?z).to_a).map{|f| File.join(@root, f) },
+ Dir.glob(File.join(@root, "*"), File::FNM_DOTMATCH).sort)
+ assert_equal([@root] + (?a..?z).map {|f| File.join(@root, f) }.sort,
+ Dir.glob([@root, File.join(@root, "*")]).sort)
+ assert_equal([@root] + (?a..?z).map {|f| File.join(@root, f) }.sort,
+ Dir.glob(@root + "\0\0\0" + File.join(@root, "*")).sort)
+
+ assert_equal((?a..?z).step(2).map {|f| File.join(File.join(@root, f), "") }.sort,
+ Dir.glob(File.join(@root, "*/")).sort)
+
+ FileUtils.touch(File.join(@root, "{}"))
+ assert_equal(%w({} a).map{|f| File.join(@root, f) },
+ Dir.glob(File.join(@root, '{\{\},a}')))
+ assert_equal([], Dir.glob(File.join(@root, '[')))
+ assert_equal([], Dir.glob(File.join(@root, '[a-\\')))
+
+ assert_equal([File.join(@root, "a")], Dir.glob(File.join(@root, 'a\\')))
+ assert_equal((?a..?f).map {|f| File.join(@root, f) }.sort, Dir.glob(File.join(@root, '[abc/def]')).sort)
+
+ d = "\u{3042}\u{3044}".encode("utf-16le")
+ assert_raise(Encoding::CompatibilityError) {Dir.glob(d)}
+ m = Class.new {define_method(:to_path) {d}}
+ assert_raise(Encoding::CompatibilityError) {Dir.glob(m.new)}
+ end
+
+ def test_foreach
+ assert_equal(Dir.foreach(@root).to_a.sort, %w(. ..) + (?a..?z).to_a)
+ end
+
+ def test_dir_enc
+ dir = Dir.open(@root, encoding: "UTF-8")
+ begin
+ while name = dir.read
+ assert_equal(Encoding.find("UTF-8"), name.encoding)
+ end
+ ensure
+ dir.close
+ end
+
+ dir = Dir.open(@root, encoding: "ASCII-8BIT")
+ begin
+ while name = dir.read
+ assert_equal(Encoding.find("ASCII-8BIT"), name.encoding)
+ end
+ ensure
+ dir.close
+ end
+ end
+
+ def test_symlink
+ begin
+ ["dummy", *?a..?z].each do |f|
+ File.symlink(File.join(@root, f),
+ File.join(@root, "symlink-#{ f }"))
+ end
+ rescue NotImplementedError
+ return
+ end
+
+ assert_equal([*?a..?z, *"symlink-a".."symlink-z"].each_slice(2).map {|f, _| File.join(@root, f + "/") }.sort,
+ Dir.glob(File.join(@root, "*/")).sort)
+
+ Dir.glob(File.join(@root, "**/"))
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_dir_m17n.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_dir_m17n.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_dir_m17n.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,234 @@
+require 'test/unit'
+require 'tmpdir'
+require_relative 'envutil'
+
+class TestDir_M17N < Test::Unit::TestCase
+ def with_tmpdir
+ Dir.mktmpdir {|dir|
+ Dir.chdir(dir) {
+ yield dir
+ }
+ }
+ end
+
+ ## UTF-8 default_external, no default_internal
+
+ def test_filename_extutf8
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ with_tmpdir {|d|
+ assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d)
+ filename = "\u3042"
+ File.open(filename, "w") {}
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename)
+ EOS
+ }
+ end
+
+ def test_filename_extutf8_invalid
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ skip "ruby on windows doesn't support invalid utf-8 path" if /mswin|mingw/ =~ RUBY_PLATFORM
+ with_tmpdir {|d|
+ assert_ruby_status(%w[-EASCII-8BIT], <<-'EOS', nil, :chdir=>d)
+ filename = "\xff".force_encoding("ASCII-8BIT") # invalid byte sequence as UTF-8
+ File.open(filename, "w") {}
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename) || ((RUBY_PLATFORM =~ /darwin/) != nil && ents.include?("%FF"))
+ EOS
+ assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d)
+ filename = "\xff".force_encoding("UTF-8") # invalid byte sequence as UTF-8
+ File.open(filename, "w") {}
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename) || ((RUBY_PLATFORM =~ /darwin/) != nil && ents.include?("%FF"))
+ EOS
+ }
+ end
+
+ def test_filename_as_bytes_extutf8
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ with_tmpdir {|d|
+ assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d)
+ filename = "\xc2\xa1".force_encoding("utf-8")
+ File.open(filename, "w") {}
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename)
+ EOS
+ assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d)
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ filename = "\x8f\xa2\xc2".force_encoding("euc-jp")
+ else
+ filename = "\xc2\xa1".force_encoding("euc-jp")
+ end
+ begin
+ open(filename) {}
+ exit true
+ rescue Errno::ENOENT
+ exit false
+ end
+ EOS
+ skip "no meaning test on windows" if /mswin|mingw/ =~ RUBY_PLATFORM
+ assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d)
+ filename1 = "\xc2\xa1".force_encoding("utf-8")
+ filename2 = "\xc2\xa1".force_encoding("euc-jp")
+ filename3 = filename1.encode("euc-jp")
+ filename4 = filename2.encode("utf-8")
+ s1 = File.stat(filename1) rescue nil
+ s2 = File.stat(filename2) rescue nil
+ s3 = File.stat(filename3) rescue nil
+ s4 = File.stat(filename4) rescue nil
+ exit((s1 && s2 && !s3 && !s4) ? true : false)
+ EOS
+ }
+ end
+
+ ## UTF-8 default_external, EUC-JP default_internal
+
+ def test_filename_extutf8_inteucjp_representable
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ with_tmpdir {|d|
+ assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d)
+ filename = "\u3042"
+ File.open(filename, "w") {}
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename)
+ EOS
+ assert_ruby_status(%w[-EUTF-8:EUC-JP], <<-'EOS', nil, :chdir=>d)
+ filename = "\xA4\xA2".force_encoding("euc-jp")
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename)
+ EOS
+ assert_ruby_status(%w[-EUTF-8:EUC-JP], <<-'EOS', nil, :chdir=>d)
+ filename = "\xA4\xA2".force_encoding("euc-jp")
+ begin
+ open(filename) {}
+ exit true
+ rescue Errno::ENOENT
+ exit false
+ end
+ EOS
+ }
+ end
+
+ def test_filename_extutf8_inteucjp_unrepresentable
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ with_tmpdir {|d|
+ assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d)
+ filename1 = "\u2661" # WHITE HEART SUIT which is not representable in EUC-JP
+ filename2 = "\u3042" # HIRAGANA LETTER A which is representable in EUC-JP
+ File.open(filename1, "w") {}
+ File.open(filename2, "w") {}
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename1) && ents.include?(filename2)
+ EOS
+ assert_ruby_status(%w[-EUTF-8:EUC-JP], <<-'EOS', nil, :chdir=>d)
+ filename1 = "\u2661" # WHITE HEART SUIT which is not representable in EUC-JP
+ filename2 = "\xA4\xA2".force_encoding("euc-jp") # HIRAGANA LETTER A in EUC-JP
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename1) && ents.include?(filename2)
+ EOS
+ assert_ruby_status(%w[-EUTF-8:EUC-JP], <<-'EOS', nil, :chdir=>d)
+ filename1 = "\u2661" # WHITE HEART SUIT which is not representable in EUC-JP
+ filename2 = "\u3042" # HIRAGANA LETTER A which is representable in EUC-JP
+ filename3 = "\xA4\xA2".force_encoding("euc-jp") # HIRAGANA LETTER A in EUC-JP
+ s1 = File.stat(filename1) rescue nil
+ s2 = File.stat(filename2) rescue nil
+ s3 = File.stat(filename3) rescue nil
+ exit((s1 && s2 && s3) ? true : false)
+ EOS
+ }
+ end
+
+ ## others
+
+ def test_filename_bytes_euc_jp
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ with_tmpdir {|d|
+ assert_ruby_status(%w[-EEUC-JP], <<-'EOS', nil, :chdir=>d)
+ filename = "\xA4\xA2".force_encoding("euc-jp")
+ File.open(filename, "w") {}
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ ents.each {|e| e.force_encoding("ASCII-8BIT") }
+ exit ents.include?(filename.force_encoding("ASCII-8BIT")) ||
+ ((RUBY_PLATFORM =~ /darwin/) != nil && ents.include?("%A4%A2".force_encoding("ASCII-8BIT")))
+ EOS
+ }
+ end
+
+ def test_filename_euc_jp
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ with_tmpdir {|d|
+ assert_ruby_status(%w[-EEUC-JP], <<-'EOS', nil, :chdir=>d)
+ filename = "\xA4\xA2".force_encoding("euc-jp")
+ File.open(filename, "w") {}
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename) || ((RUBY_PLATFORM =~ /darwin/) != nil && ents.include?("%A4%A2".force_encoding("euc-jp")))
+ EOS
+ assert_ruby_status(%w[-EASCII-8BIT], <<-'EOS', nil, :chdir=>d)
+ filename = "\xA4\xA2"
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename) ||
+ ((RUBY_PLATFORM =~ /darwin/) != nil && ents.include?("%A4%A2".force_encoding("ASCII-8BIT"))) ||
+ ((RUBY_PLATFORM =~ /mswin|mingw/) != nil && ents.include?("\x82\xA0".force_encoding("ASCII-8BIT")))
+ EOS
+ }
+ end
+
+ def test_filename_utf8_raw_name
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ with_tmpdir {|d|
+ assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d)
+ filename = "\u3042".force_encoding("utf-8")
+ File.open(filename, "w") {}
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename)
+ EOS
+ assert_ruby_status(%w[-EASCII-8BIT], <<-'EOS', nil, :chdir=>d)
+ filename = "\u3042".force_encoding("ASCII-8BIT")
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename) || ((RUBY_PLATFORM =~ /mswin|mingw/) != nil && ents.include?("\x82\xA0".force_encoding("ASCII-8BIT")))
+ EOS
+ }
+ end
+
+ def test_filename_ext_euc_jp_and_int_utf_8
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ with_tmpdir {|d|
+ assert_ruby_status(%w[-EEUC-JP], <<-'EOS', nil, :chdir=>d)
+ filename = "\xA4\xA2".force_encoding("euc-jp")
+ File.open(filename, "w") {}
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename) || ((RUBY_PLATFORM =~ /darwin/) != nil && ents.include?("%A4%A2".force_encoding("euc-jp")))
+ EOS
+ assert_ruby_status(%w[-EEUC-JP:UTF-8], <<-'EOS', nil, :chdir=>d)
+ filename = "\u3042"
+ opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
+ ents = Dir.entries(".", opts)
+ exit ents.include?(filename) || ((RUBY_PLATFORM =~ /darwin/) != nil && ents.include?("%A4%A2"))
+ EOS
+ }
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/ruby/test_econv.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_econv.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_econv.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,901 @@
+require 'test/unit'
+
+class TestEncodingConverter < Test::Unit::TestCase
+ def check_ec(edst, esrc, eres, dst, src, ec, off, len, opts=nil)
+ res = ec.primitive_convert(src, dst, off, len, opts)
+ assert_equal([edst.dup.force_encoding("ASCII-8BIT"),
+ esrc.dup.force_encoding("ASCII-8BIT"),
+ eres],
+ [dst.dup.force_encoding("ASCII-8BIT"),
+ src.dup.force_encoding("ASCII-8BIT"),
+ res])
+ end
+
+ def assert_econv(converted, eres, obuf_bytesize, ec, consumed, rest, opts=nil)
+ ec = Encoding::Converter.new(*ec) if Array === ec
+ i = consumed + rest
+ o = ""
+ ret = ec.primitive_convert(i, o, 0, obuf_bytesize, opts)
+ assert_equal([converted, eres, rest],
+ [o, ret, i])
+ end
+
+ def assert_errinfo(e_res, e_enc1, e_enc2, e_error_bytes, e_readagain_bytes, ec)
+ assert_equal([e_res, e_enc1, e_enc2,
+ e_error_bytes && e_error_bytes.dup.force_encoding("ASCII-8BIT"),
+ e_readagain_bytes && e_readagain_bytes.dup.force_encoding("ASCII-8BIT")],
+ ec.primitive_errinfo)
+ end
+
+ def test_s_asciicompat_encoding
+ assert_equal(Encoding::STATELESS_ISO_2022_JP, Encoding::Converter.asciicompat_encoding("ISO-2022-JP"))
+ assert_equal(Encoding::STATELESS_ISO_2022_JP, Encoding::Converter.asciicompat_encoding(Encoding::ISO_2022_JP))
+ assert_equal(Encoding::UTF_8, Encoding::Converter.asciicompat_encoding("UTF-16BE"))
+ assert_equal(Encoding::UTF_8, Encoding::Converter.asciicompat_encoding("UTF-16LE"))
+ assert_equal(Encoding::UTF_8, Encoding::Converter.asciicompat_encoding("UTF-32BE"))
+ assert_equal(Encoding::UTF_8, Encoding::Converter.asciicompat_encoding("UTF-32LE"))
+ assert_nil(Encoding::Converter.asciicompat_encoding("EUC-JP"))
+ assert_nil(Encoding::Converter.asciicompat_encoding("UTF-8"))
+ assert_nil(Encoding::Converter.asciicompat_encoding(Encoding::UTF_8))
+ assert_nil(Encoding::Converter.asciicompat_encoding("xml_attr_escape"))
+ assert_nil(Encoding::Converter.asciicompat_encoding("encoding-not-exist"))
+ end
+
+ def test_asciicompat_encoding_iso2022jp
+ acenc = Encoding::Converter.asciicompat_encoding("ISO-2022-JP")
+ str = "\e$B~~\(B".force_encoding("iso-2022-jp")
+ str2 = str.encode(acenc)
+ str3 = str.encode("ISO-2022-JP")
+ assert_equal(str, str3)
+ end
+
+ def test_s_new
+ assert_kind_of(Encoding::Converter, Encoding::Converter.new("UTF-8", "EUC-JP"))
+ assert_kind_of(Encoding::Converter, Encoding::Converter.new(Encoding::UTF_8, Encoding::EUC_JP))
+ end
+
+ def test_s_new_convpath
+ assert_equal([], Encoding::Converter.new([]).convpath)
+ assert_equal([[Encoding::UTF_8, Encoding::EUC_JP]],
+ Encoding::Converter.new([["UTF-8", "EUC-JP"]]).convpath)
+ assert_equal([[Encoding::UTF_8, Encoding::WINDOWS_31J]],
+ Encoding::Converter.new([["utf-8", "cp932"]]).convpath)
+ assert_equal([[Encoding::UTF_8, Encoding::EUC_JP]],
+ Encoding::Converter.new([[Encoding::UTF_8, Encoding::EUC_JP]]).convpath)
+ assert_equal([[Encoding::ISO_8859_1, Encoding::UTF_8],
+ [Encoding::UTF_8, Encoding::EUC_JP]],
+ Encoding::Converter.new([["iso-8859-1", "euc-jp"]]).convpath)
+ assert_equal([[Encoding::ISO_8859_1, Encoding::UTF_8],
+ [Encoding::UTF_8, Encoding::EUC_JP],
+ "universal_newline"],
+ Encoding::Converter.new([["iso-8859-1", "euc-jp"], "universal_newline"]).convpath)
+ assert_equal(["universal_newline",
+ [Encoding::ISO_8859_1, Encoding::UTF_8],
+ [Encoding::UTF_8, Encoding::EUC_JP],
+ "universal_newline"],
+ Encoding::Converter.new(["universal_newline", ["iso-8859-1", "euc-jp"], "universal_newline"]).convpath)
+ end
+
+ def test_s_new_fail
+ name1 = "encoding-which-is-not-exist-1"
+ name2 = "encoding-which-is-not-exist-2"
+
+ assert_raise(Encoding::ConverterNotFoundError) {
+ Encoding::Converter.new(name1, name2)
+ }
+
+ encoding_list = Encoding.list.map {|e| e.name }
+ assert(!encoding_list.include?(name1))
+ assert(!encoding_list.include?(name2))
+ end
+
+ def test_newline_converter_with_ascii_incompatible
+ skip("[BUG : #___] Abort : not supported yet")
+
+ assert_nothing_raised {
+ Encoding::Converter.new("UTF-8", "UTF-16BE", Encoding::Converter::UNIVERSAL_NEWLINE_DECORATOR)
+ }
+ assert_nothing_raised {
+ Encoding::Converter.new("UTF-16BE", "UTF-8", Encoding::Converter::CRLF_NEWLINE_DECORATOR)
+ }
+ assert_nothing_raised {
+ Encoding::Converter.new("UTF-16BE", "UTF-8", Encoding::Converter::CR_NEWLINE_DECORATOR)
+ }
+
+ assert_nothing_raised {
+ Encoding::Converter.new("UTF-16BE", "UTF-8", Encoding::Converter::UNIVERSAL_NEWLINE_DECORATOR)
+ }
+ assert_nothing_raised {
+ Encoding::Converter.new("UTF-8", "UTF-16BE", Encoding::Converter::CRLF_NEWLINE_DECORATOR)
+ }
+ assert_nothing_raised {
+ Encoding::Converter.new("UTF-8", "UTF-16BE", Encoding::Converter::CR_NEWLINE_DECORATOR)
+ }
+ end
+
+ def test_get_encoding
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ assert_equal(Encoding::UTF_8, ec.source_encoding)
+ assert_equal(Encoding::EUC_JP, ec.destination_encoding)
+ end
+
+ def test_result_encoding
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ dst = "".force_encoding("ASCII-8BIT")
+ assert_equal(Encoding::ASCII_8BIT, dst.encoding)
+ ec.primitive_convert("\u{3042}", dst, nil, 10)
+ assert_equal(Encoding::EUC_JP, dst.encoding)
+ end
+
+ def test_output_region
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ ec.primitive_convert(src="a", dst="b", nil, 1, :partial_input=>true)
+ assert_equal("ba", dst)
+ ec.primitive_convert(src="a", dst="b", 0, 1, :partial_input=>true)
+ assert_equal("a", dst)
+ ec.primitive_convert(src="a", dst="b", 1, 1, :partial_input=>true)
+ assert_equal("ba", dst)
+ assert_raise(ArgumentError) {
+ ec.primitive_convert(src="a", dst="b", 2, 1, :partial_input=>true)
+ }
+ assert_raise(ArgumentError) {
+ ec.primitive_convert(src="a", dst="b", -1, 1, :partial_input=>true)
+ }
+ assert_raise(ArgumentError) {
+ ec.primitive_convert(src="a", dst="b", 1, -1, :partial_input=>true)
+ }
+ end
+
+ def test_nil_source_buffer
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ ret = ec.primitive_convert(nil, dst="", nil, 10)
+ assert_equal(:finished, ret)
+ end
+
+ def test_nil_destination_bytesize
+ ec = Encoding::Converter.new("Shift_JIS", "UTF-8")
+ n = 10000
+ src = "\xa1".force_encoding("Shift_JIS") * n
+ ret = ec.primitive_convert(src, dst="", nil, nil)
+ assert_equal(:finished, ret)
+ assert_equal("\xEF\xBD\xA1".force_encoding("UTF-8") * n, dst)
+ end
+
+ def test_nil_destination_bytesize2
+ ec = Encoding::Converter.new("Shift_JIS", "UTF-8")
+ n = 10000
+ src = "\xa1".force_encoding("Shift_JIS") * n
+ ret = ec.primitive_convert(src, dst="")
+ assert_equal(:finished, ret)
+ assert_equal("\xEF\xBD\xA1".force_encoding("UTF-8") * n, dst)
+ end
+
+ def test_nil_destination_bytesize_with_nonnil_byteoffset
+ ec = Encoding::Converter.new("Shift_JIS", "UTF-8")
+ n = 2000
+ src = "\xa1".force_encoding("Shift_JIS") * n
+ dst = "abcd" * 2000
+ ret = ec.primitive_convert(src, dst, 3, nil)
+ assert_equal(:finished, ret)
+ assert_equal("abc" + "\xEF\xBD\xA1".force_encoding("UTF-8") * n, dst)
+ end
+
+ def test_partial_input
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ ret = ec.primitive_convert(src="", dst="", nil, 10, :partial_input=>true)
+ assert_equal(:source_buffer_empty, ret)
+ ret = ec.primitive_convert(src="", dst="", nil, 10)
+ assert_equal(:finished, ret)
+ end
+
+ def test_accumulate_dst1
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ a = ["", "abc\u{3042}def", ec, nil, 1]
+ check_ec("a", "c\u{3042}def", :destination_buffer_full, *a)
+ check_ec("ab", "\u{3042}def", :destination_buffer_full, *a)
+ check_ec("abc", "def", :destination_buffer_full, *a)
+ check_ec("abc\xA4", "def", :destination_buffer_full, *a)
+ check_ec("abc\xA4\xA2", "ef", :destination_buffer_full, *a)
+ check_ec("abc\xA4\xA2d", "f", :destination_buffer_full, *a)
+ check_ec("abc\xA4\xA2de", "", :destination_buffer_full, *a)
+ check_ec("abc\xA4\xA2def", "", :finished, *a)
+ end
+
+ def test_accumulate_dst2
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ a = ["", "abc\u{3042}def", ec, nil, 2]
+ check_ec("ab", "\u{3042}def", :destination_buffer_full, *a)
+ check_ec("abc\xA4", "def", :destination_buffer_full, *a)
+ check_ec("abc\xA4\xA2d", "f", :destination_buffer_full, *a)
+ check_ec("abc\xA4\xA2def", "", :finished, *a)
+ end
+
+ def test_eucjp_to_utf8
+ assert_econv("", :finished, 100, ["UTF-8", "EUC-JP"], "", "")
+ assert_econv("a", :finished, 100, ["UTF-8", "EUC-JP"], "a", "")
+ end
+
+ def test_iso2022jp
+ assert_econv("", :finished, 100, ["Shift_JIS", "ISO-2022-JP"], "", "")
+ end
+
+ def test_iso2022jp_encode
+ ec = Encoding::Converter.new("EUC-JP", "ISO-2022-JP")
+ a = ["", src="", ec, nil, 50, :partial_input=>true]
+ src << "a"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "\xA2"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "\xA4"; check_ec("a\e$B\"$", "", :source_buffer_empty, *a)
+ src << "\xA1"; check_ec("a\e$B\"$", "", :source_buffer_empty, *a)
+ src << "\xA2"; check_ec("a\e$B\"$!\"", "", :source_buffer_empty, *a)
+ src << "b"; check_ec("a\e$B\"$!\"\e(Bb", "", :source_buffer_empty, *a)
+ src << "\xA2\xA6"; check_ec("a\e$B\"$!\"\e(Bb\e$B\"&", "", :source_buffer_empty, *a)
+ a[-1] = 0; check_ec("a\e$B\"$!\"\e(Bb\e$B\"&\e(B", "", :finished, *a)
+ end
+
+ def test_iso2022jp_decode
+ ec = Encoding::Converter.new("ISO-2022-JP", "EUC-JP")
+ a = ["", src="", ec, nil, 50, :partial_input=>true]
+ src << "a"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "\e"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "$"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "B"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "\x21"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "\x22"; check_ec("a\xA1\xA2", "", :source_buffer_empty, *a)
+ src << "\n"; check_ec("a\xA1\xA2", "", :invalid_byte_sequence, *a)
+ src << "\x23"; check_ec("a\xA1\xA2", "", :source_buffer_empty, *a)
+ src << "\x24"; check_ec("a\xA1\xA2\xA3\xA4", "", :source_buffer_empty, *a)
+ src << "\e"; check_ec("a\xA1\xA2\xA3\xA4", "", :source_buffer_empty, *a)
+ src << "("; check_ec("a\xA1\xA2\xA3\xA4", "", :source_buffer_empty, *a)
+ src << "B"; check_ec("a\xA1\xA2\xA3\xA4", "", :source_buffer_empty, *a)
+ src << "c"; check_ec("a\xA1\xA2\xA3\xA4c", "", :source_buffer_empty, *a)
+ src << "\n"; check_ec("a\xA1\xA2\xA3\xA4c\n","", :source_buffer_empty, *a)
+ end
+
+ def test_invalid
+ assert_econv("", :invalid_byte_sequence, 100, ["UTF-8", "EUC-JP"], "\x80", "")
+ assert_econv("a", :invalid_byte_sequence, 100, ["UTF-8", "EUC-JP"], "a\x80", "")
+ assert_econv("a", :invalid_byte_sequence, 100, ["UTF-8", "EUC-JP"], "a\x80", "\x80")
+ assert_econv("abc", :invalid_byte_sequence, 100, ["UTF-8", "EUC-JP"], "abc\xFF", "def")
+ assert_econv("abc", :invalid_byte_sequence, 100, ["Shift_JIS", "EUC-JP"], "abc\xFF", "def")
+ assert_econv("abc", :invalid_byte_sequence, 100, ["ISO-2022-JP", "EUC-JP"], "abc\xFF", "def")
+ end
+
+ def test_invalid2
+ ec = Encoding::Converter.new("Shift_JIS", "EUC-JP")
+ a = ["", "abc\xFFdef", ec, nil, 1]
+ check_ec("a", "c\xFFdef", :destination_buffer_full, *a)
+ check_ec("ab", "\xFFdef", :destination_buffer_full, *a)
+ check_ec("abc", "def", :invalid_byte_sequence, *a)
+ check_ec("abcd", "f", :destination_buffer_full, *a)
+ check_ec("abcde", "", :destination_buffer_full, *a)
+ check_ec("abcdef", "", :finished, *a)
+ end
+
+ def test_invalid3
+ ec = Encoding::Converter.new("Shift_JIS", "EUC-JP")
+ a = ["", "abc\xFFdef", ec, nil, 10]
+ check_ec("abc", "def", :invalid_byte_sequence, *a)
+ check_ec("abcdef", "", :finished, *a)
+ end
+
+ def test_invalid4
+ ec = Encoding::Converter.new("Shift_JIS", "EUC-JP")
+ a = ["", "abc\xFFdef", ec, nil, 10, :after_output=>true]
+ check_ec("a", "bc\xFFdef", :after_output, *a)
+ check_ec("ab", "c\xFFdef", :after_output, *a)
+ check_ec("abc", "\xFFdef", :after_output, *a)
+ check_ec("abc", "def", :invalid_byte_sequence, *a)
+ check_ec("abcd", "ef", :after_output, *a)
+ check_ec("abcde", "f", :after_output, *a)
+ check_ec("abcdef", "", :after_output, *a)
+ check_ec("abcdef", "", :finished, *a)
+ end
+
+ def test_invalid_utf16le
+ ec = Encoding::Converter.new("UTF-16LE", "UTF-8")
+ a = ["", src="", ec, nil, 50, :partial_input=>true]
+ src << "A"; check_ec("", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\xd8"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x01"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x02"; check_ec("A", "", :invalid_byte_sequence, *a)
+ src << "\x03"; check_ec("A\u{0201}", "", :source_buffer_empty, *a)
+ src << "\x04"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\xd8"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\xd8"; check_ec("A\u{0201}\u{0403}", "", :invalid_byte_sequence, *a)
+ src << "\x00"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\xdc"; check_ec("A\u{0201}\u{0403}\u{10000}", "", :source_buffer_empty, *a)
+ end
+
+ def test_invalid_utf16be
+ ec = Encoding::Converter.new("UTF-16BE", "UTF-8")
+ a = ["", src="", ec, nil, 50, :partial_input=>true]
+ src << "\x00"; check_ec("", "", :source_buffer_empty, *a)
+ src << "A"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\xd8"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x02"; check_ec("A", "", :invalid_byte_sequence, *a)
+ src << "\x01"; check_ec("A\u{0201}", "", :source_buffer_empty, *a)
+ src << "\x04"; check_ec("A\u{0201}", "", :source_buffer_empty, *a)
+ src << "\x03"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\xd8"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\xd8"; check_ec("A\u{0201}\u{0403}", "", :invalid_byte_sequence, *a)
+ src << "\x00"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\xdc"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A\u{0201}\u{0403}\u{10000}", "", :source_buffer_empty, *a)
+ end
+
+ def test_invalid_utf32be
+ ec = Encoding::Converter.new("UTF-32BE", "UTF-8")
+ a = ["", src="", ec, nil, 50, :partial_input=>true]
+ src << "\x00"; check_ec("", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("", "", :source_buffer_empty, *a)
+ src << "A"; check_ec("A", "", :source_buffer_empty, *a)
+
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\xdc"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :invalid_byte_sequence, *a)
+
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "B"; check_ec("AB", "", :source_buffer_empty, *a)
+
+ src << "\x00"; check_ec("AB", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("AB", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("AB", "", :source_buffer_empty, *a)
+ src << "C"; check_ec("ABC", "", :source_buffer_empty, *a)
+ end
+
+ def test_invalid_utf32le
+ ec = Encoding::Converter.new("UTF-32LE", "UTF-8")
+ a = ["", src="", ec, nil, 50, :partial_input=>true]
+ src << "A"; check_ec("", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\xdc"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :invalid_byte_sequence, *a)
+
+ src << "B"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("AB", "", :source_buffer_empty, *a)
+
+ src << "C"; check_ec("AB", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("AB", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("AB", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("ABC", "", :source_buffer_empty, *a)
+ end
+
+ def test_errors
+ ec = Encoding::Converter.new("UTF-16BE", "EUC-JP")
+ a = ["", "\xFF\xFE\x00A\xDC\x00\x00B", ec, nil, 10]
+ check_ec("", "\x00A\xDC\x00\x00B", :undefined_conversion, *a)
+ check_ec("A", "\x00B", :invalid_byte_sequence, *a) # \xDC\x00 is invalid as UTF-16BE
+ check_ec("AB", "", :finished, *a)
+ end
+
+ def test_errors2
+ ec = Encoding::Converter.new("UTF-16BE", "EUC-JP")
+ a = ["", "\xFF\xFE\x00A\xDC\x00\x00B", ec, nil, 10, :after_output=>true]
+ check_ec("", "\x00A\xDC\x00\x00B", :undefined_conversion, *a)
+ check_ec("A", "\xDC\x00\x00B", :after_output, *a)
+ check_ec("A", "\x00B", :invalid_byte_sequence, *a)
+ check_ec("AB", "", :after_output, *a)
+ check_ec("AB", "", :finished, *a)
+ end
+
+ def test_universal_newline
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", universal_newline: true)
+ a = ["", src="", ec, nil, 50, :partial_input=>true]
+ src << "abc\r\ndef"; check_ec("abc\ndef", "", :source_buffer_empty, *a)
+ src << "ghi\njkl"; check_ec("abc\ndefghi\njkl", "", :source_buffer_empty, *a)
+ src << "mno\rpqr"; check_ec("abc\ndefghi\njklmno\npqr", "", :source_buffer_empty, *a)
+ src << "stu\r"; check_ec("abc\ndefghi\njklmno\npqrstu", "", :source_buffer_empty, *a)
+ src << "\nvwx"; check_ec("abc\ndefghi\njklmno\npqrstu\nvwx", "", :source_buffer_empty, *a)
+ src << "\nyz"; check_ec("abc\ndefghi\njklmno\npqrstu\nvwx\nyz", "", :source_buffer_empty, *a)
+ end
+
+ def test_universal_newline2
+ ec = Encoding::Converter.new("", "", universal_newline: true)
+ a = ["", src="", ec, nil, 50, :partial_input=>true]
+ src << "abc\r\ndef"; check_ec("abc\ndef", "", :source_buffer_empty, *a)
+ src << "ghi\njkl"; check_ec("abc\ndefghi\njkl", "", :source_buffer_empty, *a)
+ src << "mno\rpqr"; check_ec("abc\ndefghi\njklmno\npqr", "", :source_buffer_empty, *a)
+ src << "stu\r"; check_ec("abc\ndefghi\njklmno\npqrstu", "", :source_buffer_empty, *a)
+ src << "\nvwx"; check_ec("abc\ndefghi\njklmno\npqrstu\nvwx", "", :source_buffer_empty, *a)
+ src << "\nyz"; check_ec("abc\ndefghi\njklmno\npqrstu\nvwx\nyz", "", :source_buffer_empty, *a)
+ end
+
+ def test_universal_newline3
+ ec = Encoding::Converter.new("", "", universal_newline: true)
+ a = ["", src="", ec, nil, 50, :partial_input=>true]
+ src << "abc\r\ndef"; check_ec("abc\ndef", "", :source_buffer_empty, *a)
+ src << "ghi\njkl"; check_ec("abc\ndefghi\njkl", "", :source_buffer_empty, *a)
+ src << "mno\rpqr"; check_ec("abc\ndefghi\njklmno\npqr", "", :source_buffer_empty, *a)
+ src << "stu\r"; check_ec("abc\ndefghi\njklmno\npqrstu", "", :source_buffer_empty, *a)
+ src << "\nvwx"; check_ec("abc\ndefghi\njklmno\npqrstu\nvwx", "", :source_buffer_empty, *a)
+ src << "\nyz"; check_ec("abc\ndefghi\njklmno\npqrstu\nvwx\nyz", "", :source_buffer_empty, *a)
+ src << "\r"; check_ec("abc\ndefghi\njklmno\npqrstu\nvwx\nyz", "", :source_buffer_empty, *a)
+ a[-1] = nil
+ src << ""; check_ec("abc\ndefghi\njklmno\npqrstu\nvwx\nyz\n", "", :finished, *a)
+ end
+
+ def test_crlf_newline
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", crlf_newline: true)
+ assert_econv("abc\r\ndef", :finished, 50, ec, "abc\ndef", "")
+ end
+
+ def test_crlf_newline2
+ ec = Encoding::Converter.new("", "", crlf_newline: true)
+ assert_econv("abc\r\ndef", :finished, 50, ec, "abc\ndef", "")
+ end
+
+ def test_cr_newline
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", cr_newline: true)
+ assert_econv("abc\rdef", :finished, 50, ec, "abc\ndef", "")
+ end
+
+ def test_cr_newline2
+ ec = Encoding::Converter.new("", "", cr_newline: true)
+ assert_econv("abc\rdef", :finished, 50, ec, "abc\ndef", "")
+ end
+
+ def test_after_output
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ a = ["", "abc\u{3042}def", ec, nil, 100, :after_output=>true]
+ check_ec("a", "bc\u{3042}def", :after_output, *a)
+ check_ec("ab", "c\u{3042}def", :after_output, *a)
+ check_ec("abc", "\u{3042}def", :after_output, *a)
+ check_ec("abc\xA4\xA2", "def", :after_output, *a)
+ check_ec("abc\xA4\xA2d", "ef", :after_output, *a)
+ check_ec("abc\xA4\xA2de", "f", :after_output, *a)
+ check_ec("abc\xA4\xA2def", "", :after_output, *a)
+ check_ec("abc\xA4\xA2def", "", :finished, *a)
+ end
+
+ def test_errinfo_invalid_euc_jp
+ ec = Encoding::Converter.new("EUC-JP", "Shift_JIS")
+ ec.primitive_convert(src="\xff", dst="", nil, 10)
+ assert_errinfo(:invalid_byte_sequence, "EUC-JP", "Shift_JIS", "\xFF", "", ec)
+ end
+
+ def test_errinfo_invalid_euc_jp2
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.primitive_convert(src="\xff", dst="", nil, 10)
+ assert_errinfo(:invalid_byte_sequence, "EUC-JP", "UTF-8", "\xFF", "", ec)
+ end
+
+ def test_errinfo_undefined_hiragana
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.primitive_convert(src="\xa4\xa2", dst="", nil, 10)
+ assert_errinfo(:undefined_conversion, "UTF-8", "ISO-8859-1", "\xE3\x81\x82", "", ec)
+ end
+
+ def test_errinfo_invalid_partial_character
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.primitive_convert(src="\xa4", dst="", nil, 10)
+ assert_errinfo(:incomplete_input, "EUC-JP", "UTF-8", "\xA4", "", ec)
+ end
+
+ def test_errinfo_valid_partial_character
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.primitive_convert(src="\xa4", dst="", nil, 10, :partial_input=>true)
+ assert_errinfo(:source_buffer_empty, nil, nil, nil, nil, ec)
+ end
+
+ def test_errinfo_invalid_utf16be
+ ec = Encoding::Converter.new("UTF-16BE", "UTF-8")
+ ec.primitive_convert(src="\xd8\x00\x00@", dst="", nil, 10)
+ assert_errinfo(:invalid_byte_sequence, "UTF-16BE", "UTF-8", "\xD8\x00", "\x00", ec)
+ assert_equal("@", src)
+ end
+
+ def test_errinfo_invalid_utf16le
+ ec = Encoding::Converter.new("UTF-16LE", "UTF-8")
+ ec.primitive_convert(src="\x00\xd8@\x00", dst="", nil, 10)
+ assert_errinfo(:invalid_byte_sequence, "UTF-16LE", "UTF-8", "\x00\xD8", "@\x00", ec)
+ assert_equal("", src)
+ end
+
+ def test_output_iso2022jp
+ ec = Encoding::Converter.new("EUC-JP", "ISO-2022-JP")
+ ec.primitive_convert(src="\xa1\xa1", dst="", nil, 10, :partial_input=>true)
+ assert_equal("\e$B!!".force_encoding("ISO-2022-JP"), dst)
+ assert_equal(nil, ec.insert_output("???"))
+ ec.primitive_convert("", dst, nil, 10, :partial_input=>true)
+ assert_equal("\e$B!!\e(B???".force_encoding("ISO-2022-JP"), dst)
+ ec.primitive_convert(src="\xa1\xa2", dst, nil, 10, :partial_input=>true)
+ assert_equal("\e$B!!\e(B???\e$B!\"".force_encoding("ISO-2022-JP"), dst)
+
+ assert_equal(nil, ec.insert_output("\xA1\xA1".force_encoding("EUC-JP")))
+ ec.primitive_convert("", dst, nil, 10, :partial_input=>true)
+ assert_equal("\e$B!!\e(B???\e$B!\"!!".force_encoding("ISO-2022-JP"), dst)
+
+ ec.primitive_convert(src="\xa1\xa3", dst, nil, 10, :partial_input=>true)
+ assert_equal("\e$B!!\e(B???\e$B!\"!!!\#".force_encoding("ISO-2022-JP"), dst)
+
+ assert_equal(nil, ec.insert_output("\u3042"))
+ ec.primitive_convert("", dst, nil, 10, :partial_input=>true)
+ assert_equal("\e$B!!\e(B???\e$B!\"!!!\#$\"".force_encoding("ISO-2022-JP"), dst)
+
+ assert_raise(Encoding::UndefinedConversionError) {
+ ec.insert_output("\uFFFD")
+ }
+
+ assert_equal("\e$B!!\e(B???\e$B!\"!!!\#$\"".force_encoding("ISO-2022-JP"), dst)
+
+ ec.primitive_convert("", dst, nil, 10)
+ assert_equal("\e$B!!\e(B???\e$B!\"!!!\#$\"\e(B".force_encoding("ISO-2022-JP"), dst)
+ end
+
+ def test_exc_invalid
+ err = assert_raise(Encoding::InvalidByteSequenceError) {
+ "abc\xa4def".encode("ISO-8859-1", "EUC-JP")
+ }
+ assert_equal("EUC-JP", err.source_encoding_name)
+ assert_equal("UTF-8", err.destination_encoding_name)
+ assert_equal(Encoding::EUC_JP, err.source_encoding)
+ assert_equal(Encoding::UTF_8, err.destination_encoding)
+ assert_equal("\xA4".force_encoding("ASCII-8BIT"), err.error_bytes)
+ assert_equal("d", err.readagain_bytes)
+ assert_equal(false, err.incomplete_input?)
+ end
+
+ def test_exc_incomplete
+ err = assert_raise(Encoding::InvalidByteSequenceError) {
+ "abc\xa4".encode("ISO-8859-1", "EUC-JP")
+ }
+ assert_equal("EUC-JP", err.source_encoding_name)
+ assert_equal("UTF-8", err.destination_encoding_name)
+ assert_equal(Encoding::EUC_JP, err.source_encoding)
+ assert_equal(Encoding::UTF_8, err.destination_encoding)
+ assert_equal("\xA4".force_encoding("ASCII-8BIT"), err.error_bytes)
+ assert_equal(nil, err.readagain_bytes)
+ assert_equal(true, err.incomplete_input?)
+ end
+
+ def test_exc_undef
+ err = assert_raise(Encoding::UndefinedConversionError) {
+ "abc\xa4\xa2def".encode("ISO-8859-1", "EUC-JP")
+ }
+ assert_equal("UTF-8", err.source_encoding_name)
+ assert_equal("ISO-8859-1", err.destination_encoding_name)
+ assert_equal(Encoding::UTF_8, err.source_encoding)
+ assert_equal(Encoding::ISO_8859_1, err.destination_encoding)
+ assert_equal("\u{3042}", err.error_char)
+ end
+
+ def test_putback
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ret = ec.primitive_convert(src="abc\xa1def", dst="", nil, 10)
+ assert_equal(:invalid_byte_sequence, ret)
+ assert_equal(["abc", "ef"], [dst, src])
+ src = ec.putback + src
+ assert_equal(["abc", "def"], [dst, src])
+ ret = ec.primitive_convert(src, dst, nil, 10)
+ assert_equal(:finished, ret)
+ assert_equal(["abcdef", ""], [dst, src])
+ end
+
+ def test_putback2
+ ec = Encoding::Converter.new("utf-16le", "euc-jp")
+ ret = ec.primitive_convert(src="\x00\xd8\x21\x00", dst="", nil, nil)
+ assert_equal(:invalid_byte_sequence, ret)
+ assert_equal("\x00".force_encoding("utf-16le"), ec.putback(1))
+ assert_equal("\x21".force_encoding("utf-16le"), ec.putback(1))
+ assert_equal("", ec.putback(1))
+ end
+
+ def test_invalid_replace
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", invalid: :replace)
+ ret = ec.primitive_convert(src="abc\x80def", dst="", nil, 100)
+ assert_equal(:finished, ret)
+ assert_equal("", src)
+ assert_equal("abc?def", dst)
+ end
+
+ def test_invalid_ignore
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", :invalid => :replace, :replace => "")
+ ret = ec.primitive_convert(src="abc\x80def", dst="", nil, 100)
+ assert_equal(:finished, ret)
+ assert_equal("", src)
+ assert_equal("abcdef", dst)
+ end
+
+ def test_undef_replace
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", :undef => :replace)
+ ret = ec.primitive_convert(src="abc\u{fffd}def", dst="", nil, 100)
+ assert_equal(:finished, ret)
+ assert_equal("", src)
+ assert_equal("abc?def", dst)
+ end
+
+ def test_undef_ignore
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", :undef => :replace, :replace => "")
+ ret = ec.primitive_convert(src="abc\u{fffd}def", dst="", nil, 100)
+ assert_equal(:finished, ret)
+ assert_equal("", src)
+ assert_equal("abcdef", dst)
+ end
+
+ def test_noconv
+ ec = Encoding::Converter.new("", "")
+ assert_equal(nil, ec.source_encoding)
+ assert_equal(nil, ec.destination_encoding)
+ assert_equal([:source_buffer_empty, nil, nil, nil, nil], ec.primitive_errinfo)
+ a = ["", "abcdefg", ec, nil, 2]
+ check_ec("ab", "cdefg", :destination_buffer_full, *a)
+ check_ec("abcd", "efg", :destination_buffer_full, *a)
+ check_ec("abcdef", "g", :destination_buffer_full, *a)
+ check_ec("abcdefg", "", :finished, *a)
+ end
+
+ def test_noconv_partial
+ ec = Encoding::Converter.new("", "")
+ a = ["", "abcdefg", ec, nil, 2, :partial_input=>true]
+ check_ec("ab", "cdefg", :destination_buffer_full, *a)
+ check_ec("abcd", "efg", :destination_buffer_full, *a)
+ check_ec("abcdef", "g", :destination_buffer_full, *a)
+ check_ec("abcdefg", "", :source_buffer_empty, *a)
+ end
+
+ def test_noconv_after_output
+ ec = Encoding::Converter.new("", "")
+ a = ["", "abcdefg", ec, nil, 2, :after_output=>true]
+ check_ec("a", "bcdefg", :after_output, *a)
+ check_ec("ab", "cdefg", :after_output, *a)
+ check_ec("abc", "defg", :after_output, *a)
+ check_ec("abcd", "efg", :after_output, *a)
+ check_ec("abcde", "fg", :after_output, *a)
+ check_ec("abcdef", "g", :after_output, *a)
+ check_ec("abcdefg", "", :after_output, *a)
+ check_ec("abcdefg", "", :finished, *a)
+ end
+
+ def test_noconv_insert_output
+ ec = Encoding::Converter.new("", "")
+ ec.insert_output("xyz")
+ ret = ec.primitive_convert(src="abc", dst="", nil, 20)
+ assert_equal(:finished, ret)
+ assert_equal(["xyzabc", ""], [dst, src])
+ end
+
+ def test_convert
+ ec = Encoding::Converter.new("utf-8", "euc-jp")
+ assert_raise(Encoding::InvalidByteSequenceError) { ec.convert("a\x80") }
+ assert_raise(Encoding::UndefinedConversionError) { ec.convert("\ufffd") }
+ ret = ec.primitive_convert(nil, "", nil, nil)
+ assert_equal(:finished, ret)
+ assert_raise(ArgumentError) { ec.convert("a") }
+ end
+
+ def test_finish_iso2022jp
+ ec = Encoding::Converter.new("utf-8", "iso-2022-jp")
+ assert_equal("\e$B$\"".force_encoding("iso-2022-jp"), ec.convert("\u3042"))
+ assert_equal("\e(B".force_encoding("iso-2022-jp"), ec.finish)
+
+ end
+
+ def test_finish_incomplete_error
+ ec = Encoding::Converter.new("utf-8", "euc-jp")
+ ec.convert("\xEF")
+ assert_raise(Encoding::InvalidByteSequenceError) { ec.finish }
+ end
+
+ def test_last_error1
+ ec = Encoding::Converter.new("sjis", "euc-jp")
+ assert_equal(nil, ec.last_error)
+ assert_equal(:incomplete_input, ec.primitive_convert(src="fo\x81", dst="", nil, nil))
+ assert_kind_of(Encoding::InvalidByteSequenceError, ec.last_error)
+ end
+
+ def test_last_error2
+ ec = Encoding::Converter.new("sjis", "euc-jp")
+ assert_equal("fo", ec.convert(src="fo\x81"))
+ assert_raise(Encoding::InvalidByteSequenceError) { ec.finish }
+ assert_kind_of(Encoding::InvalidByteSequenceError, ec.last_error)
+ end
+
+ def test_us_ascii
+ ec = Encoding::Converter.new("UTF-8", "US-ASCII")
+ ec.primitive_convert(src="\u{3042}", dst="")
+ err = ec.last_error
+ assert_kind_of(Encoding::UndefinedConversionError, err)
+ assert_equal("\u{3042}", err.error_char)
+ end
+
+ def test_88591
+ ec = Encoding::Converter.new("UTF-8", "ISO-8859-1")
+ ec.primitive_convert(src="\u{3042}", dst="")
+ err = ec.last_error
+ assert_kind_of(Encoding::UndefinedConversionError, err)
+ assert_equal("\u{3042}", err.error_char)
+ end
+
+ def test_get_replacement
+ ec = Encoding::Converter.new("euc-jp", "iso-8859-1")
+ assert_equal("?", ec.replacement)
+
+ ec = Encoding::Converter.new("euc-jp", "utf-8")
+ assert_equal("\uFFFD", ec.replacement)
+ end
+
+ def test_set_replacement
+ ec = Encoding::Converter.new("utf-8", "us-ascii", :undef => :replace)
+ ec.replacement = "<undef>"
+ assert_equal("a <undef> b", ec.convert("a \u3042 b"))
+ end
+
+ def test_econv_new_hash
+ ec = Encoding::Converter.new("utf-8", "us-ascii", :undef => :replace)
+ assert_equal("a ? b", ec.convert("a \u3042 b"))
+ ec = Encoding::Converter.new("utf-8", "us-ascii", :undef => :replace, :replace => "X")
+ assert_equal("a X b", ec.convert("a \u3042 b"))
+ end
+
+ def test_hex_charref
+ skip("[BUG : #___] Abort : not supported yet")
+
+ ec = Encoding::Converter.new("UTF-8", "US-ASCII", Encoding::Converter::UNDEF_HEX_CHARREF)
+ assert_equal("あ", ec.convert("\u3042"))
+
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", Encoding::Converter::UNDEF_HEX_CHARREF)
+ assert_equal("\xa4\xcf\xa4\xa1\xa4\xa4♥\xa1\xa3".force_encoding("euc-jp"),
+ ec.convert("\u{306f 3041 3044 2665 3002}"))
+
+ ec = Encoding::Converter.new("UTF-8", "ISO-2022-JP", Encoding::Converter::UNDEF_HEX_CHARREF)
+ assert_equal("\e$B$O$!$$\e(B♥\e$B!#".force_encoding("ISO-2022-JP"),
+ ec.convert("\u{306f 3041 3044 2665 3002}"))
+ assert_equal("\e(B".force_encoding("ISO-2022-JP"),
+ ec.finish)
+
+ ec = Encoding::Converter.new("EUC-JP", "US-ASCII", Encoding::Converter::UNDEF_HEX_CHARREF)
+ assert_equal("交換法則: n×m=m×n".force_encoding("ISO-8859-1"),
+ ec.convert("\xB8\xF2\xB4\xB9\xCB\xA1\xC2\xA7: n\xA1\xDFm=m\xA1\xDFn"))
+
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1", Encoding::Converter::UNDEF_HEX_CHARREF)
+ assert_equal("交換法則: n\xD7m=m\xD7n".force_encoding("ISO-8859-1"),
+ ec.convert("\xB8\xF2\xB4\xB9\xCB\xA1\xC2\xA7: n\xA1\xDFm=m\xA1\xDFn"))
+
+ ec = Encoding::Converter.new("UTF-8", "US-ASCII", Encoding::Converter::UNDEF_HEX_CHARREF)
+ assert_equal("&", ec.convert("&"))
+ end
+
+ def test_xml_escape_text
+ ec = Encoding::Converter.new("", "amp_escape")
+ assert_equal('&<>"', ec.convert("&<>\""))
+ assert_equal('', ec.finish)
+
+ ec = Encoding::Converter.new("", "xml_text_escape")
+ assert_equal('&<>"', ec.convert("&<>\""))
+ assert_equal('', ec.finish)
+ end
+
+ def test_xml_escape_attr_content
+ ec = Encoding::Converter.new("", "xml_attr_content_escape")
+ assert_equal('', ec.finish)
+
+ ec = Encoding::Converter.new("", "xml_attr_content_escape")
+ assert_equal('', ec.convert(""))
+ assert_equal('', ec.finish)
+
+ ec = Encoding::Converter.new("", "xml_attr_content_escape")
+ assert_equal('"', ec.convert('"'))
+ assert_equal('', ec.finish)
+
+ ec = Encoding::Converter.new("", "xml_attr_content_escape")
+ assert_equal('&<>"', ec.convert("&<>\""))
+ assert_equal('', ec.finish)
+ end
+
+ def test_xml_escape_attr_quote
+ ec = Encoding::Converter.new("", "xml_attr_quote")
+ assert_equal('""', ec.finish)
+
+ ec = Encoding::Converter.new("", "xml_attr_quote")
+ assert_equal('', ec.convert(""))
+ assert_equal('""', ec.finish)
+
+ ec = Encoding::Converter.new("", "xml_attr_quote")
+ assert_equal('""', ec.convert('"'))
+ assert_equal('"', ec.finish)
+
+ ec = Encoding::Converter.new("", "xml_attr_quote")
+ assert_equal('"&<>"', ec.convert("&<>\""))
+ assert_equal('"', ec.finish)
+ end
+
+ def test_xml_escape_with_charref
+ skip("[BUG : #___] Abort : not supported yet")
+
+ ec = Encoding::Converter.new("utf-8", "euc-jp", Encoding::Converter::XML_TEXT_DECORATOR|Encoding::Converter::UNDEF_HEX_CHARREF)
+ assert_equal('<♥>&"♡"', ec.convert("<\u2665>&\"\u2661\""))
+ assert_equal('', ec.finish)
+
+ ec = Encoding::Converter.new("utf-8", "euc-jp",
+ Encoding::Converter::XML_ATTR_CONTENT_DECORATOR|
+ Encoding::Converter::XML_ATTR_QUOTE_DECORATOR|
+ Encoding::Converter::UNDEF_HEX_CHARREF)
+ assert_equal('"<♥>&"♡"', ec.convert("<\u2665>&\"\u2661\""))
+ assert_equal('"', ec.finish)
+
+ ec = Encoding::Converter.new("utf-8", "iso-2022-jp", Encoding::Converter::XML_TEXT_DECORATOR)
+ assert_equal("&\e$B$&\e(B&".force_encoding("iso-2022-jp"), ec.convert("&\u3046&"))
+ assert_equal('', ec.finish)
+ end
+
+ def test_xml_hasharg
+ assert_equal("&\e$B$&\e(B♥&\"'".force_encoding("iso-2022-jp"),
+ "&\u3046\u2665&\"'".encode("iso-2022-jp", xml: :text))
+ assert_equal("\"&\e$B$&\e(B♡&"'\"".force_encoding("iso-2022-jp"),
+ "&\u3046\u2661&\"'".encode("iso-2022-jp", xml: :attr))
+
+ assert_equal("&\u3046\u2661&\"'".force_encoding("utf-8"),
+ "&\u3046\u2661&\"'".encode("utf-8", xml: :text))
+ end
+
+ def test_iso2022jp_invalid_replace
+ assert_equal("?x".force_encoding("iso-2022-jp"),
+ "\222\xA1x".encode("iso-2022-jp", "stateless-iso-2022-jp", :invalid => :replace))
+ end
+
+ def test_convpath
+ eucjp = Encoding::EUC_JP
+ utf8 = Encoding::UTF_8
+ utf16be = Encoding::UTF_16BE
+ utf16le = Encoding::UTF_16LE
+ iso88591 = Encoding::ISO_8859_1
+ iso2022jp = Encoding::ISO_2022_JP
+ siso2022jp = Encoding::STATELESS_ISO_2022_JP
+
+ assert_equal([], Encoding::Converter.new("", "").convpath)
+ assert_equal([[eucjp, utf8], [utf8, iso88591]],
+ Encoding::Converter.new(eucjp, iso88591).convpath)
+ assert_equal([[eucjp, siso2022jp], [siso2022jp, iso2022jp]],
+ Encoding::Converter.new(eucjp, iso2022jp).convpath)
+ assert_equal([[iso2022jp, siso2022jp],
+ [siso2022jp, eucjp],
+ [eucjp, utf8],
+ [utf8, iso88591]],
+ Encoding::Converter.new(iso2022jp, iso88591).convpath)
+ assert_equal(["universal_newline", [utf8, utf16be]],
+ Encoding::Converter.new(utf8, utf16be, universal_newline: true).convpath)
+ assert_equal([[utf16be, utf8], "universal_newline"],
+ Encoding::Converter.new(utf16be, utf8, universal_newline: true).convpath)
+ assert_equal([[utf16be, utf8], "universal_newline", [utf8, utf16le]],
+ Encoding::Converter.new(utf16be, utf16le, universal_newline: true).convpath)
+ end
+
+ def test_search_convpath
+ eucjp = Encoding::EUC_JP
+ utf8 = Encoding::UTF_8
+ utf32be = Encoding::UTF_32BE
+ iso88591 = Encoding::ISO_8859_1
+ assert_equal([[iso88591,utf8], [utf8,eucjp]],
+ Encoding::Converter.search_convpath("ISO-8859-1", "EUC-JP"))
+ assert_equal([[iso88591,utf8], [utf8,eucjp]],
+ Encoding::Converter.search_convpath(iso88591, eucjp))
+ assert_equal([[iso88591,utf8], [utf8,eucjp], "universal_newline"],
+ Encoding::Converter.search_convpath("ISO-8859-1", "EUC-JP", universal_newline: true))
+ assert_equal([[iso88591,utf8], "universal_newline", [utf8,utf32be]],
+ Encoding::Converter.search_convpath("ISO-8859-1", "UTF-32BE", universal_newline: true))
+ end
+
+ def test_invalid_replace2
+ assert_raise(ArgumentError) {
+ broken = "\x80".force_encoding("euc-jp")
+ "".encode("euc-jp", :undef => :replace, :replace => broken)
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_encoding.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_encoding.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_encoding.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,98 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestEncoding < Test::Unit::TestCase
+
+ # Test basic encoding methods: list, find, name
+ def test_encoding
+ encodings = Encoding.list
+ assert_equal(encodings.empty?, false)
+
+ encodings.each do |e|
+ assert_equal(e, Encoding.find(e.name))
+ assert_equal(e, Encoding.find(e.name.upcase))
+ assert_equal(e, Encoding.find(e.name.capitalize))
+ assert_equal(e, Encoding.find(e.name.downcase))
+ end
+ end
+
+ def test_enc_names
+ aliases = Encoding.aliases
+ aliases.each do |a, en|
+ e = Encoding.find(a)
+ assert_equal(e.name, en)
+ assert(e.names.include?(a))
+ end
+ end
+
+ # Test that Encoding objects can't be copied
+ # And that they can be compared by object_id
+ def test_singleton
+ encodings = Encoding.list
+ encodings.each do |e|
+ assert_raise(TypeError) { e.dup }
+ assert_raise(TypeError) { e.clone }
+ assert_equal(e.object_id, Marshal.load(Marshal.dump(e)).object_id)
+ end
+ end
+
+ def test_find
+ assert_raise(ArgumentError) { Encoding.find("foobarbazqux") }
+ assert_nothing_raised{Encoding.find("locale")}
+ assert_nothing_raised{Encoding.find("filesystem")}
+
+ if /(?:ms|dar)win/ !~ RUBY_PLATFORM
+ # Unix's filesystem encoding is default_external
+ assert_ruby_status(%w[-EUTF-8:EUC-JP], <<-'EOS')
+ exit Encoding.find("filesystem") == Encoding::UTF_8
+ Encoding.default_external = Encoding::EUC_JP
+ exit Encoding.find("filesystem") == Encoding::EUC_JP
+ EOS
+ end
+ end
+
+ def test_replicate
+ assert_instance_of(Encoding, Encoding::UTF_8.replicate('UTF-8-ANOTHER'))
+ assert_instance_of(Encoding, Encoding::ISO_2022_JP.replicate('ISO-2022-JP-ANOTHER'))
+ bug3127 = '[ruby-dev:40954]'
+ assert_raise(TypeError, bug3127) {Encoding::UTF_8.replicate(0)}
+ assert_raise(ArgumentError, bug3127) {Encoding::UTF_8.replicate("\0")}
+ end
+
+ def test_dummy_p
+ assert_equal(true, Encoding::ISO_2022_JP.dummy?)
+ assert_equal(false, Encoding::UTF_8.dummy?)
+ end
+
+ def test_ascii_compatible_p
+ assert_equal(true, Encoding::ASCII_8BIT.ascii_compatible?)
+ assert_equal(true, Encoding::UTF_8.ascii_compatible?)
+ assert_equal(false, Encoding::UTF_16BE.ascii_compatible?)
+ assert_equal(false, Encoding::ISO_2022_JP.ascii_compatible?)
+ end
+
+ def test_name_list
+ assert_instance_of(Array, Encoding.name_list)
+ Encoding.name_list.each do |x|
+ assert_instance_of(String, x)
+ end
+ end
+
+ def test_aliases
+ assert_instance_of(Hash, Encoding.aliases)
+ Encoding.aliases.each do |k, v|
+ assert(Encoding.name_list.include?(k))
+ assert(Encoding.name_list.include?(v))
+ assert_instance_of(String, k)
+ assert_instance_of(String, v)
+ end
+ end
+
+ def test_marshal
+ str = "".force_encoding("EUC-JP")
+ str2 = Marshal.load(Marshal.dump(str))
+ assert_equal(str, str2)
+ str2 = Marshal.load(Marshal.dump(str2))
+ assert_equal(str, str2, '[ruby-dev:38596]')
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_enum.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_enum.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_enum.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,387 @@
+require 'test/unit'
+#require 'continuation'
+
+class TestEnumerable < Test::Unit::TestCase
+ def setup
+ @obj = Object.new
+ class << @obj
+ include Enumerable
+ def each
+ yield 1
+ yield 2
+ yield 3
+ yield 1
+ yield 2
+ end
+ end
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_grep
+ assert_equal([1, 2, 1, 2], @obj.grep(1..2))
+ a = []
+ @obj.grep(2) {|x| a << x }
+ assert_equal([2, 2], a)
+ end
+
+ def test_count
+ assert_equal(5, @obj.count)
+ assert_equal(2, @obj.count(1))
+ assert_equal(3, @obj.count {|x| x % 2 == 1 })
+ assert_equal(2, @obj.count(1) {|x| x % 2 == 1 })
+ assert_raise(ArgumentError) { @obj.count(0, 1) }
+
+ if RUBY_ENGINE == "ruby"
+ en = Class.new {
+ include Enumerable
+ alias :size :count
+ def each
+ yield 1
+ end
+ }
+ assert_equal(1, en.new.count, '[ruby-core:24794]')
+ end
+ end
+
+ def test_find
+ assert_equal(2, @obj.find {|x| x % 2 == 0 })
+ assert_equal(nil, @obj.find {|x| false })
+ assert_equal(:foo, @obj.find(proc { :foo }) {|x| false })
+ end
+
+ def test_find_index
+ assert_equal(1, @obj.find_index(2))
+ assert_equal(1, @obj.find_index {|x| x % 2 == 0 })
+ assert_equal(nil, @obj.find_index {|x| false })
+ assert_raise(ArgumentError) { @obj.find_index(0, 1) }
+ assert_equal(1, @obj.find_index(2) {|x| x == 1 })
+ end
+
+ def test_find_all
+ assert_equal([1, 3, 1], @obj.find_all {|x| x % 2 == 1 })
+ end
+
+ def test_reject
+ assert_equal([2, 3, 2], @obj.reject {|x| x < 2 })
+ end
+
+ def test_to_a
+ assert_equal([1, 2, 3, 1, 2], @obj.to_a)
+ end
+
+ def test_inject
+ assert_equal(12, @obj.inject {|z, x| z * x })
+ assert_equal(48, @obj.inject {|z, x| z * 2 + x })
+ assert_equal(12, @obj.inject(:*))
+ assert_equal(24, @obj.inject(2) {|z, x| z * x })
+ assert_equal(24, @obj.inject(2, :*) {|z, x| z * x })
+ end
+
+ def test_partition
+ assert_equal([[1, 3, 1], [2, 2]], @obj.partition {|x| x % 2 == 1 })
+ end
+
+ def test_group_by
+ h = { 1 => [1, 1], 2 => [2, 2], 3 => [3] }
+ assert_equal(h, @obj.group_by {|x| x })
+ end
+
+ def test_first
+ assert_equal(1, @obj.first)
+ assert_equal([1, 2, 3], @obj.first(3))
+ end
+
+ def test_sort
+ assert_equal([1, 1, 2, 2, 3], @obj.sort)
+ end
+
+ def test_sort_by
+ assert_equal([3, 2, 2, 1, 1], @obj.sort_by {|x| -x })
+ end
+
+ def test_all
+ assert_equal(true, @obj.all? {|x| x <= 3 })
+ assert_equal(false, @obj.all? {|x| x < 3 })
+ assert_equal(true, @obj.all?)
+ assert_equal(false, [true, true, false].all?)
+ end
+
+ def test_any
+ assert_equal(true, @obj.any? {|x| x >= 3 })
+ assert_equal(false, @obj.any? {|x| x > 3 })
+ assert_equal(true, @obj.any?)
+ assert_equal(false, [false, false, false].any?)
+ end
+
+ def test_one
+ assert(@obj.one? {|x| x == 3 })
+ assert(!(@obj.one? {|x| x == 1 }))
+ assert(!(@obj.one? {|x| x == 4 }))
+ assert(%w{ant bear cat}.one? {|word| word.length == 4})
+ assert(!(%w{ant bear cat}.one? {|word| word.length > 4}))
+ assert(!(%w{ant bear cat}.one? {|word| word.length < 4}))
+ assert(!([ nil, true, 99 ].one?))
+ assert([ nil, true, false ].one?)
+ end
+
+ def test_none
+ assert(@obj.none? {|x| x == 4 })
+ assert(!(@obj.none? {|x| x == 1 }))
+ assert(!(@obj.none? {|x| x == 3 }))
+ assert(%w{ant bear cat}.none? {|word| word.length == 5})
+ assert(!(%w{ant bear cat}.none? {|word| word.length >= 4}))
+ assert([].none?)
+ assert([nil].none?)
+ assert([nil,false].none?)
+ end
+
+ def test_min
+ assert_equal(1, @obj.min)
+ assert_equal(3, @obj.min {|a,b| b <=> a })
+ ary = %w(albatross dog horse)
+ assert_equal("albatross", ary.min)
+ assert_equal("dog", ary.min {|a,b| a.length <=> b.length })
+ assert_equal(1, [3,2,1].min)
+ end
+
+ def test_max
+ assert_equal(3, @obj.max)
+ assert_equal(1, @obj.max {|a,b| b <=> a })
+ ary = %w(albatross dog horse)
+ assert_equal("horse", ary.max)
+ assert_equal("albatross", ary.max {|a,b| a.length <=> b.length })
+ assert_equal(1, [3,2,1].max{|a,b| b <=> a })
+ end
+
+ def test_minmax
+ assert_equal([1, 3], @obj.minmax)
+ assert_equal([3, 1], @obj.minmax {|a,b| b <=> a })
+ ary = %w(albatross dog horse)
+ assert_equal(["albatross", "horse"], ary.minmax)
+ assert_equal(["dog", "albatross"], ary.minmax {|a,b| a.length <=> b.length })
+ assert_equal([1, 3], [2,3,1].minmax)
+ assert_equal([3, 1], [2,3,1].minmax {|a,b| b <=> a })
+ assert_equal([1, 3], [2,2,3,3,1,1].minmax)
+ end
+
+ def test_min_by
+ assert_equal(3, @obj.min_by {|x| -x })
+ a = %w(albatross dog horse)
+ assert_equal("dog", a.min_by {|x| x.length })
+ assert_equal(3, [2,3,1].min_by {|x| -x })
+ end
+
+ def test_max_by
+ assert_equal(1, @obj.max_by {|x| -x })
+ a = %w(albatross dog horse)
+ assert_equal("albatross", a.max_by {|x| x.length })
+ assert_equal(1, [2,3,1].max_by {|x| -x })
+ end
+
+ def test_minmax_by
+ assert_equal([3, 1], @obj.minmax_by {|x| -x })
+ a = %w(albatross dog horse)
+ assert_equal(["dog", "albatross"], a.minmax_by {|x| x.length })
+ assert_equal([3, 1], [2,3,1].minmax_by {|x| -x })
+ end
+
+ def test_member
+ assert(@obj.member?(1))
+ assert(!(@obj.member?(4)))
+ assert([1,2,3].member?(1))
+ assert(!([1,2,3].member?(4)))
+ end
+
+ class Foo
+ include Enumerable
+ def each
+ yield 1
+ yield 1,2
+ end
+ end
+
+ def test_each_with_index
+ a = []
+ @obj.each_with_index {|x, i| a << [x, i] }
+ assert_equal([[1,0],[2,1],[3,2],[1,3],[2,4]], a)
+
+ hash = Hash.new
+ %w(cat dog wombat).each_with_index do |item, index|
+ hash[item] = index
+ end
+ assert_equal({"cat"=>0, "wombat"=>2, "dog"=>1}, hash)
+ assert_equal([[1, 0], [[1, 2], 1]], Foo.new.each_with_index.to_a)
+ end
+
+ def test_each_with_object
+ obj = [0, 1]
+ ret = (1..10).each_with_object(obj) {|i, memo|
+ memo[0] += i
+ memo[1] *= i
+ }
+ assert_same(obj, ret)
+ assert_equal([55, 3628800], ret)
+ assert_equal([[1, nil], [[1, 2], nil]], Foo.new.each_with_object(nil).to_a)
+ end
+
+ def test_each_entry
+ assert_equal([1, 2, 3], [1, 2, 3].each_entry.to_a)
+ assert_equal([1, [1, 2]], Foo.new.each_entry.to_a)
+ end
+
+ def test_zip
+ assert_equal([[1,1],[2,2],[3,3],[1,1],[2,2]], @obj.zip(@obj))
+ a = []
+ @obj.zip([:a, :b, :c]) {|x,y| a << [x, y] }
+ assert_equal([[1,:a],[2,:b],[3,:c],[1,nil],[2,nil]], a)
+
+ a = []
+ @obj.zip({a: "A", b: "B", c: "C"}) {|x,y| a << [x, y] }
+ assert_equal([[1,[:a,"A"]],[2,[:b,"B"]],[3,[:c,"C"]],[1,nil],[2,nil]], a)
+
+ ary = Object.new
+ def ary.to_a; [1, 2]; end
+ assert_raise(NoMethodError){ %w(a b).zip(ary) }
+ def ary.each; [3, 4].each{|e|yield e}; end
+ assert_equal([[1, 3], [2, 4], [3, nil], [1, nil], [2, nil]], @obj.zip(ary))
+ def ary.to_ary; [5, 6]; end
+ assert_equal([[1, 5], [2, 6], [3, nil], [1, nil], [2, nil]], @obj.zip(ary))
+ end
+
+ def test_take
+ assert_equal([1,2,3], @obj.take(3))
+ end
+
+ def test_take_while
+ assert_equal([1,2], @obj.take_while {|x| x <= 2})
+ end
+
+ def test_drop
+ assert_equal([3,1,2], @obj.drop(2))
+ end
+
+ def test_drop_while
+ assert_equal([3,1,2], @obj.drop_while {|x| x <= 2})
+ end
+
+ def test_cycle
+ assert_equal([1,2,3,1,2,1,2,3,1,2], @obj.cycle.take(10))
+ end
+
+ def test_callcc
+ assert_raise(RuntimeError) do
+ c = nil
+ @obj.sort_by {|x| callcc {|c2| c ||= c2 }; x }
+ c.call
+ end
+
+ assert_raise(RuntimeError) do
+ c = nil
+ o = Object.new
+ class << o; self; end.class_eval do
+ define_method(:<=>) do |x|
+ callcc {|c2| c ||= c2 }
+ 0
+ end
+ end
+ [o, o].sort_by {|x| x }
+ c.call
+ end
+
+ assert_raise(RuntimeError) do
+ c = nil
+ o = Object.new
+ class << o; self; end.class_eval do
+ define_method(:<=>) do |x|
+ callcc {|c2| c ||= c2 }
+ 0
+ end
+ end
+ [o, o, o].sort_by {|x| x }
+ c.call
+ end
+ end
+
+ def test_reverse_each
+ assert_equal([2,1,3,2,1], @obj.reverse_each.to_a)
+ end
+
+ def test_chunk
+ e = [].chunk {|elt| true }
+ assert_equal([], e.to_a)
+
+ e = @obj.chunk {|elt| elt & 2 == 0 ? false : true }
+ assert_equal([[false, [1]], [true, [2, 3]], [false, [1]], [true, [2]]], e.to_a)
+
+ e = @obj.chunk(acc: 0) {|elt, h| h[:acc] += elt; h[:acc].even? }
+ assert_equal([[false, [1,2]], [true, [3]], [false, [1,2]]], e.to_a)
+ assert_equal([[false, [1,2]], [true, [3]], [false, [1,2]]], e.to_a) # this tests h is duplicated.
+
+ hs = [{}]
+ e = [:foo].chunk(hs[0]) {|elt, h|
+ hs << h
+ true
+ }
+ assert_equal([[true, [:foo]]], e.to_a)
+ assert_equal([[true, [:foo]]], e.to_a)
+ assert_equal([{}, {}, {}], hs)
+ assert_not_same(hs[0], hs[1])
+ assert_not_same(hs[0], hs[2])
+ assert_not_same(hs[1], hs[2])
+
+ e = @obj.chunk {|elt| elt < 3 ? :_alone : true }
+ assert_equal([[:_alone, [1]],
+ [:_alone, [2]],
+ [true, [3]],
+ [:_alone, [1]],
+ [:_alone, [2]]], e.to_a)
+
+ e = @obj.chunk {|elt| elt == 3 ? :_separator : true }
+ assert_equal([[true, [1, 2]],
+ [true, [1, 2]]], e.to_a)
+
+ e = @obj.chunk {|elt| elt == 3 ? nil : true }
+ assert_equal([[true, [1, 2]],
+ [true, [1, 2]]], e.to_a)
+
+ e = @obj.chunk {|elt| :_foo }
+ assert_raise(RuntimeError) { e.to_a }
+ end
+
+ def test_slice_before
+ e = [].slice_before {|elt| true }
+ assert_equal([], e.to_a)
+
+ e = @obj.slice_before {|elt| elt.even? }
+ assert_equal([[1], [2,3,1], [2]], e.to_a)
+
+ e = @obj.slice_before {|elt| elt.odd? }
+ assert_equal([[1,2], [3], [1,2]], e.to_a)
+
+ e = @obj.slice_before(acc: 0) {|elt, h| h[:acc] += elt; h[:acc].even? }
+ assert_equal([[1,2], [3,1,2]], e.to_a)
+ assert_equal([[1,2], [3,1,2]], e.to_a) # this tests h is duplicated.
+
+ hs = [{}]
+ e = [:foo].slice_before(hs[0]) {|elt, h|
+ hs << h
+ true
+ }
+ assert_equal([[:foo]], e.to_a)
+ assert_equal([[:foo]], e.to_a)
+ assert_equal([{}, {}, {}], hs)
+ assert_not_same(hs[0], hs[1])
+ assert_not_same(hs[0], hs[2])
+ assert_not_same(hs[1], hs[2])
+
+ ss = %w[abc defg h ijk l mno pqr st u vw xy z]
+ assert_equal([%w[abc defg h], %w[ijk l], %w[mno], %w[pqr st u vw xy z]],
+ ss.slice_before(/\A...\z/).to_a)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_enumerator.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_enumerator.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_enumerator.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,377 @@
+require 'test/unit'
+
+class TestEnumerator < Test::Unit::TestCase
+ def setup
+ @obj = Object.new
+ class << @obj
+ include Enumerable
+ def foo(*a)
+ a.each {|x| yield x }
+ end
+ end
+ end
+
+ def enum_test obj
+ i = 0
+ obj.map{|e|
+ e
+ }.sort
+ end
+
+ def test_iterators
+ assert_equal [0, 1, 2], enum_test(3.times)
+ assert_equal [:x, :y, :z], enum_test([:x, :y, :z].each)
+ assert_equal [[:x, 1], [:y, 2]], enum_test({:x=>1, :y=>2})
+ end
+
+ ## Enumerator as Iterator
+
+ def test_next
+ e = 3.times
+ 3.times{|i|
+ assert_equal i, e.next
+ }
+ assert_raise(StopIteration){e.next}
+ end
+
+ def test_loop
+ e = 3.times
+ i = 0
+ loop{
+ assert_equal(i, e.next)
+ i += 1
+ }
+ end
+
+ def test_nested_itaration
+ def (o = Object.new).each
+ yield :ok1
+ yield [:ok2, :x].each.next
+ end
+ e = o.to_enum
+ assert_equal :ok1, e.next
+ assert_equal :ok2, e.next
+ assert_raise(StopIteration){e.next}
+ end
+
+
+ def test_initialize
+ assert_equal([1, 2, 3], @obj.to_enum(:foo, 1, 2, 3).to_a)
+ assert_equal([1, 2, 3], Enumerator.new(@obj, :foo, 1, 2, 3).to_a)
+ assert_equal([1, 2, 3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.take(3))
+ assert_raise(ArgumentError) { Enumerator.new }
+ end
+
+ def test_initialize_copy
+ assert_equal([1, 2, 3], @obj.to_enum(:foo, 1, 2, 3).dup.to_a)
+ e = @obj.to_enum(:foo, 1, 2, 3)
+ assert_nothing_raised { assert_equal(1, e.next) }
+ assert_raise(TypeError) { e.dup }
+
+ e = Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.dup
+ assert_nothing_raised { assert_equal(1, e.next) }
+ assert_raise(TypeError) { e.dup }
+ end
+
+ def test_gc
+ assert_nothing_raised do
+ 1.times do
+ foo = [1,2,3].to_enum
+ GC.start
+ end
+ GC.start
+ end
+ end
+
+ def test_slice
+ assert_equal([[1,2,3],[4,5,6],[7,8,9],[10]], (1..10).each_slice(3).to_a)
+ end
+
+ def test_cons
+ a = [[1,2,3], [2,3,4], [3,4,5], [4,5,6], [5,6,7], [6,7,8], [7,8,9], [8,9,10]]
+ assert_equal(a, (1..10).each_cons(3).to_a)
+ end
+
+ def test_with_index
+ assert_equal([[1,0],[2,1],[3,2]], @obj.to_enum(:foo, 1, 2, 3).with_index.to_a)
+ assert_equal([[1,5],[2,6],[3,7]], @obj.to_enum(:foo, 1, 2, 3).with_index(5).to_a)
+ end
+
+ def test_with_object
+ obj = [0, 1]
+ ret = (1..10).each.with_object(obj) {|i, memo|
+ memo[0] += i
+ memo[1] *= i
+ }
+ assert_same(obj, ret)
+ assert_equal([55, 3628800], ret)
+
+ a = [2,5,2,1,5,3,4,2,1,0]
+ obj = {}
+ ret = a.delete_if.with_object(obj) {|i, seen|
+ if seen.key?(i)
+ true
+ else
+ seen[i] = true
+ false
+ end
+ }
+ assert_same(obj, ret)
+ assert_equal([2, 5, 1, 3, 4, 0], a)
+ end
+
+ def test_next_rewind
+ e = @obj.to_enum(:foo, 1, 2, 3)
+ assert_equal(1, e.next)
+ assert_equal(2, e.next)
+ e.rewind
+ assert_equal(1, e.next)
+ assert_equal(2, e.next)
+ assert_equal(3, e.next)
+ assert_raise(StopIteration) { e.next }
+ end
+
+ def test_peek
+ a = [1]
+ e = a.each
+ assert_equal(1, e.peek)
+ assert_equal(1, e.peek)
+ assert_equal(1, e.next)
+ assert_raise(StopIteration) { e.peek }
+ assert_raise(StopIteration) { e.peek }
+ end
+
+ def test_peek_modify
+ o = Object.new
+ def o.each
+ yield 1,2
+ end
+ e = o.to_enum
+ a = e.peek
+ a << 3
+ assert_equal([1,2], e.peek)
+ end
+
+ def test_peek_values_modify
+ o = Object.new
+ def o.each
+ yield 1,2
+ end
+ e = o.to_enum
+ a = e.peek_values
+ a << 3
+ assert_equal([1,2], e.peek)
+ end
+
+ def test_next_after_stopiteration
+ a = [1]
+ e = a.each
+ assert_equal(1, e.next)
+ assert_raise(StopIteration) { e.next }
+ assert_raise(StopIteration) { e.next }
+ e.rewind
+ assert_equal(1, e.next)
+ assert_raise(StopIteration) { e.next }
+ assert_raise(StopIteration) { e.next }
+ end
+
+ def test_stop_result
+ a = [1]
+ res = a.each {}
+ e = a.each
+ assert_equal(1, e.next)
+ exc = assert_raise(StopIteration) { e.next }
+ assert_equal(res, exc.result)
+ end
+
+ def test_next_values
+ o = Object.new
+ def o.each
+ yield
+ yield 1
+ yield 1, 2
+ end
+ e = o.to_enum
+ assert_equal(nil, e.next)
+ assert_equal(1, e.next)
+ assert_equal([1,2], e.next)
+ e = o.to_enum
+ assert_equal([], e.next_values)
+ assert_equal([1], e.next_values)
+ assert_equal([1,2], e.next_values)
+ end
+
+ def test_peek_values
+ o = Object.new
+ def o.each
+ yield
+ yield 1
+ yield 1, 2
+ end
+ e = o.to_enum
+ assert_equal(nil, e.peek)
+ assert_equal(nil, e.next)
+ assert_equal(1, e.peek)
+ assert_equal(1, e.next)
+ assert_equal([1,2], e.peek)
+ assert_equal([1,2], e.next)
+ e = o.to_enum
+ assert_equal([], e.peek_values)
+ assert_equal([], e.next_values)
+ assert_equal([1], e.peek_values)
+ assert_equal([1], e.next_values)
+ assert_equal([1,2], e.peek_values)
+ assert_equal([1,2], e.next_values)
+ e = o.to_enum
+ assert_equal([], e.peek_values)
+ assert_equal(nil, e.next)
+ assert_equal([1], e.peek_values)
+ assert_equal(1, e.next)
+ assert_equal([1,2], e.peek_values)
+ assert_equal([1,2], e.next)
+ e = o.to_enum
+ assert_equal(nil, e.peek)
+ assert_equal([], e.next_values)
+ assert_equal(1, e.peek)
+ assert_equal([1], e.next_values)
+ assert_equal([1,2], e.peek)
+ assert_equal([1,2], e.next_values)
+ end
+
+ def test_feed
+ o = Object.new
+ def o.each(ary)
+ ary << yield
+ ary << yield
+ ary << yield
+ end
+ ary = []
+ e = o.to_enum(:each, ary)
+ e.next
+ e.feed 1
+ e.next
+ e.feed 2
+ e.next
+ e.feed 3
+ assert_raise(StopIteration) { e.next }
+ assert_equal([1,2,3], ary)
+ end
+
+ def test_feed_mixed
+ o = Object.new
+ def o.each(ary)
+ ary << yield
+ ary << yield
+ ary << yield
+ end
+ ary = []
+ e = o.to_enum(:each, ary)
+ e.next
+ e.feed 1
+ e.next
+ e.next
+ e.feed 3
+ assert_raise(StopIteration) { e.next }
+ assert_equal([1,nil,3], ary)
+ end
+
+ def test_feed_twice
+ o = Object.new
+ def o.each(ary)
+ ary << yield
+ ary << yield
+ ary << yield
+ end
+ ary = []
+ e = o.to_enum(:each, ary)
+ e.feed 1
+ assert_raise(TypeError) { e.feed 2 }
+ end
+
+ def test_feed_before_first_next
+ o = Object.new
+ def o.each(ary)
+ ary << yield
+ ary << yield
+ ary << yield
+ end
+ ary = []
+ e = o.to_enum(:each, ary)
+ e.feed 1
+ e.next
+ e.next
+ assert_equal([1], ary)
+ end
+
+ def test_rewind_clear_feed
+ o = Object.new
+ def o.each(ary)
+ ary << yield
+ ary << yield
+ ary << yield
+ end
+ ary = []
+ e = o.to_enum(:each, ary)
+ e.next
+ e.feed 1
+ e.next
+ e.feed 2
+ e.rewind
+ e.next
+ e.next
+ assert_equal([1,nil], ary)
+ end
+
+ def test_feed_yielder
+ x = nil
+ e = Enumerator.new {|y| x = y.yield; 10 }
+ e.next
+ e.feed 100
+ exc = assert_raise(StopIteration) { e.next }
+ assert_equal(100, x)
+ assert_equal(10, exc.result)
+ end
+
+ def test_inspect
+ e = (0..10).each_cons(2)
+ assert_equal("#<Enumerator: 0..10:each_cons(2)>", e.inspect)
+
+ e = Enumerator.new {|y| x = y.yield; 10 }
+ assert_match(/\A#<Enumerator: .*:each>/, e.inspect)
+
+ a = []
+ e = a.each_with_object(a)
+ a << e
+ assert_equal("#<Enumerator: [#<Enumerator: ...>]:each_with_object([#<Enumerator: ...>])>",
+ e.inspect)
+ end
+
+ def test_generator
+ # note: Enumerator::Generator is a class just for internal
+ g = Enumerator::Generator.new {|y| y << 1 << 2 << 3; :foo }
+ g2 = g.dup
+ a = []
+ assert_equal(:foo, g.each {|x| a << x })
+ assert_equal([1, 2, 3], a)
+ a = []
+ assert_equal(:foo, g2.each {|x| a << x })
+ assert_equal([1, 2, 3], a)
+ end
+
+ def test_yielder
+ # note: Enumerator::Yielder is a class just for internal
+ a = []
+ y = Enumerator::Yielder.new {|x| a << x }
+ assert_equal(y, y << 1 << 2 << 3)
+ assert_equal([1, 2, 3], a)
+
+ a = []
+ y = Enumerator::Yielder.new {|x| a << x }
+ assert_equal([1], y.yield(1))
+ assert_equal([1, 2], y.yield(2))
+ assert_equal([1, 2, 3], y.yield(3))
+
+ assert_raise(LocalJumpError) { Enumerator::Yielder.new }
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/ruby/test_env.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_env.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_env.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,377 @@
+require 'test/unit'
+
+class TestEnv < Test::Unit::TestCase
+ IGNORE_CASE = /bccwin|mswin|mingw/ =~ RUBY_PLATFORM
+ PATH_ENV = "PATH"
+
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ @backup = ENV.to_hash
+ ENV.delete('test')
+ ENV.delete('TEST')
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ ENV.clear
+ @backup.each {|k, v| ENV[k] = v }
+ end
+
+ def test_bracket
+ assert_nil(ENV['test'])
+ assert_nil(ENV['TEST'])
+ ENV['test'] = 'foo'
+ assert_equal('foo', ENV['test'])
+ if IGNORE_CASE
+ assert_equal('foo', ENV['TEST'])
+ else
+ assert_nil(ENV['TEST'])
+ end
+ ENV['TEST'] = 'bar'
+ assert_equal('bar', ENV['TEST'])
+ if IGNORE_CASE
+ assert_equal('bar', ENV['test'])
+ else
+ assert_equal('foo', ENV['test'])
+ end
+
+ assert_raise(TypeError) {
+ tmp = ENV[1]
+ }
+ assert_raise(TypeError) {
+ ENV[1] = 'foo'
+ }
+ assert_raise(TypeError) {
+ ENV['test'] = 0
+ }
+ end
+
+ def test_has_value
+ val = 'a'
+ val.succ! while ENV.has_value?(val) || ENV.has_value?(val.upcase)
+ ENV['test'] = val[0...-1]
+
+ assert_equal(false, ENV.has_value?(val))
+ assert_equal(false, ENV.has_value?(val.upcase))
+ ENV['test'] = val
+ assert_equal(true, ENV.has_value?(val))
+ assert_equal(false, ENV.has_value?(val.upcase))
+ ENV['test'] = val.upcase
+ assert_equal(false, ENV.has_value?(val))
+ assert_equal(true, ENV.has_value?(val.upcase))
+ end
+
+ def test_key
+ val = 'a'
+ val.succ! while ENV.has_value?(val) || ENV.has_value?(val.upcase)
+ ENV['test'] = val[0...-1]
+
+ assert_nil(ENV.key(val))
+ assert_nil(ENV.index(val))
+ assert_nil(ENV.key(val.upcase))
+ ENV['test'] = val
+ if IGNORE_CASE
+ assert_equal('TEST', ENV.key(val).upcase)
+ else
+ assert_equal('test', ENV.key(val))
+ end
+ assert_nil(ENV.key(val.upcase))
+ ENV['test'] = val.upcase
+ assert_nil(ENV.key(val))
+ if IGNORE_CASE
+ assert_equal('TEST', ENV.key(val.upcase).upcase)
+ else
+ assert_equal('test', ENV.key(val.upcase))
+ end
+ end
+
+ def test_delete
+ assert_raise(ArgumentError) { ENV.delete("foo\0bar") }
+ assert_nil(ENV.delete("TEST"))
+ assert_nothing_raised { ENV.delete(PATH_ENV) }
+ end
+
+ def test_getenv
+ assert_raise(ArgumentError) { ENV["foo\0bar"] }
+ ENV[PATH_ENV] = ""
+ assert_equal("", ENV[PATH_ENV])
+ end
+
+ def test_fetch
+ ENV["test"] = "foo"
+ assert_equal("foo", ENV.fetch("test"))
+ ENV.delete("test")
+ assert_raise(KeyError) { ENV.fetch("test") }
+ assert_equal("foo", ENV.fetch("test", "foo"))
+ assert_equal("bar", ENV.fetch("test") { "bar" })
+ assert_equal("bar", ENV.fetch("test", "foo") { "bar" })
+ assert_raise(ArgumentError) { ENV.fetch("foo\0bar") }
+ assert_nothing_raised { ENV.fetch(PATH_ENV, "foo") }
+ ENV[PATH_ENV] = ""
+ assert_equal("", ENV.fetch(PATH_ENV))
+ end
+
+ def test_aset
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ ENV["test"] = "foo"
+ end.join
+ end
+ assert_nothing_raised { ENV["test"] = nil }
+ assert_equal(nil, ENV["test"])
+ assert_raise(ArgumentError) { ENV["foo\0bar"] = "test" }
+ assert_raise(ArgumentError) { ENV["test"] = "foo\0bar" }
+ if /netbsd/ =~ RUBY_PLATFORM
+ ENV["foo=bar"] = "test"
+ assert_equal("test", ENV["foo=bar"])
+ assert_equal("test", ENV["foo"])
+ else
+ assert_raise(Errno::EINVAL) { ENV["foo=bar"] = "test" }
+ end
+ ENV[PATH_ENV] = "/tmp/".taint
+ assert_equal("/tmp/", ENV[PATH_ENV])
+ end
+
+ def test_keys
+ a = nil
+ assert_block { a = ENV.keys }
+ assert_kind_of(Array, a)
+ a.each {|k| assert_kind_of(String, k) }
+ end
+
+ def test_each_key
+ ENV.each_key {|k| assert_kind_of(String, k) }
+ end
+
+ def test_values
+ a = nil
+ assert_block { a = ENV.values }
+ assert_kind_of(Array, a)
+ a.each {|k| assert_kind_of(String, k) }
+ end
+
+ def test_each_value
+ ENV.each_value {|k| assert_kind_of(String, k) }
+ end
+
+ def test_each_pair
+ ENV.each_pair do |k, v|
+ assert_kind_of(String, k)
+ assert_kind_of(String, v)
+ end
+ end
+
+ def test_reject_bang
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ ENV.reject! {|k, v| IGNORE_CASE ? k.upcase == "TEST" : k == "test" }
+ h2 = {}
+ ENV.each_pair {|k, v| h2[k] = v }
+ assert_equal(h1, h2)
+
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ ENV.delete_if {|k, v| IGNORE_CASE ? k.upcase == "TEST" : k == "test" }
+ h2 = {}
+ ENV.each_pair {|k, v| h2[k] = v }
+ assert_equal(h1, h2)
+ end
+
+ def test_select_bang
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ ENV.select! {|k, v| IGNORE_CASE ? k.upcase != "TEST" : k != "test" }
+ h2 = {}
+ ENV.each_pair {|k, v| h2[k] = v }
+ assert_equal(h1, h2)
+
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ ENV.keep_if {|k, v| IGNORE_CASE ? k.upcase != "TEST" : k != "test" }
+ h2 = {}
+ ENV.each_pair {|k, v| h2[k] = v }
+ assert_equal(h1, h2)
+ end
+
+ def test_values_at
+ ENV["test"] = "foo"
+ assert_equal(["foo", "foo"], ENV.values_at("test", "test"))
+ end
+
+ def test_select
+ ENV["test"] = "foo"
+ h = ENV.select {|k| IGNORE_CASE ? k.upcase == "TEST" : k == "test" }
+ assert_equal(1, h.size)
+ k = h.keys.first
+ v = h.values.first
+ if IGNORE_CASE
+ assert_equal("TEST", k.upcase)
+ assert_equal("FOO", v.upcase)
+ else
+ assert_equal("test", k)
+ assert_equal("foo", v)
+ end
+ end
+
+ def test_clear
+ ENV.clear
+ assert_equal(0, ENV.size)
+ end
+
+ def test_to_s
+ assert_equal("ENV", ENV.to_s)
+ end
+
+ def test_inspect
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ s = ENV.inspect
+ if IGNORE_CASE
+ s = s.upcase
+ assert(s == '{"FOO"=>"BAR", "BAZ"=>"QUX"}' || s == '{"BAZ"=>"QUX", "FOO"=>"BAR"}')
+ else
+ assert(s == '{"foo"=>"bar", "baz"=>"qux"}' || s == '{"baz"=>"qux", "foo"=>"bar"}')
+ end
+ end
+
+ def test_to_a
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ a = ENV.to_a
+ assert_equal(2, a.size)
+ if IGNORE_CASE
+ a = a.map {|x| x.map {|y| y.upcase } }
+ assert(a == [%w(FOO BAR), %w(BAZ QUX)] || a == [%w(BAZ QUX), %w(FOO BAR)])
+ else
+ assert(a == [%w(foo bar), %w(baz qux)] || a == [%w(baz qux), %w(foo bar)])
+ end
+ end
+
+ def test_rehash
+ assert_nil(ENV.rehash)
+ end
+
+ def test_size
+ s = ENV.size
+ ENV["test"] = "foo"
+ assert_equal(s + 1, ENV.size)
+ end
+
+ def test_empty_p
+ ENV.clear
+ assert(ENV.empty?)
+ ENV["test"] = "foo"
+ assert(!ENV.empty?)
+ end
+
+ def test_has_key
+ assert(!ENV.has_key?("test"))
+ ENV["test"] = "foo"
+ assert(ENV.has_key?("test"))
+ assert_raise(ArgumentError) { ENV.has_key?("foo\0bar") }
+ end
+
+ def test_assoc
+ assert_nil(ENV.assoc("test"))
+ ENV["test"] = "foo"
+ k, v = ENV.assoc("test")
+ if IGNORE_CASE
+ assert_equal("TEST", k.upcase)
+ assert_equal("FOO", v.upcase)
+ else
+ assert_equal("test", k)
+ assert_equal("foo", v)
+ end
+ assert_raise(ArgumentError) { ENV.assoc("foo\0bar") }
+ end
+
+ def test_has_value2
+ ENV.clear
+ assert(!ENV.has_value?("foo"))
+ ENV["test"] = "foo"
+ assert(ENV.has_value?("foo"))
+ end
+
+ def test_rassoc
+ ENV.clear
+ assert_nil(ENV.rassoc("foo"))
+ ENV["foo"] = "bar"
+ ENV["test"] = "foo"
+ ENV["baz"] = "qux"
+ k, v = ENV.rassoc("foo")
+ if IGNORE_CASE
+ assert_equal("TEST", k.upcase)
+ assert_equal("FOO", v.upcase)
+ else
+ assert_equal("test", k)
+ assert_equal("foo", v)
+ end
+ end
+
+ def test_to_hash
+ h = {}
+ ENV.each {|k, v| h[k] = v }
+ assert_equal(h, ENV.to_hash)
+ end
+
+ def test_reject
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ h2 = ENV.reject {|k, v| IGNORE_CASE ? k.upcase == "TEST" : k == "test" }
+ assert_equal(h1, h2)
+ end
+
+ def check(as, bs)
+ if IGNORE_CASE
+ as = as.map {|xs| xs.map {|x| x.upcase } }
+ bs = bs.map {|xs| xs.map {|x| x.upcase } }
+ end
+ assert_equal(as.sort, bs.sort)
+ end
+
+ def test_shift
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ a = ENV.shift
+ b = ENV.shift
+ check([a, b], [%w(foo bar), %w(baz qux)])
+ assert_nil(ENV.shift)
+ end
+
+ def test_invert
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ check(ENV.invert.to_a, [%w(bar foo), %w(qux baz)])
+ end
+
+ def test_replace
+ ENV["foo"] = "xxx"
+ ENV.replace({"foo"=>"bar", "baz"=>"qux"})
+ check(ENV.to_hash.to_a, [%w(foo bar), %w(baz qux)])
+ end
+
+ def test_update
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ ENV.update({"baz"=>"quux","a"=>"b"})
+ check(ENV.to_hash.to_a, [%w(foo bar), %w(baz quux), %w(a b)])
+
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ ENV.update({"baz"=>"quux","a"=>"b"}) {|k, v1, v2| v1 ? k + "_" + v1 + "_" + v2 : v2 }
+ check(ENV.to_hash.to_a, [%w(foo bar), %w(baz baz_qux_quux), %w(a b)])
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_eval.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_eval.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_eval.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,418 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestEval < Test::Unit::TestCase
+
+ @ivar = 12
+ @@cvar = 13
+ $gvar__eval = 14
+ Const = 15
+
+ def ruby(*args)
+ args = ['-e', '$>.write($<.read)'] if args.empty?
+ ruby = EnvUtil.rubybin
+ f = IO.popen([ruby] + args, 'r+')
+ yield(f)
+ ensure
+ f.close unless !f || f.closed?
+ end
+
+ def test_eval_basic
+ assert_equal nil, eval("nil")
+ assert_equal true, eval("true")
+ assert_equal false, eval("false")
+ assert_equal self, eval("self")
+ assert_equal 1, eval("1")
+ assert_equal :sym, eval(":sym")
+
+ assert_equal 11, eval("11")
+ @ivar = 12
+ assert_equal 12, eval("@ivar")
+ assert_equal 13, eval("@@cvar")
+ assert_equal 14, eval("$gvar__eval")
+ assert_equal 15, eval("Const")
+
+ assert_equal 16, eval("7 + 9")
+ assert_equal 17, eval("17.to_i")
+ assert_equal "18", eval(%q("18"))
+ assert_equal "19", eval(%q("1#{9}"))
+
+ 1.times {
+ assert_equal 12, eval("@ivar")
+ assert_equal 13, eval("@@cvar")
+ assert_equal 14, eval("$gvar__eval")
+ assert_equal 15, eval("Const")
+ }
+ end
+
+ def test_eval_binding_basic
+ assert_equal nil, eval("nil", binding())
+ assert_equal true, eval("true", binding())
+ assert_equal false, eval("false", binding())
+ assert_equal self, eval("self", binding())
+ assert_equal 1, eval("1", binding())
+ assert_equal :sym, eval(":sym", binding())
+
+ assert_equal 11, eval("11", binding())
+ @ivar = 12
+ assert_equal 12, eval("@ivar", binding())
+ assert_equal 13, eval("@@cvar", binding())
+ assert_equal 14, eval("$gvar__eval", binding())
+ assert_equal 15, eval("Const", binding())
+
+ assert_equal 16, eval("7 + 9", binding())
+ assert_equal 17, eval("17.to_i", binding())
+ assert_equal "18", eval(%q("18"), binding())
+ assert_equal "19", eval(%q("1#{9}"), binding())
+
+ 1.times {
+ assert_equal 12, eval("@ivar")
+ assert_equal 13, eval("@@cvar")
+ assert_equal 14, eval("$gvar__eval")
+ assert_equal 15, eval("Const")
+ }
+ end
+
+ def test_module_eval_string_basic
+ c = self.class
+ assert_equal nil, c.module_eval("nil")
+ assert_equal true, c.module_eval("true")
+ assert_equal false, c.module_eval("false")
+ assert_equal c, c.module_eval("self")
+ assert_equal :sym, c.module_eval(":sym")
+ assert_equal 11, c.module_eval("11")
+ @ivar = 12
+ assert_equal 12, c.module_eval("@ivar")
+ assert_equal 13, c.module_eval("@@cvar")
+ assert_equal 14, c.module_eval("$gvar__eval")
+ assert_equal 15, c.module_eval("Const")
+ assert_equal 16, c.module_eval("7 + 9")
+ assert_equal 17, c.module_eval("17.to_i")
+ assert_equal "18", c.module_eval(%q("18"))
+ assert_equal "19", c.module_eval(%q("1#{9}"))
+
+ @ivar = 12
+ 1.times {
+ assert_equal 12, c.module_eval("@ivar")
+ assert_equal 13, c.module_eval("@@cvar")
+ assert_equal 14, c.module_eval("$gvar__eval")
+ assert_equal 15, c.module_eval("Const")
+ }
+ end
+
+ def test_module_eval_block_basic
+ c = self.class
+ assert_equal nil, c.module_eval { nil }
+ assert_equal true, c.module_eval { true }
+ assert_equal false, c.module_eval { false }
+ assert_equal c, c.module_eval { self }
+ assert_equal :sym, c.module_eval { :sym }
+ assert_equal 11, c.module_eval { 11 }
+ @ivar = 12
+ assert_equal 12, c.module_eval { @ivar }
+ assert_equal 13, c.module_eval { @@cvar }
+ assert_equal 14, c.module_eval { $gvar__eval }
+ assert_equal 15, c.module_eval { Const }
+ assert_equal 16, c.module_eval { 7 + 9 }
+ assert_equal 17, c.module_eval { "17".to_i }
+ assert_equal "18", c.module_eval { "18" }
+ assert_equal "19", c.module_eval { "1#{9}" }
+
+ @ivar = 12
+ 1.times {
+ assert_equal 12, c.module_eval { @ivar }
+ assert_equal 13, c.module_eval { @@cvar }
+ assert_equal 14, c.module_eval { $gvar__eval }
+ assert_equal 15, c.module_eval { Const }
+ }
+ end
+
+ def forall_TYPE(mid)
+ objects = [Object.new, [], nil, true, false, 77, :sym] # TODO: check
+ objects.each do |obj|
+ obj.instance_variable_set :@ivar, 12
+ send mid, obj
+ end
+ end
+
+ def test_instance_eval_string_basic
+ forall_TYPE :instance_eval_string_basic_i
+ end
+
+ def instance_eval_string_basic_i(o)
+ assert_equal nil, o.instance_eval("nil")
+ assert_equal true, o.instance_eval("true")
+ assert_equal false, o.instance_eval("false")
+ assert_equal o, o.instance_eval("self")
+ assert_equal 1, o.instance_eval("1")
+ assert_equal :sym, o.instance_eval(":sym")
+
+ assert_equal 11, o.instance_eval("11")
+ assert_equal 12, o.instance_eval("@ivar")
+ assert_equal 13, o.instance_eval("@@cvar")
+ assert_equal 14, o.instance_eval("$gvar__eval")
+ assert_equal 15, o.instance_eval("Const")
+ assert_equal 16, o.instance_eval("7 + 9")
+ assert_equal 17, o.instance_eval("17.to_i")
+ assert_equal "18", o.instance_eval(%q("18"))
+ assert_equal "19", o.instance_eval(%q("1#{9}"))
+
+ 1.times {
+ assert_equal 12, o.instance_eval("@ivar")
+ assert_equal 13, o.instance_eval("@@cvar")
+ assert_equal 14, o.instance_eval("$gvar__eval")
+ assert_equal 15, o.instance_eval("Const")
+ }
+ end
+
+ def test_instance_eval_block_basic
+ forall_TYPE :instance_eval_block_basic_i
+ end
+
+ def instance_eval_block_basic_i(o)
+ assert_equal nil, o.instance_eval { nil }
+ assert_equal true, o.instance_eval { true }
+ assert_equal false, o.instance_eval { false }
+ assert_equal o, o.instance_eval { self }
+ assert_equal 1, o.instance_eval { 1 }
+ assert_equal :sym, o.instance_eval { :sym }
+
+ assert_equal 11, o.instance_eval { 11 }
+ assert_equal 12, o.instance_eval { @ivar }
+ assert_equal 13, o.instance_eval { @@cvar }
+ assert_equal 14, o.instance_eval { $gvar__eval }
+ assert_equal 15, o.instance_eval { Const }
+ assert_equal 16, o.instance_eval { 7 + 9 }
+ assert_equal 17, o.instance_eval { 17.to_i }
+ assert_equal "18", o.instance_eval { "18" }
+ assert_equal "19", o.instance_eval { "1#{9}" }
+
+ 1.times {
+ assert_equal 12, o.instance_eval { @ivar }
+ assert_equal 13, o.instance_eval { @@cvar }
+ assert_equal 14, o.instance_eval { $gvar__eval }
+ assert_equal 15, o.instance_eval { Const }
+ }
+ end
+
+ def test_instance_eval_cvar
+ [Object.new, [], 7, :sym, true, false, nil].each do |obj|
+ assert_equal(13, obj.instance_eval("@@cvar"))
+ assert_equal(13, obj.instance_eval{@@cvar})
+ # assert_raise(NameError){obj.instance_eval("@@cvar")}
+ # assert_raise(NameError){obj.instance_eval{@@cvar}}
+ end
+ end
+
+ #
+ # From ruby/test/ruby/test_eval.rb
+ #
+
+ def test_ev
+ local1 = "local1"
+ lambda {
+ local2 = "local2"
+ return binding
+ }.call
+ end
+
+ def test_eval_orig
+ assert_nil(eval(""))
+ $bad=false
+ eval 'while false; $bad = true; print "foo\n" end'
+ assert(!$bad)
+
+ assert(eval('TRUE'))
+ assert(eval('true'))
+ assert(!eval('NIL'))
+ assert(!eval('nil'))
+ assert(!eval('FALSE'))
+ assert(!eval('false'))
+
+ $foo = 'assert(true)'
+ begin
+ eval $foo
+ rescue
+ assert(false)
+ end
+
+ assert_equal('assert(true)', eval("$foo"))
+ assert_equal(true, eval("true"))
+ i = 5
+ assert(eval("i == 5"))
+ assert_equal(5, eval("i"))
+ assert(eval("defined? i"))
+
+ $x = test_ev
+ assert_equal("local1", eval("local1", $x)) # normal local var
+ assert_equal("local2", eval("local2", $x)) # nested local var
+ $bad = true
+ begin
+ p eval("local1")
+ rescue NameError # must raise error
+ $bad = false
+ end
+ assert(!$bad)
+
+ # !! use class_eval to avoid nested definition
+ self.class.class_eval %q(
+ module EvTest
+ EVTEST1 = 25
+ evtest2 = 125
+ $x = binding
+ end
+ )
+ assert_equal(25, eval("EVTEST1", $x)) # constant in module
+ assert_equal(125, eval("evtest2", $x)) # local var in module
+ $bad = true
+ begin
+ eval("EVTEST1")
+ rescue NameError # must raise error
+ $bad = false
+ end
+ assert(!$bad)
+
+ if false
+ # Ruby 2.0 doesn't see Proc as Binding
+ x = proc{}
+ eval "i4 = 1", x
+ assert_equal(1, eval("i4", x))
+ x = proc{proc{}}.call
+ eval "i4 = 22", x
+ assert_equal(22, eval("i4", x))
+ $x = []
+ x = proc{proc{}}.call
+ eval "(0..9).each{|i5| $x[i5] = proc{i5*2}}", x
+ assert_equal(8, $x[4].call)
+ end
+
+ x = binding
+ eval "i = 1", x
+ assert_equal(1, eval("i", x))
+ x = proc{binding}.call
+ eval "i = 22", x
+ assert_equal(22, eval("i", x))
+ $x = []
+ x = proc{binding}.call
+ eval "(0..9).each{|i5| $x[i5] = proc{i5*2}}", x
+ assert_equal(8, $x[4].call)
+ x = proc{binding}.call
+ eval "for i6 in 1..1; j6=i6; end", x
+ assert(eval("defined? i6", x))
+ assert(eval("defined? j6", x))
+
+ proc {
+ p = binding
+ eval "foo11 = 1", p
+ foo22 = 5
+ proc{foo11=22}.call
+ proc{foo22=55}.call
+ # assert_equal(eval("foo11"), eval("foo11", p))
+ # assert_equal(1, eval("foo11"))
+ assert_equal(eval("foo22"), eval("foo22", p))
+ assert_equal(55, eval("foo22"))
+ }.call
+
+ if false
+ # Ruby 2.0 doesn't see Proc as Binding
+ p1 = proc{i7 = 0; proc{i7}}.call
+ assert_equal(0, p1.call)
+ eval "i7=5", p1
+ assert_equal(5, p1.call)
+ assert(!defined?(i7))
+ end
+
+ if false
+ # Ruby 2.0 doesn't see Proc as Binding
+ p1 = proc{i7 = 0; proc{i7}}.call
+ i7 = nil
+ assert_equal(0, p1.call)
+ eval "i7=1", p1
+ assert_equal(1, p1.call)
+ eval "i7=5", p1
+ assert_equal(5, p1.call)
+ assert_nil(i7)
+ end
+ end
+
+ def test_nil_instance_eval_cvar
+ def nil.test_binding
+ binding
+ end
+ bb = eval("nil.instance_eval \"binding\"", nil.test_binding)
+ assert_raise(NameError, "[ruby-dev:24103]") { eval("@@a", bb) }
+ class << nil
+ remove_method :test_binding
+ end
+ end
+
+ def test_fixnum_instance_eval_cvar
+ assert_raise(NameError, "[ruby-dev:24213]") { 1.instance_eval "@@a" }
+ end
+
+ def test_cvar_scope_with_instance_eval
+ # TODO: check
+ Fixnum.class_eval "@@test_cvar_scope_with_instance_eval = 1" # depends on [ruby-dev:24229]
+ @@test_cvar_scope_with_instance_eval = 4
+ assert_equal(4, 1.instance_eval("@@test_cvar_scope_with_instance_eval"), "[ruby-dev:24223]")
+ Fixnum.__send__(:remove_class_variable, :@@test_cvar_scope_with_instance_eval)
+ end
+
+ def test_eval_and_define_method
+ assert_nothing_raised("[ruby-dev:24228]") {
+ def temporally_method_for_test_eval_and_define_method(&block)
+ lambda {
+ class << Object.new; self end.send(:define_method, :zzz, &block)
+ }
+ end
+ v = eval("temporally_method_for_test_eval_and_define_method {}")
+ {}[0] = {}
+ v.call
+ }
+ end
+
+ def test_define_method_block
+ cc = Class.new do
+ define_method(:foo) {|&block|
+ block.call if block
+ }
+ end
+
+ c = cc.new
+ x = "ng"
+ c.foo() {x = "ok"}
+ assert_equal("ok", x)
+ end
+
+ def test_eval_using_integer_as_binding
+ assert_raise(TypeError) { eval("", 1) }
+ end
+
+ def test_eval_raise
+ assert_raise(RuntimeError) { eval("raise ''") }
+ end
+
+ def test_eval_using_untainted_binding_under_safe4
+ assert_raise(SecurityError) do
+ Thread.new do
+ b = binding
+ $SAFE = 4
+ eval("", b)
+ end.join
+ end
+ end
+
+ def test_eval_with_toplevel_binding # [ruby-dev:37142]
+ ruby("-e", "x = 0; eval('p x', TOPLEVEL_BINDING)") do |f|
+ f.close_write
+ assert_equal("0", f.read.chomp)
+ end
+ end
+
+ def test_eval_ascii_incompatible
+ assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-16be"))}
+ assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-16le"))}
+ assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-32be"))}
+ assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-32le"))}
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_exception.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_exception.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_exception.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,315 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestException < Test::Unit::TestCase
+ def test_exception
+ begin
+ raise "this must be handled"
+ assert(false)
+ rescue
+ assert(true)
+ end
+
+ $bad = true
+ begin
+ raise "this must be handled no.2"
+ rescue
+ if $bad
+ $bad = false
+ retry
+ assert(false)
+ end
+ end
+ assert(true)
+
+ # exception in rescue clause
+ $string = "this must be handled no.3"
+ e = assert_raise(RuntimeError) do
+ begin
+ raise "exception in rescue clause"
+ rescue
+ raise $string
+ end
+ assert(false)
+ end
+ assert_equal($string, e.message)
+
+ # exception in ensure clause
+ $string = "exception in ensure clause"
+ e = assert_raise(RuntimeError) do
+ begin
+ raise "this must be handled no.4"
+ ensure
+ assert_instance_of(RuntimeError, $!)
+ assert_equal("this must be handled no.4", $!.message)
+ raise "exception in ensure clause"
+ end
+ assert(false)
+ end
+ assert_equal($string, e.message)
+
+ $bad = true
+ begin
+ begin
+ raise "this must be handled no.5"
+ ensure
+ $bad = false
+ end
+ rescue
+ end
+ assert(!$bad)
+
+ $bad = true
+ begin
+ begin
+ raise "this must be handled no.6"
+ ensure
+ $bad = false
+ end
+ rescue
+ end
+ assert(!$bad)
+
+ $bad = true
+ while true
+ begin
+ break
+ ensure
+ $bad = false
+ end
+ end
+ assert(!$bad)
+
+ assert(catch(:foo) {
+ loop do
+ loop do
+ throw :foo, true
+ break
+ end
+ break
+ assert(false) # should no reach here
+ end
+ false
+ })
+
+ end
+
+ def test_else
+ begin
+ assert(true)
+ rescue
+ assert(false)
+ else
+ assert(true)
+ end
+
+ begin
+ assert(true)
+ raise
+ assert(false)
+ rescue
+ assert(true)
+ else
+ assert(false)
+ end
+
+ begin
+ assert(true)
+ begin
+ assert(true)
+ rescue
+ assert(false)
+ else
+ assert(true)
+ end
+ assert(true)
+ rescue
+ assert(false)
+ else
+ assert(true)
+ end
+
+ begin
+ assert(true)
+ begin
+ assert(true)
+ raise
+ assert(false)
+ rescue
+ assert(true)
+ else
+ assert(false)
+ end
+ assert(true)
+ rescue
+ assert(false)
+ else
+ assert(true)
+ end
+
+ begin
+ assert(true)
+ begin
+ assert(true)
+ rescue
+ assert(false)
+ else
+ assert(true)
+ end
+ assert(true)
+ raise
+ assert(false)
+ rescue
+ assert(true)
+ else
+ assert(false)
+ end
+
+ begin
+ assert(true)
+ begin
+ assert(true)
+ raise
+ assert(false)
+ rescue
+ assert(true)
+ else
+ assert(false)
+ end
+ assert(true)
+ raise
+ assert(false)
+ rescue
+ assert(true)
+ else
+ assert(false)
+ end
+ end
+
+ def test_raise_with_wrong_number_of_arguments
+ assert_raise(TypeError) { raise nil }
+ assert_raise(TypeError) { raise 1, 1 }
+ assert_raise(ArgumentError) { raise 1, 1, 1, 1 }
+ end
+
+ def test_errat
+ assert_in_out_err([], "p $@", %w(nil), [])
+
+ assert_in_out_err([], "$@ = 1", [], /\$! not set \(ArgumentError\)$/)
+
+ assert_in_out_err([], <<-INPUT, [], /backtrace must be Array of String \(TypeError\)$/)
+ begin
+ raise
+ rescue
+ $@ = 1
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, [], /^foo: unhandled exception$/)
+ begin
+ raise
+ rescue
+ $@ = 'foo'
+ raise
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, [], /^foo: unhandled exception\s+from bar\s+from baz$/)
+ begin
+ raise
+ rescue
+ $@ = %w(foo bar baz)
+ raise
+ end
+ INPUT
+ end
+
+ def test_safe4
+ cmd = proc{raise SystemExit}
+ safe0_p = proc{|*args| args}
+
+ test_proc = proc {
+ $SAFE = 4
+ begin
+ cmd.call
+ rescue SystemExit => e
+ safe0_p["SystemExit: #{e.inspect}"]
+ raise e
+ rescue Exception => e
+ safe0_p["Exception (NOT SystemExit): #{e.inspect}"]
+ raise e
+ end
+ }
+ assert_raise(SystemExit, '[ruby-dev:38760]') {test_proc.call}
+ end
+
+ def test_thread_signal_location
+ stdout, stderr, status = EnvUtil.invoke_ruby("-d", <<-RUBY, false, true)
+Thread.start do
+ begin
+ Process.kill(:INT, $$)
+ ensure
+ raise "in ensure"
+ end
+end.join
+ RUBY
+ assert_not_match(/:0/, stderr, "[ruby-dev:39116]")
+ end
+
+ def test_errinfo
+ begin
+ raise "foo"
+ assert(false)
+ rescue => e
+ assert_equal(e, $!)
+ 1.times { assert_equal(e, $!) }
+ end
+
+ assert_equal(nil, $!)
+ end
+
+ def test_inspect
+ assert_equal("#<Exception: Exception>", Exception.new.inspect)
+
+ e = Class.new(Exception)
+ e.class_eval do
+ def to_s; ""; end
+ end
+ assert_equal(e.inspect, e.new.inspect)
+ end
+
+ def test_set_backtrace
+ e = Exception.new
+
+ e.set_backtrace("foo")
+ assert_equal(["foo"], e.backtrace)
+
+ e.set_backtrace(%w(foo bar baz))
+ assert_equal(%w(foo bar baz), e.backtrace)
+
+ assert_raise(TypeError) { e.set_backtrace(1) }
+ assert_raise(TypeError) { e.set_backtrace([1]) }
+ end
+
+ def test_exit_success_p
+ begin
+ exit
+ rescue SystemExit => e
+ end
+ assert(e.success?)
+
+ begin
+ abort
+ rescue SystemExit => e
+ end
+ assert(!e.success?)
+ end
+
+ def test_nomethoderror
+ bug3237 = '[ruby-core:29948]'
+ str = "\u2600"
+ id = :"\u2604"
+ e = assert_raise(NoMethodError) {str.__send__(id)}
+ assert_equal("undefined method `#{id}' for #{str.inspect}:String", e.message, bug3237)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_fiber.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_fiber.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_fiber.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,193 @@
+require 'test/unit'
+require 'fiber'
+require 'continuation'
+require_relative './envutil'
+
+class TestFiber < Test::Unit::TestCase
+ def test_normal
+ f = Fiber.current
+ assert_equal(:ok2,
+ Fiber.new{|e|
+ assert_equal(:ok1, e)
+ Fiber.yield :ok2
+ }.resume(:ok1)
+ )
+ assert_equal([:a, :b], Fiber.new{|a, b| [a, b]}.resume(:a, :b))
+ end
+
+ def test_argument
+ assert_equal(4, Fiber.new {|i=4| i}.resume)
+ end
+
+ def test_term
+ assert_equal(:ok, Fiber.new{:ok}.resume)
+ assert_equal([:a, :b, :c, :d, :e],
+ Fiber.new{
+ Fiber.new{
+ Fiber.new{
+ Fiber.new{
+ [:a]
+ }.resume + [:b]
+ }.resume + [:c]
+ }.resume + [:d]
+ }.resume + [:e])
+ end
+
+ def test_many_fibers
+ max = 10000
+ assert_equal(max, max.times{
+ Fiber.new{}
+ })
+ assert_equal(max,
+ max.times{|i|
+ Fiber.new{
+ }.resume
+ }
+ )
+ end
+
+ def test_many_fibers_with_threads
+ max = 1000
+ @cnt = 0
+ (1..100).map{|ti|
+ Thread.new{
+ max.times{|i|
+ Fiber.new{
+ @cnt += 1
+ }.resume
+ }
+ }
+ }.each{|t|
+ t.join
+ }
+ assert_equal(:ok, :ok)
+ end
+
+ def test_error
+ assert_raise(ArgumentError){
+ Fiber.new # Fiber without block
+ }
+ assert_raise(FiberError){
+ f = Fiber.new{}
+ Thread.new{f.resume}.join # Fiber yielding across thread
+ }
+ assert_raise(FiberError){
+ f = Fiber.new{}
+ f.resume
+ f.resume
+ }
+ assert_raise(RuntimeError){
+ f = Fiber.new{
+ @c = callcc{|c| @c = c}
+ }.resume
+ @c.call # cross fiber callcc
+ }
+ assert_raise(RuntimeError){
+ Fiber.new{
+ raise
+ }.resume
+ }
+ assert_raise(FiberError){
+ Fiber.yield
+ }
+ assert_raise(FiberError){
+ fib = Fiber.new{
+ fib.resume
+ }
+ fib.resume
+ }
+ assert_raise(FiberError){
+ fib = Fiber.new{
+ Fiber.new{
+ fib.resume
+ }.resume
+ }
+ fib.resume
+ }
+ end
+
+ def test_return
+ assert_raise(LocalJumpError){
+ Fiber.new do
+ return
+ end.resume
+ }
+ end
+
+ def test_throw
+ assert_raise(ArgumentError){
+ Fiber.new do
+ throw :a
+ end.resume
+ }
+ end
+
+ def test_transfer
+ ary = []
+ f2 = nil
+ f1 = Fiber.new{
+ ary << f2.transfer(:foo)
+ :ok
+ }
+ f2 = Fiber.new{
+ ary << f1.transfer(:baz)
+ :ng
+ }
+ assert_equal(:ok, f1.transfer)
+ assert_equal([:baz], ary)
+ end
+
+ def test_tls
+ #
+ def tvar(var, val)
+ old = Thread.current[var]
+ begin
+ Thread.current[var] = val
+ yield
+ ensure
+ Thread.current[var] = old
+ end
+ end
+
+ fb = Fiber.new {
+ assert_equal(nil, Thread.current[:v]); tvar(:v, :x) {
+ assert_equal(:x, Thread.current[:v]); Fiber.yield
+ assert_equal(:x, Thread.current[:v]); }
+ assert_equal(nil, Thread.current[:v]); Fiber.yield
+ raise # unreachable
+ }
+
+ assert_equal(nil, Thread.current[:v]); tvar(:v,1) {
+ assert_equal(1, Thread.current[:v]); tvar(:v,3) {
+ assert_equal(3, Thread.current[:v]); fb.resume
+ assert_equal(3, Thread.current[:v]); }
+ assert_equal(1, Thread.current[:v]); }
+ assert_equal(nil, Thread.current[:v]); fb.resume
+ assert_equal(nil, Thread.current[:v]);
+ end
+
+ def test_alive
+ fib = Fiber.new{Fiber.yield}
+ assert_equal(true, fib.alive?)
+ fib.resume
+ assert_equal(true, fib.alive?)
+ fib.resume
+ assert_equal(false, fib.alive?)
+ end
+
+ def test_resume_self
+ f = Fiber.new {f.resume}
+ assert_raise(FiberError, '[ruby-core:23651]') {f.transfer}
+ end
+
+ def test_fiber_transfer_segv
+ assert_normal_exit %q{
+ require 'fiber'
+ f2 = nil
+ f1 = Fiber.new{ f2.resume }
+ f2 = Fiber.new{ f1.resume }
+ f1.transfer
+ }, '[ruby-dev:40833]'
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/ruby/test_file.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_file.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_file.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,184 @@
+require 'test/unit'
+require 'tempfile'
+require_relative 'ut_eof'
+
+class TestFile < Test::Unit::TestCase
+
+ # I don't know Ruby's spec about "unlink-before-close" exactly.
+ # This test asserts current behaviour.
+ def test_unlink_before_close
+ Dir.mktmpdir('rubytest-file') {|tmpdir|
+ filename = tmpdir + '/' + File.basename(__FILE__) + ".#{$$}"
+ w = File.open(filename, "w")
+ w << "foo"
+ w.close
+ r = File.open(filename, "r")
+ begin
+ if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM
+ assert_raise(Errno::EACCES) {File.unlink(filename)}
+ else
+ assert_nothing_raised {File.unlink(filename)}
+ end
+ ensure
+ r.close
+ File.unlink(filename) if File.exist?(filename)
+ end
+ }
+ end
+
+ include TestEOF
+ def open_file(content)
+ f = Tempfile.new("test-eof")
+ f << content
+ f.rewind
+ yield f
+ end
+ alias open_file_rw open_file
+
+ include TestEOF::Seek
+
+ def test_truncate_wbuf
+ f = Tempfile.new("test-truncate")
+ f.print "abc"
+ f.truncate(0)
+ f.print "def"
+ f.flush
+ assert_equal("\0\0\0def", File.read(f.path), "[ruby-dev:24191]")
+ f.close
+ end
+
+ def test_truncate_rbuf
+ f = Tempfile.new("test-truncate")
+ f.puts "abc"
+ f.puts "def"
+ f.close
+ f.open
+ assert_equal("abc\n", f.gets)
+ f.truncate(3)
+ assert_equal(nil, f.gets, "[ruby-dev:24197]")
+ end
+
+ def test_truncate_beyond_eof
+ f = Tempfile.new("test-truncate")
+ f.print "abc"
+ f.truncate 10
+ assert_equal("\0" * 7, f.read(100), "[ruby-dev:24532]")
+ end
+
+ def test_read_all_extended_file
+ [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+ f = Tempfile.new("test-extended-file", mode)
+ assert_nil(f.getc)
+ f.print "a"
+ f.rewind
+ assert_equal("a", f.read, "mode = <#{mode}>")
+ end
+ end
+
+ def test_gets_extended_file
+ [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+ f = Tempfile.new("test-extended-file", mode)
+ assert_nil(f.getc)
+ f.print "a"
+ f.rewind
+ assert_equal("a", f.gets("a"), "mode = <#{mode}>")
+ end
+ end
+
+ def test_gets_para_extended_file
+ [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+ f = Tempfile.new("test-extended-file", mode)
+ assert_nil(f.getc)
+ f.print "\na"
+ f.rewind
+ assert_equal("a", f.gets(""), "mode = <#{mode}>")
+ end
+ end
+
+ def test_each_char_extended_file
+ [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+ f = Tempfile.new("test-extended-file", mode)
+ assert_nil(f.getc)
+ f.print "a"
+ f.rewind
+ result = []
+ f.each_char {|b| result << b }
+ assert_equal([?a], result, "mode = <#{mode}>")
+ end
+ end
+
+ def test_each_byte_extended_file
+ [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+ f = Tempfile.new("test-extended-file", mode)
+ assert_nil(f.getc)
+ f.print "a"
+ f.rewind
+ result = []
+ f.each_byte {|b| result << b.chr }
+ assert_equal([?a], result, "mode = <#{mode}>")
+ end
+ end
+
+ def test_getc_extended_file
+ [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+ f = Tempfile.new("test-extended-file", mode)
+ assert_nil(f.getc)
+ f.print "a"
+ f.rewind
+ assert_equal(?a, f.getc, "mode = <#{mode}>")
+ end
+ end
+
+ def test_getbyte_extended_file
+ [nil, {:textmode=>true}, {:binmode=>true}].each do |mode|
+ f = Tempfile.new("test-extended-file", mode)
+ assert_nil(f.getc)
+ f.print "a"
+ f.rewind
+ assert_equal(?a, f.getbyte.chr, "mode = <#{mode}>")
+ end
+ end
+
+ def test_s_chown
+ assert_nothing_raised { File.chown(-1, -1) }
+ assert_nothing_raised { File.chown nil, nil }
+ end
+
+ def test_chown
+ assert_nothing_raised {
+ File.open(__FILE__) {|f| f.chown(-1, -1) }
+ }
+ assert_nothing_raised("[ruby-dev:27140]") {
+ File.open(__FILE__) {|f| f.chown nil, nil }
+ }
+ end
+
+ def test_uninitialized
+ assert_raise(TypeError) { File::Stat.allocate.readable? }
+ assert_nothing_raised { File::Stat.allocate.inspect }
+ end
+
+ def test_realpath
+ Dir.mktmpdir('rubytest-realpath') {|tmpdir|
+ realdir = File.realpath(tmpdir)
+ tst = realdir.sub(/#{Regexp.escape(File::SEPARATOR)}/, '\0\0\0')
+ assert_equal(realdir, File.realpath(tst))
+ assert_equal(realdir, File.realpath(".", tst))
+ if File::ALT_SEPARATOR
+ bug2961 = '[ruby-core:28653]'
+ assert_equal(realdir, File.realpath(realdir.tr(File::SEPARATOR, File::ALT_SEPARATOR)), bug2961)
+ end
+ }
+ end
+
+ def test_realdirpath
+ Dir.mktmpdir('rubytest-realdirpath') {|tmpdir|
+ realdir = File.realpath(tmpdir)
+ tst = realdir.sub(/#{Regexp.escape(File::SEPARATOR)}/, '\0\0\0')
+ assert_equal(realdir, File.realdirpath(tst))
+ assert_equal(realdir, File.realdirpath(".", tst))
+ assert_equal(File.join(realdir, "foo"), File.realdirpath("foo", tst))
+ }
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_file_exhaustive.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_file_exhaustive.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_file_exhaustive.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,787 @@
+require "test/unit"
+require "fileutils"
+require "tmpdir"
+
+class TestFileExhaustive < Test::Unit::TestCase
+ def assert_incompatible_encoding
+ d = "\u{3042}\u{3044}".encode("utf-16le")
+ assert_raise(Encoding::CompatibilityError) {yield d}
+ m = Class.new {define_method(:to_path) {d}}
+ assert_raise(Encoding::CompatibilityError) {yield m.new}
+ end
+
+ def setup
+ @dir = Dir.mktmpdir("rubytest-file")
+ File.chown(-1, Process.gid, @dir)
+ @file = make_tmp_filename("file")
+ @zerofile = make_tmp_filename("zerofile")
+ @nofile = make_tmp_filename("nofile")
+ @symlinkfile = make_tmp_filename("symlinkfile")
+ @hardlinkfile = make_tmp_filename("hardlinkfile")
+ make_file("foo", @file)
+ make_file("", @zerofile)
+ @time = Time.now
+ begin
+ File.symlink(@file, @symlinkfile)
+ rescue NotImplementedError
+ @symlinkfile = nil
+ end
+ begin
+ File.link(@file, @hardlinkfile)
+ rescue NotImplementedError, Errno::EINVAL # EINVAL for Windows Vista
+ @hardlinkfile = nil
+ end
+ end
+
+ def teardown
+ GC.start
+ FileUtils.remove_entry_secure @dir
+ end
+
+ def make_file(content, file = @file)
+ open(file, "w") {|fh| fh << content }
+ end
+
+ def make_tmp_filename(prefix)
+ @hardlinkfile = @dir + "/" + prefix + File.basename(__FILE__) + ".#{$$}.test"
+ end
+
+ def test_path
+ file = @file
+
+ assert_equal(file, File.open(file) {|f| f.path})
+ assert_equal(file, File.path(file))
+ o = Object.new
+ class << o; self; end.class_eval do
+ define_method(:to_path) { file }
+ end
+ assert_equal(file, File.path(o))
+ end
+
+ def assert_integer(n)
+ assert(n.is_a?(Integer), n.inspect + " is not Fixnum.")
+ end
+
+ def assert_integer_or_nil(n)
+ assert(n.is_a?(Integer) || n.equal?(nil), n.inspect + " is neither Fixnum nor nil.")
+ end
+
+ def test_stat
+ sleep(@time - Time.now + 1.1)
+ make_file("foo", @file + "2")
+ fs1, fs2 = File.stat(@file), File.stat(@file + "2")
+ assert_nothing_raised do
+ assert_equal(0, fs1 <=> fs1)
+ assert_equal(-1, fs1 <=> fs2)
+ assert_equal(1, fs2 <=> fs1)
+ assert_nil(fs1 <=> nil)
+ assert_integer(fs1.dev)
+ assert_integer_or_nil(fs1.rdev)
+ assert_integer_or_nil(fs1.dev_major)
+ assert_integer_or_nil(fs1.dev_minor)
+ assert_integer_or_nil(fs1.rdev_major)
+ assert_integer_or_nil(fs1.rdev_minor)
+ assert_integer(fs1.ino)
+ assert_integer(fs1.mode)
+ unless /emx|mswin|mingw/ =~ RUBY_PLATFORM
+ # on Windows, nlink is always 1. but this behavior will be changed
+ # in the future.
+ assert_equal(@hardlinkfile ? 2 : 1, fs1.nlink)
+ end
+ assert_integer(fs1.uid)
+ assert_integer(fs1.gid)
+ assert_equal(3, fs1.size)
+ assert_integer_or_nil(fs1.blksize)
+ assert_integer_or_nil(fs1.blocks)
+ assert_kind_of(Time, fs1.atime)
+ assert_kind_of(Time, fs1.mtime)
+ assert_kind_of(Time, fs1.ctime)
+ assert_kind_of(String, fs1.inspect)
+ end
+ assert_raise(Errno::ENOENT) { File.stat(@nofile) }
+ assert_kind_of(File::Stat, File.open(@file) {|f| f.stat})
+ assert_raise(Errno::ENOENT) { File.lstat(@nofile) }
+ assert_kind_of(File::Stat, File.open(@file) {|f| f.lstat})
+ end
+
+ def test_directory_p
+ assert(File.directory?(@dir))
+ assert(!(File.directory?(@dir+"/...")))
+ assert(!(File.directory?(@file)))
+ assert(!(File.directory?(@nofile)))
+ end
+
+ def test_pipe_p ## xxx
+ assert(!(File.pipe?(@dir)))
+ assert(!(File.pipe?(@file)))
+ assert(!(File.pipe?(@nofile)))
+ end
+
+ def test_symlink_p
+ assert(!(File.symlink?(@dir)))
+ assert(!(File.symlink?(@file)))
+ assert(File.symlink?(@symlinkfile)) if @symlinkfile
+ assert(!(File.symlink?(@hardlinkfile))) if @hardlinkfile
+ assert(!(File.symlink?(@nofile)))
+ end
+
+ def test_socket_p ## xxx
+ assert(!(File.socket?(@dir)))
+ assert(!(File.socket?(@file)))
+ assert(!(File.socket?(@nofile)))
+ end
+
+ def test_blockdev_p ## xxx
+ assert(!(File.blockdev?(@dir)))
+ assert(!(File.blockdev?(@file)))
+ assert(!(File.blockdev?(@nofile)))
+ end
+
+ def test_chardev_p ## xxx
+ assert(!(File.chardev?(@dir)))
+ assert(!(File.chardev?(@file)))
+ assert(!(File.chardev?(@nofile)))
+ end
+
+ def test_exist_p
+ assert(File.exist?(@dir))
+ assert(File.exist?(@file))
+ assert(!(File.exist?(@nofile)))
+ end
+
+ def test_readable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ return if Process.euid == 0
+ File.chmod(0200, @file)
+ assert(!(File.readable?(@file)))
+ File.chmod(0600, @file)
+ assert(File.readable?(@file))
+ assert(!(File.readable?(@nofile)))
+ end
+
+ def test_readable_real_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ return if Process.euid == 0
+ File.chmod(0200, @file)
+ assert(!(File.readable_real?(@file)))
+ File.chmod(0600, @file)
+ assert(File.readable_real?(@file))
+ assert(!(File.readable_real?(@nofile)))
+ end
+
+ def test_world_readable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0006, @file)
+ assert(File.world_readable?(@file))
+ File.chmod(0060, @file)
+ assert(!(File.world_readable?(@file)))
+ File.chmod(0600, @file)
+ assert(!(File.world_readable?(@file)))
+ assert(!(File.world_readable?(@nofile)))
+ end
+
+ def test_writable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ return if Process.euid == 0
+ File.chmod(0400, @file)
+ assert(!(File.writable?(@file)))
+ File.chmod(0600, @file)
+ assert(File.writable?(@file))
+ assert(!(File.writable?(@nofile)))
+ end
+
+ def test_writable_real_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ return if Process.euid == 0
+ File.chmod(0400, @file)
+ assert(!(File.writable_real?(@file)))
+ File.chmod(0600, @file)
+ assert(File.writable_real?(@file))
+ assert(!(File.writable_real?(@nofile)))
+ end
+
+ def test_world_writable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0006, @file)
+ assert(File.world_writable?(@file))
+ File.chmod(0060, @file)
+ assert(!(File.world_writable?(@file)))
+ File.chmod(0600, @file)
+ assert(!(File.world_writable?(@file)))
+ assert(!(File.world_writable?(@nofile)))
+ end
+
+ def test_executable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0100, @file)
+ assert(File.executable?(@file))
+ File.chmod(0600, @file)
+ assert(!(File.executable?(@file)))
+ assert(!(File.executable?(@nofile)))
+ end
+
+ def test_executable_real_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0100, @file)
+ assert(File.executable_real?(@file))
+ File.chmod(0600, @file)
+ assert(!(File.executable_real?(@file)))
+ assert(!(File.executable_real?(@nofile)))
+ end
+
+ def test_file_p
+ assert(!(File.file?(@dir)))
+ assert(File.file?(@file))
+ assert(!(File.file?(@nofile)))
+ end
+
+ def test_zero_p
+ assert_nothing_raised { File.zero?(@dir) }
+ assert(!(File.zero?(@file)))
+ assert(File.zero?(@zerofile))
+ assert(!(File.zero?(@nofile)))
+ end
+
+ def test_size_p
+ assert_nothing_raised { File.size?(@dir) }
+ assert_equal(3, File.size?(@file))
+ assert(!(File.size?(@zerofile)))
+ assert(!(File.size?(@nofile)))
+ end
+
+ def test_owned_p ## xxx
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ assert(File.owned?(@file))
+ assert(File.grpowned?(@file))
+ end
+
+ def test_suid_sgid_sticky ## xxx
+ assert(!(File.setuid?(@file)))
+ assert(!(File.setgid?(@file)))
+ assert(!(File.sticky?(@file)))
+ end
+
+ def test_identical_p
+ assert(File.identical?(@file, @file))
+ assert(!(File.identical?(@file, @zerofile)))
+ assert(!(File.identical?(@file, @nofile)))
+ assert(!(File.identical?(@nofile, @file)))
+ end
+
+ def test_s_size
+ assert_integer(File.size(@dir))
+ assert_equal(3, File.size(@file))
+ assert_equal(0, File.size(@zerofile))
+ assert_raise(Errno::ENOENT) { File.size(@nofile) }
+ end
+
+ def test_ftype
+ assert_equal("directory", File.ftype(@dir))
+ assert_equal("file", File.ftype(@file))
+ assert_equal("link", File.ftype(@symlinkfile)) if @symlinkfile
+ assert_equal("file", File.ftype(@hardlinkfile)) if @hardlinkfile
+ assert_raise(Errno::ENOENT) { File.ftype(@nofile) }
+ end
+
+ def test_atime
+ t1 = File.atime(@file)
+ t2 = File.open(@file) {|f| f.atime}
+ assert_kind_of(Time, t1)
+ assert_kind_of(Time, t2)
+ assert_equal(t1, t2)
+ assert_raise(Errno::ENOENT) { File.atime(@nofile) }
+ end
+
+ def test_mtime
+ t1 = File.mtime(@file)
+ t2 = File.open(@file) {|f| f.mtime}
+ assert_kind_of(Time, t1)
+ assert_kind_of(Time, t2)
+ assert_equal(t1, t2)
+ assert_raise(Errno::ENOENT) { File.mtime(@nofile) }
+ end
+
+ def test_ctime
+ t1 = File.ctime(@file)
+ t2 = File.open(@file) {|f| f.ctime}
+ assert_kind_of(Time, t1)
+ assert_kind_of(Time, t2)
+ assert_equal(t1, t2)
+ assert_raise(Errno::ENOENT) { File.ctime(@nofile) }
+ end
+
+ def test_chmod
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ assert_equal(1, File.chmod(0444, @file))
+ assert_equal(0444, File.stat(@file).mode % 01000)
+ assert_equal(0, File.open(@file) {|f| f.chmod(0222)})
+ assert_equal(0222, File.stat(@file).mode % 01000)
+ File.chmod(0600, @file)
+ assert_raise(Errno::ENOENT) { File.chmod(0600, @nofile) }
+ end
+
+ def test_lchmod
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ assert_equal(1, File.lchmod(0444, @file))
+ assert_equal(0444, File.stat(@file).mode % 01000)
+ File.lchmod(0600, @file)
+ assert_raise(Errno::ENOENT) { File.lchmod(0600, @nofile) }
+ rescue NotImplementedError
+ end
+
+ def test_chown ## xxx
+ end
+
+ def test_lchown ## xxx
+ end
+
+ def test_symlink
+ return unless @symlinkfile
+ assert_equal("link", File.ftype(@symlinkfile))
+ assert_raise(Errno::EEXIST) { File.symlink(@file, @file) }
+ end
+
+ def test_utime
+ t = Time.local(2000)
+ File.utime(t + 1, t + 2, @zerofile)
+ assert_equal(t + 1, File.atime(@zerofile))
+ assert_equal(t + 2, File.mtime(@zerofile))
+ end
+
+ def test_hardlink
+ return unless @hardlinkfile
+ assert_equal("file", File.ftype(@hardlinkfile))
+ assert_raise(Errno::EEXIST) { File.link(@file, @file) }
+ end
+
+ def test_symlink2
+ return unless @symlinkfile
+ assert_equal(@file, File.readlink(@symlinkfile))
+ assert_raise(Errno::EINVAL) { File.readlink(@file) }
+ assert_raise(Errno::ENOENT) { File.readlink(@nofile) }
+ rescue NotImplementedError
+ end
+
+ def test_unlink
+ assert_equal(1, File.unlink(@file))
+ make_file("foo", @file)
+ assert_raise(Errno::ENOENT) { File.unlink(@nofile) }
+ end
+
+ def test_rename
+ assert_equal(0, File.rename(@file, @nofile))
+ assert(!(File.exist?(@file)))
+ assert(File.exist?(@nofile))
+ assert_equal(0, File.rename(@nofile, @file))
+ assert_raise(Errno::ENOENT) { File.rename(@nofile, @file) }
+ end
+
+ def test_umask
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ prev = File.umask(0777)
+ assert_equal(0777, File.umask)
+ open(@nofile, "w") { }
+ assert_equal(0, File.stat(@nofile).mode % 01000)
+ File.unlink(@nofile)
+ assert_equal(0777, File.umask(prev))
+ assert_raise(ArgumentError) { File.umask(0, 1, 2) }
+ end
+
+ def test_expand_path
+ assert_equal(@file, File.expand_path(File.basename(@file), File.dirname(@file)))
+ if /cygwin|mingw|mswin|bccwin/ =~ RUBY_PLATFORM
+ assert_equal(@file, File.expand_path(@file + " "))
+ assert_equal(@file, File.expand_path(@file + "."))
+ assert_equal(@file, File.expand_path(@file + "::$DATA"))
+ assert_match(/\Ac:\//i, File.expand_path('c:'), '[ruby-core:31591]')
+ end
+ assert_kind_of(String, File.expand_path("~"))
+ assert_raise(ArgumentError) { File.expand_path("~foo_bar_baz_unknown_user_wahaha") }
+ assert_raise(ArgumentError) { File.expand_path("~foo_bar_baz_unknown_user_wahaha", "/") }
+ begin
+ bug3630 = '[ruby-core:31537]'
+ home = ENV["HOME"]
+ ENV["HOME"] = nil
+ assert_raise(ArgumentError) { File.expand_path("~") }
+ ENV["HOME"] = "~"
+ assert_raise(ArgumentError, bug3630) { File.expand_path("~") }
+ ENV["HOME"] = "."
+ assert_raise(ArgumentError, bug3630) { File.expand_path("~") }
+ ensure
+ ENV["HOME"] = home
+ end
+ assert_incompatible_encoding {|d| File.expand_path(d)}
+ end
+
+ def test_basename
+ assert_equal(File.basename(@file).sub(/\.test$/, ""), File.basename(@file, ".test"))
+ assert_equal("", s = File.basename(""))
+ assert(!s.frozen?, '[ruby-core:24199]')
+ assert_equal("foo", s = File.basename("foo"))
+ assert(!s.frozen?, '[ruby-core:24199]')
+ assert_equal("foo", File.basename("foo", ".ext"))
+ assert_equal("foo", File.basename("foo.ext", ".ext"))
+ assert_equal("foo", File.basename("foo.ext", ".*"))
+ if /cygwin|mingw|mswin|bccwin/ =~ RUBY_PLATFORM
+ basename = File.basename(@file)
+ assert_equal(basename, File.basename(@file + " "))
+ assert_equal(basename, File.basename(@file + "."))
+ assert_equal(basename, File.basename(@file + "::$DATA"))
+ basename.chomp!(".test")
+ assert_equal(basename, File.basename(@file + " ", ".test"))
+ assert_equal(basename, File.basename(@file + ".", ".test"))
+ assert_equal(basename, File.basename(@file + "::$DATA", ".test"))
+ assert_equal(basename, File.basename(@file + " ", ".*"))
+ assert_equal(basename, File.basename(@file + ".", ".*"))
+ assert_equal(basename, File.basename(@file + "::$DATA", ".*"))
+ end
+
+ assert_incompatible_encoding {|d| File.basename(d)}
+ assert_incompatible_encoding {|d| File.basename(d, ".*")}
+ assert_raise(Encoding::CompatibilityError) {File.basename("foo.ext", ".*".encode("utf-16le"))}
+ end
+
+ def test_dirname
+ assert(@file.start_with?(File.dirname(@file)))
+ assert_equal(".", File.dirname(""))
+ assert_incompatible_encoding {|d| File.dirname(d)}
+ end
+
+ def test_extname
+ assert_equal(".test", File.extname(@file))
+ prefixes = ["", "/", ".", "/.", "bar/.", "/bar/."]
+ infixes = ["", " ", "."]
+ infixes2 = infixes + [".ext "]
+ appendixes = [""]
+ if /cygwin|mingw|mswin|bccwin/ =~ RUBY_PLATFORM
+ appendixes << " " << "." << "::$DATA" << "::$DATA.bar"
+ end
+ prefixes.each do |prefix|
+ appendixes.each do |appendix|
+ infixes.each do |infix|
+ path = "#{prefix}foo#{infix}#{appendix}"
+ assert_equal("", File.extname(path), "File.extname(#{path.inspect})")
+ end
+ infixes2.each do |infix|
+ path = "#{prefix}foo#{infix}.ext#{appendix}"
+ assert_equal(".ext", File.extname(path), "File.extname(#{path.inspect})")
+ end
+ end
+ end
+ bug3175 = '[ruby-core:29627]'
+ assert_equal(".rb", File.extname("/tmp//bla.rb"), bug3175)
+
+ assert_incompatible_encoding {|d| File.extname(d)}
+ end
+
+ def test_split
+ d, b = File.split(@file)
+ assert_equal(File.dirname(@file), d)
+ assert_equal(File.basename(@file), b)
+ end
+
+ def test_join
+ s = "foo" + File::SEPARATOR + "bar" + File::SEPARATOR + "baz"
+ assert_equal(s, File.join("foo", "bar", "baz"))
+ assert_equal(s, File.join(["foo", "bar", "baz"]))
+ o = Object.new
+ def o.to_path; "foo"; end
+ assert_equal(s, File.join(o, "bar", "baz"))
+ assert_equal(s, File.join("foo" + File::SEPARATOR, "bar", File::SEPARATOR + "baz"))
+ end
+
+ def test_truncate
+ assert_equal(0, File.truncate(@file, 1))
+ assert(File.exist?(@file))
+ assert_equal(1, File.size(@file))
+ assert_equal(0, File.truncate(@file, 0))
+ assert(File.exist?(@file))
+ assert(File.zero?(@file))
+ make_file("foo", @file)
+ assert_raise(Errno::ENOENT) { File.truncate(@nofile, 0) }
+
+ f = File.new(@file, "w")
+ assert_equal(0, f.truncate(2))
+ assert(File.exist?(@file))
+ assert_equal(2, File.size(@file))
+ assert_equal(0, f.truncate(0))
+ assert(File.exist?(@file))
+ assert(File.zero?(@file))
+ f.close
+ make_file("foo", @file)
+
+ assert_raise(IOError) { File.open(@file) {|ff| ff.truncate(0)} }
+ rescue NotImplementedError
+ end
+
+ def test_flock ## xxx
+ f = File.new(@file, "r+")
+ f.flock(File::LOCK_EX)
+ f.flock(File::LOCK_SH)
+ f.flock(File::LOCK_UN)
+ f.close
+ rescue NotImplementedError
+ end
+
+ def test_test
+ sleep(@time - Time.now + 1.1)
+ make_file("foo", @file + "2")
+ [@dir, @file, @zerofile, @symlinkfile, @hardlinkfile].compact.each do |f|
+ assert_equal(File.atime(f), test(?A, f))
+ assert_equal(File.ctime(f), test(?C, f))
+ assert_equal(File.mtime(f), test(?M, f))
+ assert_equal(File.blockdev?(f), test(?b, f))
+ assert_equal(File.chardev?(f), test(?c, f))
+ assert_equal(File.directory?(f), test(?d, f))
+ assert_equal(File.exist?(f), test(?e, f))
+ assert_equal(File.file?(f), test(?f, f))
+ assert_equal(File.setgid?(f), test(?g, f))
+ assert_equal(File.grpowned?(f), test(?G, f))
+ assert_equal(File.sticky?(f), test(?k, f))
+ assert_equal(File.symlink?(f), test(?l, f))
+ assert_equal(File.owned?(f), test(?o, f))
+ assert_nothing_raised { test(?O, f) }
+ assert_equal(File.pipe?(f), test(?p, f))
+ assert_equal(File.readable?(f), test(?r, f))
+ assert_equal(File.readable_real?(f), test(?R, f))
+ assert_equal(File.size?(f), test(?s, f))
+ assert_equal(File.socket?(f), test(?S, f))
+ assert_equal(File.setuid?(f), test(?u, f))
+ assert_equal(File.writable?(f), test(?w, f))
+ assert_equal(File.writable_real?(f), test(?W, f))
+ assert_equal(File.executable?(f), test(?x, f))
+ assert_equal(File.executable_real?(f), test(?X, f))
+ assert_equal(File.zero?(f), test(?z, f))
+ end
+ assert_equal(false, test(?-, @dir, @file))
+ assert_equal(true, test(?-, @file, @file))
+ assert_equal(true, test(?=, @file, @file))
+ assert_equal(false, test(?>, @file, @file))
+ assert_equal(false, test(?<, @file, @file))
+ unless /cygwin/ =~ RUBY_PLATFORM
+ assert_equal(false, test(?=, @file, @file + "2"))
+ assert_equal(false, test(?>, @file, @file + "2"))
+ assert_equal(true, test(?>, @file + "2", @file))
+ assert_equal(true, test(?<, @file, @file + "2"))
+ assert_equal(false, test(?<, @file + "2", @file))
+ end
+ assert_raise(ArgumentError) { test }
+ assert_raise(Errno::ENOENT) { test(?A, @nofile) }
+ assert_raise(ArgumentError) { test(?a) }
+ assert_raise(ArgumentError) { test("\0".ord) }
+ end
+
+ def test_stat_init
+ sleep(@time - Time.now + 1.1)
+ make_file("foo", @file + "2")
+ fs1, fs2 = File::Stat.new(@file), File::Stat.new(@file + "2")
+ assert_nothing_raised do
+ assert_equal(0, fs1 <=> fs1)
+ assert_equal(-1, fs1 <=> fs2)
+ assert_equal(1, fs2 <=> fs1)
+ assert_nil(fs1 <=> nil)
+ assert_integer(fs1.dev)
+ assert_integer_or_nil(fs1.rdev)
+ assert_integer_or_nil(fs1.dev_major)
+ assert_integer_or_nil(fs1.dev_minor)
+ assert_integer_or_nil(fs1.rdev_major)
+ assert_integer_or_nil(fs1.rdev_minor)
+ assert_integer(fs1.ino)
+ assert_integer(fs1.mode)
+ unless /emx|mswin|mingw/ =~ RUBY_PLATFORM
+ # on Windows, nlink is always 1. but this behavior will be changed
+ # in the future.
+ assert_equal(@hardlinkfile ? 2 : 1, fs1.nlink)
+ end
+ assert_integer(fs1.uid)
+ assert_integer(fs1.gid)
+ assert_equal(3, fs1.size)
+ assert_integer_or_nil(fs1.blksize)
+ assert_integer_or_nil(fs1.blocks)
+ assert_kind_of(Time, fs1.atime)
+ assert_kind_of(Time, fs1.mtime)
+ assert_kind_of(Time, fs1.ctime)
+ assert_kind_of(String, fs1.inspect)
+ end
+ assert_raise(Errno::ENOENT) { File::Stat.new(@nofile) }
+ assert_kind_of(File::Stat, File::Stat.new(@file).dup)
+ assert_raise(TypeError) do
+ File::Stat.new(@file).instance_eval { initialize_copy(0) }
+ end
+ end
+
+ def test_stat_ftype
+ assert_equal("directory", File::Stat.new(@dir).ftype)
+ assert_equal("file", File::Stat.new(@file).ftype)
+ # File::Stat uses stat
+ assert_equal("file", File::Stat.new(@symlinkfile).ftype) if @symlinkfile
+ assert_equal("file", File::Stat.new(@hardlinkfile).ftype) if @hardlinkfile
+ end
+
+ def test_stat_directory_p
+ assert(File::Stat.new(@dir).directory?)
+ assert(!(File::Stat.new(@file).directory?))
+ end
+
+ def test_stat_pipe_p ## xxx
+ assert(!(File::Stat.new(@dir).pipe?))
+ assert(!(File::Stat.new(@file).pipe?))
+ end
+
+ def test_stat_symlink_p
+ assert(!(File::Stat.new(@dir).symlink?))
+ assert(!(File::Stat.new(@file).symlink?))
+ # File::Stat uses stat
+ assert(!(File::Stat.new(@symlinkfile).symlink?)) if @symlinkfile
+ assert(!(File::Stat.new(@hardlinkfile).symlink?)) if @hardlinkfile
+ end
+
+ def test_stat_socket_p ## xxx
+ assert(!(File::Stat.new(@dir).socket?))
+ assert(!(File::Stat.new(@file).socket?))
+ end
+
+ def test_stat_blockdev_p ## xxx
+ assert(!(File::Stat.new(@dir).blockdev?))
+ assert(!(File::Stat.new(@file).blockdev?))
+ end
+
+ def test_stat_chardev_p ## xxx
+ assert(!(File::Stat.new(@dir).chardev?))
+ assert(!(File::Stat.new(@file).chardev?))
+ end
+
+ def test_stat_readable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ return if Process.euid == 0
+ File.chmod(0200, @file)
+ assert(!(File::Stat.new(@file).readable?))
+ File.chmod(0600, @file)
+ assert(File::Stat.new(@file).readable?)
+ end
+
+ def test_stat_readable_real_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ return if Process.euid == 0
+ File.chmod(0200, @file)
+ assert(!(File::Stat.new(@file).readable_real?))
+ File.chmod(0600, @file)
+ assert(File::Stat.new(@file).readable_real?)
+ end
+
+ def test_stat_world_readable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0006, @file)
+ assert(File::Stat.new(@file).world_readable?)
+ File.chmod(0060, @file)
+ assert(!(File::Stat.new(@file).world_readable?))
+ File.chmod(0600, @file)
+ assert(!(File::Stat.new(@file).world_readable?))
+ end
+
+ def test_stat_writable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ return if Process.euid == 0
+ File.chmod(0400, @file)
+ assert(!(File::Stat.new(@file).writable?))
+ File.chmod(0600, @file)
+ assert(File::Stat.new(@file).writable?)
+ end
+
+ def test_stat_writable_real_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ return if Process.euid == 0
+ File.chmod(0400, @file)
+ assert(!(File::Stat.new(@file).writable_real?))
+ File.chmod(0600, @file)
+ assert(File::Stat.new(@file).writable_real?)
+ end
+
+ def test_stat_world_writable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0006, @file)
+ assert(File::Stat.new(@file).world_writable?)
+ File.chmod(0060, @file)
+ assert(!(File::Stat.new(@file).world_writable?))
+ File.chmod(0600, @file)
+ assert(!(File::Stat.new(@file).world_writable?))
+ end
+
+ def test_stat_executable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0100, @file)
+ assert(File::Stat.new(@file).executable?)
+ File.chmod(0600, @file)
+ assert(!(File::Stat.new(@file).executable?))
+ end
+
+ def test_stat_executable_real_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0100, @file)
+ assert(File::Stat.new(@file).executable_real?)
+ File.chmod(0600, @file)
+ assert(!(File::Stat.new(@file).executable_real?))
+ end
+
+ def test_stat_file_p
+ assert(!(File::Stat.new(@dir).file?))
+ assert(File::Stat.new(@file).file?)
+ end
+
+ def test_stat_zero_p
+ assert_nothing_raised { File::Stat.new(@dir).zero? }
+ assert(!(File::Stat.new(@file).zero?))
+ assert(File::Stat.new(@zerofile).zero?)
+ end
+
+ def test_stat_size_p
+ assert_nothing_raised { File::Stat.new(@dir).size? }
+ assert_equal(3, File::Stat.new(@file).size?)
+ assert(!(File::Stat.new(@zerofile).size?))
+ end
+
+ def test_stat_owned_p ## xxx
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ assert(File::Stat.new(@file).owned?)
+ assert(File::Stat.new(@file).grpowned?)
+ end
+
+ def test_stat_suid_sgid_sticky ## xxx
+ assert(!(File::Stat.new(@file).setuid?))
+ assert(!(File::Stat.new(@file).setgid?))
+ assert(!(File::Stat.new(@file).sticky?))
+ end
+
+ def test_stat_size
+ assert_integer(File::Stat.new(@dir).size)
+ assert_equal(3, File::Stat.new(@file).size)
+ assert_equal(0, File::Stat.new(@zerofile).size)
+ end
+
+ def test_path_check
+ assert_nothing_raised { ENV["PATH"] }
+ end
+
+ def test_find_file
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ load(@file)
+ end.join
+ end
+ end
+
+ def test_size
+ assert_equal(3, File.open(@file) {|f| f.size })
+ File.open(@file, "a") do |f|
+ f.write("bar")
+ assert_equal(6, f.size)
+ end
+ end
+
+ def test_absolute_path
+ assert_equal(File.join(Dir.pwd, "~foo"), File.absolute_path("~foo"))
+ dir = File.expand_path("/bar")
+ assert_equal(File.join(dir, "~foo"), File.absolute_path("~foo", dir))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_fixnum.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_fixnum.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_fixnum.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,232 @@
+require 'test/unit'
+
+class TestFixnum < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_pow
+ [1, 2, 2**64, 2**63*3, 2**64*3].each do |y|
+ [-1, 0, 1].each do |x|
+ z1 = x**y
+ z2 = (-x)**y
+ if y % 2 == 1
+ assert_equal(z2, -z1)
+ else
+ assert_equal(z2, z1)
+ end
+ end
+ end
+ end
+
+ def test_succ
+ assert_equal(0x40000000, 0x3fffffff.succ, "[ruby-dev:31189]")
+ assert_equal(0x4000000000000000, 0x3fffffffffffffff.succ, "[ruby-dev:31190]")
+ end
+
+ def test_pred
+ assert_equal(-0x40000001, (-0x40000000).pred)
+ assert_equal(-0x4000000000000001, (-0x4000000000000000).pred)
+ end
+
+ def test_plus
+ assert_equal(0x40000000, 0x3fffffff+1)
+ assert_equal(0x4000000000000000, 0x3fffffffffffffff+1)
+ assert_equal(-0x40000001, (-0x40000000)+(-1))
+ assert_equal(-0x4000000000000001, (-0x4000000000000000)+(-1))
+ assert_equal(-0x80000000, (-0x40000000)+(-0x40000000))
+ end
+
+ def test_sub
+ assert_equal(0x40000000, 0x3fffffff-(-1))
+ assert_equal(0x4000000000000000, 0x3fffffffffffffff-(-1))
+ assert_equal(-0x40000001, (-0x40000000)-1)
+ assert_equal(-0x4000000000000001, (-0x4000000000000000)-1)
+ assert_equal(-0x80000000, (-0x40000000)-0x40000000)
+ end
+
+ def test_mult
+ assert_equal(0x40000000, 0x20000000*2)
+ assert_equal(0x4000000000000000, 0x2000000000000000*2)
+ assert_equal(-0x40000001, 33025*(-32513))
+ assert_equal(-0x4000000000000001, 1380655685*(-3340214413))
+ assert_equal(0x40000000, (-0x40000000)*(-1))
+ end
+
+ def test_div
+ assert_equal(2, 5/2)
+ assert_equal(0, 1/2)
+ assert_equal(-1, -1/2)
+ assert_equal(0, -(1/2))
+ assert_equal(-1, (-1)/2)
+ assert_equal(0, (-1)/(-2))
+ assert_equal(-1, 1/(-2))
+ assert_equal(1, -(1/(-2)))
+ assert_equal(0x3fffffff, 0xbffffffd/3)
+ assert_equal(0x40000000, 0xc0000000/3)
+ assert_equal(0x4000000000000000, 0xc000000000000000/3)
+ assert_equal(-0x40000001, 0xc0000003/(-3))
+ assert_equal(-0x4000000000000001, 0xc000000000000003/(-3))
+ assert_equal(0x40000000, (-0x40000000)/(-1), "[ruby-dev:31210]")
+ assert_equal(0x4000000000000000, (-0x4000000000000000)/(-1))
+ end
+
+ def test_mod
+ assert_equal(2, (-0x40000000) % 3)
+ assert_equal(0, (-0x40000000) % (-1))
+ end
+
+ def test_divmod
+ (-5).upto(5) {|a|
+ (-5).upto(5) {|b|
+ next if b == 0
+ q, r = a.divmod(b)
+ assert_equal(a, b*q+r)
+ assert(r.abs < b.abs)
+ assert(0 < b ? (0 <= r && r < b) : (b < r && r <= 0))
+ assert_equal(q, a/b)
+ assert_equal(q, a.div(b))
+ assert_equal(r, a%b)
+ assert_equal(r, a.modulo(b))
+ }
+ }
+ end
+
+ def test_not
+ assert_equal(-0x40000000, ~0x3fffffff)
+ assert_equal(0x3fffffff, ~-0x40000000)
+ end
+
+ def test_lshift
+ assert_equal(0x40000000, 0x20000000 << 1)
+ assert_equal(-0x40000000, (-0x20000000) << 1)
+ assert_equal(-0x80000000, (-0x40000000) << 1)
+ end
+
+ def test_rshift
+ assert_equal(0x20000000, 0x40000000 >> 1)
+ assert_equal(-0x20000000, (-0x40000000) >> 1)
+ assert_equal(-0x40000000, (-0x80000000) >> 1)
+ end
+
+ def test_abs
+ assert_equal(0x40000000, (-0x40000000).abs)
+ assert_equal(0x4000000000000000, (-0x4000000000000000).abs)
+ end
+
+ def test_to_s
+ assert_equal("1010", 10.to_s(2))
+ assert_equal("a", 10.to_s(36))
+ assert_raise(ArgumentError) { 10.to_s(1) }
+ end
+
+ def test_plus2
+ assert_equal(2, 1 + 1)
+ assert_equal(4294967297, 1 + 2**32)
+ assert_equal(2.0, 1 + 1.0)
+ assert_raise(TypeError) { 1 + nil }
+ end
+
+ def test_minus
+ assert_equal(0, 1 - 1)
+ assert_equal(-4294967295, 1 - 2**32)
+ assert_equal(0.0, 1 - 1.0)
+ assert_raise(TypeError) { 1 - nil }
+ end
+
+ def test_mul
+ assert_equal(6, 2.send(:*, 3))
+ a = 2**30-1
+ assert_equal(1152921502459363329, a.send(:*, a))
+
+ assert_equal(6.0, 2 * 3.0)
+ assert_raise(TypeError) { 2 * nil }
+ end
+
+ def test_divide
+ assert_equal(2.0, 4.quo(2))
+ assert_equal(2.0, 4 / 2)
+ assert_equal(2.0, 4.div(2))
+
+ assert_equal(0.5**32, 1.quo(2**32))
+ assert_equal(0, 1 / (2**32))
+ assert_equal(0, 1.div(2**32))
+
+ assert_equal(0.5, 1.quo(2.0))
+ assert_equal(0.5, 1 / 2.0)
+ assert_equal(0, 1.div(2.0))
+
+ ### rational changes the behavior of Fixnum#quo
+ #assert_raise(TypeError) { 2.quo(nil) }
+ assert_raise(TypeError, NoMethodError) { 2.quo(nil) }
+ assert_raise(TypeError) { 2 / nil }
+ assert_raise(TypeError) { 2.div(nil) }
+
+ assert_equal(0, 4.modulo(2))
+ assert_equal(1, 1.modulo(2**32))
+ assert_equal(1, 1.modulo(2.0))
+ assert_raise(TypeError) { 2.modulo(nil) }
+
+ assert_equal([2, 0], 4.divmod(2))
+ assert_equal([0, 1], 1.divmod(2**32))
+ assert_equal([0, 1], 1.divmod(2.0))
+ assert_raise(TypeError) { 2.divmod(nil) }
+ end
+
+ def test_pow2
+ assert_equal(65536, 2**16)
+ assert_equal(4294967296, 2**32)
+ assert_equal(0.5**16, 2**-16)
+ assert_equal(1, (-1)**4294967296)
+ assert_equal(-1, (-1)**4294967295)
+ assert_equal(4, 2**((2**32).coerce(2).first))
+ assert_equal(2, 4**0.5)
+ assert_equal(0, 0**0.5)
+ assert_equal(1, (0**-1.0).infinite?)
+ ### rational changes the behavior of Fixnum#**
+ #assert_raise(TypeError) { 1 ** nil }
+ assert_raise(TypeError, NoMethodError) { 1 ** nil }
+ end
+
+ def test_cmp
+ assert(1 != nil)
+
+ assert_equal(0, 1 <=> 1)
+ assert_equal(-1, 1 <=> 4294967296)
+ assert_equal(0, 1 <=> 1.0)
+ assert_nil(1 <=> nil)
+
+ assert(1.send(:>, 0))
+ assert(!(1.send(:>, 1)))
+ assert(!(1.send(:>, 2)))
+ assert(!(1.send(:>, 4294967296)))
+ assert(1.send(:>, 0.0))
+ assert_raise(ArgumentError) { 1.send(:>, nil) }
+
+ assert(1.send(:>=, 0))
+ assert(1.send(:>=, 1))
+ assert(!(1.send(:>=, 2)))
+ assert(!(1.send(:>=, 4294967296)))
+ assert(1.send(:>=, 0.0))
+ assert_raise(ArgumentError) { 1.send(:>=, nil) }
+
+ assert(!(1.send(:<, 0)))
+ assert(!(1.send(:<, 1)))
+ assert(1.send(:<, 2))
+ assert(1.send(:<, 4294967296))
+ assert(!(1.send(:<, 0.0)))
+ assert_raise(ArgumentError) { 1.send(:<, nil) }
+
+ assert(!(1.send(:<=, 0)))
+ assert(1.send(:<=, 1))
+ assert(1.send(:<=, 2))
+ assert(1.send(:<=, 4294967296))
+ assert(!(1.send(:<=, 0.0)))
+ assert_raise(ArgumentError) { 1.send(:<=, nil) }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_float.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_float.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_float.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,453 @@
+require 'test/unit'
+
+class TestFloat < Test::Unit::TestCase
+ def test_float
+ assert_equal(2, 2.6.floor)
+ assert_equal(-3, (-2.6).floor)
+ assert_equal(3, 2.6.ceil)
+ assert_equal(-2, (-2.6).ceil)
+ assert_equal(2, 2.6.truncate)
+ assert_equal(-2, (-2.6).truncate)
+ assert_equal(3, 2.6.round)
+ assert_equal(-2, (-2.4).truncate)
+ assert((13.4 % 1 - 0.4).abs < 0.0001)
+ assert_equal(36893488147419111424,
+ 36893488147419107329.0.to_i)
+ end
+
+ def nan_test(x,y)
+ extend Test::Unit::Assertions
+ assert(x != y)
+ assert_equal(false, (x < y))
+ assert_equal(false, (x > y))
+ assert_equal(false, (x <= y))
+ assert_equal(false, (x >= y))
+ end
+ def test_nan
+ nan = Float::NAN
+ nan_test(nan, nan)
+ nan_test(nan, 0)
+ nan_test(nan, 1)
+ nan_test(nan, -1)
+ nan_test(nan, 1000)
+ nan_test(nan, -1000)
+ nan_test(nan, 1_000_000_000_000)
+ nan_test(nan, -1_000_000_000_000)
+ nan_test(nan, 100.0);
+ nan_test(nan, -100.0);
+ nan_test(nan, 0.001);
+ nan_test(nan, -0.001);
+ nan_test(nan, 1.0/0);
+ nan_test(nan, -1.0/0);
+ end
+
+ def test_precision
+ u = 3.7517675036461267e+17
+ v = sprintf("%.16e", u).to_f
+ assert_in_delta(u, v, u.abs * Float::EPSILON)
+ assert_in_delta(u, v, v.abs * Float::EPSILON)
+ end
+
+ def test_symmetry_bignum # [ruby-bugs-ja:118]
+ a = 100000000000000000000000
+ b = 100000000000000000000000.0
+ assert_equal(a == b, b == a)
+ end
+
+ def test_strtod
+ a = Float("0")
+ assert(a.abs < Float::EPSILON)
+ a = Float("0.0")
+ assert(a.abs < Float::EPSILON)
+ a = Float("+0.0")
+ assert(a.abs < Float::EPSILON)
+ a = Float("-0.0")
+ assert(a.abs < Float::EPSILON)
+ a = Float("0.0000000000000000001")
+ assert(a != 0.0)
+ a = Float("+0.0000000000000000001")
+ assert(a != 0.0)
+ a = Float("-0.0000000000000000001")
+ assert(a != 0.0)
+ a = Float(".0")
+ assert(a.abs < Float::EPSILON)
+ a = Float("+.0")
+ assert(a.abs < Float::EPSILON)
+ a = Float("-.0")
+ assert(a.abs < Float::EPSILON)
+ assert_raise(ArgumentError){Float("0.")}
+ assert_raise(ArgumentError){Float("+0.")}
+ assert_raise(ArgumentError){Float("-0.")}
+ assert_raise(ArgumentError){Float(".")}
+ assert_raise(ArgumentError){Float("+")}
+ assert_raise(ArgumentError){Float("+.")}
+ assert_raise(ArgumentError){Float("-")}
+ assert_raise(ArgumentError){Float("-.")}
+ assert_raise(ArgumentError){Float("1e")}
+ assert_raise(ArgumentError){Float("1__1")}
+ # add expected behaviour here.
+ assert_equal(10, Float("1_0"))
+
+ assert_equal([ 0.0].pack('G'), [Float(" 0x0p+0").to_f].pack('G'))
+ assert_equal([-0.0].pack('G'), [Float("-0x0p+0").to_f].pack('G'))
+ assert_equal(255.0, Float("0Xff"))
+ assert_equal(255.5, Float("0Xff.8"))
+ assert_equal(1.0, Float("0X1.P+0"))
+ assert_equal(1024.0, Float("0x1p10"))
+ assert_equal(1024.0, Float("0x1p+10"))
+ assert_equal(0.0009765625, Float("0x1p-10"))
+ assert_equal(2.6881171418161356e+43, Float("0x1.3494a9b171bf5p+144"))
+ assert_equal(-3.720075976020836e-44, Float("-0x1.a8c1f14e2af5dp-145"))
+
+ end
+
+ def test_divmod
+ assert_equal([2, 3.5], 11.5.divmod(4))
+ assert_equal([-3, -0.5], 11.5.divmod(-4))
+ assert_equal([-3, 0.5], (-11.5).divmod(4))
+ assert_equal([2, -3.5], (-11.5).divmod(-4))
+ end
+
+ def test_div
+ assert_equal(2, 11.5.div(4))
+ assert_equal(-3, 11.5.div(-4))
+ assert_equal(-3, (-11.5).div(4))
+ assert_equal(2, (-11.5).div(-4))
+ end
+
+ def test_modulo
+ assert_equal(3.5, 11.5.modulo(4))
+ assert_equal(-0.5, 11.5.modulo(-4))
+ assert_equal(0.5, (-11.5).modulo(4))
+ assert_equal(-3.5, (-11.5).modulo(-4))
+ end
+
+ def test_remainder
+ assert_equal(3.5, 11.5.remainder(4))
+ assert_equal(3.5, 11.5.remainder(-4))
+ assert_equal(-3.5, (-11.5).remainder(4))
+ assert_equal(-3.5, (-11.5).remainder(-4))
+ end
+
+ def test_to_s
+ inf = Float::INFINITY
+ assert_equal("Infinity", inf.to_s)
+ assert_equal("-Infinity", (-inf).to_s)
+ assert_equal("NaN", (inf / inf).to_s)
+
+ assert_equal("1.0e+18", 1000_00000_00000_00000.0.to_s)
+
+ bug3273 = '[ruby-core:30145]'
+ [0.21611564636388508, 0.56].each do |f|
+ s = f.to_s
+ assert_equal(f, s.to_f, bug3273)
+ assert_not_equal(f, s.chop.to_f, bug3273)
+ end
+ end
+
+ def test_coerce
+ assert_equal(Float, 1.0.coerce(1).first.class)
+ end
+
+ def test_plus
+ assert_equal(4.0, 2.0.send(:+, 2))
+ assert_equal(4.0, 2.0.send(:+, (2**32).coerce(2).first))
+ assert_equal(4.0, 2.0.send(:+, 2.0))
+ assert_raise(TypeError) { 2.0.send(:+, nil) }
+ end
+
+ def test_minus
+ assert_equal(0.0, 2.0.send(:-, 2))
+ assert_equal(0.0, 2.0.send(:-, (2**32).coerce(2).first))
+ assert_equal(0.0, 2.0.send(:-, 2.0))
+ assert_raise(TypeError) { 2.0.send(:-, nil) }
+ end
+
+ def test_mul
+ assert_equal(4.0, 2.0.send(:*, 2))
+ assert_equal(4.0, 2.0.send(:*, (2**32).coerce(2).first))
+ assert_equal(4.0, 2.0.send(:*, 2.0))
+ assert_raise(TypeError) { 2.0.send(:*, nil) }
+ end
+
+ def test_div2
+ assert_equal(1.0, 2.0.send(:/, 2))
+ assert_equal(1.0, 2.0.send(:/, (2**32).coerce(2).first))
+ assert_equal(1.0, 2.0.send(:/, 2.0))
+ assert_raise(TypeError) { 2.0.send(:/, nil) }
+ end
+
+ def test_modulo2
+ assert_equal(0.0, 2.0.send(:%, 2))
+ assert_equal(0.0, 2.0.send(:%, (2**32).coerce(2).first))
+ assert_equal(0.0, 2.0.send(:%, 2.0))
+ assert_raise(TypeError) { 2.0.send(:%, nil) }
+ end
+
+ def test_divmod2
+ assert_equal([1.0, 0.0], 2.0.divmod(2))
+ assert_equal([1.0, 0.0], 2.0.divmod((2**32).coerce(2).first))
+ assert_equal([1.0, 0.0], 2.0.divmod(2.0))
+ assert_raise(TypeError) { 2.0.divmod(nil) }
+
+ inf = Float::INFINITY
+ assert_raise(ZeroDivisionError) {inf.divmod(0)}
+
+ a, b = (2.0**32).divmod(1.0)
+ assert_equal(2**32, a)
+ assert_equal(0, b)
+ end
+
+ def test_pow
+ assert_equal(1.0, 1.0 ** (2**32))
+ assert_equal(1.0, 1.0 ** 1.0)
+ assert_raise(TypeError) { 1.0 ** nil }
+ end
+
+ def test_eql
+ inf = Float::INFINITY
+ nan = Float::NAN
+ assert(1.0.eql?(1.0))
+ assert(inf.eql?(inf))
+ assert(!(nan.eql?(nan)))
+ assert(!(1.0.eql?(nil)))
+
+ assert(1.0 == 1)
+ assert(1.0 != 2**32)
+ assert(1.0 != nan)
+ assert(1.0 != nil)
+ end
+
+ def test_cmp
+ inf = Float::INFINITY
+ nan = Float::NAN
+ assert_equal(0, 1.0 <=> 1.0)
+ assert_equal(1, 1.0 <=> 0.0)
+ assert_equal(-1, 1.0 <=> 2.0)
+ assert_nil(1.0 <=> nil)
+ assert_nil(1.0 <=> nan)
+ assert_nil(nan <=> 1.0)
+
+ assert_equal(0, 1.0 <=> 1)
+ assert_equal(1, 1.0 <=> 0)
+ assert_equal(-1, 1.0 <=> 2)
+
+ assert_equal(-1, 1.0 <=> 2**32)
+
+ assert_equal(1, inf <=> (Float::MAX.to_i*2))
+ assert_equal(-1, -inf <=> (-Float::MAX.to_i*2))
+ assert_equal(-1, (Float::MAX.to_i*2) <=> inf)
+ assert_equal(1, (-Float::MAX.to_i*2) <=> -inf)
+
+ assert_raise(ArgumentError) { 1.0 > nil }
+ assert_raise(ArgumentError) { 1.0 >= nil }
+ assert_raise(ArgumentError) { 1.0 < nil }
+ assert_raise(ArgumentError) { 1.0 <= nil }
+ end
+
+ def test_zero_p
+ assert(0.0.zero?)
+ assert(!(1.0.zero?))
+ end
+
+ def test_infinite_p
+ inf = Float::INFINITY
+ assert_equal(1, inf.infinite?)
+ assert_equal(-1, (-inf).infinite?)
+ assert_nil(1.0.infinite?)
+ end
+
+ def test_finite_p
+ inf = Float::INFINITY
+ assert(!(inf.finite?))
+ assert(!((-inf).finite?))
+ assert(1.0.finite?)
+ end
+
+ def test_floor_ceil_round_truncate
+ assert_equal(1, 1.5.floor)
+ assert_equal(2, 1.5.ceil)
+ assert_equal(2, 1.5.round)
+ assert_equal(1, 1.5.truncate)
+
+ assert_equal(2, 2.0.floor)
+ assert_equal(2, 2.0.ceil)
+ assert_equal(2, 2.0.round)
+ assert_equal(2, 2.0.truncate)
+
+ assert_equal(-2, (-1.5).floor)
+ assert_equal(-1, (-1.5).ceil)
+ assert_equal(-2, (-1.5).round)
+ assert_equal(-1, (-1.5).truncate)
+
+ assert_equal(-2, (-2.0).floor)
+ assert_equal(-2, (-2.0).ceil)
+ assert_equal(-2, (-2.0).round)
+ assert_equal(-2, (-2.0).truncate)
+
+ inf = Float::INFINITY
+ assert_raise(FloatDomainError) { inf.floor }
+ assert_raise(FloatDomainError) { inf.ceil }
+ assert_raise(FloatDomainError) { inf.round }
+ assert_raise(FloatDomainError) { inf.truncate }
+
+ assert_equal(1.100, 1.111.round(1))
+ assert_equal(1.110, 1.111.round(2))
+ assert_equal(11110.0, 11111.1.round(-1))
+ assert_equal(11100.0, 11111.1.round(-2))
+ end
+
+ VS = [
+ 18446744073709551617.0,
+ 18446744073709551616.0,
+ 18446744073709551615.8,
+ 18446744073709551615.5,
+ 18446744073709551615.2,
+ 18446744073709551615.0,
+ 18446744073709551614.0,
+
+ 4611686018427387905.0,
+ 4611686018427387904.0,
+ 4611686018427387903.8,
+ 4611686018427387903.5,
+ 4611686018427387903.2,
+ 4611686018427387903.0,
+ 4611686018427387902.0,
+
+ 4294967297.0,
+ 4294967296.0,
+ 4294967295.8,
+ 4294967295.5,
+ 4294967295.2,
+ 4294967295.0,
+ 4294967294.0,
+
+ 1073741825.0,
+ 1073741824.0,
+ 1073741823.8,
+ 1073741823.5,
+ 1073741823.2,
+ 1073741823.0,
+ 1073741822.0,
+
+ -1073741823.0,
+ -1073741824.0,
+ -1073741824.2,
+ -1073741824.5,
+ -1073741824.8,
+ -1073741825.0,
+ -1073741826.0,
+
+ -4294967295.0,
+ -4294967296.0,
+ -4294967296.2,
+ -4294967296.5,
+ -4294967296.8,
+ -4294967297.0,
+ -4294967298.0,
+
+ -4611686018427387903.0,
+ -4611686018427387904.0,
+ -4611686018427387904.2,
+ -4611686018427387904.5,
+ -4611686018427387904.8,
+ -4611686018427387905.0,
+ -4611686018427387906.0,
+
+ -18446744073709551615.0,
+ -18446744073709551616.0,
+ -18446744073709551616.2,
+ -18446744073709551616.5,
+ -18446744073709551616.8,
+ -18446744073709551617.0,
+ -18446744073709551618.0,
+ ]
+
+ def test_truncate
+ VS.each {|f|
+ i = f.truncate
+ assert_equal(i, f.to_i)
+ if f < 0
+ assert_operator(i, :<, 0)
+ else
+ assert_operator(i, :>, 0)
+ end
+ assert_operator(i.abs, :<=, f.abs)
+ d = f.abs - i.abs
+ assert_operator(0, :<=, d)
+ assert_operator(d, :<, 1)
+ }
+ end
+
+ def test_ceil
+ VS.each {|f|
+ i = f.ceil
+ if f < 0
+ assert_operator(i, :<, 0)
+ else
+ assert_operator(i, :>, 0)
+ end
+ assert_operator(i, :>=, f)
+ d = f - i
+ assert_operator(-1, :<, d)
+ assert_operator(d, :<=, 0)
+ }
+ end
+
+ def test_floor
+ VS.each {|f|
+ i = f.floor
+ if f < 0
+ assert_operator(i, :<, 0)
+ else
+ assert_operator(i, :>, 0)
+ end
+ assert_operator(i, :<=, f)
+ d = f - i
+ assert_operator(0, :<=, d)
+ assert_operator(d, :<, 1)
+ }
+ end
+
+ def test_round
+ VS.each {|f|
+ i = f.round
+ if f < 0
+ assert_operator(i, :<, 0)
+ else
+ assert_operator(i, :>, 0)
+ end
+ d = f - i
+ assert_operator(-0.5, :<=, d)
+ assert_operator(d, :<=, 0.5)
+ }
+ end
+
+ def test_Float
+ assert_in_delta(0.125, Float("0.1_2_5"), 0.00001)
+ assert_in_delta(0.125, "0.1_2_5__".to_f, 0.00001)
+ assert_equal(1, Float(([1] * 10000).join).infinite?)
+ assert(!Float(([1] * 10000).join("_")).infinite?) # is it really OK?
+ assert_raise(ArgumentError) { Float("1.0\x001") }
+ assert_equal(1, Float("1e10_00").infinite?)
+ assert_raise(TypeError) { Float(nil) }
+ o = Object.new
+ def o.to_f; inf = Float::INFINITY; inf/inf; end
+ assert(Float(o).nan?)
+ end
+
+ def test_num2dbl
+ assert_raise(TypeError) do
+ 1.0.step(2.0, "0.5") {}
+ end
+ assert_raise(TypeError) do
+ 1.0.step(2.0, nil) {}
+ end
+ end
+
+ def test_sleep_with_Float
+ assert_nothing_raised("[ruby-core:23282]") do
+ sleep(0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_fnmatch.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_fnmatch.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_fnmatch.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,106 @@
+require 'test/unit'
+
+class TestFnmatch < Test::Unit::TestCase
+
+ def bracket_test(s, t) # `s' should start with neither '!' nor '^'
+ 0x21.upto(0x7E) do |i|
+ assert_equal(t.include?(i.chr), File.fnmatch("[#{s}]", i.chr, File::FNM_DOTMATCH))
+ assert_equal(t.include?(i.chr), !File.fnmatch("[^#{s}]", i.chr, File::FNM_DOTMATCH))
+ assert_equal(t.include?(i.chr), !File.fnmatch("[!#{s}]", i.chr, File::FNM_DOTMATCH))
+ end
+ end
+ def test_fnmatch
+ assert(File.fnmatch('\[1\]' , '[1]'), "[ruby-dev:22819]")
+ assert(File.fnmatch('*?', 'a'), "[ruby-dev:22815]")
+ assert(File.fnmatch('*/', 'a/'))
+ assert(File.fnmatch('\[1\]' , '[1]', File::FNM_PATHNAME))
+ assert(File.fnmatch('*?', 'a', File::FNM_PATHNAME))
+ assert(File.fnmatch('*/', 'a/', File::FNM_PATHNAME))
+ # text
+ assert(File.fnmatch('cat', 'cat'))
+ assert(!File.fnmatch('cat', 'category'))
+ assert(!File.fnmatch('cat', 'wildcat'))
+ # '?' matches any one character
+ assert(File.fnmatch('?at', 'cat'))
+ assert(File.fnmatch('c?t', 'cat'))
+ assert(File.fnmatch('ca?', 'cat'))
+ assert(File.fnmatch('?a?', 'cat'))
+ assert(!File.fnmatch('c??t', 'cat'))
+ assert(!File.fnmatch('??at', 'cat'))
+ assert(!File.fnmatch('ca??', 'cat'))
+ # '*' matches any number (including 0) of any characters
+ assert(File.fnmatch('c*', 'cats'))
+ assert(File.fnmatch('c*ts', 'cats'))
+ assert(File.fnmatch('*ts', 'cats'))
+ assert(File.fnmatch('*c*a*t*s*', 'cats'))
+ assert(!File.fnmatch('c*t', 'cats'))
+ assert(!File.fnmatch('*abc', 'abcabz'))
+ assert(File.fnmatch('*abz', 'abcabz'))
+ assert(!File.fnmatch('a*abc', 'abc'))
+ assert(File.fnmatch('a*bc', 'abc'))
+ assert(!File.fnmatch('a*bc', 'abcd'))
+ # [seq] : matches any character listed between bracket
+ # [!seq] or [^seq] : matches any character except those listed between bracket
+ bracket_test("bd-gikl-mosv-x", "bdefgiklmosvwx")
+ # escaping character
+ assert(File.fnmatch('\?', '?'))
+ assert(!File.fnmatch('\?', '\?'))
+ assert(!File.fnmatch('\?', 'a'))
+ assert(!File.fnmatch('\?', '\a'))
+ assert(File.fnmatch('\*', '*'))
+ assert(!File.fnmatch('\*', '\*'))
+ assert(!File.fnmatch('\*', 'cats'))
+ assert(!File.fnmatch('\*', '\cats'))
+ assert(File.fnmatch('\a', 'a'))
+ assert(!File.fnmatch('\a', '\a'))
+ assert(File.fnmatch('[a\-c]', 'a'))
+ assert(File.fnmatch('[a\-c]', '-'))
+ assert(File.fnmatch('[a\-c]', 'c'))
+ assert(!File.fnmatch('[a\-c]', 'b'))
+ assert(!File.fnmatch('[a\-c]', '\\'))
+ # escaping character loses its meaning if FNM_NOESCAPE is set
+ assert(!File.fnmatch('\?', '?', File::FNM_NOESCAPE))
+ assert(File.fnmatch('\?', '\?', File::FNM_NOESCAPE))
+ assert(!File.fnmatch('\?', 'a', File::FNM_NOESCAPE))
+ assert(File.fnmatch('\?', '\a', File::FNM_NOESCAPE))
+ assert(!File.fnmatch('\*', '*', File::FNM_NOESCAPE))
+ assert(File.fnmatch('\*', '\*', File::FNM_NOESCAPE))
+ assert(!File.fnmatch('\*', 'cats', File::FNM_NOESCAPE))
+ assert(File.fnmatch('\*', '\cats', File::FNM_NOESCAPE))
+ assert(!File.fnmatch('\a', 'a', File::FNM_NOESCAPE))
+ assert(File.fnmatch('\a', '\a', File::FNM_NOESCAPE))
+ assert(File.fnmatch('[a\-c]', 'a', File::FNM_NOESCAPE))
+ assert(!File.fnmatch('[a\-c]', '-', File::FNM_NOESCAPE))
+ assert(File.fnmatch('[a\-c]', 'c', File::FNM_NOESCAPE))
+ assert(File.fnmatch('[a\-c]', 'b', File::FNM_NOESCAPE)) # '\\' < 'b' < 'c'
+ assert(File.fnmatch('[a\-c]', '\\', File::FNM_NOESCAPE))
+ # case is ignored if FNM_CASEFOLD is set
+ assert(!File.fnmatch('cat', 'CAT'))
+ assert(File.fnmatch('cat', 'CAT', File::FNM_CASEFOLD))
+ assert(!File.fnmatch('[a-z]', 'D'))
+ assert(File.fnmatch('[a-z]', 'D', File::FNM_CASEFOLD))
+ assert(!File.fnmatch('[abc]', 'B'))
+ assert(File.fnmatch('[abc]', 'B', File::FNM_CASEFOLD))
+ # wildcard doesn't match '/' if FNM_PATHNAME is set
+ assert(File.fnmatch('foo?boo', 'foo/boo'))
+ assert(File.fnmatch('foo*', 'foo/boo'))
+ assert(!File.fnmatch('foo?boo', 'foo/boo', File::FNM_PATHNAME))
+ assert(!File.fnmatch('foo*', 'foo/boo', File::FNM_PATHNAME))
+ # wildcard matches leading period if FNM_DOTMATCH is set
+ assert(!File.fnmatch('*', '.profile'))
+ assert(File.fnmatch('*', '.profile', File::FNM_DOTMATCH))
+ assert(File.fnmatch('.*', '.profile'))
+ assert(File.fnmatch('*', 'dave/.profile'))
+ assert(File.fnmatch('*/*', 'dave/.profile'))
+ assert(!File.fnmatch('*/*', 'dave/.profile', File::FNM_PATHNAME))
+ assert(File.fnmatch('*/*', 'dave/.profile', File::FNM_PATHNAME | File::FNM_DOTMATCH))
+ # recursive matching
+ assert(File.fnmatch('**/foo', 'a/b/c/foo', File::FNM_PATHNAME))
+ assert(File.fnmatch('**/foo', '/foo', File::FNM_PATHNAME))
+ assert(!File.fnmatch('**/foo', 'a/.b/c/foo', File::FNM_PATHNAME))
+ assert(File.fnmatch('**/foo', 'a/.b/c/foo', File::FNM_PATHNAME | File::FNM_DOTMATCH))
+ assert(File.fnmatch('**/foo', '/root/foo', File::FNM_PATHNAME))
+ assert(File.fnmatch('**/foo', 'c:/root/foo', File::FNM_PATHNAME))
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_gc.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_gc.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_gc.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,54 @@
+require 'test/unit'
+
+class TestGc < Test::Unit::TestCase
+ class S
+ def initialize(a)
+ @a = a
+ end
+ end
+
+ def test_gc
+ prev_stress = GC.stress
+ GC.stress = false
+
+ assert_nothing_raised do
+ 1.upto(10000) {
+ tmp = [0,1,2,3,4,5,6,7,8,9]
+ }
+ tmp = nil
+ end
+ l=nil
+ 100000.times {
+ l = S.new(l)
+ }
+ GC.start
+ assert true # reach here or dumps core
+ l = []
+ 100000.times {
+ l.push([l])
+ }
+ GC.start
+ assert true # reach here or dumps core
+
+ GC.stress = prev_stress
+ end
+
+ def test_enable_disable
+ GC.enable
+ assert_equal(false, GC.enable)
+ assert_equal(false, GC.disable)
+ assert_equal(true, GC.disable)
+ assert_equal(true, GC.disable)
+ assert_nil(GC.start)
+ assert_equal(true, GC.enable)
+ assert_equal(false, GC.enable)
+ ensure
+ GC.enable
+ end
+
+ def test_count
+ c = GC.count
+ GC.start
+ assert_operator(c, :<, GC.count)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_hash.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_hash.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_hash.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,917 @@
+require 'test/unit'
+#require 'continuation'
+
+class TestHash < Test::Unit::TestCase
+
+ def test_hash
+ x = {1=>2, 2=>4, 3=>6}
+ y = {1=>2, 2=>4, 3=>6} # y = {1, 2, 2, 4, 3, 6} # 1.9 doesn't support
+
+ assert_equal(2, x[1])
+
+ assert(begin
+ for k,v in y
+ raise if k*2 != v
+ end
+ true
+ rescue
+ false
+ end)
+
+ assert_equal(3, x.length)
+ assert(x.has_key?(1))
+ assert(x.has_value?(4))
+ assert_equal([4,6], x.values_at(2,3))
+ assert_equal({1=>2, 2=>4, 3=>6}, x)
+
+ z = y.keys.join(":")
+ assert_equal("1:2:3", z)
+
+ z = y.values.join(":")
+ assert_equal("2:4:6", z)
+ assert_equal(x, y)
+
+ y.shift
+ assert_equal(2, y.length)
+
+ z = [1,2]
+ y[z] = 256
+ assert_equal(256, y[z])
+
+ x = Hash.new(0)
+ x[1] = 1
+ assert_equal(1, x[1])
+ assert_equal(0, x[2])
+
+ x = Hash.new([])
+ assert_equal([], x[22])
+ assert_same(x[22], x[22])
+
+ x = Hash.new{[]}
+ assert_equal([], x[22])
+ assert_not_same(x[22], x[22])
+
+ x = Hash.new{|h,kk| z = kk; h[kk] = kk*2}
+ z = 0
+ assert_equal(44, x[22])
+ assert_equal(22, z)
+ z = 0
+ assert_equal(44, x[22])
+ assert_equal(0, z)
+ x.default = 5
+ assert_equal(5, x[23])
+
+ x = Hash.new
+ def x.default(k)
+ $z = k
+ self[k] = k*2
+ end
+ $z = 0
+ assert_equal(44, x[22])
+ assert_equal(22, $z)
+ $z = 0
+ assert_equal(44, x[22])
+ assert_equal(0, $z)
+ end
+
+ # From rubicon
+
+ def setup
+ @cls = Hash
+ @h = @cls[
+ 1 => 'one', 2 => 'two', 3 => 'three',
+ self => 'self', true => 'true', nil => 'nil',
+ 'nil' => nil
+ ]
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_s_AREF
+ h = @cls["a" => 100, "b" => 200]
+ assert_equal(100, h['a'])
+ assert_equal(200, h['b'])
+ assert_nil(h['c'])
+
+ h = @cls.[]("a" => 100, "b" => 200)
+ assert_equal(100, h['a'])
+ assert_equal(200, h['b'])
+ assert_nil(h['c'])
+ end
+
+ def test_s_new
+ h = @cls.new
+ assert_instance_of(@cls, h)
+ assert_nil(h.default)
+ assert_nil(h['spurious'])
+
+ h = @cls.new('default')
+ assert_instance_of(@cls, h)
+ assert_equal('default', h.default)
+ assert_equal('default', h['spurious'])
+
+ end
+
+ def test_AREF # '[]'
+ t = Time.now
+ h = @cls[
+ 1 => 'one', 2 => 'two', 3 => 'three',
+ self => 'self', t => 'time', nil => 'nil',
+ 'nil' => nil
+ ]
+
+ assert_equal('one', h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal('nil', h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+
+ h1 = h.dup
+ h1.default = :default
+
+ assert_equal('one', h1[1])
+ assert_equal('two', h1[2])
+ assert_equal('three', h1[3])
+ assert_equal('self', h1[self])
+ assert_equal('time', h1[t])
+ assert_equal('nil', h1[nil])
+ assert_equal(nil, h1['nil'])
+ assert_equal(:default, h1['koala'])
+
+
+ end
+
+ def test_ASET # '[]='
+ t = Time.now
+ h = @cls.new
+ h[1] = 'one'
+ h[2] = 'two'
+ h[3] = 'three'
+ h[self] = 'self'
+ h[t] = 'time'
+ h[nil] = 'nil'
+ h['nil'] = nil
+ assert_equal('one', h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal('nil', h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+
+ h[1] = 1
+ h[nil] = 99
+ h['nil'] = nil
+ z = [1,2]
+ h[z] = 256
+ assert_equal(1, h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal(99, h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+ assert_equal(256, h[z])
+ end
+
+ def test_EQUAL # '=='
+ h1 = @cls[ "a" => 1, "c" => 2 ]
+ h2 = @cls[ "a" => 1, "c" => 2, 7 => 35 ]
+ h3 = @cls[ "a" => 1, "c" => 2, 7 => 35 ]
+ h4 = @cls[ ]
+ assert(h1 == h1)
+ assert(h2 == h2)
+ assert(h3 == h3)
+ assert(h4 == h4)
+ assert(!(h1 == h2))
+ assert(h2 == h3)
+ assert(!(h3 == h4))
+ end
+
+ def test_clear
+ assert(@h.size > 0)
+ @h.clear
+ assert_equal(0, @h.size)
+ assert_nil(@h[1])
+ end
+
+ def test_clone
+ for taint in [ false, true ]
+ for untrust in [ false, true ]
+ for frozen in [ false, true ]
+ a = @h.clone
+ a.taint if taint
+ a.untrust if untrust
+ a.freeze if frozen
+ b = a.clone
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert_equal(a.frozen?, b.frozen?)
+ assert_equal(a.untrusted?, b.untrusted?)
+ assert_equal(a.tainted?, b.tainted?)
+ end
+ end
+ end
+ end
+
+ def test_default
+ assert_nil(@h.default)
+ h = @cls.new(:xyzzy)
+ assert_equal(:xyzzy, h.default)
+ end
+
+ def test_default=
+ assert_nil(@h.default)
+ @h.default = :xyzzy
+ assert_equal(:xyzzy, @h.default)
+ end
+
+ def test_delete
+ h1 = @cls[ 1 => 'one', 2 => 'two', true => 'true' ]
+ h2 = @cls[ 1 => 'one', 2 => 'two' ]
+ h3 = @cls[ 2 => 'two' ]
+
+ assert_equal('true', h1.delete(true))
+ assert_equal(h2, h1)
+
+ assert_equal('one', h1.delete(1))
+ assert_equal(h3, h1)
+
+ assert_equal('two', h1.delete(2))
+ assert_equal(@cls[], h1)
+
+ assert_nil(h1.delete(99))
+ assert_equal(@cls[], h1)
+
+ assert_equal('default 99', h1.delete(99) {|i| "default #{i}" })
+ end
+
+ def test_delete_if
+ skip("[BUG : #793] wontfix : Iterator is executed more when calls Hash#shift in Hash's Iterator.")
+
+ base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]
+ h1 = @cls[ 1 => 'one', 2 => false, true => 'true' ]
+ h2 = @cls[ 2 => false, 'cat' => 99 ]
+ h3 = @cls[ 2 => false ]
+
+ h = base.dup
+ assert_equal(h, h.delete_if { false })
+ assert_equal(@cls[], h.delete_if { true })
+
+ h = base.dup
+ assert_equal(h1, h.delete_if {|k,v| k.instance_of?(String) })
+ assert_equal(h1, h)
+
+ h = base.dup
+ assert_equal(h2, h.delete_if {|k,v| v.instance_of?(String) })
+ assert_equal(h2, h)
+
+ h = base.dup
+ assert_equal(h3, h.delete_if {|k,v| v })
+ assert_equal(h3, h)
+
+ h = base.dup
+ n = 0
+ h.delete_if {|*a|
+ n += 1
+ assert_equal(2, a.size)
+ assert_equal(base[a[0]], a[1])
+ h.shift
+ true
+ }
+ assert_equal(base.size, n)
+ end
+
+ def test_keep_if
+ h = {1=>2,3=>4,5=>6}
+ assert_equal({3=>4,5=>6}, h.keep_if {|k, v| k + v >= 7 })
+ h = {1=>2,3=>4,5=>6}
+ assert_equal({1=>2,3=>4,5=>6}, h.keep_if{true})
+ end
+
+ def test_dup
+ for taint in [ false, true ]
+ for untrust in [ false, true ]
+ for frozen in [ false, true ]
+ a = @h.dup
+ a.taint if taint
+ a.freeze if frozen
+ b = a.dup
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert_equal(false, b.frozen?)
+ assert_equal(a.tainted?, b.tainted?)
+ assert_equal(a.untrusted?, b.untrusted?)
+ end
+ end
+ end
+ end
+
+ def test_each
+ skip("[BUG : #792] wontfix : Hash#delete while iterating is broken.")
+
+ count = 0
+ @cls[].each { |k, v| count + 1 }
+ assert_equal(0, count)
+
+ h = @h
+ h.each do |k, v|
+ assert_equal(v, h.delete(k))
+ end
+ assert_equal(@cls[], h)
+ end
+
+ def test_each_key
+ skip("[BUG : #792] wontfix : Hash#delete while iterating is broken.")
+
+ count = 0
+ @cls[].each_key { |k| count + 1 }
+ assert_equal(0, count)
+
+ h = @h
+ h.each_key do |k|
+ h.delete(k)
+ end
+ assert_equal(@cls[], h)
+ end
+
+ def test_each_pair
+ skip("[BUG : #792] wontfix : Hash#delete while iterating is broken.")
+
+ count = 0
+ @cls[].each_pair { |k, v| count + 1 }
+ assert_equal(0, count)
+
+ h = @h
+ h.each_pair do |k, v|
+ assert_equal(v, h.delete(k))
+ end
+ assert_equal(@cls[], h)
+ end
+
+ def test_each_value
+ res = []
+ @cls[].each_value { |v| res << v }
+ assert_equal(0, [].length)
+
+ @h.each_value { |v| res << v }
+ assert_equal(0, [].length)
+
+ expected = []
+ @h.each { |k, v| expected << v }
+
+ assert_equal([], expected - res)
+ assert_equal([], res - expected)
+ end
+
+ def test_empty?
+ assert(@cls[].empty?)
+ assert(!@h.empty?)
+ end
+
+ def test_fetch
+ assert_raise(KeyError) { @cls[].fetch(1) }
+ assert_raise(KeyError) { @h.fetch('gumby') }
+ assert_equal('gumbygumby', @h.fetch('gumby') {|k| k * 2 })
+ assert_equal('pokey', @h.fetch('gumby', 'pokey'))
+
+ assert_equal('one', @h.fetch(1))
+ assert_equal(nil, @h.fetch('nil'))
+ assert_equal('nil', @h.fetch(nil))
+ end
+
+ def test_key2?
+ assert(!@cls[].key?(1))
+ assert(!@cls[].key?(nil))
+ assert(@h.key?(nil))
+ assert(@h.key?(1))
+ assert(!@h.key?('gumby'))
+ end
+
+ def test_value?
+ assert(!@cls[].value?(1))
+ assert(!@cls[].value?(nil))
+ assert(@h.value?('one'))
+ assert(@h.value?(nil))
+ assert(!@h.value?('gumby'))
+ end
+
+ def test_include?
+ assert(!@cls[].include?(1))
+ assert(!@cls[].include?(nil))
+ assert(@h.include?(nil))
+ assert(@h.include?(1))
+ assert(!@h.include?('gumby'))
+ end
+
+ def test_key
+ assert_equal(1, @h.key('one'))
+ assert_equal(nil, @h.key('nil'))
+ assert_equal('nil', @h.key(nil))
+
+ assert_equal(nil, @h.key('gumby'))
+ assert_equal(nil, @cls[].key('gumby'))
+ end
+
+ def test_values_at
+ res = @h.values_at('dog', 'cat', 'horse')
+ assert(res.length == 3)
+ assert_equal([nil, nil, nil], res)
+
+ res = @h.values_at
+ assert(res.length == 0)
+
+ res = @h.values_at(3, 2, 1, nil)
+ assert_equal 4, res.length
+ assert_equal %w( three two one nil ), res
+
+ res = @h.values_at(3, 99, 1, nil)
+ assert_equal 4, res.length
+ assert_equal ['three', nil, 'one', 'nil'], res
+ end
+
+
+ def test_invert
+ h = @h.invert
+ assert_equal(1, h['one'])
+ assert_equal(true, h['true'])
+ assert_equal(nil, h['nil'])
+
+ h.each do |k, v|
+ assert(@h.key?(v)) # not true in general, but works here
+ end
+
+ h = @cls[ 'a' => 1, 'b' => 2, 'c' => 1].invert
+ assert_equal(2, h.length)
+ assert(h[1] == 'a' || h[1] == 'c')
+ assert_equal('b', h[2])
+ end
+
+ def test_key?
+ assert(!@cls[].key?(1))
+ assert(!@cls[].key?(nil))
+ assert(@h.key?(nil))
+ assert(@h.key?(1))
+ assert(!@h.key?('gumby'))
+ end
+
+ def test_keys
+ assert_equal([], @cls[].keys)
+
+ keys = @h.keys
+ expected = []
+ @h.each { |k, v| expected << k }
+ assert_equal([], keys - expected)
+ assert_equal([], expected - keys)
+ end
+
+ def test_length
+ assert_equal(0, @cls[].length)
+ assert_equal(7, @h.length)
+ end
+
+ def test_member?
+ assert(!@cls[].member?(1))
+ assert(!@cls[].member?(nil))
+ assert(@h.member?(nil))
+ assert(@h.member?(1))
+ assert(!@h.member?('gumby'))
+ end
+
+ def test_rehash
+ a = [ "a", "b" ]
+ c = [ "c", "d" ]
+ h = @cls[ a => 100, c => 300 ]
+ assert_equal(100, h[a])
+ a[0] = "z"
+ assert_nil(h[a])
+ h.rehash
+ assert_equal(100, h[a])
+ end
+
+ def test_reject
+ base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]
+ h1 = @cls[ 1 => 'one', 2 => false, true => 'true' ]
+ h2 = @cls[ 2 => false, 'cat' => 99 ]
+ h3 = @cls[ 2 => false ]
+
+ h = base.dup
+ assert_equal(h, h.reject { false })
+ assert_equal(@cls[], h.reject { true })
+
+ h = base.dup
+ assert_equal(h1, h.reject {|k,v| k.instance_of?(String) })
+
+ assert_equal(h2, h.reject {|k,v| v.instance_of?(String) })
+
+ assert_equal(h3, h.reject {|k,v| v })
+ assert_equal(base, h)
+ end
+
+ def test_reject!
+ base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]
+ h1 = @cls[ 1 => 'one', 2 => false, true => 'true' ]
+ h2 = @cls[ 2 => false, 'cat' => 99 ]
+ h3 = @cls[ 2 => false ]
+
+ h = base.dup
+ assert_equal(nil, h.reject! { false })
+ assert_equal(@cls[], h.reject! { true })
+
+ h = base.dup
+ assert_equal(h1, h.reject! {|k,v| k.instance_of?(String) })
+ assert_equal(h1, h)
+
+ h = base.dup
+ assert_equal(h2, h.reject! {|k,v| v.instance_of?(String) })
+ assert_equal(h2, h)
+
+ h = base.dup
+ assert_equal(h3, h.reject! {|k,v| v })
+ assert_equal(h3, h)
+ end
+
+ def test_replace
+ h = @cls[ 1 => 2, 3 => 4 ]
+ h1 = h.replace(@cls[ 9 => 8, 7 => 6 ])
+ assert_equal(h, h1)
+ assert_equal(8, h[9])
+ assert_equal(6, h[7])
+ assert_nil(h[1])
+ assert_nil(h[2])
+ end
+
+ def test_shift
+ h = @h.dup
+
+ @h.length.times {
+ k, v = h.shift
+ assert(@h.key?(k))
+ assert_equal(@h[k], v)
+ }
+
+ assert_equal(0, h.length)
+ end
+
+ def test_size
+ assert_equal(0, @cls[].length)
+ assert_equal(7, @h.length)
+ end
+
+ def test_sort
+ h = @cls[].sort
+ assert_equal([], h)
+
+ h = @cls[ 1 => 1, 2 => 1 ].sort
+ assert_equal([[1,1], [2,1]], h)
+
+ h = @cls[ 'cat' => 'feline', 'ass' => 'asinine', 'bee' => 'beeline' ]
+ h1 = h.sort
+ assert_equal([ %w(ass asinine), %w(bee beeline), %w(cat feline)], h1)
+ end
+
+ def test_store
+ t = Time.now
+ h = @cls.new
+ h.store(1, 'one')
+ h.store(2, 'two')
+ h.store(3, 'three')
+ h.store(self, 'self')
+ h.store(t, 'time')
+ h.store(nil, 'nil')
+ h.store('nil', nil)
+ assert_equal('one', h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal('nil', h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+
+ h.store(1, 1)
+ h.store(nil, 99)
+ h.store('nil', nil)
+ assert_equal(1, h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal(99, h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+ end
+
+ def test_to_a
+ assert_equal([], @cls[].to_a)
+ assert_equal([[1,2]], @cls[ 1=>2 ].to_a)
+ a = @cls[ 1=>2, 3=>4, 5=>6 ].to_a
+ assert_equal([1,2], a.delete([1,2]))
+ assert_equal([3,4], a.delete([3,4]))
+ assert_equal([5,6], a.delete([5,6]))
+ assert_equal(0, a.length)
+
+ h = @cls[ 1=>2, 3=>4, 5=>6 ]
+ h.taint
+ h.untrust
+ a = h.to_a
+ assert_equal(true, a.tainted?)
+ assert_equal(true, a.untrusted?)
+ end
+
+ def test_to_hash
+ h = @h.to_hash
+ assert_equal(@h, h)
+ end
+
+ def test_to_s
+ h = @cls[ 1 => 2, "cat" => "dog", 1.5 => :fred ]
+ assert_equal(h.inspect, h.to_s)
+ $, = ":"
+ assert_equal(h.inspect, h.to_s)
+ h = @cls[]
+ assert_equal(h.inspect, h.to_s)
+ ensure
+ $, = nil
+ end
+
+ def test_update
+ h1 = @cls[ 1 => 2, 2 => 3, 3 => 4 ]
+ h2 = @cls[ 2 => 'two', 4 => 'four' ]
+
+ ha = @cls[ 1 => 2, 2 => 'two', 3 => 4, 4 => 'four' ]
+ hb = @cls[ 1 => 2, 2 => 3, 3 => 4, 4 => 'four' ]
+
+ assert_equal(ha, h1.update(h2))
+ assert_equal(ha, h1)
+
+ h1 = @cls[ 1 => 2, 2 => 3, 3 => 4 ]
+ h2 = @cls[ 2 => 'two', 4 => 'four' ]
+
+ assert_equal(hb, h2.update(h1))
+ assert_equal(hb, h2)
+ end
+
+ def test_value2?
+ assert(!@cls[].value?(1))
+ assert(!@cls[].value?(nil))
+ assert(@h.value?(nil))
+ assert(@h.value?('one'))
+ assert(!@h.value?('gumby'))
+ end
+
+ def test_values
+ assert_equal([], @cls[].values)
+
+ vals = @h.values
+ expected = []
+ @h.each { |k, v| expected << v }
+ assert_equal([], vals - expected)
+ assert_equal([], expected - vals)
+ end
+
+ def test_security_check
+ h = {}
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ h[1] = 1
+ end.join
+ end
+ end
+
+ def test_intialize_wrong_arguments
+ assert_raise(ArgumentError) do
+ Hash.new(0) { }
+ end
+ end
+
+ def test_create
+ assert_equal({1=>2, 3=>4}, Hash[[[1,2],[3,4]]])
+ assert_raise(ArgumentError) { Hash[0, 1, 2] }
+ assert_equal({1=>2, 3=>4}, Hash[1,2,3,4])
+ o = Object.new
+ def o.to_hash() {1=>2} end
+ assert_equal({1=>2}, Hash[o], "[ruby-dev:34555]")
+ end
+
+ def test_rehash2
+ h = {1 => 2, 3 => 4}
+ assert_equal(h.dup, h.rehash)
+ assert_raise(RuntimeError) { h.each { h.rehash } }
+ assert_equal({}, {}.rehash)
+ end
+
+ def test_fetch2
+ assert_equal(:bar, @h.fetch(0, :foo) { :bar })
+ end
+
+ def test_default_proc
+ h = Hash.new {|hh, k| hh + k + "baz" }
+ assert_equal("foobarbaz", h.default_proc.call("foo", "bar"))
+ h = {}
+ assert_nil(h.default_proc)
+ end
+
+ def test_shift2
+ skip("[BUG : #793] wontfix : Iterator is executed more when calls Hash#shift in Hash's Iterator.")
+
+ h = Hash.new {|hh, k| :foo }
+ h[1] = 2
+ assert_equal([1, 2], h.shift)
+ assert_equal(:foo, h.shift)
+ assert_equal(:foo, h.shift)
+
+ h = Hash.new(:foo)
+ h[1] = 2
+ assert_equal([1, 2], h.shift)
+ assert_equal(:foo, h.shift)
+ assert_equal(:foo, h.shift)
+
+ h = {1=>2}
+ h.each { assert_equal([1, 2], h.shift) }
+ end
+
+ def test_reject_bang2
+ assert_equal({1=>2}, {1=>2,3=>4}.reject! {|k, v| k + v == 7 })
+ assert_nil({1=>2,3=>4}.reject! {|k, v| k == 5 })
+ assert_nil({}.reject! { })
+ end
+
+ def test_select
+ assert_equal({3=>4,5=>6}, {1=>2,3=>4,5=>6}.select {|k, v| k + v >= 7 })
+ end
+
+ def test_select!
+ h = {1=>2,3=>4,5=>6}
+ assert_equal(h, h.select! {|k, v| k + v >= 7 })
+ assert_equal({3=>4,5=>6}, h)
+ h = {1=>2,3=>4,5=>6}
+ assert_equal(nil, h.select!{true})
+ end
+
+ def test_clear2
+ assert_equal({}, {1=>2,3=>4,5=>6}.clear)
+ h = {1=>2,3=>4,5=>6}
+ h.each { h.clear }
+ assert_equal({}, h)
+ end
+
+ def test_replace2
+ h1 = Hash.new { :foo }
+ h2 = {}
+ h2.replace h1
+ assert_equal(:foo, h2[0])
+
+ assert_raise(ArgumentError) { h2.replace() }
+ assert_raise(TypeError) { h2.replace(1) }
+ h2.freeze
+ assert_raise(ArgumentError) { h2.replace() }
+ assert_raise(RuntimeError) { h2.replace(h1) }
+ assert_raise(RuntimeError) { h2.replace(42) }
+ end
+
+ def test_size2
+ assert_equal(0, {}.size)
+ end
+
+ def test_equal2
+ assert({} != 0)
+ o = Object.new
+ def o.to_hash; {}; end
+ def o.==(x); true; end
+ assert({} == o)
+ def o.==(x); false; end
+ assert({} != o)
+
+ h1 = {1=>2}; h2 = {3=>4}
+ assert(h1 != h2)
+ h1 = {1=>2}; h2 = {1=>4}
+ assert(h1 != h2)
+ end
+
+ def test_eql
+ assert(!({}.eql?(0)))
+ o = Object.new
+ def o.to_hash; {}; end
+ def o.eql?(x); true; end
+ assert({}.eql?(o))
+ def o.eql?(x); false; end
+ assert(!({}.eql?(o)))
+ end
+
+ def test_hash2
+ assert_kind_of(Integer, {}.hash)
+ end
+
+ def test_update2
+ h1 = {1=>2, 3=>4}
+ h2 = {1=>3, 5=>7}
+ h1.update(h2) {|k, v1, v2| k + v1 + v2 }
+ assert_equal({1=>6, 3=>4, 5=>7}, h1)
+ end
+
+ def test_merge
+ h1 = {1=>2, 3=>4}
+ h2 = {1=>3, 5=>7}
+ assert_equal({1=>3, 3=>4, 5=>7}, h1.merge(h2))
+ assert_equal({1=>6, 3=>4, 5=>7}, h1.merge(h2) {|k, v1, v2| k + v1 + v2 })
+ end
+
+ def test_assoc
+ assert_equal([3,4], {1=>2, 3=>4, 5=>6}.assoc(3))
+ assert_nil({1=>2, 3=>4, 5=>6}.assoc(4))
+ end
+
+ def test_rassoc
+ assert_equal([3,4], {1=>2, 3=>4, 5=>6}.rassoc(4))
+ assert_nil({1=>2, 3=>4, 5=>6}.rassoc(3))
+ end
+
+ def test_flatten
+ assert_equal([[1], [2]], {[1] => [2]}.flatten)
+ end
+
+ def test_callcc
+ h = {1=>2}
+ c = nil
+ f = false
+ h.each { callcc {|c2| c = c2 } }
+ unless f
+ f = true
+ c.call
+ end
+ assert_raise(RuntimeError) { h.each { h.rehash } }
+
+ h = {1=>2}
+ c = nil
+ assert_raise(RuntimeError) do
+ h.each { callcc {|c2| c = c2 } }
+ h.clear
+ c.call
+ end
+ end
+
+ def test_compare_by_identity
+ a = "foo"
+ assert(!{}.compare_by_identity?)
+ h = { a => "bar" }
+ assert(!h.compare_by_identity?)
+ h.compare_by_identity
+ assert(h.compare_by_identity?)
+ #assert_equal("bar", h[a])
+ assert_nil(h["foo"])
+ end
+
+ class ObjWithHash
+ def initialize(value, hash)
+ @value = value
+ @hash = hash
+ end
+ attr_reader :value, :hash
+
+ def eql?(other)
+ @value == other.value
+ end
+ end
+
+ def test_hash_hash
+ assert_equal({0=>2,11=>1}.hash, {11=>1,0=>2}.hash)
+ o1 = ObjWithHash.new(0,1)
+ o2 = ObjWithHash.new(11,1)
+ assert_equal({o1=>1,o2=>2}.hash, {o2=>2,o1=>1}.hash)
+ end
+
+ def test_hash_bignum_hash
+ x = 2<<(32-3)-1
+ assert_equal({x=>1}.hash, {x=>1}.hash)
+ x = 2<<(64-3)-1
+ assert_equal({x=>1}.hash, {x=>1}.hash)
+
+ o = Object.new
+ def o.hash; 2<<100; end
+ assert_equal({x=>1}.hash, {x=>1}.hash)
+ end
+
+ def test_hash_poped
+ assert_nothing_raised { eval("a = 1; {a => a}; a") }
+ end
+
+ def test_recursive_key
+ h = {}
+ assert_nothing_raised { h[h] = :foo }
+ h.rehash
+ assert_equal(:foo, h[h])
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_ifunless.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_ifunless.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_ifunless.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,14 @@
+require 'test/unit'
+
+class TestIfunless < Test::Unit::TestCase
+ def test_if_unless
+ $x = 'test';
+ assert(if $x == $x then true else false end)
+ $bad = false
+ unless $x == $x
+ $bad = true
+ end
+ assert(!$bad)
+ assert(unless $x != $x then true else false end)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_integer.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_integer.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_integer.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,201 @@
+require 'test/unit'
+
+class TestInteger < Test::Unit::TestCase
+ BDSIZE = 0x4000000000000000.coerce(0)[0].size
+ def self.bdsize(x)
+ ((x + 1) / 8 + BDSIZE) / BDSIZE * BDSIZE
+ end
+ def bdsize(x)
+ self.class.bdsize(x)
+ end
+
+ def test_aref
+ # assert_equal(1, (1 << 0x40000000)[0x40000000], "[ruby-dev:31271]")
+ # assert_equal(0, (-1 << 0x40000001)[0x40000000], "[ruby-dev:31271]")
+ big_zero = 0x40000000.coerce(0)[0]
+ assert_equal(0, (-0x40000002)[big_zero], "[ruby-dev:31271]")
+ assert_equal(1, 0x400000001[big_zero], "[ruby-dev:31271]")
+ end
+
+ def test_pow
+ assert_not_equal(0, begin
+ 0**-1
+ rescue
+ nil
+ end, "[ruby-dev:32084] [ruby-dev:34547]")
+ end
+
+ def test_lshift
+ assert_equal(0, 1 << -0x40000000)
+ assert_equal(0, 1 << -0x40000001)
+ assert_equal(0, 1 << -0x80000000)
+ assert_equal(0, 1 << -0x80000001)
+ # assert_equal(bdsize(0x80000000), (1 << 0x80000000).size)
+ end
+
+ def test_rshift
+ # assert_equal(bdsize(0x40000001), (1 >> -0x40000001).size)
+ assert((1 >> 0x80000000).zero?)
+ assert((1 >> 0xffffffff).zero?)
+ assert((1 >> 0x100000000).zero?)
+ # assert_equal((1 << 0x40000000), (1 >> -0x40000000))
+ # assert_equal((1 << 0x40000001), (1 >> -0x40000001))
+ end
+
+ def test_Integer
+ assert_raise(ArgumentError) {Integer("0x-1")}
+ assert_raise(ArgumentError) {Integer("-0x-1")}
+ assert_raise(ArgumentError) {Integer("0x 123")}
+ assert_raise(ArgumentError) {Integer("0x 123")}
+ assert_raise(ArgumentError) {Integer("0x0x5")}
+ assert_raise(ArgumentError) {Integer("0x0x000000005")}
+ assert_nothing_raised(ArgumentError) {
+ assert_equal(1540841, "0x0x5".to_i(36))
+ }
+ assert_raise(ArgumentError) { Integer("--0") }
+ assert_raise(ArgumentError) { Integer("-+0") }
+ assert_raise(ArgumentError) { Integer("++1") }
+ assert_raise(ArgumentError) { Integer("") }
+ assert_raise(ArgumentError) { Integer("10 x") }
+ assert_raise(ArgumentError) { Integer("1__2") }
+ assert_raise(ArgumentError) { Integer("1z") }
+ assert_raise(ArgumentError) { Integer("46116860184273__87904") }
+ assert_raise(ArgumentError) { Integer("4611686018427387904_") }
+ assert_raise(ArgumentError) { Integer("4611686018427387904 :") }
+ assert_equal(0x4000000000000000, Integer("46_11_686_0184273_87904"))
+ assert_raise(ArgumentError) { Integer("\0") }
+ assert_nothing_raised(ArgumentError, "[ruby-core:13873]") {
+ assert_equal(0, Integer("0 "))
+ }
+ assert_nothing_raised(ArgumentError, "[ruby-core:14139]") {
+ assert_equal(0377, Integer("0_3_7_7"))
+ }
+ assert_raise(ArgumentError, "[ruby-core:14139]") {Integer("0__3_7_7")}
+ assert_equal(1234, Integer(1234))
+ assert_equal(1, Integer(1.234))
+
+ # base argument
+ assert_equal(1234, Integer("1234", 10))
+ assert_equal(668, Integer("1234", 8))
+ assert_equal(4660, Integer("1234", 16))
+ assert_equal(49360, Integer("1234", 36))
+ # decimal, not octal
+ assert_equal(1234, Integer("01234", 10))
+ assert_raise(ArgumentError) { Integer("0x123", 10) }
+ assert_raise(ArgumentError) { Integer(1234, 10) }
+ assert_raise(ArgumentError) { Integer(12.34, 10) }
+ assert_raise(ArgumentError) { Integer(Object.new, 1) }
+
+ assert_raise(ArgumentError) { Integer(1, 1, 1) }
+
+ assert_equal(2 ** 50, Integer(2.0 ** 50))
+ assert_raise(TypeError) { Integer(nil) }
+ end
+
+ def test_int_p
+ assert(!(1.0.integer?))
+ assert(1.integer?)
+ end
+
+ def test_odd_p_even_p
+ Fixnum.class_eval do
+ alias odd_bak odd?
+ alias even_bak even?
+ remove_method :odd?, :even?
+ end
+
+ assert(1.odd?)
+ assert(!(2.odd?))
+ assert(!(1.even?))
+ assert(2.even?)
+
+ ensure
+ Fixnum.class_eval do
+ alias odd? odd_bak
+ alias even? even_bak
+ remove_method :odd_bak, :even_bak
+ end
+ end
+
+ def test_succ
+ assert_equal(2, 1.send(:succ))
+
+ Fixnum.class_eval do
+ alias succ_bak succ
+ remove_method :succ
+ end
+
+ assert_equal(2, 1.succ)
+ assert_equal(4294967297, 4294967296.succ)
+
+ ensure
+ Fixnum.class_eval do
+ alias succ succ_bak
+ remove_method :succ_bak
+ end
+ end
+
+ def test_chr
+ assert_equal("a", "a".ord.chr)
+ assert_raise(RangeError) { (-1).chr }
+ assert_raise(RangeError) { 0x100.chr }
+ end
+
+ def test_upto
+ a = []
+ 1.upto(3) {|x| a << x }
+ assert_equal([1, 2, 3], a)
+
+ a = []
+ 1.upto(0) {|x| a << x }
+ assert_equal([], a)
+
+ y = 2**30 - 1
+ a = []
+ y.upto(y+2) {|x| a << x }
+ assert_equal([y, y+1, y+2], a)
+ end
+
+ def test_downto
+ a = []
+ -1.downto(-3) {|x| a << x }
+ assert_equal([-1, -2, -3], a)
+
+ a = []
+ 1.downto(2) {|x| a << x }
+ assert_equal([], a)
+
+ y = -(2**30)
+ a = []
+ y.downto(y-2) {|x| a << x }
+ assert_equal([y, y-1, y-2], a)
+ end
+
+ def test_times
+ (2**32).times do |i|
+ break if i == 2
+ end
+ end
+
+ def test_round
+ assert_equal(11111, 11111.round)
+ assert_equal(Fixnum, 11111.round.class)
+ assert_equal(11111, 11111.round(0))
+ assert_equal(Fixnum, 11111.round(0).class)
+
+ assert_equal(11111.0, 11111.round(1))
+ assert_equal(Float, 11111.round(1).class)
+ assert_equal(11111.0, 11111.round(2))
+ assert_equal(Float, 11111.round(2).class)
+
+ assert_equal(11110, 11111.round(-1))
+ assert_equal(Fixnum, 11111.round(-1).class)
+ assert_equal(11100, 11111.round(-2))
+ assert_equal(Fixnum, 11111.round(-2).class)
+
+ assert_equal(1111_1111_1111_1111_1111_1111_1111_1110, 1111_1111_1111_1111_1111_1111_1111_1111.round(-1))
+ assert_equal(Bignum, 1111_1111_1111_1111_1111_1111_1111_1111.round(-1).class)
+ assert_equal(-1111_1111_1111_1111_1111_1111_1111_1110, (-1111_1111_1111_1111_1111_1111_1111_1111).round(-1))
+ assert_equal(Bignum, (-1111_1111_1111_1111_1111_1111_1111_1111).round(-1).class)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_integer_comb.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_integer_comb.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_integer_comb.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,622 @@
+require 'test/unit'
+
+class TestIntegerComb < Test::Unit::TestCase
+ VS = [
+ -0x1000000000000000000000000000000000000000000000002,
+ -0x1000000000000000000000000000000000000000000000001,
+ -0x1000000000000000000000000000000000000000000000000,
+ -0xffffffffffffffffffffffffffffffffffffffffffffffff,
+ -0x1000000000000000000000002,
+ -0x1000000000000000000000001,
+ -0x1000000000000000000000000,
+ -0xffffffffffffffffffffffff,
+ -0x10000000000000002,
+ -0x10000000000000001,
+ -0x10000000000000000,
+ -0xffffffffffffffff,
+ -0x4000000000000002,
+ -0x4000000000000001,
+ -0x4000000000000000,
+ -0x3fffffffffffffff,
+ -0x100000002,
+ -0x100000001,
+ -0x100000000,
+ -0xffffffff,
+ -0xc717a08d, # 0xc717a08d * 0x524b2245 = 0x4000000000000001
+ -0x80000002,
+ -0x80000001,
+ -0x80000000,
+ -0x7fffffff,
+ -0x524b2245,
+ -0x40000002,
+ -0x40000001,
+ -0x40000000,
+ -0x3fffffff,
+ -0x10002,
+ -0x10001,
+ -0x10000,
+ -0xffff,
+ -0x8101, # 0x8101 * 0x7f01 = 0x40000001
+ -0x8002,
+ -0x8001,
+ -0x8000,
+ -0x7fff,
+ -0x7f01,
+ -65,
+ -64,
+ -63,
+ -62,
+ -33,
+ -32,
+ -31,
+ -30,
+ -3,
+ -2,
+ -1,
+ 0,
+ 1,
+ 2,
+ 3,
+ 30,
+ 31,
+ 32,
+ 33,
+ 62,
+ 63,
+ 64,
+ 65,
+ 0x7f01,
+ 0x7ffe,
+ 0x7fff,
+ 0x8000,
+ 0x8001,
+ 0x8101,
+ 0xfffe,
+ 0xffff,
+ 0x10000,
+ 0x10001,
+ 0x3ffffffe,
+ 0x3fffffff,
+ 0x40000000,
+ 0x40000001,
+ 0x524b2245,
+ 0x7ffffffe,
+ 0x7fffffff,
+ 0x80000000,
+ 0x80000001,
+ 0xc717a08d,
+ 0xfffffffe,
+ 0xffffffff,
+ 0x100000000,
+ 0x100000001,
+ 0x3ffffffffffffffe,
+ 0x3fffffffffffffff,
+ 0x4000000000000000,
+ 0x4000000000000001,
+ 0xfffffffffffffffe,
+ 0xffffffffffffffff,
+ 0x10000000000000000,
+ 0x10000000000000001,
+ 0xffffffffffffffffffffffff,
+ 0x1000000000000000000000000,
+ 0x1000000000000000000000001,
+ 0xffffffffffffffffffffffffffffffffffffffffffffffff,
+ 0x1000000000000000000000000000000000000000000000000,
+ 0x1000000000000000000000000000000000000000000000001
+ ]
+
+ #VS.map! {|v| 0x4000000000000000.coerce(v)[0] }
+
+ min = -1
+ min *= 2 while min.class == Fixnum
+ FIXNUM_MIN = min/2
+ max = 1
+ max *= 2 while (max-1).class == Fixnum
+ FIXNUM_MAX = max/2-1
+
+ def test_fixnum_range
+ assert_instance_of(Bignum, FIXNUM_MIN-1)
+ assert_instance_of(Fixnum, FIXNUM_MIN)
+ assert_instance_of(Fixnum, FIXNUM_MAX)
+ assert_instance_of(Bignum, FIXNUM_MAX+1)
+ end
+
+ def check_class(n)
+ if FIXNUM_MIN <= n && n <= FIXNUM_MAX
+ assert_instance_of(Fixnum, n)
+ else
+ assert_instance_of(Bignum, n)
+ end
+ end
+
+ def test_aref
+ VS.each {|a|
+ 100.times {|i|
+ assert_equal((a >> i).odd? ? 1 : 0, a[i], "(#{a})[#{i}]")
+ }
+ }
+ VS.each {|a|
+ VS.each {|b|
+ c = nil
+ assert_nothing_raised("(#{a})[#{b}]") { c = a[b] }
+ check_class(c)
+ if b < 0
+ assert_equal(0, c, "(#{a})[#{b}]")
+ else
+ assert_equal((a >> b).odd? ? 1 : 0, c, "(#{a})[#{b}]")
+ end
+ }
+ }
+ end
+
+ def test_plus
+ VS.each {|a|
+ VS.each {|b|
+ c = a + b
+ check_class(c)
+ assert_equal(b + a, c, "#{a} + #{b}")
+ assert_equal(a, c - b, "(#{a} + #{b}) - #{b}")
+ assert_equal(a-~b-1, c, "#{a} + #{b}") # Hacker's Delight
+ assert_equal((a^b)+2*(a&b), c, "#{a} + #{b}") # Hacker's Delight
+ assert_equal((a|b)+(a&b), c, "#{a} + #{b}") # Hacker's Delight
+ assert_equal(2*(a|b)-(a^b), c, "#{a} + #{b}") # Hacker's Delight
+ }
+ }
+ end
+
+ def test_minus
+ VS.each {|a|
+ VS.each {|b|
+ c = a - b
+ check_class(c)
+ assert_equal(a, c + b, "(#{a} - #{b}) + #{b}")
+ assert_equal(-b, c - a, "(#{a} - #{b}) - #{a}")
+ assert_equal(a+~b+1, c, "#{a} - #{b}") # Hacker's Delight
+ assert_equal((a^b)-2*(b&~a), c, "#{a} - #{b}") # Hacker's Delight
+ assert_equal((a&~b)-(b&~a), c, "#{a} - #{b}") # Hacker's Delight
+ assert_equal(2*(a&~b)-(a^b), c, "#{a} - #{b}") # Hacker's Delight
+ }
+ }
+ end
+
+ def test_mult
+ VS.each {|a|
+ VS.each {|b|
+ c = a * b
+ check_class(c)
+ assert_equal(b * a, c, "#{a} * #{b}")
+ assert_equal(b, c / a, "(#{a} * #{b}) / #{a}") if a != 0
+ assert_equal(a.abs * b.abs, (a * b).abs, "(#{a} * #{b}).abs")
+ assert_equal((a-100)*(b-100)+(a-100)*100+(b-100)*100+10000, c, "#{a} * #{b}")
+ assert_equal((a+100)*(b+100)-(a+100)*100-(b+100)*100+10000, c, "#{a} * #{b}")
+ }
+ }
+ end
+
+ def test_divmod
+ VS.each {|a|
+ VS.each {|b|
+ if b == 0
+ assert_raise(ZeroDivisionError) { a.divmod(b) }
+ else
+ q, r = a.divmod(b)
+ check_class(q)
+ check_class(r)
+ assert_equal(a, b*q+r)
+ assert(r.abs < b.abs)
+ assert(0 < b ? (0 <= r && r < b) : (b < r && r <= 0))
+ assert_equal(q, a/b)
+ assert_equal(q, a.div(b))
+ assert_equal(r, a%b)
+ assert_equal(r, a.modulo(b))
+ end
+ }
+ }
+ end
+
+ def test_pow
+ small_values = VS.find_all {|v| 0 <= v && v < 1000 }
+ VS.each {|a|
+ small_values.each {|b|
+ c = a ** b
+ check_class(c)
+ d = 1
+ b.times { d *= a }
+ assert_equal(d, c, "(#{a}) ** #{b}")
+ if a != 0
+ d = c
+ b.times { d /= a }
+ assert_equal(1, d, "((#{a}) ** #{b}) / #{a} / ...(#{b} times)...")
+ end
+ }
+ }
+ end
+
+ def test_not
+ VS.each {|a|
+ b = ~a
+ check_class(b)
+ assert_equal(-1 ^ a, b, "~#{a}")
+ assert_equal(-a-1, b, "~#{a}") # Hacker's Delight
+ assert_equal(0, a & b, "#{a} & ~#{a}")
+ assert_equal(-1, a | b, "#{a} | ~#{a}")
+ }
+ end
+
+ def test_or
+ VS.each {|a|
+ VS.each {|b|
+ c = a | b
+ check_class(c)
+ assert_equal(b | a, c, "#{a} | #{b}")
+ assert_equal(a + b - (a&b), c, "#{a} | #{b}")
+ assert_equal((a & ~b) + b, c, "#{a} | #{b}") # Hacker's Delight
+ assert_equal(-1, c | ~a, "(#{a} | #{b}) | ~#{a})")
+ }
+ }
+ end
+
+ def test_and
+ VS.each {|a|
+ VS.each {|b|
+ c = a & b
+ check_class(c)
+ assert_equal(b & a, c, "#{a} & #{b}")
+ assert_equal(a + b - (a|b), c, "#{a} & #{b}")
+ assert_equal((~a | b) - ~a, c, "#{a} & #{b}") # Hacker's Delight
+ assert_equal(0, c & ~a, "(#{a} & #{b}) & ~#{a}")
+ }
+ }
+ end
+
+ def test_xor
+ VS.each {|a|
+ VS.each {|b|
+ c = a ^ b
+ check_class(c)
+ assert_equal(b ^ a, c, "#{a} ^ #{b}")
+ assert_equal((a|b)-(a&b), c, "#{a} ^ #{b}") # Hacker's Delight
+ assert_equal(b, c ^ a, "(#{a} ^ #{b}) ^ #{a}")
+ }
+ }
+ end
+
+ def test_lshift
+ small_values = VS.find_all {|v| v < 8000 }
+ VS.each {|a|
+ small_values.each {|b|
+ c = a << b
+ check_class(c)
+ if 0 <= b
+ assert_equal(a, c >> b, "(#{a} << #{b}) >> #{b}")
+ assert_equal(a * 2**b, c, "#{a} << #{b}")
+ end
+ 0.upto(c.size*8+10) {|nth|
+ assert_equal(a[nth-b], c[nth], "(#{a} << #{b})[#{nth}]")
+ }
+ }
+ }
+ end
+
+ def test_rshift
+ small_values = VS.find_all {|v| -8000 < v }
+ VS.each {|a|
+ small_values.each {|b|
+ c = a >> b
+ check_class(c)
+ if b <= 0
+ assert_equal(a, c << b, "(#{a} >> #{b}) << #{b}")
+ assert_equal(a * 2**(-b), c, "#{a} >> #{b}")
+ end
+ 0.upto(c.size*8+10) {|nth|
+ assert_equal(a[nth+b], c[nth], "(#{a} >> #{b})[#{nth}]")
+ }
+ }
+ }
+ end
+
+ def test_succ
+ VS.each {|a|
+ b = a.succ
+ check_class(b)
+ assert_equal(a+1, b, "(#{a}).succ")
+ assert_equal(a, b.pred, "(#{a}).succ.pred")
+ assert_equal(a, b-1, "(#{a}).succ - 1")
+ }
+ end
+
+ def test_pred
+ VS.each {|a|
+ b = a.pred
+ check_class(b)
+ assert_equal(a-1, b, "(#{a}).pred")
+ assert_equal(a, b.succ, "(#{a}).pred.succ")
+ assert_equal(a, b + 1, "(#{a}).pred + 1")
+ }
+ end
+
+ def test_unary_plus
+ VS.each {|a|
+ b = +a
+ check_class(b)
+ assert_equal(a, b, "+(#{a})")
+ }
+ end
+
+ def test_unary_minus
+ VS.each {|a|
+ b = -a
+ check_class(b)
+ assert_equal(0-a, b, "-(#{a})")
+ assert_equal(~a+1, b, "-(#{a})")
+ assert_equal(0, a+b, "#{a}+(-(#{a}))")
+ }
+ end
+
+ def test_cmp
+ VS.each_with_index {|a, i|
+ VS.each_with_index {|b, j|
+ assert_equal(i <=> j, a <=> b, "#{a} <=> #{b}")
+ assert_equal(i < j, a < b, "#{a} < #{b}")
+ assert_equal(i <= j, a <= b, "#{a} <= #{b}")
+ assert_equal(i > j, a > b, "#{a} > #{b}")
+ assert_equal(i >= j, a >= b, "#{a} >= #{b}")
+ }
+ }
+ end
+
+ def test_eq
+ VS.each_with_index {|a, i|
+ VS.each_with_index {|b, j|
+ c = a == b
+ assert_equal(b == a, c, "#{a} == #{b}")
+ assert_equal(i == j, c, "#{a} == #{b}")
+ }
+ }
+ end
+
+ def test_abs
+ VS.each {|a|
+ b = a.abs
+ check_class(b)
+ if a < 0
+ assert_equal(-a, b, "(#{a}).abs")
+ else
+ assert_equal(a, b, "(#{a}).abs")
+ end
+ }
+ end
+
+ def test_ceil
+ VS.each {|a|
+ b = a.ceil
+ check_class(b)
+ assert_equal(a, b, "(#{a}).ceil")
+ }
+ end
+
+ def test_floor
+ VS.each {|a|
+ b = a.floor
+ check_class(b)
+ assert_equal(a, b, "(#{a}).floor")
+ }
+ end
+
+ def test_round
+ VS.each {|a|
+ b = a.round
+ check_class(b)
+ assert_equal(a, b, "(#{a}).round")
+ }
+ end
+
+ def test_truncate
+ VS.each {|a|
+ b = a.truncate
+ check_class(b)
+ assert_equal(a, b, "(#{a}).truncate")
+ }
+ end
+
+ def test_remainder
+ VS.each {|a|
+ VS.each {|b|
+ if b == 0
+ assert_raise(ZeroDivisionError) { a.divmod(b) }
+ else
+ r = a.remainder(b)
+ check_class(r)
+ if a < 0
+ assert_operator(-b.abs, :<, r, "#{a}.remainder(#{b})")
+ assert_operator(0, :>=, r, "#{a}.remainder(#{b})")
+ elsif 0 < a
+ assert_operator(0, :<=, r, "#{a}.remainder(#{b})")
+ assert_operator(b.abs, :>, r, "#{a}.remainder(#{b})")
+ else
+ assert_equal(0, r, "#{a}.remainder(#{b})")
+ end
+ end
+ }
+ }
+ end
+
+ def test_zero_nonzero
+ VS.each {|a|
+ z = a.zero?
+ n = a.nonzero?
+ if a == 0
+ assert_equal(true, z, "(#{a}).zero?")
+ assert_equal(nil, n, "(#{a}).nonzero?")
+ else
+ assert_equal(false, z, "(#{a}).zero?")
+ assert_equal(a, n, "(#{a}).nonzero?")
+ check_class(n)
+ end
+ assert(z ^ n, "(#{a}).zero? ^ (#{a}).nonzero?")
+ }
+ end
+
+ def test_even_odd
+ VS.each {|a|
+ e = a.even?
+ o = a.odd?
+ assert_equal((a % 2) == 0, e, "(#{a}).even?")
+ assert_equal((a % 2) == 1, o, "(#{a}).odd")
+ assert_equal((a & 1) == 0, e, "(#{a}).even?")
+ assert_equal((a & 1) == 1, o, "(#{a}).odd")
+ assert(e ^ o, "(#{a}).even? ^ (#{a}).odd?")
+ }
+ end
+
+ def test_to_s
+ 2.upto(36) {|radix|
+ VS.each {|a|
+ s = a.to_s(radix)
+ b = s.to_i(radix)
+ assert_equal(a, b, "(#{a}).to_s(#{radix}).to_i(#{radix})")
+ }
+ }
+ end
+
+ def test_printf_x
+ VS.reverse_each {|a|
+ s = sprintf("%x", a)
+ if /\A\.\./ =~ s
+ b = -($'.tr('0123456789abcdef', 'fedcba9876543210').to_i(16) + 1)
+ else
+ b = s.to_i(16)
+ end
+ assert_equal(a, b, "sprintf('%x', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_printf_x_sign
+ VS.reverse_each {|a|
+ s = sprintf("%+x", a)
+ b = s.to_i(16)
+ assert_equal(a, b, "sprintf('%+x', #{a}) = #{s.inspect}")
+ s = sprintf("% x", a)
+ b = s.to_i(16)
+ assert_equal(a, b, "sprintf('% x', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_printf_o
+ VS.reverse_each {|a|
+ s = sprintf("%o", a)
+ if /\A\.\./ =~ s
+ b = -($'.tr('01234567', '76543210').to_i(8) + 1)
+ else
+ b = s.to_i(8)
+ end
+ assert_equal(a, b, "sprintf('%o', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_printf_o_sign
+ VS.reverse_each {|a|
+ s = sprintf("%+o", a)
+ b = s.to_i(8)
+ assert_equal(a, b, "sprintf('%+o', #{a}) = #{s.inspect}")
+ s = sprintf("% o", a)
+ b = s.to_i(8)
+ assert_equal(a, b, "sprintf('% o', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_printf_b
+ VS.reverse_each {|a|
+ s = sprintf("%b", a)
+ if /\A\.\./ =~ s
+ b = -($'.tr('01', '10').to_i(2) + 1)
+ else
+ b = s.to_i(2)
+ end
+ assert_equal(a, b, "sprintf('%b', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_printf_b_sign
+ VS.reverse_each {|a|
+ s = sprintf("%+b", a)
+ b = s.to_i(2)
+ assert_equal(a, b, "sprintf('%+b', #{a}) = #{s.inspect}")
+ s = sprintf("% b", a)
+ b = s.to_i(2)
+ assert_equal(a, b, "sprintf('% b', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_printf_diu
+ VS.reverse_each {|a|
+ s = sprintf("%d", a)
+ b = s.to_i
+ assert_equal(a, b, "sprintf('%d', #{a}) = #{s.inspect}")
+ s = sprintf("%i", a)
+ b = s.to_i
+ assert_equal(a, b, "sprintf('%i', #{a}) = #{s.inspect}")
+ s = sprintf("%u", a)
+ b = s.to_i
+ assert_equal(a, b, "sprintf('%u', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_marshal
+ VS.reverse_each {|a|
+ s = Marshal.dump(a)
+ b = Marshal.load(s)
+ assert_equal(a, b, "Marshal.load(Marshal.dump(#{a}))")
+ }
+ end
+
+ def test_pack
+ %w[c C s S s! S! i I i! I! l L l! L! q Q n N v V].each {|template|
+ size = [0].pack(template).size
+ mask = (1 << (size * 8)) - 1
+ if /[A-Znv]/ =~ template
+ min = 0
+ max = (1 << (size * 8))-1
+ else
+ min = -(1 << (size * 8 - 1))
+ max = (1 << (size * 8 - 1)) - 1
+ end
+ VS.reverse_each {|a|
+ s = [a].pack(template)
+ b = s.unpack(template)[0]
+ if min <= a && a <= max
+ assert_equal(a, b, "[#{a}].pack(#{template.dump}).unpack(#{template.dump})[0]")
+ end
+ assert_operator(min, :<=, b)
+ assert_operator(b, :<=, max)
+ assert_equal(a & mask, b & mask, "[#{a}].pack(#{template.dump}).unpack(#{template.dump})[0] & #{mask}")
+ }
+ }
+ end
+
+ def test_pack_ber
+ template = "w"
+ VS.reverse_each {|a|
+ if a < 0
+ assert_raise(ArgumentError) { [a].pack(template) }
+ else
+ s = [a].pack(template)
+ b = s.unpack(template)[0]
+ assert_equal(a, b, "[#{a}].pack(#{template.dump}).unpack(#{template.dump})")
+ end
+ }
+ end
+
+ def test_pack_utf8
+ template = "U"
+ VS.reverse_each {|a|
+ if a < 0 || 0x7fffffff < a
+ assert_raise(RangeError) { [a].pack(template) }
+ else
+ s = [a].pack(template)
+ b = s.unpack(template)[0]
+ assert_equal(a, b, "[#{a}].pack(#{template.dump}).unpack(#{template.dump})")
+ end
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_io.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_io.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_io.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1658 @@
+require 'test/unit'
+require 'tmpdir'
+require "fcntl"
+#require 'io/nonblock'
+require 'socket'
+require 'stringio'
+require 'timeout'
+require 'tempfile'
+require_relative 'envutil'
+
+class TestIO < Test::Unit::TestCase
+ def have_close_on_exec?
+ begin
+ $stdin.close_on_exec?
+ true
+ rescue NotImplementedError
+ false
+ end
+ end
+
+ def have_nonblock?
+ IO.method_defined?("nonblock=")
+ end
+
+ def test_pipe
+ r, w = IO.pipe
+ assert_instance_of(IO, r)
+ assert_instance_of(IO, w)
+ w.print "abc"
+ w.close
+ assert_equal("abc", r.read)
+ r.close
+ end
+
+ def test_pipe_block
+ x = nil
+ ret = IO.pipe {|r, w|
+ x = [r,w]
+ assert_instance_of(IO, r)
+ assert_instance_of(IO, w)
+ w.print "abc"
+ w.close
+ assert_equal("abc", r.read)
+ assert(!r.closed?)
+ assert(w.closed?)
+ :foooo
+ }
+ assert_equal(:foooo, ret)
+ assert(x[0].closed?)
+ assert(x[1].closed?)
+ end
+
+ def test_pipe_block_close
+ 4.times {|i|
+ x = nil
+ IO.pipe {|r, w|
+ x = [r,w]
+ r.close if (i&1) == 0
+ w.close if (i&2) == 0
+ }
+ assert(x[0].closed?)
+ assert(x[1].closed?)
+ }
+ end
+
+ def test_gets_rs
+ # default_rs
+ r, w = IO.pipe
+ w.print "aaa\nbbb\n"
+ w.close
+ assert_equal "aaa\n", r.gets
+ assert_equal "bbb\n", r.gets
+ assert_nil r.gets
+ r.close
+
+ # nil
+ r, w = IO.pipe
+ w.print "a\n\nb\n\n"
+ w.close
+ assert_equal "a\n\nb\n\n", r.gets(nil)
+ assert_nil r.gets("")
+ r.close
+
+ # "\377"
+ r, w = IO.pipe('ascii-8bit')
+ w.print "\377xyz"
+ w.close
+ r.binmode
+ assert_equal("\377", r.gets("\377"), "[ruby-dev:24460]")
+ r.close
+
+ # ""
+ r, w = IO.pipe
+ w.print "a\n\nb\n\n"
+ w.close
+ assert_equal "a\n\n", r.gets(""), "[ruby-core:03771]"
+ assert_equal "b\n\n", r.gets("")
+ assert_nil r.gets("")
+ r.close
+ end
+
+ def test_gets_limit_extra_arg
+ with_pipe {|r, w|
+ r, w = IO.pipe
+ w << "0123456789\n0123456789"
+ w.close
+ assert_equal("0123456789\n0", r.gets(nil, 12))
+ assert_raise(TypeError) { r.gets(3,nil) }
+ }
+ end
+
+ # This test cause SEGV.
+ def test_ungetc
+ r, w = IO.pipe
+ w.close
+ s = "a" * 1000
+ assert_raise(IOError, "[ruby-dev:31650]") { 200.times { r.ungetc s } }
+ ensure
+ r.close
+ end
+
+ def test_ungetbyte
+ t = make_tempfile
+ t.open
+ t.binmode
+ t.ungetbyte(0x41)
+ assert_equal(-1, t.pos)
+ assert_equal(0x41, t.getbyte)
+ t.rewind
+ assert_equal(0, t.pos)
+ t.ungetbyte("qux")
+ assert_equal(-3, t.pos)
+ assert_equal("quxfoo\n", t.gets)
+ assert_equal(4, t.pos)
+ t.set_encoding("utf-8")
+ t.ungetbyte(0x89)
+ t.ungetbyte(0x8e)
+ t.ungetbyte("\xe7")
+ t.ungetbyte("\xe7\xb4\x85")
+ assert_equal(-2, t.pos)
+ assert_equal("\u7d05\u7389bar\n", t.gets)
+ end
+
+ def test_each_byte
+ r, w = IO.pipe
+ w << "abc def"
+ w.close
+ r.each_byte {|byte| break if byte == 32 }
+ assert_equal("def", r.read, "[ruby-dev:31659]")
+ ensure
+ r.close
+ end
+
+ def test_each_codepoint
+ t = make_tempfile
+ bug2959 = '[ruby-core:28650]'
+ a = ""
+ File.open(t, 'rt') {|f|
+ f.each_codepoint {|c| a << c}
+ }
+ assert_equal("foo\nbar\nbaz\n", a, bug2959)
+ end
+
+ def test_rubydev33072
+ t = make_tempfile
+ path = t.path
+ t.close!
+ assert_raise(Errno::ENOENT, "[ruby-dev:33072]") do
+ File.read(path, nil, nil, {})
+ end
+ end
+
+ def with_pipe
+ r, w = IO.pipe
+ begin
+ yield r, w
+ ensure
+ r.close unless r.closed?
+ w.close unless w.closed?
+ end
+ end
+
+ def with_read_pipe(content)
+ r, w = IO.pipe
+ w << content
+ w.close
+ begin
+ yield r
+ ensure
+ r.close
+ end
+ end
+
+ def mkcdtmpdir
+ Dir.mktmpdir {|d|
+ Dir.chdir(d) {
+ yield
+ }
+ }
+ end
+
+ def test_copy_stream
+ mkcdtmpdir {
+
+ content = "foobar"
+ File.open("src", "w") {|f| f << content }
+ ret = IO.copy_stream("src", "dst")
+ assert_equal(content.bytesize, ret)
+ assert_equal(content, File.read("dst"))
+
+ # overwrite by smaller file.
+ content = "baz"
+ File.open("src", "w") {|f| f << content }
+ ret = IO.copy_stream("src", "dst")
+ assert_equal(content.bytesize, ret)
+ assert_equal(content, File.read("dst"))
+
+ ret = IO.copy_stream("src", "dst", 2)
+ assert_equal(2, ret)
+ assert_equal(content[0,2], File.read("dst"))
+
+ ret = IO.copy_stream("src", "dst", 0)
+ assert_equal(0, ret)
+ assert_equal("", File.read("dst"))
+
+ ret = IO.copy_stream("src", "dst", nil, 1)
+ assert_equal(content.bytesize-1, ret)
+ assert_equal(content[1..-1], File.read("dst"))
+
+ assert_raise(Errno::ENOENT) {
+ IO.copy_stream("nodir/foo", "dst")
+ }
+
+ assert_raise(Errno::ENOENT) {
+ IO.copy_stream("src", "nodir/bar")
+ }
+
+ with_pipe {|r, w|
+ ret = IO.copy_stream("src", w)
+ assert_equal(content.bytesize, ret)
+ w.close
+ assert_equal(content, r.read)
+ }
+
+ with_pipe {|r, w|
+ w.close
+ assert_raise(IOError) { IO.copy_stream("src", w) }
+ }
+
+ pipe_content = "abc"
+ with_read_pipe(pipe_content) {|r|
+ ret = IO.copy_stream(r, "dst")
+ assert_equal(pipe_content.bytesize, ret)
+ assert_equal(pipe_content, File.read("dst"))
+ }
+
+ with_read_pipe("abc") {|r1|
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ w2.sync = false
+ w2 << "def"
+ ret = IO.copy_stream(r1, w2)
+ assert_equal(2, ret)
+ w2.close
+ assert_equal("defbc", r2.read)
+ }
+ }
+
+ with_read_pipe("abc") {|r1|
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ w2.sync = false
+ w2 << "def"
+ ret = IO.copy_stream(r1, w2, 1)
+ assert_equal(1, ret)
+ w2.close
+ assert_equal("defb", r2.read)
+ }
+ }
+
+ with_read_pipe("abc") {|r1|
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ ret = IO.copy_stream(r1, w2)
+ assert_equal(2, ret)
+ w2.close
+ assert_equal("bc", r2.read)
+ }
+ }
+
+ with_read_pipe("abc") {|r1|
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ ret = IO.copy_stream(r1, w2, 1)
+ assert_equal(1, ret)
+ w2.close
+ assert_equal("b", r2.read)
+ }
+ }
+
+ with_read_pipe("abc") {|r1|
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ ret = IO.copy_stream(r1, w2, 0)
+ assert_equal(0, ret)
+ w2.close
+ assert_equal("", r2.read)
+ }
+ }
+
+ with_pipe {|r1, w1|
+ w1 << "abc"
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ w1 << "def"
+ w1.close
+ ret = IO.copy_stream(r1, w2)
+ assert_equal(5, ret)
+ w2.close
+ assert_equal("bcdef", r2.read)
+ }
+ }
+
+ with_pipe {|r, w|
+ ret = IO.copy_stream("src", w, 1, 1)
+ assert_equal(1, ret)
+ w.close
+ assert_equal(content[1,1], r.read)
+ }
+
+ if have_nonblock?
+ with_read_pipe("abc") {|r1|
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ begin
+ w2.nonblock = true
+ rescue Errno::EBADF
+ skip "nonblocking IO for pipe is not implemented"
+ break
+ end
+ s = w2.syswrite("a" * 100000)
+ t = Thread.new { sleep 0.1; r2.read }
+ ret = IO.copy_stream(r1, w2)
+ w2.close
+ assert_equal(2, ret)
+ assert_equal("a" * s + "bc", t.value)
+ }
+ }
+ end
+
+ bigcontent = "abc" * 123456
+ File.open("bigsrc", "w") {|f| f << bigcontent }
+ ret = IO.copy_stream("bigsrc", "bigdst")
+ assert_equal(bigcontent.bytesize, ret)
+ assert_equal(bigcontent, File.read("bigdst"))
+
+ File.unlink("bigdst")
+ ret = IO.copy_stream("bigsrc", "bigdst", nil, 100)
+ assert_equal(bigcontent.bytesize-100, ret)
+ assert_equal(bigcontent[100..-1], File.read("bigdst"))
+
+ File.unlink("bigdst")
+ ret = IO.copy_stream("bigsrc", "bigdst", 30000, 100)
+ assert_equal(30000, ret)
+ assert_equal(bigcontent[100, 30000], File.read("bigdst"))
+
+ File.open("bigsrc") {|f|
+ begin
+ assert_equal(0, f.pos)
+ ret = IO.copy_stream(f, "bigdst", nil, 10)
+ assert_equal(bigcontent.bytesize-10, ret)
+ assert_equal(bigcontent[10..-1], File.read("bigdst"))
+ assert_equal(0, f.pos)
+ ret = IO.copy_stream(f, "bigdst", 40, 30)
+ assert_equal(40, ret)
+ assert_equal(bigcontent[30, 40], File.read("bigdst"))
+ assert_equal(0, f.pos)
+ rescue NotImplementedError
+ #skip "pread(2) is not implemtented."
+ end
+ }
+
+ with_pipe {|r, w|
+ w.close
+ assert_raise(IOError) { IO.copy_stream("src", w) }
+ }
+
+ megacontent = "abc" * 1234567
+ File.open("megasrc", "w") {|f| f << megacontent }
+
+ if have_nonblock?
+ with_pipe {|r1, w1|
+ with_pipe {|r2, w2|
+ begin
+ r1.nonblock = true
+ w2.nonblock = true
+ rescue Errno::EBADF
+ skip "nonblocking IO for pipe is not implemented"
+ end
+ t1 = Thread.new { w1 << megacontent; w1.close }
+ t2 = Thread.new { r2.read }
+ ret = IO.copy_stream(r1, w2)
+ assert_equal(megacontent.bytesize, ret)
+ w2.close
+ t1.join
+ assert_equal(megacontent, t2.value)
+ }
+ }
+ end
+
+ with_pipe {|r1, w1|
+ with_pipe {|r2, w2|
+ t1 = Thread.new { w1 << megacontent; w1.close }
+ t2 = Thread.new { r2.read }
+ ret = IO.copy_stream(r1, w2)
+ assert_equal(megacontent.bytesize, ret)
+ w2.close
+ t1.join
+ assert_equal(megacontent, t2.value)
+ }
+ }
+
+ with_pipe {|r, w|
+ t = Thread.new { r.read }
+ ret = IO.copy_stream("megasrc", w)
+ assert_equal(megacontent.bytesize, ret)
+ w.close
+ assert_equal(megacontent, t.value)
+ }
+ }
+ end
+
+ def test_copy_stream_rbuf
+ mkcdtmpdir {
+ begin
+ with_pipe {|r, w|
+ File.open("foo", "w") {|f| f << "abcd" }
+ File.open("foo") {|f|
+ f.read(1)
+ assert_equal(3, IO.copy_stream(f, w, 10, 1))
+ }
+ w.close
+ assert_equal("bcd", r.read)
+ }
+ rescue NotImplementedError
+ skip "pread(2) is not implemtented."
+ end
+ }
+ end
+
+ def with_socketpair
+ s1, s2 = UNIXSocket.pair
+ begin
+ yield s1, s2
+ ensure
+ s1.close unless s1.closed?
+ s2.close unless s2.closed?
+ end
+ end
+
+ def test_copy_stream_socket
+ return unless defined? UNIXSocket
+ mkcdtmpdir {
+
+ content = "foobar"
+ File.open("src", "w") {|f| f << content }
+
+ with_socketpair {|s1, s2|
+ ret = IO.copy_stream("src", s1)
+ assert_equal(content.bytesize, ret)
+ s1.close
+ assert_equal(content, s2.read)
+ }
+
+ bigcontent = "abc" * 123456
+ File.open("bigsrc", "w") {|f| f << bigcontent }
+
+ with_socketpair {|s1, s2|
+ t = Thread.new { s2.read }
+ ret = IO.copy_stream("bigsrc", s1)
+ assert_equal(bigcontent.bytesize, ret)
+ s1.close
+ result = t.value
+ assert_equal(bigcontent, result)
+ }
+
+ with_socketpair {|s1, s2|
+ t = Thread.new { s2.read }
+ ret = IO.copy_stream("bigsrc", s1, 10000)
+ assert_equal(10000, ret)
+ s1.close
+ result = t.value
+ assert_equal(bigcontent[0,10000], result)
+ }
+
+ File.open("bigsrc") {|f|
+ assert_equal(0, f.pos)
+ with_socketpair {|s1, s2|
+ t = Thread.new { s2.read }
+ ret = IO.copy_stream(f, s1, nil, 100)
+ assert_equal(bigcontent.bytesize-100, ret)
+ assert_equal(0, f.pos)
+ s1.close
+ result = t.value
+ assert_equal(bigcontent[100..-1], result)
+ }
+ }
+
+ File.open("bigsrc") {|f|
+ assert_equal(bigcontent[0,100], f.read(100))
+ assert_equal(100, f.pos)
+ with_socketpair {|s1, s2|
+ t = Thread.new { s2.read }
+ ret = IO.copy_stream(f, s1)
+ assert_equal(bigcontent.bytesize-100, ret)
+ assert_equal(bigcontent.length, f.pos)
+ s1.close
+ result = t.value
+ assert_equal(bigcontent[100..-1], result)
+ }
+ }
+
+ megacontent = "abc" * 1234567
+ File.open("megasrc", "w") {|f| f << megacontent }
+
+ if have_nonblock?
+ with_socketpair {|s1, s2|
+ begin
+ s1.nonblock = true
+ rescue Errno::EBADF
+ skip "nonblocking IO for pipe is not implemented"
+ end
+ t = Thread.new { s2.read }
+ ret = IO.copy_stream("megasrc", s1)
+ assert_equal(megacontent.bytesize, ret)
+ s1.close
+ result = t.value
+ assert_equal(megacontent, result)
+ }
+ end
+ }
+ end
+
+ def test_copy_stream_strio
+ src = StringIO.new("abcd")
+ dst = StringIO.new
+ ret = IO.copy_stream(src, dst)
+ assert_equal(4, ret)
+ assert_equal("abcd", dst.string)
+ assert_equal(4, src.pos)
+ end
+
+ def test_copy_stream_strio_len
+ src = StringIO.new("abcd")
+ dst = StringIO.new
+ ret = IO.copy_stream(src, dst, 3)
+ assert_equal(3, ret)
+ assert_equal("abc", dst.string)
+ assert_equal(3, src.pos)
+ end
+
+ def test_copy_stream_strio_off
+ src = StringIO.new("abcd")
+ with_pipe {|r, w|
+ assert_raise(ArgumentError) {
+ IO.copy_stream(src, w, 3, 1)
+ }
+ }
+ end
+
+ def test_copy_stream_fname_to_strio
+ mkcdtmpdir {
+ File.open("foo", "w") {|f| f << "abcd" }
+ src = "foo"
+ dst = StringIO.new
+ ret = IO.copy_stream(src, dst, 3)
+ assert_equal(3, ret)
+ assert_equal("abc", dst.string)
+ }
+ end
+
+ def test_copy_stream_strio_to_fname
+ mkcdtmpdir {
+ # StringIO to filename
+ src = StringIO.new("abcd")
+ ret = IO.copy_stream(src, "fooo", 3)
+ assert_equal(3, ret)
+ assert_equal("abc", File.read("fooo"))
+ assert_equal(3, src.pos)
+ }
+ end
+
+ def test_copy_stream_io_to_strio
+ mkcdtmpdir {
+ # IO to StringIO
+ File.open("bar", "w") {|f| f << "abcd" }
+ File.open("bar") {|src|
+ dst = StringIO.new
+ ret = IO.copy_stream(src, dst, 3)
+ assert_equal(3, ret)
+ assert_equal("abc", dst.string)
+ assert_equal(3, src.pos)
+ }
+ }
+ end
+
+ def test_copy_stream_strio_to_io
+ mkcdtmpdir {
+ # StringIO to IO
+ src = StringIO.new("abcd")
+ ret = File.open("baz", "w") {|dst|
+ IO.copy_stream(src, dst, 3)
+ }
+ assert_equal(3, ret)
+ assert_equal("abc", File.read("baz"))
+ assert_equal(3, src.pos)
+ }
+ end
+
+ class Rot13IO
+ def initialize(io)
+ @io = io
+ end
+
+ def readpartial(*args)
+ ret = @io.readpartial(*args)
+ ret.tr!('a-zA-Z', 'n-za-mN-ZA-M')
+ ret
+ end
+
+ def write(str)
+ @io.write(str.tr('a-zA-Z', 'n-za-mN-ZA-M'))
+ end
+
+ def to_io
+ @io
+ end
+ end
+
+ def test_copy_stream_io_to_rot13
+ mkcdtmpdir {
+ File.open("bar", "w") {|f| f << "vex" }
+ File.open("bar") {|src|
+ File.open("baz", "w") {|dst0|
+ dst = Rot13IO.new(dst0)
+ ret = IO.copy_stream(src, dst, 3)
+ assert_equal(3, ret)
+ }
+ assert_equal("irk", File.read("baz"))
+ }
+ }
+ end
+
+ def test_copy_stream_rot13_to_io
+ mkcdtmpdir {
+ File.open("bar", "w") {|f| f << "flap" }
+ File.open("bar") {|src0|
+ src = Rot13IO.new(src0)
+ File.open("baz", "w") {|dst|
+ ret = IO.copy_stream(src, dst, 4)
+ assert_equal(4, ret)
+ }
+ }
+ assert_equal("sync", File.read("baz"))
+ }
+ end
+
+ def test_copy_stream_rot13_to_rot13
+ mkcdtmpdir {
+ File.open("bar", "w") {|f| f << "bin" }
+ File.open("bar") {|src0|
+ src = Rot13IO.new(src0)
+ File.open("baz", "w") {|dst0|
+ dst = Rot13IO.new(dst0)
+ ret = IO.copy_stream(src, dst, 3)
+ assert_equal(3, ret)
+ }
+ }
+ assert_equal("bin", File.read("baz"))
+ }
+ end
+
+ def test_copy_stream_strio_flush
+ with_pipe {|r, w|
+ w.sync = false
+ w.write "zz"
+ src = StringIO.new("abcd")
+ IO.copy_stream(src, w)
+ t = Thread.new {
+ w.close
+ }
+ assert_equal("zzabcd", r.read)
+ t.join
+ }
+ end
+
+ def test_copy_stream_strio_rbuf
+ with_pipe {|r, w|
+ w << "abcd"
+ w.close
+ assert_equal("a", r.read(1))
+ sio = StringIO.new
+ IO.copy_stream(r, sio)
+ assert_equal("bcd", sio.string)
+ }
+ end
+
+ def test_copy_stream_src_wbuf
+ mkcdtmpdir {
+ with_pipe {|r, w|
+ File.open("foe", "w+") {|f|
+ f.write "abcd\n"
+ f.rewind
+ f.write "xy"
+ IO.copy_stream(f, w)
+ }
+ assert_equal("xycd\n", File.read("foe"))
+ w.close
+ assert_equal("cd\n", r.read)
+ r.close
+ }
+ }
+ end
+
+ def test_copy_stream_dst_rbuf
+ mkcdtmpdir {
+ with_pipe {|r, w|
+ w << "xyz"
+ w.close
+ File.open("fom", "w+b") {|f|
+ f.write "abcd\n"
+ f.rewind
+ assert_equal("abc", f.read(3))
+ f.ungetc "c"
+ IO.copy_stream(r, f)
+ }
+ assert_equal("abxyz", File.read("fom"))
+ }
+ }
+ end
+
+ def safe_4
+ t = Thread.new do
+ $SAFE = 4
+ yield
+ end
+ unless t.join(10)
+ t.kill
+ flunk("timeout in safe_4")
+ end
+ end
+
+ def pipe(wp, rp)
+ r, w = IO.pipe
+ rt = Thread.new { rp.call(r) }
+ wt = Thread.new { wp.call(w) }
+ flunk("timeout") unless rt.join(10) && wt.join(10)
+ ensure
+ r.close unless !r || r.closed?
+ w.close unless !w || w.closed?
+ (rt.kill; rt.join) if rt
+ (wt.kill; wt.join) if wt
+ end
+
+ def ruby(*args)
+ args = ['-e', '$>.write($<.read)'] if args.empty?
+ ruby = EnvUtil.rubybin
+ f = IO.popen([ruby] + args, 'r+')
+ yield(f)
+ ensure
+ f.close unless !f || f.closed?
+ end
+
+ def test_try_convert
+ assert_equal(STDOUT, IO.try_convert(STDOUT))
+ assert_equal(nil, IO.try_convert("STDOUT"))
+ end
+
+ def test_ungetc2
+ f = false
+ pipe(proc do |w|
+ 0 until f
+ w.write("1" * 10000)
+ w.close
+ end, proc do |r|
+ r.ungetc("0" * 10000)
+ f = true
+ assert_equal("0" * 10000 + "1" * 10000, r.read)
+ end)
+ end
+
+ def test_write_non_writable
+ with_pipe do |r, w|
+ assert_raise(IOError) do
+ r.write "foobarbaz"
+ end
+ end
+ end
+
+ def test_dup
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ ruby do |f|
+ f2 = f.dup
+ f.puts "foo"
+ f2.puts "bar"
+ f.close_write
+ f2.close_write
+ assert_equal("foo\nbar\n", f.read)
+ assert_equal("", f2.read)
+ end
+ end
+
+ def test_dup_many
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ ruby('-e', <<-'End') {|f|
+ ok = 0
+ a = []
+ begin
+ loop {a << IO.pipe}
+ rescue Errno::EMFILE, Errno::ENFILE, Errno::ENOMEM
+ ok += 1
+ end
+ print "no" if ok != 1
+ begin
+ loop {a << [a[-1][0].dup, a[-1][1].dup]}
+ rescue Errno::EMFILE, Errno::ENFILE, Errno::ENOMEM
+ ok += 1
+ end
+ print "no" if ok != 2
+ print "ok"
+ End
+ assert_equal("ok", f.read)
+ }
+ end
+
+ def test_inspect
+ with_pipe do |r, w|
+ assert_match(/^#<IO:fd \d+>$/, r.inspect)
+ assert_raise(SecurityError) do
+ safe_4 { r.inspect }
+ end
+ end
+ end
+
+ def test_readpartial
+ pipe(proc do |w|
+ w.write "foobarbaz"
+ w.close
+ end, proc do |r|
+ assert_raise(ArgumentError) { r.readpartial(-1) }
+ assert_equal("fooba", r.readpartial(5))
+ r.readpartial(5, s = "")
+ assert_equal("rbaz", s)
+ end)
+ end
+
+ def test_readpartial_lock
+ skip("[BUG : #954] Race condition: assertion fails with IO.pipe, when checks size of String which had read from pipe.")
+
+ with_pipe do |r, w|
+ s = ""
+ t = Thread.new { r.readpartial(5, s) }
+ 0 until s.size == 5
+ assert_raise(RuntimeError) { s.clear }
+ w.write "foobarbaz"
+ w.close
+ assert_equal("fooba", t.value)
+ end
+ end
+
+ def test_readpartial_pos
+ mkcdtmpdir {
+ open("foo", "w") {|f| f << "abc" }
+ open("foo") {|f|
+ f.seek(0)
+ assert_equal("ab", f.readpartial(2))
+ assert_equal(2, f.pos)
+ }
+ }
+ end
+
+ def test_read
+ pipe(proc do |w|
+ w.write "foobarbaz"
+ w.close
+ end, proc do |r|
+ assert_raise(ArgumentError) { r.read(-1) }
+ assert_equal("fooba", r.read(5))
+ r.read(nil, s = "")
+ assert_equal("rbaz", s)
+ end)
+ end
+
+ def test_read_lock
+ skip("[BUG : #954] Race condition: assertion fails with IO.pipe, when checks size of String which had read from pipe.")
+
+ with_pipe do |r, w|
+ s = ""
+ t = Thread.new { r.read(5, s) }
+ 0 until s.size == 5
+ assert_raise(RuntimeError) { s.clear }
+ w.write "foobarbaz"
+ w.close
+ assert_equal("fooba", t.value)
+ end
+ end
+
+ def test_write_nonblock
+ skip("[BUG : #???] Assertion")
+
+ skip "IO#write_nonblock is not supported on file/pipe." if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ pipe(proc do |w|
+ w.write_nonblock(1)
+ w.close
+ end, proc do |r|
+ assert_equal("1", r.read)
+ end)
+ end
+
+ def test_read_nonblock_error
+ return if !have_nonblock?
+ skip "IO#read_nonblock is not supported on file/pipe." if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ with_pipe {|r, w|
+ begin
+ r.read_nonblock 4096
+ rescue Errno::EWOULDBLOCK
+ assert_kind_of(IO::WaitReadable, $!)
+ end
+ }
+ end
+
+ def test_write_nonblock_error
+ return if !have_nonblock?
+ skip "IO#write_nonblock is not supported on file/pipe." if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ with_pipe {|r, w|
+ begin
+ loop {
+ w.write_nonblock "a"*100000
+ }
+ rescue Errno::EWOULDBLOCK
+ assert_kind_of(IO::WaitWritable, $!)
+ end
+ }
+ end
+
+ def test_gets
+ pipe(proc do |w|
+ w.write "foobarbaz"
+ w.close
+ end, proc do |r|
+ assert_equal("", r.gets(0))
+ assert_equal("foobarbaz", s = r.gets(9))
+ end)
+ end
+
+ def test_close_read
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ ruby do |f|
+ f.close_read
+ f.write "foobarbaz"
+ assert_raise(IOError) { f.read }
+ end
+ end
+
+ def test_close_read_pipe
+ with_pipe do |r, w|
+ r.close_read
+ assert_raise(Errno::EPIPE) { w.write "foobarbaz" }
+ end
+ end
+
+ def test_close_read_security_error
+ with_pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.close_read }
+ end
+ end
+ end
+
+ def test_close_read_non_readable
+ with_pipe do |r, w|
+ assert_raise(IOError) do
+ w.close_read
+ end
+ end
+ end
+
+ def test_close_write
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ ruby do |f|
+ f.write "foobarbaz"
+ f.close_write
+ assert_equal("foobarbaz", f.read)
+ end
+ end
+
+ def test_close_write_security_error
+ with_pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.close_write }
+ end
+ end
+ end
+
+ def test_close_write_non_readable
+ with_pipe do |r, w|
+ assert_raise(IOError) do
+ r.close_write
+ end
+ end
+ end
+
+ def test_pid
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ r, w = IO.pipe
+ assert_equal(nil, r.pid)
+ assert_equal(nil, w.pid)
+
+ pipe = IO.popen(EnvUtil.rubybin, "r+")
+ pid1 = pipe.pid
+ pipe.puts "p $$"
+ pipe.close_write
+ pid2 = pipe.read.chomp.to_i
+ assert_equal(pid2, pid1)
+ assert_equal(pid2, pipe.pid)
+ pipe.close
+ assert_raise(IOError) { pipe.pid }
+ end
+
+ def make_tempfile
+ t = Tempfile.new("foo")
+ t.binmode
+ t.puts "foo"
+ t.puts "bar"
+ t.puts "baz"
+ t.close
+ t
+ end
+
+ def test_set_lineno
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ t = make_tempfile
+
+ ruby("-e", <<-SRC, t.path) do |f|
+ open(ARGV[0]) do |f|
+ p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.lineno = 1000; p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.rewind; p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.gets; p $.
+ end
+ SRC
+ assert_equal("0,1,2,2,1001,1001,1001,1,2,3,3", f.read.chomp.gsub("\n", ","))
+ end
+
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ r.gets; assert_equal(1, $.)
+ r.gets; assert_equal(2, $.)
+ r.lineno = 1000; assert_equal(2, $.)
+ r.gets; assert_equal(1001, $.)
+ r.gets; assert_equal(1001, $.)
+ end)
+ end
+
+ def test_readline
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ r.readline; assert_equal(1, $.)
+ r.readline; assert_equal(2, $.)
+ r.lineno = 1000; assert_equal(2, $.)
+ r.readline; assert_equal(1001, $.)
+ assert_raise(EOFError) { r.readline }
+ end)
+ end
+
+ def test_each_char
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ a = []
+ r.each_char {|c| a << c }
+ assert_equal(%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"], a)
+ end)
+ end
+
+ def test_lines
+ skip("[BUG : #???] Assertion")
+
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ e = r.lines
+ assert_equal("foo\n", e.next)
+ assert_equal("bar\n", e.next)
+ assert_equal("baz\n", e.next)
+ assert_raise(StopIteration) { e.next }
+ end)
+ end
+
+ def test_bytes
+ skip("[BUG : #???] Assertion")
+
+ pipe(proc do |w|
+ w.binmode
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ e = r.bytes
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c.ord, e.next)
+ end
+ assert_raise(StopIteration) { e.next }
+ end)
+ end
+
+ def test_chars
+ skip("[BUG : #???] Assertion")
+
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ e = r.chars
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c, e.next)
+ end
+ assert_raise(StopIteration) { e.next }
+ end)
+ end
+
+ def test_readbyte
+ pipe(proc do |w|
+ w.binmode
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ r.binmode
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c.ord, r.readbyte)
+ end
+ assert_raise(EOFError) { r.readbyte }
+ end)
+ end
+
+ def test_readchar
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c, r.readchar)
+ end
+ assert_raise(EOFError) { r.readchar }
+ end)
+ end
+
+ def test_close_on_exec
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ skip "IO\#close_on_exec is not implemented." unless have_close_on_exec?
+ ruby do |f|
+ assert_equal(false, f.close_on_exec?)
+ f.close_on_exec = true
+ assert_equal(true, f.close_on_exec?)
+ f.close_on_exec = false
+ assert_equal(false, f.close_on_exec?)
+ end
+
+ with_pipe do |r, w|
+ assert_equal(false, r.close_on_exec?)
+ r.close_on_exec = true
+ assert_equal(true, r.close_on_exec?)
+ r.close_on_exec = false
+ assert_equal(false, r.close_on_exec?)
+
+ assert_equal(false, w.close_on_exec?)
+ w.close_on_exec = true
+ assert_equal(true, w.close_on_exec?)
+ w.close_on_exec = false
+ assert_equal(false, w.close_on_exec?)
+ end
+ end
+
+ def test_close_security_error
+ with_pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.close }
+ end
+ end
+ end
+
+ def test_pos
+ t = make_tempfile
+
+ open(t.path, IO::RDWR|IO::CREAT|IO::TRUNC, 0600) do |f|
+ f.write "Hello"
+ assert_equal(5, f.pos)
+ end
+ open(t.path, IO::RDWR|IO::CREAT|IO::TRUNC, 0600) do |f|
+ f.sync = true
+ f.read
+ f.write "Hello"
+ assert_equal(5, f.pos)
+ end
+ end
+
+ def test_sysseek
+ t = make_tempfile
+
+ open(t.path) do |f|
+ f.sysseek(-4, IO::SEEK_END)
+ assert_equal("baz\n", f.read)
+ end
+
+ open(t.path) do |f|
+ a = [f.getc, f.getc, f.getc]
+ a.reverse_each {|c| f.ungetc c }
+ assert_raise(IOError) { f.sysseek(1) }
+ end
+ end
+
+ def test_syswrite
+ t = make_tempfile
+
+ open(t.path, "w") do |f|
+ o = Object.new
+ def o.to_s; "FOO\n"; end
+ f.syswrite(o)
+ end
+ assert_equal("FOO\n", File.read(t.path))
+ end
+
+ def test_sysread
+ t = make_tempfile
+
+ open(t.path) do |f|
+ a = [f.getc, f.getc, f.getc]
+ a.reverse_each {|c| f.ungetc c }
+ assert_raise(IOError) { f.sysread(1) }
+ end
+ end
+
+ def test_flag
+ t = make_tempfile
+
+ assert_raise(ArgumentError) do
+ open(t.path, "z") { }
+ end
+
+ assert_raise(ArgumentError) do
+ open(t.path, "rr") { }
+ end
+ end
+
+ def test_sysopen
+ t = make_tempfile
+
+ fd = IO.sysopen(t.path)
+ assert_kind_of(Integer, fd)
+ f = IO.for_fd(fd)
+ assert_equal("foo\nbar\nbaz\n", f.read)
+ f.close
+
+ fd = IO.sysopen(t.path, "w", 0666)
+ assert_kind_of(Integer, fd)
+ if defined?(Fcntl::F_GETFL)
+ f = IO.for_fd(fd)
+ else
+ f = IO.for_fd(fd, 0666)
+ end
+ f.write("FOO\n")
+ f.close
+
+ fd = IO.sysopen(t.path, "r")
+ assert_kind_of(Integer, fd)
+ f = IO.for_fd(fd)
+ assert_equal("FOO\n", f.read)
+ f.close
+ end
+
+ def try_fdopen(fd, autoclose = true, level = 100)
+ if level > 0
+ try_fdopen(fd, autoclose, level - 1)
+ GC.start
+ level
+ else
+ IO.for_fd(fd, autoclose: autoclose)
+ nil
+ end
+ end
+
+ def test_autoclose
+ feature2250 = '[ruby-core:26222]'
+ pre = 'ft2250'
+
+ Tempfile.new(pre) do |t|
+ f = IO.for_fd(t.fileno)
+ assert_equal(true, f.autoclose?)
+ f.autoclose = false
+ assert_equal(false, f.autoclose?)
+ f.close
+ assert_nothing_raised(Errno::EBADF) {t.close}
+
+ t.open
+ f = IO.for_fd(t.fileno, autoclose: false)
+ assert_equal(false, f.autoclose?)
+ f.autoclose = true
+ assert_equal(true, f.autoclose?)
+ f.close
+ assert_raise(Errno::EBADF) {t.close}
+ end
+
+ Tempfile.new(pre) do |t|
+ try_fdopen(t.fileno)
+ assert_raise(Errno::EBADF) {t.close}
+ end
+
+ Tempfile.new(pre) do |t|
+ try_fdopen(f.fileno, false)
+ assert_nothing_raised(Errno::EBADF) {t.close}
+ end
+ end
+
+ def test_open_redirect
+ o = Object.new
+ def o.to_open; self; end
+ assert_equal(o, open(o))
+ o2 = nil
+ open(o) do |f|
+ o2 = f
+ end
+ assert_equal(o, o2)
+ end
+
+ def test_open_pipe
+ open("|" + EnvUtil.rubybin, "r+") do |f|
+ f.puts "puts 'foo'"
+ f.close_write
+ assert_equal("foo\n", f.read)
+ end
+ end
+
+ def test_reopen
+ t = make_tempfile
+
+ with_pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.reopen(t.path) }
+ end
+ end
+
+ open(__FILE__) do |f|
+ f.gets
+ assert_nothing_raised {
+ f.reopen(t.path)
+ assert_equal("foo\n", f.gets)
+ }
+ end
+
+ open(__FILE__) do |f|
+ f.gets
+ f2 = open(t.path)
+ f2.gets
+ assert_nothing_raised {
+ f.reopen(f2)
+ assert_equal("bar\n", f.gets, '[ruby-core:24240]')
+ }
+ end
+
+ open(__FILE__) do |f|
+ f2 = open(t.path)
+ f.reopen(f2)
+ assert_equal("foo\n", f.gets)
+ assert_equal("bar\n", f.gets)
+ f.reopen(f2)
+ assert_equal("baz\n", f.gets, '[ruby-dev:39479]')
+ end
+ end
+
+ def test_reopen_inherit
+ mkcdtmpdir {
+ system(EnvUtil.rubybin, '-e', <<"End")
+ f = open("out", "w")
+ STDOUT.reopen(f)
+ STDERR.reopen(f)
+ system(#{EnvUtil.rubybin.dump}, '-e', 'STDOUT.print "out"')
+ system(#{EnvUtil.rubybin.dump}, '-e', 'STDERR.print "err"')
+End
+ assert_equal("outerr", File.read("out"))
+ }
+ end
+
+ def test_foreach
+ a = []
+ IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ t = make_tempfile
+
+ a = []
+ IO.foreach(t.path) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ a = []
+ IO.foreach(t.path, {:mode => "r" }) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ a = []
+ IO.foreach(t.path, {:open_args => [] }) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ a = []
+ IO.foreach(t.path, {:open_args => ["r"] }) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ a = []
+ IO.foreach(t.path, "b") {|x| a << x }
+ assert_equal(["foo\nb", "ar\nb", "az\n"], a)
+
+ a = []
+ IO.foreach(t.path, 3) {|x| a << x }
+ assert_equal(["foo", "\n", "bar", "\n", "baz", "\n"], a)
+
+ a = []
+ IO.foreach(t.path, "b", 3) {|x| a << x }
+ assert_equal(["foo", "\nb", "ar\n", "b", "az\n"], a)
+
+ end
+
+ def test_s_readlines
+ t = make_tempfile
+
+ assert_equal(["foo\n", "bar\n", "baz\n"], IO.readlines(t.path))
+ assert_equal(["foo\nb", "ar\nb", "az\n"], IO.readlines(t.path, "b"))
+ assert_equal(["fo", "o\n", "ba", "r\n", "ba", "z\n"], IO.readlines(t.path, 2))
+ assert_equal(["fo", "o\n", "b", "ar", "\nb", "az", "\n"], IO.readlines(t.path, "b", 2))
+ end
+
+ def test_printf
+ pipe(proc do |w|
+ printf(w, "foo %s baz\n", "bar")
+ w.close_write
+ end, proc do |r|
+ assert_equal("foo bar baz\n", r.read)
+ end)
+ end
+
+ def test_print
+ t = make_tempfile
+
+ assert_in_out_err(["-", t.path], "print while $<.gets", %w(foo bar baz), [])
+ end
+
+ def test_print_separators
+ skip("[BUG : #???] Assertion")
+
+ $, = ':'
+ $\ = "\n"
+ pipe(proc do |w|
+ w.print('a')
+ w.print('a','b','c')
+ w.close
+ end, proc do |r|
+ assert_equal("a\n", r.gets)
+ assert_equal("a:b:c\n", r.gets)
+ assert_nil r.gets
+ r.close
+ end)
+ ensure
+ $, = nil
+ $\ = nil
+ end
+
+ def test_putc
+ pipe(proc do |w|
+ w.putc "A"
+ w.putc "BC"
+ w.putc 68
+ w.close_write
+ end, proc do |r|
+ assert_equal("ABD", r.read)
+ end)
+
+ assert_in_out_err([], "putc 65", %w(A), [])
+ end
+
+ def test_puts_recursive_array
+ a = ["foo"]
+ a << a
+ pipe(proc do |w|
+ w.puts a
+ w.close
+ end, proc do |r|
+ assert_equal("foo\n[...]\n", r.read)
+ end)
+ end
+
+ def test_display
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ pipe(proc do |w|
+ "foo".display(w)
+ w.close
+ end, proc do |r|
+ assert_equal("foo", r.read)
+ end)
+
+ assert_in_out_err([], "'foo'.display", %w(foo), [])
+ end
+
+ def test_set_stdout
+ assert_raise(TypeError) { $> = Object.new }
+
+ assert_in_out_err([], "$> = $stderr\nputs 'foo'", [], %w(foo))
+ end
+
+ def test_initialize
+ return unless defined?(Fcntl::F_GETFL)
+
+ t = make_tempfile
+
+ fd = IO.sysopen(t.path, "w")
+ assert_kind_of(Integer, fd)
+ %w[r r+ w+ a+].each do |mode|
+ assert_raise(Errno::EINVAL, "#{mode} [ruby-dev:38571]") {IO.new(fd, mode)}
+ end
+ f = IO.new(fd, "w")
+ f.write("FOO\n")
+ f.close
+
+ assert_equal("FOO\n", File.read(t.path))
+ end
+
+ def test_reinitialize
+ t = make_tempfile
+ f = open(t.path)
+ assert_raise(RuntimeError) do
+ f.instance_eval { initialize }
+ end
+ end
+
+ def test_new_with_block
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ assert_in_out_err([], "r, w = IO.pipe; IO.new(r) {}", [], /^.+$/)
+ end
+
+ def test_readline2
+ assert_in_out_err(["-e", <<-SRC], "foo\nbar\nbaz\n", %w(foo bar baz end), [])
+ puts readline
+ puts readline
+ puts readline
+ begin
+ puts readline
+ rescue EOFError
+ puts "end"
+ end
+ SRC
+ end
+
+ def test_readlines
+ assert_in_out_err(["-e", "p readlines"], "foo\nbar\nbaz\n",
+ ["[\"foo\\n\", \"bar\\n\", \"baz\\n\"]"], [])
+ end
+
+ def test_s_read
+ t = make_tempfile
+
+ assert_equal("foo\nbar\nbaz\n", File.read(t.path))
+ assert_equal("foo\nba", File.read(t.path, 6))
+ assert_equal("bar\n", File.read(t.path, 4, 4))
+ end
+
+ def test_uninitialized
+ assert_raise(IOError) { IO.allocate.print "" }
+ end
+
+ def test_nofollow
+ # O_NOFOLLOW is not standard.
+ return if /freebsd|linux/ !~ RUBY_PLATFORM
+ return unless defined? File::NOFOLLOW
+ mkcdtmpdir {
+ open("file", "w") {|f| f << "content" }
+ begin
+ File.symlink("file", "slnk")
+ rescue NotImplementedError
+ return
+ end
+ assert_raise(Errno::EMLINK, Errno::ELOOP) {
+ open("slnk", File::RDONLY|File::NOFOLLOW) {}
+ }
+ assert_raise(Errno::EMLINK, Errno::ELOOP) {
+ File.foreach("slnk", :open_args=>[File::RDONLY|File::NOFOLLOW]) {}
+ }
+ }
+ end
+
+ def test_tainted
+ t = make_tempfile
+ assert(File.read(t.path, 4).tainted?, '[ruby-dev:38826]')
+ assert(File.open(t.path) {|f| f.read(4)}.tainted?, '[ruby-dev:38826]')
+ end
+
+ def test_binmode_after_closed
+ t = make_tempfile
+ t.close
+ assert_raise(IOError) {t.binmode}
+ end
+
+ def test_threaded_flush
+ bug3585 = '[ruby-core:31348]'
+ src = %q{\
+ t = Thread.new { sleep 3 }
+ Thread.new {sleep 1; t.kill; p 'hi!'}
+ t.join
+ }.gsub(/^\s+/, '')
+ 10.times.map do
+ Thread.start do
+ assert_in_out_err([], src, [%q["hi!"]])
+ end
+ end.each {|th| th.join}
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_io_m17n.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_io_m17n.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_io_m17n.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1839 @@
+require 'test/unit'
+require 'tmpdir'
+require 'timeout'
+require_relative 'envutil'
+
+class TestIO_M17N < Test::Unit::TestCase
+ ENCS = [
+ Encoding::ASCII_8BIT,
+ Encoding::EUC_JP,
+ Encoding::Shift_JIS,
+ Encoding::UTF_8
+ ]
+
+ def with_tmpdir
+ Dir.mktmpdir {|dir|
+ Dir.chdir(dir) {
+ yield dir
+ }
+ }
+ end
+
+ def with_pipe(*args)
+ r, w = IO.pipe(*args)
+ begin
+ yield r, w
+ ensure
+ r.close if !r.closed?
+ w.close if !w.closed?
+ end
+ end
+
+ def generate_file(path, content)
+ open(path, "wb") {|f| f.write content }
+ end
+
+ def encdump(str)
+ "#{str.dump}.force_encoding(#{str.encoding.name.dump})"
+ end
+
+ def assert_str_equal(expected, actual, message=nil)
+ full_message = build_message(message, <<EOT)
+#{encdump expected} expected but not equal to
+#{encdump actual}.
+EOT
+ assert_block(full_message) { expected == actual }
+ end
+
+ def test_open_r
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r") {|f|
+ assert_equal(Encoding.default_external, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_rb
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "rb") {|f|
+ assert_equal(Encoding.find("ASCII-8BIT"), f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_r_enc
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r:euc-jp") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_r_enc_in_opt
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r", encoding: "euc-jp") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_r_enc_in_opt2
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r", external_encoding: "euc-jp") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_r_enc_enc
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r:euc-jp:utf-8") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_r_enc_enc_in_opt
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r", encoding: "euc-jp:utf-8") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_r_enc_enc_in_opt2
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r", external_encoding: "euc-jp", internal_encoding: "utf-8") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w
+ with_tmpdir {
+ open("tmp", "w") {|f|
+ assert_equal(nil, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_wb
+ with_tmpdir {
+ open("tmp", "wb") {|f|
+ assert_equal(Encoding.find("ASCII-8BIT"), f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc
+ with_tmpdir {
+ open("tmp", "w:euc-jp") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc_in_opt
+ with_tmpdir {
+ open("tmp", "w", encoding: "euc-jp") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc_in_opt2
+ with_tmpdir {
+ open("tmp", "w", external_encoding: "euc-jp") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc_enc
+ with_tmpdir {
+ open("tmp", "w:euc-jp:utf-8") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc_enc_in_opt
+ with_tmpdir {
+ open("tmp", "w", encoding: "euc-jp:utf-8") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc_enc_in_opt2
+ with_tmpdir {
+ open("tmp", "w", external_encoding: "euc-jp", internal_encoding: "utf-8") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc_enc_perm
+ with_tmpdir {
+ open("tmp", "w:euc-jp:utf-8", 0600) {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_io_new_enc
+ with_tmpdir {
+ generate_file("tmp", "\xa1")
+ fd = IO.sysopen("tmp")
+ f = IO.new(fd, "r:sjis")
+ begin
+ assert_equal(Encoding::Shift_JIS, f.read.encoding)
+ ensure
+ f.close
+ end
+ }
+ end
+
+ def test_s_pipe_invalid
+ with_pipe("utf-8", "euc-jp", :invalid=>:replace) {|r, w|
+ w << "\x80"
+ w.close
+ assert_equal("?", r.read)
+ }
+ end
+
+ def test_s_pipe_undef
+ with_pipe("utf-8:euc-jp", :undef=>:replace) {|r, w|
+ w << "\ufffd"
+ w.close
+ assert_equal("?", r.read)
+ }
+ end
+
+ def test_s_pipe_undef_replace_string
+ with_pipe("utf-8:euc-jp", :undef=>:replace, :replace=>"X") {|r, w|
+ w << "\ufffd"
+ w.close
+ assert_equal("X", r.read)
+ }
+ end
+
+ def test_dup
+ with_pipe("utf-8:euc-jp") {|r, w|
+ w << "\u3042"
+ w.close
+ r2 = r.dup
+ begin
+ assert_equal("\xA4\xA2".force_encoding("euc-jp"), r2.read)
+ ensure
+ r2.close
+ end
+
+ }
+ end
+
+ def test_dup_undef
+ with_pipe("utf-8:euc-jp", :undef=>:replace) {|r, w|
+ w << "\uFFFD"
+ w.close
+ r2 = r.dup
+ begin
+ assert_equal("?", r2.read)
+ ensure
+ r2.close
+ end
+ }
+ end
+
+ def test_stdin
+ assert_equal(Encoding.default_external, STDIN.external_encoding)
+ assert_equal(nil, STDIN.internal_encoding)
+ end
+
+ def test_stdout
+ assert_equal(nil, STDOUT.external_encoding)
+ assert_equal(nil, STDOUT.internal_encoding)
+ end
+
+ def test_stderr
+ assert_equal(nil, STDERR.external_encoding)
+ assert_equal(nil, STDERR.internal_encoding)
+ end
+
+ def test_terminator_conversion
+ with_tmpdir {
+ generate_file('tmp', "before \u00FF after")
+ s = open("tmp", "r:utf-8:iso-8859-1") {|f|
+ f.gets("\xFF".force_encoding("iso-8859-1"))
+ }
+ assert_equal(Encoding.find("iso-8859-1"), s.encoding)
+ assert_str_equal("before \xFF".force_encoding("iso-8859-1"), s, '[ruby-core:14288]')
+ }
+ end
+
+ def test_terminator_conversion2
+ with_tmpdir {
+ generate_file('tmp', "before \xA1\xA2\xA2\xA3 after")
+ s = open("tmp", "r:euc-jp:utf-8") {|f|
+ f.gets("\xA2\xA2".force_encoding("euc-jp").encode("utf-8"))
+ }
+ assert_equal(Encoding.find("utf-8"), s.encoding)
+ assert_str_equal("before \xA1\xA2\xA2\xA3 after".force_encoding("euc-jp").encode("utf-8"), s, '[ruby-core:14319]')
+ }
+ end
+
+ def test_terminator_stateful_conversion
+ with_tmpdir {
+ src = "before \e$B\x23\x30\x23\x31\e(B after".force_encoding("iso-2022-jp")
+ generate_file('tmp', src)
+ s = open("tmp", "r:iso-2022-jp:euc-jp") {|f|
+ f.gets("0".force_encoding("euc-jp"))
+ }
+ assert_equal(Encoding.find("euc-jp"), s.encoding)
+ assert_str_equal(src.encode("euc-jp"), s)
+ }
+ end
+
+ def test_nonascii_terminator
+ with_tmpdir {
+ generate_file('tmp', "before \xA2\xA2 after")
+ open("tmp", "r:euc-jp") {|f|
+ assert_raise(ArgumentError) {
+ f.gets("\xA2\xA2".force_encoding("utf-8"))
+ }
+ }
+ }
+ end
+
+ def test_pipe_terminator_conversion
+ with_pipe("euc-jp:utf-8") {|r, w|
+ w.write "before \xa2\xa2 after"
+ rs = "\xA2\xA2".encode("utf-8", "euc-jp")
+ w.close
+ timeout(1) {
+ assert_equal("before \xa2\xa2".encode("utf-8", "euc-jp"),
+ r.gets(rs))
+ }
+ }
+ end
+
+ def test_pipe_conversion
+ with_pipe("euc-jp:utf-8") {|r, w|
+ w.write "\xa1\xa1"
+ assert_equal("\xa1\xa1".encode("utf-8", "euc-jp"), r.getc)
+ }
+ end
+
+ def test_pipe_convert_partial_read
+ with_pipe("euc-jp:utf-8") {|r, w|
+ begin
+ t = Thread.new {
+ w.write "\xa1"
+ sleep 0.1
+ w.write "\xa1"
+ }
+ assert_equal("\xa1\xa1".encode("utf-8", "euc-jp"), r.getc)
+ ensure
+ t.join if t
+ end
+ }
+ end
+
+ def test_getc_invalid
+ with_pipe("euc-jp:utf-8") {|r, w|
+ w << "\xa1xyz"
+ w.close
+ err = assert_raise(Encoding::InvalidByteSequenceError) { r.getc }
+ assert_equal("\xA1".force_encoding("ascii-8bit"), err.error_bytes)
+ assert_equal("xyz", r.read(10))
+ }
+ end
+
+ def test_getc_stateful_conversion
+ with_tmpdir {
+ src = "\e$B\x23\x30\x23\x31\e(B".force_encoding("iso-2022-jp")
+ generate_file('tmp', src)
+ open("tmp", "r:iso-2022-jp:euc-jp") {|f|
+ assert_equal("\xa3\xb0".force_encoding("euc-jp"), f.getc)
+ assert_equal("\xa3\xb1".force_encoding("euc-jp"), f.getc)
+ }
+ }
+ end
+
+ def test_getc_newlineconv
+ with_tmpdir {
+ src = "\u3042"
+ generate_file('tmp', src)
+ defext = Encoding.default_external
+ Encoding.default_external = Encoding::UTF_8
+ open("tmp", "rt") {|f|
+ s = f.getc
+ assert_equal(true, s.valid_encoding?)
+ assert_equal("\u3042", s)
+ }
+ Encoding.default_external = defext
+ }
+ end
+
+ def test_getc_newlineconv_invalid
+ with_tmpdir {
+ src = "\xE3\x81"
+ generate_file('tmp', src)
+ defext = Encoding.default_external
+ Encoding.default_external = Encoding::UTF_8
+ open("tmp", "rt") {|f|
+ s = f.getc
+ assert_equal(false, s.valid_encoding?)
+ assert_equal("\xE3".force_encoding("UTF-8"), s)
+ s = f.getc
+ assert_equal(false, s.valid_encoding?)
+ assert_equal("\x81".force_encoding("UTF-8"), s)
+ }
+ Encoding.default_external = defext
+ }
+ end
+
+ def test_ungetc_stateful_conversion
+ with_tmpdir {
+ src = "before \e$B\x23\x30\x23\x31\e(B after".force_encoding("iso-2022-jp")
+ generate_file('tmp', src)
+ s = open("tmp", "r:iso-2022-jp:euc-jp") {|f|
+ f.ungetc("0".force_encoding("euc-jp"))
+ f.read
+ }
+ assert_equal(Encoding.find("euc-jp"), s.encoding)
+ assert_str_equal("0" + src.encode("euc-jp"), s)
+ }
+ end
+
+ def test_ungetc_stateful_conversion2
+ with_tmpdir {
+ src = "before \e$B\x23\x30\x23\x31\e(B after".force_encoding("iso-2022-jp")
+ former = "before \e$B\x23\x30\e(B".force_encoding("iso-2022-jp")
+ rs = "\e$B\x23\x30\e(B".force_encoding("iso-2022-jp")
+ latter = "\e$B\x23\x31\e(B after".force_encoding("iso-2022-jp")
+ generate_file('tmp', src)
+ s = open("tmp", "r:iso-2022-jp:euc-jp") {|f|
+ assert_equal(former.encode("euc-jp", "iso-2022-jp"),
+ f.gets(rs.encode("euc-jp", "iso-2022-jp")))
+ f.ungetc("0")
+ f.read
+ }
+ assert_equal(Encoding.find("euc-jp"), s.encoding)
+ assert_str_equal("0" + latter.encode("euc-jp"), s)
+ }
+ end
+
+ def test_open_ascii
+ with_tmpdir {
+ src = "abc\n"
+ generate_file('tmp', "abc\n")
+ ENCS.each {|enc|
+ s = open('tmp', "r:#{enc}") {|f| f.gets }
+ assert_equal(enc, s.encoding)
+ assert_str_equal(src, s)
+ }
+ }
+ end
+
+ def test_open_nonascii
+ with_tmpdir {
+ src = "\xc2\xa1\n"
+ generate_file('tmp', src)
+ ENCS.each {|enc|
+ content = src.dup.force_encoding(enc)
+ s = open('tmp', "r:#{enc}") {|f| f.gets }
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content, s)
+ }
+ }
+ end
+
+ def test_read_encoding
+ with_tmpdir {
+ src = "\xc2\xa1\n".force_encoding("ASCII-8BIT")
+ generate_file('tmp', "\xc2\xa1\n")
+ ENCS.each {|enc|
+ content = src.dup.force_encoding(enc)
+ open('tmp', "r:#{enc}") {|f|
+ s = f.getc
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content[0], s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.readchar
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content[0], s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.gets
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content, s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.readline
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content, s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ lines = f.readlines
+ assert_equal(1, lines.length)
+ s = lines[0]
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content, s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ f.each_line {|s|
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content, s)
+ }
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.read
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content, s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.read(1)
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_str_equal(src[0], s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.readpartial(1)
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_str_equal(src[0], s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.sysread(1)
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_str_equal(src[0], s)
+ }
+ }
+ }
+ end
+
+ def test_write_noenc
+ src = "\xc2\xa1\n".force_encoding("ascii-8bit")
+ with_tmpdir {
+ open('tmp', "w") {|f|
+ ENCS.each {|enc|
+ f.write src.dup.force_encoding(enc)
+ }
+ }
+ open('tmp', 'r:ascii-8bit') {|f|
+ assert_equal(src*ENCS.length, f.read)
+ }
+ }
+ end
+
+ def test_write_conversion
+ utf8 = "\u6666"
+ eucjp = "\xb3\xa2".force_encoding("EUC-JP")
+ with_tmpdir {
+ open('tmp', "w:EUC-JP") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ f.print utf8
+ }
+ assert_equal(eucjp, File.read('tmp').force_encoding("EUC-JP"))
+ open('tmp', 'r:EUC-JP:UTF-8') {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ assert_equal(utf8, f.read)
+ }
+ }
+ end
+
+ def test_pipe
+ utf8 = "\u6666"
+ eucjp = "\xb3\xa2".force_encoding("EUC-JP")
+
+ with_pipe {|r,w|
+ assert_equal(Encoding.default_external, r.external_encoding)
+ assert_equal(nil, r.internal_encoding)
+ w << utf8
+ w.close
+ s = r.read
+ assert_equal(Encoding.default_external, s.encoding)
+ assert_str_equal(utf8.dup.force_encoding(Encoding.default_external), s)
+ }
+
+ with_pipe("EUC-JP") {|r,w|
+ assert_equal(Encoding::EUC_JP, r.external_encoding)
+ assert_equal(nil, r.internal_encoding)
+ w << eucjp
+ w.close
+ assert_equal(eucjp, r.read)
+ }
+
+ with_pipe("UTF-8") {|r,w|
+ w << "a" * 1023 + "\u3042" + "a" * 1022
+ w.close
+ assert_equal(true, r.read.valid_encoding?)
+ }
+
+ with_pipe("UTF-8:EUC-JP") {|r,w|
+ assert_equal(Encoding::UTF_8, r.external_encoding)
+ assert_equal(Encoding::EUC_JP, r.internal_encoding)
+ w << utf8
+ w.close
+ assert_equal(eucjp, r.read)
+ }
+
+ e = assert_raise(ArgumentError) {with_pipe("UTF-8", "UTF-8".encode("UTF-32BE")) {}}
+ assert_match(/invalid name encoding/, e.message)
+ e = assert_raise(ArgumentError) {with_pipe("UTF-8".encode("UTF-32BE")) {}}
+ assert_match(/invalid name encoding/, e.message)
+
+ ENCS.each {|enc|
+ with_pipe(enc) {|r, w|
+ w << "\xc2\xa1"
+ w.close
+ s = r.getc
+ assert_equal(enc, s.encoding)
+ }
+ }
+
+ ENCS.each {|enc|
+ next if enc == Encoding::ASCII_8BIT
+ next if enc == Encoding::UTF_8
+ with_pipe("#{enc}:UTF-8") {|r, w|
+ w << "\xc2\xa1"
+ w.close
+ s = r.read
+ assert_equal(Encoding::UTF_8, s.encoding)
+ assert_equal(s.encode("UTF-8"), s)
+ }
+ }
+
+ end
+
+ def test_marshal
+ with_pipe("EUC-JP") {|r, w|
+ data = 56225
+ Marshal.dump(data, w)
+ w.close
+ result = nil
+ assert_nothing_raised("[ruby-dev:33264]") { result = Marshal.load(r) }
+ assert_equal(data, result)
+ }
+ end
+
+ def test_gets_nil
+ with_pipe("UTF-8:EUC-JP") {|r, w|
+ w << "\u{3042}"
+ w.close
+ result = r.gets(nil)
+ assert_equal("\u{3042}".encode("euc-jp"), result)
+ }
+ end
+
+ def test_gets_limit
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.gets(1))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.gets(2))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4".force_encoding("euc-jp"), r.gets(3))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4".force_encoding("euc-jp"), r.gets(4))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4\xa4\xa6".force_encoding("euc-jp"), r.gets(5))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4\xa4\xa6".force_encoding("euc-jp"), r.gets(6))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4\xa4\xa6\n".force_encoding("euc-jp"), r.gets(7))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4\xa4\xa6\n".force_encoding("euc-jp"), r.gets(8))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4\xa4\xa6\n".force_encoding("euc-jp"), r.gets(9))
+ }
+ end
+
+ def test_gets_invalid
+ with_pipe("utf-8:euc-jp") {|r, w|
+ before = "\u{3042}\u{3044}"
+ invalid = "\x80".force_encoding("utf-8")
+ after = "\u{3046}\u{3048}"
+ w << before + invalid + after
+ w.close
+ err = assert_raise(Encoding::InvalidByteSequenceError) { r.gets }
+ assert_equal(invalid.force_encoding("ascii-8bit"), err.error_bytes)
+ assert_equal(after.encode("euc-jp"), r.gets)
+ }
+ end
+
+ def test_getc_invalid2
+ with_pipe("utf-8:euc-jp") {|r, w|
+ before1 = "\u{3042}"
+ before2 = "\u{3044}"
+ invalid = "\x80".force_encoding("utf-8")
+ after1 = "\u{3046}"
+ after2 = "\u{3048}"
+ w << before1 + before2 + invalid + after1 + after2
+ w.close
+ assert_equal(before1.encode("euc-jp"), r.getc)
+ assert_equal(before2.encode("euc-jp"), r.getc)
+ err = assert_raise(Encoding::InvalidByteSequenceError) { r.getc }
+ assert_equal(invalid.force_encoding("ascii-8bit"), err.error_bytes)
+ assert_equal(after1.encode("euc-jp"), r.getc)
+ assert_equal(after2.encode("euc-jp"), r.getc)
+ }
+ end
+
+ def test_getc_invalid3
+ skip("[BUG : #???] Assertion")
+
+ with_pipe("utf-16le:euc-jp", binmode: true) {|r, w|
+ before1 = "\x42\x30".force_encoding("utf-16le")
+ before2 = "\x44\x30".force_encoding("utf-16le")
+ invalid = "\x00\xd8".force_encoding("utf-16le")
+ after1 = "\x46\x30".force_encoding("utf-16le")
+ after2 = "\x48\x30".force_encoding("utf-16le")
+ w << before1 + before2 + invalid + after1 + after2
+ w.close
+ assert_equal(before1.encode("euc-jp"), r.getc)
+ assert_equal(before2.encode("euc-jp"), r.getc)
+ err = assert_raise(Encoding::InvalidByteSequenceError) { r.getc }
+ assert_equal(invalid.force_encoding("ascii-8bit"), err.error_bytes)
+ assert_equal(after1.encode("euc-jp"), r.getc)
+ assert_equal(after2.encode("euc-jp"), r.getc)
+ }
+ end
+
+ def test_read_all
+ with_pipe("utf-8:euc-jp") {|r, w|
+ str = "\u3042\u3044"
+ w << str
+ w.close
+ assert_equal(str.encode("euc-jp"), r.read)
+ }
+ end
+
+ def test_read_all_invalid
+ with_pipe("utf-8:euc-jp") {|r, w|
+ before = "\u{3042}\u{3044}"
+ invalid = "\x80".force_encoding("utf-8")
+ after = "\u{3046}\u{3048}"
+ w << before + invalid + after
+ w.close
+ err = assert_raise(Encoding::InvalidByteSequenceError) { r.read }
+ assert_equal(invalid.force_encoding("ascii-8bit"), err.error_bytes)
+ assert_equal(after.encode("euc-jp"), r.read)
+ }
+ end
+
+ def test_file_foreach
+ with_tmpdir {
+ generate_file('tst', 'a' * 8191 + "\xa1\xa1")
+ assert_nothing_raised {
+ File.foreach('tst', :encoding=>"euc-jp") {|line| line.inspect }
+ }
+ }
+ end
+
+ def test_set_encoding
+ with_pipe("utf-8:euc-jp") {|r, w|
+ s = "\u3042".force_encoding("ascii-8bit")
+ s << "\x82\xa0".force_encoding("ascii-8bit")
+ w << s
+ w.close
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.getc)
+ r.set_encoding("shift_jis:euc-jp")
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.getc)
+ }
+ end
+
+ def test_set_encoding2
+ with_pipe("utf-8:euc-jp") {|r, w|
+ s = "\u3042".force_encoding("ascii-8bit")
+ s << "\x82\xa0".force_encoding("ascii-8bit")
+ w << s
+ w.close
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.getc)
+ r.set_encoding("shift_jis", "euc-jp")
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.getc)
+ }
+ end
+
+ def test_set_encoding_nil
+ with_pipe("utf-8:euc-jp") {|r, w|
+ s = "\u3042".force_encoding("ascii-8bit")
+ s << "\x82\xa0".force_encoding("ascii-8bit")
+ w << s
+ w.close
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.getc)
+ r.set_encoding(nil)
+ assert_equal("\x82\xa0".force_encoding(Encoding.default_external), r.read)
+ }
+ end
+
+ def test_set_encoding_enc
+ with_pipe("utf-8:euc-jp") {|r, w|
+ s = "\u3042".force_encoding("ascii-8bit")
+ s << "\x82\xa0".force_encoding("ascii-8bit")
+ w << s
+ w.close
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.getc)
+ r.set_encoding(Encoding::Shift_JIS)
+ assert_equal("\x82\xa0".force_encoding(Encoding::Shift_JIS), r.getc)
+ }
+ end
+
+ def test_set_encoding_invalid
+ with_pipe {|r, w|
+ w << "\x80"
+ w.close
+ r.set_encoding("utf-8:euc-jp", :invalid=>:replace)
+ assert_equal("?", r.read)
+ }
+ end
+
+ def test_set_encoding_undef
+ with_pipe {|r, w|
+ w << "\ufffd"
+ w.close
+ r.set_encoding("utf-8", "euc-jp", :undef=>:replace)
+ assert_equal("?", r.read)
+ }
+ end
+
+ def test_set_encoding_undef_replace
+ with_pipe {|r, w|
+ w << "\ufffd"
+ w.close
+ r.set_encoding("utf-8", "euc-jp", :undef=>:replace, :replace=>"ZZZ")
+ assert_equal("ZZZ", r.read)
+ }
+ with_pipe {|r, w|
+ w << "\ufffd"
+ w.close
+ r.set_encoding("utf-8:euc-jp", :undef=>:replace, :replace=>"ZZZ")
+ assert_equal("ZZZ", r.read)
+ }
+ end
+
+ def test_set_encoding_binmode
+ assert_raise(ArgumentError) {
+ open(__FILE__, "rt") {|f|
+ f.set_encoding("iso-2022-jp")
+ }
+ }
+ assert_raise(ArgumentError) {
+ open(__FILE__, "r") {|f|
+ f.set_encoding("iso-2022-jp")
+ }
+ }
+ assert_nothing_raised {
+ open(__FILE__, "rb") {|f|
+ f.set_encoding("iso-2022-jp")
+ }
+ }
+ assert_nothing_raised {
+ open(__FILE__, "r") {|f|
+ f.binmode
+ f.set_encoding("iso-2022-jp")
+ }
+ }
+ assert_nothing_raised {
+ open(__FILE__, "rt") {|f|
+ f.binmode
+ f.set_encoding("iso-2022-jp")
+ }
+ }
+ end
+
+ def test_write_conversion_fixenc
+ with_pipe {|r, w|
+ w.set_encoding("iso-2022-jp:utf-8")
+ t = Thread.new { r.read.force_encoding("ascii-8bit") }
+ w << "\u3042"
+ w << "\u3044"
+ w.close
+ assert_equal("\e$B$\"$$\e(B".force_encoding("ascii-8bit"), t.value)
+ }
+ end
+
+ def test_write_conversion_anyenc_stateful
+ with_pipe {|r, w|
+ w.set_encoding("iso-2022-jp")
+ t = Thread.new { r.read.force_encoding("ascii-8bit") }
+ w << "\u3042"
+ w << "\x82\xa2".force_encoding("sjis")
+ w.close
+ assert_equal("\e$B$\"$$\e(B".force_encoding("ascii-8bit"), t.value)
+ }
+ end
+
+ def test_write_conversion_anyenc_stateless
+ with_pipe {|r, w|
+ w.set_encoding("euc-jp")
+ t = Thread.new { r.read.force_encoding("ascii-8bit") }
+ w << "\u3042"
+ w << "\x82\xa2".force_encoding("sjis")
+ w.close
+ assert_equal("\xa4\xa2\xa4\xa4".force_encoding("ascii-8bit"), t.value)
+ }
+ end
+
+ def test_write_conversion_anyenc_stateful_nosync
+ with_pipe {|r, w|
+ w.sync = false
+ w.set_encoding("iso-2022-jp")
+ t = Thread.new { r.read.force_encoding("ascii-8bit") }
+ w << "\u3042"
+ w << "\x82\xa2".force_encoding("sjis")
+ w.close
+ assert_equal("\e$B$\"$$\e(B".force_encoding("ascii-8bit"), t.value)
+ }
+ end
+
+ def test_read_stateful
+ with_pipe("euc-jp:iso-2022-jp") {|r, w|
+ w << "\xA4\xA2"
+ w.close
+ assert_equal("\e$B$\"\e(B".force_encoding("iso-2022-jp"), r.read)
+ }
+ end
+
+ def test_stdin_external_encoding_with_reopen
+ skip "passing non-stdio fds is not supported" if /mswin|mingw/ =~ RUBY_PLATFORM
+ with_tmpdir {
+ open("tst", "w+") {|f|
+ pid = spawn(EnvUtil.rubybin, '-e', <<-'End', 10=>f)
+ io = IO.new(10, "r+")
+ STDIN.reopen(io)
+ STDIN.external_encoding
+ STDIN.write "\u3042"
+ STDIN.flush
+ End
+ Process.wait pid
+ f.rewind
+ result = f.read.force_encoding("ascii-8bit")
+ assert_equal("\u3042".force_encoding("ascii-8bit"), result)
+ }
+ }
+ end
+
+ def test_popen_r_enc
+ IO.popen("#{EnvUtil.rubybin} -e 'putc 255'", "r:ascii-8bit") {|f|
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ end
+
+ def test_popen_r_enc_in_opt
+ IO.popen("#{EnvUtil.rubybin} -e 'putc 255'", "r", encoding: "ascii-8bit") {|f|
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ end
+
+ def test_popen_r_enc_in_opt2
+ IO.popen("#{EnvUtil.rubybin} -e 'putc 255'", "r", external_encoding: "ascii-8bit") {|f|
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ end
+
+ def test_popen_r_enc_enc
+ IO.popen("#{EnvUtil.rubybin} -e 'putc 0xa1'", "r:shift_jis:euc-jp") {|f|
+ assert_equal(Encoding::Shift_JIS, f.external_encoding)
+ assert_equal(Encoding::EUC_JP, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\x8e\xa1".force_encoding("euc-jp"), s)
+ }
+ end
+
+ def test_popen_r_enc_enc_in_opt
+ IO.popen("#{EnvUtil.rubybin} -e 'putc 0xa1'", "r", encoding: "shift_jis:euc-jp") {|f|
+ assert_equal(Encoding::Shift_JIS, f.external_encoding)
+ assert_equal(Encoding::EUC_JP, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\x8e\xa1".force_encoding("euc-jp"), s)
+ }
+ end
+
+ def test_popen_r_enc_enc_in_opt2
+ IO.popen("#{EnvUtil.rubybin} -e 'putc 0xa1'", "r", external_encoding: "shift_jis", internal_encoding: "euc-jp") {|f|
+ assert_equal(Encoding::Shift_JIS, f.external_encoding)
+ assert_equal(Encoding::EUC_JP, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\x8e\xa1".force_encoding("euc-jp"), s)
+ }
+ end
+
+ def test_popenv_r_enc_enc_in_opt2
+ IO.popen([EnvUtil.rubybin, "-e", "putc 0xa1"], "r", external_encoding: "shift_jis", internal_encoding: "euc-jp") {|f|
+ assert_equal(Encoding::Shift_JIS, f.external_encoding)
+ assert_equal(Encoding::EUC_JP, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\x8e\xa1".force_encoding("euc-jp"), s)
+ }
+ end
+
+ def test_open_pipe_r_enc
+ open("|#{EnvUtil.rubybin} -e 'putc 255'", "r:ascii-8bit") {|f|
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ end
+
+ def test_s_foreach_enc
+ with_tmpdir {
+ generate_file("t", "\xff")
+ IO.foreach("t", :mode => "r:ascii-8bit") {|s|
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_enc_in_opt
+ with_tmpdir {
+ generate_file("t", "\xff")
+ IO.foreach("t", :encoding => "ascii-8bit") {|s|
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_enc_in_opt2
+ with_tmpdir {
+ generate_file("t", "\xff")
+ IO.foreach("t", :external_encoding => "ascii-8bit") {|s|
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_enc_enc
+ with_tmpdir {
+ generate_file("t", "\u3042")
+ IO.foreach("t", :mode => "r:utf-8:euc-jp") {|s|
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_enc_enc_in_opt
+ with_tmpdir {
+ generate_file("t", "\u3042")
+ IO.foreach("t", :mode => "r", :encoding => "utf-8:euc-jp") {|s|
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_enc_enc_in_opt2
+ with_tmpdir {
+ generate_file("t", "\u3042")
+ IO.foreach("t", :mode => "r", :external_encoding => "utf-8", :internal_encoding => "euc-jp") {|s|
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_open_args_enc
+ with_tmpdir {
+ generate_file("t", "\xff")
+ IO.foreach("t", :open_args => ["r:ascii-8bit"]) {|s|
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_open_args_enc_in_opt
+ with_tmpdir {
+ generate_file("t", "\xff")
+ IO.foreach("t", :open_args => ["r", encoding: "ascii-8bit"]) {|s|
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_open_args_enc_in_opt2
+ with_tmpdir {
+ generate_file("t", "\xff")
+ IO.foreach("t", :open_args => ["r", external_encoding: "ascii-8bit"]) {|s|
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_open_args_enc_enc
+ with_tmpdir {
+ generate_file("t", "\u3042")
+ IO.foreach("t", :open_args => ["r:utf-8:euc-jp"]) {|s|
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_open_args_enc_enc_in_opt
+ with_tmpdir {
+ generate_file("t", "\u3042")
+ IO.foreach("t", :open_args => ["r", encoding: "utf-8:euc-jp"]) {|s|
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_open_args_enc_enc_in_opt2
+ with_tmpdir {
+ generate_file("t", "\u3042")
+ IO.foreach("t", :open_args => ["r", external_encoding: "utf-8", internal_encoding: "euc-jp"]) {|s|
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), s)
+ }
+ }
+ end
+
+ def test_both_textmode_binmode
+ assert_raise(ArgumentError) { open("not-exist", "r", :textmode=>true, :binmode=>true) }
+ end
+
+ def test_textmode_decode_universal_newline_read
+ with_tmpdir {
+ generate_file("t.crlf", "a\r\nb\r\nc\r\n")
+ assert_equal("a\nb\nc\n", File.read("t.crlf", mode:"rt:euc-jp:utf-8"))
+ assert_equal("a\nb\nc\n", File.read("t.crlf", mode:"rt"))
+ open("t.crlf", "rt:euc-jp:utf-8") {|f| assert_equal("a\nb\nc\n", f.read) }
+ open("t.crlf", "rt") {|f| assert_equal("a\nb\nc\n", f.read) }
+ open("t.crlf", "r", :textmode=>true) {|f| assert_equal("a\nb\nc\n", f.read) }
+
+ generate_file("t.cr", "a\rb\rc\r")
+ assert_equal("a\nb\nc\n", File.read("t.cr", mode:"rt:euc-jp:utf-8"))
+ assert_equal("a\nb\nc\n", File.read("t.cr", mode:"rt"))
+
+ generate_file("t.lf", "a\nb\nc\n")
+ assert_equal("a\nb\nc\n", File.read("t.cr", mode:"rt:euc-jp:utf-8"))
+ assert_equal("a\nb\nc\n", File.read("t.cr", mode:"rt"))
+ }
+ end
+
+ def test_textmode_decode_universal_newline_getc
+ with_tmpdir {
+ generate_file("t.crlf", "a\r\nb\r\nc\r\n")
+ open("t.crlf", "rt") {|f|
+ assert_equal("a", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("b", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("c", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal(nil, f.getc)
+ }
+
+ generate_file("t.cr", "a\rb\rc\r")
+ open("t.cr", "rt") {|f|
+ assert_equal("a", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("b", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("c", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal(nil, f.getc)
+ }
+
+ generate_file("t.lf", "a\nb\nc\n")
+ open("t.lf", "rt") {|f|
+ assert_equal("a", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("b", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("c", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal(nil, f.getc)
+ }
+ }
+ end
+
+ def test_textmode_decode_universal_newline_gets
+ with_tmpdir {
+ generate_file("t.crlf", "a\r\nb\r\nc\r\n")
+ open("t.crlf", "rt") {|f|
+ assert_equal("a\n", f.gets)
+ assert_equal("b\n", f.gets)
+ assert_equal("c\n", f.gets)
+ assert_equal(nil, f.gets)
+ }
+
+ generate_file("t.cr", "a\rb\rc\r")
+ open("t.cr", "rt") {|f|
+ assert_equal("a\n", f.gets)
+ assert_equal("b\n", f.gets)
+ assert_equal("c\n", f.gets)
+ assert_equal(nil, f.gets)
+ }
+
+ generate_file("t.lf", "a\nb\nc\n")
+ open("t.lf", "rt") {|f|
+ assert_equal("a\n", f.gets)
+ assert_equal("b\n", f.gets)
+ assert_equal("c\n", f.gets)
+ assert_equal(nil, f.gets)
+ }
+ }
+ end
+
+ def test_textmode_decode_universal_newline_utf16
+ with_tmpdir {
+ generate_file("t.utf16be.crlf", "\0a\0\r\0\n\0b\0\r\0\n\0c\0\r\0\n")
+ assert_equal("a\nb\nc\n", File.read("t.utf16be.crlf", mode:"rt:utf-16be:utf-8"))
+
+ generate_file("t.utf16le.crlf", "a\0\r\0\n\0b\0\r\0\n\0c\0\r\0\n\0")
+ assert_equal("a\nb\nc\n", File.read("t.utf16le.crlf", mode:"rt:utf-16le:utf-8"))
+
+ generate_file("t.utf16be.cr", "\0a\0\r\0b\0\r\0c\0\r")
+ assert_equal("a\nb\nc\n", File.read("t.utf16be.cr", mode:"rt:utf-16be:utf-8"))
+
+ generate_file("t.utf16le.cr", "a\0\r\0b\0\r\0c\0\r\0")
+ assert_equal("a\nb\nc\n", File.read("t.utf16le.cr", mode:"rt:utf-16le:utf-8"))
+
+ generate_file("t.utf16be.lf", "\0a\0\n\0b\0\n\0c\0\n")
+ assert_equal("a\nb\nc\n", File.read("t.utf16be.lf", mode:"rt:utf-16be:utf-8"))
+
+ generate_file("t.utf16le.lf", "a\0\n\0b\0\n\0c\0\n\0")
+ assert_equal("a\nb\nc\n", File.read("t.utf16le.lf", mode:"rt:utf-16le:utf-8"))
+ }
+ end
+
+ SYSTEM_NEWLINE = []
+ def system_newline
+ return SYSTEM_NEWLINE.first if !SYSTEM_NEWLINE.empty?
+ with_tmpdir {
+ open("newline", "wt") {|f|
+ f.print "\n"
+ }
+ open("newline", "rb") {|f|
+ SYSTEM_NEWLINE << f.read
+ }
+ }
+ SYSTEM_NEWLINE.first
+ end
+
+ def test_textmode_encode_newline
+ with_tmpdir {
+ open("t.txt", "wt") {|f|
+ f.puts "abc"
+ f.puts "def"
+ }
+ content = File.read("t.txt", :mode=>"rb")
+ nl = system_newline
+ assert_equal("abc#{nl}def#{nl}", content)
+ }
+ end
+
+ def test_textmode_encode_newline_enc
+ with_tmpdir {
+ open("t.txt", "wt:euc-jp") {|f|
+ f.puts "abc\u3042"
+ f.puts "def\u3044"
+ }
+ content = File.read("t.txt", :mode=>"rb:ascii-8bit")
+ nl = system_newline
+ assert_equal("abc\xA4\xA2#{nl}def\xA4\xA4#{nl}", content)
+ }
+ end
+
+ def test_read_newline_conversion_with_encoding_conversion
+ with_tmpdir {
+ generate_file("t.utf8.crlf", "a\r\nb\r\n")
+ open("t.utf8.crlf", "rb:utf-8:utf-16be") {|f|
+ content = f.read
+ assert_equal("\0a\0\r\0\n\0b\0\r\0\n".force_encoding("UTF-16BE"), content)
+ }
+ open("t.utf8.crlf", "rt:utf-8:utf-16be") {|f|
+ content = f.read
+ assert_equal("\0a\0\n\0b\0\n".force_encoding("UTF-16BE"), content)
+ }
+ open("t.utf8.crlf", "r:utf-8:utf-16be") {|f|
+ content = f.read
+ if system_newline == "\n"
+ assert_equal("\0a\0\r\0\n\0b\0\r\0\n".force_encoding("UTF-16BE"), content)
+ else
+ assert_equal("\0a\0\n\0b\0\n".force_encoding("UTF-16BE"), content)
+ end
+ }
+ }
+ end
+
+ def test_read_newline_conversion_without_encoding_conversion
+ with_tmpdir {
+ generate_file("t.utf16.crlf", "\0a\0\r\0\n\0b\0\r\0\n")
+ open("t.utf16.crlf", "rb:utf-16be") {|f|
+ content = f.read
+ assert_equal("\0a\0\r\0\n\0b\0\r\0\n".force_encoding("UTF-16BE"),
+ content)
+ }
+ }
+ end
+
+ def test_read_newline_conversion_error
+ with_tmpdir {
+ generate_file("empty.txt", "")
+ # ascii incompatible encoding without conversion needs binmode.
+ assert_raise(ArgumentError) {
+ open("empty.txt", "rt:utf-16be") {|f| }
+ }
+ assert_raise(ArgumentError) {
+ open("empty.txt", "r:utf-16be") {|f| }
+ }
+ }
+ end
+
+ def test_read_mode
+ with_tmpdir {
+ generate_file("t", "a\rb\r\nc\n\xc2\xa2")
+ generate_file("ie", "a\rb\r\nc\n\e$B\x42\x22\e(B")
+ generate_file("iu", "a\rb\r\nc\n\e$B\x21\x71\e(B")
+ generate_file("be", "\0a\0\r\0b\0\r\0\n\0c\0\n\x85\x35")
+ generate_file("bu", "\0a\0\r\0b\0\r\0\n\0c\0\n\0\xa2")
+ # "\xc2\xa2" is valid as EUC-JP and UTF-8
+ # EUC-JP UTF-8 Unicode
+ # 0xC2A2 0xE894B5 U+8535
+ # 0xA1F1 0xC2A2 U+00A2
+
+ open("t","rt") {|f| assert_equal("a\nb\nc\n\xc2\xa2".force_encoding(Encoding.default_external), f.read) }
+ open("t","rb") {|f| assert_equal("a\rb\r\nc\n\xc2\xa2".force_encoding(Encoding::ASCII_8BIT), f.read) }
+
+ open("t","rt:euc-jp") {|f| assert_equal("a\nb\nc\n\xc2\xa2".force_encoding("EUC-JP"), f.read) }
+ open("t","rb:euc-jp") {|f| assert_equal("a\rb\r\nc\n\xc2\xa2".force_encoding("EUC-JP"), f.read) }
+ open("t","rt:utf-8") {|f| assert_equal("a\nb\nc\n\xc2\xa2".force_encoding("UTF-8"), f.read) }
+ open("t","rb:utf-8") {|f| assert_equal("a\rb\r\nc\n\xc2\xa2".force_encoding("UTF-8"), f.read) }
+ assert_raise(ArgumentError) { open("t", "rt:iso-2022-jp") {|f| } }
+ open("t","rb:iso-2022-jp") {|f| assert_equal("a\rb\r\nc\n\xc2\xa2".force_encoding("ISO-2022-JP"), f.read) }
+
+ open("t","rt:euc-jp:utf-8") {|f| assert_equal("a\nb\nc\n\u8535", f.read) }
+ open("t","rt:utf-8:euc-jp") {|f| assert_equal("a\nb\nc\n\xa1\xf1".force_encoding("EUC-JP"), f.read) }
+ open("t","rb:euc-jp:utf-8") {|f| assert_equal("a\rb\r\nc\n\u8535", f.read) }
+ open("t","rb:utf-8:euc-jp") {|f| assert_equal("a\rb\r\nc\n\xa1\xf1".force_encoding("EUC-JP"), f.read) }
+
+ open("t","rt:euc-jp:iso-2022-jp"){|f| assert_equal("a\nb\nc\n\e$B\x42\x22\e(B".force_encoding("ISO-2022-JP"), f.read) }
+ open("t","rt:utf-8:iso-2022-jp"){|f| assert_equal("a\nb\nc\n\e$B\x21\x71\e(B".force_encoding("ISO-2022-JP"), f.read) }
+ open("t","rt:euc-jp:utf-16be"){|f| assert_equal("\0a\0\n\0b\0\n\0c\0\n\x85\x35".force_encoding("UTF-16BE"), f.read) }
+ open("t","rt:utf-8:utf-16be"){|f| assert_equal("\0a\0\n\0b\0\n\0c\0\n\0\xa2".force_encoding("UTF-16BE"), f.read) }
+ open("t","rb:euc-jp:iso-2022-jp"){|f|assert_equal("a\rb\r\nc\n\e$B\x42\x22\e(B".force_encoding("ISO-2022-JP"),f.read)}
+ open("t","rb:utf-8:iso-2022-jp"){|f|assert_equal("a\rb\r\nc\n\e$B\x21\x71\e(B".force_encoding("ISO-2022-JP"),f.read)}
+ open("t","rb:euc-jp:utf-16be"){|f|assert_equal("\0a\0\r\0b\0\r\0\n\0c\0\n\x85\x35".force_encoding("UTF-16BE"),f.read)}
+ open("t","rb:utf-8:utf-16be"){|f|assert_equal("\0a\0\r\0b\0\r\0\n\0c\0\n\0\xa2".force_encoding("UTF-16BE"),f.read)}
+
+ open("ie","rt:iso-2022-jp:euc-jp"){|f| assert_equal("a\nb\nc\n\xc2\xa2".force_encoding("EUC-JP"), f.read) }
+ open("iu","rt:iso-2022-jp:utf-8"){|f| assert_equal("a\nb\nc\n\xc2\xa2".force_encoding("UTF-8"), f.read) }
+ open("be","rt:utf-16be:euc-jp"){|f| assert_equal("a\nb\nc\n\xc2\xa2".force_encoding("EUC-JP"), f.read) }
+ open("bu","rt:utf-16be:utf-8"){|f| assert_equal("a\nb\nc\n\xc2\xa2".force_encoding("UTF-8"), f.read) }
+ open("ie","rb:iso-2022-jp:euc-jp"){|f|assert_equal("a\rb\r\nc\n\xc2\xa2".force_encoding("EUC-JP"),f.read)}
+ open("iu","rb:iso-2022-jp:utf-8"){|f|assert_equal("a\rb\r\nc\n\xc2\xa2".force_encoding("UTF-8"),f.read)}
+ open("be","rb:utf-16be:euc-jp"){|f|assert_equal("a\rb\r\nc\n\xc2\xa2".force_encoding("EUC-JP"),f.read)}
+ open("bu","rb:utf-16be:utf-8"){|f|assert_equal("a\rb\r\nc\n\xc2\xa2".force_encoding("UTF-8"),f.read)}
+
+ open("ie","rt:iso-2022-jp:utf-16be"){|f|assert_equal("\0a\0\n\0b\0\n\0c\0\n\x85\x35".force_encoding("UTF-16BE"),f.read)}
+ open("be","rt:utf-16be:iso-2022-jp"){|f|assert_equal("a\nb\nc\n\e$B\x42\x22\e(B".force_encoding("ISO-2022-JP"),f.read)}
+ open("ie","rb:iso-2022-jp:utf-16be"){|f|assert_equal("\0a\0\r\0b\0\r\0\n\0c\0\n\x85\x35".force_encoding("UTF-16BE"),f.read)}
+ open("be","rb:utf-16be:iso-2022-jp"){|f|assert_equal("a\rb\r\nc\n\e$B\x42\x22\e(B".force_encoding("ISO-2022-JP"),f.read)}
+ }
+ end
+
+ def assert_write(expected, mode, *args)
+ with_tmpdir {
+ open("t", mode) {|f|
+ args.each {|arg| f.print arg }
+ }
+ content = File.read("t", :mode=>"rb:ascii-8bit")
+ assert_equal(expected.dup.force_encoding("ascii-8bit"),
+ content.force_encoding("ascii-8bit"))
+ }
+ end
+
+ def test_write_mode
+ # "\xc2\xa2" is valid as EUC-JP and UTF-8
+ # EUC-JP UTF-8 Unicode
+ # 0xC2A2 0xE894B5 U+8535
+ # 0xA1F1 0xC2A2 U+00A2
+ a = "a\rb\r\nc\n"
+ e = "\xc2\xa2".force_encoding("euc-jp")
+ u8 = "\xc2\xa2".force_encoding("utf-8")
+ u16 = "\x85\x35\0\r\x00\xa2\0\r\0\n\0\n".force_encoding("utf-16be")
+ i = "\e$B\x42\x22\e(B\r\e$B\x21\x71\e(B\r\n\n".force_encoding("iso-2022-jp")
+ n = system_newline
+ un = n.encode("utf-16be").force_encoding("ascii-8bit")
+
+ assert_write("a\rb\r#{n}c#{n}", "wt", a)
+ assert_write("\xc2\xa2", "wt", e)
+ assert_write("\xc2\xa2", "wt", u8)
+
+ assert_write("a\rb\r\nc\n", "wb", a)
+ assert_write("\xc2\xa2", "wb", e)
+ assert_write("\xc2\xa2", "wb", u8)
+
+ #assert_write("\x85\x35\0\r\x00\xa2\0\r\0\n\0\n", "wt", u16) should raise
+ #assert_write("\e$B\x42\x22\e(B\r\e$B\x21\x71\e(B\r\n\n", "wt", i) should raise
+ assert_write("\x85\x35\0\r\x00\xa2\0\r\0\n\0\n", "wb", u16)
+ assert_write("\e$B\x42\x22\e(B\r\e$B\x21\x71\e(B\r\n\n", "wb", i)
+
+ t_write_mode_enc
+ t_write_mode_enc(":utf-8")
+ end
+
+ def t_write_mode_enc(enc="")
+ # "\xc2\xa2" is valid as EUC-JP and UTF-8
+ # EUC-JP UTF-8 Unicode
+ # 0xC2A2 0xE894B5 U+8535
+ # 0xA1F1 0xC2A2 U+00A2
+ a = "a\rb\r\nc\n"
+ e = "\xc2\xa2".force_encoding("euc-jp")
+ u8 = "\xc2\xa2".force_encoding("utf-8")
+ u16 = "\x85\x35\0\r\x00\xa2\0\r\0\n\0\n".force_encoding("utf-16be")
+ i = "\e$B\x42\x22\e(B\r\e$B\x21\x71\e(B\r\n\n".force_encoding("iso-2022-jp")
+ n = system_newline
+ un = n.encode("utf-16be").force_encoding("ascii-8bit")
+
+ assert_write("a\rb\r#{n}c#{n}", "wt:euc-jp#{enc}", a)
+ assert_write("\xc2\xa2", "wt:euc-jp#{enc}", e)
+ assert_write("\xa1\xf1", "wt:euc-jp#{enc}", u8)
+
+ assert_write("a\rb\r\nc\n", "wb:euc-jp#{enc}", a)
+ assert_write("\xc2\xa2", "wb:euc-jp#{enc}", e)
+ assert_write("\xa1\xf1", "wb:euc-jp#{enc}", u8)
+
+ assert_write("\xc2\xa2\r\xa1\xf1\r#{n}#{n}", "wt:euc-jp#{enc}", u16)
+ assert_write("\xc2\xa2\r\xa1\xf1\r#{n}#{n}", "wt:euc-jp#{enc}", i)
+ assert_write("\xc2\xa2\r\xa1\xf1\r\n\n", "wb:euc-jp#{enc}", u16)
+ assert_write("\xc2\xa2\r\xa1\xf1\r\n\n", "wb:euc-jp#{enc}", i)
+
+ assert_write("\0a\0\r\0b\0\r#{un}\0c#{un}", "wt:utf-16be#{enc}", a)
+ assert_write("\x85\x35", "wt:utf-16be#{enc}", e)
+ assert_write("\x00\xa2", "wt:utf-16be#{enc}", u8)
+ assert_write("a\rb\r#{n}c#{n}", "wt:iso-2022-jp#{enc}", a)
+ assert_write("\e$B\x42\x22\e(B", "wt:iso-2022-jp#{enc}", e)
+ assert_write("\e$B\x21\x71\e(B", "wt:iso-2022-jp#{enc}", u8)
+
+ assert_write("\0a\0\r\0b\0\r\0\n\0c\0\n", "wb:utf-16be#{enc}", a)
+ assert_write("\x85\x35", "wb:utf-16be#{enc}", e)
+ assert_write("\x00\xa2", "wb:utf-16be#{enc}", u8)
+ assert_write("a\rb\r\nc\n", "wb:iso-2022-jp#{enc}", a)
+ assert_write("\e$B\x42\x22\e(B", "wb:iso-2022-jp#{enc}", e)
+ assert_write("\e$B\x21\x71\e(B", "wb:iso-2022-jp#{enc}", u8)
+
+ assert_write("\x85\x35\0\r\x00\xa2\0\r#{un}#{un}", "wt:utf-16be#{enc}", u16)
+ assert_write("\x85\x35\0\r\x00\xa2\0\r#{un}#{un}", "wt:utf-16be#{enc}", i)
+ assert_write("\x85\x35\0\r\x00\xa2\0\r\0\n\0\n", "wb:utf-16be#{enc}", u16)
+ assert_write("\x85\x35\0\r\x00\xa2\0\r\0\n\0\n", "wb:utf-16be#{enc}", i)
+ assert_write("\e$B\x42\x22\e(B\r\e$B\x21\x71\e(B\r#{n}#{n}", "wt:iso-2022-jp#{enc}", u16)
+ assert_write("\e$B\x42\x22\e(B\r\e$B\x21\x71\e(B\r#{n}#{n}", "wt:iso-2022-jp#{enc}", i)
+ assert_write("\e$B\x42\x22\e(B\r\e$B\x21\x71\e(B\r\n\n", "wb:iso-2022-jp#{enc}", u16)
+ assert_write("\e$B\x42\x22\e(B\r\e$B\x21\x71\e(B\r\n\n", "wb:iso-2022-jp#{enc}", i)
+ end
+
+ def test_write_mode_fail
+ return if system_newline == "\n"
+ with_tmpdir {
+ open("t", "wt") {|f|
+ assert_raise(ArgumentError) { f.print "\0\r\0\r\0\n\0\n".force_encoding("utf-16be") }
+ }
+ }
+ end
+
+ def test_write_ascii_incompat
+ with_tmpdir {
+ open("t.utf8", "wb:utf-8:utf-16be") {|f| }
+ open("t.utf8", "wt:utf-8:utf-16be") {|f| }
+ open("t.utf8", "w:utf-8:utf-16be") {|f| }
+ open("t.utf16", "wb:utf-16be") {|f| }
+ open("t.utf16", "wt:utf-16be") {|f| }
+ open("t.utf16", "w:utf-16be") {|f| }
+ }
+ end
+
+ def test_binmode_write_ascii_incompat_internal
+ with_tmpdir {
+ open("t.utf8.lf", "wb:utf-8:utf-16be") {|f|
+ f.print "\0a\0\n\0b\0\n".force_encoding("UTF-16BE")
+ }
+ content = File.read("t.utf8.lf", :mode=>"rb:ascii-8bit")
+ assert_equal("a\nb\n", content)
+
+ open("t.utf8.lf", "wb:utf-16be") {|f|
+ f.print "\0a\0\n\0b\0\n".force_encoding("UTF-16BE")
+ }
+ content = File.read("t.utf8.lf", :mode=>"rb:ascii-8bit")
+ assert_equal("\0a\0\n\0b\0\n", content)
+ }
+ end
+
+ def test_binary
+ with_tmpdir {
+ src = "a\nb\rc\r\nd\n"
+ generate_file("t.txt", src)
+ open("t.txt", "rb") {|f|
+ assert_equal(src, f.read)
+ }
+ open("t.txt", "r", :binmode=>true) {|f|
+ assert_equal(src, f.read)
+ }
+ if system_newline == "\n"
+ open("t.txt", "r") {|f|
+ assert_equal(src, f.read)
+ }
+ end
+ }
+ end
+
+ def test_binmode
+ with_tmpdir {
+ src = "a\r\nb\r\nc\r\n"
+ generate_file("t.txt", src)
+ open("t.txt", "rt") {|f|
+ assert_equal("a", f.getc)
+ assert_equal("\n", f.getc)
+ f.binmode
+ assert_equal("b", f.getc)
+ assert_equal("\r", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("c", f.getc)
+ assert_equal("\r", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal(nil, f.getc)
+ }
+ }
+ end
+
+ def test_binmode2
+ with_tmpdir {
+ src = "a\r\nb\r\nc\r\n"
+ generate_file("t.txt", src)
+ open("t.txt", "rt:euc-jp:utf-8") {|f|
+ assert_equal("a", f.getc)
+ assert_equal("\n", f.getc)
+ f.binmode
+ assert_equal("b", f.getc)
+ assert_equal("\r", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("c", f.getc)
+ assert_equal("\r", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal(nil, f.getc)
+ }
+ }
+ end
+
+ def test_binmode3
+ with_tmpdir {
+ src = "\u3042\r\n"
+ generate_file("t.txt", src)
+ srcbin = src.dup.force_encoding("ascii-8bit")
+ open("t.txt", "rt:utf-8:euc-jp") {|f|
+ f.binmode
+ result = f.read
+ assert_str_equal(srcbin, result)
+ assert_equal(Encoding::ASCII_8BIT, result.encoding)
+ }
+ }
+ end
+
+ def test_invalid_r
+ with_tmpdir {
+ generate_file("t.txt", "a\x80b")
+ open("t.txt", "r:utf-8:euc-jp", :invalid => :replace) {|f|
+ assert_equal("a?b", f.read)
+ }
+ open("t.txt", "r:utf-8:euc-jp", :invalid => :replace, :replace => "") {|f|
+ assert_equal("ab", f.read)
+ }
+ open("t.txt", "r:utf-8:euc-jp", :undef => :replace) {|f|
+ assert_raise(Encoding::InvalidByteSequenceError) { f.read }
+ assert_equal("b", f.read)
+ }
+ open("t.txt", "r:utf-8:euc-jp", :undef => :replace, :replace => "") {|f|
+ assert_raise(Encoding::InvalidByteSequenceError) { f.read }
+ assert_equal("b", f.read)
+ }
+ }
+ end
+
+ def test_undef_r
+ with_tmpdir {
+ generate_file("t.txt", "a\uFFFDb")
+ open("t.txt", "r:utf-8:euc-jp", :undef => :replace) {|f|
+ assert_equal("a?b", f.read)
+ }
+ open("t.txt", "r:utf-8:euc-jp", :undef => :replace, :replace => "") {|f|
+ assert_equal("ab", f.read)
+ }
+ open("t.txt", "r:utf-8:euc-jp", :invalid => :replace) {|f|
+ assert_raise(Encoding::UndefinedConversionError) { f.read }
+ assert_equal("b", f.read)
+ }
+ open("t.txt", "r:utf-8:euc-jp", :invalid => :replace, :replace => "") {|f|
+ assert_raise(Encoding::UndefinedConversionError) { f.read }
+ assert_equal("b", f.read)
+ }
+ }
+ end
+
+ def test_invalid_w
+ with_tmpdir {
+ invalid_utf8 = "a\x80b".force_encoding("utf-8")
+ open("t.txt", "w:euc-jp", :invalid => :replace) {|f|
+ assert_nothing_raised { f.write invalid_utf8 }
+ }
+ assert_equal("a?b", File.read("t.txt"))
+
+ open("t.txt", "w:euc-jp", :invalid => :replace, :replace => "") {|f|
+ assert_nothing_raised { f.write invalid_utf8 }
+ }
+ assert_equal("ab", File.read("t.txt"))
+
+ open("t.txt", "w:euc-jp", :undef => :replace) {|f|
+ assert_raise(Encoding::InvalidByteSequenceError) { f.write invalid_utf8 }
+ }
+ open("t.txt", "w:euc-jp", :undef => :replace, :replace => "") {|f|
+ assert_raise(Encoding::InvalidByteSequenceError) { f.write invalid_utf8 }
+ }
+ }
+ end
+
+ def test_undef_w_stateless
+ with_tmpdir {
+ generate_file("t.txt", "a\uFFFDb")
+ open("t.txt", "w:euc-jp:utf-8", :undef => :replace) {|f|
+ assert_nothing_raised { f.write "a\uFFFDb" }
+ }
+ assert_equal("a?b", File.read("t.txt"))
+ open("t.txt", "w:euc-jp:utf-8", :undef => :replace, :replace => "") {|f|
+ assert_nothing_raised { f.write "a\uFFFDb" }
+ }
+ assert_equal("ab", File.read("t.txt"))
+ open("t.txt", "w:euc-jp:utf-8", :invalid => :replace) {|f|
+ assert_raise(Encoding::UndefinedConversionError) { f.write "a\uFFFDb" }
+ }
+ open("t.txt", "w:euc-jp:utf-8", :invalid => :replace, :replace => "") {|f|
+ assert_raise(Encoding::UndefinedConversionError) { f.write "a\uFFFDb" }
+ }
+ }
+ end
+
+ def test_undef_w_stateful
+ with_tmpdir {
+ generate_file("t.txt", "a\uFFFDb")
+ open("t.txt", "w:iso-2022-jp:utf-8", :undef => :replace) {|f|
+ assert_nothing_raised { f.write "a\uFFFDb" }
+ }
+ assert_equal("a?b", File.read("t.txt"))
+ open("t.txt", "w:iso-2022-jp:utf-8", :undef => :replace, :replace => "") {|f|
+ assert_nothing_raised { f.write "a\uFFFDb" }
+ }
+ assert_equal("ab", File.read("t.txt"))
+ open("t.txt", "w:iso-2022-jp:utf-8", :invalid => :replace) {|f|
+ assert_raise(Encoding::UndefinedConversionError) { f.write "a\uFFFDb" }
+ }
+ open("t.txt", "w:iso-2022-jp:utf-8", :invalid => :replace, :replace => "") {|f|
+ assert_raise(Encoding::UndefinedConversionError) { f.write "a\uFFFDb" }
+ }
+ }
+ end
+
+ def test_w_xml_attr
+ with_tmpdir {
+ open("raw.txt", "wb", xml: :attr) {|f| f.print '&<>"\''; f.puts "\u4E02\u3042" }
+ content = File.read("raw.txt", :mode=>"rb:ascii-8bit")
+ assert_equal("\"&<>"'\u4E02\u3042\n\"".force_encoding("ascii-8bit"), content)
+
+ open("ascii.txt", "wb:us-ascii", xml: :attr) {|f| f.print '&<>"\''; f.puts "\u4E02\u3042" }
+ content = File.read("ascii.txt", :mode=>"rb:ascii-8bit")
+ assert_equal("\"&<>"'丂あ\n\"".force_encoding("ascii-8bit"), content)
+
+ open("iso-2022-jp.txt", "wb:iso-2022-jp", xml: :attr) {|f| f.print '&<>"\''; f.puts "\u4E02\u3042" }
+ content = File.read("iso-2022-jp.txt", :mode=>"rb:ascii-8bit")
+ assert_equal("\"&<>"'丂\e$B$\"\e(B\n\"".force_encoding("ascii-8bit"), content)
+
+ open("utf-16be.txt", "wb:utf-16be", xml: :attr) {|f| f.print '&<>"\''; f.puts "\u4E02\u3042" }
+ content = File.read("utf-16be.txt", :mode=>"rb:ascii-8bit")
+ assert_equal("\0\"\0&\0a\0m\0p\0;\0&\0l\0t\0;\0&\0g\0t\0;\0&\0q\0u\0o\0t\0;\0'\x4E\x02\x30\x42\0\n\0\"".force_encoding("ascii-8bit"), content)
+
+ open("eucjp.txt", "w:euc-jp:utf-8", xml: :attr) {|f|
+ f.print "\u4E02" # U+4E02 is 0x3021 in JIS X 0212
+ }
+ content = File.read("eucjp.txt", :mode=>"rb:ascii-8bit")
+ assert_equal("\"\x8F\xB0\xA1\"".force_encoding("ascii-8bit"), content)
+
+ open("sjis.txt", "w:sjis:utf-8", xml: :attr) {|f|
+ f.print "\u4E02" # U+4E02 is 0x3021 in JIS X 0212
+ }
+ content = File.read("sjis.txt", :mode=>"rb:ascii-8bit")
+ assert_equal("\"丂\"".force_encoding("ascii-8bit"), content)
+
+ open("iso-2022-jp.txt", "w:iso-2022-jp:utf-8", xml: :attr) {|f|
+ f.print "\u4E02" # U+4E02 is 0x3021 in JIS X 0212
+ }
+ content = File.read("iso-2022-jp.txt", :mode=>"rb:ascii-8bit")
+ assert_equal("\"丂\"".force_encoding("ascii-8bit"), content)
+ }
+ end
+
+ def test_strip_bom
+ with_tmpdir {
+ text = "\uFEFFa"
+ %w/UTF-8 UTF-16BE UTF-16LE UTF-32BE UTF-32LE/.each do |name|
+ path = '%s-bom.txt' % name
+ content = text.encode(name)
+ generate_file(path, content)
+ result = File.read(path, mode: 'rb:BOM|UTF-8')
+ assert_equal(content[1].force_encoding("ascii-8bit"),
+ result.force_encoding("ascii-8bit"))
+ end
+
+ bug3407 = '[ruby-core:30641]'
+ result = File.read('UTF-8-bom.txt', encoding: 'BOM|UTF-8')
+ assert_equal("a", result.force_encoding("ascii-8bit"), bug3407)
+ }
+ end
+
+ def test_cbuf
+ with_tmpdir {
+ fn = "tst"
+ open(fn, "w") {|f| f.print "foo" }
+ open(fn, "r+t") {|f|
+ f.ungetc(f.getc)
+ assert_raise(IOError, "[ruby-dev:40493]") { f.readpartial(2) }
+ assert_raise(IOError) { f.read(2) }
+ assert_raise(IOError) { f.each_byte {|c| } }
+ assert_raise(IOError) { f.getbyte }
+ assert_raise(IOError) { f.ungetbyte(0) }
+ assert_raise(IOError) { f.sysread(2) }
+ assert_raise(IOError) { IO.copy_stream(f, "tmpout") }
+ assert_raise(IOError) { f.sysseek(2) }
+ }
+ open(fn, "r+t") {|f|
+ f.ungetc(f.getc)
+ assert_equal("foo", f.read)
+ }
+ }
+ end
+
+ def test_text_mode_ungetc_eof
+ with_tmpdir {
+ open("ff", "w") {|f| }
+ open("ff", "rt") {|f|
+ f.ungetc "a"
+ assert(!f.eof?, "[ruby-dev:40506] (3)")
+ }
+ }
+ end
+
+ def test_cbuf_select
+ with_pipe("US-ASCII:UTF-8", :universal_newline => true) do |r, w|
+ w << "\r\n"
+ r.ungetc(r.getc)
+ assert_equal([[r],[],[]], IO.select([r], nil, nil, 1))
+ end
+ end
+
+ def test_textmode_paragraphmode
+ with_pipe("US-ASCII:UTF-8", :universal_newline => true) do |r, w|
+ w << "a\n\n\nc".gsub(/\n/, "\r\n")
+ w.close
+ assert_equal("a\n\n", r.gets(""))
+ assert_equal("c", r.gets(""), "[ruby-core:23723] (18)")
+ end
+ end
+
+ def test_textmode_paragraph_binaryread
+ with_pipe("US-ASCII:UTF-8", :universal_newline => true) do |r, w|
+ w << "a\n\n\ncdefgh".gsub(/\n/, "\r\n")
+ w.close
+ assert_equal("a\n\n", r.gets(""))
+ assert_equal("c", r.getc)
+ assert_equal("defgh", r.readpartial(10))
+ end
+ end
+
+ def test_textmode_paragraph_nonasciicompat
+ bug3534 = ['[ruby-dev:41803]', '[Bug #3534]']
+ r, w = IO.pipe
+ [Encoding::UTF_32BE, Encoding::UTF_32LE,
+ Encoding::UTF_16BE, Encoding::UTF_16LE,
+ Encoding::UTF_8].each do |e|
+ r.set_encoding(Encoding::US_ASCII, e)
+ w.print(bug3534[0], "\n\n\n\n", bug3534[1], "\n")
+ assert_equal((bug3534[0]+"\n\n").encode(e), r.gets(""), bug3534[0])
+ assert_equal((bug3534[1]+"\n").encode(e), r.gets(), bug3534[1])
+ end
+ end
+
+ def test_binmode_paragraph_nonasciicompat
+ bug3534 = ['[ruby-dev:41803]', '[Bug #3534]']
+ r, w = IO.pipe
+ r.binmode
+ w.binmode
+ [Encoding::UTF_32BE, Encoding::UTF_32LE,
+ Encoding::UTF_16BE, Encoding::UTF_16LE,
+ Encoding::UTF_8].each do |e|
+ r.set_encoding(Encoding::US_ASCII, e)
+ w.print(bug3534[0], "\n\n\n\n", bug3534[1], "\n")
+ assert_equal((bug3534[0]+"\n\n").encode(e), r.gets(""), bug3534[0])
+ assert_equal((bug3534[1]+"\n").encode(e), r.gets(), bug3534[1])
+ end
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/ruby/test_iterator.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_iterator.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_iterator.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,497 @@
+require 'test/unit'
+
+class Array
+ def iter_test1
+ collect{|e| [e, yield(e)]}.sort{|a,b|a[1]<=>b[1]}
+ end
+ def iter_test2
+ ary = collect{|e| [e, yield(e)]}
+ ary.sort{|a,b|a[1]<=>b[1]}
+ end
+end
+
+class TestIterator < Test::Unit::TestCase
+ def ttt
+ assert(iterator?)
+ end
+
+ def test_iterator
+ assert(!iterator?)
+
+ ttt{}
+
+ # yield at top level !! here's not toplevel
+ assert(!defined?(yield))
+ end
+
+ def test_array
+ $x = [1, 2, 3, 4]
+ $y = []
+
+ # iterator over array
+ for i in $x
+ $y.push i
+ end
+ assert_equal($x, $y)
+ end
+
+ def tt
+ 1.upto(10) {|i|
+ yield i
+ }
+ end
+
+ def tt2(dummy)
+ yield 1
+ end
+
+ def tt3(&block)
+ tt2(raise(ArgumentError,""),&block)
+ end
+
+ def test_nested_iterator
+ i = 0
+ tt{|j| break if j == 5}
+ assert_equal(0, i)
+
+ assert_raise(ArgumentError) do
+ tt3{}
+ end
+ end
+
+ def tt4 &block
+ tt2(raise(ArgumentError,""),&block)
+ end
+
+ def test_block_argument_without_paren
+ assert_raise(ArgumentError) do
+ tt4{}
+ end
+ end
+
+ # iterator break/redo/next
+ def test_break
+ done = true
+ loop{
+ break
+ done = false # should not reach here
+ }
+ assert(done)
+
+ done = false
+ $bad = false
+ loop {
+ break if done
+ done = true
+ next
+ $bad = true # should not reach here
+ }
+ assert(!$bad)
+
+ done = false
+ $bad = false
+ loop {
+ break if done
+ done = true
+ redo
+ $bad = true # should not reach here
+ }
+ assert(!$bad)
+
+ $x = []
+ for i in 1 .. 7
+ $x.push i
+ end
+ assert_equal(7, $x.size)
+ assert_equal([1, 2, 3, 4, 5, 6, 7], $x)
+ end
+
+ def test_append_method_to_built_in_class
+ $x = [[1,2],[3,4],[5,6]]
+ assert_equal($x.iter_test1{|x|x}, $x.iter_test2{|x|x})
+ end
+
+ class IterTest
+ def initialize(e); @body = e; end
+
+ def each0(&block); @body.each(&block); end
+ def each1(&block); @body.each {|*x| block.call(*x) } end
+ def each2(&block); @body.each {|*x| block.call(x) } end
+ def each3(&block); @body.each {|x| block.call(*x) } end
+ def each4(&block); @body.each {|x| block.call(x) } end
+ def each5; @body.each {|*x| yield(*x) } end
+ def each6; @body.each {|*x| yield(x) } end
+ def each7; @body.each {|x| yield(*x) } end
+ def each8; @body.each {|x| yield(x) } end
+
+ def f(a)
+ a
+ end
+ end
+
+ def test_itertest
+ assert_equal([1], IterTest.new(nil).method(:f).to_proc.call([1]))
+ m = /\w+/.match("abc")
+ assert_equal([m], IterTest.new(nil).method(:f).to_proc.call([m]))
+
+ IterTest.new([0]).each0 {|x| assert_equal(0, x)}
+ IterTest.new([1]).each1 {|x| assert_equal(1, x)}
+ IterTest.new([2]).each2 {|x| assert_equal([2], x)}
+ IterTest.new([4]).each4 {|x| assert_equal(4, x)}
+ IterTest.new([5]).each5 {|x| assert_equal(5, x)}
+ IterTest.new([6]).each6 {|x| assert_equal([6], x)}
+ IterTest.new([8]).each8 {|x| assert_equal(8, x)}
+
+ IterTest.new([[0]]).each0 {|x| assert_equal([0], x)}
+ IterTest.new([[1]]).each1 {|x| assert_equal([1], x)}
+ IterTest.new([[2]]).each2 {|x| assert_equal([[2]], x)}
+ IterTest.new([[3]]).each3 {|x| assert_equal(3, x)}
+ IterTest.new([[4]]).each4 {|x| assert_equal([4], x)}
+ IterTest.new([[5]]).each5 {|x| assert_equal([5], x)}
+ IterTest.new([[6]]).each6 {|x| assert_equal([[6]], x)}
+ IterTest.new([[7]]).each7 {|x| assert_equal(7, x)}
+ IterTest.new([[8]]).each8 {|x| assert_equal([8], x)}
+
+ IterTest.new([[0,0]]).each0 {|*x| assert_equal([[0,0]], x)}
+ IterTest.new([[8,8]]).each8 {|*x| assert_equal([[8,8]], x)}
+ end
+
+ def m(var)
+ var
+ end
+
+ def m1
+ m(block_given?)
+ end
+
+ def m2
+ m(block_given?,&proc{})
+ end
+
+ def test_block_given
+ assert(m1{p 'test'})
+ assert(m2{p 'test'})
+ assert(!m1())
+ assert(!m2())
+ end
+
+ def m3(var, &block)
+ m(yield(var), &block)
+ end
+
+ def m4(&block)
+ m(m1(), &block)
+ end
+
+ def test_block_passing
+ assert(!m4())
+ assert(!m4 {})
+ assert_equal(100, m3(10) {|x|x*x})
+ end
+
+ class C
+ include Enumerable
+ def initialize
+ @a = [1,2,3]
+ end
+ def each(&block)
+ @a.each(&block)
+ end
+ end
+
+ def test_collect
+ assert_equal([1,2,3], C.new.collect{|n| n})
+ end
+
+ def test_proc
+ assert_instance_of(Proc, lambda{})
+ assert_instance_of(Proc, Proc.new{})
+ lambda{|a|assert_equal(a, 1)}.call(1)
+ end
+
+ def test_block
+ assert_instance_of(NilClass, get_block)
+ assert_instance_of(Proc, get_block{})
+ end
+
+ def test_argument
+ assert_nothing_raised {lambda{||}.call}
+ assert_raise(ArgumentError) {lambda{||}.call(1)}
+ assert_nothing_raised {lambda{|a,|}.call(1)}
+ assert_raise(ArgumentError) {lambda{|a,|}.call()}
+ assert_raise(ArgumentError) {lambda{|a,|}.call(1,2)}
+ end
+
+ def get_block(&block)
+ block
+ end
+
+ def test_get_block
+ assert_instance_of(Proc, get_block{})
+ assert_nothing_raised {get_block{||}.call()}
+ assert_nothing_raised {get_block{||}.call(1)}
+ assert_nothing_raised {get_block{|a,|}.call(1)}
+ assert_nothing_raised {get_block{|a,|}.call()}
+ assert_nothing_raised {get_block{|a,|}.call(1,2)}
+
+ assert_nothing_raised {get_block(&lambda{||}).call()}
+ assert_raise(ArgumentError) {get_block(&lambda{||}).call(1)}
+ assert_nothing_raised {get_block(&lambda{|a,|}).call(1)}
+ assert_raise(ArgumentError) {get_block(&lambda{|a,|}).call(1,2)}
+
+ block = get_block{11}
+ assert_instance_of(Proc, block)
+ assert_instance_of(Proc, block.to_proc)
+ assert_equal(block.clone.call, 11)
+ assert_instance_of(Proc, get_block(&block))
+
+ lmd = lambda{44}
+ assert_instance_of(Proc, lmd)
+ assert_instance_of(Proc, lmd.to_proc)
+ assert_equal(lmd.clone.call, 44)
+ assert_instance_of(Proc, get_block(&lmd))
+
+ assert_equal(1, Proc.new{|a,| a}.call(1,2,3))
+ assert_nothing_raised {Proc.new{|a,|}.call(1,2)}
+ end
+
+ def return1_test
+ Proc.new {
+ return 55
+ }.call + 5
+ end
+
+ def test_return1
+ assert_equal(55, return1_test())
+ end
+
+ def return2_test
+ lambda {
+ return 55
+ }.call + 5
+ end
+
+ def test_return2
+ assert_equal(60, return2_test())
+ end
+
+ def proc_call(&b)
+ b.call
+ end
+ def proc_yield()
+ yield
+ end
+ def proc_return1
+ proc_call{return 42}+1
+ end
+
+ def test_proc_return1
+ assert_equal(42, proc_return1())
+ end
+
+ def proc_return2
+ proc_yield{return 42}+1
+ end
+
+ def test_proc_return2
+ assert_equal(42, proc_return2())
+ end
+
+ def test_ljump
+ assert_raise(LocalJumpError) {get_block{break}.call}
+
+ # cannot use assert_nothing_raised due to passing block.
+ begin
+ val = lambda{break 11}.call
+ rescue LocalJumpError
+ assert(false, "LocalJumpError occurred from break in lambda")
+ else
+ assert_equal(11, val)
+ end
+
+ block = get_block{11}
+ lmd = lambda{44}
+ assert_equal(0, block.arity)
+ assert_equal(0, lmd.arity)
+ assert_equal(0, lambda{||}.arity)
+ assert_equal(1, lambda{|a|}.arity)
+ assert_equal(1, lambda{|a,|}.arity)
+ assert_equal(2, lambda{|a,b|}.arity)
+ end
+
+ def marity_test(m)
+ mobj = method(m)
+ assert_equal(mobj.arity, mobj.to_proc.arity)
+ end
+
+ def test_marity
+ marity_test(:assert)
+ marity_test(:marity_test)
+ marity_test(:p)
+
+ lambda(&method(:assert)).call(true)
+ lambda(&get_block{|a,n| assert(a,n)}).call(true, "marity")
+ end
+
+ def foo
+ yield(:key, :value)
+ end
+ def bar(&blk)
+ blk.call(:key, :value)
+ end
+
+ def test_yield_vs_call
+ foo{|k,v| assert_equal([:key, :value], [k,v])}
+ bar{|k,v| assert_equal([:key, :value], [k,v])}
+ end
+
+ class H
+ def each
+ yield [:key, :value]
+ end
+ alias each_pair each
+ end
+
+ def test_assoc_yield
+ [{:key=>:value}, H.new].each {|h|
+ h.each{|a| assert_equal([:key, :value], a)}
+ h.each{|a,| assert_equal(:key, a)}
+ h.each{|*a| assert_equal([[:key, :value]], a)}
+ h.each{|k,v| assert_equal([:key, :value], [k,v])}
+ h.each_pair{|a| assert_equal([:key, :value], a)}
+ h.each_pair{|a,| assert_equal(:key, a)}
+ h.each_pair{|*a| assert_equal([[:key, :value]], a)}
+ h.each_pair{|k,v| assert_equal([:key, :value], [k,v])}
+ }
+ end
+
+ class ITER_TEST1
+ def a
+ block_given?
+ end
+ end
+
+ class ITER_TEST2 < ITER_TEST1
+ include Test::Unit::Assertions
+ def a
+ assert(super)
+ super
+ end
+ end
+
+ def test_iter_test2
+ assert(ITER_TEST2.new.a {})
+ end
+
+ class ITER_TEST3
+ def foo x
+ return yield if block_given?
+ x
+ end
+ end
+
+ class ITER_TEST4 < ITER_TEST3
+ include Test::Unit::Assertions
+ def foo x
+ assert_equal(super, yield)
+ assert_equal(x, super(x, &nil))
+ end
+ end
+
+ def test_iter4
+ ITER_TEST4.new.foo(44){55}
+ end
+
+ def test_break__nested_loop1
+ _test_break__nested_loop1 do
+ break
+ end
+ end
+
+ def _test_break__nested_loop1
+ while true
+ yield
+ end
+ assert(false, "must not reach here")
+ end
+
+ def test_break__nested_loop2
+ _test_break__nested_loop2 do
+ break
+ end
+ end
+
+ def _test_break__nested_loop2
+ until false
+ yield
+ end
+ assert(false, "must not reach here")
+ end
+
+ def test_break__nested_loop3
+ _test_break__nested_loop3 do
+ break
+ end
+ end
+
+ def _test_break__nested_loop3
+ loop do
+ yield
+ end
+ assert(false, "must not reach here")
+ end
+
+ def test_break_from_enum
+ result = ["a"].inject("ng") {|x,y| break "ok"}
+ assert_equal("ok", result)
+ end
+
+ def _test_return_trace_func(x)
+ set_trace_func(proc {})
+ [].fetch(2) {return x}
+ ensure
+ set_trace_func(nil)
+ end
+
+ def test_return_trace_func
+ ok = "returned gracefully"
+ result = "skipped"
+ result = _test_return_trace_func(ok)
+ ensure
+ assert_equal(ok, result)
+ return
+ end
+
+ class IterString < ::String
+ def ===(other)
+ super if !block_given?
+ end
+ end
+
+ # Check that the block passed to an iterator
+ # does not get propagated inappropriately
+ def test_block_given_within_iterator
+ assert_equal(["b"], ["a", "b", "c"].grep(IterString.new("b")) {|s| s})
+ end
+
+ def test_enumerator
+ [1,2,3].each.with_index {|x,i|
+ assert_equal(x, i+1)
+ }
+
+ e = [1,2,3].each
+ assert_equal(1, e.next)
+ assert_equal(2, e.next)
+ assert_equal(3, e.next)
+ assert_raise(StopIteration){e.next}
+ e.rewind
+ assert_equal(1, e.next)
+ e.rewind
+ a = []
+ loop{a.push e.next}
+ assert_equal([1,2,3], a)
+
+ assert_equal([[8, 1, 10], [6, 2, 11], [4, 3, 12]],
+ [8,6,4].zip((1..10),(10..100)).to_a)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_lambda.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_lambda.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_lambda.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,68 @@
+require 'test/unit'
+
+class TestLambdaParameters < Test::Unit::TestCase
+
+ def test_exact_parameter
+ assert_raise(ArgumentError){(1..3).each(&lambda{})}
+ end
+
+ def test_call_simple
+ assert_equal(1, lambda{|a| a}.call(1))
+ assert_equal([1,2], lambda{|a, b| [a,b]}.call(1,2))
+ assert_raise(ArgumentError) { lambda{|a|}.call(1,2) }
+ assert_raise(ArgumentError) { lambda{|a|}.call() }
+ assert_raise(ArgumentError) { lambda{}.call(1) }
+ assert_raise(ArgumentError) { lambda{|a, b|}.call(1,2,3) }
+
+ assert_equal(1, ->(a){ a }.call(1))
+ assert_equal([1,2], ->(a,b){ [a,b] }.call(1,2))
+ assert_raise(ArgumentError) { ->(a){ }.call(1,2) }
+ assert_raise(ArgumentError) { ->(a){ }.call() }
+ assert_raise(ArgumentError) { ->(){ }.call(1) }
+ assert_raise(ArgumentError) { ->(a,b){ }.call(1,2,3) }
+ end
+
+end
+
+__END__
+ def test_lambda_as_iterator
+ a = 0
+ 2.times(&->(_){ a += 1 })
+ assert_equal(a, 2)
+ end
+
+ def test_call_rest_args
+ assert_equal([1,2], ->(*a){ a }.call(1,2))
+ assert_equal([1,2,[]], ->(a,b,*c){ [a,b,c] }.call(1,2))
+ assert_raise(ArgumentError){ ->(a,*b){ }.call() }
+ end
+
+ def test_call_opt_args
+ assert_equal([1,2,3,4], ->(a,b,c=3,d=4){ [a,b,c,d] }.call(1,2))
+ assert_equal([1,2,3,4], ->(a,b,c=0,d=4){ [a,b,c,d] }.call(1,2,3))
+ assert_raise(ArgumentError){ ->(a,b=1){ }.call() }
+ assert_raise(ArgumentError){ ->(a,b=1){ }.call(1,2,3) }
+ end
+
+ def test_call_rest_and_opt
+ assert_equal([1,2,3,[]], ->(a,b=2,c=3,*d){ [a,b,c,d] }.call(1))
+ assert_equal([1,2,3,[]], ->(a,b=0,c=3,*d){ [a,b,c,d] }.call(1,2))
+ assert_equal([1,2,3,[4,5,6]], ->(a,b=0,c=0,*d){ [a,b,c,d] }.call(1,2,3,4,5,6))
+ assert_raise(ArgumentError){ ->(a,b=1,*c){ }.call() }
+ end
+
+ def test_call_with_block
+ f = ->(a,b,c=3,*d,&e){ [a,b,c,d,e.call(d + [a,b,c])] }
+ assert_equal([1,2,3,[],6], f.call(1,2){|z| z.inject{|s,x| s+x} } )
+ assert_equal(nil, ->(&b){ b }.call)
+ foo { puts "bogus block " }
+ assert_equal(1, ->(&b){ b.call }.call { 1 })
+ b = nil
+ assert_equal(1, ->(&b){ b.call }.call { 1 })
+ assert_nil(b)
+ end
+
+ def foo
+ assert_equal(nil, ->(&b){ b }.call)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_literal.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_literal.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_literal.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,262 @@
+require 'test/unit'
+
+class TestRubyLiteral < Test::Unit::TestCase
+
+ def test_special_const
+ assert_equal 'true', true.inspect
+ assert_instance_of TrueClass, true
+ assert_equal 'false', false.inspect
+ assert_instance_of FalseClass, false
+ assert_equal 'nil', nil.inspect
+ assert_instance_of NilClass, nil
+ assert_equal ':sym', :sym.inspect
+ assert_instance_of Symbol, :sym
+ assert_equal '1234', 1234.inspect
+ assert_instance_of Fixnum, 1234
+ assert_equal '1234', 1_2_3_4.inspect
+ assert_instance_of Fixnum, 1_2_3_4
+ assert_equal '18', 0x12.inspect
+ assert_instance_of Fixnum, 0x12
+ assert_raise(SyntaxError) { eval("0x") }
+ assert_equal '15', 0o17.inspect
+ assert_instance_of Fixnum, 0o17
+ assert_raise(SyntaxError) { eval("0o") }
+ assert_equal '5', 0b101.inspect
+ assert_instance_of Fixnum, 0b101
+ assert_raise(SyntaxError) { eval("0b") }
+ assert_equal '123456789012345678901234567890', 123456789012345678901234567890.inspect
+ assert_instance_of Bignum, 123456789012345678901234567890
+ assert_instance_of Float, 1.3
+ end
+
+ def test_self
+ assert_equal self, self
+ assert_instance_of TestRubyLiteral, self
+ assert_respond_to self, :test_self
+ end
+
+ def test_string
+ assert_instance_of String, ?a
+ assert_equal "a", ?a
+ assert_instance_of String, ?A
+ assert_equal "A", ?A
+ assert_instance_of String, ?\n
+ assert_equal "\n", ?\n
+ assert_equal " ", ?\ # space
+ assert_equal '', ''
+ assert_equal 'string', 'string'
+ assert_equal 'string string', 'string string'
+ assert_equal ' ', ' '
+ assert_equal ' ', " "
+ assert_equal "\0", "\0"
+ assert_equal "\1", "\1"
+ assert_equal "3", "\x33"
+ assert_equal "\n", "\n"
+ bug2500 = '[ruby-core:27228]'
+ %w[c C- M-].each do |pre|
+ ["u", "x", %w[u{ }]].each do |open, close|
+ str = "\"\\#{pre}\\#{open}5555#{close}\""
+ assert_raise(SyntaxError, "#{bug2500} eval(#{str})") {eval(str)}
+ end
+ end
+ end
+
+ def test_dstring
+ assert_equal '2', "#{1+1}"
+ assert_equal '16', "#{2 ** 4}"
+ s = "string"
+ assert_equal s, "#{s}"
+ a = 'Foo'
+ b = "#{a}" << 'Bar'
+ assert_equal('Foo', a, 'r3842')
+ assert_equal('FooBar', b, 'r3842')
+ end
+
+ def test_dsymbol
+ assert_equal :a3c, :"a#{1+2}c"
+ end
+
+ def test_xstring
+ assert_equal "foo\n", `echo foo`
+ s = 'foo'
+ assert_equal "foo\n", `echo #{s}`
+ end
+
+ def test_regexp
+ assert_instance_of Regexp, //
+ assert_match(//, 'a')
+ assert_match(//, '')
+ assert_instance_of Regexp, /a/
+ assert_match(/a/, 'a')
+ assert_no_match(/test/, 'tes')
+ re = /test/
+ assert_match re, 'test'
+ str = 'test'
+ assert_match re, str
+ assert_match(/test/, str)
+ assert_equal 0, (/test/ =~ 'test')
+ assert_equal 0, (re =~ 'test')
+ assert_equal 0, (/test/ =~ str)
+ assert_equal 0, (re =~ str)
+ assert_equal 0, ('test' =~ /test/)
+ assert_equal 0, ('test' =~ re)
+ assert_equal 0, (str =~ /test/)
+ assert_equal 0, (str =~ re)
+ end
+
+ def test_dregexp
+ assert_instance_of Regexp, /re#{'ge'}xp/
+ assert_equal(/regexp/, /re#{'ge'}xp/)
+ end
+
+ def test_array
+ assert_instance_of Array, []
+ assert_equal [], []
+ assert_equal 0, [].size
+ assert_instance_of Array, [0]
+ assert_equal [3], [3]
+ assert_equal 1, [3].size
+ a = [3]
+ assert_equal 3, a[0]
+ assert_instance_of Array, [1,2]
+ assert_equal [1,2], [1,2]
+ assert_instance_of Array, [1,2,3,4,5]
+ assert_equal [1,2,3,4,5], [1,2,3,4,5]
+ assert_equal 5, [1,2,3,4,5].size
+ a = [1,2]
+ assert_equal 1, a[0]
+ assert_equal 2, a[1]
+ a = [1 + 2, 3 + 4, 5 + 6]
+ assert_instance_of Array, a
+ assert_equal [3, 7, 11], a
+ assert_equal 7, a[1]
+ assert_equal 1, ([0][0] += 1)
+ assert_equal 1, ([2][0] -= 1)
+ a = [obj = Object.new]
+ assert_instance_of Array, a
+ assert_equal 1, a.size
+ assert_equal obj, a[0]
+ a = [1,2,3]
+ a[1] = 5
+ assert_equal 5, a[1]
+ end
+
+ def test_hash
+ assert_instance_of Hash, {}
+ assert_equal({}, {})
+ assert_instance_of Hash, {1 => 2}
+ assert_equal({1 => 2}, {1 => 2})
+ h = {1 => 2}
+ assert_equal 2, h[1]
+ h = {"string" => "literal", "goto" => "hell"}
+ assert_equal h, h
+ assert_equal 2, h.size
+ assert_equal h, h
+ assert_equal "literal", h["string"]
+ end
+
+ def test_range
+ assert_instance_of Range, (1..2)
+ assert_equal(1..2, 1..2)
+ r = 1..2
+ assert_equal 1, r.begin
+ assert_equal 2, r.end
+ assert_equal false, r.exclude_end?
+ assert_instance_of Range, (1...3)
+ assert_equal(1...3, 1...3)
+ r = 1...3
+ assert_equal 1, r.begin
+ assert_equal 3, r.end
+ assert_equal true, r.exclude_end?
+ r = 1+2 .. 3+4
+ assert_instance_of Range, r
+ assert_equal 3, r.begin
+ assert_equal 7, r.end
+ assert_equal false, r.exclude_end?
+ r = 1+2 ... 3+4
+ assert_instance_of Range, r
+ assert_equal 3, r.begin
+ assert_equal 7, r.end
+ assert_equal true, r.exclude_end?
+ assert_instance_of Range, 'a'..'c'
+ r = 'a'..'c'
+ assert_equal 'a', r.begin
+ assert_equal 'c', r.end
+ end
+
+ def test__FILE__
+ assert_instance_of String, __FILE__
+ assert_equal __FILE__, __FILE__
+ assert_equal 'test_literal.rb', File.basename(__FILE__)
+ end
+
+ def test__LINE__
+ assert_instance_of Fixnum, __LINE__
+ assert_equal __LINE__, __LINE__
+ end
+
+ def test_integer
+ head = ['', '0x', '0o', '0b', '0d', '-', '+']
+ chars = ['0', '1', '_', '9', 'f']
+ head.each {|h|
+ 4.times {|len|
+ a = [h]
+ len.times { a = a.product(chars).map {|x| x.join('') } }
+ a.each {|s|
+ next if s.empty?
+ begin
+ r1 = Integer(s)
+ rescue ArgumentError
+ r1 = :err
+ end
+ begin
+ r2 = eval(s)
+ rescue NameError, SyntaxError
+ r2 = :err
+ end
+ assert_equal(r1, r2, "Integer(#{s.inspect}) != eval(#{s.inspect})")
+ }
+ }
+ }
+ bug2407 = '[ruby-dev:39798]'
+ head.each {|h|
+ if /^0/ =~ h
+ begin
+ eval("#{h}_")
+ rescue SyntaxError => e
+ assert_match(/numeric literal without digits\Z/, e.message, bug2407)
+ end
+ end
+ }
+ end
+
+ def test_float
+ head = ['', '-', '+']
+ chars = ['0', '1', '_', '9', 'f', '.']
+ head.each {|h|
+ 6.times {|len|
+ a = [h]
+ len.times { a = a.product(chars).map {|x| x.join('') } }
+ a.each {|s|
+ next if s.empty?
+ next if /\.\z/ =~ s
+ next if /\A[-+]?\./ =~ s
+ next if /\A[-+]?0/ =~ s
+ begin
+ r1 = Float(s)
+ rescue ArgumentError
+ r1 = :err
+ end
+ begin
+ r2 = eval(s)
+ rescue NameError, SyntaxError
+ r2 = :err
+ end
+ r2 = :err if Range === r2
+ assert_equal(r1, r2, "Float(#{s.inspect}) != eval(#{s.inspect})")
+ }
+ }
+ }
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_m17n.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_m17n.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_m17n.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1341 @@
+require 'test/unit'
+require 'stringio'
+
+class TestM17N < Test::Unit::TestCase
+ def assert_encoding(encname, actual, message=nil)
+ assert_equal(Encoding.find(encname), actual, message)
+ end
+
+ module AESU
+ def ua(str) str.dup.force_encoding("US-ASCII") end
+ def a(str) str.dup.force_encoding("ASCII-8BIT") end
+ def e(str) str.dup.force_encoding("EUC-JP") end
+ def s(str) str.dup.force_encoding("Windows-31J") end
+ def u(str) str.dup.force_encoding("UTF-8") end
+ end
+ include AESU
+ extend AESU
+
+ def assert_strenc(bytes, enc, actual, message=nil)
+ assert_instance_of(String, actual, message)
+ enc = Encoding.find(enc) if String === enc
+ assert_equal(enc, actual.encoding, message)
+ assert_equal(a(bytes), a(actual), message)
+ end
+
+ def assert_warning(pat, mesg=nil)
+ begin
+ org_stderr = $stderr
+ $stderr = StringIO.new(warn = '')
+ yield
+ ensure
+ $stderr = org_stderr
+ end
+ assert_match(pat, warn, mesg)
+ end
+
+ def assert_regexp_generic_encoding(r)
+ assert(!r.fixed_encoding?)
+ %w[ASCII-8BIT EUC-JP Windows-31J UTF-8].each {|ename|
+ # "\xc2\xa1" is a valid sequence for ASCII-8BIT, EUC-JP, Windows-31J and UTF-8.
+ assert_nothing_raised { r =~ "\xc2\xa1".force_encoding(ename) }
+ }
+ end
+
+ def assert_regexp_fixed_encoding(r)
+ assert(r.fixed_encoding?)
+ %w[ASCII-8BIT EUC-JP Windows-31J UTF-8].each {|ename|
+ enc = Encoding.find(ename)
+ if enc == r.encoding
+ assert_nothing_raised { r =~ "\xc2\xa1".force_encoding(enc) }
+ else
+ assert_raise(Encoding::CompatibilityError) { r =~ "\xc2\xa1".force_encoding(enc) }
+ end
+ }
+ end
+
+ def assert_regexp_generic_ascii(r)
+ assert_encoding("US-ASCII", r.encoding)
+ assert_regexp_generic_encoding(r)
+ end
+
+ def assert_regexp_fixed_ascii8bit(r)
+ assert_encoding("ASCII-8BIT", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_fixed_eucjp(r)
+ assert_encoding("EUC-JP", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_fixed_sjis(r)
+ assert_encoding("Windows-31J", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_fixed_utf8(r)
+ assert_encoding("UTF-8", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_usascii_literal(r, enc, ex = nil)
+ code = "# -*- encoding: US-ASCII -*-\n#{r}.encoding"
+ if ex
+ assert_raise(ex) { eval(code) }
+ else
+ assert_equal(enc, eval(code))
+ end
+ end
+
+ def encdump(str)
+ d = str.dump
+ if /\.force_encoding\("[A-Za-z0-9.:_+-]*"\)\z/ =~ d
+ d
+ else
+ "#{d}.force_encoding(#{str.encoding.name.dump})"
+ end
+ end
+
+ def encdumpargs(args)
+ r = '('
+ args.each_with_index {|a, i|
+ r << ',' if 0 < i
+ if String === a
+ r << encdump(a)
+ else
+ r << a.inspect
+ end
+ }
+ r << ')'
+ r
+ end
+
+ def assert_str_enc_propagation(t, s1, s2)
+ if !s1.ascii_only?
+ assert_equal(s1.encoding, t.encoding)
+ elsif !s2.ascii_only?
+ assert_equal(s2.encoding, t.encoding)
+ else
+ assert([s1.encoding, s2.encoding].include?(t.encoding))
+ end
+ end
+
+ def assert_same_result(expected_proc, actual_proc)
+ e = nil
+ begin
+ t = expected_proc.call
+ rescue
+ e = $!
+ end
+ if e
+ assert_raise(e.class) { actual_proc.call }
+ else
+ assert_equal(t, actual_proc.call)
+ end
+ end
+
+ def str_enc_compatible?(*strs)
+ encs = []
+ strs.each {|s|
+ encs << s.encoding if !s.ascii_only?
+ }
+ encs.uniq!
+ encs.length <= 1
+ end
+
+ # tests start
+
+ def test_string_ascii_literal
+ assert_encoding("ASCII-8BIT", eval(a(%{""})).encoding)
+ assert_encoding("ASCII-8BIT", eval(a(%{"a"})).encoding)
+ end
+
+ def test_string_eucjp_literal
+ assert_encoding("EUC-JP", eval(e(%{""})).encoding)
+ assert_encoding("EUC-JP", eval(e(%{"a"})).encoding)
+ assert_encoding("EUC-JP", eval(e(%{"\xa1\xa1"})).encoding)
+ assert_encoding("EUC-JP", eval(e(%{"\\xa1\\xa1"})).encoding)
+ assert_encoding("EUC-JP", eval(e(%{"\\x20"})).encoding)
+ assert_encoding("EUC-JP", eval(e(%{"\\n"})).encoding)
+ assert_encoding("EUC-JP", eval(e(%{"\\x80"})).encoding)
+ end
+
+ def test_utf8_literal
+ assert_equal(Encoding::UTF_8, "\u3042".encoding, "[ruby-dev:33406] \"\\u3042\".encoding")
+ assert_raise(SyntaxError) { eval(a('\u3052\x80')) }
+ end
+
+ def test_string_mixed_unicode
+ assert_raise(SyntaxError) { eval(a(%{"\xc2\xa1\\u{6666}"})) }
+ assert_raise(SyntaxError) { eval(e(%{"\xc2\xa1\\u{6666}"})) }
+ assert_raise(SyntaxError) { eval(s(%{"\xc2\xa1\\u{6666}"})) }
+ assert_nothing_raised { eval(u(%{"\xc2\xa1\\u{6666}"})) }
+ assert_raise(SyntaxError) { eval(a(%{"\\u{6666}\xc2\xa1"})) }
+ assert_raise(SyntaxError) { eval(e(%{"\\u{6666}\xc2\xa1"})) }
+ assert_raise(SyntaxError) { eval(s(%{"\\u{6666}\xc2\xa1"})) }
+ assert_nothing_raised { eval(u(%{"\\u{6666}\xc2\xa1"})) }
+ end
+
+ def test_string_inspect_invalid
+ assert_equal('"\xFE"', e("\xfe").inspect)
+ assert_equal('"\x8E"', e("\x8e").inspect)
+ assert_equal('"\x8F"', e("\x8f").inspect)
+ assert_equal('"\x8F\xA1"', e("\x8f\xa1").inspect)
+ assert_equal('"\xEF"', s("\xef").inspect)
+ assert_equal('"\xC2"', u("\xc2").inspect)
+ assert_equal('"\xE0\x80"', u("\xe0\x80").inspect)
+ assert_equal('"\xF0\x80\x80"', u("\xf0\x80\x80").inspect)
+ assert_equal('"\xF8\x80\x80\x80"', u("\xf8\x80\x80\x80").inspect)
+ assert_equal('"\xFC\x80\x80\x80\x80"', u("\xfc\x80\x80\x80\x80").inspect)
+
+ assert_equal('"\xFE "', e("\xfe ").inspect)
+ assert_equal('"\x8E "', e("\x8e ").inspect)
+ assert_equal('"\x8F "', e("\x8f ").inspect)
+ assert_equal('"\x8F\xA1 "', e("\x8f\xa1 ").inspect)
+ assert_equal('"\xEF "', s("\xef ").inspect)
+ assert_equal('"\xC2 "', u("\xc2 ").inspect)
+ assert_equal('"\xE0\x80 "', u("\xe0\x80 ").inspect)
+ assert_equal('"\xF0\x80\x80 "', u("\xf0\x80\x80 ").inspect)
+ assert_equal('"\xF8\x80\x80\x80 "', u("\xf8\x80\x80\x80 ").inspect)
+ assert_equal('"\xFC\x80\x80\x80\x80 "', u("\xfc\x80\x80\x80\x80 ").inspect)
+
+ assert_equal('"\x81."', s("\x81.").inspect)
+ assert_equal('"\xFC"', u("\xfc").inspect)
+ end
+
+ def test_string_inspect_encoding
+ orig_int = Encoding.default_internal
+ orig_ext = Encoding.default_external
+ Encoding.default_internal = nil
+ [Encoding::UTF_8, Encoding::EUC_JP, Encoding::Windows_31J, Encoding::GB18030].
+ each do |e|
+ Encoding.default_external = e
+ str = "\x81\x30\x81\x30".force_encoding('GB18030')
+ assert_equal(Encoding::GB18030 == e ? %{"#{str}"} : '"\x{81308130}"', str.inspect)
+ str = e("\xa1\x8f\xa1\xa1")
+ expected = "\"\\xA1\x8F\xA1\xA1\"".force_encoding("EUC-JP")
+ assert_equal(Encoding::EUC_JP == e ? expected : "\"\\xA1\\x{8FA1A1}\"", str.inspect)
+ str = s("\x81@")
+ assert_equal(Encoding::Windows_31J == e ? %{"#{str}"} : '"\x{8140}"', str.inspect)
+ str = "\u3042\u{10FFFD}"
+ assert_equal(Encoding::UTF_8 == e ? %{"#{str}"} : '"\u3042\u{10FFFD}"', str.inspect)
+ end
+ Encoding.default_external = Encoding::UTF_8
+ [Encoding::UTF_16BE, Encoding::UTF_16LE, Encoding::UTF_32BE, Encoding::UTF_32LE,
+ Encoding::UTF8_SOFTBANK].each do |e|
+ str = "abc".encode(e)
+ assert_equal('"abc"', str.inspect)
+ end
+ ensure
+ Encoding.default_internal = orig_int
+ Encoding.default_external = orig_ext
+ end
+
+ def test_str_dump
+ [
+ e("\xfe"),
+ e("\x8e"),
+ e("\x8f"),
+ e("\x8f\xa1"),
+ s("\xef"),
+ u("\xc2"),
+ u("\xe0\x80"),
+ u("\xf0\x80\x80"),
+ u("\xf8\x80\x80\x80"),
+ u("\xfc\x80\x80\x80\x80"),
+
+ e("\xfe "),
+ e("\x8e "),
+ e("\x8f "),
+ e("\x8f\xa1 "),
+ s("\xef "),
+ u("\xc2 "),
+ u("\xe0\x80 "),
+ u("\xf0\x80\x80 "),
+ u("\xf8\x80\x80\x80 "),
+ u("\xfc\x80\x80\x80\x80 "),
+
+
+ e("\xa1\x8f\xa1\xa1"),
+
+ s("\x81."),
+ s("\x81@"),
+
+ u("\xfc"),
+ "\u3042",
+ "ascii",
+
+ "\u3042".encode("UTF-16LE"),
+ "\u3042".encode("UTF-16BE"),
+ ].each do |str|
+ assert_equal(str, eval(str.dump), "[ruby-dev:33142]")
+ end
+ end
+
+ def test_validate_redundant_utf8
+ bits_0x10ffff = "11110100 10001111 10111111 10111111"
+ [
+ "0xxxxxxx",
+ "110XXXXx 10xxxxxx",
+ "1110XXXX 10Xxxxxx 10xxxxxx",
+ "11110XXX 10XXxxxx 10xxxxxx 10xxxxxx",
+ "111110XX 10XXXxxx 10xxxxxx 10xxxxxx 10xxxxxx",
+ "1111110X 10XXXXxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx",
+ "11111110 10XXXXXx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx",
+ "11111111 10XXXXXX 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx",
+ ].each {|pat0|
+ [
+ pat0.gsub(/x/, '1'),
+ pat0.gsub(/x/, '0')
+ ].each {|pat1|
+ [
+ pat1.sub(/X([^X]*)\z/, '1\1').gsub(/X/, "0"),
+ pat1.gsub(/X/, "1"),
+ ].each {|pat2|
+ s = [pat2.gsub(/ /, "")].pack("B*").force_encoding("utf-8")
+ if pat2 <= bits_0x10ffff
+ assert(s.valid_encoding?, "#{pat2}")
+ else
+ assert(!s.valid_encoding?, "#{pat2}")
+ end
+ }
+ if / / =~ pat0
+ pat3 = pat1.gsub(/X/, "0")
+ s = [pat3.gsub(/ /, "")].pack("B*").force_encoding("utf-8")
+ assert(!s.valid_encoding?, "#{pat3}")
+ end
+ }
+ }
+ end
+
+ def test_validate_surrogate
+ # 1110XXXX 10Xxxxxx 10xxxxxx : 3 bytes UTF-8
+ pats = [
+ "11101101 10011111 10111111", # just before surrogate high
+ "11101101 1010xxxx 10xxxxxx", # surrogate high
+ "11101101 1011xxxx 10xxxxxx", # surrogate low
+ "11101110 10000000 10000000", # just after surrogate low
+ ]
+ pats.values_at(1,2).each {|pat0|
+ [
+ pat0.gsub(/x/, '0'),
+ pat0.gsub(/x/, '1'),
+ ].each {|pat1|
+ s = [pat1.gsub(/ /, "")].pack("B*").force_encoding("utf-8")
+ assert(!s.valid_encoding?, "#{pat1}")
+ }
+ }
+ pats.values_at(0,3).each {|pat|
+ s = [pat.gsub(/ /, "")].pack("B*").force_encoding("utf-8")
+ assert(s.valid_encoding?, "#{pat}")
+ }
+ end
+
+ def test_regexp_too_short_multibyte_character
+ assert_raise(SyntaxError) { eval('/\xfe/e') }
+ assert_raise(SyntaxError) { eval('/\x8e/e') }
+ assert_raise(SyntaxError) { eval('/\x8f/e') }
+ assert_raise(SyntaxError) { eval('/\x8f\xa1/e') }
+ assert_raise(SyntaxError) { eval('/\xef/s') }
+ assert_raise(SyntaxError) { eval('/\xc2/u') }
+ assert_raise(SyntaxError) { eval('/\xe0\x80/u') }
+ assert_raise(SyntaxError) { eval('/\xf0\x80\x80/u') }
+ assert_raise(SyntaxError) { eval('/\xf8\x80\x80\x80/u') }
+ assert_raise(SyntaxError) { eval('/\xfc\x80\x80\x80\x80/u') }
+
+ # raw 8bit
+ assert_raise(SyntaxError) { eval("/\xfe/e") }
+ assert_raise(SyntaxError) { eval("/\xc2/u") }
+
+ # invalid suffix
+ assert_raise(SyntaxError) { eval('/\xc2\xff/u') }
+ assert_raise(SyntaxError) { eval('/\xc2 /u') }
+ assert_raise(SyntaxError) { eval('/\xc2\x20/u') }
+ end
+
+ def test_regexp_generic
+ assert_regexp_generic_ascii(/a/)
+ assert_regexp_generic_ascii(Regexp.new(a("a")))
+ assert_regexp_generic_ascii(Regexp.new(e("a")))
+ assert_regexp_generic_ascii(Regexp.new(s("a")))
+ assert_regexp_generic_ascii(Regexp.new(u("a")))
+
+ [/a/, Regexp.new(a("a"))].each {|r|
+ assert_equal(0, r =~ a("a"))
+ assert_equal(0, r =~ e("a"))
+ assert_equal(0, r =~ s("a"))
+ assert_equal(0, r =~ u("a"))
+ assert_equal(nil, r =~ a("\xc2\xa1"))
+ assert_equal(nil, r =~ e("\xc2\xa1"))
+ assert_equal(nil, r =~ s("\xc2\xa1"))
+ assert_equal(nil, r =~ u("\xc2\xa1"))
+ }
+ end
+
+ def test_regexp_ascii_none
+ r = /a/n
+
+ assert_warning(%r{regexp match /.../n against to}) {
+ assert_regexp_generic_ascii(r)
+ }
+
+ assert_equal(0, r =~ a("a"))
+ assert_equal(0, r =~ e("a"))
+ assert_equal(0, r =~ s("a"))
+ assert_equal(0, r =~ u("a"))
+ assert_equal(nil, r =~ a("\xc2\xa1"))
+ assert_warning(%r{regexp match /.../n against to EUC-JP string}) {
+ assert_equal(nil, r =~ e("\xc2\xa1"))
+ }
+ assert_warning(%r{regexp match /.../n against to Windows-31J string}) {
+ assert_equal(nil, r =~ s("\xc2\xa1"))
+ }
+ assert_warning(%r{regexp match /.../n against to UTF-8 string}) {
+ assert_equal(nil, r =~ u("\xc2\xa1"))
+ }
+
+ assert_nothing_raised { eval(e("/\\x80/n")) }
+ end
+
+ def test_regexp_ascii
+ assert_regexp_fixed_ascii8bit(/\xc2\xa1/n)
+ assert_regexp_fixed_ascii8bit(eval(a(%{/\xc2\xa1/})))
+ assert_regexp_fixed_ascii8bit(eval(a(%{/\xc2\xa1/n})))
+ assert_regexp_fixed_ascii8bit(eval(a(%q{/\xc2\xa1/})))
+
+ assert_raise(SyntaxError) { eval("/\xa1\xa1/n".force_encoding("euc-jp")) }
+
+ [/\xc2\xa1/n, eval(a(%{/\xc2\xa1/})), eval(a(%{/\xc2\xa1/n}))].each {|r|
+ assert_equal(nil, r =~ a("a"))
+ assert_equal(nil, r =~ e("a"))
+ assert_equal(nil, r =~ s("a"))
+ assert_equal(nil, r =~ u("a"))
+ assert_equal(0, r =~ a("\xc2\xa1"))
+ assert_raise(Encoding::CompatibilityError) { r =~ e("\xc2\xa1") }
+ assert_raise(Encoding::CompatibilityError) { r =~ s("\xc2\xa1") }
+ assert_raise(Encoding::CompatibilityError) { r =~ u("\xc2\xa1") }
+ }
+ end
+
+ def test_regexp_euc
+ assert_regexp_fixed_eucjp(/a/e)
+ assert_regexp_fixed_eucjp(/\xc2\xa1/e)
+ assert_regexp_fixed_eucjp(eval(e(%{/\xc2\xa1/})))
+ assert_regexp_fixed_eucjp(eval(e(%q{/\xc2\xa1/})))
+
+ [/a/e].each {|r|
+ assert_equal(0, r =~ a("a"))
+ assert_equal(0, r =~ e("a"))
+ assert_equal(0, r =~ s("a"))
+ assert_equal(0, r =~ u("a"))
+ assert_raise(Encoding::CompatibilityError) { r =~ a("\xc2\xa1") }
+ assert_equal(nil, r =~ e("\xc2\xa1"))
+ assert_raise(Encoding::CompatibilityError) { r =~ s("\xc2\xa1") }
+ assert_raise(Encoding::CompatibilityError) { r =~ u("\xc2\xa1") }
+ }
+
+ [/\xc2\xa1/e, eval(e(%{/\xc2\xa1/})), eval(e(%q{/\xc2\xa1/}))].each {|r|
+ assert_equal(nil, r =~ a("a"))
+ assert_equal(nil, r =~ e("a"))
+ assert_equal(nil, r =~ s("a"))
+ assert_equal(nil, r =~ u("a"))
+ assert_raise(Encoding::CompatibilityError) { r =~ a("\xc2\xa1") }
+ assert_equal(0, r =~ e("\xc2\xa1"))
+ assert_raise(Encoding::CompatibilityError) { r =~ s("\xc2\xa1") }
+ assert_raise(Encoding::CompatibilityError) { r =~ u("\xc2\xa1") }
+ }
+ end
+
+ def test_regexp_sjis
+ assert_regexp_fixed_sjis(/a/s)
+ assert_regexp_fixed_sjis(/\xc2\xa1/s)
+ assert_regexp_fixed_sjis(eval(s(%{/\xc2\xa1/})))
+ assert_regexp_fixed_sjis(eval(s(%q{/\xc2\xa1/})))
+ end
+
+ def test_regexp_windows_31j
+ begin
+ Regexp.new("\xa1".force_encoding("windows-31j")) =~ "\xa1\xa1".force_encoding("euc-jp")
+ rescue Encoding::CompatibilityError
+ err = $!
+ end
+ assert_match(/windows-31j/i, err.message)
+ end
+
+ def test_regexp_embed
+ r = eval(e("/\xc2\xa1/"))
+ assert_raise(RegexpError) { eval(s("/\xc2\xa1\#{r}/s")) }
+ assert_raise(RegexpError) { eval(s("/\#{r}\xc2\xa1/s")) }
+
+ r = /\xc2\xa1/e
+ assert_raise(RegexpError) { eval(s("/\xc2\xa1\#{r}/s")) }
+ assert_raise(RegexpError) { eval(s("/\#{r}\xc2\xa1/s")) }
+
+ r = eval(e("/\xc2\xa1/"))
+ assert_raise(RegexpError) { /\xc2\xa1#{r}/s }
+
+ r = /\xc2\xa1/e
+ assert_raise(RegexpError) { /\xc2\xa1#{r}/s }
+
+ r1 = Regexp.new('foo'.force_encoding("ascii-8bit"))
+ r2 = eval('/bar#{r1}/'.force_encoding('ascii-8bit'))
+ assert_equal(Encoding::US_ASCII, r2.encoding)
+
+ r1 = Regexp.new('foo'.force_encoding("us-ascii"))
+ r2 = eval('/bar#{r1}/'.force_encoding('ascii-8bit'))
+ assert_equal(Encoding::US_ASCII, r2.encoding)
+
+ r1 = Regexp.new('foo'.force_encoding("ascii-8bit"))
+ r2 = eval('/bar#{r1}/'.force_encoding('us-ascii'))
+ assert_equal(Encoding::US_ASCII, r2.encoding)
+
+ r1 = Regexp.new('foo'.force_encoding("us-ascii"))
+ r2 = eval('/bar#{r1}/'.force_encoding('us-ascii'))
+ assert_equal(Encoding::US_ASCII, r2.encoding)
+
+ r1 = Regexp.new('\xa1'.force_encoding("ascii-8bit"))
+ r2 = eval('/bar#{r1}/'.force_encoding('ascii-8bit'))
+ assert_equal(Encoding::ASCII_8BIT, r2.encoding)
+
+ r1 = Regexp.new('\xa1'.force_encoding("ascii-8bit"))
+ r2 = eval('/bar#{r1}/'.force_encoding('us-ascii'))
+ assert_equal(Encoding::ASCII_8BIT, r2.encoding)
+
+ r1 = Regexp.new('foo'.force_encoding("ascii-8bit"))
+ r2 = eval('/\xa1#{r1}/'.force_encoding('ascii-8bit'))
+ assert_equal(Encoding::ASCII_8BIT, r2.encoding)
+
+ r1 = Regexp.new('foo'.force_encoding("us-ascii"))
+ r2 = eval('/\xa1#{r1}/'.force_encoding('ascii-8bit'))
+ assert_equal(Encoding::ASCII_8BIT, r2.encoding)
+
+ r1 = Regexp.new('\xa1'.force_encoding("ascii-8bit"))
+ r2 = eval('/\xa1#{r1}/'.force_encoding('ascii-8bit'))
+ assert_equal(Encoding::ASCII_8BIT, r2.encoding)
+ end
+
+ def test_regexp_named_class
+ assert_match(/[[:space:]]/u, "\u{00a0}")
+ assert_match(/[[:space:]]/, "\u{00a0}")
+ end
+
+ def test_regexp_property
+ s = '\p{Hiragana}'.force_encoding("euc-jp")
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ r = nil
+ assert_nothing_raised {
+ r = Regexp.new(s)
+ }
+ assert(r.fixed_encoding?)
+ assert_match(r, "\xa4\xa2".force_encoding("euc-jp"))
+
+ r = eval('/\p{Hiragana}/'.force_encoding("euc-jp"))
+ assert(r.fixed_encoding?)
+ assert_match(r, "\xa4\xa2".force_encoding("euc-jp"))
+
+ r = /\p{Hiragana}/e
+ assert(r.fixed_encoding?)
+ assert_match(r, "\xa4\xa2".force_encoding("euc-jp"))
+
+ r = eval('/\u{3042}\p{Hiragana}/'.force_encoding("euc-jp"))
+ assert(r.fixed_encoding?)
+ assert_equal(Encoding::UTF_8, r.encoding)
+
+ r = eval('/\p{Hiragana}\u{3042}/'.force_encoding("euc-jp"))
+ assert(r.fixed_encoding?)
+ assert_equal(Encoding::UTF_8, r.encoding)
+ end
+
+ def test_regexp_embed_preprocess
+ r1 = /\xa4\xa2/e
+ r2 = /#{r1}/
+ assert(r2.source.include?(r1.source))
+ end
+
+ def test_begin_end_offset
+ str = e("\244\242\244\244\244\246\244\250\244\252a")
+ assert(/(a)/ =~ str)
+ assert_equal("a", $&)
+ assert_equal(5, $~.begin(0))
+ assert_equal(6, $~.end(0))
+ assert_equal([5,6], $~.offset(0))
+ assert_equal(5, $~.begin(1))
+ assert_equal(6, $~.end(1))
+ assert_equal([5,6], $~.offset(1))
+ end
+
+ def test_begin_end_offset_sjis
+ str = s("\x81@@")
+ assert(/@/ =~ str)
+ assert_equal(s("\x81@"), $`)
+ assert_equal("@", $&)
+ assert_equal("", $')
+ assert_equal([1,2], $~.offset(0))
+ end
+
+ def test_quote
+ assert_regexp_generic_ascii(/#{Regexp.quote(a("a"))}#{Regexp.quote(e("e"))}/)
+
+ assert_encoding("US-ASCII", Regexp.quote(a("")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(e("")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(s("")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(u("")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(a("a")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(e("a")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(s("a")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(u("a")).encoding)
+
+ assert_encoding("ASCII-8BIT", Regexp.quote(a("\xc2\xa1")).encoding)
+ assert_encoding("EUC-JP", Regexp.quote(e("\xc2\xa1")).encoding)
+ assert_encoding("Windows-31J", Regexp.quote(s("\xc2\xa1")).encoding)
+ assert_encoding("UTF-8", Regexp.quote(u("\xc2\xa1")).encoding)
+ end
+
+ def test_union_0
+ r = Regexp.union
+ assert_regexp_generic_ascii(r)
+ assert(r !~ a(""))
+ assert(r !~ e(""))
+ assert(r !~ s(""))
+ assert(r !~ u(""))
+ end
+
+ def test_union_1_asciionly_string
+ assert_regexp_generic_ascii(Regexp.union(a("")))
+ assert_regexp_generic_ascii(Regexp.union(e("")))
+ assert_regexp_generic_ascii(Regexp.union(s("")))
+ assert_regexp_generic_ascii(Regexp.union(u("")))
+ assert_regexp_generic_ascii(Regexp.union(a("a")))
+ assert_regexp_generic_ascii(Regexp.union(e("a")))
+ assert_regexp_generic_ascii(Regexp.union(s("a")))
+ assert_regexp_generic_ascii(Regexp.union(u("a")))
+ assert_regexp_generic_ascii(Regexp.union(a("\t")))
+ assert_regexp_generic_ascii(Regexp.union(e("\t")))
+ assert_regexp_generic_ascii(Regexp.union(s("\t")))
+ assert_regexp_generic_ascii(Regexp.union(u("\t")))
+ end
+
+ def test_union_1_nonascii_string
+ assert_regexp_fixed_ascii8bit(Regexp.union(a("\xc2\xa1")))
+ assert_regexp_fixed_eucjp(Regexp.union(e("\xc2\xa1")))
+ assert_regexp_fixed_sjis(Regexp.union(s("\xc2\xa1")))
+ assert_regexp_fixed_utf8(Regexp.union(u("\xc2\xa1")))
+ end
+
+ def test_union_1_regexp
+ assert_regexp_generic_ascii(Regexp.union(//))
+ assert_warning(%r{regexp match /.../n against to}) {
+ assert_regexp_generic_ascii(Regexp.union(//n))
+ }
+ assert_regexp_fixed_eucjp(Regexp.union(//e))
+ assert_regexp_fixed_sjis(Regexp.union(//s))
+ assert_regexp_fixed_utf8(Regexp.union(//u))
+ end
+
+ def test_union_2
+ ary = [
+ a(""), e(""), s(""), u(""),
+ a("\xc2\xa1"), e("\xc2\xa1"), s("\xc2\xa1"), u("\xc2\xa1")
+ ]
+ ary.each {|s1|
+ ary.each {|s2|
+ if s1.empty?
+ if s2.empty?
+ assert_regexp_generic_ascii(Regexp.union(s1, s2))
+ else
+ r = Regexp.union(s1, s2)
+ assert_regexp_fixed_encoding(r)
+ assert_equal(s2.encoding, r.encoding)
+ end
+ else
+ if s2.empty?
+ r = Regexp.union(s1, s2)
+ assert_regexp_fixed_encoding(r)
+ assert_equal(s1.encoding, r.encoding)
+ else
+ if s1.encoding == s2.encoding
+ r = Regexp.union(s1, s2)
+ assert_regexp_fixed_encoding(r)
+ assert_equal(s1.encoding, r.encoding)
+ else
+ assert_raise(ArgumentError) { Regexp.union(s1, s2) }
+ end
+ end
+ end
+ }
+ }
+ end
+
+ def test_dynamic_ascii_regexp
+ assert_warning(%r{regexp match /.../n against to}) {
+ assert_regexp_generic_ascii(/#{ }/n)
+ }
+ assert_regexp_fixed_ascii8bit(/#{ }\xc2\xa1/n)
+ assert_regexp_fixed_ascii8bit(/\xc2\xa1#{ }/n)
+ assert_nothing_raised { s1, s2 = a('\xc2'), a('\xa1'); /#{s1}#{s2}/ }
+ end
+
+ def test_dynamic_eucjp_regexp
+ assert_regexp_fixed_eucjp(/#{ }/e)
+ assert_regexp_fixed_eucjp(/#{ }\xc2\xa1/e)
+ assert_regexp_fixed_eucjp(/\xc2\xa1#{ }/e)
+ assert_raise(SyntaxError) { eval('/\xc2#{ }/e') }
+ assert_raise(SyntaxError) { eval('/#{ }\xc2/e') }
+ assert_raise(SyntaxError) { eval('/\xc2#{ }\xa1/e') }
+ assert_raise(ArgumentError) { s1, s2 = e('\xc2'), e('\xa1'); /#{s1}#{s2}/ }
+ end
+
+ def test_dynamic_sjis_regexp
+ assert_regexp_fixed_sjis(/#{ }/s)
+ assert_regexp_fixed_sjis(/#{ }\xc2\xa1/s)
+ assert_regexp_fixed_sjis(/\xc2\xa1#{ }/s)
+ assert_raise(SyntaxError) { eval('/\x81#{ }/s') }
+ assert_raise(SyntaxError) { eval('/#{ }\x81/s') }
+ assert_raise(SyntaxError) { eval('/\x81#{ }\xa1/s') }
+ assert_raise(ArgumentError) { s1, s2 = s('\x81'), s('\xa1'); /#{s1}#{s2}/ }
+ end
+
+ def test_dynamic_utf8_regexp
+ assert_regexp_fixed_utf8(/#{ }/u)
+ assert_regexp_fixed_utf8(/#{ }\xc2\xa1/u)
+ assert_regexp_fixed_utf8(/\xc2\xa1#{ }/u)
+ assert_raise(SyntaxError) { eval('/\xc2#{ }/u') }
+ assert_raise(SyntaxError) { eval('/#{ }\xc2/u') }
+ assert_raise(SyntaxError) { eval('/\xc2#{ }\xa1/u') }
+ assert_raise(ArgumentError) { s1, s2 = u('\xc2'), u('\xa1'); /#{s1}#{s2}/ }
+ end
+
+ def test_regexp_unicode
+ assert_nothing_raised { eval '/\u{0}/u' }
+ assert_nothing_raised { eval '/\u{D7FF}/u' }
+ assert_raise(SyntaxError) { eval '/\u{D800}/u' }
+ assert_raise(SyntaxError) { eval '/\u{DFFF}/u' }
+ assert_nothing_raised { eval '/\u{E000}/u' }
+ assert_nothing_raised { eval '/\u{10FFFF}/u' }
+ assert_raise(SyntaxError) { eval '/\u{110000}/u' }
+ end
+
+ def test_regexp_mixed_unicode
+ assert_raise(SyntaxError) { eval(a(%{/\xc2\xa1\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\xc2\xa1\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\xc2\xa1\\u{6666}/})) }
+ assert_nothing_raised { eval(u(%{/\xc2\xa1\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(a(%{/\\u{6666}\xc2\xa1/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\\u{6666}\xc2\xa1/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\\u{6666}\xc2\xa1/})) }
+ assert_nothing_raised { eval(u(%{/\\u{6666}\xc2\xa1/})) }
+
+ assert_raise(SyntaxError) { eval(a(%{/\\xc2\\xa1\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\\xc2\\xa1\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\\xc2\\xa1\\u{6666}/})) }
+ assert_nothing_raised { eval(u(%{/\\xc2\\xa1\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(a(%{/\\u{6666}\\xc2\\xa1/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\\u{6666}\\xc2\\xa1/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\\u{6666}\\xc2\\xa1/})) }
+ assert_nothing_raised { eval(u(%{/\\u{6666}\\xc2\\xa1/})) }
+
+ assert_raise(SyntaxError) { eval(a(%{/\xc2\xa1#{ }\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\xc2\xa1#{ }\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\xc2\xa1#{ }\\u{6666}/})) }
+ assert_nothing_raised { eval(u(%{/\xc2\xa1#{ }\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(a(%{/\\u{6666}#{ }\xc2\xa1/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\\u{6666}#{ }\xc2\xa1/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\\u{6666}#{ }\xc2\xa1/})) }
+ assert_nothing_raised { eval(u(%{/\\u{6666}#{ }\xc2\xa1/})) }
+
+ assert_raise(SyntaxError) { eval(a(%{/\\xc2\\xa1#{ }\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\\xc2\\xa1#{ }\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\\xc2\\xa1#{ }\\u{6666}/})) }
+ assert_nothing_raised { eval(u(%{/\\xc2\\xa1#{ }\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(a(%{/\\u{6666}#{ }\\xc2\\xa1/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\\u{6666}#{ }\\xc2\\xa1/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\\u{6666}#{ }\\xc2\\xa1/})) }
+ assert_nothing_raised { eval(u(%{/\\u{6666}#{ }\\xc2\\xa1/})) }
+ end
+
+ def test_str_allocate
+ s = String.allocate
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ end
+
+ def test_str_String
+ s = String(10)
+ assert_equal(Encoding::US_ASCII, s.encoding)
+ end
+
+ def test_sprintf_c
+ assert_strenc("\x80", 'ASCII-8BIT', a("%c") % 128)
+ #assert_raise(ArgumentError) { a("%c") % 0xc2a1 }
+ assert_strenc("\xc2\xa1", 'EUC-JP', e("%c") % 0xc2a1)
+ assert_raise(ArgumentError) { e("%c") % 0xc2 }
+ assert_strenc("\xc2", 'Windows-31J', s("%c") % 0xc2)
+ #assert_raise(ArgumentError) { s("%c") % 0xc2a1 }
+ assert_strenc("\u{c2a1}", 'UTF-8', u("%c") % 0xc2a1)
+ assert_strenc("\u{c2}", 'UTF-8', u("%c") % 0xc2)
+ assert_raise(Encoding::CompatibilityError) {
+ "%s%s" % [s("\xc2\xa1"), e("\xc2\xa1")]
+ }
+ end
+
+ def test_sprintf_p
+ enc = "".inspect.encoding
+ asc = Encoding::US_ASCII
+ Encoding.list.each do |e|
+ format = "%p".force_encoding(e)
+ ['', 'a', "\xC2\xA1", "\x00"].each do |s|
+ s.force_encoding(e)
+ assert_strenc(s.inspect, e.ascii_compatible? && enc == asc ? e : enc, format % s)
+ end
+ s = "\xC2\xA1".force_encoding(e)
+ assert_strenc('%10s' % s.inspect, enc, "%10p" % s)
+ end
+ end
+
+ def test_sprintf_s
+ assert_strenc('', 'ASCII-8BIT', a("%s") % a(""))
+ assert_strenc('', 'EUC-JP', e("%s") % e(""))
+ assert_strenc('', 'Windows-31J', s("%s") % s(""))
+ assert_strenc('', 'UTF-8', u("%s") % u(""))
+
+ assert_strenc('a', 'ASCII-8BIT', a("%s") % a("a"))
+ assert_strenc('a', 'EUC-JP', e("%s") % e("a"))
+ assert_strenc('a', 'Windows-31J', s("%s") % s("a"))
+ assert_strenc('a', 'UTF-8', u("%s") % u("a"))
+
+ assert_strenc("\xC2\xA1", 'ASCII-8BIT', a("%s") % a("\xc2\xa1"))
+ assert_strenc("\xC2\xA1", 'EUC-JP', e("%s") % e("\xc2\xa1"))
+ #assert_strenc("\xC2\xA1", 'Windows-31J', s("%s") % s("\xc2\xa1"))
+ assert_strenc("\xC2\xA1", 'UTF-8', u("%s") % u("\xc2\xa1"))
+
+ assert_strenc(" \xC2\xA1", 'ASCII-8BIT', "%10s" % a("\xc2\xa1"))
+ assert_strenc(" \xA1\xA1", 'EUC-JP', "%10s" % e("\xa1\xa1"))
+ #assert_strenc(" \xC2\xA1", 'Windows-31J', "%10s" % s("\xc2\xa1"))
+ assert_strenc(" \xC2\xA1", 'UTF-8', "%10s" % u("\xc2\xa1"))
+
+ assert_strenc("\x00", 'ASCII-8BIT', a("%s") % a("\x00"))
+ assert_strenc("\x00", 'EUC-JP', e("%s") % e("\x00"))
+ assert_strenc("\x00", 'Windows-31J', s("%s") % s("\x00"))
+ assert_strenc("\x00", 'UTF-8', u("%s") % u("\x00"))
+ assert_equal("EUC-JP", (e("\xc2\xa1 %s") % "foo").encoding.name)
+ end
+
+ def test_str_lt
+ assert(a("a") < a("\xa1"))
+ assert(a("a") < s("\xa1"))
+ assert(s("a") < a("\xa1"))
+ end
+
+ def test_str_multiply
+ str = "\u3042"
+ assert_equal(true, (str * 0).ascii_only?, "[ruby-dev:33895]")
+ assert_equal(false, (str * 1).ascii_only?)
+ assert_equal(false, (str * 2).ascii_only?)
+ end
+
+ def test_str_aref
+ assert_equal(a("\xc2"), a("\xc2\xa1")[0])
+ assert_equal(a("\xa1"), a("\xc2\xa1")[1])
+ assert_equal(nil, a("\xc2\xa1")[2])
+ assert_equal(e("\xc2\xa1"), e("\xc2\xa1")[0])
+ assert_equal(nil, e("\xc2\xa1")[1])
+ assert_equal(s("\xc2"), s("\xc2\xa1")[0])
+ assert_equal(s("\xa1"), s("\xc2\xa1")[1])
+ assert_equal(nil, s("\xc2\xa1")[2])
+ assert_equal(u("\xc2\xa1"), u("\xc2\xa1")[0])
+ assert_equal(nil, u("\xc2\xa1")[1])
+
+ str = "\u3042"
+ assert_equal(true, str[0, 0].ascii_only?, "[ruby-dev:33895]")
+ assert_equal(false, str[0, 1].ascii_only?)
+ assert_equal(false, str[0..-1].ascii_only?)
+ end
+
+ def test_utf8str_aref
+ s = "abcdefghijklmnopqrstuvwxyz\u{3042 3044 3046 3048 304A}"
+ assert_equal("a", s[0])
+ assert_equal("h", s[7])
+ assert_equal("i", s[8])
+ assert_equal("j", s[9])
+ assert_equal("\u{3044}", s[27])
+ assert_equal("\u{3046}", s[28])
+ assert_equal("\u{3048}", s[29])
+ s = "abcdefghijklmnopqrstuvw\u{3042 3044 3046 3048 304A}"
+ assert_equal("\u{3044}", s[24])
+ end
+
+ def test_str_aref_len
+ assert_equal(a("\xa1"), a("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 1])
+ assert_equal(a("\xa1\xc2"), a("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 2])
+
+ assert_equal(e("\xc2\xa2"), e("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 1])
+ assert_equal(e("\xc2\xa2\xc2\xa3"), e("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 2])
+
+ assert_equal(s("\xa1"), s("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 1])
+ assert_equal(s("\xa1\xc2"), s("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 2])
+
+ assert_equal(u("\xc2\xa2"), u("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 1])
+ assert_equal(u("\xc2\xa2\xc2\xa3"), u("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 2])
+ end
+
+ def test_str_aref_substr
+ assert_equal(a("\xa1\xc2"), a("\xc2\xa1\xc2\xa2\xc2\xa3")[a("\xa1\xc2")])
+ assert_raise(Encoding::CompatibilityError) { a("\xc2\xa1\xc2\xa2\xc2\xa3")[e("\xa1\xc2")] }
+
+ assert_equal(nil, e("\xc2\xa1\xc2\xa2\xc2\xa3")[e("\xa1\xc2")])
+ assert_raise(Encoding::CompatibilityError) { e("\xc2\xa1\xc2\xa2\xc2\xa3")[s("\xa1\xc2")] }
+
+ assert_equal(s("\xa1\xc2"), s("\xc2\xa1\xc2\xa2\xc2\xa3")[s("\xa1\xc2")])
+ assert_raise(Encoding::CompatibilityError) { s("\xc2\xa1\xc2\xa2\xc2\xa3")[u("\xa1\xc2")] }
+
+ assert_equal(nil, u("\xc2\xa1\xc2\xa2\xc2\xa3")[u("\xa1\xc2")])
+ assert_raise(Encoding::CompatibilityError) { u("\xc2\xa1\xc2\xa2\xc2\xa3")[a("\xa1\xc2")] }
+ assert_nil(e("\xa1\xa2\xa3\xa4")[e("\xa2\xa3")])
+
+ bug2379 = '[ruby-core:26787]'
+ assert_equal("\u{439}", "\u{439}"[0, 30], bug2379)
+ assert_equal("\u{439}", "a\u{439}"[1, 30], bug2379)
+ assert_equal("\u{439}", "a\u{439}bcdefghijklmnop"[1, 1][0, 1], bug2379)
+ end
+
+ def test_aset
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_raise(Encoding::CompatibilityError){s["\xb0\xa3"] = "foo"}
+ end
+
+ def test_str_center
+ assert_encoding("EUC-JP", "a".center(5, e("\xa1\xa2")).encoding)
+ assert_encoding("EUC-JP", e("\xa3\xb0").center(10).encoding)
+ end
+
+ def test_squeeze
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb1\xa3\xb3\xa3\xb4")
+ assert_equal(e("\xa3\xb0\xa3\xb1\xa3\xb3\xa3\xb4"), s.squeeze)
+ end
+
+ def test_tr
+ s = s("\x81\x41")
+ assert_equal(s.tr("A", "B"), s)
+ assert_equal(s.tr_s("A", "B"), s)
+
+ assert_nothing_raised {
+ "a".force_encoding("ASCII-8BIT").tr(a("a"), a("a"))
+ }
+
+ assert_equal(e("\xA1\xA1"), a("a").tr(a("a"), e("\xA1\xA1")))
+
+ assert_equal("X\u3042\u3044X", "A\u3042\u3044\u3046".tr("^\u3042\u3044", "X"))
+ assert_equal("\u3042\u3046" * 100, ("\u3042\u3044" * 100).tr("\u3044", "\u3046"))
+ end
+
+ def test_tr_s
+ skip("[BUG : #827] Assertion")
+
+ assert_equal("\xA1\xA1".force_encoding("EUC-JP"),
+ "a".force_encoding("ASCII-8BIT").tr("a".force_encoding("ASCII-8BIT"), "\xA1\xA1".force_encoding("EUC-JP")))
+ end
+
+ def test_count
+ assert_equal(0, e("\xa1\xa2").count("z"))
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_raise(Encoding::CompatibilityError){s.count(a("\xa3\xb0"))}
+ end
+
+ def test_delete
+ assert_equal(1, e("\xa1\xa2").delete("z").length)
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_raise(Encoding::CompatibilityError){s.delete(a("\xa3\xb2"))}
+
+ a = "\u3042\u3044\u3046\u3042\u3044\u3046"
+ a.delete!("\u3042\u3044", "^\u3044")
+ assert_equal("\u3044\u3046\u3044\u3046", a)
+ end
+
+ def test_include?
+ assert_equal(false, e("\xa1\xa2\xa3\xa4").include?(e("\xa3")))
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_equal(false, s.include?(e("\xb0\xa3")))
+ end
+
+ def test_index
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_nil(s.index(e("\xb3\xa3")))
+ assert_nil(e("\xa1\xa2\xa3\xa4").index(e("\xa3")))
+ assert_nil(e("\xa1\xa2\xa3\xa4").rindex(e("\xa3")))
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_raise(Encoding::CompatibilityError){s.rindex(a("\xb1\xa3"))}
+ end
+
+ def test_next
+ s1 = e("\xa1\xa1")
+ s2 = s1.dup
+ (94*94+94).times { s2.next! }
+ assert_not_equal(s1, s2)
+ end
+
+ def test_sub
+ s = "abc".sub(/b/, "\xa1\xa1".force_encoding("euc-jp"))
+ assert_encoding("EUC-JP", s.encoding)
+ assert_equal(Encoding::EUC_JP, "\xa4\xa2".force_encoding("euc-jp").sub(/./, '\&').encoding)
+ assert_equal(Encoding::EUC_JP, "\xa4\xa2".force_encoding("euc-jp").gsub(/./, '\&').encoding)
+ end
+
+ def test_sub2
+ s = "\x80".force_encoding("ASCII-8BIT")
+ r = Regexp.new("\x80".force_encoding("ASCII-8BIT"))
+ s2 = s.sub(r, "")
+ assert(s2.empty?)
+ assert(s2.ascii_only?)
+ end
+
+ def test_sub3
+ repl = "\x81".force_encoding("sjis")
+ assert_equal(false, repl.valid_encoding?)
+ s = "a@".sub(/a/, repl)
+ assert(s.valid_encoding?)
+ end
+
+ def test_insert
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_equal(e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4a"), s.insert(-1, "a"))
+ end
+
+ def test_scan
+ assert_equal(["a"], e("\xa1\xa2a\xa3\xa4").scan(/a/))
+ end
+
+ def test_dup_scan
+ s1 = e("\xa4\xa2")*100
+ s2 = s1.dup.force_encoding("ascii-8bit")
+ s2.scan(/\A./n) {|f|
+ assert_equal(Encoding::ASCII_8BIT, f.encoding)
+ }
+ end
+
+ def test_dup_aref
+ s1 = e("\xa4\xa2")*100
+ s2 = s1.dup.force_encoding("ascii-8bit")
+ assert_equal(Encoding::ASCII_8BIT, s2[10..-1].encoding)
+ end
+
+ def test_upto
+ s1 = e("\xa1\xa2")
+ s2 = s("\xa1\xa2")
+ assert_raise(Encoding::CompatibilityError){s1.upto(s2) {|x| break }}
+ end
+
+ def test_casecmp
+ s1 = s("\x81\x41")
+ s2 = s("\x81\x61")
+ assert_not_equal(0, s1.casecmp(s2))
+ end
+
+ def test_reverse
+ assert_equal(u("\xf0jihgfedcba"), u("abcdefghij\xf0").reverse)
+ end
+
+ def test_reverse_bang
+ s = u("abcdefghij\xf0")
+ s.reverse!
+ assert_equal(u("\xf0jihgfedcba"), s)
+ end
+
+ def test_plus
+ assert_raise(Encoding::CompatibilityError){u("\xe3\x81\x82") + a("\xa1")}
+ end
+
+ def test_chomp
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_raise(Encoding::CompatibilityError){s.chomp(s("\xa3\xb4"))}
+ end
+
+ def test_gsub
+ s = 'abc'
+ s.ascii_only?
+ s.gsub!(/b/, "\x80")
+ assert_equal(false, s.ascii_only?, "[ruby-core:14566] reported by Sam Ruby")
+
+ s = "abc".force_encoding(Encoding::ASCII_8BIT)
+ t = s.gsub(/b/, "\xa1\xa1".force_encoding("euc-jp"))
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+
+ assert_raise(Encoding::CompatibilityError) {
+ "abc".gsub(/[ac]/) {
+ $& == "a" ? "\xc2\xa1".force_encoding("euc-jp") :
+ "\xc2\xa1".force_encoding("utf-8")
+ }
+ }
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_equal(e("\xa3\xb0z\xa3\xb2\xa3\xb3\xa3\xb4"), s.gsub(/\xa3\xb1/e, "z"))
+
+ assert_equal(Encoding::EUC_JP, (a("").gsub(//) { e("") }.encoding))
+ assert_equal(Encoding::EUC_JP, (a("a").gsub(/a/) { e("") }.encoding))
+ end
+
+ def test_end_with
+ s1 = s("\x81\x40")
+ s2 = "@"
+ assert_equal(false, s1.end_with?(s2), "#{encdump s1}.end_with?(#{encdump s2})")
+ end
+
+ def test_each_line
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_raise(Encoding::CompatibilityError){s.each_line(a("\xa3\xb1")) {|l| }}
+ s = e("\xa4\xa2\nfoo")
+
+ actual = []
+ s.each_line {|line| actual << line }
+ expected = [e("\xa4\xa2\n"), e("foo")]
+ assert_equal(expected, actual)
+ end
+
+ def test_each_char
+ a = [e("\xa4\xa2"), "b", e("\xa4\xa4"), "c"]
+ s = "\xa4\xa2b\xa4\xa4c".force_encoding("euc-jp")
+ assert_equal(a, s.each_char.to_a, "[ruby-dev:33211] #{encdump s}.each_char.to_a")
+ end
+
+ def test_regexp_match
+ assert_equal([0,0], //.match("\xa1\xa1".force_encoding("euc-jp"),-1).offset(0))
+ assert_equal(0, // =~ :a)
+ end
+
+ def test_split
+ assert_equal(e("\xa1\xa2\xa1\xa3").split(//),
+ [e("\xa1\xa2"), e("\xa1\xa3")],
+ '[ruby-dev:32452]')
+ end
+
+ def test_nonascii_method_name
+ eval(e("def \xc2\xa1() @nonascii_method_name = :e end"))
+ eval(u("def \xc2\xa1() @nonascii_method_name = :u end"))
+ eval(e("\xc2\xa1()"))
+ assert_equal(:e, @nonascii_method_name)
+ eval(u("\xc2\xa1()"))
+ assert_equal(:u, @nonascii_method_name)
+ me = method(e("\xc2\xa1"))
+ mu = method(u("\xc2\xa1"))
+ assert_not_equal(me.name, mu.name)
+ assert_not_equal(me.inspect, mu.inspect)
+ assert_equal(e("\xc2\xa1"), me.name.to_s)
+ assert_equal(u("\xc2\xa1"), mu.name.to_s)
+ end
+
+ def test_symbol
+ s1 = "\xc2\xa1".force_encoding("euc-jp").intern
+ s2 = "\xc2\xa1".force_encoding("utf-8").intern
+ assert_not_equal(s1, s2)
+ end
+
+ def test_symbol_op
+ ops = %w"
+ .. ... + - +(binary) -(binary) * / % ** +@ -@ | ^ & ! <=> > >= < <= ==
+ === != =~ !~ ~ ! [] []= << >> :: `
+ "
+ ops.each do |op|
+ assert_equal(Encoding::US_ASCII, op.intern.encoding, "[ruby-dev:33449]")
+ end
+ end
+
+ def test_chr
+ 0.upto(255) {|b|
+ assert_equal([b].pack("C"), b.chr)
+ }
+ end
+
+ def test_marshal
+ s1 = "\xa1\xa1".force_encoding("euc-jp")
+ s2 = Marshal.load(Marshal.dump(s1))
+ assert_equal(s1, s2)
+ end
+
+ def test_env
+ locale_encoding = Encoding.find("locale")
+ ENV.each {|k, v|
+ assert_equal(locale_encoding, k.encoding)
+ assert_equal(locale_encoding, v.encoding)
+ }
+ end
+
+ def test_empty_string
+ assert_equal(Encoding::US_ASCII, "".encoding)
+ end
+
+ def test_nil_to_s
+ assert_equal(Encoding::US_ASCII, nil.to_s.encoding)
+ end
+
+ def test_nil_inspect
+ assert_equal(Encoding::US_ASCII, nil.inspect.encoding)
+ end
+
+ def test_true_to_s
+ assert_equal(Encoding::US_ASCII, true.to_s.encoding)
+ end
+
+ def test_false_to_s
+ assert_equal(Encoding::US_ASCII, false.to_s.encoding)
+ end
+
+ def test_fixnum_to_s
+ assert_equal(Encoding::US_ASCII, 1.to_s.encoding)
+ end
+
+ def test_float_to_s
+ assert_equal(Encoding::US_ASCII, 1.0.to_s.encoding)
+ end
+
+ def test_bignum_to_s
+ assert_equal(Encoding::US_ASCII, (1 << 129).to_s.encoding)
+ end
+
+ def test_array_to_s
+ assert_equal(Encoding::US_ASCII, [].to_s.encoding)
+ assert_equal(Encoding::US_ASCII, [nil].to_s.encoding)
+ assert_equal(Encoding::US_ASCII, [1].to_s.encoding)
+ assert_equal("".inspect.encoding, [""].to_s.encoding)
+ assert_equal("a".inspect.encoding, ["a"].to_s.encoding)
+ assert_equal(Encoding::US_ASCII, [nil,1,"","a","\x20",[]].to_s.encoding)
+ end
+
+ def test_hash_to_s
+ assert_equal(Encoding::US_ASCII, {}.to_s.encoding)
+ assert_equal(Encoding::US_ASCII, {1=>nil,"foo"=>""}.to_s.encoding)
+ end
+
+ def test_encoding_find
+ assert_raise(TypeError) {Encoding.find(nil)}
+ assert_raise(TypeError) {Encoding.find(0)}
+ assert_raise(TypeError) {Encoding.find([])}
+ assert_raise(TypeError) {Encoding.find({})}
+ end
+
+ def test_encoding_to_s
+ assert_equal(Encoding::US_ASCII, Encoding::US_ASCII.to_s.encoding)
+ assert_equal(Encoding::US_ASCII, Encoding::US_ASCII.inspect.encoding)
+ end
+
+ def test_regexp_source
+ s = "\xa4\xa2".force_encoding("euc-jp")
+ r = Regexp.new(s)
+ t = r.source
+ assert_equal(s, t, "[ruby-dev:33377] Regexp.new(#{encdump s}).source")
+ end
+
+ def test_magic_comment
+ assert_equal(Encoding::US_ASCII, eval("__ENCODING__".force_encoding("US-ASCII")))
+ assert_equal(Encoding::ASCII_8BIT, eval("__ENCODING__".force_encoding("ASCII-8BIT")))
+ assert_equal(Encoding::US_ASCII, eval("# -*- encoding: US-ASCII -*-\n__ENCODING__".force_encoding("ASCII-8BIT")))
+ assert_equal(Encoding::ASCII_8BIT, eval("# -*- encoding: ASCII-8BIT -*-\n__ENCODING__".force_encoding("US-ASCII")))
+ end
+
+ def test_magic_comment_vim
+ assert_equal(Encoding::US_ASCII, eval("# vim: filetype=ruby, fileencoding: US-ASCII, ts=3, sw=3\n__ENCODING__".force_encoding("ASCII-8BIT")))
+ assert_equal(Encoding::ASCII_8BIT, eval("# vim: filetype=ruby, fileencoding: ASCII-8BIT, ts=3, sw=3\n__ENCODING__".force_encoding("US-ASCII")))
+ end
+
+ def test_magic_comment_at_various_positions
+ # after shebang
+ assert_equal(Encoding::US_ASCII, eval("#!/usr/bin/ruby\n# -*- encoding: US-ASCII -*-\n__ENCODING__".force_encoding("ASCII-8BIT")))
+ assert_equal(Encoding::ASCII_8BIT, eval("#!/usr/bin/ruby\n# -*- encoding: ASCII-8BIT -*-\n__ENCODING__".force_encoding("US-ASCII")))
+ # wrong position
+ assert_equal(Encoding::ASCII_8BIT, eval("\n# -*- encoding: US-ASCII -*-\n__ENCODING__".force_encoding("ASCII-8BIT")))
+ assert_equal(Encoding::US_ASCII, eval("\n# -*- encoding: ASCII-8BIT -*-\n__ENCODING__".force_encoding("US-ASCII")))
+
+ # leading expressions
+ assert_equal(Encoding::ASCII_8BIT, eval("v=1 # -*- encoding: US-ASCII -*-\n__ENCODING__".force_encoding("ASCII-8BIT")))
+ assert_equal(Encoding::US_ASCII, eval("v=1 # -*- encoding: ASCII-8BIT -*-\n__ENCODING__".force_encoding("US-ASCII")))
+ end
+
+ def test_regexp_usascii
+ assert_regexp_usascii_literal('//', Encoding::US_ASCII)
+ assert_regexp_usascii_literal('/#{ }/', Encoding::US_ASCII)
+ assert_regexp_usascii_literal('/#{"a"}/', Encoding::US_ASCII)
+ assert_regexp_usascii_literal('/#{%q"\x80"}/', Encoding::ASCII_8BIT)
+ assert_regexp_usascii_literal('/#{"\x80"}/', nil, SyntaxError)
+
+ assert_regexp_usascii_literal('/a/', Encoding::US_ASCII)
+ assert_regexp_usascii_literal('/a#{ }/', Encoding::US_ASCII)
+ assert_regexp_usascii_literal('/a#{"a"}/', Encoding::US_ASCII)
+ assert_regexp_usascii_literal('/a#{%q"\x80"}/', Encoding::ASCII_8BIT)
+ assert_regexp_usascii_literal('/a#{"\x80"}/', nil, SyntaxError)
+
+ assert_regexp_usascii_literal('/\x80/', Encoding::ASCII_8BIT)
+ assert_regexp_usascii_literal('/\x80#{ }/', Encoding::ASCII_8BIT)
+ assert_regexp_usascii_literal('/\x80#{"a"}/', Encoding::ASCII_8BIT)
+ assert_regexp_usascii_literal('/\x80#{%q"\x80"}/', Encoding::ASCII_8BIT)
+ assert_regexp_usascii_literal('/\x80#{"\x80"}/', nil, SyntaxError)
+
+ assert_regexp_usascii_literal('/\u1234/', Encoding::UTF_8)
+ assert_regexp_usascii_literal('/\u1234#{ }/', Encoding::UTF_8)
+ assert_regexp_usascii_literal('/\u1234#{"a"}/', Encoding::UTF_8)
+ assert_regexp_usascii_literal('/\u1234#{%q"\x80"}/', nil, SyntaxError)
+ assert_regexp_usascii_literal('/\u1234#{"\x80"}/', nil, SyntaxError)
+ assert_regexp_usascii_literal('/\u1234\x80/', nil, SyntaxError)
+ assert_regexp_usascii_literal('/\u1234#{ }\x80/', nil, RegexpError)
+ end
+
+ def test_gbk
+ assert_equal("", "\x81\x40".force_encoding("GBK").chop)
+ end
+
+ def test_euc_tw
+ assert_equal("a", "a\x8e\xa2\xa1\xa1".force_encoding("euc-tw").chop)
+ end
+
+ def test_valid_encoding
+ s = "\xa1".force_encoding("euc-jp")
+ assert_equal(false, s.valid_encoding?)
+ assert_equal(true, (s+s).valid_encoding?, "[ruby-dev:33826]")
+ assert_equal(true, (s*2).valid_encoding?, "[ruby-dev:33826]")
+ assert_equal(true, ("%s%s" % [s, s]).valid_encoding?)
+ assert_equal(true, (s.dup << s).valid_encoding?)
+ assert_equal(true, "".center(2, s).valid_encoding?)
+
+ s = "\xa1\xa1\x8f".force_encoding("euc-jp")
+ assert_equal(false, s.valid_encoding?)
+ assert_equal(true, s.reverse.valid_encoding?)
+ end
+
+ def test_getbyte
+ assert_equal(0x82, u("\xE3\x81\x82\xE3\x81\x84").getbyte(2))
+ assert_equal(0x82, u("\xE3\x81\x82\xE3\x81\x84").getbyte(-4))
+ assert_nil(u("\xE3\x81\x82\xE3\x81\x84").getbyte(100))
+ end
+
+ def test_setbyte
+ s = u("\xE3\x81\x82\xE3\x81\x84")
+ s.setbyte(2, 0x84)
+ assert_equal(u("\xE3\x81\x84\xE3\x81\x84"), s)
+
+ s = u("\xE3\x81\x82\xE3\x81\x84")
+ assert_raise(IndexError) { s.setbyte(100, 0) }
+
+ s = u("\xE3\x81\x82\xE3\x81\x84")
+ s.setbyte(-4, 0x84)
+ assert_equal(u("\xE3\x81\x84\xE3\x81\x84"), s)
+ end
+
+ def test_compatible
+ assert_nil Encoding.compatible?("",0)
+ assert_equal(Encoding::UTF_8, Encoding.compatible?(u(""), ua("abc")))
+ assert_equal(Encoding::UTF_8, Encoding.compatible?(Encoding::UTF_8, Encoding::UTF_8))
+ assert_equal(Encoding::UTF_8, Encoding.compatible?(Encoding::UTF_8, Encoding::US_ASCII))
+ assert_equal(Encoding::ASCII_8BIT,
+ Encoding.compatible?(Encoding::ASCII_8BIT, Encoding::US_ASCII))
+ assert_nil Encoding.compatible?(Encoding::UTF_8, Encoding::ASCII_8BIT)
+ end
+
+ def test_force_encoding
+ assert(("".center(1, "\x80".force_encoding("utf-8")); true),
+ "moved from btest/knownbug, [ruby-dev:33807]")
+ a = "".force_encoding("ascii-8bit") << 0xC3 << 0xB6
+ assert_equal(1, a.force_encoding("utf-8").size, '[ruby-core:22437]')
+ b = "".force_encoding("ascii-8bit") << 0xC3.chr << 0xB6.chr
+ assert_equal(1, b.force_encoding("utf-8").size, '[ruby-core:22437]')
+ end
+
+ def test_combchar_codepoint
+ assert_equal([0x30BB, 0x309A], "\u30BB\u309A".codepoints.to_a)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_m17n_comb.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_m17n_comb.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_m17n_comb.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1641 @@
+require 'test/unit'
+require 'stringio'
+require_relative 'allpairs'
+
+class TestM17NComb < Test::Unit::TestCase
+ def assert_encoding(encname, actual, message=nil)
+ assert_equal(Encoding.find(encname), actual, message)
+ end
+
+ module AESU
+ def a(str) str.dup.force_encoding("ASCII-8BIT") end
+ def e(str) str.dup.force_encoding("EUC-JP") end
+ def s(str) str.dup.force_encoding("Shift_JIS") end
+ def u(str) str.dup.force_encoding("UTF-8") end
+ end
+ include AESU
+ extend AESU
+
+ def assert_strenc(bytes, enc, actual, message=nil)
+ assert_instance_of(String, actual, message)
+ enc = Encoding.find(enc) if String === enc
+ assert_equal(enc, actual.encoding, message)
+ assert_equal(a(bytes), a(actual), message)
+ end
+
+ def assert_warning(pat, mesg=nil)
+ begin
+ org_stderr = $stderr
+ $stderr = StringIO.new(warn = '')
+ yield
+ ensure
+ $stderr = org_stderr
+ end
+ assert_match(pat, warn, mesg)
+ end
+
+ def assert_regexp_generic_encoding(r)
+ assert(!r.fixed_encoding?)
+ %w[ASCII-8BIT EUC-JP Shift_JIS UTF-8].each {|ename|
+ # "\xc2\xa1" is a valid sequence for ASCII-8BIT, EUC-JP, Shift_JIS and UTF-8.
+ assert_nothing_raised { r =~ "\xc2\xa1".force_encoding(ename) }
+ }
+ end
+
+ def assert_regexp_fixed_encoding(r)
+ assert(r.fixed_encoding?)
+ %w[ASCII-8BIT EUC-JP Shift_JIS UTF-8].each {|ename|
+ enc = Encoding.find(ename)
+ if enc == r.encoding
+ assert_nothing_raised { r =~ "\xc2\xa1".force_encoding(enc) }
+ else
+ assert_raise(ArgumentError) { r =~ "\xc2\xa1".force_encoding(enc) }
+ end
+ }
+ end
+
+ def assert_regexp_generic_ascii(r)
+ assert_encoding("ASCII-8BIT", r.encoding)
+ assert_regexp_generic_encoding(r)
+ end
+
+ def assert_regexp_fixed_ascii8bit(r)
+ assert_encoding("ASCII-8BIT", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_fixed_eucjp(r)
+ assert_encoding("EUC-JP", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_fixed_sjis(r)
+ assert_encoding("Shift_JIS", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_fixed_utf8(r)
+ assert_encoding("UTF-8", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ STRINGS = [
+ a(""), e(""), s(""), u(""),
+ a("a"), e("a"), s("a"), u("a"),
+ a("."), e("."), s("."), u("."),
+
+ # single character
+ a("\x80"), a("\xff"),
+ e("\xa1\xa1"), e("\xfe\xfe"),
+ e("\x8e\xa1"), e("\x8e\xfe"),
+ e("\x8f\xa1\xa1"), e("\x8f\xfe\xfe"),
+ s("\x81\x40"), s("\xfc\xfc"),
+ s("\xa1"), s("\xdf"),
+ u("\xc2\x80"), u("\xf4\x8f\xbf\xbf"),
+
+ # same byte sequence
+ a("\xc2\xa1"), e("\xc2\xa1"), s("\xc2\xa1"), u("\xc2\xa1"),
+
+ s("\x81A"), # mutibyte character which contains "A"
+ s("\x81a"), # mutibyte character which contains "a"
+
+ # invalid
+ e("\xa1"), e("\x80"),
+ s("\x81"), s("\x80"),
+ u("\xc2"), u("\x80"),
+
+ # for transitivity test
+ u("\xe0\xa0\xa1"), e("\xe0\xa0\xa1"), s("\xe0\xa0\xa1"), # [ruby-dev:32693]
+ e("\xa1\xa1"), a("\xa1\xa1"), s("\xa1\xa1"), # [ruby-dev:36484]
+
+ #"aa".force_encoding("utf-16be"),
+ #"aaaa".force_encoding("utf-32be"),
+ #"aaa".force_encoding("utf-32be"),
+ ]
+
+ def combination(*args, &b)
+ AllPairs.each(*args, &b)
+ #AllPairs.exhaustive_each(*args, &b)
+ end
+
+ def encdump(str)
+ d = str.dump
+ if /\.force_encoding\("[A-Za-z0-9.:_+-]*"\)\z/ =~ d
+ d
+ else
+ "#{d}.force_encoding(#{str.encoding.name.dump})"
+ end
+ end
+
+ def encdumpargs(args)
+ r = '('
+ args.each_with_index {|a, i|
+ r << ',' if 0 < i
+ if String === a
+ r << encdump(a)
+ else
+ r << a.inspect
+ end
+ }
+ r << ')'
+ r
+ end
+
+ def enccall(recv, meth, *args, &block)
+ desc = ''
+ if String === recv
+ desc << encdump(recv)
+ else
+ desc << recv.inspect
+ end
+ desc << '.' << meth.to_s
+ if !args.empty?
+ desc << '('
+ args.each_with_index {|a, i|
+ desc << ',' if 0 < i
+ if String === a
+ desc << encdump(a)
+ else
+ desc << a.inspect
+ end
+ }
+ desc << ')'
+ end
+ if block
+ desc << ' {}'
+ end
+ result = nil
+ assert_nothing_raised(desc) {
+ result = recv.send(meth, *args, &block)
+ }
+ result
+ end
+
+ def assert_str_enc_propagation(t, s1, s2)
+ if !s1.ascii_only?
+ assert_equal(s1.encoding, t.encoding)
+ elsif !s2.ascii_only?
+ assert_equal(s2.encoding, t.encoding)
+ else
+ assert([s1.encoding, s2.encoding].include?(t.encoding))
+ end
+ end
+
+ def assert_same_result(expected_proc, actual_proc)
+ e = nil
+ begin
+ t = expected_proc.call
+ rescue
+ e = $!
+ end
+ if e
+ assert_raise(e.class) { actual_proc.call }
+ else
+ assert_equal(t, actual_proc.call)
+ end
+ end
+
+ def each_slice_call
+ combination(STRINGS, -2..2) {|s, nth|
+ yield s, nth
+ }
+ combination(STRINGS, -2..2, 0..2) {|s, nth, len|
+ yield s, nth, len
+ }
+ combination(STRINGS, STRINGS) {|s, substr|
+ yield s, substr
+ }
+ combination(STRINGS, -2..2, 0..2) {|s, first, last|
+ yield s, first..last
+ yield s, first...last
+ }
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s2.valid_encoding?
+ next
+ end
+ yield s1, Regexp.new(Regexp.escape(s2))
+ }
+ combination(STRINGS, STRINGS, 0..2) {|s1, s2, nth|
+ if !s2.valid_encoding?
+ next
+ end
+ yield s1, Regexp.new(Regexp.escape(s2)), nth
+ }
+ end
+
+ ASCII_INCOMPATIBLE_ENCODINGS = %w[
+ UTF-16BE
+ UTF-16LE
+ UTF-32BE
+ UTF-32LE
+ ]
+ def str_enc_compatible?(*strs)
+ encs = []
+ ascii_incompatible_encodings = {}
+ has_ascii_compatible = false
+ strs.each {|s|
+ encs << s.encoding if !s.ascii_only?
+ if /\A#{Regexp.union ASCII_INCOMPATIBLE_ENCODINGS}\z/o =~ s.encoding.name
+ ascii_incompatible_encodings[s.encoding] = true
+ else
+ has_ascii_compatible = true
+ end
+ }
+ if ascii_incompatible_encodings.empty?
+ encs.uniq!
+ encs.length <= 1
+ else
+ !has_ascii_compatible && ascii_incompatible_encodings.size == 1
+ end
+ end
+
+ # tests start
+
+ def test_str_new
+ STRINGS.each {|s|
+ t = String.new(s)
+ assert_strenc(a(s), s.encoding, t)
+ }
+ end
+
+ def test_str_plus
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if s1.encoding != s2.encoding && !s1.ascii_only? && !s2.ascii_only?
+ assert_raise(Encoding::CompatibilityError) { s1 + s2 }
+ else
+ t = enccall(s1, :+, s2)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert_equal(a(s1) + a(s2), a(t))
+ assert_str_enc_propagation(t, s1, s2)
+ end
+ }
+ end
+
+ def test_str_times
+ STRINGS.each {|s|
+ [0,1,2].each {|n|
+ t = s * n
+ assert(t.valid_encoding?) if s.valid_encoding?
+ assert_strenc(a(s) * n, s.encoding, t)
+ }
+ }
+ end
+
+ def test_sprintf_s
+ STRINGS.each {|s|
+ assert_strenc(a(s), s.encoding, "%s".force_encoding(s.encoding) % s)
+ if !s.empty? # xxx
+ t = enccall(a("%s"), :%, s)
+ assert_strenc(a(s), s.encoding, t)
+ end
+ }
+ end
+
+ def test_str_eq_reflexive
+ STRINGS.each {|s|
+ assert(s == s, "#{encdump s} == #{encdump s}")
+ }
+ end
+
+ def test_str_eq_symmetric
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if s1 == s2
+ assert(s2 == s1, "#{encdump s2} == #{encdump s1}")
+ else
+ assert(!(s2 == s1), "!(#{encdump s2} == #{encdump s1})")
+ end
+ }
+ end
+
+ def test_str_eq_transitive
+ combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
+ if s1 == s2 && s2 == s3
+ assert(s1 == s3, "transitive: #{encdump s1} == #{encdump s2} == #{encdump s3}")
+ end
+ }
+ end
+
+ def test_str_eq
+ combination(STRINGS, STRINGS) {|s1, s2|
+ desc_eq = "#{encdump s1} == #{encdump s2}"
+ if a(s1) == a(s2) and
+ (s1.ascii_only? && s2.ascii_only? or
+ s1.encoding == s2.encoding) then
+ assert(s1 == s2, desc_eq)
+ assert(!(s1 != s2))
+ assert_equal(0, s1 <=> s2)
+ assert(s1.eql?(s2), desc_eq)
+ else
+ assert(!(s1 == s2), "!(#{desc_eq})")
+ assert(s1 != s2)
+ assert_not_equal(0, s1 <=> s2)
+ assert(!s1.eql?(s2))
+ end
+ }
+ end
+
+ def test_str_concat
+ combination(STRINGS, STRINGS) {|s1, s2|
+ s = s1.dup
+ if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
+ s << s2
+ assert(s.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert_equal(a(s), a(s1) + a(s2))
+ assert_str_enc_propagation(s, s1, s2)
+ else
+ assert_raise(Encoding::CompatibilityError) { s << s2 }
+ end
+ }
+ end
+
+ def test_str_aref
+ STRINGS.each {|s|
+ t = ''.force_encoding(s.encoding)
+ 0.upto(s.length-1) {|i|
+ u = s[i]
+ assert(u.valid_encoding?) if s.valid_encoding?
+ t << u
+ }
+ assert_equal(t, s)
+ }
+ end
+
+ def test_str_aref_len
+ STRINGS.each {|s|
+ t = ''.force_encoding(s.encoding)
+ 0.upto(s.length-1) {|i|
+ u = s[i,1]
+ assert(u.valid_encoding?) if s.valid_encoding?
+ t << u
+ }
+ assert_equal(t, s)
+ }
+
+ STRINGS.each {|s|
+ t = ''.force_encoding(s.encoding)
+ 0.step(s.length-1, 2) {|i|
+ u = s[i,2]
+ assert(u.valid_encoding?) if s.valid_encoding?
+ t << u
+ }
+ assert_equal(t, s)
+ }
+ end
+
+ def test_str_aref_substr
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
+ t = enccall(s1, :[], s2)
+ if t != nil
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert_equal(s2, t)
+ assert_match(/#{Regexp.escape(a(s2))}/, a(s1))
+ if s1.valid_encoding?
+ assert_match(/#{Regexp.escape(s2)}/, s1)
+ end
+ end
+ else
+ assert_raise(Encoding::CompatibilityError) { s1[s2] }
+ end
+ }
+ end
+
+ def test_str_aref_range2
+ combination(STRINGS, -2..2, -2..2) {|s, first, last|
+ desc = "#{encdump s}[#{first}..#{last}]"
+ t = s[first..last]
+ if first < 0
+ first += s.length
+ if first < 0
+ assert_nil(t, desc)
+ next
+ end
+ end
+ if s.length < first
+ assert_nil(t, desc)
+ next
+ end
+ assert(t.valid_encoding?) if s.valid_encoding?
+ if last < 0
+ last += s.length
+ end
+ t2 = ''
+ first.upto(last) {|i|
+ c = s[i]
+ t2 << c if c
+ }
+ assert_equal(t2, t, desc)
+ }
+ end
+
+ def test_str_aref_range3
+ combination(STRINGS, -2..2, -2..2) {|s, first, last|
+ desc = "#{encdump s}[#{first}..#{last}]"
+ t = s[first...last]
+ if first < 0
+ first += s.length
+ if first < 0
+ assert_nil(t, desc)
+ next
+ end
+ end
+ if s.length < first
+ assert_nil(t, desc)
+ next
+ end
+ if last < 0
+ last += s.length
+ end
+ assert(t.valid_encoding?) if s.valid_encoding?
+ t2 = ''
+ first.upto(last-1) {|i|
+ c = s[i]
+ t2 << c if c
+ }
+ assert_equal(t2, t, desc)
+ }
+ end
+
+ def test_str_assign
+ combination(STRINGS, STRINGS) {|s1, s2|
+ (-2).upto(2) {|i|
+ t = s1.dup
+ if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
+ if i < -s1.length || s1.length < i
+ assert_raise(IndexError) { t[i] = s2 }
+ else
+ t[i] = s2
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert(a(t).index(a(s2)))
+ if s1.valid_encoding? && s2.valid_encoding?
+ if i == s1.length && s2.empty?
+ assert_nil(t[i])
+ elsif i < 0
+ assert_equal(s2, t[i-s2.length+1,s2.length],
+ "t = #{encdump(s1)}; t[#{i}] = #{encdump(s2)}; t[#{i-s2.length+1},#{s2.length}]")
+ else
+ assert_equal(s2, t[i,s2.length],
+ "t = #{encdump(s1)}; t[#{i}] = #{encdump(s2)}; t[#{i},#{s2.length}]")
+ end
+ end
+ end
+ else
+ assert_raise(Encoding::CompatibilityError) { t[i] = s2 }
+ end
+ }
+ }
+ end
+
+ def test_str_assign_len
+ combination(STRINGS, -2..2, 0..2, STRINGS) {|s1, i, len, s2|
+ t = s1.dup
+ if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
+ if i < -s1.length || s1.length < i
+ assert_raise(IndexError) { t[i,len] = s2 }
+ else
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ t[i,len] = s2
+ assert(a(t).index(a(s2)))
+ if s1.valid_encoding? && s2.valid_encoding?
+ if i == s1.length && s2.empty?
+ assert_nil(t[i])
+ elsif i < 0
+ if -i < len
+ len = -i
+ end
+ assert_equal(s2, t[i-s2.length+len,s2.length],
+ "t = #{encdump(s1)}; t[#{i},#{len}] = #{encdump(s2)}; t[#{i-s2.length+len},#{s2.length}]")
+ else
+ assert_equal(s2, t[i,s2.length],
+ "t = #{encdump(s1)}; t[#{i},#{len}] = #{encdump(s2)}; t[#{i},#{s2.length}]")
+ end
+ end
+ end
+ else
+ assert_raise(Encoding::CompatibilityError) { t[i,len] = s2 }
+ end
+ }
+ end
+
+ def test_str_assign_substr
+ combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
+ t = s1.dup
+ encs = [
+ !s1.ascii_only? ? s1.encoding : nil,
+ !s2.ascii_only? ? s2.encoding : nil,
+ !s3.ascii_only? ? s3.encoding : nil].uniq.compact
+ if 1 < encs.length
+ assert_raise(Encoding::CompatibilityError, IndexError) { t[s2] = s3 }
+ else
+ if encs.empty?
+ encs = [
+ s1.encoding,
+ s2.encoding,
+ s3.encoding].uniq.reject {|e| e == Encoding.find("ASCII-8BIT") }
+ if encs.empty?
+ encs = [Encoding.find("ASCII-8BIT")]
+ end
+ end
+ if !t[s2]
+ else
+ enccall(t, :[]=, s2, s3)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding? && s3.valid_encoding?
+ end
+ end
+ }
+ end
+
+ def test_str_assign_range2
+ combination(STRINGS, -2..2, -2..2, STRINGS) {|s1, first, last, s2|
+ t = s1.dup
+ if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
+ if first < -s1.length || s1.length < first
+ assert_raise(RangeError) { t[first..last] = s2 }
+ else
+ enccall(t, :[]=, first..last, s2)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert(a(t).index(a(s2)))
+ if s1.valid_encoding? && s2.valid_encoding?
+ if first < 0
+ assert_equal(s2, t[s1.length+first, s2.length])
+ else
+ assert_equal(s2, t[first, s2.length])
+ end
+ end
+ end
+ else
+ assert_raise(Encoding::CompatibilityError, RangeError,
+ "t=#{encdump(s1)};t[#{first}..#{last}]=#{encdump(s2)}") {
+ t[first..last] = s2
+ }
+ end
+ }
+ end
+
+ def test_str_assign_range3
+ combination(STRINGS, -2..2, -2..2, STRINGS) {|s1, first, last, s2|
+ t = s1.dup
+ if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
+ if first < -s1.length || s1.length < first
+ assert_raise(RangeError) { t[first...last] = s2 }
+ else
+ enccall(t, :[]=, first...last, s2)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert(a(t).index(a(s2)))
+ if s1.valid_encoding? && s2.valid_encoding?
+ if first < 0
+ assert_equal(s2, t[s1.length+first, s2.length])
+ else
+ assert_equal(s2, t[first, s2.length])
+ end
+ end
+ end
+ else
+ assert_raise(Encoding::CompatibilityError, RangeError,
+ "t=#{encdump(s1)};t[#{first}...#{last}]=#{encdump(s2)}") {
+ t[first...last] = s2
+ }
+ end
+ }
+ end
+
+ def test_str_cmp
+ combination(STRINGS, STRINGS) {|s1, s2|
+ desc = "#{encdump s1} <=> #{encdump s2}"
+ r = s1 <=> s2
+ if s1 == s2
+ assert_equal(0, r, desc)
+ else
+ assert_not_equal(0, r, desc)
+ end
+ }
+ end
+
+ def test_str_capitalize
+ STRINGS.each {|s|
+ begin
+ t1 = s.capitalize
+ rescue ArgumentError
+ assert(!s.valid_encoding?)
+ next
+ end
+ assert(t1.valid_encoding?) if s.valid_encoding?
+ assert(t1.casecmp(s))
+ t2 = s.dup
+ t2.capitalize!
+ assert_equal(t1, t2)
+ r = s.downcase
+ r = enccall(r, :sub, /\A[a-z]/) {|ch| a(ch).upcase }
+ assert_equal(r, t1)
+ }
+ end
+
+ def test_str_casecmp
+ combination(STRINGS, STRINGS) {|s1, s2|
+ #puts "#{encdump(s1)}.casecmp(#{encdump(s2)})"
+ begin
+ r = s1.casecmp(s2)
+ rescue ArgumentError
+ assert(!s1.valid_encoding? || !s2.valid_encoding?)
+ next
+ end
+ #assert_equal(s1.upcase <=> s2.upcase, r)
+ }
+ end
+
+ def test_str_center
+ skip("[BUG : #772] Assertion")
+
+ combination(STRINGS, [0,1,2,3,10]) {|s1, width|
+ t = s1.center(width)
+ assert(a(t).index(a(s1)))
+ }
+ combination(STRINGS, [0,1,2,3,10], STRINGS) {|s1, width, s2|
+ if s2.empty?
+ assert_raise(ArgumentError) { s1.center(width, s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(Encoding::CompatibilityError) { s1.center(width, s2) }
+ next
+ end
+ t = enccall(s1, :center, width, s2)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert(a(t).index(a(s1)))
+ assert_str_enc_propagation(t, s1, s2) if (t != s1)
+ }
+ end
+
+ def test_str_ljust
+ combination(STRINGS, [0,1,2,3,10]) {|s1, width|
+ t = s1.ljust(width)
+ assert(a(t).index(a(s1)))
+ }
+ combination(STRINGS, [0,1,2,3,10], STRINGS) {|s1, width, s2|
+ if s2.empty?
+ assert_raise(ArgumentError) { s1.ljust(width, s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(Encoding::CompatibilityError) { s1.ljust(width, s2) }
+ next
+ end
+ t = enccall(s1, :ljust, width, s2)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert(a(t).index(a(s1)))
+ assert_str_enc_propagation(t, s1, s2) if (t != s1)
+ }
+ end
+
+ def test_str_rjust
+ skip("[BUG : #772] Assertion")
+
+ combination(STRINGS, [0,1,2,3,10]) {|s1, width|
+ t = s1.rjust(width)
+ assert(a(t).index(a(s1)))
+ }
+ combination(STRINGS, [0,1,2,3,10], STRINGS) {|s1, width, s2|
+ if s2.empty?
+ assert_raise(ArgumentError) { s1.rjust(width, s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(Encoding::CompatibilityError) { s1.rjust(width, s2) }
+ next
+ end
+ t = enccall(s1, :rjust, width, s2)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert(a(t).index(a(s1)))
+ assert_str_enc_propagation(t, s1, s2) if (t != s1)
+ }
+ end
+
+ def test_str_chomp
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s1.ascii_only? && !s2.ascii_only? && !Encoding.compatible?(s1,s2)
+ if s1.bytesize > s2.bytesize
+ assert_raise(Encoding::CompatibilityError) { s1.chomp(s2) }
+ end
+ next
+ end
+ t = enccall(s1, :chomp, s2)
+ assert(t.valid_encoding?, "#{encdump(s1)}.chomp(#{encdump(s2)})") if s1.valid_encoding? && s2.valid_encoding?
+ assert_equal(s1.encoding, t.encoding)
+ t2 = s1.dup
+ t2.chomp!(s2)
+ assert_equal(t, t2)
+ }
+ end
+
+ def test_str_chop
+ skip("[BUG : #772] Assertion")
+
+ STRINGS.each {|s|
+ s = s.dup
+ desc = "#{encdump s}.chop"
+ t = nil
+ assert_nothing_raised(desc) { t = s.chop }
+ assert(t.valid_encoding?) if s.valid_encoding?
+ assert(a(s).index(a(t)))
+ t2 = s.dup
+ t2.chop!
+ assert_equal(t, t2)
+ }
+ end
+
+ def test_str_clear
+ STRINGS.each {|s|
+ t = s.dup
+ t.clear
+ assert(t.valid_encoding?)
+ assert(t.empty?)
+ }
+ end
+
+ def test_str_clone
+ STRINGS.each {|s|
+ t = s.clone
+ assert_equal(s, t)
+ assert_equal(s.encoding, t.encoding)
+ assert_equal(a(s), a(t))
+ }
+ end
+
+ def test_str_dup
+ STRINGS.each {|s|
+ t = s.dup
+ assert_equal(s, t)
+ assert_equal(s.encoding, t.encoding)
+ assert_equal(a(s), a(t))
+ }
+ end
+
+ def test_str_count
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_raise(ArgumentError, Encoding::CompatibilityError) { s1.count(s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(Encoding::CompatibilityError) { s1.count(s2) }
+ next
+ end
+ n = enccall(s1, :count, s2)
+ n0 = a(s1).count(a(s2))
+ assert_operator(n, :<=, n0)
+ }
+ end
+
+ def test_str_crypt
+ combination(STRINGS, STRINGS) {|str, salt|
+ if a(salt).length < 2
+ assert_raise(ArgumentError) { str.crypt(salt) }
+ next
+ end
+ t = str.crypt(salt)
+ assert_equal(a(str).crypt(a(salt)), t, "#{encdump(str)}.crypt(#{encdump(salt)})")
+ assert_encoding('ASCII-8BIT', t.encoding)
+ }
+ end
+
+ def test_str_delete
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if s1.empty?
+ assert_equal(s1, s1.delete(s2))
+ next
+ end
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_raise(ArgumentError, Encoding::CompatibilityError) { s1.delete(s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(Encoding::CompatibilityError) { s1.delete(s2) }
+ next
+ end
+ t = enccall(s1, :delete, s2)
+ assert(t.valid_encoding?)
+ assert_equal(t.encoding, s1.encoding)
+ assert_operator(t.length, :<=, s1.length)
+ t2 = s1.dup
+ t2.delete!(s2)
+ assert_equal(t, t2)
+ }
+ end
+
+ def test_str_downcase
+ STRINGS.each {|s|
+ if !s.valid_encoding?
+ assert_raise(ArgumentError) { s.downcase }
+ next
+ end
+ t = s.downcase
+ assert(t.valid_encoding?)
+ assert_equal(t.encoding, s.encoding)
+ assert(t.casecmp(s))
+ t2 = s.dup
+ t2.downcase!
+ assert_equal(t, t2)
+ }
+ end
+
+ def test_str_dump
+ STRINGS.each {|s|
+ t = s.dump
+ assert(t.valid_encoding?)
+ assert(t.ascii_only?)
+ u = eval(t)
+ assert_equal(a(s), a(u))
+ }
+ end
+
+ def test_str_each_line
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_raise(ArgumentError, Encoding::CompatibilityError) { s1.each_line(s2) {} }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(Encoding::CompatibilityError) { s1.each_line(s2) {} }
+ next
+ end
+ lines = []
+ enccall(s1, :each_line, s2) {|line|
+ assert(line.valid_encoding?)
+ assert_equal(s1.encoding, line.encoding)
+ lines << line
+ }
+ next if lines.size == 0
+ s2 = lines.join('')
+ assert_equal(s1.encoding, s2.encoding)
+ assert_equal(s1, s2)
+ }
+ end
+
+ def test_str_each_byte
+ STRINGS.each {|s|
+ bytes = []
+ s.each_byte {|b|
+ bytes << b
+ }
+ a(s).split(//).each_with_index {|ch, i|
+ assert_equal(ch.ord, bytes[i])
+ }
+ }
+ end
+
+ def test_str_empty?
+ STRINGS.each {|s|
+ if s.length == 0
+ assert(s.empty?)
+ else
+ assert(!s.empty?)
+ end
+ }
+ end
+
+ def test_str_hex
+ STRINGS.each {|s|
+ t = s.hex
+ t2 = a(s)[/\A[0-9a-fA-Fx]*/].hex
+ assert_equal(t2, t)
+ }
+ end
+
+ def test_str_include?
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(Encoding::CompatibilityError) { s1.include?(s2) }
+ assert_raise(Encoding::CompatibilityError) { s1.index(s2) }
+ assert_raise(Encoding::CompatibilityError) { s1.rindex(s2) }
+ next
+ end
+ t = enccall(s1, :include?, s2)
+ if t
+ assert(a(s1).include?(a(s2)))
+ assert(s1.index(s2))
+ assert(s1.rindex(s2))
+ else
+ assert(!s1.index(s2))
+ assert(!s1.rindex(s2), "!#{encdump(s1)}.rindex(#{encdump(s2)})")
+ end
+ if s2.empty?
+ assert_equal(true, t)
+ next
+ end
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_equal(false, t, "#{encdump s1}.include?(#{encdump s2})")
+ next
+ end
+ if t && s1.valid_encoding? && s2.valid_encoding?
+ assert_match(/#{Regexp.escape(s2)}/, s1)
+ else
+ assert_no_match(/#{Regexp.escape(s2)}/, s1)
+ end
+ }
+ end
+
+ def test_str_index
+ combination(STRINGS, STRINGS, -2..2) {|s1, s2, pos|
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(Encoding::CompatibilityError) { s1.index(s2) }
+ next
+ end
+ t = enccall(s1, :index, s2, pos)
+ if s2.empty?
+ if pos < 0 && pos+s1.length < 0
+ assert_equal(nil, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
+ elsif pos < 0
+ assert_equal(s1.length+pos, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
+ elsif s1.length < pos
+ assert_equal(nil, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
+ else
+ assert_equal(pos, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
+ end
+ next
+ end
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_equal(nil, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
+ next
+ end
+ if t
+ re = /#{Regexp.escape(s2)}/
+ assert(re.match(s1, pos))
+ assert_equal($`.length, t, "#{encdump s1}.index(#{encdump s2}, #{pos})")
+ else
+ assert_no_match(/#{Regexp.escape(s2)}/, s1[pos..-1])
+ end
+ }
+ end
+
+ def test_str_rindex
+ combination(STRINGS, STRINGS, -2..2) {|s1, s2, pos|
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(Encoding::CompatibilityError) { s1.rindex(s2) }
+ next
+ end
+ t = enccall(s1, :rindex, s2, pos)
+ if s2.empty?
+ if pos < 0 && pos+s1.length < 0
+ assert_equal(nil, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
+ elsif pos < 0
+ assert_equal(s1.length+pos, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
+ elsif s1.length < pos
+ assert_equal(s1.length, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
+ else
+ assert_equal(pos, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
+ end
+ next
+ end
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_equal(nil, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
+ next
+ end
+ if t
+ #puts "#{encdump s1}.rindex(#{encdump s2}, #{pos}) => #{t}"
+ assert(a(s1).index(a(s2)))
+ pos2 = pos
+ pos2 += s1.length if pos < 0
+ re = /\A(.{0,#{pos2}})#{Regexp.escape(s2)}/m
+ m = enccall(re, :match, s1)
+ assert(m, "#{re.inspect}.match(#{encdump(s1)})")
+ assert_equal(m[1].length, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
+ else
+ re = /#{Regexp.escape(s2)}/
+ n = re =~ s1
+ if n
+ if pos < 0
+ assert_operator(n, :>, s1.length+pos)
+ else
+ assert_operator(n, :>, pos)
+ end
+ end
+ end
+ }
+ end
+
+ def test_str_insert
+ skip("[BUG : #772] Assertion")
+
+ combination(STRINGS, 0..2, STRINGS) {|s1, nth, s2|
+ t1 = s1.dup
+ t2 = s1.dup
+ begin
+ t1[nth, 0] = s2
+ rescue Encoding::CompatibilityError, IndexError => e1
+ end
+ begin
+ t2.insert(nth, s2)
+ rescue Encoding::CompatibilityError, IndexError => e2
+ end
+ assert_equal(t1, t2, "t=#{encdump s1}; t.insert(#{nth},#{encdump s2}); t")
+ assert_equal(e1.class, e2.class, "begin #{encdump s1}.insert(#{nth},#{encdump s2}); rescue ArgumentError, IndexError => e; e end")
+ }
+ combination(STRINGS, -2..-1, STRINGS) {|s1, nth, s2|
+ next if s1.length + nth < 0
+ next unless s1.valid_encoding?
+ next unless s2.valid_encoding?
+ t1 = s1.dup
+ begin
+ t1.insert(nth, s2)
+ slen = s2.length
+ assert_equal(t1[nth-slen+1,slen], s2, "t=#{encdump s1}; t.insert(#{nth},#{encdump s2}); t")
+ rescue Encoding::CompatibilityError, IndexError => e
+ end
+ }
+ end
+
+ def test_str_intern
+ STRINGS.each {|s|
+ if /\0/ =~ a(s)
+ assert_raise(ArgumentError) { s.intern }
+ elsif s.valid_encoding?
+ sym = s.intern
+ assert_equal(s, sym.to_s, "#{encdump s}.intern.to_s")
+ assert_equal(sym, s.to_sym)
+ else
+ assert_raise(EncodingError) { s.intern }
+ end
+ }
+ end
+
+ def test_str_length
+ STRINGS.each {|s|
+ assert_operator(s.length, :<=, s.bytesize)
+ }
+ end
+
+ def test_str_oct
+ STRINGS.each {|s|
+ t = s.oct
+ t2 = a(s)[/\A[0-9a-fA-FxX]*/].oct
+ assert_equal(t2, t)
+ }
+ end
+
+ def test_str_replace
+ combination(STRINGS, STRINGS) {|s1, s2|
+ t = s1.dup
+ t.replace s2
+ assert_equal(s2, t)
+ assert_equal(s2.encoding, t.encoding)
+ }
+ end
+
+ def test_str_reverse
+ skip("[BUG : #772] Assertion")
+
+ STRINGS.each {|s|
+ t = s.reverse
+ assert_equal(s.bytesize, t.bytesize)
+ if !s.valid_encoding?
+ assert_operator(t.length, :<=, s.length)
+ next
+ end
+ assert_equal(s, t.reverse)
+ }
+ end
+
+ def test_str_scan
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s2.valid_encoding?
+ assert_raise(RegexpError) { s1.scan(s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ if s1.valid_encoding?
+ assert_raise(Encoding::CompatibilityError) { s1.scan(s2) }
+ else
+ assert_raise(ArgumentError, /invalid byte sequence/) { s1.scan(s2) }
+ end
+ next
+ end
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError) { s1.scan(s2) }
+ next
+ end
+ r = enccall(s1, :scan, s2)
+ r.each {|t|
+ assert_equal(s2, t)
+ }
+ }
+ end
+
+ def test_str_slice
+ each_slice_call {|obj, *args|
+ assert_same_result(lambda { obj[*args] }, lambda { obj.slice(*args) })
+ }
+ end
+
+ def test_str_slice!
+ each_slice_call {|s, *args|
+ desc_slice = "#{encdump s}.slice#{encdumpargs args}"
+ desc_slice_bang = "#{encdump s}.slice!#{encdumpargs args}"
+ t = s.dup
+ begin
+ r = t.slice!(*args)
+ rescue
+ e = $!
+ end
+ if e
+ assert_raise(e.class, desc_slice) { s.slice(*args) }
+ next
+ end
+ if !r
+ assert_nil(s.slice(*args), desc_slice)
+ next
+ end
+ assert_equal(s.slice(*args), r, desc_slice_bang)
+ assert_equal(s.bytesize, r.bytesize + t.bytesize)
+ if args.length == 1 && String === args[0]
+ assert_equal(args[0].encoding, r.encoding,
+ "#{encdump s}.slice!#{encdumpargs args}.encoding")
+ else
+ assert_equal(s.encoding, r.encoding,
+ "#{encdump s}.slice!#{encdumpargs args}.encoding")
+ end
+ if [s, *args].all? {|o| !(String === o) || o.valid_encoding? }
+ assert(r.valid_encoding?)
+ assert(t.valid_encoding?)
+ assert_equal(s.length, r.length + t.length)
+ end
+ }
+ end
+
+ def test_str_split
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s2.valid_encoding?
+ assert_raise(ArgumentError, RegexpError) { s1.split(s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(ArgumentError, Encoding::CompatibilityError) { s1.split(s2) }
+ next
+ end
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError) { s1.split(s2) }
+ next
+ end
+ t = enccall(s1, :split, s2)
+ t.each {|r|
+ assert(a(s1).include?(a(r)))
+ assert_equal(s1.encoding, r.encoding)
+ }
+ assert(a(s1).include?(t.map {|u| a(u) }.join(a(s2))))
+ if s1.valid_encoding? && s2.valid_encoding?
+ t.each {|r|
+ assert(r.valid_encoding?)
+ }
+ end
+ }
+ end
+
+ def test_str_squeeze
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_raise(ArgumentError, Encoding::CompatibilityError, "#{encdump s1}.squeeze(#{encdump s2})") { s1.squeeze(s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(Encoding::CompatibilityError) { s1.squeeze(s2) }
+ next
+ end
+ t = enccall(s1, :squeeze, s2)
+ assert_operator(t.length, :<=, s1.length)
+ t2 = s1.dup
+ t2.squeeze!(s2)
+ assert_equal(t, t2)
+ }
+ end
+
+ def test_str_strip
+ STRINGS.each {|s|
+ if !s.valid_encoding?
+ assert_raise(ArgumentError, "#{encdump s}.strip") { s.strip }
+ next
+ end
+ t = s.strip
+ l = s.lstrip
+ r = s.rstrip
+ assert_operator(l.length, :<=, s.length)
+ assert_operator(r.length, :<=, s.length)
+ assert_operator(t.length, :<=, l.length)
+ assert_operator(t.length, :<=, r.length)
+ t2 = s.dup
+ t2.strip!
+ assert_equal(t, t2)
+ l2 = s.dup
+ l2.lstrip!
+ assert_equal(l, l2)
+ r2 = s.dup
+ r2.rstrip!
+ assert_equal(r, r2)
+ }
+ end
+
+ def test_str_sum
+ STRINGS.each {|s|
+ assert_equal(a(s).sum, s.sum)
+ }
+ end
+
+ def test_str_swapcase
+ STRINGS.each {|s|
+ if !s.valid_encoding?
+ assert_raise(ArgumentError, "#{encdump s}.swapcase") { s.swapcase }
+ next
+ end
+ t1 = s.swapcase
+ assert(t1.valid_encoding?) if s.valid_encoding?
+ assert(t1.casecmp(s))
+ t2 = s.dup
+ t2.swapcase!
+ assert_equal(t1, t2)
+ t3 = t1.swapcase
+ assert_equal(s, t3);
+ }
+ end
+
+
+ def test_str_to_f
+ STRINGS.each {|s|
+ assert_nothing_raised { s.to_f }
+ }
+ end
+
+ def test_str_to_i
+ STRINGS.each {|s|
+ assert_nothing_raised { s.to_i }
+ 2.upto(36) {|radix|
+ assert_nothing_raised { s.to_i(radix) }
+ }
+ }
+ end
+
+ def test_str_to_s
+ STRINGS.each {|s|
+ assert_same(s, s.to_s)
+ assert_same(s, s.to_str)
+ }
+ end
+
+ def test_tr
+ skip("[BUG : #827] Assertion")
+
+ combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
+ desc = "#{encdump s1}.tr(#{encdump s2}, #{encdump s3})"
+ if s1.empty?
+ assert_equal(s1, s1.tr(s2, s3), desc)
+ next
+ end
+ if !str_enc_compatible?(s1, s2, s3)
+ assert_raise(Encoding::CompatibilityError, desc) { s1.tr(s2, s3) }
+ next
+ end
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError, desc) { s1.tr(s2, s3) }
+ next
+ end
+ if s2.empty?
+ t = enccall(s1, :tr, s2, s3)
+ assert_equal(s1, t, desc)
+ next
+ end
+ if !s2.valid_encoding? || !s3.valid_encoding?
+ assert_raise(ArgumentError, desc) { s1.tr(s2, s3) }
+ next
+ end
+ t = enccall(s1, :tr, s2, s3)
+ assert_operator(s1.length, :>=, t.length, desc)
+ }
+ end
+
+ def test_tr_s
+ skip("[BUG : #827] Assertion")
+
+ combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
+ desc = "#{encdump s1}.tr_s(#{encdump s2}, #{encdump s3})"
+ if s1.empty?
+ assert_equal(s1, s1.tr_s(s2, s3), desc)
+ next
+ end
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError, Encoding::CompatibilityError, desc) { s1.tr_s(s2, s3) }
+ next
+ end
+ if !str_enc_compatible?(s1, s2, s3)
+ assert_raise(Encoding::CompatibilityError, desc) { s1.tr(s2, s3) }
+ next
+ end
+ if s2.empty?
+ t = enccall(s1, :tr_s, s2, s3)
+ assert_equal(s1, t, desc)
+ next
+ end
+ if !s2.valid_encoding? || !s3.valid_encoding?
+ assert_raise(ArgumentError, desc) { s1.tr_s(s2, s3) }
+ next
+ end
+
+ t = enccall(s1, :tr_s, s2, s3)
+ assert_operator(s1.length, :>=, t.length, desc)
+ }
+ end
+
+ def test_str_upcase
+ STRINGS.each {|s|
+ desc = "#{encdump s}.upcase"
+ if !s.valid_encoding?
+ assert_raise(ArgumentError, desc) { s.upcase }
+ next
+ end
+ t1 = s.upcase
+ assert(t1.valid_encoding?)
+ assert(t1.casecmp(s))
+ t2 = s.dup
+ t2.upcase!
+ assert_equal(t1, t2)
+ }
+ end
+
+ def test_str_succ
+ STRINGS.each {|s0|
+ next if s0.empty?
+ s = s0.dup
+ n = 300
+ h = {}
+ n.times {|i|
+ if h[s]
+ assert(false, "#{encdump s} cycle with succ #{i-h[s]} times")
+ end
+ h[s] = i
+ assert_operator(s.length, :<=, s0.length + Math.log2(i+1) + 1, "#{encdump s0} succ #{i} times => #{encdump s}")
+ #puts encdump(s)
+ t = s.succ
+ if s.valid_encoding?
+ assert(t.valid_encoding?, "#{encdump s}.succ.valid_encoding?")
+ end
+ s = t
+ }
+ }
+ end
+
+ def test_str_hash
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if s1.eql?(s2)
+ assert_equal(s1.hash, s2.hash, "#{encdump s1}.hash == #{encdump s2}.dump")
+ end
+ }
+ end
+
+ def test_marshal
+ STRINGS.each {|s|
+ m = Marshal.dump(s)
+ t = Marshal.load(m)
+ assert_equal(s, t)
+ }
+ end
+
+ def test_str_sub
+ combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
+ if !s2.valid_encoding?
+ assert_raise(RegexpError) { Regexp.new(Regexp.escape(s2)) }
+ next
+ end
+ r2 = Regexp.new(Regexp.escape(s2))
+ [
+ [
+ "#{encdump s1}.sub(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { s1.sub(r2, s3) },
+ false
+ ],
+ [
+ "#{encdump s1}.sub(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { s1.sub(r2) { s3 } },
+ false
+ ],
+ [
+ "#{encdump s1}.gsub(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { s1.gsub(r2, s3) },
+ true
+ ],
+ [
+ "#{encdump s1}.gsub(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { s1.gsub(r2) { s3 } },
+ true
+ ]
+ ].each {|desc, doit, g|
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError, desc) { doit.call }
+ next
+ end
+ if !str_enc_compatible?(s1, s2)
+ assert_raise(Encoding::CompatibilityError, desc) { doit.call }
+ next
+ end
+ if !enccall(s1, :include?, s2)
+ assert_equal(s1, doit.call)
+ next
+ end
+ if !str_enc_compatible?(g ? s1.gsub(r2, '') : s1.sub(r2, ''), s3)
+ assert_raise(Encoding::CompatibilityError, desc) { doit.call }
+ next
+ end
+ t = nil
+ assert_nothing_raised(desc) {
+ t = doit.call
+ }
+ if s2 == s3
+ assert_equal(s1, t, desc)
+ else
+ assert_not_equal(s1, t, desc)
+ end
+ }
+ }
+ end
+
+ def test_str_sub!
+ combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
+ if !s2.valid_encoding?
+ assert_raise(RegexpError) { Regexp.new(Regexp.escape(s2)) }
+ next
+ end
+ r2 = Regexp.new(Regexp.escape(s2))
+ [
+ [
+ "t=#{encdump s1}.dup;t.sub!(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { t=s1.dup; [t, t.sub!(r2, s3)] },
+ false
+ ],
+ [
+ "t=#{encdump s1}.dup;t.sub!(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { t=s1.dup; [t, t.sub!(r2) { s3 }] },
+ false
+ ],
+ [
+ "t=#{encdump s1}.dup;t.gsub!(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { t=s1.dup; [t, t.gsub!(r2, s3)] },
+ true
+ ],
+ [
+ "t=#{encdump s1}.dup;t.gsub!(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { t=s1.dup; [t, t.gsub!(r2) { s3 }] },
+ true
+ ]
+ ].each {|desc, doit, g|
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError, desc) { doit.call }
+ next
+ end
+ if !str_enc_compatible?(s1, s2)
+ assert_raise(Encoding::CompatibilityError, desc) { doit.call }
+ next
+ end
+ if !enccall(s1, :include?, s2)
+ assert_equal([s1, nil], doit.call)
+ next
+ end
+ if !str_enc_compatible?(g ? s1.gsub(r2, '') : s1.sub(r2, ''), s3)
+ assert_raise(Encoding::CompatibilityError, desc) { doit.call }
+ next
+ end
+ t = ret = nil
+ assert_nothing_raised(desc) {
+ t, ret = doit.call
+ }
+ assert(ret)
+ if s2 == s3
+ assert_equal(s1, t, desc)
+ else
+ assert_not_equal(s1, t, desc)
+ end
+ }
+ }
+ end
+
+ def test_str_bytes
+ STRINGS.each {|s1|
+ ary = []
+ s1.bytes.each {|b|
+ ary << b
+ }
+ assert_equal(s1.unpack("C*"), ary)
+ }
+ end
+
+ def test_str_bytesize
+ STRINGS.each {|s1|
+ assert_equal(s1.unpack("C*").length, s1.bytesize)
+ }
+ end
+
+ def test_str_chars
+ STRINGS.each {|s1|
+ ary = []
+ s1.chars.each {|c|
+ ary << c
+ }
+ expected = []
+ s1.length.times {|i|
+ expected << s1[i]
+ }
+ assert_equal(expected, ary)
+ }
+ end
+
+ def test_str_chr
+ STRINGS.each {|s1|
+ if s1.empty?
+ assert_equal("", s1.chr)
+ next
+ end
+ assert_equal(s1[0], s1.chr)
+ }
+ end
+
+ def test_str_end_with?
+ combination(STRINGS, STRINGS) {|s1, s2|
+ desc = "#{encdump s1}.end_with?(#{encdump s2})"
+ if !str_enc_compatible?(s1, s2)
+ assert_raise(Encoding::CompatibilityError, desc) { s1.end_with?(s2) }
+ next
+ end
+ if s1.length < s2.length
+ assert_equal(false, enccall(s1, :end_with?, s2), desc)
+ next
+ end
+ if s1[s1.length-s2.length, s2.length] == s2
+ assert_equal(true, enccall(s1, :end_with?, s2), desc)
+ next
+ end
+ assert_equal(false, enccall(s1, :end_with?, s2), desc)
+ }
+ end
+
+ def test_str_start_with?
+ combination(STRINGS, STRINGS) {|s1, s2|
+ desc = "#{encdump s1}.start_with?(#{encdump s2})"
+ if !str_enc_compatible?(s1, s2)
+ assert_raise(Encoding::CompatibilityError, desc) { s1.start_with?(s2) }
+ next
+ end
+ s1 = s1.dup.force_encoding("ASCII-8BIT")
+ s2 = s2.dup.force_encoding("ASCII-8BIT")
+ if s1.length < s2.length
+ assert_equal(false, enccall(s1, :start_with?, s2), desc)
+ next
+ end
+ if s1[0, s2.length] == s2
+ assert_equal(true, enccall(s1, :start_with?, s2), desc)
+ next
+ end
+ assert_equal(false, enccall(s1, :start_with?, s2), desc)
+ }
+ end
+
+ def test_str_ord
+ STRINGS.each {|s1|
+ if s1.empty?
+ assert_raise(ArgumentError) { s1.ord }
+ next
+ end
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError) { s1.ord }
+ next
+ end
+ assert_equal(s1[0].ord, s1.ord)
+ }
+ end
+
+ def test_str_partition
+ combination(STRINGS, STRINGS) {|s1, s2|
+ desc = "#{encdump s1}.partition(#{encdump s2})"
+ if !str_enc_compatible?(s1, s2)
+ assert_raise(Encoding::CompatibilityError, desc) { s1.partition(s2) }
+ next
+ end
+ i = enccall(s1, :index, s2)
+ if !i
+ assert_equal([s1, "", ""], s1.partition(s2), desc)
+ next
+ end
+ assert_equal([s1[0,i], s2, s1[(i+s2.length)..-1]], s1.partition(s2), desc)
+ }
+ end
+
+ def test_str_rpartition
+ combination(STRINGS, STRINGS) {|s1, s2|
+ desc = "#{encdump s1}.rpartition(#{encdump s2})"
+ if !str_enc_compatible?(s1, s2)
+ assert_raise(Encoding::CompatibilityError, desc) { s1.rpartition(s2) }
+ next
+ end
+ i = enccall(s1, :rindex, s2)
+ if !i
+ assert_equal(["", "", s1], s1.rpartition(s2), desc)
+ next
+ end
+ assert_equal([s1[0,i], s2, s1[(i+s2.length)..-1]], s1.rpartition(s2), desc)
+ }
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_marshal.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_marshal.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_marshal.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,453 @@
+require 'test/unit'
+require 'tempfile'
+require_relative 'marshaltestlib'
+
+class TestMarshal < Test::Unit::TestCase
+ include MarshalTestLib
+
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def encode(o)
+ Marshal.dump(o)
+ end
+
+ def decode(s)
+ Marshal.load(s)
+ end
+
+ def fact(n)
+ return 1 if n == 0
+ f = 1
+ while n>0
+ f *= n
+ n -= 1
+ end
+ return f
+ end
+
+ def test_marshal
+ a = [1, 2, 3, [4,5,"foo"], {1=>"bar"}, 2.5, fact(30)]
+ assert_equal a, Marshal.load(Marshal.dump(a))
+
+ [[1,2,3,4], [81, 2, 118, 3146]].each { |w,x,y,z|
+ obj = (x.to_f + y.to_f / z.to_f) * Math.exp(w.to_f / (x.to_f + y.to_f / z.to_f))
+ assert_equal obj, Marshal.load(Marshal.dump(obj))
+ }
+ end
+
+ StrClone = String.clone
+ def test_marshal_cloned_class
+ assert_instance_of(StrClone, Marshal.load(Marshal.dump(StrClone.new("abc"))))
+ end
+
+ def test_inconsistent_struct
+ TestMarshal.const_set :StructOrNot, Struct.new(:a)
+ s = Marshal.dump(StructOrNot.new(1))
+ TestMarshal.instance_eval { remove_const :StructOrNot }
+ TestMarshal.const_set :StructOrNot, Class.new
+ assert_raise(TypeError, "[ruby-dev:31709]") { Marshal.load(s) }
+ end
+
+ def test_struct_invalid_members
+ TestMarshal.const_set :StructInvalidMembers, Struct.new(:a)
+ Marshal.load("\004\bIc&TestMarshal::StructInvalidMembers\006:\020__members__\"\bfoo")
+ assert_raise(TypeError, "[ruby-dev:31759]") {
+ TestMarshal::StructInvalidMembers.members
+ }
+ end
+
+ class C
+ def initialize(str)
+ @str = str
+ end
+ attr_reader :str
+ def _dump(limit)
+ @str
+ end
+ def self._load(s)
+ new(s)
+ end
+ end
+
+ def test_too_long_string
+ data = Marshal.dump(C.new("a".force_encoding("ascii-8bit")))
+ data[-2, 1] = "\003\377\377\377"
+ e = assert_raise(ArgumentError, "[ruby-dev:32054]") {
+ Marshal.load(data)
+ }
+ assert_equal("marshal data too short", e.message)
+ end
+
+
+ def test_userdef_encoding
+ s1 = "\xa4\xa4".force_encoding("euc-jp")
+ o1 = C.new(s1)
+ m = Marshal.dump(o1)
+ o2 = Marshal.load(m)
+ s2 = o2.str
+ assert_equal(s1, s2)
+ end
+
+ def test_pipe
+ o1 = C.new("a" * 10000)
+
+ r, w = IO.pipe
+ t = Thread.new { Marshal.load(r) }
+ Marshal.dump(o1, w)
+ o2 = t.value
+ assert_equal(o1.str, o2.str)
+
+ r, w = IO.pipe
+ t = Thread.new { Marshal.load(r) }
+ Marshal.dump(o1, w, 2)
+ o2 = t.value
+ assert_equal(o1.str, o2.str)
+
+ assert_raise(TypeError) { Marshal.dump("foo", Object.new) }
+ assert_raise(TypeError) { Marshal.load(Object.new) }
+ end
+
+ def test_limit
+ assert_equal([[[]]], Marshal.load(Marshal.dump([[[]]], 3)))
+ assert_raise(ArgumentError) { Marshal.dump([[[]]], 2) }
+ assert_nothing_raised(ArgumentError, '[ruby-core:24100]') { Marshal.dump("\u3042", 1) }
+ end
+
+ def test_userdef_invalid
+ o = C.new(nil)
+ assert_raise(TypeError) { Marshal.dump(o) }
+ end
+
+ def test_class
+ o = class << Object.new; self; end
+ assert_raise(TypeError) { Marshal.dump(o) }
+ assert_equal(Object, Marshal.load(Marshal.dump(Object)))
+ assert_equal(Enumerable, Marshal.load(Marshal.dump(Enumerable)))
+ end
+
+ class C2
+ def initialize(ary)
+ @ary = ary
+ end
+ def _dump(s)
+ @ary.clear
+ "foo"
+ end
+ end
+
+ def test_modify_array_during_dump
+ a = []
+ o = C2.new(a)
+ a << o << nil
+ assert_raise(RuntimeError) { Marshal.dump(a) }
+ end
+
+ def test_change_class_name
+ eval("class C3; def _dump(s); 'foo'; end; end")
+ m = Marshal.dump(C3.new)
+ assert_raise(TypeError) { Marshal.load(m) }
+ eval("C3 = nil")
+ assert_raise(TypeError) { Marshal.load(m) }
+ end
+
+ def test_change_struct
+ eval("C3 = Struct.new(:foo, :bar)")
+ m = Marshal.dump(C3.new("FOO", "BAR"))
+ eval("C3 = Struct.new(:foo)")
+ assert_raise(TypeError) { Marshal.load(m) }
+ eval("C3 = Struct.new(:foo, :baz)")
+ assert_raise(TypeError) { Marshal.load(m) }
+ end
+
+ class C4
+ def initialize(gc)
+ @gc = gc
+ end
+ def _dump(s)
+ GC.start if @gc
+ "foo"
+ end
+ end
+
+ def test_gc
+ assert_nothing_raised do
+ Marshal.dump((0..1000).map {|x| C4.new(x % 50 == 25) })
+ end
+ end
+
+ def test_taint_and_untrust
+ x = Object.new
+ x.taint
+ x.untrust
+ s = Marshal.dump(x)
+ assert_equal(true, s.tainted?)
+ assert_equal(true, s.untrusted?)
+ y = Marshal.load(s)
+ assert_equal(true, y.tainted?)
+ assert_equal(true, y.untrusted?)
+ end
+
+ def test_taint_and_untrust_each_object
+ x = Object.new
+ obj = [[x]]
+
+ # clean object causes crean stream
+ assert_equal(false, obj.tainted?)
+ assert_equal(false, obj.untrusted?)
+ assert_equal(false, obj.first.tainted?)
+ assert_equal(false, obj.first.untrusted?)
+ assert_equal(false, obj.first.first.tainted?)
+ assert_equal(false, obj.first.first.untrusted?)
+ s = Marshal.dump(obj)
+ assert_equal(false, s.tainted?)
+ assert_equal(false, s.untrusted?)
+
+ # tainted/untrusted object causes tainted/untrusted stream
+ x.taint
+ x.untrust
+ assert_equal(false, obj.tainted?)
+ assert_equal(false, obj.untrusted?)
+ assert_equal(false, obj.first.tainted?)
+ assert_equal(false, obj.first.untrusted?)
+ assert_equal(true, obj.first.first.tainted?)
+ assert_equal(true, obj.first.first.untrusted?)
+ t = Marshal.dump(obj)
+ assert_equal(true, t.tainted?)
+ assert_equal(true, t.untrusted?)
+
+ # clean stream causes clean objects
+ assert_equal(false, s.tainted?)
+ assert_equal(false, s.untrusted?)
+ y = Marshal.load(s)
+ assert_equal(false, y.tainted?)
+ assert_equal(false, y.untrusted?)
+ assert_equal(false, y.first.tainted?)
+ assert_equal(false, y.first.untrusted?)
+ assert_equal(false, y.first.first.tainted?)
+ assert_equal(false, y.first.first.untrusted?)
+
+ # tainted/untrusted stream causes tainted/untrusted objects
+ assert_equal(true, t.tainted?)
+ assert_equal(true, t.untrusted?)
+ y = Marshal.load(t)
+ assert_equal(true, y.tainted?)
+ assert_equal(true, y.untrusted?)
+ assert_equal(true, y.first.tainted?)
+ assert_equal(true, y.first.untrusted?)
+ assert_equal(true, y.first.first.tainted?)
+ assert_equal(true, y.first.first.untrusted?)
+
+ # same tests by different senario
+ s.taint
+ s.untrust
+ assert_equal(true, s.tainted?)
+ assert_equal(true, s.untrusted?)
+ y = Marshal.load(s)
+ assert_equal(true, y.tainted?)
+ assert_equal(true, y.untrusted?)
+ assert_equal(true, y.first.tainted?)
+ assert_equal(true, y.first.untrusted?)
+ assert_equal(true, y.first.first.tainted?)
+ assert_equal(true, y.first.first.untrusted?)
+ end
+
+ def test_symbol
+ [:ruby, :"\u{7d05}\u{7389}"].each do |sym|
+ assert_equal(sym, Marshal.load(Marshal.dump(sym)), '[ruby-core:24788]')
+ end
+ bug2548 = '[ruby-core:27375]'
+ ary = [:$1, nil]
+ assert_equal(ary, Marshal.load(Marshal.dump(ary)), bug2548)
+ end
+
+ ClassUTF8 = eval("class R\u{e9}sum\u{e9}; self; end")
+
+ iso_8859_1 = Encoding::ISO_8859_1
+
+ structISO8859_1 = Struct.new("r\xe9sum\xe9".force_encoding(iso_8859_1).intern)
+ const_set("R\xe9sum\xe9".force_encoding(iso_8859_1), structISO8859_1)
+ structISO8859_1.name
+ StructISO8859_1 = structISO8859_1
+ classISO8859_1 = Class.new do
+ attr_accessor "r\xe9sum\xe9".force_encoding(iso_8859_1)
+ eval("def initialize(x) @r\xe9sum\xe9 = x; end".force_encoding(iso_8859_1))
+ end
+ const_set("R\xe9sum\xe92".force_encoding(iso_8859_1), classISO8859_1)
+ classISO8859_1.name
+ ClassISO8859_1 = classISO8859_1
+
+ def test_class_nonascii
+ a = ClassUTF8.new
+ assert_instance_of(ClassUTF8, Marshal.load(Marshal.dump(a)), '[ruby-core:24790]')
+
+ bug1932 = '[ruby-core:24882]'
+
+ a = StructISO8859_1.new(10)
+ assert_nothing_raised(bug1932) do
+ assert_equal(a, Marshal.load(Marshal.dump(a)), bug1932)
+ end
+ a.__send__("#{StructISO8859_1.members[0]}=", a)
+ assert_nothing_raised(bug1932) do
+ assert_equal(a, Marshal.load(Marshal.dump(a)), bug1932)
+ end
+
+ a = ClassISO8859_1.new(10)
+ assert_nothing_raised(bug1932) do
+ b = Marshal.load(Marshal.dump(a))
+ assert_equal(ClassISO8859_1, b.class, bug1932)
+ assert_equal(a.instance_variables, b.instance_variables, bug1932)
+ a.instance_variables.each do |i|
+ assert_equal(a.instance_variable_get(i), b.instance_variable_get(i), bug1932)
+ end
+ end
+ a.__send__(a.methods(true).grep(/=\z/)[0], a)
+ assert_nothing_raised(bug1932) do
+ b = Marshal.load(Marshal.dump(a))
+ assert_equal(ClassISO8859_1, b.class, bug1932)
+ assert_equal(a.instance_variables, b.instance_variables, bug1932)
+ assert_equal(b, b.instance_variable_get(a.instance_variables[0]), bug1932)
+ end
+ end
+
+ def test_regexp
+ assert_equal(/\\u/, Marshal.load("\004\b/\b\\\\u\000"))
+ assert_equal(/u/, Marshal.load("\004\b/\a\\u\000"))
+ assert_equal(/u/, Marshal.load("\004\bI/\a\\u\000\006:\016 at encoding\"\vEUC-JP"))
+
+ bug2109 = '[ruby-core:25625]'
+ a = "\x82\xa0".force_encoding(Encoding::Windows_31J)
+ b = "\x82\xa2".force_encoding(Encoding::Windows_31J)
+ c = [/#{a}/, /#{b}/]
+ assert_equal(c, Marshal.load(Marshal.dump(c)), bug2109)
+
+ assert_nothing_raised(ArgumentError, '[ruby-dev:40386]') do
+ re = Tempfile.open("marshal_regexp") do |f|
+ f.binmode.write("\x04\bI/\x00\x00\x06:\rencoding\"\rUS-ASCII")
+ f.close
+ Marshal.load(f.open.binmode)
+ end
+ assert_equal(//, re)
+ end
+ end
+
+ class DumpTest
+ def marshal_dump
+ @@block.call(:marshal_dump)
+ end
+
+ def dump_each(&block)
+ @@block = block
+ Marshal.dump(self)
+ end
+ end
+
+ class LoadTest
+ def marshal_dump
+ nil
+ end
+ def marshal_load(obj)
+ @@block.call(:marshal_load)
+ end
+ def self.load_each(m, &block)
+ @@block = block
+ Marshal.load(m)
+ end
+ end
+
+ def test_context_switch
+ o = DumpTest.new
+ e = o.enum_for(:dump_each)
+ assert_equal(:marshal_dump, e.next)
+ GC.start
+ assert(true, '[ruby-dev:39425]')
+ assert_raise(StopIteration) {e.next}
+
+ o = LoadTest.new
+ m = Marshal.dump(o)
+ e = LoadTest.enum_for(:load_each, m)
+ assert_equal(:marshal_load, e.next)
+ GC.start
+ assert(true, '[ruby-dev:39425]')
+ assert_raise(StopIteration) {e.next}
+ end
+
+ def test_dump_buffer
+ bug2390 = '[ruby-dev:39744]'
+ w = ""
+ def w.write(str)
+ self << str.to_s
+ end
+ Marshal.dump(Object.new, w)
+ assert_not_empty(w, bug2390)
+ end
+
+ class C5
+ def marshal_dump
+ "foo"
+ end
+ def marshal_load(foo)
+ @foo = foo
+ end
+ def initialize(x)
+ @x = x
+ end
+ end
+ def test_marshal_dump
+ c = C5.new("bar")
+ s = Marshal.dump(c)
+ d = Marshal.load(s)
+ assert_equal("foo", d.instance_variable_get(:@foo))
+ assert_equal(false, d.instance_variable_defined?(:@x))
+ end
+
+ class C6
+ def initialize
+ @stdin = STDIN
+ end
+ attr_reader :stdin
+ def marshal_dump
+ 1
+ end
+ def marshal_load(x)
+ @stdin = STDIN
+ end
+ end
+ def test_marshal_dump_extra_iv
+ o = C6.new
+ m = nil
+ assert_nothing_raised("[ruby-dev:21475] [ruby-dev:39845]") {
+ m = Marshal.dump(o)
+ }
+ o2 = Marshal.load(m)
+ assert_equal(STDIN, o.stdin)
+ end
+
+ def test_marshal_string_encoding
+ o1 = ["foo".force_encoding("EUC-JP")] + [ "bar" ] * 2
+ m = Marshal.dump(o1)
+ o2 = Marshal.load(m)
+ assert_equal(o1, o2, "[ruby-dev:40388]")
+ end
+
+ def test_marshal_regexp_encoding
+ o1 = [Regexp.new("r1".force_encoding("EUC-JP"))] + ["r2"] * 2
+ m = Marshal.dump(o1)
+ o2 = Marshal.load(m)
+ assert_equal(o1, o2, "[ruby-dev:40416]")
+ end
+
+ def test_marshal_encoding_encoding
+ o1 = [Encoding.find("EUC-JP")] + ["r2"] * 2
+ m = Marshal.dump(o1)
+ o2 = Marshal.load(m)
+ assert_equal(o1, o2)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_math.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_math.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_math.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,278 @@
+require 'test/unit'
+
+class TestMath < Test::Unit::TestCase
+ def assert_infinity(a, *rest)
+ rest = ["not infinity: #{a.inspect}"] if rest.empty?
+ assert(!a.finite?, *rest)
+ end
+
+ def assert_nan(a, *rest)
+ rest = ["not nan: #{a.inspect}"] if rest.empty?
+ assert(a.nan?, *rest)
+ end
+
+ def check(a, b)
+ err = [Float::EPSILON * 4, [a.abs, b.abs].max * Float::EPSILON * 256].max
+ assert_in_delta(a, b, err)
+ end
+
+ def test_atan2
+ assert_raise(Math::DomainError) { Math.atan2(0, 0) }
+ assert_raise(Math::DomainError) { Math.atan2(Float::INFINITY, Float::INFINITY) }
+ assert_raise(Math::DomainError) { Math.atan2(Float::INFINITY, -Float::INFINITY) }
+ assert_raise(Math::DomainError) { Math.atan2(-Float::INFINITY, Float::INFINITY) }
+ assert_raise(Math::DomainError) { Math.atan2(-Float::INFINITY, -Float::INFINITY) }
+ check(0, Math.atan2(0, 1))
+ check(Math::PI / 4, Math.atan2(1, 1))
+ check(Math::PI / 2, Math.atan2(1, 0))
+ end
+
+ def test_cos
+ check(1.0, Math.cos(0 * Math::PI / 4))
+ check(1.0 / Math.sqrt(2), Math.cos(1 * Math::PI / 4))
+ check(0.0, Math.cos(2 * Math::PI / 4))
+ check(-1.0, Math.cos(4 * Math::PI / 4))
+ check(0.0, Math.cos(6 * Math::PI / 4))
+ end
+
+ def test_sin
+ check(0.0, Math.sin(0 * Math::PI / 4))
+ check(1.0 / Math.sqrt(2), Math.sin(1 * Math::PI / 4))
+ check(1.0, Math.sin(2 * Math::PI / 4))
+ check(0.0, Math.sin(4 * Math::PI / 4))
+ check(-1.0, Math.sin(6 * Math::PI / 4))
+ end
+
+ def test_tan
+ check(0.0, Math.tan(0 * Math::PI / 4))
+ check(1.0, Math.tan(1 * Math::PI / 4))
+ assert(Math.tan(2 * Math::PI / 4).abs > 1024)
+ check(0.0, Math.tan(4 * Math::PI / 4))
+ assert(Math.tan(6 * Math::PI / 4).abs > 1024)
+ end
+
+ def test_acos
+ check(0 * Math::PI / 4, Math.acos( 1.0))
+ check(1 * Math::PI / 4, Math.acos( 1.0 / Math.sqrt(2)))
+ check(2 * Math::PI / 4, Math.acos( 0.0))
+ check(4 * Math::PI / 4, Math.acos(-1.0))
+ assert_raise(Math::DomainError) { Math.acos(+1.0 + Float::EPSILON) }
+ assert_raise(Math::DomainError) { Math.acos(-1.0 - Float::EPSILON) }
+ assert_raise(Math::DomainError) { Math.acos(2.0) }
+ end
+
+ def test_asin
+ check( 0 * Math::PI / 4, Math.asin( 0.0))
+ check( 1 * Math::PI / 4, Math.asin( 1.0 / Math.sqrt(2)))
+ check( 2 * Math::PI / 4, Math.asin( 1.0))
+ check(-2 * Math::PI / 4, Math.asin(-1.0))
+ assert_raise(Math::DomainError) { Math.asin(+1.0 + Float::EPSILON) }
+ assert_raise(Math::DomainError) { Math.asin(-1.0 - Float::EPSILON) }
+ assert_raise(Math::DomainError) { Math.asin(2.0) }
+ end
+
+ def test_atan
+ check( 0 * Math::PI / 4, Math.atan( 0.0))
+ check( 1 * Math::PI / 4, Math.atan( 1.0))
+ check( 2 * Math::PI / 4, Math.atan(1.0 / 0.0))
+ check(-1 * Math::PI / 4, Math.atan(-1.0))
+ end
+
+ def test_cosh
+ check(1, Math.cosh(0))
+ check((Math::E ** 1 + Math::E ** -1) / 2, Math.cosh(1))
+ check((Math::E ** 2 + Math::E ** -2) / 2, Math.cosh(2))
+ end
+
+ def test_sinh
+ check(0, Math.sinh(0))
+ check((Math::E ** 1 - Math::E ** -1) / 2, Math.sinh(1))
+ check((Math::E ** 2 - Math::E ** -2) / 2, Math.sinh(2))
+ end
+
+ def test_tanh
+ check(Math.sinh(0) / Math.cosh(0), Math.tanh(0))
+ check(Math.sinh(1) / Math.cosh(1), Math.tanh(1))
+ check(Math.sinh(2) / Math.cosh(2), Math.tanh(2))
+ end
+
+ def test_acosh
+ check(0, Math.acosh(1))
+ check(1, Math.acosh((Math::E ** 1 + Math::E ** -1) / 2))
+ check(2, Math.acosh((Math::E ** 2 + Math::E ** -2) / 2))
+ assert_raise(Math::DomainError) { Math.acosh(1.0 - Float::EPSILON) }
+ assert_raise(Math::DomainError) { Math.acosh(0) }
+ end
+
+ def test_asinh
+ check(0, Math.asinh(0))
+ check(1, Math.asinh((Math::E ** 1 - Math::E ** -1) / 2))
+ check(2, Math.asinh((Math::E ** 2 - Math::E ** -2) / 2))
+ end
+
+ def test_atanh
+ check(0, Math.atanh(Math.sinh(0) / Math.cosh(0)))
+ check(1, Math.atanh(Math.sinh(1) / Math.cosh(1)))
+ check(2, Math.atanh(Math.sinh(2) / Math.cosh(2)))
+ assert_nothing_raised { assert_infinity(Math.atanh(1)) }
+ assert_nothing_raised { assert_infinity(-Math.atanh(-1)) }
+ assert_raise(Math::DomainError) { Math.atanh(+1.0 + Float::EPSILON) }
+ assert_raise(Math::DomainError) { Math.atanh(-1.0 - Float::EPSILON) }
+ end
+
+ def test_exp
+ check(1, Math.exp(0))
+ check(Math.sqrt(Math::E), Math.exp(0.5))
+ check(Math::E, Math.exp(1))
+ check(Math::E ** 2, Math.exp(2))
+ end
+
+ def test_log
+ check(0, Math.log(1))
+ check(1, Math.log(Math::E))
+ check(0, Math.log(1, 10))
+ check(1, Math.log(10, 10))
+ check(2, Math.log(100, 10))
+ assert_equal(1.0/0, Math.log(1.0/0))
+ assert_nothing_raised { assert_infinity(-Math.log(+0.0)) }
+ assert_nothing_raised { assert_infinity(-Math.log(-0.0)) }
+ assert_raise(Math::DomainError) { Math.log(-1.0) }
+ assert_raise(TypeError) { Math.log(1,nil) }
+ end
+
+ def test_log2
+ check(0, Math.log2(1))
+ check(1, Math.log2(2))
+ check(2, Math.log2(4))
+ assert_equal(1.0/0, Math.log2(1.0/0))
+ assert_nothing_raised { assert_infinity(-Math.log2(+0.0)) }
+ assert_nothing_raised { assert_infinity(-Math.log2(-0.0)) }
+ assert_raise(Math::DomainError) { Math.log2(-1.0) }
+ end
+
+ def test_log10
+ check(0, Math.log10(1))
+ check(1, Math.log10(10))
+ check(2, Math.log10(100))
+ assert_equal(1.0/0, Math.log10(1.0/0))
+ assert_nothing_raised { assert_infinity(-Math.log10(+0.0)) }
+ assert_nothing_raised { assert_infinity(-Math.log10(-0.0)) }
+ assert_raise(Math::DomainError) { Math.log10(-1.0) }
+ end
+
+ def test_sqrt
+ check(0, Math.sqrt(0))
+ check(1, Math.sqrt(1))
+ check(2, Math.sqrt(4))
+ assert_equal(1.0/0, Math.sqrt(1.0/0))
+ assert_equal("0.0", Math.sqrt(-0.0).to_s) # insure it is +0.0, not -0.0
+ assert_raise(Math::DomainError) { Math.sqrt(-1.0) }
+ end
+
+ def test_frexp
+ check(0.0, Math.frexp(0.0).first)
+ assert_equal(0, Math.frexp(0).last)
+ check(0.5, Math.frexp(0.5).first)
+ assert_equal(0, Math.frexp(0.5).last)
+ check(0.5, Math.frexp(1.0).first)
+ assert_equal(1, Math.frexp(1.0).last)
+ check(0.5, Math.frexp(2.0).first)
+ assert_equal(2, Math.frexp(2.0).last)
+ check(0.75, Math.frexp(3.0).first)
+ assert_equal(2, Math.frexp(3.0).last)
+ end
+
+ def test_ldexp
+ check(0.0, Math.ldexp(0.0, 0.0))
+ check(0.5, Math.ldexp(0.5, 0.0))
+ check(1.0, Math.ldexp(0.5, 1.0))
+ check(2.0, Math.ldexp(0.5, 2.0))
+ check(3.0, Math.ldexp(0.75, 2.0))
+ end
+
+ def test_hypot
+ check(5, Math.hypot(3, 4))
+ end
+
+ def test_erf
+ check(0, Math.erf(0))
+ check(1, Math.erf(1.0 / 0.0))
+ end
+
+ def test_erfc
+ check(1, Math.erfc(0))
+ check(0, Math.erfc(1.0 / 0.0))
+ end
+
+ def test_gamma
+ sqrt_pi = Math.sqrt(Math::PI)
+ check(4 * sqrt_pi / 3, Math.gamma(-1.5))
+ check(-2 * sqrt_pi, Math.gamma(-0.5))
+ check(sqrt_pi, Math.gamma(0.5))
+ check(1, Math.gamma(1))
+ check(sqrt_pi / 2, Math.gamma(1.5))
+ check(1, Math.gamma(2))
+ check(3 * sqrt_pi / 4, Math.gamma(2.5))
+ check(2, Math.gamma(3))
+ check(15 * sqrt_pi / 8, Math.gamma(3.5))
+ check(6, Math.gamma(4))
+
+ # no SEGV [ruby-core:25257]
+ 31.upto(65) do |i|
+ i = 1 << i
+ assert_infinity(Math.gamma(i), "Math.gamma(#{i}) should be INF")
+ assert_infinity(Math.gamma(i-1), "Math.gamma(#{i-1}) should be INF")
+ end
+
+ assert_raise(Math::DomainError) { Math.gamma(-Float::INFINITY) }
+ end
+
+ def test_lgamma
+ sqrt_pi = Math.sqrt(Math::PI)
+
+ g, s = Math.lgamma(-1.5)
+ check(Math.log(4 * sqrt_pi / 3), g)
+ assert_equal(s, 1)
+
+ g, s = Math.lgamma(-0.5)
+ check(Math.log(2 * sqrt_pi), g)
+ assert_equal(s, -1)
+
+ g, s = Math.lgamma(0.5)
+ check(Math.log(sqrt_pi), g)
+ assert_equal(s, 1)
+
+ assert_equal([0, 1], Math.lgamma(1))
+
+ g, s = Math.lgamma(1.5)
+ check(Math.log(sqrt_pi / 2), g)
+ assert_equal(s, 1)
+
+ assert_equal([0, 1], Math.lgamma(2))
+
+ g, s = Math.lgamma(2.5)
+ check(Math.log(3 * sqrt_pi / 4), g)
+ assert_equal(s, 1)
+
+ g, s = Math.lgamma(3)
+ check(Math.log(2), g)
+ assert_equal(s, 1)
+
+ g, s = Math.lgamma(3.5)
+ check(Math.log(15 * sqrt_pi / 8), g)
+ assert_equal(s, 1)
+
+ g, s = Math.lgamma(4)
+ check(Math.log(6), g)
+ assert_equal(s, 1)
+
+ assert_raise(Math::DomainError) { Math.lgamma(-Float::INFINITY) }
+ end
+
+ def test_cbrt
+ check(1, Math.cbrt(1))
+ check(-2, Math.cbrt(-8))
+ check(3, Math.cbrt(27))
+ check(-0.1, Math.cbrt(-0.001))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_metaclass.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_metaclass.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_metaclass.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,167 @@
+require 'test/unit'
+
+class TestMetaclass < Test::Unit::TestCase
+ class Foo; end
+ class Bar < Foo; end
+ class Baz; end
+
+ def setup
+ Object.class_eval do
+ def method_o; end
+ end
+ Module.class_eval do
+ def method_m; end
+ end
+ Class.class_eval do
+ def method_c; end
+ end
+ end
+ def teardown
+ Object.class_eval do
+ remove_method :method_o rescue nil
+ end
+ Module.class_eval do
+ remove_method :method_m rescue nil
+ end
+ Class.class_eval do
+ remove_method :method_c rescue nil
+ end
+ Object.class_eval do
+ class << self
+ remove_method :class_method_o rescue nil
+ end
+ end
+ Module.class_eval do
+ class << self
+ remove_method :class_method_m rescue nil
+ end
+ end
+ Class.class_eval do
+ class << self
+ remove_method :class_method_c rescue nil
+ end
+ end
+ Object.class_eval do
+ class << self
+ class << self
+ remove_method :metaclass_method_o rescue nil
+ end
+ end
+ end
+ Module.class_eval do
+ class << self
+ class << self
+ remove_method :metaclass_method_m rescue nil
+ end
+ end
+ end
+ Class.class_eval do
+ class << self
+ class << self
+ remove_method :metaclass_method_c rescue nil
+ end
+ end
+ end
+ end
+
+ def test_metaclass
+ class << Object
+ def class_method_o; end
+ end
+ class << Foo
+ def class_method_f; end
+ end
+ class << Baz
+ def class_method_b; end
+ end
+ assert_nothing_raised{ Bar.method_o }
+ assert_nothing_raised{ Bar.method_m }
+ assert_nothing_raised{ Bar.method_c }
+ assert_nothing_raised{ Bar.class_method_o }
+ assert_nothing_raised{ Bar.class_method_f }
+ assert_raise(NoMethodError){ Bar.class_method_b }
+
+ class << Module
+ def class_method_m; end
+ end
+ class << Class
+ def class_method_c; end
+ end
+ class << Object
+ class << self
+ def metaclass_method_o; end
+ end
+ end
+ class << Foo
+ class << self
+ def metaclass_method_f; end
+ end
+ end
+ class << Baz
+ class << self
+ def metaclass_method_b; end
+ end
+ end
+ metaclass_of_bar = class << Bar; self end
+ assert_nothing_raised{ metaclass_of_bar.method_o }
+ assert_nothing_raised{ metaclass_of_bar.method_m }
+ assert_nothing_raised{ metaclass_of_bar.method_c }
+ assert_nothing_raised{ metaclass_of_bar.class_method_o }
+ assert_raise(NoMethodError){ metaclass_of_bar.class_method_f }
+ assert_raise(NoMethodError){ metaclass_of_bar.class_method_b }
+ assert_nothing_raised{ metaclass_of_bar.class_method_m }
+ assert_nothing_raised{ metaclass_of_bar.class_method_c }
+ assert_nothing_raised{ metaclass_of_bar.metaclass_method_o }
+ assert_nothing_raised{ metaclass_of_bar.metaclass_method_f }
+ assert_raise(NoMethodError){ metaclass_of_bar.metaclass_method_b }
+
+ class << Module
+ class << self
+ def metaclass_method_m; end
+ end
+ end
+ class << Class
+ class << self
+ def metaclass_method_c; end
+ end
+ end
+ class << Object
+ class << self
+ class << self
+ def metametaclass_method_o; end
+ end
+ end
+ end
+ class << Foo
+ class << self
+ class << self
+ def metametaclass_method_f; end
+ end
+ end
+ end
+ class << Baz
+ class << self
+ class << self
+ def metametaclass_method_b; end
+ end
+ end
+ end
+ metametaclass_of_bar = class << metaclass_of_bar; self end
+ assert_nothing_raised{ metametaclass_of_bar.method_o }
+ assert_nothing_raised{ metametaclass_of_bar.method_m }
+ assert_nothing_raised{ metametaclass_of_bar.method_c }
+ assert_nothing_raised{ metametaclass_of_bar.class_method_o }
+ assert_raise(NoMethodError){ metametaclass_of_bar.class_method_f }
+ assert_raise(NoMethodError){ metametaclass_of_bar.class_method_b }
+ assert_nothing_raised{ metametaclass_of_bar.class_method_m }
+ assert_nothing_raised{ metametaclass_of_bar.class_method_c }
+ assert_nothing_raised{ metametaclass_of_bar.metaclass_method_o }
+ assert_raise(NoMethodError){ metametaclass_of_bar.metaclass_method_f }
+ assert_raise(NoMethodError){ metametaclass_of_bar.metaclass_method_b }
+ assert_nothing_raised{ metametaclass_of_bar.metaclass_method_m }
+ assert_nothing_raised{ metametaclass_of_bar.metaclass_method_c }
+ assert_nothing_raised{ metametaclass_of_bar.metametaclass_method_o }
+ assert_nothing_raised{ metametaclass_of_bar.metametaclass_method_f }
+ assert_raise(NoMethodError){ metametaclass_of_bar.metaclass_method_b }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_method.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_method.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_method.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,352 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestMethod < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def m0() end
+ def m1(a) end
+ def m2(a, b) end
+ def mo1(a = nil, &b) end
+ def mo2(a, b = nil) end
+ def mo3(*a) end
+ def mo4(a, *b, &c) end
+ def mo5(a, *b, c) end
+ def mo6(a, *b, c, &d) end
+ def mo7(a, b = nil, *c, d, &e) end
+ def ma1((a), &b) end
+
+ class Base
+ def foo() :base end
+ end
+ class Derived < Base
+ def foo() :derived end
+ end
+ class T
+ def initialize; end
+ def normal_method; end
+ end
+ module M
+ def func; end
+ module_function :func
+ def meth; end
+ end
+
+ def test_arity
+ assert_equal(0, method(:m0).arity)
+ assert_equal(1, method(:m1).arity)
+ assert_equal(2, method(:m2).arity)
+ assert_equal(-1, method(:mo1).arity)
+ assert_equal(-2, method(:mo2).arity)
+ assert_equal(-1, method(:mo3).arity)
+ assert_equal(-2, method(:mo4).arity)
+ assert_equal(-3, method(:mo5).arity)
+ assert_equal(-3, method(:mo6).arity)
+ end
+
+ def test_arity_special
+ assert_equal(-1, method(:__send__).arity)
+ end
+
+ def test_unbind
+ assert_equal(:derived, Derived.new.foo)
+ um = Derived.new.method(:foo).unbind
+ assert_instance_of(UnboundMethod, um)
+ Derived.class_eval do
+ def foo() :changed end
+ end
+ assert_equal(:changed, Derived.new.foo)
+ assert_equal(:derived, um.bind(Derived.new).call)
+ assert_raise(TypeError) do
+ um.bind(Base.new)
+ end
+ end
+
+ def test_callee
+ assert_equal(:test_callee, __method__)
+ assert_equal(:m, Class.new {def m; __method__; end}.new.m)
+ assert_equal(:m, Class.new {def m; tap{return __method__}; end}.new.m)
+ assert_equal(:m, Class.new {define_method(:m) {__method__}}.new.m)
+ assert_equal(:m, Class.new {define_method(:m) {tap{return __method__}}}.new.m)
+ assert_nil(eval("class TestCallee; __method__; end"))
+ end
+
+ def test_body
+ o = Object.new
+ def o.foo; end
+ assert_nothing_raised { RubyVM::InstructionSequence.disasm(o.method(:foo)) }
+ assert_nothing_raised { RubyVM::InstructionSequence.disasm("x".method(:upcase)) }
+ end
+
+ def test_new
+ c1 = Class.new
+ c1.class_eval { def foo; :foo; end }
+ c2 = Class.new(c1)
+ c2.class_eval { private :foo }
+ o = c2.new
+ o.extend(Module.new)
+ assert_raise(NameError) { o.method(:bar) }
+ assert_raise(NameError) { o.public_method(:foo) }
+ assert_equal(:foo, o.method(:foo).call)
+ end
+
+ def test_eq
+ o = Object.new
+ class << o
+ def foo; end
+ alias bar foo
+ def baz; end
+ end
+ assert_not_equal(o.method(:foo), nil)
+ m = o.method(:foo)
+ def m.foo; end
+ assert_not_equal(o.method(:foo), m)
+ assert_equal(o.method(:foo), o.method(:foo))
+ assert_equal(o.method(:foo), o.method(:bar))
+ assert_not_equal(o.method(:foo), o.method(:baz))
+ end
+
+ def test_hash
+ o = Object.new
+ def o.foo; end
+ assert_kind_of(Integer, o.method(:foo).hash)
+ end
+
+ def test_receiver_name_owner
+ o = Object.new
+ def o.foo; end
+ m = o.method(:foo)
+ assert_equal(o, m.receiver)
+ assert_equal(:foo, m.name)
+ assert_equal(class << o; self; end, m.owner)
+ assert_equal(:foo, m.unbind.name)
+ assert_equal(class << o; self; end, m.unbind.owner)
+ end
+
+ def test_instance_method
+ c = Class.new
+ c.class_eval do
+ def foo; :foo; end
+ private :foo
+ end
+ o = c.new
+ o.method(:foo).unbind
+ assert_raise(NoMethodError) { o.foo }
+ c.instance_method(:foo).bind(o)
+ assert_equal(:foo, o.instance_eval { foo })
+ assert_raise(NameError) { c.public_instance_method(:foo) }
+ def o.bar; end
+ m = o.method(:bar).unbind
+ assert_raise(TypeError) { m.bind(Object.new) }
+ end
+
+ def test_define_method
+ skip("[BUG : #???] Abort")
+
+ c = Class.new
+ c.class_eval { def foo; :foo; end }
+ o = c.new
+ def o.bar; :bar; end
+ assert_raise(TypeError) do
+ c.class_eval { define_method(:foo, :foo) }
+ end
+ assert_raise(ArgumentError) do
+ c.class_eval { define_method }
+ end
+ c2 = Class.new(c)
+ c2.class_eval { define_method(:baz, o.method(:foo)) }
+ assert_equal(:foo, c2.new.baz)
+ assert_raise(TypeError) do
+ Class.new.class_eval { define_method(:foo, o.method(:foo)) }
+ end
+ assert_raise(TypeError) do
+ Class.new.class_eval { define_method(:bar, o.method(:bar)) }
+ end
+
+ o = Object.new
+ def o.foo(c)
+ c.class_eval { define_method(:foo) }
+ end
+ c = Class.new
+ o.foo(c) { :foo }
+ assert_equal(:foo, c.new.foo)
+
+ o = Object.new
+ o.instance_eval { define_singleton_method(:foo) { :foo } }
+ assert_equal(:foo, o.foo)
+
+ assert_raise(TypeError) do
+ Class.new.class_eval { define_method(:foo, Object.new) }
+ end
+ end
+
+ def test_clone
+ o = Object.new
+ def o.foo; :foo; end
+ m = o.method(:foo)
+ def m.bar; :bar; end
+ assert_equal(:foo, m.clone.call)
+ assert_equal(:bar, m.clone.bar)
+ end
+
+ def test_call
+ skip("[BUG : #842] SecurityError Level 4")
+
+ o = Object.new
+ def o.foo; p 1; end
+ def o.bar(x); x; end
+ m = o.method(:foo)
+ m.taint
+ assert_raise(SecurityError) { m.call }
+ end
+
+ def test_inspect
+ o = Object.new
+ def o.foo; end
+ m = o.method(:foo)
+ assert_equal("#<Method: #{ o.inspect }.foo>", m.inspect)
+ m = o.method(:foo)
+ assert_equal("#<UnboundMethod: #{ class << o; self; end.inspect }#foo>", m.unbind.inspect)
+
+ c = Class.new
+ c.class_eval { def foo; end; }
+ m = c.new.method(:foo)
+ assert_equal("#<Method: #{ c.inspect }#foo>", m.inspect)
+ m = c.instance_method(:foo)
+ assert_equal("#<UnboundMethod: #{ c.inspect }#foo>", m.inspect)
+
+ c2 = Class.new(c)
+ c2.class_eval { private :foo }
+ m2 = c2.new.method(:foo)
+ assert_equal("#<Method: #{ c2.inspect }(#{ c.inspect })#foo>", m2.inspect)
+ end
+
+ def test_callee_top_level
+ assert_in_out_err([], "p __callee__", %w(nil), [])
+ end
+
+ def test_caller_top_level
+ assert_in_out_err([], "p caller", %w([]), [])
+ end
+
+ def test_caller_negative_level
+ assert_raise(ArgumentError) { caller(-1) }
+ end
+
+ def test_attrset_ivar
+ c = Class.new
+ c.class_eval { attr_accessor :foo }
+ o = c.new
+ o.method(:foo=).call(42)
+ assert_equal(42, o.foo)
+ assert_raise(ArgumentError) { o.method(:foo=).call(1, 2, 3) }
+ assert_raise(ArgumentError) { o.method(:foo).call(1) }
+ end
+
+ def test_default_accessibility
+ assert T.public_instance_methods.include?(:normal_method), 'normal methods are public by default'
+ assert !T.public_instance_methods.include?(:initialize), '#initialize is private'
+ assert !M.public_instance_methods.include?(:func), 'module methods are private by default'
+ assert M.public_instance_methods.include?(:meth), 'normal methods are public by default'
+ end
+
+ define_method(:pm0) {||}
+ define_method(:pm1) {|a|}
+ define_method(:pm2) {|a, b|}
+ define_method(:pmo1) {|a = nil, &b|}
+ define_method(:pmo2) {|a, b = nil|}
+ define_method(:pmo3) {|*a|}
+ define_method(:pmo4) {|a, *b, &c|}
+ define_method(:pmo5) {|a, *b, c|}
+ define_method(:pmo6) {|a, *b, c, &d|}
+ define_method(:pmo7) {|a, b = nil, *c, d, &e|}
+ define_method(:pma1) {|(a), &b|}
+
+ def test_bound_parameters
+ assert_equal([], method(:m0).parameters)
+ assert_equal([[:req, :a]], method(:m1).parameters)
+ assert_equal([[:req, :a], [:req, :b]], method(:m2).parameters)
+ assert_equal([[:opt, :a], [:block, :b]], method(:mo1).parameters)
+ assert_equal([[:req, :a], [:opt, :b]], method(:mo2).parameters)
+ assert_equal([[:rest, :a]], method(:mo3).parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:block, :c]], method(:mo4).parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:req, :c]], method(:mo5).parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], method(:mo6).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], method(:mo7).parameters)
+ assert_equal([[:req], [:block, :b]], method(:ma1).parameters)
+ end
+
+ def test_unbound_parameters
+ assert_equal([], self.class.instance_method(:m0).parameters)
+ assert_equal([[:req, :a]], self.class.instance_method(:m1).parameters)
+ assert_equal([[:req, :a], [:req, :b]], self.class.instance_method(:m2).parameters)
+ assert_equal([[:opt, :a], [:block, :b]], self.class.instance_method(:mo1).parameters)
+ assert_equal([[:req, :a], [:opt, :b]], self.class.instance_method(:mo2).parameters)
+ assert_equal([[:rest, :a]], self.class.instance_method(:mo3).parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:block, :c]], self.class.instance_method(:mo4).parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:req, :c]], self.class.instance_method(:mo5).parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], self.class.instance_method(:mo6).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], self.class.instance_method(:mo7).parameters)
+ assert_equal([[:req], [:block, :b]], self.class.instance_method(:ma1).parameters)
+ end
+
+ def test_bmethod_bound_parameters
+ assert_equal([], method(:pm0).parameters)
+ assert_equal([[:req, :a]], method(:pm1).parameters)
+ assert_equal([[:req, :a], [:req, :b]], method(:pm2).parameters)
+ assert_equal([[:opt, :a], [:block, :b]], method(:pmo1).parameters)
+ assert_equal([[:req, :a], [:opt, :b]], method(:pmo2).parameters)
+ assert_equal([[:rest, :a]], method(:pmo3).parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:block, :c]], method(:pmo4).parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:req, :c]], method(:pmo5).parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], method(:pmo6).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], method(:pmo7).parameters)
+ assert_equal([[:req], [:block, :b]], method(:pma1).parameters)
+ end
+
+ def test_bmethod_unbound_parameters
+ assert_equal([], self.class.instance_method(:pm0).parameters)
+ assert_equal([[:req, :a]], self.class.instance_method(:pm1).parameters)
+ assert_equal([[:req, :a], [:req, :b]], self.class.instance_method(:pm2).parameters)
+ assert_equal([[:opt, :a], [:block, :b]], self.class.instance_method(:pmo1).parameters)
+ assert_equal([[:req, :a], [:opt, :b]], self.class.instance_method(:pmo2).parameters)
+ assert_equal([[:rest, :a]], self.class.instance_method(:pmo3).parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:block, :c]], self.class.instance_method(:pmo4).parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:req, :c]], self.class.instance_method(:pmo5).parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], self.class.instance_method(:pmo6).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], self.class.instance_method(:pmo7).parameters)
+ assert_equal([[:req], [:block, :b]], self.class.instance_method(:pma1).parameters)
+ end
+
+ def test_public_method_with_zsuper_method
+ c = Class.new
+ c.class_eval do
+ def foo
+ :ok
+ end
+ private :foo
+ end
+ d = Class.new(c)
+ d.class_eval do
+ public :foo
+ end
+ assert_equal(:ok, d.new.public_method(:foo).call)
+ end
+
+ def test_public_methods_with_extended
+ m = Module.new do def m1; end end
+ a = Class.new do def a; end end
+ bug = '[ruby-dev:41553]'
+ obj = a.new
+ assert_equal([:a], obj.public_methods(false), bug)
+ obj.extend(m)
+ assert_equal([:m1, :a], obj.public_methods(false), bug)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_mixed_unicode_escapes.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_mixed_unicode_escapes.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_mixed_unicode_escapes.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,25 @@
+# -*- coding: cp932 -*-
+# This test is in a differnt file than TestUnicodeEscapes
+# So that we can have a different coding comment above
+
+require 'test/unit'
+
+class TestMixedUnicodeEscape < Test::Unit::TestCase
+ def test_basic
+ # Unicode escapes do work in an sjis encoded file, but only
+ # if they don't contain other multi-byte chars
+ assert_equal("A", "\u0041")
+ # 8-bit character escapes are okay.
+ assert_equal("B\xFF", "\u0042\xFF")
+
+ # sjis mb chars mixed with Unicode shound not work
+ assert_raise(SyntaxError) { eval %q("\xE9\x9D\u1234")}
+ assert_raise(SyntaxError) { eval %q("\u{1234}\xE9\x9D")}
+
+ # String interpolation turns into an expression and we get
+ # a different kind of error, but we still can't mix these
+ assert_raise(Encoding::CompatibilityError) { eval %q("\u{1234}#{nil}\xE9\x9D")}
+ assert_raise(Encoding::CompatibilityError) { eval %q("\xE9\x9D#{nil}\u1234")}
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_module.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_module.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_module.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,923 @@
+require 'test/unit'
+require 'pp'
+require_relative 'envutil'
+
+$m0 = Module.nesting
+
+class TestModule < Test::Unit::TestCase
+ def _wrap_assertion
+ yield
+ end
+
+ def assert_method_defined?(klass, mid, message="")
+ message = build_message(message, "#{klass}\##{mid} expected to be defined.")
+ _wrap_assertion do
+ klass.method_defined?(mid) or
+ raise Test::Unit::AssertionFailedError, message, caller(3)
+ end
+ end
+
+ def assert_method_not_defined?(klass, mid, message="")
+ message = build_message(message, "#{klass}\##{mid} expected to not be defined.")
+ _wrap_assertion do
+ klass.method_defined?(mid) and
+ raise Test::Unit::AssertionFailedError, message, caller(3)
+ end
+ end
+
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_LT_0
+ assert_equal true, String < Object
+ assert_equal false, Object < String
+ assert_nil String < Array
+ assert_equal true, Array < Enumerable
+ assert_equal false, Enumerable < Array
+ assert_nil Proc < Comparable
+ assert_nil Comparable < Proc
+ end
+
+ def test_GT_0
+ assert_equal false, String > Object
+ assert_equal true, Object > String
+ assert_nil String > Array
+ assert_equal false, Array > Enumerable
+ assert_equal true, Enumerable > Array
+ assert_nil Comparable > Proc
+ assert_nil Proc > Comparable
+ end
+
+ def test_CMP_0
+ assert_equal(-1, (String <=> Object))
+ assert_equal 1, (Object <=> String)
+ assert_nil(Array <=> String)
+ end
+
+ ExpectedException = NoMethodError
+
+ # Support stuff
+
+ def remove_pp_mixins(list)
+ list.reject {|c| c == PP::ObjectMixin }
+ end
+
+ def remove_json_mixins(list)
+ list.reject {|c| c.to_s.start_with?("JSON") }
+ end
+
+ def remove_rake_mixins(list)
+ list.
+ reject {|c| c.to_s == "RakeFileUtils" }.
+ reject {|c| c.to_s.start_with?("FileUtils") }
+ end
+
+ module Mixin
+ MIXIN = 1
+ def mixin
+ end
+ end
+
+ module User
+ USER = 2
+ include Mixin
+ def user
+ end
+ end
+
+ module Other
+ def other
+ end
+ end
+
+ class AClass
+ def AClass.cm1
+ "cm1"
+ end
+ def AClass.cm2
+ cm1 + "cm2" + cm3
+ end
+ def AClass.cm3
+ "cm3"
+ end
+
+ private_class_method :cm1, "cm3"
+
+ def aClass
+ :aClass
+ end
+
+ def aClass1
+ :aClass1
+ end
+
+ def aClass2
+ :aClass2
+ end
+
+ private :aClass1
+ protected :aClass2
+ end
+
+ class BClass < AClass
+ def bClass1
+ :bClass1
+ end
+
+ private
+
+ def bClass2
+ :bClass2
+ end
+
+ protected
+ def bClass3
+ :bClass3
+ end
+ end
+
+ class CClass < BClass
+ def self.cClass
+ end
+ end
+
+ MyClass = AClass.clone
+ class MyClass
+ public_class_method :cm1
+ end
+
+ # -----------------------------------------------------------
+
+ def test_CMP # '<=>'
+ assert_equal( 0, Mixin <=> Mixin)
+ assert_equal(-1, User <=> Mixin)
+ assert_equal( 1, Mixin <=> User)
+
+ assert_equal( 0, Object <=> Object)
+ assert_equal(-1, String <=> Object)
+ assert_equal( 1, Object <=> String)
+ end
+
+ def test_GE # '>='
+ assert(Mixin >= User)
+ assert(Mixin >= Mixin)
+ assert(!(User >= Mixin))
+
+ assert(Object >= String)
+ assert(String >= String)
+ assert(!(String >= Object))
+ end
+
+ def test_GT # '>'
+ assert(Mixin > User)
+ assert(!(Mixin > Mixin))
+ assert(!(User > Mixin))
+
+ assert(Object > String)
+ assert(!(String > String))
+ assert(!(String > Object))
+ end
+
+ def test_LE # '<='
+ assert(User <= Mixin)
+ assert(Mixin <= Mixin)
+ assert(!(Mixin <= User))
+
+ assert(String <= Object)
+ assert(String <= String)
+ assert(!(Object <= String))
+ end
+
+ def test_LT # '<'
+ assert(User < Mixin)
+ assert(!(Mixin < Mixin))
+ assert(!(Mixin < User))
+
+ assert(String < Object)
+ assert(!(String < String))
+ assert(!(Object < String))
+ end
+
+ def test_VERY_EQUAL # '==='
+ assert(Object === self)
+ assert(Test::Unit::TestCase === self)
+ assert(TestModule === self)
+ assert(!(String === self))
+ end
+
+ def test_ancestors
+ assert_equal([User, Mixin], User.ancestors)
+ assert_equal([Mixin], Mixin.ancestors)
+
+ assert_equal([Object, Kernel, BasicObject],
+ remove_rake_mixins(remove_json_mixins(remove_pp_mixins(Object.ancestors))))
+ assert_equal([String, Comparable, Object, Kernel, BasicObject],
+ remove_rake_mixins(remove_json_mixins(remove_pp_mixins(String.ancestors))))
+ end
+
+ CLASS_EVAL = 2
+ @@class_eval = 'b'
+
+ def test_class_eval
+ Other.class_eval("CLASS_EVAL = 1")
+ assert_equal(1, Other::CLASS_EVAL)
+ assert(Other.constants.include?(:CLASS_EVAL))
+ assert_equal(2, Other.class_eval { CLASS_EVAL })
+
+ Other.class_eval("@@class_eval = 'a'")
+ assert_equal('a', Other.class_variable_get(:@@class_eval))
+ assert_equal('b', Other.class_eval { @@class_eval })
+
+ Other.class_eval do
+ module_function
+
+ def class_eval_test
+ "foo"
+ end
+ end
+ assert_equal("foo", Other.class_eval_test)
+
+ assert_equal([Other], Other.class_eval { |*args| args })
+ end
+
+ def test_const_defined?
+ assert(Math.const_defined?(:PI))
+ assert(Math.const_defined?("PI"))
+ assert(!Math.const_defined?(:IP))
+ assert(!Math.const_defined?("IP"))
+ end
+
+ def test_const_get
+ assert_equal(Math::PI, Math.const_get("PI"))
+ assert_equal(Math::PI, Math.const_get(:PI))
+ end
+
+ def test_const_set
+ assert(!Other.const_defined?(:KOALA))
+ Other.const_set(:KOALA, 99)
+ assert(Other.const_defined?(:KOALA))
+ assert_equal(99, Other::KOALA)
+ Other.const_set("WOMBAT", "Hi")
+ assert_equal("Hi", Other::WOMBAT)
+ end
+
+ def test_constants
+ assert_equal([:MIXIN], Mixin.constants)
+ assert_equal([:MIXIN, :USER], User.constants.sort)
+ end
+
+ def test_included_modules
+ assert_equal([], Mixin.included_modules)
+ assert_equal([Mixin], User.included_modules)
+ assert_equal([Kernel],
+ remove_rake_mixins(remove_json_mixins(remove_pp_mixins(Object.included_modules))))
+ assert_equal([Comparable, Kernel],
+ remove_rake_mixins(remove_json_mixins(remove_pp_mixins(String.included_modules))))
+ end
+
+ def test_instance_methods
+ assert_equal([:user], User.instance_methods(false))
+ assert_equal([:user, :mixin].sort, User.instance_methods(true).sort)
+ assert_equal([:mixin], Mixin.instance_methods)
+ assert_equal([:mixin], Mixin.instance_methods(true))
+ assert_equal([:cClass], (class << CClass; self; end).instance_methods(false))
+ assert_equal([], (class << BClass; self; end).instance_methods(false))
+ assert_equal([:cm2], (class << AClass; self; end).instance_methods(false))
+ # Ruby 1.8 feature change:
+ # #instance_methods includes protected methods.
+ #assert_equal([:aClass], AClass.instance_methods(false))
+ assert_equal([:aClass, :aClass2], AClass.instance_methods(false).sort)
+ assert_equal([:aClass, :aClass2],
+ (AClass.instance_methods(true) - Object.instance_methods(true)).sort)
+ end
+
+ def test_method_defined?
+ assert_method_not_defined?(User, :wombat)
+ assert_method_defined?(User, :user)
+ assert_method_defined?(User, :mixin)
+ assert_method_not_defined?(User, :wombat)
+ assert_method_defined?(User, :user)
+ assert_method_defined?(User, :mixin)
+ end
+
+ def module_exec_aux
+ Proc.new do
+ def dynamically_added_method_3; end
+ end
+ end
+ def module_exec_aux_2(&block)
+ User.module_exec(&block)
+ end
+
+ def test_module_exec
+ User.module_exec do
+ def dynamically_added_method_1; end
+ end
+ assert_method_defined?(User, :dynamically_added_method_1)
+
+ block = Proc.new do
+ def dynamically_added_method_2; end
+ end
+ User.module_exec(&block)
+ assert_method_defined?(User, :dynamically_added_method_2)
+
+ User.module_exec(&module_exec_aux)
+ assert_method_defined?(User, :dynamically_added_method_3)
+
+ module_exec_aux_2 do
+ def dynamically_added_method_4; end
+ end
+ assert_method_defined?(User, :dynamically_added_method_4)
+ end
+
+ def test_module_eval
+ User.module_eval("MODULE_EVAL = 1")
+ assert_equal(1, User::MODULE_EVAL)
+ assert(User.constants.include?(:MODULE_EVAL))
+ User.instance_eval("remove_const(:MODULE_EVAL)")
+ assert(!User.constants.include?(:MODULE_EVAL))
+ end
+
+ def test_name
+ assert_equal("Fixnum", Fixnum.name)
+ assert_equal("TestModule::Mixin", Mixin.name)
+ assert_equal("TestModule::User", User.name)
+ end
+
+ def test_private_class_method
+ assert_raise(ExpectedException) { AClass.cm1 }
+ assert_raise(ExpectedException) { AClass.cm3 }
+ assert_equal("cm1cm2cm3", AClass.cm2)
+ end
+
+ def test_private_instance_methods
+ assert_equal([:aClass1], AClass.private_instance_methods(false))
+ assert_equal([:bClass2], BClass.private_instance_methods(false))
+ assert_equal([:aClass1, :bClass2],
+ (BClass.private_instance_methods(true) -
+ Object.private_instance_methods(true)).sort)
+ end
+
+ def test_protected_instance_methods
+ assert_equal([:aClass2], AClass.protected_instance_methods)
+ assert_equal([:bClass3], BClass.protected_instance_methods(false))
+ assert_equal([:bClass3, :aClass2].sort,
+ (BClass.protected_instance_methods(true) -
+ Object.protected_instance_methods(true)).sort)
+ end
+
+ def test_public_class_method
+ assert_equal("cm1", MyClass.cm1)
+ assert_equal("cm1cm2cm3", MyClass.cm2)
+ assert_raise(ExpectedException) { eval "MyClass.cm3" }
+ end
+
+ def test_public_instance_methods
+ assert_equal([:aClass], AClass.public_instance_methods(false))
+ assert_equal([:bClass1], BClass.public_instance_methods(false))
+ end
+
+ def test_s_constants
+ c1 = Module.constants
+ Object.module_eval "WALTER = 99"
+ c2 = Module.constants
+ assert_equal([:WALTER], c2 - c1)
+
+ assert_equal([], Module.constants(true))
+ assert_equal([], Module.constants(false))
+
+ src = <<-INPUT
+ ary = Module.constants
+ module M
+ WALTER = 99
+ end
+ class Module
+ include M
+ end
+ p Module.constants - ary, Module.constants(true), Module.constants(false)
+ INPUT
+ assert_in_out_err([], src, %w([:M] [:WALTER] []), [])
+ end
+
+ module M1
+ $m1 = Module.nesting
+ module M2
+ $m2 = Module.nesting
+ end
+ end
+
+ def test_s_nesting
+ assert_equal([], $m0)
+ assert_equal([TestModule::M1, TestModule], $m1)
+ assert_equal([TestModule::M1::M2,
+ TestModule::M1, TestModule], $m2)
+ end
+
+ def test_s_new
+ m = Module.new
+ assert_instance_of(Module, m)
+ end
+
+ def test_freeze
+ m = Module.new
+ m.freeze
+ assert_raise(RuntimeError) do
+ m.module_eval do
+ def foo; end
+ end
+ end
+ end
+
+ def test_attr_obsoleted_flag
+ c = Class.new
+ c.class_eval do
+ def initialize
+ @foo = :foo
+ @bar = :bar
+ end
+ attr :foo, true
+ attr :bar, false
+ end
+ o = c.new
+ assert_equal(true, o.respond_to?(:foo))
+ assert_equal(true, o.respond_to?(:foo=))
+ assert_equal(true, o.respond_to?(:bar))
+ assert_equal(false, o.respond_to?(:bar=))
+ end
+
+ def test_const_get2
+ c1 = Class.new
+ c2 = Class.new(c1)
+
+ eval("c1::Foo = :foo")
+ assert_equal(:foo, c1::Foo)
+ assert_equal(:foo, c2::Foo)
+ assert_equal(:foo, c2.const_get(:Foo))
+ assert_raise(NameError) { c2.const_get(:Foo, false) }
+
+ eval("c1::Foo = :foo")
+ assert_raise(NameError) { c1::Bar }
+ assert_raise(NameError) { c2::Bar }
+ assert_raise(NameError) { c2.const_get(:Bar) }
+ assert_raise(NameError) { c2.const_get(:Bar, false) }
+
+ c1.instance_eval do
+ def const_missing(x)
+ x
+ end
+ end
+
+ assert_equal(:Bar, c1::Bar)
+ assert_equal(:Bar, c2::Bar)
+ assert_equal(:Bar, c2.const_get(:Bar))
+ assert_equal(:Bar, c2.const_get(:Bar, false))
+
+ assert_raise(NameError) { c1.const_get(:foo) }
+ end
+
+ def test_const_set2
+ c1 = Class.new
+ assert_raise(NameError) { c1.const_set(:foo, :foo) }
+ end
+
+ def test_const_get3
+ c1 = Class.new
+ assert_raise(NameError) { c1.const_defined?(:foo) }
+ end
+
+ def test_class_variable_get
+ c = Class.new
+ c.class_eval('@@foo = :foo')
+ assert_equal(:foo, c.class_variable_get(:@@foo))
+ assert_raise(NameError) { c.class_variable_get(:@@bar) } # c.f. instance_variable_get
+ assert_raise(NameError) { c.class_variable_get(:foo) }
+ end
+
+ def test_class_variable_set
+ c = Class.new
+ c.class_variable_set(:@@foo, :foo)
+ assert_equal(:foo, c.class_eval('@@foo'))
+ assert_raise(NameError) { c.class_variable_set(:foo, 1) }
+ end
+
+ def test_class_variable_defined
+ c = Class.new
+ c.class_eval('@@foo = :foo')
+ assert_equal(true, c.class_variable_defined?(:@@foo))
+ assert_equal(false, c.class_variable_defined?(:@@bar))
+ assert_raise(NameError) { c.class_variable_defined?(:foo) }
+ end
+
+ def test_remove_class_variable
+ c = Class.new
+ c.class_eval('@@foo = :foo')
+ c.class_eval { remove_class_variable(:@@foo) }
+ assert_equal(false, c.class_variable_defined?(:@@foo))
+ end
+
+ def test_export_method
+ m = Module.new
+ assert_raise(NameError) do
+ m.instance_eval { public(:foo) }
+ end
+ end
+
+ def test_attr
+ assert_in_out_err([], <<-INPUT, %w(:ok nil), /warning: private attribute\?$/)
+ $VERBOSE = true
+ c = Class.new
+ c.instance_eval do
+ private
+ attr_reader :foo
+ end
+ o = c.new
+ o.foo rescue p(:ok)
+ p(o.instance_eval { foo })
+ INPUT
+
+ c = Class.new
+ assert_raise(NameError) do
+ c.instance_eval { attr_reader :"." }
+ end
+ end
+
+ def test_undef
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ Class.instance_eval { undef_method(:foo) }
+ end.join
+ end
+
+ c = Class.new
+ assert_raise(NameError) do
+ c.instance_eval { undef_method(:foo) }
+ end
+
+ m = Module.new
+ assert_raise(NameError) do
+ m.instance_eval { undef_method(:foo) }
+ end
+
+ o = Object.new
+ assert_raise(NameError) do
+ class << o; self; end.instance_eval { undef_method(:foo) }
+ end
+
+ %w(object_id __send__ initialize).each do |n|
+ assert_in_out_err([], <<-INPUT, [], /warning: undefining `#{n}' may cause serious problems$/)
+ $VERBOSE = false
+ Class.new.instance_eval { undef_method(:#{n}) }
+ INPUT
+ end
+ end
+
+ def test_alias
+ m = Module.new
+ assert_raise(NameError) do
+ m.class_eval { alias foo bar }
+ end
+
+ assert_in_out_err([], <<-INPUT, %w(2), /discarding old foo$/)
+ $VERBOSE = true
+ c = Class.new
+ c.class_eval do
+ def foo; 1; end
+ def bar; 2; end
+ end
+ c.class_eval { alias foo bar }
+ p c.new.foo
+ INPUT
+ end
+
+ def test_mod_constants
+ m = Module.new
+ m.const_set(:Foo, :foo)
+ assert_equal([:Foo], m.constants(true))
+ assert_equal([:Foo], m.constants(false))
+ m.instance_eval { remove_const(:Foo) }
+ end
+
+ def test_frozen_class
+ m = Module.new
+ m.freeze
+ assert_raise(RuntimeError) do
+ m.instance_eval { undef_method(:foo) }
+ end
+
+ c = Class.new
+ c.freeze
+ assert_raise(RuntimeError) do
+ c.instance_eval { undef_method(:foo) }
+ end
+
+ o = Object.new
+ c = class << o; self; end
+ c.freeze
+ assert_raise(RuntimeError) do
+ c.instance_eval { undef_method(:foo) }
+ end
+ end
+
+ def test_method_defined
+ c = Class.new
+ c.class_eval do
+ def foo; end
+ def bar; end
+ def baz; end
+ public :foo
+ protected :bar
+ private :baz
+ end
+
+ assert_equal(true, c.public_method_defined?(:foo))
+ assert_equal(false, c.public_method_defined?(:bar))
+ assert_equal(false, c.public_method_defined?(:baz))
+
+ assert_equal(false, c.protected_method_defined?(:foo))
+ assert_equal(true, c.protected_method_defined?(:bar))
+ assert_equal(false, c.protected_method_defined?(:baz))
+
+ assert_equal(false, c.private_method_defined?(:foo))
+ assert_equal(false, c.private_method_defined?(:bar))
+ assert_equal(true, c.private_method_defined?(:baz))
+ end
+
+ def test_change_visibility_under_safe4
+ c = Class.new
+ c.class_eval do
+ def foo; end
+ end
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ c.class_eval { private :foo }
+ end.join
+ end
+ end
+
+ def test_top_public_private
+ assert_in_out_err([], <<-INPUT, %w([:foo] [:bar]), [])
+ private
+ def foo; :foo; end
+ public
+ def bar; :bar; end
+ p self.private_methods.grep(/^foo$|^bar$/)
+ p self.methods.grep(/^foo$|^bar$/)
+ INPUT
+ end
+
+ def test_append_features
+ t = nil
+ m = Module.new
+ m.module_eval do
+ def foo; :foo; end
+ end
+ class << m; self; end.class_eval do
+ define_method(:append_features) do |mod|
+ t = mod
+ super(mod)
+ end
+ end
+
+ m2 = Module.new
+ m2.module_eval { include(m) }
+ assert_equal(m2, t)
+
+ o = Object.new
+ o.extend(m2)
+ assert_equal(true, o.respond_to?(:foo))
+ end
+
+ def test_append_features_raise
+ m = Module.new
+ m.module_eval do
+ def foo; :foo; end
+ end
+ class << m; self; end.class_eval do
+ define_method(:append_features) {|mod| raise }
+ end
+
+ m2 = Module.new
+ assert_raise(RuntimeError) do
+ m2.module_eval { include(m) }
+ end
+
+ o = Object.new
+ o.extend(m2)
+ assert_equal(false, o.respond_to?(:foo))
+ end
+
+ def test_append_features_type_error
+ assert_raise(TypeError) do
+ Module.new.instance_eval { append_features(1) }
+ end
+ end
+
+ def test_included
+ m = Module.new
+ m.module_eval do
+ def foo; :foo; end
+ end
+ class << m; self; end.class_eval do
+ define_method(:included) {|mod| raise }
+ end
+
+ m2 = Module.new
+ assert_raise(RuntimeError) do
+ m2.module_eval { include(m) }
+ end
+
+ o = Object.new
+ o.extend(m2)
+ assert_equal(true, o.respond_to?(:foo))
+ end
+
+ def test_cyclic_include
+ m1 = Module.new
+ m2 = Module.new
+ m1.instance_eval { include(m2) }
+ assert_raise(ArgumentError) do
+ m2.instance_eval { include(m1) }
+ end
+ end
+
+ def test_include_p
+ m = Module.new
+ c1 = Class.new
+ c1.instance_eval { include(m) }
+ c2 = Class.new(c1)
+ assert_equal(true, c1.include?(m))
+ assert_equal(true, c2.include?(m))
+ assert_equal(false, m.include?(m))
+ end
+
+ def test_include_under_safe4
+ m = Module.new
+ c1 = Class.new
+ assert_raise(SecurityError) do
+ lambda {
+ $SAFE = 4
+ c1.instance_eval { include(m) }
+ }.call
+ end
+ assert_nothing_raised do
+ lambda {
+ $SAFE = 4
+ c2 = Class.new
+ c2.instance_eval { include(m) }
+ }.call
+ end
+ end
+
+ def test_send
+ a = AClass.new
+ assert_equal(:aClass, a.__send__(:aClass))
+ assert_equal(:aClass1, a.__send__(:aClass1))
+ assert_equal(:aClass2, a.__send__(:aClass2))
+ b = BClass.new
+ assert_equal(:aClass, b.__send__(:aClass))
+ assert_equal(:aClass1, b.__send__(:aClass1))
+ assert_equal(:aClass2, b.__send__(:aClass2))
+ assert_equal(:bClass1, b.__send__(:bClass1))
+ assert_equal(:bClass2, b.__send__(:bClass2))
+ assert_equal(:bClass3, b.__send__(:bClass3))
+ end
+
+
+ def test_nonascii_name
+ c = eval("class ::C\u{df}; self; end")
+ assert_equal("C\u{df}", c.name, '[ruby-core:24600]')
+ c = eval("class C\u{df}; self; end")
+ assert_equal("TestModule::C\u{df}", c.name, '[ruby-core:24600]')
+ end
+
+ def test_method_added
+ memo = []
+ mod = Module.new do
+ mod = self
+ (class << self ; self ; end).class_eval do
+ define_method :method_added do |sym|
+ memo << sym
+ memo << mod.instance_methods(false)
+ memo << (mod.instance_method(sym) rescue nil)
+ end
+ end
+ def f
+ end
+ alias g f
+ attr_reader :a
+ attr_writer :a
+ end
+ assert_equal :f, memo.shift
+ assert_equal [:f], memo.shift, '[ruby-core:25536]'
+ assert_equal mod.instance_method(:f), memo.shift
+ assert_equal :g, memo.shift
+ assert_equal [:f, :g], memo.shift
+ assert_equal mod.instance_method(:f), memo.shift
+ assert_equal :a, memo.shift
+ assert_equal [:f, :g, :a], memo.shift
+ assert_equal mod.instance_method(:a), memo.shift
+ assert_equal :a=, memo.shift
+ assert_equal [:f, :g, :a, :a=], memo.shift
+ assert_equal mod.instance_method(:a=), memo.shift
+ end
+
+ def test_method_redefinition
+ feature2155 = '[ruby-dev:39400]'
+
+ line = __LINE__+4
+ stderr = EnvUtil.verbose_warning do
+ Module.new do
+ def foo; end
+ def foo; end
+ end
+ end
+ assert_match(/:#{line}: warning: method redefined; discarding old foo/, stderr)
+ assert_match(/:#{line-1}: warning: previous definition of foo/, stderr, feature2155)
+
+ stderr = EnvUtil.verbose_warning do
+ Module.new do
+ def foo; end
+ alias bar foo
+ def foo; end
+ end
+ end
+ assert_equal("", stderr)
+
+ stderr = EnvUtil.verbose_warning do
+ Module.new do
+ def foo; end
+ alias bar foo
+ alias bar foo
+ end
+ end
+ assert_equal("", stderr)
+
+ line = __LINE__+4
+ stderr = EnvUtil.verbose_warning do
+ Module.new do
+ define_method(:foo) do end
+ def foo; end
+ end
+ end
+ assert_match(/:#{line}: warning: method redefined; discarding old foo/, stderr)
+ assert_match(/:#{line-1}: warning: previous definition of foo/, stderr, feature2155)
+
+ stderr = EnvUtil.verbose_warning do
+ Module.new do
+ define_method(:foo) do end
+ alias bar foo
+ alias barf oo
+ end
+ end
+ assert_equal("", stderr)
+
+ stderr = EnvUtil.verbose_warning do
+ Module.new do
+ module_function
+ def foo; end
+ module_function :foo
+ end
+ end
+ assert_equal("", stderr, '[ruby-dev:39397]')
+
+ stderr = EnvUtil.verbose_warning do
+ Module.new do
+ def foo; end
+ undef foo
+ end
+ end
+ assert_equal("", stderr)
+ end
+
+ def test_protected_singleton_method
+ klass = Class.new
+ x = klass.new
+ class << x
+ protected
+
+ def foo
+ end
+ end
+ assert_raise(NoMethodError) do
+ x.foo
+ end
+ klass.send(:define_method, :bar) do
+ x.foo
+ end
+ assert_nothing_raised do
+ x.bar
+ end
+ y = klass.new
+ assert_raise(NoMethodError) do
+ y.bar
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_notimp.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_notimp.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_notimp.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,64 @@
+require 'test/unit'
+require 'tmpdir'
+
+class TestNotImplement < Test::Unit::TestCase
+ def test_respond_to_fork
+ assert_includes(Process.methods, :fork)
+ if /linux/ =~ RUBY_PLATFORM
+ assert_equal(true, Process.respond_to?(:fork))
+ end
+ end
+
+ def test_respond_to_lchmod
+ assert_includes(File.methods, :lchmod)
+ if /linux/ =~ RUBY_PLATFORM
+ assert_equal(false, File.respond_to?(:lchmod))
+ end
+ if /freebsd/ =~ RUBY_PLATFORM
+ assert_equal(true, File.respond_to?(:lchmod))
+ end
+ end
+
+ def test_call_fork
+ if Process.respond_to?(:fork)
+ assert_nothing_raised {
+ pid = fork {}
+ Process.wait pid
+ }
+ end
+ end
+
+ def test_call_lchmod
+ if File.respond_to?(:lchmod)
+ Dir.mktmpdir {|d|
+ f = "#{d}/f"
+ g = "#{d}/g"
+ File.open(f, "w") {}
+ File.symlink f, g
+ newmode = 0444
+ File.lchmod newmode, "#{d}/g"
+ snew = File.lstat(g)
+ assert_equal(newmode, snew.mode & 0777)
+ }
+ end
+ end
+
+ def test_method_inspect_fork
+ m = Process.method(:fork)
+ if Process.respond_to?(:fork)
+ assert_not_match(/not-implemented/, m.inspect)
+ else
+ assert_match(/not-implemented/, m.inspect)
+ end
+ end
+
+ def test_method_inspect_lchmod
+ m = File.method(:lchmod)
+ if File.respond_to?(:lchmod)
+ assert_not_match(/not-implemented/, m.inspect)
+ else
+ assert_match(/not-implemented/, m.inspect)
+ end
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_numeric.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_numeric.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_numeric.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,222 @@
+require 'test/unit'
+
+class TestNumeric < Test::Unit::TestCase
+ class DummyNumeric < Numeric
+ end
+
+ def test_coerce
+ a, b = 1.coerce(2)
+ assert_equal(Fixnum, a.class)
+ assert_equal(Fixnum, b.class)
+
+ a, b = 1.coerce(2.0)
+ assert_equal(Float, a.class)
+ assert_equal(Float, b.class)
+
+ assert_raise(TypeError) { -Numeric.new }
+ end
+
+ def test_dummynumeric
+ a = DummyNumeric.new
+
+ DummyNumeric.class_eval do
+ def coerce(x); nil; end
+ end
+ assert_raise(TypeError) { -a }
+ assert_nil(1 <=> a)
+ assert_raise(ArgumentError) { 1 <= a }
+
+ DummyNumeric.class_eval do
+ def coerce(x); 1.coerce(x); end
+ end
+ assert_equal(2, 1 + a)
+ assert_equal(0, 1 <=> a)
+ assert(1 <= a)
+
+ DummyNumeric.class_eval do
+ def coerce(x); [x, 1]; end
+ end
+ assert_equal(-1, -a)
+
+ ensure
+ DummyNumeric.class_eval do
+ remove_method :coerce
+ end
+ end
+
+ def test_numeric
+ a = Numeric.new
+ assert_raise(TypeError) { def a.foo; end }
+ assert_raise(TypeError) { eval("def a.\u3042; end") }
+ assert_raise(TypeError) { a.dup }
+ end
+
+ def test_quo
+ assert_raise(ArgumentError) {DummyNumeric.new.quo(1)}
+ end
+
+ def test_divmod
+=begin
+ DummyNumeric.class_eval do
+ def /(x); 42.0; end
+ def %(x); :mod; end
+ end
+
+ assert_equal(42, DummyNumeric.new.div(1))
+ assert_equal(:mod, DummyNumeric.new.modulo(1))
+ assert_equal([42, :mod], DummyNumeric.new.divmod(1))
+=end
+
+ assert_kind_of(Integer, 11.divmod(3.5).first, '[ruby-dev:34006]')
+
+=begin
+ ensure
+ DummyNumeric.class_eval do
+ remove_method :/, :%
+ end
+=end
+ end
+
+ def test_real_p
+ assert(Numeric.new.real?)
+ end
+
+ def test_integer_p
+ assert(!Numeric.new.integer?)
+ end
+
+ def test_abs
+ a = DummyNumeric.new
+ DummyNumeric.class_eval do
+ def -@; :ok; end
+ def <(x); true; end
+ end
+
+ assert_equal(:ok, a.abs)
+
+ DummyNumeric.class_eval do
+ def <(x); false; end
+ end
+
+ assert_equal(a, a.abs)
+
+ ensure
+ DummyNumeric.class_eval do
+ remove_method :-@, :<
+ end
+ end
+
+ def test_zero_p
+ DummyNumeric.class_eval do
+ def ==(x); true; end
+ end
+
+ assert(DummyNumeric.new.zero?)
+
+ ensure
+ DummyNumeric.class_eval do
+ remove_method :==
+ end
+ end
+
+ def test_to_int
+ DummyNumeric.class_eval do
+ def to_i; :ok; end
+ end
+
+ assert_equal(:ok, DummyNumeric.new.to_int)
+
+ ensure
+ DummyNumeric.class_eval do
+ remove_method :to_i
+ end
+ end
+
+ def test_cmp
+ a = Numeric.new
+ assert_equal(0, a <=> a)
+ assert_nil(a <=> :foo)
+ end
+
+ def test_floor_ceil_round_truncate
+ DummyNumeric.class_eval do
+ def to_f; 1.5; end
+ end
+
+ a = DummyNumeric.new
+ assert_equal(1, a.floor)
+ assert_equal(2, a.ceil)
+ assert_equal(2, a.round)
+ assert_equal(1, a.truncate)
+
+ DummyNumeric.class_eval do
+ def to_f; 1.4; end
+ end
+
+ a = DummyNumeric.new
+ assert_equal(1, a.floor)
+ assert_equal(2, a.ceil)
+ assert_equal(1, a.round)
+ assert_equal(1, a.truncate)
+
+ DummyNumeric.class_eval do
+ def to_f; -1.5; end
+ end
+
+ a = DummyNumeric.new
+ assert_equal(-2, a.floor)
+ assert_equal(-1, a.ceil)
+ assert_equal(-2, a.round)
+ assert_equal(-1, a.truncate)
+
+ ensure
+ DummyNumeric.class_eval do
+ remove_method :to_f
+ end
+ end
+
+ def test_step
+ a = []
+ 1.step(10) {|x| a << x }
+ assert_equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a)
+
+ a = []
+ 1.step(10, 2) {|x| a << x }
+ assert_equal([1, 3, 5, 7, 9], a)
+
+ assert_raise(ArgumentError) { 1.step(10, 1, 0) { } }
+ assert_raise(ArgumentError) { 1.step(10, 0) { } }
+
+ a = []
+ 10.step(1, -2) {|x| a << x }
+ assert_equal([10, 8, 6, 4, 2], a)
+
+ a = []
+ 1.0.step(10.0, 2.0) {|x| a << x }
+ assert_equal([1.0, 3.0, 5.0, 7.0, 9.0], a)
+
+ a = []
+ 1.step(10, 2**32) {|x| a << x }
+ assert_equal([1], a)
+
+ a = []
+ 10.step(1, -(2**32)) {|x| a << x }
+ assert_equal([10], a)
+ end
+
+ def test_num2long
+ assert_raise(TypeError) { 1 & nil }
+ assert_raise(TypeError) { 1 & 1.0 }
+ assert_raise(TypeError) { 1 & 2147483648.0 }
+ assert_raise(TypeError) { 1 & 9223372036854777856.0 }
+ o = Object.new
+ def o.to_int; 1; end
+ assert_equal(1, 1 & o)
+ end
+
+ def test_eql
+ assert(1 == 1.0)
+ assert(!(1.eql?(1.0)))
+ assert(!(1.eql?(2)))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_object.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_object.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_object.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,595 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestObject < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_dup
+ assert_raise(TypeError) { 1.dup }
+ assert_raise(TypeError) { true.dup }
+ assert_raise(TypeError) { nil.dup }
+
+ assert_raise(TypeError) do
+ Object.new.instance_eval { initialize_copy(1) }
+ end
+ end
+
+ def test_instance_of
+ assert_raise(TypeError) { 1.instance_of?(1) }
+ end
+
+ def test_kind_of
+ assert_raise(TypeError) { 1.kind_of?(1) }
+ end
+
+ def test_taint_frozen_obj
+ o = Object.new
+ o.freeze
+ assert_raise(RuntimeError) { o.taint }
+
+ o = Object.new
+ o.taint
+ o.freeze
+ assert_raise(RuntimeError) { o.untaint }
+ end
+
+ def test_freeze_under_safe_4
+ skip("[BUG : #842] SecurityError Level 4")
+
+ o = Object.new
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ o.freeze
+ end.join
+ end
+ end
+
+ def test_freeze_immediate
+ assert_equal(false, 1.frozen?)
+ 1.freeze
+ assert_equal(true, 1.frozen?)
+ assert_equal(false, 2.frozen?)
+ end
+
+ def test_nil_to_f
+ assert_equal(0.0, nil.to_f)
+ end
+
+ def test_not
+ assert_equal(false, Object.new.send(:!))
+ assert_equal(true, nil.send(:!))
+ end
+
+ def test_true_and
+ assert_equal(true, true & true)
+ assert_equal(true, true & 1)
+ assert_equal(false, true & false)
+ assert_equal(false, true & nil)
+ end
+
+ def test_true_or
+ assert_equal(true, true | true)
+ assert_equal(true, true | 1)
+ assert_equal(true, true | false)
+ assert_equal(true, true | nil)
+ end
+
+ def test_true_xor
+ assert_equal(false, true ^ true)
+ assert_equal(false, true ^ 1)
+ assert_equal(true, true ^ false)
+ assert_equal(true, true ^ nil)
+ end
+
+ def test_false_and
+ assert_equal(false, false & true)
+ assert_equal(false, false & 1)
+ assert_equal(false, false & false)
+ assert_equal(false, false & nil)
+ end
+
+ def test_false_or
+ assert_equal(true, false | true)
+ assert_equal(true, false | 1)
+ assert_equal(false, false | false)
+ assert_equal(false, false | nil)
+ end
+
+ def test_false_xor
+ assert_equal(true, false ^ true)
+ assert_equal(true, false ^ 1)
+ assert_equal(false, false ^ false)
+ assert_equal(false, false ^ nil)
+ end
+
+ def test_methods
+ o = Object.new
+ a1 = o.methods
+ a2 = o.methods(false)
+
+ def o.foo; end
+
+ assert_equal([:foo], o.methods(true) - a1)
+ assert_equal([:foo], o.methods(false) - a2)
+ end
+
+ def test_methods2
+ c0 = Class.new
+ c1 = Class.new(c0)
+ c1.module_eval do
+ public ; def foo; end
+ protected; def bar; end
+ private ; def baz; end
+ end
+ c2 = Class.new(c1)
+ c2.module_eval do
+ public ; def foo2; end
+ protected; def bar2; end
+ private ; def baz2; end
+ end
+
+ o0 = c0.new
+ o2 = c2.new
+
+ assert_equal([:baz, :baz2], (o2.private_methods - o0.private_methods).sort)
+ assert_equal([:baz2], (o2.private_methods(false) - o0.private_methods(false)).sort)
+
+ assert_equal([:bar, :bar2], (o2.protected_methods - o0.protected_methods).sort)
+ assert_equal([:bar2], (o2.protected_methods(false) - o0.protected_methods(false)).sort)
+
+ assert_equal([:foo, :foo2], (o2.public_methods - o0.public_methods).sort)
+ assert_equal([:foo2], (o2.public_methods(false) - o0.public_methods(false)).sort)
+ end
+
+ def test_instance_variable_get
+ o = Object.new
+ o.instance_eval { @foo = :foo }
+ assert_equal(:foo, o.instance_variable_get(:@foo))
+ assert_equal(nil, o.instance_variable_get(:@bar))
+ assert_raise(NameError) { o.instance_variable_get(:foo) }
+ end
+
+ def test_instance_variable_set
+ o = Object.new
+ o.instance_variable_set(:@foo, :foo)
+ assert_equal(:foo, o.instance_eval { @foo })
+ assert_raise(NameError) { o.instance_variable_set(:foo, 1) }
+ end
+
+ def test_instance_variable_defined
+ o = Object.new
+ o.instance_eval { @foo = :foo }
+ assert_equal(true, o.instance_variable_defined?(:@foo))
+ assert_equal(false, o.instance_variable_defined?(:@bar))
+ assert_raise(NameError) { o.instance_variable_defined?(:foo) }
+ end
+
+ def test_remove_instance_variable
+ o = Object.new
+ o.instance_eval { @foo = :foo }
+ o.instance_eval { remove_instance_variable(:@foo) }
+ assert_equal(false, o.instance_variable_defined?(:@foo))
+ end
+
+ def test_convert_type
+ o = Object.new
+ def o.to_s; 1; end
+ assert_raise(TypeError) { String(o) }
+ end
+
+ def test_check_convert_type
+ o = Object.new
+ def o.to_a; 1; end
+ assert_raise(TypeError) { Array(o) }
+ end
+
+ def test_to_integer
+ o = Object.new
+ def o.to_i; nil; end
+ assert_raise(TypeError) { Integer(o) }
+ end
+
+ class MyInteger
+ def initialize(n); @num = n; end
+ def to_int; @num; end
+ def <=>(n); @num <=> n.to_int; end
+ def <=(n); @num <= n.to_int; end
+ def +(n); MyInteger.new(@num + n.to_int); end
+ end
+
+ def test_check_to_integer
+ o1 = MyInteger.new(1)
+ o9 = MyInteger.new(9)
+ n = 0
+ Range.new(o1, o9).step(2) {|x| n += x.to_int }
+ assert_equal(1+3+5+7+9, n)
+ end
+
+ def test_add_method_under_safe4
+ skip("[BUG : #842] SecurityError Level 4")
+
+ o = Object.new
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ def o.foo
+ end
+ end.join
+ end
+ end
+
+ def test_redefine_method_under_verbose
+ assert_in_out_err([], <<-INPUT, %w(2), /warning: method redefined; discarding old foo$/)
+ $VERBOSE = true
+ o = Object.new
+ def o.foo; 1; end
+ def o.foo; 2; end
+ p o.foo
+ INPUT
+ end
+
+ def test_redefine_method_which_may_case_serious_problem
+ assert_in_out_err([], <<-INPUT, [], /warning: redefining `object_id' may cause serious problems$/)
+ $VERBOSE = false
+ def (Object.new).object_id; end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, [], /warning: redefining `__send__' may cause serious problems$/)
+ $VERBOSE = false
+ def (Object.new).__send__; end
+ INPUT
+ end
+
+ def test_remove_method
+ skip("[BUG : #842] SecurityError Level 4")
+
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ Object.instance_eval { remove_method(:foo) }
+ end.join
+ end
+
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ Class.instance_eval { remove_method(:foo) }
+ end.join
+ end
+
+ c = Class.new
+ c.freeze
+ assert_raise(RuntimeError) do
+ c.instance_eval { remove_method(:foo) }
+ end
+
+ c = Class.new do
+ def meth1; "meth" end
+ end
+ d = Class.new(c) do
+ alias meth2 meth1
+ end
+ o1 = c.new
+ assert_respond_to(o1, :meth1)
+ assert_equal("meth", o1.meth1)
+ o2 = d.new
+ assert_respond_to(o2, :meth1)
+ assert_equal("meth", o2.meth1)
+ assert_respond_to(o2, :meth2)
+ assert_equal("meth", o2.meth2)
+ d.class_eval do
+ remove_method :meth2
+ end
+ bug2202 = '[ruby-core:26074]'
+ assert_raise(NoMethodError, bug2202) {o2.meth2}
+
+ %w(object_id __send__ initialize).each do |m|
+ assert_in_out_err([], <<-INPUT, %w(:ok), /warning: removing `#{m}' may cause serious problems$/)
+ $VERBOSE = false
+ begin
+ Class.new.instance_eval { remove_method(:#{m}) }
+ rescue NameError
+ p :ok
+ end
+ INPUT
+ end
+ end
+
+ def test_method_missing
+ assert_raise(ArgumentError) do
+ 1.instance_eval { method_missing }
+ end
+
+ c = Class.new
+ c.class_eval do
+ protected
+ def foo; end
+ end
+ assert_raise(NoMethodError) do
+ c.new.foo
+ end
+
+ assert_raise(NoMethodError) do
+ 1.instance_eval { method_missing(:method_missing) }
+ end
+
+ c.class_eval do
+ undef_method(:method_missing)
+ end
+
+ assert_raise(ArgumentError) do
+ c.new.method_missing
+ end
+
+ bug2494 = '[ruby-core:27219]'
+ c = Class.new do
+ def method_missing(meth, *args)
+ super
+ end
+ end
+ b = c.new
+ foo rescue nil
+ assert_nothing_raised(bug2494) {[b].flatten}
+ end
+
+ def test_respond_to_missing
+ c = Class.new do
+ def respond_to_missing?(id, priv=false)
+ if id == :foobar
+ true
+ else
+ false
+ end
+ end
+ def method_missing(id,*args)
+ if id == :foobar
+ return [:foo, *args]
+ else
+ super
+ end
+ end
+ end
+
+ foo = c.new
+ assert_equal([:foo], foo.foobar);
+ assert_equal([:foo, 1], foo.foobar(1));
+ assert_equal([:foo, 1, 2, 3, 4, 5], foo.foobar(1, 2, 3, 4, 5));
+ assert(foo.respond_to?(:foobar))
+ assert_equal(false, foo.respond_to?(:foobarbaz))
+ assert_raise(NoMethodError) do
+ foo.foobarbaz
+ end
+
+ foobar = foo.method(:foobar)
+ assert_equal(-1, foobar.arity);
+ assert_equal([:foo], foobar.call);
+ assert_equal([:foo, 1], foobar.call(1));
+ assert_equal([:foo, 1, 2, 3, 4, 5], foobar.call(1, 2, 3, 4, 5));
+ assert_equal(foobar, foo.method(:foobar))
+ assert_not_equal(foobar, c.new.method(:foobar))
+
+ c = Class.new(c)
+ assert_equal(false, c.method_defined?(:foobar))
+ assert_raise(NameError, '[ruby-core:25748]') do
+ c.instance_method(:foobar)
+ end
+
+ m = Module.new
+ assert_equal(false, m.method_defined?(:foobar))
+ assert_raise(NameError, '[ruby-core:25748]') do
+ m.instance_method(:foobar)
+ end
+ end
+
+ def test_send_with_no_arguments
+ assert_raise(ArgumentError) { 1.send }
+ end
+
+ def test_no_superclass_method
+ bug2312 = '[ruby-dev:39581]'
+
+ o = Object.new
+ e = assert_raise(NoMethodError) {
+ o.method(:__send__).call(:never_defined_test_no_superclass_method)
+ }
+ m1 = e.message
+ assert_no_match(/no superclass method/, m1, bug2312)
+ e = assert_raise(NoMethodError) {
+ o.method(:__send__).call(:never_defined_test_no_superclass_method)
+ }
+ assert_equal(m1, e.message, bug2312)
+ e = assert_raise(NoMethodError) {
+ o.never_defined_test_no_superclass_method
+ }
+ assert_equal(m1, e.message, bug2312)
+ end
+
+ def test_superclass_method
+ bug2312 = '[ruby-dev:39581]'
+ assert_in_out_err(["-e", "module Enumerable;undef min;end; (1..2).min{}"],
+ "", [], /no superclass method/, bug2312)
+ end
+
+ def test_specific_eval_with_wrong_arguments
+ assert_raise(ArgumentError) do
+ 1.instance_eval("foo") { foo }
+ end
+
+ assert_raise(ArgumentError) do
+ 1.instance_eval
+ end
+
+ assert_raise(ArgumentError) do
+ 1.instance_eval("", 1, 1, 1)
+ end
+ end
+
+ class InstanceExec
+ INSTANCE_EXEC = 123
+ end
+
+ def test_instance_exec
+ x = 1.instance_exec(42) {|a| self + a }
+ assert_equal(43, x)
+
+ x = "foo".instance_exec("bar") {|a| self + a }
+ assert_equal("foobar", x)
+
+ assert_raise(NameError) do
+ InstanceExec.new.instance_exec { INSTANCE_EXEC }
+ end
+ end
+
+ def test_extend
+ assert_raise(ArgumentError) do
+ 1.extend
+ end
+ end
+
+ def test_untrusted
+ skip("[BUG : #842] SecurityError Level 4")
+
+ obj = lambda {
+ $SAFE = 4
+ x = Object.new
+ x.instance_eval { @foo = 1 }
+ x
+ }.call
+ assert_equal(true, obj.untrusted?)
+ assert_equal(true, obj.tainted?)
+
+ x = Object.new
+ assert_equal(false, x.untrusted?)
+ assert_raise(SecurityError) do
+ lambda {
+ $SAFE = 4
+ x.instance_eval { @foo = 1 }
+ }.call
+ end
+
+ x = Object.new
+ x.taint
+ assert_raise(SecurityError) do
+ lambda {
+ $SAFE = 4
+ x.instance_eval { @foo = 1 }
+ }.call
+ end
+
+ x.untrust
+ assert_equal(true, x.untrusted?)
+ assert_nothing_raised do
+ lambda {
+ $SAFE = 4
+ x.instance_eval { @foo = 1 }
+ }.call
+ end
+
+ x.trust
+ assert_equal(false, x.untrusted?)
+ assert_raise(SecurityError) do
+ lambda {
+ $SAFE = 4
+ x.instance_eval { @foo = 1 }
+ }.call
+ end
+
+ a = Object.new
+ a.untrust
+ assert_equal(true, a.untrusted?)
+ b = a.dup
+ assert_equal(true, b.untrusted?)
+ c = a.clone
+ assert_equal(true, c.untrusted?)
+
+ a = Object.new
+ b = lambda {
+ $SAFE = 4
+ a.dup
+ }.call
+ assert_equal(true, b.untrusted?)
+
+ a = Object.new
+ b = lambda {
+ $SAFE = 4
+ a.clone
+ }.call
+ assert_equal(true, b.untrusted?)
+ end
+
+ def test_to_s
+ x = Object.new
+ x.taint
+ x.untrust
+ s = x.to_s
+ assert_equal(true, s.untrusted?)
+ assert_equal(true, s.tainted?)
+ end
+
+ def test_exec_recursive
+ skip("[BUG : #842] SecurityError Level 4")
+
+ Thread.current[:__recursive_key__] = nil
+ a = [[]]
+ a.inspect
+
+ assert_nothing_raised do
+ -> do
+ $SAFE = 4
+ begin
+ a.hash
+ rescue ArgumentError
+ end
+ end.call
+ end
+
+ -> do
+ assert_nothing_raised do
+ $SAFE = 4
+ a.inspect
+ end
+ end.call
+
+ -> do
+ o = Object.new
+ def o.to_ary(x); end
+ def o.==(x); $SAFE = 4; false; end
+ a = [[o]]
+ b = []
+ b << b
+
+ assert_nothing_raised do
+ b == a
+ end
+ end.call
+ end
+
+ def test_singleton_class
+ x = Object.new
+ xs = class << x; self; end
+ assert_equal(xs, x.singleton_class)
+
+ y = Object.new
+ ys = y.singleton_class
+ assert_equal(class << y; self; end, ys)
+
+ assert_equal(NilClass, nil.singleton_class)
+ assert_equal(TrueClass, true.singleton_class)
+ assert_equal(FalseClass, false.singleton_class)
+
+ assert_raise(TypeError) do
+ 123.singleton_class
+ end
+ assert_raise(TypeError) do
+ :foo.singleton_class
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_objectspace.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_objectspace.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_objectspace.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,67 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestObjectSpace < Test::Unit::TestCase
+ def self.deftest_id2ref(obj)
+ /:(\d+)/ =~ caller[0]
+ file = $`
+ line = $1.to_i
+ code = <<"End"
+ define_method("test_id2ref_#{line}") {\
+ o = ObjectSpace._id2ref(obj.object_id);\
+ assert_same(obj, o, "didn't round trip: \#{obj.inspect}");\
+ }
+End
+ eval code, binding, file, line
+ end
+
+ deftest_id2ref(-0x4000000000000001)
+ deftest_id2ref(-0x4000000000000000)
+ deftest_id2ref(-0x40000001)
+ deftest_id2ref(-0x40000000)
+ deftest_id2ref(-1)
+ deftest_id2ref(0)
+ deftest_id2ref(1)
+ deftest_id2ref(0x3fffffff)
+ deftest_id2ref(0x40000000)
+ deftest_id2ref(0x3fffffffffffffff)
+ deftest_id2ref(0x4000000000000000)
+ deftest_id2ref(:a)
+ deftest_id2ref(:abcdefghijilkjl)
+ deftest_id2ref(:==)
+ deftest_id2ref(Object.new)
+ deftest_id2ref(self)
+ deftest_id2ref(true)
+ deftest_id2ref(false)
+ deftest_id2ref(nil)
+
+ def test_count_objects
+ h = {}
+ ObjectSpace.count_objects(h)
+ assert_kind_of(Hash, h)
+ assert(h.keys.all? {|x| x.is_a?(Symbol) || x.is_a?(Integer) })
+ assert(h.values.all? {|x| x.is_a?(Integer) })
+
+ h = ObjectSpace.count_objects
+ assert_kind_of(Hash, h)
+ assert(h.keys.all? {|x| x.is_a?(Symbol) || x.is_a?(Integer) })
+ assert(h.values.all? {|x| x.is_a?(Integer) })
+
+ assert_raise(TypeError) { ObjectSpace.count_objects(1) }
+
+ h0 = {:T_FOO=>1000}
+ h = ObjectSpace.count_objects(h0)
+ assert_same(h0, h)
+ assert_equal(0, h0[:T_FOO])
+ end
+
+ def test_finalizer
+ assert_in_out_err(["-e", <<-END], "", %w(:ok :ok :ok :ok), [])
+ a = []
+ ObjectSpace.define_finalizer(a) { p :ok }
+ b = a.dup
+ ObjectSpace.define_finalizer(a) { p :ok }
+ END
+ assert_raise(ArgumentError) { ObjectSpace.define_finalizer([], Object.new) }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_optimization.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_optimization.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_optimization.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,140 @@
+require 'test/unit'
+
+class TestRubyOptimization < Test::Unit::TestCase
+
+ BIGNUM_POS_MIN_32 = 1073741824 # 2 ** 30
+ if BIGNUM_POS_MIN_32.kind_of?(Fixnum)
+ FIXNUM_MAX = 4611686018427387903 # 2 ** 62 - 1
+ else
+ FIXNUM_MAX = 1073741823 # 2 ** 30 - 1
+ end
+
+ BIGNUM_NEG_MAX_32 = -1073741825 # -2 ** 30 - 1
+ if BIGNUM_NEG_MAX_32.kind_of?(Fixnum)
+ FIXNUM_MIN = -4611686018427387904 # -2 ** 62
+ else
+ FIXNUM_MIN = -1073741824 # -2 ** 30
+ end
+
+ def redefine_method(klass, method)
+ (@redefine_method_seq ||= 0)
+ seq = (@redefine_method_seq += 1)
+ eval(<<-End, ::TOPLEVEL_BINDING)
+ class #{klass}
+ alias redefine_method_orig_#{seq} #{method}
+ undef #{method}
+ def #{method}(*args)
+ args[0]
+ end
+ end
+ End
+ begin
+ return yield
+ ensure
+ eval(<<-End, ::TOPLEVEL_BINDING)
+ class #{klass}
+ undef #{method}
+ alias #{method} redefine_method_orig_#{seq}
+ end
+ End
+ end
+ end
+
+ def test_fixnum_plus
+ a, b = 1, 2
+ assert_equal 3, a + b
+ assert_instance_of Fixnum, FIXNUM_MAX
+ assert_instance_of Bignum, FIXNUM_MAX + 1
+
+ assert_equal 21, 10 + 11
+ assert_equal 11, redefine_method('Fixnum', '+') { 10 + 11 }
+ assert_equal 21, 10 + 11
+ end
+
+ def test_fixnum_minus
+ assert_equal 5, 8 - 3
+ assert_instance_of Fixnum, FIXNUM_MIN
+ assert_instance_of Bignum, FIXNUM_MIN - 1
+
+ assert_equal 5, 8 - 3
+ assert_equal 3, redefine_method('Fixnum', '-') { 8 - 3 }
+ assert_equal 5, 8 - 3
+ end
+
+ def test_fixnum_mul
+ assert_equal 15, 3 * 5
+ end
+
+ def test_fixnum_div
+ assert_equal 3, 15 / 5
+ end
+
+ def test_fixnum_mod
+ assert_equal 1, 8 % 7
+ end
+
+ def test_float_plus
+ assert_equal 4.0, 2.0 + 2.0
+ assert_equal 2.0, redefine_method('Float', '+') { 2.0 + 2.0 }
+ assert_equal 4.0, 2.0 + 2.0
+ end
+
+ def test_string_length
+ assert_equal 6, "string".length
+ assert_nil redefine_method('String', 'length') { "string".length }
+ assert_equal 6, "string".length
+ end
+
+ def test_string_plus
+ assert_equal "", "" + ""
+ assert_equal "x", "x" + ""
+ assert_equal "x", "" + "x"
+ assert_equal "ab", "a" + "b"
+ assert_equal 'b', redefine_method('String', '+') { "a" + "b" }
+ assert_equal "ab", "a" + "b"
+ end
+
+ def test_string_succ
+ assert_equal 'b', 'a'.succ
+ assert_equal 'B', 'A'.succ
+ end
+
+ def test_string_format
+ assert_equal '2', '%d' % 2
+ end
+
+ def test_array_plus
+ assert_equal [1,2], [1]+[2]
+ end
+
+ def test_array_minus
+ assert_equal [2], [1,2] - [1]
+ end
+
+ def test_array_length
+ assert_equal 0, [].length
+ assert_equal 3, [1,2,3].length
+ end
+
+ def test_hash_length
+ assert_equal 0, {}.length
+ assert_equal 1, {1=>1}.length
+ end
+
+ class MyObj
+ def ==(other)
+ true
+ end
+ end
+
+ def test_eq
+ assert_equal true, nil == nil
+ assert_equal true, 1 == 1
+ assert_equal true, 'string' == 'string'
+ assert_equal true, 1 == MyObj.new
+ assert_equal false, nil == MyObj.new
+ assert_equal true, MyObj.new == 1
+ assert_equal true, MyObj.new == nil
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_pack.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_pack.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_pack.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,618 @@
+require 'test/unit'
+
+class TestPack < Test::Unit::TestCase
+ def test_pack
+ $format = "c2x5CCxsdils_l_a6";
+ # Need the expression in here to force ary[5] to be numeric. This avoids
+ # test2 failing because ary2 goes str->numeric->str and ary does not.
+ ary = [1,-100,127,128,32767,987.654321098 / 100.0,12345,123456,-32767,-123456,"abcdef"]
+ $x = ary.pack($format)
+ ary2 = $x.unpack($format)
+
+ assert_equal(ary.length, ary2.length)
+ assert_equal(ary.join(':'), ary2.join(':'))
+ assert_match(/def/, $x)
+
+ $x = [-1073741825]
+ assert_equal($x, $x.pack("q").unpack("q"))
+
+ $x = [-1]
+ assert_equal($x, $x.pack("l").unpack("l"))
+ end
+
+ def test_pack_n
+ assert_equal "\000\000", [0].pack('n')
+ assert_equal "\000\001", [1].pack('n')
+ assert_equal "\000\002", [2].pack('n')
+ assert_equal "\000\003", [3].pack('n')
+ assert_equal "\377\376", [65534].pack('n')
+ assert_equal "\377\377", [65535].pack('n')
+
+ assert_equal "\200\000", [2**15].pack('n')
+ assert_equal "\177\377", [-2**15-1].pack('n')
+ assert_equal "\377\377", [-1].pack('n')
+
+ assert_equal "\000\001\000\001", [1,1].pack('n*')
+ assert_equal "\000\001\000\001\000\001", [1,1,1].pack('n*')
+ end
+
+ def test_unpack_n
+ assert_equal 1, "\000\001".unpack('n')[0]
+ assert_equal 2, "\000\002".unpack('n')[0]
+ assert_equal 3, "\000\003".unpack('n')[0]
+ assert_equal 65535, "\377\377".unpack('n')[0]
+ assert_equal [1,1], "\000\001\000\001".unpack('n*')
+ assert_equal [1,1,1], "\000\001\000\001\000\001".unpack('n*')
+ end
+
+ def test_pack_N
+ assert_equal "\000\000\000\000", [0].pack('N')
+ assert_equal "\000\000\000\001", [1].pack('N')
+ assert_equal "\000\000\000\002", [2].pack('N')
+ assert_equal "\000\000\000\003", [3].pack('N')
+ assert_equal "\377\377\377\376", [4294967294].pack('N')
+ assert_equal "\377\377\377\377", [4294967295].pack('N')
+
+ assert_equal "\200\000\000\000", [2**31].pack('N')
+ assert_equal "\177\377\377\377", [-2**31-1].pack('N')
+ assert_equal "\377\377\377\377", [-1].pack('N')
+
+ assert_equal "\000\000\000\001\000\000\000\001", [1,1].pack('N*')
+ assert_equal "\000\000\000\001\000\000\000\001\000\000\000\001", [1,1,1].pack('N*')
+ end
+
+ def test_unpack_N
+ assert_equal 1, "\000\000\000\001".unpack('N')[0]
+ assert_equal 2, "\000\000\000\002".unpack('N')[0]
+ assert_equal 3, "\000\000\000\003".unpack('N')[0]
+ assert_equal 4294967295, "\377\377\377\377".unpack('N')[0]
+ assert_equal [1,1], "\000\000\000\001\000\000\000\001".unpack('N*')
+ assert_equal [1,1,1], "\000\000\000\001\000\000\000\001\000\000\000\001".unpack('N*')
+ end
+
+ def test_integer_endian
+ s = [1].pack("s")
+ assert_includes(["\0\1", "\1\0"], s)
+ if s == "\0\1"
+ # big endian
+ assert_equal("\x01\x02", [0x0102].pack("s"))
+ assert_equal("\x01\x02", [0x0102].pack("S"))
+ assert_equal("\x01\x02\x03\x04", [0x01020304].pack("l"))
+ assert_equal("\x01\x02\x03\x04", [0x01020304].pack("L"))
+ assert_equal("\x01\x02\x03\x04\x05\x06\x07\x08", [0x0102030405060708].pack("q"))
+ assert_equal("\x01\x02\x03\x04\x05\x06\x07\x08", [0x0102030405060708].pack("Q"))
+ assert_match(/\A\x00*\x01\x02\z/, [0x0102].pack("s!"))
+ assert_match(/\A\x00*\x01\x02\z/, [0x0102].pack("S!"))
+ assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("i"))
+ assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("I"))
+ assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("i!"))
+ assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("I!"))
+ assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("l!"))
+ assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("L!"))
+ %w[s S l L q Q s! S! i I i! I! l! L!].each {|fmt|
+ nuls = [0].pack(fmt)
+ v = 0
+ s = "".force_encoding("ascii-8bit")
+ nuls.bytesize.times {|i|
+ j = i + 40
+ v = v * 256 + j
+ s << [j].pack("C")
+ }
+ assert_equal(s, [v].pack(fmt), "[#{v}].pack(#{fmt.dump})")
+ assert_equal([v], s.unpack(fmt), "#{s.dump}.unpack(#{fmt.dump})")
+ s2 = s+s
+ fmt2 = fmt+"*"
+ assert_equal([v,v], s2.unpack(fmt2), "#{s2.dump}.unpack(#{fmt2.dump})")
+ }
+ else
+ # little endian
+ assert_equal("\x02\x01", [0x0102].pack("s"))
+ assert_equal("\x02\x01", [0x0102].pack("S"))
+ assert_equal("\x04\x03\x02\x01", [0x01020304].pack("l"))
+ assert_equal("\x04\x03\x02\x01", [0x01020304].pack("L"))
+ assert_equal("\x08\x07\x06\x05\x04\x03\x02\x01", [0x0102030405060708].pack("q"))
+ assert_equal("\x08\x07\x06\x05\x04\x03\x02\x01", [0x0102030405060708].pack("Q"))
+ assert_match(/\A\x02\x01\x00*\z/, [0x0102].pack("s!"))
+ assert_match(/\A\x02\x01\x00*\z/, [0x0102].pack("S!"))
+ assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("i"))
+ assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("I"))
+ assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("i!"))
+ assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("I!"))
+ assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("l!"))
+ assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("L!"))
+ %w[s S l L q Q s! S! i I i! I! l! L!].each {|fmt|
+ nuls = [0].pack(fmt)
+ v = 0
+ s = "".force_encoding("ascii-8bit")
+ nuls.bytesize.times {|i|
+ j = i+40
+ v = v * 256 + j
+ s << [j].pack("C")
+ }
+ s.reverse!
+ assert_equal(s, [v].pack(fmt), "[#{v}].pack(#{fmt.dump})")
+ assert_equal([v], s.unpack(fmt), "#{s.dump}.unpack(#{fmt.dump})")
+ s2 = s+s
+ fmt2 = fmt+"*"
+ assert_equal([v,v], s2.unpack(fmt2), "#{s2.dump}.unpack(#{fmt2.dump})")
+ }
+ end
+ end
+
+ def test_pack_U
+ assert_raise(RangeError) { [-0x40000001].pack("U") }
+ assert_raise(RangeError) { [-0x40000000].pack("U") }
+ assert_raise(RangeError) { [-1].pack("U") }
+ assert_equal "\000", [0].pack("U")
+ assert_equal "\374\277\277\277\277\277".force_encoding(Encoding::UTF_8), [0x3fffffff].pack("U")
+ assert_equal "\375\200\200\200\200\200".force_encoding(Encoding::UTF_8), [0x40000000].pack("U")
+ assert_equal "\375\277\277\277\277\277".force_encoding(Encoding::UTF_8), [0x7fffffff].pack("U")
+ assert_raise(RangeError) { [0x80000000].pack("U") }
+ assert_raise(RangeError) { [0x100000000].pack("U") }
+ end
+
+ def test_pack_P
+ a = ["abc"]
+ assert_equal a, a.pack("P").unpack("P*")
+ assert_equal "a", a.pack("P").unpack("P")[0]
+ assert_equal a, a.pack("P").freeze.unpack("P*")
+ assert_raise(ArgumentError) { (a.pack("P") + "").unpack("P*") }
+ end
+
+ def test_pack_p
+ a = ["abc"]
+ assert_equal a, a.pack("p").unpack("p*")
+ assert_equal a[0], a.pack("p").unpack("p")[0]
+ assert_equal a, a.pack("p").freeze.unpack("p*")
+ assert_raise(ArgumentError) { (a.pack("p") + "").unpack("p*") }
+ end
+
+ def test_format_string_modified
+ fmt = "CC"
+ o = Object.new
+ class << o; self; end.class_eval do
+ define_method(:to_int) { fmt.clear; 0 }
+ end
+ assert_raise(RuntimeError) do
+ [o, o].pack(fmt)
+ end
+ end
+
+ def test_comment
+ assert_equal("\0\1", [0,1].pack(" C #foo \n C "))
+ assert_equal([0,1], "\0\1".unpack(" C #foo \n C "))
+ end
+
+ def test_illegal_bang
+ assert_raise(ArgumentError) { [].pack("a!") }
+ assert_raise(ArgumentError) { "".unpack("a!") }
+ end
+
+ def test_pack_unpack_aA
+ assert_equal("f", ["foo"].pack("A"))
+ assert_equal("f", ["foo"].pack("a"))
+ assert_equal("foo", ["foo"].pack("A*"))
+ assert_equal("foo", ["foo"].pack("a*"))
+ assert_equal("fo", ["foo"].pack("A2"))
+ assert_equal("fo", ["foo"].pack("a2"))
+ assert_equal("foo ", ["foo"].pack("A4"))
+ assert_equal("foo\0", ["foo"].pack("a4"))
+ assert_equal(" ", [nil].pack("A"))
+ assert_equal("\0", [nil].pack("a"))
+ assert_equal("", [nil].pack("A*"))
+ assert_equal("", [nil].pack("a*"))
+ assert_equal(" ", [nil].pack("A2"))
+ assert_equal("\0\0", [nil].pack("a2"))
+
+ assert_equal("foo" + "\0" * 27, ["foo"].pack("a30"))
+
+ assert_equal(["f"], "foo\0".unpack("A"))
+ assert_equal(["f"], "foo\0".unpack("a"))
+ assert_equal(["foo"], "foo\0".unpack("A4"))
+ assert_equal(["foo\0"], "foo\0".unpack("a4"))
+ assert_equal(["foo"], "foo ".unpack("A4"))
+ assert_equal(["foo "], "foo ".unpack("a4"))
+ assert_equal(["foo"], "foo".unpack("A4"))
+ assert_equal(["foo"], "foo".unpack("a4"))
+ end
+
+ def test_pack_unpack_Z
+ assert_equal("f", ["foo"].pack("Z"))
+ assert_equal("foo\0", ["foo"].pack("Z*"))
+ assert_equal("fo", ["foo"].pack("Z2"))
+ assert_equal("foo\0\0", ["foo"].pack("Z5"))
+ assert_equal("\0", [nil].pack("Z"))
+ assert_equal("\0", [nil].pack("Z*"))
+ assert_equal("\0\0", [nil].pack("Z2"))
+
+ assert_equal(["f"], "foo\0".unpack("Z"))
+ assert_equal(["foo"], "foo".unpack("Z*"))
+ assert_equal(["foo"], "foo\0".unpack("Z*"))
+ assert_equal(["foo"], "foo".unpack("Z5"))
+ end
+
+ def test_pack_unpack_bB
+ assert_equal("\xff\x00", ["1111111100000000"].pack("b*"))
+ assert_equal("\x01\x02", ["1000000001000000"].pack("b*"))
+ assert_equal("", ["1"].pack("b0"))
+ assert_equal("\x01", ["1"].pack("b1"))
+ assert_equal("\x01\x00", ["1"].pack("b2"))
+ assert_equal("\x01\x00", ["1"].pack("b3"))
+ assert_equal("\x01\x00\x00", ["1"].pack("b4"))
+ assert_equal("\x01\x00\x00", ["1"].pack("b5"))
+ assert_equal("\x01\x00\x00\x00", ["1"].pack("b6"))
+
+ assert_equal("\xff\x00", ["1111111100000000"].pack("B*"))
+ assert_equal("\x01\x02", ["0000000100000010"].pack("B*"))
+ assert_equal("", ["1"].pack("B0"))
+ assert_equal("\x80", ["1"].pack("B1"))
+ assert_equal("\x80\x00", ["1"].pack("B2"))
+ assert_equal("\x80\x00", ["1"].pack("B3"))
+ assert_equal("\x80\x00\x00", ["1"].pack("B4"))
+ assert_equal("\x80\x00\x00", ["1"].pack("B5"))
+ assert_equal("\x80\x00\x00\x00", ["1"].pack("B6"))
+
+ assert_equal(["1111111100000000"], "\xff\x00".unpack("b*"))
+ assert_equal(["1000000001000000"], "\x01\x02".unpack("b*"))
+ assert_equal([""], "".unpack("b0"))
+ assert_equal(["1"], "\x01".unpack("b1"))
+ assert_equal(["10"], "\x01".unpack("b2"))
+ assert_equal(["100"], "\x01".unpack("b3"))
+
+ assert_equal(["1111111100000000"], "\xff\x00".unpack("B*"))
+ assert_equal(["0000000100000010"], "\x01\x02".unpack("B*"))
+ assert_equal([""], "".unpack("B0"))
+ assert_equal(["1"], "\x80".unpack("B1"))
+ assert_equal(["10"], "\x80".unpack("B2"))
+ assert_equal(["100"], "\x80".unpack("B3"))
+ end
+
+ def test_pack_unpack_hH
+ assert_equal("\x01\xfe", ["10ef"].pack("h*"))
+ assert_equal("", ["10ef"].pack("h0"))
+ assert_equal("\x01\x0e", ["10ef"].pack("h3"))
+ assert_equal("\x01\xfe\x0", ["10ef"].pack("h5"))
+ assert_equal("\xff\x0f", ["fff"].pack("h3"))
+ assert_equal("\xff\x0f", ["fff"].pack("h4"))
+ assert_equal("\xff\x0f\0", ["fff"].pack("h5"))
+ assert_equal("\xff\x0f\0", ["fff"].pack("h6"))
+ assert_equal("\xff\x0f\0\0", ["fff"].pack("h7"))
+ assert_equal("\xff\x0f\0\0", ["fff"].pack("h8"))
+
+ assert_equal("\x10\xef", ["10ef"].pack("H*"))
+ assert_equal("", ["10ef"].pack("H0"))
+ assert_equal("\x10\xe0", ["10ef"].pack("H3"))
+ assert_equal("\x10\xef\x0", ["10ef"].pack("H5"))
+ assert_equal("\xff\xf0", ["fff"].pack("H3"))
+ assert_equal("\xff\xf0", ["fff"].pack("H4"))
+ assert_equal("\xff\xf0\0", ["fff"].pack("H5"))
+ assert_equal("\xff\xf0\0", ["fff"].pack("H6"))
+ assert_equal("\xff\xf0\0\0", ["fff"].pack("H7"))
+ assert_equal("\xff\xf0\0\0", ["fff"].pack("H8"))
+
+ assert_equal(["10ef"], "\x01\xfe".unpack("h*"))
+ assert_equal([""], "\x01\xfe".unpack("h0"))
+ assert_equal(["1"], "\x01\xfe".unpack("h1"))
+ assert_equal(["10"], "\x01\xfe".unpack("h2"))
+ assert_equal(["10e"], "\x01\xfe".unpack("h3"))
+ assert_equal(["10ef"], "\x01\xfe".unpack("h4"))
+ assert_equal(["10ef"], "\x01\xfe".unpack("h5"))
+
+ assert_equal(["10ef"], "\x10\xef".unpack("H*"))
+ assert_equal([""], "\x10\xef".unpack("H0"))
+ assert_equal(["1"], "\x10\xef".unpack("H1"))
+ assert_equal(["10"], "\x10\xef".unpack("H2"))
+ assert_equal(["10e"], "\x10\xef".unpack("H3"))
+ assert_equal(["10ef"], "\x10\xef".unpack("H4"))
+ assert_equal(["10ef"], "\x10\xef".unpack("H5"))
+ end
+
+ def test_pack_unpack_cC
+ assert_equal("\0\1\xff", [0, 1, 255].pack("c*"))
+ assert_equal("\0\1\xff", [0, 1, -1].pack("c*"))
+
+ assert_equal("\0\1\xff", [0, 1, 255].pack("C*"))
+ assert_equal("\0\1\xff", [0, 1, -1].pack("C*"))
+
+ assert_equal([0, 1, -1], "\0\1\xff".unpack("c*"))
+
+ assert_equal([0, 1, 255], "\0\1\xff".unpack("C*"))
+ end
+
+ def test_pack_unpack_sS
+ s1 = [513, -514].pack("s*")
+ s2 = [513, 65022].pack("S*")
+ assert_equal(s1, s2)
+ assert_equal([513, -514], s2.unpack("s*"))
+ assert_equal([513, 65022], s1.unpack("S*"))
+
+ s1 = [513, -514].pack("s!*")
+ s2 = [513, 65022].pack("S!*")
+ assert_equal(s1, s2)
+ assert_equal([513, -514], s2.unpack("s!*"))
+ assert_equal([513, 65022], s1.unpack("S!*"))
+
+ assert_equal(2, [1].pack("s").bytesize)
+ assert_equal(2, [1].pack("S").bytesize)
+ assert_operator(2, :<=, [1].pack("s!").bytesize)
+ assert_operator(2, :<=, [1].pack("S!").bytesize)
+ end
+
+ def test_pack_unpack_iI
+ s1 = [67305985, -50462977].pack("i*")
+ s2 = [67305985, 4244504319].pack("I*")
+ assert_equal(s1, s2)
+ assert_equal([67305985, -50462977], s2.unpack("i*"))
+ assert_equal([67305985, 4244504319], s1.unpack("I*"))
+
+ s1 = [67305985, -50462977].pack("i!*")
+ s2 = [67305985, 4244504319].pack("I!*")
+ assert_equal([67305985, -50462977], s1.unpack("i!*"))
+ assert_equal([67305985, 4244504319], s2.unpack("I!*"))
+
+ assert_operator(4, :<=, [1].pack("i").bytesize)
+ assert_operator(4, :<=, [1].pack("I").bytesize)
+ assert_operator(4, :<=, [1].pack("i!").bytesize)
+ assert_operator(4, :<=, [1].pack("I!").bytesize)
+ end
+
+ def test_pack_unpack_lL
+ s1 = [67305985, -50462977].pack("l*")
+ s2 = [67305985, 4244504319].pack("L*")
+ assert_equal(s1, s2)
+ assert_equal([67305985, -50462977], s2.unpack("l*"))
+ assert_equal([67305985, 4244504319], s1.unpack("L*"))
+
+ s1 = [67305985, -50462977].pack("l!*")
+ s2 = [67305985, 4244504319].pack("L!*")
+ assert_equal([67305985, -50462977], s1.unpack("l!*"))
+ assert_equal([67305985, 4244504319], s2.unpack("L!*"))
+
+ assert_equal(4, [1].pack("l").bytesize)
+ assert_equal(4, [1].pack("L").bytesize)
+ assert_operator(4, :<=, [1].pack("l!").bytesize)
+ assert_operator(4, :<=, [1].pack("L!").bytesize)
+ end
+
+ def test_pack_unpack_qQ
+ s1 = [578437695752307201, -506097522914230529].pack("q*")
+ s2 = [578437695752307201, 17940646550795321087].pack("Q*")
+ assert_equal(s1, s2)
+ assert_equal([578437695752307201, -506097522914230529], s2.unpack("q*"))
+ assert_equal([578437695752307201, 17940646550795321087], s1.unpack("Q*"))
+
+ assert_equal(8, [1].pack("q").bytesize)
+ assert_equal(8, [1].pack("Q").bytesize)
+ end
+
+ def test_pack_unpack_nN
+ assert_equal("\000\000\000\001\377\377\177\377\200\000\377\377", [0,1,-1,32767,-32768,65535].pack("n*"))
+ assert_equal("\000\000\000\000\000\000\000\001\377\377\377\377", [0,1,-1].pack("N*"))
+
+ assert_equal([0,1,65535,32767,32768,65535], "\000\000\000\001\377\377\177\377\200\000\377\377".unpack("n*"))
+ assert_equal([0,1,4294967295], "\000\000\000\000\000\000\000\001\377\377\377\377".unpack("N*"))
+
+ assert_equal(2, [1].pack("n").bytesize)
+ assert_equal(4, [1].pack("N").bytesize)
+ end
+
+ def test_pack_unpack_vV
+ assert_equal("\000\000\001\000\377\377\377\177\000\200\377\377", [0,1,-1,32767,-32768,65535].pack("v*"))
+ assert_equal("\000\000\000\000\001\000\000\000\377\377\377\377", [0,1,-1].pack("V*"))
+
+ assert_equal([0,1,65535,32767,32768,65535], "\000\000\001\000\377\377\377\177\000\200\377\377".unpack("v*"))
+ assert_equal([0,1,4294967295], "\000\000\000\000\001\000\000\000\377\377\377\377".unpack("V*"))
+
+ assert_equal(2, [1].pack("v").bytesize)
+ assert_equal(4, [1].pack("V").bytesize)
+ end
+
+ def test_pack_unpack_fdeEgG
+ inf = 1.0/0.0
+ nan = inf/inf
+ [0.0, 1.0, 3.0, inf, -inf, nan].each do |x|
+ %w(f d e E g G).each do |f|
+ v = [x].pack(f).unpack(f)
+ if x.nan?
+ assert(v.first.nan?)
+ else
+ assert_equal([x], v)
+ end
+ end
+ end
+ end
+
+ def test_pack_unpack_x
+ assert_equal("", [].pack("x0"))
+ assert_equal("\0", [].pack("x"))
+ assert_equal("\0" * 30, [].pack("x30"))
+
+ assert_equal([0, 2], "\x00\x00\x02".unpack("CxC"))
+ assert_raise(ArgumentError) { "".unpack("x") }
+ end
+
+ def test_pack_unpack_X
+ assert_equal("\x00\x02", [0, 1, 2].pack("CCXC"))
+ assert_equal("\x02", [0, 1, 2].pack("CCX2C"))
+ assert_raise(ArgumentError) { [].pack("X") }
+
+ assert_equal([0, 2, 2], "\x00\x02".unpack("CCXC"))
+ assert_raise(ArgumentError) { "".unpack("X") }
+ end
+
+ def test_pack_unpack_atmark
+ assert_equal("\x01\x00\x00\x02", [1, 2].pack("C at 3C"))
+ assert_equal("\x02", [1, 2].pack("C at 0C"))
+ assert_equal("\x01\x02", [1, 2].pack("C at 1C"))
+
+ assert_equal([1, 2], "\x01\x00\x00\x02".unpack("C at 3C"))
+ assert_equal([nil], "\x00".unpack("@1C")) # is it OK?
+ assert_raise(ArgumentError) { "\x00".unpack("@2C") }
+ end
+
+ def test_pack_unpack_percent
+ assert_raise(ArgumentError) { [].pack("%") }
+ assert_raise(ArgumentError) { "".unpack("%") }
+ end
+
+ def test_pack_unpack_U
+ assert_equal([0], [0].pack("U").unpack("U"))
+ assert_equal([0x80], [0x80].pack("U").unpack("U"))
+ assert_equal([0x800], [0x800].pack("U").unpack("U"))
+ assert_equal([0x10000], [0x10000].pack("U").unpack("U"))
+ assert_equal([0x400000], [0x400000].pack("U").unpack("U"))
+
+ assert_raise(ArgumentError) { "\x80".unpack("U") }
+ assert_raise(ArgumentError) { "\xff".unpack("U") }
+ assert_raise(ArgumentError) { "\xfc\x00".unpack("U") }
+ assert_raise(ArgumentError) { "\xc0\xc0".unpack("U") }
+ assert_raise(ArgumentError) { "\xe0\x80\x80".unpack("U") }
+ end
+
+ def test_pack_unpack_u
+ assert_equal("", [""].pack("u"))
+ assert_equal("!80``\n", ["a"].pack("u"))
+ assert_equal("#86)C\n", ["abc"].pack("u"))
+ assert_equal("$86)C9```\n", ["abcd"].pack("u"))
+ assert_equal("M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n", ["a"*45].pack("u"))
+ assert_equal("M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n!80``\n", ["a"*46].pack("u"))
+ assert_equal("&86)C9&5F\n#9VAI\n", ["abcdefghi"].pack("u6"))
+
+ assert_equal("M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n!80``\n", ["a"*46].pack("u0"))
+ assert_equal("M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n!80``\n", ["a"*46].pack("u1"))
+ assert_equal("M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n!80``\n", ["a"*46].pack("u2"))
+
+ assert_equal([""], "".unpack("u"))
+ assert_equal(["a"], "!80``\n".unpack("u"))
+ assert_equal(["abc"], "#86)C\n".unpack("u"))
+ assert_equal(["abcd"], "$86)C9```\n".unpack("u"))
+ assert_equal(["a"*45], "M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n".unpack("u"))
+ assert_equal(["a"*46], "M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n!80``\n".unpack("u"))
+ assert_equal(["abcdefghi"], "&86)C9&5F\n#9VAI\n".unpack("u"))
+
+ assert_equal(["\x00"], "\"\n".unpack("u"))
+ assert_equal(["\x00"], "! \r \n".unpack("u"))
+ end
+
+ def test_pack_unpack_m
+ assert_equal("", [""].pack("m"))
+ assert_equal("AA==\n", ["\0"].pack("m"))
+ assert_equal("AAA=\n", ["\0\0"].pack("m"))
+ assert_equal("AAAA\n", ["\0\0\0"].pack("m"))
+ assert_equal("/w==\n", ["\377"].pack("m"))
+ assert_equal("//8=\n", ["\377\377"].pack("m"))
+ assert_equal("////\n", ["\377\377\377"].pack("m"))
+
+ assert_equal([""], "".unpack("m"))
+ assert_equal(["\0"], "AA==\n".unpack("m"))
+ assert_equal(["\0\0"], "AAA=\n".unpack("m"))
+ assert_equal(["\0\0\0"], "AAAA\n".unpack("m"))
+ assert_equal(["\377"], "/w==\n".unpack("m"))
+ assert_equal(["\377\377"], "//8=\n".unpack("m"))
+ assert_equal(["\377\377\377"], "////\n".unpack("m"))
+ end
+
+ def test_pack_unpack_m0
+ assert_equal("", [""].pack("m0"))
+ assert_equal("AA==", ["\0"].pack("m0"))
+ assert_equal("AAA=", ["\0\0"].pack("m0"))
+ assert_equal("AAAA", ["\0\0\0"].pack("m0"))
+ assert_equal("/w==", ["\377"].pack("m0"))
+ assert_equal("//8=", ["\377\377"].pack("m0"))
+ assert_equal("////", ["\377\377\377"].pack("m0"))
+
+ assert_equal([""], "".unpack("m0"))
+ assert_equal(["\0"], "AA==".unpack("m0"))
+ assert_equal(["\0\0"], "AAA=".unpack("m0"))
+ assert_equal(["\0\0\0"], "AAAA".unpack("m0"))
+ assert_equal(["\377"], "/w==".unpack("m0"))
+ assert_equal(["\377\377"], "//8=".unpack("m0"))
+ assert_equal(["\377\377\377"], "////".unpack("m0"))
+
+ assert_raise(ArgumentError) { "^".unpack("m0") }
+ assert_raise(ArgumentError) { "A".unpack("m0") }
+ assert_raise(ArgumentError) { "A^".unpack("m0") }
+ assert_raise(ArgumentError) { "AA".unpack("m0") }
+ assert_raise(ArgumentError) { "AA=".unpack("m0") }
+ assert_raise(ArgumentError) { "AA===".unpack("m0") }
+ assert_raise(ArgumentError) { "AA=x".unpack("m0") }
+ assert_raise(ArgumentError) { "AAA".unpack("m0") }
+ assert_raise(ArgumentError) { "AAA^".unpack("m0") }
+ assert_raise(ArgumentError) { "AB==".unpack("m0") }
+ assert_raise(ArgumentError) { "AAB=".unpack("m0") }
+ end
+
+ def test_pack_unpack_M
+ assert_equal("a b c\td =\n\ne=\n", ["a b c\td \ne"].pack("M"))
+ assert_equal(["a b c\td \ne"], "a b c\td =\n\ne=\n".unpack("M"))
+ assert_equal("=00=\n", ["\0"].pack("M"))
+ assert_equal("a"*73+"=\na=\n", ["a"*74].pack("M"))
+ assert_equal(("a"*73+"=\n")*14+"a=\n", ["a"*1023].pack("M"))
+ assert_equal(["\0"], "=00=\n".unpack("M"))
+ assert_equal(["a"*74], ("a"*73+"=\na=\n").unpack("M"))
+ assert_equal(["a"*1023], (("a"*73+"=\n")*14+"a=\n").unpack("M"))
+ assert_equal(["\x0a"], "=0a=\n".unpack("M"))
+ assert_equal(["\x0a"], "=0A=\n".unpack("M"))
+ assert_equal([""], "=0Z=\n".unpack("M"))
+ assert_equal([""], "=\r\n".unpack("M"))
+ end
+
+ def test_pack_unpack_P2
+ assert_raise(ArgumentError) { ["abc"].pack("P4") }
+ assert_raise(ArgumentError) { [""].pack("P") }
+
+ assert_equal([], ".".unpack("P"))
+ assert_equal([], ".".unpack("p"))
+ assert_equal([nil], ("\0" * 1024).unpack("P"))
+ end
+
+ def test_pack_p2
+ assert_match(/\A\0*\Z/, [nil].pack("p"))
+ end
+
+ def test_pack_unpack_w
+ assert_equal("\000", [0].pack("w"))
+ assert_equal("\001", [1].pack("w"))
+ assert_equal("\177", [127].pack("w"))
+ assert_equal("\201\000", [128].pack("w"))
+ assert_equal("\377\177", [0x3fff].pack("w"))
+ assert_equal("\201\200\000", [0x4000].pack("w"))
+ assert_equal("\203\377\377\377\177", [0x3fffffff].pack("w"))
+ assert_equal("\204\200\200\200\000", [0x40000000].pack("w"))
+ assert_equal("\217\377\377\377\177", [0xffffffff].pack("w"))
+ assert_equal("\220\200\200\200\000", [0x100000000].pack("w"))
+ assert_raise(ArgumentError) { [-1].pack("w") }
+
+ assert_equal([0], "\000".unpack("w"))
+ assert_equal([1], "\001".unpack("w"), [1])
+ assert_equal([127], "\177".unpack("w"), [127])
+ assert_equal([128], "\201\000".unpack("w"), [128])
+ assert_equal([0x3fff], "\377\177".unpack("w"), [0x3fff])
+ assert_equal([0x4000], "\201\200\000".unpack("w"), [0x4000])
+ assert_equal([0x3fffffff], "\203\377\377\377\177".unpack("w"), [0x3fffffff])
+ assert_equal([0x40000000], "\204\200\200\200\000".unpack("w"), [0x40000000])
+ assert_equal([0xffffffff], "\217\377\377\377\177".unpack("w"), [0xffffffff])
+ assert_equal([0x100000000], "\220\200\200\200\000".unpack("w"), [0x100000000])
+ end
+
+ def test_modify_under_safe4
+ s = "foo"
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ s.clear
+ end.join
+ end
+ end
+
+ def test_length_too_big
+ assert_raise(RangeError) { [].pack("C100000000000000000000") }
+ end
+
+ def test_short_string
+ %w[n N v V s S i I l L q Q s! S! i! I! l! l!].each {|fmt|
+ str = [1].pack(fmt)
+ assert_equal([1,nil], str.unpack("#{fmt}2"))
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_parse.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_parse.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_parse.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,832 @@
+require 'test/unit'
+require 'stringio'
+
+class TestParse < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_else_without_rescue
+ x = eval <<-END
+ begin
+ else
+ 42
+ end
+ END
+ assert_equal(42, x)
+ end
+
+ def test_alias_backref
+ assert_raise(SyntaxError) do
+ eval <<-END
+ alias $foo $1
+ END
+ end
+ end
+
+ def test_command_call
+ t = Object.new
+ def t.foo(x); x; end
+
+ a = false
+ b = c = d = true
+ assert_nothing_raised do
+ eval <<-END
+ a &&= t.foo 42
+ b &&= t.foo 42
+ c &&= t.foo nil
+ d &&= t.foo false
+ END
+ end
+ assert_equal([false, 42, nil, false], [a, b, c, d])
+
+ a = 3
+ assert_nothing_raised { eval("a &= t.foo 5") }
+ assert_equal(1, a)
+
+ a = [nil, nil, true, true]
+ assert_nothing_raised do
+ eval <<-END
+ a[0] ||= t.foo 42
+ a[1] &&= t.foo 42
+ a[2] ||= t.foo 42
+ a[3] &&= t.foo 42
+ END
+ end
+ assert_equal([42, nil, true, 42], a)
+
+ o = Object.new
+ class << o
+ attr_accessor :foo, :bar, :Foo, :Bar, :baz, :qux
+ end
+ o.foo = o.Foo = o::baz = nil
+ o.bar = o.Bar = o::qux = 1
+ assert_nothing_raised do
+ eval <<-END
+ o.foo ||= t.foo 42
+ o.bar &&= t.foo 42
+ o.Foo ||= t.foo 42
+ o.Bar &&= t.foo 42
+ o::baz ||= t.foo 42
+ o::qux &&= t.foo 42
+ END
+ end
+ assert_equal([42, 42], [o.foo, o.bar])
+ assert_equal([42, 42], [o.Foo, o.Bar])
+ assert_equal([42, 42], [o::baz, o::qux])
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ $1 ||= t.foo 42
+ END
+ end
+
+ def t.bar(x); x + yield; end
+
+ a = b = nil
+ assert_nothing_raised do
+ eval <<-END
+ a = t.bar "foo" do
+ "bar"
+ end.gsub "ob", "OB"
+ b = t.bar "foo" do
+ "bar"
+ end::gsub "ob", "OB"
+ END
+ end
+ assert_equal("foOBar", a)
+ assert_equal("foOBar", b)
+
+ a = nil
+ assert_nothing_raised do
+ t.instance_eval <<-END
+ a = bar "foo" do "bar" end
+ END
+ end
+ assert_equal("foobar", a)
+
+ a = nil
+ assert_nothing_raised do
+ eval <<-END
+ a = t::bar "foo" do "bar" end
+ END
+ end
+ assert_equal("foobar", a)
+
+ def t.baz(*r)
+ @baz = r + (block_given? ? [yield] : [])
+ end
+
+ assert_nothing_raised do
+ t.instance_eval "baz (1), 2"
+ end
+ assert_equal([1, 2], t.instance_eval { @baz })
+ end
+
+ def test_mlhs_node
+ c = Class.new
+ class << c
+ attr_accessor :foo, :bar, :Foo, :Bar
+ FOO = BAR = nil
+ end
+
+ assert_nothing_raised do
+ eval <<-END
+ c::foo, c::bar = 1, 2
+ c.Foo, c.Bar = 1, 2
+ c::FOO, c::BAR = 1, 2
+ END
+ end
+ assert_equal([1, 2], [c::foo, c::bar])
+ assert_equal([1, 2], [c.Foo, c.Bar])
+ assert_equal([1, 2], [c::FOO, c::BAR])
+ end
+
+ def test_dynamic_constant_assignment
+ assert_raise(SyntaxError) do
+ Object.new.instance_eval <<-END
+ def foo
+ self::FOO, self::BAR = 1, 2
+ ::FOO, ::BAR = 1, 2
+ end
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ $1, $2 = 1, 2
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ Object.new.instance_eval <<-END
+ def foo
+ ::FOO = 1
+ end
+ END
+ end
+
+ c = Class.new
+ assert_raise(SyntaxError) do
+ eval <<-END
+ c::FOO &= 1
+ ::FOO &= 1
+ END
+ end
+
+ c = Class.new
+ assert_raise(SyntaxError) do
+ eval <<-END
+ $1 &= 1
+ END
+ end
+ end
+
+ def test_class_module
+ assert_raise(SyntaxError) do
+ eval <<-END
+ class foo; end
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo
+ class Foo; end
+ module Bar; end
+ end
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ class Foo Bar; end
+ END
+ end
+ end
+
+ def test_op_name
+ o = Object.new
+ def o.>(x); x; end
+ def o./(x); x; end
+
+ a = nil
+ assert_nothing_raised do
+ o.instance_eval <<-END
+ undef >, /
+ END
+ end
+ end
+
+ def test_arg
+ o = Object.new
+ class << o
+ attr_accessor :foo, :bar, :Foo, :Bar, :baz, :qux
+ end
+ o.foo = o.Foo = o::baz = nil
+ o.bar = o.Bar = o::qux = 1
+ assert_nothing_raised do
+ eval <<-END
+ o.foo ||= 42
+ o.bar &&= 42
+ o.Foo ||= 42
+ o.Bar &&= 42
+ o::baz ||= 42
+ o::qux &&= 42
+ END
+ end
+ assert_equal([42, 42], [o.foo, o.bar])
+ assert_equal([42, 42], [o.Foo, o.Bar])
+ assert_equal([42, 42], [o::baz, o::qux])
+
+ a = nil
+ assert_nothing_raised do
+ eval <<-END
+ a = -2.0 ** 2
+ END
+ end
+ assert_equal(-4.0, a)
+ end
+
+ def test_block_variable
+ o = Object.new
+ def o.foo(*r); yield(*r); end
+
+ a = nil
+ assert_nothing_raised do
+ eval <<-END
+ o.foo 1 do|; a| a = 42 end
+ END
+ end
+ assert_nil(a)
+ end
+
+ def test_bad_arg
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo(FOO); end
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo(@foo); end
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo($foo); end
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo(@@foo); end
+ END
+ end
+
+ o = Object.new
+ def o.foo(*r); yield(*r); end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ o.foo 1 {|; @a| @a = 42 }
+ END
+ end
+ end
+
+ def test_do_lambda
+ a = b = nil
+ assert_nothing_raised do
+ eval <<-END
+ a = -> do
+ b = 42
+ end
+ END
+ end
+ a.call
+ assert_equal(42, b)
+ end
+
+ def test_block_call_colon2
+ o = Object.new
+ def o.foo(x); x + yield; end
+
+ a = b = nil
+ assert_nothing_raised do
+ o.instance_eval <<-END
+ a = foo 1 do 42 end.to_s
+ b = foo 1 do 42 end::to_s
+ END
+ end
+ assert_equal("43", a)
+ assert_equal("43", b)
+ end
+
+ def test_call_method
+ a = b = nil
+ assert_nothing_raised do
+ eval <<-END
+ a = proc {|x| x + "bar" }.("foo")
+ b = proc {|x| x + "bar" }::("foo")
+ END
+ end
+ assert_equal("foobar", a)
+ assert_equal("foobar", b)
+ end
+
+ def test_xstring
+ assert_raise(Errno::ENOENT) do
+ eval("``")
+ end
+ end
+
+ def test_words
+ assert_equal([], %W( ))
+ end
+
+ def test_dstr
+ @@foo = 1
+ assert_equal("foo 1 bar", "foo #@@foo bar")
+ "1" =~ /(.)/
+ assert_equal("foo 1 bar", "foo #$1 bar")
+ end
+
+ def test_dsym
+ assert_nothing_raised { eval(':""') }
+ end
+
+ def test_arg2
+ o = Object.new
+
+ assert_nothing_raised do
+ eval <<-END
+ def o.foo(a=42,*r,z,&b); b.call(r.inject(a*1000+z*100, :+)); end
+ END
+ end
+ assert_equal(-1405, o.foo(1,2,3,4) {|x| -x })
+ assert_equal(-1302, o.foo(1,2,3) {|x| -x })
+ assert_equal(-1200, o.foo(1,2) {|x| -x })
+ assert_equal(-42100, o.foo(1) {|x| -x })
+ assert_raise(ArgumentError) { o.foo() }
+
+ assert_nothing_raised do
+ eval <<-END
+ def o.foo(a=42,z,&b); b.call(a*1000+z*100); end
+ END
+ end
+ assert_equal(-1200, o.foo(1,2) {|x| -x } )
+ assert_equal(-42100, o.foo(1) {|x| -x } )
+ assert_raise(ArgumentError) { o.foo() }
+
+ assert_nothing_raised do
+ eval <<-END
+ def o.foo(*r,z,&b); b.call(r.inject(z*100, :+)); end
+ END
+ end
+ assert_equal(-303, o.foo(1,2,3) {|x| -x } )
+ assert_equal(-201, o.foo(1,2) {|x| -x } )
+ assert_equal(-100, o.foo(1) {|x| -x } )
+ assert_raise(ArgumentError) { o.foo() }
+ end
+
+ def test_duplicate_argument
+ assert_raise(SyntaxError) do
+ eval <<-END
+ 1.times {|&b?| }
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ 1.times {|a, a|}
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo(a, a); end
+ END
+ end
+ end
+
+ def test_define_singleton_error
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def ("foo").foo; end
+ END
+ end
+ end
+
+ def test_backquote
+ t = Object.new
+
+ assert_nothing_raised do
+ eval <<-END
+ def t.`(x); "foo" + x + "bar"; end
+ END
+ end
+ a = b = nil
+ assert_nothing_raised do
+ eval <<-END
+ a = t.` "zzz"
+ 1.times {|;z| t.` ("zzz") }
+ END
+ t.instance_eval <<-END
+ b = `zzz`
+ END
+ end
+ assert_equal("foozzzbar", a)
+ assert_equal("foozzzbar", b)
+ end
+
+ def test_carrige_return
+ assert_equal(2, eval("1 +\r\n1"))
+ end
+
+ def test_string
+ assert_raise(SyntaxError) do
+ eval '"\xg1"'
+ end
+
+ assert_raise(SyntaxError) do
+ eval '"\u{1234"'
+ end
+
+ assert_raise(SyntaxError) do
+ eval '"\M1"'
+ end
+
+ assert_raise(SyntaxError) do
+ eval '"\C1"'
+ end
+
+ assert_equal("\x81", eval('"\C-\M-a"'))
+ assert_equal("\177", eval('"\c?"'))
+ end
+
+ def test_question
+ assert_raise(SyntaxError) { eval('?') }
+ assert_raise(SyntaxError) { eval('? ') }
+ assert_raise(SyntaxError) { eval("?\n") }
+ assert_raise(SyntaxError) { eval("?\t") }
+ assert_raise(SyntaxError) { eval("?\v") }
+ assert_raise(SyntaxError) { eval("?\r") }
+ assert_raise(SyntaxError) { eval("?\f") }
+ assert_equal("\u{1234}", eval("?\u{1234}"))
+ assert_equal("\u{1234}", eval('?\u{1234}'))
+ end
+
+ def test_percent
+ assert_equal(:foo, eval('%s(foo)'))
+ assert_raise(SyntaxError) { eval('%s') }
+ assert_raise(SyntaxError) { eval('%ss') }
+ assert_raise(SyntaxError) { eval('%z()') }
+ end
+
+ def test_symbol
+ bug = '[ruby-dev:41447]'
+ sym = "foo\0bar".to_sym
+ assert_nothing_raised(SyntaxError, bug) do
+ assert_equal(sym, eval(":'foo\0bar'"))
+ end
+ assert_nothing_raised(SyntaxError, bug) do
+ assert_equal(sym, eval(':"foo\u0000bar"'))
+ end
+ assert_nothing_raised(SyntaxError, bug) do
+ assert_equal(sym, eval(':"foo\u{0}bar"'))
+ end
+ assert_raise(SyntaxError) do
+ eval ':"foo\u{}bar"'
+ end
+ end
+
+ def test_parse_string
+ assert_raise(SyntaxError) do
+ eval <<-END
+/
+ END
+ end
+ end
+
+ def test_here_document
+ x = nil
+
+ assert_raise(SyntaxError) do
+ eval %Q(
+<\<FOO
+ )
+ end
+
+ assert_raise(SyntaxError) do
+ eval %q(
+<<FOO
+#$
+FOO
+ )
+ end
+
+ assert_raise(SyntaxError) do
+ eval %Q(
+<\<\"
+ )
+ end
+
+ assert_raise(SyntaxError) do
+ eval %q(
+<<``
+ )
+ end
+
+ assert_raise(SyntaxError) do
+ eval %q(
+<<--
+ )
+ end
+
+ assert_raise(SyntaxError) do
+ eval %q(
+<<FOO
+#$
+foo
+FOO
+ )
+ end
+
+ assert_nothing_raised do
+ eval "x = <<""FOO\r\n1\r\nFOO"
+ end
+ assert_equal("1\n", x)
+ end
+
+ def test_magic_comment
+ x = nil
+ assert_nothing_raised do
+ eval <<-END
+# coding = utf-8
+x = __ENCODING__
+ END
+ end
+ assert_equal(Encoding.find("UTF-8"), x)
+
+ assert_raise(ArgumentError) do
+ eval <<-END
+# coding = foobarbazquxquux_dummy_enconding
+x = __ENCODING__
+ END
+ end
+ end
+
+ def test_utf8_bom
+ x = nil
+ assert_nothing_raised do
+ eval "\xef\xbb\xbf x = __ENCODING__"
+ end
+ assert_equal(Encoding.find("UTF-8"), x)
+ assert_raise(NameError) { eval "\xef" }
+ end
+
+ def test_dot_in_next_line
+ x = nil
+ assert_nothing_raised do
+ eval <<-END
+ x = 1
+ .to_s
+ END
+ end
+ assert_equal("1", x)
+ end
+
+ def test_pow_asgn
+ x = 3
+ assert_nothing_raised { eval("x **= 2") }
+ assert_equal(9, x)
+ end
+
+ def test_embedded_rd
+ assert_raise(SyntaxError) do
+ eval <<-END
+=begin
+ END
+ end
+ end
+
+ def test_float
+ assert_equal(1.0/0, eval("1e10000"))
+ assert_raise(SyntaxError) { eval('1_E') }
+ assert_raise(SyntaxError) { eval('1E1E1') }
+ end
+
+ def test_global_variable
+ assert_equal(nil, eval('$-x'))
+ assert_equal(nil, eval('alias $preserve_last_match $&'))
+ assert_equal(nil, eval('alias $& $test_parse_foobarbazqux'))
+ $test_parse_foobarbazqux = nil
+ assert_equal(nil, $&)
+ assert_equal(nil, eval('alias $& $preserve_last_match'))
+ assert_raise(SyntaxError) { eval('$#') }
+ end
+
+ def test_invalid_instance_variable
+ assert_raise(SyntaxError) { eval('@#') }
+ end
+
+ def test_invalid_class_variable
+ assert_raise(SyntaxError) { eval('@@1') }
+ end
+
+ def test_invalid_char
+ x = 1
+ assert_equal(1, eval("\x01x"))
+ assert_equal(nil, eval("\x04x"))
+ end
+
+ def test_literal_concat
+ x = "baz"
+ assert_equal("foobarbaz", eval('"foo" "bar#{x}"'))
+ end
+
+ def test_unassignable
+ assert_raise(SyntaxError) do
+ eval %q(self = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval %q(nil = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval %q(true = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval %q(false = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval %q(__FILE__ = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval %q(__LINE__ = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval %q(__ENCODING__ = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo
+ FOO = 1
+ end
+ END
+ end
+ end
+
+ def test_block_dup
+ assert_raise(SyntaxError) do
+ eval <<-END
+ foo(&proc{}) {}
+ END
+ end
+ end
+
+ def test_set_backref
+ assert_raise(SyntaxError) do
+ eval <<-END
+ $& = 1
+ END
+ end
+ end
+
+ def test_arg_concat
+ skip("[BUG : #837] Abort")
+
+ o = Object.new
+ class << o; self; end.instance_eval do
+ define_method(:[]=) {|*r, &b| b.call(r) }
+ end
+ r = nil
+ assert_nothing_raised do
+ eval <<-END
+ o[&proc{|x| r = x }] = 1
+ END
+ end
+ assert_equal([1], r)
+ end
+
+ def test_void_expr_stmts_value
+ skip("[BUG : #???] Abort")
+
+ # This test checks if void contexts are warned correctly.
+ # Thus, warnings MUST NOT be suppressed.
+ $VERBOSE = true
+ stderr = $stderr
+ $stderr = StringIO.new("")
+ x = 1
+ assert_nil eval("x; nil")
+ assert_nil eval("1+1; nil")
+ assert_nil eval("TestParse; nil")
+ assert_nil eval("::TestParse; nil")
+ assert_nil eval("x..x; nil")
+ assert_nil eval("x...x; nil")
+ assert_nil eval("self; nil")
+ assert_nil eval("nil; nil")
+ assert_nil eval("true; nil")
+ assert_nil eval("false; nil")
+ assert_nil eval("defined?(1); nil")
+
+ assert_raise(SyntaxError) do
+ eval %q(1; next; 2)
+ end
+
+ o = Object.new
+ assert_nothing_raised do
+ eval <<-END
+ x = def o.foo; end
+ END
+ end
+ assert_equal($stderr.string.lines.to_a.size, 14)
+ $stderr = stderr
+ end
+
+ def test_assign_in_conditional
+ assert_raise(SyntaxError) do
+ eval <<-END
+ (x, y = 1, 2) ? 1 : 2
+ END
+ end
+
+ assert_nothing_raised do
+ eval <<-END
+ if @x = true
+ 1
+ else
+ 2
+ end
+ END
+ end
+ end
+
+ def test_literal_in_conditional
+ assert_nothing_raised do
+ eval <<-END
+ "foo" ? 1 : 2
+ END
+ end
+
+ assert_nothing_raised do
+ x = "bar"
+ eval <<-END
+ /foo#{x}baz/ ? 1 : 2
+ END
+ end
+
+ assert_nothing_raised do
+ eval <<-END
+ (true..false) ? 1 : 2
+ END
+ end
+
+ assert_nothing_raised do
+ eval <<-END
+ ("foo".."bar") ? 1 : 2
+ END
+ end
+
+ assert_nothing_raised do
+ x = "bar"
+ eval <<-END
+ :"foo#{"x"}baz" ? 1 : 2
+ END
+ end
+ end
+
+ def test_no_blockarg
+ assert_raise(SyntaxError) do
+ eval <<-END
+ yield(&:+)
+ END
+ end
+ end
+
+ def test_intern
+ assert_equal(':""', ''.intern.inspect)
+ assert_equal(':$foo', '$foo'.intern.inspect)
+ assert_equal(':"!foo"', '!foo'.intern.inspect)
+ assert_equal(':"foo=="', "foo==".intern.inspect)
+ end
+
+ def test_all_symbols
+ x = Symbol.all_symbols
+ assert_kind_of(Array, x)
+ assert(x.all? {|s| s.is_a?(Symbol) })
+ end
+
+ def test_is_class_id
+ c = Class.new
+ assert_raise(NameError) do
+ c.instance_eval { remove_class_variable(:@var) }
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_path.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_path.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_path.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,242 @@
+require 'test/unit'
+
+class TestPath < Test::Unit::TestCase
+ def test_path
+ assert_equal("a", File.basename("a"))
+ assert_equal("b", File.basename("a/b"))
+ assert_equal("b", File.basename("a/b/"))
+ assert_equal("/", File.basename("/"))
+ assert_equal("/", File.basename("//"))
+ assert_equal("/", File.basename("///"))
+ assert_equal("b", File.basename("a/b////"))
+ assert_equal("a", File.basename("a.rb", ".rb"))
+ assert_equal("a", File.basename("a.rb///", ".rb"))
+ assert_equal("a", File.basename("a.rb///", ".*"))
+ assert_equal("a.rb", File.basename("a.rb///", ".c"))
+ assert_equal(".", File.dirname("a"))
+ assert_equal("/", File.dirname("/"))
+ assert_equal("/", File.dirname("/a"))
+ assert_equal("a", File.dirname("a/b"))
+ assert_equal("a/b", File.dirname("a/b/c"))
+ assert_equal("/a/b", File.dirname("/a/b/c"))
+ assert_equal("/a", File.dirname("/a/b/"))
+ assert_equal("/a", File.dirname("/a/b///"))
+ case Dir.pwd
+ when %r'\A\w:'
+ assert_match(/\A\w:\/\z/, File.expand_path(".", "/"))
+ assert_match(/\A\w:\/a\z/, File.expand_path("a", "/"))
+ dosish = true
+ when %r'\A//'
+ assert_match(%r'\A//[^/]+/[^/]+\z', File.expand_path(".", "/"))
+ assert_match(%r'\A//[^/]+/[^/]+/a\z', File.expand_path(".", "/"))
+ dosish = true
+ else
+ assert_equal("/", File.expand_path(".", "/"))
+ assert_equal("/sub", File.expand_path("sub", "/"))
+ end
+ if dosish
+ assert_equal("//127.0.0.1/share", File.expand_path("/", "//127.0.0.1/share/sub"))
+ assert_equal("//127.0.0.1/share/dir", File.expand_path("/dir", "//127.0.0.1/share/sub"))
+ assert_equal("z:/", File.expand_path("/", "z:/sub"))
+ assert_equal("z:/dir", File.expand_path("/dir", "z:/sub"))
+ end
+ assert_equal("//", File.expand_path(".", "//"))
+ assert_equal("//sub", File.expand_path("sub", "//"))
+
+ assert_equal("//127.0.0.1/\u3042", File.expand_path("\u3042", "//127.0.0.1"))
+ end
+
+ def test_dirname
+ if /(bcc|ms)win\d|mingw|cygwin|emx/ =~ RUBY_PLATFORM
+ # DOSISH_DRIVE_LETTER
+ assert_equal('C:.', File.dirname('C:'))
+ assert_equal('C:.', File.dirname('C:a'))
+ assert_equal('C:.', File.dirname('C:a/'))
+ assert_equal('C:a', File.dirname('C:a/b'), "[ruby-dev:27738]")
+
+ assert_equal('C:/', File.dirname('C:/'))
+ assert_equal('C:/', File.dirname('C:/a'))
+ assert_equal('C:/', File.dirname('C:/a/'))
+ assert_equal('C:/a', File.dirname('C:/a/b'))
+
+ assert_equal('C:/', File.dirname('C://'))
+ assert_equal('C:/', File.dirname('C://a'))
+ assert_equal('C:/', File.dirname('C://a/'))
+ assert_equal('C:/a', File.dirname('C://a/b'))
+
+ assert_equal('C:/', File.dirname('C:///'), "[ruby-dev:27738]")
+ assert_equal('C:/', File.dirname('C:///a'))
+ assert_equal('C:/', File.dirname('C:///a/'))
+ assert_equal('C:/a', File.dirname('C:///a/b'))
+ else
+ # others
+ assert_equal('.', File.dirname('C:'))
+ assert_equal('.', File.dirname('C:a'))
+ assert_equal('.', File.dirname('C:a/'))
+ assert_equal('C:a', File.dirname('C:a/b'))
+
+ assert_equal('.', File.dirname('C:/'))
+ assert_equal('C:', File.dirname('C:/a'))
+ assert_equal('C:', File.dirname('C:/a/'))
+ assert_equal('C:/a', File.dirname('C:/a/b'))
+
+ assert_equal('.', File.dirname('C://'))
+ assert_equal('C:', File.dirname('C://a'))
+ assert_equal('C:', File.dirname('C://a/'))
+ # not spec.
+ #assert_equal('C://a', File.dirname('C://a/b'))
+
+ assert_equal('.', File.dirname('C:///'))
+ assert_equal('C:', File.dirname('C:///a'))
+ assert_equal('C:', File.dirname('C:///a/'))
+ # not spec.
+ #assert_equal('C:///a', File.dirname('C:///a/b'))
+ end
+
+ assert_equal('.', File.dirname(''))
+ assert_equal('.', File.dirname('a'))
+ assert_equal('.', File.dirname('a/'))
+ assert_equal('a', File.dirname('a/b'))
+
+ assert_equal('/', File.dirname('/'))
+ assert_equal('/', File.dirname('/a'))
+ assert_equal('/', File.dirname('/a/'))
+ assert_equal('/a', File.dirname('/a/b'))
+
+ if /(bcc|ms|cyg)win|mingw|emx/ =~ RUBY_PLATFORM
+ # DOSISH_UNC
+ assert_equal('//', File.dirname('//'))
+ assert_equal('//a', File.dirname('//a'))
+ assert_equal('//a', File.dirname('//a/'))
+ assert_equal('//a/b', File.dirname('//a/b'))
+ assert_equal('//a/b', File.dirname('//a/b/'))
+ assert_equal('//a/b', File.dirname('//a/b/c'))
+
+ assert_equal('//', File.dirname('///'))
+ assert_equal('//a', File.dirname('///a'))
+ assert_equal('//a', File.dirname('///a/'))
+ assert_equal('//a/b', File.dirname('///a/b'))
+ assert_equal('//a/b', File.dirname('///a/b/'))
+ assert_equal('//a/b', File.dirname('///a/b/c'))
+ else
+ # others
+ assert_equal('/', File.dirname('//'))
+ assert_equal('/', File.dirname('//a'))
+ assert_equal('/', File.dirname('//a/'))
+ assert_equal('/a', File.dirname('//a/b'))
+ assert_equal('/a', File.dirname('//a/b/'))
+ assert_equal('/a/b', File.dirname('//a/b/c'))
+
+ assert_equal('/', File.dirname('///'))
+ assert_equal('/', File.dirname('///a'))
+ assert_equal('/', File.dirname('///a/'))
+ assert_equal('/a', File.dirname('///a/b'))
+ assert_equal('/a', File.dirname('///a/b/'))
+ assert_equal('/a/b', File.dirname('///a/b/c'))
+ end
+ end
+
+ def test_basename
+ if /(bcc|ms)win\d|mingw|cygwin|emx/ =~ RUBY_PLATFORM
+ # DOSISH_DRIVE_LETTER
+ assert_equal('', File.basename('C:'))
+ assert_equal('a', File.basename('C:a'))
+ assert_equal('a', File.basename('C:a/'))
+ assert_equal('b', File.basename('C:a/b'))
+
+ assert_equal('/', File.basename('C:/'))
+ assert_equal('a', File.basename('C:/a'))
+ assert_equal('a', File.basename('C:/a/'))
+ assert_equal('b', File.basename('C:/a/b'))
+
+ assert_equal('/', File.basename('C://'))
+ assert_equal('a', File.basename('C://a'))
+ assert_equal('a', File.basename('C://a/'))
+ assert_equal('b', File.basename('C://a/b'))
+
+ assert_equal('/', File.basename('C:///'))
+ assert_equal('a', File.basename('C:///a'))
+ assert_equal('a', File.basename('C:///a/'))
+ assert_equal('b', File.basename('C:///a/b'))
+ else
+ # others
+ assert_equal('C:', File.basename('C:'))
+ assert_equal('C:a', File.basename('C:a'))
+ assert_equal('C:a', File.basename('C:a/'))
+ assert_equal('b', File.basename('C:a/b'))
+
+ assert_equal('C:', File.basename('C:/'))
+ assert_equal('a', File.basename('C:/a'))
+ assert_equal('a', File.basename('C:/a/'))
+ assert_equal('b', File.basename('C:/a/b'))
+
+ assert_equal('C:', File.basename('C://'))
+ assert_equal('a', File.basename('C://a'))
+ assert_equal('a', File.basename('C://a/'))
+ assert_equal('b', File.basename('C://a/b'))
+
+ assert_equal('C:', File.basename('C:///'))
+ assert_equal('a', File.basename('C:///a'))
+ assert_equal('a', File.basename('C:///a/'))
+ assert_equal('b', File.basename('C:///a/b'))
+ end
+
+ assert_equal('', File.basename(''))
+ assert_equal('a', File.basename('a'))
+ assert_equal('a', File.basename('a/'))
+ assert_equal('b', File.basename('a/b'))
+
+ assert_equal('/', File.basename('/'))
+ assert_equal('a', File.basename('/a'))
+ assert_equal('a', File.basename('/a/'))
+ assert_equal('b', File.basename('/a/b'))
+
+ assert_equal("..", File.basename("..", ".*"))
+
+ if /(bcc|ms|cyg)win|mingw|emx/ =~ RUBY_PLATFORM
+ # DOSISH_UNC
+ assert_equal('/', File.basename('//'))
+ assert_equal('/', File.basename('//a'))
+ assert_equal('/', File.basename('//a/'))
+ assert_equal('/', File.basename('//a/b'), "[ruby-dev:27776]")
+ assert_equal('/', File.basename('//a/b/'))
+ assert_equal('c', File.basename('//a/b/c'))
+
+ assert_equal('/', File.basename('///'))
+ assert_equal('/', File.basename('///a'))
+ assert_equal('/', File.basename('///a/'))
+ assert_equal('/', File.basename('///a/b'))
+ assert_equal('/', File.basename('///a/b/'))
+ assert_equal('c', File.basename('///a/b/c'))
+ else
+ # others
+ assert_equal('/', File.basename('//'))
+ assert_equal('a', File.basename('//a'))
+ assert_equal('a', File.basename('//a/'))
+ assert_equal('b', File.basename('//a/b'))
+ assert_equal('b', File.basename('//a/b/'))
+ assert_equal('c', File.basename('//a/b/c'))
+
+ assert_equal('/', File.basename('///'))
+ assert_equal('a', File.basename('///a'))
+ assert_equal('a', File.basename('///a/'))
+ assert_equal('b', File.basename('///a/b'))
+ assert_equal('b', File.basename('///a/b/'))
+ assert_equal('c', File.basename('///a/b/c'))
+ end
+ end
+
+ def test_extname
+ assert_equal('', File.extname('a'))
+ ext = '.rb'
+ assert_equal(ext, File.extname('a.rb'))
+ unless /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ # trailing spaces and dots are ignored on NTFS.
+ ext = ''
+ end
+ assert_equal(ext, File.extname('a.rb.'))
+ assert_equal('', File.extname('a.'))
+ assert_equal('', File.extname('.x'))
+ assert_equal('', File.extname('..x'))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_pipe.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_pipe.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_pipe.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,16 @@
+require 'test/unit'
+require_relative 'ut_eof'
+
+class TestPipe < Test::Unit::TestCase
+ include TestEOF
+ def open_file(content)
+ r, w = IO.pipe
+ w << content
+ w.close
+ begin
+ yield r
+ ensure
+ r.close
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_primitive.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_primitive.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_primitive.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,423 @@
+require 'test/unit'
+
+class TestRubyPrimitive < Test::Unit::TestCase
+
+ def test_not
+ assert_equal false, !true
+ assert_equal true, !false
+ assert_equal true, !nil
+ assert_equal false, !(1+1)
+ assert_equal false, !!nil
+ assert_equal true, !!1
+ end
+
+ def test_lvar
+ a = 1
+ assert_equal 1, a
+ b = 2
+ assert_equal 1, a
+ a = b = 3
+ assert_equal 3, a
+ assert_equal 3, b
+ a = b = c = 4
+ assert_equal 4, a
+ assert_equal 4, b
+ assert_equal 4, c
+ end
+
+ C = 1
+ class A
+ Const = 1
+ class B
+ Const = 2
+ class C
+ Const = 3
+ def const
+ Const
+ end
+ end
+ end
+ end
+ (1..2).map {
+ A::B::C::Const
+ }
+
+ def test_constant
+ assert_equal 1, C
+ assert_equal 1, C
+ assert_equal 1, A::Const
+ assert_equal 2, A::B::Const
+ assert_equal 3, A::B::C::Const
+ assert_equal 3, A::B::C.new.const
+ assert_equal 1, ::TestRubyPrimitive::A::Const
+ A::B::C.send(:remove_const, :Const)
+ assert_equal 2, A::B::C.new.const
+ assert_raise(TypeError) {
+ C::CONST
+ }
+ end
+
+ class A2
+ class B2
+ class C2
+ C = 7
+ end
+ end
+ end
+
+ def test_constant_cache
+ i = 0
+ while i < 3
+ r = A2::B2::C2::C
+ i += 1
+ end
+ assert_equal 7, r
+ end
+
+ class A3
+ class B3
+ C = 99
+ end
+ end
+ i = 0
+ while i < 3
+ r = A3::B3::C # cache
+ class A3::B3
+ remove_const :C
+ end
+ A3::B3::C = i ** i
+ i += 1
+ end
+
+ def test_constant_cache2
+ assert_equal 4, A3::B3::C
+ end
+
+ class A4
+ Const = 7
+ (1..3).map {
+ $test_ruby_primitive_constant_cache3 = self::Const
+ }
+ end
+
+ def test_constant_cache3
+ assert_equal 7, $test_ruby_primitive_constant_cache3
+ end
+
+ class A5
+ Const = 8
+ (1..3).map {
+ $test_ruby_primitive_constant_cache4 = eval('self')::Const
+ }
+ end
+
+ def test_constatant_cache4
+ assert_equal 8, $test_ruby_primitive_constant_cache4
+ end
+
+ class A6
+ Const = 0
+ def self.foo
+ self::Const
+ end
+ end
+ class B6 < A6
+ Const = 1
+ end
+ class C6 < B6
+ Const = 2
+ end
+ $test_ruby_primitive_constant_cache5 = [A6.foo, B6.foo, C6.foo]
+
+ def test_constant_cache5
+ assert_equal [0, 1, 2], $test_ruby_primitive_constant_cache5
+ end
+
+ def test_gvar
+ $test_ruby_primitive_gvar = 7
+ assert_equal 7, $test_ruby_primitive_gvar
+ assert_equal 7, $test_ruby_primitive_gvar
+ $test_ruby_primitive_gvar = 88
+ assert_equal 88, $test_ruby_primitive_gvar
+ assert_equal 88, $test_ruby_primitive_gvar
+ assert_equal 7, ($test_ruby_primitive_gvar = 7)
+ assert_equal 7, ($test_ruby_primitive_gvar = 7)
+ end
+
+ class A7
+ @@c = 1
+ def m
+ @@c += 1
+ end
+ end
+
+ def test_cvar_from_instance_method
+ assert_equal 2, A7.new.m
+ assert_equal 3, A7.new.m
+ assert_equal 4, A7.new.m
+ end
+
+ class A8
+ @@c = 1
+ class << self
+ def m
+ @@c += 1
+ end
+ end
+ end
+
+ def test_cvar_from_singleton_method
+ assert_equal 2, A8.m
+ assert_equal 3, A8.m
+ assert_equal 4, A8.m
+ end
+
+ class A9
+ @@c = 1
+ def self.m
+ @@c += 1
+ end
+ end
+
+ def test_cvar_from_singleton_method2
+ assert_equal 2, A9.m
+ assert_equal 3, A9.m
+ assert_equal 4, A9.m
+ end
+
+ class A10
+ attr_accessor :a
+ end
+
+ def test_opassign
+ i = 0
+ i += 1
+ assert_equal 1, i
+
+ @iv = 2
+ @iv += 2
+ assert_equal 4, @iv
+
+ @@cv ||= 1
+ assert_equal 1, @@cv
+ @@cv &&= 2
+ assert_equal 2, @@cv
+ @@cv ||= 99
+ assert_equal 2, @@cv
+
+ $gv = 3
+ $gv += 4
+ assert_equal 7, $gv
+
+ obj = A10.new
+ obj.a = 9
+ obj.a &&= 7
+ assert_equal 7, obj.a
+
+ obj.a = nil
+ obj.a ||= 2
+ assert_equal 2, obj.a
+
+ obj.a &&= 3
+ assert_equal 3, obj.a
+
+ a = []
+ a[0] ||= 3
+ assert_equal 3, a[0]
+ a[0] &&= 7
+ assert_equal 7, a[0]
+ a[0] ||= 3
+ assert_equal 7, a[0]
+
+ a = [0, 1, nil, 3, 4]
+ a[*[2]] ||= :foo
+ assert_equal [0, 1, :foo, 3, 4], a
+ a[*[1,3]] &&= [:bar]
+ assert_equal [0, :bar, 4], a
+ end
+
+ def test_opassign_and_or
+ a = 1
+ a ||= 2
+ assert_equal 1, a
+ a = nil
+ a ||= 2
+ assert_equal 2, a
+ a = 1
+ a &&= 3
+ assert_equal 3, a
+ a = nil
+ a &&= 4
+ assert_nil a
+
+ h = {}
+ h[0] ||= 1
+ assert_equal 1, h[0]
+ h = {}
+ h[0] &&= 1
+ assert_nil h[0]
+ h = {0 => 7}
+ h[0] ||= 1
+ assert_equal 7, h[0]
+ h = {0 => 7}
+ h[0] &&= 1
+ assert_equal 1, h[0]
+ end
+
+ def test_backref
+ /a(b)(c)d/ =~ 'xyzabcdefgabcdefg'
+ assert_equal 'b', $1
+ assert_equal 'c', $2
+ assert_nil $3
+ assert_instance_of MatchData, $~
+ assert_equal 'abcd', $&
+ assert_equal 'xyz', $`
+ assert_equal 'efgabcdefg', $'
+ assert_equal 'c', $+
+
+ /(?!)/ =~ 'xyzabcdefgabcdefg'
+ assert_nil $1
+ assert_nil $2
+ assert_nil $3
+ assert_nil $~
+ assert_nil $&
+ assert_nil $`
+ assert_nil $'
+ assert_nil $+
+ end
+
+ def test_fact
+ assert_equal 306057512216440636035370461297268629388588804173576999416776741259476533176716867465515291422477573349939147888701726368864263907759003154226842927906974559841225476930271954604008012215776252176854255965356903506788725264321896264299365204576448830388909753943489625436053225980776521270822437639449120128678675368305712293681943649956460498166450227716500185176546469340112226034729724066333258583506870150169794168850353752137554910289126407157154830282284937952636580145235233156936482233436799254594095276820608062232812387383880817049600000000000000000000000000000000000000000000000000000000000000000000000000, fact(300)
+ end
+
+ def fact(n)
+ if n > 1
+ n * fact(n - 1)
+ else
+ 1
+ end
+ end
+
+ def test_mul
+ assert_equal 0, 2 * 0
+ assert_equal 0, 0 * 2
+ assert_equal 4, 2 * 2
+ end
+
+ class MyNum
+ def /(a)
+ a * 100
+ end
+ end
+
+ def test_div
+ assert_equal 1, 3 / 2
+ assert_equal 1.5, 3.0 / 2.0
+ assert_equal 300, MyNum.new / 3
+ end
+
+ class MyArr
+ def length
+ 'string'
+ end
+ end
+
+ def test_length
+ assert_equal 0, [].length
+ assert_equal 1, [1].length
+ assert_equal 2, [1,2].length
+ assert_equal 0, {}.length
+ assert_equal 1, {1=>1}.length
+ assert_equal 2, {1=>1, 2=>2}.length
+ assert_equal 'string', MyArr.new.length
+ end
+
+ class MyNum2
+ def %(a)
+ a * 100
+ end
+ end
+
+ def test_mod
+ assert_equal 2, 5 % 3
+ assert_equal 1.0, 3.0 % 2.0
+ assert_equal 300, MyNum2.new % 3
+ end
+
+ class MyObj
+ def [](*args)
+ args
+ end
+
+ def []=(*args)
+ args
+ end
+ end
+
+ def test_aref
+ a = [0,1]
+ assert_equal 0, a[0]
+ assert_equal 1, a[1]
+ assert_nil a[2]
+ h = {0=>0, 1=>1}
+ obj = MyObj.new
+ assert_equal 0, h[0]
+ assert_equal 1, h[1]
+ assert_nil h[2]
+ assert_equal [0], obj[0]
+ assert_equal [0,1], obj[0,1]
+ assert_equal [0,1,2], obj[0,1,2]
+ end
+
+ def test_aset
+ obj = MyObj.new
+ assert_equal 7, (obj[0] = 7)
+ assert_equal 7, (obj[0,1] = 7)
+ assert_equal 7, (obj[0,1,2] = 7)
+ end
+
+ class MyObj2
+ def attr=(*args)
+ args
+ end
+ end
+
+ def test_attr_setter
+ obj = MyObj2.new
+ assert_equal 1, (obj.attr = 1)
+ end
+
+ def test_list_expand
+ a = []
+ assert_equal [0], [0, *a]
+ a = [1]
+ assert_equal [0,1], [0, *a]
+ a = [1,2]
+ assert_equal [0,1,2], [0, *a]
+ a = [1,2,3]
+ assert_equal [0,1,2,3], [0, *a]
+ #a = [1,2,3]
+ #assert_equal [0,1,2,3,4], [0, *a, 4]
+ end
+
+ def test_concatarray_ruby_dev_41933
+ bug3658 = '[ruby-dev:41933]'
+ [0, *x=1]
+ assert_equal(1, x, bug3658)
+ [0, *x=1, 2]
+ assert_equal(1, x, bug3658)
+ class << (x = Object.new)
+ attr_accessor :to_a_called
+ def to_a
+ @to_a_called = true
+ [self]
+ end
+ end
+ x.to_a_called = false
+ [0, *x]
+ assert(x.to_a_called, bug3658)
+ x.to_a_called = false
+ [0, *x, 2]
+ assert(x.to_a_called, bug3658)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_proc.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_proc.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_proc.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,795 @@
+require 'test/unit'
+
+class TestProc < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_proc
+ p1 = proc{|i| i}
+ assert_equal(2, p1.call(2))
+ assert_equal(3, p1.call(3))
+
+ p1 = proc{|i| i*2}
+ assert_equal(4, p1.call(2))
+ assert_equal(6, p1.call(3))
+
+ p2 = nil
+ x=0
+
+ proc{
+ iii=5 # nested local variable
+ p1 = proc{|i|
+ iii = i
+ }
+ p2 = proc {
+ x = iii # nested variables shared by procs
+ }
+ # scope of nested variables
+ assert(defined?(iii))
+ }.call
+ assert(!defined?(iii)) # out of scope
+
+ loop{iii=5; assert(eval("defined? iii")); break}
+ loop {
+ iii = 10
+ def self.dyna_var_check
+ loop {
+ assert(!defined?(iii))
+ break
+ }
+ end
+ dyna_var_check
+ break
+ }
+ p1.call(5)
+ p2.call
+ assert_equal(5, x)
+ end
+
+ def assert_arity(n)
+ meta = class << self; self; end
+ meta.class_eval {define_method(:foo, Proc.new)}
+ assert_equal(n, method(:foo).arity)
+ end
+
+ def test_arity
+ assert_equal(0, proc{}.arity)
+ assert_equal(0, proc{||}.arity)
+ assert_equal(1, proc{|x|}.arity)
+ assert_equal(2, proc{|x, y|}.arity)
+ assert_equal(-2, proc{|x, *y|}.arity)
+ assert_equal(-1, proc{|*x|}.arity)
+ assert_equal(-1, proc{|*|}.arity)
+ assert_equal(-3, proc{|x, *y, z|}.arity)
+ assert_equal(-4, proc{|x, *y, z, a|}.arity)
+
+ assert_arity(0) {}
+ assert_arity(0) {||}
+ assert_arity(1) {|x|}
+ assert_arity(2) {|x, y|}
+ assert_arity(-2) {|x, *y|}
+ assert_arity(-3) {|x, *y, z|}
+ assert_arity(-1) {|*x|}
+ assert_arity(-1) {|*|}
+ end
+
+ def m(x)
+ lambda { x }
+ end
+
+ def test_eq
+ a = m(1)
+ b = m(2)
+ assert_not_equal(a, b, "[ruby-dev:22592]")
+ assert_not_equal(a.call, b.call, "[ruby-dev:22592]")
+
+ assert_not_equal(proc {||}, proc {|x,y|}, "[ruby-dev:22599]")
+
+ a = lambda {|x| lambda {} }.call(1)
+ b = lambda {}
+ assert_not_equal(a, b, "[ruby-dev:22601]")
+ end
+
+ def test_block_par
+ assert_equal(10, Proc.new{|&b| b.call(10)}.call {|x| x})
+ assert_equal(12, Proc.new{|a,&b| b.call(a)}.call(12) {|x| x})
+ end
+
+ def test_safe
+ safe = $SAFE
+ c = Class.new
+ x = c.new
+
+ p = proc {
+ $SAFE += 1
+ proc {$SAFE}
+ }.call
+ assert_equal(safe, $SAFE)
+ assert_equal(safe + 1, p.call)
+ assert_equal(safe, $SAFE)
+
+ c.class_eval {define_method(:safe, p)}
+ assert_equal(safe, x.safe)
+ assert_equal(safe, x.method(:safe).call)
+ assert_equal(safe, x.method(:safe).to_proc.call)
+
+ p = proc {$SAFE += 1}
+ assert_equal(safe + 1, p.call)
+ assert_equal(safe, $SAFE)
+
+ c.class_eval {define_method(:inc, p)}
+ assert_equal(safe + 1, proc {x.inc; $SAFE}.call)
+ assert_equal(safe, $SAFE)
+ assert_equal(safe + 1, proc {x.method(:inc).call; $SAFE}.call)
+ assert_equal(safe, $SAFE)
+ assert_equal(safe + 1, proc {x.method(:inc).to_proc.call; $SAFE}.call)
+ assert_equal(safe, $SAFE)
+ end
+
+ def m2
+ "OK"
+ end
+
+ def block
+ method(:m2).to_proc
+ end
+
+ # [yarv-dev:777] block made by Method#to_proc
+ def test_method_to_proc
+ b = block()
+ assert_equal "OK", b.call
+ assert_instance_of(Binding, b.binding, '[ruby-core:25589]')
+ end
+
+ def test_curry
+ b = proc {|x, y, z| (x||0) + (y||0) + (z||0) }
+ assert_equal(6, b.curry[1][2][3])
+ assert_equal(6, b.curry[1, 2][3, 4])
+ assert_equal(6, b.curry(5)[1][2][3][4][5])
+ assert_equal(6, b.curry(5)[1, 2][3, 4][5])
+ assert_equal(1, b.curry(1)[1])
+
+ b = proc {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) }
+ assert_equal(6, b.curry[1][2][3])
+ assert_equal(10, b.curry[1, 2][3, 4])
+ assert_equal(15, b.curry(5)[1][2][3][4][5])
+ assert_equal(15, b.curry(5)[1, 2][3, 4][5])
+ assert_equal(1, b.curry(1)[1])
+
+ b = lambda {|x, y, z| (x||0) + (y||0) + (z||0) }
+ assert_equal(6, b.curry[1][2][3])
+ assert_raise(ArgumentError) { b.curry[1, 2][3, 4] }
+ assert_raise(ArgumentError) { b.curry(5) }
+ assert_raise(ArgumentError) { b.curry(1) }
+
+ b = lambda {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) }
+ assert_equal(6, b.curry[1][2][3])
+ assert_equal(10, b.curry[1, 2][3, 4])
+ assert_equal(15, b.curry(5)[1][2][3][4][5])
+ assert_equal(15, b.curry(5)[1, 2][3, 4][5])
+ assert_raise(ArgumentError) { b.curry(1) }
+
+ b = proc { :foo }
+ assert_equal(:foo, b.curry[])
+
+ b = lambda {|x, y, &blk| blk.call(x + y) }.curry
+ b = b.call(2) { raise }
+ b = b.call(3) {|x| x + 4 }
+ assert_equal(9, b)
+
+ l = proc {}
+ assert_equal(false, l.lambda?)
+ assert_equal(false, l.curry.lambda?, '[ruby-core:24127]')
+ l = lambda {}
+ assert_equal(true, l.lambda?)
+ assert_equal(true, l.curry.lambda?, '[ruby-core:24127]')
+ end
+
+ def test_curry_ski_fib
+ s = proc {|f, g, x| f[x][g[x]] }.curry
+ k = proc {|x, y| x }.curry
+ i = proc {|x| x }.curry
+
+ fib = []
+ inc = proc {|x| fib[-1] += 1; x }.curry
+ ret = proc {|x| throw :end if fib.size > 10; fib << 0; x }.curry
+
+ catch(:end) do
+ s[
+ s[s[i][i]][k[i]]
+ ][
+ k[inc]
+ ][
+ s[
+ s[
+ k[s]
+ ][
+ s[k[s[k[s]]]
+ ][
+ s[s[k[s]][s[k[s[k[ret]]]][s[k[s[i]]][k]]]][k]]
+ ]
+ ][
+ k[s[k[s]][k]]
+ ]
+ ]
+ end
+
+ assert_equal(fib, [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89])
+ end
+
+ def test_curry_from_knownbug
+ a = lambda {|x, y, &b| b }
+ b = a.curry[1]
+
+ assert_equal(:ok,
+ if b.call(2){} == nil
+ :ng
+ else
+ :ok
+ end, 'moved from btest/knownbug, [ruby-core:15551]')
+ end
+
+ def test_dup_clone
+ b = proc {|x| x + "bar" }
+ class << b; attr_accessor :foo; end
+
+ bd = b.dup
+ assert_equal("foobar", bd.call("foo"))
+ assert_raise(NoMethodError) { bd.foo = :foo }
+ assert_raise(NoMethodError) { bd.foo }
+
+ bc = b.clone
+ assert_equal("foobar", bc.call("foo"))
+ bc.foo = :foo
+ assert_equal(:foo, bc.foo)
+ end
+
+ def test_binding
+ b = proc {|x, y, z| proc {}.binding }.call(1, 2, 3)
+ class << b; attr_accessor :foo; end
+
+ bd = b.dup
+ assert_equal([1, 2, 3], bd.eval("[x, y, z]"))
+ assert_raise(NoMethodError) { bd.foo = :foo }
+ assert_raise(NoMethodError) { bd.foo }
+
+ bc = b.clone
+ assert_equal([1, 2, 3], bc.eval("[x, y, z]"))
+ bc.foo = :foo
+ assert_equal(:foo, bc.foo)
+
+ b = nil
+ 1.times { x, y, z = 1, 2, 3; b = binding }
+ assert_equal([1, 2, 3], b.eval("[x, y, z]"))
+ end
+
+ def test_proc_lambda
+ assert_raise(ArgumentError) { proc }
+ assert_raise(ArgumentError) { lambda }
+
+ o = Object.new
+ def o.foo
+ b = nil
+ 1.times { b = lambda }
+ b
+ end
+ assert_equal(:foo, o.foo { :foo }.call)
+
+ def o.foo(&b)
+ b = nil
+ 1.times { b = lambda }
+ b
+ end
+ assert_equal(:foo, o.foo { :foo }.call)
+ end
+
+ def test_arity2
+ assert_equal(0, method(:proc).to_proc.arity)
+ assert_equal(-1, proc {}.curry.arity)
+
+ c = Class.new
+ c.class_eval { attr_accessor :foo }
+ assert_equal(1, c.new.method(:foo=).to_proc.arity)
+ end
+
+ def test_proc_location
+ t = Thread.new { sleep }
+ assert_raise(ThreadError) { t.instance_eval { initialize { } } }
+ t.kill
+ end
+
+ def test_eq2
+ b1 = proc { }
+ b2 = b1.dup
+ assert(b1 == b2)
+ end
+
+ def test_to_proc
+ b = proc { :foo }
+ assert_equal(:foo, b.to_proc.call)
+ end
+
+ def test_localjump_error
+ o = Object.new
+ def foo; yield; end
+ exc = foo rescue $!
+ assert_nil(exc.exit_value)
+ assert_equal(:noreason, exc.reason)
+ end
+
+ def test_binding2
+ assert_raise(ArgumentError) { proc {}.curry.binding }
+ end
+
+ def test_proc_args_plain
+ pr = proc {|a,b,c,d,e|
+ [a,b,c,d,e]
+ }
+ assert_equal [nil,nil,nil,nil,nil], pr.call()
+ assert_equal [1,nil,nil,nil,nil], pr.call(1)
+ assert_equal [1,2,nil,nil,nil], pr.call(1,2)
+ assert_equal [1,2,3,nil,nil], pr.call(1,2,3)
+ assert_equal [1,2,3,4,nil], pr.call(1,2,3,4)
+ assert_equal [1,2,3,4,5], pr.call(1,2,3,4,5)
+ assert_equal [1,2,3,4,5], pr.call(1,2,3,4,5,6)
+
+ assert_equal [nil,nil,nil,nil,nil], pr.call([])
+ assert_equal [1,nil,nil,nil,nil], pr.call([1])
+ assert_equal [1,2,nil,nil,nil], pr.call([1,2])
+ assert_equal [1,2,3,nil,nil], pr.call([1,2,3])
+ assert_equal [1,2,3,4,nil], pr.call([1,2,3,4])
+ assert_equal [1,2,3,4,5], pr.call([1,2,3,4,5])
+ assert_equal [1,2,3,4,5], pr.call([1,2,3,4,5,6])
+
+ r = proc{|a| a}.call([1,2,3])
+ assert_equal [1,2,3], r
+
+ r = proc{|a,| a}.call([1,2,3])
+ assert_equal 1, r
+
+ r = proc{|a,| a}.call([])
+ assert_equal nil, r
+ end
+
+
+ def test_proc_args_rest
+ pr = proc {|a,b,c,*d|
+ [a,b,c,d]
+ }
+ assert_equal [nil,nil,nil,[]], pr.call()
+ assert_equal [1,nil,nil,[]], pr.call(1)
+ assert_equal [1,2,nil,[]], pr.call(1,2)
+ assert_equal [1,2,3,[]], pr.call(1,2,3)
+ assert_equal [1,2,3,[4]], pr.call(1,2,3,4)
+ assert_equal [1,2,3,[4,5]], pr.call(1,2,3,4,5)
+ assert_equal [1,2,3,[4,5,6]], pr.call(1,2,3,4,5,6)
+
+ assert_equal [nil,nil,nil,[]], pr.call([])
+ assert_equal [1,nil,nil,[]], pr.call([1])
+ assert_equal [1,2,nil,[]], pr.call([1,2])
+ assert_equal [1,2,3,[]], pr.call([1,2,3])
+ assert_equal [1,2,3,[4]], pr.call([1,2,3,4])
+ assert_equal [1,2,3,[4,5]], pr.call([1,2,3,4,5])
+ assert_equal [1,2,3,[4,5,6]], pr.call([1,2,3,4,5,6])
+
+ r = proc{|*a| a}.call([1,2,3])
+ assert_equal [[1,2,3]], r
+ end
+
+ def test_proc_args_rest_and_post
+ pr = proc {|a,b,*c,d,e|
+ [a,b,c,d,e]
+ }
+ assert_equal [nil, nil, [], nil, nil], pr.call()
+ assert_equal [1, nil, [], nil, nil], pr.call(1)
+ assert_equal [1, 2, [], nil, nil], pr.call(1,2)
+ assert_equal [1, 2, [], 3, nil], pr.call(1,2,3)
+ assert_equal [1, 2, [], 3, 4], pr.call(1,2,3,4)
+ assert_equal [1, 2, [3], 4, 5], pr.call(1,2,3,4,5)
+ assert_equal [1, 2, [3, 4], 5, 6], pr.call(1,2,3,4,5,6)
+ assert_equal [1, 2, [3, 4, 5], 6,7], pr.call(1,2,3,4,5,6,7)
+
+ assert_equal [nil, nil, [], nil, nil], pr.call([])
+ assert_equal [1, nil, [], nil, nil], pr.call([1])
+ assert_equal [1, 2, [], nil, nil], pr.call([1,2])
+ assert_equal [1, 2, [], 3, nil], pr.call([1,2,3])
+ assert_equal [1, 2, [], 3, 4], pr.call([1,2,3,4])
+ assert_equal [1, 2, [3], 4, 5], pr.call([1,2,3,4,5])
+ assert_equal [1, 2, [3, 4], 5, 6], pr.call([1,2,3,4,5,6])
+ assert_equal [1, 2, [3, 4, 5], 6,7], pr.call([1,2,3,4,5,6,7])
+ end
+
+ def test_proc_args_opt
+ pr = proc {|a,b,c=:c|
+ [a,b,c]
+ }
+ assert_equal [nil, nil, :c], pr.call()
+ assert_equal [1, nil, :c], pr.call(1)
+ assert_equal [1, 2, :c], pr.call(1,2)
+ assert_equal [1, 2, 3], pr.call(1,2,3)
+ assert_equal [1, 2, 3], pr.call(1,2,3,4)
+ assert_equal [1, 2, 3], pr.call(1,2,3,4,5)
+ assert_equal [1, 2, 3], pr.call(1,2,3,4,5,6)
+
+ assert_equal [nil, nil, :c], pr.call([])
+ assert_equal [1, nil, :c], pr.call([1])
+ assert_equal [1, 2, :c], pr.call([1,2])
+ assert_equal [1, 2, 3], pr.call([1,2,3])
+ assert_equal [1, 2, 3], pr.call([1,2,3,4])
+ assert_equal [1, 2, 3], pr.call([1,2,3,4,5])
+ assert_equal [1, 2, 3], pr.call([1,2,3,4,5,6])
+ end
+
+ def test_proc_args_opt_and_post
+ pr = proc {|a,b,c=:c,d,e|
+ [a,b,c,d,e]
+ }
+ assert_equal [nil, nil, :c, nil, nil], pr.call()
+ assert_equal [1, nil, :c, nil, nil], pr.call(1)
+ assert_equal [1, 2, :c, nil, nil], pr.call(1,2)
+ assert_equal [1, 2, :c, 3, nil], pr.call(1,2,3)
+ assert_equal [1, 2, :c, 3, 4], pr.call(1,2,3,4)
+ assert_equal [1, 2, 3, 4, 5], pr.call(1,2,3,4,5)
+ assert_equal [1, 2, 3, 4, 5], pr.call(1,2,3,4,5,6)
+
+ assert_equal [nil, nil, :c, nil, nil], pr.call([])
+ assert_equal [1, nil, :c, nil, nil], pr.call([1])
+ assert_equal [1, 2, :c, nil, nil], pr.call([1,2])
+ assert_equal [1, 2, :c, 3, nil], pr.call([1,2,3])
+ assert_equal [1, 2, :c, 3, 4], pr.call([1,2,3,4])
+ assert_equal [1, 2, 3, 4, 5], pr.call([1,2,3,4,5])
+ assert_equal [1, 2, 3, 4, 5], pr.call([1,2,3,4,5,6])
+ end
+
+ def test_proc_args_opt_and_rest
+ pr = proc {|a,b,c=:c,*d|
+ [a,b,c,d]
+ }
+ assert_equal [nil, nil, :c, []], pr.call()
+ assert_equal [1, nil, :c, []], pr.call(1)
+ assert_equal [1, 2, :c, []], pr.call(1,2)
+ assert_equal [1, 2, 3, []], pr.call(1,2,3)
+ assert_equal [1, 2, 3, [4]], pr.call(1,2,3,4)
+ assert_equal [1, 2, 3, [4, 5]], pr.call(1,2,3,4,5)
+
+ assert_equal [nil, nil, :c, []], pr.call([])
+ assert_equal [1, nil, :c, []], pr.call([1])
+ assert_equal [1, 2, :c, []], pr.call([1,2])
+ assert_equal [1, 2, 3, []], pr.call([1,2,3])
+ assert_equal [1, 2, 3, [4]], pr.call([1,2,3,4])
+ assert_equal [1, 2, 3, [4, 5]], pr.call([1,2,3,4,5])
+ end
+
+ def test_proc_args_opt_and_rest_and_post
+ pr = proc {|a,b,c=:c,*d,e|
+ [a,b,c,d,e]
+ }
+ assert_equal [nil, nil, :c, [], nil], pr.call()
+ assert_equal [1, nil, :c, [], nil], pr.call(1)
+ assert_equal [1, 2, :c, [], nil], pr.call(1,2)
+ assert_equal [1, 2, :c, [], 3], pr.call(1,2,3)
+ assert_equal [1, 2, 3, [], 4], pr.call(1,2,3,4)
+ assert_equal [1, 2, 3, [4], 5], pr.call(1,2,3,4,5)
+ assert_equal [1, 2, 3, [4,5], 6], pr.call(1,2,3,4,5,6)
+
+ assert_equal [nil, nil, :c, [], nil], pr.call([])
+ assert_equal [1, nil, :c, [], nil], pr.call([1])
+ assert_equal [1, 2, :c, [], nil], pr.call([1,2])
+ assert_equal [1, 2, :c, [], 3], pr.call([1,2,3])
+ assert_equal [1, 2, 3, [], 4], pr.call([1,2,3,4])
+ assert_equal [1, 2, 3, [4], 5], pr.call([1,2,3,4,5])
+ assert_equal [1, 2, 3, [4,5], 6], pr.call([1,2,3,4,5,6])
+ end
+
+ def test_proc_args_block
+ pr = proc {|a,b,&c|
+ [a, b, c.class, c&&c.call(:x)]
+ }
+ assert_equal [nil, nil, NilClass, nil], pr.call()
+ assert_equal [1, nil, NilClass, nil], pr.call(1)
+ assert_equal [1, 2, NilClass, nil], pr.call(1,2)
+ assert_equal [1, 2, NilClass, nil], pr.call(1,2,3)
+ assert_equal [1, 2, NilClass, nil], pr.call(1,2,3,4)
+
+ assert_equal [nil, nil, Proc, :proc], (pr.call(){ :proc })
+ assert_equal [1, nil, Proc, :proc], (pr.call(1){ :proc })
+ assert_equal [1, 2, Proc, :proc], (pr.call(1, 2){ :proc })
+ assert_equal [1, 2, Proc, :proc], (pr.call(1, 2, 3){ :proc })
+ assert_equal [1, 2, Proc, :proc], (pr.call(1, 2, 3, 4){ :proc })
+
+ assert_equal [nil, nil, Proc, :x], (pr.call(){|x| x})
+ assert_equal [1, nil, Proc, :x], (pr.call(1){|x| x})
+ assert_equal [1, 2, Proc, :x], (pr.call(1, 2){|x| x})
+ assert_equal [1, 2, Proc, :x], (pr.call(1, 2, 3){|x| x})
+ assert_equal [1, 2, Proc, :x], (pr.call(1, 2, 3, 4){|x| x})
+ end
+
+ def test_proc_args_rest_and_block
+ pr = proc {|a,b,*c,&d|
+ [a, b, c, d.class, d&&d.call(:x)]
+ }
+ assert_equal [nil, nil, [], NilClass, nil], pr.call()
+ assert_equal [1, nil, [], NilClass, nil], pr.call(1)
+ assert_equal [1, 2, [], NilClass, nil], pr.call(1,2)
+ assert_equal [1, 2, [3], NilClass, nil], pr.call(1,2,3)
+ assert_equal [1, 2, [3,4], NilClass, nil], pr.call(1,2,3,4)
+
+ assert_equal [nil, nil, [], Proc, :proc], (pr.call(){ :proc })
+ assert_equal [1, nil, [], Proc, :proc], (pr.call(1){ :proc })
+ assert_equal [1, 2, [], Proc, :proc], (pr.call(1, 2){ :proc })
+ assert_equal [1, 2, [3], Proc, :proc], (pr.call(1, 2, 3){ :proc })
+ assert_equal [1, 2, [3,4], Proc, :proc], (pr.call(1, 2, 3, 4){ :proc })
+
+ assert_equal [nil, nil, [], Proc, :x], (pr.call(){|x| x})
+ assert_equal [1, nil, [], Proc, :x], (pr.call(1){|x| x})
+ assert_equal [1, 2, [], Proc, :x], (pr.call(1, 2){|x| x})
+ assert_equal [1, 2, [3], Proc, :x], (pr.call(1, 2, 3){|x| x})
+ assert_equal [1, 2, [3,4], Proc, :x], (pr.call(1, 2, 3, 4){|x| x})
+ end
+
+ def test_proc_args_rest_and_post_and_block
+ pr = proc {|a,b,*c,d,e,&f|
+ [a, b, c, d, e, f.class, f&&f.call(:x)]
+ }
+ assert_equal [nil, nil, [], nil, nil, NilClass, nil], pr.call()
+ assert_equal [1, nil, [], nil, nil, NilClass, nil], pr.call(1)
+ assert_equal [1, 2, [], nil, nil, NilClass, nil], pr.call(1,2)
+ assert_equal [1, 2, [], 3, nil, NilClass, nil], pr.call(1,2,3)
+ assert_equal [1, 2, [], 3, 4, NilClass, nil], pr.call(1,2,3,4)
+ assert_equal [1, 2, [3], 4, 5, NilClass, nil], pr.call(1,2,3,4,5)
+ assert_equal [1, 2, [3,4], 5, 6, NilClass, nil], pr.call(1,2,3,4,5,6)
+
+ assert_equal [nil, nil, [], nil, nil, Proc, :proc], (pr.call(){ :proc })
+ assert_equal [1, nil, [], nil, nil, Proc, :proc], (pr.call(1){ :proc })
+ assert_equal [1, 2, [], nil, nil, Proc, :proc], (pr.call(1, 2){ :proc })
+ assert_equal [1, 2, [], 3, nil, Proc, :proc], (pr.call(1, 2, 3){ :proc })
+ assert_equal [1, 2, [], 3, 4, Proc, :proc], (pr.call(1, 2, 3, 4){ :proc })
+ assert_equal [1, 2, [3], 4, 5, Proc, :proc], (pr.call(1, 2, 3, 4, 5){ :proc })
+ assert_equal [1, 2, [3,4], 5, 6, Proc, :proc], (pr.call(1, 2, 3, 4, 5, 6){ :proc })
+
+ assert_equal [nil, nil, [], nil, nil, Proc, :x], (pr.call(){|x| x})
+ assert_equal [1, nil, [], nil, nil, Proc, :x], (pr.call(1){|x| x})
+ assert_equal [1, 2, [], nil, nil, Proc, :x], (pr.call(1, 2){|x| x})
+ assert_equal [1, 2, [], 3, nil, Proc, :x], (pr.call(1, 2, 3){|x| x})
+ assert_equal [1, 2, [], 3, 4, Proc, :x], (pr.call(1, 2, 3, 4){|x| x})
+ assert_equal [1, 2, [3], 4, 5, Proc, :x], (pr.call(1, 2, 3, 4, 5){|x| x})
+ assert_equal [1, 2, [3,4], 5, 6, Proc, :x], (pr.call(1, 2, 3, 4, 5, 6){|x| x})
+ end
+
+ def test_proc_args_opt_and_block
+ pr = proc {|a,b,c=:c,d=:d,&e|
+ [a, b, c, d, e.class, e&&e.call(:x)]
+ }
+ assert_equal [nil, nil, :c, :d, NilClass, nil], pr.call()
+ assert_equal [1, nil, :c, :d, NilClass, nil], pr.call(1)
+ assert_equal [1, 2, :c, :d, NilClass, nil], pr.call(1,2)
+ assert_equal [1, 2, 3, :d, NilClass, nil], pr.call(1,2,3)
+ assert_equal [1, 2, 3, 4, NilClass, nil], pr.call(1,2,3,4)
+ assert_equal [1, 2, 3, 4, NilClass, nil], pr.call(1,2,3,4,5)
+
+ assert_equal [nil, nil, :c, :d, Proc, :proc], (pr.call(){ :proc })
+ assert_equal [1, nil, :c, :d, Proc, :proc], (pr.call(1){ :proc })
+ assert_equal [1, 2, :c, :d, Proc, :proc], (pr.call(1, 2){ :proc })
+ assert_equal [1, 2, 3, :d, Proc, :proc], (pr.call(1, 2, 3){ :proc })
+ assert_equal [1, 2, 3, 4, Proc, :proc], (pr.call(1, 2, 3, 4){ :proc })
+ assert_equal [1, 2, 3, 4, Proc, :proc], (pr.call(1, 2, 3, 4, 5){ :proc })
+
+ assert_equal [nil, nil, :c, :d, Proc, :x], (pr.call(){|x| x})
+ assert_equal [1, nil, :c, :d, Proc, :x], (pr.call(1){|x| x})
+ assert_equal [1, 2, :c, :d, Proc, :x], (pr.call(1, 2){|x| x})
+ assert_equal [1, 2, 3, :d, Proc, :x], (pr.call(1, 2, 3){|x| x})
+ assert_equal [1, 2, 3, 4, Proc, :x], (pr.call(1, 2, 3, 4){|x| x})
+ assert_equal [1, 2, 3, 4, Proc, :x], (pr.call(1, 2, 3, 4, 5){|x| x})
+ end
+
+ def test_proc_args_opt_and_post_and_block
+ pr = proc {|a,b,c=:c,d=:d,e,f,&g|
+ [a, b, c, d, e, f, g.class, g&&g.call(:x)]
+ }
+ assert_equal [nil, nil, :c, :d, nil, nil, NilClass, nil], pr.call()
+ assert_equal [1, nil, :c, :d, nil, nil, NilClass, nil], pr.call(1)
+ assert_equal [1, 2, :c, :d, nil, nil, NilClass, nil], pr.call(1,2)
+ assert_equal [1, 2, :c, :d, 3, nil, NilClass, nil], pr.call(1,2,3)
+ assert_equal [1, 2, :c, :d, 3, 4, NilClass, nil], pr.call(1,2,3,4)
+ assert_equal [1, 2, 3, :d, 4, 5, NilClass, nil], pr.call(1,2,3,4,5)
+ assert_equal [1, 2, 3, 4, 5, 6, NilClass, nil], pr.call(1,2,3,4,5,6)
+ assert_equal [1, 2, 3, 4, 5, 6, NilClass, nil], pr.call(1,2,3,4,5,6,7)
+
+ assert_equal [nil, nil, :c, :d, nil, nil, Proc, :proc], (pr.call(){ :proc })
+ assert_equal [1, nil, :c, :d, nil, nil, Proc, :proc], (pr.call(1){ :proc })
+ assert_equal [1, 2, :c, :d, nil, nil, Proc, :proc], (pr.call(1, 2){ :proc })
+ assert_equal [1, 2, :c, :d, 3, nil, Proc, :proc], (pr.call(1, 2, 3){ :proc })
+ assert_equal [1, 2, :c, :d, 3, 4, Proc, :proc], (pr.call(1, 2, 3, 4){ :proc })
+ assert_equal [1, 2, 3, :d, 4, 5, Proc, :proc], (pr.call(1, 2, 3, 4, 5){ :proc })
+ assert_equal [1, 2, 3, 4, 5, 6, Proc, :proc], (pr.call(1, 2, 3, 4, 5, 6){ :proc })
+ assert_equal [1, 2, 3, 4, 5, 6, Proc, :proc], (pr.call(1, 2, 3, 4, 5, 6, 7){ :proc })
+
+ assert_equal [nil, nil, :c, :d, nil, nil, Proc, :x], (pr.call(){|x| x})
+ assert_equal [1, nil, :c, :d, nil, nil, Proc, :x], (pr.call(1){|x| x})
+ assert_equal [1, 2, :c, :d, nil, nil, Proc, :x], (pr.call(1, 2){|x| x})
+ assert_equal [1, 2, :c, :d, 3, nil, Proc, :x], (pr.call(1, 2, 3){|x| x})
+ assert_equal [1, 2, :c, :d, 3, 4, Proc, :x], (pr.call(1, 2, 3, 4){|x| x})
+ assert_equal [1, 2, 3, :d, 4, 5, Proc, :x], (pr.call(1, 2, 3, 4, 5){|x| x})
+ assert_equal [1, 2, 3, 4, 5, 6, Proc, :x], (pr.call(1, 2, 3, 4, 5, 6){|x| x})
+ assert_equal [1, 2, 3, 4, 5, 6, Proc, :x], (pr.call(1, 2, 3, 4, 5, 6, 7){|x| x})
+ end
+
+ def test_proc_args_opt_and_block2
+ pr = proc {|a,b,c=:c,d=:d,*e,&f|
+ [a, b, c, d, e, f.class, f&&f.call(:x)]
+ }
+ assert_equal [nil, nil, :c, :d, [], NilClass, nil], pr.call()
+ assert_equal [1, nil, :c, :d, [], NilClass, nil], pr.call(1)
+ assert_equal [1, 2, :c, :d, [], NilClass, nil], pr.call(1,2)
+ assert_equal [1, 2, 3, :d, [], NilClass, nil], pr.call(1,2,3)
+ assert_equal [1, 2, 3, 4, [], NilClass, nil], pr.call(1,2,3,4)
+ assert_equal [1, 2, 3, 4, [5], NilClass, nil], pr.call(1,2,3,4,5)
+ assert_equal [1, 2, 3, 4, [5,6], NilClass, nil], pr.call(1,2,3,4,5,6)
+
+ assert_equal [nil, nil, :c, :d, [], Proc, :proc], (pr.call(){ :proc })
+ assert_equal [1, nil, :c, :d, [], Proc, :proc], (pr.call(1){ :proc })
+ assert_equal [1, 2, :c, :d, [], Proc, :proc], (pr.call(1, 2){ :proc })
+ assert_equal [1, 2, 3, :d, [], Proc, :proc], (pr.call(1, 2, 3){ :proc })
+ assert_equal [1, 2, 3, 4, [], Proc, :proc], (pr.call(1, 2, 3, 4){ :proc })
+ assert_equal [1, 2, 3, 4, [5], Proc, :proc], (pr.call(1, 2, 3, 4, 5){ :proc })
+ assert_equal [1, 2, 3, 4, [5,6], Proc, :proc], (pr.call(1, 2, 3, 4, 5, 6){ :proc })
+
+ assert_equal [nil, nil, :c, :d, [], Proc, :x], (pr.call(){|x| x})
+ assert_equal [1, nil, :c, :d, [], Proc, :x], (pr.call(1){|x| x})
+ assert_equal [1, 2, :c, :d, [], Proc, :x], (pr.call(1, 2){|x| x})
+ assert_equal [1, 2, 3, :d, [], Proc, :x], (pr.call(1, 2, 3){|x| x})
+ assert_equal [1, 2, 3, 4, [], Proc, :x], (pr.call(1, 2, 3, 4){|x| x})
+ assert_equal [1, 2, 3, 4, [5], Proc, :x], (pr.call(1, 2, 3, 4, 5){|x| x})
+ assert_equal [1, 2, 3, 4, [5,6], Proc, :x], (pr.call(1, 2, 3, 4, 5, 6){|x| x})
+ end
+
+ def test_proc_args_opt_and_rest_and_post_and_block
+ pr = proc {|a,b,c=:c,d=:d,*e,f,g,&h|
+ [a, b, c, d, e, f, g, h.class, h&&h.call(:x)]
+ }
+ assert_equal [nil, nil, :c, :d, [], nil, nil, NilClass, nil], pr.call()
+ assert_equal [1, nil, :c, :d, [], nil, nil, NilClass, nil], pr.call(1)
+ assert_equal [1, 2, :c, :d, [], nil, nil, NilClass, nil], pr.call(1,2)
+ assert_equal [1, 2, :c, :d, [], 3, nil, NilClass, nil], pr.call(1,2,3)
+ assert_equal [1, 2, :c, :d, [], 3, 4, NilClass, nil], pr.call(1,2,3,4)
+ assert_equal [1, 2, 3, :d, [], 4, 5, NilClass, nil], pr.call(1,2,3,4,5)
+ assert_equal [1, 2, 3, 4, [], 5, 6, NilClass, nil], pr.call(1,2,3,4,5,6)
+ assert_equal [1, 2, 3, 4, [5], 6, 7, NilClass, nil], pr.call(1,2,3,4,5,6,7)
+ assert_equal [1, 2, 3, 4, [5,6], 7, 8, NilClass, nil], pr.call(1,2,3,4,5,6,7,8)
+
+ assert_equal [nil, nil, :c, :d, [], nil, nil, Proc, :proc], (pr.call(){ :proc })
+ assert_equal [1, nil, :c, :d, [], nil, nil, Proc, :proc], (pr.call(1){ :proc })
+ assert_equal [1, 2, :c, :d, [], nil, nil, Proc, :proc], (pr.call(1, 2){ :proc })
+ assert_equal [1, 2, :c, :d, [], 3, nil, Proc, :proc], (pr.call(1, 2, 3){ :proc })
+ assert_equal [1, 2, :c, :d, [], 3, 4, Proc, :proc], (pr.call(1, 2, 3, 4){ :proc })
+ assert_equal [1, 2, 3, :d, [], 4, 5, Proc, :proc], (pr.call(1, 2, 3, 4, 5){ :proc })
+ assert_equal [1, 2, 3, 4, [], 5, 6, Proc, :proc], (pr.call(1, 2, 3, 4, 5, 6){ :proc })
+ assert_equal [1, 2, 3, 4, [5], 6, 7, Proc, :proc], (pr.call(1, 2, 3, 4, 5, 6, 7){ :proc })
+ assert_equal [1, 2, 3, 4, [5,6], 7, 8, Proc, :proc], (pr.call(1, 2, 3, 4, 5, 6, 7, 8){ :proc })
+
+ assert_equal [nil, nil, :c, :d, [], nil, nil, Proc, :x], (pr.call(){|x| x})
+ assert_equal [1, nil, :c, :d, [], nil, nil, Proc, :x], (pr.call(1){|x| x})
+ assert_equal [1, 2, :c, :d, [], nil, nil, Proc, :x], (pr.call(1, 2){|x| x})
+ assert_equal [1, 2, :c, :d, [], 3, nil, Proc, :x], (pr.call(1, 2, 3){|x| x})
+ assert_equal [1, 2, :c, :d, [], 3, 4, Proc, :x], (pr.call(1, 2, 3, 4){|x| x})
+ assert_equal [1, 2, 3, :d, [], 4, 5, Proc, :x], (pr.call(1, 2, 3, 4, 5){|x| x})
+ assert_equal [1, 2, 3, 4, [], 5, 6, Proc, :x], (pr.call(1, 2, 3, 4, 5, 6){|x| x})
+ assert_equal [1, 2, 3, 4, [5], 6, 7, Proc, :x], (pr.call(1, 2, 3, 4, 5, 6, 7){|x| x})
+ assert_equal [1, 2, 3, 4, [5,6], 7, 8, Proc, :x], (pr.call(1, 2, 3, 4, 5, 6, 7, 8){|x| x})
+ end
+
+ def test_proc_args_unleashed
+ r = proc {|a,b=1,*c,d,e|
+ [a,b,c,d,e]
+ }.call(1,2,3,4,5)
+ assert_equal([1,2,[3],4,5], r, "[ruby-core:19485]")
+ end
+
+ def test_parameters
+ assert_equal([], proc {}.parameters)
+ assert_equal([], proc {||}.parameters)
+ assert_equal([[:opt, :a]], proc {|a|}.parameters)
+ assert_equal([[:opt, :a], [:opt, :b]], proc {|a, b|}.parameters)
+ assert_equal([[:opt, :a], [:block, :b]], proc {|a=:a, &b|}.parameters)
+ assert_equal([[:opt, :a], [:opt, :b]], proc {|a, b=:b|}.parameters)
+ assert_equal([[:rest, :a]], proc {|*a|}.parameters)
+ assert_equal([[:opt, :a], [:rest, :b], [:block, :c]], proc {|a, *b, &c|}.parameters)
+ assert_equal([[:opt, :a], [:rest, :b], [:opt, :c]], proc {|a, *b, c|}.parameters)
+ assert_equal([[:opt, :a], [:rest, :b], [:opt, :c], [:block, :d]], proc {|a, *b, c, &d|}.parameters)
+ assert_equal([[:opt, :a], [:opt, :b], [:rest, :c], [:opt, :d], [:block, :e]], proc {|a, b=:b, *c, d, &e|}.parameters)
+ assert_equal([[:opt, nil], [:block, :b]], proc {|(a), &b|}.parameters)
+ assert_equal([[:opt, :a], [:opt, :b], [:opt, :c], [:opt, :d], [:rest, :e], [:opt, :f], [:opt, :g], [:block, :h]], proc {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters)
+
+ assert_equal([[:req]], method(:putc).parameters)
+ assert_equal([[:rest]], method(:p).parameters)
+ end
+
+ def pm0() end
+ def pm1(a) end
+ def pm2(a, b) end
+ def pmo1(a = :a, &b) end
+ def pmo2(a, b = :b) end
+ def pmo3(*a) end
+ def pmo4(a, *b, &c) end
+ def pmo5(a, *b, c) end
+ def pmo6(a, *b, c, &d) end
+ def pmo7(a, b = :b, *c, d, &e) end
+ def pma1((a), &b) end
+
+
+ def test_bound_parameters
+ assert_equal([], method(:pm0).to_proc.parameters)
+ assert_equal([[:req, :a]], method(:pm1).to_proc.parameters)
+ assert_equal([[:req, :a], [:req, :b]], method(:pm2).to_proc.parameters)
+ assert_equal([[:opt, :a], [:block, :b]], method(:pmo1).to_proc.parameters)
+ assert_equal([[:req, :a], [:opt, :b]], method(:pmo2).to_proc.parameters)
+ assert_equal([[:rest, :a]], method(:pmo3).to_proc.parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:block, :c]], method(:pmo4).to_proc.parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:req, :c]], method(:pmo5).to_proc.parameters)
+ assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], method(:pmo6).to_proc.parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], method(:pmo7).to_proc.parameters)
+ assert_equal([[:req], [:block, :b]], method(:pma1).to_proc.parameters)
+
+ assert_equal([], "".method(:upcase).to_proc.parameters)
+ assert_equal([[:rest]], "".method(:gsub).to_proc.parameters)
+ assert_equal([[:rest]], proc {}.curry.parameters)
+ end
+
+ def test_to_s
+ assert_match(/^#<Proc:0x\h+@#{ Regexp.quote(__FILE__) }:\d+>$/, proc {}.to_s)
+ assert_match(/^#<Proc:0x\h+@#{ Regexp.quote(__FILE__) }:\d+ \(lambda\)>$/, lambda {}.to_s)
+ assert_match(/^#<Proc:0x\h+ \(lambda\)>$/, method(:p).to_proc.to_s)
+ x = proc {}
+ x.taint
+ assert(x.to_s.tainted?)
+ end
+
+ @@line_of_source_location_test = __LINE__ + 1
+ def source_location_test a=1,
+ b=2
+ end
+
+ def test_source_location
+ file, lineno = method(:source_location_test).source_location
+ assert_match(/^#{ Regexp.quote(__FILE__) }$/, file)
+ assert_equal(@@line_of_source_location_test, lineno, 'Bug #2427')
+ end
+
+ @@line_of_attr_reader_source_location_test = __LINE__ + 3
+ @@line_of_attr_writer_source_location_test = __LINE__ + 3
+ @@line_of_attr_accessor_source_location_test = __LINE__ + 3
+ attr_reader :attr_reader_source_location_test
+ attr_writer :attr_writer_source_location_test
+ attr_accessor :attr_accessor_source_location_test
+
+ def test_attr_source_location
+ file, lineno = method(:attr_reader_source_location_test).source_location
+ assert_match(/^#{ Regexp.quote(__FILE__) }$/, file)
+ assert_equal(@@line_of_attr_reader_source_location_test, lineno)
+
+ file, lineno = method(:attr_writer_source_location_test=).source_location
+ assert_match(/^#{ Regexp.quote(__FILE__) }$/, file)
+ assert_equal(@@line_of_attr_writer_source_location_test, lineno)
+
+ file, lineno = method(:attr_accessor_source_location_test).source_location
+ assert_match(/^#{ Regexp.quote(__FILE__) }$/, file)
+ assert_equal(@@line_of_attr_accessor_source_location_test, lineno)
+
+ file, lineno = method(:attr_accessor_source_location_test=).source_location
+ assert_match(/^#{ Regexp.quote(__FILE__) }$/, file)
+ assert_equal(@@line_of_attr_accessor_source_location_test, lineno)
+ end
+
+ def test_splat_without_respond_to
+ def (obj = Object.new).respond_to?(m); false end
+ [obj].each do |a, b|
+ assert_equal([obj, nil], [a, b], '[ruby-core:24139]')
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_process.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_process.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_process.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1222 @@
+require 'test/unit'
+require 'tmpdir'
+require 'pathname'
+require_relative 'envutil'
+require 'rbconfig'
+
+class TestProcess < Test::Unit::TestCase
+ RUBY = EnvUtil.rubybin
+
+ def setup
+ Process.waitall
+ end
+
+ def teardown
+ Process.waitall
+ end
+
+ def write_file(filename, content)
+ File.open(filename, "w") {|f|
+ f << content
+ }
+ end
+
+ def with_tmpchdir
+ Dir.mktmpdir {|d|
+ d = Pathname.new(d).realpath.to_s
+ Dir.chdir(d) {
+ yield d
+ }
+ }
+ end
+
+ def run_in_child(str) # should be called in a temporary directory
+ write_file("test-script", str)
+ Process.wait spawn(RUBY, "test-script")
+ $?
+ end
+
+ def test_rlimit_availability
+ begin
+ Process.getrlimit(nil)
+ rescue NotImplementedError
+ assert_raise(NotImplementedError) { Process.setrlimit }
+ rescue TypeError
+ assert_raise(ArgumentError) { Process.setrlimit }
+ end
+ end
+
+ def rlimit_exist?
+ Process.getrlimit(nil)
+ rescue NotImplementedError
+ return false
+ rescue TypeError
+ return true
+ end
+
+ def test_rlimit_nofile
+ return unless rlimit_exist?
+ with_tmpchdir {
+ write_file 's', <<-"End"
+ result = 1
+ begin
+ Process.setrlimit(Process::RLIMIT_NOFILE, 0)
+ rescue Errno::EINVAL
+ result = 0
+ end
+ if result == 1
+ begin
+ IO.pipe
+ rescue Errno::EMFILE
+ result = 0
+ end
+ end
+ exit result
+ End
+ pid = spawn RUBY, "s"
+ Process.wait pid
+ assert_equal(0, $?.to_i, "#{$?}")
+ }
+ end
+
+ def test_rlimit_name
+ return unless rlimit_exist?
+ [
+ :AS, "AS",
+ :CORE, "CORE",
+ :CPU, "CPU",
+ :DATA, "DATA",
+ :FSIZE, "FSIZE",
+ :MEMLOCK, "MEMLOCK",
+ :NOFILE, "NOFILE",
+ :NPROC, "NPROC",
+ :RSS, "RSS",
+ :STACK, "STACK",
+ :SBSIZE, "SBSIZE",
+ ].each {|name|
+ if Process.const_defined? "RLIMIT_#{name}"
+ assert_nothing_raised { Process.getrlimit(name) }
+ else
+ assert_raise(ArgumentError) { Process.getrlimit(name) }
+ end
+ }
+ assert_raise(ArgumentError) { Process.getrlimit(:FOO) }
+ assert_raise(ArgumentError) { Process.getrlimit("FOO") }
+ end
+
+ def test_rlimit_value
+ return unless rlimit_exist?
+ assert_raise(ArgumentError) { Process.setrlimit(:CORE, :FOO) }
+ with_tmpchdir do
+ s = run_in_child(<<-'End')
+ cur, max = Process.getrlimit(:NOFILE)
+ Process.setrlimit(:NOFILE, [max-10, cur].min)
+ begin
+ Process.setrlimit(:NOFILE, :INFINITY)
+ rescue Errno::EPERM
+ exit false
+ end
+ End
+ assert_not_equal(0, s.exitstatus)
+ s = run_in_child(<<-'End')
+ cur, max = Process.getrlimit(:NOFILE)
+ Process.setrlimit(:NOFILE, [max-10, cur].min)
+ begin
+ Process.setrlimit(:NOFILE, "INFINITY")
+ rescue Errno::EPERM
+ exit false
+ end
+ End
+ assert_not_equal(0, s.exitstatus)
+ end
+ end
+
+ TRUECOMMAND = [RUBY, '-e', '']
+
+ def test_execopts_opts
+ assert_nothing_raised {
+ Process.wait Process.spawn(*TRUECOMMAND, {})
+ }
+ assert_raise(ArgumentError) {
+ Process.wait Process.spawn(*TRUECOMMAND, :foo => 100)
+ }
+ assert_raise(ArgumentError) {
+ Process.wait Process.spawn(*TRUECOMMAND, Process => 100)
+ }
+ end
+
+ def test_execopts_pgroup
+ skip "system(:pgroup) is not supported" if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ assert_nothing_raised { system(*TRUECOMMAND, :pgroup=>false) }
+
+ io = IO.popen([RUBY, "-e", "print Process.getpgrp"])
+ assert_equal(Process.getpgrp.to_s, io.read)
+ io.close
+
+ io = IO.popen([RUBY, "-e", "print Process.getpgrp", :pgroup=>true])
+ assert_equal(io.pid.to_s, io.read)
+ io.close
+
+ assert_raise(ArgumentError) { system(*TRUECOMMAND, :pgroup=>-1) }
+ assert_raise(Errno::EPERM) { Process.wait spawn(*TRUECOMMAND, :pgroup=>2) }
+
+ io1 = IO.popen([RUBY, "-e", "print Process.getpgrp", :pgroup=>true])
+ io2 = IO.popen([RUBY, "-e", "print Process.getpgrp", :pgroup=>io1.pid])
+ assert_equal(io1.pid.to_s, io1.read)
+ assert_equal(io1.pid.to_s, io2.read)
+ Process.wait io1.pid
+ Process.wait io2.pid
+ io1.close
+ io2.close
+ end
+
+ def test_execopts_rlimit
+ return unless rlimit_exist?
+ assert_raise(ArgumentError) { system(*TRUECOMMAND, :rlimit_foo=>0) }
+ assert_raise(ArgumentError) { system(*TRUECOMMAND, :rlimit_NOFILE=>0) }
+ assert_raise(ArgumentError) { system(*TRUECOMMAND, :rlimit_nofile=>[]) }
+ assert_raise(ArgumentError) { system(*TRUECOMMAND, :rlimit_nofile=>[1,2,3]) }
+
+ max = Process.getrlimit(:CORE).last
+
+ n = max
+ IO.popen([RUBY, "-e",
+ "p Process.getrlimit(:CORE)", :rlimit_core=>n]) {|io|
+ assert_equal("[#{n}, #{n}]\n", io.read)
+ }
+
+ n = 0
+ IO.popen([RUBY, "-e",
+ "p Process.getrlimit(:CORE)", :rlimit_core=>n]) {|io|
+ assert_equal("[#{n}, #{n}]\n", io.read)
+ }
+
+ n = max
+ IO.popen([RUBY, "-e",
+ "p Process.getrlimit(:CORE)", :rlimit_core=>[n]]) {|io|
+ assert_equal("[#{n}, #{n}]", io.read.chomp)
+ }
+
+ m, n = 0, max
+ IO.popen([RUBY, "-e",
+ "p Process.getrlimit(:CORE)", :rlimit_core=>[m,n]]) {|io|
+ assert_equal("[#{m}, #{n}]", io.read.chomp)
+ }
+
+ m, n = 0, 0
+ IO.popen([RUBY, "-e",
+ "p Process.getrlimit(:CORE)", :rlimit_core=>[m,n]]) {|io|
+ assert_equal("[#{m}, #{n}]", io.read.chomp)
+ }
+
+ n = max
+ IO.popen([RUBY, "-e",
+ "p Process.getrlimit(:CORE), Process.getrlimit(:CPU)",
+ :rlimit_core=>n, :rlimit_cpu=>3600]) {|io|
+ assert_equal("[#{n}, #{n}]\n[3600, 3600]", io.read.chomp)
+ }
+ end
+
+ MANDATORY_ENVS = %w[RUBYLIB]
+ case RbConfig::CONFIG['target_os']
+ when /linux/
+ MANDATORY_ENVS << 'LD_PRELOAD'
+ when /mswin|mingw/
+ MANDATORY_ENVS.concat(%w[HOME USER TMPDIR])
+ end
+ if e = RbConfig::CONFIG['LIBPATHENV']
+ MANDATORY_ENVS << e
+ end
+ PREENVARG = ['-e', "%w[#{MANDATORY_ENVS.join(' ')}].each{|e|ENV.delete(e)}"]
+ ENVARG = ['-e', 'ENV.each {|k,v| puts "#{k}=#{v}" }']
+ ENVCOMMAND = [RUBY].concat(PREENVARG).concat(ENVARG)
+
+ def test_execopts_env
+ skip("[BUG : #???] Abort")
+
+ assert_raise(ArgumentError) {
+ system({"F=O"=>"BAR"}, *TRUECOMMAND)
+ }
+
+ with_tmpchdir {|d|
+ prog = "#{d}/notexist"
+ e = assert_raise(Errno::ENOENT) {
+ Process.wait Process.spawn({"FOO"=>"BAR"}, prog)
+ }
+ assert_equal(prog, e.message.sub(/.* - /, ''))
+ e = assert_raise(Errno::ENOENT) {
+ Process.wait Process.spawn({"FOO"=>"BAR"}, [prog, "blar"])
+ }
+ assert_equal(prog, e.message.sub(/.* - /, ''))
+ }
+ h = {}
+ cmd = [h, RUBY]
+ (ENV.keys + MANDATORY_ENVS).each do |k|
+ case k
+ when /\APATH\z/i
+ when *MANDATORY_ENVS
+ cmd << '-e' << "ENV.delete('#{k}')"
+ else
+ h[k] = nil
+ end
+ end
+ cmd << '-e' << 'puts ENV.keys.map{|e|e.upcase}'
+ IO.popen(cmd) {|io|
+ assert_equal("PATH\n", io.read)
+ }
+
+ IO.popen([{"FOO"=>"BAR"}, *ENVCOMMAND]) {|io|
+ assert_match(/^FOO=BAR$/, io.read)
+ }
+
+ with_tmpchdir {|d|
+ system({"fofo"=>"haha"}, *ENVCOMMAND, STDOUT=>"out")
+ assert_match(/^fofo=haha$/, File.read("out").chomp)
+ }
+
+ old = ENV["hmm"]
+ begin
+ ENV["hmm"] = "fufu"
+ IO.popen(ENVCOMMAND) {|io| assert_match(/^hmm=fufu$/, io.read) }
+ IO.popen([{"hmm"=>""}, *ENVCOMMAND]) {|io| assert_match(/^hmm=$/, io.read) }
+ IO.popen([{"hmm"=>nil}, *ENVCOMMAND]) {|io| assert_not_match(/^hmm=/, io.read) }
+ ENV["hmm"] = ""
+ IO.popen(ENVCOMMAND) {|io| assert_match(/^hmm=$/, io.read) }
+ IO.popen([{"hmm"=>""}, *ENVCOMMAND]) {|io| assert_match(/^hmm=$/, io.read) }
+ IO.popen([{"hmm"=>nil}, *ENVCOMMAND]) {|io| assert_not_match(/^hmm=/, io.read) }
+ ENV["hmm"] = nil
+ IO.popen(ENVCOMMAND) {|io| assert_not_match(/^hmm=/, io.read) }
+ IO.popen([{"hmm"=>""}, *ENVCOMMAND]) {|io| assert_match(/^hmm=$/, io.read) }
+ IO.popen([{"hmm"=>nil}, *ENVCOMMAND]) {|io| assert_not_match(/^hmm=/, io.read) }
+ ensure
+ ENV["hmm"] = old
+ end
+ end
+
+ def test_execopts_unsetenv_others
+ h = {}
+ MANDATORY_ENVS.each {|k| e = ENV[k] and h[k] = e}
+ IO.popen([h, *ENVCOMMAND, :unsetenv_others=>true]) {|io|
+ assert_equal("", io.read)
+ }
+ IO.popen([h.merge("A"=>"B"), *ENVCOMMAND, :unsetenv_others=>true]) {|io|
+ assert_equal("A=B\n", io.read)
+ }
+ end
+
+ PWD = [RUBY, '-e', 'puts Dir.pwd']
+
+ def test_execopts_chdir
+ with_tmpchdir {|d|
+ IO.popen([*PWD, :chdir => d]) {|io|
+ assert_equal(d, io.read.chomp)
+ }
+ assert_raise(Errno::ENOENT) {
+ Process.wait Process.spawn(*PWD, :chdir => "d/notexist")
+ }
+ }
+ end
+
+ UMASK = [RUBY, '-e', 'printf "%04o\n", File.umask']
+
+ def test_execopts_umask
+ skip "umask is not supported" if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ IO.popen([*UMASK, :umask => 0]) {|io|
+ assert_equal("0000", io.read.chomp)
+ }
+ IO.popen([*UMASK, :umask => 0777]) {|io|
+ assert_equal("0777", io.read.chomp)
+ }
+ end
+
+ def with_pipe
+ begin
+ r, w = IO.pipe
+ yield r, w
+ ensure
+ r.close unless r.closed?
+ w.close unless w.closed?
+ end
+ end
+
+ def with_pipes(n)
+ ary = []
+ begin
+ n.times {
+ ary << IO.pipe
+ }
+ yield ary
+ ensure
+ ary.each {|r, w|
+ r.close unless r.closed?
+ w.close unless w.closed?
+ }
+ end
+ end
+
+ ECHO = lambda {|arg| [RUBY, '-e', "puts #{arg.dump}; STDOUT.flush"] }
+ SORT = [RUBY, '-e', "puts ARGF.readlines.sort"]
+ CAT = [RUBY, '-e', "IO.copy_stream STDIN, STDOUT"]
+
+ def test_execopts_redirect
+ with_tmpchdir {|d|
+ Process.wait Process.spawn(*ECHO["a"], STDOUT=>["out", File::WRONLY|File::CREAT|File::TRUNC, 0644])
+ assert_equal("a", File.read("out").chomp)
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ # currently telling to child the file modes is not supported.
+ open("out", "a") {|f| f.write "0\n"}
+ else
+ Process.wait Process.spawn(*ECHO["0"], STDOUT=>["out", File::WRONLY|File::CREAT|File::APPEND, 0644])
+ assert_equal("a\n0\n", File.read("out"))
+ end
+ Process.wait Process.spawn(*SORT, STDIN=>["out", File::RDONLY, 0644],
+ STDOUT=>["out2", File::WRONLY|File::CREAT|File::TRUNC, 0644])
+ assert_equal("0\na\n", File.read("out2"))
+ Process.wait Process.spawn(*ECHO["b"], [STDOUT, STDERR]=>["out", File::WRONLY|File::CREAT|File::TRUNC, 0644])
+ assert_equal("b", File.read("out").chomp)
+ # problem occur with valgrind
+ #Process.wait Process.spawn(*ECHO["a"], STDOUT=>:close, STDERR=>["out", File::WRONLY|File::CREAT|File::TRUNC, 0644])
+ #p File.read("out")
+ #assert(!File.read("out").empty?) # error message such as "-e:1:in `flush': Bad file descriptor (Errno::EBADF)"
+ Process.wait Process.spawn(*ECHO["c"], STDERR=>STDOUT, STDOUT=>["out", File::WRONLY|File::CREAT|File::TRUNC, 0644])
+ assert_equal("c", File.read("out").chomp)
+ File.open("out", "w") {|f|
+ Process.wait Process.spawn(*ECHO["d"], f=>STDOUT, STDOUT=>f)
+ assert_equal("d", File.read("out").chomp)
+ }
+ Process.wait Process.spawn(*ECHO["e"], STDOUT=>["out", File::WRONLY|File::CREAT|File::TRUNC, 0644],
+ 3=>STDOUT, 4=>STDOUT, 5=>STDOUT, 6=>STDOUT, 7=>STDOUT)
+ assert_equal("e", File.read("out").chomp)
+ Process.wait Process.spawn(*ECHO["ee"], STDOUT=>["out", File::WRONLY|File::CREAT|File::TRUNC, 0644],
+ 3=>0, 4=>:in, 5=>STDIN,
+ 6=>1, 7=>:out, 8=>STDOUT,
+ 9=>2, 10=>:err, 11=>STDERR)
+ assert_equal("ee", File.read("out").chomp)
+ if /mswin|mingw/ !~ RUBY_PLATFORM
+ # passing non-stdio fds is not supported on Windows
+ File.open("out", "w") {|f|
+ h = {STDOUT=>f, f=>STDOUT}
+ 3.upto(30) {|i| h[i] = STDOUT if f.fileno != i }
+ Process.wait Process.spawn(*ECHO["f"], h)
+ assert_equal("f", File.read("out").chomp)
+ }
+ end
+ assert_raise(ArgumentError) {
+ Process.wait Process.spawn(*ECHO["f"], 1=>Process)
+ }
+ assert_raise(ArgumentError) {
+ Process.wait Process.spawn(*ECHO["f"], [Process]=>1)
+ }
+ assert_raise(ArgumentError) {
+ Process.wait Process.spawn(*ECHO["f"], [1, STDOUT]=>2)
+ }
+ assert_raise(ArgumentError) {
+ Process.wait Process.spawn(*ECHO["f"], -1=>2)
+ }
+ Process.wait Process.spawn(*ECHO["hhh\nggg\n"], STDOUT=>"out")
+ assert_equal("hhh\nggg\n", File.read("out"))
+ Process.wait Process.spawn(*SORT, STDIN=>"out", STDOUT=>"out2")
+ assert_equal("ggg\nhhh\n", File.read("out2"))
+
+ if /mswin|mingw/ !~ RUBY_PLATFORM
+ # passing non-stdio fds is not supported on Windows
+ assert_raise(Errno::ENOENT) {
+ Process.wait Process.spawn("non-existing-command", (3..60).to_a=>["err", File::WRONLY|File::CREAT])
+ }
+ assert_equal("", File.read("err"))
+ end
+
+ system(*ECHO["bb\naa\n"], STDOUT=>["out", "w"])
+ assert_equal("bb\naa\n", File.read("out"))
+ system(*SORT, STDIN=>["out"], STDOUT=>"out2")
+ assert_equal("aa\nbb\n", File.read("out2"))
+
+ with_pipe {|r1, w1|
+ with_pipe {|r2, w2|
+ pid = spawn(*SORT, STDIN=>r1, STDOUT=>w2, w1=>:close, r2=>:close)
+ r1.close
+ w2.close
+ w1.puts "c"
+ w1.puts "a"
+ w1.puts "b"
+ w1.close
+ assert_equal("a\nb\nc\n", r2.read)
+ r2.close
+ Process.wait(pid)
+ }
+ }
+
+ if /mswin|mingw/ !~ RUBY_PLATFORM
+ # passing non-stdio fds is not supported on Windows
+ with_pipes(5) {|pipes|
+ ios = pipes.flatten
+ h = {}
+ ios.length.times {|i| h[ios[i]] = ios[(i-1)%ios.length] }
+ h2 = h.invert
+ rios = pipes.map {|r, w| r }
+ wios = pipes.map {|r, w| w }
+ child_wfds = wios.map {|w| h2[w].fileno }
+ pid = spawn(RUBY, "-e",
+ "[#{child_wfds.join(',')}].each {|fd| IO.new(fd, 'w').puts fd }", h)
+ pipes.each {|r, w|
+ assert_equal("#{h2[w].fileno}\n", r.gets)
+ }
+ Process.wait pid;
+ }
+
+ with_pipes(5) {|pipes|
+ ios = pipes.flatten
+ h = {}
+ ios.length.times {|i| h[ios[i]] = ios[(i+1)%ios.length] }
+ h2 = h.invert
+ rios = pipes.map {|r, w| r }
+ wios = pipes.map {|r, w| w }
+ child_wfds = wios.map {|w| h2[w].fileno }
+ pid = spawn(RUBY, "-e",
+ "[#{child_wfds.join(',')}].each {|fd| IO.new(fd, 'w').puts fd }", h)
+ pipes.each {|r, w|
+ assert_equal("#{h2[w].fileno}\n", r.gets)
+ }
+ Process.wait pid
+ }
+
+ closed_fd = nil
+ with_pipes(5) {|pipes|
+ io = pipes.last.last
+ closed_fd = io.fileno
+ }
+ assert_raise(Errno::EBADF) { Process.wait spawn(*TRUECOMMAND, closed_fd=>closed_fd) }
+
+ with_pipe {|r, w|
+ if w.respond_to?(:"close_on_exec=")
+ w.close_on_exec = true
+ pid = spawn(RUBY, "-e", "IO.new(#{w.fileno}, 'w').print 'a'", w=>w)
+ w.close
+ assert_equal("a", r.read)
+ Process.wait pid
+ end
+ }
+ end
+
+ system(*ECHO["funya"], :out=>"out")
+ assert_equal("funya\n", File.read("out"))
+ system(RUBY, '-e', 'STDOUT.reopen(STDERR); puts "henya"', :err=>"out")
+ assert_equal("henya\n", File.read("out"))
+ IO.popen([*CAT, :in=>"out"]) {|io|
+ assert_equal("henya\n", io.read)
+ }
+ }
+ end
+
+ def test_execopts_redirect_dup2_child
+ with_tmpchdir {|d|
+ Process.wait spawn(RUBY, "-e", "STDERR.print 'err'; STDOUT.print 'out'",
+ STDOUT=>"out", STDERR=>[:child, STDOUT])
+ assert_equal("errout", File.read("out"))
+
+ Process.wait spawn(RUBY, "-e", "STDERR.print 'err'; STDOUT.print 'out'",
+ STDERR=>"out", STDOUT=>[:child, STDERR])
+ assert_equal("errout", File.read("out"))
+
+ if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ skip "inheritance of fd other than stdin,stdout and stderr is not supported"
+ end
+ Process.wait spawn(RUBY, "-e", "STDERR.print 'err'; STDOUT.print 'out'",
+ STDOUT=>"out",
+ STDERR=>[:child, 3],
+ 3=>[:child, 4],
+ 4=>[:child, STDOUT]
+ )
+ assert_equal("errout", File.read("out"))
+
+ IO.popen([RUBY, "-e", "STDERR.print 'err'; STDOUT.print 'out'", STDERR=>[:child, STDOUT]]) {|io|
+ assert_equal("errout", io.read)
+ }
+
+ assert_raise(ArgumentError) { Process.wait spawn(*TRUECOMMAND, STDOUT=>[:child, STDOUT]) }
+ assert_raise(ArgumentError) { Process.wait spawn(*TRUECOMMAND, 3=>[:child, 4], 4=>[:child, 3]) }
+ assert_raise(ArgumentError) { Process.wait spawn(*TRUECOMMAND, 3=>[:child, 4], 4=>[:child, 5], 5=>[:child, 3]) }
+ assert_raise(ArgumentError) { Process.wait spawn(*TRUECOMMAND, STDOUT=>[:child, 3]) }
+ }
+ end
+
+ def test_execopts_exec
+ with_tmpchdir {|d|
+ write_file("s", 'exec "echo aaa", STDOUT=>"foo"')
+ pid = spawn RUBY, 's'
+ Process.wait pid
+ assert_equal("aaa\n", File.read("foo"))
+ }
+ end
+
+ def test_execopts_popen
+ with_tmpchdir {|d|
+ IO.popen("#{RUBY} -e 'puts :foo'") {|io| assert_equal("foo\n", io.read) }
+ assert_raise(Errno::ENOENT) { IO.popen(["echo bar"]) {} } # assuming "echo bar" command not exist.
+ IO.popen(ECHO["baz"]) {|io| assert_equal("baz\n", io.read) }
+ assert_raise(ArgumentError) {
+ IO.popen([*ECHO["qux"], STDOUT=>STDOUT]) {|io| }
+ }
+ IO.popen([*ECHO["hoge"], STDERR=>STDOUT]) {|io|
+ assert_equal("hoge\n", io.read)
+ }
+ assert_raise(ArgumentError) {
+ IO.popen([*ECHO["fuga"], STDOUT=>"out"]) {|io| }
+ }
+ if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ skip "inheritance of fd other than stdin,stdout and stderr is not supported"
+ end
+ with_pipe {|r, w|
+ IO.popen([RUBY, '-e', 'IO.new(3, "w").puts("a"); puts "b"', 3=>w]) {|io|
+ assert_equal("b\n", io.read)
+ }
+ w.close
+ assert_equal("a\n", r.read)
+ }
+ IO.popen([RUBY, '-e', "IO.new(9, 'w').puts(:b)",
+ 9=>["out2", File::WRONLY|File::CREAT|File::TRUNC]]) {|io|
+ assert_equal("", io.read)
+ }
+ assert_equal("b\n", File.read("out2"))
+ }
+ end
+
+ def test_popen_fork
+ return if /freebsd/ =~ RUBY_PLATFORM # this test freeze in FreeBSD
+ IO.popen("-") {|io|
+ if !io
+ puts "fooo"
+ else
+ assert_equal("fooo\n", io.read)
+ end
+ }
+ rescue NotImplementedError
+ end
+
+ def test_fd_inheritance
+ if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ skip "inheritance of fd other than stdin,stdout and stderr is not supported"
+ end
+ with_pipe {|r, w|
+ system(RUBY, '-e', 'IO.new(ARGV[0].to_i, "w").puts(:ba)', w.fileno.to_s)
+ w.close
+ assert_equal("ba\n", r.read)
+ }
+ with_pipe {|r, w|
+ Process.wait spawn(RUBY, '-e',
+ 'IO.new(ARGV[0].to_i, "w").puts("bi") rescue nil',
+ w.fileno.to_s)
+ w.close
+ assert_equal("", r.read)
+ }
+ with_pipe {|r, w|
+ with_tmpchdir {|d|
+ write_file("s", <<-"End")
+ exec(#{RUBY.dump}, '-e',
+ 'IO.new(ARGV[0].to_i, "w").puts("bu") rescue nil',
+ #{w.fileno.to_s.dump})
+ End
+ Process.wait spawn(RUBY, "s", :close_others=>false)
+ w.close
+ assert_equal("bu\n", r.read)
+ }
+ }
+ with_pipe {|r, w|
+ io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}, 'w').puts('me')"])
+ w.close
+ errmsg = io.read
+ assert_equal("", r.read)
+ assert_not_equal("", errmsg)
+ Process.wait
+ }
+ with_pipe {|r, w|
+ errmsg = `#{RUBY} -e "STDERR.reopen(STDOUT); IO.new(#{w.fileno}, 'w').puts(123)"`
+ w.close
+ assert_equal("", r.read)
+ assert_not_equal("", errmsg)
+ }
+ end
+
+ def test_execopts_close_others
+ if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ skip "inheritance of fd other than stdin,stdout and stderr is not supported"
+ end
+ with_tmpchdir {|d|
+ with_pipe {|r, w|
+ system(RUBY, '-e', 'STDERR.reopen("err", "w"); IO.new(ARGV[0].to_i, "w").puts("ma")', w.fileno.to_s, :close_others=>true)
+ w.close
+ assert_equal("", r.read)
+ assert_not_equal("", File.read("err"))
+ File.unlink("err")
+ }
+ with_pipe {|r, w|
+ Process.wait spawn(RUBY, '-e', 'STDERR.reopen("err", "w"); IO.new(ARGV[0].to_i, "w").puts("mi")', w.fileno.to_s, :close_others=>true)
+ w.close
+ assert_equal("", r.read)
+ assert_not_equal("", File.read("err"))
+ File.unlink("err")
+ }
+ with_pipe {|r, w|
+ Process.wait spawn(RUBY, '-e', 'IO.new(ARGV[0].to_i, "w").puts("bi")', w.fileno.to_s, :close_others=>false)
+ w.close
+ assert_equal("bi\n", r.read)
+ }
+ with_pipe {|r, w|
+ write_file("s", <<-"End")
+ exec(#{RUBY.dump}, '-e',
+ 'STDERR.reopen("err", "w"); IO.new(ARGV[0].to_i, "w").puts("mu")',
+ #{w.fileno.to_s.dump},
+ :close_others=>true)
+ End
+ Process.wait spawn(RUBY, "s", :close_others=>false)
+ w.close
+ assert_equal("", r.read)
+ assert_not_equal("", File.read("err"))
+ File.unlink("err")
+ }
+ with_pipe {|r, w|
+ io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}, 'w').puts('me')", :close_others=>true])
+ w.close
+ errmsg = io.read
+ assert_equal("", r.read)
+ assert_not_equal("", errmsg)
+ Process.wait
+ }
+ with_pipe {|r, w|
+ io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}, 'w').puts('mo')", :close_others=>false])
+ w.close
+ errmsg = io.read
+ assert_equal("mo\n", r.read)
+ assert_equal("", errmsg)
+ Process.wait
+ }
+ with_pipe {|r, w|
+ io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}, 'w').puts('mo')", :close_others=>nil])
+ w.close
+ errmsg = io.read
+ assert_equal("mo\n", r.read)
+ assert_equal("", errmsg)
+ Process.wait
+ }
+
+ }
+ end
+
+ def test_execopts_redirect_self
+ begin
+ with_pipe {|r, w|
+ w << "haha\n"
+ w.close
+ r.close_on_exec = true
+ IO.popen([RUBY, "-e", "print IO.new(#{r.fileno}, 'r').read", r.fileno=>r.fileno, :close_others=>false]) {|io|
+ assert_equal("haha\n", io.read)
+ }
+ }
+ rescue NotImplementedError
+ skip "IO#close_on_exec= is not supported"
+ end
+ end
+
+ def test_execopts_duplex_io
+ IO.popen("#{RUBY} -e ''", "r+") {|duplex|
+ assert_raise(ArgumentError) { system("#{RUBY} -e ''", duplex=>STDOUT) }
+ assert_raise(ArgumentError) { system("#{RUBY} -e ''", STDOUT=>duplex) }
+ }
+ end
+
+ def test_execopts_modification
+ h = {}
+ Process.wait spawn(*TRUECOMMAND, h)
+ assert_equal({}, h)
+
+ h = {}
+ system(*TRUECOMMAND, h)
+ assert_equal({}, h)
+
+ h = {}
+ io = IO.popen([*TRUECOMMAND, h])
+ io.close
+ assert_equal({}, h)
+ end
+
+ def test_system_noshell
+ str = "echo non existing command name which contains spaces"
+ assert_nil(system([str, str]))
+ end
+
+ def test_spawn_noshell
+ str = "echo non existing command name which contains spaces"
+ assert_raise(Errno::ENOENT) { spawn([str, str]) }
+ end
+
+ def test_popen_noshell
+ str = "echo non existing command name which contains spaces"
+ assert_raise(Errno::ENOENT) { IO.popen([str, str]) }
+ end
+
+ def test_exec_noshell
+ with_tmpchdir {|d|
+ write_file("s", <<-"End")
+ str = "echo non existing command name which contains spaces"
+ STDERR.reopen(STDOUT)
+ begin
+ exec [str, str]
+ rescue Errno::ENOENT
+ print "Errno::ENOENT success"
+ end
+ End
+ r = IO.popen([RUBY, "s", :close_others=>false], "r") {|f| f.read}
+ assert_equal("Errno::ENOENT success", r)
+ }
+ end
+
+ def test_system_wordsplit
+ with_tmpchdir {|d|
+ write_file("script", <<-'End')
+ File.open("result", "w") {|t| t << "haha pid=#{$$} ppid=#{Process.ppid}" }
+ exit 5
+ End
+ str = "#{RUBY} script"
+ ret = system(str)
+ status = $?
+ assert_equal(false, ret)
+ assert(status.exited?)
+ assert_equal(5, status.exitstatus)
+ assert_equal("haha pid=#{status.pid} ppid=#{$$}", File.read("result"))
+ }
+ end
+
+ def test_spawn_wordsplit
+ with_tmpchdir {|d|
+ write_file("script", <<-'End')
+ File.open("result", "w") {|t| t << "hihi pid=#{$$} ppid=#{Process.ppid}" }
+ exit 6
+ End
+ str = "#{RUBY} script"
+ pid = spawn(str)
+ Process.wait pid
+ status = $?
+ assert_equal(pid, status.pid)
+ assert(status.exited?)
+ assert_equal(6, status.exitstatus)
+ assert_equal("hihi pid=#{status.pid} ppid=#{$$}", File.read("result"))
+ }
+ end
+
+ def test_popen_wordsplit
+ with_tmpchdir {|d|
+ write_file("script", <<-'End')
+ print "fufu pid=#{$$} ppid=#{Process.ppid}"
+ exit 7
+ End
+ str = "#{RUBY} script"
+ io = IO.popen(str)
+ pid = io.pid
+ result = io.read
+ io.close
+ status = $?
+ assert_equal(pid, status.pid)
+ assert(status.exited?)
+ assert_equal(7, status.exitstatus)
+ assert_equal("fufu pid=#{status.pid} ppid=#{$$}", result)
+ }
+ end
+
+ def test_exec_wordsplit
+ with_tmpchdir {|d|
+ write_file("script", <<-'End')
+ File.open("result", "w") {|t|
+ if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ t << "hehe ppid=#{Process.ppid}"
+ else
+ t << "hehe pid=#{$$} ppid=#{Process.ppid}"
+ end
+ }
+ exit 6
+ End
+ write_file("s", <<-"End")
+ ruby = #{RUBY.dump}
+ exec "\#{ruby} script"
+ End
+ pid = spawn(RUBY, "s")
+ Process.wait pid
+ status = $?
+ assert_equal(pid, status.pid)
+ assert(status.exited?)
+ assert_equal(6, status.exitstatus)
+ if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ expected = "hehe ppid=#{status.pid}"
+ else
+ expected = "hehe pid=#{status.pid} ppid=#{$$}"
+ end
+ assert_equal(expected, File.read("result"))
+ }
+ end
+
+ def test_system_shell
+ with_tmpchdir {|d|
+ write_file("script1", <<-'End')
+ File.open("result1", "w") {|t| t << "taka pid=#{$$} ppid=#{Process.ppid}" }
+ exit 7
+ End
+ write_file("script2", <<-'End')
+ File.open("result2", "w") {|t| t << "taki pid=#{$$} ppid=#{Process.ppid}" }
+ exit 8
+ End
+ ret = system("#{RUBY} script1 || #{RUBY} script2")
+ status = $?
+ assert_equal(false, ret)
+ assert(status.exited?)
+ result1 = File.read("result1")
+ result2 = File.read("result2")
+ assert_match(/\Ataka pid=\d+ ppid=\d+\z/, result1)
+ assert_match(/\Ataki pid=\d+ ppid=\d+\z/, result2)
+ assert_not_equal(result1[/\d+/].to_i, status.pid)
+
+ if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ Dir.mkdir(path = "path with space")
+ write_file(bat = path + "/bat test.bat", "@echo %1>out")
+ system(bat, "foo 'bar'")
+ assert_equal(%["foo 'bar'"\n], File.read("out"), '[ruby-core:22960]')
+ system(%[#{bat.dump} "foo 'bar'"])
+ assert_equal(%["foo 'bar'"\n], File.read("out"), '[ruby-core:22960]')
+ end
+ }
+ end
+
+ def test_spawn_shell
+ with_tmpchdir {|d|
+ write_file("script1", <<-'End')
+ File.open("result1", "w") {|t| t << "taku pid=#{$$} ppid=#{Process.ppid}" }
+ exit 7
+ End
+ write_file("script2", <<-'End')
+ File.open("result2", "w") {|t| t << "take pid=#{$$} ppid=#{Process.ppid}" }
+ exit 8
+ End
+ pid = spawn("#{RUBY} script1 || #{RUBY} script2")
+ Process.wait pid
+ status = $?
+ assert(status.exited?)
+ assert(!status.success?)
+ result1 = File.read("result1")
+ result2 = File.read("result2")
+ assert_match(/\Ataku pid=\d+ ppid=\d+\z/, result1)
+ assert_match(/\Atake pid=\d+ ppid=\d+\z/, result2)
+ assert_not_equal(result1[/\d+/].to_i, status.pid)
+
+ if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ Dir.mkdir(path = "path with space")
+ write_file(bat = path + "/bat test.bat", "@echo %1>out")
+ pid = spawn(bat, "foo 'bar'")
+ Process.wait pid
+ status = $?
+ assert(status.exited?)
+ assert(status.success?)
+ assert_equal(%["foo 'bar'"\n], File.read("out"), '[ruby-core:22960]')
+ pid = spawn(%[#{bat.dump} "foo 'bar'"])
+ Process.wait pid
+ status = $?
+ assert(status.exited?)
+ assert(status.success?)
+ assert_equal(%["foo 'bar'"\n], File.read("out"), '[ruby-core:22960]')
+ end
+ }
+ end
+
+ def test_popen_shell
+ with_tmpchdir {|d|
+ write_file("script1", <<-'End')
+ puts "tako pid=#{$$} ppid=#{Process.ppid}"
+ exit 7
+ End
+ write_file("script2", <<-'End')
+ puts "tika pid=#{$$} ppid=#{Process.ppid}"
+ exit 8
+ End
+ io = IO.popen("#{RUBY} script1 || #{RUBY} script2")
+ result = io.read
+ io.close
+ status = $?
+ assert(status.exited?)
+ assert(!status.success?)
+ assert_match(/\Atako pid=\d+ ppid=\d+\ntika pid=\d+ ppid=\d+\n\z/, result)
+ assert_not_equal(result[/\d+/].to_i, status.pid)
+
+ if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ Dir.mkdir(path = "path with space")
+ write_file(bat = path + "/bat test.bat", "@echo %1")
+ r = IO.popen([bat, "foo 'bar'"]) {|f| f.read}
+ assert_equal(%["foo 'bar'"\n], r, '[ruby-core:22960]')
+ r = IO.popen(%[#{bat.dump} "foo 'bar'"]) {|f| f.read}
+ assert_equal(%["foo 'bar'"\n], r, '[ruby-core:22960]')
+ end
+ }
+ end
+
+ def test_exec_shell
+ with_tmpchdir {|d|
+ write_file("script1", <<-'End')
+ File.open("result1", "w") {|t| t << "tiki pid=#{$$} ppid=#{Process.ppid}" }
+ exit 7
+ End
+ write_file("script2", <<-'End')
+ File.open("result2", "w") {|t| t << "tiku pid=#{$$} ppid=#{Process.ppid}" }
+ exit 8
+ End
+ write_file("s", <<-"End")
+ ruby = #{RUBY.dump}
+ exec("\#{ruby} script1 || \#{ruby} script2")
+ End
+ pid = spawn RUBY, "s"
+ Process.wait pid
+ status = $?
+ assert(status.exited?)
+ assert(!status.success?)
+ result1 = File.read("result1")
+ result2 = File.read("result2")
+ assert_match(/\Atiki pid=\d+ ppid=\d+\z/, result1)
+ assert_match(/\Atiku pid=\d+ ppid=\d+\z/, result2)
+ assert_not_equal(result1[/\d+/].to_i, status.pid)
+ }
+ end
+
+ def test_argv0
+ with_tmpchdir {|d|
+ assert_equal(false, system([RUBY, "asdfg"], "-e", "exit false"))
+ assert_equal(true, system([RUBY, "zxcvb"], "-e", "exit true"))
+
+ Process.wait spawn([RUBY, "poiu"], "-e", "exit 4")
+ assert_equal(4, $?.exitstatus)
+
+ assert_equal("1", IO.popen([[RUBY, "qwerty"], "-e", "print 1"]).read)
+ Process.wait
+
+ write_file("s", <<-"End")
+ exec([#{RUBY.dump}, "lkjh"], "-e", "exit 5")
+ End
+ pid = spawn RUBY, "s"
+ Process.wait pid
+ assert_equal(5, $?.exitstatus)
+ }
+ end
+
+ def with_stdin(filename)
+ open(filename) {|f|
+ begin
+ old = STDIN.dup
+ begin
+ STDIN.reopen(filename)
+ yield
+ ensure
+ STDIN.reopen(old)
+ end
+ ensure
+ old.close
+ end
+ }
+ end
+
+ def test_argv0_noarg
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ with_tmpchdir {|d|
+ open("t", "w") {|f| f.print "exit true" }
+ open("f", "w") {|f| f.print "exit false" }
+
+ with_stdin("t") { assert_equal(true, system([RUBY, "qaz"])) }
+ with_stdin("f") { assert_equal(false, system([RUBY, "wsx"])) }
+
+ with_stdin("t") { Process.wait spawn([RUBY, "edc"]) }
+ assert($?.success?)
+ with_stdin("f") { Process.wait spawn([RUBY, "rfv"]) }
+ assert(!$?.success?)
+
+ with_stdin("t") { IO.popen([[RUBY, "tgb"]]) {|io| assert_equal("", io.read) } }
+ assert($?.success?)
+ with_stdin("f") { IO.popen([[RUBY, "yhn"]]) {|io| assert_equal("", io.read) } }
+ assert(!$?.success?)
+
+ status = run_in_child "STDIN.reopen('t'); exec([#{RUBY.dump}, 'ujm'])"
+ assert(status.success?)
+ status = run_in_child "STDIN.reopen('f'); exec([#{RUBY.dump}, 'ik,'])"
+ assert(!status.success?)
+ }
+ end
+
+ def test_status
+ with_tmpchdir do
+ s = run_in_child("exit 1")
+ assert_equal("#<Process::Status: pid #{ s.pid } exit #{ s.exitstatus }>", s.inspect)
+
+ assert_equal(s, s)
+ assert_equal(s, s.to_i)
+
+ assert_equal(s.to_i & 0x55555555, s & 0x55555555)
+ assert_equal(s.to_i >> 1, s >> 1)
+ assert_equal(false, s.stopped?)
+ assert_equal(nil, s.stopsig)
+ end
+ end
+
+ def test_status_kill
+ return unless Process.respond_to?(:kill)
+ return unless Signal.list.include?("QUIT")
+
+ with_tmpchdir do
+ write_file("foo", "sleep 30")
+ pid = spawn(RUBY, "foo")
+ Thread.new { sleep 1; Process.kill(:SIGQUIT, pid) }
+ Process.wait(pid)
+ s = $?
+ assert_equal([false, true, false],
+ [s.exited?, s.signaled?, s.stopped?],
+ "[s.exited?, s.signaled?, s.stopped?]")
+ assert_send(
+ [["#<Process::Status: pid #{ s.pid } SIGQUIT (signal #{ s.termsig })>",
+ "#<Process::Status: pid #{ s.pid } SIGQUIT (signal #{ s.termsig }) (core dumped)>"],
+ :include?,
+ s.inspect])
+ assert_equal(false, s.exited?)
+ assert_equal(nil, s.success?)
+ end
+ end
+
+ def test_wait_without_arg
+ with_tmpchdir do
+ write_file("foo", "sleep 0.1")
+ pid = spawn(RUBY, "foo")
+ assert_equal(pid, Process.wait)
+ end
+ end
+
+ def test_wait2
+ with_tmpchdir do
+ write_file("foo", "sleep 0.1")
+ pid = spawn(RUBY, "foo")
+ assert_equal([pid, 0], Process.wait2)
+ end
+ end
+
+ def test_waitall
+ with_tmpchdir do
+ write_file("foo", "sleep 0.1")
+ ps = (0...3).map { spawn(RUBY, "foo") }.sort
+ ss = Process.waitall.sort
+ ps.zip(ss) do |p1, (p2, s)|
+ assert_equal(p1, p2)
+ assert_equal(p1, s.pid)
+ end
+ end
+ end
+
+ def test_abort
+ with_tmpchdir do
+ s = run_in_child("abort")
+ assert_not_equal(0, s.exitstatus)
+ end
+ end
+
+ def test_sleep
+ assert_raise(ArgumentError) { sleep(1, 1) }
+ end
+
+ def test_getpgid
+ assert_kind_of(Integer, Process.getpgid(Process.ppid))
+ rescue NotImplementedError
+ end
+
+ def test_getpriority
+ assert_kind_of(Integer, Process.getpriority(Process::PRIO_PROCESS, $$))
+ rescue NameError, NotImplementedError
+ end
+
+ def test_setpriority
+ if defined? Process::PRIO_USER
+ assert_nothing_raised do
+ pr = Process.getpriority(Process::PRIO_PROCESS, $$)
+ Process.setpriority(Process::PRIO_PROCESS, $$, pr)
+ end
+ end
+ end
+
+ def test_getuid
+ assert_kind_of(Integer, Process.uid)
+ end
+
+ def test_groups
+ gs = Process.groups
+ assert_instance_of(Array, gs)
+ gs.each {|g| assert_kind_of(Integer, g) }
+ rescue NotImplementedError
+ end
+
+ def test_maxgroups
+ assert_kind_of(Integer, Process.maxgroups)
+ end
+
+ def test_geteuid
+ assert_kind_of(Integer, Process.egid)
+ end
+
+ def test_uid_re_exchangeable_p
+ r = Process::UID.re_exchangeable?
+ assert(true == r || false == r)
+ end
+
+ def test_gid_re_exchangeable_p
+ r = Process::GID.re_exchangeable?
+ assert(true == r || false == r)
+ end
+
+ def test_uid_sid_available?
+ r = Process::UID.sid_available?
+ assert(true == r || false == r)
+ end
+
+ def test_gid_sid_available?
+ r = Process::GID.sid_available?
+ assert(true == r || false == r)
+ end
+
+ def test_pst_inspect
+ assert_nothing_raised { Process::Status.allocate.inspect }
+ end
+
+ def test_wait_and_sigchild
+ signal_received = []
+ Signal.trap(:CHLD) { signal_received << true }
+ pid = fork { sleep 1; exit }
+ Thread.start { raise }
+ Process.wait pid
+ 5.times do
+ sleep 1
+ break unless signal_received.empty?
+ end
+ assert_equal [true], signal_received, " [ruby-core:19744]"
+ rescue NotImplementedError, ArgumentError
+ ensure
+ begin
+ Signal.trap(:CHLD, 'DEFAULT')
+ rescue ArgumentError
+ end
+ end
+
+ def test_no_curdir
+ if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ skip "removing current directory is not supported"
+ end
+ with_tmpchdir {|d|
+ Dir.mkdir("vd")
+ status = nil
+ Dir.chdir("vd") {
+ dir = "#{d}/vd"
+ # OpenSolaris cannot remove the current directory.
+ system(RUBY, "-e", "Dir.chdir '..'; Dir.rmdir #{dir.dump}")
+ system({"RUBYLIB"=>nil}, RUBY, "-e", "exit true")
+ status = $?
+ }
+ assert(status.success?, "[ruby-dev:38105]")
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_rand.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_rand.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_rand.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,425 @@
+require 'test/unit'
+
+class TestRand < Test::Unit::TestCase
+ def assert_random_int(ws, m, init = 0)
+ srand(init)
+ rnds = [Random.new(init)]
+ rnds2 = [rnds[0].dup]
+ rnds3 = [rnds[0].dup]
+ ws.each_with_index do |w, i|
+ w = w.to_i
+ assert_equal(w, rand(m))
+ rnds.each do |rnd|
+ assert_equal(w, rnd.rand(m))
+ end
+ rnds2.each do |rnd|
+ r=rnd.rand(i...(m+i))
+ assert_equal(w+i, r)
+ end
+ rnds3.each do |rnd|
+ r=rnd.rand(i..(m+i-1))
+ assert_equal(w+i, r)
+ end
+ rnds << Marshal.load(Marshal.dump(rnds[-1]))
+ rnds2 << Marshal.load(Marshal.dump(rnds2[-1]))
+ end
+ end
+
+ def test_mt
+ assert_random_int(%w(1067595299 955945823 477289528 4107218783 4228976476),
+ 0x100000000, 0x00000456_00000345_00000234_00000123)
+ end
+
+ def test_0x3fffffff
+ assert_random_int(%w(209652396 398764591 924231285 404868288 441365315),
+ 0x3fffffff)
+ end
+
+ def test_0x40000000
+ assert_random_int(%w(209652396 398764591 924231285 404868288 441365315),
+ 0x40000000)
+ end
+
+ def test_0x40000001
+ assert_random_int(%w(209652396 398764591 924231285 441365315 192771779),
+ 0x40000001)
+ end
+
+ def test_0xffffffff
+ assert_random_int(%w(2357136044 2546248239 3071714933 3626093760 2588848963),
+ 0xffffffff)
+ end
+
+ def test_0x100000000
+ assert_random_int(%w(2357136044 2546248239 3071714933 3626093760 2588848963),
+ 0x100000000)
+ end
+
+ def test_0x100000001
+ assert_random_int(%w(2546248239 1277901399 243580376 1171049868 2051556033),
+ 0x100000001)
+ end
+
+ def test_rand_0x100000000
+ assert_random_int(%w(4119812344 3870378946 80324654 4294967296 410016213),
+ 0x100000001, 311702798)
+ end
+
+ def test_0x1000000000000
+ assert_random_int(%w(11736396900911
+ 183025067478208
+ 197104029029115
+ 130583529618791
+ 180361239846611),
+ 0x1000000000000)
+ end
+
+ def test_0x1000000000001
+ assert_random_int(%w(187121911899765
+ 197104029029115
+ 180361239846611
+ 236336749852452
+ 208739549485656),
+ 0x1000000000001)
+ end
+
+ def test_0x3fffffffffffffff
+ assert_random_int(%w(900450186894289455
+ 3969543146641149120
+ 1895649597198586619
+ 827948490035658087
+ 3203365596207111891),
+ 0x3fffffffffffffff)
+ end
+
+ def test_0x4000000000000000
+ assert_random_int(%w(900450186894289455
+ 3969543146641149120
+ 1895649597198586619
+ 827948490035658087
+ 3203365596207111891),
+ 0x4000000000000000)
+ end
+
+ def test_0x4000000000000001
+ assert_random_int(%w(900450186894289455
+ 3969543146641149120
+ 1895649597198586619
+ 827948490035658087
+ 2279347887019741461),
+ 0x4000000000000001)
+ end
+
+ def test_0x10000000000
+ ws = %w(455570294424 1073054410371 790795084744 2445173525 1088503892627)
+ assert_random_int(ws, 0x10000000000, 3)
+ end
+
+ def test_0x10000
+ ws = %w(2732 43567 42613 52416 45891)
+ assert_random_int(ws, 0x10000)
+ end
+
+ def test_types
+ srand(0)
+ rnd = Random.new(0)
+ assert_equal(44, rand(100.0))
+ assert_equal(44, rnd.rand(100))
+ assert_equal(1245085576965981900420779258691, rand((2**100).to_f))
+ assert_equal(1245085576965981900420779258691, rnd.rand(2**100))
+ assert_equal(914679880601515615685077935113, rand(-(2**100).to_f))
+
+ srand(0)
+ rnd = Random.new(0)
+ assert_equal(997707939797331598305742933184, rand(2**100))
+ assert_equal(997707939797331598305742933184, rnd.rand(2**100))
+ assert_in_delta(0.602763376071644, rand((2**100).coerce(0).first),
+ 0.000000000000001)
+ assert_raise(ArgumentError) {rnd.rand((2**100).coerce(0).first)}
+
+ srand(0)
+ rnd = Random.new(0)
+ assert_in_delta(0.548813503927325, rand(nil),
+ 0.000000000000001)
+ assert_in_delta(0.548813503927325, rnd.rand(),
+ 0.000000000000001)
+ srand(0)
+ rnd = Random.new(0)
+ o = Object.new
+ def o.to_int; 100; end
+ assert_equal(44, rand(o))
+ assert_equal(44, rnd.rand(o))
+ assert_equal(47, rand(o))
+ assert_equal(47, rnd.rand(o))
+ assert_equal(64, rand(o))
+ assert_equal(64, rnd.rand(o))
+ end
+
+ def test_srand
+ srand
+ assert_kind_of(Integer, rand(2))
+ assert_kind_of(Integer, Random.new.rand(2))
+
+ srand(2**100)
+ rnd = Random.new(2**100)
+ %w(3258412053).each {|w|
+ assert_equal(w.to_i, rand(0x100000000))
+ assert_equal(w.to_i, rnd.rand(0x100000000))
+ }
+ end
+
+ def test_shuffle
+ srand(0)
+ assert_equal([1,4,2,5,3], [1,2,3,4,5].shuffle)
+ end
+
+ def test_big_seed
+ assert_random_int(%w(1143843490), 0x100000000, 2**1000000-1)
+ end
+
+ def test_random_gc
+ r = Random.new(0)
+ %w(2357136044 2546248239 3071714933).each do |w|
+ assert_equal(w.to_i, r.rand(0x100000000))
+ end
+ GC.start
+ %w(3626093760 2588848963 3684848379).each do |w|
+ assert_equal(w.to_i, r.rand(0x100000000))
+ end
+ end
+
+ def test_random_type_error
+ assert_raise(TypeError) { Random.new(Object.new) }
+ assert_raise(TypeError) { Random.new(0).rand(Object.new) }
+ end
+
+ def test_random_argument_error
+ r = Random.new(0)
+ assert_raise(ArgumentError) { r.rand(0, 0) }
+ assert_raise(ArgumentError, '[ruby-core:24677]') { r.rand(-1) }
+ assert_raise(ArgumentError, '[ruby-core:24677]') { r.rand(-1.0) }
+ assert_raise(ArgumentError, '[ruby-core:24677]') { r.rand(0) }
+ assert_equal(0, r.rand(1), '[ruby-dev:39166]')
+ assert_equal(0, r.rand(0...1), '[ruby-dev:39166]')
+ assert_equal(0, r.rand(0..0), '[ruby-dev:39166]')
+ assert_equal(0.0, r.rand(0.0..0.0), '[ruby-dev:39166]')
+ assert_raise(ArgumentError, '[ruby-dev:39166]') { r.rand(0...0) }
+ assert_raise(ArgumentError, '[ruby-dev:39166]') { r.rand(0..-1) }
+ assert_raise(ArgumentError, '[ruby-dev:39166]') { r.rand(0.0...0.0) }
+ assert_raise(ArgumentError, '[ruby-dev:39166]') { r.rand(0.0...-0.1) }
+ assert_raise(ArgumentError, bug3027 = '[ruby-core:29075]') { r.rand(nil) }
+ end
+
+ def test_random_seed
+ assert_equal(0, Random.new(0).seed)
+ assert_equal(0x100000000, Random.new(0x100000000).seed)
+ assert_equal(2**100, Random.new(2**100).seed)
+ end
+
+ def test_random_dup
+ r1 = Random.new(0)
+ r2 = r1.dup
+ %w(2357136044 2546248239 3071714933).each do |w|
+ assert_equal(w.to_i, r1.rand(0x100000000))
+ end
+ %w(2357136044 2546248239 3071714933).each do |w|
+ assert_equal(w.to_i, r2.rand(0x100000000))
+ end
+ r2 = r1.dup
+ %w(3626093760 2588848963 3684848379).each do |w|
+ assert_equal(w.to_i, r1.rand(0x100000000))
+ end
+ %w(3626093760 2588848963 3684848379).each do |w|
+ assert_equal(w.to_i, r2.rand(0x100000000))
+ end
+ end
+
+ def test_random_state
+ state = <<END
+3877134065023083674777481835852171977222677629000095857864323111193832400974413
+4782302161934463784850675209112299537259006497924090422596764895633625964527441
+6943943249411681406395713106007661119327771293929504639878577616749110507385924
+0173026285378896836022134086386136835407107422834685854738117043791709411958489
+3504364936306163473541948635570644161010981140452515307286926529085424765299100
+1255453260115310687580777474046203049197643434654645011966794531914127596390825
+0832232869378617194193100828000236737535657699356156021286278281306055217995213
+8911536025132779573429499813926910299964681785069915877910855089314686097947757
+2621451199734871158015842198110309034467412292693435515184023707918034746119728
+8223459645048255809852819129671833854560563104716892857257229121211527031509280
+2390605053896565646658122125171846129817536096211475312518457776328637574563312
+8113489216547503743508184872149896518488714209752552442327273883060730945969461
+6568672445225657265545983966820639165285082194907591432296265618266901318398982
+0560425129536975583916120558652408261759226803976460322062347123360444839683204
+9868507788028894111577023917218846128348302845774997500569465902983227180328307
+3735301552935104196244116381766459468172162284042207680945316590536094294865648
+5953156978630954893391701383648157037914019502853776972615500142898763385846315
+8457790690531675205213829055442306187692107777193071680668153335688203945049935
+3404449910419303330872435985327845889440458370416464132629866593538629877042969
+7589948685901343135964343582727302330074331803900821801076139161904900333497836
+6627028345784450211920229170280462474456504317367706849373957309797251052447898
+8436235456995644876515032202483449807136139063937892187299239634252391529822163
+9187055268750679730919937006195967184206072757082920250075756273182004964087790
+3812024063897424219316687828337007888030994779068081666133751070479581394604974
+6022215489604777611774245181115126041390161592199230774968475944753915533936834
+4740049163514318351045644344358598159463605453475585370226041981040238023241538
+4958436364776113598408428801867643946791659645708540669432995503575075657406359
+8086928867900590554805639837071298576728564946552163206007997000988745940681607
+4542883814997403673656291618517107133421335645430345871041730410669209035640945
+5024601618318371192091626092482640364669969307766919645222516407626038616667754
+5781148898846306894862390724358039251444333889446128074209417936830253204064223
+3424784857908022314095011879203259864909560830176189727132432100010493659154644
+8407326292884826469503093409465946018496358514999175268200846200025235441426140
+7783386235191526371372655894290440356560751680752191224383460972099834655086068
+9989413443881686756951804138910911737670495391762470293978321414964443502180391
+4665982575919524372985773336921990352313629822677022891307943536442258282401255
+5387646898976193134193506239982621725093291970351083631367582570375381334759004
+1784150668048523676387894646666460369896619585113435743180899362844070393586212
+5023920017185866399742380706352739465848708746963693663004068892056705603018655
+8686663087894205699555906146534549176352859823832196938386172810274748624517052
+8356758650653040545267425513047130342286119889879774951060662713807133125543465
+5104086026298674827575216701372513525846650644773241437066782037334367982012148
+7987782004646896468089089826267467005660035604553432197455616078731159778086155
+9443250946037119223468305483694093795324036812927501783593256716590840500905291
+2096608538205270323065573109227029887731553399324547696295234105140157179430410
+4003109602564833086703863221058381556776789018351726488797845637981974580864082
+1630093543020854542240690897858757985640869209737744458407777584279553258261599
+0246922348101147034463235613998979344685018577901996218099622190722307356620796
+5137485271371502385527388080824050288371607602101805675021790116223360483508538
+8832149997794718410946818866375912486788005950091851067237358294899771385995876
+7088239104394332452501033090159333224995108984871426750597513314521294001864578
+2353528356752869732412552685554334966798888534847483030947310518891788722418172
+6008607577773612004956373863580996793809969715725508939568919714424871639667201
+7922255031431159347210833846575355772055570279673262115911154370983086189948124
+4653677615895887099814174914248255026619941911735341818489822197472499295786997
+7728418516719104857455960900092226749725407204388193002835497055305427730656889
+1508308778869166073740855838213112709306743479676740893150000714099064468263284
+1873435518542972182497755500300784177067568586395485329021157235696300013490087
+2866571034916258390528533374944905429089028336079264760836949419754851422499614
+5732326011260304142074554782259843903215064144396140106592193961703288125005023
+5334375212799817540775536847622032852415253966587517800661605905489339306359573
+2234947905196298436841723673626428243649931398749552780311877734063703985375067
+1239508613417041942487245370152912391885566432830659640677893488723724763120121
+4111855277511356759926232894062814360449757490961653026194107761340614059045172
+1123363102660719217740126157997033682099769790976313166682432732518101889210276
+9574144065390305904944821051736021310524344626348851573631697771556587859836330
+6997324121866564283654784470215100159122764509197570402997911258816526554863326
+9877535269005418736225944874608987238997316999444215865249840762640949599725696
+0773083894168959823152054508672272612355108904098579447774398451678239199426513
+3439507737424049578587487505080347686371029156845461151278198605267053408259090
+3158676794894709281917034995611352710898103415304769654883981727681820369090169
+9295163908214854813365413456264812190842699054830709079275249714169405719140093
+1347572458245530016346604698682269779841803667099480215265926316505737171177810
+9969036572310084022695109125200937135540995157279354438704321290061646592229860
+0156566013602344870223183295508278359111174872740360473845615437106413256386849
+2286259982118315248148847764929974917157683083659364623458927512616369119194574
+2254080
+END
+ state = state.split.join.to_i
+ r = Random.new(0)
+ srand(0)
+ assert_equal(state, r.instance_eval { state })
+ assert_equal(state, Random.instance_eval { state })
+ r.rand(0x100)
+ assert_equal(state, r.instance_eval { state })
+ end
+
+ def test_random_left
+ r = Random.new(0)
+ assert_equal(1, r.instance_eval { left })
+ r.rand(0x100)
+ assert_equal(624, r.instance_eval { left })
+ r.rand(0x100)
+ assert_equal(623, r.instance_eval { left })
+ srand(0)
+ assert_equal(1, Random.instance_eval { left })
+ rand(0x100)
+ assert_equal(624, Random.instance_eval { left })
+ rand(0x100)
+ assert_equal(623, Random.instance_eval { left })
+ end
+
+ def test_random_bytes
+ r = Random.new(0)
+ assert_equal("", r.bytes(0))
+ assert_equal("\xAC".force_encoding("ASCII-8BIT"), r.bytes(1))
+ assert_equal("/\xAA\xC4\x97u\xA6\x16\xB7\xC0\xCC".force_encoding("ASCII-8BIT"), r.bytes(10))
+ end
+
+ def test_random_range
+ r = Random.new(0)
+ %w(9 5 8).each {|w| assert_equal(w.to_i, r.rand(5..9)) }
+ %w(-237 731 383).each {|w| assert_equal(w.to_i, r.rand(-1000..1000)) }
+ %w(1267650600228229401496703205382
+ 1267650600228229401496703205384
+ 1267650600228229401496703205383).each do |w|
+ assert_equal(w.to_i, r.rand(2**100+5..2**100+9))
+ end
+ v = r.rand(3.1..4)
+ assert_instance_of(Float, v, '[ruby-core:24679]')
+ assert_includes(3.1..4, v)
+
+ now = Time.now
+ assert_equal(now, r.rand(now..now))
+ end
+
+ def test_random_float
+ r = Random.new(0)
+ assert_in_delta(0.5488135039273248, r.rand, 0.0001)
+ assert_in_delta(0.7151893663724195, r.rand, 0.0001)
+ assert_in_delta(0.6027633760716439, r.rand, 0.0001)
+ assert_in_delta(1.0897663659937937, r.rand(2.0), 0.0001)
+ assert_in_delta(5.3704626067153264e+29, r.rand((2**100).to_f), 10**25)
+
+ assert_raise(Errno::EDOM, Errno::ERANGE) { r.rand(1.0 / 0.0) }
+ assert_raise(Errno::EDOM, Errno::ERANGE) { r.rand(0.0 / 0.0) }
+
+ r = Random.new(0)
+ assert_in_delta(1.5488135039273248, r.rand(1.0...2.0), 0.0001, '[ruby-core:24655]')
+ assert_in_delta(1.7151893663724195, r.rand(1.0...2.0), 0.0001, '[ruby-core:24655]')
+ assert_in_delta(7.027633760716439, r.rand(1.0...11.0), 0.0001, '[ruby-core:24655]')
+ assert_in_delta(3.0897663659937937, r.rand(2.0...4.0), 0.0001, '[ruby-core:24655]')
+ end
+
+ def test_random_equal
+ r = Random.new(0)
+ assert(r == r)
+ assert(r == r.dup)
+ r1 = r.dup
+ r2 = r.dup
+ r1.rand(0x100)
+ assert(r1 != r2)
+ r2.rand(0x100)
+ assert(r1 == r2)
+ end
+
+ def test_fork_shuffle
+ pid = fork do
+ (1..10).to_a.shuffle
+ raise 'default seed is not set' if srand == 0
+ end
+ p2, st = Process.waitpid2(pid)
+ assert(st.success?, "#{st.inspect}")
+ rescue NotImplementedError, ArgumentError
+ end
+
+ def test_seed
+ bug3104 = '[ruby-core:29292]'
+ rand_1 = Random.new(-1).rand
+ assert_not_equal(rand_1, Random.new((1 << 31) -1).rand, "#{bug3104} (2)")
+ assert_not_equal(rand_1, Random.new((1 << 63) -1).rand, "#{bug3104} (2)")
+
+ [-1, -2**10, -2**40].each {|n|
+ b = (2**64).coerce(n)[0]
+ r1 = Random.new(n).rand
+ r2 = Random.new(b).rand
+ assert_equal(r1, r2)
+ }
+ end
+
+ def test_marshal
+ bug3656 = '[ruby-core:31622]'
+ assert_raise(TypeError, bug3656) {
+ Random.new.marshal_load(0)
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_range.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_range.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_range.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,343 @@
+require 'test/unit'
+require 'delegate'
+require 'timeout'
+
+class TestRange < Test::Unit::TestCase
+ def test_range_string
+ # XXX: Is this really the test of Range?
+ assert_equal([], ("a" ... "a").to_a)
+ assert_equal(["a"], ("a" .. "a").to_a)
+ assert_equal(["a"], ("a" ... "b").to_a)
+ assert_equal(["a", "b"], ("a" .. "b").to_a)
+ end
+
+ def test_range_numeric_string
+ assert_equal(["6", "7", "8"], ("6".."8").to_a, "[ruby-talk:343187]")
+ assert_equal(["6", "7"], ("6"..."8").to_a)
+ assert_equal(["9", "10"], ("9".."10").to_a)
+ assert_equal(["09", "10"], ("09".."10").to_a, "[ruby-dev:39361]")
+ assert_equal(["9", "10"], (SimpleDelegator.new("9").."10").to_a)
+ assert_equal(["9", "10"], ("9"..SimpleDelegator.new("10")).to_a)
+ end
+
+ def test_range_symbol
+ assert_equal([:a, :b], (:a .. :b).to_a)
+ end
+
+ def test_evaluation_order
+ arr = [1,2]
+ r = (arr.shift)..(arr.shift)
+ assert_equal(1..2, r, "[ruby-dev:26383]")
+ end
+
+ class DuckRange
+ def initialize(b,e,excl=false)
+ @begin = b
+ @end = e
+ @excl = excl
+ end
+ attr_reader :begin, :end
+
+ def exclude_end?
+ @excl
+ end
+ end
+
+ def test_duckrange
+ assert_equal("bc", "abcd"[DuckRange.new(1,2)])
+ end
+
+ def test_min
+ assert_equal(1, (1..2).min)
+ assert_equal(nil, (2..1).min)
+ assert_equal(1, (1...2).min)
+
+ assert_equal(1.0, (1.0..2.0).min)
+ assert_equal(nil, (2.0..1.0).min)
+ assert_equal(1, (1.0...2.0).min)
+
+ assert_equal(0, (0..0).min)
+ assert_equal(nil, (0...0).min)
+ end
+
+ def test_max
+ assert_equal(2, (1..2).max)
+ assert_equal(nil, (2..1).max)
+ assert_equal(1, (1...2).max)
+
+ assert_equal(2.0, (1.0..2.0).max)
+ assert_equal(nil, (2.0..1.0).max)
+ assert_raise(TypeError) { (1.0...2.0).max }
+
+ assert_equal(-0x80000002, ((-0x80000002)...(-0x80000001)).max)
+
+ assert_equal(0, (0..0).max)
+ assert_equal(nil, (0...0).max)
+ end
+
+ def test_initialize_twice
+ r = eval("1..2")
+ assert_raise(NameError) { r.instance_eval { initialize 3, 4 } }
+ end
+
+ def test_uninitialized_range
+ r = Range.allocate
+ s = Marshal.dump(r)
+ r = Marshal.load(s)
+ assert_nothing_raised { r.instance_eval { initialize 5, 6} }
+ end
+
+ def test_bad_value
+ assert_raise(ArgumentError) { (1 .. :a) }
+ end
+
+ def test_exclude_end
+ assert(!((0..1).exclude_end?))
+ assert((0...1).exclude_end?)
+ end
+
+ def test_eq
+ r = (0..1)
+ assert(r == r)
+ assert(r == (0..1))
+ assert(r != 0)
+ assert(r != (1..2))
+ assert(r != (0..2))
+ assert(r != (0...1))
+ subclass = Class.new(Range)
+ assert(r == subclass.new(0,1))
+ end
+
+ def test_eql
+ r = (0..1)
+ assert(r.eql?(r))
+ assert(r.eql?(0..1))
+ assert(!r.eql?(0))
+ assert(!r.eql?(1..2))
+ assert(!r.eql?(0..2))
+ assert(!r.eql?(0...1))
+ subclass = Class.new(Range)
+ assert(r.eql?(subclass.new(0,1)))
+ end
+
+ def test_hash
+ assert((0..1).hash.is_a?(Fixnum))
+ end
+
+ def test_step
+ a = []
+ (0..10).step {|x| a << x }
+ assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a)
+
+ a = []
+ (0..10).step(2) {|x| a << x }
+ assert_equal([0, 2, 4, 6, 8, 10], a)
+
+ assert_raise(ArgumentError) { (0..10).step(-1) { } }
+ assert_raise(ArgumentError) { (0..10).step(0) { } }
+
+ a = []
+ ("a" .. "z").step(2) {|x| a << x }
+ assert_equal(%w(a c e g i k m o q s u w y), a)
+
+ a = []
+ ("a" .. "z").step(2**32) {|x| a << x }
+ assert_equal(["a"], a)
+
+ a = []
+ (2**32-1 .. 2**32+1).step(2) {|x| a << x }
+ assert_equal([4294967295, 4294967297], a)
+ zero = (2**32).coerce(0).first
+ assert_raise(ArgumentError) { (2**32-1 .. 2**32+1).step(zero) { } }
+
+ o1 = Object.new
+ o2 = Object.new
+ def o1.<=>(x); -1; end
+ def o2.<=>(x); 0; end
+ assert_raise(TypeError) { (o1..o2).step(1) { } }
+
+ class << o1; self; end.class_eval do
+ define_method(:succ) { o2 }
+ end
+ a = []
+ (o1..o2).step(1) {|x| a << x }
+ assert_equal([o1, o2], a)
+
+ a = []
+ (o1...o2).step(1) {|x| a << x }
+ assert_equal([o1], a)
+
+ assert_nothing_raised("[ruby-dev:34557]") { (0..2).step(0.5) {|x| } }
+
+ a = []
+ (0..2).step(0.5) {|x| a << x }
+ assert_equal([0, 0.5, 1.0, 1.5, 2.0], a)
+
+ a = []
+ (0x40000000..0x40000002).step(0.5) {|x| a << x }
+ assert_equal([1073741824, 1073741824.5, 1073741825.0, 1073741825.5, 1073741826], a)
+
+ o = Object.new
+ def o.to_int() 1 end
+ assert_nothing_raised("[ruby-dev:34558]") { (0..2).step(o) {|x| } }
+ end
+
+ def test_each
+ a = []
+ (0..10).each {|x| a << x }
+ assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a)
+
+ o1 = Object.new
+ o2 = Object.new
+ def o1.setcmp(v) @cmpresult = v end
+ o1.setcmp(-1)
+ def o1.<=>(x); @cmpresult; end
+ def o2.setcmp(v) @cmpresult = v end
+ o2.setcmp(0)
+ def o2.<=>(x); @cmpresult; end
+ class << o1; self; end.class_eval do
+ define_method(:succ) { o2 }
+ end
+
+ r1 = (o1..o2)
+ r2 = (o1...o2)
+
+ a = []
+ r1.each {|x| a << x }
+ assert_equal([o1, o2], a)
+
+ a = []
+ r2.each {|x| a << x }
+ assert_equal([o1], a)
+
+ o2.setcmp(1)
+
+ a = []
+ r1.each {|x| a << x }
+ assert_equal([o1], a)
+
+ o2.setcmp(nil)
+
+ a = []
+ r1.each {|x| a << x }
+ assert_equal([o1], a)
+
+ o1.setcmp(nil)
+
+ a = []
+ r2.each {|x| a << x }
+ assert_equal([], a)
+ end
+
+ def test_begin_end
+ assert_equal(0, (0..1).begin)
+ assert_equal(1, (0..1).end)
+ end
+
+ def test_first_last
+ assert_equal([0, 1, 2], (0..10).first(3))
+ assert_equal([8, 9, 10], (0..10).last(3))
+ end
+
+ def test_to_s
+ assert_equal("0..1", (0..1).to_s)
+ assert_equal("0...1", (0...1).to_s)
+ end
+
+ def test_inspect
+ assert_equal("0..1", (0..1).inspect)
+ assert_equal("0...1", (0...1).inspect)
+ end
+
+ def test_eqq
+ assert((0..10) === 5)
+ assert(!((0..10) === 11))
+ end
+
+ def test_include
+ assert(("a".."z").include?("c"))
+ assert(!(("a".."z").include?("5")))
+ assert(("a"..."z").include?("y"))
+ assert(!(("a"..."z").include?("z")))
+ assert(!(("a".."z").include?("cc")))
+ assert((0...10).include?(5))
+ end
+
+ def test_cover
+ assert(("a".."z").cover?("c"))
+ assert(!(("a".."z").cover?("5")))
+ assert(("a"..."z").cover?("y"))
+ assert(!(("a"..."z").cover?("z")))
+ assert(("a".."z").cover?("cc"))
+ end
+
+ def test_beg_len
+ o = Object.new
+ assert_raise(TypeError) { [][o] }
+ class << o; attr_accessor :begin end
+ o.begin = -10
+ assert_raise(TypeError) { [][o] }
+ class << o; attr_accessor :end end
+ o.end = 0
+ assert_raise(NoMethodError) { [][o] }
+ def o.exclude_end=(v) @exclude_end = v end
+ def o.exclude_end?() @exclude_end end
+ o.exclude_end = false
+ assert_nil([0][o])
+ assert_raise(RangeError) { [0][o] = 1 }
+ o.begin = 10
+ o.end = 10
+ assert_nil([0][o])
+ o.begin = 0
+ assert_equal([0], [0][o])
+ o.begin = 2
+ o.end = 0
+ assert_equal([], [0, 1, 2][o])
+ end
+
+ class CyclicRange < Range
+ def <=>(other); true; end
+ end
+ def test_cyclic_range_inspect
+ skip("[BUG : #781] Segfault")
+
+ o = CyclicRange.allocate
+ o.instance_eval { initialize(o, 1) }
+ assert_equal("(... .. ...)..1", o.inspect)
+ end
+
+ def test_comparison_when_recursive
+ skip("[BUG : #781] Segfault")
+
+ x = CyclicRange.allocate; x.send(:initialize, x, 1)
+ y = CyclicRange.allocate; y.send(:initialize, y, 1)
+ Timeout.timeout(1) {
+ assert x == y
+ assert x.eql? y
+ }
+
+ z = CyclicRange.allocate; z.send(:initialize, z, :another)
+ Timeout.timeout(1) {
+ assert x != z
+ assert !x.eql?(z)
+ }
+
+ x = CyclicRange.allocate
+ y = CyclicRange.allocate
+ x.send(:initialize, y, 1)
+ y.send(:initialize, x, 1)
+ Timeout.timeout(1) {
+ assert x == y
+ assert x.eql?(y)
+ }
+
+ x = CyclicRange.allocate
+ z = CyclicRange.allocate
+ x.send(:initialize, z, 1)
+ z.send(:initialize, x, :other)
+ Timeout.timeout(1) {
+ assert x != z
+ assert !x.eql?(z)
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_rational.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_rational.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_rational.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1094 @@
+require 'test/unit'
+
+class RationalSub < Rational; end
+
+class Rational_Test < Test::Unit::TestCase
+
+ def setup
+ @complex = defined?(Complex)
+ if @complex
+ @keiju = Complex.instance_variables.include?(:@RCS_ID)
+ end
+ seps = [File::SEPARATOR, File::ALT_SEPARATOR].compact.map{|x| Regexp.escape(x)}.join("|")
+ @unify = $".grep(/(?:^|#{seps})mathn(?:\.(?:rb|so))?/).size != 0
+ end
+
+ def test_ratsub
+ c = RationalSub.__send__(:convert, 1)
+
+ assert_kind_of(Numeric, c)
+
+ if @unify
+ assert_instance_of(Fixnum, c)
+ else
+ assert_instance_of(RationalSub, c)
+
+ c2 = c + 1
+ assert_instance_of(RationalSub, c2)
+ c2 = c - 1
+ assert_instance_of(RationalSub, c2)
+
+ c3 = c - c2
+ assert_instance_of(RationalSub, c3)
+
+ s = Marshal.dump(c)
+ c5 = Marshal.load(s)
+ assert_equal(c, c5)
+ assert_instance_of(RationalSub, c5)
+ end
+
+ c1 = Rational(1)
+ assert_equal(c1.hash, c.hash, '[ruby-dev:38850]')
+ assert_equal([true, true], [c.eql?(c1), c1.eql?(c)])
+ end
+
+ def test_eql_p
+ c = Rational(0)
+ c2 = Rational(0)
+ c3 = Rational(1)
+
+ assert_equal(true, c.eql?(c2))
+ assert_equal(false, c.eql?(c3))
+
+ if @unify
+ assert_equal(true, c.eql?(0))
+ else
+ assert_equal(false, c.eql?(0))
+ end
+ end
+
+ def test_hash
+ assert_instance_of(Fixnum, Rational(1,2).hash)
+
+ h = {}
+ h[Rational(0)] = 0
+ h[Rational(1,1)] = 1
+ h[Rational(2,1)] = 2
+ h[Rational(3,1)] = 3
+
+ assert_equal(4, h.size)
+ assert_equal(2, h[Rational(2,1)])
+
+ h[Rational(0,1)] = 9
+ assert_equal(4, h.size)
+ end
+
+ def test_freeze
+ c = Rational(1)
+ c.freeze
+ unless @unify
+ assert_equal(true, c.frozen?)
+ end
+ assert_instance_of(String, c.to_s)
+ end
+
+ def test_conv
+ c = Rational(0,1)
+ assert_equal(Rational(0,1), c)
+
+ c = Rational(2**32, 2**32)
+ assert_equal(Rational(2**32,2**32), c)
+ assert_equal([1,1], [c.numerator,c.denominator])
+
+ c = Rational(-2**32, 2**32)
+ assert_equal(Rational(-2**32,2**32), c)
+ assert_equal([-1,1], [c.numerator,c.denominator])
+
+ c = Rational(2**32, -2**32)
+ assert_equal(Rational(2**32,-2**32), c)
+ assert_equal([-1,1], [c.numerator,c.denominator])
+
+ c = Rational(-2**32, -2**32)
+ assert_equal(Rational(-2**32,-2**32), c)
+ assert_equal([1,1], [c.numerator,c.denominator])
+
+ c = Rational(Rational(1,2),2)
+ assert_equal(Rational(1,4), c)
+
+ c = Rational(2,Rational(1,2))
+ assert_equal(Rational(4), c)
+
+ c = Rational(Rational(1,2),Rational(1,2))
+ assert_equal(Rational(1), c)
+
+ if @complex && !@keiju
+ c = Rational(Complex(1,2),2)
+ assert_equal(Complex(Rational(1,2),1), c)
+
+ c = Rational(2,Complex(1,2))
+ assert_equal(Complex(Rational(2,5),Rational(-4,5)), c)
+
+ c = Rational(Complex(1,2),Complex(1,2))
+ assert_equal(Rational(1), c)
+ end
+
+ assert_equal(Rational(3),Rational(3))
+ assert_equal(Rational(1),Rational(3,3))
+ assert_equal(3.3.to_r,Rational(3.3))
+ assert_equal(1,Rational(3.3,3.3))
+ assert_equal(Rational(3),Rational('3'))
+ assert_equal(Rational(1),Rational('3.0','3.0'))
+ assert_equal(Rational(1),Rational('3/3','3/3'))
+ assert_raise(TypeError){Rational(nil)}
+ assert_raise(ArgumentError){Rational('')}
+ assert_raise(TypeError){Rational(Object.new)}
+ assert_raise(ArgumentError){Rational()}
+ assert_raise(ArgumentError){Rational(1,2,3)}
+
+ if (0.0/0).nan?
+ assert_raise(FloatDomainError){Rational(0.0/0)}
+ end
+ if (1.0/0).infinite?
+ assert_raise(FloatDomainError){Rational(1.0/0)}
+ end
+ end
+
+ def test_attr
+ c = Rational(4)
+
+ assert_equal(4, c.numerator)
+ assert_equal(1, c.denominator)
+
+ c = Rational(4,5)
+
+ assert_equal(4, c.numerator)
+ assert_equal(5, c.denominator)
+
+ c = Rational(4)
+
+ assert_equal(4, c.numerator)
+ assert_equal(1, c.denominator)
+
+ c = Rational(4,5)
+
+ assert_equal(4, c.numerator)
+ assert_equal(5, c.denominator)
+
+ c = Rational(4)
+
+ assert_equal(4, c.numerator)
+ assert_equal(1, c.denominator)
+
+ c = Rational(4,5)
+
+ assert_equal(4, c.numerator)
+ assert_equal(5, c.denominator)
+ end
+
+ def test_attr2
+ c = Rational(1)
+
+ if @unify
+=begin
+ assert_equal(true, c.finite?)
+ assert_equal(false, c.infinite?)
+ assert_equal(false, c.nan?)
+ assert_equal(true, c.integer?)
+ assert_equal(false, c.float?)
+ assert_equal(true, c.rational?)
+=end
+ assert_equal(true, c.real?)
+=begin
+ assert_equal(false, c.complex?)
+ assert_equal(true, c.exact?)
+ assert_equal(false, c.inexact?)
+=end
+ else
+=begin
+ assert_equal(true, c.finite?)
+ assert_equal(false, c.infinite?)
+ assert_equal(false, c.nan?)
+ assert_equal(false, c.integer?)
+ assert_equal(false, c.float?)
+ assert_equal(true, c.rational?)
+=end
+ assert_equal(true, c.real?)
+=begin
+ assert_equal(false, c.complex?)
+ assert_equal(true, c.exact?)
+ assert_equal(false, c.inexact?)
+=end
+ end
+
+=begin
+ assert_equal(true, Rational(0).positive?)
+ assert_equal(true, Rational(1).positive?)
+ assert_equal(false, Rational(-1).positive?)
+ assert_equal(false, Rational(0).negative?)
+ assert_equal(false, Rational(1).negative?)
+ assert_equal(true, Rational(-1).negative?)
+
+ assert_equal(0, Rational(0).sign)
+ assert_equal(1, Rational(2).sign)
+ assert_equal(-1, Rational(-2).sign)
+=end
+
+ assert_equal(true, Rational(0).zero?)
+ assert_equal(true, Rational(0,1).zero?)
+ assert_equal(false, Rational(1,1).zero?)
+
+ assert_equal(nil, Rational(0).nonzero?)
+ assert_equal(nil, Rational(0,1).nonzero?)
+ assert_equal(Rational(1,1), Rational(1,1).nonzero?)
+ end
+
+ def test_uplus
+ assert_equal(Rational(1), +Rational(1))
+ assert_equal(Rational(-1), +Rational(-1))
+ assert_equal(Rational(1,1), +Rational(1,1))
+ assert_equal(Rational(-1,1), +Rational(-1,1))
+ assert_equal(Rational(-1,1), +Rational(1,-1))
+ assert_equal(Rational(1,1), +Rational(-1,-1))
+ end
+
+ def test_negate
+ assert_equal(Rational(-1), -Rational(1))
+ assert_equal(Rational(1), -Rational(-1))
+ assert_equal(Rational(-1,1), -Rational(1,1))
+ assert_equal(Rational(1,1), -Rational(-1,1))
+ assert_equal(Rational(1,1), -Rational(1,-1))
+ assert_equal(Rational(-1,1), -Rational(-1,-1))
+
+=begin
+ assert_equal(0, Rational(0).negate)
+ assert_equal(-2, Rational(2).negate)
+ assert_equal(2, Rational(-2).negate)
+=end
+ end
+
+ def test_add
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_equal(Rational(7,6), c + c2)
+
+ assert_equal(Rational(5,2), c + 2)
+ assert_equal(2.5, c + 2.0)
+ end
+
+ def test_sub
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_equal(Rational(-1,6), c - c2)
+
+ assert_equal(Rational(-3,2), c - 2)
+ assert_equal(-1.5, c - 2.0)
+ end
+
+ def test_mul
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_equal(Rational(1,3), c * c2)
+
+ assert_equal(Rational(1,1), c * 2)
+ assert_equal(1.0, c * 2.0)
+ end
+
+ def test_div
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_equal(Rational(3,4), c / c2)
+
+ assert_equal(Rational(1,4), c / 2)
+ assert_equal(0.25, c / 2.0)
+
+ assert_raise(ZeroDivisionError){Rational(1, 3) / 0}
+ assert_raise(ZeroDivisionError){Rational(1, 3) / Rational(0)}
+ end
+
+ def assert_eql(exp, act, *args)
+ unless Array === exp
+ exp = [exp]
+ end
+ unless Array === act
+ act = [act]
+ end
+ exp.zip(act).each do |e, a|
+ na = [e, a] + args
+ assert_equal(*na)
+ na = [e.class, a] + args
+ assert_instance_of(*na)
+ end
+ end
+
+ def test_idiv
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_eql(0, c.div(c2))
+ assert_eql(0, c.div(2))
+ assert_eql(0, c.div(2.0))
+
+ c = Rational(301,100)
+ c2 = Rational(7,5)
+
+ assert_equal(2, c.div(c2))
+ assert_equal(-3, c.div(-c2))
+ assert_equal(-3, (-c).div(c2))
+ assert_equal(2, (-c).div(-c2))
+
+ c = Rational(301,100)
+ c2 = Rational(2)
+
+ assert_equal(1, c.div(c2))
+ assert_equal(-2, c.div(-c2))
+ assert_equal(-2, (-c).div(c2))
+ assert_equal(1, (-c).div(-c2))
+
+ unless @unify
+ c = Rational(11)
+ c2 = Rational(3)
+
+ assert_equal(3, c.div(c2))
+ assert_equal(-4, c.div(-c2))
+ assert_equal(-4, (-c).div(c2))
+ assert_equal(3, (-c).div(-c2))
+ end
+ end
+
+ def test_modulo
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_eql(Rational(1,2), c.modulo(c2))
+ assert_eql(Rational(1,2), c.modulo(2))
+ assert_eql(0.5, c.modulo(2.0))
+
+ c = Rational(301,100)
+ c2 = Rational(7,5)
+
+ assert_equal(Rational(21,100), c.modulo(c2))
+ assert_equal(Rational(-119,100), c.modulo(-c2))
+ assert_equal(Rational(119,100), (-c).modulo(c2))
+ assert_equal(Rational(-21,100), (-c).modulo(-c2))
+
+ c = Rational(301,100)
+ c2 = Rational(2)
+
+ assert_equal(Rational(101,100), c.modulo(c2))
+ assert_equal(Rational(-99,100), c.modulo(-c2))
+ assert_equal(Rational(99,100), (-c).modulo(c2))
+ assert_equal(Rational(-101,100), (-c).modulo(-c2))
+
+ unless @unify
+ c = Rational(11)
+ c2 = Rational(3)
+
+ assert_equal(2, c.modulo(c2))
+ assert_equal(-1, c.modulo(-c2))
+ assert_equal(1, (-c).modulo(c2))
+ assert_equal(-2, (-c).modulo(-c2))
+ end
+ end
+
+ def test_divmod
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_eql([0, Rational(1,2)], c.divmod(c2))
+ assert_eql([0, Rational(1,2)], c.divmod(2))
+ assert_eql([0, 0.5], c.divmod(2.0))
+
+ c = Rational(301,100)
+ c2 = Rational(7,5)
+
+ assert_equal([2, Rational(21,100)], c.divmod(c2))
+ assert_equal([-3, Rational(-119,100)], c.divmod(-c2))
+ assert_equal([-3, Rational(119,100)], (-c).divmod(c2))
+ assert_equal([2, Rational(-21,100)], (-c).divmod(-c2))
+
+ c = Rational(301,100)
+ c2 = Rational(2)
+
+ assert_equal([1, Rational(101,100)], c.divmod(c2))
+ assert_equal([-2, Rational(-99,100)], c.divmod(-c2))
+ assert_equal([-2, Rational(99,100)], (-c).divmod(c2))
+ assert_equal([1, Rational(-101,100)], (-c).divmod(-c2))
+
+ unless @unify
+ c = Rational(11)
+ c2 = Rational(3)
+
+ assert_equal([3,2], c.divmod(c2))
+ assert_equal([-4,-1], c.divmod(-c2))
+ assert_equal([-4,1], (-c).divmod(c2))
+ assert_equal([3,-2], (-c).divmod(-c2))
+ end
+ end
+
+=begin
+ def test_quot
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_eql(0, c.quot(c2))
+ assert_eql(0, c.quot(2))
+ assert_eql(0, c.quot(2.0))
+
+ c = Rational(301,100)
+ c2 = Rational(7,5)
+
+ assert_equal(2, c.quot(c2))
+ assert_equal(-2, c.quot(-c2))
+ assert_equal(-2, (-c).quot(c2))
+ assert_equal(2, (-c).quot(-c2))
+
+ c = Rational(301,100)
+ c2 = Rational(2)
+
+ assert_equal(1, c.quot(c2))
+ assert_equal(-1, c.quot(-c2))
+ assert_equal(-1, (-c).quot(c2))
+ assert_equal(1, (-c).quot(-c2))
+
+ unless @unify
+ c = Rational(11)
+ c2 = Rational(3)
+
+ assert_equal(3, c.quot(c2))
+ assert_equal(-3, c.quot(-c2))
+ assert_equal(-3, (-c).quot(c2))
+ assert_equal(3, (-c).quot(-c2))
+ end
+ end
+=end
+
+ def test_remainder
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_eql(Rational(1,2), c.remainder(c2))
+ assert_eql(Rational(1,2), c.remainder(2))
+ assert_eql(0.5, c.remainder(2.0))
+
+ c = Rational(301,100)
+ c2 = Rational(7,5)
+
+ assert_equal(Rational(21,100), c.remainder(c2))
+ assert_equal(Rational(21,100), c.remainder(-c2))
+ assert_equal(Rational(-21,100), (-c).remainder(c2))
+ assert_equal(Rational(-21,100), (-c).remainder(-c2))
+
+ c = Rational(301,100)
+ c2 = Rational(2)
+
+ assert_equal(Rational(101,100), c.remainder(c2))
+ assert_equal(Rational(101,100), c.remainder(-c2))
+ assert_equal(Rational(-101,100), (-c).remainder(c2))
+ assert_equal(Rational(-101,100), (-c).remainder(-c2))
+
+ unless @unify
+ c = Rational(11)
+ c2 = Rational(3)
+
+ assert_equal(2, c.remainder(c2))
+ assert_equal(2, c.remainder(-c2))
+ assert_equal(-2, (-c).remainder(c2))
+ assert_equal(-2, (-c).remainder(-c2))
+ end
+ end
+
+=begin
+ def test_quotrem
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_eql([0, Rational(1,2)], c.quotrem(c2))
+ assert_eql([0, Rational(1,2)], c.quotrem(2))
+ assert_eql([0, 0.5], c.quotrem(2.0))
+
+ c = Rational(301,100)
+ c2 = Rational(7,5)
+
+ assert_equal([2, Rational(21,100)], c.quotrem(c2))
+ assert_equal([-2, Rational(21,100)], c.quotrem(-c2))
+ assert_equal([-2, Rational(-21,100)], (-c).quotrem(c2))
+ assert_equal([2, Rational(-21,100)], (-c).quotrem(-c2))
+
+ c = Rational(301,100)
+ c2 = Rational(2)
+
+ assert_equal([1, Rational(101,100)], c.quotrem(c2))
+ assert_equal([-1, Rational(101,100)], c.quotrem(-c2))
+ assert_equal([-1, Rational(-101,100)], (-c).quotrem(c2))
+ assert_equal([1, Rational(-101,100)], (-c).quotrem(-c2))
+
+ unless @unify
+ c = Rational(11)
+ c2 = Rational(3)
+
+ assert_equal([3,2], c.quotrem(c2))
+ assert_equal([-3,2], c.quotrem(-c2))
+ assert_equal([-3,-2], (-c).quotrem(c2))
+ assert_equal([3,-2], (-c).quotrem(-c2))
+ end
+ end
+=end
+
+ def test_quo
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_equal(Rational(3,4), c.quo(c2))
+
+ assert_equal(Rational(1,4), c.quo(2))
+ assert_equal(0.25, c.quo(2.0))
+ end
+
+ def test_fdiv
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_equal(0.75, c.fdiv(c2))
+
+ assert_equal(0.25, c.fdiv(2))
+ assert_equal(0.25, c.fdiv(2.0))
+ end
+
+ def test_expt
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ r = c ** c2
+ assert_in_delta(0.6299, r, 0.001)
+
+ assert_equal(Rational(1,4), c ** 2)
+ assert_equal(Rational(4), c ** -2)
+ assert_equal(Rational(1,4), (-c) ** 2)
+ assert_equal(Rational(4), (-c) ** -2)
+
+ assert_equal(0.25, c ** 2.0)
+ assert_equal(4.0, c ** -2.0)
+
+ assert_equal(Rational(1,4), c ** Rational(2))
+ assert_equal(Rational(4), c ** Rational(-2))
+
+ assert_equal(Rational(1), 0 ** Rational(0))
+ assert_equal(Rational(1), Rational(0) ** 0)
+ assert_equal(Rational(1), Rational(0) ** Rational(0))
+
+ # p ** p
+ x = 2 ** Rational(2)
+ assert_equal(Rational(4), x)
+ unless @unify
+ assert_instance_of(Rational, x)
+ end
+ assert_equal(4, x.numerator)
+ assert_equal(1, x.denominator)
+
+ x = Rational(2) ** 2
+ assert_equal(Rational(4), x)
+ unless @unify
+ assert_instance_of(Rational, x)
+ end
+ assert_equal(4, x.numerator)
+ assert_equal(1, x.denominator)
+
+ x = Rational(2) ** Rational(2)
+ assert_equal(Rational(4), x)
+ unless @unify
+ assert_instance_of(Rational, x)
+ end
+ assert_equal(4, x.numerator)
+ assert_equal(1, x.denominator)
+
+ # -p ** p
+ x = (-2) ** Rational(2)
+ assert_equal(Rational(4), x)
+ unless @unify
+ assert_instance_of(Rational, x)
+ end
+ assert_equal(4, x.numerator)
+ assert_equal(1, x.denominator)
+
+ x = Rational(-2) ** 2
+ assert_equal(Rational(4), x)
+ unless @unify
+ assert_instance_of(Rational, x)
+ end
+ assert_equal(4, x.numerator)
+ assert_equal(1, x.denominator)
+
+ x = Rational(-2) ** Rational(2)
+ assert_equal(Rational(4), x)
+ unless @unify
+ assert_instance_of(Rational, x)
+ end
+ assert_equal(4, x.numerator)
+ assert_equal(1, x.denominator)
+
+ # p ** -p
+ x = 2 ** Rational(-2)
+ assert_equal(Rational(1,4), x)
+ assert_instance_of(Rational, x)
+ assert_equal(1, x.numerator)
+ assert_equal(4, x.denominator)
+
+ x = Rational(2) ** -2
+ assert_equal(Rational(1,4), x)
+ assert_instance_of(Rational, x)
+ assert_equal(1, x.numerator)
+ assert_equal(4, x.denominator)
+
+ x = Rational(2) ** Rational(-2)
+ assert_equal(Rational(1,4), x)
+ assert_instance_of(Rational, x)
+ assert_equal(1, x.numerator)
+ assert_equal(4, x.denominator)
+
+ # -p ** -p
+ x = (-2) ** Rational(-2)
+ assert_equal(Rational(1,4), x)
+ assert_instance_of(Rational, x)
+ assert_equal(1, x.numerator)
+ assert_equal(4, x.denominator)
+
+ x = Rational(-2) ** -2
+ assert_equal(Rational(1,4), x)
+ assert_instance_of(Rational, x)
+ assert_equal(1, x.numerator)
+ assert_equal(4, x.denominator)
+
+ x = Rational(-2) ** Rational(-2)
+ assert_equal(Rational(1,4), x)
+ assert_instance_of(Rational, x)
+ assert_equal(1, x.numerator)
+ assert_equal(4, x.denominator)
+
+ unless @unify # maybe bug mathn
+ assert_raise(ZeroDivisionError){0 ** -1}
+ end
+ end
+
+ def test_cmp
+ assert_equal(-1, Rational(-1) <=> Rational(0))
+ assert_equal(0, Rational(0) <=> Rational(0))
+ assert_equal(+1, Rational(+1) <=> Rational(0))
+
+ assert_equal(-1, Rational(-1) <=> 0)
+ assert_equal(0, Rational(0) <=> 0)
+ assert_equal(+1, Rational(+1) <=> 0)
+
+ assert_equal(-1, Rational(-1) <=> 0.0)
+ assert_equal(0, Rational(0) <=> 0.0)
+ assert_equal(+1, Rational(+1) <=> 0.0)
+
+ assert_equal(-1, Rational(1,2) <=> Rational(2,3))
+ assert_equal(0, Rational(2,3) <=> Rational(2,3))
+ assert_equal(+1, Rational(2,3) <=> Rational(1,2))
+
+ f = 2**30-1
+ b = 2**30
+
+ assert_equal(0, Rational(f) <=> Rational(f))
+ assert_equal(-1, Rational(f) <=> Rational(b))
+ assert_equal(+1, Rational(b) <=> Rational(f))
+ assert_equal(0, Rational(b) <=> Rational(b))
+
+ assert_equal(-1, Rational(f-1) <=> Rational(f))
+ assert_equal(+1, Rational(f) <=> Rational(f-1))
+ assert_equal(-1, Rational(b-1) <=> Rational(b))
+ assert_equal(+1, Rational(b) <=> Rational(b-1))
+
+ assert_equal(false, Rational(0) < Rational(0))
+ assert_equal(true, Rational(0) <= Rational(0))
+ assert_equal(true, Rational(0) >= Rational(0))
+ assert_equal(false, Rational(0) > Rational(0))
+
+ assert_equal(nil, Rational(0) <=> nil)
+ assert_equal(nil, Rational(0) <=> 'foo')
+ end
+
+ def test_eqeq
+ assert(Rational(1,1) == Rational(1))
+ assert(Rational(-1,1) == Rational(-1))
+
+ assert_equal(false, Rational(2,1) == Rational(1))
+ assert_equal(true, Rational(2,1) != Rational(1))
+ assert_equal(false, Rational(1) == nil)
+ assert_equal(false, Rational(1) == '')
+ end
+
+ def test_coerce
+ assert_equal([Rational(2),Rational(1)], Rational(1).coerce(2))
+ assert_equal([Rational(2.2),Rational(1)], Rational(1).coerce(2.2))
+ assert_equal([Rational(2),Rational(1)], Rational(1).coerce(Rational(2)))
+ end
+
+ def test_unify
+ if @unify
+ assert_instance_of(Fixnum, Rational(1,2) + Rational(1,2))
+ assert_instance_of(Fixnum, Rational(1,2) - Rational(1,2))
+ assert_instance_of(Fixnum, Rational(1,2) * 2)
+ assert_instance_of(Fixnum, Rational(1,2) / Rational(1,2))
+ assert_instance_of(Fixnum, Rational(1,2).div(Rational(1,2)))
+ assert_instance_of(Fixnum, Rational(1,2).quo(Rational(1,2)))
+ assert_instance_of(Fixnum, Rational(1,2) ** -2)
+ end
+ end
+
+ def test_math
+ assert_equal(Rational(1,2), Rational(1,2).abs)
+ assert_equal(Rational(1,2), Rational(-1,2).abs)
+ if @complex && !@keiju
+ assert_equal(Rational(1,2), Rational(1,2).magnitude)
+ assert_equal(Rational(1,2), Rational(-1,2).magnitude)
+ end
+
+ assert_equal(1, Rational(1,2).numerator)
+ assert_equal(2, Rational(1,2).denominator)
+ end
+
+ def test_trunc
+ [[Rational(13, 5), [ 2, 3, 2, 3]], # 2.6
+ [Rational(5, 2), [ 2, 3, 2, 3]], # 2.5
+ [Rational(12, 5), [ 2, 3, 2, 2]], # 2.4
+ [Rational(-12,5), [-3, -2, -2, -2]], # -2.4
+ [Rational(-5, 2), [-3, -2, -2, -3]], # -2.5
+ [Rational(-13, 5), [-3, -2, -2, -3]], # -2.6
+ ].each do |i, a|
+ assert_equal(a[0], i.floor)
+ assert_equal(a[1], i.ceil)
+ assert_equal(a[2], i.truncate)
+ assert_equal(a[3], i.round)
+ end
+ end
+
+ def test_to_s
+ c = Rational(1,2)
+
+ assert_instance_of(String, c.to_s)
+ assert_equal('1/2', c.to_s)
+
+ if @unify
+ assert_equal('0', Rational(0,2).to_s)
+ assert_equal('0', Rational(0,-2).to_s)
+ else
+ assert_equal('0/1', Rational(0,2).to_s)
+ assert_equal('0/1', Rational(0,-2).to_s)
+ end
+ assert_equal('1/2', Rational(1,2).to_s)
+ assert_equal('-1/2', Rational(-1,2).to_s)
+ assert_equal('1/2', Rational(-1,-2).to_s)
+ assert_equal('-1/2', Rational(1,-2).to_s)
+ assert_equal('1/2', Rational(-1,-2).to_s)
+ end
+
+ def test_inspect
+ c = Rational(1,2)
+
+ assert_instance_of(String, c.inspect)
+ assert_equal('(1/2)', c.inspect)
+ end
+
+ def test_marshal
+ c = Rational(1,2)
+ c.instance_eval{@ivar = 9}
+
+ s = Marshal.dump(c)
+ c2 = Marshal.load(s)
+ assert_equal(c, c2)
+ assert_equal(9, c2.instance_variable_get(:@ivar))
+ assert_instance_of(Rational, c2)
+
+ assert_raise(ZeroDivisionError){
+ Marshal.load("\x04\bU:\rRational[\ai\x06i\x05")
+ }
+
+ bug3656 = '[ruby-core:31622]'
+ assert_raise(TypeError, bug3656) {
+ Rational(1,2).marshal_load(0)
+ }
+ end
+
+ def test_parse
+ assert_equal(Rational(5), '5'.to_r)
+ assert_equal(Rational(-5), '-5'.to_r)
+ assert_equal(Rational(5,3), '5/3'.to_r)
+ assert_equal(Rational(-5,3), '-5/3'.to_r)
+# assert_equal(Rational(5,-3), '5/-3'.to_r)
+# assert_equal(Rational(-5,-3), '-5/-3'.to_r)
+
+ assert_equal(Rational(5), '5.0'.to_r)
+ assert_equal(Rational(-5), '-5.0'.to_r)
+ assert_equal(Rational(5,3), '5.0/3'.to_r)
+ assert_equal(Rational(-5,3), '-5.0/3'.to_r)
+# assert_equal(Rational(5,-3), '5.0/-3'.to_r)
+# assert_equal(Rational(-5,-3), '-5.0/-3'.to_r)
+
+ assert_equal(Rational(5), '5e0'.to_r)
+ assert_equal(Rational(-5), '-5e0'.to_r)
+ assert_equal(Rational(5,3), '5e0/3'.to_r)
+ assert_equal(Rational(-5,3), '-5e0/3'.to_r)
+# assert_equal(Rational(5,-3), '5e0/-3'.to_r)
+# assert_equal(Rational(-5,-3), '-5e0/-3'.to_r)
+
+ assert_equal(Rational(33,100), '.33'.to_r)
+ assert_equal(Rational(33,100), '0.33'.to_r)
+ assert_equal(Rational(-33,100), '-.33'.to_r)
+ assert_equal(Rational(-33,100), '-0.33'.to_r)
+ assert_equal(Rational(-33,100), '-0.3_3'.to_r)
+
+ assert_equal(Rational(1,2), '5e-1'.to_r)
+ assert_equal(Rational(50), '5e+1'.to_r)
+ assert_equal(Rational(1,2), '5.0e-1'.to_r)
+ assert_equal(Rational(50), '5.0e+1'.to_r)
+ assert_equal(Rational(50), '5e1'.to_r)
+ assert_equal(Rational(50), '5E1'.to_r)
+ assert_equal(Rational(500), '5e2'.to_r)
+ assert_equal(Rational(5000), '5e3'.to_r)
+ assert_equal(Rational(500000000000), '5e1_1'.to_r)
+
+ assert_equal(Rational(5), Rational('5'))
+ assert_equal(Rational(-5), Rational('-5'))
+ assert_equal(Rational(5,3), Rational('5/3'))
+ assert_equal(Rational(-5,3), Rational('-5/3'))
+# assert_equal(Rational(5,-3), Rational('5/-3'))
+# assert_equal(Rational(-5,-3), Rational('-5/-3'))
+
+ assert_equal(Rational(5), Rational('5.0'))
+ assert_equal(Rational(-5), Rational('-5.0'))
+ assert_equal(Rational(5,3), Rational('5.0/3'))
+ assert_equal(Rational(-5,3), Rational('-5.0/3'))
+# assert_equal(Rational(5,-3), Rational('5.0/-3'))
+# assert_equal(Rational(-5,-3), Rational('-5.0/-3'))
+
+ assert_equal(Rational(5), Rational('5e0'))
+ assert_equal(Rational(-5), Rational('-5e0'))
+ assert_equal(Rational(5,3), Rational('5e0/3'))
+ assert_equal(Rational(-5,3), Rational('-5e0/3'))
+# assert_equal(Rational(5,-3), Rational('5e0/-3'))
+# assert_equal(Rational(-5,-3), Rational('-5e0/-3'))
+
+ assert_equal(Rational(33,100), Rational('.33'))
+ assert_equal(Rational(33,100), Rational('0.33'))
+ assert_equal(Rational(-33,100), Rational('-.33'))
+ assert_equal(Rational(-33,100), Rational('-0.33'))
+ assert_equal(Rational(-33,100), Rational('-0.3_3'))
+
+ assert_equal(Rational(1,2), Rational('5e-1'))
+ assert_equal(Rational(50), Rational('5e+1'))
+ assert_equal(Rational(1,2), Rational('5.0e-1'))
+ assert_equal(Rational(50), Rational('5.0e+1'))
+ assert_equal(Rational(50), Rational('5e1'))
+ assert_equal(Rational(50), Rational('5E1'))
+ assert_equal(Rational(500), Rational('5e2'))
+ assert_equal(Rational(5000), Rational('5e3'))
+ assert_equal(Rational(500000000000), Rational('5e1_1'))
+
+ assert_equal(Rational(0), ''.to_r)
+ assert_equal(Rational(0), ' '.to_r)
+ assert_equal(Rational(5), "\f\n\r\t\v5\0".to_r)
+ assert_equal(Rational(0), '_'.to_r)
+ assert_equal(Rational(0), '_5'.to_r)
+ assert_equal(Rational(5), '5_'.to_r)
+ assert_equal(Rational(5), '5x'.to_r)
+ assert_equal(Rational(5), '5/_3'.to_r)
+ assert_equal(Rational(5,3), '5/3_'.to_r)
+ assert_equal(Rational(5,3), '5/3.3'.to_r)
+ assert_equal(Rational(5,3), '5/3x'.to_r)
+ assert_raise(ArgumentError){ Rational('')}
+ assert_raise(ArgumentError){ Rational('_')}
+ assert_raise(ArgumentError){ Rational("\f\n\r\t\v5\0")}
+ assert_raise(ArgumentError){ Rational('_5')}
+ assert_raise(ArgumentError){ Rational('5_')}
+ assert_raise(ArgumentError){ Rational('5x')}
+ assert_raise(ArgumentError){ Rational('5/_3')}
+ assert_raise(ArgumentError){ Rational('5/3_')}
+ assert_raise(ArgumentError){ Rational('5/3.3')}
+ assert_raise(ArgumentError){ Rational('5/3x')}
+ end
+
+=begin
+ def test_reciprocal
+ assert_equal(Rational(1,9), Rational(9,1).reciprocal)
+ assert_equal(Rational(9,1), Rational(1,9).reciprocal)
+ assert_equal(Rational(-1,9), Rational(-9,1).reciprocal)
+ assert_equal(Rational(-9,1), Rational(-1,9).reciprocal)
+ assert_equal(Rational(1,9), Rational(9,1).inverse)
+ assert_equal(Rational(9,1), Rational(1,9).inverse)
+ assert_equal(Rational(-1,9), Rational(-9,1).inverse)
+ assert_equal(Rational(-9,1), Rational(-1,9).inverse)
+ end
+=end
+
+ def test_to_i
+ assert_equal(1, Rational(3,2).to_i)
+ assert_equal(1, Integer(Rational(3,2)))
+ end
+
+ def test_to_f
+ assert_equal(1.5, Rational(3,2).to_f)
+ assert_equal(1.5, Float(Rational(3,2)))
+ end
+
+ def test_to_c
+ if @complex && !@keiju
+ if @unify
+ assert_equal(Rational(3,2), Rational(3,2).to_c)
+ assert_equal(Rational(3,2), Complex(Rational(3,2)))
+ else
+ assert_equal(Complex(Rational(3,2)), Rational(3,2).to_c)
+ assert_equal(Complex(Rational(3,2)), Complex(Rational(3,2)))
+ end
+ end
+ end
+
+ def test_to_r
+ c = nil.to_r
+ assert_equal([0,1], [c.numerator, c.denominator])
+
+ c = 0.to_r
+ assert_equal([0,1], [c.numerator, c.denominator])
+
+ c = 1.to_r
+ assert_equal([1,1], [c.numerator, c.denominator])
+
+ c = 1.1.to_r
+ assert_equal([2476979795053773, 2251799813685248],
+ [c.numerator, c.denominator])
+
+ c = Rational(1,2).to_r
+ assert_equal([1,2], [c.numerator, c.denominator])
+
+ if @complex
+ if @keiju
+ assert_raise(NoMethodError){Complex(1,2).to_r}
+ else
+ assert_raise(RangeError){Complex(1,2).to_r}
+ end
+ end
+
+ if (0.0/0).nan?
+ assert_raise(FloatDomainError){(0.0/0).to_r}
+ end
+ if (1.0/0).infinite?
+ assert_raise(FloatDomainError){(1.0/0).to_r}
+ end
+ end
+
+ def test_rationalize
+ c = nil.rationalize
+ assert_equal([0,1], [c.numerator, c.denominator])
+
+ c = 0.rationalize
+ assert_equal([0,1], [c.numerator, c.denominator])
+
+ c = 1.rationalize
+ assert_equal([1,1], [c.numerator, c.denominator])
+
+ c = 1.1.rationalize
+ assert_equal([11, 10], [c.numerator, c.denominator])
+
+ c = Rational(1,2).rationalize
+ assert_equal([1,2], [c.numerator, c.denominator])
+
+ assert_equal(nil.rationalize(Rational(1,10)), Rational(0))
+ assert_equal(0.rationalize(Rational(1,10)), Rational(0))
+ assert_equal(10.rationalize(Rational(1,10)), Rational(10))
+
+ r = 0.3333
+ assert_equal(r.rationalize, Rational(3333, 10000))
+ assert_equal(r.rationalize(Rational(1,10)), Rational(1,3))
+ assert_equal(r.rationalize(Rational(-1,10)), Rational(1,3))
+
+ r = Rational(5404319552844595,18014398509481984)
+ assert_equal(r.rationalize, r)
+ assert_equal(r.rationalize(Rational(1,10)), Rational(1,3))
+ assert_equal(r.rationalize(Rational(-1,10)), Rational(1,3))
+
+ r = -0.3333
+ assert_equal(r.rationalize, Rational(-3333, 10000))
+ assert_equal(r.rationalize(Rational(1,10)), Rational(-1,3))
+ assert_equal(r.rationalize(Rational(-1,10)), Rational(-1,3))
+
+ r = Rational(-5404319552844595,18014398509481984)
+ assert_equal(r.rationalize, r)
+ assert_equal(r.rationalize(Rational(1,10)), Rational(-1,3))
+ assert_equal(r.rationalize(Rational(-1,10)), Rational(-1,3))
+
+ if @complex
+ if @keiju
+ else
+ assert_raise(RangeError){Complex(1,2).rationalize}
+ end
+ end
+
+ if (0.0/0).nan?
+ assert_raise(FloatDomainError){(0.0/0).rationalize}
+ end
+ if (1.0/0).infinite?
+ assert_raise(FloatDomainError){(1.0/0).rationalize}
+ end
+ end
+
+ def test_gcdlcm
+ assert_equal(7, 91.gcd(-49))
+ assert_equal(5, 5.gcd(0))
+ assert_equal(5, 0.gcd(5))
+ assert_equal(70, 14.lcm(35))
+ assert_equal(0, 5.lcm(0))
+ assert_equal(0, 0.lcm(5))
+ assert_equal([5,0], 0.gcdlcm(5))
+ assert_equal([5,0], 5.gcdlcm(0))
+
+ assert_equal(1, 1073741827.gcd(1073741789))
+ assert_equal(1152921470247108503, 1073741827.lcm(1073741789))
+
+ assert_equal(1, 1073741789.gcd(1073741827))
+ assert_equal(1152921470247108503, 1073741789.lcm(1073741827))
+ end
+
+ def test_supp
+ assert_equal(true, 1.real?)
+ assert_equal(true, 1.1.real?)
+
+ assert_equal(1, 1.numerator)
+ assert_equal(9, 9.numerator)
+ assert_equal(1, 1.denominator)
+ assert_equal(1, 9.denominator)
+
+ assert_equal(1.0, 1.0.numerator)
+ assert_equal(9.0, 9.0.numerator)
+ assert_equal(1.0, 1.0.denominator)
+ assert_equal(1.0, 9.0.denominator)
+
+=begin
+ assert_equal(Rational(1,9), 9.reciprocal)
+ assert_in_delta(0.1111, 9.0.reciprocal, 0.001)
+ assert_equal(Rational(1,9), 9.inverse)
+ assert_in_delta(0.1111, 9.0.inverse, 0.001)
+=end
+
+ assert_equal(Rational(1,2), 1.quo(2))
+ assert_equal(Rational(5000000000), 10000000000.quo(2))
+ assert_equal(0.5, 1.0.quo(2))
+ assert_equal(Rational(1,4), Rational(1,2).quo(2))
+
+ assert_equal(0.5, 1.fdiv(2))
+ assert_equal(5000000000.0, 10000000000.fdiv(2))
+ assert_equal(0.5, 1.0.fdiv(2))
+ assert_equal(0.25, Rational(1,2).fdiv(2))
+ end
+
+ def test_ruby19
+ assert_raise(NoMethodError){ Rational.new(1) }
+ assert_raise(NoMethodError){ Rational.new!(1) }
+ end
+
+ def test_fixed_bug
+ if @unify
+ assert_instance_of(Fixnum, Rational(1,2) ** 0) # mathn's bug
+ end
+
+ n = Float::MAX.to_i * 2
+ assert_equal(1.0, Rational(n + 2, n + 1).to_f, '[ruby-dev:33852]')
+ end
+
+ def test_known_bug
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_rational2.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_rational2.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_rational2.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1386 @@
+require 'test/unit'
+
+class Rational_Test2 < Test::Unit::TestCase
+
+ def test_kumi
+ assert_equal(Rational(1, 1), +Rational(1, 1))
+ assert_equal(Rational(-1, 1), -Rational(1, 1))
+ assert_equal(Rational(2, 1),
+ Rational(1, 1) + Rational(1, 1))
+ assert_equal(Rational(0, 1),
+ Rational(1, 1) - Rational(1, 1))
+ assert_equal(Rational(1, 1),
+ Rational(1, 1) * Rational(1, 1))
+ assert_equal(Rational(1, 1),
+ Rational(1, 1) / Rational(1, 1))
+ assert_equal(Rational(3, 1),
+ Rational(1, 1) + Rational(2, 1))
+ assert_equal(Rational(-1, 1),
+ Rational(1, 1) - Rational(2, 1))
+ assert_equal(Rational(2, 1),
+ Rational(1, 1) * Rational(2, 1))
+ assert_equal(Rational(1, 2),
+ Rational(1, 1) / Rational(2, 1))
+ assert_equal(Rational(4, 1),
+ Rational(1, 1) + Rational(3, 1))
+ assert_equal(Rational(-2, 1),
+ Rational(1, 1) - Rational(3, 1))
+ assert_equal(Rational(3, 1),
+ Rational(1, 1) * Rational(3, 1))
+ assert_equal(Rational(1, 3),
+ Rational(1, 1) / Rational(3, 1))
+ assert_equal(Rational(1073741790, 1),
+ Rational(1, 1) + Rational(1073741789, 1))
+ assert_equal(Rational(-1073741788, 1),
+ Rational(1, 1) - Rational(1073741789, 1))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1, 1) * Rational(1073741789, 1))
+ assert_equal(Rational(1, 1073741789),
+ Rational(1, 1) / Rational(1073741789, 1))
+ assert_equal(Rational(1073741828, 1),
+ Rational(1, 1) + Rational(1073741827, 1))
+ assert_equal(Rational(-1073741826, 1),
+ Rational(1, 1) - Rational(1073741827, 1))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1, 1) * Rational(1073741827, 1))
+ assert_equal(Rational(1, 1073741827),
+ Rational(1, 1) / Rational(1073741827, 1))
+ assert_equal(Rational(5, 3),
+ Rational(1, 1) + Rational(2, 3))
+ assert_equal(Rational(1, 3),
+ Rational(1, 1) - Rational(2, 3))
+ assert_equal(Rational(2, 3),
+ Rational(1, 1) * Rational(2, 3))
+ assert_equal(Rational(3, 2),
+ Rational(1, 1) / Rational(2, 3))
+ assert_equal(Rational(5, 2),
+ Rational(1, 1) + Rational(3, 2))
+ assert_equal(Rational(-1, 2),
+ Rational(1, 1) - Rational(3, 2))
+ assert_equal(Rational(3, 2),
+ Rational(1, 1) * Rational(3, 2))
+ assert_equal(Rational(2, 3),
+ Rational(1, 1) / Rational(3, 2))
+ assert_equal(Rational(1073741792, 1073741789),
+ Rational(1, 1) + Rational(3, 1073741789))
+ assert_equal(Rational(1073741786, 1073741789),
+ Rational(1, 1) - Rational(3, 1073741789))
+ assert_equal(Rational(3, 1073741789),
+ Rational(1, 1) * Rational(3, 1073741789))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1, 1) / Rational(3, 1073741789))
+ assert_equal(Rational(1073741792, 3),
+ Rational(1, 1) + Rational(1073741789, 3))
+ assert_equal(Rational(-1073741786, 3),
+ Rational(1, 1) - Rational(1073741789, 3))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1, 1) * Rational(1073741789, 3))
+ assert_equal(Rational(3, 1073741789),
+ Rational(1, 1) / Rational(1073741789, 3))
+ assert_equal(Rational(1073741830, 1073741827),
+ Rational(1, 1) + Rational(3, 1073741827))
+ assert_equal(Rational(1073741824, 1073741827),
+ Rational(1, 1) - Rational(3, 1073741827))
+ assert_equal(Rational(3, 1073741827),
+ Rational(1, 1) * Rational(3, 1073741827))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1, 1) / Rational(3, 1073741827))
+ assert_equal(Rational(1073741830, 3),
+ Rational(1, 1) + Rational(1073741827, 3))
+ assert_equal(Rational(-1073741824, 3),
+ Rational(1, 1) - Rational(1073741827, 3))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1, 1) * Rational(1073741827, 3))
+ assert_equal(Rational(3, 1073741827),
+ Rational(1, 1) / Rational(1073741827, 3))
+ assert_equal(Rational(2147483616, 1073741827),
+ Rational(1, 1) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(38, 1073741827),
+ Rational(1, 1) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1, 1) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1, 1) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483616, 1073741789),
+ Rational(1, 1) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(-38, 1073741789),
+ Rational(1, 1) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1, 1) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1, 1) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(2, 1), +Rational(2, 1))
+ assert_equal(Rational(-2, 1), -Rational(2, 1))
+ assert_equal(Rational(3, 1),
+ Rational(2, 1) + Rational(1, 1))
+ assert_equal(Rational(1, 1),
+ Rational(2, 1) - Rational(1, 1))
+ assert_equal(Rational(2, 1),
+ Rational(2, 1) * Rational(1, 1))
+ assert_equal(Rational(2, 1),
+ Rational(2, 1) / Rational(1, 1))
+ assert_equal(Rational(4, 1),
+ Rational(2, 1) + Rational(2, 1))
+ assert_equal(Rational(0, 1),
+ Rational(2, 1) - Rational(2, 1))
+ assert_equal(Rational(4, 1),
+ Rational(2, 1) * Rational(2, 1))
+ assert_equal(Rational(1, 1),
+ Rational(2, 1) / Rational(2, 1))
+ assert_equal(Rational(5, 1),
+ Rational(2, 1) + Rational(3, 1))
+ assert_equal(Rational(-1, 1),
+ Rational(2, 1) - Rational(3, 1))
+ assert_equal(Rational(6, 1),
+ Rational(2, 1) * Rational(3, 1))
+ assert_equal(Rational(2, 3),
+ Rational(2, 1) / Rational(3, 1))
+ assert_equal(Rational(1073741791, 1),
+ Rational(2, 1) + Rational(1073741789, 1))
+ assert_equal(Rational(-1073741787, 1),
+ Rational(2, 1) - Rational(1073741789, 1))
+ assert_equal(Rational(2147483578, 1),
+ Rational(2, 1) * Rational(1073741789, 1))
+ assert_equal(Rational(2, 1073741789),
+ Rational(2, 1) / Rational(1073741789, 1))
+ assert_equal(Rational(1073741829, 1),
+ Rational(2, 1) + Rational(1073741827, 1))
+ assert_equal(Rational(-1073741825, 1),
+ Rational(2, 1) - Rational(1073741827, 1))
+ assert_equal(Rational(2147483654, 1),
+ Rational(2, 1) * Rational(1073741827, 1))
+ assert_equal(Rational(2, 1073741827),
+ Rational(2, 1) / Rational(1073741827, 1))
+ assert_equal(Rational(8, 3),
+ Rational(2, 1) + Rational(2, 3))
+ assert_equal(Rational(4, 3),
+ Rational(2, 1) - Rational(2, 3))
+ assert_equal(Rational(4, 3),
+ Rational(2, 1) * Rational(2, 3))
+ assert_equal(Rational(3, 1),
+ Rational(2, 1) / Rational(2, 3))
+ assert_equal(Rational(7, 2),
+ Rational(2, 1) + Rational(3, 2))
+ assert_equal(Rational(1, 2),
+ Rational(2, 1) - Rational(3, 2))
+ assert_equal(Rational(3, 1),
+ Rational(2, 1) * Rational(3, 2))
+ assert_equal(Rational(4, 3),
+ Rational(2, 1) / Rational(3, 2))
+ assert_equal(Rational(2147483581, 1073741789),
+ Rational(2, 1) + Rational(3, 1073741789))
+ assert_equal(Rational(2147483575, 1073741789),
+ Rational(2, 1) - Rational(3, 1073741789))
+ assert_equal(Rational(6, 1073741789),
+ Rational(2, 1) * Rational(3, 1073741789))
+ assert_equal(Rational(2147483578, 3),
+ Rational(2, 1) / Rational(3, 1073741789))
+ assert_equal(Rational(1073741795, 3),
+ Rational(2, 1) + Rational(1073741789, 3))
+ assert_equal(Rational(-1073741783, 3),
+ Rational(2, 1) - Rational(1073741789, 3))
+ assert_equal(Rational(2147483578, 3),
+ Rational(2, 1) * Rational(1073741789, 3))
+ assert_equal(Rational(6, 1073741789),
+ Rational(2, 1) / Rational(1073741789, 3))
+ assert_equal(Rational(2147483657, 1073741827),
+ Rational(2, 1) + Rational(3, 1073741827))
+ assert_equal(Rational(2147483651, 1073741827),
+ Rational(2, 1) - Rational(3, 1073741827))
+ assert_equal(Rational(6, 1073741827),
+ Rational(2, 1) * Rational(3, 1073741827))
+ assert_equal(Rational(2147483654, 3),
+ Rational(2, 1) / Rational(3, 1073741827))
+ assert_equal(Rational(1073741833, 3),
+ Rational(2, 1) + Rational(1073741827, 3))
+ assert_equal(Rational(-1073741821, 3),
+ Rational(2, 1) - Rational(1073741827, 3))
+ assert_equal(Rational(2147483654, 3),
+ Rational(2, 1) * Rational(1073741827, 3))
+ assert_equal(Rational(6, 1073741827),
+ Rational(2, 1) / Rational(1073741827, 3))
+ assert_equal(Rational(3221225443, 1073741827),
+ Rational(2, 1) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741865, 1073741827),
+ Rational(2, 1) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483578, 1073741827),
+ Rational(2, 1) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483654, 1073741789),
+ Rational(2, 1) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225405, 1073741789),
+ Rational(2, 1) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741751, 1073741789),
+ Rational(2, 1) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483654, 1073741789),
+ Rational(2, 1) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483578, 1073741827),
+ Rational(2, 1) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(3, 1), +Rational(3, 1))
+ assert_equal(Rational(-3, 1), -Rational(3, 1))
+ assert_equal(Rational(4, 1),
+ Rational(3, 1) + Rational(1, 1))
+ assert_equal(Rational(2, 1),
+ Rational(3, 1) - Rational(1, 1))
+ assert_equal(Rational(3, 1),
+ Rational(3, 1) * Rational(1, 1))
+ assert_equal(Rational(3, 1),
+ Rational(3, 1) / Rational(1, 1))
+ assert_equal(Rational(5, 1),
+ Rational(3, 1) + Rational(2, 1))
+ assert_equal(Rational(1, 1),
+ Rational(3, 1) - Rational(2, 1))
+ assert_equal(Rational(6, 1),
+ Rational(3, 1) * Rational(2, 1))
+ assert_equal(Rational(3, 2),
+ Rational(3, 1) / Rational(2, 1))
+ assert_equal(Rational(6, 1),
+ Rational(3, 1) + Rational(3, 1))
+ assert_equal(Rational(0, 1),
+ Rational(3, 1) - Rational(3, 1))
+ assert_equal(Rational(9, 1),
+ Rational(3, 1) * Rational(3, 1))
+ assert_equal(Rational(1, 1),
+ Rational(3, 1) / Rational(3, 1))
+ assert_equal(Rational(1073741792, 1),
+ Rational(3, 1) + Rational(1073741789, 1))
+ assert_equal(Rational(-1073741786, 1),
+ Rational(3, 1) - Rational(1073741789, 1))
+ assert_equal(Rational(3221225367, 1),
+ Rational(3, 1) * Rational(1073741789, 1))
+ assert_equal(Rational(3, 1073741789),
+ Rational(3, 1) / Rational(1073741789, 1))
+ assert_equal(Rational(1073741830, 1),
+ Rational(3, 1) + Rational(1073741827, 1))
+ assert_equal(Rational(-1073741824, 1),
+ Rational(3, 1) - Rational(1073741827, 1))
+ assert_equal(Rational(3221225481, 1),
+ Rational(3, 1) * Rational(1073741827, 1))
+ assert_equal(Rational(3, 1073741827),
+ Rational(3, 1) / Rational(1073741827, 1))
+ assert_equal(Rational(11, 3),
+ Rational(3, 1) + Rational(2, 3))
+ assert_equal(Rational(7, 3),
+ Rational(3, 1) - Rational(2, 3))
+ assert_equal(Rational(2, 1),
+ Rational(3, 1) * Rational(2, 3))
+ assert_equal(Rational(9, 2),
+ Rational(3, 1) / Rational(2, 3))
+ assert_equal(Rational(9, 2),
+ Rational(3, 1) + Rational(3, 2))
+ assert_equal(Rational(3, 2),
+ Rational(3, 1) - Rational(3, 2))
+ assert_equal(Rational(9, 2),
+ Rational(3, 1) * Rational(3, 2))
+ assert_equal(Rational(2, 1),
+ Rational(3, 1) / Rational(3, 2))
+ assert_equal(Rational(3221225370, 1073741789),
+ Rational(3, 1) + Rational(3, 1073741789))
+ assert_equal(Rational(3221225364, 1073741789),
+ Rational(3, 1) - Rational(3, 1073741789))
+ assert_equal(Rational(9, 1073741789),
+ Rational(3, 1) * Rational(3, 1073741789))
+ assert_equal(Rational(1073741789, 1),
+ Rational(3, 1) / Rational(3, 1073741789))
+ assert_equal(Rational(1073741798, 3),
+ Rational(3, 1) + Rational(1073741789, 3))
+ assert_equal(Rational(-1073741780, 3),
+ Rational(3, 1) - Rational(1073741789, 3))
+ assert_equal(Rational(1073741789, 1),
+ Rational(3, 1) * Rational(1073741789, 3))
+ assert_equal(Rational(9, 1073741789),
+ Rational(3, 1) / Rational(1073741789, 3))
+ assert_equal(Rational(3221225484, 1073741827),
+ Rational(3, 1) + Rational(3, 1073741827))
+ assert_equal(Rational(3221225478, 1073741827),
+ Rational(3, 1) - Rational(3, 1073741827))
+ assert_equal(Rational(9, 1073741827),
+ Rational(3, 1) * Rational(3, 1073741827))
+ assert_equal(Rational(1073741827, 1),
+ Rational(3, 1) / Rational(3, 1073741827))
+ assert_equal(Rational(1073741836, 3),
+ Rational(3, 1) + Rational(1073741827, 3))
+ assert_equal(Rational(-1073741818, 3),
+ Rational(3, 1) - Rational(1073741827, 3))
+ assert_equal(Rational(1073741827, 1),
+ Rational(3, 1) * Rational(1073741827, 3))
+ assert_equal(Rational(9, 1073741827),
+ Rational(3, 1) / Rational(1073741827, 3))
+ assert_equal(Rational(4294967270, 1073741827),
+ Rational(3, 1) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483692, 1073741827),
+ Rational(3, 1) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225367, 1073741827),
+ Rational(3, 1) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225481, 1073741789),
+ Rational(3, 1) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(4294967194, 1073741789),
+ Rational(3, 1) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483540, 1073741789),
+ Rational(3, 1) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(3221225481, 1073741789),
+ Rational(3, 1) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(3221225367, 1073741827),
+ Rational(3, 1) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741789, 1), +Rational(1073741789, 1))
+ assert_equal(Rational(-1073741789, 1), -Rational(1073741789, 1))
+ assert_equal(Rational(1073741790, 1),
+ Rational(1073741789, 1) + Rational(1, 1))
+ assert_equal(Rational(1073741788, 1),
+ Rational(1073741789, 1) - Rational(1, 1))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1073741789, 1) * Rational(1, 1))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1073741789, 1) / Rational(1, 1))
+ assert_equal(Rational(1073741791, 1),
+ Rational(1073741789, 1) + Rational(2, 1))
+ assert_equal(Rational(1073741787, 1),
+ Rational(1073741789, 1) - Rational(2, 1))
+ assert_equal(Rational(2147483578, 1),
+ Rational(1073741789, 1) * Rational(2, 1))
+ assert_equal(Rational(1073741789, 2),
+ Rational(1073741789, 1) / Rational(2, 1))
+ assert_equal(Rational(1073741792, 1),
+ Rational(1073741789, 1) + Rational(3, 1))
+ assert_equal(Rational(1073741786, 1),
+ Rational(1073741789, 1) - Rational(3, 1))
+ assert_equal(Rational(3221225367, 1),
+ Rational(1073741789, 1) * Rational(3, 1))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741789, 1) / Rational(3, 1))
+ assert_equal(Rational(2147483578, 1),
+ Rational(1073741789, 1) + Rational(1073741789, 1))
+ assert_equal(Rational(0, 1),
+ Rational(1073741789, 1) - Rational(1073741789, 1))
+ assert_equal(Rational(1152921429444920521, 1),
+ Rational(1073741789, 1) * Rational(1073741789, 1))
+ assert_equal(Rational(1, 1),
+ Rational(1073741789, 1) / Rational(1073741789, 1))
+ assert_equal(Rational(2147483616, 1),
+ Rational(1073741789, 1) + Rational(1073741827, 1))
+ assert_equal(Rational(-38, 1),
+ Rational(1073741789, 1) - Rational(1073741827, 1))
+ assert_equal(Rational(1152921470247108503, 1),
+ Rational(1073741789, 1) * Rational(1073741827, 1))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1073741789, 1) / Rational(1073741827, 1))
+ assert_equal(Rational(3221225369, 3),
+ Rational(1073741789, 1) + Rational(2, 3))
+ assert_equal(Rational(3221225365, 3),
+ Rational(1073741789, 1) - Rational(2, 3))
+ assert_equal(Rational(2147483578, 3),
+ Rational(1073741789, 1) * Rational(2, 3))
+ assert_equal(Rational(3221225367, 2),
+ Rational(1073741789, 1) / Rational(2, 3))
+ assert_equal(Rational(2147483581, 2),
+ Rational(1073741789, 1) + Rational(3, 2))
+ assert_equal(Rational(2147483575, 2),
+ Rational(1073741789, 1) - Rational(3, 2))
+ assert_equal(Rational(3221225367, 2),
+ Rational(1073741789, 1) * Rational(3, 2))
+ assert_equal(Rational(2147483578, 3),
+ Rational(1073741789, 1) / Rational(3, 2))
+ assert_equal(Rational(1152921429444920524, 1073741789),
+ Rational(1073741789, 1) + Rational(3, 1073741789))
+ assert_equal(Rational(1152921429444920518, 1073741789),
+ Rational(1073741789, 1) - Rational(3, 1073741789))
+ assert_equal(Rational(3, 1),
+ Rational(1073741789, 1) * Rational(3, 1073741789))
+ assert_equal(Rational(1152921429444920521, 3),
+ Rational(1073741789, 1) / Rational(3, 1073741789))
+ assert_equal(Rational(4294967156, 3),
+ Rational(1073741789, 1) + Rational(1073741789, 3))
+ assert_equal(Rational(2147483578, 3),
+ Rational(1073741789, 1) - Rational(1073741789, 3))
+ assert_equal(Rational(1152921429444920521, 3),
+ Rational(1073741789, 1) * Rational(1073741789, 3))
+ assert_equal(Rational(3, 1),
+ Rational(1073741789, 1) / Rational(1073741789, 3))
+ assert_equal(Rational(1152921470247108506, 1073741827),
+ Rational(1073741789, 1) + Rational(3, 1073741827))
+ assert_equal(Rational(1152921470247108500, 1073741827),
+ Rational(1073741789, 1) - Rational(3, 1073741827))
+ assert_equal(Rational(3221225367, 1073741827),
+ Rational(1073741789, 1) * Rational(3, 1073741827))
+ assert_equal(Rational(1152921470247108503, 3),
+ Rational(1073741789, 1) / Rational(3, 1073741827))
+ assert_equal(Rational(4294967194, 3),
+ Rational(1073741789, 1) + Rational(1073741827, 3))
+ assert_equal(Rational(2147483540, 3),
+ Rational(1073741789, 1) - Rational(1073741827, 3))
+ assert_equal(Rational(1152921470247108503, 3),
+ Rational(1073741789, 1) * Rational(1073741827, 3))
+ assert_equal(Rational(3221225367, 1073741827),
+ Rational(1073741789, 1) / Rational(1073741827, 3))
+ assert_equal(Rational(1152921471320850292, 1073741827),
+ Rational(1073741789, 1) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921469173366714, 1073741827),
+ Rational(1073741789, 1) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921429444920521, 1073741827),
+ Rational(1073741789, 1) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1073741789, 1) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921430518662348, 1073741789),
+ Rational(1073741789, 1) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921428371178694, 1073741789),
+ Rational(1073741789, 1) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1073741789, 1) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921429444920521, 1073741827),
+ Rational(1073741789, 1) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741827, 1), +Rational(1073741827, 1))
+ assert_equal(Rational(-1073741827, 1), -Rational(1073741827, 1))
+ assert_equal(Rational(1073741828, 1),
+ Rational(1073741827, 1) + Rational(1, 1))
+ assert_equal(Rational(1073741826, 1),
+ Rational(1073741827, 1) - Rational(1, 1))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1073741827, 1) * Rational(1, 1))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1073741827, 1) / Rational(1, 1))
+ assert_equal(Rational(1073741829, 1),
+ Rational(1073741827, 1) + Rational(2, 1))
+ assert_equal(Rational(1073741825, 1),
+ Rational(1073741827, 1) - Rational(2, 1))
+ assert_equal(Rational(2147483654, 1),
+ Rational(1073741827, 1) * Rational(2, 1))
+ assert_equal(Rational(1073741827, 2),
+ Rational(1073741827, 1) / Rational(2, 1))
+ assert_equal(Rational(1073741830, 1),
+ Rational(1073741827, 1) + Rational(3, 1))
+ assert_equal(Rational(1073741824, 1),
+ Rational(1073741827, 1) - Rational(3, 1))
+ assert_equal(Rational(3221225481, 1),
+ Rational(1073741827, 1) * Rational(3, 1))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741827, 1) / Rational(3, 1))
+ assert_equal(Rational(2147483616, 1),
+ Rational(1073741827, 1) + Rational(1073741789, 1))
+ assert_equal(Rational(38, 1),
+ Rational(1073741827, 1) - Rational(1073741789, 1))
+ assert_equal(Rational(1152921470247108503, 1),
+ Rational(1073741827, 1) * Rational(1073741789, 1))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1073741827, 1) / Rational(1073741789, 1))
+ assert_equal(Rational(2147483654, 1),
+ Rational(1073741827, 1) + Rational(1073741827, 1))
+ assert_equal(Rational(0, 1),
+ Rational(1073741827, 1) - Rational(1073741827, 1))
+ assert_equal(Rational(1152921511049297929, 1),
+ Rational(1073741827, 1) * Rational(1073741827, 1))
+ assert_equal(Rational(1, 1),
+ Rational(1073741827, 1) / Rational(1073741827, 1))
+ assert_equal(Rational(3221225483, 3),
+ Rational(1073741827, 1) + Rational(2, 3))
+ assert_equal(Rational(3221225479, 3),
+ Rational(1073741827, 1) - Rational(2, 3))
+ assert_equal(Rational(2147483654, 3),
+ Rational(1073741827, 1) * Rational(2, 3))
+ assert_equal(Rational(3221225481, 2),
+ Rational(1073741827, 1) / Rational(2, 3))
+ assert_equal(Rational(2147483657, 2),
+ Rational(1073741827, 1) + Rational(3, 2))
+ assert_equal(Rational(2147483651, 2),
+ Rational(1073741827, 1) - Rational(3, 2))
+ assert_equal(Rational(3221225481, 2),
+ Rational(1073741827, 1) * Rational(3, 2))
+ assert_equal(Rational(2147483654, 3),
+ Rational(1073741827, 1) / Rational(3, 2))
+ assert_equal(Rational(1152921470247108506, 1073741789),
+ Rational(1073741827, 1) + Rational(3, 1073741789))
+ assert_equal(Rational(1152921470247108500, 1073741789),
+ Rational(1073741827, 1) - Rational(3, 1073741789))
+ assert_equal(Rational(3221225481, 1073741789),
+ Rational(1073741827, 1) * Rational(3, 1073741789))
+ assert_equal(Rational(1152921470247108503, 3),
+ Rational(1073741827, 1) / Rational(3, 1073741789))
+ assert_equal(Rational(4294967270, 3),
+ Rational(1073741827, 1) + Rational(1073741789, 3))
+ assert_equal(Rational(2147483692, 3),
+ Rational(1073741827, 1) - Rational(1073741789, 3))
+ assert_equal(Rational(1152921470247108503, 3),
+ Rational(1073741827, 1) * Rational(1073741789, 3))
+ assert_equal(Rational(3221225481, 1073741789),
+ Rational(1073741827, 1) / Rational(1073741789, 3))
+ assert_equal(Rational(1152921511049297932, 1073741827),
+ Rational(1073741827, 1) + Rational(3, 1073741827))
+ assert_equal(Rational(1152921511049297926, 1073741827),
+ Rational(1073741827, 1) - Rational(3, 1073741827))
+ assert_equal(Rational(3, 1),
+ Rational(1073741827, 1) * Rational(3, 1073741827))
+ assert_equal(Rational(1152921511049297929, 3),
+ Rational(1073741827, 1) / Rational(3, 1073741827))
+ assert_equal(Rational(4294967308, 3),
+ Rational(1073741827, 1) + Rational(1073741827, 3))
+ assert_equal(Rational(2147483654, 3),
+ Rational(1073741827, 1) - Rational(1073741827, 3))
+ assert_equal(Rational(1152921511049297929, 3),
+ Rational(1073741827, 1) * Rational(1073741827, 3))
+ assert_equal(Rational(3, 1),
+ Rational(1073741827, 1) / Rational(1073741827, 3))
+ assert_equal(Rational(1152921512123039718, 1073741827),
+ Rational(1073741827, 1) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921509975556140, 1073741827),
+ Rational(1073741827, 1) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1073741827, 1) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921511049297929, 1073741789),
+ Rational(1073741827, 1) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921471320850330, 1073741789),
+ Rational(1073741827, 1) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921469173366676, 1073741789),
+ Rational(1073741827, 1) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921511049297929, 1073741789),
+ Rational(1073741827, 1) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1073741827, 1) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(2, 3), +Rational(2, 3))
+ assert_equal(Rational(-2, 3), -Rational(2, 3))
+ assert_equal(Rational(5, 3),
+ Rational(2, 3) + Rational(1, 1))
+ assert_equal(Rational(-1, 3),
+ Rational(2, 3) - Rational(1, 1))
+ assert_equal(Rational(2, 3),
+ Rational(2, 3) * Rational(1, 1))
+ assert_equal(Rational(2, 3),
+ Rational(2, 3) / Rational(1, 1))
+ assert_equal(Rational(8, 3),
+ Rational(2, 3) + Rational(2, 1))
+ assert_equal(Rational(-4, 3),
+ Rational(2, 3) - Rational(2, 1))
+ assert_equal(Rational(4, 3),
+ Rational(2, 3) * Rational(2, 1))
+ assert_equal(Rational(1, 3),
+ Rational(2, 3) / Rational(2, 1))
+ assert_equal(Rational(11, 3),
+ Rational(2, 3) + Rational(3, 1))
+ assert_equal(Rational(-7, 3),
+ Rational(2, 3) - Rational(3, 1))
+ assert_equal(Rational(2, 1),
+ Rational(2, 3) * Rational(3, 1))
+ assert_equal(Rational(2, 9),
+ Rational(2, 3) / Rational(3, 1))
+ assert_equal(Rational(3221225369, 3),
+ Rational(2, 3) + Rational(1073741789, 1))
+ assert_equal(Rational(-3221225365, 3),
+ Rational(2, 3) - Rational(1073741789, 1))
+ assert_equal(Rational(2147483578, 3),
+ Rational(2, 3) * Rational(1073741789, 1))
+ assert_equal(Rational(2, 3221225367),
+ Rational(2, 3) / Rational(1073741789, 1))
+ assert_equal(Rational(3221225483, 3),
+ Rational(2, 3) + Rational(1073741827, 1))
+ assert_equal(Rational(-3221225479, 3),
+ Rational(2, 3) - Rational(1073741827, 1))
+ assert_equal(Rational(2147483654, 3),
+ Rational(2, 3) * Rational(1073741827, 1))
+ assert_equal(Rational(2, 3221225481),
+ Rational(2, 3) / Rational(1073741827, 1))
+ assert_equal(Rational(4, 3),
+ Rational(2, 3) + Rational(2, 3))
+ assert_equal(Rational(0, 1),
+ Rational(2, 3) - Rational(2, 3))
+ assert_equal(Rational(4, 9),
+ Rational(2, 3) * Rational(2, 3))
+ assert_equal(Rational(1, 1),
+ Rational(2, 3) / Rational(2, 3))
+ assert_equal(Rational(13, 6),
+ Rational(2, 3) + Rational(3, 2))
+ assert_equal(Rational(-5, 6),
+ Rational(2, 3) - Rational(3, 2))
+ assert_equal(Rational(1, 1),
+ Rational(2, 3) * Rational(3, 2))
+ assert_equal(Rational(4, 9),
+ Rational(2, 3) / Rational(3, 2))
+ assert_equal(Rational(2147483587, 3221225367),
+ Rational(2, 3) + Rational(3, 1073741789))
+ assert_equal(Rational(2147483569, 3221225367),
+ Rational(2, 3) - Rational(3, 1073741789))
+ assert_equal(Rational(2, 1073741789),
+ Rational(2, 3) * Rational(3, 1073741789))
+ assert_equal(Rational(2147483578, 9),
+ Rational(2, 3) / Rational(3, 1073741789))
+ assert_equal(Rational(1073741791, 3),
+ Rational(2, 3) + Rational(1073741789, 3))
+ assert_equal(Rational(-357913929, 1),
+ Rational(2, 3) - Rational(1073741789, 3))
+ assert_equal(Rational(2147483578, 9),
+ Rational(2, 3) * Rational(1073741789, 3))
+ assert_equal(Rational(2, 1073741789),
+ Rational(2, 3) / Rational(1073741789, 3))
+ assert_equal(Rational(2147483663, 3221225481),
+ Rational(2, 3) + Rational(3, 1073741827))
+ assert_equal(Rational(2147483645, 3221225481),
+ Rational(2, 3) - Rational(3, 1073741827))
+ assert_equal(Rational(2, 1073741827),
+ Rational(2, 3) * Rational(3, 1073741827))
+ assert_equal(Rational(2147483654, 9),
+ Rational(2, 3) / Rational(3, 1073741827))
+ assert_equal(Rational(357913943, 1),
+ Rational(2, 3) + Rational(1073741827, 3))
+ assert_equal(Rational(-1073741825, 3),
+ Rational(2, 3) - Rational(1073741827, 3))
+ assert_equal(Rational(2147483654, 9),
+ Rational(2, 3) * Rational(1073741827, 3))
+ assert_equal(Rational(2, 1073741827),
+ Rational(2, 3) / Rational(1073741827, 3))
+ assert_equal(Rational(5368709021, 3221225481),
+ Rational(2, 3) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(-1073741713, 3221225481),
+ Rational(2, 3) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483578, 3221225481),
+ Rational(2, 3) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483654, 3221225367),
+ Rational(2, 3) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(5368709059, 3221225367),
+ Rational(2, 3) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(-1073741903, 3221225367),
+ Rational(2, 3) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483654, 3221225367),
+ Rational(2, 3) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483578, 3221225481),
+ Rational(2, 3) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(3, 2), +Rational(3, 2))
+ assert_equal(Rational(-3, 2), -Rational(3, 2))
+ assert_equal(Rational(5, 2),
+ Rational(3, 2) + Rational(1, 1))
+ assert_equal(Rational(1, 2),
+ Rational(3, 2) - Rational(1, 1))
+ assert_equal(Rational(3, 2),
+ Rational(3, 2) * Rational(1, 1))
+ assert_equal(Rational(3, 2),
+ Rational(3, 2) / Rational(1, 1))
+ assert_equal(Rational(7, 2),
+ Rational(3, 2) + Rational(2, 1))
+ assert_equal(Rational(-1, 2),
+ Rational(3, 2) - Rational(2, 1))
+ assert_equal(Rational(3, 1),
+ Rational(3, 2) * Rational(2, 1))
+ assert_equal(Rational(3, 4),
+ Rational(3, 2) / Rational(2, 1))
+ assert_equal(Rational(9, 2),
+ Rational(3, 2) + Rational(3, 1))
+ assert_equal(Rational(-3, 2),
+ Rational(3, 2) - Rational(3, 1))
+ assert_equal(Rational(9, 2),
+ Rational(3, 2) * Rational(3, 1))
+ assert_equal(Rational(1, 2),
+ Rational(3, 2) / Rational(3, 1))
+ assert_equal(Rational(2147483581, 2),
+ Rational(3, 2) + Rational(1073741789, 1))
+ assert_equal(Rational(-2147483575, 2),
+ Rational(3, 2) - Rational(1073741789, 1))
+ assert_equal(Rational(3221225367, 2),
+ Rational(3, 2) * Rational(1073741789, 1))
+ assert_equal(Rational(3, 2147483578),
+ Rational(3, 2) / Rational(1073741789, 1))
+ assert_equal(Rational(2147483657, 2),
+ Rational(3, 2) + Rational(1073741827, 1))
+ assert_equal(Rational(-2147483651, 2),
+ Rational(3, 2) - Rational(1073741827, 1))
+ assert_equal(Rational(3221225481, 2),
+ Rational(3, 2) * Rational(1073741827, 1))
+ assert_equal(Rational(3, 2147483654),
+ Rational(3, 2) / Rational(1073741827, 1))
+ assert_equal(Rational(13, 6),
+ Rational(3, 2) + Rational(2, 3))
+ assert_equal(Rational(5, 6),
+ Rational(3, 2) - Rational(2, 3))
+ assert_equal(Rational(1, 1),
+ Rational(3, 2) * Rational(2, 3))
+ assert_equal(Rational(9, 4),
+ Rational(3, 2) / Rational(2, 3))
+ assert_equal(Rational(3, 1),
+ Rational(3, 2) + Rational(3, 2))
+ assert_equal(Rational(0, 1),
+ Rational(3, 2) - Rational(3, 2))
+ assert_equal(Rational(9, 4),
+ Rational(3, 2) * Rational(3, 2))
+ assert_equal(Rational(1, 1),
+ Rational(3, 2) / Rational(3, 2))
+ assert_equal(Rational(3221225373, 2147483578),
+ Rational(3, 2) + Rational(3, 1073741789))
+ assert_equal(Rational(3221225361, 2147483578),
+ Rational(3, 2) - Rational(3, 1073741789))
+ assert_equal(Rational(9, 2147483578),
+ Rational(3, 2) * Rational(3, 1073741789))
+ assert_equal(Rational(1073741789, 2),
+ Rational(3, 2) / Rational(3, 1073741789))
+ assert_equal(Rational(2147483587, 6),
+ Rational(3, 2) + Rational(1073741789, 3))
+ assert_equal(Rational(-2147483569, 6),
+ Rational(3, 2) - Rational(1073741789, 3))
+ assert_equal(Rational(1073741789, 2),
+ Rational(3, 2) * Rational(1073741789, 3))
+ assert_equal(Rational(9, 2147483578),
+ Rational(3, 2) / Rational(1073741789, 3))
+ assert_equal(Rational(3221225487, 2147483654),
+ Rational(3, 2) + Rational(3, 1073741827))
+ assert_equal(Rational(3221225475, 2147483654),
+ Rational(3, 2) - Rational(3, 1073741827))
+ assert_equal(Rational(9, 2147483654),
+ Rational(3, 2) * Rational(3, 1073741827))
+ assert_equal(Rational(1073741827, 2),
+ Rational(3, 2) / Rational(3, 1073741827))
+ assert_equal(Rational(2147483663, 6),
+ Rational(3, 2) + Rational(1073741827, 3))
+ assert_equal(Rational(-2147483645, 6),
+ Rational(3, 2) - Rational(1073741827, 3))
+ assert_equal(Rational(1073741827, 2),
+ Rational(3, 2) * Rational(1073741827, 3))
+ assert_equal(Rational(9, 2147483654),
+ Rational(3, 2) / Rational(1073741827, 3))
+ assert_equal(Rational(5368709059, 2147483654),
+ Rational(3, 2) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741903, 2147483654),
+ Rational(3, 2) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225367, 2147483654),
+ Rational(3, 2) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225481, 2147483578),
+ Rational(3, 2) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(5368709021, 2147483578),
+ Rational(3, 2) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741713, 2147483578),
+ Rational(3, 2) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(3221225481, 2147483578),
+ Rational(3, 2) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(3221225367, 2147483654),
+ Rational(3, 2) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(3, 1073741789), +Rational(3, 1073741789))
+ assert_equal(Rational(-3, 1073741789), -Rational(3, 1073741789))
+ assert_equal(Rational(1073741792, 1073741789),
+ Rational(3, 1073741789) + Rational(1, 1))
+ assert_equal(Rational(-1073741786, 1073741789),
+ Rational(3, 1073741789) - Rational(1, 1))
+ assert_equal(Rational(3, 1073741789),
+ Rational(3, 1073741789) * Rational(1, 1))
+ assert_equal(Rational(3, 1073741789),
+ Rational(3, 1073741789) / Rational(1, 1))
+ assert_equal(Rational(2147483581, 1073741789),
+ Rational(3, 1073741789) + Rational(2, 1))
+ assert_equal(Rational(-2147483575, 1073741789),
+ Rational(3, 1073741789) - Rational(2, 1))
+ assert_equal(Rational(6, 1073741789),
+ Rational(3, 1073741789) * Rational(2, 1))
+ assert_equal(Rational(3, 2147483578),
+ Rational(3, 1073741789) / Rational(2, 1))
+ assert_equal(Rational(3221225370, 1073741789),
+ Rational(3, 1073741789) + Rational(3, 1))
+ assert_equal(Rational(-3221225364, 1073741789),
+ Rational(3, 1073741789) - Rational(3, 1))
+ assert_equal(Rational(9, 1073741789),
+ Rational(3, 1073741789) * Rational(3, 1))
+ assert_equal(Rational(1, 1073741789),
+ Rational(3, 1073741789) / Rational(3, 1))
+ assert_equal(Rational(1152921429444920524, 1073741789),
+ Rational(3, 1073741789) + Rational(1073741789, 1))
+ assert_equal(Rational(-1152921429444920518, 1073741789),
+ Rational(3, 1073741789) - Rational(1073741789, 1))
+ assert_equal(Rational(3, 1),
+ Rational(3, 1073741789) * Rational(1073741789, 1))
+ assert_equal(Rational(3, 1152921429444920521),
+ Rational(3, 1073741789) / Rational(1073741789, 1))
+ assert_equal(Rational(1152921470247108506, 1073741789),
+ Rational(3, 1073741789) + Rational(1073741827, 1))
+ assert_equal(Rational(-1152921470247108500, 1073741789),
+ Rational(3, 1073741789) - Rational(1073741827, 1))
+ assert_equal(Rational(3221225481, 1073741789),
+ Rational(3, 1073741789) * Rational(1073741827, 1))
+ assert_equal(Rational(3, 1152921470247108503),
+ Rational(3, 1073741789) / Rational(1073741827, 1))
+ assert_equal(Rational(2147483587, 3221225367),
+ Rational(3, 1073741789) + Rational(2, 3))
+ assert_equal(Rational(-2147483569, 3221225367),
+ Rational(3, 1073741789) - Rational(2, 3))
+ assert_equal(Rational(2, 1073741789),
+ Rational(3, 1073741789) * Rational(2, 3))
+ assert_equal(Rational(9, 2147483578),
+ Rational(3, 1073741789) / Rational(2, 3))
+ assert_equal(Rational(3221225373, 2147483578),
+ Rational(3, 1073741789) + Rational(3, 2))
+ assert_equal(Rational(-3221225361, 2147483578),
+ Rational(3, 1073741789) - Rational(3, 2))
+ assert_equal(Rational(9, 2147483578),
+ Rational(3, 1073741789) * Rational(3, 2))
+ assert_equal(Rational(2, 1073741789),
+ Rational(3, 1073741789) / Rational(3, 2))
+ assert_equal(Rational(6, 1073741789),
+ Rational(3, 1073741789) + Rational(3, 1073741789))
+ assert_equal(Rational(0, 1),
+ Rational(3, 1073741789) - Rational(3, 1073741789))
+ assert_equal(Rational(9, 1152921429444920521),
+ Rational(3, 1073741789) * Rational(3, 1073741789))
+ assert_equal(Rational(1, 1),
+ Rational(3, 1073741789) / Rational(3, 1073741789))
+ assert_equal(Rational(1152921429444920530, 3221225367),
+ Rational(3, 1073741789) + Rational(1073741789, 3))
+ assert_equal(Rational(-1152921429444920512, 3221225367),
+ Rational(3, 1073741789) - Rational(1073741789, 3))
+ assert_equal(Rational(1, 1),
+ Rational(3, 1073741789) * Rational(1073741789, 3))
+ assert_equal(Rational(9, 1152921429444920521),
+ Rational(3, 1073741789) / Rational(1073741789, 3))
+ assert_equal(Rational(6442450848, 1152921470247108503),
+ Rational(3, 1073741789) + Rational(3, 1073741827))
+ assert_equal(Rational(114, 1152921470247108503),
+ Rational(3, 1073741789) - Rational(3, 1073741827))
+ assert_equal(Rational(9, 1152921470247108503),
+ Rational(3, 1073741789) * Rational(3, 1073741827))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(3, 1073741789) / Rational(3, 1073741827))
+ assert_equal(Rational(1152921470247108512, 3221225367),
+ Rational(3, 1073741789) + Rational(1073741827, 3))
+ assert_equal(Rational(-1152921470247108494, 3221225367),
+ Rational(3, 1073741789) - Rational(1073741827, 3))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(3, 1073741789) * Rational(1073741827, 3))
+ assert_equal(Rational(9, 1152921470247108503),
+ Rational(3, 1073741789) / Rational(1073741827, 3))
+ assert_equal(Rational(1152921432666146002, 1152921470247108503),
+ Rational(3, 1073741789) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(-1152921426223695040, 1152921470247108503),
+ Rational(3, 1073741789) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(3, 1073741827),
+ Rational(3, 1073741789) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225481, 1152921429444920521),
+ Rational(3, 1073741789) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741830, 1073741789),
+ Rational(3, 1073741789) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(-1073741824, 1073741789),
+ Rational(3, 1073741789) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(3221225481, 1152921429444920521),
+ Rational(3, 1073741789) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(3, 1073741827),
+ Rational(3, 1073741789) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741789, 3), +Rational(1073741789, 3))
+ assert_equal(Rational(-1073741789, 3), -Rational(1073741789, 3))
+ assert_equal(Rational(1073741792, 3),
+ Rational(1073741789, 3) + Rational(1, 1))
+ assert_equal(Rational(1073741786, 3),
+ Rational(1073741789, 3) - Rational(1, 1))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741789, 3) * Rational(1, 1))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741789, 3) / Rational(1, 1))
+ assert_equal(Rational(1073741795, 3),
+ Rational(1073741789, 3) + Rational(2, 1))
+ assert_equal(Rational(1073741783, 3),
+ Rational(1073741789, 3) - Rational(2, 1))
+ assert_equal(Rational(2147483578, 3),
+ Rational(1073741789, 3) * Rational(2, 1))
+ assert_equal(Rational(1073741789, 6),
+ Rational(1073741789, 3) / Rational(2, 1))
+ assert_equal(Rational(1073741798, 3),
+ Rational(1073741789, 3) + Rational(3, 1))
+ assert_equal(Rational(1073741780, 3),
+ Rational(1073741789, 3) - Rational(3, 1))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1073741789, 3) * Rational(3, 1))
+ assert_equal(Rational(1073741789, 9),
+ Rational(1073741789, 3) / Rational(3, 1))
+ assert_equal(Rational(4294967156, 3),
+ Rational(1073741789, 3) + Rational(1073741789, 1))
+ assert_equal(Rational(-2147483578, 3),
+ Rational(1073741789, 3) - Rational(1073741789, 1))
+ assert_equal(Rational(1152921429444920521, 3),
+ Rational(1073741789, 3) * Rational(1073741789, 1))
+ assert_equal(Rational(1, 3),
+ Rational(1073741789, 3) / Rational(1073741789, 1))
+ assert_equal(Rational(4294967270, 3),
+ Rational(1073741789, 3) + Rational(1073741827, 1))
+ assert_equal(Rational(-2147483692, 3),
+ Rational(1073741789, 3) - Rational(1073741827, 1))
+ assert_equal(Rational(1152921470247108503, 3),
+ Rational(1073741789, 3) * Rational(1073741827, 1))
+ assert_equal(Rational(1073741789, 3221225481),
+ Rational(1073741789, 3) / Rational(1073741827, 1))
+ assert_equal(Rational(1073741791, 3),
+ Rational(1073741789, 3) + Rational(2, 3))
+ assert_equal(Rational(357913929, 1),
+ Rational(1073741789, 3) - Rational(2, 3))
+ assert_equal(Rational(2147483578, 9),
+ Rational(1073741789, 3) * Rational(2, 3))
+ assert_equal(Rational(1073741789, 2),
+ Rational(1073741789, 3) / Rational(2, 3))
+ assert_equal(Rational(2147483587, 6),
+ Rational(1073741789, 3) + Rational(3, 2))
+ assert_equal(Rational(2147483569, 6),
+ Rational(1073741789, 3) - Rational(3, 2))
+ assert_equal(Rational(1073741789, 2),
+ Rational(1073741789, 3) * Rational(3, 2))
+ assert_equal(Rational(2147483578, 9),
+ Rational(1073741789, 3) / Rational(3, 2))
+ assert_equal(Rational(1152921429444920530, 3221225367),
+ Rational(1073741789, 3) + Rational(3, 1073741789))
+ assert_equal(Rational(1152921429444920512, 3221225367),
+ Rational(1073741789, 3) - Rational(3, 1073741789))
+ assert_equal(Rational(1, 1),
+ Rational(1073741789, 3) * Rational(3, 1073741789))
+ assert_equal(Rational(1152921429444920521, 9),
+ Rational(1073741789, 3) / Rational(3, 1073741789))
+ assert_equal(Rational(2147483578, 3),
+ Rational(1073741789, 3) + Rational(1073741789, 3))
+ assert_equal(Rational(0, 1),
+ Rational(1073741789, 3) - Rational(1073741789, 3))
+ assert_equal(Rational(1152921429444920521, 9),
+ Rational(1073741789, 3) * Rational(1073741789, 3))
+ assert_equal(Rational(1, 1),
+ Rational(1073741789, 3) / Rational(1073741789, 3))
+ assert_equal(Rational(1152921470247108512, 3221225481),
+ Rational(1073741789, 3) + Rational(3, 1073741827))
+ assert_equal(Rational(1152921470247108494, 3221225481),
+ Rational(1073741789, 3) - Rational(3, 1073741827))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1073741789, 3) * Rational(3, 1073741827))
+ assert_equal(Rational(1152921470247108503, 9),
+ Rational(1073741789, 3) / Rational(3, 1073741827))
+ assert_equal(Rational(715827872, 1),
+ Rational(1073741789, 3) + Rational(1073741827, 3))
+ assert_equal(Rational(-38, 3),
+ Rational(1073741789, 3) - Rational(1073741827, 3))
+ assert_equal(Rational(1152921470247108503, 9),
+ Rational(1073741789, 3) * Rational(1073741827, 3))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1073741789, 3) / Rational(1073741827, 3))
+ assert_equal(Rational(1152921473468333870, 3221225481),
+ Rational(1073741789, 3) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921467025883136, 3221225481),
+ Rational(1073741789, 3) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921429444920521, 3221225481),
+ Rational(1073741789, 3) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741789, 3) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921432666146002, 3221225367),
+ Rational(1073741789, 3) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921426223695040, 3221225367),
+ Rational(1073741789, 3) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741789, 3) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921429444920521, 3221225481),
+ Rational(1073741789, 3) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(3, 1073741827), +Rational(3, 1073741827))
+ assert_equal(Rational(-3, 1073741827), -Rational(3, 1073741827))
+ assert_equal(Rational(1073741830, 1073741827),
+ Rational(3, 1073741827) + Rational(1, 1))
+ assert_equal(Rational(-1073741824, 1073741827),
+ Rational(3, 1073741827) - Rational(1, 1))
+ assert_equal(Rational(3, 1073741827),
+ Rational(3, 1073741827) * Rational(1, 1))
+ assert_equal(Rational(3, 1073741827),
+ Rational(3, 1073741827) / Rational(1, 1))
+ assert_equal(Rational(2147483657, 1073741827),
+ Rational(3, 1073741827) + Rational(2, 1))
+ assert_equal(Rational(-2147483651, 1073741827),
+ Rational(3, 1073741827) - Rational(2, 1))
+ assert_equal(Rational(6, 1073741827),
+ Rational(3, 1073741827) * Rational(2, 1))
+ assert_equal(Rational(3, 2147483654),
+ Rational(3, 1073741827) / Rational(2, 1))
+ assert_equal(Rational(3221225484, 1073741827),
+ Rational(3, 1073741827) + Rational(3, 1))
+ assert_equal(Rational(-3221225478, 1073741827),
+ Rational(3, 1073741827) - Rational(3, 1))
+ assert_equal(Rational(9, 1073741827),
+ Rational(3, 1073741827) * Rational(3, 1))
+ assert_equal(Rational(1, 1073741827),
+ Rational(3, 1073741827) / Rational(3, 1))
+ assert_equal(Rational(1152921470247108506, 1073741827),
+ Rational(3, 1073741827) + Rational(1073741789, 1))
+ assert_equal(Rational(-1152921470247108500, 1073741827),
+ Rational(3, 1073741827) - Rational(1073741789, 1))
+ assert_equal(Rational(3221225367, 1073741827),
+ Rational(3, 1073741827) * Rational(1073741789, 1))
+ assert_equal(Rational(3, 1152921470247108503),
+ Rational(3, 1073741827) / Rational(1073741789, 1))
+ assert_equal(Rational(1152921511049297932, 1073741827),
+ Rational(3, 1073741827) + Rational(1073741827, 1))
+ assert_equal(Rational(-1152921511049297926, 1073741827),
+ Rational(3, 1073741827) - Rational(1073741827, 1))
+ assert_equal(Rational(3, 1),
+ Rational(3, 1073741827) * Rational(1073741827, 1))
+ assert_equal(Rational(3, 1152921511049297929),
+ Rational(3, 1073741827) / Rational(1073741827, 1))
+ assert_equal(Rational(2147483663, 3221225481),
+ Rational(3, 1073741827) + Rational(2, 3))
+ assert_equal(Rational(-2147483645, 3221225481),
+ Rational(3, 1073741827) - Rational(2, 3))
+ assert_equal(Rational(2, 1073741827),
+ Rational(3, 1073741827) * Rational(2, 3))
+ assert_equal(Rational(9, 2147483654),
+ Rational(3, 1073741827) / Rational(2, 3))
+ assert_equal(Rational(3221225487, 2147483654),
+ Rational(3, 1073741827) + Rational(3, 2))
+ assert_equal(Rational(-3221225475, 2147483654),
+ Rational(3, 1073741827) - Rational(3, 2))
+ assert_equal(Rational(9, 2147483654),
+ Rational(3, 1073741827) * Rational(3, 2))
+ assert_equal(Rational(2, 1073741827),
+ Rational(3, 1073741827) / Rational(3, 2))
+ assert_equal(Rational(6442450848, 1152921470247108503),
+ Rational(3, 1073741827) + Rational(3, 1073741789))
+ assert_equal(Rational(-114, 1152921470247108503),
+ Rational(3, 1073741827) - Rational(3, 1073741789))
+ assert_equal(Rational(9, 1152921470247108503),
+ Rational(3, 1073741827) * Rational(3, 1073741789))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(3, 1073741827) / Rational(3, 1073741789))
+ assert_equal(Rational(1152921470247108512, 3221225481),
+ Rational(3, 1073741827) + Rational(1073741789, 3))
+ assert_equal(Rational(-1152921470247108494, 3221225481),
+ Rational(3, 1073741827) - Rational(1073741789, 3))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(3, 1073741827) * Rational(1073741789, 3))
+ assert_equal(Rational(9, 1152921470247108503),
+ Rational(3, 1073741827) / Rational(1073741789, 3))
+ assert_equal(Rational(6, 1073741827),
+ Rational(3, 1073741827) + Rational(3, 1073741827))
+ assert_equal(Rational(0, 1),
+ Rational(3, 1073741827) - Rational(3, 1073741827))
+ assert_equal(Rational(9, 1152921511049297929),
+ Rational(3, 1073741827) * Rational(3, 1073741827))
+ assert_equal(Rational(1, 1),
+ Rational(3, 1073741827) / Rational(3, 1073741827))
+ assert_equal(Rational(1152921511049297938, 3221225481),
+ Rational(3, 1073741827) + Rational(1073741827, 3))
+ assert_equal(Rational(-1152921511049297920, 3221225481),
+ Rational(3, 1073741827) - Rational(1073741827, 3))
+ assert_equal(Rational(1, 1),
+ Rational(3, 1073741827) * Rational(1073741827, 3))
+ assert_equal(Rational(9, 1152921511049297929),
+ Rational(3, 1073741827) / Rational(1073741827, 3))
+ assert_equal(Rational(1073741792, 1073741827),
+ Rational(3, 1073741827) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(-1073741786, 1073741827),
+ Rational(3, 1073741827) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225367, 1152921511049297929),
+ Rational(3, 1073741827) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(3, 1073741789),
+ Rational(3, 1073741827) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921514270523296, 1152921470247108503),
+ Rational(3, 1073741827) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(-1152921507828072562, 1152921470247108503),
+ Rational(3, 1073741827) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(3, 1073741789),
+ Rational(3, 1073741827) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(3221225367, 1152921511049297929),
+ Rational(3, 1073741827) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741827, 3), +Rational(1073741827, 3))
+ assert_equal(Rational(-1073741827, 3), -Rational(1073741827, 3))
+ assert_equal(Rational(1073741830, 3),
+ Rational(1073741827, 3) + Rational(1, 1))
+ assert_equal(Rational(1073741824, 3),
+ Rational(1073741827, 3) - Rational(1, 1))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741827, 3) * Rational(1, 1))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741827, 3) / Rational(1, 1))
+ assert_equal(Rational(1073741833, 3),
+ Rational(1073741827, 3) + Rational(2, 1))
+ assert_equal(Rational(1073741821, 3),
+ Rational(1073741827, 3) - Rational(2, 1))
+ assert_equal(Rational(2147483654, 3),
+ Rational(1073741827, 3) * Rational(2, 1))
+ assert_equal(Rational(1073741827, 6),
+ Rational(1073741827, 3) / Rational(2, 1))
+ assert_equal(Rational(1073741836, 3),
+ Rational(1073741827, 3) + Rational(3, 1))
+ assert_equal(Rational(1073741818, 3),
+ Rational(1073741827, 3) - Rational(3, 1))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1073741827, 3) * Rational(3, 1))
+ assert_equal(Rational(1073741827, 9),
+ Rational(1073741827, 3) / Rational(3, 1))
+ assert_equal(Rational(4294967194, 3),
+ Rational(1073741827, 3) + Rational(1073741789, 1))
+ assert_equal(Rational(-2147483540, 3),
+ Rational(1073741827, 3) - Rational(1073741789, 1))
+ assert_equal(Rational(1152921470247108503, 3),
+ Rational(1073741827, 3) * Rational(1073741789, 1))
+ assert_equal(Rational(1073741827, 3221225367),
+ Rational(1073741827, 3) / Rational(1073741789, 1))
+ assert_equal(Rational(4294967308, 3),
+ Rational(1073741827, 3) + Rational(1073741827, 1))
+ assert_equal(Rational(-2147483654, 3),
+ Rational(1073741827, 3) - Rational(1073741827, 1))
+ assert_equal(Rational(1152921511049297929, 3),
+ Rational(1073741827, 3) * Rational(1073741827, 1))
+ assert_equal(Rational(1, 3),
+ Rational(1073741827, 3) / Rational(1073741827, 1))
+ assert_equal(Rational(357913943, 1),
+ Rational(1073741827, 3) + Rational(2, 3))
+ assert_equal(Rational(1073741825, 3),
+ Rational(1073741827, 3) - Rational(2, 3))
+ assert_equal(Rational(2147483654, 9),
+ Rational(1073741827, 3) * Rational(2, 3))
+ assert_equal(Rational(1073741827, 2),
+ Rational(1073741827, 3) / Rational(2, 3))
+ assert_equal(Rational(2147483663, 6),
+ Rational(1073741827, 3) + Rational(3, 2))
+ assert_equal(Rational(2147483645, 6),
+ Rational(1073741827, 3) - Rational(3, 2))
+ assert_equal(Rational(1073741827, 2),
+ Rational(1073741827, 3) * Rational(3, 2))
+ assert_equal(Rational(2147483654, 9),
+ Rational(1073741827, 3) / Rational(3, 2))
+ assert_equal(Rational(1152921470247108512, 3221225367),
+ Rational(1073741827, 3) + Rational(3, 1073741789))
+ assert_equal(Rational(1152921470247108494, 3221225367),
+ Rational(1073741827, 3) - Rational(3, 1073741789))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1073741827, 3) * Rational(3, 1073741789))
+ assert_equal(Rational(1152921470247108503, 9),
+ Rational(1073741827, 3) / Rational(3, 1073741789))
+ assert_equal(Rational(715827872, 1),
+ Rational(1073741827, 3) + Rational(1073741789, 3))
+ assert_equal(Rational(38, 3),
+ Rational(1073741827, 3) - Rational(1073741789, 3))
+ assert_equal(Rational(1152921470247108503, 9),
+ Rational(1073741827, 3) * Rational(1073741789, 3))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1073741827, 3) / Rational(1073741789, 3))
+ assert_equal(Rational(1152921511049297938, 3221225481),
+ Rational(1073741827, 3) + Rational(3, 1073741827))
+ assert_equal(Rational(1152921511049297920, 3221225481),
+ Rational(1073741827, 3) - Rational(3, 1073741827))
+ assert_equal(Rational(1, 1),
+ Rational(1073741827, 3) * Rational(3, 1073741827))
+ assert_equal(Rational(1152921511049297929, 9),
+ Rational(1073741827, 3) / Rational(3, 1073741827))
+ assert_equal(Rational(2147483654, 3),
+ Rational(1073741827, 3) + Rational(1073741827, 3))
+ assert_equal(Rational(0, 1),
+ Rational(1073741827, 3) - Rational(1073741827, 3))
+ assert_equal(Rational(1152921511049297929, 9),
+ Rational(1073741827, 3) * Rational(1073741827, 3))
+ assert_equal(Rational(1, 1),
+ Rational(1073741827, 3) / Rational(1073741827, 3))
+ assert_equal(Rational(1152921514270523296, 3221225481),
+ Rational(1073741827, 3) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921507828072562, 3221225481),
+ Rational(1073741827, 3) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741827, 3) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921511049297929, 3221225367),
+ Rational(1073741827, 3) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921473468333984, 3221225367),
+ Rational(1073741827, 3) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921467025883022, 3221225367),
+ Rational(1073741827, 3) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921511049297929, 3221225367),
+ Rational(1073741827, 3) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741827, 3) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741789, 1073741827), +Rational(1073741789, 1073741827))
+ assert_equal(Rational(-1073741789, 1073741827), -Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483616, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(1, 1))
+ assert_equal(Rational(-38, 1073741827),
+ Rational(1073741789, 1073741827) - Rational(1, 1))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1073741789, 1073741827) * Rational(1, 1))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1073741789, 1073741827) / Rational(1, 1))
+ assert_equal(Rational(3221225443, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(2, 1))
+ assert_equal(Rational(-1073741865, 1073741827),
+ Rational(1073741789, 1073741827) - Rational(2, 1))
+ assert_equal(Rational(2147483578, 1073741827),
+ Rational(1073741789, 1073741827) * Rational(2, 1))
+ assert_equal(Rational(1073741789, 2147483654),
+ Rational(1073741789, 1073741827) / Rational(2, 1))
+ assert_equal(Rational(4294967270, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(3, 1))
+ assert_equal(Rational(-2147483692, 1073741827),
+ Rational(1073741789, 1073741827) - Rational(3, 1))
+ assert_equal(Rational(3221225367, 1073741827),
+ Rational(1073741789, 1073741827) * Rational(3, 1))
+ assert_equal(Rational(1073741789, 3221225481),
+ Rational(1073741789, 1073741827) / Rational(3, 1))
+ assert_equal(Rational(1152921471320850292, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(1073741789, 1))
+ assert_equal(Rational(-1152921469173366714, 1073741827),
+ Rational(1073741789, 1073741827) - Rational(1073741789, 1))
+ assert_equal(Rational(1152921429444920521, 1073741827),
+ Rational(1073741789, 1073741827) * Rational(1073741789, 1))
+ assert_equal(Rational(1, 1073741827),
+ Rational(1073741789, 1073741827) / Rational(1073741789, 1))
+ assert_equal(Rational(1152921512123039718, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(1073741827, 1))
+ assert_equal(Rational(-1152921509975556140, 1073741827),
+ Rational(1073741789, 1073741827) - Rational(1073741827, 1))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1073741789, 1073741827) * Rational(1073741827, 1))
+ assert_equal(Rational(1073741789, 1152921511049297929),
+ Rational(1073741789, 1073741827) / Rational(1073741827, 1))
+ assert_equal(Rational(5368709021, 3221225481),
+ Rational(1073741789, 1073741827) + Rational(2, 3))
+ assert_equal(Rational(1073741713, 3221225481),
+ Rational(1073741789, 1073741827) - Rational(2, 3))
+ assert_equal(Rational(2147483578, 3221225481),
+ Rational(1073741789, 1073741827) * Rational(2, 3))
+ assert_equal(Rational(3221225367, 2147483654),
+ Rational(1073741789, 1073741827) / Rational(2, 3))
+ assert_equal(Rational(5368709059, 2147483654),
+ Rational(1073741789, 1073741827) + Rational(3, 2))
+ assert_equal(Rational(-1073741903, 2147483654),
+ Rational(1073741789, 1073741827) - Rational(3, 2))
+ assert_equal(Rational(3221225367, 2147483654),
+ Rational(1073741789, 1073741827) * Rational(3, 2))
+ assert_equal(Rational(2147483578, 3221225481),
+ Rational(1073741789, 1073741827) / Rational(3, 2))
+ assert_equal(Rational(1152921432666146002, 1152921470247108503),
+ Rational(1073741789, 1073741827) + Rational(3, 1073741789))
+ assert_equal(Rational(1152921426223695040, 1152921470247108503),
+ Rational(1073741789, 1073741827) - Rational(3, 1073741789))
+ assert_equal(Rational(3, 1073741827),
+ Rational(1073741789, 1073741827) * Rational(3, 1073741789))
+ assert_equal(Rational(1152921429444920521, 3221225481),
+ Rational(1073741789, 1073741827) / Rational(3, 1073741789))
+ assert_equal(Rational(1152921473468333870, 3221225481),
+ Rational(1073741789, 1073741827) + Rational(1073741789, 3))
+ assert_equal(Rational(-1152921467025883136, 3221225481),
+ Rational(1073741789, 1073741827) - Rational(1073741789, 3))
+ assert_equal(Rational(1152921429444920521, 3221225481),
+ Rational(1073741789, 1073741827) * Rational(1073741789, 3))
+ assert_equal(Rational(3, 1073741827),
+ Rational(1073741789, 1073741827) / Rational(1073741789, 3))
+ assert_equal(Rational(1073741792, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(3, 1073741827))
+ assert_equal(Rational(1073741786, 1073741827),
+ Rational(1073741789, 1073741827) - Rational(3, 1073741827))
+ assert_equal(Rational(3221225367, 1152921511049297929),
+ Rational(1073741789, 1073741827) * Rational(3, 1073741827))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741789, 1073741827) / Rational(3, 1073741827))
+ assert_equal(Rational(1152921514270523296, 3221225481),
+ Rational(1073741789, 1073741827) + Rational(1073741827, 3))
+ assert_equal(Rational(-1152921507828072562, 3221225481),
+ Rational(1073741789, 1073741827) - Rational(1073741827, 3))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741789, 1073741827) * Rational(1073741827, 3))
+ assert_equal(Rational(3221225367, 1152921511049297929),
+ Rational(1073741789, 1073741827) / Rational(1073741827, 3))
+ assert_equal(Rational(2147483578, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(0, 1),
+ Rational(1073741789, 1073741827) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921429444920521, 1152921511049297929),
+ Rational(1073741789, 1073741827) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1, 1),
+ Rational(1073741789, 1073741827) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(2305842940494218450, 1152921470247108503),
+ Rational(1073741789, 1073741827) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(-81604377408, 1152921470247108503),
+ Rational(1073741789, 1073741827) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1, 1),
+ Rational(1073741789, 1073741827) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921429444920521, 1152921511049297929),
+ Rational(1073741789, 1073741827) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741827, 1073741789), +Rational(1073741827, 1073741789))
+ assert_equal(Rational(-1073741827, 1073741789), -Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483616, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(1, 1))
+ assert_equal(Rational(38, 1073741789),
+ Rational(1073741827, 1073741789) - Rational(1, 1))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1073741827, 1073741789) * Rational(1, 1))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1073741827, 1073741789) / Rational(1, 1))
+ assert_equal(Rational(3221225405, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(2, 1))
+ assert_equal(Rational(-1073741751, 1073741789),
+ Rational(1073741827, 1073741789) - Rational(2, 1))
+ assert_equal(Rational(2147483654, 1073741789),
+ Rational(1073741827, 1073741789) * Rational(2, 1))
+ assert_equal(Rational(1073741827, 2147483578),
+ Rational(1073741827, 1073741789) / Rational(2, 1))
+ assert_equal(Rational(4294967194, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(3, 1))
+ assert_equal(Rational(-2147483540, 1073741789),
+ Rational(1073741827, 1073741789) - Rational(3, 1))
+ assert_equal(Rational(3221225481, 1073741789),
+ Rational(1073741827, 1073741789) * Rational(3, 1))
+ assert_equal(Rational(1073741827, 3221225367),
+ Rational(1073741827, 1073741789) / Rational(3, 1))
+ assert_equal(Rational(1152921430518662348, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(1073741789, 1))
+ assert_equal(Rational(-1152921428371178694, 1073741789),
+ Rational(1073741827, 1073741789) - Rational(1073741789, 1))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1073741827, 1073741789) * Rational(1073741789, 1))
+ assert_equal(Rational(1073741827, 1152921429444920521),
+ Rational(1073741827, 1073741789) / Rational(1073741789, 1))
+ assert_equal(Rational(1152921471320850330, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(1073741827, 1))
+ assert_equal(Rational(-1152921469173366676, 1073741789),
+ Rational(1073741827, 1073741789) - Rational(1073741827, 1))
+ assert_equal(Rational(1152921511049297929, 1073741789),
+ Rational(1073741827, 1073741789) * Rational(1073741827, 1))
+ assert_equal(Rational(1, 1073741789),
+ Rational(1073741827, 1073741789) / Rational(1073741827, 1))
+ assert_equal(Rational(5368709059, 3221225367),
+ Rational(1073741827, 1073741789) + Rational(2, 3))
+ assert_equal(Rational(1073741903, 3221225367),
+ Rational(1073741827, 1073741789) - Rational(2, 3))
+ assert_equal(Rational(2147483654, 3221225367),
+ Rational(1073741827, 1073741789) * Rational(2, 3))
+ assert_equal(Rational(3221225481, 2147483578),
+ Rational(1073741827, 1073741789) / Rational(2, 3))
+ assert_equal(Rational(5368709021, 2147483578),
+ Rational(1073741827, 1073741789) + Rational(3, 2))
+ assert_equal(Rational(-1073741713, 2147483578),
+ Rational(1073741827, 1073741789) - Rational(3, 2))
+ assert_equal(Rational(3221225481, 2147483578),
+ Rational(1073741827, 1073741789) * Rational(3, 2))
+ assert_equal(Rational(2147483654, 3221225367),
+ Rational(1073741827, 1073741789) / Rational(3, 2))
+ assert_equal(Rational(1073741830, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(3, 1073741789))
+ assert_equal(Rational(1073741824, 1073741789),
+ Rational(1073741827, 1073741789) - Rational(3, 1073741789))
+ assert_equal(Rational(3221225481, 1152921429444920521),
+ Rational(1073741827, 1073741789) * Rational(3, 1073741789))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741827, 1073741789) / Rational(3, 1073741789))
+ assert_equal(Rational(1152921432666146002, 3221225367),
+ Rational(1073741827, 1073741789) + Rational(1073741789, 3))
+ assert_equal(Rational(-1152921426223695040, 3221225367),
+ Rational(1073741827, 1073741789) - Rational(1073741789, 3))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741827, 1073741789) * Rational(1073741789, 3))
+ assert_equal(Rational(3221225481, 1152921429444920521),
+ Rational(1073741827, 1073741789) / Rational(1073741789, 3))
+ assert_equal(Rational(1152921514270523296, 1152921470247108503),
+ Rational(1073741827, 1073741789) + Rational(3, 1073741827))
+ assert_equal(Rational(1152921507828072562, 1152921470247108503),
+ Rational(1073741827, 1073741789) - Rational(3, 1073741827))
+ assert_equal(Rational(3, 1073741789),
+ Rational(1073741827, 1073741789) * Rational(3, 1073741827))
+ assert_equal(Rational(1152921511049297929, 3221225367),
+ Rational(1073741827, 1073741789) / Rational(3, 1073741827))
+ assert_equal(Rational(1152921473468333984, 3221225367),
+ Rational(1073741827, 1073741789) + Rational(1073741827, 3))
+ assert_equal(Rational(-1152921467025883022, 3221225367),
+ Rational(1073741827, 1073741789) - Rational(1073741827, 3))
+ assert_equal(Rational(1152921511049297929, 3221225367),
+ Rational(1073741827, 1073741789) * Rational(1073741827, 3))
+ assert_equal(Rational(3, 1073741789),
+ Rational(1073741827, 1073741789) / Rational(1073741827, 3))
+ assert_equal(Rational(2305842940494218450, 1152921470247108503),
+ Rational(1073741827, 1073741789) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(81604377408, 1152921470247108503),
+ Rational(1073741827, 1073741789) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1, 1),
+ Rational(1073741827, 1073741789) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921511049297929, 1152921429444920521),
+ Rational(1073741827, 1073741789) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483654, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(0, 1),
+ Rational(1073741827, 1073741789) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921511049297929, 1152921429444920521),
+ Rational(1073741827, 1073741789) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1, 1),
+ Rational(1073741827, 1073741789) / Rational(1073741827, 1073741789))
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_readpartial.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_readpartial.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_readpartial.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,76 @@
+require 'test/unit'
+require 'timeout'
+require 'fcntl'
+
+class TestReadPartial < Test::Unit::TestCase
+ def make_pipe
+ r, w = IO.pipe
+ r.binmode
+ w.binmode
+ begin
+ yield r, w
+ ensure
+ r.close unless r.closed?
+ w.close unless w.closed?
+ end
+ end
+
+ def pipe
+ make_pipe {|r, w|
+ yield r, w
+ }
+ return unless defined?(Fcntl::F_SETFL)
+ return unless defined?(Fcntl::F_GETFL)
+ return unless defined?(Fcntl::O_NONBLOCK)
+ make_pipe {|r, w|
+ r.fcntl(Fcntl::F_SETFL, r.fcntl(Fcntl::F_GETFL) | Fcntl::O_NONBLOCK)
+ yield r, w
+ }
+ end
+
+ def test_length_zero
+ pipe {|r, w|
+ assert_equal('', r.readpartial(0))
+ }
+ end
+
+ def test_closed_pipe
+ pipe {|r, w|
+ w << 'abc'
+ w.close
+ assert_equal('ab', r.readpartial(2))
+ assert_equal('c', r.readpartial(2))
+ assert_raise(EOFError) { r.readpartial(2) }
+ assert_raise(EOFError) { r.readpartial(2) }
+ }
+ end
+
+ def test_open_pipe
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ pipe {|r, w|
+ w << 'abc'
+ assert_equal('ab', r.readpartial(2))
+ assert_equal('c', r.readpartial(2))
+ assert_raise(TimeoutError) {
+ timeout(0.1) { r.readpartial(2) }
+ }
+ }
+ end
+
+ def test_with_stdio
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ pipe {|r, w|
+ w << "abc\ndef\n"
+ assert_equal("abc\n", r.gets)
+ w << "ghi\n"
+ assert_equal("de", r.readpartial(2))
+ assert_equal("f\n", r.readpartial(4096))
+ assert_equal("ghi\n", r.readpartial(4096))
+ assert_raise(TimeoutError) {
+ timeout(0.1) { r.readpartial(2) }
+ }
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_regexp.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_regexp.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_regexp.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,838 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestRegexp < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_ruby_dev_999
+ assert_match(/(?<=a).*b/, "aab")
+ assert_match(/(?<=\u3042).*b/, "\u3042ab")
+ end
+
+ def test_ruby_core_27247
+ assert_match(/(a){2}z/, "aaz")
+ end
+
+ def test_ruby_dev_24643
+ assert_nothing_raised("[ruby-dev:24643]") {
+ /(?:(?:[a]*[a])?b)*a*$/ =~ "aabaaca"
+ }
+ end
+
+ def test_ruby_talk_116455
+ assert_match(/^(\w{2,}).* ([A-Za-z\xa2\xc0-\xff]{2,}?)$/n, "Hallo Welt")
+ end
+
+ def test_ruby_dev_24887
+ assert_equal("a".gsub(/a\Z/, ""), "")
+ end
+
+ def test_yoshidam_net_20041111_1
+ s = "[\xC2\xA0-\xC3\xBE]"
+ assert_match(Regexp.new(s, nil, "u"), "\xC3\xBE")
+ end
+
+ def test_yoshidam_net_20041111_2
+ assert_raise(RegexpError) do
+ s = "[\xFF-\xFF]".force_encoding("utf-8")
+ Regexp.new(s, nil, "u")
+ end
+ end
+
+ def test_ruby_dev_31309
+ assert_equal('Ruby', 'Ruby'.sub(/[^a-z]/i, '-'))
+ end
+
+ def test_assert_normal_exit
+ # moved from knownbug. It caused core.
+ Regexp.union("a", "a")
+ end
+
+ def test_to_s
+ assert_equal '(?-mix:\x00)', Regexp.new("\0").to_s
+ end
+
+ def test_union
+ assert_equal :ok, begin
+ Regexp.union(
+ "a",
+ Regexp.new("\xc2\xa1".force_encoding("euc-jp")),
+ Regexp.new("\xc2\xa1".force_encoding("utf-8")))
+ :ng
+ rescue ArgumentError
+ :ok
+ end
+ end
+
+ def test_named_capture
+ m = /&(?<foo>.*?);/.match("aaa & yyy")
+ assert_equal("amp", m["foo"])
+ assert_equal("amp", m[:foo])
+ assert_equal(5, m.begin(:foo))
+ assert_equal(8, m.end(:foo))
+ assert_equal([5,8], m.offset(:foo))
+
+ assert_equal("aaa [amp] yyy",
+ "aaa & yyy".sub(/&(?<foo>.*?);/, '[\k<foo>]'))
+
+ assert_equal('#<MatchData "& y" foo:"amp">',
+ /&(?<foo>.*?); (y)/.match("aaa & yyy").inspect)
+ assert_equal('#<MatchData "& y" 1:"amp" 2:"y">',
+ /&(.*?); (y)/.match("aaa & yyy").inspect)
+ assert_equal('#<MatchData "& y" foo:"amp" bar:"y">',
+ /&(?<foo>.*?); (?<bar>y)/.match("aaa & yyy").inspect)
+ assert_equal('#<MatchData "& y" foo:"amp" foo:"y">',
+ /&(?<foo>.*?); (?<foo>y)/.match("aaa & yyy").inspect)
+
+ /(?<id>[A-Za-z_]+)/ =~ "!abc"
+ assert_equal("abc", Regexp.last_match(:id))
+
+ /a/ =~ "b" # doesn't match.
+ assert_equal(nil, Regexp.last_match)
+ assert_equal(nil, Regexp.last_match(1))
+ assert_equal(nil, Regexp.last_match(:foo))
+
+ assert_equal(["foo", "bar"], /(?<foo>.)(?<bar>.)/.names)
+ assert_equal(["foo"], /(?<foo>.)(?<foo>.)/.names)
+ assert_equal([], /(.)(.)/.names)
+
+ assert_equal(["foo", "bar"], /(?<foo>.)(?<bar>.)/.match("ab").names)
+ assert_equal(["foo"], /(?<foo>.)(?<foo>.)/.match("ab").names)
+ assert_equal([], /(.)(.)/.match("ab").names)
+
+ assert_equal({"foo"=>[1], "bar"=>[2]},
+ /(?<foo>.)(?<bar>.)/.named_captures)
+ assert_equal({"foo"=>[1, 2]},
+ /(?<foo>.)(?<foo>.)/.named_captures)
+ assert_equal({}, /(.)(.)/.named_captures)
+
+ assert_equal("a[b]c", "abc".sub(/(?<x>[bc])/, "[\\k<x>]"))
+
+ assert_equal("o", "foo"[/(?<bar>o)/, "bar"])
+
+ s = "foo"
+ s[/(?<bar>o)/, "bar"] = "baz"
+ assert_equal("fbazo", s)
+ end
+
+ def test_assign_named_capture
+ assert_equal("a", eval('/(?<foo>.)/ =~ "a"; foo'))
+ assert_equal("a", eval('foo = 1; /(?<foo>.)/ =~ "a"; foo'))
+ assert_equal("a", eval('1.times {|foo| /(?<foo>.)/ =~ "a"; break foo }'))
+ assert_nothing_raised { eval('/(?<Foo>.)/ =~ "a"') }
+ assert_nil(eval('/(?<Foo>.)/ =~ "a"; defined? Foo'))
+ end
+
+ def test_assign_named_capture_to_reserved_word
+ /(?<nil>.)/ =~ "a"
+ assert(!local_variables.include?(:nil), "[ruby-dev:32675]")
+ end
+
+ def test_match_regexp
+ r = /./
+ m = r.match("a")
+ assert_equal(r, m.regexp)
+ re = /foo/
+ assert_equal(re, re.match("foo").regexp)
+ end
+
+ def test_source
+ assert_equal('', //.source)
+ end
+
+ def test_inspect
+ assert_equal('//', //.inspect)
+ assert_equal('//i', //i.inspect)
+ assert_equal('/\//i', /\//i.inspect)
+ assert_equal('/\//i', %r"#{'/'}"i.inspect)
+ assert_equal('/\/x/i', /\/x/i.inspect)
+ assert_equal('/\x00/i', /#{"\0"}/i.inspect)
+ assert_equal("/\n/i", /#{"\n"}/i.inspect)
+ s = [0xf1, 0xf2, 0xf3].pack("C*")
+ assert_equal('/\/\xF1\xF2\xF3/i', /\/#{s}/i.inspect)
+ end
+
+ def test_char_to_option
+ assert_equal("BAR", "FOOBARBAZ"[/b../i])
+ assert_equal("bar", "foobarbaz"[/ b . . /x])
+ assert_equal("bar\n", "foo\nbar\nbaz"[/b.../m])
+ assert_raise(SyntaxError) { eval('//z') }
+ end
+
+ def test_char_to_option_kcode
+ assert_equal("bar", "foobarbaz"[/b../s])
+ assert_equal("bar", "foobarbaz"[/b../e])
+ assert_equal("bar", "foobarbaz"[/b../u])
+ end
+
+ def test_to_s2
+ assert_equal('(?-mix:foo)', /(?:foo)/.to_s)
+ assert_equal('(?m-ix:foo)', /(?:foo)/m.to_s)
+ assert_equal('(?mi-x:foo)', /(?:foo)/mi.to_s)
+ assert_equal('(?mix:foo)', /(?:foo)/mix.to_s)
+ assert_equal('(?m-ix:foo)', /(?m-ix:foo)/.to_s)
+ assert_equal('(?mi-x:foo)', /(?mi-x:foo)/.to_s)
+ assert_equal('(?mix:foo)', /(?mix:foo)/.to_s)
+ assert_equal('(?mix:)', /(?mix)/.to_s)
+ assert_equal('(?-mix:(?mix:foo) )', /(?mix:foo) /.to_s)
+ end
+
+ def test_casefold_p
+ assert_equal(false, /a/.casefold?)
+ assert_equal(true, /a/i.casefold?)
+ assert_equal(false, /(?i:a)/.casefold?)
+ end
+
+ def test_options
+ assert_equal(Regexp::IGNORECASE, /a/i.options)
+ assert_equal(Regexp::EXTENDED, /a/x.options)
+ assert_equal(Regexp::MULTILINE, /a/m.options)
+ end
+
+ def test_match_init_copy
+ m = /foo/.match("foo")
+ assert_equal(/foo/, m.dup.regexp)
+ assert_raise(TypeError) do
+ m.instance_eval { initialize_copy(nil) }
+ end
+ assert_equal([0, 3], m.offset(0))
+ assert_equal(/foo/, m.dup.regexp)
+ end
+
+ def test_match_size
+ m = /(.)(.)(\d+)(\d)/.match("THX1138.")
+ assert_equal(5, m.size)
+ end
+
+ def test_match_offset_begin_end
+ m = /(?<x>b..)/.match("foobarbaz")
+ assert_equal([3, 6], m.offset("x"))
+ assert_equal(3, m.begin("x"))
+ assert_equal(6, m.end("x"))
+ assert_raise(IndexError) { m.offset("y") }
+ assert_raise(IndexError) { m.offset(2) }
+ assert_raise(IndexError) { m.begin(2) }
+ assert_raise(IndexError) { m.end(2) }
+
+ m = /(?<x>q..)?/.match("foobarbaz")
+ assert_equal([nil, nil], m.offset("x"))
+ assert_equal(nil, m.begin("x"))
+ assert_equal(nil, m.end("x"))
+
+ m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044")
+ assert_equal([1, 2], m.offset(1))
+ assert_equal([nil, nil], m.offset(2))
+ assert_equal([2, 3], m.offset(3))
+ end
+
+ def test_match_to_s
+ m = /(?<x>b..)/.match("foobarbaz")
+ assert_equal("bar", m.to_s)
+ end
+
+ def test_match_pre_post
+ m = /(?<x>b..)/.match("foobarbaz")
+ assert_equal("foo", m.pre_match)
+ assert_equal("baz", m.post_match)
+ end
+
+ def test_match_array
+ m = /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal(["foobarbaz", "foo", "bar", "baz", nil], m.to_a)
+ end
+
+ def test_match_captures
+ m = /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal(["foo", "bar", "baz", nil], m.captures)
+ end
+
+ def test_match_aref
+ m = /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal("foo", m[1])
+ assert_equal(["foo", "bar", "baz"], m[1..3])
+ assert_nil(m[5])
+ assert_raise(IndexError) { m[:foo] }
+ end
+
+ def test_match_values_at
+ m = /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal(["foo", "bar", "baz"], m.values_at(1, 2, 3))
+ end
+
+ def test_match_string
+ m = /(?<x>b..)/.match("foobarbaz")
+ assert_equal("foobarbaz", m.string)
+ end
+
+ def test_match_inspect
+ m = /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal('#<MatchData "foobarbaz" 1:"foo" 2:"bar" 3:"baz" 4:nil>', m.inspect)
+ end
+
+ def test_initialize
+ assert_raise(ArgumentError) { Regexp.new }
+ assert_equal(/foo/, Regexp.new(/foo/, Regexp::IGNORECASE))
+ re = /foo/
+ assert_raise(SecurityError) do
+ Thread.new { $SAFE = 4; re.instance_eval { initialize(re) } }.join
+ end
+ re.taint
+ assert_raise(SecurityError) do
+ Thread.new { $SAFE = 4; re.instance_eval { initialize(re) } }.join
+ end
+
+ assert_equal(Encoding.find("US-ASCII"), Regexp.new("b..", nil, "n").encoding)
+ assert_equal("bar", "foobarbaz"[Regexp.new("b..", nil, "n")])
+ assert_equal(//n, Regexp.new("", nil, "n"))
+
+ arg_encoding_none = 32 # ARG_ENCODING_NONE is implementation defined value
+ assert_equal(arg_encoding_none, Regexp.new("", nil, "n").options)
+ assert_equal(arg_encoding_none, Regexp.new("", nil, "N").options)
+
+ assert_raise(RegexpError) { Regexp.new(")(") }
+ end
+
+ def test_unescape
+ assert_raise(ArgumentError) { s = '\\'; /#{ s }/ }
+ assert_equal(/\xFF/n, /#{ s="\\xFF" }/n)
+ assert_equal(/\177/, (s = '\177'; /#{ s }/))
+ assert_raise(ArgumentError) { s = '\u'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\u{ ffffffff }'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\u{ ffffff }'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\u{ ffff X }'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\u{ }'; /#{ s }/ }
+ assert_equal("b", "abc"[(s = '\u{0062}'; /#{ s }/)])
+ assert_equal("b", "abc"[(s = '\u0062'; /#{ s }/)])
+ assert_raise(ArgumentError) { s = '\u0'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\u000X'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = "\xff" + '\u3042'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\u3042' + [0xff].pack("C"); /#{ s }/ }
+ assert_raise(SyntaxError) { s = ''; eval(%q(/\u#{ s }/)) }
+
+ assert_equal(/a/, eval(%q(s="\u0061";/#{s}/n)))
+ assert_raise(RegexpError) { s = "\u3042"; eval(%q(/#{s}/n)) }
+ assert_raise(RegexpError) { s = "\u0061"; eval(%q(/\u3042#{s}/n)) }
+ assert_raise(RegexpError) { s1=[0xff].pack("C"); s2="\u3042"; eval(%q(/#{s1}#{s2}/)) }
+
+ assert_raise(ArgumentError) { s = '\x'; /#{ s }/ }
+
+ assert_equal("\xe1", [0x00, 0xe1, 0xff].pack("C*")[/\M-a/])
+ assert_equal("\xdc", [0x00, 0xdc, 0xff].pack("C*")[/\M-\\/])
+ assert_equal("\x8a", [0x00, 0x8a, 0xff].pack("C*")[/\M-\n/])
+ assert_equal("\x89", [0x00, 0x89, 0xff].pack("C*")[/\M-\t/])
+ assert_equal("\x8d", [0x00, 0x8d, 0xff].pack("C*")[/\M-\r/])
+ assert_equal("\x8c", [0x00, 0x8c, 0xff].pack("C*")[/\M-\f/])
+ assert_equal("\x8b", [0x00, 0x8b, 0xff].pack("C*")[/\M-\v/])
+ assert_equal("\x87", [0x00, 0x87, 0xff].pack("C*")[/\M-\a/])
+ assert_equal("\x9b", [0x00, 0x9b, 0xff].pack("C*")[/\M-\e/])
+ assert_equal("\x01", [0x00, 0x01, 0xff].pack("C*")[/\C-a/])
+
+ assert_raise(ArgumentError) { s = '\M'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\M-\M-a'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\M-\\'; /#{ s }/ }
+
+ assert_raise(ArgumentError) { s = '\C'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\c'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\C-\C-a'; /#{ s }/ }
+
+ assert_raise(ArgumentError) { s = '\M-\z'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\M-\777'; /#{ s }/ }
+
+ assert_equal("\u3042\u3042", "\u3042\u3042"[(s = "\u3042" + %q(\xe3\x81\x82); /#{s}/)])
+ assert_raise(ArgumentError) { s = "\u3042" + %q(\xe3); /#{s}/ }
+ assert_raise(ArgumentError) { s = "\u3042" + %q(\xe3\xe3); /#{s}/ }
+ assert_raise(ArgumentError) { s = '\u3042' + [0xff].pack("C"); /#{s}/ }
+
+ assert_raise(SyntaxError) { eval("/\u3042/n") }
+
+ s = ".........."
+ 5.times { s.sub!(".", "") }
+ assert_equal(".....", s)
+ end
+
+ def test_equal
+ assert_equal(true, /abc/ == /abc/)
+ assert_equal(false, /abc/ == /abc/m)
+ assert_equal(false, /abc/ == /abd/)
+ end
+
+ def test_match
+ assert_nil(//.match(nil))
+ assert_equal("abc", /.../.match(:abc)[0])
+ assert_raise(TypeError) { /.../.match(Object.new)[0] }
+ assert_equal("bc", /../.match('abc', 1)[0])
+ assert_equal("bc", /../.match('abc', -2)[0])
+ assert_nil(/../.match("abc", -4))
+ assert_nil(/../.match("abc", 4))
+ assert_equal('\x', /../n.match("\u3042" + '\x', 1)[0])
+
+ r = nil
+ /.../.match("abc") {|m| r = m[0] }
+ assert_equal("abc", r)
+
+ $_ = "abc"; assert_equal(1, ~/bc/)
+ $_ = "abc"; assert_nil(~/d/)
+ $_ = nil; assert_nil(~/./)
+ end
+
+ def test_eqq
+ assert_equal(false, /../ === nil)
+ end
+
+ def test_quote
+ assert_equal("\xff", Regexp.quote([0xff].pack("C")))
+ assert_equal("\\ ", Regexp.quote("\ "))
+ assert_equal("\\t", Regexp.quote("\t"))
+ assert_equal("\\n", Regexp.quote("\n"))
+ assert_equal("\\r", Regexp.quote("\r"))
+ assert_equal("\\f", Regexp.quote("\f"))
+ assert_equal("\\v", Regexp.quote("\v"))
+ assert_equal("\u3042\\t", Regexp.quote("\u3042\t"))
+ assert_equal("\\t\xff", Regexp.quote("\t" + [0xff].pack("C")))
+ end
+
+ def test_try_convert
+ assert_equal(/re/, Regexp.try_convert(/re/))
+ assert_nil(Regexp.try_convert("re"))
+
+ o = Object.new
+ assert_nil(Regexp.try_convert(o))
+ def o.to_regexp() /foo/ end
+ assert_equal(/foo/, Regexp.try_convert(o))
+ end
+
+ def test_union2
+ assert_equal(/(?!)/, Regexp.union)
+ assert_equal(/foo/, Regexp.union(/foo/))
+ assert_equal(/foo/, Regexp.union([/foo/]))
+ assert_equal(/\t/, Regexp.union("\t"))
+ assert_equal(/(?-mix:\u3042)|(?-mix:\u3042)/, Regexp.union(/\u3042/, /\u3042/))
+ assert_equal("\u3041", "\u3041"[Regexp.union(/\u3042/, "\u3041")])
+ end
+
+ def test_dup
+ assert_equal(//, //.dup)
+ assert_raise(TypeError) { //.instance_eval { initialize_copy(nil) } }
+ end
+
+ def test_regsub
+ assert_equal("fooXXXbaz", "foobarbaz".sub!(/bar/, "XXX"))
+ s = [0xff].pack("C")
+ assert_equal(s, "X".sub!(/./, s))
+ assert_equal('\\' + s, "X".sub!(/./, '\\' + s))
+ assert_equal('\k', "foo".sub!(/.../, '\k'))
+ assert_raise(RuntimeError) { "foo".sub!(/(?<x>o)/, '\k<x') }
+ assert_equal('foo[bar]baz', "foobarbaz".sub!(/(b..)/, '[\0]'))
+ assert_equal('foo[foo]baz', "foobarbaz".sub!(/(b..)/, '[\`]'))
+ assert_equal('foo[baz]baz', "foobarbaz".sub!(/(b..)/, '[\\\']'))
+ assert_equal('foo[r]baz', "foobarbaz".sub!(/(b)(.)(.)/, '[\+]'))
+ assert_equal('foo[\\]baz', "foobarbaz".sub!(/(b..)/, '[\\\\]'))
+ assert_equal('foo[\z]baz', "foobarbaz".sub!(/(b..)/, '[\z]'))
+ end
+
+ def test_KCODE
+ assert_nil($KCODE)
+ assert_nothing_raised { $KCODE = nil }
+ assert_equal(false, $=)
+ assert_nothing_raised { $= = nil }
+ end
+
+ def test_match_setter
+ /foo/ =~ "foo"
+ m = $~
+ /bar/ =~ "bar"
+ $~ = m
+ assert_equal("foo", $&)
+ end
+
+ def test_last_match
+ /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal("foobarbaz", Regexp.last_match(0))
+ assert_equal("foo", Regexp.last_match(1))
+ assert_nil(Regexp.last_match(5))
+ assert_nil(Regexp.last_match(-1))
+ end
+
+ def test_getter
+ alias $__REGEXP_TEST_LASTMATCH__ $&
+ alias $__REGEXP_TEST_PREMATCH__ $`
+ alias $__REGEXP_TEST_POSTMATCH__ $'
+ alias $__REGEXP_TEST_LASTPARENMATCH__ $+
+ /(b)(.)(.)/.match("foobarbaz")
+ assert_equal("bar", $__REGEXP_TEST_LASTMATCH__)
+ assert_equal("foo", $__REGEXP_TEST_PREMATCH__)
+ assert_equal("baz", $__REGEXP_TEST_POSTMATCH__)
+ assert_equal("r", $__REGEXP_TEST_LASTPARENMATCH__)
+
+ /(...)(...)(...)/.match("foobarbaz")
+ assert_equal("baz", $+)
+ end
+
+ def test_rindex_regexp
+ assert_equal(3, "foobarbaz\u3042".rindex(/b../n, 5))
+ end
+
+ def test_taint
+ m = Thread.new do
+ "foo"[/foo/]
+ $SAFE = 4
+ /foo/.match("foo")
+ end.value
+ assert(m.tainted?)
+ assert_nothing_raised('[ruby-core:26137]') {
+ m = proc {$SAFE = 4; %r"#{ }"o}.call
+ }
+ assert(m.tainted?)
+ end
+
+ def check(re, ss, fs = [])
+ re = Regexp.new(re) unless re.is_a?(Regexp)
+ ss = [ss] unless ss.is_a?(Array)
+ ss.each do |e, s|
+ s ||= e
+ assert_match(re, s)
+ m = re.match(s)
+ assert_equal(e, m[0])
+ end
+ fs = [fs] unless fs.is_a?(Array)
+ fs.each {|s| assert_no_match(re, s) }
+ end
+
+ def failcheck(re)
+ assert_raise(RegexpError) { %r"#{ re }" }
+ end
+
+ def test_parse
+ check(/\*\+\?\{\}\|\(\)\<\>\`\'/, "*+?{}|()<>`'")
+ check(/\A\w\W\z/, %w(a. b!), %w(.. ab))
+ check(/\A.\b.\b.\B.\B.\z/, %w(a.aaa .a...), %w(aaaaa .....))
+ check(/\A\s\S\z/, [' a', "\n."], [' ', "\n\n", 'a '])
+ check(/\A\d\D\z/, '0a', %w(00 aa))
+ check(/\A\h\H\z/, %w(0g ag BH), %w(a0 af GG))
+ check(/\Afoo\Z\s\z/, "foo\n", ["foo", "foo\nbar"])
+ assert_equal(%w(a b c), "abc def".scan(/\G\w/))
+ check(/\A\u3042\z/, "\u3042", ["", "\u3043", "a"])
+ check(/\A(..)\1\z/, %w(abab ....), %w(abba aba))
+ failcheck('\1')
+ check(/\A\80\z/, "80", ["\100", ""])
+ check(/\A\77\z/, "?")
+ check(/\A\78\z/, "\7" + '8', ["\100", ""])
+ check(/\A\Qfoo\E\z/, "QfooE")
+ check(/\Aa++\z/, "aaa")
+ check('\Ax]\z', "x]")
+ check(/x#foo/x, "x", "#foo")
+ check(/\Ax#foo#{ "\n" }x\z/x, "xx", ["x", "x#foo\nx"])
+ check(/\A\p{Alpha}\z/, ["a", "z"], [".", "", ".."])
+ check(/\A\p{^Alpha}\z/, [".", "!"], ["!a", ""])
+ check(/\A\n\z/, "\n")
+ check(/\A\t\z/, "\t")
+ check(/\A\r\z/, "\r")
+ check(/\A\f\z/, "\f")
+ check(/\A\a\z/, "\007")
+ check(/\A\e\z/, "\033")
+ check(/\A\v\z/, "\v")
+ failcheck('(')
+ failcheck('(?foo)')
+ failcheck('/\p{foobarbazqux}/')
+ failcheck('/\p{foobarbazqux' + 'a' * 1000 + '}/')
+ failcheck('/[1-\w]/')
+ end
+
+ def test_exec
+ check(/A*B/, %w(B AB AAB AAAB), %w(A))
+ check(/\w*!/, %w(! a! ab! abc!), %w(abc))
+ check(/\w*\W/, %w(! a" ab# abc$), %w(abc))
+ check(/\w*\w/, %w(z az abz abcz), %w(!))
+ check(/[a-z]*\w/, %w(z az abz abcz), %w(!))
+ check(/[a-z]*\W/, %w(! a" ab# abc$), %w(A))
+ check(/((a|bb|ccc|dddd)(1|22|333|4444))/i, %w(a1 bb1 a22), %w(a2 b1))
+ check(/\u0080/, (1..4).map {|i| ["\u0080", "\u0080" * i] }, ["\u0081"])
+ check(/\u0080\u0080/, (2..4).map {|i| ["\u0080" * 2, "\u0080" * i] }, ["\u0081"])
+ check(/\u0080\u0080\u0080/, (3..4).map {|i| ["\u0080" * 3, "\u0080" * i] }, ["\u0081"])
+ check(/\u0080\u0080\u0080\u0080/, (4..4).map {|i| ["\u0080" * 4, "\u0080" * i] }, ["\u0081"])
+ check(/[^\u3042\u3043\u3044]/, %W(a b \u0080 \u3041 \u3045), %W(\u3042 \u3043 \u3044))
+ check(/a.+/m, %W(a\u0080 a\u0080\u0080 a\u0080\u0080\u0080), %W(a))
+ check(/a.+z/m, %W(a\u0080z a\u0080\u0080z a\u0080\u0080\u0080z), %W(az))
+ check(/abc\B.\Bxyz/, %w(abcXxyz abc0xyz), %w(abc|xyz abc-xyz))
+ check(/\Bxyz/, [%w(xyz abcXxyz), %w(xyz abc0xyz)], %w(abc xyz abc-xyz))
+ check(/abc\B/, [%w(abc abcXxyz), %w(abc abc0xyz)], %w(abc xyz abc-xyz))
+ failcheck('(?<foo>abc)\1')
+ check(/^(A+|B+)(?>\g<1>)*[BC]$/, %w(AC BC ABC BAC AABBC), %w(AABB))
+ check(/^(A+|B(?>\g<1>)*)[AC]$/, %w(AAAC BBBAAAAC), %w(BBBAAA))
+ check(/^()(?>\g<1>)*$/, "", "a")
+ check(/^(?>(?=a)(#{ "a" * 1000 }|))++$/, ["a" * 1000, "a" * 2000, "a" * 3000], ["", "a" * 500, "b" * 1000])
+ check(eval('/^(?:a?)?$/'), ["", "a"], ["aa"])
+ check(eval('/^(?:a+)?$/'), ["", "a", "aa"], ["ab"])
+ check(/^(?:a?)+?$/, ["", "a", "aa"], ["ab"])
+ check(/^a??[ab]/, [["a", "a"], ["a", "aa"], ["b", "b"], ["a", "ab"]], ["c"])
+ check(/^(?:a*){3,5}$/, ["", "a", "aa", "aaa", "aaaa", "aaaaa", "aaaaaa"], ["b"])
+ check(/^(?:a+){3,5}$/, ["aaa", "aaaa", "aaaaa", "aaaaaa"], ["", "a", "aa", "b"])
+ end
+
+ def test_parse_look_behind
+ check(/(?<=A)B(?=C)/, [%w(B ABC)], %w(aBC ABc aBc))
+ check(/(?<!A)B(?!C)/, [%w(B aBc)], %w(ABC aBC ABc))
+ failcheck('(?<=.*)')
+ failcheck('(?<!.*)')
+ check(/(?<=A|B.)C/, [%w(C AC), %w(C BXC)], %w(C BC))
+ check(/(?<!A|B.)C/, [%w(C C), %w(C BC)], %w(AC BXC))
+ end
+
+ def test_parse_kg
+ check(/\A(.)(.)\k<1>(.)\z/, %w(abac abab ....), %w(abcd aaba xxx))
+ check(/\A(.)(.)\k<-1>(.)\z/, %w(abbc abba ....), %w(abcd aaba xxx))
+ check(/\A(?<n>.)(?<x>\g<n>){0}(?<y>\k<n+0>){0}\g<x>\g<y>\z/, "aba", "abb")
+ check(/\A(?<n>.)(?<x>\g<n>){0}(?<y>\k<n+1>){0}\g<x>\g<y>\z/, "abb", "aba")
+ check(/\A(?<x>..)\k<x>\z/, %w(abab ....), %w(abac abba xxx))
+ check(/\A(.)(..)\g<-1>\z/, "abcde", %w(.... ......))
+ failcheck('\k<x>')
+ failcheck('\k<')
+ failcheck('\k<>')
+ failcheck('\k<.>')
+ failcheck('\k<x.>')
+ failcheck('\k<1.>')
+ failcheck('\k<x')
+ failcheck('\k<x+')
+ failcheck('()\k<-2>')
+ failcheck('()\g<-2>')
+ check(/\A(?<x>.)(?<x>.)\k<x>\z/, %w(aba abb), %w(abc .. ....))
+ check(/\A(?<x>.)(?<x>.)\k<x>\z/i, %w(aba ABa abb ABb), %w(abc .. ....))
+ check('\k\g', "kg")
+ failcheck('(.\g<1>)')
+ failcheck('(.\g<2>)')
+ failcheck('(?=\g<1>)')
+ failcheck('((?=\g<1>))')
+ failcheck('(\g<1>|.)')
+ failcheck('(.|\g<1>)')
+ check(/(!)(?<=(a)|\g<1>)/, ["!"], %w(a))
+ check(/^(a|b\g<1>c)$/, %w(a bac bbacc bbbaccc), %w(bbac bacc))
+ check(/^(a|b\g<2>c)(B\g<1>C){0}$/, %w(a bBaCc bBbBaCcCc bBbBbBaCcCcCc), %w(bBbBaCcC BbBaCcCc))
+ check(/\A(?<n>.|X\g<n>)(?<x>\g<n>){0}(?<y>\k<n+0>){0}\g<x>\g<y>\z/, "XXaXbXXa", %w(XXabXa abb))
+ check(/\A(?<n>.|X\g<n>)(?<x>\g<n>){0}(?<y>\k<n+1>){0}\g<x>\g<y>\z/, "XaXXbXXb", %w(aXXbXb aba))
+ failcheck('(?<x>)(?<x>)(\g<x>)')
+ check(/^(?<x>foo)(bar)\k<x>/, %w(foobarfoo), %w(foobar barfoo))
+ check(/^(?<a>f)(?<a>o)(?<a>o)(?<a>b)(?<a>a)(?<a>r)(?<a>b)(?<a>a)(?<a>z)\k<a>{9}$/, %w(foobarbazfoobarbaz foobarbazbazbarfoo foobarbazzabraboof), %w(foobar barfoo))
+ end
+
+ def test_parse_curly_brace
+ check(/\A{/, ["{", ["{", "{x"]])
+ check(/\A{ /, ["{ ", ["{ ", "{ x"]])
+ check(/\A{,}\z/, "{,}")
+ check(/\A{}\z/, "{}")
+ check(/\Aa{0}+\z/, "", %w(a aa aab))
+ check(/\Aa{1}+\z/, %w(a aa), ["", "aab"])
+ check(/\Aa{1,2}b{1,2}\z/, %w(ab aab abb aabb), ["", "aaabb", "abbb"])
+ check(/(?!x){0,1}/, [ ['', 'ab'], ['', ''] ])
+ check(/c\z{0,1}/, [ ['c', 'abc'], ['c', 'cab']], ['abd'])
+ check(/\A{0,1}a/, [ ['a', 'abc'], ['a', '____abc']], ['bcd'])
+ failcheck('.{100001}')
+ failcheck('.{0,100001}')
+ failcheck('.{1,0}')
+ failcheck('{0}')
+ end
+
+ def test_parse_comment
+ check(/\A(?#foo\)bar)\z/, "", "a")
+ failcheck('(?#')
+ end
+
+ def test_char_type
+ check(/\u3042\d/, ["\u30421", "\u30422"])
+
+ # CClassTable cache test
+ assert_match(/\u3042\d/, "\u30421")
+ assert_match(/\u3042\d/, "\u30422")
+ end
+
+ def test_char_class
+ failcheck('[]')
+ failcheck('[x')
+ check('\A[]]\z', "]", "")
+ check('\A[]\.]+\z', %w(] . ]..]), ["", "["])
+ check(/\A[\u3042]\z/, "\u3042", "\u3042aa")
+ check(/\A[\u3042\x61]+\z/, ["aa\u3042aa", "\u3042\u3042", "a"], ["", "b"])
+ check(/\A[\u3042\x61\x62]+\z/, "abab\u3042abab\u3042")
+ check(/\A[abc]+\z/, "abcba", ["", "ada"])
+ check(/\A[\w][\W]\z/, %w(a. b!), %w(.. ab))
+ check(/\A[\s][\S]\z/, [' a', "\n."], [' ', "\n\n", 'a '])
+ check(/\A[\d][\D]\z/, '0a', %w(00 aa))
+ check(/\A[\h][\H]\z/, %w(0g ag BH), %w(a0 af GG))
+ check(/\A[\p{Alpha}]\z/, ["a", "z"], [".", "", ".."])
+ check(/\A[\p{^Alpha}]\z/, [".", "!"], ["!a", ""])
+ check(/\A[\xff]\z/, "\xff", ["", "\xfe"])
+ check(/\A[\80]+\z/, "8008", ["\\80", "\100", "\1000"])
+ check(/\A[\77]+\z/, "???")
+ check(/\A[\78]+\z/, "\788\7")
+ check(/\A[\0]\z/, "\0")
+ check(/\A[[:0]]\z/, [":", "0"], ["", ":0"])
+ check(/\A[0-]\z/, ["0", "-"], "0-")
+ check('\A[a-&&\w]\z', "a", "-")
+ check('\A[--0]\z', ["-", "/", "0"], ["", "1"])
+ check('\A[\'--0]\z', %w(* + \( \) 0 ,), ["", ".", "1"])
+ check(/\A[a-b-]\z/, %w(a b -), ["", "c"])
+ check('\A[a-b-&&\w]\z', %w(a b), ["", "-"])
+ check('\A[a-b-&&\W]\z', "-", ["", "a", "b"])
+ check('\A[a-c-e]\z', %w(a b c e), %w(- d)) # is it OK?
+ check(/\A[a-f&&[^b-c]&&[^e]]\z/, %w(a d f), %w(b c e g 0))
+ check(/\A[[^b-c]&&[^e]&&a-f]\z/, %w(a d f), %w(b c e g 0))
+ check(/\A[\n\r\t]\z/, ["\n", "\r", "\t"])
+ failcheck('[9-1]')
+
+ assert_match(/\A\d+\z/, "0123456789")
+ assert_no_match(/\d/, "\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19")
+ assert_match(/\A\w+\z/, "09azAZ_")
+ assert_no_match(/\w/, "\uff10\uff19\uff41\uff5a\uff21\uff3a")
+ assert_match(/\A\s+\z/, "\r\n\v\f\r\s")
+ assert_no_match(/\s/, "\u0085")
+ end
+
+ def test_posix_bracket
+ check(/\A[[:alpha:]0]\z/, %w(0 a), %w(1 .))
+ check(/\A[[:^alpha:]0]\z/, %w(0 1 .), "a")
+ check(/\A[[:alpha\:]]\z/, %w(a l p h a :), %w(b 0 1 .))
+ check(/\A[[:alpha:foo]0]\z/, %w(0 a), %w(1 .))
+ check(/\A[[:xdigit:]&&[:alpha:]]\z/, "a", %w(g 0))
+ check('\A[[:abcdefghijklmnopqrstu:]]+\z', "[]")
+ failcheck('[[:alpha')
+ failcheck('[[:alpha:')
+ failcheck('[[:alp:]]')
+
+ assert_match(/\A[[:digit:]]+\z/, "\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19")
+ assert_match(/\A[[:alnum:]]+\z/, "\uff10\uff19\uff41\uff5a\uff21\uff3a")
+ assert_match(/\A[[:space:]]+\z/, "\r\n\v\f\r\s\u0085")
+ assert_match(/\A[[:ascii:]]+\z/, "\x00\x7F")
+ assert_no_match(/[[:ascii:]]/, "\x80\xFF")
+ end
+
+ def test_backward
+ assert_equal(3, "foobar".rindex(/b.r/i))
+ assert_equal(nil, "foovar".rindex(/b.r/i))
+ assert_equal(3, ("foo" + "bar" * 1000).rindex(/#{"bar"*1000}/))
+ assert_equal(4, ("foo\nbar\nbaz\n").rindex(/bar/i))
+ end
+
+ def test_uninitialized
+ assert_raise(TypeError) { Regexp.allocate.hash }
+ assert_raise(TypeError) { Regexp.allocate.eql? Regexp.allocate }
+ assert_raise(TypeError) { Regexp.allocate == Regexp.allocate }
+ assert_raise(TypeError) { Regexp.allocate =~ "" }
+ assert_equal(false, Regexp.allocate === Regexp.allocate)
+ assert_nil(~Regexp.allocate)
+ assert_raise(TypeError) { Regexp.allocate.match("") }
+ assert_raise(TypeError) { Regexp.allocate.to_s }
+ assert_match(/^#<Regexp:.*>$/, Regexp.allocate.inspect)
+ assert_raise(TypeError) { Regexp.allocate.source }
+ assert_raise(TypeError) { Regexp.allocate.casefold? }
+ assert_raise(TypeError) { Regexp.allocate.options }
+ assert_equal(Encoding.find("ASCII-8BIT"), Regexp.allocate.encoding)
+ assert_equal(false, Regexp.allocate.fixed_encoding?)
+ assert_raise(TypeError) { Regexp.allocate.names }
+ assert_raise(TypeError) { Regexp.allocate.named_captures }
+
+ assert_raise(TypeError) { MatchData.allocate.regexp }
+ assert_raise(TypeError) { MatchData.allocate.names }
+ assert_raise(TypeError) { MatchData.allocate.size }
+ assert_raise(TypeError) { MatchData.allocate.length }
+ assert_raise(TypeError) { MatchData.allocate.offset(0) }
+ assert_raise(TypeError) { MatchData.allocate.begin(0) }
+ assert_raise(TypeError) { MatchData.allocate.end(0) }
+ assert_raise(TypeError) { MatchData.allocate.to_a }
+ assert_raise(TypeError) { MatchData.allocate[:foo] }
+ assert_raise(TypeError) { MatchData.allocate.captures }
+ assert_raise(TypeError) { MatchData.allocate.values_at }
+ assert_raise(TypeError) { MatchData.allocate.pre_match }
+ assert_raise(TypeError) { MatchData.allocate.post_match }
+ assert_raise(TypeError) { MatchData.allocate.to_s }
+ assert_match(/^#<MatchData:.*>$/, MatchData.allocate.inspect)
+ assert_raise(TypeError) { MatchData.allocate.string }
+ $~ = MatchData.allocate
+ assert_raise(TypeError) { $& }
+ assert_raise(TypeError) { $` }
+ assert_raise(TypeError) { $' }
+ assert_raise(TypeError) { $+ }
+ end
+
+ def test_unicode
+ assert_match(/^\u3042{0}\p{Any}$/, "a")
+ assert_match(/^\u3042{0}\p{Any}$/, "\u3041")
+ assert_match(/^\u3042{0}\p{Any}$/, "\0")
+ assert_match(/^\p{Lo}{4}$/u, "\u3401\u4E01\u{20001}\u{2A701}")
+ assert_no_match(/^\u3042{0}\p{Any}$/, "\0\0")
+ assert_no_match(/^\u3042{0}\p{Any}$/, "")
+ assert_raise(SyntaxError) { eval('/^\u3042{0}\p{' + "\u3042" + '}$/') }
+ assert_raise(SyntaxError) { eval('/^\u3042{0}\p{' + 'a' * 1000 + '}$/') }
+ assert_raise(SyntaxError) { eval('/^\u3042{0}\p{foobarbazqux}$/') }
+ assert_match(/^(\uff21)(a)\1\2$/i, "\uff21A\uff41a")
+ assert_no_match(/^(\uff21)\1$/i, "\uff21A")
+ assert_no_match(/^(\uff41)\1$/i, "\uff41a")
+ assert_match(/^\u00df$/i, "\u00df")
+ assert_match(/^\u00df$/i, "ss")
+ #assert_match(/^(\u00df)\1$/i, "\u00dfss") # this must be bug...
+ assert_match(/^\u00df{2}$/i, "\u00dfss")
+ assert_match(/^\u00c5$/i, "\u00c5")
+ assert_match(/^\u00c5$/i, "\u00e5")
+ assert_match(/^\u00c5$/i, "\u212b")
+ assert_match(/^(\u00c5)\1\1$/i, "\u00c5\u00e5\u212b")
+ assert_match(/^\u0149$/i, "\u0149")
+ assert_match(/^\u0149$/i, "\u02bcn")
+ #assert_match(/^(\u0149)\1$/i, "\u0149\u02bcn") # this must be bug...
+ assert_match(/^\u0149{2}$/i, "\u0149\u02bcn")
+ assert_match(/^\u0390$/i, "\u0390")
+ assert_match(/^\u0390$/i, "\u03b9\u0308\u0301")
+ #assert_match(/^(\u0390)\1$/i, "\u0390\u03b9\u0308\u0301") # this must be bug...
+ assert_match(/^\u0390{2}$/i, "\u0390\u03b9\u0308\u0301")
+ assert_match(/^\ufb05$/i, "\ufb05")
+ assert_match(/^\ufb05$/i, "\ufb06")
+ assert_match(/^\ufb05$/i, "st")
+ #assert_match(/^(\ufb05)\1\1$/i, "\ufb05\ufb06st") # this must be bug...
+ assert_match(/^\ufb05{3}$/i, "\ufb05\ufb06st")
+ assert_match(/^\u03b9\u0308\u0301$/i, "\u0390")
+ assert_nothing_raised { 0x03ffffff.chr("utf-8").size }
+ assert_nothing_raised { 0x7fffffff.chr("utf-8").size }
+ end
+
+ def test_matchdata
+ a = "haystack".match(/hay/)
+ b = "haystack".match(/hay/)
+ assert_equal(a, b, '[ruby-core:24748]')
+ h = {a => 42}
+ assert_equal(42, h[b], '[ruby-core:24748]')
+ end
+
+ def test_regexp_poped
+ assert_nothing_raised { eval("a = 1; /\#{ a }/; a") }
+ assert_nothing_raised { eval("a = 1; /\#{ a }/o; a") }
+ end
+
+ def test_optimize_last_anycharstar
+ s = "1" + " " * 5000000
+ assert_nothing_raised { s.match(/(\d) (.*)/) }
+ assert_equal("1", $1)
+ assert_equal(" " * 4999999, $2)
+ assert_match(/(?:A.+){2}/, 'AbAb')
+ end
+
+ def test_invalid_fragment
+ bug2547 = '[ruby-core:27374]'
+ assert_raise(SyntaxError, bug2547) {eval('/#{"\\\\"}y/')}
+ end
+
+ def test_dup_warn
+ assert_in_out_err(%w/-w -U/, "#coding:utf-8\nx=/[\u3042\u3041]/\n!x", [], [])
+ assert_in_out_err(%w/-w -U/, "#coding:utf-8\nx=/[\u3042\u3042]/\n!x", [], /duplicated/u, nil,
+ encoding: Encoding::UTF_8)
+ assert_in_out_err(%w/-w -U/, "#coding:utf-8\nx=/[\u3042\u3041-\u3043]/\n!x", [], /duplicated/u, nil,
+ encoding: Encoding::UTF_8)
+ end
+
+ def test_property_warn
+ assert_in_out_err('-w', 'x=/\p%s/', [], %r"warning: invalid Unicode Property \\p: /\\p%s/")
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_require.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_require.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_require.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,303 @@
+require 'test/unit'
+
+require 'tempfile'
+require_relative 'envutil'
+require 'tmpdir'
+
+class TestRequire < Test::Unit::TestCase
+ def test_require_invalid_shared_object
+ t = Tempfile.new(["test_ruby_test_require", ".so"])
+ t.puts "dummy"
+ t.close
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ begin
+ require \"#{ t.path }\"
+ rescue LoadError
+ p :ok
+ end
+ INPUT
+ end
+
+ def test_require_too_long_filename
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ begin
+ require '#{ "foo/" * 10000 }foo'
+ rescue LoadError
+ p :ok
+ end
+ INPUT
+
+ begin
+ assert_in_out_err(["-S", "foo/" * 10000 + "foo"], "") do |r, e|
+ assert_equal([], r)
+ assert_operator(2, :<=, e.size)
+ assert_equal("openpath: pathname too long (ignored)", e.first)
+ assert_match(/\(LoadError\)/, e.last)
+ end
+ rescue Errno::EINVAL
+ # too long commandline may be blocked by OS.
+ end
+ end
+
+ def test_require_path_home
+ env_rubypath, env_home = ENV["RUBYPATH"], ENV["HOME"]
+
+ ENV["RUBYPATH"] = "~"
+ ENV["HOME"] = "/foo" * 10000
+ assert_in_out_err(%w(-S test_ruby_test_require), "", [], /^.+$/)
+
+ ENV["RUBYPATH"] = "~" + "/foo" * 10000
+ ENV["HOME"] = "/foo"
+ assert_in_out_err(%w(-S test_ruby_test_require), "", [], /^.+$/)
+
+ t = Tempfile.new(["test_ruby_test_require", ".rb"])
+ t.puts "p :ok"
+ t.close
+ ENV["RUBYPATH"] = "~"
+ ENV["HOME"], name = File.split(t.path)
+ assert_in_out_err(["-S", name], "", %w(:ok), [])
+
+ ensure
+ env_rubypath ? ENV["RUBYPATH"] = env_rubypath : ENV.delete("RUBYPATH")
+ env_home ? ENV["HOME"] = env_home : ENV.delete("HOME")
+ end
+
+ def test_define_class
+ begin
+ require "socket"
+ rescue LoadError
+ return
+ end
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ BasicSocket = 1
+ begin
+ require 'socket'
+ p :ng
+ rescue TypeError
+ p :ok
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ class BasicSocket; end
+ begin
+ require 'socket'
+ p :ng
+ rescue TypeError
+ p :ok
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ class BasicSocket < IO; end
+ begin
+ require 'socket'
+ p :ok
+ rescue Exception
+ p :ng
+ end
+ INPUT
+ end
+
+ def test_define_class_under
+ begin
+ require "zlib"
+ rescue LoadError
+ return
+ end
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ module Zlib; end
+ Zlib::Error = 1
+ begin
+ require 'zlib'
+ p :ng
+ rescue TypeError
+ p :ok
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ module Zlib; end
+ class Zlib::Error; end
+ begin
+ require 'zlib'
+ p :ng
+ rescue NameError
+ p :ok
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ module Zlib; end
+ class Zlib::Error < StandardError; end
+ begin
+ require 'zlib'
+ p :ok
+ rescue Exception
+ p :ng
+ end
+ INPUT
+ end
+
+ def test_define_module
+ begin
+ require "zlib"
+ rescue LoadError
+ return
+ end
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ Zlib = 1
+ begin
+ require 'zlib'
+ p :ng
+ rescue TypeError
+ p :ok
+ end
+ INPUT
+ end
+
+ def test_define_module_under
+ begin
+ require "socket"
+ rescue LoadError
+ return
+ end
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ class BasicSocket < IO; end
+ class Socket < BasicSocket; end
+ Socket::Constants = 1
+ begin
+ require 'socket'
+ p :ng
+ rescue TypeError
+ p :ok
+ end
+ INPUT
+ end
+
+ def test_load
+ t = Tempfile.new(["test_ruby_test_require", ".rb"])
+ t.puts "module Foo; end"
+ t.puts "at_exit { p :wrap_end }"
+ t.puts "at_exit { raise 'error in at_exit test' }"
+ t.puts "p :ok"
+ t.close
+
+ assert_in_out_err([], <<-INPUT, %w(:ok :end :wrap_end), /error in at_exit test/)
+ load(#{ t.path.dump }, true)
+ GC.start
+ p :end
+ INPUT
+
+ assert_raise(ArgumentError) { at_exit }
+ end
+
+ def test_load2 # [ruby-core:25039]
+ t = Tempfile.new(["test_ruby_test_require", ".rb"])
+ t.puts "Hello = 'hello'"
+ t.puts "class Foo"
+ t.puts " p Hello"
+ t.puts "end"
+ t.close
+
+ assert_in_out_err([], <<-INPUT, %w("hello"), [])
+ load(#{ t.path.dump }, true)
+ INPUT
+ end
+
+ def test_tainted_loadpath
+ t = Tempfile.new(["test_ruby_test_require", ".rb"])
+ abs_dir, file = File.split(t.path)
+ abs_dir = File.expand_path(abs_dir).untaint
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ abs_dir = "#{ abs_dir }"
+ $: << abs_dir
+ require "#{ file }"
+ p :ok
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ abs_dir = "#{ abs_dir }"
+ $: << abs_dir.taint
+ require "#{ file }"
+ p :ok
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ abs_dir = "#{ abs_dir }"
+ $: << abs_dir.taint
+ $SAFE = 1
+ begin
+ require "#{ file }"
+ rescue SecurityError
+ p :ok
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ abs_dir = "#{ abs_dir }"
+ $: << abs_dir.taint
+ $SAFE = 1
+ begin
+ require "#{ file }"
+ rescue SecurityError
+ p :ok
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ abs_dir = "#{ abs_dir }"
+ $: << abs_dir << 'elsewhere'.taint
+ require "#{ file }"
+ p :ok
+ INPUT
+ end
+
+ def test_relative
+ load_path = $:.dup
+ $:.delete(".")
+ Dir.mktmpdir do |tmp|
+ Dir.chdir(tmp) do
+ Dir.mkdir('x')
+ File.open('x/t.rb', 'wb') {}
+ File.open('x/a.rb', 'wb') {|f| f.puts("require_relative('t.rb')")}
+ assert require('./x/t.rb')
+ assert !require(File.expand_path('x/t.rb'))
+ assert_nothing_raised(LoadError) {require('./x/a.rb')}
+ assert_raise(LoadError) {require('x/t.rb')}
+ File.unlink(*Dir.glob('x/*'))
+ Dir.rmdir("#{tmp}/x")
+ $:.replace(load_path)
+ load_path = nil
+ assert(!require('tmpdir'))
+ end
+ end
+ ensure
+ $:.replace(load_path) if load_path
+ end
+
+ def test_relative_symlink
+ Dir.mktmpdir {|tmp|
+ Dir.chdir(tmp) {
+ Dir.mkdir "a"
+ Dir.mkdir "b"
+ File.open("a/lib.rb", "w") {|f| f.puts 'puts "a/lib.rb"' }
+ File.open("b/lib.rb", "w") {|f| f.puts 'puts "b/lib.rb"' }
+ File.open("a/tst.rb", "w") {|f| f.puts 'require_relative "lib"' }
+ begin
+ File.symlink("../a/tst.rb", "b/tst.rb")
+ result = IO.popen([EnvUtil.rubybin, "b/tst.rb"]).read
+ assert_equal("a/lib.rb\n", result, "[ruby-dev:40040]")
+ rescue NotImplementedError
+ skip "File.symlink is not implemented"
+ end
+ }
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_rubyoptions.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_rubyoptions.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_rubyoptions.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,450 @@
+require 'test/unit'
+
+require 'tmpdir'
+require 'tempfile'
+require_relative 'envutil'
+
+class TestRubyOptions < Test::Unit::TestCase
+ def test_source_file
+ assert_in_out_err([], "", [], [])
+ end
+
+ def test_usage
+ assert_in_out_err(%w(-h)) do |r, e|
+ assert_operator(r.size, :<=, 24)
+ assert_equal([], e)
+ end
+
+ assert_in_out_err(%w(--help)) do |r, e|
+ assert_operator(r.size, :<=, 24)
+ assert_equal([], e)
+ end
+ end
+
+ def test_option_variables
+ assert_in_out_err(["-e", 'p [$-p, $-l, $-a]']) do |r, e|
+ assert_equal(["[false, false, false]"], r)
+ assert_equal([], e)
+ end
+
+ assert_in_out_err(%w(-p -l -a -e) + ['p [$-p, $-l, $-a]'],
+ "foo\nbar\nbaz\n") do |r, e|
+ assert_equal(
+ [ '[true, true, true]', 'foo',
+ '[true, true, true]', 'bar',
+ '[true, true, true]', 'baz' ], r)
+ assert_equal([], e)
+ end
+ end
+
+ def test_warning
+ save_rubyopt = ENV['RUBYOPT']
+ ENV['RUBYOPT'] = nil
+ assert_in_out_err(%w(-W0 -e) + ['p $-W'], "", %w(0), [])
+ assert_in_out_err(%w(-W1 -e) + ['p $-W'], "", %w(1), [])
+ assert_in_out_err(%w(-Wx -e) + ['p $-W'], "", %w(1), [])
+ assert_in_out_err(%w(-W -e) + ['p $-W'], "", %w(2), [])
+ ensure
+ ENV['RUBYOPT'] = save_rubyopt
+ end
+
+ def test_safe_level
+ assert_in_out_err(%w(-T -e) + [""], "", [],
+ /no -e allowed in tainted mode \(SecurityError\)/)
+
+ assert_in_out_err(%w(-T4 -S foo.rb), "", [],
+ /no -S allowed in tainted mode \(SecurityError\)/)
+ end
+
+ def test_debug
+ assert_in_out_err(%w(-de) + ["p $DEBUG"], "", %w(true), [])
+
+ assert_in_out_err(%w(--debug -e) + ["p $DEBUG"], "", %w(true), [])
+ end
+
+ def test_verbose
+ assert_in_out_err(%w(-vve) + [""]) do |r, e|
+ assert_match(/^ruby #{RUBY_VERSION}(?:[p ]|dev).*? \[#{RUBY_PLATFORM}\]$/, r.join)
+ assert_equal RUBY_DESCRIPTION, r.join.chomp
+ assert_equal([], e)
+ end
+
+ assert_in_out_err(%w(--verbose -e) + ["p $VERBOSE"], "", %w(true), [])
+
+ assert_in_out_err(%w(--verbose), "", [], [])
+ end
+
+ def test_copyright
+ assert_in_out_err(%w(--copyright), "",
+ /^ruby - Copyright \(C\) 1993-\d+ Yukihiro Matsumoto$/, [])
+
+ assert_in_out_err(%w(--verbose -e) + ["p $VERBOSE"], "", %w(true), [])
+ end
+
+ def test_enable
+ assert_in_out_err(%w(--enable all -e) + [""], "", [], [])
+ assert_in_out_err(%w(--enable-all -e) + [""], "", [], [])
+ assert_in_out_err(%w(--enable=all -e) + [""], "", [], [])
+ assert_in_out_err(%w(--enable foobarbazqux -e) + [""], "", [],
+ /unknown argument for --enable: `foobarbazqux'/)
+ assert_in_out_err(%w(--enable), "", [], /missing argument for --enable/)
+ end
+
+ def test_disable
+ assert_in_out_err(%w(--disable all -e) + [""], "", [], [])
+ assert_in_out_err(%w(--disable-all -e) + [""], "", [], [])
+ assert_in_out_err(%w(--disable=all -e) + [""], "", [], [])
+ assert_in_out_err(%w(--disable foobarbazqux -e) + [""], "", [],
+ /unknown argument for --disable: `foobarbazqux'/)
+ assert_in_out_err(%w(--disable), "", [], /missing argument for --disable/)
+ end
+
+ def test_kanji
+ assert_in_out_err(%w(-KU), "p '\u3042'") do |r, e|
+ assert_equal("\"\u3042\"", r.join.force_encoding(Encoding::UTF_8))
+ end
+ assert_in_out_err(%w(-KE -e) + [""], "", [], [])
+ assert_in_out_err(%w(-KS -e) + [""], "", [], [])
+ assert_in_out_err(%w(-KN -e) + [""], "", [], [])
+ end
+
+ def test_version
+ assert_in_out_err(%w(--version)) do |r, e|
+ assert_match(/^ruby #{RUBY_VERSION}(?:[p ]|dev).*? \[#{RUBY_PLATFORM}\]$/, r.join)
+ assert_equal RUBY_DESCRIPTION, r.join.chomp
+ assert_equal([], e)
+ end
+ end
+
+ def test_eval
+ assert_in_out_err(%w(-e), "", [], /no code specified for -e \(RuntimeError\)/)
+ end
+
+ def test_require
+ require "pp"
+ assert_in_out_err(%w(-r pp -e) + ["pp 1"], "", %w(1), [])
+ assert_in_out_err(%w(-rpp -e) + ["pp 1"], "", %w(1), [])
+ rescue LoadError
+ end
+
+ def test_include
+ d = Dir.tmpdir
+ assert_in_out_err(["-I" + d, "-e", ""], "", [], [])
+ assert_in_out_err(["-I", d, "-e", ""], "", [], [])
+ end
+
+ def test_separator
+ assert_in_out_err(%w(-000 -e) + ["print gets"], "foo\nbar\0baz", %W(foo bar\0baz), [])
+
+ assert_in_out_err(%w(-0141 -e) + ["print gets"], "foo\nbar\0baz", %w(foo ba), [])
+
+ assert_in_out_err(%w(-0e) + ["print gets"], "foo\nbar\0baz", %W(foo bar\0), [])
+ end
+
+ def test_autosplit
+ assert_in_out_err(%w(-an -F: -e) + ["p $F"], "foo:bar:baz\nqux:quux:quuux\n",
+ ['["foo", "bar", "baz\n"]', '["qux", "quux", "quuux\n"]'], [])
+ end
+
+ def test_chdir
+ assert_in_out_err(%w(-C), "", [], /Can't chdir/)
+
+ assert_in_out_err(%w(-C test_ruby_test_rubyoptions_foobarbazqux), "", [], /Can't chdir/)
+
+ d = Dir.tmpdir
+ assert_in_out_err(["-C", d, "-e", "puts Dir.pwd"]) do |r, e|
+ assert(File.identical?(r.join, d))
+ assert_equal([], e)
+ end
+ end
+
+ def test_yydebug
+ assert_in_out_err(["-ye", ""]) do |r, e|
+ assert_equal([], r)
+ assert_not_equal([], e)
+ end
+
+ assert_in_out_err(%w(--yydebug -e) + [""]) do |r, e|
+ assert_equal([], r)
+ assert_not_equal([], e)
+ end
+ end
+
+ def test_encoding
+ assert_in_out_err(%w(-Eutf-8), "p '\u3042'", [], /invalid multibyte char/)
+
+ assert_in_out_err(%w(--encoding), "", [], /missing argument for --encoding/)
+
+ assert_in_out_err(%w(--encoding test_ruby_test_rubyoptions_foobarbazqux), "", [],
+ /unknown encoding name - test_ruby_test_rubyoptions_foobarbazqux \(RuntimeError\)/)
+
+ assert_in_out_err(%w(--encoding utf-8), "p '\u3042'", [], /invalid multibyte char/)
+ end
+
+ def test_syntax_check
+ assert_in_out_err(%w(-c -e a=1+1), "", ["Syntax OK"], [])
+ end
+
+ def test_invalid_option
+ assert_in_out_err(%w(--foobarbazqux), "", [], /invalid option --foobarbazqux/)
+
+ assert_in_out_err(%W(-\r -e) + [""], "", [], [])
+
+ assert_in_out_err(%W(-\rx), "", [], /invalid option -\\x0D \(-h will show valid options\) \(RuntimeError\)/)
+
+ assert_in_out_err(%W(-\x01), "", [], /invalid option -\\x01 \(-h will show valid options\) \(RuntimeError\)/)
+
+ assert_in_out_err(%w(-Z), "", [], /invalid option -Z \(-h will show valid options\) \(RuntimeError\)/)
+ end
+
+ def test_rubyopt
+ rubyopt_orig = ENV['RUBYOPT']
+
+ ENV['RUBYOPT'] = ' - -'
+ assert_in_out_err([], "", [], [])
+
+ ENV['RUBYOPT'] = '-e "p 1"'
+ assert_in_out_err([], "", [], /invalid switch in RUBYOPT: -e \(RuntimeError\)/)
+
+ ENV['RUBYOPT'] = '-T1'
+ assert_in_out_err([], "", [], /no program input from stdin allowed in tainted mode \(SecurityError\)/)
+
+ ENV['RUBYOPT'] = '-T4'
+ assert_in_out_err([], "", [], /no program input from stdin allowed in tainted mode \(SecurityError\)/)
+
+ ENV['RUBYOPT'] = '-Eus-ascii -KN'
+ assert_in_out_err(%w(-Eutf-8 -KU), "p '\u3042'") do |r, e|
+ assert_equal("\"\u3042\"", r.join.force_encoding(Encoding::UTF_8))
+ assert_equal([], e)
+ end
+
+ ensure
+ if rubyopt_orig
+ ENV['RUBYOPT'] = rubyopt_orig
+ else
+ ENV.delete('RUBYOPT')
+ end
+ end
+
+ def test_search
+ rubypath_orig = ENV['RUBYPATH']
+ path_orig = ENV['PATH']
+
+ t = Tempfile.new(["test_ruby_test_rubyoption", ".rb"])
+ t.puts "p 1"
+ t.close
+
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+
+ ENV['PATH'] = File.dirname(t.path)
+
+ assert_in_out_err(%w(-S) + [File.basename(t.path)], "", %w(1), [])
+
+ ENV['RUBYPATH'] = File.dirname(t.path)
+
+ assert_in_out_err(%w(-S) + [File.basename(t.path)], "", %w(1), [])
+
+ ensure
+ if rubypath_orig
+ ENV['RUBYPATH'] = rubypath_orig
+ else
+ ENV.delete('RUBYPATH')
+ end
+ if path_orig
+ ENV['PATH'] = path_orig
+ else
+ ENV.delete('PATH')
+ end
+ t.close(true) if t
+ $VERBOSE = @verbose
+ end
+
+ def test_shebang
+ assert_in_out_err([], "#! /test_r_u_b_y_test_r_u_b_y_options_foobarbazqux\r\np 1\r\n",
+ [], /: no Ruby script found in input/)
+
+ assert_in_out_err([], "#! /test_r_u_b_y_test_r_u_b_y_options_foobarbazqux -foo -bar\r\np 1\r\n",
+ [], /: no Ruby script found in input/)
+
+ assert_in_out_err([], "#!ruby -KU -Eutf-8\r\np \"\u3042\"\r\n") do |r, e|
+ assert_equal("\"\u3042\"", r.join.force_encoding(Encoding::UTF_8))
+ assert_equal([], e)
+ end
+ end
+
+ def test_sflag
+ assert_in_out_err(%w(- -abc -def=foo -ghi-jkl -- -xyz),
+ "#!ruby -s\np [$abc, $def, $ghi_jkl, defined?($xyz)]\n",
+ ['[true, "foo", true, nil]'], [])
+
+ assert_in_out_err(%w(- -#), "#!ruby -s\n", [],
+ /invalid name for global variable - -# \(NameError\)/)
+
+ assert_in_out_err(%w(- -#=foo), "#!ruby -s\n", [],
+ /invalid name for global variable - -# \(NameError\)/)
+ end
+
+ def test_assignment_in_conditional
+ t = Tempfile.new(["test_ruby_test_rubyoption", ".rb"])
+ t.puts "if a = 1"
+ t.puts "end"
+ t.puts "0.times do"
+ t.puts " if b = 2"
+ t.puts " end"
+ t.puts "end"
+ t.close
+ err = ["#{t.path}:1: warning: found = in conditional, should be ==",
+ "#{t.path}:4: warning: found = in conditional, should be =="]
+ err = /\A(#{Regexp.quote(t.path)}):1(: warning: found = in conditional, should be ==)\n\1:4\2\Z/
+ bug2136 = '[ruby-dev:39363]'
+ assert_in_out_err(["-w", t.path], "", [], err, bug2136)
+ assert_in_out_err(["-wr", t.path, "-e", ""], "", [], err, bug2136)
+ ensure
+ t.close(true) if t
+ end
+
+ def test_indentation_check
+ t = Tempfile.new(["test_ruby_test_rubyoption", ".rb"])
+ t.puts "begin"
+ t.puts " end"
+ t.close
+ err = ["#{t.path}:2: warning: mismatched indentations at 'end' with 'begin' at 1"]
+ assert_in_out_err(["-w", t.path], "", [], err)
+ assert_in_out_err(["-wr", t.path, "-e", ""], "", [], err)
+ ensure
+ t.close(true) if t
+ end
+
+ def test_notfound
+ notexist = "./notexist.rb"
+ rubybin = Regexp.quote(EnvUtil.rubybin)
+ pat = Regexp.quote(notexist)
+ bug1573 = '[ruby-core:23717]'
+ assert_equal(false, File.exist?(notexist))
+ assert_in_out_err(["-r", notexist, "-ep"], "", [], /.* -- #{pat} \(LoadError\)/, bug1573)
+ assert_in_out_err([notexist], "", [], /#{rubybin}:.* -- #{pat} \(LoadError\)/, bug1573)
+ end
+
+ def test_program_name
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ ruby = EnvUtil.rubybin
+ IO.popen([ruby, '-e', 'print $0']) {|f|
+ assert_equal('-e', f.read)
+ }
+ IO.popen([ruby, '-'], 'r+') {|f|
+ f << 'print $0'
+ f.close_write
+ assert_equal('-', f.read)
+ }
+ Dir.mktmpdir {|d|
+ n1 = File.join(d, 't1')
+ open(n1, 'w') {|f| f << 'print $0' }
+ IO.popen([ruby, n1]) {|f|
+ assert_equal(n1, f.read)
+ }
+ if File.respond_to? :symlink
+ n2 = File.join(d, 't2')
+ File.symlink(n1, n2)
+ IO.popen([ruby, n2]) {|f|
+ assert_equal(n2, f.read)
+ }
+ end
+ Dir.chdir(d) {
+ n3 = '-e'
+ open(n3, 'w') {|f| f << 'print $0' }
+ IO.popen([ruby, '--', n3]) {|f|
+ assert_equal(n3, f.read)
+ }
+ n4 = '-'
+ IO.popen([ruby, '--', n4], 'r+') {|f|
+ f << 'print $0'
+ f.close_write
+ assert_equal(n4, f.read)
+ }
+ }
+ }
+ end
+
+ def test_segv_test
+ opts = {}
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ additional = '[\s\w\.\']*'
+ else
+ opts[:rlimit_core] = 0
+ additional = ""
+ end
+ assert_in_out_err(["-e", "Process.kill :SEGV, $$"], "", [],
+ %r(\A
+ -e:(?:1:)?\s\[BUG\]\sSegmentation\sfault\n
+ #{ Regexp.quote(RUBY_DESCRIPTION) }\n\n
+ --\scontrol\sframe\s----------\n
+ (?:c:.*\n)*
+ ---------------------------\n
+ (?:
+ --\sRuby\slevel\sbacktrace\sinformation\s----------------------------------------\n
+ -e:1:in\s`<main>'\n
+ -e:1:in\s`kill'\n
+ )?
+ \n
+ (?:
+ --\sC\slevel\sbacktrace\sinformation\s-------------------------------------------\n
+ (?:(?:.*\s)?\[0x\h+\]\n)*\n
+ )?
+ \[NOTE\]\n
+ You\smay\shave\sencountered\sa\sbug\sin\sthe\sRuby\sinterpreter\sor\sextension\slibraries.\n
+ Bug\sreports\sare\swelcome.\n
+ For\sdetails:\shttp:\/\/www.ruby-lang.org/bugreport.html\n
+ \n
+ (?:#{additional})
+ \z
+ )x,
+ nil,
+ opts)
+ end
+
+ def test_DATA
+ t = Tempfile.new(["test_ruby_test_rubyoption", ".rb"])
+ t.puts "puts DATA.read.inspect"
+ t.puts "__END__"
+ t.puts "foo"
+ t.puts "bar"
+ t.puts "baz"
+ t.close
+ assert_in_out_err([t.path], "", %w("foo\\nbar\\nbaz\\n"), [])
+ ensure
+ t.close(true) if t
+ end
+
+ def test_script_from_stdin
+ begin
+ require 'pty'
+ require 'io/console'
+ rescue LoadError
+ return
+ end
+ require 'timeout'
+ result = nil
+ s, w = IO.pipe
+ PTY.spawn(EnvUtil.rubybin, out: w) do |r, m|
+ w.close
+ m.print("\C-d")
+ assert_nothing_raised('[ruby-dev:37798]') do
+ result = Timeout.timeout(3) {s.read}
+ end
+ end
+ s.close
+ assert_equal("", result, '[ruby-dev:37798]')
+ s, w = IO.pipe
+ PTY.spawn(EnvUtil.rubybin, out: w) do |r, m|
+ w.close
+ m.print("$stdin.read; p $stdin.gets\n\C-d")
+ m.print("abc\n\C-d")
+ m.print("zzz\n")
+ result = s.read
+ end
+ s.close
+ assert_equal("\"zzz\\n\"\n", result, '[ruby-core:30910]')
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_settracefunc.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_settracefunc.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_settracefunc.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,357 @@
+require 'test/unit'
+
+class TestSetTraceFunc < Test::Unit::TestCase
+ def setup
+ @original_compile_option = RubyVM::InstructionSequence.compile_option
+ RubyVM::InstructionSequence.compile_option = {
+ :trace_instruction => true,
+ :specialized_instruction => false
+ }
+ end
+
+ def teardown
+ set_trace_func(nil)
+ RubyVM::InstructionSequence.compile_option = @original_compile_option
+ end
+
+ def test_c_call
+ events = []
+ eval <<-EOF.gsub(/^.*?: /, "")
+ 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
+ 2: events << [event, lineno, mid, klass]
+ 3: })
+ 4: x = 1 + 1
+ 5: set_trace_func(nil)
+ EOF
+ assert_equal(["c-return", 3, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal(["line", 4, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 4, :+, Fixnum],
+ events.shift)
+ assert_equal(["c-return", 4, :+, Fixnum],
+ events.shift)
+ assert_equal(["line", 5, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 5, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal([], events)
+ end
+
+ def test_call
+ events = []
+ eval <<-EOF.gsub(/^.*?: /, "")
+ 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
+ 2: events << [event, lineno, mid, klass]
+ 3: })
+ 4: def add(x, y)
+ 5: x + y
+ 6: end
+ 7: x = add(1, 1)
+ 8: set_trace_func(nil)
+ EOF
+ assert_equal(["c-return", 3, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal(["line", 4, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 4, :method_added, Module],
+ events.shift)
+ assert_equal(["c-return", 4, :method_added, Module],
+ events.shift)
+ assert_equal(["line", 7, __method__, self.class],
+ events.shift)
+ assert_equal(["call", 4, :add, self.class],
+ events.shift)
+ assert_equal(["line", 5, :add, self.class],
+ events.shift)
+ assert_equal(["c-call", 5, :+, Fixnum],
+ events.shift)
+ assert_equal(["c-return", 5, :+, Fixnum],
+ events.shift)
+ assert_equal(["return", 6, :add, self.class],
+ events.shift)
+ assert_equal(["line", 8, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 8, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal([], events)
+ end
+
+ def test_class
+ events = []
+ eval <<-EOF.gsub(/^.*?: /, "")
+ 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
+ 2: events << [event, lineno, mid, klass]
+ 3: })
+ 4: class Foo
+ 5: def bar
+ 6: end
+ 7: end
+ 8: x = Foo.new.bar
+ 9: set_trace_func(nil)
+ EOF
+ assert_equal(["c-return", 3, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal(["line", 4, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 4, :inherited, Class],
+ events.shift)
+ assert_equal(["c-return", 4, :inherited, Class],
+ events.shift)
+ assert_equal(["class", 4, nil, nil],
+ events.shift)
+ assert_equal(["line", 5, nil, nil],
+ events.shift)
+ assert_equal(["c-call", 5, :method_added, Module],
+ events.shift)
+ assert_equal(["c-return", 5, :method_added, Module],
+ events.shift)
+ assert_equal(["end", 7, nil, nil],
+ events.shift)
+ assert_equal(["line", 8, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 8, :new, Class],
+ events.shift)
+ assert_equal(["c-call", 8, :initialize, BasicObject],
+ events.shift)
+ assert_equal(["c-return", 8, :initialize, BasicObject],
+ events.shift)
+ assert_equal(["c-return", 8, :new, Class],
+ events.shift)
+ assert_equal(["call", 5, :bar, Foo],
+ events.shift)
+ assert_equal(["return", 6, :bar, Foo],
+ events.shift)
+ assert_equal(["line", 9, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 9, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal([], events)
+ end
+
+ def test_return # [ruby-dev:38701]
+ events = []
+ eval <<-EOF.gsub(/^.*?: /, "")
+ 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
+ 2: events << [event, lineno, mid, klass]
+ 3: })
+ 4: def foo(a)
+ 5: return if a
+ 6: return
+ 7: end
+ 8: foo(true)
+ 9: foo(false)
+ 10: set_trace_func(nil)
+ EOF
+ assert_equal(["c-return", 3, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal(["line", 4, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 4, :method_added, Module],
+ events.shift)
+ assert_equal(["c-return", 4, :method_added, Module],
+ events.shift)
+ assert_equal(["line", 8, __method__, self.class],
+ events.shift)
+ assert_equal(["call", 4, :foo, self.class],
+ events.shift)
+ assert_equal(["line", 5, :foo, self.class],
+ events.shift)
+ assert_equal(["return", 5, :foo, self.class],
+ events.shift)
+ assert_equal(["line", 9, :test_return, self.class],
+ events.shift)
+ assert_equal(["call", 4, :foo, self.class],
+ events.shift)
+ assert_equal(["line", 5, :foo, self.class],
+ events.shift)
+ assert_equal(["return", 7, :foo, self.class],
+ events.shift)
+ assert_equal(["line", 10, :test_return, self.class],
+ events.shift)
+ assert_equal(["c-call", 10, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal([], events)
+ end
+
+ def test_return2 # [ruby-core:24463]
+ events = []
+ eval <<-EOF.gsub(/^.*?: /, "")
+ 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
+ 2: events << [event, lineno, mid, klass]
+ 3: })
+ 4: def foo
+ 5: a = 5
+ 6: return a
+ 7: end
+ 8: foo
+ 9: set_trace_func(nil)
+ EOF
+ assert_equal(["c-return", 3, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal(["line", 4, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 4, :method_added, Module],
+ events.shift)
+ assert_equal(["c-return", 4, :method_added, Module],
+ events.shift)
+ assert_equal(["line", 8, __method__, self.class],
+ events.shift)
+ assert_equal(["call", 4, :foo, self.class],
+ events.shift)
+ assert_equal(["line", 5, :foo, self.class],
+ events.shift)
+ assert_equal(["line", 6, :foo, self.class],
+ events.shift)
+ assert_equal(["return", 7, :foo, self.class],
+ events.shift)
+ assert_equal(["line", 9, :test_return2, self.class],
+ events.shift)
+ assert_equal(["c-call", 9, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal([], events)
+ end
+
+ def test_raise
+ events = []
+ eval <<-EOF.gsub(/^.*?: /, "")
+ 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
+ 2: events << [event, lineno, mid, klass]
+ 3: })
+ 4: begin
+ 5: raise TypeError, "error"
+ 6: rescue TypeError
+ 7: end
+ 8: set_trace_func(nil)
+ EOF
+ assert_equal(["c-return", 3, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal(["line", 4, __method__, self.class],
+ events.shift)
+ assert_equal(["line", 5, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 5, :raise, Kernel],
+ events.shift)
+ assert_equal(["c-call", 5, :exception, Exception],
+ events.shift)
+ assert_equal(["c-call", 5, :initialize, Exception],
+ events.shift)
+ assert_equal(["c-return", 5, :initialize, Exception],
+ events.shift)
+ assert_equal(["c-return", 5, :exception, Exception],
+ events.shift)
+ assert_equal(["c-call", 5, :backtrace, Exception],
+ events.shift)
+ assert_equal(["c-return", 5, :backtrace, Exception],
+ events.shift)
+ assert_equal(["c-call", 5, :set_backtrace, Exception],
+ events.shift)
+ assert_equal(["c-return", 5, :set_backtrace, Exception],
+ events.shift)
+ assert_equal(["raise", 5, :test_raise, TestSetTraceFunc],
+ events.shift)
+ assert_equal(["c-return", 5, :raise, Kernel],
+ events.shift)
+ assert_equal(["c-call", 6, :===, Module],
+ events.shift)
+ assert_equal(["c-return", 6, :===, Module],
+ events.shift)
+ assert_equal(["line", 8, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 8, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal([], events)
+ end
+
+ def test_break # [ruby-core:27606] [Bug #2610]
+ events = []
+ eval <<-EOF.gsub(/^.*?: /, "")
+ 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
+ 2: events << [event, lineno, mid, klass]
+ 3: })
+ 4: [1,2,3].any? {|n| n}
+ 8: set_trace_func(nil)
+ EOF
+
+ [["c-return", 3, :set_trace_func, Kernel],
+ ["line", 4, __method__, self.class],
+ ["c-call", 4, :any?, Enumerable],
+ ["c-call", 4, :each, Array],
+ ["line", 4, __method__, self.class],
+ ["c-return", 4, :each, Array],
+ ["c-return", 4, :any?, Enumerable],
+ ["line", 5, __method__, self.class],
+ ["c-call", 5, :set_trace_func, Kernel]].each{|e|
+ assert_equal(e, events.shift)
+ }
+ end
+
+ def test_invalid_proc
+ assert_raise(TypeError) { set_trace_func(1) }
+ end
+
+ def test_raise_in_trace
+ set_trace_func proc {raise rescue nil}
+ assert_equal(42, (raise rescue 42), '[ruby-core:24118]')
+ end
+
+ def test_thread_trace
+ events = {:set => [], :add => []}
+ prc = Proc.new { |event, file, lineno, mid, binding, klass|
+ events[:set] << [event, lineno, mid, klass, :set]
+ }
+ prc2 = Proc.new { |event, file, lineno, mid, binding, klass|
+ events[:add] << [event, lineno, mid, klass, :add]
+ }
+
+ th = Thread.new do
+ th = Thread.current
+ eval <<-EOF.gsub(/^.*?: /, "")
+ 1: th.set_trace_func(prc)
+ 2: th.add_trace_func(prc2)
+ 3: class ThreadTraceInnerClass
+ 4: def foo
+ 5: x = 1 + 1
+ 6: end
+ 7: end
+ 8: ThreadTraceInnerClass.new.foo
+ 9: th.set_trace_func(nil)
+ EOF
+ end
+ th.join
+
+ [["c-return", 1, :set_trace_func, Thread, :set],
+ ["line", 2, __method__, self.class, :set],
+ ["c-call", 2, :add_trace_func, Thread, :set]].each do |e|
+ assert_equal(e, events[:set].shift)
+ end
+
+ [["c-return", 2, :add_trace_func, Thread],
+ ["line", 3, __method__, self.class],
+ ["c-call", 3, :inherited, Class],
+ ["c-return", 3, :inherited, Class],
+ ["class", 3, nil, nil],
+ ["line", 4, nil, nil],
+ ["c-call", 4, :method_added, Module],
+ ["c-return", 4, :method_added, Module],
+ ["end", 7, nil, nil],
+ ["line", 8, __method__, self.class],
+ ["c-call", 8, :new, Class],
+ ["c-call", 8, :initialize, BasicObject],
+ ["c-return", 8, :initialize, BasicObject],
+ ["c-return", 8, :new, Class],
+ ["call", 4, :foo, ThreadTraceInnerClass],
+ ["line", 5, :foo, ThreadTraceInnerClass],
+ ["c-call", 5, :+, Fixnum],
+ ["c-return", 5, :+, Fixnum],
+ ["return", 6, :foo, ThreadTraceInnerClass],
+ ["line", 9, __method__, self.class],
+ ["c-call", 9, :set_trace_func, Thread]].each do |e|
+ [:set, :add].each do |type|
+ assert_equal(e + [type], events[type].shift)
+ end
+ end
+ assert_equal([], events[:set])
+ assert_equal([], events[:add])
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_signal.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_signal.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_signal.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,184 @@
+require 'test/unit'
+require 'timeout'
+
+class TestSignal < Test::Unit::TestCase
+ def have_fork?
+ begin
+ Process.fork {}
+ return true
+ rescue NotImplementedError
+ return false
+ end
+ end
+
+ def test_signal
+ skip("[BUG : #861] Abort")
+
+ return unless Process.respond_to?(:kill)
+ begin
+ x = 0
+ oldtrap = Signal.trap(:INT) {|sig| x = 2 }
+ Process.kill :INT, Process.pid
+ 10.times do
+ break if 2 == x
+ sleep 0.1
+ end
+ assert_equal 2, x
+
+ Signal.trap(:INT) { raise "Interrupt" }
+ ex = assert_raise(RuntimeError) {
+ Process.kill :INT, Process.pid
+ sleep 0.1
+ }
+ assert_kind_of Exception, ex
+ assert_match(/Interrupt/, ex.message)
+ ensure
+ Signal.trap :INT, oldtrap if oldtrap
+ end
+ end
+
+ def test_exit_action
+ return unless have_fork? # skip this test
+ begin
+ r, w = IO.pipe
+ r0, w0 = IO.pipe
+ pid = Process.fork {
+ Signal.trap(:USR1, "EXIT")
+ w0.close
+ w.syswrite("a")
+ Thread.start { sleep(2) }
+ r0.sysread(4096)
+ }
+ r.sysread(1)
+ sleep 0.1
+ assert_nothing_raised("[ruby-dev:26128]") {
+ Process.kill(:USR1, pid)
+ begin
+ Timeout.timeout(3) {
+ Process.waitpid pid
+ }
+ rescue Timeout::Error
+ Process.kill(:TERM, pid)
+ raise
+ end
+ }
+ ensure
+ r.close
+ w.close
+ r0.close
+ w0.close
+ end
+ end
+
+ def test_invalid_signal_name
+ return unless Process.respond_to?(:kill)
+
+ assert_raise(ArgumentError) { Process.kill(:XXXXXXXXXX, $$) }
+ end
+
+ def test_signal_exception
+ assert_raise(ArgumentError) { SignalException.new }
+ assert_raise(ArgumentError) { SignalException.new(-1) }
+ assert_raise(ArgumentError) { SignalException.new(:XXXXXXXXXX) }
+ Signal.list.each do |signm, signo|
+ next if signm == "EXIT"
+ assert_equal(SignalException.new(signm).signo, signo)
+ assert_equal(SignalException.new(signm.to_sym).signo, signo)
+ assert_equal(SignalException.new(signo).signo, signo)
+ end
+ end
+
+ def test_interrupt
+ assert_raise(Interrupt) { raise Interrupt.new }
+ end
+
+ def test_signal2
+ return unless Process.respond_to?(:kill)
+ begin
+ x = false
+ oldtrap = Signal.trap(:INT) {|sig| x = true }
+ GC.start
+
+ assert_raise(ArgumentError) { Process.kill }
+
+ Timeout.timeout(10) do
+ x = false
+ Process.kill(SignalException.new(:INT).signo, $$)
+ nil until x
+
+ x = false
+ Process.kill("INT", $$)
+ nil until x
+
+ x = false
+ Process.kill("SIGINT", $$)
+ nil until x
+
+ x = false
+ o = Object.new
+ def o.to_str; "SIGINT"; end
+ Process.kill(o, $$)
+ nil until x
+ end
+
+ assert_raise(ArgumentError) { Process.kill(Object.new, $$) }
+
+ ensure
+ Signal.trap(:INT, oldtrap) if oldtrap
+ end
+ end
+
+ def test_trap
+ return unless Process.respond_to?(:kill)
+ begin
+ oldtrap = Signal.trap(:INT) {|sig| }
+
+ assert_raise(ArgumentError) { Signal.trap }
+
+ assert_raise(SecurityError) do
+ s = proc {}.taint
+ Signal.trap(:INT, s)
+ end
+
+ # FIXME!
+ Signal.trap(:INT, nil)
+ Signal.trap(:INT, "")
+ Signal.trap(:INT, "SIG_IGN")
+ Signal.trap(:INT, "IGNORE")
+
+ Signal.trap(:INT, "SIG_DFL")
+ Signal.trap(:INT, "SYSTEM_DEFAULT")
+
+ Signal.trap(:INT, "EXIT")
+
+ Signal.trap(:INT, "xxxxxx")
+ Signal.trap(:INT, "xxxx")
+
+ Signal.trap(SignalException.new(:INT).signo, "SIG_DFL")
+
+ assert_raise(ArgumentError) { Signal.trap(-1, "xxxx") }
+
+ o = Object.new
+ def o.to_str; "SIGINT"; end
+ Signal.trap(o, "SIG_DFL")
+
+ assert_raise(ArgumentError) { Signal.trap("XXXXXXXXXX", "SIG_DFL") }
+
+ ensure
+ Signal.trap(:INT, oldtrap) if oldtrap
+ end
+ end
+
+ def test_kill_immediately_before_termination
+ return unless have_fork? # skip this test
+
+ r, w = IO.pipe
+ pid = Process.fork do
+ r.close
+ Signal.trap(:USR1) { w.syswrite("foo") }
+ Process.kill :USR1, $$
+ end
+ w.close
+ assert_equal(r.read, "foo")
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_sleep.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_sleep.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_sleep.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,13 @@
+require 'test/unit'
+
+class TestSleep < Test::Unit::TestCase
+ def test_sleep_5sec
+ GC.disable
+ start = Time.now
+ sleep 5
+ slept = Time.now-start
+ assert_in_delta(5.0, slept, 0.1, "[ruby-core:18015]: longer than expected")
+ ensure
+ GC.enable
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_sprintf.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_sprintf.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_sprintf.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,301 @@
+require 'test/unit'
+
+class TestSprintf < Test::Unit::TestCase
+ def test_positional
+ assert_equal(" 00001", sprintf("%*1$.*2$3$d", 10, 5, 1))
+ end
+
+ def test_binary
+ assert_equal("0", sprintf("%b", 0))
+ assert_equal("1", sprintf("%b", 1))
+ assert_equal("10", sprintf("%b", 2))
+ assert_equal("..1", sprintf("%b", -1))
+
+ assert_equal(" 0", sprintf("%4b", 0))
+ assert_equal(" 1", sprintf("%4b", 1))
+ assert_equal(" 10", sprintf("%4b", 2))
+ assert_equal(" ..1", sprintf("%4b", -1))
+
+ assert_equal("0000", sprintf("%04b", 0))
+ assert_equal("0001", sprintf("%04b", 1))
+ assert_equal("0010", sprintf("%04b", 2))
+ assert_equal("..11", sprintf("%04b", -1))
+
+ assert_equal("0000", sprintf("%.4b", 0))
+ assert_equal("0001", sprintf("%.4b", 1))
+ assert_equal("0010", sprintf("%.4b", 2))
+ assert_equal("..11", sprintf("%.4b", -1))
+
+ assert_equal(" 0000", sprintf("%6.4b", 0))
+ assert_equal(" 0001", sprintf("%6.4b", 1))
+ assert_equal(" 0010", sprintf("%6.4b", 2))
+ assert_equal(" ..11", sprintf("%6.4b", -1))
+
+ assert_equal(" 0", sprintf("%#4b", 0))
+ assert_equal(" 0b1", sprintf("%#4b", 1))
+ assert_equal("0b10", sprintf("%#4b", 2))
+ assert_equal("0b..1", sprintf("%#4b", -1))
+
+ assert_equal("0000", sprintf("%#04b", 0))
+ assert_equal("0b01", sprintf("%#04b", 1))
+ assert_equal("0b10", sprintf("%#04b", 2))
+ assert_equal("0b..1", sprintf("%#04b", -1))
+
+ assert_equal("0000", sprintf("%#.4b", 0))
+ assert_equal("0b0001", sprintf("%#.4b", 1))
+ assert_equal("0b0010", sprintf("%#.4b", 2))
+ assert_equal("0b..11", sprintf("%#.4b", -1))
+
+ assert_equal(" 0000", sprintf("%#6.4b", 0))
+ assert_equal("0b0001", sprintf("%#6.4b", 1))
+ assert_equal("0b0010", sprintf("%#6.4b", 2))
+ assert_equal("0b..11", sprintf("%#6.4b", -1))
+
+ assert_equal("+0", sprintf("%+b", 0))
+ assert_equal("+1", sprintf("%+b", 1))
+ assert_equal("+10", sprintf("%+b", 2))
+ assert_equal("-1", sprintf("%+b", -1))
+
+ assert_equal(" +0", sprintf("%+4b", 0))
+ assert_equal(" +1", sprintf("%+4b", 1))
+ assert_equal(" +10", sprintf("%+4b", 2))
+ assert_equal(" -1", sprintf("%+4b", -1))
+
+ assert_equal("+000", sprintf("%+04b", 0))
+ assert_equal("+001", sprintf("%+04b", 1))
+ assert_equal("+010", sprintf("%+04b", 2))
+ assert_equal("-001", sprintf("%+04b", -1))
+
+ assert_equal("+0000", sprintf("%+.4b", 0))
+ assert_equal("+0001", sprintf("%+.4b", 1))
+ assert_equal("+0010", sprintf("%+.4b", 2))
+ assert_equal("-0001", sprintf("%+.4b", -1))
+
+ assert_equal(" +0000", sprintf("%+6.4b", 0))
+ assert_equal(" +0001", sprintf("%+6.4b", 1))
+ assert_equal(" +0010", sprintf("%+6.4b", 2))
+ assert_equal(" -0001", sprintf("%+6.4b", -1))
+ end
+
+ def test_nan
+ nan = 0.0 / 0.0
+ assert_equal("NaN", sprintf("%f", nan))
+ assert_equal("NaN", sprintf("%-f", nan))
+ assert_equal("+NaN", sprintf("%+f", nan))
+
+ assert_equal(" NaN", sprintf("%8f", nan))
+ assert_equal("NaN ", sprintf("%-8f", nan))
+ assert_equal(" +NaN", sprintf("%+8f", nan))
+
+ assert_equal(" NaN", sprintf("%08f", nan))
+ assert_equal("NaN ", sprintf("%-08f", nan))
+ assert_equal(" +NaN", sprintf("%+08f", nan))
+
+ assert_equal(" NaN", sprintf("% 8f", nan))
+ assert_equal(" NaN ", sprintf("%- 8f", nan))
+ assert_equal(" +NaN", sprintf("%+ 8f", nan))
+
+ assert_equal(" NaN", sprintf("% 08f", nan))
+ assert_equal(" NaN ", sprintf("%- 08f", nan))
+ assert_equal(" +NaN", sprintf("%+ 08f", nan))
+ end
+
+ def test_inf
+ inf = 1.0 / 0.0
+ assert_equal("Inf", sprintf("%f", inf))
+ assert_equal("Inf", sprintf("%-f", inf))
+ assert_equal("+Inf", sprintf("%+f", inf))
+
+ assert_equal(" Inf", sprintf("%8f", inf))
+ assert_equal("Inf ", sprintf("%-8f", inf))
+ assert_equal(" +Inf", sprintf("%+8f", inf))
+
+ assert_equal(" Inf", sprintf("%08f", inf))
+ assert_equal("Inf ", sprintf("%-08f", inf))
+ assert_equal(" +Inf", sprintf("%+08f", inf))
+
+ assert_equal(" Inf", sprintf("% 8f", inf))
+ assert_equal(" Inf ", sprintf("%- 8f", inf))
+ assert_equal(" +Inf", sprintf("%+ 8f", inf))
+
+ assert_equal(" Inf", sprintf("% 08f", inf))
+ assert_equal(" Inf ", sprintf("%- 08f", inf))
+ assert_equal(" +Inf", sprintf("%+ 08f", inf))
+
+ assert_equal("-Inf", sprintf("%f", -inf))
+ assert_equal("-Inf", sprintf("%-f", -inf))
+ assert_equal("-Inf", sprintf("%+f", -inf))
+
+ assert_equal(" -Inf", sprintf("%8f", -inf))
+ assert_equal("-Inf ", sprintf("%-8f", -inf))
+ assert_equal(" -Inf", sprintf("%+8f", -inf))
+
+ assert_equal(" -Inf", sprintf("%08f", -inf))
+ assert_equal("-Inf ", sprintf("%-08f", -inf))
+ assert_equal(" -Inf", sprintf("%+08f", -inf))
+
+ assert_equal(" -Inf", sprintf("% 8f", -inf))
+ assert_equal("-Inf ", sprintf("%- 8f", -inf))
+ assert_equal(" -Inf", sprintf("%+ 8f", -inf))
+
+ assert_equal(" -Inf", sprintf("% 08f", -inf))
+ assert_equal("-Inf ", sprintf("%- 08f", -inf))
+ assert_equal(" -Inf", sprintf("%+ 08f", -inf))
+ assert_equal('..f00000000',
+ sprintf("%x", -2**32), '[ruby-dev:32351]')
+ assert_equal("..101111111111111111111111111111111",
+ sprintf("%b", -2147483649), '[ruby-dev:32365]')
+ assert_equal(" Inf", sprintf("% e", inf), '[ruby-dev:34002]')
+ end
+
+ def test_invalid
+ # Star precision before star width:
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%.**d", 5, 10, 1)}
+
+ # Precision before flags and width:
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%.5+05d", 5)}
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%.5 5d", 5)}
+
+ # Overriding a star width with a numeric one:
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%*1s", 5, 1)}
+
+ # Width before flags:
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%5+0d", 1)}
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%5 0d", 1)}
+
+ # Specifying width multiple times:
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%50+30+20+10+5d", 5)}
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%50 30 20 10 5d", 5)}
+
+ # Specifying the precision multiple times with negative star arguments:
+ assert_raise(ArgumentError, "[ruby-core:11570]") {sprintf("%.*.*.*.*f", -1, -1, -1, 5, 1)}
+
+ # Null bytes after percent signs are removed:
+ assert_equal("%\0x hello", sprintf("%\0x hello"), "[ruby-core:11571]")
+
+ assert_raise(ArgumentError, "[ruby-core:11573]") {sprintf("%.25555555555555555555555555555555555555s", "hello")}
+
+ assert_raise(ArgumentError) { sprintf("%\1", 1) }
+ assert_raise(ArgumentError) { sprintf("%!", 1) }
+ assert_raise(ArgumentError) { sprintf("%1$1$d", 1) }
+ assert_raise(ArgumentError) { sprintf("%0%") }
+ verbose, $VERBOSE = $VERBOSE, nil
+ assert_nothing_raised { sprintf("", 1) }
+ ensure
+ $VERBOSE = verbose
+ end
+
+ def test_float
+ assert_equal("36893488147419111424",
+ sprintf("%20.0f", 36893488147419107329.0))
+ assert_equal(" Inf", sprintf("% 0e", 1.0/0.0), "moved from btest/knownbug")
+ end
+
+ def test_float_hex
+ assert_equal("-0x0p+0", sprintf("%a", -0.0))
+ assert_equal("0x0p+0", sprintf("%a", 0.0))
+ assert_equal("0x1p-1", sprintf("%a", 0.5))
+ assert_equal("0x1p+0", sprintf("%a", 1.0))
+ assert_equal("0x1p+1", sprintf("%a", 2.0))
+ assert_equal("0x1p+10", sprintf("%a", 1024))
+ assert_equal("0x1.23456p+789", sprintf("%a", 3.704450999893983e+237))
+ assert_equal("0x1p-1074", sprintf("%a", 4.9e-324))
+ assert_equal("Inf", sprintf("%e", Float::INFINITY))
+ assert_equal("Inf", sprintf("%E", Float::INFINITY))
+ assert_equal("NaN", sprintf("%e", Float::NAN))
+ assert_equal("NaN", sprintf("%E", Float::NAN))
+ end
+
+ BSIZ = 120
+
+ def test_skip
+ assert_equal(" " * BSIZ + "1", sprintf(" " * BSIZ + "%d", 1))
+ end
+
+ def test_char
+ assert_equal("a", sprintf("%c", 97))
+ assert_equal("a", sprintf("%c", ?a))
+ assert_raise(ArgumentError) { sprintf("%c", sprintf("%c%c", ?a, ?a)) }
+ assert_equal(" " * (BSIZ - 1) + "a", sprintf(" " * (BSIZ - 1) + "%c", ?a))
+ assert_equal(" " * (BSIZ - 1) + "a", sprintf(" " * (BSIZ - 1) + "%-1c", ?a))
+ assert_equal(" " * BSIZ + "a", sprintf("%#{ BSIZ + 1 }c", ?a))
+ assert_equal("a" + " " * BSIZ, sprintf("%-#{ BSIZ + 1 }c", ?a))
+ end
+
+ def test_string
+ assert_equal("foo", sprintf("%s", "foo"))
+ assert_equal("fo", sprintf("%.2s", "foo"))
+ assert_equal(" " * BSIZ, sprintf("%s", " " * BSIZ))
+ assert_equal(" " * (BSIZ - 1) + "foo", sprintf("%#{ BSIZ - 1 + 3 }s", "foo"))
+ assert_equal(" " * BSIZ + "foo", sprintf("%#{ BSIZ + 3 }s", "foo"))
+ assert_equal("foo" + " " * BSIZ, sprintf("%-#{ BSIZ + 3 }s", "foo"))
+ end
+
+ def test_integer
+ assert_equal("01", sprintf("%#o", 1))
+ assert_equal("0x1", sprintf("%#x", 1))
+ assert_equal("0X1", sprintf("%#X", 1))
+ assert_equal("0b1", sprintf("%#b", 1))
+ assert_equal("0B1", sprintf("%#B", 1))
+ assert_equal("1", sprintf("%d", 1.0))
+ assert_equal("4294967296", sprintf("%d", (2**32).to_f))
+ assert_equal("-2147483648", sprintf("%d", -(2**31).to_f))
+ assert_equal("18446744073709551616", sprintf("%d", (2**64).to_f))
+ assert_equal("-9223372036854775808", sprintf("%d", -(2**63).to_f))
+ assert_equal("1", sprintf("%d", "1"))
+ o = Object.new; def o.to_int; 1; end
+ assert_equal("1", sprintf("%d", o))
+ assert_equal("+1", sprintf("%+d", 1))
+ assert_equal(" 1", sprintf("% d", 1))
+ assert_equal("..f", sprintf("%x", -1))
+ assert_equal("..7", sprintf("%o", -1))
+ one = (2**32).coerce(1).first
+ mone = (2**32).coerce(-1).first
+ assert_equal("+1", sprintf("%+d", one))
+ assert_equal(" 1", sprintf("% d", one))
+ assert_equal("..f", sprintf("%x", mone))
+ assert_equal("..7", sprintf("%o", mone))
+ assert_equal(" " * BSIZ + "1", sprintf("%#{ BSIZ + 1 }d", one))
+ assert_equal(" " * (BSIZ - 1) + "1", sprintf(" " * (BSIZ - 1) + "%d", 1))
+ end
+
+ def test_float2
+ inf = 1.0 / 0.0
+ assert_equal(" " * BSIZ + "Inf", sprintf("%#{ BSIZ + 3 }.1f", inf))
+ assert_equal("+Inf", sprintf("%+-f", inf))
+ assert_equal(" " * BSIZ + "1.0", sprintf("%#{ BSIZ + 3 }.1f", 1.0))
+ end
+
+ class T012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+ end
+
+ def test_star
+ assert_equal("-1 ", sprintf("%*d", -3, -1))
+ end
+
+ def test_escape
+ assert_equal("%" * BSIZ, sprintf("%%" * BSIZ))
+ end
+
+ def test_rb_sprintf
+ assert_match(/^#<TestSprintf::T012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789:0x[0-9a-f]+>$/,
+ T012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.new.inspect)
+ end
+
+ def test_negative_hex
+ s1 = sprintf("%0x", -0x40000000)
+ s2 = sprintf("%0x", -0x40000001)
+ b1 = (/\.\./ =~ s1) != nil
+ b2 = (/\.\./ =~ s2) != nil
+ assert(b1 == b2, "[ruby-dev:33224]")
+ end
+
+ def test_named
+ assert_equal("value", sprintf("%<key>s", :key => "value"))
+ assert_raise(ArgumentError) {sprintf("%1$<key2>s", :key => "value")}
+ assert_raise(ArgumentError) {sprintf("%<key><key2>s", :key => "value")}
+ assert_equal("value", sprintf("%{key}", :key => "value"))
+ assert_raise(ArgumentError) {sprintf("%1${key2}", :key => "value")}
+ assert_equal("value{key2}", sprintf("%{key}{key2}", :key => "value"))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_sprintf_comb.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_sprintf_comb.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_sprintf_comb.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,553 @@
+require 'test/unit'
+require_relative 'allpairs'
+
+class TestSprintfComb < Test::Unit::TestCase
+ VS = [
+ #-0x1000000000000000000000000000000000000000000000002,
+ #-0x1000000000000000000000000000000000000000000000001,
+ #-0x1000000000000000000000000000000000000000000000000,
+ #-0xffffffffffffffffffffffffffffffffffffffffffffffff,
+ #-0x1000000000000000000000002,
+ #-0x1000000000000000000000001,
+ #-0x1000000000000000000000000,
+ #-0xffffffffffffffffffffffff,
+ -0x10000000000000002,
+ -0x10000000000000001,
+ -0x10000000000000000,
+ -0xffffffffffffffff,
+ -0x4000000000000002,
+ -0x4000000000000001,
+ -0x4000000000000000,
+ -0x3fffffffffffffff,
+ -0x100000002,
+ -0x100000001,
+ -0x100000000,
+ -0xffffffff,
+ #-0xc717a08d, # 0xc717a08d * 0x524b2245 = 0x4000000000000001
+ -0x80000002,
+ -0x80000001,
+ -0x80000000,
+ -0x7fffffff,
+ #-0x524b2245,
+ -0x40000002,
+ -0x40000001,
+ -0x40000000,
+ -0x3fffffff,
+ #-0x10002,
+ #-0x10001,
+ #-0x10000,
+ #-0xffff,
+ #-0x8101, # 0x8101 * 0x7f01 = 0x40000001
+ #-0x8002,
+ #-0x8001,
+ #-0x8000,
+ #-0x7fff,
+ #-0x7f01,
+ #-65,
+ #-64,
+ #-63,
+ #-62,
+ #-33,
+ #-32,
+ #-31,
+ #-30,
+ -3,
+ -2,
+ -1,
+ 0,
+ 1,
+ 2,
+ 3,
+ #30,
+ #31,
+ #32,
+ #33,
+ #62,
+ #63,
+ #64,
+ #65,
+ #0x7f01,
+ #0x7ffe,
+ #0x7fff,
+ #0x8000,
+ #0x8001,
+ #0x8101,
+ #0xfffe,
+ #0xffff,
+ #0x10000,
+ #0x10001,
+ 0x3ffffffe,
+ 0x3fffffff,
+ 0x40000000,
+ 0x40000001,
+ #0x524b2245,
+ 0x7ffffffe,
+ 0x7fffffff,
+ 0x80000000,
+ 0x80000001,
+ #0xc717a08d,
+ 0xfffffffe,
+ 0xffffffff,
+ 0x100000000,
+ 0x100000001,
+ 0x3ffffffffffffffe,
+ 0x3fffffffffffffff,
+ 0x4000000000000000,
+ 0x4000000000000001,
+ 0xfffffffffffffffe,
+ 0xffffffffffffffff,
+ 0x10000000000000000,
+ 0x10000000000000001,
+ #0xffffffffffffffffffffffff,
+ #0x1000000000000000000000000,
+ #0x1000000000000000000000001,
+ #0xffffffffffffffffffffffffffffffffffffffffffffffff,
+ #0x1000000000000000000000000000000000000000000000000,
+ #0x1000000000000000000000000000000000000000000000001
+ ]
+ VS.reverse!
+
+ def combination(*args, &b)
+ #AllPairs.exhaustive_each(*args, &b)
+ AllPairs.each(*args, &b)
+ end
+
+ def emu_int(format, v)
+ /\A%( )?(\#)?(\+)?(-)?(0)?(\d+)?(?:\.(\d*))?(.)\z/ =~ format
+ sp = $1
+ hs = $2
+ pl = $3
+ mi = $4
+ zr = $5
+ width = $6
+ precision = $7
+ type = $8
+ width = width.to_i if width
+ precision = precision.to_i if precision
+ prefix = ''
+
+ zr = nil if precision
+
+ zr = nil if mi && zr
+
+ case type
+ when 'B'
+ radix = 2
+ digitmap = {0 => '0', 1 => '1'}
+ complement = !pl && !sp
+ prefix = '0B' if hs && v != 0
+ when 'b'
+ radix = 2
+ digitmap = {0 => '0', 1 => '1'}
+ complement = !pl && !sp
+ prefix = '0b' if hs && v != 0
+ when 'd'
+ radix = 10
+ digitmap = {}
+ 10.times {|i| digitmap[i] = i.to_s }
+ complement = false
+ when 'o'
+ radix = 8
+ digitmap = {}
+ 8.times {|i| digitmap[i] = i.to_s }
+ complement = !pl && !sp
+ when 'X'
+ radix = 16
+ digitmap = {}
+ 16.times {|i| digitmap[i] = i.to_s(16).upcase }
+ complement = !pl && !sp
+ prefix = '0X' if hs && v != 0
+ when 'x'
+ radix = 16
+ digitmap = {}
+ 16.times {|i| digitmap[i] = i.to_s(16) }
+ complement = !pl && !sp
+ prefix = '0x' if hs && v != 0
+ else
+ raise "unexpected type: #{type.inspect}"
+ end
+
+ digits = []
+ abs = v.abs
+ sign = ''
+ while 0 < abs
+ digits << (abs % radix)
+ abs /= radix
+ end
+
+ if v < 0
+ if complement
+ digits.map! {|d| radix-1 - d }
+ carry = 1
+ digits.each_index {|i|
+ digits[i] += carry
+ carry = 0
+ if radix <= digits[i]
+ digits[i] -= radix
+ carry = 1
+ end
+ }
+ if digits.last != radix-1
+ digits << (radix-1)
+ end
+ sign = '..'
+ else
+ sign = '-'
+ end
+ else
+ if pl
+ sign = '+'
+ elsif sp
+ sign = ' '
+ end
+ end
+
+ dlen = digits.length
+ dlen += 2 if sign == '..'
+
+ if v < 0 && complement
+ d = radix - 1
+ else
+ d = 0
+ end
+ if precision
+ if dlen < precision
+ (precision - dlen).times {
+ digits << d
+ }
+ end
+ else
+ if dlen == 0
+ digits << d
+ end
+ end
+ if type == 'o' && hs
+ if digits.empty? || digits.last != d
+ digits << d
+ end
+ end
+
+ digits.reverse!
+
+ str = digits.map {|digit| digitmap[digit] }.join
+
+ pad = ''
+ nlen = prefix.length + sign.length + str.length
+ if width && nlen < width
+ len = width - nlen
+ if zr
+ if complement && v < 0
+ pad = digitmap[radix-1] * len
+ else
+ pad = '0' * len
+ end
+ else
+ pad = ' ' * len
+ end
+ end
+
+ if / / =~ pad
+ if sign == '..'
+ str = prefix + sign + str
+ else
+ str = sign + prefix + str
+ end
+ if mi
+ str = str + pad
+ else
+ str = pad + str
+ end
+ else
+ if sign == '..'
+ str = prefix + sign + pad + str
+ else
+ str = sign + prefix + pad + str
+ end
+ end
+
+ str
+ end
+
+ def test_format_integer
+ combination(
+ %w[B b d o X x],
+ [nil, 0, 5, 20],
+ ["", ".", ".0", ".8", ".20"],
+ ['', ' '],
+ ['', '#'],
+ ['', '+'],
+ ['', '-'],
+ ['', '0']) {|type, width, precision, sp, hs, pl, mi, zr|
+ format = "%#{sp}#{hs}#{pl}#{mi}#{zr}#{width}#{precision}#{type}"
+ VS.each {|v|
+ r = sprintf format, v
+ e = emu_int format, v
+ if true
+ assert_equal(e, r, "sprintf(#{format.dump}, #{v})")
+ else
+ if e != r
+ puts "#{e.dump}\t#{r.dump}\tsprintf(#{format.dump}, #{v})"
+ end
+ end
+ }
+ }
+ end
+
+ FLOAT_VALUES = [
+ -1e100,
+ -123456789.0,
+ -1.0,
+ -0.0,
+ 0.0,
+ 0.01,
+ 1/3.0,
+ 2/3.0,
+ 1.0,
+ 2.0,
+ 9.99999999,
+ 123456789.0,
+ 1e100,
+ Float::MAX,
+ Float::MIN,
+ Float::EPSILON,
+ 1+Float::EPSILON,
+ #1-Float::EPSILON/2,
+ 10 + Float::EPSILON*10,
+ 10 - Float::EPSILON*5,
+ 1.0/0.0,
+ -1.0/0.0,
+ 0.0/0.0,
+ ]
+
+ def split_float10(v)
+ if v == 0
+ if 1/v < 0
+ sign = -1
+ v = -v
+ else
+ sign = 1
+ end
+ else
+ if v < 0
+ sign = -1
+ v = -v
+ else
+ sign = 1
+ end
+ end
+ exp = 0
+ int = v.floor
+ v -= int
+ while v != 0
+ v *= 2
+ int *= 2
+ i = v.floor
+ v -= i
+ int += i
+ exp -= 1
+ end
+ int *= 5 ** (-exp)
+ [sign, int, exp]
+ end
+
+ def emu_e(sp, hs, pl, mi, zr, width, precision, type, v, sign, int, exp)
+ precision = 6 unless precision
+ if int == 0
+ if precision == 0 && !hs
+ result = "0#{type}+00"
+ else
+ result = "0." + "0" * precision + "#{type}+00"
+ end
+ else
+ if int < 10**precision
+ int *= 10**precision
+ exp -= precision
+ end
+ digits = int.to_s.length
+ discard = digits - (precision+1)
+ if discard != 0
+ q, r = int.divmod(10**discard)
+ if r < 10**discard / 2
+ int = q
+ exp += discard
+ elsif (q+1).to_s.length == q.to_s.length
+ int = q+1
+ exp += discard
+ else
+ discard += 1
+ q, r = int.divmod(10**discard)
+ int = q+1
+ exp += discard
+ end
+ end
+ ints = int.to_s
+ frac = ints[1..-1]
+ result = ints[0,1]
+ e = exp + frac.length
+ if precision != 0 || hs
+ result << "."
+ if precision != 0
+ result << frac
+ end
+ end
+ result << type
+ if e == 0
+ if v.abs < 1
+ result << '-00' # glibc 2.7 causes '+00'
+ else
+ result << '+00'
+ end
+ else
+ result << sprintf("%+03d", e)
+ end
+ result
+ end
+ result
+ end
+
+ def emu_f(sp, hs, pl, mi, zr, width, precision, type, sign, int, exp)
+ precision = 6 unless precision
+ if int == 0
+ if precision == 0 && !hs
+ result = '0'
+ else
+ result = '0.' + '0' * precision
+ end
+ else
+ if -precision < exp
+ int *= 10 ** (precision+exp)
+ exp = -precision
+ end
+ if exp < -precision
+ discard = -exp - precision
+ q, r = int.divmod(10**discard)
+ if 10**discard / 2 <= r
+ q += 1
+ end
+ int = q
+ exp += discard
+ end
+ result = int.to_s
+ if result.length <= precision
+ result = '0' * (precision+1 - result.length) + result
+ end
+ if precision != 0 || hs
+ if precision == 0
+ result << '.'
+ else
+ result[-precision,0] = '.'
+ end
+ end
+ end
+ result
+ end
+
+ def emu_float(format, v)
+ /\A%( )?(\#)?(\+)?(-)?(0)?(\d+)?(?:\.(\d*))?(.)\z/ =~ format
+ sp = $1
+ hs = $2
+ pl = $3
+ mi = $4
+ zr = $5
+ width = $6
+ precision = $7
+ type = $8
+ width = width.to_i if width
+ precision = precision.to_i if precision
+
+ zr = nil if mi && zr
+
+ if v.infinite?
+ sign = v < 0 ? -1 : 1
+ int = :inf
+ hs = zr = nil
+ elsif v.nan?
+ sign = 1
+ int = :nan
+ hs = zr = nil
+ else
+ sign, int, exp = split_float10(v)
+ end
+
+ if sign < 0
+ sign = '-'
+ elsif sign == 0
+ sign = ''
+ elsif pl
+ sign = '+'
+ elsif sp
+ sign = ' '
+ else
+ sign = ''
+ end
+
+ if v.nan?
+ result = 'NaN'
+ elsif v.infinite?
+ result = 'Inf'
+ else
+ case type
+ when /[eE]/
+ result = emu_e(sp, hs, pl, mi, zr, width, precision, type, v, sign, int, exp)
+ when /f/
+ result = emu_f(sp, hs, pl, mi, zr, width, precision, type, sign, int, exp)
+ when /[gG]/
+ precision = 6 unless precision
+ precision = 1 if precision == 0
+ r = emu_e(sp, hs, pl, mi, zr, width, precision-1, type.tr('gG', 'eE'), v, sign, int, exp)
+ /[eE]([+-]\d+)/ =~ r
+ e = $1.to_i
+ if e < -4 || precision <= e
+ result = r
+ else
+ result = emu_f(sp, hs, pl, mi, zr, width, precision-1-e, type, sign, int, exp)
+ end
+ result.sub!(/\.[0-9]*/) { $&.sub(/\.?0*\z/, '') } if !hs
+ else
+ raise "unexpected type: #{type}"
+ end
+ end
+
+ pad = ''
+ if width && sign.length + result.length < width
+ if zr
+ pad = '0' * (width - sign.length - result.length)
+ else
+ pad = ' ' * (width - sign.length - result.length)
+ end
+ end
+ if mi
+ sign + result + pad
+ elsif zr
+ sign + pad + result
+ else
+ pad + sign + result
+ end
+
+ end
+
+ def test_format_float
+ combination(
+ %w[e E f g G],
+ [nil, 0, 5, 20],
+ ["", ".", ".0", ".8", ".20", ".200"],
+ ['', ' '],
+ ['', '#'],
+ ['', '+'],
+ ['', '-'],
+ ['', '0']) {|type, width, precision, sp, hs, pl, mi, zr|
+ format = "%#{sp}#{hs}#{pl}#{mi}#{zr}#{width}#{precision}#{type}"
+ FLOAT_VALUES.each {|v|
+ r = sprintf format, v
+ e = emu_float format, v
+ if true
+ assert_equal(e, r, "sprintf(#{format.dump}, #{'%.20g' % v})")
+ else
+ if e != r
+ puts "#{e.dump}\t#{r.dump}\tsprintf(#{format.dump}, #{'%.20g' % v})"
+ end
+ end
+ }
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_string.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_string.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_string.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1893 @@
+require 'test/unit'
+require_relative 'envutil'
+
+# use of $= is deprecated after 1.7.1
+def pre_1_7_1
+end
+
+class TestString < Test::Unit::TestCase
+
+ def initialize(*args)
+ @cls = String
+ @aref_re_nth = true
+ @aref_re_silent = false
+ @aref_slicebang_silent = true
+ super
+ end
+
+ def S(str)
+ @cls.new(str)
+ end
+
+ def test_s_new
+ assert_equal("RUBY", S("RUBY"))
+ end
+
+ def test_AREF # '[]'
+ assert_equal("A", S("AooBar")[0])
+ assert_equal("B", S("FooBaB")[-1])
+ assert_equal(nil, S("FooBar")[6])
+ assert_equal(nil, S("FooBar")[-7])
+
+ assert_equal(S("Foo"), S("FooBar")[0,3])
+ assert_equal(S("Bar"), S("FooBar")[-3,3])
+ assert_equal(S(""), S("FooBar")[6,2])
+ assert_equal(nil, S("FooBar")[-7,10])
+
+ assert_equal(S("Foo"), S("FooBar")[0..2])
+ assert_equal(S("Foo"), S("FooBar")[0...3])
+ assert_equal(S("Bar"), S("FooBar")[-3..-1])
+ assert_equal(S(""), S("FooBar")[6..2])
+ assert_equal(nil, S("FooBar")[-10..-7])
+
+ assert_equal(S("Foo"), S("FooBar")[/^F../])
+ assert_equal(S("Bar"), S("FooBar")[/..r$/])
+ assert_equal(nil, S("FooBar")[/xyzzy/])
+ assert_equal(nil, S("FooBar")[/plugh/])
+
+ assert_equal(S("Foo"), S("FooBar")[S("Foo")])
+ assert_equal(S("Bar"), S("FooBar")[S("Bar")])
+ assert_equal(nil, S("FooBar")[S("xyzzy")])
+ assert_equal(nil, S("FooBar")[S("plugh")])
+
+ if @aref_re_nth
+ assert_equal(S("Foo"), S("FooBar")[/([A-Z]..)([A-Z]..)/, 1])
+ assert_equal(S("Bar"), S("FooBar")[/([A-Z]..)([A-Z]..)/, 2])
+ assert_equal(nil, S("FooBar")[/([A-Z]..)([A-Z]..)/, 3])
+ assert_equal(S("Bar"), S("FooBar")[/([A-Z]..)([A-Z]..)/, -1])
+ assert_equal(S("Foo"), S("FooBar")[/([A-Z]..)([A-Z]..)/, -2])
+ assert_equal(nil, S("FooBar")[/([A-Z]..)([A-Z]..)/, -3])
+ end
+
+ o = Object.new
+ def o.to_int; 2; end
+ assert_equal("o", "foo"[o])
+
+ assert_raise(ArgumentError) { "foo"[] }
+ end
+
+ def test_ASET # '[]='
+ s = S("FooBar")
+ s[0] = S('A')
+ assert_equal(S("AooBar"), s)
+
+ s[-1]= S('B')
+ assert_equal(S("AooBaB"), s)
+ assert_raise(IndexError) { s[-7] = S("xyz") }
+ assert_equal(S("AooBaB"), s)
+ s[0] = S("ABC")
+ assert_equal(S("ABCooBaB"), s)
+
+ s = S("FooBar")
+ s[0,3] = S("A")
+ assert_equal(S("ABar"),s)
+ s[0] = S("Foo")
+ assert_equal(S("FooBar"), s)
+ s[-3,3] = S("Foo")
+ assert_equal(S("FooFoo"), s)
+ assert_raise(IndexError) { s[7,3] = S("Bar") }
+ assert_raise(IndexError) { s[-7,3] = S("Bar") }
+
+ s = S("FooBar")
+ s[0..2] = S("A")
+ assert_equal(S("ABar"), s)
+ s[1..3] = S("Foo")
+ assert_equal(S("AFoo"), s)
+ s[-4..-4] = S("Foo")
+ assert_equal(S("FooFoo"), s)
+ assert_raise(RangeError) { s[7..10] = S("Bar") }
+ assert_raise(RangeError) { s[-7..-10] = S("Bar") }
+
+ s = S("FooBar")
+ s[/^F../]= S("Bar")
+ assert_equal(S("BarBar"), s)
+ s[/..r$/] = S("Foo")
+ assert_equal(S("BarFoo"), s)
+ if @aref_re_silent
+ s[/xyzzy/] = S("None")
+ assert_equal(S("BarFoo"), s)
+ else
+ assert_raise(IndexError) { s[/xyzzy/] = S("None") }
+ end
+ if @aref_re_nth
+ s[/([A-Z]..)([A-Z]..)/, 1] = S("Foo")
+ assert_equal(S("FooFoo"), s)
+ s[/([A-Z]..)([A-Z]..)/, 2] = S("Bar")
+ assert_equal(S("FooBar"), s)
+ assert_raise(IndexError) { s[/([A-Z]..)([A-Z]..)/, 3] = "None" }
+ s[/([A-Z]..)([A-Z]..)/, -1] = S("Foo")
+ assert_equal(S("FooFoo"), s)
+ s[/([A-Z]..)([A-Z]..)/, -2] = S("Bar")
+ assert_equal(S("BarFoo"), s)
+ assert_raise(IndexError) { s[/([A-Z]..)([A-Z]..)/, -3] = "None" }
+ end
+
+ s = S("FooBar")
+ s[S("Foo")] = S("Bar")
+ assert_equal(S("BarBar"), s)
+
+ pre_1_7_1 do
+ s = S("FooBar")
+ s[S("Foo")] = S("xyz")
+ assert_equal(S("xyzBar"), s)
+
+ $= = true
+ s = S("FooBar")
+ s[S("FOO")] = S("Bar")
+ assert_equal(S("BarBar"), s)
+ s[S("FOO")] = S("xyz")
+ assert_equal(S("BarBar"), s)
+ $= = false
+ end
+
+ s = S("a string")
+ s[0..s.size] = S("another string")
+ assert_equal(S("another string"), s)
+
+ o = Object.new
+ def o.to_int; 2; end
+ s = "foo"
+ s[o] = "bar"
+ assert_equal("fobar", s)
+
+ assert_raise(ArgumentError) { "foo"[1, 2, 3] = "" }
+ end
+
+ def test_CMP # '<=>'
+ assert_equal(1, S("abcdef") <=> S("abcde"))
+ assert_equal(0, S("abcdef") <=> S("abcdef"))
+ assert_equal(-1, S("abcde") <=> S("abcdef"))
+
+ assert_equal(-1, S("ABCDEF") <=> S("abcdef"))
+
+ pre_1_7_1 do
+ $= = true
+ assert_equal(0, S("ABCDEF") <=> S("abcdef"))
+ $= = false
+ end
+
+ assert_nil("foo" <=> Object.new)
+
+ o = Object.new
+ def o.to_str; "bar"; end
+ assert_nil("foo" <=> o)
+
+ def o.<=>(x); nil; end
+ assert_nil("foo" <=> o)
+
+ def o.<=>(x); 1; end
+ assert_equal(-1, "foo" <=> o)
+
+ def o.<=>(x); 2**100; end
+ assert_equal(-(2**100), "foo" <=> o)
+ end
+
+ def test_EQUAL # '=='
+ assert_equal(false, S("foo") == :foo)
+ assert(S("abcdef") == S("abcdef"))
+
+ pre_1_7_1 do
+ $= = true
+ assert(S("CAT") == S('cat'))
+ assert(S("CaT") == S('cAt'))
+ $= = false
+ end
+
+ assert(S("CAT") != S('cat'))
+ assert(S("CaT") != S('cAt'))
+
+ o = Object.new
+ def o.to_str; end
+ def o.==(x); false; end
+ assert_equal(false, "foo" == o)
+ def o.==(x); true; end
+ assert_equal(true, "foo" == o)
+ end
+
+ def test_LSHIFT # '<<'
+ assert_equal(S("world!"), S("world") << 33)
+ assert_equal(S("world!"), S("world") << S('!'))
+
+ s = "a"
+ 10.times {|i|
+ s << s
+ assert_equal("a" * (2 << i), s)
+ }
+
+ s = ["foo"].pack("p")
+ l = s.size
+ s << "bar"
+ assert_equal(l + 3, s.size)
+
+ bug = '[ruby-core:27583]'
+ assert_raise(RangeError, bug) {S("a".force_encoding(Encoding::UTF_8)) << -3}
+ assert_raise(RangeError, bug) {S("a".force_encoding(Encoding::UTF_8)) << -2}
+ assert_raise(RangeError, bug) {S("a".force_encoding(Encoding::UTF_8)) << -1}
+ assert_raise(RangeError, bug) {S("a".force_encoding(Encoding::UTF_8)) << 0x81308130}
+ assert_nothing_raised {S("a".force_encoding(Encoding::GB18030)) << 0x81308130}
+ end
+
+ def test_MATCH # '=~'
+ assert_equal(10, S("FeeFieFoo-Fum") =~ /Fum$/)
+ assert_equal(nil, S("FeeFieFoo-Fum") =~ /FUM$/)
+
+ pre_1_7_1 do
+ $= = true
+ assert_equal(10, S("FeeFieFoo-Fum") =~ /FUM$/)
+ $= = false
+ end
+
+ o = Object.new
+ def o.=~(x); x + "bar"; end
+ assert_equal("foobar", S("foo") =~ o)
+
+ assert_raise(TypeError) { S("foo") =~ "foo" }
+ end
+
+ def test_MOD # '%'
+ assert_equal(S("00123"), S("%05d") % 123)
+ assert_equal(S("123 |00000001"), S("%-5s|%08x") % [123, 1])
+ x = S("%3s %-4s%%foo %.0s%5d %#x%c%3.1f %b %x %X %#b %#x %#X") %
+ [S("hi"),
+ 123,
+ S("never seen"),
+ 456,
+ 0,
+ ?A,
+ 3.0999,
+ 11,
+ 171,
+ 171,
+ 11,
+ 171,
+ 171]
+
+ assert_equal(S(' hi 123 %foo 456 0A3.1 1011 ab AB 0b1011 0xab 0XAB'), x)
+ end
+
+ def test_MUL # '*'
+ assert_equal(S("XXX"), S("X") * 3)
+ assert_equal(S("HOHO"), S("HO") * 2)
+ end
+
+ def test_PLUS # '+'
+ assert_equal(S("Yodel"), S("Yo") + S("del"))
+ end
+
+ def casetest(a, b, rev=false)
+ case a
+ when b
+ assert(!rev)
+ else
+ assert(rev)
+ end
+ end
+
+ def test_VERY_EQUAL # '==='
+ # assert_equal(true, S("foo") === :foo)
+ casetest(S("abcdef"), S("abcdef"))
+
+ pre_1_7_1 do
+ $= = true
+ casetest(S("CAT"), S('cat'))
+ casetest(S("CaT"), S('cAt'))
+ $= = false
+ end
+
+ casetest(S("CAT"), S('cat'), true) # Reverse the test - we don't want to
+ casetest(S("CaT"), S('cAt'), true) # find these in the case.
+ end
+
+ def test_capitalize
+ assert_equal(S("Hello"), S("hello").capitalize)
+ assert_equal(S("Hello"), S("hELLO").capitalize)
+ assert_equal(S("123abc"), S("123ABC").capitalize)
+ end
+
+ def test_capitalize!
+ a = S("hello"); a.capitalize!
+ assert_equal(S("Hello"), a)
+
+ a = S("hELLO"); a.capitalize!
+ assert_equal(S("Hello"), a)
+
+ a = S("123ABC"); a.capitalize!
+ assert_equal(S("123abc"), a)
+
+ assert_equal(nil, S("123abc").capitalize!)
+ assert_equal(S("123abc"), S("123ABC").capitalize!)
+ assert_equal(S("Abc"), S("ABC").capitalize!)
+ assert_equal(S("Abc"), S("abc").capitalize!)
+ assert_equal(nil, S("Abc").capitalize!)
+
+ a = S("hello")
+ b = a.dup
+ assert_equal(S("Hello"), a.capitalize!)
+ assert_equal(S("hello"), b)
+
+ end
+
+ Bug2463 = '[ruby-dev:39856]'
+ def test_center
+ assert_equal(S("hello"), S("hello").center(4))
+ assert_equal(S(" hello "), S("hello").center(11))
+ assert_equal(S("ababaababa"), S("").center(10, "ab"), Bug2463)
+ assert_equal(S("ababaababab"), S("").center(11, "ab"), Bug2463)
+ end
+
+ def test_chomp
+ assert_equal(S("hello"), S("hello").chomp("\n"))
+ assert_equal(S("hello"), S("hello\n").chomp("\n"))
+ save = $/
+
+ $/ = "\n"
+
+ assert_equal(S("hello"), S("hello").chomp)
+ assert_equal(S("hello"), S("hello\n").chomp)
+
+ $/ = "!"
+ assert_equal(S("hello"), S("hello").chomp)
+ assert_equal(S("hello"), S("hello!").chomp)
+ $/ = save
+
+ assert_equal(S("a").hash, S("a\u0101").chomp(S("\u0101")).hash, '[ruby-core:22414]')
+ end
+
+ def test_chomp!
+ a = S("hello")
+ a.chomp!(S("\n"))
+
+ assert_equal(S("hello"), a)
+ assert_equal(nil, a.chomp!(S("\n")))
+
+ a = S("hello\n")
+ a.chomp!(S("\n"))
+ assert_equal(S("hello"), a)
+ save = $/
+
+ $/ = "\n"
+ a = S("hello")
+ a.chomp!
+ assert_equal(S("hello"), a)
+
+ a = S("hello\n")
+ a.chomp!
+ assert_equal(S("hello"), a)
+
+ $/ = "!"
+ a = S("hello")
+ a.chomp!
+ assert_equal(S("hello"), a)
+
+ a="hello!"
+ a.chomp!
+ assert_equal(S("hello"), a)
+
+ $/ = save
+
+ a = S("hello\n")
+ b = a.dup
+ assert_equal(S("hello"), a.chomp!)
+ assert_equal(S("hello\n"), b)
+
+ s = "foo\r\n"
+ s.chomp!
+ assert_equal("foo", s)
+
+ s = "foo\r"
+ s.chomp!
+ assert_equal("foo", s)
+
+ s = "foo\r\n"
+ s.chomp!("")
+ assert_equal("foo", s)
+
+ s = "foo\r"
+ s.chomp!("")
+ assert_equal("foo\r", s)
+
+ assert_equal(S("a").hash, S("a\u0101").chomp!(S("\u0101")).hash, '[ruby-core:22414]')
+ end
+
+ def test_chop
+ assert_equal(S("hell"), S("hello").chop)
+ assert_equal(S("hello"), S("hello\r\n").chop)
+ assert_equal(S("hello\n"), S("hello\n\r").chop)
+ assert_equal(S(""), S("\r\n").chop)
+ assert_equal(S(""), S("").chop)
+ assert_equal(S("a").hash, S("a\u00d8").chop.hash)
+ end
+
+ def test_chop!
+ a = S("hello").chop!
+ assert_equal(S("hell"), a)
+
+ a = S("hello\r\n").chop!
+ assert_equal(S("hello"), a)
+
+ a = S("hello\n\r").chop!
+ assert_equal(S("hello\n"), a)
+
+ a = S("\r\n").chop!
+ assert_equal(S(""), a)
+
+ a = S("").chop!
+ assert_nil(a)
+
+ a = S("a\u00d8")
+ a.chop!
+ assert_equal(S("a").hash, a.hash)
+
+ a = S("hello\n")
+ b = a.dup
+ assert_equal(S("hello"), a.chop!)
+ assert_equal(S("hello\n"), b)
+ end
+
+ def test_clone
+ for taint in [ false, true ]
+ for untrust in [ false, true ]
+ for frozen in [ false, true ]
+ a = S("Cool")
+ a.taint if taint
+ a.untrust if untrust
+ a.freeze if frozen
+ b = a.clone
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert_equal(a.frozen?, b.frozen?)
+ assert_equal(a.untrusted?, b.untrusted?)
+ assert_equal(a.tainted?, b.tainted?)
+ end
+ end
+ end
+
+ null = File.exist?("/dev/null") ? "/dev/null" : "NUL" # maybe DOSISH
+ assert_equal("", File.read(null).clone, '[ruby-dev:32819] reported by Kazuhiro NISHIYAMA')
+ end
+
+ def test_concat
+ assert_equal(S("world!"), S("world").concat(33))
+ assert_equal(S("world!"), S("world").concat(S('!')))
+ end
+
+ def test_count
+ a = S("hello world")
+ assert_equal(5, a.count(S("lo")))
+ assert_equal(2, a.count(S("lo"), S("o")))
+ assert_equal(4, a.count(S("hello"), S("^l")))
+ assert_equal(4, a.count(S("ej-m")))
+ assert_equal(0, S("y").count(S("a\\-z")))
+
+ assert_raise(ArgumentError) { "foo".count }
+ end
+
+ def test_crypt
+ assert_equal(S('aaGUC/JkO9/Sc'), S("mypassword").crypt(S("aa")))
+ assert(S('aaGUC/JkO9/Sc') != S("mypassword").crypt(S("ab")))
+ end
+
+ def test_delete
+ assert_equal(S("heo"), S("hello").delete(S("l"), S("lo")))
+ assert_equal(S("he"), S("hello").delete(S("lo")))
+ assert_equal(S("hell"), S("hello").delete(S("aeiou"), S("^e")))
+ assert_equal(S("ho"), S("hello").delete(S("ej-m")))
+
+ assert_equal("a".hash, "a\u0101".delete("\u0101").hash, '[ruby-talk:329267]')
+ assert_equal(true, "a\u0101".delete("\u0101").ascii_only?)
+ assert_equal(true, "a\u3041".delete("\u3041").ascii_only?)
+ assert_equal(false, "a\u3041\u3042".tr("\u3041", "a").ascii_only?)
+ end
+
+ def test_delete!
+ a = S("hello")
+ a.delete!(S("l"), S("lo"))
+ assert_equal(S("heo"), a)
+
+ a = S("hello")
+ a.delete!(S("lo"))
+ assert_equal(S("he"), a)
+
+ a = S("hello")
+ a.delete!(S("aeiou"), S("^e"))
+ assert_equal(S("hell"), a)
+
+ a = S("hello")
+ a.delete!(S("ej-m"))
+ assert_equal(S("ho"), a)
+
+ a = S("hello")
+ assert_nil(a.delete!(S("z")))
+
+ a = S("hello")
+ b = a.dup
+ a.delete!(S("lo"))
+ assert_equal(S("he"), a)
+ assert_equal(S("hello"), b)
+
+ a = S("hello")
+ a.delete!(S("^el"))
+ assert_equal(S("ell"), a)
+
+ assert_raise(ArgumentError) { S("foo").delete! }
+ end
+
+
+ def test_downcase
+ assert_equal(S("hello"), S("helLO").downcase)
+ assert_equal(S("hello"), S("hello").downcase)
+ assert_equal(S("hello"), S("HELLO").downcase)
+ assert_equal(S("abc hello 123"), S("abc HELLO 123").downcase)
+ end
+
+ def test_downcase!
+ a = S("helLO")
+ b = a.dup
+ assert_equal(S("hello"), a.downcase!)
+ assert_equal(S("hello"), a)
+ assert_equal(S("helLO"), b)
+
+ a=S("hello")
+ assert_nil(a.downcase!)
+ assert_equal(S("hello"), a)
+ end
+
+ def test_dump
+ a= S("Test") << 1 << 2 << 3 << 9 << 13 << 10
+ assert_equal(S('"Test\\x01\\x02\\x03\\t\\r\\n"'), a.dump)
+ end
+
+ def test_dup
+ for taint in [ false, true ]
+ for untrust in [ false, true ]
+ for frozen in [ false, true ]
+ a = S("hello")
+ a.taint if taint
+ a.untrust if untrust
+ a.freeze if frozen
+ b = a.dup
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert(!b.frozen?)
+ assert_equal(a.tainted?, b.tainted?)
+ assert_equal(a.untrusted?, b.untrusted?)
+ end
+ end
+ end
+ end
+
+ def test_each
+ save = $/
+ $/ = "\n"
+ res=[]
+ S("hello\nworld").lines.each {|x| res << x}
+ assert_equal(S("hello\n"), res[0])
+ assert_equal(S("world"), res[1])
+
+ res=[]
+ S("hello\n\n\nworld").lines(S('')).each {|x| res << x}
+ assert_equal(S("hello\n\n\n"), res[0])
+ assert_equal(S("world"), res[1])
+
+ $/ = "!"
+ res=[]
+ S("hello!world").lines.each {|x| res << x}
+ assert_equal(S("hello!"), res[0])
+ assert_equal(S("world"), res[1])
+ $/ = save
+ end
+
+ def test_each_byte
+ res = []
+ S("ABC").each_byte {|x| res << x }
+ assert_equal(65, res[0])
+ assert_equal(66, res[1])
+ assert_equal(67, res[2])
+ end
+
+ def test_each_line
+ save = $/
+ $/ = "\n"
+ res=[]
+ S("hello\nworld").lines.each {|x| res << x}
+ assert_equal(S("hello\n"), res[0])
+ assert_equal(S("world"), res[1])
+
+ res=[]
+ S("hello\n\n\nworld").lines(S('')).each {|x| res << x}
+ assert_equal(S("hello\n\n\n"), res[0])
+ assert_equal(S("world"), res[1])
+
+ $/ = "!"
+
+ res=[]
+ S("hello!world").lines.each {|x| res << x}
+ assert_equal(S("hello!"), res[0])
+ assert_equal(S("world"), res[1])
+
+ $/ = save
+
+ s = nil
+ "foo\nbar".each_line(nil) {|s2| s = s2 }
+ assert_equal("foo\nbar", s)
+ end
+
+ def test_empty?
+ assert(S("").empty?)
+ assert(!S("not").empty?)
+ end
+
+ def test_eql?
+ a = S("hello")
+ assert(a.eql?(S("hello")))
+ assert(a.eql?(a))
+ end
+
+ def test_gsub
+ assert_equal(S("h*ll*"), S("hello").gsub(/[aeiou]/, S('*')))
+ assert_equal(S("h<e>ll<o>"), S("hello").gsub(/([aeiou])/, S('<\1>')))
+ assert_equal(S("h e l l o "),
+ S("hello").gsub(/./) { |s| s[0].to_s + S(' ')})
+ assert_equal(S("HELL-o"),
+ S("hello").gsub(/(hell)(.)/) { |s| $1.upcase + S('-') + $2 })
+
+ a = S("hello")
+ a.taint
+ a.untrust
+ assert(a.gsub(/./, S('X')).tainted?)
+ assert(a.gsub(/./, S('X')).untrusted?)
+
+ assert_equal("z", "abc".gsub(/./, "a" => "z"), "moved from btest/knownbug")
+
+ assert_raise(ArgumentError) { "foo".gsub }
+ end
+
+ def test_gsub!
+ a = S("hello")
+ b = a.dup
+ a.gsub!(/[aeiou]/, S('*'))
+ assert_equal(S("h*ll*"), a)
+ assert_equal(S("hello"), b)
+
+ a = S("hello")
+ a.gsub!(/([aeiou])/, S('<\1>'))
+ assert_equal(S("h<e>ll<o>"), a)
+
+ a = S("hello")
+ a.gsub!(/./) { |s| s[0].to_s + S(' ')}
+ assert_equal(S("h e l l o "), a)
+
+ a = S("hello")
+ a.gsub!(/(hell)(.)/) { |s| $1.upcase + S('-') + $2 }
+ assert_equal(S("HELL-o"), a)
+
+ r = S('X')
+ r.taint
+ r.untrust
+ a.gsub!(/./, r)
+ assert(a.tainted?)
+ assert(a.untrusted?)
+
+ a = S("hello")
+ assert_nil(a.sub!(S('X'), S('Y')))
+ end
+
+ def test_sub_hash
+ assert_equal('azc', 'abc'.sub(/b/, "b" => "z"))
+ assert_equal('ac', 'abc'.sub(/b/, {}))
+ assert_equal('a1c', 'abc'.sub(/b/, "b" => 1))
+ assert_equal('aBc', 'abc'.sub(/b/, Hash.new {|h, k| k.upcase }))
+ assert_equal('a[\&]c', 'abc'.sub(/b/, "b" => '[\&]'))
+ assert_equal('aBcabc', 'abcabc'.sub(/b/, Hash.new {|h, k| h[k] = k.upcase }))
+ assert_equal('aBcdef', 'abcdef'.sub(/de|b/, "b" => "B", "de" => "DE"))
+ end
+
+ def test_gsub_hash
+ assert_equal('azc', 'abc'.gsub(/b/, "b" => "z"))
+ assert_equal('ac', 'abc'.gsub(/b/, {}))
+ assert_equal('a1c', 'abc'.gsub(/b/, "b" => 1))
+ assert_equal('aBc', 'abc'.gsub(/b/, Hash.new {|h, k| k.upcase }))
+ assert_equal('a[\&]c', 'abc'.gsub(/b/, "b" => '[\&]'))
+ assert_equal('aBcaBc', 'abcabc'.gsub(/b/, Hash.new {|h, k| h[k] = k.upcase }))
+ assert_equal('aBcDEf', 'abcdef'.gsub(/de|b/, "b" => "B", "de" => "DE"))
+ end
+
+ def test_hash
+ assert_equal(S("hello").hash, S("hello").hash)
+ assert(S("hello").hash != S("helLO").hash)
+ end
+
+ def test_hash_random
+ str = 'abc'
+ a = [str.hash.to_s]
+ 3.times {
+ assert_in_out_err(["-e", "print #{str.dump}.hash"], "") do |r, e|
+ a += r
+ assert_equal([], e)
+ end
+ }
+ assert_not_equal([str.hash.to_s], a.uniq)
+ end
+
+ def test_hex
+ assert_equal(255, S("0xff").hex)
+ assert_equal(-255, S("-0xff").hex)
+ assert_equal(255, S("ff").hex)
+ assert_equal(-255, S("-ff").hex)
+ assert_equal(0, S("-ralph").hex)
+ assert_equal(-15, S("-fred").hex)
+ assert_equal(15, S("fred").hex)
+ end
+
+ def test_include?
+ assert( S("foobar").include?(?f))
+ assert( S("foobar").include?(S("foo")))
+ assert(!S("foobar").include?(S("baz")))
+ assert(!S("foobar").include?(?z))
+ end
+
+ def test_index
+ assert_equal(0, S("hello").index(?h))
+ assert_equal(1, S("hello").index(S("ell")))
+ assert_equal(2, S("hello").index(/ll./))
+
+ assert_equal(3, S("hello").index(?l, 3))
+ assert_equal(3, S("hello").index(S("l"), 3))
+ assert_equal(3, S("hello").index(/l./, 3))
+
+ assert_nil(S("hello").index(?z, 3))
+ assert_nil(S("hello").index(S("z"), 3))
+ assert_nil(S("hello").index(/z./, 3))
+
+ assert_nil(S("hello").index(?z))
+ assert_nil(S("hello").index(S("z")))
+ assert_nil(S("hello").index(/z./))
+
+ o = Object.new
+ def o.to_str; "bar"; end
+ assert_equal(3, "foobarbarbaz".index(o))
+ assert_raise(TypeError) { "foo".index(Object.new) }
+
+ assert_nil("foo".index(//, -100))
+ assert_nil($~)
+ end
+
+ def test_intern
+ assert_equal(:koala, S("koala").intern)
+ assert(:koala != S("Koala").intern)
+ end
+
+ def test_length
+ assert_equal(0, S("").length)
+ assert_equal(4, S("1234").length)
+ assert_equal(6, S("1234\r\n").length)
+ assert_equal(7, S("\0011234\r\n").length)
+ end
+
+ def test_ljust
+ assert_equal(S("hello"), S("hello").ljust(4))
+ assert_equal(S("hello "), S("hello").ljust(11))
+ assert_equal(S("ababababab"), S("").ljust(10, "ab"), Bug2463)
+ assert_equal(S("abababababa"), S("").ljust(11, "ab"), Bug2463)
+ end
+
+ def test_next
+ assert_equal(S("abd"), S("abc").next)
+ assert_equal(S("z"), S("y").next)
+ assert_equal(S("aaa"), S("zz").next)
+
+ assert_equal(S("124"), S("123").next)
+ assert_equal(S("1000"), S("999").next)
+
+ assert_equal(S("2000aaa"), S("1999zzz").next)
+ assert_equal(S("AAAAA000"), S("ZZZZ999").next)
+
+ assert_equal(S("*+"), S("**").next)
+ end
+
+ def test_next!
+ a = S("abc")
+ b = a.dup
+ assert_equal(S("abd"), a.next!)
+ assert_equal(S("abd"), a)
+ assert_equal(S("abc"), b)
+
+ a = S("y")
+ assert_equal(S("z"), a.next!)
+ assert_equal(S("z"), a)
+
+ a = S("zz")
+ assert_equal(S("aaa"), a.next!)
+ assert_equal(S("aaa"), a)
+
+ a = S("123")
+ assert_equal(S("124"), a.next!)
+ assert_equal(S("124"), a)
+
+ a = S("999")
+ assert_equal(S("1000"), a.next!)
+ assert_equal(S("1000"), a)
+
+ a = S("1999zzz")
+ assert_equal(S("2000aaa"), a.next!)
+ assert_equal(S("2000aaa"), a)
+
+ a = S("ZZZZ999")
+ assert_equal(S("AAAAA000"), a.next!)
+ assert_equal(S("AAAAA000"), a)
+
+ a = S("**")
+ assert_equal(S("*+"), a.next!)
+ assert_equal(S("*+"), a)
+ end
+
+ def test_oct
+ assert_equal(255, S("0377").oct)
+ assert_equal(255, S("377").oct)
+ assert_equal(-255, S("-0377").oct)
+ assert_equal(-255, S("-377").oct)
+ assert_equal(0, S("OO").oct)
+ assert_equal(24, S("030OO").oct)
+ end
+
+ def test_replace
+ a = S("foo")
+ assert_equal(S("f"), a.replace(S("f")))
+
+ a = S("foo")
+ assert_equal(S("foobar"), a.replace(S("foobar")))
+
+ a = S("foo")
+ a.taint
+ a.untrust
+ b = a.replace(S("xyz"))
+ assert_equal(S("xyz"), b)
+ assert(b.tainted?)
+ assert(b.untrusted?)
+
+ s = "foo" * 100
+ s2 = ("bar" * 100).dup
+ s.replace(s2)
+ assert_equal(s2, s)
+
+ s2 = ["foo"].pack("p")
+ s.replace(s2)
+ assert_equal(s2, s)
+
+ fs = "".freeze
+ assert_raise(RuntimeError) { fs.replace("a") }
+ assert_raise(RuntimeError) { fs.replace(fs) }
+ assert_raise(ArgumentError) { fs.replace() }
+ assert_raise(RuntimeError) { fs.replace(42) }
+ end
+
+ def test_reverse
+ assert_equal(S("beta"), S("ateb").reverse)
+ assert_equal(S("madamImadam"), S("madamImadam").reverse)
+
+ a=S("beta")
+ assert_equal(S("ateb"), a.reverse)
+ assert_equal(S("beta"), a)
+ end
+
+ def test_reverse!
+ a = S("beta")
+ b = a.dup
+ assert_equal(S("ateb"), a.reverse!)
+ assert_equal(S("ateb"), a)
+ assert_equal(S("beta"), b)
+
+ assert_equal(S("madamImadam"), S("madamImadam").reverse!)
+
+ a = S("madamImadam")
+ assert_equal(S("madamImadam"), a.reverse!) # ??
+ assert_equal(S("madamImadam"), a)
+ end
+
+ def test_rindex
+ assert_equal(3, S("hello").rindex(?l))
+ assert_equal(6, S("ell, hello").rindex(S("ell")))
+ assert_equal(7, S("ell, hello").rindex(/ll./))
+
+ assert_equal(3, S("hello,lo").rindex(?l, 3))
+ assert_equal(3, S("hello,lo").rindex(S("l"), 3))
+ assert_equal(3, S("hello,lo").rindex(/l./, 3))
+
+ assert_nil(S("hello").rindex(?z, 3))
+ assert_nil(S("hello").rindex(S("z"), 3))
+ assert_nil(S("hello").rindex(/z./, 3))
+
+ assert_nil(S("hello").rindex(?z))
+ assert_nil(S("hello").rindex(S("z")))
+ assert_nil(S("hello").rindex(/z./))
+
+ o = Object.new
+ def o.to_str; "bar"; end
+ assert_equal(6, "foobarbarbaz".rindex(o))
+ assert_raise(TypeError) { "foo".rindex(Object.new) }
+
+ assert_nil("foo".rindex(//, -100))
+ assert_nil($~)
+ end
+
+ def test_rjust
+ assert_equal(S("hello"), S("hello").rjust(4))
+ assert_equal(S(" hello"), S("hello").rjust(11))
+ assert_equal(S("ababababab"), S("").rjust(10, "ab"), Bug2463)
+ assert_equal(S("abababababa"), S("").rjust(11, "ab"), Bug2463)
+ end
+
+ def test_scan
+ a = S("cruel world")
+ assert_equal([S("cruel"), S("world")],a.scan(/\w+/))
+ assert_equal([S("cru"), S("el "), S("wor")],a.scan(/.../))
+ assert_equal([[S("cru")], [S("el ")], [S("wor")]],a.scan(/(...)/))
+
+ res = []
+ a.scan(/\w+/) { |w| res << w }
+ assert_equal([S("cruel"), S("world") ],res)
+
+ res = []
+ a.scan(/.../) { |w| res << w }
+ assert_equal([S("cru"), S("el "), S("wor")],res)
+
+ res = []
+ a.scan(/(...)/) { |w| res << w }
+ assert_equal([[S("cru")], [S("el ")], [S("wor")]],res)
+ end
+
+ def test_size
+ assert_equal(0, S("").size)
+ assert_equal(4, S("1234").size)
+ assert_equal(6, S("1234\r\n").size)
+ assert_equal(7, S("\0011234\r\n").size)
+ end
+
+ def test_slice
+ assert_equal(?A, S("AooBar").slice(0))
+ assert_equal(?B, S("FooBaB").slice(-1))
+ assert_nil(S("FooBar").slice(6))
+ assert_nil(S("FooBar").slice(-7))
+
+ assert_equal(S("Foo"), S("FooBar").slice(0,3))
+ assert_equal(S(S("Bar")), S("FooBar").slice(-3,3))
+ assert_nil(S("FooBar").slice(7,2)) # Maybe should be six?
+ assert_nil(S("FooBar").slice(-7,10))
+
+ assert_equal(S("Foo"), S("FooBar").slice(0..2))
+ assert_equal(S("Bar"), S("FooBar").slice(-3..-1))
+ assert_equal(S(""), S("FooBar").slice(6..2))
+ assert_nil(S("FooBar").slice(-10..-7))
+
+ assert_equal(S("Foo"), S("FooBar").slice(/^F../))
+ assert_equal(S("Bar"), S("FooBar").slice(/..r$/))
+ assert_nil(S("FooBar").slice(/xyzzy/))
+ assert_nil(S("FooBar").slice(/plugh/))
+
+ assert_equal(S("Foo"), S("FooBar").slice(S("Foo")))
+ assert_equal(S("Bar"), S("FooBar").slice(S("Bar")))
+ assert_nil(S("FooBar").slice(S("xyzzy")))
+ assert_nil(S("FooBar").slice(S("plugh")))
+ end
+
+ def test_slice!
+ a = S("AooBar")
+ b = a.dup
+ assert_equal(?A, a.slice!(0))
+ assert_equal(S("ooBar"), a)
+ assert_equal(S("AooBar"), b)
+
+ a = S("FooBar")
+ assert_equal(?r,a.slice!(-1))
+ assert_equal(S("FooBa"), a)
+
+ a = S("FooBar")
+ if @aref_slicebang_silent
+ assert_nil( a.slice!(6) )
+ else
+ assert_raise(IndexError) { a.slice!(6) }
+ end
+ assert_equal(S("FooBar"), a)
+
+ if @aref_slicebang_silent
+ assert_nil( a.slice!(-7) )
+ else
+ assert_raise(IndexError) { a.slice!(-7) }
+ end
+ assert_equal(S("FooBar"), a)
+
+ a = S("FooBar")
+ assert_equal(S("Foo"), a.slice!(0,3))
+ assert_equal(S("Bar"), a)
+
+ a = S("FooBar")
+ assert_equal(S("Bar"), a.slice!(-3,3))
+ assert_equal(S("Foo"), a)
+
+ a=S("FooBar")
+ if @aref_slicebang_silent
+ assert_nil(a.slice!(7,2)) # Maybe should be six?
+ else
+ assert_raise(IndexError) {a.slice!(7,2)} # Maybe should be six?
+ end
+ assert_equal(S("FooBar"), a)
+ if @aref_slicebang_silent
+ assert_nil(a.slice!(-7,10))
+ else
+ assert_raise(IndexError) {a.slice!(-7,10)}
+ end
+ assert_equal(S("FooBar"), a)
+
+ a=S("FooBar")
+ assert_equal(S("Foo"), a.slice!(0..2))
+ assert_equal(S("Bar"), a)
+
+ a=S("FooBar")
+ assert_equal(S("Bar"), a.slice!(-3..-1))
+ assert_equal(S("Foo"), a)
+
+ a=S("FooBar")
+ if @aref_slicebang_silent
+ assert_equal(S(""), a.slice!(6..2))
+ else
+ assert_raise(RangeError) {a.slice!(6..2)}
+ end
+ assert_equal(S("FooBar"), a)
+ if @aref_slicebang_silent
+ assert_nil(a.slice!(-10..-7))
+ else
+ assert_raise(RangeError) {a.slice!(-10..-7)}
+ end
+ assert_equal(S("FooBar"), a)
+
+ a=S("FooBar")
+ assert_equal(S("Foo"), a.slice!(/^F../))
+ assert_equal(S("Bar"), a)
+
+ a=S("FooBar")
+ assert_equal(S("Bar"), a.slice!(/..r$/))
+ assert_equal(S("Foo"), a)
+
+ a=S("FooBar")
+ if @aref_slicebang_silent
+ assert_nil(a.slice!(/xyzzy/))
+ else
+ assert_raise(IndexError) {a.slice!(/xyzzy/)}
+ end
+ assert_equal(S("FooBar"), a)
+ if @aref_slicebang_silent
+ assert_nil(a.slice!(/plugh/))
+ else
+ assert_raise(IndexError) {a.slice!(/plugh/)}
+ end
+ assert_equal(S("FooBar"), a)
+
+ a=S("FooBar")
+ assert_equal(S("Foo"), a.slice!(S("Foo")))
+ assert_equal(S("Bar"), a)
+
+ a=S("FooBar")
+ assert_equal(S("Bar"), a.slice!(S("Bar")))
+ assert_equal(S("Foo"), a)
+
+ pre_1_7_1 do
+ a=S("FooBar")
+ assert_nil(a.slice!(S("xyzzy")))
+ assert_equal(S("FooBar"), a)
+ assert_nil(a.slice!(S("plugh")))
+ assert_equal(S("FooBar"), a)
+ end
+
+ assert_raise(ArgumentError) { "foo".slice! }
+ end
+
+ def test_split
+ assert_nil($;)
+ assert_equal([S("a"), S("b"), S("c")], S(" a b\t c ").split)
+ assert_equal([S("a"), S("b"), S("c")], S(" a b\t c ").split(S(" ")))
+
+ assert_equal([S(" a "), S(" b "), S(" c ")], S(" a | b | c ").split(S("|")))
+
+ assert_equal([S("a"), S("b"), S("c")], S("aXXbXXcXX").split(/X./))
+
+ assert_equal([S("a"), S("b"), S("c")], S("abc").split(//))
+
+ assert_equal([S("a|b|c")], S("a|b|c").split(S('|'), 1))
+
+ assert_equal([S("a"), S("b|c")], S("a|b|c").split(S('|'), 2))
+ assert_equal([S("a"), S("b"), S("c")], S("a|b|c").split(S('|'), 3))
+
+ assert_equal([S("a"), S("b"), S("c"), S("")], S("a|b|c|").split(S('|'), -1))
+ assert_equal([S("a"), S("b"), S("c"), S(""), S("")], S("a|b|c||").split(S('|'), -1))
+
+ assert_equal([S("a"), S(""), S("b"), S("c")], S("a||b|c|").split(S('|')))
+ assert_equal([S("a"), S(""), S("b"), S("c"), S("")], S("a||b|c|").split(S('|'), -1))
+
+ assert_equal([], "".split(//, 1))
+
+ assert_equal("[2, 3]", [1,2,3].slice!(1,10000).inspect, "moved from btest/knownbug")
+
+ end
+
+ def test_squeeze
+ assert_equal(S("abc"), S("aaabbbbccc").squeeze)
+ assert_equal(S("aa bb cc"), S("aa bb cc").squeeze(S(" ")))
+ assert_equal(S("BxTyWz"), S("BxxxTyyyWzzzzz").squeeze(S("a-z")))
+ end
+
+ def test_squeeze!
+ a = S("aaabbbbccc")
+ b = a.dup
+ assert_equal(S("abc"), a.squeeze!)
+ assert_equal(S("abc"), a)
+ assert_equal(S("aaabbbbccc"), b)
+
+ a = S("aa bb cc")
+ assert_equal(S("aa bb cc"), a.squeeze!(S(" ")))
+ assert_equal(S("aa bb cc"), a)
+
+ a = S("BxxxTyyyWzzzzz")
+ assert_equal(S("BxTyWz"), a.squeeze!(S("a-z")))
+ assert_equal(S("BxTyWz"), a)
+
+ a=S("The quick brown fox")
+ assert_nil(a.squeeze!)
+ end
+
+ def test_strip
+ assert_equal(S("x"), S(" x ").strip)
+ assert_equal(S("x"), S(" \n\r\t x \t\r\n\n ").strip)
+
+ assert_equal("0b0 ".force_encoding("UTF-16BE"),
+ "\x00 0b0 ".force_encoding("UTF-16BE").strip)
+ assert_equal("0\x000b0 ".force_encoding("UTF-16BE"),
+ "0\x000b0 ".force_encoding("UTF-16BE").strip)
+ end
+
+ def test_strip!
+ a = S(" x ")
+ b = a.dup
+ assert_equal(S("x") ,a.strip!)
+ assert_equal(S("x") ,a)
+ assert_equal(S(" x "), b)
+
+ a = S(" \n\r\t x \t\r\n\n ")
+ assert_equal(S("x"), a.strip!)
+ assert_equal(S("x"), a)
+
+ a = S("x")
+ assert_nil(a.strip!)
+ assert_equal(S("x") ,a)
+ end
+
+ def test_sub
+ assert_equal(S("h*llo"), S("hello").sub(/[aeiou]/, S('*')))
+ assert_equal(S("h<e>llo"), S("hello").sub(/([aeiou])/, S('<\1>')))
+ assert_equal(S("h ello"), S("hello").sub(/./) {
+ |s| s[0].to_s + S(' ')})
+ assert_equal(S("HELL-o"), S("hello").sub(/(hell)(.)/) {
+ |s| $1.upcase + S('-') + $2
+ })
+
+ assert_equal(S("a\\aba"), S("ababa").sub(/b/, '\\'))
+ assert_equal(S("ab\\aba"), S("ababa").sub(/(b)/, '\1\\'))
+ assert_equal(S("ababa"), S("ababa").sub(/(b)/, '\1'))
+ assert_equal(S("ababa"), S("ababa").sub(/(b)/, '\\1'))
+ assert_equal(S("a\\1aba"), S("ababa").sub(/(b)/, '\\\1'))
+ assert_equal(S("a\\1aba"), S("ababa").sub(/(b)/, '\\\\1'))
+ assert_equal(S("a\\baba"), S("ababa").sub(/(b)/, '\\\\\1'))
+
+ assert_equal(S("a--ababababababababab"),
+ S("abababababababababab").sub(/(b)/, '-\9-'))
+ assert_equal(S("1-b-0"),
+ S("1b2b3b4b5b6b7b8b9b0").
+ sub(/(b).(b).(b).(b).(b).(b).(b).(b).(b)/, '-\9-'))
+ assert_equal(S("1-b-0"),
+ S("1b2b3b4b5b6b7b8b9b0").
+ sub(/(b).(b).(b).(b).(b).(b).(b).(b).(b)/, '-\\9-'))
+ assert_equal(S("1-\\9-0"),
+ S("1b2b3b4b5b6b7b8b9b0").
+ sub(/(b).(b).(b).(b).(b).(b).(b).(b).(b)/, '-\\\9-'))
+ assert_equal(S("k"),
+ S("1a2b3c4d5e6f7g8h9iAjBk").
+ sub(/.(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.)/, '\+'))
+
+ assert_equal(S("ab\\aba"), S("ababa").sub(/b/, '\&\\'))
+ assert_equal(S("ababa"), S("ababa").sub(/b/, '\&'))
+ assert_equal(S("ababa"), S("ababa").sub(/b/, '\\&'))
+ assert_equal(S("a\\&aba"), S("ababa").sub(/b/, '\\\&'))
+ assert_equal(S("a\\&aba"), S("ababa").sub(/b/, '\\\\&'))
+ assert_equal(S("a\\baba"), S("ababa").sub(/b/, '\\\\\&'))
+
+ a = S("hello")
+ a.taint
+ a.untrust
+ x = a.sub(/./, S('X'))
+ assert(x.tainted?)
+ assert(x.untrusted?)
+
+ o = Object.new
+ def o.to_str; "bar"; end
+ assert_equal("fooBARbaz", "foobarbaz".sub(o, "BAR"))
+
+ assert_raise(TypeError) { "foo".sub(Object.new, "") }
+
+ assert_raise(ArgumentError) { "foo".sub }
+
+ assert_raise(IndexError) { "foo"[/(?:(o$)|(x))/, 2] = 'bar' }
+
+ o = Object.new
+ def o.to_s; self; end
+ assert_match(/^foo#<Object:0x.*>baz$/, "foobarbaz".sub("bar") { o })
+ end
+
+ def test_sub!
+ a = S("hello")
+ b = a.dup
+ a.sub!(/[aeiou]/, S('*'))
+ assert_equal(S("h*llo"), a)
+ assert_equal(S("hello"), b)
+
+ a = S("hello")
+ a.sub!(/([aeiou])/, S('<\1>'))
+ assert_equal(S("h<e>llo"), a)
+
+ a = S("hello")
+ a.sub!(/./) { |s| s[0].to_s + S(' ')}
+ assert_equal(S("h ello"), a)
+
+ a = S("hello")
+ a.sub!(/(hell)(.)/) { |s| $1.upcase + S('-') + $2 }
+ assert_equal(S("HELL-o"), a)
+
+ a=S("hello")
+ assert_nil(a.sub!(/X/, S('Y')))
+
+ r = S('X')
+ r.taint
+ r.untrust
+ a.sub!(/./, r)
+ assert(a.tainted?)
+ assert(a.untrusted?)
+ end
+
+ def test_succ
+ assert_equal(S("abd"), S("abc").succ)
+ assert_equal(S("z"), S("y").succ)
+ assert_equal(S("aaa"), S("zz").succ)
+
+ assert_equal(S("124"), S("123").succ)
+ assert_equal(S("1000"), S("999").succ)
+ assert_equal(S("2.000"), S("1.999").succ)
+
+ assert_equal(S("No.10"), S("No.9").succ)
+ assert_equal(S("2000aaa"), S("1999zzz").succ)
+ assert_equal(S("AAAAA000"), S("ZZZZ999").succ)
+ assert_equal(S("*+"), S("**").succ)
+
+ assert_equal("abce", "abcd".succ)
+ assert_equal("THX1139", "THX1138".succ)
+ assert_equal("<<koalb>>", "<<koala>>".succ)
+ assert_equal("2000aaa", "1999zzz".succ)
+ assert_equal("AAAA0000", "ZZZ9999".succ)
+ assert_equal("**+", "***".succ)
+ end
+
+ def test_succ!
+ a = S("abc")
+ b = a.dup
+ assert_equal(S("abd"), a.succ!)
+ assert_equal(S("abd"), a)
+ assert_equal(S("abc"), b)
+
+ a = S("y")
+ assert_equal(S("z"), a.succ!)
+ assert_equal(S("z"), a)
+
+ a = S("zz")
+ assert_equal(S("aaa"), a.succ!)
+ assert_equal(S("aaa"), a)
+
+ a = S("123")
+ assert_equal(S("124"), a.succ!)
+ assert_equal(S("124"), a)
+
+ a = S("999")
+ assert_equal(S("1000"), a.succ!)
+ assert_equal(S("1000"), a)
+
+ a = S("1999zzz")
+ assert_equal(S("2000aaa"), a.succ!)
+ assert_equal(S("2000aaa"), a)
+
+ a = S("ZZZZ999")
+ assert_equal(S("AAAAA000"), a.succ!)
+ assert_equal(S("AAAAA000"), a)
+
+ a = S("**")
+ assert_equal(S("*+"), a.succ!)
+ assert_equal(S("*+"), a)
+
+ a = S("No.9")
+ assert_equal(S("No.10"), a.succ!)
+ assert_equal(S("No.10"), a)
+
+ assert_equal("aaaaaaaaaaaa", "zzzzzzzzzzz".succ!)
+ assert_equal("aaaaaaaaaaaaaaaaaaaaaaaa", "zzzzzzzzzzzzzzzzzzzzzzz".succ!)
+ end
+
+ def test_sum
+ n = S("\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001")
+ assert_equal(15, n.sum)
+ n += S("\001")
+ assert_equal(16, n.sum(17))
+ n[0] = 2.chr
+ assert(15 != n.sum)
+ end
+
+ def check_sum(str, bits=16)
+ sum = 0
+ str.each_byte {|c| sum += c}
+ sum = sum & ((1 << bits) - 1) if bits != 0
+ assert_equal(sum, str.sum(bits))
+ end
+
+ def test_sum_2
+ assert_equal(0, "".sum)
+ assert_equal(294, "abc".sum)
+ check_sum("abc")
+ check_sum("\x80")
+ 0.upto(70) {|bits|
+ check_sum("xyz", bits)
+ }
+ end
+
+ def test_sum_long
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ s8421505 = "\xff" * 8421505
+ assert_equal(127, s8421505.sum(31))
+ assert_equal(2147483775, s8421505.sum(0))
+ s16843010 = ("\xff" * 16843010)
+ assert_equal(254, s16843010.sum(32))
+ assert_equal(4294967550, s16843010.sum(0))
+ end
+
+ def test_swapcase
+ assert_equal(S("hi&LOW"), S("HI&low").swapcase)
+ end
+
+ def test_swapcase!
+ a = S("hi&LOW")
+ b = a.dup
+ assert_equal(S("HI&low"), a.swapcase!)
+ assert_equal(S("HI&low"), a)
+ assert_equal(S("hi&LOW"), b)
+
+ a = S("$^#^%$#!!")
+ assert_nil(a.swapcase!)
+ assert_equal(S("$^#^%$#!!"), a)
+ end
+
+ def test_to_f
+ assert_equal(344.3, S("344.3").to_f)
+ assert_equal(5.9742e24, S("5.9742e24").to_f)
+ assert_equal(98.6, S("98.6 degrees").to_f)
+ assert_equal(0.0, S("degrees 100.0").to_f)
+ assert_equal([ 0.0].pack('G'), [S(" 0.0").to_f].pack('G'))
+ assert_equal([-0.0].pack('G'), [S("-0.0").to_f].pack('G'))
+ end
+
+ def test_to_i
+ assert_equal(1480, S("1480ft/sec").to_i)
+ assert_equal(0, S("speed of sound in water @20C = 1480ft/sec)").to_i)
+ assert_equal(0, " 0".to_i)
+ assert_equal(0, "+0".to_i)
+ assert_equal(0, "-0".to_i)
+ assert_equal(0, "--0".to_i)
+ assert_equal(16, "0x10".to_i(0))
+ assert_equal(16, "0X10".to_i(0))
+ assert_equal(2, "0b10".to_i(0))
+ assert_equal(2, "0B10".to_i(0))
+ assert_equal(8, "0o10".to_i(0))
+ assert_equal(8, "0O10".to_i(0))
+ assert_equal(10, "0d10".to_i(0))
+ assert_equal(10, "0D10".to_i(0))
+ assert_equal(8, "010".to_i(0))
+ assert_raise(ArgumentError) { "010".to_i(-10) }
+ 2.upto(36) {|radix|
+ assert_equal(radix, "10".to_i(radix))
+ assert_equal(radix**2, "100".to_i(radix))
+ }
+ assert_raise(ArgumentError) { "0".to_i(1) }
+ assert_raise(ArgumentError) { "0".to_i(37) }
+ assert_equal(0, "z".to_i(10))
+ assert_equal(12, "1_2".to_i(10))
+ assert_equal(0x40000000, "1073741824".to_i(10))
+ assert_equal(0x4000000000000000, "4611686018427387904".to_i(10))
+ assert_equal(1, "1__2".to_i(10))
+ assert_equal(1, "1_z".to_i(10))
+ end
+
+ def test_to_s
+ a = S("me")
+ assert_equal("me", a.to_s)
+ assert_equal(a.__id__, a.to_s.__id__) if @cls == String
+ end
+
+ def test_to_str
+ a = S("me")
+ assert_equal("me", a.to_s)
+ assert_equal(a.__id__, a.to_s.__id__) if @cls == String
+
+ o = Object.new
+ def o.to_str
+ "at"
+ end
+ assert_equal("meat", a.concat(o))
+
+ o = Object.new
+ def o.to_str
+ foo_bar()
+ end
+ assert_match(/foo_bar/, assert_raise(NoMethodError) {a.concat(o)}.message)
+ end
+
+ def test_tr
+ skip("[BUG : #827] Assertion")
+
+ assert_equal(S("hippo"), S("hello").tr(S("el"), S("ip")))
+ assert_equal(S("*e**o"), S("hello").tr(S("^aeiou"), S("*")))
+ assert_equal(S("hal"), S("ibm").tr(S("b-z"), S("a-z")))
+
+ a = "abc".force_encoding(Encoding::US_ASCII)
+ assert_equal(Encoding::US_ASCII, a.tr(S("z"), S("\u0101")).encoding, '[ruby-core:22326]')
+
+ assert_equal("a".hash, "a".tr("a", "\u0101").tr("\u0101", "a").hash, '[ruby-core:22328]')
+ assert_equal(true, "\u0101".tr("\u0101", "a").ascii_only?)
+ assert_equal(true, "\u3041".tr("\u3041", "a").ascii_only?)
+ assert_equal(false, "\u3041\u3042".tr("\u3041", "a").ascii_only?)
+ end
+
+ def test_tr!
+ skip("[BUG : #827] Assertion")
+
+ a = S("hello")
+ b = a.dup
+ assert_equal(S("hippo"), a.tr!(S("el"), S("ip")))
+ assert_equal(S("hippo"), a)
+ assert_equal(S("hello"),b)
+
+ a = S("hello")
+ assert_equal(S("*e**o"), a.tr!(S("^aeiou"), S("*")))
+ assert_equal(S("*e**o"), a)
+
+ a = S("IBM")
+ assert_equal(S("HAL"), a.tr!(S("B-Z"), S("A-Z")))
+ assert_equal(S("HAL"), a)
+
+ a = S("ibm")
+ assert_nil(a.tr!(S("B-Z"), S("A-Z")))
+ assert_equal(S("ibm"), a)
+
+ a = "abc".force_encoding(Encoding::US_ASCII)
+ assert_nil(a.tr!(S("z"), S("\u0101")), '[ruby-core:22326]')
+ assert_equal(Encoding::US_ASCII, a.encoding, '[ruby-core:22326]')
+ end
+
+ def test_tr_s
+ assert_equal(S("hypo"), S("hello").tr_s(S("el"), S("yp")))
+ assert_equal(S("h*o"), S("hello").tr_s(S("el"), S("*")))
+ assert_equal("a".hash, "\u0101\u0101".tr_s("\u0101", "a").hash)
+ assert_equal(true, "\u3041\u3041".tr("\u3041", "a").ascii_only?)
+ end
+
+ def test_tr_s!
+ a = S("hello")
+ b = a.dup
+ assert_equal(S("hypo"), a.tr_s!(S("el"), S("yp")))
+ assert_equal(S("hypo"), a)
+ assert_equal(S("hello"), b)
+
+ a = S("hello")
+ assert_equal(S("h*o"), a.tr_s!(S("el"), S("*")))
+ assert_equal(S("h*o"), a)
+ end
+
+ def test_unpack
+ a = [S("cat"), S("wom"), S("x"), S("yy")]
+ assert_equal(a, S("catwomx yy ").unpack(S("A3A3A3A3")))
+
+ assert_equal([S("cat")], S("cat \000\000").unpack(S("A*")))
+ assert_equal([S("cwx"), S("wx"), S("x"), S("yy")],
+ S("cwx yy ").unpack(S("A3 at 1A3@2A3A3")))
+ assert_equal([S("cat"), S("wom"), S("x\000\000"), S("yy\000")],
+ S("catwomx\000\000yy\000").unpack(S("a3a3a3a3")))
+ assert_equal([S("cat \000\000")], S("cat \000\000").unpack(S("a*")))
+ assert_equal([S("ca")], S("catdog").unpack(S("a2")))
+
+ assert_equal([S("cat\000\000")],
+ S("cat\000\000\000\000\000dog").unpack(S("a5")))
+
+ assert_equal([S("01100001")], S("\x61").unpack(S("B8")))
+ assert_equal([S("01100001")], S("\x61").unpack(S("B*")))
+ assert_equal([S("0110000100110111")], S("\x61\x37").unpack(S("B16")))
+ assert_equal([S("01100001"), S("00110111")], S("\x61\x37").unpack(S("B8B8")))
+ assert_equal([S("0110")], S("\x60").unpack(S("B4")))
+
+ assert_equal([S("01")], S("\x40").unpack(S("B2")))
+
+ assert_equal([S("01100001")], S("\x86").unpack(S("b8")))
+ assert_equal([S("01100001")], S("\x86").unpack(S("b*")))
+
+ assert_equal([S("0110000100110111")], S("\x86\xec").unpack(S("b16")))
+ assert_equal([S("01100001"), S("00110111")], S("\x86\xec").unpack(S("b8b8")))
+
+ assert_equal([S("0110")], S("\x06").unpack(S("b4")))
+ assert_equal([S("01")], S("\x02").unpack(S("b2")))
+
+ assert_equal([ 65, 66, 67 ], S("ABC").unpack(S("C3")))
+ assert_equal([ 255, 66, 67 ], S("\377BC").unpack("C*"))
+ assert_equal([ 65, 66, 67 ], S("ABC").unpack("c3"))
+ assert_equal([ -1, 66, 67 ], S("\377BC").unpack("c*"))
+
+
+ assert_equal([S("4142"), S("0a"), S("1")], S("AB\n\x10").unpack(S("H4H2H1")))
+ assert_equal([S("1424"), S("a0"), S("2")], S("AB\n\x02").unpack(S("h4h2h1")))
+
+ assert_equal([S("abc\002defcat\001"), S(""), S("")],
+ S("abc=02def=\ncat=\n=01=\n").unpack(S("M9M3M4")))
+
+ assert_equal([S("hello\n")], S("aGVsbG8K\n").unpack(S("m")))
+
+ assert_equal([S("hello\nhello\n")], S(",:&5L;&\\*:&5L;&\\*\n").unpack(S("u")))
+
+ assert_equal([0xa9, 0x42, 0x2260], S("\xc2\xa9B\xe2\x89\xa0").unpack(S("U*")))
+
+=begin
+ skipping "Not tested:
+ D,d & double-precision float, native format\\
+ E & double-precision float, little-endian byte order\\
+ e & single-precision float, little-endian byte order\\
+ F,f & single-precision float, native format\\
+ G & double-precision float, network (big-endian) byte order\\
+ g & single-precision float, network (big-endian) byte order\\
+ I & unsigned integer\\
+ i & integer\\
+ L & unsigned long\\
+ l & long\\
+
+ m & string encoded in base64 (uuencoded)\\
+ N & long, network (big-endian) byte order\\
+ n & short, network (big-endian) byte-order\\
+ P & pointer to a structure (fixed-length string)\\
+ p & pointer to a null-terminated string\\
+ S & unsigned short\\
+ s & short\\
+ V & long, little-endian byte order\\
+ v & short, little-endian byte order\\
+ X & back up a byte\\
+ x & null byte\\
+ Z & ASCII string (null padded, count is width)\\
+"
+=end
+ end
+
+ def test_upcase
+ assert_equal(S("HELLO"), S("hello").upcase)
+ assert_equal(S("HELLO"), S("hello").upcase)
+ assert_equal(S("HELLO"), S("HELLO").upcase)
+ assert_equal(S("ABC HELLO 123"), S("abc HELLO 123").upcase)
+ end
+
+ def test_upcase!
+ a = S("hello")
+ b = a.dup
+ assert_equal(S("HELLO"), a.upcase!)
+ assert_equal(S("HELLO"), a)
+ assert_equal(S("hello"), b)
+
+ a = S("HELLO")
+ assert_nil(a.upcase!)
+ assert_equal(S("HELLO"), a)
+ end
+
+ def test_upto
+ a = S("aa")
+ start = S("aa")
+ count = 0
+ assert_equal(S("aa"), a.upto(S("zz")) {|s|
+ assert_equal(start, s)
+ start.succ!
+ count += 1
+ })
+ assert_equal(676, count)
+ end
+
+ def test_upto_numeric
+ a = S("00")
+ start = S("00")
+ count = 0
+ assert_equal(S("00"), a.upto(S("23")) {|s|
+ assert_equal(start, s, "[ruby-dev:39361]")
+ assert_equal(Encoding::US_ASCII, s.encoding)
+ start.succ!
+ count += 1
+ })
+ assert_equal(24, count, "[ruby-dev:39361]")
+ end
+
+ def test_upto_nonalnum
+ first = S("\u3041")
+ last = S("\u3093")
+ count = 0
+ assert_equal(first, first.upto(last) {|s|
+ count += 1
+ s.replace(last)
+ })
+ assert_equal(83, count, "[ruby-dev:39626]")
+ end
+
+ def test_mod_check
+ assert_raise(RuntimeError) {
+ s = ""
+ s.sub!(/\A/) { s.replace "z" * 2000; "zzz" }
+ }
+ end
+
+ def test_frozen_check
+ assert_raise(RuntimeError) {
+ s = ""
+ s.sub!(/\A/) { s.freeze; "zzz" }
+ }
+ end
+
+ def test_tainted_str_new
+ a = []
+ a << a
+ s = a.inspect
+ assert(s.tainted?)
+ assert_equal("[[...]]", s)
+ end
+
+ class S2 < String
+ end
+ def test_str_new4
+ s = (0..54).to_a.join # length = 100
+ s2 = S2.new(s[10,90])
+ s3 = s2[10,80]
+ assert_equal((10..54).to_a.to_a.join, s2)
+ assert_equal((15..54).to_a.to_a.join, s3)
+ end
+
+ def test_rb_str_new4
+ s = "a" * 100
+ s2 = s[10,90]
+ assert_equal("a" * 90, s2)
+ s3 = s2[10,80]
+ assert_equal("a" * 80, s3)
+ end
+
+ class StringLike
+ def initialize(str)
+ @str = str
+ end
+
+ def to_str
+ @str
+ end
+ end
+
+ def test_rb_str_to_str
+ assert_equal("ab", "a" + StringLike.new("b"))
+ end
+
+ def test_rb_str_shared_replace
+ s = "a" * 100
+ s.succ!
+ assert_equal("a" * 99 + "b", s)
+ s = ""
+ s.succ!
+ assert_equal("", s)
+ end
+
+ def test_times
+ assert_raise(ArgumentError) { "a" * (-1) }
+ end
+
+ def test_splice!
+ l = S("1234\n234\n34\n4\n")
+ assert_equal(S("1234\n"), l.slice!(/\A.*\n/), "[ruby-dev:31665]")
+ assert_equal(S("234\n"), l.slice!(/\A.*\n/), "[ruby-dev:31665]")
+ assert_equal(S("34\n"), l.slice!(/\A.*\n/), "[ruby-dev:31665]")
+ assert_equal(S("4\n"), l.slice!(/\A.*\n/), "[ruby-dev:31665]")
+ assert_nil(l.slice!(/\A.*\n/), "[ruby-dev:31665]")
+ end
+
+ def test_end_with?
+ assert("abc".end_with?("c"))
+ end
+
+ def test_times2
+ s1 = ''
+ 100.times {|n|
+ s2 = "a" * n
+ assert_equal(s1, s2)
+ s1 << 'a'
+ }
+
+ assert_raise(ArgumentError) { "foo" * (-1) }
+ end
+
+ def test_respond_to
+ o = Object.new
+ def o.respond_to?(arg) [:to_str].include?(arg) ? nil : super end
+ def o.to_str() "" end
+ def o.==(other) "" == other end
+ assert_equal(false, "" == o)
+ end
+
+ def test_match_method
+ assert_equal("bar", "foobarbaz".match(/bar/).to_s)
+
+ o = /foo/
+ def o.match(x, y, z); x + y + z; end
+ assert_equal("foobarbaz", "foo".match(o, "bar", "baz"))
+ x = nil
+ "foo".match(o, "bar", "baz") {|y| x = y }
+ assert_equal("foobarbaz", x)
+
+ assert_raise(ArgumentError) { "foo".match }
+ end
+
+ def test_clear
+ s = "foo" * 100
+ s.clear
+ assert_equal("", s)
+ end
+
+ def test_to_s_2
+ c = Class.new(String)
+ s = c.new
+ s.replace("foo")
+ assert_equal("foo", s.to_s)
+ assert_instance_of(String, s.to_s)
+ end
+
+ def test_partition
+ assert_equal(%w(he l lo), "hello".partition(/l/))
+ assert_equal(%w(he l lo), "hello".partition("l"))
+ assert_raise(TypeError) { "hello".partition(1) }
+ def (hyphen = Object.new).to_str; "-"; end
+ assert_equal(%w(foo - bar), "foo-bar".partition(hyphen), '[ruby-core:23540]')
+ end
+
+ def test_rpartition
+ assert_equal(%w(hel l o), "hello".rpartition(/l/))
+ assert_equal(%w(hel l o), "hello".rpartition("l"))
+ assert_raise(TypeError) { "hello".rpartition(1) }
+ def (hyphen = Object.new).to_str; "-"; end
+ assert_equal(%w(foo - bar), "foo-bar".rpartition(hyphen), '[ruby-core:23540]')
+ end
+
+ def test_setter
+ assert_raise(TypeError) { $/ = 1 }
+ end
+
+ def test_to_id
+ c = Class.new
+ c.class_eval do
+ def initialize
+ @foo = :foo
+ end
+ end
+
+ assert_raise(TypeError) do
+ c.class_eval { attr 1 }
+ end
+
+ o = Object.new
+ def o.to_str; :foo; end
+ assert_raise(TypeError) do
+ c.class_eval { attr 1 }
+ end
+
+ def o.to_str; "foo"; end
+ assert_nothing_raised do
+ c.class_eval { attr o }
+ end
+ assert_equal(:foo, c.new.foo)
+ end
+
+ def test_gsub_enumerator
+ skip("[BUG : #___] External Iterator : not supported yet")
+
+ assert_normal_exit %q{"abc".gsub(/./).next}, "[ruby-dev:34828]"
+ end
+
+ def test_clear_nonasciicompat
+ assert_equal("", "\u3042".encode("ISO-2022-JP").clear)
+ end
+
+ def test_try_convert
+ assert_equal(nil, String.try_convert(1))
+ assert_equal("foo", String.try_convert("foo"))
+ end
+
+ def test_substr_negative_begin
+ assert_equal("\u3042", ("\u3042" * 100)[-1])
+ end
+
+ def test_compare_different_encoding_string
+ s1 = "\xff".force_encoding("UTF-8")
+ s2 = "\xff".force_encoding("ISO-2022-JP")
+ #assert_equal([-1, 1], [s1 <=> s2, s2 <=> s1].sort)
+ end
+
+ def test_casecmp
+ assert_equal(1, "\u3042B".casecmp("\u3042a"))
+ end
+
+ def test_upcase2
+ assert_equal("\u3042AB", "\u3042aB".upcase)
+ end
+
+ def test_downcase2
+ assert_equal("\u3042ab", "\u3042aB".downcase)
+ end
+
+ def test_rstrip
+ assert_equal("\u3042", "\u3042 ".rstrip)
+ assert_raise(Encoding::CompatibilityError) { "\u3042".encode("ISO-2022-JP").rstrip }
+ end
+
+ def test_symbol_table_overflow
+ return
+ assert_in_out_err([], <<-INPUT, [], /symbol table overflow \(symbol [a-z]{8}\) \(RuntimeError\)/)
+ ("aaaaaaaa".."zzzzzzzz").each {|s| s.to_sym }
+ INPUT
+ end
+
+ def test_shared_force_encoding
+ s = "\u{3066}\u{3059}\u{3068}".gsub(//, '')
+ h = {}
+ h[s] = nil
+ k = h.keys[0]
+ assert_equal(s, k, '[ruby-dev:39068]')
+ assert_equal(Encoding::UTF_8, k.encoding, '[ruby-dev:39068]')
+ s.dup.force_encoding(Encoding::ASCII_8BIT).gsub(//, '')
+ k = h.keys[0]
+ assert_equal(s, k, '[ruby-dev:39068]')
+ assert_equal(Encoding::UTF_8, k.encoding, '[ruby-dev:39068]')
+ end
+
+ def test_ascii_incomat_inspect
+ [Encoding::UTF_16LE, Encoding::UTF_16BE,
+ Encoding::UTF_32LE, Encoding::UTF_32BE].each do |e|
+ assert_equal('"abc"', "abc".encode(e).inspect)
+ assert_equal('"\\u3042\\u3044\\u3046"', "\u3042\u3044\u3046".encode(e).inspect)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_stringchar.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_stringchar.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_stringchar.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,166 @@
+require 'test/unit'
+
+class TestStringchar < Test::Unit::TestCase
+ def test_string
+ assert_equal("abcd", "abcd")
+ assert_match(/abcd/, "abcd")
+ assert("abcd" === "abcd")
+ # compile time string concatenation
+ assert_equal("abcd", "ab" "cd")
+ assert_equal("22aacd44", "#{22}aa" "cd#{44}")
+ assert_equal("22aacd445566", "#{22}aa" "cd#{44}" "55" "#{66}")
+ assert("abc" !~ /^$/)
+ assert("abc\n" !~ /^$/)
+ assert("abc" !~ /^d*$/)
+ assert_equal(3, ("abc" =~ /d*$/))
+ assert("" =~ /^$/)
+ assert("\n" =~ /^$/)
+ assert("a\n\n" =~ /^$/)
+ assert("abcabc" =~ /.*a/); assert_equal("abca", $&)
+ assert("abcabc" =~ /.*c/); assert_equal("abcabc", $&)
+ assert("abcabc" =~ /.*?a/); assert_equal("a", $&)
+ assert("abcabc" =~ /.*?c/); assert_equal("abc", $&)
+ assert(/(.|\n)*?\n(b|\n)/ =~ "a\nb\n\n"); assert_equal("a\nb", $&)
+
+ assert(/^(ab+)+b/ =~ "ababb"); assert_equal("ababb", $&)
+ assert(/^(?:ab+)+b/ =~ "ababb"); assert_equal("ababb", $&)
+ assert(/^(ab+)+/ =~ "ababb"); assert_equal("ababb", $&)
+ assert(/^(?:ab+)+/ =~ "ababb"); assert_equal("ababb", $&)
+
+ assert(/(\s+\d+){2}/ =~ " 1 2"); assert_equal(" 1 2", $&)
+ assert(/(?:\s+\d+){2}/ =~ " 1 2"); assert_equal(" 1 2", $&)
+
+ $x = <<END;
+ABCD
+ABCD
+END
+ $x.gsub!(/((.|\n)*?)B((.|\n)*?)D/m ,'\1\3')
+ assert_equal("AC\nAC\n", $x)
+
+ assert_match(/foo(?=(bar)|(baz))/, "foobar")
+ assert_match(/foo(?=(bar)|(baz))/, "foobaz")
+
+ $foo = "abc"
+ assert_equal("abc = abc", "#$foo = abc")
+ assert_equal("abc = abc", "#{$foo} = abc")
+
+ foo = "abc"
+ assert_equal("abc = abc", "#{foo} = abc")
+
+ assert_equal('-----', '-' * 5)
+ assert_equal('-', '-' * 1)
+ assert_equal('', '-' * 0)
+
+ foo = '-'
+ assert_equal('-----', foo * 5)
+ assert_equal('-', foo * 1)
+ assert_equal('', foo * 0)
+
+ $x = "a.gif"
+ assert_equal("gif", $x.sub(/.*\.([^\.]+)$/, '\1'))
+ assert_equal("b.gif", $x.sub(/.*\.([^\.]+)$/, 'b.\1'))
+ assert_equal("", $x.sub(/.*\.([^\.]+)$/, '\2'))
+ assert_equal("ab", $x.sub(/.*\.([^\.]+)$/, 'a\2b'))
+ assert_equal("<a.gif>", $x.sub(/.*\.([^\.]+)$/, '<\&>'))
+ end
+
+ def test_char
+ # character constants(assumes ASCII)
+ assert_equal(?a, "a"[0])
+ assert_equal(?a, ?a)
+ assert_equal("\1", ?\C-a)
+ assert_equal("\341", ?\M-a)
+ assert_equal("\201", ?\M-\C-a)
+ assert_equal(?A, "a".upcase![0])
+ assert_equal(?a, "A".downcase![0])
+ assert_equal("ABC", "abc".tr!("a-z", "A-Z"))
+ assert_equal("ABC", "aabbcccc".tr_s!("a-z", "A-Z"))
+ assert_equal("abc", "abcc".squeeze!("a-z"))
+ assert_equal("ad", "abcd".delete!("bc"))
+
+ $x = "abcdef"
+ $y = [ ?a, ?b, ?c, ?d, ?e, ?f ]
+ $bad = false
+ $x.each_byte {|i|
+ if i.chr != $y.shift
+ $bad = true
+ break
+ end
+ }
+ assert(!$bad)
+
+ s = "a string"
+ s[0..s.size]="another string"
+ assert_equal("another string", s)
+
+ s = <<EOS
+#{
+[1,2,3].join(",")
+}
+EOS
+ assert_equal("1,2,3\n", s)
+ assert_equal(926381, "Just".to_i(36))
+ assert_equal(-23200231779, "-another".to_i(36))
+ assert_equal("ruby", 1299022.to_s(36))
+ assert_equal("-hacker", -1045307475.to_s(36))
+ assert_equal(265419172580680477752431643787347, "Just_another_Ruby_hacker".to_i(36))
+ assert_equal("-justanotherrubyhacker", -265419172580680477752431643787347.to_s(36))
+
+ a = []
+ (0..255).each {|n|
+ ch = [n].pack("C")
+ a.push ch if /a#{Regexp.quote ch}b/x =~ "ab"
+ }
+ assert_equal(0, a.size)
+ end
+
+ def test_bang
+ s = "aBc"
+ s.upcase
+ assert_equal("aBc", s)
+ s.upcase!
+ assert_equal("ABC", s)
+
+ s = "aBc"
+ s.downcase
+ assert_equal("aBc", s)
+ s.downcase!
+ assert_equal("abc", s)
+
+ s = "aBc"
+ s.swapcase
+ assert_equal("aBc", s)
+ s.swapcase!
+ assert_equal("AbC", s)
+
+ s = "aBc"
+ s.capitalize
+ assert_equal("aBc", s)
+ s.capitalize!
+ assert_equal("Abc", s)
+
+ s = "aBc"
+ s.tr("a-z", "A-Z")
+ assert_equal("aBc", s)
+ s.tr!("a-z", "A-Z")
+ assert_equal("ABC", s)
+
+ s = "aaBBcc"
+ s.tr_s("a-z", "A-Z")
+ assert_equal("aaBBcc", s)
+ s.tr_s!("a-z", "A-Z")
+ assert_equal("ABBC", s)
+
+ s = "aaBBcc"
+ s.squeeze("a-z")
+ assert_equal("aaBBcc", s)
+ s.squeeze!("a-z")
+ assert_equal("aBBc", s)
+
+ s = "aaBBcc"
+ s.delete("a-z")
+ assert_equal("aaBBcc", s)
+ s.delete!("a-z")
+ assert_equal("BB", s)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_struct.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_struct.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_struct.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,252 @@
+require 'test/unit'
+require 'timeout'
+
+class TestStruct < Test::Unit::TestCase
+ def test_struct
+ struct_test = Struct.new("Test", :foo, :bar)
+ assert_equal(Struct::Test, struct_test)
+
+ test = struct_test.new(1, 2)
+ assert_equal(1, test.foo)
+ assert_equal(2, test.bar)
+ assert_equal(1, test[0])
+ assert_equal(2, test[1])
+
+ a, b = test.to_a
+ assert_equal(1, a)
+ assert_equal(2, b)
+
+ test[0] = 22
+ assert_equal(22, test.foo)
+
+ test.bar = 47
+ assert_equal(47, test.bar)
+ end
+
+ # [ruby-dev:26247] more than 10 struct members causes segmentation fault
+ def test_morethan10members
+ list = %w( a b c d e f g h i j k l m n o p )
+ until list.empty?
+ c = Struct.new(* list.map {|ch| ch.intern }).new
+ list.each do |ch|
+ c.__send__(ch)
+ end
+ list.pop
+ end
+ end
+
+ def test_small_structs
+ names = [:a, :b, :c, :d]
+ 1.upto(4) {|n|
+ fields = names[0, n]
+ klass = Struct.new(*fields)
+ o = klass.new(*(0...n).to_a)
+ fields.each_with_index {|name, i|
+ assert_equal(i, o[name])
+ }
+ o = klass.new(*(0...n).to_a.reverse)
+ fields.each_with_index {|name, i|
+ assert_equal(n-i-1, o[name])
+ }
+ }
+ end
+
+ def test_inherit
+ klass = Struct.new(:a)
+ klass2 = Class.new(klass)
+ o = klass2.new(1)
+ assert_equal(1, o.a)
+ end
+
+ def test_members
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_equal([:a], klass.members)
+ assert_equal([:a], o.members)
+ end
+
+ def test_ref
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_equal(1, o[:a])
+ assert_raise(NameError) { o[:b] }
+ end
+
+ def test_modify
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ o.a = 2
+ end.value
+ end
+ end
+
+ def test_set
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ o[:a] = 2
+ assert_equal(2, o[:a])
+ assert_raise(NameError) { o[:b] = 3 }
+ end
+
+ def test_struct_new
+ assert_raise(NameError) { Struct.new("foo") }
+ assert_nothing_raised { Struct.new("Foo") }
+ Struct.instance_eval { remove_const(:Foo) }
+ assert_nothing_raised { Struct.new(:a) { } }
+ assert_raise(RuntimeError) { Struct.new(:a) { raise } }
+
+ assert_equal([:utime, :stime, :cutime, :cstime], Process.times.members)
+ end
+
+ def test_initialize
+ klass = Struct.new(:a)
+ assert_raise(ArgumentError) { klass.new(1, 2) }
+ end
+
+ def test_each
+ klass = Struct.new(:a, :b)
+ o = klass.new(1, 2)
+ assert_equal([1, 2], o.each.to_a)
+ end
+
+ def test_each_pair
+ klass = Struct.new(:a, :b)
+ o = klass.new(1, 2)
+ assert_equal([[:a, 1], [:b, 2]], o.each_pair.to_a)
+ end
+
+ def test_inspect
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_equal("#<struct a=1>", o.inspect)
+ o.a = o
+ assert_match(/^#<struct a=#<struct #<.*?>:...>>$/, o.inspect)
+
+ Struct.new("Foo", :a)
+ o = Struct::Foo.new(1)
+ assert_equal("#<struct Struct::Foo a=1>", o.inspect)
+ Struct.instance_eval { remove_const(:Foo) }
+
+ klass = Struct.new(:a, :b)
+ o = klass.new(1, 2)
+ assert_equal("#<struct a=1, b=2>", o.inspect)
+
+ klass = Struct.new(:@a)
+ o = klass.new(1)
+ assert_equal("#<struct :@a=1>", o.inspect)
+ end
+
+ def test_init_copy
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_equal(o, o.dup)
+ end
+
+ def test_aref
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_equal(1, o[0])
+ assert_raise(IndexError) { o[-2] }
+ assert_raise(IndexError) { o[1] }
+ end
+
+ def test_aset
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ o[0] = 2
+ assert_equal(2, o[:a])
+ assert_raise(IndexError) { o[-2] = 3 }
+ assert_raise(IndexError) { o[1] = 3 }
+ end
+
+ def test_values_at
+ klass = Struct.new(:a, :b, :c, :d, :e, :f)
+ o = klass.new(1, 2, 3, 4, 5, 6)
+ assert_equal([2, 4, 6], o.values_at(1, 3, 5))
+ assert_equal([2, 3, 4, 3, 4, 5], o.values_at(1..3, 2...5))
+ end
+
+ def test_select
+ klass = Struct.new(:a, :b, :c, :d, :e, :f)
+ o = klass.new(1, 2, 3, 4, 5, 6)
+ assert_equal([1, 3, 5], o.select {|v| v % 2 != 0 })
+ assert_raise(ArgumentError) { o.select(1) }
+ end
+
+ def test_equal
+ klass1 = Struct.new(:a)
+ klass2 = Struct.new(:a, :b)
+ o1 = klass1.new(1)
+ o2 = klass1.new(1)
+ o3 = klass2.new(1)
+ assert(o1.==(o2))
+ assert(o1 != o3)
+ end
+
+ def test_hash
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert(o.hash.is_a?(Fixnum))
+ end
+
+ def test_eql
+ klass1 = Struct.new(:a)
+ klass2 = Struct.new(:a, :b)
+ o1 = klass1.new(1)
+ o2 = klass1.new(1)
+ o3 = klass2.new(1)
+ assert(o1.eql?(o2))
+ assert(!(o1.eql?(o3)))
+ end
+
+ def test_size
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_equal(1, o.size)
+ end
+
+ def test_error
+ assert_raise(TypeError){
+ Struct.new(0)
+ }
+ end
+
+ def test_nonascii
+ struct_test = Struct.new("R\u{e9}sum\u{e9}", :"r\u{e9}sum\u{e9}")
+ assert_equal(Struct.const_get("R\u{e9}sum\u{e9}"), struct_test, '[ruby-core:24849]')
+ a = struct_test.new(42)
+ assert_equal("#<struct Struct::R\u{e9}sum\u{e9} r\u{e9}sum\u{e9}=42>", a.inspect, '[ruby-core:24849]')
+ end
+
+ def test_comparison_when_recursive
+ klass1 = Struct.new(:a, :b, :c)
+
+ x = klass1.new(1, 2, nil); x.c = x
+ y = klass1.new(1, 2, nil); y.c = y
+ Timeout.timeout(1) {
+ assert x == y
+ assert x.eql? y
+ }
+
+ z = klass1.new(:something, :other, nil); z.c = z
+ Timeout.timeout(1) {
+ assert x != z
+ assert !x.eql?(z)
+ }
+
+ x.c = y; y.c = x
+ Timeout.timeout(1) {
+ assert x == y
+ assert x.eql?(y)
+ }
+
+ x.c = z; z.c = x
+ Timeout.timeout(1) {
+ assert x != z
+ assert !x.eql?(z)
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_super.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_super.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_super.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,142 @@
+require 'test/unit'
+
+class TestSuper < Test::Unit::TestCase
+ class Base
+ def single(a) a end
+ def double(a, b) [a,b] end
+ def array(*a) a end
+ def optional(a = 0) a end
+ end
+ class Single1 < Base
+ def single(*) super end
+ end
+ class Single2 < Base
+ def single(a,*) super end
+ end
+ class Double1 < Base
+ def double(*) super end
+ end
+ class Double2 < Base
+ def double(a,*) super end
+ end
+ class Double3 < Base
+ def double(a,b,*) super end
+ end
+ class Array1 < Base
+ def array(*) super end
+ end
+ class Array2 < Base
+ def array(a,*) super end
+ end
+ class Array3 < Base
+ def array(a,b,*) super end
+ end
+ class Array4 < Base
+ def array(a,b,c,*) super end
+ end
+ class Optional1 < Base
+ def optional(a = 1) super end
+ end
+ class Optional2 < Base
+ def optional(a, b = 1) super end
+ end
+ class Optional3 < Base
+ def single(a = 1) super end
+ end
+ class Optional4 < Base
+ def array(a = 1, *) super end
+ end
+ class Optional5 < Base
+ def array(a = 1, b = 2, *) super end
+ end
+
+ def test_single1
+ assert_equal(1, Single1.new.single(1))
+ end
+ def test_single2
+ assert_equal(1, Single2.new.single(1))
+ end
+ def test_double1
+ assert_equal([1, 2], Double1.new.double(1, 2))
+ end
+ def test_double2
+ assert_equal([1, 2], Double2.new.double(1, 2))
+ end
+ def test_double3
+ assert_equal([1, 2], Double3.new.double(1, 2))
+ end
+ def test_array1
+ assert_equal([], Array1.new.array())
+ assert_equal([1], Array1.new.array(1))
+ end
+ def test_array2
+ assert_equal([1], Array2.new.array(1))
+ assert_equal([1,2], Array2.new.array(1, 2))
+ end
+ def test_array3
+ assert_equal([1,2], Array3.new.array(1, 2))
+ assert_equal([1,2,3], Array3.new.array(1, 2, 3))
+ end
+ def test_array4
+ assert_equal([1,2,3], Array4.new.array(1, 2, 3))
+ assert_equal([1,2,3,4], Array4.new.array(1, 2, 3, 4))
+ end
+ def test_optional1
+ assert_equal(9, Optional1.new.optional(9))
+ assert_equal(1, Optional1.new.optional)
+ end
+ def test_optional2
+ assert_raise(ArgumentError) do
+ # call Base#optional with 2 arguments; the 2nd arg is supplied
+ assert_equal(9, Optional2.new.optional(9))
+ end
+ assert_raise(ArgumentError) do
+ # call Base#optional with 2 arguments
+ assert_equal(9, Optional2.new.optional(9, 2))
+ end
+ end
+ def test_optional3
+ assert_equal(9, Optional3.new.single(9))
+ # call Base#single with 1 argument; the arg is supplied
+ assert_equal(1, Optional3.new.single)
+ end
+ def test_optional4
+ assert_equal([1], Optional4.new.array)
+ assert_equal([9], Optional4.new.array(9))
+ assert_equal([9, 8], Optional4.new.array(9, 8))
+ end
+ def test_optional5
+ assert_equal([1, 2], Optional5.new.array)
+ assert_equal([9, 2], Optional5.new.array(9))
+ assert_equal([9, 8], Optional5.new.array(9, 8))
+ assert_equal([9, 8, 7], Optional5.new.array(9, 8, 7))
+ end
+
+ class A
+ def tt(aa)
+ "A#tt"
+ end
+
+ def uu(a)
+ class << self
+ define_method(:tt) do |sym|
+ super(sym)
+ end
+ end
+ end
+ end
+
+ def test_define_method
+ a = A.new
+ a.uu(12)
+ assert_equal("A#tt", a.tt(12), "[ruby-core:3856]")
+ e = assert_raise(RuntimeError, "[ruby-core:24244]") {
+ lambda {
+ Class.new do
+ define_method(:a) {super}.call
+ end
+ }.call
+ }
+ assert_match(/implicit argument passing of super from method defined by define_method/, e.message)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_symbol.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_symbol.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_symbol.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,147 @@
+require 'test/unit'
+
+class TestSymbol < Test::Unit::TestCase
+ # [ruby-core:3573]
+
+ def assert_eval_inspected(sym)
+ n = sym.inspect
+ assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(n))}
+ end
+
+ def test_inspect_invalid
+ # 2) Symbol#inspect sometimes returns invalid symbol representations:
+ assert_eval_inspected(:"!")
+ assert_eval_inspected(:"=")
+ assert_eval_inspected(:"0")
+ assert_eval_inspected(:"$1")
+ assert_eval_inspected(:"@1")
+ assert_eval_inspected(:"@@1")
+ assert_eval_inspected(:"@")
+ assert_eval_inspected(:"@@")
+ end
+
+ def assert_inspect_evaled(n)
+ assert_nothing_raised(SyntaxError) {assert_equal(n, eval(n).inspect)}
+ end
+
+ def test_inspect_suboptimal
+ # 3) Symbol#inspect sometimes returns suboptimal symbol representations:
+ assert_inspect_evaled(':foo')
+ assert_inspect_evaled(':foo!')
+ assert_inspect_evaled(':bar?')
+ assert_inspect_evaled(':<<')
+ assert_inspect_evaled(':>>')
+ assert_inspect_evaled(':<=')
+ assert_inspect_evaled(':>=')
+ assert_inspect_evaled(':=~')
+ assert_inspect_evaled(':==')
+ assert_inspect_evaled(':===')
+ assert_raise(SyntaxError) {eval ':='}
+ assert_inspect_evaled(':*')
+ assert_inspect_evaled(':**')
+ assert_raise(SyntaxError) {eval ':***'}
+ assert_inspect_evaled(':+')
+ assert_inspect_evaled(':-')
+ assert_inspect_evaled(':+@')
+ assert_inspect_evaled(':-@')
+ assert_inspect_evaled(':|')
+ assert_inspect_evaled(':^')
+ assert_inspect_evaled(':&')
+ assert_inspect_evaled(':/')
+ assert_inspect_evaled(':%')
+ assert_inspect_evaled(':~')
+ assert_inspect_evaled(':`')
+ assert_inspect_evaled(':[]')
+ assert_inspect_evaled(':[]=')
+ assert_raise(SyntaxError) {eval ':||'}
+ assert_raise(SyntaxError) {eval ':&&'}
+ assert_raise(SyntaxError) {eval ':['}
+ end
+
+ def test_inspect_dollar
+ # 4) :$- always treats next character literally:
+ sym = "$-".intern
+ assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(':$-'))}
+ assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(":$-\n"))}
+ assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(":$- "))}
+ assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(":$-#"))}
+ assert_raise(SyntaxError) {eval ':$-('}
+ end
+
+ def test_inspect_number
+ # 5) Inconsistency between :$0 and :$1? The first one is valid, but the
+ # latter isn't.
+ assert_inspect_evaled(':$0')
+ assert_inspect_evaled(':$1')
+ end
+
+ def test_to_proc
+ assert_equal %w(1 2 3), (1..3).map(&:to_s)
+ [
+ [],
+ [1],
+ [1, 2],
+ [1, [2, 3]],
+ ].each do |ary|
+ ary_id = ary.object_id
+ assert_equal ary_id, :object_id.to_proc.call(ary)
+ ary_ids = ary.collect{|x| x.object_id }
+ assert_equal ary_ids, ary.collect(&:object_id)
+ end
+ end
+
+ def test_call
+ o = Object.new
+ def o.foo(x, y); x + y; end
+
+ assert_equal(3, :foo.to_proc.call(o, 1, 2))
+ assert_raise(ArgumentError) { :foo.to_proc.call }
+ end
+
+ def test_succ
+ assert_equal(:fop, :foo.succ)
+ end
+
+ def test_cmp
+ assert_equal(0, :FoO <=> :FoO)
+ assert_equal(-1, :FoO <=> :fOO)
+ assert_equal(1, :fOO <=> :FoO)
+ assert_nil(:foo <=> "foo")
+ end
+
+ def test_casecmp
+ assert_equal(0, :FoO.casecmp(:fOO))
+ assert_equal(1, :FoO.casecmp(:BaR))
+ assert_equal(-1, :baR.casecmp(:FoO))
+ assert_nil(:foo.casecmp("foo"))
+ end
+
+ def test_length
+ assert_equal(3, :FoO.length)
+ assert_equal(3, :FoO.size)
+ end
+
+ def test_empty
+ assert_equal(false, :FoO.empty?)
+ assert_equal(true, :"".empty?)
+ end
+
+ def test_case
+ assert_equal(:FOO, :FoO.upcase)
+ assert_equal(:foo, :FoO.downcase)
+ assert_equal(:Foo, :foo.capitalize)
+ assert_equal(:fOo, :FoO.swapcase)
+ end
+
+ def test_symbol_poped
+ assert_nothing_raised { eval('a = 1; :"#{ a }"; 1') }
+ end
+
+ def test_ascii_incomat_inspect
+ [Encoding::UTF_16LE, Encoding::UTF_16BE,
+ Encoding::UTF_32LE, Encoding::UTF_32BE].each do |e|
+ assert_equal(':"abc"', "abc".encode(e).to_sym.inspect)
+ assert_equal(':"\\u3042\\u3044\\u3046"', "\u3042\u3044\u3046".encode(e).to_sym.inspect)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_system.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_system.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_system.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,113 @@
+require 'test/unit'
+require 'tmpdir'
+require_relative 'envutil'
+
+class TestSystem < Test::Unit::TestCase
+ def valid_syntax?(code, fname)
+ code = code.dup.force_encoding("ascii-8bit")
+ code.sub!(/\A(?:\xef\xbb\xbf)?(\s*\#.*$)*(\n)?/n) {
+ "#$&#{"\n" if $1 && !$2}BEGIN{throw tag, :ok}\n"
+ }
+ code.force_encoding("us-ascii")
+ catch {|tag| eval(code, binding, fname, 0)}
+ rescue SyntaxError
+ false
+ end
+
+ def test_system
+ ruby = EnvUtil.rubybin
+ assert_equal("foobar\n", `echo foobar`)
+ assert_equal('foobar', `#{ruby} -e 'print "foobar"'`)
+
+ Dir.mktmpdir("ruby_script_tmp") {|tmpdir|
+ tmpfilename = "#{tmpdir}/ruby_script_tmp.#{$$}"
+
+ tmp = open(tmpfilename, "w")
+ tmp.print "print $zzz\n";
+ tmp.close
+
+ assert_equal('true', `#{ruby} -s #{tmpfilename} -zzz`)
+ assert_equal('555', `#{ruby} -s #{tmpfilename} -zzz=555`)
+
+ tmp = open(tmpfilename, "w")
+ tmp.print "#! /usr/local/bin/ruby -s\n";
+ tmp.print "print $zzz\n";
+ tmp.close
+
+ assert_equal('678', `#{ruby} #{tmpfilename} -zzz=678`)
+
+ tmp = open(tmpfilename, "w")
+ tmp.print "this is a leading junk\n";
+ tmp.print "#! /usr/local/bin/ruby -s\n";
+ tmp.print "print $zzz if defined? $zzz\n";
+ tmp.print "__END__\n";
+ tmp.print "this is a trailing junk\n";
+ tmp.close
+
+ assert_equal('', `#{ruby} -x #{tmpfilename}`)
+ assert_equal('555', `#{ruby} -x #{tmpfilename} -zzz=555`)
+
+ tmp = open(tmpfilename, "w")
+ tmp.print "#! /non/exist\\interpreter?/./to|be:ignored\n";
+ tmp.print "this is a leading junk\n";
+ tmp.print "#! /usr/local/bin/ruby -s\n";
+ tmp.print "print $zzz if defined? $zzz\n";
+ tmp.print "__END__\n";
+ tmp.print "this is a trailing junk\n";
+ tmp.close
+
+ assert_equal('', `#{ruby} #{tmpfilename}`)
+ assert_equal('555', `#{ruby} #{tmpfilename} -zzz=555`)
+
+ tmp = open(tmpfilename, "w")
+ for i in 1..5
+ tmp.print i, "\n"
+ end
+ tmp.close
+
+ `#{ruby} -i.bak -pe '$_.sub!(/^[0-9]+$/){$&.to_i * 5}' #{tmpfilename}`
+ tmp = open(tmpfilename, "r")
+ while tmp.gets
+ assert_equal(0, $_.to_i % 5)
+ end
+ tmp.close
+
+ File.unlink tmpfilename or `/bin/rm -f "#{tmpfilename}"`
+ File.unlink "#{tmpfilename}.bak" or `/bin/rm -f "#{tmpfilename}.bak"`
+
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ testname = '[ruby-dev:38588]'
+ batch = "batch_tmp.#{$$}"
+ tmpfilename = "#{tmpdir}/#{batch}.bat"
+ open(tmpfilename, "wb") {|f| f.print "\r\n"}
+ assert(system(tmpfilename), testname)
+ assert(system("#{tmpdir}/#{batch}"), testname)
+ assert(system(tmpfilename, "1"), testname)
+ assert(system("#{tmpdir}/#{batch}", "1"), testname)
+ begin
+ path = ENV["PATH"]
+ ENV["PATH"] = "#{tmpdir.tr(File::SEPARATOR, File::ALT_SEPARATOR)}#{File::PATH_SEPARATOR + path if path}"
+ assert(system("#{batch}.bat"), testname)
+ assert(system(batch), testname)
+ assert(system("#{batch}.bat", "1"), testname)
+ assert(system(batch, "1"), testname)
+ ensure
+ ENV["PATH"] = path
+ end
+ File.unlink tmpfilename
+ end
+ }
+ end
+
+ def test_syntax
+ assert_nothing_raised(Exception) do
+ for script in Dir[File.expand_path("../../../{lib,sample,ext}/**/*.rb", __FILE__)]
+ valid_syntax? IO::read(script), script
+ end
+ end
+ end
+
+ def test_empty_evstr
+ assert_equal("", eval('"#{}"', nil, __FILE__, __LINE__), "[ruby-dev:25113]")
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_thread.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_thread.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_thread.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,539 @@
+require 'test/unit'
+require 'thread'
+require_relative 'envutil'
+
+class TestThread < Test::Unit::TestCase
+ class Thread < ::Thread
+ Threads = []
+ def self.new(*)
+ th = super
+ th.abort_on_exception = true
+ Threads << th
+ th
+ end
+ end
+
+ def setup
+ Thread::Threads.clear
+ end
+
+ def teardown
+ Thread::Threads.each do |t|
+ t.kill if t.alive?
+ begin
+ t.join
+ rescue Exception
+ end
+ end
+ end
+
+ def test_mutex_synchronize
+ m = Mutex.new
+ r = 0
+ max = 10
+ (1..max).map{
+ Thread.new{
+ i=0
+ while i<max*max
+ i+=1
+ m.synchronize{
+ r += 1
+ }
+ end
+ }
+ }.each{|e|
+ e.join
+ }
+ assert_equal(max * max * max, r)
+ end
+
+ def test_condvar
+ mutex = Mutex.new
+ condvar = ConditionVariable.new
+ result = []
+ mutex.synchronize do
+ t = Thread.new do
+ mutex.synchronize do
+ result << 1
+ condvar.signal
+ end
+ end
+
+ result << 0
+ condvar.wait(mutex)
+ result << 2
+ t.join
+ end
+ assert_equal([0, 1, 2], result)
+ end
+
+ def test_condvar_wait_not_owner
+ mutex = Mutex.new
+ condvar = ConditionVariable.new
+
+ assert_raise(ThreadError) { condvar.wait(mutex) }
+ end
+
+ def test_condvar_wait_exception_handling
+ # Calling wait in the only thread running should raise a ThreadError of
+ # 'stopping only thread'
+ mutex = Mutex.new
+ condvar = ConditionVariable.new
+
+ locked = false
+ thread = Thread.new do
+ Thread.current.abort_on_exception = false
+ mutex.synchronize do
+ begin
+ condvar.wait(mutex)
+ rescue Exception
+ locked = mutex.locked?
+ raise
+ end
+ end
+ end
+
+ until thread.stop?
+ sleep(0.1)
+ end
+
+ thread.raise Interrupt, "interrupt a dead condition variable"
+ assert_raise(Interrupt) { thread.value }
+ assert(locked)
+ end
+
+ def test_local_barrier
+ dir = File.dirname(__FILE__)
+ lbtest = File.join(dir, "lbtest.rb")
+ $:.unshift File.join(File.dirname(dir), 'ruby')
+ require 'envutil'
+ $:.shift
+ 3.times {
+ result = `#{EnvUtil.rubybin} #{lbtest}`
+ assert(!$?.coredump?, '[ruby-dev:30653]')
+ assert_equal("exit.", result[/.*\Z/], '[ruby-dev:30653]')
+ }
+ end
+
+ def test_priority
+ c1 = c2 = 0
+ t1 = Thread.new { loop { c1 += 1 } }
+ t1.priority = -1
+ t2 = Thread.new { loop { c2 += 1 } }
+ t2.priority = -3
+ assert_equal(-1, t1.priority)
+ assert_equal(-3, t2.priority)
+ sleep 0.5
+ 5.times do
+ break if c1 > c2
+ sleep 0.1
+ end
+ t1.kill
+ t2.kill
+ # assert_operator(c1, :>, c2, "[ruby-dev:33124]") # not guaranteed
+ end
+
+ def test_new
+ assert_raise(ThreadError) do
+ Thread.new
+ end
+
+ t1 = Thread.new { sleep }
+ assert_raise(ThreadError) do
+ t1.instance_eval { initialize { } }
+ end
+
+ t2 = Thread.new(&method(:sleep).to_proc)
+ assert_raise(ThreadError) do
+ t2.instance_eval { initialize { } }
+ end
+
+ ensure
+ t1.kill if t1
+ t2.kill if t2
+ end
+
+ def test_join
+ t = Thread.new { sleep }
+ assert_nil(t.join(0.5))
+
+ ensure
+ t.kill if t
+ end
+
+ def test_join2
+ t1 = Thread.new { sleep(1.5) }
+ t2 = Thread.new do
+ t1.join(1)
+ end
+ t3 = Thread.new do
+ sleep 0.5
+ t1.join
+ end
+ assert_nil(t2.value)
+ assert_equal(t1, t3.value)
+
+ ensure
+ t1.kill if t1
+ t2.kill if t2
+ t3.kill if t3
+ end
+
+ def test_kill_main_thread
+ assert_in_out_err([], <<-INPUT, %w(1), [])
+ p 1
+ Thread.kill Thread.current
+ p 2
+ INPUT
+ end
+
+ def test_exit
+ s = 0
+ Thread.new do
+ s += 1
+ Thread.exit
+ s += 2
+ end.join
+ assert_equal(1, s)
+ end
+
+ def test_wakeup
+ s = 0
+ t = Thread.new do
+ s += 1
+ Thread.stop
+ s += 1
+ end
+ sleep 0.5
+ assert_equal(1, s)
+ t.wakeup
+ sleep 0.5
+ assert_equal(2, s)
+ assert_raise(ThreadError) { t.wakeup }
+
+ ensure
+ t.kill if t
+ end
+
+ def test_stop
+ assert_in_out_err([], <<-INPUT, %w(2), [])
+ begin
+ Thread.stop
+ p 1
+ rescue ThreadError
+ p 2
+ end
+ INPUT
+ end
+
+ def test_list
+ assert_in_out_err([], <<-INPUT) do |r, e|
+ t1 = Thread.new { sleep }
+ Thread.pass
+ t2 = Thread.new { loop { } }
+ t3 = Thread.new { }.join
+ p [Thread.current, t1, t2].map{|t| t.object_id }.sort
+ p Thread.list.map{|t| t.object_id }.sort
+ INPUT
+ assert_equal(r.first, r.last)
+ assert_equal([], e)
+ end
+ end
+
+ def test_main
+ assert_in_out_err([], <<-INPUT, %w(true false), [])
+ p Thread.main == Thread.current
+ Thread.new { p Thread.main == Thread.current }.join
+ INPUT
+ end
+
+ def test_abort_on_exception
+ assert_in_out_err([], <<-INPUT, %w(false 1), [])
+ p Thread.abort_on_exception
+ begin
+ Thread.new { raise }
+ sleep 0.5
+ p 1
+ rescue
+ p 2
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(true 2), [])
+ Thread.abort_on_exception = true
+ p Thread.abort_on_exception
+ begin
+ Thread.new { raise }
+ sleep 0.5
+ p 1
+ rescue
+ p 2
+ end
+ INPUT
+
+ assert_in_out_err(%w(-d), <<-INPUT, %w(false 2), /.+/)
+ p Thread.abort_on_exception
+ begin
+ Thread.new { raise }
+ sleep 0.5
+ p 1
+ rescue
+ p 2
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(false true 2), [])
+ p Thread.abort_on_exception
+ begin
+ t = Thread.new { sleep 0.5; raise }
+ t.abort_on_exception = true
+ p t.abort_on_exception
+ sleep 1
+ p 1
+ rescue
+ p 2
+ end
+ INPUT
+ end
+
+ def test_status_and_stop_p
+ a = ::Thread.new { raise("die now") }
+ b = Thread.new { Thread.stop }
+ c = Thread.new { Thread.exit }
+ d = Thread.new { sleep }
+ e = Thread.current
+ sleep 0.5
+
+ assert_equal(nil, a.status)
+ assert(a.stop?)
+
+ assert_equal("sleep", b.status)
+ assert(b.stop?)
+
+ assert_equal(false, c.status)
+ assert_match(/^#<TestThread::Thread:.* dead>$/, c.inspect)
+ assert(c.stop?)
+
+ d.kill
+ assert_equal(["aborting", false], [d.status, d.stop?])
+
+ assert_equal(["run", false], [e.status, e.stop?])
+
+ ensure
+ a.kill if a
+ b.kill if b
+ c.kill if c
+ d.kill if d
+ end
+
+ def test_safe_level
+ t = Thread.new { $SAFE = 3; sleep }
+ sleep 0.5
+ assert_equal(0, Thread.current.safe_level)
+ assert_equal(3, t.safe_level)
+
+ ensure
+ t.kill if t
+ end
+
+ def test_thread_local
+ t = Thread.new { sleep }
+
+ assert_equal(false, t.key?(:foo))
+
+ t["foo"] = "foo"
+ t["bar"] = "bar"
+ t["baz"] = "baz"
+
+ assert_equal(true, t.key?(:foo))
+ assert_equal(true, t.key?("foo"))
+ assert_equal(false, t.key?(:qux))
+ assert_equal(false, t.key?("qux"))
+
+ assert_equal([:foo, :bar, :baz], t.keys)
+
+ ensure
+ t.kill if t
+ end
+
+ def test_thread_local_security
+ skip("[BUG : #842] SecurityError Level 4")
+
+ t = Thread.new { sleep }
+
+ assert_raise(SecurityError) do
+ Thread.new { $SAFE = 4; t[:foo] }.join
+ end
+
+ assert_raise(SecurityError) do
+ Thread.new { $SAFE = 4; t[:foo] = :baz }.join
+ end
+
+ assert_raise(RuntimeError) do
+ Thread.new do
+ Thread.current[:foo] = :bar
+ Thread.current.freeze
+ Thread.current[:foo] = :baz
+ end.join
+ end
+ end
+
+ def test_select_wait
+ assert_nil(IO.select(nil, nil, nil, 1))
+ t = Thread.new do
+ IO.select(nil, nil, nil, nil)
+ end
+ sleep 0.5
+ t.kill
+ end
+
+ def test_mutex_deadlock
+ m = Mutex.new
+ m.synchronize do
+ assert_raise(ThreadError) do
+ m.synchronize do
+ assert(false)
+ end
+ end
+ end
+ end
+
+ def test_mutex_interrupt
+ m = Mutex.new
+ m.lock
+ t = Thread.new do
+ m.lock
+ :foo
+ end
+ sleep 0.5
+ t.kill
+ assert_nil(t.value)
+ end
+
+ def test_mutex_illegal_unlock
+ m = Mutex.new
+ m.lock
+ assert_raise(ThreadError) do
+ Thread.new do
+ m.unlock
+ end.join
+ end
+ end
+
+ def test_mutex_fifo_like_lock
+ m1 = Mutex.new
+ m2 = Mutex.new
+ m1.lock
+ m2.lock
+ m1.unlock
+ m2.unlock
+ assert_equal(false, m1.locked?)
+ assert_equal(false, m2.locked?)
+
+ m3 = Mutex.new
+ m1.lock
+ m2.lock
+ m3.lock
+ m1.unlock
+ m2.unlock
+ m3.unlock
+ assert_equal(false, m1.locked?)
+ assert_equal(false, m2.locked?)
+ assert_equal(false, m3.locked?)
+ end
+
+ def test_mutex_trylock
+ m = Mutex.new
+ assert_equal(true, m.try_lock)
+ assert_equal(false, m.try_lock, '[ruby-core:20943]')
+
+ Thread.new{
+ assert_equal(false, m.try_lock)
+ }.join
+
+ m.unlock
+ end
+
+ def test_recursive_outer
+ arr = []
+ obj = Struct.new(:foo, :visited).new(arr, false)
+ arr << obj
+ def obj.hash
+ self[:visited] = true
+ super
+ raise "recursive_outer should short circuit intermediate calls"
+ end
+ assert_nothing_raised {arr.hash}
+ assert(obj[:visited])
+ end
+end
+
+class TestThreadGroup < Test::Unit::TestCase
+ def test_thread_init
+ thgrp = ThreadGroup.new
+ Thread.new{
+ thgrp.add(Thread.current)
+ assert_equal(thgrp, Thread.new{sleep 1}.group)
+ }.join
+ end
+
+ def test_frozen_thgroup
+ skip("[BUG : #???] Assertion")
+
+ thgrp = ThreadGroup.new
+
+ t = Thread.new{1}
+ Thread.new{
+ thgrp.add(Thread.current)
+ thgrp.freeze
+ assert_raise(ThreadError) do
+ Thread.new{1}.join
+ end
+ assert_raise(ThreadError) do
+ thgrp.add(t)
+ end
+ assert_raise(ThreadError) do
+ ThreadGroup.new.add Thread.current
+ end
+ }.join
+ t.join
+ end
+
+ def test_enclosed_thgroup
+ thgrp = ThreadGroup.new
+ assert_equal(false, thgrp.enclosed?)
+
+ t = Thread.new{1}
+ Thread.new{
+ thgrp.add(Thread.current)
+ thgrp.enclose
+ assert_equal(true, thgrp.enclosed?)
+ assert_nothing_raised do
+ Thread.new{1}.join
+ end
+ assert_raise(ThreadError) do
+ thgrp.add t
+ end
+ assert_raise(ThreadError) do
+ ThreadGroup.new.add Thread.current
+ end
+ }.join
+ t.join
+ end
+
+ def test_uninitialized
+ c = Class.new(Thread)
+ c.class_eval { def initialize; end }
+ assert_raise(ThreadError) { c.new.start }
+ end
+
+ def test_backtrace
+ Thread.new{
+ assert_equal(Array, Thread.main.backtrace.class)
+ }.join
+
+ t = Thread.new{}
+ t.join
+ assert_equal(nil, t.backtrace)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_time.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_time.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_time.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,679 @@
+require 'test/unit'
+require 'rational'
+require 'delegate'
+require 'timeout'
+require 'delegate'
+
+class TestTime < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_new
+ assert_equal(Time.utc(2000,2,10), Time.new(2000,2,10, 11,0,0, 3600*11))
+ assert_equal(Time.utc(2000,2,10), Time.new(2000,2,9, 13,0,0, -3600*11))
+ assert_equal(Time.utc(2000,2,10), Time.new(2000,2,10, 11,0,0, "+11:00"))
+ assert_equal(Rational(1,2), Time.new(2000,2,10, 11,0,5.5, "+11:00").subsec)
+ end
+
+ def test_time_add()
+ assert_equal(Time.utc(2000, 3, 21, 3, 30) + 3 * 3600,
+ Time.utc(2000, 3, 21, 6, 30))
+ assert_equal(Time.utc(2000, 3, 21, 3, 30) + (-3 * 3600),
+ Time.utc(2000, 3, 21, 0, 30))
+ assert_equal(0, (Time.at(1.1) + 0.9).usec)
+
+ assert((Time.utc(2000, 4, 1) + 24).utc?)
+ assert(!(Time.local(2000, 4, 1) + 24).utc?)
+
+ t = Time.new(2000, 4, 1, 0, 0, 0, "+01:00") + 24
+ assert(!t.utc?)
+ assert_equal(3600, t.utc_offset)
+ t = Time.new(2000, 4, 1, 0, 0, 0, "+02:00") + 24
+ assert(!t.utc?)
+ assert_equal(7200, t.utc_offset)
+ end
+
+ def test_time_subt()
+ assert_equal(Time.utc(2000, 3, 21, 3, 30) - 3 * 3600,
+ Time.utc(2000, 3, 21, 0, 30))
+ assert_equal(Time.utc(2000, 3, 21, 3, 30) - (-3 * 3600),
+ Time.utc(2000, 3, 21, 6, 30))
+ assert_equal(900000, (Time.at(1.1) - 0.2).usec)
+ end
+
+ def test_time_time()
+ assert_equal(Time.utc(2000, 3, 21, 3, 30) \
+ -Time.utc(2000, 3, 21, 0, 30), 3*3600)
+ assert_equal(Time.utc(2000, 3, 21, 0, 30) \
+ -Time.utc(2000, 3, 21, 3, 30), -3*3600)
+ end
+
+ def negative_time_t?
+ begin
+ Time.at(-1)
+ true
+ rescue ArgumentError
+ false
+ end
+ end
+
+ def test_timegm
+ if negative_time_t?
+ assert_equal(-0x80000000, Time.utc(1901, 12, 13, 20, 45, 52).tv_sec)
+ assert_equal(-2, Time.utc(1969, 12, 31, 23, 59, 58).tv_sec)
+ assert_equal(-1, Time.utc(1969, 12, 31, 23, 59, 59).tv_sec)
+ end
+
+ assert_equal(0, Time.utc(1970, 1, 1, 0, 0, 0).tv_sec) # the Epoch
+ assert_equal(1, Time.utc(1970, 1, 1, 0, 0, 1).tv_sec)
+ assert_equal(31535999, Time.utc(1970, 12, 31, 23, 59, 59).tv_sec)
+ assert_equal(31536000, Time.utc(1971, 1, 1, 0, 0, 0).tv_sec)
+ assert_equal(78796799, Time.utc(1972, 6, 30, 23, 59, 59).tv_sec)
+
+ # 1972-06-30T23:59:60Z is the first leap second.
+ if Time.utc(1972, 7, 1, 0, 0, 0) - Time.utc(1972, 6, 30, 23, 59, 59) == 1
+ # no leap second.
+ assert_equal(78796800, Time.utc(1972, 7, 1, 0, 0, 0).tv_sec)
+ assert_equal(78796801, Time.utc(1972, 7, 1, 0, 0, 1).tv_sec)
+ assert_equal(946684800, Time.utc(2000, 1, 1, 0, 0, 0).tv_sec)
+ assert_equal(0x7fffffff, Time.utc(2038, 1, 19, 3, 14, 7).tv_sec)
+ else
+ # leap seconds supported.
+ assert_equal(2, Time.utc(1972, 7, 1, 0, 0, 0) - Time.utc(1972, 6, 30, 23, 59, 59))
+ assert_equal(78796800, Time.utc(1972, 6, 30, 23, 59, 60).tv_sec)
+ assert_equal(78796801, Time.utc(1972, 7, 1, 0, 0, 0).tv_sec)
+ assert_equal(78796802, Time.utc(1972, 7, 1, 0, 0, 1).tv_sec)
+ assert_equal(946684822, Time.utc(2000, 1, 1, 0, 0, 0).tv_sec)
+ end
+ end
+
+ def test_strtime
+ t = nil
+ assert_nothing_raised { t = Time.utc("2000", "1", "2" , "3", "4", "5") }
+ assert_equal(Time.utc(2000,1,2,3,4,5), t)
+ end
+
+ def test_huge_difference
+ if negative_time_t?
+ assert_equal(Time.at(-0x80000000), Time.at(0x7fffffff) - 0xffffffff, "[ruby-dev:22619]")
+ assert_equal(Time.at(-0x80000000), Time.at(0x7fffffff) + (-0xffffffff))
+ assert_equal(Time.at(0x7fffffff), Time.at(-0x80000000) + 0xffffffff, "[ruby-dev:22619]")
+ assert_equal(Time.at(0x7fffffff), Time.at(-0x80000000) - (-0xffffffff))
+ end
+ end
+
+ def test_big_minus
+ begin
+ bigtime0 = Time.at(2**60)
+ bigtime1 = Time.at(2**60+1)
+ rescue RangeError
+ return
+ end
+ assert_equal(1.0, bigtime1 - bigtime0)
+ end
+
+ def test_at
+ assert_equal(100000, Time.at("0.1".to_r).usec)
+ assert_equal(10000, Time.at("0.01".to_r).usec)
+ assert_equal(1000, Time.at("0.001".to_r).usec)
+ assert_equal(100, Time.at("0.0001".to_r).usec)
+ assert_equal(10, Time.at("0.00001".to_r).usec)
+ assert_equal(1, Time.at("0.000001".to_r).usec)
+ assert_equal(100000000, Time.at("0.1".to_r).nsec)
+ assert_equal(10000000, Time.at("0.01".to_r).nsec)
+ assert_equal(1000000, Time.at("0.001".to_r).nsec)
+ assert_equal(100000, Time.at("0.0001".to_r).nsec)
+ assert_equal(10000, Time.at("0.00001".to_r).nsec)
+ assert_equal(1000, Time.at("0.000001".to_r).nsec)
+ assert_equal(100, Time.at("0.0000001".to_r).nsec)
+ assert_equal(10, Time.at("0.00000001".to_r).nsec)
+ assert_equal(1, Time.at("0.000000001".to_r).nsec)
+ assert_equal(100000, Time.at(0.1).usec)
+ assert_equal(10000, Time.at(0.01).usec)
+ assert_equal(1000, Time.at(0.001).usec)
+ assert_equal(100, Time.at(0.0001).usec)
+ assert_equal(10, Time.at(0.00001).usec)
+ assert_equal(3, Time.at(0.000003).usec)
+ assert_equal(100000000, Time.at(0.1).nsec)
+ assert_equal(10000000, Time.at(0.01).nsec)
+ assert_equal(1000000, Time.at(0.001).nsec)
+ assert_equal(100000, Time.at(0.0001).nsec)
+ assert_equal(10000, Time.at(0.00001).nsec)
+ assert_equal(3000, Time.at(0.000003).nsec)
+ assert_equal(199, Time.at(0.0000002).nsec)
+ assert_equal(10, Time.at(0.00000001).nsec)
+ assert_equal(1, Time.at(0.000000001).nsec)
+
+ assert_equal(0, Time.at(1e-10).nsec)
+ assert_equal(0, Time.at(4e-10).nsec)
+ assert_equal(0, Time.at(6e-10).nsec)
+ assert_equal(1, Time.at(14e-10).nsec)
+ assert_equal(1, Time.at(16e-10).nsec)
+ if negative_time_t?
+ assert_equal(999999999, Time.at(-1e-10).nsec)
+ assert_equal(999999999, Time.at(-4e-10).nsec)
+ assert_equal(999999999, Time.at(-6e-10).nsec)
+ assert_equal(999999998, Time.at(-14e-10).nsec)
+ assert_equal(999999998, Time.at(-16e-10).nsec)
+ end
+
+ t = Time.at(-4611686019).utc
+ assert_equal(1823, t.year)
+
+ t = Time.at(4611686018, 999999).utc
+ assert_equal(2116, t.year)
+ assert_equal("0.999999".to_r, t.subsec)
+
+ t = Time.at(2**40 + "1/3".to_r, 9999999999999).utc
+ assert_equal(36812, t.year)
+
+ t = Time.at(-0x3fff_ffff_ffff_ffff)
+ assert_equal(-146138510344, t.year)
+ t = Time.at(-0x4000_0000_0000_0000)
+ assert_equal(-146138510344, t.year)
+ t = Time.at(-0x4000_0000_0000_0001)
+ assert_equal(-146138510344, t.year)
+ t = Time.at(-0x5000_0000_0000_0001)
+ assert_equal(-182673138422, t.year)
+ t = Time.at(-0x6000_0000_0000_0000)
+ assert_equal(-219207766501, t.year)
+
+ t = Time.at(0).utc
+ assert_equal([1970,1,1, 0,0,0], [t.year, t.mon, t.day, t.hour, t.min, t.sec])
+ t = Time.at(-86400).utc
+ assert_equal([1969,12,31, 0,0,0], [t.year, t.mon, t.day, t.hour, t.min, t.sec])
+ t = Time.at(-86400 * (400 * 365 + 97)).utc
+ assert_equal([1970-400,1,1, 0,0,0], [t.year, t.mon, t.day, t.hour, t.min, t.sec])
+ t = Time.at(-86400 * (400 * 365 + 97)*1000).utc
+ assert_equal([1970-400*1000,1,1, 0,0,0], [t.year, t.mon, t.day, t.hour, t.min, t.sec])
+ t = Time.at(-86400 * (400 * 365 + 97)*2421).utc
+ assert_equal([1970-400*2421,1,1, 0,0,0], [t.year, t.mon, t.day, t.hour, t.min, t.sec])
+ t = Time.at(-86400 * (400 * 365 + 97)*1000000).utc
+ assert_equal([1970-400*1000000,1,1, 0,0,0], [t.year, t.mon, t.day, t.hour, t.min, t.sec])
+
+ t = Time.at(-30613683110400).utc
+ assert_equal([-968139,1,1, 0,0,0], [t.year, t.mon, t.day, t.hour, t.min, t.sec])
+ t = Time.at(-30613683110401).utc
+ assert_equal([-968140,12,31, 23,59,59], [t.year, t.mon, t.day, t.hour, t.min, t.sec])
+ end
+
+ def test_at2
+ assert_equal(100, Time.at(0, 0.1).nsec)
+ assert_equal(10, Time.at(0, 0.01).nsec)
+ assert_equal(1, Time.at(0, 0.001).nsec)
+ end
+
+ def test_at_rational
+ assert_equal(1, Time.at(Rational(1,1) / 1000000000).nsec)
+ assert_equal(1, Time.at(1167609600 + Rational(1,1) / 1000000000).nsec)
+ end
+
+ def test_utc_subsecond
+ assert_equal(500000, Time.utc(2007,1,1,0,0,1.5).usec)
+ assert_equal(100000, Time.utc(2007,1,1,0,0,Rational(11,10)).usec)
+ end
+
+ def test_eq_nsec
+ assert_equal(Time.at(0, 0.123), Time.at(0, 0.123))
+ assert_not_equal(Time.at(0, 0.123), Time.at(0, 0.124))
+ end
+
+ def assert_marshal_roundtrip(t)
+ iv_names = t.instance_variables
+ iv_vals1 = iv_names.map {|n| t.instance_variable_get n }
+ m = Marshal.dump(t)
+ t2 = Marshal.load(m)
+ iv_vals2 = iv_names.map {|n| t2.instance_variable_get n }
+ assert_equal(t, t2)
+ assert_equal(iv_vals1, iv_vals2)
+ t2
+ end
+
+ def test_marshal_nsec
+ assert_marshal_roundtrip(Time.at(0, 0.123))
+ assert_marshal_roundtrip(Time.at(0, 0.120))
+ end
+
+ def test_marshal_nsec_191
+ # generated by ruby 1.9.1p376
+ m = "\x04\bIu:\tTime\r \x80\x11\x80@\xE2\x01\x00\x06:\rsubmicro\"\ax\x90"
+ t = Marshal.load(m)
+ assert_equal(Time.at(Rational(123456789, 1000000000)), t, "[ruby-dev:40133]")
+ end
+
+ def test_marshal_rational
+ assert_marshal_roundtrip(Time.at(0, Rational(1,3)))
+ assert_not_match(/Rational/, Marshal.dump(Time.at(0, Rational(1,3))))
+ end
+
+ def test_marshal_ivar
+ t = Time.at(123456789, 987654.321)
+ t.instance_eval { @var = 135 }
+ assert_marshal_roundtrip(t)
+ assert_marshal_roundtrip(Marshal.load(Marshal.dump(t)))
+ end
+
+ def test_marshal_timezone
+ bug = '[ruby-dev:40063]'
+
+ t1 = Time.gm(2000)
+ m = Marshal.dump(t1.getlocal("-02:00"))
+ t2 = Marshal.load(m)
+ assert_equal(t1, t2)
+ assert_equal(-7200, t2.utc_offset, bug)
+ m = Marshal.dump(t1.getlocal("+08:15"))
+ t2 = Marshal.load(m)
+ assert_equal(t1, t2)
+ assert_equal(29700, t2.utc_offset, bug)
+ end
+
+ # Sat Jan 01 00:00:00 UTC 2000
+ T2000 = Time.at(946684800).gmtime
+
+ def test_security_error
+ assert_raise(SecurityError) do
+ Thread.new do
+ t = Time.gm(2000)
+ $SAFE = 4
+ t.localtime
+ end.join
+ end
+ end
+
+ def test_at3
+ assert_equal(T2000, Time.at(T2000))
+# assert_raise(RangeError) do
+# Time.at(2**31-1, 1_000_000)
+# Time.at(2**63-1, 1_000_000)
+# end
+# assert_raise(RangeError) do
+# Time.at(-2**31, -1_000_000)
+# Time.at(-2**63, -1_000_000)
+# end
+ end
+
+ def test_utc_or_local
+ assert_equal(T2000, Time.gm(2000))
+ assert_equal(T2000, Time.gm(0, 0, 0, 1, 1, 2000, :foo, :bar, false, :baz))
+ assert_equal(T2000, Time.gm(2000, "jan"))
+ assert_equal(T2000, Time.gm(2000, "1"))
+ assert_equal(T2000, Time.gm(2000, 1, 1, 0, 0, 0, 0))
+ assert_equal(T2000, Time.gm(2000, 1, 1, 0, 0, 0, "0"))
+ assert_equal(T2000, Time.gm(2000, 1, 1, 0, 0, "0", :foo, :foo))
+ assert_raise(ArgumentError) { Time.gm(2000, 1, 1, 0, 0, -1, :foo, :foo) }
+ assert_raise(ArgumentError) { Time.gm(2000, 1, 1, 0, 0, -1.0, :foo, :foo) }
+ assert_raise(RangeError) do
+ Time.gm(2000, 1, 1, 0, 0, 10_000_000_000_000_000_001.0, :foo, :foo)
+ end
+ assert_raise(ArgumentError) { Time.gm(2000, 1, 1, 0, 0, -(2**31), :foo, :foo) }
+ o = Object.new
+ def o.to_r; nil; end
+ assert_raise(TypeError) { Time.gm(2000, 1, 1, 0, 0, o, :foo, :foo) }
+ def o.to_r; ""; end
+ assert_raise(TypeError) { Time.gm(2000, 1, 1, 0, 0, o, :foo, :foo) }
+ def o.to_r; Rational(11); end
+ assert_equal(11, Time.gm(2000, 1, 1, 0, 0, o).sec)
+ o = Object.new
+ def o.to_int; 10; end
+ assert_equal(10, Time.gm(2000, 1, 1, 0, 0, o).sec)
+ assert_raise(ArgumentError) { Time.gm(2000, 13) }
+
+ t = Time.local(2000)
+ assert_equal(t.gmt_offset, T2000 - t)
+
+ assert_equal(-4427700000, Time.utc(-4427700000,12,1).year)
+ assert_equal(-2**30+10, Time.utc(-2**30+10,1,1).year)
+ end
+
+ def test_time_interval
+ m = Mutex.new.lock
+ assert_nothing_raised {
+ Timeout.timeout(10) {
+ m.sleep(0)
+ }
+ }
+ assert_raise(ArgumentError) { m.sleep(-1) }
+ end
+
+ def test_to_f
+ assert_equal(946684800.0, T2000.to_f)
+ end
+
+ def test_cmp
+ assert_equal(-1, T2000 <=> Time.gm(2001))
+ assert_equal(1, T2000 <=> Time.gm(1999))
+ assert_nil(T2000 <=> 0)
+ end
+
+ def test_eql
+ assert(T2000.eql?(T2000))
+ assert(!T2000.eql?(Time.gm(2001)))
+ end
+
+ def test_utc_p
+ assert(Time.gm(2000).gmt?)
+ assert(!Time.local(2000).gmt?)
+ assert(!Time.at(0).gmt?)
+ end
+
+ def test_hash
+ assert_kind_of(Integer, T2000.hash)
+ end
+
+ def test_init_copy
+ assert_equal(T2000, T2000.dup)
+ assert_raise(TypeError) do
+ T2000.instance_eval { initialize_copy(nil) }
+ end
+ end
+
+ def test_localtime_gmtime
+ assert_nothing_raised do
+ t = Time.gm(2000)
+ assert(t.gmt?)
+ t.localtime
+ assert(!t.gmt?)
+ t.localtime
+ assert(!t.gmt?)
+ t.gmtime
+ assert(t.gmt?)
+ t.gmtime
+ assert(t.gmt?)
+ end
+
+ t1 = Time.gm(2000)
+ t2 = t1.getlocal
+ assert_equal(t1, t2)
+ t3 = t1.getlocal("-02:00")
+ assert_equal(t1, t3)
+ assert_equal(-7200, t3.utc_offset)
+ t1.localtime
+ assert_equal(t1, t2)
+ assert_equal(t1.gmt?, t2.gmt?)
+ assert_equal(t1, t3)
+
+ t1 = Time.local(2000)
+ t2 = t1.getgm
+ assert_equal(t1, t2)
+ t3 = t1.getlocal("-02:00")
+ assert_equal(t1, t3)
+ assert_equal(-7200, t3.utc_offset)
+ t1.gmtime
+ assert_equal(t1, t2)
+ assert_equal(t1.gmt?, t2.gmt?)
+ assert_equal(t1, t3)
+ end
+
+ def test_asctime
+ assert_equal("Sat Jan 1 00:00:00 2000", T2000.asctime)
+ assert_kind_of(String, Time.at(0).asctime)
+ end
+
+ def test_to_s
+ assert_equal("2000-01-01 00:00:00 UTC", T2000.to_s)
+ assert_kind_of(String, Time.at(946684800).getlocal.to_s)
+ assert_equal(Time.at(946684800).getlocal.to_s, Time.at(946684800).to_s)
+ end
+
+ def test_plus_minus_succ
+ # assert_raise(RangeError) { T2000 + 10000000000 }
+ # assert_raise(RangeError) T2000 - 3094168449 }
+ # assert_raise(RangeError) { T2000 + 1200798848 }
+ assert_raise(TypeError) { T2000 + Time.now }
+ assert_equal(T2000 + 1, T2000.succ)
+ end
+
+ def test_plus_type
+ t0 = Time.utc(2000,1,1)
+ n0 = t0.to_i
+ n1 = n0+1
+ t1 = Time.at(n1)
+ assert_equal(t1, t0 + 1)
+ assert_equal(t1, t0 + 1.0)
+ assert_equal(t1, t0 + Rational(1,1))
+ assert_equal(t1, t0 + SimpleDelegator.new(1))
+ assert_equal(t1, t0 + SimpleDelegator.new(1.0))
+ assert_equal(t1, t0 + SimpleDelegator.new(Rational(1,1)))
+ assert_raise(TypeError) { t0 + nil }
+ assert_raise(TypeError) { t0 + "1" }
+ assert_raise(TypeError) { t0 + SimpleDelegator.new("1") }
+ assert_equal(0.5, (t0 + 1.5).subsec)
+ assert_equal(Rational(1,3), (t0 + Rational(4,3)).subsec)
+ assert_equal(0.5, (t0 + SimpleDelegator.new(1.5)).subsec)
+ assert_equal(Rational(1,3), (t0 + SimpleDelegator.new(Rational(4,3))).subsec)
+ end
+
+ def test_minus
+ t = Time.at(-4611686018).utc - 100
+ assert_equal(1823, t.year)
+ end
+
+ def test_readers
+ assert_equal(0, T2000.sec)
+ assert_equal(0, T2000.min)
+ assert_equal(0, T2000.hour)
+ assert_equal(1, T2000.mday)
+ assert_equal(1, T2000.mon)
+ assert_equal(2000, T2000.year)
+ assert_equal(6, T2000.wday)
+ assert_equal(1, T2000.yday)
+ assert_equal(false, T2000.isdst)
+ assert_equal("UTC", T2000.zone)
+ assert_equal(0, T2000.gmt_offset)
+ assert(!T2000.sunday?)
+ assert(!T2000.monday?)
+ assert(!T2000.tuesday?)
+ assert(!T2000.wednesday?)
+ assert(!T2000.thursday?)
+ assert(!T2000.friday?)
+ assert(T2000.saturday?)
+ assert_equal([0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"], T2000.to_a)
+
+ t = Time.at(946684800).getlocal
+ assert_equal(t.sec, Time.at(946684800).sec)
+ assert_equal(t.min, Time.at(946684800).min)
+ assert_equal(t.hour, Time.at(946684800).hour)
+ assert_equal(t.mday, Time.at(946684800).mday)
+ assert_equal(t.mon, Time.at(946684800).mon)
+ assert_equal(t.year, Time.at(946684800).year)
+ assert_equal(t.wday, Time.at(946684800).wday)
+ assert_equal(t.yday, Time.at(946684800).yday)
+ assert_equal(t.isdst, Time.at(946684800).isdst)
+ assert_equal(t.zone, Time.at(946684800).zone)
+ assert_equal(t.gmt_offset, Time.at(946684800).gmt_offset)
+ assert_equal(t.sunday?, Time.at(946684800).sunday?)
+ assert_equal(t.monday?, Time.at(946684800).monday?)
+ assert_equal(t.tuesday?, Time.at(946684800).tuesday?)
+ assert_equal(t.wednesday?, Time.at(946684800).wednesday?)
+ assert_equal(t.thursday?, Time.at(946684800).thursday?)
+ assert_equal(t.friday?, Time.at(946684800).friday?)
+ assert_equal(t.saturday?, Time.at(946684800).saturday?)
+ assert_equal(t.to_a, Time.at(946684800).to_a)
+ end
+
+ def test_strftime
+ t = Time.at(946684800).getlocal
+ assert_equal("Sat", T2000.strftime("%a"))
+ assert_equal("Saturday", T2000.strftime("%A"))
+ assert_equal("Jan", T2000.strftime("%b"))
+ assert_equal("January", T2000.strftime("%B"))
+ assert_kind_of(String, T2000.strftime("%c"))
+ assert_equal("01", T2000.strftime("%d"))
+ assert_equal("00", T2000.strftime("%H"))
+ assert_equal("12", T2000.strftime("%I"))
+ assert_equal("001", T2000.strftime("%j"))
+ assert_equal("01", T2000.strftime("%m"))
+ assert_equal("00", T2000.strftime("%M"))
+ assert_equal("AM", T2000.strftime("%p"))
+ assert_equal("00", T2000.strftime("%S"))
+ assert_equal("00", T2000.strftime("%U"))
+ assert_equal("00", T2000.strftime("%W"))
+ assert_equal("6", T2000.strftime("%w"))
+ assert_equal("01/01/00", T2000.strftime("%x"))
+ assert_equal("00:00:00", T2000.strftime("%X"))
+ assert_equal("00", T2000.strftime("%y"))
+ assert_equal("2000", T2000.strftime("%Y"))
+ assert_equal("UTC", T2000.strftime("%Z"))
+ assert_equal("%", T2000.strftime("%%"))
+ assert_equal("0", T2000.strftime("%-S"))
+
+ assert_equal("", T2000.strftime(""))
+ assert_equal("foo\0bar\x0000\x0000\x0000", T2000.strftime("foo\0bar\0%H\0%M\0%S"))
+ assert_equal("foo" * 1000, T2000.strftime("foo" * 1000))
+
+ t = Time.mktime(2000, 1, 1)
+ assert_equal("Sat", t.strftime("%a"))
+
+ t = Time.at(946684800, 123456.789)
+ assert_equal("123", t.strftime("%3N"))
+ assert_equal("123456", t.strftime("%6N"))
+ assert_equal("123456789", t.strftime("%9N"))
+ assert_equal("1234567890", t.strftime("%10N"))
+ assert_equal("123456789", t.strftime("%0N"))
+ assert_equal("000", t.strftime("%3S"))
+ assert_equal("946684800", t.strftime("%s"))
+ assert_equal("946684800", t.utc.strftime("%s"))
+
+ t = Time.mktime(2001, 10, 1)
+ assert_equal("2001-10-01", t.strftime("%F"))
+
+ t = Time.mktime(2001, 10, 1, 2, 0, 0)
+ assert_equal("01", t.strftime("%d"))
+ assert_equal("01", t.strftime("%0d"))
+ assert_equal(" 1", t.strftime("%_d"))
+ assert_equal(" 1", t.strftime("%e"))
+ assert_equal("01", t.strftime("%0e"))
+ assert_equal(" 1", t.strftime("%_e"))
+ assert_equal("AM", t.strftime("%p"))
+ assert_equal("am", t.strftime("%#p"))
+ assert_equal("am", t.strftime("%P"))
+ assert_equal("AM", t.strftime("%#P"))
+ assert_equal("02", t.strftime("%H"))
+ assert_equal("02", t.strftime("%0H"))
+ assert_equal(" 2", t.strftime("%_H"))
+ assert_equal("02", t.strftime("%I"))
+ assert_equal("02", t.strftime("%0I"))
+ assert_equal(" 2", t.strftime("%_I"))
+ assert_equal(" 2", t.strftime("%k"))
+ assert_equal("02", t.strftime("%0k"))
+ assert_equal(" 2", t.strftime("%_k"))
+ assert_equal(" 2", t.strftime("%l"))
+ assert_equal("02", t.strftime("%0l"))
+ assert_equal(" 2", t.strftime("%_l"))
+ t = Time.mktime(2001, 10, 1, 14, 0, 0)
+ assert_equal("PM", t.strftime("%p"))
+ assert_equal("pm", t.strftime("%#p"))
+ assert_equal("pm", t.strftime("%P"))
+ assert_equal("PM", t.strftime("%#P"))
+ assert_equal("14", t.strftime("%H"))
+ assert_equal("14", t.strftime("%0H"))
+ assert_equal("14", t.strftime("%_H"))
+ assert_equal("02", t.strftime("%I"))
+ assert_equal("02", t.strftime("%0I"))
+ assert_equal(" 2", t.strftime("%_I"))
+ assert_equal("14", t.strftime("%k"))
+ assert_equal("14", t.strftime("%0k"))
+ assert_equal("14", t.strftime("%_k"))
+ assert_equal(" 2", t.strftime("%l"))
+ assert_equal("02", t.strftime("%0l"))
+ assert_equal(" 2", t.strftime("%_l"))
+
+ # [ruby-dev:37155]
+ t = Time.mktime(1970, 1, 18)
+ assert_equal("0", t.strftime("%w"))
+ assert_equal("7", t.strftime("%u"))
+
+ # [ruby-dev:37160]
+ assert_equal("\t", T2000.strftime("%t"))
+ assert_equal("\t", T2000.strftime("%0t"))
+ assert_equal("\t", T2000.strftime("%1t"))
+ assert_equal(" \t", T2000.strftime("%3t"))
+ assert_equal("00\t", T2000.strftime("%03t"))
+ assert_equal("\n", T2000.strftime("%n"))
+ assert_equal("\n", T2000.strftime("%0n"))
+ assert_equal("\n", T2000.strftime("%1n"))
+ assert_equal(" \n", T2000.strftime("%3n"))
+ assert_equal("00\n", T2000.strftime("%03n"))
+
+ # [ruby-dev:37162]
+ assert_equal("SAT", T2000.strftime("%#a"))
+ assert_equal("SATURDAY", T2000.strftime("%#A"))
+ assert_equal("JAN", T2000.strftime("%#b"))
+ assert_equal("JANUARY", T2000.strftime("%#B"))
+ assert_equal("JAN", T2000.strftime("%#h"))
+ assert_equal("FRIDAY", Time.local(2008,1,4).strftime("%#A"))
+
+ t = Time.utc(2000,3,14, 6,53,"58.979323846".to_r) # Pi Day
+ assert_equal("03/14/2000 6:53:58.97932384600000000000000000000",
+ t.strftime("%m/%d/%Y %l:%M:%S.%29N"))
+ assert_equal("03/14/2000 6:53:58.9793238460",
+ t.strftime("%m/%d/%Y %l:%M:%S.%10N"))
+ assert_equal("03/14/2000 6:53:58.979323846",
+ t.strftime("%m/%d/%Y %l:%M:%S.%9N"))
+ assert_equal("03/14/2000 6:53:58.97932384",
+ t.strftime("%m/%d/%Y %l:%M:%S.%8N"))
+
+ t = Time.utc(1592,3,14, 6,53,"58.97932384626433832795028841971".to_r) # Pi Day
+ assert_equal("03/14/1592 6:53:58.97932384626433832795028841971",
+ t.strftime("%m/%d/%Y %l:%M:%S.%29N"))
+ assert_equal("03/14/1592 6:53:58.9793238462",
+ t.strftime("%m/%d/%Y %l:%M:%S.%10N"))
+ assert_equal("03/14/1592 6:53:58.979323846",
+ t.strftime("%m/%d/%Y %l:%M:%S.%9N"))
+ assert_equal("03/14/1592 6:53:58.97932384",
+ t.strftime("%m/%d/%Y %l:%M:%S.%8N"))
+ end
+
+ def test_delegate
+ d1 = SimpleDelegator.new(t1 = Time.utc(2000))
+ d2 = SimpleDelegator.new(t2 = Time.utc(2001))
+ assert_equal(-1, t1 <=> t2)
+ assert_equal(1, t2 <=> t1)
+ assert_equal(-1, d1 <=> d2)
+ assert_equal(1, d2 <=> d1)
+ end
+
+ def test_to_r
+ assert_kind_of(Rational, Time.new(2000,1,1,0,0,Rational(4,3)).to_r)
+ assert_kind_of(Rational, Time.utc(1970).to_r)
+ end
+
+ def test_round
+ t = Time.utc(1999,12,31, 23,59,59)
+ t2 = (t+0.4).round
+ assert_equal([59,59,23, 31,12,1999, 5,365,false,"UTC"], t2.to_a)
+ assert_equal(0, t2.subsec)
+ t2 = (t+0.49).round
+ assert_equal([59,59,23, 31,12,1999, 5,365,false,"UTC"], t2.to_a)
+ assert_equal(0, t2.subsec)
+ t2 = (t+0.5).round
+ assert_equal([0,0,0, 1,1,2000, 6,1,false,"UTC"], t2.to_a)
+ assert_equal(0, t2.subsec)
+ t2 = (t+1.4).round
+ assert_equal([0,0,0, 1,1,2000, 6,1,false,"UTC"], t2.to_a)
+ assert_equal(0, t2.subsec)
+ t2 = (t+1.49).round
+ assert_equal([0,0,0, 1,1,2000, 6,1,false,"UTC"], t2.to_a)
+ assert_equal(0, t2.subsec)
+ t2 = (t+1.5).round
+ assert_equal([1,0,0, 1,1,2000, 6,1,false,"UTC"], t2.to_a)
+ assert_equal(0, t2.subsec)
+
+ t2 = (t+0.123456789).round(4)
+ assert_equal([59,59,23, 31,12,1999, 5,365,false,"UTC"], t2.to_a)
+ assert_equal(Rational(1235,10000), t2.subsec)
+
+ off = 0.0
+ 100.times {|i|
+ t2 = (t+off).round(1)
+ assert_equal(Rational(i % 10, 10), t2.subsec)
+ off += 0.1
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_time_tz.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_time_tz.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_time_tz.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,249 @@
+require 'test/unit'
+
+class TestTimeTZ < Test::Unit::TestCase
+ def with_tz(tz)
+ if /linux/ =~ RUBY_PLATFORM || ENV["RUBY_FORCE_TIME_TZ_TEST"] == "yes"
+ old = ENV["TZ"]
+ begin
+ ENV["TZ"] = tz
+ yield
+ ensure
+ ENV["TZ"] = old
+ end
+ else
+ if ENV["TZ"] == tz
+ yield
+ end
+ end
+ end
+
+ def format_gmtoff(gmtoff)
+ if gmtoff < 0
+ expected = "-"
+ gmtoff = -gmtoff
+ else
+ expected = "+"
+ end
+ gmtoff /= 60
+ expected << "%02d%02d" % [gmtoff / 60, gmtoff % 60]
+ expected
+ end
+
+ def time_to_s(t)
+ if RUBY_VERSION < "1.9"
+ t.strftime("%Y-%m-%d %H:%M:%S ") + format_gmtoff(t.gmtoff)
+ else
+ t.to_s
+ end
+ end
+
+ def assert_time_constructor(tz, expected, method, args, message=nil)
+ m = message ? "#{message}\n" : ""
+ m << "TZ=#{tz} Time.#{method}(#{args.map(&:inspect).join(', ')})"
+ real = time_to_s(Time.send(method, *args))
+ assert_equal(expected, real, m)
+ end
+
+ def test_america_los_angeles
+ with_tz(tz="America/Los_Angeles") {
+ assert_time_constructor(tz, "2007-03-11 03:00:00 -0700", :local, [2007,3,11,2,0,0])
+ assert_time_constructor(tz, "2007-03-11 03:59:59 -0700", :local, [2007,3,11,2,59,59])
+ }
+ end
+
+ def test_america_managua
+ with_tz(tz="America/Managua") {
+ assert_time_constructor(tz, "1993-01-01 01:00:00 -0500", :local, [1993,1,1,0,0,0])
+ assert_time_constructor(tz, "1993-01-01 01:59:59 -0500", :local, [1993,1,1,0,59,59])
+ }
+ end
+
+ def test_asia_singapore
+ with_tz(tz="Asia/Singapore") {
+ assert_time_constructor(tz, "1981-12-31 23:59:59 +0730", :local, [1981,12,31,23,59,59])
+ assert_time_constructor(tz, "1982-01-01 00:30:00 +0800", :local, [1982,1,1,0,0,0])
+ assert_time_constructor(tz, "1982-01-01 00:59:59 +0800", :local, [1982,1,1,0,29,59])
+ assert_time_constructor(tz, "1982-01-01 00:30:00 +0800", :local, [1982,1,1,0,30,0])
+ }
+ end
+
+ def test_asia_tokyo
+ with_tz(tz="Asia/Tokyo") {
+ assert_time_constructor(tz, "1951-05-06 03:00:00 +1000", :local, [1951,5,6,2,0,0])
+ assert_time_constructor(tz, "1951-05-06 03:59:59 +1000", :local, [1951,5,6,2,59,59])
+ assert_time_constructor(tz, "2010-06-10 06:13:28 +0900", :local, [2010,6,10,6,13,28])
+ }
+ end
+
+ def test_canada_newfoundland
+ with_tz(tz="Canada/Newfoundland") {
+ assert_time_constructor(tz, "2007-11-03 23:00:59 -0230", :new, [2007,11,3,23,0,59,:dst])
+ assert_time_constructor(tz, "2007-11-03 23:01:00 -0230", :new, [2007,11,3,23,1,0,:dst])
+ assert_time_constructor(tz, "2007-11-03 23:59:59 -0230", :new, [2007,11,3,23,59,59,:dst])
+ assert_time_constructor(tz, "2007-11-04 00:00:00 -0230", :new, [2007,11,4,0,0,0,:dst])
+ assert_time_constructor(tz, "2007-11-04 00:00:59 -0230", :new, [2007,11,4,0,0,59,:dst])
+ assert_time_constructor(tz, "2007-11-03 23:01:00 -0330", :new, [2007,11,3,23,1,0,:std])
+ assert_time_constructor(tz, "2007-11-03 23:59:59 -0330", :new, [2007,11,3,23,59,59,:std])
+ assert_time_constructor(tz, "2007-11-04 00:00:59 -0330", :new, [2007,11,4,0,0,59,:std])
+ assert_time_constructor(tz, "2007-11-04 00:01:00 -0330", :new, [2007,11,4,0,1,0,:std])
+ }
+ end
+
+ def test_europe_brussels
+ with_tz(tz="Europe/Brussels") {
+ assert_time_constructor(tz, "1916-04-30 23:59:59 +0100", :local, [1916,4,30,23,59,59])
+ assert_time_constructor(tz, "1916-05-01 01:00:00 +0200", :local, [1916,5,1], "[ruby-core:30672]")
+ assert_time_constructor(tz, "1916-05-01 01:59:59 +0200", :local, [1916,5,1,0,59,59])
+ assert_time_constructor(tz, "1916-05-01 01:00:00 +0200", :local, [1916,5,1,1,0,0])
+ assert_time_constructor(tz, "1916-05-01 01:59:59 +0200", :local, [1916,5,1,1,59,59])
+ }
+ end
+
+ def test_europe_moscow
+ with_tz(tz="Europe/Moscow") {
+ assert_time_constructor(tz, "1992-03-29 00:00:00 +0400", :local, [1992,3,28,23,0,0])
+ assert_time_constructor(tz, "1992-03-29 00:59:59 +0400", :local, [1992,3,28,23,59,59])
+ }
+ end
+
+ def test_pacific_kiritimati
+ with_tz(tz="Pacific/Kiritimati") {
+ assert_time_constructor(tz, "1994-12-31 23:59:59 -1000", :local, [1994,12,31,23,59,59])
+ assert_time_constructor(tz, "1995-01-02 00:00:00 +1400", :local, [1995,1,1,0,0,0])
+ assert_time_constructor(tz, "1995-01-02 23:59:59 +1400", :local, [1995,1,1,23,59,59])
+ assert_time_constructor(tz, "1995-01-02 00:00:00 +1400", :local, [1995,1,2,0,0,0])
+ }
+ end
+
+ MON2NUM = {
+ "Jan" => 1, "Feb" => 2, "Mar" => 3, "Apr" => 4, "May" => 5, "Jun" => 6,
+ "Jul" => 7, "Aug" => 8, "Sep" => 9, "Oct" => 10, "Nov" => 11, "Dec" => 12
+ }
+
+ def test_zdump
+ sample = []
+ ZDUMP_SAMPLE.each_line {|line|
+ next if /\A\#/ =~ line || /\A\s*\z/ =~ line
+ /\A(\S+)\s+
+ \S+\s+(\S+)\s+(\d+)\s+(\d\d):(\d\d):(\d\d)\s+(\d+)\s+UTC
+ \s+=\s+
+ \S+\s+(\S+)\s+(\d+)\s+(\d\d):(\d\d):(\d\d)\s+(\d+)\s+\S+
+ \s+isdst=\d+\s+gmtoff=(-?\d+)\n
+ \z/x =~ line
+ tz, u_mon, u_day, u_hour, u_min, u_sec, u_year,
+ l_mon, l_day, l_hour, l_min, l_sec, l_year, gmtoff = $~.captures
+ u_year = u_year.to_i
+ u_mon = MON2NUM[u_mon]
+ u_day = u_day.to_i
+ u_hour = u_hour.to_i
+ u_min = u_min.to_i
+ u_sec = u_sec.to_i
+ l_year = l_year.to_i
+ l_mon = MON2NUM[l_mon]
+ l_day = l_day.to_i
+ l_hour = l_hour.to_i
+ l_min = l_min.to_i
+ l_sec = l_sec.to_i
+ gmtoff = gmtoff.to_i
+ sample << [tz,
+ [u_year, u_mon, u_day, u_hour, u_min, u_sec],
+ [l_year, l_mon, l_day, l_hour, l_min, l_sec],
+ gmtoff]
+ }
+ sample.each {|tz, u, l, gmtoff|
+ with_tz(tz) {
+ expected = "%04d-%02d-%02d %02d:%02d:%02d %s" % (l+[format_gmtoff(gmtoff)])
+ mesg = "TZ=#{tz} Time.utc(#{u.map(&:inspect).join(', ')}).localtime"
+ t = nil
+ assert_nothing_raised(mesg) { t = Time.utc(*u).localtime }
+ assert_equal(expected, time_to_s(t), mesg)
+ assert_equal(gmtoff, t.gmtoff)
+ }
+ }
+ sample.group_by {|tz, _, _, _| tz }.each {|tz, a|
+ with_tz(tz) {
+ a.each_with_index {|(_, u, l, gmtoff), i|
+ expected = "%04d-%02d-%02d %02d:%02d:%02d %s" % (l+[format_gmtoff(gmtoff)])
+ monotonic_to_past = i == 0 || (a[i-1][2] <=> l) < 0
+ monotonic_to_future = i == a.length-1 || (l <=> a[i+1][2]) < 0
+ if monotonic_to_past && monotonic_to_future
+ assert_time_constructor(tz, expected, :local, l)
+ assert_time_constructor(tz, expected, :local, l.reverse+[nil, nil, false, nil])
+ assert_time_constructor(tz, expected, :local, l.reverse+[nil, nil, true, nil])
+ assert_time_constructor(tz, expected, :new, l)
+ assert_time_constructor(tz, expected, :new, l+[:std])
+ assert_time_constructor(tz, expected, :new, l+[:dst])
+ elsif monotonic_to_past && !monotonic_to_future
+ assert_time_constructor(tz, expected, :local, l.reverse+[nil, nil, true, nil])
+ assert_time_constructor(tz, expected, :new, l+[:dst])
+ elsif !monotonic_to_past && monotonic_to_future
+ assert_time_constructor(tz, expected, :local, l.reverse+[nil, nil, false, nil])
+ assert_time_constructor(tz, expected, :new, l+[:std])
+ else
+ flunk("time in reverse order: TZ=#{tz} #{expected}")
+ end
+ }
+ }
+ }
+ end
+
+ ZDUMP_SAMPLE = <<'End'
+America/Lima Sun Apr 1 03:59:59 1990 UTC = Sat Mar 31 23:59:59 1990 PEST isdst=1 gmtoff=-14400
+America/Lima Sun Apr 1 04:00:00 1990 UTC = Sat Mar 31 23:00:00 1990 PET isdst=0 gmtoff=-18000
+America/Lima Sat Jan 1 04:59:59 1994 UTC = Fri Dec 31 23:59:59 1993 PET isdst=0 gmtoff=-18000
+America/Lima Sat Jan 1 05:00:00 1994 UTC = Sat Jan 1 01:00:00 1994 PEST isdst=1 gmtoff=-14400
+America/Lima Fri Apr 1 03:59:59 1994 UTC = Thu Mar 31 23:59:59 1994 PEST isdst=1 gmtoff=-14400
+America/Lima Fri Apr 1 04:00:00 1994 UTC = Thu Mar 31 23:00:00 1994 PET isdst=0 gmtoff=-18000
+America/Los_Angeles Sun Apr 2 09:59:59 2006 UTC = Sun Apr 2 01:59:59 2006 PST isdst=0 gmtoff=-28800
+America/Los_Angeles Sun Apr 2 10:00:00 2006 UTC = Sun Apr 2 03:00:00 2006 PDT isdst=1 gmtoff=-25200
+America/Los_Angeles Sun Oct 29 08:59:59 2006 UTC = Sun Oct 29 01:59:59 2006 PDT isdst=1 gmtoff=-25200
+America/Los_Angeles Sun Oct 29 09:00:00 2006 UTC = Sun Oct 29 01:00:00 2006 PST isdst=0 gmtoff=-28800
+America/Los_Angeles Sun Mar 11 09:59:59 2007 UTC = Sun Mar 11 01:59:59 2007 PST isdst=0 gmtoff=-28800
+America/Los_Angeles Sun Mar 11 10:00:00 2007 UTC = Sun Mar 11 03:00:00 2007 PDT isdst=1 gmtoff=-25200
+America/Los_Angeles Sun Nov 4 08:59:59 2007 UTC = Sun Nov 4 01:59:59 2007 PDT isdst=1 gmtoff=-25200
+America/Los_Angeles Sun Nov 4 09:00:00 2007 UTC = Sun Nov 4 01:00:00 2007 PST isdst=0 gmtoff=-28800
+America/Managua Thu Sep 24 04:59:59 1992 UTC = Wed Sep 23 23:59:59 1992 EST isdst=0 gmtoff=-18000
+America/Managua Thu Sep 24 05:00:00 1992 UTC = Wed Sep 23 23:00:00 1992 CST isdst=0 gmtoff=-21600
+America/Managua Fri Jan 1 05:59:59 1993 UTC = Thu Dec 31 23:59:59 1992 CST isdst=0 gmtoff=-21600
+America/Managua Fri Jan 1 06:00:00 1993 UTC = Fri Jan 1 01:00:00 1993 EST isdst=0 gmtoff=-18000
+America/Managua Wed Jan 1 04:59:59 1997 UTC = Tue Dec 31 23:59:59 1996 EST isdst=0 gmtoff=-18000
+America/Managua Wed Jan 1 05:00:00 1997 UTC = Tue Dec 31 23:00:00 1996 CST isdst=0 gmtoff=-21600
+Asia/Singapore Sun Aug 8 16:30:00 1965 UTC = Mon Aug 9 00:00:00 1965 SGT isdst=0 gmtoff=27000
+Asia/Singapore Thu Dec 31 16:29:59 1981 UTC = Thu Dec 31 23:59:59 1981 SGT isdst=0 gmtoff=27000
+Asia/Singapore Thu Dec 31 16:30:00 1981 UTC = Fri Jan 1 00:30:00 1982 SGT isdst=0 gmtoff=28800
+Asia/Tokyo Sat May 5 16:59:59 1951 UTC = Sun May 6 01:59:59 1951 JST isdst=0 gmtoff=32400
+Asia/Tokyo Sat May 5 17:00:00 1951 UTC = Sun May 6 03:00:00 1951 JDT isdst=1 gmtoff=36000
+Asia/Tokyo Fri Sep 7 15:59:59 1951 UTC = Sat Sep 8 01:59:59 1951 JDT isdst=1 gmtoff=36000
+Asia/Tokyo Fri Sep 7 16:00:00 1951 UTC = Sat Sep 8 01:00:00 1951 JST isdst=0 gmtoff=32400
+Canada/Newfoundland Sun Mar 11 03:30:59 2007 UTC = Sun Mar 11 00:00:59 2007 NST isdst=0 gmtoff=-12600
+Canada/Newfoundland Sun Mar 11 03:31:00 2007 UTC = Sun Mar 11 01:01:00 2007 NDT isdst=1 gmtoff=-9000
+Canada/Newfoundland Sun Nov 4 02:30:59 2007 UTC = Sun Nov 4 00:00:59 2007 NDT isdst=1 gmtoff=-9000
+Canada/Newfoundland Sun Nov 4 02:31:00 2007 UTC = Sat Nov 3 23:01:00 2007 NST isdst=0 gmtoff=-12600
+Europe/Brussels Sun Apr 30 22:59:59 1916 UTC = Sun Apr 30 23:59:59 1916 CET isdst=0 gmtoff=3600
+Europe/Brussels Sun Apr 30 23:00:00 1916 UTC = Mon May 1 01:00:00 1916 CEST isdst=1 gmtoff=7200
+Europe/Brussels Sat Sep 30 22:59:59 1916 UTC = Sun Oct 1 00:59:59 1916 CEST isdst=1 gmtoff=7200
+Europe/Brussels Sat Sep 30 23:00:00 1916 UTC = Sun Oct 1 00:00:00 1916 CET isdst=0 gmtoff=3600
+Europe/London Sun Mar 16 01:59:59 1947 UTC = Sun Mar 16 01:59:59 1947 GMT isdst=0 gmtoff=0
+Europe/London Sun Mar 16 02:00:00 1947 UTC = Sun Mar 16 03:00:00 1947 BST isdst=1 gmtoff=3600
+Europe/London Sun Apr 13 00:59:59 1947 UTC = Sun Apr 13 01:59:59 1947 BST isdst=1 gmtoff=3600
+Europe/London Sun Apr 13 01:00:00 1947 UTC = Sun Apr 13 03:00:00 1947 BDST isdst=1 gmtoff=7200
+Europe/London Sun Aug 10 00:59:59 1947 UTC = Sun Aug 10 02:59:59 1947 BDST isdst=1 gmtoff=7200
+Europe/London Sun Aug 10 01:00:00 1947 UTC = Sun Aug 10 02:00:00 1947 BST isdst=1 gmtoff=3600
+Europe/London Sun Nov 2 01:59:59 1947 UTC = Sun Nov 2 02:59:59 1947 BST isdst=1 gmtoff=3600
+Europe/London Sun Nov 2 02:00:00 1947 UTC = Sun Nov 2 02:00:00 1947 GMT isdst=0 gmtoff=0
+Europe/Moscow Sat Jan 18 23:59:59 1992 UTC = Sun Jan 19 01:59:59 1992 MSK isdst=0 gmtoff=7200
+Europe/Moscow Sun Jan 19 00:00:00 1992 UTC = Sun Jan 19 03:00:00 1992 MSK isdst=0 gmtoff=10800
+Europe/Moscow Sat Mar 28 19:59:59 1992 UTC = Sat Mar 28 22:59:59 1992 MSK isdst=0 gmtoff=10800
+Europe/Moscow Sat Mar 28 20:00:00 1992 UTC = Sun Mar 29 00:00:00 1992 MSD isdst=1 gmtoff=14400
+Europe/Moscow Sat Sep 26 18:59:59 1992 UTC = Sat Sep 26 22:59:59 1992 MSD isdst=1 gmtoff=14400
+Europe/Moscow Sat Sep 26 19:00:00 1992 UTC = Sat Sep 26 22:00:00 1992 MSK isdst=0 gmtoff=10800
+Pacific/Kiritimati Sun Jan 1 09:59:59 1995 UTC = Sat Dec 31 23:59:59 1994 LINT isdst=0 gmtoff=-36000
+Pacific/Kiritimati Sun Jan 1 10:00:00 1995 UTC = Mon Jan 2 00:00:00 1995 LINT isdst=0 gmtoff=50400
+right/America/Los_Angeles Fri Jun 30 23:59:60 1972 UTC = Fri Jun 30 16:59:60 1972 PDT isdst=1 gmtoff=-25200
+right/America/Los_Angeles Wed Dec 31 23:59:60 2008 UTC = Wed Dec 31 15:59:60 2008 PST isdst=0 gmtoff=-28800
+#right/Asia/Tokyo Fri Jun 30 23:59:60 1972 UTC = Sat Jul 1 08:59:60 1972 JST isdst=0 gmtoff=32400
+#right/Asia/Tokyo Sat Dec 31 23:59:60 2005 UTC = Sun Jan 1 08:59:60 2006 JST isdst=0 gmtoff=32400
+right/Europe/Paris Fri Jun 30 23:59:60 1972 UTC = Sat Jul 1 00:59:60 1972 CET isdst=0 gmtoff=3600
+right/Europe/Paris Wed Dec 31 23:59:60 2008 UTC = Thu Jan 1 00:59:60 2009 CET isdst=0 gmtoff=3600
+End
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_trace.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_trace.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_trace.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,51 @@
+require 'test/unit'
+
+class TestTrace < Test::Unit::TestCase
+ def test_trace
+ $x = 1234
+ $y = 0
+ trace_var :$x, proc{$y = $x}
+ $x = 40414
+ assert_equal($x, $y)
+
+ untrace_var :$x
+ $x = 19660208
+ assert_not_equal($x, $y)
+
+ trace_var :$x, proc{$x *= 2}
+ $x = 5
+ assert_equal(10, $x)
+
+ untrace_var :$x
+ end
+
+ def test_trace_tainted_proc
+ skip("[BUG : #842] SecurityError Level 4")
+
+ $x = 1234
+ s = proc { $y = :foo }
+ trace_var :$x, s
+ s.taint
+ $x = 42
+ assert_equal(:foo, $y)
+ ensure
+ untrace_var :$x
+ end
+
+ def test_trace_proc_that_raises_exception
+ $x = 1234
+ trace_var :$x, proc { raise }
+ assert_raise(RuntimeError) { $x = 42 }
+ ensure
+ untrace_var :$x
+ end
+
+ def test_trace_string
+ $x = 1234
+ trace_var :$x, "$y = :bar"
+ $x = 42
+ assert_equal(:bar, $y)
+ ensure
+ untrace_var :$x
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_transcode.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_transcode.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_transcode.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1933 @@
+# -*- encoding: ASCII-8BIT -*- # make sure this runs in binary mode
+# some of the comments are in UTF-8
+
+require 'test/unit'
+class TestTranscode < Test::Unit::TestCase
+ def test_errors
+ assert_raise(Encoding::ConverterNotFoundError) { 'abc'.encode('foo', 'bar') }
+ assert_raise(Encoding::ConverterNotFoundError) { 'abc'.encode!('foo', 'bar') }
+ assert_raise(Encoding::ConverterNotFoundError) { 'abc'.force_encoding('utf-8').encode('foo') }
+ assert_raise(Encoding::ConverterNotFoundError) { 'abc'.force_encoding('utf-8').encode!('foo') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x80".encode('utf-8','ASCII-8BIT') }
+ assert_raise(Encoding::InvalidByteSequenceError) { "\x80".encode('utf-8','US-ASCII') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA5".encode('utf-8','iso-8859-3') }
+ assert_raise(RuntimeError) { 'hello'.freeze.encode!('iso-8859-1') }
+ assert_raise(RuntimeError) { '\u3053\u3093\u306b\u3061\u306f'.freeze.encode!('iso-8859-1') } # こんにちは
+ end
+
+ def test_arguments
+ assert_equal('abc', 'abc'.force_encoding('utf-8').encode('iso-8859-1'))
+ # check that encoding is kept when no conversion is done
+ assert_equal('abc'.force_encoding('Shift_JIS'), 'abc'.force_encoding('Shift_JIS').encode('Shift_JIS'))
+ assert_equal('abc'.force_encoding('Shift_JIS'), 'abc'.force_encoding('Shift_JIS').encode!('Shift_JIS'))
+ # assert that encoding is correctly set
+ assert_equal("D\u00FCrst".encoding, "D\xFCrst".force_encoding('iso-8859-1').encode('utf-8').encoding)
+ # check that Encoding can be used as parameter
+ assert_equal("D\u00FCrst", "D\xFCrst".encode('utf-8', Encoding.find('ISO-8859-1')))
+ assert_equal("D\u00FCrst", "D\xFCrst".encode(Encoding.find('utf-8'), 'ISO-8859-1'))
+ assert_equal("D\u00FCrst", "D\xFCrst".encode(Encoding.find('utf-8'), Encoding.find('ISO-8859-1')))
+ end
+
+ def test_noargument
+ default_default_internal = Encoding.default_internal
+ Encoding.default_internal = nil
+ assert_equal("\u3042".encode, "\u3042")
+ assert_equal("\xE3\x81\x82\x81".force_encoding("utf-8").encode,
+ "\xE3\x81\x82\x81".force_encoding("utf-8"))
+ Encoding.default_internal = 'EUC-JP'
+ assert_equal("\u3042".encode, "\xA4\xA2".force_encoding('EUC-JP'))
+ assert_equal("\xE3\x81\x82\x81".force_encoding("utf-8").encode,
+ "\xA4\xA2?".force_encoding('EUC-JP'))
+ Encoding.default_internal = default_default_internal
+ end
+
+ def test_length
+ assert_equal("\u20AC"*20, ("\xA4"*20).encode('utf-8', 'iso-8859-15'))
+ assert_equal("\u20AC"*20, ("\xA4"*20).encode!('utf-8', 'iso-8859-15'))
+ assert_equal("\u20AC"*2000, ("\xA4"*2000).encode('utf-8', 'iso-8859-15'))
+ assert_equal("\u20AC"*2000, ("\xA4"*2000).encode!('utf-8', 'iso-8859-15'))
+ assert_equal("\u20AC"*200000, ("\xA4"*200000).encode('utf-8', 'iso-8859-15'))
+ assert_equal("\u20AC"*200000, ("\xA4"*200000).encode!('utf-8', 'iso-8859-15'))
+ end
+
+ def check_both_ways(utf8, raw, encoding)
+ assert_equal(utf8.force_encoding('utf-8'), raw.encode('utf-8', encoding))
+ assert_equal(raw.force_encoding(encoding), utf8.encode(encoding, 'utf-8'))
+ end
+
+ def check_both_ways2(str1, enc1, str2, enc2)
+ assert_equal(str1.force_encoding(enc1), str2.encode(enc1, enc2))
+ assert_equal(str2.force_encoding(enc2), str1.encode(enc2, enc1))
+ end
+
+ def test_encodings
+ check_both_ways("\u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D",
+ "\x82\xdc\x82\xc2\x82\xe0\x82\xc6 \x82\xe4\x82\xab\x82\xd0\x82\xeb", 'shift_jis') # まつもと ゆきひろ
+ check_both_ways("\u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D",
+ "\xa4\xde\xa4\xc4\xa4\xe2\xa4\xc8 \xa4\xe6\xa4\xad\xa4\xd2\xa4\xed", 'euc-jp')
+ check_both_ways("\u677E\u672C\u884C\u5F18", "\x8f\xbc\x96\x7b\x8d\x73\x8d\x4f", 'shift_jis') # 松本行弘
+ check_both_ways("\u677E\u672C\u884C\u5F18", "\xbe\xbe\xcb\xdc\xb9\xd4\xb9\xb0", 'euc-jp')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-1') # Dürst
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-2')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-3')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-4')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-9')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-10')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-13')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-14')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-15')
+ check_both_ways("r\u00E9sum\u00E9", "r\xE9sum\xE9", 'iso-8859-1') # résumé
+ check_both_ways("\u0065\u006C\u0151\u00ED\u0072\u00E1\u0073", "el\xF5\xEDr\xE1s", 'iso-8859-2') # előírás
+ check_both_ways("\u043F\u0435\u0440\u0435\u0432\u043E\u0434",
+ "\xDF\xD5\xE0\xD5\xD2\xDE\xD4", 'iso-8859-5') # перевод
+ check_both_ways("\u0643\u062A\u0628", "\xE3\xCA\xC8", 'iso-8859-6') # كتب
+ check_both_ways("\u65E5\u8A18", "\x93\xFA\x8BL", 'shift_jis') # 日記
+ check_both_ways("\u65E5\u8A18", "\xC6\xFC\xB5\xAD", 'euc-jp')
+ check_both_ways("\uC560\uC778\uAD6C\uD568\u0020\u6734\uC9C0\uC778",
+ "\xBE\xD6\xC0\xCE\xB1\xB8\xC7\xD4\x20\xDA\xD3\xC1\xF6\xC0\xCE", 'euc-kr') # 애인구함 朴지인
+ check_both_ways("\uC544\uD58F\uD58F\u0020\uB620\uBC29\uD6BD\uB2D8\u0020\uC0AC\uB791\uD716",
+ "\xBE\xC6\xC1\x64\xC1\x64\x20\x8C\x63\xB9\xE6\xC4\x4F\xB4\xD4\x20\xBB\xE7\xB6\xFB\xC5\x42", 'cp949') # 아햏햏 똠방횽님 사랑휖
+ assert_equal(Encoding::ISO_8859_1, "D\xFCrst".force_encoding('iso-8859-2').encode('iso-8859-1', 'iso-8859-1').encoding)
+ end
+
+ def test_twostep
+ assert_equal("D\xFCrst".force_encoding('iso-8859-2'), "D\xFCrst".encode('iso-8859-2', 'iso-8859-1'))
+ end
+
+ def test_ascii_range
+ encodings = [
+ 'US-ASCII', 'ASCII-8BIT',
+ 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3',
+ 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-6',
+ 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9',
+ 'ISO-8859-10', 'ISO-8859-11', 'ISO-8859-13',
+ 'ISO-8859-14', 'ISO-8859-15',
+ 'EUC-JP', 'SHIFT_JIS', 'EUC-KR'
+ ]
+ all_ascii = (0..127).to_a.pack 'C*'
+ encodings.each do |enc|
+ test_start = all_ascii
+ assert_equal(test_start, test_start.encode('UTF-8',enc).encode(enc).force_encoding('ASCII-8BIT'))
+ end
+ end
+
+ def test_all_bytes
+ encodings_8859 = [
+ 'ISO-8859-1', 'ISO-8859-2',
+ #'ISO-8859-3', # not all bytes used
+ 'ISO-8859-4', 'ISO-8859-5',
+ #'ISO-8859-6', # not all bytes used
+ #'ISO-8859-7', # not all bytes used
+ #'ISO-8859-8', # not all bytes used
+ 'ISO-8859-9', 'ISO-8859-10',
+ #'ISO-8859-11', # not all bytes used
+ #'ISO-8859-12', # not available
+ 'ISO-8859-13','ISO-8859-14','ISO-8859-15',
+ #'ISO-8859-16', # not available
+ ]
+ all_bytes = (0..255).to_a.pack 'C*'
+ encodings_8859.each do |enc|
+ test_start = all_bytes
+ assert_equal(test_start, test_start.encode('UTF-8',enc).encode(enc).force_encoding('ASCII-8BIT'))
+ end
+ end
+
+ def test_windows_874
+ check_both_ways("\u20AC", "\x80", 'windows-874') # €
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-874') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x84".encode("utf-8", 'windows-874') }
+ check_both_ways("\u2026", "\x85", 'windows-874') # …
+ assert_raise(Encoding::UndefinedConversionError) { "\x86".encode("utf-8", 'windows-874') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'windows-874') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-874') }
+ check_both_ways("\u2018", "\x91", 'windows-874') # ‘
+ check_both_ways("\u2014", "\x97", 'windows-874') # —
+ assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-874') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", 'windows-874') }
+ check_both_ways("\u00A0", "\xA0", 'windows-874') # non-breaking space
+ check_both_ways("\u0E0F", "\xAF", 'windows-874') # ฏ
+ check_both_ways("\u0E10", "\xB0", 'windows-874') # ฐ
+ check_both_ways("\u0E1F", "\xBF", 'windows-874') # ฟ
+ check_both_ways("\u0E20", "\xC0", 'windows-874') # ภ
+ check_both_ways("\u0E2F", "\xCF", 'windows-874') # ฯ
+ check_both_ways("\u0E30", "\xD0", 'windows-874') # ะ
+ check_both_ways("\u0E3A", "\xDA", 'windows-874') # ฺ
+ assert_raise(Encoding::UndefinedConversionError) { "\xDB".encode("utf-8", 'windows-874') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xDE".encode("utf-8", 'windows-874') }
+ check_both_ways("\u0E3F", "\xDF", 'windows-874') # ฿
+ check_both_ways("\u0E40", "\xE0", 'windows-874') # เ
+ check_both_ways("\u0E4F", "\xEF", 'windows-874') # ๏
+ check_both_ways("\u0E50", "\xF0", 'windows-874') # ๐
+ check_both_ways("\u0E5B", "\xFB", 'windows-874') # ๛
+ assert_raise(Encoding::UndefinedConversionError) { "\xFC".encode("utf-8", 'windows-874') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'windows-874') }
+ end
+
+ def test_windows_1250
+ check_both_ways("\u20AC", "\x80", 'windows-1250') # €
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1250') }
+ check_both_ways("\u201A", "\x82", 'windows-1250') # ‚
+ assert_raise(Encoding::UndefinedConversionError) { "\x83".encode("utf-8", 'windows-1250') }
+ check_both_ways("\u201E", "\x84", 'windows-1250') # „
+ check_both_ways("\u2021", "\x87", 'windows-1250') # ‡
+ assert_raise(Encoding::UndefinedConversionError) { "\x88".encode("utf-8", 'windows-1250') }
+ check_both_ways("\u2030", "\x89", 'windows-1250') # ‰
+ check_both_ways("\u0179", "\x8F", 'windows-1250') # Ź
+ assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1250') }
+ check_both_ways("\u2018", "\x91", 'windows-1250') # ‘
+ check_both_ways("\u2014", "\x97", 'windows-1250') # —
+ assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-1250') }
+ check_both_ways("\u2122", "\x99", 'windows-1250') # ™
+ check_both_ways("\u00A0", "\xA0", 'windows-1250') # non-breaking space
+ check_both_ways("\u017B", "\xAF", 'windows-1250') # Ż
+ check_both_ways("\u00B0", "\xB0", 'windows-1250') # °
+ check_both_ways("\u017C", "\xBF", 'windows-1250') # ż
+ check_both_ways("\u0154", "\xC0", 'windows-1250') # Ŕ
+ check_both_ways("\u010E", "\xCF", 'windows-1250') # Ď
+ check_both_ways("\u0110", "\xD0", 'windows-1250') # Đ
+ check_both_ways("\u00DF", "\xDF", 'windows-1250') # ß
+ check_both_ways("\u0155", "\xE0", 'windows-1250') # ŕ
+ check_both_ways("\u010F", "\xEF", 'windows-1250') # ď
+ check_both_ways("\u0111", "\xF0", 'windows-1250') # đ
+ check_both_ways("\u02D9", "\xFF", 'windows-1250') # ˙
+ end
+
+ def test_windows_1251
+ check_both_ways("\u0402", "\x80", 'windows-1251') # Ђ
+ check_both_ways("\u20AC", "\x88", 'windows-1251') # €
+ check_both_ways("\u040F", "\x8F", 'windows-1251') # Џ
+ check_both_ways("\u0452", "\x90", 'windows-1251') # ђ
+ assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-1251') }
+ check_both_ways("\u045F", "\x9F", 'windows-1251') # џ
+ check_both_ways("\u00A0", "\xA0", 'windows-1251') # non-breaking space
+ check_both_ways("\u0407", "\xAF", 'windows-1251') # Ї
+ check_both_ways("\u00B0", "\xB0", 'windows-1251') # °
+ check_both_ways("\u0457", "\xBF", 'windows-1251') # ї
+ check_both_ways("\u0410", "\xC0", 'windows-1251') # А
+ check_both_ways("\u041F", "\xCF", 'windows-1251') # П
+ check_both_ways("\u0420", "\xD0", 'windows-1251') # Р
+ check_both_ways("\u042F", "\xDF", 'windows-1251') # Я
+ check_both_ways("\u0430", "\xE0", 'windows-1251') # а
+ check_both_ways("\u043F", "\xEF", 'windows-1251') # п
+ check_both_ways("\u0440", "\xF0", 'windows-1251') # р
+ check_both_ways("\u044F", "\xFF", 'windows-1251') # я
+ end
+
+ def test_windows_1252
+ check_both_ways("\u20AC", "\x80", 'windows-1252') # €
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1252') }
+ check_both_ways("\u201A", "\x82", 'windows-1252') # ‚
+ check_both_ways("\u0152", "\x8C", 'windows-1252') # >Œ
+ assert_raise(Encoding::UndefinedConversionError) { "\x8D".encode("utf-8", 'windows-1252') }
+ check_both_ways("\u017D", "\x8E", 'windows-1252') # Ž
+ assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'windows-1252') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1252') }
+ check_both_ways("\u2018", "\x91", 'windows-1252') #‘
+ check_both_ways("\u0153", "\x9C", 'windows-1252') # œ
+ assert_raise(Encoding::UndefinedConversionError) { "\x9D".encode("utf-8", 'windows-1252') }
+ check_both_ways("\u017E", "\x9E", 'windows-1252') # ž
+ check_both_ways("\u00A0", "\xA0", 'windows-1252') # non-breaking space
+ check_both_ways("\u00AF", "\xAF", 'windows-1252') # ¯
+ check_both_ways("\u00B0", "\xB0", 'windows-1252') # °
+ check_both_ways("\u00BF", "\xBF", 'windows-1252') # ¿
+ check_both_ways("\u00C0", "\xC0", 'windows-1252') # À
+ check_both_ways("\u00CF", "\xCF", 'windows-1252') # Ï
+ check_both_ways("\u00D0", "\xD0", 'windows-1252') # Ð
+ check_both_ways("\u00DF", "\xDF", 'windows-1252') # ß
+ check_both_ways("\u00E0", "\xE0", 'windows-1252') # à
+ check_both_ways("\u00EF", "\xEF", 'windows-1252') # ï
+ check_both_ways("\u00F0", "\xF0", 'windows-1252') # ð
+ check_both_ways("\u00FF", "\xFF", 'windows-1252') # ÿ
+ end
+
+ def test_windows_1253
+ check_both_ways("\u20AC", "\x80", 'windows-1253') # €
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1253') }
+ check_both_ways("\u201A", "\x82", 'windows-1253') # ‚
+ check_both_ways("\u2021", "\x87", 'windows-1253') # ‡
+ assert_raise(Encoding::UndefinedConversionError) { "\x88".encode("utf-8", 'windows-1253') }
+ check_both_ways("\u2030", "\x89", 'windows-1253') # ‰
+ assert_raise(Encoding::UndefinedConversionError) { "\x8A".encode("utf-8", 'windows-1253') }
+ check_both_ways("\u2039", "\x8B", 'windows-1253') # ‹
+ assert_raise(Encoding::UndefinedConversionError) { "\x8C".encode("utf-8", 'windows-1253') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'windows-1253') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1253') }
+ check_both_ways("\u2018", "\x91", 'windows-1253') # ‘
+ check_both_ways("\u2014", "\x97", 'windows-1253') # —
+ assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-1253') }
+ check_both_ways("\u2122", "\x99", 'windows-1253') # ™
+ assert_raise(Encoding::UndefinedConversionError) { "\x9A".encode("utf-8", 'windows-1253') }
+ check_both_ways("\u203A", "\x9B", 'windows-1253') # ›
+ assert_raise(Encoding::UndefinedConversionError) { "\x9C".encode("utf-8", 'windows-1253') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", 'windows-1253') }
+ check_both_ways("\u00A0", "\xA0", 'windows-1253') # non-breaking space
+ check_both_ways("\u2015", "\xAF", 'windows-1253') # ―
+ check_both_ways("\u00B0", "\xB0", 'windows-1253') # °
+ check_both_ways("\u038F", "\xBF", 'windows-1253') # Ώ
+ check_both_ways("\u0390", "\xC0", 'windows-1253') # ΐ
+ check_both_ways("\u039F", "\xCF", 'windows-1253') # Ο
+ check_both_ways("\u03A0", "\xD0", 'windows-1253') # Π
+ check_both_ways("\u03A1", "\xD1", 'windows-1253') # Ρ
+ assert_raise(Encoding::UndefinedConversionError) { "\xD2".encode("utf-8", 'windows-1253') }
+ check_both_ways("\u03A3", "\xD3", 'windows-1253') # Σ
+ check_both_ways("\u03AF", "\xDF", 'windows-1253') # ί
+ check_both_ways("\u03B0", "\xE0", 'windows-1253') # ΰ
+ check_both_ways("\u03BF", "\xEF", 'windows-1253') # ο
+ check_both_ways("\u03C0", "\xF0", 'windows-1253') # π
+ check_both_ways("\u03CE", "\xFE", 'windows-1253') # ώ
+ assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'windows-1253') }
+ end
+
+ def test_windows_1254
+ check_both_ways("\u20AC", "\x80", 'windows-1254') # €
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1254') }
+ check_both_ways("\u201A", "\x82", 'windows-1254') # ‚
+ check_both_ways("\u0152", "\x8C", 'windows-1254') # Œ
+ assert_raise(Encoding::UndefinedConversionError) { "\x8D".encode("utf-8", 'windows-1254') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'windows-1254') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1254') }
+ check_both_ways("\u2018", "\x91", 'windows-1254') # ‘
+ check_both_ways("\u0153", "\x9C", 'windows-1254') # œ
+ assert_raise(Encoding::UndefinedConversionError) { "\x9D".encode("utf-8", 'windows-1254') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x9E".encode("utf-8", 'windows-1254') }
+ check_both_ways("\u0178", "\x9F", 'windows-1254') # Ÿ
+ check_both_ways("\u00A0", "\xA0", 'windows-1254') # non-breaking space
+ check_both_ways("\u00AF", "\xAF", 'windows-1254') # ¯
+ check_both_ways("\u00B0", "\xB0", 'windows-1254') # °
+ check_both_ways("\u00BF", "\xBF", 'windows-1254') # ¿
+ check_both_ways("\u00C0", "\xC0", 'windows-1254') # À
+ check_both_ways("\u00CF", "\xCF", 'windows-1254') # Ï
+ check_both_ways("\u011E", "\xD0", 'windows-1254') # Ğ
+ check_both_ways("\u00DF", "\xDF", 'windows-1254') # ß
+ check_both_ways("\u00E0", "\xE0", 'windows-1254') # à
+ check_both_ways("\u00EF", "\xEF", 'windows-1254') # ï
+ check_both_ways("\u011F", "\xF0", 'windows-1254') # ğ
+ check_both_ways("\u00FF", "\xFF", 'windows-1254') # ÿ
+ end
+
+ def test_windows_1255
+ check_both_ways("\u20AC", "\x80", 'windows-1255') # €
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1255') }
+ check_both_ways("\u201A", "\x82", 'windows-1255') # ‚
+ check_both_ways("\u2030", "\x89", 'windows-1255') # ‰
+ assert_raise(Encoding::UndefinedConversionError) { "\x8A".encode("utf-8", 'windows-1255') }
+ check_both_ways("\u2039", "\x8B", 'windows-1255') # ‹
+ assert_raise(Encoding::UndefinedConversionError) { "\x8C".encode("utf-8", 'windows-1255') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'windows-1255') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1255') }
+ check_both_ways("\u2018", "\x91", 'windows-1255') # ‘
+ check_both_ways("\u2122", "\x99", 'windows-1255') # ™
+ assert_raise(Encoding::UndefinedConversionError) { "\x9A".encode("utf-8", 'windows-1255') }
+ check_both_ways("\u203A", "\x9B", 'windows-1255') # ›
+ assert_raise(Encoding::UndefinedConversionError) { "\x9C".encode("utf-8", 'windows-1255') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", 'windows-1255') }
+ check_both_ways("\u00A0", "\xA0", 'windows-1255') # non-breaking space
+ check_both_ways("\u00A1", "\xA1", 'windows-1255') # ¡
+ check_both_ways("\u00D7", "\xAA", 'windows-1255') # ×
+ check_both_ways("\u00AF", "\xAF", 'windows-1255') # ¯
+ check_both_ways("\u00B0", "\xB0", 'windows-1255') # °
+ check_both_ways("\u00B8", "\xB8", 'windows-1255') # ¸
+ check_both_ways("\u00F7", "\xBA", 'windows-1255') # ÷
+ check_both_ways("\u00BF", "\xBF", 'windows-1255') # ¿
+ check_both_ways("\u05B0", "\xC0", 'windows-1255') # ְ
+ check_both_ways("\u05B9", "\xC9", 'windows-1255') # ֹ
+ assert_raise(Encoding::UndefinedConversionError) { "\xCA".encode("utf-8", 'windows-1255') }
+ check_both_ways("\u05BB", "\xCB", 'windows-1255') # ֻ
+ check_both_ways("\u05BF", "\xCF", 'windows-1255') # ֿ
+ check_both_ways("\u05C0", "\xD0", 'windows-1255') # ׀
+ check_both_ways("\u05F3", "\xD7", 'windows-1255') # ׳
+ check_both_ways("\u05F4", "\xD8", 'windows-1255') # ״
+ assert_raise(Encoding::UndefinedConversionError) { "\xD9".encode("utf-8", 'windows-1255') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xDF".encode("utf-8", 'windows-1255') }
+ check_both_ways("\u05D0", "\xE0", 'windows-1255') # א
+ check_both_ways("\u05DF", "\xEF", 'windows-1255') # ן
+ check_both_ways("\u05E0", "\xF0", 'windows-1255') # נ
+ check_both_ways("\u05EA", "\xFA", 'windows-1255') # ת
+ assert_raise(Encoding::UndefinedConversionError) { "\xFB".encode("utf-8", 'windows-1255') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xFC".encode("utf-8", 'windows-1255') }
+ check_both_ways("\u200E", "\xFD", 'windows-1255') # left-to-right mark
+ check_both_ways("\u200F", "\xFE", 'windows-1255') # right-to-left mark
+ assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'windows-1255') }
+ end
+
+ def test_windows_1256
+ check_both_ways("\u20AC", "\x80", 'windows-1256') # €
+ check_both_ways("\u0679", "\x8A", 'windows-1256') # ٹ
+ check_both_ways("\u0688", "\x8F", 'windows-1256') # ڈ
+ check_both_ways("\u06AF", "\x90", 'windows-1256') # گ
+ check_both_ways("\u06A9", "\x98", 'windows-1256') # ک
+ check_both_ways("\u0691", "\x9A", 'windows-1256') # ڑ
+ check_both_ways("\u06BA", "\x9F", 'windows-1256') # ں
+ check_both_ways("\u00A0", "\xA0", 'windows-1256') # non-breaking space
+ check_both_ways("\u06BE", "\xAA", 'windows-1256') # ھ
+ check_both_ways("\u00AF", "\xAF", 'windows-1256') # ¯
+ check_both_ways("\u00B0", "\xB0", 'windows-1256') # °
+ check_both_ways("\u061F", "\xBF", 'windows-1256') # ؟
+ check_both_ways("\u06C1", "\xC0", 'windows-1256') # ہ
+ check_both_ways("\u062F", "\xCF", 'windows-1256') # د
+ check_both_ways("\u0630", "\xD0", 'windows-1256') # ذ
+ check_both_ways("\u0643", "\xDF", 'windows-1256') # ك
+ check_both_ways("\u00E0", "\xE0", 'windows-1256') # à
+ check_both_ways("\u00EF", "\xEF", 'windows-1256') # ï
+ check_both_ways("\u064B", "\xF0", 'windows-1256') # ًً
+ check_both_ways("\u06D2", "\xFF", 'windows-1256') # ے
+ end
+
+ def test_windows_1257
+ check_both_ways("\u20AC", "\x80", 'windows-1257') # €
+ assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1257') }
+ check_both_ways("\u201A", "\x82", 'windows-1257') # ‚
+ assert_raise(Encoding::UndefinedConversionError) { "\x83".encode("utf-8", 'windows-1257') }
+ check_both_ways("\u201E", "\x84", 'windows-1257') # „
+ check_both_ways("\u2021", "\x87", 'windows-1257') # ‡
+ assert_raise(Encoding::UndefinedConversionError) { "\x88".encode("utf-8", 'windows-1257') }
+ check_both_ways("\u2030", "\x89", 'windows-1257') # ‰
+ assert_raise(Encoding::UndefinedConversionError) { "\x8A".encode("utf-8", 'windows-1257') }
+ check_both_ways("\u2039", "\x8B", 'windows-1257') # ‹
+ assert_raise(Encoding::UndefinedConversionError) { "\x8C".encode("utf-8", 'windows-1257') }
+ check_both_ways("\u00A8", "\x8D", 'windows-1257') # ¨
+ check_both_ways("\u02C7", "\x8E", 'windows-1257') # ˇ
+ check_both_ways("\u00B8", "\x8F", 'windows-1257') # ¸
+ assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1257') }
+ check_both_ways("\u2018", "\x91", 'windows-1257') # ‘
+ check_both_ways("\u2014", "\x97", 'windows-1257') # —
+ assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-1257') }
+ check_both_ways("\u2122", "\x99", 'windows-1257') # ™
+ assert_raise(Encoding::UndefinedConversionError) { "\x9A".encode("utf-8", 'windows-1257') }
+ check_both_ways("\u203A", "\x9B", 'windows-1257') # ›
+ assert_raise(Encoding::UndefinedConversionError) { "\x9C".encode("utf-8", 'windows-1257') }
+ check_both_ways("\u00AF", "\x9D", 'windows-1257') # ¯
+ check_both_ways("\u02DB", "\x9E", 'windows-1257') # ˛
+ assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", 'windows-1257') }
+ check_both_ways("\u00A0", "\xA0", 'windows-1257') # non-breaking space
+ assert_raise(Encoding::UndefinedConversionError) { "\xA1".encode("utf-8", 'windows-1257') }
+ check_both_ways("\u00A2", "\xA2", 'windows-1257') # ¢
+ check_both_ways("\u00A4", "\xA4", 'windows-1257') # ¤
+ assert_raise(Encoding::UndefinedConversionError) { "\xA5".encode("utf-8", 'windows-1257') }
+ check_both_ways("\u00A6", "\xA6", 'windows-1257') # ¦
+ check_both_ways("\u00C6", "\xAF", 'windows-1257') # Æ
+ check_both_ways("\u00B0", "\xB0", 'windows-1257') # °
+ check_both_ways("\u00E6", "\xBF", 'windows-1257') # æ
+ check_both_ways("\u0104", "\xC0", 'windows-1257') # Ą
+ check_both_ways("\u013B", "\xCF", 'windows-1257') # Ļ
+ check_both_ways("\u0160", "\xD0", 'windows-1257') # Š
+ check_both_ways("\u00DF", "\xDF", 'windows-1257') # ß
+ check_both_ways("\u0105", "\xE0", 'windows-1257') # ą
+ check_both_ways("\u013C", "\xEF", 'windows-1257') # ļ
+ check_both_ways("\u0161", "\xF0", 'windows-1257') # š
+ check_both_ways("\u02D9", "\xFF", 'windows-1257') # ˙
+ end
+
+ def test_IBM437
+ check_both_ways("\u00C7", "\x80", 'IBM437') # Ç
+ check_both_ways("\u00C5", "\x8F", 'IBM437') # Å
+ check_both_ways("\u00C9", "\x90", 'IBM437') # É
+ check_both_ways("\u0192", "\x9F", 'IBM437') # ƒ
+ check_both_ways("\u00E1", "\xA0", 'IBM437') # á
+ check_both_ways("\u00BB", "\xAF", 'IBM437') # »
+ check_both_ways("\u2591", "\xB0", 'IBM437') # ░
+ check_both_ways("\u2510", "\xBF", 'IBM437') # ┐
+ check_both_ways("\u2514", "\xC0", 'IBM437') # └
+ check_both_ways("\u2567", "\xCF", 'IBM437') # ╧
+ check_both_ways("\u2568", "\xD0", 'IBM437') # ╨
+ check_both_ways("\u2580", "\xDF", 'IBM437') # ▀
+ check_both_ways("\u03B1", "\xE0", 'IBM437') # α
+ check_both_ways("\u2229", "\xEF", 'IBM437') # ∩
+ check_both_ways("\u2261", "\xF0", 'IBM437') # ≡
+ check_both_ways("\u00A0", "\xFF", 'IBM437') # non-breaking space
+ end
+
+ def test_IBM775
+ check_both_ways("\u0106", "\x80", 'IBM775') # Ć
+ check_both_ways("\u00C5", "\x8F", 'IBM775') # Å
+ check_both_ways("\u00C9", "\x90", 'IBM775') # É
+ check_both_ways("\u00A4", "\x9F", 'IBM775') # ¤
+ check_both_ways("\u0100", "\xA0", 'IBM775') # Ā
+ check_both_ways("\u00BB", "\xAF", 'IBM775') # »
+ check_both_ways("\u2591", "\xB0", 'IBM775') # ░
+ check_both_ways("\u2510", "\xBF", 'IBM775') # ┐
+ check_both_ways("\u2514", "\xC0", 'IBM775') # └
+ check_both_ways("\u017D", "\xCF", 'IBM775') # Ž
+ check_both_ways("\u0105", "\xD0", 'IBM775') # ą
+ check_both_ways("\u2580", "\xDF", 'IBM775') # ▀
+ check_both_ways("\u00D3", "\xE0", 'IBM775') # Ó
+ check_both_ways("\u2019", "\xEF", 'IBM775') # ’
+ check_both_ways("\u00AD", "\xF0", 'IBM775') # osft hyphen
+ check_both_ways("\u00A0", "\xFF", 'IBM775') # non-breaking space
+ end
+
+ def test_IBM852
+ check_both_ways("\u00C7", "\x80", 'IBM852') # Ç
+ check_both_ways("\u0106", "\x8F", 'IBM852') # Ć
+ check_both_ways("\u00C9", "\x90", 'IBM852') # É
+ check_both_ways("\u010D", "\x9F", 'IBM852') # č
+ check_both_ways("\u00E1", "\xA0", 'IBM852') # á
+ check_both_ways("\u00BB", "\xAF", 'IBM852') # »
+ check_both_ways("\u2591", "\xB0", 'IBM852') # ░
+ check_both_ways("\u2510", "\xBF", 'IBM852') # ┐
+ check_both_ways("\u2514", "\xC0", 'IBM852') # └
+ check_both_ways("\u00A4", "\xCF", 'IBM852') # ¤
+ check_both_ways("\u0111", "\xD0", 'IBM852') # đ
+ check_both_ways("\u2580", "\xDF", 'IBM852') # ▀
+ check_both_ways("\u00D3", "\xE0", 'IBM852') # Ó
+ check_both_ways("\u00B4", "\xEF", 'IBM852') # ´
+ check_both_ways("\u00AD", "\xF0", 'IBM852') # osft hyphen
+ check_both_ways("\u00A0", "\xFF", 'IBM852') # non-breaking space
+ end
+
+ def test_IBM855
+ check_both_ways("\u0452", "\x80", 'IBM855') # ђ
+ check_both_ways("\u0408", "\x8F", 'IBM855') # Ј
+ check_both_ways("\u0459", "\x90", 'IBM855') # љ
+ check_both_ways("\u042A", "\x9F", 'IBM855') # Ъ
+ check_both_ways("\u0430", "\xA0", 'IBM855') # а
+ check_both_ways("\u00BB", "\xAF", 'IBM855') # »
+ check_both_ways("\u2591", "\xB0", 'IBM855') # ░
+ check_both_ways("\u2510", "\xBF", 'IBM855') # ┐
+ check_both_ways("\u2514", "\xC0", 'IBM855') # └
+ check_both_ways("\u00A4", "\xCF", 'IBM855') # ¤
+ check_both_ways("\u043B", "\xD0", 'IBM855') # л
+ check_both_ways("\u2580", "\xDF", 'IBM855') # ▀
+ check_both_ways("\u042F", "\xE0", 'IBM855') # Я
+ check_both_ways("\u2116", "\xEF", 'IBM855') # №
+ check_both_ways("\u00AD", "\xF0", 'IBM855') # osft hyphen
+ check_both_ways("\u00A0", "\xFF", 'IBM855') # non-breaking space
+ end
+
+ def test_IBM857
+ check_both_ways("\u00C7", "\x80", 'IBM857') # Ç
+ check_both_ways("\u00C5", "\x8F", 'IBM857') # Å
+ check_both_ways("\u00C9", "\x90", 'IBM857') # É
+ check_both_ways("\u015F", "\x9F", 'IBM857') # ş
+ check_both_ways("\u00E1", "\xA0", 'IBM857') # á
+ check_both_ways("\u00BB", "\xAF", 'IBM857') # »
+ check_both_ways("\u2591", "\xB0", 'IBM857') # ░
+ check_both_ways("\u2510", "\xBF", 'IBM857') # ┐
+ check_both_ways("\u2514", "\xC0", 'IBM857') # └
+ check_both_ways("\u00A4", "\xCF", 'IBM857') # ¤
+ check_both_ways("\u00BA", "\xD0", 'IBM857') # º
+ check_both_ways("\u00C8", "\xD4", 'IBM857') # È
+ assert_raise(Encoding::UndefinedConversionError) { "\xD5".encode("utf-8", 'IBM857') }
+ check_both_ways("\u00CD", "\xD6", 'IBM857') # Í
+ check_both_ways("\u2580", "\xDF", 'IBM857') # ▀
+ check_both_ways("\u00D3", "\xE0", 'IBM857') # Ó
+ check_both_ways("\u00B5", "\xE6", 'IBM857') # µ
+ assert_raise(Encoding::UndefinedConversionError) { "\xE7".encode("utf-8", 'IBM857') }
+ check_both_ways("\u00D7", "\xE8", 'IBM857') # ×
+ check_both_ways("\u00B4", "\xEF", 'IBM857') # ´
+ check_both_ways("\u00AD", "\xF0", 'IBM857') # soft hyphen
+ check_both_ways("\u00B1", "\xF1", 'IBM857') # ±
+ assert_raise(Encoding::UndefinedConversionError) { "\xF2".encode("utf-8", 'IBM857') }
+ check_both_ways("\u00BE", "\xF3", 'IBM857') # ¾
+ check_both_ways("\u00A0", "\xFF", 'IBM857') # non-breaking space
+ end
+
+ def test_IBM860
+ check_both_ways("\u00C7", "\x80", 'IBM860') # Ç
+ check_both_ways("\u00C2", "\x8F", 'IBM860') # Â
+ check_both_ways("\u00C9", "\x90", 'IBM860') # É
+ check_both_ways("\u00D3", "\x9F", 'IBM860') # Ó
+ check_both_ways("\u00E1", "\xA0", 'IBM860') # á
+ check_both_ways("\u00BB", "\xAF", 'IBM860') # »
+ check_both_ways("\u2591", "\xB0", 'IBM860') # ░
+ check_both_ways("\u2510", "\xBF", 'IBM860') # ┐
+ check_both_ways("\u2514", "\xC0", 'IBM860') # └
+ check_both_ways("\u2567", "\xCF", 'IBM860') # ╧
+ check_both_ways("\u2568", "\xD0", 'IBM860') # ╨
+ check_both_ways("\u2580", "\xDF", 'IBM860') # ▀
+ check_both_ways("\u03B1", "\xE0", 'IBM860') # α
+ check_both_ways("\u2229", "\xEF", 'IBM860') # ∩
+ check_both_ways("\u2261", "\xF0", 'IBM860') # ≡
+ check_both_ways("\u00A0", "\xFF", 'IBM860') # non-breaking space
+ end
+
+ def test_IBM861
+ check_both_ways("\u00C7", "\x80", 'IBM861') # Ç
+ check_both_ways("\u00C5", "\x8F", 'IBM861') # Å
+ check_both_ways("\u00C9", "\x90", 'IBM861') # É
+ check_both_ways("\u0192", "\x9F", 'IBM861') # ƒ
+ check_both_ways("\u00E1", "\xA0", 'IBM861') # á
+ check_both_ways("\u00BB", "\xAF", 'IBM861') # »
+ check_both_ways("\u2591", "\xB0", 'IBM861') # ░
+ check_both_ways("\u2510", "\xBF", 'IBM861') # ┐
+ check_both_ways("\u2514", "\xC0", 'IBM861') # └
+ check_both_ways("\u2567", "\xCF", 'IBM861') # ╧
+ check_both_ways("\u2568", "\xD0", 'IBM861') # ╨
+ check_both_ways("\u2580", "\xDF", 'IBM861') # ▀
+ check_both_ways("\u03B1", "\xE0", 'IBM861') # α
+ check_both_ways("\u2229", "\xEF", 'IBM861') # ∩
+ check_both_ways("\u2261", "\xF0", 'IBM861') # ≡
+ check_both_ways("\u00A0", "\xFF", 'IBM861') # non-breaking space
+ end
+
+ def test_IBM862
+ check_both_ways("\u05D0", "\x80", 'IBM862') # א
+ check_both_ways("\u05DF", "\x8F", 'IBM862') # ן
+ check_both_ways("\u05E0", "\x90", 'IBM862') # נ
+ check_both_ways("\u0192", "\x9F", 'IBM862') # ƒ
+ check_both_ways("\u00E1", "\xA0", 'IBM862') # á
+ check_both_ways("\u00BB", "\xAF", 'IBM862') # »
+ check_both_ways("\u2591", "\xB0", 'IBM862') # ░
+ check_both_ways("\u2510", "\xBF", 'IBM862') # ┐
+ check_both_ways("\u2514", "\xC0", 'IBM862') # └
+ check_both_ways("\u2567", "\xCF", 'IBM862') # ╧
+ check_both_ways("\u2568", "\xD0", 'IBM862') # ╨
+ check_both_ways("\u2580", "\xDF", 'IBM862') # ▀
+ check_both_ways("\u03B1", "\xE0", 'IBM862') # α
+ check_both_ways("\u2229", "\xEF", 'IBM862') # ∩
+ check_both_ways("\u2261", "\xF0", 'IBM862') # ≡
+ check_both_ways("\u00A0", "\xFF", 'IBM862') # non-breaking space
+ end
+
+ def test_IBM863
+ check_both_ways("\u00C7", "\x80", 'IBM863') # Ç
+ check_both_ways("\u00A7", "\x8F", 'IBM863') # §
+ check_both_ways("\u00C9", "\x90", 'IBM863') # É
+ check_both_ways("\u0192", "\x9F", 'IBM863') # ƒ
+ check_both_ways("\u00A6", "\xA0", 'IBM863') # ¦
+ check_both_ways("\u00BB", "\xAF", 'IBM863') # »
+ check_both_ways("\u2591", "\xB0", 'IBM863') # ░
+ check_both_ways("\u2510", "\xBF", 'IBM863') # ┐
+ check_both_ways("\u2514", "\xC0", 'IBM863') # └
+ check_both_ways("\u2567", "\xCF", 'IBM863') # ╧
+ check_both_ways("\u2568", "\xD0", 'IBM863') # ╨
+ check_both_ways("\u2580", "\xDF", 'IBM863') # ▀
+ check_both_ways("\u03B1", "\xE0", 'IBM863') # α
+ check_both_ways("\u2229", "\xEF", 'IBM863') # ∩
+ check_both_ways("\u2261", "\xF0", 'IBM863') # ≡
+ check_both_ways("\u00A0", "\xFF", 'IBM863') # non-breaking space
+ end
+
+ def test_IBM865
+ check_both_ways("\u00C7", "\x80", 'IBM865') # Ç
+ check_both_ways("\u00C5", "\x8F", 'IBM865') # Å
+ check_both_ways("\u00C9", "\x90", 'IBM865') # É
+ check_both_ways("\u0192", "\x9F", 'IBM865') # ƒ
+ check_both_ways("\u00E1", "\xA0", 'IBM865') # á
+ check_both_ways("\u00A4", "\xAF", 'IBM865') # ¤
+ check_both_ways("\u2591", "\xB0", 'IBM865') # ░
+ check_both_ways("\u2510", "\xBF", 'IBM865') # ┐
+ check_both_ways("\u2514", "\xC0", 'IBM865') # └
+ check_both_ways("\u2567", "\xCF", 'IBM865') # ╧
+ check_both_ways("\u2568", "\xD0", 'IBM865') # ╨
+ check_both_ways("\u2580", "\xDF", 'IBM865') # ▀
+ check_both_ways("\u03B1", "\xE0", 'IBM865') # α
+ check_both_ways("\u2229", "\xEF", 'IBM865') # ∩
+ check_both_ways("\u2261", "\xF0", 'IBM865') # ≡
+ check_both_ways("\u00A0", "\xFF", 'IBM865') # non-breaking space
+ end
+
+ def test_IBM866
+ check_both_ways("\u0410", "\x80", 'IBM866') # А
+ check_both_ways("\u041F", "\x8F", 'IBM866') # П
+ check_both_ways("\u0420", "\x90", 'IBM866') # Р
+ check_both_ways("\u042F", "\x9F", 'IBM866') # Я
+ check_both_ways("\u0430", "\xA0", 'IBM866') # а
+ check_both_ways("\u043F", "\xAF", 'IBM866') # п
+ check_both_ways("\u2591", "\xB0", 'IBM866') # ░
+ check_both_ways("\u2510", "\xBF", 'IBM866') # ┐
+ check_both_ways("\u2514", "\xC0", 'IBM866') # └
+ check_both_ways("\u2567", "\xCF", 'IBM866') # ╧
+ check_both_ways("\u2568", "\xD0", 'IBM866') # ╨
+ check_both_ways("\u2580", "\xDF", 'IBM866') # ▀
+ check_both_ways("\u0440", "\xE0", 'IBM866') # р
+ check_both_ways("\u044F", "\xEF", 'IBM866') # я
+ check_both_ways("\u0401", "\xF0", 'IBM866') # Ё
+ check_both_ways("\u00A0", "\xFF", 'IBM866') # non-breaking space
+ end
+
+ def test_IBM869
+ assert_raise(Encoding::UndefinedConversionError) { "\x80".encode("utf-8", 'IBM869') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x85".encode("utf-8", 'IBM869') }
+ check_both_ways("\u0386", "\x86", 'IBM869') # Ά
+ assert_raise(Encoding::UndefinedConversionError) { "\x87".encode("utf-8", 'IBM869') }
+ check_both_ways("\u00B7", "\x88", 'IBM869') # ·
+ check_both_ways("\u0389", "\x8F", 'IBM869') # Ή
+ check_both_ways("\u038A", "\x90", 'IBM869') # Ί
+ check_both_ways("\u038C", "\x92", 'IBM869') # Ό
+ assert_raise(Encoding::UndefinedConversionError) { "\x93".encode("utf-8", 'IBM869') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x94".encode("utf-8", 'IBM869') }
+ check_both_ways("\u038E", "\x95", 'IBM869') # Ύ
+ check_both_ways("\u03AF", "\x9F", 'IBM869') # ί
+ check_both_ways("\u03CA", "\xA0", 'IBM869') # ϊ
+ check_both_ways("\u00BB", "\xAF", 'IBM869') # »
+ check_both_ways("\u2591", "\xB0", 'IBM869') # ░
+ check_both_ways("\u2510", "\xBF", 'IBM869') # ┐
+ check_both_ways("\u2514", "\xC0", 'IBM869') # └
+ check_both_ways("\u03A3", "\xCF", 'IBM869') # Σ
+ check_both_ways("\u03A4", "\xD0", 'IBM869') # Τ
+ check_both_ways("\u2580", "\xDF", 'IBM869') # ▀
+ check_both_ways("\u03B6", "\xE0", 'IBM869') # ζ
+ check_both_ways("\u0384", "\xEF", 'IBM869') # ΄
+ check_both_ways("\u00AD", "\xF0", 'IBM869') # soft hyphen
+ check_both_ways("\u00A0", "\xFF", 'IBM869') # non-breaking space
+ end
+
+ def test_macCroatian
+ check_both_ways("\u00C4", "\x80", 'macCroatian') # Ä
+ check_both_ways("\u00E8", "\x8F", 'macCroatian') # è
+ check_both_ways("\u00EA", "\x90", 'macCroatian') # ê
+ check_both_ways("\u00FC", "\x9F", 'macCroatian') # ü
+ check_both_ways("\u2020", "\xA0", 'macCroatian') # †
+ check_both_ways("\u00D8", "\xAF", 'macCroatian') # Ø
+ check_both_ways("\u221E", "\xB0", 'macCroatian') # ∞
+ check_both_ways("\u00F8", "\xBF", 'macCroatian') # ø
+ check_both_ways("\u00BF", "\xC0", 'macCroatian') # ¿
+ check_both_ways("\u0153", "\xCF", 'macCroatian') # œ
+ check_both_ways("\u0110", "\xD0", 'macCroatian') # Đ
+ check_both_ways("\u00A9", "\xD9", 'macCroatian') # ©
+ check_both_ways("\u2044", "\xDA", 'macCroatian') # ⁄
+ check_both_ways("\u203A", "\xDD", 'macCroatian') # ›
+ check_both_ways("\u00C6", "\xDE", 'macCroatian') # Æ
+ check_both_ways("\u00BB", "\xDF", 'macCroatian') # »
+ check_both_ways("\u2013", "\xE0", 'macCroatian') # –
+ check_both_ways("\u00B7", "\xE1", 'macCroatian') # ·
+ check_both_ways("\u00C2", "\xE5", 'macCroatian') # Â
+ check_both_ways("\u0107", "\xE6", 'macCroatian') # ć
+ check_both_ways("\u00C1", "\xE7", 'macCroatian') # Á
+ check_both_ways("\u010D", "\xE8", 'macCroatian') # č
+ check_both_ways("\u00C8", "\xE9", 'macCroatian') # È
+ check_both_ways("\u00D4", "\xEF", 'macCroatian') # Ô
+ check_both_ways("\u0111", "\xF0", 'macCroatian') # đ
+ check_both_ways("\u00D2", "\xF1", 'macCroatian') # Ò
+ check_both_ways("\u00AF", "\xF8", 'macCroatian') # ¯
+ check_both_ways("\u03C0", "\xF9", 'macCroatian') # π
+ check_both_ways("\u00CB", "\xFA", 'macCroatian') # Ë
+ check_both_ways("\u00CA", "\xFD", 'macCroatian') # Ê
+ check_both_ways("\u00E6", "\xFE", 'macCroatian') # æ
+ check_both_ways("\u02C7", "\xFF", 'macCroatian') # ˇ
+ end
+
+ def test_macCyrillic
+ check_both_ways("\u0410", "\x80", 'macCyrillic') # А
+ check_both_ways("\u041F", "\x8F", 'macCyrillic') # П
+ check_both_ways("\u0420", "\x90", 'macCyrillic') # Р
+ check_both_ways("\u042F", "\x9F", 'macCyrillic') # Я
+ check_both_ways("\u2020", "\xA0", 'macCyrillic') # †
+ check_both_ways("\u0453", "\xAF", 'macCyrillic') # ѓ
+ check_both_ways("\u221E", "\xB0", 'macCyrillic') # ∞
+ check_both_ways("\u045A", "\xBF", 'macCyrillic') # њ
+ check_both_ways("\u0458", "\xC0", 'macCyrillic') # ј
+ check_both_ways("\u0455", "\xCF", 'macCyrillic') # ѕ
+ check_both_ways("\u2013", "\xD0", 'macCyrillic') # –
+ check_both_ways("\u044F", "\xDF", 'macCyrillic') # я
+ check_both_ways("\u0430", "\xE0", 'macCyrillic') # а
+ check_both_ways("\u043F", "\xEF", 'macCyrillic') # п
+ check_both_ways("\u0440", "\xF0", 'macCyrillic') # р
+ check_both_ways("\u00A4", "\xFF", 'macCyrillic') # ¤
+ end
+
+ def test_macGreek
+ check_both_ways("\u00C4", "\x80", 'macGreek') # Ä
+ check_both_ways("\u00E8", "\x8F", 'macGreek') # è
+ check_both_ways("\u00EA", "\x90", 'macGreek') # ê
+ check_both_ways("\u00FC", "\x9F", 'macGreek') # ü
+ check_both_ways("\u2020", "\xA0", 'macGreek') # †
+ check_both_ways("\u0393", "\xA1", 'macGreek') # Γ
+ check_both_ways("\u0387", "\xAF", 'macGreek') # ·
+ check_both_ways("\u0391", "\xB0", 'macGreek') # Α
+ check_both_ways("\u03A9", "\xBF", 'macGreek') # Ω
+ check_both_ways("\u03AC", "\xC0", 'macGreek') # ά
+ check_both_ways("\u0153", "\xCF", 'macGreek') # œ
+ check_both_ways("\u2013", "\xD0", 'macGreek') # –
+ check_both_ways("\u038F", "\xDF", 'macGreek') # Ώ
+ check_both_ways("\u03CD", "\xE0", 'macGreek') # ύ
+ check_both_ways("\u03BF", "\xEF", 'macGreek') # ο
+ check_both_ways("\u03C0", "\xF0", 'macGreek') # π
+ check_both_ways("\u03B0", "\xFE", 'macGreek') # ΰ
+ assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'macGreek') }
+ end
+
+ def test_macIceland
+ check_both_ways("\u00C4", "\x80", 'macIceland') # Ä
+ check_both_ways("\u00E8", "\x8F", 'macIceland') # è
+ check_both_ways("\u00EA", "\x90", 'macIceland') # ê
+ check_both_ways("\u00FC", "\x9F", 'macIceland') # ü
+ check_both_ways("\u00DD", "\xA0", 'macIceland') # Ý
+ check_both_ways("\u00D8", "\xAF", 'macIceland') # Ø
+ check_both_ways("\u221E", "\xB0", 'macIceland') # ∞
+ check_both_ways("\u00F8", "\xBF", 'macIceland') # ø
+ check_both_ways("\u00BF", "\xC0", 'macIceland') # ¿
+ check_both_ways("\u0153", "\xCF", 'macIceland') # œ
+ check_both_ways("\u2013", "\xD0", 'macIceland') # –
+ check_both_ways("\u00FE", "\xDF", 'macIceland') # þ
+ check_both_ways("\u00FD", "\xE0", 'macIceland') # ý
+ check_both_ways("\u00D4", "\xEF", 'macIceland') # Ô
+ #check_both_ways("\uF8FF", "\xF0", 'macIceland') # Apple logo
+ check_both_ways("\u02C7", "\xFF", 'macIceland') # ˇ
+ end
+
+ def test_macRoman
+ check_both_ways("\u00C4", "\x80", 'macRoman') # Ä
+ check_both_ways("\u00E8", "\x8F", 'macRoman') # è
+ check_both_ways("\u00EA", "\x90", 'macRoman') # ê
+ check_both_ways("\u00FC", "\x9F", 'macRoman') # ü
+ check_both_ways("\u2020", "\xA0", 'macRoman') # †
+ #check_both_ways("\u00DB", "\xAF", 'macRoman') # Ø
+ check_both_ways("\u221E", "\xB0", 'macRoman') # ∞
+ check_both_ways("\u00F8", "\xBF", 'macRoman') # ø
+ check_both_ways("\u00BF", "\xC0", 'macRoman') # ¿
+ check_both_ways("\u0153", "\xCF", 'macRoman') # œ
+ check_both_ways("\u2013", "\xD0", 'macRoman') # –
+ check_both_ways("\u00A4", "\xDB", 'macRoman') # ¤
+ check_both_ways("\uFB02", "\xDF", 'macRoman') # fl
+ check_both_ways("\u2021", "\xE0", 'macRoman') # ‡
+ check_both_ways("\u00D4", "\xEF", 'macRoman') # Ô
+ #check_both_ways("\uF8FF", "\xF0", 'macRoman') # Apple logo
+ check_both_ways("\u02C7", "\xFF", 'macRoman') # ˇ
+ end
+
+ def test_macRomania
+ check_both_ways("\u00C4", "\x80", 'macRomania') # Ä
+ check_both_ways("\u00E8", "\x8F", 'macRomania') # è
+ check_both_ways("\u00EA", "\x90", 'macRomania') # ê
+ check_both_ways("\u00FC", "\x9F", 'macRomania') # ü
+ check_both_ways("\u2020", "\xA0", 'macRomania') # †
+ check_both_ways("\u015E", "\xAF", 'macRomania') # Ş
+ check_both_ways("\u221E", "\xB0", 'macRomania') # ∞
+ check_both_ways("\u015F", "\xBF", 'macRomania') # ş
+ check_both_ways("\u00BF", "\xC0", 'macRomania') # ¿
+ check_both_ways("\u0153", "\xCF", 'macRomania') # œ
+ check_both_ways("\u2013", "\xD0", 'macRomania') # –
+ check_both_ways("\u00A4", "\xDB", 'macRomania') # €
+ check_both_ways("\u0163", "\xDF", 'macRomania') # ţ
+ check_both_ways("\u2021", "\xE0", 'macRomania') # ‡
+ check_both_ways("\u00D4", "\xEF", 'macRomania') # Ô
+ #check_both_ways("\uF8FF", "\xF0", 'macRomania') # Apple logo
+ check_both_ways("\u02C7", "\xFF", 'macRomania') # ˇ
+ end
+
+ def test_macTurkish
+ check_both_ways("\u00C4", "\x80", 'macTurkish') # Ä
+ check_both_ways("\u00E8", "\x8F", 'macTurkish') # è
+ check_both_ways("\u00EA", "\x90", 'macTurkish') # ê
+ check_both_ways("\u00FC", "\x9F", 'macTurkish') # ü
+ check_both_ways("\u2020", "\xA0", 'macTurkish') # †
+ check_both_ways("\u00D8", "\xAF", 'macTurkish') # Ø
+ check_both_ways("\u221E", "\xB0", 'macTurkish') # ∞
+ check_both_ways("\u00F8", "\xBF", 'macTurkish') # ø
+ check_both_ways("\u00BF", "\xC0", 'macTurkish') # ¿
+ check_both_ways("\u0153", "\xCF", 'macTurkish') # œ
+ check_both_ways("\u2013", "\xD0", 'macTurkish') # –
+ check_both_ways("\u015F", "\xDF", 'macTurkish') # ş
+ check_both_ways("\u2021", "\xE0", 'macTurkish') # ‡
+ check_both_ways("\u00D4", "\xEF", 'macTurkish') # Ô
+ #check_both_ways("\uF8FF", "\xF0", 'macTurkish') # Apple logo
+ check_both_ways("\u00D9", "\xF4", 'macTurkish') # Ù
+ assert_raise(Encoding::UndefinedConversionError) { "\xF5".encode("utf-8", 'macTurkish') }
+ check_both_ways("\u02C6", "\xF6", 'macTurkish') # ˆ
+ check_both_ways("\u02C7", "\xFF", 'macTurkish') # ˇ
+ end
+
+ def test_macUkraine
+ check_both_ways("\u0410", "\x80", 'macUkraine') # А
+ check_both_ways("\u041F", "\x8F", 'macUkraine') # П
+ check_both_ways("\u0420", "\x90", 'macUkraine') # Р
+ check_both_ways("\u042F", "\x9F", 'macUkraine') # Я
+ check_both_ways("\u2020", "\xA0", 'macUkraine') # †
+ check_both_ways("\u0453", "\xAF", 'macUkraine') # ѓ
+ check_both_ways("\u221E", "\xB0", 'macUkraine') # ∞
+ check_both_ways("\u045A", "\xBF", 'macUkraine') # њ
+ check_both_ways("\u0458", "\xC0", 'macUkraine') # ј
+ check_both_ways("\u0455", "\xCF", 'macUkraine') # ѕ
+ check_both_ways("\u2013", "\xD0", 'macUkraine') # –
+ check_both_ways("\u044F", "\xDF", 'macUkraine') # я
+ check_both_ways("\u0430", "\xE0", 'macUkraine') # а
+ check_both_ways("\u043F", "\xEF", 'macUkraine') # п
+ check_both_ways("\u0440", "\xF0", 'macUkraine') # р
+ check_both_ways("\u00A4", "\xFF", 'macUkraine') # ¤
+ end
+
+ def test_koi8_u
+ check_both_ways("\u2500", "\x80", 'KOI8-U') # ─
+ check_both_ways("\u2590", "\x8F", 'KOI8-U') # ▐
+ check_both_ways("\u2591", "\x90", 'KOI8-U') # ░
+ check_both_ways("\u00F7", "\x9F", 'KOI8-U') # ÷
+ check_both_ways("\u2550", "\xA0", 'KOI8-U') # ═
+ check_both_ways("\u0454", "\xA4", 'KOI8-U') # є
+ check_both_ways("\u0456", "\xA6", 'KOI8-U') # і
+ check_both_ways("\u0457", "\xA7", 'KOI8-U') # ї
+ check_both_ways("\u0491", "\xAD", 'KOI8-U') # ґ
+ check_both_ways("\u255E", "\xAF", 'KOI8-U') # ╞
+ check_both_ways("\u255F", "\xB0", 'KOI8-U') # ╟
+ check_both_ways("\u0404", "\xB4", 'KOI8-U') # Є
+ check_both_ways("\u0406", "\xB6", 'KOI8-U') # І
+ check_both_ways("\u0407", "\xB7", 'KOI8-U') # Ї
+ check_both_ways("\u0490", "\xBD", 'KOI8-U') # Ґ
+ check_both_ways("\u00A9", "\xBF", 'KOI8-U') # ©
+ check_both_ways("\u044E", "\xC0", 'KOI8-U') # ю
+ check_both_ways("\u043E", "\xCF", 'KOI8-U') # о
+ check_both_ways("\u043F", "\xD0", 'KOI8-U') # п
+ check_both_ways("\u044A", "\xDF", 'KOI8-U') # ъ
+ check_both_ways("\u042E", "\xE0", 'KOI8-U') # Ю
+ check_both_ways("\u041E", "\xEF", 'KOI8-U') # О
+ check_both_ways("\u041F", "\xF0", 'KOI8-U') # П
+ check_both_ways("\u042A", "\xFF", 'KOI8-U') # Ъ
+ end
+
+ def test_koi8_r
+ check_both_ways("\u2500", "\x80", 'KOI8-R') # ─
+ check_both_ways("\u2590", "\x8F", 'KOI8-R') # ▐
+ check_both_ways("\u2591", "\x90", 'KOI8-R') # ░
+ check_both_ways("\u00F7", "\x9F", 'KOI8-R') # ÷
+ check_both_ways("\u2550", "\xA0", 'KOI8-R') # ═
+ check_both_ways("\u255E", "\xAF", 'KOI8-R') # ╞
+ check_both_ways("\u255F", "\xB0", 'KOI8-R') # ╟
+ check_both_ways("\u00A9", "\xBF", 'KOI8-R') # ©
+ check_both_ways("\u044E", "\xC0", 'KOI8-R') # ю
+ check_both_ways("\u043E", "\xCF", 'KOI8-R') # о
+ check_both_ways("\u043F", "\xD0", 'KOI8-R') # п
+ check_both_ways("\u044A", "\xDF", 'KOI8-R') # ъ
+ check_both_ways("\u042E", "\xE0", 'KOI8-R') # Ю
+ check_both_ways("\u041E", "\xEF", 'KOI8-R') # О
+ check_both_ways("\u041F", "\xF0", 'KOI8-R') # П
+ check_both_ways("\u042A", "\xFF", 'KOI8-R') # Ъ
+ end
+
+ def test_TIS_620
+ assert_raise(Encoding::UndefinedConversionError) { "\x80".encode("utf-8", 'TIS-620') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'TIS-620') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'TIS-620') }
+ assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", 'TIS-620') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA0".encode("utf-8", 'TIS-620') }
+ check_both_ways("\u0E01", "\xA1", 'TIS-620') # ก
+ check_both_ways("\u0E0F", "\xAF", 'TIS-620') # ฏ
+ check_both_ways("\u0E10", "\xB0", 'TIS-620') # ฐ
+ check_both_ways("\u0E1F", "\xBF", 'TIS-620') # ฟ
+ check_both_ways("\u0E20", "\xC0", 'TIS-620') # ภ
+ check_both_ways("\u0E2F", "\xCF", 'TIS-620') # ฯ
+ check_both_ways("\u0E30", "\xD0", 'TIS-620') # ะ
+ check_both_ways("\u0E3A", "\xDA", 'TIS-620') # ฺ
+ assert_raise(Encoding::UndefinedConversionError) { "\xDB".encode("utf-8", 'TIS-620') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xDE".encode("utf-8", 'TIS-620') }
+ check_both_ways("\u0E3F", "\xDF", 'TIS-620') # ฿
+ check_both_ways("\u0E40", "\xE0", 'TIS-620') # เ
+ check_both_ways("\u0E4F", "\xEF", 'TIS-620') # ๏
+ check_both_ways("\u0E50", "\xF0", 'TIS-620') # ๐
+ check_both_ways("\u0E5B", "\xFB", 'TIS-620') # ๛
+ assert_raise(Encoding::UndefinedConversionError) { "\xFC".encode("utf-8", 'TIS-620') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'TIS-620') }
+ end
+
+ def test_CP850
+ check_both_ways("\u00C7", "\x80", 'CP850') # Ç
+ check_both_ways("\u00C5", "\x8F", 'CP850') # Å
+ check_both_ways("\u00C9", "\x90", 'CP850') # É
+ check_both_ways("\u0192", "\x9F", 'CP850') # ƒ
+ check_both_ways("\u00E1", "\xA0", 'CP850') # á
+ check_both_ways("\u00BB", "\xAF", 'CP850') # »
+ check_both_ways("\u2591", "\xB0", 'CP850') # ░
+ check_both_ways("\u2510", "\xBF", 'CP850') # ┐
+ check_both_ways("\u2514", "\xC0", 'CP850') # └
+ check_both_ways("\u00A4", "\xCF", 'CP850') # ¤
+ check_both_ways("\u00F0", "\xD0", 'CP850') # ð
+ check_both_ways("\u2580", "\xDF", 'CP850') # ▀
+ check_both_ways("\u00D3", "\xE0", 'CP850') # Ó
+ check_both_ways("\u00B4", "\xEF", 'CP850') # ´
+ check_both_ways("\u00AD", "\xF0", 'CP850') # soft hyphen
+ check_both_ways("\u00A0", "\xFF", 'CP850') # non-breaking space
+ end
+
+ def test_CP852
+ check_both_ways("\u00C7", "\x80", 'CP852') # Ç
+ check_both_ways("\u0106", "\x8F", 'CP852') # Ć
+ check_both_ways("\u00C9", "\x90", 'CP852') # É
+ check_both_ways("\u010D", "\x9F", 'CP852') # č
+ check_both_ways("\u00E1", "\xA0", 'CP852') # á
+ check_both_ways("\u00BB", "\xAF", 'CP852') # »
+ check_both_ways("\u2591", "\xB0", 'CP852') # ░
+ check_both_ways("\u2510", "\xBF", 'CP852') # ┐
+ check_both_ways("\u2514", "\xC0", 'CP852') # └
+ check_both_ways("\u00A4", "\xCF", 'CP852') # ¤
+ check_both_ways("\u0111", "\xD0", 'CP852') # đ
+ check_both_ways("\u2580", "\xDF", 'CP852') # ▀
+ check_both_ways("\u00D3", "\xE0", 'CP852') # Ó
+ check_both_ways("\u00B4", "\xEF", 'CP852') # ´
+ check_both_ways("\u00AD", "\xF0", 'CP852') # soft hyphen
+ check_both_ways("\u00A0", "\xFF", 'CP852') # non-breaking space
+ end
+
+ def test_CP855
+ check_both_ways("\u0452", "\x80", 'CP855') # ђ
+ check_both_ways("\u0408", "\x8F", 'CP855') # Ј
+ check_both_ways("\u0459", "\x90", 'CP855') # љ
+ check_both_ways("\u042A", "\x9F", 'CP855') # Ъ
+ check_both_ways("\u0430", "\xA0", 'CP855') # а
+ check_both_ways("\u00BB", "\xAF", 'CP855') # »
+ check_both_ways("\u2591", "\xB0", 'CP855') # ░
+ check_both_ways("\u2510", "\xBF", 'CP855') # ┐
+ check_both_ways("\u2514", "\xC0", 'CP855') # └
+ check_both_ways("\u00A4", "\xCF", 'CP855') # ¤
+ check_both_ways("\u043B", "\xD0", 'CP855') # л
+ check_both_ways("\u2580", "\xDF", 'CP855') # ▀
+ check_both_ways("\u042F", "\xE0", 'CP855') # Я
+ check_both_ways("\u2116", "\xEF", 'CP855') # №
+ check_both_ways("\u00AD", "\xF0", 'CP855') # soft hyphen
+ check_both_ways("\u00A0", "\xFF", 'CP855') # non-breaking space
+ end
+
+ def check_utf_16_both_ways(utf8, raw)
+ copy = raw.dup
+ 0.step(copy.length-1, 2) { |i| copy[i+1], copy[i] = copy[i], copy[i+1] }
+ check_both_ways(utf8, raw, 'utf-16be')
+ check_both_ways(utf8, copy, 'utf-16le')
+ end
+
+ def test_utf_16
+ check_utf_16_both_ways("abc", "\x00a\x00b\x00c")
+ check_utf_16_both_ways("\u00E9", "\x00\xE9");
+ check_utf_16_both_ways("\u00E9\u0070\u00E9\u0065", "\x00\xE9\x00\x70\x00\xE9\x00\x65") # épée
+ check_utf_16_both_ways("\u677E\u672C\u884C\u5F18", "\x67\x7E\x67\x2C\x88\x4C\x5F\x18") # 松本行弘
+ check_utf_16_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66", "\x97\x52\x5C\x71\x5B\x66\x96\x62\x59\x27\x5B\x66") # 青山学院大学
+ check_utf_16_both_ways("Martin D\u00FCrst", "\x00M\x00a\x00r\x00t\x00i\x00n\x00 \x00D\x00\xFC\x00r\x00s\x00t") # Martin Dürst
+ # BMP
+ check_utf_16_both_ways("\u0000", "\x00\x00")
+ check_utf_16_both_ways("\u007F", "\x00\x7F")
+ check_utf_16_both_ways("\u0080", "\x00\x80")
+ check_utf_16_both_ways("\u0555", "\x05\x55")
+ check_utf_16_both_ways("\u04AA", "\x04\xAA")
+ check_utf_16_both_ways("\u0333", "\x03\x33")
+ check_utf_16_both_ways("\u04CC", "\x04\xCC")
+ check_utf_16_both_ways("\u00F0", "\x00\xF0")
+ check_utf_16_both_ways("\u070F", "\x07\x0F")
+ check_utf_16_both_ways("\u07FF", "\x07\xFF")
+ check_utf_16_both_ways("\u0800", "\x08\x00")
+ check_utf_16_both_ways("\uD7FF", "\xD7\xFF")
+ check_utf_16_both_ways("\uE000", "\xE0\x00")
+ check_utf_16_both_ways("\uFFFF", "\xFF\xFF")
+ check_utf_16_both_ways("\u5555", "\x55\x55")
+ check_utf_16_both_ways("\uAAAA", "\xAA\xAA")
+ check_utf_16_both_ways("\u3333", "\x33\x33")
+ check_utf_16_both_ways("\uCCCC", "\xCC\xCC")
+ check_utf_16_both_ways("\uF0F0", "\xF0\xF0")
+ check_utf_16_both_ways("\u0F0F", "\x0F\x0F")
+ check_utf_16_both_ways("\uFF00", "\xFF\x00")
+ check_utf_16_both_ways("\u00FF", "\x00\xFF")
+ # outer planes
+ check_utf_16_both_ways("\u{10000}", "\xD8\x00\xDC\x00")
+ check_utf_16_both_ways("\u{FFFFF}", "\xDB\xBF\xDF\xFF")
+ check_utf_16_both_ways("\u{100000}", "\xDB\xC0\xDC\x00")
+ check_utf_16_both_ways("\u{10FFFF}", "\xDB\xFF\xDF\xFF")
+ check_utf_16_both_ways("\u{105555}", "\xDB\xD5\xDD\x55")
+ check_utf_16_both_ways("\u{55555}", "\xD9\x15\xDD\x55")
+ check_utf_16_both_ways("\u{AAAAA}", "\xDA\x6A\xDE\xAA")
+ check_utf_16_both_ways("\u{33333}", "\xD8\x8C\xDF\x33")
+ check_utf_16_both_ways("\u{CCCCC}", "\xDA\xF3\xDC\xCC")
+ check_utf_16_both_ways("\u{8F0F0}", "\xD9\xFC\xDC\xF0")
+ check_utf_16_both_ways("\u{F0F0F}", "\xDB\x83\xDF\x0F")
+ check_utf_16_both_ways("\u{8FF00}", "\xD9\xFF\xDF\x00")
+ check_utf_16_both_ways("\u{F00FF}", "\xDB\x80\xDC\xFF")
+ end
+
+ def check_utf_32_both_ways(utf8, raw)
+ copy = raw.dup
+ 0.step(copy.length-1, 4) do |i|
+ copy[i+3], copy[i+2], copy[i+1], copy[i] = copy[i], copy[i+1], copy[i+2], copy[i+3]
+ end
+ check_both_ways(utf8, raw, 'utf-32be')
+ #check_both_ways(utf8, copy, 'utf-32le')
+ end
+
+ def test_utf_32
+ check_utf_32_both_ways("abc", "\x00\x00\x00a\x00\x00\x00b\x00\x00\x00c")
+ check_utf_32_both_ways("\u00E9", "\x00\x00\x00\xE9");
+ check_utf_32_both_ways("\u00E9\u0070\u00E9\u0065",
+ "\x00\x00\x00\xE9\x00\x00\x00\x70\x00\x00\x00\xE9\x00\x00\x00\x65") # épée
+ check_utf_32_both_ways("\u677E\u672C\u884C\u5F18",
+ "\x00\x00\x67\x7E\x00\x00\x67\x2C\x00\x00\x88\x4C\x00\x00\x5F\x18") # 松本行弘
+ check_utf_32_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66",
+ "\x00\x00\x97\x52\x00\x00\x5C\x71\x00\x00\x5B\x66\x00\x00\x96\x62\x00\x00\x59\x27\x00\x00\x5B\x66") # 青山学院大学
+ check_utf_32_both_ways("Martin D\u00FCrst",
+ "\x00\x00\x00M\x00\x00\x00a\x00\x00\x00r\x00\x00\x00t\x00\x00\x00i\x00\x00\x00n\x00\x00\x00 \x00\x00\x00D\x00\x00\x00\xFC\x00\x00\x00r\x00\x00\x00s\x00\x00\x00t") # Martin Dürst
+ # BMP
+ check_utf_32_both_ways("\u0000", "\x00\x00\x00\x00")
+ check_utf_32_both_ways("\u007F", "\x00\x00\x00\x7F")
+ check_utf_32_both_ways("\u0080", "\x00\x00\x00\x80")
+ check_utf_32_both_ways("\u0555", "\x00\x00\x05\x55")
+ check_utf_32_both_ways("\u04AA", "\x00\x00\x04\xAA")
+ check_utf_32_both_ways("\u0333", "\x00\x00\x03\x33")
+ check_utf_32_both_ways("\u04CC", "\x00\x00\x04\xCC")
+ check_utf_32_both_ways("\u00F0", "\x00\x00\x00\xF0")
+ check_utf_32_both_ways("\u070F", "\x00\x00\x07\x0F")
+ check_utf_32_both_ways("\u07FF", "\x00\x00\x07\xFF")
+ check_utf_32_both_ways("\u0800", "\x00\x00\x08\x00")
+ check_utf_32_both_ways("\uD7FF", "\x00\x00\xD7\xFF")
+ check_utf_32_both_ways("\uE000", "\x00\x00\xE0\x00")
+ check_utf_32_both_ways("\uFFFF", "\x00\x00\xFF\xFF")
+ check_utf_32_both_ways("\u5555", "\x00\x00\x55\x55")
+ check_utf_32_both_ways("\uAAAA", "\x00\x00\xAA\xAA")
+ check_utf_32_both_ways("\u3333", "\x00\x00\x33\x33")
+ check_utf_32_both_ways("\uCCCC", "\x00\x00\xCC\xCC")
+ check_utf_32_both_ways("\uF0F0", "\x00\x00\xF0\xF0")
+ check_utf_32_both_ways("\u0F0F", "\x00\x00\x0F\x0F")
+ check_utf_32_both_ways("\uFF00", "\x00\x00\xFF\x00")
+ check_utf_32_both_ways("\u00FF", "\x00\x00\x00\xFF")
+ # outer planes
+ check_utf_32_both_ways("\u{10000}", "\x00\x01\x00\x00")
+ check_utf_32_both_ways("\u{FFFFF}", "\x00\x0F\xFF\xFF")
+ check_utf_32_both_ways("\u{100000}","\x00\x10\x00\x00")
+ check_utf_32_both_ways("\u{10FFFF}","\x00\x10\xFF\xFF")
+ check_utf_32_both_ways("\u{105555}","\x00\x10\x55\x55")
+ check_utf_32_both_ways("\u{55555}", "\x00\x05\x55\x55")
+ check_utf_32_both_ways("\u{AAAAA}", "\x00\x0A\xAA\xAA")
+ check_utf_32_both_ways("\u{33333}", "\x00\x03\x33\x33")
+ check_utf_32_both_ways("\u{CCCCC}", "\x00\x0C\xCC\xCC")
+ check_utf_32_both_ways("\u{8F0F0}", "\x00\x08\xF0\xF0")
+ check_utf_32_both_ways("\u{F0F0F}", "\x00\x0F\x0F\x0F")
+ check_utf_32_both_ways("\u{8FF00}", "\x00\x08\xFF\x00")
+ check_utf_32_both_ways("\u{F00FF}", "\x00\x0F\x00\xFF")
+ end
+
+ def test_invalid_ignore
+ # arguments only
+ assert_nothing_raised { 'abc'.encode('utf-8', invalid: :replace, replace: "") }
+ # check handling of UTF-8 ill-formed subsequences
+ assert_equal("\x00\x41\x00\x3E\x00\x42".force_encoding('UTF-16BE'),
+ "\x41\xC2\x3E\x42".encode('UTF-16BE', 'UTF-8', invalid: :replace, replace: ""))
+ assert_equal("\x00\x41\x00\xF1\x00\x42".force_encoding('UTF-16BE'),
+ "\x41\xC2\xC3\xB1\x42".encode('UTF-16BE', 'UTF-8', invalid: :replace, replace: ""))
+ assert_equal("\x00\x42".force_encoding('UTF-16BE'),
+ "\xF0\x80\x80\x42".encode('UTF-16BE', 'UTF-8', invalid: :replace, replace: ""))
+ assert_equal(''.force_encoding('UTF-16BE'),
+ "\x82\xAB".encode('UTF-16BE', 'UTF-8', invalid: :replace, replace: ""))
+
+ assert_equal("\e$B!!\e(B".force_encoding("ISO-2022-JP"),
+ "\xA1\xA1\xFF".encode("ISO-2022-JP", "EUC-JP", invalid: :replace, replace: ""))
+ assert_equal("\e$B\x24\x22\x24\x24\e(B".force_encoding("ISO-2022-JP"),
+ "\xA4\xA2\xFF\xA4\xA4".encode("ISO-2022-JP", "EUC-JP", invalid: :replace, replace: ""))
+ assert_equal("\e$B\x24\x22\x24\x24\e(B".force_encoding("ISO-2022-JP"),
+ "\xA4\xA2\xFF\xFF\xA4\xA4".encode("ISO-2022-JP", "EUC-JP", invalid: :replace, replace: ""))
+ end
+
+ def test_invalid_replace
+ # arguments only
+ assert_nothing_raised { 'abc'.encode('UTF-8', invalid: :replace) }
+ assert_equal("\xEF\xBF\xBD".force_encoding("UTF-8"),
+ "\x80".encode("UTF-8", "UTF-16BE", invalid: :replace))
+ assert_equal("\xFF\xFD".force_encoding("UTF-16BE"),
+ "\x80".encode("UTF-16BE", "UTF-8", invalid: :replace))
+ assert_equal("\xFD\xFF".force_encoding("UTF-16LE"),
+ "\x80".encode("UTF-16LE", "UTF-8", invalid: :replace))
+ assert_equal("\x00\x00\xFF\xFD".force_encoding("UTF-32BE"),
+ "\x80".encode("UTF-32BE", "UTF-8", invalid: :replace))
+ assert_equal("\xFD\xFF\x00\x00".force_encoding("UTF-32LE"),
+ "\x80".encode("UTF-32LE", "UTF-8", invalid: :replace))
+
+ assert_equal("\uFFFD!",
+ "\xdc\x00\x00!".encode("utf-8", "utf-16be", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\xd8\x00\x00!".encode("utf-8", "utf-16be", :invalid=>:replace))
+
+ assert_equal("\uFFFD!",
+ "\x00\xdc!\x00".encode("utf-8", "utf-16le", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\x00\xd8!\x00".encode("utf-8", "utf-16le", :invalid=>:replace))
+
+ assert_equal("\uFFFD!",
+ "\x01\x00\x00\x00\x00\x00\x00!".encode("utf-8", "utf-32be", :invalid=>:replace), "[ruby-dev:35726]")
+ assert_equal("\uFFFD!",
+ "\x00\xff\x00\x00\x00\x00\x00!".encode("utf-8", "utf-32be", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\x00\x00\xd8\x00\x00\x00\x00!".encode("utf-8", "utf-32be", :invalid=>:replace))
+
+ assert_equal("\uFFFD!",
+ "\x00\x00\x00\xff!\x00\x00\x00".encode("utf-8", "utf-32le", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\x00\x00\xff\x00!\x00\x00\x00".encode("utf-8", "utf-32le", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\x00\xd8\x00\x00!\x00\x00\x00".encode("utf-8", "utf-32le", :invalid=>:replace))
+
+ assert_equal("\uFFFD!",
+ "\xff!".encode("utf-8", "euc-jp", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\xa1!".encode("utf-8", "euc-jp", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\x8f\xa1!".encode("utf-8", "euc-jp", :invalid=>:replace))
+
+ assert_equal("?",
+ "\xdc\x00".encode("EUC-JP", "UTF-16BE", :invalid=>:replace), "[ruby-dev:35776]")
+ assert_equal("ab?cd?ef",
+ "\0a\0b\xdc\x00\0c\0d\xdf\x00\0e\0f".encode("EUC-JP", "UTF-16BE", :invalid=>:replace))
+
+ assert_equal("\e$B!!\e(B?".force_encoding("ISO-2022-JP"),
+ "\xA1\xA1\xFF".encode("ISO-2022-JP", "EUC-JP", invalid: :replace))
+ assert_equal("\e$B\x24\x22\e(B?\e$B\x24\x24\e(B".force_encoding("ISO-2022-JP"),
+ "\xA4\xA2\xFF\xA4\xA4".encode("ISO-2022-JP", "EUC-JP", invalid: :replace))
+ assert_equal("\e$B\x24\x22\e(B??\e$B\x24\x24\e(B".force_encoding("ISO-2022-JP"),
+ "\xA4\xA2\xFF\xFF\xA4\xA4".encode("ISO-2022-JP", "EUC-JP", invalid: :replace))
+ end
+
+ def test_invalid_replace_string
+ assert_equal("a<x>A", "a\x80A".encode("us-ascii", "euc-jp", :invalid=>:replace, :replace=>"<x>"))
+ end
+
+ def test_undef_replace
+ assert_equal("?", "\u20AC".encode("EUC-JP", :undef=>:replace), "[ruby-dev:35709]")
+ end
+
+ def test_undef_replace_string
+ assert_equal("a<x>A", "a\u3042A".encode("us-ascii", :undef=>:replace, :replace=>"<x>"))
+ end
+
+ def test_shift_jis
+ check_both_ways("\u3000", "\x81\x40", 'shift_jis') # full-width space
+ check_both_ways("\u00D7", "\x81\x7E", 'shift_jis') # ×
+ check_both_ways("\u00F7", "\x81\x80", 'shift_jis') # ÷
+ check_both_ways("\u25C7", "\x81\x9E", 'shift_jis') # ◇
+ check_both_ways("\u25C6", "\x81\x9F", 'shift_jis') # ◆
+ check_both_ways("\u25EF", "\x81\xFC", 'shift_jis') # ◯
+ check_both_ways("\u6A97", "\x9F\x40", 'shift_jis') # 檗
+ check_both_ways("\u6BEF", "\x9F\x7E", 'shift_jis') # 毯
+ check_both_ways("\u9EBE", "\x9F\x80", 'shift_jis') # 麾
+ check_both_ways("\u6CBE", "\x9F\x9E", 'shift_jis') # 沾
+ check_both_ways("\u6CBA", "\x9F\x9F", 'shift_jis') # 沺
+ check_both_ways("\u6ECC", "\x9F\xFC", 'shift_jis') # 滌
+ check_both_ways("\u6F3E", "\xE0\x40", 'shift_jis') # 漾
+ check_both_ways("\u70DD", "\xE0\x7E", 'shift_jis') # 烝
+ check_both_ways("\u70D9", "\xE0\x80", 'shift_jis') # 烙
+ check_both_ways("\u71FC", "\xE0\x9E", 'shift_jis') # 燼
+ check_both_ways("\u71F9", "\xE0\x9F", 'shift_jis') # 燹
+ check_both_ways("\u73F1", "\xE0\xFC", 'shift_jis') # 珱
+ assert_raise(Encoding::UndefinedConversionError) { "\xEF\x40".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xEF\x7E".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xEF\x80".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xEF\x9E".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xEF\x9F".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xEF\xFC".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xF0\x40".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xF0\x7E".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xF0\x80".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xF0\x9E".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xF0\x9F".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xF0\xFC".encode("utf-8", 'shift_jis') }
+ #check_both_ways("\u9ADC", "\xFC\x40", 'shift_jis') # 髜 (IBM extended)
+ assert_raise(Encoding::UndefinedConversionError) { "\xFC\x7E".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xFC\x80".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xFC\x9E".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xFC\x9F".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xFC\xFC".encode("utf-8", 'shift_jis') }
+ check_both_ways("\u677E\u672C\u884C\u5F18", "\x8f\xbc\x96\x7b\x8d\x73\x8d\x4f", 'shift_jis') # 松本行弘
+ check_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66", "\x90\xC2\x8E\x52\x8A\x77\x89\x40\x91\xE5\x8A\x77", 'shift_jis') # 青山学院大学
+ check_both_ways("\u795E\u6797\u7FA9\u535A", "\x90\x5F\x97\xD1\x8B\x60\x94\x8E", 'shift_jis') # 神林義博
+ end
+
+ def test_windows_31j
+ check_both_ways("\u222A", "\x81\xBE", 'Windows-31J') # Union
+ check_both_ways("\uFFE2", "\x81\xCA", 'Windows-31J') # Fullwidth Not Sign
+ check_both_ways("\u2235", "\x81\xE6", 'Windows-31J') # Because
+ check_both_ways("\u2160", "\x87\x54", 'Windows-31J') # Roman Numeral One
+ check_both_ways("\u2170", "\xFA\x40", 'Windows-31J') # Small Roman Numeral One
+ end
+
+ def test_euc_jp
+ check_both_ways("\u3000", "\xA1\xA1", 'euc-jp') # full-width space
+ check_both_ways("\u00D7", "\xA1\xDF", 'euc-jp') # ×
+ check_both_ways("\u00F7", "\xA1\xE0", 'euc-jp') # ÷
+ check_both_ways("\u25C7", "\xA1\xFE", 'euc-jp') # ◇
+ check_both_ways("\u25C6", "\xA2\xA1", 'euc-jp') # ◆
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xAF".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xB9".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xC2".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xC9".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xD1".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xDB".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xEB".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xF1".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xFA".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xFD".encode("utf-8", 'euc-jp') }
+ check_both_ways("\u25EF", "\xA2\xFE", 'euc-jp') # ◯
+ assert_raise(Encoding::UndefinedConversionError) { "\xA3\xAF".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA3\xBA".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA3\xC0".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA3\xDB".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA3\xE0".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA3\xFB".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA4\xF4".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA5\xF7".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA6\xB9".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA6\xC0".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA6\xD9".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA7\xC2".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA7\xD0".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA7\xF2".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA8\xC1".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xCF\xD4".encode("utf-8", 'euc-jp') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xCF\xFE".encode("utf-8", 'euc-jp') }
+ check_both_ways("\u6A97", "\xDD\xA1", 'euc-jp') # 檗
+ check_both_ways("\u6BEF", "\xDD\xDF", 'euc-jp') # 毯
+ check_both_ways("\u9EBE", "\xDD\xE0", 'euc-jp') # 麾
+ check_both_ways("\u6CBE", "\xDD\xFE", 'euc-jp') # 沾
+ check_both_ways("\u6CBA", "\xDE\xA1", 'euc-jp') # 沺
+ check_both_ways("\u6ECC", "\xDE\xFE", 'euc-jp') # 滌
+ check_both_ways("\u6F3E", "\xDF\xA1", 'euc-jp') # 漾
+ check_both_ways("\u70DD", "\xDF\xDF", 'euc-jp') # 烝
+ check_both_ways("\u70D9", "\xDF\xE0", 'euc-jp') # 烙
+ check_both_ways("\u71FC", "\xDF\xFE", 'euc-jp') # 燼
+ check_both_ways("\u71F9", "\xE0\xA1", 'euc-jp') # 燹
+ check_both_ways("\u73F1", "\xE0\xFE", 'euc-jp') # 珱
+ assert_raise(Encoding::UndefinedConversionError) { "\xF4\xA7".encode("utf-8", 'euc-jp') }
+ #check_both_ways("\u9ADC", "\xFC\xE3", 'euc-jp') # 髜 (IBM extended)
+
+ check_both_ways("\u677E\u672C\u884C\u5F18", "\xBE\xBE\xCB\xDC\xB9\xD4\xB9\xB0", 'euc-jp') # 松本行弘
+ check_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66", "\xC0\xC4\xBB\xB3\xB3\xD8\xB1\xA1\xC2\xE7\xB3\xD8", 'euc-jp') # 青山学院大学
+ check_both_ways("\u795E\u6797\u7FA9\u535A", "\xBF\xC0\xCE\xD3\xB5\xC1\xC7\xEE", 'euc-jp') # 神林義博
+ end
+
+ def test_eucjp_ms
+ check_both_ways("\u2116", "\xAD\xE2", 'eucJP-ms') # NUMERO SIGN
+ check_both_ways("\u221A", "\xA2\xE5", 'eucJP-ms') # SQUARE ROOT
+ check_both_ways("\u3231", "\xAD\xEA", 'eucJP-ms') # PARENTHESIZED IDEOGRAPH STOCK
+ check_both_ways("\uFF5E", "\xA1\xC1", 'eucJP-ms') # WAVE DASH
+ end
+
+ def test_eucjp_sjis
+ check_both_ways2("\xa1\xa1", "EUC-JP", "\x81\x40", "Shift_JIS")
+ check_both_ways2("\xa1\xdf", "EUC-JP", "\x81\x7e", "Shift_JIS")
+ check_both_ways2("\xa1\xe0", "EUC-JP", "\x81\x80", "Shift_JIS")
+ check_both_ways2("\xa1\xfe", "EUC-JP", "\x81\x9e", "Shift_JIS")
+ check_both_ways2("\xa2\xa1", "EUC-JP", "\x81\x9f", "Shift_JIS")
+ check_both_ways2("\xa2\xfe", "EUC-JP", "\x81\xfc", "Shift_JIS")
+
+ check_both_ways2("\xdd\xa1", "EUC-JP", "\x9f\x40", "Shift_JIS")
+ check_both_ways2("\xdd\xdf", "EUC-JP", "\x9f\x7e", "Shift_JIS")
+ check_both_ways2("\xdd\xe0", "EUC-JP", "\x9f\x80", "Shift_JIS")
+ check_both_ways2("\xdd\xfe", "EUC-JP", "\x9f\x9e", "Shift_JIS")
+ check_both_ways2("\xde\xa1", "EUC-JP", "\x9f\x9f", "Shift_JIS")
+ check_both_ways2("\xde\xfe", "EUC-JP", "\x9f\xfc", "Shift_JIS")
+
+ check_both_ways2("\xdf\xa1", "EUC-JP", "\xe0\x40", "Shift_JIS")
+ check_both_ways2("\xdf\xdf", "EUC-JP", "\xe0\x7e", "Shift_JIS")
+ check_both_ways2("\xdf\xe0", "EUC-JP", "\xe0\x80", "Shift_JIS")
+ check_both_ways2("\xdf\xfe", "EUC-JP", "\xe0\x9e", "Shift_JIS")
+ check_both_ways2("\xe0\xa1", "EUC-JP", "\xe0\x9f", "Shift_JIS")
+ check_both_ways2("\xe0\xfe", "EUC-JP", "\xe0\xfc", "Shift_JIS")
+
+ check_both_ways2("\xf4\xa1", "EUC-JP", "\xea\x9f", "Shift_JIS")
+ check_both_ways2("\xf4\xa2", "EUC-JP", "\xea\xa0", "Shift_JIS")
+ check_both_ways2("\xf4\xa3", "EUC-JP", "\xea\xa1", "Shift_JIS")
+ check_both_ways2("\xf4\xa4", "EUC-JP", "\xea\xa2", "Shift_JIS") # end of JIS X 0208 1983
+ check_both_ways2("\xf4\xa5", "EUC-JP", "\xea\xa3", "Shift_JIS")
+ check_both_ways2("\xf4\xa6", "EUC-JP", "\xea\xa4", "Shift_JIS") # end of JIS X 0208 1990
+
+ check_both_ways2("\x8e\xa1", "EUC-JP", "\xa1", "Shift_JIS")
+ check_both_ways2("\x8e\xdf", "EUC-JP", "\xdf", "Shift_JIS")
+ end
+
+ def test_eucjp_sjis_unassigned
+ check_both_ways2("\xfd\xa1", "EUC-JP", "\xef\x40", "Shift_JIS")
+ check_both_ways2("\xfd\xa1", "EUC-JP", "\xef\x40", "Shift_JIS")
+ check_both_ways2("\xfd\xdf", "EUC-JP", "\xef\x7e", "Shift_JIS")
+ check_both_ways2("\xfd\xe0", "EUC-JP", "\xef\x80", "Shift_JIS")
+ check_both_ways2("\xfd\xfe", "EUC-JP", "\xef\x9e", "Shift_JIS")
+ check_both_ways2("\xfe\xa1", "EUC-JP", "\xef\x9f", "Shift_JIS")
+ check_both_ways2("\xfe\xfe", "EUC-JP", "\xef\xfc", "Shift_JIS")
+ end
+
+ def test_eucjp_sjis_undef
+ assert_raise(Encoding::UndefinedConversionError) { "\x8e\xe0".encode("Shift_JIS", "EUC-JP") }
+ assert_raise(Encoding::UndefinedConversionError) { "\x8e\xfe".encode("Shift_JIS", "EUC-JP") }
+ assert_raise(Encoding::UndefinedConversionError) { "\x8f\xa1\xa1".encode("Shift_JIS", "EUC-JP") }
+ assert_raise(Encoding::UndefinedConversionError) { "\x8f\xa1\xfe".encode("Shift_JIS", "EUC-JP") }
+ assert_raise(Encoding::UndefinedConversionError) { "\x8f\xfe\xa1".encode("Shift_JIS", "EUC-JP") }
+ assert_raise(Encoding::UndefinedConversionError) { "\x8f\xfe\xfe".encode("Shift_JIS", "EUC-JP") }
+
+ assert_raise(Encoding::UndefinedConversionError) { "\xf0\x40".encode("EUC-JP", "Shift_JIS") }
+ assert_raise(Encoding::UndefinedConversionError) { "\xf0\x7e".encode("EUC-JP", "Shift_JIS") }
+ assert_raise(Encoding::UndefinedConversionError) { "\xf0\x80".encode("EUC-JP", "Shift_JIS") }
+ assert_raise(Encoding::UndefinedConversionError) { "\xf0\xfc".encode("EUC-JP", "Shift_JIS") }
+ assert_raise(Encoding::UndefinedConversionError) { "\xfc\x40".encode("EUC-JP", "Shift_JIS") }
+ assert_raise(Encoding::UndefinedConversionError) { "\xfc\x7e".encode("EUC-JP", "Shift_JIS") }
+ assert_raise(Encoding::UndefinedConversionError) { "\xfc\x80".encode("EUC-JP", "Shift_JIS") }
+ assert_raise(Encoding::UndefinedConversionError) { "\xfc\xfc".encode("EUC-JP", "Shift_JIS") }
+ end
+
+ def test_iso_2022_jp
+ assert_raise(Encoding::InvalidByteSequenceError) { "\x1b(A".encode("utf-8", "iso-2022-jp") }
+ assert_raise(Encoding::InvalidByteSequenceError) { "\x1b$(A".encode("utf-8", "iso-2022-jp") }
+ assert_raise(Encoding::InvalidByteSequenceError) { "\x1b$C".encode("utf-8", "iso-2022-jp") }
+ assert_raise(Encoding::InvalidByteSequenceError) { "\x0e".encode("utf-8", "iso-2022-jp") }
+ assert_raise(Encoding::InvalidByteSequenceError) { "\x80".encode("utf-8", "iso-2022-jp") }
+ assert_raise(Encoding::InvalidByteSequenceError) { "\x1b$(Dd!\x1b(B".encode("utf-8", "iso-2022-jp") }
+ assert_raise(Encoding::UndefinedConversionError) { "\u9299".encode("iso-2022-jp") }
+ assert_raise(Encoding::UndefinedConversionError) { "\uff71\uff72\uff73\uff74\uff75".encode("iso-2022-jp") }
+ assert_raise(Encoding::InvalidByteSequenceError) { "\x1b(I12345\x1b(B".encode("utf-8", "iso-2022-jp") }
+ assert_equal("\xA1\xA1".force_encoding("euc-jp"),
+ "\e$B!!\e(B".encode("EUC-JP", "ISO-2022-JP"))
+ assert_equal("\e$B!!\e(B".force_encoding("ISO-2022-JP"),
+ "\xA1\xA1".encode("ISO-2022-JP", "EUC-JP"))
+ end
+
+ def test_cp50221
+ assert_equal("!", "\e(B\x21".encode("utf-8", "cp50221"))
+ assert_equal("!", "\e(J\x21".encode("utf-8", "cp50221"))
+ assert_equal("\uFF71", "\xB1".encode("utf-8", "cp50221"))
+ assert_equal("\uFF71", "\e(B\xB1".encode("utf-8", "cp50221"))
+ assert_equal("\uFF71", "\e(J\xB1".encode("utf-8", "cp50221"))
+ assert_equal("\uFF71", "\e(I\xB1".encode("utf-8", "cp50221"))
+ assert_equal("\uFF71", "\e(I\x31".encode("utf-8", "cp50221"))
+ assert_equal("\uFF71", "\x0E\xB1".encode("utf-8", "cp50221"))
+ assert_equal("\u3000", "\e$@\x21\x21".encode("utf-8", "cp50221"))
+ assert_equal("\u3000", "\e$B\x21\x21".encode("utf-8", "cp50221"))
+ assert_equal("\u2460", "\e$B\x2D\x21".encode("utf-8", "cp50221"))
+ assert_equal("\u7e8a", "\e$B\x79\x21".encode("utf-8", "cp50221"))
+ assert_equal("\u5fde", "\e$B\x7A\x21".encode("utf-8", "cp50221"))
+ assert_equal("\u72be", "\e$B\x7B\x21".encode("utf-8", "cp50221"))
+ assert_equal("\u91d7", "\e$B\x7C\x21".encode("utf-8", "cp50221"))
+ assert_equal("\e(I!_\e(B", "\xA1\xDF".encode("cp50220","sjis"))
+ end
+
+ def test_cp50221
+ assert_equal("\e$B!#!,\e(B".force_encoding("cp50220"),
+ "\xA1\xDF".encode("cp50220","sjis"))
+ assert_equal("\e$B%*!+%,%I%J!+%N!+%P%\\%^!+%Q%]%\"\e(B".force_encoding("cp50220"),
+ "\xB5\xDE\xB6\xDE\xC4\xDE\xC5\xDE\xC9\xDE\xCA\xDE\xCE\xDE\xCF\xDE\xCA\xDF\xCE\xDF\xB1".
+ encode("cp50220", "sjis"))
+ end
+
+ def test_iso_2022_jp_1
+ # check_both_ways("\u9299", "\x1b$(Dd!\x1b(B", "iso-2022-jp-1") # JIS X 0212 区68 点01 銙
+ end
+
+ def test_unicode_public_review_issue_121 # see http://www.unicode.org/review/pr-121.html
+ # assert_equal("\x00\x61\xFF\xFD\x00\x62".force_encoding('UTF-16BE'),
+ # "\x61\xF1\x80\x80\xE1\x80\xC2\x62".encode('UTF-16BE', 'UTF-8', invalid: :replace)) # option 1
+ assert_equal("\x00\x61\xFF\xFD\xFF\xFD\xFF\xFD\x00\x62".force_encoding('UTF-16BE'),
+ "\x61\xF1\x80\x80\xE1\x80\xC2\x62".encode('UTF-16BE', 'UTF-8', invalid: :replace)) # option 2
+ assert_equal("\x61\x00\xFD\xFF\xFD\xFF\xFD\xFF\x62\x00".force_encoding('UTF-16LE'),
+ "\x61\xF1\x80\x80\xE1\x80\xC2\x62".encode('UTF-16LE', 'UTF-8', invalid: :replace)) # option 2
+ # assert_equal("\x00\x61\xFF\xFD\xFF\xFD\xFF\xFD\xFF\xFD\xFF\xFD\xFF\xFD\x00\x62".force_encoding('UTF-16BE'),
+ # "\x61\xF1\x80\x80\xE1\x80\xC2\x62".encode('UTF-16BE', 'UTF-8', invalid: :replace)) # option 3
+ end
+
+ def test_yen_sign
+ check_both_ways("\u005C", "\x5C", "Shift_JIS")
+ check_both_ways("\u005C", "\x5C", "Windows-31J")
+ check_both_ways("\u005C", "\x5C", "EUC-JP")
+ check_both_ways("\u005C", "\x5C", "eucJP-ms")
+ check_both_ways("\u005C", "\x5C", "CP51932")
+ check_both_ways("\u005C", "\x5C", "ISO-2022-JP")
+ assert_equal("\u005C", "\e(B\x5C\e(B".encode("UTF-8", "ISO-2022-JP"))
+ assert_equal("\u005C", "\e(J\x5C\e(B".encode("UTF-8", "ISO-2022-JP"))
+ assert_equal("\u005C", "\x5C".encode("stateless-ISO-2022-JP", "ISO-2022-JP"))
+ assert_equal("\u005C", "\e(J\x5C\e(B".encode("stateless-ISO-2022-JP", "ISO-2022-JP"))
+ assert_raise(Encoding::UndefinedConversionError) { "\u00A5".encode("Shift_JIS") }
+ assert_raise(Encoding::UndefinedConversionError) { "\u00A5".encode("Windows-31J") }
+ assert_raise(Encoding::UndefinedConversionError) { "\u00A5".encode("EUC-JP") }
+ assert_raise(Encoding::UndefinedConversionError) { "\u00A5".encode("eucJP-ms") }
+ assert_raise(Encoding::UndefinedConversionError) { "\u00A5".encode("CP51932") }
+
+ # FULLWIDTH REVERSE SOLIDUS
+ check_both_ways("\uFF3C", "\x81\x5F", "Shift_JIS")
+ check_both_ways("\uFF3C", "\x81\x5F", "Windows-31J")
+ check_both_ways("\uFF3C", "\xA1\xC0", "EUC-JP")
+ check_both_ways("\uFF3C", "\xA1\xC0", "eucJP-ms")
+ check_both_ways("\uFF3C", "\xA1\xC0", "CP51932")
+ end
+
+ def test_tilde_overline
+ check_both_ways("\u007E", "\x7E", "Shift_JIS")
+ check_both_ways("\u007E", "\x7E", "Windows-31J")
+ check_both_ways("\u007E", "\x7E", "EUC-JP")
+ check_both_ways("\u007E", "\x7E", "eucJP-ms")
+ check_both_ways("\u007E", "\x7E", "CP51932")
+ check_both_ways("\u007E", "\x7E", "ISO-2022-JP")
+ assert_equal("\u007E", "\e(B\x7E\e(B".encode("UTF-8", "ISO-2022-JP"))
+ assert_equal("\u007E", "\e(J\x7E\e(B".encode("UTF-8", "ISO-2022-JP"))
+ assert_equal("\u007E", "\x7E".encode("stateless-ISO-2022-JP", "ISO-2022-JP"))
+ assert_equal("\u007E", "\e(J\x7E\e(B".encode("stateless-ISO-2022-JP", "ISO-2022-JP"))
+ assert_raise(Encoding::UndefinedConversionError) { "\u203E".encode("Shift_JIS") }
+ assert_raise(Encoding::UndefinedConversionError) { "\u203E".encode("Windows-31J") }
+ assert_raise(Encoding::UndefinedConversionError) { "\u203E".encode("EUC-JP") }
+ assert_raise(Encoding::UndefinedConversionError) { "\u203E".encode("eucJP-ms") }
+ assert_raise(Encoding::UndefinedConversionError) { "\u203E".encode("CP51932") }
+ end
+
+ def test_gb2312
+ check_both_ways("\u3000", "\xA1\xA1", 'GB2312') # full-width space
+ check_both_ways("\u3013", "\xA1\xFE", 'GB2312') # 〓
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xB0".encode("utf-8", 'GB2312') }
+ check_both_ways("\u2488", "\xA2\xB1", 'GB2312') # ⒈
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xE4".encode("utf-8", 'GB2312') }
+ check_both_ways("\u3220", "\xA2\xE5", 'GB2312') # ㈠
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xF0".encode("utf-8", 'GB2312') }
+ check_both_ways("\u2160", "\xA2\xF1", 'GB2312') # Ⅰ
+ check_both_ways("\uFF01", "\xA3\xA1", 'GB2312') # !
+ check_both_ways("\uFFE3", "\xA3\xFE", 'GB2312') #  ̄
+ check_both_ways("\u3041", "\xA4\xA1", 'GB2312') # ぁ
+ check_both_ways("\u30A1", "\xA5\xA1", 'GB2312') # ァ
+ check_both_ways("\u0391", "\xA6\xA1", 'GB2312') # Α
+ check_both_ways("\u03B1", "\xA6\xC1", 'GB2312') # α
+ check_both_ways("\u0410", "\xA7\xA1", 'GB2312') # А
+ check_both_ways("\u0430", "\xA7\xD1", 'GB2312') # а
+ check_both_ways("\u0101", "\xA8\xA1", 'GB2312') # ā
+ assert_raise(Encoding::UndefinedConversionError) { "\xA8\xC4".encode("utf-8", 'GB2312') }
+ check_both_ways("\u3105", "\xA8\xC5", 'GB2312') # ㄅ
+ assert_raise(Encoding::UndefinedConversionError) { "\xA9\xA3".encode("utf-8", 'GB2312') }
+ check_both_ways("\u2500", "\xA9\xA4", 'GB2312') # ─
+ check_both_ways("\u554A", "\xB0\xA1", 'GB2312') # 啊
+ check_both_ways("\u5265", "\xB0\xFE", 'GB2312') # 剥
+ check_both_ways("\u4FCA", "\xBF\xA1", 'GB2312') # 俊
+ check_both_ways("\u5080", "\xBF\xFE", 'GB2312') # 傀
+ check_both_ways("\u9988", "\xC0\xA1", 'GB2312') # 馈
+ check_both_ways("\u4FD0", "\xC0\xFE", 'GB2312') # 俐
+ check_both_ways("\u7A00", "\xCF\xA1", 'GB2312') # 稀
+ check_both_ways("\u6653", "\xCF\xFE", 'GB2312') # 晓
+ check_both_ways("\u5C0F", "\xD0\xA1", 'GB2312') # 小
+ check_both_ways("\u7384", "\xD0\xFE", 'GB2312') # 玄
+ check_both_ways("\u4F4F", "\xD7\xA1", 'GB2312') # 住
+ check_both_ways("\u5EA7", "\xD7\xF9", 'GB2312') # 座
+ assert_raise(Encoding::UndefinedConversionError) { "\xD7\xFA".encode("utf-8", 'GB2312') }
+ check_both_ways("\u647A", "\xDF\xA1", 'GB2312') # 摺
+ check_both_ways("\u553C", "\xDF\xFE", 'GB2312') # 唼
+ check_both_ways("\u5537", "\xE0\xA1", 'GB2312') # 唷
+ check_both_ways("\u5E3C", "\xE0\xFE", 'GB2312') # 帼
+ check_both_ways("\u94E9", "\xEF\xA1", 'GB2312') # 铩
+ check_both_ways("\u7A14", "\xEF\xFE", 'GB2312') # 稔
+ check_both_ways("\u7A39", "\xF0\xA1", 'GB2312') # 稹
+ check_both_ways("\u7619", "\xF0\xFE", 'GB2312') # 瘙
+ check_both_ways("\u9CCC", "\xF7\xA1", 'GB2312') # 鳌
+ check_both_ways("\u9F44", "\xF7\xFE", 'GB2312') # 齄
+ check_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66", "\xC7\xE0\xC9\xBD\xD1\xA7\xD4\xBA\xB4\xF3\xD1\xA7", 'GB2312') # 青山学院大学
+ end
+
+ def test_gbk
+ check_both_ways("\u4E02", "\x81\x40", 'GBK') # 丂
+ check_both_ways("\u4E8A", "\x81\x7E", 'GBK') # 亊
+ check_both_ways("\u4E90", "\x81\x80", 'GBK') # 亐
+ check_both_ways("\u4FA2", "\x81\xFE", 'GBK') # 侢
+ check_both_ways("\u5EC6", "\x8F\x40", 'GBK') # 廆
+ check_both_ways("\u5F24", "\x8F\x7E", 'GBK') # 弤
+ check_both_ways("\u5F28", "\x8F\x80", 'GBK') # 弨
+ check_both_ways("\u6007", "\x8F\xFE", 'GBK') # 怇
+ check_both_ways("\u6008", "\x90\x40", 'GBK') # 怈
+ check_both_ways("\u6080", "\x90\x7E", 'GBK') # 悀
+ check_both_ways("\u6081", "\x90\x80", 'GBK') # 悁
+ check_both_ways("\u6146", "\x90\xFE", 'GBK') # 慆
+ check_both_ways("\u70DC", "\x9F\x40", 'GBK') # 烜
+ check_both_ways("\u7134", "\x9F\x7E", 'GBK') # 焴
+ check_both_ways("\u7135", "\x9F\x80", 'GBK') # 焵
+ check_both_ways("\u71D3", "\x9F\xFE", 'GBK') # 燓
+ check_both_ways("\u71D6", "\xA0\x40", 'GBK') # 燖
+ check_both_ways("\u721A", "\xA0\x7E", 'GBK') # 爚
+ check_both_ways("\u721B", "\xA0\x80", 'GBK') # 爛
+ check_both_ways("\u72DB", "\xA0\xFE", 'GBK') # 狛
+ check_both_ways("\u3000", "\xA1\xA1", 'GBK') # full-width space
+ check_both_ways("\u3001", "\xA1\xA2", 'GBK') # 、
+ check_both_ways("\u3013", "\xA1\xFE", 'GBK') # 〓
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xA0".encode("utf-8", 'GBK') }
+ check_both_ways("\u2170", "\xA2\xA1", 'GBK') # ⅰ
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xB0".encode("utf-8", 'GBK') }
+ check_both_ways("\u2488", "\xA2\xB1", 'GBK') # ⒈
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xE4".encode("utf-8", 'GBK') }
+ check_both_ways("\u3220", "\xA2\xE5", 'GBK') # ㈠
+ assert_raise(Encoding::UndefinedConversionError) { "\xA2\xF0".encode("utf-8", 'GBK') }
+ check_both_ways("\u2160", "\xA2\xF1", 'GBK') # Ⅰ
+ assert_raise(Encoding::UndefinedConversionError) { "\xA3\xA0".encode("utf-8", 'GBK') }
+ check_both_ways("\uFF01", "\xA3\xA1", 'GBK') # !
+ check_both_ways("\uFFE3", "\xA3\xFE", 'GBK') #  ̄
+ assert_raise(Encoding::UndefinedConversionError) { "\xA4\xA0".encode("utf-8", 'GBK') }
+ check_both_ways("\u3041", "\xA4\xA1", 'GBK') # ぁ
+ assert_raise(Encoding::UndefinedConversionError) { "\xA5\xA0".encode("utf-8", 'GBK') }
+ check_both_ways("\u30A1", "\xA5\xA1", 'GBK') # ァ
+ check_both_ways("\u0391", "\xA6\xA1", 'GBK') # Α
+ check_both_ways("\u03B1", "\xA6\xC1", 'GBK') # α
+ assert_raise(Encoding::UndefinedConversionError) { "\xA6\xED".encode("utf-8", 'GBK') }
+ check_both_ways("\uFE3B", "\xA6\xEE", 'GBK') # ︻
+ check_both_ways("\u0410", "\xA7\xA1", 'GBK') # А
+ check_both_ways("\u0430", "\xA7\xD1", 'GBK') # а
+ check_both_ways("\u02CA", "\xA8\x40", 'GBK') # ˊ
+ check_both_ways("\u2587", "\xA8\x7E", 'GBK') # ▇
+ assert_raise(Encoding::UndefinedConversionError) { "\xA8\x96".encode("utf-8", 'GBK') }
+ check_both_ways("\u0101", "\xA8\xA1", 'GBK') # ā
+ assert_raise(Encoding::UndefinedConversionError) { "\xA8\xBC".encode("utf-8", 'GBK') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA8\xBF".encode("utf-8", 'GBK') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA8\xC4".encode("utf-8", 'GBK') }
+ check_both_ways("\u3105", "\xA8\xC5", 'GBK') # ㄅ
+ check_both_ways("\u3021", "\xA9\x40", 'GBK') # 〡
+ assert_raise(Encoding::UndefinedConversionError) { "\xA9\x58".encode("utf-8", 'GBK') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA9\x5B".encode("utf-8", 'GBK') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xA9\x5D".encode("utf-8", 'GBK') }
+ check_both_ways("\u3007", "\xA9\x96", 'GBK') # 〇
+ assert_raise(Encoding::UndefinedConversionError) { "\xA9\xA3".encode("utf-8", 'GBK') }
+ check_both_ways("\u2500", "\xA9\xA4", 'GBK') # ─
+ assert_raise(Encoding::UndefinedConversionError) { "\xA9\xF0".encode("utf-8", 'GBK') }
+ check_both_ways("\u7588", "\xAF\x40", 'GBK') # 疈
+ check_both_ways("\u7607", "\xAF\x7E", 'GBK') # 瘇
+ check_both_ways("\u7608", "\xAF\x80", 'GBK') # 瘈
+ check_both_ways("\u7644", "\xAF\xA0", 'GBK') # 癄
+ assert_raise(Encoding::UndefinedConversionError) { "\xAF\xA1".encode("utf-8", 'GBK') }
+ check_both_ways("\u7645", "\xB0\x40", 'GBK') # 癅
+ check_both_ways("\u769B", "\xB0\x7E", 'GBK') # 皛
+ check_both_ways("\u769C", "\xB0\x80", 'GBK') # 皜
+ check_both_ways("\u5265", "\xB0\xFE", 'GBK') # 剥
+ check_both_ways("\u7DFB", "\xBF\x40", 'GBK') # 緻
+ check_both_ways("\u7E39", "\xBF\x7E", 'GBK') # 縹
+ check_both_ways("\u7E3A", "\xBF\x80", 'GBK') # 縺
+ check_both_ways("\u5080", "\xBF\xFE", 'GBK') # 傀
+ check_both_ways("\u7E5E", "\xC0\x40", 'GBK') # 繞
+ check_both_ways("\u7E9E", "\xC0\x7E", 'GBK') # 纞
+ check_both_ways("\u7EAE", "\xC0\x80", 'GBK') # 纮
+ check_both_ways("\u4FD0", "\xC0\xFE", 'GBK') # 俐
+ check_both_ways("\u87A5", "\xCF\x40", 'GBK') # 螥
+ check_both_ways("\u87F8", "\xCF\x7E", 'GBK') # 蟸
+ check_both_ways("\u87FA", "\xCF\x80", 'GBK') # 蟺
+ check_both_ways("\u6653", "\xCF\xFE", 'GBK') # 晓
+ check_both_ways("\u8824", "\xD0\x40", 'GBK') # 蠤
+ check_both_ways("\u887A", "\xD0\x7E", 'GBK') # 衺
+ check_both_ways("\u887B", "\xD0\x80", 'GBK') # 衻
+ check_both_ways("\u7384", "\xD0\xFE", 'GBK') # 玄
+ check_both_ways("\u9019", "\xDF\x40", 'GBK') # 這
+ check_both_ways("\u9081", "\xDF\x7E", 'GBK') # 邁
+ check_both_ways("\u9084", "\xDF\x80", 'GBK') # 還
+ check_both_ways("\u553C", "\xDF\xFE", 'GBK') # 唼
+ check_both_ways("\u90C2", "\xE0\x40", 'GBK') # 郂
+ check_both_ways("\u911C", "\xE0\x7E", 'GBK') # 鄜
+ check_both_ways("\u911D", "\xE0\x80", 'GBK') # 鄝
+ check_both_ways("\u5E3C", "\xE0\xFE", 'GBK') # 帼
+ check_both_ways("\u986F", "\xEF\x40", 'GBK') # 顯
+ check_both_ways("\u98E4", "\xEF\x7E", 'GBK') # 飤
+ check_both_ways("\u98E5", "\xEF\x80", 'GBK') # 飥
+ check_both_ways("\u7A14", "\xEF\xFE", 'GBK') # 稔
+ check_both_ways("\u9908", "\xF0\x40", 'GBK') # 餈
+ check_both_ways("\u9949", "\xF0\x7E", 'GBK') # 饉
+ check_both_ways("\u994A", "\xF0\x80", 'GBK') # 饊
+ check_both_ways("\u7619", "\xF0\xFE", 'GBK') # 瘙
+ check_both_ways("\u9F32", "\xFD\x40", 'GBK') # 鼲
+ check_both_ways("\u9F78", "\xFD\x7E", 'GBK') # 齸
+ check_both_ways("\u9F79", "\xFD\x80", 'GBK') # 齹
+ check_both_ways("\uF9F1", "\xFD\xA0", 'GBK') # 隣
+ assert_raise(Encoding::UndefinedConversionError) { "\xFD\xA1".encode("utf-8", 'GBK') }
+ check_both_ways("\uFA0C", "\xFE\x40", 'GBK') # 兀
+ check_both_ways("\uFA29", "\xFE\x4F", 'GBK') # 﨩
+ assert_raise(Encoding::UndefinedConversionError) { "\xFE\x50".encode("utf-8", 'GBK') }
+ check_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66", "\xC7\xE0\xC9\xBD\xD1\xA7\xD4\xBA\xB4\xF3\xD1\xA7", 'GBK') # 青山学院大学
+ check_both_ways("\u795E\u6797\u7FA9\u535A", "\xC9\xF1\xC1\xD6\xC1\x78\xB2\xA9", 'GBK') # 神林義博
+ end
+
+ def test_gb18030
+ # overall roundtrip test
+ all_unicode = (0x0..0xD7FF).to_a.pack 'U*' #追加
+ all_unicode << (0xE000..0xFFFF).to_a.pack("U*") #追加
+
+ assert_equal(all_unicode, all_unicode.encode("gb18030").encode("UTF-8")) #追加
+
+ # tests from GBK
+ check_both_ways("\u4E02", "\x81\x40", 'GB18030') #
+ check_both_ways("\u4E8A", "\x81\x7E", 'GB18030') #
+ check_both_ways("\u4E90", "\x81\x80", 'GB18030') #
+ check_both_ways("\u4FA2", "\x81\xFE", 'GB18030') # 侢
+ check_both_ways("\u5EC6", "\x8F\x40", 'GB18030') #
+ check_both_ways("\u5F24", "\x8F\x7E", 'GB18030') # 弤
+ check_both_ways("\u5F28", "\x8F\x80", 'GB18030') # 弨
+ check_both_ways("\u6007", "\x8F\xFE", 'GB18030') #
+ check_both_ways("\u6008", "\x90\x40", 'GB18030') #
+ check_both_ways("\u6080", "\x90\x7E", 'GB18030') # 悀
+ check_both_ways("\u6081", "\x90\x80", 'GB18030') #
+ check_both_ways("\u6146", "\x90\xFE", 'GB18030') #
+ check_both_ways("\u70DC", "\x9F\x40", 'GB18030') #
+ check_both_ways("\u7134", "\x9F\x7E", 'GB18030') # 焴
+ check_both_ways("\u7135", "\x9F\x80", 'GB18030') # 焵
+ check_both_ways("\u71D3", "\x9F\xFE", 'GB18030') #
+ check_both_ways("\u71D6", "\xA0\x40", 'GB18030') #
+ check_both_ways("\u721A", "\xA0\x7E", 'GB18030') #
+ check_both_ways("\u721B", "\xA0\x80", 'GB18030') #
+ check_both_ways("\u72DB", "\xA0\xFE", 'GB18030') #
+ check_both_ways("\u3000", "\xA1\xA1", 'GB18030') # full-width space
+ check_both_ways("\u3001", "\xA1\xA2", 'GB18030') #
+ check_both_ways("\u3013", "\xA1\xFE", 'GB18030') #
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA2\xA0".encode("utf-8", 'GB18030') }
+ check_both_ways("\u2170", "\xA2\xA1", 'GB18030') # ⅰ
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA2\xB0".encode("utf-8", 'GB18030') }
+ check_both_ways("\u2488", "\xA2\xB1", 'GB18030') #
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA2\xE4".encode("utf-8", 'GB18030') }
+ check_both_ways("\u3220", "\xA2\xE5", 'GB18030') # ㈠
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA2\xF0".encode("utf-8", 'GB18030') }
+ check_both_ways("\u2160", "\xA2\xF1", 'GB18030') # Ⅰ
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA3\xA0".encode("utf-8", 'GB18030') }
+ check_both_ways("\uFF01", "\xA3\xA1", 'GB18030') # E
+ check_both_ways("\uFFE3", "\xA3\xFE", 'GB18030') # E
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA4\xA0".encode("utf-8", 'GB18030') }
+ check_both_ways("\u3041", "\xA4\xA1", 'GB18030') #
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA5\xA0".encode("utf-8", 'GB18030') }
+ check_both_ways("\u30A1", "\xA5\xA1", 'GB18030') # ァ
+ check_both_ways("\u0391", "\xA6\xA1", 'GB18030') #
+ check_both_ways("\u03B1", "\xA6\xC1", 'GB18030') # α
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA6\xED".encode("utf-8", 'GB18030') }
+ check_both_ways("\uFE3B", "\xA6\xEE", 'GB18030') # E
+ check_both_ways("\u0410", "\xA7\xA1", 'GB18030') #
+ check_both_ways("\u0430", "\xA7\xD1", 'GB18030') # а
+ check_both_ways("\u02CA", "\xA8\x40", 'GB18030') #
+ check_both_ways("\u2587", "\xA8\x7E", 'GB18030') #
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA8\x96".encode("utf-8", 'GB18030') }
+ check_both_ways("\u0101", "\xA8\xA1", 'GB18030') #
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA8\xBC".encode("utf-8", 'GB18030') }
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA8\xBF".encode("utf-8", 'GB18030') }
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA8\xC4".encode("utf-8", 'GB18030') }
+ check_both_ways("\u3105", "\xA8\xC5", 'GB18030') #
+ check_both_ways("\u3021", "\xA9\x40", 'GB18030') # 〡
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA9\x58".encode("utf-8", 'GB18030') }
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA9\x5B".encode("utf-8", 'GB18030') }
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA9\x5D".encode("utf-8", 'GB18030') }
+ check_both_ways("\u3007", "\xA9\x96", 'GB18030') #
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA9\xA3".encode("utf-8", 'GB18030') }
+ check_both_ways("\u2500", "\xA9\xA4", 'GB18030') # ─
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA9\xF0".encode("utf-8", 'GB18030') }
+ check_both_ways("\u7588", "\xAF\x40", 'GB18030') #
+ check_both_ways("\u7607", "\xAF\x7E", 'GB18030') #
+ check_both_ways("\u7608", "\xAF\x80", 'GB18030') #
+ check_both_ways("\u7644", "\xAF\xA0", 'GB18030') #
+ #assert_raise(Encoding::UndefinedConversionError) { "\xAF\xA1".encode("utf-8", 'GB18030') }
+ check_both_ways("\u7645", "\xB0\x40", 'GB18030') #
+ check_both_ways("\u769B", "\xB0\x7E", 'GB18030') #
+ check_both_ways("\u769C", "\xB0\x80", 'GB18030') #
+ check_both_ways("\u5265", "\xB0\xFE", 'GB18030') # 剥
+ check_both_ways("\u7DFB", "\xBF\x40", 'GB18030') # 緻
+ check_both_ways("\u7E39", "\xBF\x7E", 'GB18030') # 縹
+ check_both_ways("\u7E3A", "\xBF\x80", 'GB18030') # 縺
+ check_both_ways("\u5080", "\xBF\xFE", 'GB18030') # 傀
+ check_both_ways("\u7E5E", "\xC0\x40", 'GB18030') #
+ check_both_ways("\u7E9E", "\xC0\x7E", 'GB18030') #
+ check_both_ways("\u7EAE", "\xC0\x80", 'GB18030') # 纮
+ check_both_ways("\u4FD0", "\xC0\xFE", 'GB18030') #
+ check_both_ways("\u87A5", "\xCF\x40", 'GB18030') # 螥
+ check_both_ways("\u87F8", "\xCF\x7E", 'GB18030') # 蟸
+ check_both_ways("\u87FA", "\xCF\x80", 'GB18030') # 蟺
+ check_both_ways("\u6653", "\xCF\xFE", 'GB18030') #
+ check_both_ways("\u8824", "\xD0\x40", 'GB18030') # 蠤
+ check_both_ways("\u887A", "\xD0\x7E", 'GB18030') # 衺
+ check_both_ways("\u887B", "\xD0\x80", 'GB18030') # 衻
+ check_both_ways("\u7384", "\xD0\xFE", 'GB18030') #
+ check_both_ways("\u9019", "\xDF\x40", 'GB18030') #
+ check_both_ways("\u9081", "\xDF\x7E", 'GB18030') #
+ check_both_ways("\u9084", "\xDF\x80", 'GB18030') #
+ check_both_ways("\u553C", "\xDF\xFE", 'GB18030') # 唼
+ check_both_ways("\u90C2", "\xE0\x40", 'GB18030') #
+ check_both_ways("\u911C", "\xE0\x7E", 'GB18030') #
+ check_both_ways("\u911D", "\xE0\x80", 'GB18030') #
+ check_both_ways("\u5E3C", "\xE0\xFE", 'GB18030') # 帼
+ check_both_ways("\u986F", "\xEF\x40", 'GB18030') # 顯
+ check_both_ways("\u98E4", "\xEF\x7E", 'GB18030') # 飤
+ check_both_ways("\u98E5", "\xEF\x80", 'GB18030') # 飥
+ check_both_ways("\u7A14", "\xEF\xFE", 'GB18030') #
+ check_both_ways("\u9908", "\xF0\x40", 'GB18030') #
+ check_both_ways("\u9949", "\xF0\x7E", 'GB18030') #
+ check_both_ways("\u994A", "\xF0\x80", 'GB18030') #
+ check_both_ways("\u7619", "\xF0\xFE", 'GB18030') #
+ check_both_ways("\u9F32", "\xFD\x40", 'GB18030') # 鼲
+ check_both_ways("\u9F78", "\xFD\x7E", 'GB18030') # 齸
+ check_both_ways("\u9F79", "\xFD\x80", 'GB18030') # 齹
+ check_both_ways("\uF9F1", "\xFD\xA0", 'GB18030') # E
+ #assert_raise(Encoding::UndefinedConversionError) { "\xFD\xA1".encode("utf-8", 'GB18030') }
+ check_both_ways("\uFA0C", "\xFE\x40", 'GB18030') # E
+ check_both_ways("\uFA29", "\xFE\x4F", 'GB18030') # E
+ #assert_raise(Encoding::UndefinedConversionError) { "\xFE\x50".encode("utf-8", 'GB18030') }
+ check_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66", "\xC7\xE0\xC9\xBD\xD1\xA7\xD4\xBA\xB4\xF3\xD1\xA7", 'GB18030') # 青山学院大学
+ check_both_ways("\u795E\u6797\u7FA9\u535A", "\xC9\xF1\xC1\xD6\xC1\x78\xB2\xA9", 'GB18030') # 神林義
+
+ # new tests for GB18030
+ check_both_ways("\u9FA6", "\x82\x35\x8F\x33", 'GB18030') # 龦
+ check_both_ways("\uD7FF", "\x83\x36\xC7\x38", 'GB18030') # No name ()
+
+ check_both_ways("\u0452", "\x81\x30\xD3\x30", 'GB18030') #
+ check_both_ways("\u200F", "\x81\x36\xA5\x31", 'GB18030') # RIGHT-TO-LEFT MARK
+
+ check_both_ways("\uE865", "\x83\x36\xD0\x30", 'GB18030') # No name (Private Use Area)
+ check_both_ways("\uF92B", "\x84\x30\x85\x34", 'GB18030') # E
+
+ check_both_ways("\u2643", "\x81\x37\xA8\x39", 'GB18030') #
+ check_both_ways("\u2E80", "\x81\x38\xFD\x38", 'GB18030') # ⺀
+
+ check_both_ways("\uFA2A", "\x84\x30\x9C\x38", 'GB18030') # E
+ check_both_ways("\uFE2F", "\x84\x31\x85\x37", 'GB18030') # No name (Combining Half Marks)
+
+ check_both_ways("\u3CE1", "\x82\x31\xD4\x38", 'GB18030') # 㳡
+ check_both_ways("\u4055", "\x82\x32\xAF\x32", 'GB18030') #
+
+ check_both_ways("\u361B", "\x82\x30\xA6\x33", 'GB18030') #
+ check_both_ways("\u3917", "\x82\x30\xF2\x37", 'GB18030') #
+
+ check_both_ways("\u49B8", "\x82\x34\xA1\x31", 'GB18030') # 䦸
+ check_both_ways("\u4C76", "\x82\x34\xE7\x33", 'GB18030') # 䱶
+
+ check_both_ways("\u4160", "\x82\x32\xC9\x37", 'GB18030') # 䅠
+ check_both_ways("\u4336", "\x82\x32\xF8\x37", 'GB18030') # 䌶
+
+ check_both_ways("\u478E", "\x82\x33\xE8\x38", 'GB18030') #
+ check_both_ways("\u4946", "\x82\x34\x96\x38", 'GB18030') #
+
+ check_both_ways("\u44D7", "\x82\x33\xA3\x39", 'GB18030') #
+ check_both_ways("\u464B", "\x82\x33\xC9\x31", 'GB18030') #
+
+ check_both_ways("\uFFE6", "\x84\x31\xA2\x34", 'GB18030') # E
+ check_both_ways("\uFFFF", "\x84\x31\xA4\x39", 'GB18030') # not a character
+
+ check_both_ways("\u{10000}", "\x90\x30\x81\x30", 'GB18030') #
+ check_both_ways("\u{10FFFE}", "\xE3\x32\x9A\x34", 'GB18030') # No name (Not a character)
+ check_both_ways("\u{10FFFF}", "\xE3\x32\x9A\x35", 'GB18030') # No name (Not a character)
+ end
+
+ def test_Big5
+ check_both_ways("\u3000", "\xA1\x40", 'Big5') # full-width space
+ check_both_ways("\uFE5A", "\xA1\x7E", 'Big5') # ﹚
+ check_both_ways("\uFE5B", "\xA1\xA1", 'Big5') # ﹛
+ #check_both_ways("\uFF0F", "\xA1\xFE", 'Big5') # /
+ check_both_ways("\uFF57", "\xA3\x40", 'Big5') # w
+ check_both_ways("\u310F", "\xA3\x7E", 'Big5') # ㄏ
+ check_both_ways("\u3110", "\xA3\xA1", 'Big5') # ㄐ
+ check_both_ways("\u02CB", "\xA3\xBF", 'Big5') # ˋ
+ assert_raise(Encoding::UndefinedConversionError) { "\xA3\xC0".encode("utf-8", 'Big5') }
+ check_both_ways("\u6D6C", "\xAF\x40", 'Big5') # 浬
+ check_both_ways("\u7837", "\xAF\x7E", 'Big5') # 砷
+ check_both_ways("\u7825", "\xAF\xA1", 'Big5') # 砥
+ check_both_ways("\u8343", "\xAF\xFE", 'Big5') # 荃
+ check_both_ways("\u8654", "\xB0\x40", 'Big5') # 虔
+ check_both_ways("\u9661", "\xB0\x7E", 'Big5') # 陡
+ check_both_ways("\u965B", "\xB0\xA1", 'Big5') # 陛
+ check_both_ways("\u5A40", "\xB0\xFE", 'Big5') # 婀
+ check_both_ways("\u6FC3", "\xBF\x40", 'Big5') # 濃
+ check_both_ways("\u7E0A", "\xBF\x7E", 'Big5') # 縊
+ check_both_ways("\u7E11", "\xBF\xA1", 'Big5') # 縑
+ check_both_ways("\u931A", "\xBF\xFE", 'Big5') # 錚
+ check_both_ways("\u9310", "\xC0\x40", 'Big5') # 錐
+ check_both_ways("\u5687", "\xC0\x7E", 'Big5') # 嚇
+ check_both_ways("\u568F", "\xC0\xA1", 'Big5') # 嚏
+ check_both_ways("\u77AC", "\xC0\xFE", 'Big5') # 瞬
+ check_both_ways("\u8B96", "\xC6\x40", 'Big5') # 讖
+ check_both_ways("\u7C72", "\xC6\x7E", 'Big5') # 籲
+ #assert_raise(Encoding::UndefinedConversionError) { "\xC6\xA1".encode("utf-8", 'Big5') }
+ #assert_raise(Encoding::UndefinedConversionError) { "\xC7\x40".encode("utf-8", 'Big5') }
+ assert_raise(Encoding::UndefinedConversionError) { "\xC8\x40".encode("utf-8", 'Big5') }
+ check_both_ways("\u4E42", "\xC9\x40", 'Big5') # 乂
+ check_both_ways("\u6C15", "\xC9\x7E", 'Big5') # 氕
+ check_both_ways("\u6C36", "\xC9\xA1", 'Big5') # 氶
+ check_both_ways("\u6C4B", "\xC9\xFE", 'Big5') # 汋
+ check_both_ways("\u67DC", "\xCF\x40", 'Big5') # 柜
+ check_both_ways("\u6D42", "\xCF\x7E", 'Big5') # 浂
+ check_both_ways("\u6D01", "\xCF\xA1", 'Big5') # 洁
+ check_both_ways("\u7A80", "\xCF\xFE", 'Big5') # 窀
+ check_both_ways("\u7A7E", "\xD0\x40", 'Big5') # 穾
+ check_both_ways("\u82EA", "\xD0\x7E", 'Big5') # 苪
+ check_both_ways("\u82E4", "\xD0\xA1", 'Big5') # 苤
+ check_both_ways("\u54F1", "\xD0\xFE", 'Big5') # 哱
+ check_both_ways("\u7A1B", "\xDF\x40", 'Big5') # 稛
+ check_both_ways("\u816F", "\xDF\x7E", 'Big5') # 腯
+ check_both_ways("\u8144", "\xDF\xA1", 'Big5') # 腄
+ check_both_ways("\u89E4", "\xDF\xFE", 'Big5') # 觤
+ check_both_ways("\u89E1", "\xE0\x40", 'Big5') # 觡
+ check_both_ways("\u903F", "\xE0\x7E", 'Big5') # 逿
+ check_both_ways("\u9044", "\xE0\xA1", 'Big5') # 遄
+ check_both_ways("\u50E0", "\xE0\xFE", 'Big5') # 僠
+ check_both_ways("\u979E", "\xEF\x40", 'Big5') # 鞞
+ check_both_ways("\u9D30", "\xEF\x7E", 'Big5') # 鴰
+ check_both_ways("\u9D45", "\xEF\xA1", 'Big5') # 鵅
+ check_both_ways("\u7376", "\xEF\xFE", 'Big5') # 獶
+ check_both_ways("\u74B8", "\xF0\x40", 'Big5') # 璸
+ check_both_ways("\u81D2", "\xF0\x7E", 'Big5') # 臒
+ check_both_ways("\u81D0", "\xF0\xA1", 'Big5') # 臐
+ check_both_ways("\u8E67", "\xF0\xFE", 'Big5') # 蹧
+ check_both_ways("\u7E98", "\xF9\x40", 'Big5') # 纘
+ check_both_ways("\u9F0A", "\xF9\x7E", 'Big5') # 鼊
+ check_both_ways("\u9FA4", "\xF9\xA1", 'Big5') # 龤
+ check_both_ways("\u9F98", "\xF9\xD5", 'Big5') # 龘
+ assert_raise(Encoding::UndefinedConversionError) { "\xF9\xD6".encode("utf-8", 'Big5') }
+ check_both_ways("\u795E\u6797\u7FA9\u535A", "\xAF\xAB\xAA\x4C\xB8\x71\xB3\xD5", 'Big5') # 神林義博
+ end
+
+ def test_Big5_Hkscs
+ check_both_ways("\u3000", "\xA1\x40", 'Big5-HKSCS') # full-width space
+ check_both_ways("\uFE5A", "\xA1\x7E", 'Big5-HKSCS') # ﹚
+ check_both_ways("\uFE5B", "\xA1\xA1", 'Big5-HKSCS') # ﹛
+ #check_both_ways("\uFF0F", "\xA1\xFE", 'Big5-HKSCS') # /
+ check_both_ways("\uFF57", "\xA3\x40", 'Big5-HKSCS') # w
+ check_both_ways("\u310F", "\xA3\x7E", 'Big5-HKSCS') # ㄏ
+ check_both_ways("\u3110", "\xA3\xA1", 'Big5-HKSCS') # ㄐ
+ check_both_ways("\u02CB", "\xA3\xBF", 'Big5-HKSCS') # ˋ
+ #assert_raise(Encoding::UndefinedConversionError) { "\xA3\xC0".encode("utf-8", 'Big5-HKSCS') }
+ check_both_ways("\u6D6C", "\xAF\x40", 'Big5-HKSCS') # 浬
+ check_both_ways("\u7837", "\xAF\x7E", 'Big5-HKSCS') # 砷
+ check_both_ways("\u7825", "\xAF\xA1", 'Big5-HKSCS') # 砥
+ check_both_ways("\u8343", "\xAF\xFE", 'Big5-HKSCS') # 荃
+ check_both_ways("\u8654", "\xB0\x40", 'Big5-HKSCS') # 虔
+ check_both_ways("\u9661", "\xB0\x7E", 'Big5-HKSCS') # 陡
+ check_both_ways("\u965B", "\xB0\xA1", 'Big5-HKSCS') # 陛
+ check_both_ways("\u5A40", "\xB0\xFE", 'Big5-HKSCS') # 婀
+ check_both_ways("\u6FC3", "\xBF\x40", 'Big5-HKSCS') # 濃
+ check_both_ways("\u7E0A", "\xBF\x7E", 'Big5-HKSCS') # 縊
+ check_both_ways("\u7E11", "\xBF\xA1", 'Big5-HKSCS') # 縑
+ check_both_ways("\u931A", "\xBF\xFE", 'Big5-HKSCS') # 錚
+ check_both_ways("\u9310", "\xC0\x40", 'Big5-HKSCS') # 錐
+ check_both_ways("\u5687", "\xC0\x7E", 'Big5-HKSCS') # 嚇
+ check_both_ways("\u568F", "\xC0\xA1", 'Big5-HKSCS') # 嚏
+ check_both_ways("\u77AC", "\xC0\xFE", 'Big5-HKSCS') # 瞬
+ check_both_ways("\u8B96", "\xC6\x40", 'Big5-HKSCS') # 讖
+ check_both_ways("\u7C72", "\xC6\x7E", 'Big5-HKSCS') # 籲
+ #assert_raise(Encoding::UndefinedConversionError) { "\xC6\xA1".encode("utf-8", 'Big5-HKSCS') }
+ #assert_raise(Encoding::UndefinedConversionError) { "\xC7\x40".encode("utf-8", 'Big5-HKSCS') }
+ #assert_raise(Encoding::UndefinedConversionError) { "\xC8\x40".encode("utf-8", 'Big5-HKSCS') }
+ check_both_ways("\u4E42", "\xC9\x40", 'Big5-HKSCS') # 乂
+ check_both_ways("\u6C15", "\xC9\x7E", 'Big5-HKSCS') # 氕
+ check_both_ways("\u6C36", "\xC9\xA1", 'Big5-HKSCS') # 氶
+ check_both_ways("\u6C4B", "\xC9\xFE", 'Big5-HKSCS') # 汋
+ check_both_ways("\u67DC", "\xCF\x40", 'Big5-HKSCS') # 柜
+ check_both_ways("\u6D42", "\xCF\x7E", 'Big5-HKSCS') # 浂
+ check_both_ways("\u6D01", "\xCF\xA1", 'Big5-HKSCS') # 洁
+ check_both_ways("\u7A80", "\xCF\xFE", 'Big5-HKSCS') # 窀
+ check_both_ways("\u7A7E", "\xD0\x40", 'Big5-HKSCS') # 穾
+ check_both_ways("\u82EA", "\xD0\x7E", 'Big5-HKSCS') # 苪
+ check_both_ways("\u82E4", "\xD0\xA1", 'Big5-HKSCS') # 苤
+ check_both_ways("\u54F1", "\xD0\xFE", 'Big5-HKSCS') # 哱
+ check_both_ways("\u7A1B", "\xDF\x40", 'Big5-HKSCS') # 稛
+ check_both_ways("\u816F", "\xDF\x7E", 'Big5-HKSCS') # 腯
+ check_both_ways("\u8144", "\xDF\xA1", 'Big5-HKSCS') # 腄
+ check_both_ways("\u89E4", "\xDF\xFE", 'Big5-HKSCS') # 觤
+ check_both_ways("\u89E1", "\xE0\x40", 'Big5-HKSCS') # 觡
+ check_both_ways("\u903F", "\xE0\x7E", 'Big5-HKSCS') # 逿
+ check_both_ways("\u9044", "\xE0\xA1", 'Big5-HKSCS') # 遄
+ check_both_ways("\u50E0", "\xE0\xFE", 'Big5-HKSCS') # 僠
+ check_both_ways("\u979E", "\xEF\x40", 'Big5-HKSCS') # 鞞
+ check_both_ways("\u9D30", "\xEF\x7E", 'Big5-HKSCS') # 鴰
+ check_both_ways("\u9D45", "\xEF\xA1", 'Big5-HKSCS') # 鵅
+ check_both_ways("\u7376", "\xEF\xFE", 'Big5-HKSCS') # 獶
+ check_both_ways("\u74B8", "\xF0\x40", 'Big5-HKSCS') # 璸
+ check_both_ways("\u81D2", "\xF0\x7E", 'Big5-HKSCS') # 臒
+ check_both_ways("\u81D0", "\xF0\xA1", 'Big5-HKSCS') # 臐
+ check_both_ways("\u8E67", "\xF0\xFE", 'Big5-HKSCS') # 蹧
+ check_both_ways("\u7E98", "\xF9\x40", 'Big5-HKSCS') # 纘
+ check_both_ways("\u9F0A", "\xF9\x7E", 'Big5-HKSCS') # 鼊
+ check_both_ways("\u9FA4", "\xF9\xA1", 'Big5-HKSCS') # 龤
+ check_both_ways("\u9F98", "\xF9\xD5", 'Big5-HKSCS') # 龘
+ check_both_ways("\u{23ED7}", "\x8E\x40", 'Big5-HKSCS') #
+ #assert_raise(Encoding::UndefinedConversionError) { "\xF9\xD6".encode("utf-8", 'Big5-HKSCS') }
+ check_both_ways("\u795E\u6797\u7FA9\u535A", "\xAF\xAB\xAA\x4C\xB8\x71\xB3\xD5", 'Big5-HKSCS') # 神林義博
+ end
+
+ def test_Big5_UAO
+ check_both_ways("\u4e17", "\x81\x40", 'Big5-UAO') # 丗
+ end
+
+ def test_nothing_changed
+ a = "James".force_encoding("US-ASCII")
+ b = a.encode("Shift_JIS")
+ assert_equal(Encoding::US_ASCII, a.encoding)
+ assert_equal(Encoding::Shift_JIS, b.encoding)
+ end
+
+ def test_utf8_mac
+ assert_equal("\u{fb4d}", "\u05DB\u05BF".encode("UTF-8", "UTF8-MAC"))
+ assert_equal("\u{1ff7}", "\u03C9\u0345\u0342".encode("UTF-8", "UTF8-MAC"))
+
+ assert_equal("\u05DB\u05BF", "\u{fb4d}".encode("UTF8-MAC").force_encoding("UTF-8"))
+ assert_equal("\u03C9\u0345\u0342", "\u{1ff7}".encode("UTF8-MAC").force_encoding("UTF-8"))
+
+ check_both_ways("\u{e9 74 e8}", "e\u0301te\u0300", 'UTF8-MAC')
+ end
+
+ def test_fallback
+ assert_equal("\u3042".encode("EUC-JP"), "\u{20000}".encode("EUC-JP",
+ fallback: {"\u{20000}" => "\u3042".encode("EUC-JP")}))
+ assert_equal("\u3042".encode("EUC-JP"), "\u{20000}".encode("EUC-JP",
+ fallback: {"\u{20000}" => "\u3042"}))
+ assert_equal("[ISU]", "\u{1F4BA}".encode("SJIS-KDDI",
+ fallback: {"\u{1F4BA}" => "[ISU]"}))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_undef.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_undef.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_undef.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,37 @@
+require 'test/unit'
+
+class TestUndef < Test::Unit::TestCase
+ class Undef0
+ def foo
+ "foo"
+ end
+ undef foo
+ end
+
+ class Undef1
+ def bar
+ "bar"
+ end
+ end
+
+ class Undef2 < Undef1
+ undef bar
+ end
+
+ def test_undef
+ x = Undef0.new
+ assert_raise(NoMethodError) { x.foo }
+ y = Undef1.new
+ assert_equal "bar", y.bar
+ z = Undef2.new
+ assert_raise(NoMethodError) { z.foo }
+ end
+
+ def test_special_const_undef
+ assert_raise(TypeError) do
+ 1.instance_eval do
+ undef to_s
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_unicode_escape.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_unicode_escape.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_unicode_escape.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,269 @@
+# -*- coding: utf-8 -*-
+
+require 'test/unit'
+
+class TestUnicodeEscape < Test::Unit::TestCase
+ def test_basic
+ assert_equal('Matz - 松本行弘',
+ "Matz - \u677E\u672C\u884C\u5F18")
+ assert_equal('Matz - まつもと ゆきひろ',
+ "Matz - \u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D")
+ assert_equal('Matz - まつもと ゆきひろ',
+ "Matz - \u{307E}\u{3064}\u{3082}\u{3068} \u{3086}\u{304D}\u{3072}\u{308D}")
+ assert_equal('Matz - まつもと ゆきひろ',
+ "Matz - \u{307E 3064 3082 3068 20 3086 304D 3072 308D}")
+ assert_equal("Aoyama Gakuin University - \xE9\x9D\x92\xE5\xB1\xB1\xE5\xAD\xA6\xE9\x99\xA2\xE5\xA4\xA7\xE5\xAD\xA6",
+ "Aoyama Gakuin University - \u9752\u5C71\u5B66\u9662\u5927\u5B66")
+ assert_equal('Aoyama Gakuin University - 青山学院大学',
+ "Aoyama Gakuin University - \u9752\u5C71\u5B66\u9662\u5927\u5B66")
+ assert_equal('青山学院大学', "\u9752\u5C71\u5B66\u9662\u5927\u5B66")
+ assert_equal("Martin D\xC3\xBCrst", "Martin D\u00FCrst")
+ assert_equal('Martin Dürst', "Martin D\u00FCrst")
+ assert_equal('ü', "\u00FC")
+ assert_equal("Martin D\xC3\xBCrst", "Martin D\u{FC}rst")
+ assert_equal('Martin Dürst', "Martin D\u{FC}rst")
+ assert_equal('ü', "\u{FC}")
+ assert_equal('ü', %Q|\u{FC}|)
+ assert_equal('ü', %W{\u{FC}}[0])
+
+ # \u escapes in here documents
+ assert_equal('Matz - まつもと ゆきひろ', <<EOS.chop)
+Matz - \u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D
+EOS
+
+ assert_equal('Matz - まつもと ゆきひろ', <<"EOS".chop)
+Matz - \u{307E 3064 3082 3068} \u{3086 304D 3072 308D}
+EOS
+ assert_not_equal('Matz - まつもと ゆきひろ', <<'EOS'.chop)
+Matz - \u{307E 3064 3082 3068} \u{3086 304D 3072 308D}
+EOS
+
+ # single-quoted things don't expand \u
+ assert_not_equal('ü', '\u{FC}')
+ assert_not_equal('ü', %q|\u{FC}|)
+ assert_not_equal('ü', %w{\u{FC}}[0])
+ assert_equal('\u00fc', "\\" + "u00fc")
+
+ # \u in %x strings
+ assert_match(/^("?)A\1$/, `echo "\u0041"`) #"
+ assert_match(/^("?)A\1$/, %x{echo "\u0041"}) #"
+ assert_match(/^("?)ü\1$/, `echo "\u{FC}"`.force_encoding("utf-8")) #"
+
+ # \u in quoted symbols
+ assert_equal(:A, :"\u0041")
+ assert_equal(:a, :"\u0061")
+ assert_equal(:ま, :ま)
+ assert_equal(:ü, :ü)
+ assert_equal(:"\u{41}", :"\u0041")
+ assert_equal(:ü, :"\u{fc}")
+
+ # the NUL character is allowed in symbols
+ bug = '[ruby-dev:41447]'
+ sym = "\0".to_sym
+ assert_nothing_raised(SyntaxError, bug) {assert_equal(sym, eval(%q(:"\u{0}")))}
+ assert_nothing_raised(SyntaxError, bug) {assert_equal(sym, eval(%q(:"\u0000")))}
+ assert_nothing_raised(SyntaxError, bug) {assert_equal("\u{fc}\0A".to_sym, eval(%q(:"\u{fc 0 0041}")))}
+ assert_nothing_raised(SyntaxError, bug) {assert_equal(sym, eval(%q(:"\x00")))}
+ assert_nothing_raised(SyntaxError, bug) {assert_equal(sym, eval(%q(:"\0")))}
+ end
+
+ def test_regexp
+
+ # Compare regexps to regexps
+ assert_not_equal(/Yukihiro Matsumoto - 松本行弘/,
+ /Yukihiro Matsumoto - \u677E\u672C\u884C\u5F18/)
+ assert_not_equal(/Yukihiro Matsumoto - 松本行弘/,
+ /Yukihiro Matsumoto - \u{677E 672C 884C 5F18}/)
+ assert_not_equal(/Matz - まつもと ゆきひろ/,
+ /Matz - \u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D/)
+ assert_not_equal(/Aoyama Gakuin University - 青山学院大学/,
+ /Aoyama Gakuin University - \u9752\u5C71\u5B66\u9662\u5927\u5B66/)
+ assert_not_equal(/青山学院大学/, /\u9752\u5C71\u5B66\u9662\u5927\u5B66/)
+ assert_not_equal(/Martin Dürst/, /Martin D\u00FCrst/)
+ assert_not_equal(/ü/, /\u00FC/)
+ assert_not_equal(/Martin Dürst/, /Martin D\u{FC}rst/)
+ assert_not_equal(/ü/, /\u{FC}/)
+ assert_not_equal(/ü/, %r{\u{FC}})
+ assert_not_equal(/ü/i, %r{\u00FC}i)
+
+ assert_equal('Yukihiro Matsumoto - \u677E\u672C\u884C\u5F18',
+ /Yukihiro Matsumoto - \u677E\u672C\u884C\u5F18/.source)
+ assert_equal('Yukihiro Matsumoto - \u{677E 672C 884C 5F18}',
+ /Yukihiro Matsumoto - \u{677E 672C 884C 5F18}/.source)
+ assert_equal('Matz - \u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D',
+ /Matz - \u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D/.source)
+ assert_equal('Aoyama Gakuin University - \u9752\u5C71\u5B66\u9662\u5927\u5B66',
+ /Aoyama Gakuin University - \u9752\u5C71\u5B66\u9662\u5927\u5B66/.source)
+ assert_equal('\u9752\u5C71\u5B66\u9662\u5927\u5B66',
+ /\u9752\u5C71\u5B66\u9662\u5927\u5B66/.source)
+ assert_equal('Martin D\u00FCrst', /Martin D\u00FCrst/.source)
+ assert_equal('\u00FC', /\u00FC/.source)
+ assert_equal('Martin D\u{FC}rst', /Martin D\u{FC}rst/.source)
+ assert_equal('\u{FC}', /\u{FC}/.source)
+ assert_equal('\u{FC}', %r{\u{FC}}.source)
+ assert_equal('\u00FC', %r{\u00FC}i.source)
+
+ # match strings to regexps
+ assert_equal(0, "Yukihiro Matsumoto - 松本行弘" =~ /Yukihiro Matsumoto - \u677E\u672C\u884C\u5F18/)
+ assert_equal(0, "Yukihiro Matsumoto - \u677E\u672C\u884C\u5F18" =~ /Yukihiro Matsumoto - \u677E\u672C\u884C/)
+ assert_equal(0, "Yukihiro Matsumoto - 松本行弘" =~ /Yukihiro Matsumoto - \u{677E 672C 884C 5F18}/)
+ assert_equal(0, %Q{Yukihiro Matsumoto - \u{677E 672C 884C 5F18}} =~ /Yukihiro Matsumoto - \u{677E 672C 884C 5F18}/)
+ assert_equal(0, "Matz - まつもと ゆきひろ" =~ /Matz - \u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D/)
+ assert_equal(0, "Aoyama Gakuin University - 青山学院大学" =~ /Aoyama Gakuin University - \u9752\u5C71\u5B66\u9662\u5927\u5B66/)
+ assert_equal(0, "青山学院大学" =~ /\u9752\u5C71\u5B66\u9662\u5927\u5B66/)
+ assert_equal(0, "Martin Dürst" =~ /Martin D\u00FCrst/)
+ assert_equal(0, "ü" =~ /\u00FC/)
+ assert_equal(0, "Martin Dürst" =~ /Martin D\u{FC}rst/)
+ assert_equal(0, "ü" =~ %r{\u{FC}})
+ assert_equal(0, "ü" =~ %r{\u00FC}i)
+
+ # Flip order of the two operands
+ assert_equal(0, /Martin D\u00FCrst/ =~ "Martin Dürst")
+ assert_equal(4, /\u00FC/ =~ "testü")
+ assert_equal(3, /Martin D\u{FC}rst/ =~ "fooMartin Dürstbar")
+ assert_equal(3, %r{\u{FC}} =~ "fooübar")
+
+ # Put \u in strings, literal character in regexp
+ assert_equal(0, "Martin D\u00FCrst" =~ /Martin Dürst/)
+ assert_equal(4, "test\u00FC" =~ /ü/)
+ assert_equal(3, "fooMartin D\u{FC}rstbar" =~ /Martin Dürst/)
+ assert_equal(3, %Q{foo\u{FC}bar} =~ %r<ü>)
+
+ assert_match(eval('/\u{2a}/'), "*")
+ assert_raise(SyntaxError) { eval('/\u{6666}/n') }
+ assert_raise(SyntaxError) { eval('/\u{6666}/e') }
+ assert_raise(SyntaxError) { eval('/\u{6666}/s') }
+ assert_nothing_raised { eval('/\u{6666}/u') }
+ end
+
+ def test_dynamic_regexp
+ assert_match(Regexp.new("Martin D\\u{FC}rst"), "Martin Dürst")
+ end
+
+ def test_syntax_variants
+ # all hex digits
+ assert_equal("\xC4\xA3\xE4\x95\xA7\xE8\xA6\xAB\xEC\xB7\xAF", "\u0123\u4567\u89AB\uCDEF")
+ assert_equal("\xC4\xA3\xE4\x95\xA7\xE8\xA6\xAB\xEC\xB7\xAF", "\u0123\u4567\u89AB\uCDEF")
+ assert_equal("\xC4\xA3\xE4\x95\xA7\xE8\xA6\xAB\xEC\xB7\xAF", "\u0123\u4567\u89ab\ucdef")
+ assert_equal("\xC4\xA3\xE4\x95\xA7\xE8\xA6\xAB\xEC\xB7\xAF", "\u0123\u4567\u89ab\ucdef")
+ assert_equal("\xC4\xA3\xE4\x95\xA7\xE8\xA6\xAB\xEC\xB7\xAF", "\u0123\u4567\u89aB\uCdEf")
+ assert_equal("\xC4\xA3\xE4\x95\xA7\xE8\xA6\xAB\xEC\xB7\xAF", "\u0123\u4567\u89aB\ucDEF")
+ end
+
+ def test_fulton
+ # examples from Hal Fulton's book (second edition), chapter 4
+ # precomposed e'pe'e
+ assert_equal('épée', "\u00E9\u0070\u00E9\u0065")
+ assert_equal('épée', "\u00E9p\u00E9e")
+ assert_equal("\xC3\xA9\x70\xC3\xA9\x65", "\u00E9\u0070\u00E9\u0065")
+ assert_equal("\xC3\xA9\x70\xC3\xA9\x65", "\u00E9p\u00E9e")
+ # decomposed e'pe'e
+ assert_equal('épée', "\u0065\u0301\u0070\u0065\u0301\u0065")
+ assert_equal('épée', "e\u0301pe\u0301e")
+ assert_equal("\x65\xCC\x81\x70\x65\xCC\x81\x65", "\u0065\u0301\u0070\u0065\u0301\u0065")
+ assert_equal("\x65\xCC\x81\x70\x65\xCC\x81\x65", "e\u0301pe\u0301e")
+ # combinations of NFC/D, NFKC/D
+ assert_equal('öffnen', "\u00F6\u0066\u0066\u006E\u0065\u006E")
+ assert_equal("\xC3\xB6ffnen", "\u00F6\u0066\u0066\u006E\u0065\u006E")
+ assert_equal('öffnen', "\u00F6ffnen")
+ assert_equal("\xC3\xB6ffnen", "\u00F6ffnen")
+ assert_equal('öffnen', "\u006F\u0308\u0066\u0066\u006E\u0065\u006E")
+ assert_equal("\x6F\xCC\x88ffnen", "\u006F\u0308\u0066\u0066\u006E\u0065\u006E")
+ assert_equal('öffnen', "o\u0308ffnen")
+ assert_equal("\x6F\xCC\x88ffnen", "o\u0308ffnen")
+ assert_equal('öffnen', "\u00F6\uFB00\u006E\u0065\u006E")
+ assert_equal("\xC3\xB6\xEF\xAC\x80nen", "\u00F6\uFB00\u006E\u0065\u006E")
+ assert_equal('öffnen', "\u00F6\uFB00nen")
+ assert_equal("\xC3\xB6\xEF\xAC\x80nen", "\u00F6\uFB00nen")
+ assert_equal('öffnen', "\u006F\u0308\uFB00\u006E\u0065\u006E")
+ assert_equal("\x6F\xCC\x88\xEF\xAC\x80nen", "\u006F\u0308\uFB00\u006E\u0065\u006E")
+ assert_equal('öffnen', "o\u0308\uFB00nen")
+ assert_equal("\x6F\xCC\x88\xEF\xAC\x80nen", "o\u0308\uFB00nen")
+ # German sharp s (sz)
+ assert_equal('Straße', "\u0053\u0074\u0072\u0061\u00DF\u0065")
+ assert_equal("\x53\x74\x72\x61\xC3\x9F\x65", "\u0053\u0074\u0072\u0061\u00DF\u0065")
+ assert_equal('Straße', "Stra\u00DFe")
+ assert_equal("\x53\x74\x72\x61\xC3\x9F\x65", "Stra\u00DFe")
+ assert_equal('Straße', "\u{53}\u{74}\u{72}\u{61}\u{DF}\u{65}")
+ assert_equal("\x53\x74\x72\x61\xC3\x9F\x65", "\u{53}\u{74}\u{72}\u{61}\u{DF}\u{65}")
+ assert_equal("\x53\x74\x72\x61\xC3\x9F\x65", "\u{53 74 72 61 DF 65}")
+ assert_equal('Straße', "Stra\u{DF}e")
+ assert_equal("\x53\x74\x72\x61\xC3\x9F\x65", "Stra\u{DF}e")
+ end
+
+ def test_edge_cases
+ # start and end of each outer plane
+ assert_equal("\xF4\x8F\xBF\xBF", "\u{10FFFF}")
+ assert_equal("\xF4\x80\x80\x80", "\u{100000}")
+ assert_equal("\xF3\xBF\xBF\xBF", "\u{FFFFF}")
+ assert_equal("\xF3\xB0\x80\x80", "\u{F0000}")
+ assert_equal("\xF3\xAF\xBF\xBF", "\u{EFFFF}")
+ assert_equal("\xF3\xA0\x80\x80", "\u{E0000}")
+ assert_equal("\xF3\x9F\xBF\xBF", "\u{DFFFF}")
+ assert_equal("\xF3\x90\x80\x80", "\u{D0000}")
+ assert_equal("\xF3\x8F\xBF\xBF", "\u{CFFFF}")
+ assert_equal("\xF3\x80\x80\x80", "\u{C0000}")
+ assert_equal("\xF2\xBF\xBF\xBF", "\u{BFFFF}")
+ assert_equal("\xF2\xB0\x80\x80", "\u{B0000}")
+ assert_equal("\xF2\xAF\xBF\xBF", "\u{AFFFF}")
+ assert_equal("\xF2\xA0\x80\x80", "\u{A0000}")
+ assert_equal("\xF2\x9F\xBF\xBF", "\u{9FFFF}")
+ assert_equal("\xF2\x90\x80\x80", "\u{90000}")
+ assert_equal("\xF2\x8F\xBF\xBF", "\u{8FFFF}")
+ assert_equal("\xF2\x80\x80\x80", "\u{80000}")
+ assert_equal("\xF1\xBF\xBF\xBF", "\u{7FFFF}")
+ assert_equal("\xF1\xB0\x80\x80", "\u{70000}")
+ assert_equal("\xF1\xAF\xBF\xBF", "\u{6FFFF}")
+ assert_equal("\xF1\xA0\x80\x80", "\u{60000}")
+ assert_equal("\xF1\x9F\xBF\xBF", "\u{5FFFF}")
+ assert_equal("\xF1\x90\x80\x80", "\u{50000}")
+ assert_equal("\xF1\x8F\xBF\xBF", "\u{4FFFF}")
+ assert_equal("\xF1\x80\x80\x80", "\u{40000}")
+ assert_equal("\xF0\xBF\xBF\xBF", "\u{3FFFF}")
+ assert_equal("\xF0\xB0\x80\x80", "\u{30000}")
+ assert_equal("\xF0\xAF\xBF\xBF", "\u{2FFFF}")
+ assert_equal("\xF0\xA0\x80\x80", "\u{20000}")
+ assert_equal("\xF0\x9F\xBF\xBF", "\u{1FFFF}")
+ assert_equal("\xF0\x90\x80\x80", "\u{10000}")
+ # BMP
+ assert_equal("\xEF\xBF\xBF", "\uFFFF")
+ assert_equal("\xEE\x80\x80", "\uE000")
+ assert_equal("\xED\x9F\xBF", "\uD7FF")
+ assert_equal("\xE0\xA0\x80", "\u0800")
+ assert_equal("\xDF\xBF", "\u07FF")
+ assert_equal("\xC2\x80", "\u0080")
+ assert_equal("\x7F", "\u007F")
+ assert_equal("\x00", "\u0000")
+ end
+
+ def test_chars
+ assert_equal(?\u0041, ?A)
+ assert_equal(?\u{79}, ?\x79)
+ assert_equal(?\u{0}, ?\000)
+ assert_equal(?\u0000, ?\000)
+ end
+
+ # Tests to make sure that disallowed cases fail
+ def test_fail
+ assert_raise(SyntaxError) { eval %q("\uabc") } # too short
+ assert_raise(SyntaxError) { eval %q("\uab") } # too short
+ assert_raise(SyntaxError) { eval %q("\ua") } # too short
+ assert_raise(SyntaxError) { eval %q("\u") } # too short
+ assert_raise(SyntaxError) { eval %q("\u{110000}") } # too high
+ assert_raise(SyntaxError) { eval %q("\u{abcdeff}") } # too long
+ assert_raise(SyntaxError) { eval %q("\ughij") } # bad hex digits
+ assert_raise(SyntaxError) { eval %q("\u{ghij}") } # bad hex digits
+
+ assert_raise(SyntaxError) { eval %q("\u{123 456 }")} # extra space
+ assert_raise(SyntaxError) { eval %q("\u{ 123 456}")} # extra space
+ assert_raise(SyntaxError) { eval %q("\u{123 456}")} # extra space
+
+# The utf-8 encoding object currently does not object to codepoints
+# in the surrogate blocks, so these do not raise an error.
+# assert_raise(SyntaxError) { "\uD800" } # surrogate block
+# assert_raise(SyntaxError) { "\uDCBA" } # surrogate block
+# assert_raise(SyntaxError) { "\uDFFF" } # surrogate block
+# assert_raise(SyntaxError) { "\uD847\uDD9A" } # surrogate pair
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_variable.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_variable.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_variable.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,94 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestVariable < Test::Unit::TestCase
+ class Gods
+ @@rule = "Uranus"
+ def ruler0
+ @@rule
+ end
+
+ def self.ruler1 # <= per method definition style
+ @@rule
+ end
+ class << self # <= multiple method definition style
+ def ruler2
+ @@rule
+ end
+ end
+ end
+
+ module Olympians
+ @@rule ="Zeus"
+ def ruler3
+ @@rule
+ end
+ end
+
+ class Titans < Gods
+ @@rule = "Cronus" # modifies @@rule in Gods
+ include Olympians
+ def ruler4
+ @@rule
+ end
+ end
+
+ def test_variable
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ assert_instance_of(Fixnum, $$)
+
+ # read-only variable
+ assert_raise(NameError) do
+ $$ = 5
+ end
+ assert_normal_exit("$*=0; $*", "[ruby-dev:36698]")
+
+ foobar = "foobar"
+ $_ = foobar
+ assert_equal(foobar, $_)
+
+ assert_equal("Cronus", Gods.new.ruler0)
+ assert_equal("Cronus", Gods.ruler1)
+ assert_equal("Cronus", Gods.ruler2)
+ assert_equal("Cronus", Titans.ruler1)
+ assert_equal("Cronus", Titans.ruler2)
+ atlas = Titans.new
+ assert_equal("Cronus", atlas.ruler0)
+ assert_equal("Zeus", atlas.ruler3)
+ assert_equal("Cronus", atlas.ruler4)
+ end
+
+ def test_local_variables
+ lvar = 1
+ assert_instance_of(Symbol, local_variables[0], "[ruby-dev:34008]")
+ end
+
+ def test_local_variables2
+ x = 1
+ proc do |y|
+ assert_equal([:x, :y], local_variables.sort)
+ end.call
+ end
+
+ def test_local_variables3
+ x = 1
+ proc do |y|
+ 1.times do |z|
+ assert_equal([:x, :y, :z], local_variables.sort)
+ end
+ end.call
+ end
+
+ def test_global_variable_0
+ assert_in_out_err(["-e", "$0='t'*1000;print $0"], "", /\At+\z/, [])
+ end
+
+ def test_global_variable_poped
+ assert_nothing_raised { eval("$foo; 1") }
+ end
+
+ def test_constant_poped
+ assert_nothing_raised { eval("TestVariable::Gods; 1") }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_whileuntil.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_whileuntil.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_whileuntil.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,82 @@
+require 'test/unit'
+require 'tmpdir'
+
+class TestWhileuntil < Test::Unit::TestCase
+ def test_while
+ Dir.mktmpdir("ruby_while_tmp") {|tmpdir|
+ tmpfilename = "#{tmpdir}/ruby_while_tmp.#{$$}"
+
+ tmp = open(tmpfilename, "w")
+ tmp.print "tvi925\n";
+ tmp.print "tvi920\n";
+ tmp.print "vt100\n";
+ tmp.print "Amiga\n";
+ tmp.print "paper\n";
+ tmp.close
+
+ tmp = open(tmpfilename, "r")
+ assert_instance_of(File, tmp)
+
+ while line = tmp.gets()
+ break if /vt100/ =~ line
+ end
+
+ assert(!tmp.eof?)
+ assert_match(/vt100/, line)
+ tmp.close
+
+ tmp = open(tmpfilename, "r")
+ while line = tmp.gets()
+ next if /vt100/ =~ line
+ assert_no_match(/vt100/, line)
+ end
+ assert(tmp.eof?)
+ assert_no_match(/vt100/, line)
+ tmp.close
+
+ tmp = open(tmpfilename, "r")
+ while line = tmp.gets()
+ lastline = line
+ line = line.gsub(/vt100/, 'VT100')
+ if lastline != line
+ line.gsub!('VT100', 'Vt100')
+ redo
+ end
+ assert_no_match(/vt100/, line)
+ assert_no_match(/VT100/, line)
+ end
+ assert(tmp.eof?)
+ tmp.close
+
+ sum=0
+ for i in 1..10
+ sum += i
+ i -= 1
+ if i > 0
+ redo
+ end
+ end
+ assert_equal(220, sum)
+
+ tmp = open(tmpfilename, "r")
+ while line = tmp.gets()
+ break if 3
+ assert_no_match(/vt100/, line)
+ assert_no_match(/Amiga/, line)
+ assert_no_match(/paper/, line)
+ end
+ tmp.close
+
+ File.unlink tmpfilename or `/bin/rm -f "#{tmpfilename}"`
+ assert(!File.exist?(tmpfilename))
+ }
+ end
+
+ def test_until
+ i = 0
+ until i>4
+ i+=1
+ end
+ assert(i>4)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/test_yield.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/test_yield.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/test_yield.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,382 @@
+require 'test/unit'
+require 'stringio'
+
+class TestRubyYield < Test::Unit::TestCase
+
+ def test_ary_each
+ ary = [1]
+ ary.each {|a, b, c, d| assert_equal [1,nil,nil,nil], [a,b,c,d] }
+ ary.each {|a, b, c| assert_equal [1,nil,nil], [a,b,c] }
+ ary.each {|a, b| assert_equal [1,nil], [a,b] }
+ ary.each {|a| assert_equal 1, a }
+ end
+
+ def test_hash_each
+ h = {:a => 1}
+ h.each do |k, v|
+ assert_equal :a, k
+ assert_equal 1, v
+ end
+ h.each do |kv|
+ assert_equal [:a, 1], kv
+ end
+ end
+
+ def test_yield_0
+ assert_equal 1, iter0 { 1 }
+ assert_equal 2, iter0 { 2 }
+ end
+
+ def iter0
+ yield
+ end
+
+ def test_yield_1
+ iter1([]) {|a, b| assert_equal [nil,nil], [a, b] }
+ iter1([1]) {|a, b| assert_equal [1,nil], [a, b] }
+ iter1([1, 2]) {|a, b| assert_equal [1,2], [a,b] }
+ iter1([1, 2, 3]) {|a, b| assert_equal [1,2], [a,b] }
+
+ iter1([]) {|a| assert_equal [], a }
+ iter1([1]) {|a| assert_equal [1], a }
+ iter1([1, 2]) {|a| assert_equal [1,2], a }
+ iter1([1, 2, 3]) {|a| assert_equal [1,2,3], a }
+ end
+
+ def iter1(args)
+ yield args
+ end
+
+ def test_yield2
+ def iter2_1() yield 1, *[2, 3] end
+ iter2_1 {|a, b, c| assert_equal [1,2,3], [a,b,c] }
+ def iter2_2() yield 1, *[] end
+ iter2_2 {|a, b, c| assert_equal [1,nil,nil], [a,b,c] }
+ def iter2_3() yield 1, *[2] end
+ iter2_3 {|a, b, c| assert_equal [1,2,nil], [a,b,c] }
+ end
+
+ def test_yield_nested
+ [[1, [2, 3]]].each {|a, (b, c)|
+ assert_equal [1,2,3], [a,b,c]
+ }
+ [[1, [2, 3]]].map {|a, (b, c)|
+ assert_equal [1,2,3], [a,b,c]
+ }
+ end
+
+ def test_with_enum
+ obj = Object
+ def obj.each
+ yield(*[])
+ end
+ obj.each{|*v| assert_equal([], [], '[ruby-dev:32392]')}
+ obj.to_enum.each{|*v| assert_equal([], [], '[ruby-dev:32392]')}
+ end
+
+ def block_args_unleashed
+ yield(1,2,3,4,5)
+ end
+
+ def test_block_args_unleashed
+ r = block_args_unleashed {|a,b=1,*c,d,e|
+ [a,b,c,d,e]
+ }
+ assert_equal([1,2,[3],4,5], r, "[ruby-core:19485]")
+ end
+end
+
+require_relative 'sentence'
+class TestRubyYieldGen < Test::Unit::TestCase
+ Syntax = {
+ :exp => [["0"],
+ ["nil"],
+ ["false"],
+ ["[]"],
+ ["[",:exps,"]"]],
+ :exps => [[:exp],
+ [:exp,",",:exps]],
+ :opt_block_param => [[],
+ [:block_param_def]],
+ :block_param_def => [['|', '|'],
+ ['|', :block_param, '|']],
+ :block_param => [[:f_arg, ",", :f_rest_arg, :opt_f_block_arg],
+ [:f_arg, ","],
+ [:f_arg, ',', :f_rest_arg, ",", :f_arg, :opt_f_block_arg],
+ [:f_arg, :opt_f_block_arg],
+ [:f_rest_arg, :opt_f_block_arg],
+ [:f_rest_arg, ',', :f_arg, :opt_f_block_arg],
+ [:f_block_arg]],
+ :f_arg => [[:f_arg_item],
+ [:f_arg, ',', :f_arg_item]],
+ :f_rest_arg => [['*', "var"],
+ ['*']],
+ :opt_f_block_arg => [[',', :f_block_arg],
+ []],
+ :f_block_arg => [['&', 'var']],
+ :f_arg_item => [[:f_norm_arg],
+ ['(', :f_margs, ')']],
+ :f_margs => [[:f_marg_list],
+ [:f_marg_list, ',', '*', :f_norm_arg],
+ [:f_marg_list, ',', '*', :f_norm_arg, ',', :f_marg_list],
+ [:f_marg_list, ',', '*'],
+ [:f_marg_list, ',', '*', ',', :f_marg_list],
+ [ '*', :f_norm_arg],
+ [ '*', :f_norm_arg, ',', :f_marg_list],
+ [ '*'],
+ [ '*', ',', :f_marg_list]],
+ :f_marg_list => [[:f_marg],
+ [:f_marg_list, ',', :f_marg]],
+ :f_marg => [[:f_norm_arg],
+ ['(', :f_margs, ')']],
+ :f_norm_arg => [['var']],
+
+ :command_args => [[:open_args]],
+ :open_args => [[' ',:call_args],
+ ['(', ')'],
+ ['(', :call_args2, ')']],
+ :call_args => [[:command],
+ [ :args, :opt_block_arg],
+ [ :assocs, :opt_block_arg],
+ [ :args, ',', :assocs, :opt_block_arg],
+ [ :block_arg]],
+ :call_args2 => [[:arg, ',', :args, :opt_block_arg],
+ [:arg, ',', :block_arg],
+ [ :assocs, :opt_block_arg],
+ [:arg, ',', :assocs, :opt_block_arg],
+ [:arg, ',', :args, ',', :assocs, :opt_block_arg],
+ [ :block_arg]],
+
+ :command_args_noblock => [[:open_args_noblock]],
+ :open_args_noblock => [[' ',:call_args_noblock],
+ ['(', ')'],
+ ['(', :call_args2_noblock, ')']],
+ :call_args_noblock => [[:command],
+ [ :args],
+ [ :assocs],
+ [ :args, ',', :assocs]],
+ :call_args2_noblock => [[:arg, ',', :args],
+ [ :assocs],
+ [:arg, ',', :assocs],
+ [:arg, ',', :args, ',', :assocs]],
+
+ :command => [],
+ :args => [[:arg],
+ ["*",:arg],
+ [:args,",",:arg],
+ [:args,",","*",:arg]],
+ :arg => [[:exp]],
+ :assocs => [[:assoc],
+ [:assocs, ',', :assoc]],
+ :assoc => [[:arg, '=>', :arg],
+ ['label', ':', :arg]],
+ :opt_block_arg => [[',', :block_arg],
+ []],
+ :block_arg => [['&', :arg]],
+ #:test => [['def m() yield', :command_args_noblock, ' end; r = m {', :block_param_def, 'vars', '}; undef m; r']]
+ :test_proc => [['def m() yield', :command_args_noblock, ' end; r = m {', :block_param_def, 'vars', '}; undef m; r']],
+ :test_lambda => [['def m() yield', :command_args_noblock, ' end; r = m(&lambda {', :block_param_def, 'vars', '}); undef m; r']],
+ :test_enum => [['o = Object.new; def o.each() yield', :command_args_noblock, ' end; r1 = r2 = nil; o.each {|*x| r1 = x }; o.to_enum.each {|*x| r2 = x }; [r1, r2]']]
+ }
+
+ def rename_var(obj)
+ vars = []
+ r = obj.subst('var') {
+ var = "v#{vars.length}"
+ vars << var
+ var
+ }
+ return r, vars
+ end
+
+ def split_by_comma(ary)
+ return [] if ary.empty?
+ result = [[]]
+ ary.each {|e|
+ if e == ','
+ result << []
+ else
+ result.last << e
+ end
+ }
+ result
+ end
+
+ def emu_return_args(*vs)
+ vs
+ end
+
+ def emu_eval_args(args)
+ if args.last == []
+ args = args[0...-1]
+ end
+ code = "emu_return_args(#{args.map {|a| a.join('') }.join(",")})"
+ eval code, nil, 'generated_code_in_emu_eval_args'
+ end
+
+ def emu_bind_single(arg, param, result_binding)
+ #p [:emu_bind_single, arg, param]
+ if param.length == 1 && String === param[0] && /\A[a-z0-9]+\z/ =~ param[0]
+ result_binding[param[0]] = arg
+ elsif param.length == 1 && Array === param[0] && param[0][0] == '(' && param[0][-1] == ')'
+ arg = [arg] unless Array === arg
+ emu_bind_params(arg, split_by_comma(param[0][1...-1]), false, result_binding)
+ else
+ raise "unexpected param: #{param.inspect}"
+ end
+ result_binding
+ end
+
+ def emu_bind_params(args, params, islambda, result_binding={})
+ #p [:emu_bind_params, args, params]
+ if params.last == [] # extra comma
+ params.pop
+ end
+
+ star_index = nil
+ params.each_with_index {|par, i|
+ star_index = i if par[0] == '*'
+ }
+
+ if islambda
+ if star_index
+ if args.length < params.length - 1
+ throw :emuerror, ArgumentError
+ end
+ else
+ if args.length != params.length
+ throw :emuerror, ArgumentError
+ end
+ end
+ end
+
+ # TRICK #2 : adjust mismatch on number of arguments
+ if star_index
+ pre_params = params[0...star_index]
+ rest_param = params[star_index]
+ post_params = params[(star_index+1)..-1]
+ pre_params.each {|par| emu_bind_single(args.shift, par, result_binding) }
+ if post_params.length <= args.length
+ post_params.reverse_each {|par| emu_bind_single(args.pop, par, result_binding) }
+ else
+ post_params.each {|par| emu_bind_single(args.shift, par, result_binding) }
+ end
+ if rest_param != ['*']
+ emu_bind_single(args, rest_param[1..-1], result_binding)
+ end
+ else
+ params.each_with_index {|par, i|
+ emu_bind_single(args[i], par, result_binding)
+ }
+ end
+
+ #p [args, params, result_binding]
+
+ result_binding
+ end
+
+ def emu_bind(t, islambda)
+ #puts
+ #p t
+ command_args_noblock = t[1]
+ block_param_def = t[3]
+ command_args_noblock = command_args_noblock.expand {|a| !(a[0] == '[' && a[-1] == ']') }
+ block_param_def = block_param_def.expand {|a| !(a[0] == '(' && a[-1] == ')') }
+
+ if command_args_noblock.to_a[0] == ' '
+ args = command_args_noblock.to_a[1..-1]
+ elsif command_args_noblock.to_a[0] == '(' && command_args_noblock.to_a[-1] == ')'
+ args = command_args_noblock.to_a[1...-1]
+ else
+ raise "unexpected command_args_noblock: #{command_args_noblock.inspect}"
+ end
+ args = emu_eval_args(split_by_comma(args))
+
+ params = block_param_def.to_a[1...-1]
+ params = split_by_comma(params)
+
+ #p [:emu0, args, params]
+
+ result_binding = {}
+
+ if params.last && params.last[0] == '&'
+ result_binding[params.last[1]] = nil
+ params.pop
+ end
+
+ if !islambda
+ # TRICK #1 : single array argument is expanded if there are two or more params.
+ # * block parameter is not counted.
+ # * extra comma after single param forces the expansion.
+ if args.length == 1 && Array === args[0] && 1 < params.length
+ args = args[0]
+ end
+ end
+
+ emu_bind_params(args, params, islambda, result_binding)
+ #p result_binding
+ result_binding
+ end
+
+ def emu(t, vars, islambda)
+ catch(:emuerror) {
+ emu_binding = emu_bind(t, islambda)
+ vars.map {|var| emu_binding.fetch(var, "NOVAL") }
+ }
+ end
+
+ def disable_stderr
+ begin
+ save_stderr = $stderr
+ $stderr = StringIO.new
+ yield
+ ensure
+ $stderr = save_stderr
+ end
+ end
+
+ def check_nofork(t, islambda=false)
+ t, vars = rename_var(t)
+ t = t.subst('vars') { " [#{vars.join(",")}]" }
+ emu_values = emu(t, vars, islambda)
+ s = t.to_s
+ #print "#{s}\t\t"
+ #STDOUT.flush
+ eval_values = disable_stderr {
+ begin
+ eval(s, nil, 'generated_code_in_check_nofork')
+ rescue ArgumentError
+ ArgumentError
+ end
+ }
+ #success = emu_values == eval_values ? 'succ' : 'fail'
+ #puts "eval:#{vs_ev.inspect[1...-1].delete(' ')}\temu:#{vs_emu.inspect[1...-1].delete(' ')}\t#{success}"
+ assert_equal(emu_values, eval_values, s)
+ end
+
+ def test_yield
+ syntax = Sentence.expand_syntax(Syntax)
+ Sentence.each(syntax, :test_proc, 4) {|t|
+ check_nofork(t)
+ }
+ end
+
+ def test_yield_lambda
+ syntax = Sentence.expand_syntax(Syntax)
+ Sentence.each(syntax, :test_lambda, 4) {|t|
+ check_nofork(t, true)
+ }
+ end
+
+ def test_yield_enum
+ syntax = Sentence.expand_syntax(Syntax)
+ Sentence.each(syntax, :test_enum, 4) {|t|
+ code = t.to_s
+ r1, r2 = disable_stderr {
+ eval(code, nil, 'generated_code_in_test_yield_enum')
+ }
+ assert_equal(r1, r2, "#{t}")
+ }
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/ruby/ut_eof.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/ruby/ut_eof.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/ruby/ut_eof.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,128 @@
+require 'test/unit'
+
+module TestEOF
+ def test_eof_0
+ open_file("") {|f|
+ assert_equal("", f.read(0))
+ assert_equal("", f.read(0))
+ assert_equal("", f.read)
+ assert_equal("", f.read(0))
+ assert_equal("", f.read(0))
+ }
+ open_file("") {|f|
+ assert_nil(f.read(1))
+ assert_equal("", f.read)
+ assert_nil(f.read(1))
+ }
+ open_file("") {|f|
+ s = "x"
+ assert_equal("", f.read(nil, s))
+ assert_equal("", s)
+ }
+ open_file("") {|f|
+ s = "x"
+ assert_nil(f.read(10, s))
+ assert_equal("", s)
+ }
+ end
+
+ def test_eof_0_rw
+ return unless respond_to? :open_file_rw
+ open_file_rw("") {|f|
+ assert_equal("", f.read)
+ assert_equal("", f.read)
+ assert_equal(0, f.syswrite(""))
+ assert_equal("", f.read)
+ }
+ end
+
+ def test_eof_1
+ open_file("a") {|f|
+ assert_equal("", f.read(0))
+ assert_equal("a", f.read(1))
+ assert_equal("" , f.read(0))
+ assert_equal("" , f.read(0))
+ assert_equal("", f.read)
+ assert_equal("", f.read(0))
+ assert_equal("", f.read(0))
+ }
+ open_file("a") {|f|
+ assert_equal("a", f.read(1))
+ assert_nil(f.read(1))
+ }
+ open_file("a") {|f|
+ assert_equal("a", f.read(2))
+ assert_nil(f.read(1))
+ assert_equal("", f.read)
+ assert_nil(f.read(1))
+ }
+ open_file("a") {|f|
+ assert_equal("a", f.read)
+ assert_nil(f.read(1))
+ assert_equal("", f.read)
+ assert_nil(f.read(1))
+ }
+ open_file("a") {|f|
+ assert_equal("a", f.read(2))
+ assert_equal("", f.read)
+ assert_equal("", f.read)
+ }
+ open_file("a") {|f|
+ assert_equal("a", f.read)
+ assert_equal("", f.read(0))
+ }
+ open_file("a") {|f|
+ s = "x"
+ assert_equal("a", f.read(nil, s))
+ assert_equal("a", s)
+ }
+ open_file("a") {|f|
+ s = "x"
+ assert_equal("a", f.read(10, s))
+ assert_equal("a", s)
+ }
+ end
+
+ def test_eof_2
+ open_file("") {|f|
+ assert_equal("", f.read)
+ assert(f.eof?)
+ }
+ end
+
+ def test_eof_3
+ open_file("") {|f|
+ assert(f.eof?)
+ }
+ end
+
+ module Seek
+ def open_file_seek(content, pos)
+ open_file(content) do |f|
+ f.seek(pos)
+ yield f
+ end
+ end
+
+ def test_eof_0_seek
+ open_file_seek("", 10) {|f|
+ assert_equal(10, f.pos)
+ assert_equal("", f.read(0))
+ assert_equal("", f.read)
+ assert_equal("", f.read(0))
+ assert_equal("", f.read)
+ }
+ end
+
+ def test_eof_1_seek
+ open_file_seek("a", 10) {|f|
+ assert_equal("", f.read)
+ assert_equal("", f.read)
+ }
+ open_file_seek("a", 1) {|f|
+ assert_equal("", f.read)
+ assert_equal("", f.read)
+ }
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rubygems/bogussources.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/bogussources.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/bogussources.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,8 @@
+#--
+# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
+# All rights reserved.
+# See LICENSE.txt for permissions.
+#++
+
+require 'rubygems'
+Gem.use_paths("test/mock/gems")
Added: MacRuby/trunk/test/test-mri/test/rubygems/data/gem-private_key.pem
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/data/gem-private_key.pem (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/data/gem-private_key.pem 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAz0tTOtsJuHDKAEXrQx0f6DUEzBEUTSLR1fk0iEHsY9rDCQxm
+sw5Bf2UnVhdD03B4/XzIK+pat2CMQc37/vLIBuVgS7g/fzatGiM0m5rAHtycr0XU
+8Ek6zjx4iSv70OLjybY+/utHCEc838awGDMCFR21jYxgATPVwqAIyasvwbKh/Vhw
+uErFPqT9G8BKTHsaX+H+ADIRH001OmWkjB6EyjF05114kNMa0+2C7daV9hoBL3md
+hCt6zOGcapl/9LkGxhcNEUB/So16V1ZQldg9macGyWktyNTSfctlF+f8okAmicG3
+XIwaW8UTmjFCmvDs/h1R/uKpe2IOHz87n29d2QIDAQABAoIBAQCR6n/nyg+JmTtX
+/d+hGns/RTLfQpZ7xarXZ9gmoeD4WSE42VXhbIOGXXnXDAFecKl6Jb/xycGZm4if
+OZPM3rEWyZeDNWrc7WvkHiwF7GSYVMqmRg2iJqoSSla+mAtl+pBFiNfHMW6K0Tp0
+erOyFRW+L2+A9/MMZaRun6AP9URkn0jz2kwmMFf+6szmzVn6fPFzZDRI+hEeaDmi
+LBzSrfrddrIBX+xGEoBj6RmfnKBCSUVSSxOauYjd4mVjVYxvMH4SV1hXDUS5GPl5
+MbCiBb7bpNIg/8ljMoRrQiqk0XwwS7MaCqPtMhUtpSmC/zSjAfmoN7AOc/Xh69cQ
+OCMNZH9BAoGBAPBlsuuU6fg0gVTKDdR12jHx03uRRt8/nPxHnpJkZCIh9XKh1LtY
+bkumi9HZpp3mzDiaGg/rwfCwNckKx8NLhICLgkric6ClrKftxTu6C8tBAb5YDi6u
+74KYnV8lMY/unzBtIloPgM3uluS292POmrWZpKwhvHLD71MewzMor5HFAoGBANy/
+mwsBs8i3Gzk8Twjq8effhPpE7kpxhC7bhwmjX3q41EjQWDT8M6xb1P9dRSsCIebi
+kqP1yhl27dJpA8r5WqE/z89xhBvObAGRv41eXxOI0LaH2k5lJQrUeSC+51dy+BEB
+T3GXD4C5ezZHQ8Wz/oL73uikrfhD+AqOZT2YbMEFAoGBAJvWEWpOGm3f+4bvhI+Z
+5lxCG4oa3wqRvj58XvsfQRovUWGCLtlTtgwsZq8enLf3iaOXohV4Czzvva4Z4u1i
+4v5BcbEBo1scixRBOn5BWKvl9C9j/a2dkX3jWQD4p2xaj69gz8f6DNFyPTb+tNhq
+cjgO5YUASZ1MDrSfWIKteULRAoGAZkZv8x2KyofrmQ0UITGZerDYz4t4TA1kDMGx
+QwnqhtVzpXjCJWpkFotFmDsCfPaz9mErR8PtKvcrIL1/AF+fWe5Sve3+I1P0PpXk
+hf8fVdGhwbAXuRKrouTmagGI9b9Sp65PvHUcvasyJufFwqeuV8mScX87CzeSiHGI
+/ozMdnECgYEAq4+losrhe0DEmiC9zVPvwRXjbSixDsSJxHfOcqIsZqhUgBiZ4TJD
+SrkuukrMZib6BAD+PtCJS1TBbJyyvL3QecizhHSIh3ZnT0HnaRPatLEYmU65+3kE
+kTqL4ik92bJnnWowy677sydl1lzBJDVa9ZlTs7BFSd8y/0DZaUxGg2I=
+-----END RSA PRIVATE KEY-----
Added: MacRuby/trunk/test/test-mri/test/rubygems/data/gem-public_cert.pem
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/data/gem-public_cert.pem (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/data/gem-public_cert.pem 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMREwDwYDVQQDDAhydWJ5
+Z2VtczEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUxEzARBgoJkiaJk/IsZAEZFgNj
+b20wHhcNMDcwODAyMDMyNTQyWhcNMDgwODAxMDMyNTQyWjBBMREwDwYDVQQDDAhy
+dWJ5Z2VtczEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUxEzARBgoJkiaJk/IsZAEZ
+FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPS1M62wm4cMoA
+RetDHR/oNQTMERRNItHV+TSIQexj2sMJDGazDkF/ZSdWF0PTcHj9fMgr6lq3YIxB
+zfv+8sgG5WBLuD9/Nq0aIzSbmsAe3JyvRdTwSTrOPHiJK/vQ4uPJtj7+60cIRzzf
+xrAYMwIVHbWNjGABM9XCoAjJqy/BsqH9WHC4SsU+pP0bwEpMexpf4f4AMhEfTTU6
+ZaSMHoTKMXTnXXiQ0xrT7YLt1pX2GgEveZ2EK3rM4ZxqmX/0uQbGFw0RQH9KjXpX
+VlCV2D2ZpwbJaS3I1NJ9y2UX5/yiQCaJwbdcjBpbxROaMUKa8Oz+HVH+4ql7Yg4f
+Pzufb13ZAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
+BBRYTAoj4cn8CWZMHFnHGQgoO5jyFTANBgkqhkiG9w0BAQUFAAOCAQEATRrJC05l
+dOmx67Sy3bU+AVXkOr7B9nn2Myqo9uSIAncPoElN6aHr/Q8wOOjtok4r0JcHPe1e
+eotDCZUE1Jkl13Tpv26rOfOOUHtGlyAIAtpsUGOraaJkSut4WKLr1/KckyAAEtgP
+c13A0s0mEiWFRuYxIdEi54561pTT2qQBE/DUPGoYD5rUg9XYAlSovMMwG99Oca7L
+cI6vCymr1bzzddExoywBNOy0fbBT62I3ICBGbH5yOVVKVmlxeo2Zp10FCj0kDrnq
+OuMJSDr5I2XPYqoC+W4YSbwn55o2jGIUX1lOq2Hvj4tFgSxlnJZn0tUhBfR3gSOn
+IFnrqu8PlZsLFw==
+-----END CERTIFICATE-----
Added: MacRuby/trunk/test/test-mri/test/rubygems/fake_certlib/openssl.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/fake_certlib/openssl.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/fake_certlib/openssl.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,7 @@
+#--
+# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
+# All rights reserved.
+# See LICENSE.txt for permissions.
+#++
+
+raise LoadError, "no such file to load -- openssl"
Added: MacRuby/trunk/test/test-mri/test/rubygems/foo/discover.rb
===================================================================
Added: MacRuby/trunk/test/test-mri/test/rubygems/functional.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/functional.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/functional.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,92 @@
+require 'rubygems'
+require 'minitest/unit'
+require 'test/insure_session'
+require 'rubygems/format'
+require 'rubygems/command_manager'
+
+class FunctionalTest < MiniTest::Unit::TestCase
+
+ def setup
+ @gem_path = File.expand_path("bin/gem")
+ lib_path = File.expand_path("lib")
+ @ruby_options = "-I#{lib_path} -I."
+ @verbose = false
+ end
+
+ def test_gem_help_options
+ gem_nossl 'help options'
+ assert_match(/Usage:/, @out, @err)
+ assert_status
+ end
+
+ def test_gem_help_commands
+ gem_nossl 'help commands'
+ assert_match(/gem install/, @out)
+ assert_status
+ end
+
+ def test_gem_no_args_shows_help
+ gem_nossl
+ assert_match(/Usage:/, @out)
+ assert_status 1
+ end
+
+ # This test is disabled because of the insanely long time it takes
+ # to time out.
+ def xtest_bogus_source_hoses_up_remote_install_but_gem_command_gives_decent_error_message
+ @ruby_options << " -rtest/bogussources"
+ gem_nossl "install asdf --remote"
+ assert_match(/error/im, @err)
+ assert_status 1
+ end
+
+ def test_all_command_helps
+ mgr = Gem::CommandManager.new
+ mgr.command_names.each do |cmdname|
+ gem_nossl "help #{cmdname}"
+ assert_match(/Usage: gem #{cmdname}/, @out,
+ "should see help for #{cmdname}")
+ end
+ end
+
+ # :section: Help Methods
+
+ # Run a gem command without the SSL library.
+ def gem_nossl(options="")
+ old_options = @ruby_options.dup
+ @ruby_options << " -Itest/fake_certlib"
+ gem(options)
+ ensure
+ @ruby_options = old_options
+ end
+
+ # Run a gem command with the SSL library.
+ def gem_withssl(options="")
+ gem(options)
+ end
+
+ # Run a gem command for the functional test.
+ def gem(options="")
+ shell = Session::Shell.new
+ options = options + " --config-file missing_file" if options !~ /--config-file/
+ command = "#{Gem.ruby} #{@ruby_options} #{@gem_path} #{options}"
+ puts "\n\nCOMMAND: [#{command}]" if @verbose
+ @out, @err = shell.execute command
+ @status = shell.exit_status
+ puts "STATUS: [#{@status}]" if @verbose
+ puts "OUTPUT: [#{@out}]" if @verbose
+ puts "ERROR: [#{@err}]" if @verbose
+ puts "PWD: [#{Dir.pwd}]" if @verbose
+ shell.close
+ end
+
+ private
+
+ def assert_status(expected_status=0)
+ assert_equal expected_status, @status
+ end
+
+end
+
+MiniTest::Unit.autorun
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/gem_installer_test_case.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/gem_installer_test_case.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/gem_installer_test_case.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,97 @@
+require_relative 'gemutilities'
+require 'rubygems/installer'
+
+class Gem::Installer
+ attr_accessor :gem_dir
+
+ attr_writer :format
+ attr_writer :gem_home
+ attr_writer :env_shebang
+ attr_writer :ignore_dependencies
+ attr_writer :format_executable
+ attr_writer :security_policy
+ attr_writer :spec
+ attr_writer :wrappers
+end
+
+class GemInstallerTestCase < RubyGemTestCase
+
+ def setup
+ super
+
+ @spec = quick_gem 'a'
+ @gem = File.join @tempdir, @spec.file_name
+
+ @installer = util_installer @spec, @gem, @gemhome
+
+ @user_spec = quick_gem 'b'
+ @user_gem = File.join @tempdir, @user_spec.file_name
+
+ @user_installer = util_installer @user_spec, @user_gem, Gem.user_dir
+ @user_installer.gem_dir = File.join(Gem.user_dir, 'gems',
+ @user_spec.full_name)
+ end
+
+ def util_gem_bindir(version = '2')
+ File.join util_gem_dir(version), "bin"
+ end
+
+ def util_gem_dir(version = '2')
+ File.join @gemhome, "gems", "a-#{version}" # HACK
+ end
+
+ def util_inst_bindir
+ File.join @gemhome, "bin"
+ end
+
+ def util_make_exec(version = '2', shebang = "#!/usr/bin/ruby")
+ @spec.executables = ["my_exec"]
+
+ FileUtils.mkdir_p util_gem_bindir(version)
+ exec_path = File.join util_gem_bindir(version), "my_exec"
+ File.open exec_path, 'w' do |f|
+ f.puts shebang
+ end
+ end
+
+ def util_setup_gem(ui = @ui) # HACK fix use_ui to make this automatic
+ @spec.files = File.join('lib', 'code.rb')
+ @spec.executables << 'executable'
+ @spec.extensions << File.join('ext', 'a', 'mkrf_conf.rb')
+
+ Dir.chdir @tempdir do
+ FileUtils.mkdir_p 'bin'
+ FileUtils.mkdir_p 'lib'
+ FileUtils.mkdir_p File.join('ext', 'a')
+ File.open File.join('bin', 'executable'), 'w' do |f| f.puts '1' end
+ File.open File.join('lib', 'code.rb'), 'w' do |f| f.puts '1' end
+ File.open File.join('ext', 'a', 'mkrf_conf.rb'), 'w' do |f|
+ f << <<-EOF
+ File.open 'Rakefile', 'w' do |rf| rf.puts "task :default" end
+ EOF
+ end
+
+ use_ui ui do
+ FileUtils.rm @gem
+ Gem::Builder.new(@spec).build
+ end
+ end
+
+ @installer = Gem::Installer.new @gem
+ end
+
+ def util_installer(spec, gem_path, gem_home)
+ util_build_gem spec
+ FileUtils.mv File.join(@gemhome, 'cache', spec.file_name),
+ @tempdir
+
+ installer = Gem::Installer.new gem_path
+ installer.gem_dir = util_gem_dir
+ installer.gem_home = gem_home
+ installer.spec = spec
+
+ installer
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/gem_package_tar_test_case.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/gem_package_tar_test_case.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/gem_package_tar_test_case.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,132 @@
+require_relative 'gemutilities'
+require 'rubygems/package'
+
+class TarTestCase < RubyGemTestCase
+
+ def ASCIIZ(str, length)
+ str + "\0" * (length - str.length)
+ end
+
+ def SP(s)
+ s + " "
+ end
+
+ def SP_Z(s)
+ s + " \0"
+ end
+
+ def Z(s)
+ s + "\0"
+ end
+
+ def assert_headers_equal(expected, actual)
+ expected = expected.to_s unless String === expected
+ actual = actual.to_s unless String === actual
+
+ fields = %w[
+ name 100
+ mode 8
+ uid 8
+ gid 8
+ size 12
+ mtime 12
+ checksum 8
+ typeflag 1
+ linkname 100
+ magic 6
+ version 2
+ uname 32
+ gname 32
+ devmajor 8
+ devminor 8
+ prefix 155
+ ]
+
+ offset = 0
+
+ until fields.empty? do
+ name = fields.shift
+ length = fields.shift.to_i
+
+ if name == "checksum" then
+ chksum_off = offset
+ offset += length
+ next
+ end
+
+ assert_equal expected[offset, length], actual[offset, length],
+ "Field #{name} of the tar header differs."
+
+ offset += length
+ end
+
+ assert_equal expected[chksum_off, 8], actual[chksum_off, 8]
+ end
+
+ def calc_checksum(header)
+ sum = header.unpack("C*").inject{|s,a| s + a}
+ SP(Z(to_oct(sum, 6)))
+ end
+
+ def header(type, fname, dname, length, mode, checksum = nil)
+ checksum ||= " " * 8
+
+ arr = [ # struct tarfile_entry_posix
+ ASCIIZ(fname, 100), # char name[100]; ASCII + (Z unless filled)
+ Z(to_oct(mode, 7)), # char mode[8]; 0 padded, octal null
+ Z(to_oct(0, 7)), # char uid[8]; ditto
+ Z(to_oct(0, 7)), # char gid[8]; ditto
+ Z(to_oct(length, 11)), # char size[12]; 0 padded, octal, null
+ Z(to_oct(0, 11)), # char mtime[12]; 0 padded, octal, null
+ checksum, # char checksum[8]; 0 padded, octal, null, space
+ type, # char typeflag[1]; file: "0" dir: "5"
+ "\0" * 100, # char linkname[100]; ASCII + (Z unless filled)
+ "ustar\0", # char magic[6]; "ustar\0"
+ "00", # char version[2]; "00"
+ ASCIIZ("wheel", 32), # char uname[32]; ASCIIZ
+ ASCIIZ("wheel", 32), # char gname[32]; ASCIIZ
+ Z(to_oct(0, 7)), # char devmajor[8]; 0 padded, octal, null
+ Z(to_oct(0, 7)), # char devminor[8]; 0 padded, octal, null
+ ASCIIZ(dname, 155) # char prefix[155]; ASCII + (Z unless filled)
+ ]
+
+ format = "C100C8C8C8C12C12C8CC100C6C2C32C32C8C8C155"
+ h = if RUBY_VERSION >= "1.9" then
+ arr.join
+ else
+ arr = arr.join("").split(//).map{|x| x[0]}
+ arr.pack format
+ end
+ ret = h + "\0" * (512 - h.size)
+ assert_equal(512, ret.size)
+ ret
+ end
+
+ def tar_dir_header(name, prefix, mode)
+ h = header("5", name, prefix, 0, mode)
+ checksum = calc_checksum(h)
+ header("5", name, prefix, 0, mode, checksum)
+ end
+
+ def tar_file_header(fname, dname, mode, length)
+ h = header("0", fname, dname, length, mode)
+ checksum = calc_checksum(h)
+ header("0", fname, dname, length, mode, checksum)
+ end
+
+ def to_oct(n, pad_size)
+ "%0#{pad_size}o" % n
+ end
+
+ def util_entry(tar)
+ io = TempIO.new tar
+ header = Gem::Package::TarHeader.from io
+ entry = Gem::Package::TarReader::Entry.new header, io
+ end
+
+ def util_dir_entry
+ util_entry tar_dir_header("foo", "bar", 0)
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/rubygems-bug-child-1.0/lib/.gitignore
===================================================================
Added: MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/rubygems-bug-child-1.1/lib/.gitignore
===================================================================
Added: MacRuby/trunk/test/test-mri/test/rubygems/gems/current/gems/rubygems-bug-parent-1.0/lib/.gitignore
===================================================================
Added: MacRuby/trunk/test/test-mri/test/rubygems/gems/current/specifications/.gitignore
===================================================================
Added: MacRuby/trunk/test/test-mri/test/rubygems/gemutilities.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/gemutilities.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/gemutilities.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,584 @@
+at_exit { $SAFE = 1 }
+
+$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
+
+require 'rubygems'
+require 'fileutils'
+require 'minitest/autorun'
+require 'tmpdir'
+require 'uri'
+require 'rubygems/package'
+require 'rubygems/test_utilities'
+require 'pp'
+require 'yaml'
+begin
+ YAML::ENGINE.yamler = 'psych'
+rescue LoadError
+end if YAML.const_defined? :ENGINE
+
+begin
+ gem 'rdoc'
+rescue Gem::LoadError
+end
+
+require 'rdoc/rdoc'
+
+require_relative 'mockgemui'
+
+module Gem
+ def self.searcher=(searcher)
+ MUTEX.synchronize do @searcher = searcher end
+ end
+
+ def self.source_index=(si)
+ @@source_index = si
+ end
+
+ def self.win_platform=(val)
+ @@win_platform = val
+ end
+
+ module DefaultUserInteraction
+ @ui = MockGemUi.new
+ end
+end
+
+class RubyGemTestCase < MiniTest::Unit::TestCase
+
+ include Gem::DefaultUserInteraction
+
+ undef_method :default_test if instance_methods.include? 'default_test' or
+ instance_methods.include? :default_test
+
+ def setup
+ super
+
+ @ui = MockGemUi.new
+ tmpdir = nil
+ Dir.chdir Dir.tmpdir do tmpdir = Dir.pwd end # HACK OSX /private/tmp
+ @tempdir = File.join tmpdir, "test_rubygems_#{$$}"
+ @tempdir.untaint
+ @gemhome = File.join @tempdir, "gemhome"
+ @gemcache = File.join(@gemhome, "source_cache")
+ @usrcache = File.join(@gemhome, ".gem", "user_cache")
+ @latest_usrcache = File.join(@gemhome, ".gem", "latest_user_cache")
+ @userhome = File.join @tempdir, 'userhome'
+
+ Gem.ensure_gem_subdirectories @gemhome
+
+ @orig_ruby = if ruby = ENV['RUBY'] then
+ Gem.class_eval { ruby, @ruby = @ruby, ruby }
+ ruby
+ end
+
+ Gem.ensure_gem_subdirectories @gemhome
+
+ @orig_ENV_HOME = ENV['HOME']
+ ENV['HOME'] = @userhome
+ Gem.instance_variable_set :@user_home, nil
+
+ FileUtils.mkdir_p @gemhome
+ FileUtils.mkdir_p @userhome
+
+ ENV['GEMCACHE'] = @usrcache
+ Gem.use_paths(@gemhome)
+ Gem.loaded_specs.clear
+
+ Gem.configuration.verbose = true
+ Gem.configuration.update_sources = true
+
+ @gem_repo = "http://gems.example.com/"
+ @uri = URI.parse @gem_repo
+ Gem.sources.replace [@gem_repo]
+
+ Gem::SpecFetcher.fetcher = nil
+
+ @orig_BASERUBY = Gem::ConfigMap[:BASERUBY]
+ Gem::ConfigMap[:BASERUBY] = Gem::ConfigMap[:ruby_install_name]
+
+ @orig_arch = Gem::ConfigMap[:arch]
+
+ if win_platform?
+ util_set_arch 'i386-mswin32'
+ else
+ util_set_arch 'i686-darwin8.10.1'
+ end
+
+ @marshal_version = "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
+
+ @private_key = File.expand_path File.join(File.dirname(__FILE__),
+ 'private_key.pem')
+ @public_cert = File.expand_path File.join(File.dirname(__FILE__),
+ 'public_cert.pem')
+
+ Gem.post_install_hooks.clear
+ Gem.post_uninstall_hooks.clear
+ Gem.pre_install_hooks.clear
+ Gem.pre_uninstall_hooks.clear
+
+ Gem.post_install do |installer|
+ @post_install_hook_arg = installer
+ end
+
+ Gem.post_uninstall do |uninstaller|
+ @post_uninstall_hook_arg = uninstaller
+ end
+
+ Gem.pre_install do |installer|
+ @pre_install_hook_arg = installer
+ end
+
+ Gem.pre_uninstall do |uninstaller|
+ @pre_uninstall_hook_arg = uninstaller
+ end
+ end
+
+ def teardown
+ Gem::ConfigMap[:BASERUBY] = @orig_BASERUBY
+ Gem::ConfigMap[:arch] = @orig_arch
+
+ if defined? Gem::RemoteFetcher then
+ Gem::RemoteFetcher.fetcher = nil
+ end
+
+ FileUtils.rm_rf @tempdir
+
+ ENV.delete 'GEMCACHE'
+ ENV.delete 'GEM_HOME'
+ ENV.delete 'GEM_PATH'
+
+ Gem.clear_paths
+
+ Gem.class_eval { @ruby = ruby } if ruby = @orig_ruby
+
+ if @orig_ENV_HOME then
+ ENV['HOME'] = @orig_ENV_HOME
+ else
+ ENV.delete 'HOME'
+ end
+ end
+
+ def install_gem gem
+ require 'rubygems/installer'
+
+ use_ui MockGemUi.new do
+ Dir.chdir @tempdir do
+ Gem::Builder.new(gem).build
+ end
+ end
+
+ gem = File.join(@tempdir, gem.file_name).untaint
+ Gem::Installer.new(gem, :wrappers => true).install
+ end
+
+ def mu_pp(obj)
+ s = ''
+ s = PP.pp obj, s
+ s = s.force_encoding(Encoding.default_external) if defined? Encoding
+ s.chomp
+ end
+
+ def prep_cache_files(lc)
+ @usr_si ||= Gem::SourceIndex.new
+ @usr_sice ||= Gem::SourceInfoCacheEntry.new @usr_si, 0
+
+ @sys_si ||= Gem::SourceIndex.new
+ @sys_sice ||= Gem::SourceInfoCacheEntry.new @sys_si, 0
+
+ latest_si = Gem::SourceIndex.new
+ latest_si.add_specs(*@sys_si.latest_specs)
+ latest_sys_sice = Gem::SourceInfoCacheEntry.new latest_si, 0
+
+ latest_si = Gem::SourceIndex.new
+ latest_si.add_specs(*@usr_si.latest_specs)
+ latest_usr_sice = Gem::SourceInfoCacheEntry.new latest_si, 0
+
+ [ [lc.system_cache_file, @sys_sice],
+ [lc.latest_system_cache_file, latest_sys_sice],
+ [lc.user_cache_file, @usr_sice],
+ [lc.latest_user_cache_file, latest_usr_sice],
+ ].each do |filename, data|
+ FileUtils.mkdir_p File.dirname(filename).untaint
+
+ open filename.dup.untaint, 'wb' do |f|
+ f.write Marshal.dump({ @gem_repo => data })
+ end
+ end
+ end
+
+ def read_cache(path)
+ open path.dup.untaint, 'rb' do |io|
+ Marshal.load io.read
+ end
+ end
+
+ def read_binary(path)
+ Gem.read_binary path
+ end
+
+ def write_file(path)
+ path = File.join(@gemhome, path)
+ dir = File.dirname path
+ FileUtils.mkdir_p dir
+
+ open path, 'wb' do |io|
+ yield io
+ end
+
+ path
+ end
+
+ def quick_gem(gemname, version='2')
+ require 'rubygems/specification'
+
+ spec = Gem::Specification.new do |s|
+ s.platform = Gem::Platform::RUBY
+ s.name = gemname
+ s.version = version
+ s.author = 'A User'
+ s.email = 'example at example.com'
+ s.homepage = 'http://example.com'
+ s.has_rdoc = true
+ s.summary = "this is a summary"
+ s.description = "This is a test description"
+
+ yield(s) if block_given?
+ end
+
+ path = File.join "specifications", spec.spec_name
+ written_path = write_file path do |io|
+ io.write(spec.to_ruby)
+ end
+
+ spec.loaded_from = written_path
+
+ Gem.source_index.add_spec spec
+
+ return spec
+ end
+
+ def util_build_gem(spec)
+ dir = File.join(@gemhome, 'gems', spec.full_name)
+ FileUtils.mkdir_p dir
+
+ Dir.chdir dir do
+ spec.files.each do |file|
+ next if File.exist? file
+ FileUtils.mkdir_p File.dirname(file)
+ File.open file, 'w' do |fp| fp.puts "# #{file}" end
+ end
+
+ use_ui MockGemUi.new do
+ Gem::Builder.new(spec).build
+ end
+
+ FileUtils.mv spec.file_name,
+ File.join(@gemhome, 'cache', "#{spec.original_name}.gem")
+ end
+ end
+
+ def util_clear_gems
+ FileUtils.rm_r File.join(@gemhome, 'gems')
+ FileUtils.rm_r File.join(@gemhome, 'specifications')
+ Gem.source_index.refresh!
+ end
+
+ def util_gem(name, version, &block)
+ spec = quick_gem(name, version, &block)
+
+ util_build_gem spec
+
+ cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem"
+ FileUtils.mv File.join(@gemhome, 'cache', "#{spec.original_name}.gem"),
+ cache_file
+ FileUtils.rm File.join(@gemhome, 'specifications', spec.spec_name)
+
+ spec.loaded_from = nil
+ spec.loaded = false
+
+ [spec, cache_file]
+ end
+
+ def util_gzip(data)
+ out = StringIO.new
+
+ Zlib::GzipWriter.wrap out do |io|
+ io.write data
+ end
+
+ out.string
+ end
+
+ def util_make_gems(prerelease = false)
+ @a1 = quick_gem 'a', '1' do |s|
+ s.files = %w[lib/code.rb]
+ s.require_paths = %w[lib]
+ s.date = Gem::Specification::TODAY - 86400
+ s.homepage = 'http://a.example.com'
+ s.email = %w[example at example.com example2 at example.com]
+ s.authors = %w[Example Example2]
+ s.description = <<-DESC
+This line is really, really long. So long, in fact, that it is more than eighty characters long! The purpose of this line is for testing wrapping behavior because sometimes people don't wrap their text to eighty characters. Without the wrapping, the text might not look good in the RSS feed.
+
+Also, a list:
+ * An entry that's actually kind of sort
+ * an entry that's really long, which will probably get wrapped funny. That's ok, somebody wasn't thinking straight when they made it more than eighty characters.
+ DESC
+ end
+
+ init = proc do |s|
+ s.files = %w[lib/code.rb]
+ s.require_paths = %w[lib]
+ end
+
+ @a2 = quick_gem('a', '2', &init)
+ @a3a = quick_gem('a', '3.a', &init)
+ @a_evil9 = quick_gem('a_evil', '9', &init)
+ @b2 = quick_gem('b', '2', &init)
+ @c1_2 = quick_gem('c', '1.2', &init)
+ @pl1 = quick_gem 'pl', '1' do |s| # l for legacy
+ s.files = %w[lib/code.rb]
+ s.require_paths = %w[lib]
+ s.platform = Gem::Platform.new 'i386-linux'
+ s.instance_variable_set :@original_platform, 'i386-linux'
+ end
+
+ if prerelease
+ @a2_pre = quick_gem('a', '2.a', &init)
+ write_file File.join(*%W[gems #{@a2_pre.original_name} lib code.rb]) do
+ end
+ util_build_gem @a2_pre
+ end
+
+ write_file File.join(*%W[gems #{@a1.original_name} lib code.rb]) do end
+ write_file File.join(*%W[gems #{@a2.original_name} lib code.rb]) do end
+ write_file File.join(*%W[gems #{@a3a.original_name} lib code.rb]) do end
+ write_file File.join(*%W[gems #{@b2.original_name} lib code.rb]) do end
+ write_file File.join(*%W[gems #{@c1_2.original_name} lib code.rb]) do end
+ write_file File.join(*%W[gems #{@pl1.original_name} lib code.rb]) do end
+
+ [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2, @pl1].each do |spec|
+ util_build_gem spec
+ end
+
+ FileUtils.rm_r File.join(@gemhome, 'gems', @pl1.original_name)
+
+ Gem.source_index = nil
+ end
+
+ ##
+ # Set the platform to +arch+
+
+ def util_set_arch(arch)
+ Gem::ConfigMap[:arch] = arch
+ platform = Gem::Platform.new arch
+
+ Gem.instance_variable_set :@platforms, nil
+ Gem::Platform.instance_variable_set :@local, nil
+
+ platform
+ end
+
+ def util_setup_fake_fetcher(prerelease = false)
+ require 'zlib'
+ require 'socket'
+ require 'rubygems/remote_fetcher'
+
+ @fetcher = Gem::FakeFetcher.new
+
+ util_make_gems(prerelease)
+
+ @all_gems = [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2].sort
+ @all_gem_names = @all_gems.map { |gem| gem.full_name }
+
+ gem_names = [@a1.full_name, @a2.full_name, @a3a.full_name, @b2.full_name]
+ @gem_names = gem_names.sort.join("\n")
+
+ @source_index = Gem::SourceIndex.new
+ @source_index.add_spec @a1
+ @source_index.add_spec @a2
+ @source_index.add_spec @a3a
+ @source_index.add_spec @a_evil9
+ @source_index.add_spec @c1_2
+ @source_index.add_spec @a2_pre if prerelease
+
+ Gem::RemoteFetcher.fetcher = @fetcher
+ end
+
+ def util_setup_spec_fetcher(*specs)
+ specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten]
+ si = Gem::SourceIndex.new specs
+
+ spec_fetcher = Gem::SpecFetcher.fetcher
+
+ spec_fetcher.specs[@uri] = []
+ si.gems.sort_by { |_, spec| spec }.each do |_, spec|
+ spec_tuple = [spec.name, spec.version, spec.original_platform]
+ spec_fetcher.specs[@uri] << spec_tuple
+ end
+
+ spec_fetcher.latest_specs[@uri] = []
+ si.latest_specs.sort.each do |spec|
+ spec_tuple = [spec.name, spec.version, spec.original_platform]
+ spec_fetcher.latest_specs[@uri] << spec_tuple
+ end
+
+ spec_fetcher.prerelease_specs[@uri] = []
+ si.prerelease_specs.sort.each do |spec|
+ spec_tuple = [spec.name, spec.version, spec.original_platform]
+ spec_fetcher.prerelease_specs[@uri] << spec_tuple
+ end
+
+ (si.gems.merge si.prerelease_gems).sort_by { |_,spec| spec }.each do |_, spec|
+ path = "#{@gem_repo}quick/Marshal.#{Gem.marshal_version}/#{spec.original_name}.gemspec.rz"
+ data = Marshal.dump spec
+ data_deflate = Zlib::Deflate.deflate data
+ @fetcher.data[path] = data_deflate
+ end
+
+ si
+ end
+
+ def util_zip(data)
+ Zlib::Deflate.deflate data
+ end
+
+ def self.win_platform?
+ Gem.win_platform?
+ end
+
+ def win_platform?
+ Gem.win_platform?
+ end
+
+ # Returns whether or not we're on a version of Ruby built with VC++ (or
+ # Borland) versus Cygwin, Mingw, etc.
+ #
+ def self.vc_windows?
+ RUBY_PLATFORM.match('mswin')
+ end
+
+ # Returns whether or not we're on a version of Ruby built with VC++ (or
+ # Borland) versus Cygwin, Mingw, etc.
+ #
+ def vc_windows?
+ RUBY_PLATFORM.match('mswin')
+ end
+
+ # Returns the make command for the current platform. For versions of Ruby
+ # built on MS Windows with VC++ or Borland it will return 'nmake'. On all
+ # other platforms, including Cygwin, it will return 'make'.
+ #
+ def self.make_command
+ ENV["make"] || (vc_windows? ? 'nmake' : 'make')
+ end
+
+ # Returns the make command for the current platform. For versions of Ruby
+ # built on MS Windows with VC++ or Borland it will return 'nmake'. On all
+ # other platforms, including Cygwin, it will return 'make'.
+ #
+ def make_command
+ ENV["make"] || (vc_windows? ? 'nmake' : 'make')
+ end
+
+ # Returns whether or not the nmake command could be found.
+ #
+ def nmake_found?
+ system('nmake /? 1>NUL 2>&1')
+ end
+
+ # NOTE Allow tests to use a random (but controlled) port number instead of
+ # a hardcoded one. This helps CI tools when running parallels builds on
+ # the same builder slave.
+ def self.process_based_port
+ @@process_based_port ||= 8000 + $$ % 1000
+ end
+
+ def process_based_port
+ self.class.process_based_port
+ end
+
+ def build_rake_in
+ gem_ruby = Gem.ruby
+ ruby = @@ruby
+ Gem.module_eval {@ruby = ruby}
+ env_rake = ENV["rake"]
+ ENV["rake"] = @@rake
+ yield @@rake
+ ensure
+ Gem.module_eval {@ruby = gem_ruby}
+ if env_rake
+ ENV["rake"] = env_rake
+ else
+ ENV.delete("rake")
+ end
+ end
+
+ def self.rubybin
+ if ruby = ENV["RUBY"]
+ return ruby
+ end
+ ruby = "ruby"
+ rubyexe = ruby+".exe"
+ 3.times do
+ if File.exist? ruby and File.executable? ruby and !File.directory? ruby
+ return File.expand_path(ruby)
+ end
+ if File.exist? rubyexe and File.executable? rubyexe
+ return File.expand_path(rubyexe)
+ end
+ ruby = File.join("..", ruby)
+ end
+ begin
+ require "rbconfig"
+ File.join(
+ RbConfig::CONFIG["bindir"],
+ RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"]
+ )
+ rescue LoadError
+ "ruby"
+ end
+ end
+
+ @@ruby = rubybin
+ env_rake = ENV['rake']
+ ruby19_rake = File.expand_path("../../../bin/rake", __FILE__)
+ @@rake = if env_rake then
+ ENV["rake"]
+ elsif File.exist? ruby19_rake then
+ @@ruby + " " + ruby19_rake
+ else
+ 'rake'
+ end
+
+ ##
+ # Construct a new Gem::Dependency.
+
+ def dep name, *requirements
+ Gem::Dependency.new name, *requirements
+ end
+
+ ##
+ # Construct a new Gem::Requirement.
+
+ def req *requirements
+ return requirements.first if Gem::Requirement === requirements.first
+ Gem::Requirement.create requirements
+ end
+
+ ##
+ # Construct a new Gem::Specification.
+
+ def spec name, version, &block
+ Gem::Specification.new name, v(version), &block
+ end
+
+ ##
+ # Construct a new Gem::Version.
+
+ def v string
+ Gem::Version.create string
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/insure_session.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/insure_session.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/insure_session.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,43 @@
+require 'rubygems'
+
+def install_session
+ path_to_gem = File.join("redist", "session.gem")
+ begin
+ Gem::Installer.new(path_to_gem).install
+ rescue Errno::EACCES => ex
+ puts
+ puts "*****************************************************************"
+ puts "Unable to install Gem 'Session'."
+ puts "Reason: #{ex.message}"
+ puts "Try running:"
+ puts
+ puts " gem -Li #{path_to_gem}"
+ puts
+ puts "with the appropriate admin privileges."
+ puts "*****************************************************************"
+ puts
+ exit
+ end
+ gem 'session'
+end
+
+begin
+ require 'session'
+rescue LoadError => e
+ puts
+ puts "Required Gem 'Session' missing."
+ puts "We can attempt to install from the RubyGems Distribution,"
+ puts "but installation may require admin privileges on your system."
+ puts
+ print "Install now from RubyGems distribution? [Yn]"
+ answer = gets
+ if(answer =~ /^y/i || answer =~ /^[^a-zA-Z0-9]$/) then
+ install_session
+ puts
+ puts "Retry running the functional tests."
+ exit(0)
+ else
+ puts "Test cancelled...quitting"
+ exit(1)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rubygems/mockgemui.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/mockgemui.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/mockgemui.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,56 @@
+require 'stringio'
+require 'rubygems/user_interaction'
+
+class MockGemUi < Gem::StreamUI
+ class TermError < RuntimeError; end
+
+ module TTY
+
+ attr_accessor :tty
+
+ def tty?()
+ @tty = true unless defined?(@tty)
+ @tty
+ end
+
+ end
+
+ def initialize(input = "")
+ ins = StringIO.new input
+ outs = StringIO.new
+ errs = StringIO.new
+
+ ins.extend TTY
+ outs.extend TTY
+ errs.extend TTY
+
+ super ins, outs, errs
+
+ @terminated = false
+ end
+
+ def input
+ @ins.string
+ end
+
+ def output
+ @outs.string
+ end
+
+ def error
+ @errs.string
+ end
+
+ def terminated?
+ @terminated
+ end
+
+ def terminate_interaction(status=0)
+ @terminated = true
+
+ raise TermError unless status == 0
+ raise Gem::SystemExitException, status
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/plugin/exception/rubygems_plugin.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/plugin/exception/rubygems_plugin.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/plugin/exception/rubygems_plugin.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,2 @@
+TestGem::TEST_PLUGIN_EXCEPTION = :loaded
+raise Exception.new('boom')
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/rubygems/plugin/load/rubygems_plugin.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/plugin/load/rubygems_plugin.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/plugin/load/rubygems_plugin.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+TestGem::TEST_PLUGIN_LOAD = :loaded
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/rubygems/plugin/standarderror/rubygems_plugin.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/plugin/standarderror/rubygems_plugin.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/plugin/standarderror/rubygems_plugin.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,2 @@
+TestGem::TEST_PLUGIN_STANDARDERROR = :loaded
+raise StandardError.new('boom')
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/rubygems/private_key.pem
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/private_key.pem (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/private_key.pem 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAm24C6xixiAxO+i1f3L8XRMwrmLkt6BvT60mZ7g8HsklH3af7
+KNHA6vo/G6sujs2UsNO4HY8BTEneiVOXXWQlcsJ+Z5wEPlIu4zFueAmLefx+n9lE
+ulNIUDoyUenKX4spoMRnX8k4lXL05ho/6JFq0JdDY2DmAaQ4vvTz5mh9kZiybtHQ
+fzcpbA51uY+sjdQRCPDHyUUfh0SmWJlLYMwcBdVeCiGUPBLi+iP5x1btO4uiJK6Q
+IMaV1H3SUCYtKGQKl7qwFd8k8ZBcHYOtmK61tupg3vqWQc0em6SxPj5lws8+1MVK
+twBNIDx24jF4ntxBRNKMZ7FN5SHbobAgDYkPAQIDAQABAoIBAGQilgK8X/PUajVH
+clEXU3hhSV0VQHwfIYKeYms6h6zXBVPKW0dLC0zXeDztJgueasMZQ67XaPCrTpGO
+px/l2zJ6F1HM8/bqn4aDXDY9f/xRLYryQRMBgL8fHzgitNylHWaT4j2Vt7yg2SI9
+mxrMRNKqASJPVR+Nm3l6+n9gpjVb99wEucWplPPHI6KhXLYPZOqSwt+zaH5roz3k
+UQmMs0Bs4hF1SzVl0n+KNoXHOwswVrmBWXgWvm2OhnwY2e26jfejc8toJc/ShAJ7
+C9exnrdimcgEKbd22Sum4G00CDYhcrG5LHHqkgwifcAEVctrvBZBZHGgpxlO8a8U
+eF2Vr7kCgYEAykdrBlzp7Fn9xzUInBQ3NXTTYAq51lpuJdmHQmPuTSY0buoHkd9f
+xbUCZ2qR9QAesrx4hI0qGLetc8IOKDoWx2rPepCCvO3Kx61o1SB5fAvBue03qVoq
+HqACX3Uk24Em8zAz9xuP13ETH/wU7sUbUxRHMCre6ZDmlxn4g5l+Nl8CgYEAxLVl
+22yBx0dfRr3UsHY9rxll2gIlnfnYfiJzq8wetzt/TfztRV5ILz7FyWqL5d7IoqkA
+fT2V4HAasRJASnKohwJe7z5M/H2ExwkGNFvY+jefb2CoUl5WouK9AlhbqBk3zmHi
+sY5GqQkAp/kHMntEin+sErJw6mkgAGdser3a9p8CgYEAqi31w++tunRnxw4+RRnY
+7Pdx0k6T1NxV6TAe1ONAHNY0rM/mOHqml65W7GzDiU1lhlh8SIB/VzZJDqfHw15D
+xdh94A7uf0bMILwrA4wDyTIW9Xa3Kpq57vQNqwPiU25QN69pOM+Ob+IpBfLOJafc
++kOINOUMj5Kh/aQS6Zzci58CgYEAk24dlFKEBjbRCvU2FrfYTYcsljPru7ZJc2gg
+588J6m0WYf5CWy5pzbcviGFpzvSlzXv7GOLylQ+QgcxbETFUbDPzsT4xd0AgJwj1
+dIKuYgMUZOa94VZBer2TydEtiRS1heJJhKhM/1329u4nXceTvHYqIq1JAfeee48I
+eAoZtaMCgYBz1FjWFQnMTD5nmyPEEZneoBPAR5+9jwOps+IYOoHtazoMFszzd0qo
+JZW3Ihn9KRrVSxfFApKS/ZwjiZ+tJUk7DE/v/0l0sszefY7s8b0pL1lpeZSoL71e
+QoG1WLXUiDV3BRlmyOAF1h3p12KRTLgwubN51ajECwcs3QwE+ZT8Gg==
+-----END RSA PRIVATE KEY-----
Added: MacRuby/trunk/test/test-mri/test/rubygems/public_cert.pem
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/public_cert.pem (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/public_cert.pem 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMRAwDgYDVQQDDAdkcmJy
+YWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZFgNu
+ZXQwHhcNMDcxMjIxMDIwNDE0WhcNMDgxMjIwMDIwNDE0WjBBMRAwDgYDVQQDDAdk
+cmJyYWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZ
+FgNuZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbbgLrGLGIDE76
+LV/cvxdEzCuYuS3oG9PrSZnuDweySUfdp/so0cDq+j8bqy6OzZSw07gdjwFMSd6J
+U5ddZCVywn5nnAQ+Ui7jMW54CYt5/H6f2US6U0hQOjJR6cpfiymgxGdfyTiVcvTm
+Gj/okWrQl0NjYOYBpDi+9PPmaH2RmLJu0dB/NylsDnW5j6yN1BEI8MfJRR+HRKZY
+mUtgzBwF1V4KIZQ8EuL6I/nHVu07i6IkrpAgxpXUfdJQJi0oZAqXurAV3yTxkFwd
+g62YrrW26mDe+pZBzR6bpLE+PmXCzz7UxUq3AE0gPHbiMXie3EFE0oxnsU3lIduh
+sCANiQ8BAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
+BBS5k4Z75VSpdM0AclG2UvzFA/VW5DANBgkqhkiG9w0BAQUFAAOCAQEAHagT4lfX
+kP/hDaiwGct7XPuVGbrOsKRVD59FF5kETBxEc9UQ1clKWngf8JoVuEoKD774dW19
+bU0GOVWO+J6FMmT/Cp7nuFJ79egMf/gy4gfUfQMuvfcr6DvZUPIs9P/TlK59iMYF
+DIOQ3DxdF3rMzztNUCizN4taVscEsjCcgW6WkUJnGdqlu3OHWpQxZBJkBTjPCoc6
+UW6on70SFPmAy/5Cq0OJNGEWBfgD9q7rrs/X8GGwUWqXb85RXnUVi/P8Up75E0ag
+14jEc90kN+C7oI/AGCBN0j6JnEtYIEJZibjjDJTSMWlUKKkj30kq7hlUC2CepJ4v
+x52qPcexcYZR7w==
+-----END CERTIFICATE-----
Added: MacRuby/trunk/test/test-mri/test/rubygems/rubygems/commands/crash_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/rubygems/commands/crash_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/rubygems/commands/crash_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,5 @@
+class Gem::Commands::CrashCommand < Gem::Command
+
+ raise "crash"
+
+end
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/rubygems/rubygems_plugin.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/rubygems_plugin.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/rubygems_plugin.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,21 @@
+require 'rubygems/command_manager'
+
+##
+# This is an example of exactly what NOT to do.
+#
+# DO NOT include code like this in your rubygems_plugin.rb
+
+class Gem::Commands::InterruptCommand < Gem::Command
+
+ def initialize
+ super('interrupt', 'Raises an Interrupt Exception', {})
+ end
+
+ def execute
+ raise Interrupt, "Interrupt exception"
+ end
+
+end
+
+Gem::CommandManager.instance.register_command :interrupt
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/simple_gem.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/simple_gem.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/simple_gem.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,66 @@
+SIMPLE_GEM = <<-GEMDATA
+ MD5SUM = "b12a4d48febeb2289c539c2574c4b6f8"
+ if $0 == __FILE__
+ require 'optparse'
+
+ options = {}
+ ARGV.options do |opts|
+ opts.on_tail("--help", "show this message") {puts opts; exit}
+ opts.on('--dir=DIRNAME', "Installation directory for the Gem") {|options[:directory]|}
+ opts.on('--force', "Force Gem to intall, bypassing dependency checks") {|options[:force]|}
+ opts.on('--gen-rdoc', "Generate RDoc documentation for the Gem") {|options[:gen_rdoc]|}
+ opts.parse!
+ end
+
+ require 'rubygems'
+ @directory = options[:directory] || Gem.dir
+ @force = options[:force]
+
+ gem = Gem::Installer.new(__FILE__).install(@force, @directory)
+ if options[:gen_rdoc]
+ Gem::DocManager.new(gem).generate_rdoc
+ end
+end
+
+__END__
+--- !ruby/object:Gem::Specification
+rubygems_version: "1.0"
+name: testing
+version: !ruby/object:Gem::Version
+ version: 1.2.3
+date: 2004-03-18 22:01:52.859121 -05:00
+platform:
+summary: This exercise the gem testing stuff.
+require_paths:
+ - lib
+files:
+ - lib/foo.rb
+ - lib/test
+ - lib/test.rb
+ - lib/test/wow.rb
+autorequire: test
+test_suite_file: foo
+requirements:
+ - a computer processor
+---
+-
+ size: 109
+ mode: 420
+ path: lib/foo.rb
+-
+ size: 0
+ mode: 420
+ path: lib/test.rb
+-
+ size: 15
+ mode: 420
+ path: lib/test/wow.rb
+---
+eJwVjDEKgDAUQ/eeIpsKguhY3ARPoHMp9quF0mL7e39/h5DwQpLpqz4TOqbC
+U42eO6WuYEvBntIhECuaaX1KqXXLmy2kAEc32szExK+PjyBAlpTZyK0N/Twu
+g1CKTjX9BGAj1w==
+---
+eJwDAAAAAAE=
+---
+eJwrKC0pVlAvzy9XyE3MU+cCACwiBP4=
+GEMDATA
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_config.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_config.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_config.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,12 @@
+require_relative 'gemutilities'
+require 'rubygems'
+
+class TestConfig < RubyGemTestCase
+
+ def test_datadir
+ datadir = RbConfig::CONFIG['datadir']
+ assert_equal "#{datadir}/xyz", RbConfig.datadir('xyz')
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,708 @@
+require_relative 'gemutilities'
+require 'rubygems'
+require 'rubygems/gem_openssl'
+require 'rubygems/installer'
+require 'pathname'
+require 'tmpdir'
+
+class TestGem < RubyGemTestCase
+
+ def setup
+ super
+
+ @additional = %w[a b].map { |d| File.join @tempdir, d }
+ @default_dir_re = if RUBY_VERSION > '1.9' then
+ %r|/.*?[Rr]uby.*?/[Gg]ems/[0-9.]+|
+ else
+ %r|/[Rr]uby/[Gg]ems/[0-9.]+|
+ end
+
+ util_remove_interrupt_command
+ end
+
+ def test_self_all_load_paths
+ util_make_gems
+
+ expected = [
+ File.join(@gemhome, *%W[gems #{@a1.full_name} lib]),
+ File.join(@gemhome, *%W[gems #{@a2.full_name} lib]),
+ File.join(@gemhome, *%W[gems #{@a3a.full_name} lib]),
+ File.join(@gemhome, *%W[gems #{@a_evil9.full_name} lib]),
+ File.join(@gemhome, *%W[gems #{@b2.full_name} lib]),
+ File.join(@gemhome, *%W[gems #{@c1_2.full_name} lib]),
+ File.join(@gemhome, *%W[gems #{@pl1.full_name} lib]),
+ ]
+
+ assert_equal expected, Gem.all_load_paths.sort
+ end
+
+ def test_self_available?
+ util_make_gems
+ assert(Gem.available?("a"))
+ assert(Gem.available?("a", "1"))
+ assert(Gem.available?("a", ">1"))
+ assert(!Gem.available?("monkeys"))
+ end
+
+ def test_self_bin_path_bin_name
+ util_exec_gem
+ assert_equal @abin_path, Gem.bin_path('a', 'abin')
+ end
+
+ def test_self_bin_path_bin_name_version
+ util_exec_gem
+ assert_equal @abin_path, Gem.bin_path('a', 'abin', '4')
+ end
+
+ def test_self_bin_path_name
+ util_exec_gem
+ assert_equal @exec_path, Gem.bin_path('a')
+ end
+
+ def test_self_bin_path_name_version
+ util_exec_gem
+ assert_equal @exec_path, Gem.bin_path('a', nil, '4')
+ end
+
+ def test_self_bin_path_no_default_bin
+ quick_gem 'a', '2' do |s|
+ s.executables = ['exec']
+ end
+ assert_raises(Gem::Exception) do
+ Gem.bin_path('a', '2')
+ end
+ end
+
+ def test_self_bin_path_no_bin_file
+ quick_gem 'a', '1'
+ assert_raises(Gem::Exception) do
+ Gem.bin_path('a', '1')
+ end
+ end
+
+ def test_self_bin_path_not_found
+ assert_raises(Gem::GemNotFoundException) do
+ Gem.bin_path('non-existent')
+ end
+ end
+
+ def test_self_bindir
+ assert_equal File.join(@gemhome, 'bin'), Gem.bindir
+ assert_equal File.join(@gemhome, 'bin'), Gem.bindir(Gem.dir)
+ assert_equal File.join(@gemhome, 'bin'), Gem.bindir(Pathname.new(Gem.dir))
+ end
+
+ def test_self_bindir_default_dir
+ default = Gem.default_dir
+ bindir = if defined?(RUBY_FRAMEWORK_VERSION) then
+ '/usr/bin'
+ else
+ RbConfig::CONFIG['bindir']
+ end
+
+ assert_equal bindir, Gem.bindir(default)
+ assert_equal bindir, Gem.bindir(Pathname.new(default))
+ end
+
+ def test_self_clear_paths
+ Gem.dir
+ Gem.path
+ searcher = Gem.searcher
+ source_index = Gem.source_index
+
+ Gem.clear_paths
+
+ assert_equal nil, Gem.instance_variable_get(:@gem_home)
+ assert_equal nil, Gem.instance_variable_get(:@gem_path)
+ refute_equal searcher, Gem.searcher
+ refute_equal source_index.object_id, Gem.source_index.object_id
+ end
+
+ def test_self_configuration
+ expected = Gem::ConfigFile.new []
+ Gem.configuration = nil
+
+ assert_equal expected, Gem.configuration
+ end
+
+ def test_self_datadir
+ foo = nil
+
+ Dir.chdir @tempdir do
+ FileUtils.mkdir_p 'data'
+ File.open File.join('data', 'foo.txt'), 'w' do |fp|
+ fp.puts 'blah'
+ end
+
+ foo = quick_gem 'foo' do |s| s.files = %w[data/foo.txt] end
+ install_gem foo
+ end
+
+ Gem.source_index = nil
+
+ gem 'foo'
+
+ expected = File.join @gemhome, 'gems', foo.full_name, 'data', 'foo'
+
+ assert_equal expected, Gem.datadir('foo')
+ end
+
+ def test_self_datadir_nonexistent_package
+ assert_nil Gem.datadir('xyzzy')
+ end
+
+ def test_self_default_dir
+ assert_match @default_dir_re, Gem.default_dir
+ end
+
+ def test_self_default_exec_format
+ orig_RUBY_INSTALL_NAME = Gem::ConfigMap[:ruby_install_name]
+ Gem::ConfigMap[:ruby_install_name] = 'ruby'
+
+ assert_equal '%s', Gem.default_exec_format
+ ensure
+ Gem::ConfigMap[:ruby_install_name] = orig_RUBY_INSTALL_NAME
+ end
+
+ def test_self_default_exec_format_18
+ orig_RUBY_INSTALL_NAME = Gem::ConfigMap[:ruby_install_name]
+ Gem::ConfigMap[:ruby_install_name] = 'ruby18'
+
+ assert_equal '%s18', Gem.default_exec_format
+ ensure
+ Gem::ConfigMap[:ruby_install_name] = orig_RUBY_INSTALL_NAME
+ end
+
+ def test_self_default_exec_format_jruby
+ orig_RUBY_INSTALL_NAME = Gem::ConfigMap[:ruby_install_name]
+ Gem::ConfigMap[:ruby_install_name] = 'jruby'
+
+ assert_equal 'j%s', Gem.default_exec_format
+ ensure
+ Gem::ConfigMap[:ruby_install_name] = orig_RUBY_INSTALL_NAME
+ end
+
+ def test_self_default_sources
+ assert_equal %w[http://rubygems.org/], Gem.default_sources
+ end
+
+ def test_self_dir
+ assert_equal @gemhome, Gem.dir
+ end
+
+ def test_self_ensure_gem_directories
+ FileUtils.rm_r @gemhome
+ Gem.use_paths @gemhome
+
+ Gem.ensure_gem_subdirectories @gemhome
+
+ assert File.directory?(File.join(@gemhome, "cache"))
+ end
+
+ def test_self_ensure_gem_directories_missing_parents
+ gemdir = File.join @tempdir, 'a/b/c/gemdir'
+ FileUtils.rm_rf File.join(@tempdir, 'a') rescue nil
+ refute File.exist?(File.join(@tempdir, 'a')),
+ "manually remove #{File.join @tempdir, 'a'}, tests are broken"
+ Gem.use_paths gemdir
+
+ Gem.ensure_gem_subdirectories gemdir
+
+ assert File.directory?("#{gemdir}/cache")
+ end
+
+ unless win_platform? then # only for FS that support write protection
+ def test_self_ensure_gem_directories_write_protected
+ gemdir = File.join @tempdir, "egd"
+ FileUtils.rm_r gemdir rescue nil
+ refute File.exist?(gemdir), "manually remove #{gemdir}, tests are broken"
+ FileUtils.mkdir_p gemdir
+ FileUtils.chmod 0400, gemdir
+ Gem.use_paths gemdir
+
+ Gem.ensure_gem_subdirectories gemdir
+
+ refute File.exist?("#{gemdir}/cache")
+ ensure
+ FileUtils.chmod 0600, gemdir
+ end
+
+ def test_self_ensure_gem_directories_write_protected_parents
+ parent = File.join(@tempdir, "egd")
+ gemdir = "#{parent}/a/b/c"
+
+ FileUtils.rm_r parent rescue nil
+ refute File.exist?(parent), "manually remove #{parent}, tests are broken"
+ FileUtils.mkdir_p parent
+ FileUtils.chmod 0400, parent
+ Gem.use_paths(gemdir)
+
+ Gem.ensure_gem_subdirectories gemdir
+
+ refute File.exist?("#{gemdir}/cache")
+ ensure
+ FileUtils.chmod 0600, parent
+ end
+ end
+
+ def test_ensure_ssl_available
+ orig_Gem_ssl_available = Gem.ssl_available?
+
+ Gem.ssl_available = true
+ Gem.ensure_ssl_available
+
+ Gem.ssl_available = false
+ e = assert_raises Gem::Exception do Gem.ensure_ssl_available end
+ assert_equal 'SSL is not installed on this system', e.message
+ ensure
+ Gem.ssl_available = orig_Gem_ssl_available
+ end
+
+ def test_self_find_files
+ discover_path = File.join 'lib', 'foo', 'discover.rb'
+ cwd = File.expand_path '..', __FILE__
+ $LOAD_PATH.unshift cwd.dup
+
+ foo1 = quick_gem 'foo', '1' do |s|
+ s.files << discover_path
+ end
+
+ foo2 = quick_gem 'foo', '2' do |s|
+ s.files << discover_path
+ end
+
+ path = File.join 'gems', foo1.full_name, discover_path
+ write_file(path) { |fp| fp.puts "# #{path}" }
+
+ path = File.join 'gems', foo2.full_name, discover_path
+ write_file(path) { |fp| fp.puts "# #{path}" }
+
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ Gem.source_index = util_setup_spec_fetcher foo1, foo2
+
+ Gem.searcher = nil
+
+ expected = [
+ File.expand_path('../foo/discover.rb', __FILE__),
+ File.join(foo2.full_gem_path, discover_path),
+ File.join(foo1.full_gem_path, discover_path),
+ ]
+
+ assert_equal expected, Gem.find_files('foo/discover')
+ ensure
+ assert_equal cwd, $LOAD_PATH.shift
+ end
+
+ def test_self_latest_load_paths
+ util_make_gems
+
+ expected = [
+ File.join(@gemhome, *%W[gems #{@a3a.full_name} lib]),
+ File.join(@gemhome, *%W[gems #{@a_evil9.full_name} lib]),
+ File.join(@gemhome, *%W[gems #{@b2.full_name} lib]),
+ File.join(@gemhome, *%W[gems #{@c1_2.full_name} lib]),
+ File.join(@gemhome, *%W[gems #{@pl1.full_name} lib]),
+ ]
+
+ assert_equal expected, Gem.latest_load_paths.sort
+ end
+
+ def test_self_loaded_specs
+ foo = quick_gem 'foo'
+ install_gem foo
+ Gem.source_index = nil
+
+ Gem.activate 'foo'
+
+ assert_equal true, Gem.loaded_specs.keys.include?('foo')
+ end
+
+ def test_self_path
+ assert_equal [Gem.dir], Gem.path
+ end
+
+ def test_self_path_default
+ if defined? APPLE_GEM_HOME
+ orig_APPLE_GEM_HOME = APPLE_GEM_HOME
+ Object.send :remove_const, :APPLE_GEM_HOME
+ end
+ Gem.instance_variable_set :@gem_path, nil
+
+ assert_equal [Gem.default_path, Gem.dir].flatten, Gem.path
+ ensure
+ Object.const_set :APPLE_GEM_HOME, orig_APPLE_GEM_HOME
+ end
+
+ unless win_platform?
+ def test_self_path_APPLE_GEM_HOME
+ Gem.clear_paths
+ apple_gem_home = File.join @tempdir, 'apple_gem_home'
+ Gem.const_set :APPLE_GEM_HOME, apple_gem_home
+
+ assert_includes Gem.path, apple_gem_home
+ ensure
+ Gem.send :remove_const, :APPLE_GEM_HOME
+ end
+
+ def test_self_path_APPLE_GEM_HOME_GEM_PATH
+ Gem.clear_paths
+ ENV['GEM_PATH'] = @gemhome
+ apple_gem_home = File.join @tempdir, 'apple_gem_home'
+ Gem.const_set :APPLE_GEM_HOME, apple_gem_home
+
+ refute Gem.path.include?(apple_gem_home)
+ ensure
+ Gem.send :remove_const, :APPLE_GEM_HOME
+ end
+ end
+
+ def test_self_path_ENV_PATH
+ Gem.send :set_paths, nil
+ path_count = Gem.path.size
+ Gem.clear_paths
+
+ ENV['GEM_PATH'] = @additional.join(File::PATH_SEPARATOR)
+
+ assert_equal @additional, Gem.path[0,2]
+
+ assert_equal path_count + @additional.size, Gem.path.size,
+ "extra path components: #{Gem.path[2..-1].inspect}"
+ assert_equal Gem.dir, Gem.path.last
+ end
+
+ def test_self_path_duplicate
+ Gem.clear_paths
+ util_ensure_gem_dirs
+ dirs = @additional + [@gemhome] + [File.join(@tempdir, 'a')]
+
+ ENV['GEM_HOME'] = @gemhome
+ ENV['GEM_PATH'] = dirs.join File::PATH_SEPARATOR
+
+ assert_equal @gemhome, Gem.dir
+
+ paths = [Gem.dir]
+ assert_equal @additional + paths, Gem.path
+ end
+
+ def test_self_path_overlap
+ Gem.clear_paths
+
+ util_ensure_gem_dirs
+ ENV['GEM_HOME'] = @gemhome
+ ENV['GEM_PATH'] = @additional.join(File::PATH_SEPARATOR)
+
+ assert_equal @gemhome, Gem.dir
+
+ paths = [Gem.dir]
+ assert_equal @additional + paths, Gem.path
+ end
+
+ def test_self_platforms
+ assert_equal [Gem::Platform::RUBY, Gem::Platform.local], Gem.platforms
+ end
+
+ def test_self_prefix
+ file_name = File.expand_path __FILE__
+
+ prefix = File.dirname File.dirname(file_name)
+ prefix = File.dirname prefix if File.basename(prefix) == 'test'
+
+ assert_equal prefix, Gem.prefix
+ end
+
+ def test_self_prefix_libdir
+ orig_libdir = Gem::ConfigMap[:libdir]
+
+ file_name = File.expand_path __FILE__
+ prefix = File.dirname File.dirname(file_name)
+ prefix = File.dirname prefix if File.basename(prefix) == 'test'
+
+ Gem::ConfigMap[:libdir] = prefix
+
+ assert_nil Gem.prefix
+ ensure
+ Gem::ConfigMap[:libdir] = orig_libdir
+ end
+
+ def test_self_prefix_sitelibdir
+ orig_sitelibdir = Gem::ConfigMap[:sitelibdir]
+
+ file_name = File.expand_path __FILE__
+ prefix = File.dirname File.dirname(file_name)
+ prefix = File.dirname prefix if File.basename(prefix) == 'test'
+
+ Gem::ConfigMap[:sitelibdir] = prefix
+
+ assert_nil Gem.prefix
+ ensure
+ Gem::ConfigMap[:sitelibdir] = orig_sitelibdir
+ end
+
+ def test_self_refresh
+ util_make_gems
+
+ a1_spec = File.join @gemhome, "specifications", @a1.spec_name
+
+ FileUtils.mv a1_spec, @tempdir
+
+ refute Gem.source_index.gems.include?(@a1.full_name)
+
+ FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec
+
+ Gem.refresh
+
+ assert_includes Gem.source_index.gems, @a1.full_name
+ assert_equal nil, Gem.instance_variable_get(:@searcher)
+ end
+
+ def test_self_required_location
+ util_make_gems
+
+ assert_equal File.join(@tempdir, *%w[gemhome gems c-1.2 lib code.rb]),
+ Gem.required_location("c", "code.rb")
+ assert_equal File.join(@tempdir, *%w[gemhome gems a-1 lib code.rb]),
+ Gem.required_location("a", "code.rb", "< 2")
+ assert_equal File.join(@tempdir, *%w[gemhome gems a-2 lib code.rb]),
+ Gem.required_location("a", "code.rb", "= 2")
+ end
+
+ def test_self_ruby_escaping_spaces_in_path
+ orig_ruby = Gem.ruby
+ orig_bindir = Gem::ConfigMap[:bindir]
+ orig_ruby_install_name = Gem::ConfigMap[:ruby_install_name]
+ orig_exe_ext = Gem::ConfigMap[:EXEEXT]
+
+ Gem::ConfigMap[:bindir] = "C:/Ruby 1.8/bin"
+ Gem::ConfigMap[:ruby_install_name] = "ruby"
+ Gem::ConfigMap[:EXEEXT] = ".exe"
+ Gem.instance_variable_set("@ruby", nil)
+
+ assert_equal "\"C:/Ruby 1.8/bin/ruby.exe\"", Gem.ruby
+ ensure
+ Gem.instance_variable_set("@ruby", orig_ruby)
+ Gem::ConfigMap[:bindir] = orig_bindir
+ Gem::ConfigMap[:ruby_install_name] = orig_ruby_install_name
+ Gem::ConfigMap[:EXEEXT] = orig_exe_ext
+ end
+
+ def test_self_ruby_path_without_spaces
+ orig_ruby = Gem.ruby
+ orig_bindir = Gem::ConfigMap[:bindir]
+ orig_ruby_install_name = Gem::ConfigMap[:ruby_install_name]
+ orig_exe_ext = Gem::ConfigMap[:EXEEXT]
+
+ Gem::ConfigMap[:bindir] = "C:/Ruby18/bin"
+ Gem::ConfigMap[:ruby_install_name] = "ruby"
+ Gem::ConfigMap[:EXEEXT] = ".exe"
+ Gem.instance_variable_set("@ruby", nil)
+
+ assert_equal "C:/Ruby18/bin/ruby.exe", Gem.ruby
+ ensure
+ Gem.instance_variable_set("@ruby", orig_ruby)
+ Gem::ConfigMap[:bindir] = orig_bindir
+ Gem::ConfigMap[:ruby_install_name] = orig_ruby_install_name
+ Gem::ConfigMap[:EXEEXT] = orig_exe_ext
+ end
+
+ def test_self_ruby_version_1_8_5
+ util_set_RUBY_VERSION '1.8.5'
+
+ assert_equal Gem::Version.new('1.8.5'), Gem.ruby_version
+ ensure
+ util_restore_RUBY_VERSION
+ end
+
+ def test_self_ruby_version_1_8_6p287
+ util_set_RUBY_VERSION '1.8.6', 287
+
+ assert_equal Gem::Version.new('1.8.6.287'), Gem.ruby_version
+ ensure
+ util_restore_RUBY_VERSION
+ end
+
+ def test_self_ruby_version_1_9_2dev_r23493
+ util_set_RUBY_VERSION '1.9.2', -1, 23493
+
+ assert_equal Gem::Version.new('1.9.2.dev.23493'), Gem.ruby_version
+ ensure
+ util_restore_RUBY_VERSION
+ end
+
+ def test_self_searcher
+ assert_kind_of Gem::GemPathSearcher, Gem.searcher
+ end
+
+ def test_self_set_paths
+ other = File.join @tempdir, 'other'
+ path = [@userhome, other].join File::PATH_SEPARATOR
+ Gem.send :set_paths, path
+
+ assert_equal [@userhome, other, @gemhome], Gem.path
+ end
+
+ def test_self_set_paths_nonexistent_home
+ ENV['GEM_HOME'] = @gemhome
+ Gem.clear_paths
+
+ other = File.join @tempdir, 'other'
+
+ ENV['HOME'] = other
+
+ Gem.send :set_paths, other
+
+ assert_equal [other, @gemhome], Gem.path
+ end
+
+ def test_self_source_index
+ assert_kind_of Gem::SourceIndex, Gem.source_index
+ end
+
+ def test_self_sources
+ assert_equal %w[http://gems.example.com/], Gem.sources
+ end
+
+ def test_ssl_available_eh
+ orig_Gem_ssl_available = Gem.ssl_available?
+
+ Gem.ssl_available = true
+ assert_equal true, Gem.ssl_available?
+
+ Gem.ssl_available = false
+ assert_equal false, Gem.ssl_available?
+ ensure
+ Gem.ssl_available = orig_Gem_ssl_available
+ end
+
+ def test_self_use_paths
+ util_ensure_gem_dirs
+
+ Gem.use_paths @gemhome, @additional
+
+ assert_equal @gemhome, Gem.dir
+ assert_equal @additional + [Gem.dir], Gem.path
+ end
+
+ def test_self_user_dir
+ assert_equal File.join(@userhome, '.gem', Gem.ruby_engine,
+ Gem::ConfigMap[:ruby_version]), Gem.user_dir
+ end
+
+ def test_self_user_home
+ if ENV['HOME'] then
+ assert_equal ENV['HOME'], Gem.user_home
+ else
+ assert true, 'count this test'
+ end
+ end
+
+ def test_self_user_home_user_drive_and_path
+ Gem.clear_paths
+
+ # safe-keep env variables
+ orig_home, orig_user_profile = ENV['HOME'], ENV['USERPROFILE']
+ orig_user_drive, orig_user_path = ENV['HOMEDRIVE'], ENV['HOMEPATH']
+
+ # prepare the environment
+ ENV.delete('HOME')
+ ENV.delete('USERPROFILE')
+ ENV['HOMEDRIVE'] = 'Z:'
+ ENV['HOMEPATH'] = '\\Users\\RubyUser'
+
+ assert_equal "Z:\\Users\\RubyUser", Gem.user_home
+
+ ensure
+ ENV['HOME'] = orig_home
+ ENV['USERPROFILE'] = orig_user_profile
+ ENV['USERDRIVE'] = orig_user_drive
+ ENV['USERPATH'] = orig_user_path
+ end if '1.9' > RUBY_VERSION
+
+ def test_load_plugins
+ with_plugin('load') { Gem.load_plugins }
+ assert_equal :loaded, TEST_PLUGIN_LOAD
+
+ util_remove_interrupt_command
+
+ # Should attempt to cause a StandardError
+ with_plugin('standarderror') { Gem.load_plugins }
+ assert_equal :loaded, TEST_PLUGIN_STANDARDERROR
+
+ util_remove_interrupt_command
+
+ # Should attempt to cause an Exception
+ with_plugin('exception') { Gem.load_plugins }
+ assert_equal :loaded, TEST_PLUGIN_EXCEPTION
+ end
+
+ def with_plugin(path)
+ test_plugin_path = File.expand_path "../plugin/#{path}", __FILE__
+
+ # A single test plugin should get loaded once only, in order to preserve
+ # sane test semantics.
+ refute_includes $LOAD_PATH, test_plugin_path
+ $LOAD_PATH.unshift test_plugin_path
+
+ capture_io do
+ yield
+ end
+ ensure
+ $LOAD_PATH.delete test_plugin_path
+ end
+
+ def util_ensure_gem_dirs
+ Gem.ensure_gem_subdirectories @gemhome
+ @additional.each do |dir|
+ Gem.ensure_gem_subdirectories @gemhome
+ end
+ end
+
+ def util_exec_gem
+ spec, _ = quick_gem 'a', '4' do |s|
+ s.default_executable = 'exec'
+ s.executables = ['exec', 'abin']
+ end
+
+ @exec_path = File.join spec.full_gem_path, spec.bindir, 'exec'
+ @abin_path = File.join spec.full_gem_path, spec.bindir, 'abin'
+ end
+
+ def util_set_RUBY_VERSION(version, patchlevel = nil, revision = nil)
+ if Gem.instance_variables.include? :@ruby_version or
+ Gem.instance_variables.include? '@ruby_version' then
+ Gem.send :remove_instance_variable, :@ruby_version
+ end
+
+ @RUBY_VERSION = RUBY_VERSION
+ @RUBY_PATCHLEVEL = RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
+ @RUBY_REVISION = RUBY_REVISION if defined?(RUBY_REVISION)
+
+ Object.send :remove_const, :RUBY_VERSION
+ Object.send :remove_const, :RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
+ Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
+
+ Object.const_set :RUBY_VERSION, version
+ Object.const_set :RUBY_PATCHLEVEL, patchlevel if patchlevel
+ Object.const_set :RUBY_REVISION, revision if revision
+ end
+
+ def util_restore_RUBY_VERSION
+ Object.send :remove_const, :RUBY_VERSION
+ Object.send :remove_const, :RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
+ Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
+
+ Object.const_set :RUBY_VERSION, @RUBY_VERSION
+ Object.const_set :RUBY_PATCHLEVEL, @RUBY_PATCHLEVEL if
+ defined?(@RUBY_PATCHLEVEL)
+ Object.const_set :RUBY_REVISION, @RUBY_REVISION if
+ defined?(@RUBY_REVISION)
+ end
+
+ def util_remove_interrupt_command
+ Gem::Commands.send :remove_const, :InterruptCommand if
+ Gem::Commands.const_defined? :InterruptCommand
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_activation.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_activation.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_activation.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,21 @@
+require_relative '../ruby/envutil'
+require 'test/unit'
+
+class TestGemActivation < Test::Unit::TestCase
+ def test_activation
+ bug3140 = '[ruby-core:29486]'
+ src = %{begin
+ require 'rubygems-bug-parent'
+rescue Gem::LoadError
+ puts $!
+else
+ puts $bug_3140
+end}
+ basedir = File.expand_path("../gems/current", __FILE__)
+ env = {"HOME"=>basedir, "GEM_HOME"=>basedir, "GEM_PATH"=>basedir}
+ # WONTFIX in 1.9.2
+ #assert_in_out_err([env, "-rrubygems-bug-child", "-e", src], "",
+ # /can't activate rubygems-bug-child.*already activated rubygems-bug-child-1\.1/, [],
+ # bug3140)
+ end
+end if defined?(::Gem) and RUBY_VERSION < "1.9"
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_builder.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_builder.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_builder.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,27 @@
+require_relative 'gemutilities'
+require 'rubygems/builder'
+
+class TestGemBuilder < RubyGemTestCase
+
+ def test_build
+ builder = Gem::Builder.new quick_gem('a')
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ builder.build
+ end
+ end
+
+ assert_match %r|Successfully built RubyGem\n Name: a|, @ui.output
+ end
+
+ def test_build_validates
+ builder = Gem::Builder.new Gem::Specification.new
+
+ assert_raises Gem::InvalidSpecificationException do
+ builder.build
+ end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,178 @@
+require_relative 'gemutilities'
+require 'rubygems/command'
+
+class Gem::Command
+ public :parser
+end
+
+class TestGemCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @xopt = nil
+
+ Gem::Command.common_options.clear
+ Gem::Command.common_options << [
+ ['-x', '--exe', 'Execute'], lambda do |*a|
+ @xopt = true
+ end
+ ]
+
+ @cmd_name = 'doit'
+ @cmd = Gem::Command.new @cmd_name, 'summary'
+ end
+
+ def test_self_add_specific_extra_args
+ added_args = %w[--all]
+ @cmd.add_option '--all' do |v,o| end
+
+ Gem::Command.add_specific_extra_args @cmd_name, added_args
+
+ assert_equal added_args, Gem::Command.specific_extra_args(@cmd_name)
+
+ h = @cmd.add_extra_args []
+
+ assert_equal added_args, h
+ end
+
+ def test_self_add_specific_extra_args_unknown
+ added_args = %w[--definitely_not_there]
+
+ Gem::Command.add_specific_extra_args @cmd_name, added_args
+
+ assert_equal added_args, Gem::Command.specific_extra_args(@cmd_name)
+
+ h = @cmd.add_extra_args []
+
+ assert_equal [], h
+ end
+
+ def test_basic_accessors
+ assert_equal "doit", @cmd.command
+ assert_equal "gem doit", @cmd.program_name
+ assert_equal "summary", @cmd.summary
+ end
+
+ def test_common_option_in_class
+ assert Array === Gem::Command.common_options
+ end
+
+ def test_defaults
+ @cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options|
+ options[:help] = value
+ end
+
+ @cmd.defaults = { :help => true }
+
+ @cmd.when_invoked do |options|
+ assert options[:help], "Help options should default true"
+ end
+
+ use_ui @ui do
+ @cmd.invoke
+ end
+
+ assert_match %r|Usage: gem doit|, @ui.output
+ end
+
+ def test_invoke
+ done = false
+ @cmd.when_invoked { done = true }
+
+ use_ui @ui do
+ @cmd.invoke
+ end
+
+ assert done
+ end
+
+ def test_invode_with_bad_options
+ use_ui @ui do
+ @cmd.when_invoked do true end
+
+ ex = assert_raises OptionParser::InvalidOption do
+ @cmd.invoke('-zzz')
+ end
+
+ assert_match(/invalid option:/, ex.message)
+ end
+ end
+
+ def test_invoke_with_common_options
+ @cmd.when_invoked do true end
+
+ use_ui @ui do
+ @cmd.invoke "-x"
+ end
+
+ assert @xopt, "Should have done xopt"
+ end
+
+ # Returning false from the command handler invokes the usage output.
+ def test_invoke_with_help
+ done = false
+
+ use_ui @ui do
+ @cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options|
+ options[:help] = true
+ done = true
+ end
+
+ @cmd.invoke('--help')
+
+ assert done
+ end
+
+ assert_match(/Usage/, @ui.output)
+ assert_match(/gem doit/, @ui.output)
+ assert_match(/\[options\]/, @ui.output)
+ assert_match(/-h/, @ui.output)
+ assert_match(/--help \[COMMAND\]/, @ui.output)
+ assert_match(/Get help on COMMAND/, @ui.output)
+ assert_match(/-x/, @ui.output)
+ assert_match(/--exe/, @ui.output)
+ assert_match(/Execute/, @ui.output)
+ assert_match(/Common Options:/, @ui.output)
+ end
+
+ def test_invoke_with_options
+ @cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options|
+ options[:help] = true
+ end
+
+ @cmd.when_invoked do |opts|
+ assert opts[:help]
+ end
+
+ use_ui @ui do
+ @cmd.invoke '-h'
+ end
+
+ assert_match %r|Usage: gem doit|, @ui.output
+ end
+
+ def test_option_recognition
+ @cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options|
+ options[:help] = true
+ end
+ @cmd.add_option('-f', '--file FILE', 'File option') do |value, options|
+ options[:help] = true
+ end
+ assert @cmd.handles?(['-x'])
+ assert @cmd.handles?(['-h'])
+ assert @cmd.handles?(['-h', 'command'])
+ assert @cmd.handles?(['--help', 'command'])
+ assert @cmd.handles?(['-f', 'filename'])
+ assert @cmd.handles?(['--file=filename'])
+ refute @cmd.handles?(['-z'])
+ refute @cmd.handles?(['-f'])
+ refute @cmd.handles?(['--toothpaste'])
+
+ args = ['-h', 'command']
+ @cmd.handles?(args)
+ assert_equal ['-h', 'command'], args
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_command_manager.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_command_manager.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_command_manager.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,205 @@
+require_relative 'gemutilities'
+require 'rubygems/command_manager'
+
+class TestGemCommandManager < RubyGemTestCase
+
+ def setup
+ super
+
+ @command_manager = Gem::CommandManager.instance
+ end
+
+ def test_run_interrupt
+ Gem.load_plugins
+
+ use_ui @ui do
+ assert_raises MockGemUi::TermError do
+ @command_manager.run 'interrupt'
+ end
+ assert_equal '', ui.output
+ assert_equal "ERROR: Interrupted\n", ui.error
+ end
+ end
+
+ def test_run_crash_command
+ @command_manager.register_command :crash
+ use_ui @ui do
+ assert_raises MockGemUi::TermError do
+ @command_manager.run 'crash'
+ end
+ assert_equal '', ui.output
+ err = ui.error.split("\n").first
+ assert_equal "ERROR: Loading command: crash (RuntimeError)", err
+ end
+ end
+
+ def test_process_args_bad_arg
+ use_ui @ui do
+ assert_raises(MockGemUi::TermError) {
+ @command_manager.process_args("--bad-arg")
+ }
+ end
+
+ assert_match(/invalid option: --bad-arg/i, @ui.error)
+ end
+
+ def test_process_args_install
+ #capture all install options
+ use_ui @ui do
+ check_options = nil
+ @command_manager['install'].when_invoked do |options|
+ check_options = options
+ true
+ end
+
+ #check defaults
+ @command_manager.process_args("install")
+ assert_equal false, check_options[:test]
+ assert_equal true, check_options[:generate_rdoc]
+ assert_equal false, check_options[:force]
+ assert_equal :both, check_options[:domain]
+ assert_equal true, check_options[:wrappers]
+ assert_equal Gem::Requirement.default, check_options[:version]
+ assert_equal nil, check_options[:install_dir]
+ assert_equal nil, check_options[:bin_dir]
+
+ #check settings
+ check_options = nil
+ @command_manager.process_args(
+ "install --force --test --local --rdoc --install-dir . --version 3.0 --no-wrapper --bindir . ")
+ assert_equal true, check_options[:generate_rdoc]
+ assert_equal true, check_options[:force]
+ assert_equal :local, check_options[:domain]
+ assert_equal false, check_options[:wrappers]
+ assert_equal Gem::Requirement.new('3.0'), check_options[:version]
+ assert_equal Dir.pwd, check_options[:install_dir]
+ assert_equal Dir.pwd, check_options[:bin_dir]
+
+ #check remote domain
+ check_options = nil
+ @command_manager.process_args("install --remote")
+ assert_equal :remote, check_options[:domain]
+
+ #check both domain
+ check_options = nil
+ @command_manager.process_args("install --both")
+ assert_equal :both, check_options[:domain]
+
+ #check both domain
+ check_options = nil
+ @command_manager.process_args("install --both")
+ assert_equal :both, check_options[:domain]
+ end
+ end
+
+ def test_process_args_uninstall
+ #capture all uninstall options
+ check_options = nil
+ @command_manager['uninstall'].when_invoked do |options|
+ check_options = options
+ true
+ end
+
+ #check defaults
+ @command_manager.process_args("uninstall")
+ assert_equal Gem::Requirement.default, check_options[:version]
+
+ #check settings
+ check_options = nil
+ @command_manager.process_args("uninstall foobar --version 3.0")
+ assert_equal "foobar", check_options[:args].first
+ assert_equal Gem::Requirement.new('3.0'), check_options[:version]
+ end
+
+ def test_process_args_check
+ #capture all check options
+ check_options = nil
+ @command_manager['check'].when_invoked do |options|
+ check_options = options
+ true
+ end
+
+ #check defaults
+ @command_manager.process_args("check")
+ assert_equal false, check_options[:verify]
+ assert_equal false, check_options[:alien]
+
+ #check settings
+ check_options = nil
+ @command_manager.process_args("check --verify foobar --alien")
+ assert_equal "foobar", check_options[:verify]
+ assert_equal true, check_options[:alien]
+ end
+
+ def test_process_args_build
+ #capture all build options
+ check_options = nil
+ @command_manager['build'].when_invoked do |options|
+ check_options = options
+ true
+ end
+
+ #check defaults
+ @command_manager.process_args("build")
+ #NOTE: Currently no defaults
+
+ #check settings
+ check_options = nil
+ @command_manager.process_args("build foobar.rb")
+ assert_equal 'foobar.rb', check_options[:args].first
+ end
+
+ def test_process_args_query
+ #capture all query options
+ check_options = nil
+ @command_manager['query'].when_invoked do |options|
+ check_options = options
+ true
+ end
+
+ #check defaults
+ @command_manager.process_args("query")
+ assert_equal(//, check_options[:name])
+ assert_equal :local, check_options[:domain]
+ assert_equal false, check_options[:details]
+
+ #check settings
+ check_options = nil
+ @command_manager.process_args("query --name foobar --local --details")
+ assert_equal(/foobar/i, check_options[:name])
+ assert_equal :local, check_options[:domain]
+ assert_equal true, check_options[:details]
+
+ #remote domain
+ check_options = nil
+ @command_manager.process_args("query --remote")
+ assert_equal :remote, check_options[:domain]
+
+ #both (local/remote) domains
+ check_options = nil
+ @command_manager.process_args("query --both")
+ assert_equal :both, check_options[:domain]
+ end
+
+ def test_process_args_update
+ #capture all update options
+ check_options = nil
+ @command_manager['update'].when_invoked do |options|
+ check_options = options
+ true
+ end
+
+ #check defaults
+ @command_manager.process_args("update")
+ assert_equal true, check_options[:generate_rdoc]
+
+ #check settings
+ check_options = nil
+ @command_manager.process_args("update --force --test --rdoc --install-dir .")
+ assert_equal true, check_options[:generate_rdoc]
+ assert_equal true, check_options[:force]
+ assert_equal Dir.pwd, check_options[:install_dir]
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_build_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_build_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_build_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,74 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/build_command'
+require 'rubygems/format'
+
+class TestGemCommandsBuildCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @gem = quick_gem 'some_gem' do |s|
+ s.rubyforge_project = 'example'
+ end
+
+ @cmd = Gem::Commands::BuildCommand.new
+ end
+
+ def test_execute
+ gemspec_file = File.join(@tempdir, @gem.spec_name)
+
+ File.open gemspec_file, 'w' do |gs|
+ gs.write @gem.to_ruby
+ end
+
+ util_test_build_gem @gem, gemspec_file
+ end
+
+ def test_execute_yaml
+ gemspec_file = File.join(@tempdir, @gem.spec_name)
+
+ File.open gemspec_file, 'w' do |gs|
+ gs.write @gem.to_yaml
+ end
+
+ util_test_build_gem @gem, gemspec_file
+ end
+
+ def test_execute_bad_gem
+ @cmd.options[:args] = %w[some_gem]
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal '', @ui.output
+ assert_equal "ERROR: Gemspec file not found: some_gem\n", @ui.error
+ end
+
+ def util_test_build_gem(gem, gemspec_file)
+ @cmd.options[:args] = [gemspec_file]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ output = @ui.output.split "\n"
+ assert_equal " Successfully built RubyGem", output.shift
+ assert_equal " Name: some_gem", output.shift
+ assert_equal " Version: 2", output.shift
+ assert_equal " File: some_gem-2.gem", output.shift
+ assert_equal [], output
+ assert_equal '', @ui.error
+
+ gem_file = File.join @tempdir, gem.file_name
+ assert File.exist?(gem_file)
+
+ spec = Gem::Format.from_file_by_path(gem_file).spec
+
+ assert_equal "some_gem", spec.name
+ assert_equal "this is a summary", spec.summary
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_cert_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_cert_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_cert_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,125 @@
+require_relative 'gemutilities'
+
+require 'rubygems/commands/cert_command'
+
+unless defined? OpenSSL then
+ warn "`gem cert` tests are being skipped, module OpenSSL not found"
+end
+
+class TestGemCommandsCertCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @orig_security_trust_dir = Gem::Security::OPT[:trust_dir]
+ Gem::Security::OPT[:trust_dir] = @tempdir
+
+ @cmd = Gem::Commands::CertCommand.new
+
+ root = File.expand_path(File.dirname(__FILE__))
+
+ FileUtils.cp File.join(root, 'data', 'gem-private_key.pem'), @tempdir
+ FileUtils.cp File.join(root, 'data', 'gem-public_cert.pem'), @tempdir
+
+ @cert_file_name = File.join @tempdir, 'gem-public_cert.pem'
+ @pkey_file_name = File.join @tempdir, 'gem-private_key.pem'
+ end
+
+ def teardown
+ Gem::Security::OPT[:trust_dir] = @orig_security_trust_dir
+
+ super
+ end
+
+ def test_execute_add
+ use_ui @ui do
+ @cmd.send :handle_options, %W[--add #{@cert_file_name}]
+ end
+
+ assert_equal "Added '/CN=rubygems/DC=example/DC=com'\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_build
+ FileUtils.rm @cert_file_name
+ FileUtils.rm @pkey_file_name
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.send :handle_options, %W[--build nobody at example.com]
+ end
+ end
+
+ output = @ui.output.split "\n"
+
+ assert_equal 'Public Cert: gem-public_cert.pem', output.shift
+ assert_equal 'Private Key: gem-private_key.pem', output.shift
+ assert_equal 'Don\'t forget to move the key file to somewhere private...',
+ output.shift
+ assert_equal [], output
+
+ assert_equal '', @ui.error
+
+ assert File.exist?(File.join(@tempdir, 'gem-private_key.pem'))
+ assert File.exist?(File.join(@tempdir, 'gem-public_cert.pem'))
+ end
+
+ def test_execute_certificate
+ use_ui @ui do
+ @cmd.send :handle_options, %W[--certificate #{@cert_file_name}]
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+
+ assert_equal File.read(@cert_file_name),
+ Gem::Security::OPT[:issuer_cert].to_s
+ end
+
+ def test_execute_list
+ use_ui @ui do
+ @cmd.send :handle_options, %W[--list]
+ end
+
+ assert_equal "/CN=rubygems/DC=example/DC=com\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_private_key
+ use_ui @ui do
+ @cmd.send :handle_options, %W[--private-key #{@pkey_file_name}]
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+
+ assert_equal File.read(@pkey_file_name),
+ Gem::Security::OPT[:issuer_key].to_s
+ end
+
+ def test_execute_remove
+ use_ui @ui do
+ @cmd.send :handle_options, %W[--remove rubygems]
+ end
+
+ assert_equal "Removed '/CN=rubygems/DC=example/DC=com'\n", @ui.output
+ assert_equal '', @ui.error
+
+ refute File.exist?(@cert_file_name)
+ end
+
+ def test_execute_sign
+ use_ui @ui do
+ @cmd.send :handle_options, %W[
+ -K #{@pkey_file_name} -C #{@cert_file_name} --sign #{@cert_file_name}
+ ]
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+
+ # HACK this test sucks
+ end
+
+end if defined? OpenSSL
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_check_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_check_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_check_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,18 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/check_command'
+
+class TestGemCommandsCheckCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::CheckCommand.new
+ end
+
+ def test_initialize
+ assert_equal "check", @cmd.command
+ assert_equal "gem check", @cmd.program_name
+ assert_match(/Check/, @cmd.summary)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_contents_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_contents_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_contents_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,156 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/contents_command'
+
+class TestGemCommandsContentsCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::ContentsCommand.new
+ end
+
+ def test_execute
+ @cmd.options[:args] = %w[foo]
+ quick_gem 'foo' do |gem|
+ gem.files = %w[lib/foo.rb Rakefile]
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|lib/foo\.rb|, @ui.output
+ assert_match %r|Rakefile|, @ui.output
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_all
+ @cmd.options[:all] = true
+
+ quick_gem 'foo' do |gem|
+ gem.files = %w[lib/foo.rb Rakefile]
+ end
+
+ quick_gem 'bar' do |gem|
+ gem.files = %w[lib/bar.rb Rakefile]
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|lib/foo\.rb|, @ui.output
+ assert_match %r|lib/bar\.rb|, @ui.output
+ assert_match %r|Rakefile|, @ui.output
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_bad_gem
+ @cmd.options[:args] = %w[foo]
+
+ assert_raises MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_match %r|Unable to find gem 'foo' in default gem paths|, @ui.output
+ assert_match %r|Directories searched:|, @ui.output
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_exact_match
+ @cmd.options[:args] = %w[foo]
+ quick_gem 'foo' do |gem|
+ gem.files = %w[lib/foo.rb Rakefile]
+ end
+
+ quick_gem 'foo_bar' do |gem|
+ gem.files = %w[lib/foo_bar.rb Rakefile]
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|lib/foo\.rb|, @ui.output
+ assert_match %r|Rakefile|, @ui.output
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_lib_only
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:lib_only] = true
+
+ quick_gem 'foo' do |gem|
+ gem.files = %w[lib/foo.rb Rakefile]
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|lib/foo\.rb|, @ui.output
+ refute_match %r|Rakefile|, @ui.output
+
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_multiple
+ @cmd.options[:args] = %w[foo bar]
+ quick_gem 'foo' do |gem|
+ gem.files = %w[lib/foo.rb Rakefile]
+ end
+
+ quick_gem 'bar' do |gem|
+ gem.files = %w[lib/bar.rb Rakefile]
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|lib/foo\.rb|, @ui.output
+ assert_match %r|lib/bar\.rb|, @ui.output
+ assert_match %r|Rakefile|, @ui.output
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_no_prefix
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:prefix] = false
+
+ quick_gem 'foo' do |gem|
+ gem.files = %w[lib/foo.rb Rakefile]
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+lib/foo.rb
+Rakefile
+ EOF
+
+ assert_equal expected, @ui.output
+
+ assert_equal "", @ui.error
+ end
+
+ def test_handle_options
+ refute @cmd.options[:lib_only]
+ assert @cmd.options[:prefix]
+ assert_empty @cmd.options[:specdirs]
+ assert_nil @cmd.options[:version]
+
+ @cmd.send :handle_options, %w[-l -s foo --version 0.0.2 --no-prefix]
+
+ assert @cmd.options[:lib_only]
+ refute @cmd.options[:prefix]
+ assert_equal %w[foo], @cmd.options[:specdirs]
+ assert_equal Gem::Requirement.new('0.0.2'), @cmd.options[:version]
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_dependency_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_dependency_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_dependency_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,216 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/dependency_command'
+
+class TestGemCommandsDependencyCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::DependencyCommand.new
+ @cmd.options[:domain] = :local
+
+ util_setup_fake_fetcher true
+ end
+
+ def test_execute
+ quick_gem 'foo' do |gem|
+ gem.add_dependency 'bar', '> 1'
+ gem.add_dependency 'baz', '> 1'
+ end
+
+ Gem.source_index = nil
+
+ @cmd.options[:args] = %w[foo]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "Gem foo-2\n bar (> 1, runtime)\n baz (> 1, runtime)\n\n",
+ @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_no_args
+ Gem.source_index = nil
+
+ @cmd.options[:args] = []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+Gem a-1
+
+Gem a-2.a
+
+Gem a-2
+
+Gem a-3.a
+
+Gem a_evil-9
+
+Gem b-2
+
+Gem c-1.2
+
+Gem pl-1-x86-linux
+
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_no_match
+ @cmd.options[:args] = %w[foo]
+
+ assert_raises MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "No gems found matching foo (>= 0)\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_pipe_format
+ quick_gem 'foo' do |gem|
+ gem.add_dependency 'bar', '> 1'
+ end
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:pipe_format] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "bar --version '> 1'\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_regexp
+ Gem.source_index = nil
+
+ @cmd.options[:args] = %w[/[ab]/]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+Gem a-1
+
+Gem a-2.a
+
+Gem a-2
+
+Gem a-3.a
+
+Gem a_evil-9
+
+Gem b-2
+
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_reverse
+ quick_gem 'foo' do |gem|
+ gem.add_dependency 'bar', '> 1'
+ end
+
+ quick_gem 'baz' do |gem|
+ gem.add_dependency 'foo'
+ end
+
+ Gem.source_index = nil
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:reverse_dependencies] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+Gem foo-2
+ bar (> 1, runtime)
+ Used by
+ baz-2 (foo (>= 0, runtime))
+
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_reverse_remote
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:reverse_dependencies] = true
+ @cmd.options[:domain] = :remote
+
+ assert_raises MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ expected = <<-EOF
+ERROR: Only reverse dependencies for local gems are supported.
+ EOF
+
+ assert_equal '', @ui.output
+ assert_equal expected, @ui.error
+ end
+
+ def test_execute_remote
+ foo = quick_gem 'foo' do |gem|
+ gem.add_dependency 'bar', '> 1'
+ end
+
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ util_setup_spec_fetcher foo
+
+ FileUtils.rm File.join(@gemhome, 'specifications', foo.spec_name)
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:domain] = :remote
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "Gem foo-2\n bar (> 1, runtime)\n\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_prerelease
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ util_setup_spec_fetcher @a2_pre
+
+ FileUtils.rm File.join(@gemhome, 'specifications', @a2_pre.spec_name)
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:domain] = :remote
+ @cmd.options[:prerelease] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "Gem a-2.a\n\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_environment_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_environment_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_environment_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,135 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/environment_command'
+
+class TestGemCommandsEnvironmentCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::EnvironmentCommand.new
+ end
+
+ def test_execute
+ orig_sources = Gem.sources.dup
+ Gem.sources.replace %w[http://gems.example.com]
+ Gem.configuration['gemcutter_key'] = 'blah'
+
+ @cmd.send :handle_options, %w[]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|RUBYGEMS VERSION: (\d\.)+\d|, @ui.output
+ assert_match %r|RUBY VERSION: \d\.\d\.\d \(.*\) \[.*\]|, @ui.output
+ assert_match %r|INSTALLATION DIRECTORY: #{Regexp.escape @gemhome}|,
+ @ui.output
+ assert_match %r|RUBYGEMS PREFIX: |, @ui.output
+ assert_match %r|RUBY EXECUTABLE:.*#{Gem::ConfigMap[:ruby_install_name]}|,
+ @ui.output
+ assert_match %r|EXECUTABLE DIRECTORY:|, @ui.output
+ assert_match %r|RUBYGEMS PLATFORMS:|, @ui.output
+ assert_match %r|- #{Gem::Platform.local}|, @ui.output
+ assert_match %r|GEM PATHS:|, @ui.output
+ assert_match %r|- #{Regexp.escape @gemhome}|, @ui.output
+ assert_match %r|GEM CONFIGURATION:|, @ui.output
+ assert_match %r|"gemcutter_key" => "\*\*\*\*"|, @ui.output
+ assert_match %r|:verbose => |, @ui.output
+ assert_match %r|REMOTE SOURCES:|, @ui.output
+ assert_equal '', @ui.error
+
+ ensure
+ Gem.sources.replace orig_sources
+ end
+
+ def test_execute_gemdir
+ @cmd.send :handle_options, %w[gemdir]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{@gemhome}\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_gempath
+ @cmd.send :handle_options, %w[gempath]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{@gemhome}\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_gempath_multiple
+ Gem.clear_paths
+ path = [@gemhome, "#{@gemhome}2"].join File::PATH_SEPARATOR
+ ENV['GEM_PATH'] = path
+
+ @cmd.send :handle_options, %w[gempath]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{Gem.path.join File::PATH_SEPARATOR}\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_packageversion
+ @cmd.send :handle_options, %w[packageversion]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{Gem::RubyGemsPackageVersion}\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_remotesources
+ orig_sources = Gem.sources.dup
+ Gem.sources.replace %w[http://gems.example.com]
+
+ @cmd.send :handle_options, %w[remotesources]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "http://gems.example.com\n", @ui.output
+ assert_equal '', @ui.error
+
+ ensure
+ Gem.sources.replace orig_sources
+ end
+
+ def test_execute_unknown
+ @cmd.send :handle_options, %w[unknown]
+
+ assert_raises Gem::CommandLineError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_version
+ @cmd.send :handle_options, %w[version]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{Gem::VERSION}\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_fetch_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_fetch_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_fetch_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,76 @@
+require_relative 'gemutilities'
+require 'rubygems/package'
+require 'rubygems/security'
+require 'rubygems/commands/fetch_command'
+
+class TestGemCommandsFetchCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::FetchCommand.new
+ end
+
+ def test_execute
+ util_setup_fake_fetcher
+ util_setup_spec_fetcher @a2
+
+ @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
+ File.read(File.join(@gemhome, 'cache', @a2.file_name))
+
+ @cmd.options[:args] = [@a2.name]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, @a2.file_name)),
+ "#{@a2.full_name} not fetched"
+ end
+
+ def test_execute_prerelease
+ util_setup_fake_fetcher true
+ util_setup_spec_fetcher @a2, @a2_pre
+
+ @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
+ File.read(File.join(@gemhome, 'cache', @a2.file_name))
+ @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] =
+ File.read(File.join(@gemhome, 'cache', @a2_pre.file_name))
+
+ @cmd.options[:args] = [@a2.name]
+ @cmd.options[:prerelease] = true
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, @a2_pre.file_name)),
+ "#{@a2_pre.full_name} not fetched"
+ end
+
+ def test_execute_version
+ util_setup_fake_fetcher
+ util_setup_spec_fetcher @a1, @a2
+
+ @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] =
+ File.read(File.join(@gemhome, 'cache', @a1.file_name))
+
+ @cmd.options[:args] = [@a2.name]
+ @cmd.options[:version] = Gem::Requirement.new '1'
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, @a1.file_name)),
+ "#{@a1.full_name} not fetched"
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_generate_index_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_generate_index_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_generate_index_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,135 @@
+require_relative 'gemutilities'
+require 'rubygems/indexer'
+require 'rubygems/commands/generate_index_command'
+
+class TestGemCommandsGenerateIndexCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::GenerateIndexCommand.new
+ @cmd.options[:directory] = @gemhome
+ end
+
+ def test_execute
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ yaml = File.join @gemhome, 'yaml'
+ yaml_z = File.join @gemhome, 'yaml.Z'
+ quick_index = File.join @gemhome, 'quick', 'index'
+ quick_index_rz = File.join @gemhome, 'quick', 'index.rz'
+
+ assert File.exist?(yaml), yaml
+ assert File.exist?(yaml_z), yaml_z
+ assert File.exist?(quick_index), quick_index
+ assert File.exist?(quick_index_rz), quick_index_rz
+ end
+
+ def test_execute_rss_update
+ @cmd.options[:update] = true
+ @cmd.options[:rss_host] = 'example.com'
+ @cmd.options[:rss_gems_host] = 'gems.example.com'
+
+ use_ui @ui do
+ assert_raises MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "ERROR: --update not compatible with RSS generation\n",
+ @ui.error
+ assert_empty @ui.output
+ end
+
+ def test_handle_options_directory
+ return if win_platform?
+ refute_equal '/nonexistent', @cmd.options[:directory]
+
+ @cmd.handle_options %w[--directory /nonexistent]
+
+ assert_equal '/nonexistent', @cmd.options[:directory]
+ end
+
+ def test_handle_options_directory_windows
+ return unless win_platform?
+
+ refute_equal '/nonexistent', @cmd.options[:directory]
+
+ @cmd.handle_options %w[--directory C:/nonexistent]
+
+ assert_equal 'C:/nonexistent', @cmd.options[:directory]
+ end
+
+ def test_handle_options_invalid
+ e = assert_raises OptionParser::InvalidOption do
+ @cmd.handle_options %w[--no-modern --no-legacy]
+ end
+
+ assert_equal 'invalid option: --no-legacy no indicies will be built',
+ e.message
+
+ @cmd = Gem::Commands::GenerateIndexCommand.new
+ e = assert_raises OptionParser::InvalidOption do
+ @cmd.handle_options %w[--no-legacy --no-modern]
+ end
+
+ assert_equal 'invalid option: --no-modern no indicies will be built',
+ e.message
+ end
+
+ def test_handle_options_legacy
+ @cmd.handle_options %w[--legacy]
+
+ assert @cmd.options[:build_legacy]
+ assert @cmd.options[:build_modern], ':build_modern not set'
+ end
+
+ def test_handle_options_modern
+ @cmd.handle_options %w[--modern]
+
+ assert @cmd.options[:build_legacy]
+ assert @cmd.options[:build_modern], ':build_modern not set'
+ end
+
+ def test_handle_options_no_legacy
+ @cmd.handle_options %w[--no-legacy]
+
+ refute @cmd.options[:build_legacy]
+ assert @cmd.options[:build_modern]
+ end
+
+ def test_handle_options_no_modern
+ @cmd.handle_options %w[--no-modern]
+
+ assert @cmd.options[:build_legacy]
+ refute @cmd.options[:build_modern]
+ end
+
+ def test_handle_options_rss_gems_host
+ @cmd.handle_options %w[--rss-gems-host gems.example.com]
+
+ assert_equal 'gems.example.com', @cmd.options[:rss_gems_host]
+ end
+
+ def test_handle_options_rss_host
+ @cmd.handle_options %w[--rss-host example.com]
+
+ assert_equal 'example.com', @cmd.options[:rss_host]
+ end
+
+ def test_handle_options_rss_title
+ @cmd.handle_options %w[--rss-title Example\ Gems]
+
+ assert_equal 'Example Gems', @cmd.options[:rss_title]
+ end
+
+ def test_handle_options_update
+ @cmd.handle_options %w[--update]
+
+ assert @cmd.options[:update]
+ end
+
+end if ''.respond_to? :to_xs
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_install_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_install_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_install_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,262 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/install_command'
+
+class TestGemCommandsInstallCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::InstallCommand.new
+ @cmd.options[:generate_rdoc] = false
+ @cmd.options[:generate_ri] = false
+ end
+
+ def test_execute_exclude_prerelease
+ util_setup_fake_fetcher(:prerelease)
+ util_setup_spec_fetcher @a2, @a2_pre
+
+ @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
+ read_binary(File.join(@gemhome, 'cache', @a2.file_name))
+ @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] =
+ read_binary(File.join(@gemhome, 'cache', @a2_pre.file_name))
+
+ @cmd.options[:args] = [@a2.name]
+
+ use_ui @ui do
+ e = assert_raises Gem::SystemExitException do
+ @cmd.execute
+ end
+ assert_equal 0, e.exit_code, @ui.error
+ end
+
+ assert_match(/Successfully installed #{@a2.full_name}$/, @ui.output)
+ refute_match(/Successfully installed #{@a2_pre.full_name}$/, @ui.output)
+ end
+
+ def test_execute_explicit_version_includes_prerelease
+ util_setup_fake_fetcher(:prerelease)
+ util_setup_spec_fetcher @a2, @a2_pre
+
+ @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
+ read_binary(File.join(@gemhome, 'cache', @a2.file_name))
+ @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] =
+ read_binary(File.join(@gemhome, 'cache', @a2_pre.file_name))
+
+ @cmd.handle_options [@a2_pre.name, '--version', @a2_pre.version.to_s]
+ assert @cmd.options[:prerelease]
+ assert @cmd.options[:version].satisfied_by?(@a2_pre.version)
+
+ use_ui @ui do
+ e = assert_raises Gem::SystemExitException do
+ @cmd.execute
+ end
+ assert_equal 0, e.exit_code, @ui.error
+ end
+
+ refute_match(/Successfully installed #{@a2.full_name}$/, @ui.output)
+ assert_match(/Successfully installed #{@a2_pre.full_name}$/, @ui.output)
+ end
+
+ def test_execute_include_dependencies
+ @cmd.options[:include_dependencies] = true
+ @cmd.options[:args] = []
+
+ assert_raises Gem::CommandLineError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ output = @ui.output.split "\n"
+ assert_equal "INFO: `gem install -y` is now default and will be removed",
+ output.shift
+ assert_equal "INFO: use --ignore-dependencies to install only the gems you list",
+ output.shift
+ assert output.empty?, output.inspect
+ end
+
+ def test_execute_local
+ util_setup_fake_fetcher
+ @cmd.options[:domain] = :local
+
+ FileUtils.mv File.join(@gemhome, 'cache', @a2.file_name),
+ File.join(@tempdir)
+
+ @cmd.options[:args] = [@a2.name]
+
+ use_ui @ui do
+ orig_dir = Dir.pwd
+ begin
+ Dir.chdir @tempdir
+ e = assert_raises Gem::SystemExitException do
+ @cmd.execute
+ end
+ assert_equal 0, e.exit_code
+ ensure
+ Dir.chdir orig_dir
+ end
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Successfully installed #{@a2.full_name}", out.shift
+ assert_equal "1 gem installed", out.shift
+ assert out.empty?, out.inspect
+ end
+
+ def test_no_user_install
+ skip 'skipped on MS Windows (chmod has no effect)' if win_platform?
+
+ util_setup_fake_fetcher
+ @cmd.options[:user_install] = false
+
+ FileUtils.mv File.join(@gemhome, 'cache', @a2.file_name),
+ File.join(@tempdir)
+
+ @cmd.options[:args] = [@a2.name]
+
+ use_ui @ui do
+ orig_dir = Dir.pwd
+ begin
+ File.chmod 0755, @userhome
+ File.chmod 0555, @gemhome
+
+ Dir.chdir @tempdir
+ assert_raises Gem::FilePermissionError do
+ @cmd.execute
+ end
+ ensure
+ Dir.chdir orig_dir
+ File.chmod 0755, @gemhome
+ end
+ end
+ end
+
+ def test_execute_local_missing
+ util_setup_fake_fetcher
+ @cmd.options[:domain] = :local
+
+ @cmd.options[:args] = %w[no_such_gem]
+
+ use_ui @ui do
+ e = assert_raises Gem::SystemExitException do
+ @cmd.execute
+ end
+ assert_equal 2, e.exit_code
+ end
+
+ # HACK no repository was checked
+ assert_match(/ould not find a valid gem 'no_such_gem'/, @ui.error)
+ end
+
+ def test_execute_no_gem
+ @cmd.options[:args] = %w[]
+
+ assert_raises Gem::CommandLineError do
+ @cmd.execute
+ end
+ end
+
+ def test_execute_nonexistent
+ util_setup_fake_fetcher
+ util_setup_spec_fetcher
+
+ @cmd.options[:args] = %w[nonexistent]
+
+ use_ui @ui do
+ e = assert_raises Gem::SystemExitException do
+ @cmd.execute
+ end
+ assert_equal 2, e.exit_code
+ end
+
+ assert_match(/ould not find a valid gem 'nonexistent'/, @ui.error)
+ end
+
+ def test_execute_prerelease
+ util_setup_fake_fetcher(:prerelease)
+ util_setup_spec_fetcher @a2, @a2_pre
+
+ @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
+ read_binary(File.join(@gemhome, 'cache', @a2.file_name))
+ @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] =
+ read_binary(File.join(@gemhome, 'cache', @a2_pre.file_name))
+
+ @cmd.options[:prerelease] = true
+ @cmd.options[:args] = [@a2_pre.name]
+
+ use_ui @ui do
+ e = assert_raises Gem::SystemExitException do
+ @cmd.execute
+ end
+ assert_equal 0, e.exit_code, @ui.error
+ end
+
+ refute_match(/Successfully installed #{@a2.full_name}$/, @ui.output)
+ assert_match(/Successfully installed #{@a2_pre.full_name}$/, @ui.output)
+ end
+
+ def test_execute_remote
+ @cmd.options[:generate_rdoc] = true
+ @cmd.options[:generate_ri] = true
+
+ util_setup_fake_fetcher
+ util_setup_spec_fetcher @a2
+
+ @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
+ read_binary(File.join(@gemhome, 'cache', @a2.file_name))
+
+ @cmd.options[:args] = [@a2.name]
+
+ use_ui @ui do
+ e = assert_raises Gem::SystemExitException do
+ capture_io do
+ @cmd.execute
+ end
+ end
+ assert_equal 0, e.exit_code
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Successfully installed #{@a2.full_name}", out.shift
+ assert_equal "1 gem installed", out.shift
+ assert_equal "Installing ri documentation for #{@a2.full_name}...",
+ out.shift
+ assert_equal "Installing RDoc documentation for #{@a2.full_name}...",
+ out.shift
+ assert out.empty?, out.inspect
+ end
+
+ def test_execute_two
+ util_setup_fake_fetcher
+ @cmd.options[:domain] = :local
+
+ FileUtils.mv File.join(@gemhome, 'cache', @a2.file_name),
+ File.join(@tempdir)
+
+ FileUtils.mv File.join(@gemhome, 'cache', @b2.file_name),
+ File.join(@tempdir)
+
+ @cmd.options[:args] = [@a2.name, @b2.name]
+
+ use_ui @ui do
+ orig_dir = Dir.pwd
+ begin
+ Dir.chdir @tempdir
+ e = assert_raises Gem::SystemExitException do
+ @cmd.execute
+ end
+ assert_equal 0, e.exit_code
+ ensure
+ Dir.chdir orig_dir
+ end
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Successfully installed #{@a2.full_name}", out.shift
+ assert_equal "Successfully installed #{@b2.full_name}", out.shift
+ assert_equal "2 gems installed", out.shift
+ assert out.empty?, out.inspect
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_list_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_list_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_list_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,36 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/list_command'
+
+class TestGemCommandsListCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::ListCommand.new
+
+ util_setup_fake_fetcher
+
+ @si = util_setup_spec_fetcher @a1, @a2, @pl1
+
+ @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = proc do
+ raise Gem::RemoteFetcher::FetchError
+ end
+ end
+
+ def test_execute_installed
+ @cmd.handle_options %w[c --installed]
+
+ e = assert_raises Gem::SystemExitException do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal 0, e.exit_code
+
+ assert_equal "true\n", @ui.output
+
+ assert_equal '', @ui.error
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_lock_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_lock_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_lock_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,68 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/lock_command'
+
+class TestGemCommandsLockCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @a1 = quick_gem 'a', '1'
+ @b1 = quick_gem 'b', '1' do |s|
+ s.add_runtime_dependency 'a'
+ end
+
+ @d1 = quick_gem 'd', '1' do |s|
+ s.add_runtime_dependency 'z'
+ end
+
+ @cmd = Gem::Commands::LockCommand.new
+ end
+
+ def test_execute
+ @cmd.handle_options %w[b-1]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EXPECTED
+require 'rubygems'
+gem 'b', '= 1'
+gem 'a', '= 1'
+ EXPECTED
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_missing_dependency
+ @cmd.handle_options %w[d-1]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EXPECTED
+require 'rubygems'
+gem 'd', '= 1'
+# Unable to satisfy 'z (>= 0, runtime)' from currently installed gems
+ EXPECTED
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_strict
+ @cmd.handle_options %w[c-1 --strict]
+
+ e = assert_raises Gem::Exception do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal 'Could not find gem c-1, try using the full name', e.message
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_mirror_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_mirror_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_mirror_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,60 @@
+require_relative 'gemutilities'
+require 'rubygems/indexer'
+require 'rubygems/commands/mirror_command'
+
+class TestGemCommandsMirrorCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::MirrorCommand.new
+ end
+
+ def test_execute
+ util_make_gems
+
+ gems_dir = File.join @tempdir, 'gems'
+ mirror = File.join @tempdir, 'mirror'
+
+ FileUtils.mkdir_p gems_dir
+ FileUtils.mkdir_p mirror
+
+ Dir[File.join(@gemhome, 'cache', '*.gem')].each do |gem|
+ FileUtils.mv gem, gems_dir
+ end
+
+ use_ui @ui do
+ Gem::Indexer.new(@tempdir).generate_index
+ end
+
+ orig_HOME = ENV['HOME']
+ ENV['HOME'] = @tempdir
+ Gem.instance_variable_set :@user_home, nil
+
+ File.open File.join(Gem.user_home, '.gemmirrorrc'), 'w' do |fp|
+ fp.puts "---"
+ # tempdir could be a drive+path (under windows)
+ if @tempdir.match(/[a-z]:/i)
+ fp.puts "- from: file:///#{@tempdir}"
+ else
+ fp.puts "- from: file://#{@tempdir}"
+ end
+ fp.puts " to: #{mirror}"
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert File.exist?(File.join(mirror, 'gems', @a1.file_name))
+ assert File.exist?(File.join(mirror, 'gems', @a2.file_name))
+ assert File.exist?(File.join(mirror, 'gems', @b2.file_name))
+ assert File.exist?(File.join(mirror, 'gems', @c1_2.file_name))
+ assert File.exist?(File.join(mirror, "Marshal.#{@marshal_version}"))
+ ensure
+ orig_HOME.nil? ? ENV.delete('HOME') : ENV['HOME'] = orig_HOME
+ Gem.instance_variable_set :@user_home, nil
+ end
+
+end if ''.respond_to? :to_xs
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_outdated_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_outdated_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_outdated_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,40 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/outdated_command'
+
+class TestGemCommandsOutdatedCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::OutdatedCommand.new
+ end
+
+ def test_initialize
+ assert @cmd.handles?(%W[--platform #{Gem::Platform.local}])
+ end
+
+ def test_execute
+ local_01 = quick_gem 'foo', '0.1'
+ local_02 = quick_gem 'foo', '0.2'
+ remote_10 = quick_gem 'foo', '1.0'
+ remote_20 = quick_gem 'foo', '2.0'
+
+ remote_spec_file = File.join @gemhome, 'specifications', remote_10.spec_name
+ FileUtils.rm remote_spec_file
+
+ remote_spec_file = File.join @gemhome, 'specifications', remote_20.spec_name
+ FileUtils.rm remote_spec_file
+
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ util_setup_spec_fetcher remote_10, remote_20
+
+ use_ui @ui do @cmd.execute end
+
+ assert_equal "foo (0.2 < 2.0)\n", @ui.output
+ assert_equal "", @ui.error
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_owner_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_owner_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_owner_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,105 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/owner_command'
+
+class TestGemCommandsOwnerCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+ Gem.configuration.rubygems_api_key = "ed244fbf2b1a52e012da8616c512fa47f9aa5250"
+
+ @cmd = Gem::Commands::OwnerCommand.new
+ end
+
+ def test_show_owners
+ response = <<EOF
+---
+- email: user1 at example.com
+- email: user2 at example.com
+EOF
+
+ @fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners.yaml"] = [response, 200, 'OK']
+
+ use_ui @ui do
+ @cmd.show_owners("freewill")
+ end
+
+ assert_equal Net::HTTP::Get, @fetcher.last_request.class
+ assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"]
+
+ assert_match %r{Owners for gem: freewill}, @ui.output
+ assert_match %r{- user1 at example.com}, @ui.output
+ assert_match %r{- user2 at example.com}, @ui.output
+ end
+
+ def test_show_owners_denied
+ response = "You don't have permission to push to this gem"
+ @fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners.yaml"] = [response, 403, 'Forbidden']
+
+ assert_raises MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.show_owners("freewill")
+ end
+ end
+
+ assert_match response, @ui.output
+ end
+
+ def test_add_owners
+ response = "Owner added successfully."
+ @fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners"] = [response, 200, 'OK']
+
+ use_ui @ui do
+ @cmd.add_owners("freewill", ["user-new1 at example.com"])
+ end
+
+ assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"]
+ assert_equal "email=user-new1%40example.com", @fetcher.last_request.body
+
+ assert_match response, @ui.output
+ end
+
+ def test_add_owners_denied
+ response = "You don't have permission to push to this gem"
+ @fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners"] = [response, 403, 'Forbidden']
+
+ assert_raises MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.add_owners("freewill", ["user-new1 at example.com"])
+ end
+ end
+
+ assert_match response, @ui.output
+ end
+
+ def test_remove_owners
+ response = "Owner removed successfully."
+ @fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners"] = [response, 200, 'OK']
+
+ use_ui @ui do
+ @cmd.remove_owners("freewill", ["user-remove1 at example.com"])
+ end
+
+ assert_equal Net::HTTP::Delete, @fetcher.last_request.class
+ assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"]
+ assert_equal "email=user-remove1%40example.com", @fetcher.last_request.body
+
+ assert_match response, @ui.output
+ end
+
+ def test_remove_owners_denied
+ response = "You don't have permission to push to this gem"
+ @fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners"] = [response, 403, 'Forbidden']
+
+ assert_raises MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.remove_owners("freewill", ["user-remove1 at example.com"])
+ end
+ end
+
+ assert_match response, @ui.output
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_pristine_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_pristine_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_pristine_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,108 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/pristine_command'
+
+class TestGemCommandsPristineCommand < RubyGemTestCase
+
+ def setup
+ super
+ @cmd = Gem::Commands::PristineCommand.new
+ end
+
+ def test_execute
+ a = quick_gem 'a' do |s| s.executables = %w[foo] end
+ FileUtils.mkdir_p File.join(@tempdir, 'bin')
+ File.open File.join(@tempdir, 'bin', 'foo'), 'w' do |fp|
+ fp.puts "#!/usr/bin/ruby"
+ end
+
+ install_gem a
+
+ foo_path = File.join @gemhome, 'gems', a.full_name, 'bin', 'foo'
+
+ File.open foo_path, 'w' do |io|
+ io.puts 'I changed it!'
+ end
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#!/usr/bin/ruby\n", File.read(foo_path), foo_path
+
+ out = @ui.output.split "\n"
+
+ assert_equal "Restoring gem(s) to pristine condition...", out.shift
+ assert_equal "Restored #{a.full_name}", out.shift
+ assert_empty out, out.inspect
+ end
+
+ def test_execute_all
+ a = quick_gem 'a' do |s| s.executables = %w[foo] end
+ FileUtils.mkdir_p File.join(@tempdir, 'bin')
+ File.open File.join(@tempdir, 'bin', 'foo'), 'w' do |fp|
+ fp.puts "#!/usr/bin/ruby"
+ end
+
+ install_gem a
+
+ gem_bin = File.join @gemhome, 'gems', a.full_name, 'bin', 'foo'
+
+ FileUtils.rm gem_bin
+
+ @cmd.handle_options %w[--all]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert File.exist?(gem_bin)
+
+ out = @ui.output.split "\n"
+
+ assert_equal "Restoring gem(s) to pristine condition...", out.shift
+ assert_equal "Restored #{a.full_name}", out.shift
+ assert_empty out, out.inspect
+ end
+
+ def test_execute_missing_cache_gem
+ a = quick_gem 'a' do |s| s.executables = %w[foo] end
+ FileUtils.mkdir_p File.join(@tempdir, 'bin')
+ File.open File.join(@tempdir, 'bin', 'foo'), 'w' do |fp|
+ fp.puts "#!/usr/bin/ruby"
+ end
+
+ install_gem a
+
+ FileUtils.rm File.join(@gemhome, 'cache', a.file_name)
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+
+ assert_equal "Restoring gem\(s\) to pristine condition...", out.shift
+ assert_empty out, out.inspect
+
+ assert_equal "ERROR: Cached gem for #{a.full_name} not found, use `gem install` to restore\n",
+ @ui.error
+ end
+
+ def test_execute_no_gem
+ @cmd.options[:args] = %w[]
+
+ e = assert_raises Gem::CommandLineError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_match %r|specify a gem name|, e.message
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_push_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_push_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_push_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,61 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/push_command'
+
+class TestGemCommandsPushCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @gems_dir = File.join @tempdir, 'gems'
+ @cache_dir = File.join @gemhome, 'cache'
+ FileUtils.mkdir @gems_dir
+ Gem.configuration.rubygems_api_key = "ed244fbf2b1a52e012da8616c512fa47f9aa5250"
+ @spec, @path = util_gem("freewill", "1.0.0")
+
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ @cmd = Gem::Commands::PushCommand.new
+ end
+
+ def test_sending_gem
+ response = "Successfully registered gem: freewill (1.0.0)"
+ @fetcher.data["https://rubygems.org/api/v1/gems"] = [response, 200, 'OK']
+
+ use_ui @ui do
+ @cmd.send_gem(@path)
+ end
+
+ assert_match %r{Pushing gem to RubyGems.org...}, @ui.output
+
+ assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem.read_binary(@path), @fetcher.last_request.body
+ assert_equal File.size(@path), @fetcher.last_request["Content-Length"].to_i
+ assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"]
+ assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"]
+
+ assert_match response, @ui.output
+ end
+
+ def test_raises_error_with_no_arguments
+ def @cmd.sign_in; end
+ assert_raises Gem::CommandLineError do
+ @cmd.execute
+ end
+ end
+
+ def test_sending_gem_denied
+ response = "You don't have permission to push to this gem"
+ @fetcher.data["https://rubygems.org/api/v1/gems"] = [response, 403, 'Forbidden']
+
+ assert_raises MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.send_gem(@path)
+ end
+ end
+
+ assert_match response, @ui.output
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_query_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_query_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_query_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,426 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/query_command'
+
+class TestGemCommandsQueryCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::QueryCommand.new
+
+ util_setup_fake_fetcher
+
+ @si = util_setup_spec_fetcher @a1, @a2, @pl1, @a3a
+
+ @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = proc do
+ raise Gem::RemoteFetcher::FetchError
+ end
+ end
+
+ def test_execute
+ @cmd.handle_options %w[-r]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (2)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_platform
+ @a1r = @a1.dup
+
+ @a1.platform = 'x86-linux'
+ @a2.platform = 'universal-darwin'
+
+ @si = util_setup_spec_fetcher @a1, @a1r, @a2, @b2, @pl1
+
+ @cmd.handle_options %w[-r -a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (2 universal-darwin, 1 ruby x86-linux)
+b (2)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_all
+ a1_name = @a1.full_name
+ a2_name = @a2.full_name
+
+ @cmd.handle_options %w[-r --all]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (2, 1)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_all_prerelease
+ a1_name = @a1.full_name
+ a2_name = @a2.full_name
+
+ @cmd.handle_options %w[-r --all --prerelease]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (3.a, 2, 1)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_details
+ @a2.summary = 'This is a lot of text. ' * 4
+ @a2.authors = ['Abraham Lincoln', 'Hirohito']
+ @a2.homepage = 'http://a.example.com/'
+ @a2.rubyforge_project = 'rubygems'
+
+ @si = util_setup_spec_fetcher @a1, @a2, @pl1
+
+ @cmd.handle_options %w[-r -d]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (2)
+ Authors: Abraham Lincoln, Hirohito
+ Rubyforge: http://rubyforge.org/projects/rubygems
+ Homepage: http://a.example.com/
+
+ This is a lot of text. This is a lot of text. This is a lot of text.
+ This is a lot of text.
+
+pl (1)
+ Platform: i386-linux
+ Author: A User
+ Homepage: http://example.com
+
+ this is a summary
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_details_platform
+ @a1.platform = 'x86-linux'
+
+ @a2.summary = 'This is a lot of text. ' * 4
+ @a2.authors = ['Abraham Lincoln', 'Hirohito']
+ @a2.homepage = 'http://a.example.com/'
+ @a2.rubyforge_project = 'rubygems'
+ @a2.platform = 'universal-darwin'
+
+ @si = util_setup_spec_fetcher @a1, @a2, @pl1
+
+ @cmd.handle_options %w[-r -d]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (2, 1)
+ Platforms:
+ 1: x86-linux
+ 2: universal-darwin
+ Authors: Abraham Lincoln, Hirohito
+ Rubyforge: http://rubyforge.org/projects/rubygems
+ Homepage: http://a.example.com/
+
+ This is a lot of text. This is a lot of text. This is a lot of text.
+ This is a lot of text.
+
+pl (1)
+ Platform: i386-linux
+ Author: A User
+ Homepage: http://example.com
+
+ this is a summary
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_installed
+ @cmd.handle_options %w[-n c --installed]
+
+ e = assert_raises Gem::SystemExitException do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal 0, e.exit_code
+
+ assert_equal "true\n", @ui.output
+
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_installed_no_name
+ @cmd.handle_options %w[--installed]
+
+ e = assert_raises Gem::SystemExitException do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_equal "ERROR: You must specify a gem name\n", @ui.error
+
+ assert_equal 4, e.exit_code
+ end
+
+ def test_execute_installed_not_installed
+ @cmd.handle_options %w[-n not_installed --installed]
+
+ e = assert_raises Gem::SystemExitException do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "false\n", @ui.output
+ assert_equal '', @ui.error
+
+ assert_equal 1, e.exit_code
+ end
+
+ def test_execute_installed_version
+ @cmd.handle_options %w[-n c --installed --version 1.2]
+
+ e = assert_raises Gem::SystemExitException do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "true\n", @ui.output
+ assert_equal '', @ui.error
+
+ assert_equal 0, e.exit_code
+ end
+
+ def test_execute_installed_version_not_installed
+ @cmd.handle_options %w[-n c --installed --version 2]
+
+ e = assert_raises Gem::SystemExitException do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "false\n", @ui.output
+ assert_equal '', @ui.error
+
+ assert_equal 1, e.exit_code
+ end
+
+ def test_execute_local_details
+ @a3a.summary = 'This is a lot of text. ' * 4
+ @a3a.authors = ['Abraham Lincoln', 'Hirohito']
+ @a3a.homepage = 'http://a.example.com/'
+ @a3a.rubyforge_project = 'rubygems'
+
+ @cmd.handle_options %w[--local --details]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** LOCAL GEMS ***
+
+a (3.a, 2, 1)
+ Author: A User
+ Homepage: http://example.com
+ Installed at (3.a): #{@gemhome}
+ (2): #{@gemhome}
+ (1): #{@gemhome}
+
+ this is a summary
+
+a_evil (9)
+ Author: A User
+ Homepage: http://example.com
+ Installed at: #{@gemhome}
+
+ this is a summary
+
+b (2)
+ Author: A User
+ Homepage: http://example.com
+ Installed at: #{@gemhome}
+
+ this is a summary
+
+c (1.2)
+ Author: A User
+ Homepage: http://example.com
+ Installed at: #{@gemhome}
+
+ this is a summary
+
+pl (1)
+ Platform: i386-linux
+ Author: A User
+ Homepage: http://example.com
+ Installed at: #{@gemhome}
+
+ this is a summary
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_local_notty
+ @cmd.handle_options %w[]
+
+ @ui.outs.tty = false
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+a (3.a, 2, 1)
+a_evil (9)
+b (2)
+c (1.2)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_no_versions
+ @cmd.handle_options %w[-r --no-versions]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a
+pl
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_notty
+ @cmd.handle_options %w[-r]
+
+ @ui.outs.tty = false
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+a (2)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_prerelease
+ @cmd.handle_options %w[-r --prerelease]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (3.a)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_prerelease_local
+ @cmd.handle_options %w[-l --prerelease]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** LOCAL GEMS ***
+
+a (3.a, 2, 1)
+a_evil (9)
+b (2)
+c (1.2)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal "WARNING: prereleases are always shown locally\n", @ui.error
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_server_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_server_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_server_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,59 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/server_command'
+
+class TestGemCommandsServerCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::ServerCommand.new
+ end
+
+ def test_handle_options
+ @cmd.send :handle_options, %w[-p 8808 --no-daemon]
+
+ assert_equal false, @cmd.options[:daemon]
+ assert_equal [], @cmd.options[:gemdir]
+ assert_equal 8808, @cmd.options[:port]
+
+ @cmd.send :handle_options, %w[-p 9999 -d /nonexistent --daemon]
+
+ assert_equal true, @cmd.options[:daemon]
+ assert_equal [File.expand_path('/nonexistent')], @cmd.options[:gemdir]
+ assert_equal 9999, @cmd.options[:port]
+ end
+
+ def test_handle_options_gemdir
+ @cmd.send :handle_options, %w[--dir a --dir b]
+
+ assert_equal [File.expand_path('a'), File.expand_path('b')],
+ @cmd.options[:gemdir]
+ end
+
+ def test_handle_options_port
+ @cmd.send :handle_options, %w[-p 0]
+ assert_equal 0, @cmd.options[:port]
+
+ @cmd.send :handle_options, %w[-p 65535]
+ assert_equal 65535, @cmd.options[:port]
+
+ @cmd.send :handle_options, %w[-p http]
+ assert_equal 80, @cmd.options[:port]
+
+ e = assert_raises OptionParser::InvalidArgument do
+ @cmd.send :handle_options, %w[-p nonexistent]
+ end
+
+ assert_equal 'invalid argument: -p nonexistent: no such named service',
+ e.message
+
+ e = assert_raises OptionParser::InvalidArgument do
+ @cmd.send :handle_options, %w[-p 65536]
+ end
+
+ assert_equal 'invalid argument: -p 65536: not a port number',
+ e.message
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_sources_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_sources_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_sources_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,209 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/sources_command'
+
+class TestGemCommandsSourcesCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::SourcesCommand.new
+
+ @new_repo = "http://beta-gems.example.com"
+ end
+
+ def test_initialize_proxy
+ assert @cmd.handles?(['--http-proxy', 'http://proxy.example.com'])
+ end
+
+ def test_execute
+ util_setup_spec_fetcher
+ @cmd.handle_options []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+*** CURRENT SOURCES ***
+
+#{@gem_repo}
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_add
+ util_setup_fake_fetcher
+
+ si = Gem::SourceIndex.new
+ si.add_spec @a1
+
+ specs = si.map do |_, spec|
+ [spec.name, spec.version, spec.original_platform]
+ end
+
+ specs_dump_gz = StringIO.new
+ Zlib::GzipWriter.wrap specs_dump_gz do |io|
+ Marshal.dump specs, io
+ end
+
+ @fetcher.data["#{@new_repo}/specs.#{@marshal_version}.gz"] =
+ specs_dump_gz.string
+
+ @cmd.handle_options %W[--add #{@new_repo}]
+
+ util_setup_spec_fetcher
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal [@gem_repo, @new_repo], Gem.sources
+
+ expected = <<-EOF
+#{@new_repo} added to sources
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_add_nonexistent_source
+ util_setup_fake_fetcher
+
+ uri = "http://beta-gems.example.com/specs.#{@marshal_version}.gz"
+ @fetcher.data[uri] = proc do
+ raise Gem::RemoteFetcher::FetchError.new('it died', uri)
+ end
+
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ @cmd.handle_options %w[--add http://beta-gems.example.com]
+
+ util_setup_spec_fetcher
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+Error fetching http://beta-gems.example.com:
+\tit died (#{uri})
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_add_bad_uri
+ @cmd.handle_options %w[--add beta-gems.example.com]
+
+ util_setup_spec_fetcher
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal [@gem_repo], Gem.sources
+
+ expected = <<-EOF
+beta-gems.example.com is not a URI
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_clear_all
+ @cmd.handle_options %w[--clear-all]
+
+ util_setup_spec_fetcher
+
+ fetcher = Gem::SpecFetcher.fetcher
+
+ # HACK figure out how to force directory creation via fetcher
+ #assert File.directory?(fetcher.dir), 'cache dir exists'
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+*** Removed specs cache ***
+*** Removed user source cache ***
+*** Removed latest user source cache ***
+*** Removed system source cache ***
+*** Removed latest system source cache ***
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+
+ refute File.exist?(fetcher.dir), 'cache dir removed'
+ end
+
+ def test_execute_remove
+ @cmd.handle_options %W[--remove #{@gem_repo}]
+
+ util_setup_spec_fetcher
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = "#{@gem_repo} removed from sources\n"
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_remove_no_network
+ @cmd.handle_options %W[--remove #{@gem_repo}]
+
+ util_setup_fake_fetcher
+
+ @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = proc do
+ raise Gem::RemoteFetcher::FetchError
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = "#{@gem_repo} removed from sources\n"
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_update
+ @cmd.handle_options %w[--update]
+
+ util_setup_fake_fetcher
+ source_index = util_setup_spec_fetcher @a1
+
+ specs = source_index.map do |name, spec|
+ [spec.name, spec.version, spec.original_platform]
+ end
+
+ @fetcher.data["#{@gem_repo}specs.#{Gem.marshal_version}.gz"] =
+ util_gzip Marshal.dump(specs)
+
+ latest_specs = source_index.latest_specs.map do |spec|
+ [spec.name, spec.version, spec.original_platform]
+ end
+
+ @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] =
+ util_gzip Marshal.dump(latest_specs)
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "source cache successfully updated\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_specification_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_specification_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_specification_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,139 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/specification_command'
+
+class TestGemCommandsSpecificationCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::SpecificationCommand.new
+ end
+
+ def test_execute
+ foo = quick_gem 'foo'
+ Gem.source_index.add_spec foo
+
+ @cmd.options[:args] = %w[foo]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_all
+ foo1 = quick_gem 'foo', '0.0.1'
+ foo2 = quick_gem 'foo', '0.0.2'
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:all] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+ assert_match %r|version: 0.0.1|, @ui.output
+ assert_match %r|version: 0.0.2|, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_bad_name
+ @cmd.options[:args] = %w[foo]
+
+ assert_raises MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_equal "ERROR: Unknown gem 'foo'\n", @ui.error
+ end
+
+ def test_execute_exact_match
+ foo = quick_gem 'foo'
+ foo_bar = quick_gem 'foo_bar'
+
+ @cmd.options[:args] = %w[foo]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_field
+ foo = quick_gem 'foo'
+ Gem.source_index.add_spec foo
+
+ @cmd.options[:args] = %w[foo name]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "foo", YAML.load(@ui.output)
+ end
+
+ def test_execute_marshal
+ foo = quick_gem 'foo'
+ Gem.source_index.add_spec foo
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:format] = :marshal
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal foo, Marshal.load(@ui.output)
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_remote
+ foo = quick_gem 'foo'
+
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ util_setup_spec_fetcher foo
+
+ FileUtils.rm File.join(@gemhome, 'specifications', foo.spec_name)
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:domain] = :remote
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|\A--- !ruby/object:Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+ end
+
+ def test_execute_ruby
+ foo = quick_gem 'foo'
+ Gem.source_index.add_spec foo
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:format] = :ruby
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|Gem::Specification.new|, @ui.output
+ assert_match %r|s.name = %q\{foo\}|, @ui.output
+ assert_equal '', @ui.error
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_stale_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_stale_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_stale_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,38 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/stale_command'
+
+class TestGemCommandsStaleCommand < RubyGemTestCase
+
+ def setup
+ super
+ @cmd = Gem::Commands::StaleCommand.new
+ end
+
+ def test_execute_sorts
+ files = %w[lib/foo_bar.rb Rakefile]
+ foo_bar = quick_gem 'foo_bar' do |gem|
+ gem.files = files
+ end
+ bar_baz = quick_gem 'bar_baz' do |gem|
+ gem.files = files
+ end
+
+ files.each do |file|
+ filename = bar_baz.full_gem_path + "/#{file}"
+ FileUtils.mkdir_p(File.dirname(filename))
+ FileUtils.touch(filename, :mtime => Time.now)
+
+ filename = foo_bar.full_gem_path + "/#{file}"
+ FileUtils.mkdir_p(File.dirname(filename))
+ FileUtils.touch(filename, :mtime => Time.now - 86400)
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+ lines = @ui.output.split("\n")
+ assert_equal("#{foo_bar.name}-#{foo_bar.version}", lines[0].split.first)
+ assert_equal("#{bar_baz.name}-#{bar_baz.version}", lines[1].split.first)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_uninstall_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_uninstall_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_uninstall_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,83 @@
+require_relative 'gemutilities'
+require_relative 'gem_installer_test_case'
+require 'rubygems/commands/uninstall_command'
+
+class TestGemCommandsUninstallCommand < GemInstallerTestCase
+
+ def setup
+ super
+
+ ui = MockGemUi.new
+ util_setup_gem ui
+
+ build_rake_in do
+ use_ui ui do
+ @installer.install
+ end
+ end
+
+ @cmd = Gem::Commands::UninstallCommand.new
+ @cmd.options[:executables] = true
+ @executable = File.join(@gemhome, 'bin', 'executable')
+ end
+
+ def test_execute_removes_executable
+ if win_platform?
+ assert_equal true, File.exist?(@executable)
+ else
+ assert_equal true, File.symlink?(@executable)
+ end
+
+ # Evil hack to prevent false removal success
+ FileUtils.rm_f @executable
+ File.open(@executable, "wb+") {|f| f.puts "binary"}
+
+ @cmd.options[:args] = Array(@spec.name)
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ output = @ui.output.split "\n"
+ assert_match(/Removing executable/, output.shift)
+ assert_match(/Successfully uninstalled/, output.shift)
+ assert_equal false, File.exist?(@executable)
+ assert_nil output.shift, "UI output should have contained only two lines"
+ end
+
+ def test_execute_not_installed
+ @cmd.options[:args] = ["foo"]
+ e = assert_raises Gem::InstallError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_match(/\Acannot uninstall, check `gem list -d foo`$/, e.message)
+ output = @ui.output.split "\n"
+ assert_empty output, "UI output should be empty after an uninstall error"
+ end
+
+ def test_execute_prerelease
+ @spec = quick_gem "pre", "2.b"
+ @gem = File.join @tempdir, @spec.file_name
+ FileUtils.touch @gem
+
+ util_setup_gem
+
+ build_rake_in do
+ use_ui @ui do
+ @installer.install
+ end
+ end
+
+ @cmd.options[:args] = ["pre"]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ output = @ui.output
+ assert_match(/Successfully uninstalled/, output)
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_unpack_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_unpack_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_unpack_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,159 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/unpack_command'
+
+class TestGemCommandsUnpackCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ Dir.chdir @tempdir do
+ @cmd = Gem::Commands::UnpackCommand.new
+ end
+ end
+
+ def test_execute
+ util_make_gems
+
+ @cmd.options[:args] = %w[a b]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, 'a-3.a')), 'a should be unpacked'
+ assert File.exist?(File.join(@tempdir, 'b-2')), 'b should be unpacked'
+ end
+
+ def test_execute_gem_path
+ util_make_gems
+
+ Gem.clear_paths
+
+ gemhome2 = File.join @tempdir, 'gemhome2'
+
+ Gem.send :set_paths, [gemhome2, @gemhome].join(File::PATH_SEPARATOR)
+ Gem.send :set_home, gemhome2
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, 'a-3.a'))
+ end
+
+ def test_execute_gem_path_missing
+ util_make_gems
+ util_setup_spec_fetcher
+
+ Gem.clear_paths
+
+ gemhome2 = File.join @tempdir, 'gemhome2'
+
+ Gem.send :set_paths, [gemhome2, @gemhome].join(File::PATH_SEPARATOR)
+ Gem.send :set_home, gemhome2
+
+ @cmd.options[:args] = %w[z]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ end
+
+ def test_execute_remote
+ util_setup_fake_fetcher
+ util_setup_spec_fetcher @a1, @a2
+ util_clear_gems
+
+ a2_data = nil
+ open File.join(@gemhome, 'cache', @a2.file_name), 'rb' do |fp|
+ a2_data = fp.read
+ end
+
+ Gem::RemoteFetcher.fetcher.data['http://gems.example.com/gems/a-2.gem'] =
+ a2_data
+
+ Gem.configuration.verbose = :really
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, 'a-2')), 'a should be unpacked'
+ end
+
+ def test_execute_sudo
+ util_make_gems
+
+ File.chmod 0555, @gemhome
+
+ @cmd.options[:args] = %w[b]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, 'b-2')), 'b should be unpacked'
+ ensure
+ File.chmod 0755, @gemhome
+ end
+
+ def test_execute_with_target_option
+ util_make_gems
+
+ target = 'with_target'
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:target] = target
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, target, 'a-3.a'))
+ end
+
+ def test_execute_exact_match
+ foo_spec = quick_gem 'foo'
+ foo_bar_spec = quick_gem 'foo_bar'
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ Gem::Builder.new(foo_spec).build
+ Gem::Builder.new(foo_bar_spec).build
+ end
+ end
+
+ foo_path = File.join(@tempdir, "#{foo_spec.full_name}.gem")
+ foo_bar_path = File.join(@tempdir, "#{foo_bar_spec.full_name}.gem")
+ Gem::Installer.new(foo_path).install
+ Gem::Installer.new(foo_bar_path).install
+
+ @cmd.options[:args] = %w[foo]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, foo_spec.full_name))
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_update_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_update_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_update_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,169 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/update_command'
+
+class TestGemCommandsUpdateCommand < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::UpdateCommand.new
+
+ @cmd.options[:generate_rdoc] = false
+ @cmd.options[:generate_ri] = false
+
+ util_setup_fake_fetcher
+
+ @a1_path = File.join @gemhome, 'cache', @a1.file_name
+ @a2_path = File.join @gemhome, 'cache', @a2.file_name
+
+ util_setup_spec_fetcher @a1, @a2
+
+ @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] =
+ read_binary @a1_path
+ @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
+ read_binary @a2_path
+ end
+
+ def test_execute
+ util_clear_gems
+
+ Gem::Installer.new(@a1_path).install
+
+ @cmd.options[:args] = []
+ @cmd.options[:generate_rdoc] = true
+ @cmd.options[:generate_ri] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Updating #{@a2.name}", out.shift
+ assert_equal "Successfully installed #{@a2.full_name}", out.shift
+ assert_equal "Gems updated: #{@a2.name}", out.shift
+ assert_equal "Installing ri documentation for a-2...", out.shift
+ assert_equal "Installing RDoc documentation for a-2...", out.shift
+
+ assert_empty out
+ end
+
+ # before:
+ # a1 -> c1.2
+ # after:
+ # a2 -> b2 # new dependency
+ # a2 -> c2
+
+ def test_execute_dependencies
+ @a1.add_dependency 'c', '1.2'
+
+ @c2 = quick_gem 'c', '2' do |s|
+ s.files = %w[lib/code.rb]
+ s.require_paths = %w[lib]
+ end
+
+ @a2.add_dependency 'c', '2'
+ @a2.add_dependency 'b', '2'
+
+ @b2_path = File.join @gemhome, 'cache', @b2.file_name
+ @c1_2_path = File.join @gemhome, 'cache', @c1_2.file_name
+ @c2_path = File.join @gemhome, 'cache', @c2.file_name
+
+ @source_index = Gem::SourceIndex.new
+ @source_index.add_spec @a1
+ @source_index.add_spec @a2
+ @source_index.add_spec @b2
+ @source_index.add_spec @c1_2
+ @source_index.add_spec @c2
+
+ util_build_gem @a1
+ util_build_gem @a2
+ util_build_gem @c2
+
+ @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] = read_binary @a1_path
+ @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = read_binary @a2_path
+ @fetcher.data["#{@gem_repo}gems/#{@b2.file_name}"] = read_binary @b2_path
+ @fetcher.data["#{@gem_repo}gems/#{@c1_2.file_name}"] =
+ read_binary @c1_2_path
+ @fetcher.data["#{@gem_repo}gems/#{@c2.file_name}"] = read_binary @c2_path
+
+ util_setup_spec_fetcher @a1, @a2, @b2, @c1_2, @c2
+ util_clear_gems
+
+ Gem::Installer.new(@c1_2_path).install
+ Gem::Installer.new(@a1_path).install
+
+ @cmd.options[:args] = []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Updating #{@a2.name}", out.shift
+ assert_equal "Successfully installed #{@c2.full_name}", out.shift
+ assert_equal "Successfully installed #{@b2.full_name}", out.shift
+ assert_equal "Successfully installed #{@a2.full_name}", out.shift
+ assert_equal "Gems updated: #{@c2.name}, #{@b2.name}, #{@a2.name}",
+ out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_named
+ util_clear_gems
+
+ Gem::Installer.new(@a1_path).install
+
+ @cmd.options[:args] = [@a1.name]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Updating #{@a2.name}", out.shift
+ assert_equal "Successfully installed #{@a2.full_name}", out.shift
+ assert_equal "Gems updated: #{@a2.name}", out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_named_up_to_date
+ util_clear_gems
+
+ Gem::Installer.new(@a2_path).install
+
+ @cmd.options[:args] = [@a2.name]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Nothing to update", out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_up_to_date
+ util_clear_gems
+
+ Gem::Installer.new(@a2_path).install
+
+ @cmd.options[:args] = []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Nothing to update", out.shift
+
+ assert_empty out
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_which_command.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_which_command.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_commands_which_command.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,66 @@
+require_relative 'gemutilities'
+require 'rubygems/commands/which_command'
+
+class TestGemCommandsWhichCommand < RubyGemTestCase
+
+ def setup
+ super
+ @cmd = Gem::Commands::WhichCommand.new
+ end
+
+ def test_execute
+ util_foo_bar
+
+ @cmd.handle_options %w[foo_bar]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_one_missing
+ util_foo_bar
+
+ @cmd.handle_options %w[foo_bar missing]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
+ assert_match %r%Can't find ruby library file or shared library missing\n%,
+ @ui.error
+ end
+
+ def test_execute_missing
+ @cmd.handle_options %w[missing]
+
+ use_ui @ui do
+ assert_raises MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_match %r%Can't find ruby library file or shared library missing\n%,
+ @ui.error
+ end
+
+ def util_foo_bar
+ files = %w[lib/foo_bar.rb Rakefile]
+ @foo_bar = quick_gem 'foo_bar' do |gem|
+ gem.files = files
+ end
+
+ files.each do |file|
+ filename = @foo_bar.full_gem_path + "/#{file}"
+ FileUtils.mkdir_p File.dirname(filename)
+ FileUtils.touch filename
+ end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_config_file.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_config_file.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_config_file.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,287 @@
+require_relative 'gemutilities'
+require 'rubygems/config_file'
+
+class TestGemConfigFile < RubyGemTestCase
+
+ def setup
+ super
+
+ @temp_conf = File.join @tempdir, '.gemrc'
+
+ @cfg_args = %W[--config-file #{@temp_conf}]
+
+ @orig_SYSTEM_WIDE_CONFIG_FILE = Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE
+ Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
+ Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE,
+ File.join(@tempdir, 'system-gemrc')
+ Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS.clear
+ Gem::ConfigFile::PLATFORM_DEFAULTS.clear
+
+ util_config_file
+ end
+
+ def teardown
+ Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS.clear
+ Gem::ConfigFile::PLATFORM_DEFAULTS.clear
+ Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
+ Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE,
+ @orig_SYSTEM_WIDE_CONFIG_FILE
+
+ super
+ end
+
+ def test_initialize
+ assert_equal @temp_conf, @cfg.config_file_name
+
+ assert_equal false, @cfg.backtrace
+ assert_equal true, @cfg.update_sources
+ assert_equal false, @cfg.benchmark
+ assert_equal Gem::ConfigFile::DEFAULT_BULK_THRESHOLD, @cfg.bulk_threshold
+ assert_equal true, @cfg.verbose
+ assert_equal [@gem_repo], Gem.sources
+
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":backtrace: true"
+ fp.puts ":update_sources: false"
+ fp.puts ":benchmark: true"
+ fp.puts ":bulk_threshold: 10"
+ fp.puts ":verbose: false"
+ fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97"
+ fp.puts ":sources:"
+ fp.puts " - http://more-gems.example.com"
+ fp.puts "install: --wrappers"
+ fp.puts ":gempath:"
+ fp.puts "- /usr/ruby/1.8/lib/ruby/gems/1.8"
+ fp.puts "- /var/ruby/1.8/gem_home"
+ end
+
+ util_config_file
+
+ assert_equal true, @cfg.backtrace
+ assert_equal true, @cfg.benchmark
+ assert_equal 10, @cfg.bulk_threshold
+ assert_equal false, @cfg.verbose
+ assert_equal false, @cfg.update_sources
+ assert_equal "701229f217cdf23b1344c7b4b54ca97", @cfg.rubygems_api_key
+ assert_equal %w[http://more-gems.example.com], Gem.sources
+ assert_equal '--wrappers', @cfg[:install]
+ assert_equal(['/usr/ruby/1.8/lib/ruby/gems/1.8', '/var/ruby/1.8/gem_home'],
+ @cfg.path)
+ end
+
+ def test_initialize_handle_arguments_config_file
+ util_config_file %W[--config-file #{@temp_conf}]
+
+ assert_equal @temp_conf, @cfg.config_file_name
+ end
+
+ def test_initialize_handle_arguments_config_file_with_other_params
+ util_config_file %W[--config-file #{@temp_conf} --backtrace]
+
+ assert_equal @temp_conf, @cfg.config_file_name
+ end
+
+ def test_initialize_handle_arguments_config_file_equals
+ util_config_file %W[--config-file=#{@temp_conf}]
+
+ assert_equal @temp_conf, @cfg.config_file_name
+ end
+
+ def test_initialize_operating_system_override
+ Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS[:bulk_threshold] = 1
+ Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS['install'] = '--no-env-shebang'
+
+ Gem::ConfigFile::PLATFORM_DEFAULTS[:bulk_threshold] = 2
+
+ util_config_file
+
+ assert_equal 2, @cfg.bulk_threshold
+ assert_equal '--no-env-shebang', @cfg[:install]
+ end
+
+ def test_initialize_platform_override
+ Gem::ConfigFile::PLATFORM_DEFAULTS[:bulk_threshold] = 2
+ Gem::ConfigFile::PLATFORM_DEFAULTS['install'] = '--no-env-shebang'
+
+ File.open Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE, 'w' do |fp|
+ fp.puts ":bulk_threshold: 3"
+ end
+
+ util_config_file
+
+ assert_equal 3, @cfg.bulk_threshold
+ assert_equal '--no-env-shebang', @cfg[:install]
+ end
+
+ def test_initialize_system_wide_override
+ File.open Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE, 'w' do |fp|
+ fp.puts ":backtrace: false"
+ fp.puts ":bulk_threshold: 2048"
+ end
+
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":backtrace: true"
+ end
+
+ util_config_file
+
+ assert_equal 2048, @cfg.bulk_threshold
+ assert_equal true, @cfg.backtrace
+ end
+
+ def test_handle_arguments
+ args = %w[--backtrace --bunch --of --args here]
+
+ @cfg.handle_arguments args
+
+ assert_equal %w[--bunch --of --args here], @cfg.args
+ end
+
+ def test_handle_arguments_backtrace
+ assert_equal false, @cfg.backtrace
+
+ args = %w[--backtrace]
+
+ @cfg.handle_arguments args
+
+ assert_equal true, @cfg.backtrace
+ end
+
+ def test_handle_arguments_benchmark
+ assert_equal false, @cfg.benchmark
+
+ args = %w[--benchmark]
+
+ @cfg.handle_arguments args
+
+ assert_equal true, @cfg.benchmark
+ end
+
+ def test_handle_arguments_debug
+ old_dollar_DEBUG = $DEBUG
+ assert_equal false, $DEBUG
+
+ args = %w[--debug]
+
+ @cfg.handle_arguments args
+
+ assert_equal true, $DEBUG
+ ensure
+ $DEBUG = old_dollar_DEBUG
+ end
+
+ def test_handle_arguments_override
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":benchmark: false"
+ end
+
+ util_config_file %W[--benchmark --config-file=#{@temp_conf}]
+
+ assert_equal true, @cfg.benchmark
+ end
+
+ def test_handle_arguments_traceback
+ assert_equal false, @cfg.backtrace
+
+ args = %w[--traceback]
+
+ @cfg.handle_arguments args
+
+ assert_equal true, @cfg.backtrace
+ end
+
+ def test_really_verbose
+ assert_equal false, @cfg.really_verbose
+
+ @cfg.verbose = true
+
+ assert_equal false, @cfg.really_verbose
+
+ @cfg.verbose = 1
+
+ assert_equal true, @cfg.really_verbose
+ end
+
+ def test_write
+ @cfg.backtrace = true
+ @cfg.benchmark = true
+ @cfg.update_sources = false
+ @cfg.bulk_threshold = 10
+ @cfg.verbose = false
+ Gem.sources.replace %w[http://more-gems.example.com]
+ @cfg[:install] = '--wrappers'
+
+ @cfg.write
+
+ util_config_file
+
+ # These should not be written out to the config file.
+ assert_equal false, @cfg.backtrace, 'backtrace'
+ assert_equal false, @cfg.benchmark, 'benchmark'
+ assert_equal Gem::ConfigFile::DEFAULT_BULK_THRESHOLD, @cfg.bulk_threshold,
+ 'bulk_threshold'
+ assert_equal true, @cfg.update_sources, 'update_sources'
+ assert_equal true, @cfg.verbose, 'verbose'
+
+ assert_equal '--wrappers', @cfg[:install], 'install'
+
+ # this should be written out to the config file.
+ assert_equal %w[http://more-gems.example.com], Gem.sources
+ end
+
+ def test_write_from_hash
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":backtrace: true"
+ fp.puts ":benchmark: true"
+ fp.puts ":bulk_threshold: 10"
+ fp.puts ":update_sources: false"
+ fp.puts ":verbose: false"
+ fp.puts ":sources:"
+ fp.puts " - http://more-gems.example.com"
+ fp.puts "install: --wrappers"
+ end
+
+ util_config_file
+
+ @cfg.backtrace = :junk
+ @cfg.benchmark = :junk
+ @cfg.update_sources = :junk
+ @cfg.bulk_threshold = 20
+ @cfg.verbose = :junk
+ Gem.sources.replace %w[http://even-more-gems.example.com]
+ @cfg[:install] = '--wrappers --no-rdoc'
+
+ @cfg.write
+
+ util_config_file
+
+ # These should not be written out to the config file
+ assert_equal true, @cfg.backtrace, 'backtrace'
+ assert_equal true, @cfg.benchmark, 'benchmark'
+ assert_equal 10, @cfg.bulk_threshold, 'bulk_threshold'
+ assert_equal false, @cfg.update_sources, 'update_sources'
+ assert_equal false, @cfg.verbose, 'verbose'
+
+ assert_equal '--wrappers --no-rdoc', @cfg[:install], 'install'
+
+ assert_equal %w[http://even-more-gems.example.com], Gem.sources
+ end
+
+ def test_load_rubygems_api_key_from_credentials
+ temp_cred = File.join Gem.user_home, '.gem', 'credentials'
+ FileUtils.mkdir File.dirname(temp_cred)
+ File.open temp_cred, 'w' do |fp|
+ fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97"
+ end
+
+ util_config_file
+
+ assert_equal "701229f217cdf23b1344c7b4b54ca97", @cfg.rubygems_api_key
+ end
+
+ def util_config_file(args = @cfg_args)
+ @cfg = Gem::ConfigFile.new args
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_dependency.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_dependency.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_dependency.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,149 @@
+require_relative 'gemutilities'
+require 'rubygems/dependency'
+
+class TestGemDependency < RubyGemTestCase
+
+ def test_subclass
+ sc = Class.new Gem::Dependency
+ def sc.requirement() bogus; end
+
+ out, err = capture_io do
+ assert_equal Gem::Requirement.default, sc.new('a').version_requirement
+ end
+
+ assert_match %r%deprecated%, err
+ end
+
+ def test_initialize
+ d = dep "pkg", "> 1.0"
+
+ assert_equal "pkg", d.name
+ assert_equal req("> 1.0"), d.requirement
+ end
+
+ def test_initialize_double
+ d = dep "pkg", "> 1.0", "< 2.0"
+ assert_equal req("> 1.0", "< 2.0"), d.requirement
+ end
+
+ def test_initialize_empty
+ d = dep "pkg"
+ assert_equal req(">= 0"), d.requirement
+ end
+
+ def test_initialize_type
+ assert_equal :runtime, dep("pkg").type
+ assert_equal :development, dep("pkg", [], :development).type
+
+ assert_raises ArgumentError do
+ dep "pkg", :sometimes
+ end
+ end
+
+ def test_initialize_version
+ d = dep "pkg", v("2")
+ assert_equal req("= 2"), d.requirement
+ end
+
+ def test_equals2
+ o = dep "other"
+ d = dep "pkg", "> 1.0"
+ d1 = dep "pkg", "> 1.1"
+
+ assert_equal d, d.dup
+ assert_equal d.dup, d
+
+ refute_equal d, d1
+ refute_equal d1, d
+
+ refute_equal d, o
+ refute_equal o, d
+
+ refute_equal d, Object.new
+ refute_equal Object.new, d
+ end
+
+ def test_equals2_type
+ refute_equal dep("pkg", :runtime), dep("pkg", :development)
+ end
+
+ def test_equals_tilde
+ d = dep "a", "0"
+
+ assert_match d, d, "matche self"
+ assert_match dep("a", ">= 0"), d, "match version exact"
+ assert_match dep("a", ">= 0"), dep("a", "1"), "match version"
+ assert_match dep(/a/, ">= 0"), d, "match simple regexp"
+ assert_match dep(/a|b/, ">= 0"), d, "match scary regexp"
+
+ refute_match dep(/a/), dep("b")
+ refute_match dep("a"), Object.new
+ end
+
+ def test_equals_tilde_escape
+ refute_match dep("a|b"), dep("a", "1")
+ assert_match dep(/a|b/), dep("a", "1")
+ end
+
+ def test_equals_tilde_object
+ o = Object.new
+ def o.name ; 'a' end
+ def o.version ; '0' end
+
+ assert_match dep("a"), o
+ end
+
+ def test_equals_tilde_spec
+ assert_match dep("a", ">= 0"), spec("a", "0")
+ assert_match dep("a", "1"), spec("a", "1")
+ assert_match dep(/a/, ">= 0"), spec("a", "0")
+ assert_match dep(/a|b/, ">= 0"), spec("b", "0")
+ refute_match dep(/a/, ">= 0"), spec("b", "0")
+ end
+
+ def test_hash
+ d = dep "pkg", "1.0"
+
+ assert_equal d.hash, d.dup.hash
+ assert_equal d.dup.hash, d.hash
+
+ refute_equal dep("pkg", "1.0").hash, dep("pkg", "2.0").hash, "requirement"
+ refute_equal dep("pkg", "1.0").hash, dep("abc", "1.0").hash, "name"
+ refute_equal dep("pkg", :development), dep("pkg", :runtime), "type"
+ end
+
+ def test_prerelease_eh
+ d = dep "pkg", "= 1"
+
+ refute d.prerelease?
+
+ d.prerelease = true
+
+ assert d.prerelease?
+
+ d = dep "pkg", "= 1.a"
+
+ assert d.prerelease?
+
+ d.prerelease = false
+
+ assert d.prerelease?
+
+ d = dep "pkg", "> 1.a", "> 2"
+
+ assert d.prerelease?
+ end
+
+ def test_version_requirements_equals_deprecated
+ d = dep "pkg", "1.0"
+
+ out, err = capture_io do
+ d.version_requirements = '2.0'
+ assert_equal Gem::Requirement.new(%w[2.0]), d.requirement
+ end
+
+ assert_match %r%deprecated%, err
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_dependency_installer.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_dependency_installer.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_dependency_installer.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,678 @@
+require_relative 'gemutilities'
+require 'rubygems/dependency_installer'
+
+class TestGemDependencyInstaller < RubyGemTestCase
+
+ def setup
+ super
+
+ @gems_dir = File.join @tempdir, 'gems'
+ @cache_dir = File.join @gemhome, 'cache'
+ FileUtils.mkdir @gems_dir
+
+ write_file File.join('gems', 'a-1', 'bin', 'a_bin') do |fp|
+ fp.puts "#!/usr/bin/ruby"
+ end
+
+ @a1, @a1_gem = util_gem 'a', '1' do |s| s.executables << 'a_bin' end
+ @aa1, @aa1_gem = util_gem 'aa', '1'
+ @a1_pre, @a1_pre_gem = util_gem 'a', '1.a'
+
+ @b1, @b1_gem = util_gem 'b', '1' do |s|
+ s.add_dependency 'a'
+ s.add_development_dependency 'aa'
+ end
+
+ @b1_pre, @b1_pre_gem = util_gem 'b', '1.a' do |s|
+ s.add_dependency 'a'
+ s.add_development_dependency 'aa'
+ end
+
+ @c1_pre, @c1_pre_gem = util_gem 'c', '1.a' do |s|
+ s.add_dependency 'a', '1.a'
+ s.add_dependency 'b', '1'
+ end
+
+ @d1, @d1_gem = util_gem 'd', '1'
+ @d2, @d2_gem = util_gem 'd', '2'
+
+ @x1_m, @x1_m_gem = util_gem 'x', '1' do |s|
+ s.platform = Gem::Platform.new %w[cpu my_platform 1]
+ end
+
+ @x1_o, @x1_o_gem = util_gem 'x', '1' do |s|
+ s.platform = Gem::Platform.new %w[cpu other_platform 1]
+ end
+
+ @w1, @w1_gem = util_gem 'w', '1' do |s| s.add_dependency 'x' end
+
+ @y1, @y1_gem = util_gem 'y', '1'
+ @y1_1_p, @y1_1_p_gem = util_gem 'y', '1.1' do |s|
+ s.platform = Gem::Platform.new %w[cpu my_platform 1]
+ end
+
+ @z1, @z1_gem = util_gem 'z', '1' do |s| s.add_dependency 'y' end
+
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ si = util_setup_spec_fetcher(@a1, @a1_pre, @b1, @b1_pre, @c1_pre, @d1, @d2,
+ @x1_m, @x1_o, @w1, @y1, @y1_1_p, @z1)
+
+ util_clear_gems
+ end
+
+ def test_install
+ FileUtils.mv @a1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'a'
+ end
+
+ assert_equal Gem::SourceIndex.new(@a1.full_name => @a1),
+ Gem::SourceIndex.from_installed_gems
+
+ assert_equal [@a1], inst.installed_gems
+ end
+
+ def test_install_all_dependencies
+ e1, e1_gem = util_gem 'e', '1' do |s|
+ s.add_dependency 'b'
+ end
+
+ util_clear_gems
+
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+ FileUtils.mv e1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :ignore_dependencies => true
+ inst.install 'b'
+ end
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'e'
+ end
+
+ assert_equal %w[e-1 a-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_cache_dir
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :cache_dir => @tempdir
+ inst.install 'b'
+ end
+
+ assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
+
+ assert File.exist?(File.join(@tempdir, 'cache', @a1.file_name))
+ assert File.exist?(File.join(@tempdir, 'cache', @b1.file_name))
+ end
+
+ def test_install_dependencies_satisfied
+ a2, a2_gem = util_gem 'a', '2'
+
+ FileUtils.rm_rf File.join(@gemhome, 'gems')
+ Gem.source_index.refresh!
+
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv a2_gem, @tempdir # not in index
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'a-2'
+ end
+
+ FileUtils.rm File.join(@tempdir, a2.file_name)
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'b'
+ end
+
+ installed = Gem::SourceIndex.from_installed_gems.map { |n,s| s.full_name }
+
+ assert_equal %w[a-2 b-1], installed.sort
+
+ assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_dependency
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'b'
+ end
+
+ assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_dependency_development
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @aa1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new(:development => true)
+ inst.install 'b'
+ end
+
+ assert_equal %w[a-1 aa-1 b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_dependency_existing
+ Gem::Installer.new(@a1_gem).install
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'b'
+ end
+
+ assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_dependency_old
+ e1, e1_gem = util_gem 'e', '1'
+ f1, f1_gem = util_gem 'f', '1' do |s| s.add_dependency 'e' end
+ f2, f2_gem = util_gem 'f', '2'
+
+ FileUtils.mv e1_gem, @tempdir
+ FileUtils.mv f1_gem, @tempdir
+ FileUtils.mv f2_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'f'
+ end
+
+ assert_equal %w[f-2], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_local
+ FileUtils.mv @a1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :domain => :local
+ inst.install 'a-1.gem'
+ end
+
+ assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_local_dependency
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :domain => :local
+ inst.install 'b-1.gem'
+ end
+
+ assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_local_dependency_installed
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+
+ inst = nil
+
+ Dir.chdir @tempdir do
+ Gem::Installer.new('a-1.gem').install
+
+ inst = Gem::DependencyInstaller.new :domain => :local
+ inst.install 'b-1.gem'
+ end
+
+ assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_local_subdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :domain => :local
+ inst.install 'gems/a-1.gem'
+ end
+
+ assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_env_shebang
+ FileUtils.mv @a1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :env_shebang => true, :wrappers => true
+ inst.install 'a'
+ end
+
+ env = "/\\S+/env" unless Gem.win_platform?
+
+ assert_match %r|\A#!#{env} #{Gem::ConfigMap[:ruby_install_name]}\n|,
+ File.read(File.join(@gemhome, 'bin', 'a_bin'))
+ end
+
+ def test_install_force
+ FileUtils.mv @b1_gem, @tempdir
+ si = util_setup_spec_fetcher @b1
+ @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :force => true
+ inst.install 'b'
+ end
+
+ assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_ignore_dependencies
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :ignore_dependencies => true
+ inst.install 'b'
+ end
+
+ assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_install_dir
+ FileUtils.mv @a1_gem, @tempdir
+ gemhome2 = File.join @tempdir, 'gemhome2'
+ Dir.mkdir gemhome2
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :install_dir => gemhome2
+ inst.install 'a'
+ end
+
+ assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
+
+ assert File.exist?(File.join(gemhome2, 'specifications', @a1.spec_name))
+ assert File.exist?(File.join(gemhome2, 'cache', @a1.file_name))
+ end
+
+ def test_install_domain_both
+ a1_data = nil
+ File.open @a1_gem, 'rb' do |fp|
+ a1_data = fp.read
+ end
+
+ @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data
+
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :domain => :both
+ inst.install 'b'
+ end
+
+ assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
+ a1, b1 = inst.installed_gems
+
+ a1_expected = File.join(@gemhome, 'specifications', a1.spec_name)
+ b1_expected = File.join(@gemhome, 'specifications', b1.spec_name)
+
+ assert_equal a1_expected, a1.loaded_from
+ assert_equal b1_expected, b1.loaded_from
+ end
+
+ def test_install_domain_both_no_network
+ @fetcher.data["http://gems.example.com/gems/Marshal.#{@marshal_version}"] =
+ proc do
+ raise Gem::RemoteFetcher::FetchError
+ end
+
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :domain => :both
+ inst.install 'b'
+ end
+
+ assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_domain_local
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ Gem.source_index.remove_spec @a1.full_name
+ Gem.source_index.remove_spec @a1_pre.full_name
+
+ Dir.chdir @tempdir do
+ e = assert_raises Gem::InstallError do
+ inst = Gem::DependencyInstaller.new :domain => :local
+ inst.install 'b'
+ end
+
+ assert_equal 'b requires a (>= 0, runtime)', e.message
+ end
+
+ assert_equal [], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_domain_remote
+ a1_data = nil
+ File.open @a1_gem, 'rb' do |fp|
+ a1_data = fp.read
+ end
+
+ @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data
+
+ inst = Gem::DependencyInstaller.new :domain => :remote
+ inst.install 'a'
+
+ assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_dual_repository
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ gemhome2 = "#{@gemhome}2"
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :install_dir => gemhome2
+ inst.install 'a'
+ end
+
+ ENV['GEM_HOME'] = @gemhome
+ ENV['GEM_PATH'] = [@gemhome, gemhome2].join File::PATH_SEPARATOR
+ Gem.clear_paths
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'b'
+ end
+
+ assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_remote
+ a1_data = nil
+ File.open @a1_gem, 'rb' do |fp|
+ a1_data = fp.read
+ end
+
+ @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data
+
+ inst = Gem::DependencyInstaller.new
+
+ Dir.chdir @tempdir do
+ inst.install 'a'
+ end
+
+ assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_remote_dep
+ a1_data = nil
+ File.open @a1_gem, 'rb' do |fp|
+ a1_data = fp.read
+ end
+
+ @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data
+
+ inst = Gem::DependencyInstaller.new
+
+ Dir.chdir @tempdir do
+ dep = Gem::Dependency.new @a1.name, @a1.version
+ inst.install dep
+ end
+
+ assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_domain_remote_platform_newer
+ a2_o, a2_o_gem = util_gem 'a', '2' do |s|
+ s.platform = Gem::Platform.new %w[cpu other_platform 1]
+ end
+
+ util_clear_gems
+
+ si = util_setup_spec_fetcher @a1, a2_o
+
+ @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml
+
+ a1_data = nil
+ a2_o_data = nil
+
+ File.open @a1_gem, 'rb' do |fp| a1_data = fp.read end
+ File.open a2_o_gem, 'rb' do |fp| a2_o_data = fp.read end
+
+ @fetcher.data["http://gems.example.com/gems/#{@a1.file_name}"] =
+ a1_data
+ @fetcher.data["http://gems.example.com/gems/#{a2_o.file_name}"] =
+ a2_o_data
+
+ inst = Gem::DependencyInstaller.new :domain => :remote
+ inst.install 'a'
+
+ assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_reinstall
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ Gem::Installer.new(@a1_gem).install
+ FileUtils.mv @a1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'a'
+ end
+
+ assert_equal Gem::SourceIndex.new(@a1.full_name => @a1),
+ Gem::SourceIndex.from_installed_gems
+
+ assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ if defined? OpenSSL then
+ def test_install_security_policy
+ data = File.open(@a1_gem, 'rb') { |f| f.read }
+ @fetcher.data['http://gems.example.com/gems/a-1.gem'] = data
+
+ data = File.open(@b1_gem, 'rb') { |f| f.read }
+ @fetcher.data['http://gems.example.com/gems/b-1.gem'] = data
+
+ policy = Gem::Security::HighSecurity
+ inst = Gem::DependencyInstaller.new :security_policy => policy
+
+ e = assert_raises Gem::Exception do
+ inst.install 'b'
+ end
+
+ assert_equal 'Unsigned gem', e.message
+
+ assert_equal %w[], inst.installed_gems.map { |s| s.full_name }
+ end
+ end
+
+ # Wrappers don't work on mswin
+ unless win_platform? then
+ def test_install_no_wrappers
+ @fetcher.data['http://gems.example.com/gems/a-1.gem'] = read_binary(@a1_gem)
+
+ inst = Gem::DependencyInstaller.new :wrappers => false
+ inst.install 'a'
+
+ refute_match(%r|This file was generated by RubyGems.|,
+ File.read(File.join(@gemhome, 'bin', 'a_bin')))
+ end
+ end
+
+ def test_install_version
+ data = File.open(@d2_gem, 'rb') { |f| f.read }
+ @fetcher.data['http://gems.example.com/gems/d-2.gem'] = data
+
+ data = File.open(@d1_gem, 'rb') { |f| f.read }
+ @fetcher.data['http://gems.example.com/gems/d-1.gem'] = data
+
+ inst = Gem::DependencyInstaller.new
+
+ inst.install 'd', '= 1'
+
+ assert_equal %w[d-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_version_default
+ data = File.open(@d2_gem, 'rb') { |f| f.read }
+ @fetcher.data['http://gems.example.com/gems/d-2.gem'] = data
+
+ data = File.open(@d1_gem, 'rb') { |f| f.read }
+ @fetcher.data['http://gems.example.com/gems/d-1.gem'] = data
+
+ inst = Gem::DependencyInstaller.new
+ inst.install 'd'
+
+ assert_equal %w[d-2], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_find_gems_gems_with_sources
+ inst = Gem::DependencyInstaller.new
+ dep = Gem::Dependency.new 'b', '>= 0'
+
+ assert_equal [[@b1, @gem_repo]],
+ inst.find_gems_with_sources(dep)
+ end
+
+ def test_find_gems_with_sources_local
+ FileUtils.mv @a1_gem, @tempdir
+ inst = Gem::DependencyInstaller.new
+ dep = Gem::Dependency.new 'a', '>= 0'
+ gems = nil
+
+ Dir.chdir @tempdir do
+ gems = inst.find_gems_with_sources dep
+ end
+
+ assert_equal 2, gems.length
+ remote = gems.first
+ assert_equal 'a-1', remote.first.full_name, 'remote spec'
+ assert_equal @gem_repo, remote.last, 'remote path'
+
+ local = gems.last
+ assert_equal 'a-1', local.first.full_name, 'local spec'
+ assert_equal File.join(@tempdir, @a1.file_name),
+ local.last, 'local path'
+ end
+
+ def test_find_gems_with_sources_prerelease
+ installer = Gem::DependencyInstaller.new
+
+ dependency = Gem::Dependency.new('a', Gem::Requirement.default)
+
+ releases =
+ installer.find_gems_with_sources(dependency).map { |gems, *| gems }
+
+ assert releases.any? { |s| s.name == 'a' and s.version.to_s == '1' }
+ refute releases.any? { |s| s.name == 'a' and s.version.to_s == '1.a' }
+
+ dependency.prerelease = true
+
+ prereleases =
+ installer.find_gems_with_sources(dependency).map { |gems, *| gems }
+
+ assert_equal [@a1_pre], prereleases
+ end
+
+ def test_gather_dependencies
+ inst = Gem::DependencyInstaller.new
+ inst.find_spec_by_name_and_version 'b'
+ inst.gather_dependencies
+
+ assert_equal %w[a-1 b-1], inst.gems_to_install.map { |s| s.full_name }
+ end
+
+ def test_gather_dependencies_dropped
+ b2, = util_gem 'b', '2'
+ c1, = util_gem 'c', '1' do |s| s.add_dependency 'b' end
+
+ util_clear_gems
+
+ si = util_setup_spec_fetcher @a1, @b1, b2, c1
+
+ inst = Gem::DependencyInstaller.new
+ inst.find_spec_by_name_and_version 'c'
+ inst.gather_dependencies
+
+ assert_equal %w[b-2 c-1], inst.gems_to_install.map { |s| s.full_name }
+ end
+
+ def test_gather_dependencies_platform_alternate
+ util_set_arch 'cpu-my_platform1'
+
+ inst = Gem::DependencyInstaller.new
+ inst.find_spec_by_name_and_version 'w'
+ inst.gather_dependencies
+
+ assert_equal %w[x-1-cpu-my_platform-1 w-1],
+ inst.gems_to_install.map { |s| s.full_name }
+ end
+
+ def test_gather_dependencies_platform_bump
+ inst = Gem::DependencyInstaller.new
+ inst.find_spec_by_name_and_version 'z'
+ inst.gather_dependencies
+
+ assert_equal %w[y-1 z-1], inst.gems_to_install.map { |s| s.full_name }
+ end
+
+ def test_gather_dependencies_prerelease
+ inst = Gem::DependencyInstaller.new :prerelease => true
+ inst.find_spec_by_name_and_version 'c', '1.a'
+ inst.gather_dependencies
+
+ assert_equal %w[a-1.a b-1 c-1.a],
+ inst.gems_to_install.map { |s| s.full_name }
+ end
+
+ def test_gather_dependencies_old_required
+ e1, = util_gem 'e', '1' do |s| s.add_dependency 'd', '= 1' end
+
+ util_clear_gems
+
+ si = util_setup_spec_fetcher @d1, @d2, e1
+
+ inst = Gem::DependencyInstaller.new
+ inst.find_spec_by_name_and_version 'e'
+ inst.gather_dependencies
+
+ assert_equal %w[d-1 e-1], inst.gems_to_install.map { |s| s.full_name }
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_dependency_list.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_dependency_list.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_dependency_list.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,230 @@
+require_relative 'gemutilities'
+require 'rubygems/dependency_list'
+
+class TestGemDependencyList < RubyGemTestCase
+
+ def setup
+ super
+
+ @deplist = Gem::DependencyList.new
+
+ @a1 = quick_gem 'a', '1'
+ @a2 = quick_gem 'a', '2'
+ @a3 = quick_gem 'a', '3'
+
+ @b1 = quick_gem 'b', '1' do |s| s.add_dependency 'a', '>= 1' end
+ @b2 = quick_gem 'b', '2' do |s| s.add_dependency 'a', '>= 1' end
+
+ @c1 = quick_gem 'c', '1' do |s| s.add_dependency 'b', '>= 1' end
+ @c2 = quick_gem 'c', '2'
+
+ @d1 = quick_gem 'd', '1' do |s| s.add_dependency 'c', '>= 1' end
+ end
+
+ def test_self_from_source_index
+ hash = {
+ 'a-1' => @a1,
+ 'b-2' => @b2,
+ }
+
+ si = Gem::SourceIndex.new hash
+ deps = Gem::DependencyList.from_source_index si
+
+ assert_equal %w[b-2 a-1], deps.dependency_order.map { |s| s.full_name }
+ end
+
+ def test_active_count
+ assert_equal 0, @deplist.send(:active_count, [], {})
+ assert_equal 1, @deplist.send(:active_count, [@a1], {})
+ assert_equal 0, @deplist.send(:active_count, [@a1],
+ { @a1.full_name => true })
+ end
+
+ def test_add
+ assert_equal [], @deplist.dependency_order
+
+ @deplist.add @a1, @b2
+
+ assert_equal [@b2, @a1], @deplist.dependency_order
+ end
+
+ def test_dependency_order
+ @deplist.add @a1, @b1, @c1, @d1
+
+ order = @deplist.dependency_order
+
+ assert_equal %w[d-1 c-1 b-1 a-1], order.map { |s| s.full_name }
+ end
+
+ def test_dependency_order_circle
+ @a1.add_dependency 'c', '>= 1'
+ @deplist.add @a1, @b1, @c1
+
+ order = @deplist.dependency_order
+
+ assert_equal %w[b-1 c-1 a-1], order.map { |s| s.full_name }
+ end
+
+ def test_dependency_order_development
+ e1 = quick_gem 'e', '1'
+ f1 = quick_gem 'f', '1'
+ g1 = quick_gem 'g', '1'
+
+ @a1.add_dependency 'e'
+ @a1.add_dependency 'f'
+ @a1.add_dependency 'g'
+ g1.add_development_dependency 'a'
+
+ deplist = Gem::DependencyList.new true
+ deplist.add @a1, e1, f1, g1
+
+ order = deplist.dependency_order
+
+ assert_equal %w[g-1 a-1 f-1 e-1], order.map { |s| s.full_name },
+ 'development on'
+
+ deplist2 = Gem::DependencyList.new
+ deplist2.add @a1, e1, f1, g1
+
+ order = deplist2.dependency_order
+
+ assert_equal %w[a-1 g-1 f-1 e-1], order.map { |s| s.full_name },
+ 'development off'
+ end
+
+ def test_dependency_order_diamond
+ util_diamond
+ e1 = quick_gem 'e', '1'
+ @deplist.add e1
+ @a1.add_dependency 'e', '>= 1'
+
+ order = @deplist.dependency_order
+
+ assert_equal %w[d-1 c-2 b-1 a-2 e-1], order.map { |s| s.full_name },
+ 'deps of trimmed specs not included'
+ end
+
+ def test_dependency_order_no_dependendencies
+ @deplist.add @a1, @c2
+
+ order = @deplist.dependency_order
+
+ assert_equal %w[c-2 a-1], order.map { |s| s.full_name }
+ end
+
+ def test_find_name
+ @deplist.add @a1, @b2
+
+ assert_equal "a-1", @deplist.find_name("a-1").full_name
+ assert_equal "b-2", @deplist.find_name("b-2").full_name
+
+ assert_nil @deplist.find_name("c-2")
+ end
+
+ def test_ok_eh
+ assert @deplist.ok?, 'no dependencies'
+
+ @deplist.add @b2
+
+ refute @deplist.ok?, 'unsatisfied dependency'
+
+ @deplist.add @a1
+
+ assert @deplist.ok?, 'satisfied dependency'
+ end
+
+ def test_ok_eh_mismatch
+ a1 = quick_gem 'a', '1'
+ a2 = quick_gem 'a', '2'
+
+ b = quick_gem 'b', '1' do |s| s.add_dependency 'a', '= 1' end
+ c = quick_gem 'c', '1' do |s| s.add_dependency 'a', '= 2' end
+
+ d = quick_gem 'd', '1' do |s|
+ s.add_dependency 'b'
+ s.add_dependency 'c'
+ end
+
+ @deplist.add a1, a2, b, c, d
+
+ assert @deplist.ok?, 'this will break on require'
+ end
+
+ def test_ok_eh_redundant
+ @deplist.add @a1, @a3, @b2
+
+ @deplist.remove_by_name("a-1")
+
+ assert @deplist.ok?
+ end
+
+ def test_ok_to_remove_eh
+ @deplist.add @a1
+
+ assert @deplist.ok_to_remove?("a-1")
+
+ @deplist.add @b2
+
+ refute @deplist.ok_to_remove?("a-1")
+
+ @deplist.add @a2
+
+ assert @deplist.ok_to_remove?("a-1")
+ assert @deplist.ok_to_remove?("a-2")
+ assert @deplist.ok_to_remove?("b-2")
+ end
+
+ def test_ok_to_remove_eh_after_sibling_removed
+ @deplist.add @a1, @a2, @b2
+
+ assert @deplist.ok_to_remove?("a-1")
+ assert @deplist.ok_to_remove?("a-2")
+
+ @deplist.remove_by_name("a-1")
+
+ refute @deplist.ok_to_remove?("a-2")
+ end
+
+ def test_remove_by_name
+ @deplist.add @a1, @b2
+
+ @deplist.remove_by_name "a-1"
+
+ refute @deplist.ok?
+ end
+
+ def test_tsort_each_node
+ util_diamond
+
+ order = %w[a-1 a-2 b-1 c-2 d-1]
+
+ @deplist.tsort_each_node do |node|
+ assert_equal order.shift, node.full_name
+ end
+
+ assert_empty order
+ end
+
+ def test_tsort_each_child
+ util_diamond
+
+ order = %w[a-2]
+
+ @deplist.tsort_each_child(@b1) do |node|
+ assert_equal order.shift, node.full_name
+ end
+
+ assert_empty order
+ end
+
+ # d1 -> b1 -> a1
+ # d1 -> c2 -> a2
+ def util_diamond
+ @c2.add_dependency 'a', '>= 2'
+ @d1.add_dependency 'b'
+
+ @deplist.add @a1, @a2, @b1, @c2, @d1
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_doc_manager.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_doc_manager.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_doc_manager.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,31 @@
+require_relative 'gemutilities'
+require 'rubygems/doc_manager'
+
+class TestGemDocManager < RubyGemTestCase
+
+ def setup
+ super
+
+ @spec = quick_gem 'a'
+ @manager = Gem::DocManager.new(@spec)
+ end
+
+ def test_uninstall_doc_unwritable
+ orig_mode = File.stat(@spec.installation_path).mode
+
+ # File.chmod has no effect on MS Windows directories (it needs ACL).
+ if win_platform?
+ skip("test_uninstall_doc_unwritable skipped on MS Windows")
+ else
+ File.chmod(0, @spec.installation_path)
+ end
+
+ assert_raises Gem::FilePermissionError do
+ @manager.uninstall_doc
+ end
+ ensure
+ File.chmod orig_mode, @spec.installation_path
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_ext_configure_builder.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_ext_configure_builder.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_ext_configure_builder.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,84 @@
+require_relative 'gemutilities'
+require 'rubygems/ext'
+
+class TestGemExtConfigureBuilder < RubyGemTestCase
+
+ def setup
+ super
+
+ @makefile_body = "all:\n\t at echo ok\ninstall:\n\t at echo ok"
+
+ @ext = File.join @tempdir, 'ext'
+ @dest_path = File.join @tempdir, 'prefix'
+
+ FileUtils.mkdir_p @ext
+ FileUtils.mkdir_p @dest_path
+ end
+
+ def test_self_build
+ skip("test_self_build skipped on MS Windows (VC++)") if vc_windows?
+
+ File.open File.join(@ext, './configure'), 'w' do |configure|
+ configure.puts "#!/bin/sh\necho \"#{@makefile_body}\" > Makefile"
+ end
+
+ output = []
+
+ Dir.chdir @ext do
+ Gem::Ext::ConfigureBuilder.build nil, nil, @dest_path, output
+ end
+
+ assert_equal "sh ./configure --prefix=#{@dest_path}", output.shift
+ assert_equal "", output.shift
+ assert_equal make_command, output.shift
+ assert_match(/^ok$/m, output.shift)
+ assert_equal make_command + " install", output.shift
+ assert_match(/^ok$/m, output.shift)
+ end
+
+ def test_self_build_fail
+ skip("test_self_build_fail skipped on MS Windows (VC++)") if vc_windows?
+ output = []
+
+ error = assert_raises Gem::InstallError do
+ Dir.chdir @ext do
+ Gem::Ext::ConfigureBuilder.build nil, nil, @dest_path, output
+ end
+ end
+
+ shell_error_msg = %r{(\./configure: .*)|(Can't open \./configure(?:: No such file or directory)?)}
+ sh_prefix_configure = "sh ./configure --prefix="
+
+ expected = %r(configure failed:
+
+#{Regexp.escape sh_prefix_configure}#{Regexp.escape @dest_path}
+.*?: #{shell_error_msg}
+)
+
+ assert_match expected, error.message
+
+ assert_equal "#{sh_prefix_configure}#{@dest_path}", output.shift
+ assert_match %r(#{shell_error_msg}), output.shift
+ assert_equal true, output.empty?
+ end
+
+ def test_self_build_has_makefile
+ if vc_windows? && !nmake_found?
+ skip("test_self_build_has_makefile skipped - nmake not found")
+ end
+
+ File.open File.join(@ext, 'Makefile'), 'w' do |makefile|
+ makefile.puts @makefile_body
+ end
+
+ output = []
+ Dir.chdir @ext do
+ Gem::Ext::ConfigureBuilder.build nil, nil, @dest_path, output
+ end
+
+ assert_equal make_command, output[0]
+ assert_equal "#{make_command} install", output[2]
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_ext_ext_conf_builder.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_ext_ext_conf_builder.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_ext_ext_conf_builder.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,121 @@
+require_relative 'gemutilities'
+require 'rubygems/ext'
+
+class TestGemExtExtConfBuilder < RubyGemTestCase
+
+ def setup
+ super
+
+ @ext = File.join @tempdir, 'ext'
+ @dest_path = File.join @tempdir, 'prefix'
+
+ FileUtils.mkdir_p @ext
+ FileUtils.mkdir_p @dest_path
+ end
+
+ def test_class_build
+ if vc_windows? && !nmake_found?
+ skip("test_class_build skipped - nmake not found")
+ end
+
+ File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf|
+ extconf.puts "require 'mkmf'\ncreate_makefile 'foo'"
+ end
+
+ output = []
+
+ Dir.chdir @ext do
+ Gem::Ext::ExtConfBuilder.build 'extconf.rb', nil, @dest_path, output
+ end
+
+ expected = [
+ "ruby extconf.rb",
+ "creating Makefile\n",
+ "make",
+ "make: Nothing to be done for `all'.\n",
+ "make install",
+ "make: Nothing to be done for `install'.\n"
+ ]
+
+ assert_match(/^#{Gem.ruby} extconf.rb/, output[0])
+ assert_equal "creating Makefile\n", output[1]
+ assert_equal make_command, output[2]
+ assert_equal make_command + " install", output[4]
+ end
+
+ def test_class_build_extconf_fail
+ if vc_windows? && !nmake_found?
+ skip("test_class_build_extconf_fail skipped - nmake not found")
+ end
+
+ File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf|
+ extconf.puts "require 'mkmf'"
+ extconf.puts "have_library 'nonexistent' or abort 'need libnonexistent'"
+ extconf.puts "create_makefile 'foo'"
+ end
+
+ output = []
+
+ error = assert_raises Gem::InstallError do
+ Dir.chdir @ext do
+ Gem::Ext::ExtConfBuilder.build 'extconf.rb', nil, @dest_path, output
+ end
+ end
+
+ assert_match(/\Aextconf failed:
+
+#{Gem.ruby} extconf.rb.*
+checking for main\(\) in .*?nonexistent/m, error.message)
+
+ assert_match(/^#{Gem.ruby} extconf.rb/, output[0])
+ end
+
+ def test_class_make
+ if vc_windows? && !nmake_found?
+ skip("test_class_make skipped - nmake not found")
+ end
+
+ output = []
+ makefile_path = File.join(@ext, 'Makefile')
+ File.open makefile_path, 'w' do |makefile|
+ makefile.puts "RUBYARCHDIR = $(foo)$(target_prefix)"
+ makefile.puts "RUBYLIBDIR = $(bar)$(target_prefix)"
+ makefile.puts "all:"
+ makefile.puts "install:"
+ end
+
+ Dir.chdir @ext do
+ Gem::Ext::ExtConfBuilder.make @ext, output
+ end
+
+ assert_equal make_command, output[0]
+ assert_equal "#{make_command} install", output[2]
+
+ edited_makefile = <<-EOF
+RUBYARCHDIR = #{@ext}$(target_prefix)
+RUBYLIBDIR = #{@ext}$(target_prefix)
+all:
+install:
+ EOF
+
+ assert_equal edited_makefile, File.read(makefile_path)
+ end
+
+ def test_class_make_no_Makefile
+ error = assert_raises Gem::InstallError do
+ Dir.chdir @ext do
+ Gem::Ext::ExtConfBuilder.make @ext, ['output']
+ end
+ end
+
+ expected = <<-EOF.strip
+Makefile not found:
+
+output
+ EOF
+
+ assert_equal expected, error.message
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_ext_rake_builder.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_ext_rake_builder.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_ext_rake_builder.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,81 @@
+require_relative 'gemutilities'
+require 'rubygems/ext'
+
+class TestGemExtRakeBuilder < RubyGemTestCase
+ def setup
+ super
+
+ @ext = File.join @tempdir, 'ext'
+ @dest_path = File.join @tempdir, 'prefix'
+
+ FileUtils.mkdir_p @ext
+ FileUtils.mkdir_p @dest_path
+ end
+
+ def test_class_build
+ File.open File.join(@ext, 'mkrf_conf.rb'), 'w' do |mkrf_conf|
+ mkrf_conf.puts <<-EO_MKRF
+ File.open("Rakefile","w") do |f|
+ f.puts "task :default"
+ end
+ EO_MKRF
+ end
+
+ output = []
+ realdir = nil # HACK /tmp vs. /private/tmp
+
+ build_rake_in do
+ Dir.chdir @ext do
+ realdir = Dir.pwd
+ Gem::Ext::RakeBuilder.build 'mkrf_conf.rb', nil, @dest_path, output
+ end
+ end
+
+ output = output.join "\n"
+
+ expected = [
+ "#{@@ruby} mkrf_conf.rb",
+ "",
+ "#{@@rake} RUBYARCHDIR=#{@dest_path} RUBYLIBDIR=#{@dest_path}",
+ "(in #{realdir})\n"
+ ]
+
+ refute_match %r%^rake failed:%, output
+ assert_match %r%^#{Regexp.escape @@ruby} mkrf_conf\.rb%, output
+ assert_match %r%^#{Regexp.escape @@rake} RUBYARCHDIR=#{Regexp.escape @dest_path} RUBYLIBDIR=#{Regexp.escape @dest_path}%, output
+ end
+
+ def test_class_build_fail
+ File.open File.join(@ext, 'mkrf_conf.rb'), 'w' do |mkrf_conf|
+ mkrf_conf.puts <<-EO_MKRF
+ File.open("Rakefile","w") do |f|
+ f.puts "task :default do abort 'fail' end"
+ end
+ EO_MKRF
+ end
+
+ output = []
+
+ error = assert_raises Gem::InstallError do
+ build_rake_in do
+ Dir.chdir @ext do
+ Gem::Ext::RakeBuilder.build "mkrf_conf.rb", nil, @dest_path, output
+ end
+ end
+ end
+
+ expected = <<-EOF.strip
+rake failed:
+
+#{@@ruby} mkrf_conf.rb
+
+#{@@rake} RUBYARCHDIR=#{@dest_path} RUBYLIBDIR=#{@dest_path}
+ EOF
+
+ assert_match %r%^rake failed:%, error.message
+ assert_match %r%^#{Regexp.escape @@ruby} mkrf_conf\.rb%, error.message
+ assert_match %r%^#{Regexp.escape @@rake} RUBYARCHDIR=#{Regexp.escape @dest_path} RUBYLIBDIR=#{Regexp.escape @dest_path}%, error.message
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_format.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_format.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_format.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,70 @@
+require_relative 'gemutilities'
+require_relative 'simple_gem'
+require 'rubygems/format'
+
+class TestGemFormat < RubyGemTestCase
+
+ def setup
+ super
+
+ @simple_gem = SIMPLE_GEM
+ end
+
+ def test_class_from_file_by_path
+ util_make_gems
+
+ gems = Dir[File.join(@gemhome, 'cache', '*.gem')]
+
+ names = [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2, @pl1].map do |spec|
+ spec.original_name
+ end
+
+ gems_n_names = gems.sort.zip names
+
+ gems_n_names.each do |gemfile, name|
+ spec = Gem::Format.from_file_by_path(gemfile).spec
+
+ assert_equal name, spec.original_name
+ end
+ end
+
+ def test_class_from_file_by_path_empty
+ util_make_gems
+
+ empty_gem = File.join @tempdir, 'empty.gem'
+ FileUtils.touch empty_gem
+
+ assert_nil Gem::Format.from_file_by_path(empty_gem)
+ end
+
+ def test_class_from_file_by_path_nonexistent
+ assert_raises Gem::Exception do
+ Gem::Format.from_file_by_path '/nonexistent'
+ end
+ end
+
+ def test_class_from_io_garbled
+ e = assert_raises Gem::Package::FormatError do
+ # subtly bogus input
+ Gem::Format.from_io(StringIO.new(@simple_gem.upcase))
+ end
+
+ assert_equal 'No metadata found!', e.message
+
+ e = assert_raises Gem::Package::FormatError do
+ # Totally bogus input
+ Gem::Format.from_io(StringIO.new(@simple_gem.reverse))
+ end
+
+ assert_equal 'No metadata found!', e.message
+
+ e = assert_raises Gem::Package::FormatError do
+ # This was intentionally screws up YAML parsing.
+ Gem::Format.from_io(StringIO.new(@simple_gem.gsub(/:/, "boom")))
+ end
+
+ assert_equal 'No metadata found!', e.message
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_gem_path_searcher.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_gem_path_searcher.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_gem_path_searcher.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,78 @@
+require_relative 'gemutilities'
+require 'rubygems/gem_path_searcher'
+
+class Gem::GemPathSearcher
+ attr_accessor :gemspecs
+ attr_accessor :lib_dirs
+end
+
+class TestGemGemPathSearcher < RubyGemTestCase
+
+ def setup
+ super
+
+ @foo1 = quick_gem 'foo', '0.1' do |s|
+ s.require_paths << 'lib2'
+ s.files << 'lib/foo.rb'
+ end
+
+ path = File.join 'gems', @foo1.full_name, 'lib', 'foo.rb'
+ write_file(path) { |fp| fp.puts "# #{path}" }
+
+ @foo2 = quick_gem 'foo', '0.2'
+ @bar1 = quick_gem 'bar', '0.1'
+ @bar2 = quick_gem 'bar', '0.2'
+ @nrp = quick_gem 'nil_require_paths', '0.1'
+ @nrp.require_paths = nil
+
+
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ Gem.source_index = util_setup_spec_fetcher @foo1, @foo2, @bar1, @bar2
+
+ @gps = Gem::GemPathSearcher.new
+ end
+
+ def test_find
+ assert_equal @foo1, @gps.find('foo')
+ end
+
+ def test_find_all
+ assert_equal [@foo1], @gps.find_all('foo')
+ end
+
+ def test_init_gemspecs
+ assert_equal [@bar2, @bar1, @foo2, @foo1], @gps.init_gemspecs
+ end
+
+ def test_lib_dirs_for
+ lib_dirs = @gps.lib_dirs_for(@foo1)
+ expected = File.join @gemhome, 'gems', @foo1.full_name, '{lib,lib2}'
+
+ assert_equal expected, lib_dirs
+ end
+
+ def test_lib_dirs_for_nil_require_paths
+ assert_nil @gps.lib_dirs_for(@nrp)
+ end
+
+ def test_matching_file_eh
+ refute @gps.matching_file?(@foo1, 'bar')
+ assert @gps.matching_file?(@foo1, 'foo')
+ end
+
+ def test_matching_files
+ assert_equal [], @gps.matching_files(@foo1, 'bar')
+
+ expected = File.join @foo1.full_gem_path, 'lib', 'foo.rb'
+
+ assert_equal [expected], @gps.matching_files(@foo1, 'foo')
+ end
+
+ def test_matching_files_nil_require_paths
+ assert_empty @gps.matching_files(@nrp, 'foo')
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_gem_runner.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_gem_runner.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_gem_runner.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,45 @@
+require_relative 'gemutilities'
+require 'rubygems/gem_runner'
+
+class TestGemGemRunner < RubyGemTestCase
+
+ def test_do_configuration
+ Gem.clear_paths
+
+ temp_conf = File.join @tempdir, '.gemrc'
+
+ other_gem_path = File.join @tempdir, 'other_gem_path'
+ other_gem_home = File.join @tempdir, 'other_gem_home'
+
+ Gem.ensure_gem_subdirectories other_gem_path
+ Gem.ensure_gem_subdirectories other_gem_home
+
+ File.open temp_conf, 'w' do |fp|
+ fp.puts "gem: --commands"
+ fp.puts "gemhome: #{other_gem_home}"
+ fp.puts "gempath:"
+ fp.puts " - #{other_gem_path}"
+ fp.puts "rdoc: --all"
+ end
+
+ gr = Gem::GemRunner.new
+ gr.send :do_configuration, %W[--config-file #{temp_conf}]
+
+ assert_equal [other_gem_path, other_gem_home], Gem.path
+ assert_equal %w[--commands], Gem::Command.extra_args
+ assert_equal %w[--all], Gem::DocManager.configured_args
+ end
+
+ def test_build_args__are_handled
+ Gem.clear_paths
+
+ gr = Gem::GemRunner.new
+ assert_raises(Gem::SystemExitException) do
+ gr.run(%W[--help -- --build_arg1 --build_arg2])
+ end
+
+ assert_equal %w[--build_arg1 --build_arg2], Gem::Command.build_args
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_gemcutter_utilities.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_gemcutter_utilities.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_gemcutter_utilities.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,103 @@
+require_relative 'gemutilities'
+require 'rubygems'
+require 'rubygems/gemcutter_utilities'
+
+class TestGemGemcutterUtilities < RubyGemTestCase
+
+ def setup
+ super
+
+ ENV['RUBYGEMS_HOST'] = nil
+ Gem.configuration.rubygems_api_key = nil
+
+ @cmd = Gem::Command.new '', 'summary'
+ @cmd.extend Gem::GemcutterUtilities
+ end
+
+ def test_sign_in
+ api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
+ util_sign_in [api_key, 200, 'OK']
+
+ assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
+ assert @fetcher.last_request["authorization"]
+ assert_match %r{Signed in.}, @sign_in_ui.output
+
+ credentials = YAML.load_file Gem.configuration.credentials_path
+ assert_equal api_key, credentials[:rubygems_api_key]
+ end
+
+ def test_sign_in_with_host
+ api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
+ util_sign_in [api_key, 200, 'OK'], 'http://example.com'
+
+ assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
+ assert @fetcher.last_request["authorization"]
+ assert_match %r{Signed in.}, @sign_in_ui.output
+
+ credentials = YAML.load_file Gem.configuration.credentials_path
+ assert_equal api_key, credentials[:rubygems_api_key]
+ end
+
+ def test_sign_in_skips_with_existing_credentials
+ api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
+ Gem.configuration.rubygems_api_key = api_key
+
+ util_sign_in [api_key, 200, 'OK']
+
+ assert_equal "", @sign_in_ui.output
+ end
+
+ def test_sign_in_with_other_credentials_doesnt_overwrite_other_keys
+ api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
+ other_api_key = 'f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf'
+
+ FileUtils.mkdir_p File.dirname(Gem.configuration.credentials_path)
+ open Gem.configuration.credentials_path, 'w' do |f|
+ f.write Hash[:other_api_key, other_api_key].to_yaml
+ end
+ util_sign_in [api_key, 200, 'OK']
+
+ assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
+ assert_match %r{Signed in.}, @sign_in_ui.output
+
+ credentials = YAML.load_file Gem.configuration.credentials_path
+ assert_equal api_key, credentials[:rubygems_api_key]
+ assert_equal other_api_key, credentials[:other_api_key]
+ end
+
+ def test_sign_in_with_bad_credentials
+ skip 'Always uses $stdin on windows' if Gem.win_platform?
+
+ assert_raises MockGemUi::TermError do
+ util_sign_in ['Access Denied.', 403, 'Forbidden']
+ end
+
+ assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
+ assert_match %r{Access Denied.}, @sign_in_ui.output
+ end
+
+ def util_sign_in response, host = nil
+ skip 'Always uses $stdin on windows' if Gem.win_platform?
+
+ email = 'you at example.com'
+ password = 'secret'
+
+ if host
+ ENV['RUBYGEMS_HOST'] = host
+ else
+ host = "https://rubygems.org"
+ end
+
+ @fetcher = Gem::FakeFetcher.new
+ @fetcher.data["#{host}/api/v1/api_key"] = response
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ @sign_in_ui = MockGemUi.new "#{email}\n#{password}\n"
+
+ use_ui @sign_in_ui do
+ @cmd.sign_in
+ end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_indexer.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_indexer.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_indexer.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,673 @@
+require_relative 'gemutilities'
+require 'rubygems/indexer'
+
+unless ''.respond_to? :to_xs then
+ warn "Gem::Indexer tests are being skipped. Install builder gem." if $VERBOSE
+end
+
+class TestGemIndexer < RubyGemTestCase
+
+ def setup
+ super
+
+ util_make_gems
+
+ @d2_0 = quick_gem 'd', '2.0' do |s|
+ s.date = Gem::Specification::TODAY - 86400 * 3
+ end
+ util_build_gem @d2_0
+
+ @d2_0_a = quick_gem 'd', '2.0.a'
+ util_build_gem @d2_0_a
+
+ @d2_0_b = quick_gem 'd', '2.0.b'
+ util_build_gem @d2_0_b
+
+ gems = File.join(@tempdir, 'gems')
+ FileUtils.mkdir_p gems
+ cache_gems = File.join @gemhome, 'cache', '*.gem'
+ FileUtils.mv Dir[cache_gems], gems
+
+ @indexer = Gem::Indexer.new @tempdir, :rss_title => 'ExampleForge gems',
+ :rss_host => 'example.com',
+ :rss_gems_host => 'gems.example.com'
+ end
+
+ def test_initialize
+ assert_equal @tempdir, @indexer.dest_directory
+ assert_equal File.join(Dir.tmpdir, "gem_generate_index_#{$$}"),
+ @indexer.directory
+
+ indexer = Gem::Indexer.new @tempdir
+ assert indexer.build_legacy
+ assert indexer.build_modern
+
+ indexer = Gem::Indexer.new @tempdir, :build_legacy => false,
+ :build_modern => true
+ refute indexer.build_legacy
+ assert indexer.build_modern
+
+ indexer = Gem::Indexer.new @tempdir, :build_legacy => true,
+ :build_modern => false
+ assert indexer.build_legacy
+ refute indexer.build_modern
+ end
+
+ def test_build_indicies
+ spec = quick_gem 'd', '2.0'
+ spec.instance_variable_set :@original_platform, ''
+
+ @indexer.make_temp_directories
+
+ index = Gem::SourceIndex.new
+ index.add_spec spec
+
+ use_ui @ui do
+ @indexer.build_indicies index
+ end
+
+ specs_path = File.join @indexer.directory, "specs.#{@marshal_version}"
+ specs_dump = Gem.read_binary specs_path
+ specs = Marshal.load specs_dump
+
+ expected = [
+ ['d', Gem::Version.new('2.0'), 'ruby'],
+ ]
+
+ assert_equal expected, specs, 'specs'
+
+ latest_specs_path = File.join @indexer.directory,
+ "latest_specs.#{@marshal_version}"
+ latest_specs_dump = Gem.read_binary latest_specs_path
+ latest_specs = Marshal.load latest_specs_dump
+
+ expected = [
+ ['d', Gem::Version.new('2.0'), 'ruby'],
+ ]
+
+ assert_equal expected, latest_specs, 'latest_specs'
+ end
+
+ def test_generate_index
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ assert_indexed @tempdir, 'yaml'
+ assert_indexed @tempdir, 'yaml.Z'
+ assert_indexed @tempdir, "Marshal.#{@marshal_version}"
+ assert_indexed @tempdir, "Marshal.#{@marshal_version}.Z"
+
+ quickdir = File.join @tempdir, 'quick'
+ marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
+
+ assert File.directory?(quickdir)
+ assert File.directory?(marshal_quickdir)
+
+ assert_indexed quickdir, "index"
+ assert_indexed quickdir, "index.rz"
+
+ quick_index = File.read File.join(quickdir, 'index')
+ expected = <<-EOF
+a-1
+a-2
+a-3.a
+a_evil-9
+b-2
+c-1.2
+d-2.0
+d-2.0.a
+d-2.0.b
+pl-1-i386-linux
+ EOF
+
+ assert_equal expected, quick_index
+
+ assert_indexed quickdir, "latest_index"
+ assert_indexed quickdir, "latest_index.rz"
+
+ latest_quick_index = File.read File.join(quickdir, 'latest_index')
+ expected = <<-EOF
+a-2
+a_evil-9
+b-2
+c-1.2
+d-2.0
+pl-1-i386-linux
+ EOF
+
+ assert_equal expected, latest_quick_index
+
+ assert_indexed quickdir, "#{@a1.spec_name}.rz"
+ assert_indexed quickdir, "#{@a2.spec_name}.rz"
+ assert_indexed quickdir, "#{@b2.spec_name}.rz"
+ assert_indexed quickdir, "#{@c1_2.spec_name}.rz"
+
+ assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz"
+ refute_indexed quickdir, "#{@pl1.spec_name}.rz"
+
+ assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
+ assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
+
+ refute_indexed quickdir, @c1_2.spec_name
+ refute_indexed marshal_quickdir, @c1_2.spec_name
+
+ assert_indexed @tempdir, "specs.#{@marshal_version}"
+ assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
+
+ assert_indexed @tempdir, "latest_specs.#{@marshal_version}"
+ assert_indexed @tempdir, "latest_specs.#{@marshal_version}.gz"
+
+ expected = <<-EOF
+<?xml version=\"1.0\"?>
+<rss version=\"2.0\">
+ <channel>
+ <title>ExampleForge gems</title>
+ <link>http://example.com</link>
+ <description>Recently released gems from http://example.com</description>
+ <generator>RubyGems v#{Gem::VERSION}</generator>
+ <docs>http://cyber.law.harvard.edu/rss/rss.html</docs>
+ <item>
+ <title>a-2</title>
+ <description>
+<pre>This is a test description</pre>
+ </description>
+ <author>example at example.com (A User)</author>
+ <guid>a-2</guid>
+ <enclosure url=\"http://gems.example.com/gems/a-2.gem\"
+ length=\"3072\" type=\"application/octet-stream\" />
+ <pubDate>#{@a2.date.rfc2822}</pubDate>
+ <link>http://example.com</link>
+ </item>
+ <item>
+ <title>a-3.a</title>
+ <description>
+<pre>This is a test description</pre>
+ </description>
+ <author>example at example.com (A User)</author>
+ <guid>a-3.a</guid>
+ <enclosure url=\"http://gems.example.com/gems/a-3.a.gem\"
+ length=\"3072\" type=\"application/octet-stream\" />
+ <pubDate>#{@a3a.date.rfc2822}</pubDate>
+ <link>http://example.com</link>
+ </item>
+ <item>
+ <title>a_evil-9</title>
+ <description>
+<pre>This is a test description</pre>
+ </description>
+ <author>example at example.com (A User)</author>
+ <guid>a_evil-9</guid>
+ <enclosure url=\"http://gems.example.com/gems/a_evil-9.gem\"
+ length=\"3072\" type=\"application/octet-stream\" />
+ <pubDate>#{@a_evil9.date.rfc2822}</pubDate>
+ <link>http://example.com</link>
+ </item>
+ <item>
+ <title>b-2</title>
+ <description>
+<pre>This is a test description</pre>
+ </description>
+ <author>example at example.com (A User)</author>
+ <guid>b-2</guid>
+ <enclosure url=\"http://gems.example.com/gems/b-2.gem\"
+ length=\"3072\" type=\"application/octet-stream\" />
+ <pubDate>#{@b2.date.rfc2822}</pubDate>
+ <link>http://example.com</link>
+ </item>
+ <item>
+ <title>c-1.2</title>
+ <description>
+<pre>This is a test description</pre>
+ </description>
+ <author>example at example.com (A User)</author>
+ <guid>c-1.2</guid>
+ <enclosure url=\"http://gems.example.com/gems/c-1.2.gem\"
+ length=\"3072\" type=\"application/octet-stream\" />
+ <pubDate>#{@c1_2.date.rfc2822}</pubDate>
+ <link>http://example.com</link>
+ </item>
+ <item>
+ <title>d-2.0.a</title>
+ <description>
+<pre>This is a test description</pre>
+ </description>
+ <author>example at example.com (A User)</author>
+ <guid>d-2.0.a</guid>
+ <enclosure url=\"http://gems.example.com/gems/d-2.0.a.gem\"
+ length=\"3072\" type=\"application/octet-stream\" />
+ <pubDate>#{@d2_0_a.date.rfc2822}</pubDate>
+ <link>http://example.com</link>
+ </item>
+ <item>
+ <title>d-2.0.b</title>
+ <description>
+<pre>This is a test description</pre>
+ </description>
+ <author>example at example.com (A User)</author>
+ <guid>d-2.0.b</guid>
+ <enclosure url=\"http://gems.example.com/gems/d-2.0.b.gem\"
+ length=\"3072\" type=\"application/octet-stream\" />
+ <pubDate>#{@d2_0_b.date.rfc2822}</pubDate>
+ <link>http://example.com</link>
+ </item>
+ <item>
+ <title>pl-1-x86-linux</title>
+ <description>
+<pre>This is a test description</pre>
+ </description>
+ <author>example at example.com (A User)</author>
+ <guid>pl-1-x86-linux</guid>
+ <enclosure url=\"http://gems.example.com/gems/pl-1-x86-linux.gem\"
+ length=\"3072\" type=\"application/octet-stream\" />
+ <pubDate>#{@pl1.date.rfc2822}</pubDate>
+ <link>http://example.com</link>
+ </item>
+ <item>
+ <title>a-1</title>
+ <description>
+<pre>This line is really, really long. So long, in fact, that it is more than
+eighty characters long! The purpose of this line is for testing wrapping
+behavior because sometimes people don't wrap their text to eighty characters.
+Without the wrapping, the text might not look good in the RSS feed.
+
+Also, a list:
+ * An entry that's actually kind of sort
+ * an entry that's really long, which will probably get wrapped funny.
+That's ok, somebody wasn't thinking straight when they made it more than
+eighty characters.</pre>
+ </description>
+ <author>example at example.com (Example), example2 at example.com (Example2)</author>
+ <guid>a-1</guid>
+ <enclosure url=\"http://gems.example.com/gems/a-1.gem\"
+ length=\"3584\" type=\"application/octet-stream\" />
+ <pubDate>#{@a1.date.rfc2822}</pubDate>
+ <link>http://a.example.com</link>
+ </item>
+ </channel>
+</rss>
+ EOF
+
+ gems_rss = File.read File.join(@tempdir, 'index.rss')
+
+ assert_equal expected, gems_rss
+ end
+
+ def test_generate_index_legacy
+ @indexer.build_modern = false
+ @indexer.build_legacy = true
+
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ assert_indexed @tempdir, 'yaml'
+ assert_indexed @tempdir, 'yaml.Z'
+ assert_indexed @tempdir, "Marshal.#{@marshal_version}"
+ assert_indexed @tempdir, "Marshal.#{@marshal_version}.Z"
+
+ quickdir = File.join @tempdir, 'quick'
+ marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
+
+ assert File.directory?(quickdir)
+ assert File.directory?(marshal_quickdir)
+
+ assert_indexed quickdir, "index"
+ assert_indexed quickdir, "index.rz"
+
+ assert_indexed quickdir, "latest_index"
+ assert_indexed quickdir, "latest_index.rz"
+
+ assert_indexed quickdir, "#{@a1.spec_name}.rz"
+ assert_indexed quickdir, "#{@a2.spec_name}.rz"
+ assert_indexed quickdir, "#{@b2.spec_name}.rz"
+ assert_indexed quickdir, "#{@c1_2.spec_name}.rz"
+
+ assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz"
+ refute_indexed quickdir, "#{@pl1.spec_name}.rz"
+
+ assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
+ assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
+
+ refute_indexed quickdir, "#{@c1_2.spec_name}"
+ refute_indexed marshal_quickdir, "#{@c1_2.spec_name}"
+
+ refute_indexed @tempdir, "specs.#{@marshal_version}"
+ refute_indexed @tempdir, "specs.#{@marshal_version}.gz"
+
+ refute_indexed @tempdir, "latest_specs.#{@marshal_version}"
+ refute_indexed @tempdir, "latest_specs.#{@marshal_version}.gz"
+ end
+
+ def test_generate_index_legacy_back_to_back
+ @indexer.build_modern = true
+ @indexer.build_legacy = true
+
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ @indexer = Gem::Indexer.new @tempdir
+ @indexer.build_modern = false
+ @indexer.build_legacy = true
+
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ assert_indexed @tempdir, 'yaml'
+ assert_indexed @tempdir, 'yaml.Z'
+ assert_indexed @tempdir, "Marshal.#{@marshal_version}"
+ assert_indexed @tempdir, "Marshal.#{@marshal_version}.Z"
+
+ quickdir = File.join @tempdir, 'quick'
+ marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
+
+ assert File.directory?(quickdir)
+ assert File.directory?(marshal_quickdir)
+
+ assert_indexed quickdir, "index"
+ assert_indexed quickdir, "index.rz"
+
+ assert_indexed quickdir, "latest_index"
+ assert_indexed quickdir, "latest_index.rz"
+
+ assert_indexed quickdir, "#{@a1.spec_name}.rz"
+ assert_indexed quickdir, "#{@a2.spec_name}.rz"
+ assert_indexed quickdir, "#{@b2.spec_name}.rz"
+ assert_indexed quickdir, "#{@c1_2.spec_name}.rz"
+
+ assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz"
+
+ assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
+ assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
+
+ assert_indexed @tempdir, "specs.#{@marshal_version}"
+ assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
+
+ assert_indexed @tempdir, "latest_specs.#{@marshal_version}"
+ assert_indexed @tempdir, "latest_specs.#{@marshal_version}.gz"
+ end
+
+ def test_generate_index_modern
+ @indexer.build_modern = true
+ @indexer.build_legacy = false
+
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ refute_indexed @tempdir, 'yaml'
+ refute_indexed @tempdir, 'yaml.Z'
+ refute_indexed @tempdir, "Marshal.#{@marshal_version}"
+ refute_indexed @tempdir, "Marshal.#{@marshal_version}.Z"
+
+ quickdir = File.join @tempdir, 'quick'
+ marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
+
+ assert File.directory?(quickdir), 'quickdir should be directory'
+ assert File.directory?(marshal_quickdir)
+
+ refute_indexed quickdir, "index"
+ refute_indexed quickdir, "index.rz"
+
+ refute_indexed quickdir, "latest_index"
+ refute_indexed quickdir, "latest_index.rz"
+
+ refute_indexed quickdir, "#{@a1.spec_name}.rz"
+ refute_indexed quickdir, "#{@a2.spec_name}.rz"
+ refute_indexed quickdir, "#{@b2.spec_name}.rz"
+ refute_indexed quickdir, "#{@c1_2.spec_name}.rz"
+
+ refute_indexed quickdir, "#{@pl1.original_name}.gemspec.rz"
+ refute_indexed quickdir, "#{@pl1.spec_name}.rz"
+
+ assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
+ assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
+
+ refute_indexed quickdir, "#{@c1_2.spec_name}"
+ refute_indexed marshal_quickdir, "#{@c1_2.spec_name}"
+
+ assert_indexed @tempdir, "specs.#{@marshal_version}"
+ assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
+
+ assert_indexed @tempdir, "latest_specs.#{@marshal_version}"
+ assert_indexed @tempdir, "latest_specs.#{@marshal_version}.gz"
+ end
+
+ def test_generate_index_modern_back_to_back
+ @indexer.build_modern = true
+ @indexer.build_legacy = true
+
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ @indexer = Gem::Indexer.new @tempdir
+ @indexer.build_modern = true
+ @indexer.build_legacy = false
+
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ assert_indexed @tempdir, 'yaml'
+ assert_indexed @tempdir, 'yaml.Z'
+ assert_indexed @tempdir, "Marshal.#{@marshal_version}"
+ assert_indexed @tempdir, "Marshal.#{@marshal_version}.Z"
+
+ quickdir = File.join @tempdir, 'quick'
+ marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
+
+ assert File.directory?(quickdir)
+ assert File.directory?(marshal_quickdir)
+
+ assert_indexed quickdir, "index"
+ assert_indexed quickdir, "index.rz"
+
+ assert_indexed quickdir, "latest_index"
+ assert_indexed quickdir, "latest_index.rz"
+
+ assert_indexed quickdir, "#{@a1.spec_name}.rz"
+ assert_indexed quickdir, "#{@a2.spec_name}.rz"
+ assert_indexed quickdir, "#{@b2.spec_name}.rz"
+ assert_indexed quickdir, "#{@c1_2.spec_name}.rz"
+
+ assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz"
+
+ assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
+ assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
+
+ assert_indexed @tempdir, "specs.#{@marshal_version}"
+ assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
+
+ assert_indexed @tempdir, "latest_specs.#{@marshal_version}"
+ assert_indexed @tempdir, "latest_specs.#{@marshal_version}.gz"
+ end
+
+ def test_generate_index_ui
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ assert_match %r%^Loading 10 gems from #{Regexp.escape @tempdir}$%,
+ @ui.output
+ assert_match %r%^\.\.\.\.\.\.\.\.\.\.$%, @ui.output
+ assert_match %r%^Loaded all gems$%, @ui.output
+ assert_match %r%^Generating Marshal quick index gemspecs for 10 gems$%,
+ @ui.output
+ assert_match %r%^Generating YAML quick index gemspecs for 10 gems$%,
+ @ui.output
+ assert_match %r%^Complete$%, @ui.output
+ assert_match %r%^Generating specs index$%, @ui.output
+ assert_match %r%^Generating latest specs index$%, @ui.output
+ assert_match %r%^Generating quick index$%, @ui.output
+ assert_match %r%^Generating latest index$%, @ui.output
+ assert_match %r%^Generating prerelease specs index$%, @ui.output
+ assert_match %r%^Generating Marshal master index$%, @ui.output
+ assert_match %r%^Generating YAML master index for 10 gems \(this may take a while\)$%, @ui.output
+ assert_match %r%^Complete$%, @ui.output
+ assert_match %r%^Compressing indicies$%, @ui.output
+
+ assert_equal '', @ui.error
+ end
+
+ def test_generate_index_master
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ yaml_path = File.join @tempdir, 'yaml'
+ dump_path = File.join @tempdir, "Marshal.#{@marshal_version}"
+
+ yaml_index = YAML.load_file yaml_path
+ dump_index = Marshal.load Gem.read_binary(dump_path)
+
+ dump_index.each do |_,gem|
+ gem.send :remove_instance_variable, :@loaded
+ end
+
+ assert_equal yaml_index, dump_index,
+ "expected YAML and Marshal to produce identical results"
+ end
+
+ def test_generate_index_specs
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ specs_path = File.join @tempdir, "specs.#{@marshal_version}"
+
+ specs_dump = Gem.read_binary specs_path
+ specs = Marshal.load specs_dump
+
+ expected = [
+ ['a', Gem::Version.new(1), 'ruby'],
+ ['a', Gem::Version.new(2), 'ruby'],
+ ['a_evil', Gem::Version.new(9), 'ruby'],
+ ['b', Gem::Version.new(2), 'ruby'],
+ ['c', Gem::Version.new('1.2'), 'ruby'],
+ ['d', Gem::Version.new('2.0'), 'ruby'],
+ ['pl', Gem::Version.new(1), 'i386-linux'],
+ ]
+
+ assert_equal expected, specs
+
+ assert_same specs[0].first, specs[1].first,
+ 'identical names not identical'
+
+ assert_same specs[0][1], specs[-1][1],
+ 'identical versions not identical'
+
+ assert_same specs[0].last, specs[1].last,
+ 'identical platforms not identical'
+
+ refute_same specs[1][1], specs[5][1],
+ 'different versions not different'
+ end
+
+ def test_generate_index_latest_specs
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ latest_specs_path = File.join @tempdir, "latest_specs.#{@marshal_version}"
+
+ latest_specs_dump = Gem.read_binary latest_specs_path
+ latest_specs = Marshal.load latest_specs_dump
+
+ expected = [
+ ['a', Gem::Version.new(2), 'ruby'],
+ ['a_evil', Gem::Version.new(9), 'ruby'],
+ ['b', Gem::Version.new(2), 'ruby'],
+ ['c', Gem::Version.new('1.2'), 'ruby'],
+ ['d', Gem::Version.new('2.0'), 'ruby'],
+ ['pl', Gem::Version.new(1), 'i386-linux'],
+ ]
+
+ assert_equal expected, latest_specs
+
+ assert_same latest_specs[0][1], latest_specs[2][1],
+ 'identical versions not identical'
+
+ assert_same latest_specs[0].last, latest_specs[1].last,
+ 'identical platforms not identical'
+ end
+
+ def test_generate_index_prerelease_specs
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ prerelease_specs_path = File.join @tempdir, "prerelease_specs.#{@marshal_version}"
+
+ prerelease_specs_dump = Gem.read_binary prerelease_specs_path
+ prerelease_specs = Marshal.load prerelease_specs_dump
+
+ assert_equal [['a', Gem::Version.new('3.a'), 'ruby'],
+ ['d', Gem::Version.new('2.0.a'), 'ruby'],
+ ['d', Gem::Version.new('2.0.b'), 'ruby']],
+ prerelease_specs
+ end
+
+ def test_update_index
+ use_ui @ui do
+ @indexer.generate_index
+ end
+
+ quickdir = File.join @tempdir, 'quick'
+ marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
+
+ assert File.directory?(quickdir)
+ assert File.directory?(marshal_quickdir)
+
+ @d2_1 = quick_gem 'd', '2.1'
+ util_build_gem @d2_1
+ @d2_1_tuple = [@d2_1.name, @d2_1.version, @d2_1.original_platform]
+
+ @d2_1_a = quick_gem 'd', '2.2.a'
+ util_build_gem @d2_1_a
+ @d2_1_a_tuple = [@d2_1_a.name, @d2_1_a.version, @d2_1_a.original_platform]
+
+ gems = File.join @tempdir, 'gems'
+ FileUtils.mv File.join(@gemhome, 'cache', @d2_1.file_name), gems
+ FileUtils.mv File.join(@gemhome, 'cache', @d2_1_a.file_name), gems
+
+ use_ui @ui do
+ @indexer.update_index
+ end
+
+ assert_indexed marshal_quickdir, "#{@d2_1.spec_name}.rz"
+
+ specs_index = Marshal.load Gem.read_binary(@indexer.dest_specs_index)
+
+ assert_includes specs_index, @d2_1_tuple
+ refute_includes specs_index, @d2_1_a_tuple
+
+ latest_specs_index = Marshal.load \
+ Gem.read_binary(@indexer.dest_latest_specs_index)
+
+ assert_includes latest_specs_index, @d2_1_tuple
+ assert_includes latest_specs_index,
+ [@d2_0.name, @d2_0.version, @d2_0.original_platform]
+ refute_includes latest_specs_index, @d2_1_a_tuple
+
+ pre_specs_index = Marshal.load \
+ Gem.read_binary(@indexer.dest_prerelease_specs_index)
+
+ assert_includes pre_specs_index, @d2_1_a_tuple
+ refute_includes pre_specs_index, @d2_1_tuple
+ end
+
+ def assert_indexed(dir, name)
+ file = File.join dir, name
+ assert File.exist?(file), "#{file} does not exist"
+ end
+
+ def refute_indexed(dir, name)
+ file = File.join dir, name
+ refute File.exist?(file), "#{file} exists"
+ end
+
+end if ''.respond_to? :to_xs
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_install_update_options.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_install_update_options.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_install_update_options.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,68 @@
+require_relative 'gem_installer_test_case'
+require 'rubygems/install_update_options'
+require 'rubygems/command'
+
+class TestGemInstallUpdateOptions < GemInstallerTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Command.new 'dummy', 'dummy'
+ @cmd.extend Gem::InstallUpdateOptions
+ @cmd.add_install_update_options
+ end
+
+ def test_add_install_update_options
+ args = %w[-i /install_to --rdoc --ri -E -f -t -w -P HighSecurity
+ --ignore-dependencies --format-exec --include-dependencies]
+
+ assert @cmd.handles?(args)
+ end
+
+ def test_security_policy
+ @cmd.handle_options %w[-P HighSecurity]
+
+ assert_equal Gem::Security::HighSecurity, @cmd.options[:security_policy]
+ end
+
+ def test_security_policy_unknown
+ @cmd.add_install_update_options
+
+ assert_raises OptionParser::InvalidArgument do
+ @cmd.handle_options %w[-P UnknownSecurity]
+ end
+ end
+
+ def test_user_install_enabled
+ @cmd.handle_options %w[--user-install]
+
+ assert @cmd.options[:user_install]
+
+ @installer = Gem::Installer.new @gem, @cmd.options
+ @installer.install
+ assert File.exist?(File.join(Gem.user_dir, 'gems'))
+ assert File.exist?(File.join(Gem.user_dir, 'gems',
+ @spec.full_name))
+ end
+
+ def test_user_install_disabled_read_only
+ if win_platform?
+ skip('test_user_install_disabled_read_only test skipped on MS Windows')
+ else
+ @cmd.handle_options %w[--no-user-install]
+
+ refute @cmd.options[:user_install]
+
+ File.chmod 0755, @userhome
+ FileUtils.chmod 0000, @gemhome
+
+ assert_raises(Gem::FilePermissionError) do
+ @installer = Gem::Installer.new @gem, @cmd.options
+ end
+ end
+ ensure
+ FileUtils.chmod 0755, @gemhome
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_installer.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_installer.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_installer.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,859 @@
+require_relative 'gem_installer_test_case'
+
+class TestGemInstaller < GemInstallerTestCase
+
+ def test_app_script_text
+ util_make_exec '2', ''
+
+ expected = <<-EOF
+#!#{Gem.ruby}
+#
+# This file was generated by RubyGems.
+#
+# The application 'a' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+version = \">= 0\"
+
+if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
+ version = $1
+ ARGV.shift
+end
+
+gem 'a', version
+load Gem.bin_path('a', 'my_exec', version)
+ EOF
+
+ wrapper = @installer.app_script_text 'my_exec'
+ assert_equal expected, wrapper
+ end
+
+ def test_build_extensions_none
+ use_ui @ui do
+ @installer.build_extensions
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+
+ refute File.exist?('gem_make.out')
+ end
+
+ def test_build_extensions_extconf_bad
+ @spec.extensions << 'extconf.rb'
+
+ e = assert_raises Gem::Installer::ExtensionBuildError do
+ use_ui @ui do
+ @installer.build_extensions
+ end
+ end
+
+ assert_match(/\AERROR: Failed to build gem native extension.$/, e.message)
+
+ assert_equal "Building native extensions. This could take a while...\n",
+ @ui.output
+ assert_equal '', @ui.error
+
+ gem_make_out = File.join @gemhome, 'gems', @spec.full_name, 'gem_make.out'
+ expected = <<-EOF
+#{Gem.ruby} extconf.rb
+#{Gem.ruby}: No such file or directory -- extconf.rb (LoadError)
+ EOF
+
+ assert_match %r%#{Regexp.escape Gem.ruby} extconf\.rb%,
+ File.read(gem_make_out)
+ assert_match %r%#{Regexp.escape Gem.ruby}: No such file%,
+ File.read(gem_make_out)
+ end
+
+ def test_build_extensions_unsupported
+ @spec.extensions << nil
+
+ e = assert_raises Gem::Installer::ExtensionBuildError do
+ use_ui @ui do
+ @installer.build_extensions
+ end
+ end
+
+ assert_match(/^No builder for extension ''$/, e.message)
+
+ assert_equal "Building native extensions. This could take a while...\n",
+ @ui.output
+ assert_equal '', @ui.error
+
+ assert_equal "No builder for extension ''\n", File.read('gem_make.out')
+ ensure
+ FileUtils.rm_f 'gem_make.out'
+ end
+
+ def test_ensure_dependency
+ dep = Gem::Dependency.new 'a', '>= 2'
+ assert @installer.ensure_dependency(@spec, dep)
+
+ dep = Gem::Dependency.new 'b', '> 2'
+ e = assert_raises Gem::InstallError do
+ @installer.ensure_dependency @spec, dep
+ end
+
+ assert_equal 'a requires b (> 2, runtime)', e.message
+ end
+
+ def test_extract_files
+ format = Object.new
+ def format.file_entries
+ [[{'size' => 7, 'mode' => 0400, 'path' => 'thefile'}, 'thefile']]
+ end
+
+ @installer.format = format
+
+ @installer.extract_files
+
+ thefile_path = File.join(util_gem_dir, 'thefile')
+ assert_equal 'thefile', File.read(thefile_path)
+
+ unless Gem.win_platform? then
+ assert_equal 0400, File.stat(thefile_path).mode & 0777
+ end
+ end
+
+ def test_extract_files_bad_dest
+ @installer.gem_dir = 'somedir'
+ @installer.format = nil
+ e = assert_raises ArgumentError do
+ @installer.extract_files
+ end
+
+ assert_equal 'format required to extract from', e.message
+ end
+
+ def test_extract_files_relative
+ format = Object.new
+ def format.file_entries
+ [[{'size' => 10, 'mode' => 0644, 'path' => '../thefile'}, '../thefile']]
+ end
+
+ @installer.format = format
+
+ e = assert_raises Gem::InstallError do
+ @installer.extract_files
+ end
+
+ assert_equal "attempt to install file into \"../thefile\" under #{util_gem_dir.inspect}",
+ e.message
+ assert_equal false, File.file?(File.join(@tempdir, '../thefile')),
+ "You may need to remove this file if you broke the test once"
+ end
+
+ def test_extract_files_absolute
+ format = Object.new
+ def format.file_entries
+ [[{'size' => 8, 'mode' => 0644, 'path' => '/thefile'}, '/thefile']]
+ end
+
+ @installer.format = format
+
+ e = assert_raises Gem::InstallError do
+ @installer.extract_files
+ end
+
+ assert_equal 'attempt to install file into "/thefile"', e.message
+ assert_equal false, File.file?(File.join('/thefile')),
+ "You may need to remove this file if you broke the test once"
+ end
+
+ def test_generate_bin_bindir
+ @installer.wrappers = true
+
+ @spec.executables = ["my_exec"]
+ @spec.bindir = '.'
+
+ exec_file = @installer.formatted_program_filename "my_exec"
+ exec_path = File.join util_gem_dir(@spec.version), exec_file
+ File.open exec_path, 'w' do |f|
+ f.puts '#!/usr/bin/ruby'
+ end
+
+ @installer.gem_dir = util_gem_dir
+
+ @installer.generate_bin
+
+ assert_equal true, File.directory?(util_inst_bindir)
+ installed_exec = File.join(util_inst_bindir, "my_exec")
+ assert_equal true, File.exist?(installed_exec)
+ assert_equal(0100755, File.stat(installed_exec).mode) unless win_platform?
+
+ wrapper = File.read installed_exec
+ assert_match %r|generated by RubyGems|, wrapper
+ end
+
+ def test_generate_bin_script
+ @installer.wrappers = true
+ util_make_exec
+ @installer.gem_dir = util_gem_dir
+
+ @installer.generate_bin
+ assert_equal true, File.directory?(util_inst_bindir)
+ installed_exec = File.join(util_inst_bindir, "my_exec")
+ assert_equal true, File.exist?(installed_exec)
+ assert_equal(0100755, File.stat(installed_exec).mode) unless win_platform?
+
+ wrapper = File.read installed_exec
+ assert_match %r|generated by RubyGems|, wrapper
+ end
+
+ def test_generate_bin_script_format
+ @installer.format_executable = true
+ @installer.wrappers = true
+ util_make_exec
+ @installer.gem_dir = util_gem_dir
+
+ Gem::Installer.exec_format = 'foo-%s-bar'
+ @installer.generate_bin
+ assert_equal true, File.directory?(util_inst_bindir)
+ installed_exec = File.join util_inst_bindir, 'foo-my_exec-bar'
+ assert_equal true, File.exist?(installed_exec)
+ ensure
+ Gem::Installer.exec_format = nil
+ end
+
+ def test_generate_bin_script_format_disabled
+ @installer.wrappers = true
+ util_make_exec
+ @installer.gem_dir = util_gem_dir
+
+ Gem::Installer.exec_format = 'foo-%s-bar'
+ @installer.generate_bin
+ assert_equal true, File.directory?(util_inst_bindir)
+ installed_exec = File.join util_inst_bindir, 'my_exec'
+ assert_equal true, File.exist?(installed_exec)
+ ensure
+ Gem::Installer.exec_format = nil
+ end
+
+ def test_generate_bin_script_install_dir
+ @installer.wrappers = true
+ @spec.executables = ["my_exec"]
+
+ gem_dir = File.join "#{@gemhome}2", 'gems', @spec.full_name
+ gem_bindir = File.join gem_dir, 'bin'
+ FileUtils.mkdir_p gem_bindir
+ File.open File.join(gem_bindir, "my_exec"), 'w' do |f|
+ f.puts "#!/bin/ruby"
+ end
+
+ @installer.gem_home = "#{@gemhome}2"
+ @installer.gem_dir = gem_dir
+
+ @installer.generate_bin
+
+ installed_exec = File.join("#{@gemhome}2", 'bin', 'my_exec')
+ assert_equal true, File.exist?(installed_exec)
+ assert_equal(0100755, File.stat(installed_exec).mode) unless win_platform?
+
+ wrapper = File.read installed_exec
+ assert_match %r|generated by RubyGems|, wrapper
+ end
+
+ def test_generate_bin_script_no_execs
+ @installer.wrappers = true
+ @installer.generate_bin
+ assert_equal false, File.exist?(util_inst_bindir)
+ end
+
+ def test_generate_bin_script_no_perms
+ @installer.wrappers = true
+ util_make_exec
+
+ Dir.mkdir util_inst_bindir
+
+ if win_platform?
+ skip('test_generate_bin_script_no_perms skipped on MS Windows')
+ else
+ File.chmod 0000, util_inst_bindir
+
+ assert_raises Gem::FilePermissionError do
+ @installer.generate_bin
+ end
+ end
+ ensure
+ File.chmod 0700, util_inst_bindir unless $DEBUG
+ end
+
+ def test_generate_bin_script_no_shebang
+ @installer.wrappers = true
+ @spec.executables = ["my_exec"]
+
+ gem_dir = File.join @gemhome, 'gems', @spec.full_name
+ gem_bindir = File.join gem_dir, 'bin'
+ FileUtils.mkdir_p gem_bindir
+ File.open File.join(gem_bindir, "my_exec"), 'w' do |f|
+ f.puts "blah blah blah"
+ end
+
+ @installer.generate_bin
+
+ installed_exec = File.join @gemhome, 'bin', 'my_exec'
+ assert_equal true, File.exist?(installed_exec)
+ assert_equal 0100755, File.stat(installed_exec).mode unless win_platform?
+
+ wrapper = File.read installed_exec
+ assert_match %r|generated by RubyGems|, wrapper
+ # HACK some gems don't have #! in their executables, restore 2008/06
+ #assert_no_match %r|generated by RubyGems|, wrapper
+ end
+
+ def test_generate_bin_script_wrappers
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ @installer.wrappers = true
+ util_make_exec
+ @installer.gem_dir = util_gem_dir
+ installed_exec = File.join(util_inst_bindir, "my_exec")
+
+ real_exec = File.join util_gem_dir, 'bin', 'my_exec'
+
+ # fake --no-wrappers for previous install
+ unless Gem.win_platform? then
+ FileUtils.mkdir_p File.dirname(installed_exec)
+ FileUtils.ln_s real_exec, installed_exec
+ end
+
+ @installer.generate_bin
+ assert_equal true, File.directory?(util_inst_bindir)
+ assert_equal true, File.exist?(installed_exec)
+ assert_equal(0100755, File.stat(installed_exec).mode) unless win_platform?
+
+ assert_match %r|generated by RubyGems|, File.read(installed_exec)
+
+ refute_match %r|generated by RubyGems|, File.read(real_exec),
+ 'real executable overwritten'
+ end
+
+ def test_generate_bin_symlink
+ return if win_platform? #Windows FS do not support symlinks
+
+ @installer.wrappers = false
+ util_make_exec
+ @installer.gem_dir = util_gem_dir
+
+ @installer.generate_bin
+ assert_equal true, File.directory?(util_inst_bindir)
+ installed_exec = File.join(util_inst_bindir, "my_exec")
+ assert_equal true, File.symlink?(installed_exec)
+ assert_equal(File.join(util_gem_dir, "bin", "my_exec"),
+ File.readlink(installed_exec))
+ end
+
+ def test_generate_bin_symlink_no_execs
+ @installer.wrappers = false
+ @installer.generate_bin
+ assert_equal false, File.exist?(util_inst_bindir)
+ end
+
+ def test_generate_bin_symlink_no_perms
+ @installer.wrappers = false
+ util_make_exec
+ @installer.gem_dir = util_gem_dir
+
+ Dir.mkdir util_inst_bindir
+
+ if win_platform?
+ skip('test_generate_bin_symlink_no_perms skipped on MS Windows')
+ else
+ File.chmod 0000, util_inst_bindir
+
+ assert_raises Gem::FilePermissionError do
+ @installer.generate_bin
+ end
+ end
+ ensure
+ File.chmod 0700, util_inst_bindir unless $DEBUG
+ end
+
+ def test_generate_bin_symlink_update_newer
+ return if win_platform? #Windows FS do not support symlinks
+
+ @installer.wrappers = false
+ util_make_exec
+ @installer.gem_dir = util_gem_dir
+
+ @installer.generate_bin
+ installed_exec = File.join(util_inst_bindir, "my_exec")
+ assert_equal(File.join(util_gem_dir, "bin", "my_exec"),
+ File.readlink(installed_exec))
+
+ @spec = Gem::Specification.new do |s|
+ s.files = ['lib/code.rb']
+ s.name = "a"
+ s.version = "3"
+ s.summary = "summary"
+ s.description = "desc"
+ s.require_path = 'lib'
+ end
+
+ util_make_exec '3'
+ @installer.gem_dir = File.join util_gem_dir('3')
+ @installer.generate_bin
+ installed_exec = File.join(util_inst_bindir, "my_exec")
+ assert_equal(File.join(util_gem_bindir('3'), "my_exec"),
+ File.readlink(installed_exec),
+ "Ensure symlink moved to latest version")
+ end
+
+ def test_generate_bin_symlink_update_older
+ return if win_platform? #Windows FS do not support symlinks
+
+ @installer.wrappers = false
+ util_make_exec
+ @installer.gem_dir = util_gem_dir
+
+ @installer.generate_bin
+ installed_exec = File.join(util_inst_bindir, "my_exec")
+ assert_equal(File.join(util_gem_dir, "bin", "my_exec"),
+ File.readlink(installed_exec))
+
+ spec = Gem::Specification.new do |s|
+ s.files = ['lib/code.rb']
+ s.name = "a"
+ s.version = "1"
+ s.summary = "summary"
+ s.description = "desc"
+ s.require_path = 'lib'
+ end
+
+ util_make_exec '1'
+ @installer.gem_dir = util_gem_dir('1')
+ @installer.spec = spec
+
+ @installer.generate_bin
+
+ installed_exec = File.join(util_inst_bindir, "my_exec")
+ assert_equal(File.join(util_gem_dir('2'), "bin", "my_exec"),
+ File.readlink(installed_exec),
+ "Ensure symlink not moved")
+ end
+
+ def test_generate_bin_symlink_update_remove_wrapper
+ return if win_platform? #Windows FS do not support symlinks
+
+ @installer.wrappers = true
+ util_make_exec
+ @installer.gem_dir = util_gem_dir
+
+ @installer.generate_bin
+ installed_exec = File.join(util_inst_bindir, "my_exec")
+ assert_equal true, File.exist?(installed_exec)
+
+ @spec = Gem::Specification.new do |s|
+ s.files = ['lib/code.rb']
+ s.name = "a"
+ s.version = "3"
+ s.summary = "summary"
+ s.description = "desc"
+ s.require_path = 'lib'
+ end
+
+ @installer.wrappers = false
+ util_make_exec '3'
+ @installer.gem_dir = util_gem_dir '3'
+ @installer.generate_bin
+ installed_exec = File.join(util_inst_bindir, "my_exec")
+ assert_equal(File.join(util_gem_dir('3'), "bin", "my_exec"),
+ File.readlink(installed_exec),
+ "Ensure symlink moved to latest version")
+ end
+
+ def test_generate_bin_symlink_win32
+ old_win_platform = Gem.win_platform?
+ Gem.win_platform = true
+ @installer.wrappers = false
+ util_make_exec
+ @installer.gem_dir = util_gem_dir
+
+ use_ui @ui do
+ @installer.generate_bin
+ end
+
+ assert_equal true, File.directory?(util_inst_bindir)
+ installed_exec = File.join(util_inst_bindir, "my_exec")
+ assert_equal true, File.exist?(installed_exec)
+
+ assert_match(/Unable to use symlinks on Windows, installing wrapper/i,
+ @ui.error)
+
+ wrapper = File.read installed_exec
+ assert_match(/generated by RubyGems/, wrapper)
+ ensure
+ Gem.win_platform = old_win_platform
+ end
+
+ def test_generate_bin_uses_default_shebang
+ return if win_platform? #Windows FS do not support symlinks
+
+ @installer.wrappers = true
+ util_make_exec
+
+ @installer.generate_bin
+
+ default_shebang = Gem.ruby
+ shebang_line = open("#{@gemhome}/bin/my_exec") { |f| f.readlines.first }
+ assert_match(/\A#!/, shebang_line)
+ assert_match(/#{default_shebang}/, shebang_line)
+ end
+
+ def test_initialize
+ spec = quick_gem 'a' do |s| s.platform = Gem::Platform.new 'mswin32' end
+ gem = File.join @tempdir, spec.file_name
+
+ Dir.mkdir util_inst_bindir
+ util_build_gem spec
+ FileUtils.mv File.join(@gemhome, 'cache', spec.file_name),
+ @tempdir
+
+ installer = Gem::Installer.new gem
+
+ assert_equal File.join(@gemhome, 'gems', spec.full_name), installer.gem_dir
+ end
+
+ def test_install
+ Dir.mkdir util_inst_bindir
+ util_setup_gem
+
+ cache_file = File.join @gemhome, 'cache', @spec.file_name
+
+ Gem.pre_install do |installer|
+ refute File.exist?(cache_file), 'cache file should not exist yet'
+ end
+
+ Gem.post_install do |installer|
+ assert File.exist?(cache_file), 'cache file should exist'
+ end
+
+ build_rake_in do
+ use_ui @ui do
+ assert_equal @spec, @installer.install
+ end
+ end
+
+ gemdir = File.join @gemhome, 'gems', @spec.full_name
+ assert File.exist?(gemdir)
+
+ exe = File.join(gemdir, 'bin', 'executable')
+ assert File.exist?(exe)
+ exe_mode = File.stat(exe).mode & 0111
+ assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform?
+
+ assert File.exist?(File.join(gemdir, 'lib', 'code.rb'))
+
+ assert File.exist?(File.join(gemdir, 'ext', 'a', 'Rakefile'))
+
+ spec_file = File.join(@gemhome, 'specifications', @spec.spec_name)
+
+ assert_equal spec_file, @spec.loaded_from
+ assert File.exist?(spec_file)
+
+ assert_same @installer, @pre_install_hook_arg
+ assert_same @installer, @post_install_hook_arg
+ end
+
+ def test_install_bad_gem
+ gem = nil
+
+ use_ui @ui do
+ Dir.chdir @tempdir do Gem::Builder.new(@spec).build end
+ gem = File.join @tempdir, @spec.file_name
+ end
+
+ gem_data = File.open gem, 'rb' do |fp| fp.read 1024 end
+ File.open gem, 'wb' do |fp| fp.write gem_data end
+
+ e = assert_raises Gem::InstallError do
+ use_ui @ui do
+ @installer = Gem::Installer.new gem
+ @installer.install
+ end
+ end
+
+ assert_equal "invalid gem format for #{gem}", e.message
+ end
+
+ def test_install_check_dependencies
+ @spec.add_dependency 'b', '> 5'
+ util_setup_gem
+
+ use_ui @ui do
+ assert_raises Gem::InstallError do
+ @installer.install
+ end
+ end
+ end
+
+ def test_install_check_dependencies_install_dir
+ gemhome2 = "#{@gemhome}2"
+ @spec.add_dependency 'b'
+
+ b2 = quick_gem 'b', 2
+
+ FileUtils.mv @gemhome, gemhome2
+ Gem.source_index.gems.delete b2.full_name
+ source_index = Gem::SourceIndex.from_gems_in File.join(gemhome2,
+ 'specifications')
+
+ util_setup_gem
+
+ @installer = Gem::Installer.new @gem, :install_dir => gemhome2,
+ :source_index => source_index
+
+ build_rake_in do
+ use_ui @ui do
+ @installer.install
+ end
+ end
+
+ assert File.exist?(File.join(gemhome2, 'gems', @spec.full_name))
+ end
+
+ def test_install_force
+ use_ui @ui do
+ installer = Gem::Installer.new old_ruby_required, :force => true
+ installer.install
+ end
+
+ gem_dir = File.join(@gemhome, 'gems', 'old_ruby_required-1')
+ assert File.exist?(gem_dir)
+ end
+
+ def test_install_ignore_dependencies
+ Dir.mkdir util_inst_bindir
+ @spec.add_dependency 'b', '> 5'
+ util_setup_gem
+ @installer.ignore_dependencies = true
+
+ build_rake_in do
+ use_ui @ui do
+ assert_equal @spec, @installer.install
+ end
+ end
+
+ gemdir = File.join @gemhome, 'gems', @spec.full_name
+ assert File.exist?(gemdir)
+
+ exe = File.join(gemdir, 'bin', 'executable')
+ assert File.exist?(exe)
+ exe_mode = File.stat(exe).mode & 0111
+ assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform?
+ assert File.exist?(File.join(gemdir, 'lib', 'code.rb'))
+
+ assert File.exist?(File.join(@gemhome, 'specifications', @spec.spec_name))
+ end
+
+ def test_install_missing_dirs
+ FileUtils.rm_f File.join(Gem.dir, 'cache')
+ FileUtils.rm_f File.join(Gem.dir, 'docs')
+ FileUtils.rm_f File.join(Gem.dir, 'specifications')
+
+ use_ui @ui do
+ Dir.chdir @tempdir do Gem::Builder.new(@spec).build end
+ gem = File.join @tempdir, @spec.file_name
+
+ @installer.install
+ end
+
+ File.directory? File.join(Gem.dir, 'cache')
+ File.directory? File.join(Gem.dir, 'docs')
+ File.directory? File.join(Gem.dir, 'specifications')
+
+ assert File.exist?(File.join(@gemhome, 'cache', @spec.file_name))
+ assert File.exist?(File.join(@gemhome, 'specifications', @spec.spec_name))
+ end
+
+ def test_install_with_message
+ @spec.post_install_message = 'I am a shiny gem!'
+
+ use_ui @ui do
+ Dir.chdir @tempdir do Gem::Builder.new(@spec).build end
+
+ @installer.install
+ end
+
+ assert_match %r|I am a shiny gem!|, @ui.output
+ end
+
+ def test_install_wrong_ruby_version
+ use_ui @ui do
+ installer = Gem::Installer.new old_ruby_required
+ e = assert_raises Gem::InstallError do
+ installer.install
+ end
+ assert_equal 'old_ruby_required requires Ruby version = 1.4.6.',
+ e.message
+ end
+ end
+
+ def test_install_wrong_rubygems_version
+ spec = quick_gem 'old_rubygems_required', '1' do |s|
+ s.required_rubygems_version = '< 0'
+ end
+
+ util_build_gem spec
+
+ gem = File.join @gemhome, 'cache', spec.file_name
+
+ use_ui @ui do
+ @installer = Gem::Installer.new gem
+ e = assert_raises Gem::InstallError do
+ @installer.install
+ end
+ assert_equal 'old_rubygems_required requires RubyGems version < 0. ' +
+ "Try 'gem update --system' to update RubyGems itself.", e.message
+ end
+ end
+
+ def test_installation_satisfies_dependency_eh
+ dep = Gem::Dependency.new 'a', '>= 2'
+ assert @installer.installation_satisfies_dependency?(dep)
+
+ dep = Gem::Dependency.new 'a', '> 2'
+ refute @installer.installation_satisfies_dependency?(dep)
+ end
+
+ def test_shebang
+ util_make_exec '2', "#!/usr/bin/ruby"
+
+ shebang = @installer.shebang 'my_exec'
+
+ assert_equal "#!#{Gem.ruby}", shebang
+ end
+
+ def test_shebang_arguments
+ util_make_exec '2', "#!/usr/bin/ruby -ws"
+
+ shebang = @installer.shebang 'my_exec'
+
+ assert_equal "#!#{Gem.ruby} -ws", shebang
+ end
+
+ def test_shebang_empty
+ util_make_exec '2', ''
+
+ shebang = @installer.shebang 'my_exec'
+ assert_equal "#!#{Gem.ruby}", shebang
+ end
+
+ def test_shebang_env
+ util_make_exec '2', "#!/usr/bin/env ruby"
+
+ shebang = @installer.shebang 'my_exec'
+
+ assert_equal "#!#{Gem.ruby}", shebang
+ end
+
+ def test_shebang_env_arguments
+ util_make_exec '2', "#!/usr/bin/env ruby -ws"
+
+ shebang = @installer.shebang 'my_exec'
+
+ assert_equal "#!#{Gem.ruby} -ws", shebang
+ end
+
+ def test_shebang_env_shebang
+ util_make_exec '2', ''
+ @installer.env_shebang = true
+
+ shebang = @installer.shebang 'my_exec'
+
+ env_shebang = "/usr/bin/env" unless Gem.win_platform?
+
+ assert_equal("#!#{env_shebang} #{Gem::ConfigMap[:ruby_install_name]}",
+ shebang)
+ end
+
+ def test_shebang_nested
+ util_make_exec '2', "#!/opt/local/ruby/bin/ruby"
+
+ shebang = @installer.shebang 'my_exec'
+
+ assert_equal "#!#{Gem.ruby}", shebang
+ end
+
+ def test_shebang_nested_arguments
+ util_make_exec '2', "#!/opt/local/ruby/bin/ruby -ws"
+
+ shebang = @installer.shebang 'my_exec'
+
+ assert_equal "#!#{Gem.ruby} -ws", shebang
+ end
+
+ def test_shebang_version
+ util_make_exec '2', "#!/usr/bin/ruby18"
+
+ shebang = @installer.shebang 'my_exec'
+
+ assert_equal "#!#{Gem.ruby}", shebang
+ end
+
+ def test_shebang_version_arguments
+ util_make_exec '2', "#!/usr/bin/ruby18 -ws"
+
+ shebang = @installer.shebang 'my_exec'
+
+ assert_equal "#!#{Gem.ruby} -ws", shebang
+ end
+
+ def test_shebang_version_env
+ util_make_exec '2', "#!/usr/bin/env ruby18"
+
+ shebang = @installer.shebang 'my_exec'
+
+ assert_equal "#!#{Gem.ruby}", shebang
+ end
+
+ def test_shebang_version_env_arguments
+ util_make_exec '2', "#!/usr/bin/env ruby18 -ws"
+
+ shebang = @installer.shebang 'my_exec'
+
+ assert_equal "#!#{Gem.ruby} -ws", shebang
+ end
+
+ def test_unpack
+ util_setup_gem
+
+ dest = File.join @gemhome, 'gems', @spec.full_name
+
+ @installer.unpack dest
+
+ assert File.exist?(File.join(dest, 'lib', 'code.rb'))
+ assert File.exist?(File.join(dest, 'bin', 'executable'))
+ end
+
+ def test_write_spec
+ spec_dir = File.join @gemhome, 'specifications'
+ spec_file = File.join spec_dir, @spec.spec_name
+ FileUtils.rm spec_file
+ refute File.exist?(spec_file)
+
+ @installer.spec = @spec
+ @installer.gem_home = @gemhome
+
+ @installer.write_spec
+
+ assert File.exist?(spec_file)
+ assert_equal @spec, eval(File.read(spec_file))
+ end
+
+ def old_ruby_required
+ spec = quick_gem 'old_ruby_required', '1' do |s|
+ s.required_ruby_version = '= 1.4.6'
+ end
+
+ util_build_gem spec
+
+ File.join @gemhome, 'cache', spec.file_name
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_local_remote_options.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_local_remote_options.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_local_remote_options.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,97 @@
+require_relative 'gemutilities'
+require 'rubygems/local_remote_options'
+require 'rubygems/command'
+
+class TestGemLocalRemoteOptions < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Command.new 'dummy', 'dummy'
+ @cmd.extend Gem::LocalRemoteOptions
+ end
+
+ def test_add_local_remote_options
+ @cmd.add_local_remote_options
+
+ args = %w[-l -r -b -B 10 --source http://gems.example.com -p --update-sources]
+ assert @cmd.handles?(args)
+ end
+
+ def test_both_eh
+ assert_equal false, @cmd.both?
+
+ @cmd.options[:domain] = :local
+
+ assert_equal false, @cmd.both?
+
+ @cmd.options[:domain] = :both
+
+ assert_equal true, @cmd.both?
+ end
+
+ def test_local_eh
+ assert_equal false, @cmd.local?
+
+ @cmd.options[:domain] = :local
+
+ assert_equal true, @cmd.local?
+
+ @cmd.options[:domain] = :both
+
+ assert_equal true, @cmd.local?
+ end
+
+ def test_remote_eh
+ assert_equal false, @cmd.remote?
+
+ @cmd.options[:domain] = :remote
+
+ assert_equal true, @cmd.remote?
+
+ @cmd.options[:domain] = :both
+
+ assert_equal true, @cmd.remote?
+ end
+
+ def test_source_option
+ @cmd.add_source_option
+
+ s1 = URI.parse 'http://more-gems.example.com/'
+ s2 = URI.parse 'http://even-more-gems.example.com/'
+ s3 = URI.parse 'http://other-gems.example.com/some_subdir'
+ s4 = URI.parse 'http://more-gems.example.com/' # Intentional duplicate
+
+ @cmd.handle_options %W[--source #{s1} --source #{s2} --source #{s3} --source #{s4}]
+
+ assert_equal [s1.to_s, s2.to_s, "#{s3}/"], Gem.sources
+ end
+
+ def test_update_sources_option
+ @cmd.add_update_sources_option
+
+ Gem.configuration.update_sources = false
+
+ @cmd.handle_options %W[--update-sources]
+
+ assert_equal true, Gem.configuration.update_sources
+
+ @cmd.handle_options %W[--no-update-sources]
+
+ assert_equal false, Gem.configuration.update_sources
+ end
+
+ def test_source_option_bad
+ @cmd.add_source_option
+
+ s1 = 'htp://more-gems.example.com'
+
+ assert_raises OptionParser::InvalidArgument do
+ @cmd.handle_options %W[--source #{s1}]
+ end
+
+ assert_equal [@gem_repo], Gem.sources
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_header.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_header.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_header.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,130 @@
+require_relative 'gem_package_tar_test_case'
+require 'rubygems/package'
+
+class TestGemPackageTarHeader < TarTestCase
+
+ def setup
+ super
+
+ header = {
+ :name => 'x',
+ :mode => 0644,
+ :uid => 1000,
+ :gid => 10000,
+ :size => 100,
+ :mtime => 12345,
+ :typeflag => '0',
+ :linkname => 'link',
+ :uname => 'user',
+ :gname => 'group',
+ :devmajor => 1,
+ :devminor => 2,
+ :prefix => 'y',
+ }
+
+ @tar_header = Gem::Package::TarHeader.new header
+ end
+
+ def test_self_from
+ io = TempIO.new @tar_header.to_s
+
+ new_header = Gem::Package::TarHeader.from io
+
+ assert_headers_equal @tar_header, new_header
+ end
+
+ def test_initialize
+ assert_equal '', @tar_header.checksum, 'checksum'
+ assert_equal 1, @tar_header.devmajor, 'devmajor'
+ assert_equal 2, @tar_header.devminor, 'devminor'
+ assert_equal 10000, @tar_header.gid, 'gid'
+ assert_equal 'group', @tar_header.gname, 'gname'
+ assert_equal 'link', @tar_header.linkname, 'linkname'
+ assert_equal 'ustar', @tar_header.magic, 'magic'
+ assert_equal 0644, @tar_header.mode, 'mode'
+ assert_equal 12345, @tar_header.mtime, 'mtime'
+ assert_equal 'x', @tar_header.name, 'name'
+ assert_equal 'y', @tar_header.prefix, 'prefix'
+ assert_equal 100, @tar_header.size, 'size'
+ assert_equal '0', @tar_header.typeflag, 'typeflag'
+ assert_equal 1000, @tar_header.uid, 'uid'
+ assert_equal 'user', @tar_header.uname, 'uname'
+ assert_equal '00', @tar_header.version, 'version'
+
+ refute_empty @tar_header, 'empty'
+ end
+
+ def test_initialize_bad
+ assert_raises ArgumentError do
+ Gem::Package::TarHeader.new :name => '', :size => '', :mode => ''
+ end
+
+ assert_raises ArgumentError do
+ Gem::Package::TarHeader.new :name => '', :size => '', :prefix => ''
+ end
+
+ assert_raises ArgumentError do
+ Gem::Package::TarHeader.new :name => '', :prefix => '', :mode => ''
+ end
+
+ assert_raises ArgumentError do
+ Gem::Package::TarHeader.new :prefix => '', :size => '', :mode => ''
+ end
+ end
+
+ def test_empty_eh
+ refute_empty @tar_header
+
+ @tar_header = Gem::Package::TarHeader.new :name => 'x', :prefix => '',
+ :mode => 0, :size => 0,
+ :empty => true
+
+ assert_empty @tar_header
+ end
+
+ def test_equals2
+ assert_equal @tar_header, @tar_header
+ assert_equal @tar_header, @tar_header.dup
+ end
+
+ def test_to_s
+ expected = <<-EOF.split("\n").join
+x\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\0000000644\0000001750\0000023420\00000000000144\00000000030071
+\000012467\000 0link\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000ustar\00000user\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+group\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\0000000001\0000000002\000y\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+\000\000\000\000\000\000\000\000\000\000
+ EOF
+
+ assert_headers_equal expected, @tar_header
+ end
+
+ def test_update_checksum
+ assert_equal '', @tar_header.checksum
+
+ @tar_header.update_checksum
+
+ assert_equal '012467', @tar_header.checksum
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_input.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_input.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_input.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,112 @@
+require_relative 'gem_package_tar_test_case'
+require 'rubygems/package/tar_input'
+
+class TestGemPackageTarInput < TarTestCase
+
+ # Sometimes the setgid bit doesn't take. Don't know if this is a problem on
+ # all systems, or just some. But for now, we will ignore it in the tests.
+ SETGID_BIT = 02000
+
+ def setup
+ super
+
+ inner_tar = tar_file_header("bla", "", 0612, 10)
+ inner_tar += "0123456789" + "\0" * 502
+ inner_tar += tar_file_header("foo", "", 0636, 5)
+ inner_tar += "01234" + "\0" * 507
+ inner_tar += tar_dir_header("__dir__", "", 0600)
+ inner_tar += "\0" * 1024
+ str = TempIO.new
+
+ begin
+ os = Zlib::GzipWriter.new str
+ os.write inner_tar
+ ensure
+ os.finish
+ end
+
+ str.rewind
+
+ @file = File.join @tempdir, 'bla.tar'
+
+ File.open @file, 'wb' do |f|
+ f.write tar_file_header("data.tar.gz", "", 0644, str.string.size)
+ f.write str.string
+ f.write "\0" * ((512 - (str.string.size % 512)) % 512 )
+
+ @spec = Gem::Specification.new do |spec|
+ spec.author = "Mauricio :)"
+ end
+
+ meta = @spec.to_yaml
+
+ f.write tar_file_header("metadata", "", 0644, meta.size)
+ f.write meta + "\0" * (1024 - meta.size)
+ f.write "\0" * 1024
+ end
+
+ @entry_names = %w{bla foo __dir__}
+ @entry_sizes = [10, 5, 0]
+ #FIXME: are these modes system dependent?
+ @entry_modes = [0100612, 0100636, 040600]
+ @entry_files = %W[#{@tempdir}/bla #{@tempdir}/foo]
+ @entry_contents = %w[0123456789 01234]
+ end
+
+ def test_each_works
+ open @file, 'rb' do |io|
+ Gem::Package::TarInput.open io do |tar_input|
+ count = 0
+
+ tar_input.each_with_index do |entry, i|
+ count = i
+
+ assert_kind_of Gem::Package::TarReader::Entry, entry
+ assert_equal @entry_names[i], entry.header.name
+ assert_equal @entry_sizes[i], entry.header.size
+ end
+
+ assert_equal 2, count
+
+ assert_equal @spec, tar_input.metadata
+ end
+ end
+ end
+
+ def test_extract_entry_works
+ open @file, 'rb' do |io|
+ Gem::Package::TarInput.open io do |tar_input|
+ assert_equal @spec, tar_input.metadata
+
+ count = 0
+
+ tar_input.each_with_index do |entry, i|
+ count = i
+ tar_input.extract_entry @tempdir, entry
+ name = File.join @tempdir, entry.header.name
+
+ if entry.directory? then
+ assert File.directory?(name)
+ else
+ assert File.file?(name)
+ assert_equal @entry_sizes[i], File.stat(name).size
+ #FIXME: win32? !!
+ end
+
+ unless Gem.win_platform? then
+ assert_equal @entry_modes[i], File.stat(name).mode & (~SETGID_BIT)
+ end
+ end
+
+ assert_equal 2, count
+ end
+ end
+
+ @entry_files.each_with_index do |x, i|
+ assert File.file?(x)
+ assert_equal @entry_contents[i], Gem.read_binary(x)
+ end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_output.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_output.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_output.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,97 @@
+require_relative 'gem_package_tar_test_case'
+require 'rubygems/package/tar_output'
+
+class TestGemPackageTarOutput < TarTestCase
+
+ def setup
+ super
+
+ @file = File.join @tempdir, 'bla2.tar'
+ end
+
+ def test_self_open
+ open @file, 'wb' do |tar_io|
+ Gem::Package::TarOutput.open tar_io do |tar_writer|
+ tar_writer.add_file_simple 'README', 0, 17 do |io|
+ io.write "This is a README\n"
+ end
+
+ tar_writer.metadata = "This is some metadata\n"
+ end
+ end
+
+ files = util_extract
+
+ name, data = files.shift
+ assert_equal 'data.tar.gz', name
+
+ gz = Zlib::GzipReader.new StringIO.new(data)
+
+ Gem::Package::TarReader.new gz do |tar_reader|
+ tar_reader.each do |entry|
+ assert_equal 'README', entry.full_name
+ assert_equal "This is a README\n", entry.read
+ end
+ end
+
+ gz.close
+
+ name, data = files.shift
+ assert_equal 'metadata.gz', name
+
+ gz = Zlib::GzipReader.new StringIO.new(data)
+ assert_equal "This is some metadata\n", gz.read
+
+ assert_empty files
+ ensure
+ gz.close if gz
+ end
+
+ if defined? OpenSSL then
+ def test_self_open_signed
+ signer = Gem::Security::Signer.new @private_key, [@public_cert]
+
+ open @file, 'wb' do |tar_io|
+ Gem::Package::TarOutput.open tar_io, signer do |tar_writer|
+ tar_writer.add_file_simple 'README', 0, 17 do |io|
+ io.write "This is a README\n"
+ end
+
+ tar_writer.metadata = "This is some metadata\n"
+ end
+ end
+
+ files = util_extract
+
+ name, data = files.shift
+ assert_equal 'data.tar.gz', name
+
+ name, data = files.shift
+ assert_equal 'metadata.gz', name
+
+ name, data = files.shift
+ assert_equal 'data.tar.gz.sig', name
+
+ name, data = files.shift
+ assert_equal 'metadata.gz.sig', name
+
+ assert_empty files
+ end
+ end
+
+ def util_extract
+ files = []
+
+ open @file, 'rb' do |io|
+ Gem::Package::TarReader.new io do |tar_reader|
+ tar_reader.each do |entry|
+ files << [entry.full_name, entry.read]
+ end
+ end
+ end
+
+ files
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_reader.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_reader.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_reader.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,46 @@
+require_relative 'gem_package_tar_test_case'
+require 'rubygems/package'
+
+class TestGemPackageTarReader < TarTestCase
+
+ def test_each_entry
+ tar = tar_dir_header "foo", "bar", 0
+ tar << tar_file_header("bar", "baz", 0, 0)
+
+ io = TempIO.new tar
+
+ entries = 0
+
+ Gem::Package::TarReader.new io do |tar_reader|
+ tar_reader.each_entry do |entry|
+ assert_kind_of Gem::Package::TarReader::Entry, entry
+
+ entries += 1
+ end
+ end
+
+ assert_equal 2, entries
+ end
+
+ def test_rewind
+ content = ('a'..'z').to_a.join(" ")
+
+ str = tar_file_header("lib/foo", "", 010644, content.size) + content +
+ "\0" * (512 - content.size)
+ str << "\0" * 1024
+
+ Gem::Package::TarReader.new(TempIO.new(str)) do |tar_reader|
+ 3.times do
+ tar_reader.rewind
+ i = 0
+ tar_reader.each_entry do |entry|
+ assert_equal(content, entry.read)
+ i += 1
+ end
+ assert_equal(1, i)
+ end
+ end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_reader_entry.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_reader_entry.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_reader_entry.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,109 @@
+require_relative 'gem_package_tar_test_case'
+require 'rubygems/package'
+
+class TestGemPackageTarReaderEntry < TarTestCase
+
+ def setup
+ super
+
+ @contents = ('a'..'z').to_a.join * 100
+
+ @tar = ''
+ @tar << tar_file_header("lib/foo", "", 0, @contents.size)
+ @tar << @contents
+ @tar << "\0" * (512 - (@tar.size % 512))
+
+ @entry = util_entry @tar
+ end
+
+ def test_bytes_read
+ assert_equal 0, @entry.bytes_read
+
+ @entry.getc
+
+ assert_equal 1, @entry.bytes_read
+ end
+
+ def test_close
+ @entry.close
+
+ assert @entry.bytes_read
+
+ e = assert_raises IOError do @entry.eof? end
+ assert_equal 'closed Gem::Package::TarReader::Entry', e.message
+
+ e = assert_raises IOError do @entry.getc end
+ assert_equal 'closed Gem::Package::TarReader::Entry', e.message
+
+ e = assert_raises IOError do @entry.pos end
+ assert_equal 'closed Gem::Package::TarReader::Entry', e.message
+
+ e = assert_raises IOError do @entry.read end
+ assert_equal 'closed Gem::Package::TarReader::Entry', e.message
+
+ e = assert_raises IOError do @entry.rewind end
+ assert_equal 'closed Gem::Package::TarReader::Entry', e.message
+ end
+
+ def test_closed_eh
+ @entry.close
+
+ assert @entry.closed?
+ end
+
+ def test_eof_eh
+ @entry.read
+
+ assert @entry.eof?
+ end
+
+ def test_full_name
+ assert_equal 'lib/foo', @entry.full_name
+ end
+
+ def test_getc
+ assert_equal ?a, @entry.getc
+ end
+
+ def test_directory_eh
+ assert_equal false, @entry.directory?
+ assert_equal true, util_dir_entry.directory?
+ end
+
+ def test_file_eh
+ assert_equal true, @entry.file?
+ assert_equal false, util_dir_entry.file?
+ end
+
+ def test_pos
+ assert_equal 0, @entry.pos
+
+ @entry.getc
+
+ assert_equal 1, @entry.pos
+ end
+
+ def test_read
+ assert_equal @contents, @entry.read
+ end
+
+ def test_read_big
+ assert_equal @contents, @entry.read(@contents.size * 2)
+ end
+
+ def test_read_small
+ assert_equal @contents[0...100], @entry.read(100)
+ end
+
+ def test_rewind
+ char = @entry.getc
+
+ @entry.rewind
+
+ assert_equal 0, @entry.pos
+
+ assert_equal char, @entry.getc
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_writer.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_writer.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_tar_writer.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,144 @@
+require_relative 'gem_package_tar_test_case'
+require 'rubygems/package/tar_writer'
+
+class TestTarWriter < TarTestCase
+
+ def setup
+ super
+
+ @data = 'abcde12345'
+ @io = TempIO.new
+ @tar_writer = Gem::Package::TarWriter.new @io
+ end
+
+ def teardown
+ @tar_writer.close unless @tar_writer.closed?
+
+ super
+ end
+
+ def test_add_file
+ @tar_writer.add_file 'x', 0644 do |f| f.write 'a' * 10 end
+
+ assert_headers_equal(tar_file_header('x', '', 0644, 10),
+ @io.string[0, 512])
+ assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
+ assert_equal 1024, @io.pos
+ end
+
+ def test_add_file_simple
+ @tar_writer.add_file_simple 'x', 0644, 10 do |io| io.write "a" * 10 end
+
+ assert_headers_equal(tar_file_header('x', '', 0644, 10),
+ @io.string[0, 512])
+
+ assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
+ assert_equal 1024, @io.pos
+ end
+
+ def test_add_file_simple_padding
+ @tar_writer.add_file_simple 'x', 0, 100
+
+ assert_headers_equal tar_file_header('x', '', 0, 100),
+ @io.string[0, 512]
+
+ assert_equal "\0" * 512, @io.string[512, 512]
+ end
+
+ def test_add_file_simple_data
+ @tar_writer.add_file_simple("lib/foo/bar", 0, 10) { |f| f.write @data }
+ @tar_writer.flush
+
+ assert_equal @data + ("\0" * (512- at data.size)),
+ @io.string[512, 512]
+ end
+
+ def test_add_file_simple_size
+ assert_raises Gem::Package::TarWriter::FileOverflow do
+ @tar_writer.add_file_simple("lib/foo/bar", 0, 10) do |io|
+ io.write "1" * 11
+ end
+ end
+ end
+
+ def test_add_file_unseekable
+ assert_raises Gem::Package::NonSeekableIO do
+ Gem::Package::TarWriter.new(Object.new).add_file 'x', 0
+ end
+ end
+
+ def test_close
+ @tar_writer.close
+
+ assert_equal "\0" * 1024, @io.string
+
+ e = assert_raises IOError do
+ @tar_writer.close
+ end
+ assert_equal 'closed Gem::Package::TarWriter', e.message
+
+ e = assert_raises IOError do
+ @tar_writer.flush
+ end
+ assert_equal 'closed Gem::Package::TarWriter', e.message
+
+ e = assert_raises IOError do
+ @tar_writer.add_file 'x', 0
+ end
+ assert_equal 'closed Gem::Package::TarWriter', e.message
+
+ e = assert_raises IOError do
+ @tar_writer.add_file_simple 'x', 0, 0
+ end
+ assert_equal 'closed Gem::Package::TarWriter', e.message
+
+ e = assert_raises IOError do
+ @tar_writer.mkdir 'x', 0
+ end
+ assert_equal 'closed Gem::Package::TarWriter', e.message
+ end
+
+ def test_mkdir
+ @tar_writer.mkdir 'foo', 0644
+
+ assert_headers_equal tar_dir_header('foo', '', 0644),
+ @io.string[0, 512]
+ assert_equal 512, @io.pos
+ end
+
+ def test_split_name
+ assert_equal ['b' * 100, 'a' * 155],
+ @tar_writer.split_name("#{'a' * 155}/#{'b' * 100}")
+
+ assert_equal ["#{'qwer/' * 19}bla", 'a' * 151],
+ @tar_writer.split_name("#{'a' * 151}/#{'qwer/' * 19}bla")
+ end
+
+ def test_split_name_too_long_name
+ name = File.join 'a', 'b' * 100
+ assert_equal ['b' * 100, 'a'], @tar_writer.split_name(name)
+
+ assert_raises Gem::Package::TooLongFileName do
+ name = File.join 'a', 'b' * 101
+ @tar_writer.split_name name
+ end
+ end
+
+ def test_split_name_too_long_prefix
+ name = File.join 'a' * 155, 'b'
+ assert_equal ['b', 'a' * 155], @tar_writer.split_name(name)
+
+ assert_raises Gem::Package::TooLongFileName do
+ name = File.join 'a' * 156, 'b'
+ @tar_writer.split_name name
+ end
+ end
+
+ def test_split_name_too_long_total
+ assert_raises Gem::Package::TooLongFileName do
+ @tar_writer.split_name 'a' * 257
+ end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_task.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_task.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_package_task.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,46 @@
+require_relative 'gemutilities'
+require 'rubygems'
+require 'rubygems/package_task'
+
+class TestGemPackageTask < MiniTest::Unit::TestCase
+
+ def test_gem_package
+ gem = Gem::Specification.new do |g|
+ g.name = "pkgr"
+ g.version = "1.2.3"
+ g.files = Rake::FileList["x"].resolve
+ end
+ pkg = Gem::PackageTask.new(gem) do |p|
+ p.package_files << "y"
+ end
+ assert_equal ["x", "y"], pkg.package_files
+ end
+
+ def test_gem_package_with_current_platform
+ gem = Gem::Specification.new do |g|
+ g.name = "pkgr"
+ g.version = "1.2.3"
+ g.files = Rake::FileList["x"].resolve
+ g.platform = Gem::Platform::CURRENT
+ end
+ pkg = Gem::PackageTask.new(gem) do |p|
+ p.package_files << "y"
+ end
+ assert_equal ["x", "y"], pkg.package_files
+ end
+
+ def test_gem_package_with_ruby_platform
+ gem = Gem::Specification.new do |g|
+ g.name = "pkgr"
+ g.version = "1.2.3"
+ g.files = Rake::FileList["x"].resolve
+ g.platform = Gem::Platform::RUBY
+ end
+ pkg = Gem::PackageTask.new(gem) do |p|
+ p.package_files << "y"
+ end
+ assert_equal ["x", "y"], pkg.package_files
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_platform.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_platform.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_platform.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,264 @@
+require_relative 'gemutilities'
+require 'rubygems/platform'
+require 'rbconfig'
+
+class TestGemPlatform < RubyGemTestCase
+
+ def test_self_local
+ util_set_arch 'i686-darwin8.10.1'
+
+ assert_equal Gem::Platform.new(%w[x86 darwin 8]), Gem::Platform.local
+ end
+
+ def test_self_match
+ assert Gem::Platform.match(nil), 'nil == ruby'
+ assert Gem::Platform.match(Gem::Platform.local), 'exact match'
+ assert Gem::Platform.match(Gem::Platform.local.to_s), '=~ match'
+ assert Gem::Platform.match(Gem::Platform::RUBY), 'ruby'
+ end
+
+ def test_self_new
+ assert_equal Gem::Platform.local, Gem::Platform.new(Gem::Platform::CURRENT)
+ assert_equal Gem::Platform::RUBY, Gem::Platform.new(Gem::Platform::RUBY)
+ assert_equal Gem::Platform::RUBY, Gem::Platform.new(nil)
+ assert_equal Gem::Platform::RUBY, Gem::Platform.new('')
+ end
+
+ def test_initialize
+ test_cases = {
+ 'amd64-freebsd6' => ['amd64', 'freebsd', '6'],
+ 'hppa2.0w-hpux11.31' => ['hppa2.0w', 'hpux', '11'],
+ 'java' => [nil, 'java', nil],
+ 'jruby' => [nil, 'java', nil],
+ 'universal-dotnet' => ['universal', 'dotnet', nil],
+ 'universal-dotnet2.0' => ['universal', 'dotnet', '2.0'],
+ 'universal-dotnet4.0' => ['universal', 'dotnet', '4.0'],
+ 'powerpc-aix5.3.0.0' => ['powerpc', 'aix', '5'],
+ 'powerpc-darwin7' => ['powerpc', 'darwin', '7'],
+ 'powerpc-darwin8' => ['powerpc', 'darwin', '8'],
+ 'powerpc-linux' => ['powerpc', 'linux', nil],
+ 'powerpc64-linux' => ['powerpc64', 'linux', nil],
+ 'sparc-solaris2.10' => ['sparc', 'solaris', '2.10'],
+ 'sparc-solaris2.8' => ['sparc', 'solaris', '2.8'],
+ 'sparc-solaris2.9' => ['sparc', 'solaris', '2.9'],
+ 'universal-darwin8' => ['universal', 'darwin', '8'],
+ 'universal-darwin9' => ['universal', 'darwin', '9'],
+ 'i386-cygwin' => ['x86', 'cygwin', nil],
+ 'i686-darwin' => ['x86', 'darwin', nil],
+ 'i686-darwin8.4.1' => ['x86', 'darwin', '8'],
+ 'i386-freebsd4.11' => ['x86', 'freebsd', '4'],
+ 'i386-freebsd5' => ['x86', 'freebsd', '5'],
+ 'i386-freebsd6' => ['x86', 'freebsd', '6'],
+ 'i386-freebsd7' => ['x86', 'freebsd', '7'],
+ 'i386-java1.5' => ['x86', 'java', '1.5'],
+ 'x86-java1.6' => ['x86', 'java', '1.6'],
+ 'i386-java1.6' => ['x86', 'java', '1.6'],
+ 'i686-linux' => ['x86', 'linux', nil],
+ 'i586-linux' => ['x86', 'linux', nil],
+ 'i486-linux' => ['x86', 'linux', nil],
+ 'i386-linux' => ['x86', 'linux', nil],
+ 'i586-linux-gnu' => ['x86', 'linux', nil],
+ 'i386-linux-gnu' => ['x86', 'linux', nil],
+ 'i386-mingw32' => ['x86', 'mingw32', nil],
+ 'i386-mswin32' => ['x86', 'mswin32', nil],
+ 'i386-mswin32_80' => ['x86', 'mswin32', '80'],
+ 'i386-mswin32-80' => ['x86', 'mswin32', '80'],
+ 'x86-mswin32' => ['x86', 'mswin32', nil],
+ 'x86-mswin32_60' => ['x86', 'mswin32', '60'],
+ 'x86-mswin32-60' => ['x86', 'mswin32', '60'],
+ 'i386-netbsdelf' => ['x86', 'netbsdelf', nil],
+ 'i386-openbsd4.0' => ['x86', 'openbsd', '4.0'],
+ 'i386-solaris2.10' => ['x86', 'solaris', '2.10'],
+ 'i386-solaris2.8' => ['x86', 'solaris', '2.8'],
+ 'mswin32' => ['x86', 'mswin32', nil],
+ 'x86_64-linux' => ['x86_64', 'linux', nil],
+ 'x86_64-openbsd3.9' => ['x86_64', 'openbsd', '3.9'],
+ 'x86_64-openbsd4.0' => ['x86_64', 'openbsd', '4.0'],
+ }
+
+ test_cases.each do |arch, expected|
+ platform = Gem::Platform.new arch
+ assert_equal expected, platform.to_a, arch.inspect
+ end
+ end
+
+ def test_initialize_command_line
+ expected = ['x86', 'mswin32', nil]
+
+ platform = Gem::Platform.new 'i386-mswin32'
+
+ assert_equal expected, platform.to_a, 'i386-mswin32'
+
+ expected = ['x86', 'mswin32', '80']
+
+ platform = Gem::Platform.new 'i386-mswin32-80'
+
+ assert_equal expected, platform.to_a, 'i386-mswin32-80'
+
+ expected = ['x86', 'solaris', '2.10']
+
+ platform = Gem::Platform.new 'i386-solaris-2.10'
+
+ assert_equal expected, platform.to_a, 'i386-solaris-2.10'
+ end
+
+ def test_initialize_mswin32_vc6
+ orig_RUBY_SO_NAME = RbConfig::CONFIG['RUBY_SO_NAME']
+ RbConfig::CONFIG['RUBY_SO_NAME'] = 'msvcrt-ruby18'
+
+ expected = ['x86', 'mswin32', nil]
+
+ platform = Gem::Platform.new 'i386-mswin32'
+
+ assert_equal expected, platform.to_a, 'i386-mswin32 VC6'
+ ensure
+ RbConfig::CONFIG['RUBY_SO_NAME'] = orig_RUBY_SO_NAME
+ end
+
+ def test_initialize_platform
+ platform = Gem::Platform.new 'cpu-my_platform1'
+ expected = Gem::Platform.new platform
+
+ assert_equal 'cpu', platform.cpu
+ assert_equal 'my_platform', platform.os
+ assert_equal '1', platform.version
+ end
+
+ def test_initialize_test
+ platform = Gem::Platform.new 'cpu-my_platform1'
+ assert_equal 'cpu', platform.cpu
+ assert_equal 'my_platform', platform.os
+ assert_equal '1', platform.version
+
+ platform = Gem::Platform.new 'cpu-other_platform1'
+ assert_equal 'cpu', platform.cpu
+ assert_equal 'other_platform', platform.os
+ assert_equal '1', platform.version
+ end
+
+ def test_empty
+ platform = Gem::Platform.new 'cpu-other_platform1'
+ assert_respond_to platform, :empty?
+ assert_equal false, platform.empty?
+ end
+
+ def test_to_s
+ if win_platform? then
+ assert_equal 'x86-mswin32-60', Gem::Platform.local.to_s
+ else
+ assert_equal 'x86-darwin-8', Gem::Platform.local.to_s
+ end
+ end
+
+ def test_equals2
+ my = Gem::Platform.new %w[cpu my_platform 1]
+ other = Gem::Platform.new %w[cpu other_platform 1]
+
+ assert_equal my, my
+ refute_equal my, other
+ refute_equal other, my
+ end
+
+ def test_equals3
+ my = Gem::Platform.new %w[cpu my_platform 1]
+ other = Gem::Platform.new %w[cpu other_platform 1]
+
+ assert(my === my)
+ refute(other === my)
+ refute(my === other)
+ end
+
+ def test_equals3_cpu
+ ppc_darwin8 = Gem::Platform.new 'powerpc-darwin8.0'
+ uni_darwin8 = Gem::Platform.new 'universal-darwin8.0'
+ x86_darwin8 = Gem::Platform.new 'i686-darwin8.0'
+
+ util_set_arch 'powerpc-darwin8'
+ assert((ppc_darwin8 === Gem::Platform.local), 'powerpc =~ universal')
+ assert((uni_darwin8 === Gem::Platform.local), 'powerpc =~ universal')
+ refute((x86_darwin8 === Gem::Platform.local), 'powerpc =~ universal')
+
+ util_set_arch 'i686-darwin8'
+ refute((ppc_darwin8 === Gem::Platform.local), 'powerpc =~ universal')
+ assert((uni_darwin8 === Gem::Platform.local), 'x86 =~ universal')
+ assert((x86_darwin8 === Gem::Platform.local), 'powerpc =~ universal')
+
+ util_set_arch 'universal-darwin8'
+ assert((ppc_darwin8 === Gem::Platform.local), 'universal =~ ppc')
+ assert((uni_darwin8 === Gem::Platform.local), 'universal =~ universal')
+ assert((x86_darwin8 === Gem::Platform.local), 'universal =~ x86')
+ end
+
+ def test_equals3_version
+ util_set_arch 'i686-darwin8'
+
+ x86_darwin = Gem::Platform.new ['x86', 'darwin', nil]
+ x86_darwin7 = Gem::Platform.new ['x86', 'darwin', '7']
+ x86_darwin8 = Gem::Platform.new ['x86', 'darwin', '8']
+ x86_darwin9 = Gem::Platform.new ['x86', 'darwin', '9']
+
+ assert((x86_darwin === Gem::Platform.local), 'x86_darwin === x86_darwin8')
+ assert((x86_darwin8 === Gem::Platform.local), 'x86_darwin8 === x86_darwin8')
+
+ refute((x86_darwin7 === Gem::Platform.local), 'x86_darwin7 === x86_darwin8')
+ refute((x86_darwin9 === Gem::Platform.local), 'x86_darwin9 === x86_darwin8')
+ end
+
+ def test_equals_tilde
+ util_set_arch 'i386-mswin32'
+
+ assert_match 'mswin32', Gem::Platform.local
+ assert_match 'i386-mswin32', Gem::Platform.local
+
+ # oddballs
+ assert_match 'i386-mswin32-mq5.3', Gem::Platform.local
+ assert_match 'i386-mswin32-mq6', Gem::Platform.local
+ refute_match 'win32-1.8.2-VC7', Gem::Platform.local
+ refute_match 'win32-1.8.4-VC6', Gem::Platform.local
+ refute_match 'win32-source', Gem::Platform.local
+ refute_match 'windows', Gem::Platform.local
+
+ util_set_arch 'i686-linux'
+ assert_match 'i486-linux', Gem::Platform.local
+ assert_match 'i586-linux', Gem::Platform.local
+ assert_match 'i686-linux', Gem::Platform.local
+
+ util_set_arch 'i686-darwin8'
+ assert_match 'i686-darwin8.4.1', Gem::Platform.local
+ assert_match 'i686-darwin8.8.2', Gem::Platform.local
+
+ util_set_arch 'java'
+ assert_match 'java', Gem::Platform.local
+ assert_match 'jruby', Gem::Platform.local
+
+ util_set_arch 'universal-dotnet2.0'
+ assert_match 'universal-dotnet', Gem::Platform.local
+ assert_match 'universal-dotnet-2.0', Gem::Platform.local
+ refute_match 'universal-dotnet-4.0', Gem::Platform.local
+ assert_match 'dotnet', Gem::Platform.local
+ assert_match 'dotnet-2.0', Gem::Platform.local
+ refute_match 'dotnet-4.0', Gem::Platform.local
+
+ util_set_arch 'universal-dotnet4.0'
+ assert_match 'universal-dotnet', Gem::Platform.local
+ refute_match 'universal-dotnet-2.0', Gem::Platform.local
+ assert_match 'universal-dotnet-4.0', Gem::Platform.local
+ assert_match 'dotnet', Gem::Platform.local
+ refute_match 'dotnet-2.0', Gem::Platform.local
+ assert_match 'dotnet-4.0', Gem::Platform.local
+
+ util_set_arch 'powerpc-darwin'
+ assert_match 'powerpc-darwin', Gem::Platform.local
+
+ util_set_arch 'powerpc-darwin7'
+ assert_match 'powerpc-darwin7.9.0', Gem::Platform.local
+
+ util_set_arch 'powerpc-darwin8'
+ assert_match 'powerpc-darwin8.10.0', Gem::Platform.local
+
+ util_set_arch 'sparc-solaris2.8'
+ assert_match 'sparc-solaris2.8-mq5.3', Gem::Platform.local
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_remote_fetcher.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_remote_fetcher.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_remote_fetcher.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,740 @@
+require_relative 'gemutilities'
+require 'ostruct'
+require 'webrick'
+require 'rubygems/remote_fetcher'
+require 'rubygems/format'
+
+# = Testing Proxy Settings
+#
+# These tests check the proper proxy server settings by running two
+# web servers. The web server at http://localhost:#{SERVER_PORT}
+# represents the normal gem server and returns a gemspec with a rake
+# version of 0.4.11. The web server at http://localhost:#{PROXY_PORT}
+# represents the proxy server and returns a different dataset where
+# rake has version 0.4.2. This allows us to detect which server is
+# returning the data.
+#
+# Note that the proxy server is not a *real* proxy server. But our
+# software doesn't really care, as long as we hit the proxy URL when a
+# proxy is configured.
+
+class TestGemRemoteFetcher < RubyGemTestCase
+
+ include Gem::DefaultUserInteraction
+
+ SERVER_DATA = <<-EOY
+--- !ruby/object:Gem::Cache
+gems:
+ rake-0.4.11: !ruby/object:Gem::Specification
+ rubygems_version: "0.7"
+ specification_version: 1
+ name: rake
+ version: !ruby/object:Gem::Version
+ version: 0.4.11
+ date: 2004-11-12
+ summary: Ruby based make-like utility.
+ require_paths:
+ - lib
+ author: Jim Weirich
+ email: jim at weirichhouse.org
+ homepage: http://rake.rubyforge.org
+ rubyforge_project: rake
+ description: Rake is a Make-like program implemented in Ruby. Tasks and dependencies are specified in standard Ruby syntax.
+ autorequire:
+ default_executable: rake
+ bindir: bin
+ has_rdoc: true
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
+ requirements:
+ -
+ - ">"
+ - !ruby/object:Gem::Version
+ version: 0.0.0
+ version:
+ platform: ruby
+ files:
+ - README
+ test_files: []
+ library_stubs:
+ rdoc_options:
+ extra_rdoc_files:
+ executables:
+ - rake
+ extensions: []
+ requirements: []
+ dependencies: []
+ EOY
+
+ PROXY_DATA = SERVER_DATA.gsub(/0.4.11/, '0.4.2')
+
+ # don't let 1.8 and 1.9 autotest collide
+ RUBY_VERSION =~ /(\d+)\.(\d+)\.(\d+)/
+ # don't let parallel runners collide
+ PROXY_PORT = process_based_port + 100 + $1.to_i * 100 + $2.to_i * 10 + $3.to_i
+ SERVER_PORT = process_based_port + 200 + $1.to_i * 100 + $2.to_i * 10 + $3.to_i
+
+ def setup
+ super
+ self.class.start_servers
+ self.class.enable_yaml = true
+ self.class.enable_zip = false
+ ENV.delete 'http_proxy'
+ ENV.delete 'HTTP_PROXY'
+ ENV.delete 'http_proxy_user'
+ ENV.delete 'HTTP_PROXY_USER'
+ ENV.delete 'http_proxy_pass'
+ ENV.delete 'HTTP_PROXY_PASS'
+
+ base_server_uri = "http://localhost:#{SERVER_PORT}"
+ @proxy_uri = "http://localhost:#{PROXY_PORT}"
+
+ @server_uri = base_server_uri + "/yaml"
+ @server_z_uri = base_server_uri + "/yaml.Z"
+
+ # REFACTOR: copied from test_gem_dependency_installer.rb
+ @gems_dir = File.join @tempdir, 'gems'
+ @cache_dir = File.join @gemhome, 'cache'
+ FileUtils.mkdir @gems_dir
+
+ @a1, @a1_gem = util_gem 'a', '1' do |s| s.executables << 'a_bin' end
+
+ Gem::RemoteFetcher.fetcher = nil
+
+ @fetcher = Gem::RemoteFetcher.fetcher
+ end
+
+ def teardown
+ super
+ Gem.configuration[:http_proxy] = nil
+ end
+
+ def test_self_fetcher
+ fetcher = Gem::RemoteFetcher.fetcher
+ refute_nil fetcher
+ assert_kind_of Gem::RemoteFetcher, fetcher
+ end
+
+ def test_self_fetcher_with_proxy
+ proxy_uri = 'http://proxy.example.com'
+ Gem.configuration[:http_proxy] = proxy_uri
+ Gem::RemoteFetcher.fetcher = nil
+
+ fetcher = Gem::RemoteFetcher.fetcher
+
+ refute_nil fetcher
+ assert_kind_of Gem::RemoteFetcher, fetcher
+ assert_equal proxy_uri, fetcher.instance_variable_get(:@proxy_uri).to_s
+ end
+
+ def test_self_fetcher_with_proxy_URI
+ proxy_uri = URI.parse 'http://proxy.example.com'
+ Gem.configuration[:http_proxy] = proxy_uri
+ Gem::RemoteFetcher.fetcher = nil
+
+ fetcher = Gem::RemoteFetcher.fetcher
+ refute_nil fetcher
+
+ assert_kind_of Gem::RemoteFetcher, fetcher
+ assert_equal proxy_uri, fetcher.instance_variable_get(:@proxy_uri)
+ end
+
+ def test_fetch_size_bad_uri
+ fetcher = Gem::RemoteFetcher.new nil
+
+ e = assert_raises ArgumentError do
+ fetcher.fetch_size 'gems.example.com/yaml'
+ end
+
+ assert_equal 'uri scheme is invalid', e.message
+ end
+
+ def test_fetch_size_socket_error
+ fetcher = Gem::RemoteFetcher.new nil
+ def fetcher.connection_for(uri)
+ raise SocketError, "tarded"
+ end
+
+ uri = 'http://gems.example.com/yaml'
+ e = assert_raises Gem::RemoteFetcher::FetchError do
+ fetcher.fetch_size uri
+ end
+
+ assert_equal "SocketError: tarded (#{uri})", e.message
+ end
+
+ def test_no_proxy
+ use_ui @ui do
+ assert_data_from_server @fetcher.fetch_path(@server_uri)
+ assert_equal SERVER_DATA.size, @fetcher.fetch_size(@server_uri)
+ end
+ end
+
+ def util_fuck_with_fetcher data, blow = false
+ fetcher = Gem::RemoteFetcher.fetcher
+ fetcher.instance_variable_set :@test_data, data
+
+ unless blow then
+ def fetcher.fetch_path arg
+ @test_arg = arg
+ @test_data
+ end
+ else
+ def fetcher.fetch_path arg
+ # OMG I'm such an ass
+ class << self; remove_method :fetch_path; end
+ def self.fetch_path arg
+ @test_arg = arg
+ @test_data
+ end
+
+ raise Gem::RemoteFetcher::FetchError.new("haha!", nil)
+ end
+ end
+
+ fetcher
+ end
+
+ def test_download
+ a1_data = nil
+ File.open @a1_gem, 'rb' do |fp|
+ a1_data = fp.read
+ end
+
+ fetcher = util_fuck_with_fetcher a1_data
+
+ a1_cache_gem = File.join(@gemhome, 'cache', @a1.file_name)
+ assert_equal a1_cache_gem, fetcher.download(@a1, 'http://gems.example.com')
+ assert_equal("http://gems.example.com/gems/a-1.gem",
+ fetcher.instance_variable_get(:@test_arg).to_s)
+ assert File.exist?(a1_cache_gem)
+ end
+
+ def test_download_cached
+ FileUtils.mv @a1_gem, @cache_dir
+
+ inst = Gem::RemoteFetcher.fetcher
+
+ assert_equal File.join(@gemhome, 'cache', @a1.file_name),
+ inst.download(@a1, 'http://gems.example.com')
+ end
+
+ def test_download_local
+ FileUtils.mv @a1_gem, @tempdir
+ local_path = File.join @tempdir, @a1.file_name
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::RemoteFetcher.fetcher
+ end
+
+ assert_equal File.join(@gemhome, 'cache', @a1.file_name),
+ inst.download(@a1, local_path)
+ end
+
+ def test_download_local_space
+ space_path = File.join @tempdir, 'space path'
+ FileUtils.mkdir space_path
+ FileUtils.mv @a1_gem, space_path
+ local_path = File.join space_path, @a1.file_name
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::RemoteFetcher.fetcher
+ end
+
+ assert_equal File.join(@gemhome, 'cache', @a1.file_name),
+ inst.download(@a1, local_path)
+ end
+
+ def test_download_install_dir
+ a1_data = nil
+ File.open @a1_gem, 'rb' do |fp|
+ a1_data = fp.read
+ end
+
+ fetcher = util_fuck_with_fetcher a1_data
+
+ install_dir = File.join @tempdir, 'more_gems'
+
+ a1_cache_gem = File.join install_dir, 'cache', @a1.file_name
+ FileUtils.mkdir_p(File.dirname(a1_cache_gem))
+ actual = fetcher.download(@a1, 'http://gems.example.com', install_dir)
+
+ assert_equal a1_cache_gem, actual
+ assert_equal("http://gems.example.com/gems/a-1.gem",
+ fetcher.instance_variable_get(:@test_arg).to_s)
+
+ assert File.exist?(a1_cache_gem)
+ end
+
+ unless win_platform? # File.chmod doesn't work
+ def test_download_local_read_only
+ FileUtils.mv @a1_gem, @tempdir
+ local_path = File.join @tempdir, @a1.file_name
+ inst = nil
+ File.chmod 0555, File.join(@gemhome, 'cache')
+
+ Dir.chdir @tempdir do
+ inst = Gem::RemoteFetcher.fetcher
+ end
+
+ assert_equal File.join(@tempdir, @a1.file_name),
+ inst.download(@a1, local_path)
+ ensure
+ File.chmod 0755, File.join(@gemhome, 'cache')
+ end
+
+ def test_download_read_only
+ File.chmod 0555, File.join(@gemhome, 'cache')
+ File.chmod 0555, File.join(@gemhome)
+
+ fetcher = util_fuck_with_fetcher File.read(@a1_gem)
+ fetcher.download(@a1, 'http://gems.example.com')
+ assert File.exist?(File.join(Gem.user_dir, 'cache', @a1.file_name))
+ ensure
+ File.chmod 0755, File.join(@gemhome)
+ File.chmod 0755, File.join(@gemhome, 'cache')
+ end
+ end
+
+ def test_download_platform_legacy
+ original_platform = 'old-platform'
+
+ e1, e1_gem = util_gem 'e', '1' do |s|
+ s.platform = Gem::Platform::CURRENT
+ s.instance_variable_set :@original_platform, original_platform
+ end
+
+ e1_data = nil
+ File.open e1_gem, 'rb' do |fp|
+ e1_data = fp.read
+ end
+
+ fetcher = util_fuck_with_fetcher e1_data, :blow_chunks
+
+ e1_cache_gem = File.join(@gemhome, 'cache', e1.file_name)
+
+ assert_equal e1_cache_gem, fetcher.download(e1, 'http://gems.example.com')
+
+ assert_equal("http://gems.example.com/gems/#{e1.original_name}.gem",
+ fetcher.instance_variable_get(:@test_arg).to_s)
+ assert File.exist?(e1_cache_gem)
+ end
+
+ def test_download_same_file
+ FileUtils.mv @a1_gem, @tempdir
+ local_path = File.join @tempdir, @a1.file_name
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::RemoteFetcher.fetcher
+ end
+
+ cache_path = File.join @gemhome, 'cache', @a1.file_name
+ FileUtils.mv local_path, cache_path
+
+ gem = Gem::Format.from_file_by_path cache_path
+
+ assert_equal cache_path, inst.download(gem.spec, cache_path)
+ end
+
+ def test_download_unsupported
+ inst = Gem::RemoteFetcher.fetcher
+
+ e = assert_raises Gem::InstallError do
+ inst.download @a1, 'ftp://gems.rubyforge.org'
+ end
+
+ assert_equal 'unsupported URI scheme ftp', e.message
+ end
+
+ def test_explicit_proxy
+ use_ui @ui do
+ fetcher = Gem::RemoteFetcher.new @proxy_uri
+ assert_equal PROXY_DATA.size, fetcher.fetch_size(@server_uri)
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
+ end
+ end
+
+ def test_explicit_proxy_with_user_auth
+ use_ui @ui do
+ uri = URI.parse @proxy_uri
+ uri.user, uri.password = 'foo', 'bar'
+ fetcher = Gem::RemoteFetcher.new uri.to_s
+ proxy = fetcher.instance_variable_get("@proxy_uri")
+ assert_equal 'foo', proxy.user
+ assert_equal 'bar', proxy.password
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
+ end
+
+ use_ui @ui do
+ uri = URI.parse @proxy_uri
+ uri.user, uri.password = 'domain%5Cuser', 'bar'
+ fetcher = Gem::RemoteFetcher.new uri.to_s
+ proxy = fetcher.instance_variable_get("@proxy_uri")
+ assert_equal 'domain\user', URI.unescape(proxy.user)
+ assert_equal 'bar', proxy.password
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
+ end
+
+ use_ui @ui do
+ uri = URI.parse @proxy_uri
+ uri.user, uri.password = 'user', 'my%20pass'
+ fetcher = Gem::RemoteFetcher.new uri.to_s
+ proxy = fetcher.instance_variable_get("@proxy_uri")
+ assert_equal 'user', proxy.user
+ assert_equal 'my pass', URI.unescape(proxy.password)
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
+ end
+ end
+
+ def test_explicit_proxy_with_user_auth_in_env
+ use_ui @ui do
+ ENV['http_proxy'] = @proxy_uri
+ ENV['http_proxy_user'] = 'foo'
+ ENV['http_proxy_pass'] = 'bar'
+ fetcher = Gem::RemoteFetcher.new nil
+ proxy = fetcher.instance_variable_get("@proxy_uri")
+ assert_equal 'foo', proxy.user
+ assert_equal 'bar', proxy.password
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
+ end
+
+ use_ui @ui do
+ ENV['http_proxy'] = @proxy_uri
+ ENV['http_proxy_user'] = 'foo\user'
+ ENV['http_proxy_pass'] = 'my bar'
+ fetcher = Gem::RemoteFetcher.new nil
+ proxy = fetcher.instance_variable_get("@proxy_uri")
+ assert_equal 'foo\user', URI.unescape(proxy.user)
+ assert_equal 'my bar', URI.unescape(proxy.password)
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
+ end
+ end
+
+ def test_fetch_path_gzip
+ fetcher = Gem::RemoteFetcher.new nil
+
+ def fetcher.open_uri_or_path(uri, mtime, head = nil)
+ Gem.gzip 'foo'
+ end
+
+ assert_equal 'foo', fetcher.fetch_path(@uri + 'foo.gz')
+ end
+
+ def test_fetch_path_gzip_unmodified
+ fetcher = Gem::RemoteFetcher.new nil
+
+ def fetcher.open_uri_or_path(uri, mtime, head = nil)
+ nil
+ end
+
+ assert_equal nil, fetcher.fetch_path(@uri + 'foo.gz', Time.at(0))
+ end
+
+ def test_fetch_path_io_error
+ fetcher = Gem::RemoteFetcher.new nil
+
+ def fetcher.open_uri_or_path(uri, mtime, head = nil)
+ raise EOFError
+ end
+
+ e = assert_raises Gem::RemoteFetcher::FetchError do
+ fetcher.fetch_path 'uri'
+ end
+
+ assert_equal 'EOFError: EOFError (uri)', e.message
+ assert_equal 'uri', e.uri
+ end
+
+ def test_fetch_path_socket_error
+ fetcher = Gem::RemoteFetcher.new nil
+
+ def fetcher.open_uri_or_path(uri, mtime, head = nil)
+ raise SocketError
+ end
+
+ e = assert_raises Gem::RemoteFetcher::FetchError do
+ fetcher.fetch_path 'uri'
+ end
+
+ assert_equal 'SocketError: SocketError (uri)', e.message
+ assert_equal 'uri', e.uri
+ end
+
+ def test_fetch_path_system_call_error
+ fetcher = Gem::RemoteFetcher.new nil
+
+ def fetcher.open_uri_or_path(uri, mtime = nil, head = nil)
+ raise Errno::ECONNREFUSED, 'connect(2)'
+ end
+
+ e = assert_raises Gem::RemoteFetcher::FetchError do
+ fetcher.fetch_path 'uri'
+ end
+
+ assert_match %r|ECONNREFUSED:.*connect\(2\) \(uri\)\z|,
+ e.message
+ assert_equal 'uri', e.uri
+ end
+
+ def test_fetch_path_unmodified
+ fetcher = Gem::RemoteFetcher.new nil
+
+ def fetcher.open_uri_or_path(uri, mtime, head = nil)
+ nil
+ end
+
+ assert_equal nil, fetcher.fetch_path(URI.parse(@gem_repo), Time.at(0))
+ end
+
+ def test_get_proxy_from_env_auto_normalizes
+ fetcher = Gem::RemoteFetcher.new(nil)
+ ENV['HTTP_PROXY'] = 'fakeurl:12345'
+
+ assert_equal('http://fakeurl:12345', fetcher.get_proxy_from_env.to_s)
+ end
+
+ def test_get_proxy_from_env_empty
+ orig_env_HTTP_PROXY = ENV['HTTP_PROXY']
+ orig_env_http_proxy = ENV['http_proxy']
+
+ ENV['HTTP_PROXY'] = ''
+ ENV.delete 'http_proxy'
+
+ fetcher = Gem::RemoteFetcher.new nil
+
+ assert_equal nil, fetcher.send(:get_proxy_from_env)
+
+ ensure
+ orig_env_HTTP_PROXY.nil? ? ENV.delete('HTTP_PROXY') :
+ ENV['HTTP_PROXY'] = orig_env_HTTP_PROXY
+ orig_env_http_proxy.nil? ? ENV.delete('http_proxy') :
+ ENV['http_proxy'] = orig_env_http_proxy
+ end
+
+ def test_implicit_no_proxy
+ use_ui @ui do
+ ENV['http_proxy'] = 'http://fakeurl:12345'
+ fetcher = Gem::RemoteFetcher.new :no_proxy
+ assert_data_from_server fetcher.fetch_path(@server_uri)
+ end
+ end
+
+ def test_implicit_proxy
+ use_ui @ui do
+ ENV['http_proxy'] = @proxy_uri
+ fetcher = Gem::RemoteFetcher.new nil
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
+ end
+ end
+
+ def test_implicit_upper_case_proxy
+ use_ui @ui do
+ ENV['HTTP_PROXY'] = @proxy_uri
+ fetcher = Gem::RemoteFetcher.new nil
+ assert_data_from_proxy fetcher.fetch_path(@server_uri)
+ end
+ end
+
+ def test_implicit_proxy_no_env
+ use_ui @ui do
+ fetcher = Gem::RemoteFetcher.new nil
+ assert_data_from_server fetcher.fetch_path(@server_uri)
+ end
+ end
+
+ def test_open_uri_or_path
+ fetcher = Gem::RemoteFetcher.new nil
+
+ conn = Object.new
+ def conn.started?() true end
+ def conn.request(req)
+ unless defined? @requested then
+ @requested = true
+ res = Net::HTTPMovedPermanently.new nil, 301, nil
+ res.add_field 'Location', 'http://gems.example.com/real_path'
+ res
+ else
+ res = Net::HTTPOK.new nil, 200, nil
+ def res.body() 'real_path' end
+ res
+ end
+ end
+
+ conn = { 'gems.example.com:80' => conn }
+ fetcher.instance_variable_set :@connections, conn
+
+ data = fetcher.open_uri_or_path 'http://gems.example.com/redirect'
+
+ assert_equal 'real_path', data
+ end
+
+ def test_open_uri_or_path_limited_redirects
+ fetcher = Gem::RemoteFetcher.new nil
+
+ conn = Object.new
+ def conn.started?() true end
+ def conn.request(req)
+ res = Net::HTTPMovedPermanently.new nil, 301, nil
+ res.add_field 'Location', 'http://gems.example.com/redirect'
+ res
+ end
+
+ conn = { 'gems.example.com:80' => conn }
+ fetcher.instance_variable_set :@connections, conn
+
+ e = assert_raises Gem::RemoteFetcher::FetchError do
+ fetcher.open_uri_or_path 'http://gems.example.com/redirect'
+ end
+
+ assert_equal 'too many redirects (http://gems.example.com/redirect)',
+ e.message
+ end
+
+ def test_request
+ uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}"
+ util_stub_connection_for :body => :junk, :code => 200
+
+ response = @fetcher.request uri, Net::HTTP::Get
+
+ assert_equal 200, response.code
+ assert_equal :junk, response.body
+ end
+
+ def test_request_head
+ uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}"
+ util_stub_connection_for :body => '', :code => 200
+ response = @fetcher.request uri, Net::HTTP::Head
+
+ assert_equal 200, response.code
+ assert_equal '', response.body
+ end
+
+ def test_request_unmodifed
+ uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}"
+ conn = util_stub_connection_for :body => '', :code => 304
+
+ t = Time.now
+ response = @fetcher.request uri, Net::HTTP::Head, t
+
+ assert_equal 304, response.code
+ assert_equal '', response.body
+
+ assert_equal t.rfc2822, conn.payload['if-modified-since']
+ end
+
+ def test_yaml_error_on_size
+ use_ui @ui do
+ self.class.enable_yaml = false
+ fetcher = Gem::RemoteFetcher.new nil
+ assert_error { fetcher.size }
+ end
+ end
+
+ def util_stub_connection_for hash
+ def @fetcher.connection= conn
+ @conn = conn
+ end
+
+ def @fetcher.connection_for uri
+ @conn
+ end
+
+ @fetcher.connection = Conn.new OpenStruct.new(hash)
+ end
+
+ def assert_error(exception_class=Exception)
+ got_exception = false
+ begin
+ yield
+ rescue exception_class => ex
+ got_exception = true
+ end
+ assert got_exception, "Expected exception conforming to #{exception_class}"
+ end
+
+ def assert_data_from_server(data)
+ assert_block("Data is not from server") { data =~ /0\.4\.11/ }
+ end
+
+ def assert_data_from_proxy(data)
+ assert_block("Data is not from proxy") { data =~ /0\.4\.2/ }
+ end
+
+ class Conn
+ attr_accessor :payload
+
+ def initialize(response)
+ @response = response
+ self.payload = nil
+ end
+
+ def request(req)
+ self.payload = req
+ @response
+ end
+ end
+
+ class NilLog < WEBrick::Log
+ def log(level, data) #Do nothing
+ end
+ end
+
+ class << self
+ attr_reader :normal_server, :proxy_server
+ attr_accessor :enable_zip, :enable_yaml
+
+ def start_servers
+ @normal_server ||= start_server(SERVER_PORT, SERVER_DATA)
+ @proxy_server ||= start_server(PROXY_PORT, PROXY_DATA)
+ @enable_yaml = true
+ @enable_zip = false
+ end
+
+ private
+
+ def start_server(port, data)
+ Thread.new do
+ begin
+ null_logger = NilLog.new
+ s = WEBrick::HTTPServer.new(
+ :Port => port,
+ :DocumentRoot => nil,
+ :Logger => null_logger,
+ :AccessLog => null_logger
+ )
+ s.mount_proc("/kill") { |req, res| s.shutdown }
+ s.mount_proc("/yaml") { |req, res|
+ if @enable_yaml
+ res.body = data
+ res['Content-Type'] = 'text/plain'
+ res['content-length'] = data.size
+ else
+ res.status = "404"
+ res.body = "<h1>NOT FOUND</h1>"
+ res['Content-Type'] = 'text/html'
+ end
+ }
+ s.mount_proc("/yaml.Z") { |req, res|
+ if @enable_zip
+ res.body = Zlib::Deflate.deflate(data)
+ res['Content-Type'] = 'text/plain'
+ else
+ res.status = "404"
+ res.body = "<h1>NOT FOUND</h1>"
+ res['Content-Type'] = 'text/html'
+ end
+ }
+ s.start
+ rescue Exception => ex
+ abort ex.message
+ puts "ERROR during server thread: #{ex.message}"
+ end
+ end
+ sleep 0.2 # Give the servers time to startup
+ end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_requirement.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_requirement.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_requirement.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,292 @@
+require_relative 'gemutilities'
+require "rubygems/requirement"
+
+class TestGemRequirement < RubyGemTestCase
+
+ def test_equals2
+ r = req "= 1.2"
+ assert_equal r, r.dup
+ assert_equal r.dup, r
+
+ refute_requirement_equal "= 1.2", "= 1.3"
+ refute_requirement_equal "= 1.3", "= 1.2"
+
+ refute_equal Object.new, req("= 1.2")
+ refute_equal req("= 1.2"), Object.new
+ end
+
+ def test_initialize
+ assert_requirement_equal "= 2", "2"
+ assert_requirement_equal "= 2", ["2"]
+ assert_requirement_equal "= 2", v(2)
+ end
+
+ def test_class_available_as_gem_version_requirement
+ assert_same Gem::Requirement, Gem::Version::Requirement,
+ "Gem::Version::Requirement is aliased for old YAML compatibility."
+ end
+
+ def test_parse
+ assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse(' 1')
+ assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse('= 1')
+ assert_equal ['>', Gem::Version.new(1)], Gem::Requirement.parse('> 1')
+ assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse("=\n1")
+
+ assert_equal ['=', Gem::Version.new(2)],
+ Gem::Requirement.parse(Gem::Version.new('2'))
+ end
+
+ def test_parse_bad
+ e = assert_raises ArgumentError do
+ Gem::Requirement.parse nil
+ end
+
+ assert_equal 'Illformed requirement [nil]', e.message
+
+ e = assert_raises ArgumentError do
+ Gem::Requirement.parse ""
+ end
+
+ assert_equal 'Illformed requirement [""]', e.message
+ end
+
+ def test_prerelease_eh
+ r = req '= 1'
+
+ refute r.prerelease?
+
+ r = req '= 1.a'
+
+ assert r.prerelease?
+
+ r = req '> 1.a', '< 2'
+
+ assert r.prerelease?
+ end
+
+ def test_satisfied_by_eh_bang_equal
+ r = req '!= 1.2'
+
+ assert_satisfied_by nil, r
+ assert_satisfied_by "1.1", r
+ refute_satisfied_by "1.2", r
+ assert_satisfied_by "1.3", r
+ end
+
+ def test_satisfied_by_eh_blank
+ r = req "1.2"
+
+ refute_satisfied_by nil, r
+ refute_satisfied_by "1.1", r
+ assert_satisfied_by "1.2", r
+ refute_satisfied_by "1.3", r
+ end
+
+ def test_satisfied_by_eh_equal
+ r = req "= 1.2"
+
+ refute_satisfied_by nil, r
+ refute_satisfied_by "1.1", r
+ assert_satisfied_by "1.2", r
+ refute_satisfied_by "1.3", r
+ end
+
+ def test_satisfied_by_eh_gt
+ r = req "> 1.2"
+
+ refute_satisfied_by "1.1", r
+ refute_satisfied_by "1.2", r
+ assert_satisfied_by "1.3", r
+
+ assert_raises NoMethodError do
+ r.satisfied_by? nil
+ end
+ end
+
+ def test_satisfied_by_eh_gte
+ r = req ">= 1.2"
+
+ refute_satisfied_by "1.1", r
+ assert_satisfied_by "1.2", r
+ assert_satisfied_by "1.3", r
+
+ assert_raises NoMethodError do
+ r.satisfied_by? nil
+ end
+ end
+
+ def test_satisfied_by_eh_list
+ r = req "> 1.1", "< 1.3"
+
+ refute_satisfied_by "1.1", r
+ assert_satisfied_by "1.2", r
+ refute_satisfied_by "1.3", r
+
+ assert_raises NoMethodError do
+ r.satisfied_by? nil
+ end
+ end
+
+ def test_satisfied_by_eh_lt
+ r = req "< 1.2"
+
+ assert_satisfied_by "1.1", r
+ refute_satisfied_by "1.2", r
+ refute_satisfied_by "1.3", r
+
+ assert_raises NoMethodError do
+ r.satisfied_by? nil
+ end
+ end
+
+ def test_satisfied_by_eh_lte
+ r = req "<= 1.2"
+
+ assert_satisfied_by "1.1", r
+ assert_satisfied_by "1.2", r
+ refute_satisfied_by "1.3", r
+
+ assert_raises NoMethodError do
+ r.satisfied_by? nil
+ end
+ end
+
+ def test_satisfied_by_eh_tilde_gt
+ r = req "~> 1.2"
+
+ refute_satisfied_by "1.1", r
+ assert_satisfied_by "1.2", r
+ assert_satisfied_by "1.3", r
+
+ assert_raises NoMethodError do
+ r.satisfied_by? nil
+ end
+ end
+
+ def test_satisfied_by_eh_good
+ assert_satisfied_by "0.2.33", "= 0.2.33"
+ assert_satisfied_by "0.2.34", "> 0.2.33"
+ assert_satisfied_by "1.0", "= 1.0"
+ assert_satisfied_by "1.0", "1.0"
+ assert_satisfied_by "1.8.2", "> 1.8.0"
+ assert_satisfied_by "1.112", "> 1.111"
+ assert_satisfied_by "0.2", "> 0.0.0"
+ assert_satisfied_by "0.0.0.0.0.2", "> 0.0.0"
+ assert_satisfied_by "0.0.1.0", "> 0.0.0.1"
+ assert_satisfied_by "10.3.2", "> 9.3.2"
+ assert_satisfied_by "1.0.0.0", "= 1.0"
+ assert_satisfied_by "10.3.2", "!= 9.3.4"
+ assert_satisfied_by "10.3.2", "> 9.3.2"
+ assert_satisfied_by "10.3.2", "> 9.3.2"
+ assert_satisfied_by " 9.3.2", ">= 9.3.2"
+ assert_satisfied_by "9.3.2 ", ">= 9.3.2"
+ assert_satisfied_by "", "= 0"
+ assert_satisfied_by "", "< 0.1"
+ assert_satisfied_by " ", "< 0.1 "
+ assert_satisfied_by "", " < 0.1"
+ assert_satisfied_by " ", "> 0.a "
+ assert_satisfied_by "", " > 0.a"
+ assert_satisfied_by "3.1", "< 3.2.rc1"
+ assert_satisfied_by "3.2.0", "> 3.2.0.rc1"
+ assert_satisfied_by "3.2.0.rc2", "> 3.2.0.rc1"
+ assert_satisfied_by "3.0.rc2", "< 3.0"
+ assert_satisfied_by "3.0.rc2", "< 3.0.0"
+ assert_satisfied_by "3.0.rc2", "< 3.0.1"
+ end
+
+ def test_illformed_requirements
+ [ ">>> 1.3.5", "> blah" ].each do |rq|
+ assert_raises ArgumentError, "req [#{rq}] should fail" do
+ Gem::Requirement.new rq
+ end
+ end
+ end
+
+ def test_satisfied_by_eh_boxed
+ refute_satisfied_by "1.3", "~> 1.4"
+ assert_satisfied_by "1.4", "~> 1.4"
+ assert_satisfied_by "1.5", "~> 1.4"
+ refute_satisfied_by "2.0", "~> 1.4"
+
+ refute_satisfied_by "1.3", "~> 1.4.4"
+ refute_satisfied_by "1.4", "~> 1.4.4"
+ assert_satisfied_by "1.4.4", "~> 1.4.4"
+ assert_satisfied_by "1.4.5", "~> 1.4.4"
+ refute_satisfied_by "1.5", "~> 1.4.4"
+ refute_satisfied_by "2.0", "~> 1.4.4"
+
+ refute_satisfied_by "1.1.pre", "~> 1.0.0"
+ assert_satisfied_by "1.1.pre", "~> 1.1"
+ refute_satisfied_by "2.0.a", "~> 1.0"
+ assert_satisfied_by "2.0.a", "~> 2.0"
+ end
+
+ def test_satisfied_by_eh_multiple
+ req = [">= 1.4", "<= 1.6", "!= 1.5"]
+
+ refute_satisfied_by "1.3", req
+ assert_satisfied_by "1.4", req
+ refute_satisfied_by "1.5", req
+ assert_satisfied_by "1.6", req
+ refute_satisfied_by "1.7", req
+ refute_satisfied_by "2.0", req
+ end
+
+ def test_satisfied_by_boxed
+ refute_satisfied_by "1.3", "~> 1.4"
+ assert_satisfied_by "1.4", "~> 1.4"
+ assert_satisfied_by "1.5", "~> 1.4"
+ refute_satisfied_by "2.0", "~> 1.4"
+
+ refute_satisfied_by "1.3", "~> 1.4.4"
+ refute_satisfied_by "1.4", "~> 1.4.4"
+ assert_satisfied_by "1.4.4", "~> 1.4.4"
+ assert_satisfied_by "1.4.5", "~> 1.4.4"
+ refute_satisfied_by "1.5", "~> 1.4.4"
+ refute_satisfied_by "2.0", "~> 1.4.4"
+ end
+
+ def test_bad
+ refute_satisfied_by "", "> 0.1"
+ refute_satisfied_by "1.2.3", "!= 1.2.3"
+ refute_satisfied_by "1.2.003.0.0", "!= 1.02.3"
+ refute_satisfied_by "4.5.6", "< 1.2.3"
+ refute_satisfied_by "1.0", "> 1.1"
+ refute_satisfied_by "", "= 0.1"
+ refute_satisfied_by "1.1.1", "> 1.1.1"
+ refute_satisfied_by "1.2", "= 1.1"
+ refute_satisfied_by "1.40", "= 1.1"
+ refute_satisfied_by "1.3", "= 1.40"
+ refute_satisfied_by "9.3.3", "<= 9.3.2"
+ refute_satisfied_by "9.3.1", ">= 9.3.2"
+ refute_satisfied_by "9.3.03", "<= 9.3.2"
+ refute_satisfied_by "1.0.0.1", "= 1.0"
+ end
+
+ # Assert that two requirements are equal. Handles Gem::Requirements,
+ # strings, arrays, numbers, and versions.
+
+ def assert_requirement_equal expected, actual
+ assert_equal req(expected), req(actual)
+ end
+
+ # Assert that +version+ satisfies +requirement+.
+
+ def assert_satisfied_by version, requirement
+ assert req(requirement).satisfied_by?(v(version)),
+ "#{requirement} is satisfied by #{version}"
+ end
+
+ # Refute the assumption that two requirements are equal.
+
+ def refute_requirement_equal unexpected, actual
+ refute_equal req(unexpected), req(actual)
+ end
+
+ # Refute the assumption that +version+ satisfies +requirement+.
+
+ def refute_satisfied_by version, requirement
+ refute req(requirement).satisfied_by?(v(version)),
+ "#{requirement} is not satisfied by #{version}"
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_server.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_server.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_server.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,356 @@
+require_relative 'gemutilities'
+require 'rubygems/server'
+require 'stringio'
+
+class Gem::Server
+ attr_accessor :source_index
+ attr_reader :server
+end
+
+class TestGemServer < RubyGemTestCase
+
+ def setup
+ super
+
+ @a1 = quick_gem 'a', '1'
+ @a2 = quick_gem 'a', '2'
+
+ @server = Gem::Server.new Gem.dir, process_based_port, false
+ @req = WEBrick::HTTPRequest.new :Logger => nil
+ @res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0'
+ end
+
+ def test_spec_dirs
+ s = Gem::Server.new Gem.dir, process_based_port, false
+
+ assert_equal [File.join(Gem.dir, 'specifications')], s.spec_dirs
+
+ s = Gem::Server.new [Gem.dir, Gem.dir], process_based_port, false
+
+ assert_equal [File.join(Gem.dir, 'specifications'),
+ File.join(Gem.dir, 'specifications')], s.spec_dirs
+ end
+
+ def test_Marshal
+ data = StringIO.new "GET /Marshal.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.Marshal @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'application/octet-stream', @res['content-type']
+
+ si = Gem::SourceIndex.new
+ si.add_specs @a1, @a2
+
+ assert_equal si, Marshal.load(@res.body)
+ end
+
+ def test_Marshal_Z
+ data = StringIO.new "GET /Marshal.#{Gem.marshal_version}.Z HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.Marshal @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'application/x-deflate', @res['content-type']
+
+ si = Gem::SourceIndex.new
+ si.add_specs @a1, @a2
+
+ assert_equal si, Marshal.load(Gem.inflate(@res.body))
+ end
+
+ def test_latest_specs
+ data = StringIO.new "GET /latest_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.latest_specs @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'application/octet-stream', @res['content-type']
+ assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]],
+ Marshal.load(@res.body)
+ end
+
+ def test_latest_specs_gz
+ data = StringIO.new "GET /latest_specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.latest_specs @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'application/x-gzip', @res['content-type']
+ assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]],
+ Marshal.load(Gem.gunzip(@res.body))
+ end
+
+ def test_listen
+ util_listen
+
+ out, err = capture_io do
+ @server.listen
+ end
+
+ assert_equal 1, @server.server.listeners.length
+ end
+
+ def test_listen_addresses
+ util_listen
+
+ out, err = capture_io do
+ @server.listen %w[a b]
+ end
+
+ assert_equal 2, @server.server.listeners.length
+ end
+
+ def test_quick_a_1_gemspec_rz
+ data = StringIO.new "GET /quick/a-1.gemspec.rz HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.quick @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert @res['date']
+ assert_equal 'application/x-deflate', @res['content-type']
+
+ spec = YAML.load Gem.inflate(@res.body)
+ assert_equal 'a', spec.name
+ assert_equal Gem::Version.new(1), spec.version
+ end
+
+ def test_quick_a_1_mswin32_gemspec_rz
+ a1_p = quick_gem 'a', '1' do |s| s.platform = Gem::Platform.local end
+
+ data = StringIO.new "GET /quick/a-1-#{Gem::Platform.local}.gemspec.rz HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.quick @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert @res['date']
+ assert_equal 'application/x-deflate', @res['content-type']
+
+ spec = YAML.load Gem.inflate(@res.body)
+ assert_equal 'a', spec.name
+ assert_equal Gem::Version.new(1), spec.version
+ assert_equal Gem::Platform.local, spec.platform
+ end
+
+ def test_quick_common_substrings
+ ab1 = quick_gem 'ab', '1'
+
+ data = StringIO.new "GET /quick/a-1.gemspec.rz HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.quick @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert @res['date']
+ assert_equal 'application/x-deflate', @res['content-type']
+
+ spec = YAML.load Gem.inflate(@res.body)
+ assert_equal 'a', spec.name
+ assert_equal Gem::Version.new(1), spec.version
+ end
+
+ def test_quick_index
+ data = StringIO.new "GET /quick/index HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.quick @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'text/plain', @res['content-type']
+ assert_equal "a-1\na-2", @res.body
+ end
+
+ def test_quick_index_rz
+ data = StringIO.new "GET /quick/index.rz HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.quick @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'application/x-deflate', @res['content-type']
+ assert_equal "a-1\na-2", Gem.inflate(@res.body)
+ end
+
+ def test_quick_latest_index
+ data = StringIO.new "GET /quick/latest_index HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.quick @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'text/plain', @res['content-type']
+ assert_equal 'a-2', @res.body
+ end
+
+ def test_quick_latest_index_rz
+ data = StringIO.new "GET /quick/latest_index.rz HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.quick @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'application/x-deflate', @res['content-type']
+ assert_equal 'a-2', Gem.inflate(@res.body)
+ end
+
+ def test_quick_missing
+ data = StringIO.new "GET /quick/z-9.gemspec.rz HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.quick @req, @res
+
+ assert_equal 404, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'text/plain', @res['content-type']
+ assert_equal 'No gems found matching "z" "9" nil', @res.body
+ assert_equal 404, @res.status
+ end
+
+ def test_quick_marshal_a_1_gemspec_rz
+ data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-1.gemspec.rz HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.quick @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert @res['date']
+ assert_equal 'application/x-deflate', @res['content-type']
+
+ spec = Marshal.load Gem.inflate(@res.body)
+ assert_equal 'a', spec.name
+ assert_equal Gem::Version.new(1), spec.version
+ end
+
+ def test_quick_marshal_a_1_mswin32_gemspec_rz
+ a1_p = quick_gem 'a', '1' do |s| s.platform = Gem::Platform.local end
+
+ data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-1-#{Gem::Platform.local}.gemspec.rz HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.quick @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert @res['date']
+ assert_equal 'application/x-deflate', @res['content-type']
+
+ spec = Marshal.load Gem.inflate(@res.body)
+ assert_equal 'a', spec.name
+ assert_equal Gem::Version.new(1), spec.version
+ assert_equal Gem::Platform.local, spec.platform
+ end
+
+ def test_rdoc
+ data = StringIO.new "GET /rdoc?q=a HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.rdoc @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r|No documentation found|, @res.body
+ assert_equal 'text/html', @res['content-type']
+ end
+
+ def test_root
+ data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.root @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'text/html', @res['content-type']
+ end
+
+ def test_specs
+ data = StringIO.new "GET /specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.specs @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'application/octet-stream', @res['content-type']
+
+ assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY],
+ ['a', Gem::Version.new(2), Gem::Platform::RUBY]],
+ Marshal.load(@res.body)
+ end
+
+ def test_specs_gz
+ data = StringIO.new "GET /specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.specs @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'application/x-gzip', @res['content-type']
+
+ assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY],
+ ['a', Gem::Version.new(2), Gem::Platform::RUBY]],
+ Marshal.load(Gem.gunzip(@res.body))
+ end
+
+ def test_yaml
+ data = StringIO.new "GET /yaml.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.yaml @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'text/plain', @res['content-type']
+
+ si = Gem::SourceIndex.new
+ si.add_specs @a1, @a2
+
+ assert_equal si, YAML.load(@res.body)
+ end
+
+ def test_yaml_Z
+ data = StringIO.new "GET /yaml.#{Gem.marshal_version}.Z HTTP/1.0\r\n\r\n"
+ @req.parse data
+
+ @server.yaml @req, @res
+
+ assert_equal 200, @res.status, @res.body
+ assert_match %r| \d\d:\d\d:\d\d |, @res['date']
+ assert_equal 'application/x-deflate', @res['content-type']
+
+ si = Gem::SourceIndex.new
+ si.add_specs @a1, @a2
+
+ assert_equal si, YAML.load(Gem.inflate(@res.body))
+ end
+
+ def util_listen
+ webrick = Object.new
+ webrick.instance_variable_set :@listeners, []
+ def webrick.listeners() @listeners end
+ def webrick.listen(host, port)
+ socket = Object.new
+ socket.instance_variable_set :@host, host
+ socket.instance_variable_set :@port, port
+ def socket.addr() [nil, @port, @host] end
+ @listeners << socket
+ end
+
+ @server.instance_variable_set :@server, webrick
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_source_index.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_source_index.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_source_index.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,461 @@
+require_relative 'gemutilities'
+require 'rubygems/source_index'
+require 'rubygems/config_file'
+
+class Gem::SourceIndex
+ public :fetcher, :fetch_bulk_index, :fetch_quick_index,
+ :find_missing, :gems, :remove_extra,
+ :update_with_missing, :unzip
+end
+
+class TestGemSourceIndex < RubyGemTestCase
+
+ def setup
+ super
+
+ util_setup_fake_fetcher
+ end
+
+ def test_self_from_gems_in
+ spec_dir = File.join @gemhome, 'specifications'
+
+ FileUtils.rm_r spec_dir
+
+ FileUtils.mkdir_p spec_dir
+
+ a1 = quick_gem 'a', '1' do |spec| spec.author = 'author 1' end
+
+ spec_file = File.join spec_dir, a1.spec_name
+
+ File.open spec_file, 'w' do |fp|
+ fp.write a1.to_ruby
+ end
+
+ si = Gem::SourceIndex.from_gems_in spec_dir
+
+ assert_equal [spec_dir], si.spec_dirs
+ assert_equal [a1.full_name], si.gems.keys
+ end
+
+ def test_self_load_specification
+ spec_dir = File.join @gemhome, 'specifications'
+
+ FileUtils.rm_r spec_dir
+
+ FileUtils.mkdir_p spec_dir
+
+ a1 = quick_gem 'a', '1' do |spec| spec.author = 'author 1' end
+
+ spec_file = File.join spec_dir, a1.spec_name
+
+ File.open spec_file, 'w' do |fp|
+ fp.write a1.to_ruby
+ end
+
+ spec = Gem::SourceIndex.load_specification spec_file
+
+ assert_equal a1.author, spec.author
+ end
+
+ def test_self_load_specification_utf_8
+ spec_dir = File.join @gemhome, 'specifications'
+
+ FileUtils.rm_r spec_dir
+
+ FileUtils.mkdir_p spec_dir
+
+ spec_file = File.join spec_dir, "utf-8.gemspec"
+ spec_data = <<-SPEC
+Gem::Specification.new do |s|
+ s.name = %q{utf}
+ s.version = "8"
+
+ s.required_rubygems_version = Gem::Requirement.new(">= 0")
+ s.authors = ["\317\200"]
+ s.date = %q{2008-09-10}
+ s.description = %q{This is a test description}
+ s.email = %q{example at example.com}
+ s.has_rdoc = true
+ s.homepage = %q{http://example.com}
+ s.require_paths = ["lib"]
+ s.rubygems_version = %q{1.2.0}
+ s.summary = %q{this is a summary}
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 2
+
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+ else
+ end
+ else
+ end
+end
+ SPEC
+
+ spec_data.force_encoding 'UTF-8'
+
+ File.open spec_file, 'w' do |io| io.write spec_data end
+
+ spec = Gem::SourceIndex.load_specification spec_file
+
+ pi = "\317\200"
+ pi.force_encoding 'UTF-8' if pi.respond_to? :force_encoding
+
+ assert_equal pi, spec.author
+ end if Gem.ruby_version > Gem::Version.new('1.9')
+
+ def test_self_load_specification_exception
+ spec_dir = File.join @gemhome, 'specifications'
+
+ FileUtils.mkdir_p spec_dir
+
+ spec_file = File.join spec_dir, 'a-1.gemspec'
+
+ File.open spec_file, 'w' do |fp|
+ fp.write 'raise Exception, "epic fail"'
+ end
+
+ use_ui @ui do
+ assert_equal nil, Gem::SourceIndex.load_specification(spec_file)
+ end
+
+ assert_equal '', @ui.output
+
+ expected = <<-EOF
+WARNING: #<Exception: epic fail>
+raise Exception, "epic fail"
+WARNING: Invalid .gemspec format in '#{spec_file}'
+ EOF
+
+ assert_equal expected, @ui.error
+ end
+
+ def test_self_load_specification_interrupt
+ spec_dir = File.join @gemhome, 'specifications'
+
+ FileUtils.mkdir_p spec_dir
+
+ spec_file = File.join spec_dir, 'a-1.gemspec'
+
+ File.open spec_file, 'w' do |fp|
+ fp.write 'raise Interrupt, "^C"'
+ end
+
+ use_ui @ui do
+ assert_raises Interrupt do
+ Gem::SourceIndex.load_specification(spec_file)
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_self_load_specification_syntax_error
+ spec_dir = File.join @gemhome, 'specifications'
+
+ FileUtils.mkdir_p spec_dir
+
+ spec_file = File.join spec_dir, 'a-1.gemspec'
+
+ File.open spec_file, 'w' do |fp|
+ fp.write '1 +'
+ end
+
+ use_ui @ui do
+ assert_equal nil, Gem::SourceIndex.load_specification(spec_file)
+ end
+
+ assert_equal '', @ui.output
+
+ assert_match(/syntax error/, @ui.error)
+ assert_match(/1 \+/, @ui.error)
+ end
+
+ def test_self_load_specification_system_exit
+ spec_dir = File.join @gemhome, 'specifications'
+
+ FileUtils.mkdir_p spec_dir
+
+ spec_file = File.join spec_dir, 'a-1.gemspec'
+
+ File.open spec_file, 'w' do |fp|
+ fp.write 'raise SystemExit, "bye-bye"'
+ end
+
+ use_ui @ui do
+ assert_raises SystemExit do
+ Gem::SourceIndex.load_specification(spec_file)
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_create_from_directory
+ # TODO
+ end
+
+ def test_fetcher
+ assert_equal @fetcher, @source_index.fetcher
+ end
+
+ def test_find_missing
+ missing = @source_index.find_missing [@b2.full_name]
+ assert_equal [@b2.full_name], missing
+ end
+
+ def test_find_missing_none_missing
+ missing = @source_index.find_missing [
+ @a1.full_name, @a2.full_name, @c1_2.full_name
+ ]
+
+ assert_equal [], missing
+ end
+
+ def test_find_name
+ assert_equal [@a1, @a2, @a3a], @source_index.find_name('a')
+ assert_equal [@a2], @source_index.find_name('a', '= 2')
+ assert_equal [], @source_index.find_name('bogusstring')
+ assert_equal [], @source_index.find_name('a', '= 3')
+
+ source_index = Gem::SourceIndex.new
+ source_index.add_spec @a1
+ source_index.add_spec @a2
+
+ assert_equal [@a1], source_index.find_name(@a1.name, '= 1')
+
+ r1 = Gem::Requirement.create '= 1'
+ assert_equal [@a1], source_index.find_name(@a1.name, r1)
+ end
+
+ def test_find_name_empty_cache
+ empty_source_index = Gem::SourceIndex.new({})
+ assert_equal [], empty_source_index.find_name("foo")
+ end
+
+ def test_latest_specs
+ p1_ruby = quick_gem 'p', '1'
+ p1_platform = quick_gem 'p', '1' do |spec|
+ spec.platform = Gem::Platform::CURRENT
+ end
+
+ a1_platform = quick_gem @a1.name, (@a1.version) do |s|
+ s.platform = Gem::Platform.new 'x86-my_platform1'
+ end
+
+ a2_platform = quick_gem @a2.name, (@a2.version) do |s|
+ s.platform = Gem::Platform.new 'x86-my_platform1'
+ end
+
+ a2_platform_other = quick_gem @a2.name, (@a2.version) do |s|
+ s.platform = Gem::Platform.new 'x86-other_platform1'
+ end
+
+ a3_platform_other = quick_gem @a2.name, (@a2.version.bump) do |s|
+ s.platform = Gem::Platform.new 'x86-other_platform1'
+ end
+
+ @source_index.add_spec p1_ruby
+ @source_index.add_spec p1_platform
+ @source_index.add_spec a1_platform
+ @source_index.add_spec a2_platform
+ @source_index.add_spec a2_platform_other
+ @source_index.add_spec a3_platform_other
+
+ expected = [
+ @a2.full_name,
+ a2_platform.full_name,
+ a3_platform_other.full_name,
+ @c1_2.full_name,
+ @a_evil9.full_name,
+ p1_ruby.full_name,
+ p1_platform.full_name,
+ ].sort
+
+ latest_specs = @source_index.latest_specs.map { |s| s.full_name }.sort
+
+ assert_equal expected, latest_specs
+ end
+
+ def test_load_gems_in
+ spec_dir1 = File.join @gemhome, 'specifications'
+ spec_dir2 = File.join @tempdir, 'gemhome2', 'specifications'
+
+ FileUtils.rm_r spec_dir1
+
+ FileUtils.mkdir_p spec_dir1
+ FileUtils.mkdir_p spec_dir2
+
+ a1 = quick_gem 'a', '1' do |spec| spec.author = 'author 1' end
+ a2 = quick_gem 'a', '1' do |spec| spec.author = 'author 2' end
+
+ File.open File.join(spec_dir1, a1.spec_name), 'w' do |fp|
+ fp.write a1.to_ruby
+ end
+
+ File.open File.join(spec_dir2, a2.spec_name), 'w' do |fp|
+ fp.write a2.to_ruby
+ end
+
+ @source_index.load_gems_in spec_dir1, spec_dir2
+
+ assert_equal a1.author, @source_index.specification(a1.full_name).author
+ end
+
+ def test_outdated
+ util_setup_spec_fetcher
+
+ assert_equal [], @source_index.outdated
+
+ updated = quick_gem @a2.name, (@a2.version.bump)
+ util_setup_spec_fetcher updated
+
+ assert_equal [updated.name], @source_index.outdated
+
+ updated_platform = quick_gem @a2.name, (updated.version.bump) do |s|
+ s.platform = Gem::Platform.new 'x86-other_platform1'
+ end
+
+ util_setup_spec_fetcher updated, updated_platform
+
+ assert_equal [updated_platform.name], @source_index.outdated
+ end
+
+ def test_prerelease_specs_kept_in_right_place
+ gem_a1_alpha = quick_gem 'abba', '1.a'
+ @source_index.add_spec gem_a1_alpha
+
+ refute @source_index.latest_specs.include?(gem_a1_alpha)
+ assert @source_index.find_name(gem_a1_alpha.full_name).empty?
+ assert @source_index.prerelease_specs.include?(gem_a1_alpha)
+ end
+
+ def test_refresh_bang
+ a1_spec = File.join @gemhome, "specifications", @a1.spec_name
+
+ FileUtils.mv a1_spec, @tempdir
+
+ source_index = Gem::SourceIndex.from_installed_gems
+
+ refute source_index.gems.include?(@a1.full_name)
+
+ FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec
+
+ source_index.refresh!
+
+ assert source_index.gems.include?(@a1.full_name)
+ end
+
+ def test_refresh_bang_not_from_dir
+ source_index = Gem::SourceIndex.new
+
+ e = assert_raises RuntimeError do
+ source_index.refresh!
+ end
+
+ assert_equal 'source index not created from disk', e.message
+ end
+
+ def test_remove_extra
+ @source_index.add_spec @a1
+ @source_index.add_spec @a2
+ @source_index.add_spec @pl1
+
+ @source_index.remove_extra [@a1.full_name, @pl1.full_name]
+
+ assert_equal [@a1.full_name],
+ @source_index.gems.map { |n,s| n }.sort
+ end
+
+ def test_remove_extra_no_changes
+ gems = [@a1.full_name, @a2.full_name]
+ @source_index.add_spec @a1
+ @source_index.add_spec @a2
+
+ @source_index.remove_extra gems
+
+ assert_equal gems, @source_index.gems.map { |n,s| n }.sort
+ end
+
+ def test_remove_spec
+ deleted = @source_index.remove_spec 'a-1'
+
+ assert_equal %w[a-2 a-3.a a_evil-9 c-1.2],
+ @source_index.all_gems.values.map { |s| s.full_name }.sort
+
+ deleted = @source_index.remove_spec 'a-3.a'
+
+ assert_equal %w[a-2 a_evil-9 c-1.2],
+ @source_index.all_gems.values.map { |s| s.full_name }.sort
+ end
+
+ def test_search
+ requirement = Gem::Requirement.create '= 9'
+ with_version = Gem::Dependency.new(/^a/, requirement)
+ assert_equal [@a_evil9], @source_index.search(with_version)
+
+ with_default = Gem::Dependency.new(/^a/, Gem::Requirement.default)
+ assert_equal [@a1, @a2, @a3a, @a_evil9], @source_index.search(with_default)
+
+ c1_1_dep = Gem::Dependency.new 'c', '~> 1.1'
+ assert_equal [@c1_2], @source_index.search(c1_1_dep)
+ end
+
+ def test_search_platform
+ util_set_arch 'x86-my_platform1'
+
+ a1 = quick_gem 'a', '1'
+ a1_mine = quick_gem 'a', '1' do |s|
+ s.platform = Gem::Platform.new 'x86-my_platform1'
+ end
+ a1_other = quick_gem 'a', '1' do |s|
+ s.platform = Gem::Platform.new 'x86-other_platform1'
+ end
+
+ si = Gem::SourceIndex.new(a1.full_name => a1, a1_mine.full_name => a1_mine,
+ a1_other.full_name => a1_other)
+
+ dep = Gem::Dependency.new 'a', Gem::Requirement.new('1')
+
+ gems = si.search dep, true
+
+ assert_equal [a1, a1_mine], gems.sort
+ end
+
+ def test_signature
+ sig = @source_index.gem_signature('foo-1.2.3')
+ assert_equal 64, sig.length
+ assert_match(/^[a-f0-9]{64}$/, sig)
+ end
+
+ def test_specification
+ assert_equal @a1, @source_index.specification(@a1.full_name)
+
+ assert_nil @source_index.specification("foo-1.2.4")
+ end
+
+ def test_index_signature
+ sig = @source_index.index_signature
+ assert_match(/^[a-f0-9]{64}$/, sig)
+ end
+
+ def test_unzip
+ input = "x\234+\316\317MU(I\255(\001\000\021\350\003\232"
+ assert_equal 'some text', @source_index.unzip(input)
+ end
+
+ def util_setup_bulk_fetch(compressed)
+ source_index = @source_index.dump
+
+ if compressed then
+ @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}.Z"] = util_zip source_index
+ else
+ @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = source_index
+ end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_spec_fetcher.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_spec_fetcher.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_spec_fetcher.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,410 @@
+require_relative 'gemutilities'
+require 'rubygems/spec_fetcher'
+
+class TestGemSpecFetcher < RubyGemTestCase
+
+ def setup
+ super
+
+ @uri = URI.parse @gem_repo
+
+ util_setup_fake_fetcher
+
+ @a_pre = quick_gem 'a', '1.a'
+ @source_index.add_spec @pl1
+ @source_index.add_spec @a_pre
+
+ @specs = @source_index.gems.sort.map do |name, spec|
+ [spec.name, spec.version, spec.original_platform]
+ end.sort
+
+ @latest_specs = @source_index.latest_specs.sort.map do |spec|
+ [spec.name, spec.version, spec.original_platform]
+ end
+
+ @prerelease_specs = @source_index.prerelease_gems.sort.map do |name, spec|
+ [spec.name, spec.version, spec.original_platform]
+ end.sort
+
+ @fetcher.data["#{@gem_repo}specs.#{Gem.marshal_version}.gz"] =
+ util_gzip(Marshal.dump(@specs))
+
+ @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] =
+ util_gzip(Marshal.dump(@latest_specs))
+
+ @fetcher.data["#{@gem_repo}prerelease_specs.#{Gem.marshal_version}.gz"] =
+ util_gzip(Marshal.dump(@prerelease_specs))
+
+ @sf = Gem::SpecFetcher.new
+ end
+
+ def test_fetch_all
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] =
+ util_zip(Marshal.dump(@a1))
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.spec_name}.rz"] =
+ util_zip(Marshal.dump(@a2))
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.spec_name}.rz"] =
+ util_zip(Marshal.dump(@a_pre))
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a3a.spec_name}.rz"] =
+ util_zip(Marshal.dump(@a3a))
+
+ dep = Gem::Dependency.new 'a', 1
+
+ specs_and_sources = @sf.fetch dep, true
+
+ spec_names = specs_and_sources.map do |spec, source_uri|
+ [spec.full_name, source_uri]
+ end
+
+ expected = [[@a1.full_name, @gem_repo], [@a2.full_name, @gem_repo]]
+
+ assert_equal expected, spec_names
+
+ assert_same specs_and_sources.first.last, specs_and_sources.last.last
+ end
+
+ def test_fetch_latest
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] =
+ util_zip(Marshal.dump(@a1))
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.spec_name}.rz"] =
+ util_zip(Marshal.dump(@a2))
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.spec_name}.rz"] =
+ util_zip(Marshal.dump(@a_pre))
+
+ dep = Gem::Dependency.new 'a', 1
+ specs_and_sources = @sf.fetch dep
+
+ spec_names = specs_and_sources.map do |spec, source_uri|
+ [spec.full_name, source_uri]
+ end
+
+ assert_equal [[@a2.full_name, @gem_repo]], spec_names
+ end
+
+ def test_fetch_prerelease
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] =
+ util_zip(Marshal.dump(@a1))
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.spec_name}.rz"] =
+ util_zip(Marshal.dump(@a2))
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.spec_name}.rz"] =
+ util_zip(Marshal.dump(@a_pre))
+
+ dep = Gem::Dependency.new 'a', '1.a'
+ specs_and_sources = @sf.fetch dep, false, true, true
+
+ spec_names = specs_and_sources.map do |spec, source_uri|
+ [spec.full_name, source_uri]
+ end
+
+ assert_equal [[@a_pre.full_name, @gem_repo]], spec_names
+ end
+
+ def test_fetch_platform
+ util_set_arch 'i386-linux'
+
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@pl1.original_name}.gemspec.rz"] =
+ util_zip(Marshal.dump(@pl1))
+
+ dep = Gem::Dependency.new 'pl', 1
+ specs_and_sources = @sf.fetch dep
+
+ spec_names = specs_and_sources.map do |spec, source_uri|
+ [spec.full_name, source_uri]
+ end
+
+ assert_equal [[@pl1.full_name, @gem_repo]], spec_names
+ end
+
+ def test_fetch_with_errors_mismatched_platform
+ util_set_arch 'hrpa-989'
+
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@pl1.original_name}.gemspec.rz"] =
+ util_zip(Marshal.dump(@pl1))
+
+ dep = Gem::Dependency.new 'pl', 1
+ specs_and_sources, errors = @sf.fetch_with_errors dep
+
+ assert_equal 0, specs_and_sources.size
+ assert_equal 1, errors.size
+
+ assert_equal "i386-linux", errors[0].platforms.first
+ end
+
+ def test_fetch_spec
+ spec_uri = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}"
+ @fetcher.data["#{spec_uri}.rz"] = util_zip(Marshal.dump(@a1))
+
+ spec = @sf.fetch_spec ['a', Gem::Version.new(1), 'ruby'], @uri
+ assert_equal @a1.full_name, spec.full_name
+
+ cache_dir = @sf.cache_dir URI.parse(spec_uri)
+
+ cache_file = File.join cache_dir, @a1.spec_name
+
+ assert File.exist?(cache_file)
+ end
+
+ def test_fetch_spec_cached
+ spec_uri = "#{@gem_repo}/#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}"
+ @fetcher.data["#{spec_uri}.rz"] = nil
+
+ cache_dir = @sf.cache_dir URI.parse(spec_uri)
+ FileUtils.mkdir_p cache_dir
+
+ cache_file = File.join cache_dir, @a1.spec_name
+
+ open cache_file, 'wb' do |io|
+ Marshal.dump @a1, io
+ end
+
+ spec = @sf.fetch_spec ['a', Gem::Version.new(1), 'ruby'], @uri
+ assert_equal @a1.full_name, spec.full_name
+ end
+
+ def test_fetch_spec_platform
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@pl1.original_name}.gemspec.rz"] =
+ util_zip(Marshal.dump(@pl1))
+
+ spec = @sf.fetch_spec ['pl', Gem::Version.new(1), 'i386-linux'], @uri
+
+ assert_equal @pl1.full_name, spec.full_name
+ end
+
+ def test_fetch_spec_platform_ruby
+ @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] =
+ util_zip(Marshal.dump(@a1))
+
+ spec = @sf.fetch_spec ['a', Gem::Version.new(1), nil], @uri
+ assert_equal @a1.full_name, spec.full_name
+
+ spec = @sf.fetch_spec ['a', Gem::Version.new(1), ''], @uri
+ assert_equal @a1.full_name, spec.full_name
+ end
+
+ def test_find_matching_all
+ dep = Gem::Dependency.new 'a', 1
+ specs = @sf.find_matching dep, true
+
+ expected = [
+ [['a', Gem::Version.new(1), Gem::Platform::RUBY], @gem_repo],
+ [['a', Gem::Version.new(2), Gem::Platform::RUBY], @gem_repo],
+ ]
+
+ assert_equal expected, specs
+ end
+
+ def test_find_matching_latest
+ dep = Gem::Dependency.new 'a', 1
+ specs = @sf.find_matching dep
+
+ expected = [
+ [['a', Gem::Version.new(2), Gem::Platform::RUBY], @gem_repo],
+ ]
+
+ assert_equal expected, specs
+ end
+
+ def test_find_matching_prerelease
+ dep = Gem::Dependency.new 'a', '1.a'
+ specs = @sf.find_matching dep, false, true, true
+
+ expected = [
+ [['a', Gem::Version.new('1.a'), Gem::Platform::RUBY], @gem_repo],
+ ]
+
+ assert_equal expected, specs
+ end
+
+ def test_find_matching_platform
+ util_set_arch 'i386-linux'
+
+ dep = Gem::Dependency.new 'pl', 1
+ specs = @sf.find_matching dep
+
+ expected = [
+ [['pl', Gem::Version.new(1), 'i386-linux'], @gem_repo],
+ ]
+
+ assert_equal expected, specs
+
+ util_set_arch 'i386-freebsd6'
+
+ dep = Gem::Dependency.new 'pl', 1
+ specs = @sf.find_matching dep
+
+ assert_equal [], specs
+ end
+
+ def test_find_matching_with_errors_matched_platform
+ util_set_arch 'i386-linux'
+
+ dep = Gem::Dependency.new 'pl', 1
+ specs, errors = @sf.find_matching_with_errors dep
+
+ expected = [
+ [['pl', Gem::Version.new(1), 'i386-linux'], @gem_repo],
+ ]
+
+ assert_equal expected, specs
+ assert_equal 0, errors.size
+ end
+
+ def test_find_matching_with_errors_invalid_platform
+ util_set_arch 'hrpa-899'
+
+ dep = Gem::Dependency.new 'pl', 1
+ specs, errors = @sf.find_matching_with_errors dep
+
+ assert_equal 0, specs.size
+
+ assert_equal 1, errors.size
+
+ assert_equal "i386-linux", errors[0].platforms.first
+ end
+
+ def test_find_all_platforms
+ util_set_arch 'i386-freebsd6'
+
+ dep = Gem::Dependency.new 'pl', 1
+ specs = @sf.find_matching dep, false, false
+
+ expected = [
+ [['pl', Gem::Version.new(1), 'i386-linux'], @gem_repo],
+ ]
+
+ assert_equal expected, specs
+ end
+
+ def test_list
+ specs = @sf.list
+
+ assert_equal [@uri], specs.keys
+ assert_equal @latest_specs, specs[@uri].sort
+ end
+
+ def test_list_all
+ specs = @sf.list true
+
+ assert_equal [@uri], specs.keys
+
+ assert_equal([["a", Gem::Version.new("1"), "ruby"],
+ ["a", Gem::Version.new("2"), "ruby"],
+ ["a_evil", Gem::Version.new("9"), "ruby"],
+ ["c", Gem::Version.new("1.2"), "ruby"],
+ ["pl", Gem::Version.new("1"), "i386-linux"]],
+ specs[@uri].sort)
+ end
+
+ def test_list_cache
+ specs = @sf.list
+
+ refute specs[@uri].empty?
+
+ @fetcher.data["#{@gem_repo}/latest_specs.#{Gem.marshal_version}.gz"] = nil
+
+ cached_specs = @sf.list
+
+ assert_equal specs, cached_specs
+ end
+
+ def test_list_cache_all
+ specs = @sf.list true
+
+ refute specs[@uri].empty?
+
+ @fetcher.data["#{@gem_repo}/specs.#{Gem.marshal_version}.gz"] = nil
+
+ cached_specs = @sf.list true
+
+ assert_equal specs, cached_specs
+ end
+
+ def test_list_latest_all
+ specs = @sf.list false
+
+ assert_equal [@latest_specs], specs.values
+
+ specs = @sf.list true
+
+ assert_equal([[["a", Gem::Version.new("1"), "ruby"],
+ ["a", Gem::Version.new("2"), "ruby"],
+ ["a_evil", Gem::Version.new("9"), "ruby"],
+ ["c", Gem::Version.new("1.2"), "ruby"],
+ ["pl", Gem::Version.new("1"), "i386-linux"]]],
+ specs.values, 'specs file not loaded')
+ end
+
+ def test_list_prerelease
+ specs = @sf.list false, true
+
+ assert_equal @prerelease_specs, specs[@uri].sort
+ end
+
+ def test_load_specs
+ specs = @sf.load_specs @uri, 'specs'
+
+ expected = [
+ ['a', Gem::Version.new('1.a'), Gem::Platform::RUBY],
+ ['a', Gem::Version.new(1), Gem::Platform::RUBY],
+ ['a', Gem::Version.new(2), Gem::Platform::RUBY],
+ ['a', Gem::Version.new('3.a'), Gem::Platform::RUBY],
+ ['a_evil', Gem::Version.new(9), Gem::Platform::RUBY],
+ ['c', Gem::Version.new('1.2'), Gem::Platform::RUBY],
+ ['pl', Gem::Version.new(1), 'i386-linux'],
+ ]
+
+ assert_equal expected, specs
+
+ cache_dir = File.join Gem.user_home, '.gem', 'specs', 'gems.example.com%80'
+ assert File.exist?(cache_dir), "#{cache_dir} does not exist"
+
+ cache_file = File.join cache_dir, "specs.#{Gem.marshal_version}"
+ assert File.exist?(cache_file)
+ end
+
+ def test_load_specs_cached
+ @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = nil
+ @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}"] =
+ ' ' * Marshal.dump(@latest_specs).length
+
+ cache_dir = File.join Gem.user_home, '.gem', 'specs', 'gems.example.com%80'
+
+ FileUtils.mkdir_p cache_dir
+
+ cache_file = File.join cache_dir, "latest_specs.#{Gem.marshal_version}"
+
+ open cache_file, 'wb' do |io|
+ Marshal.dump @latest_specs, io
+ end
+
+ latest_specs = @sf.load_specs @uri, 'latest_specs'
+
+ assert_equal @latest_specs, latest_specs
+ end
+
+ def test_load_specs_cached_empty
+ @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] =
+ proc do
+ @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] =
+ util_gzip(Marshal.dump(@latest_specs))
+
+ nil
+ end
+
+ cache_dir = File.join Gem.user_home, '.gem', 'specs', 'gems.example.com%80'
+
+ FileUtils.mkdir_p cache_dir
+
+ cache_file = File.join cache_dir, "latest_specs.#{Gem.marshal_version}"
+
+ open cache_file, 'wb' do |io|
+ io.write Marshal.dump(@latest_specs)[0, 10]
+ end
+
+ latest_specs = @sf.load_specs @uri, 'latest_specs'
+
+ assert_equal @latest_specs, latest_specs
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_specification.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_specification.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_specification.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1283 @@
+require_relative 'gemutilities'
+require 'stringio'
+require 'rubygems/specification'
+
+class TestGemSpecification < RubyGemTestCase
+
+ LEGACY_YAML_SPEC = <<-EOF
+--- !ruby/object:Gem::Specification
+rubygems_version: "1.0"
+name: keyedlist
+version: !ruby/object:Gem::Version
+ version: 0.4.0
+date: 2004-03-28 15:37:49.828000 +02:00
+platform:
+summary: A Hash which automatically computes keys.
+require_paths:
+ - lib
+files:
+ - lib/keyedlist.rb
+autorequire: keyedlist
+author: Florian Gross
+email: flgr at ccan.de
+has_rdoc: true
+ EOF
+
+ LEGACY_RUBY_SPEC = <<-EOF
+Gem::Specification.new do |s|
+ s.name = %q{keyedlist}
+ s.version = %q{0.4.0}
+ s.has_rdoc = true
+ s.summary = %q{A Hash which automatically computes keys.}
+ s.files = ["lib/keyedlist.rb"]
+ s.require_paths = ["lib"]
+ s.autorequire = %q{keyedlist}
+ s.author = %q{Florian Gross}
+ s.email = %q{flgr at ccan.de}
+end
+ EOF
+
+ def setup
+ super
+
+ @a1 = quick_gem 'a', '1' do |s|
+ s.executable = 'exec'
+ s.extensions << 'ext/a/extconf.rb'
+ s.has_rdoc = 'true'
+ s.test_file = 'test/suite.rb'
+ s.requirements << 'A working computer'
+ s.rubyforge_project = 'example'
+ s.license = 'MIT'
+
+ s.add_dependency 'rake', '> 0.4'
+ s.add_dependency 'jabber4r', '> 0.0.0'
+ s.add_dependency 'pqa', ['> 0.4', '<= 0.6']
+
+ s.mark_version
+ s.files = %w[lib/code.rb]
+ end
+
+ @a2 = quick_gem 'a', '2' do |s|
+ s.files = %w[lib/code.rb]
+ end
+
+ FileUtils.mkdir_p File.join(@tempdir, 'bin')
+ File.open File.join(@tempdir, 'bin', 'exec'), 'w' do |fp|
+ fp.puts "#!#{Gem.ruby}"
+ end
+
+ @current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ end
+
+ def test_self_attribute_names
+ expected_value = %w[
+ authors
+ autorequire
+ bindir
+ cert_chain
+ date
+ default_executable
+ dependencies
+ description
+ email
+ executables
+ extensions
+ extra_rdoc_files
+ files
+ has_rdoc
+ homepage
+ licenses
+ name
+ platform
+ post_install_message
+ rdoc_options
+ require_paths
+ required_ruby_version
+ required_rubygems_version
+ requirements
+ rubyforge_project
+ rubygems_version
+ signing_key
+ specification_version
+ summary
+ test_files
+ version
+ ]
+
+ actual_value = Gem::Specification.attribute_names.map { |a| a.to_s }.sort
+
+ assert_equal expected_value, actual_value
+ end
+
+ def test_self__load_future
+ spec = Gem::Specification.new
+ spec.name = 'a'
+ spec.version = '1'
+ spec.specification_version = @current_version + 1
+
+ new_spec = Marshal.load Marshal.dump(spec)
+
+ assert_equal 'a', new_spec.name
+ assert_equal Gem::Version.new(1), new_spec.version
+ assert_equal @current_version, new_spec.specification_version
+ end
+
+ def test_self_load
+ spec = File.join @gemhome, 'specifications', @a2.spec_name
+ gs = Gem::Specification.load spec
+
+ assert_equal @a2, gs
+ end
+
+ def test_self_load_legacy_ruby
+ spec = eval LEGACY_RUBY_SPEC
+ assert_equal 'keyedlist', spec.name
+ assert_equal '0.4.0', spec.version.to_s
+ assert_equal true, spec.has_rdoc?
+ assert_equal Gem::Specification::TODAY, spec.date
+ assert spec.required_ruby_version.satisfied_by?(Gem::Version.new('1'))
+ assert_equal false, spec.has_unit_tests?
+ end
+
+ def test_self_normalize_yaml_input_with_183_yaml
+ input = "!ruby/object:Gem::Specification "
+ assert_equal "--- #{input}", Gem::Specification.normalize_yaml_input(input)
+ end
+
+ def test_self_normalize_yaml_input_with_non_183_yaml
+ input = "--- !ruby/object:Gem::Specification "
+ assert_equal input, Gem::Specification.normalize_yaml_input(input)
+ end
+
+ def test_self_normalize_yaml_input_with_183_io
+ input = "!ruby/object:Gem::Specification "
+ assert_equal "--- #{input}",
+ Gem::Specification.normalize_yaml_input(StringIO.new(input))
+ end
+
+ def test_self_normalize_yaml_input_with_non_183_io
+ input = "--- !ruby/object:Gem::Specification "
+ assert_equal input,
+ Gem::Specification.normalize_yaml_input(StringIO.new(input))
+ end
+
+ def test_initialize
+ spec = Gem::Specification.new do |s|
+ s.name = "blah"
+ s.version = "1.3.5"
+ end
+
+ assert_equal "blah", spec.name
+ assert_equal "1.3.5", spec.version.to_s
+ assert_equal Gem::Platform::RUBY, spec.platform
+ assert_equal nil, spec.summary
+ assert_equal [], spec.files
+
+ assert_equal [], spec.test_files
+ assert_equal [], spec.rdoc_options
+ assert_equal [], spec.extra_rdoc_files
+ assert_equal [], spec.executables
+ assert_equal [], spec.extensions
+ assert_equal [], spec.requirements
+ assert_equal [], spec.dependencies
+ assert_equal 'bin', spec.bindir
+ assert_equal true, spec.has_rdoc
+ assert_equal true, spec.has_rdoc?
+ assert_equal '>= 0', spec.required_ruby_version.to_s
+ assert_equal '>= 0', spec.required_rubygems_version.to_s
+ end
+
+ def test_initialize_future
+ version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + 1
+ spec = Gem::Specification.new do |s|
+ s.name = "blah"
+ s.version = "1.3.5"
+
+ s.specification_version = version
+
+ s.new_unknown_attribute = "a value"
+ end
+
+ assert_equal "blah", spec.name
+ assert_equal "1.3.5", spec.version.to_s
+ end
+
+ def test_initialize_copy
+ spec = Gem::Specification.new do |s|
+ s.name = "blah"
+ s.version = "1.3.5"
+ s.summary = 'summary'
+ s.description = 'description'
+ s.authors = 'author a', 'author b'
+ s.licenses = 'BSD'
+ s.files = 'lib/file.rb'
+ s.test_files = 'test/file.rb'
+ s.rdoc_options = '--foo'
+ s.extra_rdoc_files = 'README.txt'
+ s.executables = 'exec'
+ s.extensions = 'ext/extconf.rb'
+ s.requirements = 'requirement'
+ s.add_dependency 'some_gem'
+ end
+
+ new_spec = spec.dup
+
+ assert_equal "blah", spec.name
+ assert_same spec.name, new_spec.name
+
+ assert_equal "1.3.5", spec.version.to_s
+ assert_same spec.version, new_spec.version
+
+ assert_equal Gem::Platform::RUBY, spec.platform
+ assert_same spec.platform, new_spec.platform
+
+ assert_equal 'summary', spec.summary
+ assert_same spec.summary, new_spec.summary
+
+ assert_equal %w[lib/file.rb test/file.rb bin/exec README.txt
+ ext/extconf.rb],
+ spec.files
+ refute_same spec.files, new_spec.files, 'files'
+
+ assert_equal %w[test/file.rb], spec.test_files
+ refute_same spec.test_files, new_spec.test_files, 'test_files'
+
+ assert_equal %w[--foo], spec.rdoc_options
+ refute_same spec.rdoc_options, new_spec.rdoc_options, 'rdoc_options'
+
+ assert_equal %w[README.txt], spec.extra_rdoc_files
+ refute_same spec.extra_rdoc_files, new_spec.extra_rdoc_files,
+ 'extra_rdoc_files'
+
+ assert_equal %w[exec], spec.executables
+ refute_same spec.executables, new_spec.executables, 'executables'
+
+ assert_equal %w[ext/extconf.rb], spec.extensions
+ refute_same spec.extensions, new_spec.extensions, 'extensions'
+
+ assert_equal %w[requirement], spec.requirements
+ refute_same spec.requirements, new_spec.requirements, 'requirements'
+
+ assert_equal [Gem::Dependency.new('some_gem', Gem::Requirement.default)],
+ spec.dependencies
+ refute_same spec.dependencies, new_spec.dependencies, 'dependencies'
+
+ assert_equal 'bin', spec.bindir
+ assert_same spec.bindir, new_spec.bindir
+
+ assert_equal true, spec.has_rdoc
+ assert_same spec.has_rdoc, new_spec.has_rdoc
+
+ assert_equal '>= 0', spec.required_ruby_version.to_s
+ assert_same spec.required_ruby_version, new_spec.required_ruby_version
+
+ assert_equal '>= 0', spec.required_rubygems_version.to_s
+ assert_same spec.required_rubygems_version,
+ new_spec.required_rubygems_version
+ end
+
+ def test__dump
+ @a2.platform = Gem::Platform.local
+ @a2.instance_variable_set :@original_platform, 'old_platform'
+
+ data = Marshal.dump @a2
+
+ same_spec = Marshal.load data
+
+ assert_equal 'old_platform', same_spec.original_platform
+ end
+
+ def test_add_dependency_with_explicit_type
+ gem = quick_gem "awesome", "1.0" do |awesome|
+ awesome.add_development_dependency "monkey"
+ end
+
+ monkey = gem.dependencies.detect { |d| d.name == "monkey" }
+ assert_equal(:development, monkey.type)
+ end
+
+ def test_author
+ assert_equal 'A User', @a1.author
+ end
+
+ def test_authors
+ assert_equal ['A User'], @a1.authors
+ end
+
+ def test_bindir_equals
+ @a1.bindir = 'apps'
+
+ assert_equal 'apps', @a1.bindir
+ end
+
+ def test_bindir_equals_nil
+ @a2.bindir = nil
+ @a2.executable = 'app'
+
+ assert_equal nil, @a2.bindir
+ assert_equal %w[lib/code.rb app], @a2.files
+ end
+
+ def test_date
+ assert_equal Gem::Specification::TODAY, @a1.date
+ end
+
+ def test_date_equals_date
+ @a1.date = Date.new(2003, 9, 17)
+ assert_equal Time.local(2003, 9, 17, 0,0,0), @a1.date
+ end
+
+ def test_date_equals_string
+ @a1.date = '2003-09-17'
+ assert_equal Time.local(2003, 9, 17, 0,0,0), @a1.date
+ end
+
+ def test_date_equals_time
+ @a1.date = Time.local(2003, 9, 17, 0,0,0)
+ assert_equal Time.local(2003, 9, 17, 0,0,0), @a1.date
+ end
+
+ def test_date_equals_time_local
+ # HACK PDT
+ @a1.date = Time.local(2003, 9, 17, 19,50,0)
+ assert_equal Time.local(2003, 9, 17, 0,0,0), @a1.date
+ end
+
+ def test_date_equals_time_utc
+ # HACK PDT
+ @a1.date = Time.local(2003, 9, 17, 19,50,0)
+ assert_equal Time.local(2003, 9, 17, 0,0,0), @a1.date
+ end
+
+ def test_default_executable
+ assert_equal 'exec', @a1.default_executable
+
+ @a1.default_executable = nil
+ @a1.instance_variable_set :@executables, nil
+ assert_equal nil, @a1.default_executable
+ end
+
+ def test_dependencies
+ rake = Gem::Dependency.new 'rake', '> 0.4'
+ jabber = Gem::Dependency.new 'jabber4r', '> 0.0.0'
+ pqa = Gem::Dependency.new 'pqa', ['> 0.4', '<= 0.6']
+
+ assert_equal [rake, jabber, pqa], @a1.dependencies
+ end
+
+ def test_dependencies_scoped_by_type
+ gem = quick_gem "awesome", "1.0" do |awesome|
+ awesome.add_runtime_dependency "bonobo", []
+ awesome.add_development_dependency "monkey", []
+ end
+
+ bonobo = Gem::Dependency.new("bonobo", [])
+ monkey = Gem::Dependency.new("monkey", [], :development)
+
+ assert_equal([bonobo, monkey], gem.dependencies)
+ assert_equal([bonobo], gem.runtime_dependencies)
+ assert_equal([monkey], gem.development_dependencies)
+ end
+
+ def test_description
+ assert_equal 'This is a test description', @a1.description
+ end
+
+ def test_eql_eh
+ g1 = quick_gem 'gem'
+ g2 = quick_gem 'gem'
+
+ assert_equal g1, g2
+ assert_equal g1.hash, g2.hash
+ assert_equal true, g1.eql?(g2)
+ end
+
+ def test_equals2
+ assert_equal @a1, @a1
+ assert_equal @a1, @a1.dup
+ refute_equal @a1, @a2
+ refute_equal @a1, Object.new
+ end
+
+ # The cgikit specification was reported to be causing trouble in at least
+ # one version of RubyGems, so we test explicitly for it.
+ def test_equals2_cgikit
+ cgikit = Gem::Specification.new do |s|
+ s.name = %q{cgikit}
+ s.version = "1.1.0"
+ s.date = %q{2004-03-13}
+ s.summary = %q{CGIKit is a componented-oriented web application } +
+ %q{framework like Apple Computers WebObjects. } +
+ %{This framework services Model-View-Controller architecture } +
+ %q{programming by components based on a HTML file, a definition } +
+ %q{file and a Ruby source. }
+ s.email = %q{info at spice-of-life.net}
+ s.homepage = %q{http://www.spice-of-life.net/download/cgikit/}
+ s.autorequire = %q{cgikit}
+ s.bindir = nil
+ s.has_rdoc = true
+ s.required_ruby_version = nil
+ s.platform = nil
+ s.files = ["lib/cgikit", "lib/cgikit.rb", "lib/cgikit/components", "..."]
+ end
+
+ assert_equal cgikit, cgikit
+ end
+
+ def test_equals2_default_executable
+ spec = @a1.dup
+ spec.default_executable = 'xx'
+
+ refute_equal @a1, spec
+ refute_equal spec, @a1
+ end
+
+ def test_equals2_extensions
+ spec = @a1.dup
+ spec.extensions = 'xx'
+
+ refute_equal @a1, spec
+ refute_equal spec, @a1
+ end
+
+ def test_executables
+ @a1.executable = 'app'
+ assert_equal %w[app], @a1.executables
+ end
+
+ def test_executable_equals
+ @a2.executable = 'app'
+ assert_equal 'app', @a2.executable
+ assert_equal %w[lib/code.rb bin/app], @a2.files
+ end
+
+ def test_extensions
+ assert_equal ['ext/a/extconf.rb'], @a1.extensions
+ end
+
+ def test_files
+ @a1.files = %w(files bin/common)
+ @a1.test_files = %w(test_files bin/common)
+ @a1.executables = %w(executables common)
+ @a1.extra_rdoc_files = %w(extra_rdoc_files bin/common)
+ @a1.extensions = %w(extensions bin/common)
+
+ expected = %w[
+ bin/common
+ bin/executables
+ extensions
+ extra_rdoc_files
+ files
+ test_files
+ ]
+ assert_equal expected, @a1.files.sort
+ end
+
+ def test_files_append
+ @a1.files = %w(files bin/common)
+ @a1.test_files = %w(test_files bin/common)
+ @a1.executables = %w(executables common)
+ @a1.extra_rdoc_files = %w(extra_rdoc_files bin/common)
+ @a1.extensions = %w(extensions bin/common)
+
+ expected = %w[
+ bin/common
+ bin/executables
+ extensions
+ extra_rdoc_files
+ files
+ test_files
+ ]
+ assert_equal expected, @a1.files.sort
+
+ @a1.files << "generated_file.c"
+
+ expected << "generated_file.c"
+ expected.sort!
+
+ assert_equal expected, @a1.files.sort
+ end
+
+ def test_files_duplicate
+ @a2.files = %w[a b c d b]
+ @a2.extra_rdoc_files = %w[x y z x]
+ @a2.normalize
+
+ assert_equal %w[a b c d x y z], @a2.files
+ assert_equal %w[x y z], @a2.extra_rdoc_files
+ end
+
+ def test_files_extra_rdoc_files
+ @a2.files = %w[a b c d]
+ @a2.extra_rdoc_files = %w[x y z]
+ @a2.normalize
+ assert_equal %w[a b c d x y z], @a2.files
+ end
+
+ def test_files_non_array
+ @a1.files = "F"
+ @a1.test_files = "TF"
+ @a1.executables = "X"
+ @a1.extra_rdoc_files = "ERF"
+ @a1.extensions = "E"
+
+ assert_equal %w[E ERF F TF bin/X], @a1.files.sort
+ end
+
+ def test_files_non_array_pathological
+ @a1.instance_variable_set :@files, "F"
+ @a1.instance_variable_set :@test_files, "TF"
+ @a1.instance_variable_set :@extra_rdoc_files, "ERF"
+ @a1.instance_variable_set :@extensions, "E"
+ @a1.instance_variable_set :@executables, "X"
+
+ assert_equal %w[E ERF F TF bin/X], @a1.files.sort
+ assert_kind_of Integer, @a1.hash
+ end
+
+ def test_full_gem_path
+ assert_equal File.join(@gemhome, 'gems', @a1.full_name),
+ @a1.full_gem_path
+
+ @a1.original_platform = 'mswin32'
+
+ assert_equal File.join(@gemhome, 'gems', @a1.original_name),
+ @a1.full_gem_path
+ end
+
+ def test_full_gem_path_double_slash
+ gemhome = @gemhome.sub(/\w\//, '\&/')
+ @a1.loaded_from = File.join gemhome, 'specifications', @a1.spec_name
+
+ assert_equal File.join(@gemhome, 'gems', @a1.full_name),
+ @a1.full_gem_path
+ end
+
+ def test_full_name
+ assert_equal 'a-1', @a1.full_name
+
+ @a1.platform = Gem::Platform.new ['universal', 'darwin', nil]
+ assert_equal 'a-1-universal-darwin', @a1.full_name
+
+ @a1.instance_variable_set :@new_platform, 'mswin32'
+ assert_equal 'a-1-mswin32', @a1.full_name, 'legacy'
+
+ return if win_platform?
+
+ @a1.platform = 'current'
+ assert_equal 'a-1-x86-darwin-8', @a1.full_name
+ end
+
+ def test_full_name_windows
+ test_cases = {
+ 'i386-mswin32' => 'a-1-x86-mswin32-60',
+ 'i386-mswin32_80' => 'a-1-x86-mswin32-80',
+ 'i386-mingw32' => 'a-1-x86-mingw32'
+ }
+
+ test_cases.each do |arch, expected|
+ util_set_arch arch
+ @a1.platform = 'current'
+ assert_equal expected, @a1.full_name
+ end
+ end
+
+ def test_has_rdoc_eh
+ assert @a1.has_rdoc?
+ end
+
+ def test_has_rdoc_equals
+
+ use_ui @ui do
+ @a1.has_rdoc = false
+ end
+
+ assert_equal '', @ui.output
+
+ assert_equal true, @a1.has_rdoc
+ end
+
+ def test_hash
+ assert_equal @a1.hash, @a1.hash
+ assert_equal @a1.hash, @a1.dup.hash
+ refute_equal @a1.hash, @a2.hash
+ end
+
+ def test_installation_path
+ assert_equal @gemhome, @a1.installation_path
+
+ @a1.instance_variable_set :@loaded_from, nil
+
+ e = assert_raises Gem::Exception do
+ @a1.installation_path
+ end
+
+ assert_equal 'spec a-1 is not from an installed gem', e.message
+ end
+
+ def test_lib_files
+ @a1.files = %w[lib/foo.rb Rakefile]
+
+ assert_equal %w[lib/foo.rb], @a1.lib_files
+ end
+
+ def test_license
+ assert_equal 'MIT', @a1.license
+ end
+
+ def test_licenses
+ assert_equal ['MIT'], @a1.licenses
+ end
+
+ def test_name
+ assert_equal 'a', @a1.name
+ end
+
+ def test_original_name
+ assert_equal 'a-1', @a1.full_name
+
+ @a1.platform = 'i386-linux'
+ @a1.instance_variable_set :@original_platform, 'i386-linux'
+ assert_equal 'a-1-i386-linux', @a1.original_name
+ end
+
+ def test_platform
+ assert_equal Gem::Platform::RUBY, @a1.platform
+ end
+
+ def test_platform_equals
+ @a1.platform = nil
+ assert_equal Gem::Platform::RUBY, @a1.platform
+
+ @a1.platform = Gem::Platform::RUBY
+ assert_equal Gem::Platform::RUBY, @a1.platform
+
+ test_cases = {
+ 'i386-mswin32' => ['x86', 'mswin32', '60'],
+ 'i386-mswin32_80' => ['x86', 'mswin32', '80'],
+ 'i386-mingw32' => ['x86', 'mingw32', nil ],
+ 'x86-darwin8' => ['x86', 'darwin', '8' ],
+ }
+
+ test_cases.each do |arch, expected|
+ util_set_arch arch
+ @a1.platform = Gem::Platform::CURRENT
+ assert_equal Gem::Platform.new(expected), @a1.platform
+ end
+ end
+
+ def test_platform_equals_current
+ @a1.platform = Gem::Platform::CURRENT
+ assert_equal Gem::Platform.local, @a1.platform
+ assert_equal Gem::Platform.local.to_s, @a1.original_platform
+ end
+
+ def test_platform_equals_legacy
+ @a1.platform = 'mswin32'
+ assert_equal Gem::Platform.new('x86-mswin32'), @a1.platform
+
+ @a1.platform = 'i586-linux'
+ assert_equal Gem::Platform.new('x86-linux'), @a1.platform
+
+ @a1.platform = 'powerpc-darwin'
+ assert_equal Gem::Platform.new('ppc-darwin'), @a1.platform
+ end
+
+ def test_prerelease_spec_adds_required_rubygems_version
+ @prerelease = quick_gem('tardis', '2.2.0.a')
+ refute @prerelease.required_rubygems_version.satisfied_by?(Gem::Version.new('1.3.1'))
+ assert @prerelease.required_rubygems_version.satisfied_by?(Gem::Version.new('1.4.0'))
+ end
+
+ def test_require_paths
+ @a1.require_path = 'lib'
+ assert_equal %w[lib], @a1.require_paths
+ end
+
+ def test_requirements
+ assert_equal ['A working computer'], @a1.requirements
+ end
+
+ def test_runtime_dependencies_legacy
+ # legacy gems don't have a type
+ @a1.runtime_dependencies.each do |dep|
+ dep.instance_variable_set :@type, nil
+ end
+
+ expected = %w[rake jabber4r pqa]
+
+ assert_equal expected, @a1.runtime_dependencies.map { |d| d.name }
+ end
+
+ def test_spaceship_name
+ s1 = quick_gem 'a', '1'
+ s2 = quick_gem 'b', '1'
+
+ assert_equal(-1, (s1 <=> s2))
+ assert_equal( 0, (s1 <=> s1))
+ assert_equal( 1, (s2 <=> s1))
+ end
+
+ def test_spaceship_platform
+ s1 = quick_gem 'a', '1'
+ s2 = quick_gem 'a', '1' do |s|
+ s.platform = Gem::Platform.new 'x86-my_platform1'
+ end
+
+ assert_equal( -1, (s1 <=> s2))
+ assert_equal( 0, (s1 <=> s1))
+ assert_equal( 1, (s2 <=> s1))
+ end
+
+ def test_spaceship_version
+ s1 = quick_gem 'a', '1'
+ s2 = quick_gem 'a', '2'
+
+ assert_equal( -1, (s1 <=> s2))
+ assert_equal( 0, (s1 <=> s1))
+ assert_equal( 1, (s2 <=> s1))
+ end
+
+ def test_spec_name
+ assert_equal 'a-1.gemspec', @a1.spec_name
+ end
+
+ def test_summary
+ assert_equal 'this is a summary', @a1.summary
+ end
+
+ def test_test_files
+ @a1.test_file = 'test/suite.rb'
+ assert_equal ['test/suite.rb'], @a1.test_files
+ end
+
+ def test_to_ruby
+ @a2.add_runtime_dependency 'b', '1'
+ @a2.dependencies.first.instance_variable_set :@type, nil
+ @a2.required_rubygems_version = Gem::Requirement.new '> 0'
+
+ ruby_code = @a2.to_ruby
+
+ expected = <<-SPEC
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+ s.name = %q{a}
+ s.version = \"2\"
+
+ s.required_rubygems_version = Gem::Requirement.new(\"> 0\") if s.respond_to? :required_rubygems_version=
+ s.authors = [\"A User\"]
+ s.date = %q{#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}}
+ s.description = %q{This is a test description}
+ s.email = %q{example at example.com}
+ s.files = [\"lib/code.rb\"]
+ s.homepage = %q{http://example.com}
+ s.require_paths = [\"lib\"]
+ s.rubygems_version = %q{#{Gem::VERSION}}
+ s.summary = %q{this is a summary}
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION}
+
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+ s.add_runtime_dependency(%q<b>, [\"= 1\"])
+ else
+ s.add_dependency(%q<b>, [\"= 1\"])
+ end
+ else
+ s.add_dependency(%q<b>, [\"= 1\"])
+ end
+end
+ SPEC
+
+ assert_equal expected, ruby_code
+
+ same_spec = eval ruby_code
+
+ assert_equal @a2, same_spec
+ end
+
+ def test_to_ruby_fancy
+ @a1.platform = Gem::Platform.local
+ ruby_code = @a1.to_ruby
+
+ local = Gem::Platform.local
+ expected_platform = "[#{local.cpu.inspect}, #{local.os.inspect}, #{local.version.inspect}]"
+
+ expected = <<-SPEC
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+ s.name = %q{a}
+ s.version = \"1\"
+ s.platform = Gem::Platform.new(#{expected_platform})
+
+ s.required_rubygems_version = Gem::Requirement.new(\">= 0\") if s.respond_to? :required_rubygems_version=
+ s.authors = [\"A User\"]
+ s.date = %q{#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}}
+ s.default_executable = %q{exec}
+ s.description = %q{This is a test description}
+ s.email = %q{example at example.com}
+ s.executables = [\"exec\"]
+ s.extensions = [\"ext/a/extconf.rb\"]
+ s.files = [\"lib/code.rb\", \"test/suite.rb\", \"bin/exec\", \"ext/a/extconf.rb\"]
+ s.homepage = %q{http://example.com}
+ s.licenses = [\"MIT\"]
+ s.require_paths = [\"lib\"]
+ s.requirements = [\"A working computer\"]
+ s.rubyforge_project = %q{example}
+ s.rubygems_version = %q{#{Gem::VERSION}}
+ s.summary = %q{this is a summary}
+ s.test_files = [\"test/suite.rb\"]
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 3
+
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+ s.add_runtime_dependency(%q<rake>, [\"> 0.4\"])
+ s.add_runtime_dependency(%q<jabber4r>, [\"> 0.0.0\"])
+ s.add_runtime_dependency(%q<pqa>, [\"> 0.4\", \"<= 0.6\"])
+ else
+ s.add_dependency(%q<rake>, [\"> 0.4\"])
+ s.add_dependency(%q<jabber4r>, [\"> 0.0.0\"])
+ s.add_dependency(%q<pqa>, [\"> 0.4\", \"<= 0.6\"])
+ end
+ else
+ s.add_dependency(%q<rake>, [\"> 0.4\"])
+ s.add_dependency(%q<jabber4r>, [\"> 0.0.0\"])
+ s.add_dependency(%q<pqa>, [\"> 0.4\", \"<= 0.6\"])
+ end
+end
+ SPEC
+
+ assert_equal expected, ruby_code
+
+ same_spec = eval ruby_code
+
+ assert_equal @a1, same_spec
+ end
+
+ def test_to_ruby_legacy
+ gemspec1 = eval LEGACY_RUBY_SPEC
+ ruby_code = gemspec1.to_ruby
+ gemspec2 = eval ruby_code
+
+ assert_equal gemspec1, gemspec2
+ end
+
+ def test_to_ruby_platform
+ @a2.platform = Gem::Platform.local
+ @a2.instance_variable_set :@original_platform, 'old_platform'
+
+ ruby_code = @a2.to_ruby
+
+ same_spec = eval ruby_code
+
+ assert_equal 'old_platform', same_spec.original_platform
+ end
+
+ def test_to_yaml
+ yaml_str = @a1.to_yaml
+ same_spec = YAML.load(yaml_str)
+
+ assert_equal @a1, same_spec
+ end
+
+ def test_to_yaml_fancy
+ @a1.platform = Gem::Platform.local
+ yaml_str = @a1.to_yaml
+
+ same_spec = YAML.load(yaml_str)
+
+ assert_equal Gem::Platform.local, same_spec.platform
+
+ assert_equal @a1, same_spec
+ end
+
+ def test_to_yaml_platform_empty_string
+ @a1.instance_variable_set :@original_platform, ''
+
+ assert_match %r|^platform: ruby$|, @a1.to_yaml
+ end
+
+ def test_to_yaml_platform_legacy
+ @a1.platform = 'powerpc-darwin7.9.0'
+ @a1.instance_variable_set :@original_platform, 'powerpc-darwin7.9.0'
+
+ yaml_str = @a1.to_yaml
+
+ same_spec = YAML.load yaml_str
+
+ assert_equal Gem::Platform.new('powerpc-darwin7'), same_spec.platform
+ assert_equal 'powerpc-darwin7.9.0', same_spec.original_platform
+ end
+
+ def test_to_yaml_platform_nil
+ @a1.instance_variable_set :@original_platform, nil
+
+ assert_match %r|^platform: ruby$|, @a1.to_yaml
+ end
+
+ def test_validate
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ assert @a1.validate
+ end
+ end
+
+ def test_validate_authors
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.authors = []
+
+ use_ui @ui do
+ @a1.validate
+ end
+
+ assert_equal "WARNING: no author specified\n", @ui.error, 'error'
+
+ @a1.authors = [Object.new]
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal 'authors must be Array of Strings', e.message
+
+ @a1.authors = ['FIXME (who is writing this software)']
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal '"FIXME" or "TODO" is not an author', e.message
+
+ @a1.authors = ['TODO (who is writing this software)']
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal '"FIXME" or "TODO" is not an author', e.message
+ end
+ end
+
+ def test_validate_autorequire
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.autorequire = 'code'
+
+ use_ui @ui do
+ @a1.validate
+ end
+
+ assert_equal "WARNING: deprecated autorequire specified\n",
+ @ui.error, 'error'
+ end
+ end
+
+ def test_validate_description
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.description = ''
+
+ use_ui @ui do
+ @a1.validate
+ end
+
+ assert_equal "WARNING: no description specified\n", @ui.error, 'error'
+
+ @ui = MockGemUi.new
+ @a1.summary = 'this is my summary'
+ @a1.description = @a1.summary
+
+ use_ui @ui do
+ @a1.validate
+ end
+
+ assert_equal "WARNING: description and summary are identical\n",
+ @ui.error, 'error'
+
+ @a1.description = 'FIXME (describe your package)'
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal '"FIXME" or "TODO" is not a description', e.message
+
+ @a1.description = 'TODO (describe your package)'
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal '"FIXME" or "TODO" is not a description', e.message
+ end
+ end
+
+ def test_validate_email
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.email = ''
+
+ use_ui @ui do
+ @a1.validate
+ end
+
+ assert_equal "WARNING: no email specified\n", @ui.error, 'error'
+
+ @a1.email = 'FIXME (your e-mail)'
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal '"FIXME" or "TODO" is not an email address', e.message
+
+ @a1.email = 'TODO (your e-mail)'
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal '"FIXME" or "TODO" is not an email address', e.message
+ end
+ end
+
+ def test_validate_empty
+ util_setup_validate
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ Gem::Specification.new.validate
+ end
+
+ assert_equal 'missing value for attribute name', e.message
+ end
+
+ def test_validate_executables
+ util_setup_validate
+
+ FileUtils.mkdir_p File.join(@tempdir, 'bin')
+ File.open File.join(@tempdir, 'bin', 'exec'), 'w' do end
+ FileUtils.mkdir_p File.join(@tempdir, 'exec')
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ assert @a1.validate
+ end
+ end
+
+ assert_equal %w[exec], @a1.executables
+
+ assert_equal '', @ui.output, 'output'
+ assert_equal "WARNING: bin/exec is missing #! line\n", @ui.error, 'error'
+ end
+
+ def test_validate_empty_require_paths
+ if win_platform? then
+ skip 'test_validate_empty_require_paths skipped on MS Windows (symlink)'
+ else
+ util_setup_validate
+
+ @a1.require_paths = []
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal 'specification must have at least one require_path',
+ e.message
+ end
+ end
+
+ def test_validate_files
+ skip 'test_validate_files skipped on MS Windows (symlink)' if win_platform?
+ util_setup_validate
+
+ @a1.files += ['lib', 'lib2']
+
+ Dir.chdir @tempdir do
+ FileUtils.ln_s '/root/path', 'lib2' unless vc_windows?
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal '["lib2"] are not files', e.message
+ end
+
+ assert_equal %w[lib/code.rb test/suite.rb bin/exec ext/a/extconf.rb lib2],
+ @a1.files
+ end
+
+ def test_validate_homepage
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.homepage = nil
+
+ use_ui @ui do
+ @a1.validate
+ end
+
+ assert_equal "WARNING: no homepage specified\n", @ui.error, 'error'
+
+ @ui = MockGemUi.new
+
+ @a1.homepage = ''
+
+ use_ui @ui do
+ @a1.validate
+ end
+
+ assert_equal "WARNING: no homepage specified\n", @ui.error, 'error'
+
+ @a1.homepage = 'over at my cool site'
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal '"over at my cool site" is not a URI', e.message
+ end
+ end
+
+ def test_validate_name
+ util_setup_validate
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.name = :json
+ @a1.validate
+ end
+
+ assert_equal 'invalid value for attribute name: ":json"', e.message
+ end
+
+ def test_validate_platform_legacy
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.platform = 'mswin32'
+ assert @a1.validate
+
+ @a1.platform = 'i586-linux'
+ assert @a1.validate
+
+ @a1.platform = 'powerpc-darwin'
+ assert @a1.validate
+ end
+ end
+
+ def test_validate_rubyforge_project
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.rubyforge_project = ''
+
+ use_ui @ui do
+ @a1.validate
+ end
+
+ assert_equal "WARNING: no rubyforge_project specified\n",
+ @ui.error, 'error'
+ end
+ end
+
+ def test_validate_rubygems_version
+ util_setup_validate
+
+ @a1.rubygems_version = "3"
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal "expected RubyGems version #{Gem::VERSION}, was 3",
+ e.message
+ end
+
+ def test_validate_specification_version
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.specification_version = '1.0'
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ use_ui @ui do
+ @a1.validate
+ end
+ end
+
+ err = 'specification_version must be a Fixnum (did you mean version?)'
+ assert_equal err, e.message
+ end
+ end
+
+ def test_validate_summary
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.summary = ''
+
+ use_ui @ui do
+ @a1.validate
+ end
+
+ assert_equal "WARNING: no summary specified\n", @ui.error, 'error'
+
+ @a1.summary = 'FIXME (describe your package)'
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal '"FIXME" or "TODO" is not a summary', e.message
+
+ @a1.summary = 'TODO (describe your package)'
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ @a1.validate
+ end
+
+ assert_equal '"FIXME" or "TODO" is not a summary', e.message
+ end
+ end
+
+ def test_version
+ assert_equal Gem::Version.new('1'), @a1.version
+ end
+
+ def test_load_errors_contain_filename
+ specfile = Tempfile.new(self.class.name.downcase)
+ specfile.write "raise 'boom'"
+ specfile.close
+ begin
+ Gem::Specification.load(specfile.path)
+ rescue => e
+ name_rexp = Regexp.new(Regexp.escape(specfile.path))
+ assert e.backtrace.grep(name_rexp).any?
+ end
+ ensure
+ specfile.delete
+ end
+
+ def util_setup_validate
+ Dir.chdir @tempdir do
+ FileUtils.mkdir_p File.join('ext', 'a')
+ FileUtils.mkdir_p 'lib'
+ FileUtils.mkdir_p 'test'
+
+ FileUtils.touch File.join('ext', 'a', 'extconf.rb')
+ FileUtils.touch File.join('lib', 'code.rb')
+ FileUtils.touch File.join('test', 'suite.rb')
+ end
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_stream_ui.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_stream_ui.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_stream_ui.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,140 @@
+require_relative 'gemutilities'
+require 'rubygems/user_interaction'
+
+class TestGemStreamUI < RubyGemTestCase
+
+ module IsTty
+ attr_accessor :tty
+
+ def tty?
+ @tty = true unless defined? @tty
+ return @tty
+ end
+
+ alias_method :isatty, :tty?
+ end
+
+ def setup
+ super
+
+ @cfg = Gem.configuration
+
+ @in = StringIO.new
+ @out = StringIO.new
+ @err = StringIO.new
+
+ @in.extend IsTty
+
+ @sui = Gem::StreamUI.new @in, @out, @err
+ end
+
+ def test_ask
+ timeout(1) do
+ expected_answer = "Arthur, King of the Britons"
+ @in.string = "#{expected_answer}\n"
+ actual_answer = @sui.ask("What is your name?")
+ assert_equal expected_answer, actual_answer
+ end
+ end
+
+ def test_ask_no_tty
+ @in.tty = false
+
+ timeout(0.1) do
+ answer = @sui.ask("what is your favorite color?")
+ assert_equal nil, answer
+ end
+ end
+
+ def test_ask_for_password
+ skip 'Always uses $stdin on windows' if Gem.win_platform?
+
+ timeout(1) do
+ expected_answer = "Arthur, King of the Britons"
+ @in.string = "#{expected_answer}\n"
+ actual_answer = @sui.ask_for_password("What is your name?")
+ assert_equal expected_answer, actual_answer
+ end
+ end
+
+ def test_ask_for_password_no_tty
+ @in.tty = false
+
+ timeout(0.1) do
+ answer = @sui.ask_for_password("what is the airspeed velocity of an unladen swallow?")
+ assert_equal nil, answer
+ end
+ end
+
+ def test_ask_yes_no_no_tty_with_default
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ @in.tty = false
+
+ timeout(0.1) do
+ answer = @sui.ask_yes_no("do coconuts migrate?", false)
+ assert_equal false, answer
+
+ answer = @sui.ask_yes_no("do coconuts migrate?", true)
+ assert_equal true, answer
+ end
+ end
+
+ def test_ask_yes_no_no_tty_without_default
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ @in.tty = false
+
+ timeout(0.1) do
+ assert_raises(Gem::OperationNotSupportedError) do
+ @sui.ask_yes_no("do coconuts migrate?")
+ end
+ end
+ end
+
+ def test_choose_from_list
+ @in.puts "1"
+ @in.rewind
+
+ result = @sui.choose_from_list 'which one?', %w[foo bar]
+
+ assert_equal ['foo', 0], result
+ assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string
+ end
+
+ def test_choose_from_list_EOF
+ result = @sui.choose_from_list 'which one?', %w[foo bar]
+
+ assert_equal [nil, nil], result
+ assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string
+ end
+
+ def test_proress_reporter_silent_nil
+ @cfg.verbose = nil
+ reporter = @sui.progress_reporter 10, 'hi'
+ assert_kind_of Gem::StreamUI::SilentProgressReporter, reporter
+ end
+
+ def test_proress_reporter_silent_false
+ @cfg.verbose = false
+ reporter = @sui.progress_reporter 10, 'hi'
+ assert_kind_of Gem::StreamUI::SilentProgressReporter, reporter
+ assert_equal "", @out.string
+ end
+
+ def test_proress_reporter_simple
+ @cfg.verbose = true
+ reporter = @sui.progress_reporter 10, 'hi'
+ assert_kind_of Gem::StreamUI::SimpleProgressReporter, reporter
+ assert_equal "hi\n", @out.string
+ end
+
+ def test_proress_reporter_verbose
+ @cfg.verbose = 0
+ reporter = @sui.progress_reporter 10, 'hi'
+ assert_kind_of Gem::StreamUI::VerboseProgressReporter, reporter
+ assert_equal "hi\n", @out.string
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_uninstaller.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_uninstaller.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_uninstaller.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,146 @@
+require_relative 'gem_installer_test_case'
+require 'rubygems/uninstaller'
+
+class TestGemUninstaller < GemInstallerTestCase
+
+ def setup
+ super
+
+ ui = MockGemUi.new
+ util_setup_gem ui
+
+ @user_spec.executables = ["my_exec"]
+
+ # HACK util_make_exec
+ user_bin_dir = File.join Gem.user_dir, 'gems', @user_spec.full_name, 'bin'
+ FileUtils.mkdir_p user_bin_dir
+ exec_path = File.join user_bin_dir, "my_exec"
+ File.open exec_path, 'w' do |f|
+ f.puts "#!/usr/bin/ruby"
+ end
+
+ user_bin_dir = File.join Gem.user_dir, 'bin'
+ FileUtils.mkdir_p user_bin_dir
+ exec_path = File.join user_bin_dir, "my_exec"
+ File.open exec_path, 'w' do |f|
+ f.puts "#!/usr/bin/ruby"
+ end
+
+ build_rake_in do
+ use_ui ui do
+ @installer.install
+ @user_installer.install
+ Gem::Uninstaller.new(@user_spec.name, :executables => false).uninstall
+ end
+ end
+ end
+
+ def test_initialize_expand_path
+ uninstaller = Gem::Uninstaller.new nil, :install_dir => '/foo//bar'
+
+ assert_match %r|/foo/bar$|, uninstaller.instance_variable_get(:@gem_home)
+ end
+
+ def test_remove_executables_force_keep
+ uninstaller = Gem::Uninstaller.new nil, :executables => false
+
+ use_ui @ui do
+ uninstaller.remove_executables @spec
+ end
+
+ assert_equal true, File.exist?(File.join(@gemhome, 'bin', 'executable'))
+
+ assert_equal "Executables and scripts will remain installed.\n", @ui.output
+ end
+
+ def test_remove_executables_force_remove
+ uninstaller = Gem::Uninstaller.new nil, :executables => true
+
+ use_ui @ui do
+ uninstaller.remove_executables @spec
+ end
+
+ assert_equal "Removing executable\n", @ui.output
+
+ assert_equal false, File.exist?(File.join(@gemhome, 'bin', 'executable'))
+ end
+
+ def test_remove_executables_user
+ uninstaller = Gem::Uninstaller.new nil, :executables => true
+
+ use_ui @ui do
+ uninstaller.remove_executables @user_spec
+ end
+
+ exec_path = File.join Gem.user_dir, 'bin', 'my_exec'
+ assert_equal false, File.exist?(exec_path), 'removed exec from bin dir'
+
+ assert_equal "Removing my_exec\n", @ui.output
+ end
+
+ def test_path_ok_eh
+ uninstaller = Gem::Uninstaller.new nil
+
+ assert_equal true, uninstaller.path_ok?(@gemhome, @spec)
+ end
+
+ def test_path_ok_eh_legacy
+ uninstaller = Gem::Uninstaller.new nil
+
+ @spec.loaded_from.gsub! @spec.full_name, '\&-legacy'
+ @spec.platform = 'legacy'
+
+ assert_equal true, uninstaller.path_ok?(@gemhome, @spec)
+ end
+
+ def test_path_ok_eh_user
+ uninstaller = Gem::Uninstaller.new nil
+
+ assert_equal true, uninstaller.path_ok?(Gem.user_dir, @user_spec)
+ end
+
+ def test_uninstall
+ uninstaller = Gem::Uninstaller.new @spec.name, :executables => true
+
+ gem_dir = File.join @gemhome, 'gems', @spec.full_name
+
+ Gem.pre_uninstall do
+ assert File.exist?(gem_dir), 'gem_dir should exist'
+ end
+
+ Gem.post_uninstall do
+ refute File.exist?(gem_dir), 'gem_dir should not exist'
+ end
+
+ uninstaller.uninstall
+
+ refute File.exist?(gem_dir)
+
+ assert_same uninstaller, @pre_uninstall_hook_arg
+ assert_same uninstaller, @post_uninstall_hook_arg
+ end
+
+ def test_uninstall_user
+ uninstaller = Gem::Uninstaller.new @user_spec.name, :executables => true,
+ :user_install => true
+
+ gem_dir = File.join Gem.user_dir, 'gems', @user_spec.full_name
+
+ Gem.pre_uninstall do
+ assert File.exist?(gem_dir), 'gem_dir should exist'
+ end
+
+ Gem.post_uninstall do
+ refute File.exist?(gem_dir), 'gem_dir should not exist'
+ end
+
+ uninstaller.uninstall
+
+ refute File.exist?(gem_dir)
+
+ assert_same uninstaller, @pre_uninstall_hook_arg
+ assert_same uninstaller, @post_uninstall_hook_arg
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_validator.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_validator.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_validator.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,63 @@
+require_relative 'gemutilities'
+require_relative 'simple_gem'
+require 'rubygems/validator'
+
+class TestGemValidator < RubyGemTestCase
+
+ def setup
+ super
+
+ @simple_gem = SIMPLE_GEM
+ @validator = Gem::Validator.new
+ end
+
+ def test_verify_gem_file
+ gem_file = File.join @tempdir, 'simple_gem.gem'
+ File.open gem_file, 'wb' do |fp| fp.write @simple_gem end
+
+ assert_equal nil, @validator.verify_gem_file(gem_file)
+ end
+
+ def test_verify_gem_file_empty
+ e = assert_raises Gem::VerificationError do
+ @validator.verify_gem_file ''
+ end
+
+ assert_equal 'missing gem file ', e.message
+ end
+
+ def test_verify_gem_file_nonexistent
+ file = '/nonexistent/nonexistent.gem'
+ e = assert_raises Gem::VerificationError do
+ @validator.verify_gem_file file
+ end
+
+ assert_equal "missing gem file #{file}", e.message
+ end
+
+ def test_verify_gem
+ assert_equal nil, @validator.verify_gem(@simple_gem)
+ end
+
+ def test_verify_gem_empty
+ e = assert_raises Gem::VerificationError do
+ @validator.verify_gem ''
+ end
+
+ assert_equal 'empty gem file', e.message
+ end
+
+ def test_verify_gem_invalid_checksum
+ e = assert_raises Gem::VerificationError do
+ @validator.verify_gem @simple_gem.upcase
+ end
+
+ assert_equal 'invalid checksum for gem file', e.message
+ end
+
+ def test_verify_gem_no_sum
+ assert_equal nil, @validator.verify_gem('words')
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_version.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_version.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_version.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,172 @@
+require_relative 'gemutilities'
+require 'rubygems/version'
+
+class TestGemVersion < RubyGemTestCase
+
+ def test_bump
+ assert_bumped_version_equal "5.3", "5.2.4"
+ end
+
+ def test_bump_alpha
+ assert_bumped_version_equal "5.3", "5.2.4.a"
+ end
+
+ def test_bump_trailing_zeros
+ assert_bumped_version_equal "5.1", "5.0.0"
+ end
+
+ def test_bump_one_level
+ assert_bumped_version_equal "6", "5"
+ end
+
+ # FIX: For "legacy reasons," any object that responds to +version+
+ # is returned unchanged. I'm not certain why.
+
+ def test_class_create
+ fake = Object.new
+ def fake.version; "1.0" end
+
+ assert_same fake, Gem::Version.create(fake)
+ assert_nil Gem::Version.create(nil)
+ assert_equal v("5.1"), Gem::Version.create("5.1")
+ end
+
+ def test_eql_eh
+ assert_version_eql "1.2", "1.2"
+ refute_version_eql "1.2", "1.2.0"
+ refute_version_eql "1.2", "1.3"
+ end
+
+ def test_equals
+ assert_version_equal "1.2", "1.2"
+ refute_version_equal "1.2", "1.3"
+ end
+
+ # REVISIT: consider removing as too impl-bound
+ def test_hash
+ assert_equal v("1.2").hash, v("1.2").hash
+ refute_equal v("1.2").hash, v("1.3").hash
+ refute_equal v("1.2").hash, v("1.2.0").hash
+ end
+
+ def test_initialize
+ ["1.0", "1.0 ", " 1.0 ", "1.0\n", "\n1.0\n"].each do |good|
+ assert_version_equal "1.0", good
+ end
+
+ assert_version_equal "1", 1
+ end
+
+ def test_initialize_bad
+ ["junk", "1.0\n2.0"].each do |bad|
+ e = assert_raises ArgumentError do
+ Gem::Version.new bad
+ end
+
+ assert_equal "Malformed version number string #{bad}", e.message
+ end
+ end
+
+ def test_prerelease
+ assert_prerelease "1.2.0.a"
+ assert_prerelease "2.9.b"
+ assert_prerelease "22.1.50.0.d"
+ assert_prerelease "1.2.d.42"
+
+ assert_prerelease '1.A'
+
+ refute_prerelease "1.2.0"
+ refute_prerelease "2.9"
+ refute_prerelease "22.1.50.0"
+ end
+
+ def test_release
+ assert_release_equal "1.2.0", "1.2.0.a"
+ assert_release_equal "1.1", "1.1.rc10"
+ assert_release_equal "1.9.3", "1.9.3.alpha.5"
+ assert_release_equal "1.9.3", "1.9.3"
+ end
+
+ def test_spaceship
+ assert_equal( 0, v("1.0") <=> v("1.0.0"))
+ assert_equal( 1, v("1.0") <=> v("1.0.a"))
+ assert_equal( 1, v("1.8.2") <=> v("0.0.0"))
+ assert_equal( 1, v("1.8.2") <=> v("1.8.2.a"))
+ assert_equal( 1, v("1.8.2.b") <=> v("1.8.2.a"))
+ assert_equal(-1, v("1.8.2.a") <=> v("1.8.2"))
+ assert_equal( 0, v("") <=> v("0"))
+ end
+
+ def test_spermy_recommendation
+ assert_spermy_equal "~> 1.0", "1"
+ assert_spermy_equal "~> 1.0", "1.0"
+ assert_spermy_equal "~> 1.2", "1.2"
+ assert_spermy_equal "~> 1.2", "1.2.0"
+ assert_spermy_equal "~> 1.2", "1.2.3"
+ assert_spermy_equal "~> 1.2", "1.2.3.a.4"
+ end
+
+ def test_to_s
+ assert_equal "5.2.4", v("5.2.4").to_s
+ end
+
+ # Asserts that +version+ is a prerelease.
+
+ def assert_prerelease version
+ assert v(version).prerelease?, "#{version} is a prerelease"
+ end
+
+ # Assert that +expected+ is the "spermy" recommendation for +version".
+
+ def assert_spermy_equal expected, version
+ assert_equal expected, v(version).spermy_recommendation
+ end
+
+ # Assert that bumping the +unbumped+ version yields the +expected+.
+
+ def assert_bumped_version_equal expected, unbumped
+ assert_version_equal expected, v(unbumped).bump
+ end
+
+ # Assert that +release+ is the correct non-prerelease +version+.
+
+ def assert_release_equal release, version
+ assert_version_equal release, v(version).release
+ end
+
+ # Assert that two versions are equal. Handles strings or
+ # Gem::Version instances.
+
+ def assert_version_equal expected, actual
+ assert_equal v(expected), v(actual)
+ end
+
+ # Assert that two versions are eql?. Checks both directions.
+
+ def assert_version_eql first, second
+ first, second = v(first), v(second)
+ assert first.eql?(second), "#{first} is eql? #{second}"
+ assert second.eql?(first), "#{second} is eql? #{first}"
+ end
+
+ # Refute the assumption that +version+ is a prerelease.
+
+ def refute_prerelease version
+ refute v(version).prerelease?, "#{version} is NOT a prerelease"
+ end
+
+ # Refute the assumption that two versions are eql?. Checks both
+ # directions.
+
+ def refute_version_eql first, second
+ first, second = v(first), v(second)
+ refute first.eql?(second), "#{first} is NOT eql? #{second}"
+ refute second.eql?(first), "#{second} is NOT eql? #{first}"
+ end
+
+ # Refute the assumption that the two versions are equal?.
+
+ def refute_version_equal unexpected, actual
+ refute_equal v(unexpected), v(actual)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_gem_version_option.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_gem_version_option.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_gem_version_option.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,89 @@
+require_relative 'gemutilities'
+require 'rubygems/command'
+require 'rubygems/version_option'
+
+class TestGemVersionOption < RubyGemTestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Command.new 'dummy', 'dummy'
+ @cmd.extend Gem::VersionOption
+ end
+
+ def test_add_platform_option
+ @cmd.add_platform_option
+
+ assert @cmd.handles?(%w[--platform x86-darwin])
+ end
+
+ def test_add_version_option
+ @cmd.add_version_option
+
+ assert @cmd.handles?(%w[--version >1])
+ end
+
+ def test_enables_prerelease
+ @cmd.add_version_option
+
+ @cmd.handle_options %w[mygem -v 0.2.0.a]
+ assert @cmd.options[:prerelease]
+
+ @cmd.handle_options %w[mygem -v 0.2.0]
+ refute @cmd.options[:prerelease]
+
+ @cmd.handle_options %w[mygem]
+ refute @cmd.options[:prerelease]
+ end
+
+ def test_platform_option
+ @cmd.add_platform_option
+
+ @cmd.handle_options %w[--platform x86-freebsd6 --platform x86-freebsd7]
+
+ expected = [
+ Gem::Platform::RUBY,
+ Gem::Platform.new('x86-freebsd6'),
+ Gem::Platform.new('x86-freebsd7'),
+ ]
+
+ assert_equal expected, Gem.platforms
+ end
+
+ def test_platform_option_ruby
+ @cmd.add_platform_option
+
+ @cmd.handle_options %w[--platform ruby]
+
+ expected = [
+ Gem::Platform::RUBY
+ ]
+
+ assert_equal expected, Gem.platforms
+ end
+
+ def test_platform_option_twice
+ @cmd.add_platform_option
+
+ @cmd.handle_options %w[--platform x86-freebsd6 --platform x86-freebsd-6]
+
+ expected = [
+ Gem::Platform::RUBY,
+ Gem::Platform.new('x86-freebsd6'),
+ ]
+
+ assert_equal expected, Gem.platforms
+ end
+
+ def test_version_option
+ @cmd.add_version_option
+
+ @cmd.handle_options %w[--version >1]
+
+ expected = { :version => Gem::Requirement.new('> 1'), :args => [] }
+
+ assert_equal expected, @cmd.options
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/rubygems/test_kernel.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/rubygems/test_kernel.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/rubygems/test_kernel.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,59 @@
+require_relative 'gemutilities'
+require 'rubygems/package'
+
+class TestKernel < RubyGemTestCase
+
+ def setup
+ super
+
+ @old_path = $:.dup
+
+ util_make_gems
+ end
+
+ def teardown
+ super
+
+ $:.replace @old_path
+ end
+
+ def test_gem
+ assert gem('a', '= 1'), "Should load"
+ assert $:.any? { |p| %r{a-1/lib} =~ p }
+ assert $:.any? { |p| %r{a-1/bin} =~ p }
+ end
+
+ def test_gem_redundent
+ assert gem('a', '= 1'), "Should load"
+ refute gem('a', '= 1'), "Should not load"
+ assert_equal 1, $:.select { |p| %r{a-1/lib} =~ p }.size
+ assert_equal 1, $:.select { |p| %r{a-1/bin} =~ p }.size
+ end
+
+ def test_gem_overlapping
+ assert gem('a', '= 1'), "Should load"
+ refute gem('a', '>= 1'), "Should not load"
+ assert_equal 1, $:.select { |p| %r{a-1/lib} =~ p }.size
+ assert_equal 1, $:.select { |p| %r{a-1/bin} =~ p }.size
+ end
+
+ def test_gem_conflicting
+ assert gem('a', '= 1'), "Should load"
+
+ ex = assert_raises Gem::LoadError do
+ gem 'a', '= 2'
+ end
+
+ assert_match(/activate a \(= 2, runtime\)/, ex.message)
+ assert_match(/activated a-1/, ex.message)
+ assert_equal 'a', ex.name
+ assert_equal Gem::Requirement.new('= 2'), ex.version_requirement
+
+ assert $:.any? { |p| %r{a-1/lib} =~ p }
+ assert $:.any? { |p| %r{a-1/bin} =~ p }
+ refute $:.any? { |p| %r{a-2/lib} =~ p }
+ refute $:.any? { |p| %r{a-2/bin} =~ p }
+ end
+
+end
+
Added: MacRuby/trunk/test/test-mri/test/runner.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/runner.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/runner.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,25 @@
+require 'rbconfig'
+exit if CROSS_COMPILING
+
+require 'test/unit'
+
+src_testdir = File.dirname(File.expand_path(__FILE__))
+srcdir = File.dirname(src_testdir)
+
+Test::Unit.setup_argv {|files|
+ if files.empty?
+ [src_testdir]
+ else
+ files.map {|f|
+ if File.exist? "#{src_testdir}/#{f}"
+ "#{src_testdir}/#{f}"
+ elsif File.exist? "#{srcdir}/#{f}"
+ "#{srcdir}/#{f}"
+ elsif File.exist? f
+ f
+ else
+ raise ArgumentError, "not found: #{f}"
+ end
+ }
+ end
+}
Added: MacRuby/trunk/test/test-mri/test/scanf/data.txt
===================================================================
--- MacRuby/trunk/test/test-mri/test/scanf/data.txt (rev 0)
+++ MacRuby/trunk/test/test-mri/test/scanf/data.txt 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,6 @@
+this is 33 a fun
+little input file
+
+with
+
+characters
Added: MacRuby/trunk/test/test-mri/test/scanf/test_scanf.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/scanf/test_scanf.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/scanf/test_scanf.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,322 @@
+# $Id: test_scanf.rb 27139 2010-04-01 04:32:22Z naruse $
+#
+# scanf for Ruby
+#
+# Unit tests
+#
+
+require 'scanf.rb'
+require 'test/unit'
+require 'tmpdir'
+
+# Comment out either of these lines to skip those tests.
+
+class TestStringScanf < Test::Unit::TestCase;end
+class TestIOScanf < Test::Unit::TestCase;end
+
+module ScanfTests
+
+ def tests
+ [
+
+# Scratchpad
+ [ "%2[a]", "nbc", []],
+ [ "%*d %*3d %*s", "123 +456 abc", [] ],
+ [ "%d%c", "123 x", [ 123, " " ] ],
+ [ "%d%c", "123x", [ 123, "x" ] ],
+ [ "%d %c", "123x", [ 123, "x" ] ],
+ [ "%d %c", "123 x", [ 123, "x" ] ],
+
+# Testing failures
+ [ "%x", "x", [] ],
+ [ "%2x", "x", [] ],
+ [ "%i", "x", [] ],
+# ]; end; def nothing; [
+ [ "%2i", "x", [] ],
+ [ "%2o", "x", [] ],
+ [ "%d", "x", [] ],
+ [ "%2d", "x", [] ],
+ [ "%3d", "+x3", [] ],
+ [ "%d%[abc]", "eabc", [] ],
+ [ "%d\n%[abc]", "\neabc", [] ],
+ [ "%d%[^abc]", "ghiabc", [ ] ],
+ [ "%d%[abc]", "abc", [] ],
+ [ "%*d %*3d %*s", "123 +456 abc", [] ],
+ [ "%d%s", "", [] ],
+ [ "%d%s", "blah 123 string", [] ],
+ [ "%[\n]", "abc\n", [] ],
+ [ "%[\n]", "abc\n", [] ],
+ [ "%[\n]", "abc\n", [] ],
+ [ "%f", "x", [] ],
+ [ "%f", "z", [] ],
+ [ "%f", "z3.2534", [] ],
+ [ "", "", [] ],
+ [ "", "abc 123", [] ],
+ [ '%[^\\w]%c', "a...1", [] ],
+
+# Testing 'x'
+ [ "%3x", "0xz", [0] ],
+
+# Testing 'i'
+ [ "%3i", "097", [0] ],
+ [ "%3i", "0xz", [0] ],
+ [ "%1i", "3", [ 3 ] ],
+ [ "%2i", "07", [ 7 ] ],
+ [ "%2i", "0a", [ 0 ] ],
+
+# Testing 'c'
+ [ "%3c", "abc", [ "abc" ] ],
+ [ "%3c", "a\nb", [ "a\nb" ] ],
+ [ "%3c", "a\nbcd", [ "a\nb" ] ],
+ [ "%c\n\n", "x\n\n", [ "x" ] ],
+ [ "%c\n\n", "x\n\n", [ "x" ] ],
+ [ "%c", "\n", [ "\n" ] ],
+ [ "%c", "x\n", [ "x" ] ],
+ [ "%2c", " 123", [" 1"] ],
+ [ " %c", " x", ["x"] ],
+ [ "%c", " x", [" "] ],
+ [ "%c", "123", ["1"] ],
+ [ "%2c", "123", ["12"] ],
+ [ "%5c", "a\nb\n\n", [ "a\nb\n\n" ] ],
+ [ "%6c", "a\nb\n\nx", [ "a\nb\n\nx" ] ],
+ [ "%5c", "ab\ncd", [ "ab\ncd" ] ],
+ [ "%5c", "a\nb\n\n", [ "a\nb\n\n" ] ],
+
+# Testing 'o'
+ [ "%3o", "0xz", [0] ],
+
+# Testing 'd'
+ [ "%d", "\n123", [ 123 ] ],
+ [ "%d", "\n\n123", [ 123 ] ],
+ [ "%d", "\n123", [ 123 ] ],
+ [ "%1d", "2", [2] ],
+
+# Mixed tests
+# Includes:
+# whitespace/newline
+# mixed integer bases
+# various mixed specifiers
+
+ [ "%[^\\w]%c", "...1", [ "...", "1"] ],
+ [ '%[^\\w]%c', "...1", [ "...", "1"] ],
+ [ "%[abc\n]%d", "a\n\nb\n\nc 123", [ "a\n\nb\n\nc", 123 ] ],
+ [ "%[abc\n]%d", "a\n\nb\n\nc \t 123", [ "a\n\nb\n\nc", 123 ] ],
+ [ "%[abc\t]%d", "a\t\tb\t\tc 123", [ "a\t\tb\t\tc", 123 ] ],
+ [ "%d%3[abc\n]", "123a\nbeaab", [ 123, "a\nb" ] ],
+ [ "%d%20c", "42 is the key", [ 42, " is the key" ] ],
+ [ "%d %20c", "42 is the key", [ 42, "is the key" ] ],
+ [ "%d%3[^abc\n]%d", "123de\nf123", [ 123, "de" ] ],
+ [ "%d %4c", "3abc", [ 3, "abc" ] ],
+ [ "%f%d\n%[abc]", "1\neabc", [1.0] ],
+ [ "%d%3[abc]", "123aaab", [ 123, "aaa" ] ],
+ [ "%d%3[abc]", "123 aaab", [ 123 ] ],
+ [ "%d%3[abc]", "123aeaab", [ 123, "a" ] ],
+ [ "%d%[^abc]", "123defabc", [123, "def" ] ],
+ [ "%d%3[^abc]", "123defdef", [ 123, "def" ] ],
+ [ "%d%3[^abc] ", "123defdef ", [ 123, "def" ] ],
+ [ "%d%3[^abc]ghi", "123defghi", [ 123, "def" ] ],
+ [ "%d%3[^abc]", "123defdef", [ 123, "def" ] ],
+ [ "%d%3[^abc]", "123adefdef", [ 123 ] ],
+ [ "%d%3[^abc]", "123deafdef", [ 123, "de" ] ],
+ [ "%d%3[^abc\n]", "123de\nf", [ 123, "de" ] ],
+ [ "%s%c%c%s", "abc\n\ndef", ["abc", "\n","\n", "def" ] ],
+ [ "%c%d", "\n\n123", [ "\n",123 ] ],
+ [ "%s%c%d", "abc\n123", [ "abc", "\n", 123 ] ],
+ [ "%s%c%d", "abc\n\n123", [ "abc", "\n", 123 ] ],
+ [ "%c%d", "\t\n123", [ "\t",123 ] ],
+ [ "%s%c%d", "abc\t\n123", [ "abc", "\t", 123 ] ],
+ [ "%3c%d", "abc123", [ "abc", 123 ] ],
+ [ "%3c\n%d", "abc123", [ "abc", 123 ] ],
+ [ "%3c\n%d", "abc 123", [ "abc", 123 ] ],
+ [ "%3c %d", "abc123", [ "abc", 123 ] ],
+ [ "%3c\t%d", "abc \n 123", [ "abc", 123 ] ],
+ [ "%3c\t%d", "abc \n 123 ", [ "abc", 123 ] ],
+ [ "%3c%d", "a\nb123", [ "a\nb", 123 ] ],
+ [ "%f%3c", "1.2x\ny", [ 1.2, "x\ny"] ],
+ [ "%d\n%d\n%d", "123 456 789", [ 123,456,789 ] ],
+ [ "%d\n%i%2d%x\n%d", "123 0718932", [ 123, 071, 89, 0x32] ],
+ [ "%c\n%c", "x y", [ "x", "y" ] ],
+ [ "%c\t%c", "x y", [ "x", "y" ] ],
+ [ "%s\n%s", "x y", [ "x", "y" ] ],
+ [ "%s%s\n", "x y", [ "x", "y" ] ],
+ [ "%c\n\n%c", "x\n\ny", [ "x", "y" ] ],
+ [ "%s%d%d", "abc\n123\n456", [ "abc", 123, 456 ] ],
+ [ "%3s%c%3c%d", "1.2x\n\ny123", [ "1.2", "x", "\n\ny", 123 ] ],
+ [ "%f%3c", "1.2x\ny", [ 1.2, "x\ny"] ],
+ [ "%c\n%c", "x\n\ny", [ "x", "y" ] ],
+ [ "%c\n\n%c", "x\n\ny", [ "x", "y" ] ],
+ [ "%c %c", "x\n\ny", [ "x", "y" ] ],
+ [ "%s\n\n%c", "x\n\ny", [ "x", "y" ] ],
+ [ "%s\n\n%s", "x\n\ny", [ "x", "y" ] ],
+ [ "%d\n\n%d", "23\n\n45", [ 23, 45 ] ],
+ [ "%d\n%d", "23\n\n45", [ 23, 45 ] ],
+ [ "%c\n\n%c", "x y", [ "x", "y" ] ],
+ [ "%c%c", "x\n\ny", [ "x", "\n" ] ],
+ [ "%c\n%c", "x y", [ "x", "y" ] ],
+ [ "%c\t%c", "x y", [ "x", "y" ] ],
+ [ "%s\n%s", "x y", [ "x", "y" ] ],
+ [ "%s%s\n", "x y", [ "x", "y" ] ],
+ [ "%c%c", "x\n", [ "x", "\n" ] ],
+ [ "%d%c%c%d", "345 678", [ 345, " ", " ", 678] ],
+ [ "%d %c%s", "123 x hello", [123, "x", "hello"] ],
+ [ "%d%2c", "654 123", [654," 1"] ],
+ [ "%5c%s", "a\nb\n\nxyz", [ "a\nb\n\n","xyz" ] ],
+ [ "%s%[ xyz]%d", "hello x 32", ["hello", " x ", 32] ],
+ [ "%5s%8[a-z]%d", "helloblahblah 32", ["hello", "blahblah", 32] ],
+ [ '%s%[abcde\\s]%d', "hello badea 32", ["hello", " badea ", 32] ],
+ [ '%d%[\\s]%c', "123 \n\t X", [ 123," \n\t ", "X"] ],
+ [ "%4s%2c%c", "1.2x\n\ny", [ "1.2x", "\n\n","y"] ],
+ [ "%f%c %3c%d", "1.2x\n\ny123", [ 1.2, "x", "y12", 3 ] ],
+ [ "%s%5c", "abc ab\ncd", [ "abc", " ab\nc" ] ],
+ [ "%5c%f", "ab\ncd1.2", [ "ab\ncd",1.2 ] ],
+ [ "%5c%c", "ab\ncd1", [ "ab\ncd","1" ] ],
+ [ "%f%c%2c%d", "1.2x\ny123", [ 1.2, "x", "\ny", 123 ] ],
+ [ "%f%c%3c", "1.2x\ny123", [ 1.2, "x", "\ny1"] ],
+ [ "%s\n%s", "blah\n\nand\nmore stuff", [ "blah", "and" ] ],
+ [ "%o%d%x", "21912a3", [ "21".oct, 912, "a3".hex ] ],
+ [ "%3o%4d%3x", "21912a3", [ "21".oct, 912, "a3".hex ] ],
+ [ "%3o%4d%5x", "2191240xa3", [ "21".oct, 9124, "a3".hex ] ],
+ [ "%3d%3x", "12abc", [12, "abc".hex] ],
+ [ "%s%i%d", "hello +0xdef 123", [ "hello", "def".hex, 123] ],
+ [ "%s%i%d", "hello -0xdef 123", [ "hello", -"def".hex, 123] ],
+ [ "%s%i%i%i%i", "hello 012 -012 100 1", [ "hello", 10, -10, 100, 1 ] ],
+ [ "%s%i%i%i%i", "hello 012 0x12 100 1", [ "hello", 10, 18, 100, 1 ] ],
+ [ "%s%5i%3i%4i", "hello 0x123 123 0123", [ "hello", "0x123".hex, 123,"0123".oct] ],
+ [ "%s%3i%4i", "hello 1230123", [ "hello", 123,"0123".oct] ],
+ [ "%s%3i", "hello 1230", [ "hello", 123] ],
+ [ "%s%5x%d", "hello 0xdef 123", [ "hello", "def".hex, 123] ],
+ [ "%s%6x%d", "hello +0xdef 123", [ "hello", "def".hex, 123] ],
+ [ "%s%6x%d", "hello -0xdef 123", [ "hello", -"def".hex, 123] ],
+ [ "%s%6x%d", "hello -0xdef 123", [ "hello", -"def".hex, 123] ],
+ [ "%s%4x%d", "hello -def 123", [ "hello", -"def".hex, 123] ],
+ [ "%s%3x%d", "hello def 123", [ "hello", "def".hex, 123] ],
+ [ "%s%x%d", "hello -def 123", [ "hello", -"def".hex, 123] ],
+ [ "%s%x%d", "hello -0xdef 123", [ "hello", -"def".hex, 123] ],
+ [ "%s%x%d", "hello 0xdef 123", [ "hello", "def".hex, 123] ],
+ [ "%s%d%x%s", "hello 123 abc def", [ "hello", 123, "abc".hex, "def"] ],
+ [ "%s%d%o%d", "hello 012 012 100", [ "hello", 12, 10, 100 ] ],
+ [ "%s%d%o%d", "hello 012 -012 100", [ "hello", 12, -10, 100 ] ],
+ [ "%s%o%x%d", "hello 012 0x12 100", [ "hello", 10, 18, 100 ] ],
+ [ "%s%d%o%d", "hello 012 +01288", [ "hello", 12, 10, 88 ] ],
+ [ "%f %d %s", "12.3e23 45 string", ["12.3e23".to_f, 45, "string"] ],
+ [ "%f %d %s", "12.3e+23 45 string", ["12.3e23".to_f, 45, "string"] ],
+ [ "%f %d %s", "12.3e-23 45 string", ["12.3e-23".to_f, 45, "string"] ],
+ [ "%f %d %s", "12.3e23 45 string", ["12.3e23".to_f, 45, "string"] ],
+ [ "%f %d %s", "-12.3e-23 45 string", ["-12.3e-23".to_f, 45, "string"] ],
+ [ "%f %d %s", "12.e23 45 string", ["12.e23".to_f, 45, "string"] ],
+ [ "%5f %d %s", "1.2e23 string", ["1.2e2".to_f, 3, "string"] ],
+ [ "%5f%d %s", "1.2e23 string", ["1.2e2".to_f, 3, "string"] ],
+ [ "%5f%d %d %s", "1.2e23 45 string", ["1.2e2".to_f, 3, 45, "string"] ],
+ [ "%6f %d %d %s", "+1.2e23 45 string", ["1.2e2".to_f, 3, 45, "string"] ],
+ [ "%d %d", "123 \n 345", [123, 345] ],
+ [ "%d %*d", "123 \n 345", [123] ],
+ [ "%d %3d789", "123 +45789", [123, 45] ],
+ [ "%d %3d%d", "123 +456789", [123, 45, 6789] ],
+ [ "%d %3dabc", "123 456abc", [123, 456] ],
+ [ "%d %s", "123abc", [123, "abc"] ],
+ [ "%d%s %s", "123 abc def", [123, "abc", "def"] ],
+ [ "%s%s", "abc123 def", ["abc123", "def"] ],
+ [ "%s%s %s", "123 abc def", ["123", "abc", "def"] ],
+ [ "%s%%%s", "abc % def", ["abc", "def"] ],
+ [ "%d %3d %s", "+123 456abc", [123, 456, "abc"] ],
+ [ "%d %3d %s", "123 456abc", [123, 456, "abc"] ],
+ [ "%d %3d %s", "123 +456 abc", [123, 45, "6"] ],
+ [ "%d %3d %s", "-123-456abc", [-123, -45, "6abc"] ],
+ [ "%dabc%d", "123abc345", [123, 345] ],
+ [ "%d%5s%d", "123 abcde12", [123, "abcde", 12] ],
+ [ "%5d%5s%5d", "12345abcde67890", [12345, "abcde", 67890] ],
+ [ "%5d%*5s%5d", "12345abcde67890", [12345, 67890] ],
+ [ " 12345%5s%5d", "12345abcde67890", [ "abcde", 67890] ],
+ [ "%5dabcde%5d", "12345abcde67890", [ 12345, 67890] ],
+ [ "%s%%%*s", "abc % def", ["abc"] ],
+ [ "%*6s %d", "string 123", [123] ],
+ [ "%d %*3d %s", "-123-456abc", [-123, "6abc"] ],
+ [ "%d%s", "123", [123] ],
+ [ "%s%d", "abc", ["abc"] ],
+ [ "%f%x", "3.2e45x", ["3.2e45x".to_f] ],
+ [ "%s%d", "abc", ["abc"] ],
+ [ "%*5f%d %d %s", "1.2e23 45 string", [3, 45, "string"] ],
+ [ "%5f%*d %d %s", "1.2e23 45 string", ["1.2e2".to_f, 45, "string"] ],
+ [ "%*5f%*d %*d %s", "1.2e23 45 string", ["string"] ],
+ [ "%f %*d %s", "12.e23 45 string", ["12.e23".to_f, "string"] ],
+ [ "%5f %d %s", "1.2e23 string", ["1.2e2".to_f, 3, "string"] ],
+ [ "%s %f %s %d %x%c%c%c%c",
+ "float: 1.2e23 dec/hex: 135a23 abc",
+ ["float:", "1.2e23".to_f, "dec/hex:", 135, "a23".hex, " ", "a", "b", "c" ] ],
+
+# Testing 's'
+ [ "%s\n", "blah\n\n\n", [ "blah" ] ],
+
+# Testing '['
+ [ "%[a\nb]", "a\nb", [ "a\nb" ] ],
+ [ "%[abc]", "acb", [ "acb" ] ],
+ [ "%[abc\n]", "a\nb", [ "a\nb" ] ],
+ [ "%[^abc]", "defabc", [ "def" ] ],
+ [ "%[-abc]", "abc-cba", [ "abc-cba" ] ],
+ [ "%[\n]", "\n", [ "\n" ] ],
+ [ "%[\n]", "\nabc", [ "\n" ] ],
+ [ "%[\n\t]", "\t\n", [ "\t\n" ] ],
+ [ "%[a-f]", "abczef", [ "abc" ] ],
+ [ "%d%3[abc]", "123 aaab", [ 123 ] ],
+ [ "%d%3[^abc]", "123adefdef", [ 123 ] ],
+ [ "%d%3[[:lower:]] %f", "123ade1.2", [ 123,"ade",1.2 ] ],
+ [ "%d%3[[:lower:]] %f", "123ad1.2", [ 123,"ad",1.2 ] ],
+ [ "%d%3[[:lower:]] %f", "123 ad1.2", [ 123 ] ],
+ [ "%d%[[:lower:]]", "123abcdef1.2", [ 123, "abcdef" ] ],
+ [ "%[[:lower:]]%d", "abcdef123", [ "abcdef", 123 ] ],
+ [ "%[[:digit:]]%[[:alpha:]]", "123abcdef", [ "123", "abcdef" ] ],
+ [ "%[[:digit:]]%d", "123 123", [ "123", 123 ] ],
+ [ "%[[:upper:]]", "ABCdefGHI", [ "ABC" ] ],
+
+# Testing 'f'
+ [ "%2f", "x", [] ],
+ [ "%F", "1.23e45", [1.23e+45] ],
+ [ "%e", "3.25ee", [3.25] ],
+ [ "%E", "3..25", [3.0] ],
+ [ "%g", "+3.25", [3.25] ],
+ [ "%G", "+3.25e2", [325.0] ],
+ [ "%f", "3.z", [3.0] ],
+ [ "%a", "0X1P+10", [1024.0] ],
+ [ "%A", "0x1.deadbeefp+99", [1.1851510441583988e+30] ],
+
+# Testing embedded matches including literal '[' behavior
+ [",%d,%f", ",10,1.1", [10,1.1] ],
+ [" ,%d,%f", " ,10,1.1", [10,1.1] ],
+ ["[%d,%f", "[10,1.1", [10,1.1] ],
+ [" [%d,%f", " [10,1.1", [10,1.1] ],
+
+ ]
+ end
+end
+
+class TestStringScanf
+ include Scanf
+ extend ScanfTests
+
+ i = 1
+ self.tests.each do |test|
+ define_method("test_#{i}") do ||
+ assert_equal(test[2], test[1].scanf(test[0]))
+ end
+ i += 1
+ end
+end
+
+class TestIOScanf
+ include Scanf
+ extend ScanfTests
+
+ tmpfilename = "#{Dir.tmpdir}/iotest.dat.#{$$}"
+
+ i = 1
+ self.tests.each do |test|
+ define_method("test_#{i}") do ||
+ File.open(tmpfilename, "w") {|fh| fh.print test[1]}
+ File.open(tmpfilename, "r") { |fh|
+ assert_equal(test[2], fh.scanf(test[0]))
+ }
+ File.delete(tmpfilename)
+ end
+ i += 1
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/scanf/test_scanfblocks.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/scanf/test_scanfblocks.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/scanf/test_scanfblocks.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,81 @@
+# $Id: test_scanfblocks.rb 25189 2009-10-02 12:04:37Z akr $
+#
+# scanf for Ruby
+#
+# Some not very comprehensive tests of block behavior.
+
+
+require 'test/unit'
+require 'scanf'
+require 'tmpdir'
+
+class TestScanfBlock < Test::Unit::TestCase
+
+ def setup
+ @str = <<-EOS
+ Beethoven 1770
+ Bach 1685
+ Handel 1685
+ Scarlatti 1685
+ Brahms 1833
+ EOS
+ end
+
+alias set_up setup
+ def test_str1
+ res = @str.scanf("%s%d") { |name, year| "#{name} was born in #{year}." }
+ assert_equal(res,
+ [ "Beethoven was born in 1770.",
+ "Bach was born in 1685.",
+ "Handel was born in 1685.",
+ "Scarlatti was born in 1685.",
+ "Brahms was born in 1833." ])
+ end
+
+ def test_str2
+ names = @str.scanf("%s%d") { |name, year| name.upcase }
+ assert_equal(names, ["BEETHOVEN", "BACH", "HANDEL", "SCARLATTI", "BRAHMS"])
+ end
+
+ def test_str3
+ assert_equal("".scanf("%d%f%s") {}, [])
+ end
+
+ def test_str4
+ assert_equal("abc".scanf("%d%f%s") {}, [])
+ end
+
+ def test_str5
+ assert_equal("abc".scanf("") {}, [])
+ end
+
+ def test_io1
+ fn = "#{Dir.tmpdir}/iotest.dat.#{$$}"
+ File.open(fn, "w") { |fh| fh.puts(@str) }
+ fh = File.open(fn, "rb")
+ res = fh.scanf("%s%d") { |name, year| "#{name} was born in #{year}." }
+
+ assert_equal(
+ [ "Beethoven was born in 1770.",
+ "Bach was born in 1685.",
+ "Handel was born in 1685.",
+ "Scarlatti was born in 1685.",
+ "Brahms was born in 1833." ],res)
+ fh.close
+ ensure
+ File.delete(fn)
+ end
+
+ def test_io2
+ fn = "#{Dir.tmpdir}/iotest.dat.#{$$}"
+ File.open(fn, "w").close
+ fh = File.open(fn,"rb")
+ assert_equal(fh.scanf("") {}, [])
+ fh.seek(0)
+ assert_equal(fh.scanf("%d%f%s") {}, [])
+ fh.close
+ ensure
+ File.delete(fn)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/scanf/test_scanfio.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/scanf/test_scanfio.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/scanf/test_scanfio.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,20 @@
+# $Id: test_scanfio.rb 25426 2009-10-21 03:44:56Z nobu $
+#
+# scanf for Ruby
+#
+# Ad hoc tests of IO#scanf (needs to be expanded)
+
+
+require "scanf"
+
+class TestScanfIO < Test::Unit::TestCase
+ def test_io
+ fh = File.new(File.join(File.dirname(__FILE__), "data.txt"), "r")
+ assert_equal(0, fh.pos)
+ assert_equal(["this", "is"], fh.scanf("%s%s"))
+ assert_equal([33, "little"], fh.scanf("%da fun%s"))
+ ensure
+ fh.close
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/sdbm/test_sdbm.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/sdbm/test_sdbm.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/sdbm/test_sdbm.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,555 @@
+require 'test/unit'
+require 'tmpdir'
+
+begin
+ require 'sdbm'
+rescue LoadError
+end
+
+class TestSDBM < Test::Unit::TestCase
+ def setup
+ @tmpdir = Dir.mktmpdir("tmptest_sdbm")
+ @prefix = "tmptest_sdbm_#{$$}"
+ @path = "#{@tmpdir}/#{@prefix}_"
+ assert_instance_of(SDBM, @sdbm = SDBM.new(@path))
+ end
+ def teardown
+ assert_nil(@sdbm.close)
+ ObjectSpace.each_object(SDBM) do |obj|
+ obj.close unless obj.closed?
+ end
+ FileUtils.remove_entry_secure @tmpdir
+ end
+
+ def check_size(expect, sdbm=@sdbm)
+ assert_equal(expect, sdbm.size)
+ n = 0
+ sdbm.each { n+=1 }
+ assert_equal(expect, n)
+ if expect == 0
+ assert_equal(true, sdbm.empty?)
+ else
+ assert_equal(false, sdbm.empty?)
+ end
+ end
+
+ def have_fork?
+ begin
+ fork{}
+ true
+ rescue NotImplementedError
+ false
+ end
+ end
+
+ def test_version
+ assert(! SDBM.const_defined?(:VERSION))
+ end
+
+ def test_s_new_has_no_block
+ # SDBM.new ignore the block
+ foo = true
+ assert_instance_of(SDBM, sdbm = SDBM.new("#{@tmpdir}/#{@prefix}") { foo = false })
+ assert_equal(foo, true)
+ assert_nil(sdbm.close)
+ end
+ def test_s_open_no_create
+ assert_nil(sdbm = SDBM.open("#{@tmpdir}/#{@prefix}", nil))
+ ensure
+ sdbm.close if sdbm
+ end
+ def test_s_open_with_block
+ assert_equal(SDBM.open("#{@tmpdir}/#{@prefix}") { :foo }, :foo)
+ end
+=begin
+ # Is it guaranteed on many OS?
+ def test_s_open_lock_one_process
+ # locking on one process
+ assert_instance_of(SDBM, sdbm = SDBM.open("#{@tmpdir}/#{@prefix}", 0644))
+ assert_raise(Errno::EWOULDBLOCK) {
+ begin
+ SDBM.open("#{@tmpdir}/#{@prefix}", 0644)
+ rescue Errno::EAGAIN
+ raise Errno::EWOULDBLOCK
+ end
+ }
+ end
+=end
+
+ def test_s_open_nolock
+ # sdbm 1.8.0 specific
+ if not defined? SDBM::NOLOCK
+ return
+ end
+ return unless have_fork? # snip this test
+
+ pid = fork() {
+ assert_instance_of(SDBM, sdbm = SDBM.open("#{@tmpdir}/#{@prefix}", 0644,
+ SDBM::NOLOCK))
+ sleep 2
+ }
+ sleep 1
+ begin
+ sdbm2 = nil
+ assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
+ assert_instance_of(SDBM, sdbm2 = SDBM.open("#{@tmpdir}/#{@prefix}", 0644))
+ }
+ ensure
+ Process.wait pid
+ sdbm2.close if sdbm2
+ end
+
+ p Dir.glob("#{@tmpdir}/#{@prefix}*") if $DEBUG
+
+ pid = fork() {
+ assert_instance_of(SDBM, sdbm = SDBM.open("#{@tmpdir}/#{@prefix}", 0644))
+ sleep 2
+ }
+ begin
+ sleep 1
+ sdbm2 = nil
+ assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
+ # this test is failed on Cygwin98 (???)
+ assert_instance_of(SDBM, sdbm2 = SDBM.open("#{@tmpdir}/#{@prefix}", 0644,
+ SDBM::NOLOCK))
+ }
+ ensure
+ Process.wait pid
+ sdbm2.close if sdbm2
+ end
+ end
+
+ def test_s_open_error
+ skip "doesn't support to avoid read access by owner on Windows" if /mswin|mingw/ =~ RUBY_PLATFORM
+ assert_instance_of(SDBM, sdbm = SDBM.open("#{@tmpdir}/#{@prefix}", 0))
+ assert_raise(Errno::EACCES) {
+ SDBM.open("#{@tmpdir}/#{@prefix}", 0)
+ }
+ sdbm.close
+ end
+
+ def test_close
+ assert_instance_of(SDBM, sdbm = SDBM.open("#{@tmpdir}/#{@prefix}"))
+ assert_nil(sdbm.close)
+
+ # closed SDBM file
+ assert_raise(SDBMError) { sdbm.close }
+ end
+
+ def test_aref
+ assert_equal('bar', @sdbm['foo'] = 'bar')
+ assert_equal('bar', @sdbm['foo'])
+
+ assert_nil(@sdbm['bar'])
+ end
+
+ def test_fetch
+ assert_equal('bar', @sdbm['foo']='bar')
+ assert_equal('bar', @sdbm.fetch('foo'))
+
+ # key not found
+ assert_raise(IndexError) {
+ @sdbm.fetch('bar')
+ }
+
+ # test for `ifnone' arg
+ assert_equal('baz', @sdbm.fetch('bar', 'baz'))
+
+ # test for `ifnone' block
+ assert_equal('foobar', @sdbm.fetch('bar') {|key| 'foo' + key })
+ end
+
+ def test_aset
+ num = 0
+ 2.times {|i|
+ assert_equal('foo', @sdbm['foo'] = 'foo')
+ assert_equal('foo', @sdbm['foo'])
+ assert_equal('bar', @sdbm['foo'] = 'bar')
+ assert_equal('bar', @sdbm['foo'])
+
+ num += 1 if i == 0
+ assert_equal(num, @sdbm.size)
+
+ # assign nil
+ assert_equal('', @sdbm['bar'] = '')
+ assert_equal('', @sdbm['bar'])
+
+ num += 1 if i == 0
+ assert_equal(num, @sdbm.size)
+
+ # empty string
+ assert_equal('', @sdbm[''] = '')
+ assert_equal('', @sdbm[''])
+
+ num += 1 if i == 0
+ assert_equal(num, @sdbm.size)
+
+ # Fixnum
+ assert_equal('200', @sdbm['100'] = '200')
+ assert_equal('200', @sdbm['100'])
+
+ num += 1 if i == 0
+ assert_equal(num, @sdbm.size)
+
+ # Big key and value
+ assert_equal('y' * 100, @sdbm['x' * 100] = 'y' * 100)
+ assert_equal('y' * 100, @sdbm['x' * 100])
+
+ num += 1 if i == 0
+ assert_equal(num, @sdbm.size)
+ }
+ end
+
+ def test_key
+ assert_equal('bar', @sdbm['foo'] = 'bar')
+ assert_equal('foo', @sdbm.key('bar'))
+ assert_nil(@sdbm['bar'])
+ end
+
+ def test_values_at
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+ @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
+ assert_equal(values.reverse, @sdbm.values_at(*keys.reverse))
+ end
+
+ def test_select_with_block
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+ @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
+ ret = @sdbm.select {|k,v|
+ assert_equal(k.upcase, v)
+ k != "bar"
+ }
+ assert_equal([['baz', 'BAZ'], ['foo', 'FOO']],
+ ret.sort)
+ end
+
+ def test_length
+ num = 10
+ assert_equal(0, @sdbm.size)
+ num.times {|i|
+ i = i.to_s
+ @sdbm[i] = i
+ }
+ assert_equal(num, @sdbm.size)
+
+ @sdbm.shift
+
+ assert_equal(num - 1, @sdbm.size)
+ end
+
+ def test_empty?
+ assert_equal(true, @sdbm.empty?)
+ @sdbm['foo'] = 'FOO'
+ assert_equal(false, @sdbm.empty?)
+ end
+
+ def test_each_pair
+ n = 0
+ @sdbm.each_pair { n += 1 }
+ assert_equal(0, n)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
+
+ n = 0
+ ret = @sdbm.each_pair {|key, val|
+ assert_not_nil(i = keys.index(key))
+ assert_equal(val, values[i])
+
+ n += 1
+ }
+ assert_equal(keys.size, n)
+ assert_equal(@sdbm, ret)
+ end
+
+ def test_each_value
+ n = 0
+ @sdbm.each_value { n += 1 }
+ assert_equal(0, n)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
+
+ n = 0
+ ret = @sdbm.each_value {|val|
+ assert_not_nil(key = @sdbm.key(val))
+ assert_not_nil(i = keys.index(key))
+ assert_equal(val, values[i])
+
+ n += 1
+ }
+ assert_equal(keys.size, n)
+ assert_equal(@sdbm, ret)
+ end
+
+ def test_each_key
+ n = 0
+ @sdbm.each_key { n += 1 }
+ assert_equal(0, n)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
+
+ n = 0
+ ret = @sdbm.each_key {|key|
+ assert_not_nil(i = keys.index(key))
+ assert_equal(@sdbm[key], values[i])
+
+ n += 1
+ }
+ assert_equal(keys.size, n)
+ assert_equal(@sdbm, ret)
+ end
+
+ def test_keys
+ assert_equal([], @sdbm.keys)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
+
+ assert_equal(keys.sort, @sdbm.keys.sort)
+ assert_equal(values.sort, @sdbm.values.sort)
+ end
+
+ def test_values
+ test_keys
+ end
+
+ def test_shift
+ assert_nil(@sdbm.shift)
+ assert_equal(0, @sdbm.size)
+
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+
+ @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
+
+ ret_keys = []
+ ret_values = []
+ while ret = @sdbm.shift
+ ret_keys.push ret[0]
+ ret_values.push ret[1]
+
+ assert_equal(keys.size - ret_keys.size, @sdbm.size)
+ end
+
+ assert_equal(keys.sort, ret_keys.sort)
+ assert_equal(values.sort, ret_values.sort)
+ end
+
+ def test_delete
+ keys = %w(foo bar baz)
+ values = %w(FOO BAR BAZ)
+ key = keys[1]
+
+ assert_nil(@sdbm.delete(key))
+ assert_equal(0, @sdbm.size)
+
+ @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
+
+ assert_equal('BAR', @sdbm.delete(key))
+ assert_nil(@sdbm[key])
+ assert_equal(2, @sdbm.size)
+
+ assert_nil(@sdbm.delete(key))
+ end
+ def test_delete_with_block
+ key = 'no called block'
+ @sdbm[key] = 'foo'
+ assert_equal('foo', @sdbm.delete(key) {|k| k.replace 'called block'; :blockval})
+ assert_equal(0, @sdbm.size)
+
+ key = 'no called block'
+ assert_equal(:blockval, @sdbm.delete(key) {|k| k.replace 'called block'; :blockval})
+ assert_equal(0, @sdbm.size)
+ end
+
+ def test_delete_if
+ v = "0"
+ 100.times {@sdbm[v] = v; v = v.next}
+
+ ret = @sdbm.delete_if {|key, val| key.to_i < 50}
+ assert_equal(@sdbm, ret)
+ check_size(50, @sdbm)
+
+ ret = @sdbm.delete_if {|key, val| key.to_i >= 50}
+ assert_equal(@sdbm, ret)
+ check_size(0, @sdbm)
+
+ # break
+ v = "0"
+ 100.times {@sdbm[v] = v; v = v.next}
+ check_size(100, @sdbm)
+ n = 0;
+ @sdbm.delete_if {|key, val|
+ break if n > 50
+ n+=1
+ true
+ }
+ assert_equal(51, n)
+ check_size(49, @sdbm)
+
+ @sdbm.clear
+
+ # raise
+ v = "0"
+ 100.times {@sdbm[v] = v; v = v.next}
+ check_size(100, @sdbm)
+ n = 0;
+ begin
+ @sdbm.delete_if {|key, val|
+ raise "runtime error" if n > 50
+ n+=1
+ true
+ }
+ rescue
+ end
+ assert_equal(51, n)
+ check_size(49, @sdbm)
+ end
+
+ def test_reject
+ v = "0"
+ 100.times {@sdbm[v] = v; v = v.next}
+
+ hash = @sdbm.reject {|key, val| key.to_i < 50}
+ assert_instance_of(Hash, hash)
+ assert_equal(100, @sdbm.size)
+
+ assert_equal(50, hash.size)
+ hash.each_pair {|key,val|
+ assert_equal(false, key.to_i < 50)
+ assert_equal(key, val)
+ }
+
+ hash = @sdbm.reject {|key, val| key.to_i < 100}
+ assert_instance_of(Hash, hash)
+ assert_equal(true, hash.empty?)
+ end
+
+ def test_clear
+ v = "1"
+ 100.times {v = v.next; @sdbm[v] = v}
+
+ assert_equal(@sdbm, @sdbm.clear)
+
+ # validate SDBM#size
+ i = 0
+ @sdbm.each { i += 1 }
+ assert_equal(@sdbm.size, i)
+ assert_equal(0, i)
+ end
+
+ def test_invert
+ v = "0"
+ 100.times {@sdbm[v] = v; v = v.next}
+
+ hash = @sdbm.invert
+ assert_instance_of(Hash, hash)
+ assert_equal(100, hash.size)
+ hash.each_pair {|key, val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_update
+ hash = {}
+ v = "0"
+ 100.times {v = v.next; hash[v] = v}
+
+ @sdbm["101"] = "101"
+ @sdbm.update hash
+ assert_equal(101, @sdbm.size)
+ @sdbm.each_pair {|key, val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_replace
+ hash = {}
+ v = "0"
+ 100.times {v = v.next; hash[v] = v}
+
+ @sdbm["101"] = "101"
+ @sdbm.replace hash
+ assert_equal(100, @sdbm.size)
+ @sdbm.each_pair {|key, val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_haskey?
+ assert_equal('bar', @sdbm['foo']='bar')
+ assert_equal(true, @sdbm.has_key?('foo'))
+ assert_equal(false, @sdbm.has_key?('bar'))
+ end
+
+ def test_has_value?
+ assert_equal('bar', @sdbm['foo']='bar')
+ assert_equal(true, @sdbm.has_value?('bar'))
+ assert_equal(false, @sdbm.has_value?('foo'))
+ end
+
+ def test_to_a
+ v = "0"
+ 100.times {v = v.next; @sdbm[v] = v}
+
+ ary = @sdbm.to_a
+ assert_instance_of(Array, ary)
+ assert_equal(100, ary.size)
+ ary.each {|key,val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_to_hash
+ v = "0"
+ 100.times {v = v.next; @sdbm[v] = v}
+
+ hash = @sdbm.to_hash
+ assert_instance_of(Hash, hash)
+ assert_equal(100, hash.size)
+ hash.each {|key,val|
+ assert_equal(key.to_i, val.to_i)
+ }
+ end
+
+ def test_closed
+ assert_equal(false, @sdbm.closed?)
+ @sdbm.close
+ assert_equal(true, @sdbm.closed?)
+ @sdbm = SDBM.new(@path)
+ end
+
+ def test_readonly
+ @sdbm["bar"] = "baz"
+ @sdbm.close
+ File.chmod(0444, @path + ".dir")
+ File.chmod(0444, @path + ".pag")
+ @sdbm = SDBM.new(@path)
+ assert_raise(SDBMError) { @sdbm["bar"] = "foo" }
+ assert_raise(SDBMError) { @sdbm.delete("bar") }
+ assert_raise(SDBMError) { @sdbm.delete_if { true } }
+ assert_raise(SDBMError) { @sdbm.clear }
+ assert_nil(@sdbm.store("bar", nil))
+ end
+
+ def test_update2
+ obj = Object.new
+ def obj.each_pair
+ yield []
+ end
+ assert_raise(ArgumentError) { @sdbm.update(obj) }
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/socket/test_addrinfo.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/socket/test_addrinfo.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/socket/test_addrinfo.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,615 @@
+begin
+ require "socket"
+rescue LoadError
+end
+
+require "test/unit"
+
+class TestSocketAddrinfo < Test::Unit::TestCase
+ HAS_UNIXSOCKET = defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM
+
+ def tcp_unspecified_to_loopback(addrinfo)
+ if addrinfo.ipv4? && addrinfo.ip_address == "0.0.0.0"
+ Addrinfo.tcp("127.0.0.1", addrinfo.ip_port)
+ elsif addrinfo.ipv6? && addrinfo.ipv6_unspecified?
+ Addrinfo.tcp("::1", addrinfo.ip_port)
+ elsif addrinfo.ipv6? && (ai = addrinfo.ipv6_to_ipv4) && ai.ip_address == "0.0.0.0"
+ Addrinfo.tcp("127.0.0.1", addrinfo.ip_port)
+ else
+ addrinfo
+ end
+ end
+
+ def test_addrinfo_ip
+ ai = Addrinfo.ip("127.0.0.1")
+ assert_equal([0, "127.0.0.1"], Socket.unpack_sockaddr_in(ai))
+ assert_equal(Socket::AF_INET, ai.afamily)
+ assert_equal(Socket::PF_INET, ai.pfamily)
+ assert_equal(0, ai.socktype)
+ assert_equal(0, ai.protocol)
+ end
+
+ def test_addrinfo_tcp
+ ai = Addrinfo.tcp("127.0.0.1", 80)
+ assert_equal([80, "127.0.0.1"], Socket.unpack_sockaddr_in(ai))
+ assert_equal(Socket::AF_INET, ai.afamily)
+ assert_equal(Socket::PF_INET, ai.pfamily)
+ assert_equal(Socket::SOCK_STREAM, ai.socktype)
+ assert_includes([0, Socket::IPPROTO_TCP], ai.protocol)
+ end
+
+ def test_addrinfo_udp
+ ai = Addrinfo.udp("127.0.0.1", 80)
+ assert_equal([80, "127.0.0.1"], Socket.unpack_sockaddr_in(ai))
+ assert_equal(Socket::AF_INET, ai.afamily)
+ assert_equal(Socket::PF_INET, ai.pfamily)
+ assert_equal(Socket::SOCK_DGRAM, ai.socktype)
+ assert_includes([0, Socket::IPPROTO_UDP], ai.protocol)
+ end
+
+ def test_addrinfo_ip_unpack
+ ai = Addrinfo.tcp("127.0.0.1", 80)
+ assert_equal(["127.0.0.1", 80], ai.ip_unpack)
+ assert_equal("127.0.0.1", ai.ip_address)
+ assert_equal(80, ai.ip_port)
+ end
+
+ def test_addrinfo_inspect_sockaddr
+ ai = Addrinfo.tcp("127.0.0.1", 80)
+ assert_equal("127.0.0.1:80", ai.inspect_sockaddr)
+ end
+
+ def test_addrinfo_new_inet
+ ai = Addrinfo.new(["AF_INET", 46102, "localhost.localdomain", "127.0.0.2"])
+ assert_equal([46102, "127.0.0.2"], Socket.unpack_sockaddr_in(ai))
+ assert_equal(Socket::AF_INET, ai.afamily)
+ assert_equal(Socket::PF_INET, ai.pfamily)
+ assert_equal(0, ai.socktype)
+ assert_equal(0, ai.protocol)
+ end
+
+ def test_addrinfo_predicates
+ ipv4_ai = Addrinfo.new(Socket.sockaddr_in(80, "192.168.0.1"))
+ assert(ipv4_ai.ip?)
+ assert(ipv4_ai.ipv4?)
+ assert(!ipv4_ai.ipv6?)
+ assert(!ipv4_ai.unix?)
+ end
+
+ def test_ipv4_address_predicates
+ list = [
+ [:ipv4_private?, "10.0.0.0", "10.255.255.255",
+ "172.16.0.0", "172.31.255.255",
+ "192.168.0.0", "192.168.255.255"],
+ [:ipv4_loopback?, "127.0.0.1", "127.0.0.0", "127.255.255.255"],
+ [:ipv4_multicast?, "224.0.0.0", "224.255.255.255"]
+ ]
+ list.each {|meth, *addrs|
+ addrs.each {|addr|
+ assert(Addrinfo.ip(addr).send(meth), "Addrinfo.ip(#{addr.inspect}).#{meth}")
+ list.each {|meth2,|
+ next if meth == meth2
+ assert(!Addrinfo.ip(addr).send(meth2), "!Addrinfo.ip(#{addr.inspect}).#{meth2}")
+ }
+ }
+ }
+ end
+
+ def test_basicsocket_send
+ s1 = Socket.new(:INET, :DGRAM, 0)
+ s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ sa = s1.getsockname
+ ai = Addrinfo.new(sa)
+ s2 = Socket.new(:INET, :DGRAM, 0)
+ s2.send("test-basicsocket-send", 0, ai)
+ assert_equal("test-basicsocket-send", s1.recv(100))
+ ensure
+ s1.close if s1 && !s1.closed?
+ s2.close if s2 && !s2.closed?
+ end
+
+ def test_udpsocket_send
+ s1 = UDPSocket.new
+ s1.bind("127.0.0.1", 0)
+ ai = Addrinfo.new(s1.getsockname)
+ s2 = UDPSocket.new
+ s2.send("test-udp-send", 0, ai)
+ assert_equal("test-udp-send", s1.recv(100))
+ ensure
+ s1.close if s1 && !s1.closed?
+ s2.close if s2 && !s2.closed?
+ end
+
+ def test_socket_bind
+ s1 = Socket.new(:INET, :DGRAM, 0)
+ sa = Socket.sockaddr_in(0, "127.0.0.1")
+ ai = Addrinfo.new(sa)
+ s1.bind(ai)
+ s2 = UDPSocket.new
+ s2.send("test-socket-bind", 0, s1.getsockname)
+ assert_equal("test-socket-bind", s1.recv(100))
+ ensure
+ s1.close if s1 && !s1.closed?
+ s2.close if s2 && !s2.closed?
+ end
+
+ def test_socket_connect
+ s1 = Socket.new(:INET, :STREAM, 0)
+ s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ s1.listen(5)
+ ai = Addrinfo.new(s1.getsockname)
+ s2 = Socket.new(:INET, :STREAM, 0)
+ s2.connect(ai)
+ s3, sender_addr = s1.accept
+ s2.send("test-socket-connect", 0)
+ assert_equal("test-socket-connect", s3.recv(100))
+ ensure
+ s1.close if s1 && !s1.closed?
+ s2.close if s2 && !s2.closed?
+ s3.close if s3 && !s3.closed?
+ end
+
+ def test_socket_connect_nonblock
+ s1 = Socket.new(:INET, :STREAM, 0)
+ s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ s1.listen(5)
+ ai = Addrinfo.new(s1.getsockname)
+ s2 = Socket.new(:INET, :STREAM, 0)
+ begin
+ s2.connect_nonblock(ai)
+ rescue IO::WaitWritable
+ IO.select(nil, [s2])
+ begin
+ s2.connect_nonblock(ai)
+ rescue Errno::EISCONN
+ end
+ end
+ s3, sender_addr = s1.accept
+ s2.send("test-socket-connect-nonblock", 0)
+ assert_equal("test-socket-connect-nonblock", s3.recv(100))
+ ensure
+ s1.close if s1 && !s1.closed?
+ s2.close if s2 && !s2.closed?
+ s3.close if s3 && !s3.closed?
+ end
+
+ def test_socket_getnameinfo
+ ai = Addrinfo.udp("127.0.0.1", 8888)
+ assert_equal(["127.0.0.1", "8888"], Socket.getnameinfo(ai, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV))
+ end
+
+ def test_basicsocket_local_address
+ s1 = Socket.new(:INET, :DGRAM, 0)
+ s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ e = Socket.unpack_sockaddr_in(s1.getsockname)
+ a = Socket.unpack_sockaddr_in(s1.local_address.to_sockaddr)
+ assert_equal(e, a)
+ assert_equal(Socket::AF_INET, s1.local_address.afamily)
+ assert_equal(Socket::PF_INET, s1.local_address.pfamily)
+ assert_equal(Socket::SOCK_DGRAM, s1.local_address.socktype)
+ ensure
+ s1.close if s1 && !s1.closed?
+ end
+
+ def test_basicsocket_remote_address
+ s1 = TCPServer.new("127.0.0.1", 0)
+ s2 = Socket.new(:INET, :STREAM, 0)
+ s2.connect(s1.getsockname)
+ s3, _ = s1.accept
+ e = Socket.unpack_sockaddr_in(s2.getsockname)
+ a = Socket.unpack_sockaddr_in(s3.remote_address.to_sockaddr)
+ assert_equal(e, a)
+ assert_equal(Socket::AF_INET, s3.remote_address.afamily)
+ assert_equal(Socket::PF_INET, s3.remote_address.pfamily)
+ assert_equal(Socket::SOCK_STREAM, s3.remote_address.socktype)
+ ensure
+ s1.close if s1 && !s1.closed?
+ s2.close if s2 && !s2.closed?
+ s3.close if s3 && !s3.closed?
+ end
+
+ def test_socket_accept
+ serv = Socket.new(:INET, :STREAM, 0)
+ serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ serv.listen(5)
+ c = Socket.new(:INET, :STREAM, 0)
+ c.connect(serv.local_address)
+ ret = serv.accept
+ s, ai = ret
+ assert_kind_of(Array, ret)
+ assert_equal(2, ret.length)
+ assert_kind_of(Addrinfo, ai)
+ e = Socket.unpack_sockaddr_in(c.getsockname)
+ a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
+ assert_equal(e, a)
+ ensure
+ serv.close if serv && !serv.closed?
+ s.close if s && !s.closed?
+ c.close if c && !c.closed?
+ end
+
+ def test_socket_accept_nonblock
+ serv = Socket.new(:INET, :STREAM, 0)
+ serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ serv.listen(5)
+ c = Socket.new(:INET, :STREAM, 0)
+ c.connect(serv.local_address)
+ begin
+ ret = serv.accept_nonblock
+ rescue IO::WaitReadable, Errno::EINTR
+ IO.select([serv])
+ retry
+ end
+ s, ai = ret
+ assert_kind_of(Array, ret)
+ assert_equal(2, ret.length)
+ assert_kind_of(Addrinfo, ai)
+ e = Socket.unpack_sockaddr_in(c.getsockname)
+ a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
+ assert_equal(e, a)
+ ensure
+ serv.close if serv && !serv.closed?
+ s.close if s && !s.closed?
+ c.close if c && !c.closed?
+ end
+
+ def test_socket_sysaccept
+ serv = Socket.new(:INET, :STREAM, 0)
+ serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ serv.listen(5)
+ c = Socket.new(:INET, :STREAM, 0)
+ c.connect(serv.local_address)
+ ret = serv.sysaccept
+ fd, ai = ret
+ s = IO.new(fd)
+ assert_kind_of(Array, ret)
+ assert_equal(2, ret.length)
+ assert_kind_of(Addrinfo, ai)
+ e = Socket.unpack_sockaddr_in(c.getsockname)
+ a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
+ assert_equal(e, a)
+ ensure
+ serv.close if serv && !serv.closed?
+ s.close if s && !s.closed?
+ c.close if c && !c.closed?
+ end
+
+ def test_socket_recvfrom
+ s1 = Socket.new(:INET, :DGRAM, 0)
+ s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ s2 = Socket.new(:INET, :DGRAM, 0)
+ s2.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ s2.send("test-socket-recvfrom", 0, s1.getsockname)
+ data, ai = s1.recvfrom(100)
+ assert_equal("test-socket-recvfrom", data)
+ assert_kind_of(Addrinfo, ai)
+ e = Socket.unpack_sockaddr_in(s2.getsockname)
+ a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
+ assert_equal(e, a)
+ ensure
+ s1.close if s1 && !s1.closed?
+ s2.close if s2 && !s2.closed?
+ end
+
+ def test_socket_recvfrom_nonblock
+ s1 = Socket.new(:INET, :DGRAM, 0)
+ s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ s2 = Socket.new(:INET, :DGRAM, 0)
+ s2.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ s2.send("test-socket-recvfrom", 0, s1.getsockname)
+ begin
+ data, ai = s1.recvfrom_nonblock(100)
+ rescue IO::WaitReadable
+ IO.select([s1])
+ retry
+ end
+ assert_equal("test-socket-recvfrom", data)
+ assert_kind_of(Addrinfo, ai)
+ e = Socket.unpack_sockaddr_in(s2.getsockname)
+ a = Socket.unpack_sockaddr_in(ai.to_sockaddr)
+ assert_equal(e, a)
+ ensure
+ s1.close if s1 && !s1.closed?
+ s2.close if s2 && !s2.closed?
+ end
+
+ def test_family_addrinfo
+ ai = Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("127.0.0.1", 80)
+ assert_equal(["127.0.0.1", 80], ai.ip_unpack)
+ assert_equal(Socket::SOCK_STREAM, ai.socktype)
+ return unless Addrinfo.respond_to?(:unix)
+ ai = Addrinfo.unix("/testdir/sock").family_addrinfo("/testdir/sock2")
+ assert_equal("/testdir/sock2", ai.unix_path)
+ assert_equal(Socket::SOCK_STREAM, ai.socktype)
+ assert_raise(SocketError) { Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("::1", 80) }
+ end
+
+ def random_port
+ # IANA suggests dynamic port for 49152 to 65535
+ # http://www.iana.org/assignments/port-numbers
+ 49152 + rand(65535-49152+1)
+ end
+
+ def test_connect_from
+ TCPServer.open("0.0.0.0", 0) {|serv|
+ serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
+ serv_ai = tcp_unspecified_to_loopback(serv_ai)
+ port = random_port
+ begin
+ serv_ai.connect_from("0.0.0.0", port) {|s1|
+ s2 = serv.accept
+ begin
+ assert_equal(port, s2.remote_address.ip_port)
+ ensure
+ s2.close
+ end
+ }
+ rescue Errno::EADDRINUSE
+ # not test failure
+ end
+ }
+ end
+
+ def test_connect_to
+ TCPServer.open("0.0.0.0", 0) {|serv|
+ serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
+ serv_ai = tcp_unspecified_to_loopback(serv_ai)
+ port = random_port
+ client_ai = Addrinfo.tcp("0.0.0.0", port)
+ begin
+ client_ai.connect_to(*serv_ai.ip_unpack) {|s1|
+ s2 = serv.accept
+ begin
+ assert_equal(port, s2.remote_address.ip_port)
+ ensure
+ s2.close
+ end
+ }
+ rescue Errno::EADDRINUSE
+ # not test failure
+ end
+ }
+ end
+
+ def test_connect
+ TCPServer.open("0.0.0.0", 0) {|serv|
+ serv_ai = Addrinfo.new(serv.getsockname, :INET, :STREAM)
+ serv_ai = tcp_unspecified_to_loopback(serv_ai)
+ begin
+ serv_ai.connect {|s1|
+ s2 = serv.accept
+ begin
+ assert_equal(s1.local_address.ip_unpack, s2.remote_address.ip_unpack)
+ assert_equal(s2.local_address.ip_unpack, s1.remote_address.ip_unpack)
+ ensure
+ s2.close
+ end
+ }
+ rescue Errno::EADDRINUSE
+ # not test failure
+ end
+ }
+ end
+
+ def test_bind
+ port = random_port
+ client_ai = Addrinfo.tcp("0.0.0.0", port)
+ begin
+ client_ai.bind {|s|
+ assert_equal(port, s.local_address.ip_port)
+ }
+ rescue Errno::EADDRINUSE
+ # not test failure
+ end
+ end
+
+ def test_listen
+ port = random_port
+ client_ai = Addrinfo.tcp("0.0.0.0", port)
+ begin
+ client_ai.listen {|serv|
+ assert_equal(port, serv.local_address.ip_port)
+ serv_addr, serv_port = serv.local_address.ip_unpack
+ case serv_addr
+ when "0.0.0.0" then serv_addr = "127.0.0.1"
+ end
+ TCPSocket.open(serv_addr, serv_port) {|s1|
+ s2, addr = serv.accept
+ begin
+ assert_equal(s1.local_address.ip_unpack, addr.ip_unpack)
+ ensure
+ s2.close
+ end
+ }
+ }
+ rescue Errno::EADDRINUSE
+ # not test failure
+ end
+ end
+
+ def test_s_foreach
+ Addrinfo.foreach(nil, 80, nil, :STREAM) {|ai|
+ assert_kind_of(Addrinfo, ai)
+ }
+ end
+
+ def test_marshal
+ ai1 = Addrinfo.tcp("127.0.0.1", 80)
+ ai2 = Marshal.load(Marshal.dump(ai1))
+ assert_equal(ai1.afamily, ai2.afamily)
+ assert_equal(ai1.ip_unpack, ai2.ip_unpack)
+ assert_equal(ai1.pfamily, ai2.pfamily)
+ assert_equal(ai1.socktype, ai2.socktype)
+ assert_equal(ai1.protocol, ai2.protocol)
+ assert_equal(ai1.canonname, ai2.canonname)
+ end
+
+ if Socket.const_defined?("AF_INET6") && Socket::AF_INET6.is_a?(Integer)
+
+ def test_addrinfo_new_inet6
+ ai = Addrinfo.new(["AF_INET6", 42304, "ip6-localhost", "::1"])
+ assert_equal([42304, "::1"], Socket.unpack_sockaddr_in(ai))
+ assert_equal(Socket::AF_INET6, ai.afamily)
+ assert_equal(Socket::PF_INET6, ai.pfamily)
+ assert_equal(0, ai.socktype)
+ assert_equal(0, ai.protocol)
+ end
+
+ def test_addrinfo_ip_unpack_inet6
+ ai = Addrinfo.tcp("::1", 80)
+ assert_equal(["::1", 80], ai.ip_unpack)
+ assert_equal("::1", ai.ip_address)
+ assert_equal(80, ai.ip_port)
+ end
+
+ def test_addrinfo_inspect_sockaddr_inet6
+ ai = Addrinfo.tcp("::1", 80)
+ assert_equal("[::1]:80", ai.inspect_sockaddr)
+ end
+
+ def test_marshal_inet6
+ ai1 = Addrinfo.tcp("::1", 80)
+ ai2 = Marshal.load(Marshal.dump(ai1))
+ assert_equal(ai1.afamily, ai2.afamily)
+ assert_equal(ai1.ip_unpack, ai2.ip_unpack)
+ assert_equal(ai1.pfamily, ai2.pfamily)
+ assert_equal(ai1.socktype, ai2.socktype)
+ assert_equal(ai1.protocol, ai2.protocol)
+ assert_equal(ai1.canonname, ai2.canonname)
+ end
+
+ def ipv6(str)
+ Addrinfo.getaddrinfo(str, nil, :INET6, :DGRAM).fetch(0)
+ end
+
+ def test_ipv6_address_predicates
+ list = [
+ [:ipv6_unspecified?, "::"],
+ [:ipv6_loopback?, "::1"],
+ [:ipv6_v4compat?, "::0.0.0.2", "::255.255.255.255"],
+ [:ipv6_v4mapped?, "::ffff:0.0.0.0", "::ffff:255.255.255.255"],
+ [:ipv6_linklocal?, "fe80::", "febf::"],
+ [:ipv6_sitelocal?, "fec0::", "feef::"],
+ [:ipv6_multicast?, "ff00::", "ffff::"]
+ ]
+ mlist = [
+ [:ipv6_mc_nodelocal?, "ff01::", "ff11::"],
+ [:ipv6_mc_linklocal?, "ff02::", "ff12::"],
+ [:ipv6_mc_sitelocal?, "ff05::", "ff15::"],
+ [:ipv6_mc_orglocal?, "ff08::", "ff18::"],
+ [:ipv6_mc_global?, "ff0e::", "ff1e::"]
+ ]
+ list.each {|meth, *addrs|
+ addrs.each {|addr|
+ addr_exp = "Addrinfo.getaddrinfo(#{addr.inspect}, nil, :INET6, :DGRAM).fetch(0)"
+ if meth == :ipv6_v4compat? || meth == :ipv6_v4mapped?
+ # MacOS X returns IPv4 address for ::ffff:1.2.3.4 and ::1.2.3.4.
+ # Solaris returns IPv4 address for ::ffff:1.2.3.4.
+ ai = ipv6(addr)
+ assert(ai.ipv4? || ai.send(meth), "ai=#{addr_exp}; ai.ipv4? || .#{meth}")
+ else
+ assert(ipv6(addr).send(meth), "#{addr_exp}.#{meth}")
+ assert_equal(addr, ipv6(addr).ip_address)
+ end
+ list.each {|meth2,|
+ next if meth == meth2
+ assert(!ipv6(addr).send(meth2), "!#{addr_exp}.#{meth2}")
+ }
+ }
+ }
+ mlist.each {|meth, *addrs|
+ addrs.each {|addr|
+ addr_exp = "Addrinfo.getaddrinfo(#{addr.inspect}, nil, :INET6, :DGRAM).fetch(0)"
+ assert(ipv6(addr).send(meth), "#{addr_exp}.#{meth}")
+ assert(ipv6(addr).ipv6_multicast?, "#{addr_exp}.ipv6_multicast?")
+ mlist.each {|meth2,|
+ next if meth == meth2
+ assert(!ipv6(addr).send(meth2), "!#{addr_exp}.#{meth2}")
+ }
+ list.each {|meth2,|
+ next if :ipv6_multicast? == meth2
+ assert(!ipv6(addr).send(meth2), "!#{addr_exp}.#{meth2}")
+ }
+ }
+ }
+ end
+
+ def test_ipv6_to_ipv4
+ ai = Addrinfo.ip("::192.0.2.3")
+ ai = ai.ipv6_to_ipv4 if !ai.ipv4?
+ assert(ai.ipv4?)
+ assert_equal("192.0.2.3", ai.ip_address)
+
+ ai = Addrinfo.ip("::ffff:192.0.2.3")
+ ai = ai.ipv6_to_ipv4 if !ai.ipv4?
+ assert(ai.ipv4?)
+ assert_equal("192.0.2.3", ai.ip_address)
+
+ assert_nil(Addrinfo.ip("::1").ipv6_to_ipv4)
+ assert_nil(Addrinfo.ip("192.0.2.3").ipv6_to_ipv4)
+ if HAS_UNIXSOCKET
+ assert_nil(Addrinfo.unix("/testdir/sock").ipv6_to_ipv4)
+ end
+ end
+ end
+
+ if HAS_UNIXSOCKET
+
+ def test_addrinfo_unix
+ ai = Addrinfo.unix("/testdir/sock")
+ assert_equal("/testdir/sock", Socket.unpack_sockaddr_un(ai))
+ assert_equal(Socket::AF_UNIX, ai.afamily)
+ assert_equal(Socket::PF_UNIX, ai.pfamily)
+ assert_equal(Socket::SOCK_STREAM, ai.socktype)
+ assert_equal(0, ai.protocol)
+ end
+
+ def test_addrinfo_unix_dgram
+ ai = Addrinfo.unix("/testdir/sock", :DGRAM)
+ assert_equal("/testdir/sock", Socket.unpack_sockaddr_un(ai))
+ assert_equal(Socket::AF_UNIX, ai.afamily)
+ assert_equal(Socket::PF_UNIX, ai.pfamily)
+ assert_equal(Socket::SOCK_DGRAM, ai.socktype)
+ assert_equal(0, ai.protocol)
+ end
+
+ def test_addrinfo_unix_path
+ ai = Addrinfo.unix("/testdir/sock1")
+ assert_equal("/testdir/sock1", ai.unix_path)
+ end
+
+ def test_addrinfo_inspect_sockaddr_unix
+ ai = Addrinfo.unix("/testdir/test_addrinfo_inspect_sockaddr_unix")
+ assert_equal("/testdir/test_addrinfo_inspect_sockaddr_unix", ai.inspect_sockaddr)
+ end
+
+ def test_addrinfo_new_unix
+ ai = Addrinfo.new(["AF_UNIX", "/testdir/sock"])
+ assert_equal("/testdir/sock", Socket.unpack_sockaddr_un(ai))
+ assert_equal(Socket::AF_UNIX, ai.afamily)
+ assert_equal(Socket::PF_UNIX, ai.pfamily)
+ assert_equal(Socket::SOCK_STREAM, ai.socktype) # UNIXSocket/UNIXServer is SOCK_STREAM only.
+ assert_equal(0, ai.protocol)
+ end
+
+ def test_addrinfo_predicates_unix
+ unix_ai = Addrinfo.new(Socket.sockaddr_un("/testdir/sososo"))
+ assert(!unix_ai.ip?)
+ assert(!unix_ai.ipv4?)
+ assert(!unix_ai.ipv6?)
+ assert(unix_ai.unix?)
+ end
+
+ def test_marshal_unix
+ ai1 = Addrinfo.unix("/testdir/sock")
+ ai2 = Marshal.load(Marshal.dump(ai1))
+ assert_equal(ai1.afamily, ai2.afamily)
+ assert_equal(ai1.unix_path, ai2.unix_path)
+ assert_equal(ai1.pfamily, ai2.pfamily)
+ assert_equal(ai1.socktype, ai2.socktype)
+ assert_equal(ai1.protocol, ai2.protocol)
+ assert_equal(ai1.canonname, ai2.canonname)
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/socket/test_ancdata.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/socket/test_ancdata.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/socket/test_ancdata.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,66 @@
+require 'test/unit'
+require 'socket'
+
+class TestSocketAncData < Test::Unit::TestCase
+ def test_int
+ ancdata = Socket::AncillaryData.int(0, 0, 0, 123)
+ assert_equal(123, ancdata.int)
+ assert_equal([123].pack("i"), ancdata.data)
+ end
+
+ def test_ip_pktinfo
+ addr = Addrinfo.ip("127.0.0.1")
+ ifindex = 0
+ spec_dst = Addrinfo.ip("127.0.0.2")
+ begin
+ ancdata = Socket::AncillaryData.ip_pktinfo(addr, ifindex, spec_dst)
+ rescue NotImplementedError
+ return
+ end
+ assert_equal(Socket::AF_INET, ancdata.family)
+ assert_equal(Socket::IPPROTO_IP, ancdata.level)
+ assert_equal(Socket::IP_PKTINFO, ancdata.type)
+ assert_equal(addr.ip_address, ancdata.ip_pktinfo[0].ip_address)
+ assert_equal(ifindex, ancdata.ip_pktinfo[1])
+ assert_equal(spec_dst.ip_address, ancdata.ip_pktinfo[2].ip_address)
+ assert(ancdata.cmsg_is?(:IP, :PKTINFO))
+ assert(ancdata.cmsg_is?("IP", "PKTINFO"))
+ assert(ancdata.cmsg_is?(Socket::IPPROTO_IP, Socket::IP_PKTINFO))
+ if defined? Socket::IPV6_PKTINFO
+ assert(!ancdata.cmsg_is?(:IPV6, :PKTINFO))
+ end
+ ancdata2 = Socket::AncillaryData.ip_pktinfo(addr, ifindex)
+ assert_equal(addr.ip_address, ancdata2.ip_pktinfo[2].ip_address)
+ end
+
+ def test_ipv6_pktinfo
+ addr = Addrinfo.ip("::1")
+ ifindex = 0
+ begin
+ ancdata = Socket::AncillaryData.ipv6_pktinfo(addr, ifindex)
+ rescue NotImplementedError
+ return
+ end
+ assert_equal(Socket::AF_INET6, ancdata.family)
+ assert_equal(Socket::IPPROTO_IPV6, ancdata.level)
+ assert_equal(Socket::IPV6_PKTINFO, ancdata.type)
+ assert_equal(addr.ip_address, ancdata.ipv6_pktinfo[0].ip_address)
+ assert_equal(ifindex, ancdata.ipv6_pktinfo[1])
+ assert_equal(addr.ip_address, ancdata.ipv6_pktinfo_addr.ip_address)
+ assert_equal(ifindex, ancdata.ipv6_pktinfo_ifindex)
+ assert(ancdata.cmsg_is?(:IPV6, :PKTINFO))
+ assert(ancdata.cmsg_is?("IPV6", "PKTINFO"))
+ assert(ancdata.cmsg_is?(Socket::IPPROTO_IPV6, Socket::IPV6_PKTINFO))
+ if defined? Socket::IP_PKTINFO
+ assert(!ancdata.cmsg_is?(:IP, :PKTINFO))
+ end
+ end
+
+ if defined?(Socket::SCM_RIGHTS) && defined?(Socket::SCM_TIMESTAMP)
+ def test_unix_rights
+ assert_raise(TypeError) {
+ Socket::AncillaryData.int(:UNIX, :SOL_SOCKET, :TIMESTAMP, 1).unix_rights
+ }
+ end
+ end
+end if defined? Socket::AncillaryData
Added: MacRuby/trunk/test/test-mri/test/socket/test_basicsocket.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/socket/test_basicsocket.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/socket/test_basicsocket.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,88 @@
+begin
+ require "socket"
+ require "test/unit"
+rescue LoadError
+end
+
+class TestSocket_BasicSocket < Test::Unit::TestCase
+ def inet_stream
+ sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
+ yield sock
+ ensure
+ assert_raise(IOError) {sock.close}
+ end
+
+ def test_getsockopt
+ inet_stream do |s|
+ n = s.getsockopt(Socket::SOL_SOCKET, Socket::SO_TYPE)
+ assert_equal([Socket::SOCK_STREAM].pack("i"), n.data)
+
+ n = s.getsockopt("SOL_SOCKET", "SO_TYPE")
+ assert_equal([Socket::SOCK_STREAM].pack("i"), n.data)
+
+ n = s.getsockopt(:SOL_SOCKET, :SO_TYPE)
+ assert_equal([Socket::SOCK_STREAM].pack("i"), n.data)
+
+ n = s.getsockopt(:SOCKET, :TYPE)
+ assert_equal([Socket::SOCK_STREAM].pack("i"), n.data)
+
+ n = s.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR)
+ assert_equal([0].pack("i"), n.data)
+
+ val = Object.new
+ class << val; self end.send(:define_method, :to_int) {
+ s.close
+ Socket::SO_TYPE
+ }
+ assert_raise(IOError) {
+ n = s.getsockopt(Socket::SOL_SOCKET, val)
+ }
+ end
+ end
+
+ def test_setsockopt
+ s = nil
+ linger = [0, 0].pack("ii")
+
+ val = Object.new
+ class << val; self end.send(:define_method, :to_str) {
+ s.close
+ linger
+ }
+ inet_stream do |sock|
+ s = sock
+ assert_equal(0, s.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, linger))
+
+ assert_raise(IOError, "[ruby-dev:25039]") {
+ s.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, val)
+ }
+ end
+
+ val = Object.new
+ class << val; self end.send(:define_method, :to_int) {
+ s.close
+ Socket::SO_LINGER
+ }
+ inet_stream do |sock|
+ s = sock
+ assert_raise(IOError) {
+ s.setsockopt(Socket::SOL_SOCKET, val, linger)
+ }
+ end
+ end
+
+ def test_listen
+ s = nil
+ log = Object.new
+ class << log; self end.send(:define_method, :to_int) {
+ s.close
+ 2
+ }
+ inet_stream do |sock|
+ s = sock
+ assert_raise(IOError) {
+ s.listen(log)
+ }
+ end
+ end
+end if defined?(BasicSocket)
Added: MacRuby/trunk/test/test-mri/test/socket/test_nonblock.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/socket/test_nonblock.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/socket/test_nonblock.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,284 @@
+begin
+ require "socket"
+rescue LoadError
+end
+
+require "test/unit"
+require "tempfile"
+require "timeout"
+
+class TestSocketNonblock < Test::Unit::TestCase
+ def test_accept_nonblock
+ serv = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
+ serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ serv.listen(5)
+ assert_raise(IO::WaitReadable) { serv.accept_nonblock }
+ c = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
+ c.connect(serv.getsockname)
+ begin
+ s, sockaddr = serv.accept_nonblock
+ rescue IO::WaitReadable
+ IO.select [serv]
+ s, sockaddr = serv.accept_nonblock
+ end
+ assert_equal(Socket.unpack_sockaddr_in(c.getsockname), Socket.unpack_sockaddr_in(sockaddr))
+ ensure
+ serv.close if serv
+ c.close if c
+ s.close if s
+ end
+
+ def test_connect_nonblock
+ serv = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
+ serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ serv.listen(5)
+ c = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
+ servaddr = serv.getsockname
+ begin
+ c.connect_nonblock(servaddr)
+ rescue IO::WaitWritable
+ IO.select nil, [c]
+ assert_nothing_raised {
+ begin
+ c.connect_nonblock(servaddr)
+ rescue Errno::EISCONN
+ end
+ }
+ end
+ s, sockaddr = serv.accept
+ assert_equal(Socket.unpack_sockaddr_in(c.getsockname), Socket.unpack_sockaddr_in(sockaddr))
+ ensure
+ serv.close if serv
+ c.close if c
+ s.close if s
+ end
+
+ def test_udp_recvfrom_nonblock
+ u1 = UDPSocket.new
+ u2 = UDPSocket.new
+ u1.bind("127.0.0.1", 0)
+ assert_raise(IO::WaitReadable) { u1.recvfrom_nonblock(100) }
+ assert_raise(IO::WaitReadable, Errno::EINVAL) { u2.recvfrom_nonblock(100) }
+ u2.send("aaa", 0, u1.getsockname)
+ IO.select [u1]
+ mesg, inet_addr = u1.recvfrom_nonblock(100)
+ assert_equal(4, inet_addr.length)
+ assert_equal("aaa", mesg)
+ af, port, host, addr = inet_addr
+ u2_port, u2_addr = Socket.unpack_sockaddr_in(u2.getsockname)
+ assert_equal(u2_port, port)
+ assert_raise(IO::WaitReadable) { u1.recvfrom_nonblock(100) }
+ u2.send("", 0, u1.getsockname)
+ assert_nothing_raised("cygwin 1.5.19 has a problem to send an empty UDP packet. [ruby-dev:28915]") {
+ timeout(1) { IO.select [u1] }
+ }
+ mesg, inet_addr = u1.recvfrom_nonblock(100)
+ assert_equal("", mesg)
+ ensure
+ u1.close if u1
+ u2.close if u2
+ end
+
+ def test_udp_recv_nonblock
+ u1 = UDPSocket.new
+ u2 = UDPSocket.new
+ u1.bind("127.0.0.1", 0)
+ assert_raise(IO::WaitReadable) { u1.recv_nonblock(100) }
+ assert_raise(IO::WaitReadable, Errno::EINVAL) { u2.recv_nonblock(100) }
+ u2.send("aaa", 0, u1.getsockname)
+ IO.select [u1]
+ mesg = u1.recv_nonblock(100)
+ assert_equal("aaa", mesg)
+ assert_raise(IO::WaitReadable) { u1.recv_nonblock(100) }
+ u2.send("", 0, u1.getsockname)
+ assert_nothing_raised("cygwin 1.5.19 has a problem to send an empty UDP packet. [ruby-dev:28915]") {
+ timeout(1) { IO.select [u1] }
+ }
+ mesg = u1.recv_nonblock(100)
+ assert_equal("", mesg)
+ ensure
+ u1.close if u1
+ u2.close if u2
+ end
+
+ def test_socket_recvfrom_nonblock
+ s1 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
+ s1.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ s2 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
+ assert_raise(IO::WaitReadable) { s1.recvfrom_nonblock(100) }
+ assert_raise(IO::WaitReadable, Errno::EINVAL) { s2.recvfrom_nonblock(100) }
+ s2.send("aaa", 0, s1.getsockname)
+ IO.select [s1]
+ mesg, sockaddr = s1.recvfrom_nonblock(100)
+ assert_equal("aaa", mesg)
+ port, addr = Socket.unpack_sockaddr_in(sockaddr)
+ s2_port, s2_addr = Socket.unpack_sockaddr_in(s2.getsockname)
+ assert_equal(s2_port, port)
+ ensure
+ s1.close if s1
+ s2.close if s2
+ end
+
+ def tcp_pair
+ serv = TCPServer.new("127.0.0.1", 0)
+ af, port, host, addr = serv.addr
+ c = TCPSocket.new(addr, port)
+ s = serv.accept
+ if block_given?
+ begin
+ yield c, s
+ ensure
+ c.close if !c.closed?
+ s.close if !s.closed?
+ end
+ else
+ return c, s
+ end
+ ensure
+ serv.close if serv && !serv.closed?
+ end
+
+ def udp_pair
+ s1 = UDPSocket.new
+ s1.bind('127.0.0.1', 0)
+ af, port1, host, addr1 = s1.addr
+
+ s2 = UDPSocket.new
+ s2.bind('127.0.0.1', 0)
+ af, port2, host, addr2 = s2.addr
+
+ s1.connect(addr2, port2)
+ s2.connect(addr1, port1)
+
+ if block_given?
+ begin
+ yield s1, s2
+ ensure
+ s1.close if !s1.closed?
+ s2.close if !s2.closed?
+ end
+ else
+ return s1, s2
+ end
+ end
+
+ def test_tcp_recv_nonblock
+ c, s = tcp_pair
+ assert_raise(IO::WaitReadable) { c.recv_nonblock(100) }
+ assert_raise(IO::WaitReadable) { s.recv_nonblock(100) }
+ c.write("abc")
+ IO.select [s]
+ assert_equal("a", s.recv_nonblock(1))
+ assert_equal("bc", s.recv_nonblock(100))
+ assert_raise(IO::WaitReadable) { s.recv_nonblock(100) }
+ ensure
+ c.close if c
+ s.close if s
+ end
+
+ def test_read_nonblock
+ c, s = tcp_pair
+ assert_raise(IO::WaitReadable) { c.read_nonblock(100) }
+ assert_raise(IO::WaitReadable) { s.read_nonblock(100) }
+ c.write("abc")
+ IO.select [s]
+ assert_equal("a", s.read_nonblock(1))
+ assert_equal("bc", s.read_nonblock(100))
+ assert_raise(IO::WaitReadable) { s.read_nonblock(100) }
+ ensure
+ c.close if c
+ s.close if s
+ end
+
+=begin
+ def test_write_nonblock
+ c, s = tcp_pair
+ str = "a" * 10000
+ _, ws, _ = IO.select(nil, [c], nil)
+ assert_equal([c], ws)
+ ret = c.write_nonblock(str)
+ assert_operator(ret, :>, 0)
+ loop {
+ assert_raise(IO::WaitWritable) {
+ loop {
+ ret = c.write_nonblock(str)
+ assert_operator(ret, :>, 0)
+ }
+ }
+ _, ws, _ = IO.select(nil, [c], nil, 0)
+ break if !ws
+ }
+ ensure
+ c.close if c
+ s.close if s
+ end
+=end
+
+ def test_sendmsg_nonblock_error
+ udp_pair {|s1, s2|
+ begin
+ loop {
+ s1.sendmsg_nonblock("a" * 100000)
+ }
+ rescue NotImplementedError, Errno::ENOSYS
+ skip "sendmsg not implemented on this platform."
+ rescue Errno::EMSGSIZE
+ # UDP has 64K limit (if no Jumbograms). No problem.
+ rescue Errno::EWOULDBLOCK
+ assert_kind_of(IO::WaitWritable, $!)
+ end
+ }
+ end
+
+ def test_recvmsg_nonblock_error
+ udp_pair {|s1, s2|
+ begin
+ s1.recvmsg_nonblock(4096)
+ rescue NotImplementedError
+ skip "recvmsg not implemented on this platform."
+ rescue Errno::EWOULDBLOCK
+ assert_kind_of(IO::WaitReadable, $!)
+ end
+ }
+ end
+
+ def test_recv_nonblock_error
+ tcp_pair {|c, s|
+ begin
+ c.recv_nonblock(4096)
+ rescue Errno::EWOULDBLOCK
+ assert_kind_of(IO::WaitReadable, $!)
+ end
+ }
+ end
+
+ def test_connect_nonblock_error
+ serv = TCPServer.new("127.0.0.1", 0)
+ af, port, host, addr = serv.addr
+ c = Socket.new(:INET, :STREAM)
+ begin
+ c.connect_nonblock(Socket.sockaddr_in(port, "127.0.0.1"))
+ rescue Errno::EINPROGRESS
+ assert_kind_of(IO::WaitWritable, $!)
+ end
+ ensure
+ serv.close if serv && !serv.closed?
+ c.close if c && !c.closed?
+ end
+
+ def test_accept_nonblock_error
+ serv = Socket.new(:INET, :STREAM)
+ serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ serv.listen(5)
+ port = serv.local_address.ip_port
+ begin
+ s, _ = serv.accept_nonblock
+ rescue Errno::EWOULDBLOCK
+ assert_kind_of(IO::WaitReadable, $!)
+ end
+ ensure
+ serv.close if serv && !serv.closed?
+ s.close if s && !s.closed?
+ end
+
+end if defined?(Socket)
Added: MacRuby/trunk/test/test-mri/test/socket/test_socket.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/socket/test_socket.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/socket/test_socket.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,409 @@
+begin
+ require "socket"
+ require "tmpdir"
+ require "test/unit"
+rescue LoadError
+end
+
+class TestSocket < Test::Unit::TestCase
+ def test_socket_new
+ s = Socket.new(:INET, :STREAM)
+ assert_kind_of(Socket, s)
+ end
+
+ def test_unpack_sockaddr
+ sockaddr_in = Socket.sockaddr_in(80, "")
+ assert_raise(ArgumentError) { Socket.unpack_sockaddr_un(sockaddr_in) }
+ sockaddr_un = Socket.sockaddr_un("/testdir/s")
+ assert_raise(ArgumentError) { Socket.unpack_sockaddr_in(sockaddr_un) }
+ assert_raise(ArgumentError) { Socket.unpack_sockaddr_in("") }
+ assert_raise(ArgumentError) { Socket.unpack_sockaddr_un("") }
+ end if Socket.respond_to?(:sockaddr_un)
+
+ def test_sysaccept
+ serv = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
+ serv.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ serv.listen 5
+ c = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
+ c.connect(serv.getsockname)
+ fd, peeraddr = serv.sysaccept
+ assert_equal(c.getsockname, peeraddr.to_sockaddr)
+ ensure
+ serv.close if serv
+ c.close if c
+ IO.for_fd(fd).close if fd
+ end
+
+ def test_initialize
+ Socket.open(Socket::AF_INET, Socket::SOCK_STREAM, 0) {|s|
+ s.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ addr = s.getsockname
+ assert_nothing_raised { Socket.unpack_sockaddr_in(addr) }
+ assert_raise(ArgumentError, NoMethodError) { Socket.unpack_sockaddr_un(addr) }
+ }
+ Socket.open("AF_INET", "SOCK_STREAM", 0) {|s|
+ s.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ addr = s.getsockname
+ assert_nothing_raised { Socket.unpack_sockaddr_in(addr) }
+ assert_raise(ArgumentError, NoMethodError) { Socket.unpack_sockaddr_un(addr) }
+ }
+ Socket.open(:AF_INET, :SOCK_STREAM, 0) {|s|
+ s.bind(Socket.sockaddr_in(0, "127.0.0.1"))
+ addr = s.getsockname
+ assert_nothing_raised { Socket.unpack_sockaddr_in(addr) }
+ assert_raise(ArgumentError, NoMethodError) { Socket.unpack_sockaddr_un(addr) }
+ }
+ end
+
+ def test_getaddrinfo
+ # This should not send a DNS query because AF_UNIX.
+ assert_raise(SocketError) { Socket.getaddrinfo("www.kame.net", 80, "AF_UNIX") }
+ end
+
+ def test_getaddrinfo_raises_no_errors_on_port_argument_of_0 # [ruby-core:29427]
+ assert_nothing_raised('[ruby-core:29427]'){ Socket.getaddrinfo('localhost', 0, Socket::AF_INET, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) }
+ assert_nothing_raised('[ruby-core:29427]'){ Socket.getaddrinfo('localhost', '0', Socket::AF_INET, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) }
+ assert_nothing_raised('[ruby-core:29427]'){ Socket.getaddrinfo('localhost', '00', Socket::AF_INET, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) }
+ assert_raise(SocketError, '[ruby-core:29427]'){ Socket.getaddrinfo(nil, nil, Socket::AF_INET, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) }
+ assert_nothing_raised('[ruby-core:29427]'){ TCPServer.open('localhost', 0) {} }
+ end
+
+
+ def test_getnameinfo
+ assert_raise(SocketError) { Socket.getnameinfo(["AF_UNIX", 80, "0.0.0.0"]) }
+ end
+
+ def test_ip_address_list
+ begin
+ list = Socket.ip_address_list
+ rescue NotImplementedError
+ return
+ end
+ list.each {|ai|
+ assert_instance_of(Addrinfo, ai)
+ assert(ai.ip?)
+ }
+ end
+
+ def test_tcp
+ TCPServer.open(0) {|serv|
+ addr = serv.connect_address
+ addr.connect {|s1|
+ s2 = serv.accept
+ begin
+ assert_equal(s2.remote_address.ip_unpack, s1.local_address.ip_unpack)
+ ensure
+ s2.close
+ end
+ }
+ }
+ end
+
+ def random_port
+ # IANA suggests dynamic port for 49152 to 65535
+ # http://www.iana.org/assignments/port-numbers
+ 49152 + rand(65535-49152+1)
+ end
+
+ def test_tcp_server_sockets
+ port = random_port
+ begin
+ sockets = Socket.tcp_server_sockets(port)
+ rescue Errno::EADDRINUSE
+ return # not test failure
+ end
+ begin
+ sockets.each {|s|
+ assert_equal(port, s.local_address.ip_port)
+ }
+ ensure
+ sockets.each {|s|
+ s.close
+ }
+ end
+ end
+
+ def test_tcp_server_sockets_port0
+ sockets = Socket.tcp_server_sockets(0)
+ ports = sockets.map {|s| s.local_address.ip_port }
+ the_port = ports.first
+ ports.each {|port|
+ assert_equal(the_port, port)
+ }
+ ensure
+ if sockets
+ sockets.each {|s|
+ s.close
+ }
+ end
+ end
+
+ if defined? UNIXSocket
+ def test_unix
+ Dir.mktmpdir {|tmpdir|
+ path = "#{tmpdir}/sock"
+ UNIXServer.open(path) {|serv|
+ Socket.unix(path) {|s1|
+ s2 = serv.accept
+ begin
+ s2raddr = s2.remote_address
+ s1laddr = s1.local_address
+ assert(s2raddr.to_sockaddr.empty? ||
+ s1laddr.to_sockaddr.empty? ||
+ s2raddr.unix_path == s1laddr.unix_path)
+ ensure
+ s2.close
+ end
+ }
+ }
+ }
+ end
+
+ def test_unix_server_socket
+ Dir.mktmpdir {|tmpdir|
+ path = "#{tmpdir}/sock"
+ 2.times {
+ serv = Socket.unix_server_socket(path)
+ begin
+ assert_kind_of(Socket, serv)
+ assert(File.socket?(path))
+ assert_equal(path, serv.local_address.unix_path)
+ ensure
+ serv.close
+ end
+ }
+ }
+ end
+
+ def test_accept_loop_with_unix
+ Dir.mktmpdir {|tmpdir|
+ tcp_servers = []
+ clients = []
+ accepted = []
+ begin
+ tcp_servers = Socket.tcp_server_sockets(0)
+ unix_server = Socket.unix_server_socket("#{tmpdir}/sock")
+ tcp_servers.each {|s|
+ addr = s.connect_address
+ assert_nothing_raised("connect to #{addr.inspect}") {
+ clients << addr.connect
+ }
+ }
+ addr = unix_server.connect_address
+ assert_nothing_raised("connect to #{addr.inspect}") {
+ clients << addr.connect
+ }
+ Socket.accept_loop(tcp_servers, unix_server) {|s|
+ accepted << s
+ break if clients.length == accepted.length
+ }
+ assert_equal(clients.length, accepted.length)
+ ensure
+ tcp_servers.each {|s| s.close if !s.closed? }
+ unix_server.close if unix_server && !unix_server.closed?
+ clients.each {|s| s.close if !s.closed? }
+ accepted.each {|s| s.close if !s.closed? }
+ end
+ }
+ end
+ end
+
+ def test_accept_loop
+ servers = []
+ begin
+ servers = Socket.tcp_server_sockets(0)
+ port = servers[0].local_address.ip_port
+ Socket.tcp("localhost", port) {|s1|
+ Socket.accept_loop(servers) {|s2, client_ai|
+ begin
+ assert_equal(s1.local_address.ip_unpack, client_ai.ip_unpack)
+ ensure
+ s2.close
+ end
+ break
+ }
+ }
+ ensure
+ servers.each {|s| s.close if !s.closed? }
+ end
+ end
+
+ def test_accept_loop_multi_port
+ servers = []
+ begin
+ servers = Socket.tcp_server_sockets(0)
+ port = servers[0].local_address.ip_port
+ servers2 = Socket.tcp_server_sockets(0)
+ servers.concat servers2
+ port2 = servers2[0].local_address.ip_port
+
+ Socket.tcp("localhost", port) {|s1|
+ Socket.accept_loop(servers) {|s2, client_ai|
+ begin
+ assert_equal(s1.local_address.ip_unpack, client_ai.ip_unpack)
+ ensure
+ s2.close
+ end
+ break
+ }
+ }
+ Socket.tcp("localhost", port2) {|s1|
+ Socket.accept_loop(servers) {|s2, client_ai|
+ begin
+ assert_equal(s1.local_address.ip_unpack, client_ai.ip_unpack)
+ ensure
+ s2.close
+ end
+ break
+ }
+ }
+ ensure
+ servers.each {|s| s.close if !s.closed? }
+ end
+ end
+
+ def test_udp_server
+ begin
+ ip_addrs = Socket.ip_address_list
+ rescue NotImplementedError
+ skip "Socket.ip_address_list not implemented"
+ end
+
+ Socket.udp_server_sockets(0) {|sockets|
+ famlies = {}
+ sockets.each {|s| famlies[s.local_address.afamily] = true }
+ ip_addrs.reject! {|ai| !famlies[ai.afamily] }
+ skipped = false
+ begin
+ port = sockets.first.local_address.ip_port
+
+ th = Thread.new {
+ Socket.udp_server_loop_on(sockets) {|msg, msg_src|
+ break if msg == "exit"
+ rmsg = Marshal.dump([msg, msg_src.remote_address, msg_src.local_address])
+ msg_src.reply rmsg
+ }
+ }
+
+ ip_addrs.each {|ai|
+ Addrinfo.udp(ai.ip_address, port).connect {|s|
+ msg1 = "<<<#{ai.inspect}>>>"
+ s.sendmsg msg1
+ unless IO.select([s], nil, nil, 10)
+ raise "no response from #{ai.inspect}"
+ end
+ msg2, addr = s.recvmsg
+ msg2, remote_address, local_address = Marshal.load(msg2)
+ assert_equal(msg1, msg2)
+ assert_equal(ai.ip_address, addr.ip_address)
+ }
+ }
+ rescue NotImplementedError, Errno::ENOSYS
+ skipped = true
+ skip "need sendmsg and recvmsg"
+ ensure
+ if th
+ if skipped
+ Thread.kill th unless th.join(10)
+ else
+ Addrinfo.udp("127.0.0.1", port).connect {|s| s.sendmsg "exit" }
+ unless th.join(10)
+ Thread.kill th
+ th.join(10)
+ raise "thread killed"
+ end
+ end
+ end
+ end
+ }
+ end
+
+ def test_linger
+ opt = Socket::Option.linger(true, 0)
+ assert_equal([true, 0], opt.linger)
+ Addrinfo.tcp("127.0.0.1", 0).listen {|serv|
+ serv.local_address.connect {|s1|
+ s2, _ = serv.accept
+ begin
+ s1.setsockopt(opt)
+ s1.close
+ assert_raise(Errno::ECONNRESET) { s2.read }
+ ensure
+ s2.close
+ end
+ }
+ }
+ end
+
+ def test_timestamp
+ return if /linux|freebsd|netbsd|openbsd|solaris|darwin/ !~ RUBY_PLATFORM
+ return if !defined?(Socket::AncillaryData)
+ t1 = Time.now.strftime("%Y-%m-%d")
+ stamp = nil
+ Addrinfo.udp("127.0.0.1", 0).bind {|s1|
+ Addrinfo.udp("127.0.0.1", 0).bind {|s2|
+ s1.setsockopt(:SOCKET, :TIMESTAMP, true)
+ s2.send "a", 0, s1.local_address
+ msg, addr, rflags, stamp = s1.recvmsg
+ assert_equal("a", msg)
+ assert(stamp.cmsg_is?(:SOCKET, :TIMESTAMP))
+ }
+ }
+ t2 = Time.now.strftime("%Y-%m-%d")
+ pat = Regexp.union([t1, t2].uniq)
+ assert_match(pat, stamp.inspect)
+ t = stamp.timestamp
+ assert_match(pat, t.strftime("%Y-%m-%d"))
+ pat = /\.#{"%06d" % t.usec}/
+ assert_match(pat, stamp.inspect)
+ end
+
+ def test_timestampns
+ return if /linux/ !~ RUBY_PLATFORM || !defined?(Socket::SO_TIMESTAMPNS)
+ t1 = Time.now.strftime("%Y-%m-%d")
+ stamp = nil
+ Addrinfo.udp("127.0.0.1", 0).bind {|s1|
+ Addrinfo.udp("127.0.0.1", 0).bind {|s2|
+ begin
+ s1.setsockopt(:SOCKET, :TIMESTAMPNS, true)
+ rescue Errno::ENOPROTOOPT
+ # SO_TIMESTAMPNS is available since Linux 2.6.22
+ return
+ end
+ s2.send "a", 0, s1.local_address
+ msg, addr, rflags, stamp = s1.recvmsg
+ assert_equal("a", msg)
+ assert(stamp.cmsg_is?(:SOCKET, :TIMESTAMPNS))
+ }
+ }
+ t2 = Time.now.strftime("%Y-%m-%d")
+ pat = Regexp.union([t1, t2].uniq)
+ assert_match(pat, stamp.inspect)
+ t = stamp.timestamp
+ assert_match(pat, t.strftime("%Y-%m-%d"))
+ pat = /\.#{"%09d" % t.nsec}/
+ assert_match(pat, stamp.inspect)
+ end
+
+ def test_bintime
+ return if /freebsd/ !~ RUBY_PLATFORM
+ t1 = Time.now.strftime("%Y-%m-%d")
+ stamp = nil
+ Addrinfo.udp("127.0.0.1", 0).bind {|s1|
+ Addrinfo.udp("127.0.0.1", 0).bind {|s2|
+ s1.setsockopt(:SOCKET, :BINTIME, true)
+ s2.send "a", 0, s1.local_address
+ msg, addr, rflags, stamp = s1.recvmsg
+ assert_equal("a", msg)
+ assert(stamp.cmsg_is?(:SOCKET, :BINTIME))
+ }
+ }
+ t2 = Time.now.strftime("%Y-%m-%d")
+ pat = Regexp.union([t1, t2].uniq)
+ assert_match(pat, stamp.inspect)
+ t = stamp.timestamp
+ assert_match(pat, t.strftime("%Y-%m-%d"))
+ assert_equal(stamp.data[-8,8].unpack("Q")[0], t.subsec * 2**64)
+ end
+
+end if defined?(Socket)
Added: MacRuby/trunk/test/test-mri/test/socket/test_sockopt.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/socket/test_sockopt.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/socket/test_sockopt.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,33 @@
+require 'test/unit'
+require 'socket'
+
+class TestSocketOption < Test::Unit::TestCase
+ def test_new
+ data = [1].pack("i")
+ sockopt = Socket::Option.new(:INET, :SOCKET, :KEEPALIVE, data)
+ assert_equal(Socket::AF_INET, sockopt.family)
+ assert_equal(Socket::SOL_SOCKET, sockopt.level)
+ assert_equal(Socket::SO_KEEPALIVE, sockopt.optname)
+ assert_equal(Socket::SO_KEEPALIVE, sockopt.optname)
+ assert_equal(data, sockopt.data)
+ end
+
+ def test_bool
+ opt = Socket::Option.bool(:INET, :SOCKET, :KEEPALIVE, true)
+ assert_equal(1, opt.int)
+ opt = Socket::Option.bool(:INET, :SOCKET, :KEEPALIVE, false)
+ assert_equal(0, opt.int)
+ opt = Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 0)
+ assert_equal(false, opt.bool)
+ opt = Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 1)
+ assert_equal(true, opt.bool)
+ opt = Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 2)
+ assert_equal(true, opt.bool)
+ end
+
+ def test_unpack
+ sockopt = Socket::Option.new(:INET, :SOCKET, :KEEPALIVE, [1].pack("i"))
+ assert_equal([1], sockopt.unpack("i"))
+ assert_equal([1], sockopt.data.unpack("i"))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/socket/test_tcp.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/socket/test_tcp.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/socket/test_tcp.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,42 @@
+begin
+ require "socket"
+ require "test/unit"
+rescue LoadError
+end
+
+
+class TestSocket_TCPSocket < Test::Unit::TestCase
+ def test_recvfrom
+ svr = TCPServer.new("localhost", 0)
+ th = Thread.new {
+ c = svr.accept
+ c.write "foo"
+ c.close
+ }
+ addr = svr.addr
+ sock = TCPSocket.open(addr[3], addr[1])
+ assert_equal(["foo", nil], sock.recvfrom(0x10000))
+ ensure
+ th.kill if th
+ th.join if th
+ end
+
+ def test_encoding
+ svr = TCPServer.new("localhost", 0)
+ th = Thread.new {
+ c = svr.accept
+ c.write "foo\r\n"
+ c.close
+ }
+ addr = svr.addr
+ sock = TCPSocket.open(addr[3], addr[1])
+ assert_equal(true, sock.binmode?)
+ s = sock.gets
+ assert_equal("foo\r\n", s)
+ assert_equal(Encoding.find("ASCII-8BIT"), s.encoding)
+ ensure
+ th.kill if th
+ th.join if th
+ sock.close if sock
+ end
+end if defined?(TCPSocket)
Added: MacRuby/trunk/test/test-mri/test/socket/test_udp.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/socket/test_udp.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/socket/test_udp.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,39 @@
+begin
+ require "socket"
+ require "test/unit"
+rescue LoadError
+end
+
+
+class TestSocket_UDPSocket < Test::Unit::TestCase
+ def test_open
+ assert_nothing_raised { UDPSocket.open {} }
+ assert_nothing_raised { UDPSocket.open(Socket::AF_INET) {} }
+ assert_nothing_raised { UDPSocket.open("AF_INET") {} }
+ assert_nothing_raised { UDPSocket.open(:AF_INET) {} }
+ end
+
+ def test_connect
+ s = UDPSocket.new
+ host = Object.new
+ class << host; self end.send(:define_method, :to_str) {
+ s.close
+ "127.0.0.1"
+ }
+ assert_raise(IOError, "[ruby-dev:25045]") {
+ s.connect(host, 1)
+ }
+ end
+
+ def test_bind
+ s = UDPSocket.new
+ host = Object.new
+ class << host; self end.send(:define_method, :to_str) {
+ s.close
+ "127.0.0.1"
+ }
+ assert_raise(IOError, "[ruby-dev:25057]") {
+ s.bind(host, 2000)
+ }
+ end
+end if defined?(UDPSocket)
Added: MacRuby/trunk/test/test-mri/test/socket/test_unix.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/socket/test_unix.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/socket/test_unix.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,475 @@
+begin
+ require "socket"
+rescue LoadError
+end
+
+require "test/unit"
+require "tempfile"
+require "tmpdir"
+
+class TestSocket_UNIXSocket < Test::Unit::TestCase
+ def test_fd_passing
+ r1, w = IO.pipe
+ s1, s2 = UNIXSocket.pair
+ begin
+ s1.send_io(nil)
+ rescue NotImplementedError
+ assert_raise(NotImplementedError) { s2.recv_io }
+ rescue TypeError
+ s1.send_io(r1)
+ r2 = s2.recv_io
+ assert_equal(r1.stat.ino, r2.stat.ino)
+ assert_not_equal(r1.fileno, r2.fileno)
+ w.syswrite "a"
+ assert_equal("a", r2.sysread(10))
+ ensure
+ s1.close
+ s2.close
+ w.close
+ r1.close
+ r2.close if r2 && !r2.closed?
+ end
+ end
+
+ def test_fd_passing_n
+ io_ary = []
+ return if !defined?(Socket::SCM_RIGHTS)
+ io_ary.concat IO.pipe
+ io_ary.concat IO.pipe
+ io_ary.concat IO.pipe
+ send_io_ary = []
+ io_ary.each {|io|
+ send_io_ary << io
+ UNIXSocket.pair {|s1, s2|
+ begin
+ ret = s1.sendmsg("\0", 0, nil, [Socket::SOL_SOCKET, Socket::SCM_RIGHTS,
+ send_io_ary.map {|io2| io2.fileno }.pack("i!*")])
+ rescue NotImplementedError
+ return
+ end
+ assert_equal(1, ret)
+ ret = s2.recvmsg(:scm_rights=>true)
+ data, srcaddr, flags, *ctls = ret
+ recv_io_ary = []
+ ctls.each {|ctl|
+ next if ctl.level != Socket::SOL_SOCKET || ctl.type != Socket::SCM_RIGHTS
+ recv_io_ary.concat ctl.unix_rights
+ }
+ assert_equal(send_io_ary.length, recv_io_ary.length)
+ send_io_ary.length.times {|i|
+ assert_not_equal(send_io_ary[i].fileno, recv_io_ary[i].fileno)
+ assert(File.identical?(send_io_ary[i], recv_io_ary[i]))
+ }
+ }
+ }
+ ensure
+ io_ary.each {|io| io.close if !io.closed? }
+ end
+
+ def test_fd_passing_n2
+ io_ary = []
+ return if !defined?(Socket::SCM_RIGHTS)
+ return if !defined?(Socket::AncillaryData)
+ io_ary.concat IO.pipe
+ io_ary.concat IO.pipe
+ io_ary.concat IO.pipe
+ send_io_ary = []
+ io_ary.each {|io|
+ send_io_ary << io
+ UNIXSocket.pair {|s1, s2|
+ begin
+ ancdata = Socket::AncillaryData.unix_rights(*send_io_ary)
+ ret = s1.sendmsg("\0", 0, nil, ancdata)
+ rescue NotImplementedError
+ return
+ end
+ assert_equal(1, ret)
+ ret = s2.recvmsg(:scm_rights=>true)
+ data, srcaddr, flags, *ctls = ret
+ recv_io_ary = []
+ ctls.each {|ctl|
+ next if ctl.level != Socket::SOL_SOCKET || ctl.type != Socket::SCM_RIGHTS
+ recv_io_ary.concat ctl.unix_rights
+ }
+ assert_equal(send_io_ary.length, recv_io_ary.length)
+ send_io_ary.length.times {|i|
+ assert_not_equal(send_io_ary[i].fileno, recv_io_ary[i].fileno)
+ assert(File.identical?(send_io_ary[i], recv_io_ary[i]))
+ }
+ }
+ }
+ ensure
+ io_ary.each {|io| io.close if !io.closed? }
+ end
+
+ def test_sendmsg
+ return if !defined?(Socket::SCM_RIGHTS)
+ IO.pipe {|r1, w|
+ UNIXSocket.pair {|s1, s2|
+ begin
+ ret = s1.sendmsg("\0", 0, nil, [Socket::SOL_SOCKET, Socket::SCM_RIGHTS, [r1.fileno].pack("i!")])
+ rescue NotImplementedError
+ return
+ end
+ assert_equal(1, ret)
+ r2 = s2.recv_io
+ begin
+ assert(File.identical?(r1, r2))
+ ensure
+ r2.close
+ end
+ }
+ }
+ end
+
+ def test_sendmsg_ancillarydata_int
+ return if !defined?(Socket::SCM_RIGHTS)
+ return if !defined?(Socket::AncillaryData)
+ IO.pipe {|r1, w|
+ UNIXSocket.pair {|s1, s2|
+ begin
+ ad = Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, r1.fileno)
+ ret = s1.sendmsg("\0", 0, nil, ad)
+ rescue NotImplementedError
+ return
+ end
+ assert_equal(1, ret)
+ r2 = s2.recv_io
+ begin
+ assert(File.identical?(r1, r2))
+ ensure
+ r2.close
+ end
+ }
+ }
+ end
+
+ def test_sendmsg_ancillarydata_unix_rights
+ return if !defined?(Socket::SCM_RIGHTS)
+ return if !defined?(Socket::AncillaryData)
+ IO.pipe {|r1, w|
+ UNIXSocket.pair {|s1, s2|
+ begin
+ ad = Socket::AncillaryData.unix_rights(r1)
+ ret = s1.sendmsg("\0", 0, nil, ad)
+ rescue NotImplementedError
+ return
+ end
+ assert_equal(1, ret)
+ r2 = s2.recv_io
+ begin
+ assert(File.identical?(r1, r2))
+ ensure
+ r2.close
+ end
+ }
+ }
+ end
+
+ def test_recvmsg
+ return if !defined?(Socket::SCM_RIGHTS)
+ return if !defined?(Socket::AncillaryData)
+ IO.pipe {|r1, w|
+ UNIXSocket.pair {|s1, s2|
+ s1.send_io(r1)
+ ret = s2.recvmsg(:scm_rights=>true)
+ data, srcaddr, flags, *ctls = ret
+ assert_equal("\0", data)
+ if flags == nil
+ # struct msghdr is 4.3BSD style (msg_accrights field).
+ assert_instance_of(Array, ctls)
+ assert_equal(0, ctls.length)
+ else
+ # struct msghdr is POSIX/4.4BSD style (msg_control field).
+ assert_equal(0, flags & (Socket::MSG_TRUNC|Socket::MSG_CTRUNC))
+ assert_instance_of(Addrinfo, srcaddr)
+ assert_instance_of(Array, ctls)
+ assert_equal(1, ctls.length)
+ ctl = ctls[0]
+ assert_instance_of(Socket::AncillaryData, ctl)
+ assert_equal(Socket::SOL_SOCKET, ctl.level)
+ assert_equal(Socket::SCM_RIGHTS, ctl.type)
+ assert_instance_of(String, ctl.data)
+ ios = ctl.unix_rights
+ assert_equal(1, ios.length)
+ r2 = ios[0]
+ begin
+ assert(File.identical?(r1, r2))
+ ensure
+ r2.close
+ end
+ end
+ }
+ }
+ end
+
+ def bound_unix_socket(klass)
+ tmpfile = Tempfile.new("testrubysock")
+ path = tmpfile.path
+ tmpfile.close(true)
+ yield klass.new(path), path
+ ensure
+ File.unlink path if path && File.socket?(path)
+ end
+
+ def test_addr
+ bound_unix_socket(UNIXServer) {|serv, path|
+ c = UNIXSocket.new(path)
+ s = serv.accept
+ assert_equal(["AF_UNIX", path], c.peeraddr)
+ assert_equal(["AF_UNIX", ""], c.addr)
+ assert_equal(["AF_UNIX", ""], s.peeraddr)
+ assert_equal(["AF_UNIX", path], s.addr)
+ assert_equal(path, s.path)
+ assert_equal("", c.path)
+ }
+ end
+
+ def test_noname_path
+ s1, s2 = UNIXSocket.pair
+ assert_equal("", s1.path)
+ assert_equal("", s2.path)
+ ensure
+ s1.close
+ s2.close
+ end
+
+ def test_noname_addr
+ s1, s2 = UNIXSocket.pair
+ assert_equal(["AF_UNIX", ""], s1.addr)
+ assert_equal(["AF_UNIX", ""], s2.addr)
+ ensure
+ s1.close
+ s2.close
+ end
+
+ def test_noname_peeraddr
+ s1, s2 = UNIXSocket.pair
+ assert_equal(["AF_UNIX", ""], s1.peeraddr)
+ assert_equal(["AF_UNIX", ""], s2.peeraddr)
+ ensure
+ s1.close
+ s2.close
+ end
+
+ def test_noname_unpack_sockaddr_un
+ s1, s2 = UNIXSocket.pair
+ n = nil
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getsockname) != ""
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getsockname) != ""
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s2.getsockname) != ""
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getpeername) != ""
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s2.getpeername) != ""
+ ensure
+ s1.close
+ s2.close
+ end
+
+ def test_noname_recvfrom
+ s1, s2 = UNIXSocket.pair
+ s2.write("a")
+ assert_equal(["a", ["AF_UNIX", ""]], s1.recvfrom(10))
+ ensure
+ s1.close
+ s2.close
+ end
+
+ def test_noname_recv_nonblock
+ s1, s2 = UNIXSocket.pair
+ s2.write("a")
+ IO.select [s1]
+ assert_equal("a", s1.recv_nonblock(10))
+ ensure
+ s1.close
+ s2.close
+ end
+
+ def test_too_long_path
+ assert_raise(ArgumentError) { Socket.sockaddr_un("a" * 300) }
+ assert_raise(ArgumentError) { UNIXServer.new("a" * 300) }
+ end
+
+ def test_nul
+ assert_raise(ArgumentError) { Socket.sockaddr_un("a\0b") }
+ end
+
+ def test_dgram_pair
+ s1, s2 = UNIXSocket.pair(Socket::SOCK_DGRAM)
+ assert_raise(Errno::EAGAIN) { s1.recv_nonblock(10) }
+ s2.send("", 0)
+ s2.send("haha", 0)
+ s2.send("", 0)
+ s2.send("", 0)
+ assert_equal("", s1.recv(10))
+ assert_equal("haha", s1.recv(10))
+ assert_equal("", s1.recv(10))
+ assert_equal("", s1.recv(10))
+ assert_raise(Errno::EAGAIN) { s1.recv_nonblock(10) }
+ ensure
+ s1.close if s1
+ s2.close if s2
+ end
+
+ def test_epipe # [ruby-dev:34619]
+ s1, s2 = UNIXSocket.pair
+ s1.shutdown(Socket::SHUT_WR)
+ assert_raise(Errno::EPIPE) { s1.write "a" }
+ assert_equal(nil, s2.read(1))
+ s2.write "a"
+ assert_equal("a", s1.read(1))
+ end
+
+ def test_socket_pair_with_block
+ pair = nil
+ ret = Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM, 0) {|s1, s2|
+ pair = [s1, s2]
+ :return_value
+ }
+ assert_equal(:return_value, ret)
+ assert_kind_of(Socket, pair[0])
+ assert_kind_of(Socket, pair[1])
+ end
+
+ def test_unix_socket_pair_with_block
+ pair = nil
+ UNIXSocket.pair {|s1, s2|
+ pair = [s1, s2]
+ }
+ assert_kind_of(UNIXSocket, pair[0])
+ assert_kind_of(UNIXSocket, pair[1])
+ end
+
+ def test_initialize
+ Dir.mktmpdir {|d|
+ Socket.open(Socket::AF_UNIX, Socket::SOCK_STREAM, 0) {|s|
+ s.bind(Socket.pack_sockaddr_un("#{d}/s1"))
+ addr = s.getsockname
+ assert_nothing_raised { Socket.unpack_sockaddr_un(addr) }
+ assert_raise(ArgumentError) { Socket.unpack_sockaddr_in(addr) }
+ }
+ Socket.open("AF_UNIX", "SOCK_STREAM", 0) {|s|
+ s.bind(Socket.pack_sockaddr_un("#{d}/s2"))
+ addr = s.getsockname
+ assert_nothing_raised { Socket.unpack_sockaddr_un(addr) }
+ assert_raise(ArgumentError) { Socket.unpack_sockaddr_in(addr) }
+ }
+ }
+ end
+
+ def test_unix_server_socket
+ Dir.mktmpdir {|d|
+ path = "#{d}/sock"
+ s0 = nil
+ Socket.unix_server_socket(path) {|s|
+ assert_equal(path, s.local_address.unix_path)
+ assert(File.socket?(path))
+ s0 = s
+ }
+ assert(s0.closed?)
+ assert_raise(Errno::ENOENT) { File.stat path }
+ }
+ end
+
+ def test_getcred_ucred
+ return if /linux/ !~ RUBY_PLATFORM
+ Dir.mktmpdir {|d|
+ sockpath = "#{d}/sock"
+ serv = Socket.unix_server_socket(sockpath)
+ c = Socket.unix(sockpath)
+ s, = serv.accept
+ cred = s.getsockopt(:SOCKET, :PEERCRED)
+ inspect = cred.inspect
+ assert_match(/ pid=#{$$} /, inspect)
+ assert_match(/ euid=#{Process.euid} /, inspect)
+ assert_match(/ egid=#{Process.egid} /, inspect)
+ assert_match(/ \(ucred\)/, inspect)
+ }
+ end
+
+ def test_getcred_xucred
+ return if /freebsd|darwin/ !~ RUBY_PLATFORM
+ Dir.mktmpdir {|d|
+ sockpath = "#{d}/sock"
+ serv = Socket.unix_server_socket(sockpath)
+ c = Socket.unix(sockpath)
+ s, = serv.accept
+ cred = s.getsockopt(0, Socket::LOCAL_PEERCRED)
+ inspect = cred.inspect
+ assert_match(/ euid=#{Process.euid} /, inspect)
+ assert_match(/ \(xucred\)/, inspect)
+ }
+ end
+
+ def test_sendcred_ucred
+ return if /linux/ !~ RUBY_PLATFORM
+ Dir.mktmpdir {|d|
+ sockpath = "#{d}/sock"
+ serv = Socket.unix_server_socket(sockpath)
+ c = Socket.unix(sockpath)
+ s, = serv.accept
+ s.setsockopt(:SOCKET, :PASSCRED, 1)
+ c.print "a"
+ msg, cliend_ai, rflags, cred = s.recvmsg
+ inspect = cred.inspect
+ assert_equal("a", msg)
+ assert_match(/ pid=#{$$} /, inspect)
+ assert_match(/ uid=#{Process.uid} /, inspect)
+ assert_match(/ gid=#{Process.gid} /, inspect)
+ assert_match(/ \(ucred\)/, inspect)
+ }
+ end
+
+ def test_sendcred_sockcred
+ return if /netbsd|freebsd/ !~ RUBY_PLATFORM
+ Dir.mktmpdir {|d|
+ sockpath = "#{d}/sock"
+ serv = Socket.unix_server_socket(sockpath)
+ c = Socket.unix(sockpath)
+ s, = serv.accept
+ s.setsockopt(0, Socket::LOCAL_CREDS, 1)
+ c.print "a"
+ msg, cliend_ai, rflags, cred = s.recvmsg
+ assert_equal("a", msg)
+ inspect = cred.inspect
+ assert_match(/ uid=#{Process.uid} /, inspect)
+ assert_match(/ euid=#{Process.euid} /, inspect)
+ assert_match(/ gid=#{Process.gid} /, inspect)
+ assert_match(/ egid=#{Process.egid} /, inspect)
+ assert_match(/ \(sockcred\)/, inspect)
+ }
+ end
+
+ def test_sendcred_cmsgcred
+ return if /freebsd/ !~ RUBY_PLATFORM
+ Dir.mktmpdir {|d|
+ sockpath = "#{d}/sock"
+ serv = Socket.unix_server_socket(sockpath)
+ c = Socket.unix(sockpath)
+ s, = serv.accept
+ c.sendmsg("a", 0, nil, [:SOCKET, Socket::SCM_CREDS, ""])
+ msg, cliend_ai, rflags, cred = s.recvmsg
+ assert_equal("a", msg)
+ inspect = cred.inspect
+ assert_match(/ pid=#{$$} /, inspect)
+ assert_match(/ uid=#{Process.uid} /, inspect)
+ assert_match(/ euid=#{Process.euid} /, inspect)
+ assert_match(/ gid=#{Process.gid} /, inspect)
+ assert_match(/ \(cmsgcred\)/, inspect)
+ }
+ end
+
+ def test_getpeereid
+ Dir.mktmpdir {|d|
+ path = "#{d}/sock"
+ serv = Socket.unix_server_socket(path)
+ c = Socket.unix(path)
+ s, = serv.accept
+ begin
+ assert_equal([Process.euid, Process.egid], c.getpeereid)
+ assert_equal([Process.euid, Process.egid], s.getpeereid)
+ rescue NotImplementedError
+ end
+ }
+ end
+
+end if defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM
Added: MacRuby/trunk/test/test-mri/test/stringio/test_stringio.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/stringio/test_stringio.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/stringio/test_stringio.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,468 @@
+require 'test/unit'
+require 'stringio'
+require_relative '../ruby/ut_eof'
+
+class TestStringIO < Test::Unit::TestCase
+ include TestEOF
+ def open_file(content)
+ f = StringIO.new(content)
+ yield f
+ end
+ alias open_file_rw open_file
+
+ include TestEOF::Seek
+
+ def test_truncate
+ io = StringIO.new("")
+ io.puts "abc"
+ io.truncate(0)
+ io.puts "def"
+ assert_equal("\0\0\0\0def\n", io.string, "[ruby-dev:24190]")
+ assert_raise(Errno::EINVAL) { io.truncate(-1) }
+ io.truncate(10)
+ assert_equal("\0\0\0\0def\n\0\0", io.string)
+ end
+
+ def test_seek_beyond_eof
+ io = StringIO.new
+ n = 100
+ io.seek(n)
+ io.print "last"
+ assert_equal("\0" * n + "last", io.string, "[ruby-dev:24194]")
+ end
+
+ def test_overwrite
+ stringio = StringIO.new
+ responses = ['', 'just another ruby', 'hacker']
+ responses.each do |resp|
+ stringio.puts(resp)
+ stringio.rewind
+ end
+ assert_equal("hacker\nother ruby\n", stringio.string, "[ruby-core:3836]")
+ end
+
+ def test_gets
+ assert_equal(nil, StringIO.new("").gets)
+ assert_equal("\n", StringIO.new("\n").gets)
+ assert_equal("a\n", StringIO.new("a\n").gets)
+ assert_equal("a\n", StringIO.new("a\nb\n").gets)
+ assert_equal("a", StringIO.new("a").gets)
+ assert_equal("a\n", StringIO.new("a\nb").gets)
+ assert_equal("abc\n", StringIO.new("abc\n\ndef\n").gets)
+ assert_equal("abc\n\ndef\n", StringIO.new("abc\n\ndef\n").gets(nil))
+ assert_equal("abc\n\n", StringIO.new("abc\n\ndef\n").gets(""))
+ end
+
+ def test_readlines
+ assert_equal([], StringIO.new("").readlines)
+ assert_equal(["\n"], StringIO.new("\n").readlines)
+ assert_equal(["a\n"], StringIO.new("a\n").readlines)
+ assert_equal(["a\n", "b\n"], StringIO.new("a\nb\n").readlines)
+ assert_equal(["a"], StringIO.new("a").readlines)
+ assert_equal(["a\n", "b"], StringIO.new("a\nb").readlines)
+ assert_equal(["abc\n", "\n", "def\n"], StringIO.new("abc\n\ndef\n").readlines)
+ assert_equal(["abc\n\ndef\n"], StringIO.new("abc\n\ndef\n").readlines(nil), "[ruby-dev:34591]")
+ assert_equal(["abc\n\n", "def\n"], StringIO.new("abc\n\ndef\n").readlines(""))
+ end
+
+ def test_write
+ s = ""
+ f = StringIO.new(s, "w")
+ f.print("foo")
+ f.close
+ assert_equal("foo", s)
+
+ f = StringIO.new(s, File::WRONLY)
+ f.print("bar")
+ f.close
+ assert_equal("bar", s)
+
+ f = StringIO.new(s, "a")
+ o = Object.new
+ def o.to_s; "baz"; end
+ f.print(o)
+ f.close
+ assert_equal("barbaz", s)
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_write_nonblock
+ s = ""
+ f = StringIO.new(s, "w")
+ f.write_nonblock("foo")
+ f.close
+ assert_equal("foo", s)
+
+ f = StringIO.new(s, File::WRONLY)
+ f.write_nonblock("bar")
+ f.close
+ assert_equal("bar", s)
+
+ f = StringIO.new(s, "a")
+ o = Object.new
+ def o.to_s; "baz"; end
+ f.write_nonblock(o)
+ f.close
+ assert_equal("barbaz", s)
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_mode_error
+ f = StringIO.new("", "r")
+ assert_raise(IOError) { f.write("foo") }
+
+ f = StringIO.new("", "w")
+ assert_raise(IOError) { f.read }
+
+ assert_raise(Errno::EACCES) { StringIO.new("".freeze, "w") }
+ s = ""
+ f = StringIO.new(s, "w")
+ s.freeze
+ assert_raise(IOError) { f.write("foo") }
+
+ assert_raise(IOError) { StringIO.allocate.read }
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_open
+ s = ""
+ StringIO.open("foo") {|f| s = f.read }
+ assert_equal("foo", s)
+ end
+
+ def test_isatty
+ assert_equal(false, StringIO.new("").isatty)
+ end
+
+ def test_fsync
+ assert_equal(0, StringIO.new("").fsync)
+ end
+
+ def test_sync
+ assert_equal(true, StringIO.new("").sync)
+ assert_equal(false, StringIO.new("").sync = false)
+ end
+
+ def test_set_fcntl
+ assert_raise(NotImplementedError) { StringIO.new("").fcntl }
+ end
+
+ def test_close
+ f = StringIO.new("")
+ f.close
+ assert_raise(IOError) { f.close }
+
+ f = StringIO.new("")
+ f.close_read
+ f.close_write
+ assert_raise(IOError) { f.close }
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_close_read
+ f = StringIO.new("")
+ f.close_read
+ assert_raise(IOError) { f.read }
+ assert_raise(IOError) { f.close_read }
+ f.close
+
+ f = StringIO.new("", "w")
+ assert_raise(IOError) { f.close_read }
+ f.close
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_close_write
+ f = StringIO.new("")
+ f.close_write
+ assert_raise(IOError) { f.write("foo") }
+ assert_raise(IOError) { f.close_write }
+ f.close
+
+ f = StringIO.new("", "r")
+ assert_raise(IOError) { f.close_write }
+ f.close
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_closed
+ f = StringIO.new("")
+ assert_equal(false, f.closed?)
+ f.close
+ assert_equal(true, f.closed?)
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_closed_read
+ f = StringIO.new("")
+ assert_equal(false, f.closed_read?)
+ f.close_write
+ assert_equal(false, f.closed_read?)
+ f.close_read
+ assert_equal(true, f.closed_read?)
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_closed_write
+ f = StringIO.new("")
+ assert_equal(false, f.closed_write?)
+ f.close_read
+ assert_equal(false, f.closed_write?)
+ f.close_write
+ assert_equal(true, f.closed_write?)
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_dup
+ f1 = StringIO.new("1234")
+ assert_equal("1", f1.getc)
+ f2 = f1.dup
+ assert_equal("2", f2.getc)
+ assert_equal("3", f1.getc)
+ assert_equal("4", f2.getc)
+ assert_equal(nil, f1.getc)
+ assert_equal(true, f2.eof?)
+ f1.close
+ assert_equal(true, f2.closed?)
+ ensure
+ f1.close unless f1.closed?
+ f2.close unless f2.closed?
+ end
+
+ def test_lineno
+ f = StringIO.new("foo\nbar\nbaz\n")
+ assert_equal([0, "foo\n"], [f.lineno, f.gets])
+ assert_equal([1, "bar\n"], [f.lineno, f.gets])
+ f.lineno = 1000
+ assert_equal([1000, "baz\n"], [f.lineno, f.gets])
+ assert_equal([1001, nil], [f.lineno, f.gets])
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_pos
+ f = StringIO.new("foo\nbar\nbaz\n")
+ assert_equal([0, "foo\n"], [f.pos, f.gets])
+ assert_equal([4, "bar\n"], [f.pos, f.gets])
+ assert_raise(Errno::EINVAL) { f.pos = -1 }
+ f.pos = 1
+ assert_equal([1, "oo\n"], [f.pos, f.gets])
+ assert_equal([4, "bar\n"], [f.pos, f.gets])
+ assert_equal([8, "baz\n"], [f.pos, f.gets])
+ assert_equal([12, nil], [f.pos, f.gets])
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_reopen
+ f = StringIO.new("foo\nbar\nbaz\n")
+ assert_equal("foo\n", f.gets)
+ f.reopen("qux\nquux\nquuux\n")
+ assert_equal("qux\n", f.gets)
+
+ f2 = StringIO.new("")
+ f2.reopen(f)
+ assert_equal("quux\n", f2.gets)
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_seek
+ f = StringIO.new("1234")
+ assert_raise(Errno::EINVAL) { f.seek(-1) }
+ f.seek(-1, 2)
+ assert_equal("4", f.getc)
+ assert_raise(Errno::EINVAL) { f.seek(1, 3) }
+ f.close
+ assert_raise(IOError) { f.seek(0) }
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_each_byte
+ f = StringIO.new("1234")
+ a = []
+ f.each_byte {|c| a << c }
+ assert_equal(%w(1 2 3 4).map {|c| c.ord }, a)
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_getbyte
+ f = StringIO.new("1234")
+ assert_equal("1".ord, f.getbyte)
+ assert_equal("2".ord, f.getbyte)
+ assert_equal("3".ord, f.getbyte)
+ assert_equal("4".ord, f.getbyte)
+ assert_equal(nil, f.getbyte)
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_ungetbyte
+ s = "foo\nbar\n"
+ t = StringIO.new(s, "r")
+ t.ungetbyte(0x41)
+ assert_equal(0x41, t.getbyte)
+ t.ungetbyte("qux")
+ assert_equal("quxfoo\n", t.gets)
+ t.set_encoding("utf-8")
+ t.ungetbyte(0x89)
+ t.ungetbyte(0x8e)
+ t.ungetbyte("\xe7")
+ t.ungetbyte("\xe7\xb4\x85")
+ assert_equal("\u7d05\u7389bar\n", t.gets)
+ end
+
+ def test_ungetc
+ s = "1234"
+ f = StringIO.new(s, "r")
+ assert_nothing_raised { f.ungetc("x") }
+ assert_equal("x", f.getc) # bug? -> it's a feature from 1.9.
+ assert_equal("1", f.getc)
+
+ s = "1234"
+ f = StringIO.new(s, "r")
+ assert_equal("1", f.getc)
+ f.ungetc("y".ord)
+ assert_equal("y", f.getc)
+ assert_equal("2", f.getc)
+ ensure
+ f.close unless f.closed?
+ end
+
+ def test_readchar
+ f = StringIO.new("1234")
+ a = ""
+ assert_raise(EOFError) { loop { a << f.readchar } }
+ assert_equal("1234", a)
+ end
+
+ def test_readbyte
+ f = StringIO.new("1234")
+ a = []
+ assert_raise(EOFError) { loop { a << f.readbyte } }
+ assert_equal("1234".unpack("C*"), a)
+ end
+
+ def test_each_char
+ f = StringIO.new("1234")
+ assert_equal(%w(1 2 3 4), f.each_char.to_a)
+ end
+
+ def test_each_codepoint
+ f = StringIO.new("1234")
+ assert_equal([49, 50, 51, 52], f.each_codepoint.to_a)
+ end
+
+ def test_gets2
+ f = StringIO.new("foo\nbar\nbaz\n")
+ assert_equal("fo", f.gets(2))
+
+ o = Object.new
+ def o.to_str; "z"; end
+ assert_equal("o\nbar\nbaz", f.gets(o))
+
+ f = StringIO.new("foo\nbar\nbaz\n")
+ assert_equal("foo\nbar\nbaz", f.gets("az"))
+ f = StringIO.new("a" * 10000 + "zz!")
+ assert_equal("a" * 10000 + "zz", f.gets("zz"))
+ f = StringIO.new("a" * 10000 + "zz!")
+ assert_equal("a" * 10000 + "zz!", f.gets("zzz"))
+ end
+
+ def test_each
+ f = StringIO.new("foo\nbar\nbaz\n")
+ assert_equal(["foo\n", "bar\n", "baz\n"], f.each.to_a)
+ end
+
+ def test_putc
+ s = ""
+ f = StringIO.new(s, "w")
+ f.putc("1")
+ f.putc("2")
+ f.putc("3")
+ f.close
+ assert_equal("123", s)
+
+ s = "foo"
+ f = StringIO.new(s, "a")
+ f.putc("1")
+ f.putc("2")
+ f.putc("3")
+ f.close
+ assert_equal("foo123", s)
+ end
+
+ def test_read
+ f = StringIO.new("\u3042\u3044")
+ assert_raise(ArgumentError) { f.read(-1) }
+ assert_raise(ArgumentError) { f.read(1, 2, 3) }
+ assert_equal("\u3042\u3044", f.read)
+ f.rewind
+ assert_equal("\u3042\u3044".force_encoding(Encoding::ASCII_8BIT), f.read(f.size))
+ end
+
+ def test_readpartial
+ f = StringIO.new("\u3042\u3044")
+ assert_raise(ArgumentError) { f.readpartial(-1) }
+ assert_raise(ArgumentError) { f.readpartial(1, 2, 3) }
+ assert_equal("\u3042\u3044", f.readpartial)
+ f.rewind
+ assert_equal("\u3042\u3044".force_encoding(Encoding::ASCII_8BIT), f.readpartial(f.size))
+ end
+
+ def test_read_nonblock
+ f = StringIO.new("\u3042\u3044")
+ assert_raise(ArgumentError) { f.read_nonblock(-1) }
+ assert_raise(ArgumentError) { f.read_nonblock(1, 2, 3) }
+ assert_equal("\u3042\u3044", f.read_nonblock)
+ f.rewind
+ assert_equal("\u3042\u3044".force_encoding(Encoding::ASCII_8BIT), f.read_nonblock(f.size))
+ end
+
+ def test_size
+ f = StringIO.new("1234")
+ assert_equal(4, f.size)
+ end
+
+ # This test is should in ruby/test_method.rb
+ # However this test depends on stringio library,
+ # we write it here.
+ class C < StringIO
+ alias old_init initialize
+ attr_reader :foo
+ def initialize
+ @foo = :ok
+ old_init
+ end
+ end
+
+ def test_method
+ assert_equal(:ok, C.new.foo, 'Bug #632 [ruby-core:19282]')
+ end
+
+ def test_ungetc_pos
+ b = '\\b00010001 \\B00010001 \\b1 \\B1 \\b000100011'
+ s = StringIO.new( b )
+ expected_pos = 0
+ while n = s.getc
+ assert_equal( expected_pos + 1, s.pos )
+
+ s.ungetc( n )
+ assert_equal( expected_pos, s.pos )
+ assert_equal( n, s.getc )
+
+ expected_pos += 1
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/strscan/test_stringscanner.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/strscan/test_stringscanner.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/strscan/test_stringscanner.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,693 @@
+#
+# test/strscan/test_stringscanner.rb
+#
+
+require 'strscan'
+require 'test/unit'
+
+class TestStringScanner < Test::Unit::TestCase
+ def test_s_new
+ s = StringScanner.new('test string')
+ assert_instance_of StringScanner, s
+ assert_equal false, s.eos?
+ assert_equal false, s.tainted?
+
+ str = 'test string'
+ str.taint
+ s = StringScanner.new(str, false)
+ assert_instance_of StringScanner, s
+ assert_equal false, s.eos?
+ assert_same str, s.string
+ assert_equal true, s.string.tainted?
+
+ str = 'test string'
+ str.taint
+ s = StringScanner.new(str)
+ assert_equal true, s.string.tainted?
+ end
+
+ UNINIT_ERROR = ArgumentError
+
+ def test_s_allocate
+ s = StringScanner.allocate
+ assert_equal '#<StringScanner (uninitialized)>', s.inspect.sub(/StringScanner_C/, 'StringScanner')
+ assert_raise(UNINIT_ERROR) { s.eos? }
+ assert_raise(UNINIT_ERROR) { s.scan(/a/) }
+ s.string = 'test'
+ assert_equal '#<StringScanner 0/4 @ "test">', s.inspect.sub(/StringScanner_C/, 'StringScanner')
+ assert_nothing_raised(UNINIT_ERROR) { s.eos? }
+ assert_equal false, s.eos?
+ end
+
+ def test_s_mustc
+ assert_nothing_raised(NotImplementedError) {
+ StringScanner.must_C_version
+ }
+ end
+
+ def test_dup
+ s = StringScanner.new('test string')
+ d = s.dup
+ assert_equal s.inspect, d.inspect
+ assert_equal s.string, d.string
+ assert_equal s.pos, d.pos
+ assert_equal s.matched?, d.matched?
+ assert_equal s.eos?, d.eos?
+
+ s = StringScanner.new('test string')
+ s.scan(/test/)
+ d = s.dup
+ assert_equal s.inspect, d.inspect
+ assert_equal s.string, d.string
+ assert_equal s.pos, d.pos
+ assert_equal s.matched?, d.matched?
+ assert_equal s.eos?, d.eos?
+
+ s = StringScanner.new('test string')
+ s.scan(/test/)
+ s.scan(/NOT MATCH/)
+ d = s.dup
+ assert_equal s.inspect, d.inspect
+ assert_equal s.string, d.string
+ assert_equal s.pos, d.pos
+ assert_equal s.matched?, d.matched?
+ assert_equal s.eos?, d.eos?
+
+ s = StringScanner.new('test string')
+ s.terminate
+ d = s.dup
+ assert_equal s.inspect, d.inspect
+ assert_equal s.string, d.string
+ assert_equal s.pos, d.pos
+ assert_equal s.matched?, d.matched?
+ assert_equal s.eos?, d.eos?
+ end
+
+ def test_const_Version
+ assert_instance_of String, StringScanner::Version
+ assert_equal true, StringScanner::Version.frozen?
+ end
+
+ def test_const_Id
+ assert_instance_of String, StringScanner::Id
+ assert_equal true, StringScanner::Id.frozen?
+ end
+
+ def test_inspect
+ str = 'test string'
+ str.taint
+ s = StringScanner.new(str, false)
+ assert_instance_of String, s.inspect
+ assert_equal s.inspect, s.inspect
+ assert_equal '#<StringScanner 0/11 @ "test ...">', s.inspect.sub(/StringScanner_C/, 'StringScanner')
+ s.get_byte
+ assert_equal '#<StringScanner 1/11 "t" @ "est s...">', s.inspect.sub(/StringScanner_C/, 'StringScanner')
+ assert_equal true, s.inspect.tainted?
+
+ s = StringScanner.new("\n")
+ assert_equal '#<StringScanner 0/1 @ "\n">', s.inspect
+ end
+
+ def test_eos?
+ s = StringScanner.new('test string')
+ assert_equal false, s.eos?
+ assert_equal false, s.eos?
+ s.scan(/\w+/)
+ assert_equal false, s.eos?
+ assert_equal false, s.eos?
+ s.scan(/\s+/)
+ s.scan(/\w+/)
+ assert_equal true, s.eos?
+ assert_equal true, s.eos?
+ s.scan(/\w+/)
+ assert_equal true, s.eos?
+
+ s = StringScanner.new('test')
+ s.scan(/te/)
+ s.string.replace ''
+ assert_equal true, s.eos?
+ end
+
+ def test_bol?
+ s = StringScanner.new("a\nbbb\n\ncccc\nddd\r\neee")
+ assert_equal true, s.bol?
+ assert_equal true, s.bol?
+ s.scan(/a/)
+ assert_equal false, s.bol?
+ assert_equal false, s.bol?
+ s.scan(/\n/)
+ assert_equal true, s.bol?
+ s.scan(/b/)
+ assert_equal false, s.bol?
+ s.scan(/b/)
+ assert_equal false, s.bol?
+ s.scan(/b/)
+ assert_equal false, s.bol?
+ s.scan(/\n/)
+ assert_equal true, s.bol?
+ s.unscan
+ assert_equal false, s.bol?
+ s.scan(/\n/)
+ s.scan(/\n/)
+ assert_equal true, s.bol?
+ s.scan(/c+\n/)
+ assert_equal true, s.bol?
+ s.scan(/d+\r\n/)
+ assert_equal true, s.bol?
+ s.scan(/e+/)
+ assert_equal false, s.bol?
+ end
+
+ def test_string
+ s = StringScanner.new('test')
+ assert_equal 'test', s.string
+ s.string = 'a'
+ assert_equal 'a', s.string
+ s.scan(/a/)
+ s.string = 'b'
+ assert_equal 0, s.pos
+ end
+
+ def test_string_set_is_equal
+ name = 'tenderlove'
+
+ s = StringScanner.new(name)
+ assert_equal name.object_id, s.string.object_id
+
+ s.string = name
+ assert_equal name.object_id, s.string.object_id
+ end
+
+ def test_string_append
+ s = StringScanner.new('tender')
+ s << 'love'
+ assert_equal 'tenderlove', s.string
+
+ s.string = 'tender'
+ s << 'love'
+ assert_equal 'tenderlove', s.string
+ end
+
+ def test_pos
+ s = StringScanner.new('test string')
+ assert_equal 0, s.pos
+ s.get_byte
+ assert_equal 1, s.pos
+ s.get_byte
+ assert_equal 2, s.pos
+ s.terminate
+ assert_equal 11, s.pos
+ end
+
+ def test_concat
+ s = StringScanner.new('a')
+ s.scan(/a/)
+ s.concat 'b'
+ assert_equal false, s.eos?
+ assert_equal 'b', s.scan(/b/)
+ assert_equal true, s.eos?
+ s.concat 'c'
+ assert_equal false, s.eos?
+ assert_equal 'c', s.scan(/c/)
+ assert_equal true, s.eos?
+ end
+
+ def test_scan
+ s = StringScanner.new('stra strb strc', true)
+ tmp = s.scan(/\w+/)
+ assert_equal 'stra', tmp
+ assert_equal false, tmp.tainted?
+
+ tmp = s.scan(/\s+/)
+ assert_equal ' ', tmp
+ assert_equal false, tmp.tainted?
+
+ assert_equal 'strb', s.scan(/\w+/)
+ assert_equal ' ', s.scan(/\s+/)
+
+ tmp = s.scan(/\w+/)
+ assert_equal 'strc', tmp
+ assert_equal false, tmp.tainted?
+
+ assert_nil s.scan(/\w+/)
+ assert_nil s.scan(/\w+/)
+
+
+ str = 'stra strb strc'
+ str.taint
+ s = StringScanner.new(str, false)
+ tmp = s.scan(/\w+/)
+ assert_equal 'stra', tmp
+ assert_equal true, tmp.tainted?
+
+ tmp = s.scan(/\s+/)
+ assert_equal ' ', tmp
+ assert_equal true, tmp.tainted?
+
+ assert_equal 'strb', s.scan(/\w+/)
+ assert_equal ' ', s.scan(/\s+/)
+
+ tmp = s.scan(/\w+/)
+ assert_equal 'strc', tmp
+ assert_equal true, tmp.tainted?
+
+ assert_nil s.scan(/\w+/)
+ assert_nil s.scan(/\w+/)
+
+ s = StringScanner.new('test')
+ s.scan(/te/)
+ # This assumes #string does not duplicate string,
+ # but it is implementation specific issue.
+ # DO NOT RELY ON THIS FEATURE.
+ s.string.replace ''
+ # unspecified: assert_equal 2, s.pos
+ assert_equal nil, s.scan(/test/)
+
+ # [ruby-bugs:4361]
+ s = StringScanner.new("")
+ assert_equal "", s.scan(//)
+ assert_equal "", s.scan(//)
+ end
+
+ def test_skip
+ s = StringScanner.new('stra strb strc', true)
+ assert_equal 4, s.skip(/\w+/)
+ assert_equal 1, s.skip(/\s+/)
+ assert_equal 4, s.skip(/\w+/)
+ assert_equal 1, s.skip(/\s+/)
+ assert_equal 4, s.skip(/\w+/)
+ assert_nil s.skip(/\w+/)
+ assert_nil s.skip(/\s+/)
+ assert_equal true, s.eos?
+
+ s = StringScanner.new('test')
+ s.scan(/te/)
+ s.string.replace ''
+ assert_equal nil, s.skip(/./)
+
+ # [ruby-bugs:4361]
+ s = StringScanner.new("")
+ assert_equal 0, s.skip(//)
+ assert_equal 0, s.skip(//)
+ end
+
+ def test_getch
+ s = StringScanner.new('abcde')
+ assert_equal 'a', s.getch
+ assert_equal 'b', s.getch
+ assert_equal 'c', s.getch
+ assert_equal 'd', s.getch
+ assert_equal 'e', s.getch
+ assert_nil s.getch
+
+ str = 'abc'
+ str.taint
+ s = StringScanner.new(str)
+ assert_equal true, s.getch.tainted?
+ assert_equal true, s.getch.tainted?
+ assert_equal true, s.getch.tainted?
+ assert_nil s.getch
+
+ s = StringScanner.new("\244\242".force_encoding("euc-jp"))
+ assert_equal "\244\242".force_encoding("euc-jp"), s.getch
+ assert_nil s.getch
+
+ s = StringScanner.new('test')
+ s.scan(/te/)
+ s.string.replace ''
+ assert_equal nil, s.getch
+ end
+
+ def test_get_byte
+ s = StringScanner.new('abcde')
+ assert_equal 'a', s.get_byte
+ assert_equal 'b', s.get_byte
+ assert_equal 'c', s.get_byte
+ assert_equal 'd', s.get_byte
+ assert_equal 'e', s.get_byte
+ assert_nil s.get_byte
+ assert_nil s.get_byte
+
+ str = 'abc'
+ str.taint
+ s = StringScanner.new(str)
+ assert_equal true, s.get_byte.tainted?
+ assert_equal true, s.get_byte.tainted?
+ assert_equal true, s.get_byte.tainted?
+ assert_nil s.get_byte
+
+ s = StringScanner.new("\244\242".force_encoding("euc-jp"))
+ assert_equal "\244".force_encoding("euc-jp"), s.get_byte
+ assert_equal "\242".force_encoding("euc-jp"), s.get_byte
+ assert_nil s.get_byte
+
+ s = StringScanner.new('test')
+ s.scan(/te/)
+ s.string.replace ''
+ assert_equal nil, s.get_byte
+ end
+
+ def test_matched
+ s = StringScanner.new('stra strb strc')
+ s.scan(/\w+/)
+ assert_equal 'stra', s.matched
+ assert_equal false, s.matched.tainted?
+ s.scan(/\s+/)
+ assert_equal ' ', s.matched
+ s.scan(/\w+/)
+ assert_equal 'strb', s.matched
+ s.scan(/\s+/)
+ assert_equal ' ', s.matched
+ s.scan(/\w+/)
+ assert_equal 'strc', s.matched
+ s.scan(/\w+/)
+ assert_nil s.matched
+ s.getch
+ assert_nil s.matched
+
+ s = StringScanner.new('stra strb strc')
+ s.getch
+ assert_equal 's', s.matched
+ assert_equal false, s.matched.tainted?
+ s.get_byte
+ assert_equal 't', s.matched
+ assert_equal 't', s.matched
+ assert_equal false, s.matched.tainted?
+
+ str = 'test'
+ str.taint
+ s = StringScanner.new(str)
+ s.scan(/\w+/)
+ assert_equal true, s.matched.tainted?
+ assert_equal true, s.matched.tainted?
+ end
+
+ def test_AREF
+ s = StringScanner.new('stra strb strc')
+
+ s.scan(/\w+/)
+ assert_nil s[-2]
+ assert_equal 'stra', s[-1]
+ assert_equal 'stra', s[0]
+ assert_nil s[1]
+
+ assert_equal false, s[-1].tainted?
+ assert_equal false, s[0].tainted?
+
+ s.skip(/\s+/)
+ assert_nil s[-2]
+ assert_equal ' ', s[-1]
+ assert_equal ' ', s[0]
+ assert_nil s[1]
+
+ s.scan(/(s)t(r)b/)
+ assert_nil s[-100]
+ assert_nil s[-4]
+ assert_equal 'strb', s[-3]
+ assert_equal 's', s[-2]
+ assert_equal 'r', s[-1]
+ assert_equal 'strb', s[0]
+ assert_equal 's', s[1]
+ assert_equal 'r', s[2]
+ assert_nil s[3]
+ assert_nil s[100]
+
+ s.scan(/\s+/)
+
+ s.getch
+ assert_nil s[-2]
+ assert_equal 's', s[-1]
+ assert_equal 's', s[0]
+ assert_nil s[1]
+
+ s.get_byte
+ assert_nil s[-2]
+ assert_equal 't', s[-1]
+ assert_equal 't', s[0]
+ assert_nil s[1]
+
+ s.scan(/.*/)
+ s.scan(/./)
+ assert_nil s[0]
+ assert_nil s[0]
+
+
+ s = StringScanner.new("\244\242".force_encoding("euc-jp"))
+ s.getch
+ assert_equal "\244\242".force_encoding("euc-jp"), s[0]
+
+ str = 'test'
+ str.taint
+ s = StringScanner.new(str)
+ s.scan(/(t)(e)(s)(t)/)
+ assert_equal true, s[0].tainted?
+ assert_equal true, s[1].tainted?
+ assert_equal true, s[2].tainted?
+ assert_equal true, s[3].tainted?
+ assert_equal true, s[4].tainted?
+ end
+
+ def test_pre_match
+ s = StringScanner.new('a b c d e')
+ s.scan(/\w/)
+ assert_equal '', s.pre_match
+ assert_equal false, s.pre_match.tainted?
+ s.skip(/\s/)
+ assert_equal 'a', s.pre_match
+ assert_equal false, s.pre_match.tainted?
+ s.scan(/\w/)
+ assert_equal 'a ', s.pre_match
+ s.scan_until(/c/)
+ assert_equal 'a b ', s.pre_match
+ s.getch
+ assert_equal 'a b c', s.pre_match
+ s.get_byte
+ assert_equal 'a b c ', s.pre_match
+ s.get_byte
+ assert_equal 'a b c d', s.pre_match
+ s.scan(/never match/)
+ assert_nil s.pre_match
+
+ str = 'test string'
+ str.taint
+ s = StringScanner.new(str)
+ s.scan(/\w+/)
+ assert_equal true, s.pre_match.tainted?
+ s.scan(/\s+/)
+ assert_equal true, s.pre_match.tainted?
+ s.scan(/\w+/)
+ assert_equal true, s.pre_match.tainted?
+ end
+
+ def test_post_match
+ s = StringScanner.new('a b c d e')
+ s.scan(/\w/)
+ assert_equal ' b c d e', s.post_match
+ s.skip(/\s/)
+ assert_equal 'b c d e', s.post_match
+ s.scan(/\w/)
+ assert_equal ' c d e', s.post_match
+ s.scan_until(/c/)
+ assert_equal ' d e', s.post_match
+ s.getch
+ assert_equal 'd e', s.post_match
+ s.get_byte
+ assert_equal ' e', s.post_match
+ s.get_byte
+ assert_equal 'e', s.post_match
+ s.scan(/never match/)
+ assert_nil s.post_match
+ s.scan(/./)
+ assert_equal '', s.post_match
+ s.scan(/./)
+ assert_nil s.post_match
+
+ str = 'test string'
+ str.taint
+ s = StringScanner.new(str)
+ s.scan(/\w+/)
+ assert_equal true, s.post_match.tainted?
+ s.scan(/\s+/)
+ assert_equal true, s.post_match.tainted?
+ s.scan(/\w+/)
+ assert_equal true, s.post_match.tainted?
+ end
+
+ def test_terminate
+ s = StringScanner.new('ssss')
+ s.getch
+ s.terminate
+ assert_equal true, s.eos?
+ s.terminate
+ assert_equal true, s.eos?
+ end
+
+ def test_reset
+ s = StringScanner.new('ssss')
+ s.getch
+ s.reset
+ assert_equal 0, s.pos
+ s.scan(/\w+/)
+ s.reset
+ assert_equal 0, s.pos
+ s.reset
+ assert_equal 0, s.pos
+ end
+
+ def test_matched_size
+ s = StringScanner.new('test string')
+ assert_nil s.matched_size
+ s.scan(/test/)
+ assert_equal 4, s.matched_size
+ assert_equal 4, s.matched_size
+ s.scan(//)
+ assert_equal 0, s.matched_size
+ s.scan(/x/)
+ assert_nil s.matched_size
+ assert_nil s.matched_size
+ s.terminate
+ assert_nil s.matched_size
+
+ s = StringScanner.new('test string')
+ assert_nil s.matched_size
+ s.scan(/test/)
+ assert_equal 4, s.matched_size
+ s.terminate
+ assert_nil s.matched_size
+ end
+
+ def test_encoding
+ ss = StringScanner.new("\xA1\xA2".force_encoding("euc-jp"))
+ assert_equal(Encoding::EUC_JP, ss.scan(/./e).encoding)
+ end
+
+ def test_generic_regexp
+ ss = StringScanner.new("\xA1\xA2".force_encoding("euc-jp"))
+ t = ss.scan(/./)
+ assert_equal("\xa1\xa2".force_encoding("euc-jp"), t)
+ end
+
+ def test_set_pos
+ s = StringScanner.new("test string")
+ s.pos = 7
+ assert_equal("ring", s.rest)
+ end
+
+ def test_match_p
+ s = StringScanner.new("test string")
+ assert_equal(4, s.match?(/\w+/))
+ assert_equal(4, s.match?(/\w+/))
+ assert_equal(nil, s.match?(/\s+/))
+ end
+
+ def test_check
+ s = StringScanner.new("Foo Bar Baz")
+ assert_equal("Foo", s.check(/Foo/))
+ assert_equal(0, s.pos)
+ assert_equal("Foo", s.matched)
+ assert_equal(nil, s.check(/Bar/))
+ assert_equal(nil, s.matched)
+ end
+
+ def test_scan_full
+ s = StringScanner.new("Foo Bar Baz")
+ assert_equal(4, s.scan_full(/Foo /, false, false))
+ assert_equal(0, s.pos)
+ assert_equal(nil, s.scan_full(/Baz/, false, false))
+ assert_equal("Foo ", s.scan_full(/Foo /, false, true))
+ assert_equal(0, s.pos)
+ assert_equal(nil, s.scan_full(/Baz/, false, false))
+ assert_equal(4, s.scan_full(/Foo /, true, false))
+ assert_equal(4, s.pos)
+ assert_equal(nil, s.scan_full(/Baz /, false, false))
+ assert_equal("Bar ", s.scan_full(/Bar /, true, true))
+ assert_equal(8, s.pos)
+ assert_equal(nil, s.scan_full(/az/, false, false))
+ end
+
+ def test_exist_p
+ s = StringScanner.new("test string")
+ assert_equal(3, s.exist?(/s/))
+ assert_equal(0, s.pos)
+ s.scan(/test/)
+ assert_equal(2, s.exist?(/s/))
+ assert_equal(4, s.pos)
+ assert_equal(nil, s.exist?(/e/))
+ end
+
+ def test_skip_until
+ s = StringScanner.new("Foo Bar Baz")
+ assert_equal(3, s.skip_until(/Foo/))
+ assert_equal(3, s.pos)
+ assert_equal(4, s.skip_until(/Bar/))
+ assert_equal(7, s.pos)
+ assert_equal(nil, s.skip_until(/Qux/))
+ end
+
+ def test_check_until
+ s = StringScanner.new("Foo Bar Baz")
+ assert_equal("Foo", s.check_until(/Foo/))
+ assert_equal(0, s.pos)
+ assert_equal("Foo Bar", s.check_until(/Bar/))
+ assert_equal(0, s.pos)
+ assert_equal(nil, s.check_until(/Qux/))
+ end
+
+ def test_search_full
+ s = StringScanner.new("Foo Bar Baz")
+ assert_equal(8, s.search_full(/Bar /, false, false))
+ assert_equal(0, s.pos)
+ assert_equal("Foo Bar ", s.search_full(/Bar /, false, true))
+ assert_equal(0, s.pos)
+ assert_equal(8, s.search_full(/Bar /, true, false))
+ assert_equal(8, s.pos)
+ assert_equal("Baz", s.search_full(/az/, true, true))
+ assert_equal(11, s.pos)
+ end
+
+ def test_peek
+ s = StringScanner.new("test string")
+ assert_equal("test st", s.peek(7))
+ assert_equal("test st", s.peek(7))
+ s.scan(/test/)
+ assert_equal(" stri", s.peek(5))
+ assert_equal(" string", s.peek(10))
+ s.scan(/ string/)
+ assert_equal("", s.peek(10))
+ end
+
+ def test_unscan
+ s = StringScanner.new('test string')
+ assert_equal("test", s.scan(/\w+/))
+ s.unscan
+ assert_equal("te", s.scan(/../))
+ assert_equal(nil, s.scan(/\d/))
+ assert_raise(ScanError) { s.unscan }
+ end
+
+ def test_rest
+ s = StringScanner.new('test string')
+ assert_equal("test string", s.rest)
+ s.scan(/test/)
+ assert_equal(" string", s.rest)
+ s.scan(/ string/)
+ assert_equal("", s.rest)
+ s.scan(/ string/)
+ end
+
+ def test_rest_size
+ s = StringScanner.new('test string')
+ assert_equal(11, s.rest_size)
+ s.scan(/test/)
+ assert_equal(7, s.rest_size)
+ s.scan(/ string/)
+ assert_equal(0, s.rest_size)
+ s.scan(/ string/)
+ end
+
+ def test_inspect2
+ s = StringScanner.new('test string test')
+ s.scan(/test strin/)
+ assert_equal('#<StringScanner 10/16 "...strin" @ "g tes...">', s.inspect)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_array.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_array.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_array.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,18 @@
+require 'test/unit'
+require 'yaml'
+
+module Syck
+ class TestArray < Test::Unit::TestCase
+ def setup
+ @list = [{ :a => 'b' }, 'foo']
+ end
+
+ def test_to_yaml
+ assert_equal @list, YAML.load(@list.to_yaml)
+ end
+
+ def test_dump
+ assert_equal @list, YAML.load(YAML.dump(@list))
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_boolean.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_boolean.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_boolean.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,37 @@
+require 'test/unit'
+require 'yaml'
+
+module Syck
+ ###
+ # Test booleans from YAML spec:
+ # http://yaml.org/type/bool.html
+ class TestBoolean < Test::Unit::TestCase
+ %w{ yes Yes YES true True TRUE on On ON }.each do |truth|
+ define_method(:"test_#{truth}") do
+ assert_equal true, YAML.load("--- #{truth}")
+ end
+ end
+
+ %w{ no No NO false False FALSE off Off OFF }.each do |truth|
+ define_method(:"test_#{truth}") do
+ assert_equal false, YAML.load("--- #{truth}")
+ end
+ end
+
+ ###
+ # YAML spec says "y" and "Y" may be used as true, but Syck treats them
+ # as literal strings
+ def test_y
+ assert_equal "y", YAML.load("--- y")
+ assert_equal "Y", YAML.load("--- Y")
+ end
+
+ ###
+ # YAML spec says "n" and "N" may be used as false, but Syck treats them
+ # as literal strings
+ def test_n
+ assert_equal "n", YAML.load("--- n")
+ assert_equal "N", YAML.load("--- N")
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_class.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_class.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_class.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,18 @@
+require 'test/unit'
+require 'yaml'
+
+module Syck
+ class TestClass < Test::Unit::TestCase
+ def test_to_yaml
+ assert_raises(::TypeError) do
+ TestClass.to_yaml
+ end
+ end
+
+ def test_dump
+ assert_raises(::TypeError) do
+ YAML.dump TestClass
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_engine_manager.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_engine_manager.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_engine_manager.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,3 @@
+require 'test/unit'
+require 'yaml'
+
Added: MacRuby/trunk/test/test-mri/test/syck/test_exception.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_exception.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_exception.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,46 @@
+require 'test/unit'
+require 'yaml'
+
+module Syck
+ class TestException < Test::Unit::TestCase
+ class Wups < Exception
+ attr_reader :foo, :bar
+ def initialize *args
+ super
+ @foo = 1
+ @bar = 2
+ end
+ end
+
+ def setup
+ @wups = Wups.new
+ end
+
+ def test_to_yaml
+ w = YAML.load(@wups.to_yaml)
+ assert_equal @wups, w
+ assert_equal 1, w.foo
+ assert_equal 2, w.bar
+ end
+
+ def test_dump
+ w = YAML.load(@wups.to_yaml)
+ assert_equal @wups, w
+ assert_equal 1, w.foo
+ assert_equal 2, w.bar
+ end
+
+ def test_to_yaml_properties
+ class << @wups
+ def to_yaml_properties
+ [:@foo]
+ end
+ end
+
+ w = YAML.load(YAML.dump(@wups))
+ assert_equal @wups, w
+ assert_equal 1, w.foo
+ assert_nil w.bar
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_hash.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_hash.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_hash.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,29 @@
+require 'test/unit'
+require 'yaml'
+
+module Syck
+ class TestHash < Test::Unit::TestCase
+ def setup
+ @hash = { :a => 'b' }
+ end
+
+ def test_to_yaml
+ assert_equal @hash, YAML.load(@hash.to_yaml)
+ end
+
+ def test_dump
+ assert_equal @hash, YAML.load(YAML.dump(@hash))
+ end
+
+ def test_ref_append
+ hash = YAML.load(<<-eoyml)
+---
+foo: &foo
+ hello: world
+bar:
+ <<: *foo
+eoyml
+ assert_equal({"foo"=>{"hello"=>"world"}, "bar"=>{"hello"=>"world"}}, hash)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_null.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_null.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_null.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,20 @@
+require 'test/unit'
+require 'yaml'
+
+module Syck
+ ###
+ # Test null from YAML spec:
+ # http://yaml.org/type/null.html
+ class TestNull < Test::Unit::TestCase
+ def test_null_list
+ assert_equal [nil] * 5, YAML.load(<<-eoyml)
+---
+- ~
+- null
+-
+- Null
+- NULL
+ eoyml
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_omap.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_omap.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_omap.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,56 @@
+require 'test/unit'
+require 'yaml'
+
+module Syck
+ class TestOmap < Test::Unit::TestCase
+ def test_keys
+ map = YAML::Omap.new
+ map['foo'] = 'bar'
+ assert_equal 'bar', map['foo']
+ end
+
+ def test_order
+ map = YAML::Omap.new
+ map['a'] = 'b'
+ map['b'] = 'c'
+ assert_equal [%w{a b}, %w{b c}], map.to_a
+ end
+
+ def test_square
+ list = [["a", "b"], ["b", "c"]]
+ map = YAML::Omap[*list.flatten]
+ assert_equal list, map.to_a
+ assert_equal 'b', map['a']
+ assert_equal 'c', map['b']
+ end
+
+ def test_to_yaml
+ map = YAML::Omap['a', 'b', 'c', 'd']
+ yaml = map.to_yaml
+ assert_match('!omap', yaml)
+ assert_match('- a: b', yaml)
+ assert_match('- c: d', yaml)
+ end
+
+ def test_round_trip
+ list = [["a", "b"], ["b", "c"]]
+ map = YAML::Omap[*list.flatten]
+ loaded = YAML.load(YAML.dump(map))
+
+ assert_equal map, loaded
+ assert_equal list, loaded.to_a
+ end
+
+ ###
+ # FIXME: Syck should also support !!omap as shorthand
+ def test_load
+ list = [["a", "b"], ["c", "d"]]
+ map = YAML.load(<<-eoyml)
+--- !omap
+- a: b
+- c: d
+ eoyml
+ assert_equal list, map.to_a
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_set.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_set.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_set.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,31 @@
+require 'test/unit'
+require 'yaml'
+
+module Syck
+ class TestSet < Test::Unit::TestCase
+ def setup
+ @set = YAML::Set.new
+ @set['foo'] = 'bar'
+ @set['bar'] = 'baz'
+ end
+
+ def test_to_yaml
+ assert_match(/!set/, @set.to_yaml)
+ end
+
+ def test_roundtrip
+ assert_equal(@set, YAML.load(YAML.dump(@set)))
+ end
+
+ ###
+ # FIXME: Syck should also support !!set as shorthand
+ def test_load_from_yaml
+ loaded = YAML.load(<<-eoyml)
+--- !set
+foo: bar
+bar: baz
+ eoyml
+ assert_equal(@set, loaded)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_string.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_string.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_string.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,45 @@
+require 'test/unit'
+require 'yaml'
+
+module Syck
+ class TestString < Test::Unit::TestCase
+ def test_binary_string_null
+ string = "\x00"
+ yml = YAML.dump string
+ assert_match(/binary/, yml)
+ assert_equal string, YAML.load(yml)
+ end
+
+ def test_binary_string
+ string = binary_string
+ yml = YAML.dump string
+ assert_match(/binary/, yml)
+ assert_equal string, YAML.load(yml)
+ end
+
+ def test_non_binary_string
+ string = binary_string(0.29)
+ yml = YAML.dump string
+ refute_match(/binary/, yml)
+ assert_equal string, YAML.load(yml)
+ end
+
+ def test_string_with_ivars
+ food = "is delicious"
+ ivar = "on rock and roll"
+ food.instance_variable_set(:@we_built_this_city, ivar)
+
+ str = YAML.load YAML.dump food
+ assert_equal ivar, food.instance_variable_get(:@we_built_this_city)
+ end
+
+ def binary_string percentage = 0.31, length = 100
+ string = ''
+ (percentage * length).to_i.times do |i|
+ string << "\b"
+ end
+ string << 'a' * (length - string.length)
+ string
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_struct.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_struct.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_struct.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,42 @@
+require 'test/unit'
+require 'yaml'
+
+class StructWithIvar < Struct.new(:foo)
+ attr_reader :bar
+ def initialize *args
+ super
+ @bar = 'hello'
+ end
+end
+
+module Syck
+ class TestStruct < MiniTest::Unit::TestCase
+ def setup
+ @current_engine = YAML::ENGINE.yamler
+ YAML::ENGINE.yamler = 'syck'
+ end
+
+ def teardown
+ YAML::ENGINE.yamler = @current_engine
+ end
+
+ def test_roundtrip
+ thing = StructWithIvar.new('bar')
+ struct = YAML.load(YAML.dump(thing))
+
+ assert_equal 'hello', struct.bar
+ assert_equal 'bar', struct.foo
+ end
+
+ def test_load
+ obj = YAML.load(<<-eoyml)
+--- !ruby/struct:StructWithIvar
+foo: bar
+ at bar: hello
+eoyml
+
+ assert_equal 'hello', obj.bar
+ assert_equal 'bar', obj.foo
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_symbol.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_symbol.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_symbol.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,22 @@
+require 'test/unit'
+require 'yaml'
+
+module Syck
+ class TestSymbol < Test::Unit::TestCase
+ def test_to_yaml
+ assert_equal :a, YAML.load(:a.to_yaml)
+ end
+
+ def test_dump
+ assert_equal :a, YAML.load(YAML.dump(:a))
+ end
+
+ def test_stringy
+ assert_equal :"1", YAML.load(YAML.dump(:"1"))
+ end
+
+ def test_load_quoted
+ assert_equal :"1", YAML.load("--- :'1'\n")
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_yaml.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_yaml.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_yaml.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,1408 @@
+# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4; indent-tabs-mode: t -*-
+# vim:sw=4:ts=4
+# $Id: test_yaml.rb 27591 2010-05-02 23:15:08Z nobu $
+#
+require 'test/unit'
+require 'yaml'
+require 'syck/ypath'
+
+# [ruby-core:01946]
+module YAML_Tests
+ StructTest = Struct::new( :c )
+end
+
+module Syck
+class YAML_Unit_Tests < Test::Unit::TestCase
+ def setup
+ @current_engine = YAML::ENGINE.yamler
+ YAML::ENGINE.yamler = 'syck'
+ end
+
+ def teardown
+ YAML::ENGINE.yamler = @current_engine
+ end
+
+ #
+ # Convert between YAML and the object to verify correct parsing and
+ # emitting
+ #
+ def assert_to_yaml( obj, yaml, msg = nil )
+ assert_equal( obj, YAML::load( yaml ), msg )
+ assert_equal( obj, YAML::parse( yaml ).transform, msg )
+ assert_equal( obj, YAML::load( obj.to_yaml ), msg )
+ assert_equal( obj, YAML::parse( obj.to_yaml ).transform, msg )
+ assert_equal( obj, YAML::load(
+ obj.to_yaml( :UseVersion => true, :UseHeader => true, :SortKeys => true )
+ ), msg )
+ end
+
+ #
+ # Test parser only
+ #
+ def assert_parse_only( obj, yaml, msg = nil )
+ assert_equal( obj, YAML::load( yaml ), msg )
+ assert_equal( obj, YAML::parse( yaml ).transform, msg )
+ end
+
+ def assert_cycle( obj, msg = nil )
+ assert_equal( obj, YAML::load( obj.to_yaml ), msg )
+ end
+
+ def assert_path_segments( path, segments, msg = nil )
+ YAML::YPath.each_path( path ) { |choice|
+ assert_equal( choice.segments, segments.shift, msg )
+ }
+ assert_equal( segments.length, 0, "Some segments leftover: #{ segments.inspect }" )
+ end
+
+ #
+ # Make a time with the time zone
+ #
+ def mktime( year, mon, day, hour, min, sec, usec, zone = "Z" )
+ usec = Rational(usec.to_s) * 1000000
+ val = Time::utc( year.to_i, mon.to_i, day.to_i, hour.to_i, min.to_i, sec.to_i, usec )
+ if zone != "Z"
+ hour = zone[0,3].to_i * 3600
+ min = zone[3,2].to_i * 60
+ ofs = (hour + min)
+ val = Time.at( val.tv_sec - ofs, val.tv_nsec / 1000.0 )
+ end
+ return val
+ end
+
+ #
+ # Tests modified from 00basic.t in YAML.pm
+ #
+ def test_basic_map
+ # Simple map
+ assert_parse_only(
+ { 'one' => 'foo', 'three' => 'baz', 'two' => 'bar' }, <<EOY
+one: foo
+two: bar
+three: baz
+EOY
+ )
+ end
+
+ def test_basic_strings
+ # Common string types
+ assert_cycle("x")
+ assert_cycle(":x")
+ assert_cycle(":")
+ assert_parse_only(
+ { 1 => 'simple string', 2 => 42, 3 => '1 Single Quoted String',
+ 4 => 'YAML\'s Double "Quoted" String', 5 => "A block\n with several\n lines.\n",
+ 6 => "A \"chomped\" block", 7 => "A folded\n string\n", 8 => ": started string" },
+ <<EOY
+1: simple string
+2: 42
+3: '1 Single Quoted String'
+4: "YAML's Double \\\"Quoted\\\" String"
+5: |
+ A block
+ with several
+ lines.
+6: |-
+ A "chomped" block
+7: >
+ A
+ folded
+ string
+8: ": started string"
+EOY
+ )
+ end
+
+ #
+ # Test the specification examples
+ # - Many examples have been changes because of whitespace problems that
+ # caused the two to be inequivalent, or keys to be sorted wrong
+ #
+
+ def test_spec_simple_implicit_sequence
+ # Simple implicit sequence
+ assert_to_yaml(
+ [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ], <<EOY
+- Mark McGwire
+- Sammy Sosa
+- Ken Griffey
+EOY
+ )
+ end
+
+ def test_spec_simple_implicit_map
+ # Simple implicit map
+ assert_to_yaml(
+ { 'hr' => 65, 'avg' => 0.278, 'rbi' => 147 }, <<EOY
+avg: 0.278
+hr: 65
+rbi: 147
+EOY
+ )
+ end
+
+ def test_spec_simple_map_with_nested_sequences
+ # Simple mapping with nested sequences
+ assert_to_yaml(
+ { 'american' =>
+ [ 'Boston Red Sox', 'Detroit Tigers', 'New York Yankees' ],
+ 'national' =>
+ [ 'New York Mets', 'Chicago Cubs', 'Atlanta Braves' ] }, <<EOY
+american:
+ - Boston Red Sox
+ - Detroit Tigers
+ - New York Yankees
+national:
+ - New York Mets
+ - Chicago Cubs
+ - Atlanta Braves
+EOY
+ )
+ end
+
+ def test_spec_simple_sequence_with_nested_map
+ # Simple sequence with nested map
+ assert_to_yaml(
+ [
+ {'name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278},
+ {'name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288}
+ ], <<EOY
+-
+ avg: 0.278
+ hr: 65
+ name: Mark McGwire
+-
+ avg: 0.288
+ hr: 63
+ name: Sammy Sosa
+EOY
+ )
+ end
+
+ def test_spec_sequence_of_sequences
+ # Simple sequence with inline sequences
+ assert_parse_only(
+ [
+ [ 'name', 'hr', 'avg' ],
+ [ 'Mark McGwire', 65, 0.278 ],
+ [ 'Sammy Sosa', 63, 0.288 ]
+ ], <<EOY
+- [ name , hr , avg ]
+- [ Mark McGwire , 65 , 0.278 ]
+- [ Sammy Sosa , 63 , 0.288 ]
+EOY
+ )
+ end
+
+ def test_spec_mapping_of_mappings
+ # Simple map with inline maps
+ assert_parse_only(
+ { 'Mark McGwire' =>
+ { 'hr' => 65, 'avg' => 0.278 },
+ 'Sammy Sosa' =>
+ { 'hr' => 63, 'avg' => 0.288 }
+ }, <<EOY
+Mark McGwire: {hr: 65, avg: 0.278}
+Sammy Sosa: {hr: 63,
+ avg: 0.288}
+EOY
+ )
+ end
+
+ def test_ambiguous_comments
+ # [ruby-talk:88012]
+ assert_to_yaml( "Call the method #dave", <<EOY )
+--- "Call the method #dave"
+EOY
+ end
+
+ def test_spec_nested_comments
+ # Map and sequences with comments
+ assert_parse_only(
+ { 'hr' => [ 'Mark McGwire', 'Sammy Sosa' ],
+ 'rbi' => [ 'Sammy Sosa', 'Ken Griffey' ] }, <<EOY
+hr: # 1998 hr ranking
+ - Mark McGwire
+ - Sammy Sosa
+rbi:
+ # 1998 rbi ranking
+ - Sammy Sosa
+ - Ken Griffey
+EOY
+ )
+ end
+
+ def test_spec_anchors_and_aliases
+ # Anchors and aliases
+ assert_parse_only(
+ { 'hr' =>
+ [ 'Mark McGwire', 'Sammy Sosa' ],
+ 'rbi' =>
+ [ 'Sammy Sosa', 'Ken Griffey' ] }, <<EOY
+hr:
+ - Mark McGwire
+ # Name "Sammy Sosa" scalar SS
+ - &SS Sammy Sosa
+rbi:
+ # So it can be referenced later.
+ - *SS
+ - Ken Griffey
+EOY
+ )
+
+ assert_to_yaml(
+ [{"arrival"=>"EDI", "departure"=>"LAX", "fareref"=>"DOGMA", "currency"=>"GBP"}, {"arrival"=>"MEL", "departure"=>"SYD", "fareref"=>"MADF", "currency"=>"AUD"}, {"arrival"=>"MCO", "departure"=>"JFK", "fareref"=>"DFSF", "currency"=>"USD"}], <<EOY
+ -
+ &F fareref: DOGMA
+ &C currency: GBP
+ &D departure: LAX
+ &A arrival: EDI
+ - { *F: MADF, *C: AUD, *D: SYD, *A: MEL }
+ - { *F: DFSF, *C: USD, *D: JFK, *A: MCO }
+EOY
+ )
+
+ assert_to_yaml(
+ {"ALIASES"=>["fareref", "currency", "departure", "arrival"], "FARES"=>[{"arrival"=>"EDI", "departure"=>"LAX", "fareref"=>"DOGMA", "currency"=>"GBP"}, {"arrival"=>"MEL", "departure"=>"SYD", "fareref"=>"MADF", "currency"=>"AUD"}, {"arrival"=>"MCO", "departure"=>"JFK", "fareref"=>"DFSF", "currency"=>"USD"}]}, <<EOY
+---
+ALIASES: [&f fareref, &c currency, &d departure, &a arrival]
+FARES:
+- *f: DOGMA
+ *c: GBP
+ *d: LAX
+ *a: EDI
+
+- *f: MADF
+ *c: AUD
+ *d: SYD
+ *a: MEL
+
+- *f: DFSF
+ *c: USD
+ *d: JFK
+ *a: MCO
+
+EOY
+ )
+
+ end
+
+ def test_spec_mapping_between_sequences
+ # Complex key #1
+ dj = Date.new( 2001, 7, 23 )
+ assert_parse_only(
+ { [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ],
+ [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ] }, <<EOY
+? # PLAY SCHEDULE
+ - Detroit Tigers
+ - Chicago Cubs
+:
+ - 2001-07-23
+
+? [ New York Yankees,
+ Atlanta Braves ]
+: [ 2001-07-02, 2001-08-12,
+ 2001-08-14 ]
+EOY
+ )
+
+ # Complex key #2
+ assert_parse_only(
+ { [ 'New York Yankees', 'Atlanta Braves' ] =>
+ [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ),
+ Date.new( 2001, 8, 14 ) ],
+ [ 'Detroit Tigers', 'Chicago Cubs' ] =>
+ [ Date.new( 2001, 7, 23 ) ]
+ }, <<EOY
+?
+ - New York Yankees
+ - Atlanta Braves
+:
+ - 2001-07-02
+ - 2001-08-12
+ - 2001-08-14
+?
+ - Detroit Tigers
+ - Chicago Cubs
+:
+ - 2001-07-23
+EOY
+ )
+ end
+
+ def test_spec_sequence_key_shortcut
+ # Shortcut sequence map
+ assert_parse_only(
+ { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ),
+ 'bill-to' => 'Chris Dumars', 'product' =>
+ [ { 'item' => 'Super Hoop', 'quantity' => 1 },
+ { 'item' => 'Basketball', 'quantity' => 4 },
+ { 'item' => 'Big Shoes', 'quantity' => 1 } ] }, <<EOY
+invoice: 34843
+date : 2001-01-23
+bill-to: Chris Dumars
+product:
+ - item : Super Hoop
+ quantity: 1
+ - item : Basketball
+ quantity: 4
+ - item : Big Shoes
+ quantity: 1
+EOY
+ )
+ end
+
+ def test_spec_sequence_in_sequence_shortcut
+ # Seq-in-seq
+ assert_parse_only( [ [ [ 'one', 'two', 'three' ] ] ], <<EOY )
+- - - one
+ - two
+ - three
+EOY
+ end
+
+ def test_spec_sequence_shortcuts
+ # Sequence shortcuts combined
+ assert_parse_only(
+[
+ [
+ [ [ 'one' ] ],
+ [ 'two', 'three' ],
+ { 'four' => nil },
+ [ { 'five' => [ 'six' ] } ],
+ [ 'seven' ]
+ ],
+ [ 'eight', 'nine' ]
+], <<EOY )
+- - - - one
+ - - two
+ - three
+ - four:
+ - - five:
+ - six
+ - - seven
+- - eight
+ - nine
+EOY
+ end
+
+ def test_spec_single_literal
+ # Literal scalar block
+ assert_parse_only( [ "\\/|\\/|\n/ | |_\n" ], <<EOY )
+- |
+ \\/|\\/|
+ / | |_
+EOY
+ end
+
+ def test_spec_single_folded
+ # Folded scalar block
+ assert_parse_only(
+ [ "Mark McGwire's year was crippled by a knee injury.\n" ], <<EOY
+- >
+ Mark McGwire\'s
+ year was crippled
+ by a knee injury.
+EOY
+ )
+ end
+
+ def test_spec_preserve_indent
+ # Preserve indented spaces
+ assert_parse_only(
+ "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n", <<EOY
+--- >
+ Sammy Sosa completed another
+ fine season with great stats.
+
+ 63 Home Runs
+ 0.288 Batting Average
+
+ What a year!
+EOY
+ )
+ end
+
+ def test_spec_indentation_determines_scope
+ assert_parse_only(
+ { 'name' => 'Mark McGwire', 'accomplishment' => "Mark set a major league home run record in 1998.\n",
+ 'stats' => "65 Home Runs\n0.278 Batting Average\n" }, <<EOY
+name: Mark McGwire
+accomplishment: >
+ Mark set a major league
+ home run record in 1998.
+stats: |
+ 65 Home Runs
+ 0.278 Batting Average
+EOY
+ )
+ end
+
+ #
+ # Reports from N.Easterly & J.Trupiano : Tests with patch from daz
+ # [ruby-core:23006] [Bug #1311] http://redmine.ruby-lang.org/issues/show/1311
+ #
+ def test_scan_scalar_nl
+ bug1311 = '[ruby-core:23006]'
+ assert_cycle(<<EoY, bug1311)
+
+ a
+b
+EoY
+ assert_cycle(<<EoY, bug1311)
+
+ a
+ b
+c
+EoY
+ assert_cycle(<<EoY, bug1311)
+
+ a
+ b
+EoY
+ assert_cycle(" Do I work?\nNo indent", bug1311)
+ assert_cycle(" \n Do I work?\nNo indent", bug1311)
+ assert_cycle("\n Do I work?\nNo indent", bug1311)
+ assert_cycle("\n", bug1311)
+ assert_cycle("\n\n", bug1311)
+ assert_cycle("\r\n", bug1311)
+
+ assert_cycle <<EoY, '[ruby-core:28777]'
+ Domain name:
+ ckgteam.co.uk
+
+ Registrant:
+ James Gregory
+
+ Registrant type:
+ UK Individual
+
+ Registrant's address:
+ The registrant is a non-trading individual who has opted to have their
+ address omitted from the WHOIS service.
+
+ Registrar:
+ Webfusion Ltd t/a 123-Reg.co.uk [Tag = 123-REG]
+ URL: http://www.123-reg.co.uk
+
+ Relevant dates:
+ Registered on: 16-Nov-2009
+ Renewal date: 16-Nov-2011
+ Last updated: 25-Nov-2009
+
+ Registration status:
+ Registered until renewal date.
+
+ Name servers:
+ ns1.slicehost.net
+ ns2.slicehost.net
+ ns3.slicehost.net
+
+ WHOIS lookup made at 11:56:46 19-Mar-2010
+
+--
+This WHOIS information is provided for free by Nominet UK the central registry
+for .uk domain names. This information and the .uk WHOIS are:
+
+ Copyright Nominet UK 1996 - 2010.
+
+You may not access the .uk WHOIS or use any data from it except as permitted
+by the terms of use available in full at http://www.nominet.org.uk/whois, which
+includes restrictions on: (A) use of the data for advertising, or its
+repackaging, recompilation, redistribution or reuse (B) obscuring, removing
+or hiding any or all of this notice and (C) exceeding query rate or volume
+limits. The data is provided on an 'as-is' basis and may lag behind the
+register. Access may be withdrawn or restricted at any time.
+EoY
+
+ end
+
+ def test_spec_multiline_scalars
+ # Multiline flow scalars
+ assert_parse_only(
+ { 'plain' => 'This unquoted scalar spans many lines.',
+ 'quoted' => "So does this quoted scalar.\n" }, <<EOY
+plain: This unquoted
+ scalar spans
+ many lines.
+quoted: "\\
+ So does this quoted
+ scalar.\\n"
+EOY
+ )
+ end
+
+ def test_spec_type_int
+ assert_parse_only(
+ { 'canonical' => 12345, 'decimal' => 12345, 'octal' => '014'.oct, 'hexadecimal' => '0xC'.hex }, <<EOY
+canonical: 12345
+decimal: +12,345
+octal: 014
+hexadecimal: 0xC
+EOY
+ )
+ assert_parse_only(
+ { 'canonical' => 685230, 'decimal' => 685230, 'octal' => 02472256, 'hexadecimal' => 0x0A74AE, 'sexagesimal' => 685230 }, <<EOY)
+canonical: 685230
+decimal: +685,230
+octal: 02472256
+hexadecimal: 0x0A,74,AE
+sexagesimal: 190:20:30
+EOY
+ end
+
+ def test_spec_type_float
+ assert_parse_only(
+ { 'canonical' => 1230.15, 'exponential' => 1230.15, 'fixed' => 1230.15,
+ 'negative infinity' => -1.0/0.0 }, <<EOY)
+canonical: 1.23015e+3
+exponential: 12.3015e+02
+fixed: 1,230.15
+negative infinity: -.inf
+EOY
+ nan = YAML::load( <<EOY )
+not a number: .NaN
+EOY
+ assert( nan['not a number'].nan? )
+ end
+
+ def test_spec_type_misc
+ assert_parse_only(
+ { nil => nil, true => true, false => false, 'string' => '12345' }, <<EOY
+null: ~
+true: yes
+false: no
+string: '12345'
+EOY
+ )
+ end
+
+ def test_spec_complex_invoice
+ # Complex invoice type
+ id001 = { 'given' => 'Chris', 'family' => 'Dumars', 'address' =>
+ { 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak',
+ 'state' => 'MI', 'postal' => 48046 } }
+ assert_parse_only(
+ { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ),
+ 'bill-to' => id001, 'ship-to' => id001, 'product' =>
+ [ { 'sku' => 'BL394D', 'quantity' => 4,
+ 'description' => 'Basketball', 'price' => 450.00 },
+ { 'sku' => 'BL4438H', 'quantity' => 1,
+ 'description' => 'Super Hoop', 'price' => 2392.00 } ],
+ 'tax' => 251.42, 'total' => 4443.52,
+ 'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n" }, <<EOY
+invoice: 34843
+date : 2001-01-23
+bill-to: &id001
+ given : Chris
+ family : !str Dumars
+ address:
+ lines: |
+ 458 Walkman Dr.
+ Suite #292
+ city : Royal Oak
+ state : MI
+ postal : 48046
+ship-to: *id001
+product:
+ - !map
+ sku : BL394D
+ quantity : 4
+ description : Basketball
+ price : 450.00
+ - sku : BL4438H
+ quantity : 1
+ description : Super Hoop
+ price : 2392.00
+tax : 251.42
+total: 4443.52
+comments: >
+ Late afternoon is best.
+ Backup contact is Nancy
+ Billsmer @ 338-4338.
+EOY
+ )
+ end
+
+ def test_spec_log_file
+ doc_ct = 0
+ YAML::load_documents( <<EOY
+---
+Time: 2001-11-23 15:01:42 -05:00
+User: ed
+Warning: >
+ This is an error message
+ for the log file
+---
+Time: 2001-11-23 15:02:31 -05:00
+User: ed
+Warning: >
+ A slightly different error
+ message.
+---
+Date: 2001-11-23 15:03:17 -05:00
+User: ed
+Fatal: >
+ Unknown variable "bar"
+Stack:
+ - file: TopClass.py
+ line: 23
+ code: |
+ x = MoreObject("345\\n")
+ - file: MoreClass.py
+ line: 58
+ code: |-
+ foo = bar
+EOY
+ ) { |doc|
+ case doc_ct
+ when 0
+ assert_equal( doc, { 'Time' => mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ),
+ 'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } )
+ when 1
+ assert_equal( doc, { 'Time' => mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ),
+ 'User' => 'ed', 'Warning' => "A slightly different error message.\n" } )
+ when 2
+ assert_equal( doc, { 'Date' => mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ),
+ 'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n",
+ 'Stack' => [
+ { 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" },
+ { 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } )
+ end
+ doc_ct += 1
+ }
+ assert_equal( doc_ct, 3 )
+ end
+
+ def test_spec_root_fold
+ y = YAML::load( <<EOY
+--- >
+This YAML stream contains a single text value.
+The next stream is a log file - a sequence of
+log entries. Adding an entry to the log is a
+simple matter of appending it at the end.
+EOY
+ )
+ assert_equal( y, "This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n" )
+ end
+
+ def test_spec_root_mapping
+ y = YAML::load( <<EOY
+# This stream is an example of a top-level mapping.
+invoice : 34843
+date : 2001-01-23
+total : 4443.52
+EOY
+ )
+ assert_equal( y, { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ), 'total' => 4443.52 } )
+ end
+
+ def test_spec_oneline_docs
+ doc_ct = 0
+ YAML::load_documents( <<EOY
+# The following is a sequence of three documents.
+# The first contains an empty mapping, the second
+# an empty sequence, and the last an empty string.
+--- {}
+--- [ ]
+--- ''
+EOY
+ ) { |doc|
+ case doc_ct
+ when 0
+ assert_equal( doc, {} )
+ when 1
+ assert_equal( doc, [] )
+ when 2
+ assert_equal( doc, '' )
+ end
+ doc_ct += 1
+ }
+ assert_equal( doc_ct, 3 )
+ end
+
+ def test_spec_domain_prefix
+ customer_proc = proc { |type, val|
+ if Hash === val
+ scheme, domain, type = type.split( ':', 3 )
+ val['type'] = "domain #{type}"
+ val
+ else
+ raise ArgumentError, "Not a Hash in domain.tld,2002/invoice: " + val.inspect
+ end
+ }
+ YAML.add_domain_type( "domain.tld,2002", 'invoice', &customer_proc )
+ YAML.add_domain_type( "domain.tld,2002", 'customer', &customer_proc )
+ assert_parse_only( { "invoice"=> { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } }, <<EOY
+# 'http://domain.tld,2002/invoice' is some type family.
+invoice: !domain.tld,2002/^invoice
+ # 'seq' is shorthand for 'http://yaml.org/seq'.
+ # This does not effect '^customer' below
+ # because it is does not specify a prefix.
+ customers: !seq
+ # '^customer' is shorthand for the full
+ # notation 'http://domain.tld,2002/customer'.
+ - !^customer
+ given : Chris
+ family : Dumars
+EOY
+ )
+ end
+
+ def test_spec_throwaway
+ assert_parse_only(
+ {"this"=>"contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n"}, <<EOY
+### These are four throwaway comment ###
+
+### lines (the second line is empty). ###
+this: | # Comments may trail lines.
+ contains three lines of text.
+ The third one starts with a
+ # character. This isn't a comment.
+
+# These are three throwaway comment
+# lines (the first line is empty).
+EOY
+ )
+ end
+
+ def test_spec_force_implicit
+ # Force implicit
+ assert_parse_only(
+ { 'integer' => 12, 'also int' => 12, 'string' => '12' }, <<EOY
+integer: 12
+also int: ! "12"
+string: !str 12
+EOY
+ )
+ end
+
+ def test_spec_private_types
+ doc_ct = 0
+ YAML::parse_documents( <<EOY
+# Private types are per-document.
+---
+pool: !!ball
+ number: 8
+ color: black
+---
+bearing: !!ball
+ material: steel
+EOY
+ ) { |doc|
+ case doc_ct
+ when 0
+ assert_equal( doc['pool'].type_id, 'x-private:ball' )
+ assert_equal( doc['pool'].transform.value, { 'number' => 8, 'color' => 'black' } )
+ when 1
+ assert_equal( doc['bearing'].type_id, 'x-private:ball' )
+ assert_equal( doc['bearing'].transform.value, { 'material' => 'steel' } )
+ end
+ doc_ct += 1
+ }
+ assert_equal( doc_ct, 2 )
+ end
+
+ def test_spec_url_escaping
+ YAML.add_domain_type( "domain.tld,2002", "type0" ) { |type, val|
+ "ONE: #{val}"
+ }
+ YAML.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val|
+ "TWO: #{val}"
+ }
+ assert_parse_only(
+ { 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value' ] }, <<EOY
+same:
+ - !domain.tld,2002/type\\x30 value
+ - !domain.tld,2002/type0 value
+different: # As far as the YAML parser is concerned
+ - !domain.tld,2002/type%30 value
+EOY
+ )
+ end
+
+ def test_spec_override_anchor
+ # Override anchor
+ a001 = "The alias node below is a repeated use of this value.\n"
+ assert_parse_only(
+ { 'anchor' => 'This scalar has an anchor.', 'override' => a001, 'alias' => a001 }, <<EOY
+anchor : &A001 This scalar has an anchor.
+override : &A001 >
+ The alias node below is a
+ repeated use of this value.
+alias : *A001
+EOY
+ )
+ end
+
+ def test_spec_explicit_families
+ YAML.add_domain_type( "somewhere.com,2002", 'type' ) { |type, val|
+ "SOMEWHERE: #{val}"
+ }
+ assert_parse_only(
+ { 'not-date' => '2002-04-28', 'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;", 'hmm' => "SOMEWHERE: family above is short for\nhttp://somewhere.com/type\n" }, <<EOY
+not-date: !str 2002-04-28
+picture: !binary |
+ R0lGODlhDAAMAIQAAP//9/X
+ 17unp5WZmZgAAAOfn515eXv
+ Pz7Y6OjuDg4J+fn5OTk6enp
+ 56enmleECcgggoBADs=
+
+hmm: !somewhere.com,2002/type |
+ family above is short for
+ http://somewhere.com/type
+EOY
+ )
+ end
+
+ def test_spec_application_family
+ # Testing the clarkevans.com graphs
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/shape' ) { |type, val|
+ if Array === val
+ val << "Shape Container"
+ val
+ else
+ raise ArgumentError, "Invalid graph of type #{val.class}: " + val.inspect
+ end
+ }
+ one_shape_proc = Proc.new { |type, val|
+ if Hash === val
+ type = type.split( /:/ )
+ val['TYPE'] = "Shape: #{type[2]}"
+ val
+ else
+ raise ArgumentError, "Invalid graph of type #{val.class}: " + val.inspect
+ end
+ }
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/circle', &one_shape_proc )
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/line', &one_shape_proc )
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/text', &one_shape_proc )
+ assert_parse_only(
+ [[{"radius"=>7, "center"=>{"x"=>73, "y"=>129}, "TYPE"=>"Shape: graph/circle"}, {"finish"=>{"x"=>89, "y"=>102}, "TYPE"=>"Shape: graph/line", "start"=>{"x"=>73, "y"=>129}}, {"TYPE"=>"Shape: graph/text", "value"=>"Pretty vector drawing.", "start"=>{"x"=>73, "y"=>129}, "color"=>16772795}, "Shape Container"]], <<EOY
+- !clarkevans.com,2002/graph/^shape
+ - !^circle
+ center: &ORIGIN {x: 73, y: 129}
+ radius: 7
+ - !^line # !clarkevans.com,2002/graph/line
+ start: *ORIGIN
+ finish: { x: 89, y: 102 }
+ - !^text
+ start: *ORIGIN
+ color: 0xFFEEBB
+ value: Pretty vector drawing.
+EOY
+ )
+ end
+
+ def test_spec_float_explicit
+ assert_parse_only(
+ [ 10.0, 10.0, 10.0, 10.0 ], <<EOY
+# All entries in the sequence
+# have the same type and value.
+- 10.0
+- !float 10
+- !yaml.org,2002/^float '10'
+- !yaml.org,2002/float "\\
+ 1\\
+ 0"
+EOY
+ )
+ end
+
+ def test_spec_builtin_seq
+ # Assortment of sequences
+ assert_parse_only(
+ { 'empty' => [], 'in-line' => [ 'one', 'two', 'three', 'four', 'five' ],
+ 'nested' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ],
+ "A multi-line sequence entry\n", 'Sixth item in top sequence' ] }, <<EOY
+empty: []
+in-line: [ one, two, three # May span lines,
+ , four, # indentation is
+ five ] # mostly ignored.
+nested:
+ - First item in top sequence
+ -
+ - Subordinate sequence entry
+ - >
+ A multi-line
+ sequence entry
+ - Sixth item in top sequence
+EOY
+ )
+ end
+
+ def test_spec_builtin_map
+ # Assortment of mappings
+ assert_parse_only(
+ { 'empty' => {}, 'in-line' => { 'one' => 1, 'two' => 2 },
+ 'spanning' => { 'one' => 1, 'two' => 2 },
+ 'nested' => { 'first' => 'First entry', 'second' =>
+ { 'key' => 'Subordinate mapping' }, 'third' =>
+ [ 'Subordinate sequence', {}, 'Previous mapping is empty.',
+ { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' },
+ 'The previous entry is equal to the following one.',
+ { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ],
+ 12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.',
+ "\a" => 'This key had to be escaped.',
+ "This is a multi-line folded key\n" => "Whose value is also multi-line.\n",
+ [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } }, <<EOY
+
+empty: {}
+in-line: { one: 1, two: 2 }
+spanning: { one: 1,
+ two: 2 }
+nested:
+ first : First entry
+ second:
+ key: Subordinate mapping
+ third:
+ - Subordinate sequence
+ - { }
+ - Previous mapping is empty.
+ - A key: value pair in a sequence.
+ A second: key:value pair.
+ - The previous entry is equal to the following one.
+ -
+ A key: value pair in a sequence.
+ A second: key:value pair.
+ !float 12 : This key is a float.
+ ? >
+ ?
+ : This key had to be protected.
+ "\\a" : This key had to be escaped.
+ ? >
+ This is a
+ multi-line
+ folded key
+ : >
+ Whose value is
+ also multi-line.
+ ?
+ - This key
+ - is a sequence
+ :
+ - With a sequence value.
+# The following parses correctly,
+# but Ruby 1.6.* fails the comparison!
+# ?
+# This: key
+# is a: mapping
+# :
+# with a: mapping value.
+EOY
+ )
+ end
+
+ def test_spec_builtin_literal_blocks
+ # Assortment of literal scalar blocks
+ assert_parse_only(
+ {"both are equal to"=>" This has no newline.", "is equal to"=>"The \\ ' \" characters may be\nfreely used. Leading white\n space is significant.\n\nLine breaks are significant.\nThus this value contains one\nempty line and ends with a\nsingle line break, but does\nnot start with one.\n", "also written as"=>" This has no newline.", "indented and chomped"=>" This has no newline.", "empty"=>"", "literal"=>"The \\ ' \" characters may be\nfreely used. Leading white\n space is significant.\n\nLine breaks are significant.\nThus this value contains one\nempty line and ends with a\nsingle line break, but does\nnot start with one.\n"}, <<EOY
+empty: |
+
+literal: |
+ The \\ ' " characters may be
+ freely used. Leading white
+ space is significant.
+
+ Line breaks are significant.
+ Thus this value contains one
+ empty line and ends with a
+ single line break, but does
+ not start with one.
+
+is equal to: "The \\ ' \\" characters may \\
+ be\\nfreely used. Leading white\\n space \\
+ is significant.\\n\\nLine breaks are \\
+ significant.\\nThus this value contains \\
+ one\\nempty line and ends with a\\nsingle \\
+ line break, but does\\nnot start with one.\\n"
+
+# Comments may follow a nested
+# scalar value. They must be
+# less indented.
+
+# Modifiers may be combined in any order.
+indented and chomped: |2-
+ This has no newline.
+
+also written as: |-2
+ This has no newline.
+
+both are equal to: " This has no newline."
+EOY
+ )
+
+ str1 = "This has one newline.\n"
+ str2 = "This has no newline."
+ str3 = "This has two newlines.\n\n"
+ assert_parse_only(
+ { 'clipped' => str1, 'same as "clipped" above' => str1,
+ 'stripped' => str2, 'same as "stripped" above' => str2,
+ 'kept' => str3, 'same as "kept" above' => str3 }, <<EOY
+clipped: |
+ This has one newline.
+
+same as "clipped" above: "This has one newline.\\n"
+
+stripped: |-
+ This has no newline.
+
+same as "stripped" above: "This has no newline."
+
+kept: |+
+ This has two newlines.
+
+same as "kept" above: "This has two newlines.\\n\\n"
+
+EOY
+ )
+ end
+
+ def test_spec_span_single_quote
+ assert_parse_only( {"third"=>"a single quote ' must be escaped.", "second"=>"! : \\ etc. can be used freely.", "is same as"=>"this contains six spaces\nand one line break", "empty"=>"", "span"=>"this contains six spaces\nand one line break"}, <<EOY
+empty: ''
+second: '! : \\ etc. can be used freely.'
+third: 'a single quote '' must be escaped.'
+span: 'this contains
+ six spaces
+
+ and one
+ line break'
+is same as: "this contains six spaces\\nand one line break"
+EOY
+ )
+ end
+
+ def test_spec_span_double_quote
+ assert_parse_only( {"is equal to"=>"this contains four spaces", "third"=>"a \" or a \\ must be escaped.", "second"=>"! : etc. can be used freely.", "empty"=>"", "fourth"=>"this value ends with an LF.\n", "span"=>"this contains four spaces"}, <<EOY
+empty: ""
+second: "! : etc. can be used freely."
+third: "a \\\" or a \\\\ must be escaped."
+fourth: "this value ends with an LF.\\n"
+span: "this contains
+ four \\
+ spaces"
+is equal to: "this contains four spaces"
+EOY
+ )
+ end
+
+ def test_spec_builtin_time
+ # Time
+ assert_parse_only(
+ { "space separated" => mktime( 2001, 12, 14, 21, 59, 43, ".10", "-05:00" ),
+ "canonical" => mktime( 2001, 12, 15, 2, 59, 43, ".10" ),
+ "date (noon UTC)" => Date.new( 2002, 12, 14),
+ "valid iso8601" => mktime( 2001, 12, 14, 21, 59, 43, ".10", "-05:00" ) }, <<EOY
+canonical: 2001-12-15T02:59:43.1Z
+valid iso8601: 2001-12-14t21:59:43.10-05:00
+space separated: 2001-12-14 21:59:43.10 -05:00
+date (noon UTC): 2002-12-14
+EOY
+ )
+ end
+
+ def test_spec_builtin_binary
+ arrow_gif = "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371!\376\016Made with GIMP\000,\000\000\000\000\f\000\f\000\000\005, \216\2010\236\343@\024\350i\020\304\321\212\010\034\317\200M$z\357\3770\205p\270\2601f\r\e\316\001\303\001\036\020' \202\n\001\000;"
+ assert_parse_only(
+ { 'canonical' => arrow_gif, 'base64' => arrow_gif,
+ 'description' => "The binary value above is a tiny arrow encoded as a gif image.\n" }, <<EOY
+canonical: !binary "\\
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOf\\
+ n515eXvPz7Y6OjuDg4J+fn5OTk6enp56enmlpaW\\
+ NjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++\\
+ f/++f/++f/++f/++f/++f/++f/++SH+Dk1hZGUg\\
+ d2l0aCBHSU1QACwAAAAADAAMAAAFLCAgjoEwnuN\\
+ AFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84Bww\\
+ EeECcgggoBADs="
+base64: !binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOf
+ n515eXvPz7Y6OjuDg4J+fn5OTk6enp56enmlpaW
+ NjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++
+ f/++f/++f/++f/++f/++f/++f/++SH+Dk1hZGUg
+ d2l0aCBHSU1QACwAAAAADAAMAAAFLCAgjoEwnuN
+ AFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84Bww
+ EeECcgggoBADs=
+description: >
+ The binary value above is a tiny arrow
+ encoded as a gif image.
+EOY
+ )
+ end
+ def test_ruby_regexp
+ # Test Ruby regular expressions
+ assert_to_yaml(
+ { 'simple' => /a.b/, 'complex' => %r'\A"((?:[^"]|\")+)"',
+ 'case-insensitive' => /George McFly/i }, <<EOY
+case-insensitive: !ruby/regexp "/George McFly/i"
+complex: !ruby/regexp "/\\\\A\\"((?:[^\\"]|\\\\\\")+)\\"/"
+simple: !ruby/regexp "/a.b/"
+EOY
+ )
+ end
+
+ #
+ # Test of Ranges
+ #
+ def test_ranges
+
+ # Simple numeric
+ assert_to_yaml( 1..3, <<EOY )
+--- !ruby/range 1..3
+EOY
+
+ # Simple alphabetic
+ assert_to_yaml( 'a'..'z', <<EOY )
+--- !ruby/range a..z
+EOY
+
+ # Float
+ assert_to_yaml( 10.5...30.3, <<EOY )
+--- !ruby/range 10.5...30.3
+EOY
+
+ end
+
+ def test_ruby_struct
+ # Ruby structures
+ book_struct = Struct::new( "BookStruct", :author, :title, :year, :isbn )
+ assert_to_yaml(
+ [ book_struct.new( "Yukihiro Matsumoto", "Ruby in a Nutshell", 2002, "0-596-00214-9" ),
+ book_struct.new( [ 'Dave Thomas', 'Andy Hunt' ], "The Pickaxe", 2002,
+ book_struct.new( "This should be the ISBN", "but I have another struct here", 2002, "None" )
+ ) ], <<EOY
+- !ruby/struct:BookStruct
+ author: Yukihiro Matsumoto
+ title: Ruby in a Nutshell
+ year: 2002
+ isbn: 0-596-00214-9
+- !ruby/struct:BookStruct
+ author:
+ - Dave Thomas
+ - Andy Hunt
+ title: The Pickaxe
+ year: 2002
+ isbn: !ruby/struct:BookStruct
+ author: This should be the ISBN
+ title: but I have another struct here
+ year: 2002
+ isbn: None
+EOY
+ )
+
+ assert_to_yaml( YAML_Tests::StructTest.new( 123 ), <<EOY )
+--- !ruby/struct:YAML_Tests::StructTest
+c: 123
+EOY
+
+ end
+
+ def test_ruby_rational
+ assert_to_yaml( Rational(1, 2), <<EOY )
+--- !ruby/object:Rational
+numerator: 1
+denominator: 2
+EOY
+
+ # Read YAML dumped by the ruby 1.8.3.
+ assert_to_yaml( Rational(1, 2), "!ruby/object:Rational 1/2\n" )
+ assert_raise( ArgumentError ) { YAML.load("!ruby/object:Rational INVALID/RATIONAL\n") }
+ end
+
+ def test_ruby_complex
+ assert_to_yaml( Complex(3, 4), <<EOY )
+--- !ruby/object:Complex
+image: 4
+real: 3
+EOY
+
+ # Read YAML dumped by the ruby 1.8.3.
+ assert_to_yaml( Complex(3, 4), "!ruby/object:Complex 3+4i\n" )
+ assert_raise( ArgumentError ) { YAML.load("!ruby/object:Complex INVALID+COMPLEXi\n") }
+ end
+
+ def test_emitting_indicators
+ assert_to_yaml( "Hi, from Object 1. You passed: please, pretty please", <<EOY
+--- "Hi, from Object 1. You passed: please, pretty please"
+EOY
+ )
+ end
+
+ #
+ # Test the YAML::Stream class -- INACTIVE at the moment
+ #
+ def test_document
+ y = YAML::Stream.new( :Indent => 2, :UseVersion => 0 )
+ y.add(
+ { 'hi' => 'hello', 'map' =>
+ { 'good' => 'two' },
+ 'time' => Time.now,
+ 'try' => /^po(.*)$/,
+ 'bye' => 'goodbye'
+ }
+ )
+ y.add( { 'po' => 'nil', 'oper' => 90 } )
+ y.add( { 'hi' => 'wow!', 'bye' => 'wow!' } )
+ y.add( { [ 'Red Socks', 'Boston' ] => [ 'One', 'Two', 'Three' ] } )
+ y.add( [ true, false, false ] )
+ end
+
+ #
+ # Test YPath choices parsing
+ #
+ def test_ypath_parsing
+ assert_path_segments( "/*/((one|three)/name|place)|//place",
+ [ ["*", "one", "name"],
+ ["*", "three", "name"],
+ ["*", "place"],
+ ["/", "place"] ]
+ )
+ end
+
+ #
+ # Tests from Tanaka Akira on [ruby-core]
+ #
+ def test_akira
+
+ # Commas in plain scalars [ruby-core:1066]
+ assert_to_yaml(
+ {"A"=>"A,","B"=>"B"}, <<EOY
+A: "A,"
+B: B
+EOY
+ )
+
+ # Double-quoted keys [ruby-core:1069]
+ assert_to_yaml(
+ {"1"=>2, "2"=>3}, <<EOY
+'1': 2
+"2": 3
+EOY
+ )
+
+ # Anchored mapping [ruby-core:1071]
+ assert_to_yaml(
+ [{"a"=>"b"}] * 2, <<EOY
+- &id001
+ a: b
+- *id001
+EOY
+ )
+
+ # Stress test [ruby-core:1071]
+ # a = []; 1000.times { a << {"a"=>"b", "c"=>"d"} }
+ # YAML::load( a.to_yaml )
+
+ end
+
+ #
+ # Test Time.now cycle
+ #
+ def test_time_now_cycle
+ #
+ # From Minero Aoki [ruby-core:2305]
+ #
+ require 'yaml'
+ t = Time.now
+ t = Time.at(t.tv_sec, t.tv_usec)
+ 5.times do
+ assert_cycle(t)
+ end
+ end
+
+ #
+ # Test Range cycle
+ #
+ def test_range_cycle
+ #
+ # From Minero Aoki [ruby-core:02306]
+ #
+ assert_cycle("a".."z")
+
+ #
+ # From Nobu Nakada [ruby-core:02311]
+ #
+ assert_cycle(0..1)
+ assert_cycle(1.0e20 .. 2.0e20)
+ assert_cycle("0".."1")
+ assert_cycle(".."..."...")
+ assert_cycle(".rb"..".pl")
+ assert_cycle(".rb"...".pl")
+ assert_cycle('"'...".")
+ assert_cycle("'"...".")
+ end
+
+ #
+ # Circular references
+ #
+ def test_circular_references
+ a = []; a[0] = a; a[1] = a
+ inspect_str = "[[...], [...]]"
+ assert_equal( inspect_str, YAML::load( a.to_yaml ).inspect )
+ end
+
+ #
+ # Test Symbol cycle
+ #
+ def test_symbol_cycle
+ #
+ # From Aaron Schrab [ruby-Bugs:2535]
+ #
+ assert_cycle(:"^foo")
+ end
+
+ #
+ # Test Numeric cycle
+ #
+ class NumericTest < Numeric
+ def initialize(value)
+ @value = value
+ end
+ def ==(other)
+ @value == other.instance_eval{ @value }
+ end
+ end
+ def test_numeric_cycle
+ assert_cycle(1) # Fixnum
+ assert_cycle(111111111111111111111111111111111) # Bignum
+ assert_cycle(NumericTest.new(3)) # Subclass of Numeric
+ end
+
+ #
+ # Test empty map/seq in map cycle
+ #
+ def test_empty_map_key
+ #
+ # empty seq as key
+ #
+ o = YAML.load({[]=>""}.to_yaml)
+ assert_equal(Hash, o.class)
+ assert_equal([[]], o.keys)
+
+ #
+ # empty map as key
+ #
+ o = YAML.load({{}=>""}.to_yaml)
+ assert_equal(Hash, o.class)
+ assert_equal([{}], o.keys)
+ end
+
+ #
+ # contributed by riley lynch [ruby-Bugs-8548]
+ #
+ def test_object_id_collision
+ omap = YAML::Omap.new
+ 1000.times { |i| omap["key_#{i}"] = { "value" => i } }
+ raise "id collision in ordered map" if omap.to_yaml =~ /id\d+/
+ end
+
+ def test_date_out_of_range
+ assert_nothing_raised{YAML::load('1900-01-01T00:00:00+00:00')}
+ end
+
+ def test_normal_exit
+ YAML.load("2000-01-01 00:00:00.#{"0"*1000} +00:00\n")
+ # '[ruby-core:13735]'
+ end
+end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_yaml_properties.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_yaml_properties.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_yaml_properties.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,64 @@
+require 'test/unit'
+require 'yaml'
+
+module Syck
+ class TestYamlProperties < Test::Unit::TestCase
+ class Foo
+ attr_reader :a, :b, :c
+ def initialize
+ @a = 1
+ @b = 2
+ @c = 3
+ end
+
+ def to_yaml_properties
+ [:@a, :@b]
+ end
+ end
+
+ def test_object_dump_yaml_properties
+ foo = YAML.load(YAML.dump(Foo.new))
+ assert_equal 1, foo.a
+ assert_equal 2, foo.b
+ assert_nil foo.c
+ end
+
+ class Bar < Struct.new(:foo, :bar)
+ attr_reader :baz
+ def initialize *args
+ super
+ @baz = 'hello'
+ end
+
+ def to_yaml_properties
+ []
+ end
+ end
+
+ def test_struct_dump_yaml_properties
+ bar = YAML.load(YAML.dump(Bar.new('a', 'b')))
+ assert_equal 'a', bar.foo
+ assert_equal 'b', bar.bar
+ assert_nil bar.baz
+ end
+
+ def test_string_dump
+ string = "okonomiyaki"
+ class << string
+ def to_yaml_properties
+ [:@tastes]
+ end
+ end
+
+ string.instance_variable_set(:@tastes, 'delicious')
+ v = YAML.load YAML.dump string
+ assert_equal 'delicious', v.instance_variable_get(:@tastes)
+ end
+
+ def test_string_load
+ str = YAML.load("--- !str \nstr: okonomiyaki\n:@tastes: delicious\n")
+ assert_equal 'okonomiyaki', str
+ assert_equal 'delicious', str.instance_variable_get(:@tastes)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/syck/test_yamlstore.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/syck/test_yamlstore.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/syck/test_yamlstore.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,76 @@
+require 'test/unit'
+
+module Syck
+ class YAMLStoreTest < Test::Unit::TestCase
+ def setup
+ require 'yaml/store'
+ @yamlstore_file = "yamlstore.tmp.#{Process.pid}"
+ @yamlstore = YAML::Store.new(@yamlstore_file)
+ end
+
+ def teardown
+ File.unlink(@yamlstore_file) rescue nil
+ end
+
+ def test_opening_new_file_in_readonly_mode_should_result_in_empty_values
+ @yamlstore.transaction(true) do
+ assert_nil @yamlstore[:foo]
+ assert_nil @yamlstore[:bar]
+ end
+ end
+
+ def test_opening_new_file_in_readwrite_mode_should_result_in_empty_values
+ @yamlstore.transaction do
+ assert_nil @yamlstore[:foo]
+ assert_nil @yamlstore[:bar]
+ end
+ end
+
+ def test_data_should_be_loaded_correctly_when_in_readonly_mode
+ @yamlstore.transaction do
+ @yamlstore[:foo] = "bar"
+ end
+ @yamlstore.transaction(true) do
+ assert_equal "bar", @yamlstore[:foo]
+ end
+ end
+
+ def test_data_should_be_loaded_correctly_when_in_readwrite_mode
+ @yamlstore.transaction do
+ @yamlstore[:foo] = "bar"
+ end
+ @yamlstore.transaction do
+ assert_equal "bar", @yamlstore[:foo]
+ end
+ end
+
+ def test_changes_after_commit_are_discarded
+ @yamlstore.transaction do
+ @yamlstore[:foo] = "bar"
+ @yamlstore.commit
+ @yamlstore[:foo] = "baz"
+ end
+ @yamlstore.transaction(true) do
+ assert_equal "bar", @yamlstore[:foo]
+ end
+ end
+
+ def test_changes_are_not_written_on_abort
+ @yamlstore.transaction do
+ @yamlstore[:foo] = "bar"
+ @yamlstore.abort
+ end
+ @yamlstore.transaction(true) do
+ assert_nil @yamlstore[:foo]
+ end
+ end
+
+ def test_writing_inside_readonly_transaction_raises_error
+ assert_raise(PStore::Error) do
+ @yamlstore.transaction(true) do
+ @yamlstore[:foo] = "bar"
+ end
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/test_delegate.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_delegate.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_delegate.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,129 @@
+require 'test/unit'
+require 'delegate'
+
+class TestDelegateClass < Test::Unit::TestCase
+ module M
+ attr_reader :m
+ end
+
+ def test_extend
+ obj = DelegateClass(Array).new([])
+ obj.instance_eval { @m = :m }
+ obj.extend M
+ assert_equal(:m, obj.m, "[ruby-dev:33116]")
+ end
+
+ def test_systemcallerror_eq
+ e = SystemCallError.new(0)
+ assert((SimpleDelegator.new(e) == e) == (e == SimpleDelegator.new(e)), "[ruby-dev:34808]")
+ end
+
+ class Myclass < DelegateClass(Array);end
+
+ def test_delegateclass_class
+ myclass=Myclass.new([])
+ assert_equal(Myclass,myclass.class)
+ assert_equal(Myclass,myclass.dup.class,'[ruby-dev:40313]')
+ assert_equal(Myclass,myclass.clone.class,'[ruby-dev:40313]')
+ end
+
+ def test_simpledelegator_class
+ simple=SimpleDelegator.new([])
+ assert_equal(SimpleDelegator,simple.class)
+ assert_equal(SimpleDelegator,simple.dup.class)
+ assert_equal(SimpleDelegator,simple.clone.class)
+ end
+
+ class Object
+ def m
+ :o
+ end
+ private
+ def delegate_test_m
+ :o
+ end
+ end
+
+ class Foo
+ def m
+ :m
+ end
+ def delegate_test_m
+ :m
+ end
+ end
+
+ class Bar < DelegateClass(Foo)
+ end
+
+ def test_override
+ foo = Foo.new
+ foo2 = SimpleDelegator.new(foo)
+ bar = Bar.new(foo)
+ assert_equal(:o, Object.new.m)
+ assert_equal(:m, foo.m)
+ assert_equal(:m, foo2.m)
+ assert_equal(:m, bar.m)
+ bug = '[ruby-dev:39154]'
+ assert_equal(:m, foo2.send(:delegate_test_m), bug)
+ assert_equal(:m, bar.send(:delegate_test_m), bug)
+ end
+
+ class IV < DelegateClass(Integer)
+ attr_accessor :var
+
+ def initialize
+ @var = 1
+ super(0)
+ end
+ end
+
+ def test_marshal
+ bug1744 = '[ruby-core:24211]'
+ c = IV.new
+ assert_equal(1, c.var)
+ d = Marshal.load(Marshal.dump(c))
+ assert_equal(1, d.var, bug1744)
+ end
+
+ def test_copy_frozen
+ bug2679 = '[ruby-dev:40242]'
+ a = [42, :hello].freeze
+ d = SimpleDelegator.new(a)
+ assert_nothing_raised(bug2679) {d.dup[0] += 1}
+ assert_raise(RuntimeError) {d.clone[0] += 1}
+ d.freeze
+ assert(d.clone.frozen?)
+ assert(!d.dup.frozen?)
+ end
+
+ def test_frozen
+ d = SimpleDelegator.new([1, :foo])
+ d.freeze
+ assert_raise(RuntimeError, '[ruby-dev:40314]#1') {d.__setobj__("foo")}
+ assert_equal([1, :foo], d)
+ end
+
+ def test_instance_method
+ s = SimpleDelegator.new("foo")
+ m = s.method("upcase")
+ s.__setobj__([1,2,3])
+ assert_raise(NoMethodError, '[ruby-dev:40314]#3') {m.call}
+ end
+
+ class Foo
+ private
+ def delegate_test_private
+ :m
+ end
+ end
+
+ def test_private_method
+ foo = Foo.new
+ d = SimpleDelegator.new(foo)
+ assert_raise(NoMethodError) {foo.delegate_test_private}
+ assert_equal(:m, foo.send(:delegate_test_private))
+ assert_raise(NoMethodError, '[ruby-dev:40314]#4') {d.delegate_test_private}
+ assert_raise(NoMethodError, '[ruby-dev:40314]#5') {d.send(:delegate_test_private)}
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/test_find.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_find.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_find.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,226 @@
+require 'test/unit'
+require 'find'
+require 'tmpdir'
+
+class TestFind < Test::Unit::TestCase
+ def test_empty
+ Dir.mktmpdir {|d|
+ a = []
+ Find.find(d) {|f| a << f }
+ assert_equal([d], a)
+ }
+ end
+
+ def test_rec
+ Dir.mktmpdir {|d|
+ File.open("#{d}/a", "w"){}
+ Dir.mkdir("#{d}/b")
+ File.open("#{d}/b/a", "w"){}
+ File.open("#{d}/b/b", "w"){}
+ Dir.mkdir("#{d}/c")
+ a = []
+ Find.find(d) {|f| a << f }
+ assert_equal([d, "#{d}/a", "#{d}/b", "#{d}/b/a", "#{d}/b/b", "#{d}/c"], a)
+ }
+ end
+
+ def test_relative
+ Dir.mktmpdir {|d|
+ File.open("#{d}/a", "w"){}
+ Dir.mkdir("#{d}/b")
+ File.open("#{d}/b/a", "w"){}
+ File.open("#{d}/b/b", "w"){}
+ Dir.mkdir("#{d}/c")
+ a = []
+ Dir.chdir(d) {
+ Find.find(".") {|f| a << f }
+ }
+ assert_equal([".", "./a", "./b", "./b/a", "./b/b", "./c"], a)
+ }
+ end
+
+ def test_dont_follow_symlink
+ Dir.mktmpdir {|d|
+ File.open("#{d}/a", "w"){}
+ Dir.mkdir("#{d}/b")
+ File.open("#{d}/b/a", "w"){}
+ File.open("#{d}/b/b", "w"){}
+ begin
+ File.symlink("#{d}/b", "#{d}/c")
+ rescue NotImplementedError
+ skip "symlink is not supported."
+ end
+ a = []
+ Find.find(d) {|f| a << f }
+ assert_equal([d, "#{d}/a", "#{d}/b", "#{d}/b/a", "#{d}/b/b", "#{d}/c"], a)
+ }
+ end
+
+ def test_prune
+ Dir.mktmpdir {|d|
+ File.open("#{d}/a", "w"){}
+ Dir.mkdir("#{d}/b")
+ File.open("#{d}/b/a", "w"){}
+ File.open("#{d}/b/b", "w"){}
+ Dir.mkdir("#{d}/c")
+ a = []
+ Find.find(d) {|f|
+ a << f
+ Find.prune if f == "#{d}/b"
+ }
+ assert_equal([d, "#{d}/a", "#{d}/b", "#{d}/c"], a)
+ }
+ end
+
+ def test_countup3
+ Dir.mktmpdir {|d|
+ 1.upto(3) {|n| File.open("#{d}/#{n}", "w"){} }
+ a = []
+ Find.find(d) {|f| a << f }
+ assert_equal([d, "#{d}/1", "#{d}/2", "#{d}/3"], a)
+ }
+ end
+
+ def test_countdown3
+ Dir.mktmpdir {|d|
+ 3.downto(1) {|n| File.open("#{d}/#{n}", "w"){} }
+ a = []
+ Find.find(d) {|f| a << f }
+ assert_equal([d, "#{d}/1", "#{d}/2", "#{d}/3"], a)
+ }
+ end
+
+ def test_unreadable_dir
+ skip "no meaning test on Windows" if /mswin|mingw/ =~ RUBY_PLATFORM
+ Dir.mktmpdir {|d|
+ Dir.mkdir(dir = "#{d}/dir")
+ File.open(file = "#{dir}/foo", "w"){}
+ begin
+ File.chmod(0300, dir)
+ a = []
+ Find.find(d) {|f| a << f }
+ assert_equal([d, dir], a)
+ ensure
+ File.chmod(0700, dir)
+ end
+ }
+ end
+
+ def test_unsearchable_dir
+ Dir.mktmpdir {|d|
+ Dir.mkdir(dir = "#{d}/dir")
+ File.open(file = "#{dir}/foo", "w"){}
+ begin
+ File.chmod(0600, dir)
+ a = []
+ Find.find(d) {|f| a << f }
+ assert_equal([d, dir, file], a)
+ skip "no meaning test on Windows" if /mswin|mingw/ =~ RUBY_PLATFORM
+ assert_raise(Errno::EACCES) { File.lstat(file) }
+ ensure
+ File.chmod(0700, dir)
+ end
+ }
+ end
+
+ def test_dangling_symlink
+ Dir.mktmpdir {|d|
+ begin
+ File.symlink("foo", "#{d}/bar")
+ rescue NotImplementedError
+ skip "symlink is not supported."
+ end
+ a = []
+ Find.find(d) {|f| a << f }
+ assert_equal([d, "#{d}/bar"], a)
+ assert_raise(Errno::ENOENT) { File.stat("#{d}/bar") }
+ }
+ end
+
+ def test_dangling_symlink_stat_error
+ Dir.mktmpdir {|d|
+ begin
+ File.symlink("foo", "#{d}/bar")
+ rescue NotImplementedError
+ skip "symlink is not supported."
+ end
+ assert_raise(Errno::ENOENT) {
+ Find.find(d) {|f| File.stat(f) }
+ }
+ }
+ end
+
+ def test_change_dir_to_file
+ Dir.mktmpdir {|d|
+ Dir.mkdir(dir_1 = "#{d}/d1")
+ File.open(file_a = "#{dir_1}/a", "w"){}
+ File.open(file_b = "#{dir_1}/b", "w"){}
+ File.open(file_c = "#{dir_1}/c", "w"){}
+ Dir.mkdir(dir_d = "#{dir_1}/d")
+ File.open(file_de = "#{dir_d}/e", "w"){}
+ dir_2 = "#{d}/d2"
+ a = []
+ Find.find(d) {|f|
+ a << f
+ if f == file_b
+ File.rename(dir_1, dir_2)
+ File.open(dir_1, "w") {}
+ end
+ }
+ assert_equal([d, dir_1, file_a, file_b, file_c, dir_d], a)
+ }
+ end
+
+ def test_change_dir_to_symlink_loop
+ Dir.mktmpdir {|d|
+ Dir.mkdir(dir_1 = "#{d}/d1")
+ File.open(file_a = "#{dir_1}/a", "w"){}
+ File.open(file_b = "#{dir_1}/b", "w"){}
+ File.open(file_c = "#{dir_1}/c", "w"){}
+ Dir.mkdir(dir_d = "#{dir_1}/d")
+ File.open(file_de = "#{dir_d}/e", "w"){}
+ dir_2 = "#{d}/d2"
+ a = []
+ Find.find(d) {|f|
+ a << f
+ if f == file_b
+ File.rename(dir_1, dir_2)
+ begin
+ File.symlink("d1", dir_1)
+ rescue NotImplementedError
+ skip "symlink is not supported."
+ end
+ end
+ }
+ assert_equal([d, dir_1, file_a, file_b, file_c, dir_d], a)
+ }
+ end
+
+ def test_enumerator
+ Dir.mktmpdir {|d|
+ File.open("#{d}/a", "w"){}
+ Dir.mkdir("#{d}/b")
+ File.open("#{d}/b/a", "w"){}
+ File.open("#{d}/b/b", "w"){}
+ Dir.mkdir("#{d}/c")
+ e = Find.find(d)
+ a = []
+ e.each {|f| a << f }
+ assert_equal([d, "#{d}/a", "#{d}/b", "#{d}/b/a", "#{d}/b/b", "#{d}/c"], a)
+ }
+ end
+
+ class TestInclude < Test::Unit::TestCase
+ include Find
+
+ def test_functional_call
+ Dir.mktmpdir {|d|
+ File.open("#{d}/a", "w"){}
+ a = []
+ find(d) {|f| a << f }
+ assert_equal([d, "#{d}/a"], a)
+ }
+ end
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/test_ipaddr.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_ipaddr.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_ipaddr.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,3 @@
+require_relative 'inlinetest.rb'
+target = __FILE__[/test_(.*\.rb)$/, 1]
+InlineTest.loadtest__END__part(target)
Added: MacRuby/trunk/test/test-mri/test/test_mathn.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_mathn.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_mathn.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,10 @@
+require 'test/unit'
+require_relative 'ruby/envutil'
+
+# mathn redefines too much. It must be isolated to child processes.
+class TestMathn < Test::Unit::TestCase
+ def test_power
+ assert_in_out_err ['-r', 'mathn', '-e', 'a=1**2'], "", [], [], '[ruby-core:25740]'
+ assert_in_out_err ['-r', 'mathn', '-e', 'a=(1<<126)**2'], "", [], [], '[ruby-core:25740]'
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/test_open3.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_open3.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_open3.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,250 @@
+require 'test/unit'
+require 'open3'
+require_relative 'ruby/envutil'
+
+class TestOpen3 < Test::Unit::TestCase
+ RUBY = EnvUtil.rubybin
+
+ def test_exit_status
+ Open3.popen3(RUBY, '-e', 'exit true') {|i,o,e,t|
+ assert_equal(true, t.value.success?)
+ }
+ Open3.popen3(RUBY, '-e', 'exit false') {|i,o,e,t|
+ assert_equal(false, t.value.success?)
+ }
+ end
+
+ def test_stdin
+ Open3.popen3(RUBY, '-e', 'exit STDIN.gets.chomp == "t"') {|i,o,e,t|
+ i.puts 't'
+ assert_equal(true, t.value.success?)
+ }
+ Open3.popen3(RUBY, '-e', 'exit STDIN.gets.chomp == "t"') {|i,o,e,t|
+ i.puts 'f'
+ assert_equal(false, t.value.success?)
+ }
+ end
+
+ def test_stdout
+ Open3.popen3(RUBY, '-e', 'STDOUT.print "foo"') {|i,o,e,t|
+ assert_equal("foo", o.read)
+ }
+ end
+
+ def test_stderr
+ Open3.popen3(RUBY, '-e', 'STDERR.print "bar"') {|i,o,e,t|
+ assert_equal("bar", e.read)
+ }
+ end
+
+ def test_block
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ r = Open3.popen3(RUBY, '-e', 'STDOUT.print STDIN.read') {|i,o,e,t|
+ i.print "baz"
+ i.close
+ assert_equal("baz", o.read)
+ "qux"
+ }
+ assert_equal("qux", r)
+ end
+
+ def test_noblock
+ i,o,e,t = Open3.popen3(RUBY, '-e', 'STDOUT.print STDIN.read')
+ i.print "baz"
+ i.close
+ assert_equal("baz", o.read)
+ ensure
+ i.close if !i.closed?
+ o.close if !o.closed?
+ e.close if !e.closed?
+ end
+
+ def test_commandline
+ commandline = "echo quux\n"
+ Open3.popen3(commandline) {|i,o,e,t|
+ assert_equal("quux\n", o.read)
+ }
+ end
+
+ def test_pid
+ Open3.popen3(RUBY, '-e', 'print $$') {|i,o,e,t|
+ pid = o.read.to_i
+ assert_equal(pid, t[:pid])
+ assert_equal(pid, t.pid)
+ }
+ end
+
+ def with_pipe
+ r, w = IO.pipe
+ yield r, w
+ ensure
+ r.close if !r.closed?
+ w.close if !w.closed?
+ end
+
+ def with_reopen(io, arg)
+ old = io.dup
+ io.reopen(arg)
+ yield old
+ ensure
+ io.reopen(old)
+ old.close if old && !old.closed?
+ end
+
+ def test_popen2
+ with_pipe {|r, w|
+ with_reopen(STDERR, w) {|old|
+ w.close
+ Open3.popen2(RUBY, '-e', 's=STDIN.read; STDOUT.print s+"o"; STDERR.print s+"e"') {|i,o,t|
+ assert_kind_of(Thread, t)
+ i.print "z"
+ i.close
+ STDERR.reopen(old)
+ assert_equal("zo", o.read)
+ assert_equal("ze", r.read)
+ }
+ }
+ }
+ end
+
+ def test_popen2e
+ with_pipe {|r, w|
+ with_reopen(STDERR, w) {|old|
+ w.close
+ Open3.popen2e(RUBY, '-e', 's=STDIN.read; STDOUT.print s+"o"; STDOUT.flush; STDERR.print s+"e"') {|i,o,t|
+ assert_kind_of(Thread, t)
+ i.print "y"
+ i.close
+ STDERR.reopen(old)
+ assert_equal("yoye", o.read)
+ assert_equal("", r.read)
+ }
+ }
+ }
+ end
+
+ def test_capture3
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ o, e, s = Open3.capture3(RUBY, '-e', 'i=STDIN.read; print i+"o"; STDOUT.flush; STDERR.print i+"e"', :stdin_data=>"i")
+ assert_equal("io", o)
+ assert_equal("ie", e)
+ assert(s.success?)
+ end
+
+ def test_capture3_flip
+ o, e, s = Open3.capture3(RUBY, '-e', 'STDOUT.sync=true; 1000.times { print "o"*1000; STDERR.print "e"*1000 }')
+ assert_equal("o"*1000000, o)
+ assert_equal("e"*1000000, e)
+ assert(s.success?)
+ end
+
+ def test_capture2
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ o, s = Open3.capture2(RUBY, '-e', 'i=STDIN.read; print i+"o"', :stdin_data=>"i")
+ assert_equal("io", o)
+ assert(s.success?)
+ end
+
+ def test_capture2e
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ oe, s = Open3.capture2e(RUBY, '-e', 'i=STDIN.read; print i+"o"; STDOUT.flush; STDERR.print i+"e"', :stdin_data=>"i")
+ assert_equal("ioie", oe)
+ assert(s.success?)
+ end
+
+ def test_pipeline_rw
+ Open3.pipeline_rw([RUBY, '-e', 'print STDIN.read + "1"'],
+ [RUBY, '-e', 'print STDIN.read + "2"']) {|i,o,ts|
+ assert_kind_of(IO, i)
+ assert_kind_of(IO, o)
+ assert_kind_of(Array, ts)
+ assert_equal(2, ts.length)
+ ts.each {|t| assert_kind_of(Thread, t) }
+ i.print "0"
+ i.close
+ assert_equal("012", o.read)
+ ts.each {|t|
+ assert(t.value.success?)
+ }
+ }
+ end
+
+ def test_pipeline_r
+ Open3.pipeline_r([RUBY, '-e', 'print "1"'],
+ [RUBY, '-e', 'print STDIN.read + "2"']) {|o,ts|
+ assert_kind_of(IO, o)
+ assert_kind_of(Array, ts)
+ assert_equal(2, ts.length)
+ ts.each {|t| assert_kind_of(Thread, t) }
+ assert_equal("12", o.read)
+ ts.each {|t|
+ assert(t.value.success?)
+ }
+ }
+ end
+
+ def test_pipeline_w
+ command = [RUBY, '-e', 's=STDIN.read; print s[1..-1]; exit s[0] == ?t']
+ str = 'ttftff'
+ Open3.pipeline_w(*[command]*str.length) {|i,ts|
+ assert_kind_of(IO, i)
+ assert_kind_of(Array, ts)
+ assert_equal(str.length, ts.length)
+ ts.each {|t| assert_kind_of(Thread, t) }
+ i.print str
+ i.close
+ ts.each_with_index {|t, ii|
+ assert_equal(str[ii] == ?t, t.value.success?)
+ }
+ }
+ end
+
+ def test_pipeline_start
+ command = [RUBY, '-e', 's=STDIN.read; print s[1..-1]; exit s[0] == ?t']
+ str = 'ttftff'
+ Open3.pipeline_start([RUBY, '-e', 'print ARGV[0]', str],
+ *([command]*str.length)) {|ts|
+ assert_kind_of(Array, ts)
+ assert_equal(str.length+1, ts.length)
+ ts.each {|t| assert_kind_of(Thread, t) }
+ ts.each_with_index {|t, i|
+ if i == 0
+ assert(t.value.success?)
+ else
+ assert_equal(str[i-1] == ?t, t.value.success?)
+ end
+ }
+ }
+ end
+
+ def test_pipeline_start_noblock
+ ts = Open3.pipeline_start([RUBY, '-e', ''])
+ assert_kind_of(Array, ts)
+ assert_equal(1, ts.length)
+ ts.each {|t| assert_kind_of(Thread, t) }
+ t = ts[0]
+ assert(t.value.success?)
+ end
+
+ def test_pipeline
+ command = [RUBY, '-e', 's=STDIN.read; print s[1..-1]; exit s[0] == ?t']
+ str = 'ttftff'
+ ss = Open3.pipeline([RUBY, '-e', 'print ARGV[0]', str],
+ *([command]*str.length))
+ assert_kind_of(Array, ss)
+ assert_equal(str.length+1, ss.length)
+ ss.each {|s| assert_kind_of(Process::Status, s) }
+ ss.each_with_index {|s, i|
+ if i == 0
+ assert(s.success?)
+ else
+ assert_equal(str[i-1] == ?t, s.success?)
+ end
+ }
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/test_pp.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_pp.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_pp.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,194 @@
+require 'pp'
+require 'delegate'
+require 'test/unit'
+
+module PPTestModule
+
+class PPTest < Test::Unit::TestCase
+ def test_list0123_12
+ assert_equal("[0, 1, 2, 3]\n", PP.pp([0,1,2,3], '', 12))
+ end
+
+ def test_list0123_11
+ assert_equal("[0,\n 1,\n 2,\n 3]\n", PP.pp([0,1,2,3], '', 11))
+ end
+
+ OverriddenStruct = Struct.new("OverriddenStruct", :members, :class)
+ def test_struct_override_members # [ruby-core:7865]
+ a = OverriddenStruct.new(1,2)
+ assert_equal("#<struct Struct::OverriddenStruct members=1, class=2>\n", PP.pp(a, ''))
+ end
+
+ def test_redefined_method
+ o = ""
+ def o.method
+ end
+ assert_equal(%(""\n), PP.pp(o, ""))
+ end
+end
+
+class HasInspect
+ def initialize(a)
+ @a = a
+ end
+
+ def inspect
+ return "<inspect:#{@a.inspect}>"
+ end
+end
+
+class HasPrettyPrint
+ def initialize(a)
+ @a = a
+ end
+
+ def pretty_print(q)
+ q.text "<pretty_print:"
+ q.pp @a
+ q.text ">"
+ end
+end
+
+class HasBoth
+ def initialize(a)
+ @a = a
+ end
+
+ def inspect
+ return "<inspect:#{@a.inspect}>"
+ end
+
+ def pretty_print(q)
+ q.text "<pretty_print:"
+ q.pp @a
+ q.text ">"
+ end
+end
+
+class PrettyPrintInspect < HasPrettyPrint
+ alias inspect pretty_print_inspect
+end
+
+class PrettyPrintInspectWithoutPrettyPrint
+ alias inspect pretty_print_inspect
+end
+
+class PPInspectTest < Test::Unit::TestCase
+ def test_hasinspect
+ a = HasInspect.new(1)
+ assert_equal("<inspect:1>\n", PP.pp(a, ''))
+ end
+
+ def test_hasprettyprint
+ a = HasPrettyPrint.new(1)
+ assert_equal("<pretty_print:1>\n", PP.pp(a, ''))
+ end
+
+ def test_hasboth
+ a = HasBoth.new(1)
+ assert_equal("<pretty_print:1>\n", PP.pp(a, ''))
+ end
+
+ def test_pretty_print_inspect
+ skip("[BUG : #???] Segfault")
+
+ a = PrettyPrintInspect.new(1)
+ assert_equal("<pretty_print:1>", a.inspect)
+ a = PrettyPrintInspectWithoutPrettyPrint.new
+ assert_raise(RuntimeError) { a.inspect }
+ end
+
+ def test_proc
+ a = proc {1}
+ assert_equal("#{a.inspect}\n", PP.pp(a, ''))
+ end
+
+ def test_to_s_with_iv
+ a = Object.new
+ def a.to_s() "aaa" end
+ a.instance_eval { @a = nil }
+ result = PP.pp(a, '')
+ assert_equal("#{a.inspect}\n", result)
+ a = 1.0
+ a.instance_eval { @a = nil }
+ result = PP.pp(a, '')
+ assert_equal("#{a.inspect}\n", result)
+ end
+
+ def test_to_s_without_iv
+ a = Object.new
+ def a.to_s() "aaa" end
+ result = PP.pp(a, '')
+ assert_equal("#{a.inspect}\n", result)
+ assert_equal("aaa\n", result)
+ end
+end
+
+class PPCycleTest < Test::Unit::TestCase
+ def test_array
+ a = []
+ a << a
+ assert_equal("[[...]]\n", PP.pp(a, ''))
+ assert_equal("#{a.inspect}\n", PP.pp(a, ''))
+ end
+
+ def test_hash
+ a = {}
+ a[0] = a
+ assert_equal("{0=>{...}}\n", PP.pp(a, ''))
+ assert_equal("#{a.inspect}\n", PP.pp(a, ''))
+ end
+
+ S = Struct.new("S", :a, :b)
+ def test_struct
+ a = S.new(1,2)
+ a.b = a
+ assert_equal("#<struct Struct::S a=1, b=#<struct Struct::S:...>>\n", PP.pp(a, ''))
+ assert_equal("#{a.inspect}\n", PP.pp(a, ''))
+ end
+
+ def test_object
+ a = Object.new
+ a.instance_eval {@a = a}
+ assert_equal(a.inspect + "\n", PP.pp(a, ''))
+ end
+
+ def test_anonymous
+ a = Class.new.new
+ assert_equal(a.inspect + "\n", PP.pp(a, ''))
+ end
+
+ def test_withinspect
+ a = []
+ a << HasInspect.new(a)
+ assert_equal("[<inspect:[...]>]\n", PP.pp(a, ''))
+ assert_equal("#{a.inspect}\n", PP.pp(a, ''))
+ end
+
+ def test_share_nil
+ begin
+ PP.sharing_detection = true
+ a = [nil, nil]
+ assert_equal("[nil, nil]\n", PP.pp(a, ''))
+ ensure
+ PP.sharing_detection = false
+ end
+ end
+end
+
+class PPSingleLineTest < Test::Unit::TestCase
+ def test_hash
+ assert_equal("{1=>1}", PP.singleline_pp({ 1 => 1}, '')) # [ruby-core:02699]
+ assert_equal("[1#{', 1'*99}]", PP.singleline_pp([1]*100, ''))
+ end
+end
+
+class PPDelegateTest < Test::Unit::TestCase
+ class A < DelegateClass(Array); end
+
+ def test_delegate
+ assert_equal("[]\n", A.new([]).pretty_inspect, "[ruby-core:25804]")
+ end
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/test_prettyprint.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_prettyprint.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_prettyprint.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,519 @@
+require 'prettyprint'
+require 'test/unit'
+
+module PrettyPrintTest
+
+class WadlerExample < Test::Unit::TestCase # :nodoc:
+ def setup
+ @tree = Tree.new("aaaa", Tree.new("bbbbb", Tree.new("ccc"),
+ Tree.new("dd")),
+ Tree.new("eee"),
+ Tree.new("ffff", Tree.new("gg"),
+ Tree.new("hhh"),
+ Tree.new("ii")))
+ end
+
+ def hello(width)
+ PrettyPrint.format('', width) {|hello|
+ hello.group {
+ hello.group {
+ hello.group {
+ hello.group {
+ hello.text 'hello'
+ hello.breakable; hello.text 'a'
+ }
+ hello.breakable; hello.text 'b'
+ }
+ hello.breakable; hello.text 'c'
+ }
+ hello.breakable; hello.text 'd'
+ }
+ }
+ end
+
+ def test_hello_00_06
+ expected = <<'End'.chomp
+hello
+a
+b
+c
+d
+End
+ assert_equal(expected, hello(0))
+ assert_equal(expected, hello(6))
+ end
+
+ def test_hello_07_08
+ expected = <<'End'.chomp
+hello a
+b
+c
+d
+End
+ assert_equal(expected, hello(7))
+ assert_equal(expected, hello(8))
+ end
+
+ def test_hello_09_10
+ expected = <<'End'.chomp
+hello a b
+c
+d
+End
+ out = hello(9); assert_equal(expected, out)
+ out = hello(10); assert_equal(expected, out)
+ end
+
+ def test_hello_11_12
+ expected = <<'End'.chomp
+hello a b c
+d
+End
+ assert_equal(expected, hello(11))
+ assert_equal(expected, hello(12))
+ end
+
+ def test_hello_13
+ expected = <<'End'.chomp
+hello a b c d
+End
+ assert_equal(expected, hello(13))
+ end
+
+ def tree(width)
+ PrettyPrint.format('', width) {|q| @tree.show(q)}
+ end
+
+ def test_tree_00_19
+ expected = <<'End'.chomp
+aaaa[bbbbb[ccc,
+ dd],
+ eee,
+ ffff[gg,
+ hhh,
+ ii]]
+End
+ assert_equal(expected, tree(0))
+ assert_equal(expected, tree(19))
+ end
+
+ def test_tree_20_22
+ expected = <<'End'.chomp
+aaaa[bbbbb[ccc, dd],
+ eee,
+ ffff[gg,
+ hhh,
+ ii]]
+End
+ assert_equal(expected, tree(20))
+ assert_equal(expected, tree(22))
+ end
+
+ def test_tree_23_43
+ expected = <<'End'.chomp
+aaaa[bbbbb[ccc, dd],
+ eee,
+ ffff[gg, hhh, ii]]
+End
+ assert_equal(expected, tree(23))
+ assert_equal(expected, tree(43))
+ end
+
+ def test_tree_44
+ assert_equal(<<'End'.chomp, tree(44))
+aaaa[bbbbb[ccc, dd], eee, ffff[gg, hhh, ii]]
+End
+ end
+
+ def tree_alt(width)
+ PrettyPrint.format('', width) {|q| @tree.altshow(q)}
+ end
+
+ def test_tree_alt_00_18
+ expected = <<'End'.chomp
+aaaa[
+ bbbbb[
+ ccc,
+ dd
+ ],
+ eee,
+ ffff[
+ gg,
+ hhh,
+ ii
+ ]
+]
+End
+ assert_equal(expected, tree_alt(0))
+ assert_equal(expected, tree_alt(18))
+ end
+
+ def test_tree_alt_19_20
+ expected = <<'End'.chomp
+aaaa[
+ bbbbb[ ccc, dd ],
+ eee,
+ ffff[
+ gg,
+ hhh,
+ ii
+ ]
+]
+End
+ assert_equal(expected, tree_alt(19))
+ assert_equal(expected, tree_alt(20))
+ end
+
+ def test_tree_alt_20_49
+ expected = <<'End'.chomp
+aaaa[
+ bbbbb[ ccc, dd ],
+ eee,
+ ffff[ gg, hhh, ii ]
+]
+End
+ assert_equal(expected, tree_alt(21))
+ assert_equal(expected, tree_alt(49))
+ end
+
+ def test_tree_alt_50
+ expected = <<'End'.chomp
+aaaa[ bbbbb[ ccc, dd ], eee, ffff[ gg, hhh, ii ] ]
+End
+ assert_equal(expected, tree_alt(50))
+ end
+
+ class Tree # :nodoc:
+ def initialize(string, *children)
+ @string = string
+ @children = children
+ end
+
+ def show(q)
+ q.group {
+ q.text @string
+ q.nest(@string.length) {
+ unless @children.empty?
+ q.text '['
+ q.nest(1) {
+ first = true
+ @children.each {|t|
+ if first
+ first = false
+ else
+ q.text ','
+ q.breakable
+ end
+ t.show(q)
+ }
+ }
+ q.text ']'
+ end
+ }
+ }
+ end
+
+ def altshow(q)
+ q.group {
+ q.text @string
+ unless @children.empty?
+ q.text '['
+ q.nest(2) {
+ q.breakable
+ first = true
+ @children.each {|t|
+ if first
+ first = false
+ else
+ q.text ','
+ q.breakable
+ end
+ t.altshow(q)
+ }
+ }
+ q.breakable
+ q.text ']'
+ end
+ }
+ end
+
+ end
+end
+
+class StrictPrettyExample < Test::Unit::TestCase # :nodoc:
+ def prog(width)
+ PrettyPrint.format('', width) {|q|
+ q.group {
+ q.group {q.nest(2) {
+ q.text "if"; q.breakable;
+ q.group {
+ q.nest(2) {
+ q.group {q.text "a"; q.breakable; q.text "=="}
+ q.breakable; q.text "b"}}}}
+ q.breakable
+ q.group {q.nest(2) {
+ q.text "then"; q.breakable;
+ q.group {
+ q.nest(2) {
+ q.group {q.text "a"; q.breakable; q.text "<<"}
+ q.breakable; q.text "2"}}}}
+ q.breakable
+ q.group {q.nest(2) {
+ q.text "else"; q.breakable;
+ q.group {
+ q.nest(2) {
+ q.group {q.text "a"; q.breakable; q.text "+"}
+ q.breakable; q.text "b"}}}}}
+ }
+ end
+
+ def test_00_04
+ expected = <<'End'.chomp
+if
+ a
+ ==
+ b
+then
+ a
+ <<
+ 2
+else
+ a
+ +
+ b
+End
+ assert_equal(expected, prog(0))
+ assert_equal(expected, prog(4))
+ end
+
+ def test_05
+ expected = <<'End'.chomp
+if
+ a
+ ==
+ b
+then
+ a
+ <<
+ 2
+else
+ a +
+ b
+End
+ assert_equal(expected, prog(5))
+ end
+
+ def test_06
+ expected = <<'End'.chomp
+if
+ a ==
+ b
+then
+ a <<
+ 2
+else
+ a +
+ b
+End
+ assert_equal(expected, prog(6))
+ end
+
+ def test_07
+ expected = <<'End'.chomp
+if
+ a ==
+ b
+then
+ a <<
+ 2
+else
+ a + b
+End
+ assert_equal(expected, prog(7))
+ end
+
+ def test_08
+ expected = <<'End'.chomp
+if
+ a == b
+then
+ a << 2
+else
+ a + b
+End
+ assert_equal(expected, prog(8))
+ end
+
+ def test_09
+ expected = <<'End'.chomp
+if a == b
+then
+ a << 2
+else
+ a + b
+End
+ assert_equal(expected, prog(9))
+ end
+
+ def test_10
+ expected = <<'End'.chomp
+if a == b
+then
+ a << 2
+else a + b
+End
+ assert_equal(expected, prog(10))
+ end
+
+ def test_11_31
+ expected = <<'End'.chomp
+if a == b
+then a << 2
+else a + b
+End
+ assert_equal(expected, prog(11))
+ assert_equal(expected, prog(15))
+ assert_equal(expected, prog(31))
+ end
+
+ def test_32
+ expected = <<'End'.chomp
+if a == b then a << 2 else a + b
+End
+ assert_equal(expected, prog(32))
+ end
+
+end
+
+class TailGroup < Test::Unit::TestCase # :nodoc:
+ def test_1
+ out = PrettyPrint.format('', 10) {|q|
+ q.group {
+ q.group {
+ q.text "abc"
+ q.breakable
+ q.text "def"
+ }
+ q.group {
+ q.text "ghi"
+ q.breakable
+ q.text "jkl"
+ }
+ }
+ }
+ assert_equal("abc defghi\njkl", out)
+ end
+end
+
+class NonString < Test::Unit::TestCase # :nodoc:
+ def format(width)
+ PrettyPrint.format([], width, 'newline', lambda {|n| "#{n} spaces"}) {|q|
+ q.text(3, 3)
+ q.breakable(1, 1)
+ q.text(3, 3)
+ }
+ end
+
+ def test_6
+ assert_equal([3, "newline", "0 spaces", 3], format(6))
+ end
+
+ def test_7
+ assert_equal([3, 1, 3], format(7))
+ end
+
+end
+
+class Fill < Test::Unit::TestCase # :nodoc:
+ def format(width)
+ PrettyPrint.format('', width) {|q|
+ q.group {
+ q.text 'abc'
+ q.fill_breakable
+ q.text 'def'
+ q.fill_breakable
+ q.text 'ghi'
+ q.fill_breakable
+ q.text 'jkl'
+ q.fill_breakable
+ q.text 'mno'
+ q.fill_breakable
+ q.text 'pqr'
+ q.fill_breakable
+ q.text 'stu'
+ }
+ }
+ end
+
+ def test_00_06
+ expected = <<'End'.chomp
+abc
+def
+ghi
+jkl
+mno
+pqr
+stu
+End
+ assert_equal(expected, format(0))
+ assert_equal(expected, format(6))
+ end
+
+ def test_07_10
+ expected = <<'End'.chomp
+abc def
+ghi jkl
+mno pqr
+stu
+End
+ assert_equal(expected, format(7))
+ assert_equal(expected, format(10))
+ end
+
+ def test_11_14
+ expected = <<'End'.chomp
+abc def ghi
+jkl mno pqr
+stu
+End
+ assert_equal(expected, format(11))
+ assert_equal(expected, format(14))
+ end
+
+ def test_15_18
+ expected = <<'End'.chomp
+abc def ghi jkl
+mno pqr stu
+End
+ assert_equal(expected, format(15))
+ assert_equal(expected, format(18))
+ end
+
+ def test_19_22
+ expected = <<'End'.chomp
+abc def ghi jkl mno
+pqr stu
+End
+ assert_equal(expected, format(19))
+ assert_equal(expected, format(22))
+ end
+
+ def test_23_26
+ expected = <<'End'.chomp
+abc def ghi jkl mno pqr
+stu
+End
+ assert_equal(expected, format(23))
+ assert_equal(expected, format(26))
+ end
+
+ def test_27
+ expected = <<'End'.chomp
+abc def ghi jkl mno pqr stu
+End
+ assert_equal(expected, format(27))
+ end
+
+end
+
+end
Added: MacRuby/trunk/test/test-mri/test/test_prime.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_prime.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_prime.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,172 @@
+require 'test/unit'
+require 'prime'
+require 'stringio'
+require 'timeout'
+
+class TestPrime < Test::Unit::TestCase
+ # The first 100 prime numbers
+ PRIMES = [
+ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,
+ 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83,
+ 89, 97, 101, 103, 107, 109, 113, 127, 131,
+ 137, 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227, 229,
+ 233, 239, 241, 251, 257, 263, 269, 271, 277,
+ 281, 283, 293, 307, 311, 313, 317, 331, 337,
+ 347, 349, 353, 359, 367, 373, 379, 383, 389,
+ 397, 401, 409, 419, 421, 431, 433, 439, 443,
+ 449, 457, 461, 463, 467, 479, 487, 491, 499,
+ 503, 509, 521, 523, 541,
+ ]
+ def test_each
+ primes = []
+ Prime.each do |p|
+ break if p > 541
+ primes << p
+ end
+ assert_equal PRIMES, primes
+ end
+
+ def test_each_by_prime_number_theorem
+ 3.upto(15) do |i|
+ max = 2**i
+ primes = []
+ Prime.each do |p|
+ break if p >= max
+ primes << p
+ end
+
+ # Prime number theorem
+ assert primes.length >= max/Math.log(max)
+ delta = 0.05
+ li = (2..max).step(delta).inject(0){|sum,x| sum + delta/Math.log(x)}
+ assert primes.length <= li
+ end
+ end
+
+ def test_each_without_block
+ enum = Prime.each
+ assert enum.respond_to?(:each)
+ assert enum.kind_of?(Enumerable)
+ assert enum.respond_to?(:with_index)
+ assert enum.respond_to?(:next)
+ assert enum.respond_to?(:succ)
+ assert enum.respond_to?(:rewind)
+ end
+
+ def test_new
+ buf = StringIO.new('', 'w')
+ orig, $stderr = $stderr, buf
+
+ enum = Prime.new
+ assert !buf.string.empty?
+ $stderr = orig
+
+ assert enum.respond_to?(:each)
+ assert enum.kind_of?(Enumerable)
+ assert enum.respond_to?(:succ)
+
+ assert Prime === enum
+ ensure
+ $stderr = orig
+ end
+
+ def test_enumerator_succ
+ enum = Prime.each
+ assert_equal PRIMES[0, 50], 50.times.map{ enum.succ }
+ assert_equal PRIMES[50, 50], 50.times.map{ enum.succ }
+ enum.rewind
+ assert_equal PRIMES[0, 100], 100.times.map{ enum.succ }
+ end
+
+ def test_enumerator_with_index
+ enum = Prime.each
+ last = -1
+ enum.with_index do |p,i|
+ break if i >= 100
+ assert_equal last+1, i
+ assert_equal PRIMES[i], p
+ last = i
+ end
+ end
+
+ def test_default_instance_does_not_have_compatibility_methods
+ assert !Prime.instance.respond_to?(:succ)
+ assert !Prime.instance.respond_to?(:next)
+ end
+
+ class TestInteger < Test::Unit::TestCase
+ def test_prime_division
+ pd = PRIMES.inject(&:*).prime_division
+ assert_equal PRIMES.map{|p| [p, 1]}, pd
+
+ pd = (-PRIMES.inject(&:*)).prime_division
+ assert_equal [-1, *PRIMES].map{|p| [p, 1]}, pd
+ end
+
+ def test_from_prime_division
+ assert_equal PRIMES.inject(&:*), Integer.from_prime_division(PRIMES.map{|p| [p,1]})
+
+ assert_equal(-PRIMES.inject(&:*), Integer.from_prime_division([[-1, 1]] + PRIMES.map{|p| [p,1]}))
+ end
+
+ def test_prime?
+ # zero and unit
+ assert !0.prime?
+ assert !1.prime?
+
+ # small primes
+ assert 2.prime?
+ assert 3.prime?
+
+ # squared prime
+ assert !4.prime?
+ assert !9.prime?
+
+ # mersenne numbers
+ assert((2**31-1).prime?)
+ assert !(2**32-1).prime?
+
+ # fermat numbers
+ assert((2**(2**4)+1).prime?)
+ assert !(2**(2**5)+1).prime? # Euler!
+
+ # large composite
+ assert !((2**13-1) * (2**17-1)).prime?
+
+ # factorial
+ assert !(2...100).inject(&:*).prime?
+
+ # negative
+ assert !-1.prime?
+ assert(-2.prime?)
+ assert(-3.prime?)
+ assert !-4.prime?
+ end
+ end
+
+ def test_eratosthenes_works_fine_after_timeout
+ sieve = Prime::EratosthenesSieve.instance
+ sieve.send(:initialize)
+ begin
+ # simulates that Timeout.timeout interrupts Prime::EratosthenesSieve#extend_table
+ def sieve.Integer(n)
+ n = super(n)
+ sleep 10 if /extend_table/ =~ caller.first
+ return n
+ end
+
+ begin
+ Timeout.timeout(0.5) { Prime.each(7*37){} }
+ flunk("timeout expected")
+ rescue Timeout::Error
+ end
+ ensure
+ class << sieve
+ remove_method :Integer
+ end
+ end
+
+ refute_includes Prime.each(7*37).to_a, 7*37, "[ruby-dev:39465]"
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/test_pstore.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_pstore.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_pstore.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,74 @@
+require 'test/unit'
+require 'pstore'
+
+class PStoreTest < Test::Unit::TestCase
+ def setup
+ @pstore_file = "pstore.tmp.#{Process.pid}"
+ @pstore = PStore.new(@pstore_file)
+ end
+
+ def teardown
+ File.unlink(@pstore_file) rescue nil
+ end
+
+ def test_opening_new_file_in_readonly_mode_should_result_in_empty_values
+ @pstore.transaction(true) do
+ assert_nil @pstore[:foo]
+ assert_nil @pstore[:bar]
+ end
+ end
+
+ def test_opening_new_file_in_readwrite_mode_should_result_in_empty_values
+ @pstore.transaction do
+ assert_nil @pstore[:foo]
+ assert_nil @pstore[:bar]
+ end
+ end
+
+ def test_data_should_be_loaded_correctly_when_in_readonly_mode
+ @pstore.transaction do
+ @pstore[:foo] = "bar"
+ end
+ @pstore.transaction(true) do
+ assert_equal "bar", @pstore[:foo]
+ end
+ end
+
+ def test_data_should_be_loaded_correctly_when_in_readwrite_mode
+ @pstore.transaction do
+ @pstore[:foo] = "bar"
+ end
+ @pstore.transaction do
+ assert_equal "bar", @pstore[:foo]
+ end
+ end
+
+ def test_changes_after_commit_are_discarded
+ @pstore.transaction do
+ @pstore[:foo] = "bar"
+ @pstore.commit
+ @pstore[:foo] = "baz"
+ end
+ @pstore.transaction(true) do
+ assert_equal "bar", @pstore[:foo]
+ end
+ end
+
+ def test_changes_are_not_written_on_abort
+ @pstore.transaction do
+ @pstore[:foo] = "bar"
+ @pstore.abort
+ end
+ @pstore.transaction(true) do
+ assert_nil @pstore[:foo]
+ end
+ end
+
+ def test_writing_inside_readonly_transaction_raises_error
+ assert_raise(PStore::Error) do
+ @pstore.transaction(true) do
+ @pstore[:foo] = "bar"
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/test_pty.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_pty.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_pty.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,127 @@
+require 'test/unit'
+require_relative 'ruby/envutil'
+require 'shellwords'
+
+begin
+ require 'pty'
+rescue LoadError
+end
+
+class TestPTY < Test::Unit::TestCase
+ RUBY = EnvUtil.rubybin
+
+ def test_spawn_without_block
+ r, w, pid = PTY.spawn(RUBY, '-e', 'puts "a"')
+ assert_equal("a\r\n", r.gets)
+ ensure
+ Process.wait pid if pid
+ end
+
+ def test_spawn_with_block
+ PTY.spawn(RUBY, '-e', 'puts "b"') {|r,w,pid|
+ assert_equal("b\r\n", r.gets)
+ Process.wait(pid)
+ }
+ end
+
+ def test_commandline
+ commandline = Shellwords.join([RUBY, '-e', 'puts "foo"'])
+ PTY.spawn(commandline) {|r,w,pid|
+ assert_equal("foo\r\n", r.gets)
+ Process.wait(pid)
+ }
+ end
+
+ def test_argv0
+ PTY.spawn([RUBY, "argv0"], '-e', 'puts "bar"') {|r,w,pid|
+ assert_equal("bar\r\n", r.gets)
+ Process.wait(pid)
+ }
+ end
+
+ def test_open_without_block
+ ret = PTY.open
+ assert_kind_of(Array, ret)
+ assert_equal(2, ret.length)
+ assert_equal(IO, ret[0].class)
+ assert_equal(File, ret[1].class)
+ master, slave = ret
+ assert(slave.tty?)
+ assert(File.chardev?(slave.path))
+ ensure
+ if ret
+ ret[0].close
+ ret[1].close
+ end
+ end
+
+ def test_open_with_block
+ r = nil
+ x = Object.new
+ y = PTY.open {|ret|
+ r = ret;
+ assert_kind_of(Array, ret)
+ assert_equal(2, ret.length)
+ assert_equal(IO, ret[0].class)
+ assert_equal(File, ret[1].class)
+ master, slave = ret
+ assert(slave.tty?)
+ assert(File.chardev?(slave.path))
+ x
+ }
+ assert(r[0].closed?)
+ assert(r[1].closed?)
+ assert_equal(y, x)
+ end
+
+ def test_close_in_block
+ PTY.open {|master, slave|
+ slave.close
+ master.close
+ assert(slave.closed?)
+ assert(master.closed?)
+ }
+ assert_nothing_raised {
+ PTY.open {|master, slave|
+ slave.close
+ master.close
+ }
+ }
+ end
+
+ def test_open
+ PTY.open {|master, slave|
+ slave.puts "foo"
+ assert_equal("foo", master.gets.chomp)
+ master.puts "bar"
+ assert_equal("bar", slave.gets.chomp)
+ }
+ end
+
+ def test_stat_slave
+ PTY.open {|master, slave|
+ s = File.stat(slave.path)
+ assert_equal(Process.uid, s.uid)
+ assert_equal(0600, s.mode & 0777)
+ }
+ end
+
+ def test_close_master
+ PTY.open {|master, slave|
+ master.close
+ assert_raise(EOFError) { slave.readpartial(10) }
+ }
+ end
+
+ def test_close_slave
+ PTY.open {|master, slave|
+ slave.close
+ # This exception is platform dependent.
+ assert_raise(
+ EOFError, # FreeBSD
+ Errno::EIO # GNU/Linux
+ ) { master.readpartial(10) }
+ }
+ end
+end if defined? PTY
+
Added: MacRuby/trunk/test/test-mri/test/test_set.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_set.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_set.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,3 @@
+require_relative 'inlinetest.rb'
+target = __FILE__[/test_(.*\.rb)$/, 1]
+InlineTest.loadtest__END__part(target)
Added: MacRuby/trunk/test/test-mri/test/test_shellwords.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_shellwords.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_shellwords.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,39 @@
+require 'test/unit'
+require 'shellwords'
+
+class TestShellwords < Test::Unit::TestCase
+
+ include Shellwords
+
+ def setup
+ @not_string = Class.new
+ @cmd = "ruby my_prog.rb | less"
+ end
+
+
+ def test_string
+ assert_instance_of(Array, shellwords(@cmd))
+ assert_equal(4, shellwords(@cmd).length)
+ end
+
+ def test_unmatched_double_quote
+ bad_cmd = 'one two "three'
+ assert_raise ArgumentError do
+ shellwords(bad_cmd)
+ end
+ end
+
+ def test_unmatched_single_quote
+ bad_cmd = "one two 'three"
+ assert_raise ArgumentError do
+ shellwords(bad_cmd)
+ end
+ end
+
+ def test_unmatched_quotes
+ bad_cmd = "one '"'"''""'""
+ assert_raise ArgumentError do
+ shellwords(bad_cmd)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/test_singleton.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_singleton.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_singleton.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,15 @@
+require 'test/unit'
+require 'singleton'
+
+class TestSingleton < Test::Unit::TestCase
+ class C
+ include Singleton
+ end
+
+ def test_marshal
+ o1 = C.instance
+ m = Marshal.dump(o1)
+ o2 = Marshal.load(m)
+ assert_same(o1, o2)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/test_syslog.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_syslog.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_syslog.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,162 @@
+#!/usr/bin/env ruby
+# $RoughId: test.rb,v 1.9 2002/02/25 08:20:14 knu Exp $
+# $Id: test_syslog.rb 25189 2009-10-02 12:04:37Z akr $
+
+# Please only run this test on machines reasonable for testing.
+# If in doubt, ask your admin.
+
+require 'test/unit'
+require 'syslog'
+
+class TestSyslog < Test::Unit::TestCase
+ def test_new
+ assert_raises(NoMethodError) {
+ Syslog.new
+ }
+ end
+
+ def test_instance
+ sl1 = Syslog.instance
+ sl2 = Syslog.open
+ sl3 = Syslog.instance
+
+ assert_equal(Syslog, sl1)
+ assert_equal(Syslog, sl2)
+ assert_equal(Syslog, sl3)
+ ensure
+ Syslog.close if Syslog.opened?
+ end
+
+ def test_open
+ # default parameters
+ Syslog.open
+
+ assert_equal($0, Syslog.ident)
+ assert_equal(Syslog::LOG_PID | Syslog::LOG_CONS, Syslog.options)
+ assert_equal(Syslog::LOG_USER, Syslog.facility)
+
+ # open without close
+ assert_raises(RuntimeError) {
+ Syslog.open
+ }
+
+ Syslog.close
+
+ # given parameters
+ Syslog.open("foo", Syslog::LOG_NDELAY | Syslog::LOG_PERROR, Syslog::LOG_DAEMON)
+
+ assert_equal('foo', Syslog.ident)
+ assert_equal(Syslog::LOG_NDELAY | Syslog::LOG_PERROR, Syslog.options)
+ assert_equal(Syslog::LOG_DAEMON, Syslog.facility)
+
+ Syslog.close
+
+ # default parameters again (after close)
+ Syslog.open
+ Syslog.close
+
+ assert_equal(nil, Syslog.ident)
+ assert_equal(nil, Syslog.options)
+ assert_equal(nil, Syslog.facility)
+
+ # block
+ param = nil
+ Syslog.open { |syslog|
+ param = syslog
+ }
+ assert_equal(Syslog, param)
+ ensure
+ Syslog.close if Syslog.opened?
+ end
+
+ def test_opened?
+ assert_equal(false, Syslog.opened?)
+
+ Syslog.open
+ assert_equal(true, Syslog.opened?)
+
+ Syslog.close
+ assert_equal(false, Syslog.opened?)
+
+ Syslog.open {
+ assert_equal(true, Syslog.opened?)
+ }
+
+ assert_equal(false, Syslog.opened?)
+ end
+
+ def test_close
+ assert_raises(RuntimeError) {
+ Syslog.close
+ }
+ end
+
+ def test_mask
+ assert_equal(nil, Syslog.mask)
+
+ Syslog.open
+
+ orig = Syslog.mask
+
+ Syslog.mask = Syslog.LOG_UPTO(Syslog::LOG_ERR)
+ assert_equal(Syslog.LOG_UPTO(Syslog::LOG_ERR), Syslog.mask)
+
+ Syslog.mask = Syslog.LOG_MASK(Syslog::LOG_CRIT)
+ assert_equal(Syslog.LOG_MASK(Syslog::LOG_CRIT), Syslog.mask)
+
+ Syslog.mask = orig
+ ensure
+ Syslog.close if Syslog.opened?
+ end
+
+ def test_log
+ stderr = IO::pipe
+
+ pid = fork {
+ stderr[0].close
+ STDERR.reopen(stderr[1])
+ stderr[1].close
+
+ options = Syslog::LOG_PERROR | Syslog::LOG_NDELAY
+
+ Syslog.open("syslog_test", options) { |sl|
+ sl.log(Syslog::LOG_NOTICE, "test1 - hello, %s!", "world")
+ sl.notice("test1 - hello, %s!", "world")
+ }
+
+ Syslog.open("syslog_test", options | Syslog::LOG_PID) { |sl|
+ sl.log(Syslog::LOG_CRIT, "test2 - pid")
+ sl.crit("test2 - pid")
+ }
+ exit!
+ }
+
+ stderr[1].close
+ Process.waitpid(pid)
+
+ # LOG_PERROR is not yet implemented on Cygwin.
+ return if RUBY_PLATFORM =~ /cygwin/
+
+ 2.times {
+ assert_equal("syslog_test: test1 - hello, world!\n", stderr[0].gets)
+ }
+
+ 2.times {
+ assert_equal(format("syslog_test[%d]: test2 - pid\n", pid), stderr[0].gets)
+ }
+ end
+
+ def test_inspect
+ Syslog.open { |sl|
+ assert_equal(format('<#%s: opened=true, ident="%s", options=%d, facility=%d, mask=%d>',
+ Syslog,
+ sl.ident,
+ sl.options,
+ sl.facility,
+ sl.mask),
+ sl.inspect)
+ }
+
+ assert_equal(format('<#%s: opened=false>', Syslog), Syslog.inspect)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/test_tempfile.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_tempfile.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_tempfile.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,308 @@
+require 'test/unit'
+require 'tempfile'
+require_relative 'ruby/envutil'
+
+class TestTempfile < Test::Unit::TestCase
+ def initialize(*)
+ super
+ @tempfile = nil
+ end
+
+ def tempfile(*args, &block)
+ t = Tempfile.new(*args, &block)
+ @tempfile = (t unless block)
+ end
+
+ def teardown
+ if @tempfile
+ @tempfile.close!
+ end
+ end
+
+ def test_basic
+ t = tempfile("foo")
+ path = t.path
+ t.write("hello world")
+ t.close
+ assert_equal "hello world", File.read(path)
+ end
+
+ def test_saves_in_dir_tmpdir_by_default
+ t = tempfile("foo")
+ assert_equal Dir.tmpdir, File.dirname(t.path)
+ end
+
+ def test_saves_in_given_directory
+ subdir = File.join(Dir.tmpdir, "tempfile-test-#{rand}")
+ Dir.mkdir(subdir)
+ begin
+ tempfile = Tempfile.new("foo", subdir)
+ tempfile.close
+ begin
+ assert_equal subdir, File.dirname(tempfile.path)
+ ensure
+ tempfile.unlink
+ end
+ ensure
+ Dir.rmdir(subdir)
+ end
+ end
+
+ def test_basename
+ t = tempfile("foo")
+ assert_match(/^foo/, File.basename(t.path))
+ end
+
+ def test_basename_with_suffix
+ t = tempfile(["foo", ".txt"])
+ assert_match(/^foo/, File.basename(t.path))
+ assert_match(/\.txt$/, File.basename(t.path))
+ end
+
+ def test_unlink
+ t = tempfile("foo")
+ path = t.path
+
+ t.close
+ assert File.exist?(path)
+
+ t.unlink
+ assert !File.exist?(path)
+
+ assert_nil t.path
+ end
+
+ def test_unlink_silently_fails_on_windows
+ tempfile = tempfile("foo")
+ path = tempfile.path
+ begin
+ assert_nothing_raised do
+ tempfile.unlink
+ end
+ ensure
+ tempfile.close
+ File.unlink(path) if File.exist?(path)
+ end
+ end
+
+ def test_unlink_before_close_works_on_posix_systems
+ skip "on Windows, unlink is always delayed" if /mswin|mingw/ =~ RUBY_PLATFORM
+ tempfile = tempfile("foo")
+ begin
+ path = tempfile.path
+ tempfile.unlink
+ assert !File.exist?(path)
+ tempfile.write("hello ")
+ tempfile.write("world\n")
+ tempfile.rewind
+ assert_equal "hello world\n", tempfile.read
+ ensure
+ tempfile.close
+ tempfile.unlink
+ end
+ end
+
+ def test_close_and_close_p
+ t = tempfile("foo")
+ assert !t.closed?
+ t.close
+ assert t.closed?
+ end
+
+ def test_close_with_unlink_now_true_works
+ t = tempfile("foo")
+ path = t.path
+ t.close(true)
+ assert t.closed?
+ assert_nil t.path
+ assert !File.exist?(path)
+ end
+
+ def test_close_with_unlink_now_true_does_not_unlink_if_already_unlinked
+ skip "on Windows, unlink is always delayed" if /mswin|mingw/ =~ RUBY_PLATFORM
+ t = tempfile("foo")
+ path = t.path
+ t.unlink
+ File.open(path, "w").close
+ begin
+ t.close(true)
+ assert File.exist?(path)
+ ensure
+ File.unlink(path) rescue nil
+ end
+ end
+
+ def test_close_bang_works
+ t = tempfile("foo")
+ path = t.path
+ t.close!
+ assert t.closed?
+ assert_nil t.path
+ assert !File.exist?(path)
+ end
+
+ def test_close_bang_does_not_unlink_if_already_unlinked
+ skip "on Windows, unlink is always delayed" if /mswin|mingw/ =~ RUBY_PLATFORM
+ t = tempfile("foo")
+ path = t.path
+ t.unlink
+ File.open(path, "w").close
+ begin
+ t.close!
+ assert File.exist?(path)
+ ensure
+ File.unlink(path) rescue nil
+ end
+ end
+
+ def test_finalizer_does_not_unlink_if_already_unlinked
+ skip "on Windows, unlink is always delayed" if /mswin|mingw/ =~ RUBY_PLATFORM
+ assert_in_out_err('-rtempfile', <<-'EOS') do |(filename,*), (error,*)|
+file = Tempfile.new('foo')
+path = file.path
+puts path
+file.close!
+File.open(path, "w").close
+ EOS
+ assert File.exist?(filename)
+ File.unlink(filename)
+ assert_nil error
+ end
+
+ assert_in_out_err('-rtempfile', <<-'EOS') do |(filename,*), (error,*)|
+file = Tempfile.new('foo')
+path = file.path
+file.unlink
+puts path
+File.open(path, "w").close
+ EOS
+ if !filename.empty?
+ # POSIX unlink semantics supported, continue with test
+ assert File.exist?(filename)
+ File.unlink(filename)
+ end
+ assert_nil error
+ end
+ end
+
+ def test_close_does_not_make_path_nil
+ t = tempfile("foo")
+ t.close
+ assert_not_nil t.path
+ end
+
+ def test_close_flushes_buffer
+ t = tempfile("foo")
+ t.write("hello")
+ t.close
+ assert_equal 5, File.size(t.path)
+ end
+
+ def test_tempfile_is_unlinked_when_ruby_exits
+ assert_in_out_err('-rtempfile', <<-'EOS') do |(filename), (error)|
+puts Tempfile.new('foo').path
+ EOS
+ assert !File.exist?(filename)
+ end
+ end
+
+ def test_size_flushes_buffer_before_determining_file_size
+ t = tempfile("foo")
+ t.write("hello")
+ assert_equal 0, File.size(t.path)
+ assert_equal 5, t.size
+ assert_equal 5, File.size(t.path)
+ end
+
+ def test_size_works_if_file_is_closed
+ t = tempfile("foo")
+ t.write("hello")
+ t.close
+ assert_equal 5, t.size
+ end
+
+ def test_concurrency
+ threads = []
+ tempfiles = []
+ lock = Mutex.new
+ cond = ConditionVariable.new
+ start = false
+
+ 4.times do
+ threads << Thread.new do
+ lock.synchronize do
+ while !start
+ cond.wait(lock)
+ end
+ end
+ result = []
+ 30.times do
+ result << Tempfile.new('foo')
+ end
+ Thread.current[:result] = result
+ end
+ end
+
+ lock.synchronize do
+ start = true
+ cond.broadcast
+ end
+ threads.each do |thread|
+ thread.join
+ tempfiles |= thread[:result]
+ end
+ filenames = tempfiles.map { |f| f.path }
+ begin
+ assert_equal filenames.size, filenames.uniq.size
+ ensure
+ tempfiles.each do |tempfile|
+ tempfile.close!
+ end
+ end
+ end
+
+ module M
+ end
+
+ def test_extend
+ o = tempfile("foo")
+ o.extend M
+ assert(M === o, "[ruby-dev:32932]")
+ end
+
+ def test_tempfile_encoding_nooption
+ default_external=Encoding.default_external
+ t = tempfile("TEST")
+ t.write("\xE6\x9D\xBE\xE6\xB1\x9F")
+ t.rewind
+ assert_equal(default_external,t.read.encoding)
+ end
+
+ def test_tempfile_encoding_ascii8bit
+ default_external=Encoding.default_external
+ t = tempfile("TEST",:encoding=>"ascii-8bit")
+ t.write("\xE6\x9D\xBE\xE6\xB1\x9F")
+ t.rewind
+ assert_equal(Encoding::ASCII_8BIT,t.read.encoding)
+ end
+
+ def test_tempfile_encoding_ascii8bit2
+ default_external=Encoding.default_external
+ t = tempfile("TEST",Dir::tmpdir,:encoding=>"ascii-8bit")
+ t.write("\xE6\x9D\xBE\xE6\xB1\x9F")
+ t.rewind
+ assert_equal(Encoding::ASCII_8BIT,t.read.encoding)
+ end
+
+ def test_binmode
+ t = tempfile("TEST", mode: IO::BINARY)
+ if IO::BINARY.nonzero?
+ assert(t.binmode?)
+ t.open
+ assert(t.binmode?, 'binmode after reopen')
+ else
+ assert_equal(0600, t.stat.mode & 0777)
+ end
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/test_time.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_time.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_time.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,400 @@
+require 'time'
+require 'test/unit'
+
+class TestTimeExtension < Test::Unit::TestCase # :nodoc:
+ def test_rfc822
+ assert_equal(Time.utc(1976, 8, 26, 14, 30) + 4 * 3600,
+ Time.rfc2822("26 Aug 76 14:30 EDT"))
+ assert_equal(Time.utc(1976, 8, 27, 9, 32) + 7 * 3600,
+ Time.rfc2822("27 Aug 76 09:32 PDT"))
+ end
+
+ def test_rfc2822
+ assert_equal(Time.utc(1997, 11, 21, 9, 55, 6) + 6 * 3600,
+ Time.rfc2822("Fri, 21 Nov 1997 09:55:06 -0600"))
+ assert_equal(Time.utc(2003, 7, 1, 10, 52, 37) - 2 * 3600,
+ Time.rfc2822("Tue, 1 Jul 2003 10:52:37 +0200"))
+ assert_equal(Time.utc(1997, 11, 21, 10, 1, 10) + 6 * 3600,
+ Time.rfc2822("Fri, 21 Nov 1997 10:01:10 -0600"))
+ assert_equal(Time.utc(1997, 11, 21, 11, 0, 0) + 6 * 3600,
+ Time.rfc2822("Fri, 21 Nov 1997 11:00:00 -0600"))
+ assert_equal(Time.utc(1997, 11, 24, 14, 22, 1) + 8 * 3600,
+ Time.rfc2822("Mon, 24 Nov 1997 14:22:01 -0800"))
+ begin
+ Time.at(-1)
+ rescue ArgumentError
+ # ignore
+ else
+ assert_equal(Time.utc(1969, 2, 13, 23, 32, 54) + 3 * 3600 + 30 * 60,
+ Time.rfc2822("Thu, 13 Feb 1969 23:32:54 -0330"))
+ assert_equal(Time.utc(1969, 2, 13, 23, 32, 0) + 3 * 3600 + 30 * 60,
+ Time.rfc2822(" Thu,
+ 13
+ Feb
+ 1969
+ 23:32
+ -0330 (Newfoundland Time)"))
+ end
+ assert_equal(Time.utc(1997, 11, 21, 9, 55, 6),
+ Time.rfc2822("21 Nov 97 09:55:06 GMT"))
+ assert_equal(Time.utc(1997, 11, 21, 9, 55, 6) + 6 * 3600,
+ Time.rfc2822("Fri, 21 Nov 1997 09 : 55 : 06 -0600"))
+ assert_raise(ArgumentError) {
+ # inner comment is not supported.
+ Time.rfc2822("Fri, 21 Nov 1997 09(comment): 55 : 06 -0600")
+ }
+ end
+
+ def test_encode_rfc2822
+ t = Time.utc(1)
+ assert_equal("Mon, 01 Jan 0001 00:00:00 -0000", t.rfc2822)
+ end
+
+ def test_rfc2616
+ t = Time.utc(1994, 11, 6, 8, 49, 37)
+ assert_equal(t, Time.httpdate("Sun, 06 Nov 1994 08:49:37 GMT"))
+ assert_equal(t, Time.httpdate("Sunday, 06-Nov-94 08:49:37 GMT"))
+ assert_equal(t, Time.httpdate("Sun Nov 6 08:49:37 1994"))
+ assert_equal(Time.utc(1995, 11, 15, 6, 25, 24),
+ Time.httpdate("Wed, 15 Nov 1995 06:25:24 GMT"))
+ assert_equal(Time.utc(1995, 11, 15, 4, 58, 8),
+ Time.httpdate("Wed, 15 Nov 1995 04:58:08 GMT"))
+ assert_equal(Time.utc(1994, 11, 15, 8, 12, 31),
+ Time.httpdate("Tue, 15 Nov 1994 08:12:31 GMT"))
+ assert_equal(Time.utc(1994, 12, 1, 16, 0, 0),
+ Time.httpdate("Thu, 01 Dec 1994 16:00:00 GMT"))
+ assert_equal(Time.utc(1994, 10, 29, 19, 43, 31),
+ Time.httpdate("Sat, 29 Oct 1994 19:43:31 GMT"))
+ assert_equal(Time.utc(1994, 11, 15, 12, 45, 26),
+ Time.httpdate("Tue, 15 Nov 1994 12:45:26 GMT"))
+ assert_equal(Time.utc(1999, 12, 31, 23, 59, 59),
+ Time.httpdate("Fri, 31 Dec 1999 23:59:59 GMT"))
+
+ assert_equal(Time.utc(2007, 12, 23, 11, 22, 33),
+ Time.httpdate('Sunday, 23-Dec-07 11:22:33 GMT'))
+ end
+
+ def test_encode_httpdate
+ t = Time.utc(1)
+ assert_equal("Mon, 01 Jan 0001 00:00:00 GMT", t.httpdate)
+ end
+
+ def test_rfc3339
+ t = Time.utc(1985, 4, 12, 23, 20, 50, 520000)
+ s = "1985-04-12T23:20:50.52Z"
+ assert_equal(t, Time.iso8601(s))
+ assert_equal(s, t.iso8601(2))
+
+ t = Time.utc(1996, 12, 20, 0, 39, 57)
+ s = "1996-12-19T16:39:57-08:00"
+ assert_equal(t, Time.iso8601(s))
+ # There is no way to generate time string with arbitrary timezone.
+ s = "1996-12-20T00:39:57Z"
+ assert_equal(t, Time.iso8601(s))
+ assert_equal(s, t.iso8601)
+
+ t = Time.utc(1990, 12, 31, 23, 59, 60)
+ s = "1990-12-31T23:59:60Z"
+ assert_equal(t, Time.iso8601(s))
+ # leap second is representable only if timezone file has it.
+ s = "1990-12-31T15:59:60-08:00"
+ assert_equal(t, Time.iso8601(s))
+
+ begin
+ Time.at(-1)
+ rescue ArgumentError
+ # ignore
+ else
+ t = Time.utc(1937, 1, 1, 11, 40, 27, 870000)
+ s = "1937-01-01T12:00:27.87+00:20"
+ assert_equal(t, Time.iso8601(s))
+ end
+ end
+
+ # http://www.w3.org/TR/xmlschema-2/
+ def test_xmlschema
+ assert_equal(Time.utc(1999, 5, 31, 13, 20, 0) + 5 * 3600,
+ Time.xmlschema("1999-05-31T13:20:00-05:00"))
+ assert_equal(Time.local(2000, 1, 20, 12, 0, 0),
+ Time.xmlschema("2000-01-20T12:00:00"))
+ assert_equal(Time.utc(2000, 1, 20, 12, 0, 0),
+ Time.xmlschema("2000-01-20T12:00:00Z"))
+ assert_equal(Time.utc(2000, 1, 20, 12, 0, 0) - 12 * 3600,
+ Time.xmlschema("2000-01-20T12:00:00+12:00"))
+ assert_equal(Time.utc(2000, 1, 20, 12, 0, 0) + 13 * 3600,
+ Time.xmlschema("2000-01-20T12:00:00-13:00"))
+ assert_equal(Time.utc(2000, 3, 4, 23, 0, 0) - 3 * 3600,
+ Time.xmlschema("2000-03-04T23:00:00+03:00"))
+ assert_equal(Time.utc(2000, 3, 4, 20, 0, 0),
+ Time.xmlschema("2000-03-04T20:00:00Z"))
+ assert_equal(Time.local(2000, 1, 15, 0, 0, 0),
+ Time.xmlschema("2000-01-15T00:00:00"))
+ assert_equal(Time.local(2000, 2, 15, 0, 0, 0),
+ Time.xmlschema("2000-02-15T00:00:00"))
+ assert_equal(Time.local(2000, 1, 15, 12, 0, 0),
+ Time.xmlschema("2000-01-15T12:00:00"))
+ assert_equal(Time.utc(2000, 1, 16, 12, 0, 0),
+ Time.xmlschema("2000-01-16T12:00:00Z"))
+ assert_equal(Time.local(2000, 1, 1, 12, 0, 0),
+ Time.xmlschema("2000-01-01T12:00:00"))
+ assert_equal(Time.utc(1999, 12, 31, 23, 0, 0),
+ Time.xmlschema("1999-12-31T23:00:00Z"))
+ assert_equal(Time.local(2000, 1, 16, 12, 0, 0),
+ Time.xmlschema("2000-01-16T12:00:00"))
+ assert_equal(Time.local(2000, 1, 16, 0, 0, 0),
+ Time.xmlschema("2000-01-16T00:00:00"))
+ assert_equal(Time.utc(2000, 1, 12, 12, 13, 14),
+ Time.xmlschema("2000-01-12T12:13:14Z"))
+ assert_equal(Time.utc(2001, 4, 17, 19, 23, 17, 300000),
+ Time.xmlschema("2001-04-17T19:23:17.3Z"))
+ assert_equal(Time.utc(2000, 1, 2, 0, 0, 0),
+ Time.xmlschema("2000-01-01T24:00:00Z"))
+ assert_raise(ArgumentError) { Time.xmlschema("2000-01-01T00:00:00.+00:00") }
+ end
+
+ def test_encode_xmlschema
+ t = Time.utc(2001, 4, 17, 19, 23, 17, 300000)
+ assert_equal("2001-04-17T19:23:17Z", t.xmlschema)
+ assert_equal("2001-04-17T19:23:17.3Z", t.xmlschema(1))
+ assert_equal("2001-04-17T19:23:17.300000Z", t.xmlschema(6))
+ assert_equal("2001-04-17T19:23:17.3000000Z", t.xmlschema(7))
+
+ t = Time.utc(2001, 4, 17, 19, 23, 17, 123456)
+ assert_equal("2001-04-17T19:23:17.1234560Z", t.xmlschema(7))
+ assert_equal("2001-04-17T19:23:17.123456Z", t.xmlschema(6))
+ assert_equal("2001-04-17T19:23:17.12345Z", t.xmlschema(5))
+ assert_equal("2001-04-17T19:23:17.1Z", t.xmlschema(1))
+
+ t = Time.at(2.quo(3)).getlocal("+09:00")
+ assert_equal("1970-01-01T09:00:00.666+09:00", t.xmlschema(3))
+ assert_equal("1970-01-01T09:00:00.6666666666+09:00", t.xmlschema(10))
+ assert_equal("1970-01-01T09:00:00.66666666666666666666+09:00", t.xmlschema(20))
+
+ t = Time.at(123456789.quo(9999999999)).getlocal("+09:00")
+ assert_equal("1970-01-01T09:00:00.012+09:00", t.xmlschema(3))
+ assert_equal("1970-01-01T09:00:00.012345678+09:00", t.xmlschema(9))
+ assert_equal("1970-01-01T09:00:00.0123456789+09:00", t.xmlschema(10))
+ assert_equal("1970-01-01T09:00:00.0123456789012345678+09:00", t.xmlschema(19))
+ assert_equal("1970-01-01T09:00:00.01234567890123456789+09:00", t.xmlschema(20))
+
+ t = Time.utc(1)
+ assert_equal("0001-01-01T00:00:00Z", t.xmlschema)
+
+ begin
+ Time.at(-1)
+ rescue ArgumentError
+ # ignore
+ else
+ t = Time.utc(1960, 12, 31, 23, 0, 0, 123456)
+ assert_equal("1960-12-31T23:00:00.123456Z", t.xmlschema(6))
+ end
+
+ assert_equal(249, Time.xmlschema("2008-06-05T23:49:23.000249+09:00").usec)
+
+ assert_equal("10000-01-01T00:00:00Z", Time.utc(10000).xmlschema)
+ assert_equal("9999-01-01T00:00:00Z", Time.utc(9999).xmlschema)
+ assert_equal("0001-01-01T00:00:00Z", Time.utc(1).xmlschema) # 1 AD
+ assert_equal("0000-01-01T00:00:00Z", Time.utc(0).xmlschema) # 1 BC
+ assert_equal("-0001-01-01T00:00:00Z", Time.utc(-1).xmlschema) # 2 BC
+ assert_equal("-0004-01-01T00:00:00Z", Time.utc(-4).xmlschema) # 5 BC
+ assert_equal("-9999-01-01T00:00:00Z", Time.utc(-9999).xmlschema)
+ assert_equal("-10000-01-01T00:00:00Z", Time.utc(-10000).xmlschema)
+ end
+
+ def test_completion
+ now = Time.local(2001,11,29,21,26,35)
+ assert_equal(Time.local( 2001,11,29,21,12),
+ Time.parse("2001/11/29 21:12", now))
+ assert_equal(Time.local( 2001,11,29),
+ Time.parse("2001/11/29", now))
+ assert_equal(Time.local( 2001,11,29),
+ Time.parse( "11/29", now))
+ #assert_equal(Time.local(2001,11,1), Time.parse("Nov", now))
+ assert_equal(Time.local( 2001,11,29,10,22),
+ Time.parse( "10:22", now))
+ assert_raise(ArgumentError) { Time.parse("foo", now) }
+ end
+
+ def test_invalid
+ # They were actually used in some web sites.
+ assert_raise(ArgumentError) { Time.httpdate("1 Dec 2001 10:23:57 GMT") }
+ assert_raise(ArgumentError) { Time.httpdate("Sat, 1 Dec 2001 10:25:42 GMT") }
+ assert_raise(ArgumentError) { Time.httpdate("Sat, 1-Dec-2001 10:53:55 GMT") }
+ assert_raise(ArgumentError) { Time.httpdate("Saturday, 01-Dec-2001 10:15:34 GMT") }
+ assert_raise(ArgumentError) { Time.httpdate("Saturday, 01-Dec-101 11:10:07 GMT") }
+ assert_raise(ArgumentError) { Time.httpdate("Fri, 30 Nov 2001 21:30:00 JST") }
+
+ # They were actually used in some mails.
+ assert_raise(ArgumentError) { Time.rfc2822("01-5-20") }
+ assert_raise(ArgumentError) { Time.rfc2822("7/21/00") }
+ assert_raise(ArgumentError) { Time.rfc2822("2001-8-28") }
+ assert_raise(ArgumentError) { Time.rfc2822("00-5-6 1:13:06") }
+ assert_raise(ArgumentError) { Time.rfc2822("2001-9-27 9:36:49") }
+ assert_raise(ArgumentError) { Time.rfc2822("2000-12-13 11:01:11") }
+ assert_raise(ArgumentError) { Time.rfc2822("2001/10/17 04:29:55") }
+ assert_raise(ArgumentError) { Time.rfc2822("9/4/2001 9:23:19 PM") }
+ assert_raise(ArgumentError) { Time.rfc2822("01 Nov 2001 09:04:31") }
+ assert_raise(ArgumentError) { Time.rfc2822("13 Feb 2001 16:4 GMT") }
+ assert_raise(ArgumentError) { Time.rfc2822("01 Oct 00 5:41:19 PM") }
+ assert_raise(ArgumentError) { Time.rfc2822("2 Jul 00 00:51:37 JST") }
+ assert_raise(ArgumentError) { Time.rfc2822("01 11 2001 06:55:57 -0500") }
+ assert_raise(ArgumentError) { Time.rfc2822("18 \343\366\356\341\370 2000") }
+ assert_raise(ArgumentError) { Time.rfc2822("Fri, Oct 2001 18:53:32") }
+ assert_raise(ArgumentError) { Time.rfc2822("Fri, 2 Nov 2001 03:47:54") }
+ assert_raise(ArgumentError) { Time.rfc2822("Fri, 27 Jul 2001 11.14.14 +0200") }
+ assert_raise(ArgumentError) { Time.rfc2822("Thu, 2 Nov 2000 04:13:53 -600") }
+ assert_raise(ArgumentError) { Time.rfc2822("Wed, 5 Apr 2000 22:57:09 JST") }
+ assert_raise(ArgumentError) { Time.rfc2822("Mon, 11 Sep 2000 19:47:33 00000") }
+ assert_raise(ArgumentError) { Time.rfc2822("Fri, 28 Apr 2000 20:40:47 +-900") }
+ assert_raise(ArgumentError) { Time.rfc2822("Fri, 19 Jan 2001 8:15:36 AM -0500") }
+ assert_raise(ArgumentError) { Time.rfc2822("Thursday, Sep 27 2001 7:42:35 AM EST") }
+ assert_raise(ArgumentError) { Time.rfc2822("3/11/2001 1:31:57 PM Pacific Daylight Time") }
+ assert_raise(ArgumentError) { Time.rfc2822("Mi, 28 Mrz 2001 11:51:36") }
+ assert_raise(ArgumentError) { Time.rfc2822("P, 30 sept 2001 23:03:14") }
+ assert_raise(ArgumentError) { Time.rfc2822("fr, 11 aug 2000 18:39:22") }
+ assert_raise(ArgumentError) { Time.rfc2822("Fr, 21 Sep 2001 17:44:03 -1000") }
+ assert_raise(ArgumentError) { Time.rfc2822("Mo, 18 Jun 2001 19:21:40 -1000") }
+ assert_raise(ArgumentError) { Time.rfc2822("l\366, 12 aug 2000 18:53:20") }
+ assert_raise(ArgumentError) { Time.rfc2822("l\366, 26 maj 2001 00:15:58") }
+ assert_raise(ArgumentError) { Time.rfc2822("Dom, 30 Sep 2001 17:36:30") }
+ assert_raise(ArgumentError) { Time.rfc2822("%&, 31 %2/ 2000 15:44:47 -0500") }
+ assert_raise(ArgumentError) { Time.rfc2822("dom, 26 ago 2001 03:57:07 -0300") }
+ assert_raise(ArgumentError) { Time.rfc2822("ter, 04 set 2001 16:27:58 -0300") }
+ assert_raise(ArgumentError) { Time.rfc2822("Wen, 3 oct 2001 23:17:49 -0400") }
+ assert_raise(ArgumentError) { Time.rfc2822("Wen, 3 oct 2001 23:17:49 -0400") }
+ assert_raise(ArgumentError) { Time.rfc2822("ele, 11 h: 2000 12:42:15 -0500") }
+ assert_raise(ArgumentError) { Time.rfc2822("Tue, 14 Aug 2001 3:55:3 +0200") }
+ assert_raise(ArgumentError) { Time.rfc2822("Fri, 25 Aug 2000 9:3:48 +0800") }
+ assert_raise(ArgumentError) { Time.rfc2822("Fri, 1 Dec 2000 0:57:50 EST") }
+ assert_raise(ArgumentError) { Time.rfc2822("Mon, 7 May 2001 9:39:51 +0200") }
+ assert_raise(ArgumentError) { Time.rfc2822("Wed, 1 Aug 2001 16:9:15 +0200") }
+ assert_raise(ArgumentError) { Time.rfc2822("Wed, 23 Aug 2000 9:17:36 +0800") }
+ assert_raise(ArgumentError) { Time.rfc2822("Fri, 11 Aug 2000 10:4:42 +0800") }
+ assert_raise(ArgumentError) { Time.rfc2822("Sat, 15 Sep 2001 13:22:2 +0300") }
+ assert_raise(ArgumentError) { Time.rfc2822("Wed,16 \276\305\324\302 2001 20:06:25 +0800") }
+ assert_raise(ArgumentError) { Time.rfc2822("Wed,7 \312\256\322\273\324\302 2001 23:47:22 +0800") }
+ assert_raise(ArgumentError) { Time.rfc2822("=?iso-8859-1?Q?(=C5=DA),?= 10 2 2001 23:32:26 +0900 (JST)") }
+ assert_raise(ArgumentError) { Time.rfc2822("\307\341\314\343\332\311, 30 \344\346\335\343\310\321 2001 10:01:06") }
+ assert_raise(ArgumentError) { Time.rfc2822("=?iso-8859-1?Q?(=BF=E5),?= 12 =?iso-8859-1?Q?9=B7=EE?= 2001 14:52:41\n+0900 (JST)") }
+ end
+
+ def test_zone_0000
+ assert_equal(true, Time.parse("2000-01-01T00:00:00Z").utc?)
+ assert_equal(true, Time.parse("2000-01-01T00:00:00-00:00").utc?)
+ assert_equal(false, Time.parse("2000-01-01T00:00:00+00:00").utc?)
+ assert_equal(false, Time.parse("Sat, 01 Jan 2000 00:00:00 GMT").utc?)
+ assert_equal(true, Time.parse("Sat, 01 Jan 2000 00:00:00 -0000").utc?)
+ assert_equal(false, Time.parse("Sat, 01 Jan 2000 00:00:00 +0000").utc?)
+ assert_equal(false, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 GMT").utc?)
+ assert_equal(true, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 -0000").utc?)
+ assert_equal(false, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 +0000").utc?)
+ assert_equal(true, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 UTC").utc?)
+ end
+
+ def test_rfc2822_utc_roundtrip_winter
+ t1 = Time.local(2008,12,1)
+ t2 = Time.rfc2822(t1.rfc2822)
+ assert_equal(t1.utc?, t2.utc?, "[ruby-dev:37126]")
+ end
+
+ def test_rfc2822_utc_roundtrip_summer
+ t1 = Time.local(2008,8,1)
+ t2 = Time.rfc2822(t1.rfc2822)
+ assert_equal(t1.utc?, t2.utc?)
+ end
+
+ def test_parse_leap_second
+ t = Time.utc(1998,12,31,23,59,59)
+ assert_equal(t, Time.parse("Thu Dec 31 23:59:59 UTC 1998"))
+ assert_equal(t, Time.parse("Fri Dec 31 23:59:59 -0000 1998"));t.localtime
+ assert_equal(t, Time.parse("Fri Jan 1 08:59:59 +0900 1999"))
+ assert_equal(t, Time.parse("Fri Jan 1 00:59:59 +0100 1999"))
+ assert_equal(t, Time.parse("Fri Dec 31 23:59:59 +0000 1998"))
+ assert_equal(t, Time.parse("Fri Dec 31 22:59:59 -0100 1998"));t.utc
+ t += 1
+ assert_equal(t, Time.parse("Thu Dec 31 23:59:60 UTC 1998"))
+ assert_equal(t, Time.parse("Fri Dec 31 23:59:60 -0000 1998"));t.localtime
+ assert_equal(t, Time.parse("Fri Jan 1 08:59:60 +0900 1999"))
+ assert_equal(t, Time.parse("Fri Jan 1 00:59:60 +0100 1999"))
+ assert_equal(t, Time.parse("Fri Dec 31 23:59:60 +0000 1998"))
+ assert_equal(t, Time.parse("Fri Dec 31 22:59:60 -0100 1998"));t.utc
+ t += 1 if t.sec == 60
+ assert_equal(t, Time.parse("Thu Jan 1 00:00:00 UTC 1999"))
+ assert_equal(t, Time.parse("Fri Jan 1 00:00:00 -0000 1999"));t.localtime
+ assert_equal(t, Time.parse("Fri Jan 1 09:00:00 +0900 1999"))
+ assert_equal(t, Time.parse("Fri Jan 1 01:00:00 +0100 1999"))
+ assert_equal(t, Time.parse("Fri Jan 1 00:00:00 +0000 1999"))
+ assert_equal(t, Time.parse("Fri Dec 31 23:00:00 -0100 1998"))
+ end
+
+ def test_rfc2822_leap_second
+ t = Time.utc(1998,12,31,23,59,59)
+ assert_equal(t, Time.rfc2822("Thu, 31 Dec 1998 23:59:59 UTC"))
+ assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 -0000"));t.localtime
+ assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 08:59:59 +0900"))
+ assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:59:59 +0100"))
+ assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 +0000"))
+ assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 22:59:59 -0100"));t.utc
+ t += 1
+ assert_equal(t, Time.rfc2822("Thu, 31 Dec 1998 23:59:60 UTC"))
+ assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 -0000"));t.localtime
+ assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 08:59:60 +0900"))
+ assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:59:60 +0100"))
+ assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 +0000"))
+ assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 22:59:60 -0100"));t.utc
+ t += 1 if t.sec == 60
+ assert_equal(t, Time.rfc2822("Thu, 1 Jan 1999 00:00:00 UTC"))
+ assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:00:00 -0000"));t.localtime
+ assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 09:00:00 +0900"))
+ assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 01:00:00 +0100"))
+ assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:00:00 +0000"))
+ assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:00:00 -0100"))
+ end
+
+ def test_xmlschema_leap_second
+ t = Time.utc(1998,12,31,23,59,59)
+ assert_equal(t, Time.xmlschema("1998-12-31T23:59:59Z"))
+ assert_equal(t, Time.xmlschema("1998-12-31T23:59:59-00:00"));t.localtime
+ assert_equal(t, Time.xmlschema("1999-01-01T08:59:59+09:00"))
+ assert_equal(t, Time.xmlschema("1999-01-01T00:59:59+01:00"))
+ assert_equal(t, Time.xmlschema("1998-12-31T23:59:59+00:00"))
+ assert_equal(t, Time.xmlschema("1998-12-31T22:59:59-01:00"));t.utc
+ t += 1
+ assert_equal(t, Time.xmlschema("1998-12-31T23:59:60Z"))
+ assert_equal(t, Time.xmlschema("1998-12-31T23:59:60-00:00"));t.localtime
+ assert_equal(t, Time.xmlschema("1999-01-01T08:59:60+09:00"))
+ assert_equal(t, Time.xmlschema("1999-01-01T00:59:60+01:00"))
+ assert_equal(t, Time.xmlschema("1998-12-31T23:59:60+00:00"))
+ assert_equal(t, Time.xmlschema("1998-12-31T22:59:60-01:00"));t.utc
+ t += 1 if t.sec == 60
+ assert_equal(t, Time.xmlschema("1999-01-01T00:00:00Z"))
+ assert_equal(t, Time.xmlschema("1999-01-01T00:00:00-00:00"));t.localtime
+ assert_equal(t, Time.xmlschema("1999-01-01T09:00:00+09:00"))
+ assert_equal(t, Time.xmlschema("1999-01-01T01:00:00+01:00"))
+ assert_equal(t, Time.xmlschema("1999-01-01T00:00:00+00:00"))
+ assert_equal(t, Time.xmlschema("1998-12-31T23:00:00-01:00"))
+ end
+
+ def test_xmlschema_fraction
+ assert_equal(500000, Time.xmlschema("2000-01-01T00:00:00.5+00:00").tv_usec)
+ end
+
+ def test_ruby_talk_152866
+ t = Time::xmlschema('2005-08-30T22:48:00-07:00')
+ assert_equal(31, t.day)
+ assert_equal(8, t.mon)
+ end
+
+ def test_parse_fraction
+ assert_equal(500000, Time.parse("2000-01-01T00:00:00.5+00:00").tv_usec)
+ end
+
+ def test_strptime
+ assert_equal(Time.utc(2005, 8, 28, 06, 54, 20), Time.strptime("28/Aug/2005:06:54:20 +0000", "%d/%b/%Y:%T %z"))
+ end
+
+ def test_nsec
+ assert_equal(123456789, Time.xmlschema("2000-01-01T00:00:00.123456789+00:00").tv_nsec)
+ assert_equal(123456789, Time.parse("2000-01-01T00:00:00.123456789+00:00").tv_nsec)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/test_timeout.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_timeout.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_timeout.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,32 @@
+require 'test/unit'
+require 'timeout'
+require 'thread'
+
+class TestTimeout < Test::Unit::TestCase
+ def test_queue
+ q = Queue.new
+ assert_raise(Timeout::Error, "[ruby-dev:32935]") {
+ timeout(0.1) { q.pop }
+ }
+ end
+
+ def test_timeout
+ @flag = true
+ Thread.start {
+ sleep 0.1
+ @flag = false
+ }
+ assert_nothing_raised("[ruby-dev:38319]") do
+ Timeout.timeout(1) {
+ nil while @flag
+ }
+ end
+ assert !@flag, "[ruby-dev:38319]"
+ end
+
+ def test_cannot_convert_into_time_interval
+ bug3168 = '[ruby-dev:41010]'
+ def (n = Object.new).zero?; false; end
+ assert_raise(TypeError, bug3168) {Timeout.timeout(n) { sleep 0.1 }}
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/test_tsort.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/test_tsort.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/test_tsort.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,44 @@
+require 'tsort'
+require 'test/unit'
+
+class TSortHash < Hash # :nodoc:
+ include TSort
+ alias tsort_each_node each_key
+ def tsort_each_child(node, &block)
+ fetch(node).each(&block)
+ end
+end
+
+class TSortArray < Array # :nodoc:
+ include TSort
+ alias tsort_each_node each_index
+ def tsort_each_child(node, &block)
+ fetch(node).each(&block)
+ end
+end
+
+class TSortTest < Test::Unit::TestCase # :nodoc:
+ def test_dag
+ h = TSortHash[{1=>[2, 3], 2=>[3], 3=>[]}]
+ assert_equal([3, 2, 1], h.tsort)
+ assert_equal([[3], [2], [1]], h.strongly_connected_components)
+ end
+
+ def test_cycle
+ h = TSortHash[{1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}]
+ assert_equal([[4], [2, 3], [1]],
+ h.strongly_connected_components.map {|nodes| nodes.sort})
+ assert_raise(TSort::Cyclic) { h.tsort }
+ end
+
+ def test_array
+ a = TSortArray[[1], [0], [0], [2]]
+ assert_equal([[0, 1], [2], [3]],
+ a.strongly_connected_components.map {|nodes| nodes.sort})
+
+ a = TSortArray[[], [0]]
+ assert_equal([[0], [1]],
+ a.strongly_connected_components.map {|nodes| nodes.sort})
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/testunit/test_assertion.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/testunit/test_assertion.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/testunit/test_assertion.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,8 @@
+require 'test/unit'
+class TestAssertion < Test::Unit::TestCase
+ def test_wrong_assertion
+ error, line = assert_raise(ArgumentError) {assert(true, true)}, __LINE__
+ assert_match(/assertion message must be String or Proc, but TrueClass was given/, error.message)
+ assert_match(/\A#{Regexp.quote(__FILE__)}:#{line}:/, error.backtrace[0])
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/thread/test_queue.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/thread/test_queue.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/thread/test_queue.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,42 @@
+require 'test/unit'
+require 'thread'
+
+class TestQueue < Test::Unit::TestCase
+ def test_queue
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ grind(5, 1000, 15, Queue)
+ end
+
+ def test_sized_queue
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ grind(5, 1000, 15, SizedQueue, 1000)
+ end
+
+ def grind(num_threads, num_objects, num_iterations, klass, *args)
+ from_workers = klass.new(*args)
+ to_workers = klass.new(*args)
+
+ workers = (1..num_threads).map {
+ Thread.new {
+ while object = to_workers.pop
+ from_workers.push object
+ end
+ }
+ }
+
+ Thread.new {
+ num_iterations.times {
+ num_objects.times { to_workers.push 99 }
+ num_objects.times { from_workers.pop }
+ }
+ }.join
+
+ num_threads.times { to_workers.push nil }
+ workers.each { |t| t.join }
+
+ assert_equal 0, from_workers.size
+ assert_equal 0, to_workers.size
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/uri/test_common.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/uri/test_common.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/uri/test_common.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,102 @@
+require 'test/unit'
+require 'uri'
+
+module URI
+
+
+class TestCommon < Test::Unit::TestCase
+ def setup
+ end
+
+ def teardown
+ end
+
+ def test_extract
+ assert_equal(['http://example.com'],
+ URI.extract('http://example.com'))
+ assert_equal(['http://example.com'],
+ URI.extract('(http://example.com)'))
+ assert_equal(['http://example.com/foo)'],
+ URI.extract('(http://example.com/foo)'))
+ assert_equal(['http://example.jphttp://example.jp'],
+ URI.extract('http://example.jphttp://example.jp'), "[ruby-list:36086]")
+ assert_equal(['http://example.jphttp://example.jp'],
+ URI.extract('http://example.jphttp://example.jp', ['http']), "[ruby-list:36086]")
+ assert_equal(['http://', 'mailto:'].sort,
+ URI.extract('ftp:// http:// mailto: https://', ['http', 'mailto']).sort)
+ # reported by Doug Kearns <djkea2 at mugca.its.monash.edu.au>
+ assert_equal(['From:', 'mailto:xxx at xxx.xxx.xxx]'].sort,
+ URI.extract('From: XXX [mailto:xxx at xxx.xxx.xxx]').sort)
+ end
+
+ def test_regexp
+ assert_instance_of Regexp, URI.regexp
+ assert_instance_of Regexp, URI.regexp(['http'])
+ assert_equal URI.regexp, URI.regexp
+ assert_equal 'http://', 'x http:// x'.slice(URI.regexp)
+ assert_equal 'http://', 'x http:// x'.slice(URI.regexp(['http']))
+ assert_equal 'http://', 'x http:// x ftp://'.slice(URI.regexp(['http']))
+ assert_equal nil, 'http://'.slice(URI.regexp([]))
+ assert_equal nil, ''.slice(URI.regexp)
+ assert_equal nil, 'xxxx'.slice(URI.regexp)
+ assert_equal nil, ':'.slice(URI.regexp)
+ assert_equal 'From:', 'From:'.slice(URI.regexp)
+ end
+
+ def test_kernel_uri
+ expected = URI.parse("http://www.ruby-lang.org/")
+ assert_equal(expected, URI("http://www.ruby-lang.org/"))
+ assert_equal(expected, Kernel::URI("http://www.ruby-lang.org/"))
+ assert_raise(NoMethodError) { Object.new.URI("http://www.ruby-lang.org/") }
+ end
+
+ def test_encode_www_form_component
+ assert_equal("%00+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \
+ "AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E",
+ URI.encode_www_form_component("\x00 !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~"))
+ assert_equal("%95A", URI.encode_www_form_component(
+ "\x95\x41".force_encoding(Encoding::Shift_JIS)))
+ assert_equal("%E3%81%82", URI.encode_www_form_component(
+ "\x30\x42".force_encoding(Encoding::UTF_16BE)))
+ assert_equal("%1B%24B%24%22%1B%28B", URI.encode_www_form_component(
+ "\e$B$\"\e(B".force_encoding(Encoding::ISO_2022_JP)))
+ end
+
+ def test_decode_www_form_component
+ assert_equal(" !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~",
+ URI.decode_www_form_component(
+ "%20+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \
+ "AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E"))
+ assert_equal("\xA1\xA2".force_encoding(Encoding::EUC_JP),
+ URI.decode_www_form_component("%A1%A2", "EUC-JP"))
+ assert_raise(ArgumentError){URI.decode_www_form_component("%")}
+ end
+
+ def test_encode_www_form
+ assert_equal("a=1", URI.encode_www_form("a" => "1"))
+ assert_equal("a=1", URI.encode_www_form(a: 1))
+ assert_equal("a=1", URI.encode_www_form([["a", "1"]]))
+ assert_equal("a=1", URI.encode_www_form([[:a, 1]]))
+ expected = "a=1&%E3%81%82=%E6%BC%A2"
+ assert_equal(expected, URI.encode_www_form("a" => "1", "\u3042" => "\u6F22"))
+ assert_equal(expected, URI.encode_www_form(a: 1, :"\u3042" => "\u6F22"))
+ assert_equal(expected, URI.encode_www_form([["a", "1"], ["\u3042", "\u6F22"]]))
+ assert_equal(expected, URI.encode_www_form([[:a, 1], [:"\u3042", "\u6F22"]]))
+ end
+
+ def test_decode_www_form
+ assert_equal([%w[a 1], %w[a 2]], URI.decode_www_form("a=1&a=2"))
+ assert_equal([%w[a 1], ["\u3042", "\u6F22"]],
+ URI.decode_www_form("a=1;%E3%81%82=%E6%BC%A2"))
+ assert_equal([%w[?a 1], %w[a 2]], URI.decode_www_form("?a=1&a=2"))
+ assert_equal([], URI.decode_www_form(""))
+ assert_raise(ArgumentError){URI.decode_www_form("%=1")}
+ assert_raise(ArgumentError){URI.decode_www_form("a=%")}
+ assert_raise(ArgumentError){URI.decode_www_form("a=1&%=2")}
+ assert_raise(ArgumentError){URI.decode_www_form("a=1&b=%")}
+ assert_raise(ArgumentError){URI.decode_www_form("a&b")}
+ end
+end
+
+
+end
Added: MacRuby/trunk/test/test-mri/test/uri/test_ftp.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/uri/test_ftp.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/uri/test_ftp.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,62 @@
+require 'test/unit'
+require 'uri/ftp'
+
+module URI
+
+
+class TestFTP < Test::Unit::TestCase
+ def setup
+ end
+
+ def test_parse
+ url = URI.parse('ftp://user:pass@host.com/abc/def')
+ assert_kind_of(URI::FTP, url)
+
+ exp = [
+ 'ftp',
+ 'user:pass', 'host.com', URI::FTP.default_port,
+ 'abc/def', nil,
+ ]
+ ary = [
+ url.scheme, url.userinfo, url.host, url.port,
+ url.path, url.opaque
+ ]
+ assert_equal(exp, ary)
+
+ assert_equal('user', url.user)
+ assert_equal('pass', url.password)
+ end
+
+ def test_paths
+ # If you think what's below is wrong, please read RubyForge bug 2055,
+ # RFC 1738 section 3.2.2, and RFC 2396.
+ u = URI.parse('ftp://ftp.example.com/foo/bar/file.ext')
+ assert(u.path == 'foo/bar/file.ext')
+ u = URI.parse('ftp://ftp.example.com//foo/bar/file.ext')
+ assert(u.path == '/foo/bar/file.ext')
+ u = URI.parse('ftp://ftp.example.com/%2Ffoo/bar/file.ext')
+ assert(u.path == '/foo/bar/file.ext')
+ end
+
+ def test_assemble
+ # uri/ftp is conservative and uses the older RFC 1738 rules, rather than
+ # assuming everyone else has implemented RFC 2396.
+ uri = URI::FTP.build(['user:password', 'ftp.example.com', nil,
+ '/path/file.zip', 'i'])
+ assert(uri.to_s ==
+ 'ftp://user:password@ftp.example.com/%2Fpath/file.zip;type=i')
+ end
+
+ def test_select
+ assert_equal(['ftp', 'a.b.c', 21], URI.parse('ftp://a.b.c/').select(:scheme, :host, :port))
+ u = URI.parse('ftp://a.b.c/')
+ ary = u.component.collect {|c| u.send(c)}
+ assert_equal(ary, u.select(*u.component))
+ assert_raise(ArgumentError) do
+ u.select(:scheme, :host, :not_exist, :port)
+ end
+ end
+end
+
+
+end
Added: MacRuby/trunk/test/test-mri/test/uri/test_generic.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/uri/test_generic.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/uri/test_generic.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,698 @@
+require 'test/unit'
+require 'uri'
+
+class URI::TestGeneric < Test::Unit::TestCase
+ def setup
+ @url = 'http://a/b/c/d;p?q'
+ @base_url = URI.parse(@url)
+ end
+
+ def teardown
+ end
+
+ def uri_to_ary(uri)
+ uri.class.component.collect {|c| uri.send(c)}
+ end
+
+ def test_parse
+ # 0
+ assert_kind_of(URI::HTTP, @base_url)
+
+ exp = [
+ 'http',
+ nil, 'a', URI::HTTP.default_port,
+ '/b/c/d;p',
+ 'q',
+ nil
+ ]
+ ary = uri_to_ary(@base_url)
+ assert_equal(exp, ary)
+
+ # 1
+ url = URI.parse('ftp://ftp.is.co.za/rfc/rfc1808.txt')
+ assert_kind_of(URI::FTP, url)
+
+ exp = [
+ 'ftp',
+ nil, 'ftp.is.co.za', URI::FTP.default_port,
+ 'rfc/rfc1808.txt', nil,
+ ]
+ ary = uri_to_ary(url)
+ assert_equal(exp, ary)
+ # 1'
+ url = URI.parse('ftp://ftp.is.co.za/%2Frfc/rfc1808.txt')
+ assert_kind_of(URI::FTP, url)
+
+ exp = [
+ 'ftp',
+ nil, 'ftp.is.co.za', URI::FTP.default_port,
+ '/rfc/rfc1808.txt', nil,
+ ]
+ ary = uri_to_ary(url)
+ assert_equal(exp, ary)
+
+ # 2
+ url = URI.parse('gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles')
+ assert_kind_of(URI::Generic, url)
+
+ exp = [
+ 'gopher',
+ nil, 'spinaltap.micro.umn.edu', nil, nil,
+ '/00/Weather/California/Los%20Angeles', nil,
+ nil,
+ nil
+ ]
+ ary = uri_to_ary(url)
+ assert_equal(exp, ary)
+
+ # 3
+ url = URI.parse('http://www.math.uio.no/faq/compression-faq/part1.html')
+ assert_kind_of(URI::HTTP, url)
+
+ exp = [
+ 'http',
+ nil, 'www.math.uio.no', URI::HTTP.default_port,
+ '/faq/compression-faq/part1.html',
+ nil,
+ nil
+ ]
+ ary = uri_to_ary(url)
+ assert_equal(exp, ary)
+
+ # 4
+ url = URI.parse('mailto:mduerst at ifi.unizh.ch')
+ assert_kind_of(URI::Generic, url)
+
+ exp = [
+ 'mailto',
+ 'mduerst at ifi.unizh.ch',
+ []
+ ]
+ ary = uri_to_ary(url)
+ assert_equal(exp, ary)
+
+ # 5
+ url = URI.parse('news:comp.infosystems.www.servers.unix')
+ assert_kind_of(URI::Generic, url)
+
+ exp = [
+ 'news',
+ nil, nil, nil, nil,
+ nil, 'comp.infosystems.www.servers.unix',
+ nil,
+ nil
+ ]
+ ary = uri_to_ary(url)
+ assert_equal(exp, ary)
+
+ # 6
+ url = URI.parse('telnet://melvyl.ucop.edu/')
+ assert_kind_of(URI::Generic, url)
+
+ exp = [
+ 'telnet',
+ nil, 'melvyl.ucop.edu', nil, nil,
+ '/', nil,
+ nil,
+ nil
+ ]
+ ary = uri_to_ary(url)
+ assert_equal(exp, ary)
+
+ # 7
+ # reported by Mr. Kubota <em6t-kbt at asahi-net.or.jp>
+ assert_raise(URI::InvalidURIError) { URI.parse('http://a_b:80/') }
+ assert_raise(URI::InvalidURIError) { URI.parse('http://a_b/') }
+
+ # 8
+ # reported by m_seki
+ uri = URI.parse('file:///foo/bar.txt')
+ assert_kind_of(URI::Generic, url)
+ uri = URI.parse('file:/foo/bar.txt')
+ assert_kind_of(URI::Generic, url)
+
+ # 9
+ url = URI.parse('ftp://:pass@localhost/')
+ assert_equal('', url.user, "[ruby-dev:25667]")
+ assert_equal('pass', url.password)
+ assert_equal(':pass', url.userinfo, "[ruby-dev:25667]")
+ url = URI.parse('ftp://user@localhost/')
+ assert_equal('user', url.user)
+ assert_equal(nil, url.password)
+ assert_equal('user', url.userinfo)
+ url = URI.parse('ftp://localhost/')
+ assert_equal(nil, url.user)
+ assert_equal(nil, url.password)
+ assert_equal(nil, url.userinfo)
+ end
+
+ def test_merge
+ u1 = URI.parse('http://foo')
+ u2 = URI.parse('http://foo/')
+ u3 = URI.parse('http://foo/bar')
+ u4 = URI.parse('http://foo/bar/')
+
+ assert_equal(URI.parse('http://foo/baz'), u1 + 'baz')
+ assert_equal(URI.parse('http://foo/baz'), u2 + 'baz')
+ assert_equal(URI.parse('http://foo/baz'), u3 + 'baz')
+ assert_equal(URI.parse('http://foo/bar/baz'), u4 + 'baz')
+
+ assert_equal(URI.parse('http://foo/baz'), u1 + '/baz')
+ assert_equal(URI.parse('http://foo/baz'), u2 + '/baz')
+ assert_equal(URI.parse('http://foo/baz'), u3 + '/baz')
+ assert_equal(URI.parse('http://foo/baz'), u4 + '/baz')
+
+ url = URI.parse('http://hoge/a.html') + 'b.html'
+ assert_equal('http://hoge/b.html', url.to_s, "[ruby-dev:11508]")
+
+ # reported by Mr. Kubota <em6t-kbt at asahi-net.or.jp>
+ url = URI.parse('http://a/b') + 'http://x/y'
+ assert_equal('http://x/y', url.to_s)
+ assert_equal(url, URI.parse('') + 'http://x/y')
+ assert_equal(url, URI.parse('').normalize + 'http://x/y')
+ assert_equal(url, URI.parse('http://a/b').normalize + 'http://x/y')
+
+ u = URI.parse('http://foo/bar/baz')
+ assert_equal(nil, u.merge!(""))
+ assert_equal(nil, u.merge!(u))
+ assert(nil != u.merge!("."))
+ assert_equal('http://foo/bar/', u.to_s)
+ assert(nil != u.merge!("../baz"))
+ assert_equal('http://foo/baz', u.to_s)
+
+ u0 = URI.parse('mailto:foo at example.com')
+ u1 = URI.parse('mailto:foo at example.com#bar')
+ assert_equal(uri_to_ary(u0 + '#bar'), uri_to_ary(u1), "[ruby-dev:23628]")
+
+ u0 = URI.parse('http://www.example.com/')
+ u1 = URI.parse('http://www.example.com/foo/..') + './'
+ assert_equal(u0, u1, "[ruby-list:39838]")
+ u0 = URI.parse('http://www.example.com/foo/')
+ u1 = URI.parse('http://www.example.com/foo/bar/..') + './'
+ assert_equal(u0, u1)
+ u0 = URI.parse('http://www.example.com/foo/bar/')
+ u1 = URI.parse('http://www.example.com/foo/bar/baz/..') + './'
+ assert_equal(u0, u1)
+ u0 = URI.parse('http://www.example.com/')
+ u1 = URI.parse('http://www.example.com/foo/bar/../..') + './'
+ assert_equal(u0, u1)
+ u0 = URI.parse('http://www.example.com/foo/')
+ u1 = URI.parse('http://www.example.com/foo/bar/baz/../..') + './'
+ assert_equal(u0, u1)
+
+ u = URI.parse('http://www.example.com/')
+ u0 = u + './foo/'
+ u1 = u + './foo/bar/..'
+ assert_equal(u0, u1, "[ruby-list:39844]")
+ u = URI.parse('http://www.example.com/')
+ u0 = u + './'
+ u1 = u + './foo/bar/../..'
+ assert_equal(u0, u1)
+ end
+
+ def test_route
+ url = URI.parse('http://hoge/a.html').route_to('http://hoge/b.html')
+ assert_equal('b.html', url.to_s)
+
+ url = URI.parse('http://hoge/a/').route_to('http://hoge/b/')
+ assert_equal('../b/', url.to_s)
+ url = URI.parse('http://hoge/a/b').route_to('http://hoge/b/')
+ assert_equal('../b/', url.to_s)
+
+ url = URI.parse('http://hoge/a/b/').route_to('http://hoge/b/')
+ assert_equal('../../b/', url.to_s)
+
+ url = URI.parse('http://hoge/a/b/').route_to('http://HOGE/b/')
+ assert_equal('../../b/', url.to_s)
+
+ url = URI.parse('http://hoge/a/b/').route_to('http://MOGE/b/')
+ assert_equal('//MOGE/b/', url.to_s)
+
+ url = URI.parse('file:///a/b/').route_to('file:///a/b/')
+ assert_equal('', url.to_s)
+
+ url = URI.parse('mailto:foo at example.com').route_to('mailto:foo at example.com#bar')
+ assert_equal('#bar', url.to_s)
+
+ url = URI.parse('mailto:foo at example.com#bar').route_to('mailto:foo at example.com')
+ assert_equal('', url.to_s)
+
+ url = URI.parse('mailto:foo at example.com').route_to('mailto:foo at example.com')
+ assert_equal('', url.to_s)
+ end
+
+ def test_rfc3986_examples
+# http://a/b/c/d;p?q
+# g:h = g:h
+ url = @base_url.merge('g:h')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g:h', url.to_s)
+ url = @base_url.route_to('g:h')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g:h', url.to_s)
+
+# http://a/b/c/d;p?q
+# g = http://a/b/c/g
+ url = @base_url.merge('g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g', url.to_s)
+
+# http://a/b/c/d;p?q
+# ./g = http://a/b/c/g
+ url = @base_url.merge('./g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g')
+ assert_kind_of(URI::Generic, url)
+ assert('./g' != url.to_s) # ok
+ assert_equal('g', url.to_s)
+
+# http://a/b/c/d;p?q
+# g/ = http://a/b/c/g/
+ url = @base_url.merge('g/')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g/', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g/')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g/', url.to_s)
+
+# http://a/b/c/d;p?q
+# /g = http://a/g
+ url = @base_url.merge('/g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/g', url.to_s)
+ url = @base_url.route_to('http://a/g')
+ assert_kind_of(URI::Generic, url)
+ assert('/g' != url.to_s) # ok
+ assert_equal('../../g', url.to_s)
+
+# http://a/b/c/d;p?q
+# //g = http://g
+ url = @base_url.merge('//g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://g', url.to_s)
+ url = @base_url.route_to('http://g')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('//g', url.to_s)
+
+# http://a/b/c/d;p?q
+# ?y = http://a/b/c/d;p?y
+ url = @base_url.merge('?y')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/d;p?y', url.to_s)
+ url = @base_url.route_to('http://a/b/c/d;p?y')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('?y', url.to_s)
+
+# http://a/b/c/d;p?q
+# g?y = http://a/b/c/g?y
+ url = @base_url.merge('g?y')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g?y', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g?y')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g?y', url.to_s)
+
+# http://a/b/c/d;p?q
+# #s = http://a/b/c/d;p?q#s
+ url = @base_url.merge('#s')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/d;p?q#s', url.to_s)
+ url = @base_url.route_to('http://a/b/c/d;p?q#s')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('#s', url.to_s)
+
+# http://a/b/c/d;p?q
+# g#s = http://a/b/c/g#s
+ url = @base_url.merge('g#s')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g#s', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g#s')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g#s', url.to_s)
+
+# http://a/b/c/d;p?q
+# g?y#s = http://a/b/c/g?y#s
+ url = @base_url.merge('g?y#s')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g?y#s', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g?y#s')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g?y#s', url.to_s)
+
+# http://a/b/c/d;p?q
+# ;x = http://a/b/c/;x
+ url = @base_url.merge(';x')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/;x', url.to_s)
+ url = @base_url.route_to('http://a/b/c/;x')
+ assert_kind_of(URI::Generic, url)
+ assert_equal(';x', url.to_s)
+
+# http://a/b/c/d;p?q
+# g;x = http://a/b/c/g;x
+ url = @base_url.merge('g;x')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g;x', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g;x')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g;x', url.to_s)
+
+# http://a/b/c/d;p?q
+# g;x?y#s = http://a/b/c/g;x?y#s
+ url = @base_url.merge('g;x?y#s')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g;x?y#s', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g;x?y#s')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g;x?y#s', url.to_s)
+
+# http://a/b/c/d;p?q
+# . = http://a/b/c/
+ url = @base_url.merge('.')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/', url.to_s)
+ url = @base_url.route_to('http://a/b/c/')
+ assert_kind_of(URI::Generic, url)
+ assert('.' != url.to_s) # ok
+ assert_equal('./', url.to_s)
+
+# http://a/b/c/d;p?q
+# ./ = http://a/b/c/
+ url = @base_url.merge('./')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/', url.to_s)
+ url = @base_url.route_to('http://a/b/c/')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('./', url.to_s)
+
+# http://a/b/c/d;p?q
+# .. = http://a/b/
+ url = @base_url.merge('..')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/', url.to_s)
+ url = @base_url.route_to('http://a/b/')
+ assert_kind_of(URI::Generic, url)
+ assert('..' != url.to_s) # ok
+ assert_equal('../', url.to_s)
+
+# http://a/b/c/d;p?q
+# ../ = http://a/b/
+ url = @base_url.merge('../')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/', url.to_s)
+ url = @base_url.route_to('http://a/b/')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('../', url.to_s)
+
+# http://a/b/c/d;p?q
+# ../g = http://a/b/g
+ url = @base_url.merge('../g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/g', url.to_s)
+ url = @base_url.route_to('http://a/b/g')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('../g', url.to_s)
+
+# http://a/b/c/d;p?q
+# ../.. = http://a/
+ url = @base_url.merge('../..')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/', url.to_s)
+ url = @base_url.route_to('http://a/')
+ assert_kind_of(URI::Generic, url)
+ assert('../..' != url.to_s) # ok
+ assert_equal('../../', url.to_s)
+
+# http://a/b/c/d;p?q
+# ../../ = http://a/
+ url = @base_url.merge('../../')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/', url.to_s)
+ url = @base_url.route_to('http://a/')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('../../', url.to_s)
+
+# http://a/b/c/d;p?q
+# ../../g = http://a/g
+ url = @base_url.merge('../../g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/g', url.to_s)
+ url = @base_url.route_to('http://a/g')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('../../g', url.to_s)
+
+# http://a/b/c/d;p?q
+# <> = (current document)
+ url = @base_url.merge('')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/d;p?q', url.to_s)
+ url = @base_url.route_to('http://a/b/c/d;p?q')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('', url.to_s)
+
+# http://a/b/c/d;p?q
+# /./g = http://a/g
+ url = @base_url.merge('/./g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/g', url.to_s)
+# url = @base_url.route_to('http://a/./g')
+# assert_kind_of(URI::Generic, url)
+# assert_equal('/./g', url.to_s)
+
+# http://a/b/c/d;p?q
+# /../g = http://a/g
+ url = @base_url.merge('/../g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/g', url.to_s)
+# url = @base_url.route_to('http://a/../g')
+# assert_kind_of(URI::Generic, url)
+# assert_equal('/../g', url.to_s)
+
+# http://a/b/c/d;p?q
+# g. = http://a/b/c/g.
+ url = @base_url.merge('g.')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g.', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g.')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g.', url.to_s)
+
+# http://a/b/c/d;p?q
+# .g = http://a/b/c/.g
+ url = @base_url.merge('.g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/.g', url.to_s)
+ url = @base_url.route_to('http://a/b/c/.g')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('.g', url.to_s)
+
+# http://a/b/c/d;p?q
+# g.. = http://a/b/c/g..
+ url = @base_url.merge('g..')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g..', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g..')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g..', url.to_s)
+
+# http://a/b/c/d;p?q
+# ..g = http://a/b/c/..g
+ url = @base_url.merge('..g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/..g', url.to_s)
+ url = @base_url.route_to('http://a/b/c/..g')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('..g', url.to_s)
+
+# http://a/b/c/d;p?q
+# ../../../g = http://a/g
+ url = @base_url.merge('../../../g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/g', url.to_s)
+ url = @base_url.route_to('http://a/g')
+ assert_kind_of(URI::Generic, url)
+ assert('../../../g' != url.to_s) # ok? yes, it confuses you
+ assert_equal('../../g', url.to_s) # and it is clearly
+
+# http://a/b/c/d;p?q
+# ../../../../g = http://a/g
+ url = @base_url.merge('../../../../g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/g', url.to_s)
+ url = @base_url.route_to('http://a/g')
+ assert_kind_of(URI::Generic, url)
+ assert('../../../../g' != url.to_s) # ok? yes, it confuses you
+ assert_equal('../../g', url.to_s) # and it is clearly
+
+# http://a/b/c/d;p?q
+# ./../g = http://a/b/g
+ url = @base_url.merge('./../g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/g', url.to_s)
+ url = @base_url.route_to('http://a/b/g')
+ assert_kind_of(URI::Generic, url)
+ assert('./../g' != url.to_s) # ok
+ assert_equal('../g', url.to_s)
+
+# http://a/b/c/d;p?q
+# ./g/. = http://a/b/c/g/
+ url = @base_url.merge('./g/.')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g/', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g/')
+ assert_kind_of(URI::Generic, url)
+ assert('./g/.' != url.to_s) # ok
+ assert_equal('g/', url.to_s)
+
+# http://a/b/c/d;p?q
+# g/./h = http://a/b/c/g/h
+ url = @base_url.merge('g/./h')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g/h', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g/h')
+ assert_kind_of(URI::Generic, url)
+ assert('g/./h' != url.to_s) # ok
+ assert_equal('g/h', url.to_s)
+
+# http://a/b/c/d;p?q
+# g/../h = http://a/b/c/h
+ url = @base_url.merge('g/../h')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/h', url.to_s)
+ url = @base_url.route_to('http://a/b/c/h')
+ assert_kind_of(URI::Generic, url)
+ assert('g/../h' != url.to_s) # ok
+ assert_equal('h', url.to_s)
+
+# http://a/b/c/d;p?q
+# g;x=1/./y = http://a/b/c/g;x=1/y
+ url = @base_url.merge('g;x=1/./y')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g;x=1/y', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g;x=1/y')
+ assert_kind_of(URI::Generic, url)
+ assert('g;x=1/./y' != url.to_s) # ok
+ assert_equal('g;x=1/y', url.to_s)
+
+# http://a/b/c/d;p?q
+# g;x=1/../y = http://a/b/c/y
+ url = @base_url.merge('g;x=1/../y')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/y', url.to_s)
+ url = @base_url.route_to('http://a/b/c/y')
+ assert_kind_of(URI::Generic, url)
+ assert('g;x=1/../y' != url.to_s) # ok
+ assert_equal('y', url.to_s)
+
+# http://a/b/c/d;p?q
+# g?y/./x = http://a/b/c/g?y/./x
+ url = @base_url.merge('g?y/./x')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g?y/./x', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g?y/./x')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g?y/./x', url.to_s)
+
+# http://a/b/c/d;p?q
+# g?y/../x = http://a/b/c/g?y/../x
+ url = @base_url.merge('g?y/../x')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g?y/../x', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g?y/../x')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g?y/../x', url.to_s)
+
+# http://a/b/c/d;p?q
+# g#s/./x = http://a/b/c/g#s/./x
+ url = @base_url.merge('g#s/./x')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g#s/./x', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g#s/./x')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g#s/./x', url.to_s)
+
+# http://a/b/c/d;p?q
+# g#s/../x = http://a/b/c/g#s/../x
+ url = @base_url.merge('g#s/../x')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http://a/b/c/g#s/../x', url.to_s)
+ url = @base_url.route_to('http://a/b/c/g#s/../x')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('g#s/../x', url.to_s)
+
+# http://a/b/c/d;p?q
+# http:g = http:g ; for validating parsers
+# | http://a/b/c/g ; for backwards compatibility
+ url = @base_url.merge('http:g')
+ assert_kind_of(URI::HTTP, url)
+ assert_equal('http:g', url.to_s)
+ url = @base_url.route_to('http:g')
+ assert_kind_of(URI::Generic, url)
+ assert_equal('http:g', url.to_s)
+ end
+
+ def test_join
+ assert_equal(URI.parse('http://foo/bar'), URI.join('http://foo/bar'))
+ assert_equal(URI.parse('http://foo/bar'), URI.join('http://foo', 'bar'))
+ assert_equal(URI.parse('http://foo/bar/'), URI.join('http://foo', 'bar/'))
+
+ assert_equal(URI.parse('http://foo/baz'), URI.join('http://foo', 'bar', 'baz'))
+ assert_equal(URI.parse('http://foo/baz'), URI.join('http://foo', 'bar', '/baz'))
+ assert_equal(URI.parse('http://foo/baz/'), URI.join('http://foo', 'bar', '/baz/'))
+ assert_equal(URI.parse('http://foo/bar/baz'), URI.join('http://foo', 'bar/', 'baz'))
+ assert_equal(URI.parse('http://foo/hoge'), URI.join('http://foo', 'bar', 'baz', 'hoge'))
+
+ assert_equal(URI.parse('http://foo/bar/baz'), URI.join('http://foo', 'bar/baz'))
+ assert_equal(URI.parse('http://foo/bar/hoge'), URI.join('http://foo', 'bar/baz', 'hoge'))
+ assert_equal(URI.parse('http://foo/bar/baz/hoge'), URI.join('http://foo', 'bar/baz/', 'hoge'))
+ assert_equal(URI.parse('http://foo/hoge'), URI.join('http://foo', 'bar/baz', '/hoge'))
+ assert_equal(URI.parse('http://foo/bar/hoge'), URI.join('http://foo', 'bar/baz', 'hoge'))
+ assert_equal(URI.parse('http://foo/bar/baz/hoge'), URI.join('http://foo', 'bar/baz/', 'hoge'))
+ assert_equal(URI.parse('http://foo/hoge'), URI.join('http://foo', 'bar/baz', '/hoge'))
+ end
+
+ # ruby-dev:16728
+ def test_set_component
+ uri = URI.parse('http://foo:bar@baz')
+ assert_equal('oof', uri.user = 'oof')
+ assert_equal('http://oof:bar@baz', uri.to_s)
+ assert_equal('rab', uri.password = 'rab')
+ assert_equal('http://oof:rab@baz', uri.to_s)
+ assert_equal('foo', uri.userinfo = 'foo')
+ assert_equal('http://foo:rab@baz', uri.to_s)
+ assert_equal(['foo', 'bar'], uri.userinfo = ['foo', 'bar'])
+ assert_equal('http://foo:bar@baz', uri.to_s)
+ assert_equal(['foo'], uri.userinfo = ['foo'])
+ assert_equal('http://foo:bar@baz', uri.to_s)
+ assert_equal('zab', uri.host = 'zab')
+ assert_equal('http://foo:bar@zab', uri.to_s)
+ assert_equal(8080, uri.port = 8080)
+ assert_equal('http://foo:bar@zab:8080', uri.to_s)
+ assert_equal('/', uri.path = '/')
+ assert_equal('http://foo:bar@zab:8080/', uri.to_s)
+ assert_equal('a=1', uri.query = 'a=1')
+ assert_equal('http://foo:bar@zab:8080/?a=1', uri.to_s)
+ assert_equal('b123', uri.fragment = 'b123')
+ assert_equal('http://foo:bar@zab:8080/?a=1#b123', uri.to_s)
+
+ uri = URI.parse('http://example.com')
+ assert_raise(URI::InvalidURIError) { uri.password = 'bar' }
+ uri.userinfo = 'foo:bar'
+ assert_equal('http://foo:bar@example.com', uri.to_s)
+ assert_raise(URI::InvalidURIError) { uri.registry = 'bar' }
+ assert_raise(URI::InvalidURIError) { uri.opaque = 'bar' }
+
+ uri = URI.parse('mailto:foo at example.com')
+ assert_raise(URI::InvalidURIError) { uri.user = 'bar' }
+ assert_raise(URI::InvalidURIError) { uri.password = 'bar' }
+ assert_raise(URI::InvalidURIError) { uri.userinfo = ['bar', 'baz'] }
+ assert_raise(URI::InvalidURIError) { uri.host = 'bar' }
+ assert_raise(URI::InvalidURIError) { uri.port = 'bar' }
+ assert_raise(URI::InvalidURIError) { uri.path = 'bar' }
+ assert_raise(URI::InvalidURIError) { uri.query = 'bar' }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/uri/test_http.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/uri/test_http.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/uri/test_http.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,63 @@
+require 'test/unit'
+require 'uri/http'
+
+module URI
+
+
+class TestHTTP < Test::Unit::TestCase
+ def setup
+ end
+
+ def teardown
+ end
+
+ def uri_to_ary(uri)
+ uri.class.component.collect {|c| uri.send(c)}
+ end
+
+ def test_parse
+ u = URI.parse('http://a')
+ assert_kind_of(URI::HTTP, u)
+ assert_equal(['http',
+ nil, 'a', URI::HTTP.default_port,
+ '', nil, nil], uri_to_ary(u))
+ end
+
+ def test_normalize
+ host = 'aBcD'
+ u1 = URI.parse('http://' + host + '/eFg?HiJ')
+ u2 = URI.parse('http://' + host.downcase + '/eFg?HiJ')
+ assert(u1.normalize.host == 'abcd')
+ assert(u1.normalize.path == u1.path)
+ assert(u1.normalize == u2.normalize)
+ assert(!u1.normalize.host.equal?(u1.host))
+ assert( u2.normalize.host.equal?(u2.host))
+
+ assert_equal('http://abc/', URI.parse('http://abc').normalize.to_s)
+ end
+
+ def test_equal
+ assert(URI.parse('http://abc') == URI.parse('http://ABC'))
+ assert(URI.parse('http://abc/def') == URI.parse('http://ABC/def'))
+ assert(URI.parse('http://abc/def') != URI.parse('http://ABC/DEF'))
+ end
+
+ def test_request_uri
+ assert_equal('/', URI.parse('http://a.b.c/').request_uri)
+ assert_equal('/?abc=def', URI.parse('http://a.b.c/?abc=def').request_uri)
+ assert_equal('/', URI.parse('http://a.b.c').request_uri)
+ assert_equal('/?abc=def', URI.parse('http://a.b.c?abc=def').request_uri)
+ end
+
+ def test_select
+ assert_equal(['http', 'a.b.c', 80], URI.parse('http://a.b.c/').select(:scheme, :host, :port))
+ u = URI.parse('http://a.b.c/')
+ assert_equal(uri_to_ary(u), u.select(*u.component))
+ assert_raise(ArgumentError) do
+ u.select(:scheme, :host, :not_exist, :port)
+ end
+ end
+end
+
+
+end
Added: MacRuby/trunk/test/test-mri/test/uri/test_ldap.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/uri/test_ldap.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/uri/test_ldap.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,100 @@
+require 'test/unit'
+require 'uri/ldap'
+
+module URI
+
+
+class TestLDAP < Test::Unit::TestCase
+ def setup
+ end
+
+ def teardown
+ end
+
+ def uri_to_ary(uri)
+ uri.class.component.collect {|c| uri.send(c)}
+ end
+
+ def test_parse
+ url = 'ldap://ldap.jaist.ac.jp/o=JAIST,c=JP?sn?base?(sn=ttate*)'
+ u = URI.parse(url)
+ assert_kind_of(URI::LDAP, u)
+ assert_equal(url, u.to_s)
+ assert_equal('o=JAIST,c=JP', u.dn)
+ assert_equal('sn', u.attributes)
+ assert_equal('base', u.scope)
+ assert_equal('(sn=ttate*)', u.filter)
+ assert_equal(nil, u.extensions)
+
+ u.scope = URI::LDAP::SCOPE_SUB
+ u.attributes = 'sn,cn,mail'
+ assert_equal('ldap://ldap.jaist.ac.jp/o=JAIST,c=JP?sn,cn,mail?sub?(sn=ttate*)', u.to_s)
+ assert_equal('o=JAIST,c=JP', u.dn)
+ assert_equal('sn,cn,mail', u.attributes)
+ assert_equal('sub', u.scope)
+ assert_equal('(sn=ttate*)', u.filter)
+ assert_equal(nil, u.extensions)
+
+ # from RFC2255, section 6.
+ urls = {
+ 'ldap:///o=University%20of%20Michigan,c=US' =>
+ ['ldap', nil, URI::LDAP::DEFAULT_PORT,
+ 'o=University%20of%20Michigan,c=US',
+ nil, nil, nil, nil],
+
+ 'ldap://ldap.itd.umich.edu/o=University%20of%20Michigan,c=US' =>
+ ['ldap', 'ldap.itd.umich.edu', URI::LDAP::DEFAULT_PORT,
+ 'o=University%20of%20Michigan,c=US',
+ nil, nil, nil, nil],
+
+ 'ldap://ldap.itd.umich.edu/o=University%20of%20Michigan,c=US?postalAddress' =>
+ ['ldap', 'ldap.itd.umich.edu', URI::LDAP::DEFAULT_PORT,
+ 'o=University%20of%20Michigan,c=US',
+ 'postalAddress', nil, nil, nil],
+
+ 'ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Babs%20Jensen)' =>
+ ['ldap', 'host.com', 6666,
+ 'o=University%20of%20Michigan,c=US',
+ nil, 'sub', '(cn=Babs%20Jensen)', nil],
+
+ 'ldap://ldap.itd.umich.edu/c=GB?objectClass?one' =>
+ ['ldap', 'ldap.itd.umich.edu', URI::LDAP::DEFAULT_PORT,
+ 'c=GB',
+ 'objectClass', 'one', nil, nil],
+
+ 'ldap://ldap.question.com/o=Question%3f,c=US?mail' =>
+ ['ldap', 'ldap.question.com', URI::LDAP::DEFAULT_PORT,
+ 'o=Question%3f,c=US',
+ 'mail', nil, nil, nil],
+
+ 'ldap://ldap.netscape.com/o=Babsco,c=US??(int=%5c00%5c00%5c00%5c04)' =>
+ ['ldap', 'ldap.netscape.com', URI::LDAP::DEFAULT_PORT,
+ 'o=Babsco,c=US',
+ nil, '(int=%5c00%5c00%5c00%5c04)', nil, nil],
+
+ 'ldap:///??sub??bindname=cn=Manager%2co=Foo' =>
+ ['ldap', nil, URI::LDAP::DEFAULT_PORT,
+ '',
+ nil, 'sub', nil, 'bindname=cn=Manager%2co=Foo'],
+
+ 'ldap:///??sub??!bindname=cn=Manager%2co=Foo' =>
+ ['ldap', nil, URI::LDAP::DEFAULT_PORT,
+ '',
+ nil, 'sub', nil, '!bindname=cn=Manager%2co=Foo'],
+ }.each do |url2, ary|
+ u = URI.parse(url2)
+ assert_equal(ary, uri_to_ary(u))
+ end
+ end
+
+ def test_select
+ u = URI.parse('ldap:///??sub??!bindname=cn=Manager%2co=Foo')
+ assert_equal(uri_to_ary(u), u.select(*u.component))
+ assert_raise(ArgumentError) do
+ u.select(:scheme, :host, :not_exist, :port)
+ end
+ end
+end
+
+
+end
Added: MacRuby/trunk/test/test-mri/test/uri/test_mailto.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/uri/test_mailto.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/uri/test_mailto.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,122 @@
+require 'test/unit'
+require 'uri/mailto'
+
+module URI
+
+
+class TestMailTo < Test::Unit::TestCase
+ def setup
+ @u = URI::MailTo
+ end
+
+ def teardown
+ end
+
+ def uri_to_ary(uri)
+ uri.class.component.collect {|c| uri.send(c)}
+ end
+
+ def test_build
+ ok = []
+ bad = []
+
+ # RFC2368, 6. Examples
+ # mailto:chris at example.com
+ ok << ["mailto:chris at example.com"]
+ ok[-1] << ["chris at example.com", nil]
+ ok[-1] << {:to => "chris at example.com"}
+
+ # mailto:infobot at example.com?subject=current-issue
+ ok << ["mailto:infobot at example.com?subject=current-issue"]
+ ok[-1] << ["infobot at example.com", ["subject=current-issue"]]
+ ok[-1] << {:to => "infobot at example.com",
+ :headers => ["subject=current-issue"]}
+
+ # mailto:infobot at example.com?body=send%20current-issue
+ ok << ["mailto:infobot at example.com?body=send%20current-issue"]
+ ok[-1] << ["infobot at example.com", ["body=send%20current-issue"]]
+ ok[-1] << {:to => "infobot at example.com",
+ :headers => ["body=send%20current-issue"]}
+
+ # mailto:infobot at example.com?body=send%20current-issue%0D%0Asend%20index
+ ok << ["mailto:infobot at example.com?body=send%20current-issue%0D%0Asend%20index"]
+ ok[-1] << ["infobot at example.com",
+ ["body=send%20current-issue%0D%0Asend%20index"]]
+ ok[-1] << {:to => "infobot at example.com",
+ :headers => ["body=send%20current-issue%0D%0Asend%20index"]}
+
+ # mailto:foobar at example.com?In-Reply-To=%3c3469A91.D10AF4C at example.com
+ ok << ["mailto:foobar at example.com?In-Reply-To=%3c3469A91.D10AF4C at example.com"]
+ ok[-1] << ["foobar at example.com",
+ ["In-Reply-To=%3c3469A91.D10AF4C at example.com"]]
+ ok[-1] << {:to => "foobar at example.com",
+ :headers => ["In-Reply-To=%3c3469A91.D10AF4C at example.com"]}
+
+ # mailto:majordomo at example.com?body=subscribe%20bamboo-l
+ ok << ["mailto:majordomo at example.com?body=subscribe%20bamboo-l"]
+ ok[-1] << ["majordomo at example.com", ["body=subscribe%20bamboo-l"]]
+ ok[-1] << {:to => "majordomo at example.com",
+ :headers => ["body=subscribe%20bamboo-l"]}
+
+ # mailto:joe at example.com?cc=bob at example.com&body=hello
+ ok << ["mailto:joe at example.com?cc=bob at example.com&body=hello"]
+ ok[-1] << ["joe at example.com", ["cc=bob at example.com", "body=hello"]]
+ ok[-1] << {:to => "joe at example.com",
+ :headers => ["cc=bob at example.com", "body=hello"]}
+
+ # mailto:?to=joe at example.com&cc=bob at example.com&body=hello
+ ok << ["mailto:?to=joe at example.com&cc=bob at example.com&body=hello"]
+ ok[-1] << [nil,
+ ["to=joe at example.com", "cc=bob at example.com", "body=hello"]]
+ ok[-1] << {:headers => ["to=joe at example.com",
+ "cc=bob at example.com", "body=hello"]}
+
+ # mailto:gorby%25kremvax at example.com
+ ok << ["mailto:gorby%25kremvax at example.com"]
+ ok[-1] << ["gorby%25kremvax at example.com", nil]
+ ok[-1] << {:to => "gorby%25kremvax at example.com"}
+
+ # mailto:unlikely%3Faddress at example.com?blat=foop
+ ok << ["mailto:unlikely%3Faddress at example.com?blat=foop"]
+ ok[-1] << ["unlikely%3Faddress at example.com", ["blat=foop"]]
+ ok[-1] << {:to => "unlikely%3Faddress at example.com",
+ :headers => ["blat=foop"]}
+
+ ok_all = ok.flatten.join("\0")
+
+ # mailto:joe at example.com?cc=bob at example.com?body=hello ; WRONG!
+ bad << ["joe at example.com", ["cc=bob at example.com?body=hello"]]
+
+ # mailto:javascript:alert()
+ bad << ["javascript:alert()", []]
+
+ # '=' which is in hname or hvalue is wrong.
+ bad << ["foo at example.jp?subject=1+1=2", []]
+
+ ok.each do |x|
+ assert_equal(x[0],
+ @u.build(x[1]).to_s)
+ assert_equal(x[0],
+ @u.build(x[2]).to_s)
+ end
+
+ bad.each do |x|
+ assert_raise(URI::InvalidComponentError) {
+ @u.build(x)
+ }
+ end
+
+ assert_equal(ok_all, ok.flatten.join("\0"))
+ end
+
+ def test_select
+ u = URI.parse('mailto:joe at example.com?cc=bob at example.com&body=hello')
+ assert_equal(uri_to_ary(u), u.select(*u.component))
+ assert_raise(ArgumentError) do
+ u.select(:scheme, :host, :not_exist, :port)
+ end
+ end
+end
+
+
+end
Added: MacRuby/trunk/test/test-mri/test/uri/test_parser.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/uri/test_parser.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/uri/test_parser.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,41 @@
+require 'test/unit'
+require 'uri'
+
+class URI::TestParser < Test::Unit::TestCase
+ def uri_to_ary(uri)
+ uri.class.component.collect {|c| uri.send(c)}
+ end
+
+ def test_compare
+ url = 'http://a/b/c/d;p?q'
+ u0 = URI.parse(url)
+ u1 = URI.parse(url)
+ p = URI::Parser.new
+ u2 = p.parse(url)
+ u3 = p.parse(url)
+
+ assert(u0 == u1)
+ assert(u0.eql?(u1))
+ assert(!u0.equal?(u1))
+
+ assert(u1 == u2)
+ assert(!u1.eql?(u2))
+ assert(!u1.equal?(u2))
+
+ assert(u2 == u3)
+ assert(u2.eql?(u3))
+ assert(!u2.equal?(u3))
+ end
+
+ def test_parse
+ escaped = URI::REGEXP::PATTERN::ESCAPED
+ hex = URI::REGEXP::PATTERN::HEX
+ p1 = URI::Parser.new(:ESCAPED => "(?:#{escaped}|%u[#{hex}]{4})")
+ u1 = p1.parse('http://a/b/%uABCD')
+ assert_equal(['http', nil, 'a', URI::HTTP.default_port, '/b/%uABCD', nil, nil],
+ uri_to_ary(u1))
+ u1.path = '/%uDCBA'
+ assert_equal(['http', nil, 'a', URI::HTTP.default_port, '/%uDCBA', nil, nil],
+ uri_to_ary(u1))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/.htaccess
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/.htaccess (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/.htaccess 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+this file should not be published.
Added: MacRuby/trunk/test/test-mri/test/webrick/test_cgi.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/test_cgi.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/test_cgi.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,137 @@
+require_relative "utils"
+require "webrick"
+require "test/unit"
+
+class TestWEBrickCGI < Test::Unit::TestCase
+ CRLF = "\r\n"
+
+ def start_cgi_server(&block)
+ config = {
+ :CGIInterpreter => TestWEBrick::RubyBin,
+ :DocumentRoot => File.dirname(__FILE__),
+ :DirectoryIndex => ["webrick.cgi"],
+ :RequestHandler => Proc.new{|req, res|
+ def req.meta_vars
+ meta = super
+ meta["RUBYLIB"] = $:.join(File::PATH_SEPARATOR)
+ return meta
+ end
+ },
+ }
+ if RUBY_PLATFORM =~ /mswin32|mingw|cygwin|bccwin32/
+ config[:CGIPathEnv] = ENV['PATH'] # runtime dll may not be in system dir.
+ end
+ TestWEBrick.start_httpserver(config){|server, addr, port, log|
+ block.call(server, addr, port, log)
+ }
+ end
+
+ def test_cgi
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ start_cgi_server{|server, addr, port, log|
+ http = Net::HTTP.new(addr, port)
+ req = Net::HTTP::Get.new("/webrick.cgi")
+ http.request(req){|res| assert_equal("/webrick.cgi", res.body, log.call)}
+ req = Net::HTTP::Get.new("/webrick.cgi/path/info")
+ http.request(req){|res| assert_equal("/path/info", res.body, log.call)}
+ req = Net::HTTP::Get.new("/webrick.cgi/%3F%3F%3F?foo=bar")
+ http.request(req){|res| assert_equal("/???", res.body, log.call)}
+ req = Net::HTTP::Get.new("/webrick.cgi/%A4%DB%A4%B2/%A4%DB%A4%B2")
+ http.request(req){|res|
+ assert_equal("/\xA4\xDB\xA4\xB2/\xA4\xDB\xA4\xB2", res.body, log.call)}
+ req = Net::HTTP::Get.new("/webrick.cgi?a=1;a=2;b=x")
+ http.request(req){|res| assert_equal("a=1, a=2, b=x", res.body, log.call)}
+ req = Net::HTTP::Get.new("/webrick.cgi?a=1&a=2&b=x")
+ http.request(req){|res| assert_equal("a=1, a=2, b=x", res.body, log.call)}
+
+ req = Net::HTTP::Post.new("/webrick.cgi?a=x;a=y;b=1")
+ req["Content-Type"] = "application/x-www-form-urlencoded"
+ http.request(req, "a=1;a=2;b=x"){|res|
+ assert_equal("a=1, a=2, b=x", res.body, log.call)}
+ req = Net::HTTP::Post.new("/webrick.cgi?a=x&a=y&b=1")
+ req["Content-Type"] = "application/x-www-form-urlencoded"
+ http.request(req, "a=1&a=2&b=x"){|res|
+ assert_equal("a=1, a=2, b=x", res.body, log.call)}
+ req = Net::HTTP::Get.new("/")
+ http.request(req){|res|
+ ary = res.body.lines.to_a
+ assert_match(%r{/$}, ary[0], log.call)
+ assert_match(%r{/webrick.cgi$}, ary[1], log.call)
+ }
+
+ req = Net::HTTP::Get.new("/webrick.cgi")
+ req["Cookie"] = "CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001"
+ http.request(req){|res|
+ assert_equal(
+ "CUSTOMER=WILE_E_COYOTE\nPART_NUMBER=ROCKET_LAUNCHER_0001\n",
+ res.body, log.call)
+ }
+
+ req = Net::HTTP::Get.new("/webrick.cgi")
+ cookie = %{$Version="1"; }
+ cookie << %{Customer="WILE_E_COYOTE"; $Path="/acme"; }
+ cookie << %{Part_Number="Rocket_Launcher_0001"; $Path="/acme"; }
+ cookie << %{Shipping="FedEx"; $Path="/acme"}
+ req["Cookie"] = cookie
+ http.request(req){|res|
+ assert_equal("Customer=WILE_E_COYOTE, Shipping=FedEx",
+ res["Set-Cookie"], log.call)
+ assert_equal("Customer=WILE_E_COYOTE\n" +
+ "Part_Number=Rocket_Launcher_0001\n" +
+ "Shipping=FedEx\n", res.body, log.call)
+ }
+ }
+ end
+
+ def test_bad_request
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ start_cgi_server{|server, addr, port, log|
+ sock = TCPSocket.new(addr, port)
+ begin
+ sock << "POST /webrick.cgi HTTP/1.0" << CRLF
+ sock << "Content-Type: application/x-www-form-urlencoded" << CRLF
+ sock << "Content-Length: 1024" << CRLF
+ sock << CRLF
+ sock << "a=1&a=2&b=x"
+ sock.close_write
+ assert_match(%r{\AHTTP/\d.\d 400 Bad Request}, sock.read, log.call)
+ ensure
+ sock.close
+ end
+ }
+ end
+
+ CtrlSeq = [0x7f, *(1..31)].pack("C*").gsub(/\s+/, '')
+ CtrlPat = /#{Regexp.quote(CtrlSeq)}/o
+ DumpPat = /#{Regexp.quote(CtrlSeq.dump[1...-1])}/o
+
+ def test_bad_uri
+ start_cgi_server{|server, addr, port, log|
+ res = TCPSocket.open(addr, port) {|sock|
+ sock << "GET /#{CtrlSeq}#{CRLF}#{CRLF}"
+ sock.close_write
+ sock.read
+ }
+ assert_match(%r{\AHTTP/\d.\d 400 Bad Request}, res)
+ s = log.call.each_line.grep(/ERROR bad URI/)[0]
+ assert_match(DumpPat, s)
+ assert_not_match(CtrlPat, s)
+ }
+ end
+
+ def test_bad_header
+ start_cgi_server{|server, addr, port, log|
+ res = TCPSocket.open(addr, port) {|sock|
+ sock << "GET / HTTP/1.0#{CRLF}#{CtrlSeq}#{CRLF}#{CRLF}"
+ sock.close_write
+ sock.read
+ }
+ assert_match(%r{\AHTTP/\d.\d 400 Bad Request}, res)
+ s = log.call.each_line.grep(/ERROR bad header/)[0]
+ assert_match(DumpPat, s)
+ assert_not_match(CtrlPat, s)
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/test_cookie.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/test_cookie.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/test_cookie.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,104 @@
+require "test/unit"
+require "webrick/cookie"
+
+class TestWEBrickCookie < Test::Unit::TestCase
+ def test_new
+ cookie = WEBrick::Cookie.new("foo","bar")
+ assert_equal("foo", cookie.name)
+ assert_equal("bar", cookie.value)
+ assert_equal("foo=bar", cookie.to_s)
+ end
+
+ def test_time
+ cookie = WEBrick::Cookie.new("foo","bar")
+ t = 1000000000
+ cookie.max_age = t
+ assert_match(t.to_s, cookie.to_s)
+
+ cookie = WEBrick::Cookie.new("foo","bar")
+ t = Time.at(1000000000)
+ cookie.expires = t
+ assert_equal(Time, cookie.expires.class)
+ assert_equal(t, cookie.expires)
+ ts = t.httpdate
+ cookie.expires = ts
+ assert_equal(Time, cookie.expires.class)
+ assert_equal(t, cookie.expires)
+ assert_match(ts, cookie.to_s)
+ end
+
+ def test_parse
+ data = ""
+ data << '$Version="1"; '
+ data << 'Customer="WILE_E_COYOTE"; $Path="/acme"; '
+ data << 'Part_Number="Rocket_Launcher_0001"; $Path="/acme"; '
+ data << 'Shipping="FedEx"; $Path="/acme"'
+ cookies = WEBrick::Cookie.parse(data)
+ assert_equal(1, cookies[0].version)
+ assert_equal("Customer", cookies[0].name)
+ assert_equal("WILE_E_COYOTE", cookies[0].value)
+ assert_equal("/acme", cookies[0].path)
+ assert_equal(1, cookies[1].version)
+ assert_equal("Part_Number", cookies[1].name)
+ assert_equal("Rocket_Launcher_0001", cookies[1].value)
+ assert_equal(1, cookies[2].version)
+ assert_equal("Shipping", cookies[2].name)
+ assert_equal("FedEx", cookies[2].value)
+
+ data = "hoge=moge; __div__session=9865ecfd514be7f7"
+ cookies = WEBrick::Cookie.parse(data)
+ assert_equal(0, cookies[0].version)
+ assert_equal("hoge", cookies[0].name)
+ assert_equal("moge", cookies[0].value)
+ assert_equal("__div__session", cookies[1].name)
+ assert_equal("9865ecfd514be7f7", cookies[1].value)
+ end
+
+ def test_parse_set_cookie
+ data = %(Customer="WILE_E_COYOTE"; Version="1"; Path="/acme")
+ cookie = WEBrick::Cookie.parse_set_cookie(data)
+ assert_equal("Customer", cookie.name)
+ assert_equal("WILE_E_COYOTE", cookie.value)
+ assert_equal(1, cookie.version)
+ assert_equal("/acme", cookie.path)
+
+ data = %(Shipping="FedEx"; Version="1"; Path="/acme"; Secure)
+ cookie = WEBrick::Cookie.parse_set_cookie(data)
+ assert_equal("Shipping", cookie.name)
+ assert_equal("FedEx", cookie.value)
+ assert_equal(1, cookie.version)
+ assert_equal("/acme", cookie.path)
+ assert_equal(true, cookie.secure)
+ end
+
+ def test_parse_set_cookies
+ data = %(Shipping="FedEx"; Version="1"; Path="/acme"; Secure)
+ data << %(, CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT; path=/; Secure)
+ data << %(, name="Aaron"; Version="1"; path="/acme")
+ cookies = WEBrick::Cookie.parse_set_cookies(data)
+ assert_equal(3, cookies.length)
+
+ fed_ex = cookies.find { |c| c.name == 'Shipping' }
+ assert_not_nil(fed_ex)
+ assert_equal("Shipping", fed_ex.name)
+ assert_equal("FedEx", fed_ex.value)
+ assert_equal(1, fed_ex.version)
+ assert_equal("/acme", fed_ex.path)
+ assert_equal(true, fed_ex.secure)
+
+ name = cookies.find { |c| c.name == 'name' }
+ assert_not_nil(name)
+ assert_equal("name", name.name)
+ assert_equal("Aaron", name.value)
+ assert_equal(1, name.version)
+ assert_equal("/acme", name.path)
+
+ customer = cookies.find { |c| c.name == 'CUSTOMER' }
+ assert_not_nil(customer)
+ assert_equal("CUSTOMER", customer.name)
+ assert_equal("WILE_E_COYOTE", customer.value)
+ assert_equal(0, customer.version)
+ assert_equal("/", customer.path)
+ assert_equal(Time.utc(1999, 11, 9, 23, 12, 40), customer.expires)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/test_filehandler.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/test_filehandler.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/test_filehandler.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,272 @@
+require "test/unit"
+require_relative "utils.rb"
+require "webrick"
+require "stringio"
+
+class WEBrick::TestFileHandler < Test::Unit::TestCase
+ def default_file_handler(filename)
+ klass = WEBrick::HTTPServlet::DefaultFileHandler
+ klass.new(WEBrick::Config::HTTP, filename)
+ end
+
+ def windows?
+ File.directory?("\\")
+ end
+
+ def get_res_body(res)
+ if defined? res.body.read
+ res.body.read
+ else
+ res.body
+ end
+ end
+
+ def make_range_request(range_spec)
+ msg = <<-_end_of_request_
+ GET / HTTP/1.0
+ Range: #{range_spec}
+
+ _end_of_request_
+ return StringIO.new(msg.gsub(/^ {6}/, ""))
+ end
+
+ def make_range_response(file, range_spec)
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(make_range_request(range_spec))
+ res = WEBrick::HTTPResponse.new(WEBrick::Config::HTTP)
+ size = File.size(file)
+ handler = default_file_handler(file)
+ handler.make_partial_content(req, res, file, size)
+ return res
+ end
+
+ def test_make_partial_content
+ filename = __FILE__
+ filesize = File.size(filename)
+
+ res = make_range_response(filename, "bytes=#{filesize-100}-")
+ assert_match(%r{^text/plain}, res["content-type"])
+ assert_equal(get_res_body(res).size, 100)
+
+ res = make_range_response(filename, "bytes=-100")
+ assert_match(%r{^text/plain}, res["content-type"])
+ assert_equal(get_res_body(res).size, 100)
+
+ res = make_range_response(filename, "bytes=0-99")
+ assert_match(%r{^text/plain}, res["content-type"])
+ assert_equal(get_res_body(res).size, 100)
+
+ res = make_range_response(filename, "bytes=100-199")
+ assert_match(%r{^text/plain}, res["content-type"])
+ assert_equal(get_res_body(res).size, 100)
+
+ res = make_range_response(filename, "bytes=0-0")
+ assert_match(%r{^text/plain}, res["content-type"])
+ assert_equal(get_res_body(res).size, 1)
+
+ res = make_range_response(filename, "bytes=-1")
+ assert_match(%r{^text/plain}, res["content-type"])
+ assert_equal(get_res_body(res).size, 1)
+
+ res = make_range_response(filename, "bytes=0-0, -2")
+ assert_match(%r{^multipart/byteranges}, res["content-type"])
+ end
+
+ def test_filehandler
+ config = { :DocumentRoot => File.dirname(__FILE__), }
+ this_file = File.basename(__FILE__)
+ filesize = File.size(__FILE__)
+ this_data = File.open(__FILE__, "rb") {|f| f.read}
+ range = nil
+ bug2593 = '[ruby-dev:40030]'
+
+ TestWEBrick.start_httpserver(config) do |server, addr, port, log|
+ http = Net::HTTP.new(addr, port)
+ req = Net::HTTP::Get.new("/")
+ http.request(req){|res|
+ assert_equal("200", res.code, log.call)
+ assert_equal("text/html", res.content_type, log.call)
+ assert_match(/HREF="#{this_file}"/, res.body, log.call)
+ }
+ req = Net::HTTP::Get.new("/#{this_file}")
+ http.request(req){|res|
+ assert_equal("200", res.code, log.call)
+ assert_equal("text/plain", res.content_type, log.call)
+ assert_equal(File.read(__FILE__), res.body, log.call)
+ }
+
+ req = Net::HTTP::Get.new("/#{this_file}", "range"=>"bytes=#{filesize-100}-")
+ http.request(req){|res|
+ assert_equal("206", res.code, log.call)
+ assert_equal("text/plain", res.content_type, log.call)
+ assert_nothing_raised(bug2593) {range = res.content_range}
+ assert_equal((filesize-100)..(filesize-1), range, log.call)
+ assert_equal(this_data[-100..-1], res.body, log.call)
+ }
+
+ req = Net::HTTP::Get.new("/#{this_file}", "range"=>"bytes=-100")
+ http.request(req){|res|
+ assert_equal("206", res.code, log.call)
+ assert_equal("text/plain", res.content_type, log.call)
+ assert_nothing_raised(bug2593) {range = res.content_range}
+ assert_equal((filesize-100)..(filesize-1), range, log.call)
+ assert_equal(this_data[-100..-1], res.body, log.call)
+ }
+
+ req = Net::HTTP::Get.new("/#{this_file}", "range"=>"bytes=0-99")
+ http.request(req){|res|
+ assert_equal("206", res.code, log.call)
+ assert_equal("text/plain", res.content_type, log.call)
+ assert_nothing_raised(bug2593) {range = res.content_range}
+ assert_equal(0..99, range, log.call)
+ assert_equal(this_data[0..99], res.body, log.call)
+ }
+
+ req = Net::HTTP::Get.new("/#{this_file}", "range"=>"bytes=100-199")
+ http.request(req){|res|
+ assert_equal("206", res.code, log.call)
+ assert_equal("text/plain", res.content_type, log.call)
+ assert_nothing_raised(bug2593) {range = res.content_range}
+ assert_equal(100..199, range, log.call)
+ assert_equal(this_data[100..199], res.body, log.call)
+ }
+
+ req = Net::HTTP::Get.new("/#{this_file}", "range"=>"bytes=0-0")
+ http.request(req){|res|
+ assert_equal("206", res.code, log.call)
+ assert_equal("text/plain", res.content_type, log.call)
+ assert_nothing_raised(bug2593) {range = res.content_range}
+ assert_equal(0..0, range, log.call)
+ assert_equal(this_data[0..0], res.body, log.call)
+ }
+
+ req = Net::HTTP::Get.new("/#{this_file}", "range"=>"bytes=-1")
+ http.request(req){|res|
+ assert_equal("206", res.code, log.call)
+ assert_equal("text/plain", res.content_type, log.call)
+ assert_nothing_raised(bug2593) {range = res.content_range}
+ assert_equal((filesize-1)..(filesize-1), range, log.call)
+ assert_equal(this_data[-1, 1], res.body, log.call)
+ }
+
+ req = Net::HTTP::Get.new("/#{this_file}", "range"=>"bytes=0-0, -2")
+ http.request(req){|res|
+ assert_equal("206", res.code, log.call)
+ assert_equal("multipart/byteranges", res.content_type, log.call)
+ }
+
+ end
+ end
+
+ def test_non_disclosure_name
+ config = { :DocumentRoot => File.dirname(__FILE__), }
+ this_file = File.basename(__FILE__)
+ TestWEBrick.start_httpserver(config) do |server, addr, port, log|
+ http = Net::HTTP.new(addr, port)
+ doc_root_opts = server[:DocumentRootOptions]
+ doc_root_opts[:NondisclosureName] = %w(.ht* *~ test_*)
+ req = Net::HTTP::Get.new("/")
+ http.request(req){|res|
+ assert_equal("200", res.code, log.call)
+ assert_equal("text/html", res.content_type, log.call)
+ assert_no_match(/HREF="#{File.basename(__FILE__)}"/, res.body)
+ }
+ req = Net::HTTP::Get.new("/#{this_file}")
+ http.request(req){|res|
+ assert_equal("404", res.code, log.call)
+ }
+ doc_root_opts[:NondisclosureName] = %w(.ht* *~ TEST_*)
+ http.request(req){|res|
+ assert_equal("404", res.code, log.call)
+ }
+ end
+ end
+
+ def test_directory_traversal
+ config = { :DocumentRoot => File.dirname(__FILE__), }
+ this_file = File.basename(__FILE__)
+ TestWEBrick.start_httpserver(config) do |server, addr, port, log|
+ http = Net::HTTP.new(addr, port)
+ req = Net::HTTP::Get.new("/../../")
+ http.request(req){|res| assert_equal("400", res.code, log.call) }
+ req = Net::HTTP::Get.new("/..%5c../#{File.basename(__FILE__)}")
+ http.request(req){|res| assert_equal(windows? ? "200" : "404", res.code, log.call) }
+ req = Net::HTTP::Get.new("/..%5c..%5cruby.c")
+ http.request(req){|res| assert_equal("404", res.code, log.call) }
+ end
+ end
+
+ def test_unwise_in_path
+ if windows?
+ config = { :DocumentRoot => File.dirname(__FILE__), }
+ this_file = File.basename(__FILE__)
+ TestWEBrick.start_httpserver(config) do |server, addr, port, log|
+ http = Net::HTTP.new(addr, port)
+ req = Net::HTTP::Get.new("/..%5c..")
+ http.request(req){|res| assert_equal("301", res.code, log.call) }
+ end
+ end
+ end
+
+ def test_short_filename
+ config = {
+ :CGIInterpreter => TestWEBrick::RubyBin,
+ :DocumentRoot => File.dirname(__FILE__),
+ :CGIPathEnv => ENV['PATH'],
+ }
+ TestWEBrick.start_httpserver(config) do |server, addr, port, log|
+ http = Net::HTTP.new(addr, port)
+
+ req = Net::HTTP::Get.new("/webric~1.cgi/test")
+ http.request(req) do |res|
+ if windows?
+ assert_equal("200", res.code, log.call)
+ assert_equal("/test", res.body, log.call)
+ else
+ assert_equal("404", res.code, log.call)
+ end
+ end
+
+ req = Net::HTTP::Get.new("/.htaccess")
+ http.request(req) {|res| assert_equal("404", res.code, log.call) }
+ req = Net::HTTP::Get.new("/htacce~1")
+ http.request(req) {|res| assert_equal("404", res.code, log.call) }
+ req = Net::HTTP::Get.new("/HTACCE~1")
+ http.request(req) {|res| assert_equal("404", res.code, log.call) }
+ end
+ end
+
+ def test_script_disclosure
+ skip("[BUG : #???] Timeout, MacRuby don't finish")
+
+ config = {
+ :CGIInterpreter => TestWEBrick::RubyBin,
+ :DocumentRoot => File.dirname(__FILE__),
+ :CGIPathEnv => ENV['PATH'],
+ }
+ TestWEBrick.start_httpserver(config) do |server, addr, port, log|
+ http = Net::HTTP.new(addr, port)
+
+ req = Net::HTTP::Get.new("/webrick.cgi/test")
+ http.request(req) do |res|
+ assert_equal("200", res.code, log.call)
+ assert_equal("/test", res.body, log.call)
+ end
+
+ response_assertion = Proc.new do |res|
+ if windows?
+ assert_equal("200", res.code, log.call)
+ assert_equal("/test", res.body, log.call)
+ else
+ assert_equal("404", res.code, log.call)
+ end
+ end
+ req = Net::HTTP::Get.new("/webrick.cgi%20/test")
+ http.request(req, &response_assertion)
+ req = Net::HTTP::Get.new("/webrick.cgi./test")
+ http.request(req, &response_assertion)
+ req = Net::HTTP::Get.new("/webrick.cgi::$DATA/test")
+ http.request(req, &response_assertion)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/test_httpauth.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/test_httpauth.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/test_httpauth.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,82 @@
+require "test/unit"
+require "net/http"
+require "tempfile"
+require "webrick"
+require "webrick/httpauth/basicauth"
+require_relative "utils"
+
+class TestWEBrickHTTPAuth < Test::Unit::TestCase
+ def test_basic_auth
+ TestWEBrick.start_httpserver{|server, addr, port, log|
+ realm = "WEBrick's realm"
+ path = "/basic_auth"
+
+ server.mount_proc(path){|req, res|
+ WEBrick::HTTPAuth.basic_auth(req, res, realm){|user, pass|
+ user == "webrick" && pass == "supersecretpassword"
+ }
+ res.body = "hoge"
+ }
+ http = Net::HTTP.new(addr, port)
+ g = Net::HTTP::Get.new(path)
+ g.basic_auth("webrick", "supersecretpassword")
+ http.request(g){|res| assert_equal("hoge", res.body, log.call)}
+ g.basic_auth("webrick", "not super")
+ http.request(g){|res| assert_not_equal("hoge", res.body, log.call)}
+ }
+ end
+
+ def test_basic_auth2
+ TestWEBrick.start_httpserver{|server, addr, port, log|
+ realm = "WEBrick's realm"
+ path = "/basic_auth2"
+
+ tmpfile = Tempfile.new("test_webrick_auth")
+ tmpfile.close
+ tmp_pass = WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
+ tmp_pass.set_passwd(realm, "webrick", "supersecretpassword")
+ tmp_pass.set_passwd(realm, "foo", "supersecretpassword")
+ tmp_pass.flush
+
+ htpasswd = WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
+ users = []
+ htpasswd.each{|user, pass| users << user }
+ assert_equal(2, users.size, log.call)
+ assert(users.member?("webrick"), log.call)
+ assert(users.member?("foo"), log.call)
+
+ server.mount_proc(path){|req, res|
+ auth = WEBrick::HTTPAuth::BasicAuth.new(
+ :Realm => realm, :UserDB => htpasswd,
+ :Logger => server.logger
+ )
+ auth.authenticate(req, res)
+ res.body = "hoge"
+ }
+ http = Net::HTTP.new(addr, port)
+ g = Net::HTTP::Get.new(path)
+ g.basic_auth("webrick", "supersecretpassword")
+ http.request(g){|res| assert_equal("hoge", res.body, log.call)}
+ g.basic_auth("webrick", "not super")
+ http.request(g){|res| assert_not_equal("hoge", res.body, log.call)}
+ }
+ end
+
+ def test_basic_auth3
+ tmpfile = Tempfile.new("test_webrick_auth")
+ tmpfile.puts("webrick:{SHA}GJYFRpBbdchp595jlh3Bhfmgp8k=")
+ tmpfile.flush
+ assert_raise(NotImplementedError){
+ WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
+ }
+ tmpfile.close(true)
+
+ tmpfile = Tempfile.new("test_webrick_auth")
+ tmpfile.puts("webrick:$apr1$IOVMD/..$rmnOSPXr0.wwrLPZHBQZy0")
+ tmpfile.flush
+ assert_raise(NotImplementedError){
+ WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
+ }
+ tmpfile.close(true)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/test_httpproxy.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/test_httpproxy.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/test_httpproxy.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,281 @@
+require "test/unit"
+require "net/http"
+require "webrick"
+require "webrick/httpproxy"
+begin
+ require "webrick/ssl"
+ require "net/https"
+ require File.expand_path("../openssl/utils.rb", File.dirname(__FILE__))
+rescue LoadError
+ # test_connect will be skipped
+end
+require File.expand_path("utils.rb", File.dirname(__FILE__))
+
+class TestWEBrickHTTPProxy < Test::Unit::TestCase
+ def test_fake_proxy
+ assert_nil(WEBrick::FakeProxyURI.scheme)
+ assert_nil(WEBrick::FakeProxyURI.host)
+ assert_nil(WEBrick::FakeProxyURI.port)
+ assert_nil(WEBrick::FakeProxyURI.path)
+ assert_nil(WEBrick::FakeProxyURI.userinfo)
+ assert_raise(NoMethodError){ WEBrick::FakeProxyURI.foo }
+ end
+
+ def test_proxy
+ # Testing GET or POST to the proxy server
+ # Note that the proxy server works as the origin server.
+ # +------+
+ # V |
+ # client -------> proxy ---+
+ # GET / POST GET / POST
+ #
+ proxy_handler_called = request_handler_called = 0
+ config = {
+ :ServerName => "localhost.localdomain",
+ :ProxyContentHandler => Proc.new{|req, res| proxy_handler_called += 1 },
+ :RequestHandler => Proc.new{|req, res| request_handler_called += 1 }
+ }
+ TestWEBrick.start_httpproxy(config){|server, addr, port, log|
+ server.mount_proc("/"){|req, res|
+ res.body = "#{req.request_method} #{req.path} #{req.body}"
+ }
+ http = Net::HTTP.new(addr, port, addr, port)
+
+ req = Net::HTTP::Get.new("/")
+ http.request(req){|res|
+ assert_equal("1.1 localhost.localdomain:#{port}", res["via"], log.call)
+ assert_equal("GET / ", res.body, log.call)
+ }
+ assert_equal(1, proxy_handler_called, log.call)
+ assert_equal(2, request_handler_called, log.call)
+
+ req = Net::HTTP::Head.new("/")
+ http.request(req){|res|
+ assert_equal("1.1 localhost.localdomain:#{port}", res["via"], log.call)
+ assert_nil(res.body, log.call)
+ }
+ assert_equal(2, proxy_handler_called, log.call)
+ assert_equal(4, request_handler_called, log.call)
+
+ req = Net::HTTP::Post.new("/")
+ req.body = "post-data"
+ http.request(req){|res|
+ assert_equal("1.1 localhost.localdomain:#{port}", res["via"], log.call)
+ assert_equal("POST / post-data", res.body, log.call)
+ }
+ assert_equal(3, proxy_handler_called, log.call)
+ assert_equal(6, request_handler_called, log.call)
+ }
+ end
+
+ def test_no_proxy
+ # Testing GET or POST to the proxy server without proxy request.
+ #
+ # client -------> proxy
+ # GET / POST
+ #
+ proxy_handler_called = request_handler_called = 0
+ config = {
+ :ServerName => "localhost.localdomain",
+ :ProxyContentHandler => Proc.new{|req, res| proxy_handler_called += 1 },
+ :RequestHandler => Proc.new{|req, res| request_handler_called += 1 }
+ }
+ TestWEBrick.start_httpproxy(config){|server, addr, port, log|
+ server.mount_proc("/"){|req, res|
+ res.body = "#{req.request_method} #{req.path} #{req.body}"
+ }
+ http = Net::HTTP.new(addr, port)
+
+ req = Net::HTTP::Get.new("/")
+ http.request(req){|res|
+ assert_nil(res["via"], log.call)
+ assert_equal("GET / ", res.body, log.call)
+ }
+ assert_equal(0, proxy_handler_called, log.call)
+ assert_equal(1, request_handler_called, log.call)
+
+ req = Net::HTTP::Head.new("/")
+ http.request(req){|res|
+ assert_nil(res["via"], log.call)
+ assert_nil(res.body, log.call)
+ }
+ assert_equal(0, proxy_handler_called, log.call)
+ assert_equal(2, request_handler_called, log.call)
+
+ req = Net::HTTP::Post.new("/")
+ req.body = "post-data"
+ http.request(req){|res|
+ assert_nil(res["via"], log.call)
+ assert_equal("POST / post-data", res.body, log.call)
+ }
+ assert_equal(0, proxy_handler_called, log.call)
+ assert_equal(3, request_handler_called, log.call)
+ }
+ end
+
+ def make_certificate(key, cn)
+ subject = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=#{cn}")
+ exts = [
+ ["keyUsage", "keyEncipherment,digitalSignature", true],
+ ]
+ cert = OpenSSL::TestUtils.issue_cert(
+ subject, key, 1, Time.now, Time.now + 3600, exts,
+ nil, nil, OpenSSL::Digest::SHA1.new
+ )
+ return cert
+ end
+
+ def test_connect
+ # Testing CONNECT to proxy server
+ #
+ # client -----------> proxy -----------> https
+ # 1. CONNECT establish TCP
+ # 2. ---- establish SSL session --->
+ # 3. ------- GET or POST ---------->
+ #
+ key = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ cert = make_certificate(key, "127.0.0.1")
+ s_config = {
+ :SSLEnable =>true,
+ :ServerName => "localhost",
+ :SSLCertificate => cert,
+ :SSLPrivateKey => key,
+ }
+ config = {
+ :ServerName => "localhost.localdomain",
+ :RequestHandler => Proc.new{|req, res|
+ assert_equal("CONNECT", req.request_method)
+ },
+ }
+ TestWEBrick.start_httpserver(s_config){|s_server, s_addr, s_port, s_log|
+ s_server.mount_proc("/"){|req, res|
+ res.body = "SSL #{req.request_method} #{req.path} #{req.body}"
+ }
+ TestWEBrick.start_httpproxy(config){|server, addr, port, log|
+ http = Net::HTTP.new("127.0.0.1", s_port, addr, port)
+ http.use_ssl = true
+ http.verify_callback = Proc.new do |preverify_ok, store_ctx|
+ store_ctx.current_cert.to_der == cert.to_der
+ end
+
+ req = Net::HTTP::Get.new("/")
+ http.request(req){|res|
+ assert_equal("SSL GET / ", res.body, s_log.call + log.call)
+ }
+
+ req = Net::HTTP::Post.new("/")
+ req.body = "post-data"
+ http.request(req){|res|
+ assert_equal("SSL POST / post-data", res.body, s_log.call + log.call)
+ }
+ }
+ }
+ end if defined?(OpenSSL)
+
+ def test_upstream_proxy
+ # Testing GET or POST through the upstream proxy server
+ # Note that the upstream proxy server works as the origin server.
+ # +------+
+ # V |
+ # client -------> proxy -------> proxy ---+
+ # GET / POST GET / POST GET / POST
+ #
+ up_proxy_handler_called = up_request_handler_called = 0
+ proxy_handler_called = request_handler_called = 0
+ up_config = {
+ :ServerName => "localhost.localdomain",
+ :ProxyContentHandler => Proc.new{|req, res| up_proxy_handler_called += 1},
+ :RequestHandler => Proc.new{|req, res| up_request_handler_called += 1}
+ }
+ TestWEBrick.start_httpproxy(up_config){|up_server, up_addr, up_port, up_log|
+ up_server.mount_proc("/"){|req, res|
+ res.body = "#{req.request_method} #{req.path} #{req.body}"
+ }
+ config = {
+ :ServerName => "localhost.localdomain",
+ :ProxyURI => URI.parse("http://localhost:#{up_port}"),
+ :ProxyContentHandler => Proc.new{|req, res| proxy_handler_called += 1},
+ :RequestHandler => Proc.new{|req, res| request_handler_called += 1},
+ }
+ TestWEBrick.start_httpproxy(config){|server, addr, port, log|
+ http = Net::HTTP.new(up_addr, up_port, addr, port)
+
+ req = Net::HTTP::Get.new("/")
+ http.request(req){|res|
+ via = res["via"].split(/,\s+/)
+ assert(via.include?("1.1 localhost.localdomain:#{up_port}"), up_log.call + log.call)
+ assert(via.include?("1.1 localhost.localdomain:#{port}"), up_log.call + log.call)
+ assert_equal("GET / ", res.body)
+ }
+ assert_equal(1, up_proxy_handler_called, up_log.call + log.call)
+ assert_equal(2, up_request_handler_called, up_log.call + log.call)
+ assert_equal(1, proxy_handler_called, up_log.call + log.call)
+ assert_equal(1, request_handler_called, up_log.call + log.call)
+
+ req = Net::HTTP::Head.new("/")
+ http.request(req){|res|
+ via = res["via"].split(/,\s+/)
+ assert(via.include?("1.1 localhost.localdomain:#{up_port}"), up_log.call + log.call)
+ assert(via.include?("1.1 localhost.localdomain:#{port}"), up_log.call + log.call)
+ assert_nil(res.body, up_log.call + log.call)
+ }
+ assert_equal(2, up_proxy_handler_called, up_log.call + log.call)
+ assert_equal(4, up_request_handler_called, up_log.call + log.call)
+ assert_equal(2, proxy_handler_called, up_log.call + log.call)
+ assert_equal(2, request_handler_called, up_log.call + log.call)
+
+ req = Net::HTTP::Post.new("/")
+ req.body = "post-data"
+ http.request(req){|res|
+ via = res["via"].split(/,\s+/)
+ assert(via.include?("1.1 localhost.localdomain:#{up_port}"), up_log.call + log.call)
+ assert(via.include?("1.1 localhost.localdomain:#{port}"), up_log.call + log.call)
+ assert_equal("POST / post-data", res.body, up_log.call + log.call)
+ }
+ assert_equal(3, up_proxy_handler_called, up_log.call + log.call)
+ assert_equal(6, up_request_handler_called, up_log.call + log.call)
+ assert_equal(3, proxy_handler_called, up_log.call + log.call)
+ assert_equal(3, request_handler_called, up_log.call + log.call)
+
+ if defined?(OpenSSL)
+ # Testing CONNECT to the upstream proxy server
+ #
+ # client -------> proxy -------> proxy -------> https
+ # 1. CONNECT CONNECT establish TCP
+ # 2. -------- establish SSL session ------>
+ # 3. ---------- GET or POST -------------->
+ #
+ key = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ cert = make_certificate(key, "127.0.0.1")
+ s_config = {
+ :SSLEnable =>true,
+ :ServerName => "localhost",
+ :SSLCertificate => cert,
+ :SSLPrivateKey => key,
+ }
+ TestWEBrick.start_httpserver(s_config){|s_server, s_addr, s_port, s_log|
+ s_server.mount_proc("/"){|req2, res|
+ res.body = "SSL #{req2.request_method} #{req2.path} #{req2.body}"
+ }
+ http = Net::HTTP.new("127.0.0.1", s_port, addr, port, up_log.call + log.call + s_log.call)
+ http.use_ssl = true
+ http.verify_callback = Proc.new do |preverify_ok, store_ctx|
+ store_ctx.current_cert.to_der == cert.to_der
+ end
+
+ req2 = Net::HTTP::Get.new("/")
+ http.request(req2){|res|
+ assert_equal("SSL GET / ", res.body, up_log.call + log.call + s_log.call)
+ }
+
+ req2 = Net::HTTP::Post.new("/")
+ req2.body = "post-data"
+ http.request(req2){|res|
+ assert_equal("SSL POST / post-data", res.body, up_log.call + log.call + s_log.call)
+ }
+ }
+ end
+ }
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/test_httprequest.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/test_httprequest.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/test_httprequest.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,349 @@
+require "webrick"
+require "stringio"
+require "test/unit"
+
+class TestWEBrickHTTPRequest < Test::Unit::TestCase
+ def test_parse_09
+ msg = <<-_end_of_message_
+ GET /
+ foobar # HTTP/0.9 request don't have header nor entity body.
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ assert_equal("GET", req.request_method)
+ assert_equal("/", req.unparsed_uri)
+ assert_equal(WEBrick::HTTPVersion.new("0.9"), req.http_version)
+ assert_equal(WEBrick::Config::HTTP[:ServerName], req.host)
+ assert_equal(80, req.port)
+ assert_equal(false, req.keep_alive?)
+ assert_equal(nil, req.body)
+ assert(req.query.empty?)
+ end
+
+ def test_parse_10
+ msg = <<-_end_of_message_
+ GET / HTTP/1.0
+
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ assert_equal("GET", req.request_method)
+ assert_equal("/", req.unparsed_uri)
+ assert_equal(WEBrick::HTTPVersion.new("1.0"), req.http_version)
+ assert_equal(WEBrick::Config::HTTP[:ServerName], req.host)
+ assert_equal(80, req.port)
+ assert_equal(false, req.keep_alive?)
+ assert_equal(nil, req.body)
+ assert(req.query.empty?)
+ end
+
+ def test_parse_11
+ msg = <<-_end_of_message_
+ GET /path HTTP/1.1
+
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ assert_equal("GET", req.request_method)
+ assert_equal("/path", req.unparsed_uri)
+ assert_equal("", req.script_name)
+ assert_equal("/path", req.path_info)
+ assert_equal(WEBrick::HTTPVersion.new("1.1"), req.http_version)
+ assert_equal(WEBrick::Config::HTTP[:ServerName], req.host)
+ assert_equal(80, req.port)
+ assert_equal(true, req.keep_alive?)
+ assert_equal(nil, req.body)
+ assert(req.query.empty?)
+ end
+
+ def test_request_uri_too_large
+ msg = <<-_end_of_message_
+ GET /#{"a"*1024} HTTP/1.1
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ assert_raise(WEBrick::HTTPStatus::RequestURITooLarge){
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ }
+ end
+
+ def test_parse_headers
+ msg = <<-_end_of_message_
+ GET /path HTTP/1.1
+ Host: test.ruby-lang.org:8080
+ Connection: close
+ Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
+ text/html;level=2;q=0.4, */*;q=0.5
+ Accept-Encoding: compress;q=0.5
+ Accept-Encoding: gzip;q=1.0, identity; q=0.4, *;q=0
+ Accept-Language: en;q=0.5, *; q=0
+ Accept-Language: ja
+ Content-Type: text/plain
+ Content-Length: 7
+ X-Empty-Header:
+
+ foobar
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ assert_equal(
+ URI.parse("http://test.ruby-lang.org:8080/path"), req.request_uri)
+ assert_equal("test.ruby-lang.org", req.host)
+ assert_equal(8080, req.port)
+ assert_equal(false, req.keep_alive?)
+ assert_equal(
+ %w(text/html;level=1 text/html */* text/html;level=2 text/*),
+ req.accept)
+ assert_equal(%w(gzip compress identity *), req.accept_encoding)
+ assert_equal(%w(ja en *), req.accept_language)
+ assert_equal(7, req.content_length)
+ assert_equal("text/plain", req.content_type)
+ assert_equal("foobar\n", req.body)
+ assert_equal("", req["x-empty-header"])
+ assert_equal(nil, req["x-no-header"])
+ assert(req.query.empty?)
+ end
+
+ def test_parse_header2()
+ msg = <<-_end_of_message_
+ POST /foo/bar/../baz?q=a HTTP/1.0
+ Content-Length: 9
+ User-Agent:
+ FOO BAR
+ BAZ
+
+ hogehoge
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ assert_equal("POST", req.request_method)
+ assert_equal("/foo/baz", req.path)
+ assert_equal("", req.script_name)
+ assert_equal("/foo/baz", req.path_info)
+ assert_equal("9", req['content-length'])
+ assert_equal("FOO BAR BAZ", req['user-agent'])
+ assert_equal("hogehoge\n", req.body)
+ end
+
+ def test_parse_headers3
+ msg = <<-_end_of_message_
+ GET /path HTTP/1.1
+ Host: test.ruby-lang.org
+
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ assert_equal(URI.parse("http://test.ruby-lang.org/path"), req.request_uri)
+ assert_equal("test.ruby-lang.org", req.host)
+ assert_equal(80, req.port)
+
+ msg = <<-_end_of_message_
+ GET /path HTTP/1.1
+ Host: 192.168.1.1
+
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ assert_equal(URI.parse("http://192.168.1.1/path"), req.request_uri)
+ assert_equal("192.168.1.1", req.host)
+ assert_equal(80, req.port)
+
+ msg = <<-_end_of_message_
+ GET /path HTTP/1.1
+ Host: [fe80::208:dff:feef:98c7]
+
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ assert_equal(URI.parse("http://[fe80::208:dff:feef:98c7]/path"),
+ req.request_uri)
+ assert_equal("[fe80::208:dff:feef:98c7]", req.host)
+ assert_equal(80, req.port)
+
+ msg = <<-_end_of_message_
+ GET /path HTTP/1.1
+ Host: 192.168.1.1:8080
+
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ assert_equal(URI.parse("http://192.168.1.1:8080/path"), req.request_uri)
+ assert_equal("192.168.1.1", req.host)
+ assert_equal(8080, req.port)
+
+ msg = <<-_end_of_message_
+ GET /path HTTP/1.1
+ Host: [fe80::208:dff:feef:98c7]:8080
+
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ assert_equal(URI.parse("http://[fe80::208:dff:feef:98c7]:8080/path"),
+ req.request_uri)
+ assert_equal("[fe80::208:dff:feef:98c7]", req.host)
+ assert_equal(8080, req.port)
+ end
+
+ def test_parse_get_params
+ param = "foo=1;foo=2;foo=3;bar=x"
+ msg = <<-_end_of_message_
+ GET /path?#{param} HTTP/1.1
+ Host: test.ruby-lang.org:8080
+
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ query = req.query
+ assert_equal("1", query["foo"])
+ assert_equal(["1", "2", "3"], query["foo"].to_ary)
+ assert_equal(["1", "2", "3"], query["foo"].list)
+ assert_equal("x", query["bar"])
+ assert_equal(["x"], query["bar"].list)
+ end
+
+ def test_parse_post_params
+ param = "foo=1;foo=2;foo=3;bar=x"
+ msg = <<-_end_of_message_
+ POST /path?foo=x;foo=y;foo=z;bar=1 HTTP/1.1
+ Host: test.ruby-lang.org:8080
+ Content-Length: #{param.size}
+ Content-Type: application/x-www-form-urlencoded
+
+ #{param}
+ _end_of_message_
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ query = req.query
+ assert_equal("1", query["foo"])
+ assert_equal(["1", "2", "3"], query["foo"].to_ary)
+ assert_equal(["1", "2", "3"], query["foo"].list)
+ assert_equal("x", query["bar"])
+ assert_equal(["x"], query["bar"].list)
+ end
+
+ def test_chunked
+ crlf = "\x0d\x0a"
+ msg = <<-_end_of_message_
+ POST /path HTTP/1.1
+ Host: test.ruby-lang.org:8080
+ Transfer-Encoding: chunked
+
+ _end_of_message_
+ msg.gsub!(/^ {6}/, "")
+ open(__FILE__){|io|
+ while chunk = io.read(100)
+ msg << chunk.size.to_s(16) << crlf
+ msg << chunk << crlf
+ end
+ }
+ msg << "0" << crlf
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg))
+ assert_equal(File.read(__FILE__), req.body)
+ end
+
+ def test_forwarded
+ msg = <<-_end_of_message_
+ GET /foo HTTP/1.1
+ Host: localhost:10080
+ User-Agent: w3m/0.5.2
+ X-Forwarded-For: 123.123.123.123
+ X-Forwarded-Host: forward.example.com
+ X-Forwarded-Server: server.example.com
+ Connection: Keep-Alive
+
+ _end_of_message_
+ msg.gsub!(/^ {6}/, "")
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg))
+ assert_equal("server.example.com", req.server_name)
+ assert_equal("http://forward.example.com/foo", req.request_uri.to_s)
+ assert_equal("forward.example.com", req.host)
+ assert_equal(80, req.port)
+ assert_equal("123.123.123.123", req.remote_ip)
+ assert(!req.ssl?)
+
+ msg = <<-_end_of_message_
+ GET /foo HTTP/1.1
+ Host: localhost:10080
+ User-Agent: w3m/0.5.2
+ X-Forwarded-For: 192.168.1.10, 172.16.1.1, 123.123.123.123
+ X-Forwarded-Host: forward.example.com:8080
+ X-Forwarded-Server: server.example.com
+ Connection: Keep-Alive
+
+ _end_of_message_
+ msg.gsub!(/^ {6}/, "")
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg))
+ assert_equal("server.example.com", req.server_name)
+ assert_equal("http://forward.example.com:8080/foo", req.request_uri.to_s)
+ assert_equal("forward.example.com", req.host)
+ assert_equal(8080, req.port)
+ assert_equal("123.123.123.123", req.remote_ip)
+ assert(!req.ssl?)
+
+ msg = <<-_end_of_message_
+ GET /foo HTTP/1.1
+ Host: localhost:10080
+ Client-IP: 234.234.234.234
+ X-Forwarded-Proto: https
+ X-Forwarded-For: 192.168.1.10, 10.0.0.1, 123.123.123.123
+ X-Forwarded-Host: forward.example.com
+ X-Forwarded-Server: server.example.com
+ X-Requested-With: XMLHttpRequest
+ Connection: Keep-Alive
+
+ _end_of_message_
+ msg.gsub!(/^ {6}/, "")
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg))
+ assert_equal("server.example.com", req.server_name)
+ assert_equal("https://forward.example.com/foo", req.request_uri.to_s)
+ assert_equal("forward.example.com", req.host)
+ assert_equal(443, req.port)
+ assert_equal("234.234.234.234", req.remote_ip)
+ assert(req.ssl?)
+ end
+
+ def test_bad_messages
+ param = "foo=1;foo=2;foo=3;bar=x"
+ msg = <<-_end_of_message_
+ POST /path?foo=x;foo=y;foo=z;bar=1 HTTP/1.1
+ Host: test.ruby-lang.org:8080
+ Content-Type: application/x-www-form-urlencoded
+
+ #{param}
+ _end_of_message_
+ assert_raise(WEBrick::HTTPStatus::LengthRequired){
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ req.body
+ }
+
+ msg = <<-_end_of_message_
+ POST /path?foo=x;foo=y;foo=z;bar=1 HTTP/1.1
+ Host: test.ruby-lang.org:8080
+ Content-Length: 100000
+
+ body is too short.
+ _end_of_message_
+ assert_raise(WEBrick::HTTPStatus::BadRequest){
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ req.body
+ }
+
+ msg = <<-_end_of_message_
+ POST /path?foo=x;foo=y;foo=z;bar=1 HTTP/1.1
+ Host: test.ruby-lang.org:8080
+ Transfer-Encoding: foobar
+
+ body is too short.
+ _end_of_message_
+ assert_raise(WEBrick::HTTPStatus::NotImplemented){
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
+ req.body
+ }
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/test_httpserver.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/test_httpserver.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/test_httpserver.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,260 @@
+require "test/unit"
+require "net/http"
+require "webrick"
+require_relative "utils"
+
+class TestWEBrickHTTPServer < Test::Unit::TestCase
+ def test_mount
+ httpd = WEBrick::HTTPServer.new(
+ :Logger => WEBrick::Log.new(TestWEBrick::NullWriter),
+ :DoNotListen=>true
+ )
+ httpd.mount("/", :Root)
+ httpd.mount("/foo", :Foo)
+ httpd.mount("/foo/bar", :Bar, :bar1)
+ httpd.mount("/foo/bar/baz", :Baz, :baz1, :baz2)
+
+ serv, opts, script_name, path_info = httpd.search_servlet("/")
+ assert_equal(:Root, serv)
+ assert_equal([], opts)
+ assert_equal(script_name, "")
+ assert_equal(path_info, "/")
+
+ serv, opts, script_name, path_info = httpd.search_servlet("/sub")
+ assert_equal(:Root, serv)
+ assert_equal([], opts)
+ assert_equal(script_name, "")
+ assert_equal(path_info, "/sub")
+
+ serv, opts, script_name, path_info = httpd.search_servlet("/sub/")
+ assert_equal(:Root, serv)
+ assert_equal([], opts)
+ assert_equal(script_name, "")
+ assert_equal(path_info, "/sub/")
+
+ serv, opts, script_name, path_info = httpd.search_servlet("/foo")
+ assert_equal(:Foo, serv)
+ assert_equal([], opts)
+ assert_equal(script_name, "/foo")
+ assert_equal(path_info, "")
+
+ serv, opts, script_name, path_info = httpd.search_servlet("/foo/")
+ assert_equal(:Foo, serv)
+ assert_equal([], opts)
+ assert_equal(script_name, "/foo")
+ assert_equal(path_info, "/")
+
+ serv, opts, script_name, path_info = httpd.search_servlet("/foo/sub")
+ assert_equal(:Foo, serv)
+ assert_equal([], opts)
+ assert_equal(script_name, "/foo")
+ assert_equal(path_info, "/sub")
+
+ serv, opts, script_name, path_info = httpd.search_servlet("/foo/bar")
+ assert_equal(:Bar, serv)
+ assert_equal([:bar1], opts)
+ assert_equal(script_name, "/foo/bar")
+ assert_equal(path_info, "")
+
+ serv, opts, script_name, path_info = httpd.search_servlet("/foo/bar/baz")
+ assert_equal(:Baz, serv)
+ assert_equal([:baz1, :baz2], opts)
+ assert_equal(script_name, "/foo/bar/baz")
+ assert_equal(path_info, "")
+ end
+
+ class Req
+ attr_reader :port, :host
+ def initialize(addr, port, host)
+ @addr, @port, @host = addr, port, host
+ end
+ def addr
+ [0,0,0, at addr]
+ end
+ end
+
+ def httpd(addr, port, host, ali)
+ config ={
+ :Logger => WEBrick::Log.new(TestWEBrick::NullWriter),
+ :DoNotListen => true,
+ :BindAddress => addr,
+ :Port => port,
+ :ServerName => host,
+ :ServerAlias => ali,
+ }
+ return WEBrick::HTTPServer.new(config)
+ end
+
+ def assert_eql?(v1, v2)
+ assert_equal(v1.object_id, v2.object_id)
+ end
+
+ def test_lookup_server
+ addr1 = "192.168.100.1"
+ addr2 = "192.168.100.2"
+ addrz = "192.168.100.254"
+ local = "127.0.0.1"
+ port1 = 80
+ port2 = 8080
+ port3 = 10080
+ portz = 32767
+ name1 = "www.example.com"
+ name2 = "www2.example.com"
+ name3 = "www3.example.com"
+ namea = "www.example.co.jp"
+ nameb = "www.example.jp"
+ namec = "www2.example.co.jp"
+ named = "www2.example.jp"
+ namez = "foobar.example.com"
+ alias1 = [namea, nameb]
+ alias2 = [namec, named]
+
+ host1 = httpd(nil, port1, name1, nil)
+ hosts = [
+ host2 = httpd(addr1, port1, name1, nil),
+ host3 = httpd(addr1, port1, name2, alias1),
+ host4 = httpd(addr1, port2, name1, nil),
+ host5 = httpd(addr1, port2, name2, alias1),
+ host6 = httpd(addr1, port2, name3, alias2),
+ host7 = httpd(addr2, nil, name1, nil),
+ host8 = httpd(addr2, nil, name2, alias1),
+ host9 = httpd(addr2, nil, name3, alias2),
+ host10 = httpd(local, nil, nil, nil),
+ host11 = httpd(nil, port3, nil, nil),
+ ].sort_by{ rand }
+ hosts.each{|h| host1.virtual_host(h) }
+
+ # connect to addr1
+ assert_eql?(host2, host1.lookup_server(Req.new(addr1, port1, name1)))
+ assert_eql?(host3, host1.lookup_server(Req.new(addr1, port1, name2)))
+ assert_eql?(host3, host1.lookup_server(Req.new(addr1, port1, namea)))
+ assert_eql?(host3, host1.lookup_server(Req.new(addr1, port1, nameb)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addr1, port1, namez)))
+ assert_eql?(host4, host1.lookup_server(Req.new(addr1, port2, name1)))
+ assert_eql?(host5, host1.lookup_server(Req.new(addr1, port2, name2)))
+ assert_eql?(host5, host1.lookup_server(Req.new(addr1, port2, namea)))
+ assert_eql?(host5, host1.lookup_server(Req.new(addr1, port2, nameb)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addr1, port2, namez)))
+ assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, name1)))
+ assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, name2)))
+ assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, namea)))
+ assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, nameb)))
+ assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, namez)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, name1)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, name2)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, namea)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, nameb)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, namez)))
+
+ # connect to addr2
+ assert_eql?(host7, host1.lookup_server(Req.new(addr2, port1, name1)))
+ assert_eql?(host8, host1.lookup_server(Req.new(addr2, port1, name2)))
+ assert_eql?(host8, host1.lookup_server(Req.new(addr2, port1, namea)))
+ assert_eql?(host8, host1.lookup_server(Req.new(addr2, port1, nameb)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addr2, port1, namez)))
+ assert_eql?(host7, host1.lookup_server(Req.new(addr2, port2, name1)))
+ assert_eql?(host8, host1.lookup_server(Req.new(addr2, port2, name2)))
+ assert_eql?(host8, host1.lookup_server(Req.new(addr2, port2, namea)))
+ assert_eql?(host8, host1.lookup_server(Req.new(addr2, port2, nameb)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addr2, port2, namez)))
+ assert_eql?(host7, host1.lookup_server(Req.new(addr2, port3, name1)))
+ assert_eql?(host8, host1.lookup_server(Req.new(addr2, port3, name2)))
+ assert_eql?(host8, host1.lookup_server(Req.new(addr2, port3, namea)))
+ assert_eql?(host8, host1.lookup_server(Req.new(addr2, port3, nameb)))
+ assert_eql?(host11, host1.lookup_server(Req.new(addr2, port3, namez)))
+ assert_eql?(host7, host1.lookup_server(Req.new(addr2, portz, name1)))
+ assert_eql?(host8, host1.lookup_server(Req.new(addr2, portz, name2)))
+ assert_eql?(host8, host1.lookup_server(Req.new(addr2, portz, namea)))
+ assert_eql?(host8, host1.lookup_server(Req.new(addr2, portz, nameb)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addr2, portz, namez)))
+
+ # connect to addrz
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, name1)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, name2)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, namea)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, nameb)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, namez)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, name1)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, name2)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, namea)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, nameb)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, namez)))
+ assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, name1)))
+ assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, name2)))
+ assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, namea)))
+ assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, nameb)))
+ assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, namez)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, name1)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, name2)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, namea)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, nameb)))
+ assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, namez)))
+
+ # connect to localhost
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port1, name1)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port1, name2)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port1, namea)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port1, nameb)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port1, namez)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port2, name1)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port2, name2)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port2, namea)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port2, nameb)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port2, namez)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port3, name1)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port3, name2)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port3, namea)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port3, nameb)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, port3, namez)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, portz, name1)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, portz, name2)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, portz, namea)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, portz, nameb)))
+ assert_eql?(host10, host1.lookup_server(Req.new(local, portz, namez)))
+ end
+
+ def test_callbacks
+ accepted = started = stopped = 0
+ requested0 = requested1 = 0
+ config = {
+ :ServerName => "localhost",
+ :AcceptCallback => Proc.new{ accepted += 1 },
+ :StartCallback => Proc.new{ started += 1 },
+ :StopCallback => Proc.new{ stopped += 1 },
+ :RequestCallback => Proc.new{|req, res| requested0 += 1 },
+ }
+ TestWEBrick.start_httpserver(config){|server, addr, port, log|
+ vhost_config = {
+ :ServerName => "myhostname",
+ :BindAddress => addr,
+ :Port => port,
+ :DoNotListen => true,
+ :Logger => WEBrick::Log.new(TestWEBrick::NullWriter),
+ :AccessLog => [],
+ :RequestCallback => Proc.new{|req, res| requested1 += 1 },
+ }
+ server.virtual_host(WEBrick::HTTPServer.new(vhost_config))
+
+ true while server.status != :Running
+ assert_equal(started, 1, log.call)
+ assert_equal(stopped, 0, log.call)
+ assert_equal(accepted, 0, log.call)
+
+ http = Net::HTTP.new(addr, port)
+ req = Net::HTTP::Get.new("/")
+ req["Host"] = "myhostname:#{port}"
+ http.request(req){|res| assert_equal("404", res.code, log.call)}
+ http.request(req){|res| assert_equal("404", res.code, log.call)}
+ http.request(req){|res| assert_equal("404", res.code, log.call)}
+ req["Host"] = "localhost:#{port}"
+ http.request(req){|res| assert_equal("404", res.code, log.call)}
+ http.request(req){|res| assert_equal("404", res.code, log.call)}
+ http.request(req){|res| assert_equal("404", res.code, log.call)}
+ assert_equal(6, accepted, log.call)
+ assert_equal(3, requested0, log.call)
+ assert_equal(3, requested1, log.call)
+ }
+ assert_equal(started, 1)
+ assert_equal(stopped, 1)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/test_httputils.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/test_httputils.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/test_httputils.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,96 @@
+require "test/unit"
+require "webrick/httputils"
+
+class TestWEBrickHTTPUtils < Test::Unit::TestCase
+ include WEBrick::HTTPUtils
+
+ def test_normilize_path
+ assert_equal("/foo", normalize_path("/foo"))
+ assert_equal("/foo/bar/", normalize_path("/foo/bar/"))
+
+ assert_equal("/", normalize_path("/foo/../"))
+ assert_equal("/", normalize_path("/foo/.."))
+ assert_equal("/", normalize_path("/foo/bar/../../"))
+ assert_equal("/", normalize_path("/foo/bar/../.."))
+ assert_equal("/", normalize_path("/foo/bar/../.."))
+ assert_equal("/baz", normalize_path("/foo/bar/../../baz"))
+ assert_equal("/baz", normalize_path("/foo/../bar/../baz"))
+ assert_equal("/baz/", normalize_path("/foo/../bar/../baz/"))
+ assert_equal("/...", normalize_path("/bar/../..."))
+ assert_equal("/.../", normalize_path("/bar/../.../"))
+
+ assert_equal("/foo/", normalize_path("/foo/./"))
+ assert_equal("/foo/", normalize_path("/foo/."))
+ assert_equal("/foo/", normalize_path("/foo/././"))
+ assert_equal("/foo/", normalize_path("/foo/./."))
+ assert_equal("/foo/bar", normalize_path("/foo/./bar"))
+ assert_equal("/foo/bar/", normalize_path("/foo/./bar/."))
+ assert_equal("/foo/bar/", normalize_path("/./././foo/./bar/."))
+
+ assert_equal("/foo/bar/", normalize_path("//foo///.//bar/.///.//"))
+ assert_equal("/", normalize_path("//foo///..///bar/.///..//.//"))
+
+ assert_raise(RuntimeError){ normalize_path("foo/bar") }
+ assert_raise(RuntimeError){ normalize_path("..") }
+ assert_raise(RuntimeError){ normalize_path("/..") }
+ assert_raise(RuntimeError){ normalize_path("/./..") }
+ assert_raise(RuntimeError){ normalize_path("/./../") }
+ assert_raise(RuntimeError){ normalize_path("/./../..") }
+ assert_raise(RuntimeError){ normalize_path("/./../../") }
+ assert_raise(RuntimeError){ normalize_path("/./../") }
+ assert_raise(RuntimeError){ normalize_path("/../..") }
+ assert_raise(RuntimeError){ normalize_path("/../../") }
+ assert_raise(RuntimeError){ normalize_path("/../../..") }
+ assert_raise(RuntimeError){ normalize_path("/../../../") }
+ assert_raise(RuntimeError){ normalize_path("/../foo/../") }
+ assert_raise(RuntimeError){ normalize_path("/../foo/../../") }
+ assert_raise(RuntimeError){ normalize_path("/foo/bar/../../../../") }
+ assert_raise(RuntimeError){ normalize_path("/foo/../bar/../../") }
+ assert_raise(RuntimeError){ normalize_path("/./../bar/") }
+ assert_raise(RuntimeError){ normalize_path("/./../") }
+ end
+
+ def test_split_header_value
+ assert_equal(['foo', 'bar'], split_header_value('foo, bar'))
+ assert_equal(['"foo"', 'bar'], split_header_value('"foo", bar'))
+ assert_equal(['foo', '"bar"'], split_header_value('foo, "bar"'))
+ assert_equal(['*'], split_header_value('*'))
+ assert_equal(['W/"xyzzy"', 'W/"r2d2xxxx"', 'W/"c3piozzzz"'],
+ split_header_value('W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"'))
+ end
+
+ def test_escape
+ assert_equal("/foo/bar", escape("/foo/bar"))
+ assert_equal("/~foo/bar", escape("/~foo/bar"))
+ assert_equal("/~foo%20bar", escape("/~foo bar"))
+ assert_equal("/~foo%20bar", escape("/~foo bar"))
+ assert_equal("/~foo%09bar", escape("/~foo\tbar"))
+ assert_equal("/~foo+bar", escape("/~foo+bar"))
+ end
+
+ def test_escape_form
+ assert_equal("%2Ffoo%2Fbar", escape_form("/foo/bar"))
+ assert_equal("%2F~foo%2Fbar", escape_form("/~foo/bar"))
+ assert_equal("%2F~foo+bar", escape_form("/~foo bar"))
+ assert_equal("%2F~foo+%2B+bar", escape_form("/~foo + bar"))
+ end
+
+ def test_unescape
+ assert_equal("/foo/bar", unescape("%2ffoo%2fbar"))
+ assert_equal("/~foo/bar", unescape("/%7efoo/bar"))
+ assert_equal("/~foo/bar", unescape("%2f%7efoo%2fbar"))
+ assert_equal("/~foo+bar", unescape("/%7efoo+bar"))
+ end
+
+ def test_unescape_form
+ assert_equal("//foo/bar", unescape_form("/%2Ffoo/bar"))
+ assert_equal("//foo/bar baz", unescape_form("/%2Ffoo/bar+baz"))
+ assert_equal("/~foo/bar baz", unescape_form("/%7Efoo/bar+baz"))
+ end
+
+ def test_escape_path
+ assert_equal("/foo/bar", escape_path("/foo/bar"))
+ assert_equal("/foo/bar/", escape_path("/foo/bar/"))
+ assert_equal("/%25foo/bar/", escape_path("/%foo/bar/"))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/test_httpversion.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/test_httpversion.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/test_httpversion.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,40 @@
+require "test/unit"
+require "webrick/httpversion"
+
+class TestWEBrickHTTPVersion < Test::Unit::TestCase
+ def setup
+ @v09 = WEBrick::HTTPVersion.new("0.9")
+ @v10 = WEBrick::HTTPVersion.new("1.0")
+ @v11 = WEBrick::HTTPVersion.new("1.001")
+ end
+
+ def test_to_s()
+ assert_equal("0.9", @v09.to_s)
+ assert_equal("1.0", @v10.to_s)
+ assert_equal("1.1", @v11.to_s)
+ end
+
+ def test_major()
+ assert_equal(0, @v09.major)
+ assert_equal(1, @v10.major)
+ assert_equal(1, @v11.major)
+ end
+
+ def test_minor()
+ assert_equal(9, @v09.minor)
+ assert_equal(0, @v10.minor)
+ assert_equal(1, @v11.minor)
+ end
+
+ def test_compar()
+ assert_equal(0, @v09 <=> "0.9")
+ assert_equal(0, @v09 <=> "0.09")
+
+ assert_equal(-1, @v09 <=> @v10)
+ assert_equal(-1, @v09 <=> "1.00")
+
+ assert_equal(1, @v11 <=> @v09)
+ assert_equal(1, @v11 <=> "1.0")
+ assert_equal(1, @v11 <=> "0.9")
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/test_server.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/test_server.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/test_server.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,64 @@
+require "test/unit"
+require "tempfile"
+require "webrick"
+require_relative "utils"
+
+class TestWEBrickServer < Test::Unit::TestCase
+ class Echo < WEBrick::GenericServer
+ def run(sock)
+ while line = sock.gets
+ sock << line
+ end
+ end
+ end
+
+ def test_server
+ TestWEBrick.start_server(Echo){|server, addr, port, log|
+ TCPSocket.open(addr, port){|sock|
+ sock.puts("foo"); assert_equal("foo\n", sock.gets, log.call)
+ sock.puts("bar"); assert_equal("bar\n", sock.gets, log.call)
+ sock.puts("baz"); assert_equal("baz\n", sock.gets, log.call)
+ sock.puts("qux"); assert_equal("qux\n", sock.gets, log.call)
+ }
+ }
+ end
+
+ def test_callbacks
+ accepted = started = stopped = 0
+ config = {
+ :AcceptCallback => Proc.new{ accepted += 1 },
+ :StartCallback => Proc.new{ started += 1 },
+ :StopCallback => Proc.new{ stopped += 1 },
+ }
+ TestWEBrick.start_server(Echo, config){|server, addr, port, log|
+ true while server.status != :Running
+ assert_equal(started, 1, log.call)
+ assert_equal(stopped, 0, log.call)
+ assert_equal(accepted, 0, log.call)
+ TCPSocket.open(addr, port){|sock| (sock << "foo\n").gets }
+ TCPSocket.open(addr, port){|sock| (sock << "foo\n").gets }
+ TCPSocket.open(addr, port){|sock| (sock << "foo\n").gets }
+ assert_equal(accepted, 3, log.call)
+ }
+ assert_equal(started, 1)
+ assert_equal(stopped, 1)
+ end
+
+ def test_daemon
+ begin
+ r, w = IO.pipe
+ Process.fork{
+ r.close
+ WEBrick::Daemon.start
+ w.puts(Process.pid)
+ sleep
+ }
+ assert(Process.kill(:KILL, r.gets.to_i))
+ rescue NotImplementedError
+ # snip this test
+ ensure
+ r.close
+ w.close
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/test_utils.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/test_utils.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/test_utils.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,64 @@
+require "test/unit"
+require "webrick/utils"
+
+class TestWEBrickUtils < Test::Unit::TestCase
+ def assert_expired(flag, m)
+ if m == WEBrick::Utils
+ handler = WEBrick::Utils::TimeoutHandler.instance
+ assert_equal(flag, handler.instance_eval{ @timeout_info.empty? })
+ end
+ end
+
+ def do_test_timeout(m)
+ ex = Class.new(StandardError)
+
+ assert_equal(:foo, m.timeout(10){ :foo })
+ assert_expired(true, m)
+
+ i = 0
+ assert_raise(Timeout::Error){
+ m.timeout(2){
+ assert_raise(Timeout::Error){ m.timeout(1){ i += 1; sleep } }
+ assert_expired(false, m)
+ i += 1
+ sleep
+ }
+ }
+ assert_equal(2, i)
+ assert_expired(true, m)
+
+ assert_raise(Timeout::Error){ m.timeout(0.1){ sleep } }
+ assert_expired(true, m)
+
+ assert_raise(ex){ m.timeout(0.1, ex){ sleep } }
+ assert_expired(true, m)
+
+ i = 0
+ assert_raise(ex){
+ m.timeout(10){
+ m.timeout(1, ex){ i += 1; sleep }
+ }
+ sleep
+ }
+ assert_equal(1, i)
+ assert_expired(true, m)
+
+ i = 0
+ assert_raise(Timeout::Error){
+ m.timeout(1){
+ m.timeout(10, ex){ i += 1; sleep }
+ }
+ sleep
+ }
+ assert_equal(1, i)
+ assert_expired(true, m)
+ end
+
+ def test_webrick_timeout
+ do_test_timeout(WEBrick::Utils)
+ end
+
+ #def test_timeout
+ # do_test_timeout(Timeout)
+ #end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/utils.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/utils.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/utils.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,57 @@
+require_relative '../ruby/envutil'
+require "webrick"
+begin
+ require "webrick/https"
+rescue LoadError
+end
+require "webrick/httpproxy"
+
+module TestWEBrick
+ NullWriter = Object.new
+ def NullWriter.<<(msg)
+ puts msg if $DEBUG
+ return self
+ end
+
+ RubyBin = "\"#{EnvUtil.rubybin}\""
+ RubyBin << " \"-I#{File.expand_path("../..", File.dirname(__FILE__))}/lib\""
+ RubyBin << " \"-I#{File.dirname(EnvUtil.rubybin)}/.ext/common\""
+ RubyBin << " \"-I#{File.dirname(EnvUtil.rubybin)}/.ext/#{RUBY_PLATFORM}\""
+
+ module_function
+
+ def start_server(klass, config={}, &block)
+ log_string = ""
+ logger = Object.new
+ logger.instance_eval do
+ define_singleton_method(:<<) {|msg| log_string << msg }
+ end
+ log = proc { "webrick log start:\n" + log_string.gsub(/^/, " ").chomp + "\nwebrick log end" }
+ server = klass.new({
+ :BindAddress => "127.0.0.1", :Port => 0,
+ :ShutdownSocketWithoutClose =>true,
+ :ServerType => Thread,
+ :Logger => WEBrick::Log.new(logger),
+ :AccessLog => [[logger, ""]]
+ }.update(config))
+ begin
+ server.start
+ addr = server.listeners[0].addr
+ block.yield([server, addr[3], addr[1], log])
+ ensure
+ server.shutdown
+ until server.status == :Stop
+ sleep 0.1
+ end
+ end
+ log_string
+ end
+
+ def start_httpserver(config={}, &block)
+ start_server(WEBrick::HTTPServer, config, &block)
+ end
+
+ def start_httpproxy(config={}, &block)
+ start_server(WEBrick::HTTPProxyServer, config, &block)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/webrick/webrick.cgi
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/webrick.cgi (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/webrick.cgi 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,36 @@
+#!ruby -d
+require "webrick/cgi"
+
+class TestApp < WEBrick::CGI
+ def do_GET(req, res)
+ res["content-type"] = "text/plain"
+ if (p = req.path_info) && p.length > 0
+ res.body = p
+ elsif (q = req.query).size > 0
+ res.body = q.keys.sort.collect{|key|
+ q[key].list.sort.collect{|v|
+ "#{key}=#{v}"
+ }.join(", ")
+ }.join(", ")
+ elsif %r{/$} =~ req.request_uri.to_s
+ res.body = ""
+ res.body << req.request_uri.to_s << "\n"
+ res.body << req.script_name
+ elsif !req.cookies.empty?
+ res.body = req.cookies.inject(""){|result, cookie|
+ result << "%s=%s\n" % [cookie.name, cookie.value]
+ }
+ res.cookies << WEBrick::Cookie.new("Customer", "WILE_E_COYOTE")
+ res.cookies << WEBrick::Cookie.new("Shipping", "FedEx")
+ else
+ res.body = req.script_name
+ end
+ end
+
+ def do_POST(req, res)
+ do_GET(req, res)
+ end
+end
+
+cgi = TestApp.new
+cgi.start
Added: MacRuby/trunk/test/test-mri/test/webrick/webrick_long_filename.cgi
===================================================================
--- MacRuby/trunk/test/test-mri/test/webrick/webrick_long_filename.cgi (rev 0)
+++ MacRuby/trunk/test/test-mri/test/webrick/webrick_long_filename.cgi 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,36 @@
+#!ruby -d
+require "webrick/cgi"
+
+class TestApp < WEBrick::CGI
+ def do_GET(req, res)
+ res["content-type"] = "text/plain"
+ if (p = req.path_info) && p.length > 0
+ res.body = p
+ elsif (q = req.query).size > 0
+ res.body = q.keys.sort.collect{|key|
+ q[key].list.sort.collect{|v|
+ "#{key}=#{v}"
+ }.join(", ")
+ }.join(", ")
+ elsif %r{/$} =~ req.request_uri.to_s
+ res.body = ""
+ res.body << req.request_uri.to_s << "\n"
+ res.body << req.script_name
+ elsif !req.cookies.empty?
+ res.body = req.cookies.inject(""){|result, cookie|
+ result << "%s=%s\n" % [cookie.name, cookie.value]
+ }
+ res.cookies << WEBrick::Cookie.new("Customer", "WILE_E_COYOTE")
+ res.cookies << WEBrick::Cookie.new("Shipping", "FedEx")
+ else
+ res.body = req.script_name
+ end
+ end
+
+ def do_POST(req, res)
+ do_GET(req, res)
+ end
+end
+
+cgi = TestApp.new
+cgi.start
Added: MacRuby/trunk/test/test-mri/test/win32ole/err_in_callback.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/err_in_callback.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/err_in_callback.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,9 @@
+require 'win32ole'
+db = WIN32OLE.new('ADODB.Connection')
+db.connectionString = "Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=.;"
+ev = WIN32OLE_EVENT.new(db)
+ev.on_event('WillConnect') {|*args|
+ foo
+}
+db.open
+WIN32OLE_EVENT.message_loop
Added: MacRuby/trunk/test/test-mri/test/win32ole/orig_data.csv
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/orig_data.csv (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/orig_data.csv 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,5 @@
+ID,VALUE
+1,"A"
+2,"B"
+3,"C"
+4,"B"
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_err_in_callback.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_err_in_callback.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_err_in_callback.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,44 @@
+#
+# test Win32OLE avoids cfp consistency error when the exception raised
+# in WIN32OLE_EVENT handler block. [ruby-dev:35450]
+#
+
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require 'rbconfig'
+if defined?(WIN32OLE)
+ require 'mkmf'
+ require 'test/unit'
+ class TestErrInCallBack < Test::Unit::TestCase
+ def setup
+ @ruby = nil
+ if File.exist?("./" + CONFIG["RUBY_INSTALL_NAME"] + CONFIG["EXEEXT"])
+ sep = File::ALT_SEPARATOR || "/"
+ @ruby = "." + sep + CONFIG["RUBY_INSTALL_NAME"]
+ @iopt = $:.map {|e|
+ " -I " + e
+ }.join("")
+ @script = File.dirname(__FILE__) + "/err_in_callback.rb"
+ end
+ end
+
+ def test_err_in_callback
+ if @ruby
+ cmd = "#{@ruby} -v #{@iopt} #{@script} > test_err_in_callback.log 2>&1"
+ system(cmd)
+ str = ""
+ open("test_err_in_callback.log") {|ifs|
+ str = ifs.read
+ }
+ assert_match(/NameError/, str)
+ end
+ end
+
+ def teardown
+ File.unlink("test_err_in_callback.log")
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_folderitem2_invokeverb.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_folderitem2_invokeverb.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_folderitem2_invokeverb.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,91 @@
+#
+# This script check that Win32OLE can execute InvokeVerb method of FolderItem2.
+#
+
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require 'test/unit'
+
+if defined?(WIN32OLE)
+ class TestInvokeVerb < Test::Unit::TestCase
+ def setup
+ #
+ # make dummy.txt file for InvokeVerb test.
+ #
+
+ @fso = WIN32OLE.new('Scripting.FileSystemObject')
+ @dummy_file = @fso.GetTempName
+ @cfolder = @fso.getFolder(".")
+ f = @cfolder.CreateTextFile(@dummy_file)
+ f.close
+ @dummy_path = @cfolder.path + "\\" + @dummy_file
+
+ @shell=WIN32OLE.new('Shell.Application')
+ @nsp = @shell.NameSpace(@cfolder.path)
+ @fi2 = @nsp.parseName(@dummy_file)
+
+ @shortcut = nil
+
+ #
+ # Search the 'Create Shortcut (&S)' string in Japanese.
+ # Yes, I know the string in the Windows 2000 Japanese Edition.
+ # But I do not know about the string in any other Windows.
+ #
+ verbs = @fi2.verbs
+ verbs.extend(Enumerable)
+ @cp = WIN32OLE.codepage
+ begin
+ WIN32OLE.codepage = 932
+ rescue
+ end
+ @shortcut = verbs.collect{|verb|
+ verb.name
+ }.find {|name|
+ name.unpack("C*") == [131, 86, 131, 135, 129, 91, 131, 103, 131, 74, 131, 98, 131, 103, 130, 204, 141, 236, 144, 172, 40, 38, 83, 41]
+ # /.*\(\&S\)$/ =~ name
+ }
+ end
+
+ def find_link(path)
+ arlink = []
+ @cfolder.files.each do |f|
+ if /\.lnk$/ =~ f.path
+ linkinfo = @nsp.parseName(f.name).getLink
+ arlink.push f if linkinfo.path == path
+ end
+ end
+ arlink
+ end
+
+ def test_invokeverb
+ # this test should run only when "Create Shortcut (&S)"
+ # is found in context menu,
+ if @shortcut
+ links = find_link(@dummy_path)
+ assert_equal(0, links.size)
+
+ # Now create shortcut to @dummy_path
+ arg = WIN32OLE_VARIANT.new(@shortcut)
+ @fi2.InvokeVerb(arg)
+
+ # Now search shortcut to @dummy_path
+ links = find_link(@dummy_path)
+ assert_equal(1, links.size)
+ @lpath = links[0].path
+ end
+ end
+
+ def teardown
+ if @lpath
+ @fso.deleteFile(@lpath)
+ end
+ if @dummy_path
+ @fso.deleteFile(@dummy_path)
+ end
+ WIN32OLE.codepage = @cp
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_nil2vtempty.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_nil2vtempty.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_nil2vtempty.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,36 @@
+# This is test script to check that WIN32OLE should convert nil to VT_EMPTY in second try.
+# [ruby-talk:137054]
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require 'test/unit'
+
+if defined?(WIN32OLE)
+ class TestNIL2VT_EMPTY < Test::Unit::TestCase
+ def setup
+ fs = WIN32OLE.new('Scripting.FileSystemObject')
+ @path = fs.GetFolder(".").path
+ end
+ def test_openSchema
+ con = nil
+ begin
+ con = WIN32OLE.new('ADODB.Connection')
+ con.connectionString = "Provider=MSDASQL;Extended Properties="
+ con.connectionString +="\"DRIVER={Microsoft Text Driver (*.txt; *.csv)};DBQ=#{@path}\""
+ con.open
+ rescue
+ con = nil
+ end
+ if con
+ rs = con.openSchema(4, [nil,nil,"DUMMY", "TABLE"])
+ assert(rs)
+ assert_equal("_Recordset", rs.ole_type.name)
+
+ rs = con.openSchema(4, [WIN32OLE_VARIANT::Empty, WIN32OLE_VARIANT::Empty, "DUMMY", "TABLE"])
+ assert(rs)
+ assert_equal("_Recordset", rs.ole_type.name)
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_ole_methods.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_ole_methods.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_ole_methods.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,36 @@
+#
+# This is test for [ruby-talk:196897]
+#
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(WIN32OLE)
+ class TestWIN32OLE_FOR_PROPERTYPUTREF < Test::Unit::TestCase
+
+ def setup
+ @obj = WIN32OLE.new('Scripting.Dictionary')
+ end
+
+ def test_ole_methods
+ x = @obj.ole_methods.select {|m|
+ m.invoke_kind == 'PROPERTYPUTREF'
+ }
+ assert(x.size > 0)
+ assert_equal(1, x.size)
+ assert_equal('Item', x[0].name)
+ end
+
+ def test_ole_put_methods
+ x = @obj.ole_put_methods.select {|m|
+ m.invoke_kind == 'PROPERTYPUTREF'
+ }
+ assert(x.size > 0)
+ assert_equal(1, x.size)
+ assert_equal('Item', x[0].name)
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_propertyputref.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_propertyputref.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_propertyputref.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,30 @@
+require 'test/unit'
+begin
+ require 'win32ole'
+rescue LoadError
+end
+
+if defined?(WIN32OLE)
+ class TestWIN32OLE_PROPERTYPUTREF < Test::Unit::TestCase
+ def setup
+ begin
+ @sapi = WIN32OLE.new('SAPI.SpVoice')
+ @sv = @sapi.voice
+ rescue WIN32OLERuntimeError
+ @sapi = nil
+ end
+ end
+ def test_sapi
+ if @sapi
+ new_id = @sapi.getvoices.item(0).Id
+ @sapi.voice = @sapi.getvoices.item(0)
+ assert_equal(new_id, @sapi.voice.Id)
+ end
+ end
+ def teardown
+ if @sapi
+ @sapi.voice = @sv
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,516 @@
+#
+
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require 'test/unit'
+
+if defined?(WIN32OLE)
+ module CONST1
+ end
+ module CONST2
+ end
+
+ module TestCaseForDict
+ def test_convert_bignum
+ @dict1.add("a", 9999999999)
+ @dict1.add("b", 999999999)
+ @dict1.add("c", @dict1.item("b") * 10 + 9)
+ assert_equal(9999999999, @dict1.item("a"))
+ assert_equal(9999999999, @dict1.item("c"))
+ end
+ def test_add
+ @dict1.add("a", 1000)
+ assert_equal(1000, @dict1.item("a"))
+ end
+ def test_setproperty_equal_ended
+ @dict1.compareMode = 1
+ @dict1.add("one", 1)
+ assert_equal(1, @dict1.item("ONE"))
+ @dict2.add("one", 1)
+ assert_nil(@dict2.item("ONE"))
+ assert_equal(1, @dict2.item("one"))
+ end
+ def test_non_exist_property
+ assert_raise(WIN32OLERuntimeError) {
+ @dict1.unknown_property = 1
+ }
+ end
+
+ def test_raise_message
+ exc = assert_raise(WIN32OLERuntimeError) {
+ @dict1.add
+ }
+ assert_match(/^\(in OLE method `add': \)/, exc.message) #`
+
+ exc = assert_raise(WIN32OLERuntimeError) {
+ @dict1._invoke(1, [], [])
+ }
+ assert_match(/^\(in OLE method `<dispatch id:1>': \)/, exc.message) #`
+
+ exc = assert_raise(WIN32OLERuntimeError) {
+ @dict1.compareMode = -1
+ }
+ assert_match(/^\(in setting property `compareMode': \)/, exc.message) #`
+ end
+
+ def test_no_method_error
+ exc = assert_raise(NoMethodError) {
+ @dict1.non_exist_method
+ }
+ assert_match(/non_exist_method/, exc.message)
+ end
+
+ def test_ole_methods
+ methods = @dict1.ole_methods
+ mnames = methods.collect {|m|
+ m.name
+ }
+ assert(mnames.include?("Add"))
+ end
+
+ def test_ole_func_methods
+ methods = @dict1.ole_func_methods
+ mnames = methods.collect {|m|
+ m.name
+ }
+ assert(mnames.include?("Add"))
+ end
+
+ def test_ole_put_methods
+ methods = @dict1.ole_put_methods
+ mnames = methods.collect {|m|
+ m.name
+ }
+ assert(mnames.include?("CompareMode"))
+ end
+
+ def test_ole_get_methods
+ methods = @dict1.ole_get_methods
+ mnames = methods.collect {|m|
+ m.name
+ }
+ assert(mnames.include?("Count"))
+ end
+
+ def test_ole_mehtod_help
+ minfo = @dict1.ole_method_help("Add")
+ assert_equal(2, minfo.size_params)
+ end
+
+ def test_ole_typelib
+ tlib = @dict1.ole_typelib
+ assert_equal("Microsoft Scripting Runtime", tlib.name);
+ end
+
+ def test_each
+ @dict1.add("one", 1)
+ @dict1.add("two", 2)
+ i = 0
+ @dict1.keys.each do |item|
+ i += 1
+ end
+ assert_equal(2, i)
+ end
+
+ def test_bracket
+ @dict1.add("foo", "FOO")
+ assert_equal("FOO", @dict1.item("foo"))
+ assert_equal("FOO", @dict1["foo"])
+ end
+
+ def test_bracket_equal
+ @dict1.add("foo", "FOO")
+ @dict1["foo"] = "BAR"
+ assert_equal("BAR", @dict1["foo"])
+ end
+
+ def test_bracket_with_numkey
+ @dict1.add(1, "ONE")
+ @dict1.add(2, "two")
+ assert_equal("ONE", @dict1[1])
+ @dict1[2] = "TWO"
+ assert_equal("TWO", @dict1[2])
+ end
+
+ def test_invoke_with_array
+ @dict1.add("ary1", [1,2,3])
+ assert_equal([1,2,3], @dict1["ary1"])
+
+ @dict1.add("ary2", [[1,2,"a"], [3,4,"b"]])
+ assert_equal([[1,2,"a"], [3,4,"b"]], @dict1["ary2"])
+
+ @dict1.add("ary3", [[[1]]])
+ assert_equal([[[1]]], @dict1["ary3"])
+
+ @dict1.add("ary4", [[[1], [2], [3]], [[4], [5], [6]]])
+ assert_equal([[[1],[2], [3]], [[4], [5], [6]]], @dict1["ary4"])
+ end
+ end
+
+ class TestWin32OLE < Test::Unit::TestCase
+ include TestCaseForDict
+ def setup
+ @dict1 = WIN32OLE.new('Scripting.Dictionary')
+ @dict2 = WIN32OLE.new('Scripting.Dictionary')
+ end
+ def test_s_new
+ assert_instance_of(WIN32OLE, @dict1)
+ assert_instance_of(WIN32OLE, @dict2)
+ end
+
+ def test_s_new_exc
+ assert_raise(TypeError) {
+ WIN32OLE.new(1)
+ }
+ assert_raise(TypeError) {
+ WIN32OLE.new("Scripting.Dictionary", 1)
+ }
+ end
+
+ def test_s_new_DCOM
+ rshell = WIN32OLE.new("Shell.Application")
+ assert_instance_of(WIN32OLE, rshell)
+ end
+
+ def test_s_new_from_clsid
+ shell = WIN32OLE.new("{13709620-C279-11CE-A49E-444553540000}")
+ assert_instance_of(WIN32OLE, shell)
+ exc = assert_raise(WIN32OLERuntimeError) {
+ WIN32OLE.new("{000}")
+ }
+ assert_match(/unknown OLE server: `\{000\}'/, exc.message) #`
+ end
+
+ def test_s_connect
+ obj = WIN32OLE.connect("winmgmts:")
+ assert_instance_of(WIN32OLE, obj)
+ end
+
+ def test_s_connect_exc
+ assert_raise(TypeError) {
+ WIN32OLE.connect(1)
+ }
+ end
+
+ def test_invoke_accept_symbol_hash_key
+ fso = WIN32OLE.new('Scripting.FileSystemObject')
+ afolder = fso.getFolder(".")
+ bfolder = fso.getFolder({"FolderPath" => "."})
+ cfolder = fso.getFolder({:FolderPath => "."})
+ assert_equal(afolder.path, bfolder.path)
+ assert_equal(afolder.path, cfolder.path)
+ fso = nil
+ end
+
+ def test_setproperty
+ installer = WIN32OLE.new("WindowsInstaller.Installer")
+ record = installer.CreateRecord(2)
+ # this is the way to set property with argument in Win32OLE.
+ record.setproperty( "StringData", 1, 'dddd')
+ assert_equal('dddd', record.StringData(1))
+ end
+
+ def test_ole_type
+ fso = WIN32OLE.new('Scripting.FileSystemObject')
+ tobj = fso.ole_type
+ assert_match(/^IFileSystem/, tobj.name)
+ end
+
+ def test_ole_obj_help
+ fso = WIN32OLE.new('Scripting.FileSystemObject')
+ tobj = fso.ole_obj_help
+ assert_match(/^IFileSystem/, tobj.name)
+ end
+
+
+ def test_invoke_hash_key_non_str_sym
+ fso = WIN32OLE.new('Scripting.FileSystemObject')
+ begin
+ bfolder = fso.getFolder({1 => "."})
+ assert(false)
+ rescue TypeError
+ assert(true)
+ end
+ fso = nil
+ end
+
+ def test_get_win32ole_object
+ shell = WIN32OLE.new('Shell.Application')
+ folder = shell.nameSpace(0)
+ assert_instance_of(WIN32OLE, folder)
+ end
+
+ def test_invoke_accept_multi_hash_key
+ shell = WIN32OLE.new('Shell.Application')
+ folder = shell.nameSpace(0)
+ item = folder.items.item(0)
+ name = folder.getDetailsOf(item, 0)
+ assert_equal(item.name, name)
+ name = folder.getDetailsOf({:vItem => item, :iColumn => 0})
+ assert_equal(item.name, name)
+ name = folder.getDetailsOf({"vItem" => item, :iColumn => 0})
+ assert_equal(item.name, name)
+ end
+
+ def test_ole_invoke_with_named_arg_last
+ shell = WIN32OLE.new('Shell.Application')
+ folder = shell.nameSpace(0)
+ item = folder.items.item(0)
+ name = folder.getDetailsOf(item, {:iColumn => 0})
+ assert_equal(item.name, name)
+ end
+
+ def test__invoke
+ shell=WIN32OLE.new('Shell.Application')
+ assert_equal(shell.NameSpace(0).title, shell._invoke(0x60020002, [0], [WIN32OLE::VARIANT::VT_VARIANT]).title)
+ end
+
+ def test_ole_query_interface
+ shell=WIN32OLE.new('Shell.Application')
+ assert_raise(ArgumentError) {
+ shell2 = shell.ole_query_interface
+ }
+ shell2 = shell.ole_query_interface('{A4C6892C-3BA9-11D2-9DEA-00C04FB16162}')
+ assert_instance_of(WIN32OLE, shell2)
+ end
+
+ def test_ole_respond_to
+ fso = WIN32OLE.new('Scripting.FileSystemObject')
+ assert(fso.ole_respond_to?('getFolder'))
+ assert(fso.ole_respond_to?('GETFOLDER'))
+ assert(fso.ole_respond_to?(:getFolder))
+ assert(!fso.ole_respond_to?('XXXXX'))
+ assert_raise(TypeError) {
+ assert_raise(fso.ole_respond_to?(1))
+ }
+ end
+
+ def test_invoke
+ fso = WIN32OLE.new('Scripting.FileSystemObject')
+ assert(fso.invoke(:getFolder, "."))
+ assert(fso.invoke('getFolder', "."))
+ end
+
+ def test_s_const_load
+ assert(!defined?(CONST1::SsfWINDOWS))
+ shell=WIN32OLE.new('Shell.Application')
+ WIN32OLE.const_load(shell, CONST1)
+ assert_equal(36, CONST1::SsfWINDOWS)
+
+ assert(!defined?(CONST2::SsfWINDOWS))
+ WIN32OLE.const_load("Microsoft Shell Controls And Automation", CONST2)
+ assert_equal(36, CONST2::SsfWINDOWS)
+ end
+
+ def test_s_create_guid
+ guid = WIN32OLE.create_guid
+ assert_match(/^\{[A-Z0-9]{8}\-[A-Z0-9]{4}\-[A-Z0-9]{4}\-[A-Z0-9]{4}\-[A-Z0-9]{12}/,
+ guid)
+ end
+
+ #
+ # WIN32OLE.codepage is initialized according to Encoding.default_external.
+ #
+ # def test_s_codepage
+ # assert_equal(WIN32OLE::CP_ACP, WIN32OLE.codepage)
+ # end
+
+ def test_s_codepage_set
+ cp = WIN32OLE.codepage
+ WIN32OLE.codepage = WIN32OLE::CP_UTF8
+ assert_equal(WIN32OLE::CP_UTF8, WIN32OLE.codepage)
+ WIN32OLE.codepage = cp
+ end
+
+ def test_s_codepage_changed
+ cp = WIN32OLE.codepage
+ fso = WIN32OLE.new("Scripting.FileSystemObject")
+ fname = fso.getTempName
+ begin
+ obj = WIN32OLE_VARIANT.new([0x3042].pack("U*").force_encoding("UTF-8"))
+ WIN32OLE.codepage = WIN32OLE::CP_UTF8
+ assert_equal("\xE3\x81\x82".force_encoding("CP65001"), obj.value)
+
+ begin
+ WIN32OLE.codepage = 932 # Windows-31J
+ rescue WIN32OLERuntimeError
+ end
+ if (WIN32OLE.codepage == 932)
+ assert_equal("\x82\xA0".force_encoding("CP932"), obj.value)
+ end
+
+ begin
+ WIN32OLE.codepage = 20932 # MS EUC-JP
+ rescue WIN32OLERuntimeError
+ end
+ if (WIN32OLE.codepage == 20932)
+ assert_equal("\xA4\xA2".force_encoding("CP20932"), obj.value)
+ end
+
+ WIN32OLE.codepage = cp
+ file = fso.opentextfile(fname, 2, true)
+ begin
+ file.write [0x3042].pack("U*").force_encoding("UTF-8")
+ ensure
+ file.close
+ end
+ str = ""
+ open(fname, "r:ascii-8bit") {|ifs|
+ str = ifs.read
+ }
+ assert_equal("\202\240", str)
+
+ # This test fail if codepage 20932 (euc) is not installed.
+ begin
+ WIN32OLE.codepage = 20932
+ rescue WIN32OLERuntimeError
+ end
+ if (WIN32OLE.codepage == 20932)
+ WIN32OLE.codepage = cp
+ file = fso.opentextfile(fname, 2, true)
+ begin
+ file.write [164, 162].pack("c*").force_encoding("EUC-JP")
+ ensure
+ file.close
+ end
+ open(fname, "r:ascii-8bit") {|ifs|
+ str = ifs.read
+ }
+ assert_equal("\202\240", str)
+ end
+
+ ensure
+ WIN32OLE.codepage = cp
+ if (File.exist?(fname))
+ File.unlink(fname)
+ end
+ end
+ end
+
+ def test_cp51932
+ cp = WIN32OLE.codepage
+ begin
+ obj = WIN32OLE_VARIANT.new([0x3042].pack("U*").force_encoding("UTF-8"))
+ begin
+ WIN32OLE.codepage = 51932
+ rescue
+ end
+ if WIN32OLE.codepage == 51932
+ assert_equal("\xA4\xA2".force_encoding("CP51932"), obj.value)
+ end
+ ensure
+ WIN32OLE.codepage = cp
+ end
+ end
+
+ def test_s_locale
+ assert_equal(WIN32OLE::LOCALE_SYSTEM_DEFAULT, WIN32OLE.locale)
+ end
+
+ def test_s_locale_set
+ begin
+ begin
+ WIN32OLE.locale = 1041
+ rescue WIN32OLERuntimeError
+ STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_set is skipped(Japanese locale is not installed)")
+ return
+ end
+ assert_equal(1041, WIN32OLE.locale)
+ WIN32OLE.locale = WIN32OLE::LOCALE_SYSTEM_DEFAULT
+ assert_raise(WIN32OLERuntimeError) {
+ WIN32OLE.locale = 111
+ }
+ assert_equal(WIN32OLE::LOCALE_SYSTEM_DEFAULT, WIN32OLE.locale)
+ ensure
+ WIN32OLE.locale = WIN32OLE::LOCALE_SYSTEM_DEFAULT
+ end
+ end
+
+ def test_s_locale_change
+ begin
+ begin
+ WIN32OLE.locale = 0x0411
+ rescue WIN32OLERuntimeError
+ end
+ if WIN32OLE.locale == 0x0411
+ obj = WIN32OLE_VARIANT.new("\\100,000", WIN32OLE::VARIANT::VT_CY)
+ assert_equal("100000", obj.value)
+ assert_raise(WIN32OLERuntimeError) {
+ obj = WIN32OLE_VARIANT.new("$100.000", WIN32OLE::VARIANT::VT_CY)
+ }
+ else
+ STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_change is skipped(Japanese locale is not installed)")
+ end
+
+ begin
+ WIN32OLE.locale = 1033
+ rescue WIN32OLERuntimeError
+ end
+ if WIN32OLE.locale == 1033
+ obj = WIN32OLE_VARIANT.new("$100,000", WIN32OLE::VARIANT::VT_CY)
+ assert_equal("100000", obj.value)
+ else
+ STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_change is skipped(US English locale is not installed)")
+ end
+ ensure
+ WIN32OLE.locale = WIN32OLE::LOCALE_SYSTEM_DEFAULT
+ end
+ end
+
+ def test_const_CP_ACP
+ assert_equal(0, WIN32OLE::CP_ACP)
+ end
+
+ def test_const_CP_OEMCP
+ assert_equal(1, WIN32OLE::CP_OEMCP)
+ end
+
+ def test_const_CP_MACCP
+ assert_equal(2, WIN32OLE::CP_MACCP)
+ end
+
+ def test_const_CP_THREAD_ACP
+ assert_equal(3, WIN32OLE::CP_THREAD_ACP)
+ end
+
+ def test_const_CP_SYMBOL
+ assert_equal(42, WIN32OLE::CP_SYMBOL)
+ end
+
+ def test_const_CP_UTF7
+ assert_equal(65000, WIN32OLE::CP_UTF7)
+ end
+
+ def test_const_CP_UTF8
+ assert_equal(65001, WIN32OLE::CP_UTF8)
+ end
+
+ def test_const_LOCALE_SYSTEM_DEFAULT
+ assert_equal(0x0800, WIN32OLE::LOCALE_SYSTEM_DEFAULT);
+ end
+
+ def test_const_LOCALE_USER_DEFAULT
+ assert_equal(0x0400, WIN32OLE::LOCALE_USER_DEFAULT);
+ end
+ end
+
+ # test of subclass of WIN32OLE
+ class MyDict < WIN32OLE
+ def MyDict.new
+ super('Scripting.Dictionary')
+ end
+ end
+ class TestMyDict < Test::Unit::TestCase
+ include TestCaseForDict
+ def setup
+ @dict1 = MyDict.new
+ @dict2 = MyDict.new
+ end
+ def test_s_new
+ assert_instance_of(MyDict, @dict1)
+ assert_instance_of(MyDict, @dict2)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_event.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_event.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_event.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,334 @@
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require 'test/unit'
+
+def ado_installed?
+ installed = false
+ if defined?(WIN32OLE)
+ db = nil
+ begin
+ db = WIN32OLE.new('ADODB.Connection')
+ db.connectionString = "Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=.;"
+ db.open
+ db.close
+ db = nil
+ installed = true
+ rescue
+ end
+ end
+ installed
+end
+
+if defined?(WIN32OLE_EVENT)
+ dotest = ado_installed?
+ if !dotest
+ STDERR.puts("\n#{__FILE__} skipped(ActiveX Data Object Library not found.)")
+ end
+ if dotest
+ class TestWIN32OLE_EVENT < Test::Unit::TestCase
+ CONNSTR="Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=.;"
+ module ADO
+ end
+ def message_loop
+ WIN32OLE_EVENT.message_loop
+ end
+
+ def default_handler(event, *args)
+ @event += event
+ end
+
+ def setup
+ @db = WIN32OLE.new('ADODB.Connection')
+ if !defined?(ADO::AdStateOpen)
+ WIN32OLE.const_load(@db, ADO)
+ end
+ @db.connectionString = CONNSTR
+ @event = ""
+ @event2 = ""
+ @event3 = ""
+ end
+
+ def test_s_new
+ assert_raise(TypeError) {
+ ev = WIN32OLE_EVENT.new("A")
+ }
+ end
+
+ def test_s_new_without_itf
+ ev = WIN32OLE_EVENT.new(@db)
+ ev.on_event {|*args| default_handler(*args)}
+ @db.open
+ @db.close
+ 10.times do |i|
+ WIN32OLE_EVENT.new(@db)
+ GC.start
+ message_loop
+ @db.open
+ message_loop
+ @db.close
+ end
+ assert_match(/WillConnect/, @event)
+ end
+
+ def test_on_event
+ ev = WIN32OLE_EVENT.new(@db, 'ConnectionEvents')
+ ev.on_event {|*args| default_handler(*args)}
+ @db.open
+ message_loop
+ assert_match(/WillConnect/, @event)
+ end
+
+ def test_on_event_symbol
+ ev = WIN32OLE_EVENT.new(@db)
+ ev.on_event(:WillConnect) {|*args|
+ handler1
+ }
+ @db.open
+ message_loop
+ assert_equal("handler1", @event2)
+ end
+
+ def test_on_event2
+ ev = WIN32OLE_EVENT.new(@db, 'ConnectionEvents')
+ ev.on_event('WillConnect') {|*args| handler1}
+ ev.on_event('WillConnect') {|*args| handler2}
+ @db.open
+ message_loop
+ assert_equal("handler2", @event2)
+ end
+
+ def test_on_event3
+ ev = WIN32OLE_EVENT.new(@db, 'ConnectionEvents')
+ ev.on_event('WillConnect') {|*args| handler1}
+ ev.on_event('WillConnect') {|*args| handler2}
+ @db.open
+ message_loop
+ assert_equal("handler2", @event2)
+ end
+
+ def test_on_event4
+ ev = WIN32OLE_EVENT.new(@db, 'ConnectionEvents')
+ ev.on_event{|*args| handler1}
+ ev.on_event{|*args| handler2}
+ ev.on_event('WillConnect'){|*args| handler3(*args)}
+ @db.open
+ message_loop
+ assert_equal(CONNSTR, @event3)
+ assert("handler2", @event2)
+ end
+
+ def test_on_event5
+ ev = WIN32OLE_EVENT.new(@db, 'ConnectionEvents')
+ ev.on_event {|*args| default_handler(*args)}
+ ev.on_event('WillConnect'){|*args| handler3(*args)}
+ @db.open
+ message_loop
+ assert_match(/ConnectComplete/, @event)
+ assert(/WillConnect/ !~ @event)
+ assert_equal(CONNSTR, @event3)
+ end
+
+ def test_unadvise
+ ev = WIN32OLE_EVENT.new(@db, 'ConnectionEvents')
+ ev.on_event {|*args| default_handler(*args)}
+ @db.open
+ message_loop
+ assert_match(/WillConnect/, @event)
+ ev.unadvise
+ @event = ""
+ @db.close
+ @db.open
+ message_loop
+ assert_equal("", @event);
+ assert_raise(WIN32OLERuntimeError) {
+ ev.on_event {|*args| default_handler(*args)}
+ }
+ end
+
+ def test_non_exist_event
+ assert_raise(RuntimeError) {
+ ev = WIN32OLE_EVENT.new(@db, 'XXXX')
+ }
+ dict = WIN32OLE.new('Scripting.Dictionary')
+ assert_raise(RuntimeError) {
+ ev = WIN32OLE_EVENT.new(dict)
+ }
+ end
+
+ def test_on_event_with_outargs
+ ev = WIN32OLE_EVENT.new(@db)
+ @db.connectionString = 'XXX' # set illegal connection string
+ assert_raise(WIN32OLERuntimeError) {
+ @db.open
+ }
+ ev.on_event_with_outargs('WillConnect'){|*args|
+ args.last[0] = CONNSTR # ConnectionString = CONNSTR
+ }
+ @db.open
+ message_loop
+ assert(true)
+ end
+
+ def test_on_event_hash_return
+ ev = WIN32OLE_EVENT.new(@db)
+ ev.on_event('WillConnect'){|*args|
+ {:return => 1, :ConnectionString => CONNSTR}
+ }
+ @db.connectionString = 'XXX'
+ @db.open
+ assert(true)
+ end
+
+ def test_on_event_hash_return2
+ ev = WIN32OLE_EVENT.new(@db)
+ ev.on_event('WillConnect'){|*args|
+ {:ConnectionString => CONNSTR}
+ }
+ @db.connectionString = 'XXX'
+ @db.open
+ assert(true)
+ end
+
+ def test_on_event_hash_return3
+ ev = WIN32OLE_EVENT.new(@db)
+ ev.on_event('WillConnect'){|*args|
+ {'ConnectionString' => CONNSTR}
+ }
+ @db.connectionString = 'XXX'
+ @db.open
+ assert(true)
+ end
+
+ def test_on_event_hash_return4
+ ev = WIN32OLE_EVENT.new(@db)
+ ev.on_event('WillConnect'){|*args|
+ {'return' => 1, 'ConnectionString' => CONNSTR}
+ }
+ @db.connectionString = 'XXX'
+ @db.open
+ assert(true)
+ end
+
+ def test_on_event_hash_return5
+ ev = WIN32OLE_EVENT.new(@db)
+ ev.on_event('WillConnect'){|*args|
+ {0 => CONNSTR}
+ }
+ @db.connectionString = 'XXX'
+ @db.open
+ assert(true)
+ end
+
+ def test_off_event
+ ev = WIN32OLE_EVENT.new(@db)
+ ev.on_event{handler1}
+ ev.off_event
+ @db.open
+ message_loop
+ assert_equal("", @event2)
+ end
+
+ def test_off_event_arg
+ ev = WIN32OLE_EVENT.new(@db)
+ ev.on_event('WillConnect'){handler1}
+ ev.off_event('WillConnect')
+ @db.open
+ message_loop
+ assert_equal("", @event2)
+ end
+
+ def test_off_event_arg2
+ ev = WIN32OLE_EVENT.new(@db)
+ ev.on_event('WillConnect'){handler1}
+ ev.on_event('ConnectComplete'){handler1}
+ ev.off_event('WillConnect')
+ @db.open
+ message_loop
+ assert_equal("handler1", @event2)
+ end
+
+ def test_off_event_sym_arg
+ ev = WIN32OLE_EVENT.new(@db)
+ ev.on_event('WillConnect'){handler1}
+ ev.off_event(:WillConnect)
+ @db.open
+ message_loop
+ assert_equal("", @event2)
+ end
+
+ def handler1
+ @event2 = "handler1"
+ end
+
+ def handler2
+ @event2 = "handler2"
+ end
+
+ def handler3(*arg)
+ @event3 += arg[0]
+ end
+
+ def teardown
+ if @db && @db.state == ADO::AdStateOpen
+ @db.close
+ end
+ message_loop
+ @db = nil
+ end
+
+ class Handler1
+ attr_reader :val1, :val2, :val3, :val4
+ def initialize
+ @val1 = nil
+ @val2 = nil
+ @val3 = nil
+ @val4 = nil
+ end
+ def onWillConnect(conn, uid, pwd, opts, stat, pconn)
+ @val1 = conn
+ end
+ def onConnectComplete(err, stat, pconn)
+ @val2 = err
+ @val3 = stat
+ end
+ def onInfoMessage(err, stat, pconn)
+ @val4 = stat
+ end
+ end
+
+ class Handler2
+ attr_reader :ev
+ def initialize
+ @ev = ""
+ end
+ def method_missing(ev, *arg)
+ @ev += ev
+ end
+ end
+
+ def test_handler1
+ ev = WIN32OLE_EVENT.new(@db)
+ h1 = Handler1.new
+ ev.handler = h1
+ @db.open
+ message_loop
+ assert_equal(CONNSTR, h1.val1)
+ assert_equal(h1.val1, ev.handler.val1)
+ assert_equal(nil, h1.val2)
+ assert_equal(ADO::AdStateOpen, h1.val3)
+ assert_equal(ADO::AdStateOpen, h1.val4)
+ end
+
+ def test_handler2
+ ev = WIN32OLE_EVENT.new(@db)
+ h2 = Handler2.new
+ ev.handler = h2
+ @db.open
+ message_loop
+ assert(h2.ev != "")
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_method.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_method.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_method.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,146 @@
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(WIN32OLE_METHOD)
+ class TestWIN32OLE_METHOD < Test::Unit::TestCase
+
+ def setup
+ ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+ @m_open = WIN32OLE_METHOD.new(ole_type, "open")
+ @m_namespace = WIN32OLE_METHOD.new(ole_type, "namespace")
+ @m_parent = WIN32OLE_METHOD.new(ole_type, "parent")
+ @m_invoke = WIN32OLE_METHOD.new(ole_type, "invoke")
+ @m_browse_for_folder = WIN32OLE_METHOD.new(ole_type, "BrowseForFolder")
+
+ ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "File")
+ @m_file_name = WIN32OLE_METHOD.new(ole_type, "name")
+
+ ole_type = WIN32OLE_TYPE.new("Microsoft Internet Controls", "WebBrowser")
+ @m_navigate_complete = WIN32OLE_METHOD.new(ole_type, "NavigateComplete")
+ end
+
+ def test_initialize
+ ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+ assert_raise(TypeError) {
+ WIN32OLE_METHOD.new(1, 2)
+ }
+ assert_raise(ArgumentError) {
+ method = WIN32OLE_METHOD.new("foo")
+ }
+ assert_raise(ArgumentError) {
+ method = WIN32OLE_METHOD.new(ole_type)
+ }
+ assert_raise(WIN32OLERuntimeError) {
+ method = WIN32OLE_METHOD.new(ole_type, "NonExistMethod")
+ }
+ assert_raise(TypeError) {
+ method = WIN32OLE_METHOD.new(ole_type, 1)
+ }
+ method = WIN32OLE_METHOD.new(ole_type, "Open")
+ assert_instance_of(WIN32OLE_METHOD, method)
+ method = WIN32OLE_METHOD.new(ole_type, "open")
+ assert_instance_of(WIN32OLE_METHOD, method)
+ end
+
+ def test_name
+ assert_equal("Open", @m_open.name)
+ end
+
+ def test_return_type
+ assert_equal("VOID", @m_open.return_type)
+ assert_equal("Folder", @m_namespace.return_type)
+ end
+
+ def test_return_vtype
+ assert_equal(24, @m_open.return_vtype)
+ assert_equal(26, @m_namespace.return_vtype)
+ end
+
+ def test_return_type_detail
+ assert_equal(['VOID'], @m_open.return_type_detail)
+ assert_equal(['PTR', 'USERDEFINED', 'Folder'], @m_namespace.return_type_detail)
+ end
+
+ def test_invoke_kind
+ assert_equal('FUNC', @m_open.invoke_kind)
+ assert_equal('FUNC', @m_namespace.invoke_kind)
+ assert_equal('PROPERTYGET', @m_parent.invoke_kind)
+ end
+
+ def test_invkind
+ assert_equal(1, @m_namespace.invkind)
+ assert_equal(2, @m_parent.invkind)
+ end
+
+ def test_visible?
+ assert(@m_namespace.visible?)
+ assert(!@m_invoke.visible?)
+ end
+
+ def test_event?
+ assert(@m_navigate_complete.event?)
+ assert(!@m_namespace.event?)
+ end
+
+ def test_event_interface
+ assert_equal("DWebBrowserEvents", @m_navigate_complete.event_interface)
+ assert_equal(nil, @m_namespace.event_interface)
+ end
+
+ def test_helpstring
+ assert_equal("Get special folder from ShellSpecialFolderConstants", @m_namespace.helpstring)
+ end
+
+ def test_helpfile
+ assert_equal("", @m_namespace.helpfile)
+ assert_match(/VBENLR.*\.CHM$/i, @m_file_name.helpfile)
+ end
+
+ def test_helpcontext
+ assert_equal(0, @m_namespace.helpcontext)
+ assert_equal(2181996, @m_file_name.helpcontext)
+ end
+
+ def test_dispid
+ assert_equal(1610743810, @m_namespace.dispid)
+ end
+
+ def is_ruby64?
+ /mswin64|mingw64/ =~ RUBY_PLATFORM
+ end
+
+ def test_offset_vtbl
+ exp = is_ruby64? ? 48 : 24
+ assert_equal(exp, @m_invoke.offset_vtbl)
+ end
+
+ def test_size_params
+ assert_equal(1, @m_open.size_params)
+ assert_equal(4, @m_browse_for_folder.size_params)
+ end
+
+ def test_size_opt_params
+ assert_equal(0, @m_open.size_opt_params)
+ assert_equal(1, @m_browse_for_folder.size_opt_params)
+ end
+
+ def test_params
+ params = @m_browse_for_folder.params
+ assert_instance_of(Array, params)
+ assert_equal(4, params.size)
+ assert_instance_of(WIN32OLE_PARAM, params[0])
+ end
+
+ def test_to_s
+ assert_equal(@m_namespace.name, @m_namespace.to_s)
+ end
+
+ def test_inspect
+ assert_equal("#<WIN32OLE_METHOD:NameSpace>", @m_namespace.inspect)
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_param.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_param.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_param.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,106 @@
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(WIN32OLE_PARAM)
+ class TestWIN32OLE_PARAM < Test::Unit::TestCase
+
+ def setup
+ ole_type = WIN32OLE_TYPE.new("Microsoft Internet Controls", "WebBrowser")
+ m_navigate = WIN32OLE_METHOD.new(ole_type, "Navigate")
+ m_before_navigate = WIN32OLE_METHOD.new(ole_type, "BeforeNavigate")
+ params = m_navigate.params
+ @param_url = params[0]
+ @param_flags = params[1]
+ @param_cancel = m_before_navigate.params[5]
+
+ ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellLinkObject")
+ m_geticonlocation = WIN32OLE_METHOD.new(ole_type, "GetIconLocation")
+ @param_pbs = m_geticonlocation.params[0]
+
+ ole_type = WIN32OLE_TYPE.new("Microsoft HTML Object Library", "FontNames")
+ m_count = WIN32OLE_METHOD.new(ole_type, "Count")
+ @param_p = m_count.params[0]
+
+ ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "FileSystemObject")
+ m_copyfile = WIN32OLE_METHOD.new(ole_type, "CopyFile")
+ @param_overwritefiles = m_copyfile.params[2]
+ end
+
+ def test_s_new
+ assert_raise(ArgumentError) {
+ WIN32OLE_PARAM.new("hoge")
+ }
+ ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "FileSystemObject")
+ m_copyfile = WIN32OLE_METHOD.new(ole_type, "CopyFile")
+ assert_raise(IndexError) {
+ WIN32OLE_PARAM.new(m_copyfile, 4);
+ }
+ assert_raise(IndexError) {
+ WIN32OLE_PARAM.new(m_copyfile, 0);
+ }
+ assert_raise(IndexError) {
+ WIN32OLE_PARAM.new(m_copyfile, 0);
+ }
+ param = WIN32OLE_PARAM.new(m_copyfile, 3)
+ assert_equal("OverWriteFiles", param.name)
+ assert_equal(WIN32OLE_PARAM, param.class)
+ assert_equal(true, param.default)
+ assert_equal("#<WIN32OLE_PARAM:OverWriteFiles=true>", param.inspect)
+ end
+
+ def test_name
+ assert_equal('URL', @param_url.name)
+ assert_equal('Flags', @param_flags.name)
+ assert_equal('Cancel', @param_cancel.name)
+ end
+
+ def test_ole_type
+ assert_equal('BSTR', @param_url.ole_type)
+ assert_equal('VARIANT', @param_flags.ole_type)
+ end
+
+ def test_ole_type_detail
+ assert_equal(['BSTR'], @param_url.ole_type_detail)
+ assert_equal(['PTR', 'VARIANT'], @param_flags.ole_type_detail)
+ end
+
+ def test_input?
+ assert(@param_url.input?)
+ assert(@param_cancel.input?)
+ assert(!@param_pbs.input?)
+ end
+
+ def test_output?
+ assert(!@param_url.output?)
+ assert(@param_cancel.output?)
+ assert(@param_pbs.output?)
+ end
+
+ def test_optional?
+ assert(!@param_url.optional?)
+ assert(@param_flags.optional?)
+ end
+
+ def test_retval?
+ assert(!@param_url.retval?)
+ assert(@param_p.retval?)
+ end
+
+ def test_default
+ assert_equal(nil, @param_url.default)
+ assert_equal(true, @param_overwritefiles.default)
+ end
+
+ def test_to_s
+ assert_equal(@param_url.name, @param_url.to_s)
+ end
+
+ def test_inspect
+ assert_equal("#<WIN32OLE_PARAM:URL>", @param_url.inspect)
+ assert_equal("#<WIN32OLE_PARAM:OverWriteFiles=true>", @param_overwritefiles.inspect)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_type.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_type.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_type.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,249 @@
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(WIN32OLE_TYPE)
+ class TestWIN32OLE_TYPE < Test::Unit::TestCase
+
+ def test_s_progids
+ progids = WIN32OLE_TYPE.progids
+ assert_instance_of(Array, progids)
+ assert(progids.size > 0)
+ assert_instance_of(String, progids[0])
+ assert(progids.include?("Shell.Application.1"))
+ end
+
+ def test_initialize
+ assert_raise(ArgumentError) {
+ WIN32OLE_TYPE.new
+ }
+ assert_raise(ArgumentError) {
+ WIN32OLE_TYPE.new("foo")
+ }
+ assert_raise(TypeError) {
+ WIN32OLE_TYPE.new(1, 2)
+ }
+ assert_raise(TypeError) {
+ WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", 1)
+ }
+ assert_raise(WIN32OLERuntimeError) {
+ WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "foo")
+ }
+ assert_raise(WIN32OLERuntimeError) {
+ WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Application")
+ }
+ ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+ assert_instance_of(WIN32OLE_TYPE, ole_type)
+ assert_equal("Shell", ole_type.name)
+ assert_equal("Class", ole_type.ole_type)
+ assert_equal("{13709620-C279-11CE-A49E-444553540000}", ole_type.guid)
+ assert_equal("Shell.Application.1", ole_type.progid)
+ assert_equal(true, ole_type.visible?)
+ assert_equal("Shell", ole_type.to_s)
+ assert_equal(0, ole_type.major_version)
+ assert_equal(0, ole_type.minor_version)
+ assert_equal(5, ole_type.typekind)
+ assert_equal("Shell Object Type Information", ole_type.helpstring)
+ assert_equal(nil, ole_type.src_type)
+ assert_equal("", ole_type.helpfile)
+ assert_equal(0, ole_type.helpcontext)
+ assert_equal([], ole_type.variables)
+ assert(ole_type.ole_methods.select{|m|/NameSpace/i =~ m.name}.size > 0)
+
+ ole_type2 = WIN32OLE_TYPE.new("{13709620-C279-11CE-A49E-444553540000}", "Shell")
+ assert_instance_of(WIN32OLE_TYPE, ole_type)
+ assert_equal(ole_type.name, ole_type2.name)
+ assert_equal(ole_type.ole_type, ole_type2.ole_type)
+ assert_equal(ole_type.guid, ole_type2.guid)
+ assert_equal(ole_type.progid, ole_type2.progid)
+ assert_equal(ole_type.visible?, ole_type2.visible?)
+ assert_equal(ole_type.to_s, ole_type2.to_s)
+ assert_equal(ole_type.major_version, ole_type2.major_version)
+ assert_equal(ole_type.minor_version, ole_type2.minor_version)
+ assert_equal(ole_type.typekind, ole_type2.typekind)
+ assert_equal(ole_type.helpstring, ole_type2.helpstring)
+ assert_equal(ole_type.src_type, ole_type2.src_type)
+ assert_equal(ole_type.helpfile, ole_type2.helpfile)
+ assert_equal(ole_type.helpcontext, ole_type2.helpcontext)
+ assert_equal(ole_type.variables.size, ole_type2.variables.size)
+ assert_equal(ole_type.ole_methods[0].name, ole_type2.ole_methods[0].name)
+ assert_equal(ole_type.ole_typelib.name, ole_type2.ole_typelib.name)
+ assert_equal(ole_type.implemented_ole_types.size, ole_type2.implemented_ole_types.size)
+ assert_equal(ole_type.inspect, ole_type2.inspect)
+ end
+
+ def setup
+ @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+ end
+
+ def test_name
+ assert_equal("Shell", @ole_type.name)
+ end
+
+ def test_ole_type
+ assert_equal("Class", @ole_type.ole_type)
+ end
+
+ def test_guid
+ assert_equal("{13709620-C279-11CE-A49E-444553540000}", @ole_type.guid)
+ end
+
+ def test_progid
+ assert_equal("Shell.Application.1", @ole_type.progid)
+ end
+
+ def test_visible?
+ assert(@ole_type.visible?)
+ ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "IShellDispatch")
+ assert(!ole_type.visible?)
+ end
+
+ def test_to_s
+ assert_equal(@ole_type.to_s, @ole_type.name)
+ end
+
+ def test_major_version
+ assert_equal(0, @ole_type.major_version)
+ # ole_type = WIN32OLE_TYPE.new("Microsoft Word 11.0 Object Library", "Documents")
+ # assert_equal(8, ole_type.major_version)
+ end
+
+ def test_minor_version
+ assert_equal(0, @ole_type.minor_version)
+ # ole_type = WIN32OLE_TYPE.new("Microsoft Word 11.0 Object Library", "Documents")
+ # assert_equal(3, ole_type.minor_version)
+ end
+
+ def test_typekind
+ assert_equal(5, @ole_type.typekind)
+ end
+
+ def test_helpstring
+ assert_equal("Shell Object Type Information", @ole_type.helpstring)
+ end
+
+ def test_src_type
+ ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "DriveTypeConst")
+ assert_match(/__MIDL___MIDL_itf_scrrun_/, ole_type.src_type)
+ assert_equal(nil, @ole_type.src_type)
+ end
+
+ def test_helpfile
+ assert_equal("", @ole_type.helpfile)
+ ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "Folders")
+ assert_match(/VBENLR98\.CHM$/i, ole_type.helpfile)
+ end
+
+ def test_helpcontext
+ assert_equal(0, @ole_type.helpcontext)
+ ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "Folders")
+ assert_equal(2181929, ole_type.helpcontext)
+ end
+
+ def test_variables
+ variables = @ole_type.variables
+ assert_instance_of(Array, variables)
+ assert(variables.size == 0)
+
+ ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
+ variables = ole_type.variables
+ assert_instance_of(Array, variables)
+ assert(variables.size > 0)
+
+ assert_instance_of(WIN32OLE_VARIABLE, variables[0])
+ end
+
+ def test_ole_methods
+ methods = @ole_type.ole_methods
+ assert_instance_of(Array, methods)
+ assert(methods.size > 0)
+ assert_instance_of(WIN32OLE_METHOD, methods[0]);
+ assert(methods.collect{|m| m.name}.include?("Application"))
+ end
+
+ def test_ole_typelib
+ tlib = @ole_type.ole_typelib
+ assert_instance_of(WIN32OLE_TYPELIB, tlib)
+ assert_equal("Microsoft Shell Controls And Automation", tlib.name)
+ end
+
+ def test_implemented_ole_types
+ ole_types = @ole_type.implemented_ole_types
+ assert_instance_of(Array, ole_types)
+ assert_equal(1, ole_types.size)
+ assert_match(/^IShellDispatch5{0,1}$/, ole_types[0].name)
+
+ ie_otype = WIN32OLE_TYPE.new("Microsoft Internet Controls", "InternetExplorer")
+ ole_types = ie_otype.implemented_ole_types
+ assert_equal(4, ole_types.size)
+ otype = ole_types.select{|t| t.name == "IWebBrowser2"}
+ assert_equal(1, otype.size)
+ otype = ole_types.select{|t| t.name == "IWebBrowserApp"}
+ assert_equal(1, otype.size)
+ otype = ole_types.select{|t| t.name == "DWebBrowserEvents2"}
+ assert_equal(1, otype.size)
+ otype = ole_types.select{|t| t.name == "DWebBrowserEvents"}
+ assert_equal(1, otype.size)
+ end
+
+ def test_default_ole_types
+ ie_otype = WIN32OLE_TYPE.new("Microsoft Internet Controls", "InternetExplorer")
+ ole_types = ie_otype.default_ole_types
+ otype = ole_types.select{|t| t.name == "IWebBrowser2"}
+ assert_equal(1, otype.size)
+ otype = ole_types.select{|t| t.name == "IWebBrowserApp"}
+ assert_equal(0, otype.size)
+ otype = ole_types.select{|t| t.name == "DWebBrowserEvents2"}
+ assert_equal(1, otype.size)
+ otype = ole_types.select{|t| t.name == "DWebBrowserEvents"}
+ assert_equal(0, otype.size)
+ end
+
+ def test_source_ole_types
+ ie_otype = WIN32OLE_TYPE.new("Microsoft Internet Controls", "InternetExplorer")
+ ole_types = ie_otype.source_ole_types
+ otype = ole_types.select{|t| t.name == "IWebBrowser2"}
+ assert_equal(0, otype.size)
+ otype = ole_types.select{|t| t.name == "IWebBrowserApp"}
+ assert_equal(0, otype.size)
+ otype = ole_types.select{|t| t.name == "DWebBrowserEvents2"}
+ assert_equal(1, otype.size)
+ otype = ole_types.select{|t| t.name == "DWebBrowserEvents"}
+ assert_equal(1, otype.size)
+ end
+
+ def test_default_event_sources
+ ie_otype = WIN32OLE_TYPE.new("Microsoft Internet Controls", "InternetExplorer")
+ ole_types = ie_otype.default_event_sources
+ otype = ole_types.select{|t| t.name == "IWebBrowser2"}
+ assert_equal(0, otype.size)
+ otype = ole_types.select{|t| t.name == "IWebBrowserApp"}
+ assert_equal(0, otype.size)
+ otype = ole_types.select{|t| t.name == "DWebBrowserEvents2"}
+ assert_equal(1, otype.size)
+ otype = ole_types.select{|t| t.name == "DWebBrowserEvents"}
+ assert_equal(0, otype.size)
+ end
+
+ def test_inspect
+ assert_equal("#<WIN32OLE_TYPE:Shell>", @ole_type.inspect)
+ end
+ # WIN32OLE_TYPE.typelibs will be obsoleted.
+ def test_s_typelibs
+ tlibs = WIN32OLE_TYPE.typelibs.sort
+ tlibs2 = WIN32OLE_TYPELIB.typelibs.collect{|t|t.name}.sort
+ assert_equal(tlibs2, tlibs)
+ end
+
+ # WIN32OLE_TYPE.ole_classes will be obsoleted.
+ def test_s_ole_classes
+ ots1 = WIN32OLE_TYPE.ole_classes("Microsoft Shell Controls And Automation")
+ ots2 = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation").ole_types
+ otns1 = ots1.collect{|t| t.name}.sort
+ otns2 = ots2.collect{|t| t.name}.sort
+ assert_equal(otns2, otns1)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_typelib.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_typelib.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_typelib.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,110 @@
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(WIN32OLE_TYPELIB)
+ class TestWIN32OLE_TYPELIB < Test::Unit::TestCase
+ def test_s_typelibs
+ tlibs = WIN32OLE_TYPELIB.typelibs
+ assert_instance_of(Array, tlibs)
+ assert(tlibs.size > 0)
+ tlib = tlibs.find {|t| t.name == "Microsoft Shell Controls And Automation"}
+ assert(tlib)
+ end
+
+ def test_initialize
+ assert_raise(ArgumentError) {
+ WIN32OLE_TYPELIB.new(1,2,3,4)
+ }
+
+ assert_raise(TypeError) {
+ WIN32OLE_TYPELIB.new(100)
+ }
+
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ assert_instance_of(WIN32OLE_TYPELIB, tlib)
+
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation", 1.0)
+ assert_instance_of(WIN32OLE_TYPELIB, tlib)
+
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation", 1, 0)
+ assert_instance_of(WIN32OLE_TYPELIB, tlib)
+ guid = tlib.guid
+
+ tlib_by_guid = WIN32OLE_TYPELIB.new(guid, 1, 0)
+ assert_instance_of(WIN32OLE_TYPELIB, tlib_by_guid)
+ assert_equal("Microsoft Shell Controls And Automation" , tlib_by_guid.name)
+
+ path = tlib.path
+ tlib_by_path = WIN32OLE_TYPELIB.new(path)
+ assert_equal("Microsoft Shell Controls And Automation" , tlib_by_path.name)
+
+ assert_raise(WIN32OLERuntimeError) {
+ WIN32OLE_TYPELIB.new("Non Exist Type Library")
+ }
+ end
+
+ def test_guid
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ assert_equal("{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}", tlib.guid)
+ end
+
+ def test_name
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ assert_equal("Microsoft Shell Controls And Automation", tlib.name)
+ tlib = WIN32OLE_TYPELIB.new("{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}")
+ assert_equal("Microsoft Shell Controls And Automation", tlib.name)
+ end
+
+ def test_version
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ assert_equal(1.0, tlib.version)
+ end
+
+ def test_major_version
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ assert_equal(1, tlib.major_version)
+ end
+
+ def test_minor_version
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ assert_equal(0, tlib.minor_version)
+ end
+
+ def test_path
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ assert_match(/shell32\.dll$/i, tlib.path)
+ end
+
+ def test_visible?
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ assert(tlib.visible?)
+ end
+
+ def test_library_name
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ assert_equal("Shell32", tlib.library_name)
+ end
+
+ def test_to_s
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ assert_equal("Microsoft Shell Controls And Automation", tlib.to_s)
+ end
+
+ def test_ole_types
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ ole_types = tlib.ole_types
+ assert_instance_of(Array, ole_types)
+ assert(ole_types.size > 0)
+ assert_instance_of(WIN32OLE_TYPE, ole_types[0])
+ end
+
+ def test_inspect
+ tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ assert_equal("#<WIN32OLE_TYPELIB:Microsoft Shell Controls And Automation>", tlib.inspect)
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variable.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variable.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variable.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,61 @@
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(WIN32OLE_VARIABLE)
+ class TestWIN32OLE_VARIABLE < Test::Unit::TestCase
+
+ def setup
+ ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
+ @var1 = ole_type.variables.find {|v| v.name == 'ssfDESKTOP'}
+
+ variables = WIN32OLE_TYPE.new("Microsoft Windows Installer Object Library", "Installer").variables
+ @var2 = variables.find {|v| v.name == 'UILevel'}
+ end
+
+ def test_name
+ assert_equal('ssfDESKTOP', @var1.name)
+ end
+
+ def test_ole_type
+ assert_equal('INT', @var1.ole_type)
+ assert_equal('MsiUILevel', @var2.ole_type)
+ end
+
+ def test_ole_type_detail
+ assert_equal(['INT'], @var1.ole_type_detail)
+ assert_equal(['USERDEFINED', 'MsiUILevel'], @var2.ole_type_detail)
+ end
+
+ def test_ole_type_value
+ assert_equal(0, @var1.value)
+ assert_equal(nil, @var2.value)
+ end
+
+ def test_ole_type_visible?
+ assert(@var1.visible?)
+ end
+
+ def test_ole_type_variable_kind
+ assert_equal("CONSTANT", @var1.variable_kind)
+ assert_equal("DISPATCH", @var2.variable_kind)
+ end
+
+ def test_ole_type_varkind
+ assert_equal(2, @var1.varkind)
+ assert_equal(3, @var2.varkind)
+ end
+
+ def test_to_s
+ assert_equal(@var1.name, @var1.to_s)
+ end
+
+ def test_inspect
+ assert_equal("#<WIN32OLE_VARIABLE:ssfDESKTOP=0>", @var1.inspect)
+ assert_equal("#<WIN32OLE_VARIABLE:UILevel=nil>", @var2.inspect)
+ end
+
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variant.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variant.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variant.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,661 @@
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require "test/unit"
+
+$MSGS = []
+def add_skip_message(msg)
+ $MSGS.push msg
+end
+
+if defined?(WIN32OLE_VARIANT)
+
+ class TestWIN32OLE_VARIANT < Test::Unit::TestCase
+
+ def test_s_new
+ obj = WIN32OLE_VARIANT.new('foo')
+ assert_instance_of(WIN32OLE_VARIANT, obj)
+ end
+
+ def test_s_new_exc
+ assert_raise(TypeError) {
+ WIN32OLE_VARIANT.new(/foo/)
+ }
+ end
+
+ def test_s_new_no_argument
+ ex = nil
+ begin
+ obj = WIN32OLE_VARIANT.new
+ rescue ArgumentError
+ ex = $!
+ end
+ assert_instance_of(ArgumentError, ex)
+ assert_equal("wrong number of arguments (0 for 1..3)", ex.message);
+ end
+
+ def test_s_new_one_argument
+ ex = nil
+ begin
+ obj = WIN32OLE_VARIANT.new('foo')
+ rescue
+ ex = $!
+ end
+ assert_equal(nil, ex);
+ end
+
+ def test_s_new_with_nil
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_I2)
+ assert_equal(0, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I2, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_I4)
+ assert_equal(0, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_R4)
+ assert_equal(0, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_R4, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_R8)
+ assert_equal(0, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_R8, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_CY)
+ assert_equal("0", obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_CY, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(1899,12,30), obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_DATE, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_BSTR)
+ assert_equal("", obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_BSTR, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_DISPATCH)
+ assert_nil(obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_DISPATCH, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_BOOL)
+ assert_equal(false, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_BOOL, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_VARIANT)
+ assert_nil(obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_VARIANT, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_I1)
+ assert_equal(0, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I1, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_UI1)
+ assert_equal(0, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UI1, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_UI2)
+ assert_equal(0, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UI2, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_UI4)
+ assert_equal(0, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UI4, obj.vartype)
+
+
+ if defined?(WIN32OLE::VARIANT::VT_I8)
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_I8)
+ assert_equal(0, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I8, obj.vartype)
+ end
+
+ if defined?(WIN32OLE::VARIANT::VT_UI8)
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_UI8)
+ assert_equal(0, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UI8, obj.vartype)
+ end
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_INT)
+ assert_equal(0, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_INT, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_UINT)
+ assert_equal(0, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UINT, obj.vartype)
+ end
+
+ def test_s_new_with_non_nil
+ obj = WIN32OLE_VARIANT.new(2, WIN32OLE::VARIANT::VT_I2)
+ assert_equal(2, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I2, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(3, WIN32OLE::VARIANT::VT_I4)
+ assert_equal(3, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(4.5, WIN32OLE::VARIANT::VT_R4)
+ assert_equal(4.5, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_R4, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(5.5, WIN32OLE::VARIANT::VT_R8)
+ assert_equal(5.5, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_R8, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(600, WIN32OLE::VARIANT::VT_CY)
+ assert_equal("600", obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_CY, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new("2001-06-15 12:17:34", WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(2001,06,15,12,17,34), obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_DATE, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new("foo", WIN32OLE::VARIANT::VT_BSTR)
+ assert_equal("foo", obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_BSTR, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(true, WIN32OLE::VARIANT::VT_BOOL)
+ assert_equal(true, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_BOOL, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(2, WIN32OLE::VARIANT::VT_I1)
+ assert_equal(2, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I1, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(3, WIN32OLE::VARIANT::VT_UI1)
+ assert_equal(3, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UI1, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(4, WIN32OLE::VARIANT::VT_UI2)
+ assert_equal(4, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UI2, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(5, WIN32OLE::VARIANT::VT_UI4)
+ assert_equal(5, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UI4, obj.vartype)
+
+ if defined?(WIN32OLE::VARIANT::VT_I8)
+ obj = WIN32OLE_VARIANT.new(-123456789012345, WIN32OLE::VARIANT::VT_I8)
+ assert_equal(-123456789012345, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I8, obj.vartype)
+ end
+
+ if defined?(WIN32OLE::VARIANT::VT_UI8)
+ obj = WIN32OLE_VARIANT.new(123456789012345, WIN32OLE::VARIANT::VT_UI8)
+ assert_equal(123456789012345, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UI8, obj.vartype)
+ end
+
+ obj = WIN32OLE_VARIANT.new(4, WIN32OLE::VARIANT::VT_INT)
+ assert_equal(4, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_INT, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(5, WIN32OLE::VARIANT::VT_UINT)
+ assert_equal(5, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UINT, obj.vartype)
+ end
+
+ def test_s_new_with_non_nil_byref
+ obj = WIN32OLE_VARIANT.new(2, WIN32OLE::VARIANT::VT_I2|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(2, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I2|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(3, WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(3, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(4.5, WIN32OLE::VARIANT::VT_R4|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(4.5, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_R4|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(5.5, WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(5.5, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(600, WIN32OLE::VARIANT::VT_CY|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal("600", obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_CY|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new("2001-06-15 12:17:34", WIN32OLE::VARIANT::VT_DATE|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(Time.new(2001,06,15,12,17,34), obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_DATE|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new("foo", WIN32OLE::VARIANT::VT_BSTR|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal("foo", obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_BSTR|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(true, WIN32OLE::VARIANT::VT_BOOL|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(true, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_BOOL|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(2, WIN32OLE::VARIANT::VT_I1|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(2, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I1|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(3, WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(3, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(4, WIN32OLE::VARIANT::VT_UI2|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(4, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UI2|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(5, WIN32OLE::VARIANT::VT_UI4|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(5, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UI4|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(4, WIN32OLE::VARIANT::VT_INT|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(4, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_INT|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new(5, WIN32OLE::VARIANT::VT_UINT|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(5, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UINT|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+ end
+
+ # This test is failed in cygwin.
+ # The tagVARIANT definition has no union member pllVal in cygwin.
+ def test_s_new_with_i8_byref
+ if defined?(WIN32OLE::VARIANT::VT_I8) && /mswin/ =~ RUBY_PLATFORM
+ obj = WIN32OLE_VARIANT.new(-123456789012345, WIN32OLE::VARIANT::VT_I8|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(-123456789012345, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I8|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+ else
+ STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_new_with_i8_byref is skipped")
+ end
+ end
+
+ # This test is failed in cygwin.
+ # The tagVARIANT definition has no union member pullVal in cygwin.
+ def test_s_new_with_ui8_byref
+ if defined?(WIN32OLE::VARIANT::VT_UI8) && /mswin/ =~ RUBY_PLATFORM
+ obj = WIN32OLE_VARIANT.new(123456789012345, WIN32OLE::VARIANT::VT_UI8|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(123456789012345, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_UI8|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+ else
+ STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_new_with_ui8_byref is skipped.")
+ end
+ end
+
+ def test_value
+ obj = WIN32OLE_VARIANT.new('foo')
+ assert_equal('foo', obj.value)
+ end
+
+ def test_s_new_2_argument
+ obj = WIN32OLE_VARIANT.new('foo', WIN32OLE::VARIANT::VT_BSTR|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal('foo', obj.value);
+ end
+
+ def test_s_new_2_argument2
+ obj = WIN32OLE_VARIANT.new('foo', WIN32OLE::VARIANT::VT_BSTR)
+ assert_equal('foo', obj.value);
+ end
+
+ def test_s_new_dispatch_array
+ vt = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_DISPATCH
+ obj = WIN32OLE_VARIANT.new(nil, vt)
+ assert_equal(vt, obj.vartype)
+ assert_nil(obj.value)
+
+ vt = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_DISPATCH|WIN32OLE::VARIANT::VT_BYREF
+ obj = WIN32OLE_VARIANT.new(nil, vt)
+ assert_equal(vt, obj.vartype)
+ assert_nil(obj.value)
+ end
+
+ def test_s_new_array
+ # should not occur stack over flow
+ ar = (1..500000).to_a.map{|i| [i]}
+ ar2 = WIN32OLE_VARIANT.new(ar)
+ assert_equal(ar, ar2.value)
+ end
+
+ def test_s_array
+ obj = WIN32OLE_VARIANT.array([2,3], WIN32OLE::VARIANT::VT_I4)
+ assert_instance_of(WIN32OLE_VARIANT, obj)
+ assert_equal(WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_ARRAY, obj.vartype)
+ assert_equal([[0, 0, 0],[0, 0, 0]], obj.value)
+
+ obj = WIN32OLE_VARIANT.array([2,3], WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF|WIN32OLE::VARIANT::VT_ARRAY, obj.vartype)
+ assert_equal([[0, 0, 0],[0, 0, 0]], obj.value)
+
+ obj = WIN32OLE_VARIANT.array([2,3], WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_ARRAY)
+ assert_instance_of(WIN32OLE_VARIANT, obj)
+ assert_equal(WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_ARRAY, obj.vartype)
+ assert_equal([[0, 0, 0],[0, 0, 0]], obj.value)
+
+ assert_equal(0, obj[0,0])
+ obj[0,0] = 10
+ assert_equal([[10, 0, 0],[0, 0, 0]], obj.value)
+ obj[0,1] = "13.2"
+ assert_equal([[10, 13, 0],[0, 0, 0]], obj.value)
+
+ obj = WIN32OLE_VARIANT.array([3, 2], WIN32OLE::VARIANT::VT_VARIANT)
+ obj[0,0] = 10
+ obj[0,1] = "string"
+ obj[1,0] = 12.735
+ assert_equal([[10, "string"],[12.735, nil],[nil,nil]], obj.value)
+
+ obj = WIN32OLE_VARIANT.array([2,3], WIN32OLE::VARIANT::VT_DISPATCH)
+ assert_equal([[nil, nil, nil],[nil,nil,nil]], obj.value)
+
+ end
+
+ def test_s_array_exc
+ assert_raise(TypeError) {
+ obj = WIN32OLE_VARIANT.array(2, WIN32OLE::VARIANT::VT_I4)
+ }
+ end
+
+ def test_conversion_num2str
+ obj = WIN32OLE_VARIANT.new(124, WIN32OLE::VARIANT::VT_BSTR)
+ assert_equal("124", obj.value);
+ end
+
+ def test_conversion_float2int
+ obj = WIN32OLE_VARIANT.new(12.345, WIN32OLE::VARIANT::VT_I4)
+ assert_equal(12, obj.value)
+ obj = WIN32OLE_VARIANT.new(12.345, WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(12, obj.value)
+ end
+
+ def test_conversion_str2num
+ obj = WIN32OLE_VARIANT.new("12.345", WIN32OLE::VARIANT::VT_R8)
+ assert_equal(12.345, obj.value)
+ end
+
+ def test_conversion_ole_variant2ole_variant
+ obj = WIN32OLE_VARIANT.new("12.345", WIN32OLE::VARIANT::VT_R4)
+ obj = WIN32OLE_VARIANT.new(obj, WIN32OLE::VARIANT::VT_I4)
+ assert_equal(12, obj.value)
+ end
+
+ def test_conversion_str2date
+ obj = WIN32OLE_VARIANT.new("2004-12-24 12:24:45", WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(2004,12,24,12,24,45), obj.value)
+ end
+
+ def test_conversion_time2date
+ dt = Time.mktime(2004, 12, 24, 12, 24, 45)
+ obj = WIN32OLE_VARIANT.new(dt, WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(dt, obj.value)
+ end
+
+ # this test failed because of VariantTimeToSystemTime
+ # and SystemTimeToVariantTime API ignores wMilliseconds
+ # member of SYSTEMTIME struct.
+ #
+ # def test_conversion_time_nsec2date
+ # dt = Time.new(2004, 12,24, 12, 24, 45)
+ # dt += 0.1
+ # obj = WIN32OLE_VARIANT.new(dt, WIN32OLE::VARIANT::VT_DATE)
+ # assert_equal(dt, obj.value)
+ # end
+
+ def test_conversion_str2cy
+ begin
+ begin
+ WIN32OLE.locale = 0x0411 # set locale Japanese
+ rescue WIN32OLERuntimeError
+ STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_conversion_str2cy is skipped(Japanese locale is not installed)")
+ end
+ if WIN32OLE.locale == 0x0411
+ obj = WIN32OLE_VARIANT.new("\\10,000", WIN32OLE::VARIANT::VT_CY)
+ assert_equal("10000", obj.value)
+ end
+ ensure
+ WIN32OLE.locale = WIN32OLE::LOCALE_SYSTEM_DEFAULT
+ end
+ end
+
+ def test_create_vt_array
+ obj = WIN32OLE_VARIANT.new([1.2, 2.3], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8)
+ assert_equal([1.2, 2.3], obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new([1.2, 2.3], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal([1.2, 2.3], obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+ end
+
+ def test_create_vt_array2
+ obj = WIN32OLE_VARIANT.new([1.2, "a"], WIN32OLE::VARIANT::VT_ARRAY)
+ assert_equal([1.2, "a"], obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_VARIANT, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new([1.2, "a"])
+ assert_equal([1.2, "a"], obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_VARIANT, obj.vartype)
+ end
+
+
+ def test_create_vt_nested_array
+ obj = WIN32OLE_VARIANT.new([[1.2, "a", "b"], [3.4, "C", "D"]], WIN32OLE::VARIANT::VT_ARRAY)
+ assert_equal([[1.2, "a", "b"], [3.4, "C", "D"]], obj.value)
+
+ obj = WIN32OLE_VARIANT.new([[1.2, "a", "b"], [3.4, "C", "D"]])
+ assert_equal([[1.2, "a", "b"], [3.4, "C", "D"]], obj.value)
+
+ obj = WIN32OLE_VARIANT.new([[1.2, "a", "b"], [3.4, "C", "D"], [5.6, "E", "F"]])
+ assert_equal([[1.2, "a", "b"], [3.4, "C", "D"], [5.6, "E", "F"]], obj.value)
+
+ obj = WIN32OLE_VARIANT.new([[[1.2], [3.4]], [[5.6], [7.8]], [[9.1],[9.2]]])
+ assert_equal([[[1.2], [3.4]], [[5.6], [7.8]], [[9.1],[9.2]]], obj.value)
+ end
+
+ def test_create_vt_array3
+ obj = WIN32OLE_VARIANT.new([])
+ assert_equal([], obj.value)
+
+ obj = WIN32OLE_VARIANT.new([[]])
+ assert_equal([[]], obj.value)
+
+ obj = WIN32OLE_VARIANT.new([[],[]])
+ assert_equal([[],[]], obj.value)
+
+ obj = WIN32OLE_VARIANT.new([], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal([], obj.value)
+
+ obj = WIN32OLE_VARIANT.new([[]], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal([[]], obj.value)
+
+ obj = WIN32OLE_VARIANT.new([[],[]], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal([[],[]], obj.value)
+ end
+
+ def test_create_vt_array_nil
+ vartype = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_DISPATCH|WIN32OLE::VARIANT::VT_BYREF
+ obj = WIN32OLE_VARIANT.new(nil, vartype)
+ assert_nil(obj.value)
+ assert_equal(vartype, obj.vartype)
+
+ vartype = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_DISPATCH
+ obj = WIN32OLE_VARIANT.new(nil, vartype)
+ assert_nil(obj.value)
+ assert_equal(vartype, obj.vartype)
+ end
+
+ def test_create_vt_array_str
+ vartype = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BSTR
+ obj = WIN32OLE_VARIANT.new(["abc", "123"], vartype)
+ assert_equal(vartype, obj.vartype)
+ assert_equal(["abc", "123"], obj.value)
+
+ vartype = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF|WIN32OLE::VARIANT::VT_BSTR
+ obj = WIN32OLE_VARIANT.new(["abc", "123"], vartype)
+ assert_equal(vartype, obj.vartype)
+ assert_equal(["abc", "123"], obj.value)
+ end
+
+ def test_create_vt_array_exc
+ exc = assert_raise(TypeError) {
+ obj = WIN32OLE_VARIANT.new(1, WIN32OLE::VARIANT::VT_ARRAY);
+ }
+ assert_match(/wrong argument type Fixnum \(expected Array\)/, exc.message)
+ end
+
+ def test_create_vt_array_str2ui1array
+ obj = WIN32OLE_VARIANT.new("ABC", WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1)
+ assert_equal("ABC", obj.value)
+
+ obj.value = "DEF"
+ assert_equal("DEF", obj.value)
+ obj[0] = 71
+ assert_equal("GEF", obj.value)
+
+ obj = WIN32OLE_VARIANT.new([65, 0].pack("C*"), WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1)
+ assert_equal([65, 0].pack("C*"), obj.value)
+
+ obj = WIN32OLE_VARIANT.new("abc", WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal("abc", obj.value)
+ obj.value = "DEF"
+ assert_equal("DEF", obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
+ obj[1] = 71
+ assert_equal("DGF", obj.value)
+
+ end
+
+ def test_create_vt_array_int
+ obj = WIN32OLE_VARIANT.new([65, 0], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1)
+ assert_equal([65, 0].pack("C*"), obj.value)
+
+ obj = WIN32OLE_VARIANT.new([65, 0])
+ assert_equal([65, 0], obj.value)
+
+ obj = WIN32OLE_VARIANT.new([65, 0], WIN32OLE::VARIANT::VT_I2|WIN32OLE::VARIANT::VT_ARRAY)
+ assert_equal([65, 0], obj.value)
+
+ end
+
+ def test_vt_array_bracket
+ obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]])
+ assert_equal(1, obj[0,0])
+ assert_equal(2, obj[0,1])
+ assert_equal(3, obj[0,2])
+ assert_equal(4, obj[1,0])
+ assert_equal(5, obj[1,1])
+ assert_equal(6, obj[1,2])
+
+ assert_raise(WIN32OLERuntimeError) {
+ obj[0,4]
+ }
+ assert_raise(WIN32OLERuntimeError) {
+ obj[0,-1]
+ }
+ assert_raise(ArgumentError) {
+ obj[0]
+ }
+
+ obj[0,0] = 7
+ obj[1,2] = 8
+ assert_equal([[7,2,3], [4,5,8]], obj.value)
+
+ assert_raise(WIN32OLERuntimeError) {
+ obj[0,4] = 9
+ }
+ assert_raise(WIN32OLERuntimeError) {
+ obj[0,-1] = 10
+ }
+ assert_raise(ArgumentError) {
+ obj[0] = 11
+ }
+ end
+
+ def test_conversion_vt_date
+ obj = WIN32OLE_VARIANT.new(-657434, WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(100,1,1), obj.value)
+
+ obj = WIN32OLE_VARIANT.new("1500/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(1500,12,29,23,59,59), obj.value)
+
+ obj = WIN32OLE_VARIANT.new("1500/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(1500,12,30), obj.value)
+
+ obj = WIN32OLE_VARIANT.new("1500/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(1500,12,30,0,0,1), obj.value)
+
+ obj = WIN32OLE_VARIANT.new("1899/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(1899,12,29,23,59,59), obj.value)
+
+ obj = WIN32OLE_VARIANT.new("1899/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(1899,12,30), obj.value)
+
+ obj = WIN32OLE_VARIANT.new("1899/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(1899,12,30,0,0,1), obj.value)
+
+ obj = WIN32OLE_VARIANT.new(0, WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(1899,12,30), obj.value)
+
+ obj = WIN32OLE_VARIANT.new("2008/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(2008,12,29,23,59,59), obj.value)
+
+ obj = WIN32OLE_VARIANT.new("2008/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(2008,12,30,0,0,0), obj.value)
+
+ obj = WIN32OLE_VARIANT.new("2008/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(2008,12,30,0,0,1), obj.value)
+
+ obj = WIN32OLE_VARIANT.new("9999/12/31 23:59:59", WIN32OLE::VARIANT::VT_DATE)
+ assert_equal(Time.new(9999,12,31,23,59,59), obj.value)
+ end
+
+ def test_create_nil_dispatch
+ var = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_DISPATCH)
+ assert_nil(var.value)
+ end
+
+ def test_create_variant_byref
+ obj = WIN32OLE_VARIANT.new("Str", WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF);
+ assert_equal("Str", obj.value);
+ end
+
+ def test_vartype
+ obj = WIN32OLE_VARIANT.new("Str")
+ assert_equal(WIN32OLE::VARIANT::VT_BSTR, obj.vartype)
+ end
+
+ def test_set_value
+ obj = WIN32OLE_VARIANT.new(10)
+ obj.value = 12
+ assert_equal(12, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
+ obj.value = "14"
+ assert_equal(14, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
+ obj.value = 11.2
+ assert_equal(11, obj.value)
+ assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
+
+ obj = WIN32OLE_VARIANT.new([1,2])
+ assert_raise(WIN32OLERuntimeError) {
+ obj.value = [3,4]
+ }
+
+ obj = WIN32OLE_VARIANT.new("2007/01/01", WIN32OLE::VARIANT::VT_DATE)
+ assert_raise(WIN32OLERuntimeError) {
+ obj.value = "hogehoge"
+ }
+ assert_equal(Time.new(2007,1,1), obj.value)
+
+ obj2 = WIN32OLE_VARIANT.new("2006/01/01", WIN32OLE::VARIANT::VT_DATE)
+ obj.value = obj2
+ assert_equal(Time.new(2006,01,01), obj.value)
+ end
+
+ def test_c_nothing
+ assert_nil(WIN32OLE_VARIANT::Nothing.value)
+ end
+
+ def test_c_empty
+ assert_nil(WIN32OLE_VARIANT::Empty.value)
+ end
+
+ def test_c_null
+ assert_nil(WIN32OLE_VARIANT::Null.value)
+ end
+
+ end
+end
+
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variant_m.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variant_m.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variant_m.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,35 @@
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require "test/unit"
+
+if defined?(WIN32OLE::VARIANT)
+ class TestWin32OLE_VARIANT_MODULE < Test::Unit::TestCase
+ include WIN32OLE::VARIANT
+ def test_variant
+ assert_equal(0, VT_EMPTY)
+ assert_equal(1, VT_NULL)
+ assert_equal(2, VT_I2)
+ assert_equal(3, VT_I4)
+ assert_equal(4, VT_R4)
+ assert_equal(5, VT_R8)
+ assert_equal(6, VT_CY)
+ assert_equal(7, VT_DATE)
+ assert_equal(8, VT_BSTR)
+ assert_equal(9, VT_DISPATCH)
+ assert_equal(10, VT_ERROR)
+ assert_equal(11, VT_BOOL)
+ assert_equal(12, VT_VARIANT)
+ assert_equal(13, VT_UNKNOWN)
+ assert_equal(16, VT_I1)
+ assert_equal(17, VT_UI1)
+ assert_equal(18, VT_UI2)
+ assert_equal(19, VT_UI4)
+ assert_equal(22, VT_INT)
+ assert_equal(23, VT_UINT)
+ assert_equal(0x2000, VT_ARRAY)
+ assert_equal(0x4000, VT_BYREF)
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variant_outarg.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variant_outarg.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_win32ole_variant_outarg.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,69 @@
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require 'test/unit'
+require 'fileutils'
+
+def ado_csv_installed?
+ installed = false
+ if defined?(WIN32OLE)
+ db = nil
+ begin
+ db = WIN32OLE.new('ADODB.Connection')
+ db.connectionString = "Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=.;"
+ db.open
+ db.close
+ db = nil
+ installed = true
+ rescue
+ end
+ end
+ installed
+end
+
+if defined?(WIN32OLE_VARIANT)
+ dotest = ado_csv_installed?
+ if !dotest
+ STDERR.puts("\n#{__FILE__} skipped(ActiveX Data Object Library not found.)")
+ end
+ if dotest
+ class TestWIN32OLE_VARIANT_OUTARG < Test::Unit::TestCase
+ module ADO
+ end
+ CONNSTR="Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=.;"
+ def setup
+ FileUtils.cp(File.dirname(__FILE__) + '/orig_data.csv', './data.csv')
+ @db = WIN32OLE.new('ADODB.Connection')
+ if !defined?(ADO::AdStateOpen)
+ WIN32OLE.const_load(@db, ADO)
+ end
+ @db.connectionString = CONNSTR
+ @db.open
+ end
+
+ def test_variant_ref_and_argv
+ sql = "INSERT INTO data.csv VALUES (5, 'E')"
+ @db.execute(sql, -1)
+ c = WIN32OLE::ARGV[1]
+ assert_equal(1, WIN32OLE::ARGV[1])
+ obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(nil, obj.value)
+ @db.execute(sql , obj)
+ assert_equal(1, obj.value)
+ obj = WIN32OLE_VARIANT.new(-100, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF)
+ assert_equal(-100, obj.value)
+ @db.execute(sql, obj)
+ assert_equal(1, obj.value)
+ end
+
+ def teardown
+ if @db && @db.state == ADO::AdStateOpen
+ @db.close
+ end
+ File.unlink("data.csv")
+ end
+
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/win32ole/test_word.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/win32ole/test_word.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/win32ole/test_word.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,72 @@
+#
+# This is test for [ruby-Bugs#3237]
+#
+begin
+ require 'win32ole'
+rescue LoadError
+end
+require "test/unit"
+
+def word_installed?
+ installed = false
+ w = nil
+ if defined?(WIN32OLE)
+ begin
+ w = WIN32OLE.new('Word.Application')
+ installed = true
+ rescue
+ ensure
+ if w
+ w.quit
+ w = nil
+ end
+ end
+ end
+ return installed
+end
+
+if defined?(WIN32OLE)
+ w = nil
+ dotest = word_installed?
+ if !dotest
+ STDERR.puts("\n#{__FILE__} skipped(Microsoft Word not found.)")
+ end
+ if dotest
+ class TestWIN32OLE_WITH_WORD < Test::Unit::TestCase
+ def setup
+ begin
+ @obj = WIN32OLE.new('Word.Application')
+ rescue WIN32OLERuntimeError
+ @obj = nil
+ if !$skipped
+ $skipped = true
+ end
+ end
+ end
+
+ def test_ole_methods
+ if @obj
+ @obj.visible = true
+ @obj.wordbasic.disableAutoMacros(true)
+ assert(true)
+ else
+ end
+ end
+
+ def test_s_connect
+ if @obj
+ obj2 = WIN32OLE.connect("Word.Application")
+ assert_instance_of(WIN32OLE, obj2)
+ obj2.visible = true
+ end
+ end
+
+ def teardown
+ if @obj
+ @obj.quit
+ @obj = nil
+ end
+ end
+ end
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_bool.expected
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_bool.expected (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_bool.expected 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,3 @@
+---
+- true
+- false
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_bool.xml
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_bool.xml (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_bool.xml 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<methodResponse>
+ <params>
+ <param>
+ <value><boolean>0</boolean></value>
+ </param>
+ </params>
+</methodResponse>
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_cdata.expected
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_cdata.expected (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_cdata.expected 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,3 @@
+---
+- true
+- test
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_cdata.xml
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_cdata.xml (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_cdata.xml 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<methodResponse>
+ <params>
+ <param>
+ <value><string><![CDATA[test]]></string></value>
+ </param>
+ </params>
+</methodResponse>
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_covert.expected
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_covert.expected (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_covert.expected 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,10 @@
+---
+- true
+- >
+ Site,SANs,Array
+
+ Configured Capacity,Array Reserved Capacity,Array Ava
+
+ ilable Capacity,Array % Reserved,Host Allocated,Host Used,Host Free,Host %
+
+ Used
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_covert.xml
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_covert.xml (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/data/bug_covert.xml 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,6 @@
+<?xml version="1.0"
+encoding="ISO-8859-1"?><methodResponse><params><param><value>Site,SANs,Array
+Configured Capacity,Array Reserved Capacity,Array Ava
+ilable Capacity,Array % Reserved,Host Allocated,Host Used,Host Free,Host %
+Used
+</value></param></params></methodResponse>
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/data/datetime_iso8601.xml
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/data/datetime_iso8601.xml (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/data/datetime_iso8601.xml 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<methodResponse>
+ <params>
+ <param>
+ <value><dateTime.iso8601>20041105T01:15:23Z</dateTime.iso8601></value>
+ </param>
+ </params>
+</methodResponse>
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/data/fault.xml
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/data/fault.xml (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/data/fault.xml 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<methodResponse>
+ <fault>
+ <value><struct>
+ <member>
+ <name>faultCode</name>
+ <value><int>4</int></value>
+ </member>
+ <member>
+ <name>faultString</name>
+ <value>an error message</value>
+ </member>
+ </struct></value>
+ </fault>
+</methodResponse>
+
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/data/value.expected
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/data/value.expected (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/data/value.expected 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,7 @@
+---
+- Test
+-
+ - Hallo Leute
+ - " Hallo "
+ - ''
+ - " "
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/data/value.xml
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/data/value.xml (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/data/value.xml 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<methodCall>
+ <methodName>Test</methodName>
+ <params>
+ <param>
+ <value>Hallo Leute</value>
+ </param>
+ <param>
+ <value> Hallo </value>
+ </param>
+ <param>
+ <value></value>
+ </param>
+ <param>
+ <value> </value>
+ </param>
+ </params>
+</methodCall>
+
+
+
+
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/data/xml1.expected
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/data/xml1.expected (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/data/xml1.expected 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,243 @@
+---
+- true
+-
+ -
+ subscriber: MegaCorp
+ lastName: Baker
+ telephone1: 1-508-791-1267
+ telephone2: 1-800-445-2588
+ password: p1111
+ OID: "1"
+ email: hbaker at yahoo.com
+ adminId: hbaker
+ objectName: AdministratorDO
+ -
+ subscriber: CornerStore
+ lastName: Dragon
+ telephone1: 1-781-789-9089
+ telephone2: 1-800-445-2588
+ password: p3333
+ OID: "3"
+ email: adragon at yahoo.com
+ adminId: adragon
+ objectName: AdministratorDO
+ -
+ subscriber: Cyberdyne
+ lastName: Rodman
+ telephone1: 1-617-789-1890
+ telephone2: 1-800-445-2588
+ password: p4444
+ OID: "4"
+ email: mrodman at yahoo.com
+ adminId: mrodman
+ objectName: AdministratorDO
+ -
+ subscriber: StarSports
+ lastName: Jordan
+ telephone1: 1-617-890-7897
+ telephone2: 1-800-445-2588
+ password: p5555
+ OID: "5"
+ email: mjordan at yahoo.com
+ adminId: mjordan
+ objectName: AdministratorDO
+ -
+ subscriber: GreatBooks
+ lastName: Pippen
+ telephone1: 1-781-789-9876
+ telephone2: 1-800-445-2588
+ password: p6666
+ OID: "6"
+ email: gpippen at yahoo.com
+ adminId: gpippen
+ objectName: AdministratorDO
+ -
+ subscriber: AxisChemicals
+ lastName: Andhrew
+ telephone1: 1-781-678-8970
+ telephone2: 1-800-445-2588
+ password: p7777
+ OID: "7"
+ email: aandrew at yahoo.com
+ adminId: aandrew
+ objectName: AdministratorDO
+ -
+ subscriber: MediaShop
+ lastName: Vincent
+ telephone1: 1-786-897-8908
+ telephone2: 1-800-445-2588
+ password: p8888
+ OID: "8"
+ email: tvincent at yahoo.com
+ adminId: tvincent
+ objectName: AdministratorDO
+ -
+ subscriber: SmartShop
+ lastName: Richard
+ telephone1: 1-508-789-6789
+ telephone2: 1-800-445-2588
+ password: p9999
+ OID: "9"
+ email: krichard at yahoo.com
+ adminId: krichard
+ objectName: AdministratorDO
+ -
+ subscriber: HomeNeeds
+ lastName: Cornell
+ telephone1: 1-617-789-8979
+ telephone2: 1-800-445-2588
+ password: paaaa
+ OID: "10"
+ email: gconell at yahoo.com
+ adminId: gcornell
+ objectName: AdministratorDO
+ -
+ subscriber: MegaCorp
+ lastName: HorstMann
+ telephone1: 1-508-791-1267
+ telephone2: 1-800-445-2588
+ password: p1111
+ OID: "11"
+ email: shorstmann at yahoo.com
+ adminId: shorstmann
+ objectName: AdministratorDO
+ -
+ subscriber: CornerStore
+ lastName: Bob
+ telephone1: 1-781-789-9089
+ telephone2: 1-800-445-2588
+ password: p3333
+ OID: "13"
+ email: rbob at yahoo.com
+ adminId: rbob
+ objectName: AdministratorDO
+ -
+ subscriber: Cyberdyne
+ lastName: Peter
+ telephone1: 1-617-789-1890
+ telephone2: 1-800-445-2588
+ password: p4444
+ OID: "14"
+ email: speter at yahoo.com
+ adminId: speter
+ objectName: AdministratorDO
+ -
+ subscriber: StarSports
+ lastName: Novak
+ telephone1: 1-617-890-7897
+ telephone2: 1-800-445-2588
+ password: p5555
+ OID: "15"
+ email: pnovak at yahoo.com
+ adminId: pnovak
+ objectName: AdministratorDO
+ -
+ subscriber: GreatBooks
+ lastName: Nancy
+ telephone1: 1-781-789-9876
+ telephone2: 1-800-445-2588
+ password: p6666
+ OID: "16"
+ email: pnancy at yahoo.com
+ adminId: pnancy
+ objectName: AdministratorDO
+ -
+ subscriber: AxisChemicals
+ lastName: Michel
+ telephone1: 1-781-678-8970
+ telephone2: 1-800-445-2588
+ password: p7777
+ OID: "17"
+ email: hmichel at yahoo.com
+ adminId: hmichel
+ objectName: AdministratorDO
+ -
+ subscriber: MediaShop
+ lastName: David
+ telephone1: 1-786-897-8908
+ telephone2: 1-800-445-2588
+ password: p8888
+ OID: "18"
+ email: kdavid at yahoo.com
+ adminId: kdavid
+ objectName: AdministratorDO
+ -
+ subscriber: SmartShop
+ lastName: Valnoor
+ telephone1: 1-508-789-6789
+ telephone2: 1-800-445-2588
+ password: p9999
+ OID: "19"
+ email: pvalnoor at yahoo.com
+ adminId: pvalnoor
+ objectName: AdministratorDO
+ -
+ subscriber: HomeNeeds
+ lastName: Smith
+ telephone1: 1-617-789-8979
+ telephone2: 1-800-445-2588
+ password: paaaa
+ OID: "20"
+ email: wsmith at yahoo.com
+ adminId: wsmith
+ objectName: AdministratorDO
+ -
+ subscriber: MegaCorp
+ lastName: Caral
+ telephone1: 1-781-789-9876
+ telephone2: 1-800-445-2588
+ password: p6666
+ OID: "21"
+ email: gcaral at yahoo.com
+ adminId: gcaral
+ objectName: AdministratorDO
+ -
+ subscriber: CornerStore
+ lastName: Hillary
+ telephone1: 1-786-897-8908
+ telephone2: 1-800-445-2588
+ password: p8888
+ OID: "23"
+ email: phillary at yahoo.com
+ adminId: phillary
+ objectName: AdministratorDO
+ -
+ subscriber: Cyberdyne
+ lastName: Philip
+ telephone1: 1-508-789-6789
+ telephone2: 1-800-445-2588
+ password: p9999
+ OID: "24"
+ email: bphilip at yahoo.com
+ adminId: bphilip
+ objectName: AdministratorDO
+ -
+ subscriber: StarSports
+ lastName: Andrea
+ telephone1: 1-617-789-8979
+ telephone2: 1-800-445-2588
+ password: paaaa
+ OID: "25"
+ email: sandrea at yahoo.com
+ adminId: sandrea
+ objectName: AdministratorDO
+ -
+ subscriber: s4
+ lastName: "null"
+ telephone1: "null"
+ telephone2: "null"
+ password: s4
+ OID: "26"
+ email: "null"
+ adminId: s4
+ objectName: AdministratorDO
+ -
+ subscriber: BigBank
+ lastName: administrator
+ telephone1: ''
+ telephone2: ''
+ password: admin
+ OID: "82"
+ email: ''
+ adminId: admin
+ objectName: AdministratorDO
\ No newline at end of file
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/data/xml1.xml
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/data/xml1.xml (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/data/xml1.xml 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="ISO-8859-1"?><methodResponse><params><param><value><array><data><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>hbaker</value></member><member><name>email</name><value>hbaker at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-508-791-1267</value></member><member><name>OID</name><value>1</value></member><member><name>password</name><value>p1111</value></member><member><name>lastName</name><value>Baker</value></member><member><name>subscriber</name><value>MegaCorp</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>adragon</value></member><member><name>email</name><value>adragon at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-789-9089</value></member><member><name>OID</name><value>3</value></member><member><name>password</name><value>p3333</value></member><member><name>lastName</name><value>Dragon</value></member><member><name>subscriber</name><value>CornerStore</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>mrodman</value></member><member><name>email</name><value>mrodman at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-789-1890</value></member><member><name>OID</name><value>4</value></member><member><name>password</name><value>p4444</value></member><member><name>lastName</name><value>Rodman</value></member><member><name>subscriber</name><value>Cyberdyne</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>mjordan</value></member><member><name>email</name><value>mjordan at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-890-7897</value></member><member><name>OID</name><value>5</value></member><member><name>password</name><value>p5555</value></member><member><name>lastName</name><value>Jordan</value></member><member><name>subscriber</name><value>StarSports</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>gpippen</value></member><member><name>email</name><value>gpippen at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-789-9876</value></member><member><name>OID</name><value>6</value></member><member><name>password</name><value>p6666</value></member><member><name>lastName</name><value>Pippen</value></member><member><name>subscriber</name><value>GreatBooks</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>aandrew</value></member><member><name>email</name><value>aandrew at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-678-8970</value></member><member><name>OID</name><value>7</value></member><member><name>password</name><value>p7777</value></member><member><name>lastName</name><value>Andhrew</value></member><member><name>subscriber</name><value>AxisChemicals</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>tvincent</value></member><member><name>email</name><value>tvincent at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-786-897-8908</value></member><member><name>OID</name><value>8</value></member><member><name>password</name><value>p8888</value></member><member><name>lastName</name><value>Vincent</value></member><member><name>subscriber</name><value>MediaShop</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>krichard</value></member><member><name>email</name><value>krichard at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-508-789-6789</value></member><member><name>OID</name><value>9</value></member><member><name>password</name><value>p9999</value></member><member><name>lastName</name><value>Richard</value></member><member><name>subscriber</name><value>SmartShop</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>gcornell</value></member><member><name>email</name><value>gconell at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-789-8979</value></member><member><name>OID</name><value>10</value></member><member><name>password</name><value>paaaa</value></member><member><name>lastName</name><value>Cornell</value></member><member><name>subscriber</name><value>HomeNeeds</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>shorstmann</value></member><member><name>email</name><value>shorstmann at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-508-791-1267</value></member><member><name>OID</name><value>11</value></member><member><name>password</name><value>p1111</value></member><member><name>lastName</name><value>HorstMann</value></member><member><name>subscriber</name><value>MegaCorp</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>rbob</value></member><member><name>email</name><value>rbob at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-789-9089</value></member><member><name>OID</name><value>13</value></member><member><name>password</name><value>p3333</value></member><member><name>lastName</name><value>Bob</value></member><member><name>subscriber</name><value>CornerStore</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>speter</value></member><member><name>email</name><value>speter at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-789-1890</value></member><member><name>OID</name><value>14</value></member><member><name>password</name><value>p4444</value></member><member><name>lastName</name><value>Peter</value></member><member><name>subscriber</name><value>Cyberdyne</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>pnovak</value></member><member><name>email</name><value>pnovak at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-890-7897</value></member><member><name>OID</name><value>15</value></member><member><name>password</name><value>p5555</value></member><member><name>lastName</name><value>Novak</value></member><member><name>subscriber</name><value>StarSports</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>pnancy</value></member><member><name>email</name><value>pnancy at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-789-9876</value></member><member><name>OID</name><value>16</value></member><member><name>password</name><value>p6666</value></member><member><name>lastName</name><value>Nancy</value></member><member><name>subscriber</name><value>GreatBooks</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>hmichel</value></member><member><name>email</name><value>hmichel at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-678-8970</value></member><member><name>OID</name><value>17</value></member><member><name>password</name><value>p7777</value></member><member><name>lastName</name><value>Michel</value></member><member><name>subscriber</name><value>AxisChemicals</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>kdavid</value></member><member><name>email</name><value>kdavid at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-786-897-8908</value></member><member><name>OID</name><value>18</value></member><member><name>password</name><value>p8888</value></member><member><name>lastName</name><value>David</value></member><member><name>subscriber</name><value>MediaShop</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>pvalnoor</value></member><member><name>email</name><value>pvalnoor at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-508-789-6789</value></member><member><name>OID</name><value>19</value></member><member><name>password</name><value>p9999</value></member><member><name>lastName</name><value>Valnoor</value></member><member><name>subscriber</name><value>SmartShop</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>wsmith</value></member><member><name>email</name><value>wsmith at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-789-8979</value></member><member><name>OID</name><value>20</value></member><member><name>password</name><value>paaaa</value></member><member><name>lastName</name><value>Smith</value></member><member><name>subscriber</name><value>HomeNeeds</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>gcaral</value></member><member><name>email</name><value>gcaral at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-789-9876</value></member><member><name>OID</name><value>21</value></member><member><name>password</name><value>p6666</value></member><member><name>lastName</name><value>Caral</value></member><member><name>subscriber</name><value>MegaCorp</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>phillary</value></member><member><name>email</name><value>phillary at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-786-897-8908</value></member><member><name>OID</name><value>23</value></member><member><name>password</name><value>p8888</value></member><member><name>lastName</name><value>Hillary</value></member><member><name>subscriber</name><value>CornerStore</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>bphilip</value></member><member><name>email</name><value>bphilip at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-508-789-6789</value></member><member><name>OID</name><value>24</value></member><member><name>password</name><value>p9999</value></member><member><name>lastName</name><value>Philip</value></member><member><name>subscriber</name><value>Cyberdyne</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>sandrea</value></member><member><name>email</name><value>sandrea at yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-789-8979</value></member><member><name>OID</name><value>25</value></member><member><name>password</name><value>paaaa</value></member><member><name>lastName</name><value>Andrea</value></member><member><name>subscriber</name><value>StarSports</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>s4</value></member><member><name>email</name><value>null</value></member><member><name>telephone2</name><value>null</value></member><member><name>telephone1</name><value>null</value></member><member><name>OID</name><value>26</value></member><member><name>password</name><value>s4</value></member><member><name>lastName</name><value>null</value></member><member><name>subscriber</name><value>s4</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>admin</value></member><member><name>email</name><value></value></member><member><name>telephone2</name><value></value></member><member><name>telephone1</name><value></value></member><member><name>OID</name><value>82</value></member><member><name>password</name><value>admin</value></member><member><name>lastName</name><value>administrator</value></member><member><name>subscriber</name><value>BigBank</value></member></struct></value></data></array></value></param></params></methodResponse>
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/test_cookie.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/test_cookie.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/test_cookie.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,96 @@
+require 'test/unit'
+require 'time'
+require 'webrick'
+require_relative 'webrick_testing'
+require "xmlrpc/server"
+require 'xmlrpc/client'
+
+class TestCookie < Test::Unit::TestCase
+ include WEBrick_Testing
+
+ def create_servlet
+ s = XMLRPC::WEBrickServlet.new
+
+ def s.logged_in_users
+ @logged_in_users ||= {}
+ end
+ def s.request
+ @request
+ end
+ def s.response
+ @response
+ end
+ def s.service(request, response)
+ @request = request
+ @response = response
+ super
+ ensure
+ @request = nil
+ @response = nil
+ end
+
+ key = Time.now.to_i.to_s
+ valid_user = "valid-user"
+ s.add_handler("test.login") do |user, password|
+ ok = (user == valid_user and password == "secret")
+ if ok
+ s.logged_in_users[key] = user
+ expires = (Time.now + 60 * 60).httpdate
+ cookies = s.response.cookies
+ cookies << "key=\"#{key}\"; path=\"/RPC2\"; expires=#{expires}"
+ cookies << "user=\"#{user}\"; path=\"/RPC2\""
+ end
+ ok
+ end
+
+ s.add_handler("test.require_authenticate_echo") do |string|
+ cookies = {}
+ s.request.cookies.each do |cookie|
+ cookies[cookie.name] = cookie.value
+ end
+ if cookies == {"key" => key, "user" => valid_user}
+ string
+ else
+ raise XMLRPC::FaultException.new(29, "Authentication required")
+ end
+ end
+
+ s.set_default_handler do |name, *args|
+ raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
+ " or wrong number of parameters!")
+ end
+
+ s.add_introspection
+
+ s
+ end
+
+ def setup_http_server(port)
+ option = {:Port => port}
+
+ start_server(option) {|w| w.mount('/RPC2', create_servlet) }
+
+ @s = XMLRPC::Client.new3(:port => port)
+ end
+
+ PORT = 8070
+ def test_cookie
+ begin
+ setup_http_server(PORT)
+ do_test
+ ensure
+ stop_server
+ end
+ end
+
+ def do_test
+ assert(!@s.call("test.login", "invalid-user", "invalid-password"))
+ exception = assert_raise(XMLRPC::FaultException) do
+ @s.call("test.require_authenticate_echo", "Hello")
+ end
+ assert_equal(29, exception.faultCode)
+
+ assert(@s.call("test.login", "valid-user", "secret"))
+ assert_equal("Hello", @s.call("test.require_authenticate_echo", "Hello"))
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/test_datetime.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/test_datetime.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/test_datetime.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,159 @@
+require 'test/unit'
+require "xmlrpc/datetime"
+
+class Test_DateTime < Test::Unit::TestCase
+
+ def test_new
+ dt = createDateTime()
+
+ assert_instance_of(XMLRPC::DateTime, dt)
+ end
+
+ def test_new_exception
+ assert_raise(ArgumentError) { XMLRPC::DateTime.new(4.5, 13, 32, 25, 60, 60) }
+ assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 32, 25, 60, 60) }
+ assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 31, 25, 60, 60) }
+ assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 31, 24, 60, 60) }
+ assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 31, 24, 59, 60) }
+ assert_nothing_raised(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 31, 24, 59, 59) }
+
+ assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 0, 0, -1, -1, -1) }
+ assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 0, -1, -1, -1) }
+ assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 1, -1, -1, -1) }
+ assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 1, 0, -1, -1) }
+ assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 1, 0, 0, -1) }
+ assert_nothing_raised(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 1, 0, 0, 0) }
+ end
+
+
+ def test_get_values
+ y, m, d, h, mi, s = 1970, 3, 24, 12, 0, 5
+ dt = XMLRPC::DateTime.new(y, m, d, h, mi, s)
+
+ assert_equal(y, dt.year)
+ assert_equal(m, dt.month)
+ assert_equal(m, dt.mon)
+ assert_equal(d, dt.day)
+
+ assert_equal(h, dt.hour)
+ assert_equal(mi,dt.min)
+ assert_equal(s, dt.sec)
+ end
+
+ def test_set_values
+ dt = createDateTime()
+ y, m, d, h, mi, s = 1950, 12, 9, 8, 52, 30
+
+ dt.year = y
+ dt.month = m
+ dt.day = d
+ dt.hour = h
+ dt.min = mi
+ dt.sec = s
+
+ assert_equal(y, dt.year)
+ assert_equal(m, dt.month)
+ assert_equal(m, dt.mon)
+ assert_equal(d, dt.day)
+
+ assert_equal(h, dt.hour)
+ assert_equal(mi,dt.min)
+ assert_equal(s, dt.sec)
+
+ dt.mon = 5
+ assert_equal(5, dt.month)
+ assert_equal(5, dt.mon)
+ end
+
+ def test_set_exception
+ dt = createDateTime()
+
+ assert_raise(ArgumentError) { dt.year = 4.5 }
+ assert_nothing_raised(ArgumentError) { dt.year = -2000 }
+
+ assert_raise(ArgumentError) { dt.month = 0 }
+ assert_raise(ArgumentError) { dt.month = 13 }
+ assert_nothing_raised(ArgumentError) { dt.month = 7 }
+
+ assert_raise(ArgumentError) { dt.mon = 0 }
+ assert_raise(ArgumentError) { dt.mon = 13 }
+ assert_nothing_raised(ArgumentError) { dt.mon = 7 }
+
+ assert_raise(ArgumentError) { dt.day = 0 }
+ assert_raise(ArgumentError) { dt.day = 32 }
+ assert_nothing_raised(ArgumentError) { dt.day = 16 }
+
+ assert_raise(ArgumentError) { dt.hour = -1 }
+ assert_raise(ArgumentError) { dt.hour = 25 }
+ assert_nothing_raised(ArgumentError) { dt.hour = 12 }
+
+ assert_raise(ArgumentError) { dt.min = -1 }
+ assert_raise(ArgumentError) { dt.min = 60 }
+ assert_nothing_raised(ArgumentError) { dt.min = 30 }
+
+ assert_raise(ArgumentError) { dt.sec = -1 }
+ assert_raise(ArgumentError) { dt.sec = 60 }
+ assert_nothing_raised(ArgumentError) { dt.sec = 30 }
+ end
+
+ def test_to_a
+ y, m, d, h, mi, s = 1970, 3, 24, 12, 0, 5
+ dt = XMLRPC::DateTime.new(y, m, d, h, mi, s)
+ a = dt.to_a
+
+ assert_instance_of(Array, a)
+ assert_equal(6, a.size, "Returned array has wrong size")
+
+ assert_equal(y, a[0])
+ assert_equal(m, a[1])
+ assert_equal(d, a[2])
+ assert_equal(h, a[3])
+ assert_equal(mi, a[4])
+ assert_equal(s, a[5])
+ end
+
+ def test_to_time1
+ y, m, d, h, mi, s = 1970, 3, 24, 12, 0, 5
+ dt = XMLRPC::DateTime.new(y, m, d, h, mi, s)
+ time = dt.to_time
+
+ assert_not_nil(time)
+
+ assert_equal(y, time.year)
+ assert_equal(m, time.month)
+ assert_equal(d, time.day)
+ assert_equal(h, time.hour)
+ assert_equal(mi, time.min)
+ assert_equal(s, time.sec)
+ end
+
+ def test_to_time2
+ dt = createDateTime()
+ dt.year = 1969
+
+ assert_nil(dt.to_time)
+ end
+
+ def test_to_date1
+ y, m, d, h, mi, s = 1970, 3, 24, 12, 0, 5
+ dt = XMLRPC::DateTime.new(y, m, d, h, mi, s)
+ date = dt.to_date
+
+ assert_equal(y, date.year)
+ assert_equal(m, date.month)
+ assert_equal(d, date.day)
+ end
+
+ def test_to_date2
+ dt = createDateTime()
+ dt.year = 666
+
+ assert_equal(666, dt.to_date.year)
+ end
+
+
+ def createDateTime
+ XMLRPC::DateTime.new(1970, 3, 24, 12, 0, 5)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/test_features.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/test_features.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/test_features.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,48 @@
+require 'test/unit'
+require "xmlrpc/create"
+require "xmlrpc/parser"
+require "xmlrpc/config"
+
+class Test_Features < Test::Unit::TestCase
+
+ def setup
+ @params = [nil, {"test" => nil}, [nil, 1, nil]]
+ end
+
+ def test_nil_create
+ XMLRPC::XMLWriter.each_installed_writer do |writer|
+ c = XMLRPC::Create.new(writer)
+
+ XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_CREATE)}
+ XMLRPC::Config.const_set(:ENABLE_NIL_CREATE, false)
+ assert_raise(RuntimeError) { str = c.methodCall("test", *@params) }
+
+ XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_CREATE)}
+ XMLRPC::Config.const_set(:ENABLE_NIL_CREATE, true)
+ assert_nothing_raised { str = c.methodCall("test", *@params) }
+ end
+ end
+
+ def test_nil_parse
+ XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_CREATE)}
+ XMLRPC::Config.const_set(:ENABLE_NIL_CREATE, true)
+
+ XMLRPC::XMLWriter.each_installed_writer do |writer|
+ c = XMLRPC::Create.new(writer)
+ str = c.methodCall("test", *@params)
+ XMLRPC::XMLParser.each_installed_parser do |parser|
+ para = nil
+
+ XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_PARSER)}
+ XMLRPC::Config.const_set(:ENABLE_NIL_PARSER, false)
+ assert_raise(RuntimeError) { para = parser.parseMethodCall(str) }
+
+ XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_PARSER)}
+ XMLRPC::Config.const_set(:ENABLE_NIL_PARSER, true)
+ assert_nothing_raised { para = parser.parseMethodCall(str) }
+ assert_equal(para[1], @params)
+ end
+ end
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/test_marshal.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/test_marshal.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/test_marshal.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,93 @@
+require 'test/unit'
+require "xmlrpc/marshal"
+
+class Test_Marshal < Test::Unit::TestCase
+ # for test_parser_values
+ class Person
+ include XMLRPC::Marshallable
+ attr_reader :name
+ def initialize(name)
+ @name = name
+ end
+ end
+
+
+ def test1_dump_response
+ assert_nothing_raised(NameError) {
+ XMLRPC::Marshal.dump_response('arg')
+ }
+ end
+
+ def test1_dump_call
+ assert_nothing_raised(NameError) {
+ XMLRPC::Marshal.dump_call('methodName', 'arg')
+ }
+ end
+
+ def test2_dump_load_response
+ value = [1, 2, 3, {"test" => true}, 3.4]
+ res = XMLRPC::Marshal.dump_response(value)
+
+ assert_equal(value, XMLRPC::Marshal.load_response(res))
+ end
+
+ def test2_dump_load_call
+ methodName = "testMethod"
+ value = [1, 2, 3, {"test" => true}, 3.4]
+ exp = [methodName, [value, value]]
+
+ res = XMLRPC::Marshal.dump_call(methodName, value, value)
+
+ assert_equal(exp, XMLRPC::Marshal.load_call(res))
+ end
+
+ def test_parser_values
+ v1 = [
+ 1, -7778, # integers
+ 1.0, 0.0, -333.0, 2343434343.0, # floats
+ false, true, true, false, # booleans
+ "Hallo", "with < and >", "" # strings
+ ]
+
+ v2 = [
+ [v1, v1, v1],
+ {"a" => v1}
+ ]
+
+ v3 = [
+ XMLRPC::Base64.new("\001"*1000), # base64
+ :aSymbol, :anotherSym # symbols (-> string)
+ ]
+ v3_exp = [
+ "\001"*1000,
+ "aSymbol", "anotherSym"
+ ]
+ person = Person.new("Michael")
+
+ XMLRPC::XMLParser.each_installed_parser do |parser|
+ m = XMLRPC::Marshal.new(parser)
+
+ assert_equal( v1, m.load_response(m.dump_response(v1)) )
+ assert_equal( v2, m.load_response(m.dump_response(v2)) )
+ assert_equal( v3_exp, m.load_response(m.dump_response(v3)) )
+
+ pers = m.load_response(m.dump_response(person))
+
+ assert( pers.is_a?(Person) )
+ assert( person.name == pers.name )
+ end
+
+ # missing, Date, Time, DateTime
+ # Struct
+ end
+
+ def test_no_params_tag
+ # bug found by Idan Sofer
+
+ expect = %{<?xml version="1.0" ?><methodCall><methodName>myMethod</methodName><params/></methodCall>\n}
+
+ str = XMLRPC::Marshal.dump_call("myMethod")
+ assert_equal(expect, str)
+ end
+
+end
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/test_parser.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/test_parser.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/test_parser.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,85 @@
+require 'test/unit'
+require 'xmlrpc/datetime'
+require "xmlrpc/parser"
+require 'yaml'
+
+module GenericParserTest
+ def datafile(base)
+ File.join(File.dirname(__FILE__), "data", base)
+ end
+
+ def load_data(name)
+ [File.read(datafile(name) + ".xml"), YAML.load(File.read(datafile(name) + ".expected"))]
+ end
+
+ def setup
+ @xml1, @expected1 = load_data('xml1')
+ @xml2, @expected2 = load_data('bug_covert')
+ @xml3, @expected3 = load_data('bug_bool')
+ @xml4, @expected4 = load_data('value')
+
+ @cdata_xml, @cdata_expected = load_data('bug_cdata')
+
+ @datetime_xml = File.read(datafile('datetime_iso8601.xml'))
+ @datetime_expected = XMLRPC::DateTime.new(2004, 11, 5, 1, 15, 23)
+
+ @fault_doc = File.read(datafile('fault.xml'))
+ end
+
+ # test parseMethodResponse --------------------------------------------------
+
+ def test_parseMethodResponse1
+ assert_equal(@expected1, @p.parseMethodResponse(@xml1))
+ end
+
+ def test_parseMethodResponse2
+ assert_equal(@expected2, @p.parseMethodResponse(@xml2))
+ end
+
+ def test_parseMethodResponse3
+ assert_equal(@expected3, @p.parseMethodResponse(@xml3))
+ end
+
+ def test_cdata
+ assert_equal(@cdata_expected, @p.parseMethodResponse(@cdata_xml))
+ end
+
+ def test_dateTime
+ assert_equal(@datetime_expected, @p.parseMethodResponse(@datetime_xml)[1])
+ end
+
+ # test parseMethodCall ------------------------------------------------------
+
+ def test_parseMethodCall
+ assert_equal(@expected4, @p.parseMethodCall(@xml4))
+ end
+
+ # test fault ----------------------------------------------------------------
+
+ def test_fault
+ flag, fault = @p.parseMethodResponse(@fault_doc)
+ assert_equal(flag, false)
+ unless fault.is_a? XMLRPC::FaultException
+ assert(false, "must be an instance of class XMLRPC::FaultException")
+ end
+ assert_equal(fault.faultCode, 4)
+ assert_equal(fault.faultString, "an error message")
+ end
+end
+
+# create test class for each installed parser
+XMLRPC::XMLParser.each_installed_parser do |parser|
+ klass = parser.class
+ name = klass.to_s.split("::").last
+
+ eval %{
+ class Test_#{name} < Test::Unit::TestCase
+ include GenericParserTest
+
+ def setup
+ super
+ @p = #{klass}.new
+ end
+ end
+ }
+end
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/test_webrick_server.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/test_webrick_server.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/test_webrick_server.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,98 @@
+require 'test/unit'
+require 'webrick'
+require_relative 'webrick_testing'
+require "xmlrpc/server"
+require 'xmlrpc/client'
+
+class Test_Webrick < Test::Unit::TestCase
+ include WEBrick_Testing
+
+ def create_servlet
+ s = XMLRPC::WEBrickServlet.new
+
+ s.add_handler("test.add") do |a,b|
+ a + b
+ end
+
+ s.add_handler("test.div") do |a,b|
+ if b == 0
+ raise XMLRPC::FaultException.new(1, "division by zero")
+ else
+ a / b
+ end
+ end
+
+ s.set_default_handler do |name, *args|
+ raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
+ " or wrong number of parameters!")
+ end
+
+ s.add_introspection
+
+ return s
+ end
+
+ def setup_http_server(port, use_ssl)
+ option = {
+ :Port => port,
+ :SSLEnable => use_ssl,
+ }
+ if use_ssl
+ require 'webrick/https'
+ option.update(
+ :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
+ :SSLCertName => []
+ )
+ end
+
+ start_server(option) {|w| w.mount('/RPC2', create_servlet) }
+
+ @s = XMLRPC::Client.new3(:port => port, :use_ssl => use_ssl)
+ end
+
+ PORT = 8070
+ def test_client_server
+ # NOTE: I don't enable SSL testing as this hangs
+ [false].each do |use_ssl|
+ begin
+ setup_http_server(PORT, use_ssl)
+ do_test
+ ensure
+ stop_server
+ end
+ end
+ end
+
+ def do_test
+ # simple call
+ assert_equal 9, @s.call('test.add', 4, 5)
+
+ # fault exception
+ assert_raise(XMLRPC::FaultException) { @s.call('test.div', 1, 0) }
+
+ # fault exception via call2
+ ok, param = @s.call2('test.div', 1, 0)
+ assert_equal false, ok
+ assert_instance_of XMLRPC::FaultException, param
+ assert_equal 1, param.faultCode
+ assert_equal 'division by zero', param.faultString
+
+ # call2 without fault exception
+ ok, param = @s.call2('test.div', 10, 5)
+ assert_equal true, ok
+ assert_equal param, 2
+
+ # introspection
+ assert_equal ["test.add", "test.div", "system.listMethods", "system.methodSignature", "system.methodHelp"], @s.call("system.listMethods")
+
+ # default handler (missing handler)
+ ok, param = @s.call2('test.nonexisting')
+ assert_equal false, ok
+ assert_equal(-99, param.faultCode)
+
+ # default handler (wrong number of arguments)
+ ok, param = @s.call2('test.add', 1, 2, 3)
+ assert_equal false, ok
+ assert_equal(-99, param.faultCode)
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/xmlrpc/webrick_testing.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/xmlrpc/webrick_testing.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/xmlrpc/webrick_testing.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,38 @@
+require 'timeout'
+
+module WEBrick_Testing
+ class DummyLog < WEBrick::BasicLog
+ def initialize() super(self) end
+ def <<(*args) end
+ end
+
+ def start_server(config={})
+ raise "already started" if defined?(@__server) && @__server
+ @__started = false
+
+ @__server_thread = Thread.new {
+ @__server = WEBrick::HTTPServer.new(
+ {
+ :Logger => DummyLog.new,
+ :AccessLog => [],
+ :StartCallback => proc { @__started = true }
+ }.update(config))
+ yield @__server
+ @__server.start
+ @__started = false
+ }
+
+ Timeout.timeout(5) {
+ Thread.pass until @__started # wait until the server is ready
+ }
+ end
+
+ def stop_server
+ Timeout.timeout(5) {
+ @__server.shutdown
+ Thread.pass while @__started # wait until the server is down
+ }
+ @__server_thread.join
+ @__server = nil
+ end
+end
Added: MacRuby/trunk/test/test-mri/test/zlib/test_zlib.rb
===================================================================
--- MacRuby/trunk/test/test-mri/test/zlib/test_zlib.rb (rev 0)
+++ MacRuby/trunk/test/test-mri/test/zlib/test_zlib.rb 2010-10-14 13:40:31 UTC (rev 4794)
@@ -0,0 +1,698 @@
+require 'test/unit'
+require 'stringio'
+require 'tempfile'
+
+begin
+ require 'zlib'
+rescue LoadError
+end
+
+if defined? Zlib
+ class TestZlibDeflate < Test::Unit::TestCase
+ def test_initialize
+ z = Zlib::Deflate.new
+ s = z.deflate("foo", Zlib::FINISH)
+ assert_equal("foo", Zlib::Inflate.inflate(s))
+
+ z = Zlib::Deflate.new
+ s = z.deflate("foo")
+ s << z.deflate(nil, Zlib::FINISH)
+ assert_equal("foo", Zlib::Inflate.inflate(s))
+
+ assert_raise(Zlib::StreamError) { Zlib::Deflate.new(10000) }
+ end
+
+ def test_dup
+ z1 = Zlib::Deflate.new
+ s = z1.deflate("foo")
+ z2 = z1.dup
+ s1 = s + z1.deflate("bar", Zlib::FINISH)
+ s2 = s + z2.deflate("baz", Zlib::FINISH)
+ assert_equal("foobar", Zlib::Inflate.inflate(s1))
+ assert_equal("foobaz", Zlib::Inflate.inflate(s2))
+ end
+
+ def test_deflate
+ s = Zlib::Deflate.deflate("foo")
+ assert_equal("foo", Zlib::Inflate.inflate(s))
+
+ assert_raise(Zlib::StreamError) { Zlib::Deflate.deflate("foo", 10000) }
+ end
+
+ def test_addstr
+ z = Zlib::Deflate.new
+ z << "foo"
+ s = z.deflate(nil, Zlib::FINISH)
+ assert_equal("foo", Zlib::Inflate.inflate(s))
+ end
+
+ def test_flush
+ z = Zlib::Deflate.new
+ z << "foo"
+ s = z.flush
+ z << "bar"
+ s << z.flush_next_in
+ z << "baz"
+ s << z.flush_next_out
+ s << z.deflate("qux", Zlib::FINISH)
+ assert_equal("foobarbazqux", Zlib::Inflate.inflate(s))
+ end
+
+ def test_avail
+ z = Zlib::Deflate.new
+ assert_equal(0, z.avail_in)
+ assert_equal(0, z.avail_out)
+ z << "foo"
+ z.avail_out += 100
+ z << "bar"
+ s = z.finish
+ assert_equal("foobar", Zlib::Inflate.inflate(s))
+ end
+
+ def test_total
+ z = Zlib::Deflate.new
+ 1000.times { z << "foo" }
+ s = z.finish
+ assert_equal(3000, z.total_in)
+ assert_operator(3000, :>, z.total_out)
+ assert_equal("foo" * 1000, Zlib::Inflate.inflate(s))
+ end
+
+ def test_data_type
+ z = Zlib::Deflate.new
+ assert([Zlib::ASCII, Zlib::BINARY, Zlib::UNKNOWN].include?(z.data_type))
+ end
+
+ def test_adler
+ z = Zlib::Deflate.new
+ z << "foo"
+ s = z.finish
+ assert_equal(0x02820145, z.adler)
+ end
+
+ def test_finished_p
+ z = Zlib::Deflate.new
+ assert_equal(false, z.finished?)
+ z << "foo"
+ assert_equal(false, z.finished?)
+ s = z.finish
+ assert_equal(true, z.finished?)
+ z.close
+ assert_raise(Zlib::Error) { z.finished? }
+ end
+
+ def test_closed_p
+ z = Zlib::Deflate.new
+ assert_equal(false, z.closed?)
+ z << "foo"
+ assert_equal(false, z.closed?)
+ s = z.finish
+ assert_equal(false, z.closed?)
+ z.close
+ assert_equal(true, z.closed?)
+ end
+
+ def test_params
+ z = Zlib::Deflate.new
+ z << "foo"
+ z.params(Zlib::DEFAULT_COMPRESSION, Zlib::DEFAULT_STRATEGY)
+ z << "bar"
+ s = z.finish
+ assert_equal("foobar", Zlib::Inflate.inflate(s))
+
+ data = ('a'..'z').to_a.join
+ z = Zlib::Deflate.new(Zlib::NO_COMPRESSION, Zlib::MAX_WBITS,
+ Zlib::DEF_MEM_LEVEL, Zlib::DEFAULT_STRATEGY)
+ z << data[0, 10]
+ z.params(Zlib::BEST_COMPRESSION, Zlib::DEFAULT_STRATEGY)
+ z << data[10 .. -1]
+ assert_equal(data, Zlib::Inflate.inflate(z.finish))
+
+ z = Zlib::Deflate.new
+ s = z.deflate("foo", Zlib::FULL_FLUSH)
+ z.avail_out = 0
+ z.params(Zlib::NO_COMPRESSION, Zlib::FILTERED)
+ s << z.deflate("bar", Zlib::FULL_FLUSH)
+ z.avail_out = 0
+ z.params(Zlib::BEST_COMPRESSION, Zlib::HUFFMAN_ONLY)
+ s << z.deflate("baz", Zlib::FINISH)
+ assert_equal("foobarbaz", Zlib::Inflate.inflate(s))
+
+ z = Zlib::Deflate.new
+ assert_raise(Zlib::StreamError) { z.params(10000, 10000) }
+ z.close # without this, outputs `zlib(finalizer): the stream was freed prematurely.'
+ end
+
+ def test_set_dictionary
+ z = Zlib::Deflate.new
+ z.set_dictionary("foo")
+ s = z.deflate("foo" * 100, Zlib::FINISH)
+ z = Zlib::Inflate.new
+ assert_raise(Zlib::NeedDict) { z.inflate(s) }
+ z.set_dictionary("foo")
+ assert_equal("foo" * 100, z.inflate(s)) # ???
+
+ z = Zlib::Deflate.new
+ z << "foo"
+ assert_raise(Zlib::StreamError) { z.set_dictionary("foo") }
+ z.close # without this, outputs `zlib(finalizer): the stream was freed prematurely.'
+ end
+
+ def test_reset
+ z = Zlib::Deflate.new
+ z << "foo"
+ z.reset
+ z << "bar"
+ s = z.finish
+ assert_equal("bar", Zlib::Inflate.inflate(s))
+ end
+
+ def test_close
+ z = Zlib::Deflate.new
+ z.close
+ assert_raise(Zlib::Error) { z << "foo" }
+ assert_raise(Zlib::Error) { z.reset }
+ end
+ end
+
+ class TestZlibInflate < Test::Unit::TestCase
+ def test_initialize
+ assert_raise(Zlib::StreamError) { Zlib::Inflate.new(-1) }
+
+ s = Zlib::Deflate.deflate("foo")
+ z = Zlib::Inflate.new
+ z << s << nil
+ assert_equal("foo", z.finish)
+ end
+
+ def test_inflate
+ s = Zlib::Deflate.deflate("foo")
+ z = Zlib::Inflate.new
+ s = z.inflate(s)
+ s << z.inflate(nil)
+ assert_equal("foo", s)
+ z.inflate("foo") # ???
+ z << "foo" # ???
+ end
+
+ def test_sync
+ z = Zlib::Deflate.new
+ s = z.deflate("foo" * 1000, Zlib::FULL_FLUSH)
+ z.avail_out = 0
+ z.params(Zlib::NO_COMPRESSION, Zlib::FILTERED)
+ s << z.deflate("bar" * 1000, Zlib::FULL_FLUSH)
+ z.avail_out = 0
+ z.params(Zlib::BEST_COMPRESSION, Zlib::HUFFMAN_ONLY)
+ s << z.deflate("baz" * 1000, Zlib::FINISH)
+
+ z = Zlib::Inflate.new
+ assert_raise(Zlib::DataError) { z << "\0" * 100 }
+ assert_equal(false, z.sync(""))
+ assert_equal(false, z.sync_point?)
+
+ z = Zlib::Inflate.new
+ assert_raise(Zlib::DataError) { z << "\0" * 100 + s }
+ assert_equal(true, z.sync(""))
+ #assert_equal(true, z.sync_point?)
+
+ z = Zlib::Inflate.new
+ assert_equal(false, z.sync("\0" * 100))
+ assert_equal(false, z.sync_point?)
+
+ z = Zlib::Inflate.new
+ assert_equal(true, z.sync("\0" * 100 + s))
+ #assert_equal(true, z.sync_point?)
+ end
+
+ def test_set_dictionary
+ z = Zlib::Inflate.new
+ assert_raise(Zlib::StreamError) { z.set_dictionary("foo") }
+ z.close
+ end
+ end
+
+ class TestZlibGzipFile < Test::Unit::TestCase
+ def test_to_io
+ t = Tempfile.new("test_zlib_gzip_file")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo") }
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_kind_of(IO, f.to_io)
+ end
+
+ def test_crc
+ t = Tempfile.new("test_zlib_gzip_file")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo") }
+
+ f = Zlib::GzipReader.open(t.path)
+ f.read
+ assert_equal(0x8c736521, f.crc)
+ end
+
+ def test_mtime
+ tim = Time.now
+
+ t = Tempfile.new("test_zlib_gzip_file")
+ t.close
+ Zlib::GzipWriter.open(t.path) do |gz|
+ gz.mtime = -1
+ gz.mtime = tim
+ gz.print("foo")
+ gz.flush
+ assert_raise(Zlib::GzipFile::Error) { gz.mtime = Time.now }
+ end
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal(tim.to_i, f.mtime.to_i)
+ end
+
+ def test_level
+ t = Tempfile.new("test_zlib_gzip_file")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo") }
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal(Zlib::DEFAULT_COMPRESSION, f.level)
+ end
+
+ def test_os_code
+ t = Tempfile.new("test_zlib_gzip_file")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo") }
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal(Zlib::OS_CODE, f.os_code)
+ end
+
+ def test_orig_name
+ t = Tempfile.new("test_zlib_gzip_file")
+ t.close
+ Zlib::GzipWriter.open(t.path) do |gz|
+ gz.orig_name = "foobarbazqux\0quux"
+ gz.print("foo")
+ gz.flush
+ assert_raise(Zlib::GzipFile::Error) { gz.orig_name = "quux" }
+ end
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal("foobarbazqux", f.orig_name)
+ end
+
+ def test_comment
+ t = Tempfile.new("test_zlib_gzip_file")
+ t.close
+ Zlib::GzipWriter.open(t.path) do |gz|
+ gz.comment = "foobarbazqux\0quux"
+ gz.print("foo")
+ gz.flush
+ assert_raise(Zlib::GzipFile::Error) { gz.comment = "quux" }
+ end
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal("foobarbazqux", f.comment)
+ end
+
+ def test_lineno
+ t = Tempfile.new("test_zlib_gzip_file")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo\nbar\nbaz\nqux\n") }
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal([0, "foo\n"], [f.lineno, f.gets])
+ assert_equal([1, "bar\n"], [f.lineno, f.gets])
+ f.lineno = 1000
+ assert_equal([1000, "baz\n"], [f.lineno, f.gets])
+ assert_equal([1001, "qux\n"], [f.lineno, f.gets])
+ end
+
+ def test_closed_p
+ t = Tempfile.new("test_zlib_gzip_file")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo") }
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal(false, f.closed?)
+ f.read
+ assert_equal(false, f.closed?)
+ f.close
+ assert_equal(true, f.closed?)
+ end
+
+ def test_sync
+ t = Tempfile.new("test_zlib_gzip_file")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo") }
+
+ f = Zlib::GzipReader.open(t.path)
+ f.sync = true
+ assert_equal(true, f.sync)
+ f.read
+ f.sync = false
+ assert_equal(false, f.sync)
+ f.close
+ end
+
+ def test_pos
+ t = Tempfile.new("test_zlib_gzip_file")
+ t.close
+ Zlib::GzipWriter.open(t.path) do |gz|
+ gz.print("foo")
+ gz.flush
+ assert_equal(3, gz.tell)
+ end
+ end
+
+ def test_path
+ t = Tempfile.new("test_zlib_gzip_file")
+ t.close
+
+ gz = Zlib::GzipWriter.open(t.path)
+ gz.print("foo")
+ assert_equal(t.path, gz.path)
+ gz.close
+ assert_equal(t.path, gz.path)
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal(t.path, f.path)
+ f.close
+ assert_equal(t.path, f.path)
+
+ s = ""
+ sio = StringIO.new(s)
+ gz = Zlib::GzipWriter.new(sio)
+ gz.print("foo")
+ assert_raise(NoMethodError) { gz.path }
+ gz.close
+
+ sio = StringIO.new(s)
+ f = Zlib::GzipReader.new(sio)
+ assert_raise(NoMethodError) { f.path }
+ f.close
+ end
+ end
+
+ class TestZlibGzipReader < Test::Unit::TestCase
+ D0 = "\037\213\010\000S`\017A\000\003\003\000\000\000\000\000\000\000\000\000"
+ def test_read0
+ assert_equal("", Zlib::GzipReader.new(StringIO.new(D0)).read(0))
+ end
+
+ def test_ungetc
+ s = ""
+ w = Zlib::GzipWriter.new(StringIO.new(s))
+ w << (1...1000).to_a.inspect
+ w.close
+ r = Zlib::GzipReader.new(StringIO.new(s))
+ r.read(100)
+ r.ungetc ?a
+ assert_nothing_raised("[ruby-dev:24060]") {
+ r.read(100)
+ r.read
+ r.close
+ }
+ end
+
+ def test_ungetc_paragraph
+ s = ""
+ w = Zlib::GzipWriter.new(StringIO.new(s))
+ w << "abc"
+ w.close
+ r = Zlib::GzipReader.new(StringIO.new(s))
+ r.ungetc ?\n
+ assert_equal("abc", r.gets(""))
+ assert_nothing_raised("[ruby-dev:24065]") {
+ r.read
+ r.close
+ }
+ end
+
+ def test_open
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo") }
+
+ assert_raise(ArgumentError) { Zlib::GzipReader.open }
+
+ assert_equal("foo", Zlib::GzipReader.open(t.path) {|gz| gz.read })
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal("foo", f.read)
+ f.close
+ end
+
+ def test_rewind
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo") }
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal("foo", f.read)
+ f.rewind
+ assert_equal("foo", f.read)
+ f.close
+ end
+
+ def test_unused
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foobar") }
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal("foo", f.read(3))
+ f.unused
+ assert_equal("bar", f.read)
+ f.unused
+ f.close
+ end
+
+ def test_read
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ str = "\u3042\u3044\u3046"
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print(str) }
+
+ f = Zlib::GzipReader.open(t.path, encoding: "UTF-8")
+ assert_raise(ArgumentError) { f.read(-1) }
+ assert_equal(str, f.read)
+ end
+
+ def test_readpartial
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foobar") }
+
+ f = Zlib::GzipReader.open(t.path)
+ assert("foo".start_with?(f.readpartial(3)))
+
+ f = Zlib::GzipReader.open(t.path)
+ s = ""
+ f.readpartial(3, s)
+ assert("foo".start_with?(s))
+
+ assert_raise(ArgumentError) { f.readpartial(-1) }
+ end
+
+ def test_getc
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foobar") }
+
+ f = Zlib::GzipReader.open(t.path)
+ "foobar".each_char {|c| assert_equal(c, f.getc) }
+ assert_nil(f.getc)
+ end
+
+ def test_getbyte
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foobar") }
+
+ f = Zlib::GzipReader.open(t.path)
+ "foobar".each_byte {|c| assert_equal(c, f.getbyte) }
+ assert_nil(f.getbyte)
+ end
+
+ def test_readchar
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foobar") }
+
+ f = Zlib::GzipReader.open(t.path)
+ "foobar".each_byte {|c| assert_equal(c, f.readchar.ord) }
+ assert_raise(EOFError) { f.readchar }
+ end
+
+ def test_each_byte
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foobar") }
+
+ f = Zlib::GzipReader.open(t.path)
+ a = []
+ f.each_byte {|c| a << c }
+ assert_equal("foobar".each_byte.to_a, a)
+ end
+
+ def test_gets2
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo\nbar\nbaz\n") }
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal("foo\n", f.gets)
+ assert_equal("bar\n", f.gets)
+ assert_equal("baz\n", f.gets)
+ assert_nil(f.gets)
+ f.close
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal("foo\nbar\nbaz\n", f.gets(nil))
+ f.close
+ end
+
+ def test_gets
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo\nbar\nbaz\n") }
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal("foo\n", f.readline)
+ assert_equal("bar\n", f.readline)
+ assert_equal("baz\n", f.readline)
+ assert_raise(EOFError) { f.readline }
+ f.close
+ end
+
+ def test_each
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo\nbar\nbaz\n") }
+
+ f = Zlib::GzipReader.open(t.path)
+ a = ["foo\n", "bar\n", "baz\n"]
+ f.each {|l| assert_equal(a.shift, l) }
+ f.close
+ end
+
+ def test_readlines
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo\nbar\nbaz\n") }
+
+ f = Zlib::GzipReader.open(t.path)
+ assert_equal(["foo\n", "bar\n", "baz\n"], f.readlines)
+ f.close
+ end
+
+ def test_reader_wrap
+ t = Tempfile.new("test_zlib_gzip_reader")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo") }
+ f = open(t.path)
+ assert_equal("foo", Zlib::GzipReader.wrap(f) {|gz| gz.read })
+ assert_raise(IOError) { f.close }
+ end
+ end
+
+ class TestZlibGzipWriter < Test::Unit::TestCase
+ def test_invalid_new
+ assert_raise(NoMethodError, "[ruby-dev:23228]") { Zlib::GzipWriter.new(nil).close }
+ assert_raise(NoMethodError, "[ruby-dev:23344]") { Zlib::GzipWriter.new(true).close }
+ assert_raise(NoMethodError, "[ruby-dev:23344]") { Zlib::GzipWriter.new(0).close }
+ assert_raise(NoMethodError, "[ruby-dev:23344]") { Zlib::GzipWriter.new(:hoge).close }
+ end
+
+ def test_open
+ assert_raise(ArgumentError) { Zlib::GzipWriter.open }
+
+ t = Tempfile.new("test_zlib_gzip_writer")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo") }
+ assert_equal("foo", Zlib::GzipReader.open(t.path) {|gz| gz.read })
+
+ f = Zlib::GzipWriter.open(t.path)
+ f.print("bar")
+ f.close
+ assert_equal("bar", Zlib::GzipReader.open(t.path) {|gz| gz.read })
+
+ assert_raise(Zlib::StreamError) { Zlib::GzipWriter.open(t.path, 10000) }
+ end
+
+ def test_write
+ t = Tempfile.new("test_zlib_gzip_writer")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print("foo") }
+ assert_equal("foo", Zlib::GzipReader.open(t.path) {|gz| gz.read })
+
+ o = Object.new
+ def o.to_s; "bar"; end
+ Zlib::GzipWriter.open(t.path) {|gz| gz.print(o) }
+ assert_equal("bar", Zlib::GzipReader.open(t.path) {|gz| gz.read })
+ end
+
+ def test_putc
+ t = Tempfile.new("test_zlib_gzip_writer")
+ t.close
+ Zlib::GzipWriter.open(t.path) {|gz| gz.putc(?x) }
+ assert_equal("x", Zlib::GzipReader.open(t.path) {|gz| gz.read })
+
+ # todo: multibyte char
+ end
+
+ def test_writer_wrap
+ t = Tempfile.new("test_zlib_gzip_writer")
+ Zlib::GzipWriter.wrap(t) {|gz| gz.print("foo") }
+ t.close
+ assert_equal("foo", Zlib::GzipReader.open(t.path) {|gz| gz.read })
+ end
+ end
+
+ class TestZlib < Test::Unit::TestCase
+ def test_version
+ assert_instance_of(String, Zlib.zlib_version)
+ assert(Zlib.zlib_version.tainted?)
+ end
+
+ def test_adler32
+ assert_equal(0x00000001, Zlib.adler32)
+ assert_equal(0x02820145, Zlib.adler32("foo"))
+ assert_equal(0x02820145, Zlib.adler32("o", Zlib.adler32("fo")))
+ assert_equal(0x8a62c964, Zlib.adler32("abc\x01\x02\x03" * 10000))
+ end
+
+ def test_adler32_combine
+ one = Zlib.adler32("fo")
+ two = Zlib.adler32("o")
+ begin
+ assert_equal(0x02820145, Zlib.adler32_combine(one, two, 1))
+ rescue NotImplementedError
+ skip "adler32_combine is not implemented"
+ end
+ end
+
+ def test_crc32
+ assert_equal(0x00000000, Zlib.crc32)
+ assert_equal(0x8c736521, Zlib.crc32("foo"))
+ assert_equal(0x8c736521, Zlib.crc32("o", Zlib.crc32("fo")))
+ assert_equal(0x07f0d68f, Zlib.crc32("abc\x01\x02\x03" * 10000))
+ end
+
+ def test_crc32_combine
+ one = Zlib.crc32("fo")
+ two = Zlib.crc32("o")
+ begin
+ assert_equal(0x8c736521, Zlib.crc32_combine(one, two, 1))
+ rescue NotImplementedError
+ skip "crc32_combine is not implemented"
+ end
+ end
+
+ def test_crc_table
+ t = Zlib.crc_table
+ assert_instance_of(Array, t)
+ t.each {|x| assert_kind_of(Integer, x) }
+ end
+ end
+end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20101014/8c61b327/attachment-0001.html>
More information about the macruby-changes
mailing list