js_regex 3.2.0 → 3.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 48540644a806114addad63fb0f3ff9ba7ad00a084b3b281b9132d2eddbe610ff
4
- data.tar.gz: 775fd5d3f54c8b3c32b145414707c0b69c5c783cbd5270d9bc8d5e1564a6fec7
3
+ metadata.gz: 8365bf02c61518e8db07367f1501e31ac8599f709b0cfb80847803d7aa4f17b1
4
+ data.tar.gz: f6840ad243194ad82ff589a9cd3f11c3db11b6f2a0f471b50dbb0b3510ebcc08
5
5
  SHA512:
6
- metadata.gz: 97810021249f6b512ebae5898f6ffe51ae95269f1e47909fb7b95fbe1e8aa6ba9696e4c7966bac27cbc7c1bd36668729aeb5d0ab4c243e85a88bb70fd6cbb203
7
- data.tar.gz: 5681e9d950c14f7260596b46a382a9829c0be4326bd898acbdcf5a257936c0f543018b5c7b1435582d8ba976a680d3b08ac0189e85d82b49e621e5f8918b93a9
6
+ metadata.gz: 163fdc6a6011088e22804a0bb2174d30c5c053afec187964aac9f6cfaf1dfecd93719a824971f6820b25c54e6ac521e2cd2ca7b5be13463ab7461fb1f1ac794d
7
+ data.tar.gz: f0f6efbf118747f79211caec3335b8b34f5f69b69c7d0c78db5b0edb77812a2663dba6bd78e0b074efe2b27d58542c504e18239f78d5b25d40942f21b1486e15
@@ -13,25 +13,27 @@ class JsRegex
13
13
  require_relative 'second_pass'
14
14
 
15
15
  class << self
16
- def of(ruby_regex, options: nil)
17
- source, warnings = convert_source(ruby_regex)
18
- options_string = convert_options(ruby_regex, options)
16
+ def of(input, options: nil)
17
+ source, warnings = convert_source(input)
18
+ options_string = convert_options(input, options)
19
19
  [source, options_string, warnings]
20
20
  end
21
21
 
22
22
  private
23
23
 
24
- def convert_source(ruby_regex)
25
- tree = Regexp::Parser.parse(ruby_regex)
24
+ def convert_source(input)
25
+ tree = Regexp::Parser.parse(input)
26
26
  context = Converter::Context.new(case_insensitive_root: tree.i?)
27
27
  converted_tree = Converter.convert(tree, context)
28
28
  final_tree = SecondPass.call(converted_tree)
29
29
  [final_tree.to_s, context.warnings]
30
30
  end
31
31
 
32
- def convert_options(ruby_regex, custom_options)
32
+ def convert_options(input, custom_options)
33
33
  options = custom_options.to_s.scan(/[gimuy]/)
34
- options << 'i' if (ruby_regex.options & Regexp::IGNORECASE).nonzero?
34
+ if input.is_a?(Regexp) && (input.options & Regexp::IGNORECASE).nonzero?
35
+ options << 'i'
36
+ end
35
37
  options.uniq.sort.join
36
38
  end
37
39
  end
@@ -32,18 +32,10 @@ class JsRegex
32
32
  MAP[expression.type].new
33
33
  end
34
34
 
35
- # Limit the number of generated surrogate pairs, else the output might
36
- # get to large for certain applications. The chosen number is somewhat
37
- # arbitrary. 100 pairs make for about 1 KB, uncompressed. The median char
38
- # count of all properties supported by Ruby is 92. 75% are below 300 chars.
39
- #
40
- # Set this to nil if you need full unicode matches and size doesn't matter.
41
- attr_writer :surrogate_pair_limit
42
-
43
- def in_surrogate_pair_limit?(&pair_count)
44
- @surrogate_pair_limit.nil? || @surrogate_pair_limit >= pair_count.call
35
+ # Legacy method. Remove in v4.0.0.
36
+ def surrogate_pair_limit=(_arg)
37
+ warn '#surrogate_pair_limit= is deprecated and has no effect anymore.'
45
38
  end
46
39
  end
