hashie 3.6.0 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +228 -174
  3. data/CONTRIBUTING.md +13 -6
  4. data/README.md +127 -15
  5. data/UPGRADING.md +83 -7
  6. data/hashie.gemspec +13 -7
  7. data/lib/hashie.rb +21 -19
  8. data/lib/hashie/dash.rb +2 -1
  9. data/lib/hashie/extensions/active_support/core_ext/hash.rb +14 -0
  10. data/lib/hashie/extensions/coercion.rb +23 -16
  11. data/lib/hashie/extensions/dash/indifferent_access.rb +20 -1
  12. data/lib/hashie/extensions/dash/property_translation.rb +6 -3
  13. data/lib/hashie/extensions/deep_fetch.rb +4 -2
  14. data/lib/hashie/extensions/deep_find.rb +12 -3
  15. data/lib/hashie/extensions/deep_locate.rb +22 -7
  16. data/lib/hashie/extensions/deep_merge.rb +18 -1
  17. data/lib/hashie/extensions/indifferent_access.rb +1 -3
  18. data/lib/hashie/extensions/key_conflict_warning.rb +55 -0
  19. data/lib/hashie/extensions/mash/define_accessors.rb +90 -0
  20. data/lib/hashie/extensions/mash/keep_original_keys.rb +2 -1
  21. data/lib/hashie/extensions/mash/permissive_respond_to.rb +61 -0
  22. data/lib/hashie/extensions/mash/safe_assignment.rb +3 -1
  23. data/lib/hashie/extensions/method_access.rb +5 -2
  24. data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +26 -4
  25. data/lib/hashie/extensions/ruby_version_check.rb +5 -1
  26. data/lib/hashie/extensions/strict_key_access.rb +8 -4
  27. data/lib/hashie/hash.rb +16 -9
  28. data/lib/hashie/mash.rb +114 -53
  29. data/lib/hashie/railtie.rb +7 -0
  30. data/lib/hashie/rash.rb +1 -1
  31. data/lib/hashie/utils.rb +28 -0
  32. data/lib/hashie/version.rb +1 -1
  33. metadata +19 -130
  34. data/spec/hashie/array_spec.rb +0 -29
  35. data/spec/hashie/clash_spec.rb +0 -70
  36. data/spec/hashie/dash_spec.rb +0 -598
  37. data/spec/hashie/extensions/autoload_spec.rb +0 -24
  38. data/spec/hashie/extensions/coercion_spec.rb +0 -639
  39. data/spec/hashie/extensions/dash/coercion_spec.rb +0 -13
  40. data/spec/hashie/extensions/dash/indifferent_access_spec.rb +0 -84
  41. data/spec/hashie/extensions/deep_fetch_spec.rb +0 -97
  42. data/spec/hashie/extensions/deep_find_spec.rb +0 -138
  43. data/spec/hashie/extensions/deep_locate_spec.rb +0 -137
  44. data/spec/hashie/extensions/deep_merge_spec.rb +0 -70
  45. data/spec/hashie/extensions/ignore_undeclared_spec.rb +0 -47
  46. data/spec/hashie/extensions/indifferent_access_spec.rb +0 -295
  47. data/spec/hashie/extensions/indifferent_access_with_rails_hwia_spec.rb +0 -208
  48. data/spec/hashie/extensions/key_conversion_spec.rb +0 -12
  49. data/spec/hashie/extensions/mash/keep_original_keys_spec.rb +0 -46
  50. data/spec/hashie/extensions/mash/safe_assignment_spec.rb +0 -50
  51. data/spec/hashie/extensions/mash/symbolize_keys_spec.rb +0 -39
  52. data/spec/hashie/extensions/merge_initializer_spec.rb +0 -23
  53. data/spec/hashie/extensions/method_access_spec.rb +0 -226
  54. data/spec/hashie/extensions/strict_key_access_spec.rb +0 -110
  55. data/spec/hashie/extensions/stringify_keys_spec.rb +0 -124
  56. data/spec/hashie/extensions/symbolize_keys_spec.rb +0 -129
  57. data/spec/hashie/hash_spec.rb +0 -84
  58. data/spec/hashie/mash_spec.rb +0 -771
  59. data/spec/hashie/parsers/yaml_erb_parser_spec.rb +0 -46
  60. data/spec/hashie/rash_spec.rb +0 -83
  61. data/spec/hashie/trash_spec.rb +0 -328
  62. data/spec/hashie/utils_spec.rb +0 -25
  63. data/spec/hashie/version_spec.rb +0 -7
  64. data/spec/hashie_spec.rb +0 -13
  65. data/spec/integration/elasticsearch/integration_spec.rb +0 -40
  66. data/spec/integration/omniauth-oauth2/app.rb +0 -52
  67. data/spec/integration/omniauth-oauth2/integration_spec.rb +0 -26
  68. data/spec/integration/omniauth-oauth2/some_site.rb +0 -38
  69. data/spec/integration/omniauth/app.rb +0 -11
  70. data/spec/integration/omniauth/integration_spec.rb +0 -38
  71. data/spec/integration/rails-without-dependency/integration_spec.rb +0 -15
  72. data/spec/integration/rails/app.rb +0 -47
  73. data/spec/integration/rails/integration_spec.rb +0 -26
  74. data/spec/spec_helper.rb +0 -23
  75. data/spec/support/integration_specs.rb +0 -36
  76. data/spec/support/logger.rb +0 -24
  77. data/spec/support/module_context.rb +0 -11
  78. data/spec/support/ruby_version_check.rb +0 -6
@@ -1,25 +0,0 @@
1
- require 'spec_helper'
2
-
3
- def a_method_to_match_against
4
- 'Hello world!'
5
- end
6
-
7
- RSpec.describe Hashie::Utils do
8
- describe '.method_information' do
9
- it 'states the module or class that a native method was defined in' do
10
- bound_method = method(:trust)
11
-
12
- message = Hashie::Utils.method_information(bound_method)
13
-
14
- expect(message).to match('Kernel')
15
- end
16
-
17
- it 'states the line a Ruby method was defined at' do
18
- bound_method = method(:a_method_to_match_against)
19
-
20
- message = Hashie::Utils.method_information(bound_method)
21
-
22
- expect(message).to match('spec/hashie/utils_spec.rb')
23
- end
24
- end
25
- end
@@ -1,7 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hashie do
4
- it 'has a version' do
5
- expect(Hashie::VERSION).not_to be_nil
6
- end
7
- end
data/spec/hashie_spec.rb DELETED
@@ -1,13 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe Hashie do
4
- describe '.logger' do
5
- include_context 'with a logger'
6
-
7
- it 'is available via an accessor' do
8
- Hashie.logger.info('Fee fi fo fum')
9
-
10
- expect(logger_output).to match('Fee fi fo fum')
11
- end
12
- end
13
- end
@@ -1,40 +0,0 @@
1
- require 'elasticsearch/model'
2
- require 'hashie'
3
-
4
- RSpec.configure do |config|
5
- config.expect_with :rspec do |expect|
6
- expect.syntax = :expect
7
- end
8
- end
9
-
10
- class MyModel < Hashie::Mash
11
- include Elasticsearch::Model
12
-
13
- disable_warnings
14
-
15
- index_name 'model'
16
- document_type 'model'
17
- end
18
-
19
- RSpec.describe 'elaasticsearch-model' do
20
- # See https://github.com/intridea/hashie/issues/354#issuecomment-363306114
21
- # for the reason why this doesn't work as you would expect
22
- it 'raises an error when the model does has an id' do
23
- object = MyModel.new
24
- stub_elasticsearch_client
25
-
26
- expect { object.__elasticsearch__.index_document }.to raise_error(NoMethodError)
27
- end
28
-
29
- it 'does not raise an error when the model has an id' do
30
- object = MyModel.new(id: 123)
31
- stub_elasticsearch_client
32
-
33
- expect { object.__elasticsearch__.index_document }.not_to raise_error
34
- end
35
-
36
- def stub_elasticsearch_client
37
- response = double('Response', body: '{}')
38
- allow_any_instance_of(Elasticsearch::Transport::Client).to receive(:perform_request) { response }
39
- end
40
- end
@@ -1,52 +0,0 @@
1
- require 'action_controller/railtie'
2
- require 'action_view/railtie'
3
- require 'action_view/testing/resolvers'
4
- require 'rails/test_unit/railtie'
5
- require_relative 'some_site'
6
-
7
- module RailsApp
8
- class Application < ::Rails::Application
9
- config.eager_load = false
10
- config.secret_key_base = 'hashieintegrationtest'
11
-
12
- config.middleware.use OmniAuth::Builder do
13
- provider :some_site
14
- end
15
-
16
- routes.append do
17
- get '/' => 'application#index'
18
- end
19
- end
20
- end
21
-
22
- LAYOUT = <<-HTML.freeze
23
- <!DOCTYPE html>
24
- <html>
25
- <head>
26
- <title>TestApp</title>
27
- <%= csrf_meta_tags %>
28
- </head>
29
- <body>
30
- <%= yield %>
31
- </body>
32
- </html>
33
- HTML
34
-
35
- INDEX = '<h1>Hello, world!</h1>'.freeze
36
-
37
- class ApplicationController < ActionController::Base
38
- include Rails.application.routes.url_helpers
39
-
40
- layout 'application'
41
-
42
- self.view_paths = [ActionView::FixtureResolver.new(
43
- 'layouts/application.html.erb' => LAYOUT,
44
- 'application/index.html.erb' => INDEX
45
- )]
46
-
47
- def index; end
48
- end
49
-
50
- Bundler.require(:default, Rails.env)
51
-
52
- RailsApp::Application.initialize!
@@ -1,26 +0,0 @@
1
- ENV['RAILS_ENV'] = 'test'
2
-
3
- require 'rspec/core'
4
-
5
- RSpec.describe 'omniauth-oauth2 inside of rails', type: :request do
6
- let(:stdout) { StringIO.new }
7
-
8
- around(:each) do |example|
9
- original_stdout = $stdout
10
- $stdout = stdout
11
- require_relative 'app'
12
- require 'rspec/rails'
13
- example.run
14
- $stdout = original_stdout
15
- end
16
-
17
- it 'does not log anything to STDOUT when initializing a Rails app and is set to Rails logger' do
18
- expect(stdout.string).to eq('')
19
- expect(Hashie.logger).to eq(Rails.logger)
20
- end
21
-
22
- it 'works' do
23
- get '/'
24
- assert_select 'h1', 'Hello, world!'
25
- end
26
- end
@@ -1,38 +0,0 @@
1
- require 'omniauth-oauth2'
2
-
3
- module OmniAuth
4
- module Strategies
5
- class SomeSite < OmniAuth::Strategies::OAuth2
6
- # Give your strategy a name.
7
- option :name, 'some_site'
8
-
9
- # This is where you pass the options you would pass when
10
- # initializing your consumer from the OAuth gem.
11
- option :client_options, site: 'https://api.somesite.com'
12
-
13
- # These are called after authentication has succeeded. If
14
- # possible, you should try to set the UID without making
15
- # additional calls (if the user id is returned with the token
16
- # or as a URI parameter). This may not be possible with all
17
- # providers.
18
- uid { raw_info['id'] }
19
-
20
- info do
21
- {
22
- name: raw_info['name'],
23
- email: raw_info['email']
24
- }
25
- end
26
-
27
- extra do
28
- {
29
- 'raw_info' => raw_info
30
- }
31
- end
32
-
33
- def raw_info
34
- @raw_info ||= access_token.get('/me').parsed
35
- end
36
- end
37
- end
38
- end
@@ -1,11 +0,0 @@
1
- require 'sinatra'
2
- require 'omniauth'
3
-
4
- class MyApplication < Sinatra::Base
5
- use Rack::Session::Cookie, secret: 'hashie integration tests'
6
- use OmniAuth::Strategies::Developer
7
-
8
- get '/' do
9
- 'Hello World'
10
- end
11
- end
@@ -1,38 +0,0 @@
1
- ENV['RACK_ENV'] = 'test'
2
-
3
- require 'rspec/core'
4
- require 'rack/test'
5
-
6
- RSpec.configure do |config|
7
- config.expect_with :rspec do |expect|
8
- expect.syntax = :expect
9
- end
10
- end
11
-
12
- RSpec.describe 'omniauth' do
13
- include Rack::Test::Methods
14
-
15
- def app
16
- MyApplication
17
- end
18
-
19
- let(:stdout) { StringIO.new }
20
-
21
- around(:each) do |example|
22
- original_stdout = $stdout
23
- $stdout = stdout
24
- require_relative 'app'
25
- example.run
26
- $stdout = original_stdout
27
- end
28
-
29
- it 'does not log anything to STDOUT when initializing' do
30
- expect(stdout.string).to eq('')
31
- end
32
-
33
- it 'works' do
34
- get '/'
35
- expect(last_response).to be_ok
36
- expect(last_response.body).to eq 'Hello World'
37
- end
38
- end
@@ -1,15 +0,0 @@
1
- require 'rspec/core'
2
-
3
- RSpec.describe 'partial-rails' do
4
- context 'when Rails constant is present but the railties are not' do
5
- before(:all) do
6
- class Rails
7
- # A class about railways
8
- end
9
- end
10
-
11
- it 'does not raise an exception when we require hashie' do
12
- expect { require 'hashie' }.not_to raise_error
13
- end
14
- end
15
- end
@@ -1,47 +0,0 @@
1
- require 'action_controller/railtie'
2
- require 'action_view/railtie'
3
- require 'action_view/testing/resolvers'
4
- require 'rails/test_unit/railtie'
5
-
6
- module RailsApp
7
- class Application < ::Rails::Application
8
- config.eager_load = false
9
- config.secret_key_base = 'hashieintegrationtest'
10
-
11
- routes.append do
12
- get '/' => 'application#index'
13
- end
14
- end
15
- end
16
-
17
- LAYOUT = <<-HTML.freeze
18
- <!DOCTYPE html>
19
- <html>
20
- <head>
21
- <title>TestApp</title>
22
- <%= csrf_meta_tags %>
23
- </head>
24
- <body>
25
- <%= yield %>
26
- </body>
27
- </html>
28
- HTML
29
-
30
- INDEX = '<h1>Hello, world!</h1>'.freeze
31
-
32
- class ApplicationController < ActionController::Base
33
- include Rails.application.routes.url_helpers
34
-
35
- layout 'application'
36
-
37
- self.view_paths = [ActionView::FixtureResolver.new(
38
- 'layouts/application.html.erb' => LAYOUT,
39
- 'application/index.html.erb' => INDEX
40
- )]
41
-
42
- def index; end
43
- end
44
-
45
- Bundler.require(:default, Rails.env)
46
-
47
- RailsApp::Application.initialize!
@@ -1,26 +0,0 @@
1
- ENV['RAILS_ENV'] = 'test'
2
-
3
- require 'rspec/core'
4
-
5
- RSpec.describe 'rails', type: :request do
6
- let(:stdout) { StringIO.new }
7
-
8
- around(:each) do |example|
9
- original_stdout = $stdout
10
- $stdout = stdout
11
- require_relative 'app'
12
- require 'rspec/rails'
13
- example.run
14
- $stdout = original_stdout
15
- end
16
-
17
- it 'does not log anything to STDOUT when initializing and sets the Hashie logger to the Rails logger' do
18
- expect(stdout.string).to eq('')
19
- expect(Hashie.logger).to eq(Rails.logger)
20
- end
21
-
22
- it 'works' do
23
- get '/'
24
- assert_select 'h1', 'Hello, world!'
25
- end
26
- end
data/spec/spec_helper.rb DELETED
@@ -1,23 +0,0 @@
1
- if ENV['CI']
2
- require 'simplecov'
3
- SimpleCov.start
4
- end
5
-
6
- require 'pry'
7
-
8
- require 'rspec'
9
- require 'hashie'
10
- require 'rspec/pending_for'
11
- require './spec/support/ruby_version_check'
12
- require './spec/support/logger'
13
-
14
- require 'active_support'
15
- require 'active_support/core_ext'
16
-
17
- RSpec.configure do |config|
18
- config.extend RubyVersionCheck
19
- config.expect_with :rspec do |expect|
20
- expect.syntax = :expect
21
- end
22
- config.warnings = true
23
- end
@@ -1,36 +0,0 @@
1
- # Generates the bundle command for running an integration test
2
- #
3
- # @param [String] integration the integration folder to run
4
- # @param [String] command the command to run
5
- # @return [String]
6
- def integration_command(integration, command)
7
- "#{integration_gemfile(integration)} #{command}"
8
- end
9
-
10
- # Generates the Gemfile for an integration
11
- #
12
- # @param [String] integration the integration test name
13
- # @return [String]
14
- def integration_gemfile(integration)
15
- "BUNDLE_GEMFILE=#{integration_path(integration)}/Gemfile"
16
- end
17
-
18
- # Generates the path to the integration
19
- #
20
- # @param [String] integration the integration test name
21
- # @return [String]
22
- def integration_path(integration)
23
- "spec/integration/#{integration}"
24
- end
25
-
26
- # Runs all integration specs in their own environment
27
- def run_all_integration_specs(handler: ->(_code) {}, logger: ->(_msg) {})
28
- Dir['spec/integration/*']
29
- .map { |directory| directory.split('/').last }
30
- .each do |integration|
31
- logger.call(%(Running "#{integration}" integration spec))
32
- system(integration_command(integration, 'bundle --quiet'))
33
- system(integration_command(integration, "bundle exec rspec #{integration_path(integration)}"))
34
- handler.call($CHILD_STATUS.exitstatus)
35
- end
36
- end
@@ -1,24 +0,0 @@
1
- # A shared context that allows you to check the output of Hashie's logger.
2
- #
3
- # @example
4
- # include_context 'with a logger'
5
- #
6
- # it 'logs info message' do
7
- # Hashie.logger.info 'What is happening in here?!'
8
- #
9
- # expect(logger_output).to match('What is happening in here?!')
10
- # end
11
- RSpec.shared_context 'with a logger' do
12
- # @private
13
- let(:log) { StringIO.new }
14
-
15
- # The output string from the logger
16
- let(:logger_output) { log.rewind && log.string }
17
-
18
- around(:each) do |example|
19
- original_logger = Hashie.logger
20
- Hashie.logger = Logger.new(log)
21
- example.run
22
- Hashie.logger = original_logger
23
- end
24
- end