epic 0.0.2 → 0.0.3
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/History.txt +5 -1
- data/VERSION +1 -1
- data/epic.gemspec +9 -4
- data/lib/epic.rb +4 -153
- data/lib/epic/base.rb +49 -0
- data/lib/epic/compressor.rb +126 -0
- data/lib/epic/validator.rb +118 -0
- data/spec/compressor_spec.rb +127 -0
- data/spec/epic_spec.rb +1 -1
- data/vendor/ext/yuicompressor-2.4.2.jar +0 -0
- metadata +7 -2
- data/lib/file.rb +0 -63
data/History.txt
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
data/epic.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{epic}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jeff Coleman"]
|
@@ -30,13 +30,17 @@ Gem::Specification.new do |s|
|
|
30
30
|
"bin/epic",
|
31
31
|
"epic.gemspec",
|
32
32
|
"lib/epic.rb",
|
33
|
-
"lib/
|
33
|
+
"lib/epic/base.rb",
|
34
|
+
"lib/epic/compressor.rb",
|
35
|
+
"lib/epic/validator.rb",
|
36
|
+
"spec/compressor_spec.rb",
|
34
37
|
"spec/epic_spec.rb",
|
35
38
|
"spec/spec.opts",
|
36
39
|
"spec/spec_helper.rb",
|
37
40
|
"spec/stubs.rb",
|
38
41
|
"vendor/ext/js.jar",
|
39
|
-
"vendor/ext/jslint.js"
|
42
|
+
"vendor/ext/jslint.js",
|
43
|
+
"vendor/ext/yuicompressor-2.4.2.jar"
|
40
44
|
]
|
41
45
|
s.homepage = %q{http://github.com/progressions/epic}
|
42
46
|
s.rdoc_options = ["--charset=UTF-8"]
|
@@ -44,7 +48,8 @@ Gem::Specification.new do |s|
|
|
44
48
|
s.rubygems_version = %q{1.3.5}
|
45
49
|
s.summary = %q{Epic validation of HTML, JavaScript and CSS}
|
46
50
|
s.test_files = [
|
47
|
-
"spec/
|
51
|
+
"spec/compressor_spec.rb",
|
52
|
+
"spec/epic_spec.rb",
|
48
53
|
"spec/spec_helper.rb",
|
49
54
|
"spec/stubs.rb"
|
50
55
|
]
|
data/lib/epic.rb
CHANGED
@@ -2,160 +2,11 @@ dir = File.dirname(__FILE__)
|
|
2
2
|
$LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir)
|
3
3
|
|
4
4
|
require 'rubygems'
|
5
|
-
require '
|
5
|
+
require 'f'
|
6
6
|
require 'g'
|
7
7
|
require 'active_support'
|
8
8
|
require 'w3c_validators'
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
attr_accessor :base_path, :tmp_path, :doctype, :jslint_settings
|
14
|
-
end
|
15
|
-
|
16
|
-
class Base
|
17
|
-
class << self
|
18
|
-
def configuration
|
19
|
-
@@configuration ||= Epic::Validator::Configuration.new
|
20
|
-
end
|
21
|
-
|
22
|
-
def configure
|
23
|
-
yield configuration
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def configuration
|
28
|
-
self.class.configuration
|
29
|
-
end
|
30
|
-
|
31
|
-
# Parses out the <tt>base_path</tt> setting from a path to display it in a
|
32
|
-
# less verbose way.
|
33
|
-
#
|
34
|
-
def display_path(path)
|
35
|
-
path = File.expand_path(path)
|
36
|
-
path.gsub(base_path.to_s, "")
|
37
|
-
end
|
38
|
-
|
39
|
-
def base_path
|
40
|
-
configuration.base_path || ""
|
41
|
-
end
|
42
|
-
|
43
|
-
def tmp_path
|
44
|
-
configuration.tmp_path || ""
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
class HTML < Base
|
49
|
-
def validator
|
50
|
-
@validator ||= W3CValidators::MarkupValidator.new
|
51
|
-
end
|
52
|
-
|
53
|
-
def validate(path)
|
54
|
-
$stdout.print " #{path} validating . . . "
|
55
|
-
|
56
|
-
doctype = configuration.doctype || "HTML 4.01 Transitional"
|
57
|
-
validator.set_doctype!(doctype)
|
58
|
-
|
59
|
-
results = validator.validate_file(path)
|
60
|
-
|
61
|
-
valid = results.errors.length <= 0
|
62
|
-
|
63
|
-
if valid
|
64
|
-
$stdout.puts "OK"
|
65
|
-
else
|
66
|
-
$stdout.puts "validation errors"
|
67
|
-
results.errors.each do |err|
|
68
|
-
$stdout.puts
|
69
|
-
$stdout.puts err.to_s
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
valid
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
class JavaScript < Base
|
78
|
-
def use_jslint_settings?
|
79
|
-
!jslint_settings.blank?
|
80
|
-
end
|
81
|
-
|
82
|
-
def jslint_settings
|
83
|
-
configuration.jslint_settings
|
84
|
-
end
|
85
|
-
|
86
|
-
def jslint_settings_count
|
87
|
-
jslint_settings.to_s.split("\n").size
|
88
|
-
end
|
89
|
-
|
90
|
-
def pre_process(content)
|
91
|
-
content
|
92
|
-
end
|
93
|
-
|
94
|
-
def validate(path)
|
95
|
-
display = display_path(path)
|
96
|
-
$stdout.print " #{display} validating . . . "
|
97
|
-
output = ""
|
98
|
-
|
99
|
-
File.open(path) do |f|
|
100
|
-
output = f.read
|
101
|
-
end
|
102
|
-
|
103
|
-
output = pre_process(output)
|
104
|
-
|
105
|
-
FileUtils.mkdir_p(tmp_path)
|
106
|
-
|
107
|
-
js_fragment_path = File.expand_path("#{tmp_path}/#{File.basename(path)}_fragment")
|
108
|
-
fragment_display_path = display_path(js_fragment_path)
|
109
|
-
|
110
|
-
if File.exists?(js_fragment_path)
|
111
|
-
puts "That already exists?"
|
112
|
-
else
|
113
|
-
File.open(js_fragment_path,'w') do |f|
|
114
|
-
f.puts jslint_settings if use_jslint_settings?
|
115
|
-
f.puts output
|
116
|
-
end
|
117
|
-
|
118
|
-
jslint_path = File.expand_path("#{File.dirname(__FILE__)}/../vendor/ext/jslint.js")
|
119
|
-
raise "#{jslint_path} does not exist" unless File.exists?(jslint_path)
|
120
|
-
rhino_path = File.expand_path("#{File.dirname(__FILE__)}/../vendor/ext/js.jar")
|
121
|
-
raise "#{rhino_path} does not exist" unless File.exists?(rhino_path)
|
122
|
-
|
123
|
-
results = F.execute("java -jar #{rhino_path} #{jslint_path} #{js_fragment_path}", :return => true)
|
124
|
-
|
125
|
-
if results =~ /jslint: No problems found/
|
126
|
-
$stdout.puts "OK"
|
127
|
-
else
|
128
|
-
$stdout.puts "errors found!"
|
129
|
-
results.split("\n").each do |result|
|
130
|
-
if result =~ /line (\d+) character (\d+): (.*)/
|
131
|
-
line_number = $1.to_i
|
132
|
-
error = "Error at #{fragment_display_path} line #{line_number-jslint_settings_count} character #{$2}: #{$3}"
|
133
|
-
error += F.get_line_from_file(js_fragment_path, line_number)
|
134
|
-
|
135
|
-
$stdout.puts error
|
136
|
-
end
|
137
|
-
end
|
138
|
-
message = "JavaScript Errors embedded in #{display}"
|
139
|
-
g(message)
|
140
|
-
raise message
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
class JSON < JavaScript
|
147
|
-
def pre_process(output)
|
148
|
-
output
|
149
|
-
end
|
150
|
-
|
151
|
-
def jslint_settings
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
class Stylesheet < Base
|
156
|
-
def validate(filename)
|
157
|
-
true
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
10
|
+
require 'epic/base'
|
11
|
+
require 'epic/validator'
|
12
|
+
require 'epic/compressor'
|
data/lib/epic/base.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Epic #:nodoc
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :base_path, :tmp_path, :doctype, :jslint_settings
|
4
|
+
end
|
5
|
+
|
6
|
+
class Base
|
7
|
+
class << self
|
8
|
+
def configuration
|
9
|
+
@@configuration ||= Epic::Configuration.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def configure
|
13
|
+
yield configuration
|
14
|
+
end
|
15
|
+
|
16
|
+
# Parses out the <tt>base_path</tt> setting from a path to display it in a
|
17
|
+
# less verbose way.
|
18
|
+
#
|
19
|
+
def display_path(path)
|
20
|
+
path = File.expand_path(path)
|
21
|
+
path.gsub(base_path.to_s, "")
|
22
|
+
end
|
23
|
+
|
24
|
+
def base_path
|
25
|
+
configuration.base_path
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def configuration
|
30
|
+
self.class.configuration
|
31
|
+
end
|
32
|
+
|
33
|
+
# Parses out the <tt>base_path</tt> setting from a path to display it in a
|
34
|
+
# less verbose way.
|
35
|
+
#
|
36
|
+
def display_path(path)
|
37
|
+
path = File.expand_path(path)
|
38
|
+
path.gsub(base_path.to_s, "")
|
39
|
+
end
|
40
|
+
|
41
|
+
def base_path
|
42
|
+
configuration.base_path || ""
|
43
|
+
end
|
44
|
+
|
45
|
+
def tmp_path
|
46
|
+
configuration.tmp_path || ""
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module Epic #:nodoc:
|
2
|
+
module Compressor #:nodoc:
|
3
|
+
# Compresses a file using the specified compressor/minifier (currently YUI Compressor 2.4.2).
|
4
|
+
#
|
5
|
+
# === Usage
|
6
|
+
#
|
7
|
+
# Epic::Compressor::Base.compress("filename.js", "type" => "js")
|
8
|
+
#
|
9
|
+
# Epic::Compressor::Base.compress("filename.css", "type" => "css")
|
10
|
+
#
|
11
|
+
# Outputs the compressed file to <tt>_path_.min.</tt>
|
12
|
+
#
|
13
|
+
# === Options
|
14
|
+
#
|
15
|
+
# "type":: "js" or "css". Identifies the file type.
|
16
|
+
#
|
17
|
+
# "obfuscate":: true or false. Change internal variable names within the code.
|
18
|
+
#
|
19
|
+
# "verbose":: true or false. Output warnings about code quality.
|
20
|
+
#
|
21
|
+
# "preserve_semi":: true or false. Preserve unnecessary semicolons.
|
22
|
+
#
|
23
|
+
# TODO: Make it support multiple compressors.
|
24
|
+
#
|
25
|
+
# TODO: Convert it to an object, so you instantiate the Compressor class and then call it
|
26
|
+
# on a file or a string.
|
27
|
+
#
|
28
|
+
# TODO: Get some stringify_keys! action going so you can send in symbols or strings.
|
29
|
+
#
|
30
|
+
class Base < Epic::Base
|
31
|
+
def self.compress(path, options={})
|
32
|
+
options.stringify_keys!
|
33
|
+
compressed_display_path = display_path(path)
|
34
|
+
compressed_path = "#{path}.min"
|
35
|
+
|
36
|
+
options["type"] ||= "js"
|
37
|
+
options["type"] = options["type"].to_s
|
38
|
+
|
39
|
+
# if the compressed_file exists, don't create it again
|
40
|
+
#
|
41
|
+
unless File.exists?(compressed_path)
|
42
|
+
$stdout.print " #{compressed_display_path} compressing . . . "
|
43
|
+
compressed = ''
|
44
|
+
|
45
|
+
# set options and defaults
|
46
|
+
#
|
47
|
+
if options.delete("obfuscate")
|
48
|
+
options["nomunge"] = ""
|
49
|
+
end
|
50
|
+
if options.delete("verbose")
|
51
|
+
options["verbose"] = ""
|
52
|
+
end
|
53
|
+
options["charset"] = "utf-8"
|
54
|
+
|
55
|
+
if options["type"].to_s == "js" && !options["preserve_semi"]
|
56
|
+
options["preserve-semi"] = ""
|
57
|
+
end
|
58
|
+
|
59
|
+
# join the options together for appending to the command line
|
60
|
+
#
|
61
|
+
options_string = options.map {|k,v| "--#{k} #{v}"}.join(" ")
|
62
|
+
|
63
|
+
# call the compressor
|
64
|
+
#
|
65
|
+
compressor_path = File.expand_path("#{File.dirname(__FILE__)}/../../vendor/ext/yuicompressor-2.4.2.jar")
|
66
|
+
raise "#{compressor_path} does not exist" unless File.exists?(compressor_path)
|
67
|
+
|
68
|
+
command = "java -jar #{compressor_path} #{options_string} #{path} -o #{compressed_path} 2>&1"
|
69
|
+
result = F.execute(command, :return => true)
|
70
|
+
|
71
|
+
result.split("\n").each do |line|
|
72
|
+
if line =~ /\[ERROR\] (\d+):(\d+):(.*)/
|
73
|
+
line_number = $1.to_i
|
74
|
+
error = "Error at #{compressed_display_path} line #{line_number} character #{$2}: #{$3}"
|
75
|
+
error += F.get_line_from_file(path, line_number)
|
76
|
+
|
77
|
+
$stdout.puts error
|
78
|
+
g(error)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
if result =~ /ERROR/
|
83
|
+
raise "JavaScript errors in #{compressed_display_path}"
|
84
|
+
else
|
85
|
+
$stdout.puts "OK"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# The compressed file should exist now. If it does, use it. If not, raise an error.
|
90
|
+
#
|
91
|
+
if File.exists?(compressed_path)
|
92
|
+
compressed = File.read(compressed_path)
|
93
|
+
else
|
94
|
+
raise "File does not exist: #{compressed_display_path}"
|
95
|
+
end
|
96
|
+
|
97
|
+
compressed
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Compresses a CSS file using the specified compressor/minifier (currently YUI Compressor 2.4.2).
|
102
|
+
#
|
103
|
+
# === Usage
|
104
|
+
#
|
105
|
+
# Epic::Compressor::Stylesheet.compress("filename.css")
|
106
|
+
#
|
107
|
+
class Stylesheet < Base
|
108
|
+
def self.compress(path)
|
109
|
+
super(path, "type" => "css")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Compresses a JavaScript file using the specified compressor/minifier (currently YUI Compressor 2.4.2).
|
114
|
+
#
|
115
|
+
# === Usage
|
116
|
+
#
|
117
|
+
# Epic::Compressor::JavaScript.compress("filename.js")
|
118
|
+
#
|
119
|
+
class JavaScript < Base
|
120
|
+
# TODO: Add options hash
|
121
|
+
def self.compress(filename)
|
122
|
+
super(filename, "type" => "js")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'epic/base'
|
2
|
+
|
3
|
+
module Epic
|
4
|
+
module Validator
|
5
|
+
class HTML < Epic::Base
|
6
|
+
def validator
|
7
|
+
@validator ||= W3CValidators::MarkupValidator.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate(path)
|
11
|
+
$stdout.print " #{path} validating . . . "
|
12
|
+
|
13
|
+
doctype = configuration.doctype || "HTML 4.01 Transitional"
|
14
|
+
validator.set_doctype!(doctype)
|
15
|
+
|
16
|
+
results = validator.validate_file(path)
|
17
|
+
|
18
|
+
valid = results.errors.length <= 0
|
19
|
+
|
20
|
+
if valid
|
21
|
+
$stdout.puts "OK"
|
22
|
+
else
|
23
|
+
$stdout.puts "validation errors"
|
24
|
+
results.errors.each do |err|
|
25
|
+
$stdout.puts
|
26
|
+
$stdout.puts err.to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
valid
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class JavaScript < Base
|
35
|
+
def use_jslint_settings?
|
36
|
+
!jslint_settings.blank?
|
37
|
+
end
|
38
|
+
|
39
|
+
def jslint_settings
|
40
|
+
configuration.jslint_settings
|
41
|
+
end
|
42
|
+
|
43
|
+
def jslint_settings_count
|
44
|
+
jslint_settings.to_s.split("\n").size
|
45
|
+
end
|
46
|
+
|
47
|
+
def pre_process(content)
|
48
|
+
content
|
49
|
+
end
|
50
|
+
|
51
|
+
def validate(path)
|
52
|
+
display = display_path(path)
|
53
|
+
$stdout.print " #{display} validating . . . "
|
54
|
+
output = ""
|
55
|
+
|
56
|
+
File.open(path) do |f|
|
57
|
+
output = f.read
|
58
|
+
end
|
59
|
+
|
60
|
+
output = pre_process(output)
|
61
|
+
|
62
|
+
FileUtils.mkdir_p(tmp_path)
|
63
|
+
|
64
|
+
js_fragment_path = File.expand_path("#{tmp_path}/#{File.basename(path)}_fragment")
|
65
|
+
fragment_display_path = display_path(js_fragment_path)
|
66
|
+
|
67
|
+
if File.exists?(js_fragment_path)
|
68
|
+
puts "That already exists?"
|
69
|
+
else
|
70
|
+
File.open(js_fragment_path,'w') do |f|
|
71
|
+
f.puts jslint_settings if use_jslint_settings?
|
72
|
+
f.puts output
|
73
|
+
end
|
74
|
+
|
75
|
+
jslint_path = File.expand_path("#{File.dirname(__FILE__)}/../../vendor/ext/jslint.js")
|
76
|
+
raise "#{jslint_path} does not exist" unless File.exists?(jslint_path)
|
77
|
+
rhino_path = File.expand_path("#{File.dirname(__FILE__)}/../../vendor/ext/js.jar")
|
78
|
+
raise "#{rhino_path} does not exist" unless File.exists?(rhino_path)
|
79
|
+
|
80
|
+
results = F.execute("java -jar #{rhino_path} #{jslint_path} #{js_fragment_path}", :return => true)
|
81
|
+
|
82
|
+
if results =~ /jslint: No problems found/
|
83
|
+
$stdout.puts "OK"
|
84
|
+
else
|
85
|
+
$stdout.puts "errors found!"
|
86
|
+
results.split("\n").each do |result|
|
87
|
+
if result =~ /line (\d+) character (\d+): (.*)/
|
88
|
+
line_number = $1.to_i
|
89
|
+
error = "Error at #{fragment_display_path} line #{line_number-jslint_settings_count} character #{$2}: #{$3}"
|
90
|
+
error += F.get_line_from_file(js_fragment_path, line_number)
|
91
|
+
|
92
|
+
$stdout.puts error
|
93
|
+
end
|
94
|
+
end
|
95
|
+
message = "JavaScript Errors embedded in #{display}"
|
96
|
+
g(message)
|
97
|
+
raise message
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class JSON < JavaScript
|
104
|
+
def pre_process(output)
|
105
|
+
output
|
106
|
+
end
|
107
|
+
|
108
|
+
def jslint_settings
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
class Stylesheet < Base
|
113
|
+
def validate(filename)
|
114
|
+
true
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Compressor" do
|
4
|
+
before(:each) do
|
5
|
+
stub_io
|
6
|
+
File.stub!(:exists?).with(/yuicompressor/).and_return(true)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "Base" do
|
10
|
+
it "should use the compressed file if it already exists" do
|
11
|
+
File.stub!(:exists?).with(/file.js/).and_return(true)
|
12
|
+
@file = "compressed file"
|
13
|
+
File.stub(:read).and_return(@file)
|
14
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js").should == @file
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "generate a compressed file if one doesn't exist" do
|
18
|
+
before(:each) do
|
19
|
+
File.stub!(:exists?).with(/file.js/).and_return(false, true)
|
20
|
+
File.stub!(:exists?).with(/file.css/).and_return(false, true)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should log what it's doing" do
|
24
|
+
$stdout.should_receive(:print).with(/file.js compressing . . ./)
|
25
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should run the compressor" do
|
29
|
+
F.should_receive(:execute).with(/yuicompressor/, :return => true).and_return("")
|
30
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js")
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "options" do
|
34
|
+
it "should set nomunge" do
|
35
|
+
F.should_receive(:execute).with(/nomunge/, :return => true).and_return("")
|
36
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js", "obfuscate" => true)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should not set nomunge" do
|
40
|
+
F.stub!(:execute).with(/yuicompressor/, :return => true).and_return("")
|
41
|
+
F.should_not_receive(:execute).with(/nomunge/, :return => true).and_return("")
|
42
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js", "obfuscate" => false)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should set verbose" do
|
46
|
+
F.should_receive(:execute).with(/verbose/, :return => true).and_return("")
|
47
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js", "verbose" => true)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should not set verbose" do
|
51
|
+
F.stub!(:execute).with(/yuicompressor/, :return => true).and_return("")
|
52
|
+
F.should_not_receive(:execute).with(/verbose/, :return => true).and_return("")
|
53
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js", "verbose" => false)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should set preserve-semi on javascript" do
|
57
|
+
F.should_receive(:execute).with(/preserve-semi/, :return => true).and_return("")
|
58
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js")
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should not set preserve-semi on css" do
|
62
|
+
File.stub!(:exists?).with(/file.css/).and_return(true)
|
63
|
+
F.stub!(:execute).with(/yuicompressor/, :return => true).and_return("")
|
64
|
+
F.should_not_receive(:execute).with(/preserve-semi/, :return => true).and_return("")
|
65
|
+
Epic::Compressor::Base.compress("file.css", "type" => "css")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "on errors" do
|
70
|
+
before(:each) do
|
71
|
+
F.stub!(:execute).with(/yuicompressor/, :return => true).and_return("[ERROR] 12:13: Too much fruzzlegump")
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should raise an exception" do
|
75
|
+
lambda {
|
76
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js")
|
77
|
+
}.should raise_error(/JavaScript errors/)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should growl" do
|
81
|
+
@g.should_receive(:notify)
|
82
|
+
lambda {
|
83
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js")
|
84
|
+
}.should raise_error(/JavaScript errors/)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should show the source code" do
|
88
|
+
F.should_receive(:get_line_from_file).with("file.js", 12).and_return("")
|
89
|
+
lambda {
|
90
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js")
|
91
|
+
}.should raise_error(/JavaScript errors/)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should report OK" do
|
96
|
+
$stdout.should_receive(:puts).with("OK")
|
97
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js")
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should raise an error if the compressed file doesn't exist" do
|
101
|
+
# File.stub!(:exists?).with(/file.js/).and_return(true)
|
102
|
+
# File.stub!(:exists?).with(/file.js.min/).and_return(false)
|
103
|
+
# lambda {
|
104
|
+
Epic::Compressor::Base.compress("file.js", "type" => "js")
|
105
|
+
# }.should raise_error(/File does not exist/)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "JavaScript" do
|
111
|
+
it "should call Base with type js" do
|
112
|
+
File.stub(:exists?).with(/file.js/).and_return(true)
|
113
|
+
@file = "compressed file"
|
114
|
+
File.stub(:read).and_return(@file)
|
115
|
+
Epic::Compressor::JavaScript.compress("file.js").should == @file
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "Stylesheet" do
|
120
|
+
it "should call Base with type css" do
|
121
|
+
File.stub(:exists?).with(/file.css/).and_return(true)
|
122
|
+
@file = "compressed file"
|
123
|
+
File.stub(:read).and_return(@file)
|
124
|
+
Epic::Compressor::Stylesheet.compress("file.css").should == @file
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/spec/epic_spec.rb
CHANGED
@@ -81,7 +81,7 @@ describe "Validator" do
|
|
81
81
|
end
|
82
82
|
|
83
83
|
it "should set jslint settings" do
|
84
|
-
Epic::
|
84
|
+
Epic::Base.configure do |config|
|
85
85
|
config.jslint_settings = @jslint_settings
|
86
86
|
end
|
87
87
|
Epic::Validator::JavaScript.new.jslint_settings.should == @jslint_settings
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: epic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Coleman
|
@@ -63,13 +63,17 @@ files:
|
|
63
63
|
- bin/epic
|
64
64
|
- epic.gemspec
|
65
65
|
- lib/epic.rb
|
66
|
-
- lib/
|
66
|
+
- lib/epic/base.rb
|
67
|
+
- lib/epic/compressor.rb
|
68
|
+
- lib/epic/validator.rb
|
69
|
+
- spec/compressor_spec.rb
|
67
70
|
- spec/epic_spec.rb
|
68
71
|
- spec/spec.opts
|
69
72
|
- spec/spec_helper.rb
|
70
73
|
- spec/stubs.rb
|
71
74
|
- vendor/ext/js.jar
|
72
75
|
- vendor/ext/jslint.js
|
76
|
+
- vendor/ext/yuicompressor-2.4.2.jar
|
73
77
|
has_rdoc: true
|
74
78
|
homepage: http://github.com/progressions/epic
|
75
79
|
licenses: []
|
@@ -99,6 +103,7 @@ signing_key:
|
|
99
103
|
specification_version: 3
|
100
104
|
summary: Epic validation of HTML, JavaScript and CSS
|
101
105
|
test_files:
|
106
|
+
- spec/compressor_spec.rb
|
102
107
|
- spec/epic_spec.rb
|
103
108
|
- spec/spec_helper.rb
|
104
109
|
- spec/stubs.rb
|
data/lib/file.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
# Provides a wrapper around common calls that interact with the file system.
|
2
|
-
#
|
3
|
-
module F
|
4
|
-
|
5
|
-
module_function
|
6
|
-
|
7
|
-
# Concatenates together the contents of all the files in the <tt>source_path</tt>
|
8
|
-
# into the <tt>destination_path</tt>.
|
9
|
-
#
|
10
|
-
def concat_files(source_path, destination_path)
|
11
|
-
File.open(destination_path, "a") do |output|
|
12
|
-
Dir[source_path].each do |path|
|
13
|
-
output.puts File.read(path)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# Saves the <tt>output</tt> string to the <tt>destination_path</tt> given.
|
19
|
-
#
|
20
|
-
# Returns <tt>true</tt> if the destination file was newly created, <tt>false</tt> if
|
21
|
-
# it already existed.
|
22
|
-
#
|
23
|
-
def save_to_file(output, destination_path)
|
24
|
-
if File.exists?(destination_path)
|
25
|
-
false
|
26
|
-
else
|
27
|
-
File.open(destination_path, "w") do |w|
|
28
|
-
w.write(output)
|
29
|
-
end
|
30
|
-
true
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# Given a <tt>path</tt> and <tt>line_number</tt>, returns the line and two lines previous
|
35
|
-
#
|
36
|
-
# Used for displaying validation errors.
|
37
|
-
#
|
38
|
-
def get_line_from_file(path, line_number)
|
39
|
-
line_number = line_number.to_i
|
40
|
-
output = "\n"
|
41
|
-
lines = File.readlines(path)
|
42
|
-
|
43
|
-
3.times do |i|
|
44
|
-
line = lines[line_number-(3-i)]
|
45
|
-
output += line if line
|
46
|
-
end
|
47
|
-
|
48
|
-
output += "\n"
|
49
|
-
output
|
50
|
-
end
|
51
|
-
|
52
|
-
# Execute a system command. If the parameter <tt>:return</tt> is true, execute the command
|
53
|
-
# with the backtick (`) command and return the results. Otherwise, just execute the command
|
54
|
-
# and let the output go to the screen.
|
55
|
-
#
|
56
|
-
def execute(command, params={})
|
57
|
-
if params[:return]
|
58
|
-
`#{command}`
|
59
|
-
else
|
60
|
-
Kernel.system command
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|