Merge lp:~lukasz-czyzykowski/django-configglue/django-1.4 into lp:django-configglue
- django-1.4
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Ricardo Kirkner |
Approved revision: | 108 |
Merged at revision: | 71 |
Proposed branch: | lp:~lukasz-czyzykowski/django-configglue/django-1.4 |
Merge into: | lp:django-configglue |
Diff against target: |
1248 lines (+536/-212) 12 files modified
django_configglue/management/__init__.py (+9/-9) django_configglue/schema.py (+349/-43) django_configglue/tests/helpers.py (+32/-26) django_configglue/tests/settings.py (+3/-3) django_configglue/tests/test_configglue.py (+42/-25) django_configglue/tests/test_settings.py (+36/-28) django_configglue/utils.py (+15/-0) setup.py (+1/-1) testproject/main-12.cfg (+0/-12) testproject/main-14.cfg (+10/-0) testproject/main.cfg (+0/-2) tox.ini (+39/-63) |
To merge this branch: | bzr merge lp:~lukasz-czyzykowski/django-configglue/django-1.4 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ricardo Kirkner | Approve | ||
Review via email: mp+149555@code.launchpad.net |
Commit message
Django 1.4 compatibility.
Description of the change
Overview
========
Updated code to work against Django 1.4. On the way there dropped support for anything earlier than Django 1.3. Schemas for them still exist in the codebase, but are not registered.
- 96. By Łukasz Czyżykowski
-
MP reviews comment updates.
- 97. By Łukasz Czyżykowski
-
Updated setup.py to point to the earliest supported version.
Łukasz Czyżykowski (lukasz-czyzykowski) wrote : | # |
l. 515,581: done
l. 551,562: it has to be done around the settings reload, and before clean up, as otherwise tearDown will fail
l. 573,693: because django 1.3 prints the help message to stderr, 1.4 to stdout so to test on both, we need to mix them
l. 989: done
The 1.4.5 is specified in tox.ini, but updated setup.py to point to the 1.3.7 as the version officially supported.
- 98. By Łukasz Czyżykowski
-
Moved super call to the top of setUp method.
- 99. By Łukasz Czyżykowski
-
Added code to handle django versions before 1.4.5
- 100. By Łukasz Czyżykowski
-
Added testenv for django 1.4.1
- 101. By Łukasz Czyżykowski
-
Fixed super call in setUp.
- 102. By Łukasz Czyżykowski
-
Fixed small issue in assert_
schema_ structure. - 103. By Łukasz Czyżykowski
-
Properly rearranged schemas to include base one for Django 1.3 and 1.4.
- 104. By Łukasz Czyżykowski
-
Fixed test for schma by generating new versions.
- 105. By Łukasz Czyżykowski
-
Fixed test generation test.
- 106. By Łukasz Czyżykowski
-
Fixed test for Django 1.3.*
- 107. By Łukasz Czyżykowski
-
Fixed tests on all version.
- 108. By Łukasz Czyżykowski
-
essage=Changed the way in which version is used in schema building.
Ricardo Kirkner (ricardokirkner) wrote : | # |
Great stuff! Thanks
Preview Diff
1 | === modified file 'django_configglue/management/__init__.py' |
2 | --- django_configglue/management/__init__.py 2012-10-15 14:30:11 +0000 |
3 | +++ django_configglue/management/__init__.py 2013-03-22 14:01:30 +0000 |
4 | @@ -4,16 +4,16 @@ |
5 | # GNU Lesser General Public License version 3 (see the file LICENSE) |
6 | # except where third-party/django/LICENSE applies. |
7 | |
8 | - |
9 | from optparse import BadOptionError |
10 | -import sys |
11 | - |
12 | -import django |
13 | -import django.core.management |
14 | + |
15 | +from django.core import management |
16 | +from django.core.management import ( |
17 | + ManagementUtility, |
18 | + LaxOptionParser as _LaxOptionParser, |
19 | +) |
20 | +from django.conf import settings |
21 | + |
22 | from configglue.glue import schemaconfigglue |
23 | -from django.core.management import ManagementUtility, LaxOptionParser as _LaxOptionParser |
24 | -from django.core.management.base import BaseCommand, handle_default_options |
25 | -from django.conf import settings |
26 | from django_configglue import utils |
27 | |
28 | |
29 | @@ -86,4 +86,4 @@ |
30 | |
31 | |
32 | # We're going to go ahead and use our own ManagementUtility here, thank you. |
33 | -django.core.management.ManagementUtility = GlueManagementUtility |
34 | +management.ManagementUtility = GlueManagementUtility |
35 | |
36 | === modified file 'django_configglue/schema.py' |
37 | --- django_configglue/schema.py 2013-02-20 08:51:07 +0000 |
38 | +++ django_configglue/schema.py 2013-03-22 14:01:30 +0000 |
39 | @@ -13,10 +13,10 @@ |
40 | StringOption, |
41 | TupleOption, |
42 | ) |
43 | -from django import get_version |
44 | +from django import get_version, VERSION |
45 | from django.conf import global_settings |
46 | -from django.conf.project_template import settings as project_settings |
47 | |
48 | +from django_configglue.utils import get_project_settings |
49 | |
50 | # As in django.conf.global_settings: |
51 | # This is defined here as a do-nothing function because we can't import |
52 | @@ -446,23 +446,6 @@ |
53 | help="The profanities that will trigger a validation error in the " |
54 | "'hasNoProfanities' validator. All of these should be in " |
55 | "lowercase") |
56 | - comments_banned_users_group = StringOption(null=True, |
57 | - help="The group ID that designates which users are banned. " |
58 | - "Set to None if you're not using it") |
59 | - comments_moderators_group = StringOption(null=True, |
60 | - help="The group ID that designates which users can moderate " |
61 | - "comments. Set to None if you're not using it") |
62 | - comments_sketchy_users_group = StringOption(null=True, |
63 | - help="The group ID that designates the users whose comments " |
64 | - "should be e-mailed to MANAGERS. Set to None if you're not " |
65 | - "using it") |
66 | - comments_first_few = IntOption(default=0, |
67 | - help="The system will e-mail MANAGERS the first " |
68 | - "COMMENTS_FIRST_FEW comments by each user. Set this to 0 if " |
69 | - "you want to disable it") |
70 | - banned_ips = TupleOption( |
71 | - help="A tuple of IP addresses that have been banned from " |
72 | - "participating in various Django-powered features") |
73 | |
74 | ################## |
75 | # AUTHENTICATION # |
76 | @@ -873,19 +856,16 @@ |
77 | |
78 | |
79 | Django13Base = derivate_django_schema( |
80 | - Django12Schema, exclude=['cache_backend']) |
81 | + Django12Schema, |
82 | + exclude=[ |
83 | + 'cache_backend', |
84 | + ]) |
85 | |
86 | |
87 | class Django13Schema(Django13Base): |
88 | version = '1.3' |
89 | |
90 | - # sections |
91 | class django(Django13Base.django): |
92 | - |
93 | - ################ |
94 | - # CORE # |
95 | - ################ |
96 | - |
97 | # update default value |
98 | languages = ListOption( |
99 | item=TupleOption(length=2), |
100 | @@ -1025,6 +1005,27 @@ |
101 | help="The profanities that will trigger a validation error in the " |
102 | "'hasNoProfanities' validator. All of these should be in " |
103 | "lowercase") |
104 | + comments_banned_users_group = StringOption( |
105 | + null=True, |
106 | + help="The group ID that designates which users are banned. " |
107 | + "Set to None if you're not using it") |
108 | + comments_moderators_group = StringOption( |
109 | + null=True, |
110 | + help="The group ID that designates which users can moderate " |
111 | + "comments. Set to None if you're not using it") |
112 | + comments_sketchy_users_group = StringOption( |
113 | + null=True, |
114 | + help="The group ID that designates the users whose comments " |
115 | + "should be e-mailed to MANAGERS. Set to None if you're not " |
116 | + "using it") |
117 | + comments_first_few = IntOption( |
118 | + default=0, |
119 | + help="The system will e-mail MANAGERS the first " |
120 | + "COMMENTS_FIRST_FEW comments by each user. Set this to 0 if " |
121 | + "you want to disable it") |
122 | + banned_ips = TupleOption( |
123 | + help="A tuple of IP addresses that have been banned from " |
124 | + "participating in various Django-powered features") |
125 | |
126 | ########### |
127 | # LOGGING # |
128 | @@ -1115,11 +1116,50 @@ |
129 | "Examples: 'htttp://foo.com/media/', '/media/'") |
130 | |
131 | |
132 | -class Django14Schema(Django13Schema): |
133 | +class Django136Schema(Django13Schema): |
134 | + version = '1.3.6' |
135 | + |
136 | + class django(Django13Schema.django): |
137 | + |
138 | + allowed_hosts = ListOption( |
139 | + item=StringOption(), |
140 | + help="A list of strings representing the host/domain names " |
141 | + "that this Django site can serve. This is a security " |
142 | + "measure to prevent an attacker from poisoning caches and " |
143 | + "password reset emails with links to malicious hosts by " |
144 | + "submitting requests with a fake HTTP Host header, which is " |
145 | + "possible even under many seemingly-safe webserver " |
146 | + "configurations.") |
147 | + |
148 | + |
149 | +Django14Base = derivate_django_schema( |
150 | + Django13Schema, |
151 | + exclude=[ |
152 | + 'admin_media_prefix', |
153 | + 'ignorable_404_starts', |
154 | + 'ignorable_404_ends', |
155 | + 'banned_ips', |
156 | + 'comments_banned_users_group', |
157 | + 'comments_moderators_group', |
158 | + 'comments_sketchy_users_group', |
159 | + 'comments_first_few', |
160 | + 'database_engine', |
161 | + 'database_host', |
162 | + 'database_name', |
163 | + 'database_options', |
164 | + 'database_password', |
165 | + 'database_port', |
166 | + 'database_user', |
167 | + 'test_database_charset', |
168 | + 'test_database_collation', |
169 | + 'test_database_name', |
170 | + ]) |
171 | + |
172 | + |
173 | +class Django14Schema(Django14Base): |
174 | version = '1.4' |
175 | |
176 | - #sections |
177 | - class django(Django13Schema.django): |
178 | + class django(Django14Base.django): |
179 | |
180 | wsgi_application = StringOption( |
181 | help="The full Python path of the WSGI application object" |
182 | @@ -1140,6 +1180,7 @@ |
183 | |
184 | secure_proxy_ssl_header = TupleOption( |
185 | length=2, |
186 | + default=None, |
187 | help="A tuple representing a HTTP header/value combination " |
188 | "that signifies a request is secure. This controls the " |
189 | "behavior of the request object's is_secure() method.") |
190 | @@ -1153,6 +1194,252 @@ |
191 | "as favicon.ico or robots.txt, or if it gets hammered by " |
192 | "script kiddies.") |
193 | |
194 | + password_hashers = ListOption( |
195 | + item=StringOption(), |
196 | + help="This is a list of hashing algorithm classes that this " |
197 | + "Django installation supports. The first entry in this list " |
198 | + "(that is, settings.PASSWORD_HASHERS[0]) will be used to " |
199 | + "store passwords, and all the other entries are valid " |
200 | + "hashers that can be used to check existing passwords.", |
201 | + default=[ |
202 | + 'django.contrib.auth.hashers.PBKDF2PasswordHasher', |
203 | + 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', |
204 | + 'django.contrib.auth.hashers.BCryptPasswordHasher', |
205 | + 'django.contrib.auth.hashers.SHA1PasswordHasher', |
206 | + 'django.contrib.auth.hashers.MD5PasswordHasher', |
207 | + 'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher', |
208 | + 'django.contrib.auth.hashers.CryptPasswordHasher', |
209 | + ] |
210 | + ) |
211 | + |
212 | + x_frame_options = StringOption( |
213 | + default='SAMEORIGIN', |
214 | + help="The default value for the X-Frame-Options header used " |
215 | + "by XFrameOptionsMiddleware.") |
216 | + |
217 | + use_tz = BoolOption( |
218 | + default=True, |
219 | + help="A boolean that specifies if datetimes will be timezone-aware" |
220 | + " by default or not. If this is set to True, Django will use " |
221 | + "timezone-aware datetimes internally. Otherwise, Django will " |
222 | + "use naive datetimes in local time.") |
223 | + |
224 | + default_exception_reporter_filter = StringOption( |
225 | + default='django.views.debug.SafeExceptionReporterFilter', |
226 | + help="Default exception reporter filter class to be used if none " |
227 | + "has been assigned to the HttpRequest instance yet.") |
228 | + |
229 | + signing_backend = StringOption( |
230 | + default='django.core.signing.TimestampSigner', |
231 | + help="The backend used for signing cookies and other data.") |
232 | + |
233 | + url_validator_user_agent = StringOption( |
234 | + default=("Django/%s (https://www.djangoproject.com)" % |
235 | + get_version()), |
236 | + help="The User-Agent string to use when checking for URL validity " |
237 | + "through the isExistingURL validator") |
238 | + |
239 | + message_storage = StringOption( |
240 | + default='django.contrib.messages.storage.fallback.' |
241 | + 'FallbackStorage', |
242 | + help="Class to be used as messages backend") |
243 | + |
244 | + |
245 | + logging = DictOption( |
246 | + spec={ |
247 | + 'version': IntOption(default=1), |
248 | + 'formatters': DictOption( |
249 | + item=DictOption( |
250 | + spec={ |
251 | + 'format': StringOption(null=True), |
252 | + 'datefmt': StringOption(null=True)})), |
253 | + 'filters': DictOption( |
254 | + item=DictOption( |
255 | + spec={'name': StringOption()})), |
256 | + 'handlers': DictOption( |
257 | + item=DictOption( |
258 | + spec={ |
259 | + 'class': StringOption(fatal=True), |
260 | + 'level': StringOption(), |
261 | + 'formatter': StringOption(), |
262 | + 'filters': StringOption()})), |
263 | + 'loggers': DictOption( |
264 | + item=DictOption( |
265 | + spec={ |
266 | + 'level': StringOption(), |
267 | + 'propagate': BoolOption(), |
268 | + 'filters': ListOption(item=StringOption()), |
269 | + 'handlers': ListOption(item=StringOption()), |
270 | + })), |
271 | + 'root': DictOption( |
272 | + spec={ |
273 | + 'level': StringOption(), |
274 | + 'filters': ListOption(item=StringOption()), |
275 | + 'handlers': ListOption(item=StringOption()), |
276 | + }), |
277 | + 'incremental': BoolOption(default=False), |
278 | + 'disable_existing_loggers': BoolOption(default=False), |
279 | + }, |
280 | + default={ |
281 | + 'version': 1, |
282 | + 'disable_existing_loggers': False, |
283 | + 'filters': { |
284 | + 'require_debug_false': { |
285 | + '()': 'django.utils.log.RequireDebugFalse', |
286 | + } |
287 | + }, |
288 | + 'handlers': { |
289 | + 'mail_admins': { |
290 | + 'level': 'ERROR', |
291 | + 'filters': ['require_debug_false'], |
292 | + 'class': 'django.utils.log.AdminEmailHandler' |
293 | + } |
294 | + }, |
295 | + 'loggers': { |
296 | + 'django.request': { |
297 | + 'handlers': ['mail_admins'], |
298 | + 'level': 'ERROR', |
299 | + 'propagate': True, |
300 | + }, |
301 | + } |
302 | + }, |
303 | + help="The default logging configuration. This sends an email to " |
304 | + "the site admins on every HTTP 500 error. All other records " |
305 | + "are sent to the bit bucket.") |
306 | + |
307 | + template_context_processors = ListOption( |
308 | + item=StringOption(), |
309 | + default=['django.contrib.auth.context_processors.auth', |
310 | + 'django.core.context_processors.debug', |
311 | + 'django.core.context_processors.i18n', |
312 | + 'django.core.context_processors.media', |
313 | + 'django.core.context_processors.static', |
314 | + 'django.core.context_processors.tz', |
315 | + 'django.contrib.messages.context_processors.messages', |
316 | + ], |
317 | + help="List of processors used by RequestContext to populate the " |
318 | + "context. Each one should be a callable that takes the " |
319 | + "request object as its only parameter and returns a " |
320 | + "dictionary to add to the context") |
321 | + |
322 | + languages = ListOption( |
323 | + item=TupleOption(length=2), |
324 | + default=[ |
325 | + ('ar', gettext_noop('Arabic')), |
326 | + ('az', gettext_noop('Azerbaijani')), |
327 | + ('bg', gettext_noop('Bulgarian')), |
328 | + ('bn', gettext_noop('Bengali')), |
329 | + ('bs', gettext_noop('Bosnian')), |
330 | + ('ca', gettext_noop('Catalan')), |
331 | + ('cs', gettext_noop('Czech')), |
332 | + ('cy', gettext_noop('Welsh')), |
333 | + ('da', gettext_noop('Danish')), |
334 | + ('de', gettext_noop('German')), |
335 | + ('el', gettext_noop('Greek')), |
336 | + ('en', gettext_noop('English')), |
337 | + ('en-gb', gettext_noop('British English')), |
338 | + ('eo', gettext_noop('Esperanto')), |
339 | + ('es', gettext_noop('Spanish')), |
340 | + ('es-ar', gettext_noop('Argentinian Spanish')), |
341 | + ('es-mx', gettext_noop('Mexican Spanish')), |
342 | + ('es-ni', gettext_noop('Nicaraguan Spanish')), |
343 | + ('et', gettext_noop('Estonian')), |
344 | + ('eu', gettext_noop('Basque')), |
345 | + ('fa', gettext_noop('Persian')), |
346 | + ('fi', gettext_noop('Finnish')), |
347 | + ('fr', gettext_noop('French')), |
348 | + ('fy-nl', gettext_noop('Frisian')), |
349 | + ('ga', gettext_noop('Irish')), |
350 | + ('gl', gettext_noop('Galician')), |
351 | + ('he', gettext_noop('Hebrew')), |
352 | + ('hi', gettext_noop('Hindi')), |
353 | + ('hr', gettext_noop('Croatian')), |
354 | + ('hu', gettext_noop('Hungarian')), |
355 | + ('id', gettext_noop('Indonesian')), |
356 | + ('is', gettext_noop('Icelandic')), |
357 | + ('it', gettext_noop('Italian')), |
358 | + ('ja', gettext_noop('Japanese')), |
359 | + ('ka', gettext_noop('Georgian')), |
360 | + ('kk', gettext_noop('Kazakh')), |
361 | + ('km', gettext_noop('Khmer')), |
362 | + ('kn', gettext_noop('Kannada')), |
363 | + ('ko', gettext_noop('Korean')), |
364 | + ('lt', gettext_noop('Lithuanian')), |
365 | + ('lv', gettext_noop('Latvian')), |
366 | + ('mk', gettext_noop('Macedonian')), |
367 | + ('ml', gettext_noop('Malayalam')), |
368 | + ('mn', gettext_noop('Mongolian')), |
369 | + ('nb', gettext_noop('Norwegian Bokmal')), |
370 | + ('ne', gettext_noop('Nepali')), |
371 | + ('nl', gettext_noop('Dutch')), |
372 | + ('nn', gettext_noop('Norwegian Nynorsk')), |
373 | + ('pa', gettext_noop('Punjabi')), |
374 | + ('pl', gettext_noop('Polish')), |
375 | + ('pt', gettext_noop('Portuguese')), |
376 | + ('pt-br', gettext_noop('Brazilian Portuguese')), |
377 | + ('ro', gettext_noop('Romanian')), |
378 | + ('ru', gettext_noop('Russian')), |
379 | + ('sk', gettext_noop('Slovak')), |
380 | + ('sl', gettext_noop('Slovenian')), |
381 | + ('sq', gettext_noop('Albanian')), |
382 | + ('sr', gettext_noop('Serbian')), |
383 | + ('sr-latn', gettext_noop('Serbian Latin')), |
384 | + ('sv', gettext_noop('Swedish')), |
385 | + ('sw', gettext_noop('Swahili')), |
386 | + ('ta', gettext_noop('Tamil')), |
387 | + ('te', gettext_noop('Telugu')), |
388 | + ('th', gettext_noop('Thai')), |
389 | + ('tr', gettext_noop('Turkish')), |
390 | + ('tt', gettext_noop('Tatar')), |
391 | + ('uk', gettext_noop('Ukrainian')), |
392 | + ('ur', gettext_noop('Urdu')), |
393 | + ('vi', gettext_noop('Vietnamese')), |
394 | + ('zh-cn', gettext_noop('Simplified Chinese')), |
395 | + ('zh-tw', gettext_noop('Traditional Chinese'))], |
396 | + help="Languages we provide translations for, out of the box. " |
397 | + "The language name should be the utf-8 encoded local name " |
398 | + "for the language") |
399 | + |
400 | + session_cookie_httponly = BoolOption( |
401 | + default=True, |
402 | + help="Whether to use the non-RFC standard htt pOnly flag (IE, " |
403 | + "FF3+, others)") |
404 | + |
405 | + datetime_input_formats = ListOption( |
406 | + item=StringOption(), |
407 | + default=[ |
408 | + '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' |
409 | + '%Y-%m-%d %H:%M:%S.%f', # '2006-10-25 14:30:59.000200' |
410 | + '%Y-%m-%d %H:%M', # '2006-10-25 14:30' |
411 | + '%Y-%m-%d', # '2006-10-25' |
412 | + '%m/%d/%Y %H:%M:%S', # '10/25/2006 14:30:59' |
413 | + '%m/%d/%Y %H:%M:%S.%f', # '10/25/2006 14:30:59.000200' |
414 | + '%m/%d/%Y %H:%M', # '10/25/2006 14:30' |
415 | + '%m/%d/%Y', # '10/25/2006' |
416 | + '%m/%d/%y %H:%M:%S', # '10/25/06 14:30:59' |
417 | + '%m/%d/%y %H:%M:%S.%f', # '10/25/06 14:30:59.000200' |
418 | + '%m/%d/%y %H:%M', # '10/25/06 14:30' |
419 | + '%m/%d/%y', # '10/25/06' |
420 | + ], |
421 | + help="Default formats to be used when parsing dates and times " |
422 | + "from input boxes, in order") |
423 | + |
424 | + |
425 | +class Django144Schema(Django14Schema): |
426 | + version = '1.4.4' |
427 | + |
428 | + class django(Django14Schema.django): |
429 | + |
430 | + allowed_hosts = ListOption( |
431 | + item=StringOption(), |
432 | + help="A list of strings representing the host/domain names " |
433 | + "that this Django site can serve. This is a security " |
434 | + "measure to prevent an attacker from poisoning caches and " |
435 | + "password reset emails with links to malicious hosts by " |
436 | + "submitting requests with a fake HTTP Host header, which is " |
437 | + "possible even under many seemingly-safe webserver " |
438 | + "configurations.") |
439 | + |
440 | |
441 | class DjangoSchemaFactory(object): |
442 | def __init__(self): |
443 | @@ -1172,6 +1459,7 @@ |
444 | return self._schemas[version] |
445 | |
446 | msg = "No schema registered for version %r" % version |
447 | + |
448 | if strict: |
449 | raise ValueError(msg) |
450 | else: |
451 | @@ -1181,10 +1469,14 @@ |
452 | schema = self.build(version) |
453 | return schema |
454 | |
455 | - def build(self, version_string=None, options=None): |
456 | + def build(self, version_string=None, options=None, |
457 | + BaseSchema=BaseDjangoSchema): |
458 | if version_string is None: |
459 | version_string = get_version() |
460 | + |
461 | if options is None: |
462 | + project_settings = get_project_settings() |
463 | + |
464 | options = dict([(name.lower(), value) for (name, value) in |
465 | inspect.getmembers(global_settings) if name.isupper()]) |
466 | project_options = dict([(name.lower(), value) for (name, value) in |
467 | @@ -1197,10 +1489,18 @@ |
468 | |
469 | options.update(project_options) |
470 | |
471 | - class DjangoSchema(Schema): |
472 | + try: |
473 | + base_version = '{0}.{1}'.format(*VERSION[:2]) |
474 | + BaseSchema = self.get(base_version) |
475 | + except ValueError: |
476 | + pass |
477 | + |
478 | + section_base_class = getattr(BaseSchema, 'django', Section) |
479 | + |
480 | + class DjangoSchema(BaseSchema): |
481 | version = version_string |
482 | |
483 | - class django(Section): |
484 | + class django(section_base_class): |
485 | pass |
486 | |
487 | def get_option_type(name, value): |
488 | @@ -1214,8 +1514,18 @@ |
489 | unicode: StringOption, |
490 | } |
491 | if value is None: |
492 | + # Special casing strange value, which by default is None but |
493 | + # should be set to tuple. |
494 | + if name == 'secure_proxy_ssl_header': |
495 | + return TupleOption(name=name, default=None) |
496 | + |
497 | return StringOption(name=name, default=value, null=True) |
498 | else: |
499 | + # Clean up values comming from the project template and having |
500 | + # {{ }} substitutions in them. |
501 | + if name in ('secret_key', 'wsgi_application'): |
502 | + value = '' |
503 | + |
504 | option_type = type_mappings[type(value)] |
505 | kwargs = {'name': name, 'default': value} |
506 | |
507 | @@ -1246,8 +1556,9 @@ |
508 | for name, value in options.items(): |
509 | if name == '__CONFIGGLUE_PARSER__': |
510 | continue |
511 | - option = get_option_type(name, value) |
512 | - setattr(DjangoSchema.django, name, option) |
513 | + if not hasattr(DjangoSchema.django, name): |
514 | + option = get_option_type(name, value) |
515 | + setattr(DjangoSchema.django, name, option) |
516 | |
517 | # register schema for it to be available during next query |
518 | self.register(DjangoSchema, version_string) |
519 | @@ -1256,14 +1567,9 @@ |
520 | |
521 | schemas = DjangoSchemaFactory() |
522 | schemas.register(BaseDjangoSchema) |
523 | -schemas.register(BaseDjangoSchema, '1.0.4') |
524 | -schemas.register(Django11Schema) |
525 | -schemas.register(Django11Schema, '1.1.2') |
526 | -schemas.register(Django11Schema, '1.1.4') |
527 | -schemas.register(Django12Schema) |
528 | -schemas.register(Django12Schema, '1.2.7') |
529 | schemas.register(Django13Schema) |
530 | -for i in range(1, 6): |
531 | - schemas.register(Django13Schema, '1.3.%d' % i) |
532 | +schemas.register(Django136Schema) |
533 | +schemas.register(Django136Schema, '1.3.7') |
534 | schemas.register(Django14Schema) |
535 | -schemas.register(Django14Schema, '1.4.3') |
536 | +schemas.register(Django144Schema) |
537 | +schemas.register(Django144Schema, '1.4.5') |
538 | |
539 | === modified file 'django_configglue/tests/helpers.py' |
540 | --- django_configglue/tests/helpers.py 2011-08-05 16:12:53 +0000 |
541 | +++ django_configglue/tests/helpers.py 2013-03-22 14:01:30 +0000 |
542 | @@ -11,6 +11,10 @@ |
543 | from django.core import management |
544 | from django.conf import settings |
545 | from django.test import TestCase |
546 | +try: |
547 | + from django.utils.functional import empty |
548 | +except ImportError: |
549 | + empty = None |
550 | |
551 | from configglue.schema import ( |
552 | ListOption, |
553 | @@ -23,31 +27,25 @@ |
554 | COMMAND = '' |
555 | |
556 | def setUp(self): |
557 | + super(ConfigGlueDjangoCommandTestCase, self).setUp() |
558 | # disable logging during tests |
559 | self.level = logging.getLogger().level |
560 | logging.disable(logging.ERROR) |
561 | |
562 | config = textwrap.dedent(""" |
563 | [django] |
564 | - database_engine = sqlite3 |
565 | - database_name = :memory: |
566 | installed_apps = django_configglue |
567 | time_zone = Europe/London |
568 | + databases = databases |
569 | + |
570 | + [databases] |
571 | + default = db_default |
572 | + |
573 | + [db_default] |
574 | + engine = django.db.backends.sqlite3 |
575 | + name = :memory: |
576 | """) |
577 | |
578 | - if django.VERSION[:2] > (1, 1): |
579 | - # since 1.2 use multi database settings format |
580 | - config += textwrap.dedent(""" |
581 | - databases = databases |
582 | - |
583 | - [databases] |
584 | - default = db_default |
585 | - |
586 | - [db_default] |
587 | - engine = sqlite3 |
588 | - name = :memory: |
589 | - """) |
590 | - |
591 | self.set_config(config) |
592 | self._DJANGO_SETTINGS_MODULE = self.load_settings() |
593 | |
594 | @@ -60,6 +58,7 @@ |
595 | self._DJANGO_SETTINGS_MODULE) |
596 | |
597 | os.remove('test.cfg') |
598 | + super(ConfigGlueDjangoCommandTestCase, self).tearDown() |
599 | |
600 | def set_config(self, config): |
601 | config_file = open('test.cfg', 'w') |
602 | @@ -68,14 +67,11 @@ |
603 | |
604 | @property |
605 | def wrapped_settings(self): |
606 | - wrapped = '_target' |
607 | - if django.VERSION[:3] > (1, 0, 2): |
608 | - wrapped = '_wrapped' |
609 | # make sure the wrapped object is not None |
610 | # by just querying it for a setting |
611 | getattr(settings, 'DEBUG', False) |
612 | - assert(getattr(settings, wrapped) != None) |
613 | - return wrapped |
614 | + assert(getattr(settings, '_wrapped') is not empty) |
615 | + return '_wrapped' |
616 | |
617 | def load_settings(self, module='django_configglue.tests.settings'): |
618 | old_module = os.environ['DJANGO_SETTINGS_MODULE'] |
619 | @@ -90,8 +86,12 @@ |
620 | 'DATABASE_SUPPORTS_TRANSACTIONS': getattr( |
621 | settings, 'DATABASE_SUPPORTS_TRANSACTIONS'), |
622 | } |
623 | + # save _original_allowed_hosts so that the teardown will work |
624 | + # properly |
625 | + _original_allowed_hosts = getattr( |
626 | + settings, '_original_allowed_hosts', None) |
627 | # force django to reload its settings |
628 | - setattr(settings, self.wrapped_settings, None) |
629 | + setattr(settings, self.wrapped_settings, empty) |
630 | # update settings module for next reload |
631 | os.environ['DJANGO_SETTINGS_MODULE'] = module |
632 | |
633 | @@ -99,6 +99,8 @@ |
634 | for key, value in extra_settings.items(): |
635 | setattr(settings, key, value) |
636 | |
637 | + settings._original_allowed_hosts = _original_allowed_hosts |
638 | + |
639 | if hasattr(self, 'extra_settings'): |
640 | for key, value in self.extra_settings.items(): |
641 | setattr(settings, key, value) |
642 | @@ -119,8 +121,7 @@ |
643 | sys.stdout.seek(0) |
644 | sys.stderr.seek(0) |
645 | |
646 | - self.capture = {'stdout': sys.stdout.read(), |
647 | - 'stderr': sys.stderr.read()} |
648 | + self.output = sys.stdout.read() + sys.stderr.read() |
649 | |
650 | sys.stdout = self._stdout |
651 | sys.stderr = self._stderr |
652 | @@ -135,6 +136,7 @@ |
653 | |
654 | class SchemaHelperTestCase(TestCase): |
655 | def setUp(self): |
656 | + super(SchemaHelperTestCase, self).setUp() |
657 | # disable logging during tests |
658 | self.level = logging.getLogger().level |
659 | logging.disable(logging.ERROR) |
660 | @@ -142,10 +144,11 @@ |
661 | def tearDown(self): |
662 | # re-enable logging |
663 | logging.getLogger().setLevel(self.level) |
664 | + super(SchemaHelperTestCase, self).tearDown() |
665 | |
666 | def assert_schema_structure(self, schema_cls, version, options): |
667 | self.assertTrue(issubclass(schema_cls, Schema)) |
668 | - self.assertEqual(schema_cls.version, 'bogus') |
669 | + self.assertEqual(schema_cls.version, version) |
670 | |
671 | schema = schema_cls() |
672 | |
673 | @@ -187,8 +190,11 @@ |
674 | # django defaults to tuples for options it defines as lists |
675 | if (isinstance(option, (ListOption, TupleOption)) or |
676 | isinstance(expected_option, (ListOption, TupleOption))): |
677 | - self.assertEqual(list(option.default), |
678 | - list(expected_option.default)) |
679 | + if option.default is None: |
680 | + self.assertIsNone(expected_option.default) |
681 | + else: |
682 | + self.assertEqual(list(option.default), |
683 | + list(expected_option.default)) |
684 | else: |
685 | self.assertEqual(option.default, |
686 | expected_option.default) |
687 | |
688 | === modified file 'django_configglue/tests/settings.py' |
689 | --- django_configglue/tests/settings.py 2011-07-19 01:24:06 +0000 |
690 | +++ django_configglue/tests/settings.py 2013-03-22 14:01:30 +0000 |
691 | @@ -10,9 +10,9 @@ |
692 | |
693 | version = DjangoSchema.version |
694 | main_cfg = 'main.cfg' |
695 | -if version >= '1.3': |
696 | +if version >= '1.4': |
697 | + main_cfg = 'main-14.cfg' |
698 | +elif version >= '1.3': |
699 | main_cfg = 'main-13.cfg' |
700 | -elif version >= '1.2': |
701 | - main_cfg = 'main-12.cfg' |
702 | |
703 | configglue(DjangoSchema, [main_cfg, 'test.cfg'], __name__) |
704 | |
705 | === modified file 'django_configglue/tests/test_configglue.py' |
706 | --- django_configglue/tests/test_configglue.py 2013-02-20 08:51:07 +0000 |
707 | +++ django_configglue/tests/test_configglue.py 2013-03-22 14:01:30 +0000 |
708 | @@ -25,7 +25,6 @@ |
709 | ) |
710 | from django.conf import settings |
711 | from django.conf import global_settings |
712 | -from django.conf.project_template import settings as project_settings |
713 | from mock import patch |
714 | |
715 | from django_configglue.management import GlueManagementUtility, LaxOptionParser |
716 | @@ -34,6 +33,7 @@ |
717 | configglue, |
718 | get_django_settings, |
719 | update_settings, |
720 | + get_project_settings, |
721 | ) |
722 | from django_configglue.schema import ( |
723 | BaseDjangoSchema, |
724 | @@ -100,11 +100,11 @@ |
725 | self.assertRaises(ValueError, schemas.get, '1.1.1', strict=True) |
726 | |
727 | def test_schema_versions(self): |
728 | - django_10 = schemas.get('1.0')() |
729 | - django_11 = schemas.get('1.1')() |
730 | - self.assertEqual(django_10.version, '1.0') |
731 | - self.assertEqual(django_11.version, '1.1') |
732 | - self.assertFalse(django_10 is django_11) |
733 | + django_13 = schemas.get('1.3')() |
734 | + django_14 = schemas.get('1.4')() |
735 | + self.assertEqual(django_13.version, '1.3') |
736 | + self.assertEqual(django_14.version, '1.4') |
737 | + self.assertFalse(django_13 is django_14) |
738 | |
739 | def test_register_without_version(self): |
740 | class MySchema(Schema): |
741 | @@ -156,10 +156,10 @@ |
742 | (StringOption, 'foo'), |
743 | ] |
744 | |
745 | - for opt_type, default in data: |
746 | - schema_cls = schemas.build('bogus', {'foo': default}) |
747 | + for i, (opt_type, default) in enumerate(data): |
748 | + schema_cls = schemas.build('bogus.%d' % i, {'foo': default}, Schema) |
749 | # do common checks |
750 | - self.assert_schema_structure(schema_cls, 'bogus', |
751 | + self.assert_schema_structure(schema_cls, 'bogus.%d' % i, |
752 | {'foo': opt_type(name='foo', default=default)}) |
753 | |
754 | def test_schemafactory_build_django(self): |
755 | @@ -231,7 +231,7 @@ |
756 | options = dict([(name.lower(), value) for (name, value) in |
757 | inspect.getmembers(global_settings) if name.isupper()]) |
758 | project_options = dict([(name.lower(), value) for (name, value) in |
759 | - inspect.getmembers(project_settings) if name.isupper()]) |
760 | + inspect.getmembers(get_project_settings()) if name.isupper()]) |
761 | # handle special case of ROOT_URLCONF which depends on the |
762 | # project name |
763 | root_urlconf = project_options['root_urlconf'].replace( |
764 | @@ -353,38 +353,52 @@ |
765 | |
766 | def test_execute_no_args(self): |
767 | self.util.argv = [''] |
768 | - self.assertRaises(SystemExit, self.execute) |
769 | + try: |
770 | + self.execute() |
771 | + except SystemExit: |
772 | + pass |
773 | self.assertTrue( |
774 | "Type '%s help <subcommand>' for help" % (self.util.prog_name,) in |
775 | - self.capture['stderr']) |
776 | + self.output) |
777 | |
778 | - def test_execute_help(self): |
779 | + @patch('sys.stdout') |
780 | + def test_execute_help(self, mock_stdout): |
781 | + mock_stdout.isatty.return_value = False |
782 | self.util.argv = ['', 'help'] |
783 | - self.assertRaises(SystemExit, self.execute) |
784 | - self.assertTrue(self.util.main_help_text() in self.capture['stderr']) |
785 | + try: |
786 | + self.execute() |
787 | + except SystemExit: |
788 | + # In earlier versions than 1.4, help was raising SystemExit |
789 | + pass |
790 | + self.assertTrue(self.util.main_help_text() in self.output) |
791 | |
792 | - def test_execute_help_option(self): |
793 | + @patch('sys.stdout') |
794 | + def test_execute_help_option(self, mock_stdout): |
795 | + mock_stdout.isatty.return_value = False |
796 | self.util.argv = ['', '--help'] |
797 | self.execute() |
798 | - self.assertTrue(self.util.main_help_text() in self.capture['stderr']) |
799 | + self.assertTrue(self.util.main_help_text() in self.output) |
800 | |
801 | def test_execute_help_for_command(self): |
802 | self.util.argv = ['', 'help', 'settings'] |
803 | self.execute() |
804 | - self.assertTrue('Show settings attributes' in self.capture['stdout']) |
805 | + self.assertTrue('Show settings attributes' in self.output) |
806 | |
807 | def test_execute_version(self): |
808 | from django import get_version |
809 | self.util.argv = ['', '--version'] |
810 | self.execute() |
811 | - self.assertTrue(get_version() in self.capture['stdout']) |
812 | + self.assertTrue(get_version() in self.output) |
813 | |
814 | def test_execute(self): |
815 | self.util.argv = ['', 'settings'] |
816 | self.execute() |
817 | - self.assertTrue('Show settings attributes' in self.capture['stdout']) |
818 | - |
819 | - def test_execute_settings_exception(self): |
820 | + self.assertTrue('Show settings attributes' in self.output) |
821 | + |
822 | + @patch('sys.stdout') |
823 | + def test_execute_settings_exception(self, mock_stdout): |
824 | + mock_stdout.isatty.return_value = False |
825 | + |
826 | from django.conf import settings |
827 | wrapped = getattr(settings, self.wrapped_settings) |
828 | old_CONFIGGLUE_PARSER = wrapped.__CONFIGGLUE_PARSER__ |
829 | @@ -392,16 +406,19 @@ |
830 | |
831 | try: |
832 | self.util.argv = ['', 'help'] |
833 | - self.assertRaises(SystemExit, self.execute) |
834 | + try: |
835 | + self.execute() |
836 | + except SystemExit: |
837 | + pass |
838 | self.assertTrue( |
839 | - self.util.main_help_text() in self.capture['stderr']) |
840 | + self.util.main_help_text() in self.output) |
841 | finally: |
842 | wrapped.__CONFIGGLUE_PARSER__ = old_CONFIGGLUE_PARSER |
843 | |
844 | def test_execute_with_schema_options(self): |
845 | self.util.argv = ['', '--django_debug=False', 'help', 'settings'] |
846 | self.execute() |
847 | - self.assertTrue('Show settings attributes' in self.capture['stdout']) |
848 | + self.assertTrue('Show settings attributes' in self.output) |
849 | |
850 | def test_verbosity_is_preserved(self): |
851 | self.util.argv = ['', 'settings', '--verbosity=2'] |
852 | |
853 | === modified file 'django_configglue/tests/test_settings.py' |
854 | --- django_configglue/tests/test_settings.py 2012-10-15 14:21:03 +0000 |
855 | +++ django_configglue/tests/test_settings.py 2013-03-22 14:01:30 +0000 |
856 | @@ -23,30 +23,27 @@ |
857 | |
858 | def test_no_args(self): |
859 | self.call_command() |
860 | - self.assertTrue(self.capture['stdout'].startswith('Usage: ')) |
861 | + self.assertTrue(self.output.startswith('Usage: ')) |
862 | |
863 | def test_get(self): |
864 | self.call_command('installed_apps') |
865 | expected_output = "INSTALLED_APPS = ['django_configglue']" |
866 | - self.assertEqual(self.capture['stdout'].strip(), expected_output) |
867 | + self.assertEqual(self.output.strip(), expected_output) |
868 | |
869 | def test_get_not_found(self): |
870 | self.call_command('bogus') |
871 | expected_output = "setting BOGUS not found" |
872 | - self.assertEqual(self.capture['stdout'].strip(), expected_output) |
873 | + self.assertEqual(self.output.strip(), expected_output) |
874 | |
875 | def test_show(self): |
876 | expected_values = [ |
877 | + 'SITE_ID = 1', |
878 | + "SETTINGS_MODULE = 'django_configglue.tests.settings'", |
879 | "ROOT_URLCONF = 'urls'", |
880 | - "SITE_ID = 1", |
881 | - "SETTINGS_MODULE = 'django_configglue.tests.settings'", |
882 | "SETTINGS_ENCODING = '%s'" % SETTINGS_ENCODING, |
883 | ] |
884 | - django_version = django.VERSION[:2] |
885 | - if django_version == (1, 1): |
886 | - expected_values.append("DATABASE_SUPPORTS_TRANSACTIONS = True") |
887 | self.call_command(show_current=True) |
888 | - output_lines = self.capture['stdout'].strip().split('\n') |
889 | + output_lines = self.output.strip().split('\n') |
890 | self.assertEqual(set(expected_values), set(output_lines)) |
891 | |
892 | def test_show_global(self): |
893 | @@ -55,7 +52,7 @@ |
894 | dir(settings) if self.is_setting(key)]) |
895 | # process output into dictionary |
896 | items = map(lambda x: x.split(' = '), |
897 | - self.capture['stdout'].strip().split('\n')) |
898 | + self.output.strip().split('\n')) |
899 | items = map(lambda x: (x[0].strip(), eval(x[1].strip())), |
900 | (t for t in items if self.is_setting(t[0]))) |
901 | output = dict(items) |
902 | @@ -66,12 +63,12 @@ |
903 | self.call_command('time_zone', locate=True) |
904 | location = os.path.join(os.path.realpath(os.path.curdir), 'test.cfg') |
905 | expected_output = "setting TIME_ZONE last defined in '%s'" % location |
906 | - self.assertEqual(self.capture['stdout'].strip(), expected_output) |
907 | + self.assertEqual(self.output.strip(), expected_output) |
908 | |
909 | def test_locate_setting_not_found(self): |
910 | self.call_command('bogus', locate=True) |
911 | expected_output = 'setting BOGUS not found' |
912 | - self.assertEqual(self.capture['stdout'].strip(), expected_output) |
913 | + self.assertEqual(self.output.strip(), expected_output) |
914 | |
915 | def test_locate_setting_no_configglue_parser(self): |
916 | wrapped = getattr(settings, self.wrapped_settings) |
917 | @@ -84,7 +81,7 @@ |
918 | locals(), ['']) |
919 | location = os.path.realpath(mod.__file__) |
920 | expected_output = "setting TIME_ZONE last defined in %r" % location |
921 | - self.assertEqual(self.capture['stdout'].strip(), expected_output) |
922 | + self.assertEqual(self.output.strip(), expected_output) |
923 | finally: |
924 | wrapped.__CONFIGGLUE_PARSER__ = old_CONFIGGLUE_PARSER |
925 | |
926 | @@ -96,7 +93,7 @@ |
927 | try: |
928 | self.call_command('bogus', locate=True) |
929 | expected_output = 'setting BOGUS not found' |
930 | - self.assertEqual(self.capture['stdout'].strip(), expected_output) |
931 | + self.assertEqual(self.output.strip(), expected_output) |
932 | finally: |
933 | wrapped.__CONFIGGLUE_PARSER__ = old_CONFIGGLUE_PARSER |
934 | |
935 | @@ -115,10 +112,11 @@ |
936 | class GeneratedSettingsTestCase(ConfigGlueDjangoCommandTestCase, |
937 | SchemaHelperTestCase): |
938 | def setUp(self): |
939 | + super(GeneratedSettingsTestCase, self).setUp() |
940 | self.expected_schema = schemas.get( |
941 | django.get_version(), strict=True)() |
942 | - |
943 | - mock_get_version = Mock(return_value='foo') |
944 | + self.version = '.'.join(django.get_version().split('.')[:2]) + '.foo' |
945 | + mock_get_version = Mock(return_value=self.version) |
946 | self.patch_get_version = patch( |
947 | 'django_configglue.tests.settings.django.get_version', |
948 | mock_get_version) |
949 | @@ -127,7 +125,6 @@ |
950 | self.patch_warn = patch( |
951 | 'django_configglue.schema.logging.warn', self.mock_warn) |
952 | self.patch_warn.start() |
953 | - super(GeneratedSettingsTestCase, self).setUp() |
954 | |
955 | def tearDown(self): |
956 | self.patch_get_version.stop() |
957 | @@ -137,22 +134,29 @@ |
958 | def test_generated_schema(self): |
959 | # import here so that the necessary modules can be mocked before |
960 | # being required |
961 | + self.load_settings() |
962 | + |
963 | from django.conf import settings |
964 | schema = settings.__CONFIGGLUE_PARSER__.schema |
965 | |
966 | self.assert_schemas_equal(schema, self.expected_schema) |
967 | self.assertEqual(self.mock_warn.call_args_list, |
968 | - [(("No schema registered for version 'foo'",), {}), |
969 | - (("Dynamically creating schema for version 'foo'",), {})]) |
970 | + [(("No schema registered for version '%s'" % self.version,), |
971 | + {}), |
972 | + (("Dynamically creating schema for version '%s'" % self.version,), |
973 | + {})]) |
974 | |
975 | |
976 | class ValidateCommandTestCase(ConfigGlueDjangoCommandTestCase): |
977 | COMMAND = 'settings' |
978 | |
979 | def test_valid_config(self): |
980 | - self.call_command(validate=True) |
981 | + try: |
982 | + self.call_command(validate=True) |
983 | + except SystemExit: |
984 | + pass |
985 | expected_output = 'Settings appear to be fine.' |
986 | - self.assertEqual(self.capture['stdout'].strip(), expected_output) |
987 | + self.assertEqual(self.output.strip(), expected_output) |
988 | |
989 | def test_invalid_config(self): |
990 | config = """ |
991 | @@ -168,7 +172,7 @@ |
992 | except SystemExit, e: |
993 | self.assertEqual(e.code, 1) |
994 | error_msg = 'Error: Settings did not validate against schema.' |
995 | - self.assertTrue(self.capture['stderr'].strip().startswith( |
996 | + self.assertTrue(self.output.strip().startswith( |
997 | error_msg)) |
998 | |
999 | def test_no_configglue_parser(self): |
1000 | @@ -180,7 +184,7 @@ |
1001 | self.call_command(validate=True) |
1002 | expected_output = ('The settings module was not generated by ' |
1003 | 'configglue. Can only validate configglue generated settings.') |
1004 | - self.assertEqual(self.capture['stdout'].strip(), expected_output) |
1005 | + self.assertEqual(self.output.strip(), expected_output) |
1006 | finally: |
1007 | wrapped.__CONFIGGLUE_PARSER__ = old_CONFIGGLUE_PARSER |
1008 | |
1009 | @@ -190,7 +194,7 @@ |
1010 | |
1011 | def test_help(self): |
1012 | self.call_command() |
1013 | - self.assertTrue('--django_debug' in self.capture['stdout']) |
1014 | + self.assertTrue('--django_debug' in self.output) |
1015 | |
1016 | def test_update_settings(self): |
1017 | self.assertTrue(settings.DEBUG) |
1018 | @@ -201,7 +205,7 @@ |
1019 | utility.execute() |
1020 | finally: |
1021 | self.end_capture() |
1022 | - self.assertTrue('False' in self.capture['stdout']) |
1023 | + self.assertTrue('False' in self.output) |
1024 | |
1025 | def test_version_is_printed_once(self): |
1026 | args = ['manage.py', '--version'] |
1027 | @@ -212,14 +216,18 @@ |
1028 | finally: |
1029 | self.end_capture() |
1030 | expected = get_version() |
1031 | - self.assertEqual(1, self.capture['stdout'].count(expected)) |
1032 | + self.assertEqual(1, self.output.count(expected)) |
1033 | |
1034 | def test_noargs_doesnt_error(self): |
1035 | args = ['manage.py'] |
1036 | utility = ManagementUtility(argv=args) |
1037 | self.begin_capture() |
1038 | try: |
1039 | - self.assertRaises(SystemExit, utility.execute) |
1040 | + utility.execute() |
1041 | + except SystemExit: |
1042 | + # Django <= 1.3 uses SystemExit to terminate management |
1043 | + # command |
1044 | + pass |
1045 | finally: |
1046 | self.end_capture() |
1047 | - self.assertFalse('Unknown command' in self.capture['stdout']) |
1048 | + self.assertFalse('Unknown command' in self.output) |
1049 | |
1050 | === modified file 'django_configglue/utils.py' |
1051 | --- django_configglue/utils.py 2011-07-27 00:14:34 +0000 |
1052 | +++ django_configglue/utils.py 2013-03-22 14:01:30 +0000 |
1053 | @@ -1,5 +1,7 @@ |
1054 | # Copyright 2010-2011 Canonical Ltd. This software is licensed under the |
1055 | # GNU Lesser General Public License version 3 (see the file LICENSE). |
1056 | +import imp |
1057 | +import os |
1058 | import sys |
1059 | |
1060 | from configglue.parser import SchemaConfigParser |
1061 | @@ -56,3 +58,16 @@ |
1062 | scp.read(configs) |
1063 | update_settings(scp, target) |
1064 | return scp |
1065 | + |
1066 | + |
1067 | +def get_project_settings(): |
1068 | + """Find project_template settings file, in 1.4 you can't just use import""" |
1069 | + from django import conf |
1070 | + |
1071 | + project_template_dir = os.path.join( |
1072 | + os.path.dirname(conf.__file__), |
1073 | + 'project_template') |
1074 | + for root, dirs, files in os.walk(project_template_dir): |
1075 | + if 'settings.py' in files: |
1076 | + return imp.load_source('project_settings', |
1077 | + os.path.join(root, 'settings.py')) |
1078 | |
1079 | === modified file 'setup.py' |
1080 | --- setup.py 2011-07-27 00:14:34 +0000 |
1081 | +++ setup.py 2013-03-22 14:01:30 +0000 |
1082 | @@ -38,7 +38,7 @@ |
1083 | |
1084 | # content |
1085 | packages=find_packages(exclude=['testproject*']), |
1086 | - install_requires=['django >= 1.0.2-final', 'configglue >= 1.0'], |
1087 | + install_requires=['django >= 1.3.7', 'configglue >= 1.0'], |
1088 | |
1089 | # tests |
1090 | test_suite='testproject.testrunner.runtests', |
1091 | |
1092 | === removed file 'testproject/main-12.cfg' |
1093 | --- testproject/main-12.cfg 2011-04-11 01:06:16 +0000 |
1094 | +++ testproject/main-12.cfg 1970-01-01 00:00:00 +0000 |
1095 | @@ -1,12 +0,0 @@ |
1096 | -[django] |
1097 | -database_engine = sqlite3 |
1098 | -database_name = :memory: |
1099 | -installed_apps = django_configglue |
1100 | -databases = databases |
1101 | - |
1102 | -[databases] |
1103 | -default = db_default |
1104 | - |
1105 | -[db_default] |
1106 | -engine = sqlite3 |
1107 | -name = :memory: |
1108 | |
1109 | === added file 'testproject/main-14.cfg' |
1110 | --- testproject/main-14.cfg 1970-01-01 00:00:00 +0000 |
1111 | +++ testproject/main-14.cfg 2013-03-22 14:01:30 +0000 |
1112 | @@ -0,0 +1,10 @@ |
1113 | +[django] |
1114 | +installed_apps = django_configglue |
1115 | +databases = databases |
1116 | + |
1117 | +[databases] |
1118 | +default = db_default |
1119 | + |
1120 | +[db_default] |
1121 | +engine = django.db.backends.sqlite3 |
1122 | +name = :memory: |
1123 | |
1124 | === modified file 'testproject/main.cfg' |
1125 | --- testproject/main.cfg 2011-04-11 01:06:16 +0000 |
1126 | +++ testproject/main.cfg 2013-03-22 14:01:30 +0000 |
1127 | @@ -1,4 +1,2 @@ |
1128 | [django] |
1129 | -database_engine = sqlite3 |
1130 | -database_name = :memory: |
1131 | installed_apps = django_configglue |
1132 | |
1133 | === modified file 'tox.ini' |
1134 | --- tox.ini 2013-02-20 08:48:09 +0000 |
1135 | +++ tox.ini 2013-03-22 14:01:30 +0000 |
1136 | @@ -1,73 +1,49 @@ |
1137 | [tox] |
1138 | envlist = |
1139 | - py26-django114, |
1140 | - py26-django127, |
1141 | - py26-django135, |
1142 | - py26-django143, |
1143 | - py27-django114, |
1144 | - py27-django127, |
1145 | - py27-django135, |
1146 | - py27-django143, |
1147 | + py26-django137, |
1148 | + py26-django141, |
1149 | + py26-django145, |
1150 | + py27-django137, |
1151 | + py27-django145, |
1152 | configglue-dev |
1153 | |
1154 | [testenv] |
1155 | commands = python setup.py test |
1156 | |
1157 | -[testenv:py26-django114] |
1158 | -basepython = python2.6 |
1159 | -deps = |
1160 | - configglue |
1161 | - mock |
1162 | - django==1.1.4 |
1163 | - |
1164 | -[testenv:py26-django127] |
1165 | -basepython = python2.6 |
1166 | -deps = |
1167 | - configglue |
1168 | - mock |
1169 | - django==1.2.7 |
1170 | - |
1171 | -[testenv:py26-django135] |
1172 | -basepython = python2.6 |
1173 | -deps = |
1174 | - configglue |
1175 | - mock |
1176 | - django==1.3.5 |
1177 | - |
1178 | -[testenv:py26-django143] |
1179 | -basepython = python2.6 |
1180 | -deps = |
1181 | - configglue |
1182 | - mock |
1183 | - django==1.4.3 |
1184 | - |
1185 | -[testenv:py27-django114] |
1186 | -basepython = python2.7 |
1187 | -deps = |
1188 | - configglue |
1189 | - mock |
1190 | - django==1.1.4 |
1191 | - |
1192 | -[testenv:py27-django127] |
1193 | -basepython = python2.7 |
1194 | -deps = |
1195 | - configglue |
1196 | - mock |
1197 | - django==1.2.7 |
1198 | - |
1199 | -[testenv:py27-django135] |
1200 | -basepython = python2.7 |
1201 | -deps = |
1202 | - configglue |
1203 | - mock |
1204 | - django==1.3.5 |
1205 | - |
1206 | -[testenv:py27-django143] |
1207 | -basepython = python2.7 |
1208 | -deps = |
1209 | - configglue |
1210 | - mock |
1211 | - django==1.4.3 |
1212 | +[testenv:py26-django137] |
1213 | +basepython = python2.6 |
1214 | +deps = |
1215 | + configglue |
1216 | + mock |
1217 | + django==1.3.7 |
1218 | + |
1219 | +[testenv:py26-django145] |
1220 | +basepython = python2.6 |
1221 | +deps = |
1222 | + configglue |
1223 | + mock |
1224 | + django==1.4.5 |
1225 | + |
1226 | +[testenv:py26-django141] |
1227 | +basepython = python2.6 |
1228 | +deps = |
1229 | + configglue |
1230 | + mock |
1231 | + django==1.4.1 |
1232 | + |
1233 | +[testenv:py27-django137] |
1234 | +basepython = python2.7 |
1235 | +deps = |
1236 | + configglue |
1237 | + mock |
1238 | + django==1.3.7 |
1239 | + |
1240 | +[testenv:py27-django145] |
1241 | +basepython = python2.7 |
1242 | +deps = |
1243 | + configglue |
1244 | + mock |
1245 | + django==1.4.5 |
1246 | |
1247 | [testenv:configglue-dev] |
1248 | deps = |
l. 515,581: this should probably be at the start of the setUp method
l. 551,562: instead you could use the addCleanup idiom which is nicer than having to store this
l. 573,693: why mixing stdout and stderr?
l. 989: remove commented out code
Also tests are currently not passing when running them like 'python setup.py test'. I have django 1.4.1 as a system package. If tests require a specific django version (like 1.4.5, it should be specified in setup.py).