diff --git a/coverage/.last_run.json b/coverage/.last_run.json
index 3ceb5d8..3cb5e70 100644
--- a/coverage/.last_run.json
+++ b/coverage/.last_run.json
@@ -1 +1,5 @@
-{"result":{"covered_percent":99.66}}
+{
+ "result": {
+ "covered_percent": 100.0
+ }
+}
diff --git a/coverage/.resultset.json b/coverage/.resultset.json
index aaefc5b..7e0c8c6 100644
--- a/coverage/.resultset.json
+++ b/coverage/.resultset.json
@@ -1 +1,668 @@
-{"RSpec":{"coverage":{"/home/tom/git/regexp-examples/lib/regexp-examples.rb":[9,null],"/home/tom/git/regexp-examples/lib/regexp-examples/version.rb":[1,1,null],"/home/tom/git/regexp-examples/lib/regexp-examples/helpers.rb":[1,null,null,null,null,null,null,null,null,1,271,271,164,237,null,null,null,1,237,237,null,null,237,null,null,null],"/home/tom/git/regexp-examples/lib/regexp-examples/repeaters.rb":[1,1,1,1,271,null,null,1,271,271,271,299,413,null,null,271,null,null,null,1,1,247,null,null,1,247,null,null,null,1,1,5,null,null,1,5,null,null,null,1,1,4,null,null,1,4,null,null,null,1,1,11,null,null,1,11,null,null,null,1,1,4,4,4,1,3,1,null,2,null,null,null,1,4,null,null,null,null],"/home/tom/git/regexp-examples/lib/regexp-examples/backreferences.rb":[1,1,1,1,1633,1633,1633,122,null,1633,null,null,1,1667,null,null,null,1,413,null,null,1,0,null,null,null,1,1,54,148,28,null,148,null,null,null,1,1,28,76,null,null,null,null,null,null],"/home/tom/git/regexp-examples/lib/regexp-examples/constants.rb":[1,null,1,null,null,null,null,null,1,null,1,1,1,1,null,null,39,1,1,null,null,null,1,null,null,null,32,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"/home/tom/git/regexp-examples/lib/regexp-examples/parser.rb":[1,1,1,1,54,54,54,null,null,1,101,101,312,312,271,271,271,null,101,null,null,1,null,1,312,312,null,41,null,41,null,14,null,1,null,6,null,38,null,171,null,312,null,null,1,38,null,null,19,19,null,1,1,null,14,null,null,null,null,4,null,38,38,null,null,1,271,271,null,5,null,4,null,11,null,4,null,247,null,271,null,null,1,41,41,41,41,null,null,38,null,1,1,null,null,null,null,null,2,2,41,null,41,41,null,null,1,41,null,null,1,14,14,14,null,null,1,1,null,null,14,null,null,null,null,41,41,null,14,null,null,1,1,null,null,1,6,6,6,null,null,null,1,175,null,null,1,20,null,null,1,5,5,null,null,1,4,4,null,null,1,11,11,null,null,1,4,4,4,4,4,4,null,null,1,247,null,null,1,102,null,null,null,null],"/home/tom/git/regexp-examples/lib/regexp-examples/groups.rb":[1,1,1,175,null,1,175,null,null,null,1,1,28,28,1,1,null,27,null,null,28,28,null,null,1,null,28,28,28,28,null,28,9,null,null,28,28,null,null,1,28,540,13,4,null,2,null,7,null,null,null,null,null,1,28,572,null,null,null,null,1,1,1,94,null,null,null,null,1,1,1,41,41,null,null,null,null,null,1,186,41,101,null,null,null,null,1,null,null,1,1,6,6,null,null,1,6,6,null,6,6,null,6,21,null,null,null,null,1,1,1,20,null,null,1,20,null,null,null,null],"/home/tom/git/regexp-examples/lib/regexp-examples/regexp_extensions.rb":[1,1,1,54,null,null,114,54,54,null,null,1,null,null],"/home/tom/git/regexp-examples/spec/regexp-examples_spec.rb":[1,1,7,54,54,54,202,null,null,null,null,null,null,null,null,1,1,null,1,null,null,null,null,null,null,null,null,null,1,null,1,null,null,null,null,null,null,1,null,1,null,null,null,null,null,null,null,null,null,null,null,null,null,null,1,null,1,null,null,null,null,null,null,null,null,null,null,null,null,1,null,1,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,1,null,1,null,null,null,null,null,null,null,null,1,null,null,1,null,null,null,null,null,null,null,null,null,null]},"timestamp":1421273505}}
+{
+ "RSpec": {
+ "coverage": {
+ "/home/tom/regexp-examples/lib/regexp-examples.rb": [
+ 10,
+ null
+ ],
+ "/home/tom/regexp-examples/lib/regexp-examples/exceptions.rb": [
+ 1,
+ 1,
+ 1,
+ 1,
+ null
+ ],
+ "/home/tom/regexp-examples/lib/regexp-examples/helpers.rb": [
+ 1,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 271,
+ 271,
+ 164,
+ 237,
+ null,
+ null,
+ null,
+ 1,
+ 237,
+ 237,
+ null,
+ null,
+ 237,
+ null,
+ null,
+ null
+ ],
+ "/home/tom/regexp-examples/lib/regexp-examples/parser.rb": [
+ 1,
+ 1,
+ 1,
+ 1,
+ 58,
+ 58,
+ 58,
+ null,
+ null,
+ 1,
+ 105,
+ 105,
+ 316,
+ 312,
+ 271,
+ 271,
+ 271,
+ null,
+ 101,
+ null,
+ null,
+ 1,
+ null,
+ 1,
+ 316,
+ 316,
+ null,
+ 45,
+ null,
+ 41,
+ null,
+ 14,
+ null,
+ 1,
+ null,
+ 6,
+ null,
+ 36,
+ null,
+ 173,
+ null,
+ 312,
+ null,
+ null,
+ 1,
+ 36,
+ null,
+ null,
+ 19,
+ 19,
+ null,
+ 1,
+ 1,
+ null,
+ 14,
+ null,
+ null,
+ null,
+ null,
+ 2,
+ null,
+ 36,
+ 36,
+ null,
+ null,
+ 1,
+ 271,
+ 271,
+ null,
+ 5,
+ null,
+ 4,
+ null,
+ 11,
+ null,
+ 4,
+ null,
+ 247,
+ null,
+ 271,
+ null,
+ null,
+ 1,
+ 45,
+ 45,
+ 45,
+ 45,
+ null,
+ null,
+ 38,
+ null,
+ 1,
+ 1,
+ null,
+ 2,
+ null,
+ 2,
+ null,
+ 2,
+ 2,
+ 45,
+ null,
+ 41,
+ 41,
+ null,
+ null,
+ 1,
+ 41,
+ null,
+ null,
+ 1,
+ 14,
+ 14,
+ 14,
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ null,
+ 14,
+ null,
+ null,
+ null,
+ null,
+ 41,
+ 41,
+ null,
+ 14,
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ null,
+ 1,
+ 6,
+ 6,
+ 6,
+ null,
+ null,
+ null,
+ 1,
+ 175,
+ null,
+ null,
+ 1,
+ 20,
+ null,
+ null,
+ 1,
+ 5,
+ 5,
+ null,
+ null,
+ 1,
+ 4,
+ 4,
+ null,
+ null,
+ 1,
+ 11,
+ 11,
+ null,
+ null,
+ 1,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ null,
+ null,
+ 1,
+ 247,
+ null,
+ null,
+ 1,
+ 102,
+ null,
+ null,
+ null,
+ null
+ ],
+ "/home/tom/regexp-examples/lib/regexp-examples/constants.rb": [
+ 1,
+ null,
+ 1,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ null,
+ 1,
+ 1,
+ 1,
+ 1,
+ null,
+ null,
+ 39,
+ 1,
+ 1,
+ null,
+ null,
+ null,
+ 1,
+ null,
+ null,
+ null,
+ 32,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null
+ ],
+ "/home/tom/regexp-examples/lib/regexp-examples/backreferences.rb": [
+ 1,
+ 1,
+ 1,
+ 54,
+ 148,
+ 28,
+ null,
+ 148,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 28,
+ 76,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null
+ ],
+ "/home/tom/regexp-examples/lib/regexp-examples/repeaters.rb": [
+ 1,
+ 1,
+ 1,
+ 1,
+ 271,
+ null,
+ null,
+ 1,
+ 271,
+ 271,
+ 271,
+ 299,
+ 413,
+ null,
+ null,
+ 271,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 247,
+ null,
+ null,
+ 1,
+ 247,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 5,
+ null,
+ null,
+ 1,
+ 5,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 4,
+ null,
+ null,
+ 1,
+ 4,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 11,
+ null,
+ null,
+ 1,
+ 11,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 4,
+ 4,
+ 4,
+ 1,
+ 3,
+ 1,
+ null,
+ 2,
+ null,
+ null,
+ null,
+ 1,
+ 4,
+ null,
+ null,
+ null,
+ null
+ ],
+ "/home/tom/regexp-examples/lib/regexp-examples/groups.rb": [
+ 1,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 1,
+ 1633,
+ 1633,
+ 1633,
+ 122,
+ null,
+ 1633,
+ null,
+ null,
+ 1,
+ 1667,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 413,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 175,
+ null,
+ 1,
+ 175,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 28,
+ 28,
+ 1,
+ 1,
+ null,
+ 27,
+ null,
+ null,
+ 28,
+ 28,
+ null,
+ null,
+ 1,
+ null,
+ 28,
+ 28,
+ 28,
+ 28,
+ null,
+ 28,
+ 9,
+ null,
+ null,
+ 28,
+ 28,
+ null,
+ null,
+ 1,
+ 28,
+ 540,
+ 13,
+ 4,
+ null,
+ 2,
+ null,
+ 7,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 28,
+ 572,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 1,
+ 94,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 1,
+ 41,
+ 41,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 186,
+ 41,
+ 101,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ null,
+ null,
+ 1,
+ 1,
+ 6,
+ 6,
+ null,
+ null,
+ 1,
+ 6,
+ 6,
+ null,
+ 6,
+ 6,
+ null,
+ 6,
+ 21,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 1,
+ 20,
+ null,
+ null,
+ 1,
+ 20,
+ null,
+ null,
+ null,
+ null
+ ],
+ "/home/tom/regexp-examples/lib/regexp-examples/regexp_extensions.rb": [
+ 1,
+ 1,
+ 1,
+ 58,
+ null,
+ null,
+ 114,
+ 54,
+ 54,
+ null,
+ null,
+ 1,
+ null,
+ null
+ ],
+ "/home/tom/regexp-examples/spec/regexp-examples_spec.rb": [
+ 1,
+ 1,
+ 7,
+ 54,
+ 54,
+ 54,
+ 202,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 4,
+ 8,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ 1,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ null,
+ 1,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null
+ ]
+ },
+ "timestamp": 1421316594
+ }
+}
diff --git a/coverage/coverage-badge.png b/coverage/coverage-badge.png
index df1fc15..8b8d023 100644
Binary files a/coverage/coverage-badge.png and b/coverage/coverage-badge.png differ
diff --git a/coverage/index.html b/coverage/index.html
index 2dc30ee..1aa2480 100644
--- a/coverage/index.html
+++ b/coverage/index.html
@@ -14,27 +14,27 @@
-
Generated
2015-01-14T22:11:45+00:00
+
Generated
2015-01-15T10:09:55+00:00
All Files
- (99.66%
+ (100.0%
covered at
- 77.21
+ 75.39
hits/line)
10 files in total.
- 290 relevant lines.
- 289 lines covered and
- 1 lines missed
+ 298 relevant lines.
+ 298 lines covered and
+ 0 lines missed
@@ -51,27 +51,27 @@
- lib/regexp-examples.rb |
+ lib/regexp-examples.rb |
100.0 % |
2 |
1 |
1 |
0 |
- 9.0 |
+ 10.0 |
- lib/regexp-examples/backreferences.rb |
- 96.0 % |
- 46 |
- 25 |
- 24 |
- 1 |
- 369.1 |
+ lib/regexp-examples/backreferences.rb |
+ 100.0 % |
+ 21 |
+ 11 |
+ 11 |
+ 0 |
+ 44.3 |
- lib/regexp-examples/constants.rb |
+ lib/regexp-examples/constants.rb |
100.0 % |
42 |
12 |
@@ -81,17 +81,27 @@
- lib/regexp-examples/groups.rb |
+ lib/regexp-examples/exceptions.rb |
+ 100.0 % |
+ 5 |
+ 4 |
+ 4 |
+ 0 |
+ 1.0 |
+
+
+
+ lib/regexp-examples/groups.rb |
100.0 % |
- 120 |
- 65 |
- 65 |
+ 145 |
+ 77 |
+ 77 |
0 |
- 38.8 |
+ 146.2 |
- lib/regexp-examples/helpers.rb |
+ lib/regexp-examples/helpers.rb |
100.0 % |
26 |
10 |
@@ -101,27 +111,27 @@
- lib/regexp-examples/parser.rb |
+ lib/regexp-examples/parser.rb |
100.0 % |
184 |
- 102 |
- 102 |
+ 104 |
+ 104 |
0 |
- 54.7 |
+ 54.2 |
- lib/regexp-examples/regexp_extensions.rb |
+ lib/regexp-examples/regexp_extensions.rb |
100.0 % |
14 |
8 |
8 |
0 |
- 35.0 |
+ 35.5 |
- lib/regexp-examples/repeaters.rb |
+ lib/regexp-examples/repeaters.rb |
100.0 % |
78 |
43 |
@@ -131,23 +141,13 @@
- lib/regexp-examples/version.rb |
- 100.0 % |
- 3 |
- 2 |
- 2 |
- 0 |
- 1.0 |
-
-
-
- spec/regexp-examples_spec.rb |
+ spec/regexp-examples_spec.rb |
100.0 % |
- 113 |
- 22 |
- 22 |
+ 124 |
+ 28 |
+ 28 |
0 |
- 17.6 |
+ 14.4 |
@@ -166,7 +166,7 @@
-
+
-
+
@@ -219,268 +219,118 @@
96.0 % covered
1
- class GroupResult < String
-
-
-
- 1
-
- attr_reader :group_id, :subgroups
-
-
-
- 1
-
- def initialize(result, group_id = nil, subgroups = [])
-
-
-
- 1633
-
- @group_id = group_id
-
-
-
- 1633
-
- @subgroups = subgroups
-
-
-
- 1633
-
- if result.respond_to?(:group_id)
-
-
-
- 122
-
- @subgroups = result.all_subgroups
-
-
-
-
-
- end
-
-
-
- 1633
-
- super(result)
-
-
-
-
-
- end
-
-
-
-
-
-
-
-
-
- 1
-
- def all_subgroups
-
-
-
- 1667
-
- [self, subgroups].flatten.reject { |subgroup| subgroup.group_id.nil? }
-
-
-
-
-
- end
-
-
-
-
-
-
-
-
-
-
-
- # Overridden in order to preserve the @group_id and @subgroups
-
-
-
- 1
-
- def *(int)
-
-
-
- 413
-
- self.class.new(super.to_s, group_id, subgroups)
-
-
-
-
-
- end
-
-
-
-
-
- # Overridden in order to preserve the @group_id and @subgroups
-
-
-
- 1
-
- def gsub(regex)
-
-
-
-
-
- self.class.new(super.to_s, group_id, subgroups)
-
-
-
-
-
- end
-
-
-
-
-
- end
-
-
-
-
-
-
-
-
-
- 1
-
class BackReferenceReplacer
-
+
1
def substitute_backreferences(full_examples)
-
+
54
full_examples.map do |full_example|
-
+
148
while full_example.match(/__(\w+?)__/)
-
+
28
full_example.sub!(/__(\w+?)__/, find_backref_for(full_example, $1))
-
+
end
-
+
148
full_example
-
+
end
-
+
end
-
+
-
+
1
private
-
+
1
def find_backref_for(full_example, group_id)
-
+
28
full_example.all_subgroups.detect do |subgroup|
-
+
76
subgroup.group_id == group_id
-
+
end
-
+
end
-
+
-
+
end
-
+
-
+
end
@@ -490,7 +340,7 @@ 96.0 % covered
-
+
-
+
@@ -783,712 +633,910 @@
100.0 % covered
1
- class SingleCharGroup
+ class Error < StandardError; end
1
- def initialize(char)
+ class UnsupportedSyntaxError < Error; end
-
- 175
+
+ 1
- @char = char
+ class IllegalSyntaxError < Error; end
- end
+ end
-
+
+
+
+
+
+
+
+
+
+
+ -
1
-
def result
+ module RegexpExamples
- -
- 175
+
-
-
[GroupResult.new(@char)]
+
+ # All Group#result methods return an array of GroupResult objects
- -
+
-
-
end
+ # The key objective here is to keep track of all capture groups, in order
- -
+
-
-
end
+ # to fill in backreferences
- -
-
+
-
+ 1
-
+ class GroupResult < String
- -
+
-
1
-
class CharGroup
+ attr_reader :group_id, :subgroups
- -
+
-
1
-
def initialize(chars)
+ def initialize(result, group_id = nil, subgroups = [])
- -
- 28
+
-
+ 1633
-
@chars = chars
+ @group_id = group_id
- -
- 28
+
-
+ 1633
-
if chars[0] == "^"
+ @subgroups = subgroups
- -
- 1
+
-
+ 1633
-
@negative = true
+ if result.respond_to?(:group_id)
- -
- 1
+
-
+ 122
+
+
@subgroups = result.all_subgroups
+
+
+ -
+
+
+
end
+
+
+ -
+ 1633
+
+
super(result)
+
+
+ -
+
+
+
end
+
+
+ -
+
+
+
+
+
+ -
+ 1
+
+
def all_subgroups
+
+
+ -
+ 1667
+
+
[self, subgroups].flatten.reject { |subgroup| subgroup.group_id.nil? }
+
+
+ -
+
+
+
end
+
+
+ -
+
+
+
+
+
+ -
+
+
+
# Overridden in order to preserve the @group_id and @subgroups
+
+
+ -
+
+
+
# Used by BaseGroup (which, in turn, is used by all Group objects)
+
+
+ -
+ 1
+
+
def *(int)
+
+
+ -
+ 413
+
+
self.class.new(super.to_s, group_id, subgroups)
+
+
+ -
+
+
+
end
+
+
+ -
+
+
+
end
+
+
+ -
+
+
+
+
+
+ -
+ 1
+
+
class SingleCharGroup
+
+
+ -
+ 1
+
+
def initialize(char)
+
+
+ -
+ 175
+
+
@char = char
+
+
+ -
+
+
+
end
+
+
+ -
+ 1
+
+
def result
+
+
+ -
+ 175
+
+
[GroupResult.new(@char)]
+
+
+ -
+
+
+
end
+
+
+ -
+
+
+
end
+
+
+ -
+
+
+
+
+
+ -
+ 1
+
+
class CharGroup
+
+
+ -
+ 1
+
+
def initialize(chars)
+
+
+ -
+ 28
+
+
@chars = chars
+
+
+ -
+ 28
+
+
if chars[0] == "^"
+
+
+ -
+ 1
+
+
@negative = true
+
+
+ -
+ 1
@chars = @chars[1..-1]
- -
+
-
else
- -
+
-
27
@negative = false
- -
+
-
end
- -
+
-
- -
+
-
28
init_backslash_chars
- -
+
-
28
init_ranges
- -
+
-
end
- -
+
-
- -
+
-
1
def init_ranges
- -
+
-
# save first and last "-" if present
- -
+
-
28
first = nil
- -
+
-
28
last = nil
- -
+
-
28
first = @chars.shift if @chars.first == "-"
- -
+
-
28
last = @chars.pop if @chars.last == "-"
- -
+
-
# Replace all instances of e.g. ["a" "-" "z"] with ["a", "b", ..., "z"]
- -
+
-
28
while i = @chars.index("-")
- -
+
-
9
@chars[i-1..i+1] = (@chars[i-1]..@chars[i+1]).to_a
- -
+
-
end
- -
+
-
# restore them back
- -
+
-
28
@chars.unshift(first) if first
- -
+
-
28
@chars.push(last) if last
- -
+
-
end
- -
+
-
- -
+
-
1
def init_backslash_chars
- -
+
-
28
@chars.each_with_index do |char, i|
- -
+
-
540
if char == "\\"
- -
+
-
13
if BackslashCharMap.keys.include?(@chars[i+1])
- -
+
-
4
@chars[i..i+1] = BackslashCharMap[@chars[i+1]]
- -
+
-
elsif @chars[i+1] == "\\"
- -
+
-
2
@chars.delete_at(i+1)
- -
+
-
else
- -
+
-
7
@chars.delete_at(i)
- -
+
-
end
- -
+
-
end
- -
+
-
end
- -
+
-
end
- -
+
-
- -
+
-
1
def result
- -
+
-
28
(@negative ? (CharSets::Any - @chars) : @chars).map do |result|
- -
+
-
572
GroupResult.new(result)
- -
+
-
end
- -
+
-
end
- -
+
-
end
- -
+
-
- -
+
-
1
class DotGroup
- -
+
-
1
def result
- -
+
-
1
CharSets::Any.map do |result|
- -
+
-
94
GroupResult.new(result)
- -
+
-
end
- -
+
-
end
- -
+
-
end
- -
+
-
- -
+
-
1
class MultiGroup
- -
+
-
1
attr_reader :group_id
- -
+
-
1
def initialize(groups, group_id)
- -
+
-
41
@groups = groups
- -
+
-
41
@group_id = group_id
- -
+
-
end
- -
+
-
- -
+
-
# Generates the result of each contained group
- -
+
-
# and adds the filled group of each result to
- -
+
-
# itself
- -
+
-
1
def result
- -
+
-
186
strings = @groups.map {|repeater| repeater.result}
- -
+
-
41
RegexpExamples::permutations_of_strings(strings).map do |result|
- -
+
-
101
GroupResult.new(result, group_id)
- -
+
-
end
- -
+
-
end
- -
+
-
end
- -
+
-
- -
+
-
1
class MultiGroupEnd
- -
+
-
end
- -
+
-
- -
+
-
1
class OrGroup
- -
+
-
1
def initialize(left_repeaters, right_repeaters)
- -
+
-
6
@left_repeaters = left_repeaters
- -
+
-
6
@right_repeaters = right_repeaters
- -
+
-
end
- -
+
-
- -
+
-
1
def result
- -
+
-
6
left_result = @left_repeaters.map do |repeater|
- -
+
-
6
RegexpExamples::permutations_of_strings([repeater.result])
- -
+
-
end
- -
+
-
6
right_result = @right_repeaters.map do |repeater|
- -
+
-
6
RegexpExamples::permutations_of_strings([repeater.result])
- -
+
-
end
- -
+
-
6
left_result.concat(right_result).flatten.uniq.map do |result|
- -
+
-
21
GroupResult.new(result)
- -
+
-
end
- -
+
-
end
- -
+
-
end
- -
+
-
- -
+
-
1
class BackReferenceGroup
- -
+
-
1
attr_reader :id
- -
+
-
1
def initialize(id)
- -
+
-
20
@id = id
- -
+
-
end
- -
+
-
- -
+
-
1
def result
- -
+
-
20
[ GroupResult.new("__#{@id}__") ]
- -
+
-
end
- -
+
-
end
- -
+
-
- -
+
-
end
@@ -1498,7 +1546,7 @@ 100.0 % covered
-
+
-
+
@@ -1710,20 +1758,20 @@
100.0 % covered
def initialize(regexp_string)
-
- 54
+
+ 58
@regexp_string = regexp_string
-
- 54
+
+ 58
@num_groups = 0
-
- 54
+
+ 58
@current_position = 0
@@ -1746,20 +1794,20 @@ 100.0 % covered
def parse
-
- 101
+
+ 105
repeaters = []
-
- 101
+
+ 105
while @current_position < regexp_string.length
-
- 312
+
+ 316
group = parse_group(repeaters)
@@ -1830,14 +1878,14 @@ 100.0 % covered
def parse_group(repeaters)
-
- 312
+
+ 316
char = regexp_string[@current_position]
-
- 312
+
+ 316
case char
@@ -1845,11 +1893,11 @@ 100.0 % covered
- when '('
+ when '('
-
- 41
+
+ 45
group = parse_multi_group
@@ -1857,7 +1905,7 @@ 100.0 % covered
- when ')'
+ when ')'
@@ -1869,7 +1917,7 @@ 100.0 % covered
- when '['
+ when '['
@@ -1881,7 +1929,7 @@ 100.0 % covered
- when '.'
+ when '.'
@@ -1893,7 +1941,7 @@ 100.0 % covered
- when '|'
+ when '|'
@@ -1905,11 +1953,11 @@ 100.0 % covered
- when '\\'
+ when '\\'
-
- 38
+
+ 36
group = parse_after_backslash_group
@@ -1920,8 +1968,8 @@ 100.0 % covered
else
-
- 171
+
+ 173
group = parse_single_char_group(char)
@@ -1956,8 +2004,8 @@ 100.0 % covered
def parse_after_backslash_group
-
- 38
+
+ 36
@current_position += 1
@@ -2040,8 +2088,8 @@ 100.0 % covered
else
-
- 4
+
+ 2
group = parse_single_char_group( regexp_string[@current_position] )
@@ -2052,14 +2100,14 @@ 100.0 % covered
# TODO: What about cases like \A, \z, \Z ?
-
- 38
+
+ 36
end
-
- 38
+
+ 36
group
@@ -2097,7 +2145,7 @@ 100.0 % covered
- when '*'
+ when '*'
@@ -2109,7 +2157,7 @@ 100.0 % covered
- when '+'
+ when '+'
@@ -2121,7 +2169,7 @@ 100.0 % covered
- when '?'
+ when '?'
@@ -2133,7 +2181,7 @@ 100.0 % covered
- when '{'
+ when '{'
@@ -2184,26 +2232,26 @@ 100.0 % covered
def parse_multi_group
-
- 41
+
+ 45
@current_position += 1
-
- 41
+
+ 45
@num_groups += 1
-
- 41
+
+ 45
group_id = nil # init
-
- 41
+
+ 45
rest_of_string.match(/\A(\?)?(:|!|=|<(!|=|[^!=][^>]*))?/) do |match|
@@ -2229,7 +2277,7 @@ 100.0 % covered
- when match[2] == ':' # e.g. /(?:nocapture)/
+ when match[2] == ':' # e.g. /(?:nocapture)/
@@ -2250,10 +2298,10 @@ 100.0 % covered
when %w(! =).include?(match[2]) # e.g. /(?=lookahead)/, /(?!neglookahead)/
-
-
+
+ 2
- # TODO: Raise exception
+ raise IllegalSyntaxError, "Lookaheads are not regular; cannot generate examples"
@@ -2262,10 +2310,10 @@ 100.0 % covered
when %w(! =).include?(match[3]) # e.g. /(?<=lookbehind)/, /(?<!neglookbehind)/
-
-
+
+ 2
- # TODO: Raise exception
+ raise IllegalSyntaxError, "Lookbehinds are not regular; cannot generate examples"
@@ -2286,8 +2334,8 @@ 100.0 % covered
group_id = match[3]
-
- 41
+
+ 45
end
@@ -2367,7 +2415,7 @@ 100.0 % covered
14
- if regexp_string[@current_position] == ']'
+ if regexp_string[@current_position] == ']'
@@ -2385,7 +2433,7 @@ 100.0 % covered
1
- chars << ']'
+ chars << ']'
@@ -2403,7 +2451,7 @@ 100.0 % covered
- until regexp_string[@current_position] == ']' \
+ until regexp_string[@current_position] == ']' \
@@ -2794,7 +2842,7 @@ 100.0 % covered
-
+
-
+
-
-
-
-
-
-
- -
- 1
-
-
module RegexpExamples
-
-
- -
- 1
-
-
VERSION = '0.2.1'
-
-
- -
-
-
-
end
-
-
-
-
-
-
-
+
@@ -3483,7 +3495,7 @@
100.0 % covered
- # For example, we don't want things like:
+ # For example, we don't want things like:
@@ -3525,586 +3537,652 @@ 100.0 % covered
1
- context 'returns matching strings' do
+ def self.examples_raise_illegal_syntax_error(*regexps)
1
- context "for basic repeaters" do
+ regexps.each do |regexp|
-
+
+ 4
+ it do
+
+
+
+ 8
- examples_exist_and_match(
+ expect{regexp.examples}.to raise_error RegexpExamples::IllegalSyntaxError
-
+
+
+
+ end
+
+
+
+
+
+ end
+
+
+
+
+
+ end
+
+
+
+
+
+
+
+
+
1
+ context 'returns matching strings' do
+
+
+
+ 1
+
+ context "for basic repeaters" do
+
+
+
+ 1
+
+ examples_exist_and_match(
+
+
+
+
+
/a/,
-
+
/a*/,
-
+
/a+/,
-
+
/a?/,
-
+
/a{1}/,
-
+
/a{1,}/,
-
+
/a{1,2}/
-
+
)
-
+
end
-
+
-
+
1
context "for basic groups" do
-
-
+
+ 1
examples_exist_and_match(
-
- 1
+
+
/[a]/,
-
+
/(a)/,
-
+
/a|b/,
-
+
/./
-
+
)
-
+
end
-
+
-
+
1
context "for complex char groups (square brackets)" do
-
-
+
+ 1
examples_exist_and_match(
-
- 1
+
+
/[abc]/,
-
+
/[a-c]/,
-
+
/[abc-e]/,
-
+
/[^a-zA-Z]/,
-
+
/[\w]/,
-
+
/[]]/, # TODO: How to suppress annoying warnings on this test?
-
+
/[\]]/,
-
+
/[\\]/,
-
+
/[\\\]]/,
-
+
/[\n-\r]/,
-
+
/[\-]/,
-
+
/[%-+]/ # This regex is "supposed to" match some surprising things!!!
-
+
)
-
+
end
-
+
-
+
1
context "for complex multi groups" do
-
-
+
+ 1
examples_exist_and_match(
-
- 1
+
+
/(normal)/,
-
+
/(?:nocapture)/,
-
+
/(?<name>namedgroup)/,
-
+
/(?<name>namedgroup) \k<name>/
-
+
)
-
-
-
- # TODO: These are not yet implemented
-
-
-
-
-
- # (expect to raise exception)
-
-
-
-
-
- # /(?=lookahead)/,
-
-
-
-
-
- # /(?!neglookahead)/,
-
-
-
-
-
- # /(?<=lookbehind)/,
-
-
-
-
-
- # /(?<!neglookbehind)/,
-
-
-
+
end
-
+
-
+
1
context "for escaped characters" do
-
-
+
+ 1
examples_exist_and_match(
-
- 1
+
+
/\w/,
-
+
/\W/,
-
+
/\s/,
-
+
/\S/,
-
+
/\d/,
-
+
/\D/,
-
+
/\h/,
-
+
/\H/,
-
+
/\t/,
-
+
/\n/,
-
+
/\f/,
-
+
/\a/,
-
+
/\v/,
-
+
/\e/
-
+
)
-
+
end
-
+
-
+
1
context "for backreferences" do
-
-
+
+ 1
examples_exist_and_match(
-
- 1
+
+
/(repeat) \1/,
-
+
/(ref1) (ref2) \1 \2/,
-
+
/((ref2)ref1) \1 \2/,
-
+
/((ref1and2)) \1 \2/,
-
+
/(one)(two)(three)(four)(five)(six)(seven)(eight)(nine)(ten) \10\9\8\7\6\5\4\3\2\1/,
-
+
/(a?(b?(c?(d?(e?)))))/
-
+
)
-
+
end
-
+
-
+
1
context "for complex patterns" do
-
+
# Longer combinations of the above
-
-
+
+ 1
examples_exist_and_match(
-
- 1
+
+
/https?:\/\/(www\.)github\.com/,
-
+
/(I(N(C(E(P(T(I(O(N)))))))))*/,
-
+
/[\w]{1}/,
-
+
/((a?b*c+)) \1/,
-
+
/((a?b*c+)?) \1/,
-
+
/a|b|c|d/,
-
+
/a+|b*|c?/
-
+
)
-
+
end
-
+
+
+
+
+
+
+
+ 1
+
+ context "for illegal syntax" do
+
+
+
+ 1
+
+ examples_raise_illegal_syntax_error(
+
+
+
+
+
+ /(?=lookahead)/,
+
+
+
+
+
+ /(?!neglookahead)/,
+
+
+
+
+
+ /(?<=lookbehind)/,
+
+
+
+
+
+ /(?<!neglookbehind)/
+
+
+
+
+
+ )
+
+
+
+
+
+ end
+
+
+
end
-
+
end
diff --git a/lib/regexp-examples/exceptions.rb b/lib/regexp-examples/exceptions.rb
new file mode 100644
index 0000000..78c779e
--- /dev/null
+++ b/lib/regexp-examples/exceptions.rb
@@ -0,0 +1,5 @@
+module RegexpExamples
+ class Error < StandardError; end
+ class UnsupportedSyntaxError < Error; end
+ class IllegalSyntaxError < Error; end
+end
diff --git a/lib/regexp-examples/parser.rb b/lib/regexp-examples/parser.rb
index bd17a5c..5432faa 100644
--- a/lib/regexp-examples/parser.rb
+++ b/lib/regexp-examples/parser.rb
@@ -92,9 +92,9 @@ def parse_multi_group
@current_position += 2
group_id = nil
when %w(! =).include?(match[2]) # e.g. /(?=lookahead)/, /(?!neglookahead)/
- # TODO: Raise exception
+ raise IllegalSyntaxError, "Lookaheads are not regular; cannot generate examples"
when %w(! =).include?(match[3]) # e.g. /(?<=lookbehind)/, /(?namedgroup)/
@current_position += (match[3].length + 3)
group_id = match[3]
diff --git a/spec/regexp-examples_spec.rb b/spec/regexp-examples_spec.rb
index 9626f32..c68e889 100644
--- a/spec/regexp-examples_spec.rb
+++ b/spec/regexp-examples_spec.rb
@@ -13,6 +13,14 @@ def self.examples_exist_and_match(*regexps)
end
end
+ def self.examples_raise_illegal_syntax_error(*regexps)
+ regexps.each do |regexp|
+ it do
+ expect{regexp.examples}.to raise_error RegexpExamples::IllegalSyntaxError
+ end
+ end
+ end
+
context 'returns matching strings' do
context "for basic repeaters" do
examples_exist_and_match(
@@ -59,12 +67,6 @@ def self.examples_exist_and_match(*regexps)
/(?namedgroup)/,
/(?namedgroup) \k/
)
- # TODO: These are not yet implemented
- # (expect to raise exception)
-# /(?=lookahead)/,
-# /(?!neglookahead)/,
-# /(?<=lookbehind)/,
-# /(?