tconsole 1.2.7 → 1.2.8

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.
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  .rvmrc
6
+ .rspec
data/Gemfile CHANGED
@@ -4,4 +4,4 @@ source "http://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  gem "rake"
7
- gem "nutrasuite"
7
+ gem "rspec"
data/Rakefile CHANGED
@@ -1,10 +1 @@
1
1
  require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- task :default => [:test]
5
-
6
- Rake::TestTask.new do |t|
7
- t.libs << "test"
8
- t.test_files = FileList['test/unit/**/*_test.rb']
9
- t.verbose = true
10
- end
@@ -2,4 +2,4 @@
2
2
 
3
3
  require File.join(File.dirname(__FILE__), "..", "lib", "tconsole")
4
4
 
5
- TConsole::Runner.run(ARGV)
5
+ TConsole::Runner.new(ARGV).run
@@ -1,104 +1,19 @@
1
1
  require "tconsole/version"
2
- require "tconsole/config"
3
- require "tconsole/console"
4
- require "tconsole/server"
5
- require "tconsole/pipe_server"
6
- require "tconsole/test_result"
7
- require "tconsole/util"
8
2
 
3
+ require "chattyproc"
9
4
  require "optparse"
10
5
  require "readline"
11
6
  require "benchmark"
12
- require "drb/drb"
13
7
  require "term/ansicolor"
14
8
  require "shellwords"
15
9
 
16
- module TConsole
17
- class Runner
18
-
19
- # Spawns a new environment. Looks at the results of the environment to determine whether to stop or
20
- # keep running
21
- def self.run(argv)
22
- stty_save = `stty -g`.chomp
23
-
24
- running = true
25
- trap("SIGINT", "IGNORE")
26
- trap("SIGTSTP", "IGNORE")
27
-
28
- # A little welcome
29
- puts
30
- puts "Welcome to tconsole (v#{TConsole::VERSION}). Type 'help' for help or 'exit' to quit."
31
-
32
- # set up the config
33
- Config.load_config(File.join(Dir.home, ".tconsole"))
34
- Config.load_config(File.join(Dir.pwd, ".tconsole"))
35
- config = Config.configure(argv)
36
-
37
- config_errors = config.validation_errors
38
- if config_errors.length > 0
39
- puts
40
- puts config_errors.first
41
- exit(1)
42
- end
43
-
44
- # Set up our console input handling and history
45
- console = Console.new(config)
46
-
47
- # Start the server
48
- while running
49
- # ignore ctrl-c during load, since things can get kind of messy if we don't
50
-
51
- pipe_server = PipeServer.new
52
-
53
- config.trace("Forking test server.")
54
- server_pid = fork do
55
- pipe_server.callee!
56
-
57
- server = Server.new(config)
58
-
59
- while message = pipe_server.read
60
- config.trace("Server Received Message: #{message[:action]}")
61
- begin
62
- result = server.handle(message)
63
- pipe_server.write(result)
64
- rescue => e
65
- puts
66
- puts "An error occured: #{e.message}"
67
- config.trace("===========")
68
- config.trace(e.backtrace.join("\n"))
69
- config.trace("===========")
70
- pipe_server.write(nil)
71
- end
72
- end
73
- end
74
-
75
- pipe_server.caller!
76
-
77
- wait_until = Time.now + 10
78
-
79
- config.trace("Attempting to load environment.")
80
- pipe_server.write({:action => "load_environment"})
81
-
82
- unless pipe_server.read
83
- puts "Couldn't load the test environment. Exiting."
84
- exit(1)
85
- end
86
- config.trace("Environment loaded successfully.")
87
-
88
- console.pipe_server = pipe_server
89
- running = console.read_and_execute
90
- console.pipe_server = nil
91
-
92
- Process.waitall
93
- end
94
-
95
- console.store_history
10
+ require "tconsole/config"
11
+ require "tconsole/reporter"
12
+ require "tconsole/console"
13
+ require "tconsole/server"
14
+ require "tconsole/test_result"
15
+ require "tconsole/util"
16
+ require "tconsole/runner"
96
17
 
97
- puts
98
- puts "Exiting. Bye!"
99
- system("stty", stty_save);
100
- end
101
- end
102
- end
103
18
 
104
19
 
@@ -37,9 +37,9 @@ module TConsole
37
37
  # Only runs the command passed on the command line, and then exits
38
38
  attr_accessor :once
39
39
 
40
- def initialize(argv)
40
+ def initialize(argv = [])
41
41
  self.trace_execution = false
42
- self.test_dir = "./test"
42
+ self.test_dir = "test"
43
43
  self.include_paths = ["./test", "./lib"]
44
44
  self.preload_paths = []
45
45
  self.fail_fast = false
@@ -172,7 +172,6 @@ module TConsole
172
172
  "integration" => ["#{config.test_dir}/integration/**/*_test.rb"]
173
173
  }
174
174
 
175
-
176
175
  config.before_load do
177
176
  ENV["RAILS_ENV"] ||= "test"
178
177
  end
@@ -205,10 +204,5 @@ module TConsole
205
204
  def self.is_rails?
206
205
  @rails ||= !!File.exist?("./config/application.rb")
207
206
  end
208
-
209
- # Outputs trace message if our config allows it
210
- def trace(message)
211
- puts "[tconsole trace] #{message}" if trace?
212
- end
213
207
  end
214
208
  end
@@ -2,16 +2,15 @@ module TConsole
2
2
  class Console
3
3
  KNOWN_COMMANDS = ["exit", "reload", "help", "info", "!failed", "!timings", "set"]
4
4
 
5
- attr_accessor :pipe_server
5
+ attr_accessor :config, :reporter
6
6
 
7
- def initialize(config)
8
- @config = config
7
+ def initialize(config, reporter)
8
+ self.config = config
9
+ self.reporter = reporter
9
10
  read_history
10
-
11
- define_autocomplete
12
11
  end
13
12
 
14
- def define_autocomplete
13
+ def define_autocomplete(pipe_server)
15
14
  Readline.completion_append_character = ""
16
15
 
17
16
  # Proc for helping us figure out autocompletes
@@ -21,7 +20,7 @@ module TConsole
21
20
 
22
21
  known_elements = []
23
22
  unless pipe_server.nil?
24
- known_elements = send_message(:autocomplete, str)
23
+ known_elements = send_message(pipe_server, :autocomplete, str)
25
24
  end
26
25
 
27
26
  known_commands.concat(known_elements)
@@ -29,12 +28,7 @@ module TConsole
29
28
  end
30
29
 
31
30
  # Returns true if the app should keep running, false otherwise
32
- def read_and_execute
33
- if pipe_server.nil?
34
- puts "No connection to test environment. Exiting."
35
- return false
36
- end
37
-
31
+ def read_and_execute(pipe_server)
38
32
  prompt = "tconsole> "
39
33
 
40
34
  trap("SIGTSTP", "SYSTEM_DEFAULT")
@@ -43,7 +37,7 @@ module TConsole
43
37
  end
44
38
 
45
39
  # Run any commands that have been passed
46
- result = process_command(@config.run_command)
40
+ result = process_command(pipe_server, @config.run_command)
47
41
  @config.run_command = ""
48
42
  if result == :exit || @config.once
49
43
  return false
@@ -51,10 +45,12 @@ module TConsole
51
45
  return true
52
46
  end
53
47
 
48
+ define_autocomplete(pipe_server)
49
+
54
50
  # The command entry loop
55
51
  while command = Readline.readline(prompt, false)
56
52
  command.strip!
57
- result = process_command(command)
53
+ result = process_command(pipe_server, command)
58
54
 
59
55
  if result == :exit
60
56
  return false
@@ -69,8 +65,9 @@ module TConsole
69
65
 
70
66
  # Public: Process a command however it needs to be handled.
71
67
  #
68
+ # pipe_server - The pipe server we're working with
72
69
  # command - The command we need to parse and handle
73
- def process_command(command)
70
+ def process_command(pipe_server, command)
74
71
  args = Shellwords.shellwords(command)
75
72
 
76
73
  # save the command unless we're exiting or repeating the last command
@@ -81,80 +78,49 @@ module TConsole
81
78
  if command == ""
82
79
  # do nothing
83
80
  elsif args[0] == "exit"
84
- send_message(:stop)
85
- self.pipe_server = nil
81
+ send_message(pipe_server, :stop)
86
82
  return :exit
87
83
  elsif args[0] == "reload"
88
- send_message(:stop)
84
+ send_message(pipe_server, :stop)
89
85
  return :reload
90
86
  elsif args[0] == "help"
91
- print_help
87
+ reporter.help_message
92
88
  elsif args[0] == "!failed"
93
- send_message(:run_failed)
89
+ send_message(pipe_server, :run_failed)
94
90
  elsif args[0] == "!timings"
95
- send_message(:show_performance, args[1])
91
+ send_message(pipe_server, :show_performance, args[1])
96
92
  elsif args[0] == "info"
97
- send_message(:run_info)
93
+ send_message(pipe_server, :run_info)
98
94
  elsif args[0] == "set"
99
- send_message(:set, args[1], args[2])
95
+ send_message(pipe_server, :set, args[1], args[2])
100
96
  elsif args[0].start_with?(".")
101
- send_message(:shell, command[1, command.length - 1])
97
+ shell_command(command[1, command.length - 1])
102
98
  elsif @config.file_sets.has_key?(args[0])
103
- send_message(:run_file_set, args[0])
99
+ send_message(pipe_server, :run_file_set, args[0])
104
100
  else
105
- send_message(:run_all_tests, args)
101
+ send_message(pipe_server, :run_all_tests, args)
106
102
  end
107
103
 
108
104
  nil
109
105
  end
110
106
 
111
- def send_message(message, *args)
107
+ def send_message(pipe_server, message, *args)
112
108
  pipe_server.write({:action => message.to_sym, :args => args})
113
109
  pipe_server.read
114
110
  end
115
111
 
116
- # Prints a list of available commands
117
- def print_help
118
- puts
119
- puts "Available commands:"
120
- puts
121
- puts "reload # Reload your Rails environment"
122
- puts "set [variable] [value] # Sets a runtime variable (see below for details)"
123
- puts "exit # Exit the console"
124
- puts "!failed # Runs the last set of failing tests"
125
- puts "!timings [limit] # Lists the timings for the last test run, sorted."
126
- puts "[filename] [test_pattern] # Run the tests contained in the given file"
127
- puts ".[command] # Executes the given command in a subshell"
128
- puts
129
- puts "Running file sets"
130
- puts
131
- puts "File sets are sets of files that are typically run together. For example,"
132
- puts "in Rails projects it's common to run `rake test:units` to run all of the"
133
- puts "tests under the units directory."
134
- puts
135
- puts "Available file sets:"
136
-
137
- @config.file_sets.each do |set, paths|
138
- puts set
139
- end
112
+ # Internal: Runs a shell command on the console and outputs the results.
113
+ def shell_command(command)
114
+ system(command)
140
115
 
