tty-file 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +18 -2
  3. data/README.md +58 -16
  4. data/Rakefile +1 -1
  5. data/lib/tty-file.rb +0 -2
  6. data/lib/tty/file.rb +35 -9
  7. data/lib/tty/file/create_file.rb +3 -1
  8. data/lib/tty/file/differ.rb +3 -2
  9. data/lib/tty/file/digest_file.rb +1 -1
  10. data/lib/tty/file/download_file.rb +3 -3
  11. data/lib/tty/file/read_backward_file.rb +0 -1
  12. data/lib/tty/file/version.rb +2 -2
  13. data/spec/fixtures/cli_app/%name%_cli.rb +2 -0
  14. data/spec/fixtures/cli_app/commands/subcommand.rb +2 -0
  15. data/spec/fixtures/cli_app/excluded/%name%_cli.rb +2 -0
  16. data/spec/fixtures/templates/%file_name%.rb +1 -0
  17. data/spec/fixtures/templates/unit_test.rb +1 -0
  18. data/spec/spec_helper.rb +90 -0
  19. data/spec/unit/append_to_file_spec.rb +85 -0
  20. data/spec/unit/binary_spec.rb +206 -0
  21. data/spec/unit/checksum_file_spec.rb +39 -0
  22. data/spec/unit/chmod_spec.rb +78 -0
  23. data/spec/unit/copy_directory_spec.rb +106 -0
  24. data/spec/unit/copy_file_spec.rb +157 -0
  25. data/spec/unit/create_directory_spec.rb +79 -0
  26. data/spec/unit/create_file_spec.rb +116 -0
  27. data/spec/unit/diff_spec.rb +93 -0
  28. data/spec/unit/differ/call_spec.rb +101 -0
  29. data/spec/unit/download_file_spec.rb +54 -0
  30. data/spec/unit/escape_glob_path_spec.rb +14 -0
  31. data/spec/unit/inject_into_file_spec.rb +162 -0
  32. data/spec/unit/prepend_to_file_spec.rb +98 -0
  33. data/spec/unit/remove_file_spec.rb +53 -0
  34. data/spec/unit/replace_in_file_spec.rb +126 -0
  35. data/spec/unit/tail_file_spec.rb +63 -0
  36. data/tasks/console.rake +1 -1
  37. data/tasks/coverage.rake +1 -1
  38. data/tasks/spec.rake +1 -1
  39. data/tty-file.gemspec +5 -4
  40. metadata +30 -13
  41. data/.gitignore +0 -10
  42. data/.rspec +0 -3
  43. data/.travis.yml +0 -26
  44. data/CODE_OF_CONDUCT.md +0 -49
  45. data/Gemfile +0 -9
  46. data/appveyor.yml +0 -26