47
- self.surrogate_pair_limit = 300
48
40
  end
49
41
  end
@@ -23,9 +23,8 @@ class JsRegex
23
23
  end
24
24
 
25
25
  def pass_boundary_with_warning(boundary)
26
- warn("The boundary '#{boundary}' at index #{expression.ts} "\
27
- 'is not unicode-aware in JavaScript, '\
28
- 'so it might act differently than in Ruby.')
26
+ warn_of("The anchor '#{boundary}' at index #{expression.ts} "\
27
+ 'only works at ASCII word boundaries in JavaScript.')
29
28
  boundary
30
29
  end
31
30
  end
@@ -54,11 +54,11 @@ class JsRegex
54
54
  def warn_of_unsupported_feature(description = nil)
55
55
  description ||= "#{subtype} #{expression.type}".tr('_', ' ')
56
56
  full_desc = "#{description} '#{expression}'"
57
- warn("Dropped unsupported #{full_desc} at index #{expression.ts}")
57
+ warn_of("Dropped unsupported #{full_desc} at index #{expression.ts}")
58
58
  drop
59
59
  end
60
60
 
61
- def warn(text)
61
+ def warn_of(text)
62
62
  context.warnings << text
63
63
  end
64
64
 
@@ -44,7 +44,7 @@ class JsRegex
44
44
  when :control, :meta_sequence
45
45
  unicode_escape_codepoint
46
46
  when :literal
47
- LiteralConverter.convert_data(data)
47
+ LiteralConverter.convert_data(expression.char)
48
48
  when *ESCAPES_SHARED_BY_RUBY_AND_JS
49
49
  pass_through
50
50
  when :bell, :escape
@@ -34,9 +34,6 @@ class JsRegex
34
34
  end
35
35
 
36
36
  def build_options_group
37
- unless (encoding_options = data.scan(/[adu]/)).empty?
38
- warn_of_unsupported_feature("encoding options #{encoding_options}")
39
- end
40
37
  if subtype.equal?(:options_switch)
41
38
  # can be ignored since #options on subsequent Expressions are correct
42
39
  drop_without_warning
@@ -13,40 +13,30 @@ class JsRegex
13
13
 
14
14
  def convert_data(data)
15
15
  if data =~ ASTRAL_PLANE_CODEPOINT_PATTERN
16
- data.each_char.each_with_object(Node.new) do |chr, node|
17
- if chr =~ ASTRAL_PLANE_CODEPOINT_PATTERN
18
- node << surrogate_pair_for(chr)
19
- else
20
- node << convert_bmp_data(chr)
21
- end
22
- end
16
+ convert_astral_data(data)
23
17
  else
24
- convert_bmp_data(data)
18
+ escape_incompatible_bmp_literals(data)
25
19
  end
26
20
  end
27
21
 
28
- def convert_bmp_data(data)
29
- ensure_json_compatibility(
30
- ensure_forward_slashes_are_escaped(data)
31
- )
22
+ def convert_astral_data(data)
23
+ data.each_char.each_with_object(Node.new) do |char, node|
24
+ if char =~ ASTRAL_PLANE_CODEPOINT_PATTERN
25
+ node << surrogate_substitution_for(char)
26
+ else
27
+ node << escape_incompatible_bmp_literals(char)
28
+ end
29
+ end
32
30
  end
33
31
 
34
- private
35
-
36
- def surrogate_pair_for(astral_char)
37
- base = astral_char.codepoints.first - 65_536
38
- high = ((base / 1024).floor + 55_296).to_s(16)
39
- low = (base % 1024 + 56_320).to_s(16)
40
- "(?:\\u#{high}\\u#{low})"
32
+ def escape_incompatible_bmp_literals(data)
33
+ data.gsub('/', '\\/').gsub(/[\f\n\r\t]/) { |lit| Regexp.escape(lit) }
41
34
  end
42
35
 
43
- def ensure_forward_slashes_are_escaped(data)
44
- # literal slashes would signify the pattern end in JsRegex#to_s
45
- data.gsub(%r{\\?/}, '\\/')
46
- end
36
+ private
47
37
 