141
- puts
142
- puts "Working with test patterns:"
143
- puts
144
- puts "All of the test execution commands include an optional test_pattern argument. A"
145
- puts "test pattern can be given to filter the executed tests to only those tests whose"
146
- puts "name matches the pattern given. This is especially useful when rerunning a failing"
147
- puts "test."
148
- puts
149
- puts "Runtime Variables"
150
- puts
151
- puts "You can set runtime variables with the set command. This helps out with changing"
152
- puts "features of TConsole that you may want to change at runtime. At present, the"
153
- puts "following runtime variables are available:"
154
- puts
155
- puts "fast # Turns on fail fast mode. Values: on, off"
156
- puts
116
+ result = $?
157
117
 
118
+ reporter.info
119
+ if result.exitstatus == 0
120
+ reporter.exclaim("Command exited with status code: 0")
121
+ else
122
+ reporter.error("Command exited with status code: #{result.exitstatus}")
123
+ end
158
124
  end
159
125
 
160
126
  def history_file
@@ -0,0 +1,113 @@
1
+ # Manages all output for TConsole
2
+ module TConsole
3
+ class Reporter
4
+ attr_accessor :config
5
+
6
+ def initialize(config)
7
+ self.config = config
8
+ end
9
+
10
+ # Public: Ouptuts an informative message.
11
+ def info(message = "")
12
+ puts message
13
+ end
14
+
15
+ # Public: Outputs a positive informative message.
16
+ # Colors it green if the console supports it.
17
+ def exclaim(message = "")
18
+ puts ::Term::ANSIColor.green(message)
19
+ end
20
+
21
+ # Public: Outputs a warning message.
22
+ def warn(message = "")
23
+ puts ::Term::ANSIColor.yellow(message)
24
+ end
25
+
26
+ # Public: Outputs an error message.
27
+ def error(message = "")
28
+ puts ::Term::ANSIColor.red(message)
29
+ end
30
+
31
+
32
+ # Public: Outputs a trace message, when needed.
33
+ def trace(message = "")
34
+ puts "[tconsole trace] #{message}" if config.trace?
35
+ end
36
+
37
+ # Public: Prints a backtrace out.
38
+ def trace_backtrace(exception)
39
+ trace("===========")
40
+ trace(exception.backtrace.join("\n"))
41
+ trace("===========")
42
+ end
43
+
44
+ # Public: Outputs a timing for the timings command, using the proper
45
+ # color logic
46
+ def timing(timing, test_id)
47
+ output = "#{"%0.6f" % timing[:time]}s #{timing[:name]}"
48
+ if timing[:time] > 1
49
+ print ::Term::ANSIColor.red, output, ::Term::ANSIColor.reset
50
+ else
51
+ print ::Term::ANSIColor.green, output, ::Term::ANSIColor.reset
52
+ end
53
+
54
+ print ::Term::ANSIColor.magenta, " #{last_result}", ::Term::ANSIColor.reset, "\n"
55
+ end
56
+
57
+ # Public: Prints a list of available commands
58
+ def help_message
59
+ puts
60
+ puts "Available commands:"
61
+ puts
62
+ puts "reload # Reload your Rails environment"
63
+ puts "set [variable] [value] # Sets a runtime variable (see below for details)"
64
+ puts "exit # Exit the console"
65
+ puts "!failed # Runs the last set of failing tests"
66
+ puts "!timings [limit] # Lists the timings for the last test run, sorted."
67
+ puts "[filename] [test_pattern] # Run the tests contained in the given file"
68
+ puts ".[command] # Executes the given command in a subshell"
69
+ puts
70
+ puts "Running file sets"
71
+ puts
72
+ puts "File sets are sets of files that are typically run together. For example,"
73
+ puts "in Rails projects it's common to run `rake test:units` to run all of the"
74
+ puts "tests under the units directory."
75
+ puts
76
+ puts "Available file sets:"
77
+
78
+ config.file_sets.each do |set, paths|
79
+ puts set
80
+ end
81
+
82
+ puts
83
+ puts "Working with test patterns:"
84
+ puts
85
+ puts "All of the test execution commands include an optional test_pattern argument. A"
86
+ puts "test pattern can be given to filter the executed tests to only those tests whose"
87
+ puts "name matches the pattern given. This is especially useful when rerunning a failing"
88
+ puts "test."
89
+ puts
90
+ puts "Runtime Variables"
91
+ puts
92
+ puts "You can set runtime variables with the set command. This helps out with changing"
93
+ puts "features of TConsole that you may want to change at runtime. At present, the"
94
+ puts "following runtime variables are available:"
95
+ puts
96
+ puts "fast # Turns on fail fast mode. Values: on, off"
97
+ puts
98
+
99
+ end
100
+
101
+ # Public: Outputs the tconsole welcome message
102
+ def welcome_message
103
+ info
104
+ info("Welcome to tconsole (v#{TConsole::VERSION}). Type 'help' for help or 'exit' to quit.")
105
+ end
106
+
107
+ # Public: Outputs the tconsole exit message
108
+ def exit_message
109
+ info
110
+ info("Exiting. Bye!")
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,127 @@
1
+ module TConsole
2
+ class Runner
3
+
4
+ attr_accessor :config, :reporter, :console, :stty_save
5
+
6
+ # Public: Sets up the new runner's config.
7
+ def initialize(argv = [])
8
+ # try to load the default configs
9
+ Config.load_config(File.join(Dir.home, ".tconsole"))
10
+ Config.load_config(File.join(Dir.pwd, ".tconsole"))
11
+ self.config = Config.configure(argv)
12
+ self.reporter = Reporter.new(config)
13
+ end
14
+
15
+ # Spawns a new environment. Looks at the results of the environment to determine whether to stop or
16
+ # keep running
17
+ def run
18
+ prepare_process
19
+ reporter.welcome_message
20
+ exit(1) if print_config_errors
21
+
22
+ # Set up our console input handling and history
23
+ console = Console.new(config, reporter)
24
+
25
+ # Start the server
26
+ while console_run_loop(console)
27
+ # just need to run the loop
28
+ end
29
+
30
+ console.store_history
31
+
32
+ cleanup_process
33
+ end
34
+
35
+ # Internal: Set up the process and console.
36
+ def prepare_process
37
+ self.stty_save = `stty -g`.chomp
38
+
39
+ trap("SIGINT", "IGNORE")
40
+ trap("SIGTSTP", "IGNORE")
41
+ end
42
+
43
+ # Internal: Cleans up the process at the end of execution.
44
+ def cleanup_process
45
+ reporter.exit_message
46
+ system("stty", self.stty_save);
47
+ end
48
+
49
+ # Internal: Prints config errors, if there are any.
50
+ #
51
+ # Returns true if there were errors, false otherwise.
52
+ def print_config_errors
53
+ config_errors = @config.validation_errors
54
+ if config_errors.length > 0
55
+ reporter.error
56
+ reporter.error(config_errors.first)
57
+ true
58
+ else
59
+ false
60
+ end
61
+ end
62
+
63
+ # Internal: Environment reload run loop.
64
+ #
65
+ # This run loop handles spawning a new tconsole environment - it's basically
66
+ # just there to handle reloads. Also calls out to the input loop for the
67
+ # console.
68
+ #
69
+ # Returns false if tconsole needs to stop, true otherwise.
70
+ def console_run_loop(console)
71
+ pipe_server = ChattyProc::PipeServer.new
72
+
73
+ reporter.trace("Forking test server.")
74
+ server_pid = fork do
75
+ server_run_loop(pipe_server)
76
+ end
77
+
78
+ pipe_server.caller!
79
+ unless load_environment(pipe_server)
80
+ pipe_server.write({:action => "exit"})
81
+ return false
82
+ end
83
+
84
+ continue = console.read_and_execute(pipe_server)
85
+ reporter.trace("Console read loop returned - continue: #{continue}")
86
+
87
+ Process.waitall
88
+
89
+ continue
90
+ end
91
+
92
+ # Internal: Asks the server to load the environment.
93
+ #
94
+ # Returns true if the environment was loaded, or false otherwise.
95
+ def load_environment(pipe_server)
96
+ reporter.trace("Attempting to load environment.")
97
+ pipe_server.write({:action => "load_environment"})
98
+
99
+ if pipe_server.read
100
+ reporter.trace("Environment loaded successfully.")
101
+ true
102
+ else
103
+ reporter.error("Couldn't load the test environment. Exiting.")
104
+ false
105
+ end
106
+ end
107
+
108
+ # Internal: Run loop for the server.
109
+ def server_run_loop(pipe_server)
110
+ pipe_server.callee!
111
+ server = Server.new(config, reporter)
112
+
113
+ while message = pipe_server.read
114
+ reporter.trace("Server Received Message: #{message[:action]}")
115
+ begin
116
+ result = server.handle(message)
117
+ pipe_server.write(result)
118
+ rescue => e
119
+ reporter.error
120
+ reporter.error("An error occured: #{e.message}")
121
+ reporter.trace_backtrace(e)
122
+ pipe_server.write(nil)
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -1,9 +1,10 @@
1
1
  module TConsole
