baby_erubis 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/baby_erubis.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  ###
4
- ### $Release: 0.1.0 $
4
+ ### $Release: 1.0.0 $
5
5
  ### $Copyright: copyright(c) 2014 kuwata-lab.com all rights reserved $
6
6
  ### $License: MIT License $
7
7
  ###
@@ -25,6 +25,8 @@
25
25
 
26
26
  module BabyErubis
27
27
 
28
+ RELEASE = '$Release: 1.0.0 $'.split(' ')[1]
29
+
28
30
 
29
31
  class Template
30
32
 
@@ -38,7 +40,9 @@ module BabyErubis
38
40
  end
39
41
 
40
42
  def from_file(filename, encoding='utf-8')
41
- input = File.open(filename, "rb:#{encoding}") {|f| f.read() }
43
+ mode = "rb:#{encoding}"
44
+ mode = "rb" if RUBY_VERSION < '1.9'
45
+ input = File.open(filename, mode) {|f| f.read() }
42
46
  compile(parse(input), filename, 1)
43
47
  return self
44
48
  end
@@ -94,7 +98,7 @@ module BabyErubis
94
98
  end
95
99
 
96
100
  def render(context={})
97
- ctxobj = context.is_a?(Hash) ? new_context(context) : context
101
+ ctxobj = context.nil? || context.is_a?(Hash) ? new_context(context) : context
98
102
  return ctxobj.instance_eval(&@proc)
99
103
  end
100
104
 
@@ -155,11 +159,10 @@ module BabyErubis
155
159
 
156
160
  class HtmlTemplate < Template
157
161
 
158
- protected
159
-
160
162
  def escaped_expr(code)
161
163
  return "escape(#{code})" # escape() is defined in HtmlTemplateContext
162
164
  end
165
+ protected :escaped_expr
163
166
 
164
167
  def new_context(hash)
165
168
  return HtmlTemplateContext.new(hash)
data/test/context_test.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  ###
4
- ### $Release: 0.1.0 $
4
+ ### $Release: 1.0.0 $
5
5
  ### $Copyright: copyright(c) 2014 kuwata-lab.com all rights reserved $
6
6
  ### $License: MIT License $
7
7
  ###
data/test/run_all.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  ###
4
- ### $Release: 0.1.0 $
4
+ ### $Release: 1.0.0 $
5
5
  ### $Copyright: copyright(c) 2014 kuwata-lab.com all rights reserved $
6
6
  ### $License: MIT License $
7
7
  ###
@@ -0,0 +1,646 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ###
4
+ ### $Release: 1.0.0 $
5
+ ### $Copyright: copyright(c) 2014 kuwata-lab.com all rights reserved $
6
+ ### $License: MIT License $
7
+ ###
8
+
9
+ libpath = File.class_eval { join(dirname(dirname(__FILE__)), 'lib') }
10
+ $: << libpath unless $:.include?(libpath)
11
+
12
+ require 'minitest/autorun'
13
+
14
+ ## enforce not to use String#freeze() even if RUBY_VERSION >= 2.1
15
+ #require 'baby_erubis'
16
+ #BabyErubis::Template.class_eval do
17
+ # remove_const :FREEZE
18
+ # FREEZE = false
19
+ #end
20
+
21
+ ## load script file ('bin/baby_erubis.rb')
22
+ NOEXEC_SCRIPT = true
23
+ load File.join(File.dirname(libpath), 'bin', 'baby_erubis')
24
+
25
+ ## helper to steal stdin, stdout and stderr
26
+ require 'stringio'
27
+ def dummy_stdio(input=nil)
28
+ stdin, stdout, stderr = $stdin, $stdout, $stderr
29
+ $stdin = StringIO.new(input || '')
30
+ $stdout = StringIO.new
31
+ $stderr = StringIO.new
32
+ yield
33
+ return $stdout.string, $stderr.string
34
+ ensure
35
+ $stdin = stdin
36
+ $stdout = stdout
37
+ $stderr = stderr
38
+ end
39
+
40
+ ## helper to create dummy file temporarily
41
+ def with_tmpfile(filename, content)
42
+ File.open(filename, 'wb') {|f| f.write(content) }
43
+ yield filename
44
+ ensure
45
+ File.unlink(filename) if File.exist?(filename)
46
+ end
47
+
48
+ ## helper to create eruby file temporarily
49
+ def with_erubyfile(content=nil)
50
+ content ||= ERUBY_TEMPLATE
51
+ filename = "test_eruby.rhtml"
52
+ with_tmpfile(filename, content) do
53
+ yield filename
54
+ end
55
+ end
56
+
57
+
58
+ describe Main do
59
+
60
+ def _modify(ruby_code)
61
+ if (''.freeze).equal?(''.freeze)
62
+ return ruby_code.gsub(/([^'])';/m, "\\1'.freeze;")
63
+ else
64
+ return ruby_code
65
+ end
66
+ end
67
+
68
+ def on_rubinius?
69
+ return defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
70
+ end
71
+
72
+ help_message = <<'END'.gsub(/\$SCRIPT/, File.basename($0))
73
+ Usage: $SCRIPT [..options..] [erubyfile]
74
+ -h, --help : help
75
+ -v, --version : version
76
+ -x : show ruby code
77
+ -X : show ruby code only (no text part)
78
+ -N : numbering: add line numbers (for '-x/-X')
79
+ -U : unique: compress empty lines (for '-x/-X')
80
+ -C : compact: remove empty lines (for '-x/-X')
81
+ -c context : context string (yaml inline style or ruby code)
82
+ -f file : context data file (*.yaml, *.json, or *.rb)
83
+ -H : same as --format=html
84
+ --format={text|html} : format (default: text)
85
+ --encoding=name : encoding (default: utf-8)
86
+ --freeze={true|false} : use String#freeze() or not
87
+
88
+ Example:
89
+ ## convert eRuby file into Ruby code
90
+ $ $SCRIPT -x file.erb # text
91
+ $ $SCRIPT -xH file.erb # html
92
+ $ $SCRIPT -X file.erb # embedded code only
93
+ ## render eRuby file with context data
94
+ $ $SCRIPT -c '{items: [A, B, C]}' file.erb # YAML
95
+ $ $SCRIPT -c '@items=["A","B","C"]' file.erb # Ruby
96
+ $ $SCRIPT -f data.yaml file.erb # or -f *.json, *.rb
97
+ ## debug eRuby file
98
+ $ $SCRIPT -xH file.erb | ruby -wc # check syntax error
99
+ $ $SCRIPT -XHNU file.erb # show embedded ruby code
100
+ END
101
+
102
+ ERUBY_TEMPLATE = <<'END'
103
+ <html>
104
+ <body>
105
+ <h1><%= @title %></h1>
106
+ <h1><%== @title %></h1>
107
+ <div>
108
+ <ul>
109
+ <% for item in @items %>
110
+ <li><%= item %></li>
111
+ <% end %>
112
+ </ul>
113
+ </div>
114
+ </body>
115
+ </html>
116
+ END
117
+ SOURCE_TEXT = <<'END'
118
+ _buf = ''; _buf << '<html>
119
+ <body>
120
+ <h1>'; _buf << (@title).to_s; _buf << '</h1>
121
+ <h1>'; _buf << (@title).to_s; _buf << '</h1>
122
+ <div>
123
+ <ul>
124
+ '; for item in @items;
125
+ _buf << ' <li>'; _buf << (item).to_s; _buf << '</li>
126
+ '; end;
127
+ _buf << ' </ul>
128
+ </div>
129
+ </body>
130
+ </html>
131
+ '; _buf.to_s
132
+ END
133
+ SOURCE_HTML = <<'END'
134
+ _buf = ''; _buf << '<html>
135
+ <body>
136
+ <h1>'; _buf << escape(@title); _buf << '</h1>
137
+ <h1>'; _buf << (@title).to_s; _buf << '</h1>
138
+ <div>
139
+ <ul>
140
+ '; for item in @items;
141
+ _buf << ' <li>'; _buf << escape(item); _buf << '</li>
142
+ '; end;
143
+ _buf << ' </ul>
144
+ </div>
145
+ </body>
146
+ </html>
147
+ '; _buf.to_s
148
+ END
149
+ SOURCE_NO_TEXT = <<'END'
150
+ _buf = '';
151
+
152
+ _buf << (@title).to_s;
153
+ _buf << (@title).to_s;
154
+
155
+
156
+ for item in @items;
157
+ _buf << (item).to_s;
158
+ end;
159
+
160
+
161
+
162
+ _buf.to_s
163
+ END
164
+ OUTPUT_HTML = <<'END'
165
+ <html>
166
+ <body>
167
+ <h1>Love&amp;Peace</h1>
168
+ <h1>Love&Peace</h1>
169
+ <div>
170
+ <ul>
171
+ <li>A</li>
172
+ <li>B</li>
173
+ <li>C</li>
174
+ </ul>
175
+ </div>
176
+ </body>
177
+ </html>
178
+ END
179
+ OUTPUT_TEXT = OUTPUT_HTML.sub(/&amp;/, '&')
180
+
181
+
182
+ describe '-h, --help' do
183
+
184
+ it "prints help message." do
185
+ sout, serr = dummy_stdio { Main.main(["-h"]) }
186
+ assert_equal help_message, sout
187
+ assert_equal "", serr
188
+ sout, serr = dummy_stdio { Main.main(["--help"]) }
189
+ assert_equal help_message, sout
190
+ assert_equal "", serr
191
+ end
192
+
193
+ end
194
+
195
+
196
+ describe '-v, --version' do
197
+
198
+ it "prints release version." do
199
+ expected = "#{BabyErubis::RELEASE}\n"
200
+ sout, serr = dummy_stdio { Main.main(["-v"]) }
201
+ assert_equal expected, sout
202
+ assert_equal "", serr
203
+ sout, serr = dummy_stdio { Main.main(["--version"]) }
204
+ assert_equal expected, sout
205
+ assert_equal "", serr
206
+ end
207
+
208
+ end
209
+
210
+
211
+ describe '-x' do
212
+
213
+ it "shows ruby code compiled." do
214
+ sout, serr = with_erubyfile do |fname|
215
+ dummy_stdio { Main.main(['-x', fname]) }
216
+ end
217
+ assert_equal _modify(SOURCE_TEXT), sout
218
+ assert_equal "", serr
219
+ end
220
+
221
+ it "reads stdin when no file specified." do
222
+ sout, serr = dummy_stdio(ERUBY_TEMPLATE) { Main.main(['-x']) }
223
+ assert_equal _modify(SOURCE_TEXT), sout
224
+ assert_equal "", serr
225
+ end
226
+
227
+ end
228
+
229
+
230
+ describe '-X' do
231
+
232
+ it "shows ruby code only (no text part)." do
233
+ expected = <<'END'
234
+ _buf = '';
235
+
236
+ _buf << (@title).to_s;
237
+ _buf << (@title).to_s;
238
+
239
+
240
+ for item in @items;
241
+ _buf << (item).to_s;
242
+ end;
243
+
244
+
245
+
246
+
247
+ _buf.to_s
248
+ END
249
+ sout, serr = with_erubyfile do |fname|
250
+ dummy_stdio { Main.main(['-X', fname]) }
251
+ end
252
+ assert_equal expected, sout
253
+ assert_equal "", serr
254
+ end
255
+
256
+ end
257
+
258
+
259
+ describe '-N' do
260
+
261
+ it "adds line numbers." do
262
+ expected = <<'END'
263
+ 1: _buf = '';
264
+ 2:
265
+ 3: _buf << (@title).to_s;
266
+ 4: _buf << (@title).to_s;
267
+ 5:
268
+ 6:
269
+ 7: for item in @items;
270
+ 8: _buf << (item).to_s;
271
+ 9: end;
272
+ 10:
273
+ 11:
274
+ 12:
275
+ 13:
276
+ 14: _buf.to_s
277
+ END
278
+ sout, serr = with_erubyfile do |fname|
279
+ dummy_stdio { Main.main(['-XN', fname]) }
280
+ end
281
+ assert_equal expected, sout
282
+ assert_equal "", serr
283
+ end
284
+
285
+ end
286
+
287
+
288
+ describe '-U' do
289
+
290
+ it "compresses empty lines." do
291
+ expected = <<'END'
292
+ 1: _buf = '';
293
+
294
+ 3: _buf << (@title).to_s;
295
+ 4: _buf << (@title).to_s;
296
+
297
+ 7: for item in @items;
298
+ 8: _buf << (item).to_s;
299
+ 9: end;
300
+
301
+ 14: _buf.to_s
302
+ END
303
+ sout, serr = with_erubyfile do |fname|
304
+ dummy_stdio { Main.main(['-XNU', fname]) }
305
+ end
306
+ assert_equal expected, sout
307
+ assert_equal "", serr
308
+ end
309
+
310
+ end
311
+
312
+
313
+ describe '-C' do
314
+
315
+ it "removes empty lines." do
316
+ expected = <<'END'
317
+ 1: _buf = '';
318
+ 3: _buf << (@title).to_s;
319
+ 4: _buf << (@title).to_s;
320
+ 7: for item in @items;
321
+ 8: _buf << (item).to_s;
322
+ 9: end;
323
+ 14: _buf.to_s
324
+ END
325
+ sout, serr = with_erubyfile do |fname|
326
+ dummy_stdio { Main.main(['-XNC', fname]) }
327
+ end
328
+ assert_equal expected, sout
329
+ assert_equal "", serr
330
+ end
331
+
332
+ end
333
+
334
+
335
+ describe '-H' do
336
+
337
+ it "escapes expressions." do
338
+ sout, serr = with_erubyfile do |fname|
339
+ dummy_stdio { Main.main(['-Hx', fname]) }
340
+ end
341
+ assert_equal _modify(SOURCE_HTML), sout
342
+ assert_equal "", serr
343
+ end
344
+
345
+ end
346
+
347
+
348
+ describe '-c cotnext' do
349
+
350
+ it "can specify context data in YAML format." do
351
+ context_str = "{title: Love&Peace, items: [A, B, C]}"
352
+ sout, serr = with_erubyfile do |fname|
353
+ dummy_stdio { Main.main(['-Hc', context_str, fname]) }
354
+ end
355
+ assert_equal OUTPUT_HTML, sout
356
+ assert_equal "", serr
357
+ ## when syntax error exists
358
+ context_str = "{title:Love&Peace,items:[A,B,C]"
359
+ sout, serr = with_erubyfile do |fname|
360
+ dummy_stdio { Main.main(['-Hc', context_str, fname]) }
361
+ end
362
+ assert_equal "", sout
363
+ if on_rubinius?
364
+ assert_equal "-c '{title:Love&Peace,items:[A,B,C]': YAML syntax error: (ArgumentError) col 31\n", serr
365
+ else
366
+ assert_equal "-c '{title:Love&Peace,items:[A,B,C]': YAML syntax error: (Psych::SyntaxError) found unexpected ':' while scanning a plain scalar at line 1 column 2\n", serr
367
+ end
368
+ end
369
+
370
+ it "can specify context data as Ruby code." do
371
+ context_str = "@title = 'Love&Peace'; @items = ['A','B','C']"
372
+ sout, serr = with_erubyfile do |fname|
373
+ dummy_stdio { Main.main(['-Hc', context_str, fname]) }
374
+ end
375
+ assert_equal OUTPUT_HTML, sout
376
+ assert_equal "", serr
377
+ ## when syntax error exists
378
+ context_str = "@title = 'Love&Peace' @items = ['A','B','C']"
379
+ sout, serr = with_erubyfile do |fname|
380
+ dummy_stdio { Main.main(['-Hc', context_str, fname]) }
381
+ end
382
+ expected = "-c '@title = 'Love&Peace' @items = ['A','B','C']': Ruby syntax error: (SyntaxError) unexpected tIVAR, expecting $end
383
+ @title = 'Love&Peace' @items = ['A','B','C']
384
+ ^
385
+ "
386
+ expected = expected.sub(/\$end/, "end-of-input") if RUBY_VERSION =~ /^2\./
387
+ expected = "-c '@title = 'Love&Peace' @items = ['A','B','C']': Ruby syntax error: (SyntaxError) expecting $end: (eval):1:28\n" if on_rubinius?
388
+ assert_equal "", sout
389
+ assert_equal expected, serr
390
+ end
391
+
392
+ end
393
+
394
+
395
+ describe '-f datafile' do
396
+
397
+ it "can specify context data in YAML format." do
398
+ ctx_str = "{title: Love&Peace, items: [A, B, C]}"
399
+ ctx_file = "tmpdata.yaml"
400
+ sout, serr = with_erubyfile do |fname|
401
+ with_tmpfile(ctx_file, ctx_str) do
402
+ dummy_stdio { Main.main(['-Hf', ctx_file, fname]) }
403
+ end
404
+ end
405
+ assert_equal OUTPUT_HTML, sout
406
+ assert_equal "", serr
407
+ ## when file not found
408
+ sout, serr = with_erubyfile do |fname|
409
+ dummy_stdio { Main.main(['-Hf', ctx_file, fname]) }
410
+ end
411
+ assert_equal "", sout
412
+ assert_equal "-f #{ctx_file}: file not found.\n", serr
413
+ ## when syntax error exists
414
+ ctx_str = "{title:Love&Peace,items:[A, B, C]"
415
+ sout, serr = with_erubyfile do |fname|
416
+ with_tmpfile(ctx_file, ctx_str) do
417
+ dummy_stdio { Main.main(['-Hf', ctx_file, fname]) }
418
+ end
419
+ end
420
+ assert_equal "", sout
421
+ if on_rubinius?
422
+ assert_equal "-f #{ctx_file}: YAML syntax error: (ArgumentError) col 33\n", serr
423
+ else
424
+ assert_equal "-f #{ctx_file}: YAML syntax error: (Psych::SyntaxError) found unexpected ':' while scanning a plain scalar at line 1 column 2\n", serr
425
+ end
426
+ end
427
+
428
+ it "can specify context data in JSON format." do
429
+ ctx_str = '{"title":"Love&Peace","items":["A","B","C"]}'
430
+ ctx_file = "tmpdata.json"
431
+ sout, serr = with_erubyfile do |fname|
432
+ with_tmpfile(ctx_file, ctx_str) do
433
+ dummy_stdio { Main.main(['-Hf', ctx_file, fname]) }
434
+ end
435
+ end
436
+ assert_equal OUTPUT_HTML, sout
437
+ assert_equal "", serr
438
+ ## when file not found
439
+ sout, serr = with_erubyfile do |fname|
440
+ dummy_stdio { Main.main(['-Hf', ctx_file, fname]) }
441
+ end
442
+ assert_equal "", sout
443
+ assert_equal "-f #{ctx_file}: file not found.\n", serr
444
+ ## when syntax error exists
445
+ ctx_str = '{"title":"Love&Peace",items:["A","B","C"],}'
446
+ sout, serr = with_erubyfile do |fname|
447
+ with_tmpfile(ctx_file, ctx_str) do
448
+ dummy_stdio { Main.main(['-Hf', ctx_file, fname]) }
449
+ end
450
+ end
451
+ expected = "-f #{ctx_file}: JSON syntax error: (JSON::ParserError) 743: unexpected token\n"
452
+ expected = expected.sub(/743/, '795') if RUBY_VERSION >= '2.0'
453
+ assert_equal "", sout
454
+ assert_equal expected, serr
455
+ end
456
+
457
+ it "can specify context data as Ruby code." do
458
+ ctx_str = "@title = 'Love&Peace'; @items = ['A','B','C']"
459
+ ctx_file = "tmpdata.rb"
460
+ sout, serr = with_erubyfile do |fname|
461
+ with_tmpfile(ctx_file, ctx_str) do
462
+ dummy_stdio { Main.main(["-Hf#{ctx_file}", fname]) }
463
+ end
464
+ end
465
+ assert_equal OUTPUT_HTML, sout
466
+ assert_equal "", serr
467
+ ## when file not found
468
+ sout, serr = with_erubyfile do |fname|
469
+ dummy_stdio { Main.main(['-Hf', ctx_file, fname]) }
470
+ end
471
+ assert_equal "", sout
472
+ assert_equal "-f #{ctx_file}: file not found.\n", serr
473
+ ## when syntax error exists
474
+ ctx_str = "@title = 'Love&Peace' @items = ['A','B','C']"
475
+ sout, serr = with_erubyfile do |fname|
476
+ with_tmpfile(ctx_file, ctx_str) do
477
+ dummy_stdio { Main.main(['-Hf', ctx_file, fname]) }
478
+ end
479
+ end
480
+ expected = "-f #{ctx_file}: Ruby syntax error: (SyntaxError) unexpected tIVAR, expecting $end
481
+ @title = 'Love&Peace' @items = ['A','B','C']
482
+ ^\n"
483
+ expected = expected.sub(/\$end/, "end-of-input") if RUBY_VERSION =~ /^2\./
484
+ expected = "-f #{ctx_file}: Ruby syntax error: (SyntaxError) expecting $end: (eval):1:28\n" if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
485
+ assert_equal "", sout
486
+ assert_equal expected, serr
487
+ end
488
+
489
+ it "reports error when unknown data file suffix." do
490
+ ctx_str = '{"title": "Love&Peace", "items": ["A","B","C"]}'
491
+ ctx_file = "tmpdata.js"
492
+ sout, serr = with_erubyfile do |fname|
493
+ with_tmpfile(ctx_file, ctx_str) do
494
+ dummy_stdio { Main.main(["-Hf#{ctx_file}", fname]) }
495
+ end
496
+ end
497
+ assert_equal "", sout
498
+ assert_equal "-f #{ctx_file}: unknown suffix (expected '.yaml', '.json', or '.rb').\n", serr
499
+ end
500
+
501
+ end
502
+
503
+
504
+ describe '--format={text|html}' do
505
+
506
+ it "can enforce text format." do
507
+ ctx_str = "{title: Love&Peace, items: [A, B, C]}"
508
+ sout, serr = with_erubyfile do |fname|
509
+ dummy_stdio { Main.main(['--format=text', '-c', ctx_str, fname]) }
510
+ end
511
+ assert_equal OUTPUT_TEXT, sout
512
+ assert_equal "", serr
513
+ end
514
+
515
+ it "can enforce html format." do
516
+ ctx_str = "{title: Love&Peace, items: [A, B, C]}"
517
+ sout, serr = with_erubyfile do |fname|
518
+ dummy_stdio { Main.main(['--format=html', '-c', ctx_str, fname]) }
519
+ end
520
+ assert_equal OUTPUT_HTML, sout
521
+ assert_equal "", serr
522
+ end
523
+
524
+ it "reports error when argument is missng." do
525
+ status = nil
526
+ sout, serr = with_erubyfile do |fname|
527
+ dummy_stdio { status = Main.main(['-x', '--format', fname]) }
528
+ end
529
+ assert_equal "", sout
530
+ assert_equal "#{File.basename($0)}: --format: argument required.\n", serr
531
+ assert_equal 1, status
532
+ end
533
+
534
+ it "reports error when unknown argument." do
535
+ status = nil
536
+ sout, serr = with_erubyfile do |fname|
537
+ dummy_stdio { status = Main.main(['-x', '--format=json', fname]) }
538
+ end
539
+ assert_equal "", sout
540
+ assert_equal "#{File.basename($0)}: --format=json: 'text' or 'html' expected\n", serr
541
+ assert_equal 1, status
542
+ end
543
+
544
+ end
545
+
546
+
547
+ describe '--encoding=name' do
548
+
549
+ it "can specify encoding of file content." do
550
+ sout, serr = with_erubyfile do |fname|
551
+ dummy_stdio { status = Main.main(['-x', '--encoding=utf-8', fname]) }
552
+ end
553
+ assert_equal _modify(SOURCE_TEXT), sout
554
+ assert_equal "" , serr
555
+ end
556
+
557
+ end
558
+
559
+
560
+ describe '--freeze={true|false}' do
561
+
562
+ it "can generate ruby code using String#freeze." do
563
+ sout, serr = with_erubyfile do |fname|
564
+ dummy_stdio { Main.main(['-x', '--freeze=true', fname]) }
565
+ end
566
+ expected = _modify(SOURCE_TEXT).gsub(/([^'])';/, "\\1'.freeze;")
567
+ assert_equal expected, sout
568
+ end
569
+
570
+ it "can generate ruby code without String#freeze." do
571
+ sout, serr = with_erubyfile do |fname|
572
+ dummy_stdio { Main.main(['-x', '--freeze=false', fname]) }
573
+ end
574
+ expected = SOURCE_TEXT
575
+ assert_equal expected, sout
576
+ end
577
+
578
+ it "reports error when argument is missing." do
579
+ status = nil
580
+ sout, serr = with_erubyfile do |fname|
581
+ dummy_stdio { status = Main.main(['-x', '--freeze', fname]) }
582
+ end
583
+ assert_equal "", sout
584
+ assert_equal "#{File.basename($0)}: --freeze: argument required.\n", serr
585
+ assert_equal 1, status
586
+ end
587
+
588
+ it "reports error when unknown argument." do
589
+ status = nil
590
+ sout, serr = with_erubyfile do |fname|
591
+ dummy_stdio { status = Main.main(['-x', '--freeze=yes', fname]) }
592
+ end
593
+ assert_equal "", sout
594
+ assert_equal "#{File.basename($0)}: --freeze=yes: 'true' or 'false' expected\n", serr
595
+ assert_equal 1, status
596
+ end
597
+
598
+ end
599
+
600
+
601
+ end
602
+
603
+
604
+ describe Cmdopt::Parser do
605
+
606
+ let(:parser) { Main.new.__send__(:build_parser) }
607
+
608
+
609
+ describe '#parse()' do
610
+
611
+ it "parses short options." do
612
+ argv = ["-vh", "-xc", "{x: 1}", "-fdata.txt", "file1", "file2"]
613
+ options = parser.parse(argv)
614
+ expected = {'version'=>true, 'help'=>true, 'x'=>true, 'c'=>'{x: 1}', 'f'=>'data.txt'}
615
+ assert_equal expected, options
616
+ assert_equal ["file1", "file2"], argv
617
+ end
618
+
619
+ it "parses long options" do
620
+ argv = ["--help", "--version", "--format=html", "--freeze=true", "file1", "file2"]
621
+ options = parser.parse(argv)
622
+ expected = {'version'=>true, 'help'=>true, 'format'=>'html', 'freeze'=>'true'}
623
+ assert_equal expected, options
624
+ assert_equal ["file1", "file2"], argv
625
+ end
626
+
627
+ it "raises error when required argument of short option is missing." do
628
+ argv = ["-f"]
629
+ ex = assert_raises Cmdopt::ParseError do
630
+ options = parser.parse(argv)
631
+ end
632
+ assert_equal "#{File.basename($0)}: -f: argument required.", ex.message
633
+ end
634
+
635
+ it "raises error when required argument of long option is missing." do
636
+ argv = ["--format", "file1"]
637
+ ex = assert_raises Cmdopt::ParseError do
638
+ options = parser.parse(argv)
639
+ end
640
+ assert_equal "#{File.basename($0)}: --format: argument required.", ex.message
641
+ end
642
+
643
+ end
644
+
645
+
646
+ end