Sfoglia il codice sorgente

Merge pull request #666 from exercism/hello-world

Updates now that two-fer is part of the track!
FridaTveit 9 anni fa
parent
commit
83bf9111cf

exercises/clock/HINT.md → exercises/clock/HINTS.md Vedi File


+ 0
- 49
exercises/hello-world/GETTING_STARTED.md Vedi File

@@ -1,49 +0,0 @@
1
-----
2
-# Quick Start Guide
3
-
4
-This guide picks-up where [Running the Tests (in Java)](http://exercism.io/languages/java/tests)
5
-left off.  If you haven't reviewed those instructions, do so now.
6
-
7
-Need more information?  A **step-by-step tutorial** is available in this directory at TUTORIAL.md or you can read 
8
-the [HTML version](https://github.com/exercism/java/blob/master/exercises/hello-world/TUTORIAL.md).
9
-
10
-The following instructions work equally well on Windows, Mac OS X and Linux.
11
-
12
-## Solve "Hello World"
13
-
14
-Try writing a solution that passes one test at a time, running Gradle each time:
15
-
16
-
17
-```
18
-$ gradle test
19
-```
20
-
21
-## Iterate through the tests
22
-
23
-After your first test passes, iterate on your solution, testing after each change.
24
-
25
-## All the tests pass?  Submit your solution!
26
-
27
-With a working solution that we've reviewed, we're ready to submit it to
28
-exercism.io.
29
-
30
-```
31
-$ exercism submit src/main/java/HelloWorld.java
32
-```
33
-
34
-## Next Steps
35
-
36
-From here, there are a number of paths you can take.
37
-
38
-1. Move on to the next exercise
39
-2. Review (and comment on) others' submissions to this exercise
40
-3. Submit another iteration
41
-4. Contribute to Exercism
42
-
43
-
44
-We sincerely hope you learn and enjoy being part of this community.  If at any time you need assistance
45
-do not hesitate to ask for help:
46
-
47
-http://exercism.io/languages/java/help
48
-
49
-Cheers!

+ 0
- 7
exercises/hello-world/HINT.md Vedi File

@@ -1,7 +0,0 @@
1
-The default implementation for this exercise uses an [exception](https://docs.oracle.com/javase/tutorial/essential/exceptions/) 
2
-which will cause the test to fail with the provided error message.
3
-This particular exception type, [UnsupportedOperationException](http://docs.oracle.com/javase/8/docs/api/?java/lang/UnsupportedOperationException.html), 
4
-is commonly thrown to alert developers that a method has not yet been implemented.
5
-Throwing exceptions in this manner means the tests will compile but not pass right away.
6
-
7
-To make the test pass you need to remove the line which throws the exception and replace it with your implementation of the method.

+ 4
- 0
exercises/hello-world/HINTS.md Vedi File

@@ -0,0 +1,4 @@
1
+Since this is your first Java exercise, we've included a detailed TUTORIAL.md
2
+file that guides you through your solution. Check it out for tips and
3
+assistance!
4
+

+ 113
- 362
exercises/hello-world/TUTORIAL.md Vedi File

@@ -1,39 +1,42 @@
1
-NOTE: You can also view the HTML version of this file here:
2
-https://github.com/exercism/java/blob/master/exercises/hello-world/TUTORIAL.md
1
+# Table of Contents
3 2
 
3
+* [Introduction](#introduction)
4
+* [Exercise Structure](#exercise-structure)
4 5
 * [Solving "Hello, World!"](#solving-hello-world)
5
- * [Reading Gradle output](#reading-gradle-output)
6
- * [Fixing the first failing test](#fixing-the-first-failing-test)
7
- * [Enabling and fixing the second test](#enabling-and-fixing-the-second-test)
8
- * [Enabling the last test](#enabling-the-last-test)
9
- * [Refactoring](#refactoring)
10 6
 * [Submitting your first iteration](#submitting-your-first-iteration)
11 7
 * [Next Steps](#next-steps)
12
- * [Review (and comment on) others' submissions to this exercise](#review-and-comment-on-others-submissions-to-this-exercise)
13
- * [Extend an exercise](#extend-an-exercise)
14 8
 
15
-----
16
-
17
-# Solving "Hello, World!"
9
+# Introduction
18 10
 
19 11
 Welcome to the first exercise on the Java track!
20 12
 
21
-This is a step-by-step guide to solving this exercise.
13
+This document is a step-by-step guide to solving this exercise. The
14
+instructions should work equally well on Windows, Mac OS X and Linux.
22 15
 
23
-Each exercise comes with a set of tests.  The first pass through the
24
-exercise is about getting all of the tests to pass, one at a time.
16
+Even if you are already familiar with Java basics, stepping through this guide
17
+may be helpful as it will help you understand the output from the tool, Gradle,
18
+that we use to compile and test our code, as well as introduce some of the
19
+patterns common to all exercises in this track.
25 20
 
26
-If you have not installed the Java Development Kit and Gradle, you must do
27
-so now.  For help with this, see: http://exercism.io/languages/java/installing
21
+# Exercise Structure
28 22
 
29
-----
23
+When you fetch a new Java exercise, you will receive:
30 24
 
31
-This guide picks-up where [Running the Tests (in Java)](http://exercism.io/languages/java/tests)
32
-left off.  If you haven't reviewed those instructions, do so now.
25
+* __one or more test files__ (always). These live in the `src/test/java`
26
+directory and define a set of tests that our solution must satisfy before we
27
+can safely declare that it is working.
28
+* __one or more starter files__ (initially). If provided, these live in the
29
+`src/main/java` directory and define shells of the classes you will need
30
+in order to solve the current problem.
33 31
 
34
-The following instructions work equally well on Windows, Mac OS X and Linux.
32
+# Solving "Hello, World!"
35 33
 
36
-## Reading Gradle output
34
+Before proceeding any further, make sure you have completed the required setup
35
+steps described by the links below:
36
+* [Installing Java](http://exercism.io/languages/java/installing);
37
+* [Running the Tests (in Java)](http://exercism.io/languages/java/tests).
38
+
39
+## Step 1: Run the tests against the starter solution
37 40
 
38 41
 Use Gradle to run the tests:
39 42
 
@@ -51,8 +54,8 @@ This command does a lot and displays a bunch of stuff.  Let's break it down...
51 54
 
52 55
 Each line that begins with a colon (like `:compileJava`) is Gradle telling
53 56
 us that it's starting that task.  The first three tasks are about compiling
54
-the source code of our *solution*. We've done you a favor and included just
55
-enough code for the solution that it compiles.
57
+the source code of our _solution_. This exercise contains starter files with
58
+just enough code for the solution to compile without requiring modification.
56 59
 
57 60
 When a task is successful, it generally does not output anything.  This is
58 61
 why `:compileJava` and `:classes` do not produce any additional output.
@@ -60,7 +63,7 @@ why `:compileJava` and `:classes` do not produce any additional output.
60 63
 
61 64
 So far, so good...
62 65
 
63
-The next three tasks are about compiling source code of the *tests*.
66
+The next three tasks are about compiling source code of the _tests_.
64 67
 
65 68
 ```
66 69
 :compileTestJava
@@ -74,34 +77,19 @@ running the task you asked it to: executing the tests against the solution.
74 77
 ```
75 78
 :test
76 79
 
77
-HelloWorldTest > helloSampleName FAILED
78
-    java.lang.UnsupportedOperationException: Delete this statement and write your own implementation.
79
-        at HelloWorld.hello(HelloWorld.java:3)
80
-        at HelloWorldTest.helloSampleName(HelloWorldTest.java:22)
81
-
82
-HelloWorldTest > helloNoName FAILED
83
-    java.lang.UnsupportedOperationException: Delete this statement and write your own implementation.
84
-        at HelloWorld.hello(HelloWorld.java:3)
85
-        at HelloWorldTest.helloNoName(HelloWorldTest.java:11)
86
-
87
-HelloWorldTest > emptyStringIsComparedByValue FAILED
88
-    java.lang.UnsupportedOperationException: Delete this statement and write your own implementation.
89
-        at HelloWorld.hello(HelloWorld.java:3)
90
-        at HelloWorldTest.emptyStringIsComparedByValue(HelloWorldTest.java:17)
91
-
92
-HelloWorldTest > helloAnotherSampleName FAILED
80
+GreeterTest > testThatGreeterReturnsTheCorrectGreeting FAILED
93 81
     java.lang.UnsupportedOperationException: Delete this statement and write your own implementation.
94
-        at HelloWorld.hello(HelloWorld.java:3)
95
-        at HelloWorldTest.helloAnotherSampleName(HelloWorldTest.java:27)
82
+        at getGreeting(Greeter.java:4)
83
+        at GreeterTest.testThatGreeterReturnsTheCorrectGreeting(GreeterTest.java:9)
96 84
 
97
-4 tests completed, 4 failed
85
+1 tests completed, 1 failed
98 86
 :test FAILED
99 87
 
100 88
 FAILURE: Build failed with an exception.
101 89
 
102 90
 * What went wrong:
103 91
 Execution failed for task ':test'.
104
-> There were failing tests. See the report at: file:///home/logan/hello-world/build/reports/tests/index.html
92
+> There were failing tests. See the report at: file:///home/<username>/hello-world/build/reports/tests/index.html
105 93
 
106 94
 * Try:
107 95
 Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
@@ -111,353 +99,140 @@ BUILD FAILED
111 99
 Total time: 12.361 secs
112 100
 ```
113 101
 
114
-Seeing the word "fail" TEN TIMES might give you the impression you've done
115
-something horribly wrong.  You haven't.  It's a whole lot of noise over
116
-a few tests not passing.
102
+Seeing the word "FAILED" might give you the impression you've done
103
+something wrong.  You haven't.  This output is just a very verbose way of
104
+telling us that the included test did not pass. This is expected - we haven't
105
+written any code to help it pass yet!
117 106
 
118 107
 Let's focus in on the important bits:
119 108
 
120 109
 ```
121
-HelloWorldTest > helloSampleName FAILED
110
+GreeterTest > testThatGreeterReturnsTheCorrectGreeting FAILED
122 111
     java.lang.UnsupportedOperationException: Delete this statement and write your own implementation.
123 112
 ```
124 113
 
125
-...is read: "Within the test class named `HelloWorldTest`, the test method
126
-`helloSampleName` did not pass because an `UnsupportedOperationException` was thrown with the message
127
-`Delete this statement and write your own implementation.`."
114
+...is read: "Within the test class named `GreeterTest`, the test method
115
+`testThatGreeterReturnsTheCorrectGreeting` did not pass because an
116
+`UnsupportedOperationException` was thrown with the message `Delete this
117
+statement and write your own implementation.`."
128 118
 
129
-The next line of the stack trace tells us where the exception was thrown:
119
+The next line of the [stack trace](https://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors)
120
+tells us where this `UnsupportedOperationException` was thrown:
130 121
 
131 122
 ```
132
-        at HelloWorld.hello(HelloWorld.java:3)
123
+        at getGreeting(Greeter.java:4)
133 124
 ```
134 125
 
135
-Looks like it was on line 3 in the HelloWorld file.
126
+Looks like it was on line 4 in the `Greeter.java` file. Let's update that line
127
+as instructed, and try running the tests again.
136 128
 
137
-We should remove this line from our `HelloWorld.java` file.
129
+## Step 2: Replace the `UnsupportedOperationException` 
138 130
 
139
-In your favorite text editor, open `src/main/java/HelloWorld.java`.
131
+In your favorite text editor, open `src/main/java/Greeter.java`. You should
132
+find the source of the exception encountered above on line 4:
140 133
 
141
-Delete the contents of that line and replace it with the following:
142 134
 ```java
143
-return null;
144
-```
145
-Now you can run `gradle test` again.
146
-
147
-You should see a new error this time, don't worry though, you're making progress.
148
-
149
-```
150
-HelloWorldTest > helloNoName FAILED
151
-    java.lang.AssertionError: expected:<Hello, World!> but was:<null>
152
-```
153
-...is read: "Within the test class named HelloWorldTest, 
154
-the test method helloNoName did not pass because the solution did not satisfy an assertion. 
155
-Apparently, we expected to see the string 'Hello, World!' but the value null was returned instead.
156
-
157
-The last line of the stack trace tells us exactly where this unsatisfied assertion lives:
158
-
159
-```
160
-        at HelloWorldTest.helloNoName(HelloWorldTest.java:10)
135
+throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
161 136
 ```
162
-Looks like the crime was discovered on line 10 in the test file.
163 137
 
164
-Knowing these two facts,
138
+[`Exception`s](https://docs.oracle.com/javase/tutorial/essential/exceptions/)
139
+are often used in Java to draw the attention of a developer when something goes
140
+wrong. In our case, nothing is wrong per se; we just haven't written our
141
+solution yet! The use of an
142
+[`UnsupportedOperationException`](http://docs.oracle.com/javase/8/docs/api/?java/lang/UnsupportedOperationException.html)
143
+in this situation is designed to remind us of exactly this fact. It effectively
144
+says: "Your Code Goes Here!".
165 145
 
166
-1. The return value was not what was expected, and
167
-2. The failure was on line 10 of the test,
168
-
169
-We can turn this failure into success.
170
-
171
-
172
-## Fixing the first test
173
-
174
-Open `src/test/java/HelloWorldTest.java`
175
-and go to line 10.
146
+Delete the contents of line 4 and replace it with the following:
176 147
 
177 148
 ```java
178
-assertEquals("Hello, World!", HelloWorld.hello(""));
149
+return null;
179 150
 ```
180 151
 
181
-The test is expecting that `hello()`, when given an empty string (`""`),
182
-returns "Hello, World!".  Instead, `hello()` is returning `null`.
183
-Let's fix that.
184
-
185
-Open `src/main/java/HelloWorld.java`.
186
-
187
-```java
188
-public class HelloWorld {
189
-  public static String hello(String name) {
190
-    return null;
191
-  }
192
-}
193
-```
152
+Now run `gradle test` again.
194 153
 
195
-Let's change that to return the expected string:
154
+You should see a new error this time. Don't worry though, that still
155
+represents forward progress!
196 156
 
197
-```java
198
-public class HelloWorld {
199
-  public static String hello(String name) {
200
-    return "Hello, World!";
201
-  }
202
-}
203 157
 ```
204
-
205
-Save the file and run the tests again:
206
-
158
+GreeterTest > testThatGreeterReturnsTheCorrectGreeting FAILED
159
+    java.lang.AssertionError: expected:<Hello, World!> but was:<null>
207 160
 ```
208
-$ gradle test
209
-:compileJava
210
-:processResources UP-TO-DATE
211
-:classes
212
-:compileTestJava
213
-:processTestResources UP-TO-DATE
214
-:testClasses
215
-:test
216
-
217
-HelloWorldTest > helloSampleName FAILED
218
-    org.junit.ComparisonFailure: expected:<Hello, [Alice]!> but was:<Hello, [World]!>
219
-        at org.junit.Assert.assertEquals(Assert.java:115)
220
-        at org.junit.Assert.assertEquals(Assert.java:144)
221
-        at HelloWorldTest.helloSampleName(HelloWorldTest.java:22)
222
-
223
-HelloWorldTest > helloNoName PASSED
224
-
225
-HelloWorldTest > emptyStringIsComparedByValue PASSED
226
-
227
-HelloWorldTest > helloAnotherSampleName FAILED
228
-    org.junit.ComparisonFailure: expected:<Hello, [Bob]!> but was:<Hello, [World]!>
229
-        at org.junit.Assert.assertEquals(Assert.java:115)
230
-        at org.junit.Assert.assertEquals(Assert.java:144)
231
-        at HelloWorldTest.helloAnotherSampleName(HelloWorldTest.java:27)
232
-
233
-4 tests completed, 2 failed
234
-:test FAILED
235 161
 
236
-FAILURE: Build failed with an exception.
162
+...is read: "Within the test class named `GreeterTest`, 
163
+the test method `testThatGreeterReturnsTheCorrectGreeting` did not pass because
164
+the solution did not satisfy an assertion." 
237 165
 
238
-* What went wrong:
239
-Execution failed for task ':test'.
240
-> There were failing tests. See the report at: file:///home/logan/hello-world/build/reports/tests/index.html
241
-
242
-* Try:
243
-Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
166
+Apparently, our test was expecting to see the string "Hello, World!", but it
167
+received the value `null` instead.
244 168
 
245
-BUILD FAILED
169
+The last line of the stack trace tells us exactly where this "unsatisfied
170
+assertion" lives:
246 171
 
247
-Total time: 20.855 secs
248 172
 ```
173
+        at testThatGreeterReturnsTheCorrectGreeting(GreeterTest.java:9)
174
+```
175
+Looks like the mismatch was discovered on line 9 in the test file.
249 176
 
250
-Woohoo! :)  You can see that `helloNoName()` and `emptyStringIsComparedByValue()` are
251
-now passing.
252
-
253
-Let's tackle the next test...
254
-
177
+Knowing these two facts:
255 178
 
179
+1. that the return value was not what was expected, and
180
+2. that the failure was on line 9 of the test file,
256 181
 
257
-## Fixing the second test
182
+we can turn this failure into success.
258 183
 
259
-Right now, we've hardcoded the greeting.  This second test has
260
-unleashed a new expectation: that our program must incorporate a name given
261
-into that greeting.  When given the name "`Alice`", that's who should be
262
-greeted instead of "`World`".
184
+## Step 3: Fix the test!
263 185
 
264
-(Re)open `src/main/java/HelloWorld.java`.
186
+Open `src/test/java/GreeterTest.java` and go to line 9. It reads:
265 187
 
266 188
 ```java
267
-public class HelloWorld {
268
-  public static String hello(String name) {
269
-    return "Hello, World!";
270
-  }
271
-}
189
+assertEquals("Hello, World!", new Greeter().getGreeting());
272 190
 ```
273 191
 
274
-While `hello()` does accept a reference to a string named `name`, it is not
275
-using it in the output.  Let's change that:
192
+The test is expecting that the method `getGreeting()` returns "Hello, World!".
193
+Instead, `getGreeting()` is returning `null`. Let's fix that.
276 194
 
195
+Open `src/main/java/Greeter.java`. It should look like this:
277 196
 
278 197
 ```java
279
-public class HelloWorld {
280
-  public static String hello(String name) {
281
-    return "Hello, " + name + "!";
282
-  }
283
-}
284
-```
285
-
286
-... and rerun the tests ...
287
-
288
-```
289
-$ gradle test
290
-:test
291
-
292
-HelloWorldTest > helloSampleName PASSED
293
-
294
-HelloWorldTest > helloNoName FAILED
295
-    org.junit.ComparisonFailure: expected:<Hello, [World]!> but was:<Hello, []!>
296
-        at org.junit.Assert.assertEquals(Assert.java:115)
297
-        at org.junit.Assert.assertEquals(Assert.java:144)
298
-        at HelloWorldTest.helloNoName(HelloWorldTest.java:11)
198
+class Greeter {
299 199
 
300
-HelloWorldTest > emptyStringIsComparedByValue FAILED
301
-    org.junit.ComparisonFailure: expected:<Hello, [World]!> but was:<Hello, []!>
302
-        at org.junit.Assert.assertEquals(Assert.java:115)
303
-        at org.junit.Assert.assertEquals(Assert.java:144)
304
-        at HelloWorldTest.emptyStringIsComparedByValue(HelloWorldTest.java:17)
305
-
306
-HelloWorldTest > helloAnotherSampleName PASSED
307
-
308
-4 tests completed, 2 failed
309
-:test FAILED
310
-
311
-FAILURE: Build failed with an exception.
312
-
313
-* What went wrong:
314
-Execution failed for task ':test'.
315
-> There were failing tests. See the report at: file:///home/logan/hello-world/build/reports/tests/index.html
316
-
317
-* Try:
318
-Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
319
-
320
-BUILD FAILED
200
+    String getGreeting() {
201
+        return null;
202
+    }
321 203
 
322
-Total time: 12.466 secs
204
+}
323 205
 ```
324 206
 
325
-Wait... didn't we just fix the test?  Why is it failing?  Take a closer look...
207
+Remove the `return null` that we previously added, and instead return the
208
+string our test was expecting:
326 209
 
327
-In fact, `helloSampleName()` *is* passing.  It's just that at the same time,
328
-we just inadvertently broke the first tests: `helloNoName()` and `emptyStringIsComparedByValue()`.
329
-
330
-This is one tiny example of the benefit of maintaining a test suite: if we
331
-use them to drive out our code, the second we break the program the tests
332
-say so.  Since we saw them passing just *before* our latest change,
333
-whatever we *just* did most likely cause that regression.
334
-
335
-Our latest change was making the greeting dependent on the name given. Our
336
-first two tests expects that if either a blank string or null are given as the
337
-name, then "`World`" should be substituted in.  Let's implement that.
338
-
339
-`src/main/java/HelloWorld.java`:
340 210
 ```java
341
-public class HelloWorld {
342
-  public static String hello(String name) {
343
-    if(name == null || "".equals(name)) {
344
-      name = "World";
211
+    String getGreeting() {
212
+        return "Hello, World!";
345 213
     }
346
-    return "Hello, " + name + "!";
347
-  }
348
-}
349 214
 ```
350 215
 
351
-... and re-run the tests ...
216
+Save the file and run the tests again:
352 217
 
353 218
 ```
354 219
 $ gradle test
355
-...
220
+:compileJava
221
+:processResources UP-TO-DATE
222
+:classes
223
+:compileTestJava
224
+:processTestResources UP-TO-DATE
225
+:testClasses
356 226
 :test
357 227
 
358
-HelloWorldTest > helloSampleName PASSED
359
-
360
-HelloWorldTest > helloNoName PASSED
361
-
362
-HelloWorldTest > emptyStringIsComparedByValue PASSED
363
-
364
-HelloWorldTest > helloAnotherSampleName PASSED
228
+GreeterTest > testThatGreeterReturnsTheCorrectGreeting PASSED
365 229
 
366 230
 BUILD SUCCESSFUL
367 231
 
368 232
 Total time: 11.717 secs
369 233
 ```
370 234
 
371
-Oh, hello!  Turns out, the solution we put into place didn't just apply for
372
-"`Alice`" but "`Bob`" equally well.  In this case, the test succeeded with
373
-no additional code on our part.
374
-
375
-
376
-
377
-## Refactoring
378
-
379
-Now that you've got all the tests passing, you might consider whether
380
-the code is in the most readable/maintainable/efficient shape.  What makes
381
-for "good" design of software is a big topic.  The pursuit of it underlies
382
-much of what makes up the more valuable conversations on Exercism.
383
-
384
-For now, let's just take a quick review of our solution and see if there's
385
-any part of it we'd like to refactor.  Refactoring is changing the way
386
-a bit of code reads without changing what it does.
387
-
388
-Right now, the details of detecting whether the caller of `hello()` has
389
-given a name or not (i.e. `name` is either `null` or an empty string) is
390
-sitting right next to the core responsibility of the method: to produce a
391
-personalized greeting.
392
-
393
-```java
394
-public class HelloWorld {
395
-  public static String hello(String name) {
396
-    if(name == null || "".equals(name)) {
397
-      name = "World";
398
-    }
399
-    return "Hello, " + name + "!";
400
-  }
401
-}
402
-```
403
-
404
-How would things read if we extracted those details into a separate method
405
-and at the same time, replaced the `if` with a ternary expression?
406
-
407
-```java
408
-public class HelloWorld {
409
-
410
-  public static String hello(String name) {
411
-    String whom = isBlank(name) ? "World" : name;
412
-    return "Hello, " + whom + "!";
413
-  }
414
-
415
-  private static boolean isBlank(String string) {
416
-    return string == null || "".equals(string);
417
-  }
418
-}
419
-```
420
-
421
-By extracting that logic into the `isBlank()` method, we've added a little
422
-abstraction to our program -- it's not as literal as it was before.  Yet,
423
-it allows us to defer *needing* to understand *how* "blankness" is
424
-detected.  If we can assume that `isBlank()` just works, we don't have to
425
-downshift in our head to those details.  Instead, we can remain at the same
426
-level of thinking: to whom are we greeting?
427
-
428
-The ternary operator allowed us to express that choice in a more compact
429
-form.  Less to read without losing the intent.
430
-
431
-Finally, we introduced another variable: `whom`.  Doing so gives a name to
432
-the output of the ternary expression.  We certainly could have continued
433
-to reuse `name`, but by introducing a second `String` to hold the
434
-calculated value this keeps crisp the two ideas: `name` is what's given
435
-and `whom` is what's been determined.
436
-
437
-We made a bunch of changes, let's make sure we didn't break the program!
438
-
439
-```
440
-$ gradle test
441
-...
442
-HelloWorldTest > helloSampleName PASSED
443
-
444
-HelloWorldTest > helloNoName PASSED
445
-
446
-HelloWorldTest > emptyStringIsComparedByValue PASSED
447
-
448
-HelloWorldTest > helloAnotherSampleName PASSED
449
-...
450
-```
451
-
452
-This illustrates another benefit of writing tests: you can make significant
453
-changes to the structure of the program and very quickly restore your
454
-confidence that the program still works.  These tests are a far cry from a
455
-"proof" of correctness, but well-written tests do a much better job of
456
-(very quickly) giving us evidence that it is.  Without them, we manually
457
-run the program with different inputs and/or inspecting the code
458
-line-by-line -- time-consuming and error prone.
459
-
460
-
235
+Success! Our solution passes the only test case supplied. We're good to go!
461 236
 
462 237
 # Submitting your first iteration
463 238
 
@@ -465,15 +240,20 @@ With a working solution that we've reviewed, we're ready to submit it to
465 240
 exercism.io.
466 241
 
467 242
 ```
468
-$ exercism submit src/main/java/HelloWorld.java
243
+$ exercism submit src/main/java/Greeter.java
469 244
 ```
470 245
 
471
-
472
-
473 246
 # Next Steps
474 247
 
475 248
 From here, there are a number of paths you can take.
476 249
 
250
+Regardless of what you decide to do next, we sincerely hope you learn
251
+and enjoy being part of this community.  If at any time you need assistance
252
+do not hesitate to ask for help:
253
+
254
+http://exercism.io/languages/java/help
255
+
256
+Cheers!
477 257
 
478 258
 ## Move on to the next exercise
479 259
 
@@ -483,7 +263,6 @@ There are many more exercises you can practice with.  Grab the next one!
483 263
 $ exercism fetch java
484 264
 ```
485 265
 
486
-
487 266
 ## Review (and comment on) others' submissions to this exercise
488 267
 
489 268
 The heart of Exercism are the conversations about coding
@@ -503,39 +282,11 @@ Here's an up-to-date list of submissions on the Java track:
503 282
 
504 283
 http://exercism.io/tracks/java/exercises
505 284
 
506
-
507
-
508
-## Submit another iteration
509
-
510
-You are also encouraged to consider additional "requirements" on a given
511
-exercise.
512
-
513
-For example, you could add a test or two that requires that the greeting
514
-use the capitalized form on the person's name, regardless of the case they
515
-used.
516
-
517
-In that situation, you'd write a test to set-up that new expectation and
518
-then implement that in the code (the same process we just went through
519
-together, above).
520
-
521
-
522
-
523 285
 ## Contribute to Exercism
524 286
 
525
-The entire of Exercism is Open Source and is the labor of love for over
287
+The entire of Exercism is Open Source and is a labor of love for over
526 288
 100 maintainers and many more contributors.
527 289
 
528 290
 A starting point to jumping in can be found here:
529 291
 
530
-https://github.com/exercism/problem-specifications/blob/master/CONTRIBUTING.md
531
-
532
-
533
-----
534
-
535
-Regardless of what you decide to do next, we sincerely hope you learn
536
-and enjoy being part of this community.  If at any time you need assistance
537
-do not hesitate to ask for help:
538
-
539
-http://exercism.io/languages/java/help
540
-
541
-Cheers!
292
+https://github.com/exercism/docs/tree/master/contributing-to-language-tracks

+ 7
- 0
exercises/hello-world/src/example/java/Greeter.java Vedi File

@@ -0,0 +1,7 @@
1
+class Greeter {
2
+
3
+    String getGreeting() {
4
+        return "Hello, World!";
5
+    }
6
+
7
+}

+ 0
- 9
exercises/hello-world/src/example/java/HelloWorld.java Vedi File

@@ -1,9 +0,0 @@
1
-public class HelloWorld {
2
-    public static String hello(String name) {
3
-        if (name == null || name.isEmpty()) {
4
-            return "Hello, World!";
5
-        }
6
-
7
-        return String.format("Hello, %s!", name);
8
-    }
9
-}

exercises/hello-world/src/main/java/HelloWorld.java → exercises/hello-world/src/main/java/Greeter.java Vedi File

@@ -1,5 +1,7 @@
1
-public class HelloWorld {
2
-    public static String hello(String name) {
1
+class Greeter {
2
+
3
+    String getGreeting() {
3 4
         throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
4 5
     }
6
+
5 7
 }

+ 12
- 0
exercises/hello-world/src/test/java/GreeterTest.java Vedi File

@@ -0,0 +1,12 @@
1
+import org.junit.Test;
2
+
3
+import static org.junit.Assert.assertEquals;
4
+
5
+public class GreeterTest {
6
+
7
+    @Test
8
+    public void testThatGreeterReturnsTheCorrectGreeting() {
9
+        assertEquals("Hello, World!", new Greeter().getGreeting());
10
+    }
11
+
12
+}

+ 0
- 28
exercises/hello-world/src/test/java/HelloWorldTest.java Vedi File

@@ -1,28 +0,0 @@
1
-import org.junit.Test;
2
-import org.junit.Ignore;
3
-
4
-import static org.junit.Assert.assertEquals;
5
-
6
-public class HelloWorldTest {
7
-
8
-    @Test
9
-    public void helloNoName() {
10
-        assertEquals("Hello, World!", HelloWorld.hello(""));
11
-        assertEquals("Hello, World!", HelloWorld.hello(null));
12
-    }
13
-
14
-    @Test
15
-    public void emptyStringIsComparedByValue() {
16
-        assertEquals("Hello, World!", HelloWorld.hello(new String("")));
17
-    }
18
-    
19
-    @Test
20
-    public void helloSampleName() {
21
-        assertEquals("Hello, Alice!", HelloWorld.hello("Alice"));
22
-    }
23
-
24
-    @Test
25
-    public void helloAnotherSampleName() {
26
-        assertEquals("Hello, Bob!", HelloWorld.hello("Bob"));
27
-    }
28
-}

exercises/isogram/HINT.md → exercises/isogram/HINTS.md Vedi File


exercises/simple-cipher/HINT.md → exercises/simple-cipher/HINTS.md Vedi File


+ 0
- 3
exercises/two-fer/HINT.md Vedi File

@@ -1,3 +0,0 @@
1
-To help you focus on one test at a time, [@Ignore](http://junit.sourceforge.net/javadoc/org/junit/Ignore.html)
2
-annotations have been added to every test but the first one. Any test with an `@Ignore` annotation will be skipped
3
-when you run the tests.

+ 38
- 0
exercises/two-fer/HINTS.md Vedi File

@@ -0,0 +1,38 @@
1
+Most Java exercises include multiple test cases. These cases are structured to
2
+support a useful process known as
3
+[test-driven development (TDD)](https://en.wikipedia.org/wiki/Test-driven_development).
4
+TDD involves repeating a structured cycle that helps programmers build complex
5
+functionality piece by piece rather than all at once. That cycle can be
6
+described as follows:
7
+
8
+1. Add a test that describes one piece of desired functionality your code is
9
+currently missing.
10
+2. Run the tests to verify that this newly-added test fails.
11
+3. Update your existing code until:
12
+    - All the old tests continue to pass;
13
+    - The new test also passes.
14
+4. [Clean up](https://en.wikipedia.org/wiki/Code_refactoring) your code, making
15
+sure that all tests continue to pass. This typically involves renaming
16
+variables, removing duplicated chunks of logic, removing leftover logging, etc.
17
+5. Return to step 1 until all desired functionality has been built!
18
+
19
+The test files in this track contain _all_ the tests your solution should pass
20
+to be considered valid. That doesn't immediately seem to be compatible with the
21
+cycle described above, in which tests are written one by one. However, the
22
+tool that we use to write our tests, [JUnit](http://junit.org), provides an
23
+[@Ignore](http://junit.sourceforge.net/javadoc/org/junit/Ignore.html)
24
+[annotation](https://docs.oracle.com/javase/tutorial/java/annotations/) that
25
+can be used to temporarily skip an already-written test. Using this annotation,
26
+we make sure that the test files we deliver to you satisfy the following rules:
27
+
28
+- The first test in any test file is _not_ skipped by default.
29
+- All but the first test in any test file _are_ skipped by default.
30
+
31
+This allows you to simulate the TDD cycle by following these slightly-modified
32
+steps:
33
+
34
+1. Run the tests to verify that _at most one_ test currently fails.
35
+2. Update your existing code until all the non-skipped tests pass.
36
+3. Clean up your code, making sure that all non-skipped tests continue to pass.
37
+4. Remove the topmost `@Ignore` annotation in the test file.
38
+5. Return to step 1 until no tests are skipped and all tests pass!