2
2
  class Server
3
- attr_accessor :config, :last_result
3
+ attr_accessor :config, :reporter, :last_result
4
4
 
5
- def initialize(config)
5
+ def initialize(config, reporter)
6
6
  self.config = config
7
+ self.reporter = reporter
7
8
  self.last_result = TConsole::TestResult.new
8
9
  end
9
10
 
@@ -23,8 +24,8 @@ module TConsole
23
24
  result = false
24
25
 
25
26
  time = Benchmark.realtime do
26
- puts
27
- puts "Loading environment..."
27
+ reporter.info
28
+ reporter.info("Loading environment...")
28
29
 
29
30
  begin
30
31
  # Append our include paths
@@ -43,20 +44,16 @@ module TConsole
43
44
 
44
45
  result = true
45
46
  rescue Exception => e
46
- puts "Error - Loading your environment failed: #{e.message}"
47
- if config.trace?
48
- puts
49
- puts " #{e.backtrace.join("\n ")}"
50
- end
51
-
47
+ reporter.error("Error - Loading your environment failed: #{e.message}")
48
+ reporter.trace_backtrace(e)
52
49
  return false
53
50
  end
54
51
 
55
52
  preload_test_ids
56
53
  end
57
54
 
58
- puts "Environment loaded in #{"%0.6f" % time}s."
59
- puts
55
+ reporter.info("Environment loaded in #{"%0.6f" % time}s.")
56
+ reporter.info
60
57
 
61
58
  result
62
59
  end
@@ -86,11 +83,11 @@ module TConsole
86
83
  Process.wait(pid)
87
84
 
88
85
  begin
