nirvdrum-less 1.1.4

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 (164) hide show
  1. data/.gitignore +4 -0
  2. data/LICENSE +179 -0
  3. data/README.md +39 -0
  4. data/Rakefile +90 -0
  5. data/VERSION +1 -0
  6. data/bin/lessc +86 -0
  7. data/less.gemspec +205 -0
  8. data/lib/ext.rb +62 -0
  9. data/lib/less.rb +33 -0
  10. data/lib/less/command.rb +106 -0
  11. data/lib/less/engine.rb +54 -0
  12. data/lib/less/engine/builder.rb +8 -0
  13. data/lib/less/engine/grammar/common.tt +29 -0
  14. data/lib/less/engine/grammar/entity.tt +139 -0
  15. data/lib/less/engine/grammar/less.tt +271 -0
  16. data/lib/less/engine/nodes.rb +9 -0
  17. data/lib/less/engine/nodes/element.rb +186 -0
  18. data/lib/less/engine/nodes/entity.rb +79 -0
  19. data/lib/less/engine/nodes/function.rb +79 -0
  20. data/lib/less/engine/nodes/literal.rb +167 -0
  21. data/lib/less/engine/nodes/property.rb +156 -0
  22. data/lib/less/engine/nodes/ruleset.rb +12 -0
  23. data/lib/less/engine/nodes/selector.rb +39 -0
  24. data/lib/vendor/treetop/.gitignore +7 -0
  25. data/lib/vendor/treetop/LICENSE +19 -0
  26. data/lib/vendor/treetop/README +164 -0
  27. data/lib/vendor/treetop/Rakefile +19 -0
  28. data/lib/vendor/treetop/benchmark/seqpar.gnuplot +15 -0
  29. data/lib/vendor/treetop/benchmark/seqpar.treetop +16 -0
  30. data/lib/vendor/treetop/benchmark/seqpar_benchmark.rb +107 -0
  31. data/lib/vendor/treetop/bin/tt +28 -0
  32. data/lib/vendor/treetop/lib/treetop.rb +8 -0
  33. data/lib/vendor/treetop/lib/treetop/bootstrap_gen_1_metagrammar.rb +45 -0
  34. data/lib/vendor/treetop/lib/treetop/compiler.rb +6 -0
  35. data/lib/vendor/treetop/lib/treetop/compiler/grammar_compiler.rb +42 -0
  36. data/lib/vendor/treetop/lib/treetop/compiler/lexical_address_space.rb +17 -0
  37. data/lib/vendor/treetop/lib/treetop/compiler/metagrammar.rb +3097 -0
  38. data/lib/vendor/treetop/lib/treetop/compiler/metagrammar.treetop +408 -0
  39. data/lib/vendor/treetop/lib/treetop/compiler/node_classes.rb +19 -0
  40. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/anything_symbol.rb +18 -0
  41. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/atomic_expression.rb +14 -0
  42. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/character_class.rb +24 -0
  43. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/choice.rb +31 -0
  44. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/declaration_sequence.rb +24 -0
  45. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/grammar.rb +28 -0
  46. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/inline_module.rb +27 -0
  47. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/nonterminal.rb +13 -0
  48. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/optional.rb +19 -0
  49. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/parenthesized_expression.rb +9 -0
  50. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/parsing_expression.rb +138 -0
  51. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/parsing_rule.rb +55 -0
  52. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/predicate.rb +45 -0
  53. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/repetition.rb +55 -0
  54. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/sequence.rb +68 -0
  55. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/terminal.rb +20 -0
  56. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/transient_prefix.rb +9 -0
  57. data/lib/vendor/treetop/lib/treetop/compiler/node_classes/treetop_file.rb +9 -0
  58. data/lib/vendor/treetop/lib/treetop/compiler/ruby_builder.rb +113 -0
  59. data/lib/vendor/treetop/lib/treetop/ruby_extensions.rb +2 -0
  60. data/lib/vendor/treetop/lib/treetop/ruby_extensions/string.rb +42 -0
  61. data/lib/vendor/treetop/lib/treetop/runtime.rb +5 -0
  62. data/lib/vendor/treetop/lib/treetop/runtime/compiled_parser.rb +105 -0
  63. data/lib/vendor/treetop/lib/treetop/runtime/interval_skip_list.rb +4 -0
  64. data/lib/vendor/treetop/lib/treetop/runtime/interval_skip_list/head_node.rb +15 -0
  65. data/lib/vendor/treetop/lib/treetop/runtime/interval_skip_list/interval_skip_list.rb +200 -0
  66. data/lib/vendor/treetop/lib/treetop/runtime/interval_skip_list/node.rb +164 -0
  67. data/lib/vendor/treetop/lib/treetop/runtime/syntax_node.rb +72 -0
  68. data/lib/vendor/treetop/lib/treetop/runtime/terminal_parse_failure.rb +16 -0
  69. data/lib/vendor/treetop/lib/treetop/runtime/terminal_syntax_node.rb +17 -0
  70. data/lib/vendor/treetop/lib/treetop/version.rb +9 -0
  71. data/lib/vendor/treetop/spec/compiler/and_predicate_spec.rb +36 -0
  72. data/lib/vendor/treetop/spec/compiler/anything_symbol_spec.rb +44 -0
  73. data/lib/vendor/treetop/spec/compiler/character_class_spec.rb +182 -0
  74. data/lib/vendor/treetop/spec/compiler/choice_spec.rb +80 -0
  75. data/lib/vendor/treetop/spec/compiler/circular_compilation_spec.rb +28 -0
  76. data/lib/vendor/treetop/spec/compiler/failure_propagation_functional_spec.rb +21 -0
  77. data/lib/vendor/treetop/spec/compiler/grammar_compiler_spec.rb +84 -0
  78. data/lib/vendor/treetop/spec/compiler/grammar_spec.rb +41 -0
  79. data/lib/vendor/treetop/spec/compiler/nonterminal_symbol_spec.rb +40 -0
  80. data/lib/vendor/treetop/spec/compiler/not_predicate_spec.rb +38 -0
  81. data/lib/vendor/treetop/spec/compiler/one_or_more_spec.rb +35 -0
  82. data/lib/vendor/treetop/spec/compiler/optional_spec.rb +37 -0
  83. data/lib/vendor/treetop/spec/compiler/parenthesized_expression_spec.rb +19 -0
  84. data/lib/vendor/treetop/spec/compiler/parsing_rule_spec.rb +32 -0
  85. data/lib/vendor/treetop/spec/compiler/sequence_spec.rb +115 -0
  86. data/lib/vendor/treetop/spec/compiler/terminal_spec.rb +81 -0
  87. data/lib/vendor/treetop/spec/compiler/terminal_symbol_spec.rb +37 -0
  88. data/lib/vendor/treetop/spec/compiler/test_grammar.treetop +7 -0
  89. data/lib/vendor/treetop/spec/compiler/test_grammar.tt +7 -0
  90. data/lib/vendor/treetop/spec/compiler/test_grammar_do.treetop +7 -0
  91. data/lib/vendor/treetop/spec/compiler/zero_or_more_spec.rb +56 -0
  92. data/lib/vendor/treetop/spec/composition/a.treetop +11 -0
  93. data/lib/vendor/treetop/spec/composition/b.treetop +11 -0
  94. data/lib/vendor/treetop/spec/composition/c.treetop +10 -0
  95. data/lib/vendor/treetop/spec/composition/d.treetop +10 -0
  96. data/lib/vendor/treetop/spec/composition/f.treetop +17 -0
  97. data/lib/vendor/treetop/spec/composition/grammar_composition_spec.rb +40 -0
  98. data/lib/vendor/treetop/spec/composition/subfolder/e_includes_c.treetop +15 -0
  99. data/lib/vendor/treetop/spec/ruby_extensions/string_spec.rb +32 -0
  100. data/lib/vendor/treetop/spec/runtime/compiled_parser_spec.rb +101 -0
  101. data/lib/vendor/treetop/spec/runtime/interval_skip_list/delete_spec.rb +147 -0
  102. data/lib/vendor/treetop/spec/runtime/interval_skip_list/expire_range_spec.rb +349 -0
  103. data/lib/vendor/treetop/spec/runtime/interval_skip_list/insert_and_delete_node.rb +385 -0
  104. data/lib/vendor/treetop/spec/runtime/interval_skip_list/insert_spec.rb +660 -0
  105. data/lib/vendor/treetop/spec/runtime/interval_skip_list/interval_skip_list_spec.graffle +6175 -0
  106. data/lib/vendor/treetop/spec/runtime/interval_skip_list/interval_skip_list_spec.rb +58 -0
  107. data/lib/vendor/treetop/spec/runtime/interval_skip_list/palindromic_fixture.rb +23 -0
  108. data/lib/vendor/treetop/spec/runtime/interval_skip_list/palindromic_fixture_spec.rb +164 -0
  109. data/lib/vendor/treetop/spec/runtime/interval_skip_list/spec_helper.rb +84 -0
  110. data/lib/vendor/treetop/spec/runtime/syntax_node_spec.rb +53 -0
  111. data/lib/vendor/treetop/spec/spec_helper.rb +106 -0
  112. data/lib/vendor/treetop/spec/spec_suite.rb +4 -0
  113. data/lib/vendor/treetop/treetop.gemspec +17 -0
  114. data/spec/command_spec.rb +102 -0
  115. data/spec/css/accessors.css +18 -0
  116. data/spec/css/big.css +3768 -0
  117. data/spec/css/colors.css +11 -0
  118. data/spec/css/comments.css +9 -0
  119. data/spec/css/css-3.css +2 -0
  120. data/spec/css/css.css +45 -0
  121. data/spec/css/functions.css +6 -0
  122. data/spec/css/import.css +12 -0
  123. data/spec/css/lazy-eval.css +1 -0
  124. data/spec/css/mixins-args.css +0 -0
  125. data/spec/css/mixins.css +28 -0
  126. data/spec/css/operations.css +28 -0
  127. data/spec/css/parens.css +16 -0
  128. data/spec/css/rulesets.css +17 -0
  129. data/spec/css/scope.css +11 -0
  130. data/spec/css/selectors.css +8 -0
  131. data/spec/css/strings.css +12 -0
  132. data/spec/css/variables.css +6 -0
  133. data/spec/css/whitespace.css +11 -0
  134. data/spec/engine_spec.rb +111 -0
  135. data/spec/less/accessors.less +20 -0
  136. data/spec/less/big.less +4810 -0
  137. data/spec/less/colors.less +34 -0
  138. data/spec/less/comments.less +46 -0
  139. data/spec/less/css-3.less +11 -0
  140. data/spec/less/css.less +98 -0
  141. data/spec/less/exceptions/mixed-units-error.less +3 -0
  142. data/spec/less/exceptions/name-error-1.0.less +3 -0
  143. data/spec/less/exceptions/syntax-error-1.0.less +3 -0
  144. data/spec/less/functions.less +6 -0
  145. data/spec/less/import.less +7 -0
  146. data/spec/less/import/import-test-a.less +2 -0
  147. data/spec/less/import/import-test-b.less +8 -0
  148. data/spec/less/import/import-test-c.less +6 -0
  149. data/spec/less/import/import-test-d.css +1 -0
  150. data/spec/less/lazy-eval.less +6 -0
  151. data/spec/less/mixins-args.less +0 -0
  152. data/spec/less/mixins.less +43 -0
  153. data/spec/less/operations.less +39 -0
  154. data/spec/less/parens.less +21 -0
  155. data/spec/less/rulesets.less +30 -0
  156. data/spec/less/scope.less +32 -0
  157. data/spec/less/selectors.less +15 -0
  158. data/spec/less/strings.less +14 -0
  159. data/spec/less/variables.less +18 -0
  160. data/spec/less/whitespace.less +30 -0
  161. data/spec/spec.css +82 -0
  162. data/spec/spec.less +148 -0
  163. data/spec/spec_helper.rb +8 -0
  164. metadata +219 -0
