appengine-apis 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/appengine-apis.rb +1 -1
- data/lib/appengine-apis/apiproxy.rb +11 -4
- data/lib/appengine-apis/labs/taskqueue.rb +2 -2
- data/lib/appengine-apis/memcache.rb +8 -8
- data/lib/appengine-apis/runtime.rb +32 -0
- data/lib/appengine-apis/testing.rb +63 -159
- data/lib/appengine-apis/urlfetch.rb +8 -2
- data/spec/memcache_spec.rb +64 -55
- data/spec/spec_helper.rb +9 -10
- data/spec/users_spec.rb +16 -14
- metadata +19 -9
data/lib/appengine-apis.rb
CHANGED
@@ -23,16 +23,22 @@ module AppEngine
|
|
23
23
|
import com.google.apphosting.api.ApiProxy
|
24
24
|
|
25
25
|
class << ApiProxy
|
26
|
-
def
|
26
|
+
def version
|
27
|
+
version_id = get_current_environment.getVersionId
|
28
|
+
version_id[0,version_id.rindex(".").to_i] # nil to 0
|
29
|
+
end
|
30
|
+
|
31
|
+
def app_id
|
27
32
|
get_current_environment.getAppId
|
28
33
|
end
|
29
|
-
|
30
|
-
|
34
|
+
alias :get_app_id :app_id
|
35
|
+
|
36
|
+
def auth_domain
|
31
37
|
get_current_environment.getAuthDomain
|
32
38
|
end
|
39
|
+
alias :get_auth_domain :auth_domain
|
33
40
|
|
34
41
|
alias :add_log_record :log
|
35
|
-
|
36
42
|
def log(level, message)
|
37
43
|
message = (message || "").to_s.chomp
|
38
44
|
return if message.nil? || message.empty?
|
@@ -40,6 +46,7 @@ module AppEngine
|
|
40
46
|
level, java.lang.System.currentTimeMillis() * 1000, message.to_s)
|
41
47
|
add_log_record(record)
|
42
48
|
end
|
49
|
+
|
43
50
|
end
|
44
51
|
end
|
45
52
|
end
|
@@ -112,7 +112,7 @@ module AppEngine
|
|
112
112
|
# - queue: Name of the queue where this Task should be added. (optional)
|
113
113
|
#
|
114
114
|
def add(queue=nil)
|
115
|
-
queue = Queue.new(queue) unless
|
115
|
+
queue = Queue.new(queue) unless queue.kind_of? Queue
|
116
116
|
@handle = queue.java_queue.add(_task)
|
117
117
|
self
|
118
118
|
end
|
@@ -263,4 +263,4 @@ module AppEngine
|
|
263
263
|
end
|
264
264
|
end
|
265
265
|
end
|
266
|
-
end
|
266
|
+
end
|
@@ -433,7 +433,7 @@ module AppEngine
|
|
433
433
|
|
434
434
|
def memcache_key(obj)
|
435
435
|
key = obj
|
436
|
-
key = key.to_s
|
436
|
+
key = java.lang.String.new(key.to_s) if key
|
437
437
|
key
|
438
438
|
end
|
439
439
|
|
@@ -450,10 +450,10 @@ module AppEngine
|
|
450
450
|
else
|
451
451
|
if obj.class == String
|
452
452
|
# Convert plain strings to Java strings
|
453
|
-
obj
|
453
|
+
java.lang.String.new(obj)
|
454
454
|
else
|
455
455
|
bytes = Marshal.dump(obj).to_java_bytes
|
456
|
-
java.util.ArrayList.new([MARSHAL_MARKER
|
456
|
+
java.util.ArrayList.new([java.lang.String.new(MARSHAL_MARKER), bytes])
|
457
457
|
end
|
458
458
|
end
|
459
459
|
end
|
@@ -502,8 +502,8 @@ module AppEngine
|
|
502
502
|
convert_exceptions do
|
503
503
|
key = memcache_key(key)
|
504
504
|
value = memcache_value(value)
|
505
|
-
|
506
|
-
service.put(key, value,
|
505
|
+
expiration = memcache_expiration(expiration)
|
506
|
+
service.put(key, value, expiration, mode)
|
507
507
|
end
|
508
508
|
end
|
509
509
|
|
@@ -541,7 +541,7 @@ module AppEngine
|
|
541
541
|
end
|
542
542
|
@map[string_key] = key
|
543
543
|
if string_key
|
544
|
-
string_key
|
544
|
+
java.lang.String.new(string_key)
|
545
545
|
else
|
546
546
|
string_key
|
547
547
|
end
|
@@ -550,7 +550,7 @@ module AppEngine
|
|
550
550
|
def java_keys
|
551
551
|
@map.keys.collect do |key|
|
552
552
|
if key
|
553
|
-
key
|
553
|
+
java.lang.String.new(key)
|
554
554
|
else
|
555
555
|
key
|
556
556
|
end
|
@@ -577,4 +577,4 @@ module AppEngine
|
|
577
577
|
end
|
578
578
|
end
|
579
579
|
end
|
580
|
-
end
|
580
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/ruby1.8 -w
|
2
|
+
#
|
3
|
+
# Copyright:: Copyright 2009 Google Inc.
|
4
|
+
# Original Author:: John Woodell (mailto:woodie@google.com)
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
module AppEngine
|
19
|
+
if defined? Java
|
20
|
+
import com.google.appengine.api.utils.SystemProperty
|
21
|
+
|
22
|
+
class Runtime
|
23
|
+
def self.environment
|
24
|
+
SystemProperty.environment.get.to_s.downcase
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.version
|
28
|
+
SystemProperty.version.get.to_s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -18,10 +18,8 @@
|
|
18
18
|
#
|
19
19
|
# Helpers for installing stub apis in unit tests.
|
20
20
|
|
21
|
-
require 'appengine-apis/apiproxy'
|
22
|
-
|
23
21
|
module AppEngine
|
24
|
-
|
22
|
+
|
25
23
|
# Local testing support for Google App Engine
|
26
24
|
#
|
27
25
|
# If you run your code on Google's servers or under dev_appserver,
|
@@ -31,187 +29,93 @@ module AppEngine
|
|
31
29
|
# api stubs.
|
32
30
|
module Testing
|
33
31
|
|
34
|
-
|
35
|
-
include AppEngine::ApiProxy::Environment
|
36
|
-
|
37
|
-
attr_writer :appid, :version, :email, :admin
|
38
|
-
attr_writer :auth_domain, :request_namespace, :default_namespace
|
39
|
-
attr_reader :attributes
|
40
|
-
|
41
|
-
def initialize
|
42
|
-
@appid = "test"
|
43
|
-
@version = "1.0"
|
44
|
-
@auth_domain= "gmail.com"
|
45
|
-
@default_namespace = @request_namespace = ""
|
46
|
-
@email = ""
|
47
|
-
@attributes = java.util.HashMap.new
|
48
|
-
end
|
49
|
-
|
50
|
-
def getAppId
|
51
|
-
@appid
|
52
|
-
end
|
53
|
-
|
54
|
-
def getVersionId
|
55
|
-
@version
|
56
|
-
end
|
57
|
-
|
58
|
-
def getEmail
|
59
|
-
@email
|
60
|
-
end
|
61
|
-
|
62
|
-
def isLoggedIn
|
63
|
-
!(@email.nil? || @auth_domain.nil? || @email.empty?)
|
64
|
-
end
|
65
|
-
|
66
|
-
def isAdmin
|
67
|
-
!!@admin
|
68
|
-
end
|
69
|
-
|
70
|
-
def getAuthDomain
|
71
|
-
@auth_domain
|
72
|
-
end
|
73
|
-
|
74
|
-
def getRequestNamespace
|
75
|
-
@request_namespace
|
76
|
-
end
|
77
|
-
|
78
|
-
def getDefaultNamespace
|
79
|
-
@default_namespace
|
80
|
-
end
|
81
|
-
|
82
|
-
def setDefaultNamespace(s)
|
83
|
-
@default_namespace = s
|
84
|
-
end
|
85
|
-
|
86
|
-
def getAttributes
|
87
|
-
@attributes
|
88
|
-
end
|
89
|
-
|
90
|
-
def inspect
|
91
|
-
"#<TestEnv>"
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
32
|
+
|
95
33
|
class << self
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
#
|
103
|
-
#
|
104
|
-
def
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
34
|
+
def delegate # :nodoc:
|
35
|
+
helper # make sure everything's loaded
|
36
|
+
require 'appengine-apis/apiproxy'
|
37
|
+
AppEngine::ApiProxy.getDelegate
|
38
|
+
end
|
39
|
+
|
40
|
+
# The LocalServiceTestHelper used by this class.
|
41
|
+
# Use this to set the logged in user, etc.
|
42
|
+
def helper
|
43
|
+
failed = false
|
44
|
+
@helper ||= begin
|
45
|
+
testing = Java::ComGoogleAppengineToolsDevelopmentTesting
|
46
|
+
@datastore_config = testing::LocalDatastoreServiceTestConfig.new
|
47
|
+
configs = [
|
48
|
+
@datastore_config,
|
49
|
+
testing::LocalBlobstoreServiceTestConfig.new,
|
50
|
+
testing::LocalImagesServiceTestConfig.new,
|
51
|
+
testing::LocalMailServiceTestConfig.new,
|
52
|
+
testing::LocalMemcacheServiceTestConfig.new,
|
53
|
+
testing::LocalTaskQueueTestConfig.new,
|
54
|
+
testing::LocalURLFetchServiceTestConfig.new,
|
55
|
+
testing::LocalUserServiceTestConfig.new,
|
56
|
+
testing::LocalXMPPServiceTestConfig.new,
|
57
|
+
].to_java(testing::LocalServiceTestConfig)
|
58
|
+
testing::LocalServiceTestHelper.new(configs)
|
59
|
+
rescue => ex
|
60
|
+
if failed
|
61
|
+
raise ex
|
62
|
+
else
|
63
|
+
failed = true
|
64
|
+
require 'appengine-sdk'
|
65
|
+
AppEngine::SDK.load_local_test_helper
|
66
|
+
retry
|
67
|
+
end
|
116
68
|
end
|
117
69
|
end
|
118
|
-
|
119
|
-
# The application directory, or '.' if not set.
|
120
|
-
# Composite index definitions are written to "#{app_dir}/WEB-INF/".
|
121
|
-
def app_dir
|
122
|
-
file = factory.getApplicationDirectory
|
123
|
-
file && file.path
|
124
|
-
end
|
125
70
|
|
126
|
-
# Sets the application directory. Should be called before
|
127
|
-
# creating stubs.
|
128
|
-
#
|
129
|
-
# Composite index definitions are written to "#{app_dir}/WEB-INF/".
|
130
|
-
def app_dir=(dir)
|
131
|
-
factory.setApplicationDirectory(java.io.File.new(dir))
|
132
|
-
end
|
133
|
-
|
134
71
|
# Install stub apis and force all datastore operations to use
|
135
72
|
# an in-memory datastore.
|
136
73
|
#
|
137
74
|
# You may call this multiple times to reset to a new in-memory datastore.
|
138
75
|
def install_test_datastore
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
delegate.set_property(
|
143
|
-
lds::NO_STORAGE_PROPERTY, "true")
|
144
|
-
delegate.set_property(
|
145
|
-
lds::MAX_QUERY_LIFETIME_PROPERTY,
|
146
|
-
java.lang.Integer::MAX_VALUE.to_s)
|
147
|
-
delegate.set_property(
|
148
|
-
lds::MAX_TRANSACTION_LIFETIME_PROPERTY,
|
149
|
-
java.lang.Integer::MAX_VALUE.to_s)
|
150
|
-
ApiProxy::setDelegate(delegate)
|
151
|
-
delegate
|
76
|
+
self.persistent_datastore = false
|
77
|
+
setup
|
152
78
|
end
|
153
|
-
|
154
|
-
# Install stub apis. The datastore will be written to the disk
|
155
|
-
# inside #app_dir.
|
156
|
-
#
|
157
|
-
# You could potentially use this to run under a ruby web server
|
158
|
-
# instead of dev_appserver. In that case you will need to install
|
159
|
-
# and configure a test environment for each request.
|
160
|
-
def install_api_stubs
|
161
|
-
current_delegate = ApiProxy.getDelegate
|
162
|
-
current_delegate.stop if current_delegate.respond_to? :stop
|
163
79
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
80
|
+
def persistent_datastore
|
81
|
+
helper
|
82
|
+
!@datastore_config.is_no_storage
|
83
|
+
end
|
84
|
+
|
85
|
+
def persistent_datastore=(value)
|
86
|
+
helper
|
87
|
+
@datastore_config.set_no_storage(!value)
|
88
|
+
setup
|
89
|
+
end
|
90
|
+
|
91
|
+
def setup
|
92
|
+
if delegate
|
93
|
+
teardown rescue nil
|
169
94
|
end
|
170
|
-
|
95
|
+
helper.setUp
|
171
96
|
end
|
172
|
-
|
97
|
+
|
98
|
+
def teardown
|
99
|
+
helper.tearDown
|
100
|
+
end
|
101
|
+
|
173
102
|
# Loads stub API implementations if no API implementation is
|
174
103
|
# currently configured.
|
175
104
|
#
|
176
|
-
# Sets up a datastore saved to disk in
|
177
|
-
# to ENV['APPLICATION_ROOT'] or '.' if not specified.
|
105
|
+
# Sets up a datastore saved to disk in '.'.
|
178
106
|
#
|
179
107
|
# Does nothing is APIs are already configured (e.g. in production).
|
180
108
|
#
|
181
109
|
# As a shortcut you can use
|
182
110
|
# require 'appengine-apis/local_boot'
|
183
111
|
#
|
184
|
-
def boot
|
185
|
-
if
|
186
|
-
AppEngine::ApiProxy.getDelegate
|
112
|
+
def boot
|
113
|
+
if delegate
|
187
114
|
return
|
188
115
|
end
|
189
|
-
|
190
|
-
|
191
|
-
env = install_test_env
|
192
|
-
appid = get_app_id(app_dir)
|
193
|
-
env.appid = appid if appid
|
194
|
-
end
|
195
|
-
unless AppEngine::ApiProxy.getDelegate
|
196
|
-
self.app_dir = app_dir
|
197
|
-
install_api_stubs
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
# Looks for app.yaml or WEB-INF/appengine-web.xml in +app_dir+
|
202
|
-
# and parses the application id.
|
203
|
-
def get_app_id(app_dir)
|
204
|
-
require 'appengine-rack'
|
205
|
-
app_id = AppEngine::Rack.app.id
|
206
|
-
return app_id if app_id
|
207
|
-
aeweb_path = File.join(app_dir, 'WEB-INF', 'appengine-web.xml')
|
208
|
-
if File.exist?(aeweb_path)
|
209
|
-
require 'rexml/document'
|
210
|
-
aeweb = REXML::Document.new(File.new(aeweb_path))
|
211
|
-
return aeweb.root.elements['application'].text
|
212
|
-
end
|
116
|
+
self.persistent_datastore = true
|
117
|
+
setup
|
213
118
|
end
|
214
|
-
|
215
119
|
end
|
216
120
|
|
217
121
|
end
|
@@ -103,9 +103,11 @@ module AppEngine
|
|
103
103
|
payload = options.delete(:payload)
|
104
104
|
headers = options.delete(:headers) || {}
|
105
105
|
truncate = options.delete(:allow_truncated)
|
106
|
-
follow_redirects = options.delete(:follow_redirects)
|
106
|
+
follow_redirects = options.delete(:follow_redirects)
|
107
107
|
deadline = options.delete(:deadline)
|
108
108
|
|
109
|
+
follow_redirects = true if follow_redirects.nil?
|
110
|
+
|
109
111
|
unless options.empty?
|
110
112
|
raise ArgumentError, "Unsupported options #{options.inspect}."
|
111
113
|
end
|
@@ -204,7 +206,11 @@ module Net # :nodoc:
|
|
204
206
|
yield res if block_given?
|
205
207
|
}
|
206
208
|
return res
|
207
|
-
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def use_ssl=(flag)
|
212
|
+
@use_ssl = flag
|
213
|
+
end
|
208
214
|
end
|
209
215
|
|
210
216
|
class HTTPResponse # :nodoc:
|
data/spec/memcache_spec.rb
CHANGED
@@ -21,61 +21,57 @@ describe AppEngine::Memcache do
|
|
21
21
|
AppEngine::Testing::install_test_datastore
|
22
22
|
@cache = AppEngine::Memcache.new
|
23
23
|
end
|
24
|
-
|
25
|
-
before :all do
|
26
|
-
AppEngine::Testing::install_test_env
|
27
|
-
end
|
28
|
-
|
24
|
+
|
29
25
|
describe 'get' do
|
30
|
-
|
26
|
+
|
31
27
|
it 'should return nil on miss' do
|
32
28
|
@cache.get('foobar').should == nil
|
33
29
|
@cache['foobar'].should == nil
|
34
30
|
end
|
35
|
-
|
31
|
+
|
36
32
|
it 'should support strings' do
|
37
33
|
@cache.set('foobar', 'test').should == true
|
38
34
|
@cache.get('foobar').should == 'test'
|
39
35
|
@cache['foobar'].should == 'test'
|
40
36
|
end
|
41
|
-
|
37
|
+
|
42
38
|
it 'should support multiple values' do
|
43
39
|
@cache.get('foo', 'bar', 'baz').should == [nil, nil, nil]
|
44
40
|
@cache['foo', 'bar', 'baz'].should == [nil, nil, nil]
|
45
41
|
@cache.set('bar', 'food').should == true
|
46
42
|
@cache['foo', 'bar', 'baz'].should == [nil, 'food', nil]
|
47
43
|
end
|
48
|
-
|
44
|
+
|
49
45
|
it 'should support getting an array of keys' do
|
50
46
|
@cache.set('foobar', 'test').should == true
|
51
47
|
@cache.get(['foobar', 'flowers']).should == ['test', nil]
|
52
48
|
@cache.get(['foobar']).should == ['test']
|
53
49
|
end
|
54
|
-
|
50
|
+
|
55
51
|
it 'should support numbers' do
|
56
52
|
@cache.set('one', 1).should == true
|
57
53
|
@cache.set('pi', 3.14).should == true
|
58
54
|
@cache.get('pi').should == 3.14
|
59
55
|
@cache.get('one').should === 1
|
60
56
|
end
|
61
|
-
|
57
|
+
|
62
58
|
it 'should support symbol keys' do
|
63
59
|
@cache.set(:a, 'A')
|
64
60
|
@cache.get(:a).should == 'A'
|
65
61
|
end
|
66
|
-
|
62
|
+
|
67
63
|
it 'should support booleans' do
|
68
64
|
@cache.set('true', true)
|
69
65
|
@cache.set('false', false)
|
70
66
|
@cache.get('true').should == true
|
71
67
|
@cache.get('false').should == false
|
72
68
|
end
|
73
|
-
|
69
|
+
|
74
70
|
it 'should support marshaled objects' do
|
75
71
|
@cache.set('a', 1..5)
|
76
72
|
@cache.get('a').should == (1..5)
|
77
73
|
end
|
78
|
-
|
74
|
+
|
79
75
|
it 'should support false keys' do
|
80
76
|
@cache.set(nil, 'nil')
|
81
77
|
@cache.set(false, 'false')
|
@@ -83,19 +79,19 @@ describe AppEngine::Memcache do
|
|
83
79
|
@cache.get(false).should == 'false'
|
84
80
|
end
|
85
81
|
end
|
86
|
-
|
82
|
+
|
87
83
|
describe 'get_hash' do
|
88
84
|
it 'should not include missing keys' do
|
89
85
|
@cache.get_hash(:a, :b).should == {}
|
90
86
|
end
|
91
|
-
|
87
|
+
|
92
88
|
it 'should get objects' do
|
93
89
|
@cache.set('a', 'A')
|
94
90
|
@cache.set('b', 3)
|
95
91
|
@cache.get_hash('a', 'c', 'b').should == {'a' => 'A', 'b' => 3 }
|
96
92
|
end
|
97
93
|
end
|
98
|
-
|
94
|
+
|
99
95
|
describe 'clear' do
|
100
96
|
it 'should clear the cache' do
|
101
97
|
@cache.set(:a, 'A')
|
@@ -104,7 +100,7 @@ describe AppEngine::Memcache do
|
|
104
100
|
@cache.get_hash(:a, 'b', :c).should == {}
|
105
101
|
end
|
106
102
|
end
|
107
|
-
|
103
|
+
|
108
104
|
describe 'flush_all' do
|
109
105
|
it 'should clear the cache' do
|
110
106
|
@cache.set(:a, 'A')
|
@@ -113,7 +109,7 @@ describe AppEngine::Memcache do
|
|
113
109
|
@cache.get_hash(:a, 'b', :c).should == {}
|
114
110
|
end
|
115
111
|
end
|
116
|
-
|
112
|
+
|
117
113
|
describe 'stats' do
|
118
114
|
it 'should count items' do
|
119
115
|
@cache.stats[:items].should == 0
|
@@ -130,11 +126,11 @@ describe AppEngine::Memcache do
|
|
130
126
|
@cache.get(:a).should == nil
|
131
127
|
@cache.get_hash(:a).should == {}
|
132
128
|
end
|
133
|
-
|
129
|
+
|
134
130
|
it 'should return false on missing items' do
|
135
131
|
@cache.delete(:a).should == false
|
136
132
|
end
|
137
|
-
|
133
|
+
|
138
134
|
it 'should allow blocking adds' do
|
139
135
|
@cache.set(:a, '1')
|
140
136
|
@cache.set(:b, '2')
|
@@ -144,7 +140,7 @@ describe AppEngine::Memcache do
|
|
144
140
|
@cache.add(:b, 'B').should == false
|
145
141
|
end
|
146
142
|
end
|
147
|
-
|
143
|
+
|
148
144
|
describe 'delete_many' do
|
149
145
|
it 'should remove items' do
|
150
146
|
@cache.set(:a, 'A')
|
@@ -153,7 +149,7 @@ describe AppEngine::Memcache do
|
|
153
149
|
@cache.delete_many([:a, :c])
|
154
150
|
@cache.get_hash(:a, :b, :c).should == {:b => 'B'}
|
155
151
|
end
|
156
|
-
|
152
|
+
|
157
153
|
it 'should return removed keys' do
|
158
154
|
@cache.set('a', 'A')
|
159
155
|
@cache.set('b', 'B')
|
@@ -161,7 +157,7 @@ describe AppEngine::Memcache do
|
|
161
157
|
removed = @cache.delete_many(['a', 'c'])
|
162
158
|
removed.sort.should == ['a', 'c']
|
163
159
|
end
|
164
|
-
|
160
|
+
|
165
161
|
it 'should not return missing keys' do
|
166
162
|
@cache.set('a', 'A')
|
167
163
|
@cache.set('b', 'B')
|
@@ -170,8 +166,8 @@ describe AppEngine::Memcache do
|
|
170
166
|
removed.sort.should == ['a', 'c']
|
171
167
|
@cache.delete_many(['e']).should == []
|
172
168
|
end
|
173
|
-
|
174
|
-
|
169
|
+
|
170
|
+
|
175
171
|
it 'should allow blocking adds' do
|
176
172
|
@cache.set(:a, '1')
|
177
173
|
@cache.set(:b, '2')
|
@@ -181,44 +177,44 @@ describe AppEngine::Memcache do
|
|
181
177
|
@cache.add(:b, 'B').should == false
|
182
178
|
end
|
183
179
|
end
|
184
|
-
|
180
|
+
|
185
181
|
describe 'add' do
|
186
182
|
it 'should add missing' do
|
187
183
|
@cache.add(:a, 'A').should == true
|
188
184
|
@cache.get(:a).should == 'A'
|
189
185
|
end
|
190
|
-
|
186
|
+
|
191
187
|
it 'should not replace existing entries' do
|
192
188
|
@cache.set(:a, 1)
|
193
189
|
@cache.add(:a, 'A').should == false
|
194
190
|
@cache.get(:a).should == 1
|
195
191
|
end
|
196
192
|
end
|
197
|
-
|
193
|
+
|
198
194
|
describe 'add_many' do
|
199
195
|
it 'should add missing' do
|
200
196
|
@cache.add_many({:a => 1, :b =>2})
|
201
197
|
@cache.get(:b, :a).should == [2, 1]
|
202
198
|
end
|
203
|
-
|
199
|
+
|
204
200
|
it 'should not replace existing entries' do
|
205
201
|
@cache.set(:a, 1)
|
206
202
|
@cache.add_many({:a => 'A', :b => 'B'})
|
207
203
|
@cache.get(:a, :b).should == [1, 'B']
|
208
204
|
end
|
209
|
-
|
205
|
+
|
210
206
|
it 'should return existing keys' do
|
211
207
|
@cache.set(:a, 1)
|
212
208
|
@cache.add_many({:a => 'A', :b => 'B'}).should == [:a]
|
213
209
|
end
|
214
210
|
end
|
215
|
-
|
211
|
+
|
216
212
|
describe 'set' do
|
217
213
|
it 'should add missing' do
|
218
214
|
@cache.set(:a, :A).should == true
|
219
215
|
@cache.get(:a).should == :A
|
220
216
|
end
|
221
|
-
|
217
|
+
|
222
218
|
it 'should replace existing' do
|
223
219
|
@cache.set(:a, :A).should == true
|
224
220
|
@cache.get(:a).should == :A
|
@@ -226,13 +222,13 @@ describe AppEngine::Memcache do
|
|
226
222
|
@cache.get(:a).should == 1
|
227
223
|
end
|
228
224
|
end
|
229
|
-
|
225
|
+
|
230
226
|
describe 'set_many' do
|
231
227
|
it 'should set multiple values' do
|
232
228
|
@cache.set_many({:a => 1, :b => 2}).should == []
|
233
229
|
end
|
234
230
|
end
|
235
|
-
|
231
|
+
|
236
232
|
describe 'replace' do
|
237
233
|
it 'should replace existing' do
|
238
234
|
@cache.set(:a, :A).should == true
|
@@ -240,12 +236,12 @@ describe AppEngine::Memcache do
|
|
240
236
|
@cache.replace(:a, 1).should == true
|
241
237
|
@cache.get(:a).should == 1
|
242
238
|
end
|
243
|
-
|
239
|
+
|
244
240
|
it 'should not replace missing' do
|
245
241
|
@cache.replace(:a, :A).should == false
|
246
242
|
end
|
247
243
|
end
|
248
|
-
|
244
|
+
|
249
245
|
describe 'replace_many' do
|
250
246
|
it 'should replace many' do
|
251
247
|
@cache.set_many({:a => 1, :c => 3})
|
@@ -253,7 +249,7 @@ describe AppEngine::Memcache do
|
|
253
249
|
@cache.get(:a, :b, :c).should == [:A, nil, :C]
|
254
250
|
end
|
255
251
|
end
|
256
|
-
|
252
|
+
|
257
253
|
describe 'dict access' do
|
258
254
|
it 'should support getting with []' do
|
259
255
|
@cache.set(:a, 7)
|
@@ -261,7 +257,7 @@ describe AppEngine::Memcache do
|
|
261
257
|
@cache.set(:b, :B)
|
262
258
|
@cache[:a, :b].should == [7, :B]
|
263
259
|
end
|
264
|
-
|
260
|
+
|
265
261
|
it 'should support setting with []=' do
|
266
262
|
@cache[:a, :b] = [1, :B]
|
267
263
|
@cache[:c] = 3
|
@@ -270,7 +266,7 @@ describe AppEngine::Memcache do
|
|
270
266
|
@cache[:c].should == 3
|
271
267
|
end
|
272
268
|
end
|
273
|
-
|
269
|
+
|
274
270
|
describe 'incr' do
|
275
271
|
it 'should increment number' do
|
276
272
|
@cache.set(:a, 1)
|
@@ -278,13 +274,13 @@ describe AppEngine::Memcache do
|
|
278
274
|
@cache.incr(:a, 7).should == 9
|
279
275
|
@cache.get(:a).should == 9
|
280
276
|
end
|
281
|
-
|
277
|
+
|
282
278
|
it 'should wrap' do
|
283
279
|
@cache.set(:a, 7)
|
284
280
|
@cache.incr(:a, 2**62).should == 2**62 + 7
|
285
281
|
@cache.incr(:a, 2**62).should < 2**62
|
286
282
|
end
|
287
|
-
|
283
|
+
|
288
284
|
it 'should fail if not number' do
|
289
285
|
@cache.incr(:a).should == nil
|
290
286
|
@cache.get_hash([:a]).should == {}
|
@@ -292,13 +288,13 @@ describe AppEngine::Memcache do
|
|
292
288
|
lambda {@cache.incr(:b)}.should raise_error(
|
293
289
|
AppEngine::Memcache::InvalidValueError)
|
294
290
|
end
|
295
|
-
|
291
|
+
|
296
292
|
it 'should increment strings' do
|
297
293
|
@cache.set(:a, '7')
|
298
294
|
@cache.incr(:a).should == 8
|
299
295
|
end
|
300
296
|
end
|
301
|
-
|
297
|
+
|
302
298
|
describe 'decr' do
|
303
299
|
it 'should decrement number' do
|
304
300
|
@cache.set(:a, 7)
|
@@ -312,72 +308,85 @@ describe AppEngine::Memcache do
|
|
312
308
|
@cache.get(:a).should == 0
|
313
309
|
end
|
314
310
|
end
|
315
|
-
|
311
|
+
|
316
312
|
describe 'readonly' do
|
317
313
|
before :each do
|
318
314
|
@rocache = AppEngine::Memcache.new(:readonly => true)
|
319
315
|
@ex = AppEngine::Memcache::MemcacheError
|
320
316
|
end
|
321
|
-
|
317
|
+
|
322
318
|
it 'should allow reads' do
|
323
319
|
@cache[:a] = 1
|
324
320
|
@rocache.get(:a).should == 1
|
325
321
|
end
|
326
|
-
|
322
|
+
|
327
323
|
it 'should allow stats' do
|
328
324
|
@cache[:a] = 7
|
329
325
|
@rocache.stats[:items].should == 1
|
330
326
|
end
|
331
|
-
|
327
|
+
|
332
328
|
it 'should block delete' do
|
333
329
|
@cache[:a] = 1
|
334
330
|
lambda {@rocache.delete(:a)}.should raise_error(@ex)
|
335
331
|
@cache[:a].should == 1
|
336
332
|
end
|
337
|
-
|
333
|
+
|
338
334
|
it 'should block add' do
|
339
335
|
lambda {@rocache.add(:a, 1)}.should raise_error(@ex)
|
340
336
|
lambda {@rocache.add_many({:b => 1})}.should raise_error(@ex)
|
341
337
|
@rocache.get_hash(:a, :b).should == {}
|
342
338
|
end
|
343
|
-
|
339
|
+
|
344
340
|
it 'should block set' do
|
345
341
|
lambda {@rocache.set(:a, 1)}.should raise_error(@ex)
|
346
342
|
lambda {@rocache.set_many({:b => 1})}.should raise_error(@ex)
|
347
343
|
@rocache.get_hash(:a, :b).should == {}
|
348
344
|
end
|
349
|
-
|
345
|
+
|
350
346
|
it 'should block replace' do
|
351
347
|
@cache[:a, :b] = :A, :B
|
352
348
|
lambda {@rocache.replace(:a, 1)}.should raise_error(@ex)
|
353
349
|
lambda {@rocache.replace_many({:b => 1})}.should raise_error(@ex)
|
354
350
|
@rocache[:a, :b].should == [:A, :B]
|
355
351
|
end
|
356
|
-
|
352
|
+
|
357
353
|
it 'should block clear' do
|
358
354
|
@cache[:a] = 1
|
359
355
|
lambda {@rocache.clear}.should raise_error(@ex)
|
360
356
|
lambda {@rocache.flush_all}.should raise_error(@ex)
|
361
357
|
@rocache[:a].should == 1
|
362
358
|
end
|
363
|
-
|
359
|
+
|
364
360
|
it 'should block incr' do
|
365
361
|
@cache[:a] = 1
|
366
362
|
lambda {@rocache.incr(:a)}.should raise_error(@ex)
|
367
363
|
@rocache[:a].should == 1
|
368
364
|
end
|
369
|
-
|
365
|
+
|
370
366
|
it 'should block decr' do
|
371
367
|
@cache[:a] = 1
|
372
368
|
lambda {@rocache.decr(:a)}.should raise_error(@ex)
|
373
369
|
@rocache[:a].should == 1
|
374
370
|
end
|
375
371
|
end
|
376
|
-
|
372
|
+
|
377
373
|
describe "namespaces" do
|
378
374
|
it 'should get namespace from initialize' do
|
379
375
|
cache = AppEngine::Memcache.new(:namespace => "foo")
|
380
376
|
cache.namespace.should == "foo"
|
381
377
|
end
|
382
378
|
end
|
379
|
+
|
380
|
+
describe "utf8" do
|
381
|
+
it "should support utf8 value" do
|
382
|
+
@cache.set('foobar', 'テスト').should == true
|
383
|
+
@cache.get('foobar').should == 'テスト'
|
384
|
+
@cache['foobar'].should == 'テスト'
|
385
|
+
end
|
386
|
+
it "should support utf8 key" do
|
387
|
+
@cache.set('ふーばー', 'てすと').should == true
|
388
|
+
@cache.get('ふーばー').should == 'てすと'
|
389
|
+
@cache['ふーばー'].should == 'てすと'
|
390
|
+
end
|
391
|
+
end
|
383
392
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -8,9 +8,8 @@ rescue LoadError
|
|
8
8
|
end
|
9
9
|
|
10
10
|
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
11
|
-
AppEngine::SDK.load_apiproxy
|
12
11
|
require 'appengine-apis/testing'
|
13
|
-
AppEngine::Testing.
|
12
|
+
AppEngine::Testing.setup
|
14
13
|
|
15
14
|
class ProtoMatcher
|
16
15
|
def compare(hash, proto, prefix='')
|
@@ -36,19 +35,19 @@ class ProtoMatcher
|
|
36
35
|
end
|
37
36
|
end
|
38
37
|
end
|
39
|
-
|
38
|
+
|
40
39
|
def compare_value(label, expected, actual)
|
41
40
|
if expected != actual
|
42
|
-
@failures << "%s differs. expected: %s actual: %s" %
|
41
|
+
@failures << "%s differs. expected: %s actual: %s" %
|
43
42
|
[label, expected.inspect, actual.inspect]
|
44
43
|
end
|
45
44
|
end
|
46
|
-
|
45
|
+
|
47
46
|
def initialize(klass, expected)
|
48
47
|
@klass = klass
|
49
48
|
@expected = expected
|
50
49
|
end
|
51
|
-
|
50
|
+
|
52
51
|
def matches(bytes)
|
53
52
|
@failures = []
|
54
53
|
@proto = @klass.new
|
@@ -56,12 +55,12 @@ class ProtoMatcher
|
|
56
55
|
compare(@expected, @proto)
|
57
56
|
@failures.empty?
|
58
57
|
end
|
59
|
-
|
58
|
+
|
60
59
|
def ==(bytes)
|
61
60
|
Spec::Expectations.fail_with(failure_message) unless matches(bytes)
|
62
61
|
true
|
63
62
|
end
|
64
|
-
|
63
|
+
|
65
64
|
def failure_message
|
66
65
|
@failures.join("\n")
|
67
66
|
end
|
@@ -72,7 +71,7 @@ module ProtoMethods
|
|
72
71
|
ProtoMatcher.new(klass, hash)
|
73
72
|
end
|
74
73
|
alias be_proto proto
|
75
|
-
|
74
|
+
|
76
75
|
def mock_delegate
|
77
76
|
delegate = mock("apiproxy")
|
78
77
|
delegate.instance_eval do
|
@@ -80,7 +79,7 @@ module ProtoMethods
|
|
80
79
|
include AppEngine::ApiProxy::Delegate
|
81
80
|
end
|
82
81
|
end
|
83
|
-
end
|
82
|
+
end
|
84
83
|
end
|
85
84
|
|
86
85
|
Spec::Runner.configure do |config|
|
data/spec/users_spec.rb
CHANGED
@@ -18,50 +18,52 @@ require 'appengine-apis/users'
|
|
18
18
|
|
19
19
|
describe AppEngine::Users do
|
20
20
|
before :all do
|
21
|
-
AppEngine::Testing::
|
21
|
+
AppEngine::Testing::setup
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
before :each do
|
25
|
-
@env = AppEngine::Testing::
|
26
|
-
@env.
|
25
|
+
@env = AppEngine::Testing::helper
|
26
|
+
@env.set_env_email 'foo@example.com'
|
27
|
+
@env.set_env_auth_domain 'gmail.com'
|
28
|
+
@env.set_env_is_logged_in true
|
27
29
|
end
|
28
|
-
|
30
|
+
|
29
31
|
it "should have default auth_domain" do
|
30
32
|
user = AppEngine::Users.current_user
|
31
33
|
user.email.should == 'foo@example.com'
|
32
34
|
user.auth_domain.should == 'gmail.com'
|
33
35
|
end
|
34
|
-
|
36
|
+
|
35
37
|
it 'should read auth_domain' do
|
36
|
-
@env.
|
38
|
+
@env.set_env_auth_domain 'example.com'
|
37
39
|
AppEngine::Users.current_user.auth_domain.should == 'example.com'
|
38
40
|
end
|
39
|
-
|
41
|
+
|
40
42
|
it 'should read admin' do
|
41
43
|
AppEngine::Users.admin?.should == false
|
42
|
-
@env.
|
44
|
+
@env.set_env_is_admin true
|
43
45
|
AppEngine::Users.admin?.should == true
|
44
46
|
end
|
45
47
|
|
46
48
|
it 'should set logged_in?' do
|
47
49
|
AppEngine::Users.logged_in?.should == true
|
48
|
-
@env.
|
50
|
+
@env.set_env_is_logged_in nil
|
49
51
|
AppEngine::Users.logged_in?.should == false
|
50
52
|
end
|
51
|
-
|
53
|
+
|
52
54
|
it 'should create urls' do
|
53
55
|
login = AppEngine::Users.create_login_url('/foobar')
|
54
56
|
logout = AppEngine::Users.create_logout_url('/foobaz')
|
55
57
|
login.should =~ /foobar/
|
56
58
|
logout.should =~ /foobaz/
|
57
59
|
end
|
58
|
-
|
60
|
+
|
59
61
|
it 'should support new without auth domain' do
|
60
62
|
user = AppEngine::Users::User.new('foo@example.com')
|
61
63
|
user.auth_domain.should == 'gmail.com'
|
62
64
|
end
|
63
|
-
|
64
|
-
|
65
|
+
|
66
|
+
|
65
67
|
it 'should support new with auth domain' do
|
66
68
|
user = AppEngine::Users::User.new('foo@example.com', 'example.com')
|
67
69
|
user.auth_domain.should == 'example.com'
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appengine-apis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 13
|
9
|
+
version: 0.0.13
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Ryan Brown
|
@@ -9,19 +14,21 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date:
|
17
|
+
date: 2010-04-08 00:00:00 -07:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: appengine-rack
|
17
|
-
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
24
|
requirements:
|
21
25
|
- - ">="
|
22
26
|
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
23
29
|
version: "0"
|
24
|
-
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
25
32
|
description: Ruby API wrappers for App Engine
|
26
33
|
email: ribrdb@gmail.com
|
27
34
|
executables: []
|
@@ -45,6 +52,7 @@ files:
|
|
45
52
|
- lib/appengine-apis/mail.rb
|
46
53
|
- lib/appengine-apis/memcache.rb
|
47
54
|
- lib/appengine-apis/merb-logger.rb
|
55
|
+
- lib/appengine-apis/runtime.rb
|
48
56
|
- lib/appengine-apis/sdk.rb
|
49
57
|
- lib/appengine-apis/tempfile.rb
|
50
58
|
- lib/appengine-apis/testing.rb
|
@@ -76,18 +84,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
84
|
requirements:
|
77
85
|
- - ">="
|
78
86
|
- !ruby/object:Gem::Version
|
87
|
+
segments:
|
88
|
+
- 0
|
79
89
|
version: "0"
|
80
|
-
version:
|
81
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
91
|
requirements:
|
83
92
|
- - ">="
|
84
93
|
- !ruby/object:Gem::Version
|
94
|
+
segments:
|
95
|
+
- 0
|
85
96
|
version: "0"
|
86
|
-
version:
|
87
97
|
requirements: []
|
88
98
|
|
89
99
|
rubyforge_project:
|
90
|
-
rubygems_version: 1.3.
|
100
|
+
rubygems_version: 1.3.6
|
91
101
|
signing_key:
|
92
102
|
specification_version: 3
|
93
103
|
summary: Ruby API wrappers for App Engine
|