faml 0.2.13 → 0.2.14

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/README.md +2 -0
  4. data/faml.gemspec +2 -1
  5. data/incompatibilities/README.md +29 -0
  6. data/incompatibilities/spec/compiler_newline_spec.md +31 -0
  7. data/incompatibilities/spec/render/attribute_spec.md +587 -0
  8. data/incompatibilities/spec/render/comment_spec.md +42 -0
  9. data/incompatibilities/spec/render/doctype_spec.md +22 -0
  10. data/incompatibilities/spec/render/element_spec.md +95 -0
  11. data/incompatibilities/spec/render/filters/cdata_spec.md +25 -0
  12. data/incompatibilities/spec/render/filters/coffee_spec.md +88 -0
  13. data/incompatibilities/spec/render/filters/css_spec.md +38 -0
  14. data/incompatibilities/spec/render/filters/escaped_spec.md +33 -0
  15. data/incompatibilities/spec/render/filters/javascript_spec.md +38 -0
  16. data/incompatibilities/spec/render/filters/markdown_spec.md +24 -0
  17. data/incompatibilities/spec/render/filters/preserve_spec.md +29 -0
  18. data/incompatibilities/spec/render/filters/sass_spec.md +59 -0
  19. data/incompatibilities/spec/render/filters/scss_spec.md +65 -0
  20. data/incompatibilities/spec/render/helpers_spec.md +17 -0
  21. data/incompatibilities/spec/render/indent_spec.md +21 -0
  22. data/incompatibilities/spec/render/multiline_spec.md +55 -0
  23. data/incompatibilities/spec/render/newline_spec.md +91 -0
  24. data/incompatibilities/spec/render/plain_spec.md +19 -0
  25. data/incompatibilities/spec/render/sanitize_spec.md +36 -0
  26. data/incompatibilities/spec/render/silent_script_spec.md +31 -0
  27. data/incompatibilities/spec/render/unescape_spec.md +56 -0
  28. data/lib/faml/indent_tracker.rb +39 -3
  29. data/lib/faml/parser.rb +2 -0
  30. data/lib/faml/version.rb +1 -1
  31. data/spec/render/element_spec.rb +0 -9
  32. data/spec/render/indent_spec.rb +47 -0
  33. data/spec/spec_helper.rb +21 -2
  34. data/spec/support/incompatibilities_generator.rb +132 -0
  35. metadata +53 -3
@@ -3,6 +3,29 @@ require 'faml/error'
3
3
  module Faml
4
4
  class IndentTracker
5
5
  class IndentMismatch < Error
6
+ attr_reader :current_level, :indent_levels
7
+
8
+ def initialize(current_level, indent_levels, lineno)
9
+ super("Unexpected indent level: #{current_level}: indent_level=#{indent_levels}", lineno)
10
+ @current_level = current_level
11
+ @indent_levels = indent_levels
12
+ end
13
+ end
14
+
15
+ class InconsistentIndent < Error
16
+ attr_reader :previous_size, :current_size
17
+
18
+ def initialize(previous_size, current_size, lineno)
19
+ super("Inconsistent indentation: #{current_size} spaces used for indentation, but the rest of the document was indented using #{previous_size} spaces.", lineno)
20
+ @previous_size = previous_size
21
+ @current_size = current_size
22
+ end
23
+ end
24
+
25
+ class HardTabNotAllowed < Error
26
+ def initialize(lineno)
27
+ super('Indentation with hard tabs are not allowed :-p', lineno)
28
+ end
6
29
  end
7
30
 
8
31
  def initialize(on_enter: nil, on_leave: nil)
@@ -13,6 +36,9 @@ module Faml
13
36
  end
14
37
 
15
38
  def process(line, lineno)
39
+ if line =~ /\A\t/
40
+ raise HardTabNotAllowed.new(lineno)
41
+ end
16
42
  indent, text = split(line)
17
43
  indent_level = indent.size
18
44
 
@@ -39,17 +65,27 @@ module Faml
39
65
  @comment_level = @indent_levels[-2]
40
66
  end
41
67
 
