3 -- Copyright (c) 2009 Mauro Iazzi
5 -- Permission is hereby granted, free of charge, to any person
6 -- obtaining a copy of this software and associated documentation
7 -- files (the "Software"), to deal in the Software without
8 -- restriction, including without limitation the rights to use,
9 -- copy, modify, merge, publish, distribute, sublicense, and/or sell
10 -- copies of the Software, and to permit persons to whom the
11 -- Software is furnished to do so, subject to the following
14 -- The above copyright notice and this permission notice shall be
15 -- included in all copies or substantial portions of the Software.
17 -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 -- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 -- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 -- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 -- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 -- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 -- OTHER DEALINGS IN THE SOFTWARE.
31 local gr
= dofile'mime.lua'
33 local match
= function (s
, r
, c
)
35 local ret
= { string = s
, rule
= r
, match
= true, capture
= c
}
40 { string = '\r\n ', rule
= 'FWS', match
= true, capture
= ' ' },
41 { string = '"rrr\r\n aaa"', rule
= lpeg
.Cs(lpeg
.V
'quoted-string'), match
= true, capture
= '"rrr aaa"'},
42 { string = '"rrr \\$\r\n aaa"', rule
= lpeg
.Cs(lpeg
.V
'quoted-string'), match
= true, capture
= '"rrr $ aaa"'},
43 { string = '(some stupid @(comment) \\( ** \r\n )', rule
='comment', match
= true, capture
= ' '},
44 { string = 'single_atom_1', rule
='atom', match
= true, capture
= 'single_atom_1'},
45 { string = '2nd{atom}2', rule
='atom', match
= true, capture
= '2nd{atom}2'},
46 { string = '2nd{atom}2.&checking!', rule
='dot-atom', match
= true, capture
= '2nd{atom}2.&checking!'},
47 { string = '\r\n (another comment ) \t\r\n (id %(crmnr) \\( ** \r\n ) ', rule
='CFWS', match
= true, capture
= ' '},
48 { string = '()', rule
='CFWS', match
= true, capture
= ' '},
49 { string = 'Icanwrite"a \r\n simple"phrase', rule
='phrase', match
= true, capture
='Icanwrite"a simple"phrase'},
50 { string = 'Thu, 2\r\n Apr 2009 14:36:04 +0000', rule
='date-time', match
= true, capture
={ 'Thu, 2 Apr 2009 14:36:04 +0000', weekday
='Thu', year
='2009', month
='Apr', day
='2', zone
='+0000', minute
='36', hour
='14', second
='04' }},
51 { string = '(a CFWS) \r\n (that ends here)[ 127.0.0.1:8888 \r\n oooo]', rule
='domain-literal', match
= true, capture
=' [ 127.0.0.1:8888 oooo]'},
52 { string = 'mauro.iazzi@gmail.com', rule
='addr-spec', match
= true, capture
={ [1]='mauro.iazzi@gmail.com', box
='mauro.iazzi', domain
='gmail.com' }, },
53 { string = 'mauro.iazzi@gmail.com', rule
='address', match
= true, capture
={ [1]='mauro.iazzi@gmail.com', box
='mauro.iazzi', domain
='gmail.com' }, },
54 { string = '"Mauro Iazzi" <"mauro\\2\r\n .iazzi"@gmail.com>', rule
='address', match
= true, capture
={ [1]='"Mauro Iazzi" <"mauro2.iazzi"@gmail.com>', box
='mauro.iazzi', domain
='gmail.com' }, },
55 { string = '"Mauro \r\n Iazzi" (a comment?) <mauro.iazzi@gmail.com>', rule
='address', match
= true, capture
={ [1]='"Mauro Iazzi" <mauro.iazzi@gmail.com>', box
='mauro.iazzi', domain
='gmail.com' }, },
56 { string = '<mauro.iazzi@gmail.com>', rule
='msg-id', match
= true, },
57 { string = '<"sent\\ by\\ \\"M.I.\\"mauro.iazzi"@[from\\ domain\\ gmail.com]>', rule
='msg-id', match
= true, },
60 local dee
= function (...)
65 local gather
= function (...)
66 local n
= select('#', ...)
67 return n
==1 and ... or { ... }
70 local function equal (a
, b
)
72 if a
==b
then return true end
73 if type(a
)~=type(b
) then return false end
74 if type(a
)=='table' then
75 for k
, v
in pairs(a
) do
76 if not equal(v
, b
[k
]) then return false end
78 for k
, v
in pairs(b
) do
79 if not equal(v
, a
[k
]) then return false end
86 local do_test
= function (i
, t
)
87 local s
, r
, m
, c
= t
.string, t
.rule
, t
.match
, t
.capture
89 if type(r
)=='string' then
92 gr
[1] = r
/ gather
* lpeg
.Cp()
93 local patt
= lpeg
.P(gr
)
94 local ret
, n
= dee(patt
:match(s
))
96 assert(ret
, 'test '..i
..' failed by not matching a conforming string')
97 assert(n
==#s
+1, 'test '..i
..' failed by not matching the full string (match was '..string.sub(s
, 1, n
-1)..')')
99 assert(equal(ret
, c
), 'test '..i
..' failed by returning the wrong capture '..tostring(ret
)..' instead of '..tostring(c
))
102 assert(ret
==nil, 'test '..i
..' failed by matching a wrong string')
105 print("starting the tests ...")
106 for i
, t
in ipairs(tests
) do
107 io
.write('performing test ' .. i
.. ' on rule ' .. tostring(t
.rule
))
109 local st
, err
= pcall(do_test
, i
, t
)
110 if st
then err
= 'success' end