jazor 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +9 -0
- data/Gemfile.lock +22 -0
- data/README.md +135 -0
- data/Rakefile +9 -13
- data/bin/jazor +38 -26
- data/jazor.gemspec +23 -0
- data/lib/jazor.rb +26 -27
- data/spec/jazor_cli_spec.rb +67 -0
- data/spec/jazor_lib_spec.rb +44 -0
- data/spec/test.json +8 -0
- metadata +54 -10
- data/CHANGELOG.rdoc +0 -34
- data/LICENSE +0 -19
- data/README.rdoc +0 -75
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.3)
|
5
|
+
json (1.6.5)
|
6
|
+
rake (0.9.2.2)
|
7
|
+
rspec (2.8.0)
|
8
|
+
rspec-core (~> 2.8.0)
|
9
|
+
rspec-expectations (~> 2.8.0)
|
10
|
+
rspec-mocks (~> 2.8.0)
|
11
|
+
rspec-core (2.8.0)
|
12
|
+
rspec-expectations (2.8.0)
|
13
|
+
diff-lcs (~> 1.1.2)
|
14
|
+
rspec-mocks (2.8.0)
|
15
|
+
|
16
|
+
PLATFORMS
|
17
|
+
ruby
|
18
|
+
|
19
|
+
DEPENDENCIES
|
20
|
+
json
|
21
|
+
rake
|
22
|
+
rspec
|
data/README.md
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# Jazor
|
2
|
+
|
3
|
+
Jazor (JSON razor) is a simple command line JSON parsing tool.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
gem install jazor
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
jazor [options] [source] [expression ...]
|
12
|
+
|
13
|
+
### Options
|
14
|
+
|
15
|
+
See the **--help** command line option.
|
16
|
+
|
17
|
+
### Sources
|
18
|
+
|
19
|
+
The **source** argument refers to a file, URL or string containing a JSON object.
|
20
|
+
Since attempts to implement a full-featured HTTP client within Jazor would have
|
21
|
+
been futile, Jazor also accepts input from STDIN. This means if you ever need
|
22
|
+
to use an advanced HTTP option that Jazor doesn't implement, you can always use
|
23
|
+
a *real* HTTP client (e.g. [cURL](http://curl.haxx.se/)) and simply pipe the
|
24
|
+
output to Jazor.
|
25
|
+
|
26
|
+
### Expressions
|
27
|
+
|
28
|
+
Jazor accepts one or more Ruby **expressions** which are simply eval'ed within
|
29
|
+
the context of your JSON object. After Jazor parses your JSON input into native
|
30
|
+
Ruby data types (Hash, Array, etc.), these expressions are used to slice and
|
31
|
+
dice the data any way you want. The results will be "pretty printed" to STDOUT.
|
32
|
+
|
33
|
+
Note that hash keys can be accessed via standard Ruby (e.g. foo['bar'],
|
34
|
+
foo.fetch('bar'), etc.) or Javascript (e.g. foo.bar) syntax.
|
35
|
+
|
36
|
+
### Expression Testing
|
37
|
+
|
38
|
+
Expression testing (**--test**) allows you to test the "truthiness" of your
|
39
|
+
expression results. If any expression returns a "falsy" value, Jazor will exit
|
40
|
+
with a non-zero return code. This is useful for calling Jazor from within shell
|
41
|
+
scripts.
|
42
|
+
|
43
|
+
## Examples
|
44
|
+
|
45
|
+
$ jazor http://github.com/api/v2/json/commits/list/mconigliaro/jazor/master commits.count
|
46
|
+
16
|
47
|
+
|
48
|
+
$ curl --silent http://github.com/api/v2/json/commits/list/mconigliaro/jazor/master | jazor commits.last.message
|
49
|
+
initial commit
|
50
|
+
|
51
|
+
$ jazor '{ "foo": "abc", "bar": [1, 2, 3] }' 'foo.split(//)'
|
52
|
+
["a", "b", "c"]
|
53
|
+
|
54
|
+
$ jazor '{ "foo": "abc", "bar": [1, 2, 3] }' 'bar.inject { |memo,obj| memo + obj }'
|
55
|
+
6
|
56
|
+
|
57
|
+
$ jazor '[1, 2, 3, 4, 5]' 'select(&:even?)'
|
58
|
+
[2, 4]
|
59
|
+
|
60
|
+
$ jazor '[1, 2, 3, 4, 5]' 'select(&:odd?)'
|
61
|
+
[1, 3, 5]
|
62
|
+
|
63
|
+
$ jazor '["a", "b", "c", "d", "e"]' 'self[1..3]'
|
64
|
+
["b", "c", "d"]
|
65
|
+
|
66
|
+
$ jazor '[1, 2, 3, 4, 5]' "'odds=%s; evens=%s' % [select(&:odd?).join(','), select(&:even?).join(',')]"
|
67
|
+
odds=1,3,5; evens=2,4
|
68
|
+
|
69
|
+
## Change Log
|
70
|
+
|
71
|
+
### 0.1.4 (2012-03-05)
|
72
|
+
|
73
|
+
* Add --quirks-mode option
|
74
|
+
* Update all dependencies
|
75
|
+
* Refactoring
|
76
|
+
|
77
|
+
### 0.1.3 (2011-12-13)
|
78
|
+
|
79
|
+
* Handle HTTPS URLs
|
80
|
+
* Use .rvmrc and Bundler in project
|
81
|
+
* Convert tests from Test::Unit to RSpec
|
82
|
+
|
83
|
+
### 0.1.2 (2011-08-24)
|
84
|
+
|
85
|
+
* Apply sort after evaluating expression
|
86
|
+
|
87
|
+
### 0.1.1 (2011-08-24)
|
88
|
+
|
89
|
+
* Added sort option (Dan Hopkins)
|
90
|
+
|
91
|
+
### 0.1.0 (2011-08-23)
|
92
|
+
|
93
|
+
* Code refactoring
|
94
|
+
* Documentation rewrite
|
95
|
+
* Changed test option to a switch that operates on all expressions
|
96
|
+
|
97
|
+
### 0.0.4 (2011-01-25)
|
98
|
+
|
99
|
+
* Print help summary on absence of input
|
100
|
+
* Bug fixes
|
101
|
+
|
102
|
+
### 0.0.3 (2011-01-25)
|
103
|
+
|
104
|
+
* Bug fixes
|
105
|
+
|
106
|
+
### 0.0.2 (2011-01-24)
|
107
|
+
|
108
|
+
* Initial public release
|
109
|
+
|
110
|
+
## Licence
|
111
|
+
|
112
|
+
Copyright (C) 2012 Michael Paul Thomas Conigliaro
|
113
|
+
|
114
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
115
|
+
this software and associated documentation files (the "Software"), to deal in
|
116
|
+
the Software without restriction, including without limitation the rights to
|
117
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
118
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
119
|
+
so, subject to the following conditions:
|
120
|
+
|
121
|
+
The above copyright notice and this permission notice shall be included in all
|
122
|
+
copies or substantial portions of the Software.
|
123
|
+
|
124
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
125
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
126
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
127
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
128
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
129
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
130
|
+
SOFTWARE.
|
131
|
+
|
132
|
+
## Credits
|
133
|
+
|
134
|
+
* [Michael Paul Thomas Conigliaro](http://conigliaro.org): Original author
|
135
|
+
* [Daniel Hopkins](https://github.com/danielhopkins): Sorted output
|
data/Rakefile
CHANGED
@@ -1,15 +1,11 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
system "gem build *.gemspec"
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:test) do |t|
|
5
|
+
t.rspec_opts = [
|
6
|
+
"-f doc",
|
7
|
+
"-r #{File.expand_path(File.join(File.dirname(__FILE__), "lib", "jazor.rb"))}"
|
8
|
+
]
|
10
9
|
end
|
11
10
|
|
12
|
-
|
13
|
-
task :push do
|
14
|
-
system "gem push *.gem"
|
15
|
-
end
|
11
|
+
task :default => :test
|
data/bin/jazor
CHANGED
@@ -1,57 +1,61 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
|
6
|
-
$:.push File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
-
require 'jazor'
|
3
|
+
require "fcntl"
|
4
|
+
require "optparse"
|
8
5
|
|
6
|
+
$:.push File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
7
|
+
require "jazor"
|
9
8
|
|
10
9
|
options = {
|
10
|
+
:quirks_mode => false,
|
11
11
|
:test => false,
|
12
12
|
:rest_data => {},
|
13
13
|
:rest_headers => {},
|
14
|
-
:rest_request =>
|
14
|
+
:rest_request => "GET"
|
15
15
|
}
|
16
16
|
|
17
17
|
OptionParser.new do |opts|
|
18
18
|
opts.version = Jazor::VERSION
|
19
19
|
opts.banner = "Usage: #{$0} [options] [source] [expression ...]\n\n"
|
20
20
|
|
21
|
-
opts.on(
|
22
|
-
key, value = opt.split(
|
21
|
+
opts.on("-d", "--data NAME=VALUE", "Data sent with REST request") do |opt|
|
22
|
+
key, value = opt.split("=")
|
23
23
|
options[:rest_data][key.strip] = value.strip
|
24
24
|
end
|
25
25
|
|
26
|
-
opts.on(
|
27
|
-
key, value = opt.split(
|
26
|
+
opts.on("-H", "--header NAME:VALUE", "Header sent with REST request") do |opt|
|
27
|
+
key, value = opt.split(":")
|
28
28
|
options[:rest_headers][key.strip] = value.strip
|
29
29
|
end
|
30
30
|
|
31
|
-
opts.on(
|
31
|
+
opts.on("-t", "--test", "Enable expression testing") do |opt|
|
32
32
|
options[:test] = true
|
33
33
|
end
|
34
34
|
|
35
|
-
opts.on(
|
35
|
+
opts.on("-v", "--verbose", "Enable verbose logging") do |opt|
|
36
36
|
Jazor::LOG.level = Logger::DEBUG
|
37
37
|
end
|
38
38
|
|
39
|
-
opts.on(
|
39
|
+
opts.on("-X", "--request REQUEST", "REST request method (default: %s)" % options[:rest_request]) do |opt|
|
40
40
|
options[:rest_request] = opt
|
41
41
|
end
|
42
42
|
|
43
43
|
if Jazor::HAS_ORDERED_HASH
|
44
|
-
opts.on(
|
44
|
+
opts.on("-s", "--sort", "Sort output") do
|
45
45
|
options[:sort] = true
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
opts.
|
49
|
+
opts.on("-q", "--quirks-mode", 'Enable "quirks mode" for JSON parser') do
|
50
|
+
options[:quirks_mode] = true
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
50
54
|
puts opts.help
|
51
55
|
exit
|
52
56
|
end
|
53
57
|
|
54
|
-
opts.on_tail(
|
58
|
+
opts.on_tail("--version", "Show version") do
|
55
59
|
puts "%s %s\n%s <%s>\n%s" % [opts.program_name, opts.version, Jazor::AUTHOR, Jazor::AUTHOR_EMAIL, Jazor::URL]
|
56
60
|
exit
|
57
61
|
end
|
@@ -62,26 +66,30 @@ OptionParser.new do |opts|
|
|
62
66
|
end
|
63
67
|
end.parse!
|
64
68
|
|
69
|
+
parse_options = {
|
70
|
+
:quirks_mode => options[:quirks_mode]
|
71
|
+
}
|
72
|
+
|
65
73
|
begin
|
66
74
|
|
67
75
|
obj = if STDIN.fcntl(Fcntl::F_GETFL, 0) == 0
|
68
|
-
Jazor::LOG.debug(
|
69
|
-
Jazor::parse(STDIN.read)
|
76
|
+
Jazor::LOG.debug("Reading JSON from STDIN")
|
77
|
+
Jazor::parse(STDIN.read, parse_options)
|
70
78
|
elsif !ARGV[0].nil?
|
71
79
|
if ARGV[0] =~ URI::regexp
|
72
80
|
Jazor::LOG.debug("Reading JSON from URI: #{ARGV[0]}")
|
73
|
-
Jazor::parse(Jazor::RestClient.send(options[:rest_request], ARGV.shift, options[:rest_headers], options[:rest_data]).body)
|
81
|
+
Jazor::parse(Jazor::RestClient.send(options[:rest_request], ARGV.shift, options[:rest_headers], options[:rest_data]).body, parse_options)
|
74
82
|
elsif File.readable?(ARGV[0])
|
75
83
|
Jazor::LOG.debug("Reading JSON from file: #{ARGV[0]}")
|
76
|
-
Jazor::parse(IO.read(ARGV.shift))
|
84
|
+
Jazor::parse(IO.read(ARGV.shift), parse_options)
|
77
85
|
else
|
78
86
|
Jazor::LOG.debug("Reading JSON from ARGV: #{ARGV[0]}")
|
79
|
-
Jazor::parse(ARGV.shift)
|
87
|
+
Jazor::parse(ARGV.shift, parse_options)
|
80
88
|
end
|
81
89
|
end
|
82
90
|
|
83
91
|
(ARGV.length > 0 ? ARGV[0..ARGV.length] : [nil]).each do |expression|
|
84
|
-
result =
|
92
|
+
result = Jazor::evaluate(obj, expression)
|
85
93
|
|
86
94
|
if options[:sort] && result.respond_to?(:sort)
|
87
95
|
result = if result.respond_to?(:keys) && result.respond_to?(:values)
|
@@ -99,13 +107,17 @@ begin
|
|
99
107
|
exit(1)
|
100
108
|
end
|
101
109
|
else
|
102
|
-
|
110
|
+
if [Hash, Array].include?(result.class)
|
111
|
+
puts JSON.pretty_generate(result)
|
112
|
+
elsif result.is_a?(String)
|
113
|
+
puts "\"#{result}\""
|
114
|
+
else
|
115
|
+
puts result
|
116
|
+
end
|
103
117
|
end
|
104
118
|
end
|
105
119
|
|
106
120
|
rescue StandardError => e
|
107
|
-
|
108
|
-
puts e.backtrace
|
109
|
-
Jazor::LOG.error(e.message)
|
121
|
+
Jazor::LOG.error(e)
|
110
122
|
exit(1)
|
111
123
|
end
|
data/jazor.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
$:.push File.expand_path(File.join(File.dirname(__FILE__), "lib"))
|
2
|
+
require "jazor"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = Jazor::NAME
|
6
|
+
s.version = Jazor::VERSION
|
7
|
+
s.authors = Jazor::AUTHOR
|
8
|
+
s.email = Jazor::AUTHOR_EMAIL
|
9
|
+
s.homepage = Jazor::URL
|
10
|
+
s.rubyforge_project = Jazor::NAME
|
11
|
+
s.summary = Jazor::DESCRIPTION
|
12
|
+
s.description = Jazor::DESCRIPTION
|
13
|
+
|
14
|
+
s.add_dependency("bundler")
|
15
|
+
s.add_dependency("json")
|
16
|
+
|
17
|
+
s.add_development_dependency("rake")
|
18
|
+
s.add_development_dependency("rspec")
|
19
|
+
|
20
|
+
s.files = ["jazor.gemspec", "Gemfile", "Gemfile.lock", "README.md"] + Dir["bin/*"] + Dir["lib/*.rb"]
|
21
|
+
s.test_files = ["Rakefile"] + Dir["spec/*"]
|
22
|
+
s.executables = ["jazor"]
|
23
|
+
end
|
data/lib/jazor.rb
CHANGED
@@ -1,45 +1,44 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require 'net/https'
|
4
|
-
require 'pp'
|
5
|
-
require 'uri'
|
6
|
-
|
7
|
-
require 'rubygems'
|
8
|
-
require 'json'
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
9
3
|
|
4
|
+
require "json"
|
5
|
+
require "logger"
|
6
|
+
require "net/http"
|
7
|
+
require "net/https"
|
8
|
+
require "pp"
|
9
|
+
require "uri"
|
10
10
|
|
11
11
|
module Jazor
|
12
12
|
|
13
|
-
NAME =
|
14
|
-
VERSION =
|
15
|
-
AUTHOR =
|
16
|
-
AUTHOR_EMAIL =
|
17
|
-
DESCRIPTION =
|
18
|
-
URL =
|
13
|
+
NAME = "jazor"
|
14
|
+
VERSION = "0.1.4"
|
15
|
+
AUTHOR = "Michael Paul Thomas Conigliaro"
|
16
|
+
AUTHOR_EMAIL = "mike [at] conigliaro [dot] org"
|
17
|
+
DESCRIPTION = "Jazor (JSON razor) is a simple command line JSON parsing tool."
|
18
|
+
URL = "http://github.com/mconigliaro/jazor"
|
19
19
|
|
20
20
|
LOG = Logger.new(STDOUT)
|
21
21
|
LOG.level = Logger::INFO
|
22
22
|
|
23
|
-
HAS_ORDERED_HASH = (RUBY_VERSION.split(
|
23
|
+
HAS_ORDERED_HASH = (RUBY_VERSION.split(".").map(&:to_i) <=> [1, 9, 1]) >= 0
|
24
24
|
|
25
|
-
def self.parse(input=nil)
|
26
|
-
|
27
|
-
|
28
|
-
if obj.is_a?(String)
|
29
|
-
if obj == 'true'
|
30
|
-
obj = true
|
31
|
-
elsif obj == 'false'
|
32
|
-
obj = false
|
33
|
-
end
|
34
|
-
end
|
25
|
+
def self.parse(input=nil, options={})
|
26
|
+
obj = JSON.parse(input, options)
|
27
|
+
Jazor::LOG.debug("Parsed JSON as a #{obj.class}")
|
35
28
|
obj
|
36
29
|
end
|
37
30
|
|
31
|
+
def self.evaluate(obj, expression)
|
32
|
+
result = expression.nil? ? obj : obj.instance_eval(expression)
|
33
|
+
Jazor::LOG.debug("Expression (#{expression}) returns a #{result.class}")
|
34
|
+
result
|
35
|
+
end
|
36
|
+
|
38
37
|
class RestClient
|
39
38
|
def self.method_missing(method, uri, headers={}, data={})
|
40
39
|
uri_parsed = URI.parse(uri)
|
41
40
|
http = Net::HTTP.new(uri_parsed.host, port=uri_parsed.port)
|
42
|
-
if uri_parsed.scheme ==
|
41
|
+
if uri_parsed.scheme == "https"
|
43
42
|
http.use_ssl = true
|
44
43
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
45
44
|
end
|
@@ -50,7 +49,7 @@ module Jazor
|
|
50
49
|
|
51
50
|
LOG.debug("#{self} #{method.to_s.upcase}: uri=#{File.join(uri_parsed.host, request_uri)} headers=#{headers.to_json} data=#{data.to_json}")
|
52
51
|
response = http.request(request)
|
53
|
-
LOG.debug("#{self} result: code=#{response.code} body=%s" % response.body.gsub("\r",
|
52
|
+
LOG.debug("#{self} result: code=#{response.code} body=%s" % response.body.gsub("\r", " ").gsub("\n", " "))
|
54
53
|
|
55
54
|
response
|
56
55
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
describe "Jazor command" do
|
2
|
+
|
3
|
+
before(:all) do
|
4
|
+
@test_url = "http://github.com/api/v2/json/commits/list/mconigliaro/jazor/master"
|
5
|
+
@test_file = File.expand_path(File.join(File.dirname(__FILE__), "test.json"))
|
6
|
+
@test_hash = JSON.parse(IO.read(@test_file))
|
7
|
+
@jazor_bin = File.expand_path(File.join(File.dirname(__FILE__), "..", "bin", "jazor"))
|
8
|
+
end
|
9
|
+
|
10
|
+
it "prints a help summary on absence of input" do
|
11
|
+
`#{@jazor_bin}`.should =~ /Usage:/
|
12
|
+
end
|
13
|
+
|
14
|
+
it "parses JSON from STDIN" do
|
15
|
+
JSON.parse(`cat #{@test_file} | #{@jazor_bin} -q`).should == @test_hash
|
16
|
+
end
|
17
|
+
|
18
|
+
it "parses JSON from a URL" do
|
19
|
+
JSON.parse(`#{@jazor_bin} "#{@test_url}"`).should be_a Hash
|
20
|
+
end
|
21
|
+
|
22
|
+
it "parses JSON from a file" do
|
23
|
+
JSON.parse(`#{@jazor_bin} #{@test_file}`).should == @test_hash
|
24
|
+
end
|
25
|
+
|
26
|
+
it "parses JSON from ARGV" do
|
27
|
+
JSON.parse(`#{@jazor_bin} '#{IO.read(@test_file)}'`).should == @test_hash
|
28
|
+
end
|
29
|
+
|
30
|
+
it "parses true/false values in quirks mode" do
|
31
|
+
[true, false].each do |obj|
|
32
|
+
eval(`#{@jazor_bin} -q "#{obj}"`).should == obj
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "exits with non-zero status on invalid JSON" do
|
37
|
+
`#{@jazor_bin} invalid`
|
38
|
+
$?.should_not == 0
|
39
|
+
end
|
40
|
+
|
41
|
+
it "parses JSON from a file with an expression" do
|
42
|
+
JSON.parse(`#{@jazor_bin} #{@test_file} test_Array`).should == @test_hash["test_Array"]
|
43
|
+
%w{String Integer Float TrueClass FalseClass}.each do |t|
|
44
|
+
eval(`#{@jazor_bin} #{@test_file} test_#{t}`).should == @test_hash["test_#{t}"]
|
45
|
+
end
|
46
|
+
eval(`#{@jazor_bin} #{@test_file} dontexist`).should be_nil
|
47
|
+
end
|
48
|
+
|
49
|
+
it "parses JSON from a file with tests" do
|
50
|
+
`#{@jazor_bin} -t #{@test_file} "test_Integer==123"`.should =~ /passed/
|
51
|
+
`#{@jazor_bin} -t #{@test_file} "test_Integer==1234"`.should =~ /failed/
|
52
|
+
end
|
53
|
+
|
54
|
+
it "sorts output" do
|
55
|
+
if Jazor::HAS_ORDERED_HASH
|
56
|
+
{
|
57
|
+
"[3, 2, 1]" => [1, 2, 3],
|
58
|
+
'["foo", "bar", 1]' => [1, "bar", "foo"],
|
59
|
+
'{"foo":1, "bar":2}' => {"bar" => 2, "foo" => 1},
|
60
|
+
'{"1":1, "bar":2}' => {"1" => 1, "bar" => 2}
|
61
|
+
}.each do |k,v|
|
62
|
+
JSON.parse(`#{@jazor_bin} -s '#{k}'`).should == v
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
describe "Jazor lib" do
|
2
|
+
|
3
|
+
before(:all) do
|
4
|
+
@test_file = IO.read(File.expand_path(File.join(File.dirname(__FILE__), "test.json")))
|
5
|
+
@test_hash = JSON.parse(@test_file)
|
6
|
+
end
|
7
|
+
|
8
|
+
%w{String Integer Float TrueClass FalseClass Array}.each do |t|
|
9
|
+
it "parses #{t} values in the root object" do
|
10
|
+
obj = Jazor::parse(@test_file)["test_#{t}"]
|
11
|
+
obj.should be_a Kernel.const_get(t)
|
12
|
+
obj.should == @test_hash["test_#{t}"]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "evaluates the expression \"test_#{t}\" and returns the correct result" do
|
16
|
+
obj = Jazor::evaluate(Jazor::parse(@test_file), "test_#{t}")
|
17
|
+
obj.should be_a Kernel.const_get(t)
|
18
|
+
obj.should == @test_hash["test_#{t}"]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "REST client" do
|
23
|
+
|
24
|
+
it "can issue GET requests over HTTP" do
|
25
|
+
response = Jazor::RestClient.get("http://ajax.googleapis.com/ajax/services/search/web")
|
26
|
+
response.code.should == "200"
|
27
|
+
response.body.should =~ /"responseStatus": 400/
|
28
|
+
end
|
29
|
+
|
30
|
+
it "can issue GET requests over HTTPS" do
|
31
|
+
response = Jazor::RestClient.get("https://github.com/api/v2/json/commits/list/mconigliaro/jazor/master")
|
32
|
+
response.code.should == "200"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "can issue GET requests over HTTP with a query string" do
|
36
|
+
response = Jazor::RestClient.get("http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=jazor")
|
37
|
+
response.code.should == "200"
|
38
|
+
response.body.should =~ /"responseStatus": 200/
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
data/spec/test.json
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jazor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-03-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: &2153832180 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2153832180
|
14
25
|
- !ruby/object:Gem::Dependency
|
15
26
|
name: json
|
16
|
-
requirement: &
|
27
|
+
requirement: &2153831560 !ruby/object:Gem::Requirement
|
17
28
|
none: false
|
18
29
|
requirements:
|
19
30
|
- - ! '>='
|
@@ -21,7 +32,29 @@ dependencies:
|
|
21
32
|
version: '0'
|
22
33
|
type: :runtime
|
23
34
|
prerelease: false
|
24
|
-
version_requirements: *
|
35
|
+
version_requirements: *2153831560
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &2153830560 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2153830560
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &2153828820 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2153828820
|
25
58
|
description: Jazor (JSON razor) is a simple command line JSON parsing tool.
|
26
59
|
email: mike [at] conigliaro [dot] org
|
27
60
|
executables:
|
@@ -29,12 +62,16 @@ executables:
|
|
29
62
|
extensions: []
|
30
63
|
extra_rdoc_files: []
|
31
64
|
files:
|
32
|
-
-
|
33
|
-
-
|
34
|
-
-
|
35
|
-
- README.
|
65
|
+
- jazor.gemspec
|
66
|
+
- Gemfile
|
67
|
+
- Gemfile.lock
|
68
|
+
- README.md
|
36
69
|
- bin/jazor
|
37
70
|
- lib/jazor.rb
|
71
|
+
- Rakefile
|
72
|
+
- spec/jazor_cli_spec.rb
|
73
|
+
- spec/jazor_lib_spec.rb
|
74
|
+
- spec/test.json
|
38
75
|
homepage: http://github.com/mconigliaro/jazor
|
39
76
|
licenses: []
|
40
77
|
post_install_message:
|
@@ -47,6 +84,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
47
84
|
- - ! '>='
|
48
85
|
- !ruby/object:Gem::Version
|
49
86
|
version: '0'
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
hash: 607493245767784991
|
50
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
91
|
none: false
|
52
92
|
requirements:
|
@@ -55,8 +95,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
95
|
version: '0'
|
56
96
|
requirements: []
|
57
97
|
rubyforge_project: jazor
|
58
|
-
rubygems_version: 1.8.
|
98
|
+
rubygems_version: 1.8.17
|
59
99
|
signing_key:
|
60
100
|
specification_version: 3
|
61
101
|
summary: Jazor (JSON razor) is a simple command line JSON parsing tool.
|
62
|
-
test_files:
|
102
|
+
test_files:
|
103
|
+
- Rakefile
|
104
|
+
- spec/jazor_cli_spec.rb
|
105
|
+
- spec/jazor_lib_spec.rb
|
106
|
+
- spec/test.json
|
data/CHANGELOG.rdoc
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
= Change Log
|
2
|
-
|
3
|
-
== 0.1.3 (2011-12-13)
|
4
|
-
|
5
|
-
* Handle HTTPS URLs
|
6
|
-
* Use .rvmrc and Bundler in project
|
7
|
-
* Convert tests from Test::Unit to RSpec
|
8
|
-
|
9
|
-
== 0.1.2 (2011-08-24)
|
10
|
-
|
11
|
-
* Apply sort after evaluating expression
|
12
|
-
|
13
|
-
== 0.1.1 (2011-08-24)
|
14
|
-
|
15
|
-
* Added sort option (Dan Hopkins)
|
16
|
-
|
17
|
-
== 0.1.0 (2011-08-23)
|
18
|
-
|
19
|
-
* Code refactoring
|
20
|
-
* Documentation rewrite
|
21
|
-
* Changed test option to a switch that operates on all expressions
|
22
|
-
|
23
|
-
== 0.0.4 (2011-01-25)
|
24
|
-
|
25
|
-
* Print help summary on absence of input
|
26
|
-
* Bug fixes
|
27
|
-
|
28
|
-
== 0.0.3 (2011-01-25)
|
29
|
-
|
30
|
-
* Bug fixes
|
31
|
-
|
32
|
-
== 0.0.2 (2011-01-24)
|
33
|
-
|
34
|
-
* Initial public release
|
data/LICENSE
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
Copyright (C) 2011 Michael Paul Thomas Conigliaro
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
-
this software and associated documentation files (the "Software"), to deal in
|
5
|
-
the Software without restriction, including without limitation the rights to
|
6
|
-
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7
|
-
of the Software, and to permit persons to whom the Software is furnished to do
|
8
|
-
so, subject to the following conditions:
|
9
|
-
|
10
|
-
The above copyright notice and this permission notice shall be included in all
|
11
|
-
copies or substantial portions of the Software.
|
12
|
-
|
13
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
-
SOFTWARE.
|
data/README.rdoc
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
= Jazor
|
2
|
-
|
3
|
-
Jazor (JSON razor) is a simple command line JSON parsing tool.
|
4
|
-
|
5
|
-
== Installation
|
6
|
-
|
7
|
-
gem install jazor
|
8
|
-
|
9
|
-
== Usage
|
10
|
-
|
11
|
-
jazor [options] [source] [expression ...]
|
12
|
-
|
13
|
-
=== Options
|
14
|
-
|
15
|
-
See the *--help* command line option.
|
16
|
-
|
17
|
-
=== Sources
|
18
|
-
|
19
|
-
The *source* argument refers to a file, URL or string containing a JSON object.
|
20
|
-
Since attempts to implement a full-featured HTTP client within Jazor would have
|
21
|
-
been futile, Jazor also accepts input from STDIN. This means if you ever need
|
22
|
-
to use an advanced HTTP option that Jazor doesn't implement, you can always use
|
23
|
-
a *real* HTTP client (e.g. {cURL}[http://curl.haxx.se/]) and simply pipe the
|
24
|
-
output to Jazor.
|
25
|
-
|
26
|
-
=== Expressions
|
27
|
-
|
28
|
-
Jazor accepts one or more Ruby *expressions* which are simply eval'ed within
|
29
|
-
the context of your JSON object. After Jazor parses your JSON input into native
|
30
|
-
Ruby data types (Hash, Array, etc.), these expressions are used to slice and
|
31
|
-
dice the data any way you want. The results will be "pretty printed" to STDOUT.
|
32
|
-
|
33
|
-
Note that hash keys can be accessed via standard Ruby (e.g. foo['bar'],
|
34
|
-
foo.fetch('bar'), etc.) or Javascript (e.g. foo.bar) syntax.
|
35
|
-
|
36
|
-
=== Expression Testing
|
37
|
-
|
38
|
-
Expression testing (*--test*) allows you to test the "truthiness" of your
|
39
|
-
expression results. If any expression returns a "falsy" value, Jazor will exit
|
40
|
-
with a non-zero return code. This is useful for calling Jazor from within shell
|
41
|
-
scripts.
|
42
|
-
|
43
|
-
== Examples
|
44
|
-
|
45
|
-
$ jazor http://github.com/api/v2/json/commits/list/mconigliaro/jazor/master commits.count
|
46
|
-
16
|
47
|
-
|
48
|
-
$ curl --silent http://github.com/api/v2/json/commits/list/mconigliaro/jazor/master | jazor commits.last.message
|
49
|
-
initial commit
|
50
|
-
|
51
|
-
$ jazor '{ "foo": "abc", "bar": [1, 2, 3] }' 'foo.split(//)'
|
52
|
-
["a", "b", "c"]
|
53
|
-
|
54
|
-
$ jazor '{ "foo": "abc", "bar": [1, 2, 3] }' 'bar.inject { |memo,obj| memo + obj }'
|
55
|
-
6
|
56
|
-
|
57
|
-
$ jazor '[1, 2, 3, 4, 5]' 'select(&:even?)'
|
58
|
-
[2, 4]
|
59
|
-
|
60
|
-
$ jazor '[1, 2, 3, 4, 5]' 'select(&:odd?)'
|
61
|
-
[1, 3, 5]
|
62
|
-
|
63
|
-
$ jazor '["a", "b", "c", "d", "e"]' 'self[1..3]'
|
64
|
-
["b", "c", "d"]
|
65
|
-
|
66
|
-
$ jazor '[1, 2, 3, 4, 5]' "'odds=%s; evens=%s' % [select(&:odd?).join(','), select(&:even?).join(',')]"
|
67
|
-
odds=1,3,5; evens=2,4
|
68
|
-
|
69
|
-
== Authors
|
70
|
-
|
71
|
-
* Michael Paul Thomas Conigliaro <mike [at] conigliaro [dot] org>
|
72
|
-
|
73
|
-
== Contributers
|
74
|
-
|
75
|
-
* {Daniel Hopkins}[https://github.com/danielhopkins]
|