Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS Test Driver #64

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions bin/sc-jstd
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env ruby
# ===========================================================================
# Project: Abbot - SproutCore Build Tools
# Copyright: ©2010 Apple Inc.
# portions copyright @2006-2011 Strobe Inc.
# and contributors
# ===========================================================================

if caller.empty?
puts "FATAL: You need to invoke sc-jstd from an installed gem or through bundler. For more information, please visit http://github.com/sproutcore/abbot/wiki/Using-Abbot-1.4-From-Source"
exit
end

require "sproutcore"

begin
gem 'nokogiri'
rescue LoadError
puts "FATAL: Missing nokogiri. Please install nokogiri (~1.5.0) to use sc-jstd."
exit
end

SC::Tools.invoke 'jstd'

# EOF
6 changes: 6 additions & 0 deletions lib/sproutcore.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ def self.builtin_project
@builtin_project ||= SC::Project.new(PATH)
end

# This is used by sc-jstd. When using sc-jstd you will have two servers running, sc-server and
# the jstd server. Because the browser will be connecting to the jstd server directly these
# url paths need to be absolute. Not the most ideal approach, but this avoids alot of refactoring.
def self.module_url_prefix; return @module_url_prefix if @module_url_prefix; return "" end
def self.module_url_prefix=(module_url_prefix); @module_url_prefix = module_url_prefix; end

# Returns the current project, if defined. This is normally only set
# when you start sc-server in interactive mode.
def self.project; @project; end
Expand Down
9 changes: 5 additions & 4 deletions lib/sproutcore/builders/module.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def build(dst_path)
EOT

output = ""
module_url_prefix = SC.module_url_prefix

entry.targets.each do |t|
next unless t[:target_type] == :module
Expand All @@ -48,19 +49,19 @@ def build(dst_path)

script_entry = manifest.find_entry('javascript.js')
next if not script_entry
script_url = script_entry.cacheable_url
script_url = module_url_prefix + script_entry.cacheable_url

string_entry = manifest.find_entry('javascript-strings.js')
next if not string_entry
string_url = string_entry.cacheable_url
string_url = module_url_prefix + string_entry.cacheable_url

module_info = t.module_info({ :variation => entry[:variation] })

