ghostbuster 0.1.0 → 0.2.0

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/README.md CHANGED
@@ -8,7 +8,37 @@ To install first `gem install ghostbuster`. Once you've done that, you can run `
8
8
 
9
9
  ## Usage
10
10
 
11
- Once installed, you can simply use `ghostbuster path/to/tests` to run your tests. You should get some output that looks something like this.
11
+ Once installed, you can simply use `ghostbuster [path/to/Ghostfile]` to run your tests.
12
+
13
+ ## `Ghostfile`
14
+
15
+ Your `Ghostfile` handles your configuration. To set the pattern use:
16
+
17
+ ~~~~
18
+ ghost.pattern = "test_*.coffee" # this is the default
19
+ ~~~~
20
+
21
+ To enable (or disable) screenshots use:
22
+
23
+ ~~~~
24
+ ghost.take_screenshots! # or #do_not_takescreenshots! defaults to take_screenshots!
25
+ ~~~~
26
+
27
+ To set the directory your screenshots will save to use:
28
+
29
+ ~~~~
30
+ ghost.screenshot_dir = '.'
31
+ ~~~~
32
+
33
+ To set the dimensions for the screenshots use:
34
+
35
+ ~~~~
36
+ ghost.screenshot_dimensions 800, 2000 # x, y
37
+ ~~~~
38
+
39
+ If no Ghostfile is found, it will simply use the defaults.
40
+
41
+ You should get some output that looks something like this.
12
42
 
13
43
  ~~~~
14
44
 
data/Rakefile CHANGED
@@ -1,3 +1,30 @@
1
1
  require 'bundler/gem_tasks'
2
2
  $: << 'lib'
3
- require 'ghostbuster/install_rake'
3
+ require 'ghostbuster/install_rake'
4
+
5
+ def test_output
6
+ out = `bundle exec rake test:ghostbuster`
7
+ $?.success? ? out.gsub(/server .*?\n/m, "server\n") : raise("there was a problem")
8
+ end
9
+
10
+ desc "Run tests"
11
+ task :test do
12
+ out = test_output
13
+ if File.read(File.join(File.dirname(__FILE__), 'test', 'output')) == out
14
+ puts "Everything is great!"
15
+ else
16
+ puts out
17
+ raise "Things aren't great."
18
+ end
19
+ end
20
+
21
+ desc "Update tests"
22
+ task :'test:update' do
23
+ File.open(File.join(File.dirname(__FILE__), 'test', 'output'), 'w') {|f| f << test_output}
24
+ puts "Test output updated"
25
+ end
26
+
27
+ desc "Show output"
28
+ task :"test:output" do
29
+ puts test_output
30
+ end
data/ghost/Ghostfile ADDED
@@ -0,0 +1,4 @@
1
+ ghost.pattern = "test_*.coffee"
2
+ ghost.do_not_take_screenshots! # or do_not_takescreenshots! defaults to true
3
+ ghost.screenshot_dir = '.'
4
+ ghost.screenshot_dimensions 800, 2000
@@ -1,12 +1,16 @@
1
1
  class Test
2
2
  constructor: (@runner, @name, @testBody) ->
3
3
  @page = new WebPage()
4
+ if @runner.useScreenshots()
5
+ @page.viewportSize = @runner.viewportDimensions()
4
6
  @page.onConsoleMessage = (msg) ->
5
7
  console.log "PAGE CONSOLE: #{msg}"
6
8
  @page.onAlert = (msg) => @setLastError(msg)
7
9
  @lastError = null
8
10
  @assertions = []
9
11
  @seenCallbacks = []
