regexp_parser 0.1.6 → 0.2.0

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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +57 -0
  3. data/Gemfile +8 -0
  4. data/LICENSE +1 -1
  5. data/README.md +225 -206
  6. data/Rakefile +9 -3
  7. data/lib/regexp_parser.rb +7 -11
  8. data/lib/regexp_parser/expression.rb +72 -14
  9. data/lib/regexp_parser/expression/classes/alternation.rb +3 -16
  10. data/lib/regexp_parser/expression/classes/conditional.rb +57 -0
  11. data/lib/regexp_parser/expression/classes/free_space.rb +17 -0
  12. data/lib/regexp_parser/expression/classes/keep.rb +7 -0
  13. data/lib/regexp_parser/expression/classes/set.rb +28 -7
  14. data/lib/regexp_parser/expression/methods/strfregexp.rb +113 -0
  15. data/lib/regexp_parser/expression/methods/tests.rb +116 -0
  16. data/lib/regexp_parser/expression/methods/traverse.rb +63 -0
  17. data/lib/regexp_parser/expression/quantifier.rb +10 -0
  18. data/lib/regexp_parser/expression/sequence.rb +45 -0
  19. data/lib/regexp_parser/expression/subexpression.rb +29 -1
  20. data/lib/regexp_parser/lexer.rb +31 -8
  21. data/lib/regexp_parser/parser.rb +118 -45
  22. data/lib/regexp_parser/scanner.rb +1745 -1404
  23. data/lib/regexp_parser/scanner/property.rl +57 -3
  24. data/lib/regexp_parser/scanner/scanner.rl +161 -34
  25. data/lib/regexp_parser/syntax.rb +12 -2
  26. data/lib/regexp_parser/syntax/ruby/1.9.1.rb +3 -3
  27. data/lib/regexp_parser/syntax/ruby/1.9.3.rb +2 -7
  28. data/lib/regexp_parser/syntax/ruby/2.0.0.rb +4 -1
  29. data/lib/regexp_parser/syntax/ruby/2.1.4.rb +13 -0
  30. data/lib/regexp_parser/syntax/ruby/2.1.5.rb +13 -0
  31. data/lib/regexp_parser/syntax/ruby/2.1.rb +2 -2
  32. data/lib/regexp_parser/syntax/ruby/2.2.0.rb +16 -0
  33. data/lib/regexp_parser/syntax/ruby/2.2.rb +8 -0
  34. data/lib/regexp_parser/syntax/tokens.rb +19 -2
  35. data/lib/regexp_parser/syntax/tokens/conditional.rb +22 -0
  36. data/lib/regexp_parser/syntax/tokens/keep.rb +14 -0
  37. data/lib/regexp_parser/syntax/tokens/unicode_property.rb +45 -4
  38. data/lib/regexp_parser/token.rb +23 -8
  39. data/lib/regexp_parser/version.rb +5 -0
  40. data/regexp_parser.gemspec +35 -0
  41. data/test/expression/test_all.rb +6 -1
  42. data/test/expression/test_base.rb +19 -0
  43. data/test/expression/test_conditionals.rb +114 -0
  44. data/test/expression/test_free_space.rb +33 -0
  45. data/test/expression/test_set.rb +61 -0
  46. data/test/expression/test_strfregexp.rb +214 -0
  47. data/test/expression/test_subexpression.rb +24 -0
  48. data/test/expression/test_tests.rb +99 -0
  49. data/test/expression/test_to_h.rb +48 -0
  50. data/test/expression/test_to_s.rb +46 -0
  51. data/test/expression/test_traverse.rb +164 -0
  52. data/test/lexer/test_all.rb +16 -3
  53. data/test/lexer/test_conditionals.rb +101 -0
  54. data/test/lexer/test_keep.rb +24 -0
  55. data/test/lexer/test_literals.rb +51 -51
  56. data/test/lexer/test_nesting.rb +62 -62
  57. data/test/lexer/test_refcalls.rb +18 -20
  58. data/test/parser/test_all.rb +18 -3
  59. data/test/parser/test_alternation.rb +11 -14
  60. data/test/parser/test_conditionals.rb +148 -0
  61. data/test/parser/test_escapes.rb +29 -5
  62. data/test/parser/test_free_space.rb +139 -0
  63. data/test/parser/test_groups.rb +40 -0
  64. data/test/parser/test_keep.rb +21 -0
  65. data/test/scanner/test_all.rb +8 -2
  66. data/test/scanner/test_conditionals.rb +166 -0
  67. data/test/scanner/test_escapes.rb +8 -5
  68. data/test/scanner/test_free_space.rb +133 -0
  69. data/test/scanner/test_groups.rb +28 -0
  70. data/test/scanner/test_keep.rb +33 -0
  71. data/test/scanner/test_properties.rb +4 -0
  72. data/test/scanner/test_scripts.rb +71 -1
  73. data/test/syntax/ruby/test_1.9.3.rb +2 -2
  74. data/test/syntax/ruby/test_2.0.0.rb +38 -0
  75. data/test/syntax/ruby/test_2.2.0.rb +38 -0
  76. data/test/syntax/ruby/test_all.rb +1 -8
  77. data/test/syntax/ruby/test_files.rb +104 -0
  78. data/test/test_all.rb +2 -1
  79. data/test/token/test_all.rb +2 -0
  80. data/test/token/test_token.rb +109 -0
  81. metadata +75 -21
  82. data/VERSION.yml +0 -5
  83. data/lib/regexp_parser/ctype.rb +0 -48
  84. data/test/syntax/ruby/test_2.x.rb +0 -46
@@ -1,5 +1,6 @@
1
+ require File.expand_path('../syntax/tokens', __FILE__)
2
+
1
3
  module Regexp::Syntax
2
- require File.expand_path('../syntax/tokens', __FILE__)
3
4
 
4
5
  class SyntaxError < StandardError
5
6
  def initialize(what)
@@ -63,10 +64,18 @@ module Regexp::Syntax
63
64
  when 'ruby/2.1.0'; syntax = Regexp::Syntax::Ruby::V210.new
64
65
  when 'ruby/2.1.2'; syntax = Regexp::Syntax::Ruby::V212.new
65
66
  when 'ruby/2.1.3'; syntax = Regexp::Syntax::Ruby::V213.new
67
+ when 'ruby/2.1.4'; syntax = Regexp::Syntax::Ruby::V214.new
68
+ when 'ruby/2.1.5'; syntax = Regexp::Syntax::Ruby::V215.new
66
69
 
67
70
  # aliases for the latest 2.1 implementations
68
71
  when 'ruby/2.1'; syntax = Regexp::Syntax::Ruby::V21.new
69
72
 
73
+ # Ruby 2.2.x
74
+ when 'ruby/2.2.0'; syntax = Regexp::Syntax::Ruby::V220.new
75
+
76
+ # aliases for the latest 2.2 implementations
77
+ when 'ruby/2.2'; syntax = Regexp::Syntax::Ruby::V22.new
78
+
70
79
  else
71
80
  raise UnknownSyntaxError.new(name)
72
81
  end
@@ -87,7 +96,8 @@ module Regexp::Syntax
87
96
  def initialize
88
97
  @implements = {}
89
98
 
90
- implements :literal, [:literal]
99
+ implements Token::Literal::Type, Token::Literal::All
100
+ implements Token::FreeSpace::Type, Token::FreeSpace::All
91
101
  end
92
102
 
93
103
  def implementation
@@ -18,10 +18,10 @@ module Regexp::Syntax
18
18
  implements :escape, CharacterType::Hex
19
19
 
20
20
  implements :property,
21
- UnicodeProperty::All
21
+ UnicodeProperty::V190
22
22
 
23
23
  implements :nonproperty,
24
- UnicodeProperty::All
24
+ UnicodeProperty::V190
25
25
 
26
26
  implements :quantifier,
27
27
  Quantifier::Possessive + Quantifier::IntervalPossessive
@@ -30,7 +30,7 @@ module Regexp::Syntax
30
30
  CharacterSet::POSIX::StandardNegative +
31
31
  CharacterSet::POSIX::Extensions +
32
32
  CharacterSet::POSIX::ExtensionsNegative +
33
- UnicodeProperty::All
33
+ UnicodeProperty::V190
34
34
 
35
35
  implements :subset, CharacterSet::OpenClose +
36
36
  CharacterSet::Extended + CharacterSet::Types +
@@ -10,13 +10,8 @@ module Regexp::Syntax
10
10
  super
11
11
 
12
12
  # these were added with update of Oniguruma to Unicode 6.0
13
- implements :property,
14
- [:script_mandaic, :script_batak, :script_brahmi] +
15
- UnicodeProperty::Age
16
-
17
- implements :nonproperty,
18
- [:script_mandaic, :script_batak, :script_brahmi] +
19
- UnicodeProperty::Age
13
+ implements :property, UnicodeProperty::V193
14
+ implements :nonproperty, UnicodeProperty::V193
20
15
  end
21
16
  end
22
17
  end
@@ -8,7 +8,10 @@ module Regexp::Syntax
8
8
  def initialize
9
9
  super
10
10
 
11
- #implements :escape, CharacterType::Hex
11
+ implements :keep, Keep::All
12
+ implements :conditional, Conditional::All
13
+ implements :property, UnicodeProperty::V200
14
+ implements :nonproperty, UnicodeProperty::V200
12
15
  end
13
16
  end
14
17
 
@@ -0,0 +1,13 @@
1
+ require File.expand_path('../2.1.3', __FILE__)
2
+
3
+ module Regexp::Syntax
4
+ module Ruby
5
+
6
+ class V214 < Regexp::Syntax::Ruby::V213
7
+ def initialize
8
+ super
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require File.expand_path('../2.1.4', __FILE__)
2
+
3
+ module Regexp::Syntax
4
+ module Ruby
5
+
6
+ class V215 < Regexp::Syntax::Ruby::V214
7
+ def initialize
8
+ super
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -1,8 +1,8 @@
1
- require File.expand_path('../2.1.3', __FILE__)
1
+ require File.expand_path('../2.1.5', __FILE__)
2
2
 
3
3
  module Regexp::Syntax
4
4
  module Ruby
5
5
  # uses the latest 2.1 release
6
- class V21 < Regexp::Syntax::Ruby::V213; end
6
+ class V21 < Regexp::Syntax::Ruby::V215; end
7
7
  end
8
8
  end
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../2.1', __FILE__)
2
+
3
+ module Regexp::Syntax
4
+ module Ruby
5
+
6
+ class V220 < Regexp::Syntax::Ruby::V21
7
+ def initialize
8
+ super
9
+
10
+ implements :property, UnicodeProperty::V220
11
+ implements :nonproperty, UnicodeProperty::V220
12
+ end
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ require File.expand_path('../2.2.0', __FILE__)
2
+
3
+ module Regexp::Syntax
4
+ module Ruby
5
+ # uses the latest 2.2 release
6
+ class V22 < Regexp::Syntax::Ruby::V220; end
7
+ end
8
+ end
@@ -8,13 +8,30 @@ module Regexp::Syntax
8
8
  Type = :literal
9
9
  end
10
10
 
11
- Map[Literal::Type] = Literal::All
11
+ module FreeSpace
12
+ All = [:comment, :whitespace]
13
+ Type = :free_space
14
+ end
15
+
16
+ Map[FreeSpace::Type] = FreeSpace::All
17
+ Map[Literal::Type] = Literal::All
12
18
  end
13
19
  end
14
20
 
15
21
 
16
22
  # Load all the token files, they will populate the Map constant.
17
- Dir[File.dirname(__FILE__) + '/tokens/*.rb'].each {|f| require f }
23
+ require 'regexp_parser/syntax/tokens/anchor'
24
+ require 'regexp_parser/syntax/tokens/assertion'
25
+ require 'regexp_parser/syntax/tokens/backref'
26
+ require 'regexp_parser/syntax/tokens/character_set'
27
+ require 'regexp_parser/syntax/tokens/character_type'
28
+ require 'regexp_parser/syntax/tokens/conditional'
29
+ require 'regexp_parser/syntax/tokens/escape'
30
+ require 'regexp_parser/syntax/tokens/group'
31
+ require 'regexp_parser/syntax/tokens/keep'
32
+ require 'regexp_parser/syntax/tokens/meta'
33
+ require 'regexp_parser/syntax/tokens/quantifier'
34
+ require 'regexp_parser/syntax/tokens/unicode_property'
18
35
 
19
36
 
20
37
  # After loading all the tokens the map is full. Extract all tokens and types