89
- config.trace("Reading result from fork.")
86
+ reporter.trace("Reading result from fork.")
90
87
  Marshal.load(response.unpack("m")[0])
91
88
  rescue => e
92
- config.trace("Problem reading result from fork. Returning nil.")
93
- config.trace(e.message)
89
+ reporter.trace("Problem reading result from fork. Returning nil.")
90
+ reporter.trace(e.message)
94
91
  nil
95
92
  end
96
93
  end
@@ -99,8 +96,8 @@ module TConsole
99
96
  # with class names, method names, and test ids using match_patterns.
100
97
  def run_tests(globs, match_patterns, message = "Running tests...")
101
98
  time = Benchmark.realtime do
102
- puts message
103
- puts
99
+ reporter.info(message)
100
+ reporter.info
104
101
 
105
102
  paths = []
106
103
  globs.each do |glob|
@@ -108,34 +105,34 @@ module TConsole
108
105
  end
109
106
 
110
107
  if paths.length == 0
111
- puts ::Term::ANSIColor.yellow("No test files match your requested test set: #{globs.join(",")}.")
112
- puts ::Term::ANSIColor.yellow("Skipping execution.")
108
+ reporter.warn("No test files match your requested test set: #{globs.join(",")}.")
109
+ reporter.warn("Skipping execution.")
113
110
  return nil
114
111
  end
115
112
 
116
113
  self.last_result = run_in_fork do
117
114
 
118
115
  paths.each do |path|
119
- config.trace("Requested path `#{path}` doesn't exist.") unless File.exist?(path)
116
+ reporter.trace("Requested path `#{path}` doesn't exist.") unless File.exist?(path)
120
117
  require File.expand_path(path)
121
118
  end
122
119
 
123
- config.trace("Running before_test_run callback")
120
+ reporter.trace("Running before_test_run callback")
124
121
  config.before_test_run!
125
- config.trace("Completed before_test_run callback")
122
+ reporter.trace("Completed before_test_run callback")
126
123
 
127
124
  result = nil
128
125
  if defined?(::MiniTest)
129
- config.trace("Detected minitest.")
126
+ reporter.trace("Detected minitest.")
130
127
  require File.join(File.dirname(__FILE__), "minitest_handler")
131
128
 
132
- config.trace("Running tests.")
129
+ reporter.trace("Running tests.")
133
130
  runner = MiniTestHandler.setup(match_patterns, config)
134
131
 
135
132
  # Handle trapping interrupts
136
133
  trap("SIGINT") do
137
- puts
138
- puts "Trapped interrupt. Halting tests."
134
+ reporter.warn
135
+ reporter.warn("Trapped interrupt. Halting tests.")
139
136
 
140
137
  runner.interrupted = true
141
138
  end
@@ -147,16 +144,16 @@ module TConsole
147
144
  # Make sure minitest doesn't run automatically
148
145
  MiniTestHandler.patch_minitest
149
146
 
150
- config.trace("Finished running tests.")
147
+ reporter.trace("Finished running tests.")
151
148
 
152
149
  if runner.interrupted
153
- puts ::Term::ANSIColor.red("Test run was interrupted.")
150
+ reporter.error("Test run was interrupted.")
154
151
  end
155
152
 
156
153
  elsif defined?(::Test::Unit)
157
- puts "Sorry, but tconsole doesn't support Test::Unit yet"
154
+ reporter.error("Sorry, but tconsole doesn't support Test::Unit yet")
158
155
  elsif defined?(::RSpec)
159
- puts "Sorry, but tconsole doesn't support RSpec yet"
156
+ reporter.error("Sorry, but tconsole doesn't support RSpec yet")
160
157
  end
161
158
 
162
159
  result
@@ -172,9 +169,9 @@ module TConsole
172
169
  true
173
170
  end
174
171
 
175
- puts
176
- puts "Tests ran in #{"%0.6f" % time}s. Finished at #{Time.now.strftime('%Y-%m-%d %l:%M:%S %p')}."
177
- puts
172
+ reporter.info
173
+ reporter.info("Tests ran in #{"%0.6f" % time}s. Finished at #{Time.now.strftime('%Y-%m-%d %l:%M:%S %p')}.")
174
+ reporter.info
178
175
  end
179
176
 
180
177
  # Preloads our autocomplete cache
@@ -206,18 +203,18 @@ module TConsole
206
203
 
207
204
  def run_failed
208
205
  if last_result.failures.empty?
209
- puts "No tests failed in your last run, or you haven't run any tests in this session yet."
210
- puts
206
+ reporter.info("No tests failed in your last run, or you haven't run any tests in this session yet.")
207
+ reporter.info
211
208
  else
212
209
  run_tests(config.file_sets["all"], last_result.failures)
213
210
  end
214
211
  end
215
212
 
216
213
  def run_info
217
- puts "Defined Constants:"
218
- puts Module.constants.sort.join("\n")
219
- puts
220
- puts
214
+ reporter.info("Defined Constants:")
215
+ reporter.info(Module.constants.sort.join("\n"))
216
+ reporter.info
217
+ reporter.info
221
218
  end
222
219
 
223
220
  def show_performance(limit = nil)
@@ -227,26 +224,19 @@ module TConsole
227
224
 
228
225
  sorted_timings = last_result.timings.sort_by { |timing| timing[:time] }
229
226
 
230
- puts
231
- puts "Timings from last run:"
232
- puts
227
+ reporter.info
228
+ reporter.info("Timings from last run:")
229
+ reporter.info
233
230
 