48
- def ensure_json_compatibility(data)
49
- data.gsub(%r{\\?([\f\n\r\t])}) { Regexp.escape($1) }
38
+ def surrogate_substitution_for(char)
39
+ CharacterSet::Writer.write_surrogate_ranges([], [char.codepoints])
50
40
  end
51
41
  end
52
42
 
@@ -8,6 +8,9 @@ class JsRegex
8
8
  # Template class implementation.
9
9
  #
10
10
  class MetaConverter < JsRegex::Converter::Base
11
+ DOT_EXPANSION = '(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\n\uD800-\uDFFF])'
12
+ ML_DOT_EXPANSION = '(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF])'
13
+
11
14
  private
12
15
 
13
16
  def convert_data
@@ -15,22 +18,27 @@ class JsRegex
15
18
  when :alternation
16
19
  convert_alternatives
17
20
  when :dot
18
- expression.multiline? ? '(?:.|\n)' : '.'
21
+ expression.multiline? ? ML_DOT_EXPANSION : DOT_EXPANSION
19
22
  else
20
23
  warn_of_unsupported_feature
21
24
  end
22
25
  end
23
26
 
24
27
  def convert_alternatives
25
- kept_any = nil
28
+ kept_any_previous_branch = nil
26
29
 
27
30
  convert_subexpressions.transform do |node|
28
- dropped = !node.children.empty? && node.children.all?(&:dropped?)
29
- node.children.unshift('|') if kept_any && !dropped
30
- kept_any = true unless dropped
31
+ unless dropped_branch?(node)
32
+ node.children.unshift('|') if kept_any_previous_branch
33
+ kept_any_previous_branch = true
34
+ end
31
35
  node
32
36
  end
33
37
  end
38
+
39
+ def dropped_branch?(branch_node)
40
+ branch_node.children.any? && branch_node.children.all?(&:dropped?)
41
+ end
34
42
  end
35
43
  end
36
44
  end
@@ -15,25 +15,15 @@ class JsRegex
15
15
  private
16
16
 
17
17
  def convert_data
18
- content = CharacterSet.of_property(subtype)
18
+ content = CharacterSet.of_expression(expression)
19
+
19
20
  if expression.case_insensitive? && !context.case_insensitive_root
20
21
  content = content.case_insensitive
22
+ elsif !expression.case_insensitive? && context.case_insensitive_root
23
+ warn_of_unsupported_feature('nested case-sensitive property')
21
24
  end
22
25
 
23
- if expression.negative?
24
- if content.astral_part?
25
- warn_of_unsupported_feature('astral plane negation by property')
26
- end
27
- elsif Converter.in_surrogate_pair_limit? { content.astral_part.size }
28
- return content.to_s_with_surrogate_alternation
29
- else
30
- warn_of_unsupported_feature('large astral plane match of property')
31
- end
32
-
33
- bmp_part = content.bmp_part
34
- return drop if bmp_part.empty?
35
-
36
- "[#{'^' if expression.negative?}#{bmp_part}]"
26
+ content.to_s_with_surrogate_ranges
37
27
  end
38
28
  end
39
29
  end
@@ -19,10 +19,7 @@ class JsRegex
19
19
  private
20
20
 
21
21
  def convert_data
22
- if directly_compatible?
23
- return expression.to_s(:base)
24
- .gsub(%r{\\?([\f\n\r\t])}) { Regexp.escape($1) }
25
- end
22
+ return pass_through_with_escaping if directly_compatible?
26
23
 
27
24
  content = CharacterSet.of_expression(expression)
28
25
  if expression.case_insensitive? && !context.case_insensitive_root
@@ -31,38 +28,42 @@ class JsRegex
31
28
  warn_of_unsupported_feature('nested case-sensitive set')
32
29
  end
33
30
 
34
- if Converter.in_surrogate_pair_limit? { content.astral_part.size }
35
- content.to_s_with_surrogate_alternation
36
- else
37
- warn_of_unsupported_feature('large astral plane match of set')
38
- bmp_part = content.bmp_part
39
- bmp_part.empty? ? drop : bmp_part.to_s(in_brackets: true)
40
- end
31
+ content.to_s_with_surrogate_ranges
41
32
  end
