sstephenson-sprockets 0.1.1 → 0.3.0

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.
@@ -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
+