forked from ksarantakos/theladders.github.com
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
3653 lines (2978 loc) · 310 KB
/
atom.xml
File metadata and controls
3653 lines (2978 loc) · 310 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[TheLadders Engineering Stories]]></title>
<link href="http://dev.theladders.com/atom.xml" rel="self"/>
<link href="http://dev.theladders.com/"/>
<updated>2015-05-15T09:54:12-04:00</updated>
<id>http://dev.theladders.com/</id>
<author>
<name><![CDATA[TheLadders Engineering]]></name>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[Working in Harmony: ES6 in a nutshell]]></title>
<link href="http://dev.theladders.com/2015/05/working-in-harmony-es6-in-a-nutshell/"/>
<updated>2015-05-04T16:05:00-04:00</updated>
<id>http://dev.theladders.com/2015/05/working-in-harmony-es6-in-a-nutshell</id>
<content type="html"><![CDATA[<blockquote><p>“JavaScript is a language with more than its share of bad parts.”</p><footer><strong>–Douglas Crockford</strong> <cite>JavaScript: The Good Parts</cite></footer></blockquote>
<h1>Harmony</h1>
<p>JavaScript, also known as ECMAScript, has extended its life beyond the boundaries of the browser. It can be found in <a href="https://nodejs.org/">server side code</a>, in <a href="http://docs.unity3d.com/Manual/CreatingAndUsingScripts.html">video game engines</a>, even frameworks to run C programs in the <a href="http://asmjs.org/">browser</a>. Unfortunately, the language specification has not been updated since 2009, which in turn has led to different frameworks and tools to accommodate for the lack of features. Luckily, TC-39, the committee for approving ECMAScript, has a targeted release date of June 2015 for the next version of ECMAScript (ES6). ECMAScript is a significant update to the language and brings a slew of new features.</p>
<p>Here are several of the important features that will make the ES6 release:</p>
<h1>Modules</h1>
<p>Modules provide private and public encapsulation to limit the creation of variables and functions on the global scope. They are part of a popular design pattern that has resulted in several frameworks such as <a href="http://requirejs.org/">RequireJS</a>, <a href="http://browserify.org/">Browserify</a>, and <a href="http://webpack.github.io/">Webpack</a>. ES6 provides a native solution that combines attributes of both CommonJS and AMD.</p>
<ul>
<li>Similar to CommonJS, native modules provide a compact syntax, a preference for single exports and support for cyclic dependencies.</li>
<li>Similar to AMD, they have direct support for asynchronous loading and configurable module loading.</li>
</ul>
<p>Let’s look at an example of using native modules. Within a utility file, we have two functions, sumOfNumbers and logMessage. The module pattern allows us to choose which functions or attributes we want to expose to our consumers. There are two kinds of exports:</p>
<ul>
<li><strong>named exports</strong> (several per module), where the user specifies the name of the attribute on import.</li>
<li><strong>default exports</strong> (one per module), where the compiler picks the export item labeled with the default keyword when it cannot match a named export.</li>
</ul>
<p><em>Note:</em> You can run the following examples in babel’s <a href="https://babeljs.io/repl/">live script editor</a>.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">// lib/utility.js</span>
</span><span class='line'><span class="kr">export</span> <span class="kd">function</span> <span class="nx">sumOfNumbers</span><span class="p">(){</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">numbers</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">);</span>
</span><span class='line'> <span class="k">return</span> <span class="nx">numbers</span><span class="p">.</span><span class="nx">reduce</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="nx">y</span><span class="p">){</span> <span class="k">return</span> <span class="nx">x</span> <span class="o">+</span> <span class="nx">y</span> <span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">logMessage</span><span class="p">(</span><span class="nx">msg</span><span class="p">){</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Message is '</span><span class="p">,</span> <span class="nx">msg</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// app.js</span>
</span><span class='line'><span class="kr">import</span> <span class="p">{</span><span class="nx">logMessage</span><span class="p">,</span> <span class="nx">sumOfNumbers</span><span class="p">}</span> <span class="nx">from</span> <span class="s1">'utility'</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="nx">logMessage</span><span class="p">(</span><span class="nx">sumOfNumbers</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">));</span> <span class="c1">// Message is 15</span>
</span><span class='line'><span class="nx">logMessage</span><span class="p">(</span><span class="nx">sumOfNumbers</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">10</span><span class="p">));</span> <span class="c1">// Message is 19</span>
</span></code></pre></td></tr></table></div></figure>
<h1>Classes</h1>
<p>ES6 brings classes to the language. The class implementation still uses prototypical inheritance, so it is syntactic sugar to make it easier to implement and understand. Using the <strong>extends</strong> keyword provides the following benefits:</p>
<ul>
<li>Binds the correct context when using the <em>extends</em> keyword.</li>
<li>Methods defined within the class block are defined on the prototype object.</li>
<li>Provides the <em>super</em> keyword to easily invoke parent methods.</li>
</ul>
<p>As a simple example of class inheritance, let’s create a shape class with a triangle child class extending from shape.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">//Traditional way to create inheritance</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">Shape</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">){</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="nx">width</span><span class="p">;</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">height</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="nx">Shape</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">printObject</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Shape'</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">height</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">Triangle</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">){</span>
</span><span class='line'><span class="c1">//Note: not a convenient way to invoke parent constructor</span>
</span><span class='line'><span class="c1">// we have to call the parent object with Triangle's context.</span>
</span><span class='line'> <span class="nx">Shape</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">);</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">sides</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="nx">Triangle</span><span class="p">.</span><span class="nx">prototype</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nx">Shape</span><span class="p">.</span><span class="nx">prototype</span><span class="p">);</span> <span class="c1">//prototype object now inheritances the properties of Shape</span>
</span><span class='line'>
</span><span class='line'><span class="nx">Triangle</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">printObject</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Triangle'</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">height</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">sides</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">//ES6 Way to create inheritance</span>
</span><span class='line'><span class="kr">class</span> <span class="nx">Shape</span><span class="p">{</span>
</span><span class='line'> <span class="nx">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// properties of the class</span>
</span><span class='line'> <span class="nx">height</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// note: they are NOT private</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">//function called with you call Shape with 'new' keyword</span>
</span><span class='line'> <span class="nx">constructor</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">){</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="nx">width</span><span class="p">;</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">height</span><span class="p">;</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">//method part of shape</span>
</span><span class='line'> <span class="nx">printObject</span><span class="p">(){</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Shape'</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">height</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kr">class</span> <span class="nx">Triangle</span> <span class="kr">extends</span> <span class="nx">Shape</span><span class="p">{</span>
</span><span class='line'> <span class="nx">sides</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">constructor</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">){</span>
</span><span class='line'> <span class="c1">//invokes the parent constructor by calling super</span>
</span><span class='line'> <span class="c1">// automatically applies the correct context.</span>
</span><span class='line'> <span class="kr">super</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">//Overrides the method on the parent object</span>
</span><span class='line'> <span class="nx">printObject</span><span class="p">(){</span>
</span><span class='line'> <span class="c1">//Draw the triangle</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Triangle'</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">height</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>We can apply this new syntax to existing frameworks such as Backbone.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">//current backbone implementation</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">MyView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span><span class='line'> <span class="nx">template</span><span class="o">:</span> <span class="s1">'<div>Sample Template</div>'</span><span class="p">,</span>
</span><span class='line'> <span class="nx">events</span><span class="o">:</span> <span class="p">{</span>
</span><span class='line'> <span class="s1">'click'</span> <span class="o">:</span> <span class="s1">'clickHandler'</span>
</span><span class='line'> <span class="p">},</span>
</span><span class='line'> <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">template</span><span class="p">);</span>
</span><span class='line'> <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
</span><span class='line'> <span class="p">},</span>
</span><span class='line'> <span class="nx">clickHandler</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span>
</span><span class='line'> <span class="nx">alert</span><span class="p">(</span><span class="s1">'My view was clicked'</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="c1">//Backbone using classes</span>
</span><span class='line'><span class="kr">class</span> <span class="nx">MyView</span> <span class="kr">extends</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">constructor</span><span class="p">(</span><span class="nx">options</span><span class="p">){</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">template</span> <span class="o">=</span> <span class="s1">'<div>Sample Template</div>'</span><span class="p">;</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">events</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'> <span class="s1">'click'</span> <span class="o">:</span> <span class="s1">'clickHandler'</span>
</span><span class='line'> <span class="p">};</span>
</span><span class='line'> <span class="kr">super</span><span class="p">(</span><span class="nx">options</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="nx">render</span><span class="p">(){</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">template</span><span class="p">);</span>
</span><span class='line'> <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="nx">clickHandler</span><span class="p">(){</span>
</span><span class='line'> <span class="nx">alert</span><span class="p">(</span><span class="s1">'My view was clicked'</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<h1>Arrow Functions</h1>
<p>ES6 has also added arrow functions, which provide a for more concise syntax for anonymous functions. However, there are a number of differences between arrow functions and traditional JavaScript functions:</p>
<ul>
<li><strong>Lexical <em>this</em> binding</strong> – The value of <em>this</em> inside of the function is determined by where the arrow function is defined, not where it is used.</li>
<li><strong>Not <em>new</em>-able</strong> – Arrow functions do not have a constructor method and therefore can not be used to create instances. Arrow functions throw an error when called with “new”.</li>
<li><strong>Cannot change the value of <em>this</em></strong> – The value of <em>this</em> remains the same value throughout the lifecycle of the function.</li>
<li><strong>No <em>arguments</em> object</strong> – Function arguments are not accessible through the arguments object; you must use named arguments or ES6 <a href="http://wiki.ecmascript.org/doku.php?id=harmony:rest_parameters">rest arguments</a>.</li>
</ul>
<p>Here is a simple example using arrow functions. We are iterating of a list of items and printing out each number to the console.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'> <span class="kd">var</span> <span class="nx">numbers</span> <span class="o">=</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">];</span>
</span><span class='line'> <span class="c1">//Current javascript implementation</span>
</span><span class='line'> <span class="nx">numbers</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">number</span><span class="p">){</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">number</span><span class="p">);</span>
</span><span class='line'> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">// ES6 - Arrow functions</span>
</span><span class='line'> <span class="nx">numbers</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">number</span> <span class="o">=></span> <span class="p">{</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">number</span><span class="p">);</span>
</span><span class='line'> <span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<p>Let’s look at more practical example using an event handler:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">//Current Javascript implementation</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">Person</span><span class="p">(){</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">$el</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">'button'</span><span class="p">);</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">text</span> <span class="o">=</span> <span class="s2">"Hello I am a person"</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">//Problem with current Javascript that we have to "bind" the person context </span>
</span><span class='line'> <span class="c1">// in order to get the callback to work properly. Without "bind", the function</span>
</span><span class='line'> <span class="c1">// would print out undefined.</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'click'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(){</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">text</span><span class="p">);</span>
</span><span class='line'> <span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">));</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">//ES6</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">Person</span><span class="p">(){</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">$el</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">'button'</span><span class="p">);</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">text</span> <span class="o">=</span> <span class="s2">"Hello I am a person"</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">//No longer need to "bind" the function since it is set to where it is defined.</span>
</span><span class='line'> <span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">'click'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">text</span><span class="p">);</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>Arrow functions also provide different types of optional syntax. Here are several examples:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'> <span class="kd">var</span> <span class="nx">numbers</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">];</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">temp</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">//arrow functions return last value, no need for return statement.</span>
</span><span class='line'> <span class="nx">temp</span> <span class="o">=</span> <span class="nx">numbers</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">number</span> <span class="o">=></span> <span class="nx">number</span> <span class="o">+</span> <span class="mi">2</span><span class="p">);</span>
</span><span class='line'> <span class="c1">//need empty parentheses if no parameters are passed</span>
</span><span class='line'> <span class="nx">temp</span> <span class="o">=</span> <span class="nx">numbers</span><span class="p">.</span><span class="nx">map</span><span class="p">(()</span> <span class="o">=></span> <span class="mi">5</span><span class="p">);</span>
</span><span class='line'> <span class="c1">//multiple parameters </span>
</span><span class='line'> <span class="nx">temp</span> <span class="o">=</span> <span class="nx">numbers</span><span class="p">.</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">x</span><span class="p">,</span><span class="nx">y</span><span class="p">)</span> <span class="o">=></span> <span class="nx">x</span> <span class="o">+</span> <span class="nx">y</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>
<h1>Destructing Variables</h1>
<p>Destructuring allows binding via pattern matching. ES6 supports matching for arrays and objects. It will try to match the variable directly and return undefined when no match is found.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'> <span class="kd">var</span> <span class="nx">numbers</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">];</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">a</span><span class="o">:</span> <span class="mi">4</span><span class="p">,</span> <span class="nx">b</span><span class="o">:</span> <span class="s1">'Hello'</span><span class="p">,</span> <span class="nx">c</span><span class="o">:</span> <span class="kc">false</span> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">//first = 1, third = 3</span>
</span><span class='line'> <span class="kd">var</span> <span class="p">[</span><span class="nx">first</span><span class="p">,</span> <span class="p">,</span> <span class="nx">third</span><span class="p">]</span> <span class="o">=</span> <span class="nx">numbers</span><span class="p">;</span>
</span><span class='line'> <span class="kd">var</span> <span class="p">{</span><span class="nx">a</span><span class="p">,</span><span class="nx">c</span><span class="p">}</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">;</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">a</span><span class="p">);</span> <span class="c1">//prints out 4</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">c</span><span class="p">);</span> <span class="c1">//prints out false</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">//assigning value of 'b' in object to variable 'anotherName'</span>
</span><span class='line'> <span class="kd">var</span> <span class="p">{</span><span class="nx">b</span><span class="o">:</span> <span class="nx">anotherName</span><span class="p">}</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">;</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">anotherName</span><span class="p">);</span> <span class="c1">//prints out 'Hello'</span>
</span></code></pre></td></tr></table></div></figure>
<h1>Default, Rest, Spread</h1>
<p>ES6 provides the flexibility to set default values for function parameters. It lets you grab trailing values without using the arguments keyword. And it also allows you to turn an array into consecutive arguments for a function call. With these options, there is no longer a need to use the arguments variable.</p>
<h5>Default Parameter</h5>
<ul>
<li>Current values that are not set are given a value of undefined. ES6 provides new syntax to add default values for parameters.</li>
</ul>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'> <span class="kd">function</span> <span class="nx">add2</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span> <span class="o">=</span> <span class="mi">2</span><span class="p">){</span>
</span><span class='line'> <span class="k">return</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span><span class="p">;</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="nx">add2</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">5</span><span class="p">);</span> <span class="c1">// returns 7</span>
</span><span class='line'> <span class="nx">add2</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span> <span class="c1">//return 4</span>
</span></code></pre></td></tr></table></div></figure>
<h5>Rest parameter</h5>
<ul>
<li>Currently, in order to grab all argument values as an array, we need to explicitly convert the values using the arguments keyword.</li>
</ul>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'> <span class="c1">// Current Javascript</span>
</span><span class='line'> <span class="c1">//need to convert arguments into an array object in order to use any useful method.</span>
</span><span class='line'> <span class="kd">function</span> <span class="nx">sum</span><span class="p">(){</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">numbers</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">);</span>
</span><span class='line'> <span class="k">return</span> <span class="nx">numbers</span><span class="p">.</span><span class="nx">reduce</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">){</span> <span class="k">return</span> <span class="nx">x</span> <span class="o">+</span> <span class="nx">y</span><span class="p">;</span> <span class="p">});</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">// ES6</span>
</span><span class='line'> <span class="c1">// The conversion happens automatically. </span>
</span><span class='line'> <span class="kd">function</span> <span class="nx">sum</span><span class="p">(...</span><span class="nx">numbers</span><span class="p">){</span>
</span><span class='line'> <span class="k">return</span> <span class="nx">numbers</span><span class="p">.</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">x</span><span class="p">,</span><span class="nx">y</span><span class="p">)</span> <span class="o">=></span> <span class="nx">x</span> <span class="o">+</span> <span class="nx">y</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<h5>Spread parameter</h5>
<ul>
<li>Spread functionality allows us to convert an array into consecutive arguments to pass into a function. Currently, we have to use the <em>apply</em> keyword in order to provide the same functionality.</li>
</ul>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'> <span class="c1">//current implementation</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">numbers</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">];</span>
</span><span class='line'> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nb">Math</span><span class="p">,</span> <span class="nx">numbers</span><span class="p">);</span> <span class="c1">//spreads the array and returns 5</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">//Future implementation</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">numbers</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">];</span>
</span><span class='line'> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(...</span><span class="nx">numbers</span><span class="p">);</span> <span class="c1">//performs the same action</span>
</span></code></pre></td></tr></table></div></figure>
<h1>Current Alternatives</h1>
<p>The JavaScript specification is targeted to release in June, but it could take browsers months to <a href="http://kangax.github.io/compat-table/es6/">implement</a> these new features and years before users decide it’s a good time to upgrade their browsers. Luckily, there are solutions which allow us to take advantage of these features right now. Here are several options:</p>
<h3><a href="https://babeljs.io/"><img src="https://raw.githubusercontent.com/babel/logo/master/logo.png" alt="Babel" width="250px"></a></h3>
<ul>
<li>A compiler for converting ES6 syntax to ES5-compatible javascript. Babel is among the most mature compilers for ES6 conversion with the options of extensible plugins as well as framework and tool integration.</li>
</ul>
<h3><a href="https://github.com/google/traceur-compiler"><img src="https://google.github.com/traceur-compiler/logo/tc.svg" alt="Traceur logo" width="200px"> Traceur</a></h3>
<ul>
<li>Google’s version of Babel. Traceur is a JavaScript.next-to-JavaScript-of-today compiler that allows you to use features from the future today. Traceur supports ES6 as well as some experimental ES.next features.</li>
</ul>
<h3><a href="http://www.typescriptlang.org/"><img src="http://www.typescriptlang.org/content/images/logo_small.png" alt="Typescript"></a></h3>
<ul>
<li>Typescript is a typed superset of JavaScript that compiles to plain JavaScript. It also provides the option of applying types to variables and functions at compile time. TypeScript provides the flexibility of using ES6 features such as classes, modules and arrow function which ultimately compile to ES5 compatible JavaScript. Similar to Babel, Typescript has integrations with many development environments and definition files for existing frameworks.</li>
</ul>
<h3><a href="http://flowtype.org/"><img src="http://flowtype.org/static/flow-hero-logo.png" alt="Flow" width="200px"></a></h3>
<ul>
<li>Flow is a new static type checker for JavaScript. Flow is similar to Typescript in that it will compile down to plain JavaScript. The difference is that it provides valid checking for null variable type. Flow integrates well with other Facebook tools such as React and Flux.</li>
</ul>
<h1>Conclusion</h1>
<p>ECMAScript 6 provides an array of exciting tools and libraries that we can leverage to make development both easier and more exciting. Though we know that it could be months before we can use these tools natively, we have alternatives that allow developers to expand their toolsets and think of efficient and abstract solutions. If interested in learning more, here are several links:</p>
<h4>Resources:</h4>
<ul>
<li><a href="https://github.com/lukehoban/es6features">All ES6 Features</a></li>
<li><a href="https://leanpub.com/understandinges6/">Understanding ES6 – Nicolas Zakas</a></li>
<li><a href="https://babeljs.io/docs/learn-es6/">Try ES6 Compilation using Babel</a></li>
<li><a href="https://www.youtube.com/watch?v=DqMFX91ToLw">Evolution of Javascript – Netflix Javascript Talks</a></li>
<li><a href="https://people.mozilla.org/~jorendorff/es6-draft.html">EcmaScript 6 Draft</a></li>
</ul>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Writing better API tests]]></title>
<link href="http://dev.theladders.com/2015/04/writing-better-api-tests/"/>
<updated>2015-04-27T17:41:00-04:00</updated>
<id>http://dev.theladders.com/2015/04/writing-better-api-tests</id>
<content type="html"><![CDATA[<blockquote><p>It is only through labor and painful effort, by grim energy and resolute courage, that we move on to better things.</p><footer><strong>–Theodore Roosevelt</strong></footer></blockquote>
<h1>The problem</h1>
<p>When I was first tasked with writing the web service for our <a href="http://www.theladders.com/mobile/">jobseeker iOS app</a>, I wanted to be able to write tests against the API without diving into the world of iOS automated functional testing. I really didn’t see a need to fire up an iOS client just so I could make calls to a service that was under heavy development and in a constant state of change. So how could I write tests that would exercise the API in a way similar to an iOS client?</p>
<p>Fortunately for me, engineers at TheLadders have always emphasized testing in one form or another. Sometimes this means a unit test for a particular method on a class. Other times it means an automated functional test (AFT) verifying client/service interactions for a particular feature. And in some instances it may even mean, f**k it, ship it and see if it blows up in production (a rare occurrence of course).</p>
<p>It turns out that before I even started working on the mobile service, people before me were asking similar questions about testing their APIs, and they had come up with a slightly different type of test that we now call “web tests”. A “web test” is basically a way to fire up an instance of the service for each test and, using a Jersey client, programmatically make calls to that service within the test itself. This was great because it allowed us to write tests against our APIs without needing to fire up an external tool such as a web browser. The following code is an example of such a test:</p>
<figure class='code'><figcaption><span>Basic web test</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="n">TestRestClient</span> <span class="n">client</span> <span class="o">=</span> <span class="n">createTestRestClient</span><span class="o">();</span>
</span><span class='line'><span class="n">Response</span> <span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="err">“</span><span class="n">api</span><span class="o">/</span><span class="n">jobs</span><span class="err">”</span><span class="o">);</span>
</span><span class='line'><span class="n">assertEquals</span><span class="o">(</span><span class="mi">200</span><span class="o">,</span> <span class="n">response</span><span class="o">.</span><span class="na">getStatus</span><span class="o">());</span>
</span></code></pre></td></tr></table></div></figure>
<p>This code makes a call to retrieve a list of jobs and verifies the response status code is 200.</p>
<p>The idea of the “web” or “API test” was exactly what I needed. This gave me a starting point. But I knew these web tests could be improved upon, making it easier to test our APIs. So I set about trying to figure out what I wanted for testing the mobile service and came up with a list of requirements.</p>
<h1>The requirements</h1>
<p>There were some requirements I wanted to establish that would help guide my decision-making process when writing web tests. These requirements included the following:</p>
<ul>
<li>The tests should mimic how an iOS client would navigate the API</li>
<li>Anyone reading the test code should be able to easily understand what is being tested</li>
<li>The code should be easy to reuse, reducing duplication where possible</li>
</ul>
<p>These really aren’t groundbreaking ideas, but they were helpful to keep in mind at all times. They served as guideposts throughout my decision-making process. With these requirements defined, I’m going to give you a quick rundown of some key elements of the API before diving into implementation details.</p>
<h1>The API</h1>
<p>The API for the mobile service is a RESTful API that uses <a href="http://en.wikipedia.org/wiki/HATEOAS">hypermedia as the engine of application state (HATEOAS)</a>. We use the HTTP methods GET, DELETE, POST, and PUT against URLs representing resources. Everything is stateless and we leverage headers for things such as authorization and versioning. The following figure illustrates sample request and response against this API:</p>
<p><img class="center medium" src="http://dev.theladders.com/images/api-tests/api-request-response.png"></p>
<p>The above example illustrates a request for the details of an individual job. One important thing to note here is the “links” element in the JSON. This is the HATEOAS piece I mentioned earlier. If a user taps the “like” button on the app for this particular job, the client code would send a request to the URL associated with the “like” action. If the job was already liked when it was retrieved, then an “unlike” link would have been present instead.</p>
<p>We use hypermedia links extensively in the API. In fact, the only URL that is hard-coded in the iOS application is what we call a “bootstrap” URL. This URL gives the client all of the hypermedia links needed to get started with the app, and would look something like the following:</p>
<figure class='code'><figcaption><span>Bootstrap JSON response</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="nt">"links"</span> <span class="p">:</span> <span class="p">[{</span>
</span><span class='line'> <span class="nt">"action"</span> <span class="p">:</span> <span class="s2">"authenticate"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"method"</span> <span class="p">:</span> <span class="s2">"POST"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"uri"</span> <span class="p">:</span> <span class="s2">"https://localhost:54837/authenticate"</span><span class="p">,</span>
</span><span class='line'> <span class="p">},</span> <span class="p">{</span>
</span><span class='line'> <span class="nt">"action"</span> <span class="p">:</span> <span class="s2">"lookupIndustries"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"method"</span> <span class="p">:</span> <span class="s2">"GET"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"uri"</span> <span class="p">:</span> <span class="s2">"https://localhost:54837/api/lookup/industries"</span><span class="p">,</span>
</span><span class='line'> <span class="p">},</span> <span class="p">{</span>
</span><span class='line'> <span class="nt">"action"</span> <span class="p">:</span> <span class="s2">"autocompleteTitle"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"method"</span> <span class="p">:</span> <span class="s2">"GET"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"uri"</span> <span class="p">:</span> <span class="s2">"https://localhost:54837/api/autocomplete/title?q={toMatch}"</span><span class="p">,</span>
</span><span class='line'> <span class="p">},</span> <span class="p">{</span>
</span><span class='line'> <span class="nt">"action"</span> <span class="p">:</span> <span class="s2">"register"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"method"</span> <span class="p">:</span> <span class="s2">"POST"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"uri"</span> <span class="p">:</span> <span class="s2">"https://localhost:54837/register"</span><span class="p">,</span>
</span><span class='line'> <span class="p">}]</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>From here, the client has the links for retrieving some lookup lists, maybe a URL for auto-completing the job title field, a link for logging in an existing user, and a link for registering a new user. If the link to login is invoked, then new response JSON will be returned containing “links” for valid actions that user can perform, and so on and so forth.</p>
<p>There is more to the API and I’ve glossed over some details. But this should give you enough of an idea of how things work to understand the implementation.</p>
<h1>The implementation</h1>
<p>It’s important to keep in mind that the following implementation has evolved over time. What I present to you here is an example that identifies the key components of the current state. I was always going back-and-forth with different ideas, trying out various implementations. And I’m pretty certain the team will continue to iterate on what we have today.</p>
<p>But in its current state, the implementation has the following four components:</p>
<ol>
<li>Class representing request/response JSON</li>
<li>Class for performing asserts against a body of JSON</li>
<li>Class representing the actions that can be taken on a body of JSON (such as calling hypermedia links or accessing an item in a list)</li>
<li>Class representing a user, their state, and their “connection” to the API.</li>
</ol>
<p>These four components and how they relate to the API can be seen in the following figure:</p>
<p><img class="center medium" src="http://dev.theladders.com/images/api-tests/api-implementation-components.png"></p>
<p>In addition to these four components, I did my best to provide some “syntactic sugar” for allowing us to write tests in the given/when/then style. So let’s dive into each of the four components and give you some concrete examples to work with.</p>
<h2>Class representing request/response JSON</h2>
<p>We have what are called “representation” classes whose sole purpose is to “represent” incoming or outgoing JSON. These classes are annotated with JAXB annotations for serialization/deserialization purposes. These classes also have methods for accessing the hypermedia links (some of which may be optional). So the following JSON:</p>
<figure class='code'><figcaption><span>Job JSON</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='json'><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="nt">"details"</span> <span class="p">:</span> <span class="p">{</span>
</span><span class='line'> <span class="nt">"title"</span> <span class="p">:</span> <span class="s2">"Software Engineer"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"company"</span> <span class="p">:</span> <span class="s2">"TheLadders"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"location"</span> <span class="p">:</span> <span class="s2">"New York, NY"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"postedOn"</span> <span class="p">:</span> <span class="s2">"2015-04-17"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"salary"</span> <span class="p">:</span> <span class="s2">"$100k"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"description"</span> <span class="p">:</span> <span class="s2">"Work with us!"</span>
</span><span class='line'> <span class="p">},</span>
</span><span class='line'> <span class="nt">"links"</span> <span class="p">:</span> <span class="p">[</span> <span class="p">{</span>
</span><span class='line'> <span class="nt">"action"</span> <span class="p">:</span> <span class="s2">"like"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"method"</span> <span class="p">:</span> <span class="s2">"POST"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"uri"</span> <span class="p">:</span> <span class="s2">"https://localhost:54837/api/jobs/e-1/like"</span>
</span><span class='line'> <span class="p">},</span> <span class="p">{</span>
</span><span class='line'> <span class="nt">"action"</span> <span class="p">:</span> <span class="s2">"get"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"method"</span> <span class="p">:</span> <span class="s2">"GET"</span><span class="p">,</span>
</span><span class='line'> <span class="nt">"uri"</span> <span class="p">:</span> <span class="s2">"https://localhost:54837/api/jobs/e-1"</span>
</span><span class='line'> <span class="p">}</span> <span class="p">]</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>Would be represented by a class that looks like:</p>
<figure class='code'><figcaption><span>JobRepresentation.java</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="nd">@XmlRootElement</span>
</span><span class='line'><span class="nd">@XmlAccessorType</span><span class="o">(</span><span class="n">XmlAccessType</span><span class="o">.</span><span class="na">FIELD</span><span class="o">)</span>
</span><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">JobRepresentation</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'> <span class="kd">public</span> <span class="n">JobDetailRepresentation</span> <span class="n">details</span><span class="o">;</span>
</span><span class='line'> <span class="kd">public</span> <span class="n">HypermediaLinks</span> <span class="n">links</span><span class="o">;</span>
</span><span class='line'>
</span><span class='line'> <span class="o">...</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="n">Optional</span><span class="o"><</span><span class="n">HypermediaLink</span><span class="o">></span> <span class="nf">likeLink</span><span class="o">()</span>
</span><span class='line'> <span class="o">{</span>
</span><span class='line'> <span class="k">return</span> <span class="n">Optional</span><span class="o">.</span><span class="na">ofNullable</span><span class="o">(</span><span class="n">links</span><span class="o">.</span><span class="na">forAction</span><span class="o">(</span><span class="err">“</span><span class="n">like</span><span class="err">”</span><span class="o">));</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="n">Optional</span><span class="o"><</span><span class="n">HypermediaLink</span><span class="o">></span> <span class="nf">unlikeLink</span><span class="o">()</span>
</span><span class='line'> <span class="o">{</span>
</span><span class='line'> <span class="k">return</span> <span class="n">Optional</span><span class="o">.</span><span class="na">ofNullable</span><span class="o">(</span><span class="n">links</span><span class="o">.</span><span class="na">forAction</span><span class="o">(</span><span class="err">“</span><span class="n">unlike</span><span class="err">”</span><span class="o">));</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="n">HypermediaLink</span> <span class="nf">getLink</span><span class="o">()</span>
</span><span class='line'> <span class="o">{</span>
</span><span class='line'> <span class="k">return</span> <span class="n">links</span><span class="o">.</span><span class="na">forAction</span><span class="o">(</span><span class="err">“</span><span class="n">get</span><span class="err">”</span><span class="o">);</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>The methods for the links are particularly useful when navigating the API in a way an actual client would in tests. Having defined a class representing a body of JSON, let’s move on to the class for performing assertions against this body of JSON.</p>
<h2>Class for performing asserts against a body of JSON</h2>
<p>Having a class for performing assertions against a particular body of JSON helps us achieve two goals: 1) write more expressive test code and 2) have assertions that can be reused across tests. For example, there may be several tests that require asserting the title for a particular job returned by the API. We may also want to verify the presence or absence of certain hypermedia links. The following code illustrates an “asserts” class for a job representation.</p>
<figure class='code'><figcaption><span>JobRepresentationAsserts.java</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">JobRepresentationAsserts</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'> <span class="kd">private</span> <span class="kd">final</span> <span class="n">JobRepresentation</span> <span class="n">representation</span><span class="o">;</span>
</span><span class='line'>
</span><span class='line'> <span class="o">...</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">hasTitleOf</span><span class="o">(</span><span class="n">String</span> <span class="n">title</span><span class="o">)</span>
</span><span class='line'> <span class="o">{</span>
</span><span class='line'> <span class="n">assertEquals</span><span class="o">(</span><span class="n">title</span><span class="o">,</span> <span class="n">representation</span><span class="o">.</span><span class="na">details</span><span class="o">.</span><span class="na">title</span><span class="o">);</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'>
</span><span class='line'> <span class="o">...</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">hasLikeLink</span><span class="o">()</span>
</span><span class='line'> <span class="o">{</span>
</span><span class='line'> <span class="n">assertTrue</span><span class="o">(</span><span class="n">representation</span><span class="o">.</span><span class="na">likeLink</span><span class="o">().</span><span class="na">isPresent</span><span class="o">());</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">doesNotHaveLikeLink</span><span class="o">()</span>
</span><span class='line'> <span class="o">{</span>
</span><span class='line'> <span class="n">assertFalse</span><span class="o">(</span><span class="n">representation</span><span class="o">.</span><span class="na">likeLink</span><span class="o">().</span><span class="na">isPresent</span><span class="o">());</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">hasUnlikeLink</span><span class="o">()</span>
</span><span class='line'> <span class="o">{</span>
</span><span class='line'> <span class="n">assertTrue</span><span class="o">(</span><span class="n">representation</span><span class="o">.</span><span class="na">unlikeLink</span><span class="o">().</span><span class="na">isPresent</span><span class="o">());</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">doesNotHaveUnlikeLink</span><span class="o">()</span>
</span><span class='line'> <span class="o">{</span>
</span><span class='line'> <span class="n">assertFalse</span><span class="o">(</span><span class="n">representation</span><span class="o">.</span><span class="na">unlikeLink</span><span class="o">().</span><span class="na">isPresent</span><span class="o">());</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>In addition to these “asserts” classes, I created a class with static builder methods to provide some syntactic sugar. This allows us to write our tests in a given/when/then fashion. This builder class is as follows:</p>
<figure class='code'><figcaption><span>AssertsBuilder.java</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">AssertsBuilder</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'> <span class="o">...</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="kd">static</span> <span class="n">JobRepresentationAsserts</span> <span class="nf">thenThe</span><span class="o">(</span><span class="n">JobRepresentation</span> <span class="n">representation</span><span class="o">)</span>
</span><span class='line'> <span class="o">{</span>
</span><span class='line'> <span class="k">return</span> <span class="k">new</span> <span class="nf">JobRepresentationAsserts</span><span class="o">(</span><span class="n">representation</span><span class="o">);</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'>
</span><span class='line'> <span class="o">...</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>This results in something like the following in a test:</p>
<figure class='code'><figcaption><span>Sample job test</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kn">import</span> <span class="nn">static</span> <span class="n">com</span><span class="o">.</span><span class="na">theladders</span><span class="o">.</span><span class="na">AssertsBuilder</span><span class="o">.*;</span>
</span><span class='line'>
</span><span class='line'><span class="o">...</span>
</span><span class='line'>
</span><span class='line'><span class="n">JobRepresentation</span> <span class="n">job</span> <span class="o">=</span> <span class="n">apiCallToGetJob</span><span class="o">();</span>
</span><span class='line'><span class="n">thenThe</span><span class="o">(</span><span class="n">job</span><span class="o">).</span><span class="na">hasTitleOf</span><span class="o">(</span><span class="err">“</span><span class="n">Software</span> <span class="n">Engineer</span><span class="err">”</span><span class="o">);</span>
</span><span class='line'><span class="n">thenThe</span><span class="o">(</span><span class="n">job</span><span class="o">).</span><span class="na">hasLikeLink</span><span class="o">();</span>
</span></code></pre></td></tr></table></div></figure>
<p>We’re not there yet, but we’re making progress. So far we have the following:</p>
<ul>
<li>Class for representing incoming/outgoing bodies of JSON</li>
<li>Class for performing assertions against a particular body of JSON</li>
<li>Some syntactic sugar for creating assert-related objects.</li>
</ul>
<p>The next piece of the puzzle is a class representing the actions that can be taken on a body of JSON.</p>
<h2>Class representing the actions that can be taken on a body of JSON</h2>
<p>What exactly do I mean by “taking actions on a body of JSON”. “Actions” can include anything from selecting an individual item in a list (a job in a list of jobs) to calling a URL associated with a hypermedia link. So why the need for a separate class encapsulating these “actions” when we already have a representation class for a body of JSON (which includes hypermedia links)? The reason is rooted in the fact that our representation classes are used in production code for serialization purposes (a topic worthy of its own blog post), and I didn’t want to mix in testing concerns with our representation classes for something like calling the API via TestRestClient. So I decided to create a different type of class for this purpose. I called this the “actions” class.</p>
<p>Let’s take a look at JSON containing a list of jobs as an example. If a user is viewing a list of jobs, it’s reasonable to expect they might want to “do something” with a particular job. This would be captured with something like the following:</p>
<figure class='code'><figcaption><span>JobListActions.java</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">JobListActions</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'> <span class="kd">public</span> <span class="n">UserAndClient</span> <span class="n">userAndClient</span><span class="o">;</span> <span class="c1">// this class represents a user and their connection to the API and will be discussed next.</span>
</span><span class='line'> <span class="kd">public</span> <span class="n">JobListRepresentation</span> <span class="n">representation</span><span class="o">;</span>
</span><span class='line'>
</span><span class='line'> <span class="o">...</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="n">JobActions</span> <span class="nf">actingOnJobAtIndex</span><span class="o">(</span><span class="kt">int</span> <span class="n">index</span><span class="o">)</span>
</span><span class='line'> <span class="o">{</span>
</span><span class='line'> <span class="k">return</span> <span class="k">new</span> <span class="nf">JobActions</span><span class="o">(</span><span class="n">userAndClient</span><span class="o">,</span> <span class="n">representation</span><span class="o">.</span><span class="na">jobs</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">index</span><span class="o">));</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>JobListActions by itself isn’t necessarily interesting, but it does provide a nice way for indicating what job a user is acting upon in a test. The next code listing is more interesting, providing methods for performing various “actions” an individual job.</p>
<figure class='code'><figcaption><span>JobActions.java</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">JobActions</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'> <span class="kd">private</span> <span class="kd">final</span> <span class="n">UserAndClient</span> <span class="n">userAndClient</span><span class="o">;</span> <span class="c1">// this class represents a user and their connection to the API and will be discussed next</span>
</span><span class='line'> <span class="kd">private</span> <span class="kd">final</span> <span class="n">JobRepresentation</span> <span class="n">representation</span><span class="o">;</span>
</span><span class='line'>
</span><span class='line'> <span class="o">...</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="n">Response</span><span class="o"><</span><span class="n">JobRepresentation</span><span class="o">></span> <span class="nf">like</span><span class="o">()</span>
</span><span class='line'> <span class="o">{</span>
</span><span class='line'> <span class="n">Optional</span><span class="o"><</span><span class="n">HypermediaLink</span><span class="o">></span> <span class="n">link</span> <span class="o">=</span> <span class="n">representation</span><span class="o">.</span><span class="na">likeLink</span><span class="o">();</span>
</span><span class='line'> <span class="k">return</span> <span class="k">new</span> <span class="n">Response</span><span class="o"><>(</span><span class="n">userAndClient</span><span class="o">.</span><span class="na">client</span><span class="o">.</span><span class="na">post</span><span class="o">(</span><span class="n">link</span><span class="o">.</span><span class="na">get</span><span class="o">()),</span> <span class="n">JobRepresentation</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="n">Response</span><span class="o"><</span><span class="n">JobRepresentation</span><span class="o">></span> <span class="nf">unlike</span><span class="o">()</span>
</span><span class='line'> <span class="o">{</span>
</span><span class='line'> <span class="n">Optional</span><span class="o"><</span><span class="n">HypermediaLink</span><span class="o">></span> <span class="n">link</span> <span class="o">=</span> <span class="n">representation</span><span class="o">.</span><span class="na">unlikeLink</span><span class="o">();</span>
</span><span class='line'> <span class="k">return</span> <span class="k">new</span> <span class="n">Response</span><span class="o"><>(</span><span class="n">userAndClient</span><span class="o">.</span><span class="na">client</span><span class="o">.</span><span class="na">post</span><span class="o">(</span><span class="n">link</span><span class="o">.</span><span class="na">get</span><span class="o">()),</span> <span class="n">JobRepresentation</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>This class contains methods for liking and un-liking a job. This is done by using the TestRestClient found in UserAndClient (more on this next) to make calls to the API via the hypermedia links. The Response class that is returned from these methods is a simple wrapper class for a JAX-RS response and looks like the following:</p>
<figure class='code'><figcaption><span>Response.java</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Response</span><span class="o"><</span><span class="n">T</span><span class="o">></span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'> <span class="kd">private</span> <span class="kd">final</span> <span class="n">javax</span><span class="o">.</span><span class="na">ws</span><span class="o">.</span><span class="na">rs</span><span class="o">.</span><span class="na">core</span><span class="o">.</span><span class="na">Response</span> <span class="n">response</span><span class="o">;</span>
</span><span class='line'> <span class="kd">private</span> <span class="kd">final</span> <span class="n">Class</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="n">responseBodyType</span><span class="o">;</span>
</span><span class='line'>
</span><span class='line'> <span class="o">...</span>
</span><span class='line'>
</span><span class='line'> <span class="kd">public</span> <span class="kt">int</span> <span class="nf">status</span><span class="o">()</span>
</span><span class='line'> <span class="o">{</span>