diff --git a/NEWS.md b/NEWS.md index 7534539a21d2c9..5a9277b3992411 100644 --- a/NEWS.md +++ b/NEWS.md @@ -184,7 +184,7 @@ The following default gems are updated. * io-console 0.8.1 * io-nonblock 0.3.2 * io-wait 0.3.2 -* json 2.13.2 +* json 2.14.1 * optparse 0.7.0.dev.2 * prism 1.5.1 * psych 5.2.6 diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index 8fcc980d478f80..6a38cc60a7964f 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -29,6 +29,7 @@ typedef struct JSON_Generator_StateStruct { enum duplicate_key_action on_duplicate_key; + bool as_json_single_arg; bool allow_nan; bool ascii_only; bool script_safe; @@ -1033,6 +1034,13 @@ json_inspect_hash_with_mixed_keys(struct hash_foreach_arg *arg) } } +static VALUE +json_call_as_json(JSON_Generator_State *state, VALUE object, VALUE is_key) +{ + VALUE proc_args[2] = {object, is_key}; + return rb_proc_call_with_block(state->as_json, 2, proc_args, Qnil); +} + static int json_object_i(VALUE key, VALUE val, VALUE _arg) { @@ -1086,7 +1094,7 @@ json_object_i(VALUE key, VALUE val, VALUE _arg) default: if (data->state->strict) { if (RTEST(data->state->as_json) && !as_json_called) { - key = rb_proc_call_with_block(data->state->as_json, 1, &key, Qnil); + key = json_call_as_json(data->state, key, Qtrue); key_type = rb_type(key); as_json_called = true; goto start; @@ -1328,7 +1336,7 @@ static void generate_json_float(FBuffer *buffer, struct generate_json_data *data /* for NaN and Infinity values we either raise an error or rely on Float#to_s. */ if (!allow_nan) { if (data->state->strict && data->state->as_json) { - VALUE casted_obj = rb_proc_call_with_block(data->state->as_json, 1, &obj, Qnil); + VALUE casted_obj = json_call_as_json(data->state, obj, Qfalse); if (casted_obj != obj) { increase_depth(data); generate_json(buffer, data, casted_obj); @@ -1345,12 +1353,11 @@ static void generate_json_float(FBuffer *buffer, struct generate_json_data *data } /* This implementation writes directly into the buffer. We reserve - * the 28 characters that fpconv_dtoa states as its maximum. + * the 32 characters that fpconv_dtoa states as its maximum. */ - fbuffer_inc_capa(buffer, 28); + fbuffer_inc_capa(buffer, 32); char* d = buffer->ptr + buffer->len; int len = fpconv_dtoa(value, d); - /* fpconv_dtoa converts a float to its shortest string representation, * but it adds a ".0" if this is a plain integer. */ @@ -1417,7 +1424,7 @@ static void generate_json(FBuffer *buffer, struct generate_json_data *data, VALU general: if (data->state->strict) { if (RTEST(data->state->as_json) && !as_json_called) { - obj = rb_proc_call_with_block(data->state->as_json, 1, &obj, Qnil); + obj = json_call_as_json(data->state, obj, Qfalse); as_json_called = true; goto start; } else { @@ -1943,6 +1950,7 @@ static int configure_state_i(VALUE key, VALUE val, VALUE _arg) else if (key == sym_allow_duplicate_key) { state->on_duplicate_key = RTEST(val) ? JSON_IGNORE : JSON_RAISE; } else if (key == sym_as_json) { VALUE proc = RTEST(val) ? rb_convert_type(val, T_DATA, "Proc", "to_proc") : Qfalse; + state->as_json_single_arg = proc && rb_proc_arity(proc) == 1; state_write_value(data, &state->as_json, proc); } return ST_CONTINUE; diff --git a/ext/json/lib/json/version.rb b/ext/json/lib/json/version.rb index f9ac3e17a947a5..9c928e3940e493 100644 --- a/ext/json/lib/json/version.rb +++ b/ext/json/lib/json/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module JSON - VERSION = '2.13.2' + VERSION = '2.14.1' end diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c index e34f1999d5f191..297031dcf17bb6 100644 --- a/ext/json/parser/parser.c +++ b/ext/json/parser/parser.c @@ -713,11 +713,16 @@ static VALUE json_string_unescape(JSON_ParserState *state, const char *string, c } if (pe[0] == '\\' && pe[1] == 'u') { uint32_t sur = unescape_unicode(state, (unsigned char *) pe + 2); + + if ((sur & 0xFC00) != 0xDC00) { + raise_parse_error_at("invalid surrogate pair at %s", state, p); + } + ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) | (sur & 0x3FF)); pe += 5; } else { - unescape = (char *) "?"; + raise_parse_error_at("incomplete surrogate pair at %s", state, p); break; } } diff --git a/ext/json/vendor/fpconv.c b/ext/json/vendor/fpconv.c index 75efd46f11e624..e91c7889c26b5d 100644 --- a/ext/json/vendor/fpconv.c +++ b/ext/json/vendor/fpconv.c @@ -29,6 +29,10 @@ #include #include +#ifdef JSON_DEBUG +#include +#endif + #define npowers 87 #define steppowers 8 #define firstpower -348 /* 10 ^ -348 */ @@ -320,15 +324,7 @@ static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg) { int exp = absv(K + ndigits - 1); - int max_trailing_zeros = 7; - - if(neg) { - max_trailing_zeros -= 1; - } - - /* write plain integer */ - if(K >= 0 && (exp < (ndigits + max_trailing_zeros))) { - + if(K >= 0 && exp < 15) { memcpy(dest, digits, ndigits); memset(dest + ndigits, '0', K); @@ -432,10 +428,12 @@ static int filter_special(double fp, char* dest) * * Input: * fp -> the double to convert, dest -> destination buffer. - * The generated string will never be longer than 28 characters. - * Make sure to pass a pointer to at least 28 bytes of memory. + * The generated string will never be longer than 32 characters. + * Make sure to pass a pointer to at least 32 bytes of memory. * The emitted string will not be null terminated. * + * + * * Output: * The number of written characters. * @@ -474,6 +472,9 @@ static int fpconv_dtoa(double d, char dest[28]) int ndigits = grisu2(d, digits, &K); str_len += emit_digits(digits, ndigits, dest + str_len, K, neg); +#ifdef JSON_DEBUG + assert(str_len <= 32); +#endif return str_len; } diff --git a/imemo.c b/imemo.c index 10ac960095675f..5a5ec4a4d382e8 100644 --- a/imemo.c +++ b/imemo.c @@ -123,7 +123,7 @@ rb_imemo_fields_new(VALUE owner, size_t capa) static VALUE imemo_fields_new_complex(VALUE owner, size_t capa) { - VALUE fields = imemo_fields_new(owner, 1); + VALUE fields = rb_imemo_new(imemo_fields, owner, sizeof(struct rb_fields)); IMEMO_OBJ_FIELDS(fields)->as.complex.table = st_init_numtable_with_size(capa); FL_SET_RAW(fields, OBJ_FIELD_HEAP); return fields; diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index 0635260e95c2db..c577f4981470a4 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -24,7 +24,7 @@ class CLI < Thor }.freeze def self.start(*) - check_deprecated_ext_option(ARGV) if ARGV.include?("--ext") + check_invalid_ext_option(ARGV) if ARGV.include?("--ext") super ensure @@ -288,12 +288,11 @@ def update(*gems) Calling show with [GEM] will list the exact location of that gem on your machine. D method_option "paths", type: :boolean, banner: "List the paths of all gems that are required by your Gemfile." - method_option "outdated", type: :boolean, banner: "Show verbose output including whether gems are outdated." + method_option "outdated", type: :boolean, banner: "Show verbose output including whether gems are outdated (removed)." def show(gem_name = nil) if ARGV.include?("--outdated") - message = "the `--outdated` flag to `bundle show` will be removed in favor of `bundle show --verbose`" removed_message = "the `--outdated` flag to `bundle show` has been removed in favor of `bundle show --verbose`" - SharedHelpers.major_deprecation(2, message, removed_message: removed_message) + raise InvalidOption, removed_message end require_relative "cli/show" Show.new(options, gem_name).run @@ -658,18 +657,15 @@ def self.reformatted_help_args(args) end end - def self.check_deprecated_ext_option(arguments) - # when deprecated version of `--ext` is called - # print out deprecation warning and pretend `--ext=c` was provided - if deprecated_ext_value?(arguments) - message = "Extensions can now be generated using C or Rust, so `--ext` with no arguments has been deprecated. Please select a language, e.g. `--ext=rust` to generate a Rust extension. This gem will now be generated as if `--ext=c` was used." + def self.check_invalid_ext_option(arguments) + # when invalid version of `--ext` is called + if invalid_ext_value?(arguments) removed_message = "Extensions can now be generated using C or Rust, so `--ext` with no arguments has been removed. Please select a language, e.g. `--ext=rust` to generate a Rust extension." - SharedHelpers.major_deprecation 2, message, removed_message: removed_message - arguments[arguments.index("--ext")] = "--ext=c" + raise InvalidOption, removed_message end end - def self.deprecated_ext_value?(arguments) + def self.invalid_ext_value?(arguments) index = arguments.index("--ext") next_argument = arguments[index + 1] @@ -677,15 +673,15 @@ def self.deprecated_ext_value?(arguments) # for example `bundle gem hello --ext c` return false if EXTENSIONS.include?(next_argument) - # deprecated call when --ext is called with no value in last position + # invalid call when --ext is called with no value in last position # for example `bundle gem hello_gem --ext` return true if next_argument.nil? - # deprecated call when --ext is followed by other parameter + # invalid call when --ext is followed by other parameter # for example `bundle gem --ext --no-ci hello_gem` return true if next_argument.start_with?("-") - # deprecated call when --ext is followed by gem name + # invalid call when --ext is followed by gem name # for example `bundle gem --ext hello_gem` return true if next_argument diff --git a/lib/bundler/cli/plugin.rb b/lib/bundler/cli/plugin.rb index fd61ef0d954dea..32fa660fe0a3f1 100644 --- a/lib/bundler/cli/plugin.rb +++ b/lib/bundler/cli/plugin.rb @@ -10,11 +10,15 @@ class CLI::Plugin < Thor method_option "source", type: :string, default: nil, banner: "URL of the RubyGems source to fetch the plugin from" method_option "version", type: :string, default: nil, banner: "The version of the plugin to fetch" method_option "git", type: :string, default: nil, banner: "URL of the git repo to fetch from" - method_option "local_git", type: :string, default: nil, banner: "Path of the local git repo to fetch from (deprecated)" + method_option "local_git", type: :string, default: nil, banner: "Path of the local git repo to fetch from (removed)" method_option "branch", type: :string, default: nil, banner: "The git branch to checkout" method_option "ref", type: :string, default: nil, banner: "The git revision to check out" method_option "path", type: :string, default: nil, banner: "Path of a local gem to directly use" def install(*plugins) + if options.key?(:local_git) + raise InvalidOption, "--local_git has been removed, use --git" + end + Bundler::Plugin.install(plugins, options) end diff --git a/lib/bundler/cli/show.rb b/lib/bundler/cli/show.rb index b55eb7bad5aecc..67fdcc797e8592 100644 --- a/lib/bundler/cli/show.rb +++ b/lib/bundler/cli/show.rb @@ -6,7 +6,7 @@ class CLI::Show def initialize(options, gem_name) @options = options @gem_name = gem_name - @verbose = options[:verbose] || options[:outdated] + @verbose = options[:verbose] @latest_specs = fetch_latest_specs if @verbose end diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 32dd13399ec597..49627cc56237ce 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -136,7 +136,7 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti @locked_sources = [] @originally_locked_specs = @locked_specs @originally_locked_sources = @locked_sources - @locked_checksums = Bundler.feature_flag.lockfile_checksums? + @locked_checksums = Bundler.settings[:lockfile_checksums] end @unlocking_ruby ||= if @ruby_version && locked_ruby_version_object diff --git a/lib/bundler/feature_flag.rb b/lib/bundler/feature_flag.rb index 73e6ddcc68beb5..b2b134889573c1 100644 --- a/lib/bundler/feature_flag.rb +++ b/lib/bundler/feature_flag.rb @@ -27,9 +27,7 @@ def self.settings_method(name, key, &default) (1..10).each {|v| define_method("bundler_#{v}_mode?") { @major_version >= v } } - settings_flag(:cache_all) { bundler_4_mode? } settings_flag(:global_gem_cache) { bundler_5_mode? } - settings_flag(:lockfile_checksums) { bundler_4_mode? } settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") } settings_flag(:update_requires_all_flag) { bundler_5_mode? } diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1 index b7276daa89195a..29e830a3b0e03b 100644 --- a/lib/bundler/man/bundle-config.1 +++ b/lib/bundler/man/bundle-config.1 @@ -146,7 +146,7 @@ Generate a \fBgems\.rb\fR instead of a \fBGemfile\fR when running \fBbundle init The number of gems Bundler can install in parallel\. Defaults to the number of available processors\. .TP \fBlockfile_checksums\fR (\fBBUNDLE_LOCKFILE_CHECKSUMS\fR) -Whether Bundler should include a checksums section in new lockfiles, to protect from compromised gem sources\. +Whether Bundler should include a checksums section in new lockfiles, to protect from compromised gem sources\. Defaults to true\. .TP \fBno_install\fR (\fBBUNDLE_NO_INSTALL\fR) Whether \fBbundle package\fR should skip installing gems\. diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn index 18260c6c931f09..62fce8fa919aa0 100644 --- a/lib/bundler/man/bundle-config.1.ronn +++ b/lib/bundler/man/bundle-config.1.ronn @@ -190,7 +190,7 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html). The number of gems Bundler can install in parallel. Defaults to the number of available processors. * `lockfile_checksums` (`BUNDLE_LOCKFILE_CHECKSUMS`): - Whether Bundler should include a checksums section in new lockfiles, to protect from compromised gem sources. + Whether Bundler should include a checksums section in new lockfiles, to protect from compromised gem sources. Defaults to true. * `no_install` (`BUNDLE_NO_INSTALL`): Whether `bundle package` should skip installing gems. * `no_prune` (`BUNDLE_NO_PRUNE`): diff --git a/lib/bundler/man/bundle-plugin.1 b/lib/bundler/man/bundle-plugin.1 index 9da6927dc4d8f0..25da56247598b5 100644 --- a/lib/bundler/man/bundle-plugin.1 +++ b/lib/bundler/man/bundle-plugin.1 @@ -4,7 +4,7 @@ .SH "NAME" \fBbundle\-plugin\fR \- Manage Bundler plugins .SH "SYNOPSIS" -\fBbundle plugin\fR install PLUGINS [\-\-source=SOURCE] [\-\-version=VERSION] [\-\-git=GIT] [\-\-branch=BRANCH|\-\-ref=REF] [\-\-local\-git=LOCAL_GIT] [\-\-path=PATH] +\fBbundle plugin\fR install PLUGINS [\-\-source=SOURCE] [\-\-version=VERSION] [\-\-git=GIT] [\-\-branch=BRANCH|\-\-ref=REF] [\-\-path=PATH] .br \fBbundle plugin\fR uninstall PLUGINS [\-\-all] .br @@ -54,13 +54,6 @@ When you specify \fB\-\-git\fR, you can use \fB\-\-ref\fR to specify any tag, or Install the plugin gem from a local path\. .IP Example: \fBbundle plugin install bundler\-graph \-\-path \.\./bundler\-graph\fR -.TP -\fB\-\-local\-git=LOCAL_GIT\fR -Install the plugin gem from a local Git repository\. -.IP -Example: \fBbundle plugin install bundler\-graph \-\-local\-git \.\./bundler\-graph\fR\. -.IP -This option is deprecated in favor of \fB\-\-git\fR\. .SS "uninstall" Uninstall the plugin(s) specified in PLUGINS\. .P diff --git a/lib/bundler/man/bundle-plugin.1.ronn b/lib/bundler/man/bundle-plugin.1.ronn index efb42407611836..b54e0c08b4e424 100644 --- a/lib/bundler/man/bundle-plugin.1.ronn +++ b/lib/bundler/man/bundle-plugin.1.ronn @@ -5,7 +5,6 @@ bundle-plugin(1) -- Manage Bundler plugins `bundle plugin` install PLUGINS [--source=SOURCE] [--version=VERSION] [--git=GIT] [--branch=BRANCH|--ref=REF] - [--local-git=LOCAL_GIT] [--path=PATH]
`bundle plugin` uninstall PLUGINS [--all]
`bundle plugin` list
@@ -59,13 +58,6 @@ global source specified in Gemfile is ignored. Example: `bundle plugin install bundler-graph --path ../bundler-graph` -* `--local-git=LOCAL_GIT`: - Install the plugin gem from a local Git repository. - - Example: `bundle plugin install bundler-graph --local-git ../bundler-graph`. - - This option is deprecated in favor of `--git`. - ### uninstall Uninstall the plugin(s) specified in PLUGINS. diff --git a/lib/bundler/man/bundle-show.1 b/lib/bundler/man/bundle-show.1 index 3a6d157903d6bb..901460962cfed6 100644 --- a/lib/bundler/man/bundle-show.1 +++ b/lib/bundler/man/bundle-show.1 @@ -4,7 +4,7 @@ .SH "NAME" \fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem .SH "SYNOPSIS" -\fBbundle show\fR [GEM] [\-\-paths] [\-\-outdated] +\fBbundle show\fR [GEM] [\-\-paths] .SH "DESCRIPTION" Without the [GEM] option, \fBshow\fR will print a list of the names and versions of all gems that are required by your [\fBGemfile(5)\fR][Gemfile(5)], sorted by name\. .P @@ -13,7 +13,4 @@ Calling show with [GEM] will list the exact location of that gem on your machine .TP \fB\-\-paths\fR List the paths of all gems that are required by your [\fBGemfile(5)\fR][Gemfile(5)], sorted by gem name\. -.TP -\fB\-\-outdated\fR -Show verbose output including whether gems are outdated\. diff --git a/lib/bundler/man/bundle-show.1.ronn b/lib/bundler/man/bundle-show.1.ronn index 6e80b046964704..a6a59a1445dcd3 100644 --- a/lib/bundler/man/bundle-show.1.ronn +++ b/lib/bundler/man/bundle-show.1.ronn @@ -5,7 +5,6 @@ bundle-show(1) -- Shows all the gems in your bundle, or the path to a gem `bundle show` [GEM] [--paths] - [--outdated] ## DESCRIPTION @@ -20,6 +19,3 @@ machine. * `--paths`: List the paths of all gems that are required by your [`Gemfile(5)`][Gemfile(5)], sorted by gem name. - -* `--outdated`: - Show verbose output including whether gems are outdated. diff --git a/lib/bundler/materialization.rb b/lib/bundler/materialization.rb index 43124f25fbedbf..82e48464a73bd9 100644 --- a/lib/bundler/materialization.rb +++ b/lib/bundler/materialization.rb @@ -29,7 +29,7 @@ def specs end def dependencies - specs.first.runtime_dependencies.map {|d| [d, platform] } + (materialized_spec || specs.first).runtime_dependencies.map {|d| [d, platform] } end def materialized_spec diff --git a/lib/bundler/plugin/installer.rb b/lib/bundler/plugin/installer.rb index ac3c3ea7f31216..853ad9edca4f6f 100644 --- a/lib/bundler/plugin/installer.rb +++ b/lib/bundler/plugin/installer.rb @@ -43,16 +43,6 @@ def definition.lock(*); end private def check_sources_consistency!(options) - if options.key?(:git) && options.key?(:local_git) - raise InvalidOption, "Remote and local plugin git sources can't be both specified" - end - - # back-compat; local_git is an alias for git - if options.key?(:local_git) - Bundler::SharedHelpers.major_deprecation(2, "--local_git is deprecated, use --git") - options[:git] = options.delete(:local_git) - end - if (options.keys & [:source, :git, :path]).length > 1 raise InvalidOption, "Only one of --source, --git, or --path may be specified" end diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb index ecc3ee8080a239..7923ba51c36630 100644 --- a/lib/bundler/settings.rb +++ b/lib/bundler/settings.rb @@ -81,6 +81,8 @@ class Settings "BUNDLE_RETRY" => 3, "BUNDLE_TIMEOUT" => 10, "BUNDLE_VERSION" => "lockfile", + "BUNDLE_LOCKFILE_CHECKSUMS" => true, + "BUNDLE_CACHE_ALL" => true, }.freeze def initialize(root = nil) diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb index ddea7714a16f5d..bb12ff52f514fb 100644 --- a/lib/bundler/source/git.rb +++ b/lib/bundler/source/git.rb @@ -268,7 +268,7 @@ def local? private def cache_to(custom_path, try_migrate: false) - return unless Bundler.feature_flag.cache_all? + return unless Bundler.settings[:cache_all] app_cache_path = app_cache_path(custom_path) diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb index 76bd1c66c19f08..d258270fe09dd9 100644 --- a/lib/bundler/source/path.rb +++ b/lib/bundler/source/path.rb @@ -83,7 +83,7 @@ def install(spec, options = {}) def cache(spec, custom_path = nil) app_cache_path = app_cache_path(custom_path) - return unless Bundler.feature_flag.cache_all? + return unless Bundler.settings[:cache_all] return if expand(@original_path).to_s.index(root_path.to_s + "/") == 0 unless @original_path.exist? diff --git a/lib/rubygems.rb b/lib/rubygems.rb index f8f1451ee661a7..8bb8cdfc0486de 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -16,6 +16,7 @@ module Gem require_relative "rubygems/deprecate" require_relative "rubygems/errors" require_relative "rubygems/target_rbconfig" +require_relative "rubygems/win_platform" ## # RubyGems is the Ruby standard for publishing and managing third party @@ -113,18 +114,6 @@ module Gem module Gem RUBYGEMS_DIR = __dir__ - ## - # An Array of Regexps that match windows Ruby platforms. - - WIN_PATTERNS = [ - /bccwin/i, - /cygwin/i, - /djgpp/i, - /mingw/i, - /mswin/i, - /wince/i, - ].freeze - GEM_DEP_FILES = %w[ gem.deps.rb gems.rb @@ -160,8 +149,6 @@ module Gem DEFAULT_SOURCE_DATE_EPOCH = 315_619_200 - @@win_platform = nil - @configuration = nil @gemdeps = nil @loaded_specs = {} @@ -1091,18 +1078,6 @@ def self.use_paths(home, *paths) self.paths = hash end - ## - # Is this a windows platform? - - def self.win_platform? - if @@win_platform.nil? - ruby_platform = RbConfig::CONFIG["host_os"] - @@win_platform = !WIN_PATTERNS.find {|r| ruby_platform =~ r }.nil? - end - - @@win_platform - end - ## # Is this a java platform? diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index cd8dfdf37d1a15..b56d68cc45bb15 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -7,6 +7,7 @@ # rubocop:enable Style/AsciiComments +require_relative "win_platform" require_relative "security" require_relative "user_interaction" @@ -518,10 +519,12 @@ def install_location(filename, destination_dir) # :nodoc: destination end - def normalize_path(pathname) - if Gem.win_platform? + if Gem.win_platform? + def normalize_path(pathname) # :nodoc: pathname.downcase - else + end + else + def normalize_path(pathname) # :nodoc: pathname end end diff --git a/lib/rubygems/win_platform.rb b/lib/rubygems/win_platform.rb new file mode 100644 index 00000000000000..78e968fe493084 --- /dev/null +++ b/lib/rubygems/win_platform.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require "rbconfig" + +module Gem + ## + # An Array of Regexps that match windows Ruby platforms. + + WIN_PATTERNS = [ + /bccwin/i, + /cygwin/i, + /djgpp/i, + /mingw/i, + /mswin/i, + /wince/i, + ].freeze + + @@win_platform = nil + + ## + # Is this a windows platform? + + def self.win_platform? + if @@win_platform.nil? + ruby_platform = RbConfig::CONFIG["host_os"] + @@win_platform = !WIN_PATTERNS.find {|r| ruby_platform =~ r }.nil? + end + + @@win_platform + end +end diff --git a/spec/bundler/cache/git_spec.rb b/spec/bundler/cache/git_spec.rb index 66eaf65dd1201d..149fad28384446 100644 --- a/spec/bundler/cache/git_spec.rb +++ b/spec/bundler/cache/git_spec.rb @@ -13,6 +13,22 @@ end RSpec.describe "bundle cache with git" do + it "does not copy repository to vendor cache when cache_all set to false" do + git = build_git "foo" + ref = git.ref_for("main", 11) + + install_gemfile <<-G + source "https://gem.repo1" + gem "foo", :git => '#{lib_path("foo-1.0")}' + G + + bundle "config cache_all false" + bundle :cache + expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).not_to exist + + expect(the_bundle).to include_gems "foo 1.0" + end + it "copies repository to vendor cache and uses it" do git = build_git "foo" ref = git.ref_for("main", 11) @@ -22,7 +38,6 @@ gem "foo", :git => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.git")).not_to exist @@ -43,7 +58,6 @@ bundle "config set --local path vendor/bundle" bundle "install" - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist @@ -61,7 +75,6 @@ gem "foo", :git => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" bundle :cache bundle :cache @@ -79,7 +92,6 @@ gem "foo", :git => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" bundle :cache update_git "foo" do |s| @@ -109,7 +121,6 @@ gem "foo", :git => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" bundle :cache update_git "foo" do |s| @@ -140,7 +151,6 @@ bundle %(config set local.foo #{lib_path("foo-1.0")}) bundle "install" - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/foo-invalid-#{ref}")).to exist @@ -179,7 +189,6 @@ source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" bundle :cache, "all-platforms" => true pristine_system_gems @@ -196,7 +205,6 @@ source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" bundle :cache, "all-platforms" => true pristine_system_gems @@ -213,7 +221,6 @@ source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" bundle :cache, "all-platforms" => true pristine_system_gems @@ -242,7 +249,6 @@ gem "foo", :git => '#{lib_path("foo-1.0")}' G bundle "config set global_gem_cache false" - bundle "config set cache_all true" bundle "config path vendor/bundle" bundle :install @@ -274,7 +280,6 @@ gem "foo", :git => '#{lib_path("foo-1.0")}' G bundle "config set global_gem_cache false" - bundle "config set cache_all true" bundle "config path vendor/bundle" bundle :install @@ -304,7 +309,6 @@ gem "foo", :git => '#{lib_path("foo-1.0")}' G bundle "config set global_gem_cache false" - bundle "config set cache_all true" bundle "config path vendor/bundle" bundle :install @@ -342,7 +346,6 @@ G ref = git.ref_for("main", 11) - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/has_submodule-1.0-#{ref}")).to exist @@ -362,7 +365,6 @@ source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" bundle :cache ref = git.ref_for("main", 11) @@ -377,7 +379,6 @@ source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" bundle :cache, "all-platforms" => true, :install => false pristine_system_gems @@ -436,7 +437,6 @@ source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" # The algorithm for the cache location for a git checkout is # in Bundle::Source::Git#cache_path @@ -498,7 +498,6 @@ end FileUtils.mkdir_p(bundled_app("vendor/cache")) - bundle "config set cache_all all" install_gemfile <<-G source "https://gem.repo1" diff --git a/spec/bundler/cache/path_spec.rb b/spec/bundler/cache/path_spec.rb index 2a64397417ba82..6865e54b321fa9 100644 --- a/spec/bundler/cache/path_spec.rb +++ b/spec/bundler/cache/path_spec.rb @@ -9,7 +9,6 @@ gem "foo", :path => '#{bundled_app("lib/foo")}' G - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/foo-1.0")).not_to exist expect(the_bundle).to include_gems "foo 1.0" @@ -23,7 +22,6 @@ gem "foo", :path => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/foo-1.0")).to exist expect(bundled_app("vendor/cache/foo-1.0/.bundlecache")).to be_file @@ -42,7 +40,6 @@ gem "#{libname}", :path => '#{libpath}' G - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/#{libname}")).to exist expect(bundled_app("vendor/cache/#{libname}/.bundlecache")).to be_file @@ -58,7 +55,6 @@ gem "foo", :path => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" bundle :cache build_lib "foo" do |s| @@ -81,7 +77,6 @@ gem "foo", :path => '#{lib_path("foo-1.0")}' G - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/foo-1.0")).to exist @@ -97,20 +92,21 @@ expect(bundled_app("vendor/cache/foo-1.0")).not_to exist end - it "does not cache path gems by default" do + it "does not cache path gems if cache_all is set to false" do build_lib "foo" install_gemfile <<-G source "https://gem.repo1" gem "foo", :path => '#{lib_path("foo-1.0")}' G + bundle "config cache_all false" bundle :cache expect(err).to be_empty expect(bundled_app("vendor/cache/foo-1.0")).not_to exist end - it "caches path gems by default", bundler: "4" do + it "caches path gems by default" do build_lib "foo" install_gemfile <<-G diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb index 5a31d1733a5556..a7460ed695a456 100644 --- a/spec/bundler/commands/lock_spec.rb +++ b/spec/bundler/commands/lock_spec.rb @@ -2097,7 +2097,7 @@ L end - it "generates checksums by default if configured to do so" do + it "generates checksums by default" do build_repo4 do build_gem "nokogiri", "1.14.2" build_gem "nokogiri", "1.14.2" do |s| @@ -2105,8 +2105,6 @@ end end - bundle "config lockfile_checksums true" - simulate_platform "x86_64-linux" do install_gemfile <<-G source "https://gem.repo4" @@ -2139,6 +2137,43 @@ L end + it "disables checksums if configured to do so" do + build_repo4 do + build_gem "nokogiri", "1.14.2" + build_gem "nokogiri", "1.14.2" do |s| + s.platform = "x86_64-linux" + end + end + + bundle "config lockfile_checksums false" + + simulate_platform "x86_64-linux" do + install_gemfile <<-G + source "https://gem.repo4" + + gem "nokogiri" + G + end + + expect(lockfile).to eq <<~L + GEM + remote: https://gem.repo4/ + specs: + nokogiri (1.14.2) + nokogiri (1.14.2-x86_64-linux) + + PLATFORMS + ruby + x86_64-linux + + DEPENDENCIES + nokogiri + + BUNDLED WITH + #{Bundler::VERSION} + L + end + context "when re-resolving to include prereleases" do before do build_repo4 do diff --git a/spec/bundler/commands/newgem_spec.rb b/spec/bundler/commands/newgem_spec.rb index 0b13344f994154..1ce4a0da09cac1 100644 --- a/spec/bundler/commands/newgem_spec.rb +++ b/spec/bundler/commands/newgem_spec.rb @@ -1661,24 +1661,6 @@ def create_temporary_dir(dir) include_examples "paths that depend on gem name" - context "--ext parameter with no value" do - context "is deprecated" do - it "prints deprecation when used after gem name" do - bundle ["gem", "--ext", gem_name].compact.join(" ") - expect(err).to include "[DEPRECATED]" - expect(err).to include "`--ext` with no arguments has been deprecated" - expect(bundled_app("#{gem_name}/ext/#{gem_name}/#{gem_name}.c")).to exist - end - - it "prints deprecation when used before gem name" do - bundle ["gem", gem_name, "--ext"].compact.join(" ") - expect(err).to include "[DEPRECATED]" - expect(err).to include "`--ext` with no arguments has been deprecated" - expect(bundled_app("#{gem_name}/ext/#{gem_name}/#{gem_name}.c")).to exist - end - end - end - context "--ext parameter set with C" do let(:flags) { "--ext=c" } @@ -1686,10 +1668,6 @@ def create_temporary_dir(dir) bundle ["gem", gem_name, flags].compact.join(" ") end - it "is not deprecated" do - expect(err).not_to include "[DEPRECATED] Option `--ext` without explicit value is deprecated." - end - it "builds ext skeleton" do expect(bundled_app("#{gem_name}/ext/#{gem_name}/extconf.rb")).to exist expect(bundled_app("#{gem_name}/ext/#{gem_name}/#{gem_name}.h")).to exist diff --git a/spec/bundler/commands/show_spec.rb b/spec/bundler/commands/show_spec.rb index ba903ac4957a5a..34e809f1358191 100644 --- a/spec/bundler/commands/show_spec.rb +++ b/spec/bundler/commands/show_spec.rb @@ -210,33 +210,6 @@ expect(err).to include("Could not find gem '#{invalid_regexp}'.") end end - - context "--outdated option" do - # Regression test for https://github.com/rubygems/bundler/issues/5375 - before do - build_repo2 - end - - it "doesn't update gems to newer versions" do - install_gemfile <<-G - source "https://gem.repo2" - gem "rails" - G - - expect(the_bundle).to include_gem("rails 2.3.2") - - update_repo2 do - build_gem "rails", "3.0.0" do |s| - s.executables = "rails" - end - end - - bundle "show --outdated" - - bundle "install" - expect(the_bundle).to include_gem("rails 2.3.2") - end - end end RSpec.describe "bundle show", bundler: "5" do diff --git a/spec/bundler/install/deploy_spec.rb b/spec/bundler/install/deploy_spec.rb index e401f26a16ece2..7d10ef059407bb 100644 --- a/spec/bundler/install/deploy_spec.rb +++ b/spec/bundler/install/deploy_spec.rb @@ -474,7 +474,6 @@ bundle :install expect(the_bundle).to include_gems "foo 1.0" - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/foo")).to be_directory diff --git a/spec/bundler/install/gemfile/path_spec.rb b/spec/bundler/install/gemfile/path_spec.rb index 55bf11928d6acd..ea59f11bbe9773 100644 --- a/spec/bundler/install/gemfile/path_spec.rb +++ b/spec/bundler/install/gemfile/path_spec.rb @@ -831,6 +831,55 @@ end end + context "when platform specific version locked, and having less dependencies that the generic version that's actually installed" do + before do + build_repo4 do + build_gem "racc", "1.8.1" + build_gem "mini_portile2", "2.8.2" + end + + build_lib "nokogiri", "1.18.9", path: lib_path("nokogiri") do |s| + s.add_dependency "mini_portile2", "~> 2.8.2" + s.add_dependency "racc", "~> 1.4" + end + + gemfile <<~G + source "https://gem.repo4" + + gem "nokogiri", path: "#{lib_path("nokogiri")}" + G + + lockfile <<~L + PATH + remote: #{lib_path("nokogiri")} + specs: + nokogiri (1.18.9) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) + nokogiri (1.18.9-arm64-darwin) + racc (~> 1.4) + + GEM + remote: https://rubygems.org/ + specs: + racc (1.8.1) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + nokogiri! + + BUNDLED WITH + #{Bundler::VERSION} + L + end + + it "works" do + bundle "install" + end + end + describe "switching sources" do it "doesn't switch pinned git sources to rubygems when pinning the parent gem to a path source" do build_gem "foo", "1.0", to_system: true do |s| diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index 62540f0488de62..09ed9a4faaa7c8 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -336,7 +336,6 @@ #{Bundler::VERSION} L - bundle "config set --local cache_all true" bundle "cache --all-platforms" expect(err).to be_empty diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb index 6b98e0924e41d8..4b767c7415b656 100644 --- a/spec/bundler/lock/lockfile_spec.rb +++ b/spec/bundler/lock/lockfile_spec.rb @@ -786,7 +786,6 @@ c.no_checksum "foo", "1.0" end - bundle "config set cache_all true" bundle :cache bundle :install, local: true diff --git a/spec/bundler/other/major_deprecation_spec.rb b/spec/bundler/other/major_deprecation_spec.rb index 1749d7e6827eaf..6117ff61374845 100644 --- a/spec/bundler/other/major_deprecation_spec.rb +++ b/spec/bundler/other/major_deprecation_spec.rb @@ -647,14 +647,12 @@ context "with --outdated flag" do before do - bundle "show --outdated" + bundle "show --outdated", raise_on_error: false end - it "prints a deprecation warning informing about its removal" do - expect(deprecations).to include("the `--outdated` flag to `bundle show` will be removed in favor of `bundle show --verbose`") + it "fails with a helpful message" do + expect(err).to include("the `--outdated` flag to `bundle show` has been removed in favor of `bundle show --verbose`") end - - pending "fails with a helpful message", bundler: "4" end end @@ -702,14 +700,11 @@ end end - it "prints a deprecation warning" do - bundle "plugin install foo --local_git #{lib_path("foo-1.0")}" + it "fails with a helpful message" do + bundle "plugin install foo --local_git #{lib_path("foo-1.0")}", raise_on_error: false - expect(out).to include("Installed plugin foo") - expect(deprecations).to include "--local_git is deprecated, use --git" + expect(err).to include "--local_git has been removed, use --git" end - - pending "fails with a helpful message", bundler: "4" end describe "removing rubocop" do @@ -740,4 +735,16 @@ end end end + + context " bundle gem --ext parameter with no value" do + it "prints error when used before gem name" do + bundle "gem --ext foo", raise_on_error: false + expect(err).to include "Extensions can now be generated using C or Rust, so `--ext` with no arguments has been removed. Please select a language, e.g. `--ext=rust` to generate a Rust extension." + end + + it "prints error when used after gem name" do + bundle "gem foo --ext", raise_on_error: false + expect(err).to include "Extensions can now be generated using C or Rust, so `--ext` with no arguments has been removed. Please select a language, e.g. `--ext=rust` to generate a Rust extension." + end + end end diff --git a/spec/bundler/plugins/install_spec.rb b/spec/bundler/plugins/install_spec.rb index 1ccefabc0b50a9..0cddeb09185bc7 100644 --- a/spec/bundler/plugins/install_spec.rb +++ b/spec/bundler/plugins/install_spec.rb @@ -203,13 +203,6 @@ def exec(command, args) expect(out).to include("Installed plugin foo") plugin_should_be_installed("foo") end - - it "raises an error when both git and local git sources are specified" do - bundle "plugin install foo --git /phony/path/project --local_git git@gitphony.com:/repo/project", raise_on_error: false - - expect(exitstatus).not_to eq(0) - expect(err).to eq("Remote and local plugin git sources can't be both specified") - end end context "path plugins" do diff --git a/spec/bundler/plugins/source/example_spec.rb b/spec/bundler/plugins/source/example_spec.rb index f9624463144ab4..da64886f01d224 100644 --- a/spec/bundler/plugins/source/example_spec.rb +++ b/spec/bundler/plugins/source/example_spec.rb @@ -124,7 +124,6 @@ def install(spec, opts) let(:uri_hash) { Digest(:SHA1).hexdigest(lib_path("a-path-gem-1.0").to_s) } it "copies repository to vendor cache and uses it" do bundle "install" - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist @@ -138,7 +137,6 @@ def install(spec, opts) it "copies repository to vendor cache and uses it even when installed with `path` configured" do bundle "config set --local path vendor/bundle" bundle :install - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist @@ -150,7 +148,6 @@ def install(spec, opts) it "bundler package copies repository to vendor cache" do bundle "config set --local path vendor/bundle" bundle :install - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist @@ -446,7 +443,6 @@ def installed? end G - bundle "config set cache_all true" bundle :cache expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.git")).not_to exist diff --git a/spec/bundler/support/checksums.rb b/spec/bundler/support/checksums.rb index 8e0dea4a717f96..cf8ea417d67adb 100644 --- a/spec/bundler/support/checksums.rb +++ b/spec/bundler/support/checksums.rb @@ -58,7 +58,7 @@ def checksums_section_when_enabled(target_lockfile = nil, &block) begin enabled = (target_lockfile || lockfile).match?(/^CHECKSUMS$/) rescue Errno::ENOENT - enabled = Bundler.feature_flag.bundler_4_mode? + enabled = true end checksums_section(enabled, &block) end diff --git a/test/json/json_coder_test.rb b/test/json/json_coder_test.rb index fc4aba296858ae..c7248353769969 100755 --- a/test/json/json_coder_test.rb +++ b/test/json/json_coder_test.rb @@ -12,7 +12,8 @@ def test_json_coder_with_proc end def test_json_coder_with_proc_with_unsupported_value - coder = JSON::Coder.new do |object| + coder = JSON::Coder.new do |object, is_key| + assert_equal false, is_key Object.new end assert_raise(JSON::GeneratorError) { coder.dump([Object.new]) } @@ -20,7 +21,10 @@ def test_json_coder_with_proc_with_unsupported_value def test_json_coder_hash_key obj = Object.new - coder = JSON::Coder.new(&:to_s) + coder = JSON::Coder.new do |obj, is_key| + assert_equal true, is_key + obj.to_s + end assert_equal %({#{obj.to_s.inspect}:1}), coder.dump({ obj => 1 }) coder = JSON::Coder.new { 42 } @@ -49,14 +53,14 @@ def test_json_coder_load_options end def test_json_coder_dump_NaN_or_Infinity - coder = JSON::Coder.new(&:inspect) + coder = JSON::Coder.new { |o| o.inspect } assert_equal "NaN", coder.load(coder.dump(Float::NAN)) assert_equal "Infinity", coder.load(coder.dump(Float::INFINITY)) assert_equal "-Infinity", coder.load(coder.dump(-Float::INFINITY)) end def test_json_coder_dump_NaN_or_Infinity_loop - coder = JSON::Coder.new(&:itself) + coder = JSON::Coder.new { |o| o.itself } error = assert_raise JSON::GeneratorError do coder.dump(Float::NAN) end diff --git a/test/json/json_encoding_test.rb b/test/json/json_encoding_test.rb index caf335d521f994..8dce81da590e76 100644 --- a/test/json/json_encoding_test.rb +++ b/test/json/json_encoding_test.rb @@ -31,6 +31,12 @@ def test_generate assert_equal @generated, JSON.generate(@utf_16_data, ascii_only: true) end + def test_generate_shared_string + # Ref: https://github.com/ruby/json/issues/859 + s = "01234567890" + assert_equal '"234567890"', JSON.dump(s[2..-1]) + end + def test_unicode assert_equal '""', ''.to_json assert_equal '"\\b"', "\b".to_json diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb index 6b42de2ad29abe..a6950f88878db8 100755 --- a/test/json/json_generator_test.rb +++ b/test/json/json_generator_test.rb @@ -822,29 +822,44 @@ def test_fragment def test_json_generate_as_json_convert_to_proc object = Object.new - assert_equal object.object_id.to_json, JSON.generate(object, strict: true, as_json: :object_id) + assert_equal object.object_id.to_json, JSON.generate(object, strict: true, as_json: -> (o, is_key) { o.object_id }) end - def test_json_generate_float - values = [-1.0, 1.0, 0.0, 12.2, 7.5 / 3.2, 12.0, 100.0, 1000.0] - expecteds = ["-1.0", "1.0", "0.0", "12.2", "2.34375", "12.0", "100.0", "1000.0"] - - if RUBY_ENGINE == "jruby" - values << 1746861937.7842371 - expecteds << "1.7468619377842371E9" - else - values << 1746861937.7842371 - expecteds << "1746861937.7842371" - end - - if RUBY_ENGINE == "ruby" - values << -2.2471348024634545e-08 << -2.2471348024634545e-09 << -2.2471348024634545e-10 - expecteds << "-0.000000022471348024634545" << "-0.0000000022471348024634545" << "-2.2471348024634546e-10" - end + def assert_float_roundtrip(expected, actual) + assert_equal(expected, JSON.generate(actual)) + assert_equal(actual, JSON.parse(JSON.generate(actual)), "JSON: #{JSON.generate(actual)}") + end - values.zip(expecteds).each do |value, expected| - assert_equal expected, value.to_json - end + def test_json_generate_float + assert_float_roundtrip "-1.0", -1.0 + assert_float_roundtrip "1.0", 1.0 + assert_float_roundtrip "0.0", 0.0 + assert_float_roundtrip "12.2", 12.2 + assert_float_roundtrip "2.34375", 7.5 / 3.2 + assert_float_roundtrip "12.0", 12.0 + assert_float_roundtrip "100.0", 100.0 + assert_float_roundtrip "1000.0", 1000.0 + + if RUBY_ENGINE == "jruby" + assert_float_roundtrip "1.7468619377842371E9", 1746861937.7842371 + else + assert_float_roundtrip "1746861937.7842371", 1746861937.7842371 + end + + if RUBY_ENGINE == "ruby" + assert_float_roundtrip "100000000000000.0", 100000000000000.0 + assert_float_roundtrip "1e+15", 1e+15 + assert_float_roundtrip "-100000000000000.0", -100000000000000.0 + assert_float_roundtrip "-1e+15", -1e+15 + assert_float_roundtrip "1111111111111111.1", 1111111111111111.1 + assert_float_roundtrip "1.1111111111111112e+16", 11111111111111111.1 + assert_float_roundtrip "-1111111111111111.1", -1111111111111111.1 + assert_float_roundtrip "-1.1111111111111112e+16", -11111111111111111.1 + + assert_float_roundtrip "-0.000000022471348024634545", -2.2471348024634545e-08 + assert_float_roundtrip "-0.0000000022471348024634545", -2.2471348024634545e-09 + assert_float_roundtrip "-2.2471348024634546e-10", -2.2471348024634545e-10 + end end def test_numbers_of_various_sizes diff --git a/test/json/json_parser_test.rb b/test/json/json_parser_test.rb index a9b0624f6bab58..9d387cb808925a 100644 --- a/test/json/json_parser_test.rb +++ b/test/json/json_parser_test.rb @@ -319,6 +319,12 @@ def test_invalid_unicode_escape assert_raise(JSON::ParserError) { parse('"\u111___"') } end + def test_invalid_surogates + assert_raise(JSON::ParserError) { parse('"\\uD800"') } + assert_raise(JSON::ParserError) { parse('"\\uD800_________________"') } + assert_raise(JSON::ParserError) { parse('"\\uD800\\u0041"') } + end + def test_parse_big_integers json1 = JSON(orig = (1 << 31) - 1) assert_equal orig, parse(json1) diff --git a/test/json/test_helper.rb b/test/json/test_helper.rb index a788804ddeca4e..24cde4348cdbf7 100644 --- a/test/json/test_helper.rb +++ b/test/json/test_helper.rb @@ -1,14 +1,27 @@ $LOAD_PATH.unshift(File.expand_path('../../../ext', __FILE__), File.expand_path('../../../lib', __FILE__)) -require 'coverage' -Coverage.start +if ENV["JSON_COVERAGE"] + # This test helper is loaded inside Ruby's own test suite, so we try to not mess it up. + require 'coverage' + + branches_supported = Coverage.respond_to?(:supported?) && Coverage.supported?(:branches) + + # Coverage module must be started before SimpleCov to work around the cyclic require order. + # Track both branches and lines, or else SimpleCov misleadingly reports 0/0 = 100% for non-branching files. + Coverage.start(lines: true, + branches: branches_supported) -begin require 'simplecov' -rescue LoadError - # Don't fail Ruby's test suite -else - SimpleCov.start + SimpleCov.start do + # Enabling both coverage types to let SimpleCov know to output them together in reports + enable_coverage :line + enable_coverage :branch if branches_supported + + # Can't always trust SimpleCov to find files implicitly + track_files 'lib/**/*.rb' + + add_filter 'lib/json/truffle_ruby' unless RUBY_ENGINE == 'truffleruby' + end end require 'json'