friends 0.29 → 0.30
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +6 -0
- data/.travis.yml +2 -5
- data/CHANGELOG.md +15 -0
- data/PULL_REQUEST_TEMPLATE.md +2 -2
- data/README.md +41 -6
- data/bin/friends +7 -0
- data/friends.gemspec +3 -4
- data/lib/friends/commands/graph.rb +4 -2
- data/lib/friends/commands/list.rb +8 -27
- data/lib/friends/graph.rb +1 -0
- data/lib/friends/introvert.rb +67 -30
- data/lib/friends/serializable.rb +1 -1
- data/lib/friends/version.rb +1 -1
- data/test/commands/graph_spec.rb +34 -0
- data/test/commands/list/activities_spec.rb +36 -0
- data/test/commands/list/favorite/friends_spec.rb +84 -2
- data/test/commands/list/favorite/locations_spec.rb +88 -1
- data/test/commands/list/friends_spec.rb +25 -0
- data/test/helper.rb +14 -4
- metadata +14 -29
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81e378aa8d3e1a7285adcb3f92cc91977c22eca2
|
4
|
+
data.tar.gz: f48b3ccd7d4006679c7b072b06a980432c759a6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee11daf225f5c245b68a732267b0fafd7041d478d8cff7d68860f9b50a71f9a3db51de2edd4a7dac723a6db5c5c26045a697a21bc7215acc770bed3a2390ee10
|
7
|
+
data.tar.gz: e47d850e7cc62ea74a0c212f0315de2cc5bd1eb72f331526ccee67dd39d7599b091a546770d14ba2af7132f929ab8d9076f61b28cb8a68a36432ccda3d481f56
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -125,6 +125,9 @@ Lambda:
|
|
125
125
|
LambdaCall:
|
126
126
|
Enabled: false
|
127
127
|
|
128
|
+
Layout/IndentHeredoc:
|
129
|
+
Enabled: false
|
130
|
+
|
128
131
|
LineEndConcatenation:
|
129
132
|
Enabled: false
|
130
133
|
|
@@ -235,6 +238,9 @@ StringLiterals:
|
|
235
238
|
Style/MultilineBlockChain:
|
236
239
|
Enabled: false
|
237
240
|
|
241
|
+
Style/SymbolArray:
|
242
|
+
EnforcedStyle: brackets
|
243
|
+
|
238
244
|
VariableInterpolation:
|
239
245
|
Enabled: false
|
240
246
|
|
data/.travis.yml
CHANGED
@@ -5,10 +5,7 @@ rvm:
|
|
5
5
|
- 2.3.0
|
6
6
|
- 2.4.0
|
7
7
|
script:
|
8
|
-
|
9
|
-
|
10
|
-
addons:
|
11
|
-
code_climate:
|
12
|
-
repo_token: d744a74c96e3e5c763ed776709aff0662ac2f3e8274c01e439e09b38c8be4225
|
8
|
+
- bundle exec rake test
|
9
|
+
- bundle exec rubocop
|
13
10
|
notifications:
|
14
11
|
email: false
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [v0.30](https://github.com/JacobEvelyn/friends/tree/v0.30) (2017-05-30)
|
4
|
+
[Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.29...v0.30)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- Code coverage in README is too low [\#163](https://github.com/JacobEvelyn/friends/issues/163)
|
9
|
+
- Improve display of favorites for ties [\#158](https://github.com/JacobEvelyn/friends/issues/158)
|
10
|
+
- Filter activities based on more than one friend/tag/etc. [\#88](https://github.com/JacobEvelyn/friends/issues/88)
|
11
|
+
|
12
|
+
**Merged pull requests:**
|
13
|
+
|
14
|
+
- Be able to filter output by more than one friend or tag [\#168](https://github.com/JacobEvelyn/friends/pull/168) ([JacobEvelyn](https://github.com/JacobEvelyn))
|
15
|
+
- Improve display of favorites for ties [\#165](https://github.com/JacobEvelyn/friends/pull/165) ([JacobEvelyn](https://github.com/JacobEvelyn))
|
16
|
+
- Correct code coverage calculations [\#164](https://github.com/JacobEvelyn/friends/pull/164) ([JacobEvelyn](https://github.com/JacobEvelyn))
|
17
|
+
|
3
18
|
## [v0.29](https://github.com/JacobEvelyn/friends/tree/v0.29) (2017-03-18)
|
4
19
|
[Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.28...v0.29)
|
5
20
|
|
data/PULL_REQUEST_TEMPLATE.md
CHANGED
@@ -6,8 +6,8 @@ merge this change:
|
|
6
6
|
- [ ] The code in these changes works correctly.
|
7
7
|
- [ ] Code has tests as appropriate.
|
8
8
|
- [ ] Code has been reviewed by @JacobEvelyn.
|
9
|
-
- [ ] All tests pass on
|
10
|
-
- [ ] Rubocop reports no issues on
|
9
|
+
- [ ] All tests pass on Travis CI.
|
10
|
+
- [ ] Rubocop reports no issues on Travis CI.
|
11
11
|
- [ ] The `README.md` file is updated as appropriate.
|
12
12
|
|
13
13
|
Don't worry—this list will get checked off in no time!
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
[](https://badge.fury.io/rb/friends) [](https://gemnasium.com/github.com/JacobEvelyn/friends)
|
2
|
-
[](https://coveralls.io/github/JacobEvelyn/friends) [](https://travis-ci.org/JacobEvelyn/friends) [](http://inch-ci.org/github/JacobEvelyn/friends) [](https://ghit.me/repo/JacobEvelyn/friends)
|
3
3
|
|
4
4
|
# `friends`
|
5
5
|
|
@@ -343,6 +343,13 @@ Jan 2015 |█████
|
|
343
343
|
Feb 2015 |███
|
344
344
|
```
|
345
345
|
|
346
|
+
Or a certain group of friends:
|
347
|
+
|
348
|
+
```bash
|
349
|
+
$ friends graph --with George --with Grace
|
350
|
+
Jan 2015 |█
|
351
|
+
```
|
352
|
+
|
346
353
|
Or graph only activities with a certain tag:
|
347
354
|
|
348
355
|
```bash
|
@@ -353,6 +360,13 @@ Jan 2015 |
|
|
353
360
|
Feb 2015 |███
|
354
361
|
```
|
355
362
|
|
363
|
+
Or with multiple tags:
|
364
|
+
|
365
|
+
```bash
|
366
|
+
$ friends graph --tagged @fun --tagged @work
|
367
|
+
Jul 2017 |█
|
368
|
+
```
|
369
|
+
|
356
370
|
Or graph only activities in a certain location:
|
357
371
|
|
358
372
|
```bash
|
@@ -443,6 +457,13 @@ $ friends list activities --with George
|
|
443
457
|
2014-11-15: Talked to George Washington Carver on the phone for an hour.
|
444
458
|
```
|
445
459
|
|
460
|
+
Or only filter activities done with a group of friends:
|
461
|
+
|
462
|
+
```bash
|
463
|
+
$ friends list activities --with George --with Grace
|
464
|
+
2015-01-04: Got lunch with Grace Hopper and George Washington Carver. @food
|
465
|
+
```
|
466
|
+
|
446
467
|
Or filter your activities by location:
|
447
468
|
|
448
469
|
```bash
|
@@ -457,16 +478,23 @@ $ friends list activities --tagged food
|
|
457
478
|
2015-01-04: Got lunch with Grace Hopper and George Washington Carver. @food
|
458
479
|
```
|
459
480
|
|
481
|
+
Or use more than one tag:
|
482
|
+
|
483
|
+
```bash
|
484
|
+
$ friends list activities --tagged @fun --tagged @work
|
485
|
+
2017-07-04: Summer picnic with @work colleagues. @fun
|
486
|
+
```
|
487
|
+
|
460
488
|
Or by date:
|
461
489
|
|
462
490
|
```bash
|
463
|
-
$ friends
|
491
|
+
$ friends list activities --since 'December 31st 2014'
|
464
492
|
2015-01-04: Got lunch with Grace Hopper and George Washington Carver. @food
|
465
493
|
2014-12-31: Celebrated the new year with Marie Curie in New York City. @partying
|
466
494
|
```
|
467
495
|
|
468
496
|
```bash
|
469
|
-
$ friends
|
497
|
+
$ friends list activities --until 'December 31st 2014'
|
470
498
|
2014-12-31: Celebrated the new year with Marie Curie in New York City. @partying
|
471
499
|
2014-11-15: Talked to George Washington Carver on the phone for an hour.
|
472
500
|
```
|
@@ -474,7 +502,7 @@ $ friends graph --until 'December 31st 2014'
|
|
474
502
|
And you can mix and match these options to your heart's content:
|
475
503
|
|
476
504
|
```bash
|
477
|
-
$ friends list activities --tagged food --with Grace
|
505
|
+
$ friends list activities --tagged food --with Grace --with George
|
478
506
|
2015-01-04: Got lunch with Grace Hopper and George Washington Carver. @food
|
479
507
|
```
|
480
508
|
|
@@ -487,7 +515,7 @@ $ friends list favorite friends
|
|
487
515
|
Your favorite friends:
|
488
516
|
1. George Washington Carver (2 activities)
|
489
517
|
2. Grace Hopper (1)
|
490
|
-
3. Marie Curie (
|
518
|
+
3. Marie Curie (0)
|
491
519
|
```
|
492
520
|
|
493
521
|
You can specify a number of favorites to show:
|
@@ -508,7 +536,7 @@ $ friends list favorite locations
|
|
508
536
|
Your favorite locations:
|
509
537
|
1. Atlantis (2 activities)
|
510
538
|
2. Paris (1)
|
511
|
-
3. London (
|
539
|
+
3. London (0)
|
512
540
|
```
|
513
541
|
|
514
542
|
You can specify a number of favorites to show:
|
@@ -555,6 +583,13 @@ Grace Hopper
|
|
555
583
|
Marie Curie
|
556
584
|
```
|
557
585
|
|
586
|
+
You can even use more than one tag to further narrow down the list:
|
587
|
+
|
588
|
+
```bash
|
589
|
+
$ friends list friends --tagged science --tagged navy
|
590
|
+
Grace Hopper
|
591
|
+
```
|
592
|
+
|
558
593
|
#### `list tags`
|
559
594
|
|
560
595
|
Lists all tags you've used, in alphabetical order:
|
data/bin/friends
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
if ENV["TRAVIS"] == "true"
|
5
|
+
require "simplecov"
|
6
|
+
SimpleCov.formatter = SimpleCov::Formatter::SimpleFormatter
|
7
|
+
SimpleCov.command_name Process.pid
|
8
|
+
SimpleCov.start
|
9
|
+
end
|
10
|
+
|
4
11
|
require "gli"
|
5
12
|
require "paint"
|
6
13
|
require "readline"
|
data/friends.gemspec
CHANGED
@@ -30,11 +30,10 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_dependency "semverse", "~> 1.2"
|
31
31
|
|
32
32
|
spec.add_development_dependency "bundler", "~> 1.6"
|
33
|
-
spec.add_development_dependency "
|
33
|
+
spec.add_development_dependency "coveralls", "~> 0.8"
|
34
34
|
spec.add_development_dependency "minitest", "~> 5.5"
|
35
|
-
spec.add_development_dependency "minitest-parallel_fork", "~> 1.0"
|
36
35
|
spec.add_development_dependency "minitest-proveit", "~> 1.0"
|
37
|
-
spec.add_development_dependency "overcommit", "~> 0.34"
|
38
36
|
spec.add_development_dependency "rake", "~> 11.2"
|
39
|
-
spec.add_development_dependency "rubocop", "~> 0.
|
37
|
+
spec.add_development_dependency "rubocop", "~> 0.49"
|
38
|
+
spec.add_development_dependency "simplecov", "~> 0.14"
|
40
39
|
end
|
@@ -5,7 +5,8 @@ command :graph do |graph|
|
|
5
5
|
graph.flag [:with],
|
6
6
|
arg_name: "NAME",
|
7
7
|
desc: "Graph activities with the given friend",
|
8
|
-
type: Stripped
|
8
|
+
type: Stripped,
|
9
|
+
multiple: true
|
9
10
|
|
10
11
|
graph.flag [:in],
|
11
12
|
arg_name: "LOCATION",
|
@@ -15,7 +16,8 @@ command :graph do |graph|
|
|
15
16
|
graph.flag [:tagged],
|
16
17
|
arg_name: "@TAG",
|
17
18
|
desc: "Graph activities with the given tag",
|
18
|
-
type: Tag
|
19
|
+
type: Tag,
|
20
|
+
multiple: true
|
19
21
|
|
20
22
|
graph.flag [:since],
|
21
23
|
arg_name: "DATE",
|
@@ -12,7 +12,8 @@ command :list do |list|
|
|
12
12
|
list_friends.flag [:tagged],
|
13
13
|
arg_name: "@TAG",
|
14
14
|
desc: "List only friends with the given tag",
|
15
|
-
type: Tag
|
15
|
+
type: Tag,
|
16
|
+
multiple: true
|
16
17
|
|
17
18
|
list_friends.switch [:verbose],
|
18
19
|
negatable: false,
|
@@ -38,7 +39,8 @@ command :list do |list|
|
|
38
39
|
list_activities.flag [:with],
|
39
40
|
arg_name: "NAME",
|
40
41
|
desc: "List only activities with the given friend",
|
41
|
-
type: Stripped
|
42
|
+
type: Stripped,
|
43
|
+
multiple: true
|
42
44
|
|
43
45
|
list_activities.flag [:in],
|
44
46
|
arg_name: "LOCATION",
|
@@ -48,7 +50,8 @@ command :list do |list|
|
|
48
50
|
list_activities.flag [:tagged],
|
49
51
|
arg_name: "@TAG",
|
50
52
|
desc: "List only activities with the given tag",
|
51
|
-
type: Tag
|
53
|
+
type: Tag,
|
54
|
+
multiple: true
|
52
55
|
|
53
56
|
list_activities.flag [:since],
|
54
57
|
arg_name: "DATE",
|
@@ -101,18 +104,7 @@ command :list do |list|
|
|
101
104
|
type: Integer
|
102
105
|
|
103
106
|
list_favorite_friends.action do |_, options|
|
104
|
-
|
105
|
-
|
106
|
-
if options[:limit] == 1
|
107
|
-
puts "Your best friend is #{favorites.first}"
|
108
|
-
else
|
109
|
-
puts "Your favorite friends:"
|
110
|
-
|
111
|
-
num_str_size = favorites.size.to_s.size + 1
|
112
|
-
favorites.each.with_index(1) do |name, rank|
|
113
|
-
puts "#{"#{rank}.".ljust(num_str_size)} #{name}"
|
114
|
-
end
|
115
|
-
end
|
107
|
+
@introvert.list_favorite_friends(limit: options[:limit])
|
116
108
|
end
|
117
109
|
end
|
118
110
|
|
@@ -125,18 +117,7 @@ command :list do |list|
|
|
125
117
|
type: Integer
|
126
118
|
|
127
119
|
list_favorite_locations.action do |_, options|
|
128
|
-
|
129
|
-
|
130
|
-
if options[:limit] == 1
|
131
|
-
puts "Your favorite location is #{favorites.first}"
|
132
|
-
else
|
133
|
-
puts "Your favorite locations:"
|
134
|
-
|
135
|
-
num_str_size = favorites.size.to_s.size + 1
|
136
|
-
favorites.each.with_index(1) do |name, rank|
|
137
|
-
puts "#{"#{rank}.".ljust(num_str_size)} #{name}"
|
138
|
-
end
|
139
|
-
end
|
120
|
+
@introvert.list_favorite_locations(limit: options[:limit])
|
140
121
|
end
|
141
122
|
end
|
142
123
|
end
|
data/lib/friends/graph.rb
CHANGED
data/lib/friends/introvert.rb
CHANGED
@@ -186,8 +186,8 @@ module Friends
|
|
186
186
|
# List all friend names in the friends file.
|
187
187
|
# @param location_name [String] the name of a location to filter by, or nil
|
188
188
|
# for unfiltered
|
189
|
-
# @param tagged [String] the
|
190
|
-
#
|
189
|
+
# @param tagged [Array<String>] the names of tags to filter by, or empty for
|
190
|
+
# unfiltered
|
191
191
|
# @param verbose [Boolean] true iff we should output friend names with
|
192
192
|
# nicknames, locations, and tags; false for names only
|
193
193
|
# @return [Array] a list of all friend names
|
@@ -200,8 +200,12 @@ module Friends
|
|
200
200
|
fs = fs.select { |friend| friend.location_name == location.name }
|
201
201
|
end
|
202
202
|
|
203
|
-
# Filter by tag if
|
204
|
-
|
203
|
+
# Filter by tag if param is passed.
|
204
|
+
unless tagged.empty?
|
205
|
+
fs = fs.select do |friend|
|
206
|
+
tagged.all? { |tag| friend.tags.include? tag }
|
207
|
+
end
|
208
|
+
end
|
205
209
|
|
206
210
|
verbose ? fs.map(&:to_s) : fs.map(&:name)
|
207
211
|
end
|
@@ -225,12 +229,12 @@ module Friends
|
|
225
229
|
# List all activity details.
|
226
230
|
# @param limit [Integer] the number of activities to return, or nil for no
|
227
231
|
# limit
|
228
|
-
# @param with [String] the
|
232
|
+
# @param with [Array<String>] the names of friends to filter by, or empty for
|
233
|
+
# unfiltered
|
234
|
+
# @param location_name [String] the name of a location to filter by, or
|
235
|
+
# nil for unfiltered
|
236
|
+
# @param tagged [Array<String>] the names of tags to filter by, or empty for
|
229
237
|
# unfiltered
|
230
|
-
# @param location_name [String] the name of a location to filter by, or nil
|
231
|
-
# for unfiltered
|
232
|
-
# @param tagged [String] the name of a tag to filter by (of the form:
|
233
|
-
# "@tag"), or nil for unfiltered
|
234
238
|
# @param since_date [Date] a date on or after which to find activities, or nil for unfiltered
|
235
239
|
# @param until_date [Date] a date before or on which to find activities, or nil for unfiltered
|
236
240
|
# @return [Array] a list of all activity text values
|
@@ -294,12 +298,12 @@ module Friends
|
|
294
298
|
# The keys of the hash are all of the months (inclusive) between the first
|
295
299
|
# and last month in which activities have been recorded.
|
296
300
|
#
|
297
|
-
# @param with [String] the
|
301
|
+
# @param with [Array<String>] the names of friends to filter by, or empty for
|
302
|
+
# unfiltered
|
303
|
+
# @param location_name [String] the name of a location to filter by, or
|
304
|
+
# nil for unfiltered
|
305
|
+
# @param tagged [Array<String>] the names of tags to filter by, or empty for
|
298
306
|
# unfiltered
|
299
|
-
# @param location_name [String] the name of a location to filter by, or nil
|
300
|
-
# for unfiltered
|
301
|
-
# @param tagged [String] the name of a tag to filter by (of the form:
|
302
|
-
# "@tag"), or nil for unfiltered
|
303
307
|
# @param since_date [Date] a date on or after which to find activities, or nil for unfiltered
|
304
308
|
# @param until_date [Date] a date before or on which to find activities, or nil for unfiltered
|
305
309
|
# @return [Hash{String => Integer}]
|
@@ -451,11 +455,11 @@ module Friends
|
|
451
455
|
private
|
452
456
|
|
453
457
|
# Filter activities by friend, location and tag
|
454
|
-
# @param with [String] the
|
458
|
+
# @param with [Array<String>] the names of friends to filter by, or empty for
|
455
459
|
# unfiltered
|
456
|
-
# @param location_name [String] the name of a location to filter by, or
|
457
|
-
# for unfiltered
|
458
|
-
# @param tagged [String] the
|
460
|
+
# @param location_name [String] the name of a location to filter by, or
|
461
|
+
# nil for unfiltered
|
462
|
+
# @param tagged [Array<String>] the names of tags to filter by, or empty for
|
459
463
|
# unfiltered
|
460
464
|
# @param since_date [Date] a date on or after which to find activities, or nil for unfiltered
|
461
465
|
# @param until_date [Date] a date before or on which to find activities, or nil for unfiltered
|
@@ -466,9 +470,11 @@ module Friends
|
|
466
470
|
acts = @activities
|
467
471
|
|
468
472
|
# Filter by friend name if argument is passed.
|
469
|
-
unless with.
|
470
|
-
|
471
|
-
acts = acts.select
|
473
|
+
unless with.empty?
|
474
|
+
friends = with.map { |name| thing_with_name_in(:friend, name) }
|
475
|
+
acts = acts.select do |act|
|
476
|
+
friends.all? { |friend| act.includes_friend?(friend) }
|
477
|
+
end
|
472
478
|
end
|
473
479
|
|
474
480
|
# Filter by location name if argument is passed.
|
@@ -478,7 +484,11 @@ module Friends
|
|
478
484
|
end
|
479
485
|
|
480
486
|
# Filter by tag if argument is passed.
|
481
|
-
|
487
|
+
unless tagged.empty?
|
488
|
+
acts = acts.select do |act|
|
489
|
+
tagged.all? { |tag| act.includes_tag?(tag) }
|
490
|
+
end
|
491
|
+
end
|
482
492
|
|
483
493
|
# Filter by date if arguments are passed.
|
484
494
|
acts = acts.select { |act| act.date >= since_date } unless since_date.nil?
|
@@ -504,15 +514,42 @@ module Friends
|
|
504
514
|
-thing.n_activities
|
505
515
|
end.take(limit) # Trim the list.
|
506
516
|
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
517
|
+
if results.size == 1
|
518
|
+
favorite = results.first
|
519
|
+
puts "Your favorite #{type} is "\
|
520
|
+
"#{favorite.name} "\
|
521
|
+
"(#{favorite.n_activities} "\
|
522
|
+
"#{favorite.n_activities == 1 ? 'activity' : 'activities'})"
|
523
|
+
else
|
524
|
+
puts "Your favorite #{type}s:"
|
525
|
+
|
526
|
+
max_str_size = results.map(&:name).map(&:size).max
|
527
|
+
|
528
|
+
grouped_results = results.group_by(&:n_activities)
|
529
|
+
|
530
|
+
rank = 1
|
531
|
+
first = true
|
532
|
+
data = grouped_results.each.with_object([]) do |(n_activities, things), arr|
|
533
|
+
things.each do |thing|
|
534
|
+
name = thing.name.ljust(max_str_size)
|
535
|
+
if first
|
536
|
+
label = n_activities == 1 ? " activity" : " activities"
|
537
|
+
first = false
|
538
|
+
end
|
539
|
+
str = "#{name} (#{n_activities}#{label})"
|
540
|
+
|
541
|
+
arr << [rank, str]
|
542
|
+
end
|
543
|
+
rank += things.size
|
544
|
+
end
|
545
|
+
|
546
|
+
# We need to use `data.last.first` instead of `rank` to determine the size
|
547
|
+
# of the numbering prefix because `rank` will simply be the size of all
|
548
|
+
# elements, which may be too large if the last element in the list is a tie.
|
549
|
+
num_str_size = data.last.first.to_s.size + 1 unless data.empty?
|
550
|
+
data.each do |ranking, str|
|
551
|
+
puts "#{"#{ranking}.".ljust(num_str_size)} #{str}"
|
513
552
|
end
|
514
|
-
parenthetical = "(#{n}#{label})"
|
515
|
-
"#{name} #{parenthetical}"
|
516
553
|
end
|
517
554
|
end
|
518
555
|
|
data/lib/friends/serializable.rb
CHANGED
data/lib/friends/version.rb
CHANGED
data/test/commands/graph_spec.rb
CHANGED
@@ -90,6 +90,16 @@ Jan 2015 |█
|
|
90
90
|
OUTPUT
|
91
91
|
end
|
92
92
|
end
|
93
|
+
|
94
|
+
describe "when more than one friend name is passed" do
|
95
|
+
subject { run_cmd("graph --with #{friend_name1} --with #{friend_name2}") }
|
96
|
+
let(:friend_name1) { "george" }
|
97
|
+
let(:friend_name2) { "grace" }
|
98
|
+
|
99
|
+
it "matches all friends case-insensitively" do
|
100
|
+
stdout_only "Jan 2015 |█"
|
101
|
+
end
|
102
|
+
end
|
93
103
|
end
|
94
104
|
|
95
105
|
describe "--tagged" do
|
@@ -110,6 +120,30 @@ Oct 2015 |
|
|
110
120
|
Nov 2015 |█
|
111
121
|
OUTPUT
|
112
122
|
end
|
123
|
+
|
124
|
+
describe "when more than one tag is passed" do
|
125
|
+
subject { run_cmd("graph --tagged #{tag1} --tagged #{tag2}") }
|
126
|
+
let(:tag1) { "food" }
|
127
|
+
let(:tag2) { "partying" }
|
128
|
+
let(:content) do
|
129
|
+
<<-FILE
|
130
|
+
### Activities:
|
131
|
+
- 2015-01-04: Got lunch with **Grace Hopper** and **George Washington Carver**. @food
|
132
|
+
- 2015-11-01: **Grace Hopper** and I went to _Marie's Diner_. George had to cancel at the last minute. @food
|
133
|
+
- 2014-11-15: Talked to **George Washington Carver** on the phone for an hour.
|
134
|
+
- 2014-12-31: Celebrated the new year in _Paris_ with **Marie Curie**. @partying @food
|
135
|
+
|
136
|
+
### Friends:
|
137
|
+
- George Washington Carver
|
138
|
+
- Marie Curie [Atlantis] @science
|
139
|
+
- Grace Hopper (a.k.a. The Admiral a.k.a. Amazing Grace) [Paris] @navy @science
|
140
|
+
FILE
|
141
|
+
end
|
142
|
+
|
143
|
+
it "matches all tags case-sensitively" do
|
144
|
+
stdout_only "Dec 2014 |█"
|
145
|
+
end
|
146
|
+
end
|
113
147
|
end
|
114
148
|
|
115
149
|
describe "--since" do
|
@@ -97,6 +97,16 @@ clean_describe "list activities" do
|
|
97
97
|
stdout_only "2014-12-31: Celebrated the new year in Paris with Marie Curie. @partying"
|
98
98
|
end
|
99
99
|
end
|
100
|
+
|
101
|
+
describe "when more than one friend name is passed" do
|
102
|
+
subject { run_cmd("list activities --with #{friend_name1} --with #{friend_name2}") }
|
103
|
+
let(:friend_name1) { "george" }
|
104
|
+
let(:friend_name2) { "grace" }
|
105
|
+
|
106
|
+
it "matches all friends case-insensitively" do
|
107
|
+
stdout_only "2015-01-04: Got lunch with Grace Hopper and George Washington Carver. @food"
|
108
|
+
end
|
109
|
+
end
|
100
110
|
end
|
101
111
|
|
102
112
|
describe "--tagged" do
|
@@ -108,6 +118,32 @@ clean_describe "list activities" do
|
|
108
118
|
2015-11-01: Grace Hopper and I went to Marie's Diner. George had to cancel at the last minute. @food
|
109
119
|
OUTPUT
|
110
120
|
end
|
121
|
+
|
122
|
+
describe "when more than one tag is passed" do
|
123
|
+
subject { run_cmd("list activities --tagged #{tag1} --tagged #{tag2}") }
|
124
|
+
let(:tag1) { "food" }
|
125
|
+
let(:tag2) { "partying" }
|
126
|
+
let(:content) do
|
127
|
+
<<-FILE
|
128
|
+
### Activities:
|
129
|
+
- 2015-01-04: Got lunch with **Grace Hopper** and **George Washington Carver**. @food
|
130
|
+
- 2015-11-01: **Grace Hopper** and I went to _Marie's Diner_. George had to cancel at the last minute. @food
|
131
|
+
- 2014-11-15: Talked to **George Washington Carver** on the phone for an hour.
|
132
|
+
- 2014-12-31: Celebrated the new year in _Paris_ with **Marie Curie**. @partying @food
|
133
|
+
|
134
|
+
### Friends:
|
135
|
+
- George Washington Carver
|
136
|
+
- Marie Curie [Atlantis] @science
|
137
|
+
- Grace Hopper (a.k.a. The Admiral a.k.a. Amazing Grace) [Paris] @navy @science
|
138
|
+
FILE
|
139
|
+
end
|
140
|
+
|
141
|
+
it "matches all tags case-sensitively" do
|
142
|
+
stdout_only(
|
143
|
+
"2014-12-31: Celebrated the new year in Paris with Marie Curie. @partying @food"
|
144
|
+
)
|
145
|
+
end
|
146
|
+
end
|
111
147
|
end
|
112
148
|
|
113
149
|
describe "--since" do
|
@@ -45,6 +45,69 @@ Your favorite friends:
|
|
45
45
|
OUTPUT
|
46
46
|
end
|
47
47
|
|
48
|
+
describe "when friends are tied for the same number of activities" do
|
49
|
+
let(:content) do
|
50
|
+
<<-FILE
|
51
|
+
### Activities:
|
52
|
+
- 2017-01-01: Did something with **Friend A**.
|
53
|
+
- 2017-01-01: Did something with **Friend A**.
|
54
|
+
- 2017-01-01: Did something with **Friend B**.
|
55
|
+
- 2017-01-01: Did something with **Friend B**.
|
56
|
+
- 2017-01-01: Did something with **Friend C**.
|
57
|
+
- 2017-01-01: Did something with **Friend D**.
|
58
|
+
- 2017-01-01: Did something with **Friend E**.
|
59
|
+
- 2017-01-01: Did something with **Friend F**.
|
60
|
+
- 2017-01-01: Did something with **Friend G**.
|
61
|
+
- 2017-01-01: Did something with **Friend H**.
|
62
|
+
- 2017-01-01: Did something with **Friend I**.
|
63
|
+
- 2017-01-01: Did something with **Friend J**.
|
64
|
+
|
65
|
+
### Friends:
|
66
|
+
- Friend A
|
67
|
+
- Friend B
|
68
|
+
- Friend C
|
69
|
+
- Friend D
|
70
|
+
- Friend E
|
71
|
+
- Friend F
|
72
|
+
- Friend G
|
73
|
+
- Friend H
|
74
|
+
- Friend I
|
75
|
+
- Friend J
|
76
|
+
FILE
|
77
|
+
end
|
78
|
+
|
79
|
+
it "uses tied ranks" do
|
80
|
+
subject[:stderr].must_equal ""
|
81
|
+
subject[:status].must_equal 0
|
82
|
+
|
83
|
+
lines = subject[:stdout].split("\n")
|
84
|
+
lines[1].must_match(/1\. Friend (A|B)/)
|
85
|
+
lines[2].must_match(/1\. Friend (A|B)/)
|
86
|
+
lines[3].must_include "3. Friend"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "only uses the word 'activities' for the first item, even when a tie" do
|
90
|
+
subject[:stderr].must_equal ""
|
91
|
+
subject[:status].must_equal 0
|
92
|
+
|
93
|
+
lines = subject[:stdout].split("\n")
|
94
|
+
lines[1].must_include "activities"
|
95
|
+
lines[2].wont_include "activities"
|
96
|
+
end
|
97
|
+
|
98
|
+
it "indents based on the highest rank number, not the number of friends" do
|
99
|
+
subject[:stderr].must_equal ""
|
100
|
+
subject[:status].must_equal 0
|
101
|
+
|
102
|
+
# Since there are 10 friends, a naive implementation would pad our output
|
103
|
+
# assuming the (numerically) highest rank is "10." but since the highest
|
104
|
+
# rank is a tie, we never display a double-digit rank, so we don't need to
|
105
|
+
# pad our output for double digits.
|
106
|
+
lines = subject[:stdout].split("\n")
|
107
|
+
lines.last.must_include "3. Friend"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
48
111
|
describe "--limit" do
|
49
112
|
subject { run_cmd("list favorite friends --limit #{limit}") }
|
50
113
|
|
@@ -57,8 +120,27 @@ Your favorite friends:
|
|
57
120
|
|
58
121
|
describe "when limit is 1" do
|
59
122
|
let(:limit) { 1 }
|
60
|
-
|
61
|
-
|
123
|
+
|
124
|
+
it "uses correct friend pluralization" do
|
125
|
+
stdout_only "Your favorite friend is Grace Hopper (3 activities)"
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "when favorite friend only has one activity" do
|
129
|
+
let(:content) do
|
130
|
+
<<-FILE
|
131
|
+
### Activities:
|
132
|
+
- 2017-01-01: Did some math with **Grace Hopper**.
|
133
|
+
|
134
|
+
### Friends:
|
135
|
+
- George Washington Carver
|
136
|
+
- Grace Hopper (a.k.a. The Admiral a.k.a. Amazing Grace) [Paris] @navy @science
|
137
|
+
- Marie Curie [Atlantis] @science
|
138
|
+
FILE
|
139
|
+
end
|
140
|
+
|
141
|
+
it "uses correct activity pluralization" do
|
142
|
+
stdout_only "Your favorite friend is Grace Hopper (1 activity)"
|
143
|
+
end
|
62
144
|
end
|
63
145
|
end
|
64
146
|
|
@@ -50,6 +50,69 @@ Your favorite locations:
|
|
50
50
|
OUTPUT
|
51
51
|
end
|
52
52
|
|
53
|
+
describe "when locations are tied for the same number of activities" do
|
54
|
+
let(:content) do
|
55
|
+
<<-FILE
|
56
|
+
### Activities:
|
57
|
+
- 2017-01-01: Did something in _Location A_.
|
58
|
+
- 2017-01-01: Did something in _Location A_.
|
59
|
+
- 2017-01-01: Did something in _Location B_.
|
60
|
+
- 2017-01-01: Did something in _Location B_.
|
61
|
+
- 2017-01-01: Did something in _Location C_.
|
62
|
+
- 2017-01-01: Did something in _Location D_.
|
63
|
+
- 2017-01-01: Did something in _Location E_.
|
64
|
+
- 2017-01-01: Did something in _Location F_.
|
65
|
+
- 2017-01-01: Did something in _Location G_.
|
66
|
+
- 2017-01-01: Did something in _Location H_.
|
67
|
+
- 2017-01-01: Did something in _Location I_.
|
68
|
+
- 2017-01-01: Did something in _Location J_.
|
69
|
+
|
70
|
+
### Locations:
|
71
|
+
- Location A
|
72
|
+
- Location B
|
73
|
+
- Location C
|
74
|
+
- Location D
|
75
|
+
- Location E
|
76
|
+
- Location F
|
77
|
+
- Location G
|
78
|
+
- Location H
|
79
|
+
- Location I
|
80
|
+
- Location J
|
81
|
+
FILE
|
82
|
+
end
|
83
|
+
|
84
|
+
it "uses tied ranks" do
|
85
|
+
subject[:stderr].must_equal ""
|
86
|
+
subject[:status].must_equal 0
|
87
|
+
|
88
|
+
lines = subject[:stdout].split("\n")
|
89
|
+
lines[1].must_match(/1\. Location (A|B)/)
|
90
|
+
lines[2].must_match(/1\. Location (A|B)/)
|
91
|
+
lines[3].must_include "3. Location"
|
92
|
+
end
|
93
|
+
|
94
|
+
it "only uses the word 'activities' for the first item, even when a tie" do
|
95
|
+
subject[:stderr].must_equal ""
|
96
|
+
subject[:status].must_equal 0
|
97
|
+
|
98
|
+
lines = subject[:stdout].split("\n")
|
99
|
+
lines[1].must_include "activities"
|
100
|
+
lines[2].wont_include "activities"
|
101
|
+
end
|
102
|
+
|
103
|
+
it "indents based on the highest rank number, not the number of locations" do
|
104
|
+
subject[:stderr].must_equal ""
|
105
|
+
subject[:status].must_equal 0
|
106
|
+
|
107
|
+
# Since there are 10 friends, a naive implementation would pad our output
|
108
|
+
# assuming the (numerically) highest rank is "10." but since the highest
|
109
|
+
# rank is a tie, we never display a double-digit rank, so we don't need to
|
110
|
+
# pad our output for double digits.
|
111
|
+
lines = subject[:stdout].split("\n")
|
112
|
+
lines.last.must_include "3. Location"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
53
116
|
describe "--limit" do
|
54
117
|
subject { run_cmd("list favorite locations --limit #{limit}") }
|
55
118
|
|
@@ -62,9 +125,33 @@ Your favorite locations:
|
|
62
125
|
|
63
126
|
describe "when limit is 1" do
|
64
127
|
let(:limit) { 1 }
|
65
|
-
|
128
|
+
|
129
|
+
it "uses correct location pluralization" do
|
66
130
|
stdout_only "Your favorite location is Marie's Diner (2 activities)"
|
67
131
|
end
|
132
|
+
|
133
|
+
describe "when favorite location only has one activity" do
|
134
|
+
let(:content) do
|
135
|
+
<<-FILE
|
136
|
+
### Activities:
|
137
|
+
- 2017-01-01: Did some math with **Grace Hopper** at _Marie's Diner_.
|
138
|
+
|
139
|
+
### Friends:
|
140
|
+
- George Washington Carver
|
141
|
+
- Grace Hopper (a.k.a. The Admiral a.k.a. Amazing Grace) [Paris] @navy @science
|
142
|
+
- Marie Curie [Atlantis] @science
|
143
|
+
|
144
|
+
### Locations:
|
145
|
+
- Atlantis
|
146
|
+
- Marie's Diner
|
147
|
+
- Paris
|
148
|
+
FILE
|
149
|
+
end
|
150
|
+
|
151
|
+
it "uses correct activity pluralization" do
|
152
|
+
stdout_only "Your favorite location is Marie's Diner (1 activity)"
|
153
|
+
end
|
154
|
+
end
|
68
155
|
end
|
69
156
|
|
70
157
|
describe "when limit is greater than 1" do
|
@@ -71,6 +71,31 @@ Marie Curie
|
|
71
71
|
Grace Hopper
|
72
72
|
OUTPUT
|
73
73
|
end
|
74
|
+
|
75
|
+
describe "when more than one tag is passed" do
|
76
|
+
subject { run_cmd("list friends --tagged #{tag1} --tagged #{tag2}") }
|
77
|
+
let(:tag1) { "science" }
|
78
|
+
let(:tag2) { "navy" }
|
79
|
+
let(:content) do
|
80
|
+
<<-FILE
|
81
|
+
### Activities:
|
82
|
+
|
83
|
+
### Friends:
|
84
|
+
- George Washington Carver
|
85
|
+
- Grace Hopper (a.k.a. The Admiral a.k.a. Amazing Grace) [Paris] @navy @science
|
86
|
+
- Marie Curie [Atlantis] @science
|
87
|
+
- Neil Armstrong @navy @science
|
88
|
+
- John F. Kennedy @navy
|
89
|
+
FILE
|
90
|
+
end
|
91
|
+
|
92
|
+
it "matches all tags case-sensitively" do
|
93
|
+
stdout_only <<-OUTPUT
|
94
|
+
Grace Hopper
|
95
|
+
Neil Armstrong
|
96
|
+
OUTPUT
|
97
|
+
end
|
98
|
+
end
|
74
99
|
end
|
75
100
|
end
|
76
101
|
end
|
data/test/helper.rb
CHANGED
@@ -1,14 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
if ENV["TRAVIS"] == "true"
|
4
|
+
require "simplecov"
|
5
|
+
require "coveralls"
|
6
|
+
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
7
|
+
SimpleCov.start do
|
8
|
+
add_filter "/test/"
|
9
|
+
end
|
10
|
+
end
|
5
11
|
|
6
12
|
ENV["MT_HELL"] = "1" # Forces tests to have at least one assertion to pass.
|
7
13
|
|
8
14
|
require "minitest/autorun"
|
9
|
-
|
10
|
-
|
15
|
+
|
16
|
+
# Runs tests in parallel. Also, in combination with the MT_HELL environment var
|
17
|
+
# set above and the loading of the `minitest-proveit` gem, requires that tests
|
18
|
+
# have at least one assertion to pass.
|
11
19
|
require "minitest/hell"
|
20
|
+
|
21
|
+
require "minitest/pride"
|
12
22
|
require "open3"
|
13
23
|
require "securerandom"
|
14
24
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: friends
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.30'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Evelyn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chronic
|
@@ -95,19 +95,19 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '1.6'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: coveralls
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0.
|
103
|
+
version: '0.8'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '0.
|
110
|
+
version: '0.8'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: minitest
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,20 +122,6 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '5.5'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: minitest-parallel_fork
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '1.0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '1.0'
|
139
125
|
- !ruby/object:Gem::Dependency
|
140
126
|
name: minitest-proveit
|
141
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -151,47 +137,47 @@ dependencies:
|
|
151
137
|
- !ruby/object:Gem::Version
|
152
138
|
version: '1.0'
|
153
139
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
140
|
+
name: rake
|
155
141
|
requirement: !ruby/object:Gem::Requirement
|
156
142
|
requirements:
|
157
143
|
- - "~>"
|
158
144
|
- !ruby/object:Gem::Version
|
159
|
-
version: '
|
145
|
+
version: '11.2'
|
160
146
|
type: :development
|
161
147
|
prerelease: false
|
162
148
|
version_requirements: !ruby/object:Gem::Requirement
|
163
149
|
requirements:
|
164
150
|
- - "~>"
|
165
151
|
- !ruby/object:Gem::Version
|
166
|
-
version: '
|
152
|
+
version: '11.2'
|
167
153
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
154
|
+
name: rubocop
|
169
155
|
requirement: !ruby/object:Gem::Requirement
|
170
156
|
requirements:
|
171
157
|
- - "~>"
|
172
158
|
- !ruby/object:Gem::Version
|
173
|
-
version: '
|
159
|
+
version: '0.49'
|
174
160
|
type: :development
|
175
161
|
prerelease: false
|
176
162
|
version_requirements: !ruby/object:Gem::Requirement
|
177
163
|
requirements:
|
178
164
|
- - "~>"
|
179
165
|
- !ruby/object:Gem::Version
|
180
|
-
version: '
|
166
|
+
version: '0.49'
|
181
167
|
- !ruby/object:Gem::Dependency
|
182
|
-
name:
|
168
|
+
name: simplecov
|
183
169
|
requirement: !ruby/object:Gem::Requirement
|
184
170
|
requirements:
|
185
171
|
- - "~>"
|
186
172
|
- !ruby/object:Gem::Version
|
187
|
-
version: '0.
|
173
|
+
version: '0.14'
|
188
174
|
type: :development
|
189
175
|
prerelease: false
|
190
176
|
version_requirements: !ruby/object:Gem::Requirement
|
191
177
|
requirements:
|
192
178
|
- - "~>"
|
193
179
|
- !ruby/object:Gem::Version
|
194
|
-
version: '0.
|
180
|
+
version: '0.14'
|
195
181
|
description: Spend time with the people you care about. Introvert-tested. Extrovert-approved.
|
196
182
|
email:
|
197
183
|
- jacobevelyn@gmail.com
|
@@ -203,7 +189,6 @@ files:
|
|
203
189
|
- ".gitignore"
|
204
190
|
- ".overcommit.yml"
|
205
191
|
- ".rubocop.yml"
|
206
|
-
- ".ruby-version"
|
207
192
|
- ".travis.yml"
|
208
193
|
- CHANGELOG.md
|
209
194
|
- CODE_OF_CONDUCT.md
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.4.0
|