summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Ball <tyleraball@gmail.com>2014-10-08 14:29:14 -0700
committerTyler Ball <tyleraball@gmail.com>2014-10-08 14:29:14 -0700
commit25930bc96580a94fc5ed84fd9d42b9ed9babebd4 (patch)
tree8717abdc2c5e3fee03ea6e1f6221b6a7279edc36
parent8f3fa042873a5c9c1dc55592446f1c36742b5708 (diff)
parenta349694218db2cb35ca2b4d14acdc6a92ba540da (diff)
downloadchef-25930bc96580a94fc5ed84fd9d42b9ed9babebd4.tar.gz
Merge pull request #2120 from opscode/tball/11-stable-yajl-replace-json
Chef 11 - Switch JSON dependency for ffi-yajl
-rw-r--r--CHANGELOG.md2
-rw-r--r--Gemfile2
-rw-r--r--chef.gemspec2
-rw-r--r--lib/chef/api_client.rb2
-rw-r--r--lib/chef/chef_fs/chef_fs_data_store.rb5
-rw-r--r--lib/chef/chef_fs/command_line.rb5
-rw-r--r--lib/chef/chef_fs/file_system/acl_entry.rb3
-rw-r--r--lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb3
-rw-r--r--lib/chef/chef_fs/file_system/rest_list_dir.rb5
-rw-r--r--lib/chef/chef_fs/file_system/rest_list_entry.rb9
-rw-r--r--lib/chef/config_fetcher.rb2
-rw-r--r--lib/chef/cookbook/cookbook_version_loader.rb8
-rw-r--r--lib/chef/cookbook/metadata.rb2
-rw-r--r--lib/chef/cookbook_version.rb4
-rw-r--r--lib/chef/data_bag.rb2
-rw-r--r--lib/chef/data_bag_item.rb2
-rw-r--r--lib/chef/encrypted_data_bag_item/decryptor.rb6
-rw-r--r--lib/chef/environment.rb2
-rw-r--r--lib/chef/exceptions.rb10
-rw-r--r--lib/chef/json_compat.rb109
-rw-r--r--lib/chef/knife/bootstrap.rb4
-rw-r--r--lib/chef/knife/bootstrap/archlinux-gems.erb4
-rw-r--r--lib/chef/knife/bootstrap/centos5-gems.erb4
-rw-r--r--lib/chef/knife/bootstrap/chef-aix.erb4
-rw-r--r--lib/chef/knife/bootstrap/chef-full.erb4
-rw-r--r--lib/chef/knife/bootstrap/fedora13-gems.erb4
-rw-r--r--lib/chef/knife/bootstrap/ubuntu10.04-apt.erb4
-rw-r--r--lib/chef/knife/bootstrap/ubuntu10.04-gems.erb4
-rw-r--r--lib/chef/knife/bootstrap/ubuntu12.04-gems.erb4
-rw-r--r--lib/chef/knife/cookbook_site_share.rb2
-rw-r--r--lib/chef/knife/deps.rb5
-rw-r--r--lib/chef/node.rb2
-rw-r--r--lib/chef/provider/deploy/revision.rb2
-rw-r--r--lib/chef/provider/remote_file/cache_control_data.rb2
-rw-r--r--lib/chef/resource.rb2
-rw-r--r--lib/chef/resource_collection.rb2
-rw-r--r--lib/chef/resource_reporter.rb6
-rw-r--r--lib/chef/role.rb2
-rw-r--r--lib/chef/run_list.rb2
-rw-r--r--lib/chef/user.rb2
-rw-r--r--lib/chef/util/powershell/cmdlet_result.rb4
-rw-r--r--spec/data/bootstrap/test-hints.erb2
-rw-r--r--spec/data/bootstrap/test.erb2
-rw-r--r--spec/functional/knife/cookbook_delete_spec.rb6
-rw-r--r--spec/functional/knife/exec_spec.rb2
-rw-r--r--spec/functional/util/powershell/cmdlet_spec.rb3
-rw-r--r--spec/integration/knife/chef_repo_path_spec.rb5
-rw-r--r--spec/integration/knife/diff_spec.rb4
-rw-r--r--spec/integration/knife/download_spec.rb4
-rw-r--r--spec/integration/knife/raw_spec.rb10
-rw-r--r--spec/integration/knife/upload_spec.rb16
-rw-r--r--spec/spec_helper.rb3
-rw-r--r--spec/support/shared/integration/integration_helper.rb3
-rw-r--r--spec/support/shared/shared_examples.rb10
-rw-r--r--spec/tiny_server.rb3
-rw-r--r--spec/unit/api_client_spec.rb6
-rw-r--r--spec/unit/config_fetcher_spec.rb2
-rw-r--r--spec/unit/cookbook/metadata_spec.rb10
-rw-r--r--spec/unit/cookbook_loader_spec.rb2
-rw-r--r--spec/unit/cookbook_version_spec.rb4
-rw-r--r--spec/unit/data_bag_item_spec.rb6
-rw-r--r--spec/unit/data_bag_spec.rb6
-rw-r--r--spec/unit/deprecation_spec.rb2
-rw-r--r--spec/unit/encrypted_data_bag_item_spec.rb21
-rw-r--r--spec/unit/environment_spec.rb10
-rw-r--r--spec/unit/exceptions_spec.rb6
-rw-r--r--spec/unit/json_compat_spec.rb75
-rw-r--r--spec/unit/knife/cookbook_metadata_from_file_spec.rb1
-rw-r--r--spec/unit/knife/cookbook_site_share_spec.rb8
-rw-r--r--spec/unit/knife/core/bootstrap_context_spec.rb4
-rw-r--r--spec/unit/knife/data_bag_from_file_spec.rb3
-rw-r--r--spec/unit/node_spec.rb4
-rw-r--r--spec/unit/provider/remote_file/cache_control_data_spec.rb2
-rw-r--r--spec/unit/resource_collection_spec.rb6
-rw-r--r--spec/unit/resource_reporter_spec.rb6
-rw-r--r--spec/unit/resource_spec.rb6
-rw-r--r--spec/unit/role_spec.rb4
-rw-r--r--spec/unit/run_list_spec.rb6
-rw-r--r--spec/unit/user_spec.rb6
79 files changed, 346 insertions, 187 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2ca56ff9b5..06e9157e09 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
## Unreleased:
+* Removed dependencies on the 'json' gem, replaced with ffi-yajl. Use Chef::JSONCompat library for parsing and printing.
+
## Last Release: 11.16.4
* Windows omnibus installer security updates for redistributed bash.exe / sh.exe
diff --git a/Gemfile b/Gemfile
index 1418235ebc..b298b396e0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -2,6 +2,8 @@ source "https://rubygems.org"
gemspec :name => "chef"
gem "activesupport", "< 4.0.0", :group => :compat_testing, :platform => "ruby"
+# TODO remove this when next version of ffi-yajl is released including this change
+gem "ffi-yajl", :github => 'tyler-ball/ffi-yajl', :branch => 'tball/remove_to_json'
group(:docgen) do
gem "yard"
diff --git a/chef.gemspec b/chef.gemspec
index 7c53618a51..7e9dc257b2 100644
--- a/chef.gemspec
+++ b/chef.gemspec
@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
# it's the version I had when I tested.
s.add_dependency "mime-types", "~> 1.16"
- s.add_dependency "ffi-yajl", "~> 1.0"
+ s.add_dependency "ffi-yajl", "~> 1.1"
s.add_dependency "net-ssh", "~> 2.6"
s.add_dependency "net-ssh-multi", "~> 1.1"
# CHEF-3027: The knife-cloud plugins require newer features from highline, core chef should not.
diff --git a/lib/chef/api_client.rb b/lib/chef/api_client.rb
index 7b7fd99ff7..334fb23f38 100644
--- a/lib/chef/api_client.rb
+++ b/lib/chef/api_client.rb
@@ -121,7 +121,7 @@ class Chef
#
# @return [String] the JSON string.
def to_json(*a)
- to_hash.to_json(*a)
+ Chef::JSONCompat.to_json(to_hash, *a)
end
def self.json_create(o)
diff --git a/lib/chef/chef_fs/chef_fs_data_store.rb b/lib/chef/chef_fs/chef_fs_data_store.rb
index b84fc1945d..a88bf0c256 100644
--- a/lib/chef/chef_fs/chef_fs_data_store.rb
+++ b/lib/chef/chef_fs/chef_fs_data_store.rb
@@ -23,6 +23,7 @@ require 'chef/chef_fs/file_pattern'
require 'chef/chef_fs/file_system'
require 'chef/chef_fs/file_system/not_found_error'
require 'chef/chef_fs/file_system/memory_root'
+require 'chef/json_compat'
require 'fileutils'
class Chef
@@ -114,7 +115,7 @@ class Chef
end
end
end
- JSON.pretty_generate(result)
+ Chef::JSONCompat.to_json_pretty(result)
else
begin
@@ -269,7 +270,7 @@ class Chef
# Create a little Chef::ChefFS memory filesystem with the data
cookbook_fs = Chef::ChefFS::FileSystem::MemoryRoot.new('uploading')
- cookbook = JSON.parse(data, :create_additions => false)
+ cookbook = Chef::JSONCompat.parse(data, :create_additions => false)
cookbook.each_pair do |key, value|
if value.is_a?(Array)
value.each do |file|
diff --git a/lib/chef/chef_fs/command_line.rb b/lib/chef/chef_fs/command_line.rb
index 967c59ecae..5fa770089b 100644
--- a/lib/chef/chef_fs/command_line.rb
+++ b/lib/chef/chef_fs/command_line.rb
@@ -19,6 +19,7 @@
require 'chef/chef_fs/file_system'
require 'chef/chef_fs/file_system/operation_failed_error'
require 'chef/chef_fs/file_system/operation_not_allowed_error'
+require 'chef/json_compat'
require 'chef/util/diff'
class Chef
@@ -251,9 +252,9 @@ class Chef
end
def self.canonicalize_json(json_text)
- parsed_json = JSON.parse(json_text, :create_additions => false)
+ parsed_json = Chef::JSONCompat.parse(json_text, :create_additions => false)
sorted_json = sort_keys(parsed_json)
- JSON.pretty_generate(sorted_json)
+ Chef::JSONCompat.to_json_pretty(sorted_json)
end
def self.diff_text(old_path, new_path, old_value, new_value)
diff --git a/lib/chef/chef_fs/file_system/acl_entry.rb b/lib/chef/chef_fs/file_system/acl_entry.rb
index 8edc02d5c5..1659b557ba 100644
--- a/lib/chef/chef_fs/file_system/acl_entry.rb
+++ b/lib/chef/chef_fs/file_system/acl_entry.rb
@@ -20,6 +20,7 @@ require 'chef/chef_fs/file_system/rest_list_entry'
require 'chef/chef_fs/file_system/not_found_error'
require 'chef/chef_fs/file_system/operation_not_allowed_error'
require 'chef/chef_fs/file_system/operation_failed_error'
+require 'chef/json_compat'
class Chef
module ChefFS
@@ -37,7 +38,7 @@ class Chef
def write(file_contents)
# ACL writes are fun.
- acls = data_handler.normalize(JSON.parse(file_contents, :create_additions => false), self)
+ acls = data_handler.normalize(Chef::JSONCompat.parse(file_contents, :create_additions => false), self)
PERMISSIONS.each do |permission|
begin
rest.put("#{api_path}/#{permission}", { permission => acls[permission] })
diff --git a/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb b/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb
index 3d3f58201e..d22d11b0f3 100644
--- a/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb
+++ b/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb
@@ -19,6 +19,7 @@
require 'chef/chef_fs/file_system/file_system_entry'
require 'chef/chef_fs/file_system/not_found_error'
+require 'chef/json_compat'
class Chef
module ChefFS
@@ -41,7 +42,7 @@ class Chef
def chef_object
begin
- return data_handler.chef_object(JSON.parse(read, :create_additions => false))
+ return data_handler.chef_object(Chef::JSONCompat.parse(read, :create_additions => false))
rescue
Chef::Log.error("Could not read #{path_for_printing} into a Chef object: #{$!}")
end
diff --git a/lib/chef/chef_fs/file_system/rest_list_dir.rb b/lib/chef/chef_fs/file_system/rest_list_dir.rb
index b7ee51d284..273caa3478 100644
--- a/lib/chef/chef_fs/file_system/rest_list_dir.rb
+++ b/lib/chef/chef_fs/file_system/rest_list_dir.rb
@@ -19,6 +19,7 @@
require 'chef/chef_fs/file_system/base_fs_dir'
require 'chef/chef_fs/file_system/rest_list_entry'
require 'chef/chef_fs/file_system/not_found_error'
+require 'chef/json_compat'
class Chef
module ChefFS
@@ -61,8 +62,8 @@ class Chef
def create_child(name, file_contents)
begin
- object = JSON.parse(file_contents, :create_additions => false)
- rescue JSON::ParserError => e
+ object = Chef::JSONCompat.parse(file_contents, :create_additions => false)
+ rescue Chef::Exceptions::JSON::ParseError => e
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:create_child, self, e), "Parse error reading JSON creating child '#{name}': #{e}"
end
diff --git a/lib/chef/chef_fs/file_system/rest_list_entry.rb b/lib/chef/chef_fs/file_system/rest_list_entry.rb
index 0d5557de1d..345fab63be 100644
--- a/lib/chef/chef_fs/file_system/rest_list_entry.rb
+++ b/lib/chef/chef_fs/file_system/rest_list_entry.rb
@@ -19,6 +19,7 @@
require 'chef/chef_fs/file_system/base_fs_object'
require 'chef/chef_fs/file_system/not_found_error'
require 'chef/chef_fs/file_system/operation_failed_error'
+require 'chef/json_compat'
require 'chef/role'
require 'chef/node'
@@ -128,8 +129,8 @@ class Chef
value = minimize_value(value)
value_json = Chef::JSONCompat.to_json_pretty(value)
begin
- other_value = JSON.parse(other_value_json, :create_additions => false)
- rescue JSON::ParserError => e
+ other_value = Chef::JSONCompat.parse(other_value_json, :create_additions => false)
+ rescue Chef::Exceptions::JSON::ParseError => e
Chef::Log.warn("Parse error reading #{other.path_for_printing} as JSON: #{e}")
return [ nil, value_json, other_value_json ]
end
@@ -145,8 +146,8 @@ class Chef
def write(file_contents)
begin
- object = JSON.parse(file_contents, :create_additions => false)
- rescue JSON::ParserError => e
+ object = Chef::JSONCompat.parse(file_contents, :create_additions => false)
+ rescue Chef::Exceptions::JSON::ParseError => e
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:write, self, e), "Parse error reading JSON: #{e}"
end
diff --git a/lib/chef/config_fetcher.rb b/lib/chef/config_fetcher.rb
index c1fd262656..1d0693eaa2 100644
--- a/lib/chef/config_fetcher.rb
+++ b/lib/chef/config_fetcher.rb
@@ -18,7 +18,7 @@ class Chef
config_data = read_config
begin
Chef::JSONCompat.from_json(config_data)
- rescue FFI_Yajl::ParseError => error
+ rescue Chef::Exceptions::JSON::ParseError => error
Chef::Application.fatal!("Could not parse the provided JSON file (#{config_location}): " + error.message, 2)
end
end
diff --git a/lib/chef/cookbook/cookbook_version_loader.rb b/lib/chef/cookbook/cookbook_version_loader.rb
index 4e92b74ae9..fac8c80993 100644
--- a/lib/chef/cookbook/cookbook_version_loader.rb
+++ b/lib/chef/cookbook/cookbook_version_loader.rb
@@ -170,7 +170,7 @@ class Chef
def apply_ruby_metadata(file)
begin
@metadata.from_file(file)
- rescue JSON::ParserError
+ rescue Chef::Exceptions::JSON::ParseError
Chef::Log.error("Error evaluating metadata.rb for #@cookbook_name in " + file)
raise
end
@@ -179,7 +179,7 @@ class Chef
def apply_json_metadata(file)
begin
@metadata.from_json(IO.read(file))
- rescue JSON::ParserError
+ rescue Chef::Exceptions::JSON::ParseError
Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in " + file)
raise
end
@@ -189,7 +189,7 @@ class Chef
begin
data = Chef::JSONCompat.from_json(IO.read(file), :create_additions => false)
@metadata.from_hash(data['metadata'])
- rescue JSON::ParserError
+ rescue Chef::Exceptions::JSON::ParseError
Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in " + file)
raise
end
@@ -200,7 +200,7 @@ class Chef
begin
data = Chef::JSONCompat.from_json(IO.read(uploaded_cookbook_version_file), :create_additions => false)
@frozen = data['frozen?']
- rescue JSON::ParserError
+ rescue Chef::Exceptions::JSON::ParseError
Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in #{uploaded_cookbook_version_file}")
raise
end
diff --git a/lib/chef/cookbook/metadata.rb b/lib/chef/cookbook/metadata.rb
index 7da1ae70de..21ab72e1cd 100644
--- a/lib/chef/cookbook/metadata.rb
+++ b/lib/chef/cookbook/metadata.rb
@@ -441,7 +441,7 @@ class Chef
end
def to_json(*a)
- self.to_hash.to_json(*a)
+ Chef::JSONCompat.to_json(self.to_hash, *a)
end
def self.from_hash(o)
diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb
index 3d8b9fb908..f9775c4d8d 100644
--- a/lib/chef/cookbook_version.rb
+++ b/lib/chef/cookbook_version.rb
@@ -459,7 +459,7 @@ class Chef
def to_json(*a)
result = self.to_hash
result['json_class'] = self.class.name
- result.to_json(*a)
+ Chef::JSONCompat.to_json(result, *a)
end
def self.json_create(o)
@@ -469,7 +469,7 @@ class Chef
cookbook_version.manifest = o
# We don't need the following step when we decide to stop supporting deprecated operators in the metadata (e.g. <<, >>)
- cookbook_version.manifest["metadata"] = Chef::JSONCompat.from_json(cookbook_version.metadata.to_json)
+ cookbook_version.manifest["metadata"] = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(cookbook_version.metadata))
cookbook_version.freeze_version if o["frozen?"]
cookbook_version
diff --git a/lib/chef/data_bag.rb b/lib/chef/data_bag.rb
index 639d71a74d..f50aa93d2d 100644
--- a/lib/chef/data_bag.rb
+++ b/lib/chef/data_bag.rb
@@ -63,7 +63,7 @@ class Chef
# Serialize this object as a hash
def to_json(*a)
- to_hash.to_json(*a)
+ Chef::JSONCompat.to_json(to_hash, *a)
end
def chef_server_rest
diff --git a/lib/chef/data_bag_item.rb b/lib/chef/data_bag_item.rb
index 07dd15a1dc..3772f9ea1c 100644
--- a/lib/chef/data_bag_item.rb
+++ b/lib/chef/data_bag_item.rb
@@ -118,7 +118,7 @@ class Chef
"data_bag" => self.data_bag,
"raw_data" => self.raw_data
}
- result.to_json(*a)
+ Chef::JSONCompat.to_json(result, *a)
end
def self.from_hash(h)
diff --git a/lib/chef/encrypted_data_bag_item/decryptor.rb b/lib/chef/encrypted_data_bag_item/decryptor.rb
index 69b8d62e3b..503a8f3099 100644
--- a/lib/chef/encrypted_data_bag_item/decryptor.rb
+++ b/lib/chef/encrypted_data_bag_item/decryptor.rb
@@ -17,10 +17,10 @@
#
require 'yaml'
-require 'ffi_yajl'
require 'openssl'
require 'base64'
require 'digest/sha2'
+require 'chef/json_compat'
require 'chef/encrypted_data_bag_item'
require 'chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format'
require 'chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format'
@@ -121,8 +121,8 @@ class Chef::EncryptedDataBagItem
end
def for_decrypted_item
- FFI_Yajl::Parser.parse(decrypted_data)["json_wrapper"]
- rescue FFI_Yajl::ParseError
+ Chef::JSONCompat.parse(decrypted_data)["json_wrapper"]
+ rescue Chef::Exceptions::JSON::ParseError
# convert to a DecryptionFailure error because the most likely scenario
# here is that the decryption step was unsuccessful but returned bad
# data rather than raising an error.
diff --git a/lib/chef/environment.rb b/lib/chef/environment.rb
index 5c719ca285..3620ee0b7c 100644
--- a/lib/chef/environment.rb
+++ b/lib/chef/environment.rb
@@ -129,7 +129,7 @@ class Chef
end
def to_json(*a)
- to_hash.to_json(*a)
+ Chef::JSONCompat.to_json(to_hash, *a)
end
def update_from!(o)
diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb
index 9ea40f71f6..2e7a92ab6f 100644
--- a/lib/chef/exceptions.rb
+++ b/lib/chef/exceptions.rb
@@ -267,7 +267,7 @@ class Chef
"non_existent_cookbooks" => non_existent_cookbooks,
"cookbooks_with_no_versions" => cookbooks_with_no_matching_versions
}
- result.to_json(*a)
+ Chef::JSONCompat.to_json(result, *a)
end
end
@@ -302,7 +302,7 @@ class Chef
"non_existent_cookbooks" => non_existent_cookbooks,
"most_constrained_cookbooks" => most_constrained_cookbooks
}
- result.to_json(*a)
+ Chef::JSONCompat.to_json(result, *a)
end
end
@@ -337,5 +337,11 @@ class Chef
end
class BadProxyURI < RuntimeError; end
+
+ # Raised by Chef::JSONCompat
+ class JSON
+ class EncodeError < RuntimeError; end
+ class ParseError < RuntimeError; end
+ end
end
end
diff --git a/lib/chef/json_compat.rb b/lib/chef/json_compat.rb
index 2dbb607d9b..9db358b5b9 100644
--- a/lib/chef/json_compat.rb
+++ b/lib/chef/json_compat.rb
@@ -18,7 +18,9 @@
# Wrapper class for interacting with JSON.
require 'ffi_yajl'
-require 'ffi_yajl/json_gem' # XXX: parts of chef require JSON gem's Hash#to_json monkeypatch
+require 'chef/exceptions'
+# We're requiring this to prevent breaking consumers using Hash.to_json
+require 'json'
class Chef
class JSONCompat
@@ -40,15 +42,24 @@ class Chef
class <<self
+ # API to use to avoid create_addtions
+ def parse(source, opts = {})
+ begin
+ FFI_Yajl::Parser.parse(source, opts)
+ rescue FFI_Yajl::ParseError => e
+ raise Chef::Exceptions::JSON::ParseError, e.message
+ end
+ end
+
# Just call the JSON gem's parse method with a modified :max_nesting field
def from_json(source, opts = {})
- obj = ::FFI_Yajl::Parser.parse(source)
+ obj = parse(source, opts)
# JSON gem requires top level object to be a Hash or Array (otherwise
# you get the "must contain two octets" error). Yajl doesn't impose the
# same limitation. For compatibility, we re-impose this condition.
unless obj.kind_of?(Hash) or obj.kind_of?(Array)
- raise JSON::ParserError, "Top level JSON object must be a Hash or Array. (actual: #{obj.class})"
+ raise Chef::Exceptions::JSON::ParseError, "Top level JSON object must be a Hash or Array. (actual: #{obj.class})"
end
# The old default in the json gem (which we are mimicing because we
@@ -66,17 +77,17 @@ class Chef
# to an instance of Chef classes if desired.
def map_to_rb_obj(json_obj)
case json_obj
- when Hash
- mapped_hash = map_hash_to_rb_obj(json_obj)
- if json_obj.has_key?(JSON_CLASS) && (class_to_inflate = class_for_json_class(json_obj[JSON_CLASS]))
- class_to_inflate.json_create(mapped_hash)
+ when Hash
+ mapped_hash = map_hash_to_rb_obj(json_obj)
+ if json_obj.has_key?(JSON_CLASS) && (class_to_inflate = class_for_json_class(json_obj[JSON_CLASS]))
+ class_to_inflate.json_create(mapped_hash)
+ else
+ mapped_hash
+ end
+ when Array
+ json_obj.map {|e| map_to_rb_obj(e) }
else
- mapped_hash
- end
- when Array
- json_obj.map {|e| map_to_rb_obj(e) }
- else
- json_obj
+ json_obj
end
end
@@ -88,52 +99,60 @@ class Chef
end
def to_json(obj, opts = nil)
- obj.to_json(opts)
+ begin
+ FFI_Yajl::Encoder.encode(obj, opts)
+ rescue FFI_Yajl::EncodeError => e
+ raise Chef::Exceptions::JSON::EncodeError, e.message
+ end
end
def to_json_pretty(obj, opts = nil)
- ::JSON.pretty_generate(obj, opts)
+ opts ||= {}
+ options_map = {}
+ options_map[:pretty] = true
+ options_map[:indent] = opts[:indent] if opts.has_key?(:indent)
+ to_json(obj, options_map).chomp
end
-
# Map +json_class+ to a Class object. We use a +case+ instead of a Hash
# assigned to a constant because otherwise this file could not be loaded
# until all the constants were defined, which means you'd have to load
# the world to get json, which would make knife very slow.
def class_for_json_class(json_class)
case json_class
- when CHEF_APICLIENT
- Chef::ApiClient
- when CHEF_CHECKSUM
- Chef::Checksum
- when CHEF_COOKBOOKVERSION
- Chef::CookbookVersion
- when CHEF_DATABAG
- Chef::DataBag
- when CHEF_DATABAGITEM
- Chef::DataBagItem
- when CHEF_ENVIRONMENT
- Chef::Environment
- when CHEF_NODE
- Chef::Node
- when CHEF_ROLE
- Chef::Role
- when CHEF_SANDBOX
- # a falsey return here will disable object inflation/"create
- # additions" in the caller. In Chef 11 this is correct, we just have
- # a dummy Chef::Sandbox class for compat with Chef 10 servers.
- false
- when CHEF_RESOURCE
- Chef::Resource
- when CHEF_RESOURCECOLLECTION
- Chef::ResourceCollection
- when /^Chef::Resource/
- Chef::Resource.find_subclass_by_name(json_class)
- else
- raise JSON::ParserError, "Unsupported `json_class` type '#{json_class}'"
+ when CHEF_APICLIENT
+ Chef::ApiClient
+ when CHEF_CHECKSUM
+ Chef::Checksum
+ when CHEF_COOKBOOKVERSION
+ Chef::CookbookVersion
+ when CHEF_DATABAG
+ Chef::DataBag
+ when CHEF_DATABAGITEM
+ Chef::DataBagItem
+ when CHEF_ENVIRONMENT
+ Chef::Environment
+ when CHEF_NODE
+ Chef::Node
+ when CHEF_ROLE
+ Chef::Role
+ when CHEF_SANDBOX
+ # a falsey return here will disable object inflation/"create
+ # additions" in the caller. In Chef 11 this is correct, we just have
+ # a dummy Chef::Sandbox class for compat with Chef 10 servers.
+ false
+ when CHEF_RESOURCE
+ Chef::Resource
+ when CHEF_RESOURCECOLLECTION
+ Chef::ResourceCollection
+ when /^Chef::Resource/
+ Chef::Resource.find_subclass_by_name(json_class)
+ else
+ raise Chef::Exceptions::JSON::ParseError, "Unsupported `json_class` type '#{json_class}'"
end
end
end
end
end
+
diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb
index 46cacbd3e0..d3d45bad4b 100644
--- a/lib/chef/knife/bootstrap.rb
+++ b/lib/chef/knife/bootstrap.rb
@@ -126,7 +126,7 @@ class Chef
:short => "-j JSON_ATTRIBS",
:long => "--json-attributes",
:description => "A JSON string to be added to the first run of chef-client",
- :proc => lambda { |o| JSON.parse(o) },
+ :proc => lambda { |o| Chef::JSONCompat.parse(o) },
:default => {}
option :host_key_verify,
@@ -141,7 +141,7 @@ class Chef
:proc => Proc.new { |h|
Chef::Config[:knife][:hints] ||= Hash.new
name, path = h.split("=")
- Chef::Config[:knife][:hints][name] = path ? JSON.parse(::File.read(path)) : Hash.new }
+ Chef::Config[:knife][:hints][name] = path ? Chef::JSONCompat.parse(::File.read(path)) : Hash.new }
option :secret,
:short => "-s SECRET",
diff --git a/lib/chef/knife/bootstrap/archlinux-gems.erb b/lib/chef/knife/bootstrap/archlinux-gems.erb
index ab2aa7a7f1..35133e23e5 100644
--- a/lib/chef/knife/bootstrap/archlinux-gems.erb
+++ b/lib/chef/knife/bootstrap/archlinux-gems.erb
@@ -29,7 +29,7 @@ mkdir -p /etc/chef/ohai/hints
<% @chef_config[:knife][:hints].each do |name, hash| -%>
cat > /etc/chef/ohai/hints/<%= name %>.json <<'EOP'
-<%= hash.to_json %>
+<%= Chef::JSONCompat.to_json(hash) %>
EOP
<% end -%>
<% end -%>
@@ -56,7 +56,7 @@ https_proxy "<%= knife_config[:bootstrap_proxy] %>"
EOP
cat > /etc/chef/first-boot.json <<'EOP'
-<%= first_boot.to_json %>
+<%= Chef::JSONCompat.to_json(first_boot) %>
EOP
<%= start_chef %>'
diff --git a/lib/chef/knife/bootstrap/centos5-gems.erb b/lib/chef/knife/bootstrap/centos5-gems.erb
index 6aacc47179..30418eca2d 100644
--- a/lib/chef/knife/bootstrap/centos5-gems.erb
+++ b/lib/chef/knife/bootstrap/centos5-gems.erb
@@ -46,7 +46,7 @@ mkdir -p /etc/chef/ohai/hints
<% @chef_config[:knife][:hints].each do |name, hash| -%>
cat > /etc/chef/ohai/hints/<%= name %>.json <<'EOP'
-<%= hash.to_json %>
+<%= Chef::JSONCompat.to_json(hash) %>
EOP
<% end -%>
<% end -%>
@@ -56,7 +56,7 @@ cat > /etc/chef/client.rb <<'EOP'
EOP
cat > /etc/chef/first-boot.json <<'EOP'
-<%= first_boot.to_json %>
+<%= Chef::JSONCompat.to_json(first_boot) %>
EOP
<%= start_chef %>'
diff --git a/lib/chef/knife/bootstrap/chef-aix.erb b/lib/chef/knife/bootstrap/chef-aix.erb
index 59993b478a..3985415d73 100644
--- a/lib/chef/knife/bootstrap/chef-aix.erb
+++ b/lib/chef/knife/bootstrap/chef-aix.erb
@@ -42,7 +42,7 @@ mkdir -p /etc/chef/ohai/hints
<% @chef_config[:knife][:hints].each do |name, hash| -%>
cat > /etc/chef/ohai/hints/<%= name %>.json <<'EOP'
-<%= hash.to_json %>
+<%= Chef::JSONCompat.to_json(hash) %>
EOP
<% end -%>
<% end -%>
@@ -52,7 +52,7 @@ cat > /etc/chef/client.rb <<'EOP'
EOP
cat > /etc/chef/first-boot.json <<'EOP'
-<%= first_boot.to_json %>
+<%= Chef::JSONCompat.to_json(first_boot) %>
EOP
<%= start_chef %>'
diff --git a/lib/chef/knife/bootstrap/chef-full.erb b/lib/chef/knife/bootstrap/chef-full.erb
index c953a7e433..cffe7007e9 100644
--- a/lib/chef/knife/bootstrap/chef-full.erb
+++ b/lib/chef/knife/bootstrap/chef-full.erb
@@ -57,7 +57,7 @@ mkdir -p /etc/chef/ohai/hints
<% @chef_config[:knife][:hints].each do |name, hash| -%>
cat > /etc/chef/ohai/hints/<%= name %>.json <<'EOP'
-<%= hash.to_json %>
+<%= Chef::JSONCompat.to_json(hash) %>
EOP
<% end -%>
<% end -%>
@@ -67,7 +67,7 @@ cat > /etc/chef/client.rb <<'EOP'
EOP
cat > /etc/chef/first-boot.json <<'EOP'
-<%= first_boot.to_json %>
+<%= Chef::JSONCompat.to_json(first_boot) %>
EOP
echo "Starting first Chef Client run..."
diff --git a/lib/chef/knife/bootstrap/fedora13-gems.erb b/lib/chef/knife/bootstrap/fedora13-gems.erb
index 0aabc31085..431d2bdb00 100644
--- a/lib/chef/knife/bootstrap/fedora13-gems.erb
+++ b/lib/chef/knife/bootstrap/fedora13-gems.erb
@@ -28,7 +28,7 @@ mkdir -p /etc/chef/ohai/hints
<% @chef_config[:knife][:hints].each do |name, hash| -%>
cat > /etc/chef/ohai/hints/<%= name %>.json <<'EOP'
-<%= hash.to_json %>
+<%= Chef::JSONCompat.to_json(hash) %>
EOP
<% end -%>
<% end -%>
@@ -38,7 +38,7 @@ cat > /etc/chef/client.rb <<'EOP'
EOP
cat > /etc/chef/first-boot.json <<'EOP'
-<%= first_boot.to_json %>
+<%= Chef::JSONCompat.to_json(first_boot) %>
EOP
<%= start_chef %>'
diff --git a/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb b/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb
index 4549b94d2b..d95de60149 100644
--- a/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb
+++ b/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb
@@ -28,7 +28,7 @@ mkdir -p /etc/chef/ohai/hints
<% @chef_config[:knife][:hints].each do |name, hash| -%>
cat > /etc/chef/ohai/hints/<%= name %>.json <<'EOP'
-<%= hash.to_json %>
+<%= Chef::JSONCompat.to_json(hash) %>
EOP
<% end -%>
<% end -%>
@@ -47,7 +47,7 @@ echo 'https_proxy "knife_config[:bootstrap_proxy]"' >> /etc/chef/client.rb
<% end -%>
cat > /etc/chef/first-boot.json <<'EOP'
-<%= first_boot.to_json %>
+<%= Chef::JSONCompat.to_json(first_boot) %>
EOP
<%= start_chef %>'
diff --git a/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb b/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb
index 62ff7c857e..8e41c8f059 100644
--- a/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb
+++ b/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb
@@ -32,7 +32,7 @@ mkdir -p /etc/chef/ohai/hints
<% @chef_config[:knife][:hints].each do |name, hash| -%>
cat > /etc/chef/ohai/hints/<%= name %>.json <<'EOP'
-<%= hash.to_json %>
+<%= Chef::JSONCompat.to_json(hash) %>
EOP
<% end -%>
<% end -%>
@@ -42,7 +42,7 @@ cat > /etc/chef/client.rb <<'EOP'
EOP
cat > /etc/chef/first-boot.json <<'EOP'
-<%= first_boot.to_json %>
+<%= Chef::JSONCompat.to_json(first_boot) %>
EOP
<%= start_chef %>'
diff --git a/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb b/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb
index 8e9c6583d0..b6a5aee7e7 100644
--- a/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb
+++ b/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb
@@ -30,7 +30,7 @@ mkdir -p /etc/chef/ohai/hints
<% @chef_config[:knife][:hints].each do |name, hash| -%>
cat > /etc/chef/ohai/hints/<%= name %>.json <<'EOP'
-<%= hash.to_json %>
+<%= Chef::JSONCompat.to_json(hash) %>
EOP
<% end -%>
<% end -%>
@@ -40,7 +40,7 @@ cat > /etc/chef/client.rb <<'EOP'
EOP
cat > /etc/chef/first-boot.json <<'EOP'
-<%= first_boot.to_json %>
+<%= Chef::JSONCompat.to_json(first_boot) %>
EOP
<%= start_chef %>'
diff --git a/lib/chef/knife/cookbook_site_share.rb b/lib/chef/knife/cookbook_site_share.rb
index 4dcce42d7f..2de0f9c5f3 100644
--- a/lib/chef/knife/cookbook_site_share.rb
+++ b/lib/chef/knife/cookbook_site_share.rb
@@ -87,7 +87,7 @@ class Chef
def do_upload(cookbook_filename, cookbook_category, user_id, user_secret_filename)
uri = "http://cookbooks.opscode.com/api/v1/cookbooks"
- category_string = { 'category'=>cookbook_category }.to_json
+ category_string = Chef::JSONCompat.to_json({ 'category'=>cookbook_category })
http_resp = Chef::CookbookSiteStreamingUploader.post(uri, user_id, user_secret_filename, {
:tarball => File.open(cookbook_filename),
diff --git a/lib/chef/knife/deps.rb b/lib/chef/knife/deps.rb
index b2a39a0725..89fd42124f 100644
--- a/lib/chef/knife/deps.rb
+++ b/lib/chef/knife/deps.rb
@@ -9,6 +9,7 @@ class Chef
deps do
require 'chef/chef_fs/file_system'
+ require 'chef/json_compat'
require 'chef/run_list'
end
@@ -77,7 +78,7 @@ class Chef
return entry.chef_object.metadata.dependencies.keys.map { |cookbook| "/cookbooks/#{cookbook}" }
elsif entry.parent && entry.parent.path == '/nodes'
- node = JSON.parse(entry.read, :create_additions => false)
+ node = Chef::JSONCompat.parse(entry.read, :create_additions => false)
result = []
if node['chef_environment'] && node['chef_environment'] != '_default'
result << "/environments/#{node['chef_environment']}.json"
@@ -88,7 +89,7 @@ class Chef
result
elsif entry.parent && entry.parent.path == '/roles'
- role = JSON.parse(entry.read, :create_additions => false)
+ role = Chef::JSONCompat.parse(entry.read, :create_additions => false)
result = []
if role['run_list']
dependencies_from_runlist(role['run_list']).each do |dependency|
diff --git a/lib/chef/node.rb b/lib/chef/node.rb
index 17ec1d0f0a..261c4a3f10 100644
--- a/lib/chef/node.rb
+++ b/lib/chef/node.rb
@@ -416,7 +416,7 @@ class Chef
# Serialize this object as a hash
def to_json(*a)
- for_json.to_json(*a)
+ Chef::JSONCompat.to_json(for_json, *a)
end
def for_json
diff --git a/lib/chef/provider/deploy/revision.rb b/lib/chef/provider/deploy/revision.rb
index f1eb171cd7..89710088d1 100644
--- a/lib/chef/provider/deploy/revision.rb
+++ b/lib/chef/provider/deploy/revision.rb
@@ -97,7 +97,7 @@ class Chef
end
def save_cache(cache)
- Chef::FileCache.store("revision-deploys/#{new_resource.name}", cache.to_json)
+ Chef::FileCache.store("revision-deploys/#{new_resource.name}", Chef::JSONCompat.to_json(cache))
cache
end
diff --git a/lib/chef/provider/remote_file/cache_control_data.rb b/lib/chef/provider/remote_file/cache_control_data.rb
index 0add74f50a..95b2bc6a1b 100644
--- a/lib/chef/provider/remote_file/cache_control_data.rb
+++ b/lib/chef/provider/remote_file/cache_control_data.rb
@@ -140,7 +140,7 @@ class Chef
def load_data
Chef::JSONCompat.from_json(load_json_data)
- rescue Chef::Exceptions::FileNotFound, FFI_Yajl::ParseError, JSON::ParserError
+ rescue Chef::Exceptions::FileNotFound, FFI_Yajl::ParseError, Chef::Exceptions::JSON::ParseError
false
end
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index f6283e4033..a112e3b463 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -544,7 +544,7 @@ F
# Serialize this object as a hash
def to_json(*a)
results = as_json
- results.to_json(*a)
+ Chef::JSONCompat.to_json(results, *a)
end
def to_hash
diff --git a/lib/chef/resource_collection.rb b/lib/chef/resource_collection.rb
index a528a18aed..3097707a13 100644
--- a/lib/chef/resource_collection.rb
+++ b/lib/chef/resource_collection.rb
@@ -198,7 +198,7 @@ class Chef
'json_class' => self.class.name,
'instance_vars' => instance_vars
}
- results.to_json(*a)
+ Chef::JSONCompat.to_json(results, *a)
end
def self.json_create(o)
diff --git a/lib/chef/resource_reporter.rb b/lib/chef/resource_reporter.rb
index 046e4e82c6..a19f26125e 100644
--- a/lib/chef/resource_reporter.rb
+++ b/lib/chef/resource_reporter.rb
@@ -230,7 +230,7 @@ class Chef
resource_history_url = "reports/nodes/#{node_name}/runs/#{run_id}"
Chef::Log.info("Sending resource update report (run-id: #{run_id})")
Chef::Log.debug run_data.inspect
- compressed_data = encode_gzip(run_data.to_json)
+ compressed_data = encode_gzip(Chef::JSONCompat.to_json(run_data))
Chef::Log.debug("Sending compressed run data...")
# Since we're posting compressed data we can not directly call post_rest which expects JSON
reporting_url = @rest_client.create_url(resource_history_url)
@@ -273,7 +273,7 @@ class Chef
resource_record.for_json
end
run_data["status"] = @status
- run_data["run_list"] = @run_status.node.run_list.to_json
+ run_data["run_list"] = Chef::JSONCompat.to_json(@run_status.node.run_list)
run_data["total_res_count"] = @total_res_count.to_s
run_data["data"] = {}
run_data["start_time"] = start_time.to_s
@@ -283,7 +283,7 @@ class Chef
exception_data = {}
exception_data["class"] = exception.inspect
exception_data["message"] = exception.message
- exception_data["backtrace"] = exception.backtrace.to_json
+ exception_data["backtrace"] = Chef::JSONCompat.to_json(exception.backtrace)
exception_data["description"] = @error_descriptions
run_data["data"]["exception"] = exception_data
end
diff --git a/lib/chef/role.rb b/lib/chef/role.rb
index 57f3a2aa29..aeea873051 100644
--- a/lib/chef/role.rb
+++ b/lib/chef/role.rb
@@ -143,7 +143,7 @@ class Chef
# Serialize this object as a hash
def to_json(*a)
- to_hash.to_json(*a)
+ Chef::JSONCompat.to_json(to_hash, *a)
end
def update_from!(o)
diff --git a/lib/chef/run_list.rb b/lib/chef/run_list.rb
index 684c5e19fc..d0ba342e2c 100644
--- a/lib/chef/run_list.rb
+++ b/lib/chef/run_list.rb
@@ -86,7 +86,7 @@ class Chef
end
def to_json(*args)
- to_a.map { |item| item.to_s}.to_json(*args)
+ Chef::JSONCompat.to_json(to_a.map { |item| item.to_s}, *args)
end
def empty?
diff --git a/lib/chef/user.rb b/lib/chef/user.rb
index e2ef45dc5c..6569a97f00 100644
--- a/lib/chef/user.rb
+++ b/lib/chef/user.rb
@@ -73,7 +73,7 @@ class Chef
end
def to_json(*a)
- to_hash.to_json(*a)
+ Chef::JSONCompat.to_json(to_hash, *a)
end
def destroy
diff --git a/lib/chef/util/powershell/cmdlet_result.rb b/lib/chef/util/powershell/cmdlet_result.rb
index af7b3607cd..246701a7bc 100644
--- a/lib/chef/util/powershell/cmdlet_result.rb
+++ b/lib/chef/util/powershell/cmdlet_result.rb
@@ -16,7 +16,7 @@
# limitations under the License.
#
-require 'json'
+require 'chef/json_compat'
class Chef::Util::Powershell
class CmdletResult
@@ -33,7 +33,7 @@ class Chef::Util::Powershell
def return_value
if output_format == :object
- JSON.parse(@status.stdout)
+ Chef::JSONCompat.parse(@status.stdout)
else
@status.stdout
end
diff --git a/spec/data/bootstrap/test-hints.erb b/spec/data/bootstrap/test-hints.erb
index 29ba710b42..7693fdc7c9 100644
--- a/spec/data/bootstrap/test-hints.erb
+++ b/spec/data/bootstrap/test-hints.erb
@@ -6,7 +6,7 @@ mkdir -p /etc/chef/ohai/hints
<% @chef_config[:knife][:hints].each do |name, hash| -%>
(
cat <<'EOP'
-<%= hash.to_json %>
+<%= Chef::JSONCompat.to_json(hash) %>
EOP
) > /etc/chef/ohai/hints/<%= name %>.json
<% end -%>
diff --git a/spec/data/bootstrap/test.erb b/spec/data/bootstrap/test.erb
index 7cdc7dfdd0..3a383b47d0 100644
--- a/spec/data/bootstrap/test.erb
+++ b/spec/data/bootstrap/test.erb
@@ -1 +1 @@
-<%= first_boot.to_json %> \ No newline at end of file
+<%= Chef::JSONCompat.to_json(first_boot) %>
diff --git a/spec/functional/knife/cookbook_delete_spec.rb b/spec/functional/knife/cookbook_delete_spec.rb
index ee620bf165..4773fd2185 100644
--- a/spec/functional/knife/cookbook_delete_spec.rb
+++ b/spec/functional/knife/cookbook_delete_spec.rb
@@ -47,7 +47,7 @@ describe Chef::Knife::CookbookDelete do
Chef::Log.level = :debug
@knife.name_args = %w{no-such-cookbook}
- @api.get("/cookbooks/no-such-cookbook", 404, {'error'=>'dear Tim, no. -Sent from my iPad'}.to_json)
+ @api.get("/cookbooks/no-such-cookbook", 404, Chef::JSONCompat.to_json({'error'=>'dear Tim, no. -Sent from my iPad'}))
end
it "logs an error and exits" do
@@ -62,7 +62,7 @@ describe Chef::Knife::CookbookDelete do
before do
@knife.name_args = %w{obsolete-cookbook}
@cookbook_list = {'obsolete-cookbook' => { 'versions' => ['version' => '1.0.0']} }
- @api.get("/cookbooks/obsolete-cookbook", 200, @cookbook_list.to_json)
+ @api.get("/cookbooks/obsolete-cookbook", 200, Chef::JSONCompat.to_json(@cookbook_list))
end
it "asks for confirmation, then deletes the cookbook" do
@@ -105,7 +105,7 @@ describe Chef::Knife::CookbookDelete do
versions = ['1.0.0', '1.1.0', '1.2.0']
with_version = lambda { |version| { 'version' => version } }
@cookbook_list = {'obsolete-cookbook' => { 'versions' => versions.map(&with_version) } }
- @api.get("/cookbooks/obsolete-cookbook", 200, @cookbook_list.to_json)
+ @api.get("/cookbooks/obsolete-cookbook", 200, Chef::JSONCompat.to_json(@cookbook_list))
end
it "deletes all versions of a cookbook when given the '-a' flag" do
diff --git a/spec/functional/knife/exec_spec.rb b/spec/functional/knife/exec_spec.rb
index 455160fd5c..7eb52d01df 100644
--- a/spec/functional/knife/exec_spec.rb
+++ b/spec/functional/knife/exec_spec.rb
@@ -47,7 +47,7 @@ describe Chef::Knife::Exec do
@node = Chef::Node.new
@node.name("ohai-world")
response = {"rows" => [@node],"start" => 0,"total" => 1}
- @api.get(%r{^/search/node}, 200, response.to_json)
+ @api.get(%r{^/search/node}, 200, Chef::JSONCompat.to_json(response))
code = "$output.puts nodes.all"
@knife.config[:exec] = code
@knife.run
diff --git a/spec/functional/util/powershell/cmdlet_spec.rb b/spec/functional/util/powershell/cmdlet_spec.rb
index 63d1ac09b5..ca142e66b6 100644
--- a/spec/functional/util/powershell/cmdlet_spec.rb
+++ b/spec/functional/util/powershell/cmdlet_spec.rb
@@ -16,7 +16,6 @@
# limitations under the License.
#
-require 'json'
require File.expand_path('../../../../spec_helper', __FILE__)
describe Chef::Util::Powershell::Cmdlet, :windows_only do
@@ -91,7 +90,7 @@ describe Chef::Util::Powershell::Cmdlet, :windows_only do
it "returns json format data", :windows_powershell_dsc_only do
result = cmdlet_alias_requires_switch_or_argument.run({},{},'ls')
expect(result.succeeded?).to eq(true)
- expect(lambda{JSON.parse(result.return_value)}).not_to raise_error
+ expect(lambda{Chef::JSONCompat.parse(result.return_value)}).not_to raise_error
end
end
diff --git a/spec/integration/knife/chef_repo_path_spec.rb b/spec/integration/knife/chef_repo_path_spec.rb
index 72d2ffbf75..ba642c18dc 100644
--- a/spec/integration/knife/chef_repo_path_spec.rb
+++ b/spec/integration/knife/chef_repo_path_spec.rb
@@ -287,6 +287,7 @@ EOM
knife('show --local /clients/blah.json').should_succeed <<EOM
/clients/blah.json:
{
+
}
EOM
end
@@ -374,6 +375,7 @@ EOM
knife('show --local /environments/blah.json').should_succeed <<EOM
/environments/blah.json:
{
+
}
EOM
end
@@ -386,6 +388,7 @@ EOM
knife('show --local /nodes/blah.json').should_succeed <<EOM
/nodes/blah.json:
{
+
}
EOM
end
@@ -398,6 +401,7 @@ EOM
knife('show --local /roles/blah.json').should_succeed <<EOM
/roles/blah.json:
{
+
}
EOM
end
@@ -410,6 +414,7 @@ EOM
knife('show --local /users/blah.json').should_succeed <<EOM
/users/blah.json:
{
+
}
EOM
end
diff --git a/spec/integration/knife/diff_spec.rb b/spec/integration/knife/diff_spec.rb
index 2e36f39c82..232b486b62 100644
--- a/spec/integration/knife/diff_spec.rb
+++ b/spec/integration/knife/diff_spec.rb
@@ -275,7 +275,7 @@ EOM
when_the_repository 'has an environment with bad JSON' do
file 'environments/x.json', '{'
it 'knife diff reports an error and does a textual diff' do
- knife('diff /environments/x.json').should_succeed(/- "name": "x"/, :stderr => "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\n")
+ knife('diff /environments/x.json').should_succeed(/- "name": "x"/, :stderr => /WARN: Parse error reading #{path_to('environments/x.json')} as JSON: parse error: premature EOF\n/)
end
end
end
@@ -528,7 +528,7 @@ EOM
when_the_repository 'has an environment with bad JSON' do
file 'environments/x.json', '{'
it 'knife diff reports an error and does a textual diff' do
- knife('diff /environments/x.json').should_succeed(/- "name": "x"/, :stderr => "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\n")
+ knife('diff /environments/x.json').should_succeed(/- "name": "x"/, :stderr => /WARN: Parse error reading #{path_to('environments/x.json')} as JSON: parse error: premature EOF\n/)
end
end
end
diff --git a/spec/integration/knife/download_spec.rb b/spec/integration/knife/download_spec.rb
index f266b47b1b..68eb5713ce 100644
--- a/spec/integration/knife/download_spec.rb
+++ b/spec/integration/knife/download_spec.rb
@@ -496,7 +496,7 @@ EOM
when_the_repository 'has an environment with bad JSON' do
file 'environments/x.json', '{'
it 'knife download succeeds' do
- knife('download /environments/x.json').should_succeed "Updated /environments/x.json\n", :stderr => "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\n"
+ knife('download /environments/x.json').should_succeed "Updated /environments/x.json\n", :stderr => /WARN: Parse error reading #{path_to('environments/x.json')} as JSON: parse error: premature EOF\n/
knife('diff --name-status /environments/x.json').should_succeed ''
end
end
@@ -946,7 +946,7 @@ EOM
when_the_repository 'has an environment with bad JSON' do
file 'environments/x.json', '{'
it 'knife download succeeds' do
- knife('download /environments/x.json').should_succeed "Updated /environments/x.json\n", :stderr => "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\n"
+ knife('download /environments/x.json').should_succeed "Updated /environments/x.json\n", :stderr => /WARN: Parse error reading #{path_to('environments/x.json')} as JSON: parse error: premature EOF\n/
knife('diff --name-status /environments/x.json').should_succeed ''
end
end
diff --git a/spec/integration/knife/raw_spec.rb b/spec/integration/knife/raw_spec.rb
index 2a9b5d8904..50ca6cb135 100644
--- a/spec/integration/knife/raw_spec.rb
+++ b/spec/integration/knife/raw_spec.rb
@@ -44,12 +44,16 @@ describe 'knife raw' do
"chef_type": "node",
"chef_environment": "_default",
"override": {
+
},
"normal": {
+
},
"default": {
+
},
"automatic": {
+
},
"run_list": [
@@ -70,13 +74,16 @@ EOM
"json_class": "Chef::Role",
"chef_type": "role",
"default_attributes": {
+
},
"override_attributes": {
+
},
"run_list": [
],
"env_run_lists": {
+
}
}
EOM
@@ -111,13 +118,16 @@ EOM
"json_class": "Chef::Role",
"chef_type": "role",
"default_attributes": {
+
},
"override_attributes": {
+
},
"run_list": [
],
"env_run_lists": {
+
}
}
EOM
diff --git a/spec/integration/knife/upload_spec.rb b/spec/integration/knife/upload_spec.rb
index 46b804205f..d98cb7ba9d 100644
--- a/spec/integration/knife/upload_spec.rb
+++ b/spec/integration/knife/upload_spec.rb
@@ -237,7 +237,7 @@ Created /data_bags/x/y.json
EOM
knife('diff --name-status /data_bags').should_succeed <<EOM
EOM
- JSON.parse(knife('raw /data/x/y').stdout, :create_additions => false).keys.sort.should == [ 'foo', 'id' ]
+ Chef::JSONCompat.parse(knife('raw /data/x/y').stdout, :create_additions => false).keys.sort.should == [ 'foo', 'id' ]
end
it 'knife upload /data_bags/x /data_bags/x/y.json uploads x once' do
@@ -256,7 +256,7 @@ Created /data_bags/x
Created /data_bags/x/y.json
EOM
knife('diff --name-status /data_bags').should_succeed ''
- result = JSON.parse(knife('raw /data/x/y').stdout, :create_additions => false)
+ result = Chef::JSONCompat.parse(knife('raw /data/x/y').stdout, :create_additions => false)
result.keys.sort.should == [ 'chef_type', 'data_bag', 'id' ]
result['chef_type'].should == 'aaa'
result['data_bag'].should == 'bbb'
@@ -528,8 +528,8 @@ EOM
when_the_repository 'has an environment with bad JSON' do
file 'environments/x.json', '{'
it 'knife upload tries and fails' do
- knife('upload /environments/x.json').should_fail "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\nERROR: /environments/x.json failed to write: Parse error reading JSON: A JSON text must at least contain two octets!\n"
- knife('diff --name-status /environments/x.json').should_succeed "M\t/environments/x.json\n", :stderr => "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\n"
+ knife('upload /environments/x.json').should_fail /WARN: Parse error reading #{path_to('environments/x.json')} as JSON: parse error: premature EOF\n.+ERROR: \/environments\/x.json failed to write: Parse error reading JSON: parse error: premature EOF\n/m
+ knife('diff --name-status /environments/x.json').should_succeed "M\t/environments/x.json\n", :stderr => /WARN: Parse error reading #{path_to('environments/x.json')} as JSON: parse error: premature EOF\n/
end
end
@@ -554,7 +554,7 @@ EOM
when_the_repository 'has an environment with bad JSON' do
file 'environments/x.json', '{'
it 'knife upload tries and fails' do
- knife('upload /environments/x.json').should_fail "ERROR: /environments failed to create_child: Parse error reading JSON creating child 'x.json': A JSON text must at least contain two octets!\n"
+ knife('upload /environments/x.json').should_fail /ERROR: \/environments failed to create_child: Parse error reading JSON creating child 'x.json': parse error: premature EOF\n/
knife('diff --name-status /environments/x.json').should_succeed "A\t/environments/x.json\n"
end
end
@@ -1007,8 +1007,8 @@ EOM
when_the_repository 'has an environment with bad JSON' do
file 'environments/x.json', '{'
it 'knife upload tries and fails' do
- knife('upload /environments/x.json').should_fail "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\nERROR: /environments/x.json failed to write: Parse error reading JSON: A JSON text must at least contain two octets!\n"
- knife('diff --name-status /environments/x.json').should_succeed "M\t/environments/x.json\n", :stderr => "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\n"
+ knife('upload /environments/x.json').should_fail /WARN: Parse error reading #{path_to('environments/x.json')} as JSON: parse error: premature EOF\n.+ERROR: \/environments\/x.json failed to write: Parse error reading JSON: parse error: premature EOF\n/m
+ knife('diff --name-status /environments/x.json').should_succeed "M\t/environments/x.json\n", :stderr => /WARN: Parse error reading #{path_to('environments/x.json')} as JSON: parse error: premature EOF\n/
end
end
@@ -1033,7 +1033,7 @@ EOM
when_the_repository 'has an environment with bad JSON' do
file 'environments/x.json', '{'
it 'knife upload tries and fails' do
- knife('upload /environments/x.json').should_fail "ERROR: /environments failed to create_child: Parse error reading JSON creating child 'x.json': A JSON text must at least contain two octets!\n"
+ knife('upload /environments/x.json').should_fail /ERROR: \/environments failed to create_child: Parse error reading JSON creating child 'x.json': parse error: premature EOF\n/
knife('diff --name-status /environments/x.json').should_succeed "A\t/environments/x.json\n"
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index e73010d2b5..475daff39e 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -182,3 +182,6 @@ module WEBrick
end
end
end
+
+# Enough stuff needs json serialization that I'm just adding it here for equality asserts
+require 'chef/json_compat'
diff --git a/spec/support/shared/integration/integration_helper.rb b/spec/support/shared/integration/integration_helper.rb
index abed4c2715..d262e58b48 100644
--- a/spec/support/shared/integration/integration_helper.rb
+++ b/spec/support/shared/integration/integration_helper.rb
@@ -21,7 +21,6 @@ require 'tmpdir'
require 'fileutils'
require 'chef/config'
require 'chef_zero/rspec'
-require 'json'
require 'support/shared/integration/knife_support'
require 'support/shared/integration/app_server_support'
require 'spec_helper'
@@ -69,7 +68,7 @@ module IntegrationSupport
File.open(filename, 'w') do |file|
raw = case contents
when Hash
- JSON.pretty_generate(contents)
+ Chef::JSONCompat.to_json_pretty(contents)
when Array
contents.join("\n")
else
diff --git a/spec/support/shared/shared_examples.rb b/spec/support/shared/shared_examples.rb
new file mode 100644
index 0000000000..ccdd8cf316
--- /dev/null
+++ b/spec/support/shared/shared_examples.rb
@@ -0,0 +1,10 @@
+# For storing any examples shared between multiple tests
+
+# Any object which defines a .to_json should import this test
+shared_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+
+ it "should allow consumers to call #to_json or Chef::JSONCompat.to_json" do
+ expect(subject.to_json).to eq(Chef::JSONCompat.to_json(subject))
+ end
+
+end
diff --git a/spec/tiny_server.rb b/spec/tiny_server.rb
index 7e6ef3a809..848e2f1133 100644
--- a/spec/tiny_server.rb
+++ b/spec/tiny_server.rb
@@ -25,6 +25,7 @@ require 'singleton'
require 'chef/json_compat'
require 'open-uri'
require 'chef/config'
+require 'chef/json_compat'
module TinyServer
@@ -152,7 +153,7 @@ module TinyServer
:available_routes => @routes, :request => env}
# Uncomment me for glorious debugging
# pp :not_found => debug_info
- [404, {'Content-Type' => 'application/json'}, [ debug_info.to_json ]]
+ [404, {'Content-Type' => 'application/json'}, [ Chef::JSONCompat.to_json(debug_info) ]]
end
end
diff --git a/spec/unit/api_client_spec.rb b/spec/unit/api_client_spec.rb
index 76fc4afb5c..14dcc60467 100644
--- a/spec/unit/api_client_spec.rb
+++ b/spec/unit/api_client_spec.rb
@@ -92,7 +92,7 @@ describe Chef::ApiClient do
before(:each) do
@client.name("black")
@client.public_key("crowes")
- @json = @client.to_json
+ @json = Chef::JSONCompat.to_json(@client)
end
it "serializes as a JSON object" do
@@ -117,7 +117,7 @@ describe Chef::ApiClient do
it "includes the private key when present" do
@client.private_key("monkeypants")
- @client.to_json.should include(%q{"private_key":"monkeypants"})
+ Chef::JSONCompat.to_json(@client).should include(%q{"private_key":"monkeypants"})
end
it "does not include the private key if not present" do
@@ -135,7 +135,7 @@ describe Chef::ApiClient do
"validator" => true,
"json_class" => "Chef::ApiClient"
}
- @client = Chef::JSONCompat.from_json(client.to_json)
+ @client = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(client))
end
it "should deserialize to a Chef::ApiClient object" do
diff --git a/spec/unit/config_fetcher_spec.rb b/spec/unit/config_fetcher_spec.rb
index c29521806a..66681b85ab 100644
--- a/spec/unit/config_fetcher_spec.rb
+++ b/spec/unit/config_fetcher_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
require 'chef/config_fetcher'
describe Chef::ConfigFetcher do
- let(:valid_json) { {:a=>"b"}.to_json }
+ let(:valid_json) { Chef::JSONCompat.to_json({:a=>"b"}) }
let(:invalid_json) { %q[{"syntax-error": "missing quote}] }
let(:http) { double("Chef::HTTP::Simple") }
diff --git a/spec/unit/cookbook/metadata_spec.rb b/spec/unit/cookbook/metadata_spec.rb
index 8e98610183..24c9a48b81 100644
--- a/spec/unit/cookbook/metadata_spec.rb
+++ b/spec/unit/cookbook/metadata_spec.rb
@@ -582,7 +582,7 @@ describe Chef::Cookbook::Metadata do
@meta.version "1.2.3"
end
- describe "serialize" do
+ describe "#to_json" do
before(:each) do
@serial = Chef::JSONCompat.from_json(@meta.to_json)
end
@@ -613,11 +613,15 @@ describe Chef::Cookbook::Metadata do
@serial[t].should == @meta.send(t.to_sym)
end
end
+
+ it "should produce the same output from to_json and Chef::JSONCompat" do
+ expect(@meta.to_json).to eq(Chef::JSONCompat.to_json(@meta))
+ end
end
- describe "deserialize" do
+ describe "::from_json" do
before(:each) do
- @deserial = Chef::Cookbook::Metadata.from_json(@meta.to_json)
+ @deserial = Chef::Cookbook::Metadata.from_json(Chef::JSONCompat.to_json(@meta))
end
it "should deserialize to a Chef::Cookbook::Metadata object" do
diff --git a/spec/unit/cookbook_loader_spec.rb b/spec/unit/cookbook_loader_spec.rb
index 4c21c124e0..2bcba07eb2 100644
--- a/spec/unit/cookbook_loader_spec.rb
+++ b/spec/unit/cookbook_loader_spec.rb
@@ -181,7 +181,7 @@ describe Chef::CookbookLoader do
aa.to_hash["metadata"].recipes.keys.should include("openldap")
expected_desc = "Main Open LDAP configuration"
aa.to_hash["metadata"].recipes["openldap"].should == expected_desc
- raw = aa.to_hash["metadata"].recipes.to_json
+ raw = Chef::JSONCompat.to_json(aa.to_hash["metadata"].recipes)
search_str = "\"openldap\":\""
key_idx = raw.index(search_str)
key_idx.should be > 0
diff --git a/spec/unit/cookbook_version_spec.rb b/spec/unit/cookbook_version_spec.rb
index f20bc3766a..ea36dcc6d8 100644
--- a/spec/unit/cookbook_version_spec.rb
+++ b/spec/unit/cookbook_version_spec.rb
@@ -420,6 +420,10 @@ describe Chef::CookbookVersion do
end
end
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:subject) { Chef::CookbookVersion.new("tatft", '/tmp/blah') }
+ end
+
end
end
diff --git a/spec/unit/data_bag_item_spec.rb b/spec/unit/data_bag_item_spec.rb
index ead0dadfa2..f28450ef72 100644
--- a/spec/unit/data_bag_item_spec.rb
+++ b/spec/unit/data_bag_item_spec.rb
@@ -166,7 +166,7 @@ describe Chef::DataBagItem do
before(:each) do
@data_bag_item.data_bag('mars_volta')
@data_bag_item.raw_data = { "id" => "octahedron", "snooze" => { "finally" => :world_will }}
- @deserial = Chef::JSONCompat.from_json(@data_bag_item.to_json)
+ @deserial = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(@data_bag_item))
end
it "should deserialize to a Chef::DataBagItem object" do
@@ -184,6 +184,10 @@ describe Chef::DataBagItem do
it "should have a matching 'snooze' key" do
@deserial["snooze"].should == { "finally" => "world_will" }
end
+
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:subject) { @data_bag_item }
+ end
end
describe "when converting to a string" do
diff --git a/spec/unit/data_bag_spec.rb b/spec/unit/data_bag_spec.rb
index 4ac843c869..b1c4b0ea6f 100644
--- a/spec/unit/data_bag_spec.rb
+++ b/spec/unit/data_bag_spec.rb
@@ -58,7 +58,7 @@ describe Chef::DataBag do
describe "deserialize" do
before(:each) do
@data_bag.name('mars_volta')
- @deserial = Chef::JSONCompat.from_json(@data_bag.to_json)
+ @deserial = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(@data_bag))
end
it "should deserialize to a Chef::DataBag object" do
@@ -73,6 +73,10 @@ describe Chef::DataBag do
end
end
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:subject) { @data_bag }
+ end
+
end
describe "when saving" do
diff --git a/spec/unit/deprecation_spec.rb b/spec/unit/deprecation_spec.rb
index 8617cb3cb3..6a405c2bb6 100644
--- a/spec/unit/deprecation_spec.rb
+++ b/spec/unit/deprecation_spec.rb
@@ -46,7 +46,7 @@ describe Chef::Deprecation do
end
method_snapshot_file = File.join(CHEF_SPEC_DATA, "file-providers-method-snapshot-chef-11-4.json")
- method_snapshot = JSON.parse(File.open(method_snapshot_file).read())
+ method_snapshot = Chef::JSONCompat.parse(File.open(method_snapshot_file).read())
method_snapshot.each do |class_name, old_methods|
class_object = class_from_string(class_name)
diff --git a/spec/unit/encrypted_data_bag_item_spec.rb b/spec/unit/encrypted_data_bag_item_spec.rb
index 1e662a0b7c..998b493514 100644
--- a/spec/unit/encrypted_data_bag_item_spec.rb
+++ b/spec/unit/encrypted_data_bag_item_spec.rb
@@ -100,6 +100,17 @@ describe Chef::EncryptedDataBagItem::Decryptor do
let(:plaintext_data) { {"foo" => "bar"} }
let(:encryption_key) { "passwd" }
let(:decryption_key) { encryption_key }
+ let(:json_wrapped_data) { Chef::JSONCompat.to_json({"json_wrapper" => plaintext_data}) }
+
+ shared_examples "decryption examples" do
+ it "decrypts the encrypted value" do
+ decryptor.decrypted_data.should eq(json_wrapped_data)
+ end
+
+ it "unwraps the encrypted data and returns it" do
+ decryptor.for_decrypted_item.should eq plaintext_data
+ end
+ end
context "when decrypting a version 2 (JSON+aes-256-cbc+hmac-sha256+random iv) encrypted value" do
let(:encrypted_value) do
@@ -112,6 +123,8 @@ describe Chef::EncryptedDataBagItem::Decryptor do
Base64.encode64(raw_hmac)
end
+ include_examples "decryption examples"
+
it "rejects the data if the hmac is wrong" do
encrypted_value["hmac"] = bogus_hmac
lambda { decryptor.for_decrypted_item }.should raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
@@ -134,13 +147,7 @@ describe Chef::EncryptedDataBagItem::Decryptor do
decryptor.should be_a_kind_of Chef::EncryptedDataBagItem::Decryptor::Version1Decryptor
end
- it "decrypts the encrypted value" do
- decryptor.decrypted_data.should eq({"json_wrapper" => plaintext_data}.to_json)
- end
-
- it "unwraps the encrypted data and returns it" do
- decryptor.for_decrypted_item.should eq plaintext_data
- end
+ include_examples "decryption examples"
describe "and the decryption step returns invalid data" do
it "raises a decryption failure error" do
diff --git a/spec/unit/environment_spec.rb b/spec/unit/environment_spec.rb
index 0e230e46ed..bb4ece0a47 100644
--- a/spec/unit/environment_spec.rb
+++ b/spec/unit/environment_spec.rb
@@ -196,7 +196,7 @@ describe Chef::Environment do
%w{name description cookbook_versions}.each do |t|
it "should include '#{t}'" do
- @json.should =~ /"#{t}":#{Regexp.escape(@environment.send(t.to_sym).to_json)}/
+ @json.should =~ /"#{t}":#{Regexp.escape(Chef::JSONCompat.to_json(@environment.send(t.to_sym)))}/
end
end
@@ -207,6 +207,10 @@ describe Chef::Environment do
it "should include 'chef_type'" do
@json.should =~ /"chef_type":"environment"/
end
+
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:subject) { @environment }
+ end
end
describe "from_json" do
@@ -222,7 +226,7 @@ describe Chef::Environment do
"json_class" => "Chef::Environment",
"chef_type" => "environment"
}
- @environment = Chef::JSONCompat.from_json(@data.to_json)
+ @environment = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(@data))
end
it "should return a Chef::Environment" do
@@ -420,7 +424,7 @@ describe Chef::Environment do
"description" => "desc",
"chef_type" => "environment"
}
- IO.should_receive(:read).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(JSON.dump(environment_hash))
+ IO.should_receive(:read).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(Chef::JSONCompat.to_json(environment_hash))
environment = Chef::Environment.load('foo')
environment.should be_a_kind_of(Chef::Environment)
diff --git a/spec/unit/exceptions_spec.rb b/spec/unit/exceptions_spec.rb
index 3e7b1ba93f..c7bfc63e6b 100644
--- a/spec/unit/exceptions_spec.rb
+++ b/spec/unit/exceptions_spec.rb
@@ -74,5 +74,11 @@ describe Chef::Exceptions do
it "should have an exception class of #{exception} which inherits from #{expected_super_class}" do
lambda{ raise exception }.should raise_error(expected_super_class)
end
+
+ if exception.methods.include?(:to_json)
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:subject) { exception }
+ end
+ end
end
end
diff --git a/spec/unit/json_compat_spec.rb b/spec/unit/json_compat_spec.rb
index cce31b0c7c..2d10df874f 100644
--- a/spec/unit/json_compat_spec.rb
+++ b/spec/unit/json_compat_spec.rb
@@ -21,49 +21,90 @@ require 'chef/json_compat'
describe Chef::JSONCompat do
- describe "with JSON containing an existing class" do
- let(:json){'{"json_class": "Chef::Role"}'}
+ describe "#from_json with JSON containing an existing class" do
+ let(:json) { '{"json_class": "Chef::Role"}' }
+
it "returns an instance of the class instead of a Hash" do
- Chef::JSONCompat.from_json(json).class.should eq Chef::Role
+ expect(Chef::JSONCompat.from_json(json).class).to eq Chef::Role
+ end
+ end
+
+ describe "#from_json with JSON containing comments" do
+ let(:json) { %Q{{\n/* comment */\n// comment 2\n"json_class": "Chef::Role"}} }
+
+ it "returns an instance of the class instead of a Hash" do
+ expect(Chef::JSONCompat.from_json(json).class).to eq Chef::Role
+ end
+ end
+
+ describe "#parse with JSON containing comments" do
+ let(:json) { %Q{{\n/* comment */\n// comment 2\n"json_class": "Chef::Role"}} }
+
+ it "returns a Hash" do
+ expect(Chef::JSONCompat.parse(json).class).to eq Hash
end
end
describe 'with JSON containing "Chef::Sandbox" as a json_class value' do
require 'chef/sandbox' # Only needed for this test
- let(:json){'{"json_class": "Chef::Sandbox", "arbitrary": "data"}'}
+
+ let(:json) { '{"json_class": "Chef::Sandbox", "arbitrary": "data"}' }
+
it "returns a Hash, because Chef::Sandbox is a dummy class" do
- Chef::JSONCompat.from_json(json).should eq({"json_class" => "Chef::Sandbox", "arbitrary" => "data"})
+ expect(Chef::JSONCompat.from_json(json)).to eq({"json_class" => "Chef::Sandbox", "arbitrary" => "data"})
end
end
- describe "with a file with 300 or less nested entries" do
- before(:all) do
- @json = IO.read(File.join(CHEF_SPEC_DATA, 'big_json.json'))
- @hash = Chef::JSONCompat.from_json(@json)
+ describe "when pretty printing an object that defines #to_json" do
+ class Foo
+ def to_json(*a)
+ Chef::JSONCompat.to_json({'bar' => {'baz' => 5678}}, *a)
+ end
end
+ it "should work" do
+ f = Foo.new
+ expect(Chef::JSONCompat.to_json_pretty(f)).to eql("{\n \"bar\": {\n \"baz\": 5678\n }\n}\n")
+ end
+
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:subject) { Foo.new }
+ end
+ end
+
+ describe "with a file with 300 or less nested entries" do
+ let(:json) { IO.read(File.join(CHEF_SPEC_DATA, 'big_json.json')) }
+ let(:hash) { Chef::JSONCompat.from_json(json) }
+
describe "when a big json file is loaded" do
it "should create a Hash from the file" do
- @hash.should be_kind_of(Hash)
+ expect(hash).to be_kind_of(Hash)
end
+
it "should has 'test' as a 300th nested value" do
- @hash['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key'].should == 'test'
+ expect(hash['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']).to eq('test')
end
end
end
+
describe "with a file with more than 300 nested entries" do
- before(:all) do
- @json = IO.read(File.join(CHEF_SPEC_DATA, 'big_json_plus_one.json'))
- @hash = Chef::JSONCompat.from_json(@json, {:max_nesting => 301})
- end
+ let(:json) { IO.read(File.join(CHEF_SPEC_DATA, 'big_json_plus_one.json')) }
+ let(:hash) { Chef::JSONCompat.from_json(json, {:max_nesting => 301}) }
describe "when a big json file is loaded" do
it "should create a Hash from the file" do
- @hash.should be_kind_of(Hash)
+ expect(hash).to be_kind_of(Hash)
end
+
it "should has 'test' as a 301st nested value" do
- @hash['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key'].should == 'test'
+ expect(hash['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']).to eq('test')
end
end
end
+
+ it "should define .to_json on all classes" do
+ class SomeClass; end
+
+ expect(SomeClass.new.respond_to?(:to_json)).to eq(true)
+ end
end
diff --git a/spec/unit/knife/cookbook_metadata_from_file_spec.rb b/spec/unit/knife/cookbook_metadata_from_file_spec.rb
index 68ab6740ab..3a1dd9b21e 100644
--- a/spec/unit/knife/cookbook_metadata_from_file_spec.rb
+++ b/spec/unit/knife/cookbook_metadata_from_file_spec.rb
@@ -27,7 +27,6 @@ describe Chef::Knife::CookbookMetadataFromFile do
@tgt = File.expand_path(File.join(CHEF_SPEC_DATA, "metadata", "quick_start", "metadata.json"))
@knife = Chef::Knife::CookbookMetadataFromFile.new
@knife.name_args = [ @src ]
- @knife.stub(:to_json_pretty).and_return(true)
@md = Chef::Cookbook::Metadata.new
Chef::Cookbook::Metadata.stub(:new).and_return(@md)
$stdout.stub(:write)
diff --git a/spec/unit/knife/cookbook_site_share_spec.rb b/spec/unit/knife/cookbook_site_share_spec.rb
index 28b2a509fd..7e4a65ae7e 100644
--- a/spec/unit/knife/cookbook_site_share_spec.rb
+++ b/spec/unit/knife/cookbook_site_share_spec.rb
@@ -109,7 +109,7 @@ describe Chef::Knife::CookbookSiteShare do
end
it 'should post the cookbook to "http://cookbooks.opscode.com"' do
- response_text = {:uri => 'http://cookbooks.opscode.com/cookbooks/cookbook_name'}.to_json
+ response_text = Chef::JSONCompat.to_json({:uri => 'http://cookbooks.opscode.com/cookbooks/cookbook_name'})
@upload_response.stub(:body).and_return(response_text)
@upload_response.stub(:code).and_return(201)
Chef::CookbookSiteStreamingUploader.should_receive(:post).with(/cookbooks\.opscode\.com/, anything(), anything(), anything())
@@ -117,7 +117,7 @@ describe Chef::Knife::CookbookSiteShare do
end
it 'should alert the user when a version already exists' do
- response_text = {:error_messages => ['Version already exists']}.to_json
+ response_text = Chef::JSONCompat.to_json({:error_messages => ['Version already exists']})
@upload_response.stub(:body).and_return(response_text)
@upload_response.stub(:code).and_return(409)
lambda { @knife.run }.should raise_error(SystemExit)
@@ -125,7 +125,7 @@ describe Chef::Knife::CookbookSiteShare do
end
it 'should pass any errors on to the user' do
- response_text = {:error_messages => ["You're holding it wrong"]}.to_json
+ response_text = Chef::JSONCompat.to_json({:error_messages => ["You're holding it wrong"]})
@upload_response.stub(:body).and_return(response_text)
@upload_response.stub(:code).and_return(403)
lambda { @knife.run }.should raise_error(SystemExit)
@@ -133,7 +133,7 @@ describe Chef::Knife::CookbookSiteShare do
end
it 'should print the body if no errors are exposed on failure' do
- response_text = {:system_error => "Your call was dropped", :reason => "There's a map for that"}.to_json
+ response_text = Chef::JSONCompat.to_json({:system_error => "Your call was dropped", :reason => "There's a map for that"})
@upload_response.stub(:body).and_return(response_text)
@upload_response.stub(:code).and_return(500)
@knife.ui.should_receive(:error).with(/#{Regexp.escape(response_text)}/)#.ordered
diff --git a/spec/unit/knife/core/bootstrap_context_spec.rb b/spec/unit/knife/core/bootstrap_context_spec.rb
index 9cabc59719..57c1934439 100644
--- a/spec/unit/knife/core/bootstrap_context_spec.rb
+++ b/spec/unit/knife/core/bootstrap_context_spec.rb
@@ -116,13 +116,13 @@ EXPECTED
describe "when JSON attributes are given" do
let(:config) { {:first_boot_attributes => {:baz => :quux}} }
it "adds the attributes to first_boot" do
- bootstrap_context.first_boot.to_json.should eq({:baz => :quux, :run_list => run_list}.to_json)
+ Chef::JSONCompat.to_json(bootstrap_context.first_boot).should eq(Chef::JSONCompat.to_json({:baz => :quux, :run_list => run_list}))
end
end
describe "when JSON attributes are NOT given" do
it "sets first_boot equal to run_list" do
- bootstrap_context.first_boot.to_json.should eq({:run_list => run_list}.to_json)
+ Chef::JSONCompat.to_json(bootstrap_context.first_boot).should eq(Chef::JSONCompat.to_json({:run_list => run_list}))
end
end
diff --git a/spec/unit/knife/data_bag_from_file_spec.rb b/spec/unit/knife/data_bag_from_file_spec.rb
index 8537045164..0e53a67619 100644
--- a/spec/unit/knife/data_bag_from_file_spec.rb
+++ b/spec/unit/knife/data_bag_from_file_spec.rb
@@ -21,7 +21,6 @@ require 'spec_helper'
require 'chef/data_bag_item'
require 'chef/encrypted_data_bag_item'
require 'tempfile'
-require 'json'
Chef::Knife::DataBagFromFile.load_deps
@@ -46,7 +45,7 @@ describe Chef::Knife::DataBagFromFile do
"greeting" => "hello",
"nested" => { "a1" => [1, 2, 3], "a2" => { "b1" => true }}
}
- @db_file.write(@plain_data.to_json)
+ @db_file.write(Chef::JSONCompat.to_json(@plain_data))
@db_file.flush
@knife.instance_variable_set(:@name_args, ['bag_name', @db_file.path])
end
diff --git a/spec/unit/node_spec.rb b/spec/unit/node_spec.rb
index 21a978a9c9..ccecfca2f0 100644
--- a/spec/unit/node_spec.rb
+++ b/spec/unit/node_spec.rb
@@ -762,6 +762,10 @@ describe Chef::Node do
end
serialized_node.run_list.should == node.run_list
end
+
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:subject) { node.from_file(File.expand_path("nodes/test.example.com.rb", CHEF_SPEC_DATA)) }
+ end
end
describe "to_s" do
diff --git a/spec/unit/provider/remote_file/cache_control_data_spec.rb b/spec/unit/provider/remote_file/cache_control_data_spec.rb
index 8e396b1b40..8a849d9d7d 100644
--- a/spec/unit/provider/remote_file/cache_control_data_spec.rb
+++ b/spec/unit/provider/remote_file/cache_control_data_spec.rb
@@ -85,7 +85,7 @@ describe Chef::Provider::RemoteFile::CacheControlData do
cache["etag"] = etag
cache["mtime"] = mtime
cache["checksum"] = last_fetched_checksum
- cache.to_json
+ Chef::JSONCompat.to_json(cache)
end
before do
diff --git a/spec/unit/resource_collection_spec.rb b/spec/unit/resource_collection_spec.rb
index cf62f5ff40..cc9cc83923 100644
--- a/spec/unit/resource_collection_spec.rb
+++ b/spec/unit/resource_collection_spec.rb
@@ -245,12 +245,16 @@ describe Chef::ResourceCollection do
json.should =~ /json_class/
json.should =~ /instance_vars/
end
+
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:subject) { @rc }
+ end
end
describe "self.from_json" do
it "should deserialize itself from json" do
@rc << @resource
- json = @rc.to_json
+ json = Chef::JSONCompat.to_json(@rc)
s_rc = Chef::JSONCompat.from_json(json)
s_rc.should be_a_kind_of(Chef::ResourceCollection)
s_rc[0].name.should eql(@resource.name)
diff --git a/spec/unit/resource_reporter_spec.rb b/spec/unit/resource_reporter_spec.rb
index fe6a895b5a..1a89cbdce1 100644
--- a/spec/unit/resource_reporter_spec.rb
+++ b/spec/unit/resource_reporter_spec.rb
@@ -421,7 +421,7 @@ describe Chef::ResourceReporter do
it "includes the run_list" do
@report.should have_key("run_list")
- @report["run_list"].should == @run_status.node.run_list.to_json
+ @report["run_list"].should == Chef::JSONCompat.to_json(@run_status.node.run_list)
end
it "includes the end_time" do
@@ -484,7 +484,7 @@ describe Chef::ResourceReporter do
it "includes the exception trace in the event data" do
@report["data"]["exception"].should have_key("backtrace")
- @report["data"]["exception"]["backtrace"].should == @backtrace.to_json
+ @report["data"]["exception"]["backtrace"].should == Chef::JSONCompat.to_json(@backtrace)
end
it "includes the error inspector output in the event data" do
@@ -701,7 +701,7 @@ describe Chef::ResourceReporter do
})
data_stream = Zlib::GzipReader.new(StringIO.new(data))
data = data_stream.read
- data.should eq(@expected_data.to_json)
+ data.should eq(Chef::JSONCompat.to_json(@expected_data))
response
end
diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb
index 70941e4e82..d10f3ca27b 100644
--- a/spec/unit/resource_spec.rb
+++ b/spec/unit/resource_spec.rb
@@ -336,6 +336,10 @@ describe Chef::Resource do
json.should =~ /json_class/
json.should =~ /instance_vars/
end
+
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:subject) { @resource }
+ end
end
describe "to_hash" do
@@ -354,7 +358,7 @@ describe Chef::Resource do
describe "self.json_create" do
it "should deserialize itself from json" do
- json = @resource.to_json
+ json = Chef::JSONCompat.to_json(@resource)
serialized_node = Chef::JSONCompat.from_json(json)
serialized_node.should be_a_kind_of(Chef::Resource)
serialized_node.name.should eql(@resource.name)
diff --git a/spec/unit/role_spec.rb b/spec/unit/role_spec.rb
index 05ebf282db..42819cda21 100644
--- a/spec/unit/role_spec.rb
+++ b/spec/unit/role_spec.rb
@@ -215,6 +215,10 @@ describe Chef::Role do
end
end
+
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:subject) { @role }
+ end
end
describe "when created from JSON", :json => true do
diff --git a/spec/unit/run_list_spec.rb b/spec/unit/run_list_spec.rb
index 220e4ea4a6..d2f0e01811 100644
--- a/spec/unit/run_list_spec.rb
+++ b/spec/unit/run_list_spec.rb
@@ -304,7 +304,11 @@ describe Chef::RunList do
end
it "converts to json by converting its array form" do
- @run_list.to_json.should == ["recipe[nagios::client]", "role[production]", "recipe[apache2]"].to_json
+ Chef::JSONCompat.to_json(@run_list).should == Chef::JSONCompat.to_json(["recipe[nagios::client]", "role[production]", "recipe[apache2]"])
+ end
+
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:subject) { @run_list }
end
end
diff --git a/spec/unit/user_spec.rb b/spec/unit/user_spec.rb
index 08bde33d7b..055512444b 100644
--- a/spec/unit/user_spec.rb
+++ b/spec/unit/user_spec.rb
@@ -154,6 +154,10 @@ describe Chef::User do
it "does not include the password if not present" do
@json.should_not include("password")
end
+
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:subject) { @user }
+ end
end
describe "when deserializing from JSON" do
@@ -163,7 +167,7 @@ describe Chef::User do
"private_key" => "pandas",
"password" => "password",
"admin" => true }
- @user = Chef::User.from_json(user.to_json)
+ @user = Chef::User.from_json(Chef::JSONCompat.to_json(user))
end
it "should deserialize to a Chef::User object" do