42
33
 
43
34
  def directly_compatible?
44
- if expression.case_insensitive? ^ context.case_insensitive_root
45
- # casefolding needed
46
- return
47
- end
35
+ all_children_directly_compatible? && !casefolding_needed?
36
+ end
48
37
 
49
- # check for children needing conversion (#each_expression is recursive)
38
+ def all_children_directly_compatible?
39
+ # note that #each_expression is recursive
50
40
  expression.each_expression do |exp|
51
- case exp.type
52
- when :literal
53
- # surrogate pair substitution needed if astral
54
- next if exp.text.ord <= 0xFFFF
55
- when :set
56
- # conversion needed for nested sets, intersections
57
- next if exp.token.equal?(:range)
58
- when :type
59
- next if TypeConverter::TYPES_SHARED_BY_RUBY_AND_JS.include?(exp.token)
60
- when :escape
61
- next if EscapeConverter::ESCAPES_SHARED_BY_RUBY_AND_JS.include?(exp.token)
62
- end
63
- return
41
+ return unless child_directly_compatible?(exp)
64
42
  end
65
- true
43
+ end
44
+
45
+ def child_directly_compatible?(exp)
46
+ case exp.type
47
+ when :literal
48
+ # surrogate pair substitution needed if astral
49
+ exp.text.ord <= 0xFFFF
50
+ when :set
51
+ # conversion needed for nested sets, intersections
52
+ exp.token.equal?(:range)
53
+ when :type
54
+ TypeConverter.directly_compatible?(exp)
55
+ when :escape
56
+ EscapeConverter::ESCAPES_SHARED_BY_RUBY_AND_JS.include?(exp.token)
57
+ end
58
+ end
59
+
60
+ def casefolding_needed?
61
+ expression.case_insensitive? ^ context.case_insensitive_root
62
+ end
63
+
64
+ def pass_through_with_escaping
65
+ string = expression.to_s(:base)
66
+ LiteralConverter.escape_incompatible_bmp_literals(string)
66
67
  end
67
68
  end
68
69
  end
@@ -8,19 +8,19 @@ class JsRegex
8
8
  # Template class implementation.
9
9
  #
10
10
  class TypeConverter < JsRegex::Converter::Base
11
- TYPES_SHARED_BY_RUBY_AND_JS = %i[
12
- digit
13
- nondigit
14
- word
15
- nonword
16
- space
17
- nonspace
18
- ].freeze
19
-
20
11
  HEX_EXPANSION = '[0-9A-Fa-f]'
21
12
  NONHEX_EXPANSION = '[^0-9A-Fa-f]'
22
13
  LINEBREAK_EXPANSION = '(?:\r\n|[\n\v\f\r\u0085\u2028\u2029])'
23
14
 
15
+ def self.directly_compatible?(expression)
16
+ case expression.token
17
+ when :space, :nonspace
18
+ !expression.ascii_classes?
19
+ when :digit, :nondigit, :word, :nonword
20
+ !expression.unicode_classes?
21
+ end
22
+ end
23
+
24
24
  private
25
25
 
26
26
  def convert_data
@@ -28,12 +28,30 @@ class JsRegex
28
28
  when :hex then HEX_EXPANSION
29
29
  when :nonhex then NONHEX_EXPANSION
30
30
  when :linebreak then LINEBREAK_EXPANSION
31
- when *TYPES_SHARED_BY_RUBY_AND_JS
32
- pass_through
31
+ when :digit, :space, :word
32
+ return pass_through if self.class.directly_compatible?(expression)
33
+ set_substitution
34
+ when :nondigit, :nonspace, :nonword
35
+ return pass_through if self.class.directly_compatible?(expression)
36
+ negative_set_substitution
33
37
  else
34
38
  warn_of_unsupported_feature
35
39
  end
36
40
  end
