slinky 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 889ff2fbc318014fa07dc0a6b6ec58f6836e8154
4
- data.tar.gz: e9ae1e023ceeb1f07ce8c8950f279a52d1f6e048
3
+ metadata.gz: b1e4131531f13a7e59d8af244621759990a0e195
4
+ data.tar.gz: c8fc44e9a92a3344c896b6aec2ace9eec058e552
5
5
  SHA512:
6
- metadata.gz: 4b072781ffd19338d0685a2bf3cd0d25545343ec88d92de5aa3463afbcf992b23034639ad3792efe47a510d6db371fbd2d6cc9a4c2e9cc2078bae9d3cd98b513
7
- data.tar.gz: 9ea118ef3f70d8708fa85547029ffec8023b798e09ca8dc701111927c634bdb0a96ad8ec660070bcada4c6933dd83dc06faab7e6462024884bb6cd08fee938de
6
+ metadata.gz: 23db4994117d3d0a118ae014920f15a84848fd9239e3f8fa012fd378ba02ee8d745a0bdca8018bfd3546284f04031759724dbd6589f97e46e78302c754a74bb7
7
+ data.tar.gz: bdbf6cf9ada64a30b0044a8c363638588ebcda0c048a7228a7ba7566507074c02a191df588d713934ea728338dece776616a88272cbaae778d2786eb2ad39c5a
data/Gemfile CHANGED
@@ -22,4 +22,8 @@ group :development do
22
22
  gem "jeweler", "~> 1.8"
23
23
  gem "fakefs", '~> 0.5', :require => "fakefs/safe"
24
24
  gem "em-http-request", '~> 1.0'
25
+ gem 'simplecov'
26
+ # optional compilation gems
27
+ gem "less", ">= 2.2.0"
28
+ gem "therubyracer" # for less
25
29
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.1
1
+ 0.7.2
@@ -4,7 +4,7 @@ module Slinky
4
4
  class CompiledFile
5
5
  attr_accessor :source, :print_name, :output_path
6
6
  attr_reader :last_compiled, :output_ext
7
-
7
+
8
8
  # Creates a new CompiledFile, compiling the provided source file
9
9
  # with the provided compiler class.
10
10
  def initialize source, compiler, output_ext
@@ -36,7 +36,7 @@ module Slinky
36
36
  out = File.open @source do |f|
37
37
  @compiler.compile f.read, @source
38
38
  end
39
-
39
+
40
40
  compile_succeeded
41
41
  File.open(path, "w+") do |f|
42
42
  f.write out
@@ -6,7 +6,10 @@ module Slinky
6
6
  :dependencies => [["sass", ">= 3.1.1"]]
7
7
 
8
8
  def SassCompiler::compile s, file
9
- sass_engine = Sass::Engine.new(s, :load_paths => [File.dirname(file)])
9
+ syntax = file.end_with?(".sass") ? :sass : :scss
10
+ sass_engine = Sass::Engine.new(s,
11
+ :syntax => syntax,
12
+ :load_paths => [File.dirname(file)])
10
13
  sass_engine.render
11
14
  end
12
15
  end
@@ -2,7 +2,7 @@ require 'set'
2
2
 
3
3
  module Slinky
4
4
  EXTENSION_REGEX = /(.+)\.(\w+)/
5
-
5
+
6
6
  class Compilers
7
7
  @compilers = []
8
8
  @compilers_by_ext = {}
@@ -50,7 +50,7 @@ module Slinky
50
50
  end
51
51
  }
52
52
  end
53
-
53
+
54
54
  # Produces a CompiledFile for an input file if the file needs to
55
55
  # be compiled, or nil otherwise. Note that path is the path of
56
56
  # the compiled file, so script.js not script.coffee.
@@ -1,60 +1,77 @@
1
1
  module Slinky
2
- class ConfigReader
3
- def self.from_file path
4
- new File.open(path).read
5
- end
2
+ # Raised when reading an invalid configuraiton
3
+ class InvalidConfigError < StandardError; end
6
4
 
7
- def self.empty
8
- new "{}"
9
- end
10
-
11
- def initialize string
12
- @config = YAML::load(string)
13
- end
14
-
15
- def proxies
16
- @config["proxy"] || {}
17
- end
5
+ class ConfigReader
6
+ HASH_TYPE = "hash"
7
+ ARRAY_TYPE = "array"
8
+ STRING_TYPE = "string"
9
+ NUMBER_TYPE = "number"
10
+ BOOL_TYPE = "bool"
11
+ ANY_TYPE = "any"
18
12
 
19
- def ignores
20
- @config["ignore"] || []
13
+ class ConfigEntry
14
+ attr_reader :type, :name, :default
15
+ def initialize(name, type, default)
16
+ @name = name
17
+ @type = type
18
+ @default = default
19
+ end
21
20
  end
22
21
 
23
- def port
24
- @config["port"] || 5323
25
- end
22
+ @entries = [
23
+ ConfigEntry.new("proxy", HASH_TYPE, {}),
24
+ ConfigEntry.new("ignore", ARRAY_TYPE, []),
25
+ ConfigEntry.new("port", NUMBER_TYPE, 5323),
26
+ ConfigEntry.new("src_dir", STRING_TYPE, "."),
27
+ ConfigEntry.new("build_dir", STRING_TYPE, "."),
28
+ ConfigEntry.new("no_proxy", BOOL_TYPE, false),
29
+ ConfigEntry.new("no_livereload", BOOL_TYPE, false),
30
+ ConfigEntry.new("livereload_port", NUMBER_TYPE, 35729),
31
+ ConfigEntry.new("dont_minify", BOOL_TYPE, false),
32
+ ConfigEntry.new("pushstate", ANY_TYPE, []),
33
+ ]
26
34
 
27
- def src_dir
28
- @config["src_dir"] || "."
29
- end
35
+ @entries.each{|e|
36
+ self.class_eval %{
37
+ def #{e.name}
38
+ @config["#{e.name}"] || #{e.default.inspect}
39
+ end
40
+ }
41
+ }
30
42
 
31
- def build_dir
32
- @config["build_dir"] || "build"
43
+ def self.from_file path
44
+ new File.open(path).read
33
45
  end
34
46
 
35
- def no_proxy
36
- @config["no_proxy"] || false
37
- end
38
-
39
- def no_livereload
40
- @config["no_livereload"] || false
47
+ def self.empty
48
+ new "{}"
41
49
  end
