regexp-examples 0.2.1 → 0.2.2

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.
@@ -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'