Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 # This will attempt to import the actual App Engine modules, and if it fails, | 5 # This will attempt to import the actual App Engine modules, and if it fails, |
| 6 # they will be replaced with fake modules. This is useful during testing. | 6 # they will be replaced with fake modules. This is useful during testing. |
| 7 try: | 7 try: |
| 8 import google.appengine.ext.blobstore as blobstore | 8 import google.appengine.ext.blobstore as blobstore |
| 9 from google.appengine.ext.blobstore.blobstore import BlobReferenceProperty | 9 from google.appengine.ext.blobstore.blobstore import BlobReferenceProperty |
| 10 import google.appengine.ext.db as db | 10 import google.appengine.ext.db as db |
| 11 import google.appengine.ext.webapp as webapp | 11 import google.appengine.ext.webapp as webapp |
| 12 import google.appengine.api.files as files | 12 import google.appengine.api.files as files |
| 13 import google.appengine.api.memcache as memcache | 13 import google.appengine.api.memcache as memcache |
| 14 import google.appengine.api.urlfetch as urlfetch | 14 import google.appengine.api.urlfetch as urlfetch |
| 15 except ImportError: | 15 except ImportError: |
| 16 import re | 16 import re |
| 17 from StringIO import StringIO | |
| 17 | 18 |
| 18 FAKE_URL_FETCHER_CONFIGURATION = None | 19 FAKE_URL_FETCHER_CONFIGURATION = None |
| 19 | 20 |
| 20 def ConfigureFakeUrlFetch(configuration): | 21 def ConfigureFakeUrlFetch(configuration): |
| 21 """|configuration| is a dictionary mapping strings to fake urlfetch classes. | 22 """|configuration| is a dictionary mapping strings to fake urlfetch classes. |
| 22 A fake urlfetch class just needs to have a fetch method. The keys of the | 23 A fake urlfetch class just needs to have a fetch method. The keys of the |
| 23 dictionary are treated as regex, and they are matched with the URL to | 24 dictionary are treated as regex, and they are matched with the URL to |
| 24 determine which fake urlfetch is used. | 25 determine which fake urlfetch is used. |
| 25 """ | 26 """ |
| 26 global FAKE_URL_FETCHER_CONFIGURATION | 27 global FAKE_URL_FETCHER_CONFIGURATION |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 60 return _RPC() | 61 return _RPC() |
| 61 | 62 |
| 62 def make_fetch_call(self, rpc, url): | 63 def make_fetch_call(self, rpc, url): |
| 63 rpc.result = self.fetch(url) | 64 rpc.result = self.fetch(url) |
| 64 urlfetch = FakeUrlFetch() | 65 urlfetch = FakeUrlFetch() |
| 65 | 66 |
| 66 class NotImplemented(object): | 67 class NotImplemented(object): |
| 67 def __getattr__(self, attr): | 68 def __getattr__(self, attr): |
| 68 raise NotImplementedError() | 69 raise NotImplementedError() |
| 69 | 70 |
| 70 blobstore = NotImplemented() | 71 BLOBS = {} |
|
not at google - send to devlin
2012/08/22 13:57:58
_BLOBS?
cduvall
2012/08/22 17:20:43
Done.
| |
| 71 files = NotImplemented() | 72 KEY = 1 |
|
not at google - send to devlin
2012/08/22 13:57:58
can you put this on FakeFiles, and call it _next_b
cduvall
2012/08/22 17:20:43
Done.
| |
| 73 class FakeBlobstore(object): | |
| 74 class BlobReader(object): | |
| 75 def __init__(self, blob_key): | |
| 76 self._data = BLOBS[blob_key].getvalue() | |
| 77 | |
| 78 def read(self): | |
| 79 return self._data | |
| 80 | |
| 81 blobstore = FakeBlobstore() | |
| 82 | |
| 83 class FakeStringIO(StringIO): | |
|
not at google - send to devlin
2012/08/22 13:57:58
using just a normal StringIO isn't enough where th
cduvall
2012/08/22 17:20:43
Done.
| |
| 84 def __init__(self, io): | |
| 85 self._io = io | |
| 86 | |
| 87 def __exit__(self, *args): | |
| 88 pass | |
| 89 | |
| 90 def write(self, data): | |
| 91 self._io.write(data) | |
| 92 | |
| 93 def __enter__(self, *args): | |
| 94 return self._io | |
| 95 | |
| 96 class FakeFiles(object): | |
| 97 class blobstore(object): | |
| 98 @staticmethod | |
| 99 def create(): | |
| 100 global KEY | |
| 101 KEY += 1 | |
| 102 return KEY | |
| 103 | |
| 104 @staticmethod | |
| 105 def get_blob_key(filename): | |
| 106 return filename | |
| 107 | |
| 108 def open(self, filename, mode): | |
| 109 BLOBS[filename] = StringIO() | |
| 110 return FakeStringIO(BLOBS[filename]) | |
| 111 | |
| 112 def finalize(self, filename): | |
| 113 pass | |
| 114 | |
| 115 files = FakeFiles() | |
| 72 | 116 |
| 73 class InMemoryMemcache(object): | 117 class InMemoryMemcache(object): |
| 74 """A fake memcache that does nothing. | 118 """A fake memcache that does nothing. |
| 75 """ | 119 """ |
| 76 class Client(object): | 120 class Client(object): |
| 77 def set_multi_async(self, mapping, namespace='', time=0): | 121 def set_multi_async(self, mapping, namespace='', time=0): |
| 78 return | 122 return |
| 79 | 123 |
| 80 def get_multi_async(self, keys, namespace='', time=0): | 124 def get_multi_async(self, keys, namespace='', time=0): |
| 81 return _RPC(result=dict((k, None) for k in keys)) | 125 return _RPC(result=dict((k, None) for k in keys)) |
| 82 | 126 |
| 83 def set(self, key, value, namespace='', time=0): | 127 def set(self, key, value, namespace='', time=0): |
| 84 return | 128 return |
| 85 | 129 |
| 86 def get(self, key, namespace='', time=0): | 130 def get(self, key, namespace='', time=0): |
| 87 return None | 131 return None |
| 88 | 132 |
| 89 def delete(self, key, namespace): | 133 def delete(self, key, namespace): |
| 90 return | 134 return |
| 135 | |
| 91 memcache = InMemoryMemcache() | 136 memcache = InMemoryMemcache() |
| 92 | 137 |
| 93 class webapp(object): | 138 class webapp(object): |
| 94 class RequestHandler(object): | 139 class RequestHandler(object): |
| 95 """A fake webapp.RequestHandler class for Handler to extend. | 140 """A fake webapp.RequestHandler class for Handler to extend. |
| 96 """ | 141 """ |
| 97 def __init__(self, request, response): | 142 def __init__(self, request, response): |
| 98 self.request = request | 143 self.request = request |
| 99 self.response = response | 144 self.response = response |
| 100 | 145 |
| 101 def redirect(self, path): | 146 def redirect(self, path): |
| 102 self.request.path = path | 147 self.request.path = path |
| 103 | 148 |
| 104 class _Db_Result(object): | 149 class _Db_Result(object): |
| 150 def __init__(self, data): | |
| 151 self._data = data | |
| 152 | |
| 153 class _Result(object): | |
| 154 def __init__(self, value): | |
| 155 self.value = value | |
| 156 | |
| 105 def get(self): | 157 def get(self): |
| 106 return [] | 158 return self._Result(self._data) |
| 107 | 159 |
| 160 DB = {} | |
|
not at google - send to devlin
2012/08/22 13:57:58
put on the db or Model class, call _store or somet
cduvall
2012/08/22 17:20:43
Done.
| |
| 108 class db(object): | 161 class db(object): |
| 109 class StringProperty(object): | 162 class StringProperty(object): |
| 110 pass | 163 pass |
| 111 | 164 |
| 112 class Model(object): | 165 class Model(object): |
| 166 def __init__(self, key_='', value=''): | |
| 167 self._key = key_ | |
| 168 self._value = value | |
| 169 | |
| 113 @staticmethod | 170 @staticmethod |
| 114 def gql(*args): | 171 def gql(query, key): |
| 115 return _Db_Result() | 172 return _Db_Result(DB.get(key, None)) |
| 173 | |
| 174 def put(self): | |
| 175 DB[self._key] = self._value | |
| 116 | 176 |
| 117 class BlobReferenceProperty(object): | 177 class BlobReferenceProperty(object): |
| 118 pass | 178 pass |
| OLD | NEW |