Create a gist now

Instantly share code, notes, and snippets.

%%{
machine parser;
action begin_domain {
@parts[:local] = data[address_begin..p-1]
@parts[:host] = process_host(data[p+1..-1])
}
action name {
@parts[:name] = data[0..p].strip.gsub('"', '')
}
action address_begin {
address_begin = p+1
}
action address_end {
@parts[:local], @parts[:host] = data[address_begin..p-1].split('@')
process_host(@parts[:host])
}
address_end = '>' $address_end;
address_begin = '<' $address_begin;
domain_separator = '@' $begin_domain;
name = [^<]+ & print+ $name;
main := (
(print+ . domain_separator)
| (name . address_begin . print+ . address_end)
);
}%%
def process_host(host)
host.gsub(' ','')
end
def parse(email)
address_begin = 0
@parts = {}
data = email
%%write data;
%%write init;
%%write exec;
@parts
end
require 'minitest/spec'
require 'minitest/autorun'
describe "mail parsing" do
it "can parse a basic email address" do
address = parse("ryan@example.com")
address[:local].must_equal "ryan"
address[:host].must_equal "example.com"
end
it "can parse a named address" do
address = parse("Ryan Bigg <ryan@example.com>")
address[:name].must_equal "Ryan Bigg"
address[:local].must_equal "ryan"
address[:host].must_equal "example.com"
end
# Stolen from Mail
it "should support |Minero Aoki<aamine@0246.loveruby.net>|" do
address = parse("Minero Aoki<aamine@0246.loveruby.net>")
address[:name].must_equal "Minero Aoki"
address[:local].must_equal "aamine"
address[:host].must_equal "0246.loveruby.net"
end
# Stolen from Mail
it "should support lots of dots" do
1.upto(10) do |times|
dots = "." * times
address = parse("hoge#{dots}test@docomo.ne.jp")
address[:local].must_equal "hoge#{dots}test"
address[:host].must_equal "docomo.ne.jp"
end
end
# Stolen from Mail
it "should handle trailing dots" do
1.upto(10) do |times|
dots = "." * times
address = parse("hoge#{dots}@docomo.ne.jp")
address[:local].must_equal "hoge#{dots}"
address[:host].must_equal "docomo.ne.jp"
end
end
# Stolen from Mail (which actually stole it from a Perl test suite)
it 'should handle "Joe & J. Harvey" <ddd @Org>' do
address = parse('"Joe & J. Harvey" <ddd @Org>')
address[:name].must_equal "Joe & J. Harvey"
address[:local].must_equal "ddd "
address[:host].must_equal "Org"
end
it "should handle jrh%cup.portal.com@portal.unix.portal.com" do
address = parse('jrh%cup.portal.com@portal.unix.portal.com')
address[:local].must_equal "jrh%cup.portal.com"
address[:host].must_equal "portal.unix.portal.com"
end
it "should handle David Apfelbaum <da0g+@andrew.cmu.edu>" do
address = parse("David Apfelbaum <da0g+@andrew.cmu.edu>'")
address[:name].must_equal "David Apfelbaum"
address[:local].must_equal "da0g+"
address[:host].must_equal "andrew.cmu.edu"
end
it "should handle Stephen Burke, Liverpool <BURKE@vxdsya.desy.de>" do
address = parse("Stephen Burke, Liverpool <BURKE@vxdsya.desy.de>")
address[:name].must_equal "Stephen Burke, Liverpool"
address[:local].must_equal "BURKE"
address[:host].must_equal "vxdsya.desy.de"
end
it "should handle jdoe@test . example" do
address = parse("jdoe@test . example")
address[:local].must_equal "jdoe"
address[:host].must_equal "test.example"
end
it "should handle /G=Owen/S=Smith/O=SJ-Research/ADMD=INTERSPAN/C=GB/@mhs-relay.ac.uk" do
address = parse("/G=Owen/S=Smith/O=SJ-Research/ADMD=INTERSPAN/C=GB/@mhs-relay.ac.uk")
address[:local].must_equal "/G=Owen/S=Smith/O=SJ-Research/ADMD=INTERSPAN/C=GB/"
address[:host].must_equal "mhs-relay.ac.uk"
end
it "should handle The Newcastle Info-Server <info-admin@newcastle.ac.uk>" do
address = parse("The Newcastle Info-Server <info-admin@newcastle.ac.uk>")
address[:name].must_equal "The Newcastle Info-Server"
address[:local].must_equal "info-admin"
address[:host].must_equal "newcastle.ac.uk"
end
it "should handle JAMES R. TWINE - THE NERD <TWINE57%SDELVB%SNYDELVA.bitnet@CUNYVM.CUNY.EDU>" do
address = parse(%Q{"JAMES R. TWINE - THE NERD" <TWINE57%SDELVB%SNYDELVA.bitnet@CUNYVM.CUNY.EDU>})
address[:name].must_equal "JAMES R. TWINE - THE NERD"
address[:local].must_equal "TWINE57%SDELVB%SNYDELVA.bitnet"
address[:host].must_equal "CUNYVM.CUNY.EDU"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment