coderay 1.0.0.598.pre → 1.0.0.738.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/bin/coderay +1 -1
  2. data/lib/coderay.rb +38 -32
  3. data/lib/coderay/duo.rb +1 -54
  4. data/lib/coderay/encoder.rb +31 -33
  5. data/lib/coderay/encoders/_map.rb +4 -2
  6. data/lib/coderay/encoders/comment_filter.rb +0 -61
  7. data/lib/coderay/encoders/count.rb +2 -23
  8. data/lib/coderay/encoders/debug.rb +11 -60
  9. data/lib/coderay/encoders/filter.rb +0 -46
  10. data/lib/coderay/encoders/html.rb +83 -91
  11. data/lib/coderay/encoders/html/css.rb +1 -6
  12. data/lib/coderay/encoders/html/numbering.rb +18 -21
  13. data/lib/coderay/encoders/html/output.rb +10 -52
  14. data/lib/coderay/encoders/json.rb +19 -39
  15. data/lib/coderay/encoders/lines_of_code.rb +7 -52
  16. data/lib/coderay/encoders/null.rb +6 -13
  17. data/lib/coderay/encoders/statistic.rb +30 -93
  18. data/lib/coderay/encoders/terminal.rb +3 -4
  19. data/lib/coderay/encoders/text.rb +1 -23
  20. data/lib/coderay/encoders/token_kind_filter.rb +0 -58
  21. data/lib/coderay/helpers/file_type.rb +119 -240
  22. data/lib/coderay/helpers/gzip.rb +41 -0
  23. data/lib/coderay/helpers/plugin.rb +237 -307
  24. data/lib/coderay/scanner.rb +112 -88
  25. data/lib/coderay/scanners/_map.rb +3 -3
  26. data/lib/coderay/scanners/c.rb +7 -7
  27. data/lib/coderay/scanners/clojure.rb +204 -0
  28. data/lib/coderay/scanners/css.rb +10 -20
  29. data/lib/coderay/scanners/debug.rb +9 -55
  30. data/lib/coderay/scanners/diff.rb +21 -4
  31. data/lib/coderay/scanners/html.rb +65 -18
  32. data/lib/coderay/scanners/java.rb +3 -2
  33. data/lib/coderay/scanners/java_script.rb +3 -3
  34. data/lib/coderay/scanners/json.rb +7 -6
  35. data/lib/coderay/scanners/php.rb +2 -1
  36. data/lib/coderay/scanners/rhtml.rb +6 -2
  37. data/lib/coderay/scanners/ruby.rb +193 -193
  38. data/lib/coderay/scanners/ruby/patterns.rb +15 -82
  39. data/lib/coderay/scanners/ruby/string_state.rb +71 -0
  40. data/lib/coderay/scanners/sql.rb +1 -1
  41. data/lib/coderay/scanners/yaml.rb +4 -2
  42. data/lib/coderay/styles/_map.rb +2 -2
  43. data/lib/coderay/styles/alpha.rb +48 -38
  44. data/lib/coderay/styles/cycnus.rb +2 -1
  45. data/lib/coderay/token_kinds.rb +88 -86
  46. data/lib/coderay/tokens.rb +88 -112
  47. data/test/functional/basic.rb +184 -5
  48. data/test/functional/examples.rb +4 -4
  49. data/test/functional/for_redcloth.rb +3 -2
  50. data/test/functional/suite.rb +7 -6
  51. metadata +11 -24
  52. data/lib/coderay/helpers/gzip_simple.rb +0 -123
  53. data/test/functional/load_plugin_scanner.rb +0 -11
  54. data/test/functional/vhdl.rb +0 -126
  55. data/test/functional/word_list.rb +0 -79
@@ -8,7 +8,7 @@ class ExamplesTest < Test::Unit::TestCase
8
8
  div = CodeRay.scan('puts "Hello, world!"', :ruby).div
9
9
  assert_equal <<-DIV, div
10
10
  <div class="CodeRay">
11
- <div class="code"><pre>puts <span style="background-color:hsla(0,100%,50%,0.1)"><span style="color:#710">&quot;</span><span style="color:#D20">Hello, world!</span><span style="color:#710">&quot;</span></span></pre></div>
11
+ <div class="code"><pre>puts <span style="background-color:hsla(0,100%,50%,0.08)"><span style="color:#710">&quot;</span><span style="color:#D20">Hello, world!</span><span style="color:#710">&quot;</span></span></pre></div>
12
12
  </div>
13
13
  DIV
14
14
 
@@ -24,8 +24,8 @@ end
24
24
  <a href="#n2" name="n2">2</a>
25
25
  <a href="#n3" name="n3">3</a>
26
26
  </pre></td>
27
- <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span style="color:#00D;font-weight:bold">5</span>.times <span style="color:#080;font-weight:bold">do</span>
28
- puts <span style="background-color:hsla(0,100%,50%,0.1)"><span style="color:#710">'</span><span style="color:#D20">Hello, world!</span><span style="color:#710">'</span></span>
27
+ <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span style="color:#00D">5</span>.times <span style="color:#080;font-weight:bold">do</span>
28
+ puts <span style="background-color:hsla(0,100%,50%,0.08)"><span style="color:#710">'</span><span style="color:#D20">Hello, world!</span><span style="color:#710">'</span></span>
29
29
  <span style="color:#080;font-weight:bold">end</span></pre></td>
30
30
  </tr></table>
31
31
  DIV
@@ -116,7 +116,7 @@ Token Types (5):
116
116
  div = ruby_highlighter.encode('puts "Hello, world!"')
117
117
  assert_equal <<-DIV, div
118
118
  <div class="CodeRay">
119
- <div class="code"><pre>puts <span style="background-color:hsla(0,100%,50%,0.1)"><span style="color:#710">&quot;</span><span style="color:#D20">Hello, world!</span><span style="color:#710">&quot;</span></span></pre></div>
119
+ <div class="code"><pre>puts <span style="background-color:hsla(0,100%,50%,0.08)"><span style="color:#710">&quot;</span><span style="color:#D20">Hello, world!</span><span style="color:#710">&quot;</span></span></pre></div>
120
120
  </div>
121
121
  DIV
122
122
  end
@@ -8,17 +8,18 @@ begin
8
8
  require 'redcloth'
9
9
  rescue LoadError
10
10
  warn 'RedCloth not found - skipping for_redcloth tests.'
11
+ undef RedCloth if defined? RedCloth
11
12
  end
12
13
 
13
14
  class BasicTest < Test::Unit::TestCase
14
15
 
15
16
  def test_for_redcloth
16
17
  require 'coderay/for_redcloth'
17
- assert_equal "<p><span lang=\"ruby\" class=\"CodeRay\">puts <span style=\"background-color:hsla(0,100%,50%,0.1)\"><span style=\"color:#710\">&quot;</span><span style=\"color:#D20\">Hello, World!</span><span style=\"color:#710\">&quot;</span></span></span></p>",
18
+ assert_equal "<p><span lang=\"ruby\" class=\"CodeRay\">puts <span style=\"background-color:hsla(0,100%,50%,0.08)\"><span style=\"color:#710\">&quot;</span><span style=\"color:#D20\">Hello, World!</span><span style=\"color:#710\">&quot;</span></span></span></p>",
18
19
  RedCloth.new('@[ruby]puts "Hello, World!"@').to_html
19
20
  assert_equal <<-BLOCKCODE.chomp,
20
21
  <div lang="ruby" class="CodeRay">
21
- <div class="code"><pre>puts <span style="background-color:hsla(0,100%,50%,0.1)"><span style="color:#710">&quot;</span><span style="color:#D20">Hello, World!</span><span style="color:#710">&quot;</span></span></pre></div>
22
+ <div class="code"><pre>puts <span style="background-color:hsla(0,100%,50%,0.08)"><span style="color:#710">&quot;</span><span style="color:#D20">Hello, World!</span><span style="color:#710">&quot;</span></span></pre></div>
22
23
  </div>
23
24
  BLOCKCODE
24
25
  RedCloth.new('bc[ruby]. puts "Hello, World!"').to_html
@@ -1,12 +1,13 @@
1
1
  require 'test/unit'
2
-
3
- MYDIR = File.dirname(__FILE__)
4
-
5
2
  $:.unshift 'lib'
6
3
  require 'coderay'
7
- puts "Running basic CodeRay #{CodeRay::VERSION} tests..."
8
4
 
9
- suite = %w(basic examples load_plugin_scanner word_list)
5
+ mydir = File.dirname(__FILE__)
6
+ suite = Dir[File.join(mydir, '*.rb')].
7
+ map { |tc| File.basename(tc).sub(/\.rb$/, '') } - %w'suite for_redcloth'
8
+
9
+ puts "Running basic CodeRay #{CodeRay::VERSION} tests: #{suite.join(', ')}"
10
+
10
11
  for test_case in suite
11
- load File.join(MYDIR, test_case + '.rb')
12
+ load File.join(mydir, test_case + '.rb')
12
13
  end
metadata CHANGED
@@ -1,14 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coderay
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: true
5
- segments:
6
- - 1
7
- - 0
8
- - 0
9
- - 598
10
- - pre
11
- version: 1.0.0.598.pre
4
+ prerelease: 10
5
+ version: 1.0.0.738.pre
12
6
  platform: ruby
13
7
  authors:
14
8
  - murphy
@@ -16,8 +10,7 @@ autorequire:
16
10
  bindir: bin
17
11
  cert_chain: []
18
12
 
19
- date: 2010-06-11 00:00:00 +02:00
20
- default_executable:
13
+ date: 2011-04-13 00:00:00 Z
21
14
  dependencies: []
22
15
 
23
16
  description: |
@@ -59,12 +52,13 @@ files:
59
52
  - ./lib/coderay/encoders/yaml.rb
60
53
  - ./lib/coderay/for_redcloth.rb
61
54
  - ./lib/coderay/helpers/file_type.rb
62
- - ./lib/coderay/helpers/gzip_simple.rb
55
+ - ./lib/coderay/helpers/gzip.rb
63
56
  - ./lib/coderay/helpers/plugin.rb
64
57
  - ./lib/coderay/helpers/word_list.rb
65
58
  - ./lib/coderay/scanner.rb
66
59
  - ./lib/coderay/scanners/_map.rb
67
60
  - ./lib/coderay/scanners/c.rb
61
+ - ./lib/coderay/scanners/clojure.rb
68
62
  - ./lib/coderay/scanners/cpp.rb
69
63
  - ./lib/coderay/scanners/css.rb
70
64
  - ./lib/coderay/scanners/debug.rb
@@ -83,6 +77,7 @@ files:
83
77
  - ./lib/coderay/scanners/raydebug.rb
84
78
  - ./lib/coderay/scanners/rhtml.rb
85
79
  - ./lib/coderay/scanners/ruby/patterns.rb
80
+ - ./lib/coderay/scanners/ruby/string_state.rb
86
81
  - ./lib/coderay/scanners/ruby.rb
87
82
  - ./lib/coderay/scanners/scheme.rb
88
83
  - ./lib/coderay/scanners/sql.rb
@@ -100,15 +95,13 @@ files:
100
95
  - ./test/functional/basic.rb
101
96
  - ./test/functional/examples.rb
102
97
  - ./test/functional/for_redcloth.rb
103
- - ./test/functional/load_plugin_scanner.rb
104
98
  - ./test/functional/suite.rb
105
- - ./test/functional/vhdl.rb
106
- - ./test/functional/word_list.rb
107
99
  - ./lib/README
108
100
  - ./LICENSE
109
101
  - lib/README
110
102
  - FOLDERS
111
- has_rdoc: true
103
+ - bin/coderay
104
+ - bin/coderay_stylesheet
112
105
  homepage: http://coderay.rubychan.de
113
106
  licenses: []
114
107
 
@@ -120,27 +113,21 @@ rdoc_options:
120
113
  require_paths:
121
114
  - lib
122
115
  required_ruby_version: !ruby/object:Gem::Requirement
116
+ none: false
123
117
  requirements:
124
118
  - - ">="
125
119
  - !ruby/object:Gem::Version
126
- segments:
127
- - 1
128
- - 8
129
- - 2
130
120
  version: 1.8.2
131
121
  required_rubygems_version: !ruby/object:Gem::Requirement
122
+ none: false
132
123
  requirements:
133
124
  - - ">"
134
125
  - !ruby/object:Gem::Version
135
- segments:
136
- - 1
137
- - 3
138
- - 1
139
126
  version: 1.3.1
140
127
  requirements: []
141
128
 
142
129
  rubyforge_project: coderay
143
- rubygems_version: 1.3.6
130
+ rubygems_version: 1.7.2
144
131
  signing_key:
145
132
  specification_version: 3
146
133
  summary: Fast syntax highlighting for selected languages.
@@ -1,123 +0,0 @@
1
- # =GZip Simple
2
- #
3
- # A simplified interface to the gzip library +zlib+ (from the Ruby Standard Library.)
4
- #
5
- # Author: murphy (mail to murphy rubychan de)
6
- #
7
- # Version: 0.2 (2005.may.28)
8
- #
9
- # ==Documentation
10
- #
11
- # See +GZip+ module and the +String+ extensions.
12
- #
13
- module GZip
14
-
15
- require 'zlib'
16
-
17
- # The default zipping level. 7 zips good and fast.
18
- DEFAULT_GZIP_LEVEL = 7
19
-
20
- # Unzips the given string +s+.
21
- #
22
- # Example:
23
- # require 'gzip_simple'
24
- # print GZip.gunzip(File.read('adresses.gz'))
25
- def GZip.gunzip s
26
- Zlib::Inflate.inflate s
27
- end
28
-
29
- # Zips the given string +s+.
30
- #
31
- # Example:
32
- # require 'gzip_simple'
33
- # File.open('adresses.gz', 'w') do |file
34
- # file.write GZip.gzip('Mum: 0123 456 789', 9)
35
- # end
36
- #
37
- # If you provide a +level+, you can control how strong
38
- # the string is compressed:
39
- # - 0: no compression, only convert to gzip format
40
- # - 1: compress fast
41
- # - 7: compress more, but still fast (default)
42
- # - 8: compress more, slower
43
- # - 9: compress best, very slow
44
- def GZip.gzip s, level = DEFAULT_GZIP_LEVEL
45
- Zlib::Deflate.new(level).deflate s, Zlib::FINISH
46
- end
47
- end
48
-
49
-
50
- # String extensions to use the GZip module.
51
- #
52
- # The methods gzip and gunzip provide an even more simple
53
- # interface to the ZLib:
54
- #
55
- # # create a big string
56
- # x = 'a' * 1000
57
- #
58
- # # zip it
59
- # x_gz = x.gzip
60
- #
61
- # # test the result
62
- # puts 'Zipped %d bytes to %d bytes.' % [x.size, x_gz.size]
63
- # #-> Zipped 1000 bytes to 19 bytes.
64
- #
65
- # # unzipping works
66
- # p x_gz.gunzip == x #-> true
67
- class String
68
- # Returns the string, unzipped.
69
- # See GZip.gunzip
70
- def gunzip
71
- GZip.gunzip self
72
- end
73
- # Replaces the string with its unzipped value.
74
- # See GZip.gunzip
75
- def gunzip!
76
- replace gunzip
77
- end
78
-
79
- # Returns the string, zipped.
80
- # +level+ is the gzip compression level, see GZip.gzip.
81
- def gzip level = GZip::DEFAULT_GZIP_LEVEL
82
- GZip.gzip self, level
83
- end
84
- # Replaces the string with its zipped value.
85
- # See GZip.gzip.
86
- def gzip!(*args)
87
- replace gzip(*args)
88
- end
89
- end
90
-
91
- if $0 == __FILE__
92
- eval DATA.read, nil, $0, __LINE__+4
93
- end
94
-
95
- __END__
96
- #CODE
97
-
98
- # Testing / Benchmark
99
- x = 'a' * 1000
100
- x_gz = x.gzip
101
- puts 'Zipped %d bytes to %d bytes.' % [x.size, x_gz.size] #-> Zipped 1000 bytes to 19 bytes.
102
- p x_gz.gunzip == x #-> true
103
-
104
- require 'benchmark'
105
-
106
- INFO = 'packed to %0.3f%%' # :nodoc:
107
-
108
- x = Array.new(100000) { rand(255).chr + 'aaaaaaaaa' + rand(255).chr }.join
109
- Benchmark.bm(10) do |bm|
110
- for level in 0..9
111
- bm.report "zip #{level}" do
112
- $x = x.gzip level
113
- end
114
- puts INFO % [100.0 * $x.size / x.size]
115
- end
116
- bm.report 'zip' do
117
- $x = x.gzip
118
- end
119
- puts INFO % [100.0 * $x.size / x.size]
120
- bm.report 'unzip' do
121
- $x.gunzip
122
- end
123
- end
@@ -1,11 +0,0 @@
1
- require 'test/unit'
2
- require 'coderay'
3
-
4
- class PluginScannerTest < Test::Unit::TestCase
5
-
6
- def test_load
7
- require File.join(File.dirname(__FILE__), 'vhdl')
8
- assert_equal 'VHDL', CodeRay.scanner(:vhdl).class.name
9
- end
10
-
11
- end
@@ -1,126 +0,0 @@
1
- class VHDL < CodeRay::Scanners::Scanner
2
-
3
- register_for :vhdl
4
-
5
- RESERVED_WORDS = [
6
- 'access','after','alias','all','assert','architecture','begin',
7
- 'block','body','buffer','bus','case','component','configuration','constant',
8
- 'disconnect','downto','else','elsif','end','entity','exit','file','for',
9
- 'function','generate','generic','group','guarded','if','impure','in',
10
- 'inertial','inout','is','label','library','linkage','literal','loop',
11
- 'map','new','next','null','of','on','open','others','out','package',
12
- 'port','postponed','procedure','process','pure','range','record','register',
13
- 'reject','report','return','select','severity','signal','shared','subtype',
14
- 'then','to','transport','type','unaffected','units','until','use','variable',
15
- 'wait','when','while','with','note','warning','error','failure','and',
16
- 'or','xor','not','nor',
17
- 'array'
18
- ]
19
-
20
- PREDEFINED_TYPES = [
21
- 'bit','bit_vector','character','boolean','integer','real','time','string',
22
- 'severity_level','positive','natural','signed','unsigned','line','text',
23
- 'std_logic','std_logic_vector','std_ulogic','std_ulogic_vector','qsim_state',
24
- 'qsim_state_vector','qsim_12state','qsim_12state_vector','qsim_strength',
25
- 'mux_bit','mux_vector','reg_bit','reg_vector','wor_bit','wor_vector'
26
- ]
27
-
28
- PREDEFINED_CONSTANTS = [
29
-
30
- ]
31
-
32
- IDENT_KIND = CodeRay::CaseIgnoringWordList.new(:ident).
33
- add(RESERVED_WORDS, :reserved).
34
- add(PREDEFINED_TYPES, :pre_type).
35
- add(PREDEFINED_CONSTANTS, :pre_constant)
36
-
37
- ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
38
- UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x
39
-
40
- def scan_tokens tokens, options
41
-
42
- state = :initial
43
-
44
- until eos?
45
-
46
- kind = nil
47
- match = nil
48
-
49
- case state
50
-
51
- when :initial
52
-
53
- if scan(/ \s+ | \\\n /x)
54
- kind = :space
55
-
56
- elsif scan(/-- .*/x)
57
- kind = :comment
58
-
59
- elsif scan(/ [-+*\/=<>?:;,!&^|()\[\]{}~%]+ | \.(?!\d) /x)
60
- kind = :operator
61
-
62
- elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
63
- kind = IDENT_KIND[match.downcase]
64
-
65
- elsif match = scan(/[a-z]?"/i)
66
- tokens << [:open, :string]
67
- state = :string
68
- kind = :delimiter
69
-
70
- elsif scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox)
71
- kind = :char
72
-
73
- elsif scan(/(?:\d+)(?![.eEfF])/)
74
- kind = :integer
75
-
76
- elsif scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
77
- kind = :float
78
-
79
- else
80
- getch
81
- kind = :error
82
-
83
- end
84
-
85
- when :string
86
- if scan(/[^\\\n"]+/)
87
- kind = :content
88
- elsif scan(/"/)
89
- tokens << ['"', :delimiter]
90
- tokens << [:close, :string]
91
- state = :initial
92
- next
93
- elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
94
- kind = :char
95
- elsif scan(/ \\ | $ /x)
96
- tokens << [:close, :string]
97
- kind = :error
98
- state = :initial
99
- else
100
- raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
101
- end
102
-
103
- else
104
- raise_inspect 'Unknown state', tokens
105
-
106
- end
107
-
108
- match ||= matched
109
- if $CODERAY_DEBUG and not kind
110
- raise_inspect 'Error token %p in line %d' %
111
- [[match, kind], line], tokens
112
- end
113
- raise_inspect 'Empty token', tokens unless match
114
-
115
- tokens << [match, kind]
116
-
117
- end
118
-
119
- if state == :string
120
- tokens << [:close, :string]
121
- end
122
-
123
- tokens
124
- end
125
-
126
- end
@@ -1,79 +0,0 @@
1
- require 'test/unit'
2
- require 'coderay'
3
-
4
- class WordListTest < Test::Unit::TestCase
5
-
6
- include CodeRay
7
-
8
- # define word arrays
9
- RESERVED_WORDS = %w[
10
- asm break case continue default do else
11
- ...
12
- ]
13
-
14
- PREDEFINED_TYPES = %w[
15
- int long short char void
16
- ...
17
- ]
18
-
19
- PREDEFINED_CONSTANTS = %w[
20
- EOF NULL ...
21
- ]
22
-
23
- # make a WordList
24
- IDENT_KIND = WordList.new(:ident).
25
- add(RESERVED_WORDS, :reserved).
26
- add(PREDEFINED_TYPES, :pre_type).
27
- add(PREDEFINED_CONSTANTS, :pre_constant)
28
-
29
- def test_word_list_example
30
- assert_equal :pre_type, IDENT_KIND['void']
31
- # assert_equal :pre_constant, IDENT_KIND['...'] # not specified
32
- end
33
-
34
- def test_word_list
35
- list = WordList.new(:ident).add(['foobar'], :reserved)
36
- assert_equal :reserved, list['foobar']
37
- assert_equal :ident, list['FooBar']
38
- end
39
-
40
- def test_word_list_cached
41
- list = WordList.new(:ident, true).add(['foobar'], :reserved)
42
- assert_equal :reserved, list['foobar']
43
- assert_equal :ident, list['FooBar']
44
- end
45
-
46
- def test_case_ignoring_word_list
47
- list = CaseIgnoringWordList.new(:ident).add(['foobar'], :reserved)
48
- assert_equal :ident, list['foo']
49
- assert_equal :reserved, list['foobar']
50
- assert_equal :reserved, list['FooBar']
51
-
52
- list = CaseIgnoringWordList.new(:ident).add(['FooBar'], :reserved)
53
- assert_equal :ident, list['foo']
54
- assert_equal :reserved, list['foobar']
55
- assert_equal :reserved, list['FooBar']
56
- end
57
-
58
- def test_case_ignoring_word_list_cached
59
- list = CaseIgnoringWordList.new(:ident, true).add(['foobar'], :reserved)
60
- assert_equal :ident, list['foo']
61
- assert_equal :reserved, list['foobar']
62
- assert_equal :reserved, list['FooBar']
63
-
64
- list = CaseIgnoringWordList.new(:ident, true).add(['FooBar'], :reserved)
65
- assert_equal :ident, list['foo']
66
- assert_equal :reserved, list['foobar']
67
- assert_equal :reserved, list['FooBar']
68
- end
69
-
70
- def test_dup
71
- list = WordList.new(:ident).add(['foobar'], :reserved)
72
- assert_equal :reserved, list['foobar']
73
- list2 = list.dup
74
- list2.add(%w[foobar], :keyword)
75
- assert_equal :keyword, list2['foobar']
76
- assert_equal :reserved, list['foobar']
77
- end
78
-
79
- end