@@ -0,0 +1,22 @@
1
+ module Regexp::Syntax
2
+ module Token
3
+
4
+ module Conditional
5
+ Delimiters = [:open, :close]
6
+
7
+ Condition = [:condition_open, :condition, :condition_close]
8
+ Separator = [:separator]
9
+
10
+ All = (
11
+ Conditional::Delimiters +
12
+ Conditional::Condition +
13
+ Conditional::Separator
14
+ ).flatten
15
+
16
+ Type = :conditional
17
+ end
18
+
19
+ Map[Conditional::Type] = Conditional::All
20
+
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ module Regexp::Syntax
2
+ module Token
3
+
4
+ module Keep
5
+ Mark = [:mark]
6
+
7
+ All = Mark
8
+ Type = :keep
9
+ end
10
+
11
+ Map[Keep::Type] = Keep::All
12
+
13
+ end
14
+ end
@@ -34,9 +34,17 @@ module Regexp::Syntax
34
34
  Symbol + Separator + Codepoint
35
35
  end
36
36
 
37
- Age = [:age_1_1, :age_2_0, :age_2_1, :age_3_0, :age_3_1,
38
- :age_3_2, :age_4_0, :age_4_1, :age_5_0, :age_5_1,
39
- :age_5_2, :age_6_0]
37
+ # As of ruby version 1.9.3
38
+ Age_V193 = [:age_1_1, :age_2_0, :age_2_1, :age_3_0, :age_3_1,
39
+ :age_3_2, :age_4_0, :age_4_1, :age_5_0, :age_5_1,
40
+ :age_5_2, :age_6_0]
41
+
42
+ Age_V200 = [:age_6_1]
43
+
44
+ # These were merged (from Onigmo) in the branch for 2.2.0
45
+ Age_V220 = [:age_6_2, :age_6_3, :age_7_0]
46
+
47
+ Age = Age_V193 + Age_V200 + Age_V220
40
48
 