@@ -0,0 +1,164 @@
1
+ class IntervalSkipList
2
+ class Node < HeadNode
3
+ attr_accessor :key
4
+ attr_reader :markers, :endpoint_of
5
+
6
+ def initialize(key, height, path)
7
+ super(height)
8
+ @key = key
9
+ @markers = []
10
+ @endpoint_of = []
11
+ update_forward_pointers(path)
12
+ promote_markers(path)
13
+ end
14
+
15
+ def all_forward_markers
16
+ markers.flatten
17
+ end
18
+
19
+ def delete(path)
20
+ 0.upto(top_level) do |i|
21
+ path[i].forward[i] = forward[i]
22
+ end
23
+ demote_markers(path)
24
+ end
25
+
26
+ def propagate_length_change(length_change)
27
+ cur_node = self
28
+ while cur_node do
29
+ cur_node.key += length_change
30
+ cur_node = cur_node.forward[0]
31
+ end
32
+ end
33
+
34
+ protected
35
+
36
+ def update_forward_pointers(path)
37
+ 0.upto(top_level) do |i|
38
+ forward[i] = path[i].forward[i]
39
+ path[i].forward[i] = self
40
+ end
41
+ end
42
+
43
+ def promote_markers(path)
44
+ promoted = []
45
+ new_promoted = []
46
+ 0.upto(top_level) do |i|
47
+ incoming_markers = path[i].forward_markers[i]
48
+ markers.concat(incoming_markers)
49
+
50
+ incoming_markers.each do |marker|
51
+ if can_be_promoted_higher?(marker, i)
52
+ new_promoted.push(marker)
53
+ forward[i].delete_marker_from_path(marker, i, forward[i+1])
54
+ else
55
+ forward_markers[i].push(marker)
56
+ end
57
+ end
58
+
59
+ promoted.each do |marker|
60
+ if can_be_promoted_higher?(marker, i)
61
+ new_promoted.push(marker)
62
+ forward[i].delete_marker_from_path(marker, i, forward[i+1])
63
+ else
64
+ forward_markers[i].push(marker)
65
+ end
66
+ end
67
+
68
+ promoted = new_promoted
69
+ new_promoted = []
70
+ end
71
+ end
72
+
73
+
74
+ def can_be_promoted_higher?(marker, level)
75
+ level < top_level && forward[level + 1] && forward[level + 1].markers.include?(marker)
76
+ end
77
+
78
+ def delete_marker_from_path(marker, level, terminus)
79
+ cur_node = self
80
+ until cur_node == terminus
81
+ cur_node.forward_markers[level].delete(marker)
82
+ cur_node.markers.delete(marker)
83
+ cur_node = cur_node.forward[level]
84
+ end
85
+ end
86
+
87
+ def demote_markers(path)
88
+ demote_inbound_markers(path)
89
+ demote_outbound_markers(path)
90
+ end
91
+
92
+ def demote_inbound_markers(path)
93
+ demoted = []
94
+ new_demoted = []
95
+
96
+ top_level.downto(0) do |i|
97
+ incoming_markers = path[i].forward_markers[i].dup
98
+ incoming_markers.each do |marker|
99
+ unless forward_node_with_marker_at_or_above_level?(marker, i)
100
+ path[i].forward_markers[i].delete(marker)
101
+ new_demoted.push(marker)
102
+ end
103
+ end
104
+
105
+ demoted.each do |marker|
106
+ path[i + 1].place_marker_on_inbound_path(marker, i, path[i])
107
+
108
+ if forward[i].markers.include?(marker)
109
+ path[i].forward_markers[i].push(marker)
110
+ else
111
+ new_demoted.push(marker)
112
+ end
113
+ end
114
+
115
+ demoted = new_demoted
116
+ new_demoted = []
117
+ end
118
+ end
119
+
120
+ def demote_outbound_markers(path)
121
+ demoted = []
122
+ new_demoted = []
123
+
124
+ top_level.downto(0) do |i|
125
+ forward_markers[i].each do |marker|
126
+ new_demoted.push(marker) unless path[i].forward_markers[i].include?(marker)
127
+ end
128
+
129
+ demoted.each do |marker|
130
+ forward[i].place_marker_on_outbound_path(marker, i, forward[i + 1])
131
+ new_demoted.push(marker) unless path[i].forward_markers[i].include?(marker)
132
+ end
133
+
134
+ demoted = new_demoted
135
+ new_demoted = []
136
+ end
137
+ end
138
+
139
+ def forward_node_with_marker_at_or_above_level?(marker, level)
140
+ level.upto(top_level) do |i|
141
+ return true if forward[i].markers.include?(marker)
142
+ end
143
+ false
144
+ end
145
+
146
+ def place_marker_on_outbound_path(marker, level, terminus)
147
+ cur_node = self
148
+ until cur_node == terminus
149
+ cur_node.forward_markers[level].push(marker)
150
+ cur_node.markers.push(marker)
151
+ cur_node = cur_node.forward[level]
152
+ end
153
+ end
154
+
155
+ def place_marker_on_inbound_path(marker, level, terminus)
156
+ cur_node = self
157
+ until cur_node == terminus
158
+ cur_node.forward_markers[level].push(marker)
159
+ cur_node = cur_node.forward[level]
160
+ cur_node.markers.push(marker)
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,72 @@
1
+ module Treetop
2
+ module Runtime
3
+ class SyntaxNode
4
+ attr_reader :input, :interval, :elements
5
+ attr_accessor :parent
6
+
7
+ def initialize(input, interval, elements = nil)
8
+ @input = input
9
+ @interval = interval
10
+ if @elements = elements
11
+ elements.each do |element|
12
+ element.parent = self
13
+ end
14
+ end
15
+ end
16
+
17
+ def terminal?
18
+ @elements.nil?
19
+ end
20
+
21
+ def nonterminal?
22
+ !terminal?
23
+ end
24
+
25
+ def text_value
26
+ input[interval]
27
+ end
28
+
29
+ def empty?
30
+ interval.first == interval.last && interval.exclude_end?
31
+ end
32
+
33
+ def extension_modules
34
+ local_extensions =
35
+ class <<self
36
+ included_modules-Object.included_modules
37
+ end
38
+ if local_extensions.size > 0
39
+ local_extensions
40
+ else
41
+ [] # There weren't any; must be a literal node
42
+ end
43
+ end
44
+
45
+ def inspect(indent="")
46
+ em = extension_modules
47
+ interesting_methods = methods-[em.last ? em.last.methods : nil]-self.class.instance_methods
48
+ im = interesting_methods.size > 0 ? " (#{interesting_methods.join(",")})" : ""
49
+ tv = text_value
50
+ tv = "...#{tv[-20..-1]}" if tv.size > 20
51
+
52
+ indent +
53
+ self.class.to_s.sub(/.*:/,'') +
54
+ em.map{|m| "+"+m.to_s.sub(/.*:/,'')}*"" +
55
+ " offset=#{interval.first}" +
56
+ ", #{tv.inspect}" +
57
+ im +
58
+ (elements && elements.size > 0 ?
59
+ ":" +
60
+ (@elements||[]).map{|e|
61
+ begin
62
+ "\n"+e.inspect(indent+" ")
63
+ rescue # Defend against inspect not taking a parameter
64
+ "\n"+indent+" "+e.inspect
65
+ end
66
+ }.join("") :
67
+ ""
68
+ )
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,16 @@
1
+ module Treetop
2
+ module Runtime
3
+ class TerminalParseFailure
4
+ attr_reader :index, :expected_string
5
+
6
+ def initialize(index, expected_string)
7
+ @index = index
8
+ @expected_string = expected_string
9
+ end
10
+
11
+ def to_s
12
+ "String matching #{expected_string} expected."
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Treetop
2
+ module Runtime
3
+ class TerminalSyntaxNode < SyntaxNode
4
+
5
+ def initialize(input, interval)
6
+ super(input, interval, [])
7
+ end
8
+
9
+ def inspect(indent="")
10
+ indent+
11
+ self.class.to_s.sub(/.*:/,'') +
12
+ " offset=#{interval.first}" +
13
+ " #{text_value.inspect}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ module Treetop #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 1
4
+ MINOR = 3
5
+ TINY = 0
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1,36 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ module AndPredicateSpec
4
+ describe "An &-predicated terminal symbol" do
5
+ testing_expression '&"foo"'
6
+
7
+ it "successfully parses input matching the terminal symbol, returning an epsilon syntax node" do
8
+ parse('foo', :consume_all_input => false) do |result|
9
+ result.should_not be_nil
10
+ result.interval.should == (0...0)
11
+ end
12
+ end
13
+ end
14
+
15
+ describe "A sequence of a terminal and an and another &-predicated terminal" do
16
+ testing_expression '"foo" &"bar"'
17
+
18
+ it "matches input matching both terminals, but only consumes the first" do
19
+ parse('foobar', :consume_all_input => false) do |result|
20
+ result.should_not be_nil
21
+ result.text_value.should == 'foo'
22
+ end
23
+ end
24
+
25
+ it "fails to parse input matching only the first terminal, with a terminal failure recorded at index 3" do
26
+ parse('foo') do |result|
27
+ result.should be_nil
28
+ terminal_failures = parser.terminal_failures
29
+ terminal_failures.size.should == 1
30
+ failure = terminal_failures[0]
31
+ failure.index.should == 3
32
+ failure.expected_string.should == 'bar'
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ module AnythingSymbolSpec
4
+ class Foo < Treetop::Runtime::SyntaxNode
5
+ end
6
+
7
+ describe "an anything symbol followed by a node class declaration and a block" do
8
+ testing_expression '. <AnythingSymbolSpec::Foo> { def a_method; end }'
9
+
10
+ it "matches any single character in a big range, returning an instance of the declared node class that responds to methods defined in the inline module" do
11
+ (33..127).each do |digit|
12
+ parse(digit.chr) do |result|
13
+ result.should_not be_nil
14
+ result.should be_an_instance_of(Foo)
15
+ result.should respond_to(:a_method)
16
+ result.interval.should == (0...1)
17
+ end
18
+ end
19
+ end
20
+
21
+ it "fails to parse epsilon" do
22
+ parse('').should be_nil
23
+ end
24
+ end
25
+
26
+ module ModFoo
27
+ end
28
+
29
+ describe "an anything symbol followed by a module declaration and a block" do
30
+ testing_expression '. <AnythingSymbolSpec::ModFoo> { def a_method; end }'
31
+
32
+ it "matches any single character in a big range, returning an instance of SyntaxNode extended by the declared module that responds to methods defined in the inline module" do
33
+ (33..127).each do |digit|
34
+ parse(digit.chr) do |result|
35
+ result.should_not be_nil
36
+ result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
37
+ result.should be_a_kind_of(ModFoo)
38
+ result.should respond_to(:a_method)
39
+ result.interval.should == (0...1)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,182 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ module CharacterClassSpec
4
+ class Foo < Treetop::Runtime::SyntaxNode
5
+ end
6
+
7
+ describe "a character class followed by a node class declaration and a block" do
8
+
9
+ testing_expression "[A-Z] <CharacterClassSpec::Foo> { def a_method; end }"
10
+
11
+ it "matches single characters within that range, returning instances of the declared node class that respond to the method defined in the inline module" do
12
+ result = parse('A')
13
+ result.should be_an_instance_of(Foo)
14
+ result.should respond_to(:a_method)
15
+ result = parse('N')
16
+ result.should be_an_instance_of(Foo)
17
+ result.should respond_to(:a_method)
18
+ result = parse('Z')
19
+ result.should be_an_instance_of(Foo)
20
+ result.should respond_to(:a_method)
21
+ end
22
+
23
+ it "does not match single characters outside of that range" do
24
+ parse('8').should be_nil
25
+ parse('a').should be_nil
26
+ end
27
+
28
+ it "matches a single character within that range at index 1" do
29
+ parse(' A', :index => 1).should_not be_nil
30
+ end
31
+
32
+ it "fails to match a single character out of that range at index 1" do
33
+ parse(' 1', :index => 1).should be_nil
34
+ end
35
+ end
36
+
37
+ module ModFoo
38
+ end
39
+
40
+ describe "a character class followed by a node module declaration and a block" do
41
+
42
+ testing_expression "[A-Z] <CharacterClassSpec::ModFoo> { def a_method; end }"
43
+
44
+ it "matches single characters within that range, returning instances of SyntaxNode extended by the specified module" do
45
+ result = parse('A')
46
+ result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
47
+ result.should be_a_kind_of(ModFoo)
48
+ result.should respond_to(:a_method)
49
+ result = parse('N')
50
+ result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
51
+ result.should be_a_kind_of(ModFoo)
52
+ result.should respond_to(:a_method)
53
+ result = parse('Z')
54
+ result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
55
+ result.should be_a_kind_of(ModFoo)
56
+ result.should respond_to(:a_method)
57
+ end
58
+
59
+ it "does not match single characters outside of that range" do
60
+ parse('8').should be_nil
61
+ parse('a').should be_nil
62
+ end
63
+
64
+ it "matches a single character within that range at index 1" do
65
+ parse(' A', :index => 1).should_not be_nil
66
+ end
67
+
68
+ it "fails to match a single character out of that range at index 1" do
69
+ parse(' 1', :index => 1).should be_nil
70
+ end
71
+ end
72
+
73
+ describe "A character class containing quotes" do
74
+ testing_expression "[\"']"
75
+
76
+ it "matches a quote" do
77
+ parse("'").should_not be_nil
78
+ end
79
+
80
+ it "matches a double-quote" do
81
+ parse('"').should_not be_nil
82
+ end
83
+ end
84
+
85
+ describe "A character class containing a special character" do
86
+ testing_expression "[\t]"
87
+ it "matches that character only" do
88
+ parse("\t").should_not be_nil
89
+ parse('t').should be_nil
90
+ end
91
+ end
92
+
93
+ describe "A character class containing an escaped backslash" do
94
+ slash = "\\" # Make it explicit that there are *two* backslashes here
95
+ testing_expression "[#{slash}#{slash}]"
96
+ it "matches a backslash only" do
97
+ parse("\\").should_not be_nil
98
+ parse('t').should be_nil
99
+ end
100
+ end
101
+
102
+ describe "A character class containing a hex escape" do
103
+ slash = "\\"
104
+ testing_expression "[#{slash}x41]"
105
+ it "matches that character only" do
106
+ parse('A').should_not be_nil
107
+ parse('\\').should be_nil
108
+ parse('x').should be_nil
109
+ parse('4').should be_nil
110
+ parse('1').should be_nil
111
+ end
112
+ end
113
+
114
+ describe "A character class containing an octal escape" do
115
+ slash = "\\"
116
+ testing_expression "[#{slash}101]"
117
+ it "matches that character only" do
118
+ parse('A').should_not be_nil
119
+ parse('\\').should be_nil
120
+ parse('1').should be_nil
121
+ parse('0').should be_nil
122
+ end
123
+ end
124
+
125
+ describe "A character class containing a \\c control-char escape" do
126
+ slash = "\\"
127
+ testing_expression "[#{slash}cC]"
128
+ it "matches that character only" do
129
+ parse("\003").should_not be_nil
130
+ parse('\\').should be_nil
131
+ parse('c').should be_nil
132
+ parse('C').should be_nil
133
+ end
134
+ end
135
+
136
+ describe "A character class containing a \\C- control-char escape" do
137
+ slash = "\\"
138
+ testing_expression "[#{slash}C-C]"
139
+ it "matches that character only" do
140
+ parse("\003").should_not be_nil
141
+ parse('\\').should be_nil
142
+ parse('C').should be_nil
143
+ parse('-').should be_nil
144
+ end
145
+ end
146
+
147
+ describe "A character class containing a \\M- meta-char escape" do
148
+ slash = "\\"
149
+ testing_expression "[#{slash}M- ]"
150
+ it "matches that character only" do
151
+ parse("\240").should_not be_nil
152
+ parse('\\').should be_nil
153
+ parse('M').should be_nil
154
+ parse('-').should be_nil
155
+ parse(' ').should be_nil
156
+ end
157
+ end
158
+
159
+ describe "A character class containing an escaped non-special character" do
160
+ slash = "\\"
161
+ testing_expression "[#{slash}y]"
162
+ it "matches that character only" do
163
+ parse("y").should_not be_nil
164
+ parse('\\').should be_nil
165
+ end
166
+ end
167
+
168
+ describe "A character class containing an \#{...} insertion" do
169
+ testing_expression "[\#{raise 'error'}]"
170
+ it "doesn't evaluate the insertion" do
171
+ x = true
172
+ lambda{
173
+ x = parse("y")
174
+ }.should_not raise_error
175
+ x.should be_nil
176
+ parse('#').should_not be_nil
177
+ parse("'").should_not be_nil
178
+ parse("0").should be_nil
179
+ end
180
+ end
181
+
182
+ end