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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 266cfedd5b0654ca5ebd434c11ead3d8c21d4e9e
4
- data.tar.gz: 76d290e42cc9babe0dcfe3dd9419dded6ca4825d
3
+ metadata.gz: 81e378aa8d3e1a7285adcb3f92cc91977c22eca2
4
+ data.tar.gz: f48b3ccd7d4006679c7b072b06a980432c759a6c
5
5
  SHA512:
6
- metadata.gz: 41e311c6cd3f8dc4a0c9e86d5268badad683731307626f6f50ef33eaf15edfc930754adce617f2934262b6915caa87b3167b138741b3e6b99025d0c4cc542a06
7
- data.tar.gz: e838474558ec1a065cd7d72a828fb6073adafac32a6aec23b4bc6e930063f5838e55129d9a6d82d01bf0236a79777db936a31a32b15104fce83cdd3c146e1c5c
6
+ metadata.gz: ee11daf225f5c245b68a732267b0fafd7041d478d8cff7d68860f9b50a71f9a3db51de2edd4a7dac723a6db5c5c26045a697a21bc7215acc770bed3a2390ee10
7
+ data.tar.gz: e47d850e7cc62ea74a0c212f0315de2cc5bd1eb72f331526ccee67dd39d7599b091a546770d14ba2af7132f929ab8d9076f61b28cb8a68a36432ccda3d481f56
data/.gitignore CHANGED
@@ -17,3 +17,4 @@ ideas.txt
17
17
  TODO.txt
18
18
  .DS_Store
19
19
  .byebug_history
20
+ .ruby-version
@@ -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
 
@@ -5,10 +5,7 @@ rvm:
5
5
  - 2.3.0
6
6
  - 2.4.0
7
7
  script:
8
- - bundle exec rake test
9
- - bundle exec rubocop
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
@@ -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
 
@@ -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 TravisCI.
10
- - [ ] Rubocop reports no issues on TravisCI.
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
  [![Gem Version](https://badge.fury.io/rb/friends.svg)](https://badge.fury.io/rb/friends) [![Dependency Status](https://gemnasium.com/badges/github.com/JacobEvelyn/friends.svg)](https://gemnasium.com/github.com/JacobEvelyn/friends)
2
- [![Code Climate](https://codeclimate.com/github/JacobEvelyn/friends/badges/gpa.svg)](https://codeclimate.com/github/JacobEvelyn/friends) [![Test Coverage](https://codeclimate.com/github/JacobEvelyn/friends/badges/coverage.svg)](https://codeclimate.com/github/JacobEvelyn/friends) [![Build Status](https://travis-ci.org/JacobEvelyn/friends.svg?branch=master)](https://travis-ci.org/JacobEvelyn/friends) [![Inline docs](http://inch-ci.org/github/JacobEvelyn/friends.png)](http://inch-ci.org/github/JacobEvelyn/friends) [![ghit.me](https://ghit.me/badge.svg?repo=JacobEvelyn/friends)](https://ghit.me/repo/JacobEvelyn/friends)
2
+ [![Coverage Status](https://coveralls.io/repos/github/JacobEvelyn/friends/badge.svg)](https://coveralls.io/github/JacobEvelyn/friends) [![Build Status](https://travis-ci.org/JacobEvelyn/friends.svg?branch=master)](https://travis-ci.org/JacobEvelyn/friends) [![Inline docs](http://inch-ci.org/github/JacobEvelyn/friends.png)](http://inch-ci.org/github/JacobEvelyn/friends) [![ghit.me](https://ghit.me/badge.svg?repo=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 graph --since 'December 31st 2014'
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 graph --until 'December 31st 2014'
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 (1)
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 (1)
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:
@@ -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"
@@ -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 "codeclimate-test-reporter", "~> 0.5"
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.40"
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
- favorites = @introvert.list_favorite_friends(limit: options[:limit])
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
- favorites = @introvert.list_favorite_locations(limit: options[:limit])
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
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Graphs activities by month
3
4
 
4
5
  module Friends
@@ -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 name of a tag to filter by (of the form:
190
- # "@tag"), or nil for unfiltered
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 one is passed.
204
- fs = fs.select { |friend| friend.tags.include? tagged } if tagged
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 name of a friend to filter by, or nil for
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 name of a friend to filter by, or nil for
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 name of a friend to filter by, or nil for
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 nil
457
- # for unfiltered
458
- # @param tagged [String] the name of a tag to filter by, or nil for
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.nil?
470
- friend = thing_with_name_in(:friend, with)
471
- acts = acts.select { |act| act.includes_friend?(friend) }
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
- acts = acts.select { |act| act.includes_tag?(tagged) } unless tagged.nil?
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
- max_str_size = results.map(&:name).map(&:size).max
508
- results.map.with_index(0) do |thing, index|
509
- name = thing.name.ljust(max_str_size)
510
- n = thing.n_activities
511
- if index.zero?
512
- label = n == 1 ? " activity" : " activities"
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
 
@@ -24,7 +24,7 @@ module Serializable
24
24
  args = match.names.
25
25
  map { |name| { name.to_sym => match[name.to_sym] } }.
26
26
  reduce(:merge).
27
- select { |_, v| !v.nil? }
27
+ reject { |_, v| v.nil? }
28
28
 
29
29
  new(args)
30
30
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Friends
4
- VERSION = "0.29"
4
+ VERSION = "0.30"
5
5
  end
@@ -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
- it "outputs as a best friend" do
61
- stdout_only "Your best friend is Grace Hopper (3 activities)"
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
- it "outputs as a favorite location" do
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
@@ -1,14 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "codeclimate-test-reporter"
4
- CodeClimate::TestReporter.start
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
- require "minitest/parallel_fork"
10
- require "minitest/pride"
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.29'
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-03-18 00:00:00.000000000 Z
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: codeclimate-test-reporter
98
+ name: coveralls
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '0.5'
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.5'
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: overcommit
140
+ name: rake
155
141
  requirement: !ruby/object:Gem::Requirement
156
142
  requirements:
157
143
  - - "~>"
158
144
  - !ruby/object:Gem::Version
159
- version: '0.34'
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: '0.34'
152
+ version: '11.2'
167
153
  - !ruby/object:Gem::Dependency
168
- name: rake
154
+ name: rubocop
169
155
  requirement: !ruby/object:Gem::Requirement
170
156
  requirements:
171
157
  - - "~>"
172
158
  - !ruby/object:Gem::Version
173
- version: '11.2'
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: '11.2'
166
+ version: '0.49'
181
167
  - !ruby/object:Gem::Dependency
182
- name: rubocop
168
+ name: simplecov
183
169
  requirement: !ruby/object:Gem::Requirement
184
170
  requirements:
185
171
  - - "~>"
186
172
  - !ruby/object:Gem::Version
187
- version: '0.40'
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.40'
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
@@ -1 +0,0 @@
1
- 2.4.0