68
+ def check_indent_level!(lineno)
69
+ if @indent_levels.size >= 3
70
+ previous_size = @indent_levels[-2] - @indent_levels[-3]
71
+ current_size = @indent_levels[-1] - @indent_levels[-2]
72
+ if previous_size != current_size
73
+ raise InconsistentIndent.new(previous_size, current_size, lineno)
74
+ end
75
+ end
76
+ end
77
+
42
78
  private
43
79
 
44
80
  def track(indent_level, text, lineno)
45
81
  if indent_level > @indent_levels.last
46
- indent_enter(indent_level, text)
82
+ indent_enter(indent_level, text, lineno)
47
83
  elsif indent_level < @indent_levels.last
48
84
  indent_leave(indent_level, text, lineno)
49
85
  end
50
86
  end
51
87
 
52
- def indent_enter(indent_level, text)
88
+ def indent_enter(indent_level, text, lineno)
53
89
  unless @comment_level
54
90
  @indent_levels.push(indent_level)
55
91
  @on_enter.call(indent_level, text)
@@ -73,7 +109,7 @@ module Faml
73
109
  end
74
110
 
75
111
  if indent_level != @indent_levels.last
76
- raise IndentMismatch.new("Unexpected indent level: #{indent_level}: indent_level=#{@indent_levels}", lineno)
112
+ raise IndentMismatch.new(indent_level, @indent_levels.dup, lineno)
77
113
  end
78
114
  end
79
115
  end
data/lib/faml/parser.rb CHANGED
@@ -186,6 +186,8 @@ module Faml
186
186
  end
187
187
  if @ast.is_a?(Ast::HamlComment)
188
188
  @indent_tracker.enter_comment!
189
+ else
190
+ @indent_tracker.check_indent_level!(@line_parser.lineno)
189
191
  end
190
192
  nil
191
193
  end
data/lib/faml/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Faml
2
- VERSION = "0.2.13"
2
+ VERSION = "0.2.14"
3
3
  end
@@ -42,15 +42,6 @@ HAML
42
42
  HAML
43
43
  end
44
44
 
45
- it 'raises error if indent is wrong' do
46
- expect { render_string(<<HAML) }.to raise_error(Faml::IndentTracker::IndentMismatch)
47
- %div
48
- %div
49
- %div
50
- %div
51
- HAML
52
- end
53
-
54
45
  it 'parses classes' do
55
46
  expect(render_string('%span.foo.bar hello')).to eq(%Q{<span class='foo bar'>hello</span>\n})
56
47
  end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Indent', type: :render do
4
+ it 'raises error if indent is wrong' do
5
+ expect { render_string(<<HAML) }.to raise_error(Faml::IndentTracker::IndentMismatch) { |e|
6
+ %div
7
+ %div
8
+ %div
9
+ %div
10
+ HAML
11
+ expect(e.current_level).to eq(2)
12
+ expect(e.indent_levels).to eq([0])
13
+ expect(e.lineno).to eq(4)
14
+ }
15
+ end
16
+
17
+ it 'raises error if the current indent is deeper than the previous one' do
18
+ expect { render_string(<<HAML) }.to raise_error(Faml::IndentTracker::InconsistentIndent) { |e|
19
+ %div
20
+ %div
21
+ %div
22
+ HAML
23
+ expect(e.previous_size).to eq(2)
24
+ expect(e.current_size).to eq(4)
25
+ expect(e.lineno).to eq(3)
26
+ }
27
+ end
28
+
29
+ it 'raises error if the current indent is shallower than the previous one' do
30
+ expect { render_string(<<HAML) }.to raise_error(Faml::IndentTracker::InconsistentIndent) { |e|
31
+ %div
32
+ %div
33
+ %div
34
+ HAML
35
+ expect(e.previous_size).to eq(4)
36
+ expect(e.current_size).to eq(2)
37
+ expect(e.lineno).to eq(3)
38
+ }
39
+ end
40
+
41
+ it 'raises error if indented with hard tabs' do
42
+ expect { render_string(<<HAML) }.to raise_error(Faml::IndentTracker::HardTabNotAllowed)
43
+ %p
44
+ %a
45
+ HAML
46
+ end
47
+ end
data/spec/spec_helper.rb CHANGED
@@ -12,8 +12,21 @@ end
12
12
  require 'faml'