output << eruby.evaluate({
:target_name => t[:target_name].to_s.sub(/^\//,''),
:dependencies => module_info[:requires].map{ |t| "'#{t[:target_name].to_s.sub(/^\//,'')}'" },
:styles => module_info[:css_urls].map{ |url| "'#{url}'" },
:styles2x => module_info[:css_2x_urls].map {|url| "'#{url}'"},
:styles => module_info[:css_urls].map{ |url| "'#{module_url_prefix}#{url}'" },
:styles2x => module_info[:css_2x_urls].map {|url| "'#{module_url_prefix}#{url}'"},
:script => script_url,
:string => string_url,
:prefetched => t[:prefetched_module]
Expand Down
6 changes: 6 additions & 0 deletions lib/sproutcore/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ class Project

# Parent project this project shoud inherit build rules and targets from
attr_reader :parent_project

# Proc that will be called when changes are detected to a monitored project
attr_accessor :monitor_proc

# regex so that certain files don't trigger monitor update
attr_accessor :nomonitor_pattern

def inspect
"SC::Project(#{File.basename(project_root || '')})"
Expand Down
9 changes: 7 additions & 2 deletions lib/sproutcore/rack/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ def monitor_project!
@project_mtime = files.map { |x| File.mtime(x).to_i }.max

Thread.new do
# TODO instead of polling every second, should investigate using a FS event
# monitor like fssm (https://github.com/ttilley/fssm). Would be both quicker
# and less resource intensive than polling
while @should_monitor

# only need to start scanning again 2 seconds after the last
Expand All @@ -227,8 +230,7 @@ def monitor_project!
# follow 1-level of symlinks
files += Dir.glob(@project_root / '**' / '*' / '**' / '*')
tmp_path = /^#{Regexp.escape(@project_root / 'tmp')}/
files.reject! { |f| f =~ tmp_path }
files.reject! { |f| File.directory?(f) }
files.reject! { |f| (f =~ tmp_path || File.directory?(f) || f =~ @project.nomonitor_pattern) }

cur_file_count = files.size
cur_mtime = files.map { |x| File.mtime(x).to_i }.max
Expand All @@ -238,6 +240,9 @@ def monitor_project!
@project_did_change = true
@project_file_count = cur_file_count
@project_mtime = cur_mtime
# place for some extra project maintainen
extra_action = @project.monitor_proc
extra_action.call if (extra_action && extra_action.respond_to?(:call))
end
end

Expand Down
1 change: 1 addition & 0 deletions lib/sproutcore/tools.rb
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ def self.start(args = ARGV)
require "sproutcore/tools/docs"
require "sproutcore/tools/gen"
require "sproutcore/tools/init"
require "sproutcore/tools/jstd"
require "sproutcore/tools/manifest"
require "sproutcore/tools/server"

93 changes: 93 additions & 0 deletions lib/sproutcore/tools/jstd.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# ===========================================================================
# Copyright: ©2011 Paul Lambert <[email protected]> & Sproutcore Contributors
# For Abbot, and licensed under same terms as Sproutcore itself
# ===========================================================================

require 'open-uri'
require 'thread'
require 'yaml'
require 'digest/md5'

module SC
class Tools

desc "jstd TARGET [OPTIONS]", "Generates configuration file for JsTestDriver (http://code.google.com/p/js-test-driver/wiki/ConfigurationFile)"
method_options :daemonize => false,
:pid => :string,
:port => :string,
:jstdport => :string,
:jstdhost => :string,
:jstdconfpath => :string,
:app => :string,
:host => :string,
:irb => false,
:filesystem => true

def jstd(*targets)
require 'nokogiri'

# set defaults
port = options[:port] = options[:port] || "4225"
jstdport = options[:jstdport] || "4224"
jstdhost = options[:jstdhost] || "http://localhost"
jstdconfpath = options[:jstdconfpath] || "jsTestDriver.conf"
host = options[:host] || "http://localhost"
SC.module_url_prefix = "#{host}:#{port}"

# find app target
target = requires_target!(*targets)
fatal! "Target must be an app" unless target[:target_type] == :app
target_name = target[:target_name].to_s

project = requires_project!
# apparently necessary as getting target results in connections being refused
# unless project is subsequently reloaded
project.reload!

# wrap logic to rebuild configuration file in a Proc/closure
# allowing for it to be rebuilt 'on the fly', which makes for
# a much nicer testing loop. See rack/builder.rb for monitoring and
# invokation of this callback
project.monitor_proc = Proc.new do
url = "#{host}:#{port}#{target_name}/en/current/tests.html"
doc = Nokogiri::HTML(open(url))
dir = "tmp/jstd"
Dir.mkdir(dir) if not Dir.exists?(dir)

loadPaths = []
doc.css('script').each do |link|
js = link['src']
if js
loadPaths << "#{host}:#{port}#{js}"
elsif (link.content and link.content.length > 0)
js = link.content

filename = "#{dir}/#{Digest::MD5.hexdigest(js)}.js"
File.open(filename, "w") do |f|
f.write(js)
end

loadPaths << filename
end
end
project.nomonitor_pattern = Regexp.new(Regexp.escape(jstdconfpath))

# write out to yaml conf
conf = {"server"=>"#{jstdhost}:#{jstdport}", "load"=>loadPaths}
File.open(jstdconfpath, "w") do |f|
f.write(YAML::dump(conf))
end

SC.logger.info "Wrote to #{jstdconfpath}"
end

Thread.new do
sleep(4) # give server a chance to start up
project.monitor_proc.call # call once to make sure everything's fresh and valid
end

server()
end

end
end
1 change: 0 additions & 1 deletion sproutcore.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ Gem::Specification.new do |s|
s.add_dependency 'erubis', "~> 2.6"
s.add_dependency 'thor', '~> 0.14.3'
s.add_dependency 'haml', '~> 3.1.1'

s.add_dependency 'compass', '~> 0.11.1'

s.add_dependency 'em-http-request', '~> 1.0.0.beta'
Expand Down