Skip to content

Commit

Permalink
First kinda working prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
jnicklas committed Jul 3, 2010
1 parent 12d2685 commit bce45bf
Show file tree
Hide file tree
Showing 15 changed files with 286 additions and 35 deletions.
5 changes: 4 additions & 1 deletion README
@@ -1 +1,4 @@
Javascript TDD kata using Jasmine with Node
Evergreen
=========

Evergreen glues together some pieces to simplify JavaScript unit testing in Rails3 applications.
18 changes: 18 additions & 0 deletions bin/evergreen
@@ -0,0 +1,18 @@
#!/usr/bin/env ruby

$:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')

require 'evergreen'

begin
# The dup is to keep ARGV intact, so that tools like ruby-debug can respawn.
failure = Evergreen::Cli.execute(ARGV.dup)
Kernel.exit(failure ? 1 : 0)
rescue SystemExit => e
Kernel.exit(e.status)
rescue Exception => e
STDERR.puts("#{e.message} (#{e.class})")
STDERR.puts(e.backtrace.join("\n"))
Kernel.exit(1)
end

1 change: 1 addition & 0 deletions example/public/implementation.js
@@ -0,0 +1 @@
var foo = 'foo';
7 changes: 4 additions & 3 deletions specs/foo_spec.js → example/spec/javascripts/foo_spec.js
@@ -1,15 +1,18 @@
require('./implementation')
require('/implementation.js')

describe('with no tokens', function () {
it("should return an empty string if an empty string is given", function() {
expect(foo).toEqual('foo');
})

it("should return a string unchanged", function() {
expect(foo).toEqual('foo');
})
})