13
13
 
14
14
  module RenderSpecHelper
15
- def render_string(str, options = {})
16
- eval(Faml::Engine.new(options).call(str))
15
+ if ENV['GENERATE_INCOMPATIBILITIES'] == '1'
16
+ require_relative 'support/incompatibilities_generator'
17
+
18
+ def render_string(str, options = {})
19
+ eval(Faml::Engine.new(options).call(str)).tap do |html|
20
+ IncompatibilitiesGenerator.instance.record(str, options, html, RSpec.current_example)
21
+ end
22
+ rescue => e
23
+ IncompatibilitiesGenerator.instance.record(str, options, e, RSpec.current_example)
24
+ raise e
25
+ end
26
+ else
27
+ def render_string(str, options = {})
28
+ eval(Faml::Engine.new(options).call(str))
29
+ end
17
30
  end
18
31
  end
19
32
 
@@ -44,4 +57,10 @@ RSpec.configure do |config|
44
57
  Kernel.srand config.seed
45
58
 
46
59
  config.include(RenderSpecHelper, type: :render)
60
+
61
+ if ENV['GENERATE_INCOMPATIBILITIES'] == '1'
62
+ config.after :suite do
63
+ IncompatibilitiesGenerator.instance.write_to('incompatibilities')
64
+ end
65
+ end
47
66
  end
