friends 0.34 → 0.35

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,323 +3,7 @@
3
3
  require "date"
4
4
 
5
5
  require "./test/helper"
6
-
7
- def date_parsing_specs(test_stdout: true)
8
- describe "date parsing" do
9
- let(:description) { "Test." }
10
-
11
- describe "when date is in YYYY-MM-DD" do
12
- let(:date) { "2017-01-01" }
13
-
14
- it { line_added "- #{date}: #{description}" }
15
- it { stdout_only "Activity added: \"#{date}: #{description}\"" } if test_stdout
16
- end
17
-
18
- describe "when date is in MM-DD-YYYY" do
19
- let(:date) { "01-02-2017" }
20
-
21
- it { line_added "- 2017-01-02: #{description}" }
22
- it { stdout_only "Activity added: \"2017-01-02: #{description}\"" } if test_stdout
23
- end
24
-
25
- describe "when date is invalid" do
26
- let(:date) { "2017-02-30" }
27
-
28
- it { line_added "- 2017-03-02: #{description}" }
29
- it { stdout_only "Activity added: \"2017-03-02: #{description}\"" } if test_stdout
30
- end
31
-
32
- describe "when date is natural language and in full" do
33
- let(:date) { "February 23rd, 2017" }
34
-
35
- it { line_added "- 2017-02-23: #{description}" }
36
- it { stdout_only "Activity added: \"2017-02-23: #{description}\"" } if test_stdout
37
- end
38
-
39
- describe "when date is natural language and only month and day" do
40
- # We use two days rather than just one to avoid strange behavior around
41
- # edge cases when the test is being run right around midnight.
42
- let(:two_days_in_seconds) { 2 * 24 * 60 * 60 }
43
- let(:raw_date) { Time.now + two_days_in_seconds }
44
- let(:date) { raw_date.strftime("%B %d") }
45
- let(:expected_year) { raw_date.strftime("%Y").to_i - 1 }
46
- let(:expected_date_str) { "#{expected_year}-#{raw_date.strftime('%m-%d')}" }
47
-
48
- it { line_added "- #{expected_date_str}: #{description}" }
49
- it { stdout_only "Activity added: \"#{expected_date_str}: #{description}\"" } if test_stdout
50
- end
51
- end
52
- end
53
-
54
- def description_parsing_specs(test_stdout: true)
55
- describe "description parsing" do
56
- let(:date) { Date.today.strftime }
57
-
58
- describe "when description includes a friend's full name (case insensitive)" do
59
- let(:description) { "Lunch with grace hopper." }
60
-
61
- it { line_added "- #{date}: Lunch with **Grace Hopper**." }
62
- it { stdout_only "Activity added: \"#{date}: Lunch with Grace Hopper.\"" } if test_stdout
63
- end
64
-
65
- describe "when description includes a friend's first name (case insensitive)" do
66
- let(:description) { "Lunch with grace." }
67
-
68
- it { line_added "- #{date}: Lunch with **Grace Hopper**." }
69
- it { stdout_only "Activity added: \"#{date}: Lunch with Grace Hopper.\"" } if test_stdout
70
- end
71
-
72
- describe "when description has a friend's first name and last initial (case insensitive)" do
73
- describe "when followed by no period" do
74
- let(:description) { "Lunch with grace h" }
75
-
76
- it { line_added "- #{date}: Lunch with **Grace Hopper**" }
77
- it { stdout_only "Activity added: \"#{date}: Lunch with Grace Hopper\"" } if test_stdout
78
- end
79
-
80
- describe "when followed by a period at the end of a sentence" do
81
- let(:description) { "Met grace h. So fun!" }
82
-
83
- it { line_added "- #{date}: Met **Grace Hopper**. So fun!" }
84
- it { stdout_only "Activity added: \"#{date}: Met Grace Hopper. So fun!\"" } if test_stdout
85
- end
86
-
87
- describe "when followed by a period at the end of the description" do
88
- let(:description) { "Lunch with grace h." }
89
-
90
- it { line_added "- #{date}: Lunch with **Grace Hopper**." }
91
- it { stdout_only "Activity added: \"#{date}: Lunch with Grace Hopper.\"" } if test_stdout
92
- end
93
-
94
- describe "when followed by a period in the middle of a sentence" do
95
- let(:description) { "Met grace h. at 12." }
96
-
97
- it { line_added "- #{date}: Met **Grace Hopper** at 12." }
98
- it { stdout_only "Activity added: \"#{date}: Met Grace Hopper at 12.\"" } if test_stdout
99
- end
100
- end
101
-
102
- describe "when description includes a friend's nickname (case insensitive)" do
103
- let(:description) { "Lunch with the admiral." }
104
-
105
- it { line_added "- #{date}: Lunch with **Grace Hopper**." }
106
- it { stdout_only "Activity added: \"#{date}: Lunch with Grace Hopper.\"" } if test_stdout
107
- end
108
-
109
- describe "when description includes a friend's nickname which contains a name" do
110
- let(:description) { "Lunch with Amazing Grace." }
111
-
112
- it { line_added "- #{date}: Lunch with **Grace Hopper**." }
113
- it { stdout_only "Activity added: \"#{date}: Lunch with Grace Hopper.\"" } if test_stdout
114
- end
115
-
116
- describe "when description includes a friend's name at the beginning of a word" do
117
- # Capitalization reduces chance of a false positive.
118
- let(:description) { "Gracefully strolled." }
119
-
120
- it { line_added "- #{date}: Gracefully strolled." }
121
- it { stdout_only "Activity added: \"#{date}: Gracefully strolled.\"" } if test_stdout
122
- end
123
-
124
- describe "when description includes a friend's name at the end of a word" do
125
- # Capitalization reduces chance of a false positive.
126
- let(:description) { "The service was a disGrace." }
127
-
128
- it { line_added "- #{date}: The service was a disGrace." }
129
- it { stdout_only "Activity added: \"#{date}: The service was a disGrace.\"" } if test_stdout
130
- end
131
-
132
- describe "when description includes a friend's name in the middle of a word" do
133
- # Capitalization reduces chance of a false positive.
134
- let(:description) { "The service was disGraceful." }
135
-
136
- it { line_added "- #{date}: The service was disGraceful." }
137
- it { stdout_only "Activity added: \"#{date}: The service was disGraceful.\"" } if test_stdout
138
- end
139
-
140
- describe "when a friend's name is escaped with a backslash" do
141
- # We have to use four backslashes here because of Ruby's backslash escaping; when this
142
- # goes through all of the layers of this test it emerges on the other side as a single one.
143
- let(:description) { "Dinner with \\\\Grace Kelly." }
144
-
145
- it { line_added "- #{date}: Dinner with Grace Kelly." }
146
- it { stdout_only "Activity added: \"#{date}: Dinner with Grace Kelly.\"" } if test_stdout
147
- end
148
-
149
- describe "hyphenated name edge cases" do
150
- describe "when one name precedes another before a hyphen" do
151
- let(:description) { "Shopped w/ Mary-Kate." }
152
-
153
- # Make sure "Mary" is a closer friend than "Mary-Kate" so we know our
154
- # test result isn't due to chance.
155
- let(:content) do
156
- <<-FILE
157
- ### Activities:
158
- - 2017-01-01: Singing with **Mary Poppins**.
159
-
160
- ### Friends:
161
- - Mary Poppins
162
- - Mary-Kate Olsen
163
-
164
- ### Locations:
165
- FILE
166
- end
167
-
168
- it { line_added "- #{date}: Shopped w/ **Mary-Kate Olsen**." }
169
- it { stdout_only "Activity added: \"#{date}: Shopped w/ Mary-Kate Olsen.\"" } if test_stdout
170
- end
171
-
172
- describe "when one name follows another after a hyphen" do
173
- let(:description) { "Shopped w/ Mary-Kate." }
174
-
175
- # Make sure "Kate" is a closer friend than "Mary-Kate" so we know our
176
- # test result isn't due to chance.
177
- let(:content) do
178
- <<-FILE
179
- ### Activities:
180
- - 2017-01-01: Improv with **Kate Winslet**.
181
-
182
- ### Friends:
183
- - Kate Winslet
184
- - Mary-Kate Olsen
185
-
186
- ### Locations:
187
- FILE
188
- end
189
-
190
- it { line_added "- #{date}: Shopped w/ **Mary-Kate Olsen**." }
191
- it { stdout_only "Activity added: \"#{date}: Shopped w/ Mary-Kate Olsen.\"" } if test_stdout
192
- end
193
-
194
- describe "when one name is contained within another via hyphens" do
195
- let(:description) { "Met Mary-Jo-Kate." }
196
-
197
- # Make sure "Jo" is a closer friend than "Mary-Jo-Kate" so we know our
198
- # test result isn't due to chance.
199
- let(:content) do
200
- <<-FILE
201
- ### Activities:
202
- - 2017-01-01: Singing with **Jo Stafford**.
203
-
204
- ### Friends:
205
- - Jo Stafford
206
- - Mary-Jo-Kate Olsen
207
-
208
- ### Locations:
209
- FILE
210
- end
211
-
212
- it { line_added "- #{date}: Met **Mary-Jo-Kate Olsen**." }
213
- it { stdout_only "Activity added: \"#{date}: Met Mary-Jo-Kate Olsen.\"" } if test_stdout
214
- end
215
- end
216
-
217
- describe "when description has a friend's name with leading asterisks" do
218
- let(:description) { "Lunch with **Grace Hopper." }
219
-
220
- it { line_added "- #{date}: Lunch with **Grace Hopper." }
221
- it { stdout_only "Activity added: \"#{date}: Lunch with **Grace Hopper.\"" } if test_stdout
222
- end
223
-
224
- describe "when description has a friend's name with trailing asterisks" do
225
- # Note: We can't guarantee that "Grace Hopper**" doesn't match because the "Grace" isn't
226
- # surrounded by asterisks.
227
- let(:description) { "Lunch with Grace**." }
228
-
229
- it { line_added "- #{date}: Lunch with Grace**." }
230
- it { stdout_only "Activity added: \"#{date}: Lunch with Grace**.\"" } if test_stdout
231
- end
232
-
233
- describe "when description has a friend's name multiple times" do
234
- let(:description) { "Grace! Grace!!!" }
235
-
236
- it { line_added "- #{date}: **Grace Hopper**! **Grace Hopper**!!!" }
237
- it { stdout_only "Activity added: \"#{date}: Grace Hopper! Grace Hopper!!!\"" } if test_stdout
238
- end
239
-
240
- describe "when description has a name with multiple friend matches" do
241
- describe "when there is useful context from past activities" do
242
- let(:description) { "Met John + Elizabeth." }
243
-
244
- # Create a past activity in which Elizabeth Cady Stanton did something
245
- # with John Cage. Then, create past activities to make Elizabeth II a
246
- # better friend than Elizabeth Cady Stanton.
247
- let(:content) do
248
- <<-FILE
249
- ### Activities:
250
- - 2017-01-05: Picnic with **Elizabeth Cady Stanton** and **John Cage**.
251
- - 2017-01-04: Got lunch with **Elizabeth II**.
252
- - 2017-01-03: Ice skated with **Elizabeth II**.
253
-
254
- ### Friends:
255
- - Elizabeth Cady Stanton
256
- - Elizabeth II
257
- - John Cage
258
-
259
- ### Locations:
260
- FILE
261
- end
262
-
263
- # Elizabeth II is the better friend, but historical activities have
264
- # had Elizabeth Cady Stanton and John Cage together. Thus, we should
265
- # interpret "Elizabeth" as Elizabeth Cady Stanton.
266
- it { line_added "- #{date}: Met **John Cage** + **Elizabeth Cady Stanton**." }
267
- if test_stdout
268
- it { stdout_only "Activity added: \"#{date}: Met John Cage + Elizabeth Cady Stanton.\"" }
269
- end
270
- end
271
-
272
- describe "when there is no useful context from past activities" do
273
- let(:description) { "Dinner with John and Elizabeth." }
274
-
275
- # Create a past activity in which Elizabeth Cady Stanton did something
276
- # with John Cage. Then, create past activities to make Elizabeth II a
277
- # better friend than Elizabeth Cady Stanton.
278
- let(:content) do
279
- <<-FILE
280
- ### Activities:
281
- - 2017-01-03: Ice skated with **Elizabeth II**.
282
-
283
- ### Friends:
284
- - Elizabeth Cady Stanton
285
- - Elizabeth II
286
- - John Cage
287
-
288
- ### Locations:
289
- FILE
290
- end
291
-
292
- # Pick the "Elizabeth" with more activities.
293
- it { line_added "- #{date}: Dinner with **John Cage** and **Elizabeth II**." }
294
- if test_stdout
295
- it { stdout_only "Activity added: \"#{date}: Dinner with John Cage and Elizabeth II.\"" }
296
- end
297
- end
298
- end
299
-
300
- describe "when description contains a location name (case insensitive)" do
301
- let(:description) { "Lunch at a cafe in paris." }
302
-
303
- it { line_added "- #{date}: Lunch at a cafe in _Paris_." }
304
- it { stdout_only "Activity added: \"#{date}: Lunch at a cafe in Paris.\"" } if test_stdout
305
- end
306
-
307
- describe "when description contains both names and locations" do
308
- let(:description) { "Grace and I went to Atlantis and then Paris for lunch with George." }
309
-
310
- it do
311
- line_added "- #{date}: **Grace Hopper** and I went to _Atlantis_ and then _Paris_ for "\
312
- "lunch with **George Washington Carver**."
313
- end
314
- if test_stdout
315
- it do
316
- stdout_only "Activity added: \"#{date}: Grace Hopper and I went to Atlantis and then "\
317
- "Paris for lunch with George Washington Carver.\""
318
- end
319
- end
320
- end
321
- end
322
- end
6
+ require "./test/add_event_helper"
323
7
 