12
+ @assertionIndex = 0
13
+ nameForRender: -> "#{@runner.suite.screenshot_dir}/#{@runner.nameForRender()}-#{@name.toLowerCase()}".replace(///\s///g, '_').replace(///'///g, '')
10
14
  getLastError: -> @runner.lastErrors[@name]
11
15
  resetLastError: -> delete @runner.lastErrors[@name]
12
16
  setLastError: (error) ->
@@ -43,17 +47,18 @@ class Test
43
47
  fail: (msg) ->
44
48
  @callback(false, msg)
45
49
  assert: (opts, valueFetcher) ->
46
- @assertions.push(new Assertion(this, opts, valueFetcher))
50
+ @assertions.push(new Assertion(this, ++@assertionIndex, opts, valueFetcher))
47
51
  @assertions[0].start() if @assertions.length == 1
48
52
  wait: (time, callback) ->
49
53
  test = this
50
54
  setTimeout (-> callback.call(test)), time * 1000
51
55
 
52
56
  class Assertion
53
- constructor: (@test, @opts, @fetcher) ->
57
+ constructor: (@test, @idx, @opts, @fetcher) ->
54
58
  @count = 0
55
59
  @totalTime = if @opts['total'] then @opts['total'] * 1000 else 1000
56
60
  @everyTime = if @opts['every'] then @opts['every'] else 75
61
+ nameForRender: -> "#{@test.nameForRender()}-#{@idx}.png"
57
62
  start: ->
58
63
  test = @test
59
64
  assertion = this
@@ -69,6 +74,8 @@ class Assertion
69
74
  test.resetLastError()
70
75
  test.assertions.splice(test.assertions.indexOf(assertion), 1)
71
76
  clearTimeout assertion.fatal
77
+ if test.runner.useScreenshots()
78
+ test.page.render assertion.nameForRender()
72
79
  if test.assertions.length > 0
73
80
  test.assertions[0].start()
74
81
  else
@@ -180,12 +187,16 @@ class PendingTest
180
187
  constructor: (@runner, @name) ->
181
188
  run: (callback) -> callback('pending')
182
189
  actuallyRun: -> false
190
+
183
191
  class TestFile
184
192
  constructor: (@suite, @name) ->
185
193
  @tests = []
186
194
  @lastErrors = {}
187
195
  @befores = []
188
196
  @afters = []
197
+ nameForRender: -> @name.toLowerCase()
198
+ useScreenshots: -> @suite.screenshots
199
+ viewportDimensions: -> width: @suite.screenshot_x, height: @suite.screenshot_y
189
200
  normalizePath: (path) -> if path.match(/^http/) then path else "#{@root}#{path}"
190
201
  addPending: (name, body) -> @tests.push new PendingTest(this, name)
191
202
  before: (body) -> @befores.push(body)
@@ -257,7 +268,11 @@ class TestSuite
257
268
  @failure += failure
258
269
  @pending += pending
259
270
  run: ->
260
- count = 0
271
+ @screenshots = @args[0] == 'true'
272
+ @screenshot_x = @args[1]
273
+ @screenshot_y = @args[2]
274
+ @screenshot_dir = @args[3]
275
+ count = 4
261
276
  suite = this
262
277
  runNextTest = ->
263
278
  if suite.args.length == count
data/lib/ghostbuster.rb CHANGED
@@ -1,22 +1,23 @@
1
1
  require 'ghostbuster/version'
2
2
  require 'ghostbuster/shell'
3
+ require 'ghostbuster/config'
3
4
 
4
5
  class Ghostbuster
5
6
  include Shell
6
7
  autoload :Rake, 'ghostbuster/rake'
7
8
  autoload :Runner, 'ghostbuster/runner'
8
9
 
9
- def initialize(*paths)
10
- @paths = paths
11
- @paths.flatten!
12
- @dir = File.directory?(@paths[0]) ? @paths[0] : File.dirname(@paths[0])
10
+ def initialize(path)
11
+ @path = File.exist?(path) ? path : '.'
12
+ @dir = File.directory?(@path) ? @path : File.basename(@path)
13
+ @file = File.directory?(@dir) ? File.join(@dir, 'Ghostfile') : @dir
13
14
  @ghost_lib = File.expand_path(File.join(File.dirname(__FILE__), "ghostbuster.coffee"))
14
15
  @phantom_bin = File.join(ENV['HOME'], '.ghostbuster', 'phantomjs')
16
+ @config = Config.new(@file)
15
17
  STDOUT.sync = true
16
18
  end
17
19
 
18
20
  def run
19
- files = Array(@paths).map{|path| Dir[path].to_a}.flatten.map{|f| File.expand_path(f)}
20
21
  status = 1
21
22
  Dir.chdir(@dir) do
22
23
  spinner "Starting server" do
@@ -24,7 +25,7 @@ class Ghostbuster
24
25
  sleep 2
25
26
  end
26
27
  begin
27
- _, status = Process.waitpid2 fork { exec("#{@phantom_bin} #{@ghost_lib} #{files.join(' ')}") }
28
+ _, status = Process.waitpid2 fork { exec("#{@phantom_bin} #{@ghost_lib} #{@config.screenshots?} #{@config.screenshot_x} #{@config.screenshot_y} #{File.expand_path(@config.screenshot_dir)} #{Dir[@config.pattern].to_a.join(' ')}") }
28
29
  ensure
29
30
  spinner "Stopping server" do
30
31
  sh "./stop.sh"
@@ -0,0 +1,38 @@
1
+ class Ghostbuster
2
+ class Config
3
+
4
+ attr_accessor :pattern, :screenshot_dir
5
+ attr_reader :screenshot_x, :screenshot_y
6
+ def initialize(path_to_file = nil)
7
+ @config_file = path_to_file || './Ghostfile'
8
+ @screenshot_x, @screenshot_y = 800, 2000
9
+ @pattern = "./test_*.coffee"
10
+ @screenshot_dir = "."
11
+ @screenshots = true
12
+ if File.exist?(@config_file)
13
+ instance_eval File.read(@config_file), @config_file, 1
14
+ end
15
+ end
16
+
17
+ def ghost
18
+ self
19
+ end
20
+
21
+ def screenshot_dimensions(x, y)
22
+ @screenshot_x, @screenshot_y = x, y
23
+ end
24
+
25
+ def do_not_take_screenshots!
26
+ @screenshots = false
27
+ end
28
+
29
+ def take_screenshots!
30
+ @screenshots = true
31
+ end
32
+
33
+ def screenshots?
34
+ @screenshots
35
+ end
36
+ end
37
+ end
38
+
@@ -7,11 +7,11 @@ class Ghostbuster
7
7
  end
8
8
  end
9
9
  def self.include_rake_tasks(opts = {})
10
+ opts[:path] ||= './ghost'
10
11
  opts[:task_name] ||= :"test:ghostbuster"
11
- opts[:file_pattern] ||= "ghost/test_*.{coffee,js}"
12
12
  desc "Run ghostbuster tasks"
13
13
  task opts[:task_name] do
14
- Ghostbuster.new(opts[:file_pattern]).run
14
+ Ghostbuster.new(opts[:path]).run
15
15
  end
16
16
  end
17
17
  end
@@ -5,12 +5,12 @@ class Ghostbuster
5
5
  end
6
6
 
7
7
  def run
8
- if @args.size == 0
9
- puts "ghostbuster <path/to/tests>"
8
+ if @args.size == 1 && @args.first == /^--?[\?h](|elp)$/i or @args.size > 1
9
+ puts "ghostbuster [path/to/Ghostfile]"
10
10
  puts " Version #{VERSION}"
11
- exit(1)
11
+ exit(0)
12
12
  else
13
- Ghostbuster.new(@args).run
13
+ Ghostbuster.new(@args.first).run
14
14
  end
15
15
  end
16
16
  end
@@ -1,3 +1,3 @@
1
1
  class Ghostbuster
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
data/test/output ADDED
@@ -0,0 +1,23 @@
1
+ (in /Users/joshbuddy/Development/ghostbuster)
2
+ Starting server
3
+ GhostBuster
4
+ For test_ghost.coffee
5
+ ✓ Simple index
6
+ ✓ Form input
7
+ ✓ Link traversal
8
+ ✗ Bad link traversal
9
+ Assert location failed: Excepted http://127.0.0.1:4567/not-correct, got http://127.0.0.1:4567/
10
+ ✗ Form input not equal
11
+ Assert first for selector #out did not meet expectations
12
+
13
+ For test_ghostmore.coffee
14
+ ✓ Simple form
15
+ ◐ Form should do more things
16
+ ✓ Simple form with wait
17
+ ✓ Slow form
18
+ ✓ Before block var
19
+ ✗ This test will explode!
20
+ I hate you!
21
+
22
+ 7 success, 3 failure, 1 pending
23
+ Stopping server
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ghostbuster
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Josh Hull
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-08-29 00:00:00 -07:00
18
+ date: 2011-08-30 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -97,6 +97,7 @@ files:
97
97
  - Rakefile
98
98
  - bin/ghostbuster
99
99
  - bin/setup-ghostbuster
100
+ - ghost/Ghostfile
100
101
  - ghost/config.ru
101
102
  - ghost/start.sh
102
103
  - ghost/stop.sh
@@ -108,12 +109,14 @@ files:
108
109
  - ghostbuster.gemspec
109
110
  - lib/ghostbuster.coffee
110
111
  - lib/ghostbuster.rb
112
+ - lib/ghostbuster/config.rb
111
113
  - lib/ghostbuster/install_rake.rb
112
114
  - lib/ghostbuster/rake.rb
113
115
  - lib/ghostbuster/runner.rb
114
116
  - lib/ghostbuster/shell.rb
115
117
  - lib/ghostbuster/version.rb
116
118
  - log/thin.log
119
+ - test/output
117
120
  has_rdoc: true
118
121
  homepage: https://github.com/joshbuddy/ghostbuster
119
122
  licenses: []
@@ -148,5 +151,5 @@ rubygems_version: 1.6.2
148
151
  signing_key:
149
152
  specification_version: 3
150
153
  summary: Integration testing ftw
151
- test_files: []
152
-
154
+ test_files:
155
+ - test/output