spring-jruby 1.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +364 -0
- data/bin/spring +49 -0
- data/lib/spring-jruby/application.rb +283 -0
- data/lib/spring-jruby/application/boot.rb +19 -0
- data/lib/spring-jruby/binstub.rb +13 -0
- data/lib/spring-jruby/boot.rb +9 -0
- data/lib/spring-jruby/client.rb +46 -0
- data/lib/spring-jruby/client/binstub.rb +188 -0
- data/lib/spring-jruby/client/command.rb +18 -0
- data/lib/spring-jruby/client/help.rb +62 -0
- data/lib/spring-jruby/client/rails.rb +34 -0
- data/lib/spring-jruby/client/run.rb +167 -0
- data/lib/spring-jruby/client/status.rb +30 -0
- data/lib/spring-jruby/client/stop.rb +22 -0
- data/lib/spring-jruby/client/version.rb +11 -0
- data/lib/spring-jruby/command_wrapper.rb +82 -0
- data/lib/spring-jruby/commands.rb +51 -0
- data/lib/spring-jruby/commands/rails.rb +112 -0
- data/lib/spring-jruby/commands/rake.rb +30 -0
- data/lib/spring-jruby/configuration.rb +60 -0
- data/lib/spring-jruby/env.rb +109 -0
- data/lib/spring-jruby/errors.rb +36 -0
- data/lib/spring-jruby/impl/application.rb +7 -0
- data/lib/spring-jruby/impl/application_manager.rb +7 -0
- data/lib/spring-jruby/impl/fork/application.rb +69 -0
- data/lib/spring-jruby/impl/fork/application_manager.rb +137 -0
- data/lib/spring-jruby/impl/fork/run.rb +47 -0
- data/lib/spring-jruby/impl/pool/application.rb +47 -0
- data/lib/spring-jruby/impl/pool/application_manager.rb +226 -0
- data/lib/spring-jruby/impl/pool/run.rb +27 -0
- data/lib/spring-jruby/impl/run.rb +7 -0
- data/lib/spring-jruby/io_helpers.rb +92 -0
- data/lib/spring-jruby/json.rb +626 -0
- data/lib/spring-jruby/platform.rb +23 -0
- data/lib/spring-jruby/process_title_updater.rb +65 -0
- data/lib/spring-jruby/server.rb +130 -0
- data/lib/spring-jruby/sid.rb +42 -0
- data/lib/spring-jruby/test.rb +18 -0
- data/lib/spring-jruby/test/acceptance_test.rb +371 -0
- data/lib/spring-jruby/test/application.rb +217 -0
- data/lib/spring-jruby/test/application_generator.rb +134 -0
- data/lib/spring-jruby/test/rails_version.rb +40 -0
- data/lib/spring-jruby/test/watcher_test.rb +167 -0
- data/lib/spring-jruby/version.rb +3 -0
- data/lib/spring-jruby/watcher.rb +30 -0
- data/lib/spring-jruby/watcher/abstract.rb +86 -0
- data/lib/spring-jruby/watcher/polling.rb +61 -0
- metadata +137 -0
@@ -0,0 +1,217 @@
|
|
1
|
+
require "spring-jruby/env"
|
2
|
+
|
3
|
+
module Spring
|
4
|
+
module Test
|
5
|
+
class Application
|
6
|
+
DEFAULT_TIMEOUT = ENV['CI'] ? 30 : 10
|
7
|
+
|
8
|
+
attr_reader :root, :spring_env
|
9
|
+
|
10
|
+
def initialize(root)
|
11
|
+
@root = Pathname.new(root)
|
12
|
+
@spring_env = Spring::Env.new(root)
|
13
|
+
end
|
14
|
+
|
15
|
+
def exists?
|
16
|
+
root.exist?
|
17
|
+
end
|
18
|
+
|
19
|
+
def stdout
|
20
|
+
@stdout ||= IO.pipe
|
21
|
+
end
|
22
|
+
|
23
|
+
def stderr
|
24
|
+
@stderr ||= IO.pipe
|
25
|
+
end
|
26
|
+
|
27
|
+
def log_file
|
28
|
+
@log_file ||= path("tmp/spring.log").open("w+")
|
29
|
+
end
|
30
|
+
|
31
|
+
def env
|
32
|
+
@env ||= {
|
33
|
+
"GEM_HOME" => gem_home.to_s,
|
34
|
+
"GEM_PATH" => gem_home.to_s,
|
35
|
+
"HOME" => user_home.to_s,
|
36
|
+
"RAILS_ENV" => nil,
|
37
|
+
"RACK_ENV" => nil,
|
38
|
+
"SPRING_LOG" => log_file.path
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def path(addition)
|
43
|
+
root.join addition
|
44
|
+
end
|
45
|
+
|
46
|
+
def gemfile
|
47
|
+
path "Gemfile"
|
48
|
+
end
|
49
|
+
|
50
|
+
def gem_home
|
51
|
+
path "../gems/#{RUBY_VERSION}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def user_home
|
55
|
+
path "user_home"
|
56
|
+
end
|
57
|
+
|
58
|
+
def spring
|
59
|
+
gem_home.join "bin/spring"
|
60
|
+
end
|
61
|
+
|
62
|
+
def rails_version
|
63
|
+
@rails_version ||= RailsVersion.new(gemfile.read.match(/gem 'rails', '(.*)'/)[1])
|
64
|
+
end
|
65
|
+
|
66
|
+
def spring_test_command
|
67
|
+
"#{rails_version.test_command} #{test}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def stop_spring
|
71
|
+
run "#{spring} stop"
|
72
|
+
rescue Errno::ENOENT
|
73
|
+
end
|
74
|
+
|
75
|
+
def test
|
76
|
+
path "test/#{rails_version.controller_tests_dir}/posts_controller_test.rb"
|
77
|
+
end
|
78
|
+
|
79
|
+
def controller
|
80
|
+
path "app/controllers/posts_controller.rb"
|
81
|
+
end
|
82
|
+
|
83
|
+
def application_config
|
84
|
+
path "config/application.rb"
|
85
|
+
end
|
86
|
+
|
87
|
+
def spring_config
|
88
|
+
path "config/spring.rb"
|
89
|
+
end
|
90
|
+
|
91
|
+
def run(command, opts = {})
|
92
|
+
start_time = Time.now
|
93
|
+
|
94
|
+
Bundler.with_clean_env do
|
95
|
+
Process.spawn(
|
96
|
+
env,
|
97
|
+
command.to_s,
|
98
|
+
out: stdout.last,
|
99
|
+
err: stderr.last,
|
100
|
+
in: :close,
|
101
|
+
chdir: root.to_s,
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
_, status = Timeout.timeout(opts.fetch(:timeout, DEFAULT_TIMEOUT)) { Process.wait2 }
|
106
|
+
|
107
|
+
if pid = spring_env.pid
|
108
|
+
@server_pid = pid
|
109
|
+
lines = `ps -A -o ppid= -o pid= | egrep '^\\s*#{@server_pid}'`.lines
|
110
|
+
@application_pids = lines.map { |l| l.split.last.to_i }
|
111
|
+
end
|
112
|
+
|
113
|
+
output = read_streams
|
114
|
+
puts dump_streams(command, output) if ENV["SPRING_DEBUG"]
|
115
|
+
|
116
|
+
@times << (Time.now - start_time) if @times
|
117
|
+
|
118
|
+
output.merge(status: status, command: command)
|
119
|
+
rescue Timeout::Error => e
|
120
|
+
raise e, "Output:\n\n#{dump_streams(command, read_streams)}"
|
121
|
+
end
|
122
|
+
|
123
|
+
def with_timing
|
124
|
+
@times = []
|
125
|
+
yield
|
126
|
+
ensure
|
127
|
+
@times = nil
|
128
|
+
end
|
129
|
+
|
130
|
+
def last_time
|
131
|
+
@times.last
|
132
|
+
end
|
133
|
+
|
134
|
+
def first_time
|
135
|
+
@times.first
|
136
|
+
end
|
137
|
+
|
138
|
+
def timing_ratio
|
139
|
+
last_time / first_time
|
140
|
+
end
|
141
|
+
|
142
|
+
def read_streams
|
143
|
+
{
|
144
|
+
stdout: read_stream(stdout.first),
|
145
|
+
stderr: read_stream(stderr.first),
|
146
|
+
log: read_stream(log_file)
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
150
|
+
def read_stream(stream)
|
151
|
+
output = ""
|
152
|
+
while IO.select([stream], [], [], 0.5) && !stream.eof?
|
153
|
+
output << stream.readpartial(10240)
|
154
|
+
end
|
155
|
+
output
|
156
|
+
end
|
157
|
+
|
158
|
+
def dump_streams(command, streams)
|
159
|
+
output = "$ #{command}\n"
|
160
|
+
|
161
|
+
streams.each do |name, stream|
|
162
|
+
unless stream.chomp.empty?
|
163
|
+
output << "--- #{name} ---\n"
|
164
|
+
output << "#{stream.chomp}\n"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
output << "\n"
|
169
|
+
output
|
170
|
+
end
|
171
|
+
|
172
|
+
def debug(artifacts)
|
173
|
+
artifacts = artifacts.dup
|
174
|
+
artifacts.delete :status
|
175
|
+
dump_streams(artifacts.delete(:command), artifacts)
|
176
|
+
end
|
177
|
+
|
178
|
+
def await_reload
|
179
|
+
raise "no pid" if @application_pids.nil? || @application_pids.empty?
|
180
|
+
|
181
|
+
Timeout.timeout(DEFAULT_TIMEOUT) do
|
182
|
+
sleep 0.1 while @application_pids.any? { |p| process_alive?(p) }
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def run!(command, options = {})
|
187
|
+
attempts = (options.delete(:retry) || 0) + 1
|
188
|
+
artifacts = nil
|
189
|
+
|
190
|
+
until attempts == 0 || artifacts && artifacts[:status].success?
|
191
|
+
artifacts = run(command, options)
|
192
|
+
attempts -= 1
|
193
|
+
end
|
194
|
+
|
195
|
+
if artifacts[:status].success?
|
196
|
+
artifacts
|
197
|
+
else
|
198
|
+
raise "command failed\n\n#{debug(artifacts)}"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def bundle
|
203
|
+
run! "(gem list bundler | grep bundler) || gem install bundler", timeout: nil, retry: 2
|
204
|
+
run! "bundle check || bundle update --retry=2", timeout: nil
|
205
|
+
end
|
206
|
+
|
207
|
+
private
|
208
|
+
|
209
|
+
def process_alive?(pid)
|
210
|
+
Process.kill 0, pid
|
211
|
+
true
|
212
|
+
rescue Errno::ESRCH
|
213
|
+
false
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module Spring
|
2
|
+
module Test
|
3
|
+
class ApplicationGenerator
|
4
|
+
attr_reader :version_constraint, :version, :application
|
5
|
+
|
6
|
+
def initialize(version_constraint)
|
7
|
+
@version_constraint = version_constraint
|
8
|
+
@version = RailsVersion.new(version_constraint.split(' ').last)
|
9
|
+
@application = Application.new(root)
|
10
|
+
@bundled = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_root
|
14
|
+
Pathname.new Spring::Test.root
|
15
|
+
end
|
16
|
+
|
17
|
+
def root
|
18
|
+
test_root.join("apps/rails-#{version.major}-#{version.minor}-spring-#{Spring::VERSION}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def system(command)
|
22
|
+
if ENV["SPRING_DEBUG"]
|
23
|
+
puts "$ #{command}\n"
|
24
|
+
else
|
25
|
+
command = "(#{command}) > /dev/null"
|
26
|
+
end
|
27
|
+
|
28
|
+
Kernel.system(command) or raise "command failed: #{command}"
|
29
|
+
puts if ENV["SPRING_DEBUG"]
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate
|
33
|
+
Bundler.with_clean_env { generate_files }
|
34
|
+
install_spring
|
35
|
+
generate_scaffold
|
36
|
+
end
|
37
|
+
|
38
|
+
# Sporadic SSL errors keep causing test failures so there are anti-SSL workarounds here
|
39
|
+
def generate_files
|
40
|
+
system("gem list '^rails$' --installed --version '#{version_constraint}' || " \
|
41
|
+
"gem install rails --clear-sources --source http://rubygems.org --version '#{version_constraint}'")
|
42
|
+
|
43
|
+
@version = RailsVersion.new(`ruby -e 'puts Gem::Specification.find_by_name("rails", "#{version_constraint}").version'`.chomp)
|
44
|
+
|
45
|
+
skips = %w(--skip-bundle --skip-javascript --skip-sprockets)
|
46
|
+
skips << "--skip-spring" if version.bundles_spring?
|
47
|
+
|
48
|
+
system("rails _#{version}_ new #{application.root} #{skips.join(' ')}")
|
49
|
+
raise "application generation failed" unless application.exists?
|
50
|
+
|
51
|
+
FileUtils.mkdir_p(application.gem_home)
|
52
|
+
FileUtils.mkdir_p(application.user_home)
|
53
|
+
FileUtils.rm_rf(application.path("test/performance"))
|
54
|
+
|
55
|
+
append_to_file(application.gemfile, "gem 'spring', '#{Spring::VERSION}'")
|
56
|
+
|
57
|
+
if version.needs_testunit?
|
58
|
+
append_to_file(application.gemfile, "gem 'spring-commands-testunit'")
|
59
|
+
end
|
60
|
+
|
61
|
+
rewrite_file(application.gemfile) do |c|
|
62
|
+
c.sub!("https://rubygems.org", "http://rubygems.org")
|
63
|
+
c.gsub!(/(gem '(byebug|web-console|sdoc|jbuilder)')/, "# \\1")
|
64
|
+
c
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
if application.path("bin").exist?
|
69
|
+
FileUtils.cp_r(application.path("bin"), application.path("bin_original"))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def rewrite_file(file)
|
74
|
+
File.write(file, yield(file.read))
|
75
|
+
end
|
76
|
+
|
77
|
+
def append_to_file(file, add)
|
78
|
+
rewrite_file(file) { |c| c << "#{add}\n" }
|
79
|
+
end
|
80
|
+
|
81
|
+
def generate_if_missing
|
82
|
+
generate unless application.exists?
|
83
|
+
end
|
84
|
+
|
85
|
+
def install_spring
|
86
|
+
return if @installed
|
87
|
+
|
88
|
+
build_and_install_gems
|
89
|
+
|
90
|
+
application.bundle
|
91
|
+
|
92
|
+
FileUtils.rm_rf application.path("bin")
|
93
|
+
|
94
|
+
if application.path("bin_original").exist?
|
95
|
+
FileUtils.cp_r application.path("bin_original"), application.path("bin")
|
96
|
+
end
|
97
|
+
|
98
|
+
application.run! "#{application.spring} binstub --all"
|
99
|
+
@installed = true
|
100
|
+
end
|
101
|
+
|
102
|
+
def manually_built_gems
|
103
|
+
%w(spring)
|
104
|
+
end
|
105
|
+
|
106
|
+
def build_and_install_gems
|
107
|
+
manually_built_gems.each do |name|
|
108
|
+
spec = Gem::Specification.find_by_name(name)
|
109
|
+
|
110
|
+
FileUtils.cd(spec.gem_dir) do
|
111
|
+
FileUtils.rm(Dir.glob("#{name}-*.gem"))
|
112
|
+
system("gem build #{name}.gemspec 2>&1")
|
113
|
+
end
|
114
|
+
|
115
|
+
application.run! "gem install #{spec.gem_dir}/#{name}-*.gem", timeout: nil
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def copy_to(path)
|
120
|
+
system("rm -rf #{path}")
|
121
|
+
system("cp -r #{application.root} #{path}")
|
122
|
+
end
|
123
|
+
|
124
|
+
def generate_scaffold
|
125
|
+
application.run! "bundle exec rails g scaffold post title:string"
|
126
|
+
application.run! "bundle exec rake db:migrate db:test:clone"
|
127
|
+
end
|
128
|
+
|
129
|
+
def gemspec(name)
|
130
|
+
"#{Gem::Specification.find_by_name(name).gem_dir}/#{name}.gemspec"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Spring
|
2
|
+
module Test
|
3
|
+
class RailsVersion
|
4
|
+
attr_reader :version
|
5
|
+
|
6
|
+
def initialize(string)
|
7
|
+
@version = Gem::Version.new(string)
|
8
|
+
end
|
9
|
+
|
10
|
+
def rails_3?
|
11
|
+
version < Gem::Version.new("4.0.0")
|
12
|
+
end
|
13
|
+
alias needs_testunit? rails_3?
|
14
|
+
|
15
|
+
def test_command
|
16
|
+
needs_testunit? ? 'bin/testunit' : 'bin/rake test'
|
17
|
+
end
|
18
|
+
|
19
|
+
def controller_tests_dir
|
20
|
+
rails_3? ? 'functional' : 'controllers'
|
21
|
+
end
|
22
|
+
|
23
|
+
def bundles_spring?
|
24
|
+
version.segments.take(2) == [4, 1] || version > Gem::Version.new("4.1")
|
25
|
+
end
|
26
|
+
|
27
|
+
def major
|
28
|
+
version.segments[0]
|
29
|
+
end
|
30
|
+
|
31
|
+
def minor
|
32
|
+
version.segments[1]
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
version.to_s
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require "tmpdir"
|
2
|
+
require "fileutils"
|
3
|
+
require "timeout"
|
4
|
+
require "active_support/core_ext/numeric/time"
|
5
|
+
|
6
|
+
module Spring
|
7
|
+
module Test
|
8
|
+
class WatcherTest < ActiveSupport::TestCase
|
9
|
+
runnables.delete self # prevent Minitest running this class
|
10
|
+
|
11
|
+
LATENCY = 0.001
|
12
|
+
TIMEOUT = 1
|
13
|
+
|
14
|
+
attr_accessor :dir
|
15
|
+
|
16
|
+
def watcher_class
|
17
|
+
raise NotImplementedError
|
18
|
+
end
|
19
|
+
|
20
|
+
def watcher
|
21
|
+
@watcher ||= watcher_class.new(dir, LATENCY)
|
22
|
+
end
|
23
|
+
|
24
|
+
def setup
|
25
|
+
@dir = File.realpath(Dir.mktmpdir)
|
26
|
+
end
|
27
|
+
|
28
|
+
def teardown
|
29
|
+
FileUtils.remove_entry_secure @dir
|
30
|
+
watcher.stop
|
31
|
+
end
|
32
|
+
|
33
|
+
def touch(file, mtime = nil)
|
34
|
+
options = {}
|
35
|
+
options[:mtime] = mtime if mtime
|
36
|
+
FileUtils.touch(file, options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def assert_stale
|
40
|
+
timeout = Time.now + TIMEOUT
|
41
|
+
sleep LATENCY until watcher.stale? || Time.now > timeout
|
42
|
+
assert watcher.stale?
|
43
|
+
end
|
44
|
+
|
45
|
+
def assert_not_stale
|
46
|
+
sleep LATENCY * 10
|
47
|
+
assert !watcher.stale?
|
48
|
+
end
|
49
|
+
|
50
|
+
test "starting with no file" do
|
51
|
+
file = "#{@dir}/omg"
|
52
|
+
touch file, Time.now - 2.seconds
|
53
|
+
|
54
|
+
watcher.start
|
55
|
+
watcher.add file
|
56
|
+
|
57
|
+
assert_not_stale
|
58
|
+
touch file, Time.now
|
59
|
+
assert_stale
|
60
|
+
end
|
61
|
+
|
62
|
+
test "is stale when a watched file is updated" do
|
63
|
+
file = "#{@dir}/omg"
|
64
|
+
touch file, Time.now - 2.seconds
|
65
|
+
|
66
|
+
watcher.add file
|
67
|
+
watcher.start
|
68
|
+
|
69
|
+
assert_not_stale
|
70
|
+
touch file, Time.now
|
71
|
+
assert_stale
|
72
|
+
end
|
73
|
+
|
74
|
+
test "is stale when removing files" do
|
75
|
+
file = "#{@dir}/omg"
|
76
|
+
touch file, Time.now
|
77
|
+
|
78
|
+
watcher.add file
|
79
|
+
watcher.start
|
80
|
+
|
81
|
+
assert_not_stale
|
82
|
+
FileUtils.rm(file)
|
83
|
+
assert_stale
|
84
|
+
end
|
85
|
+
|
86
|
+
test "is stale when files are added to a watched directory" do
|
87
|
+
subdir = "#{@dir}/subdir"
|
88
|
+
FileUtils.mkdir(subdir)
|
89
|
+
|
90
|
+
watcher.add subdir
|
91
|
+
watcher.start
|
92
|
+
|
93
|
+
assert_not_stale
|
94
|
+
touch "#{subdir}/foo", Time.now - 1.minute
|
95
|
+
assert_stale
|
96
|
+
end
|
97
|
+
|
98
|
+
test "is stale when a file is changed in a watched directory" do
|
99
|
+
subdir = "#{@dir}/subdir"
|
100
|
+
FileUtils.mkdir(subdir)
|
101
|
+
touch "#{subdir}/foo", Time.now - 1.minute
|
102
|
+
|
103
|
+
watcher.add subdir
|
104
|
+
watcher.start
|
105
|
+
|
106
|
+
assert_not_stale
|
107
|
+
touch "#{subdir}/foo", Time.now
|
108
|
+
assert_stale
|
109
|
+
end
|
110
|
+
|
111
|
+
test "adding doesn't wipe stale state" do
|
112
|
+
file = "#{@dir}/omg"
|
113
|
+
file2 = "#{@dir}/foo"
|
114
|
+
touch file, Time.now - 2.seconds
|
115
|
+
touch file2, Time.now - 2.seconds
|
116
|
+
|
117
|
+
watcher.add file
|
118
|
+
watcher.start
|
119
|
+
|
120
|
+
assert_not_stale
|
121
|
+
|
122
|
+
touch file, Time.now
|
123
|
+
watcher.add file2
|
124
|
+
|
125
|
+
assert_stale
|
126
|
+
end
|
127
|
+
|
128
|
+
test "on stale" do
|
129
|
+
file = "#{@dir}/omg"
|
130
|
+
touch file, Time.now - 2.seconds
|
131
|
+
|
132
|
+
stale = false
|
133
|
+
watcher.on_stale { stale = true }
|
134
|
+
|
135
|
+
watcher.add file
|
136
|
+
watcher.start
|
137
|
+
|
138
|
+
touch file, Time.now
|
139
|
+
|
140
|
+
Timeout.timeout(1) { sleep 0.01 until stale }
|
141
|
+
assert stale
|
142
|
+
|
143
|
+
# Check that we only get notified once
|
144
|
+
stale = false
|
145
|
+
sleep LATENCY * 3
|
146
|
+
assert !stale
|
147
|
+
end
|
148
|
+
|
149
|
+
test "add relative path" do
|
150
|
+
File.write("#{dir}/foo", "foo")
|
151
|
+
watcher.add "foo"
|
152
|
+
assert_equal ["#{dir}/foo"], watcher.files.to_a
|
153
|
+
end
|
154
|
+
|
155
|
+
test "add dot relative path" do
|
156
|
+
File.write("#{dir}/foo", "foo")
|
157
|
+
watcher.add "./foo"
|
158
|
+
assert_equal ["#{dir}/foo"], watcher.files.to_a
|
159
|
+
end
|
160
|
+
|
161
|
+
test "add non existent file" do
|
162
|
+
watcher.add './foobar'
|
163
|
+
assert watcher.files.empty?
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|