slinky 0.7.1 → 0.7.2

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.
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/