41
+
42
+ def negative_set_substitution
43
+ # ::of_expression returns an inverted set for negative expressions,
44
+ # so we need to un-invert before wrapping in [^ and ]. Kinda lame.
45
+ "[^#{character_set.inversion.bmp_part}]"
46
+ end
47
+
48
+ def set_substitution
49
+ character_set.bmp_part.to_s(in_brackets: true)
50
+ end
51
+
52
+ def character_set
53
+ CharacterSet.of_expression(expression)
54
+ end
37
55
  end
38
56
  end
39
57
  end
@@ -25,32 +25,16 @@ class JsRegex
25
25
  end
26
26
 
27
27
  def conditional_tree_permutations(tree)
28
- all_conditions = conditions(tree)
29
- return [] if all_conditions.empty?
28
+ all_conds = conditions(tree)
29
+ return [] if all_conds.empty?
30
30
 
31
- captured_groups_per_branch = captured_group_count(tree)
31
+ caps_per_branch = captured_group_count(tree)
32
32
 
33
- condition_permutations(all_conditions).map.with_index do |truthy_conds, i|
33
+ condition_permutations(all_conds).map.with_index do |truthy_conds, i|
34
34
  tree_permutation = tree.clone
35
35
  # find referenced groups and conditionals and make one-sided
36
36
  crawl(tree_permutation) do |node|
37
- truthy = truthy_conds.include?(node.reference)
38
-
39
- if node.type.equal?(:captured_group) &&
40
- all_conditions.include?(node.reference)
41
- truthy ? min_quantify(node) : null_quantify(node)
42
- elsif node.type.equal?(:conditional)
43
- branches = node.children[1...-1]
44
- if branches.count == 1
45
- truthy || null_quantify(branches.first)
46
- else
47
- null_quantify(truthy ? branches.last : branches.first)
48
- end
49
- node.update(type: :plain)
50
- elsif node.type.equal?(:backref_num)
51
- new_num = node.children[0].to_i + captured_groups_per_branch * i
52
- node.update(children: [new_num.to_s])
53
- end
37
+ build_permutation(node, all_conds, truthy_conds, caps_per_branch, i)
54
38
  end
55
39
  end
56
40
  end
@@ -81,8 +65,40 @@ class JsRegex
81
65
  end
82
66
  end
83
67
 
68
+ def build_permutation(node, all_conds, truthy_conds, caps_per_branch, i)
69
+ truthy = truthy_conds.include?(node.reference)
70
+
71
+ if node.type.equal?(:captured_group) &&
72
+ all_conds.include?(node.reference)
73
+ adapt_referenced_group_to_permutation(node, truthy)
74
+ elsif node.type.equal?(:conditional)
75
+ adapt_conditional_to_permutation(node, truthy)
76
+ elsif node.type.equal?(:backref_num)
77
+ adapt_backref_to_permutation(node, caps_per_branch, i)
78
+ end
79
+ end
80
+
81
+ def adapt_referenced_group_to_permutation(group_node, truthy)
82
+ truthy ? min_quantify(group_node) : null_quantify(group_node)
83
+ end
84
+
85
+ def adapt_conditional_to_permutation(conditional_node, truthy)
86
+ branches = conditional_node.children[1...-1]
87
+ if branches.count == 1
88
+ truthy || null_quantify(branches.first)
89
+ else
90
+ null_quantify(truthy ? branches.last : branches.first)
91
+ end
92
+ conditional_node.update(type: :plain)
93
+ end
94
+
95
+ def adapt_backref_to_permutation(backref_node, caps_per_branch, i)
96
+ new_num = backref_node.children[0].to_i + caps_per_branch * i
97
+ backref_node.update(children: [new_num.to_s])
98
+ end
99
+
84
100
  def min_quantify(node)
85
- return if (qtf = node.quantifier).nil? || qtf.min > 0
101
+ return if guarantees_at_least_one_match?(qtf = node.quantifier)
86
102
 
87
103
  if qtf.max.equal?(1) # any zero_or_one quantifier (?, ??, ?+)
88
104
  node.update(quantifier: nil)
@@ -91,6 +107,10 @@ class JsRegex
91
107
  end
92
108
  end
93
109
 
110
+ def guarantees_at_least_one_match?(quantifier)
111
+ quantifier.nil? || quantifier.min > 0
112
+ end
113
+
94
114
  def null_quantify(node)
