zeus 0.15.4 → 0.15.10

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2f28b5877e1a9f2d864f994db8ec997e2bfd2e88
4
+ data.tar.gz: 7e71058d4c5171c6992f5074e5f1df204392019f
5
+ SHA512:
6
+ metadata.gz: 4c369f05160ce2dbbb0b631af280f73bc19bdfa524109e03d33c9ef0216f33b0c47e1289d248e7d7b462c275d7960da72acfee86f2dd2c05f47682278cc0a4da
7
+ data.tar.gz: 266f75f0595297687016d2af1d7d7319f62f83a45a8ed815c56c73a2385bd40e46b75478c5f3221dc358a752283b1e0455abb4fe00bbbaefcc64d567db136c73
data/Gemfile CHANGED
@@ -3,5 +3,9 @@ source 'https://rubygems.org'
3
3
  # NOTE: Avoid putting development deps in gemspec
4
4
  gemspec development_group: :gem_build_tools
5
5
 
6
- gem 'rspec', '~> 3.1', groups: [:test, :development]
6
+ group :test, :development do
7
+ gem 'rspec', '~> 3.1'
8
+ gem 'pry', '~> 0.10'
9
+ end
10
+
7
11
  gem 'rake', group: :gem_build_tools
@@ -1,33 +1,44 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- zeus (0.15.4)
4
+ zeus (0.15.10)
5
5
  method_source (>= 0.6.7)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
+ coderay (1.1.1)
10
11
  diff-lcs (1.2.5)
11
12
  method_source (0.8.2)
12
- rake (10.3.0)
13
- rspec (3.1.0)
14
- rspec-core (~> 3.1.0)
15
- rspec-expectations (~> 3.1.0)
16
- rspec-mocks (~> 3.1.0)
17
- rspec-core (3.1.7)
18
- rspec-support (~> 3.1.0)
19
- rspec-expectations (3.1.2)
13
+ pry (0.10.3)
14
+ coderay (~> 1.1.0)
15
+ method_source (~> 0.8.1)
16
+ slop (~> 3.4)
17
+ rake (11.1.2)
18
+ rspec (3.4.0)
19
+ rspec-core (~> 3.4.0)
20
+ rspec-expectations (~> 3.4.0)
21
+ rspec-mocks (~> 3.4.0)
22
+ rspec-core (3.4.4)
23
+ rspec-support (~> 3.4.0)
24
+ rspec-expectations (3.4.0)
20
25
  diff-lcs (>= 1.2.0, < 2.0)
21
- rspec-support (~> 3.1.0)
22
- rspec-mocks (3.1.3)
23
- rspec-support (~> 3.1.0)
24
- rspec-support (3.1.2)
26
+ rspec-support (~> 3.4.0)
27
+ rspec-mocks (3.4.1)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.4.0)
30
+ rspec-support (3.4.1)
31
+ slop (3.6.0)
25
32
 
26
33
  PLATFORMS
27
34
  ruby
28
35
 
29
36
  DEPENDENCIES
30
37
  bundler (~> 1.6)
38
+ pry (~> 0.10)
31
39
  rake
32
40
  rspec (~> 3.1)
33
41
  zeus!
42
+
43
+ BUNDLED WITH
44
+ 1.12.3
data/bin/pry ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'pry' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('pry', 'pry')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rake' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rake', 'rake')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'rspec')
Binary file
Binary file
Binary file
@@ -65,17 +65,11 @@ module Zeus
65
65
  master.send_io(remote)
66
66
 
67
67
  # Now I need to tell the master about my PID and ID
68
- local.write "P:#{Process.pid}:#{identifier}\0"
68
+ local.write "P:#{Process.pid}:#{@parent_pid || 0}:#{identifier}\0"
69
69
  local.send_io(feature_pipe_r)
70
70
  feature_pipe_r.close
71
71
 
72
- # Now we run the action and report its success/fail status to the master.
73
- features = Zeus::LoadTracking.features_loaded_by {
74
- run_action(local, identifier, feature_pipe_w)
75
- }
76
-
77
- # the master wants to know about the files that running the action caused us to load.
78
- Thread.new { notify_features(feature_pipe_w, features) }
72
+ run_action(local, identifier, feature_pipe_w)
79
73
 
80
74
  # We are now 'connected'. From this point, we may receive requests to fork.
81
75
  children = Set.new
@@ -93,15 +87,20 @@ module Zeus
93
87
  messages.split("\0").each do |new_identifier|
94
88
  new_identifier =~ /^(.):(.*)/
95
89
  code, ident = $1, $2
90
+
91
+ forked_from = Process.pid
92
+
96
93
  pid = fork
97
94
  if pid
98
95
  # We're in the parent. Record the child:
99
96
  children << pid
100
97
  elsif code == "S"
101
98
  # Child, supposed to start another step:
99
+ @parent_pid = forked_from
102
100
  throw(:boot_step, ident.to_sym)
103
101
  else
104
102
  # Child, supposed to run a command:
103
+ @parent_pid = forked_from
105
104
  return [ident.to_sym, local]
106
105
  end
107
106
  end
@@ -137,7 +136,7 @@ module Zeus
137
136
 
138
137
  plan.after_fork
139
138
  client_terminal = local.recv_io
140
- local.write "P:#{Process.pid}:\0"
139
+ local.write "P:#{Process.pid}:#{@parent_pid}:\0"
141
140
  local.close
142
141
 
143
142
  $stdin.reopen(client_terminal)
@@ -194,20 +193,27 @@ module Zeus
194
193
  end
195
194
 
196
195
  def run_action(socket, identifier, feature_pipe_w)
197
- loaded = false
198
- begin
196
+ # Now we run the action and report its success/fail status to the master.
197
+ features, err = Zeus::LoadTracking.features_loaded_by do
199
198
  plan.after_fork unless identifier == :boot
200
199
  plan.send(identifier)
201
- loaded = true
202
- socket.write "R:OK\0"
203
- rescue Exception => e
204
- report_error_to_master(socket, e)
200
+ end
205
201
 
206
- # Report any setup-time failures back to the Zeus master:
207
- unless loaded
208
- notify_features(feature_pipe_w, Zeus::LoadTracking.all_features)
202
+ if err
203
+ # If we received an error, report features to the master syncronously.
204
+ # We need to do this before reporting the error to the master
205
+ # otherwise it will kill us before we can report features.
206
+ begin
207
+ notify_features(feature_pipe_w, features)
208
+ feature_pipe_w.close
209
+ ensure
210
+ report_error_to_master(socket, err)
209
211
  end
210
- feature_pipe_w.close
212
+ else
213
+ # If we booted successfully, report features in a new thread
214
+ # so we can immediately begin listening for commands.
215
+ socket.write "R:OK\0"
216
+ Thread.new { notify_features(feature_pipe_w, features) }
211
217
  end
212
218
  end
213
219
  end
@@ -1,23 +1,47 @@
1
1
  module Zeus
2
2
  class LoadTracking
3
3
  class << self
4
-
5
4
  def features_loaded_by(&block)
6
- old_features = all_features()
7
- yield
8
- new_features = all_features() - old_features
9
- return new_features
5
+ old_features = all_features
6
+
7
+ # Catch exceptions so we can determine the features
8
+ # that were being loaded at the time of the exception.
9
+ err_features = []
10
+ begin
11
+ yield
12
+ rescue SyntaxError => err
13
+ # SyntaxErrors are a bit weird in that the file containing
14
+ # the error is not in the backtrace, only the error message.
15
+ match = /\A([^:]+):\d+: syntax error/.match(err.message)
16
+ err_features << match[1] if match
17
+ rescue Exception => err
18
+ # Just capture this to add to the err_features list
19
+ end
20
+
21
+ if err && err.backtrace
22
+ err_features += err.backtrace.map { |b| b.split(':').first }
23
+ .select { |f| f.start_with?('/') }
24
+ .take_while { |f| f != __FILE__ }
25
+ end
26
+
27
+ new_features = all_features + err_features - old_features
28
+ new_features.uniq!
29
+
30
+ [new_features, err]
10
31
  end
11
32
 
33
+ # Check the load path first to see if the file getting loaded is already
34
+ # loaded. Otherwise, add the file to the $untracked_features array which
35
+ # then gets added to $LOADED_FEATURES array.
12
36
  def add_feature(file)
13
- path = if File.exist?(File.expand_path(file))
14
- File.expand_path(file)
15
- else
16
- find_in_load_path(file)
37
+ full_path = File.expand_path(file)
38
+
39
+ if find_in_load_path(full_path) || File.exist?(full_path)
40
+ add_extra_feature(full_path)
17
41
  end
18
- add_extra_feature(path) if path
19
42
  end
20
43
 
44
+ # $LOADED_FEATURES global variable is used internally by Rubygems
21
45
  def all_features
22
46
  untracked = defined?($untracked_features) ? $untracked_features : []
23
47
  $LOADED_FEATURES + untracked
@@ -30,18 +54,20 @@ module Zeus
30
54
  $untracked_features << path
31
55
  end
32
56
 
33
- def find_in_load_path(file)
34
- $LOAD_PATH.map { |path| "#{path}/#{file}" }.detect{ |file| File.exist? file }
57
+ def find_in_load_path(file_path)
58
+ $LOAD_PATH.detect { |path| path == file_path }
35
59
  end
36
60
  end
37
61
  end
38
62
  end
39
63
 
64
+
40
65
  module Kernel
41
66
 
42
67
  def load(file, *a)
43
68
  Kernel.load(file, *a)
44
69
  end
70
+ private :load
45
71
 
46
72
  class << self
47
73
  alias_method :__load_without_zeus, :load
@@ -194,12 +194,9 @@ module Zeus
194
194
 
195
195
  # directly run the tests from here and exit with the status of the tests passing or failing
196
196
  case framework
