regexp-examples 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,49 +1,18 @@
1
1
  module RegexpExamples
2
- class CaptureGroupResult < String
3
- attr_reader :group_id, :subgroups
4
- def initialize(group_id, subgroups, values)
5
- @group_id = group_id
6
- @subgroups = subgroups
7
- super(values)
8
- end
9
-
10
- def all_subgroups
11
- [self, subgroups].flatten
12
- end
13
-
14
- # Overridden in order to preserve the @group_id and @subgroups
15
- def *(int)
16
- self.class.new(group_id, subgroups, super)
17
- end
18
- # Overridden in order to preserve the @group_id and @subgroups
19
- def gsub(regex)
20
- self.class.new(group_id, subgroups, super)
21
- end
22
- end
23
-
24
2
  class BackReferenceReplacer
25
3
  def substitute_backreferences(full_examples)
26
- full_examples.map! do |full_example|
27
- if full_example.is_a? String
28
- [full_example]
29
- else
30
- full_example.map! do |partial_example|
31
- partial_example.gsub(/__(\w+)__/) do |match|
32
- find_backref_for(full_example, $1)
33
- end
34
- end
4
+ full_examples.map do |full_example|
5
+ while full_example.match(/__(\w+?)__/)
6
+ full_example.sub!(/__(\w+?)__/, find_backref_for(full_example, $1))
35
7
  end
8
+ full_example
36
9
  end
37
- full_examples
38
10
  end
39
11
 
40
12
  private
41
13
  def find_backref_for(full_example, group_id)
42
- full_example.each do |partial_example|
43
- next unless partial_example.respond_to?(:group_id)
44
- partial_example.all_subgroups.each do |subgroup|
45
- return subgroup if subgroup.group_id == group_id
46
- end
14
+ full_example.all_subgroups.detect do |subgroup|
15
+ subgroup.group_id == group_id
47
16
  end
48
17
  end
49
18
 
@@ -0,0 +1,5 @@
1
+ module RegexpExamples
2
+ class Error < StandardError; end
3
+ class UnsupportedSyntaxError < Error; end
4
+ class IllegalSyntaxError < Error; end
5
+ end
@@ -1,10 +1,35 @@
1
1
  module RegexpExamples
2
+ # All Group#result methods return an array of GroupResult objects
3
+ # The key objective here is to keep track of all capture groups, in order
4
+ # to fill in backreferences
5
+ class GroupResult < String
6
+ attr_reader :group_id, :subgroups
7
+ def initialize(result, group_id = nil, subgroups = [])
8
+ @group_id = group_id
9
+ @subgroups = subgroups
10
+ if result.respond_to?(:group_id)
11
+ @subgroups = result.all_subgroups
12
+ end
13
+ super(result)
14
+ end
15
+
16
+ def all_subgroups
17
+ [self, subgroups].flatten.reject { |subgroup| subgroup.group_id.nil? }
18
+ end
19
+
20
+ # Overridden in order to preserve the @group_id and @subgroups
21
+ # Used by BaseGroup (which, in turn, is used by all Group objects)
22
+ def *(int)
23
+ self.class.new(super.to_s, group_id, subgroups)
24
+ end
25
+ end
26
+
2
27
  class SingleCharGroup
3
28
  def initialize(char)
4
29
  @char = char
5
30
  end
6
31
  def result
7
- [@char]
32
+ [GroupResult.new(@char)]
8
33
  end
9
34
  end
10
35
 
@@ -52,17 +77,17 @@ module RegexpExamples
52
77
  end
53
78
 
54
79
  def result
55
- if @negative
56
- CharSets::Any - @chars
57
- else
58
- @chars
80
+ (@negative ? (CharSets::Any - @chars) : @chars).map do |result|
81
+ GroupResult.new(result)
59
82
  end
60
83
  end
61
84
  end
62
85
 
63
86
  class DotGroup
64
87
  def result
65
- CharSets::Any
88
+ CharSets::Any.map do |result|
89
+ GroupResult.new(result)
90
+ end
66
91
  end
67
92
  end
68
93
 
@@ -79,8 +104,7 @@ module RegexpExamples
79
104
  def result
80
105
  strings = @groups.map {|repeater| repeater.result}
81
106
  RegexpExamples::permutations_of_strings(strings).map do |result|
82
- subgroups = result.respond_to?(:group_id) ? result.all_subgroups : []
83
- group_id ? CaptureGroupResult.new(group_id, subgroups, result) : result
107
+ GroupResult.new(result, group_id)
84
108
  end
85
109
  end
86
110
  end
@@ -101,7 +125,9 @@ module RegexpExamples
101
125
  right_result = @right_repeaters.map do |repeater|
102
126
  RegexpExamples::permutations_of_strings([repeater.result])
103
127
  end
104
- left_result.concat(right_result).flatten.uniq
128
+ left_result.concat(right_result).flatten.uniq.map do |result|
129
+ GroupResult.new(result)
130
+ end
105
131
  end
106
132
  end
107
133
 
@@ -112,7 +138,7 @@ module RegexpExamples
112
138
  end
113
139
 
114
140
  def result
115
- ["__#{@id}__"]
141
+ [ GroupResult.new("__#{@id}__") ]
116
142
  end
117
143
  end
118
144
 
@@ -11,26 +11,16 @@ module RegexpExamples
11
11
  first = arrays_of_strings.shift
12
12
  return first if arrays_of_strings.empty?
13
13
  first.product( permutations_of_strings(arrays_of_strings, options) ).map do |result|
