sstephenson-sprockets 0.1.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -22,7 +22,16 @@ module Sprockets
22
22
  end
23
23
 
24
24
  def find(location)
25
- load_path.map { |pathname| pathname.find(location) }.compact.first
25
+ find_all(location).first
26
+ end
27
+
28
+ def constants(reload = false)
29
+ @constants = nil if reload
30
+ @constants ||= find_all("constants.yml").inject({}) do |constants, pathname|
31
+ contents = YAML.load(pathname.contents) rescue nil
32
+ contents = {} unless contents.is_a?(Hash)
33
+ constants.merge(contents)
34
+ end
26
35
  end
27
36
 
28
37
  protected
@@ -31,5 +40,9 @@ module Sprockets
31
40
  location = File.join(root.absolute_location, location) unless location[/^\//]
32
41
  File.expand_path(location)
33
42
  end
43
+
44
+ def find_all(location)
45
+ load_path.map { |pathname| pathname.find(location) }.compact
46
+ end
34
47
  end
35
48
  end
@@ -1,4 +1,5 @@
1
1
  module Sprockets
2
- class Error < ::StandardError; end
3
- class LoadError < Error; end
2
+ class Error < ::StandardError; end
3
+ class LoadError < Error; end
4
+ class UndefinedConstantError < Error; end
4
5
  end
@@ -4,17 +4,33 @@ module Sprockets
4
4
 
5
5
  def initialize
6
6
  @source_lines = []
7
+ @source_file_mtimes = {}
7
8
  end
8
9
 
9
10
  def record(source_line)
10
- @source_lines << source_line
11
+ source_lines << source_line
12
+ record_mtime_for(source_line.source_file)
11
13
  source_line
12
14
  end
13
15
 
14
16
  def to_s
15
- @source_lines.map do |source_line|
16
- source_line.line
17
- end.join
17
+ source_lines.join
18
18
  end
19
+
20
+ def mtime
21
+ @source_file_mtimes.values.max
22
+ end
23
+
24
+ def save_to(filename)
25
+ timestamp = mtime
26
+ File.open(filename, "w") { |file| file.write(to_s) }
27
+ File.utime(timestamp, timestamp, filename)
28
+ true
29
+ end
30
+
31
+ protected
32
+ def record_mtime_for(source_file)
33
+ @source_file_mtimes[source_file] ||= source_file.mtime
34
+ end
19
35
  end
20
36
  end
@@ -21,6 +21,10 @@ module Sprockets
21
21
  SourceFile.new(environment, self)
22
22
  end
23
23
 
24
+ def contents
25
+ IO.read(absolute_location)
26
+ end
27
+
24
28
  def ==(pathname)
25
29
  environment == pathname.environment &&
26
30
  absolute_location == pathname.absolute_location
@@ -30,11 +30,29 @@ module Sprockets
30
30
  end
31
31
 
32
32
  def record_source_line(source_line)
33
- unless source_line.comment? && strip_comments?
34
- output_file.record(source_line)
33
+ skip_pdoc_comments(source_line) do
34
+ unless source_line.comment? && strip_comments?
35
+ output_file.record(source_line)
36
+ end
35
37
  end
36
38
  end
37
-
39
+
40
+ def skip_pdoc_comments(source_line)
41
+ yield unless strip_comments?
42
+
43
+ @commented ||= false
44
+
45
+ if source_line.begins_multiline_comment?
46
+ @commented = true
47
+ end
48
+
49
+ yield unless @commented
50
+
51
+ if source_line.closes_multiline_comment?
52
+ @commented = false
53
+ end
54
+ end
55
+
38
56
  def strip_comments?
39
57
  options[:strip_comments] != false
40
58
  end
@@ -22,5 +22,11 @@ module Sprockets
22
22
  def ==(source_file)
23
23
  pathname == source_file.pathname
24
24
  end
25
+
26
+ def mtime
27
+ File.mtime(pathname.absolute_location)
28
+ rescue Errno::ENOENT
29
+ 0
30
+ end
25
31
  end
26
32
  end
@@ -16,6 +16,14 @@ module Sprockets
16
16
  !!comment
17
17
  end
18
18
 
19
+ def begins_multiline_comment?
20
+ line =~ /^\s*\/\*\*(.*)/
21
+ end
22
+
23
+ def closes_multiline_comment?
24
+ line =~ /^(.*)*\*\*\/\s*/
25
+ end
26
+
19
27
  def require
20
28
  @require ||= (comment || "")[/^=\s+require\s+(\"(.*?)\"|<(.*?)>)\s*$/, 1]
21
29
  end
@@ -27,5 +35,16 @@ module Sprockets
27
35
  def inspect
28
36
  "line #@number of #{@source_file.pathname}"
29
37
  end
38
+
39
+ def to_s(constants = source_file.environment.constants)
40
+ line.chomp.gsub(/<%=(.*?)%>/) do
41
+ constant = $1.strip
42
+ if value = constants[constant]
43
+ value
44
+ else
45
+ raise UndefinedConstantError, "couldn't find constant `#{constant}' in #{inspect}"
46
+ end
47
+ end + $/
48
+ end
30
49
  end
31
50
  end
data/lib/sprockets.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  $:.unshift File.dirname(__FILE__)
2
2
 
3
+ require "yaml"
4
+
3
5
  require "sprockets/version"
4
6
  require "sprockets/error"
5
7
  require "sprockets/environment"
@@ -0,0 +1 @@
1
+ VERSION: 1.0
@@ -1 +1,2 @@
1
1
  // This is a double-slash comment that should appear in the resulting output file.
2
+ /* This is a slash-star comment that should appear in the resulting output file. */
@@ -1,2 +1,2 @@
1
1
  // This is a double-slash comment that should not appear in the resulting output file.
2
- /* This is a slash-star comment that should appear in the resulting output file. */
2
+ /* This is a slash-star comment that should not appear in the resulting output file. */
@@ -0,0 +1,4 @@
1
+ /**
2
+ * This is a slash-star comment
3
+ * that should appear in the resulting output file.
4
+ **/
@@ -0,0 +1,3 @@
1
+ ONE: one
2
+ TWO: two
3
+ HELLO: Hello world!
@@ -51,6 +51,12 @@ class EnvironmentTest < Test::Unit::TestCase
51
51
  assert_nil environment.find("nonexistent.js")
52
52
  end
53
53
 
54
+ def test_constants_should_return_a_hash_of_all_constants_defined_in_the_load_path
55
+ constants = environment_for_fixtures.constants
56
+ assert_kind_of Hash, constants
57
+ assert_equal %w(HELLO ONE TWO VERSION), constants.keys.sort
58
+ end
59
+
54
60
  protected
55
61
  def assert_load_path_equals(load_path_absolute_locations, environment)
56
62
  assert load_path_absolute_locations.zip(environment.load_path).map { |location, pathname| location == pathname.absolute_location }.all?
data/test/test_helper.rb CHANGED
@@ -38,6 +38,6 @@ class Test::Unit::TestCase
38
38
  end
39
39
 
40
40
  def source_line(line, source_file = nil, line_number = 1)
41
- Sprockets::SourceLine.new(source_file, line, line_number)
41
+ Sprockets::SourceLine.new(source_file || source_file("dummy"), line, line_number)
42
42
  end
43
43
  end
@@ -3,13 +3,14 @@ require "test_helper"
3
3
  class OutputFileTest < Test::Unit::TestCase
4
4
  def setup
5
5
  @output_file = Sprockets::OutputFile.new
6
+ @environment = environment_for_fixtures
6
7
  end
7
8
 
8
9
  def test_record
9
10
  assert_equal [], @output_file.source_lines
10
- assert_equal "hello\n", @output_file.record("hello\n")
11
- assert_equal "world\n", @output_file.record("world\n")
12
- assert_equal ["hello\n", "world\n"], @output_file.source_lines
11
+ assert_equal "hello\n", @output_file.record(source_line("hello\n")).to_s
12
+ assert_equal "world\n", @output_file.record(source_line("world\n")).to_s
13
+ assert_equal ["hello\n", "world\n"], @output_file.source_lines.map { |source_line| source_line.to_s }
13
14
  end
14
15
 
15
16
  def test_to_s
@@ -17,4 +18,11 @@ class OutputFileTest < Test::Unit::TestCase
17
18
  @output_file.record(source_line("world\n"))
18
19
  assert_equal "hello\nworld\n", @output_file.to_s
19
20
  end
21
+
22
+ def test_save_to
23
+ filename = File.join(FIXTURES_PATH, "output.js")
24
+ @output_file.save_to(filename)
25
+ assert_equal @output_file.to_s, IO.read(filename)
26
+ File.unlink(filename)
27
+ end
20
28
  end
@@ -9,15 +9,24 @@ class PreprocessorTest < Test::Unit::TestCase
9
9
  def test_double_slash_comments_that_are_not_requires_should_be_removed_by_default
10
10
  require_file_for_this_test
11
11
  assert_output_file_does_not_contain_line "// This is a double-slash comment that should not appear in the resulting output file."
12
- assert_output_file_contains_line "/* This is a slash-star comment that should appear in the resulting output file. */"
12
+ assert_output_file_contains_line "/* This is a slash-star comment that should not appear in the resulting output file. */"
13
13
  end
14
14
 
15
15
  def test_double_slash_comments_that_are_not_requires_should_be_ignored_when_strip_comments_is_false
16
16
  @preprocessor = Sprockets::Preprocessor.new(@environment, :strip_comments => false)
17
17
  require_file_for_this_test
18
18
  assert_output_file_contains_line "// This is a double-slash comment that should appear in the resulting output file."
19
+ assert_output_file_contains_line "/* This is a slash-star comment that should appear in the resulting output file. */"
19
20
  end
20
-
21
+
22
+ def test_multiline_comments_should_be_removed_by_default
23
+ require_file_for_this_test
24
+ assert_output_file_does_not_contain_line "/**"
25
+ assert_output_file_does_not_contain_line " * This is a slash-star comment"
26
+ assert_output_file_does_not_contain_line " * that should appear in the resulting output file."
27
+ assert_output_file_does_not_contain_line "**/"
28
+ end
29
+
21
30
  def test_requiring_a_single_file_should_replace_the_require_comment_with_the_file_contents
22
31
  require_file_for_this_test
23
32
  assert_output_file_contains <<-LINES
@@ -76,11 +85,11 @@ class PreprocessorTest < Test::Unit::TestCase
76
85
  end
77
86
 
78
87
  def assert_output_file_does_not_contain_line(line)
79
- assert source_lines_matching(line).empty?
88
+ assert source_lines_matching(line).empty?, "Expected #{line.inspect} to not exist"
80
89
  end
81
90
 
82
91
  def assert_output_file_contains_line(line)
83
- assert source_lines_matching(line).any?
92
+ assert source_lines_matching(line).any?, "Expected #{line.inspect} to exist"
84
93
  end
85
94
 
86
95
  def assert_output_file_contains(indented_text)
@@ -9,7 +9,17 @@ class SourceLineTest < Test::Unit::TestCase
9
9
  assert source_line(" //").comment?
10
10
  assert source_line("\t//").comment?
11
11
  end
12
-
12
+
13
+ def test_line_that_begins_a_multiline_comment
14
+ assert !source_line(" /*").begins_multiline_comment?
15
+ assert source_line(" /**").begins_multiline_comment?
16
+ end
17
+
18
+ def test_line_that_closes_a_multiline_comment
19
+ assert !source_line(" */").closes_multiline_comment?
20
+ assert source_line(" **/").closes_multiline_comment?
21
+ end
22
+
13
23
  def test_line_that_contains_but_does_not_begin_with_double_slash_should_not_be_a_comment
14
24
  assert !source_line("f //").comment?
15
25
  assert !source_line("f //= require <foo>").comment?
@@ -41,4 +51,14 @@ class SourceLineTest < Test::Unit::TestCase
41
51
  source_file = Sprockets::SourceFile.new(environment, pathname)
42
52
  assert_equal "line 25 of /a/b/c.js", source_line("hello", source_file, 25).inspect
43
53
  end
54
+
55
+ def test_interpolation_of_constants
56
+ assert_equal %(var VERSION = "1.0";\n), source_line('var VERSION = "<%= VERSION %>";').to_s("VERSION" => "1.0")
57
+ end
58
+
59
+ def test_interpolation_of_missing_constant_raises_undefined_constant_error
60
+ assert_raises(Sprockets::UndefinedConstantError) do
61
+ source_line('<%= NONEXISTENT %>').to_s("VERSION" => "1.0")
62
+ end
63
+ end
44
64
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sstephenson-sprockets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Stephenson
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-06-01 00:00:00 -07:00
12
+ date: 2009-01-28 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -44,8 +44,11 @@ files:
44
44
  - test/fixtures/src/foo/bar.js
45
45
  - test/fixtures/src/foo/foo.js
46
46
  - test/fixtures/src/foo.js
47
+ - test/fixtures/src/constants.yml
48
+ - test/fixtures/multiline_comments_should_be_removed_by_default.js
47
49
  - test/fixtures/requiring_a_single_file_should_replace_the_require_comment_with_the_file_contents.js
48
50
  - test/fixtures/double_slash_comments_that_are_not_requires_should_be_removed_by_default.js
51
+ - test/fixtures/constants.yml
49
52
  - test/fixtures/requiring_a_file_that_does_not_exist_should_raise_an_error.js
50
53
  - test/fixtures/requiring_a_file_after_it_has_already_been_required_should_do_nothing.js
51
54
  - test/fixtures/double_slash_comments_that_are_not_requires_should_be_ignored_when_strip_comments_is_false.js
@@ -75,15 +78,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
78
  requirements: []
76
79
 
77
80
  rubyforge_project:
78
- rubygems_version: 1.0.1
81
+ rubygems_version: 1.2.0
79
82
  signing_key:
80
83
  specification_version: 2
81
84
  summary: JavaScript dependency management and concatenation
82
- test_files:
83
- - test/test_preprocessor.rb
84
- - test/test_source_line.rb
85
- - test/test_source_file.rb
86
- - test/test_output_file.rb
87
- - test/test_pathname.rb
88
- - test/test_helper.rb
89
- - test/test_environment.rb
85
+ test_files: []
86
+