197
- when :minitest5
198
- nerf_test_unit_autorunner
199
- exit(Minitest.run(test_arguments) ? 0 : 1)
200
- when :minitest_old
201
- nerf_test_unit_autorunner
202
- exit(MiniTest::Unit.runner.run(test_arguments).to_i)
197
+ when :minitest5, :minitest_old
198
+ ARGV.replace(test_arguments)
199
+ exit
203
200
  when :testunit1, :testunit2
204
201
  exit Test::Unit::AutoRunner.run(false, nil, test_arguments)
205
202
  else
@@ -348,13 +345,6 @@ module Zeus
348
345
  end
349
346
  end
350
347
 
351
- def nerf_test_unit_autorunner
352
- return unless defined?(Test::Unit::Runner)
353
- if Test::Unit::Runner.class_variable_get("@@installed_at_exit")
354
- Test::Unit::Runner.class_variable_set("@@stop_auto_run", true)
355
- end
356
- end
357
-
358
348
  # Fail loudly if this isn't supported
359
349
  def not_supported
360
350
  abort "This test framework is not supported! Please open up an issue at https://github.com/qrush/m !"
@@ -131,6 +131,13 @@ module Zeus
131
131
  require 'rails/commands/console'
132
132
 
133
133
  if defined?(Pry)
134
+ # Adding Rails Console helpers to Pry.
135
+ if (3..4).include?(::Rails::VERSION::MAJOR)
136
+ require 'rails/console/app'
137
+ require 'rails/console/helpers'
138
+ TOPLEVEL_BINDING.eval('self').extend ::Rails::ConsoleMethods
139
+ end
140
+
134
141
  Pry.start
135
142
  else
136
143
  ::Rails::Console.start(::Rails.application)
@@ -174,20 +181,6 @@ module Zeus
174
181
  end
175
182
 
176
183
  def test_helper
177
- # don't let minitest setup another exit hook
178
- begin
179
- require 'minitest/unit'
180
- if defined?(Minitest::Runnable)
181
- # Minitest 5
182
- MiniTest.class_variable_set('@@installed_at_exit', true)
183
- elsif defined?(MiniTest)
184
- # Old versions of Minitest
185
- MiniTest::Unit.class_variable_set("@@installed_at_exit", true)
186
- end
187
- rescue LoadError
188
- # noop
189
- end
190
-
191
184
  if ENV['RAILS_TEST_HELPER']
192
185
  require ENV['RAILS_TEST_HELPER']
193
186
  else
@@ -209,22 +202,30 @@ module Zeus
209
202
  # if there are two test frameworks and one of them is RSpec,
210
203
  # then "zeus test/rspec/testrb" without arguments runs the
211
204
  # RSpec suite by default.
212
- if (argv.empty? || spec_file?(argv)) && defined?(RSpec)
213
- # disable autorun in case the user left it in spec_helper.rb
214
- RSpec::Core::Runner.disable_autorun!
215
- argv = ["spec"] if argv.empty?
216
- exit RSpec::Core::Runner.run(argv)
205
+ if using_rspec?(argv)
206
+ ARGV.replace(argv)
207
+ RSpec::Core::Runner.invoke
217
208
  else
209
+ require 'minitest/autorun' if using_minitest?
210
+ # Minitest and old Test::Unit
218
211
  Zeus::M.run(argv)
219
212
  end
220
213
  end
221
214
 
222
215
  private
223
216
 
217
+ def using_rspec?(argv)
218
+ defined?(RSpec) && (argv.empty? || spec_file?(argv))
219
+ end
220
+
221
+ def using_minitest?
222
+ defined?(:MiniTest) || defined?(:Minitest)
223
+ end
224
+
224
225
  SPEC_DIR_REGEXP = %r"(^|/)spec"
225
226
  SPEC_FILE_REGEXP = /.+_spec\.rb$/
226
227
 
227
- def spec_file? argv
228
+ def spec_file?(argv)
228
229
  argv.any? do |arg|
229
230
  arg.match(Regexp.union(SPEC_DIR_REGEXP, SPEC_FILE_REGEXP))
230
231
  end
@@ -1,3 +1,3 @@
1
1
  module Zeus
2
- VERSION = "0.15.4"
2
+ VERSION = "0.15.10"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "ZEUS" "1" "September 2014" "" ""
4
+ .TH "ZEUS" "1" "January 2016" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBzeus\fR \- boot rails in under a second
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "ZEUS\-INIT" "1" "April 2014" "" ""
4
+ .TH "ZEUS\-INIT" "1" "January 2016" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBzeus\-init\fR \- Generate a template zeus\.json
@@ -14,4 +14,4 @@ DESCRIPTION
14
14
 
15
15
 
16
16
 
17
- April 2014 ZEUS-INIT(1)
17
+ January 2016 ZEUS-INIT(1)
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "ZEUS\-START" "1" "April 2014" "" ""
4
+ .TH "ZEUS\-START" "1" "January 2016" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBzeus\-start\fR \- Start a zeus server
@@ -15,4 +15,4 @@ DESCRIPTION
15
15
 
