serialization_extender 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in serialization_extender.gemspec
4
+ gemspec
@@ -0,0 +1,7 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ end
6
+ task :default => :spec
7
+
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ require 'serialization_extender/version'
3
+ require 'ruby_interface'
4
+ module SerializationExtender
5
+ extend RubyInterface
6
+
7
+ interface :serialization_extender do
8
+ class_attribute :profiles
9
+ self.profiles ||= {}
10
+ def self.profile(name, options = {}, &blk)
11
+ self.profiles = profiles.merge name => { :options => options, :blk => blk }
12
+ end
13
+
14
+ interfaced do
15
+ alias_method_chain :serializable_hash, :extending
16
+ end
17
+
18
+ def apply(options = nil)
19
+ options = options.dup if options
20
+ profile = (options && options.delete(:profile)) || Thread.current["_serialization_profile"] || :default
21
+ calculated_options, blk = get_params profile, options
22
+ res = owner.serializable_hash_without_extending calculated_options
23
+ blk ? owner.instance_exec(res, &blk) : res
24
+ end
25
+
26
+ protected
27
+ def get_params(profile_name, options = nil)
28
+ profile = self.profiles[profile_name]
29
+ return [options, nil] unless profile
30
+ [options_merge(options ? options : {}, profile[:options]), profile[:blk]]
31
+ end
32
+
33
+ def options_merge(o1, o2)
34
+ o2.each do |k, v|
35
+ case o1[k]
36
+ when Hash
37
+ o1[k] = options_merge o1[k], o2[k]
38
+ when Array
39
+ o1[k] += v
40
+ else
41
+ o1[k] = v
42
+ end
43
+ end
44
+ o1
45
+ end
46
+
47
+ end
48
+
49
+ def serializable_hash_with_extending(options = nil)
50
+ serialization_extender.apply options
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ module SerializationExtender
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,248 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
3
+
4
+ describe UserbaseClient::User do
5
+ before(:each) do
6
+ @host = UserbaseClient.config.host
7
+ @params = {'login' => "nick"}
8
+ @guid = "GUID"
9
+ end
10
+
11
+ shared_examples_for "стандартный успешный ответ" do
12
+ it "результат метода должен быть хешом" do
13
+ stub_request(:any, @path).to_return(:body => "{}")
14
+ @request.call.should be_instance_of(Hash)
15
+ end
16
+ end
17
+
18
+ shared_examples_for "стандартный неуспешный ответ" do
19
+ it "должен поднимать UserbaseClient::RecordNotFound при коде ответа 404" do
20
+ stub_request(:any, @path).to_return(:status => 404)
21
+ @request.should raise_error(UserbaseClient::RecordNotFound)
22
+ end
23
+
24
+ it "должен поднимать UserbaseClient::BadRequestError при коде ответа 400" do
25
+ stub_request(:any, @path).to_return(:status => 400)
26
+ @request.should raise_error(UserbaseClient::BadRequestError)
27
+ end
28
+
29
+ it "должен поднимать UserbaseClient::ConnectionError при коде ответа 500" do
30
+ stub_request(:any, @path).to_return(:status => 500)
31
+ @request.should raise_error(UserbaseClient::ConnectionError)
32
+ end
33
+
34
+ it "должен поднимать UserbaseClient::ConnectionError при таймауте" do
35
+ stub_request(:any, @path).to_timeout
36
+ @request.should raise_error(UserbaseClient::ConnectionError)
37
+ end
38
+ end
39
+
40
+ describe ".create" do
41
+ before(:each) do
42
+ @path = "http://" + @host + "/v1/users.json"
43
+ stub_request(:any, @path).to_return(:body => "{}")
44
+ @request = lambda {UserbaseClient::User.create @params }
45
+ @result = @request.call
46
+ end
47
+
48
+ it_should_behave_like "стандартный успешный ответ"
49
+ it_should_behave_like "стандартный неуспешный ответ"
50
+
51
+ it "должен запрашиваться /v1/users.json через POST" do
52
+ WebMock.should have_requested(:post, @path)
53
+ end
54
+
55
+ it "передаваемые параметры должны попадать в запрос" do
56
+ WebMock.should have_requested(:post, @path).with(:body => @params)
57
+ end
58
+ end
59
+
60
+ describe ".update" do
61
+ before(:each) do
62
+ @path = "http://" + @host + "/v1/users/#{@guid}/attributes.json"
63
+ stub_request(:any, @path).to_return(:body => "{}")
64
+ @request = lambda { UserbaseClient::User.update @guid, @params }
65
+ @result = @request.call
66
+ end
67
+
68
+ it_should_behave_like "стандартный успешный ответ"
69
+ it_should_behave_like "стандартный неуспешный ответ"
70
+
71
+ it "должен запрашиваться /v1/users/GUID/attributes.json через POST" do
72
+ WebMock.should have_requested(:put, @path)
73
+ end
74
+
75
+ it "передаваемые параметры должны попадать в запрос" do
76
+ WebMock.should have_requested(:put, @path).with(:body => @params)
77
+ end
78
+ end
79
+
80
+ describe ".find_by_guid" do
81
+ before(:each) do
82
+ @path = "http://" + @host + "/v1/users/#{@guid}.json"
83
+ @request = lambda { UserbaseClient::User.find_by_guid @guid }
84
+ end
85
+
86
+ it_should_behave_like "стандартный успешный ответ"
87
+ it_should_behave_like "стандартный неуспешный ответ"
88
+
89
+ context "успешный запрос" do
90
+ before(:each) do
91
+ stub_request(:any, @path).to_return(:body => Yajl::Encoder.encode(@params))
92
+ @result = @request.call
93
+ end
94
+
95
+ it "должен запрашиваться /v1/users/GUID.json через GET" do
96
+ WebMock.should have_requested(:get, @path)
97
+ end
98
+
99
+ it "должен возвращать распарсенные параметры ответа" do
100
+ @result.should == @params
101
+ end
102
+ end
103
+ end
104
+
105
+ describe ".destroy" do
106
+ before(:each) do
107
+ @path = "http://" + @host + "/v1/users/#{@guid}.json"
108
+ stub_request(:any, @path).to_return(:body => "{}")
109
+ @request = lambda { UserbaseClient::User.destroy @guid }
110
+ @result = @request.call
111
+ end
112
+
113
+ it_should_behave_like "стандартный успешный ответ"
114
+ it_should_behave_like "стандартный неуспешный ответ"
115
+
116
+ it "должен запрашиваться /v1/users/GUID.json через DELETE" do
117
+ WebMock.should have_requested(:delete, @path)
118
+ end
119
+ end
120
+
121
+ describe ".find_attribute" do
122
+ before(:each) do
123
+ @path = "http://" + @host + "/v1/users/#{@guid}/attributes/#{@params.keys.first}.json"
124
+ stub_request(:any, @path).to_return(:body => Yajl::Encoder.encode(@params))
125
+ @request = lambda { UserbaseClient::User.find_attribute @guid, @params.keys.first }
126
+ @result = @request.call
127
+ end
128
+
129
+ it_should_behave_like "стандартный неуспешный ответ"
130
+
131
+ it "должен запрашиваться /v1/users/GUID/attributes/ATTRIBUTE.json через GET" do
132
+ WebMock.should have_requested(:get, @path)
133
+ end
134
+
135
+ it "должен возвращать распарсенные параметры ответа" do
136
+ @result.should == @params[@params.keys.first]
137
+ end
138
+ end
139
+
140
+ describe ".find_attributes" do
141
+ before(:each) do
142
+ @params = {"login" => "my_login", "name" => "Nick"}
143
+ @path = "http://" + @host + "/v1/users/#{@guid}.json?" + {:attrs => @params.keys}.to_param
144
+ stub_request(:any, @path).to_return(:body => Yajl::Encoder.encode(@params))
145
+ @request = lambda { UserbaseClient::User.find_attributes @guid, @params.keys }
146
+ end
147
+
148
+ context "с выполненным запросом" do
149
+ before(:each) do
150
+ @result = @request.call
151
+ end
152
+
153
+ it_should_behave_like "стандартный неуспешный ответ"
154
+
155
+ it "должен возвращать распарсенные параметры ответа" do
156
+ @result.should include(@params)
157
+ end
158
+ end
159
+
160
+ it "должен запрашиваться /v1/users/GUID.json через GET" do
161
+ stub_request(:any, @path).to_return(:body => Yajl::Encoder.encode(@params))
162
+ @result = @request.call
163
+ WebMock.should have_requested(:get, @path)
164
+ end
165
+ end
166
+
167
+ describe ".destroy_attributes" do
168
+ context "один атрибут" do
169
+ before(:each) do
170
+ @path = "http://" + @host + "/v1/users/#{@guid}/attributes.json?" + {:attrs => [@params.keys.first]}.to_param
171
+ stub_request(:any, @path).to_return(:body => "{}")
172
+ @request = lambda { UserbaseClient::User.destroy_attributes @guid, @params.keys.first }
173
+ @result = @request.call
174
+ end
175
+
176
+ it_should_behave_like "стандартный успешный ответ"
177
+ it_should_behave_like "стандартный неуспешный ответ"
178
+
179
+ it "должен запрашиваться /v1/users/GUID/attributes.json через DELETE" do
180
+ WebMock.should have_requested(:delete, @path)
181
+ end
182
+ end
183
+
184
+ context "несколько атрибутов" do
185
+ before(:each) do
186
+ @path = "http://" + @host + "/v1/users/#{@guid}/attributes.json?" + {:attrs => @params.keys}.to_param
187
+ stub_request(:any, @path).to_return(:body => "{}")
188
+ @request = lambda { UserbaseClient::User.destroy_attributes @guid, @params.keys }
189
+ @result = @request.call
190
+ end
191
+
192
+ it_should_behave_like "стандартный успешный ответ"
193
+ it_should_behave_like "стандартный неуспешный ответ"
194
+
195
+ it "должен запрашиваться /v1/users/GUID/attributes.json через DELETE" do
196
+ WebMock.should have_requested(:delete, @path).with(:attrs => @params.keys.first)
197
+ end
198
+ end
199
+ end
200
+
201
+ describe ".authenticate" do
202
+ before(:each) do
203
+ @path = "http://" + @host + "/v1/sessions.json"
204
+ stub_request(:any, @path).to_return(:body => Yajl::Encoder.encode({:guid => @guid}), :content_type => 'application/json')
205
+ end
206
+
207
+ context "без указания атрибутов" do
208
+ before(:each) do
209
+ @request = lambda { UserbaseClient::User.authenticate @params.values.first, "pass" }
210
+ end
211
+
212
+ it "не должен поднимать ошибок" do
213
+ @request.should_not raise_error
214
+ end
215
+
216
+ it "должен отправлять POST запрос с логином и паролем" do
217
+ @request.call
218
+ WebMock.should have_requested(:post, @path).with(:body => @params.merge('password' => 'pass'))
219
+ end
220
+ end
221
+
222
+ context "с указанием параметров" do
223
+ before(:each) do
224
+ @request = lambda { UserbaseClient::User.authenticate @params.values.first, "pass", ["guid", "login"] }
225
+ @result = @request.call
226
+ end
227
+
228
+ it_should_behave_like "стандартный неуспешный ответ"
229
+
230
+ it "должен запрашиваться /v1/sessions.json через POST" do
231
+ WebMock.should have_requested(:post, @path)
232
+ end
233
+
234
+ it "передаваемые параметры должны попадать в запрос" do
235
+ WebMock.should have_requested(:post, @path).with(:body => @params.merge('password' => 'pass', 'attrs' => ['guid', 'login']))
236
+ end
237
+
238
+ it "должен возвращать GUID при наличии guid в ответе" do
239
+ @result.should be_true
240
+ end
241
+
242
+ it "должен возвращать false при статусе ответа 401" do
243
+ stub_request(:any, @path).to_return(:status => 401)
244
+ @request.call.should be_false
245
+ end
246
+ end
247
+ end
248
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe UserbaseClient do
5
+ it "должен устанавливаться хост" do
6
+ UserbaseClient.config.host = 'example.com'
7
+ UserbaseClient.config.host.should == 'example.com'
8
+ end
9
+
10
+ it "должен присутствовать хост по умолчанию" do
11
+ UserbaseClient.config.host.should_not be_empty
12
+ end
13
+
14
+ it "конфигурация должна происзводиться через блок" do
15
+ UserbaseClient.config do |config|
16
+ config.host = "example3.com"
17
+ end
18
+ UserbaseClient.config.host.should == 'example3.com'
19
+ end
20
+
21
+ it "конфигурация должна происзводиться через блок после простой конфигурации" do
22
+ UserbaseClient.config.host = 'example.com'
23
+ UserbaseClient.config do |config|
24
+ config.host = "example4.com"
25
+ end
26
+ UserbaseClient.config.host.should == 'example4.com'
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "serialization_extender/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "serialization_extender"
7
+ s.version = SerializationExtender::VERSION
8
+ s.authors = ["Andrew Rudenko", "Nick Recobra"]
9
+ s.email = ["ceo@prepor.ru"]
10
+ s.homepage = "http://github.com/Undev/serialization_extender"
11
+ s.summary = %q{JSON serialization profiles.}
12
+ s.description = %q{Multiple JSON serialization profiles for your ActiveModel objects.}
13
+
14
+ s.rubyforge_project = "serialization_extender"
15
+ s.add_dependency 'ruby-interface', '>= 0.0.6'
16
+ s.add_development_dependency 'rspec', '>= 2.6.0'
17
+ s.add_development_dependency 'activemodel', '>= 3.0.0'
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+ end
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'active_model'
4
+
5
+ describe SerializationExtender do
6
+ let(:klass) do
7
+ Class.new do
8
+ include ActiveModel::Serializers::JSON
9
+ include SerializationExtender
10
+ serialization_extender do
11
+ profile :default, :methods => [:extended_foo]
12
+ end
13
+ attr_accessor :foo, :bar
14
+
15
+ def attributes
16
+ @attributes ||= { 'foo' => 'nil', 'bar' => 'nil' }
17
+ end
18
+
19
+ def self.name
20
+ "Obj"
21
+ end
22
+
23
+ def extended_foo
24
+ "extended foo"
25
+ end
26
+ end
27
+ end
28
+
29
+ let(:obj) { klass.new }
30
+
31
+ it "should include `extended_foo` serialization result" do
32
+ obj.as_json['obj'][:extended_foo].should eq("extended foo")
33
+ end
34
+
35
+ context "multiple profiles" do
36
+ before do
37
+ klass.serialization_extender.profile :short, :only => [:foo]
38
+ end
39
+
40
+ it "should serialize only `foo`" do
41
+ obj.foo = "fee"
42
+ obj.as_json(:profile => :short)['obj'].should eq({ "foo" => "fee" })
43
+ end
44
+ end
45
+
46
+ context "with block" do
47
+ before do
48
+ klass.serialization_extender.profile :custom do |res|
49
+ res.merge :custom => "cu"
50
+ end
51
+ end
52
+
53
+ it "should add `custom`" do
54
+ obj.foo = "fee"
55
+ res = obj.as_json(:profile => :custom)['obj']
56
+ res["foo"].should eq("fee")
57
+ res[:custom].should eq("cu")
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require 'rubygems'
3
+ require 'rspec'
4
+ require 'serialization_extender'
5
+
6
+ RSpec.configure do |c|
7
+ c.mock_with :rspec
8
+ end
9
+
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: serialization_extender
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Rudenko
9
+ - Nick Recobra
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2011-08-02 00:00:00.000000000Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ruby-interface
17
+ requirement: &2153532040 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 0.0.6
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2153532040
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ requirement: &2153531540 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 2.6.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *2153531540
37
+ - !ruby/object:Gem::Dependency
38
+ name: activemodel
39
+ requirement: &2153531080 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: 3.0.0
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *2153531080
48
+ description: Multiple JSON serialization profiles for your ActiveModel objects.
49
+ email:
50
+ - ceo@prepor.ru
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - Gemfile
57
+ - Rakefile
58
+ - lib/serialization_extender.rb
59
+ - lib/serialization_extender/version.rb
60
+ - lib/userbase_client/user_spec.rb
61
+ - lib/userbase_client_spec.rb
62
+ - serialization_extender.gemspec
63
+ - spec/lib/serialization_extender_spec.rb
64
+ - spec/spec_helper.rb
65
+ homepage: http://github.com/Undev/serialization_extender
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project: serialization_extender
85
+ rubygems_version: 1.8.5
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: JSON serialization profiles.
89
+ test_files:
90
+ - spec/lib/serialization_extender_spec.rb
91
+ - spec/spec_helper.rb