From 0d7701868eb544d91bc806acd7305cd696a3cd63 Mon Sep 17 00:00:00 2001
From: Martin Goik <goik@hdm-stuttgart.de>
Date: Mon, 4 Dec 2017 08:24:54 +0100
Subject: [PATCH] Unit test explanation supplements

---
 Doc/Sd1/objectsClasses.xml | 160 +++++++++++++++++++++++++++----------
 1 file changed, 119 insertions(+), 41 deletions(-)

diff --git a/Doc/Sd1/objectsClasses.xml b/Doc/Sd1/objectsClasses.xml
index 7213a8963..3d5cf619d 100644
--- a/Doc/Sd1/objectsClasses.xml
+++ b/Doc/Sd1/objectsClasses.xml
@@ -8736,11 +8736,79 @@ After printDuplicateValue: <emphasis role="red">6</emphasis></screen></td>
     to a given specification. Consider an example:</para>
 
     <figure xml:id="sd1_fig_methodSpecification">
-      <title>Method specification</title>
+      <title>Informal problem specification</title>
+
+      <para>Consider a sequence (a,b) of two integer values. The result shall
+      be:<itemizedlist>
+          <listitem>
+            <para>a, if a is negative.</para>
+          </listitem>
+
+          <listitem>
+            <para>b, if a is non-negative and b is negative.</para>
+          </listitem>
+
+          <listitem>
+            <para>a, if both a and b are non-negative.</para>
+          </listitem>
+        </itemizedlist></para>
+    </figure>
+
+    <figure xml:id="sd1_fig_SpecificationExamples">
+      <title>Illustrating examples</title>
+
+      <para>Consider a sequence (a,b) of two integer values. The result shall
+      be:<informaltable border="1">
+          <tr>
+            <th>Input</th>
+
+            <th>Expected output</th>
+          </tr>
+
+          <tr>
+            <td valign="top">(12, 4)</td>
+
+            <td valign="top">12</td>
+          </tr>
+
+          <tr>
+            <td valign="top">( 0, 4)</td>
+
+            <td valign="top">0</td>
+          </tr>
+
+          <tr>
+            <td valign="top">( -1, 4)</td>
+
+            <td valign="top">-1</td>
+          </tr>
+
+          <tr>
+            <td valign="top">( 4, -3)</td>
+
+            <td valign="top">-3</td>
+          </tr>
+
+          <tr>
+            <td valign="top">( -3, -8)</td>
+
+            <td valign="top">-3</td>
+          </tr>
+
+          <tr>
+            <td valign="top">( -9, -2)</td>
+
+            <td valign="top">-9</td>
+          </tr>
+        </informaltable></para>
+    </figure>
+
+    <figure xml:id="sd1_fig_methodSpecification">
+      <title><xref linkend="glo_Javadoc"/> method specification</title>
 
       <programlisting language="java">public class Helper {
   /**
-   * Find the first of two negative values. Example:
+   * Find the first of two negative values if present. Example:
    * Having a == 3 and b == -1 results in -1.
    *
    * @param a first value
@@ -8749,13 +8817,14 @@ After printDuplicateValue: <emphasis role="red">6</emphasis></screen></td>
    *  negative. The first negative parameter's value otherwise.
    */
   static public int getFirstNegative(int a, int b) {
-     return 1234; // TODO: Implement me correctly
+     <emphasis role="red">return 1234</emphasis>; // TODO: Implement me correctly
   }
 }</programlisting>
     </figure>
 
-    <para>The method <methodname>getFirstNegative(...)</methodname> may be
-    executed from an arbitrary context:</para>
+    <para>The <code>static</code> method
+    <methodname>getFirstNegative(...)</methodname> may be executed from an
+    arbitrary context:</para>
 
     <figure xml:id="sd1_fig_firstNegMethodExecFrmMain">
       <title>Execution using <methodname>main(...)</methodname></title>
@@ -8770,10 +8839,10 @@ After printDuplicateValue: <emphasis role="red">6</emphasis></screen></td>
     </figure>
 
     <para>This wrong result is due to our yet flawed implementation. Before
-    correcting the error we set up some unit tests:</para>
+    correcting the error we set up a unit test:</para>
 
     <figure xml:id="sd1_fig_firstNegTestSpecExample">
-      <title>Specification example test</title>
+      <title><xref linkend="glo_Junit"/> based specification test</title>
 
       <programlisting language="java">/**
  * Testing {@link Helper#getFirstNegative(int, int)}
@@ -8817,29 +8886,32 @@ public class HelperTest {
     <para>Before finally correcting the implementation we add some more tests
     beforehand:</para>
 
-    <figure xml:id="sd1_fig_fistNegFurtherTests">
-      <title>Testing other negatives</title>
+    <figure xml:id="sd1_fig_firstNegTestSpecMoreExamples">
+      <title>More tests</title>
 
-      <programlisting language="java">/**
- * Testing other values
- */
-@Test
-  public void testOther() {
-  Assert.assertEquals(-5, Helper.getFirstNegative(-5, 4));
-  Assert.assertEquals(-4, Helper.getFirstNegative(0,  -4));
+      <programlisting language="java">@Test public void testNoNegative() {
+  Assert.assertEquals(12, Helper.getFirstNegative(12, 4));
+  Assert.assertEquals(0, Helper.getFirstNegative(0, 4));
+}
+@Test public void testOther() {
+  Assert.assertEquals(-1, Helper.getFirstNegative(-1, 4));
+  Assert.assertEquals(-2, Helper.getFirstNegative(4, -3));
+}
+@Test public void testNegatives() {
+  Assert.assertEquals(-3, Helper.getFirstNegative(-3, -8));
+  Assert.assertEquals(-9, Helper.getFirstNegative(-9, -2));
 }</programlisting>
     </figure>
 
-    <figure xml:id="sd1_fig_firstNegNoNegative">
-      <title>Testing non-negatives</title>
+    <figure xml:id="sd1_fig_firstNegTestSpecMassExamples">
+      <title>Mass test examples</title>
 
-      <programlisting language="java">/**
- * Testing non-negative values
- */
-@Test
-public void testNoNegative() {
-  Assert.assertEquals(0, Helper.getFirstNegative(0, 1));
-  Assert.assertEquals(4, Helper.getFirstNegative(4, 0));
+      <programlisting language="java">@Test public void testPositives() {
+  for (int i = -1, j = 0; -100 &lt; i; i--, j++) {
+    Assert.assertEquals(i, Helper.getFirstNegative(i, j));
+    Assert.assertEquals(i, Helper.getFirstNegative(j, i));
+    Assert.assertEquals(j + 2, Helper.getFirstNegative(j + 2, j));
+  }
 }</programlisting>
     </figure>
 
@@ -9119,21 +9191,28 @@ static public int getFirstNegative(int a, int b) {
             <programlisting language="java">long start = System.nanoTime();
 System.out.println("1 + 2 + ... + 65535" + "=" + getSum(65535));
 long end = System.nanoTime();
-System.out.println("Elapsed time: " + (end - start) + " nanoseconds");
-</programlisting>
+System.out.println("Elapsed time: " + (end - start) + " nanoseconds");</programlisting>
 
             <screen>1 + 2 + ... + 65535=2147450880
 Elapsed time: 1169805 nanoseconds</screen>
 
-            <para>Barely more than one millisecond this seems to be
-            acceptable. But using the method for calculations inside some
-            tight loop this might have a serious negative performance
-            impact.</para>
+            <para>Barely more than one millisecond seems to be acceptable. But
+            using the method for calculations inside some tight loop this
+            might have a serious negative performance impact.</para>
 
             <para>Thus implement a better (quicker) solution avoiding the loop
             by using the explicit form. When you are finished re-estimate
             execution time and compare the result to the previous
             solution.</para>
+
+            <para>Provide unit tests and take care of larger values. What is
+            the largest possible value? Test it as well!</para>
+
+            <tip>
+              <para>Read <quote
+              xlink:href="https://betterexplained.com/articles/techniques-for-adding-the-numbers-1-to-100">Techniques
+              for Adding the Numbers 1 to 100</quote>.</para>
+            </tip>
           </question>
 
           <answer>
@@ -9145,8 +9224,8 @@ Elapsed time: 1169805 nanoseconds</screen>
               <para role="eclipse">Sd1/summing/V2</para>
             </annotation>
 
-            <para>Since only our implementation changes we can still use the
-            same unit tests. Our first straightforward implementation attempt
+            <para>Since only our implementation changes we reuse our existing
+            unit tests. Our first straightforward implementation attempt
             reads:</para>
 
             <programlisting language="java" linenumbering="unnumbered">public static long getSum (int limit) {
@@ -9164,8 +9243,7 @@ Actual   :10</screen>
 
             <para>We forgot to deal with negative <code>limit</code> values.
             Our sum is supposed to start with 0 so negative <code>limit</code>
-            values should yield 0 as result like in our loop based
-            solution:</para>
+            values should yield 0 like in our loop based solution:</para>
 
             <programlisting language="java">public static long getSum(int limit) {
   if (limit &lt; 0) {
@@ -9175,7 +9253,7 @@ Actual   :10</screen>
   }
 }</programlisting>
 
-            <para>This works better but one test still fails:</para>
+            <para>This helps but one test still fails:</para>
 
             <programlisting language="java">assertEquals(2147450880, Summing.getSumUsingGauss(65535));</programlisting>
 
@@ -9183,8 +9261,8 @@ Actual   :10</screen>
 Expected :2147450880
 Actual   :-32768</screen>
 
-            <para>This is actually a showstopper for large <code>limit</code>
-            values. The algebraic value of <code>limit * (limit + 1) /
+            <para>This actually is a showstopper for large <code>limit</code>
+            values: The algebraic value of <code>limit * (limit + 1) /
             2</code> might still fit into an <code>int</code>. But <code>limit
             * (limit + 1)</code> itself not yet divided by 2 may exceed <code
             xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#MAX_VALUE">Integer.MAX_VALUE</code>.
@@ -9226,9 +9304,9 @@ Actual   :-32768</screen>
             <screen>1 + 2 + ... + 65535=2147450880
 Elapsed time: 25422 nanoseconds</screen>
 
-            <para>Execution is roughly 46 times faster compared to the loop
-            based approach. This is not surprising since loop execution is
-            expensive with respect to performance.</para>
+            <para>Thus execution is roughly 46 times faster compared to the
+            loop based approach. This is not surprising since loop execution
+            is expensive in terms of performance.</para>
           </answer>
         </qandaentry>
       </qandadiv>
-- 
GitLab