Skip to content

Commit b79cd1f

Browse files
committed
black into chap 4 on refactoring
1 parent 018475d commit b79cd1f

File tree

4 files changed

+91
-68
lines changed

4 files changed

+91
-68
lines changed

chapter_philosophy_and_refactoring.asciidoc

Lines changed: 64 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ FAIL: test_can_start_a_list_and_retrieve_it_later
131131
Traceback (most recent call last):
132132
File "...python-tdd-book/functional_tests.py", line 19, in
133133
test_can_start_a_list_and_retrieve_it_later
134-
self.fail('Finish the test!')
134+
self.fail("Finish the test!")
135135
AssertionError: Finish the test!
136136
137137
---------------------------------------------------------------------
@@ -165,8 +165,8 @@ from selenium.webdriver.common.keys import Keys
165165
import time
166166
import unittest
167167
168-
class NewVisitorTest(unittest.TestCase):
169168
169+
class NewVisitorTest(unittest.TestCase):
170170
def setUp(self):
171171
self.browser = webdriver.Firefox()
172172
@@ -176,39 +176,34 @@ class NewVisitorTest(unittest.TestCase):
176176
def test_can_start_a_list_and_retrieve_it_later(self):
177177
# Edith has heard about a cool new online to-do app. She goes
178178
# to check out its homepage
179-
self.browser.get('http://localhost:8000')
179+
self.browser.get("http://localhost:8000")
180180
181181
# She notices the page title and header mention to-do lists
182-
self.assertIn('To-Do', self.browser.title)
183-
header_text = self.browser.find_element(By.TAG_NAME, 'h1').text #<1>
184-
self.assertIn('To-Do', header_text)
182+
self.assertIn("To-Do", self.browser.title)
183+
header_text = self.browser.find_element(By.TAG_NAME, "h1").text # <1>
184+
self.assertIn("To-Do", header_text)
185185
186186
# She is invited to enter a to-do item straight away
187-
inputbox = self.browser.find_element(By.ID, 'id_new_item') #<1>
188-
self.assertEqual(
189-
inputbox.get_attribute('placeholder'),
190-
'Enter a to-do item'
191-
)
187+
inputbox = self.browser.find_element(By.ID, "id_new_item") # <1>
188+
self.assertEqual(inputbox.get_attribute("placeholder"), "Enter a to-do item")
192189
193-
# She types "Buy peacock feathers" into a text box (Edith's hobby
194-
# is tying fly-fishing lures)
195-
inputbox.send_keys('Buy peacock feathers') #<2>
190+
# She types "Buy peacock feathers" into a text box
191+
# (Edith's hobby is tying fly-fishing lures)
192+
inputbox.send_keys("Buy peacock feathers") # <2>
196193
197194
# When she hits enter, the page updates, and now the page lists
198195
# "1: Buy peacock feathers" as an item in a to-do list table
199-
inputbox.send_keys(Keys.ENTER) #<3>
200-
time.sleep(1) #<4>
196+
inputbox.send_keys(Keys.ENTER) # <3>
197+
time.sleep(1) # <4>
201198
202-
table = self.browser.find_element(By.ID, 'id_list_table')
203-
rows = table.find_elements(By.TAG_NAME, 'tr') #<1>
204-
self.assertTrue(
205-
any(row.text == '1: Buy peacock feathers' for row in rows)
206-
)
199+
table = self.browser.find_element(By.ID, "id_list_table")
200+
rows = table.find_elements(By.TAG_NAME, "tr") # <1>
201+
self.assertTrue(any(row.text == "1: Buy peacock feathers" for row in rows))
207202
208-
# There is still a text box inviting her to add another item. She
209-
# enters "Use peacock feathers to make a fly" (Edith is very
210-
# methodical)
211-
self.fail('Finish the test!')
203+
# There is still a text box inviting her to add another item.
204+
# She enters "Use peacock feathers to make a fly"
205+
# (Edith is very methodical)
206+
self.fail("Finish the test!")
212207
213208
# The page updates again, and now shows both items on her list
214209
[...]
@@ -371,14 +366,15 @@ https://docs.djangoproject.com/en/1.11/intro/tutorial03/#write-views-that-actual
371366
Mmmh, syntax-highlighted...much nicer! Now to change our view function:
372367

373368
[role="sourcecode"]
374-
.lists/views.py
369+
.lists/views.py (ch04l002)
375370
====
376371
[source,python]
377372
----
378373
from django.shortcuts import render
379374
375+
380376
def home_page(request):
381-
return render(request, 'home.html')
377+
return render(request, "home.html")
382378
----
383379
====
384380

@@ -395,6 +391,7 @@ NOTE: Templates are a very powerful feature of Django's, and their main
395391
why we use `render` and (later) +render_to&#8203;_string+ rather
396392
than, say, manually reading the file from disk with the built-in `open`.
397393

394+
398395
Let's see if it works:
399396

400397
[subs="specialcharacters,macros,callouts"]
@@ -410,7 +407,7 @@ Traceback (most recent call last):
410407
response = home_page(request) <3>
411408
^^^^^^^^^^^^^^^^^^
412409
File ...python-tdd-book/lists/views.py", line 5, in home_page
413-
return render(request, 'home.html') <4>
410+
return render(request, "home.html") <4>
414411
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
415412
File ".../django/shortcuts.py", line 24, in render
416413
content = loader.render_to_string(template_name, context, request, using=using)
@@ -459,32 +456,32 @@ well. Belt and braces. Open it up and look for a variable called
459456
# Application definition
460457

461458
INSTALLED_APPS = [
462-
'django.contrib.admin',
463-
'django.contrib.auth',
464-
'django.contrib.contenttypes',
465-
'django.contrib.sessions',
466-
'django.contrib.messages',
467-
'django.contrib.staticfiles',
468-
'lists',
459+
"django.contrib.admin",
460+
"django.contrib.auth",
461+
"django.contrib.contenttypes",
462+
"django.contrib.sessions",
463+
"django.contrib.messages",
464+
"django.contrib.staticfiles",
465+
"lists.apps.ListsConfig",
469466
]
470467
----
471468
====
472469
473-
//TODO: the new way of adding it would be lists.apps.ListConfig
474-
475470
476-
You can see there's lots of apps already in there by default. We just need to
477-
add ours, `lists`, to the bottom of the list. Don't forget the trailing
478-
comma--it may not be required, but one day you'll be really annoyed when you
479-
forget it and Python concatenates two strings on different lines...
471+
You can see there's lots of apps already in there by default.
472+
We just need to add ours, using the name `lists.app.ListsConfig`,
473+
to the bottom of the list.
474+
Don't forget the trailing comma--it may not be required,
475+
but one day you'll be really annoyed when you forget it
476+
and Python concatenates two strings on different lines...
480477
481478
Now we can try running the tests again:
482479
483480
[subs="specialcharacters,macros"]
484481
----
485482
$ pass:quotes[*python manage.py test*]
486483
[...]
487-
self.assertTrue(html.endswith('</html>'))
484+
self.assertTrue(html.endswith("</html>"))
488485
AssertionError: False is not true
489486
----
490487
@@ -509,7 +506,7 @@ additional newline (`\n`) at the end. We can get them to pass like this:
509506
====
510507
[source,python]
511508
----
512-
self.assertTrue(html.strip().endswith('</html>'))
509+
self.assertTrue(html.strip().endswith("</html>"))
513510
----
514511
====
515512
@@ -547,8 +544,8 @@ from django.template.loader import render_to_string
547544
def test_home_page_returns_correct_html(self):
548545
request = HttpRequest()
549546
response = home_page(request)
550-
html = response.content.decode('utf8')
551-
expected_html = render_to_string('home.html')
547+
html = response.content.decode("utf8")
548+
expected_html = render_to_string("home.html")
552549
self.assertEqual(html, expected_html)
553550
----
554551
====
@@ -567,15 +564,15 @@ Here's how it looks:
567564
====
568565
[source,python]
569566
----
570-
def test_home_page_returns_correct_html(self):
571-
response = self.client.get('/') #<1>
567+
def test_home_page_returns_correct_html(self):
568+
response = self.client.get("/") # <1>
572569

573-
html = response.content.decode('utf8') #<2>
574-
self.assertTrue(html.startswith('<html>'))
575-
self.assertIn('<title>To-Do lists</title>', html)
576-
self.assertTrue(html.strip().endswith('</html>'))
570+
html = response.content.decode("utf8") # <2>
571+
self.assertTrue(html.startswith("<html>"))
572+
self.assertIn("<title>To-Do lists</title>", html)
573+
self.assertTrue(html.strip().endswith("</html>"))
577574

