test_gettext.py revision be8d06f5234ace688520bfea9139e68214788910
19e035921494cb8f101c3bfc22956fa968c6ab41fBarry Warsawimport os 2ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsawimport base64 3a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawimport shutil 49e035921494cb8f101c3bfc22956fa968c6ab41fBarry Warsawimport gettext 5d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwisimport unittest 6a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw 7ee8712cda46338d223509cc5751fd36509ad3860Benjamin Petersonfrom test import support 8a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw 9004d5e6880940ddbb38460986ac62ee0f1bae97dFred Drake 10d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# TODO: 11d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# - Add new tests, for example for "dgettext" 12d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# - Remove dummy tests, for example testing for single and double quotes 13d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# has no sense, it would have if we were testing a parser (i.e. pygettext) 14d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# - Tests should have only one assert. 1564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 1639478e852827a4ca6955151bf004c7a15099a4b1Guido van RossumGNU_MO_DATA = b'''\ 17d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis3hIElQAAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj 18d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisAAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD 19d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisAAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh 20d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwiseW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU 21d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisaGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u 22d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisCnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh 23d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisY2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51 24d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt 25d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisMDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k 26d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisYXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN 27d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisSU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4 28d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisNTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0 29d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0 30d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwisd29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo 31d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwiseXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn 32d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisIHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1 33d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA== 34d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis''' 35d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 36be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou# This data contains an invalid major version number (5) 37be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou# An unexpected major version number should be treated as an error when 38be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou# parsing a .mo file 39be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou 40be8d06f5234ace688520bfea9139e68214788910Antoine PitrouGNU_MO_DATA_BAD_MAJOR_VERSION = b'''\ 41be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou3hIElQAABQAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj 42be8d06f5234ace688520bfea9139e68214788910Antoine PitrouAAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD 43be8d06f5234ace688520bfea9139e68214788910Antoine PitrouAAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh 44be8d06f5234ace688520bfea9139e68214788910Antoine PitroueW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU 45be8d06f5234ace688520bfea9139e68214788910Antoine PitrouaGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u 46be8d06f5234ace688520bfea9139e68214788910Antoine PitrouCnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh 47be8d06f5234ace688520bfea9139e68214788910Antoine PitrouY2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51 48be8d06f5234ace688520bfea9139e68214788910Antoine PitrouZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt 49be8d06f5234ace688520bfea9139e68214788910Antoine PitrouMDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k 50be8d06f5234ace688520bfea9139e68214788910Antoine PitrouYXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN 51be8d06f5234ace688520bfea9139e68214788910Antoine PitrouSU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4 52be8d06f5234ace688520bfea9139e68214788910Antoine PitrouNTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0 53be8d06f5234ace688520bfea9139e68214788910Antoine PitrouZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0 54be8d06f5234ace688520bfea9139e68214788910Antoine Pitroud29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo 55be8d06f5234ace688520bfea9139e68214788910Antoine PitroueXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn 56be8d06f5234ace688520bfea9139e68214788910Antoine PitrouIHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1 57be8d06f5234ace688520bfea9139e68214788910Antoine PitrouciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA== 58be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou''' 59be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou 60be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou# This data contains an invalid minor version number (7) 61be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou# An unexpected minor version number only indicates that some of the file's 62be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou# contents may not be able to be read. It does not indicate an error. 63be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou 64be8d06f5234ace688520bfea9139e68214788910Antoine PitrouGNU_MO_DATA_BAD_MINOR_VERSION = b'''\ 65be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou3hIElQcAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj 66be8d06f5234ace688520bfea9139e68214788910Antoine PitrouAAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD 67be8d06f5234ace688520bfea9139e68214788910Antoine PitrouAAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh 68be8d06f5234ace688520bfea9139e68214788910Antoine PitroueW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU 69be8d06f5234ace688520bfea9139e68214788910Antoine PitrouaGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u 70be8d06f5234ace688520bfea9139e68214788910Antoine PitrouCnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh 71be8d06f5234ace688520bfea9139e68214788910Antoine PitrouY2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51 72be8d06f5234ace688520bfea9139e68214788910Antoine PitrouZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt 73be8d06f5234ace688520bfea9139e68214788910Antoine PitrouMDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k 74be8d06f5234ace688520bfea9139e68214788910Antoine PitrouYXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN 75be8d06f5234ace688520bfea9139e68214788910Antoine PitrouSU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4 76be8d06f5234ace688520bfea9139e68214788910Antoine PitrouNTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0 77be8d06f5234ace688520bfea9139e68214788910Antoine PitrouZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0 78be8d06f5234ace688520bfea9139e68214788910Antoine Pitroud29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo 79be8d06f5234ace688520bfea9139e68214788910Antoine PitroueXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn 80be8d06f5234ace688520bfea9139e68214788910Antoine PitrouIHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1 81be8d06f5234ace688520bfea9139e68214788910Antoine PitrouciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA== 82be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou''' 83be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou 84be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou 8539478e852827a4ca6955151bf004c7a15099a4b1Guido van RossumUMO_DATA = b'''\ 86a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw3hIElQAAAAACAAAAHAAAACwAAAAFAAAAPAAAAAAAAABQAAAABAAAAFEAAAAPAQAAVgAAAAQAAABm 87a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsawAQAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAYWLDngBQcm9qZWN0LUlkLVZlcnNpb246IDIuMApQTy1S 88a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsawZXZpc2lvbi1EYXRlOiAyMDAzLTA0LTExIDEyOjQyLTA0MDAKTGFzdC1UcmFuc2xhdG9yOiBCYXJy 89a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsaweSBBLiBXQXJzYXcgPGJhcnJ5QHB5dGhvbi5vcmc+Ckxhbmd1YWdlLVRlYW06IFhYIDxweXRob24t 90a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsawZGV2QHB5dGhvbi5vcmc+Ck1JTUUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFp 91a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsawbjsgY2hhcnNldD11dGYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0CkdlbmVyYXRl 92a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsawZC1CeTogbWFudWFsbHkKAMKkeXoA 93a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw''' 94d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 9539478e852827a4ca6955151bf004c7a15099a4b1Guido van RossumMMO_DATA = b'''\ 96e960e22579838419541357712bbbc3317c219071Barry Warsaw3hIElQAAAAABAAAAHAAAACQAAAADAAAALAAAAAAAAAA4AAAAeAEAADkAAAABAAAAAAAAAAAAAAAA 97e960e22579838419541357712bbbc3317c219071Barry WarsawUHJvamVjdC1JZC1WZXJzaW9uOiBObyBQcm9qZWN0IDAuMApQT1QtQ3JlYXRpb24tRGF0ZTogV2Vk 98e960e22579838419541357712bbbc3317c219071Barry WarsawIERlYyAxMSAwNzo0NDoxNSAyMDAyClBPLVJldmlzaW9uLURhdGU6IDIwMDItMDgtMTQgMDE6MTg6 99e960e22579838419541357712bbbc3317c219071Barry WarsawNTgrMDA6MDAKTGFzdC1UcmFuc2xhdG9yOiBKb2huIERvZSA8amRvZUBleGFtcGxlLmNvbT4KSmFu 100e960e22579838419541357712bbbc3317c219071Barry WarsawZSBGb29iYXIgPGpmb29iYXJAZXhhbXBsZS5jb20+Ckxhbmd1YWdlLVRlYW06IHh4IDx4eEBleGFt 101e960e22579838419541357712bbbc3317c219071Barry WarsawcGxlLmNvbT4KTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFy 102e960e22579838419541357712bbbc3317c219071Barry Warsawc2V0PWlzby04ODU5LTE1CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IHF1b3RlZC1wcmludGFi 103e960e22579838419541357712bbbc3317c219071Barry WarsawbGUKR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgMS4zCgA= 104e960e22579838419541357712bbbc3317c219071Barry Warsaw''' 105e960e22579838419541357712bbbc3317c219071Barry Warsaw 106d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisLOCALEDIR = os.path.join('xx', 'LC_MESSAGES') 107d899605e30eef8e77f70184eac15fad1bf770586Martin v. LöwisMOFILE = os.path.join(LOCALEDIR, 'gettext.mo') 108be8d06f5234ace688520bfea9139e68214788910Antoine PitrouMOFILE_BAD_MAJOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_major_version.mo') 109be8d06f5234ace688520bfea9139e68214788910Antoine PitrouMOFILE_BAD_MINOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_minor_version.mo') 110a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry WarsawUMOFILE = os.path.join(LOCALEDIR, 'ugettext.mo') 111e960e22579838419541357712bbbc3317c219071Barry WarsawMMOFILE = os.path.join(LOCALEDIR, 'metadata.mo') 112d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 113d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 114a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawclass GettextBaseTest(unittest.TestCase): 115a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw def setUp(self): 116a0e0cd3013840299a789f05be239d6ecb6387cdfNeal Norwitz if not os.path.isdir(LOCALEDIR): 117a0e0cd3013840299a789f05be239d6ecb6387cdfNeal Norwitz os.makedirs(LOCALEDIR) 1187fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo with open(MOFILE, 'wb') as fp: 1197fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo fp.write(base64.decodebytes(GNU_MO_DATA)) 120be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou with open(MOFILE_BAD_MAJOR_VERSION, 'wb') as fp: 121be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MAJOR_VERSION)) 122be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou with open(MOFILE_BAD_MINOR_VERSION, 'wb') as fp: 123be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MINOR_VERSION)) 1247fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo with open(UMOFILE, 'wb') as fp: 1257fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo fp.write(base64.decodebytes(UMO_DATA)) 1267fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo with open(MMOFILE, 'wb') as fp: 1277fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo fp.write(base64.decodebytes(MMO_DATA)) 128155374d95d8ecd235d3a3edd92dd6f6a23d59f11Walter Dörwald self.env = support.EnvironmentVarGuard() 129155374d95d8ecd235d3a3edd92dd6f6a23d59f11Walter Dörwald self.env['LANGUAGE'] = 'xx' 13037a89334da1fbe5b30f5a03a97b8f8c2a59adc1bÉric Araujo gettext._translations.clear() 131a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw 132a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw def tearDown(self): 133155374d95d8ecd235d3a3edd92dd6f6a23d59f11Walter Dörwald self.env.__exit__() 134155374d95d8ecd235d3a3edd92dd6f6a23d59f11Walter Dörwald del self.env 135cdb2c601db078e0af2fcca49341a7d17d603e500Victor Stinner support.rmtree(os.path.split(LOCALEDIR)[0]) 136d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 137ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw 138a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawclass GettextTestCase1(GettextBaseTest): 139d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def setUp(self): 140a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw GettextBaseTest.setUp(self) 141d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis self.localedir = os.curdir 142d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis self.mofile = MOFILE 143d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis gettext.install('gettext', self.localedir) 144ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw 145d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_some_translations(self): 146a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 147d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # test some translations 148a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(_('albatross'), 'albatross') 149ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(_('mullusk'), 'bacon') 150a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(_(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove') 151ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(_(r'nudge nudge'), 'wink wink') 152d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 153d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_double_quotes(self): 154a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 155d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # double quotes 156a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(_("albatross"), 'albatross') 157ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(_("mullusk"), 'bacon') 158a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(_(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove') 159ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(_(r"nudge nudge"), 'wink wink') 160d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 161d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_triple_single_quotes(self): 162a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 163d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # triple single quotes 164a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(_('''albatross'''), 'albatross') 165ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(_('''mullusk'''), 'bacon') 166a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(_(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove') 167ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(_(r'''nudge nudge'''), 'wink wink') 168d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 169d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_triple_double_quotes(self): 170a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 171d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # triple double quotes 172a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(_("""albatross"""), 'albatross') 173ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(_("""mullusk"""), 'bacon') 174a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(_(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove') 175ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(_(r"""nudge nudge"""), 'wink wink') 176d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 177d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_multiline_strings(self): 178a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 179d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # multiline strings 180a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(_('''This module provides internationalization and localization 1819e035921494cb8f101c3bfc22956fa968c6ab41fBarry Warsawsupport for your Python programs by providing an interface to the GNU 182a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawgettext message catalog library.'''), 183a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba 184d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwisfhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH 185a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawtrggrkg zrffntr pngnybt yvoenel.''') 186ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw 187d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_the_alternative_interface(self): 188a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 189d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # test the alternative interface 1907fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo with open(self.mofile, 'rb') as fp: 1917fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo t = gettext.GNUTranslations(fp) 192a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw # Install the translation object 193d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis t.install() 194a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(_('nudge nudge'), 'wink wink') 195a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw # Try unicode return type 196801844d6fc8b48cfa969dd2573bd522a2b26f974Benjamin Peterson t.install() 197a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(_('mullusk'), 'bacon') 198602b9ba6b37c4ac4ed445f8c9e9dccd68d631899Georg Brandl # Test installation of other methods 1991a3284ed69d545e4ef59869998cb8c29233a45faGeorg Brandl import builtins 200801844d6fc8b48cfa969dd2573bd522a2b26f974Benjamin Peterson t.install(names=["gettext", "lgettext"]) 201801844d6fc8b48cfa969dd2573bd522a2b26f974Benjamin Peterson eq(_, t.gettext) 202801844d6fc8b48cfa969dd2573bd522a2b26f974Benjamin Peterson eq(builtins.gettext, t.gettext) 203602b9ba6b37c4ac4ed445f8c9e9dccd68d631899Georg Brandl eq(lgettext, t.lgettext) 2041a3284ed69d545e4ef59869998cb8c29233a45faGeorg Brandl del builtins.gettext 2051a3284ed69d545e4ef59869998cb8c29233a45faGeorg Brandl del builtins.lgettext 206d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 207ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw 208a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawclass GettextTestCase2(GettextBaseTest): 209d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def setUp(self): 210a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw GettextBaseTest.setUp(self) 211d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis self.localedir = os.curdir 212a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw # Set up the bindings 213d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis gettext.bindtextdomain('gettext', self.localedir) 214d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis gettext.textdomain('gettext') 215a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw # For convenience 216d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis self._ = gettext.gettext 21764dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 218d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_bindtextdomain(self): 219a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw self.assertEqual(gettext.bindtextdomain('gettext'), self.localedir) 22064dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 221d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_textdomain(self): 222a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw self.assertEqual(gettext.textdomain(), 'gettext') 22364dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 224be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou def test_bad_major_version(self): 225be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou with open(MOFILE_BAD_MAJOR_VERSION, 'rb') as fp: 226be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou with self.assertRaises(OSError) as cm: 227be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou gettext.GNUTranslations(fp) 228be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou 229be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou exception = cm.exception 230be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou self.assertEqual(exception.errno, 0) 231be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou self.assertEqual(exception.strerror, "Bad version number 5") 232be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou self.assertEqual(exception.filename, MOFILE_BAD_MAJOR_VERSION) 233be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou 234be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou def test_bad_minor_version(self): 235be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou with open(MOFILE_BAD_MINOR_VERSION, 'rb') as fp: 236be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou # Check that no error is thrown with a bad minor version number 237be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou gettext.GNUTranslations(fp) 238be8d06f5234ace688520bfea9139e68214788910Antoine Pitrou 239d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_some_translations(self): 240a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 241d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # test some translations 242a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(self._('albatross'), 'albatross') 243ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(self._('mullusk'), 'bacon') 244a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(self._(r'Raymond Luxury Yach-t'), 'Throatwobbler Mangrove') 245ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(self._(r'nudge nudge'), 'wink wink') 24664dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 247d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_double_quotes(self): 248a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 249d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # double quotes 250a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(self._("albatross"), 'albatross') 251ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(self._("mullusk"), 'bacon') 252a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(self._(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove') 253ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(self._(r"nudge nudge"), 'wink wink') 254d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 255d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_triple_single_quotes(self): 256a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 257d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # triple single quotes 258a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(self._('''albatross'''), 'albatross') 259ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(self._('''mullusk'''), 'bacon') 260a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(self._(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove') 261ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(self._(r'''nudge nudge'''), 'wink wink') 262d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 263d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_triple_double_quotes(self): 264a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 265d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # triple double quotes 266a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(self._("""albatross"""), 'albatross') 267ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(self._("""mullusk"""), 'bacon') 268a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(self._(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove') 269ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(self._(r"""nudge nudge"""), 'wink wink') 270d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 271d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_multiline_strings(self): 272a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 273d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # multiline strings 274a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(self._('''This module provides internationalization and localization 27564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawsupport for your Python programs by providing an interface to the GNU 276a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawgettext message catalog library.'''), 277a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw '''Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba 278d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwisfhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH 279a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawtrggrkg zrffntr pngnybt yvoenel.''') 28064dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 28164dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 282a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawclass PluralFormsTestCase(GettextBaseTest): 283d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def setUp(self): 284a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw GettextBaseTest.setUp(self) 285d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis self.mofile = MOFILE 286ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw 287d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_plural_forms1(self): 288a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 289d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis x = gettext.ngettext('There is %s file', 'There are %s files', 1) 290a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(x, 'Hay %s fichero') 291d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis x = gettext.ngettext('There is %s file', 'There are %s files', 2) 292a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(x, 'Hay %s ficheros') 293ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw 294d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_plural_forms2(self): 295a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 2967fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo with open(self.mofile, 'rb') as fp: 2977fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo t = gettext.GNUTranslations(fp) 298d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis x = t.ngettext('There is %s file', 'There are %s files', 1) 299a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(x, 'Hay %s fichero') 300d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis x = t.ngettext('There is %s file', 'There are %s files', 2) 301a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(x, 'Hay %s ficheros') 302d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 303d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_hu(self): 304a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 305d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis f = gettext.c2py('0') 306d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis s = ''.join([ str(f(x)) for x in range(200) ]) 307a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(s, "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") 308d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 309d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_de(self): 310a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 311d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis f = gettext.c2py('n != 1') 312d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis s = ''.join([ str(f(x)) for x in range(200) ]) 313a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(s, "10111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") 314d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 315d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_fr(self): 316a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 317d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis f = gettext.c2py('n>1') 318d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis s = ''.join([ str(f(x)) for x in range(200) ]) 319a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(s, "00111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") 320ff6d8136574e9f4e1b11f75a945af5f8ab44a6fdBarry Warsaw 321d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_gd(self): 322a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 323d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis f = gettext.c2py('n==1 ? 0 : n==2 ? 1 : 2') 324d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis s = ''.join([ str(f(x)) for x in range(200) ]) 325a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222") 326d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 327d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_gd2(self): 328a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 329d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # Tests the combination of parentheses and "?:" 330d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis f = gettext.c2py('n==1 ? 0 : (n==2 ? 1 : 2)') 331d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis s = ''.join([ str(f(x)) for x in range(200) ]) 332a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(s, "20122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222") 333d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 334d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_lt(self): 335a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 336d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2') 337d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis s = ''.join([ str(f(x)) for x in range(200) ]) 338a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(s, "20111111112222222222201111111120111111112011111111201111111120111111112011111111201111111120111111112011111111222222222220111111112011111111201111111120111111112011111111201111111120111111112011111111") 339d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 340d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_ru(self): 341a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 342d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis f = gettext.c2py('n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2') 343d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis s = ''.join([ str(f(x)) for x in range(200) ]) 344a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(s, "20111222222222222222201112222220111222222011122222201112222220111222222011122222201112222220111222222011122222222222222220111222222011122222201112222220111222222011122222201112222220111222222011122222") 345d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 346d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_pl(self): 347a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 348d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis f = gettext.c2py('n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2') 349d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis s = ''.join([ str(f(x)) for x in range(200) ]) 350a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(s, "20111222222222222222221112222222111222222211122222221112222222111222222211122222221112222222111222222211122222222222222222111222222211122222221112222222111222222211122222221112222222111222222211122222") 351d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 352d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_sl(self): 353a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 354d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis f = gettext.c2py('n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3') 355d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis s = ''.join([ str(f(x)) for x in range(200) ]) 356a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq(s, "30122333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333012233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333") 357d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 358d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis def test_security(self): 359a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw raises = self.assertRaises 360d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis # Test for a dangerous expression 361a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw raises(ValueError, gettext.c2py, "os.chmod('/etc/passwd',0777)") 362a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw 363a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw 364a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawclass UnicodeTranslationsTest(GettextBaseTest): 365a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw def setUp(self): 366a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw GettextBaseTest.setUp(self) 3677fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo with open(UMOFILE, 'rb') as fp: 368edb155fda199f7fa481d0020e911a6eec0705dfaBarry Warsaw self.t = gettext.GNUTranslations(fp) 369801844d6fc8b48cfa969dd2573bd522a2b26f974Benjamin Peterson self._ = self.t.gettext 370d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 371a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw def test_unicode_msgid(self): 372c9c0f201fed21efcf669dbbf5f923eaf0eeb1db9Benjamin Peterson unless = self.assertTrue 373ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum unless(isinstance(self._(''), str)) 374ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum unless(isinstance(self._(''), str)) 375d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 376a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw def test_unicode_msgstr(self): 377a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw eq = self.assertEqual 378ef87d6ed94780fe00250a551031023aeb2898365Guido van Rossum eq(self._('ab\xde'), '\xa4yz') 379d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 380d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 381e960e22579838419541357712bbbc3317c219071Barry Warsawclass WeirdMetadataTest(GettextBaseTest): 382e960e22579838419541357712bbbc3317c219071Barry Warsaw def setUp(self): 383e960e22579838419541357712bbbc3317c219071Barry Warsaw GettextBaseTest.setUp(self) 3847fa886df3622bbedbeb9c2486a8af5f05334a928Éric Araujo with open(MMOFILE, 'rb') as fp: 385e960e22579838419541357712bbbc3317c219071Barry Warsaw try: 386e960e22579838419541357712bbbc3317c219071Barry Warsaw self.t = gettext.GNUTranslations(fp) 387e960e22579838419541357712bbbc3317c219071Barry Warsaw except: 388e960e22579838419541357712bbbc3317c219071Barry Warsaw self.tearDown() 389e960e22579838419541357712bbbc3317c219071Barry Warsaw raise 390e960e22579838419541357712bbbc3317c219071Barry Warsaw 391e960e22579838419541357712bbbc3317c219071Barry Warsaw def test_weird_metadata(self): 392e960e22579838419541357712bbbc3317c219071Barry Warsaw info = self.t.info() 3936ae5d7f2a132aa9690bfb59b8eebcc1fb7c792c8Christian Heimes self.assertEqual(len(info), 9) 394e960e22579838419541357712bbbc3317c219071Barry Warsaw self.assertEqual(info['last-translator'], 395e960e22579838419541357712bbbc3317c219071Barry Warsaw 'John Doe <jdoe@example.com>\nJane Foobar <jfoobar@example.com>') 396e960e22579838419541357712bbbc3317c219071Barry Warsaw 397e960e22579838419541357712bbbc3317c219071Barry Warsaw 3986108bf5ed002925f2092deb025f336d8c2024299Éric Araujoclass DummyGNUTranslations(gettext.GNUTranslations): 3996108bf5ed002925f2092deb025f336d8c2024299Éric Araujo def foo(self): 4006108bf5ed002925f2092deb025f336d8c2024299Éric Araujo return 'foo' 4016108bf5ed002925f2092deb025f336d8c2024299Éric Araujo 4026108bf5ed002925f2092deb025f336d8c2024299Éric Araujo 4036108bf5ed002925f2092deb025f336d8c2024299Éric Araujoclass GettextCacheTestCase(GettextBaseTest): 4046108bf5ed002925f2092deb025f336d8c2024299Éric Araujo def test_cache(self): 4056108bf5ed002925f2092deb025f336d8c2024299Éric Araujo self.localedir = os.curdir 4066108bf5ed002925f2092deb025f336d8c2024299Éric Araujo self.mofile = MOFILE 4076108bf5ed002925f2092deb025f336d8c2024299Éric Araujo 4086108bf5ed002925f2092deb025f336d8c2024299Éric Araujo self.assertEqual(len(gettext._translations), 0) 4096108bf5ed002925f2092deb025f336d8c2024299Éric Araujo 4106108bf5ed002925f2092deb025f336d8c2024299Éric Araujo t = gettext.translation('gettext', self.localedir) 4116108bf5ed002925f2092deb025f336d8c2024299Éric Araujo 4126108bf5ed002925f2092deb025f336d8c2024299Éric Araujo self.assertEqual(len(gettext._translations), 1) 4136108bf5ed002925f2092deb025f336d8c2024299Éric Araujo 4146108bf5ed002925f2092deb025f336d8c2024299Éric Araujo t = gettext.translation('gettext', self.localedir, 4156108bf5ed002925f2092deb025f336d8c2024299Éric Araujo class_=DummyGNUTranslations) 4166108bf5ed002925f2092deb025f336d8c2024299Éric Araujo 4176108bf5ed002925f2092deb025f336d8c2024299Éric Araujo self.assertEqual(len(gettext._translations), 2) 4186108bf5ed002925f2092deb025f336d8c2024299Éric Araujo self.assertEqual(t.__class__, DummyGNUTranslations) 4196108bf5ed002925f2092deb025f336d8c2024299Éric Araujo 4206108bf5ed002925f2092deb025f336d8c2024299Éric Araujo # Calling it again doesn't add to the cache 4216108bf5ed002925f2092deb025f336d8c2024299Éric Araujo 4226108bf5ed002925f2092deb025f336d8c2024299Éric Araujo t = gettext.translation('gettext', self.localedir, 4236108bf5ed002925f2092deb025f336d8c2024299Éric Araujo class_=DummyGNUTranslations) 4246108bf5ed002925f2092deb025f336d8c2024299Éric Araujo 4256108bf5ed002925f2092deb025f336d8c2024299Éric Araujo self.assertEqual(len(gettext._translations), 2) 4266108bf5ed002925f2092deb025f336d8c2024299Éric Araujo self.assertEqual(t.__class__, DummyGNUTranslations) 4276108bf5ed002925f2092deb025f336d8c2024299Éric Araujo 4286108bf5ed002925f2092deb025f336d8c2024299Éric Araujo 429a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawdef test_main(): 430ee8712cda46338d223509cc5751fd36509ad3860Benjamin Peterson support.run_unittest(__name__) 431004d5e6880940ddbb38460986ac62ee0f1bae97dFred Drake 432a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawif __name__ == '__main__': 433a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw test_main() 434a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw 435a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw 436a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# For reference, here's the .po file used to created the GNU_MO_DATA above. 437d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# 438d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# The original version was automatically generated from the sources with 439d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# pygettext. Later it was manually modified to add plural forms support. 44064dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 44164dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw''' 442a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# Dummy translation for the Python test_gettext.py module. 443191487351abb5d2b7daf9d839ca2b3a3c7fdc07bBarry Warsaw# Copyright (C) 2001 Python Software Foundation 444191487351abb5d2b7daf9d839ca2b3a3c7fdc07bBarry Warsaw# Barry Warsaw <barry@python.org>, 2000. 44564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw# 44664dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgid "" 44764dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgstr "" 44864dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"Project-Id-Version: 2.0\n" 449a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"PO-Revision-Date: 2003-04-11 14:32-0400\n" 450d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis"Last-Translator: J. David Ibanez <j-david@noos.fr>\n" 45164dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"Language-Team: XX <python-dev@python.org>\n" 45264dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"MIME-Version: 1.0\n" 453d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis"Content-Type: text/plain; charset=iso-8859-1\n" 454d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis"Content-Transfer-Encoding: 8bit\n" 45564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"Generated-By: pygettext.py 1.1\n" 456d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis"Plural-Forms: nplurals=2; plural=n!=1;\n" 45764dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 45864dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:19 test_gettext.py:25 test_gettext.py:31 test_gettext.py:37 45964dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:51 test_gettext.py:80 test_gettext.py:86 test_gettext.py:92 46064dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:98 46164dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgid "nudge nudge" 46264dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgstr "wink wink" 46364dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 46464dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:16 test_gettext.py:22 test_gettext.py:28 test_gettext.py:34 46564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:77 test_gettext.py:83 test_gettext.py:89 test_gettext.py:95 46664dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgid "albatross" 46764dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgstr "" 46864dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 46964dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:18 test_gettext.py:24 test_gettext.py:30 test_gettext.py:36 47064dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:79 test_gettext.py:85 test_gettext.py:91 test_gettext.py:97 47164dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgid "Raymond Luxury Yach-t" 47264dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgstr "Throatwobbler Mangrove" 47364dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 47464dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:17 test_gettext.py:23 test_gettext.py:29 test_gettext.py:35 47564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:56 test_gettext.py:78 test_gettext.py:84 test_gettext.py:90 47664dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:96 47764dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgid "mullusk" 47864dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgstr "bacon" 47964dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw 48064dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw#: test_gettext.py:40 test_gettext.py:101 48164dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgid "" 48264dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"This module provides internationalization and localization\n" 48364dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"support for your Python programs by providing an interface to the GNU\n" 48464dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"gettext message catalog library." 48564dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsawmsgstr "" 48664dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"Guvf zbqhyr cebivqrf vagreangvbanyvmngvba naq ybpnyvmngvba\n" 48764dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"fhccbeg sbe lbhe Clguba cebtenzf ol cebivqvat na vagresnpr gb gur TAH\n" 48864dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw"trggrkg zrffntr pngnybt yvoenel." 489d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis 490d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# Manually added, as neither pygettext nor xgettext support plural forms 491d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwis# in Python. 492d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwismsgid "There is %s file" 493d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwismsgid_plural "There are %s files" 494d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwismsgstr[0] "Hay %s fichero" 495d899605e30eef8e77f70184eac15fad1bf770586Martin v. Löwismsgstr[1] "Hay %s ficheros" 49664dab4602e17878e816ae1d3f48b2f589ceebdfbBarry Warsaw''' 497a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw 498a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# Here's the second example po file example, used to generate the UMO_DATA 499a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# containing utf-8 encoded Unicode strings 500a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw 501a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw''' 502a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# Dummy translation for the Python test_gettext.py module. 503a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# Copyright (C) 2001 Python Software Foundation 504a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# Barry Warsaw <barry@python.org>, 2000. 505a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw# 506a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawmsgid "" 507a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawmsgstr "" 508a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"Project-Id-Version: 2.0\n" 509a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"PO-Revision-Date: 2003-04-11 12:42-0400\n" 510a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"Last-Translator: Barry A. WArsaw <barry@python.org>\n" 511a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"Language-Team: XX <python-dev@python.org>\n" 512a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"MIME-Version: 1.0\n" 513a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"Content-Type: text/plain; charset=utf-8\n" 514a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"Content-Transfer-Encoding: 7bit\n" 515a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw"Generated-By: manually\n" 516a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw 517a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw#: nofile:0 518a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawmsgid "ab\xc3\x9e" 519a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsawmsgstr "\xc2\xa4yz" 520a1ce93f87cb221be9a7466c2f9d2b7dc494f458dBarry Warsaw''' 521e960e22579838419541357712bbbc3317c219071Barry Warsaw 522e960e22579838419541357712bbbc3317c219071Barry Warsaw# Here's the third example po file, used to generate MMO_DATA 523e960e22579838419541357712bbbc3317c219071Barry Warsaw 524e960e22579838419541357712bbbc3317c219071Barry Warsaw''' 525e960e22579838419541357712bbbc3317c219071Barry Warsawmsgid "" 526e960e22579838419541357712bbbc3317c219071Barry Warsawmsgstr "" 527e960e22579838419541357712bbbc3317c219071Barry Warsaw"Project-Id-Version: No Project 0.0\n" 528e960e22579838419541357712bbbc3317c219071Barry Warsaw"POT-Creation-Date: Wed Dec 11 07:44:15 2002\n" 529e960e22579838419541357712bbbc3317c219071Barry Warsaw"PO-Revision-Date: 2002-08-14 01:18:58+00:00\n" 530e960e22579838419541357712bbbc3317c219071Barry Warsaw"Last-Translator: John Doe <jdoe@example.com>\n" 531e960e22579838419541357712bbbc3317c219071Barry Warsaw"Jane Foobar <jfoobar@example.com>\n" 532e960e22579838419541357712bbbc3317c219071Barry Warsaw"Language-Team: xx <xx@example.com>\n" 533e960e22579838419541357712bbbc3317c219071Barry Warsaw"MIME-Version: 1.0\n" 534e960e22579838419541357712bbbc3317c219071Barry Warsaw"Content-Type: text/plain; charset=iso-8859-15\n" 535e960e22579838419541357712bbbc3317c219071Barry Warsaw"Content-Transfer-Encoding: quoted-printable\n" 536e960e22579838419541357712bbbc3317c219071Barry Warsaw"Generated-By: pygettext.py 1.3\n" 537e960e22579838419541357712bbbc3317c219071Barry Warsaw''' 538