pax_global_header 0000666 0000000 0000000 00000000064 12545704171 0014520 g ustar 00root root 0000000 0000000 52 comment=173edc9c43f9392be66cd6800581ba643366760b
multi_json-1.11.2/ 0000775 0000000 0000000 00000000000 12545704171 0013765 5 ustar 00root root 0000000 0000000 multi_json-1.11.2/.document 0000664 0000000 0000000 00000000075 12545704171 0015606 0 ustar 00root root 0000000 0000000 LICENSE.md
README.md
bin/*
features/**/*.feature
lib/**/*.rb
multi_json-1.11.2/.gitignore 0000664 0000000 0000000 00000000355 12545704171 0015760 0 ustar 00root root 0000000 0000000 ## TEXTMATE
*.tmproj
tmtags
## EMACS
*~
\#*
.\#*
## VIM
*.swp
## PROJECT::GENERAL
.yardoc
coverage
doc
rdoc
log
## BUNDLER
*.gem
.bundle
pkg
Gemfile.lock
## RBENV
.ruby-version
.rbenv*
## RCOV
coverage.data
tmp
## RUBINIUS
*.rbc
multi_json-1.11.2/.rspec 0000664 0000000 0000000 00000000027 12545704171 0015101 0 ustar 00root root 0000000 0000000 --color
--order random
multi_json-1.11.2/.travis.yml 0000664 0000000 0000000 00000000457 12545704171 0016104 0 ustar 00root root 0000000 0000000 bundler_args: --without development
language: ruby
rvm:
- 1.8.7
- 1.9.2
- 1.9.3
- 2.0.0
- 2.1
- 2.2
- jruby-18mode
- jruby-19mode
- jruby-head
- rbx-2
- ruby-head
matrix:
allow_failures:
- rvm: rbx-2
- rvm: jruby-head
- rvm: ruby-head
fast_finish: true
sudo: false
multi_json-1.11.2/.yardopts 0000664 0000000 0000000 00000000106 12545704171 0015630 0 ustar 00root root 0000000 0000000 --markup markdown
-
CHANGELOG.md
CONTRIBUTING.md
LICENSE.md
README.md
multi_json-1.11.2/CHANGELOG.md 0000664 0000000 0000000 00000027014 12545704171 0015602 0 ustar 00root root 0000000 0000000 1.11.2
------
* [Only pass one argument to JrJackson when two is not supported](https://github.com/intridea/multi_json/commit/e798fa517c817fc706982d3f3c61129b6651d601)
1.11.1
------
* [Dump method passes options throught for JrJackson adapter](https://github.com/intridea/multi_json/commit/3c730fd12135c3e7bf212f878958004908f13909)
1.11.0
------
* [Make all adapters read IO object before load](https://github.com/intridea/multi_json/commit/167f559e18d4efee05e1f160a2661d16dbb215d4)
1.10.1
------
* [Explicitly require stringio for Gson adapter](https://github.com/intridea/multi_json/commit/623ec8142d4a212fa0db763bb71295789a119929)
* [Do not read StringIO object before passing it to JrJackson](https://github.com/intridea/multi_json/commit/a6dc935df08e7b3d5d701fbb9298384c96df0fde)
1.10.0
------
* [Performance tweaks](https://github.com/intridea/multi_json/commit/58724acfed31866d079eaafb1cd824e341ade287)
1.9.3
-----
* [Convert indent option to Fixnum before passing to Oj](https://github.com/intridea/multi_json/commit/826fc5535b863b74fc9f981dfdda3e26f1ee4e5b)
1.9.2
-----
* [Enable use_to_json option for Oj adapter by default](https://github.com/intridea/multi_json/commit/76a4aaf697b10bbabd5d535d83cf1149efcfe5c7)
1.9.1
-----
* [Remove unused LoadError file](https://github.com/intridea/multi_json/commit/65dedd84d59baeefc25c477fedf0bbe85e7ce2cd)
1.9.0
----
* [Rename LoadError to ParseError](https://github.com/intridea/multi_json/commit/4abb98fe3a90b2a7b3d1594515c8a06042b4a27d)
* [Adapter load failure throws AdapterError instead of ArgumentError](https://github.com/intridea/multi_json/commit/4da612b617bd932bb6fa1cc4c43210327f98f271)
1.8.4
-----
* [Make Gson adapter explicitly read StringIO object](https://github.com/intridea/multi_json/commit/b58b498747ff6e94f41488c971b2a30a98760ef2)
1.8.3
-----
* [Make JrJackson explicitly read StringIO objects](https://github.com/intridea/multi_json/commit/e1f162d5b668e5e4db5afa175361a601a8aa2b05)
* [Prevent calling #downcase on alias symbols](https://github.com/intridea/multi_json/commit/c1cf075453ce0110f7decc4f906444b1233bb67c)
1.8.2
-----
* [Downcase adapter string name for OS compatibility](https://github.com/intridea/multi_json/commit/b8e15a032247a63f1410d21a18add05035f3fa66)
1.8.1
-----
* [Let the adapter handle strings with invalid encoding](https://github.com/intridea/multi_json/commit/6af2bf87b89f44eabf2ae9ca96779febc65ea94b)
1.8.0
-----
* [Raise MultiJson::LoadError on blank input](https://github.com/intridea/multi_json/commit/c44f9c928bb25fe672246ad394b3e5b991be32e6)
1.7.9
-----
* [Explicitly require json gem code even when constant is defined](https://github.com/intridea/multi_json/commit/36f7906c66477eb4b55b7afeaa3684b6db69eff2)
1.7.8
-----
* [Reorder JrJackson before json_gem](https://github.com/intridea/multi_json/commit/315b6e460b6e4dcdb6c82e04e4be8ee975d395da)
* [Update vendored OkJson to version 43](https://github.com/intridea/multi_json/commit/99a6b662f6ef4036e3ee94d7eb547fa72fb2ab50)
1.7.7
-----
* [Fix options caching issues](https://github.com/intridea/multi_json/commit/a3f14c3661688c5927638fa6088c7b46a67e875e)
1.7.6
-----
* [Bring back MultiJson::VERSION constant](https://github.com/intridea/multi_json/commit/31b990c2725e6673bf8ce57540fe66b57a751a72)
1.7.5
-----
* [Fix warning '*' interpreted as argument prefix](https://github.com/intridea/multi_json/commit/b698962c7f64430222a1f06430669706a47aff89)
* [Remove stdlib warning](https://github.com/intridea/multi_json/commit/d06eec6b7996ac8b4ff0e2229efd835379b0c30f)
1.7.4
-----
* [Cache options for better performance](https://github.com/intridea/multi_json/commit/8a26ee93140c4bed36194ed9fb887a1b6919257b)
1.7.3
-----
* [Require json/ext to ensure extension version gets loaded for json_gem](https://github.com/intridea/multi_json/commit/942686f7e8597418c6f90ee69e1d45242fac07b1)
* [Rename JrJackson](https://github.com/intridea/multi_json/commit/078de7ba8b6035343c3e96b4767549e9ec43369a)
* [Prefer JrJackson to JSON gem if present](https://github.com/intridea/multi_json/commit/af8bd9799a66855f04b3aff1c488485950cec7bf)
* [Print a warning if outdated gem versions are used](https://github.com/intridea/multi_json/commit/e7438e7ba2be0236cfa24c2bb9ad40ee821286d1)
* [Loosen required_rubygems_version for compatibility with Ubuntu 10.04](https://github.com/intridea/multi_json/commit/59fad014e8fe41dbc6f09485ea0dc21fc42fd7a7)
1.7.2
-----
* [Rename Jrjackson adapter to JrJackson](https://github.com/intridea/multi_json/commit/b36dc915fc0e6548cbad06b5db6f520e040c9c8b)
* [Implement jrjackson -> jr_jackson alias for back-compatability](https://github.com/intridea/multi_json/commit/aa50ab8b7bb646b8b75d5d65dfeadae8248a4f10)
* [Update vendored OkJson module](https://github.com/intridea/multi_json/commit/30a3f474e17dd86a697c3fab04f468d1a4fd69d7)
1.7.1
-----
* [Fix capitalization of JrJackson class](https://github.com/intridea/multi_json/commit/5373a5e38c647f02427a0477cb8e0e0dafad1b8d)
1.7.0
-----
* [Add load_options/dump_options to MultiJson](https://github.com/intridea/multi_json/commit/a153956be6b0df06ea1705ce3c1ff0b5b0e27ea5)
* [MultiJson does not modify arguments](https://github.com/intridea/multi_json/commit/58525b01c4c2f6635ba2ac13d6fd987b79f3962f)
* [Enable quirks_mode by default for json_gem/json_pure adapters](https://github.com/intridea/multi_json/commit/1fd4e6635c436515b7d7d5a0bee4548de8571520)
* [Add JrJackson adapter](https://github.com/intridea/multi_json/commit/4dd86fa96300aaaf6d762578b9b31ea82adb056d)
* [Raise ArgumentError on bad adapter input](https://github.com/intridea/multi_json/commit/911a3756bdff2cb5ac06497da3fa3e72199cb7ad)
1.6.1
-----
* [Revert "Use JSON.generate instead of #to_json"](https://github.com/intridea/multi_json/issues/86)
1.6.0
-----
* [Add gson.rb support](https://github.com/intridea/multi_json/pull/71)
* [Add MultiJson.default_options](https://github.com/intridea/multi_json/pull/70)
* [Add MultiJson.with_adapter](https://github.com/intridea/multi_json/pull/67)
* [Stringify all possible keys for ok_json](https://github.com/intridea/multi_json/pull/66)
* [Use JSON.generate instead of #to_json](https://github.com/intridea/multi_json/issues/73)
* [Alias `MultiJson::DecodeError` to `MultiJson::LoadError`](https://github.com/intridea/multi_json/pull/79)
1.5.1
-----
* [Do not allow Oj or JSON to create symbols by searching for classes](https://github.com/intridea/multi_json/commit/193e28cf4dc61b6e7b7b7d80f06f74c76df65c41)
1.5.0
-----
* [Add `MultiJson.with_adapter` method](https://github.com/intridea/multi_json/commit/d14c5d28cae96557a0421298621b9499e1f28104)
* [Stringify all possible keys for `ok_json`](https://github.com/intridea/multi_json/commit/73998074058e1e58c557ffa7b9541d486d6041fa)
1.4.0
-----
* [Allow `load`/`dump` of JSON fragments](https://github.com/intridea/multi_json/commit/707aae7d48d39c85b38febbd2c210ba87f6e4a36)
1.3.7
-----
* [Fix rescue clause for MagLev](https://github.com/intridea/multi_json/commit/39abdf50199828c50e85b2ce8f8ba31fcbbc9332)
* [Remove unnecessary check for string version of options key](https://github.com/intridea/multi_json/commit/660101b70e962b3c007d0b90d45944fa47d13ec4)
* [Explicitly set default adapter when adapter is set to `nil` or `false`](https://github.com/intridea/multi_json/commit/a9e587d5a63eafb4baee9fb211265e4dd96a26bc)
* [Fix Oj `ParseError` mapping for Oj 1.4.0](https://github.com/intridea/multi_json/commit/7d9045338cc9029401c16f3c409d54ce97f275e2)
1.3.6
-----
* [Allow adapter-specific options to be passed through to Oj](https://github.com/intridea/multi_json/commit/d0e5feeebcba0bc69400dd203a295f5c30971223)
1.3.5
-----
* [Add pretty support to Oj adapter](https://github.com/intridea/multi_json/commit/0c8f75f03020c53bcf4c6be258faf433d24b2c2b)
1.3.4
-----
* [Use `class << self` instead of `module_function` to create aliases](https://github.com/intridea/multi_json/commit/ba1451c4c48baa297e049889be241a424cb05980)
1.3.3
-----
* [Remove deprecation warnings](https://github.com/intridea/multi_json/commit/36b524e71544eb0186826a891bcc03b2820a008f)
1.3.2
-----
* [Add ability to use adapter per call](https://github.com/intridea/multi_json/commit/106bbec469d5d0a832bfa31fffcb8c0f0cdc9bd3)
* [Add and deprecate `default_engine` method](https://github.com/intridea/multi_json/commit/fc3df0c7a3e2ab9ce0c2c7e7617a4da97dd13f6e)
1.3.1
-----
* [Only warn once for each instance a deprecated method is called](https://github.com/intridea/multi_json/commit/e21d6eb7da74b3f283995c1d27d5880e75f0ae84)
1.3.0
-----
* [Implement `load`/`dump`; deprecate `decode`/`encode`](https://github.com/intridea/multi_json/commit/e90fd6cb1b0293eb0c73c2f4eb0f7a1764370216)
* [Rename engines to adapters](https://github.com/intridea/multi_json/commit/ae7fd144a7949a9c221dcaa446196ec23db908df)
1.2.0
-----
* [Add support for Oj](https://github.com/intridea/multi_json/commit/acd06b233edabe6c44f226873db7b49dab560c60)
1.1.0
-----
* [`NSJSONSerialization` support for MacRuby](https://github.com/intridea/multi_json/commit/f862e2fc966cac8867fe7da3997fc76e8a6cf5d4)
1.0.4
-----
* [Set data context to `DecodeError` exception](https://github.com/intridea/multi_json/commit/19ddafd44029c6681f66fae2a0f6eabfd0f85176)
* [Allow `ok_json` to fallback to `to_json`](https://github.com/intridea/multi_json/commit/c157240b1193b283d06d1bd4d4b5b06bcf3761f8)
* [Add warning when using `ok_json`](https://github.com/intridea/multi_json/commit/dd4b68810c84f826fb98f9713bfb29ab96888d57)
* [Options can be passed to an engine on encode](https://github.com/intridea/multi_json/commit/e0a7ff5d5ff621ffccc61617ed8aeec5816e81f7)
1.0.3
-----
* [`Array` support for `stringify_keys`](https://github.com/intridea/multi_json/commit/644d1c5c7c7f6a27663b11668527b346094e38b9)
* [`Array` support for `symbolize_keys`](https://github.com/intridea/multi_json/commit/c885377d47a2aa39cb0d971fea78db2d2fa479a7)
1.0.2
-----
* [Allow encoding of rootless JSON when `ok_json` is used](https://github.com/intridea/multi_json/commit/d1cde7de97cb0f6152aef8daf14037521cdce8c6)
1.0.1
-----
* [Correct an issue with `ok_json` not being returned as the default engine](https://github.com/intridea/multi_json/commit/d33c141619c54cccd770199694da8fd1bd8f449d)
1.0.0
-----
* [Remove `ActiveSupport::JSON` support](https://github.com/intridea/multi_json/commit/c2f4140141d785a24b3f56e58811b0e561b37f6a)
* [Fix `@engine` ivar warning](https://github.com/intridea/multi_json/commit/3b978a8995721a8dffedc3b75a7f49e5494ec553)
* [Only `rescue` from parsing errors during decoding, not any `StandardError`](https://github.com/intridea/multi_json/commit/391d00b5e85294d42d41347605d8d46b4a7f66cc)
* [Rename `okjson` engine and vendored lib to `ok_json`](https://github.com/intridea/multi_json/commit/5bd1afc977a8208ddb0443e1d57cb79665c019f1)
* [Add `StringIO` support to `json` gem and `ok_json`](https://github.com/intridea/multi_json/commit/1706b11568db7f50af451fce5f4d679aeb3bbe8f)
0.0.5
-----
* [Trap all JSON decoding errors; raise `MultiJson::DecodeError`](https://github.com/intridea/multi_json/commit/dea9a1aef6dd1212aa1e5a37ab1669f9b045b732)
0.0.4
-----
* [Fix default_engine check for `json` gem](https://github.com/intridea/multi_json/commit/caced0c4e8c795922a109ebc00c3c4fa8635bed8)
* [Make requirement mapper an `Array` to preserve order in Ruby versions < 1.9](https://github.com/intridea/multi_json/commit/526f5f29a42131574a088ad9bbb43d7f48439b2c)
0.0.3
-----
* [Improve defaulting and documentation](https://github.com/sferik/twitter/commit/3a0e41b9e4b0909201045fa47704b78c9d949b73)
0.0.2
-----
* [Rename to `multi_json`](https://github.com/sferik/twitter/commit/461ab89ce071c8c9fabfc183581e0ec523788b62)
0.0.1
-----
* [Initial commit](https://github.com/sferik/twitter/commit/518c21ab299c500527491e6c049ab2229e22a805)
multi_json-1.11.2/CONTRIBUTING.md 0000664 0000000 0000000 00000003376 12545704171 0016227 0 ustar 00root root 0000000 0000000 ## Contributing
In the spirit of [free software][free-sw], **everyone** is encouraged to help
improve this project.
[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
Here are some ways *you* can contribute:
* by using alpha, beta, and prerelease versions
* by reporting bugs
* by suggesting new features
* by writing or editing documentation
* by writing specifications
* by writing code (**no patch is too small**: fix typos, add comments, clean up
inconsistent whitespace)
* by refactoring code
* by closing [issues][]
* by reviewing patches
[issues]: https://github.com/intridea/multi_json/issues
## Submitting an Issue
We use the [GitHub issue tracker][issues] to track bugs and features. Before
submitting a bug report or feature request, check to make sure it hasn't
already been submitted. When submitting a bug report, please include a [Gist][]
that includes a stack trace and any details that may be necessary to reproduce
the bug, including your gem version, Ruby version, and operating system.
Ideally, a bug report should include a pull request with failing specs.
[gist]: https://gist.github.com/
## Submitting a Pull Request
1. [Fork the repository.][fork]
2. [Create a topic branch.][branch]
3. Add specs for your unimplemented feature or bug fix.
4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
5. Implement your feature or bug fix.
6. Run `bundle exec rake spec`. If your specs fail, return to step 5.
7. Run `open coverage/index.html`. If your changes are not completely covered
by your tests, return to step 3.
8. Add, commit, and push your changes.
9. [Submit a pull request.][pr]
[fork]: http://help.github.com/fork-a-repo/
[branch]: http://learn.github.com/p/branching.html
[pr]: http://help.github.com/send-pull-requests/
multi_json-1.11.2/Gemfile 0000664 0000000 0000000 00000001004 12545704171 0015253 0 ustar 00root root 0000000 0000000 source 'https://rubygems.org'
gem 'rake', '>= 0.9'
gem 'yard', '>= 0.8'
gem 'json', '~> 1.4', :require => nil
gem 'json_pure', '~> 1.4', :require => nil
group :development do
gem 'kramdown', '>= 0.14'
gem 'pry'
end
group :test do
gem 'rspec', '>= 2.14'
end
platforms :jruby do
gem 'gson', '>= 0.6', :require => nil
gem 'jrjackson', '~> 0.2.2', :require => nil
end
platforms :mingw, :mswin, :ruby do
gem 'oj', '~> 2.9', :require => nil
gem 'yajl-ruby', '~> 1.0', :require => nil
end
gemspec
multi_json-1.11.2/LICENSE.md 0000664 0000000 0000000 00000002134 12545704171 0015371 0 ustar 00root root 0000000 0000000 Copyright (c) 2010-2013 Michael Bleigh, Josh Kalderimis, Erik Michaels-Ober, Pavel Pravosud
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
multi_json-1.11.2/README.md 0000664 0000000 0000000 00000012124 12545704171 0015244 0 ustar 00root root 0000000 0000000 # MultiJSON
[][gem]
[][travis]
[][gemnasium]
[][codeclimate]
[gem]: https://rubygems.org/gems/multi_json
[travis]: http://travis-ci.org/intridea/multi_json
[gemnasium]: https://gemnasium.com/intridea/multi_json
[codeclimate]: https://codeclimate.com/github/intridea/multi_json
Lots of Ruby libraries parse JSON and everyone has their favorite JSON coder.
Instead of choosing a single JSON coder and forcing users of your library to be
stuck with it, you can use MultiJSON instead, which will simply choose the
fastest available JSON coder. Here's how to use it:
```ruby
require 'multi_json'
MultiJson.load('{"abc":"def"}') #=> {"abc" => "def"}
MultiJson.load('{"abc":"def"}', :symbolize_keys => true) #=> {:abc => "def"}
MultiJson.dump({:abc => 'def'}) # convert Ruby back to JSON
MultiJson.dump({:abc => 'def'}, :pretty => true) # encoded in a pretty form (if supported by the coder)
```
When loading invalid JSON, MultiJson will throw a `MultiJson::ParseError`. `MultiJson::DecodeError` and `MultiJson::LoadError` are aliases for backwards compatibility.
```ruby
begin
MultiJson.load('{invalid json}')
rescue MultiJson::ParseError => exception
exception.data # => "{invalid json}"
exception.cause # => JSON::ParserError: 795: unexpected token at '{invalid json}'
end
```
`ParseError` instance has `cause` reader which contains the original exception.
It also has `data` reader with the input that caused the problem.
The `use` method, which sets the MultiJson adapter, takes either a symbol or a
class (to allow for custom JSON parsers) that responds to both `.load` and `.dump`
at the class level.
When MultiJson fails to load the specified adapter, it'll throw `MultiJson::AdapterError`
which inherits from `ArgumentError`.
MultiJSON tries to have intelligent defaulting. That is, if you have any of the
supported engines already loaded, it will utilize them before attempting to
load any. When loading, libraries are ordered by speed. First Oj, then Yajl,
then the JSON gem, then JSON pure. If no other JSON library is available,
MultiJSON falls back to [OkJson][], a simple, vendorable JSON parser.
[okjson]: https://github.com/kr/okjson
## Supported JSON Engines
* [Oj](https://github.com/ohler55/oj) Optimized JSON by Peter Ohler
* [Yajl](https://github.com/brianmario/yajl-ruby) Yet Another JSON Library by Brian Lopez
* [JSON](https://github.com/flori/json) The default JSON gem with C-extensions (ships with Ruby 1.9)
* [JSON Pure](https://github.com/flori/json) A Ruby variant of the JSON gem
* [NSJSONSerialization](https://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html) Wrapper for Apple's NSJSONSerialization in the Cocoa Framework (MacRuby only)
* [gson.rb](https://github.com/avsej/gson.rb) A Ruby wrapper for google-gson library (JRuby only)
* [JrJackson](https://github.com/guyboertje/jrjackson) JRuby wrapper for Jackson (JRuby only)
* [OkJson][okjson] A simple, vendorable JSON parser
## Supported Ruby Versions
This library aims to support and is [tested against][travis] the following Ruby
implementations:
* Ruby 1.8.7
* Ruby 1.9.2
* Ruby 1.9.3
* Ruby 2.0.0
* Ruby 2.1.1
* [JRuby][]
* [Rubinius][]
* [MacRuby][] (not tested on Travis CI)
[jruby]: http://www.jruby.org/
[rubinius]: http://rubini.us/
[macruby]: http://www.macruby.org/
If something doesn't work on one of these interpreters, it's a bug.
This library may inadvertently work (or seem to work) on other Ruby
implementations, however support will only be provided for the versions listed
above.
If you would like this library to support another Ruby version, you may
volunteer to be a maintainer. Being a maintainer entails making sure all tests
run and pass on that implementation. When something breaks on your
implementation, you will be responsible for providing patches in a timely
fashion. If critical issues for a particular implementation exist at the time
of a major release, support for that Ruby version may be dropped.
## Versioning
This library aims to adhere to [Semantic Versioning 2.0.0][semver]. Violations
of this scheme should be reported as bugs. Specifically, if a minor or patch
version is released that breaks backward compatibility, that version should be
immediately yanked and/or a new version should be immediately released that
restores compatibility. Breaking changes to the public API will only be
introduced with new major versions. As a result of this policy, you can (and
should) specify a dependency on this gem using the [Pessimistic Version
Constraint][pvc] with two digits of precision. For example:
```ruby
spec.add_dependency 'multi_json', '~> 1.0'
```
[semver]: http://semver.org/
[pvc]: http://docs.rubygems.org/read/chapter/16#page74
## Copyright
Copyright (c) 2010-2013 Michael Bleigh, Josh Kalderimis, Erik Michaels-Ober,
and Pavel Pravosud. See [LICENSE][] for details.
[license]: LICENSE.md
multi_json-1.11.2/Rakefile 0000664 0000000 0000000 00000001324 12545704171 0015432 0 ustar 00root root 0000000 0000000 require 'bundler'
Bundler::GemHelper.install_tasks
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:base_spec) do |task|
task.pattern = 'spec/multi_json_spec.rb'
end
namespace :adapters do
Dir['spec/*_adapter_spec.rb'].each do |adapter_spec|
adapter_name = adapter_spec[/(\w+)_adapter_spec/, 1]
desc "Run #{adapter_name} adapter specs"
RSpec::Core::RakeTask.new(adapter_name) do |task|
task.pattern = adapter_spec
end
end
end
task :spec => %w[base_spec adapters:oj adapters:yajl adapters:json_gem adapters:json_pure adapters:ok_json adapters:gson adapters:jr_jackson adapters:nsjsonserialization]
task :default => :spec
task :test => :spec
require 'yard'
YARD::Rake::YardocTask.new
multi_json-1.11.2/certs/ 0000775 0000000 0000000 00000000000 12545704171 0015105 5 ustar 00root root 0000000 0000000 multi_json-1.11.2/certs/rwz.pem 0000664 0000000 0000000 00000002345 12545704171 0016436 0 ustar 00root root 0000000 0000000 -----BEGIN CERTIFICATE-----
MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQ4wDAYDVQQDDAVwYXZl
bDEYMBYGCgmSJomT8ixkARkWCHByYXZvc3VkMRMwEQYKCZImiZPyLGQBGRYDY29t
MB4XDTE1MDMwNDA0MTAzNVoXDTE2MDMwMzA0MTAzNVowPzEOMAwGA1UEAwwFcGF2
ZWwxGDAWBgoJkiaJk/IsZAEZFghwcmF2b3N1ZDETMBEGCgmSJomT8ixkARkWA2Nv
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKgJODgg1dH3weeyKtQF
mhC3C8gleHSTZYAt1pMBZQ6QmRD7/kLIfLTJB/zgFUVoNoHVZ8qyFmx89reqk5Z4
x/rIVskzpB76MushyaEJhw5UrxEZvoCK0b+nSUR8NT0YcznkjSbALBBagny5NWHn
98LbVtIQYXdJTgC8xvV1u2Bix1JI/Qv1wuDKCw14XF2AFmT4nPt40FEUk4zWwbGI
rdKjssA43TGDjzKmzdOpJ4aOble+Zq6N7jBacMdlsqQAvQ0bbGLokp8W7Ci/UNWC
Q8DwDrjlbURMu729T70yuswrQHyxmh7SISMmjp44+C5ElwVbfcCQQxiwsdAcE3zD
ST0CAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJ7X
Ly29ycziHHerLL3NCavLRSv5MB0GA1UdEQQWMBSBEnBhdmVsQHByYXZvc3VkLmNv
bTAdBgNVHRIEFjAUgRJwYXZlbEBwcmF2b3N1ZC5jb20wDQYJKoZIhvcNAQEFBQAD
ggEBAJM/D4S0IHFerw9xcEKR2sehNn9deQKsS7auR3wAtxEitrPzKZb+8Uy3KVqP
Jt/z5WABxO2Bjd7IM+s445lZF6kDsGsYYydlEkf9yzOYrtVmISTJYrsApU8BZQfL
bWJg8zt1qjAKmmwULsCiYOfIGhUIhKVdVKrlkdXFFCB5v8R124FZXjo43WXZ2OCp
4W7nHEaaaZLxrPnZCAiaryoFUL06d78sxq9F4MYfSD4CLdwJjNb5TOrwVAXK9uE9
88AJhXqiqrY/cm2sh/xcGvGkhy9YOMyMZZrCAq4ruaXAB+tAkMrJ1paJDJRgErvJ
8Vss1khfU5E/Xig1ytdFyNPPkCA=
-----END CERTIFICATE-----
multi_json-1.11.2/certs/sferik.pem 0000664 0000000 0000000 00000002214 12545704171 0017072 0 ustar 00root root 0000000 0000000 -----BEGIN CERTIFICATE-----
MIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQUFADA9MQ8wDQYDVQQDDAZzZmVy
aWsxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2NvbTAe
Fw0xMzAyMDMxMDAyMjdaFw0xNDAyMDMxMDAyMjdaMD0xDzANBgNVBAMMBnNmZXJp
azEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29tMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl0x5dx8uKxi7TkrIuyBUTJVB
v1o93nUB9j/y4M96gV2rYwAci1JPBseNd6Fybzjo3YGuHl7EQHuSHNaf1p2lxew/
y60JXIJBBgPcDK/KCP4NUHofm0jfoYD+H5uNJfHCNq7/ZsTxOtE3Ra92s0BCMTpm
wBMMlWR5MtdEhIYuBO4XhnejYgH0L/7BL2lymntVnsr/agdQoojQCN1IQmsRJvrR
duZRO3tZvoIo1pBc4JEehDuqCeyBgPLOqMoKtQlold1TQs1kWUBK7KWMFEhKC/Kg
zyzKRHQo9yDYwOvYngoBLY+T/lwCT4dyssdhzRbfnxAhaKu4SAssIwaC01yVowID
AQABozkwNzAJBgNVHRMEAjAAMB0GA1UdDgQWBBS0ruDfRak5ci1OpDNX/ZdDEkIs
iTALBgNVHQ8EBAMCBLAwDQYJKoZIhvcNAQEFBQADggEBAHHSMs/MP0sOaLkEv4Jo
zvkm3qn5A6t0vaHx774cmejyMU+5wySxRezspL7ULh9NeuK2OhU+Oe3TpqrAg5TK
R8GQILnVu2FemGA6sAkPDlcPtgA6ieI19PZOF6HVLmc/ID/dP/NgZWWzEeqQKmcK
2+HM+SEEDhZkScYekw4ZOe164ZtZG816oAv5x0pGitSIkumUp7V8iEZ/6ehr7Y9e
XOg4eeun5L/JjmjARoW2kNdvkRD3c2EeSLqWvQRsBlypHfhs6JJuLlyZPGhU3R/v
Sf3lVKpBCWgRpGTvy45XVpB+59y33PJmEuQ1PTEOYvQyao9UKMAAaAN/7qWQtjl0
hlw=
-----END CERTIFICATE-----
multi_json-1.11.2/lib/ 0000775 0000000 0000000 00000000000 12545704171 0014533 5 ustar 00root root 0000000 0000000 multi_json-1.11.2/lib/multi_json.rb 0000664 0000000 0000000 00000010036 12545704171 0017243 0 ustar 00root root 0000000 0000000 require 'multi_json/options'
require 'multi_json/version'
require 'multi_json/adapter_error'
require 'multi_json/parse_error'
module MultiJson
include Options
extend self
def default_options=(value)
Kernel.warn "MultiJson.default_options setter is deprecated\n" +
"Use MultiJson.load_options and MultiJson.dump_options instead"
self.load_options = self.dump_options = value
end
def default_options
Kernel.warn "MultiJson.default_options is deprecated\n" +
"Use MultiJson.load_options or MultiJson.dump_options instead"
self.load_options
end
%w[cached_options reset_cached_options!].each do |method_name|
define_method method_name do |*|
Kernel.warn "MultiJson.#{method_name} method is deprecated and no longer used."
end
end
ALIASES = { 'jrjackson' => 'jr_jackson' }
REQUIREMENT_MAP = [
['oj', :oj],
['yajl', :yajl],
['jrjackson', :jr_jackson],
['json/ext', :json_gem],
['gson', :gson],
['json/pure', :json_pure]
]
# The default adapter based on what you currently
# have loaded and installed. First checks to see
# if any adapters are already loaded, then checks
# to see which are installed if none are loaded.
def default_adapter
return :oj if defined?(::Oj)
return :yajl if defined?(::Yajl)
return :jr_jackson if defined?(::JrJackson)
return :json_gem if defined?(::JSON::JSON_LOADED)
return :gson if defined?(::Gson)
REQUIREMENT_MAP.each do |library, adapter|
begin
require library
return adapter
rescue ::LoadError
next
end
end
Kernel.warn '[WARNING] MultiJson is using the default adapter (ok_json).' +
'We recommend loading a different JSON library to improve performance.'
:ok_json
end
alias default_engine default_adapter
# Get the current adapter class.
def adapter
return @adapter if defined?(@adapter) && @adapter
self.use nil # load default adapter
@adapter
end
alias engine adapter
# Set the JSON parser utilizing a symbol, string, or class.
# Supported by default are:
#
# * :oj
# * :json_gem
# * :json_pure
# * :ok_json
# * :yajl
# * :nsjsonserialization (MacRuby only)
# * :gson (JRuby only)
# * :jr_jackson (JRuby only)
def use(new_adapter)
@adapter = load_adapter(new_adapter)
end
alias adapter= use
alias engine= use
def load_adapter(new_adapter)
case new_adapter
when String, Symbol
load_adapter_from_string_name new_adapter.to_s
when NilClass, FalseClass
load_adapter default_adapter
when Class, Module
new_adapter
else
raise ::LoadError, new_adapter
end
rescue ::LoadError => exception
raise AdapterError.build(exception)
end
# Decode a JSON string into Ruby.
#
# Options
#
# :symbolize_keys :: If true, will use symbols instead of strings for the keys.
# :adapter :: If set, the selected adapter will be used for this call.
def load(string, options={})
adapter = current_adapter(options)
begin
adapter.load(string, options)
rescue adapter::ParseError => exception
raise ParseError.build(exception, string)
end
end
alias decode load
def current_adapter(options={})
if new_adapter = options[:adapter]
load_adapter(new_adapter)
else
adapter
end
end
# Encodes a Ruby object as JSON.
def dump(object, options={})
current_adapter(options).dump(object, options)
end
alias encode dump
# Executes passed block using specified adapter.
def with_adapter(new_adapter)
old_adapter, self.adapter = adapter, new_adapter
yield
ensure
self.adapter = old_adapter
end
alias with_engine with_adapter
private
def load_adapter_from_string_name(name)
name = ALIASES.fetch(name, name)
require "multi_json/adapters/#{name.downcase}"
klass_name = name.to_s.split('_').map(&:capitalize) * ''
MultiJson::Adapters.const_get(klass_name)
end
end
multi_json-1.11.2/lib/multi_json/ 0000775 0000000 0000000 00000000000 12545704171 0016716 5 ustar 00root root 0000000 0000000 multi_json-1.11.2/lib/multi_json/adapter.rb 0000664 0000000 0000000 00000001654 12545704171 0020671 0 ustar 00root root 0000000 0000000 require 'singleton'
require 'multi_json/options'
module MultiJson
class Adapter
extend Options
include Singleton
class << self
def defaults(action, value)
metaclass = class << self; self; end
metaclass.instance_eval do
define_method("default_#{action}_options"){ value }
end
end
def load(string, options={})
raise self::ParseError if blank?(string)
string = string.read if string.respond_to?(:read)
instance.load(string, load_options(options).merge(MultiJson.load_options(options)).merge!(options))
end
def dump(object, options={})
instance.dump(object, dump_options(options).merge(MultiJson.dump_options(options)).merge!(options))
end
private
def blank?(input)
input.nil? || /\A\s*\z/ === input
rescue ArgumentError # invalid byte sequence in UTF-8
false
end
end
end
end
multi_json-1.11.2/lib/multi_json/adapter_error.rb 0000664 0000000 0000000 00000000641 12545704171 0022075 0 ustar 00root root 0000000 0000000 module MultiJson
class AdapterError < ArgumentError
attr_reader :cause
def self.build(original_exception)
message = "Did not recognize your adapter specification (#{original_exception.message})."
new(message).tap do |exception|
exception.instance_eval do
@cause = original_exception
set_backtrace original_exception.backtrace
end
end
end
end
end
multi_json-1.11.2/lib/multi_json/adapters/ 0000775 0000000 0000000 00000000000 12545704171 0020521 5 ustar 00root root 0000000 0000000 multi_json-1.11.2/lib/multi_json/adapters/gson.rb 0000664 0000000 0000000 00000000645 12545704171 0022021 0 ustar 00root root 0000000 0000000 require 'gson'
require 'stringio'
require 'multi_json/adapter'
module MultiJson
module Adapters
# Use the gson.rb library to dump/load.
class Gson < Adapter
ParseError = ::Gson::DecodeError
def load(string, options={})
::Gson::Decoder.new(options).decode(string)
end
def dump(object, options={})
::Gson::Encoder.new(options).encode(object)
end
end
end
end
multi_json-1.11.2/lib/multi_json/adapters/jr_jackson.rb 0000664 0000000 0000000 00000001143 12545704171 0023170 0 ustar 00root root 0000000 0000000 require 'jrjackson' unless defined?(::JrJackson)
require 'multi_json/adapter'
module MultiJson
module Adapters
# Use the jrjackson.rb library to dump/load.
class JrJackson < Adapter
ParseError = ::JrJackson::ParseError
def load(string, options={}) #:nodoc:
::JrJackson::Json.load(string, options)
end
if ::JrJackson::Json.method(:dump).arity == 1
def dump(object, _)
::JrJackson::Json.dump(object)
end
else
def dump(object, options={})
::JrJackson::Json.dump(object, options)
end
end
end
end
end
multi_json-1.11.2/lib/multi_json/adapters/json_common.rb 0000664 0000000 0000000 00000001177 12545704171 0023375 0 ustar 00root root 0000000 0000000 require 'multi_json/adapter'
module MultiJson
module Adapters
class JsonCommon < Adapter
defaults :load, :create_additions => false, :quirks_mode => true
def load(string, options={})
if string.respond_to?(:force_encoding)
string = string.dup.force_encoding(::Encoding::ASCII_8BIT)
end
options[:symbolize_names] = true if options.delete(:symbolize_keys)
::JSON.parse(string, options)
end
def dump(object, options={})
options.merge!(::JSON::PRETTY_STATE_PROTOTYPE.to_h) if options.delete(:pretty)
object.to_json(options)
end
end
end
end
multi_json-1.11.2/lib/multi_json/adapters/json_gem.rb 0000664 0000000 0000000 00000000336 12545704171 0022651 0 ustar 00root root 0000000 0000000 require 'json/ext'
require 'multi_json/adapters/json_common'
module MultiJson
module Adapters
# Use the JSON gem to dump/load.
class JsonGem < JsonCommon
ParseError = ::JSON::ParserError
end
end
end
multi_json-1.11.2/lib/multi_json/adapters/json_pure.rb 0000664 0000000 0000000 00000000335 12545704171 0023053 0 ustar 00root root 0000000 0000000 require 'json/pure'
require 'multi_json/adapters/json_common'
module MultiJson
module Adapters
# Use JSON pure to dump/load.
class JsonPure < JsonCommon
ParseError = ::JSON::ParserError
end
end
end
multi_json-1.11.2/lib/multi_json/adapters/nsjsonserialization.rb 0000664 0000000 0000000 00000002124 12545704171 0025155 0 ustar 00root root 0000000 0000000 framework 'Foundation'
require 'multi_json/adapters/ok_json'
module MultiJson
module Adapters
class Nsjsonserialization < MultiJson::Adapters::OkJson
ParseError = ::MultiJson::OkJson::Error
def load(string, options={})
data = string.dataUsingEncoding(NSUTF8StringEncoding)
object = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves, error: nil)
if object
object = symbolize_keys(object) if options[:symbolize_keys]
object
else
super(string, options={})
end
end
def dump(object, options={})
pretty = options[:pretty] ? NSJSONWritingPrettyPrinted : 0
object = object.as_json if object.respond_to?(:as_json)
if NSJSONSerialization.isValidJSONObject(object)
data = NSJSONSerialization.dataWithJSONObject(object, options: pretty, error: nil)
NSMutableString.alloc.initWithData(data, encoding: NSUTF8StringEncoding)
else
super(object, options)
end
end
end
end
end
multi_json-1.11.2/lib/multi_json/adapters/oj.rb 0000664 0000000 0000000 00000001343 12545704171 0021457 0 ustar 00root root 0000000 0000000 require 'oj'
require 'multi_json/adapter'
module MultiJson
module Adapters
# Use the Oj library to dump/load.
class Oj < Adapter
defaults :load, :mode => :strict, :symbolize_keys => false
defaults :dump, :mode => :compat, :time_format => :ruby, :use_to_json => true
ParseError = defined?(::Oj::ParseError) ? ::Oj::ParseError : SyntaxError
def load(string, options={})
options[:symbol_keys] = options.delete(:symbolize_keys)
::Oj.load(string, options)
end
def dump(object, options={})
options.merge!(:indent => 2) if options[:pretty]
options[:indent] = options[:indent].to_i if options[:indent]
::Oj.dump(object, options)
end
end
end
end
multi_json-1.11.2/lib/multi_json/adapters/ok_json.rb 0000664 0000000 0000000 00000001174 12545704171 0022513 0 ustar 00root root 0000000 0000000 require 'multi_json/adapter'
require 'multi_json/convertible_hash_keys'
require 'multi_json/vendor/okjson'
module MultiJson
module Adapters
class OkJson < Adapter
include ConvertibleHashKeys
ParseError = ::MultiJson::OkJson::Error
def load(string, options={})
result = ::MultiJson::OkJson.decode("[#{string}]").first
options[:symbolize_keys] ? symbolize_keys(result) : result
rescue ArgumentError # invalid byte sequence in UTF-8
raise ParseError
end
def dump(object, options={})
::MultiJson::OkJson.valenc(stringify_keys(object))
end
end
end
end
multi_json-1.11.2/lib/multi_json/adapters/yajl.rb 0000664 0000000 0000000 00000000661 12545704171 0022010 0 ustar 00root root 0000000 0000000 require 'yajl'
require 'multi_json/adapter'
module MultiJson
module Adapters
# Use the Yajl-Ruby library to dump/load.
class Yajl < Adapter
ParseError = ::Yajl::ParseError
def load(string, options={})
::Yajl::Parser.new(:symbolize_keys => options[:symbolize_keys]).parse(string)
end
def dump(object, options={})
::Yajl::Encoder.encode(object, options)
end
end
end
end
multi_json-1.11.2/lib/multi_json/convertible_hash_keys.rb 0000664 0000000 0000000 00000001742 12545704171 0023621 0 ustar 00root root 0000000 0000000 module MultiJson
module ConvertibleHashKeys
private
def symbolize_keys(hash)
prepare_hash(hash) do |key|
key.respond_to?(:to_sym) ? key.to_sym : key
end
end
def stringify_keys(hash)
prepare_hash(hash) do |key|
key.respond_to?(:to_s) ? key.to_s : key
end
end
def prepare_hash(hash, &key_modifier)
return hash unless block_given?
case hash
when Array
hash.map do |value|
prepare_hash(value, &key_modifier)
end
when Hash
hash.inject({}) do |result, (key, value)|
new_key = key_modifier.call(key)
new_value = prepare_hash(value, &key_modifier)
result.merge! new_key => new_value
end
when String, Numeric, true, false, nil
hash
else
if hash.respond_to?(:to_json)
hash
elsif hash.respond_to?(:to_s)
hash.to_s
else
hash
end
end
end
end
end
multi_json-1.11.2/lib/multi_json/options.rb 0000664 0000000 0000000 00000001522 12545704171 0020736 0 ustar 00root root 0000000 0000000 module MultiJson
module Options
def load_options=(options)
@load_options = options
end
def dump_options=(options)
@dump_options = options
end
def load_options(*args)
defined?(@load_options) && get_options(@load_options, *args) || default_load_options
end
def dump_options(*args)
defined?(@dump_options) && get_options(@dump_options, *args) || default_dump_options
end
def default_load_options
@default_load_options ||= {}
end
def default_dump_options
@default_dump_options ||= {}
end
private
def get_options(options, *args)
if options.respond_to?(:call) and options.arity
options.arity == 0 ? options[] : options[*args]
elsif Hash === options or options.respond_to?(:to_hash)
options.to_hash
end
end
end
end
multi_json-1.11.2/lib/multi_json/parse_error.rb 0000664 0000000 0000000 00000000657 12545704171 0021576 0 ustar 00root root 0000000 0000000 module MultiJson
class ParseError < StandardError
attr_reader :data, :cause
def self.build(original_exception, data)
new(original_exception.message).tap do |exception|
exception.instance_eval do
@cause = original_exception
set_backtrace original_exception.backtrace
@data = data
end
end
end
end
DecodeError = LoadError = ParseError # Legacy support
end
multi_json-1.11.2/lib/multi_json/vendor/ 0000775 0000000 0000000 00000000000 12545704171 0020213 5 ustar 00root root 0000000 0000000 multi_json-1.11.2/lib/multi_json/vendor/okjson.rb 0000664 0000000 0000000 00000035512 12545704171 0022051 0 ustar 00root root 0000000 0000000 # encoding: UTF-8
#
# Copyright 2011, 2012 Keith Rarick
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# See https://github.com/kr/okjson for updates.
require 'stringio'
module MultiJson
# Some parts adapted from
# http://golang.org/src/pkg/json/decode.go and
# http://golang.org/src/pkg/utf8/utf8.go
module OkJson
Upstream = '43'
extend self
# Decodes a json document in string s and
# returns the corresponding ruby value.
# String s must be valid UTF-8. If you have
# a string in some other encoding, convert
# it first.
#
# String values in the resulting structure
# will be UTF-8.
def decode(s)
ts = lex(s)
v, ts = textparse(ts)
if ts.length > 0
raise Error, 'trailing garbage'
end
v
end
# Encodes x into a json text. It may contain only
# Array, Hash, String, Numeric, true, false, nil.
# (Note, this list excludes Symbol.)
# X itself must be an Array or a Hash.
# No other value can be encoded, and an error will
# be raised if x contains any other value, such as
# Nan, Infinity, Symbol, and Proc, or if a Hash key
# is not a String.
# Strings contained in x must be valid UTF-8.
def encode(x)
case x
when Hash then objenc(x)
when Array then arrenc(x)
else
raise Error, 'root value must be an Array or a Hash'
end
end
def valenc(x)
case x
when Hash then objenc(x)
when Array then arrenc(x)
when String then strenc(x)
when Numeric then numenc(x)
when true then "true"
when false then "false"
when nil then "null"
else
if x.respond_to?(:to_json)
x.to_json
else
raise Error, "cannot encode #{x.class}: #{x.inspect}"
end
end
end
private
# Parses a "json text" in the sense of RFC 4627.
# Returns the parsed value and any trailing tokens.
# Note: this is almost the same as valparse,
# except that it does not accept atomic values.
def textparse(ts)
if ts.length <= 0
raise Error, 'empty'
end
typ, _, val = ts[0]
case typ
when '{' then objparse(ts)
when '[' then arrparse(ts)
else
raise Error, "unexpected #{val.inspect}"
end
end
# Parses a "value" in the sense of RFC 4627.
# Returns the parsed value and any trailing tokens.
def valparse(ts)
if ts.length <= 0
raise Error, 'empty'
end
typ, _, val = ts[0]
case typ
when '{' then objparse(ts)
when '[' then arrparse(ts)
when :val,:str then [val, ts[1..-1]]
else
raise Error, "unexpected #{val.inspect}"
end
end
# Parses an "object" in the sense of RFC 4627.
# Returns the parsed value and any trailing tokens.
def objparse(ts)
ts = eat('{', ts)
obj = {}
if ts[0][0] == '}'
return obj, ts[1..-1]
end
k, v, ts = pairparse(ts)
obj[k] = v
if ts[0][0] == '}'
return obj, ts[1..-1]
end
loop do
ts = eat(',', ts)
k, v, ts = pairparse(ts)
obj[k] = v
if ts[0][0] == '}'
return obj, ts[1..-1]
end
end
end
# Parses a "member" in the sense of RFC 4627.
# Returns the parsed values and any trailing tokens.
def pairparse(ts)
(typ, _, k), ts = ts[0], ts[1..-1]
if typ != :str
raise Error, "unexpected #{k.inspect}"
end
ts = eat(':', ts)
v, ts = valparse(ts)
[k, v, ts]
end
# Parses an "array" in the sense of RFC 4627.
# Returns the parsed value and any trailing tokens.
def arrparse(ts)
ts = eat('[', ts)
arr = []
if ts[0][0] == ']'
return arr, ts[1..-1]
end
v, ts = valparse(ts)
arr << v
if ts[0][0] == ']'
return arr, ts[1..-1]
end
loop do
ts = eat(',', ts)
v, ts = valparse(ts)
arr << v
if ts[0][0] == ']'
return arr, ts[1..-1]
end
end
end
def eat(typ, ts)
if ts[0][0] != typ
raise Error, "expected #{typ} (got #{ts[0].inspect})"
end
ts[1..-1]
end
# Scans s and returns a list of json tokens,
# excluding white space (as defined in RFC 4627).
def lex(s)
ts = []
while s.length > 0
typ, lexeme, val = tok(s)
if typ == nil
raise Error, "invalid character at #{s[0,10].inspect}"
end
if typ != :space
ts << [typ, lexeme, val]
end
s = s[lexeme.length..-1]
end
ts
end
# Scans the first token in s and
# returns a 3-element list, or nil
# if s does not begin with a valid token.
#
# The first list element is one of
# '{', '}', ':', ',', '[', ']',
# :val, :str, and :space.
#
# The second element is the lexeme.
#
# The third element is the value of the
# token for :val and :str, otherwise
# it is the lexeme.
def tok(s)
case s[0]
when ?{ then ['{', s[0,1], s[0,1]]
when ?} then ['}', s[0,1], s[0,1]]
when ?: then [':', s[0,1], s[0,1]]
when ?, then [',', s[0,1], s[0,1]]
when ?[ then ['[', s[0,1], s[0,1]]
when ?] then [']', s[0,1], s[0,1]]
when ?n then nulltok(s)
when ?t then truetok(s)
when ?f then falsetok(s)
when ?" then strtok(s)
when Spc, ?\t, ?\n, ?\r then [:space, s[0,1], s[0,1]]
else
numtok(s)
end
end
def nulltok(s); s[0,4] == 'null' ? [:val, 'null', nil] : [] end
def truetok(s); s[0,4] == 'true' ? [:val, 'true', true] : [] end
def falsetok(s); s[0,5] == 'false' ? [:val, 'false', false] : [] end
def numtok(s)
m = /-?([1-9][0-9]+|[0-9])([.][0-9]+)?([eE][+-]?[0-9]+)?/.match(s)
if m && m.begin(0) == 0
if !m[2] && !m[3]
[:val, m[0], Integer(m[0])]
elsif m[2]
[:val, m[0], Float(m[0])]
else
[:val, m[0], Integer(m[1])*(10**Integer(m[3][1..-1]))]
end
else
[]
end
end
def strtok(s)
m = /"([^"\\]|\\["\/\\bfnrt]|\\u[0-9a-fA-F]{4})*"/.match(s)
if ! m
raise Error, "invalid string literal at #{abbrev(s)}"
end
[:str, m[0], unquote(m[0])]
end
def abbrev(s)
t = s[0,10]
p = t['`']
t = t[0,p] if p
t = t + '...' if t.length < s.length
'`' + t + '`'
end
# Converts a quoted json string literal q into a UTF-8-encoded string.
# The rules are different than for Ruby, so we cannot use eval.
# Unquote will raise an error if q contains control characters.
def unquote(q)
q = q[1...-1]
a = q.dup # allocate a big enough string
# In ruby >= 1.9, a[w] is a codepoint, not a byte.
if rubydoesenc?
a.force_encoding('UTF-8')
end
r, w = 0, 0
while r < q.length
c = q[r]
if c == ?\\
r += 1
if r >= q.length
raise Error, "string literal ends with a \"\\\": \"#{q}\""
end
case q[r]
when ?",?\\,?/,?'
a[w] = q[r]
r += 1
w += 1
when ?b,?f,?n,?r,?t
a[w] = Unesc[q[r]]
r += 1
w += 1
when ?u
r += 1
uchar = begin
hexdec4(q[r,4])
rescue RuntimeError => e
raise Error, "invalid escape sequence \\u#{q[r,4]}: #{e}"
end
r += 4
if surrogate? uchar
if q.length >= r+6
uchar1 = hexdec4(q[r+2,4])
uchar = subst(uchar, uchar1)
if uchar != Ucharerr
# A valid pair; consume.
r += 6
end
end
end
if rubydoesenc?
a[w] = '' << uchar
w += 1
else
w += ucharenc(a, w, uchar)
end
else
raise Error, "invalid escape char #{q[r]} in \"#{q}\""
end
elsif c == ?" || c < Spc
raise Error, "invalid character in string literal \"#{q}\""
else
# Copy anything else byte-for-byte.
# Valid UTF-8 will remain valid UTF-8.
# Invalid UTF-8 will remain invalid UTF-8.
# In ruby >= 1.9, c is a codepoint, not a byte,
# in which case this is still what we want.
a[w] = c
r += 1
w += 1
end
end
a[0,w]
end
# Encodes unicode character u as UTF-8
# bytes in string a at position i.
# Returns the number of bytes written.
def ucharenc(a, i, u)
if u <= Uchar1max
a[i] = (u & 0xff).chr
1
elsif u <= Uchar2max
a[i+0] = (Utag2 | ((u>>6)&0xff)).chr
a[i+1] = (Utagx | (u&Umaskx)).chr
2
elsif u <= Uchar3max
a[i+0] = (Utag3 | ((u>>12)&0xff)).chr
a[i+1] = (Utagx | ((u>>6)&Umaskx)).chr
a[i+2] = (Utagx | (u&Umaskx)).chr
3
else
a[i+0] = (Utag4 | ((u>>18)&0xff)).chr
a[i+1] = (Utagx | ((u>>12)&Umaskx)).chr
a[i+2] = (Utagx | ((u>>6)&Umaskx)).chr
a[i+3] = (Utagx | (u&Umaskx)).chr
4
end
end
def hexdec4(s)
if s.length != 4
raise Error, 'short'
end
(nibble(s[0])<<12) | (nibble(s[1])<<8) | (nibble(s[2])<<4) | nibble(s[3])
end
def subst(u1, u2)
if Usurr1 <= u1 && u1 < Usurr2 && Usurr2 <= u2 && u2 < Usurr3
return ((u1-Usurr1)<<10) | (u2-Usurr2) + Usurrself
end
return Ucharerr
end
def surrogate?(u)
Usurr1 <= u && u < Usurr3
end
def nibble(c)
if ?0 <= c && c <= ?9 then c.ord - ?0.ord
elsif ?a <= c && c <= ?z then c.ord - ?a.ord + 10
elsif ?A <= c && c <= ?Z then c.ord - ?A.ord + 10
else
raise Error, "invalid hex code #{c}"
end
end
def objenc(x)
'{' + x.map{|k,v| keyenc(k) + ':' + valenc(v)}.join(',') + '}'
end
def arrenc(a)
'[' + a.map{|x| valenc(x)}.join(',') + ']'
end
def keyenc(k)
case k
when String then strenc(k)
else
raise Error, "Hash key is not a string: #{k.inspect}"
end
end
def strenc(s)
t = StringIO.new
t.putc(?")
r = 0
while r < s.length
case s[r]
when ?" then t.print('\\"')
when ?\\ then t.print('\\\\')
when ?\b then t.print('\\b')
when ?\f then t.print('\\f')
when ?\n then t.print('\\n')
when ?\r then t.print('\\r')
when ?\t then t.print('\\t')
else
c = s[r]
# In ruby >= 1.9, s[r] is a codepoint, not a byte.
if rubydoesenc?
begin
# c.ord will raise an error if c is invalid UTF-8
if c.ord < Spc.ord
c = "\\u%04x" % [c.ord]
end
t.write(c)
rescue
t.write(Ustrerr)
end
elsif c < Spc
t.write("\\u%04x" % c)
elsif Spc <= c && c <= ?~
t.putc(c)
else
n = ucharcopy(t, s, r) # ensure valid UTF-8 output
r += n - 1 # r is incremented below
end
end
r += 1
end
t.putc(?")
t.string
end
def numenc(x)
if ((x.nan? || x.infinite?) rescue false)
raise Error, "Numeric cannot be represented: #{x}"
end
"#{x}"
end
# Copies the valid UTF-8 bytes of a single character
# from string s at position i to I/O object t, and
# returns the number of bytes copied.
# If no valid UTF-8 char exists at position i,
# ucharcopy writes Ustrerr and returns 1.
def ucharcopy(t, s, i)
n = s.length - i
raise Utf8Error if n < 1
c0 = s[i].ord
# 1-byte, 7-bit sequence?
if c0 < Utagx
t.putc(c0)
return 1
end
raise Utf8Error if c0 < Utag2 # unexpected continuation byte?
raise Utf8Error if n < 2 # need continuation byte
c1 = s[i+1].ord
raise Utf8Error if c1 < Utagx || Utag2 <= c1
# 2-byte, 11-bit sequence?
if c0 < Utag3
raise Utf8Error if ((c0&Umask2)<<6 | (c1&Umaskx)) <= Uchar1max
t.putc(c0)
t.putc(c1)
return 2
end
# need second continuation byte
raise Utf8Error if n < 3
c2 = s[i+2].ord
raise Utf8Error if c2 < Utagx || Utag2 <= c2
# 3-byte, 16-bit sequence?
if c0 < Utag4
u = (c0&Umask3)<<12 | (c1&Umaskx)<<6 | (c2&Umaskx)
raise Utf8Error if u <= Uchar2max
t.putc(c0)
t.putc(c1)
t.putc(c2)
return 3
end
# need third continuation byte
raise Utf8Error if n < 4
c3 = s[i+3].ord
raise Utf8Error if c3 < Utagx || Utag2 <= c3
# 4-byte, 21-bit sequence?
if c0 < Utag5
u = (c0&Umask4)<<18 | (c1&Umaskx)<<12 | (c2&Umaskx)<<6 | (c3&Umaskx)
raise Utf8Error if u <= Uchar3max
t.putc(c0)
t.putc(c1)
t.putc(c2)
t.putc(c3)
return 4
end
raise Utf8Error
rescue Utf8Error
t.write(Ustrerr)
return 1
end
def rubydoesenc?
::String.method_defined?(:force_encoding)
end
class Utf8Error < ::StandardError
end
class Error < ::StandardError
end
Utagx = 0b1000_0000
Utag2 = 0b1100_0000
Utag3 = 0b1110_0000
Utag4 = 0b1111_0000
Utag5 = 0b1111_1000
Umaskx = 0b0011_1111
Umask2 = 0b0001_1111
Umask3 = 0b0000_1111
Umask4 = 0b0000_0111
Uchar1max = (1<<7) - 1
Uchar2max = (1<<11) - 1
Uchar3max = (1<<16) - 1
Ucharerr = 0xFFFD # unicode "replacement char"
Ustrerr = "\xef\xbf\xbd" # unicode "replacement char"
Usurrself = 0x10000
Usurr1 = 0xd800
Usurr2 = 0xdc00
Usurr3 = 0xe000
Spc = ' '[0]
Unesc = {?b=>?\b, ?f=>?\f, ?n=>?\n, ?r=>?\r, ?t=>?\t}
end
end
multi_json-1.11.2/lib/multi_json/version.rb 0000664 0000000 0000000 00000000663 12545704171 0020735 0 ustar 00root root 0000000 0000000 module MultiJson
class Version
MAJOR = 1 unless defined? MultiJson::Version::MAJOR
MINOR = 11 unless defined? MultiJson::Version::MINOR
PATCH = 2 unless defined? MultiJson::Version::PATCH
PRE = nil unless defined? MultiJson::Version::PRE
class << self
# @return [String]
def to_s
[MAJOR, MINOR, PATCH, PRE].compact.join('.')
end
end
end
VERSION = Version.to_s.freeze
end
multi_json-1.11.2/multi_json.gemspec 0000664 0000000 0000000 00000002202 12545704171 0017511 0 ustar 00root root 0000000 0000000 # coding: utf-8
require File.expand_path("../lib/multi_json/version.rb", __FILE__)
Gem::Specification.new do |spec|
spec.authors = ["Michael Bleigh", "Josh Kalderimis", "Erik Michaels-Ober", "Pavel Pravosud"]
spec.cert_chain = %w[certs/rwz.pem]
spec.summary = "A common interface to multiple JSON libraries."
spec.description = "A common interface to multiple JSON libraries, including Oj, Yajl, the JSON gem (with C-extensions), the pure-Ruby JSON gem, NSJSONSerialization, gson.rb, JrJackson, and OkJson."
spec.email = %w[michael@intridea.com josh.kalderimis@gmail.com sferik@gmail.com pavel@pravosud.com]
spec.files = Dir["CHANGELOG.md", "CONTRIBUTING.md", "LICENSE.md", "README.md", "multi_json.gemspec", "lib/**/*"]
spec.homepage = "http://github.com/intridea/multi_json"
spec.license = "MIT"
spec.name = "multi_json"
spec.require_path = "lib"
spec.signing_key = File.expand_path("~/.gem/private_key.pem") if $0 =~ /gem\z/
spec.version = MultiJson::Version
spec.required_rubygems_version = ">= 1.3.5"
spec.add_development_dependency "bundler", "~> 1.0"
end
multi_json-1.11.2/spec/ 0000775 0000000 0000000 00000000000 12545704171 0014717 5 ustar 00root root 0000000 0000000 multi_json-1.11.2/spec/gson_adapter_spec.rb 0000664 0000000 0000000 00000000307 12545704171 0020724 0 ustar 00root root 0000000 0000000 require 'spec_helper'
exit true unless jruby?
require 'shared/adapter'
require 'multi_json/adapters/gson'
describe MultiJson::Adapters::Gson do
it_behaves_like 'an adapter', described_class
end
multi_json-1.11.2/spec/jr_jackson_adapter_spec.rb 0000664 0000000 0000000 00000000321 12545704171 0022075 0 ustar 00root root 0000000 0000000 require 'spec_helper'
exit true unless jruby?
require 'shared/adapter'
require 'multi_json/adapters/jr_jackson'
describe MultiJson::Adapters::JrJackson do
it_behaves_like 'an adapter', described_class
end multi_json-1.11.2/spec/json_gem_adapter_spec.rb 0000664 0000000 0000000 00000000417 12545704171 0021561 0 ustar 00root root 0000000 0000000 require 'spec_helper'
require 'shared/adapter'
require 'shared/json_common_adapter'
require 'multi_json/adapters/json_gem'
describe MultiJson::Adapters::JsonGem do
it_behaves_like 'an adapter', described_class
it_behaves_like 'JSON-like adapter', described_class
end multi_json-1.11.2/spec/json_pure_adapter_spec.rb 0000664 0000000 0000000 00000000421 12545704171 0021757 0 ustar 00root root 0000000 0000000 require 'spec_helper'
require 'shared/adapter'
require 'shared/json_common_adapter'
require 'multi_json/adapters/json_pure'
describe MultiJson::Adapters::JsonPure do
it_behaves_like 'an adapter', described_class
it_behaves_like 'JSON-like adapter', described_class
end multi_json-1.11.2/spec/multi_json_spec.rb 0000664 0000000 0000000 00000014226 12545704171 0020446 0 ustar 00root root 0000000 0000000 require 'spec_helper'
require 'shared/options'
describe MultiJson do
before(:all) do
# make sure all available libs are required
MultiJson::REQUIREMENT_MAP.each do |library, adapter|
begin
require library
rescue ::LoadError
next
end
end
end
context 'when no other json implementations are available' do
around do |example|
simulate_no_adapters{ example.call }
end
it 'defaults to ok_json if no other json implementions are available' do
silence_warnings do
expect(MultiJson.default_adapter).to eq(:ok_json)
end
end
it 'prints a warning' do
expect(Kernel).to receive(:warn).with(/warning/i)
MultiJson.default_adapter
end
end
context 'caching' do
before{ MultiJson.use adapter }
let(:adapter){ MultiJson::Adapters::JsonGem }
let(:json_string){ '{"abc":"def"}' }
it 'busts caches on global options change' do
MultiJson.load_options = { :symbolize_keys => true }
expect(MultiJson.load(json_string)).to eq(:abc => 'def')
MultiJson.load_options = nil
expect(MultiJson.load(json_string)).to eq('abc' => 'def')
end
it 'busts caches on per-adapter options change' do
adapter.load_options = { :symbolize_keys => true }
expect(MultiJson.load(json_string)).to eq(:abc => 'def')
adapter.load_options = nil
expect(MultiJson.load(json_string)).to eq('abc' => 'def')
end
end
it 'defaults to the best available gem' do
# Clear cache variable already set by previous tests
MultiJson.send(:remove_instance_variable, :@adapter) if MultiJson.instance_variable_defined?(:@adapter)
if jruby?
expect(MultiJson.adapter.to_s).to eq('MultiJson::Adapters::JrJackson')
else
expect(MultiJson.adapter.to_s).to eq('MultiJson::Adapters::Oj')
end
end
it 'looks for adapter even if @adapter variable is nil' do
MultiJson.send(:instance_variable_set, :@adapter, nil)
expect(MultiJson).to receive(:default_adapter).and_return(:ok_json)
expect(MultiJson.adapter).to eq(MultiJson::Adapters::OkJson)
end
it 'is settable via a symbol' do
MultiJson.use :json_gem
expect(MultiJson.adapter).to eq(MultiJson::Adapters::JsonGem)
end
it 'is settable via a case-insensitive string' do
MultiJson.use 'Json_Gem'
expect(MultiJson.adapter).to eq(MultiJson::Adapters::JsonGem)
end
it 'is settable via a class' do
adapter = Class.new
MultiJson.use adapter
expect(MultiJson.adapter).to eq(adapter)
end
it 'is settable via a module' do
adapter = Module.new
MultiJson.use adapter
expect(MultiJson.adapter).to eq(adapter)
end
it 'throws AdapterError on bad input' do
expect{ MultiJson.use 'bad adapter' }.to raise_error(MultiJson::AdapterError, /bad adapter/)
end
it 'gives access to original error when raising AdapterError' do
exception = get_exception(MultiJson::AdapterError){ MultiJson.use 'foobar' }
expect(exception.cause).to be_instance_of(::LoadError)
expect(exception.message).to include("-- multi_json/adapters/foobar")
expect(exception.message).to include("Did not recognize your adapter specification")
end
context 'using one-shot parser' do
before do
expect(MultiJson::Adapters::JsonPure).to receive(:dump).once.and_return('dump_something')
expect(MultiJson::Adapters::JsonPure).to receive(:load).once.and_return('load_something')
end
it 'should use the defined parser just for the call' do
MultiJson.use :json_gem
expect(MultiJson.dump('', :adapter => :json_pure)).to eq('dump_something')
expect(MultiJson.load('', :adapter => :json_pure)).to eq('load_something')
expect(MultiJson.adapter).to eq(MultiJson::Adapters::JsonGem)
end
end
it 'can set adapter for a block' do
MultiJson.use :ok_json
MultiJson.with_adapter(:json_pure) do
MultiJson.with_engine(:json_gem) do
expect(MultiJson.adapter).to eq(MultiJson::Adapters::JsonGem)
end
expect(MultiJson.adapter).to eq(MultiJson::Adapters::JsonPure)
end
expect(MultiJson.adapter).to eq(MultiJson::Adapters::OkJson)
end
it 'JSON gem does not create symbols on parse' do
MultiJson.with_engine(:json_gem) do
MultiJson.load('{"json_class":"ZOMG"}') rescue nil
expect{
MultiJson.load('{"json_class":"OMG"}') rescue nil
}.to_not change{Symbol.all_symbols.count}
end
end
unless jruby?
it 'Oj does not create symbols on parse' do
MultiJson.with_engine(:oj) do
MultiJson.load('{"json_class":"ZOMG"}') rescue nil
expect{
MultiJson.load('{"json_class":"OMG"}') rescue nil
}.to_not change{Symbol.all_symbols.count}
end
end
context 'with Oj.default_settings' do
around do |example|
options = Oj.default_options
Oj.default_options = { :symbol_keys => true }
MultiJson.with_engine(:oj){ example.call }
Oj.default_options = options
end
it 'ignores global settings' do
MultiJson.with_engine(:oj) do
example = '{"a": 1, "b": 2}'
expected = { 'a' => 1, 'b' => 2 }
expect(MultiJson.load(example)).to eq(expected)
end
end
end
end
describe 'default options' do
after(:all){ MultiJson.load_options = MultiJson.dump_options = nil }
it 'is deprecated' do
expect(Kernel).to receive(:warn).with(/deprecated/i)
silence_warnings{ MultiJson.default_options = {:foo => 'bar'} }
end
it 'sets both load and dump options' do
expect(MultiJson).to receive(:dump_options=).with(:foo => 'bar')
expect(MultiJson).to receive(:load_options=).with(:foo => 'bar')
silence_warnings{ MultiJson.default_options = {:foo => 'bar'} }
end
end
it_behaves_like 'has options', MultiJson
describe 'aliases' do
if jruby?
describe 'jrjackson' do
after{ expect(MultiJson.adapter).to eq(MultiJson::Adapters::JrJackson) }
it 'allows jrjackson alias as symbol' do
expect{ MultiJson.use :jrjackson }.not_to raise_error
end
it 'allows jrjackson alias as string' do
expect{ MultiJson.use 'jrjackson' }.not_to raise_error
end
end
end
end
end
multi_json-1.11.2/spec/nsjsonserialization_adapter_spec.rb 0000664 0000000 0000000 00000000346 12545704171 0024071 0 ustar 00root root 0000000 0000000 require 'spec_helper'
exit true unless macruby?
require 'shared/adapter'
require 'multi_json/adapters/nsjsonserialization'
describe MultiJson::Adapters::Nsjsonserialization do
it_behaves_like 'an adapter', described_class
end multi_json-1.11.2/spec/oj_adapter_spec.rb 0000664 0000000 0000000 00000000667 12545704171 0020377 0 ustar 00root root 0000000 0000000 require 'spec_helper'
exit true if jruby?
require 'shared/adapter'
require 'multi_json/adapters/oj'
describe MultiJson::Adapters::Oj do
it_behaves_like 'an adapter', described_class
describe '.dump' do
describe '#dump_options' do
around{ |example| with_default_options(&example) }
it 'ensures indent is a Fixnum' do
expect{ MultiJson.dump(42, :indent => '')}.not_to raise_error
end
end
end
end
multi_json-1.11.2/spec/ok_json_adapter_spec.rb 0000664 0000000 0000000 00000000261 12545704171 0021417 0 ustar 00root root 0000000 0000000 require 'spec_helper'
require 'shared/adapter'
require 'multi_json/adapters/ok_json'
describe MultiJson::Adapters::OkJson do
it_behaves_like 'an adapter', described_class
end multi_json-1.11.2/spec/shared/ 0000775 0000000 0000000 00000000000 12545704171 0016165 5 ustar 00root root 0000000 0000000 multi_json-1.11.2/spec/shared/adapter.rb 0000664 0000000 0000000 00000015754 12545704171 0020146 0 ustar 00root root 0000000 0000000 # encoding: UTF-8
require 'shared/options'
shared_examples_for 'an adapter' do |adapter|
before{ MultiJson.use adapter }
it_behaves_like 'has options', adapter
it 'does not modify argument hashes' do
options = { :symbolize_keys => true, :pretty => false, :adapter => :ok_json }
expect{MultiJson.load('{}', options)}.to_not change{options}
expect{MultiJson.dump([42], options)}.to_not change{options}
end
describe '.dump' do
describe '#dump_options' do
before{ MultiJson.dump_options = MultiJson.adapter.dump_options = {} }
after do
expect(MultiJson.adapter.instance).to receive(:dump).with(1, :foo => 'bar', :fizz => 'buzz')
MultiJson.dump(1, :fizz => 'buzz')
MultiJson.dump_options = MultiJson.adapter.dump_options = nil
end
it 'respects global dump options' do
MultiJson.dump_options = {:foo => 'bar'}
end
it 'respects per-adapter dump options' do
MultiJson.adapter.dump_options = {:foo => 'bar'}
end
it 'adapter-specific are overridden by global options' do
MultiJson.adapter.dump_options = {:foo => 'foo'}
MultiJson.dump_options = {:foo => 'bar'}
end
end
it 'writes decodable JSON' do
examples = [
{'abc' => 'def'},
[],
1,
'2',
true,
false,
nil
]
examples.each do |example|
expect(MultiJson.load(MultiJson.dump(example))).to eq(example)
end
end
unless 'json_pure' == adapter || 'json_gem' == adapter
it 'dumps time in correct format' do
time = Time.at(1355218745).utc
dumped_json = MultiJson.dump(time)
expected = if RUBY_VERSION > '1.9'
'2012-12-11 09:39:05 UTC'
else
'Tue Dec 11 09:39:05 UTC 2012'
end
expect(MultiJson.load(dumped_json)).to eq(expected)
end
end
it 'dumps symbol and fixnum keys as strings' do
[
[
{:foo => {:bar => 'baz'}},
{'foo' => {'bar' => 'baz'}},
],
[
[{:foo => {:bar => 'baz'}}],
[{'foo' => {'bar' => 'baz'}}],
],
[
{:foo => [{:bar => 'baz'}]},
{'foo' => [{'bar' => 'baz'}]},
],
[
{1 => {2 => {3 => 'bar'}}},
{'1' => {'2' => {'3' => 'bar'}}}
]
].each do |example, expected|
dumped_json = MultiJson.dump(example)
expect(MultiJson.load(dumped_json)).to eq(expected)
end
end
it 'dumps rootless JSON' do
expect(MultiJson.dump('random rootless string')).to eq('"random rootless string"')
expect(MultiJson.dump(123)).to eq('123')
end
it 'passes options to the adapter' do
expect(MultiJson.adapter).to receive(:dump).with('foo', {:bar => :baz})
MultiJson.dump('foo', :bar => :baz)
end
it 'dumps custom objects that implement to_json' do
pending 'not supported' if adapter.name == 'MultiJson::Adapters::Gson'
klass = Class.new do
def to_json(*)
'"foobar"'
end
end
expect(MultiJson.dump(klass.new)).to eq('"foobar"')
end
it 'allows to dump JSON values' do
expect(MultiJson.dump(42)).to eq('42')
end
it 'allows to dump JSON with UTF-8 characters' do
expect(MultiJson.dump('color' => 'żółć')).to eq('{"color":"żółć"}')
end
end
describe '.load' do
describe '#load_options' do
before{ MultiJson.load_options = MultiJson.adapter.load_options = {} }
after do
expect(MultiJson.adapter.instance).to receive(:load).with('1', :foo => 'bar', :fizz => 'buzz')
MultiJson.load('1', :fizz => 'buzz')
MultiJson.load_options = MultiJson.adapter.load_options = nil
end
it 'respects global load options' do
MultiJson.load_options = {:foo => 'bar'}
end
it 'respects per-adapter load options' do
MultiJson.adapter.load_options = {:foo => 'bar'}
end
it 'adapter-specific are overridden by global options' do
MultiJson.adapter.load_options = {:foo => 'foo'}
MultiJson.load_options = {:foo => 'bar'}
end
end
it 'does not modify input' do
input = %Q{\n\n {"foo":"bar"} \n\n\t}
expect{
MultiJson.load(input)
}.to_not change{ input }
end
# Ruby 1.8 doesn't support String encodings
if RUBY_VERSION > '1.9'
it 'does not modify input encoding' do
input = '[123]'
input.force_encoding('iso-8859-1')
expect{
MultiJson.load(input)
}.to_not change{ input.encoding }
end
end
it 'properly loads valid JSON' do
expect(MultiJson.load('{"abc":"def"}')).to eq('abc' => 'def')
end
it 'raises MultiJson::ParseError on blank input or invalid input' do
[nil, '{"abc"}', ' ', "\t\t\t", "\n", "\x82\xAC\xEF"].each do |input|
if input == "\x82\xAC\xEF"
pending 'GSON bug: https://github.com/avsej/gson.rb/issues/3' if adapter.name =~ /Gson/
end
expect{MultiJson.load(input)}.to raise_error(MultiJson::ParseError)
end
end
it 'raises MultiJson::ParseError with data on invalid JSON' do
data = '{invalid}'
exception = get_exception(MultiJson::ParseError){ MultiJson.load data }
expect(exception.data).to eq(data)
expect(exception.cause).to be_kind_of(MultiJson.adapter::ParseError)
end
it 'catches MultiJson::DecodeError for legacy support' do
data = '{invalid}'
exception = get_exception(MultiJson::DecodeError){ MultiJson.load data }
expect(exception.data).to eq(data)
expect(exception.cause).to be_kind_of(MultiJson.adapter::ParseError)
end
it 'catches MultiJson::LoadError for legacy support' do
data = '{invalid}'
exception = get_exception(MultiJson::LoadError){ MultiJson.load data }
expect(exception.data).to eq(data)
expect(exception.cause).to be_kind_of(MultiJson.adapter::ParseError)
end
it 'stringifys symbol keys when encoding' do
dumped_json = MultiJson.dump(:a => 1, :b => {:c => 2})
loaded_json = MultiJson.load(dumped_json)
expect(loaded_json).to eq('a' => 1, 'b' => {'c' => 2})
end
it 'properly loads valid JSON in StringIOs' do
json = StringIO.new('{"abc":"def"}')
expect(MultiJson.load(json)).to eq('abc' => 'def')
end
it 'allows for symbolization of keys' do
[
[
'{"abc":{"def":"hgi"}}',
{:abc => {:def => 'hgi'}},
],
[
'[{"abc":{"def":"hgi"}}]',
[{:abc => {:def => 'hgi'}}],
],
[
'{"abc":[{"def":"hgi"}]}',
{:abc => [{:def => 'hgi'}]},
]
].each do |example, expected|
expect(MultiJson.load(example, :symbolize_keys => true)).to eq(expected)
end
end
it 'allows to load JSON values' do
expect(MultiJson.load('42')).to eq(42)
end
it 'allows to load JSON with UTF-8 characters' do
expect(MultiJson.load('{"color":"żółć"}')).to eq('color' => 'żółć')
end
end
end
multi_json-1.11.2/spec/shared/json_common_adapter.rb 0000664 0000000 0000000 00000001636 12545704171 0022541 0 ustar 00root root 0000000 0000000 shared_examples_for 'JSON-like adapter' do |adapter|
before{ MultiJson.use adapter }
describe '.dump' do
before{ MultiJson.dump_options = MultiJson.adapter.dump_options = nil }
describe 'with :pretty option set to true' do
it 'passes default pretty options' do
object = 'foo'
expect(object).to receive(:to_json).with(JSON::PRETTY_STATE_PROTOTYPE.to_h)
MultiJson.dump(object, :pretty => true)
end
end
describe 'with :indent option' do
it 'passes it on dump' do
object = 'foo'
expect(object).to receive(:to_json).with(:indent => "\t")
MultiJson.dump(object, :indent => "\t")
end
end
end
describe '.load' do
it 'passes :quirks_mode option' do
expect(::JSON).to receive(:parse).with('[123]', {:quirks_mode => false, :create_additions => false})
MultiJson.load('[123]', :quirks_mode => false)
end
end
end
multi_json-1.11.2/spec/shared/options.rb 0000664 0000000 0000000 00000006141 12545704171 0020207 0 ustar 00root root 0000000 0000000 shared_examples_for 'has options' do |object|
if object.respond_to?(:call)
subject{ object.call }
else
subject{ object }
end
describe "dump options" do
before do
subject.dump_options = nil
end
after do
subject.dump_options = nil
end
it 'returns default options if not set' do
expect(subject.dump_options).to eq(subject.default_dump_options)
end
it 'allows hashes' do
subject.dump_options = {:foo => 'bar'}
expect(subject.dump_options).to eq(:foo => 'bar')
end
it 'allows objects that implement #to_hash' do
value = Class.new do
def to_hash
{:foo => 'bar'}
end
end.new
subject.dump_options = value
expect(subject.dump_options).to eq(:foo => 'bar')
end
it 'evaluates lambda returning options (with args)' do
subject.dump_options = lambda{ |a1, a2| { a1 => a2 }}
expect(subject.dump_options('1', '2')).to eq('1' => '2')
end
it 'evaluates lambda returning options (with no args)' do
subject.dump_options = lambda{{:foo => 'bar'}}
expect(subject.dump_options).to eq(:foo => 'bar')
end
it 'returns empty hash in all other cases' do
subject.dump_options = true
expect(subject.dump_options).to eq(subject.default_dump_options)
subject.dump_options = false
expect(subject.dump_options).to eq(subject.default_dump_options)
subject.dump_options = 10
expect(subject.dump_options).to eq(subject.default_dump_options)
subject.dump_options = nil
expect(subject.dump_options).to eq(subject.default_dump_options)
end
end
describe "load options" do
before do
subject.load_options = nil
end
after do
subject.load_options = nil
end
it 'returns default options if not set' do
expect(subject.load_options).to eq(subject.default_load_options)
end
it 'allows hashes' do
subject.load_options = {:foo => 'bar'}
expect(subject.load_options).to eq(:foo => 'bar')
end
it 'allows objects that implement #to_hash' do
value = Class.new do
def to_hash
{:foo => 'bar'}
end
end.new
subject.load_options = value
expect(subject.load_options).to eq(:foo => 'bar')
end
it 'evaluates lambda returning options (with args)' do
subject.load_options = lambda{ |a1, a2| { a1 => a2 }}
expect(subject.load_options('1', '2')).to eq('1' => '2')
end
it 'evaluates lambda returning options (with no args)' do
subject.load_options = lambda{{:foo => 'bar'}}
expect(subject.load_options).to eq(:foo => 'bar')
end
it 'returns empty hash in all other cases' do
subject.load_options = true
expect(subject.load_options).to eq(subject.default_load_options)
subject.load_options = false
expect(subject.load_options).to eq(subject.default_load_options)
subject.load_options = 10
expect(subject.load_options).to eq(subject.default_load_options)
subject.load_options = nil
expect(subject.load_options).to eq(subject.default_load_options)
end
end
end
multi_json-1.11.2/spec/spec_helper.rb 0000664 0000000 0000000 00000003073 12545704171 0017540 0 ustar 00root root 0000000 0000000 require 'multi_json'
require 'rspec'
RSpec.configure do |config|
config.expect_with :rspec do |c|
c.syntax = :expect
end
end
def silence_warnings
old_verbose, $VERBOSE = $VERBOSE, nil
yield
ensure
$VERBOSE = old_verbose
end
def macruby?
defined?(RUBY_ENGINE) && RUBY_ENGINE == 'macruby'
end
def jruby?
defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
end
def undefine_constants(*consts)
values = {}
consts.each do |const|
if Object.const_defined?(const)
values[const] = Object.const_get(const)
Object.send :remove_const, const
end
end
yield
ensure
values.each do |const, value|
Object.const_set const, value
end
end
def break_requirements
requirements = MultiJson::REQUIREMENT_MAP
MultiJson::REQUIREMENT_MAP.each_with_index do |(library, adapter), index|
MultiJson::REQUIREMENT_MAP[index] = ["foo/#{library}", adapter]
end
yield
ensure
requirements.each_with_index do |(library, adapter), index|
MultiJson::REQUIREMENT_MAP[index] = [library, adapter]
end
end
def simulate_no_adapters
break_requirements do
undefine_constants :JSON, :Oj, :Yajl, :Gson, :JrJackson do
yield
end
end
end
def get_exception(exception_class = StandardError)
begin
yield
rescue exception_class => exception
exception
end
end
def with_default_options
adapter = MultiJson.adapter
adapter.load_options = adapter.dump_options = MultiJson.load_options = MultiJson.dump_options = nil
yield
ensure
adapter.load_options = adapter.dump_options = MultiJson.load_options = MultiJson.dump_options = nil
end
multi_json-1.11.2/spec/yajl_adapter_spec.rb 0000664 0000000 0000000 00000000302 12545704171 0020710 0 ustar 00root root 0000000 0000000 require 'spec_helper'
exit true if jruby?
require 'shared/adapter'
require 'multi_json/adapters/yajl'
describe MultiJson::Adapters::Yajl do
it_behaves_like 'an adapter', described_class
end