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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/README.md +79 -20
- data/RELEASING.md +7 -6
- data/friends.md +4 -0
- data/lib/friends/activity.rb +4 -291
- data/lib/friends/commands/add.rb +15 -13
- data/lib/friends/commands/list.rb +51 -47
- data/lib/friends/commands/stats.rb +3 -0
- data/lib/friends/event.rb +298 -0
- data/lib/friends/introvert.rb +109 -57
- data/lib/friends/note.rb +19 -0
- data/lib/friends/version.rb +1 -1
- data/test/add_event_helper.rb +410 -0
- data/test/commands/add/activity_spec.rb +6 -350
- data/test/commands/add/note_spec.rb +55 -0
- data/test/commands/clean_spec.rb +25 -3
- data/test/commands/list/notes_spec.rb +179 -0
- data/test/commands/list/tags_spec.rb +24 -0
- data/test/commands/stats_spec.rb +100 -7
- data/test/helper.rb +12 -0
- metadata +10 -2
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "./test/helper"
|
|
4
|
+
|
|
5
|
+
clean_describe "list notes" do
|
|
6
|
+
subject { run_cmd("list notes") }
|
|
7
|
+
|
|
8
|
+
describe "when file does not exist" do
|
|
9
|
+
let(:content) { nil }
|
|
10
|
+
|
|
11
|
+
it "does not list anything" do
|
|
12
|
+
stdout_only ""
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "when file is empty" do
|
|
17
|
+
let(:content) { "" }
|
|
18
|
+
|
|
19
|
+
it "does not list anything" do
|
|
20
|
+
stdout_only ""
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "when file has content" do
|
|
25
|
+
# Use scrambled content to differentiate between output that is sorted and output that
|
|
26
|
+
# only reads from the (usually-sorted) file.
|
|
27
|
+
let(:content) { SCRAMBLED_CONTENT }
|
|
28
|
+
|
|
29
|
+
it "lists notes in file order" do
|
|
30
|
+
stdout_only <<-OUTPUT
|
|
31
|
+
2015-01-04: Grace Hopper and George Washington Carver both won an award.
|
|
32
|
+
2015-06-06: Marie Curie just got accepted into a PhD program in Paris. @school
|
|
33
|
+
2017-03-12: Marie Curie completed her PhD in record time. @school
|
|
34
|
+
2015-06-15: Grace Hopper found out she's getting a big Naval Academy building named after her. @navy
|
|
35
|
+
OUTPUT
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe "--limit" do
|
|
39
|
+
subject { run_cmd("list notes --limit #{limit}") }
|
|
40
|
+
|
|
41
|
+
describe "when limit is less than 1" do
|
|
42
|
+
let(:limit) { 0 }
|
|
43
|
+
it "prints an error message" do
|
|
44
|
+
stderr_only "Error: Limit must be positive"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "when limit is 1 or greater" do
|
|
49
|
+
let(:limit) { 2 }
|
|
50
|
+
it "limits output to the number specified" do
|
|
51
|
+
stdout_only <<-OUTPUT
|
|
52
|
+
2015-01-04: Grace Hopper and George Washington Carver both won an award.
|
|
53
|
+
2015-06-06: Marie Curie just got accepted into a PhD program in Paris. @school
|
|
54
|
+
OUTPUT
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe "--in" do
|
|
60
|
+
subject { run_cmd("list notes --in #{location_name}") }
|
|
61
|
+
|
|
62
|
+
describe "when location does not exist" do
|
|
63
|
+
let(:location_name) { "Garbage" }
|
|
64
|
+
it "prints an error message" do
|
|
65
|
+
stderr_only 'Error: No location found for "Garbage"'
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe "when location exists" do
|
|
70
|
+
let(:location_name) { "paris" }
|
|
71
|
+
it "matches location case-insensitively" do
|
|
72
|
+
stdout_only "2015-06-06: "\
|
|
73
|
+
"Marie Curie just got accepted into a PhD program in Paris. @school"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe "--with" do
|
|
79
|
+
subject { run_cmd("list notes --with #{friend_name}") }
|
|
80
|
+
|
|
81
|
+
describe "when friend does not exist" do
|
|
82
|
+
let(:friend_name) { "Garbage" }
|
|
83
|
+
it "prints an error message" do
|
|
84
|
+
stderr_only 'Error: No friend found for "Garbage"'
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
describe "when friend name matches more than one friend" do
|
|
89
|
+
let(:friend_name) { "george" }
|
|
90
|
+
before { run_cmd("add friend George Harrison") }
|
|
91
|
+
it "prints an error message" do
|
|
92
|
+
stderr_only 'Error: More than one friend found for "george": '\
|
|
93
|
+
"George Harrison, George Washington Carver"
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe "when friend name matches one friend" do
|
|
98
|
+
let(:friend_name) { "grace" }
|
|
99
|
+
it "matches friend case-insensitively" do
|
|
100
|
+
stdout_only <<-OUTPUT
|
|
101
|
+
2015-01-04: Grace Hopper and George Washington Carver both won an award.
|
|
102
|
+
2015-06-15: Grace Hopper found out she's getting a big Naval Academy building named after her. @navy
|
|
103
|
+
OUTPUT
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe "when more than one friend name is passed" do
|
|
108
|
+
subject { run_cmd("list notes --with #{friend_name1} --with #{friend_name2}") }
|
|
109
|
+
let(:friend_name1) { "george" }
|
|
110
|
+
let(:friend_name2) { "grace" }
|
|
111
|
+
|
|
112
|
+
it "matches all friends case-insensitively" do
|
|
113
|
+
stdout_only "2015-01-04: Grace Hopper and George Washington Carver both won an award."
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
describe "--tagged" do
|
|
119
|
+
subject { run_cmd("list notes --tagged school") }
|
|
120
|
+
|
|
121
|
+
it "matches tag case-sensitively" do
|
|
122
|
+
stdout_only <<-OUTPUT
|
|
123
|
+
2015-06-06: Marie Curie just got accepted into a PhD program in Paris. @school
|
|
124
|
+
2017-03-12: Marie Curie completed her PhD in record time. @school
|
|
125
|
+
OUTPUT
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
describe "when more than one tag is passed" do
|
|
129
|
+
subject { run_cmd("list notes --tagged #{tag1} --tagged #{tag2}") }
|
|
130
|
+
let(:tag1) { "science" }
|
|
131
|
+
let(:tag2) { "school" }
|
|
132
|
+
let(:content) do
|
|
133
|
+
<<-FILE
|
|
134
|
+
### Notes:
|
|
135
|
+
- 2015-01-04: **Grace Hopper** and **George Washington Carver** both won an award. @recognition
|
|
136
|
+
- 2015-11-01: **Grace Hopper** just started a PhD program. @school @science
|
|
137
|
+
- 2014-11-15: **Marie Curie** made some amazing scientific discoveries today. @science
|
|
138
|
+
- 2014-12-31: **Marie Curie** completed her PhD today! @science @school
|
|
139
|
+
|
|
140
|
+
### Friends:
|
|
141
|
+
- George Washington Carver
|
|
142
|
+
- Marie Curie [Atlantis] @science
|
|
143
|
+
- Grace Hopper (a.k.a. The Admiral a.k.a. Amazing Grace) [Paris] @navy @science
|
|
144
|
+
FILE
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "matches all tags case-sensitively" do
|
|
148
|
+
stdout_only <<-OUTPUT
|
|
149
|
+
2015-11-01: Grace Hopper just started a PhD program. @school @science
|
|
150
|
+
2014-12-31: Marie Curie completed her PhD today! @science @school
|
|
151
|
+
OUTPUT
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
describe "--since" do
|
|
157
|
+
subject { run_cmd("list notes --since 'June 15th 2015'") }
|
|
158
|
+
|
|
159
|
+
it "lists notes on and after the specified date" do
|
|
160
|
+
stdout_only <<-OUTPUT
|
|
161
|
+
2017-03-12: Marie Curie completed her PhD in record time. @school
|
|
162
|
+
2015-06-15: Grace Hopper found out she's getting a big Naval Academy building named after her. @navy
|
|
163
|
+
OUTPUT
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
describe "--until" do
|
|
168
|
+
subject { run_cmd("list notes --until 'June 15th 2015'") }
|
|
169
|
+
|
|
170
|
+
it "lists notes before and on the specified date" do
|
|
171
|
+
stdout_only <<-OUTPUT
|
|
172
|
+
2015-01-04: Grace Hopper and George Washington Carver both won an award.
|
|
173
|
+
2015-06-06: Marie Curie just got accepted into a PhD program in Paris. @school
|
|
174
|
+
2015-06-15: Grace Hopper found out she's getting a big Naval Academy building named after her. @navy
|
|
175
|
+
OUTPUT
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
@@ -31,6 +31,7 @@ clean_describe "list tags" do
|
|
|
31
31
|
@food
|
|
32
32
|
@navy
|
|
33
33
|
@partying
|
|
34
|
+
@school
|
|
34
35
|
@science
|
|
35
36
|
OUTPUT
|
|
36
37
|
end
|
|
@@ -46,12 +47,35 @@ clean_describe "list tags" do
|
|
|
46
47
|
end
|
|
47
48
|
end
|
|
48
49
|
|
|
50
|
+
describe "--from notes" do
|
|
51
|
+
subject { run_cmd("list tags --from notes") }
|
|
52
|
+
|
|
53
|
+
it "lists unique tags from notes" do
|
|
54
|
+
stdout_only <<-OUTPUT
|
|
55
|
+
@navy
|
|
56
|
+
@school
|
|
57
|
+
OUTPUT
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
49
61
|
describe "--from friends" do
|
|
50
62
|
subject { run_cmd("list tags --from friends") }
|
|
51
63
|
|
|
52
64
|
it "lists unique tags from friends" do
|
|
53
65
|
stdout_only <<-OUTPUT
|
|
54
66
|
@navy
|
|
67
|
+
@science
|
|
68
|
+
OUTPUT
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe "with more than one --from flag" do
|
|
73
|
+
subject { run_cmd("list tags --from friends --from notes") }
|
|
74
|
+
|
|
75
|
+
it "lists unique tags from friends and notes" do
|
|
76
|
+
stdout_only <<-OUTPUT
|
|
77
|
+
@navy
|
|
78
|
+
@school
|
|
55
79
|
@science
|
|
56
80
|
OUTPUT
|
|
57
81
|
end
|
data/test/commands/stats_spec.rb
CHANGED
|
@@ -9,11 +9,14 @@ clean_describe "stats" do
|
|
|
9
9
|
let(:content) { nil }
|
|
10
10
|
|
|
11
11
|
it "returns the stats" do
|
|
12
|
-
stdout_only <<-
|
|
12
|
+
stdout_only <<-OUTPUT
|
|
13
13
|
Total activities: 0
|
|
14
14
|
Total friends: 0
|
|
15
|
+
Total locations: 0
|
|
16
|
+
Total notes: 0
|
|
17
|
+
Total tags: 0
|
|
15
18
|
Total time elapsed: 0 days
|
|
16
|
-
|
|
19
|
+
OUTPUT
|
|
17
20
|
end
|
|
18
21
|
end
|
|
19
22
|
|
|
@@ -21,11 +24,14 @@ Total time elapsed: 0 days
|
|
|
21
24
|
let(:content) { "" }
|
|
22
25
|
|
|
23
26
|
it "returns the stats" do
|
|
24
|
-
stdout_only <<-
|
|
27
|
+
stdout_only <<-OUTPUT
|
|
25
28
|
Total activities: 0
|
|
26
29
|
Total friends: 0
|
|
30
|
+
Total locations: 0
|
|
31
|
+
Total notes: 0
|
|
32
|
+
Total tags: 0
|
|
27
33
|
Total time elapsed: 0 days
|
|
28
|
-
|
|
34
|
+
OUTPUT
|
|
29
35
|
end
|
|
30
36
|
end
|
|
31
37
|
|
|
@@ -33,11 +39,98 @@ Total time elapsed: 0 days
|
|
|
33
39
|
let(:content) { CONTENT }
|
|
34
40
|
|
|
35
41
|
it "returns the content" do
|
|
36
|
-
stdout_only <<-
|
|
42
|
+
stdout_only <<-OUTPUT
|
|
37
43
|
Total activities: 4
|
|
38
44
|
Total friends: 3
|
|
39
|
-
Total
|
|
40
|
-
|
|
45
|
+
Total locations: 3
|
|
46
|
+
Total notes: 4
|
|
47
|
+
Total tags: 5
|
|
48
|
+
Total time elapsed: 848 days
|
|
49
|
+
OUTPUT
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe "when the file has a single note and no activities" do
|
|
53
|
+
let(:content) do
|
|
54
|
+
<<-FILE
|
|
55
|
+
### Notes:
|
|
56
|
+
- 2015-11-01: **Grace Hopper** just started a PhD program. @school @science
|
|
57
|
+
FILE
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "counts elapsed days as 0" do
|
|
61
|
+
stdout_only <<-OUTPUT
|
|
62
|
+
Total activities: 0
|
|
63
|
+
Total friends: 0
|
|
64
|
+
Total locations: 0
|
|
65
|
+
Total notes: 1
|
|
66
|
+
Total tags: 2
|
|
67
|
+
Total time elapsed: 0 days
|
|
68
|
+
OUTPUT
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe "when the file has a single activity and no notes" do
|
|
73
|
+
let(:content) do
|
|
74
|
+
<<-FILE
|
|
75
|
+
### Activities:
|
|
76
|
+
- 2015-11-01: **Grace Hopper** and I got lunch today.
|
|
77
|
+
FILE
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "counts elapsed days as 0" do
|
|
81
|
+
stdout_only <<-OUTPUT
|
|
82
|
+
Total activities: 1
|
|
83
|
+
Total friends: 0
|
|
84
|
+
Total locations: 0
|
|
85
|
+
Total notes: 0
|
|
86
|
+
Total tags: 0
|
|
87
|
+
Total time elapsed: 0 days
|
|
88
|
+
OUTPUT
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe "when the file has one activity and one note" do
|
|
93
|
+
let(:content) do
|
|
94
|
+
<<-FILE
|
|
95
|
+
### Activities:
|
|
96
|
+
- #{activity_date}: **Grace Hopper** and I got lunch today.
|
|
97
|
+
|
|
98
|
+
### Notes:
|
|
99
|
+
- #{note_date}: **Grace Hopper** just started a PhD program. @school @science
|
|
100
|
+
FILE
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
describe "when the note and activity are on the same day" do
|
|
104
|
+
let(:activity_date) { "2015-11-01" }
|
|
105
|
+
let(:note_date) { activity_date }
|
|
106
|
+
|
|
107
|
+
it "counts elapsed days as 0" do
|
|
108
|
+
stdout_only <<-OUTPUT
|
|
109
|
+
Total activities: 1
|
|
110
|
+
Total friends: 0
|
|
111
|
+
Total locations: 0
|
|
112
|
+
Total notes: 1
|
|
113
|
+
Total tags: 2
|
|
114
|
+
Total time elapsed: 0 days
|
|
115
|
+
OUTPUT
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe "when the note and activity are one day apart" do
|
|
120
|
+
let(:activity_date) { "2015-11-01" }
|
|
121
|
+
let(:note_date) { "2015-11-02" }
|
|
122
|
+
|
|
123
|
+
it "uses the singular for one elapsed day" do
|
|
124
|
+
stdout_only <<-OUTPUT
|
|
125
|
+
Total activities: 1
|
|
126
|
+
Total friends: 0
|
|
127
|
+
Total locations: 0
|
|
128
|
+
Total notes: 1
|
|
129
|
+
Total tags: 2
|
|
130
|
+
Total time elapsed: 1 day
|
|
131
|
+
OUTPUT
|
|
132
|
+
end
|
|
133
|
+
end
|
|
41
134
|
end
|
|
42
135
|
end
|
|
43
136
|
end
|
data/test/helper.rb
CHANGED
|
@@ -31,6 +31,12 @@ CONTENT = <<-FILE.freeze
|
|
|
31
31
|
- 2014-12-31: Celebrated the new year in _Paris_ with **Marie Curie**. @partying
|
|
32
32
|
- 2014-11-15: Talked to **George Washington Carver** on the phone for an hour.
|
|
33
33
|
|
|
34
|
+
### Notes:
|
|
35
|
+
- 2017-03-12: **Marie Curie** completed her PhD in record time. @school
|
|
36
|
+
- 2015-06-15: **Grace Hopper** found out she's getting a big Naval Academy building named after her. @navy
|
|
37
|
+
- 2015-06-06: **Marie Curie** just got accepted into a PhD program in _Paris_. @school
|
|
38
|
+
- 2015-01-04: **Grace Hopper** and **George Washington Carver** both won an award.
|
|
39
|
+
|
|
34
40
|
### Friends:
|
|
35
41
|
- George Washington Carver
|
|
36
42
|
- Grace Hopper (a.k.a. The Admiral a.k.a. Amazing Grace) [Paris] @navy @science
|
|
@@ -50,6 +56,12 @@ SCRAMBLED_CONTENT = <<-FILE.freeze
|
|
|
50
56
|
- 2014-11-15: Talked to **George Washington Carver** on the phone for an hour.
|
|
51
57
|
- 2014-12-31: Celebrated the new year in _Paris_ with **Marie Curie**. @partying
|
|
52
58
|
|
|
59
|
+
### Notes:
|
|
60
|
+
- 2015-01-04: **Grace Hopper** and **George Washington Carver** both won an award.
|
|
61
|
+
- 2015-06-06: **Marie Curie** just got accepted into a PhD program in _Paris_. @school
|
|
62
|
+
- 2017-03-12: **Marie Curie** completed her PhD in record time. @school
|
|
63
|
+
- 2015-06-15: **Grace Hopper** found out she's getting a big Naval Academy building named after her. @navy
|
|
64
|
+
|
|
53
65
|
### Friends:
|
|
54
66
|
- George Washington Carver
|
|
55
67
|
- Marie Curie [Atlantis] @science
|
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.35'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jacob Evelyn
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-01-
|
|
11
|
+
date: 2018-01-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: chronic
|
|
@@ -201,18 +201,22 @@ files:
|
|
|
201
201
|
- lib/friends/commands/stats.rb
|
|
202
202
|
- lib/friends/commands/suggest.rb
|
|
203
203
|
- lib/friends/commands/update.rb
|
|
204
|
+
- lib/friends/event.rb
|
|
204
205
|
- lib/friends/friend.rb
|
|
205
206
|
- lib/friends/friends_error.rb
|
|
206
207
|
- lib/friends/graph.rb
|
|
207
208
|
- lib/friends/introvert.rb
|
|
208
209
|
- lib/friends/location.rb
|
|
210
|
+
- lib/friends/note.rb
|
|
209
211
|
- lib/friends/regex_builder.rb
|
|
210
212
|
- lib/friends/serializable.rb
|
|
211
213
|
- lib/friends/version.rb
|
|
214
|
+
- test/add_event_helper.rb
|
|
212
215
|
- test/commands/add/activity_spec.rb
|
|
213
216
|
- test/commands/add/friend_spec.rb
|
|
214
217
|
- test/commands/add/location_spec.rb
|
|
215
218
|
- test/commands/add/nickname_spec.rb
|
|
219
|
+
- test/commands/add/note_spec.rb
|
|
216
220
|
- test/commands/add/tag_spec.rb
|
|
217
221
|
- test/commands/clean_spec.rb
|
|
218
222
|
- test/commands/edit_spec.rb
|
|
@@ -223,6 +227,7 @@ files:
|
|
|
223
227
|
- test/commands/list/favorite/locations_spec.rb
|
|
224
228
|
- test/commands/list/friends_spec.rb
|
|
225
229
|
- test/commands/list/locations_spec.rb
|
|
230
|
+
- test/commands/list/notes_spec.rb
|
|
226
231
|
- test/commands/list/tags_spec.rb
|
|
227
232
|
- test/commands/remove/nickname_spec.rb
|
|
228
233
|
- test/commands/remove/tag_spec.rb
|
|
@@ -259,10 +264,12 @@ signing_key:
|
|
|
259
264
|
specification_version: 4
|
|
260
265
|
summary: Spend time with the people you care about.
|
|
261
266
|
test_files:
|
|
267
|
+
- test/add_event_helper.rb
|
|
262
268
|
- test/commands/add/activity_spec.rb
|
|
263
269
|
- test/commands/add/friend_spec.rb
|
|
264
270
|
- test/commands/add/location_spec.rb
|
|
265
271
|
- test/commands/add/nickname_spec.rb
|
|
272
|
+
- test/commands/add/note_spec.rb
|
|
266
273
|
- test/commands/add/tag_spec.rb
|
|
267
274
|
- test/commands/clean_spec.rb
|
|
268
275
|
- test/commands/edit_spec.rb
|
|
@@ -273,6 +280,7 @@ test_files:
|
|
|
273
280
|
- test/commands/list/favorite/locations_spec.rb
|
|
274
281
|
- test/commands/list/friends_spec.rb
|
|
275
282
|
- test/commands/list/locations_spec.rb
|
|
283
|
+
- test/commands/list/notes_spec.rb
|
|
276
284
|
- test/commands/list/tags_spec.rb
|
|
277
285
|
- test/commands/remove/nickname_spec.rb
|
|
278
286
|
- test/commands/remove/tag_spec.rb
|