-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathbookbytes-018.json
More file actions
1870 lines (1870 loc) · 83.3 KB
/
bookbytes-018.json
File metadata and controls
1870 lines (1870 loc) · 83.3 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
{
"note": "Do not edit this file directly. Edit the txt file and then run the convertTranscript script to generate this file.",
"podcast": "BookBytes",
"episode": "18",
"transcript": [
{
"text": "(Intro music: Electro Swing)"
},
{
"timestamp": "0:00:12.6",
"speaker": "Adam Garrett-Harris",
"text": "Hello and welcome to BookBytes, a book club podcast for developers. We’re continuing our- No, it’s not even the Summer anymore, we’re like, into the Fall with this Imposter’s Syndrome. We’re talking about The Imposter’s Handbook: A CS Primer for Self-Taught Programmers by Rob Conery. So we’re gonna go over the last two chapters, chapters 14 and 15 which is “Testing” and “Essential Unix.”"
},
{
"timestamp": "0:00:36.2",
"speaker": "Adam Garrett-Harris",
"text": "I’m Adam Garrett-Harris."
},
{
"timestamp": "0:00:38.3",
"speaker": "Safia Abdalla",
"text": "I’m Safia Abdalla."
},
{
"timestamp": "0:00:40.2",
"speaker": "Jen Luker",
"text": "I’m Jen Luker."
},
{
"timestamp": "0:00:41.3",
"speaker": "Jason Staten",
"text": "And I’m Jason Staten."
},
{
"timestamp": "0:00:43.0",
"speaker": "Adam Garrett-Harris",
"text": "So, we’ve been doing this book news section and one we haven’t mentioned yet is the sequel to this book is coming out, which is Season Two of Imposter’s Handbook and it’s for sale right now, currently in presale which means you can read it in advance and then submit issues on GitHub if you see any problems with it. And it’s written by Rob Conery and his friend Scott Hanselman."
},
{
"timestamp": "0:01:11.9",
"speaker": "Jason Staten",
"text": "I’m excited."
},
{
"timestamp": "0:01:13.0",
"speaker": "Adam Garrett-Harris",
"text": "Yeah! Did you look at the topics?"
},
{
"timestamp": "0:01:15.7",
"speaker": "Jason Staten",
"text": "I did once before and I do not know them off of the top of my head right now but I know looking at it I was like, “All right, I’m ready for this.”"
},
{
"timestamp": "0:01:25.2",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, it looks like he’s doing a real deep dive into information flow all the way from binary to encoding and network protocols."
},
{
"timestamp": "0:01:36.2",
"speaker": "Jason Staten",
"text": "Nice!"
},
{
"timestamp": "0:01:37.0",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, so I’m pretty excited. We, I don’t know if we’ll talk about it on here yet, but it is available for people to read."
},
{
"timestamp": "0:01:43.1",
"speaker": "Jason Staten",
"text": "Yeah, we’re already lined up for the next one."
},
{
"timestamp": "0:01:45.0",
"speaker": "Adam Garrett-Harris",
"text": "Yeah! So I should mention that. Our next book is “Code Girls.”"
},
{
"timestamp": "0:01:48.2",
"speaker": "Jen Luker",
"text": "I’m pretty excited about that one."
},
{
"timestamp": "0:01:49.8",
"speaker": "Adam Garrett-Harris",
"text": "Yeah. Yeah, do you want to give a quick explanation what that’s about?"
},
{
"timestamp": "0:01:52.8",
"speaker": "Jen Luker",
"text": "No."
},
{
"timestamp": "0:01:53.4",
"speaker": "Adam Garrett-Harris",
"text": "No? (laughs)"
},
{
"timestamp": "0:01:54.1",
"speaker": "Jason Staten",
"text": "(laughs)"
},
{
"timestamp": "0:01:54.8",
"speaker": "Adam Garrett-Harris",
"text": "So that’s about the women who helped crack the enemy codes during World War II and yeah, I’m pretty excited about that, too."
},
{
"timestamp": "0:02:05.1",
"speaker": "Jen Luker",
"text": "I didn’t give my description because I haven’t started reading it yet, so."
},
{
"timestamp": "0:02:09.3",
"speaker": "Adam Garrett-Harris",
"text": "(laughs) I mean, yeah. I’m… I’m into it, I don’t know how far, but it’s kind of a long book."
},
{
"timestamp": "0:02:17.5",
"speaker": "Jen Luker",
"text": "Hmm. But we’re breaking it up though, aren’t we?"
},
{
"timestamp": "0:02:20.7",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, yeah."
},
{
"timestamp": "0:02:22.0",
"speaker": "Jen Luker",
"text": "Into not chapters but…"
},
{
"timestamp": "0:02:25.0",
"speaker": "Adam Garrett-Harris",
"text": "Parts. I think there’s three parts."
},
{
"timestamp": "0:02:27.3",
"speaker": "Jen Luker",
"text": "Yeah, three episodes."
},
{
"timestamp": "0:02:29.1",
"speaker": "Adam Garrett-Harris",
"text": "So, let’s get into testing."
},
{
"text": "(Typewriter Dings)"
},
{
"timestamp": "0:02:33.0",
"speaker": "Jason Staten",
"text": "This is definitely an opinionated-"
},
{
"timestamp": "0:02:35.9",
"speaker": "Jen Luker",
"text": "(laughs)"
},
{
"timestamp": "0:02:36.6",
"speaker": "Jason Staten",
"text": "Topic in the industry, for sure. And I guess, sound off real quick. Do you do test driven development and with that is it all the time, some of the time, or rarely if ever?"
},
{
"timestamp": "0:02:52.5",
"speaker": "Jen Luker",
"text": "Some of the time."
},
{
"timestamp": "0:02:54.1",
"speaker": "Safia Abdalla",
"text": "For me it depends on the context and the open source project that I work on. We’ve got pretty heavy test driven development going on, good coverage and all that. At work I think it depends on a lot of different factors and tends to be like a personal choice with the developer, but we do have things like tests running on pull request filters and tests on pre-commit hooks and pre-push hooks and stuff like that. So there’s like, set up an infrastructure for it but it’s not like a super strict, “You have to put in a test first and then start coding.” It’s just, “You should have a test with every pull request you merge.”"
},
{
"timestamp": "0:03:37.5",
"speaker": "Adam Garrett-Harris",
"text": "Yeah. So for me at work we do test driven development almost all the time. The exception is for things that are harder to test or would be more fragile like how the UI looks. So all of the backend is TDD and in the frontend where it makes sense. What about you, Jason?"
},
{
"timestamp": "0:04:02.1",
"speaker": "Jason Staten",
"text": "I would say that I fall in somewhere between that sometimes, not too often. I used to be more of an advocate of it, and like, I guess more of a practitioner of it and that kind of fell off as time went on. Like, I guess when I was writing Ruby it was just what you did and so that’s what I did and a factor in that was that with Ruby because when you have so many dynamic features related to it if you are not running a test suite then you will find all sorts of issues at production time and so, it was really necessary. ‘Cause it was like, full on spell checker. Like, if you typo’d something you would not know until your code was executing whereas in other environments you have a little bit more help from the tooling on that. And so it’s led to probably a little bit more lax standards than where I should be at, but that’s my realm."
},
{
"timestamp": "0:04:56.5",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, I feel like things like TypeScript or aesthetically typed languages really reduce the number of tests you need. So with JavaScript you might have a test that ensures that it returns a number or something and you don’t need those kinds of tests with TypeScript."
},
{
"timestamp": "0:05:13.3",
"speaker": "Jason Staten",
"text": "Yeah, that’s a thing that I’ve really liked about working in Rust over the course of this book, has been its type system. It’s pretty rigorous on many of the things that you’re doing and not doing. It’s not even just the semantics of like, are you returning the correct type but also are the contracts you’re making about like, are you going to mutate this data? Or like, if you’re trying to mutate data but you haven’t said that you want to then the compiler will actually prevent you from doing that. And so you get a level of guarantees that just come from the tooling that you don’t actually have to write a test for. And so it’s not that you don’t have to write tests but you get a good number of them checked for you all the time just as you write and compile the code."
},
{
"timestamp": "0:05:58.3",
"speaker": "Safia Abdalla",
"text": "Yeah, that’s a good point, Jason. And I think it touches a little bit going further into the chapter on the distinction that he provided between behavior driven development and test driven development with the notion that, you know, when you’re writing a test using TDD you’re generally doing something like, testing all of the inputs, testing different values, all of that stuff. It’s like, very, I think the word he used to describe it was clinical. And when you’re doing behavior driven development, you know, you’re testing kind of user workflows, and I think one of the things with TypeScript is that it takes away a lot of that clinical checking that you would have to do in tests like you mentioned and it puts it in the type checker."
},
{
"timestamp": "0:06:39.7",
"text": "And that’s why as I was reading this I realized that nowadays when I’m writing code most of the tests I’m writing are not like, tests as in the TDD style but more behavior driven tests like, testing out the full user workflow for a feature that I’m adding, and that tends to just kind of fit better in with the way I develop software. So, you know, you get assigned a task to do and usually the task is “add a feature,” and when I’m adding a feature I think about like, the full user story and the behavior around it and test that, but not necessarily test like, “Does this button render this way when I do this?” Or, “If I pass null to this will it do that?”"
},
{
"timestamp": "0:07:21.1",
"speaker": "Jason Staten",
"text": "Hmm."
},
{
"timestamp": "0:07:21.6",
"speaker": "Adam Garrett-Harris",
"text": "Yeah. When I think of behavior driven development I think of the idea that the names of the tests should be readable to a stakeholder. And I think he mentions in the book it’s very rare for a stakeholder to ever actually do that, like nobody exports the names of their tests and then hands them over to a business person and then says, “Here’s what the code does.” But it gets you thinking in more of that mindset, I guess."
},
{
"timestamp": "0:07:48.2",
"speaker": "Safia Abdalla",
"text": "Yeah, and I definitely do find myself thinking in more of that mindset, like around business logic when I’m coding."
},
{
"timestamp": "0:07:56.4",
"speaker": "Adam Garrett-Harris",
"text": "Now are those still unit tests or are they more like integration or acceptance tests?"
},
{
"timestamp": "0:08:01.1",
"speaker": "Safia Abdalla",
"text": "The way I’ve written them they’re set up as unit tests, a few of them are integration tests just ‘cause they made sense with the existing set up that we had, but yeah, for the most part they’re unit tests."
},
{
"timestamp": "0:08:12.3",
"speaker": "Adam Garrett-Harris",
"text": "Cool."
},
{
"timestamp": "0:08:13.1",
"speaker": "Jason Staten",
"text": "I do tend to think of them as being something that’s a little bit higher than unit, at least like, when I hear the comparison of them. And maybe not full on integration, like starting up your whole application, but the thing that I like about doing that sort of style, like testing multiple pieces or like the bigger picture of things is it gives you more flexibility when you’re writing code, and I guess in particular more flexibility to make changes to your code. One thing that I’ve run into before with doing test driven development is because the model of my coding was driven by all of my tests when I was to go back and make changes to my code, any time I would do that potentially you would get like, 10 tests failed because I went and removed this line. And it’s kind of discouraging to have like, a whole bunch of tests fail just because you changed like, one thing."
},
{
"timestamp": "0:09:06.5",
"text": "I mean, it’s good that they’re there and they’re checking it, like that’s what you want. But at the same time, like, the amount of maintenance that can come from a test suite made it that way can be burdensome. And I know that if done properly, like, it should be straightforward but I maybe hadn’t gotten to the point of doing it quite properly, but doing some of those slightly higher level, or behavior style tests where it’s like, these things need to happen, but the details are a little bit less important and may not be asserting on those, but like, as long as I give this input and get my desired end goal output in terms of more feature or behaviorish, then I’m happy. And you know, the details can slide a little bit more."
},
{
"timestamp": "0:09:51.2",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, I’ve had that kind of issue. Typically when that happens it means I’m testing something that should be like, a private method because it’s just implementation detail and I’m tempted to want to test those things because it’s part of the code that I’m writing, but really, if it’s not part of the API or something I shouldn’t be testing that method, probably."
},
{
"timestamp": "0:10:14.4",
"speaker": "Jason Staten",
"text": "One other thing that I came across during the process of doing Rust, and I’ve seen it in the past as well with other languages, and it’s called QuickCheck, which is for property testing. And I think I originally saw it in Haskell, but QuickCheck is a way of saying that I want to test the method and assert some property about it. Like, for an example, if I were to go and create a reverse function that reversed an array then I could go and say that for all inputs that are an array that if I reverse it and then reverse it again, it will be equivalent to the original input."
},
{
"timestamp": "0:10:55.7",
"speaker": "Adam Garrett-Harris",
"text": "Hmm."
},
{
"timestamp": "0:10:56.5",
"speaker": "Jason Staten",
"text": "And so what QuickCheck will do is it will call your function some number of times, like a huge number of times with a whole bunch of randomly generated inputs, and if it succeeds then you just get like, a passing test. But if it fails then what it’ll try and do is actually reduce the input set to the smallest possible reproduction case. So that way like, if it fails with a list of 1,000 items in it, it may just be that your reversal algorithm doesn’t handle having nulls in the list or something like that, and it can boil it down to like, that “It’s having null in here that is actually making the failure case.”"
},
{
"timestamp": "0:11:33.4",
"speaker": "Adam Garrett-Harris",
"text": "That is interesting. It sounds a lot like in Elm, there’s a thing called Fuzz Testing."
},
{
"timestamp": "0:11:37.5",
"speaker": "Jason Staten",
"text": "Mm-hmm (affirmative)."
},
{
"timestamp": "0:11:38.1",
"speaker": "Adam Garrett-Harris",
"text": "And you kind of just say like, “Hey, run this test 100 times with various inputs.” And then if it fails you can see why."
},
{
"timestamp": "0:11:45.3",
"speaker": "Jason Staten",
"text": "Yeah, that sounds really similar. I used the same mechanism for testing when I was writing the various sorting algorithms for earlier in the book to assert that any of my sorting algorithms, whatever output they produced had to be the same as whatever the built in output of Rust built in sort was."
},
{
"timestamp": "0:12:05.8",
"speaker": "Adam Garrett-Harris",
"text": "Hmm."
},
{
"timestamp": "0:12:05.1",
"speaker": "Jason Staten",
"text": "Because I assumed, like, Rust’s built in sort is going to be correct."
},
{
"timestamp": "0:12:08.8",
"speaker": "Adam Garrett-Harris",
"text": "(laughs)"
},
{
"timestamp": "0:12:08.8",
"speaker": "Jason Staten",
"text": "Like, if not there’s something seriously wrong. And so knowing that I am fallible and likely to write an algorithm that is not quite right, if I go and put QuickCheck against it say, for any given input it needs to match the Rust implementation then I know that my implementation is true for that property."
},
{
"timestamp": "0:12:28.1",
"speaker": "Adam Garrett-Harris",
"text": "So, I want to ask y’all, for those of you that don’t use TDD very much, which I guess is all three of you, why not? I guess I should say who don’t use it all the time."
},
{
"timestamp": "0:12:40.8",
"speaker": "Safia Abdalla",
"text": "Yeah, I would say for me sometimes it’s like, things need to get pushed out the door really quickly ‘cause there are deadlines and there’s just like, no time to test. And I know this sounds bad and terrible and all that, but like, usually they’re kind of the first thing to go or, you know, you’ll add tests later but it never gets done, things like that. And usually it's just like in situations where there’s urgency around getting something shipped and there’s not a ton of time to be like,very formulated about it. I would say that’s one example, and other cases mostly it’s just been like, the testing infrastructure isn’t there. You’re trying to test this new component or interface and like, you don't know how to set up the mocks properly because no one’s ever done it before. And there’s all of these weird, like, modules being injected and how do you test that?"
},
{
"timestamp": "0:13:32.8",
"text": "So just like, sometimes, the setup for tests isn’t really well done and that discourages you from writing the test because well, now you have to go out and like, set up your testing environment before you can even actually get to work. But other than that, if I know, like, a test is going to be easy to add or I know what I need to do to actually like, set up a unit test and like, I’m in no rush to get something out the door, I’ll do it."
},
{
"timestamp": "0:13:59.9",
"speaker": "Jen Luker",
"text": "For me, it’s not that I don’t do it all the time, even though it’s not really all the time, it just depends on what it is I’m writing. It just seems like not every single bit of code needs to be unit tested. It’s mostly the crud functions that most specifically need it more than, I don’t know, a small little function that doesn’t really do much."
},
{
"timestamp": "0:14:23.0",
"speaker": "Safia Abdalla",
"text": "Yeah."
},
{
"timestamp": "0:14:23.0",
"speaker": "Adam Garrett-Harris",
"text": "Yeah. I think trying to achieve 100% test coverage is not… not good."
},
{
"timestamp": "0:14:29.2",
"speaker": "Jen Luker",
"text": "Right."
},
{
"timestamp": "0:14:29.2",
"speaker": "Safia Abdalla",
"text": "Yeah, I agree."
},
{
"timestamp": "0:14:29.7",
"speaker": "Jen Luker",
"text": "So, for me it’s more like the test driven development happens much more efficiently and much more effectively if I know what I’m writing is going to be larger than a 3-line function. So-"
},
{
"timestamp": "0:14:43.2",
"speaker": "Adam Garrett-Harris",
"text": "Mm-hmm (affirmative)."
},
{
"timestamp": "0:14:43.8",
"speaker": "Jen Luker",
"text": "It has to do with the purpose for the test. It’s not just for testing the method it’s for making sure that what you’re writing is also clean and efficient and doesn’t include a lot of extra code that you won’t necessarily need. It’s about trying to make sure that you only write the bare minimum of what you need in order to get a test to pass, and then making sure that it fails in the right spots, too."
},
{
"timestamp": "0:15:12.4",
"speaker": "Adam Garrett-Harris",
"text": "Mm-hmm (affirmative)."
},
{
"timestamp": "0:15:12.9",
"speaker": "Jen Luker",
"text": "So it just seems like, for me, it’s more to do with complexity of the thing that I’m testing than it does with the function of that class or object or function."
},
{
"timestamp": "0:15:28.2",
"speaker": "Adam Garrett-Harris",
"text": "Cool."
},
{
"timestamp": "0:15:29.1",
"speaker": "Jason Staten",
"text": "I’m kind of in that same camp of not having quite the same infrastructure, or correct infrastructure to build out stuff well. Like, sometimes it is the mocking story and I know that like, that is a sign that whatever thing that I’m depending on may not be correctly, like, isolated or something like that."
},
{
"timestamp": "0:15:51.0",
"speaker": "Adam Garrett-Harris",
"text": "So like, if it’s hard to test then that may be a sign that it’s not designed well? Is that what you’re trying to say? Or…"
},
{
"timestamp": "0:15:58.7",
"speaker": "Jason Staten",
"text": "Yeah. I would say, like, if your code isn’t testable, like that can be, it can be sign. Like, it doesn’t necessarily for sure like, say like, “Oh, this is poorly designed.” I mean, sometimes there are things that are difficult to test and have to be for one reason or another. I mean, maybe they’re just inherently complex or involve a lot of dependencies. Maybe it’s like an orchestration type class that pulls in a lot of stuff. Then yeah, that can be pretty painful to test."
},
{
"timestamp": "0:16:30.6",
"text": "I actually find myself blaming, in particular working with React during the day, I find myself that I don’t really enjoy writing tests for React. When it’s a small project it’s not too big of a deal, but like, if it grows and it’s something that say, has like, Redux and internationalization and other things that involve React-like context, making those tests and like, the setup process for them is just a pain to deal with. And please direct me if I’m not right on that front, but I find myself more prone to writing tests for if I’m making a just straight JavaScript module that has a bunch of more, like, utility-esque functions that take in an input and give out an output. I am more apt to actually go and do those TDD. But with React I find that it’s painful and it doesn’t excite me to actually go and write the tests. I’m like, “Oh what’s all the boilerplate that I have to write to even make this thing successfully run?”"
},
{
"timestamp": "0:17:30.5",
"text": "And then the other thing, too, is a lot of times, at least in the way that I try and write my code, is that there aren’t too many branches and conditions so it’s basically just asserting it like, if I set this prop on this thing, like, it’s gonna render this way."
},
{
"timestamp": "0:17:43.5",
"speaker": "Adam Garrett-Harris",
"text": "(laughs)"
},
{
"timestamp": "0:17:44.7",
"speaker": "Jason Staten",
"text": "And that’s that. And then I feel like this is a super valuable test."
},
{
"timestamp": "0:17:49.1",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, but then you don’t want to test like, “Oh, the background color is this, and the borders are rounded, and how’s this text?” Because-"
},
{
"timestamp": "0:17:57.0",
"speaker": "Jason Staten",
"text": "It’s-"
},
{
"timestamp": "0:17:57.2",
"speaker": "Adam Garrett-Harris",
"text": "That’s gonna change all the time."
},
{
"timestamp": "0:17:58.6",
"speaker": "Jason Staten",
"text": "Yeah."
},
{
"timestamp": "0:17:59.5",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, I totally agree. With React it’s not fun and probably not necessary."
},
{
"timestamp": "0:18:03.7",
"speaker": "Jen Luker",
"text": "I still feel like there has to be some sort of… I mean we have different types of tests for reasons, right? Like, we have our unit tests for trying to make sure that the complexity that we’re coding is limited, whereas the other tests that we’re writing, such as behavior driven, would be much more closely related to like, crud processes making sure that what we’re coding actually functions the same way in the long run. So even if we go in and modify our code to be completely different and fail our unit tests, it may still pass our behavioral or functional tests because of what we need it to do is still the same. I feel that no matter what, you need to have some sort of behavioral tests when it comes to your crud processes. Crud being like, create, read, update, and delete."
},
{
"timestamp": "0:18:56.2",
"speaker": "Adam Garrett-Harris",
"text": "Yeah."
},
{
"timestamp": "0:18:55.4",
"speaker": "Jen Luker",
"text": "Whereas the unit tests are much more for us and making sure that our complexity stays limited."
},
{
"timestamp": "0:19:05.1",
"speaker": "Safia Abdalla",
"text": "Yeah, and I think that’s why oftentimes the things that I see most unit tested, like Jason mentioned, are things like, utility files where you’re like, checking that something formats a date correctly or makes some kind of, like, numerical computation correctly as opposed to like those entire behavioral workflows."
},
{
"timestamp": "0:19:24.4",
"speaker": "Adam Garrett-Harris",
"text": "Yeah."
},
{
"timestamp": "0:19:25.3",
"speaker": "Jason Staten",
"text": "I’ve talked about Gary Bernhardt a couple of times because I really enjoy watching his talks and screencasts, and one of his screen casts that he made was one that was called “Functional Core, Imperative Shell.” And the idea was that you have, kind of two different segments in your application, there’s not like a specific hard line drawn, but it becomes obvious as you’re building out different components or different module of your application in that like, the core of your application should be written in more of a functional style where it’s very much a pipeline of things. Like, it’s functions just passing output to other functions and not really stateful. And those types of things are pretty straightforward to test and so, like, you’re able to go and make a nice test suite against them and they're not dependent on external things like databases and whatnot. And so they are also really fast because he’s adamant about having a really fast test suite because slow test suites also are discouraging."
},
{
"timestamp": "0:20:27.9",
"speaker": "Adam Garrett-Harris",
"text": "Mm-hmm (affirmative)."
},
{
"timestamp": "0:20:28.5",
"speaker": "Jason Staten",
"text": "I thought about that today because I have been refactoring a massive amount of tests at work. And then on the flip of it there is the imperative shell so it is the code that is very stateful and deals with things like user input and like, database and/or screen output or something like that. And on that side it says like, testing here is, it’s way more difficult and way less beneficial. And so the goal is like, you want to have that core as big as you can, so you can have a like, a thoroughly tested application, but those things on the edges, like, because they’re difficult like the benefit of actually doing it can be much lower."
},
{
"timestamp": "0:21:10.9",
"speaker": "Safia Abdalla",
"text": "Yeah."
},
{
"timestamp": "0:21:11.5",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, yeah. I really want to take that business logic out of that shell and make them as dumb as possible and just very presentational. Yeah, I like that. That like you can test those things, but it’s hard and it has like, decreasing benefits."
},
{
"timestamp": "0:21:25.5",
"speaker": "Safia Abdalla",
"text": "I think like, one of the things about testing your code is you have to like, really analyze and understand the complexity and interconnectedness of how the software you’re working on works to be able to like, isolate things and test them well enough. ‘Cause I’ve definitely seen situations where like, someone will like, write unit tests for something and they’ll like, look good, and you know, you’ll merge them and you’ll go ahead and then like, three months later there’s like a huge bug discovered that those same unit tests didn’t catch because there wasn’t an understanding of like, the complexity and the side effects caused by a particular bit of code."
},
{
"timestamp": "0:22:05.5",
"speaker": "Adam Garrett-Harris",
"text": "Hmm."
},
{
"timestamp": "0:22:06.1",
"speaker": "Safia Abdalla",
"text": "Like, writing unit tests in and of itself is like writing a feature or fixing a bug. Like, I don’t think it’s just like icing you put on a cake or something like that. It definitely is part of like, the cake batter. That was a terrible, what am I doing with this analogy? (laughs)"
},
{
"timestamp": "0:22:20.9",
"speaker": "Jason Staten",
"text": "(laughs)"
},
{
"timestamp": "0:22:22.6",
"speaker": "Adam Garrett-Harris",
"text": "I like it. I like it, keep going."
},
{
"timestamp": "0:22:23.7",
"speaker": "Jason Staten",
"text": "Yeah."
},
{
"timestamp": "0:22:24.1",
"speaker": "Safia Abdalla",
"text": "Yeah, but I definitely think it’s like, test code is code in and of itself, and like, architecting it, when we were talking earlier about having good test infrastructure, figuring out when you write test and when you don’t is the same as figuring out when you write code and where you don’t."
},
{
"timestamp": "0:22:40.0",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, and refactoring your tests can be as important as refactoring your code."
},
{
"timestamp": "0:22:44.1",
"speaker": "Safia Abdalla",
"text": "Yeah. And I think one of the things even when we like, maybe I’m just getting the wrong impression of it, even when we talk about test driven development it still treats tests as this kind of entity that is separate from your code base and like, additive. When really I think what makes it hard is you have to figure out a way to write code that is like, customer facing, and code that is developer facing. For example your tests, this could also be like your configurations and stuff like that, that like, work as one. And when those two things clash together I think is when it gets really hard to write tests."
},
{
"timestamp": "0:23:21.8",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, I really like having my test files right next to the thing I’m testing as opposed to stashed away in some other folder that you forget to look at."
},
{
"timestamp": "0:23:29.8",
"speaker": "Safia Abdalla",
"text": "Yeah, I agree. And I think that’s one of the reasons that for the open source project I work on has a really good testing culture, it’s ‘cause we kind of adopt that kind of philosophy of having your tests in the same directory as your components or your source files."
},
{
"timestamp": "0:23:45.1",
"speaker": "Jen Luker",
"text": "So I want to add to that a bit in that one of the benefits of having the files themselves co-located in the same folder, and not just your tests but also your CSS and you know, any other additional pieces that you have and that nesting them is that when that feature no longer used you just delete the entire folder."
},
{
"timestamp": "0:24:03.5",
"speaker": "Adam Garrett-Harris",
"text": "Yeah."
},
{
"timestamp": "0:24:04.0",
"speaker": "Jen Luker",
"text": "So it’s writing code for deletion later."
},
{
"timestamp": "0:24:08.3",
"speaker": "Safia Abdalla",
"text": "Yeah. And I feel like this whole putting your tests next to your source thing, maybe I’m just not as experienced with this, was like, kind of a fairly new approach to get popular? Or was this something that was just always done and I was not aware of it?"
},
{
"timestamp": "0:24:25.7",
"speaker": "Jen Luker",
"text": "I don’t think it was necessarily always done. I do think that with increased understanding of Webpack and how it’s utilized it’s starting to become much more popular. Before it was just easier to say, “Okay, it’s in this folder. We’re just gonna do it that way because you can just import it and test it and run it that way.” But I think as people just dive deeper into our bundlers it’s easier to understand."
},
{
"timestamp": "0:24:53.8",
"speaker": "Safia Abdalla",
"text": "Yeah."
},
{
"timestamp": "0:24:53.8",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, that’s a good point. It used to be easier to say, “Here’s all my test files in this folder. Run those tests.”"
},
{
"timestamp": "0:24:59.1",
"speaker": "Jen Luker",
"text": "Mm-hmm (affirmative)."
},
{
"timestamp": "0:24:59.5",
"speaker": "Adam Garrett-Harris",
"text": "And tell your bundler, “Here’s all my source files, bundle every single file in this folder whether I need it or not.” So you don’t want to put your tests in there and then ship those to customers."
},
{
"timestamp": "0:25:09.7",
"speaker": "Jen Luker",
"text": "And I don’t think it’s that complicated anymore. I think the people understand how to set it up initially in a way that you can do both without complexity."
},
{
"timestamp": "0:25:23.4",
"speaker": "Jason Staten",
"text": "This is another case that I actually get to share a little bit of love for Rust, and that is that you don’t even write your test in a separate file, but you actually write them in the same file as your code. Like, in terms of unit tests, you would go and you’d just make an additional module inside of your current file that you’re working on, generally it’s called test. And it gets compiled away like, during any production build, but it exists during test builds."
},
{
"timestamp": "0:25:52.0",
"text": "And secondly when you go and you set up a new project using cargo, their package manager, it’s got cargo test built into it, so you don’t have to go figure out a testing framework whether you want to use TAP or tape or Jest or QUnit, or whatever other thing that you ought to. Like, they have one that’s just there that’s built in when you start a project. Like, you have testing infrastructure that already exists and you don’t have to make any decisions on that front which is really nice for getting a good testing culture."
},
{
"timestamp": "0:26:29.2",
"speaker": "Safia Abdalla",
"text": "I think those two things are really closely connected, like culture and infrastructure. ‘Cause I think when you’re writing a test, like, you’re not just writing it for yourself, you’re writing it for everybody who’s going to be reviewing your PR or touching that code after you. And I always think like, that’s the first… well, I think for anything code related, the first thing if you want to change your code base you have to change your culture first. And sometimes some teams have a poor testing culture, some have a medium, some have a really good one that’s stringent. And I think it tends to be like, super dependent on the business."
},
{
"timestamp": "0:27:05.4",
"text": "Like, I remember one of my first jobs was working at Bank of America and they had like, a really solid testing culture, obviously because they were a bank, but also because they would get audited before every software release and part of the audit was looking through their tests and making sure that like, everything was tested correctly."
},
{
"timestamp": "0:27:25.6",
"text": "And so that kind of like, I guess business climate influenced team culture which influenced how well their testing infrastructure was set up. Like, they had really good testing infrastructure there. I don’t know, we could probably talk for hours about infrastructure and culture and tests and all of that good stuff."
},
{
"timestamp": "0:27:43.8",
"speaker": "Jen Luker",
"text": "I also want to say that there’s a difference between a stringent testing culture and a good testing culture in that, you know, as we’ve mentioned before but I really want to reiterate it here, that reaching 100% test coverage is really brutal and isn’t always necessary. So there can be cases where it’s too stringent and that makes it much more painful for anything to happen. So I think that separating those two things and saying healthy test culture-"
},
{
"timestamp": "0:28:16.9",
"speaker": "Safia Abdalla",
"text": "Hmm."
},
{
"timestamp": "0:28:18.2",
"speaker": "Jen Luker",
"text": "Is better than saying stringent is equal to good."
},
{
"timestamp": "0:28:21.3",
"speaker": "Safia Abdalla",
"text": "Ditto what she said, basically. But I agree, I think that it’s not just about the stringent ness. I don’t think anything software related should be judged on how stringent it is because I think that’s where you get into areas that are very dark and not good and bad. But I do think just… There’s a certain level of like, accountability that you have to have as a team to make sure that you’re building a healthy testing culture."
},
{
"timestamp": "0:28:47.2",
"speaker": "Adam Garrett-Harris",
"text": "Nice. Shall we move on to Essential Unix?"
},
{
"timestamp": "0:28:51.6",
"speaker": "Jason Staten",
"text": "Yes."
},
{
"timestamp": "0:28:52.1",
"speaker": "Safia Abdalla",
"text": "Sure."
},
{
"timestamp": "0:28:53.2",
"speaker": "Adam Garrett-Harris",
"text": "All right, but first we’ve got a sponsor."
},
{
"timestamp": "0:28:55.3",
"speaker": "Jen Luker",
"text": "Yay!"
},
{
"text": "(Typewriter Dings)"
},
{
"timestamp": "0:28:57.2",
"speaker": "Adam Garrett-Harris",
"text": "This episode of BookBytes is brought to you by V School. Established in 2013, V School is Utah’s highest ranked coding boot camp, and the first of its kind in Utah! They really care about diversity, they partnered with Adobe to provide inclusion based scholarships to foster a diverse workforce. And you can choose to learn full-time, or part-time in the evenings."
},
{
"timestamp": "0:29:15.8",
"text": "You’ll immerse yourself in learning new skills like React, or full-stack development. They take care of everything you need so you can just focus on learning, including free housing if you need it and this is really cool ‘cause it’s just a few blocks from school and you can, or you can actually learn from home in their virtual classroom. You’ll get a super transcript when you finish, it’s like a portfolio, transcript, and letter of recommendation all in one, and it will help an employer to quickly understand your strengths, abilities, and then the work you’ve accomplished."
},
{
"timestamp": "0:29:45.0",
"text": "They encourage you to take a campus tour, meet their students, faculty, and even shadow a class to see if it’s a good fit for you. If you go visit, tell them you heard about them on BookBytes. Check out VSchool.io, that’s the letter “V” School dot io."
},
{
"timestamp": "0:29:59.1",
"text": "V School. Life awaits. Launch a career in code, design, or data. And thanks to V School for sponsoring the show."
},
{
"text": "(Typewriter Dings)"
},
{
"text": "________________"
},
{
"timestamp": "0:30:09.4",
"speaker": "Adam Garrett-Harris",
"text": "So, Unix! I always think saying unix out loud is really weird because it sounds like something else."
},
{
"timestamp": "0:30:16.1",
"speaker": "Safia Abdalla",
"text": "It sounds like a pokemon."
},
{
"timestamp": "0:30:16.8",
"speaker": "Adam Garrett-Harris",
"text": "E-, it sounds like E-U-, how do you spell it?"
},
{
"timestamp": "0:30:20.8",
"speaker": "Jen Luker",
"text": "Mm-hmm (affirmative)."
},
{
"timestamp": "0:30:21.6",
"speaker": "Adam Garrett-Harris",
"text": "You know what I’m talking about?"
},
{
"timestamp": "0:30:23.5",
"speaker": "Jen Luker",
"text": "Yes."
},
{
"timestamp": "0:30:23.9",
"speaker": "Adam Garrett-Harris",
"text": "E-U-N-O-C-H?"
},
{
"timestamp": "0:30:26.0",
"speaker": "Jen Luker",
"text": "Yes."
},
{
"timestamp": "0:30:26.6",
"speaker": "Safia Abdalla",
"text": "No. I know the word you’re talking about but I’ve never said it out loud or heard it. So…"
},
{
"timestamp": "0:30:32.6",
"speaker": "Adam Garrett-Harris",
"text": "Yep, yeah. It’s, a eunuch is a man who’s been castrated."
},
{
"timestamp": "0:30:37.0",
"speaker": "Safia Abdalla",
"text": "(laughs) I was not expecting that definition to come up."
},
{
"timestamp": "0:30:41.5",
"speaker": "Jason Staten",
"text": "You learn something every day."
},
{
"timestamp": "0:30:43.3",
"speaker": "Safia Abdalla",
"text": "Yeah."
},
{
"timestamp": "0:30:46.4",
"speaker": "Adam Garrett-Harris",
"text": "Moving on."
},
{
"timestamp": "0:30:46.9",
"speaker": "Safia Abdalla",
"text": "Okay."
},
{
"timestamp": "0:30:47.3",
"speaker": "Jen Luker",
"text": "Yes, please."
},
{
"timestamp": "0:30:51.8",
"speaker": "Adam Garrett-Harris",
"text": "So what did y’all think of this chapter?"
},
{
"timestamp": "0:30:55.3",
"speaker": "Safia Abdalla",
"text": "I thought it was interesting. I had prior understanding of a lot of the things that were mentioned so some of it wasn’t, it wasn’t as like, eye-opening as some of the other chapters. But I really appreciated the like, Make section and talking about the history of BuildTools and why most programming languages tend to have their own build tools, because Make came from the deepest pits of hell."
},
{
"timestamp": "0:31:24.9",
"speaker": "Jason Staten",
"text": "(laughs)"
},
{
"timestamp": "0:31:26.8",
"speaker": "Adam Garrett-Harris",
"text": "Wait, did it say that in here?"
},
{
"timestamp": "0:31:28.2",
"speaker": "Safia Abdalla",
"text": "No, that was my language."
},
{
"timestamp": "0:31:30.0",
"speaker": "Adam Garrett-Harris",
"text": "So, I’ve never used Make. I’ve heard of Make, I’ve heard of Jake and Rake, but yeah, when I learned about Make in this book I thought, “That’s really cool! Like, you could just use that in pretty much any language you’re writing code in.”"
},
{
"timestamp": "0:31:42.3",
"speaker": "Safia Abdalla",
"text": "Yeah. It gets really complicated really fast. I remember-"
},
{
"timestamp": "0:31:46.9",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, I’m sure."
},
{
"timestamp": "0:31:46.9",
"speaker": "Safia Abdalla",
"text": "Working on some things and you’d just have like, Make files and you would have to like, track down references within the Make file, and it just got like, really hard to navigate."
},
{
"timestamp": "0:31:58.8",
"speaker": "Adam Garrett-Harris",
"text": "Yeah."
},
{
"timestamp": "0:31:59.4",
"speaker": "Jason Staten",
"text": "Also, I did on the topic of Make, he talks about going and building a JavaScript project with it as an example and that was something that you, I guess, you can still do and did previously used to where he goes and just concatenates all the files together, and it brings you back to the days of like, having a whole bunch of self-evaluating functions wrapping everything ‘cause it all got dumped on the global. And so you didn’t really write stuff in modular form."
},
{
"timestamp": "0:32:31.9",
"text": "Or I guess you did and you wrote it in like, AMD syntax which like, wrapping everything in a “define” or something like that. Like, that’s what that brought back memories of and I don’t miss doing that. Especially because like, you still have, there’s some concerns about like, ordering and whatnot. And like, the solution of numbering things doesn’t really work out well as you really scale stuff out and so it’s actually like, the case where I started to see value in some of the bundlers such as Webpack or Rollup or Parcel or whatever other slew of other ones."
},
{
"timestamp": "0:33:14.3",
"text": "Like, in terms of like, grunt and gulp you could use Make in place of them or NPM scripts for that matter, which is just a task runner that’s even, it’s even simpler than Make ‘cause it doesn’t have like, depencies and whatnot in it. But things like Webpack and the others, they actually go and are parsing your code base and creating a dependency graph in order to figure out ordering of loading of things. And so like, they certainly do a lot more than just going and cancatinating your files together. So I think some of the additional stuff that they do, like the going and minifying after the fact is something that you could go and hand off to like, a piping, like, using Unix Pipes, which, hey we haven’t really talked a lot about yet but we can get into, but you know, like handing it off through that process. That is something you could do. Like, with minification after the fact, but there is value in what they do and like, just substituting Make for it is going to mean that you’re definitely down in those pits of hell trying to figure out your dependencies."
},
{
"timestamp": "0:34:21.9",
"speaker": "Adam Garrett-Harris",
"text": "Make is not recommended for JavaScript in 2018."
},
{
"timestamp": "0:34:25.1",
"speaker": "Jason Staten",
"text": "(laughs)"
},
{
"timestamp": "0:34:25.8",
"speaker": "Jen Luker",
"text": "No."
},
{
"timestamp": "0:34:26.5",
"speaker": "Adam Garrett-Harris",
"text": "Totally agree, yeah."
},
{
"timestamp": "0:34:27.2",
"speaker": "Jason Staten",
"text": "(laughs)"
},
{
"timestamp": "0:34:28.1",
"speaker": "Adam Garrett-Harris",
"text": "I was like, that’s an interesting example, but I don’t do it."
},
{
"timestamp": "0:34:32.2",
"speaker": "Safia Abdalla",
"text": "It definitely is a good way to like, look under the hood of what’s going on in some of the build tools that exist currently, ‘cause I definitely do think one of the like, overwhelming things about BuildTools is that they are a little opaque for some people, especially if you’re like a beginner. So I think this chapter would be really helpful to go through if you just want to like, get a sense of what’s going on under the hood. Or what it looks like is going on under the hood."
},
{
"timestamp": "0:34:56.9",
"speaker": "Adam Garrett-Harris",
"text": "Yeah. So I thought this chapter, speaking of pipes, I thought this chapter was gonna be more about really kind of basic commands you would run in Unix like CD and LS and kind of the Unix philosophy of each of these programs or these tiny little programs that do one thing and do it really well, and the open/close principle where we’re not gonna change that program if you want some additional functionality. You pipe the output of that program into another program to extend the functionality. It kind of got into a little bit, I guess. ‘Cause he writes a shell script later on in the chapter."
},
{
"timestamp": "0:35:31.1",
"speaker": "Jason Staten",
"text": "It is true. Like, I mean we talked about standard in and standard out but..."
},
{
"timestamp": "0:35:36.2",
"speaker": "Adam Garrett-Harris",
"text": "Yeah."
},
{
"timestamp": "0:35:36.6",
"speaker": "Jason Staten",
"text": "I don’t know if I actually caught it. Like, the whole like, Unix philosophy that like, everything is a file. Like, that’s kind of a core concept as well is like, you should be able to go open up anything. Like, if you want to go and like, open up your mouse device and start piping that through sed or something else, you can do that. You may get complete garbage that’s handed through, but everything lives on your file system, but just like, as a file. Like, and-"
},
{
"timestamp": "0:36:07.1",
"speaker": "Adam Garrett-Harris",
"text": "Hmm."
},
{
"timestamp": "0:36:07.0",
"speaker": "Jason Staten",
"text": "It appears the same with, you know, caveats here and there because modern Unix doesn’t do that."
},
{
"timestamp": "0:36:13.7",
"speaker": "Adam Garrett-Harris",
"text": "So what does that mean, exactly? Can you expand on that idea of everything is a file."
},
{
"timestamp": "0:36:18.4",
"speaker": "Jason Staten",
"text": "Yeah, so for example, if you go and, this is speaking more to Linux. I am, I find myself digging less at the internals when I’m on OS10. And like, say you were to go and like, plug a mouse into your computer then if you look under a directory at like, the root of your file system, like you’d have a folder called /dev inside of there."
},
{
"timestamp": "0:36:46.7",
"speaker": "Adam Garrett-Harris",
"text": "Hmm."
},
{
"timestamp": "0:36:47.4",
"speaker": "Jason Staten",
"text": "And if you list everything that’s inside of /dev, yeah, it exists on OS10, too. But if you list in there, like, you’ll notice that there’s a whole bunch of things in there that are like, devices. And it’s like, a device is not a file, but in fact, like, the way that the kernel handles it it actually does turn it into a file. Like, every USB device is just a file that you can go and you can write to and read from if you want to."
},
{
"timestamp": "0:37:12.8",
"speaker": "Adam Garrett-Harris",
"text": "Is it using that file? Like when the mouse moved around? Is it like writing stuff to that file?"
},
{
"timestamp": "0:37:20.0",
"speaker": "Jason Staten",
"text": "Yeah, like if you... I don’t know which particular file that it would be, but like, yeah you could find your mouse and you could start piping that into cat if you wanted to and you could watch what it looks like when your mouse moves. And like you could create any application to go and to listen to that. What’s cool about that is like, it’s sharing that same interface across like, whatever thing that you’re using. Like, if you actually writing to a file or if you ‘re talking to a piece of hardware, or yeah. It’s just everything winds up being a, having that same interface of just being a file that you can go and open up and read from and write to. It’s like, just an input/output system."
},
{
"timestamp": "0:38:01.5",
"speaker": "Adam Garrett-Harris",
"text": "Yeah, that’s cool."
},
{
"timestamp": "0:38:02.3",
"speaker": "Jason Staten",
"text": "Yeah, I guess I don’t step back and appreciate the value of that enough and so that is a positive that came from the chapters, thinking on that. Also I’m glad that he brings up Vim as well, ‘cause I’m a Vim user, myself."
},
{
"timestamp": "0:38:16.5",
"speaker": "Adam Garrett-Harris",
"text": "Yay! Vim!"
},
{
"timestamp": "0:38:17.9",
"speaker": "Jason Staten",
"text": "(laughs)"
},
{
"timestamp": "0:38:17.9",
"speaker": "Safia Abdalla",
"text": "(laughs)"
},
{
"timestamp": "0:38:18.6",
"speaker": "Jason Staten",
"text": "Heh, yeah. Yay Vim! I would say that like, it seemed a little strange. Like, if you’re trying to learn Unix, like, getting dropped into Vim, like gives you the sense of like, I brand this command and I can’t escape from it now."
},
{
"timestamp": "0:38:34.4",
"speaker": "Safia Abdalla",
"text": "(laughs)"
},
{
"timestamp": "0:38:35.1",
"speaker": "Jason Staten",
"text": "Like, does that…"
},
{
"timestamp": "0:38:35.7",
"speaker": "Adam Garrett-Harris",
"text": "(laughs) Yeah."
},
{
"timestamp": "0:38:36.5",
"speaker": "Jason Staten",
"text": "That certainly happens and so like, I mean, having to learn how to bat, like-"
},
{
"timestamp": "0:38:40.5",
"speaker": "Adam Garrett-Harris",
"text": "And also your Vim will not look as pretty as his if it’s the first time you’re using it."
},
{
"timestamp": "0:38:44.8",
"speaker": "Jason Staten",
"text": "Yeah. Like, it will be be pretty plain and you… Yeah, it won’t even have like syntax highlighting or anything like that to begin with and so I also would say with caution, like if you’re going to learn Unix, like, you don’t have to learn Vim and the same time. You will only-"
},
{
"timestamp": "0:38:59.6",
"speaker": "Adam Garrett-Harris",
"text": "Or Emacs."
},
{
"timestamp": "0:39:00.5",
"speaker": "Jason Staten",
"text": "Or Emacs-"
},
{
"timestamp": "0:39:01.3",
"speaker": "Jen Luker",
"text": "Mm-hmm (affirmative)."
},
{
"timestamp": "0:39:01.7",
"speaker": "Jason Staten",
"text": "Like, I’m not a big promoter of GNU Nano but it is also like, what you would probably expect."
},
{
"timestamp": "0:39:07.4",
"speaker": "Jen Luker",