screw_server 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.run +3 -0
- data/Gemfile.run.lock +41 -0
- data/assets/screw-jslint.js +69 -0
- data/assets/screw-server.js +120 -0
- data/assets/screw.css +70 -0
- data/assets/vendor/fulljslint.js +5699 -0
- data/assets/vendor/screw-unit/CHANGES +7 -0
- data/assets/vendor/screw-unit/EXAMPLE.html +68 -0
- data/assets/vendor/screw-unit/LICENSE +22 -0
- data/assets/vendor/screw-unit/README.markdown +307 -0
- data/assets/vendor/screw-unit/example/models/cat.js +5 -0
- data/assets/vendor/screw-unit/example/models/man.js +17 -0
- data/assets/vendor/screw-unit/example/spec/matchers/have.js +8 -0
- data/assets/vendor/screw-unit/example/spec/models/cat_spec.js +31 -0
- data/assets/vendor/screw-unit/example/spec/models/man_spec.js +34 -0
- data/assets/vendor/screw-unit/example/spec/spec_helper.js +5 -0
- data/assets/vendor/screw-unit/example/spec/suite.html +25 -0
- data/assets/vendor/screw-unit/lib/jquery-1.2.6.js +3549 -0
- data/assets/vendor/screw-unit/lib/jquery.fn.js +29 -0
- data/assets/vendor/screw-unit/lib/jquery.print.js +109 -0
- data/assets/vendor/screw-unit/lib/screw.behaviors.js +101 -0
- data/assets/vendor/screw-unit/lib/screw.builder.js +90 -0
- data/assets/vendor/screw-unit/lib/screw.css +90 -0
- data/assets/vendor/screw-unit/lib/screw.events.js +45 -0
- data/assets/vendor/screw-unit/lib/screw.matchers.js +203 -0
- data/assets/vendor/screw-unit/spec/behaviors_spec.js +188 -0
- data/assets/vendor/screw-unit/spec/matchers_spec.js +391 -0
- data/assets/vendor/screw-unit/spec/print_spec.js +158 -0
- data/assets/vendor/screw-unit/spec/spec_helper.js +0 -0
- data/assets/vendor/screw-unit/spec/suite.html +18 -0
- data/assets/vendor/smoke/LICENSE +22 -0
- data/assets/vendor/smoke/README.markdown +68 -0
- data/assets/vendor/smoke/lib/smoke.core.js +49 -0
- data/assets/vendor/smoke/lib/smoke.mock.js +219 -0
- data/assets/vendor/smoke/lib/smoke.stub.js +29 -0
- data/assets/vendor/smoke/plugins/screw.mocking.js +26 -0
- data/assets/vendor/smoke/spec/core_spec.js +115 -0
- data/assets/vendor/smoke/spec/mock_spec.js +431 -0
- data/assets/vendor/smoke/spec/screw_integration_spec.js +17 -0
- data/assets/vendor/smoke/spec/spec_helper.js +0 -0
- data/assets/vendor/smoke/spec/stub_spec.js +17 -0
- data/assets/vendor/smoke/spec/su/jquery-1.2.3.js +3408 -0
- data/assets/vendor/smoke/spec/su/jquery.fn.js +29 -0
- data/assets/vendor/smoke/spec/su/jquery.print.js +108 -0
- data/assets/vendor/smoke/spec/su/screw.behaviors.js +91 -0
- data/assets/vendor/smoke/spec/su/screw.builder.js +80 -0
- data/assets/vendor/smoke/spec/su/screw.css +74 -0
- data/assets/vendor/smoke/spec/su/screw.events.js +38 -0
- data/assets/vendor/smoke/spec/su/screw.matchers.js +65 -0
- data/assets/vendor/smoke/spec/suite.html +29 -0
- data/bin/screw_server +43 -0
- data/lib/screw_server/app.rb +197 -0
- data/lib/screw_server/base.rb +21 -0
- data/lib/screw_server/fixture_file.rb +17 -0
- data/lib/screw_server/jslint_suite.rb +51 -0
- data/lib/screw_server/spec_file.rb +76 -0
- data/lib/screw_server.rb +2 -0
- data/screw_server.gemspec +28 -0
- data/views/index.haml +13 -0
- data/views/missing_spec_helper.haml +12 -0
- data/views/no_specs.haml +11 -0
- data/views/run_spec.haml +30 -0
- data/views/sample_spec.js +7 -0
- data/views/sample_spec_helper.js +2 -0
- metadata +257 -0
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
require 'screw_server/jslint_suite'
|
4
|
+
require "screw_server/spec_file"
|
5
|
+
|
6
|
+
module ScrewServer
|
7
|
+
class App < Sinatra::Base
|
8
|
+
|
9
|
+
SPEC_BASE_URL = "___screw_specs___"
|
10
|
+
ASSET_BASE_URL = "___screw_assets___"
|
11
|
+
VIEW_PATH = File.join(File.dirname(__FILE__), "..", "..", "views")
|
12
|
+
|
13
|
+
set :views, VIEW_PATH
|
14
|
+
|
15
|
+
get "/run/:name" do
|
16
|
+
run_specs([SpecFile.new(params[:name])])
|
17
|
+
end
|
18
|
+
|
19
|
+
get "/run" do
|
20
|
+
run_specs(SpecFile.all)
|
21
|
+
end
|
22
|
+
|
23
|
+
get "/bisect/:victim/:begin/:end" do
|
24
|
+
victim = params[:victim]
|
25
|
+
suspects = SpecFile.all.map { |spec| spec.name } - [victim]
|
26
|
+
|
27
|
+
subset = suspects[params[:begin].to_i..(params[:end].to_i - 1)]
|
28
|
+
|
29
|
+
puts "suspects: #{subset.length}"
|
30
|
+
|
31
|
+
specs_to_run = (subset + [victim]).map {|name| SpecFile.new(name) }
|
32
|
+
run_specs(specs_to_run)
|
33
|
+
end
|
34
|
+
|
35
|
+
get "/" do
|
36
|
+
@specs = SpecFile.all
|
37
|
+
if @specs.empty?
|
38
|
+
render_setup_tutorial(:no_specs)
|
39
|
+
else
|
40
|
+
haml :index
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
get "/monitor" do
|
45
|
+
spec = SpecFile.latest
|
46
|
+
@include_monitor_code = true
|
47
|
+
run_specs([spec]);
|
48
|
+
end
|
49
|
+
|
50
|
+
get "/has_changes_since/:spec/:timestamp" do
|
51
|
+
if SpecFile.latest.name != params[:spec]
|
52
|
+
"true"
|
53
|
+
else
|
54
|
+
spec = SpecFile.new(params[:spec])
|
55
|
+
if spec.last_dependency_change > params[:timestamp].to_i
|
56
|
+
"true"
|
57
|
+
else
|
58
|
+
"false"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
get "/#{SPEC_BASE_URL}/*" do
|
64
|
+
send_file(file_from_base_dir(Base.spec_base_dir, params[:splat]))
|
65
|
+
end
|
66
|
+
|
67
|
+
get "/#{ASSET_BASE_URL}/*" do
|
68
|
+
send_file(file_from_base_dir(asset_base_dir, params[:splat]))
|
69
|
+
end
|
70
|
+
|
71
|
+
helpers do
|
72
|
+
def cache_busting_url(url)
|
73
|
+
"#{url}?#{rand}"
|
74
|
+
end
|
75
|
+
|
76
|
+
def jslint_suites
|
77
|
+
jslint_file = File.join(Base.spec_base_dir, "jslint.rb")
|
78
|
+
if !File.exists?(jslint_file)
|
79
|
+
[]
|
80
|
+
else
|
81
|
+
JslintSuite.suites_from(jslint_file).map do |suite|
|
82
|
+
{
|
83
|
+
:file_list => suite.file_list.map { |file| url_for_source_file(file) },
|
84
|
+
:options => suite.options_with_defaults
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def url_for_screw_asset(file)
|
91
|
+
"/#{ASSET_BASE_URL}/#{file}"
|
92
|
+
end
|
93
|
+
|
94
|
+
def url_for_spec(file)
|
95
|
+
"/#{SPEC_BASE_URL}/#{file}"
|
96
|
+
end
|
97
|
+
|
98
|
+
def fixture_html
|
99
|
+
@specs.inject({}) { |result, spec| result.merge(spec.fixture_hash) }
|
100
|
+
end
|
101
|
+
|
102
|
+
def required_files
|
103
|
+
@specs.map(&:required_scripts).flatten.uniq
|
104
|
+
end
|
105
|
+
|
106
|
+
def monitor_code
|
107
|
+
spec = SpecFile.latest
|
108
|
+
<<-EOS
|
109
|
+
Screw.check_for_change = function() {
|
110
|
+
Screw.ajax({
|
111
|
+
url: "/has_changes_since/#{spec.name}/#{spec.last_dependency_change}",
|
112
|
+
cache: false,
|
113
|
+
success: function(answer) {
|
114
|
+
if (answer === "true") {
|
115
|
+
location.reload();
|
116
|
+
}
|
117
|
+
else {
|
118
|
+
setTimeout(Screw.check_for_change, 1000);
|
119
|
+
}
|
120
|
+
}
|
121
|
+
});
|
122
|
+
};
|
123
|
+
Screw.check_for_change();
|
124
|
+
EOS
|
125
|
+
end
|
126
|
+
|
127
|
+
def screw_assets
|
128
|
+
%w{
|
129
|
+
vendor/fulljslint.js
|
130
|
+
vendor/screw-unit/lib/jquery.fn.js
|
131
|
+
vendor/screw-unit/lib/jquery.print.js
|
132
|
+
vendor/screw-unit/lib/screw.builder.js
|
133
|
+
vendor/screw-unit/lib/screw.matchers.js
|
134
|
+
vendor/screw-unit/lib/screw.events.js
|
135
|
+
vendor/screw-unit/lib/screw.behaviors.js
|
136
|
+
vendor/smoke/lib/smoke.core.js
|
137
|
+
vendor/smoke/lib/smoke.mock.js
|
138
|
+
vendor/smoke/lib/smoke.stub.js
|
139
|
+
vendor/smoke/plugins/screw.mocking.js
|
140
|
+
screw-server.js
|
141
|
+
}
|
142
|
+
end
|
143
|
+
|
144
|
+
def sample_spec_file
|
145
|
+
"\n"+File.read(File.join(VIEW_PATH, "sample_spec.js"))
|
146
|
+
end
|
147
|
+
|
148
|
+
def sample_spec_helper
|
149
|
+
"\n"+File.read(File.join(VIEW_PATH, "sample_spec_helper.js"))
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.run!(*args)
|
154
|
+
set(:public, Base.code_base_dir)
|
155
|
+
super(*args)
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def file_from_base_dir(base_dir, file)
|
161
|
+
File.expand_path(File.join(base_dir, file)).tap do |result|
|
162
|
+
unless result.start_with?(base_dir)
|
163
|
+
raise Sinatra::NotFound, "Forbidden Access out of base directory"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def url_for_source_file(filename)
|
169
|
+
file = File.expand_path(filename)
|
170
|
+
if file.start_with?(Base.code_base_dir)
|
171
|
+
file[Base.code_base_dir.length..-1]
|
172
|
+
elsif file.start_with?(Base.spec_base_dir)
|
173
|
+
url_for_spec(file[(Base.spec_base_dir.length + 1)..-1])
|
174
|
+
else
|
175
|
+
raise "file #{file} cannot be checked by jslint since it it not inside the spec or code path"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def run_specs(specs)
|
180
|
+
if File.exists?(SpecFile.spec_helper_file)
|
181
|
+
@specs = specs
|
182
|
+
haml :run_spec
|
183
|
+
else
|
184
|
+
render_setup_tutorial(:missing_spec_helper)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def asset_base_dir
|
189
|
+
@assert_base_dir ||= File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "assets"))
|
190
|
+
end
|
191
|
+
|
192
|
+
def render_setup_tutorial(template)
|
193
|
+
@spec_base_dir = Base.spec_base_dir
|
194
|
+
haml template
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ScrewServer
|
2
|
+
module Base
|
3
|
+
def self.spec_base_dir=(d)
|
4
|
+
raise "expected a directory with javascript specs under #{d}" unless File.exists?(d)
|
5
|
+
@spec_base_dir = d
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.spec_base_dir
|
9
|
+
@spec_base_dir
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.code_base_dir=(d)
|
13
|
+
raise "expected a directory with javascript code under #{d}" unless File.exists?(d)
|
14
|
+
@code_base_dir = d
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.code_base_dir
|
18
|
+
@code_base_dir
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ScrewServer
|
2
|
+
class FixtureFile
|
3
|
+
attr_reader :name
|
4
|
+
|
5
|
+
def self.base_dir
|
6
|
+
File.join(Base.spec_base_dir, "fixtures")
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
@name = name
|
11
|
+
end
|
12
|
+
|
13
|
+
def filename
|
14
|
+
"#{Base.spec_base_dir}/fixtures/#{name}.html"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module ScrewServer
|
2
|
+
class JslintSuite
|
3
|
+
|
4
|
+
DEFAULT_OPTIONS = {
|
5
|
+
# true
|
6
|
+
"bitwise" => true,
|
7
|
+
"browser" => true,
|
8
|
+
"eqeqeq" => true,
|
9
|
+
"immed" => true,
|
10
|
+
"newcap" => true,
|
11
|
+
"nomen" => true,
|
12
|
+
"regexp" => true,
|
13
|
+
"undef" => true,
|
14
|
+
# false
|
15
|
+
"plusplus" => false,
|
16
|
+
"indent" => false,
|
17
|
+
"onevar" => false,
|
18
|
+
"white" => false,
|
19
|
+
"regexp" => false,
|
20
|
+
"nomen" => false
|
21
|
+
}
|
22
|
+
|
23
|
+
attr_accessor :name, :file_list, :options
|
24
|
+
|
25
|
+
def initialize(n)
|
26
|
+
@name = n
|
27
|
+
end
|
28
|
+
|
29
|
+
def file_list=(v)
|
30
|
+
@file_list = v.map { |file| File.expand_path(file) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.suites_from(file)
|
34
|
+
@suites = []
|
35
|
+
eval(IO.read(file), binding, file)
|
36
|
+
@suites
|
37
|
+
end
|
38
|
+
|
39
|
+
def options_with_defaults
|
40
|
+
DEFAULT_OPTIONS.merge(self.options || {})
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def self.jslint(name)
|
46
|
+
suite = JslintSuite.new(name)
|
47
|
+
yield suite
|
48
|
+
@suites << suite
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require "screw_server/base"
|
2
|
+
require "screw_server/fixture_file"
|
3
|
+
|
4
|
+
module ScrewServer
|
5
|
+
class SpecFile
|
6
|
+
def self.all
|
7
|
+
Dir.glob(File.join(Base.spec_base_dir, "*_spec.js")).sort.map do |file|
|
8
|
+
SpecFile.new(file.gsub("#{Base.spec_base_dir}/", "").gsub("_spec.js", ""))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.latest
|
13
|
+
SpecFile.all.sort{ |a, b| a.last_changed <=> b.last_changed }.last
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :name
|
17
|
+
|
18
|
+
def initialize(name)
|
19
|
+
@name = name
|
20
|
+
end
|
21
|
+
|
22
|
+
def filename
|
23
|
+
File.join(Base.spec_base_dir, full_name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def full_name
|
27
|
+
name + "_spec.js"
|
28
|
+
end
|
29
|
+
|
30
|
+
def used_fixtures
|
31
|
+
scan_for_statement("use_fixture", filename).map {|name| FixtureFile.new(name) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def fixture_hash
|
35
|
+
used_fixtures.inject({}) do |result, fixture|
|
36
|
+
result.merge(fixture.name => File.read(fixture.filename))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def required_scripts
|
41
|
+
required_files_in(SpecFile.spec_helper_file) + required_files_in(filename)
|
42
|
+
end
|
43
|
+
|
44
|
+
def last_dependency_change
|
45
|
+
used_files.map do |file|
|
46
|
+
File.mtime(file).to_i rescue 0
|
47
|
+
end.max
|
48
|
+
end
|
49
|
+
|
50
|
+
def last_changed
|
51
|
+
@last_changed ||= File.mtime(filename).to_i
|
52
|
+
end
|
53
|
+
|
54
|
+
def used_files
|
55
|
+
[filename, SpecFile.spec_helper_file] +
|
56
|
+
used_fixtures.map(&:filename) +
|
57
|
+
required_scripts.map {|script| File.join(Base.code_base_dir, script)}
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.spec_helper_file
|
61
|
+
File.join(Base.spec_base_dir, "spec_helper.js")
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
def scan_for_statement(statement, filename)
|
67
|
+
File.read(filename).scan(/#{statement}\(["']\/?(.+)['"]\)/).map { |groups| groups[0] }
|
68
|
+
end
|
69
|
+
|
70
|
+
def required_files_in(filename)
|
71
|
+
files = scan_for_statement("require", filename)
|
72
|
+
files = files.reject { |file| file == "spec_helper.js" }
|
73
|
+
files = files.map { |file| file.gsub("../../public", "") }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/screw_server.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = %q{screw_server}
|
3
|
+
s.version = "0.1.4"
|
4
|
+
s.authors = ["Kristian Hanekamp", "Infopark AG"]
|
5
|
+
s.description = %q{Screw Server - easy javascript unit tests}
|
6
|
+
s.email = %q{kristian.hanekamp@infopark.de}
|
7
|
+
s.files =
|
8
|
+
Dir.glob("{lib,assets,views}/**/*") +
|
9
|
+
["bin/screw_server", "Gemfile.run", "Gemfile.run.lock", "screw_server.gemspec"]
|
10
|
+
s.summary = %q{Screw Server}
|
11
|
+
|
12
|
+
s.add_dependency("json", "=1.4.3")
|
13
|
+
s.add_dependency("haml", "= 3.0.13")
|
14
|
+
s.add_dependency("bundler", "= 1.0.7")
|
15
|
+
|
16
|
+
# sinatra and dependencies
|
17
|
+
s.add_dependency("rack", "= 1.1.0")
|
18
|
+
s.add_dependency("sinatra", "= 1.0")
|
19
|
+
|
20
|
+
# thin and dependencies
|
21
|
+
s.add_dependency("daemons", "= 1.0.10")
|
22
|
+
# eventmachine 0.12.[7-10] has a bug when running without native extensions
|
23
|
+
# http://groups.google.com/group/eventmachine/browse_thread/thread/29fef72ee865ed6d
|
24
|
+
s.add_dependency("eventmachine", "= 0.12.6")
|
25
|
+
s.add_dependency("thin", "= 1.2.7")
|
26
|
+
|
27
|
+
s.executables = ['screw_server']
|
28
|
+
end
|
data/views/index.haml
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
%html
|
2
|
+
%head
|
3
|
+
%link{:rel => "stylesheet", :href => url_for_screw_asset("screw.css"), :type => "text/css"}
|
4
|
+
|
5
|
+
%body
|
6
|
+
%h1 Screw Server
|
7
|
+
%div{:style => "margin: 20px;"}
|
8
|
+
%div{:style => "margin: 20px;"}
|
9
|
+
%a{:href => "/run"} RUN ALL
|
10
|
+
%a{:href => "/monitor"} MONITOR
|
11
|
+
-@specs.each do |spec|
|
12
|
+
%li
|
13
|
+
%a{:href => "/run/#{spec.name}"}= spec.name
|
@@ -0,0 +1,12 @@
|
|
1
|
+
%html
|
2
|
+
%head
|
3
|
+
%link{:rel => "stylesheet", :href => url_for_screw_asset("screw.css"), :type => "text/css"}
|
4
|
+
|
5
|
+
%body
|
6
|
+
%p Cannot find #{@spec_base_dir}/spec_helper.js.
|
7
|
+
%br
|
8
|
+
%p Please create that file and use it for global test helpers.
|
9
|
+
%p Initially the file should at least require jQuery like this:
|
10
|
+
%br
|
11
|
+
%pre
|
12
|
+
= sample_spec_helper
|
data/views/no_specs.haml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
%html
|
2
|
+
%head
|
3
|
+
%link{:rel => "stylesheet", :href => url_for_screw_asset("screw.css"), :type => "text/css"}
|
4
|
+
|
5
|
+
%body
|
6
|
+
%p The directory #{@spec_base_dir} does not contain any specs.
|
7
|
+
%br
|
8
|
+
%p Create a file #{@spec_base_dir}/foo_spec.js with the following content
|
9
|
+
%br
|
10
|
+
%pre
|
11
|
+
= sample_spec_file
|
data/views/run_spec.haml
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
%html
|
2
|
+
%head
|
3
|
+
%link{:rel => "stylesheet", :href => url_for_screw_asset("screw.css"), :type => "text/css"}
|
4
|
+
|
5
|
+
- required_files.each do |required_file|
|
6
|
+
%script{:type => "text/javascript", :src => cache_busting_url("/#{required_file}")}
|
7
|
+
|
8
|
+
- screw_assets.each do |asset|
|
9
|
+
%script{:type => "text/javascript", :src => url_for_screw_asset(asset)}
|
10
|
+
|
11
|
+
%script{:type => "text/javascript", :src => url_for_spec("spec_helper.js")}
|
12
|
+
|
13
|
+
%script{:type => "text/javascript"}
|
14
|
+
= "fixture_container = #{fixture_html.to_json}"
|
15
|
+
= "Screw.jslint_suites = #{jslint_suites.to_json};"
|
16
|
+
%body
|
17
|
+
%h3#screw_server_loading{:class => "status"}
|
18
|
+
Loading...
|
19
|
+
#fixture_container
|
20
|
+
- @specs.each do |spec|
|
21
|
+
%script{:type => "text/javascript", :src => cache_busting_url(url_for_spec(spec.full_name))}
|
22
|
+
|
23
|
+
%script{:type => "text/javascript", :src => url_for_screw_asset("screw-jslint.js")}
|
24
|
+
|
25
|
+
:javascript
|
26
|
+
$("#screw_server_loading").remove();
|
27
|
+
|
28
|
+
- if @include_monitor_code
|
29
|
+
%script{:type => "text/javascript"}
|
30
|
+
= monitor_code
|