thebigdb 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ # See http://help.github.com/ignore-files/ for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile ~/.gitignore_global
6
+
7
+ # Ignore bundler config
8
+ /.bundle
9
+
10
+ *;*
11
+ .backups
12
+ .DS_Store
13
+ log/*
14
+ ._*
15
+ .__*
16
+ *~
17
+ *.swp
18
+ .rvmrc
19
+ *.gem
20
+ tmp/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,60 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ thebigdb (1.0.0)
5
+ rack (~> 1.4)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ addressable (2.3.2)
11
+ coderay (1.0.8)
12
+ crack (0.3.1)
13
+ diff-lcs (1.1.3)
14
+ ffi (1.2.0)
15
+ guard (1.5.4)
16
+ listen (>= 0.4.2)
17
+ lumberjack (>= 1.0.2)
18
+ pry (>= 0.9.10)
19
+ thor (>= 0.14.6)
20
+ guard-rspec (2.3.1)
21
+ guard (>= 1.1)
22
+ rspec (~> 2.11)
23
+ listen (0.6.0)
24
+ lumberjack (1.0.2)
25
+ method_source (0.8.1)
26
+ pry (0.9.10)
27
+ coderay (~> 1.0.5)
28
+ method_source (~> 0.8)
29
+ slop (~> 3.3.1)
30
+ rack (1.4.1)
31
+ rb-fchange (0.0.6)
32
+ ffi
33
+ rb-fsevent (0.9.2)
34
+ rb-inotify (0.8.8)
35
+ ffi (>= 0.5.0)
36
+ rspec (2.12.0)
37
+ rspec-core (~> 2.12.0)
38
+ rspec-expectations (~> 2.12.0)
39
+ rspec-mocks (~> 2.12.0)
40
+ rspec-core (2.12.1)
41
+ rspec-expectations (2.12.0)
42
+ diff-lcs (~> 1.1.3)
43
+ rspec-mocks (2.12.0)
44
+ slop (3.3.3)
45
+ thor (0.16.0)
46
+ webmock (1.9.0)
47
+ addressable (>= 2.2.7)
48
+ crack (>= 0.1.7)
49
+
50
+ PLATFORMS
51
+ ruby
52
+
53
+ DEPENDENCIES
54
+ guard-rspec (~> 2.3)
55
+ rb-fchange
56
+ rb-fsevent
57
+ rb-inotify
58
+ rspec (~> 2.12)
59
+ thebigdb!
60
+ webmock (~> 1.9)
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ guard 'rspec' do
2
+ watch("spec/spec_helper.rb") { "spec" }
3
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
4
+
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/thebigdb\.rb$}) { "spec" }
7
+ watch(%r{^lib/thebigdb/(.+)\.rb$}) {|m| "spec/#{m[1]}_spec.rb" }
8
+ end
data/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013, Christophe Maximin <christophe@thebigdb.com>
4
+
5
+ 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:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ 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.
data/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # TheBigDB Ruby Wrapper
2
+
3
+ A simple ruby wrapper for making requests to the API of [TheBigDB.com][0].
4
+
5
+ ## Install
6
+
7
+ gem install thebigdb
8
+
9
+ ## Usage
10
+
11
+ Make your requests using this structure:
12
+
13
+
14
+ TheBigDB::Statement(action, parameters)
15
+
16
+
17
+ **[action]** => String of the action as described in the API (e.g. "search", "show", ...)
18
+ **[parameters]** => Hash. Request parameters as described in the API. Tip: Arrays like ``["abc", "def"]`` will automatically be converted to ``{"0" => "abc", "1" => "def"}``
19
+
20
+
21
+ Examples:
22
+
23
+ request = TheBigDB::Statement(:search,
24
+ {
25
+ nodes: [{search: ""}, "job", "President of the United States"],
26
+ period: {from: "2000-01-01 00:00:00", to: "2002-01-01 00:00:00"}
27
+ }
28
+ )
29
+
30
+ puts request.response
31
+
32
+ Will print something like:
33
+
34
+ {
35
+ "status" => "success",
36
+ "statements" => [
37
+ {"nodes" => ["Bill Clinton", "job", "President of the United States"], "id" => "8e6aec890c942b6f7854d2d7a9f0d002f5ddd0c0", "period"=>{"from" => "1993-01-20 00:00:00", "to" => "2001-01-20 00:00:00"}},
38
+ {"nodes" => ["George W. Bush", "job", "President of the United States"], "id" => "3f27673816455054032bd46e65bbe4db8ccf9076", "period"=>{"from" => "2001-01-20 00:00:00", "to" => "2009-01-20 00:00:00"}}
39
+ ]
40
+ }
41
+
42
+ That's it!
43
+
44
+ ## The TheBigDB::Request object
45
+
46
+ Every request you make will return a ``TheBigDB::Request`` object.
47
+ It has several readable attributes:
48
+
49
+ request = TheBigDB::Statement(:search, {nodes: ["iPhone", "weight"]})
50
+ request.http # Net::HTTP
51
+ request.http_request # subclass of Net::HTTPGenericRequest (Net::HTTP::Get or Net::HTTP::Post)
52
+ request.http_response # subclass of Net::HTTPResponse (e.g. Net::HTTPOK)
53
+ request.data_sent # Hash of the data sent, keys: "headers", "host", "port", "path", "method", "params"
54
+ request.data_received # Hash of the data received, keys: "headers", "content"
55
+ request.response # Hash, body of the http response converted from json
56
+
57
+ ## Other Features
58
+
59
+ You can access other parts of the API in the same way as statements:
60
+
61
+ TheBigDB::User(action, parameters)
62
+ TheBigDB::Toolbox::Unit(action, parameters)
63
+
64
+ # Examples
65
+ TheBigDB::User(:show, {login: "christophe"}).response["user"]["karma"]
66
+ TheBigDB::Toolbox::Unit(:compare, {values: ["100 g", "1.2 kg"]}).response["result"]
67
+
68
+ You can modify the TheBigDB module with several configuration options:
69
+
70
+ TheBigDB.api_key = "your-private-api-key" # default: nil
71
+ TheBigDB.use_ssl = true # default: false
72
+
73
+ # Both of them take a Proc or a Lambda, the TheBigDB::Request instance is passed as argument
74
+ TheBigDB.before_request_execution = ->(request){ Logger.foo(request) } # default: Proc.new{}
75
+ TheBigDB.after_request_execution = ->(request){ Logger.foo(request) } # default: Proc.new{}
76
+
77
+
78
+ ## Contributing
79
+
80
+ Don't hesitate to send a pull request !
81
+
82
+ ## Testing
83
+
84
+ rspec spec/
85
+
86
+ ## License
87
+
88
+ This software is distributed under the MIT License. Copyright (c) 2013, Christophe Maximin <christophe@thebigdb.com>
89
+
90
+
91
+ [0]: http://thebigdb.com
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'rspec/core/rake_task'
2
+ RSpec::Core::RakeTask.new('spec')
3
+
4
+ desc "Run tests"
5
+ task :default => [:spec]
@@ -0,0 +1,4 @@
1
+ # Because a lot of people are bound to make those mistakes
2
+ Thebigdb = TheBigDB
3
+ TheBigDb = TheBigDB
4
+ TheBigdb = TheBigDB
@@ -0,0 +1,43 @@
1
+ # Heavily inspired by "core_ext/module/attribute_accessors" from activesupport (4.0.0.beta)
2
+ module TheBigDB
3
+ def self.mattr_reader(*syms)
4
+ syms.each do |sym|
5
+ raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
6
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
7
+ @@#{sym} = nil unless defined? @@#{sym}
8
+
9
+ def self.#{sym}
10
+ @@#{sym}
11
+ end
12
+ EOS
13
+
14
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
15
+ def #{sym}
16
+ @@#{sym}
17
+ end
18
+ EOS
19
+ end
20
+ end
21
+
22
+ def self.mattr_writer(*syms)
23
+ syms.each do |sym|
24
+ raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
25
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
26
+ def self.#{sym}=(obj)
27
+ @@#{sym} = obj
28
+ end
29
+ EOS
30
+
31
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
32
+ def #{sym}=(obj)
33
+ @@#{sym} = obj
34
+ end
35
+ EOS
36
+ end
37
+ end
38
+
39
+ def self.mattr_accessor(*syms)
40
+ mattr_reader(*syms)
41
+ mattr_writer(*syms)
42
+ end
43
+ end
@@ -0,0 +1,145 @@
1
+ module TheBigDB
2
+ class Request
3
+ attr_reader :http, :http_request, :http_response, :data_sent, :data_received, :response
4
+
5
+ # Prepares the basic @http object with the current values of the module (host, port, ...)
6
+ def initialize
7
+ @http = Net::HTTP.new(TheBigDB.api_host, TheBigDB.api_port)
8
+
9
+ if TheBigDB.use_ssl
10
+ @http.use_ssl = true
11
+ if TheBigDB.verify_ssl_certificates
12
+ raise NotImplementedError
13
+ else
14
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
15
+ end
16
+ end
17
+ end
18
+
19
+ # Prepares the @http_request object with the actual content of the request
20
+ def prepare(method, request_uri, params = {})
21
+ method = method.downcase.to_s
22
+
23
+ # we add the API version to the URL, with a trailing slash and the rest of the request
24
+ request_uri = "/v#{TheBigDB.api_version}" + (request_uri.start_with?("/") ? request_uri : "/#{request_uri}")
25
+
26
+ if method == "get"
27
+ encoded_params = TheBigDB::Request::serialize_query_params(params)
28
+ @http_request = Net::HTTP::Get.new(request_uri + "?" + encoded_params)
29
+ elsif method == "post"
30
+ @http_request = Net::HTTP::Post.new(request_uri)
31
+ @http_request.set_form_data(TheBigDB::Request::flatten_params_keys(params))
32
+ else
33
+ raise ArgumentError, "The request method must be 'get' or 'post'"
34
+ end
35
+
36
+ @http_request["user-agent"] = "TheBigDB RubyWrapper/#{TheBigDB::VERSION::STRING}"
37
+
38
+ client_user_agent = {
39
+ :publisher => "thebigdb",
40
+ :version => TheBigDB::VERSION::STRING,
41
+ :language => "ruby",
42
+ :language_version => "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})",
43
+ }
44
+
45
+ @http_request["X-TheBigDB-Client-User-Agent"] = JSON(client_user_agent)
46
+
47
+ self
48
+ end
49
+
50
+ # Actually makes the request prepared in @http_request, and sets @http_response
51
+ def execute
52
+ # Here is the order of operations:
53
+ # -> executing before_request_execution callback
54
+ # -> executing the HTTP request
55
+ # -> setting @response
56
+ # -> setting @data_sent
57
+ # -> setting @data_received
58
+ # -> executing after_request_execution callback
59
+
60
+ # Executing callback
61
+ TheBigDB.before_request_execution.call(self)
62
+
63
+ # Here is where the request is actually executed
64
+ @http_response = @http.request(@http_request)
65
+
66
+ # Setting @response
67
+ begin
68
+ # We parse the JSON answer and return it.
69
+ @response = JSON(@http_response.body)
70
+ rescue JSON::ParserError => e
71
+ @response = {"error" => {"code" => "0000", "description" => "The server gave an invalid JSON body:\n#{@http_response.body}"}}
72
+ end
73
+
74
+ # Setting @data_sent and @data_received
75
+ params = Rack::Utils.parse_nested_query(URI.parse(@http_request.path).query)
76
+ # Since that's how it will be interpreted anyway on the server, we merge the POST params to the GET params,
77
+ # but it's not supposed to happen: either every params is prepared for GET/query params, or as POST body
78
+ params.merge!(Rack::Utils.parse_nested_query(@http_request.body.to_s))
79
+
80
+ # About: Hash[{}.map{|k,v| [k, v.join] }]
81
+ # it transforms the following hash:
82
+ # {"accept"=>["*/*"], "user-agent"=>["TheBigDB RubyWrapper/X.Y.Z"], "host"=>["computer.host"]}
83
+ # into the following hash:
84
+ # {"accept"=>"*/*", "user-agent"=>"TheBigDB RubyWrapper/X.Y.Z", "host"=>"computer.host"}
85
+ # which is way more useful and cleaner.
86
+ @data_sent = {
87
+ "headers" => Hash[@http_request.to_hash.map{|k,v| [k, v.join] }],
88
+ "host" => @http.address,
89
+ "port" => @http.port,
90
+ "path" => URI.parse(@http_request.path).path,
91
+ "method" => @http_request.method,
92
+ "params" => params
93
+ }
94
+
95
+ @data_received = {
96
+ "headers" => Hash[@http_response.to_hash.map{|k,v| [k, v.join] }],
97
+ "content" => @response
98
+ }
99
+
100
+ TheBigDB.after_request_execution.call(self)
101
+
102
+ self
103
+ end
104
+
105
+ ##############
106
+ ## Engine Helpers
107
+ ##############
108
+
109
+ # serialize_query_params({house: "bricks", animals: ["cat", "dog"], computers: {cool: true, drives: ["hard", "flash"]}})
110
+ # => house=bricks&animals%5B%5D=cat&animals%5B%5D=dog&computers%5Bcool%5D=true&computers%5Bdrives%5D%5B%5D=hard&computers%5Bdrives%5D%5B%5D=flash
111
+ # which will be read by the server as:
112
+ # => house=bricks&animals[]=cat&animals[]=dog&computers[cool]=true&computers[drives][]=hard&computers[drives][]=flash
113
+ def self.serialize_query_params(params, prefix = nil)
114
+ ret = []
115
+ params.each_pair do |key, value|
116
+ param_key = prefix ? "#{prefix}[#{key}]" : key
117
+
118
+ if value.is_a?(Hash)
119
+ ret << self.serialize_query_params(value, param_key.to_s)
120
+ elsif value.is_a?(Array)
121
+ sub_hash = {}
122
+ value.each_with_index do |value_item, i|
123
+ sub_hash[i.to_s] = value_item
124
+ end
125
+ ret << self.serialize_query_params(sub_hash, param_key.to_s)
126
+ else
127
+ ret << URI.encode_www_form_component(param_key.to_s) + "=" + URI.encode_www_form_component(value.to_s)
128
+ end
129
+ end
130
+ ret.join("&")
131
+ end
132
+
133
+ # flatten_params_keys({house: "bricks", animals: ["cat", "dog"], computers: {cool: true, drives: ["hard", "flash"]}})
134
+ # => {"house" => "bricks", "animals[0]" => "cat", "animals[1]" => "dog", "computers[cool]" => "true", "computers[drives][0]" => "hard", "computers[drives][1]" => "flash"}
135
+ def self.flatten_params_keys(params)
136
+ serialized_params = self.serialize_query_params(params)
137
+ new_params = {}
138
+ serialized_params.split("&").each do |assign|
139
+ key, value = assign.split("=")
140
+ new_params[URI.decode(key)] = URI.decode(value)
141
+ end
142
+ new_params
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,10 @@
1
+ module TheBigDB
2
+ def self.Statement(action, params)
3
+ method = ["get", "show", "search"].include?(action.to_s) ? "GET" : "POST"
4
+ path = "/statements/#{action}"
5
+
6
+ request = TheBigDB::Request.new
7
+ request.prepare(method, path, params)
8
+ request.execute
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ module TheBigDB
2
+ module Toolbox
3
+ def self.Unit(action, params)
4
+ method = "GET"
5
+ path = "/toolbox/units/#{action}"
6
+
7
+ request = TheBigDB::Request.new
8
+ request.prepare(method, path, params)
9
+ request.execute
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ module TheBigDB
2
+ def self.User(action, params)
3
+ method = "GET"
4
+ path = "/users/#{action}"
5
+
6
+ request = TheBigDB::Request.new
7
+ request.prepare(method, path, params)
8
+ request.execute
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module TheBigDB
2
+ module VERSION
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ TINY = 0
6
+
7
+ STRING = [MAJOR, MINOR, TINY].compact.join('.')
8
+ end
9
+ end
data/lib/thebigdb.rb ADDED
@@ -0,0 +1,75 @@
1
+ require "net/https"
2
+ require "json"
3
+ require "rack"
4
+
5
+ %w(
6
+ module_attribute_accessors
7
+ aliases
8
+ request
9
+ version
10
+ resources/statement
11
+ resources/user
12
+ resources/toolbox
13
+ ).each do |file_name|
14
+ require File.join(File.dirname(__FILE__), 'thebigdb', file_name)
15
+ end
16
+
17
+ module TheBigDB
18
+
19
+ DEFAULT_VALUES = {
20
+ "api_host" => "api.thebigdb.com",
21
+ "api_port" => 80,
22
+ "api_version" => "1",
23
+ "use_ssl" => false,
24
+ "verify_ssl_certificates" => false,
25
+ "before_request_execution" => Proc.new{},
26
+ "after_request_execution" => Proc.new{}
27
+ }
28
+
29
+ mattr_accessor :api_host, :api_port, :api_version, :api_key
30
+ mattr_accessor :use_ssl, :verify_ssl_certificates
31
+ mattr_accessor :before_request_execution, :after_request_execution
32
+
33
+ def self.reset_default_values
34
+ DEFAULT_VALUES.each_pair do |key, value|
35
+ send(key + "=", value)
36
+ end
37
+ end
38
+ reset_default_values
39
+
40
+ def self.use_ssl=(bool)
41
+ @@api_port = bool ? 443 : 80
42
+ @@use_ssl = bool
43
+ end
44
+
45
+ def self.verify_ssl_certificates=(bool)
46
+ if bool
47
+ raise NotImplementedError, "The certificates are never checked"
48
+ end
49
+ @@verify_ssl_certificates = bool
50
+ end
51
+
52
+ def self.before_request_execution=(object)
53
+ unless object.is_a?(Proc)
54
+ raise ArgumentError, "You must pass a proc or lambda"
55
+ end
56
+ @@before_request_execution = object
57
+ end
58
+
59
+ def self.after_request_execution=(object)
60
+ unless object.is_a?(Proc)
61
+ raise ArgumentError, "You must pass a proc or lambda"
62
+ end
63
+ @@after_request_execution = object
64
+ end
65
+
66
+
67
+ # Shortcut: prepares, executes and returns Hash containing the server's response
68
+ def self.send_request(*args)
69
+ request = Request.new
70
+ request.prepare(*args)
71
+ request.execute
72
+ request.response
73
+ end
74
+
75
+ end
@@ -0,0 +1,315 @@
1
+ require "spec_helper"
2
+
3
+ # Here we're testing standard requests behaviour,
4
+ # what they send, what they receive,
5
+ # and how they incorporate them into this wrapper's objects.
6
+
7
+ describe "initializing requests" do
8
+ before do
9
+ @request = TheBigDB::Request.new
10
+ end
11
+
12
+ it "sets a http instance variable with correct attributes" do
13
+ @request.http.address.should == TheBigDB.api_host
14
+ @request.http.port.should == TheBigDB.api_port
15
+ end
16
+ end
17
+
18
+ describe "preparing" do
19
+ context "GET requests" do
20
+ before do
21
+ @request = TheBigDB::Request.new
22
+ @request.prepare(:get, "/abc", :foo => "bar")
23
+ end
24
+
25
+ it "sets a http_request instance variable with correct attributes" do
26
+ http_request = @request.http_request
27
+ http_request.method == "GET"
28
+ http_request.path.should == "/v#{TheBigDB.api_version}/abc?foo=bar"
29
+ end
30
+ end
31
+
32
+ context "POST requests" do
33
+ before do
34
+ @request = TheBigDB::Request.new
35
+ @request.prepare(:post, "/abc", :foo => "bar")
36
+ end
37
+
38
+ it "sets a http_request instance variable with correct attributes" do
39
+ http_request = @request.http_request
40
+ http_request.method == "POST"
41
+ http_request.path.should == "/v#{TheBigDB.api_version}/abc"
42
+ http_request.body.should == "foo=bar"
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "executing" do
48
+
49
+ context "requests" do
50
+ before do
51
+ stub_request(:get, /#{TheBigDB.api_host}/).to_return(:body => '{"server_says": "hello world"}')
52
+
53
+ @request = TheBigDB::Request.new
54
+ @request.prepare(:get, "/", :foo => "bar")
55
+ @request.execute
56
+ end
57
+
58
+ it "sends the correct HTTP request" do
59
+ a_request(:get, /#{TheBigDB.api_host}/).with(:query => {"foo" => "bar"}).should have_been_made
60
+ end
61
+
62
+ it "sets the correct http_response object" do
63
+ @request.http_response.body.should == '{"server_says": "hello world"}'
64
+ end
65
+
66
+ it "sets the correct response Hash" do
67
+ @request.response.should == {"server_says" => "hello world"}
68
+ end
69
+ end
70
+
71
+ context "requests with before/after callbacks" do
72
+ it "runs both of them" do
73
+ stub_request(:get, /#{TheBigDB.api_host}/).to_return(:body => "{}")
74
+
75
+ String.should_receive(:new).with("called in before_execution")
76
+ String.should_receive(:new).with("called in after_execution")
77
+
78
+ TheBigDB.before_request_execution = proc { String.new("called in before_execution") }
79
+ TheBigDB.after_request_execution = proc { String.new("called in after_execution") }
80
+
81
+ TheBigDB.send_request(:get, "/")
82
+ end
83
+ end
84
+
85
+ context "GET requests" do
86
+ context "with basic params" do
87
+ before do
88
+ stub_request(:get, /#{TheBigDB.api_host}/).to_return(:body => '{"server_says": "hello world"}')
89
+
90
+ @request = TheBigDB::Request.new
91
+ @request.prepare(:get, "/", :foo => "bar")
92
+ @request.execute
93
+ end
94
+
95
+ it "sets the correct data_sent instance variable" do
96
+ @request.data_sent.should == {
97
+ "headers" => Hash[@request.http_request.to_hash.map{|k,v| [k, v.join] }],
98
+ "host" => TheBigDB.api_host,
99
+ "port" => TheBigDB.api_port,
100
+ "path" => "/v#{TheBigDB.api_version}/",
101
+ "method" => "GET",
102
+ "params" => {"foo" => "bar"}
103
+ }
104
+ end
105
+
106
+ it "sets the correct data_received instance variable" do
107
+ @request.data_received.should include({
108
+ "headers" => Hash[@request.http_response.to_hash.map{|k,v| [k, v.join] }],
109
+ "content" => {"server_says" => "hello world"}
110
+ })
111
+ end
112
+ end
113
+
114
+ context "with arrays in params" do
115
+ before do
116
+ stub_request(:get, /#{TheBigDB.api_host}/).to_return(:body => '{"server_says": "hello world"}')
117
+
118
+ @request = TheBigDB::Request.new
119
+ @request.prepare(:get, "/", :nodes => ["foo", "bar"])
120
+ @request.execute
121
+ end
122
+
123
+ it "sets the correct data_sent instance variable" do
124
+ @request.data_sent.should == {
125
+ "headers" => Hash[@request.http_request.to_hash.map{|k,v| [k, v.join] }],
126
+ "host" => TheBigDB.api_host,
127
+ "port" => TheBigDB.api_port,
128
+ "path" => "/v#{TheBigDB.api_version}/",
129
+ "method" => "GET",
130
+ "params" => {"nodes" => {"0" => "foo", "1" => "bar"}}
131
+ }
132
+ end
133
+
134
+ it "sets the correct data_received instance variable" do
135
+ @request.data_received.should include({
136
+ "headers" => Hash[@request.http_response.to_hash.map{|k,v| [k, v.join] }],
137
+ "content" => {"server_says" => "hello world"}
138
+ })
139
+ end
140
+ end
141
+
142
+ context "with hashes in params" do
143
+ before do
144
+ stub_request(:get, /#{TheBigDB.api_host}/).to_return(:body => '{"server_says": "hello world"}')
145
+
146
+ @request = TheBigDB::Request.new
147
+ @request.prepare(:get, "/", :nodes => {"0" => "foo", "1" => "bar"})
148
+ @request.execute
149
+ end
150
+
151
+ it "sets the correct data_sent instance variable" do
152
+ @request.data_sent.should == {
153
+ "headers" => Hash[@request.http_request.to_hash.map{|k,v| [k, v.join] }],
154
+ "host" => TheBigDB.api_host,
155
+ "port" => TheBigDB.api_port,
156
+ "path" => "/v#{TheBigDB.api_version}/",
157
+ "method" => "GET",
158
+ "params" => {"nodes" => {"0" => "foo", "1" => "bar"}}
159
+ }
160
+ end
161
+
162
+ it "sets the correct data_received instance variable" do
163
+ @request.data_received.should include({
164
+ "headers" => Hash[@request.http_response.to_hash.map{|k,v| [k, v.join] }],
165
+ "content" => {"server_says" => "hello world"}
166
+ })
167
+ end
168
+ end
169
+ end
170
+
171
+ context "POST requests" do
172
+ context "with basic params" do
173
+ before do
174
+ stub_request(:post, /#{TheBigDB.api_host}/).to_return(:body => '{"server_says": "hello world"}')
175
+
176
+ @request = TheBigDB::Request.new
177
+ @request.prepare(:post, "/", :foo => "bar")
178
+ @request.execute
179
+ end
180
+
181
+ it "sets the correct data_sent instance variable" do
182
+ @request.data_sent.should == {
183
+ "headers" => Hash[@request.http_request.to_hash.map{|k,v| [k, v.join] }],
184
+ "host" => TheBigDB.api_host,
185
+ "port" => TheBigDB.api_port,
186
+ "path" => "/v#{TheBigDB.api_version}/",
187
+ "method" => "POST",
188
+ "params" => {"foo" => "bar"}
189
+ }
190
+ end
191
+
192
+ it "sets the correct data_received instance variable" do
193
+ @request.data_received.should include({
194
+ "headers" => Hash[@request.http_response.to_hash.map{|k,v| [k, v.join] }],
195
+ "content" => {"server_says" => "hello world"}
196
+ })
197
+ end
198
+ end
199
+
200
+ context "with array arguments" do
201
+ before do
202
+ stub_request(:post, /#{TheBigDB.api_host}/).to_return(:body => '{"server_says": "hello world"}')
203
+
204
+ @request = TheBigDB::Request.new
205
+ @request.prepare(:post, "/", :nodes => ["foo", "bar"])
206
+ @request.execute
207
+ end
208
+
209
+ it "sets the correct data_sent instance variable" do
210
+ @request.data_sent.should == {
211
+ "headers" => Hash[@request.http_request.to_hash.map{|k,v| [k, v.join] }],
212
+ "host" => TheBigDB.api_host,
213
+ "port" => TheBigDB.api_port,
214
+ "path" => "/v#{TheBigDB.api_version}/",
215
+ "method" => "POST",
216
+ "params" => {"nodes" => {"0" => "foo", "1" => "bar"}}
217
+ }
218
+ end
219
+
220
+ it "sets the correct data_received instance variable" do
221
+ @request.data_received.should include({
222
+ "headers" => Hash[@request.http_response.to_hash.map{|k,v| [k, v.join] }],
223
+ "content" => {"server_says" => "hello world"}
224
+ })
225
+ end
226
+ end
227
+
228
+ context "with hash arguments" do
229
+ before do
230
+ stub_request(:post, /#{TheBigDB.api_host}/).to_return(:body => '{"server_says": "hello world"}')
231
+
232
+ @request = TheBigDB::Request.new
233
+ @request.prepare(:post, "/", :nodes => {"0" => "foo", "1" => "bar"})
234
+ @request.execute
235
+ end
236
+
237
+ it "sets the correct data_sent instance variable" do
238
+ @request.data_sent.should == {
239
+ "headers" => Hash[@request.http_request.to_hash.map{|k,v| [k, v.join] }],
240
+ "host" => TheBigDB.api_host,
241
+ "port" => TheBigDB.api_port,
242
+ "path" => "/v#{TheBigDB.api_version}/",
243
+ "method" => "POST",
244
+ "params" => {"nodes" => {"0" => "foo", "1" => "bar"}}
245
+ }
246
+ end
247
+
248
+ it "sets the correct data_received instance variable" do
249
+ @request.data_received.should include({
250
+ "headers" => Hash[@request.http_response.to_hash.map{|k,v| [k, v.join] }],
251
+ "content" => {"server_says" => "hello world"}
252
+ })
253
+ end
254
+ end
255
+ end
256
+ end
257
+
258
+ describe "Request helper" do
259
+ describe "serialize_query_params" do
260
+ it "works with simple a=b&c=d params" do
261
+ TheBigDB::Request.serialize_query_params(a: "b", c: "d").should == "a=b&c=d"
262
+ end
263
+
264
+ it "works with more complex imbricated params" do
265
+ TheBigDB::Request.serialize_query_params({
266
+ house: "bricks",
267
+ animals: ["cat", "dog"],
268
+ computers: {cool: true, drives: ["hard", "flash"]}
269
+ }).should == "house=bricks&animals%5B0%5D=cat&animals%5B1%5D=dog&computers%5Bcool%5D=true&computers%5Bdrives%5D%5B0%5D=hard&computers%5Bdrives%5D%5B1%5D=flash"
270
+
271
+ # and with a hash instead of an array
272
+ TheBigDB::Request.serialize_query_params({
273
+ house: "bricks",
274
+ animals: {"0" => "cat", "1" => "dog"},
275
+ computers: {cool: true, drives: ["hard", "flash"]}
276
+ }).should == "house=bricks&animals%5B0%5D=cat&animals%5B1%5D=dog&computers%5Bcool%5D=true&computers%5Bdrives%5D%5B0%5D=hard&computers%5Bdrives%5D%5B1%5D=flash"
277
+ end
278
+ end
279
+
280
+ describe "flatten_params_keys" do
281
+ it "works with simple a=b&c=d params" do
282
+ TheBigDB::Request.flatten_params_keys(a: "b", c: "d").should == {"a" => "b", "c" => "d"}
283
+ end
284
+
285
+ it "works with more complex imbricated params" do
286
+ TheBigDB::Request.flatten_params_keys({
287
+ house: "bricks",
288
+ animals: ["cat", "dog"],
289
+ computers: {cool: true, drives: ["hard", "flash"]}
290
+ }).should == {
291
+ "house" => "bricks",
292
+ "animals[0]" => "cat",
293
+ "animals[1]" => "dog",
294
+ "computers[cool]" => "true",
295
+ "computers[drives][0]" => "hard",
296
+ "computers[drives][1]" => "flash"
297
+ }
298
+
299
+ # and with a hash instead of an array
300
+ TheBigDB::Request.flatten_params_keys({
301
+ house: "bricks",
302
+ animals: {"0" => "cat", "1" => "dog"},
303
+ computers: {cool: true, drives: ["hard", "flash"]}
304
+ }).should == {
305
+ "house" => "bricks",
306
+ "animals[0]" => "cat",
307
+ "animals[1]" => "dog",
308
+ "computers[cool]" => "true",
309
+ "computers[drives][0]" => "hard",
310
+ "computers[drives][1]" => "flash"
311
+ }
312
+ end
313
+ end
314
+ end
315
+
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe "Statement" do
4
+ context "basic request executing" do
5
+ before do
6
+ stub_request(:get, /#{TheBigDB.api_host}\/v#{TheBigDB.api_version}\/statements\/search/).to_return(:body => '{"server_says": "hello world"}')
7
+
8
+ @request = TheBigDB::Statement(:search, nodes: ["a", "b"])
9
+ end
10
+
11
+ it "sets the correct data_sent instance variable" do
12
+ @request.data_sent.should == {
13
+ "headers" => Hash[@request.http_request.to_hash.map{|k,v| [k, v.join] }],
14
+ "host" => TheBigDB.api_host,
15
+ "port" => TheBigDB.api_port,
16
+ "path" => "/v#{TheBigDB.api_version}/statements/search",
17
+ "method" => "GET",
18
+ "params" => {"nodes" => {"0" => "a", "1" => "b"}}
19
+ }
20
+ end
21
+
22
+ it "sets the correct data_received instance variable" do
23
+ @request.data_received.should include({
24
+ "headers" => Hash[@request.http_response.to_hash.map{|k,v| [k, v.join] }],
25
+ "content" => {"server_says" => "hello world"}
26
+ })
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe "Toolbox Units" do
4
+ context "basic request executing" do
5
+ before do
6
+ stub_request(:get, /#{TheBigDB.api_host}\/v#{TheBigDB.api_version}\/toolbox\/units\/convert/).to_return(:body => '{"server_says": "hello world"}')
7
+
8
+ @request = TheBigDB::Toolbox::Unit(:convert, :value => "100 ly", :new_unit => "cm")
9
+ end
10
+
11
+ it "sets the correct data_sent instance variable" do
12
+ @request.data_sent.should == {
13
+ "headers" => Hash[@request.http_request.to_hash.map{|k,v| [k, v.join] }],
14
+ "host" => TheBigDB.api_host,
15
+ "port" => TheBigDB.api_port,
16
+ "path" => "/v#{TheBigDB.api_version}/toolbox/units/convert",
17
+ "method" => "GET",
18
+ "params" => {"value" => "100 ly", "new_unit" => "cm"}
19
+ }
20
+ end
21
+
22
+ it "sets the correct data_received instance variable" do
23
+ @request.data_received.should include({
24
+ "headers" => Hash[@request.http_response.to_hash.map{|k,v| [k, v.join] }],
25
+ "content" => {"server_says" => "hello world"}
26
+ })
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe "User" do
4
+ context "basic request executing" do
5
+ before do
6
+ stub_request(:get, /#{TheBigDB.api_host}\/v#{TheBigDB.api_version}\/users\/show/).to_return(:body => '{"server_says": "hello world"}')
7
+
8
+ @request = TheBigDB::User(:show, login: "christophe")
9
+ end
10
+
11
+ it "sets the correct data_sent instance variable" do
12
+ @request.data_sent.should == {
13
+ "headers" => Hash[@request.http_request.to_hash.map{|k,v| [k, v.join] }],
14
+ "host" => TheBigDB.api_host,
15
+ "port" => TheBigDB.api_port,
16
+ "path" => "/v#{TheBigDB.api_version}/users/show",
17
+ "method" => "GET",
18
+ "params" => {"login" => "christophe"}
19
+ }
20
+ end
21
+
22
+ it "sets the correct data_received instance variable" do
23
+ @request.data_received.should include({
24
+ "headers" => Hash[@request.http_response.to_hash.map{|k,v| [k, v.join] }],
25
+ "content" => {"server_says" => "hello world"}
26
+ })
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ require "rspec"
2
+ require "webmock/rspec"
3
+ require "thebigdb"
4
+
5
+ RSpec.configure do |config|
6
+ config.order = "random"
7
+
8
+ config.before(:each) do
9
+ TheBigDB::DEFAULT_VALUES["api_host"] = "fake.test.host"
10
+ TheBigDB.reset_default_values
11
+ end
12
+
13
+ config.after(:each) do
14
+ TheBigDB.reset_default_values
15
+ end
16
+
17
+ config.filter_run focus: true
18
+ config.run_all_when_everything_filtered = true
19
+ end
@@ -0,0 +1,23 @@
1
+ require "spec_helper"
2
+
3
+ # Here's we're testing the basics of the module itself,
4
+ # the variable that you can set, the actions you can take, etc.
5
+
6
+ describe "TheBigDB module" do
7
+ it "has accessors for common used global variables" do
8
+ TheBigDB.api_host = "foobar"
9
+ TheBigDB.api_port = 1337
10
+ TheBigDB.api_version = "1337"
11
+
12
+ TheBigDB.api_host.should == "foobar"
13
+ TheBigDB.api_port.should == 1337
14
+ TheBigDB.api_version.should == "1337"
15
+ end
16
+
17
+ it "has resettable default values" do
18
+ default_host = TheBigDB.api_host.dup
19
+ TheBigDB.api_host = "foobar"
20
+ TheBigDB.reset_default_values
21
+ TheBigDB.api_host.should == default_host
22
+ end
23
+ end
data/thebigdb.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require "thebigdb/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "thebigdb"
6
+ s.version = TheBigDB::VERSION::STRING
7
+ s.date = "2013-03-12"
8
+ s.summary = "Ruby bindings for TheBigDB API"
9
+ s.description = "TheBigDB a simply structured open database of real life facts. See http://thebigdb.com for details."
10
+ s.authors = ["Christophe Maximin"]
11
+ s.email = "christophe@thebigdb.com"
12
+ s.homepage = "http://thebigdb.com"
13
+
14
+ s.platform = Gem::Platform::RUBY
15
+
16
+ s.add_runtime_dependency "rack", "~> 1.4"
17
+
18
+ s.add_development_dependency "rspec", "~> 2.12"
19
+ s.add_development_dependency "guard-rspec", "~> 2.3"
20
+ s.add_development_dependency "rb-inotify"
21
+ s.add_development_dependency "rb-fsevent"
22
+ s.add_development_dependency "rb-fchange"
23
+ s.add_development_dependency "webmock", "~> 1.9"
24
+
25
+
26
+
27
+ s.files = `git ls-files`.split("\n")
28
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
29
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
30
+
31
+ s.require_paths = ["lib"]
32
+ end
metadata ADDED
@@ -0,0 +1,186 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thebigdb
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Christophe Maximin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.4'
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.4'
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.12'
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.12'
46
+ - !ruby/object:Gem::Dependency
47
+ name: guard-rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '2.3'
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: '2.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rb-inotify
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rb-fsevent
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rb-fchange
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: webmock
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '1.9'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '1.9'
126
+ description: TheBigDB a simply structured open database of real life facts. See http://thebigdb.com
127
+ for details.
128
+ email: christophe@thebigdb.com
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .gitignore
134
+ - .rspec
135
+ - Gemfile
136
+ - Gemfile.lock
137
+ - Guardfile
138
+ - LICENSE
139
+ - README.md
140
+ - Rakefile
141
+ - lib/thebigdb.rb
142
+ - lib/thebigdb/aliases.rb
143
+ - lib/thebigdb/module_attribute_accessors.rb
144
+ - lib/thebigdb/request.rb
145
+ - lib/thebigdb/resources/statement.rb
146
+ - lib/thebigdb/resources/toolbox.rb
147
+ - lib/thebigdb/resources/user.rb
148
+ - lib/thebigdb/version.rb
149
+ - spec/request_spec.rb
150
+ - spec/resources/statement_spec.rb
151
+ - spec/resources/toolbox_spec.rb
152
+ - spec/resources/user_spec.rb
153
+ - spec/spec_helper.rb
154
+ - spec/thebigdb_spec.rb
155
+ - thebigdb.gemspec
156
+ homepage: http://thebigdb.com
157
+ licenses: []
158
+ post_install_message:
159
+ rdoc_options: []
160
+ require_paths:
161
+ - lib
162
+ required_ruby_version: !ruby/object:Gem::Requirement
163
+ none: false
164
+ requirements:
165
+ - - ! '>='
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ required_rubygems_version: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ requirements: []
175
+ rubyforge_project:
176
+ rubygems_version: 1.8.25
177
+ signing_key:
178
+ specification_version: 3
179
+ summary: Ruby bindings for TheBigDB API
180
+ test_files:
181
+ - spec/request_spec.rb
182
+ - spec/resources/statement_spec.rb
183
+ - spec/resources/toolbox_spec.rb
184
+ - spec/resources/user_spec.rb
185
+ - spec/spec_helper.rb
186
+ - spec/thebigdb_spec.rb