friends 0.34 → 0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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