@@ -0,0 +1,132 @@
1
+ require 'pathname'
2
+ require 'singleton'
3
+ require 'hamlit/engine'
4
+ require 'hamlit/version'
5
+
6
+ class IncompatibilitiesGenerator
7
+ include Singleton
8
+
9
+ class Record < Struct.new(:template, :options, :spec_path, :line_number, :faml_result, :haml_result, :hamlit_result)
10
+ end
11
+
12
+ def initialize
13
+ @records = []
14
+ end
15
+
16
+ def record(template, options, faml_result, example)
17
+ m = example.location.match(/\A(.+):(\d+)\z/)
18
+ @records.push(Record.new(template, options, m[1], m[2].to_i, faml_result, render_haml(template, options), render_hamlit(template, options)))
19
+ end
20
+
21
+ def write_to(markdown_root)
22
+ markdown_root = Pathname.new(markdown_root)
23
+
24
+ incompatibilities = Hash.new { |h, k| h[k] = [] }
25
+ @records.each do |record|
26
+ if record.faml_result.is_a?(Exception) && record.haml_result.is_a?(Exception) && record.hamlit_result.is_a?(Exception)
27
+ # All errored, not an incompatibility.
28
+ elsif record.faml_result != record.haml_result || record.faml_result != record.hamlit_result || record.haml_result != record.hamlit_result
29
+ incompatibilities[record.spec_path] << record
30
+ end
31
+ end
32
+
33
+ incompatibilities.keys.sort.each do |spec_path|
34
+ path = markdown_path(markdown_root, spec_path)
35
+ path.parent.mkpath
36
+ path.open('w') do |f|
37
+ incompatibilities[spec_path].sort_by(&:line_number).each do |record|
38
+ render_difference(f, path, record)
39
+ end
40
+ end
41
+ end
42
+ render_toc(markdown_root, incompatibilities.keys)
43
+ end
44
+
45
+ private
46
+
47
+ def render_haml(template, options)
48
+ obj = Object.new
49
+ Haml::Engine.new(template, {ugly: true, escape_html: true}.merge(options)).def_method(obj, :haml)
50
+ obj.haml
51
+ rescue Exception => e
52
+ e
53
+ end
54
+
55
+ def render_hamlit(template, options)
56
+ obj = Object.new
57
+ obj.instance_eval "def hamlit; #{Hamlit::Engine.new(options).call(template)}; end"
58
+ obj.hamlit
59
+ rescue Exception => e
60
+ e
61
+ end
62
+
63
+ def render_difference(file, path, record)
64
+ spec_path = Pathname.new(record.spec_path).relative_path_from(path.parent).to_s
65
+ file.write <<"EOS"
66
+ # [#{record.spec_path}:#{record.line_number}](#{spec_path}#L#{record.line_number})
67
+ ## #{render_input_title(record.options)}
68
+ ```haml
69
+ #{record.template}
70
+ ```
71
+
72
+ EOS
73
+ if record.faml_result != record.haml_result && record.faml_result != record.hamlit_result && record.haml_result != record.hamlit_result
74
+ render_grouped_difference(file, 'Faml' => record.faml_result, 'Haml' => record.haml_result, 'Hamlit' => record.hamlit_result)
75
+ elsif record.faml_result == record.haml_result
76
+ render_grouped_difference(file, 'Faml, Haml' => record.faml_result, 'Hamlit' => record.hamlit_result)
77
+ elsif record.faml_result == record.hamlit_result
78
+ render_grouped_difference(file, 'Faml, Hamlit' => record.faml_result, 'Haml' => record.haml_result)
79
+ else
80
+ render_grouped_difference(file, 'Faml' => record.faml_result, 'Haml, Hamlit' => record.haml_result)
81
+ end
82
+ end
83
+
84
+ def render_input_title(options)
85
+ title = 'Input'
86
+ if !options.empty?
87
+ title << " (with options=#{options.inspect})"
88
+ end
89
+ title
90
+ end
91
+
92
+ def render_grouped_difference(file, grouped_results)
93
+ grouped_results.each do |title, result|
94
+ file.write <<"EOS"
95
+ ## #{render_section(title, result)}
96
+ ```html
97
+ #{result}
98
+ ```
99
+
100
+ EOS
101
+ end
102
+ end
103
+
104
+ def render_section(title, result)
105
+ if result.is_a?(Exception)
106
+ "#{title} (Error)"
107
+ else
108
+ title
109
+ end
110
+ end
111
+
112
+ def markdown_path(markdown_root, spec_path)
113
+ markdown_root.join(spec_path).sub_ext('.md')
114
+ end
115
+
116
+ def render_toc(markdown_root, spec_paths)
117
+ toc_path = markdown_root.join('README.md')
118
+ toc_path.open('w') do |f|
119
+ f.puts '# Incompatibilities'
120
+ f.puts '## Versions'
121
+ f.puts "- Haml #{Haml::VERSION}"
122
+ f.puts "- Faml #{Faml::VERSION}"
123
+ f.puts "- Hamlit #{Hamlit::VERSION}"
124
+ f.puts
125
+ f.puts '## Table of contents'
126
+ spec_paths.sort.each do |spec_path|
127
+ path = markdown_path(markdown_root, spec_path).relative_path_from(markdown_root)
128
+ f.puts "- [#{path}](#{path})"
129
+ end
130
+ end
131
+ end
132
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.13
4
+ version: 0.2.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kohei Suzuki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-13 00:00:00.000000000 Z
11
+ date: 2015-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: escape_utils
@@ -298,6 +298,29 @@ files:
298
298
  - gemfiles/rails_4.2.gemfile
299
299
  - gemfiles/rails_edge.gemfile
300
300
  - haml_spec_test.rb
301
+ - incompatibilities/README.md
302
+ - incompatibilities/spec/compiler_newline_spec.md
303
+ - incompatibilities/spec/render/attribute_spec.md
304
+ - incompatibilities/spec/render/comment_spec.md
305
+ - incompatibilities/spec/render/doctype_spec.md
306
+ - incompatibilities/spec/render/element_spec.md
307
+ - incompatibilities/spec/render/filters/cdata_spec.md
308
+ - incompatibilities/spec/render/filters/coffee_spec.md
309
+ - incompatibilities/spec/render/filters/css_spec.md
310
+ - incompatibilities/spec/render/filters/escaped_spec.md
311
+ - incompatibilities/spec/render/filters/javascript_spec.md
312
+ - incompatibilities/spec/render/filters/markdown_spec.md
313
+ - incompatibilities/spec/render/filters/preserve_spec.md
314
+ - incompatibilities/spec/render/filters/sass_spec.md
315
+ - incompatibilities/spec/render/filters/scss_spec.md
316
+ - incompatibilities/spec/render/helpers_spec.md
317
+ - incompatibilities/spec/render/indent_spec.md
318
+ - incompatibilities/spec/render/multiline_spec.md
319
+ - incompatibilities/spec/render/newline_spec.md
320
+ - incompatibilities/spec/render/plain_spec.md
321
+ - incompatibilities/spec/render/sanitize_spec.md
322
+ - incompatibilities/spec/render/silent_script_spec.md
323
+ - incompatibilities/spec/render/unescape_spec.md
301
324
  - lib/faml.rb
302
325
  - lib/faml/ast.rb
303
326
  - lib/faml/cli.rb
@@ -417,6 +440,7 @@ files:
417
440
  - spec/render/filters_spec.rb
418
441
  - spec/render/haml_comment_spec.rb
419
442
  - spec/render/helpers_spec.rb
443
+ - spec/render/indent_spec.rb
420
444
  - spec/render/multiline_spec.rb
421
445
  - spec/render/newline_spec.rb
422
446
  - spec/render/plain_spec.rb
@@ -426,6 +450,7 @@ files:
426
450
  - spec/render/silent_script_spec.rb
427
451
  - spec/render/unescape_spec.rb
428
452
  - spec/spec_helper.rb
453
+ - spec/support/incompatibilities_generator.rb
429
454
  - spec/tilt_spec.rb
430
455
  homepage: https://github.com/eagletmt/faml
431
456
  licenses:
@@ -439,7 +464,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
439
464
  requirements:
440
465
  - - ">="
441
466
  - !ruby/object:Gem::Version
442
- version: '0'
467
+ version: 2.0.0
443
468
  required_rubygems_version: !ruby/object:Gem::Requirement
444
469
  requirements:
445
470
  - - ">="
@@ -452,6 +477,29 @@ signing_key:
452
477
  specification_version: 4
453
478
  summary: Faster implementation of Haml template language.
454
479
  test_files:
480
+ - incompatibilities/README.md
481
+ - incompatibilities/spec/compiler_newline_spec.md
482
+ - incompatibilities/spec/render/attribute_spec.md
483
+ - incompatibilities/spec/render/comment_spec.md
484
+ - incompatibilities/spec/render/doctype_spec.md
485
+ - incompatibilities/spec/render/element_spec.md
486
+ - incompatibilities/spec/render/filters/cdata_spec.md
487
+ - incompatibilities/spec/render/filters/coffee_spec.md
488
+ - incompatibilities/spec/render/filters/css_spec.md
489
+ - incompatibilities/spec/render/filters/escaped_spec.md
490
+ - incompatibilities/spec/render/filters/javascript_spec.md
491
+ - incompatibilities/spec/render/filters/markdown_spec.md
492
+ - incompatibilities/spec/render/filters/preserve_spec.md
493
+ - incompatibilities/spec/render/filters/sass_spec.md
494
+ - incompatibilities/spec/render/filters/scss_spec.md
495
+ - incompatibilities/spec/render/helpers_spec.md
496
+ - incompatibilities/spec/render/indent_spec.md
497
+ - incompatibilities/spec/render/multiline_spec.md
498
+ - incompatibilities/spec/render/newline_spec.md
499
+ - incompatibilities/spec/render/plain_spec.md
500
+ - incompatibilities/spec/render/sanitize_spec.md
501
+ - incompatibilities/spec/render/silent_script_spec.md
502
+ - incompatibilities/spec/render/unescape_spec.md
455
503
  - spec/compiler_newline_spec.rb
456
504
  - spec/rails/Rakefile
457
505
  - spec/rails/app/assets/images/.keep
@@ -532,6 +580,7 @@ test_files:
532
580
  - spec/render/filters_spec.rb
533
581
  - spec/render/haml_comment_spec.rb
534
582
  - spec/render/helpers_spec.rb
583
+ - spec/render/indent_spec.rb
535
584
  - spec/render/multiline_spec.rb
536
585
  - spec/render/newline_spec.rb
537
586
  - spec/render/plain_spec.rb
@@ -541,4 +590,5 @@ test_files:
541
590
  - spec/render/silent_script_spec.rb
542
591
  - spec/render/unescape_spec.rb
543
592
  - spec/spec_helper.rb
593
+ - spec/support/incompatibilities_generator.rb
544
594
  - spec/tilt_spec.rb