api-query-provider 0.0.1

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.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5
5
+
6
+ gem 'httparty'
7
+ gem 'json'
8
+
9
+ # Add dependencies to develop your gem here.
10
+ # Include everything needed to run rake, tests, features, etc.
11
+ group :development do
12
+ gem "rspec", ">= 0"
13
+ gem "rdoc", "~> 3.12"
14
+ gem "bundler", "~> 1.0.0"
15
+ gem "jeweler", "~> 1.8.3"
16
+ gem "simplecov", ">= 0"
17
+ end
@@ -0,0 +1,43 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.3)
5
+ git (1.2.5)
6
+ httparty (0.8.1)
7
+ multi_json
8
+ multi_xml
9
+ jeweler (1.8.3)
10
+ bundler (~> 1.0)
11
+ git (>= 1.2.5)
12
+ rake
13
+ rdoc
14
+ json (1.6.5)
15
+ multi_json (1.1.0)
16
+ multi_xml (0.4.2)
17
+ rake (0.9.2.2)
18
+ rdoc (3.12)
19
+ json (~> 1.4)
20
+ rspec (2.8.0)
21
+ rspec-core (~> 2.8.0)
22
+ rspec-expectations (~> 2.8.0)
23
+ rspec-mocks (~> 2.8.0)
24
+ rspec-core (2.8.0)
25
+ rspec-expectations (2.8.0)
26
+ diff-lcs (~> 1.1.2)
27
+ rspec-mocks (2.8.0)
28
+ simplecov (0.6.1)
29
+ multi_json (~> 1.0)
30
+ simplecov-html (~> 0.5.3)
31
+ simplecov-html (0.5.3)
32
+
33
+ PLATFORMS
34
+ ruby
35
+
36
+ DEPENDENCIES
37
+ bundler (~> 1.0.0)
38
+ httparty
39
+ jeweler (~> 1.8.3)
40
+ json
41
+ rdoc (~> 3.12)
42
+ rspec
43
+ simplecov
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Femaref
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,10 @@
1
+ = api-query-provider
2
+
3
+ This gem provides an interface to an arbitrary json api. It provides ActiveRecord-like methods,
4
+ which can be chained together.
5
+
6
+ == Copyright
7
+
8
+ Copyright (c) 2012 Femaref. See LICENSE.txt for
9
+ further details.
10
+
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "api-query-provider"
18
+ gem.homepage = "http://github.com/Femaref/api-query-provider"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Provides an easy interface to arbitrary json apis}
21
+ gem.description = %Q{Provides an easy interface to arbitrary json apis}
22
+ gem.email = "femaref@googlemail.com"
23
+ gem.authors = ["Femaref"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ task :default => :spec
35
+
36
+ task :simplecov do
37
+ ENV['COVERAGE'] = "true"
38
+ Rake::Task[:spec].execute
39
+ end
40
+
41
+ require 'rdoc/task'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "api-query-provider #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/TODO ADDED
@@ -0,0 +1,8 @@
1
+ - improve ApiQueryProvider::Base.shadow (allow user defined aliasing)
2
+ - improve field definition on non autogenerated models (rename custom_fields -> field, allow call with no block for default behaviour)
3
+ - probably should split ApiQueryProvider::Base into Base and Object, Base serving as interaction layer, Object contains all field handling methods, would allow anonymous objects without much hassle
4
+ - improve ApiQueryProvider::Provider.system_symbols, should be a constant as it won't change at runtime
5
+ - think about ApiQueryProvider::Provider.execute, does it really need a forced array, could easily just return a single object
6
+ - ApiQueryProvider::Base.required_symbols should be cached, api_path shouldn't really change
7
+ - make configuration setters private, not needed to expose them
8
+ - ApiQueryProvider::Base should automatically try to create objects from nested hashes, also should iterate over arrays
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,85 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "api-query-provider"
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Femaref"]
12
+ s.date = "2012-04-21"
13
+ s.description = "Provides an easy interface to arbitrary json apis"
14
+ s.email = "femaref@googlemail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc",
18
+ "TODO"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".travis.yml",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE.txt",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "TODO",
29
+ "VERSION",
30
+ "api-query-provider.gemspec",
31
+ "lib/api-query-provider.rb",
32
+ "lib/api-query-provider/base.rb",
33
+ "lib/api-query-provider/provider.rb",
34
+ "spec/attr_spec.rb",
35
+ "spec/autogeneration_spec.rb",
36
+ "spec/base_spec.rb",
37
+ "spec/constructor_spec.rb",
38
+ "spec/github_api_spec.rb",
39
+ "spec/lib/auto_generate_test_class.rb",
40
+ "spec/lib/github_commits.rb",
41
+ "spec/lib/github_user.rb",
42
+ "spec/lib/optional_where_test_class.rb",
43
+ "spec/lib/parameterless_auto_generate_test_class.rb",
44
+ "spec/lib/test_class.rb",
45
+ "spec/provider_spec.rb",
46
+ "spec/spec_helper.rb",
47
+ "spec/where_spec.rb"
48
+ ]
49
+ s.homepage = "http://github.com/Femaref/api-query-provider"
50
+ s.licenses = ["MIT"]
51
+ s.require_paths = ["lib"]
52
+ s.rubygems_version = "1.8.10"
53
+ s.summary = "Provides an easy interface to arbitrary json apis"
54
+
55
+ if s.respond_to? :specification_version then
56
+ s.specification_version = 3
57
+
58
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
59
+ s.add_runtime_dependency(%q<httparty>, [">= 0"])
60
+ s.add_runtime_dependency(%q<json>, [">= 0"])
61
+ s.add_development_dependency(%q<rspec>, [">= 0"])
62
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
63
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
64
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
65
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
66
+ else
67
+ s.add_dependency(%q<httparty>, [">= 0"])
68
+ s.add_dependency(%q<json>, [">= 0"])
69
+ s.add_dependency(%q<rspec>, [">= 0"])
70
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
71
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
72
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
73
+ s.add_dependency(%q<simplecov>, [">= 0"])
74
+ end
75
+ else
76
+ s.add_dependency(%q<httparty>, [">= 0"])
77
+ s.add_dependency(%q<json>, [">= 0"])
78
+ s.add_dependency(%q<rspec>, [">= 0"])
79
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
80
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
81
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
82
+ s.add_dependency(%q<simplecov>, [">= 0"])
83
+ end
84
+ end
85
+
@@ -0,0 +1,6 @@
1
+ require "httparty"
2
+ require "uri"
3
+ require "json"
4
+
5
+ require "api-query-provider/provider"
6
+ require "api-query-provider/base"
@@ -0,0 +1,152 @@
1
+ module ApiQueryProvider
2
+ # This class serves as a base class for any API Requests, it has several settings:
3
+ # +api_url+: sets the base url requests are made to_sym
4
+ # +api_path+: sets the path specific to this class, can contain replaceable elements
5
+ # +data_selector+: if the data is wrapped in an object, you can define a +Proc+ taking
6
+ # the parsed response as Hash and returning a portion of that Hash for further parsing
7
+ # the keys are +String+s.
8
+ # Be aware that if the data contains any fields named like a ruby internal method or field,
9
+ # it will be shadowed if you define it explicitly, it autogeneration is enabled, the name will
10
+ # have a underscore appended.
11
+ class Base
12
+
13
+ def self.api_url
14
+ @api_url
15
+ end
16
+
17
+ def self.api_url= (value)
18
+ @api_url = value
19
+ end
20
+
21
+ def self.api_path
22
+ @api_path
23
+ end
24
+
25
+ def self.api_path= (value)
26
+ @api_path = value
27
+ end
28
+
29
+ def self.required_symbols
30
+ @api_path.scan(/:(\w+)/).flatten.map { |e| e.to_sym } - ApiQueryProvider::Provider.system_symbols
31
+ end
32
+
33
+ def self.data_selector
34
+ @data_selector || Proc.new { |e| e }
35
+ end
36
+
37
+ def self.data_selector= (value)
38
+ @data_selector = value
39
+ end
40
+
41
+ def self.autogenerate
42
+ if @autogenerate.nil?
43
+ false
44
+ else
45
+ @autogenerate
46
+ end
47
+ end
48
+
49
+ def self.autogenerate= (value)
50
+ @autogenerate = value
51
+ end
52
+
53
+ def self.custom_field(field, &block)
54
+ @custom_fields ||= {}
55
+
56
+ @custom_fields[field.to_sym] = block.to_proc
57
+ end
58
+
59
+ def self.custom_fields
60
+ @custom_fields || {}
61
+ end
62
+
63
+ def self.shadow(key)
64
+ key.to_sym == :class ? "class_".to_sym : key
65
+ end
66
+
67
+ attr_reader :provided_symbols
68
+
69
+
70
+ # basic parsing constructor
71
+ # takes the json data and tries to assign it to +attr_accessor+ methods
72
+ # make sure to define them for any field present in the response
73
+ def initialize(data)
74
+ if self.class == ApiQueryProvider::Base
75
+ raise "this class should never be instanciated directly"
76
+ end
77
+
78
+ @provided_symbols = []
79
+
80
+ data.each do |key, value|
81
+ @provided_symbols << key.to_sym
82
+
83
+ key = self.class.shadow key
84
+
85
+ if !self.respond_to? key.to_sym
86
+ if self.class.autogenerate
87
+ self.class.class_eval do
88
+ attr_accessor key.to_sym
89
+ end
90
+ else
91
+ raise "field not found: #{key}. Either enable auto generation or add attr_accessor :#{key}"
92
+ end
93
+ end
94
+
95
+ if self.class.custom_fields.include? key.to_sym
96
+ value = self.class.custom_fields[key.to_sym].call(value)
97
+ end
98
+
99
+ self.send("#{key}=".to_sym, value)
100
+ end
101
+ end
102
+
103
+ def extend
104
+ if !(self.class.required_symbols - provided_symbols).empty?
105
+ raise "not all needed values are present"
106
+ end
107
+
108
+ request = self.class.where
109
+
110
+ self.class.required_symbols.each do |sym|
111
+ request = request.where(sym => self.send(self.class.shadow(sym).to_sym))
112
+ end
113
+
114
+ response = request.execute
115
+
116
+ if response.count != 1
117
+ raise "the request did not return exactly one element"
118
+ end
119
+
120
+ response.first
121
+ end
122
+
123
+ def extend!
124
+ local = self.extend
125
+
126
+ local.provided_symbols.each do |symbol|
127
+ shadow = self.class.shadow(symbol).to_sym
128
+ self.send("#{shadow}=".to_sym, local.send("#{shadow}".to_sym))
129
+ end
130
+
131
+ @provided_symbols = local.provided_symbols
132
+
133
+ self
134
+ end
135
+
136
+ def self.interface
137
+ ApiQueryProvider::Provider.new(self)
138
+ end
139
+
140
+ def self.where(opt = {})
141
+ interface.where(opt)
142
+ end
143
+
144
+ def self.limit(count)
145
+ interface.limit(count)
146
+ end
147
+
148
+ def self.select(*fields)
149
+ interface.select(fields)
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,99 @@
1
+ module ApiQueryProvider
2
+ # Provides method chaining support
3
+ # replaces parameters in the api_path
4
+ # named parameters will be replaced by the assosicated value from where calls
5
+ # if a :where symbol is present in the string, any further values provided by where will be
6
+ # concatted to a key1=value,key2=value string and replaced there
7
+ # a value provided by limit will be replaced in to the :limit symbol
8
+ # if you can request additional fields or restrict the fields provided, place a :select symbol in the string
9
+ class Provider
10
+ attr_reader :where_constraints
11
+ attr_reader :count_constraint
12
+ attr_reader :select_fields
13
+ attr_reader :klass
14
+
15
+ def initialize (base)
16
+ api_url = base.api_url
17
+ api_path = base.api_path
18
+ if base.is_a? Class
19
+ @where_constraints = {}
20
+ @select_fields = []
21
+ @count_constraint = 0
22
+ @klass = base
23
+ else
24
+ @where_constraints = base.where_constraints
25
+ @select_fields = base.select_fields
26
+ @count_constraint = base.count_constraint
27
+ end
28
+
29
+ end
30
+
31
+ def where(opt = {})
32
+ @where_constraints.merge! opt
33
+
34
+ return self
35
+ end
36
+
37
+ def limit(count)
38
+ @count_constraint = count
39
+
40
+ return self
41
+ end
42
+
43
+ def select(*fields)
44
+ @select_fields |= fields.flatten
45
+
46
+ return self
47
+ end
48
+
49
+ def replace_path
50
+ replaced_path = klass.api_path.dup
51
+
52
+ used_keys = []
53
+
54
+ @where_constraints.each do |key, value|
55
+ if replaced_path.gsub! /:#{key}/, value.to_s
56
+ used_keys << key
57
+ end
58
+ end
59
+
60
+ @where_constraints.reject! { |key, value| used_keys.include? key }
61
+
62
+ replaced_path.gsub! /:where/, @where_constraints.to_a.map { |e| e.join("=") }.join("&")
63
+ replaced_path.gsub! /:select/, @select_fields.join(",")
64
+ replaced_path.gsub! /:limit/, @count_constraint.to_s
65
+
66
+ if replaced_path.include?(":")
67
+ raise "you didn't replace all fields in the api_path"
68
+ end
69
+
70
+ replaced_path
71
+ end
72
+
73
+ def response
74
+ begin
75
+ uri = URI.join(klass.api_url, self.replace_path)
76
+ rescue
77
+ raise "invalid uri"
78
+ end
79
+
80
+ HTTParty.get(uri.to_s)
81
+ end
82
+
83
+ def execute
84
+ local_response = self.response
85
+
86
+ [klass.data_selector.call(JSON.parse(local_response.body))].flatten.map do |elem|
87
+ klass.new elem
88
+ end
89
+ end
90
+
91
+ def self.interface
92
+ ApiQueryProvider::Provider.new(self)
93
+ end
94
+
95
+ def self.system_symbols
96
+ [ :where, :count, :select ]
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+ require 'lib/test_class'
3
+ require 'lib/github_commits'
4
+
5
+ describe "ApiQueryProvider::Provider" do
6
+ it "should not replace api_url and api_path of two classes" do
7
+ TestClass.api_url.should == "http://example.com"
8
+ TestClass.api_path.should == "/foo/:id/id"
9
+
10
+ GithubCommits.api_url.should == "http://github.com/api/v2/json/"
11
+ GithubCommits.api_path.should == "commits/list/:user_id/:repository/:branch"
12
+ end
13
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'lib/auto_generate_test_class'
3
+ require 'lib/test_class'
4
+
5
+ describe AutoGenerateTestClass do
6
+ it "should auto generate fields" do
7
+ real = AutoGenerateTestClass.new({:foo => :bar})
8
+
9
+ real.respond_to?(:foo).should == true
10
+ real.respond_to?(:bar).should == false
11
+ end
12
+ end
13
+
14
+ describe TestClass do
15
+ it "should raise exception encountering a non existant field" do
16
+ lambda { real = TestClass.new({:foo => :bar}) }.should raise_error
17
+ end
18
+
19
+ # TODO move to own test
20
+ it "should return :id as required symbol" do
21
+ TestClass.required_symbols.should == [ :id ]
22
+ end
23
+
24
+ # TODO move to own test
25
+ it "should raise on non-replaced mandatory field" do
26
+ lambda { TestClass.where().replace_path }.should raise_error(Exception, "you didn't replace all fields in the api_path")
27
+ end
28
+
29
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'lib/auto_generate_test_class'
3
+ require 'lib/parameterless_auto_generate_test_class'
4
+
5
+ describe ApiQueryProvider::Base do
6
+ it "should raise an exception being instanciated directly" do
7
+ lambda { real = ApiQueryProvider::Base.new({}) }.should raise_error(Exception, "this class should never be instanciated directly")
8
+ end
9
+
10
+ it "should not be manipulated if a deriving class is manipulated" do
11
+ AutoGenerateTestClass.new({:foo => :bar})
12
+
13
+ ApiQueryProvider::Base.instance_methods.include?(:foo).should == false
14
+ end
15
+
16
+ describe "extend" do
17
+ it "should raise on missing symbol" do
18
+ real = AutoGenerateTestClass.new({})
19
+
20
+ lambda { real.extend }.should raise_error(Exception, "not all needed values are present")
21
+ end
22
+
23
+ it "should allow parameterless api calls" do
24
+ HTTParty.stub(:get) { double(:body => %q({ "id" : "1", "name": "test" })) }
25
+
26
+ real = ParameterlessAutoGenerateTestClass.new({})
27
+
28
+ lambda { real.extend }.should_not raise_error
29
+ end
30
+ end
31
+
32
+ describe "extend!" do
33
+ it "should copy additional fields to the current object" do
34
+ HTTParty.stub(:get) { double(:body => %q({ "id" : "1", "name": "test" })) }
35
+
36
+ real = AutoGenerateTestClass.new({:id => 1})
37
+
38
+ real.extend!
39
+
40
+ real.name.should == "test"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+ require 'lib/test_class'
3
+
4
+ describe "ApiQueryProvider::Provider" do
5
+ it "should save the base class" do
6
+ real = TestClass.interface
7
+
8
+ real.klass.should == TestClass
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ require 'lib/github_commits'
3
+ require 'lib/github_user'
4
+
5
+ describe "github commit api" do
6
+ it "should construct a valid object" do
7
+ lambda do
8
+ GithubCommits.where(:user_id => "Femaref")
9
+ .where(:repository => "c2dm-rails")
10
+ .where(:branch => "master")
11
+ .execute
12
+ end.should_not raise_error
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ class AutoGenerateTestClass < ApiQueryProvider::Base
2
+
3
+ self.api_url = "http://example.com"
4
+ self.api_path = "/foo/:id/id"
5
+ self.autogenerate = true
6
+ end
@@ -0,0 +1,10 @@
1
+ class GithubCommits < ApiQueryProvider::Base
2
+ self.api_url = "http://github.com/api/v2/json/"
3
+ self.api_path = "commits/list/:user_id/:repository/:branch"
4
+ self.data_selector = Proc.new {|element| element["commits"] }
5
+ self.autogenerate = true
6
+
7
+ self.custom_field :author do |input|
8
+ GithubUser.new input
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ class GithubUser < ApiQueryProvider::Base
2
+ self.api_url = "http://github.com/api/v2/json/"
3
+ self.api_path = "user/show/:name"
4
+ self.data_selector = Proc.new {|element| element["user"] }
5
+ self.autogenerate = true
6
+ end
@@ -0,0 +1,5 @@
1
+ class OptionalWhereTestClass < ApiQueryProvider::Base
2
+
3
+ self.api_url = "example.com"
4
+ self.api_path = "/foo/?:where"
5
+ end
@@ -0,0 +1,6 @@
1
+ class ParameterlessAutoGenerateTestClass < ApiQueryProvider::Base
2
+
3
+ self.api_url = "http://example.com"
4
+ self.api_path = "/foo/id"
5
+ self.autogenerate = true
6
+ end
@@ -0,0 +1,5 @@
1
+ class TestClass < ApiQueryProvider::Base
2
+
3
+ self.api_url = "http://example.com"
4
+ self.api_path = "/foo/:id/id"
5
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ require 'lib/auto_generate_test_class'
3
+
4
+ # uses the auto generation test class as interface
5
+
6
+ describe AutoGenerateTestClass do
7
+ it "should not modify @api_path" do
8
+ HTTParty.stub(:get) { double(:body => %q({ "id" : "1", "name": "test" })) }
9
+
10
+ real = AutoGenerateTestClass.api_path.dup
11
+
12
+ AutoGenerateTestClass.where(:id => 1).execute
13
+
14
+ AutoGenerateTestClass.api_path.should == real
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'simplecov'
5
+
6
+ module SimpleCov::Configuration
7
+ def clean_filters
8
+ @filters = []
9
+ end
10
+ end
11
+
12
+ SimpleCov.configure do
13
+ clean_filters
14
+ load_adapter 'test_frameworks'
15
+ end
16
+
17
+ ENV["COVERAGE"] && SimpleCov.start do
18
+ add_filter "/.rvm/"
19
+ end
20
+
21
+
22
+ require 'rspec'
23
+ require 'api-query-provider'
24
+
25
+ # Requires supporting files with custom matchers and macros, etc,
26
+ # in ./support/ and its subdirectories.
27
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
28
+
29
+ RSpec.configure do |config|
30
+
31
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'lib/test_class'
3
+ require 'lib/optional_where_test_class'
4
+
5
+ describe "Where" do
6
+ it "should merge the where_constraint hash" do
7
+ real = TestClass.where(:id => 1).where(:name => "foo")
8
+
9
+ real.where_constraints.should == ({ :id => 1, :name => "foo" })
10
+ end
11
+
12
+ it "should replace only symbols" do
13
+ real = TestClass.where(:id => 1)
14
+
15
+ real.replace_path.should == "/foo/1/id"
16
+ end
17
+
18
+ it "should not add non-defined symbol values" do
19
+ real = TestClass.where(:id => 1, :name => "something")
20
+
21
+ real.replace_path.should == "/foo/1/id"
22
+ end
23
+ end
24
+
25
+ describe OptionalWhereTestClass do
26
+ it "should replace optional :where symbol" do
27
+ real = OptionalWhereTestClass.where(:ref_id => 1, :ref_type => 2)
28
+
29
+ real.replace_path.should == "/foo/?ref_id=1&ref_type=2"
30
+ end
31
+ end
32
+
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: api-query-provider
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Femaref
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: &70154304918460 !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: *70154304918460
25
+ - !ruby/object:Gem::Dependency
26
+ name: json
27
+ requirement: &70154304917980 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70154304917980
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70154304917500 !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: *70154304917500
47
+ - !ruby/object:Gem::Dependency
48
+ name: rdoc
49
+ requirement: &70154304917020 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '3.12'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70154304917020
58
+ - !ruby/object:Gem::Dependency
59
+ name: bundler
60
+ requirement: &70154304916540 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 1.0.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70154304916540
69
+ - !ruby/object:Gem::Dependency
70
+ name: jeweler
71
+ requirement: &70154304916060 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.8.3
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70154304916060
80
+ - !ruby/object:Gem::Dependency
81
+ name: simplecov
82
+ requirement: &70154304915580 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70154304915580
91
+ description: Provides an easy interface to arbitrary json apis
92
+ email: femaref@googlemail.com
93
+ executables: []
94
+ extensions: []
95
+ extra_rdoc_files:
96
+ - LICENSE.txt
97
+ - README.rdoc
98
+ - TODO
99
+ files:
100
+ - .document
101
+ - .travis.yml
102
+ - Gemfile
103
+ - Gemfile.lock
104
+ - LICENSE.txt
105
+ - README.rdoc
106
+ - Rakefile
107
+ - TODO
108
+ - VERSION
109
+ - api-query-provider.gemspec
110
+ - lib/api-query-provider.rb
111
+ - lib/api-query-provider/base.rb
112
+ - lib/api-query-provider/provider.rb
113
+ - spec/attr_spec.rb
114
+ - spec/autogeneration_spec.rb
115
+ - spec/base_spec.rb
116
+ - spec/constructor_spec.rb
117
+ - spec/github_api_spec.rb
118
+ - spec/lib/auto_generate_test_class.rb
119
+ - spec/lib/github_commits.rb
120
+ - spec/lib/github_user.rb
121
+ - spec/lib/optional_where_test_class.rb
122
+ - spec/lib/parameterless_auto_generate_test_class.rb
123
+ - spec/lib/test_class.rb
124
+ - spec/provider_spec.rb
125
+ - spec/spec_helper.rb
126
+ - spec/where_spec.rb
127
+ homepage: http://github.com/Femaref/api-query-provider
128
+ licenses:
129
+ - MIT
130
+ post_install_message:
131
+ rdoc_options: []
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ segments:
141
+ - 0
142
+ hash: -771518329520128874
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ none: false
145
+ requirements:
146
+ - - ! '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 1.8.10
152
+ signing_key:
153
+ specification_version: 3
154
+ summary: Provides an easy interface to arbitrary json apis
155
+ test_files: []