578-
self.assertTemplateUsed(response, 'home.html') #<3>
575+
self.assertTemplateUsed(response, "home.html") # <3>
579576
----
580577
====
581578
@@ -607,7 +604,7 @@ deliberately break it:
607604
====
608605
[source,python]
609606
----
610-
self.assertTemplateUsed(response, 'wrong.html')
607+
self.assertTemplateUsed(response, "wrong.html")
611608
----
612609
====
613610
@@ -630,11 +627,11 @@ Django Test Client. We've combined two long-winded tests into one!
630627
----
631628
from django.test import TestCase
632629

633-
class HomePageTest(TestCase):
634630

631+
class HomePageTest(TestCase):
635632
def test_uses_home_template(self):
636-
response = self.client.get('/')
637-
self.assertTemplateUsed(response, 'home.html')
633+
response = self.client.get("/")
634+
self.assertTemplateUsed(response, "home.html")
638635
----
639636
====
640637
@@ -671,11 +668,12 @@ On Refactoring
671668
~~~~~~~~~~~~~~
672669
673670
674-
((("unit tests", "refactoring in")))((("refactoring")))That
675-
was an absolutely trivial example of refactoring. But, as Kent Beck puts
676-
it in <<tddbe,'Test-Driven Development: By Example'>>, "Am I recommending that
677-
you actually work this way? No. I'm recommending that you be 'able' to work
678-
this way".
671+
((("unit tests", "refactoring in")))
672+
((("refactoring")))
673+
That was an absolutely trivial example of refactoring.
674+
But, as Kent Beck puts it in <<tddbe,'Test-Driven Development: By Example'>>,
675+
"Am I recommending that you actually work this way? No.
676+
I'm recommending that you be 'able' to work this way".
679677
680678
In fact, as I was writing this my first instinct was to dive in and change the
681679
test first--make it use the `assertTemplateUsed` function straight away;
@@ -808,9 +806,9 @@ empty...
808806
Now what does the FT say?
809807
810808
----
811-
File "functional_tests.py", line 43, in
809+
File "...python-tdd-book/functional_tests.py", line 40, in
812810
test_can_start_a_list_and_retrieve_it_later
813-
any(row.text == '1: Buy peacock feathers' for row in rows)
811+
self.assertTrue(any(row.text == "1: Buy peacock feathers" for row in rows))
814812
AssertionError: False is not true
815813
----
816814
@@ -823,13 +821,13 @@ a custom error message as an argument to most `assertX` methods in `unittest`:
823821
824822
825823
[role="sourcecode"]
826-
.functional_tests.py
824+
.functional_tests.py (ch04l015)
827825
====
828826
[source,python]
829827
----
830828
self.assertTrue(
831-
any(row.text == '1: Buy peacock feathers' for row in rows),
832-
"New to-do item did not appear in table"
829+
any(row.text == "1: Buy peacock feathers" for row in rows),
830+
"New to-do item did not appear in table",
833831
)
834832
----
835833
====

source/blackify-chap.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/bash
2+
set -e
3+
4+
PREV=$1
5+
CHAP=$2
6+
7+
# assumes a git remote local pointing at a local bare repo...
8+
REPO=local
9+
10+
cd $CHAP/superlists
11+
12+
git fetch $REPO
13+
14+
STARTCOMMIT="$(git rev-parse $PREV)"
15+
ENDCOMMIT="$(git rev-parse $CHAP)"
16+
17+
git checkout $CHAP
18+
git reset --hard $REPO/$PREV
19+
20+
git rev-list $STARTCOMMIT^..$ENDCOMMIT| tac | xargs -n1 sh -c 'git co $0 -- . && black . && git commit -am "$(git show -s --format=%B $0)"'
21+
22+
git diff -w $REPO/$CHAP
23+
24+
25+
cd ../..

tests/book_tester.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ def assert_console_output_correct(self, actual, expected, ls=False):
525525
elif line.startswith(' '):
526526
self.assertLineIn(line, actual_lines)
527527
else:
528-
self.assertLineIn(line, [l.strip() for l in actual_lines])
528+
self.assertLineIn(line.rstrip(), [l.strip() for l in actual_lines])
529529

530530
if len(expected_lines) > 4 and '[...' not in expected_fixed:
531531
if expected.type != 'qunit output':

0 commit comments

Comments
 (0)