95
115
  node.update(quantifier: '{0}')
96
116
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class JsRegex
4
- VERSION = '3.2.0'
4
+ VERSION = '3.6.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: js_regex
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janosch Müller
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-18 00:00:00.000000000 Z
11
+ date: 2020-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: character_set
@@ -16,126 +16,98 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.2'
19
+ version: '1.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.2'
26
+ version: '1.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: regexp_parser
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.5'
33
+ version: '2.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.5'
40
+ version: '2.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: regexp_property_values
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.3'
47
+ version: '1.0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.3'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '12.3'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '12.3'
54
+ version: '1.0'
69
55
  - !ruby/object:Gem::Dependency
70
- name: rspec-core
56
+ name: mini_racer
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
59
  - - "~>"
74
60
  - !ruby/object:Gem::Version
75
- version: '3.8'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '3.8'
83
- - !ruby/object:Gem::Dependency
84
- name: rspec-expectations
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '3.8'
61
+ version: '0.3'
90
62
  type: :development
91
63
  prerelease: false
92
64
  version_requirements: !ruby/object:Gem::Requirement
93
65
  requirements:
94
66
  - - "~>"
95
67
  - !ruby/object:Gem::Version
96
- version: '3.8'
68
+ version: '0.3'
97
69
  - !ruby/object:Gem::Dependency
98
- name: rspec-mocks
70
+ name: rake
99
71
  requirement: !ruby/object:Gem::Requirement
100
72
  requirements:
101
73
  - - "~>"
102
74
  - !ruby/object:Gem::Version
103
- version: '3.8'
75
+ version: '13.0'
104
76
  type: :development
105
77
  prerelease: false
106
78
  version_requirements: !ruby/object:Gem::Requirement
107
79
  requirements:
108
80
  - - "~>"
109
81
  - !ruby/object:Gem::Version
110
- version: '3.8'
82
+ version: '13.0'
111
83
  - !ruby/object:Gem::Dependency
112
- name: therubyracer
84
+ name: rspec
113
85
  requirement: !ruby/object:Gem::Requirement
114
86
  requirements:
115
87
  - - "~>"
116
88
  - !ruby/object:Gem::Version
117
- version: '0.12'
89
+ version: '3.10'
118
90
  type: :development
119
91
  prerelease: false
120
92
  version_requirements: !ruby/object:Gem::Requirement
121
93
  requirements:
122
94
  - - "~>"
123
95
  - !ruby/object:Gem::Version
124
- version: '0.12'
96
+ version: '3.10'
125
97
  - !ruby/object:Gem::Dependency
126
- name: mutant-rspec
98
+ name: codecov
127
99
  requirement: !ruby/object:Gem::Requirement
128
100
  requirements:
129
101
  - - "~>"
130
102
  - !ruby/object:Gem::Version
131
- version: '0.8'
103
+ version: 0.2.12
132
104
  type: :development
133
105
  prerelease: false
134
106
  version_requirements: !ruby/object:Gem::Requirement
135
107
  requirements:
136
108
  - - "~>"
137
109
  - !ruby/object:Gem::Version
138
- version: '0.8'
110
+ version: 0.2.12
139
111
  description: JsRegex converts Ruby's native regular expressions for JavaScript, taking
140
112
  care of various incompatibilities and returning warnings for unsolvable differences.
141
113
  email:
@@ -170,7 +142,7 @@ homepage: https://github.com/jaynetics/js_regex
170
142
  licenses:
171
143
  - MIT
172
144
  metadata: {}
173
- post_install_message:
145
+ post_install_message:
174
146
  rdoc_options: []
175
147
  require_paths:
176
148
  - lib
@@ -185,8 +157,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
157
  - !ruby/object:Gem::Version
186
158
  version: '0'
187
159
  requirements: []
188
- rubygems_version: 3.0.3
189
- signing_key:
160
+ rubygems_version: 3.1.2
161
+ signing_key:
190
162
  specification_version: 4
191
163
  summary: Converts Ruby regexes to JavaScript regexes.
192
164
  test_files: []