41
49
  Derived = [
42
50
  :ascii_hex,
@@ -191,7 +199,40 @@ module Regexp::Syntax
191
199
 
192
200
  Script_6_0 = [:script_brahmi, :script_batak, :script_mandaic]
193
201
 
194
- All = CharType + POSIX + Category::All + Age + Derived + Script
202
+ Script_7_0 = [
203
+ :script_caucasian_albanian,
204
+ :script_bassa_vah,
205
+ :script_duployan,
206
+ :script_elbasan,
207
+ :script_grantha,
208
+ :script_pahawh_hmong,
209
+ :script_khojki,
210
+ :script_linear_a,
211
+ :script_mahajani,
212
+ :script_manichaean,
213
+ :script_mende_kikakui,
214
+ :script_modi,
215
+ :script_mro,
216
+ :script_old_north_arabian,
217
+ :script_nabataean,
218
+ :script_palmyrene,
219
+ :script_pau_cin_hau,
220
+ :script_old_permic,
221
+ :script_psalter_pahlavi,
222
+ :script_siddham,
223
+ :script_khudawadi,
224
+ :script_tirhuta,
225
+ :script_warang_citi
226
+ ]
227
+
228
+ V190 = CharType + POSIX + Category::All + Derived + Script
229
+ V193 = Age_V193 + Script_6_0
230
+
231
+ V200 = Age_V200
232
+
233
+ V220 = Age_V220 + Script_7_0
234
+
235
+ All = V190 + V193 + V200 + V220
195
236
 
196
237
  Type = :property
197
238
  NonType = :nonproperty
@@ -1,6 +1,16 @@
1
1
  class Regexp
2
2
 
3
- TOKEN_KEYS = [:type, :token, :text, :ts, :te, :level, :set_level].freeze
3
+ TOKEN_KEYS = [
4
+ :type,
5
+ :token,
6
+ :text,
7
+ :ts,
8
+ :te,
9
+ :level,
10
+ :set_level,
11
+ :conditional_level
12
+ ].freeze
13
+
4
14
  Token = Struct.new(*TOKEN_KEYS) do
5
15
  def offset
6
16
  [self.ts, self.te]
@@ -10,13 +20,6 @@ class Regexp
10
20
  self.te - self.ts
11
21
  end
12
22
 
13
- def to_h
14
- hash = {}
15
- members.each do |member|
16
- hash[member.to_sym] = self.send(member.to_sym)
17
- end; hash
18
- end
19
-
20
23
  def next(exp = nil)
21
24
  if exp
22
25
  @next = exp
@@ -32,6 +35,18 @@ class Regexp
32
35
  @previous
33
36
  end
34
37
  end
38
+
39
+ if RUBY_VERSION < '2.0.0'
40
+ def to_h
41
+ hash = {}
42
+
43
+ members.each do |member|
44
+ hash[member.to_sym] = self.send(member.to_sym)
45
+ end
46
+
47
+ hash
48
+ end
49
+ end
35
50
  end
36
51
 
37
52
  end
@@ -0,0 +1,5 @@
1
+ class Regexp
2
+ module Parser
3
+ VERSION = '0.2.0'
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
2
+
3
+ require 'regexp_parser/version'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = 'regexp_parser'
7
+ gem.version = ::Regexp::Parser::VERSION
8
+
9
+ gem.summary = "Scanner, lexer, parser for ruby's regular expressions"
10
+ gem.description = 'A library for tokenizing, lexing, and parsing Ruby regular expressions.'
11
+ gem.homepage = 'http://github.com/ammar/regexp_parser'
12
+
13
+ if gem.respond_to?(:metadata)
14
+ gem.metadata = { 'issue_tracker' => 'https://github.com/ammar/regexp_parser/issues' }
15
+ end
16
+
17
+ gem.authors = ['Ammar Ali']
18
+ gem.email = ['ammarabuali@gmail.com']
19
+
20
+ gem.license = 'MIT'
21
+
22
+ gem.require_paths = ['lib']
23
+
24
+ gem.files = Dir.glob('{lib,test}/**/*.rb') +
25
+ Dir.glob('lib/**/*.rl') +
26
+ %w(Gemfile Rakefile LICENSE README.md ChangeLog regexp_parser.gemspec)
27
+
28
+ gem.test_files = Dir.glob('test/**/*.rb')
29
+
30
+ gem.rdoc_options = ["--inline-source", "--charset=UTF-8"]
31
+
32
+ gem.platform = Gem::Platform::RUBY
33
+
34
+ gem.required_ruby_version = '>= 1.8.7'
35
+ end
@@ -1,7 +1,12 @@
1
1
  require File.expand_path("../../helpers", __FILE__)
2
2
 
3
3
  %w{
4
- base to_s clone
4
+ base to_s to_h clone subexpression free_space tests
5
+ traverse strfregexp
5
6
  }.each do|tc|
6
7
  require File.expand_path("../test_#{tc}", __FILE__)
7
8
  end
9
+
10
+ if RUBY_VERSION >= '2.0.0'
11
+ require File.expand_path("../test_conditionals", __FILE__)
12
+ end
@@ -13,6 +13,25 @@ class ExpressionBase < Test::Unit::TestCase
13
13
  assert_equal( re.source, re_text )
14
14
  end
15
15
 
16
+ def test_expression_level
17
+ regexp = /^a(b(c(d)))e$/
18
+ root = RP.parse(regexp)
19
+
20
+ %w{^ a (b(c(d))) e $}.each_with_index do |t, i|
21
+ assert_equal( t, root[i].to_s )
22
+ assert_equal( 0, root[i].level )
23
+ end
24
+
25
+ assert_equal( 'b', root[2][0].to_s )
26
+ assert_equal( 1, root[2][0].level )
27
+
28
+ assert_equal( 'c', root[2][1][0].to_s )
29
+ assert_equal( 2, root[2][1][0].level )
30
+
31
+ assert_equal( 'd', root[2][1][1][0].to_s )
32
+ assert_equal( 3, root[2][1][1][0].level )
33
+ end
34
+
16
35
  def test_expression_terminal?
17
36
  root = RP.parse('^a([b]+)c$')
18
37
 
@@ -0,0 +1,114 @@
1
+ require File.expand_path("../../helpers", __FILE__)
2
+
3
+ class ExpressionConditionals < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @root = RP.parse(/^a(b(?(1)c|(?(2)d|(?(3)e|f)))g)$/)
7
+
8
+ @cond_1 = @root[2][1]
9
+ @cond_2 = @root[2][1][2][0]
10
+ @cond_3 = @root[2][1][2][0][2][0]
11
+ end
12
+
13
+ def is_conditional_condition?(exp)
14
+ exp.is_a?(Conditional::Condition)
15
+ end
16
+
17
+ def is_conditional_branch?(exp)
18
+ exp.is_a?(Conditional::Branch)
19
+ end
20
+
21
+ def test_expression_conditional_root_level
22
+ %w{^ a (b(?(1)c|(?(2)d|(?(3)e|f)))g) $}.each_with_index do |t, i|
23
+ assert_equal( 0, @root[i].conditional_level )
24
+ assert_equal( t, @root[i].to_s )
25
+ end
26
+
27
+ # First capture group
28
+ assert_equal( 'b', @root[2][0].text )
29
+ assert_equal( 0, @root[2][0].conditional_level )
30
+ end
31
+
32
+ def test_expression_conditional_level_one
33
+ condition = @cond_1.condition
34
+ branch_1 = @cond_1.branches.first
35
+ branch_2 = @cond_1.branches.last
36
+
37
+ # Condition
38
+ assert_equal( true, is_conditional_condition?(condition) )
39
+ assert_equal( '(1)', condition.text )
40
+ assert_equal( 1, condition.conditional_level )
41
+
42
+ # Branch 1
43
+ assert_equal( true, is_conditional_branch?(branch_1) )
44
+ assert_equal( 'c', branch_1.text )
45
+ assert_equal( 1, branch_1.conditional_level )
46
+
47
+ # Literal
48
+ assert_equal( 'c', branch_1.first.text )
49
+ assert_equal( 1, branch_1.first.conditional_level )
50
+
51
+ end
52
+
53
+ def test_expression_conditional_level_two
54
+ condition = @cond_2.condition
55
+ branch_1 = @cond_2.branches.first
56
+ branch_2 = @cond_2.branches.last
57
+
58
+ assert_equal( '(?', @cond_2.text )
59
+ assert_equal( 1, @cond_2.conditional_level )
60
+
61
+ # Condition
62
+ assert_equal( true, is_conditional_condition?(condition) )
63
+ assert_equal( '(2)', condition.text )
64
+ assert_equal( 2, condition.conditional_level )
65
+
66
+ # Branch 1
67
+ assert_equal( true, is_conditional_branch?(branch_1) )
68
+ assert_equal( 'd', branch_1.text )
69
+ assert_equal( 2, branch_1.conditional_level )
70
+
71
+ # Literal
72
+ assert_equal( 'd', branch_1.first.text )
73
+ assert_equal( 2, branch_1.first.conditional_level )
74
+
75
+ # Branch 2
76
+ assert_equal( '(?', branch_2.first.text )
77
+ assert_equal( 2, branch_2.first.conditional_level )
78
+ end
79
+
80
+ def test_expression_conditional_level_three
81
+ condition = @cond_3.condition
82
+ branch_1 = @cond_3.branches.first
83
+ branch_2 = @cond_3.branches.last
84
+
85
+ # Condition
86
+ assert_equal( true, is_conditional_condition?(condition) )
87
+ assert_equal( '(3)', condition.text )
88
+ assert_equal( 3, condition.conditional_level )
89
+
90
+ # Same as branch 2 in level two
91
+ assert_equal( '(?', @cond_3.text )
92
+ assert_equal( '(?(3)e|f)', @cond_3.to_s )
93
+ assert_equal( 2, @cond_3.conditional_level )
94
+
95
+ # Branch 1
96
+ assert_equal( true, is_conditional_branch?(branch_1) )
97
+ assert_equal( 'e', branch_1.text )
98
+ assert_equal( 3, branch_1.conditional_level )
99
+
100
+ # Literal
101
+ assert_equal( 'e', branch_1.first.text )
102
+ assert_equal( 3, branch_1.first.conditional_level )
103
+
104
+ # Branch 2
105
+ assert_equal( true, is_conditional_branch?(branch_2) )
106
+ assert_equal( 'f', branch_2.text )
107
+ assert_equal( 3, branch_2.conditional_level )
108
+
109
+ # Literal
110
+ assert_equal( 'f', branch_2.first.text )
111
+ assert_equal( 3, branch_2.first.conditional_level )
112
+ end
113
+
114
+ end