cucumber 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +25 -4
- data/VERSION.yml +1 -1
- data/cucumber.gemspec +33 -29
- data/examples/i18n/{cat → ca}/Rakefile +0 -0
- data/examples/i18n/{cat → ca}/features/step_definitons/calculator_steps.rb +0 -0
- data/examples/i18n/{cat → ca}/features/suma.feature +1 -1
- data/examples/i18n/{cat → ca}/lib/calculadora.rb +0 -0
- data/examples/i18n/{se → sr-Cyrl}/Rakefile +0 -0
- data/examples/i18n/{sr → sr-Cyrl}/features/sabiranje.feature +1 -1
- data/examples/i18n/{sr → sr-Cyrl}/features/step_definitons/calculator_steps.rb +0 -0
- data/examples/i18n/{sr → sr-Cyrl}/features/support/env.rb +0 -0
- data/examples/i18n/{sr-latn → sr-Cyrl}/lib/calculator.rb +0 -0
- data/examples/i18n/{sr-latn → sr-Latn}/Rakefile +0 -0
- data/examples/i18n/{sr-latn → sr-Latn}/features/sabiranje.feature +0 -0
- data/examples/i18n/{sr-latn → sr-Latn}/features/step_definitons/calculator_steps.rb +0 -0
- data/examples/i18n/{sr → sr-Latn}/lib/calculator.rb +0 -0
- data/examples/i18n/{sr → sv}/Rakefile +0 -0
- data/examples/i18n/{se → sv}/features/step_definitons/kalkulator_steps.rb +0 -0
- data/examples/i18n/{se → sv}/features/summering.feature +1 -1
- data/examples/i18n/{se → sv}/lib/kalkulator.rb +0 -0
- data/features/announce.feature +27 -5
- data/features/bug_585_tab_indentation.feature +22 -0
- data/features/exception_in_after_block.feature +25 -0
- data/features/exception_in_before_block.feature +21 -0
- data/features/language_help.feature +6 -6
- data/features/snippets_when_using_star_keyword.feature +36 -0
- data/features/wire_protocol_tags.feature +50 -10
- data/gem_tasks/contributors.rake +4 -2
- data/lib/autotest/cucumber_rails_rspec2.rb +6 -0
- data/lib/autotest/cucumber_rspec2.rb +6 -0
- data/lib/cucumber/ast/outline_table.rb +8 -0
- data/lib/cucumber/ast/py_string.rb +5 -1
- data/lib/cucumber/ast/step_invocation.rb +2 -2
- data/lib/cucumber/cli/options.rb +1 -0
- data/lib/cucumber/cli/profile_loader.rb +8 -2
- data/lib/cucumber/formatter/pdf.rb +9 -2
- data/lib/cucumber/formatter/progress.rb +24 -2
- data/lib/cucumber/formatter/unicode.rb +11 -11
- data/lib/cucumber/languages.yml +14 -13
- data/lib/cucumber/parser/feature.rb +0 -257
- data/lib/cucumber/parser/feature.tt +0 -32
- data/lib/cucumber/parser/i18n.tt +2 -1
- data/lib/cucumber/parser/natural_language.rb +7 -4
- data/lib/cucumber/parser/py_string.rb +2 -2
- data/lib/cucumber/parser/py_string.tt +2 -2
- data/lib/cucumber/rb_support/rb_world.rb +9 -0
- data/lib/cucumber/step_mother.rb +3 -3
- data/spec/cucumber/ast/feature_factory.rb +1 -1
- data/spec/cucumber/ast/py_string_spec.rb +4 -4
- data/spec/cucumber/ast/step_spec.rb +1 -1
- data/spec/cucumber/cli/configuration_spec.rb +7 -0
- data/spec/cucumber/cli/profile_loader_spec.rb +29 -4
- data/spec/cucumber/step_mother_spec.rb +13 -3
- metadata +34 -30
@@ -5,7 +5,15 @@ Feature: Wire protocol tags
|
|
5
5
|
|
6
6
|
Background:
|
7
7
|
Given a standard Cucumber project directory structure
|
8
|
-
And a file named "features/
|
8
|
+
And a file named "features/step_definitions/some_remote_place.wire" with:
|
9
|
+
"""
|
10
|
+
host: localhost
|
11
|
+
port: 54321
|
12
|
+
|
13
|
+
"""
|
14
|
+
|
15
|
+
Scenario: Run a scenario
|
16
|
+
Given a file named "features/wired.feature" with:
|
9
17
|
"""
|
10
18
|
@foo @bar
|
11
19
|
Feature: Wired
|
@@ -15,15 +23,7 @@ Feature: Wire protocol tags
|
|
15
23
|
Given we're all wired
|
16
24
|
|
17
25
|
"""
|
18
|
-
And
|
19
|
-
"""
|
20
|
-
host: localhost
|
21
|
-
port: 54321
|
22
|
-
|
23
|
-
"""
|
24
|
-
|
25
|
-
Scenario: Run the scenario
|
26
|
-
Given there is a wire server running on port 54321 which understands the following protocol:
|
26
|
+
And there is a wire server running on port 54321 which understands the following protocol:
|
27
27
|
| request | response |
|
28
28
|
| ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
|
29
29
|
| ["begin_scenario", {"tags":["bar","baz","foo"]}] | ["success"] |
|
@@ -45,3 +45,43 @@ Feature: Wire protocol tags
|
|
45
45
|
|
46
46
|
"""
|
47
47
|
|
48
|
+
Scenario: Run a scenario outline example
|
49
|
+
Given a file named "features/wired.feature" with:
|
50
|
+
"""
|
51
|
+
@foo @bar
|
52
|
+
Feature: Wired
|
53
|
+
|
54
|
+
@baz
|
55
|
+
Scenario Outline: Everybody's Wired
|
56
|
+
Given we're all <something>
|
57
|
+
|
58
|
+
Examples:
|
59
|
+
| something |
|
60
|
+
| wired |
|
61
|
+
|
62
|
+
"""
|
63
|
+
And there is a wire server running on port 54321 which understands the following protocol:
|
64
|
+
| request | response |
|
65
|
+
| ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
|
66
|
+
| ["begin_scenario", {"tags":["bar","baz","foo"]}] | ["success"] |
|
67
|
+
| ["invoke",{"id":"1","args":[]}] | ["success"] |
|
68
|
+
| ["end_scenario", {"tags":["bar","baz","foo"]}] | ["success"] |
|
69
|
+
When I run cucumber -f pretty -q
|
70
|
+
Then STDERR should be empty
|
71
|
+
And it should pass with
|
72
|
+
"""
|
73
|
+
@foo @bar
|
74
|
+
Feature: Wired
|
75
|
+
|
76
|
+
@baz
|
77
|
+
Scenario Outline: Everybody's Wired
|
78
|
+
Given we're all <something>
|
79
|
+
|
80
|
+
Examples:
|
81
|
+
| something |
|
82
|
+
| wired |
|
83
|
+
|
84
|
+
1 scenario (1 passed)
|
85
|
+
1 step (1 passed)
|
86
|
+
|
87
|
+
"""
|
data/gem_tasks/contributors.rake
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
desc 'List contributors'
|
2
3
|
task :contributors do
|
3
|
-
contributors = `git log --pretty=short --no-merges | git shortlog -ne | egrep -ve '^ +' | egrep -ve '^$'
|
4
|
-
puts contributors
|
4
|
+
contributors = `git log --pretty=short --no-merges | git shortlog -ne | egrep -ve '^ +' | egrep -ve '^$'`.split("\n")
|
5
|
+
puts contributors
|
6
|
+
puts "Total: #{contributors.length}"
|
5
7
|
end
|
6
8
|
|
7
9
|
task :codeswarm do
|
@@ -23,6 +23,10 @@ module Cucumber
|
|
23
23
|
def accept_hook?(hook)
|
24
24
|
@scenario_outline.accept_hook?(hook)
|
25
25
|
end
|
26
|
+
|
27
|
+
def source_tag_names
|
28
|
+
@scenario_outline.source_tag_names
|
29
|
+
end
|
26
30
|
|
27
31
|
def skip_invoke!
|
28
32
|
example_rows.each do |cells|
|
@@ -61,6 +65,10 @@ module Cucumber
|
|
61
65
|
super
|
62
66
|
@scenario_exception = nil
|
63
67
|
end
|
68
|
+
|
69
|
+
def source_tag_names
|
70
|
+
@table.source_tag_names
|
71
|
+
end
|
64
72
|
|
65
73
|
def create_step_invocations!(scenario_outline)
|
66
74
|
@scenario_outline = scenario_outline
|
@@ -29,7 +29,11 @@ module Cucumber
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def to_s
|
32
|
-
|
32
|
+
# Assume all whitespace before the first triple quote is the same.
|
33
|
+
# Also assume the contents of the pystring is indented with the same prefix.
|
34
|
+
# This allows indentation with both " " and "\t" characters.
|
35
|
+
return @string if @quotes_indent == ""
|
36
|
+
@string.gsub(/^#{@quotes_indent[0..0]}{0,#{@quotes_indent.length}}/, "")
|
33
37
|
end
|
34
38
|
|
35
39
|
def accept(visitor)
|
@@ -142,11 +142,11 @@ module Cucumber
|
|
142
142
|
end
|
143
143
|
|
144
144
|
def actual_keyword
|
145
|
-
repeat_keywords = [language.but_keywords(false), language.and_keywords(false)].flatten
|
145
|
+
repeat_keywords = [language.but_keywords(false), language.and_keywords(false)].flatten.uniq.reject{|kw| kw == '*'}
|
146
146
|
if repeat_keywords.index(@step.keyword) && previous
|
147
147
|
previous.actual_keyword
|
148
148
|
else
|
149
|
-
keyword
|
149
|
+
keyword == '*' ? language.given_keyword : keyword
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
data/lib/cucumber/cli/options.rb
CHANGED
@@ -352,6 +352,7 @@ module Cucumber
|
|
352
352
|
end
|
353
353
|
@options[:source] &= other_options[:source]
|
354
354
|
@options[:snippets] &= other_options[:snippets]
|
355
|
+
@options[:strict] |= other_options[:strict]
|
355
356
|
|
356
357
|
@profiles += other_options.profiles
|
357
358
|
@expanded_args += other_options.expanded_args
|
@@ -22,8 +22,14 @@ Defined profiles in cucumber.yml:
|
|
22
22
|
case(args_from_yml)
|
23
23
|
when String
|
24
24
|
raise YmlLoadError, "The '#{profile}' profile in cucumber.yml was blank. Please define the command line arguments for the '#{profile}' profile in cucumber.yml.\n" if args_from_yml =~ /^\s*$/
|
25
|
-
|
26
|
-
|
25
|
+
if(Cucumber::WINDOWS)
|
26
|
+
#Shellwords treats backslash as an escape character so here's a rudimentary approximation of the same code
|
27
|
+
args_from_yml = args_from_yml.split
|
28
|
+
args_from_yml = args_from_yml.collect {|x| x.gsub(/^\"(.*)\"/,'\1') }
|
29
|
+
else
|
30
|
+
require 'shellwords'
|
31
|
+
args_from_yml = Shellwords.shellwords(args_from_yml)
|
32
|
+
end
|
27
33
|
when Array
|
28
34
|
raise YmlLoadError, "The '#{profile}' profile in cucumber.yml was empty. Please define the command line arguments for the '#{profile}' profile in cucumber.yml.\n" if args_from_yml.empty?
|
29
35
|
else
|
@@ -39,9 +39,9 @@ module Cucumber
|
|
39
39
|
@coder = HTMLEntities.new
|
40
40
|
|
41
41
|
if(options[:dry_run])
|
42
|
-
@status_colors = { :passed => BLACK, :skipped => BLACK, :undefined => BLACK, :failed => BLACK}
|
42
|
+
@status_colors = { :passed => BLACK, :skipped => BLACK, :undefined => BLACK, :failed => BLACK, :announced => GREY}
|
43
43
|
else
|
44
|
-
@status_colors = { :passed => '055902', :skipped => GREY, :undefined => 'F27405', :failed => '730202'}
|
44
|
+
@status_colors = { :passed => '055902', :skipped => GREY, :undefined => 'F27405', :failed => '730202', :announced => GREY}
|
45
45
|
end
|
46
46
|
|
47
47
|
@pdf = Prawn::Document.new
|
@@ -82,6 +82,13 @@ module Cucumber
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
+
def announce(announcement)
|
86
|
+
@pdf.fill_color(@status_colors[:announced])
|
87
|
+
@pdf.text announcement, :size => 10
|
88
|
+
@pdf.fill_color BLACK
|
89
|
+
end
|
90
|
+
|
91
|
+
|
85
92
|
def after_features(features)
|
86
93
|
@pdf.render_file(@file.path)
|
87
94
|
puts "\ndone"
|
@@ -19,15 +19,33 @@ module Cucumber
|
|
19
19
|
print_summary(features)
|
20
20
|
end
|
21
21
|
|
22
|
+
def before_feature_element(*args)
|
23
|
+
@exception_raised = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def after_feature_element(*args)
|
27
|
+
progress(:failed) if @exception_raised
|
28
|
+
@exception_raised = false
|
29
|
+
end
|
30
|
+
|
31
|
+
def before_steps(*args)
|
32
|
+
progress(:failed) if @exception_raised
|
33
|
+
@exception_raised = false
|
34
|
+
end
|
35
|
+
|
36
|
+
def after_steps(*args)
|
37
|
+
@exception_raised = false
|
38
|
+
end
|
39
|
+
|
22
40
|
def after_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
|
23
41
|
progress(status)
|
24
42
|
@status = status
|
25
43
|
end
|
26
|
-
|
44
|
+
|
27
45
|
def before_outline_table(outline_table)
|
28
46
|
@outline_table = outline_table
|
29
47
|
end
|
30
|
-
|
48
|
+
|
31
49
|
def after_outline_table(outline_table)
|
32
50
|
@outline_table = nil
|
33
51
|
end
|
@@ -38,6 +56,10 @@ module Cucumber
|
|
38
56
|
progress(status) unless table_header_cell?(status)
|
39
57
|
end
|
40
58
|
|
59
|
+
def exception(*args)
|
60
|
+
@exception_raised = true
|
61
|
+
end
|
62
|
+
|
41
63
|
private
|
42
64
|
|
43
65
|
def print_summary(features)
|
@@ -7,6 +7,17 @@ $KCODE='u' unless Cucumber::RUBY_1_9
|
|
7
7
|
if Cucumber::WINDOWS
|
8
8
|
require 'iconv'
|
9
9
|
|
10
|
+
if ENV['CUCUMBER_OUTPUT_ENCODING']
|
11
|
+
Cucumber::CODEPAGE = ENV['CUCUMBER_OUTPUT_ENCODING']
|
12
|
+
elsif Cucumber::WINDOWS_MRI
|
13
|
+
Cucumber::CODEPAGE = "cp#{Win32::Console::OutputCP()}"
|
14
|
+
elsif `cmd /c chcp` =~ /(\d+)/
|
15
|
+
Cucumber::CODEPAGE = "cp#{$1.to_i}"
|
16
|
+
else
|
17
|
+
Cucumber::CODEPAGE = "cp1252"
|
18
|
+
STDERR.puts("WARNING: Couldn't detect your output codepage. Assuming it is 1252. You may have to chcp 1252 or SET CUCUMBER_OUTPUT_ENCODING=cp1252.")
|
19
|
+
end
|
20
|
+
|
10
21
|
module Cucumber
|
11
22
|
module WindowsOutput #:nodoc:
|
12
23
|
def self.extended(o)
|
@@ -44,15 +55,4 @@ if Cucumber::WINDOWS
|
|
44
55
|
STDERR.extend(self)
|
45
56
|
end
|
46
57
|
end
|
47
|
-
|
48
|
-
if ENV['CUCUMBER_OUTPUT_ENCODING']
|
49
|
-
Cucumber::CODEPAGE = ENV['CUCUMBER_OUTPUT_ENCODING']
|
50
|
-
elsif Cucumber::WINDOWS_MRI
|
51
|
-
Cucumber::CODEPAGE = "cp#{Win32::Console::OutputCP()}"
|
52
|
-
elsif `cmd /c chcp` =~ /(\d+)/
|
53
|
-
Cucumber::CODEPAGE = "cp#{$1.to_i}"
|
54
|
-
else
|
55
|
-
Cucumber::CODEPAGE = "cp1252"
|
56
|
-
STDERR.cucumber_puts("WARNING: Couldn't detect your output codepage. Assuming it is 1252. You may have to chcp 1252 or SET CUCUMBER_OUTPUT_ENCODING=cp1252.")
|
57
|
-
end
|
58
58
|
end
|
data/lib/cucumber/languages.yml
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
-
#
|
3
|
-
#
|
2
|
+
#
|
3
|
+
# We use ISO 639-1 (language) and ISO 3166 alpha-2 (region - if appliccable):
|
4
|
+
# http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
|
5
|
+
# http://en.wikipedia.org/wiki/ISO_3166-1
|
4
6
|
#
|
5
7
|
# If you want several aliases for a keyword, just separate them
|
6
8
|
# with a | character. Make sure there are no ambiguities in the
|
7
9
|
# keywords.
|
8
10
|
#
|
11
|
+
# If you do *not* want a trailing space after a keyword, end it with a < character.
|
12
|
+
# (See Chinese for examples).
|
13
|
+
#
|
9
14
|
"en":
|
10
15
|
name: English
|
11
16
|
native: English
|
@@ -20,10 +25,6 @@
|
|
20
25
|
and: "*|And"
|
21
26
|
but: "*|But"
|
22
27
|
|
23
|
-
# Please help us keeping the languages below uptodate. The parsers for a language
|
24
|
-
# that is missing a keyword will expect the English word until the missing word(s)
|
25
|
-
# are added.
|
26
|
-
#
|
27
28
|
# Please keep the grammars in alphabetical order by name from here and down.
|
28
29
|
|
29
30
|
"ar":
|
@@ -52,7 +53,7 @@
|
|
52
53
|
then: "*|То"
|
53
54
|
and: "*|И"
|
54
55
|
but: "*|Но"
|
55
|
-
"
|
56
|
+
"ca":
|
56
57
|
name: Catalan
|
57
58
|
native: català
|
58
59
|
background: Rerefons|Antecedents
|
@@ -65,7 +66,7 @@
|
|
65
66
|
then: "*|Aleshores|Cal"
|
66
67
|
and: "*|I"
|
67
68
|
but: "*|Però"
|
68
|
-
"cy":
|
69
|
+
"cy-GB":
|
69
70
|
name: Welsh
|
70
71
|
native: Cymraeg
|
71
72
|
background: Cefndir
|
@@ -390,7 +391,7 @@
|
|
390
391
|
then: "*|Atunci"
|
391
392
|
and: "*|Si"
|
392
393
|
but: "*|Dar"
|
393
|
-
"
|
394
|
+
"ro-RO":
|
394
395
|
name: Romanian (diacritical)
|
395
396
|
native: română (diacritical)
|
396
397
|
background: Condiţii
|
@@ -416,7 +417,7 @@
|
|
416
417
|
then: "*|То"
|
417
418
|
and: "*|И|К тому же"
|
418
419
|
but: "*|Но|А"
|
419
|
-
"
|
420
|
+
"sv":
|
420
421
|
name: Swedish
|
421
422
|
native: Svenska
|
422
423
|
feature: Egenskap
|
@@ -443,8 +444,8 @@
|
|
443
444
|
and: "*|A"
|
444
445
|
but: "*|Ale"
|
445
446
|
"sr-Latn":
|
446
|
-
name:
|
447
|
-
native:
|
447
|
+
name: Serbian (Latin)
|
448
|
+
native: Srpski (Latinica)
|
448
449
|
feature: Funkcionalnost|Mogućnost|Mogucnost|Osobina
|
449
450
|
background: Kontekst|Osnova|Pozadina
|
450
451
|
scenario: Scenario|Primer
|
@@ -455,7 +456,7 @@
|
|
455
456
|
then: "*|Onda"
|
456
457
|
and: "*|I"
|
457
458
|
but: "*|Ali"
|
458
|
-
"sr":
|
459
|
+
"sr-Cyrl":
|
459
460
|
name: Serbian
|
460
461
|
native: Српски
|
461
462
|
feature: Функционалност|Могућност|Особина
|
@@ -1542,263 +1542,6 @@ module Cucumber
|
|
1542
1542
|
r0
|
1543
1543
|
end
|
1544
1544
|
|
1545
|
-
module PyString0
|
1546
|
-
end
|
1547
|
-
|
1548
|
-
module PyString1
|
1549
|
-
def open_py_string
|
1550
|
-
elements[0]
|
1551
|
-
end
|
1552
|
-
|
1553
|
-
def s
|
1554
|
-
elements[1]
|
1555
|
-
end
|
1556
|
-
|
1557
|
-
def close_py_string
|
1558
|
-
elements[2]
|
1559
|
-
end
|
1560
|
-
end
|
1561
|
-
|
1562
|
-
module PyString2
|
1563
|
-
def at_line?(line)
|
1564
|
-
line >= open_py_string.line && line <= close_py_string.line
|
1565
|
-
end
|
1566
|
-
|
1567
|
-
def build
|
1568
|
-
Ast::PyString.new(open_py_string.line, close_py_string.line, s.text_value, open_py_string.indentation)
|
1569
|
-
end
|
1570
|
-
end
|
1571
|
-
|
1572
|
-
def _nt_py_string
|
1573
|
-
start_index = index
|
1574
|
-
if node_cache[:py_string].has_key?(index)
|
1575
|
-
cached = node_cache[:py_string][index]
|
1576
|
-
if cached
|
1577
|
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
1578
|
-
@index = cached.interval.end
|
1579
|
-
end
|
1580
|
-
return cached
|
1581
|
-
end
|
1582
|
-
|
1583
|
-
i0, s0 = index, []
|
1584
|
-
r1 = _nt_open_py_string
|
1585
|
-
s0 << r1
|
1586
|
-
if r1
|
1587
|
-
s2, i2 = [], index
|
1588
|
-
loop do
|
1589
|
-
i3, s3 = index, []
|
1590
|
-
i4 = index
|
1591
|
-
r5 = _nt_close_py_string
|
1592
|
-
if r5
|
1593
|
-
r4 = nil
|
1594
|
-
else
|
1595
|
-
@index = i4
|
1596
|
-
r4 = instantiate_node(SyntaxNode,input, index...index)
|
1597
|
-
end
|
1598
|
-
s3 << r4
|
1599
|
-
if r4
|
1600
|
-
if index < input_length
|
1601
|
-
r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
1602
|
-
@index += 1
|
1603
|
-
else
|
1604
|
-
terminal_parse_failure("any character")
|
1605
|
-
r6 = nil
|
1606
|
-
end
|
1607
|
-
s3 << r6
|
1608
|
-
end
|
1609
|
-
if s3.last
|
1610
|
-
r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
|
1611
|
-
r3.extend(PyString0)
|
1612
|
-
else
|
1613
|
-
@index = i3
|
1614
|
-
r3 = nil
|
1615
|
-
end
|
1616
|
-
if r3
|
1617
|
-
s2 << r3
|
1618
|
-
else
|
1619
|
-
break
|
1620
|
-
end
|
1621
|
-
end
|
1622
|
-
r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
|
1623
|
-
s0 << r2
|
1624
|
-
if r2
|
1625
|
-
r7 = _nt_close_py_string
|
1626
|
-
s0 << r7
|
1627
|
-
end
|
1628
|
-
end
|
1629
|
-
if s0.last
|
1630
|
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
1631
|
-
r0.extend(PyString1)
|
1632
|
-
r0.extend(PyString2)
|
1633
|
-
else
|
1634
|
-
@index = i0
|
1635
|
-
r0 = nil
|
1636
|
-
end
|
1637
|
-
|
1638
|
-
node_cache[:py_string][start_index] = r0
|
1639
|
-
|
1640
|
-
r0
|
1641
|
-
end
|
1642
|
-
|
1643
|
-
module OpenPyString0
|
1644
|
-
def indent
|
1645
|
-
elements[0]
|
1646
|
-
end
|
1647
|
-
|
1648
|
-
def eol
|
1649
|
-
elements[3]
|
1650
|
-
end
|
1651
|
-
end
|
1652
|
-
|
1653
|
-
module OpenPyString1
|
1654
|
-
def indentation
|
1655
|
-
indent.text_value.length
|
1656
|
-
end
|
1657
|
-
|
1658
|
-
def line
|
1659
|
-
indent.line
|
1660
|
-
end
|
1661
|
-
end
|
1662
|
-
|
1663
|
-
def _nt_open_py_string
|
1664
|
-
start_index = index
|
1665
|
-
if node_cache[:open_py_string].has_key?(index)
|
1666
|
-
cached = node_cache[:open_py_string][index]
|
1667
|
-
if cached
|
1668
|
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
1669
|
-
@index = cached.interval.end
|
1670
|
-
end
|
1671
|
-
return cached
|
1672
|
-
end
|
1673
|
-
|
1674
|
-
i0, s0 = index, []
|
1675
|
-
s1, i1 = [], index
|
1676
|
-
loop do
|
1677
|
-
r2 = _nt_space
|
1678
|
-
if r2
|
1679
|
-
s1 << r2
|
1680
|
-
else
|
1681
|
-
break
|
1682
|
-
end
|
1683
|
-
end
|
1684
|
-
r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
|
1685
|
-
s0 << r1
|
1686
|
-
if r1
|
1687
|
-
if has_terminal?('"""', false, index)
|
1688
|
-
r3 = instantiate_node(SyntaxNode,input, index...(index + 3))
|
1689
|
-
@index += 3
|
1690
|
-
else
|
1691
|
-
terminal_parse_failure('"""')
|
1692
|
-
r3 = nil
|
1693
|
-
end
|
1694
|
-
s0 << r3
|
1695
|
-
if r3
|
1696
|
-
s4, i4 = [], index
|
1697
|
-
loop do
|
1698
|
-
r5 = _nt_space
|
1699
|
-
if r5
|
1700
|
-
s4 << r5
|
1701
|
-
else
|
1702
|
-
break
|
1703
|
-
end
|
1704
|
-
end
|
1705
|
-
r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
|
1706
|
-
s0 << r4
|
1707
|
-
if r4
|
1708
|
-
r6 = _nt_eol
|
1709
|
-
s0 << r6
|
1710
|
-
end
|
1711
|
-
end
|
1712
|
-
end
|
1713
|
-
if s0.last
|
1714
|
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
1715
|
-
r0.extend(OpenPyString0)
|
1716
|
-
r0.extend(OpenPyString1)
|
1717
|
-
else
|
1718
|
-
@index = i0
|
1719
|
-
r0 = nil
|
1720
|
-
end
|
1721
|
-
|
1722
|
-
node_cache[:open_py_string][start_index] = r0
|
1723
|
-
|
1724
|
-
r0
|
1725
|
-
end
|
1726
|
-
|
1727
|
-
module ClosePyString0
|
1728
|
-
def eol
|
1729
|
-
elements[0]
|
1730
|
-
end
|
1731
|
-
|
1732
|
-
def quotes
|
1733
|
-
elements[2]
|
1734
|
-
end
|
1735
|
-
|
1736
|
-
def white
|
1737
|
-
elements[3]
|
1738
|
-
end
|
1739
|
-
end
|
1740
|
-
|
1741
|
-
module ClosePyString1
|
1742
|
-
def line
|
1743
|
-
quotes.line
|
1744
|
-
end
|
1745
|
-
end
|
1746
|
-
|
1747
|
-
def _nt_close_py_string
|
1748
|
-
start_index = index
|
1749
|
-
if node_cache[:close_py_string].has_key?(index)
|
1750
|
-
cached = node_cache[:close_py_string][index]
|
1751
|
-
if cached
|
1752
|
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
1753
|
-
@index = cached.interval.end
|
1754
|
-
end
|
1755
|
-
return cached
|
1756
|
-
end
|
1757
|
-
|
1758
|
-
i0, s0 = index, []
|
1759
|
-
r1 = _nt_eol
|
1760
|
-
s0 << r1
|
1761
|
-
if r1
|
1762
|
-
s2, i2 = [], index
|
1763
|
-
loop do
|
1764
|
-
r3 = _nt_space
|
1765
|
-
if r3
|
1766
|
-
s2 << r3
|
1767
|
-
else
|
1768
|
-
break
|
1769
|
-
end
|
1770
|
-
end
|
1771
|
-
r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
|
1772
|
-
s0 << r2
|
1773
|
-
if r2
|
1774
|
-
if has_terminal?('"""', false, index)
|
1775
|
-
r4 = instantiate_node(SyntaxNode,input, index...(index + 3))
|
1776
|
-
@index += 3
|
1777
|
-
else
|
1778
|
-
terminal_parse_failure('"""')
|
1779
|
-
r4 = nil
|
1780
|
-
end
|
1781
|
-
s0 << r4
|
1782
|
-
if r4
|
1783
|
-
r5 = _nt_white
|
1784
|
-
s0 << r5
|
1785
|
-
end
|
1786
|
-
end
|
1787
|
-
end
|
1788
|
-
if s0.last
|
1789
|
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
1790
|
-
r0.extend(ClosePyString0)
|
1791
|
-
r0.extend(ClosePyString1)
|
1792
|
-
else
|
1793
|
-
@index = i0
|
1794
|
-
r0 = nil
|
1795
|
-
end
|
1796
|
-
|
1797
|
-
node_cache[:close_py_string][start_index] = r0
|
1798
|
-
|
1799
|
-
r0
|
1800
|
-
end
|
1801
|
-
|
1802
1545
|
def _nt_white
|
1803
1546
|
start_index = index
|
1804
1547
|
if node_cache[:white].has_key?(index)
|