234
231
  if sorted_timings.length == 0
235
- puts ::Term::ANSIColor.red + "No timing data available. Be sure you've run some tests." + ::Term::ANSIColor.reset
232
+ reporter.error("No timing data available. Be sure you've run some tests.")
236
233
  else
237
234
  sorted_timings.reverse[0, limit].each do |timing|
238
- output = "#{"%0.6f" % timing[:time]}s #{timing[:name]}"
239
- if timing[:time] > 1
240
- print ::Term::ANSIColor.red, output, ::Term::ANSIColor.reset
241
- else
242
- print ::Term::ANSIColor.green, output, ::Term::ANSIColor.reset
243
- end
244
-
245
- print ::Term::ANSIColor.magenta, " #{last_result.elements[timing[:name]]}", ::Term::ANSIColor.reset, "\n"
235
+ reporter.timing(timing, last_result.elements[timing[:name]])
246
236
  end
247
237
  end
248
238
 
249
- puts
239
+ reporter.info
250
240
  end
251
241
 
252
242
  def set(key, value)
@@ -259,35 +249,16 @@ module TConsole
259
249
  config.fail_fast = false
260
250
  end
261
251
 
262
- puts ::Term::ANSIColor.green + "Fail Fast is now #{config.fail_fast ? "on" : "off"}" + ::Term::ANSIColor.reset
263
- puts
252
+ reporter.exclaim("Fail Fast is now #{config.fail_fast ? "on" : "off"}")
253
+ reporter.exclaim
264
254
  else
265
- puts ::Term::ANSIColor.green + "Fail fast is currently #{config.fail_fast ? "on" : "off"}" + ::Term::ANSIColor.reset
266
- puts
255
+ reporter.exclaim("Fail fast is currently #{config.fail_fast ? "on" : "off"}")
256
+ reporter.exclaim
267
257
  end
268
258
  else
269
- puts ::Term::ANSIColor.yellow + "I don't know how to set `#{key}`." + ::Term::ANSIColor.reset + " Usage: set {key} {value}"
270
- puts
271
- end
272
- end
273
-
274
- # Internal: Runs the given command in the shell.
275
- #
276
- # command - the command to execute
277
- #
278
- # Examples
279
- #
280
- # shell("ls -la")
281
- def shell(command)
282
- system(command)
283
-
284
- result = $?
285
-
286
- puts
287
- if result.exitstatus == 0
288
- puts ::Term::ANSIColor.green + "Command exited with status code: 0" + ::Term::ANSIColor.reset
289
- else
290
- puts ::Term::ANSIColor.red + "Command exited with status code: #{result.exitstatus}" + ::Term::ANSIColor.reset
259
+ reporter.warn("I don't know how to set `#{key}`.")
260
+ reporter.info("Usage: set {key} {value}")
261
+ reporter.warn
291
262
  end
292
263
  end
293
264
  end
@@ -1,3 +1,3 @@
1
1
  module TConsole
2
- VERSION = "1.2.7"
2
+ VERSION = "1.2.8"
3
3
  end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ describe TConsole::Config do
4
+ context "a Config without arguments" do
5
+ before do
6
+ @config = TConsole::Config.new([])
7
+ @config.test_dir = "./spec/fixtures/minitest"
8
+ end
9
+
10
+ context "when configured test directory doesn't exist" do
11
+ before do
12
+ @config.test_dir = "./monkey_business"
13
+ end
14
+
15
+ it "sets a validation error" do
16
+ expect(@config.validation_errors[0]).to eq("Couldn't find test directory `./monkey_business`. Exiting.")
17
+ end
18
+ end
19
+
20
+ context "when the configuration doesn't include an all file set" do
21
+ before do
22
+ @config.file_sets = {}
23
+ end
24
+
25
+ it "sets a validation error" do
26
+ expect(@config.validation_errors[0]).to eq("No `all` file set is defined in your configuration. Exiting.")
27
+ end
28
+ end
29
+ end
30
+
31
+ context "a Config with the trace argument" do
32
+ before do
33
+ @config = TConsole::Config.new(Shellwords.shellwords("--trace"))
34
+ end
35
+
36
+ it "has tracing enabled" do
37
+ expect(@config.trace_execution).to be_true
38
+ end
39
+ end
40
+
41
+ context "a Config with the once argument" do
42
+ before do
43
+ @config = TConsole::Config.new(Shellwords.shellwords("--once all"))
44
+ end
45
+
46
+ it "has run once enabled" do
47
+ expect(@config.once).to be_true
48
+ end
49
+ end
50
+
51
+ context "a Config with remaining arguments" do
52
+ before do
53
+ @config = TConsole::Config.new(Shellwords.shellwords("--trace set fast on"))
54
+ end
55
+
56
+ it "sets remaining args as first command" do
57
+ expect(@config.run_command).to eq("set fast on")
58
+ end
59
+ end
60
+
61
+ describe ".run" do
62
+ before do
63
+ TConsole::Config.run do |config|
64
+ config.test_dir = "./awesome_sauce"
65
+ end
66
+ end
67
+
68
+ after do
69
+ TConsole::Config.clear_loaded_configs
70
+ end
71
+
72
+ it "saves the run proc" do
73
+ loaded_configs = TConsole::Config.instance_variable_get(:@loaded_configs)
74
+ expect(loaded_configs.length).to eq(1)
75
+ end
76
+
77
+ it "runs loaded configs from first to last" do
78
+ TConsole::Config.run do |config|
79
+ config.test_dir = "./awesomer_sauce"
80
+ end
81
+
82
+ config = TConsole::Config.configure
83
+ expect(config.test_dir).to eq("./awesomer_sauce")
84
+ end
85
+ end
86
+
87
+ describe ".load_config" do
88
+ it "loads configs" do
89
+ TConsole::Config.load_config(File.join(File.dirname(__FILE__), "sample_config"))
90
+ loaded_configs = TConsole::Config.instance_variable_get(:@loaded_configs)
91
+ expect(loaded_configs.length).to eq(1)
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,38 @@
1
+ require "spec_helper"
2
+
3
+ describe TConsole::Runner do
4
+ before do
5
+ @runner = TConsole::Runner.new
6
+ @ps = ChattyProc::PipeServer.new
7
+ end
8
+
9
+ describe "#load_environment" do
10
+ before do
11
+ @ps.stub(:write) { }
12
+ end
13
+
14
+ it "returns false if the environment load call fails" do
15
+ @ps.stub(:read) { false }
16
+ expect(@runner.load_environment(@ps)).to be_false
17
+ end
18
+
19
+ it "returns true if the environment load call succeeds" do
20
+ @ps.stub(:read) { true }
21
+ expect(@runner.load_environment(@ps)).to be_true
22
+ end
23
+ end
24
+
25
+ describe "#console_run_loop" do
26
+ before do
27
+ @config = TConsole::Config.new
28
+ @reporter = TConsole::Reporter.new(@config)
29
+ @console = TConsole::Console.new(@config, @reporter)
30
+ end
31
+
32
+ it "returns false when loading the environment fails" do
33
+ @runner.stub(:load_environment) { false }
34
+
35
+ expect(@runner.console_run_loop(@console)).to be_false
36
+ end
37
+ end
38
+ end
File without changes
@@ -1,7 +1,4 @@
1
1
  require "rubygems"
