diff --git a/docs/apA.md b/docs/apA.md
index 7854342..e8bc8c9 100644
--- a/docs/apA.md
+++ b/docs/apA.md
@@ -1,5 +1,5 @@
-# Appendix A
-Concurrency II
+# 附录 A 并发编程 II
+
by Brett L. Schuchert
This appendix supports and amplifies the Concurrency chapter on page 177. It is written as a series of independent topics and you can generally read them in any order. There is some duplication between sections to allow for such reading.
diff --git a/docs/ch9.md b/docs/ch9.md
index d73b2ac..c073487 100644
--- a/docs/ch9.md
+++ b/docs/ch9.md
@@ -6,7 +6,7 @@ Our profession has come a long way in the last ten years. In 1997 no one had hea
I remember writing a C++ program for an embedded real-time system back in the mid-90s. The program was a simple timer with the following signature:
```cpp
- void Timer::ScheduleCommand(Command* theCommand, int milliseconds)
+void Timer::ScheduleCommand(Command* theCommand, int milliseconds)
```
The idea was simple; the execute method of the Command would be executed in a new thread after the specified number of milliseconds. The problem was, how to test it.
@@ -73,70 +73,70 @@ Consider the code from FitNesse in Listing 9-1. These three tests are difficult
Listing 9-1 SerializedPageResponderTest.java
```java
- public void testGetPageHieratchyAsXml() throws Exception
- {
+public void testGetPageHieratchyAsXml() throws Exception
+{
- crawler.addPage(root, PathParser.parse(“PageOne”));
- crawler.addPage(root, PathParser.parse(“PageOne.ChildOne”));
- crawler.addPage(root, PathParser.parse(“PageTwo”));
-
- request.setResource(“root”);
- request.addInput(“type”, “pages”);
- Responder responder = new SerializedPageResponder();
- SimpleResponse response =
- (SimpleResponse) responder.makeResponse(
- new FitNesseContext(root), request);
- String xml = response.getContent();
-
- assertEquals(“text/xml”, response.getContentType());
- assertSubString(“PageOne”, xml);
- assertSubString(“PageTwo”, xml);
- assertSubString(“ChildOne”, xml);
- }
- public void testGetPageHieratchyAsXmlDoesntContainSymbolicLinks()
- throws Exception {
-
- WikiPage pageOne = crawler.addPage(root, PathParser.parse(“PageOne”));
- crawler.addPage(root, PathParser.parse(“PageOne.ChildOne”));
- crawler.addPage(root, PathParser.parse(“PageTwo”));
-
- PageData data = pageOne.getData();
- WikiPageProperties properties = data.getProperties();
- WikiPageProperty symLinks = properties.set(SymbolicPage.PROPERTY_NAME);
- symLinks.set(“SymPage”, ”PageTwo”);
- pageOne.commit(data);
-
- request.setResource(“root”);
- request.addInput(“type”, ”pages”);
- Responder responder = new SerializedPageResponder();
- SimpleResponse response =
- (SimpleResponse) responder.makeResponse(
- new FitNesseContext(root), request);
- String xml = response.getContent();
-
- assertEquals(“text/xml”, response.getContentType());
- assertSubString(“PageOne”, xml);
- assertSubString(“PageTwo”, xml);
- assertSubString(“ChildOne”, xml);
- assertNotSubString(“SymPage”, xml);
- }
-
- public void testGetDataAsHtml() throws Exception
- {
- crawler.addPage(root, PathParser.parse(“TestPageOne”), ”test page”);
-
- request.setResource(“TestPageOne”);
- request.addInput(“type”, ”data”);
- Responder responder = new SerializedPageResponder();
- SimpleResponse response =
- (SimpleResponse) responder.makeResponse(
- new FitNesseContext(root), request);
- String xml = response.getContent();
-
- assertEquals(“text/xml”, response.getContentType());
- assertSubString(“test page”, xml);
- assertSubString(“PageOne”, xml);
+ assertSubString(“PageTwo”, xml);
+ assertSubString(“ChildOne”, xml);
+}
+public void testGetPageHieratchyAsXmlDoesntContainSymbolicLinks()
+throws Exception {
+
+ WikiPage pageOne = crawler.addPage(root, PathParser.parse(“PageOne”));
+ crawler.addPage(root, PathParser.parse(“PageOne.ChildOne”));
+ crawler.addPage(root, PathParser.parse(“PageTwo”));
+
+ PageData data = pageOne.getData();
+ WikiPageProperties properties = data.getProperties();
+ WikiPageProperty symLinks = properties.set(SymbolicPage.PROPERTY_NAME);
+ symLinks.set(“SymPage”, ”PageTwo”);
+ pageOne.commit(data);
+
+ request.setResource(“root”);
+ request.addInput(“type”, ”pages”);
+ Responder responder = new SerializedPageResponder();
+ SimpleResponse response =
+ (SimpleResponse) responder.makeResponse(
+ new FitNesseContext(root), request);
+ String xml = response.getContent();
+
+ assertEquals(“text/xml”, response.getContentType());
+ assertSubString(“PageOne”, xml);
+ assertSubString(“PageTwo”, xml);
+ assertSubString(“ChildOne”, xml);
+ assertNotSubString(“SymPage”, xml);
+}
+
+public void testGetDataAsHtml() throws Exception
+{
+ crawler.addPage(root, PathParser.parse(“TestPageOne”), ”test page”);
+
+ request.setResource(“TestPageOne”);
+ request.addInput(“type”, ”data”);
+ Responder responder = new SerializedPageResponder();
+ SimpleResponse response =
+ (SimpleResponse) responder.makeResponse(
+ new FitNesseContext(root), request);
+ String xml = response.getContent();
+
+ assertEquals(“text/xml”, response.getContentType());
+ assertSubString(“test page”, xml);
+ assertSubString(“PageOne”, “PageTwo”, “ChildOne”
- );
- }
-
- public void testSymbolicLinksAreNotInXmlPageHierarchy() throws Exception {
- WikiPage page = makePage(“PageOne”);
- makePages(“PageOne.ChildOne”, “PageTwo”);
-
- addLinkTo(page, “PageTwo”, “SymPage”);
-
- submitRequest(“root”, “type:pages”);
-
- assertResponseIsXML();
- assertResponseContains(
- “PageOne”, “PageTwo”,
- “ChildOne”
- );
- assertResponseDoesNotContain(“SymPage”);
- }
-
- public void testGetDataAsXml() throws Exception {
- makePageWithContent(“TestPageOne”, “test page”);
-
- submitRequest(“TestPageOne”, “type:data”);
-
- assertResponseIsXML();
- assertResponseContains(“test page”, “PageOne”, “PageTwo”, “ChildOne”
+ );
+}
+
+public void testSymbolicLinksAreNotInXmlPageHierarchy() throws Exception {
+ WikiPage page = makePage(“PageOne”);
+ makePages(“PageOne.ChildOne”, “PageTwo”);
+
+ addLinkTo(page, “PageTwo”, “SymPage”);
+
+ submitRequest(“root”, “type:pages”);
+
+ assertResponseIsXML();
+ assertResponseContains(
+ “PageOne”, “PageTwo”,
+ “ChildOne”
+ );
+ assertResponseDoesNotContain(“SymPage”);
+}
+
+public void testGetDataAsXml() throws Exception {
+ makePageWithContent(“TestPageOne”, “test page”);
+
+ submitRequest(“TestPageOne”, “type:data”);
+
+ assertResponseIsXML();
+ assertResponseContains(“test page”, “PageOne”, “PageTwo”, “ChildOne”
- );
- }
+public void testGetPageHierarchyAsXml() throws Exception {
+ givenPages(“PageOne”, “PageOne.ChildOne”, “PageTwo”);
+
+ whenRequestIsIssued(“root”, “type:pages”);
+
+ thenResponseShouldBeXML();
+}
+public void testGetPageHierarchyHasRightTags() throws Exception {
+ givenPages(“PageOne”, “PageOne.ChildOne”, “PageTwo”);
+
+ whenRequestIsIssued(“root”, “type:pages”);
+
+ thenResponseShouldContain(
+ “PageOne”, “PageTwo”, “ChildOne”
+ );
+}
```
Notice that I have changed the names of the functions to use the common given-when-then5 convention. This makes the tests even easier to read. Unfortunately, splitting the tests as shown results in a lot of duplicate code.
@@ -324,28 +324,28 @@ Perhaps a better rule is that we want to test a single concept in each test func
Listing 9-8
```java
- /**
- * Miscellaneous tests for the addMonths() method.
- */
- public void testAddMonths() {
- SerialDate d1 = SerialDate.createInstance(31, 5, 2004);
-
- SerialDate d2 = SerialDate.addMonths(1, d1);
- assertEquals(30, d2.getDayOfMonth());
- assertEquals(6, d2.getMonth());
- assertEquals(2004, d2.getYYYY());
-
- SerialDate d3 = SerialDate.addMonths(2, d1);
- assertEquals(31, d3.getDayOfMonth());
- assertEquals(7, d3.getMonth());
- assertEquals(2004, d3.getYYYY());
-
- SerialDate d4 = SerialDate.addMonths(1, SerialDate.addMonths(1, d1));
- assertEquals(30, d4.getDayOfMonth());
- assertEquals(7, d4.getMonth());
- assertEquals(2004, d4.getYYYY());
-
- }
+/**
+* Miscellaneous tests for the addMonths() method.
+*/
+public void testAddMonths() {
+ SerialDate d1 = SerialDate.createInstance(31, 5, 2004);
+
+ SerialDate d2 = SerialDate.addMonths(1, d1);
+ assertEquals(30, d2.getDayOfMonth());
+ assertEquals(6, d2.getMonth());
+ assertEquals(2004, d2.getYYYY());
+
+ SerialDate d3 = SerialDate.addMonths(2, d1);
+ assertEquals(31, d3.getDayOfMonth());
+ assertEquals(7, d3.getMonth());
+ assertEquals(2004, d3.getYYYY());
+
+ SerialDate d4 = SerialDate.addMonths(1, SerialDate.addMonths(1, d1));
+ assertEquals(30, d4.getDayOfMonth());
+ assertEquals(7, d4.getMonth());
+ assertEquals(2004, d4.getYYYY());
+
+}
```
The three test functions probably ought to be like this: