"""
    Matching tests for Include macro

    This module tests the matching ability of the Include regular expression  
    The following URL contains what should be valid examples:
    
    http://purl.net/wiki/moinmaster/HelpOnMacros/Include

"""

"""
  The test set is a list of dictionarys, where each dictionary contains:
   The test string ('test', 'test-string'),
   The name string ('name', 'name-string'),
  and these optional values: 
   heading, hquote, htext, level, fquote, from, tquote, to, sort, items,
   skipitems, titlesonly
  The items correspond to the named fields in the regular expression
"""

test_sets = [  
dict([('test','FooBar'), ('name','FooBar')]), 
dict([('test','FooBar, '), ('name','FooBar'), ('heading',',')]),
dict([('test','FooBar, , 2'), ('name','FooBar'), ('heading', ','), 
      ('level','2')]), 
dict([('test',"FooBar, 'All about Foo Bar', 2"), ('name','FooBar'), 
      ('heading',','), ('hquote',"'"), ('htext',"All about Foo Bar"),
      ('level','2')]),
dict([('test','FooBar, , from="^----$"'), ('name','FooBar'),
      ('heading',','), ('fquote', '"'), ('from','^----$')]),
dict([('test','FooBar, , to="^----$"'), ('name','FooBar'),
      ('heading',','), ('tquote','"'), ('to','^----$')]),
dict([('test','^FooBar/.*, , sort=descending'), ('name','^FooBar/.*'),
      ('heading',','), ('sort','descending')]), 
dict([('test','^FooBar/.*, , items=3'), ('name','^FooBar/.*'),
      ('heading',','), ('items','3')]),      
dict([('test','^BlogBase/.*,, to="^----$", sort=descending, items=7'),
      ('name','^BlogBase/.*'), ('heading',','), ('tquote','"'),
      ('to','^----$'), ('sort','descending'), ('items','7')]),
dict([('test','^BlogBase/.*,, to="^----$", sort=descending, items=7, skipitems=7,titlesonly'),
      ('name','^BlogBase/.*'), ('heading',','), ('tquote','"'),
      ('to','^----$'), ('sort','descending'), ('items','7'),
      ('skipitems','7'),('titlesonly','titlesonly')]),
dict([('test','^FirstnameLastname/20..-..-..,,to="^----",sort=descending,items=3'),
      ('name','^FirstnameLastname/20..-..-..'), ('heading',','), 
      ('tquote','"'),('to','^----'),('sort','descending'),('items','3')]),
dict([('test','^FirstnameLastname/20..-..-..,,to="^----",sort=descending,items=4,skipitems=3,titlesonly'),
      ('name','^FirstnameLastname/20..-..-..'), ('heading',','), 
      ('tquote','"'),('to','^----'),('sort','descending'),('items','4'),
      ('skipitems','3'),('titlesonly','titlesonly')]),
dict([('test', 'TitleTest, "Heading for Title Test 1",1,to="^----$"'),  ('name', 'TitleTest'),
      ('heading',','), ('hquote', '"'), ('htext', 'Heading for Title Test 1'),
      ('level','1'),('to', '^----$')]),
dict([('test', 'TitleTest, "Heading for Title Test 2", ,to="^----$"'),  ('name', 'TitleTest'),
      ('heading',','), ('hquote', '"'), ('htext', 'Heading for Title Test 2'),
      ('to', '^----$')])
]

import re

_arg_heading = r'(?P<heading>,)\s*(|(?P<hquote>[\'"])(?P<htext>.+?)(?P=hquote))'
OLD_arg_level = r',\s*(?P<level>\d+)'
_arg_level = r',\s*(?P<level>\d+)?'
_arg_from = r'(,\s*from=(?P<fquote>[\'"])(?P<from>.+?)(?P=fquote))?'
_arg_to = r'(,\s*to=(?P<tquote>[\'"])(?P<to>.+?)(?P=tquote))?'
_arg_sort = r'(,\s*sort=(?P<sort>(ascending|descending)))?'
_arg_items = r'(,\s*items=(?P<items>\d+))?'
_arg_skipitems = r'(,\s*skipitems=(?P<skipitems>\d+))?'
_arg_titlesonly = r'(,\s*(?P<titlesonly>titlesonly))?'
_args_re_pattern_OLD = r'^(?P<name>[^,]+)(%s(%s)?%s%s%s%s%s%s)?$' % (
    _arg_heading, OLD_arg_level, _arg_from, _arg_to, _arg_sort, _arg_items,
    _arg_skipitems, _arg_titlesonly)
_args_re_pattern = r'^(?P<name>[^,]+)(%s(%s)?%s%s%s%s%s%s)?$' % (
    _arg_heading, _arg_level, _arg_from, _arg_to, _arg_sort, _arg_items,
    _arg_skipitems, _arg_titlesonly)

def test_import_re(pattern=_args_re_pattern):
  args_re=re.compile(pattern)
  test_num=0
  number_failed=0 
  for test_set in test_sets:
    test_failed=0
    test_str = test_set['test']
    test_num=test_num+1
    print "Test", test_num, ":", test_str
    
    args = args_re.match(test_str)
    if not args:
      print "  FAIL: failed to match on test string"
      test_failed=1
    else:      
      for k, v in test_set.iteritems():
        if k != 'test' and k != 'hquote':
          re_res = args.group(k)
          if not re_res:
            print "  FAIL: failed to match on key '", k, "'"
            test_failed=1
          elif v != re_res:
            print "  FAIL: On key '", k, "', value was '", re_res, "', expected '", v, "'."
            test_failed=1
    number_failed += test_failed
  
  if number_failed == 0:
    print "All tests passed!"
  else:
    print str(number_failed), "out of", str(test_num), "tests failed."

print "*** ORIGINAL CODE ***"
test_import_re(_args_re_pattern_OLD)

print
print "*** CHANGED CODE ***"
test_import_re()