describe('with one token', function () {
it("should replace the token with an empty string if no value is passed in", function() {
expect(foo).toEqual('foo');
})

it("should replace the token with a given value", function() {
Expand All @@ -32,5 +35,3 @@ describe('with two tokens (OMG!?)', function () {
it("should replace tokens without value with the empty string", function() {
})
})

jasmine.run()
43 changes: 43 additions & 0 deletions lib/evergreen.rb
@@ -0,0 +1,43 @@
require 'rubygems'
require 'sinatra/base'
require 'capybara'
require 'capybara/envjs'
require 'capybara/wait_until'
require 'launchy'

module Evergreen
autoload :Cli, 'evergreen/cli'
autoload :Server, 'evergreen/server'
autoload :Runner, 'evergreen/runner'
autoload :Spec, 'evergreen/spec'

class << self
def application(root)
Class.new(Sinatra::Base).tap do |app|
app.reset!
app.class_eval do
set :static, true
set :root, File.expand_path('evergreen', File.dirname(__FILE__))
set :public, File.expand_path(File.join(root, 'public'), File.dirname(__FILE__))

use Rack::Static, :urls => ["/lib"], :root => File.expand_path('jasmine', File.dirname(__FILE__))
use Rack::Static, :urls => ["/evergreen"], :root => File.dirname(__FILE__)

get '/' do
@specs = Spec.all(root)
erb :list
end

get '/run/:name' do |name|
@spec = Spec.new(root, name)
erb :spec
end

get '/spec/:name.js' do |name|
Spec.new(root, name).read
end
end
end
end
end
end
23 changes: 23 additions & 0 deletions lib/evergreen/cli.rb
@@ -0,0 +1,23 @@
module Evergreen
class Cli
def self.execute(argv)
new.execute(argv)
end

def execute(argv)
command = argv.shift
root = File.expand_path(argv.shift || '.', Dir.pwd)

case command
when "serve"
Evergreen::Server.run(root)
return true
when "run"
return Evergreen::Runner.run(root)
else
puts "no such command '#{command}'"
return false
end
end
end
end
3 changes: 3 additions & 0 deletions lib/evergreen/evergreen.js
@@ -0,0 +1,3 @@
var require = function(file) {
document.write('<script type="text/javascript" src="' + file + '"></script>');
};
56 changes: 56 additions & 0 deletions lib/evergreen/runner.rb
@@ -0,0 +1,56 @@
module Evergreen
class Runner
attr_reader :spec

def self.run(root)
runners = Spec.all(root).map { |spec| new(spec) }
runners.each do |runner|
if runner.passed?
print '.'
else
print 'F'
end
end
puts ""

runners.each do |runner|
puts runner.failure_message unless runner.passed?
end
end

def initialize(spec)
@spec = spec
end

def passed?
failed_examples.empty?
end

def failed_examples
results.select { |row| !row.passed }
end

def failure_message
failed_examples.map do |row|
<<-ERROR
Failed: #{row.name}
#{row.message}
in #{row.trace.fileName}:#{row.trace.lineNumber}
ERROR
end.join("\n\n")
end

def results
@results ||= begin
session = Capybara::Session.new(:envjs, Evergreen.application(spec.root))
session.visit(spec.url)
session.evaluate_script('jasmine.results')
end
end

end
end




31 changes: 31 additions & 0 deletions lib/evergreen/server.rb
@@ -0,0 +1,31 @@
module Evergreen
class Server
def self.run(root)
serve = new(root)
serve.boot
serve.launch_browser
end

def initialize(root)
@root = root
end

def server
@server ||= Capybara::Server.new(Evergreen.application(@root))
end

def boot
server.boot
end

def root_url
server.url('/')
end

def launch_browser
Launchy.open(root_url)
sleep
end
end
end

60 changes: 60 additions & 0 deletions lib/evergreen/spec.rb
@@ -0,0 +1,60 @@
module Evergreen
class Spec

def self.all(root)
Dir.glob(File.join(root, 'spec/javascripts', '*_spec.js')).map do |path|
new(root, File.basename(path).sub(/_spec\.js$/, ''))
end
end

attr_reader :name, :root

def initialize(root, name)
@root = root
@name = name
end

def path
File.join(root, 'spec/javascripts', name + '_spec.js')
end

def read
File.read(path)
end

def url
"/run/#{name}"
end

def passed?
run unless has_run?
results.all? { |row| row.passed }
end

def failure_message
run unless has_run?
results.each do |row|
puts "Failed: #{row.name}"
puts " #{row.message}"
puts " in #{row.trace.fileName}:#{row.trace.lineNumber}"
puts ""
puts ""
end
end

protected

def run
session.visit(url)
@results = session.evaluate_script('jasmine.results')
end

def has_run?
@results
end

def session
@session ||= Capybara::Session.new(:envjs, Evergreen.applications(root))
end
end
end
6 changes: 6 additions & 0 deletions lib/evergreen/views/list.erb
@@ -0,0 +1,6 @@
<h1>JS Specs</h1>

<% @specs.each do |spec| %>
<p><a href="<%= spec.url %>"><%= spec.name %></a></p>
<% end %>

37 changes: 37 additions & 0 deletions lib/evergreen/views/spec.erb
@@ -0,0 +1,37 @@
<!doctype html>

<html>
<head>
<link rel="stylesheet" type="text/css" href="/lib/jasmine.css">
<script src="/lib/jasmine-0.10.4.js" type="text/javascript"></script>
<script type="text/javascript" src="/lib/TrivialReporter.js"></script>
<script type="text/javascript" src="/lib/consolex.js"></script>
<script type="text/javascript" src="/evergreen/evergreen.js"></script>
<script src="/spec/<%= @spec.name %>.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
(function() {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.addReporter(new jasmine.TrivialReporter());
jasmineEnv.addReporter({
reportRunnerStarting: function(runner) {
jasmine.results = []
},
reportSpecResults: function(spec) {
var results = spec.results();
var item = results.getItems()[0] || {};
jasmine.results.push({
name: spec.getFullName(),
passed: results.failedCount === 0,
message: item.message,
trace: item.trace
});
}
});

jasmineEnv.execute();
})();
</script>
</body>
</html>
14 changes: 0 additions & 14 deletions tests.rb

This file was deleted.

7 changes: 0 additions & 7 deletions views/list.erb

This file was deleted.

10 changes: 0 additions & 10 deletions views/spec.erb

This file was deleted.

0 comments on commit bce45bf

Please sign in to comment.