jsbin-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,4 @@
1
+ 23 May 2013
2
+ -----------
3
+
4
+ Gem created
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in capybara-screenshot.gemspec
4
+ gemspec
5
+
6
+ gem 'rake'
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 Matthew O'Riordan, inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all 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
19
+ THE SOFTWARE.
@@ -0,0 +1,75 @@
1
+ jsbin-client
2
+ ============
3
+
4
+ jsbin-client is a simple Ruby client for JSBin [http://jsbin.com/](http://jsbin.com/). It provides basic CRUD methods to retrieve a bin, create a bin, and create a revision for an existing bin.
5
+
6
+ The library supports anonymous or token authentication if required by the server.
7
+
8
+ Please see [https://github.com/remy/jsbin/pull/605](https://github.com/remy/jsbin/pull/605) for more information on JSBin's support API requests
9
+
10
+ Installation
11
+ ------------
12
+
13
+ Using Bundler, add the following to your Gemfile
14
+
15
+ gem 'jsbin-client'
16
+
17
+ or install manually using Ruby Gems:
18
+
19
+ gem install jsbin-client
20
+
21
+
22
+ Code example
23
+ ------------
24
+
25
+ ```ruby
26
+ client = JsBinClient.new(host: 'jsbin.com', port: 80, ssl: false)
27
+
28
+ bin = client.create(html: '<html><body></body></html>', javascript: 'console.log("init");', css: 'body { color: red }')
29
+ # => {
30
+ # "html"=>"<html><body></body></html>",
31
+ # "javascript": "console.log(\"init\");",
32
+ # "css": "body { color: red }'",
33
+ # "settings": "{ processors: {} }",
34
+ # "url": "[unique-id]",
35
+ # "revision": 1,
36
+ # "streamingKey": "[key]",
37
+ # "id": 7
38
+ # }
39
+
40
+ bin.get(bin[:url])
41
+ # returns JSON representation of bin
42
+
43
+ bin.create_revision(bin[:url], html: 'updated html')
44
+ # returns JSON representation of new bin revision
45
+
46
+ bin.url_for(bin[:url])
47
+ # => 'http://jsbin.com:80/[unique-id]/edit'
48
+
49
+ bin.url_for(bin[:url], preview: true)
50
+ # => 'http://jsbin.com:80/[unique-id]'
51
+
52
+ bin.url_for(bin[:url], embed: true, panels: ['javascript', 'live'])
53
+ # => 'http://jsbin.com:80/[unique-id]/embed?javascript,live'
54
+ ```
55
+
56
+ Repository
57
+ ----------
58
+
59
+ Please fork, submit patches or feedback at [https://github.com/mattheworiordan/jsbin-client](https://github.com/mattheworiordan/jsbin-client)
60
+
61
+ The gem details on RubyGems.org can be found at [https://rubygems.org/gems/jsbin-client](https://rubygems.org/gems/jsbin-client)
62
+
63
+ About
64
+ -----
65
+
66
+ This gem was written by **Matthew O'Riordan**
67
+
68
+ - [http://mattheworiordan.com](http://mattheworiordan.com)
69
+ - [@mattheworiordan](http://twitter.com/#!/mattheworiordan)
70
+ - [Linked In](http://www.linkedin.com/in/lemon)
71
+
72
+ License
73
+ -------
74
+
75
+ Copyright © 2013 Matthew O'Riordan, inc. It is free software, and may be redistributed under the terms specified in the LICENSE file.
@@ -0,0 +1,6 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ task :default => :spec
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "jsbin-client/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "jsbin-client"
7
+ s.version = JsBinClient::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Matthew O'Riordan"]
10
+ s.email = ["matthew.oriordan@gmail.com"]
11
+ s.homepage = "http://github.com/mattheworiordan/jsbin-client"
12
+ s.summary = %q{A simple API client for JSBin}
13
+ s.description = %q{Provides methods to add, update, create revisions of bins and obtain bin preview URLs}
14
+
15
+ s.rubyforge_project = "jsbin-client"
16
+
17
+ s.add_dependency 'rest-client', '>= 1.6'
18
+
19
+ s.add_development_dependency 'rspec', '~> 2.7'
20
+ s.add_development_dependency 'webmock', '~> 1.11'
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+ end
@@ -0,0 +1,55 @@
1
+ require 'jsbin-client/config'
2
+ require 'jsbin-client/exceptions'
3
+ require 'jsbin-client/rest'
4
+ require 'ostruct'
5
+ require 'rest-client'
6
+
7
+ class JsBinClient
8
+ API_PREFIX = 'api/'
9
+ attr_reader :options
10
+
11
+ def initialize(options_param = {})
12
+ @options = OpenStruct.new(Config.to_hash.merge(options_param || {}))
13
+ @rest = Rest.new(@options)
14
+ end
15
+
16
+ # retrieve a bin
17
+ def get(id, revision = nil)
18
+ url = [id, revision].compact.join('/')
19
+ @rest.get(url)
20
+ end
21
+
22
+ # create a new bin
23
+ def create(bin_params)
24
+ @rest.post('save', bin_params)
25
+ end
26
+
27
+ # create revision for bin
28
+ def create_revision(id, bin_params)
29
+ @rest.post("#{id}/save", bin_params)
30
+ end
31
+
32
+ # URL for JSBin
33
+ def url_for(id, options = {})
34
+ panels = options[:panels]
35
+ if options[:panels].kind_of?(Array)
36
+ panels = options[:panels].join(',')
37
+ end
38
+
39
+ url = "#{@options.ssl ? 'https' : 'http'}://#{@options.host}:#{@options.port}/#{id}"
40
+ url << if options[:revision]
41
+ "/#{options[:revision]}"
42
+ else
43
+ "/latest"
44
+ end
45
+ if options[:embed]
46
+ url << "/embed"
47
+ url << "?#{panels}" unless panels.nil?
48
+ elsif !options[:preview]
49
+ url << "/edit"
50
+ url << "##{panels}" unless panels.nil?
51
+ end
52
+
53
+ url
54
+ end
55
+ end
@@ -0,0 +1,28 @@
1
+ class JsBinClient
2
+ class Config
3
+ @host = 'jsbin.com'
4
+ @ssl = false
5
+ @basic_port = 80
6
+ @ssl_port = 443
7
+
8
+ class << self
9
+ attr_reader :host, :ssl, :basic_port
10
+
11
+ def port
12
+ if ssl
13
+ @ssl_port
14
+ else
15
+ @basic_port
16
+ end
17
+ end
18
+
19
+ def to_hash
20
+ {
21
+ host: host,
22
+ ssl: ssl,
23
+ port: port
24
+ }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,6 @@
1
+ class JsBinClient
2
+ class AuthenticationRequired < StandardError; end
3
+ class OwnershipError < StandardError; end
4
+ class BinMissing < StandardError; end
5
+ class InvalidJson < StandardError; end
6
+ end
@@ -0,0 +1,74 @@
1
+ require 'json'
2
+
3
+ class JsBinClient
4
+ class Rest
5
+ def initialize(options)
6
+ @options = options
7
+ end
8
+
9
+ def get(path)
10
+ rest_request :get, "#{end_point}#{path}", headers
11
+ end
12
+
13
+ def put(path, params = {})
14
+ rest_request :put, "#{end_point}#{path}", params, headers
15
+ end
16
+
17
+ def post(path, params = {})
18
+ rest_request :post, "#{end_point}#{path}", params, headers
19
+ end
20
+
21
+ private
22
+ def end_point
23
+ "#{@options.ssl? ? 'https' : 'http'}://#{@options.host}:#{@options.port}/#{API_PREFIX}"
24
+ end
25
+
26
+ def headers
27
+ if @options.respond_to?(:api_key)
28
+ { authorization: "token #{@options.api_key}" }
29
+ else
30
+ {}
31
+ end
32
+ end
33
+
34
+ def rest_request(*args)
35
+ begin
36
+ IndifferentJson.new(RestClient.send(args.first, *args[1..-1]))
37
+ rescue JSON::ParserError => e
38
+ raise InvalidJson, e.message
39
+ rescue RestClient::ResourceNotFound => e
40
+ raise BinMissing, e.message
41
+ rescue RestClient::RequestFailed => e
42
+ if e.message =~ /^403/
43
+ message = JSON.parse(e.response)['error'] rescue nil
44
+ exception = if !message.nil? && message.match(/owner/)
45
+ OwnershipError
46
+ else
47
+ AuthenticationRequired
48
+ end
49
+ raise exception, message || e.message
50
+ else
51
+ raise e
52
+ end
53
+ end
54
+ end
55
+
56
+ class IndifferentJson
57
+ def initialize(json_string)
58
+ @json = JSON.parse(json_string)
59
+ end
60
+
61
+ def [](id)
62
+ @json[id.to_s]
63
+ end
64
+
65
+ def keys
66
+ @json.keys
67
+ end
68
+
69
+ def values
70
+ @json.values
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,3 @@
1
+ class JsBinClient
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,152 @@
1
+ require 'spec_helper'
2
+
3
+ describe JsBinClient::Config do
4
+ subject { JsBinClient::Config }
5
+
6
+ its(:host) { should == 'jsbin.com' }
7
+ its(:port) { should == 80 }
8
+ its(:ssl) { should be_false }
9
+
10
+ context 'when using ssl' do
11
+ before { JsBinClient::Config.stub(:ssl) { true } }
12
+ after { JsBinClient::Config.rspec_reset }
13
+
14
+ its(:port) { should == 443 }
15
+ end
16
+ end
17
+
18
+ describe JsBinClient do
19
+ def json_response(url, revision, options = {})
20
+ %{
21
+ {
22
+ "id": 1,
23
+ "html": "#{options[:html] || '<html></html>'}",
24
+ "css": "#{options[:css] || 'body { color: red }'}",
25
+ "javascript": "#{options[:javascript] || 'console.log(\'loaded\');'}",
26
+ "created": "2013-05-23T15:50:19.850Z",
27
+ "last_viewed": "2013-05-23T15:50:19.800Z",
28
+ "url": "#{url}",
29
+ "active": true,
30
+ "reported": null,
31
+ "streaming": "n",
32
+ "streaming_key": "479be77ce3819c266b00bcddb97795e8",
33
+ "streaming_read_key": "479be77ce3819c266b00bcddb97795e8",
34
+ "active_tab": null,
35
+ "active_cursor": null,
36
+ "revision": #{revision},
37
+ "settings": {
38
+ "processors": {}
39
+ },
40
+ "last_updated": "2012-07-23T00:00:00.000Z"
41
+ }
42
+ }
43
+ end
44
+
45
+ context 'when initialising with options' do
46
+ subject { JsBinClient.new(host: 'localhost', port: 8080, api_key: 'example' ).options }
47
+
48
+ its(:host) { should == 'localhost' }
49
+ its(:port) { should == 8080 }
50
+ its(:ssl) { should be_false }
51
+ its(:api_key) { should == 'example' }
52
+ end
53
+
54
+ context 'retrieving a bin' do
55
+ subject { JsBinClient.new(host: 'localhost', port: 8080) }
56
+ let(:stub_path) { "http://localhost:8080/#{JsBinClient::API_PREFIX}" }
57
+
58
+ it 'should throw an exception if missing' do
59
+ stub_request(:get, "#{stub_path}invalid").to_return(status: 404, body: '{"error":"message"}')
60
+ expect { subject.get('invalid') }.to raise_exception JsBinClient::BinMissing
61
+ end
62
+
63
+ it 'should return valid data' do
64
+ url_id = '1234'
65
+ stub_request(:get, "#{stub_path}#{url_id}").to_return(status: 200, body: json_response(url_id, 1))
66
+ response = subject.get(url_id)
67
+
68
+ response[:javascript].should match(/console\.log/)
69
+ response[:css].should match(/red/)
70
+ response[:html].should match(/html/)
71
+ response[:id].should == 1
72
+ response[:url].should == url_id
73
+ end
74
+ end
75
+
76
+ context 'creating a bin' do
77
+ subject { JsBinClient.new(host: 'localhost', port: 8080) }
78
+ let(:stub_path) { "http://localhost:8080/#{JsBinClient::API_PREFIX}" }
79
+ let(:new_id) { '1234' }
80
+ let(:bin_params) { { html: 'html1', javascript: 'javascript1', css: 'css1' } }
81
+
82
+ specify do
83
+ stub_request(:post, "#{stub_path}save").to_return(status: 200, body: json_response(new_id, 1, bin_params))
84
+ response = subject.create(bin_params)
85
+
86
+ [:javascript, :css, :html].each { |p| response[p].should == bin_params[p] }
87
+ response[:url].should == new_id
88
+
89
+ a_request(:post, "#{stub_path}save").with(:body => bin_params).should have_been_made.once
90
+ end
91
+ end
92
+
93
+ context 'create a revision for a bin' do
94
+ subject { JsBinClient.new(host: 'localhost', port: 8080) }
95
+ let(:stub_path) { "http://localhost:8080/#{JsBinClient::API_PREFIX}" }
96
+ let(:url_id) { '1234' }
97
+ let(:bin_params) { { html: 'html1', javascript: 'javascript1', css: 'css1' } }
98
+
99
+ specify do
100
+ stub_request(:post, "#{stub_path}#{url_id}/save").to_return(status: 200, body: json_response(url_id, 1, bin_params))
101
+ response = subject.create_revision(url_id, bin_params)
102
+
103
+ [:javascript, :css, :html].each { |p| response[p].should == bin_params[p] }
104
+ response[:url].should == url_id
105
+
106
+ a_request(:post, "#{stub_path}#{url_id}/save").with(:body => bin_params).should have_been_made.once
107
+ end
108
+ end
109
+
110
+ context '#url_for' do
111
+ subject { JsBinClient.new(host: 'localhost', port: 8080) }
112
+ let(:url_path) { "http://localhost:8080/" }
113
+ let(:url_id) { 'asdsad' }
114
+
115
+ it 'should return edit URL without revision by default' do
116
+ subject.url_for(url_id).should == "#{url_path}#{url_id}/latest/edit"
117
+ end
118
+
119
+ it 'should return edit URL with revision by default' do
120
+ subject.url_for(url_id, revision: 3).should == "#{url_path}#{url_id}/3/edit"
121
+ end
122
+
123
+ it 'should return preview URL without revision' do
124
+ subject.url_for(url_id, preview: true).should == "#{url_path}#{url_id}/latest"
125
+ end
126
+
127
+ it 'should return preview URL with revision' do
128
+ subject.url_for(url_id, preview: true, revision: 3).should == "#{url_path}#{url_id}/3"
129
+ end
130
+
131
+ it 'should return edit URL with panels with revision' do
132
+ subject.url_for(url_id, revision: 3, panels: 'javascript,html').should == "#{url_path}#{url_id}/3/edit#javascript,html"
133
+ end
134
+
135
+ it 'should return edit URL with panels from array' do
136
+ subject.url_for(url_id, panels: %w(javascript html)).should == "#{url_path}#{url_id}/latest/edit#javascript,html"
137
+ end
138
+
139
+ it 'should return embeddable URL with revision with panels' do
140
+ subject.url_for(url_id, embed: true, revision: 3, panels: %w(javascript live)).should == "#{url_path}#{url_id}/3/embed?javascript,live"
141
+ end
142
+
143
+ it 'should return embeddable URL' do
144
+ subject.url_for(url_id, embed: true).should == "#{url_path}#{url_id}/latest/embed"
145
+ end
146
+
147
+ it 'should support SSL' do
148
+ client = JsBinClient.new(host: 'jsbin.com', port: 443, ssl: true)
149
+ client.url_for(url_id, preview: true).should == "https://jsbin.com:443/#{url_id}/latest"
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+
4
+ describe 'JsBinClient::Rest' do
5
+ let(:bin_id) { 'exampleID' }
6
+ let(:options) { OpenStruct.new({ host: 'host', port: 8080, ssl: false, api_key: '3' }) }
7
+ let(:url) { "http://host:8080/api/#{bin_id}" }
8
+ subject { JsBinClient::Rest.new(options)}
9
+
10
+ context 'should use the options' do
11
+ before { stub_request(:get, url).to_return(status: 200, body: '{"response":"valid"}') }
12
+ after { a_request(:get, url).with(:headers => {'authorization' => 'token 3'}).should have_been_made.once }
13
+
14
+ specify do
15
+ subject.get(bin_id)['response'].should == 'valid'
16
+ end
17
+
18
+ it 'over SSL' do
19
+ options.ssl = true
20
+ subject.get(bin_id)['response'].should == 'valid'
21
+ end
22
+
23
+ it 'and return indifferent JSON' do
24
+ subject.get(bin_id)[:response].should == 'valid'
25
+ end
26
+ end
27
+
28
+ context 'should support all HTTP verbs' do
29
+ let(:methods) { %w(get post put) }
30
+ before do
31
+ methods.each { |method| stub_request(method.to_sym, url).to_return(status: 200, body: "{\"method\":\"#{method}\"}") }
32
+ end
33
+
34
+ specify do
35
+ methods.each do |method|
36
+ subject.send(method.to_sym, bin_id)['method'].should == method
37
+ end
38
+ end
39
+ end
40
+
41
+ context 'should catch invalid JSON response' do
42
+ before { stub_request(:get, url).to_return(status: 200, body: 'this is not JSON') }
43
+ specify do
44
+ expect { subject.get(bin_id) }.to raise_exception(JsBinClient::InvalidJson)
45
+ end
46
+ end
47
+
48
+ context 'should catch a JSBin' do
49
+ specify '404 error' do
50
+ stub_request(:get, url).to_return(status: 404, body: '{"error":"message"}')
51
+ expect { subject.get(bin_id) }.to raise_exception(JsBinClient::BinMissing)
52
+ end
53
+
54
+ specify 'ownership 403 error' do
55
+ stub_request(:get, url).to_return(status: 403, body: '{"error":"You are not the owner"}')
56
+ expect { subject.get(bin_id) }.to raise_exception(JsBinClient::OwnershipError, 'You are not the owner')
57
+ end
58
+
59
+ specify 'permission 403 error' do
60
+ stub_request(:get, url).to_return(status: 403, body: '{"error":"The API key you provided is not valid"}')
61
+ expect { subject.get(bin_id) }.to raise_exception(JsBinClient::AuthenticationRequired, 'The API key you provided is not valid')
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,10 @@
1
+ $: << '../lib'
2
+ require 'jsbin-client'
3
+ require 'webmock'
4
+ require 'webmock/rspec'
5
+
6
+ RSpec.configure do |config|
7
+ # using standard RSpec config
8
+ end
9
+
10
+ WebMock.disable_net_connect!
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jsbin-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matthew O'Riordan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rest-client
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '1.6'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '1.6'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.7'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.7'
46
+ - !ruby/object:Gem::Dependency
47
+ name: webmock
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.11'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.11'
62
+ description: Provides methods to add, update, create revisions of bins and obtain
63
+ bin preview URLs
64
+ email:
65
+ - matthew.oriordan@gmail.com
66
+ executables: []
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - .rspec
72
+ - CHANGELOG.md
73
+ - Gemfile
74
+ - LICENSE
75
+ - README.md
76
+ - Rakefile
77
+ - jsbin-client.gemspec
78
+ - lib/jsbin-client.rb
79
+ - lib/jsbin-client/config.rb
80
+ - lib/jsbin-client/exceptions.rb
81
+ - lib/jsbin-client/rest.rb
82
+ - lib/jsbin-client/version.rb
83
+ - spec/jsbin-client_spec.rb
84
+ - spec/rest_spec.rb
85
+ - spec/spec_helper.rb
86
+ homepage: http://github.com/mattheworiordan/jsbin-client
87
+ licenses: []
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ segments:
99
+ - 0
100
+ hash: -3100341442518055608
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ segments:
108
+ - 0
109
+ hash: -3100341442518055608
110
+ requirements: []
111
+ rubyforge_project: jsbin-client
112
+ rubygems_version: 1.8.24
113
+ signing_key:
114
+ specification_version: 3
115
+ summary: A simple API client for JSBin
116
+ test_files: []