42
50
 
43
- def livereload_port
44
- @config["livereload_port"] || 35729
45
- end
51
+ # Validates whether a supplied hash is well-formed according to
52
+ # the allowed entries
53
+ def self.validate config
54
+ entries = {}
55
+ @entries.each{|e| entries[e.name] = e}
56
+ errors = config.map{|k, v|
57
+ if !entries[k]
58
+ " * '#{k}' is not an allowed configuration key"
59
+ end
60
+ }.compact
46
61
 
47
- def dont_minify
48
- @config["dont_minify"] || false
62
+ if !errors.empty?
63
+ raise InvalidConfigError.new(errors.join("\n"))
64
+ end
49
65
  end
50
66
 
51
- def pushstates
52
- @config["pushstate"]
67
+ def initialize string
68
+ @config = YAML::load(string)
69
+ ConfigReader.validate(@config)
53
70
  end
54
71
 
55
72
  def pushstate_for_path path
56
- if pushstates && pushstates.is_a?(Hash)
57
- p = pushstates.sort_by{|from, to| -from.count("/")}.find{|a|
73
+ if pushstate && pushstate.is_a?(Hash)
74
+ p = pushstate.sort_by{|from, to| -from.count("/")}.find{|a|
58
75
  path.start_with? a[0]
59
76
  }
60
77
  p[1] if p
@@ -22,16 +22,16 @@ module EventMachine
22
22
  EM.attach rd, Popen3StderrHandler, connection
23
23
  connection
24
24
  end
25
-
25
+
26
26
  class Popen3StderrHandler < EventMachine::Connection
27
27
  def initialize(connection)
28
28
  @connection = connection
29
29
  end
30
-
30
+
31
31
  def receive_data(data)
32
32
  @connection.receive_stderr(data)
33
33
  end
34
- end
34
+ end
35
35
  end
36
36
 
37
37
  class ProcessHandler < EventMachine::Connection
@@ -48,7 +48,7 @@ class ProcessHandler < EventMachine::Connection
48
48
  def receive_stderr data
49
49
  @stderr << data
50
50
  end
51
-
51
+
52
52
  def unbind
53
53
  @cb.call @stdout.join(''), @stderr.join(''), get_status if @cb
54
54
  end
@@ -8,11 +8,14 @@ module Slinky
8
8
  end
9
9
 
10
10
  def run
11
+ manifest_md5 = @manifest.md5
11
12
  listener = Listen.to(@manifest.dir) do |mod, add, rem|
12
- handle_mod(mod) if mod.size > 0
13
- handle_add(add) if add.size > 0
14
13
 
15
14
  EM.next_tick {
15
+ handle_mod(mod) if mod.size > 0
16
+ handle_add(add) if add.size > 0
17
+ handle_rem(rem) if rem.size > 0
18
+
16
19
  files = (mod + add + rem).map{|path|
17
20
  mpath = Pathname.new(path)\
18
21
  .relative_path_from(Pathname.new(@manifest.dir).expand_path).to_s
@@ -23,34 +26,28 @@ module Slinky
23
26
  path
24
27
  end
25
28
  }
26
- @livereload.reload_browser(files)
27
- } if @livereload
28
29
 
29
- handle_rem(rem) if rem.size > 0
30
+ # only reload if something's actually changed
31
+ if manifest_md5 != @manifest.md5
32
+ manifest_md5 = @manifest.md5
33
+ @livereload.reload_browser(files)
34
+ end
35
+ } if @livereload
30
36
  end
31
37
  listener.start
32
38
  listener
33
39
  end
34
40
 
35
41
  def handle_mod files
42
+ @manifest.update_all_by_path files rescue nil
36
43
  end
37
-
44
+
38
45
  def handle_add files
39
- EM.next_tick {
40
- begin
41
- @manifest.add_all_by_path files
42
- rescue
43
- end
44
- }
46
+ @manifest.add_all_by_path files rescue nil
45
47
  end
46
48
 
47
49
  def handle_rem files
48
- EM.next_tick {
49
- begin
50
- @manifest.remove_all_by_path files
51
- rescue
52
- end
53
- }
50
+ @manifest.remove_all_by_path files rescue nil
54
51
  end
55
52
  end
56
53
  end
@@ -17,7 +17,6 @@ module Slinky
17
17
  EventMachine::WebSocket::Connection, {}) do |ws|
18
18
  ws.onopen do
19
19
  begin
20
- $stdout.puts "Browser connected to livereload server"
21
20
  ws.send "!!ver:1.6"
22
21
  @websockets << ws
23
22
  rescue
@@ -27,7 +26,6 @@ module Slinky
27
26
 
28
27
  ws.onclose do
29
28
  @websockets.delete ws
30
- $stdout.puts "Browser disconnected"
31
29
  end
32
30
  end
33
31
  $stdout.puts "Started live-reload server on port #{@port}"
@@ -22,7 +22,7 @@ module Slinky
22
22
  # Raised when there is a cycle in the dependency graph (i.e., file A
23
23
  # requires file B which requires C which requires A)
24
24
  class DependencyError < StandardError; end
25
-
25
+
26
26
  class Manifest
27
27
  attr_accessor :manifest_dir, :dir
28
28
 
@@ -50,7 +50,7 @@ module Slinky
50
50
  if include_ignores
51
51
  @files
52
52
  else
53
- @files.reject{|f| @config.ignores.any?{|p| f.in_tree? p}}
53
+ @files.reject{|f| @config.ignore.any?{|p| f.in_tree? p}}
54
54
  end
55
55
  end
56
56
 
@@ -62,14 +62,23 @@ module Slinky
62
62
  end
63
63
  end
64
64
 
65
+ # Notifies of an update to a file in the manifest
66
+ def update_all_by_path paths
67
+ manifest_update paths do |path|
68
+ md = find_by_path(File.dirname(path)).first
69
+ if mf = find_by_path(path).first
70
+ mf.parent.remove_file(mf)
71
+ end
72
+ md.add_file(File.basename(path))
73
+ end
74
+ end
75
+
65
76
  # Removes a file from the manifest
66
77
  def remove_all_by_path paths
67
78
  manifest_update paths do |path|
68
79
  mf = find_by_path(path).first()
69
- begin
80
+ if mf
70
81
  mf.parent.remove_file(mf)
