pathspec 0.1.2 → 0.2.1

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.
@@ -1,17 +1,21 @@
1
1
  require 'pathspec/spec'
2
2
 
3
- class RegexSpec < Spec
4
- def initialize(regex)
5
- @regex = Regexp.compile regex
3
+ class PathSpec
4
+ # Simple regex-based spec
5
+ class RegexSpec < Spec
6
+ def initialize(pattern)
7
+ @pattern = pattern.dup
8
+ @regex = Regexp.compile pattern
6
9
 
7
- super
8
- end
10
+ super
11
+ end
9
12
 
10
- def inclusive?
11
- true
12
- end
13
+ def inclusive?
14
+ true
15
+ end
13
16
 
14
- def match(path)
15
- @regex.match(path) if @regex
17
+ def match(path)
18
+ @regex.match(path) if @regex
19
+ end
16
20
  end
17
21
  end
@@ -1,14 +1,21 @@
1
- class Spec
2
- attr_reader :regex
1
+ class PathSpec
2
+ # Abstract spec
3
+ class Spec
4
+ attr_reader :regex
5
+ attr_reader :pattern
3
6
 
4
- def initialize(*_)
5
- end
7
+ def initialize(*_); end
6
8
 
7
- def match(files)
8
- raise "Unimplemented"
9
- end
9
+ def match(files)
10
+ raise 'Unimplemented'
11
+ end
12
+
13
+ def inclusive?
14
+ true
15
+ end
10
16
 
11
- def inclusive?
12
- true
17
+ def to_s
18
+ @pattern
19
+ end
13
20
  end
14
21
  end
