karl-loris 0.0.7 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.gitignore +1 -0
  2. data/README.rdoc +9 -1
  3. data/Rakefile +24 -5
  4. data/TODO +1 -1
  5. data/VERSION +1 -1
  6. data/examples/self_test/jsl.conf +1 -0
  7. data/features/javascript_lint.feature +34 -0
  8. data/features/run.feature +1 -2
  9. data/features/step_definitons/all.rb +8 -0
  10. data/lib/filters/ends_with_filter.rb +17 -0
  11. data/lib/{extension_filter.rb → filters/extension_filter.rb} +0 -0
  12. data/lib/{file_filter.rb → filters/file_filter.rb} +0 -0
  13. data/lib/{modified_filter.rb → filters/modified_filter.rb} +0 -0
  14. data/lib/loris.rb +19 -13
  15. data/lib/tasks/javascript_lint/javascript_lint_runner.rb +21 -0
  16. data/lib/tasks/{javascript_lint_task.rb → javascript_lint/javascript_lint_task.rb} +9 -8
  17. data/lib/tasks/js_test_driver/js_test_driver_runner.rb +22 -0
  18. data/lib/tasks/{js_test_driver_task.rb → js_test_driver/js_test_driver_task.rb} +2 -1
  19. data/lib/tasks/jspec/jspec_runner.rb +21 -0
  20. data/lib/tasks/{jspec_task.rb → jspec/jspec_task.rb} +2 -1
  21. data/lib/tasks/rspec/rspec_runner.rb +21 -0
  22. data/lib/tasks/rspec/rspec_task.rb +50 -0
  23. data/loris.gemspec +37 -24
  24. data/loris.tmproj +74 -44
  25. data/spec/file_finder_spec.rb +3 -3
  26. data/spec/filters/ends_with_filter_spec.rb +26 -0
  27. data/spec/{file_filter_spec.rb → filters/file_filter_spec.rb} +1 -1
  28. data/spec/{modified_filter_spec.rb → filters/modified_filter_spec.rb} +1 -1
  29. data/spec/tasks/javascript_lint/javascript_lint_runner_spec.rb +90 -0
  30. data/spec/tasks/js_test_driver/js_test_driver_runner_spec.rb +91 -0
  31. data/spec/tasks/jspec/jspec_runner_spec.rb +78 -0
  32. data/spec/tasks/jspec/jspec_task_spec.rb +45 -0
  33. metadata +41 -21
  34. data/.autotest +0 -12
  35. data/autotest/discover.rb +0 -3
  36. data/lib/tasks/javascript_lint_runner.rb +0 -15
  37. data/lib/tasks/js_test_driver_runner.rb +0 -16
  38. data/lib/tasks/jspec_runner.rb +0 -15
  39. data/spec/jspec_task_spec.rb +0 -47
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
+ .gitignore
1
2
  .DS_Store
data/README.rdoc CHANGED
@@ -1 +1,9 @@
1
- Work in progress...
1
+ == Autotest for Javascript ==
2
+
3
+ Run your javascript unit tests any time a file in your project changes.
4
+
5
+ Runs Javascript Lint (if jsl.conf is found)
6
+ Runs JSpec (if spec/spec.rhino.js is found)
7
+ Runs JS Test Driver (if jsTestDriver.conf is found)
8
+
9
+ Also runs RSpec (if any file ending in _spec.rb is found in the spec directory)
data/Rakefile CHANGED
@@ -1,21 +1,40 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
+ require 'spec/rake/spectask'
4
+ require 'cucumber'
5
+ require 'cucumber/rake/task'
3
6
 
4
7
  begin
5
8
  require 'jeweler'
6
9
  Jeweler::Tasks.new do |gem|
7
10
  gem.name = "loris"
8
- gem.summary = %Q{TODO: Automatically run javascript tests}
9
- gem.description = %Q{TODO: Automatically run javascript tests}
11
+ gem.summary = 'Automatically run javascript unit tests'
12
+ gem.description = 'Automatically run javascript unit tests'
10
13
  gem.email = "loris@monket.net"
11
14
  gem.homepage = "http://github.com/karl/loris"
12
15
  gem.authors = ["Karl O'Keeffe"]
13
16
 
14
- gem.add_dependency(%q<visionmedia-bind>, [">= 0.2.6"])
15
- gem.add_dependency(%q<karl-growl>, [">= 1.0.3"])
17
+ gem.add_dependency('visionmedia-bind', [">= 0.2.6"])
18
+ gem.add_dependency('karl-growl', [">= 1.0.3"])
19
+ gem.add_dependency('extensions', [">= 0.6.0"])
16
20
 