71
- rescue
72
- puts "Failed to remove <#{path}>"
73
82
  end
74
83
  end
75
84
  end
@@ -86,9 +95,9 @@ module Slinky
86
95
 
87
96
  def scripts_string
88
97
  if @devel
89
- dependency_list.reject{|x| x.output_path.extname != ".js"}.collect{|d|
98
+ dependency_list.reject{|x| x.output_path.extname != ".js" }.collect{|d|
90
99
  %Q\<script type="text/javascript" src="/#{d.relative_output_path}"></script>\
91
- }.join("")
100
+ }.join("\n")
92
101
  else
93
102
  %Q\<script type="text/javascript" src="/scripts.js?#{rand(999999999)}"></script>\
94
103
  end
@@ -113,7 +122,7 @@ module Slinky
113
122
  scripts.collect{|s| FileUtils.rm(s.build_to)}
114
123
  end
115
124
  end
116
-
125
+
117
126
  def compress_scripts
118
127
  compressor = YUI::JavaScriptCompressor.new(:munge => false)
119
128
  compress(".js", "#{@build_to}/scripts.js", compressor)
@@ -134,7 +143,7 @@ module Slinky
134
143
  if @devel
135
144
  dependency_list.reject{|x| x.output_path.extname != ".css"}.collect{|d|
136
145
  %Q\<link rel="stylesheet" href="/#{d.relative_output_path}" />\
137
- }.join("")
146
+ }.join("\n")
138
147
  else
139
148
  %Q\<link rel="stylesheet" href="/styles.css?#{rand(999999999)}" />\
140
149
  end
@@ -202,6 +211,18 @@ module Slinky
202
211
  end
203
212
  end
204
213
 
214
+ # Returns a md5 encompassing the current state of the manifest.
215
+ # Any change to the manifest should produce a different hash.
216
+ # This can be used to determine if the manifest has changed.
217
+ def md5
218
+ if @md5
219
+ @md5
220
+ else
221
+ @md5 = Digest::MD5.hexdigest(files.map{|f| [f.source, f.md5]}
222
+ .sort.flatten.join(":"))
223
+ end
224
+ end
225
+
205
226
  private
206
227
  def files_rec md
207
228
  @files += md.files
@@ -213,6 +234,7 @@ module Slinky
213
234
  def invalidate_cache
214
235
  @files = nil
215
236
  @dependency_graph = nil
237
+ @md5 = nil
216
238
  end
217
239
 
218
240
  def manifest_update paths
@@ -305,15 +327,20 @@ module Slinky
305
327
  md
306
328
  end
307
329
  end
308
-
330
+
309
331
  # Adds a file on the filesystem to the manifest
310
332
  #
311
333
  # @param String path The path of the file
312
334
  def add_file path
313
335
  file = File.basename(path)
314
- full_path = [@dir, file].join(File::SEPARATOR)
315
- if File.exists? full_path
336
+ full_path = Pathname.new(@dir).join(file).to_s
337
+ if File.exists?(full_path) && !file.start_with?(".")
316
338
  mf = ManifestFile.new(full_path, @build_dir, @manifest, self)
339
+ # we don't want two files with the same source
340
+ extant_file = @files.find{|f| f.source == mf.source}
341
+ if extant_file
342
+ @files.delete(extant_file)
343
+ end
317
344
  @files << mf
318
345
  mf
319
346
  end
@@ -325,7 +352,7 @@ module Slinky
325
352
  def remove_file mf
326
353
  @files.delete(mf)
327
354
  end
328
-
355
+
329
356
  def build
330
357
  unless File.directory?(@build_dir.to_s)
331
358
  FileUtils.mkdir(@build_dir.to_s)
@@ -397,11 +424,10 @@ module Slinky
397
424
  # Predicate which determines whether the file is the supplied path
398
425
  # or lies on supplied tree
399
426
  def in_tree? path
400
- return true if matches? path
401
- abs_path = Pathname.new(path).expand_path.to_s
402
- asdf = Pathname.new(@source).dirname.expand_path.to_s
403
- # puts [abs_path, asdf, asdf.start_with?(abs_path), abs_path == asdf].inspect
404
- asdf.start_with?(abs_path)
427
+ full_path = @manifest.dir + "/" + path
428
+ abs_path = Pathname.new(full_path).expand_path.to_s
429
+ dir = Pathname.new(@source).dirname.expand_path.to_s
430
+ dir.start_with?(abs_path) || abs_path == @source
405
431
  end
406
432
 
407
433
  # Returns the path to which this file should be output. This is
@@ -418,6 +444,11 @@ module Slinky
418
444
  end
419
445
  end
420
446
 
447
+ # returns the source path relative to the manifest directory
448
+ def relative_source_path
449
+ Pathname.new(@source).relative_path_from Pathname.new(@manifest.dir)
450
+ end
451
+
421
452
  # Returns the output path relative to the manifest directory
422
453
  def relative_output_path
423
454
  output_path.relative_path_from Pathname.new(@manifest.dir)
@@ -495,7 +526,7 @@ module Slinky
495
526
  # @param String path to which the file should be compiled
496
527
  #
497
528
  # @return String the path of the processed file, ready for serving
498
- def process to = nil
529
+ def process to = nil, should_compile = true
499
530
  return if @processing # prevent infinite recursion
500
531
  start_time = Time.now
501
532
  hash = md5
@@ -522,7 +553,8 @@ module Slinky
522
553
  @last_md5 = hash
523
554
  @updated = Time.now
524
555
  # mangle file appropriately
525
- @last_path = handle_directives((compile @source), to)
556
+ f = should_compile ? (compile @source) : @source
557
+ @last_path = handle_directives(f, to)
526
558
  end
527
559
  end
528
560
 
@@ -2,7 +2,7 @@ module Slinky
2
2
  module ProxyServer
3
3
  HTTP_MATCHER = /(GET|POST|PUT|DELETE|HEAD) (.+?)(?= HTTP)/
4
4
  HOST_MATCHER = /Host: (.+)/
5
-
5
+
6
6
  def self.process_proxies proxy_hash