@@ -0,0 +1,2 @@
1
+ !**/important.txt
2
+ abc/**
@@ -0,0 +1,51 @@
1
+ # Source: https://github.com/github/gitignore/blob/master/Ruby.gitignore
2
+ *.gem
3
+ *.rbc
4
+ /.config
5
+ /coverage/
6
+ /InstalledFiles
7
+ /pkg/
8
+ /spec/reports/
9
+ /spec/examples.txt
10
+ /test/tmp/
11
+ /test/version_tmp/
12
+ /tmp/
13
+
14
+ # Used by dotenv library to load environment variables.
15
+ # .env
16
+
17
+ ## Specific to RubyMotion:
18
+ .dat*
19
+ .repl_history
20
+ build/
21
+ *.bridgesupport
22
+ build-iPhoneOS/
23
+ build-iPhoneSimulator/
24
+
25
+ ## Specific to RubyMotion (use of CocoaPods):
26
+ #
27
+ # We recommend against adding the Pods directory to your .gitignore. However
28
+ # you should judge for yourself, the pros and cons are mentioned at:
29
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
30
+ #
31
+ # vendor/Pods/
32
+
33
+ ## Documentation cache and generated files:
34
+ /.yardoc/
35
+ /_yardoc/
36
+ /doc/
37
+ /rdoc/
38
+
39
+ ## Environment normalization:
40
+ /.bundle/
41
+ /vendor/bundle
42
+ /lib/bundler/man/
43
+
44
+ # for a library or gem, you might want to ignore these files since the code is
45
+ # intended to run in multiple environments; otherwise, check them in:
46
+ # Gemfile.lock
47
+ # .ruby-version
48
+ # .ruby-gemset
49
+
50
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
51
+ .rvmrc
@@ -0,0 +1 @@
1
+ *.md
@@ -0,0 +1 @@
1
+ .*\.md
@@ -1,9 +1,6 @@
1
1
  begin
2
2
  require 'simplecov'
3
3
  SimpleCov.start
4
-
5
- require 'codecov'
6
- SimpleCov.formatter = SimpleCov::Formatter::Codecov
7
- rescue
4
+ rescue StandardError
8
5
  puts 'SimpleCov failed to start, most likely this due to running Ruby 1.8.7'
9
6
  end
@@ -1,20 +1,20 @@
1
1
  require 'spec_helper'
2
2
  require 'pathspec/gitignorespec'
3
3
 
4
- describe GitIgnoreSpec do
4
+ describe PathSpec::GitIgnoreSpec do
5
5
  # Original specification by http://git-scm.com/docs/gitignore
6
6
 
7
7
  # A blank line matches no files, so it can serve as a separator for
8
8
  # readability.
9
9
  describe 'does nothing for newlines' do
10
- subject { GitIgnoreSpec.new "\n" }
10
+ subject { PathSpec::GitIgnoreSpec.new "\n" }
11
11
  it { is_expected.to_not match('foo.tmp') }
12
12
  it { is_expected.to_not match(' ') }
13
13
  it { is_expected.to_not be_inclusive }
14
14
  end
15
15
 
16
16
  describe 'does nothing for blank strings' do
17
- subject { GitIgnoreSpec.new '' }
17
+ subject { PathSpec::GitIgnoreSpec.new '' }
18
18
  it { is_expected.to_not match 'foo.tmp' }
19
19
  it { is_expected.to_not match ' ' }
20
20
  it { is_expected.to_not be_inclusive }
@@ -23,21 +23,21 @@ describe GitIgnoreSpec do
23
23
  # A line starting with # serves as a comment. Put a backslash ("\") in front
24
24
  # of the first hash for patterns that begin with a hash.
25
25
  describe 'does nothing for comments' do
26
- subject { GitIgnoreSpec.new '# this is a gitignore style comment' }
26
+ subject { PathSpec::GitIgnoreSpec.new '# this is a gitignore style comment' }
27
27
  it { is_expected.to_not match('foo.tmp') }
28
28
  it { is_expected.to_not match(' ') }
29
29
  it { is_expected.to_not be_inclusive }
30
30
  end
31
31
 
32
32
  describe 'ignores comment char with a slash' do
33
- subject { GitIgnoreSpec.new '\#averystrangefile' }
33
+ subject { PathSpec::GitIgnoreSpec.new '\#averystrangefile' }
34
34
  it { is_expected.to match('#averystrangefile') }
35
35
  it { is_expected.to_not match('foobar') }
36
36
  it { is_expected.to be_inclusive }
37
37
  end
38
38
 
39
39
  describe 'escapes characters with slashes' do
40
- subject { GitIgnoreSpec.new 'twinkletwinkle\*' }
40
+ subject { PathSpec::GitIgnoreSpec.new 'twinkletwinkle\*' }
41
41
  it { is_expected.to match('twinkletwinkle*') }
42
42
  it { is_expected.to_not match('twinkletwinkletwinkle') }
43
43
  it { is_expected.to be_inclusive }
@@ -45,7 +45,7 @@ describe GitIgnoreSpec do
45
45
 
46
46
  # Trailing spaces are ignored unless they are quoted with backlash ("\").
47
47
  describe 'ignores trailing spaces' do
48
- subject { GitIgnoreSpec.new 'foo ' }
48
+ subject { PathSpec::GitIgnoreSpec.new 'foo ' }
49
49
  it { is_expected.to match('foo') }
50
50
  it { is_expected.to_not match('foo ') }
51
51
  it { is_expected.to be_inclusive }
@@ -62,7 +62,7 @@ describe GitIgnoreSpec do
62
62
  # backslash ("\") in front of the first "!" for patterns that begin with a
63
63
  # literal "!", for example, "\!important!.txt".
64
64
  describe 'is exclusive of !' do
65
- subject { GitIgnoreSpec.new '!important.txt' }
65
+ subject { PathSpec::GitIgnoreSpec.new '!important.txt' }
66
66
  it { is_expected.to match('important.txt') }
67
67
  it { is_expected.to_not be_inclusive }
68
68
  it { is_expected.to_not match('!important.txt') }
@@ -74,7 +74,7 @@ describe GitIgnoreSpec do
74
74
  # will not match a regular file or a symbolic link foo (this is consistent
75
75
  # with the way how pathspec works in general in Git).
76
76
  describe 'trailing slashes match directories and their contents but not regular files or symlinks' do
77
- subject { GitIgnoreSpec.new 'foo/' }
77
+ subject { PathSpec::GitIgnoreSpec.new 'foo/' }
78
78
  it { is_expected.to match('foo/') }
79
79
  it { is_expected.to match('foo/bar') }
80
80
  it { is_expected.to match('baz/foo/bar') }
@@ -87,7 +87,7 @@ describe GitIgnoreSpec do
87
87
  # of the .gitignore file (relative to the toplevel of the work tree if not
88
88
  # from a .gitignore file).
89
89
  describe 'handles basic globbing' do
90
- subject { GitIgnoreSpec.new '*.tmp' }
90
+ subject { PathSpec::GitIgnoreSpec.new '*.tmp' }
91
91
  it { is_expected.to match('foo.tmp') }
92
92
  it { is_expected.to match('foo/bar.tmp') }
93
93
  it { is_expected.to match('foo/bar.tmp/baz') }
@@ -96,7 +96,7 @@ describe GitIgnoreSpec do
96
96
  end
97
97
 
98
98
  describe 'handles inner globs' do
99
- subject { GitIgnoreSpec.new 'foo-*-bar' }
99
+ subject { PathSpec::GitIgnoreSpec.new 'foo-*-bar' }
100
100
  it { is_expected.to match('foo--bar') }
101
101
  it { is_expected.to match('foo-hello-bar') }
102
102
  it { is_expected.to match('a/foo-hello-bar') }
@@ -106,7 +106,7 @@ describe GitIgnoreSpec do
106
106
  end
107
107
 
108
108
  describe 'handles postfix globs' do
109
- subject { GitIgnoreSpec.new '~temp-*' }
109
+ subject { PathSpec::GitIgnoreSpec.new '~temp-*' }
110
110
  it { is_expected.to match('~temp-') }
111
111
  it { is_expected.to match('~temp-foo') }
112
112
  it { is_expected.to match('foo/~temp-bar') }
@@ -115,14 +115,14 @@ describe GitIgnoreSpec do
115
115
  end
116
116
 
117
117
  describe 'handles multiple globs' do
118
- subject { GitIgnoreSpec.new '*.middle.*' }
118
+ subject { PathSpec::GitIgnoreSpec.new '*.middle.*' }
119
119
  it { is_expected.to match('hello.middle.rb') }
120
120
  it { is_expected.to_not match('foo.rb') }
121
121
  it { is_expected.to be_inclusive }
122
122
  end
123
123
 
124
124
  describe 'handles dir globs' do
125
- subject { GitIgnoreSpec.new 'dir/*' }
125
+ subject { PathSpec::GitIgnoreSpec.new 'dir/*' }
126
126
  it { is_expected.to match('dir/foo') }
127
127
  it { is_expected.to_not match('foo/') }
128
128
  it { is_expected.to be_inclusive }
@@ -134,14 +134,14 @@ describe GitIgnoreSpec do
134
134
  # "Documentation/git.html" but not "Documentation/ppc/ppc.html" or
135
135
  # "tools/perf/Documentation/perf.html".
136
136
  describe 'handles dir globs' do
137
- subject { GitIgnoreSpec.new 'dir/*' }
137
+ subject { PathSpec::GitIgnoreSpec.new 'dir/*' }
138
138
  it { is_expected.to match('dir/foo') }
139
139
  it { is_expected.to_not match('foo/') }
140
140
  it { is_expected.to be_inclusive }
141
141
  end
142
142
 
143
143
  describe 'handles globs inside of dirs' do
144
- subject { GitIgnoreSpec.new 'Documentation/*.html' }
144
+ subject { PathSpec::GitIgnoreSpec.new 'Documentation/*.html' }
145
145
  it { is_expected.to match('Documentation/git.html') }
146
146
  it { is_expected.to_not match('Documentation/ppc/ppc.html') }
147
147
  it { is_expected.to_not match('tools/perf/Documentation/perf.html') } # TODO: Or is it? Git 2 weirdness?
@@ -149,14 +149,14 @@ describe GitIgnoreSpec do
149
149
  end
150
150
 
151
151
  describe 'handles wildcards' do
152
- subject { GitIgnoreSpec.new 'jokeris????' }
152
+ subject { PathSpec::GitIgnoreSpec.new 'jokeris????' }
153
153
  it { is_expected.to match('jokeriswild') }
154
154
  it { is_expected.to_not match('jokerisfat') }
155
155
  it { is_expected.to be_inclusive }
156
156
  end
157
157
 
158
158
  describe 'handles brackets' do
159
- subject { GitIgnoreSpec.new '*[eu][xl]*' }
159
+ subject { PathSpec::GitIgnoreSpec.new '*[eu][xl]*' }
160
160
  it { is_expected.to match('youknowregex') }
161
161
  it { is_expected.to match('youknowregularexpressions') }
162
162
  it { is_expected.to_not match('youknownothing') }
@@ -164,19 +164,19 @@ describe GitIgnoreSpec do
164
164
  end
165
165
 
166
166
  describe 'handles unmatched brackets' do
167
- subject { GitIgnoreSpec.new '*[*[*' }
167
+ subject { PathSpec::GitIgnoreSpec.new '*[*[*' }
168
168
  it { is_expected.to match('bracket[oh[wow') }
169
169
  it { is_expected.to be_inclusive }
170
170
  end
171
171
 
172
172
  describe 'handles brackets with carats' do
173
- subject { GitIgnoreSpec.new '*[^]' }
173
+ subject { PathSpec::GitIgnoreSpec.new '*[^]' }
174
174
  it { is_expected.to match('myfavorite^') }
175
175
  it { is_expected.to be_inclusive }
176
176
  end
177
177
 
178
178
  describe 'handles brackets for brackets' do
179
- subject { GitIgnoreSpec.new '*[]]' }
179
+ subject { PathSpec::GitIgnoreSpec.new '*[]]' }
180
180
  it { is_expected.to match('yodawg[]]') }
181
181
  it { is_expected.to be_inclusive }
182
182
  end
@@ -189,7 +189,7 @@ describe GitIgnoreSpec do
189
189
  end
190
190
 
191
191
  describe 'handles negated brackets' do
192
- subject { GitIgnoreSpec.new 'ab[!cd]ef' }
192
+ subject { PathSpec::GitIgnoreSpec.new 'ab[!cd]ef' }
193
193
  it { is_expected.to_not match('abcef') }
194
194
  it { is_expected.to match('abzef') }
195
195
  it { is_expected.to be_inclusive }
@@ -198,14 +198,14 @@ describe GitIgnoreSpec do
198
198
  # A leading slash matches the beginning of the pathname. For example, "/*.c"
199
199
  # matches "cat-file.c" but not "mozilla-sha1/sha1.c".
200
200
  describe 'handles leading / as relative to base directory' do
201
- subject { GitIgnoreSpec.new '/*.c' }
201
+ subject { PathSpec::GitIgnoreSpec.new '/*.c' }
202
202
  it { is_expected.to match('cat-file.c') }
203
203
  it { is_expected.to_not match('mozilla-sha1/sha1.c') }
204
204
  it { is_expected.to be_inclusive }
205
205
  end
206
206
 
207
207
  describe 'handles simple single paths' do
208
- subject { GitIgnoreSpec.new 'spam' }
208
+ subject { PathSpec::GitIgnoreSpec.new 'spam' }
209
209
  it { is_expected.to match('spam') }
210
210
  it { is_expected.to match('spam/') }
211
211
  it { is_expected.to match('foo/spam') }
@@ -222,7 +222,7 @@ describe GitIgnoreSpec do
222
222
  # pattern "foo". "**/foo/bar" matches file or directory "bar" anywhere that is