2
2
  require "bundler/setup"
3
3
 
4
- require 'test/unit'
5
- require 'nutrasuite'
6
-
7
4
  require 'tconsole'
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe "TConsole::Util" do
4
+ describe ".filter_backtrace" do
5
+ before do
6
+ @non_tconsole_path = "/Users/alan/Projects/commondream/tconsole-test/test/functional/posts_controller_test.rb:16:in `block in <class:PostsControllerTest>'"
7
+ @tconsole_path = "#{File.expand_path(File.join(File.dirname(__FILE__), ".."))}/posts_controller_test.rb:16:in `block in <class:PostsControllerTest>'"
8
+
9
+ @backtrace = [
10
+ @non_tconsole_path,
11
+ @tconsole_path
12
+ ]
13
+
14
+ @filtered_backtrace = TConsole::Util.filter_backtrace(@backtrace)
15
+ end
16
+
17
+ context "removes tconsole paths" do
18
+ it { expect(@filtered_backtrace.length).to eq(1) }
19
+ it { expect(@filtered_backtrace).to_not include(@tconsole_path) }
20
+ end
21
+
22
+ it "doesn't remove non-tconsole paths" do
23
+ expect(@filtered_backtrace).to include(@non_tconsole_path)
24
+ end
25
+ end
26
+ end
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
 
24
24
  # specify any dependencies here; for example:
25
25
  # s.add_development_dependency "rspec"
26
+ s.add_runtime_dependency "chattyproc", "~> 1.0.0"
26
27
  s.add_runtime_dependency "term-ansicolor", "~> 1.0.7"
27
28
  s.add_runtime_dependency "minitest", "~> 4.3.0"
28
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tconsole
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.7
4
+ version: 1.2.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-16 00:00:00.000000000 Z
12
+ date: 2013-01-21 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: chattyproc
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.0
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: term-ansicolor
16
32
  requirement: !ruby/object:Gem::Requirement
@@ -65,16 +81,18 @@ files:
65
81
  - lib/tconsole/config.rb
66
82
  - lib/tconsole/console.rb
67
83
  - lib/tconsole/minitest_handler.rb
68
- - lib/tconsole/pipe_server.rb
84
+ - lib/tconsole/reporter.rb
85
+ - lib/tconsole/runner.rb
69
86
  - lib/tconsole/server.rb
70
87
  - lib/tconsole/test_result.rb
71
88
  - lib/tconsole/util.rb
72
89
  - lib/tconsole/version.rb
90
+ - spec/config_spec.rb
91
+ - spec/runner_spec.rb
92
+ - spec/sample_config
93
+ - spec/spec_helper.rb
94
+ - spec/util_spec.rb
73
95
  - tconsole.gemspec
74
- - test/test_helper.rb
75
- - test/unit/config_test.rb
76
- - test/unit/sample_config
77
- - test/unit/util_test.rb
78
96
  homepage: ''
79
97
  licenses: []
80
98
  post_install_message:
@@ -100,7 +118,8 @@ signing_key:
100
118
  specification_version: 3
101
119
  summary: tconsole is a helpful console for running Rails tests
102
120
  test_files:
103
- - test/test_helper.rb
104
- - test/unit/config_test.rb
105
- - test/unit/sample_config
106
- - test/unit/util_test.rb
121
+ - spec/config_spec.rb
122
+ - spec/runner_spec.rb
123
+ - spec/sample_config
124
+ - spec/spec_helper.rb
125
+ - spec/util_spec.rb
@@ -1,47 +0,0 @@
1
- module TConsole
2
- class PipeServer
3
-
4
- def initialize
5
- @callee = []
6
- @caller = []
7
- @callee[0], @caller[1] = IO.pipe
8
- @caller[0], @callee[1] = IO.pipe
9
-
10
- @me = nil
11
- end
12
-
13
- # Identifies the current process as the callee process
14
- def callee!
15
- @me = @callee
16
-
17
- @caller.each do |io|
18
- io.close
19
- end
20
- end
21
-
22
- # Identifies the current process as the caller process
23
- def caller!
24
- @me = @caller
25
-
26
- @callee.each do |io|
27
- io.close
28
- end
29
- end
30
-
31
- # Writes a message to the appropriate pipe. The message can be
32
- # anything that will Marshal cleanly
33
- def write(message)
34
- encoded_message = [Marshal.dump(message)].pack("m0")
35
- @me[1].puts(encoded_message)
36
- end
37
-
38
- # Reads a message from the appropriate pipe and unmarshalls it
39
- def read
40
- raw_message = @me[0].gets
41
-
42
- return nil if raw_message.nil?
43
-
44
- Marshal.load(raw_message.unpack("m")[0])
45
- end
46
- end
47
- end
@@ -1,91 +0,0 @@
1
- require 'test_helper'
2
-
3
- module TConsole
4
- class ConfigTest < MiniTest::Unit::TestCase
5
-
6
- a "Config" do
7
- before do
8
- @config = TConsole::Config.new([])
9
- end
10
-
11
- it "should have appropriate defaults" do
12
- assert_equal false, @config.trace_execution
13
- assert_equal "./test", @config.test_dir
14
- assert_equal ["./test", "./lib"], @config.include_paths
15
- assert_equal [], @config.preload_paths
16
- assert_equal false, @config.fail_fast
17
- assert_equal({ "all" => ["./test/**/*_test.rb"] }, @config.file_sets)
18
- end
19
-
20
- it "should have a validation error if the configured test directory doesn't exist" do
21
- @config.test_dir = "./monkey_business"
22
-
23
- errors = @config.validation_errors
24
- refute_nil errors
25
- assert_equal "Couldn't find test directory `./monkey_business`. Exiting.", errors[0]
26
- end
27
-
28
- it "should have a validation error if the configuration doesn't include an all file set" do
29
- @config.file_sets = {}
30
-
31
- errors = @config.validation_errors
32
- refute_nil errors
33
- assert_equal "No `all` file set is defined in your configuration. Exiting.", errors[0]
34
- end
35
- end
36
-
37
- a "Config with command line arguments" do
38
- it "should set up tracing correctly" do
39
- @config = Config.new(Shellwords.shellwords("--trace"))
40
-
41
- assert @config.trace_execution
42
- end
43
-
44
- it "should set up only running the passed command and exiting" do
45
- @config = Config.new(Shellwords.shellwords("--once all"))
46
-
47
- assert @config.once
48
- end
49
-
50
- it "should set all remaining unparsed text to be the first command to run" do
51
- @config = Config.new(Shellwords.shellwords("--trace set fast on"))
52
-
53
- assert_equal "set fast on", @config.run_command
54
- end
55
- end
56
-
57
- the "Config class" do
58
- before do
59
- TConsole::Config.clear_loaded_configs
60
- end
61
-
62
- it "should save the proc passed to run when it's called" do
63
- TConsole::Config.run do |config|
64
- config.test_dir = "./awesome_sauce"
65
- end
66
-
67
- assert_equal 1, TConsole::Config.instance_variable_get(:@loaded_configs).length
68
- end
69
-
70
- it "should apply the loaded configs from first to last when configure is called" do
71
- TConsole::Config.run do |config|
72
- config.test_dir = "./awesome_sauce"
73
- end
74
-
75
- TConsole::Config.run do |config|
76
- config.test_dir = "./awesomer_sauce"
77
- end
78
-
79
- config = TConsole::Config.configure
80
-
81
- assert_equal "./awesomer_sauce", config.test_dir
82
- end
83
-
84
- it "should load a config file when load_config is called" do
85
- TConsole::Config.load_config(File.join(File.dirname(__FILE__), "sample_config"))
86
-
87
- assert_equal 1, TConsole::Config.instance_variable_get(:@loaded_configs).length
88
- end
89
- end
90
- end
91
- end
@@ -1,29 +0,0 @@
1
- require 'test_helper'
2
-
3
- module TConsole
4
- class ConfigTest < MiniTest::Unit::TestCase
5
- a "Backtrace" do
6
- before do
7
- @non_tconsole_path = "/Users/alan/Projects/commondream/tconsole-test/test/functional/posts_controller_test.rb:16:in `block in <class:PostsControllerTest>'"
8
- @tconsole_path = "#{File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))}/posts_controller_test.rb:16:in `block in <class:PostsControllerTest>'"
9
-
10
- @backtrace = [
11
- @non_tconsole_path,
12
- @tconsole_path
13
- ]
14
-
15
- @filtered_backtrace = Util.filter_backtrace(@backtrace)
16
- end
17
-
18
- it "should remove the tconsole path" do
19
- assert_equal 1, @filtered_backtrace.length
20
- assert !@filtered_backtrace.include?(@tconsole_path), "Should filter backtrace item under tconsole"
21
- end
22
-
23
- it "shouldn't remove the non-tconsole path" do
24
- assert @filtered_backtrace.include?(@non_tconsole_path), "Should not filter backtrace item outside of tconsole"
25
- end
26
-
27
- end
28
- end
29
- end