walrus 0.1

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 (208) hide show
  1. data/bin/walrus +44 -0
  2. data/ext/jindex/extconf.rb +11 -0
  3. data/ext/jindex/jindex.c +79 -0
  4. data/ext/mkdtemp/extconf.rb +11 -0
  5. data/ext/mkdtemp/mkdtemp.c +41 -0
  6. data/lib/walrus/additions/module.rb +36 -0
  7. data/lib/walrus/additions/string.rb +37 -0
  8. data/lib/walrus/additions/test/unit/error_collector.rb +62 -0
  9. data/lib/walrus/compile_error.rb +28 -0
  10. data/lib/walrus/compiler.rb +124 -0
  11. data/lib/walrus/contrib/spec/walruscloth_spec.rb +32 -0
  12. data/lib/walrus/contrib/walruscloth.rb +82 -0
  13. data/lib/walrus/diff.rb +89 -0
  14. data/lib/walrus/document.rb +98 -0
  15. data/lib/walrus/grammar/additions/proc.rb +20 -0
  16. data/lib/walrus/grammar/additions/regexp.rb +21 -0
  17. data/lib/walrus/grammar/additions/string.rb +52 -0
  18. data/lib/walrus/grammar/additions/symbol.rb +42 -0
  19. data/lib/walrus/grammar/and_predicate.rb +40 -0
  20. data/lib/walrus/grammar/array_result.rb +19 -0
  21. data/lib/walrus/grammar/continuation_wrapper_exception.rb +28 -0
  22. data/lib/walrus/grammar/left_recursion_exception.rb +27 -0
  23. data/lib/walrus/grammar/location_tracking.rb +105 -0
  24. data/lib/walrus/grammar/match_data_wrapper.rb +65 -0
  25. data/lib/walrus/grammar/memoizing.rb +41 -0
  26. data/lib/walrus/grammar/memoizing_cache.rb +94 -0
  27. data/lib/walrus/grammar/node.rb +60 -0
  28. data/lib/walrus/grammar/not_predicate.rb +40 -0
  29. data/lib/walrus/grammar/parse_error.rb +39 -0
  30. data/lib/walrus/grammar/parser_state.rb +181 -0
  31. data/lib/walrus/grammar/parslet.rb +28 -0
  32. data/lib/walrus/grammar/parslet_choice.rb +120 -0
  33. data/lib/walrus/grammar/parslet_combination.rb +26 -0
  34. data/lib/walrus/grammar/parslet_combining.rb +154 -0
  35. data/lib/walrus/grammar/parslet_merge.rb +88 -0
  36. data/lib/walrus/grammar/parslet_omission.rb +57 -0
  37. data/lib/walrus/grammar/parslet_repetition.rb +97 -0
  38. data/lib/walrus/grammar/parslet_repetition_default.rb +58 -0
  39. data/lib/walrus/grammar/parslet_sequence.rb +202 -0
  40. data/lib/walrus/grammar/predicate.rb +57 -0
  41. data/lib/walrus/grammar/proc_parslet.rb +52 -0
  42. data/lib/walrus/grammar/regexp_parslet.rb +73 -0
  43. data/lib/walrus/grammar/skipped_substring_exception.rb +36 -0
  44. data/lib/walrus/grammar/string_enumerator.rb +45 -0
  45. data/lib/walrus/grammar/string_parslet.rb +75 -0
  46. data/lib/walrus/grammar/string_result.rb +24 -0
  47. data/lib/walrus/grammar/symbol_parslet.rb +63 -0
  48. data/lib/walrus/grammar.rb +170 -0
  49. data/lib/walrus/no_parameter_marker.rb +19 -0
  50. data/lib/walrus/parser.rb +420 -0
  51. data/lib/walrus/runner.rb +356 -0
  52. data/lib/walrus/template.rb +75 -0
  53. data/lib/walrus/walrus_grammar/assignment_expression.rb +24 -0
  54. data/lib/walrus/walrus_grammar/block_directive.rb +28 -0
  55. data/lib/walrus/walrus_grammar/comment.rb +24 -0
  56. data/lib/walrus/walrus_grammar/def_directive.rb +64 -0
  57. data/lib/walrus/walrus_grammar/echo_directive.rb +44 -0
  58. data/lib/walrus/walrus_grammar/escape_sequence.rb +24 -0
  59. data/lib/walrus/walrus_grammar/import_directive.rb +44 -0
  60. data/lib/walrus/walrus_grammar/include_directive.rb +27 -0
  61. data/lib/walrus/walrus_grammar/instance_variable.rb +24 -0
  62. data/lib/walrus/walrus_grammar/literal.rb +24 -0
  63. data/lib/walrus/walrus_grammar/message_expression.rb +25 -0
  64. data/lib/walrus/walrus_grammar/multiline_comment.rb +54 -0
  65. data/lib/walrus/walrus_grammar/placeholder.rb +40 -0
  66. data/lib/walrus/walrus_grammar/raw_directive.rb +42 -0
  67. data/lib/walrus/walrus_grammar/raw_text.rb +45 -0
  68. data/lib/walrus/walrus_grammar/ruby_directive.rb +29 -0
  69. data/lib/walrus/walrus_grammar/ruby_expression.rb +31 -0
  70. data/lib/walrus/walrus_grammar/set_directive.rb +24 -0
  71. data/lib/walrus/walrus_grammar/silent_directive.rb +44 -0
  72. data/lib/walrus/walrus_grammar/slurp_directive.rb +25 -0
  73. data/lib/walrus/walrus_grammar/super_directive.rb +27 -0
  74. data/lib/walrus.rb +64 -0
  75. data/spec/acceptance/acceptance_spec.rb +97 -0
  76. data/spec/acceptance/block/basic_block.expected +1 -0
  77. data/spec/acceptance/block/basic_block.tmpl +3 -0
  78. data/spec/acceptance/block/nested_blocks.expected +5 -0
  79. data/spec/acceptance/block/nested_blocks.tmpl +11 -0
  80. data/spec/acceptance/comments/comments_and_text.expected +3 -0
  81. data/spec/acceptance/comments/comments_and_text.tmpl +6 -0
  82. data/spec/acceptance/comments/single_comment.expected +0 -0
  83. data/spec/acceptance/comments/single_comment.tmpl +1 -0
  84. data/spec/acceptance/def/alternative_def_calling_conventions.expected +3 -0
  85. data/spec/acceptance/def/alternative_def_calling_conventions.tmpl +18 -0
  86. data/spec/acceptance/def/basic_def_block_no_output.expected +0 -0
  87. data/spec/acceptance/def/basic_def_block_no_output.tmpl +17 -0
  88. data/spec/acceptance/def/defs_can_be_called_multiple_times.expected +3 -0
  89. data/spec/acceptance/def/defs_can_be_called_multiple_times.tmpl +6 -0
  90. data/spec/acceptance/def/defs_can_be_dynamic.expected +4 -0
  91. data/spec/acceptance/def/defs_can_be_dynamic.tmpl +12 -0
  92. data/spec/acceptance/echo/echo_directive_with_numeric_literal.expected +1 -0
  93. data/spec/acceptance/echo/echo_directive_with_numeric_literal.tmpl +1 -0
  94. data/spec/acceptance/echo/echo_expression_list.expected +1 -0
  95. data/spec/acceptance/echo/echo_expression_list.tmpl +1 -0
  96. data/spec/acceptance/echo/echo_short_notation.expected +1 -0
  97. data/spec/acceptance/echo/echo_short_notation.tmpl +1 -0
  98. data/spec/acceptance/echo/echo_simple_expression.expected +1 -0
  99. data/spec/acceptance/echo/echo_simple_expression.tmpl +1 -0
  100. data/spec/acceptance/echo/echo_single_quoted_string_literal.expected +1 -0
  101. data/spec/acceptance/echo/echo_single_quoted_string_literal.tmpl +1 -0
  102. data/spec/acceptance/echo/multiple_echo_statements.expected +1 -0
  103. data/spec/acceptance/echo/multiple_echo_statements.tmpl +2 -0
  104. data/spec/acceptance/includes/basic_included_file.txt +1 -0
  105. data/spec/acceptance/includes/basic_includer.complex +3 -0
  106. data/spec/acceptance/includes/basic_includer.expected +3 -0
  107. data/spec/acceptance/includes/basic_includer.rb +38 -0
  108. data/spec/acceptance/includes/complicated_included_file.txt +3 -0
  109. data/spec/acceptance/includes/complicated_includer.complex +3 -0
  110. data/spec/acceptance/includes/complicated_includer.expected +3 -0
  111. data/spec/acceptance/includes/complicated_includer.rb +41 -0
  112. data/spec/acceptance/includes/nested_include_1.txt +3 -0
  113. data/spec/acceptance/includes/nested_include_2.txt +1 -0
  114. data/spec/acceptance/includes/nested_includer.complex +3 -0
  115. data/spec/acceptance/includes/nested_includer.expected +4 -0
  116. data/spec/acceptance/includes/nested_includer.rb +41 -0
  117. data/spec/acceptance/inheritance/basic_child.complex +10 -0
  118. data/spec/acceptance/inheritance/basic_child.expected +9 -0
  119. data/spec/acceptance/inheritance/basic_child.rb +54 -0
  120. data/spec/acceptance/inheritance/basic_parent.complex +5 -0
  121. data/spec/acceptance/inheritance/basic_parent.expected +3 -0
  122. data/spec/acceptance/inheritance/basic_parent.rb +41 -0
  123. data/spec/acceptance/inheritance/importing_child.complex +8 -0
  124. data/spec/acceptance/inheritance/importing_child.expected +7 -0
  125. data/spec/acceptance/inheritance/importing_child.rb +46 -0
  126. data/spec/acceptance/inheritance/subdirectory/importing_child_in_subdirectory.complex +8 -0
  127. data/spec/acceptance/inheritance/subdirectory/importing_child_in_subdirectory.expected +7 -0
  128. data/spec/acceptance/inheritance/subdirectory/importing_child_in_subdirectory.rb +44 -0
  129. data/spec/acceptance/multiline_comments/multiline_comment_with_directives_inside.expected +0 -0
  130. data/spec/acceptance/multiline_comments/multiline_comment_with_directives_inside.tmpl +15 -0
  131. data/spec/acceptance/multiline_comments/simple_multiline_comment.expected +2 -0
  132. data/spec/acceptance/multiline_comments/simple_multiline_comment.tmpl +4 -0
  133. data/spec/acceptance/raw/complicated_raw_example.expected +57 -0
  134. data/spec/acceptance/raw/complicated_raw_example.tmpl +79 -0
  135. data/spec/acceptance/raw-text/UTF_8.expected +12 -0
  136. data/spec/acceptance/raw-text/UTF_8.tmpl +12 -0
  137. data/spec/acceptance/raw-text/empty_file.expected +0 -0
  138. data/spec/acceptance/raw-text/empty_file.tmpl +0 -0
  139. data/spec/acceptance/raw-text/multi_line.expected +4 -0
  140. data/spec/acceptance/raw-text/multi_line.tmpl +4 -0
  141. data/spec/acceptance/raw-text/single_line.expected +1 -0
  142. data/spec/acceptance/raw-text/single_line.tmpl +1 -0
  143. data/spec/acceptance/raw-text/single_line_whitespace.expected +1 -0
  144. data/spec/acceptance/raw-text/single_line_whitespace.tmpl +1 -0
  145. data/spec/acceptance/ruby/ruby_directive_is_just_like_silent.expected +1 -0
  146. data/spec/acceptance/ruby/ruby_directive_is_just_like_silent.tmpl +4 -0
  147. data/spec/acceptance/ruby/ruby_directive_using_here_doc.expected +1 -0
  148. data/spec/acceptance/ruby/ruby_directive_using_here_doc.tmpl +4 -0
  149. data/spec/acceptance/ruby/ruby_directive_using_here_doc_alt_syntax.expected +1 -0
  150. data/spec/acceptance/ruby/ruby_directive_using_here_doc_alt_syntax.tmpl +4 -0
  151. data/spec/acceptance/ruby/ruby_directive_with_accumulate.expected +1 -0
  152. data/spec/acceptance/ruby/ruby_directive_with_accumulate.tmpl +4 -0
  153. data/spec/acceptance/ruby/ruby_directive_with_accumulate_and_block.expected +1 -0
  154. data/spec/acceptance/ruby/ruby_directive_with_accumulate_and_block.tmpl +6 -0
  155. data/spec/acceptance/set/unused_set.expected +0 -0
  156. data/spec/acceptance/set/unused_set.tmpl +1 -0
  157. data/spec/acceptance/set/used_set.expected +1 -0
  158. data/spec/acceptance/set/used_set.tmpl +2 -0
  159. data/spec/acceptance/silent/silent_and_echo_combined.expected +1 -0
  160. data/spec/acceptance/silent/silent_and_echo_combined.tmpl +2 -0
  161. data/spec/acceptance/silent/silent_short_notation.expected +1 -0
  162. data/spec/acceptance/silent/silent_short_notation.tmpl +1 -0
  163. data/spec/acceptance/silent/simple_silent_directive.expected +0 -0
  164. data/spec/acceptance/silent/simple_silent_directive.tmpl +1 -0
  165. data/spec/acceptance/slurp/basic_slurp_demo.expected +1 -0
  166. data/spec/acceptance/slurp/basic_slurp_demo.tmpl +4 -0
  167. data/spec/acceptance/super/super_with_no_effect.expected +4 -0
  168. data/spec/acceptance/super/super_with_no_effect.tmpl +5 -0
  169. data/spec/additions/module_spec.rb +126 -0
  170. data/spec/additions/string_spec.rb +99 -0
  171. data/spec/compiler_spec.rb +55 -0
  172. data/spec/grammar/additions/proc_spec.rb +25 -0
  173. data/spec/grammar/additions/regexp_spec.rb +37 -0
  174. data/spec/grammar/additions/string_spec.rb +106 -0
  175. data/spec/grammar/and_predicate_spec.rb +29 -0
  176. data/spec/grammar/continuation_wrapper_exception_spec.rb +23 -0
  177. data/spec/grammar/match_data_wrapper_spec.rb +41 -0
  178. data/spec/grammar/memoizing_cache_spec.rb +112 -0
  179. data/spec/grammar/node_spec.rb +126 -0
  180. data/spec/grammar/not_predicate_spec.rb +29 -0
  181. data/spec/grammar/parser_state_spec.rb +172 -0
  182. data/spec/grammar/parslet_choice_spec.rb +49 -0
  183. data/spec/grammar/parslet_combining_spec.rb +287 -0
  184. data/spec/grammar/parslet_merge_spec.rb +33 -0
  185. data/spec/grammar/parslet_omission_spec.rb +58 -0
  186. data/spec/grammar/parslet_repetition_spec.rb +77 -0
  187. data/spec/grammar/parslet_sequence_spec.rb +49 -0
  188. data/spec/grammar/parslet_spec.rb +23 -0
  189. data/spec/grammar/predicate_spec.rb +53 -0
  190. data/spec/grammar/proc_parslet_spec.rb +52 -0
  191. data/spec/grammar/regexp_parslet_spec.rb +347 -0
  192. data/spec/grammar/string_enumerator_spec.rb +94 -0
  193. data/spec/grammar/string_parslet_spec.rb +143 -0
  194. data/spec/grammar/symbol_parslet_spec.rb +30 -0
  195. data/spec/grammar_spec.rb +545 -0
  196. data/spec/parser_spec.rb +1418 -0
  197. data/spec/spec_helper.rb +34 -0
  198. data/spec/walrus_grammar/comment_spec.rb +39 -0
  199. data/spec/walrus_grammar/echo_directive_spec.rb +63 -0
  200. data/spec/walrus_grammar/escape_sequence_spec.rb +85 -0
  201. data/spec/walrus_grammar/literal_spec.rb +41 -0
  202. data/spec/walrus_grammar/message_expression_spec.rb +37 -0
  203. data/spec/walrus_grammar/multiline_comment_spec.rb +58 -0
  204. data/spec/walrus_grammar/placeholder_spec.rb +48 -0
  205. data/spec/walrus_grammar/raw_directive_spec.rb +81 -0
  206. data/spec/walrus_grammar/raw_text_spec.rb +65 -0
  207. data/spec/walrus_grammar/silent_directive_spec.rb +34 -0
  208. metadata +291 -0
@@ -0,0 +1,79 @@
1
+ This example demonstrates a number of different uses of the \#raw directive.
2
+ In this paragraph if I want to use characters that have a special meaning for
3
+ Walrus then I have to escape them (example, a \$placeholder, a \#directive, an
4
+ \\\$ escape sequence).
5
+
6
+ #raw
7
+ But this paragraph is different, it is inside a #raw block.
8
+ I can do anything at all in the #raw block without having to escape it.
9
+ For example, use Walrus directives:
10
+ #super, #set a = b
11
+ Use placeholders:
12
+ $a, $b, $c
13
+ Use backslashes:
14
+ \n, \t, \m, \n, \o
15
+ #end
16
+
17
+ #raw
18
+ This paragraph is another example where the closing marker is not
19
+ on a new line of it's own...#end
20
+
21
+ #raw#This is an example where I use an explicit directive-closing marker (#) so that
22
+ I can start my #raw content on the same line as the opening directive. I can do the
23
+ same trick with the closing directive so that my text can continue on on the same
24
+ line...#end# See?
25
+
26
+ #raw <<HERE
27
+ This paragraph uses a "here document". That means I can include a literal #end directive
28
+ in it without it causing the block to come to an end. Here we see the block continuing
29
+ and I can still use $placeholders and #directives without them having any special meaning.
30
+ The end marker (in this case "HERE") must be the first and last thing on the line in order
31
+ for it to be detected. All other uses of the end marker go through literally with no
32
+ special meaning.
33
+ HERE
34
+
35
+ #raw
36
+ There is no way to include a literal end directive in a #raw block without the help of
37
+ a "here document". You can't escape the end directive for example, because the escape
38
+ character (\) has no special meaning in a #raw block. Notice that if I try it it won't
39
+ work:\#end
40
+
41
+ I am now outside the \#raw block because the \#end directive was interpreted as an end marker
42
+ despite my attempt to escape it.
43
+
44
+ #raw <<-THERE
45
+ This is an example of an alternative "here document" syntax. The hyphen means that you can
46
+ precede the end marker with whitespace. Note that if the marker (in this case "THERE") is
47
+ preceded by non-whitespace characters on the same line then it has no special meaning: THERE
48
+ Likewise, if it is followed by such characters then it has no meaning either....
49
+ THERE... we keep going because "THERE" wasn't the last thing on the line.
50
+ THERE
51
+
52
+ #raw <<ANOTHER
53
+ Trailing whitespace is acceptable after the end marker, but it is not included in the output.
54
+ ANOTHER
55
+
56
+ #raw <<-YET_ANOTHER
57
+ The same is true when using the alternative syntax.
58
+ YET_ANOTHER
59
+
60
+ #raw <<BAZ
61
+ In fact, trailing whitespace is acceptable when first opening the here document too, but it
62
+ is ignored
63
+ BAZ
64
+
65
+ #raw <<-BAZ
66
+ THe same is true for the alternate syntax.
67
+ BAZ
68
+
69
+ #raw <<-FOOBAR
70
+ Note that when using the alternative "here document" syntax the optional whitespace before the
71
+ end marker truly is optional; that is, the end marker can be the first thing on the line if
72
+ you want it to. (Although if that's the case you may as well use the first syntax.)
73
+ FOOBAR
74
+
75
+ #raw
76
+ In this example I am going to use some multi-byte characters:
77
+ €áéíóú
78
+ àèìòù
79
+ #end
@@ -0,0 +1,12 @@
1
+ This is a simple template that contains some non-ASCII characters.
2
+
3
+ Cañon, información, pengüino, Alcalá, élite, ícono, €, ©, ¿?, ¡!, ªº
4
+
5
+ áéíúó
6
+ ÁÉÍÓÚ
7
+ äëïöü
8
+ ÄËÏÖÜ
9
+ àèìòù
10
+ ÀÈÌÙÒ
11
+ âêîôû
12
+ ÂÊÎÔÛ
@@ -0,0 +1,12 @@
1
+ This is a simple template that contains some non-ASCII characters.
2
+
3
+ Cañon, información, pengüino, Alcalá, élite, ícono, €, ©, ¿?, ¡!, ªº
4
+
5
+ áéíúó
6
+ ÁÉÍÓÚ
7
+ äëïöü
8
+ ÄËÏÖÜ
9
+ àèìòù
10
+ ÀÈÌÙÒ
11
+ âêîôû
12
+ ÂÊÎÔÛ
File without changes
File without changes
@@ -0,0 +1,4 @@
1
+ This is a basic template containing a number of lines.
2
+ Second line.
3
+ Third line.
4
+ Fourth line with trailing whitespace...
@@ -0,0 +1,4 @@
1
+ This is a basic template containing a number of lines.
2
+ Second line.
3
+ Third line.
4
+ Fourth line with trailing whitespace...
@@ -0,0 +1 @@
1
+ This is a basic template containing only a single line.
@@ -0,0 +1 @@
1
+ This is a basic template containing only a single line.
@@ -0,0 +1 @@
1
+ This is a single-line template with whitespace on the left and right; this is a tab:
@@ -0,0 +1 @@
1
+ This is a single-line template with whitespace on the left and right; this is a tab:
@@ -0,0 +1 @@
1
+ the secret ivar is foo
@@ -0,0 +1,4 @@
1
+ #ruby
2
+ @secret_ivar = 'foo'
3
+ #end
4
+ #echo 'the secret ivar is '; @secret_ivar
@@ -0,0 +1 @@
1
+ I can use a literal #end in this one
@@ -0,0 +1,4 @@
1
+ #ruby <<HERE
2
+ accumulate 'I can use a literal #end in this one'
3
+ #end, #end, and #end again...
4
+ HERE
@@ -0,0 +1 @@
1
+ I can use a literal #end in this one
@@ -0,0 +1,4 @@
1
+ #ruby <<-HERE
2
+ accumulate 'I can use a literal #end in this one'
3
+ #end, #end, and #end again...
4
+ HERE
@@ -0,0 +1,4 @@
1
+ #ruby
2
+ # You can explicitly use the accumulate method if you want to produce output from inside a #ruby block
3
+ accumulate 'Hello, world!'
4
+ #end
@@ -0,0 +1,6 @@
1
+ #ruby
2
+ # You can explicitly use the accumulate method if you want to produce output from inside a #ruby block
3
+ accumulate do
4
+ 'Hello, world!'
5
+ end
6
+ #end
File without changes
@@ -0,0 +1 @@
1
+ #set $foo = 'bar'
@@ -0,0 +1 @@
1
+ bar
@@ -0,0 +1,2 @@
1
+ #set $foo = 'bar'
2
+ $foo
@@ -0,0 +1 @@
1
+ the secret ivar is foo
@@ -0,0 +1,2 @@
1
+ #silent @secret_ivar = 'foo'
2
+ #echo 'the secret ivar is '; @secret_ivar
@@ -0,0 +1 @@
1
+ the secret ivar is foo
@@ -0,0 +1 @@
1
+ # @secret_ivar = 'foo' ##echo 'the secret ivar is '; @secret_ivar
@@ -0,0 +1 @@
1
+ #silent 'foo'
@@ -0,0 +1 @@
1
+ The #slurp directive can be used to gobble up a trailing newline. This template consists of several lines of text, but thanks to the use of the #slurp directive the newlines are all gobbled up and the final output appears all on one line.
@@ -0,0 +1,4 @@
1
+ The \#slurp directive can be used to gobble up a trailing newline. #slurp
2
+ This template consists of several lines of text, but thanks to the #slurp
3
+ use of the \#slurp directive the newlines are all gobbled up and #slurp
4
+ the final output appears all on one line.
@@ -0,0 +1,4 @@
1
+ By default, text which appears in a template is considered to be part of the "template_body" block.
2
+ In the Document superclass from which all compiled templates ultimately inherit, the "template_body"
3
+ block is empty (it emits nothing). So, if I call #super from within the top-level of this template
4
+ it will have no effect on the output.
@@ -0,0 +1,5 @@
1
+ By default, text which appears in a template is considered to be part of the "template_body" block.
2
+ In the Document superclass from which all compiled templates ultimately inherit, the "template_body"
3
+ block is empty (it emits nothing). So, if I call \#super from within the top-level of this template
4
+ it will have no effect on the output.
5
+ #super
@@ -0,0 +1,126 @@
1
+ # Copyright 2007 Wincent Colaiuta
2
+ # This program is distributed in the hope that it will be useful, but WITHOUT
3
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5
+ # in the accompanying file, "LICENSE.txt", for more details.
6
+ #
7
+ # $Id: /mirrors/Walrus/trunk/walrus/spec/additions/module_spec.rb 6702 2007-04-09T15:04:40.448669Z wincent $
8
+
9
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
10
+
11
+ module Walrus
12
+
13
+ class ByCopyAccessDemo
14
+ attr_bycopy :foo
15
+ attr_bycopy :bar, false
16
+ attr_bycopy :baz, true
17
+ attr_writer_bycopy :beta
18
+ attr_accessor_bycopy :gamma
19
+ attr_writer_bycopy :beta2, :beta3
20
+ attr_accessor_bycopy :gamma2, :gamma3
21
+ end
22
+
23
+ describe 'using "by copy" accessors' do
24
+
25
+ setup do
26
+ @instance = ByCopyAccessDemo.new
27
+ end
28
+
29
+ it 'those accessors should be "private"' do
30
+ lambda { ByCopyAccessDemo.attr_bycopy :hello }.should raise_error(NoMethodError)
31
+ lambda { ByCopyAccessDemo.attr_writer_bycopy :hello }.should raise_error(NoMethodError)
32
+ lambda { ByCopyAccessDemo.attr_accessor_bycopy :hello }.should raise_error(NoMethodError)
33
+ end
34
+
35
+ it 'should accept "normal" objects like String, making copies of them' do
36
+
37
+ # original values
38
+ foo = "hello"
39
+ bar = "world"
40
+ baz = "..."
41
+ beta = "abc"
42
+ gamma = "def"
43
+ beta2 = "ghi"
44
+ beta3 = "jkl"
45
+ gamma2 = "mno"
46
+ gamma3 = "pqr"
47
+
48
+ # assignments
49
+ lambda { @instance.foo = foo }.should raise_error(NoMethodError) # no writer defined
50
+ lambda { @instance.bar = bar }.should raise_error(NoMethodError) # no writer defined
51
+ @instance.baz = baz
52
+ @instance.beta = beta
53
+ @instance.gamma = gamma
54
+ @instance.beta2 = beta2
55
+ @instance.beta3 = beta3
56
+ @instance.gamma2 = gamma2
57
+ @instance.gamma3 = gamma3
58
+
59
+ # check equality
60
+ @instance.baz.should == baz
61
+ @instance.instance_eval { @beta }.should == beta # no reader defined
62
+ @instance.gamma.should == gamma
63
+ @instance.instance_eval { @beta2 }.should == beta2 # no reader defined
64
+ @instance.instance_eval { @beta3 }.should == beta3 # no reader defined
65
+ @instance.gamma2.should == gamma2
66
+ @instance.gamma3.should == gamma3
67
+
68
+ # check that copies were made
69
+ @instance.baz.object_id.should_not == baz.object_id
70
+ @instance.instance_eval { @beta }.object_id.should_not == beta.object_id # no reader defined
71
+ @instance.gamma.object_id.should_not == gamma.object_id
72
+ @instance.instance_eval { @beta2 }.object_id.should_not == beta2.object_id # no reader defined
73
+ @instance.instance_eval { @beta3 }.object_id.should_not == beta3.object_id # no reader defined
74
+ @instance.gamma2.object_id.should_not == gamma2.object_id
75
+ @instance.gamma3.object_id.should_not == gamma3.object_id
76
+
77
+ end
78
+
79
+ it 'should accept non-copyable objects like instances of Nil, Symbol and Fixnum' do
80
+
81
+ # original values
82
+ foo = nil
83
+ bar = 1
84
+ baz = 2
85
+ beta = 3
86
+ gamma = 4
87
+ beta2 = nil
88
+ beta3 = 5
89
+ gamma2 = nil
90
+ gamma3 = :symbol
91
+
92
+ # assignments
93
+ lambda { @instance.foo = foo }.should raise_error(NoMethodError) # no writer defined
94
+ lambda { @instance.bar = bar }.should raise_error(NoMethodError) # no writer defined
95
+ @instance.baz = baz
96
+ @instance.beta = beta
97
+ @instance.gamma = gamma
98
+ @instance.beta2 = beta2
99
+ @instance.beta3 = beta3
100
+ @instance.gamma2 = gamma2
101
+ @instance.gamma3 = gamma3
102
+
103
+ # check equality
104
+ @instance.baz.should == baz
105
+ @instance.instance_eval { @beta }.should == beta # no reader defined
106
+ @instance.gamma.should == gamma
107
+ @instance.instance_eval { @beta2 }.should == beta2 # no reader defined
108
+ @instance.instance_eval { @beta3 }.should == beta3 # no reader defined
109
+ @instance.gamma2.should == gamma2
110
+ @instance.gamma3.should == gamma3
111
+
112
+ # check that copies were not made
113
+ @instance.baz.object_id.should == baz.object_id
114
+ @instance.instance_eval { @beta }.object_id.should == beta.object_id # no reader defined
115
+ @instance.gamma.object_id.should == gamma.object_id
116
+ @instance.instance_eval { @beta2 }.object_id.should == beta2.object_id # no reader defined
117
+ @instance.instance_eval { @beta3 }.object_id.should == beta3.object_id # no reader defined
118
+ @instance.gamma2.object_id.should == gamma2.object_id
119
+ @instance.gamma3.object_id.should == gamma3.object_id
120
+
121
+ end
122
+
123
+ end
124
+
125
+ end
126
+
@@ -0,0 +1,99 @@
1
+ # Copyright 2007 Wincent Colaiuta
2
+ # This program is distributed in the hope that it will be useful, but WITHOUT
3
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5
+ # in the accompanying file, "LICENSE.txt", for more details.
6
+ #
7
+ # $Id: /mirrors/Walrus/trunk/walrus/spec/additions/string_spec.rb 6702 2007-04-09T15:04:40.448669Z wincent $
8
+
9
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
10
+
11
+ describe 'converting from class names to require names' do
12
+
13
+ it 'should work with single letters' do
14
+ 'A'.to_require_name.should == 'a'
15
+ end
16
+
17
+ it 'should work with runs of capitals' do
18
+ 'EOLToken'.to_require_name.should == 'eol_token'
19
+ end
20
+
21
+ it 'should work with consecutive underscores' do
22
+ 'EOL__Token'.to_require_name.should == 'eol__token'
23
+ 'EOL__token'.to_require_name.should == 'eol__token'
24
+ 'Eol__Token'.to_require_name.should == 'eol__token'
25
+ 'Eol__token'.to_require_name.should == 'eol__token'
26
+ end
27
+
28
+ it 'should work with trailing underscores' do
29
+ 'EOL__'.to_require_name.should == 'eol__'
30
+ 'Eol__'.to_require_name.should == 'eol__'
31
+ end
32
+
33
+ it 'should work with standard classnames' do
34
+ 'Foo'.to_require_name.should == 'foo'
35
+ 'MyURLHandler'.to_require_name.should == 'my_url_handler'
36
+ 'Signals37'.to_require_name.should == 'signals_37'
37
+ 'MyClass'.to_require_name.should == 'my_class'
38
+ 'Foo_bar'.to_require_name.should == 'foo_bar'
39
+ 'C99case'.to_require_name.should == 'c_99_case'
40
+ 'EOL99doFun'.to_require_name.should == 'eol_99_do_fun'
41
+ 'Foo_Bar'.to_require_name.should == 'foo_bar'
42
+ end
43
+
44
+ end
45
+
46
+ describe 'converting from require names to class names' do
47
+
48
+ it 'should work with standard case' do
49
+ 'foo_bar'.to_class_name.should == 'FooBar'
50
+ end
51
+
52
+ it 'should work with single-letter' do
53
+ 'f'.to_class_name.should == 'F'
54
+ end
55
+
56
+ it 'should work with double-underscores' do
57
+ 'foo__bar'.to_class_name.should == 'FooBar'
58
+ end
59
+
60
+ it 'should work with terminating double-underscores' do
61
+ 'foo__'.to_class_name.should == 'Foo'
62
+ end
63
+
64
+ it "shouldn't preserve uppercase acronym information lost on the conversion from class name to require name" do
65
+ 'eol_token'.to_class_name.should == 'EolToken'
66
+ end
67
+
68
+ end
69
+
70
+ describe 'converting to source strings' do
71
+
72
+ it 'standard strings should be unchanged' do
73
+ ''.to_source_string.should == ''
74
+ 'hello world'.to_source_string.should == 'hello world'
75
+ "hello\nworld".to_source_string.should == "hello\nworld"
76
+ end
77
+
78
+ it 'single quotes should be escaped' do
79
+ "'foo'".to_source_string.should == "\\'foo\\'"
80
+ end
81
+
82
+ it 'backslashes should be escaped' do
83
+ 'hello\\nworld'.to_source_string.should == "hello\\\\nworld"
84
+ end
85
+
86
+ it 'should work with Unicode characters' do
87
+ '€ información…'.to_source_string.should == '€ información…'
88
+ end
89
+
90
+ it 'should be able to round trip' do
91
+ eval("'" + ''.to_source_string + "'").should == ''
92
+ eval("'" + 'hello world'.to_source_string + "'").should == 'hello world'
93
+ eval("'" + "hello\nworld".to_source_string + "'").should == "hello\nworld"
94
+ eval("'" + "'foo'".to_source_string + "'").should == '\'foo\''
95
+ eval("'" + 'hello\\nworld'.to_source_string + "'").should == 'hello\\nworld'
96
+ eval("'" + '€ información…'.to_source_string + "'").should == '€ información…'
97
+ end
98
+
99
+ end
@@ -0,0 +1,55 @@
1
+ # Copyright 2007 Wincent Colaiuta
2
+ # This program is distributed in the hope that it will be useful, but WITHOUT
3
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5
+ # in the accompanying file, "LICENSE.txt", for more details.
6
+ #
7
+ # $Id: /mirrors/Walrus/trunk/walrus/spec/compiler_spec.rb 6720 2007-04-10T15:33:38.497892Z wincent $
8
+
9
+ require File.join(File.dirname(__FILE__), 'spec_helper.rb')
10
+ require 'walrus/parser' # ensure that WalrusGrammar is defined before continuing
11
+
12
+ module Walrus
13
+
14
+ class WalrusGrammar
15
+
16
+ describe 'using the Compiler class' do
17
+
18
+ context_setup do
19
+ @parser = Parser.new
20
+ end
21
+
22
+ it 'should be able to compile a comment followed by raw text' do
23
+
24
+ # note that trailing newline is eaten when the comment is the only thing on the newline
25
+ compiled = @parser.compile("## hello world\nhere's some raw text", :class_name => :CompilerSpecAlpha)
26
+ self.class.module_eval(compiled)
27
+ self.class::Walrus::WalrusGrammar::CompilerSpecAlpha.new.fill.should == "here's some raw text"
28
+
29
+ end
30
+
31
+ it 'should be able to compile raw text followed by a comment' do
32
+
33
+ # on the same line (note that trailing newline is not eaten)
34
+ compiled = @parser.compile("here's some raw text## hello world\n", :class_name => :CompilerSpecBeta)
35
+ self.class.module_eval(compiled)
36
+ self.class::Walrus::WalrusGrammar::CompilerSpecBeta.new.fill.should == "here's some raw text\n"
37
+
38
+ # on two separate lines (note that second trailing newline gets eaten)
39
+ compiled = @parser.compile("here's some raw text\n## hello world\n", :class_name => :CompilerSpecDelta)
40
+ self.class.module_eval(compiled)
41
+ self.class::Walrus::WalrusGrammar::CompilerSpecDelta.new.fill.should == "here's some raw text\n"
42
+
43
+ # same but with no trailing newline
44
+ compiled = @parser.compile("here's some raw text\n## hello world", :class_name => :CompilerSpecGamma)
45
+ self.class.module_eval(compiled)
46
+ self.class::Walrus::WalrusGrammar::CompilerSpecGamma.new.fill.should == "here's some raw text\n"
47
+
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+
54
+ end # module Walrus
55
+
@@ -0,0 +1,25 @@
1
+ # Copyright 2007 Wincent Colaiuta
2
+ # This program is distributed in the hope that it will be useful, but WITHOUT
3
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5
+ # in the accompanying file, "LICENSE.txt", for more details.
6
+ #
7
+ # $Id: /mirrors/Walrus/trunk/walrus/spec/grammar/additions/proc_spec.rb 6702 2007-04-09T15:04:40.448669Z wincent $
8
+
9
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper.rb')
10
+
11
+ module Walrus
12
+ class Grammar
13
+
14
+ describe 'work with Proc instances' do
15
+
16
+ it 'should respond to "to_parseable", "parse" and "memoizing_parse"' do
17
+ proc = lambda { |string, options| 'foo' }.to_parseable
18
+ proc.parse('bar').should == 'foo'
19
+ proc.memoizing_parse('bar').should == 'foo'
20
+ end
21
+
22
+ end
23
+
24
+ end # class Grammar
25
+ end # module Walrus
@@ -0,0 +1,37 @@
1
+ # Copyright 2007 Wincent Colaiuta
2
+ # This program is distributed in the hope that it will be useful, but WITHOUT
3
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5
+ # in the accompanying file, "LICENSE.txt", for more details.
6
+ #
7
+ # $Id: /mirrors/Walrus/trunk/walrus/spec/grammar/additions/regexp_spec.rb 6702 2007-04-09T15:04:40.448669Z wincent $
8
+
9
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper.rb')
10
+
11
+ module Walrus
12
+ class Grammar
13
+
14
+ # For more detailed specification of the RegexpParslet behaviour see regexp_parslet_spec.rb.
15
+ describe 'using shorthand to get RegexpParslets from Regexp instances' do
16
+
17
+ it 'chaining two Regexps with the "&" operator should yield a two-element sequence' do
18
+ sequence = /foo/ & /bar/
19
+ sequence.parse('foobar').collect { |each| each.to_s }.should == ['foo', 'bar']
20
+ end
21
+
22
+ it 'chaining three Regexps with the "&" operator should yield a three-element sequence' do
23
+ sequence = /foo/ & /bar/ & /\.\.\./
24
+ sequence.parse('foobar...').collect { |each| each.to_s }.should == ['foo', 'bar', '...']
25
+ end
26
+
27
+ it 'alternating two Regexps with the "|" operator should yield a MatchDataWrapper' do
28
+ sequence = /foo/ | /bar/
29
+ sequence.parse('foobar').to_s.should == 'foo'
30
+ sequence.parse('bar...').to_s.should == 'bar'
31
+ lambda { sequence.parse('no match') }.should raise_error(ParseError)
32
+ end
33
+
34
+ end
35
+
36
+ end # class Grammar
37
+ end # module Walrus