223
223
  # directly under directory "foo".
224
224
  describe 'handles prefixed ** as searching any location' do
225
- subject { GitIgnoreSpec.new '**/foo' }
225
+ subject { PathSpec::GitIgnoreSpec.new '**/foo' }
226
226
  it { is_expected.to match('foo') }
227
227
  it { is_expected.to match('bar/foo') }
228
228
  it { is_expected.to match('baz/bar/foo') }
@@ -231,7 +231,7 @@ describe GitIgnoreSpec do
231
231
  end
232
232
 
233
233
  describe 'handles prefixed ** with a directory as searching a file under a directory in any location' do
234
- subject { GitIgnoreSpec.new '**/foo/bar' }
234
+ subject { PathSpec::GitIgnoreSpec.new '**/foo/bar' }
235
235
  it { is_expected.to_not match('foo') }
236
236
  it { is_expected.to match('foo/bar') }
237
237
  it { is_expected.to match('baz/foo/bar') }
@@ -245,7 +245,7 @@ describe GitIgnoreSpec do
245
245
  # all files inside directory "abc", relative to the location of the .gitignore
246
246
  # file, with infinite depth.
247
247
  describe 'handles leading /** as all files inside a directory' do
248
- subject { GitIgnoreSpec.new 'abc/**' }
248
+ subject { PathSpec::GitIgnoreSpec.new 'abc/**' }
249
249
  it { is_expected.to match('abc/') }
