File: cli_spec.rb

package info (click to toggle)
ruby-pathspec 3.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 248 kB
  • sloc: ruby: 1,037; makefile: 9; sh: 5
file content (217 lines) | stat: -rw-r--r-- 7,705 bytes parent folder | download
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# frozen_string_literal: true

require 'spec_helper'
require 'open3'
require 'tmpdir'

describe 'pathspec-rb CLI' do
  let(:cli_path) { File.expand_path('../../bin/pathspec-rb', __dir__) }
  let(:lib_path) { File.expand_path('../../lib', __dir__) }
  let(:gitignore_simple) { File.expand_path('../files/gitignore_simple', __dir__) }
  let(:gitignore_readme) { File.expand_path('../files/gitignore_readme', __dir__) }
  let(:regex_simple) { File.expand_path('../files/regex_simple', __dir__) }

  def run_cli(*args)
    env = { 'RUBYLIB' => lib_path }
    stdout, stderr, status = Open3.capture3(env, 'ruby', cli_path, *args)
    [stdout, stderr, status]
  end

  describe 'help and errors' do
    it 'shows help when no arguments provided' do
      stdout, _stderr, status = run_cli
      expect(stdout).to include('Usage: pathspec-rb')
      expect(stdout).to include('Subcommands:')
      expect(stdout).to include('specs_match')
      expect(stdout).to include('tree')
      expect(stdout).to include('match')
      expect(status.exitstatus).to eq(2)
    end

    it 'shows error for unreadable file' do
      stdout, _stderr, status = run_cli('-f', '/nonexistent/file', 'match', 'test.txt')
      expect(stdout).to include("Error: I couldn't read /nonexistent/file")
      expect(status.exitstatus).to eq(2)
    end

    it 'shows error for unknown subcommand' do
      stdout, _stderr, status = run_cli('-f', gitignore_simple, 'unknown_command', 'test.txt')
      expect(stdout).to include('Unknown sub-command unknown_command')
      expect(stdout).to include('Usage: pathspec-rb')
      expect(status.exitstatus).to eq(2)
    end
  end

  describe 'match subcommand' do
    context 'with matching path' do
      it 'exits with 0' do
        _stdout, _stderr, status = run_cli('-f', gitignore_simple, 'match', 'test.md')
        expect(status.exitstatus).to eq(0)
      end

      it 'shows match message with verbose flag' do
        stdout, _stderr, status = run_cli('-f', gitignore_simple, '-v', 'match', 'test.md')
        expect(stdout).to include('test.md matches a spec')
        expect(status.exitstatus).to eq(0)
      end
    end

    context 'with non-matching path' do
      it 'exits with 1' do
        _stdout, _stderr, status = run_cli('-f', gitignore_simple, 'match', 'other.txt')
        expect(status.exitstatus).to eq(1)
      end

      it 'shows no match message with verbose flag' do
        stdout, _stderr, status = run_cli('-f', gitignore_simple, '-v', 'match', 'other.txt')
        expect(stdout).to include('other.txt does not match')
        expect(status.exitstatus).to eq(1)
      end
    end

    context 'with negated pattern' do
      it 'does not match negated paths' do
        _stdout, _stderr, status = run_cli('-f', gitignore_readme, 'match', 'abc/important.txt')
        expect(status.exitstatus).to eq(1)
      end

      it 'matches non-negated paths' do
        _stdout, _stderr, status = run_cli('-f', gitignore_readme, 'match', 'abc/other.txt')
        expect(status.exitstatus).to eq(0)
      end
    end
  end

  describe 'specs_match subcommand' do
    context 'with matching path' do
      it 'exits with 0 and shows matching specs' do
        stdout, _stderr, status = run_cli('-f', gitignore_readme, 'specs_match', 'abc/def.rb')
        expect(stdout).to include('abc/**')
        expect(status.exitstatus).to eq(0)
      end

      it 'shows verbose message with -v flag' do
        stdout, _stderr, status = run_cli('-f', gitignore_readme, '-v', 'specs_match', 'abc/def.rb')
        expect(stdout).to include('abc/def.rb matches the following specs')
        expect(stdout).to include('abc/**')
        expect(status.exitstatus).to eq(0)
      end
    end

    context 'with non-matching path' do
      it 'exits with 1' do
        _stdout, _stderr, status = run_cli('-f', gitignore_readme, 'specs_match', 'xyz/file.txt')
        expect(status.exitstatus).to eq(1)
      end

      it 'shows no match message with verbose flag' do
        stdout, _stderr, status = run_cli('-f', gitignore_readme, '-v', 'specs_match', 'xyz/file.txt')
        expect(stdout).to include('xyz/file.txt does not match any specs')
        expect(status.exitstatus).to eq(1)
      end
    end
  end

  describe 'tree subcommand' do
    around do |example|
      Dir.mktmpdir do |temp_dir|
        @temp_dir = temp_dir
        example.run
      end
    end

    before do
      # Create test directory structure
      FileUtils.mkdir_p(File.join(@temp_dir, 'foo'))
      FileUtils.mkdir_p(File.join(@temp_dir, 'other'))
      FileUtils.touch(File.join(@temp_dir, 'foo', 'test.txt'))
      FileUtils.touch(File.join(@temp_dir, 'foo', 'another.txt'))
      FileUtils.touch(File.join(@temp_dir, 'other', 'file.txt'))

      # Create a gitignore that matches foo/**
      @temp_gitignore = File.join(@temp_dir, '.gitignore')
      File.write(@temp_gitignore, "foo/**\n")
    end

    context 'with matching files' do
      it 'exits with 0 and lists matching files' do
        stdout, _stderr, status = run_cli('-f', @temp_gitignore, 'tree', @temp_dir)
        expect(stdout).to include('foo')
        expect(stdout.lines.any? { |line| line.include?('other') && !line.include?('another') }).to be false
        expect(status.exitstatus).to eq(0)
      end

      it 'shows verbose message with -v flag' do
        stdout, _stderr, status = run_cli('-f', @temp_gitignore, '-v', 'tree', @temp_dir)
        expect(stdout).to include("Files in #{@temp_dir} that match")
        expect(status.exitstatus).to eq(0)
      end
    end

    context 'with no matching files' do
      before do
        # Create gitignore with pattern that won't match anything
        File.write(@temp_gitignore, "nomatch/**\n")
      end

      it 'exits with 1' do
        _stdout, _stderr, status = run_cli('-f', @temp_gitignore, 'tree', @temp_dir)
        expect(status.exitstatus).to eq(1)
      end

      it 'shows no match message with verbose flag' do
        stdout, _stderr, status = run_cli('-f', @temp_gitignore, '-v', 'tree', @temp_dir)
        expect(stdout).to include('No file')
        expect(stdout).to include('matched')
        expect(status.exitstatus).to eq(1)
      end
    end
  end

  describe 'type flag' do
    context 'with git type (default)' do
      it 'parses gitignore patterns' do
        _stdout, _stderr, status = run_cli('-f', gitignore_simple, '-t', 'git', 'match', 'test.md')
        expect(status.exitstatus).to eq(0)
      end
    end

    context 'with regex type' do
      it 'parses regex patterns' do
        _stdout, _stderr, status = run_cli('-f', regex_simple, '-t', 'regex', 'match', 'foo.md')
        expect(status.exitstatus).to eq(0)
      end
    end
  end

  describe 'file flag' do
    it 'uses default .gitignore when not specified' do
      Dir.mktmpdir do |dir|
        gitignore_path = File.join(dir, '.gitignore')
        File.write(gitignore_path, "test/**\n")

        Dir.chdir(dir) do
          _stdout, _stderr, status = run_cli('match', 'test/file.txt')
          expect(status.exitstatus).to eq(0)
        end
      end
    end

    it 'uses specified file with -f flag' do
      _stdout, _stderr, status = run_cli('-f', gitignore_simple, 'match', 'test.md')
      expect(status.exitstatus).to eq(0)
    end

    it 'uses specified file with --file flag' do
      _stdout, _stderr, status = run_cli('--file', gitignore_simple, 'match', 'test.md')
      expect(status.exitstatus).to eq(0)
    end
  end

  describe 'empty string match command' do
    it 'treats empty string as match command' do
      _stdout, _stderr, status = run_cli('-f', gitignore_simple, '', 'test.md')
      expect(status.exitstatus).to eq(0)
    end
  end
end