324
8
  clean_describe "add activity" do
325
9
  let(:content) { CONTENT }
@@ -332,6 +16,8 @@ clean_describe "add activity" do
332
16
  - 2017-01-01: Activity 1.
333
17
  - 2016-01-01: Activity one year earlier.
334
18
 
19
+ ### Notes:
20
+
335
21
  ### Friends:
336
22
 
337
23
  ### Locations:
@@ -356,6 +42,8 @@ FILE
356
42
  - 2017-01-01: Activity 1.
357
43
  - 2016-01-01: Activity one year earlier.
358
44
 
45
+ ### Notes:
46
+
359
47
  ### Friends:
360
48
 
361
49
  ### Locations:
@@ -363,37 +51,5 @@ FILE
363
51
  end
364
52
  end
365
53
 
366
- describe "when given a date and a description in the command" do
367
- subject { run_cmd("add activity #{date}: #{description}") }
368
-
369
- date_parsing_specs
370
- description_parsing_specs
371
- end
372
-
373
- describe "when given only a date in the command" do
374
- subject { run_cmd("add activity #{date}", stdin_data: description) }
375
-
376
- # We don't try to test the STDOUT here because our command prompt produces other STDOUT that's
377
- # hard to test.
378
- date_parsing_specs(test_stdout: false)
379
- description_parsing_specs(test_stdout: false)
380
- end
381
-
382
- describe "when given only a description in the command" do
383
- subject { run_cmd("add activity #{description}") }
384
-
385
- # We don't test date parsing since in this case the date is always inferred to be today.
386
-
387
- description_parsing_specs
388
- end
389
-
390
- describe "when given neither a date nor a description in the command" do
391
- subject { run_cmd("add activity", stdin_data: description) }
392
-
393
- # We don't test date parsing since in this case the date is always inferred to be today.
394
-
395
- # We don't try to test the STDOUT here because our command prompt produces other STDOUT that's
396
- # hard to test.
397
- description_parsing_specs(test_stdout: false)
398
- end
54
+ parsing_specs(event: :activity)
399
55
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+
5
+ require "./test/helper"
6
+ require "./test/add_event_helper"
7
+
8
+ clean_describe "add note" do
9
+ let(:content) { CONTENT }
10
+
11
+ describe "date ordering" do
12
+ let(:content) do
13
+ <<-FILE
14
+ ### Activities:
15
+
16
+ ### Notes:
17
+ - 2018-01-01: Note one year later.
18
+ - 2017-01-01: Note 1.
19
+ - 2016-01-01: Note one year earlier.
20
+
21
+ ### Friends:
22
+
23
+ ### Locations:
24
+ FILE
25
+ end
26
+
27
+ subject do
28
+ 4.times do |i|
29
+ run_cmd("add note 2017-01-01: Note #{i + 2}.")
30
+ end
31
+ end
32
+
33
+ it "orders dates by insertion time" do
34
+ subject
35
+ File.read(filename).must_equal <<-FILE
36
+ ### Activities:
37
+
38
+ ### Notes:
39
+ - 2018-01-01: Note one year later.
40
+ - 2017-01-01: Note 5.
41
+ - 2017-01-01: Note 4.
42
+ - 2017-01-01: Note 3.
43
+ - 2017-01-01: Note 2.
44
+ - 2017-01-01: Note 1.
45
+ - 2016-01-01: Note one year earlier.
46
+
47
+ ### Friends:
48
+
49
+ ### Locations:
50
+ FILE
51
+ end
52
+ end
53
+
54
+ parsing_specs(event: :note)
55
+ end
@@ -25,6 +25,8 @@ clean_describe "clean" do
25
25
  file_equals <<-FILE
26
26
  ### Activities:
27
27
 
28
+ ### Notes:
29
+
28
30
  ### Friends:
29
31
 
30
32
  ### Locations:
@@ -33,10 +35,30 @@ clean_describe "clean" do
33
35
  end
34
36
 
35
37
  describe "when file has content" do
36
- let(:content) { SCRAMBLED_CONTENT }
38
+ describe "when content is formatted correctly" do
39
+ let(:content) { SCRAMBLED_CONTENT }
40
+
41
+ it "writes the file with contents sorted" do
42
+ file_equals CONTENT
43
+ end
44
+ end
45
+
46
+ describe "when a header is malformed" do
47
+ let(:content) do
48
+ <<-FILE
49
+ ### Activities:
50
+
51
+ ### Garbage:
52
+
53
+ ### Friends:
54
+
55
+ ### Locations:
56
+ FILE
57
+ end
37
58
 
38
- it "writes the file with contents sorted" do
39
- file_equals CONTENT
59
+ it "prints an error message" do
60
+ stderr_only 'Error: Expected "a valid header" on line 3'
61
+ end
40
62
  end
41
63
  end
42
64
  end