250
250
  it { is_expected.to match('abc/def') }
251
251
  it { is_expected.to_not match('123/abc/def') }
@@ -257,7 +257,7 @@ describe GitIgnoreSpec do
257
257
  # more directories. For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b"
258
258
  # and so on.
259
259
  describe 'handles /** in the middle of a path' do
260
- subject { GitIgnoreSpec.new 'a/**/b' }
260
+ subject { PathSpec::GitIgnoreSpec.new 'a/**/b' }
261
261
  it { is_expected.to match('a/b') }
262
262
  it { is_expected.to match('a/x/b') }
263
263
  it { is_expected.to match('a/x/y/b') }
@@ -267,7 +267,7 @@ describe GitIgnoreSpec do
267
267
  end
268
268
 
269
269
  describe 'matches all paths when given **' do
270
- subject { GitIgnoreSpec.new '**' }
270
+ subject { PathSpec::GitIgnoreSpec.new '**' }
271
271
 
272
272
  it { is_expected.to match('a/b') }
273
273
  it { is_expected.to match('a/x/b') }
@@ -278,7 +278,7 @@ describe GitIgnoreSpec do
278
278
 
279
279
  # Other consecutive asterisks are considered invalid.
280
280
  describe 'considers other consecutive asterisks invalid' do
281
- subject { GitIgnoreSpec.new 'a/***/b' }
281
+ subject { PathSpec::GitIgnoreSpec.new 'a/***/b' }
282
282
  it { is_expected.to_not match('a/b') }
