tbooster 0.0.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .rvmrc
2
+ *.gem
3
+ todo
4
+ *.swp
5
+ tmp
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ tbooster
2
+ ========
3
+
4
+ Runs unit tests faster by not reloading the testing environment every time
data/bin/tbooster ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ require 'tbooster'
3
+
4
+ if !Tbooster.runned_from_rails_root?
5
+ puts "must be in rails root"
6
+ exit
7
+ end
8
+
9
+ if ARGV && ARGV[0] == "reload"
10
+ Tbooster.reload
11
+ exit
12
+ end
13
+
14
+ if ARGV && ARGV[0] == "exit"
15
+ puts "tbooster shutting down"
16
+ Tbooster.close_all_and_cleanup
17
+ exit
18
+ end
19
+
20
+ if !Tbooster.listeners_loaded?
21
+ Tbooster.close_all_and_cleanup
22
+ Tbooster.send(ARGV)
23
+ Tbooster.start_listeners #listener needs the pipe which is created by the send command
24
+ else
25
+ Tbooster.send(ARGV)
26
+ end
27
+
@@ -0,0 +1,30 @@
1
+ class Command
2
+ attr_accessor :file, :args
3
+
4
+ def self.get(arg)
5
+ args = arg.gsub("\n","").split(' ')
6
+
7
+ if args.length < 2
8
+ return InvalidCommand.new
9
+ end
10
+
11
+ cmd = args[0]
12
+ file = args[1]
13
+
14
+ case cmd
15
+ when 'reload_file'
16
+ return ReloadFileCommand.new(file)
17
+ when 'run'
18
+ return TestRunnerCommand.new(file, args[1..-1] || [])
19
+ end
20
+
21
+
22
+ return Command.new
23
+ end
24
+
25
+ def run
26
+ puts "unknown command"
27
+ end
28
+
29
+ end
30
+
@@ -0,0 +1,5 @@
1
+ class InvalidCommand < Command
2
+ def run
3
+ puts "invalid command"
4
+ end
5
+ end
@@ -0,0 +1,40 @@
1
+ class ReloadFileCommand < Command
2
+ @@to_reload = {}
3
+ def to_reload
4
+ @@to_reload
5
+ end
6
+
7
+ def initialize(file)
8
+ self.file = file
9
+ end
10
+
11
+ def run
12
+ return if !ReloadFileCommand.is_reloadable_file(file)
13
+
14
+ if to_reload[file] == nil
15
+ reload
16
+ else
17
+ last_reload_time = Time.now - to_reload[file]
18
+ if last_reload_time > 5 #more than 5 seconds passed since the last file reload
19
+ reload
20
+ end
21
+ end
22
+ end
23
+
24
+ def reload
25
+ #ActiveRecord::Base.establish_connection ENV['RAILS_ENV']
26
+ to_reload[file] = Time.now
27
+ puts "change detected for: #{file}"
28
+ load file
29
+ end
30
+
31
+ def self.is_reloadable_file(file)
32
+ return true if (file =~ watchable_file)
33
+ return false
34
+ end
35
+
36
+ def self.watchable_file
37
+ /((app\/(models|controllers|helpers))|lib)\/(.*)\.rb$/
38
+ end
39
+ end
40
+
@@ -0,0 +1,29 @@
1
+ class TestRunnerCommand < Command
2
+ def initialize(file, args)
3
+ self.file = file
4
+ self.args = args
5
+ end
6
+
7
+ def run
8
+ if !is_test_file
9
+ puts "this is not a test file"
10
+ return
11
+ end
12
+
13
+ test_start = Time.now
14
+
15
+ fork do
16
+ ActiveRecord::Base.establish_connection ENV['RAILS_ENV']
17
+
18
+ puts "running: #{file}"
19
+ ARGV.replace(args)
20
+ require(file.gsub(".rb", ""))
21
+
22
+ test_end = Time.now
23
+ end
24
+ end
25
+
26
+ def is_test_file
27
+ file =~ /test\/(.*)\/(.*)_test\.rb$/
28
+ end
29
+ end
data/lib/tbooster.rb CHANGED
@@ -1 +1,119 @@
1
- puts "Tbooster loaded"
1
+ class Tbooster
2
+ #poor mans man check to verify if we're in a rails root
3
+ def self.runned_from_rails_root?
4
+ File.directory?("./app/views") && File.directory?("./app/models") && File.directory?("./app/controllers")
5
+ end
6
+
7
+ def self.pid
8
+ "#{File.expand_path(Dir.pwd)}/tmp/tbooster.pid"
9
+ end
10
+
11
+ def self.pipe
12
+ "#{File.expand_path(Dir.pwd)}/tmp/tbooster_pipe"
13
+ end
14
+
15
+ def self.listeners_loaded?
16
+ if File.exists?(pid) && listener_processes_exist?
17
+ return true
18
+ end
19
+ return false
20
+ end
21
+
22
+ def self.listener_processes_exist?
23
+ listener_pids = (%x( cat #{pid} ) || "").split(" ").map{|pid| pid.to_i}.select{|pid| pid > 0}
24
+ return false if listener_pids.length != 2
25
+
26
+ processes_exist = true
27
+
28
+ listener_pids.each do |pid|
29
+ begin
30
+ Process.kill 0, pid
31
+ rescue Exception => e
32
+ return false
33
+ end
34
+ end
35
+
36
+ processes_exist
37
+ end
38
+
39
+ def self.close_all_and_cleanup
40
+ %x( rm -f #{pipe} ) if File.exists?(pipe)
41
+ if File.exists?(pid)
42
+ kill_opened_processes
43
+ %x( rm -f #{pid} )
44
+ end
45
+ end
46
+
47
+ def self.kill_opened_processes
48
+ %x( kill -9 `cat #{pid}` )
49
+ end
50
+
51
+ def self.start_listeners
52
+ puts "starting listeners"
53
+ command_listener
54
+ file_listener
55
+ end
56
+
57
+ def self.command_listener
58
+ fork do
59
+ puts 'starting testing environment'
60
+ require 'test/test_helper'
61
+ puts 'loaded testing environment'
62
+ File.open(pid, "a") { |f| f<<" #{Process.pid}" }
63
+ input = File.open(pipe, "r+")
64
+ while true do
65
+ cmd = Command.get(input.gets)
66
+
67
+ begin
68
+ cmd.run
69
+ rescue Exception => e
70
+ puts "Message: #{e.message}"
71
+ puts "Stack: #{e.backtrace}"
72
+ end
73
+ end
74
+
75
+ puts "closed command listener process"
76
+ end
77
+ end
78
+
79
+ def self.file_listener
80
+ fork do
81
+ File.open(pid, "a") { |f| f<< " #{Process.pid}" }
82
+
83
+ require 'rubygems'
84
+ require 'listen'
85
+ output = open(pipe, "w+")
86
+
87
+ Listen.to('./', :filter => ReloadFileCommand.watchable_file) do |modified, added, removed|
88
+ output.puts "reload_file #{modified || added}"
89
+ output.flush
90
+ end
91
+
92
+ puts "closed watcher"
93
+
94
+ end
95
+ end
96
+
97
+ def self.send(args)
98
+ unless File.exist?(pipe)
99
+ %x( mkfifo #{pipe} )
100
+ end
101
+
102
+ if args.length > 0
103
+ output = open(pipe, "w+")
104
+ output.puts "run #{args.join(' ')}"
105
+ output.flush
106
+ end
107
+ end
108
+
109
+ def self.reload
110
+ Tbooster.close_all_and_cleanup
111
+ Tbooster.start_listeners
112
+ end
113
+ end
114
+
115
+ require 'tbooster/command'
116
+ require 'tbooster/commands/invalid'
117
+ require 'tbooster/commands/reload_file'
118
+ require 'tbooster/commands/test_runner'
119
+
data/tbooster.gemspec ADDED
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "tbooster"
3
+ s.version = "0.2.0"
4
+ s.date = "2012-12-07"
5
+ s.summary = "Test booster"
6
+ s.description = "Runs unit tests faster by not reloading the testing environment every time"
7
+ s.authors = ["Razvan Dimescu"]
8
+ s.email = 'ssaricu@gmail.com'
9
+ s.homepage = 'http://rubygems.org/gems/tbooster'
10
+
11
+
12
+ s.require_paths = ["lib"]
13
+ s.files = `git ls-files`.split("\n")
14
+ s.executables << 'tbooster'
15
+
16
+ s.add_dependency "listen", ">= 0.6.0"
17
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tbooster
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 2
8
9
  - 0
9
- - 0
10
- version: 0.0.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Razvan Dimescu
@@ -16,18 +16,41 @@ bindir: bin
16
16
  cert_chain: []
17
17
 
18
18
  date: 2012-12-07 00:00:00 Z
19
- dependencies: []
20
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: listen
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 7
29
+ segments:
30
+ - 0
31
+ - 6
32
+ - 0
33
+ version: 0.6.0
34
+ type: :runtime
35
+ version_requirements: *id001
21
36
  description: Runs unit tests faster by not reloading the testing environment every time
22
37
  email: ssaricu@gmail.com
23
- executables: []
24
-
38
+ executables:
39
+ - tbooster
25
40
  extensions: []
26
41
 
27
42
  extra_rdoc_files: []
28
43
 
29
44
  files:
45
+ - .gitignore
46
+ - README.md
47
+ - bin/tbooster
30
48
  - lib/tbooster.rb
49
+ - lib/tbooster/command.rb
50
+ - lib/tbooster/commands/invalid.rb
51
+ - lib/tbooster/commands/reload_file.rb
52
+ - lib/tbooster/commands/test_runner.rb
53
+ - tbooster.gemspec
31
54
  homepage: http://rubygems.org/gems/tbooster
32
55
  licenses: []
33
56