7
7
  proxy_hash.map{|from, h|
8
8
  begin
@@ -23,7 +23,7 @@ module Slinky
23
23
  end
24
24
 
25
25
  def self.rewrite_path path, proxy
26
- path.gsub(/^#{proxy[0]}/, "")
26
+ path.gsub(/^#{proxy[0]}/, "")
27
27
  end
28
28
 
29
29
  def self.replace_path http, old_path, new_path, addition
data/lib/slinky/runner.rb CHANGED
@@ -19,11 +19,18 @@ module Slinky
19
19
  @arguments = @argv
20
20
 
21
21
  config_path = @options[:config] || "#{@options[:src_dir] || "."}/slinky.yaml"
22
- @config = if File.exist?(config_path)
23
- ConfigReader.from_file(config_path)
24
- else
25
- ConfigReader.empty
26
- end
22
+ begin
23
+ @config = if File.exist?(config_path)
24
+ ConfigReader.from_file(config_path)
25
+ else
26
+ ConfigReader.empty
27
+ end
28
+ rescue InvalidConfigError => e
29
+ $stderr.puts("The configuration file at #{config_path} is invalid:".foreground(:red))
30
+ $stderr.puts(e.message.foreground(:red))
31
+ exit(1)
32
+ end
33
+
27
34
  end
28
35
 
29
36
  def version
@@ -72,9 +79,9 @@ module Slinky
72
79
  port = @options[:port] || @config.port
73
80
 
74
81
  should_proxy = !(@config.no_proxy || @options[:no_proxy])
75
- if !@config.proxies.empty? && should_proxy
82
+ if !@config.proxy.empty? && should_proxy
76
83
  server = EM::start_server "127.0.0.1", port+1, Slinky::Server
77
- ProxyServer.run(@config.proxies, port, port+1)
84
+ ProxyServer.run(@config.proxy, port, port+1)
78
85
  else
79
86
  EM::start_server "127.0.0.1", port, Slinky::Server
80
87
  end
data/lib/slinky/server.rb CHANGED
@@ -42,16 +42,13 @@ module Slinky
42
42
  path += "/index.html"
43
43
  end
44
44
 
45
- resp.content_type MIME::Types.type_for(path).first
45
+ resp.content_type MIME::Types.type_for(path).first.to_s
46
46
 
47
47
  if file
48
- if file.source.end_with?(path)
49
- # They're requesting the source file and we should just
50
- # return it
51
- serve_file(resp, file.source)
52
- else
53
- handle_file(resp, file)
54
- end
48
+ # They're requesting the source file and we should not
49
+ # compile it (but still process directives)
50
+ compile = !(file.source.end_with?(path) && file.source)
51
+ handle_file(resp, file, compile)
55
52
  elsif !pushstate && p = config.pushstate_for_path("/" + path)
56
53
  path = p[0] == "/" ? p[1..-1] : p
57
54
  self.process_path(resp, path, true)
@@ -62,9 +59,9 @@ module Slinky
62
59
  end
63
60
 
64
61
  # Takes a manifest file and produces a response for it
65
- def self.handle_file resp, mf
62
+ def self.handle_file resp, mf, compile = true
66
63
  begin
67
- if path = mf.process
64
+ if path = mf.process(nil, compile)
68
65
  serve_file resp, path.to_s
69
66
  else
70
67
  raise StandardError.new
data/slinky.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: slinky 0.7.1 ruby lib
5
+ # stub: slinky 0.7.2 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "slinky"
9
- s.version = "0.7.1"
9
+ s.version = "0.7.2"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Micah Wylde"]
14
- s.date = "2014-03-30"
14
+ s.date = "2014-04-10"
15
15
  s.description = "A static file server for rich web apps that automatically compiles SASS, HAML, CoffeeScript and more"
16
16
  s.email = "micah@micahw.com"
17
17
  s.executables = ["slinky"]
@@ -47,6 +47,7 @@ Gem::Specification.new do |s|
47
47
  "lib/slinky/runner.rb",
48
48
  "lib/slinky/server.rb",
49
49
  "slinky.gemspec",
50
+ "spec/compilers_spec.rb",
50
51
  "spec/slinky_spec.rb",
51
52
  "spec/spec_helper.rb"
52
53
  ]
@@ -76,6 +77,9 @@ Gem::Specification.new do |s|
76
77
  s.add_development_dependency(%q<jeweler>, ["~> 1.8"])
77
78
  s.add_development_dependency(%q<fakefs>, ["~> 0.5"])
78
79
  s.add_development_dependency(%q<em-http-request>, ["~> 1.0"])
80
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
81
+ s.add_development_dependency(%q<less>, [">= 2.2.0"])
82
+ s.add_development_dependency(%q<therubyracer>, [">= 0"])
79
83
  else
80
84
  s.add_dependency(%q<eventmachine>, ["~> 1.0"])
81
85
  s.add_dependency(%q<eventmachine_httpserver>, ["~> 0.2"])
@@ -94,6 +98,9 @@ Gem::Specification.new do |s|
94
98
  s.add_dependency(%q<jeweler>, ["~> 1.8"])
95
99
  s.add_dependency(%q<fakefs>, ["~> 0.5"])
96
100
  s.add_dependency(%q<em-http-request>, ["~> 1.0"])
101
+ s.add_dependency(%q<simplecov>, [">= 0"])
102
+ s.add_dependency(%q<less>, [">= 2.2.0"])
103
+ s.add_dependency(%q<therubyracer>, [">= 0"])
97
104
  end
98
105
  else
99
106
  s.add_dependency(%q<eventmachine>, ["~> 1.0"])
@@ -113,6 +120,9 @@ Gem::Specification.new do |s|
113
120
  s.add_dependency(%q<jeweler>, ["~> 1.8"])
114
121
  s.add_dependency(%q<fakefs>, ["~> 0.5"])
115
122
  s.add_dependency(%q<em-http-request>, ["~> 1.0"])
123
+ s.add_dependency(%q<simplecov>, [">= 0"])
124
+ s.add_dependency(%q<less>, [">= 2.2.0"])
125
+ s.add_dependency(%q<therubyracer>, [">= 0"])
116
126
  end
117
127
  end
118
128
 
@@ -0,0 +1,93 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'em-http'
3
+
4
+ def compiler_test file, ext, src, &test
5
+ File.open(file, "w+"){|f| f.write(src)}
6
+ cf = Slinky::Compilers.cfile_for_file(file)
7
+ called_back = false
8
+
9
+ $stdout.should_receive(:puts).with("Compiled #{file}".foreground(:green))
10
+
11
+ cf.compile{|cpath, _, _, error|
12
+ error.should == nil
13
+ cpath.nil?.should == false
14
+ cpath.end_with?(ext).should == true
15
+ test.call(File.open(cpath).read).should == true
16
+ called_back = true
17
+ }
18
+
19
+ called_back.should == true
20
+ end
21
+
22
+ describe "Compilers" do
23
+ before :each do
24
+ FileUtils.rm_rf("/compilers") rescue nil
25
+ FileUtils.mkdir("/compilers")
26
+ end
27
+
28
+ context "SassCompiler" do
29
+ it "should be able to compile SASS files" do
30
+ src = <<eos
31
+ h1
32
+ color: red
33
+ eos
34
+ compiler_test("/compilers/test.sass", ".css", src){|s|
35
+ s.include?("color: red;")
36
+ }
37
+ end
38
+
39
+ it "should be able to compile SCSS files" do
40
+ src = <<eos
41
+ h1 {
42
+ a {
43
+ color: red;
44
+ }
45
+ }
46
+ eos
47
+ compiler_test("/compilers/test.scss", ".css", src){|s|
48
+ s.include?("color: red;") && s.include?("h1 a")
49
+ }
50
+ end
51
+ end
52
+
53
+ context "LessCompiler" do
54
+ it "should be able to compile LESS files" do
55
+ src = <<eos
56
+ @width: 0.5;
57
+
58
+ .class {
59
+ width: percentage(@width);
60
+ }
61
+ eos
62
+ compiler_test("/compilers/test.less", ".css", src){|s|
63
+ s.include?("width: 50%;")
64
+ }
65
+ end
66
+ end
67
+
68
+ context "CoffeeCompiler" do
69
+ it "should be able to compile .coffee files" do
70
+ src = <<eos
71
+ test = {do: (x) -> console.log(x)}
72
+ test.do("Hello, world")
73
+ eos
74
+ compiler_test("/compilers/test.coffee", ".js", src){|s|
75
+ s.include?("function(x) {")
76
+ }
77
+ end
78
+ end
79
+
80
+ context "HamlCompiler" do
81
+ it "should be able to compile .haml files" do
82
+ src = <<eos
83
+ !!!5
84
+ %head
85
+ %title Hello!
86
+ %body
87
+ eos
88
+ compiler_test("/compilers/test.haml", ".html", src){|s|
89
+ s.include?("<title>Hello!</title>")
90
+ }
91
+ end
92
+ end
93
+ end
data/spec/slinky_spec.rb CHANGED
@@ -23,7 +23,7 @@ describe "Slinky" do
23
23
  @md_prod = @mprod.manifest_dir
24
24
  @md_devel = @mdevel.manifest_dir
25
25
  end
26
-
26
+
27
27
  it "should build manifest dir with all files in current dir" do
28
28
  @md_prod.files.collect{|f| f.source}.should == ["/src/test.haml"]
29
29
  @md_devel.files.collect{|f| f.source}.should == ["/src/test.haml"]
@@ -38,6 +38,21 @@ describe "Slinky" do
38
38
  }.sort.should == @files.collect{|x| "/src/" + x}.sort
39
39
  end
40
40
 
41
+ it "should not include dot files" do
42
+ File.open("/src/.index.haml.swp", "w+"){|f| f.write("x")}
43
+ manifest = Slinky::Manifest.new("/src", @config)
44
+ manifest.files.map{|x| x.source}.include?("/src/.index.haml.swp").should == false
45
+ end
46
+
47
+ it "should be able to compute a hash for the entire manifest" do
48
+ m = @mdevel
49
+ hash1 = m.md5
50
+ File.open("/src/hello.html", "w+") {|f| f.write("Hell!") }
51
+ $stdout.should_receive(:puts).with("Compiled /src/test.haml".foreground(:green)).exactly(2).times
52
+ m.add_all_by_path(["/src/hello.html"])
53
+ m.md5.should_not == hash1
54
+ end
55
+
41
56
  it "should find files in the manifest by path" do
42
57
  @mdevel.find_by_path("test.haml").first.source.should == "/src/test.haml"
43
58
  @mdevel.find_by_path("asdf.haml").first.should == nil
@@ -53,7 +68,12 @@ describe "Slinky" do
53
68
  end
54
69
 
55
70
  it "should produce the correct scripts string for devel" do
56
- @mdevel.scripts_string.should == '<script type="text/javascript" src="/l1/test5.js"></script><script type="text/javascript" src="/l1/l2/test6.js"></script><script type="text/javascript" src="/l1/test2.js"></script><script type="text/javascript" src="/l1/l2/test3.js"></script><script type="text/javascript" src="/l1/test.js"></script>'
71
+ @mdevel.scripts_string.should == [
72
+ '<script type="text/javascript" src="/l1/test5.js"></script>',
73
+ '<script type="text/javascript" src="/l1/l2/test6.js"></script>',
74
+ '<script type="text/javascript" src="/l1/test2.js"></script>',
75
+ '<script type="text/javascript" src="/l1/l2/test3.js"></script>',
76
+ '<script type="text/javascript" src="/l1/test.js"></script>'].join("\n")
57
77
  end
58
78
 
59
79
  it "should produce the correct styles string for production" do
@@ -66,7 +86,9 @@ describe "Slinky" do
66
86
  f.write "require('../test.sass')\ncolor: red;"
67
87
  }
68
88
  manifest = Slinky::Manifest.new("/src", @config)
69
- @mdevel.styles_string.should == '<link rel="stylesheet" href="/l1/test.css" /><link rel="stylesheet" href="/l1/l2/test2.css" />'
89
+ @mdevel.styles_string.should == [
90
+ '<link rel="stylesheet" href="/l1/test.css" />',
91
+ '<link rel="stylesheet" href="/l1/l2/test2.css" />'].join("\n")
70
92
  end
71
93
 
72
94
  it "should allow the creation of ManifestFiles" do
@@ -95,6 +117,14 @@ describe "Slinky" do
95
117
  File.read(path).match(/slinky_scripts|slinky_styles/).should == nil
96
118
  end
97
119
 
120
+ it "should build tmp file without directives for .js" do
121
+ original = "/src/l1/test.js"
122
+ mf = Slinky::ManifestFile.new("/src/l1/test.js", "/src/build", @mprod)
123
+ path = mf.handle_directives mf.source
124
+ File.read(original).match(/slinky_require/).should_not == nil
125
+ File.read(path).match(/slinky_require/).should == nil
126
+ end
127
+
98
128
  it "should compile files that need it" do
99
129
  $stdout.should_receive(:puts).with("Compiled /src/test.haml".foreground(:green))
