json-canonicalization 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/AUTHORS +1 -0
- data/LICENSE +24 -0
- data/README.md +92 -0
- data/VERSION +1 -0
- data/lib/json/canonicalization/version.rb +20 -0
- data/lib/json/canonicalization.rb +83 -0
- data/spec/c14n_spec.rb +11 -0
- data/spec/input/arrays.json +8 -0
- data/spec/input/french.json +6 -0
- data/spec/input/structures.json +8 -0
- data/spec/input/unicode.json +3 -0
- data/spec/input/values.json +5 -0
- data/spec/input/wierd.json +11 -0
- data/spec/number_spec.rb +37 -0
- data/spec/output/arrays.json +1 -0
- data/spec/output/french.json +1 -0
- data/spec/output/structures.json +1 -0
- data/spec/output/unicode.json +1 -0
- data/spec/output/values.json +1 -0
- data/spec/output/wierd.json +1 -0
- data/spec/spec_helper.rb +24 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 75fbded244fc0096ae6a46a90730fbf8a3fe1913d9a58fe60ec9fc91fb238522
|
4
|
+
data.tar.gz: 817b4072f362414762a9cb19eec0551dab9c4290bc8720640faedb050ff64b75
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5b8cf4b810ce1ca14b30232cd172d9bb3350b9d0aaaefd7c02cacad1fdb47c87ec7f88091b51c86621319bbeb59df53be34dcb81743b8a70307a90678a19862e
|
7
|
+
data.tar.gz: fc41d6154f7fb136396028f6c03ca3bfbb6e0ce65a676990773ad3361eef48c868990196b63ba790a57e537e12096ac8997036eefc7a7ab1773a94f4672fafcc
|
data/AUTHORS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
* Gregg Kellogg <gregg@greggkellogg.net>
|
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
4
|
+
distribute this software, either in source code form or as a compiled
|
5
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
6
|
+
means.
|
7
|
+
|
8
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
9
|
+
of this software dedicate any and all copyright interest in the
|
10
|
+
software to the public domain. We make this dedication for the benefit
|
11
|
+
of the public at large and to the detriment of our heirs and
|
12
|
+
successors. We intend this dedication to be an overt act of
|
13
|
+
relinquishment in perpetuity of all present and future rights to this
|
14
|
+
software under copyright law.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
20
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
21
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
For more information, please refer to <http://unlicense.org>
|
data/README.md
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# json-canonicalization
|
2
|
+
An implementation of the JSON Canonicalization Scheme for Ruby
|
3
|
+
|
4
|
+
Implements version 5 of [draft-rundgren-json-canonicalization-scheme-05](https://tools.ietf.org/html/draft-rundgren-json-canonicalization-scheme-05#page-5).
|
5
|
+
|
6
|
+
[![Gem Version](https://badge.fury.io/rb/json-canonicalization.png)](http://badge.fury.io/rb/json-canonicalization)
|
7
|
+
[![Build Status](https://travis-ci.org/dryruby/json-canonicalization.png?branch=master)](http://travis-ci.org/dryruby/json-canonicalization)
|
8
|
+
[![Coverage Status](https://coveralls.io/repos/dryruby/json-canonicalization/badge.svg)](https://coveralls.io/r/dryruby/json-canonicalization)
|
9
|
+
|
10
|
+
# Description
|
11
|
+
|
12
|
+
Cryptographic operations like hashing and signing depend on that the target
|
13
|
+
data does not change during serialization, transport, or parsing.
|
14
|
+
By applying the rules defined by JCS (JSON Canonicalization Scheme),
|
15
|
+
data provided in the JSON [[RFC8259](https://tools.ietf.org/html/rfc8259)]
|
16
|
+
format can be exchanged "as is", while still being subject to secure cryptographic operations.
|
17
|
+
JCS achieves this by building on the serialization formats for JSON
|
18
|
+
primitives as defined by ECMAScript [[ES6](https://www.ecma-international.org/ecma-262/6.0/index.html)],
|
19
|
+
constraining JSON data to the<br>I-JSON [[RFC7493](https://tools.ietf.org/html//rfc7493)] subset,
|
20
|
+
and through a platform independent property sorting scheme.
|
21
|
+
|
22
|
+
Working document: https://cyberphone.github.io/ietf-json-canon<br>
|
23
|
+
Published IETF Draft: https://tools.ietf.org/html/draft-rundgren-json-canonicalization-scheme-05
|
24
|
+
|
25
|
+
The JSON Canonicalization Scheme concept in a nutshell:
|
26
|
+
- Serialization of primitive JSON data types using methods compatible with ECMAScript's `JSON.stringify()`
|
27
|
+
- Lexicographic sorting of JSON `Object` properties in a *recursive* process
|
28
|
+
- JSON `Array` data is also subject to canonicalization, *but element order remains untouched*
|
29
|
+
|
30
|
+
### Sample Input:
|
31
|
+
```code
|
32
|
+
{
|
33
|
+
"numbers": [333333333.33333329, 1E30, 4.50, 2e-3, 0.000000000000000000000000001],
|
34
|
+
"string": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
|
35
|
+
"literals": [null, true, false]
|
36
|
+
}
|
37
|
+
```
|
38
|
+
### Expected Output:
|
39
|
+
```code
|
40
|
+
{"literals":[null,true,false],"numbers":[333333333.3333333,1e+30,4.5,0.002,1e-27],"string":"€$\u000f\nA'B\"\\\\\"/"}
|
41
|
+
```
|
42
|
+
## Usage
|
43
|
+
The library accepts Ruby input and generates canonical JSON via the `#to_json_c14n` method. This is based on the standard JSON gem's version of `#to_json` with overloads for `Hash`, `String` and `Numeric`
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
data = {
|
47
|
+
"numbers" => [
|
48
|
+
333333333.3333333,
|
49
|
+
1.0e+30,
|
50
|
+
4.5,
|
51
|
+
0.002,
|
52
|
+
1.0e-27
|
53
|
+
],
|
54
|
+
"string" => "€$\u000F\nA'B\"\\\\\"/",
|
55
|
+
"literals" => [nil, true, false]
|
56
|
+
}
|
57
|
+
|
58
|
+
puts data.to_json_c14n
|
59
|
+
=>
|
60
|
+
```
|
61
|
+
|
62
|
+
## Documentation
|
63
|
+
Full documentation available on [RubyDoc](http://rubydoc.info/gems/json-canonicalization/file/README.md)
|
64
|
+
|
65
|
+
### Principal Classes
|
66
|
+
* {JSON::Canonicalization}
|
67
|
+
|
68
|
+
## Dependencies
|
69
|
+
* [Ruby](http://ruby-lang.org/) (>= 2.2.2)
|
70
|
+
* [JSON](https://rubygems.org/gems/json) (>= 2.1)
|
71
|
+
|
72
|
+
## Author
|
73
|
+
* [Gregg Kellogg](http://github.com/gkellogg) - <http://kellogg-assoc.com/>
|
74
|
+
|
75
|
+
## Contributing
|
76
|
+
* Do your best to adhere to the existing coding conventions and idioms.
|
77
|
+
* Don't use hard tabs, and don't leave trailing whitespace on any line.
|
78
|
+
* Do document every method you add using [YARD][] annotations. Read the
|
79
|
+
[tutorial][YARD-GS] or just look at the existing code for examples.
|
80
|
+
* Don't touch the `json-ld.gemspec`, `VERSION` or `AUTHORS` files. If you need to
|
81
|
+
change them, do so on your private branch only.
|
82
|
+
* Do feel free to add yourself to the `CREDITS` file and the corresponding
|
83
|
+
list in the the `README`. Alphabetical order applies.
|
84
|
+
* Do note that in order for us to merge any non-trivial changes (as a rule
|
85
|
+
of thumb, additions larger than about 15 lines of code), we need an
|
86
|
+
explicit [public domain dedication][PDD] on record from you.
|
87
|
+
|
88
|
+
##License
|
89
|
+
|
90
|
+
This is free and unencumbered public domain software. For more information,
|
91
|
+
see <http://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
92
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
module JSON::Canonicalization::VERSION
|
4
|
+
VERSION_FILE = File.join(File.expand_path(File.dirname(__FILE__)), "..", "..", "..", "VERSION")
|
5
|
+
MAJOR, MINOR, TINY, EXTRA = File.read(VERSION_FILE).chomp.split(".")
|
6
|
+
|
7
|
+
STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join('.')
|
8
|
+
|
9
|
+
##
|
10
|
+
# @return [String]
|
11
|
+
def self.to_s() STRING end
|
12
|
+
|
13
|
+
##
|
14
|
+
# @return [String]
|
15
|
+
def self.to_str() STRING end
|
16
|
+
|
17
|
+
##
|
18
|
+
# @return [Array(Integer, Integer, Integer)]
|
19
|
+
def self.to_a() STRING.split(".") end
|
20
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
$:.unshift(File.expand_path("../ld", __FILE__))
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module JSON
|
7
|
+
##
|
8
|
+
# `JSON::Canonicalization` generates canonical JSON output from Ruby objects
|
9
|
+
module Canonicalization
|
10
|
+
autoload :VERSION, 'json/ld/version'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Object
|
15
|
+
# Default canonicalization output for Ruby objects
|
16
|
+
# @return [String]
|
17
|
+
def to_json_c14n
|
18
|
+
self.to_json
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Array
|
23
|
+
def to_json_c14n
|
24
|
+
'[' + self.map(&:to_json_c14n).join(',') + ']'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Numeric
|
29
|
+
def to_json_c14n
|
30
|
+
raise RangeError if self.is_a?(Float) && (self.nan? || self.infinite?)
|
31
|
+
return "0" if self.zero?
|
32
|
+
num = self
|
33
|
+
if num < 0
|
34
|
+
num, sign = -num, '-'
|
35
|
+
end
|
36
|
+
native_rep = "%.15E" % num
|
37
|
+
decimal, exponential = native_rep.split('E')
|
38
|
+
exp_val = exponential.to_i
|
39
|
+
exponential = exp_val > 0 ? ('+' + exp_val.to_s) : exp_val.to_s
|
40
|
+
|
41
|
+
integral, fractional = decimal.split('.')
|
42
|
+
fractional = fractional.sub(/0+$/, '') # Remove trailing zeros
|
43
|
+
|
44
|
+
if exp_val > 0 && exp_val < 21
|
45
|
+
while exp_val > 0
|
46
|
+
integral += fractional.to_s[0] || '0'
|
47
|
+
fractional = fractional.to_s[1..-1]
|
48
|
+
exp_val -= 1
|
49
|
+
end
|
50
|
+
exponential = nil
|
51
|
+
elsif exp_val == 0
|
52
|
+
exponential = nil
|
53
|
+
elsif exp_val < 0 && exp_val > -7
|
54
|
+
# Small numbers are shown as 0.etc with e-6 as lower limit
|
55
|
+
fractional, integral, exponential = integral + fractional.to_s, '0', nil
|
56
|
+
fractional = ("0" * (-exp_val - 1)) + fractional
|
57
|
+
end
|
58
|
+
|
59
|
+
fractional = nil if fractional.to_s.empty?
|
60
|
+
sign.to_s + integral + (fractional ? ".#{fractional}" : '') + (exponential ? "e#{exponential}" : '')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class Hash
|
65
|
+
# Output JSON with keys sorted lexicographically
|
66
|
+
# @return [String]
|
67
|
+
def to_json_c14n
|
68
|
+
"{" + self.
|
69
|
+
keys.
|
70
|
+
sort_by {|k| k.encode(Encoding::UTF_16)}.
|
71
|
+
map {|k| k.to_json_c14n + ':' + self[k].to_json_c14n}
|
72
|
+
.join(',') +
|
73
|
+
'}'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class String
|
78
|
+
# Output JSON with control characters escaped
|
79
|
+
# @return [String]
|
80
|
+
def to_json_c14n
|
81
|
+
self.to_json
|
82
|
+
end
|
83
|
+
end
|
data/spec/c14n_spec.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe "conversions" do
|
4
|
+
Dir.glob(File.expand_path("../input/*.json", __FILE__)).each do |input|
|
5
|
+
it "converts #{input.split('/').last}" do
|
6
|
+
expected = File.read(input.sub('input', 'output'))
|
7
|
+
data = JSON.parse(File.read(input))
|
8
|
+
expect(data.to_json_c14n).to eq expected
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{
|
2
|
+
"\u20ac": "Euro Sign",
|
3
|
+
"\r": "Carriage Return",
|
4
|
+
"\u000a": "Newline",
|
5
|
+
"1": "One",
|
6
|
+
"\u0080": "Control\u007f",
|
7
|
+
"\ud83d\ude02": "Smiley",
|
8
|
+
"\u00f6": "Latin Small Letter O With Diaeresis",
|
9
|
+
"\ufb33": "Hebrew Letter Dalet With Dagesh",
|
10
|
+
"</script>": "Browser Challenge"
|
11
|
+
}
|
data/spec/number_spec.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe "conversions" do
|
4
|
+
{
|
5
|
+
-1/0.0 => RangeError,
|
6
|
+
-9007199254740992 => '-9007199254740992',
|
7
|
+
0 => '0',
|
8
|
+
0.000001 => '0.000001',
|
9
|
+
0/0.0 => RangeError,
|
10
|
+
1/0.0 => RangeError,
|
11
|
+
1e+21 => '1e+21',
|
12
|
+
9.999999999999997e+22 => '9.999999999999997e+22',
|
13
|
+
9.999999999999997e-7 => '9.999999999999997e-7',
|
14
|
+
9007199254740992 => '9007199254740992',
|
15
|
+
9007199254740994 => '9007199254740994',
|
16
|
+
9007199254740996 => '9007199254740996',
|
17
|
+
999999999999999700000 => '999999999999999700000',
|
18
|
+
999999999999999900000 => '999999999999999900000',
|
19
|
+
# -5e-324 => '-5e-324', # Outside Ruby Range
|
20
|
+
# 1.0000000000000001e+23 => '1.0000000000000001e+23', # Outside Ruby Range
|
21
|
+
# 295147905179352830000 => '295147905179352830000', # Outside Ruby Range
|
22
|
+
#-1.7976931348623157e+308 => '-1.7976931348623157e+308', # Outside Ruby Range
|
23
|
+
#1.7976931348623157e+308 => '1.7976931348623157e+308', # Outside Ruby Range
|
24
|
+
#1e+23 => '1e+23', # Outside Ruby
|
25
|
+
#5e-324 => '5e-324', # Outside Ruby Range
|
26
|
+
}.each do |data, expected|
|
27
|
+
if expected.is_a?(String)
|
28
|
+
it "converts #{data} to #{expected}" do
|
29
|
+
expect(data.to_json_c14n).to eq expected
|
30
|
+
end
|
31
|
+
else
|
32
|
+
it "raises #{expected} for #{data}" do
|
33
|
+
expect {data.to_json_c14n}.to raise_error(expected)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
[56,{"1":[],"10":null,"d":true}]
|
@@ -0,0 +1 @@
|
|
1
|
+
{"peach":"This sorting order","péché":"is wrong according to French","pêche":"but canonicalization MUST","sin":"ignore locale"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"":"empty","1":{"\n":56,"f":{"F":5,"f":"hi"}},"10":{},"111":[{"E":"no","e":"yes"}],"A":{},"a":{}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"Unnormalized Unicode":"Å"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"literals":[null,true,false],"numbers":[333333333.3333333,1e+30,4.5,0.002,1e-27],"string":"€$\u000f\nA'B\"\\\\\"/"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"\n":"Newline","\r":"Carriage Return","1":"One","</script>":"Browser Challenge","":"Control","ö":"Latin Small Letter O With Diaeresis","€":"Euro Sign","😂":"Smiley","דּ":"Hebrew Letter Dalet With Dagesh"}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
$:.unshift(File.join("../../lib", __FILE__))
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'simplecov'
|
8
|
+
require 'coveralls' unless ENV['NOCOVERALLS']
|
9
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
10
|
+
SimpleCov::Formatter::HTMLFormatter,
|
11
|
+
(Coveralls::SimpleCov::Formatter unless ENV['NOCOVERALLS'])
|
12
|
+
])
|
13
|
+
SimpleCov.start do
|
14
|
+
add_filter "/spec/"
|
15
|
+
end
|
16
|
+
rescue LoadError
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'json/canonicalization'
|
20
|
+
|
21
|
+
::RSpec.configure do |c|
|
22
|
+
c.filter_run focus: true
|
23
|
+
c.run_all_when_everything_filtered = true
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: json-canonicalization
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gregg Kellogg
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-03-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.8'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: yard
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.9'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.9'
|
41
|
+
description: JSON::Canonicalization generates canonical JSON output from Ruby objects.
|
42
|
+
email:
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- AUTHORS
|
48
|
+
- LICENSE
|
49
|
+
- README.md
|
50
|
+
- VERSION
|
51
|
+
- lib/json/canonicalization.rb
|
52
|
+
- lib/json/canonicalization/version.rb
|
53
|
+
- spec/c14n_spec.rb
|
54
|
+
- spec/input/arrays.json
|
55
|
+
- spec/input/french.json
|
56
|
+
- spec/input/structures.json
|
57
|
+
- spec/input/unicode.json
|
58
|
+
- spec/input/values.json
|
59
|
+
- spec/input/wierd.json
|
60
|
+
- spec/number_spec.rb
|
61
|
+
- spec/output/arrays.json
|
62
|
+
- spec/output/french.json
|
63
|
+
- spec/output/structures.json
|
64
|
+
- spec/output/unicode.json
|
65
|
+
- spec/output/values.json
|
66
|
+
- spec/output/wierd.json
|
67
|
+
- spec/spec_helper.rb
|
68
|
+
homepage: http://github.com/dryruby/json-canonicalization
|
69
|
+
licenses:
|
70
|
+
- Unlicense
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 2.2.2
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubygems_version: 3.0.2
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: JSON Canonicalization for Ruby.
|
91
|
+
test_files:
|
92
|
+
- spec/spec_helper.rb
|
93
|
+
- spec/c14n_spec.rb
|
94
|
+
- spec/number_spec.rb
|
95
|
+
- spec/input/french.json
|
96
|
+
- spec/input/arrays.json
|
97
|
+
- spec/input/structures.json
|
98
|
+
- spec/input/unicode.json
|
99
|
+
- spec/input/wierd.json
|
100
|
+
- spec/input/values.json
|
101
|
+
- spec/output/french.json
|
102
|
+
- spec/output/arrays.json
|
103
|
+
- spec/output/structures.json
|
104
|
+
- spec/output/unicode.json
|
105
|
+
- spec/output/wierd.json
|
106
|
+
- spec/output/values.json
|