14
- if options[:no_join]
15
- result.flatten
16
- else
17
- join_preserving_capture_groups(result)
18
- end
14
+ join_preserving_capture_groups(result)
19
15
  end
20
16
  end
21
17
 
22
18
  def self.join_preserving_capture_groups(result)
23
19
  result.flatten!
24
20
  subgroups = result
25
- .select { |partial| partial.respond_to? :group_id }
26
21
  .map(&:all_subgroups)
27
22
  .flatten
28
-
29
- if subgroups.empty?
30
- result.join
31
- else
32
- CaptureGroupResult.new(nil, subgroups, result.join)
33
- end
23
+ GroupResult.new(result.join, nil, subgroups)
34
24
  end
35
25
  end
36
26
 
@@ -92,9 +92,9 @@ module RegexpExamples
92
92
  @current_position += 2
93
93
  group_id = nil
94
94
  when %w(! =).include?(match[2]) # e.g. /(?=lookahead)/, /(?!neglookahead)/
95
- # TODO: Raise exception
95
+ raise IllegalSyntaxError, "Lookaheads are not regular; cannot generate examples"
96
96
  when %w(! =).include?(match[3]) # e.g. /(?<=lookbehind)/, /(?<!neglookbehind)/
97
- # TODO: Raise exception
97
+ raise IllegalSyntaxError, "Lookbehinds are not regular; cannot generate examples"
98
98
  else # e.g. /(?<name>namedgroup)/
99
99
  @current_position += (match[3].length + 3)
100
100
  group_id = match[3]
@@ -3,12 +3,10 @@ class Regexp
3
3
  def examples
4
4
  partial_examples =
5
5
  RegexpExamples::Parser.new(source)
6
- .parse
7
- .map {|repeater| repeater.result}
8
- full_examples = RegexpExamples::permutations_of_strings(partial_examples.dup, no_join: true)
9
- full_examples_with_backrefs = \
10
- RegexpExamples::BackReferenceReplacer.new.substitute_backreferences(full_examples)
11
- full_examples_with_backrefs.map(&:join)
6
+ .parse
7
+ .map {|repeater| repeater.result}
8
+ full_examples = RegexpExamples::permutations_of_strings(partial_examples)
9
+ RegexpExamples::BackReferenceReplacer.new.substitute_backreferences(full_examples)
12
10
  end
13
11
  end
14
12
  include Examples
@@ -1,3 +1,3 @@
1
1
  module RegexpExamples
2
- VERSION = '0.2.1'
2
+ VERSION = '0.2.2'
3
3
  end
@@ -18,4 +18,5 @@ Gem::Specification.new do |s|
18
18
  s.add_development_dependency "bundler", "~> 1.7"
19
19
  s.add_development_dependency "rake", "~> 10.0"
20
20
  s.license = 'MIT'
21
+ s.required_ruby_version = '>= 1.9.2'
21
22
  end
@@ -13,6 +13,14 @@ RSpec.describe Regexp, "#examples" do
13
13
  end
14
14
  end
15
15
 
16
+ def self.examples_raise_illegal_syntax_error(*regexps)
17
+ regexps.each do |regexp|
18
+ it do
19
+ expect{regexp.examples}.to raise_error RegexpExamples::IllegalSyntaxError
20
+ end
21
+ end
22
+ end
23
+
16
24
  context 'returns matching strings' do
17
25
  context "for basic repeaters" do
18
26
  examples_exist_and_match(
@@ -59,12 +67,6 @@ RSpec.describe Regexp, "#examples" do
59
67
  /(?<name>namedgroup)/,
60
68
  /(?<name>namedgroup) \k<name>/
61
69
  )
62
- # TODO: These are not yet implemented
63
- # (expect to raise exception)
64
- # /(?=lookahead)/,
65
- # /(?!neglookahead)/,
66
- # /(?<=lookbehind)/,
67
- # /(?<!neglookbehind)/,
68
70
  end
69
71
 
70
72
  context "for escaped characters" do
@@ -109,5 +111,14 @@ RSpec.describe Regexp, "#examples" do
109
111
  /a+|b*|c?/
110
112
  )
111
113
  end
114
+
115
+ context "for illegal syntax" do
116
+ examples_raise_illegal_syntax_error(
117
+ /(?=lookahead)/,
118
+ /(?!neglookahead)/,
119
+ /(?<=lookbehind)/,
120
+ /(?<!neglookbehind)/
121
+ )
122
+ end
112
123
  end
113
124
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: regexp-examples
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Lord
@@ -82,6 +82,7 @@ files:
82
82
  - lib/regexp-examples.rb
83
83
  - lib/regexp-examples/backreferences.rb
84
84
  - lib/regexp-examples/constants.rb
85
+ - lib/regexp-examples/exceptions.rb
85
86
  - lib/regexp-examples/groups.rb
86
87
  - lib/regexp-examples/helpers.rb
87
88
  - lib/regexp-examples/parser.rb
@@ -103,7 +104,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
103
104
  requirements:
104
105
  - - ">="
105
106
  - !ruby/object:Gem::Version
106
- version: '0'
107
+ version: 1.9.2
107
108
  required_rubygems_version: !ruby/object:Gem::Requirement
108
109
  requirements:
109
110
  - - ">="
@@ -111,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
112
  version: '0'
112
113
  requirements: []
113
114
  rubyforge_project:
114
- rubygems_version: 2.2.2
115
+ rubygems_version: 2.4.5
115
116
  signing_key:
116
117
  specification_version: 4
117
118
  summary: Extends the Regexp class with '#examples'