100
130
  mf = Slinky::ManifestFile.new("/src/test.haml", "/src/build", @mprod)
@@ -175,6 +205,15 @@ describe "Slinky" do
175
205
  mf.matches?("test.sass").should == true
176
206
  end
177
207
 
208
+ it "should should properly determine if in tree" do
209
+ mf = Slinky::ManifestFile.new("/src/l1/l2/test.txt", "/src/build/l1/l2", @mprod)
210
+ mf.in_tree?("/l1").should == true
211
+ mf.in_tree?("/l1/l2").should == true
212
+ mf.in_tree?("/l1/l2/test.txt").should == true
213
+ mf.in_tree?("/l1/l3").should == false
214
+ mf.in_tree?("test.txt").should == false
215
+ end
216
+
178
217
  it "should correctly build the dependency graph" do
179
218
  @mprod.build_dependency_graph.collect{|x| x.collect{|y| y.source}}.sort.should ==
180
219
  [["/src/l1/test2.js", "/src/l1/test.js"],
@@ -246,7 +285,7 @@ describe "Slinky" do
246
285
  f.process
247
286
  File.open("/src/l1/cache.coffee", "a"){|f| f.write("() -> 'goodbye, world!'\n")}
248
287
  $stdout.should_receive(:puts).with(/Compiled \/src\/l1\/cache.coffee/)
249
- f.process
288
+ f.process
250
289
  end
251
290
 
252
291
  it "should handle new directives" do
@@ -280,18 +319,18 @@ describe "Slinky" do
280
319
  f = manifest.find_by_path("l1/cache.coffee").first
281
320
  f.should_not == nil
282
321
  manifest.scripts_string.match("l1/cache.js").should_not == nil
283
-
322
+
284
323
  FileUtils.rm("/src/l1/cache.coffee")
285
324
  File.exists?("/src/l1/cache.coffee").should == false
286
325
  manifest.remove_all_by_path(["/src/l1/cache.coffee"])
287
326
  f = manifest.find_by_path("l1/cache.coffee").first
288
327
  f.should == nil
289
- manifest.scripts_string.match("l1/cache.js").should == nil
328
+ manifest.scripts_string.match("l1/cache.js").should == nil
290
329
  end
291
330
 
292
331
  it "should ignore the build directory" do
293
332
  $stdout.should_receive(:puts).with(/Compiled \/src\/.+/).exactly(6).times
294
- options = {:src_dir => "/src", :build_dir => "/src/build"}
333
+ options = {:src_dir => "/src", :build_dir => "/src/build"}
295
334
  Slinky::Builder.build(options, @config)
296
335
  File.exists?("/src/build/build").should_not == true
297
336
  File.exists?("/src/build/test.html").should == true
@@ -326,6 +365,75 @@ describe "Slinky" do
326
365
  css.include?("url('/l1/bg.png')").should == true
327
366
  css.include?("url('/l1/l2/l3/hello.png')").should == true
328
367
  end
368
+
369
+ it "should properly filter out ignores in files list" do
370
+ config = Slinky::ConfigReader.new("ignore:\n - /l1/test2.js")
371
+ config.ignore.should == ["/l1/test2.js"]
372
+ mdevel = Slinky::Manifest.new("/src", config)
373
+ mfiles = mdevel.files(false).map{|x| x.source}.sort
374
+ files = (@files - ["l1/test2.js"]).map{|x| "/src/" + x}.sort
375
+ mfiles.should == files
376
+ # double check
377
+ mfiles.include?("/src/l1/test2.js").should == false
378
+ end
379
+
380
+ it "should properly filter out relative ignores in files list" do
381
+ config = Slinky::ConfigReader.new("ignore:\n - l1/test2.js")
382
+ config.ignore.should == ["l1/test2.js"]
383
+ mdevel = Slinky::Manifest.new("/src", config)
384
+ mfiles = mdevel.files(false).map{|x| x.source}.sort
385
+ files = (@files - ["l1/test2.js"]).map{|x| "/src/" + x}.sort
386
+ mfiles.should == files
387
+ # double check
388
+ mfiles.include?("/src/l1/test2.js").should == false
389
+ end
390
+
391
+ it "should properly filter out directory ignores in files list" do
392
+ config = Slinky::ConfigReader.new("ignore:\n - /l1/l2")
393
+ config.ignore.should == ["/l1/l2"]
394
+ mdevel = Slinky::Manifest.new("/src", config)
395
+ mfiles = mdevel.files(false).map{|x| x.source}.sort
396
+ files = (@files.reject{|x| x.start_with?("l1/l2")}).map{|x| "/src/" + x}.sort
397
+ mfiles.should == files
398
+ end
399
+
400
+ it "should properly handle ignores for scripts" do
401
+ File.open("/src/l1/l2/ignore.js", "w+"){|f| f.write("IGNORE!!!")}
402
+ config = Slinky::ConfigReader.new("ignore:\n - /l1/l2/ignore.js")
403
+ config.ignore.should == ["/l1/l2/ignore.js"]
404
+
405
+ mdevel = Slinky::Manifest.new("/src", config)
406
+ mdevel.scripts_string.scan(/src=\"(.+?)\"/).flatten.
407
+ include?("/l1/l2/ignore.js").should == false
408
+
409
+ mprod = Slinky::Manifest.new("/src", config, :devel => false,
410
+ :build_to => "/build")
411
+
412
+ $stdout.should_receive(:puts).with(/Compiled \/src\/.+/).exactly(3).times
413
+ mprod.build
414
+
415
+ File.read("/build/scripts.js").include?("IGNORE!!!").should == false
416
+ File.exists?("/build/l1/l2/ignore.js").should == true
417
+ end
418
+
419
+ it "should properly handle ignores for styles" do
420
+ File.open("/src/l1/l2/ignore.css", "w+"){|f| f.write("IGNORE!!!")}
421
+ config = Slinky::ConfigReader.new("ignore:\n - /l1/l2/ignore.css")
422
+ config.ignore.should == ["/l1/l2/ignore.css"]
423
+
424
+ mdevel = Slinky::Manifest.new("/src", config)
425
+ mdevel.styles_string.scan(/href=\"(.+?)\"/).flatten.
426
+ include?("/l1/l2/ignore.css").should == false
427
+
428
+ mprod = Slinky::Manifest.new("/src", config, :devel => false,
429
+ :build_to => "/build")
430
+
431
+ $stdout.should_receive(:puts).with(/Compiled \/src\/.+/).exactly(3).times
432
+ mprod.build
433
+
434
+ File.read("/build/styles.css").include?("IGNORE!!!").should == false
435
+ File.exists?("/build/l1/l2/ignore.css").should == true
436
+ end
329
437
  end
330
438
 
331
439
  context "Server" do
@@ -333,7 +441,7 @@ describe "Slinky" do
333
441
  @resp = double("EventMachine::DelegatedHttpResponse")
334
442
  @resp.stub(:content=){|c| @content = c}
335
443
  @resp.stub(:content){ @content }
336
- @mdevel = Slinky::Manifest.new("/src", @config)
444
+ @mdevel = Slinky::Manifest.new("/src", @config)
337
445
  end
338
446
 
339
447
  it "path_for_uri should work correctly" do
@@ -362,11 +470,19 @@ describe "Slinky" do
362
470
  @resp.content.should == File.read("/src/l1/l2/test.txt")
363
471
  end
364
472
 
473
+ it "should serve the processed version of static files" do
474
+ Slinky::Server.manifest = @mdevel
475
+ @resp.should_receive(:content_type).with("application/javascript").at_least(:once)
476
+ Slinky::Server.process_path @resp, "/l1/test.js"
477
+ File.read("/src/l1/test.js").match("slinky_require").should_not == nil
478
+ @resp.content.match("slinky_require").should == nil
479
+ end
480
+
365
481
  it "should handle compiled files" do
366
482
  mf = Slinky::ManifestFile.new("/src/l1/test.sass", nil, @mdevel)
367
483
  $stdout.should_receive(:puts).with("Compiled /src/l1/test.sass".foreground(:green))
368
484
  Slinky::Server.handle_file @resp, mf
369
- @resp.content.should == Slinky::SassCompiler::compile(File.read("/src/l1/test.sass"), "")
485
+ @resp.content.should == Slinky::SassCompiler::compile(File.read("/src/l1/test.sass"), "/src/l1/test.sass")
370
486
  end
371
487
 
372
488
  it "should handle non-existant files" do
@@ -381,8 +497,8 @@ describe "Slinky" do
381
497
  pushstate:
382
498
  "/": "/test.html"
383
499
  eos
384
- File.open("/src/slinky.yaml", "w+"){|f| f.write config}
385
- cr = Slinky::ConfigReader.from_file("/src/slinky.yaml")
500
+ File.open("/src/slinky.yaml", "w+"){|f| f.write config}
501
+ cr = Slinky::ConfigReader.from_file("/src/slinky.yaml")
386
502
  Slinky::Server.config = cr
387
503
  Slinky::Server.manifest = @mdevel
388
504
  $stdout.should_receive(:puts).with("Compiled /src/test.haml".foreground(:green))
@@ -396,12 +512,12 @@ eos
396
512
  pushstate:
397
513
  "/": "/notreal.html"
398
514
  eos
399
- File.open("/src/slinky.yaml", "w+"){|f| f.write config}
400
- cr = Slinky::ConfigReader.from_file("/src/slinky.yaml")
515
+ File.open("/src/slinky.yaml", "w+"){|f| f.write config}
516
+ cr = Slinky::ConfigReader.from_file("/src/slinky.yaml")
401
517
  Slinky::Server.config = cr
402
518
  Slinky::Server.manifest = @mdevel
403
519
  @resp.should_receive(:status=).with(404)
404
- @resp.should_receive(:content_type).with("text/html").at_least(:once)
520
+ @resp.should_receive(:content_type).with("text/html").at_least(:once)
405
521
  Slinky::Server.process_path @resp, "this/doesnt/exist.html"
406
522
  end
407
523
 
@@ -456,7 +572,7 @@ eos
456
572
  base = "http://localhost:43453"
457
573
  multi = EventMachine::MultiRequest.new
458
574
  $stdout.should_receive(:puts).with(/Compiled \/src\/index.haml/)
459
-
575
+
460
576
  # add multiple requests to the multi-handler
461
577
  multi.add(:index, EventMachine::HttpRequest.new("#{base}/index.html").get)
462
578
  multi.add(:base, EventMachine::HttpRequest.new(base).get)
@@ -521,14 +637,14 @@ eos
521
637
 
522
638
  it "should be able to read configuration from strings" do
523
639
  cr = Slinky::ConfigReader.new(@config)
524
- cr.proxies.should == @proxies
525
- cr.ignores.should == @ignores
640
+ cr.proxy.should == @proxies
641
+ cr.ignore.should == @ignores
526
642
  end
527
643
 
528
644
  it "should be able to read configuration from files" do
529
645
  cr = Slinky::ConfigReader.from_file("/src/slinky.yaml")
530
- cr.proxies.should == @proxies
531
- cr.ignores.should == @ignores
646
+ cr.proxy.should == @proxies
647
+ cr.ignore.should == @ignores
532
648
  cr.port.should == 5555
533
649
  cr.src_dir.should == "src/"
534
650
  cr.build_dir.should == "build/"
@@ -536,12 +652,21 @@ eos
536
652
  cr.no_livereload.should == true
537
653
  cr.livereload_port.should == 5556
538
654
  cr.dont_minify.should == true
539
- cr.pushstates.should == @pushstates
655
+ cr.pushstate.should == @pushstates
540
656
  end
541
657
 
542
658
  it "should be able to create the empty config" do
543
- Slinky::ConfigReader.empty.proxies.should == {}
544
- Slinky::ConfigReader.empty.ignores.should == []
659
+ Slinky::ConfigReader.empty.proxy.should == {}
660
+ Slinky::ConfigReader.empty.ignore.should == []
661
+ end
662
+
663
+ it "should error on invalid configuration" do
664
+ config = <<eos
665
+ invalid:
666
+ -script/vendor
667
+ eos
668
+ proc { Slinky::ConfigReader.new(config) }
669
+ .should raise_error Slinky::InvalidConfigError
545
670
  end
546
671
  end
547
672
 
@@ -553,7 +678,7 @@ proxy:
553
678
  "/test2/": "http://127.0.0.1:7000"
554
679
  eos
555
680
  @cr = Slinky::ConfigReader.new(@config)
556
- @proxies = Slinky::ProxyServer.process_proxies(@cr.proxies)
681
+ @proxies = Slinky::ProxyServer.process_proxies(@cr.proxy)
557
682
  @data = <<eos
558
683
  GET /test1/something/and?q=asdf&c=E9oBiwFqZmoJam9uYXNmdXAyclkLEj0KABoMQ29ja3RhaWxJbXBsIzAFchIaA2Z0cyAAKgkaB3doaXNrZXkkS1IPd2VpZ2h0ZWRBdmFyYWdlWAJMDAsSDENvY2t0YWlsSW1wbCIGNDYtODE3DHIeGg93ZWlnaHRlZEF2YXJhZ2UgACoJIQAAAAAAAAAAggEA4AEAFA HTTP/1.1\r\nHost: 127.0.0.1:8888\nConnection: keep-alive\r\nX-Requested-With: XMLHttpRequest\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.904.0 Safari/535.7\r\nAccept: */*\r\nReferer: http://localhost:5323/\r\nAccept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\nCookie: mp_super_properties=%7B%22all%22%3A%20%7B%22%24initial_referrer%22%3A%20%22http%3A//localhost%3A5323/%22%2C%22%24initial_referring_domain%22%3A%20%22localhost%3A5323%22%7D%2C%22events%22%3A%20%7B%7D%2C%22funnels%22%3A%20%7B%7D%7D\r\n\r\n
559
684
  eos
@@ -571,16 +696,16 @@ eos
571
696
  Slinky::ProxyServer.process_proxy_servers(@proxies).should ==
572
697
  [["127.0.0.1", 8000], ["127.0.0.1", 7000]]
573
698
  end
574
-
699
+
575
700
  it "should find the correct matcher for a request" do
576
701
  p = Slinky::ProxyServer.find_matcher(@proxies, "/test1/this/is/another")
577
702
  p[0].should == "/test1"
578
703
  p[1].to_s.should == "http://127.0.0.1:8000"
579
-
704
+
580
705
  p = Slinky::ProxyServer.find_matcher(@proxies, "/test2/whatsgoing.html?something=asdf")
581
706
  p[0].should == "/test2/"
582
707
  p[1].to_s.should == "http://127.0.0.1:7000"
583
-
708
+
584
709
  Slinky::ProxyServer.find_matcher(@proxies, "/asdf/test1/asdf").should == nil
585
710
  Slinky::ProxyServer.find_matcher(@proxies, "/test2x/asdf").should == nil
586
711
  end
@@ -613,12 +738,11 @@ proxy:
613
738
  lag: 1000
614
739
  eos
615
740
  @cr = Slinky::ConfigReader.new(@config)
616
- @proxies = Slinky::ProxyServer.process_proxies(@cr.proxies)
741
+ @proxies = Slinky::ProxyServer.process_proxies(@cr.proxy)
617
742
 
618
743
  @proxies[0][0].should == "/test3"
619
744
  @proxies[0][1].to_s.should == "http://127.0.0.1:6000"
620
745
  @proxies[0][2].should == {"lag" => 1000}
621
746
  end
622
-
623
747
  end
624
748
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
 
4
+ require 'simplecov'
5
+ SimpleCov.start
6
+
4
7
  require 'bundler/setup'
5
8
  require 'rspec'
6
9
  require 'slinky'
@@ -102,7 +105,7 @@ module Slinky
102
105
  s
103
106
  end
104
107
  end
105
-
108
+
106
109
  class Manifest
107
110
  alias :old_compress :compress
108
111
  def compress ext, output, compressor
@@ -113,7 +116,7 @@ module Slinky
113
116
  end
114
117
  end
115
118
  end
116
-
119
+
117
120
  # No way to make this work with FakeFS, so just disabled it
118
121
  class Listener
119
122
  def run; end
@@ -130,9 +133,11 @@ end
130
133
  RSpec.configure do |config|
131
134
  config.before :all do
132
135
  FakeFS.activate!
136
+ FileUtils.rm_rf("/tmp") rescue nil
133
137
  FileUtils.mkdir("/tmp")
134
138
  @config = Slinky::ConfigReader.empty
135
139
  end
140
+
136
141
  config.before :each do
137
142
  FakeFS.activate!
138
143
  FileUtils.rm_rf("/src") rescue nil
@@ -171,6 +176,7 @@ eos
171
176
  f.write <<eos
172
177
  slinky_require('test2.js')
173
178
  slinky_require("l2/test3.js")
179
+ console.log("Hello!");
174
180
  eos
175
181
  }
176
182
 
@@ -211,4 +217,3 @@ def run_for secs
211
217
  }
212
218
  end
213
219
  end
214
-
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slinky
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Micah Wylde
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-30 00:00:00.000000000 Z
11
+ date: 2014-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eventmachine
@@ -248,6 +248,48 @@ dependencies:
248
248
  - - "~>"
249
249
  - !ruby/object:Gem::Version
250
250
  version: '1.0'
251
+ - !ruby/object:Gem::Dependency
252
+ name: simplecov
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - ">="
256
+ - !ruby/object:Gem::Version
257
+ version: '0'
258
+ type: :development
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: '0'
265
+ - !ruby/object:Gem::Dependency
266
+ name: less
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - ">="
270
+ - !ruby/object:Gem::Version
271
+ version: 2.2.0
272
+ type: :development
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - ">="
277
+ - !ruby/object:Gem::Version
278
+ version: 2.2.0
279
+ - !ruby/object:Gem::Dependency
280
+ name: therubyracer
281
+ requirement: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - ">="
284
+ - !ruby/object:Gem::Version
285
+ version: '0'
286
+ type: :development
287
+ prerelease: false
288
+ version_requirements: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - ">="
291
+ - !ruby/object:Gem::Version
292
+ version: '0'
251
293
  description: A static file server for rich web apps that automatically compiles SASS,
252
294
  HAML, CoffeeScript and more
253
295
  email: micah@micahw.com
@@ -285,6 +327,7 @@ files:
285
327
  - lib/slinky/runner.rb
286
328
  - lib/slinky/server.rb
287
329
  - slinky.gemspec
330
+ - spec/compilers_spec.rb
288
331
  - spec/slinky_spec.rb
289
332
  - spec/spec_helper.rb
290
333
  homepage: http://mwylde.github.com/slinky/