283
283
  it { is_expected.to_not match('a/x/b') }
284
284
  it { is_expected.to_not match('a/x/y/b') }
@@ -288,18 +288,16 @@ describe GitIgnoreSpec do
288
288
  end
289
289
 
290
290
  describe 'does not match single absolute paths' do
291
- subject { GitIgnoreSpec.new "/" }
291
+ subject { PathSpec::GitIgnoreSpec.new '/' }
292
292
  it { is_expected.to_not match('foo.tmp') }
293
293
  it { is_expected.to_not match(' ') }
294
294
  it { is_expected.to_not match('a/b') }
295
295
  end
296
296
 
297
297
  describe 'nested paths are relative to the file' do
298
- subject { GitIgnoreSpec.new 'foo/spam' }
298
+ subject { PathSpec::GitIgnoreSpec.new 'foo/spam' }
299
299
  it { is_expected.to match('foo/spam') }
300
300
  it { is_expected.to match('foo/spam/bar') }
301
301
  it { is_expected.to_not match('bar/foo/spam') }
302
302
  end
303
-
304
-
305
303
  end
@@ -1,12 +1,12 @@
1
1
  require 'spec_helper'
2
2
  require 'pathspec/spec'
3
3
 
4
- describe Spec do
5
- subject { Spec.new }
4
+ describe PathSpec::Spec do
5
+ subject { PathSpec::Spec.new }
6
6
 
7
- it "does not allow matching" do
8
- expect { subject.match "anything" }.to raise_error
7
+ it 'does not allow matching' do
8
+ expect { subject.match 'anything' }.to raise_error(/Unimplemented/)
9
9
  end
10
10
 
11
- it { is_expected.to be_inclusive }
11
+ it { is_expected.to be_inclusive }
12
12
  end
@@ -4,30 +4,47 @@ require 'pathspec'
4
4
  require 'fakefs/spec_helpers'
5
5
 
6
6
  describe PathSpec do
7
- shared_examples "standard gitignore negation" do
8
- it { is_expected.to_not match('important.txt') }
9
- it { is_expected.to_not match('foo/important.txt') }
10
- it { is_expected.to match('foo/bar/') }
7
+ shared_examples 'standard gitignore negation' do
8
+ it { is_expected.not_to match('important.txt') }
9
+ it { is_expected.not_to match('abc/important.txt') }
10
+ it { is_expected.to match('bar/baz/') }
11
+ it { is_expected.to match('foo/file') }
12
+ it { is_expected.not_to match('foo/important.txt') }
13
+ it { is_expected.to match('foo/subdir/file') }
11
14
  end
12
15
 
13
- context "initialization" do
14
- context "from multilines" do
15
- context "#new" do
16
- subject { PathSpec.new <<-IGNORELINES
16
+ # Specs that should be kept up to date with the README
17
+ context 'README.md' do
18
+ subject { PathSpec.from_filename 'spec/files/gitignore_readme' }
19
+
20
+ it { is_expected.to match('abc/def.rb') }
21
+ it { is_expected.not_to match('abc/important.txt') }
22
+ it do
23
+ expect(subject.match_paths(['/abc/123', '/abc/important.txt', '/abc/'])).to contain_exactly(
24
+ '/abc/123',
25
+ '/abc/')
26
+ end
27
+ end
28
+
29
+ context 'initialization' do
30
+ context 'from multilines' do
31
+ context '#new' do
32
+ subject {
33
+ PathSpec.new <<-IGNORELINES
17
34
  !important.txt
18
35
  foo/**
19
36
  /bar/baz
20
37
  IGNORELINES
21
38
  }
22
39
 
23
- it_behaves_like "standard gitignore negation"
40
+ it_behaves_like 'standard gitignore negation'
24
41
  end
25
42
  end
26
43
 
27
- context "from a string with no newlines" do
28
- let(:str) { "foo/**" }
44
+ context 'from a string with no newlines' do
45
+ let(:str) { 'foo/**' }
29
46
 
30
- context "#new" do
47
+ context '#new' do
31
48
  subject { PathSpec.new str }
32
49
 
33
50
  it { is_expected.to match('foo/important.txt') }
@@ -35,67 +52,67 @@ IGNORELINES
35
52
  end
36
53
  end
37
54
 
38
- context "from a non-string/non-enumerable" do
39
- it "throws an exception" do
40
- expect { PathSpec.new Object.new }.to raise_error
55
+ context 'from a non-string/non-enumerable' do
56
+ it 'throws an exception' do
57
+ expect { PathSpec.new Object.new }.to raise_error(/Cannot make Pathspec/)
41
58
  end
42
59
  end
43
60
 
44
- context "from array of gitignore strings" do
45
- let(:arr) { ["!important.txt", "foo/**", "/bar/baz"] }
61
+ context 'from array of gitignore strings' do
62
+ let(:arr) { ['!important.txt', 'foo/**', '/bar/baz'] }
46
63
 
47
- context "#new" do
64
+ context '#new' do
48
65
  subject { PathSpec.new arr }
49
66
 
50
- it_behaves_like "standard gitignore negation"
67
+ it_behaves_like 'standard gitignore negation'
51
68
  end
52
69
 
53
- context "#from_lines" do
70
+ context '#from_lines' do
54
71
  subject {
55
72
  PathSpec.from_lines(arr)
56
73
  }
57
74
 
58
- it_behaves_like "standard gitignore negation"
75
+ it_behaves_like 'standard gitignore negation'
59
76
  end
60
77
 
61
- context "#add array" do
78
+ context '#add array' do
62
79
  subject {
63
80
  ps = PathSpec.new []
64
81
  ps.add arr
65
82
  }
66
83
 
67
- it_behaves_like "standard gitignore negation"
84
+ it_behaves_like 'standard gitignore negation'
68
85
  end
69
86
  end
70
87
 
71
- context "from linedelimited gitignore string" do
88
+ context 'from linedelimited gitignore string' do
72
89
  let(:line) { "!important.txt\nfoo/**\n/bar/baz\n" }
73
90
 
74
- context "#new" do
91
+ context '#new' do
75
92
  subject { PathSpec.new line }
76
93
 
77
- it_behaves_like "standard gitignore negation"
94
+ it_behaves_like 'standard gitignore negation'
78
95
  end
79
96
 
80
- context "#from_lines" do
97
+ context '#from_lines' do
81
98
  subject {
82
99
  PathSpec.from_lines(line)
83
100
  }
84
101
 
85
- it_behaves_like "standard gitignore negation"
102
+ it_behaves_like 'standard gitignore negation'
86
103
  end
87
104
 
88
- context "#add" do
105
+ context '#add' do
89
106
  subject {
90
107
  ps = PathSpec.new
91
108
  ps.add line
92
109
  }
93
110
 
94
- it_behaves_like "standard gitignore negation"
111
+ it_behaves_like 'standard gitignore negation'
95
112
  end
96
113
  end
97
114
 
98
- context "from a gitignore file" do
115
+ context 'from a gitignore file' do
99
116
  include FakeFS::SpecHelpers
100
117
 
101
118
  let(:filename) { '.gitignore' }
@@ -107,24 +124,24 @@ IGNORELINES
107
124
  }
108
125
  end
109
126
 
110
- context "#new" do
127
+ context '#new' do
111
128
  subject {
112
129
  PathSpec.new File.open(filename, 'r')
113
130
  }
114
131
 
115
- it_behaves_like "standard gitignore negation"
132
+ it_behaves_like 'standard gitignore negation'
116
133
  end
117
134
 
118
- context "#from_filename" do
135
+ context '#from_filename' do
119
136
  subject {
120
137
  PathSpec.from_filename(filename)
121
138
  }
122
139
 
123
- it_behaves_like "standard gitignore negation"
140
+ it_behaves_like 'standard gitignore negation'
124
141
  end
125
142
  end
126
143
 
127
- context "from multiple gitignore files" do
144
+ context 'from multiple gitignore files' do
128
145
  include FakeFS::SpecHelpers
129
146
 
130
147
  let(:filenames) { ['.gitignore', '.otherignore'] }
@@ -141,26 +158,26 @@ IGNORELINES
141
158
  }
142
159
  end
143
160
 
144
- context "#new" do
161
+ context '#new' do
145
162
  subject {
146
163
  arr = filenames.collect { |f| File.open(f, 'r') }
147
164
  PathSpec.new arr
148
165
  }
149
166
 
150
- it_behaves_like "standard gitignore negation"
167
+ it_behaves_like 'standard gitignore negation'
151
168
 
152
169
  it { is_expected.to_not match('banana') }
153
170
  it { is_expected.to match('banananananana') }
154
171
  end
155
172
 
156
- context "#add" do
173
+ context '#add' do
157
174
  subject {
158
175
  arr = filenames.collect { |f| File.open(f, 'r') }
159
176
  ps = PathSpec.new
160
177
  ps.add arr
161
178
  }
162
179
 
163
- it_behaves_like "standard gitignore negation"
180
+ it_behaves_like 'standard gitignore negation'
164
181
 
165
182
  it { is_expected.to_not match('banana') }
166
183
  it { is_expected.to match('banananananana') }
@@ -168,12 +185,13 @@ IGNORELINES
168
185
  end
169
186
  end
170
187
 
171
- context "#match_tree" do
188
+ context '#match_tree' do
172
189
  include FakeFS::SpecHelpers
173
190
 
174
- context "unix" do
191
+ context 'unix' do
175
192
  let(:root) {'/tmp/project'}
176
- let(:gitignore) { <<-GITIGNORE
193
+ let(:gitignore) {
194
+ <<-GITIGNORE
177
195
  !**/important.txt
178
196
  abc/**
179
197
  GITIGNORE
@@ -194,12 +212,13 @@ IGNORELINES
194
212
  it { is_expected.to include "#{root}/abc".to_s }
195
213
  it { is_expected.to include "#{root}/abc/1".to_s }
196
214
  it { is_expected.not_to include "#{root}/abc/important.txt".to_s }
197
- it { is_expected.not_to include "#{root}".to_s }
215
+ it { is_expected.not_to include root.to_s.to_s }
198
216
  end
199
217
 
200
- context "windows" do
218
+ context 'windows' do
201
219
  let(:root) {'C:/project'}
202
- let(:gitignore) { <<-GITIGNORE
220
+ let(:gitignore) {
221
+ <<-GITIGNORE
203
222
  !**/important.txt
204
223
  abc/**
205
224
  GITIGNORE
@@ -220,53 +239,59 @@ IGNORELINES
220
239
  it { is_expected.to include "#{root}/abc".to_s }
221
240
  it { is_expected.to include "#{root}/abc/1".to_s }
222
241
  it { is_expected.not_to include "#{root}/abc/important.txt".to_s }
223
- it { is_expected.not_to include "#{root}".to_s }
242
+ it { is_expected.not_to include root.to_s.to_s }
224
243
  end
225
244
  end
226
245
 
227
- context "#match_paths" do
228
- let(:gitignore) { <<-GITIGNORE
246
+ context '#match_paths' do
247
+ let(:gitignore) {
248
+ <<-GITIGNORE
229
249
  !**/important.txt
230
250
  /abc/**
231
251
  GITIGNORE
232
252
  }
233
253
 
234
- context "with no root arg" do
254
+ context 'with no root arg' do
235
255
  subject { PathSpec.new(gitignore).match_paths(['/abc/important.txt', '/abc/', '/abc/1']) }
236
256
 
237
- it { is_expected.to include "/abc/" }
238
- it { is_expected.to include "/abc/1" }
239
- it { is_expected.not_to include "/abc/important.txt" }
257
+ it { is_expected.to include '/abc/' }
258
+ it { is_expected.to include '/abc/1' }
259
+ it { is_expected.not_to include '/abc/important.txt' }
240
260
  end
241
261
 
242
262
  context 'relative to non-root dir' do
243
- subject { PathSpec.new(gitignore).match_paths([
244
- '/def/abc/important.txt',
245
- '/def/abc/',
246
- '/def/abc/1'], '/def') }
247
-
248
- it { is_expected.to include "/def/abc/" }
249
- it { is_expected.to include "/def/abc/1" }
250
- it { is_expected.not_to include "/def/abc/important.txt" }
263
+ subject {
264
+ PathSpec.new(gitignore).match_paths([
265
+ '/def/abc/important.txt',
266
+ '/def/abc/',
267
+ '/def/abc/1'
268
+ ], '/def') }
269
+
270
+ it { is_expected.to include '/def/abc/' }
271
+ it { is_expected.to include '/def/abc/1' }
272
+ it { is_expected.not_to include '/def/abc/important.txt' }
251
273
  end
252
274
 
253
275
  context 'relative to windows drive letter' do
254
- subject { PathSpec.new(gitignore).match_paths([
255
- 'C:/def/abc/important.txt',
256
- 'C:/def/abc/',
257
- 'C:/def/abc/1'], 'C:/def/') }
258
-
259
- it { is_expected.to include "C:/def/abc/" }
260
- it { is_expected.to include "C:/def/abc/1" }
261
- it { is_expected.not_to include "C:/def/abc/important.txt" }
276
+ subject {
277
+ PathSpec.new(gitignore).match_paths([
278
+ 'C:/def/abc/important.txt',
279
+ 'C:/def/abc/',
280
+ 'C:/def/abc/1'
281
+ ], 'C:/def/') }
282
+
283
+ it { is_expected.to include 'C:/def/abc/' }
284
+ it { is_expected.to include 'C:/def/abc/1' }
285
+ it { is_expected.not_to include 'C:/def/abc/important.txt' }
262
286
  end
263
287
  end
264
288
 
265
289
  # Example to exclude everything except a specific directory foo/bar (note
266
290
  # the /* - without the slash, the wildcard would also exclude everything
267
291
  # within foo/bar): (from git-scm.com)
268
- context "very specific gitignore" do
269
- let(:gitignore) { <<-GITIGNORE
292
+ context 'very specific gitignore' do
293
+ let(:gitignore) {
294
+ <<-GITIGNORE
270
295
  # exclude everything except directory foo/bar
271
296
  /*
272
297
  !/foo
@@ -277,13 +302,14 @@ GITIGNORE
277
302
 
278
303
  subject { PathSpec.new(gitignore) }
279
304
 
280
- it { is_expected.not_to match("foo/bar") }
281
- it { is_expected.to match("anything") }
282
- it { is_expected.to match("foo/otherthing") }
305
+ it { is_expected.not_to match('foo/bar') }
306
+ it { is_expected.to match('anything') }
307
+ it { is_expected.to match('foo/otherthing') }
283
308
  end
284
309
 
285
- context "#empty" do
286
- let(:gitignore) { <<-GITIGNORE
310
+ context '#empty' do
311
+ let(:gitignore) {
312
+ <<-GITIGNORE
287
313
  # A comment
288
314
  GITIGNORE
289
315
  }
@@ -295,39 +321,65 @@ GITIGNORE
295
321
  end
296
322
  end
297
323
 
298
- context "regex file" do
299
- let(:regexfile) { <<-REGEX
324
+ context 'regex file' do
325
+ let(:regexfile) {
326
+ <<-REGEX
300
327
  ab*a
301
328
  REGEX
302
329
  }
303
330
 
304
331
  subject { PathSpec.new regexfile, :regex}
305
332
 
306
- it "matches the regex" do
333
+ it 'matches the regex' do
307
334
  expect(subject.match('anna')).to be false
308
335
  expect(subject.match('abba')).to be true
309
336
  end
310
337
 
311
- context "#from_filename" do
312
- it "forwards the type argument" do
338
+ context '#from_filename' do
339
+ it 'forwards the type argument' do
313
340
  io = double
314
341
 
315
342
  expect(File).to receive(:open).and_yield(io)
316
343
  expect(PathSpec).to receive(:from_lines).with(io, :regex)
317
344
 
318
- PathSpec.from_filename "/some/file", :regex
345
+ PathSpec.from_filename '/some/file', :regex
346
+ end
347
+
348
+ it 'reads a simple regex file' do
349
+ spec = PathSpec.from_filename 'spec/files/regex_simple', :regex
350
+
351
+ expect(spec.match('artifact.md')).to be true
352
+ expect(spec.match('code.rb')).to be false
353
+ end
354
+
355
+ it 'reads a simple gitignore file' do
356
+ spec = PathSpec.from_filename 'spec/files/gitignore_simple', :git
357
+
358
+ expect(spec.match('artifact.md')).to be true
359
+ expect(spec.match('code.rb')).to be false
360
+ end
361
+
362
+ it 'reads an example ruby gitignore file' do
363
+ spec = PathSpec.from_filename 'spec/files/gitignore_ruby', :git
364
+
365
+ expect(spec.match('coverage/')).to be true
366
+ expect(spec.match('coverage/index.html')).to be true
367
+ expect(spec.match('pathspec-0.0.1.gem')).to be true
368
+ expect(spec.match('lib/pathspec')).to be false
369
+ expect(spec.match('Gemfile')).to be false
319
370
  end
320
371
  end
321
372
  end
322
373
 
323
- context "unsuppored spec type" do
324
- let(:file) { <<-REGEX
374
+ context 'unsuppored spec type' do
375
+ let(:file) {
376
+ <<-REGEX
325
377
  This is some kind of nonsense.
326
378
  REGEX
327
379
  }
328
380
 
329
- it "does not allow an unknown spec type" do
330
- expect { PathSpec.new file, :foo}.to raise_error
381
+ it 'does not allow an unknown spec type' do
382
+ expect { PathSpec.new file, :foo}.to raise_error(/Unknown/)
331
383
  end
332
384
  end
333
385
  end