17
21
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
22
  end
19
23
  rescue LoadError
20
24
  puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
21
- end
25
+ end
26
+
27
+
28
+ task :default => [:spec, :features]
29
+
30
+ Spec::Rake::SpecTask.new(:spec) do |t|
31
+ t.spec_files = Dir.glob('spec/**/*_spec.rb')
32
+ # t.rcov = true
33
+ end
34
+
35
+ Cucumber::Rake::Task.new(:features) do |t|
36
+ t.cucumber_opts = "features --format pretty"
37
+ end
38
+
39
+
40
+
data/TODO CHANGED
@@ -1,3 +1,4 @@
1
+ * Remove JsTestDriver.jar from lib dir
1
2
  * Tidy Windows related if statements
2
3
  * Tidy JSL filename removing
3
4
 
@@ -16,6 +17,5 @@
16
17
  * separate thread (create new and kill old)
17
18
  * listen for interrupt
18
19
  * detect file deletion
19
- * rspec task
20
20
  * cucumber task
21
21
  * Tidy growl windows code
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.7
1
+ 0.0.9
@@ -0,0 +1 @@
1
+ +process tmp/*.js
@@ -0,0 +1,34 @@
1
+ Feature Javascript Lint
2
+
3
+ Scenario: Javascript Lint is run
4
+ Given I run loris --debug
5
+ When I create a file named "example.js" with:
6
+ """
7
+ var foo = function() {
8
+ x = 'moo'
9
+ }
10
+ """
11
+ And I wait until loris has finished processing changes
12
+ Then the Loris output should contain:
13
+ """
14
+ Javascript Lint
15
+ warning
16
+ """
17
+ And I should not see any errors
18
+
19
+ # Scenario: Javascript Lint is run when Loris starts
20
+ # When I create a file named "example.js" with:
21
+ # """
22
+ # var foo = function() {
23
+ # x = 'moo'
24
+ # }
25
+ # """
26
+ # Given I run loris --debug
27
+ # And I wait until loris has finished processing changes
28
+ # Then the Loris output should contain:
29
+ # """
30
+ # Javascript Lint
31
+ # warning
32
+ # """
33
+ # And I should not see any errors
34
+ #
data/features/run.feature CHANGED
@@ -33,5 +33,4 @@ Feature: Run Loris
33
33
  When I create a directory named "dir"
34
34
  And I wait until loris has finished processing changes
35
35
  Then I should NOT see "dir" in the Loris output
36
- And I should not see any errors
37
-
36
+ And I should not see any errors
@@ -52,6 +52,14 @@ Then /^I should see "([^\"]*)" in the Loris output$/ do |text|
52
52
  get_background_output.should include text
53
53
  end
54
54
 
55
+ Then /^the Loris output should contain:$/ do |text|
56
+ get_background_output.should include text
57
+ end
58
+
59
+ Then /^the Loris output should NOT contain:$/ do |text|
60
+ get_background_output.should_not include text
61
+ end
62
+
55
63
  Then /^I should NOT see "([^\"]*)" in the Loris output$/ do |text|
56
64
  get_background_output.should_not include text
57
65
  end
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'extensions/string'
3
+
4
+ class EndsWithFilter
5
+
6
+ def initialize(text)
7
+ @text = text.downcase
8
+ end
9
+
10
+ def filter(file_name)
11
+ return file_name.downcase.ends_with? @text
12
+ end
13
+
14
+ def complete()
15
+ end
16
+
17
+ end
File without changes
data/lib/loris.rb CHANGED
@@ -13,10 +13,12 @@ require 'poller'
13
13
  require 'sleep_waiter'
14
14
  require 'always_continuer'
15
15
  require 'file_actioner'
16
- require 'modified_filter'
17
- require 'file_filter'
18
16
  require 'task_manager'
19
- require 'extension_filter'
17
+
18
+ require 'filters/extension_filter'
19
+ require 'filters/modified_filter'
20
+ require 'filters/file_filter'
21
+ require 'filters/ends_with_filter'
20
22
 
21
23
  require 'outputs/output_collection'
22
24
  require 'outputs/shell_output'
@@ -25,12 +27,14 @@ require 'outputs/unix_console_clearing_output'
25
27
  require 'outputs/growl_output'
26
28
 
27
29
  require 'tasks/list_task'
28
- require 'tasks/jspec_task'
29
- require 'tasks/jspec_runner'
30
- require 'tasks/javascript_lint_task'
31
- require 'tasks/javascript_lint_runner'
32
- require 'tasks/js_test_driver_task'
33
- require 'tasks/js_test_driver_runner'
30
+ require 'tasks/jspec/jspec_task'
31
+ require 'tasks/jspec/jspec_runner'
32
+ require 'tasks/javascript_lint/javascript_lint_task'
33
+ require 'tasks/javascript_lint/javascript_lint_runner'
34
+ require 'tasks/js_test_driver/js_test_driver_task'
35
+ require 'tasks/js_test_driver/js_test_driver_runner'
36
+ require 'tasks/rspec/rspec_task'
37
+ require 'tasks/rspec/rspec_runner'
34
38
 
35
39
 
36
40
  include Config
@@ -87,14 +91,15 @@ module Loris
87
91
 
88
92
  oc = OutputCollection.new()
89
93
  oc.add(ShellOutput.new($stdout))
90
- oc.add(cco)
94
+ oc.add(cco) unless debug
91
95
  oc.add(GrowlOutput.new(Growl)) unless debug
92
96
 
93
97
  tm = TaskManager.new(oc)
94
98
  tm.add(ListTask.new()) if debug
95
- tm.add(JavascriptLintTask.new(JavascriptLintRunner.new(dir), dir))
96
- tm.add(JSpecTask.new(JSpecRunner.new(dir)))
97
- tm.add(JsTestDriverTask.new(JsTestDriverRunner.new(dir, jstd_jar)))
99
+ tm.add(JavascriptLintTask.new(JavascriptLintRunner.new(dir, ExtensionFilter.new(File, 'js')), dir))
100
+ tm.add(JSpecTask.new(JSpecRunner.new(dir, ExtensionFilter.new(File, 'js'))))
101
+ tm.add(JsTestDriverTask.new(JsTestDriverRunner.new(dir, jstd_jar, ExtensionFilter.new(File, 'js'))))
102
+ tm.add(RSpecTask.new(RSpecRunner.new(dir, ExtensionFilter.new(File, 'rb'), EndsWithFilter.new('_spec.rb'))))
98
103
 
99
104
  a = FileActioner.new(ff, tm)
100
105
 
@@ -102,6 +107,7 @@ module Loris
102
107
 
103
108
  p = Poller.new(w, c, debug ? da : a)
104
109
 
110
+ # Start!
105
111
  p.start()
106
112
 
107
113
  end
@@ -0,0 +1,21 @@
1
+ class JavascriptLintRunner
2
+
3
+ def initialize(dir, filter)
4
+ @config = dir + '/jsl.conf'
5
+ @dir = dir
6
+ @filter = filter
7
+ end
8
+
9
+ def execute()
10
+ return `jsl -conf "#{@config}" -nologo -nofilelisting 2>&1`
11
+ end
12
+
13
+ def is_configured?(all_files)
14
+ return all_files.include?(@config)
15
+ end
16
+
17
+ def should_run?(modified_files)
18
+ return !(modified_files.detect { |file| @filter.filter(file) }).nil? || modified_files.include?(@config)
19
+ end
20
+
21
+ end
@@ -3,30 +3,31 @@ class JavascriptLintTask
3
3
  def initialize(javascript_lint, dir)
4
4
  @javascript_lint = javascript_lint
5
5
  @dir = dir
6
-
6
+
7
7
  # TODO: Tidy!
8
8
  if (RUBY_PLATFORM =~ /mswin32/)
9
9
  @dir = @dir.gsub('/', '\\')
10
10
  end
11
-
11
+
12
12
  end
13
13
 
14
14
  def run(files)
15
15
  all_files = files[:all]
16
- mofified_files = files[:filtered]
16
+ modified_files = files[:filtered]
17
17
 
18
- return nil if (!@javascript_lint.is_configured? all_files)
19
-
18
+ return nil if (!@javascript_lint.is_configured? all_files)
19
+ return nil if (!@javascript_lint.should_run? modified_files)
20
+
20
21
  detail = @javascript_lint.execute()
21
22
 
22
23
  state, summary, first = parse_result(detail)
23
-
24
+
24
25
  # TODO: Tidy!
25
26
  # Move to function/class w/ win32 related code
26
27
  if (first[0, @dir.length] == @dir)
27
28
  first = first[(@dir.length + 1)..-1]
28
29
  end
29
-
30
+
30
31
  return {
31
32
  :state => state,
32
33
  :title => 'Javascript Lint',
@@ -51,7 +52,7 @@ class JavascriptLintTask
51
52
  error_info = detail.grep(/\([0-9]+\):([^:]*)Error:/)[0].strip
52
53
  return :failure, num_failures + ' Errors', error_info
53
54
  end
54
-
55
+
55
56
  if summary_line =~ /([1-9]+)\d*\s+warning/
56
57
  num_failures = $1
57
58
  error_info = detail.grep(/\([0-9]+\)/)[0].strip
@@ -0,0 +1,22 @@
1
+ class JsTestDriverRunner
2
+
3
+ def initialize(dir, jar, filter)
4
+ @config = dir + '/jsTestDriver.conf'
5
+ @dir = dir
6
+ @jar = jar
7
+ @filter = filter
8
+ end
9
+
10
+ def execute()
11
+ return `java -jar "#{@jar}" --config "#{@config}" --tests all --verbose 2>&1`
12
+ end
13
+
14
+ def is_configured?(all_files)
15
+ return all_files.include?(@dir + '/jsTestDriver.conf')
16
+ end
17
+
18
+ def should_run?(modified_files)
19
+ return !(modified_files.detect { |file| @filter.filter(file) }).nil? || modified_files.include?(@config)
20
+ end
21
+
22
+ end
@@ -6,9 +6,10 @@ class JsTestDriverTask
6
6
 
7
7
  def run(files)
8
8
  all_files = files[:all]
9
- mofified_files = files[:filtered]
9
+ modified_files = files[:filtered]
10
10
 
11
11
  return nil if (!@js_test_driver.is_configured? all_files)
12
+ return nil if (!@js_test_driver.should_run? modified_files)
12
13
 
13
14
  detail = @js_test_driver.execute()
14
15
 
@@ -0,0 +1,21 @@
1
+ class JSpecRunner
2
+
3
+ def initialize(dir, filter)
4
+ @config = dir + '/spec/spec.rhino.js'
5
+ @dir = dir
6
+ @filter = filter
7
+ end
8
+
9
+ def execute
10
+ return `jspec run --rhino --trace 2>&1`
11
+ end
12
+
13
+ def is_configured?(all_files)
14
+ return all_files.include?(@config)
15
+ end
16
+
17
+ def should_run?(modified_files)
18
+ return !(modified_files.detect { |file| @filter.filter(file) }).nil?
19
+ end
20
+
21
+ end
@@ -6,9 +6,10 @@ class JSpecTask
6
6
 
7
7
  def run(files)
8
8
  all_files = files[:all]
9
- mofified_files = files[:filtered]
9
+ modified_files = files[:filtered]
10
10
 
11
11
  return nil if (!@jspec.is_configured? all_files)
12
+ return nil if (!@jspec.should_run? modified_files)
12
13
 
13
14
  detail = @jspec.execute
14
15
 
@@ -0,0 +1,21 @@
1
+ class RSpecRunner
2
+
3
+ def initialize(dir, ruby_filter, spec_filter)
4
+ @dir = dir
5
+ @ruby_filter = ruby_filter
6
+ @spec_filter = spec_filter
7
+ end
8
+
9
+ def execute()
10
+ return `spec . 2>&1`
11
+ end
12
+
13
+ def is_configured?(all_files)
14
+ return !(all_files.detect { |file| @spec_filter.filter(file) }).nil?
15
+ end
16
+
17
+ def should_run?(modified_files)
18
+ return !(modified_files.detect { |file| @ruby_filter.filter(file) }).nil?
19
+ end
20
+
21
+ end
@@ -0,0 +1,50 @@
1
+ class RSpecTask
2
+
3
+ def initialize(rspec)
4
+ @rspec = rspec
5
+ end
6
+
7
+ def run(files)
8
+ all_files = files[:all]
9
+ modified_files = files[:filtered]
10
+
11
+ return nil if (!@rspec.is_configured? all_files)
12
+ return nil if (!@rspec.should_run? modified_files)
13
+
14
+ detail = @rspec.execute()
15
+
16
+ state, summary, first = parse_result(detail)
17
+
18
+ return {
19
+ :state => state,
20
+ :title => 'RSpec',
21
+ :summary => summary,
22
+ :first => first,
23
+ :detail => detail
24
+ }
25
+ end
26
+
27
+ # Move to parse class
28
+ def parse_result(detail)
29
+ summary_line = detail.grep( /\d+ examples?, \d+ failures?/ )[0]
30
+
31
+ if summary_line.nil?
32
+ # error
33
+ error_info = (detail + "\nUnknown Error!").to_a[0].strip
34
+ return :error, 'Error', error_info
35
+ end
36
+
37
+ if summary_line =~ /([1-9]+) failures?/
38
+ num_errors = $1
39
+
40
+ items = detail.split("\n\n")
41
+
42
+ error_info = items[1].split("\n")[1]
43
+ return :failure, num_errors + ' Errors', error_info
44
+ end
45
+
46
+ return :success, 'All specs pass', ''
47
+
48
+ end
49
+
50
+ end