Class: XMP2Assert::XMP2Rexp

Inherits:
Object
  • Object
show all
Defined in:
lib/xmp2assert/xmp2rexp.rb

Overview

An XMP comment normally looks like this:

Object.new   # => #<Object:0x007f896c9b49c8>

Here, the hexadecimal number 0x007f896c9b49c8 is the raw pointer address of this evaluated object. When we check sanity of this XMP, that part would never match because pointer addresses are kind of arbitrary.

To reroute the problem, here we convert a XMP comment into a regular expression. The idea behind this is the diff process hook implemented in https://github.com/ruby/chkbuild

Class Method Summary collapse

Class Method Details

.xmp2rexp(xmp) ⇒ Regexp

Generates a regular expression that roughly matches the input.

Parameters:

  • xmp (String)

    example.

Returns:

  • (Regexp)

    converted regular expression.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/xmp2assert/xmp2rexp.rb', line 45

def self.xmp2rexp xmp
  # :NOTE: we are  editing regular expressions using  regular expressions. In
  # order  to hack  this method  you must  be a  seasoned regular  expression
  # craftsperson who can count backslashes at ease.
  nln = /\n*\z/.match(xmp).to_s.length
  src = Regexp.escape xmp.strip
  src.gsub!(/([^\\])(\\n|\\ )+/, '\\1\s+')
  src.gsub!(/(#<[\w:]+?:)0x[0-9a-f]+/, '\\10x[0-9a-f]+')
  src.gsub!(/\\u\\{([0-9a-f]{1,4})\\}/) {
    str = $1
    len = 4 - str.length
    pad = '0' * len
    next sprintf '\\u(?:%s%s|\\{%s\\})', pad, str.upcase, str
  }
  src.gsub!(/\\u([0-9A-F]{4})/) {
    str = $1
    hex = str.each_char.drop_while {|i| i == '0' }.join # :FIXME: slow?
    next sprintf '\\u(?:%s|\\{%s\\})', str, hex.downcase
  }
  src.gsub!(/\\\.rb:\d+/, '\\.rb:\d+')

  case nln when 0, 1 then
    return Regexp.new "\\A#{src}\\n?\\z"
  else
    return Regexp.new "\\A#{src}\\n{#{nln}}\\z"
  end
end