16
16
 
17
17
 
18
- April 2014 ZEUS-START(1)
18
+ January 2016 ZEUS-START(1)
@@ -75,4 +75,4 @@ BUILTIN COMMANDS
75
75
 
76
76
 
77
77
 
78
- September 2014 ZEUS(1)
78
+ January 2016 ZEUS(1)
@@ -0,0 +1 @@
1
+ exit(1)
@@ -0,0 +1,2 @@
1
+ # This file has invalid syntax and will cause a LoadError when required
2
+ foo(
@@ -0,0 +1,2 @@
1
+ # This is a single ruby file that doesn't do anything
2
+ # on require.
@@ -0,0 +1,3 @@
1
+ def raise_it(e)
2
+ raise e.new('Raising!')
3
+ end
@@ -0,0 +1,2 @@
1
+ # This is a single ruby file that doesn't do anything
2
+ # on require.
@@ -0,0 +1,2 @@
1
+ # This is a single ruby file that doesn't do anything
2
+ # on require.
@@ -0,0 +1,2 @@
1
+ # Loading this file triggers a runtime error
2
+ raise "You can't catch me!"
@@ -0,0 +1,2 @@
1
+ # This is a single ruby file that doesn't do anything
2
+ # on require.
@@ -1,20 +1,31 @@
1
- module MiniTest
2
- module Unit
1
+ module Minitest
2
+ class Runnable
3
+ end
4
+ end
5
+
6
+ class MiniTest
7
+ class Unit
3
8
  class TestCase
4
9
  end
5
10
  end
6
11
  end
7
12
 
8
13
  def stub_mini_test_methods
9
- allow(MiniTest::Unit::TestCase).to receive(:test_suites).and_return([fake_suite])
10
- allow(MiniTest::Unit).to receive(:runner).and_return(fake_runner)
14
+ allow(Minitest::Runnable).to receive(:runnables).and_return([fake_mt5_suite])
15
+ allow(MiniTest::Unit::TestCase).to receive(:test_suite).and_return([fake_mt_old_suite])
11
16
  end
12
17
 
13
18
  def fake_runner
14
- @runner ||= double("Runner", :run => 0)
19
+ @runner ||= double("Runner", :run => 0)
20
+ end
21
+
22
+ def fake_mt5_suite
23
+ @suite ||= double("TestSuite",
24
+ :runnable_methods => [test_method],
25
+ :instance_method => fake_instance_method(test_method))
15
26
  end
16
27
 
17
- def fake_suite
28
+ def fake_mt_old_suite
18
29
  @suite ||= double("TestSuite",
19
30
  :test_methods => [test_method],
20
31
  :instance_method => fake_instance_method(test_method))
@@ -0,0 +1,105 @@
1
+ require 'zeus/load_tracking'
2
+
3
+ describe "Zeus::LoadTracking" do
4
+ let(:test_filename) { __FILE__ }
5
+ let(:test_dirname) { File.dirname(test_filename) }
6
+
7
+ class MyError < StandardError; end
8
+
9
+ describe '.add_feature' do
10
+ context 'already in load path' do
11
+ before do
12
+ # add the dir path of the tempfile to LOAD_PATH
13
+ $LOAD_PATH << test_dirname
14
+ end
15
+
16
+ after { $LOAD_PATH.delete test_dirname }
17
+
18
+ it 'adds full filepath to $untracked_features' do
19
+ Zeus::LoadTracking.add_feature(test_filename)
20
+
21
+ expect($untracked_features).to include(__dir__ + "/load_tracking_spec.rb")
22
+ end
23
+ end
24
+
25
+ context 'not in load path' do
26
+ it 'adds full filepath to $untracked_features' do
27
+ Zeus::LoadTracking.add_feature(test_filename)
28
+
29
+ expect($untracked_features).to include(__dir__ + "/load_tracking_spec.rb")
30
+ end
31
+ end
32
+
33
+ context '.features_loaded_by' do
34
+ it 'returns list of new files loaded when block executes' do
35
+ new_files, = Zeus::LoadTracking.features_loaded_by do
36
+ $untracked_features << "an_untracked_feature.rb"
37
+ end
38
+
39
+ expect(new_files).to eq(["an_untracked_feature.rb"])
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '.features_loaded_by' do
45
+ def expect_to_load(expect_features, expect_err=NilClass)
46
+ new_files, err = Zeus::LoadTracking.features_loaded_by do
47
+ yield
48
+ end
49
+
50
+ expect(new_files.sort).to eq(expect_features.sort)
51
+ expect(err).to be_instance_of(expect_err)
52
+ end
53
+
54
+ def expand_asset_path(path)
55
+ File.join(__dir__, 'assets', path)
56
+ end
57
+
58
+ context 'loading valid code' do
59
+ it 'tracks successful require_relative' do
60
+ expect_to_load([expand_asset_path('require_relative.rb')]) do
61
+ require_relative 'assets/require_relative'
62
+ end
63
+ end
64
+
65
+ it 'tracks successful require' do
66
+ expect_to_load([expand_asset_path('require.rb')]) do
67
+ require expand_asset_path('require')
68
+ end
69
+ end
70
+
71
+ it 'tracks loads' do
72
+ expect_to_load([expand_asset_path('load.rb')]) do
73
+ load expand_asset_path('load.rb')
74
+ end
75
+ end
76
+ end
77
+
78
+ context 'loading invalid code' do
79
+ it 'tracks requires that raise a SyntaxError' do
80
+ expect_to_load([expand_asset_path('invalid_syntax.rb')], SyntaxError) do
81
+ require expand_asset_path('invalid_syntax')
82
+ end
83
+ end
84
+
85
+ it 'tracks requires that raise a RuntimeError' do
86
+ expect_to_load([expand_asset_path('runtime_error.rb')], RuntimeError) do
87
+ require expand_asset_path('runtime_error')
88
+ end
89
+ end
90
+
91
+ it 'tracks requires that exit' do
92
+ expect_to_load([expand_asset_path('exit.rb')], SystemExit) do
93
+ require expand_asset_path('exit')
94
+ end
95
+ end
96
+
97
+ it 'tracks requires that throw in a method call' do
98
+ expect_to_load([expand_asset_path('raise.rb')], MyError) do
99
+ require expand_asset_path('raise')
100
+ raise_it(MyError)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -1,11 +1,36 @@
1
- require 'spec_helper'
1
+ require 'zeus/rails'
2
2
  require 'fake_mini_test'
3
3
 
4
4
  module Zeus::M
5
5
  describe Runner do
6
6
  let(:test_method) { fake_test_method }
7
7
 
8
+ matcher :exit_with_code do |exp_code|
9
+ actual = nil
10
+ match do |block|
11
+ begin
12
+ block.call
13
+ rescue SystemExit => e
14
+ actual = e.status
15
+ end
16
+ actual and actual == exp_code
17
+ end
18
+ failure_message do |_block|
19
+ "expected block to call exit(#{exp_code}) but exit" +
20
+ (actual.nil? ? " not called" : "(#{actual}) was called")
21
+ end
22
+ failure_message_when_negated do |_block|
23
+ "expected block not to call exit(#{exp_code})"
24
+ end
25
+ description do
26
+ "expect block to call exit(#{exp_code})"
27
+ end
28
+ end
29
+
8
30
  before(:each) do
31
+ allow(Dir).to receive(:glob).and_return(["path/to/file.rb"])
32
+ allow(Kernel).to receive(:load)
33
+
9
34
  stub_mini_test_methods
10
35
  end
11
36
 
@@ -15,17 +40,16 @@ module Zeus::M
15
40
  it "escapes the question mark when using line number" do
16
41
  argv = ["path/to/file.rb:2"]
17
42
 
18
- expect(fake_runner).to receive(:run).with(["-n", "/(test_my_test_method\\?)/"])
19
-
20
43
  expect(lambda { Runner.new(argv).run }).to exit_with_code(0)
44
+ expect(ARGV).to eq(["-n", "/(test_my_test_method\\?)/"])
21
45
  end
22
46
 
23
47
  it "does not escape regex on explicit names" do
24
48
  argv = ["path/to/file.rb", "--name", fake_special_characters_test_method]
25
49
 
26
- allow(fake_runner).to receive(:run).with(["-n", "test_my_test_method?"])
27
-
28
50
  expect(lambda { Runner.new(argv).run }).to exit_with_code(0)
51
+
52
+ expect(ARGV).to eq(["-n", "test_my_test_method?"])
29
53
  end
30
54
  end
31
55
 
@@ -33,9 +57,9 @@ module Zeus::M
33
57
  it "runs the test" do
34
58
  argv = ["path/to/file.rb"]
35
59
 
36
- allow(fake_runner).to receive(:run).with([])
37
-
38
60
  expect(lambda { Runner.new(argv).run }).to exit_with_code(0)
61
+
62
+ expect(ARGV).to eq([])
39
63
  end
40
64
  end
41
65
 
@@ -44,7 +68,6 @@ module Zeus::M
44
68
  argv = ["path/to/file.rb:100"]
45
69
 
46
70
  expect(STDERR).to receive(:write).with(/No tests found on line 100/)
47
- expect(fake_runner).to_not receive :run
48
71
 
49
72
  expect(lambda { Runner.new(argv).run }).to_not exit_with_code(0)
50
73
  end
@@ -52,9 +75,8 @@ module Zeus::M
52
75
  it "runs the test if the correct line number is given" do
53
76
  argv = ["path/to/file.rb:2"]
54
77
 
55
- expect(fake_runner).to receive(:run).with(["-n", "/(#{fake_test_method})/"])
56
-
57
78
  expect(lambda { Runner.new(argv).run }).to exit_with_code(0)
79
+ expect(ARGV).to eq(["-n", "/(#{fake_test_method})/"])
58
80
  end
59
81
  end
60
82
 
@@ -62,17 +84,15 @@ module Zeus::M
62
84
  it "runs the specified tests when using a pattern in --name option" do
63
85
  argv = ["path/to/file.rb", "--name", "/#{fake_test_method}/"]
64
86
 
65
- expect(fake_runner).to receive(:run).with(["-n", "/#{fake_test_method}/"])
66
-
67
87
  expect(lambda { Runner.new(argv).run }).to exit_with_code(0)
88
+ expect(ARGV).to eq(["-n", "/#{fake_test_method}/"])
68
89
  end
69
90
 
70
91
  it "runs the specified tests when using a pattern in -n option" do
71
92
  argv = ["path/to/file.rb", "-n", "/method/"]
72
93
 
73
- expect(fake_runner).to receive(:run).with(["-n", "/method/"])
74
-
75
94
  expect(lambda { Runner.new(argv).run }).to exit_with_code(0)
95
+ expect(ARGV).to eq(["-n", "/method/"])
76
96
  end
77
97
 
78
98
  it "aborts if no test matches the given pattern" do
@@ -87,9 +107,8 @@ module Zeus::M
87
107
  it "runs the specified tests when using a name (no pattern)" do
88
108
  argv = ["path/to/file.rb", "-n", "#{fake_test_method}"]
89
109
 
90
- expect(fake_runner).to receive(:run).with(["-n", fake_test_method])
91
-
92
110
  expect(lambda { Runner.new(argv).run }).to exit_with_code(0)
111
+ expect(ARGV).to eq(["-n", fake_test_method])
93
112
  end
94
113
 
95
114
  it "aborts if no test matches the given test name" do
@@ -1,17 +1,14 @@
1
- require 'spec_helper'
1
+ require 'zeus/rails'
2
2
 
3
3
  module Zeus
4
4
  describe Rails do
5
5
  subject(:rails) { Rails.new }
6
6
 
7
- describe "#test_helper" do
8
- before(:each) do
9
- # Zeus::Rails#test_helper will require minitest/unit by default.
10
- # We need to catch it first, before setting expectations on
11
- # helper_file requires below.
12
- expect(rails).to receive(:require).with("minitest/unit")
13
- end
7
+ def mock_file_existence(file, result)
8
+ expect(File).to receive(:exists?).with(file).and_return(result)
9
+ end
14
10
 
11
+ describe "#test_helper" do
15
12
  context "when ENV['RAILS_TEST_HELPER'] is set" do
16
13
  it "loads the test helper file from the environment variable" do
17
14
  helper = "a_test_helper"
@@ -84,5 +81,48 @@ module Zeus
84
81
  end
85
82
  end
86
83
  end
84
+
85
+ describe "#test" do
86
+ def expect_minitest_autorun
87
+ # Zeus::Rails#test_helper will require minitest/unit by default.
88
+ # We need to catch it first, before setting expectations on
89
+ # helper_file requires below.
90
+ expect_any_instance_of(Rails).to receive(:require).with("minitest/autorun")
91
+ end
92
+
93
+ context 'minitest' do
94
+ before do
95
+ module Zeus::M
96
+ end
97
+ expect(Zeus::M).to receive(:run)
98
+ end
99
+
100
+ it "requires autorun when testing with new minitest" do
101
+ module ::Minitest
102
+ end
103
+ expect_minitest_autorun
104
+
105
+ rails.test
106
+ end
107
+
108
+ it "requires autorun when testing with old minitest" do
109
+ expect_minitest_autorun
110
+
111
+ rails.test
112
+ end
113
+ end
114
+
115
+ context 'rspec' do
116
+ before do
117
+ class ::RSpec::Core::Runner
118
+ end
119
+ end
120
+
121
+ it "calls rspec core runner" do
122
+ expect(RSpec::Core::Runner).to receive(:invoke)
123
+ rails.test(['test_spec.rb'])
124
+ end
125
+ end
126
+ end
87
127
  end
88
128
  end
@@ -5,7 +5,7 @@
5
5
  version = begin
6
6
  require File.expand_path('../lib/zeus/version', __FILE__)
7
7
  Zeus::VERSION
8
- rescue LoadError
8
+ rescue LoadError, NameError
9
9
  "0.0.0"
10
10
  end
11
11
 
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.homepage = "http://zeus.is"
20
20
 
21
21
  gem.files = files
22
- gem.extensions = ["ext/inotify-wrapper/extconf.rb"]
22
+ gem.extensions = []
23
23
  gem.executables = ['zeus']
24
24
  gem.test_files = []
25
25
  gem.name = "zeus"
metadata CHANGED
@@ -1,46 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zeus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.4
5
- prerelease:
4
+ version: 0.15.10
6
5
  platform: ruby
7
6
  authors:
8
7
  - Burke Libbey
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-01-21 00:00:00.000000000 Z
11
+ date: 2016-07-26 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: method_source
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: 0.6.7
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: 0.6.7
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: bundler
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
33
  version: '1.6'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
40
  version: '1.6'
46
41
  description: Boot any rails app in under a second
@@ -48,13 +43,17 @@ email:
48
43
  - burke@libbey.me
49
44
  executables:
50
45
  - zeus
51
- extensions:
52
- - ext/inotify-wrapper/extconf.rb
46
+ extensions: []
53
47
  extra_rdoc_files: []
54
48
  files:
55
- - .DS_Store
49
+ - Gemfile
50
+ - Gemfile.lock
51
+ - MIT-LICENSE
52
+ - Rakefile
53
+ - bin/pry
54
+ - bin/rake
55
+ - bin/rspec
56
56
  - bin/zeus
57
- - build/fsevents-wrapper
58
57
  - build/zeus-darwin-amd64
59
58
  - build/zeus-linux-386
60
59
  - build/zeus-linux-amd64
@@ -62,61 +61,56 @@ files:
62
61
  - examples/custom_plan/custom_plan.rb
63
62
  - examples/custom_plan/zeus.json
64
63
  - examples/zeus.json
65
- - ext/inotify-wrapper/extconf.rb
66
- - ext/inotify-wrapper/inotify-wrapper.cpp
67
- - Gemfile
68
- - Gemfile.lock
64
+ - lib/zeus.rb
69
65
  - lib/zeus/load_tracking.rb
66
+ - lib/zeus/m.rb
70
67
  - lib/zeus/m/test_collection.rb
71
68
  - lib/zeus/m/test_method.rb
72
- - lib/zeus/m.rb
73
69
  - lib/zeus/plan.rb
74
70
  - lib/zeus/rails.rb
75
71
  - lib/zeus/version.rb
76
- - lib/zeus.rb
77
72
  - man/build/zeus
78
73
  - man/build/zeus-init
79
74
  - man/build/zeus-init.txt
80
75
  - man/build/zeus-start
81
76
  - man/build/zeus-start.txt
82
77
  - man/build/zeus.txt
83
- - MIT-LICENSE
84
- - Rakefile
78
+ - spec/assets/exit.rb
79
+ - spec/assets/invalid_syntax.rb
80
+ - spec/assets/load.rb
81
+ - spec/assets/raise.rb
82
+ - spec/assets/require.rb
83
+ - spec/assets/require_relative.rb
84
+ - spec/assets/runtime_error.rb
85
+ - spec/assets/single_file.rb
85
86
  - spec/fake_mini_test.rb
87
+ - spec/load_tracking_spec.rb
86
88
  - spec/m_spec.rb
87
89
  - spec/rails_spec.rb
88
- - spec/spec_helper.rb
89
90
  - zeus.gemspec
90
91
  homepage: http://zeus.is
91
92
  licenses:
92
93
  - MIT
94
+ metadata: {}
93
95
  post_install_message:
94
96
  rdoc_options: []
95
97
  require_paths:
96
98
  - lib
97
99
  required_ruby_version: !ruby/object:Gem::Requirement
98
- none: false
99
100
  requirements:
100
- - - ! '>='
101
+ - - ">="
101
102
  - !ruby/object:Gem::Version
102
103
  version: '0'
103
- segments:
104
- - 0
105
- hash: -3287208852062006683
106
104
  required_rubygems_version: !ruby/object:Gem::Requirement
107
- none: false
108
105
  requirements:
109
- - - ! '>='
106
+ - - ">="
110
107
  - !ruby/object:Gem::Version
111
108
  version: '0'
112
- segments:
113
- - 0
114
- hash: -3287208852062006683
115
109
  requirements: []
116
110
  rubyforge_project:
117
- rubygems_version: 1.8.23
111
+ rubygems_version: 2.4.5.1
118
112
  signing_key:
119
- specification_version: 3
113
+ specification_version: 4
120
114
  summary: Zeus is an intelligent preloader for ruby applications. It allows normal
121
115
  development tasks to be run in a fraction of a second.
122
116
  test_files: []
data/.DS_Store DELETED
Binary file
Binary file
@@ -1,24 +0,0 @@
1
- if /linux/ =~ RUBY_PLATFORM
2
- open("Makefile", "wb") do |f|
3
- f.write <<-EOF
4
- CXX = g++
5
- CXXFLAGS = -O3 -g -Wall
6
-
7
- inotify-wrapper: inotify-wrapper.o
8
- $(CXX) $(CXXFLAGS) $< -o $@
9
-
10
- %.o: %.cpp
11
- $(CXX) $(CXXFLAGS) -c $< -o $@
12
-
13
- install:
14
- # do nothing
15
- EOF
16
- end
17
- else
18
- open("Makefile", "wb") do |f|
19
- f.write <<-EOF
20
- install:
21
- # do nothing
22
- EOF
23
- end
24
- end
@@ -1,117 +0,0 @@
1
- #include <map>
2
- #include <string>
3
-
4
- #include <stdio.h>
5
- #include <stdlib.h>
6
- #include <string.h>
7
- #include <errno.h>
8
- #include <unistd.h>
9
- #include <sys/types.h>
10
- #include <sys/inotify.h>
11
-
12
- #include <errno.h>
13
-
14
- #define EVENT_SIZE (sizeof (struct inotify_event))
15
- #define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
16
-
17
- using namespace std;
18
-
19
- static int _inotify_fd;
20
- static map<int, string> _WatchedFiles;
21
- static map<string, bool> _FileIsWatched;
22
-
23
- // static int inotifyFlags = IN_ATTRIB | IN_MODIFY | IN_MOVE_SELF | IN_DELETE_SELF;
24
- static int inotifyFlags = IN_ATTRIB | IN_MODIFY | IN_MOVE_SELF | IN_DELETE_SELF;
25
-
26
- void maybeAddFileToWatchList(string file)
27
- {
28
- if (_FileIsWatched[file]) return;
29
-
30
- int wd = inotify_add_watch(_inotify_fd, file.c_str(), inotifyFlags);
31
- int attempts = 0;
32
- // Files are momentarily inaccessible when they are rewritten. I couldn't
33
- // find a good way to deal with this, so we poll 'deleted' files for 0.25s or so
34
- // to see if they reappear.
35
- while (wd == -1 && errno == ENOENT) {
36
- usleep(10000);
37
- wd = inotify_add_watch(_inotify_fd, file.c_str(), inotifyFlags);
38
- if (attempts++ == 25) break; // try for at most about a quarter of a second
39
- }
40
- if (wd != -1) {
41
- _WatchedFiles[wd] = file;
42
- _FileIsWatched[file] = true;
43
- }
44
- }
45
-
46
- // This essentially removes a file from the watchlist then
47
- // immediately re-adds it. This is because when a file is rewritten,
48
- // as so many editors love to do, the watchdescriptor no longer refers to
49
- // the file, so re must re-watch the path.
50
- void replaceFileInWatchList(int wd, string file)
51
- {
52
- _FileIsWatched.erase(file);
53
- _WatchedFiles.erase(wd);
54
- inotify_rm_watch(_inotify_fd, wd);
55
- maybeAddFileToWatchList(file);
56
- }
57
-
58
- void handleStdin()
59
- {
60
- char line[2048];
61
- if (fgets(line, sizeof(line), stdin) == NULL) return;
62
- line[strlen(line)-1] = 0;
63
-
64
- maybeAddFileToWatchList(string(line));
65
- }
66
-
67
- void handleInotify()
68
- {
69
- int length;
70
- int i = 0;
71
- char buffer[EVENT_BUF_LEN];
72
- string filename;
73
-
74
- length = read(_inotify_fd, buffer, EVENT_BUF_LEN);
75
- if (length < 0) return;
76
-
77
- while (i < length) {
78
- struct inotify_event *event = (struct inotify_event *) &buffer[i];
79
- string file = _WatchedFiles[event->wd];
80
- if (file != "") {
81
- printf("%s\n", file.c_str());
82
- fflush(stdout);
83
- replaceFileInWatchList(event->wd, file);
84
- }
85
-
86
- i += EVENT_SIZE + event->len;
87
- }
88
- }
89
-
90
- void go()
91
- {
92
- fd_set rfds;
93
- int retval;
94
-
95
- for (;;) {
96
- FD_ZERO(&rfds);
97
- FD_SET(0, &rfds);
98
- FD_SET(_inotify_fd, &rfds);
99
-
100
- retval = select(_inotify_fd+1, &rfds, NULL, NULL, NULL);
101
-
102
- if (retval == -1) {
103
- // perror("select");
104
- } else if (retval) {
105
- if(feof(stdin)) break;
106
- if (FD_ISSET(0, &rfds)) handleStdin();
107
- if (FD_ISSET(_inotify_fd, &rfds)) handleInotify();
108
- }
109
- }
110
- }
111
-
112
-
113
- int main(int argc, const char *argv[])
114
- {
115
- _inotify_fd = inotify_init();
116
- go();
117
- }
@@ -1,38 +0,0 @@
1
- require 'zeus/rails'
2
-
3
- RSpec::Matchers.define :exit_with_code do |exp_code|
4
- actual = nil
5
- match do |block|
6
- begin
7
- block.call
8
- rescue SystemExit => e
9
- actual = e.status
10
- end
11
- actual and actual == exp_code
12
- end
13
- failure_message do |block|
14
- "expected block to call exit(#{exp_code}) but exit" +
15
- (actual.nil? ? " not called" : "(#{actual}) was called")
16
- end
17
- failure_message_when_negated do |block|
18
- "expected block not to call exit(#{exp_code})"
19
- end
20
- description do
21
- "expect block to call exit(#{exp_code})"
22
- end
23
- end
24
-
25
- def stub_system_methods
26
- allow(Dir).to receive(:glob).and_return(["path/to/file.rb"])
27
- allow(Kernel).to receive(:load)
28
- end
29
-
30
- def mock_file_existence(file, result)
31
- expect(File).to receive(:exists?).with(file).and_return(result)
32
- end
33
-
34
- RSpec.configure do |config|
35
- config.before(:each) do
36
- stub_system_methods
37
- end
38
- end