@@ -0,0 +1 @@
1
+ class <%= class_name %>Test; end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ if ENV['COVERAGE'] || ENV['TRAVIS']
4
+ require 'simplecov'
5
+ require 'coveralls'
6
+
7
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
+ SimpleCov::Formatter::HTMLFormatter,
9
+ Coveralls::SimpleCov::Formatter
10
+ ]
11
+
12
+ SimpleCov.start do
13
+ command_name 'spec'
14
+ add_filter 'spec'
15
+ end
16
+ end
17
+
18
+ require 'tty/file'
19
+ require 'find'
20
+ require "webmock/rspec"
21
+
22
+ module Helpers
23
+ def gem_root
24
+ ::File.join(File.dirname(__FILE__), "..")
25
+ end
26
+
27
+ def dir_path(*args)
28
+ path = ::File.join(gem_root, *args)
29
+ ::FileUtils.mkdir_p(path) unless ::File.exist?(path)
30
+ ::File.realpath(path)
31
+ end
32
+
33
+ def fixtures_path(filename = nil)
34
+ ::File.join(dir_path('spec', 'fixtures'), filename.to_s)
35
+ end
36
+
37
+ def tmp_path(filename = nil)
38
+ ::File.join(dir_path('tmp'), filename.to_s)
39
+ end
40
+
41
+ def exists_and_identical?(source, dest)
42
+ dest_path = tmp_path(dest)
43
+ expect(::File.exist?(dest_path)).to be(true)
44
+
45
+ source_path = fixtures_path(source)
46
+ expect(::FileUtils).to be_identical(source_path, dest_path)
47
+ end
48
+
49
+ def strip_heredoc(content)
50
+ indent = content.scan(/^[ \t]*(?=\S)/).min.size || 0
51
+ content.gsub(/^[ \t]{#{indent}}/, '')
52
+ end
53
+ end
54
+
55
+ RSpec.configure do |config|
56
+ config.include(Helpers)
57
+
58
+ config.before(:each) do
59
+ FileUtils.cp_r(fixtures_path('/.'), tmp_path)
60
+ end
61
+
62
+ config.after(:each) do
63
+ FileUtils.rm_rf(tmp_path)
64
+ end
65
+
66
+ config.expect_with :rspec do |expectations|
67
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
68
+ end
69
+
70
+ config.mock_with :rspec do |mocks|
71
+ mocks.verify_partial_doubles = true
72
+ end
73
+
74
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
75
+ config.disable_monkey_patching!
76
+
77
+ # This setting enables warnings. It's recommended, but in some cases may
78
+ # be too noisy due to issues in dependencies.
79
+ config.warnings = true
80
+
81
+ if config.files_to_run.one?
82
+ config.default_formatter = 'doc'
83
+ end
84
+
85
+ config.profile_examples = 2
86
+
87
+ config.order = :random
88
+
89
+ Kernel.srand config.seed
90
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TTY::File, '#append_to_file' do
4
+ it "appends to file" do
5
+ file = tmp_path('Gemfile')
6
+ TTY::File.append_to_file(file, "gem 'tty'", verbose: false)
7
+ expect(File.read(file)).to eq([
8
+ "gem 'nokogiri'\n",
9
+ "gem 'rails', '5.0.0'\n",
10
+ "gem 'rack', '>=1.0'\n",
11
+ "gem 'tty'"
12
+ ].join)
13
+ end
14
+
15
+ it "appends multiple lines to file" do
16
+ file = tmp_path('Gemfile')
17
+ TTY::File.append_to_file(file, "gem 'tty'\n", "gem 'rake'", verbose: false)
18
+ expect(File.read(file)).to eq([
19
+ "gem 'nokogiri'\n",
20
+ "gem 'rails', '5.0.0'\n",
21
+ "gem 'rack', '>=1.0'\n",
22
+ "gem 'tty'\n",
23
+ "gem 'rake'"
24
+ ].join)
25
+ end
26
+
27
+ it "appends content in a block" do
28
+ file = tmp_path('Gemfile')
29
+ TTY::File.append_to_file(file, verbose: false) { "gem 'tty'"}
30
+ expect(File.read(file)).to eq([
31
+ "gem 'nokogiri'\n",
32
+ "gem 'rails', '5.0.0'\n",
33
+ "gem 'rack', '>=1.0'\n",
34
+ "gem 'tty'"
35
+ ].join)
36
+ end
37
+
38
+ it "doesn't append if already present" do
39
+ file = tmp_path('Gemfile')
40
+ TTY::File.append_to_file(file, "gem 'rack', '>=1.0'\n", force: false, verbose: false)
41
+ expect(::File.read(file)).to eq([
42
+ "gem 'nokogiri'\n",
43
+ "gem 'rails', '5.0.0'\n",
44
+ "gem 'rack', '>=1.0'\n",
45
+ ].join)
46
+ end
47
+
48
+ it "appends safely checking if content already present" do
49
+ file = tmp_path('Gemfile')
50
+ TTY::File.safe_append_to_file(file, "gem 'rack', '>=1.0'\n", verbose: false)
51
+
52
+ expect(::File.read(file)).to eq([
53
+ "gem 'nokogiri'\n",
54
+ "gem 'rails', '5.0.0'\n",
55
+ "gem 'rack', '>=1.0'\n",
56
+ ].join)
57
+ end
58
+
59
+ it "appends multiple times by default" do
60
+ file = tmp_path('Gemfile')
61
+ TTY::File.append_to_file(file, "gem 'tty'\n", verbose: false)
62
+ TTY::File.append_to_file(file, "gem 'tty'\n", verbose: false)
63
+ expect(::File.read(file)).to eq([
64
+ "gem 'nokogiri'\n",
65
+ "gem 'rails', '5.0.0'\n",
66
+ "gem 'rack', '>=1.0'\n",
67
+ "gem 'tty'\n",
68
+ "gem 'tty'\n"
69
+ ].join)
70
+ end
71
+
72
+ it "logs action" do
73
+ file = tmp_path('Gemfile')
74
+ expect {
75
+ TTY::File.add_to_file(file, "gem 'tty'")
76
+ }.to output(/\e\[32mappend\e\[0m.*Gemfile/).to_stdout_from_any_process
77
+ end
78
+
79
+ it "logs action without color" do
80
+ file = tmp_path('Gemfile')
81
+ expect {
82
+ TTY::File.add_to_file(file, "gem 'tty'", color: false)
83
+ }.to output(/\s+append.*Gemfile/).to_stdout_from_any_process
84
+ end
85
+ end
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TTY::File, '#binary?' do
4
+ let(:ascii) { "This is a text file.\nWith more than one line.\nAnd a \tTab.\nAnd other printable chars too: ~!@\#$%^&*()`:\"<>?{}|_+,./;'[]\\-=\n" }
5
+
6
+ let(:utf_8) { "Testing utf-8 unicode...\n\n\non a new line: \xE2\x80\x93\n" }
7
+
8
+ let(:latin_1) { "Testing latin chars...\nsuch as #{0xFD.chr}mlaut.\n" }
9
+
10
+ let(:shift_jis) { "And some kanjis:\n #{0x83.chr}#{0x80.chr}.\n" }
11
+
12
+ it "identifies zero-length file as non-binary" do
13
+ Tempfile.open('tty-file-binary-spec') do |file|
14
+ expect(TTY::File.binary?(file)).to eq(false)
15
+ end
16
+ end
17
+
18
+ it "indentifies text with hex as binary" do
19
+ Tempfile.open('tty-file-binary-spec') do |file|
20
+ file << "hi \xAD"
21
+ file.close
22
+
23
+ expect(TTY::File.binary?(file)).to eq(true)
24
+ end
25
+ end
26
+
27
+ it "identifies image as binary" do
28
+ file = tmp_path('blackhole.png')
29
+
30
+ expect(TTY::File.binary?(file)).to eq(true)
31
+ end
32
+
33
+ it "indetifies text file as non-binary" do
34
+ file = tmp_path('Gemfile')
35
+
36
+ expect(TTY::File.binary?(file)).to eq(false)
37
+ end
38
+
39
+ it "indetifies a null-terminated string file as binary" do
40
+ Tempfile.open('tty-file-binary-spec') do |file|
41
+ file.write("Binary content.\0")
42
+ file.close
43
+
44
+ expect(TTY::File.binary?(file)).to eq(true)
45
+ end
46
+ end
47
+
48
+ it "indetifies a null-terminated multi-line string file as binary" do
49
+ Tempfile.open('tty-file-binary-spec') do |file|
50
+ file.write("Binary content.\non manylnes\nreally\0")
51
+ file.close
52
+
53
+ expect(TTY::File.binary?(file)).to eq(true)
54
+ end
55
+ end
56
+
57
+ context "when the default external encoding is UTF-8" do
58
+ before do
59
+ @saved_verbosity = $VERBOSE
60
+ @saved_encoding = Encoding.default_external
61
+ $VERBOSE = nil
62
+ Encoding.default_external = Encoding::UTF_8
63
+ end
64
+
65
+ after do
66
+ Encoding.default_external = @saved_encoding
67
+ $VERBOSE = @saved_verbosity
68
+ end
69
+
70
+ it "identifies ASCII as non-binary" do
71
+ Tempfile.open('tty-file-binary-spec') do |file|
72
+ file << ascii
73
+ file.close
74
+
75
+ expect(TTY::File.binary?(file)).to eq(false)
76
+ end
77
+ end
78
+
79
+ it "identifies UTF-8 as non-binary" do
80
+ Tempfile.open('tty-file-binary-spec') do |file|
81
+ file << utf_8
82
+ file.close
83
+
84
+ expect(TTY::File.binary?(file)).to eq(false)
85
+ end
86
+ end
87
+
88
+ it "indentifies Latin-1 as invalid UTF-8 and hence as binary" do
89
+ Tempfile.open('tty-file-binary-spec') do |file|
90
+ file << latin_1
91
+ file.close
92
+
93
+ expect(TTY::File.binary?(file)).to eq(true)
94
+ end
95
+ end
96
+
97
+ it "identifies Shift-JIS as invalid UTF-8 and hence as binary" do
98
+ Tempfile.open('tty-file-binary-spec') do |file|
99
+ file << shift_jis
100
+ file.close
101
+
102
+ expect(TTY::File.binary?(file)).to eq(true)
103
+ end
104
+ end
105
+ end
106
+
107
+ context "when the default external encoding is Latin-1" do
108
+ before do
109
+ @saved_verbosity = $VERBOSE
110
+ @saved_encoding = Encoding.default_external
111
+ $VERBOSE = nil
112
+ Encoding.default_external = Encoding::ISO_8859_1
113
+ end
114
+
115
+ after do
116
+ Encoding.default_external = @saved_encoding
117
+ $VERBOSE = @saved_verbosity
118
+ end
119
+
120
+ it "identifies ASCII as non-binary" do
121
+ Tempfile.open('tty-file-binary-spec') do |file|
122
+ file << ascii
123
+ file.close
124
+
125
+ expect(TTY::File.binary?(file)).to eq(false)
126
+ end
127
+ end
128
+
129
+ it "identifies UTF-8 as invalid Latin-1 and hence binary" do
130
+ Tempfile.open('tty-file-binary-spec') do |file|
131
+ file << utf_8
132
+ file.close
133
+
134
+ expect(TTY::File.binary?(file)).to eq(true)
135
+ end
136
+ end
137
+
138
+ it "indentifies Latin-1 as non-binary" do
139
+ Tempfile.open('tty-file-binary-spec') do |file|
140
+ file << latin_1
141
+ file.close
142
+
143
+ expect(TTY::File.binary?(file)).to eq(false)
144
+ end
145
+ end
146
+
147
+ it "identifies Shift-JIS as invalid Latin-1 and hence as binary" do
148
+ Tempfile.open('tty-file-binary-spec') do |file|
149
+ file << shift_jis
150
+ file.close
151
+
152
+ expect(TTY::File.binary?(file)).to eq(true)
153
+ end
154
+ end
155
+ end
156
+
157
+ context "when the default external encoding is Shift-JIS" do
158
+ before do
159
+ @saved_verbosity = $VERBOSE
160
+ @saved_encoding = Encoding.default_external
161
+ $VERBOSE = nil
162
+ Encoding.default_external = Encoding::SHIFT_JIS
163
+ end
164
+
165
+ after do
166
+ Encoding.default_external = @saved_encoding
167
+ $VERBOSE = @saved_verbosity
168
+ end
169
+
170
+ it "identifies ASCII as non-binary" do
171
+ Tempfile.open('tty-file-binary-spec') do |file|
172
+ file << ascii
173
+ file.close
174
+
175
+ expect(TTY::File.binary?(file)).to eq(false)
176
+ end
177
+ end
178
+
179
+ it "identifies UTF-8 as invalid Shift-JIS and hence as binary" do
180
+ Tempfile.open('tty-file-binary-spec') do |file|
181
+ file << utf_8
182
+ file.close
183
+
184
+ expect(TTY::File.binary?(file)).to eq(true)
185
+ end
186
+ end
187
+
188
+ it "indentifies Latin-1 as invalid Shift-JIS and hence as binary" do
189
+ Tempfile.open('tty-file-binary-spec') do |file|
190
+ file << latin_1
191
+ file.close
192
+
193
+ expect(TTY::File.binary?(file)).to eq(true)
194
+ end
195
+ end
196
+
197
+ it "identifies Shift-JIS as non-binary" do
198
+ Tempfile.open('tty-file-binary-spec') do |file|
199
+ file << shift_jis
200
+ file.close
201
+
202
+ expect(TTY::File.binary?(file)).to eq(false)
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TTY::File, '#checksum_file' do
4
+ it "generates checksum for a file" do
5
+ file = tmp_path('checksum/README.md')
6
+
7
+ checksum = TTY::File.checksum_file(file)
8
+ expected = '76ba1beb6c611fa32624ed253444138cdf23eb938a3812137f8a399c5b375bfe'
9
+
10
+ expect(checksum).to eq(expected)
11
+ end
12
+
13
+ it "generates checksum for IO object" do
14
+ io = StringIO.new("Some content\nThe end")
15
+
16
+ checksum = TTY::File.checksum_file(io, 'md5')
17
+ expected = "ad0962e2374b1899fcfb818896703e50"
18
+
19
+ expect(checksum).to eq(expected)
20
+ end
21
+
22
+ it "generates checksum for String" do
23
+ string = "Some content\nThe end"
24
+
25
+ checksum = TTY::File.checksum_file(string, 'sha1')
26
+ expected = "289388f187404135e6c15b21460442cf867180dd"
27
+
28
+ expect(checksum).to eq(expected)
29
+ end
30
+
31
+ it "doesn't digest when :noop option" do
32
+ digester = double(:digester)
33
+ allow(TTY::File::DigestFile).to receive(:new).and_return(digester)
34
+
35
+ TTY::File.checksum_file('string', noop: true)
36
+
37
+ expect(digester).to_not receive(:call)
38
+ end
39
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TTY::File, '#chmod' do
4
+ context 'when octal permisssions' do
5
+ it "adds permissions to file - user executable",
6
+ unless: RSpec::Support::OS.windows? do
7
+
8
+ file = tmp_path('script.sh')
9
+ mode = File.lstat(file).mode
10
+ expect(File.executable?(file)).to eq(false)
11
+
12
+ TTY::File.chmod(file, mode | TTY::File::U_X, verbose: false)
13
+
14
+ expect(File.lstat(file).mode).to eq(mode | TTY::File::U_X)
15
+ end
16
+
17
+ it "logs status when :verbose flag is true",
18
+ unless: RSpec::Support::OS.windows? do
19
+
20
+ file = tmp_path('script.sh')
21
+ mode = File.lstat(file).mode
22
+ expect(File.executable?(file)).to eq(false)
23
+
24
+ expect {
25
+ TTY::File.chmod(file, mode | TTY::File::U_X)
26
+ }.to output(/chmod/).to_stdout_from_any_process
27
+
28
+ expect(File.lstat(file).mode).to eq(mode | TTY::File::U_X)
29
+ end
30
+
31
+ it "doesn't change permission when :noop flag is true" do
32
+ file = tmp_path('script.sh')
33
+ mode = File.lstat(file).mode
34
+ expect(File.executable?(file)).to eq(false)
35
+
36
+ TTY::File.chmod(file, mode | TTY::File::U_X, verbose: false, noop: true)
37
+
38
+ expect(File.lstat(file).mode).to eq(mode)
39
+ end
40
+ end
41
+
42
+ context 'when human readable permissions' do
43
+ it "adds permisions to file - user executable",
44
+ unless: RSpec::Support::OS.windows? do
45
+
46
+ file = tmp_path('script.sh')
47
+ mode = File.lstat(file).mode
48
+ expect(File.executable?(file)).to eq(false)
49
+
50
+ TTY::File.chmod(file, 'u+x', verbose: false)
51
+
52
+ expect(File.lstat(file).mode).to eq(mode | TTY::File::U_X)
53
+ end
54
+
55
+ it "removes permission for user executable" do
56
+ file = tmp_path('script.sh')
57
+ mode = File.lstat(file).mode
58
+ expect(File.writable?(file)).to eq(true)
59
+
60
+ TTY::File.chmod(file, 'u-w', verbose: false)
61
+
62
+ expect(File.lstat(file).mode).to eq(mode ^ TTY::File::U_W)
63
+ expect(File.writable?(file)).to eq(false)
64
+ end
65
+
66
+ it "adds multiple permissions separated by comma",
67
+ unless: RSpec::Support::OS.windows? do
68
+
69
+ file = tmp_path('script.sh')
70
+ mode = File.lstat(file).mode
71
+ expect(File.executable?(file)).to eq(false)
72
+
73
+ TTY::File.chmod(file, 'u+x,g+x', verbose: false)
74
+
75
+ expect(File.lstat(file).mode).to eq(mode | TTY::File::U_X | TTY::File::G_X)
76
+ end
77
+ end
78
+ end