Grammalecte  Hex Artifact Content

Artifact 3d6c560ee1d7b8e7002bd4e7020e7e290fd5919b8884cde07e13c8a303a05fd8:


0000: 23 21 20 70 79 74 68 6f 6e 33 0a 0a 22 22 22 0a  #! python3..""".
0010: 47 72 61 6d 6d 61 72 20 63 68 65 63 6b 65 72 20  Grammar checker 
0020: 74 65 73 74 73 20 66 6f 72 20 46 72 65 6e 63 68  tests for French
0030: 20 6c 61 6e 67 75 61 67 65 0a 22 22 22 0a 0a 69   language."""..i
0040: 6d 70 6f 72 74 20 75 6e 69 74 74 65 73 74 0a 69  mport unittest.i
0050: 6d 70 6f 72 74 20 6f 73 0a 69 6d 70 6f 72 74 20  mport os.import 
0060: 72 65 0a 69 6d 70 6f 72 74 20 74 69 6d 65 0a 66  re.import time.f
0070: 72 6f 6d 20 63 6f 6e 74 65 78 74 6c 69 62 20 69  rom contextlib i
0080: 6d 70 6f 72 74 20 63 6f 6e 74 65 78 74 6d 61 6e  mport contextman
0090: 61 67 65 72 0a 0a 66 72 6f 6d 20 2e 2e 67 72 61  ager..from ..gra
00a0: 70 68 73 70 65 6c 6c 2e 69 62 64 61 77 67 20 69  phspell.ibdawg i
00b0: 6d 70 6f 72 74 20 49 42 44 41 57 47 0a 66 72 6f  mport IBDAWG.fro
00c0: 6d 20 2e 2e 67 72 61 70 68 73 70 65 6c 6c 2e 65  m ..graphspell.e
00d0: 63 68 6f 20 69 6d 70 6f 72 74 20 65 63 68 6f 0a  cho import echo.
00e0: 66 72 6f 6d 20 2e 20 69 6d 70 6f 72 74 20 67 63  from . import gc
00f0: 5f 65 6e 67 69 6e 65 20 61 73 20 67 63 65 0a 66  _engine as gce.f
0100: 72 6f 6d 20 2e 20 69 6d 70 6f 72 74 20 63 6f 6e  rom . import con
0110: 6a 0a 66 72 6f 6d 20 2e 20 69 6d 70 6f 72 74 20  j.from . import 
0120: 70 68 6f 6e 65 74 0a 66 72 6f 6d 20 2e 20 69 6d  phonet.from . im
0130: 70 6f 72 74 20 6d 66 73 70 0a 0a 0a 40 63 6f 6e  port mfsp...@con
0140: 74 65 78 74 6d 61 6e 61 67 65 72 0a 64 65 66 20  textmanager.def 
0150: 74 69 6d 65 62 6c 6f 63 6b 20 28 6c 61 62 65 6c  timeblock (label
0160: 2c 20 68 44 73 74 29 3a 0a 20 20 20 20 22 70 65  , hDst):.    "pe
0170: 72 66 6f 72 6d 61 6e 63 65 20 63 6f 75 6e 74 65  rformance counte
0180: 72 20 28 63 6f 6e 74 65 78 74 6d 61 6e 61 67 65  r (contextmanage
0190: 72 29 22 0a 20 20 20 20 73 74 61 72 74 20 3d 20  r)".    start = 
01a0: 74 69 6d 65 2e 70 65 72 66 5f 63 6f 75 6e 74 65  time.perf_counte
01b0: 72 28 29 0a 20 20 20 20 74 72 79 3a 0a 20 20 20  r().    try:.   
01c0: 20 20 20 20 20 79 69 65 6c 64 0a 20 20 20 20 66       yield.    f
01d0: 69 6e 61 6c 6c 79 3a 0a 20 20 20 20 20 20 20 20  inally:.        
01e0: 65 6e 64 20 3d 20 74 69 6d 65 2e 70 65 72 66 5f  end = time.perf_
01f0: 63 6f 75 6e 74 65 72 28 29 0a 20 20 20 20 20 20  counter().      
0200: 20 20 70 72 69 6e 74 28 27 7b 7d 20 3a 20 7b 7d    print('{} : {}
0210: 27 2e 66 6f 72 6d 61 74 28 6c 61 62 65 6c 2c 20  '.format(label, 
0220: 65 6e 64 20 2d 20 73 74 61 72 74 29 29 0a 20 20  end - start)).  
0230: 20 20 20 20 20 20 69 66 20 68 44 73 74 3a 0a 20        if hDst:. 
0240: 20 20 20 20 20 20 20 20 20 20 20 68 44 73 74 2e             hDst.
0250: 77 72 69 74 65 28 22 7b 3a 3c 31 32 2e 36 7d 22  write("{:<12.6}"
0260: 2e 66 6f 72 6d 61 74 28 65 6e 64 2d 73 74 61 72  .format(end-star
0270: 74 29 29 0a 0a 0a 64 65 66 20 70 65 72 66 20 28  t))...def perf (
0280: 73 56 65 72 73 69 6f 6e 2c 20 68 44 73 74 3d 4e  sVersion, hDst=N
0290: 6f 6e 65 29 3a 0a 20 20 20 20 22 70 65 72 66 6f  one):.    "perfo
02a0: 72 6d 61 6e 63 65 20 74 65 73 74 73 22 0a 20 20  rmance tests".  
02b0: 20 20 70 72 69 6e 74 28 22 5c 6e 50 65 72 66 6f    print("\nPerfo
02c0: 72 6d 61 6e 63 65 20 74 65 73 74 73 22 29 0a 20  rmance tests"). 
02d0: 20 20 20 67 63 65 2e 6c 6f 61 64 28 29 0a 20 20     gce.load().  
02e0: 20 20 67 63 65 2e 70 61 72 73 65 28 22 54 65 78    gce.parse("Tex
02f0: 74 65 20 73 61 6e 73 20 69 6d 70 6f 72 74 61 6e  te sans importan
0300: 63 65 e2 80 a6 20 75 74 69 6c 65 20 70 6f 75 72  ce... utile pour
0310: 20 6c 61 20 63 6f 6d 70 69 6c 61 74 69 6f 6e 20   la compilation 
0320: 64 65 73 20 72 c3 a8 67 6c 65 73 20 61 76 61 6e  des r..gles avan
0330: 74 20 6c 65 20 63 61 6c 63 75 6c 20 64 65 73 20  t le calcul des 
0340: 70 65 72 66 73 2e 22 29 0a 0a 20 20 20 20 73 70  perfs.")..    sp
0350: 48 65 72 65 2c 20 5f 20 3d 20 6f 73 2e 70 61 74  Here, _ = os.pat
0360: 68 2e 73 70 6c 69 74 28 5f 5f 66 69 6c 65 5f 5f  h.split(__file__
0370: 29 0a 20 20 20 20 77 69 74 68 20 6f 70 65 6e 28  ).    with open(
0380: 6f 73 2e 70 61 74 68 2e 6a 6f 69 6e 28 73 70 48  os.path.join(spH
0390: 65 72 65 2c 20 22 70 65 72 66 2e 74 78 74 22 29  ere, "perf.txt")
03a0: 2c 20 22 72 22 2c 20 65 6e 63 6f 64 69 6e 67 3d  , "r", encoding=
03b0: 22 75 74 66 2d 38 22 29 20 61 73 20 68 53 72 63  "utf-8") as hSrc
03c0: 3a 0a 20 20 20 20 20 20 20 20 69 66 20 68 44 73  :.        if hDs
03d0: 74 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 68  t:.            h
03e0: 44 73 74 2e 77 72 69 74 65 28 22 7b 3a 3c 31 32  Dst.write("{:<12
03f0: 7d 7b 3a 3c 32 30 7d 22 2e 66 6f 72 6d 61 74 28  }{:<20}".format(
0400: 73 56 65 72 73 69 6f 6e 2c 20 74 69 6d 65 2e 73  sVersion, time.s
0410: 74 72 66 74 69 6d 65 28 22 25 59 2e 25 6d 2e 25  trftime("%Y.%m.%
0420: 64 20 25 48 3a 25 4d 22 29 29 29 0a 20 20 20 20  d %H:%M"))).    
0430: 20 20 20 20 66 6f 72 20 73 54 65 78 74 20 69 6e      for sText in
0440: 20 28 20 73 2e 73 74 72 69 70 28 29 20 66 6f 72   ( s.strip() for
0450: 20 73 20 69 6e 20 68 53 72 63 20 69 66 20 6e 6f   s in hSrc if no
0460: 74 20 73 2e 73 74 61 72 74 73 77 69 74 68 28 22  t s.startswith("
0470: 23 22 29 20 61 6e 64 20 73 2e 73 74 72 69 70 28  #") and s.strip(
0480: 29 20 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ) ):.           
0490: 20 77 69 74 68 20 74 69 6d 65 62 6c 6f 63 6b 28   with timeblock(
04a0: 73 54 65 78 74 5b 3a 73 54 65 78 74 2e 66 69 6e  sText[:sText.fin
04b0: 64 28 22 2e 22 29 5d 2c 20 68 44 73 74 29 3a 0a  d(".")], hDst):.
04c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04d0: 67 63 65 2e 70 61 72 73 65 28 73 54 65 78 74 29  gce.parse(sText)
04e0: 0a 20 20 20 20 20 20 20 20 69 66 20 68 44 73 74  .        if hDst
04f0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 68 44  :.            hD
0500: 73 74 2e 77 72 69 74 65 28 22 5c 6e 22 29 0a 0a  st.write("\n")..
0510: 0a 64 65 66 20 5f 66 75 63 6b 42 61 63 6b 73 6c  .def _fuckBacksl
0520: 61 73 68 55 54 46 38 20 28 73 29 3a 0a 20 20 20  ashUTF8 (s):.   
0530: 20 22 66 75 63 6b 20 74 68 61 74 20 73 68 69 74   "fuck that shit
0540: 22 0a 20 20 20 20 72 65 74 75 72 6e 20 73 2e 72  ".    return s.r
0550: 65 70 6c 61 63 65 28 22 5c 75 32 30 31 39 22 2c  eplace("\u2019",
0560: 20 22 27 22 29 2e 72 65 70 6c 61 63 65 28 22 5c   "'").replace("\
0570: 75 32 30 31 33 22 2c 20 22 e2 80 93 22 29 2e 72  u2013", "...").r
0580: 65 70 6c 61 63 65 28 22 5c 75 32 30 31 34 22 2c  eplace("\u2014",
0590: 20 22 e2 80 94 22 29 0a 0a 0a 63 6c 61 73 73 20   "...")...class 
05a0: 54 65 73 74 44 69 63 74 69 6f 6e 61 72 79 20 28  TestDictionary (
05b0: 75 6e 69 74 74 65 73 74 2e 54 65 73 74 43 61 73  unittest.TestCas
05c0: 65 29 3a 0a 20 20 20 20 22 54 65 73 74 20 64 75  e):.    "Test du
05d0: 20 63 6f 72 72 65 63 74 65 75 72 20 6f 72 74 68   correcteur orth
05e0: 6f 67 72 61 70 68 69 71 75 65 22 0a 0a 20 20 20  ographique"..   
05f0: 20 40 63 6c 61 73 73 6d 65 74 68 6f 64 0a 20 20   @classmethod.  
0600: 20 20 64 65 66 20 73 65 74 55 70 43 6c 61 73 73    def setUpClass
0610: 20 28 63 6c 73 29 3a 0a 20 20 20 20 20 20 20 20   (cls):.        
0620: 63 6c 73 2e 6f 44 69 63 20 3d 20 49 42 44 41 57  cls.oDic = IBDAW
0630: 47 28 22 24 7b 64 69 63 5f 6d 61 69 6e 5f 66 69  G("${dic_main_fi
0640: 6c 65 6e 61 6d 65 5f 70 79 7d 22 29 0a 0a 20 20  lename_py}")..  
0650: 20 20 64 65 66 20 74 65 73 74 5f 6c 6f 6f 6b 75    def test_looku
0660: 70 20 28 73 65 6c 66 29 3a 0a 20 20 20 20 20 20  p (self):.      
0670: 20 20 66 6f 72 20 73 57 6f 72 64 20 69 6e 20 5b    for sWord in [
0680: 22 62 72 61 6e 63 68 65 22 2c 20 22 c3 89 6d 69  "branche", "..mi
0690: 6c 69 65 22 5d 3a 0a 20 20 20 20 20 20 20 20 20  lie"]:.         
06a0: 20 20 20 73 65 6c 66 2e 61 73 73 65 72 74 54 72     self.assertTr
06b0: 75 65 28 73 65 6c 66 2e 6f 44 69 63 2e 6c 6f 6f  ue(self.oDic.loo
06c0: 6b 75 70 28 73 57 6f 72 64 29 2c 20 73 57 6f 72  kup(sWord), sWor
06d0: 64 29 0a 0a 20 20 20 20 64 65 66 20 74 65 73 74  d)..    def test
06e0: 5f 6c 6f 6f 6b 75 70 5f 66 61 69 6c 65 64 20 28  _lookup_failed (
06f0: 73 65 6c 66 29 3a 0a 20 20 20 20 20 20 20 20 66  self):.        f
0700: 6f 72 20 73 57 6f 72 64 20 69 6e 20 5b 22 42 72  or sWord in ["Br
0710: 61 6e 63 68 65 22 2c 20 22 42 52 41 4e 43 48 45  anche", "BRANCHE
0720: 22 2c 20 22 42 72 61 6e 63 68 45 22 2c 20 22 42  ", "BranchE", "B
0730: 52 61 6e 63 68 65 22 2c 20 22 42 52 41 6e 43 48  Ranche", "BRAnCH
0740: 45 22 2c 20 22 c3 a9 6d 69 6c 69 65 22 5d 3a 0a  E", "..milie"]:.
0750: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 6c 66              self
0760: 2e 61 73 73 65 72 74 46 61 6c 73 65 28 73 65 6c  .assertFalse(sel
0770: 66 2e 6f 44 69 63 2e 6c 6f 6f 6b 75 70 28 73 57  f.oDic.lookup(sW
0780: 6f 72 64 29 2c 20 73 57 6f 72 64 29 0a 0a 20 20  ord), sWord)..  
0790: 20 20 64 65 66 20 74 65 73 74 5f 69 73 76 61 6c    def test_isval
07a0: 69 64 20 28 73 65 6c 66 29 3a 0a 20 20 20 20 20  id (self):.     
07b0: 20 20 20 66 6f 72 20 73 57 6f 72 64 20 69 6e 20     for sWord in 
07c0: 5b 22 42 72 61 6e 63 68 65 22 2c 20 22 62 72 61  ["Branche", "bra
07d0: 6e 63 68 65 22 2c 20 22 42 52 41 4e 43 48 45 22  nche", "BRANCHE"
07e0: 2c 20 22 c3 89 6d 69 6c 69 65 22 2c 20 22 c3 89  , "..milie", "..
07f0: 4d 49 4c 49 45 22 2c 20 22 61 75 6a 6f 75 72 64  MILIE", "aujourd
0800: 27 68 75 69 22 2c 20 22 61 75 6a 6f 75 72 64 e2  'hui", "aujourd.
0810: 80 99 68 75 69 22 2c 20 22 41 75 6a 6f 75 72 64  ..hui", "Aujourd
0820: 27 68 75 69 22 2c 20 22 41 75 6a 6f 75 72 64 e2  'hui", "Aujourd.
0830: 80 99 68 75 69 22 5d 3a 0a 20 20 20 20 20 20 20  ..hui"]:.       
0840: 20 20 20 20 20 73 65 6c 66 2e 61 73 73 65 72 74       self.assert
0850: 54 72 75 65 28 73 65 6c 66 2e 6f 44 69 63 2e 69  True(self.oDic.i
0860: 73 56 61 6c 69 64 28 73 57 6f 72 64 29 2c 20 73  sValid(sWord), s
0870: 57 6f 72 64 29 0a 0a 20 20 20 20 64 65 66 20 74  Word)..    def t
0880: 65 73 74 5f 69 73 76 61 6c 69 64 5f 66 61 69 6c  est_isvalid_fail
0890: 65 64 20 28 73 65 6c 66 29 3a 0a 20 20 20 20 20  ed (self):.     
08a0: 20 20 20 66 6f 72 20 73 57 6f 72 64 20 69 6e 20     for sWord in 
08b0: 5b 22 42 72 61 6e 63 68 45 22 2c 20 22 42 52 61  ["BranchE", "BRa
08c0: 6e 63 68 65 22 2c 20 22 42 52 41 6e 43 48 45 22  nche", "BRAnCHE"
08d0: 2c 20 22 c3 a9 6d 69 6c 69 65 22 2c 20 22 c3 a9  , "..milie", "..
08e0: 4d 49 4c 49 45 22 2c 20 22 c3 a9 6d 69 4c 69 65  MILIE", "..miLie
08f0: 22 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "]:.            
0900: 73 65 6c 66 2e 61 73 73 65 72 74 46 61 6c 73 65  self.assertFalse
0910: 28 73 65 6c 66 2e 6f 44 69 63 2e 69 73 56 61 6c  (self.oDic.isVal
0920: 69 64 28 73 57 6f 72 64 29 2c 20 73 57 6f 72 64  id(sWord), sWord
0930: 29 0a 0a 0a 63 6c 61 73 73 20 54 65 73 74 43 6f  )...class TestCo
0940: 6e 6a 75 67 61 74 69 6f 6e 20 28 75 6e 69 74 74  njugation (unitt
0950: 65 73 74 2e 54 65 73 74 43 61 73 65 29 3a 0a 20  est.TestCase):. 
0960: 20 20 20 22 54 65 73 74 73 20 64 65 73 20 63 6f     "Tests des co
0970: 6e 6a 75 67 61 69 73 6f 6e 73 22 0a 0a 20 20 20  njugaisons"..   
0980: 20 40 63 6c 61 73 73 6d 65 74 68 6f 64 0a 20 20   @classmethod.  
0990: 20 20 64 65 66 20 73 65 74 55 70 43 6c 61 73 73    def setUpClass
09a0: 20 28 63 6c 73 29 3a 0a 20 20 20 20 20 20 20 20   (cls):.        
09b0: 70 61 73 73 0a 0a 20 20 20 20 64 65 66 20 74 65  pass..    def te
09c0: 73 74 5f 69 73 76 65 72 62 20 28 73 65 6c 66 29  st_isverb (self)
09d0: 3a 0a 20 20 20 20 20 20 20 20 66 6f 72 20 73 56  :.        for sV
09e0: 65 72 62 20 69 6e 20 5b 22 61 76 6f 69 72 22 2c  erb in ["avoir",
09f0: 20 22 c3 aa 74 72 65 22 2c 20 22 61 6c 6c 65 72   "..tre", "aller
0a00: 22 2c 20 22 6d 61 6e 67 65 72 22 2c 20 22 63 6f  ", "manger", "co
0a10: 75 72 69 72 22 2c 20 22 76 65 6e 69 72 22 2c 20  urir", "venir", 
0a20: 22 66 61 69 72 65 22 2c 20 22 66 69 6e 69 72 22  "faire", "finir"
0a30: 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  ]:.            s
0a40: 65 6c 66 2e 61 73 73 65 72 74 54 72 75 65 28 63  elf.assertTrue(c
0a50: 6f 6e 6a 2e 69 73 56 65 72 62 28 73 56 65 72 62  onj.isVerb(sVerb
0a60: 29 2c 20 73 56 65 72 62 29 0a 20 20 20 20 20 20  ), sVerb).      
0a70: 20 20 66 6f 72 20 73 56 65 72 62 20 69 6e 20 5b    for sVerb in [
0a80: 22 62 65 72 6b 22 2c 20 22 61 22 2c 20 22 76 61  "berk", "a", "va
0a90: 22 2c 20 22 63 6f 6e 74 72 65 22 2c 20 22 73 75  ", "contre", "su
0aa0: 70 65 72 22 2c 20 22 22 2c 20 22 c3 a0 22 5d 3a  per", "", ".."]:
0ab0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 65 6c  .            sel
0ac0: 66 2e 61 73 73 65 72 74 46 61 6c 73 65 28 63 6f  f.assertFalse(co
0ad0: 6e 6a 2e 69 73 56 65 72 62 28 73 56 65 72 62 29  nj.isVerb(sVerb)
0ae0: 2c 20 73 56 65 72 62 29 0a 0a 20 20 20 20 64 65  , sVerb)..    de
0af0: 66 20 74 65 73 74 5f 68 61 73 63 6f 6e 6a 20 28  f test_hasconj (
0b00: 73 65 6c 66 29 3a 0a 20 20 20 20 20 20 20 20 66  self):.        f
0b10: 6f 72 20 73 56 65 72 62 2c 20 73 54 65 6e 73 65  or sVerb, sTense
0b20: 2c 20 73 57 68 6f 20 69 6e 20 5b 28 22 61 6c 6c  , sWho in [("all
0b30: 65 72 22 2c 20 22 3a 45 22 2c 20 22 3a 32 73 22  er", ":E", ":2s"
0b40: 29 2c 20 28 22 61 76 6f 69 72 22 2c 20 22 3a 49  ), ("avoir", ":I
0b50: 73 22 2c 20 22 3a 31 73 22 29 2c 20 28 22 c3 aa  s", ":1s"), ("..
0b60: 74 72 65 22 2c 20 22 3a 49 70 22 2c 20 22 3a 32  tre", ":Ip", ":2
0b70: 70 22 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20  p"),.           
0b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b90: 20 20 20 20 20 20 20 20 20 28 22 6d 61 6e 67 65           ("mange
0ba0: 72 22 2c 20 22 3a 53 70 22 2c 20 22 3a 33 73 22  r", ":Sp", ":3s"
0bb0: 29 2c 20 28 22 66 69 6e 69 72 22 2c 20 22 3a 4b  ), ("finir", ":K
0bc0: 22 2c 20 22 3a 33 70 22 29 2c 20 28 22 70 72 65  ", ":3p"), ("pre
0bd0: 6e 64 72 65 22 2c 20 22 3a 49 66 22 2c 20 22 3a  ndre", ":If", ":
0be0: 31 70 22 29 5d 3a 0a 20 20 20 20 20 20 20 20 20  1p")]:.         
0bf0: 20 20 20 73 65 6c 66 2e 61 73 73 65 72 74 54 72     self.assertTr
0c00: 75 65 28 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28  ue(conj.hasConj(
0c10: 73 56 65 72 62 2c 20 73 54 65 6e 73 65 2c 20 73  sVerb, sTense, s
0c20: 57 68 6f 29 2c 20 73 56 65 72 62 29 0a 0a 20 20  Who), sVerb)..  
0c30: 20 20 64 65 66 20 74 65 73 74 5f 67 65 74 63 6f    def test_getco
0c40: 6e 6a 20 28 73 65 6c 66 29 3a 0a 20 20 20 20 20  nj (self):.     
0c50: 20 20 20 66 6f 72 20 73 56 65 72 62 2c 20 73 54     for sVerb, sT
0c60: 65 6e 73 65 2c 20 73 57 68 6f 2c 20 73 43 6f 6e  ense, sWho, sCon
0c70: 6a 20 69 6e 20 5b 28 22 61 6c 6c 65 72 22 2c 20  j in [("aller", 
0c80: 22 3a 45 22 2c 20 22 3a 32 73 22 2c 20 22 76 61  ":E", ":2s", "va
0c90: 22 29 2c 20 28 22 61 76 6f 69 72 22 2c 20 22 3a  "), ("avoir", ":
0ca0: 49 71 22 2c 20 22 3a 31 73 22 2c 20 22 61 76 61  Iq", ":1s", "ava
0cb0: 69 73 22 29 2c 20 28 22 c3 aa 74 72 65 22 2c 20  is"), ("..tre", 
0cc0: 22 3a 49 70 22 2c 20 22 3a 32 70 22 2c 20 22 c3  ":Ip", ":2p", ".
0cd0: aa 74 65 73 22 29 2c 0a 20 20 20 20 20 20 20 20  .tes"),.        
0ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d00: 20 20 20 28 22 6d 61 6e 67 65 72 22 2c 20 22 3a     ("manger", ":
0d10: 53 70 22 2c 20 22 3a 33 73 22 2c 20 22 6d 61 6e  Sp", ":3s", "man
0d20: 67 65 22 29 2c 20 28 22 66 69 6e 69 72 22 2c 20  ge"), ("finir", 
0d30: 22 3a 4b 22 2c 20 22 3a 33 70 22 2c 20 22 66 69  ":K", ":3p", "fi
0d40: 6e 69 72 61 69 65 6e 74 22 29 2c 20 28 22 70 72  niraient"), ("pr
0d50: 65 6e 64 72 65 22 2c 20 22 3a 49 66 22 2c 20 22  endre", ":If", "
0d60: 3a 31 70 22 2c 20 22 70 72 65 6e 64 72 6f 6e 73  :1p", "prendrons
0d70: 22 29 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ")]:.           
0d80: 20 73 65 6c 66 2e 61 73 73 65 72 74 45 71 75 61   self.assertEqua
0d90: 6c 28 63 6f 6e 6a 2e 67 65 74 43 6f 6e 6a 28 73  l(conj.getConj(s
0da0: 56 65 72 62 2c 20 73 54 65 6e 73 65 2c 20 73 57  Verb, sTense, sW
0db0: 68 6f 29 2c 20 73 43 6f 6e 6a 2c 20 73 56 65 72  ho), sConj, sVer
0dc0: 62 29 0a 0a 0a 63 6c 61 73 73 20 54 65 73 74 50  b)...class TestP
0dd0: 68 6f 6e 65 74 20 28 75 6e 69 74 74 65 73 74 2e  honet (unittest.
0de0: 54 65 73 74 43 61 73 65 29 3a 0a 20 20 20 20 22  TestCase):.    "
0df0: 54 65 73 74 73 20 64 65 73 20 c3 a9 71 75 69 76  Tests des ..quiv
0e00: 61 6c 65 6e 63 65 73 20 70 68 6f 6e c3 a9 74 69  alences phon..ti
0e10: 71 75 65 73 22 0a 0a 20 20 20 20 40 63 6c 61 73  ques"..    @clas
0e20: 73 6d 65 74 68 6f 64 0a 20 20 20 20 64 65 66 20  smethod.    def 
0e30: 73 65 74 55 70 43 6c 61 73 73 20 28 63 6c 73 29  setUpClass (cls)
0e40: 3a 0a 20 20 20 20 20 20 20 20 63 6c 73 2e 6c 53  :.        cls.lS
0e50: 65 74 20 3d 20 5b 0a 20 20 20 20 20 20 20 20 20  et = [.         
0e60: 20 20 20 5b 22 63 65 22 2c 20 22 73 65 22 5d 2c     ["ce", "se"],
0e70: 0a 20 20 20 20 20 20 20 20 20 20 20 20 5b 22 63  .            ["c
0e80: 65 73 22 2c 20 22 73 65 73 22 2c 20 22 73 61 69  es", "ses", "sai
0e90: 73 22 2c 20 22 73 61 69 74 22 5d 2c 0a 20 20 20  s", "sait"],.   
0ea0: 20 20 20 20 20 20 20 20 20 5b 22 63 65 74 22 2c           ["cet",
0eb0: 20 22 63 65 74 74 65 22 2c 20 22 73 65 70 74 22   "cette", "sept"
0ec0: 2c 20 22 73 65 74 22 2c 20 22 73 65 74 73 22 5d  , "set", "sets"]
0ed0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 5b 22  ,.            ["
0ee0: 64 c3 a9 22 2c 20 22 64 c3 a9 73 22 2c 20 22 64  d..", "d..s", "d
0ef0: c3 a8 73 22 2c 20 22 64 61 69 73 22 2c 20 22 64  ..s", "dais", "d
0f00: 65 73 22 5d 2c 0a 20 20 20 20 20 20 20 20 20 20  es"],.          
0f10: 20 20 5b 22 64 6f 6e 22 2c 20 22 64 6f 6e 73 22    ["don", "dons"
0f20: 2c 20 22 64 6f 6e 74 22 5d 2c 0a 20 20 20 20 20  , "dont"],.     
0f30: 20 20 20 20 20 20 20 5b 22 c3 a9 74 c3 a9 22 2c         ["..t..",
0f40: 20 22 c3 a9 74 61 69 65 22 2c 20 22 c3 a9 74 61   "..taie", "..ta
0f50: 69 65 73 22 2c 20 22 c3 a9 74 61 69 73 22 2c 20  ies", "..tais", 
0f60: 22 c3 a9 74 61 69 74 22 2c 20 22 c3 a9 74 61 69  "..tait", "..tai
0f70: 22 2c 20 22 c3 a9 74 c3 a9 73 22 2c 20 22 c3 a9  ", "..t..s", "..
0f80: 74 61 69 65 6e 74 22 5d 2c 0a 20 20 20 20 20 20  taient"],.      
0f90: 20 20 20 20 20 20 5b 22 66 61 69 72 65 22 2c 20        ["faire", 
0fa0: 22 66 65 72 22 2c 20 22 66 65 72 73 22 2c 20 22  "fer", "fers", "
0fb0: 66 65 72 72 65 22 2c 20 22 66 65 72 72 65 73 22  ferre", "ferres"
0fc0: 2c 20 22 66 65 72 72 65 6e 74 22 5d 2c 0a 20 20  , "ferrent"],.  
0fd0: 20 20 20 20 20 20 20 20 20 20 5b 22 66 6f 69 73            ["fois
0fe0: 22 2c 20 22 66 6f 69 22 2c 20 22 66 6f 69 65 22  ", "foi", "foie"
0ff0: 2c 20 22 66 6f 69 65 73 22 5d 2c 0a 20 20 20 20  , "foies"],.    
1000: 20 20 20 20 20 20 20 20 5b 22 6c 61 22 2c 20 22          ["la", "
1010: 6c c3 a0 22 2c 20 22 6c 61 73 22 5d 2c 0a 20 20  l..", "las"],.  
1020: 20 20 20 20 20 20 20 20 20 20 5b 22 6d 65 73 22            ["mes"
1030: 2c 20 22 6d 65 74 73 22 2c 20 22 6d 65 74 22 2c  , "mets", "met",
1040: 20 22 6d 61 69 22 2c 20 22 6d 61 69 73 22 5d 2c   "mai", "mais"],
1050: 0a 20 20 20 20 20 20 20 20 20 20 20 20 5b 22 6d  .            ["m
1060: 6f 6e 22 2c 20 22 6d 6f 6e 74 22 2c 20 22 6d 6f  on", "mont", "mo
1070: 6e 74 73 22 5d 2c 0a 20 20 20 20 20 20 20 20 20  nts"],.         
1080: 20 20 20 5b 22 6d 6f 74 22 2c 20 22 6d 6f 74 73     ["mot", "mots
1090: 22 2c 20 22 6d 61 75 78 22 5d 2c 0a 20 20 20 20  ", "maux"],.    
10a0: 20 20 20 20 20 20 20 20 5b 22 6d 6f 69 22 2c 20          ["moi", 
10b0: 22 6d 6f 69 73 22 5d 2c 0a 20 20 20 20 20 20 20  "mois"],.       
10c0: 20 20 20 20 20 5b 22 6e 6f 74 72 65 22 2c 20 22       ["notre", "
10d0: 6e c3 b4 74 72 65 22 2c 20 22 6e c3 b4 74 72 65  n..tre", "n..tre
10e0: 73 22 5d 2c 0a 20 20 20 20 20 20 20 20 20 20 20  s"],.           
10f0: 20 5b 22 6f 72 22 2c 20 22 6f 72 73 22 2c 20 22   ["or", "ors", "
1100: 68 6f 72 73 22 5d 2c 0a 20 20 20 20 20 20 20 20  hors"],.        
1110: 20 20 20 20 5b 22 68 6f 75 22 2c 20 22 68 6f 75      ["hou", "hou
1120: 65 22 2c 20 22 68 6f 75 65 73 22 2c 20 22 6f 75  e", "houes", "ou
1130: 22 2c 20 22 6f c3 b9 22 2c 20 22 68 6f 75 78 22  ", "o..", "houx"
1140: 5d 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 5b  ],.            [
1150: 22 70 65 75 22 2c 20 22 70 65 75 78 22 2c 20 22  "peu", "peux", "
1160: 70 65 75 74 22 5d 2c 0a 20 20 20 20 20 20 20 20  peut"],.        
1170: 20 20 20 20 5b 22 73 65 73 22 2c 20 22 63 65 73      ["ses", "ces
1180: 22 2c 20 22 73 61 69 73 22 2c 20 22 73 61 69 74  ", "sais", "sait
1190: 22 5d 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  "],.            
11a0: 5b 22 73 6f 6e 22 2c 20 22 73 6f 6e 73 22 2c 20  ["son", "sons", 
11b0: 22 73 6f 6e 74 22 5d 2c 0a 20 20 20 20 20 20 20  "sont"],.       
11c0: 20 20 20 20 20 5b 22 74 65 73 22 2c 20 22 74 61       ["tes", "ta
11d0: 69 73 22 2c 20 22 74 61 69 74 22 2c 20 22 74 61  is", "tait", "ta
11e0: 69 65 22 2c 20 22 74 61 69 65 73 22 2c 20 22 74  ie", "taies", "t
11f0: 68 c3 a9 22 2c 20 22 74 68 c3 a9 73 22 5d 2c 0a  h..", "th..s"],.
1200: 20 20 20 20 20 20 20 20 20 20 20 20 5b 22 74 6f              ["to
1210: 69 22 2c 20 22 74 6f 69 74 22 2c 20 22 74 6f 69  i", "toit", "toi
1220: 74 73 22 5d 2c 0a 20 20 20 20 20 20 20 20 20 20  ts"],.          
1230: 20 20 5b 22 74 6f 6e 22 2c 20 22 74 6f 6e 73 22    ["ton", "tons"
1240: 2c 20 22 74 68 6f 6e 22 2c 20 22 74 68 6f 6e 73  , "thon", "thons
1250: 22 2c 20 22 74 6f 6e 64 22 2c 20 22 74 6f 6e 64  ", "tond", "tond
1260: 73 22 5d 2c 0a 20 20 20 20 20 20 20 20 20 20 20  s"],.           
1270: 20 5b 22 76 6f 69 72 22 2c 20 22 76 6f 69 72 65   ["voir", "voire
1280: 22 5d 0a 20 20 20 20 20 20 20 20 5d 0a 0a 20 20  "].        ]..  
1290: 20 20 64 65 66 20 74 65 73 74 5f 67 65 74 73 69    def test_getsi
12a0: 6d 69 6c 20 28 73 65 6c 66 29 3a 0a 20 20 20 20  mil (self):.    
12b0: 20 20 20 20 66 6f 72 20 61 53 65 74 20 69 6e 20      for aSet in 
12c0: 73 65 6c 66 2e 6c 53 65 74 3a 0a 20 20 20 20 20  self.lSet:.     
12d0: 20 20 20 20 20 20 20 66 6f 72 20 73 57 6f 72 64         for sWord
12e0: 20 69 6e 20 61 53 65 74 3a 0a 20 20 20 20 20 20   in aSet:.      
12f0: 20 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e 61            self.a
1300: 73 73 65 72 74 4c 69 73 74 45 71 75 61 6c 28 70  ssertListEqual(p
1310: 68 6f 6e 65 74 2e 67 65 74 53 69 6d 69 6c 28 73  honet.getSimil(s
1320: 57 6f 72 64 29 2c 20 73 6f 72 74 65 64 28 61 53  Word), sorted(aS
1330: 65 74 29 29 0a 0a 0a 63 6c 61 73 73 20 54 65 73  et))...class Tes
1340: 74 4d 61 73 46 65 6d 53 69 6e 67 50 6c 75 72 20  tMasFemSingPlur 
1350: 28 75 6e 69 74 74 65 73 74 2e 54 65 73 74 43 61  (unittest.TestCa
1360: 73 65 29 3a 0a 20 20 20 20 22 54 65 73 74 73 20  se):.    "Tests 
1370: 64 65 73 20 6d 61 73 63 75 6c 69 6e 73 2c 20 66  des masculins, f
1380: c3 a9 6d 69 6e 69 6e 73 2c 20 73 69 6e 67 75 6c  ..minins, singul
1390: 69 65 72 73 20 65 74 20 70 6c 75 72 69 65 6c 73  iers et pluriels
13a0: 22 0a 0a 20 20 20 20 40 63 6c 61 73 73 6d 65 74  "..    @classmet
13b0: 68 6f 64 0a 20 20 20 20 64 65 66 20 73 65 74 55  hod.    def setU
13c0: 70 43 6c 61 73 73 20 28 63 6c 73 29 3a 0a 20 20  pClass (cls):.  
13d0: 20 20 20 20 20 20 63 6c 73 2e 6c 50 6c 75 72 61        cls.lPlura
13e0: 6c 20 3d 20 5b 0a 20 20 20 20 20 20 20 20 20 20  l = [.          
13f0: 20 20 28 22 74 72 61 76 61 69 6c 22 2c 20 5b 22    ("travail", ["
1400: 74 72 61 76 61 75 78 22 5d 29 2c 0a 20 20 20 20  travaux"]),.    
1410: 20 20 20 20 20 20 20 20 28 22 76 c5 93 75 22 2c          ("v..u",
1420: 20 5b 22 76 c5 93 75 78 22 5d 29 2c 0a 20 20 20   ["v..ux"]),.   
1430: 20 20 20 20 20 20 20 20 20 28 22 67 65 6e 74 6c           ("gentl
1440: 65 6d 61 6e 22 2c 20 5b 22 67 65 6e 74 6c 65 6d  eman", ["gentlem
1450: 61 6e 73 22 2c 20 22 67 65 6e 74 6c 65 6d 65 6e  ans", "gentlemen
1460: 22 5d 29 0a 20 20 20 20 20 20 20 20 5d 0a 0a 20  "]).        ].. 
1470: 20 20 20 64 65 66 20 74 65 73 74 5f 67 65 74 70     def test_getp
1480: 6c 75 72 61 6c 20 28 73 65 6c 66 29 3a 0a 20 20  lural (self):.  
1490: 20 20 20 20 20 20 66 6f 72 20 73 53 69 6e 67 2c        for sSing,
14a0: 20 6c 50 6c 75 72 20 69 6e 20 73 65 6c 66 2e 6c   lPlur in self.l
14b0: 50 6c 75 72 61 6c 3a 0a 20 20 20 20 20 20 20 20  Plural:.        
14c0: 20 20 20 20 73 65 6c 66 2e 61 73 73 65 72 74 4c      self.assertL
14d0: 69 73 74 45 71 75 61 6c 28 6d 66 73 70 2e 67 65  istEqual(mfsp.ge
14e0: 74 4d 69 73 63 50 6c 75 72 61 6c 28 73 53 69 6e  tMiscPlural(sSin
14f0: 67 29 2c 20 6c 50 6c 75 72 29 0a 0a 0a 63 6c 61  g), lPlur)...cla
1500: 73 73 20 54 65 73 74 47 72 61 6d 6d 61 72 43 68  ss TestGrammarCh
1510: 65 63 6b 69 6e 67 20 28 75 6e 69 74 74 65 73 74  ecking (unittest
1520: 2e 54 65 73 74 43 61 73 65 29 3a 0a 20 20 20 20  .TestCase):.    
1530: 22 54 65 73 74 73 20 64 75 20 63 6f 72 72 65 63  "Tests du correc
1540: 74 65 75 72 20 67 72 61 6d 6d 61 74 69 63 61 6c  teur grammatical
1550: 22 0a 0a 20 20 20 20 40 63 6c 61 73 73 6d 65 74  "..    @classmet
1560: 68 6f 64 0a 20 20 20 20 64 65 66 20 73 65 74 55  hod.    def setU
1570: 70 43 6c 61 73 73 20 28 63 6c 73 29 3a 0a 20 20  pClass (cls):.  
1580: 20 20 20 20 20 20 67 63 65 2e 6c 6f 61 64 28 29        gce.load()
1590: 0a 20 20 20 20 20 20 20 20 63 6c 73 2e 5f 7a 45  .        cls._zE
15a0: 72 72 6f 72 20 3d 20 72 65 2e 63 6f 6d 70 69 6c  rror = re.compil
15b0: 65 28 72 22 5c 7b 5c 7b 2e 2a 3f 5c 7d 5c 7d 22  e(r"\{\{.*?\}\}"
15c0: 29 0a 20 20 20 20 20 20 20 20 63 6c 73 2e 5f 61  ).        cls._a
15d0: 54 65 73 74 65 64 52 75 6c 65 73 20 3d 20 73 65  TestedRules = se
15e0: 74 28 29 0a 0a 20 20 20 20 64 65 66 20 74 65 73  t()..    def tes
15f0: 74 5f 70 61 72 73 65 20 28 73 65 6c 66 29 3a 0a  t_parse (self):.
1600: 20 20 20 20 20 20 20 20 7a 4f 70 74 69 6f 6e 20          zOption 
1610: 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 22 5e 5f  = re.compile("^_
1620: 5f 28 5b 61 2d 7a 41 2d 5a 30 2d 39 5d 2b 29 5f  _([a-zA-Z0-9]+)_
1630: 5f 20 22 29 0a 20 20 20 20 20 20 20 20 73 70 48  _ ").        spH
1640: 65 72 65 2c 20 5f 20 3d 20 6f 73 2e 70 61 74 68  ere, _ = os.path
1650: 2e 73 70 6c 69 74 28 5f 5f 66 69 6c 65 5f 5f 29  .split(__file__)
1660: 0a 20 20 20 20 20 20 20 20 77 69 74 68 20 6f 70  .        with op
1670: 65 6e 28 6f 73 2e 70 61 74 68 2e 6a 6f 69 6e 28  en(os.path.join(
1680: 73 70 48 65 72 65 2c 20 22 67 63 5f 74 65 73 74  spHere, "gc_test
1690: 2e 74 78 74 22 29 2c 20 22 72 22 2c 20 65 6e 63  .txt"), "r", enc
16a0: 6f 64 69 6e 67 3d 22 75 74 66 2d 38 22 29 20 61  oding="utf-8") a
16b0: 73 20 68 53 72 63 3a 0a 20 20 20 20 20 20 20 20  s hSrc:.        
16c0: 20 20 20 20 6e 45 72 72 6f 72 20 3d 20 30 0a 20      nError = 0. 
16d0: 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 73             for s
16e0: 4c 69 6e 65 20 69 6e 20 28 20 73 20 66 6f 72 20  Line in ( s for 
16f0: 73 20 69 6e 20 68 53 72 63 20 69 66 20 6e 6f 74  s in hSrc if not
1700: 20 73 2e 73 74 61 72 74 73 77 69 74 68 28 22 23   s.startswith("#
1710: 22 29 20 61 6e 64 20 73 2e 73 74 72 69 70 28 29  ") and s.strip()
1720: 20 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20   ):.            
1730: 20 20 20 20 73 4c 69 6e 65 4e 75 6d 20 3d 20 73      sLineNum = s
1740: 4c 69 6e 65 5b 3a 31 30 5d 2e 73 74 72 69 70 28  Line[:10].strip(
1750: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
1760: 20 20 73 4c 69 6e 65 20 3d 20 73 4c 69 6e 65 5b    sLine = sLine[
1770: 31 30 3a 5d 2e 73 74 72 69 70 28 29 0a 20 20 20  10:].strip().   
1780: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 4f 70               sOp
1790: 74 69 6f 6e 20 3d 20 4e 6f 6e 65 0a 20 20 20 20  tion = None.    
17a0: 20 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d 20              m = 
17b0: 7a 4f 70 74 69 6f 6e 2e 73 65 61 72 63 68 28 73  zOption.search(s
17c0: 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20 20  Line).          
17d0: 20 20 20 20 20 20 69 66 20 6d 3a 0a 20 20 20 20        if m:.    
17e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17f0: 73 4c 69 6e 65 20 3d 20 73 4c 69 6e 65 5b 6d 2e  sLine = sLine[m.
1800: 65 6e 64 28 29 3a 5d 0a 20 20 20 20 20 20 20 20  end():].        
1810: 20 20 20 20 20 20 20 20 20 20 20 20 73 4f 70 74              sOpt
1820: 69 6f 6e 20 3d 20 6d 2e 67 72 6f 75 70 28 31 29  ion = m.group(1)
1830: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1840: 20 69 66 20 22 2d 3e 3e 22 20 69 6e 20 73 4c 69   if "->>" in sLi
1850: 6e 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ne:.            
1860: 20 20 20 20 20 20 20 20 73 45 72 72 6f 72 54 65          sErrorTe
1870: 78 74 2c 20 73 45 78 63 65 70 74 65 64 53 75 67  xt, sExceptedSug
1880: 67 73 20 3d 20 73 65 6c 66 2e 5f 73 70 6c 69 74  gs = self._split
1890: 54 65 73 74 4c 69 6e 65 28 73 4c 69 6e 65 29 0a  TestLine(sLine).
18a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18b0: 20 20 20 20 69 66 20 73 45 78 63 65 70 74 65 64      if sExcepted
18c0: 53 75 67 67 73 2e 73 74 61 72 74 73 77 69 74 68  Suggs.startswith
18d0: 28 27 22 27 29 20 61 6e 64 20 73 45 78 63 65 70  ('"') and sExcep
18e0: 74 65 64 53 75 67 67 73 2e 65 6e 64 73 77 69 74  tedSuggs.endswit
18f0: 68 28 27 22 27 29 3a 0a 20 20 20 20 20 20 20 20  h('"'):.        
1900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1910: 73 45 78 63 65 70 74 65 64 53 75 67 67 73 20 3d  sExceptedSuggs =
1920: 20 73 45 78 63 65 70 74 65 64 53 75 67 67 73 5b   sExceptedSuggs[
1930: 31 3a 2d 31 5d 0a 20 20 20 20 20 20 20 20 20 20  1:-1].          
1940: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
1950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1960: 73 45 72 72 6f 72 54 65 78 74 20 3d 20 73 4c 69  sErrorText = sLi
1970: 6e 65 2e 73 74 72 69 70 28 29 0a 20 20 20 20 20  ne.strip().     
1980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
1990: 45 78 63 65 70 74 65 64 53 75 67 67 73 20 3d 20  ExceptedSuggs = 
19a0: 22 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  "".             
19b0: 20 20 20 73 45 78 70 65 63 74 65 64 45 72 72 6f     sExpectedErro
19c0: 72 73 20 3d 20 73 65 6c 66 2e 5f 67 65 74 45 78  rs = self._getEx
19d0: 70 65 63 74 65 64 45 72 72 6f 72 73 28 73 45 72  pectedErrors(sEr
19e0: 72 6f 72 54 65 78 74 29 0a 20 20 20 20 20 20 20  rorText).       
19f0: 20 20 20 20 20 20 20 20 20 73 54 65 78 74 54 6f           sTextTo
1a00: 43 68 65 63 6b 20 3d 20 73 45 72 72 6f 72 54 65  Check = sErrorTe
1a10: 78 74 2e 72 65 70 6c 61 63 65 28 22 7d 7d 22 2c  xt.replace("}}",
1a20: 20 22 22 29 2e 72 65 70 6c 61 63 65 28 22 7b 7b   "").replace("{{
1a30: 22 2c 20 22 22 29 0a 20 20 20 20 20 20 20 20 20  ", "").         
1a40: 20 20 20 20 20 20 20 73 46 6f 75 6e 64 45 72 72         sFoundErr
1a50: 6f 72 73 2c 20 73 4c 69 73 74 45 72 72 2c 20 73  ors, sListErr, s
1a60: 46 6f 75 6e 64 53 75 67 67 73 20 3d 20 73 65 6c  FoundSuggs = sel
1a70: 66 2e 5f 67 65 74 46 6f 75 6e 64 45 72 72 6f 72  f._getFoundError
1a80: 73 28 73 54 65 78 74 54 6f 43 68 65 63 6b 2c 20  s(sTextToCheck, 
1a90: 73 4f 70 74 69 6f 6e 29 0a 20 20 20 20 20 20 20  sOption).       
1aa0: 20 20 20 20 20 20 20 20 20 23 20 74 65 73 74 73           # tests
1ab0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1ac0: 20 69 66 20 73 45 78 70 65 63 74 65 64 45 72 72   if sExpectedErr
1ad0: 6f 72 73 20 21 3d 20 73 46 6f 75 6e 64 45 72 72  ors != sFoundErr
1ae0: 6f 72 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ors:.           
1af0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
1b00: 5c 6e 23 20 4c 69 6e 65 20 6e 75 6d 3a 20 22 20  \n# Line num: " 
1b10: 2b 20 73 4c 69 6e 65 4e 75 6d 20 2b 20 5c 0a 20  + sLineNum + \. 
1b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b30: 20 20 20 20 20 20 20 20 20 22 5c 6e 3e 20 74 6f           "\n> to
1b40: 20 63 68 65 63 6b 3a 20 22 20 2b 20 5f 66 75 63   check: " + _fuc
1b50: 6b 42 61 63 6b 73 6c 61 73 68 55 54 46 38 28 73  kBackslashUTF8(s
1b60: 54 65 78 74 54 6f 43 68 65 63 6b 29 20 2b 20 5c  TextToCheck) + \
1b70: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1b80: 20 20 20 20 20 20 20 20 20 20 20 22 5c 6e 20 20             "\n  
1b90: 65 78 70 65 63 74 65 64 3a 20 22 20 2b 20 73 45  expected: " + sE
1ba0: 78 70 65 63 74 65 64 45 72 72 6f 72 73 20 2b 20  xpectedErrors + 
1bb0: 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  \.              
1bc0: 20 20 20 20 20 20 20 20 20 20 20 20 22 5c 6e 20              "\n 
1bd0: 20 66 6f 75 6e 64 3a 20 20 20 20 22 20 2b 20 73   found:    " + s
1be0: 46 6f 75 6e 64 45 72 72 6f 72 73 20 2b 20 5c 0a  FoundErrors + \.
1bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c00: 20 20 20 20 20 20 20 20 20 20 22 5c 6e 20 20 65            "\n  e
1c10: 72 72 6f 72 73 3a 20 20 20 5c 6e 22 20 2b 20 73  rrors:   \n" + s
1c20: 4c 69 73 74 45 72 72 29 0a 20 20 20 20 20 20 20  ListErr).       
1c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 45 72               nEr
1c40: 72 6f 72 20 2b 3d 20 31 0a 20 20 20 20 20 20 20  ror += 1.       
1c50: 20 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 45           elif sE
1c60: 78 63 65 70 74 65 64 53 75 67 67 73 3a 0a 20 20  xceptedSuggs:.  
1c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c80: 20 20 69 66 20 73 45 78 63 65 70 74 65 64 53 75    if sExceptedSu
1c90: 67 67 73 20 21 3d 20 73 46 6f 75 6e 64 53 75 67  ggs != sFoundSug
1ca0: 67 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  gs:.            
1cb0: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
1cc0: 74 28 22 5c 6e 23 20 4c 69 6e 65 20 6e 75 6d 3a  t("\n# Line num:
1cd0: 20 22 20 2b 20 73 4c 69 6e 65 4e 75 6d 20 2b 20   " + sLineNum + 
1ce0: 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  \.              
1cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d00: 22 5c 6e 3e 20 74 6f 20 63 68 65 63 6b 3a 20 22  "\n> to check: "
1d10: 20 2b 20 5f 66 75 63 6b 42 61 63 6b 73 6c 61 73   + _fuckBackslas
1d20: 68 55 54 46 38 28 73 54 65 78 74 54 6f 43 68 65  hUTF8(sTextToChe
1d30: 63 6b 29 20 2b 20 5c 0a 20 20 20 20 20 20 20 20  ck) + \.        
1d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d50: 20 20 20 20 20 20 22 5c 6e 20 20 65 78 70 65 63        "\n  expec
1d60: 74 65 64 3a 20 22 20 2b 20 73 45 78 63 65 70 74  ted: " + sExcept
1d70: 65 64 53 75 67 67 73 20 2b 20 5c 0a 20 20 20 20  edSuggs + \.    
1d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d90: 20 20 20 20 20 20 20 20 20 20 22 5c 6e 20 20 66            "\n  f
1da0: 6f 75 6e 64 3a 20 20 20 20 22 20 2b 20 73 46 6f  ound:    " + sFo
1db0: 75 6e 64 53 75 67 67 73 20 2b 20 5c 0a 20 20 20  undSuggs + \.   
1dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1dd0: 20 20 20 20 20 20 20 20 20 20 20 22 5c 6e 20 20             "\n  
1de0: 65 72 72 6f 72 73 3a 20 20 20 5c 6e 22 20 2b 20  errors:   \n" + 
1df0: 73 4c 69 73 74 45 72 72 29 0a 20 20 20 20 20 20  sListErr).      
1e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e10: 20 20 6e 45 72 72 6f 72 20 2b 3d 20 31 0a 20 20    nError += 1.  
1e20: 20 20 20 20 20 20 20 20 20 20 69 66 20 6e 45 72            if nEr
1e30: 72 6f 72 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ror:.           
1e40: 20 20 20 20 20 70 72 69 6e 74 28 22 55 6e 65 78       print("Unex
1e50: 70 65 63 74 65 64 20 65 72 72 6f 72 73 3a 22 2c  pected errors:",
1e60: 20 6e 45 72 72 6f 72 29 0a 20 20 20 20 20 20 20   nError).       
1e70: 20 23 20 75 6e 74 65 73 74 65 64 20 72 75 6c 65   # untested rule
1e80: 73 0a 20 20 20 20 20 20 20 20 69 20 3d 20 30 0a  s.        i = 0.
1e90: 20 20 20 20 20 20 20 20 66 6f 72 20 5f 2c 20 73          for _, s
1ea0: 4f 70 74 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52  Opt, sLineId, sR
1eb0: 75 6c 65 49 64 20 69 6e 20 67 63 65 2e 6c 69 73  uleId in gce.lis
1ec0: 74 52 75 6c 65 73 28 29 3a 0a 20 20 20 20 20 20  tRules():.      
1ed0: 20 20 20 20 20 20 69 66 20 73 4f 70 74 20 21 3d        if sOpt !=
1ee0: 20 22 40 40 40 40 22 20 61 6e 64 20 73 52 75 6c   "@@@@" and sRul
1ef0: 65 49 64 20 6e 6f 74 20 69 6e 20 73 65 6c 66 2e  eId not in self.
1f00: 5f 61 54 65 73 74 65 64 52 75 6c 65 73 20 61 6e  _aTestedRules an
1f10: 64 20 6e 6f 74 20 72 65 2e 73 65 61 72 63 68 28  d not re.search(
1f20: 22 5e 5b 30 2d 39 5d 2b 5b 73 70 5d 24 7c 5e 5b  "^[0-9]+[sp]$|^[
1f30: 70 64 5d 5f 22 2c 20 73 52 75 6c 65 49 64 29 3a  pd]_", sRuleId):
1f40: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1f50: 20 65 63 68 6f 28 73 4c 69 6e 65 49 64 20 2b 20   echo(sLineId + 
1f60: 22 2f 22 20 2b 20 73 52 75 6c 65 49 64 2c 20 65  "/" + sRuleId, e
1f70: 6e 64 3d 20 22 2c 20 22 29 0a 20 20 20 20 20 20  nd= ", ").      
1f80: 20 20 20 20 20 20 20 20 20 20 69 20 2b 3d 20 31            i += 1
1f90: 0a 20 20 20 20 20 20 20 20 69 66 20 69 3a 0a 20  .        if i:. 
1fa0: 20 20 20 20 20 20 20 20 20 20 20 65 63 68 6f 28             echo(
1fb0: 22 5c 6e 5b 7b 7d 20 75 6e 74 65 73 74 65 64 20  "\n[{} untested 
1fc0: 72 75 6c 65 73 5d 22 2e 66 6f 72 6d 61 74 28 69  rules]".format(i
1fd0: 29 29 0a 0a 20 20 20 20 64 65 66 20 5f 73 70 6c  ))..    def _spl
1fe0: 69 74 54 65 73 74 4c 69 6e 65 20 28 73 65 6c 66  itTestLine (self
1ff0: 2c 20 73 4c 69 6e 65 29 3a 0a 20 20 20 20 20 20  , sLine):.      
2000: 20 20 73 54 65 78 74 2c 20 73 53 75 67 67 20 3d    sText, sSugg =
2010: 20 73 4c 69 6e 65 2e 73 70 6c 69 74 28 22 2d 3e   sLine.split("->
2020: 3e 22 29 0a 20 20 20 20 20 20 20 20 72 65 74 75  >").        retu
2030: 72 6e 20 28 73 54 65 78 74 2e 73 74 72 69 70 28  rn (sText.strip(
2040: 29 2c 20 73 53 75 67 67 2e 73 74 72 69 70 28 29  ), sSugg.strip()
2050: 29 0a 0a 20 20 20 20 64 65 66 20 5f 67 65 74 46  )..    def _getF
2060: 6f 75 6e 64 45 72 72 6f 72 73 20 28 73 65 6c 66  oundErrors (self
2070: 2c 20 73 4c 69 6e 65 2c 20 73 4f 70 74 69 6f 6e  , sLine, sOption
2080: 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73 4f  ):.        if sO
2090: 70 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 20  ption:.         
20a0: 20 20 20 67 63 65 2e 73 65 74 4f 70 74 69 6f 6e     gce.setOption
20b0: 28 73 4f 70 74 69 6f 6e 2c 20 54 72 75 65 29 0a  (sOption, True).
20c0: 20 20 20 20 20 20 20 20 20 20 20 20 61 45 72 72              aErr
20d0: 73 20 3d 20 67 63 65 2e 70 61 72 73 65 28 73 4c  s = gce.parse(sL
20e0: 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20 20 20  ine).           
20f0: 20 67 63 65 2e 73 65 74 4f 70 74 69 6f 6e 28 73   gce.setOption(s
2100: 4f 70 74 69 6f 6e 2c 20 46 61 6c 73 65 29 0a 20  Option, False). 
2110: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
2120: 20 20 20 20 20 20 20 20 20 61 45 72 72 73 20 3d           aErrs =
2130: 20 67 63 65 2e 70 61 72 73 65 28 73 4c 69 6e 65   gce.parse(sLine
2140: 29 0a 20 20 20 20 20 20 20 20 73 52 65 73 20 3d  ).        sRes =
2150: 20 22 20 22 20 2a 20 6c 65 6e 28 73 4c 69 6e 65   " " * len(sLine
2160: 29 0a 20 20 20 20 20 20 20 20 73 4c 69 73 74 45  ).        sListE
2170: 72 72 20 3d 20 22 22 0a 20 20 20 20 20 20 20 20  rr = "".        
2180: 6c 41 6c 6c 53 75 67 67 20 3d 20 5b 5d 0a 20 20  lAllSugg = [].  
2190: 20 20 20 20 20 20 66 6f 72 20 64 45 72 72 20 69        for dErr i
21a0: 6e 20 61 45 72 72 73 3a 0a 20 20 20 20 20 20 20  n aErrs:.       
21b0: 20 20 20 20 20 73 52 65 73 20 3d 20 73 52 65 73       sRes = sRes
21c0: 5b 3a 64 45 72 72 5b 22 6e 53 74 61 72 74 22 5d  [:dErr["nStart"]
21d0: 5d 20 2b 20 22 7e 22 20 2a 20 28 64 45 72 72 5b  ] + "~" * (dErr[
21e0: 22 6e 45 6e 64 22 5d 20 2d 20 64 45 72 72 5b 22  "nEnd"] - dErr["
21f0: 6e 53 74 61 72 74 22 5d 29 20 2b 20 73 52 65 73  nStart"]) + sRes
2200: 5b 64 45 72 72 5b 22 6e 45 6e 64 22 5d 3a 5d 0a  [dErr["nEnd"]:].
2210: 20 20 20 20 20 20 20 20 20 20 20 20 73 4c 69 73              sLis
2220: 74 45 72 72 20 2b 3d 20 22 20 20 20 20 2a 20 7b  tErr += "    * {
2230: 73 4c 69 6e 65 49 64 7d 20 2f 20 7b 73 52 75 6c  sLineId} / {sRul
2240: 65 49 64 7d 20 20 61 74 20 20 7b 6e 53 74 61 72  eId}  at  {nStar
2250: 74 7d 3a 7b 6e 45 6e 64 7d 5c 6e 22 2e 66 6f 72  t}:{nEnd}\n".for
2260: 6d 61 74 28 2a 2a 64 45 72 72 29 0a 20 20 20 20  mat(**dErr).    
2270: 20 20 20 20 20 20 20 20 6c 41 6c 6c 53 75 67 67          lAllSugg
2280: 2e 61 70 70 65 6e 64 28 22 7c 22 2e 6a 6f 69 6e  .append("|".join
2290: 28 64 45 72 72 5b 22 61 53 75 67 67 65 73 74 69  (dErr["aSuggesti
22a0: 6f 6e 73 22 5d 29 29 0a 20 20 20 20 20 20 20 20  ons"])).        
22b0: 20 20 20 20 73 65 6c 66 2e 5f 61 54 65 73 74 65      self._aTeste
22c0: 64 52 75 6c 65 73 2e 61 64 64 28 64 45 72 72 5b  dRules.add(dErr[
22d0: 22 73 52 75 6c 65 49 64 22 5d 29 0a 20 20 20 20  "sRuleId"]).    
22e0: 20 20 20 20 20 20 20 20 23 20 74 65 73 74 20 6d          # test m
22f0: 65 73 73 61 67 65 73 0a 20 20 20 20 20 20 20 20  essages.        
2300: 20 20 20 20 69 66 20 22 3c 73 74 61 72 74 3e 22      if "<start>"
2310: 20 69 6e 20 64 45 72 72 5b 22 73 4d 65 73 73 61   in dErr["sMessa
2320: 67 65 22 5d 20 6f 72 20 22 3c 65 6e 64 3e 22 20  ge"] or "<end>" 
2330: 69 6e 20 64 45 72 72 5b 22 73 4d 65 73 73 61 67  in dErr["sMessag
2340: 65 22 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20  e"]:.           
2350: 20 20 20 20 20 70 72 69 6e 74 28 22 5c 6e 23 20       print("\n# 
2360: 4c 69 6e 65 20 6e 75 6d 20 3a 20 22 20 2b 20 64  Line num : " + d
2370: 45 72 72 5b 22 73 4c 69 6e 65 49 64 22 5d 20 2b  Err["sLineId"] +
2380: 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   \.             
2390: 20 20 20 20 20 20 20 20 20 22 5c 6e 20 20 72 75           "\n  ru
23a0: 6c 65 20 6e 61 6d 65 3a 20 22 20 2b 20 64 45 72  le name: " + dEr
23b0: 72 5b 22 73 52 75 6c 65 49 64 22 5d 20 2b 20 5c  r["sRuleId"] + \
23c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
23d0: 20 20 20 20 20 20 20 22 5c 6e 20 20 6d 65 73 73         "\n  mess
23e0: 61 67 65 20 20 3a 20 22 20 2b 20 64 45 72 72 5b  age  : " + dErr[
23f0: 22 73 4d 65 73 73 61 67 65 22 5d 29 0a 20 20 20  "sMessage"]).   
2400: 20 20 20 20 20 72 65 74 75 72 6e 20 73 52 65 73       return sRes
2410: 2c 20 73 4c 69 73 74 45 72 72 2c 20 22 7c 7c 7c  , sListErr, "|||
2420: 22 2e 6a 6f 69 6e 28 6c 41 6c 6c 53 75 67 67 29  ".join(lAllSugg)
2430: 0a 0a 20 20 20 20 64 65 66 20 5f 67 65 74 45 78  ..    def _getEx
2440: 70 65 63 74 65 64 45 72 72 6f 72 73 20 28 73 65  pectedErrors (se
2450: 6c 66 2c 20 73 4c 69 6e 65 29 3a 0a 20 20 20 20  lf, sLine):.    
2460: 20 20 20 20 73 52 65 73 20 3d 20 22 20 22 20 2a      sRes = " " *
2470: 20 6c 65 6e 28 73 4c 69 6e 65 29 0a 20 20 20 20   len(sLine).    
2480: 20 20 20 20 66 6f 72 20 69 2c 20 6d 20 69 6e 20      for i, m in 
2490: 65 6e 75 6d 65 72 61 74 65 28 73 65 6c 66 2e 5f  enumerate(self._
24a0: 7a 45 72 72 6f 72 2e 66 69 6e 64 69 74 65 72 28  zError.finditer(
24b0: 73 4c 69 6e 65 29 29 3a 0a 20 20 20 20 20 20 20  sLine)):.       
24c0: 20 20 20 20 20 6e 53 74 61 72 74 20 3d 20 6d 2e       nStart = m.
24d0: 73 74 61 72 74 28 29 20 2d 20 28 34 20 2a 20 69  start() - (4 * i
24e0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 45  ).            nE
24f0: 6e 64 20 3d 20 6d 2e 65 6e 64 28 29 20 2d 20 28  nd = m.end() - (
2500: 34 20 2a 20 28 69 2b 31 29 29 0a 20 20 20 20 20  4 * (i+1)).     
2510: 20 20 20 20 20 20 20 73 52 65 73 20 3d 20 73 52         sRes = sR
2520: 65 73 5b 3a 6e 53 74 61 72 74 5d 20 2b 20 22 7e  es[:nStart] + "~
2530: 22 20 2a 20 28 6e 45 6e 64 20 2d 20 6e 53 74 61  " * (nEnd - nSta
2540: 72 74 29 20 2b 20 73 52 65 73 5b 6e 45 6e 64 3a  rt) + sRes[nEnd:
2550: 2d 34 5d 0a 20 20 20 20 20 20 20 20 72 65 74 75  -4].        retu
2560: 72 6e 20 73 52 65 73 0a 0a 0a 64 65 66 20 6d 61  rn sRes...def ma
2570: 69 6e 28 29 3a 0a 20 20 20 20 22 73 74 61 72 74  in():.    "start
2580: 20 66 75 6e 63 74 69 6f 6e 22 0a 20 20 20 20 75   function".    u
2590: 6e 69 74 74 65 73 74 2e 6d 61 69 6e 28 29 0a 0a  nittest.main()..
25a0: 0a 69 66 20 5f 5f 6e 61 6d 65 5f 5f 20 3d 3d 20  .if __name__ == 
25b0: 27 5f 5f 6d 61 69 6e 5f 5f 27 3a 0a 20 20 20 20  '__main__':.    
25c0: 6d 61 69 6e 28 29 0a                             main().