1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
require 'spec_helper'
describe Gitlab::Git::Attributes, seed_helper: true do
let(:path) do
File.join(SEED_REPOSITORY_PATH, 'with-git-attributes.git')
end
subject { described_class.new(path) }
describe '#attributes' do
context 'using a path with attributes' do
it 'returns the attributes as a Hash' do
expect(subject.attributes('test.txt')).to eq({ 'text' => true })
end
it 'returns a Hash containing multiple attributes' do
expect(subject.attributes('test.sh')).
to eq({ 'eol' => 'lf', 'gitlab-language' => 'shell' })
end
it 'returns a Hash containing attributes for a file with multiple extensions' do
expect(subject.attributes('test.haml.html')).
to eq({ 'gitlab-language' => 'haml' })
end
it 'returns a Hash containing attributes for a file in a directory' do
expect(subject.attributes('foo/bar.txt')).to eq({ 'foo' => true })
end
it 'returns a Hash containing attributes with query string parameters' do
expect(subject.attributes('foo.cgi')).
to eq({ 'key' => 'value?p1=v1&p2=v2' })
end
it 'returns a Hash containing the attributes for an absolute path' do
expect(subject.attributes('/test.txt')).to eq({ 'text' => true })
end
it 'returns a Hash containing the attributes when a pattern is defined using an absolute path' do
# When a path is given without a leading slash it should still match
# patterns defined with a leading slash.
expect(subject.attributes('foo.png')).
to eq({ 'gitlab-language' => 'png' })
expect(subject.attributes('/foo.png')).
to eq({ 'gitlab-language' => 'png' })
end
it 'returns an empty Hash for a defined path without attributes' do
expect(subject.attributes('bla/bla.txt')).to eq({})
end
context 'when the "binary" option is set for a path' do
it 'returns true for the "binary" option' do
expect(subject.attributes('test.binary')['binary']).to eq(true)
end
it 'returns false for the "diff" option' do
expect(subject.attributes('test.binary')['diff']).to eq(false)
end
end
end
context 'using a path without any attributes' do
it 'returns an empty Hash' do
expect(subject.attributes('test.foo')).to eq({})
end
end
end
describe '#patterns' do
it 'parses a file with entries' do
expect(subject.patterns).to be_an_instance_of(Hash)
end
it 'parses an entry that uses a tab to separate the pattern and attributes' do
expect(subject.patterns[File.join(path, '*.md')]).
to eq({ 'gitlab-language' => 'markdown' })
end
it 'stores patterns in reverse order' do
first = subject.patterns.to_a[0]
expect(first[0]).to eq(File.join(path, 'bla/bla.txt'))
end
# It's a bit hard to test for something _not_ being processed. As such we'll
# just test the number of entries.
it 'ignores any comments and empty lines' do
expect(subject.patterns.length).to eq(10)
end
it 'does not parse anything when the attributes file does not exist' do
expect(File).to receive(:exist?).
with(File.join(path, 'info/attributes')).
and_return(false)
expect(subject.patterns).to eq({})
end
end
describe '#parse_attributes' do
it 'parses a boolean attribute' do
expect(subject.parse_attributes('text')).to eq({ 'text' => true })
end
it 'parses a negated boolean attribute' do
expect(subject.parse_attributes('-text')).to eq({ 'text' => false })
end
it 'parses a key-value pair' do
expect(subject.parse_attributes('foo=bar')).to eq({ 'foo' => 'bar' })
end
it 'parses multiple attributes' do
input = 'boolean key=value -negated'
expect(subject.parse_attributes(input)).
to eq({ 'boolean' => true, 'key' => 'value', 'negated' => false })
end
it 'parses attributes with query string parameters' do
expect(subject.parse_attributes('foo=bar?baz=1')).
to eq({ 'foo' => 'bar?baz=1' })
end
end
describe '#each_line' do
it 'iterates over every line in the attributes file' do
args = [String] * 14 # the number of lines in the file
expect { |b| subject.each_line(&b) }.to yield_successive_args(*args)
end
it 'does not yield when the attributes file does not exist' do
expect(File).to receive(:exist?).
with(File.join(path, 'info/attributes')).
and_return(false)
expect { |b| subject.each_line(&b) }.not_to yield_control
end
it 'does not yield when the attributes file has an unsupported encoding' do
path = File.join(SEED_REPOSITORY_PATH, 'with-invalid-git-attributes.git')
attrs = described_class.new(path)
expect { |b| attrs.each_line(&b) }.not_to yield_control
end
end
end