Best Python code snippet using pyatom_python
test__header_value_parser.py
Source:test__header_value_parser.py
1import string2import unittest3from email import _header_value_parser as parser4from email import errors5from email import policy6from test.test_email import TestEmailBase, parameterize7class TestTokens(TestEmailBase):8 # EWWhiteSpaceTerminal9 def test_EWWhiteSpaceTerminal(self):10 x = parser.EWWhiteSpaceTerminal(' \t', 'fws')11 self.assertEqual(x, ' \t')12 self.assertEqual(str(x), '')13 self.assertEqual(x.value, '')14 self.assertEqual(x.encoded, ' \t')15 # UnstructuredTokenList16 def test_undecodable_bytes_error_preserved(self):17 badstr = b"le pouf c\xaflebre".decode('ascii', 'surrogateescape')18 unst = parser.get_unstructured(badstr)19 self.assertDefectsEqual(unst.all_defects, [errors.UndecodableBytesDefect])20 parts = list(unst.parts)21 self.assertDefectsEqual(parts[0].all_defects, [])22 self.assertDefectsEqual(parts[1].all_defects, [])23 self.assertDefectsEqual(parts[2].all_defects, [errors.UndecodableBytesDefect])24class TestParserMixin:25 def _assert_results(self, tl, rest, string, value, defects, remainder,26 comments=None):27 self.assertEqual(str(tl), string)28 self.assertEqual(tl.value, value)29 self.assertDefectsEqual(tl.all_defects, defects)30 self.assertEqual(rest, remainder)31 if comments is not None:32 self.assertEqual(tl.comments, comments)33 def _test_get_x(self, method, source, string, value, defects,34 remainder, comments=None):35 tl, rest = method(source)36 self._assert_results(tl, rest, string, value, defects, remainder,37 comments=None)38 return tl39 def _test_parse_x(self, method, input, string, value, defects,40 comments=None):41 tl = method(input)42 self._assert_results(tl, '', string, value, defects, '', comments)43 return tl44class TestParser(TestParserMixin, TestEmailBase):45 # _wsp_splitter46 rfc_printable_ascii = bytes(range(33, 127)).decode('ascii')47 rfc_atext_chars = (string.ascii_letters + string.digits +48 "!#$%&\'*+-/=?^_`{}|~")49 rfc_dtext_chars = rfc_printable_ascii.translate(str.maketrans('','',r'\[]'))50 def test__wsp_splitter_one_word(self):51 self.assertEqual(parser._wsp_splitter('foo', 1), ['foo'])52 def test__wsp_splitter_two_words(self):53 self.assertEqual(parser._wsp_splitter('foo def', 1),54 ['foo', ' ', 'def'])55 def test__wsp_splitter_ws_runs(self):56 self.assertEqual(parser._wsp_splitter('foo \t def jik', 1),57 ['foo', ' \t ', 'def jik'])58 # get_fws59 def test_get_fws_only(self):60 fws = self._test_get_x(parser.get_fws, ' \t ', ' \t ', ' ', [], '')61 self.assertEqual(fws.token_type, 'fws')62 def test_get_fws_space(self):63 self._test_get_x(parser.get_fws, ' foo', ' ', ' ', [], 'foo')64 def test_get_fws_ws_run(self):65 self._test_get_x(parser.get_fws, ' \t foo ', ' \t ', ' ', [], 'foo ')66 # get_encoded_word67 def test_get_encoded_word_missing_start_raises(self):68 with self.assertRaises(errors.HeaderParseError):69 parser.get_encoded_word('abc')70 def test_get_encoded_word_missing_end_raises(self):71 with self.assertRaises(errors.HeaderParseError):72 parser.get_encoded_word('=?abc')73 def test_get_encoded_word_missing_middle_raises(self):74 with self.assertRaises(errors.HeaderParseError):75 parser.get_encoded_word('=?abc?=')76 def test_get_encoded_word_valid_ew(self):77 self._test_get_x(parser.get_encoded_word,78 '=?us-ascii?q?this_is_a_test?= bird',79 'this is a test',80 'this is a test',81 [],82 ' bird')83 def test_get_encoded_word_internal_spaces(self):84 self._test_get_x(parser.get_encoded_word,85 '=?us-ascii?q?this is a test?= bird',86 'this is a test',87 'this is a test',88 [errors.InvalidHeaderDefect],89 ' bird')90 def test_get_encoded_word_gets_first(self):91 self._test_get_x(parser.get_encoded_word,92 '=?us-ascii?q?first?= =?utf-8?q?second?=',93 'first',94 'first',95 [],96 ' =?utf-8?q?second?=')97 def test_get_encoded_word_gets_first_even_if_no_space(self):98 self._test_get_x(parser.get_encoded_word,99 '=?us-ascii?q?first?==?utf-8?q?second?=',100 'first',101 'first',102 [],103 '=?utf-8?q?second?=')104 def test_get_encoded_word_sets_extra_attributes(self):105 ew = self._test_get_x(parser.get_encoded_word,106 '=?us-ascii*jive?q?first_second?=',107 'first second',108 'first second',109 [],110 '')111 self.assertEqual(ew.encoded, '=?us-ascii*jive?q?first_second?=')112 self.assertEqual(ew.charset, 'us-ascii')113 self.assertEqual(ew.lang, 'jive')114 def test_get_encoded_word_lang_default_is_blank(self):115 ew = self._test_get_x(parser.get_encoded_word,116 '=?us-ascii?q?first_second?=',117 'first second',118 'first second',119 [],120 '')121 self.assertEqual(ew.encoded, '=?us-ascii?q?first_second?=')122 self.assertEqual(ew.charset, 'us-ascii')123 self.assertEqual(ew.lang, '')124 def test_get_encoded_word_non_printable_defect(self):125 self._test_get_x(parser.get_encoded_word,126 '=?us-ascii?q?first\x02second?=',127 'first\x02second',128 'first\x02second',129 [errors.NonPrintableDefect],130 '')131 def test_get_encoded_word_leading_internal_space(self):132 self._test_get_x(parser.get_encoded_word,133 '=?us-ascii?q?=20foo?=',134 ' foo',135 ' foo',136 [],137 '')138 def test_get_encoded_word_quopri_utf_escape_follows_cte(self):139 # Issue 18044140 self._test_get_x(parser.get_encoded_word,141 '=?utf-8?q?=C3=89ric?=',142 'Ãric',143 'Ãric',144 [],145 '')146 # get_unstructured147 def _get_unst(self, value):148 token = parser.get_unstructured(value)149 return token, ''150 def test_get_unstructured_null(self):151 self._test_get_x(self._get_unst, '', '', '', [], '')152 def test_get_unstructured_one_word(self):153 self._test_get_x(self._get_unst, 'foo', 'foo', 'foo', [], '')154 def test_get_unstructured_normal_phrase(self):155 self._test_get_x(self._get_unst, 'foo bar bird',156 'foo bar bird',157 'foo bar bird',158 [],159 '')160 def test_get_unstructured_normal_phrase_with_whitespace(self):161 self._test_get_x(self._get_unst, 'foo \t bar bird',162 'foo \t bar bird',163 'foo bar bird',164 [],165 '')166 def test_get_unstructured_leading_whitespace(self):167 self._test_get_x(self._get_unst, ' foo bar',168 ' foo bar',169 ' foo bar',170 [],171 '')172 def test_get_unstructured_trailing_whitespace(self):173 self._test_get_x(self._get_unst, 'foo bar ',174 'foo bar ',175 'foo bar ',176 [],177 '')178 def test_get_unstructured_leading_and_trailing_whitespace(self):179 self._test_get_x(self._get_unst, ' foo bar ',180 ' foo bar ',181 ' foo bar ',182 [],183 '')184 def test_get_unstructured_one_valid_ew_no_ws(self):185 self._test_get_x(self._get_unst, '=?us-ascii?q?bar?=',186 'bar',187 'bar',188 [],189 '')190 def test_get_unstructured_one_ew_trailing_ws(self):191 self._test_get_x(self._get_unst, '=?us-ascii?q?bar?= ',192 'bar ',193 'bar ',194 [],195 '')196 def test_get_unstructured_one_valid_ew_trailing_text(self):197 self._test_get_x(self._get_unst, '=?us-ascii?q?bar?= bird',198 'bar bird',199 'bar bird',200 [],201 '')202 def test_get_unstructured_phrase_with_ew_in_middle_of_text(self):203 self._test_get_x(self._get_unst, 'foo =?us-ascii?q?bar?= bird',204 'foo bar bird',205 'foo bar bird',206 [],207 '')208 def test_get_unstructured_phrase_with_two_ew(self):209 self._test_get_x(self._get_unst,210 'foo =?us-ascii?q?bar?= =?us-ascii?q?bird?=',211 'foo barbird',212 'foo barbird',213 [],214 '')215 def test_get_unstructured_phrase_with_two_ew_trailing_ws(self):216 self._test_get_x(self._get_unst,217 'foo =?us-ascii?q?bar?= =?us-ascii?q?bird?= ',218 'foo barbird ',219 'foo barbird ',220 [],221 '')222 def test_get_unstructured_phrase_with_ew_with_leading_ws(self):223 self._test_get_x(self._get_unst,224 ' =?us-ascii?q?bar?=',225 ' bar',226 ' bar',227 [],228 '')229 def test_get_unstructured_phrase_with_two_ew_extra_ws(self):230 self._test_get_x(self._get_unst,231 'foo =?us-ascii?q?bar?= \t =?us-ascii?q?bird?=',232 'foo barbird',233 'foo barbird',234 [],235 '')236 def test_get_unstructured_two_ew_extra_ws_trailing_text(self):237 self._test_get_x(self._get_unst,238 '=?us-ascii?q?test?= =?us-ascii?q?foo?= val',239 'testfoo val',240 'testfoo val',241 [],242 '')243 def test_get_unstructured_ew_with_internal_ws(self):244 self._test_get_x(self._get_unst,245 '=?iso-8859-1?q?hello=20world?=',246 'hello world',247 'hello world',248 [],249 '')250 def test_get_unstructured_ew_with_internal_leading_ws(self):251 self._test_get_x(self._get_unst,252 ' =?us-ascii?q?=20test?= =?us-ascii?q?=20foo?= val',253 ' test foo val',254 ' test foo val',255 [],256 '')257 def test_get_unstructured_invaild_ew(self):258 self._test_get_x(self._get_unst,259 '=?test val',260 '=?test val',261 '=?test val',262 [],263 '')264 def test_get_unstructured_undecodable_bytes(self):265 self._test_get_x(self._get_unst,266 b'test \xACfoo val'.decode('ascii', 'surrogateescape'),267 'test \uDCACfoo val',268 'test \uDCACfoo val',269 [errors.UndecodableBytesDefect],270 '')271 def test_get_unstructured_undecodable_bytes_in_EW(self):272 self._test_get_x(self._get_unst,273 (b'=?us-ascii?q?=20test?= =?us-ascii?q?=20\xACfoo?='274 b' val').decode('ascii', 'surrogateescape'),275 ' test \uDCACfoo val',276 ' test \uDCACfoo val',277 [errors.UndecodableBytesDefect]*2,278 '')279 def test_get_unstructured_missing_base64_padding(self):280 self._test_get_x(self._get_unst,281 '=?utf-8?b?dmk?=',282 'vi',283 'vi',284 [errors.InvalidBase64PaddingDefect],285 '')286 def test_get_unstructured_invalid_base64_character(self):287 self._test_get_x(self._get_unst,288 '=?utf-8?b?dm\x01k===?=',289 'vi',290 'vi',291 [errors.InvalidBase64CharactersDefect],292 '')293 def test_get_unstructured_invalid_base64_character_and_bad_padding(self):294 self._test_get_x(self._get_unst,295 '=?utf-8?b?dm\x01k?=',296 'vi',297 'vi',298 [errors.InvalidBase64CharactersDefect,299 errors.InvalidBase64PaddingDefect],300 '')301 def test_get_unstructured_no_whitespace_between_ews(self):302 self._test_get_x(self._get_unst,303 '=?utf-8?q?foo?==?utf-8?q?bar?=',304 'foobar',305 'foobar',306 [errors.InvalidHeaderDefect],307 '')308 # get_qp_ctext309 def test_get_qp_ctext_only(self):310 ptext = self._test_get_x(parser.get_qp_ctext,311 'foobar', 'foobar', ' ', [], '')312 self.assertEqual(ptext.token_type, 'ptext')313 def test_get_qp_ctext_all_printables(self):314 with_qp = self.rfc_printable_ascii.replace('\\', '\\\\')315 with_qp = with_qp. replace('(', r'\(')316 with_qp = with_qp.replace(')', r'\)')317 ptext = self._test_get_x(parser.get_qp_ctext,318 with_qp, self.rfc_printable_ascii, ' ', [], '')319 def test_get_qp_ctext_two_words_gets_first(self):320 self._test_get_x(parser.get_qp_ctext,321 'foo de', 'foo', ' ', [], ' de')322 def test_get_qp_ctext_following_wsp_preserved(self):323 self._test_get_x(parser.get_qp_ctext,324 'foo \t\tde', 'foo', ' ', [], ' \t\tde')325 def test_get_qp_ctext_up_to_close_paren_only(self):326 self._test_get_x(parser.get_qp_ctext,327 'foo)', 'foo', ' ', [], ')')328 def test_get_qp_ctext_wsp_before_close_paren_preserved(self):329 self._test_get_x(parser.get_qp_ctext,330 'foo )', 'foo', ' ', [], ' )')331 def test_get_qp_ctext_close_paren_mid_word(self):332 self._test_get_x(parser.get_qp_ctext,333 'foo)bar', 'foo', ' ', [], ')bar')334 def test_get_qp_ctext_up_to_open_paren_only(self):335 self._test_get_x(parser.get_qp_ctext,336 'foo(', 'foo', ' ', [], '(')337 def test_get_qp_ctext_wsp_before_open_paren_preserved(self):338 self._test_get_x(parser.get_qp_ctext,339 'foo (', 'foo', ' ', [], ' (')340 def test_get_qp_ctext_open_paren_mid_word(self):341 self._test_get_x(parser.get_qp_ctext,342 'foo(bar', 'foo', ' ', [], '(bar')343 def test_get_qp_ctext_non_printables(self):344 ptext = self._test_get_x(parser.get_qp_ctext,345 'foo\x00bar)', 'foo\x00bar', ' ',346 [errors.NonPrintableDefect], ')')347 self.assertEqual(ptext.defects[0].non_printables[0], '\x00')348 # get_qcontent349 def test_get_qcontent_only(self):350 ptext = self._test_get_x(parser.get_qcontent,351 'foobar', 'foobar', 'foobar', [], '')352 self.assertEqual(ptext.token_type, 'ptext')353 def test_get_qcontent_all_printables(self):354 with_qp = self.rfc_printable_ascii.replace('\\', '\\\\')355 with_qp = with_qp. replace('"', r'\"')356 ptext = self._test_get_x(parser.get_qcontent, with_qp,357 self.rfc_printable_ascii,358 self.rfc_printable_ascii, [], '')359 def test_get_qcontent_two_words_gets_first(self):360 self._test_get_x(parser.get_qcontent,361 'foo de', 'foo', 'foo', [], ' de')362 def test_get_qcontent_following_wsp_preserved(self):363 self._test_get_x(parser.get_qcontent,364 'foo \t\tde', 'foo', 'foo', [], ' \t\tde')365 def test_get_qcontent_up_to_dquote_only(self):366 self._test_get_x(parser.get_qcontent,367 'foo"', 'foo', 'foo', [], '"')368 def test_get_qcontent_wsp_before_close_paren_preserved(self):369 self._test_get_x(parser.get_qcontent,370 'foo "', 'foo', 'foo', [], ' "')371 def test_get_qcontent_close_paren_mid_word(self):372 self._test_get_x(parser.get_qcontent,373 'foo"bar', 'foo', 'foo', [], '"bar')374 def test_get_qcontent_non_printables(self):375 ptext = self._test_get_x(parser.get_qcontent,376 'foo\x00fg"', 'foo\x00fg', 'foo\x00fg',377 [errors.NonPrintableDefect], '"')378 self.assertEqual(ptext.defects[0].non_printables[0], '\x00')379 # get_atext380 def test_get_atext_only(self):381 atext = self._test_get_x(parser.get_atext,382 'foobar', 'foobar', 'foobar', [], '')383 self.assertEqual(atext.token_type, 'atext')384 def test_get_atext_all_atext(self):385 atext = self._test_get_x(parser.get_atext, self.rfc_atext_chars,386 self.rfc_atext_chars,387 self.rfc_atext_chars, [], '')388 def test_get_atext_two_words_gets_first(self):389 self._test_get_x(parser.get_atext,390 'foo bar', 'foo', 'foo', [], ' bar')391 def test_get_atext_following_wsp_preserved(self):392 self._test_get_x(parser.get_atext,393 'foo \t\tbar', 'foo', 'foo', [], ' \t\tbar')394 def test_get_atext_up_to_special(self):395 self._test_get_x(parser.get_atext,396 'foo@bar', 'foo', 'foo', [], '@bar')397 def test_get_atext_non_printables(self):398 atext = self._test_get_x(parser.get_atext,399 'foo\x00bar(', 'foo\x00bar', 'foo\x00bar',400 [errors.NonPrintableDefect], '(')401 self.assertEqual(atext.defects[0].non_printables[0], '\x00')402 # get_bare_quoted_string403 def test_get_bare_quoted_string_only(self):404 bqs = self._test_get_x(parser.get_bare_quoted_string,405 '"foo"', '"foo"', 'foo', [], '')406 self.assertEqual(bqs.token_type, 'bare-quoted-string')407 def test_get_bare_quoted_string_must_start_with_dquote(self):408 with self.assertRaises(errors.HeaderParseError):409 parser.get_bare_quoted_string('foo"')410 with self.assertRaises(errors.HeaderParseError):411 parser.get_bare_quoted_string(' "foo"')412 def test_get_bare_quoted_string_following_wsp_preserved(self):413 self._test_get_x(parser.get_bare_quoted_string,414 '"foo"\t bar', '"foo"', 'foo', [], '\t bar')415 def test_get_bare_quoted_string_multiple_words(self):416 self._test_get_x(parser.get_bare_quoted_string,417 '"foo bar moo"', '"foo bar moo"', 'foo bar moo', [], '')418 def test_get_bare_quoted_string_multiple_words_wsp_preserved(self):419 self._test_get_x(parser.get_bare_quoted_string,420 '" foo moo\t"', '" foo moo\t"', ' foo moo\t', [], '')421 def test_get_bare_quoted_string_end_dquote_mid_word(self):422 self._test_get_x(parser.get_bare_quoted_string,423 '"foo"bar', '"foo"', 'foo', [], 'bar')424 def test_get_bare_quoted_string_quoted_dquote(self):425 self._test_get_x(parser.get_bare_quoted_string,426 r'"foo\"in"a', r'"foo\"in"', 'foo"in', [], 'a')427 def test_get_bare_quoted_string_non_printables(self):428 self._test_get_x(parser.get_bare_quoted_string,429 '"a\x01a"', '"a\x01a"', 'a\x01a',430 [errors.NonPrintableDefect], '')431 def test_get_bare_quoted_string_no_end_dquote(self):432 self._test_get_x(parser.get_bare_quoted_string,433 '"foo', '"foo"', 'foo',434 [errors.InvalidHeaderDefect], '')435 self._test_get_x(parser.get_bare_quoted_string,436 '"foo ', '"foo "', 'foo ',437 [errors.InvalidHeaderDefect], '')438 def test_get_bare_quoted_string_empty_quotes(self):439 self._test_get_x(parser.get_bare_quoted_string,440 '""', '""', '', [], '')441 # get_comment442 def test_get_comment_only(self):443 comment = self._test_get_x(parser.get_comment,444 '(comment)', '(comment)', ' ', [], '', ['comment'])445 self.assertEqual(comment.token_type, 'comment')446 def test_get_comment_must_start_with_paren(self):447 with self.assertRaises(errors.HeaderParseError):448 parser.get_comment('foo"')449 with self.assertRaises(errors.HeaderParseError):450 parser.get_comment(' (foo"')451 def test_get_comment_following_wsp_preserved(self):452 self._test_get_x(parser.get_comment,453 '(comment) \t', '(comment)', ' ', [], ' \t', ['comment'])454 def test_get_comment_multiple_words(self):455 self._test_get_x(parser.get_comment,456 '(foo bar) \t', '(foo bar)', ' ', [], ' \t', ['foo bar'])457 def test_get_comment_multiple_words_wsp_preserved(self):458 self._test_get_x(parser.get_comment,459 '( foo bar\t ) \t', '( foo bar\t )', ' ', [], ' \t',460 [' foo bar\t '])461 def test_get_comment_end_paren_mid_word(self):462 self._test_get_x(parser.get_comment,463 '(foo)bar', '(foo)', ' ', [], 'bar', ['foo'])464 def test_get_comment_quoted_parens(self):465 self._test_get_x(parser.get_comment,466 '(foo\) \(\)bar)', '(foo\) \(\)bar)', ' ', [], '', ['foo) ()bar'])467 def test_get_comment_non_printable(self):468 self._test_get_x(parser.get_comment,469 '(foo\x7Fbar)', '(foo\x7Fbar)', ' ',470 [errors.NonPrintableDefect], '', ['foo\x7Fbar'])471 def test_get_comment_no_end_paren(self):472 self._test_get_x(parser.get_comment,473 '(foo bar', '(foo bar)', ' ',474 [errors.InvalidHeaderDefect], '', ['foo bar'])475 self._test_get_x(parser.get_comment,476 '(foo bar ', '(foo bar )', ' ',477 [errors.InvalidHeaderDefect], '', ['foo bar '])478 def test_get_comment_nested_comment(self):479 comment = self._test_get_x(parser.get_comment,480 '(foo(bar))', '(foo(bar))', ' ', [], '', ['foo(bar)'])481 self.assertEqual(comment[1].content, 'bar')482 def test_get_comment_nested_comment_wsp(self):483 comment = self._test_get_x(parser.get_comment,484 '(foo ( bar ) )', '(foo ( bar ) )', ' ', [], '', ['foo ( bar ) '])485 self.assertEqual(comment[2].content, ' bar ')486 def test_get_comment_empty_comment(self):487 self._test_get_x(parser.get_comment,488 '()', '()', ' ', [], '', [''])489 def test_get_comment_multiple_nesting(self):490 comment = self._test_get_x(parser.get_comment,491 '(((((foo)))))', '(((((foo)))))', ' ', [], '', ['((((foo))))'])492 for i in range(4, 0, -1):493 self.assertEqual(comment[0].content, '('*(i-1)+'foo'+')'*(i-1))494 comment = comment[0]495 self.assertEqual(comment.content, 'foo')496 def test_get_comment_missing_end_of_nesting(self):497 self._test_get_x(parser.get_comment,498 '(((((foo)))', '(((((foo)))))', ' ',499 [errors.InvalidHeaderDefect]*2, '', ['((((foo))))'])500 def test_get_comment_qs_in_nested_comment(self):501 comment = self._test_get_x(parser.get_comment,502 '(foo (b\)))', '(foo (b\)))', ' ', [], '', ['foo (b\))'])503 self.assertEqual(comment[2].content, 'b)')504 # get_cfws505 def test_get_cfws_only_ws(self):506 cfws = self._test_get_x(parser.get_cfws,507 ' \t \t', ' \t \t', ' ', [], '', [])508 self.assertEqual(cfws.token_type, 'cfws')509 def test_get_cfws_only_comment(self):510 cfws = self._test_get_x(parser.get_cfws,511 '(foo)', '(foo)', ' ', [], '', ['foo'])512 self.assertEqual(cfws[0].content, 'foo')513 def test_get_cfws_only_mixed(self):514 cfws = self._test_get_x(parser.get_cfws,515 ' (foo ) ( bar) ', ' (foo ) ( bar) ', ' ', [], '',516 ['foo ', ' bar'])517 self.assertEqual(cfws[1].content, 'foo ')518 self.assertEqual(cfws[3].content, ' bar')519 def test_get_cfws_ends_at_non_leader(self):520 cfws = self._test_get_x(parser.get_cfws,521 '(foo) bar', '(foo) ', ' ', [], 'bar', ['foo'])522 self.assertEqual(cfws[0].content, 'foo')523 def test_get_cfws_ends_at_non_printable(self):524 cfws = self._test_get_x(parser.get_cfws,525 '(foo) \x07', '(foo) ', ' ', [], '\x07', ['foo'])526 self.assertEqual(cfws[0].content, 'foo')527 def test_get_cfws_non_printable_in_comment(self):528 cfws = self._test_get_x(parser.get_cfws,529 '(foo \x07) "test"', '(foo \x07) ', ' ',530 [errors.NonPrintableDefect], '"test"', ['foo \x07'])531 self.assertEqual(cfws[0].content, 'foo \x07')532 def test_get_cfws_header_ends_in_comment(self):533 cfws = self._test_get_x(parser.get_cfws,534 ' (foo ', ' (foo )', ' ',535 [errors.InvalidHeaderDefect], '', ['foo '])536 self.assertEqual(cfws[1].content, 'foo ')537 def test_get_cfws_multiple_nested_comments(self):538 cfws = self._test_get_x(parser.get_cfws,539 '(foo (bar)) ((a)(a))', '(foo (bar)) ((a)(a))', ' ', [],540 '', ['foo (bar)', '(a)(a)'])541 self.assertEqual(cfws[0].comments, ['foo (bar)'])542 self.assertEqual(cfws[2].comments, ['(a)(a)'])543 # get_quoted_string544 def test_get_quoted_string_only(self):545 qs = self._test_get_x(parser.get_quoted_string,546 '"bob"', '"bob"', 'bob', [], '')547 self.assertEqual(qs.token_type, 'quoted-string')548 self.assertEqual(qs.quoted_value, '"bob"')549 self.assertEqual(qs.content, 'bob')550 def test_get_quoted_string_with_wsp(self):551 qs = self._test_get_x(parser.get_quoted_string,552 '\t "bob" ', '\t "bob" ', ' bob ', [], '')553 self.assertEqual(qs.quoted_value, ' "bob" ')554 self.assertEqual(qs.content, 'bob')555 def test_get_quoted_string_with_comments_and_wsp(self):556 qs = self._test_get_x(parser.get_quoted_string,557 ' (foo) "bob"(bar)', ' (foo) "bob"(bar)', ' bob ', [], '')558 self.assertEqual(qs[0][1].content, 'foo')559 self.assertEqual(qs[2][0].content, 'bar')560 self.assertEqual(qs.content, 'bob')561 self.assertEqual(qs.quoted_value, ' "bob" ')562 def test_get_quoted_string_with_multiple_comments(self):563 qs = self._test_get_x(parser.get_quoted_string,564 ' (foo) (bar) "bob"(bird)', ' (foo) (bar) "bob"(bird)', ' bob ',565 [], '')566 self.assertEqual(qs[0].comments, ['foo', 'bar'])567 self.assertEqual(qs[2].comments, ['bird'])568 self.assertEqual(qs.content, 'bob')569 self.assertEqual(qs.quoted_value, ' "bob" ')570 def test_get_quoted_string_non_printable_in_comment(self):571 qs = self._test_get_x(parser.get_quoted_string,572 ' (\x0A) "bob"', ' (\x0A) "bob"', ' bob',573 [errors.NonPrintableDefect], '')574 self.assertEqual(qs[0].comments, ['\x0A'])575 self.assertEqual(qs.content, 'bob')576 self.assertEqual(qs.quoted_value, ' "bob"')577 def test_get_quoted_string_non_printable_in_qcontent(self):578 qs = self._test_get_x(parser.get_quoted_string,579 ' (a) "a\x0B"', ' (a) "a\x0B"', ' a\x0B',580 [errors.NonPrintableDefect], '')581 self.assertEqual(qs[0].comments, ['a'])582 self.assertEqual(qs.content, 'a\x0B')583 self.assertEqual(qs.quoted_value, ' "a\x0B"')584 def test_get_quoted_string_internal_ws(self):585 qs = self._test_get_x(parser.get_quoted_string,586 ' (a) "foo bar "', ' (a) "foo bar "', ' foo bar ',587 [], '')588 self.assertEqual(qs[0].comments, ['a'])589 self.assertEqual(qs.content, 'foo bar ')590 self.assertEqual(qs.quoted_value, ' "foo bar "')591 def test_get_quoted_string_header_ends_in_comment(self):592 qs = self._test_get_x(parser.get_quoted_string,593 ' (a) "bob" (a', ' (a) "bob" (a)', ' bob ',594 [errors.InvalidHeaderDefect], '')595 self.assertEqual(qs[0].comments, ['a'])596 self.assertEqual(qs[2].comments, ['a'])597 self.assertEqual(qs.content, 'bob')598 self.assertEqual(qs.quoted_value, ' "bob" ')599 def test_get_quoted_string_header_ends_in_qcontent(self):600 qs = self._test_get_x(parser.get_quoted_string,601 ' (a) "bob', ' (a) "bob"', ' bob',602 [errors.InvalidHeaderDefect], '')603 self.assertEqual(qs[0].comments, ['a'])604 self.assertEqual(qs.content, 'bob')605 self.assertEqual(qs.quoted_value, ' "bob"')606 def test_get_quoted_string_no_quoted_string(self):607 with self.assertRaises(errors.HeaderParseError):608 parser.get_quoted_string(' (ab) xyz')609 def test_get_quoted_string_qs_ends_at_noncfws(self):610 qs = self._test_get_x(parser.get_quoted_string,611 '\t "bob" fee', '\t "bob" ', ' bob ', [], 'fee')612 self.assertEqual(qs.content, 'bob')613 self.assertEqual(qs.quoted_value, ' "bob" ')614 # get_atom615 def test_get_atom_only(self):616 atom = self._test_get_x(parser.get_atom,617 'bob', 'bob', 'bob', [], '')618 self.assertEqual(atom.token_type, 'atom')619 def test_get_atom_with_wsp(self):620 self._test_get_x(parser.get_atom,621 '\t bob ', '\t bob ', ' bob ', [], '')622 def test_get_atom_with_comments_and_wsp(self):623 atom = self._test_get_x(parser.get_atom,624 ' (foo) bob(bar)', ' (foo) bob(bar)', ' bob ', [], '')625 self.assertEqual(atom[0][1].content, 'foo')626 self.assertEqual(atom[2][0].content, 'bar')627 def test_get_atom_with_multiple_comments(self):628 atom = self._test_get_x(parser.get_atom,629 ' (foo) (bar) bob(bird)', ' (foo) (bar) bob(bird)', ' bob ',630 [], '')631 self.assertEqual(atom[0].comments, ['foo', 'bar'])632 self.assertEqual(atom[2].comments, ['bird'])633 def test_get_atom_non_printable_in_comment(self):634 atom = self._test_get_x(parser.get_atom,635 ' (\x0A) bob', ' (\x0A) bob', ' bob',636 [errors.NonPrintableDefect], '')637 self.assertEqual(atom[0].comments, ['\x0A'])638 def test_get_atom_non_printable_in_atext(self):639 atom = self._test_get_x(parser.get_atom,640 ' (a) a\x0B', ' (a) a\x0B', ' a\x0B',641 [errors.NonPrintableDefect], '')642 self.assertEqual(atom[0].comments, ['a'])643 def test_get_atom_header_ends_in_comment(self):644 atom = self._test_get_x(parser.get_atom,645 ' (a) bob (a', ' (a) bob (a)', ' bob ',646 [errors.InvalidHeaderDefect], '')647 self.assertEqual(atom[0].comments, ['a'])648 self.assertEqual(atom[2].comments, ['a'])649 def test_get_atom_no_atom(self):650 with self.assertRaises(errors.HeaderParseError):651 parser.get_atom(' (ab) ')652 def test_get_atom_no_atom_before_special(self):653 with self.assertRaises(errors.HeaderParseError):654 parser.get_atom(' (ab) @')655 def test_get_atom_atom_ends_at_special(self):656 atom = self._test_get_x(parser.get_atom,657 ' (foo) bob(bar) @bang', ' (foo) bob(bar) ', ' bob ', [], '@bang')658 self.assertEqual(atom[0].comments, ['foo'])659 self.assertEqual(atom[2].comments, ['bar'])660 def test_get_atom_atom_ends_at_noncfws(self):661 self._test_get_x(parser.get_atom,662 'bob fred', 'bob ', 'bob ', [], 'fred')663 def test_get_atom_rfc2047_atom(self):664 self._test_get_x(parser.get_atom,665 '=?utf-8?q?=20bob?=', ' bob', ' bob', [], '')666 # get_dot_atom_text667 def test_get_dot_atom_text(self):668 dot_atom_text = self._test_get_x(parser.get_dot_atom_text,669 'foo.bar.bang', 'foo.bar.bang', 'foo.bar.bang', [], '')670 self.assertEqual(dot_atom_text.token_type, 'dot-atom-text')671 self.assertEqual(len(dot_atom_text), 5)672 def test_get_dot_atom_text_lone_atom_is_valid(self):673 dot_atom_text = self._test_get_x(parser.get_dot_atom_text,674 'foo', 'foo', 'foo', [], '')675 def test_get_dot_atom_text_raises_on_leading_dot(self):676 with self.assertRaises(errors.HeaderParseError):677 parser.get_dot_atom_text('.foo.bar')678 def test_get_dot_atom_text_raises_on_trailing_dot(self):679 with self.assertRaises(errors.HeaderParseError):680 parser.get_dot_atom_text('foo.bar.')681 def test_get_dot_atom_text_raises_on_leading_non_atext(self):682 with self.assertRaises(errors.HeaderParseError):683 parser.get_dot_atom_text(' foo.bar')684 with self.assertRaises(errors.HeaderParseError):685 parser.get_dot_atom_text('@foo.bar')686 with self.assertRaises(errors.HeaderParseError):687 parser.get_dot_atom_text('"foo.bar"')688 def test_get_dot_atom_text_trailing_text_preserved(self):689 dot_atom_text = self._test_get_x(parser.get_dot_atom_text,690 'foo@bar', 'foo', 'foo', [], '@bar')691 def test_get_dot_atom_text_trailing_ws_preserved(self):692 dot_atom_text = self._test_get_x(parser.get_dot_atom_text,693 'foo .bar', 'foo', 'foo', [], ' .bar')694 # get_dot_atom695 def test_get_dot_atom_only(self):696 dot_atom = self._test_get_x(parser.get_dot_atom,697 'foo.bar.bing', 'foo.bar.bing', 'foo.bar.bing', [], '')698 self.assertEqual(dot_atom.token_type, 'dot-atom')699 self.assertEqual(len(dot_atom), 1)700 def test_get_dot_atom_with_wsp(self):701 self._test_get_x(parser.get_dot_atom,702 '\t foo.bar.bing ', '\t foo.bar.bing ', ' foo.bar.bing ', [], '')703 def test_get_dot_atom_with_comments_and_wsp(self):704 self._test_get_x(parser.get_dot_atom,705 ' (sing) foo.bar.bing (here) ', ' (sing) foo.bar.bing (here) ',706 ' foo.bar.bing ', [], '')707 def test_get_dot_atom_space_ends_dot_atom(self):708 self._test_get_x(parser.get_dot_atom,709 ' (sing) foo.bar .bing (here) ', ' (sing) foo.bar ',710 ' foo.bar ', [], '.bing (here) ')711 def test_get_dot_atom_no_atom_raises(self):712 with self.assertRaises(errors.HeaderParseError):713 parser.get_dot_atom(' (foo) ')714 def test_get_dot_atom_leading_dot_raises(self):715 with self.assertRaises(errors.HeaderParseError):716 parser.get_dot_atom(' (foo) .bar')717 def test_get_dot_atom_two_dots_raises(self):718 with self.assertRaises(errors.HeaderParseError):719 parser.get_dot_atom('bar..bang')720 def test_get_dot_atom_trailing_dot_raises(self):721 with self.assertRaises(errors.HeaderParseError):722 parser.get_dot_atom(' (foo) bar.bang. foo')723 def test_get_dot_atom_rfc2047_atom(self):724 self._test_get_x(parser.get_dot_atom,725 '=?utf-8?q?=20bob?=', ' bob', ' bob', [], '')726 # get_word (if this were black box we'd repeat all the qs/atom tests)727 def test_get_word_atom_yields_atom(self):728 word = self._test_get_x(parser.get_word,729 ' (foo) bar (bang) :ah', ' (foo) bar (bang) ', ' bar ', [], ':ah')730 self.assertEqual(word.token_type, 'atom')731 self.assertEqual(word[0].token_type, 'cfws')732 def test_get_word_qs_yields_qs(self):733 word = self._test_get_x(parser.get_word,734 '"bar " (bang) ah', '"bar " (bang) ', 'bar ', [], 'ah')735 self.assertEqual(word.token_type, 'quoted-string')736 self.assertEqual(word[0].token_type, 'bare-quoted-string')737 self.assertEqual(word[0].value, 'bar ')738 self.assertEqual(word.content, 'bar ')739 def test_get_word_ends_at_dot(self):740 self._test_get_x(parser.get_word,741 'foo.', 'foo', 'foo', [], '.')742 # get_phrase743 def test_get_phrase_simple(self):744 phrase = self._test_get_x(parser.get_phrase,745 '"Fred A. Johnson" is his name, oh.',746 '"Fred A. Johnson" is his name',747 'Fred A. Johnson is his name',748 [],749 ', oh.')750 self.assertEqual(phrase.token_type, 'phrase')751 def test_get_phrase_complex(self):752 phrase = self._test_get_x(parser.get_phrase,753 ' (A) bird (in (my|your)) "hand " is messy\t<>\t',754 ' (A) bird (in (my|your)) "hand " is messy\t',755 ' bird hand is messy ',756 [],757 '<>\t')758 self.assertEqual(phrase[0][0].comments, ['A'])759 self.assertEqual(phrase[0][2].comments, ['in (my|your)'])760 def test_get_phrase_obsolete(self):761 phrase = self._test_get_x(parser.get_phrase,762 'Fred A.(weird).O Johnson',763 'Fred A.(weird).O Johnson',764 'Fred A. .O Johnson',765 [errors.ObsoleteHeaderDefect]*3,766 '')767 self.assertEqual(len(phrase), 7)768 self.assertEqual(phrase[3].comments, ['weird'])769 def test_get_phrase_pharse_must_start_with_word(self):770 phrase = self._test_get_x(parser.get_phrase,771 '(even weirder).name',772 '(even weirder).name',773 ' .name',774 [errors.InvalidHeaderDefect] + [errors.ObsoleteHeaderDefect]*2,775 '')776 self.assertEqual(len(phrase), 3)777 self.assertEqual(phrase[0].comments, ['even weirder'])778 def test_get_phrase_ending_with_obsolete(self):779 phrase = self._test_get_x(parser.get_phrase,780 'simple phrase.(with trailing comment):boo',781 'simple phrase.(with trailing comment)',782 'simple phrase. ',783 [errors.ObsoleteHeaderDefect]*2,784 ':boo')785 self.assertEqual(len(phrase), 4)786 self.assertEqual(phrase[3].comments, ['with trailing comment'])787 def get_phrase_cfws_only_raises(self):788 with self.assertRaises(errors.HeaderParseError):789 parser.get_phrase(' (foo) ')790 # get_local_part791 def test_get_local_part_simple(self):792 local_part = self._test_get_x(parser.get_local_part,793 'dinsdale@python.org', 'dinsdale', 'dinsdale', [], '@python.org')794 self.assertEqual(local_part.token_type, 'local-part')795 self.assertEqual(local_part.local_part, 'dinsdale')796 def test_get_local_part_with_dot(self):797 local_part = self._test_get_x(parser.get_local_part,798 'Fred.A.Johnson@python.org',799 'Fred.A.Johnson',800 'Fred.A.Johnson',801 [],802 '@python.org')803 self.assertEqual(local_part.local_part, 'Fred.A.Johnson')804 def test_get_local_part_with_whitespace(self):805 local_part = self._test_get_x(parser.get_local_part,806 ' Fred.A.Johnson @python.org',807 ' Fred.A.Johnson ',808 ' Fred.A.Johnson ',809 [],810 '@python.org')811 self.assertEqual(local_part.local_part, 'Fred.A.Johnson')812 def test_get_local_part_with_cfws(self):813 local_part = self._test_get_x(parser.get_local_part,814 ' (foo) Fred.A.Johnson (bar (bird)) @python.org',815 ' (foo) Fred.A.Johnson (bar (bird)) ',816 ' Fred.A.Johnson ',817 [],818 '@python.org')819 self.assertEqual(local_part.local_part, 'Fred.A.Johnson')820 self.assertEqual(local_part[0][0].comments, ['foo'])821 self.assertEqual(local_part[0][2].comments, ['bar (bird)'])822 def test_get_local_part_simple_quoted(self):823 local_part = self._test_get_x(parser.get_local_part,824 '"dinsdale"@python.org', '"dinsdale"', '"dinsdale"', [], '@python.org')825 self.assertEqual(local_part.token_type, 'local-part')826 self.assertEqual(local_part.local_part, 'dinsdale')827 def test_get_local_part_with_quoted_dot(self):828 local_part = self._test_get_x(parser.get_local_part,829 '"Fred.A.Johnson"@python.org',830 '"Fred.A.Johnson"',831 '"Fred.A.Johnson"',832 [],833 '@python.org')834 self.assertEqual(local_part.local_part, 'Fred.A.Johnson')835 def test_get_local_part_quoted_with_whitespace(self):836 local_part = self._test_get_x(parser.get_local_part,837 ' "Fred A. Johnson" @python.org',838 ' "Fred A. Johnson" ',839 ' "Fred A. Johnson" ',840 [],841 '@python.org')842 self.assertEqual(local_part.local_part, 'Fred A. Johnson')843 def test_get_local_part_quoted_with_cfws(self):844 local_part = self._test_get_x(parser.get_local_part,845 ' (foo) " Fred A. Johnson " (bar (bird)) @python.org',846 ' (foo) " Fred A. Johnson " (bar (bird)) ',847 ' " Fred A. Johnson " ',848 [],849 '@python.org')850 self.assertEqual(local_part.local_part, ' Fred A. Johnson ')851 self.assertEqual(local_part[0][0].comments, ['foo'])852 self.assertEqual(local_part[0][2].comments, ['bar (bird)'])853 def test_get_local_part_simple_obsolete(self):854 local_part = self._test_get_x(parser.get_local_part,855 'Fred. A.Johnson@python.org',856 'Fred. A.Johnson',857 'Fred. A.Johnson',858 [errors.ObsoleteHeaderDefect],859 '@python.org')860 self.assertEqual(local_part.local_part, 'Fred.A.Johnson')861 def test_get_local_part_complex_obsolete_1(self):862 local_part = self._test_get_x(parser.get_local_part,863 ' (foo )Fred (bar).(bird) A.(sheep)Johnson."and dogs "@python.org',864 ' (foo )Fred (bar).(bird) A.(sheep)Johnson."and dogs "',865 ' Fred . A. Johnson.and dogs ',866 [errors.ObsoleteHeaderDefect],867 '@python.org')868 self.assertEqual(local_part.local_part, 'Fred.A.Johnson.and dogs ')869 def test_get_local_part_complex_obsolete_invalid(self):870 local_part = self._test_get_x(parser.get_local_part,871 ' (foo )Fred (bar).(bird) A.(sheep)Johnson "and dogs"@python.org',872 ' (foo )Fred (bar).(bird) A.(sheep)Johnson "and dogs"',873 ' Fred . A. Johnson and dogs',874 [errors.InvalidHeaderDefect]*2,875 '@python.org')876 self.assertEqual(local_part.local_part, 'Fred.A.Johnson and dogs')877 def test_get_local_part_no_part_raises(self):878 with self.assertRaises(errors.HeaderParseError):879 parser.get_local_part(' (foo) ')880 def test_get_local_part_special_instead_raises(self):881 with self.assertRaises(errors.HeaderParseError):882 parser.get_local_part(' (foo) @python.org')883 def test_get_local_part_trailing_dot(self):884 local_part = self._test_get_x(parser.get_local_part,885 ' borris.@python.org',886 ' borris.',887 ' borris.',888 [errors.InvalidHeaderDefect]*2,889 '@python.org')890 self.assertEqual(local_part.local_part, 'borris.')891 def test_get_local_part_trailing_dot_with_ws(self):892 local_part = self._test_get_x(parser.get_local_part,893 ' borris. @python.org',894 ' borris. ',895 ' borris. ',896 [errors.InvalidHeaderDefect]*2,897 '@python.org')898 self.assertEqual(local_part.local_part, 'borris.')899 def test_get_local_part_leading_dot(self):900 local_part = self._test_get_x(parser.get_local_part,901 '.borris@python.org',902 '.borris',903 '.borris',904 [errors.InvalidHeaderDefect]*2,905 '@python.org')906 self.assertEqual(local_part.local_part, '.borris')907 def test_get_local_part_leading_dot_after_ws(self):908 local_part = self._test_get_x(parser.get_local_part,909 ' .borris@python.org',910 ' .borris',911 ' .borris',912 [errors.InvalidHeaderDefect]*2,913 '@python.org')914 self.assertEqual(local_part.local_part, '.borris')915 def test_get_local_part_double_dot_raises(self):916 local_part = self._test_get_x(parser.get_local_part,917 ' borris.(foo).natasha@python.org',918 ' borris.(foo).natasha',919 ' borris. .natasha',920 [errors.InvalidHeaderDefect]*2,921 '@python.org')922 self.assertEqual(local_part.local_part, 'borris..natasha')923 def test_get_local_part_quoted_strings_in_atom_list(self):924 local_part = self._test_get_x(parser.get_local_part,925 '""example" example"@example.com',926 '""example" example"',927 'example example',928 [errors.InvalidHeaderDefect]*3,929 '@example.com')930 self.assertEqual(local_part.local_part, 'example example')931 def test_get_local_part_valid_and_invalid_qp_in_atom_list(self):932 local_part = self._test_get_x(parser.get_local_part,933 r'"\\"example\\" example"@example.com',934 r'"\\"example\\" example"',935 r'\example\\ example',936 [errors.InvalidHeaderDefect]*5,937 '@example.com')938 self.assertEqual(local_part.local_part, r'\example\\ example')939 def test_get_local_part_unicode_defect(self):940 # Currently this only happens when parsing unicode, not when parsing941 # stuff that was originally binary.942 local_part = self._test_get_x(parser.get_local_part,943 'exámple@example.com',944 'exámple',945 'exámple',946 [errors.NonASCIILocalPartDefect],947 '@example.com')948 self.assertEqual(local_part.local_part, 'exámple')949 # get_dtext950 def test_get_dtext_only(self):951 dtext = self._test_get_x(parser.get_dtext,952 'foobar', 'foobar', 'foobar', [], '')953 self.assertEqual(dtext.token_type, 'ptext')954 def test_get_dtext_all_dtext(self):955 dtext = self._test_get_x(parser.get_dtext, self.rfc_dtext_chars,956 self.rfc_dtext_chars,957 self.rfc_dtext_chars, [], '')958 def test_get_dtext_two_words_gets_first(self):959 self._test_get_x(parser.get_dtext,960 'foo bar', 'foo', 'foo', [], ' bar')961 def test_get_dtext_following_wsp_preserved(self):962 self._test_get_x(parser.get_dtext,963 'foo \t\tbar', 'foo', 'foo', [], ' \t\tbar')964 def test_get_dtext_non_printables(self):965 dtext = self._test_get_x(parser.get_dtext,966 'foo\x00bar]', 'foo\x00bar', 'foo\x00bar',967 [errors.NonPrintableDefect], ']')968 self.assertEqual(dtext.defects[0].non_printables[0], '\x00')969 def test_get_dtext_with_qp(self):970 ptext = self._test_get_x(parser.get_dtext,971 r'foo\]\[\\bar\b\e\l\l',972 r'foo][\barbell',973 r'foo][\barbell',974 [errors.ObsoleteHeaderDefect],975 '')976 def test_get_dtext_up_to_close_bracket_only(self):977 self._test_get_x(parser.get_dtext,978 'foo]', 'foo', 'foo', [], ']')979 def test_get_dtext_wsp_before_close_bracket_preserved(self):980 self._test_get_x(parser.get_dtext,981 'foo ]', 'foo', 'foo', [], ' ]')982 def test_get_dtext_close_bracket_mid_word(self):983 self._test_get_x(parser.get_dtext,984 'foo]bar', 'foo', 'foo', [], ']bar')985 def test_get_dtext_up_to_open_bracket_only(self):986 self._test_get_x(parser.get_dtext,987 'foo[', 'foo', 'foo', [], '[')988 def test_get_dtext_wsp_before_open_bracket_preserved(self):989 self._test_get_x(parser.get_dtext,990 'foo [', 'foo', 'foo', [], ' [')991 def test_get_dtext_open_bracket_mid_word(self):992 self._test_get_x(parser.get_dtext,993 'foo[bar', 'foo', 'foo', [], '[bar')994 # get_domain_literal995 def test_get_domain_literal_only(self):996 domain_literal = domain_literal = self._test_get_x(parser.get_domain_literal,997 '[127.0.0.1]',998 '[127.0.0.1]',999 '[127.0.0.1]',1000 [],1001 '')1002 self.assertEqual(domain_literal.token_type, 'domain-literal')1003 self.assertEqual(domain_literal.domain, '[127.0.0.1]')1004 self.assertEqual(domain_literal.ip, '127.0.0.1')1005 def test_get_domain_literal_with_internal_ws(self):1006 domain_literal = self._test_get_x(parser.get_domain_literal,1007 '[ 127.0.0.1\t ]',1008 '[ 127.0.0.1\t ]',1009 '[ 127.0.0.1 ]',1010 [],1011 '')1012 self.assertEqual(domain_literal.domain, '[127.0.0.1]')1013 self.assertEqual(domain_literal.ip, '127.0.0.1')1014 def test_get_domain_literal_with_surrounding_cfws(self):1015 domain_literal = self._test_get_x(parser.get_domain_literal,1016 '(foo)[ 127.0.0.1] (bar)',1017 '(foo)[ 127.0.0.1] (bar)',1018 ' [ 127.0.0.1] ',1019 [],1020 '')1021 self.assertEqual(domain_literal.domain, '[127.0.0.1]')1022 self.assertEqual(domain_literal.ip, '127.0.0.1')1023 def test_get_domain_literal_no_start_char_raises(self):1024 with self.assertRaises(errors.HeaderParseError):1025 parser.get_domain_literal('(foo) ')1026 def test_get_domain_literal_no_start_char_before_special_raises(self):1027 with self.assertRaises(errors.HeaderParseError):1028 parser.get_domain_literal('(foo) @')1029 def test_get_domain_literal_bad_dtext_char_before_special_raises(self):1030 with self.assertRaises(errors.HeaderParseError):1031 parser.get_domain_literal('(foo) [abc[@')1032 # get_domain1033 def test_get_domain_regular_domain_only(self):1034 domain = self._test_get_x(parser.get_domain,1035 'example.com',1036 'example.com',1037 'example.com',1038 [],1039 '')1040 self.assertEqual(domain.token_type, 'domain')1041 self.assertEqual(domain.domain, 'example.com')1042 def test_get_domain_domain_literal_only(self):1043 domain = self._test_get_x(parser.get_domain,1044 '[127.0.0.1]',1045 '[127.0.0.1]',1046 '[127.0.0.1]',1047 [],1048 '')1049 self.assertEqual(domain.token_type, 'domain')1050 self.assertEqual(domain.domain, '[127.0.0.1]')1051 def test_get_domain_with_cfws(self):1052 domain = self._test_get_x(parser.get_domain,1053 '(foo) example.com(bar)\t',1054 '(foo) example.com(bar)\t',1055 ' example.com ',1056 [],1057 '')1058 self.assertEqual(domain.domain, 'example.com')1059 def test_get_domain_domain_literal_with_cfws(self):1060 domain = self._test_get_x(parser.get_domain,1061 '(foo)[127.0.0.1]\t(bar)',1062 '(foo)[127.0.0.1]\t(bar)',1063 ' [127.0.0.1] ',1064 [],1065 '')1066 self.assertEqual(domain.domain, '[127.0.0.1]')1067 def test_get_domain_domain_with_cfws_ends_at_special(self):1068 domain = self._test_get_x(parser.get_domain,1069 '(foo)example.com\t(bar), next',1070 '(foo)example.com\t(bar)',1071 ' example.com ',1072 [],1073 ', next')1074 self.assertEqual(domain.domain, 'example.com')1075 def test_get_domain_domain_literal_with_cfws_ends_at_special(self):1076 domain = self._test_get_x(parser.get_domain,1077 '(foo)[127.0.0.1]\t(bar), next',1078 '(foo)[127.0.0.1]\t(bar)',1079 ' [127.0.0.1] ',1080 [],1081 ', next')1082 self.assertEqual(domain.domain, '[127.0.0.1]')1083 def test_get_domain_obsolete(self):1084 domain = self._test_get_x(parser.get_domain,1085 '(foo) example . (bird)com(bar)\t',1086 '(foo) example . (bird)com(bar)\t',1087 ' example . com ',1088 [errors.ObsoleteHeaderDefect],1089 '')1090 self.assertEqual(domain.domain, 'example.com')1091 def test_get_domain_no_non_cfws_raises(self):1092 with self.assertRaises(errors.HeaderParseError):1093 parser.get_domain(" (foo)\t")1094 def test_get_domain_no_atom_raises(self):1095 with self.assertRaises(errors.HeaderParseError):1096 parser.get_domain(" (foo)\t, broken")1097 # get_addr_spec1098 def test_get_addr_spec_normal(self):1099 addr_spec = self._test_get_x(parser.get_addr_spec,1100 'dinsdale@example.com',1101 'dinsdale@example.com',1102 'dinsdale@example.com',1103 [],1104 '')1105 self.assertEqual(addr_spec.token_type, 'addr-spec')1106 self.assertEqual(addr_spec.local_part, 'dinsdale')1107 self.assertEqual(addr_spec.domain, 'example.com')1108 self.assertEqual(addr_spec.addr_spec, 'dinsdale@example.com')1109 def test_get_addr_spec_with_doamin_literal(self):1110 addr_spec = self._test_get_x(parser.get_addr_spec,1111 'dinsdale@[127.0.0.1]',1112 'dinsdale@[127.0.0.1]',1113 'dinsdale@[127.0.0.1]',1114 [],1115 '')1116 self.assertEqual(addr_spec.local_part, 'dinsdale')1117 self.assertEqual(addr_spec.domain, '[127.0.0.1]')1118 self.assertEqual(addr_spec.addr_spec, 'dinsdale@[127.0.0.1]')1119 def test_get_addr_spec_with_cfws(self):1120 addr_spec = self._test_get_x(parser.get_addr_spec,1121 '(foo) dinsdale(bar)@ (bird) example.com (bog)',1122 '(foo) dinsdale(bar)@ (bird) example.com (bog)',1123 ' dinsdale@example.com ',1124 [],1125 '')1126 self.assertEqual(addr_spec.local_part, 'dinsdale')1127 self.assertEqual(addr_spec.domain, 'example.com')1128 self.assertEqual(addr_spec.addr_spec, 'dinsdale@example.com')1129 def test_get_addr_spec_with_qouoted_string_and_cfws(self):1130 addr_spec = self._test_get_x(parser.get_addr_spec,1131 '(foo) "roy a bug"(bar)@ (bird) example.com (bog)',1132 '(foo) "roy a bug"(bar)@ (bird) example.com (bog)',1133 ' "roy a bug"@example.com ',1134 [],1135 '')1136 self.assertEqual(addr_spec.local_part, 'roy a bug')1137 self.assertEqual(addr_spec.domain, 'example.com')1138 self.assertEqual(addr_spec.addr_spec, '"roy a bug"@example.com')1139 def test_get_addr_spec_ends_at_special(self):1140 addr_spec = self._test_get_x(parser.get_addr_spec,1141 '(foo) "roy a bug"(bar)@ (bird) example.com (bog) , next',1142 '(foo) "roy a bug"(bar)@ (bird) example.com (bog) ',1143 ' "roy a bug"@example.com ',1144 [],1145 ', next')1146 self.assertEqual(addr_spec.local_part, 'roy a bug')1147 self.assertEqual(addr_spec.domain, 'example.com')1148 self.assertEqual(addr_spec.addr_spec, '"roy a bug"@example.com')1149 def test_get_addr_spec_quoted_strings_in_atom_list(self):1150 addr_spec = self._test_get_x(parser.get_addr_spec,1151 '""example" example"@example.com',1152 '""example" example"@example.com',1153 'example example@example.com',1154 [errors.InvalidHeaderDefect]*3,1155 '')1156 self.assertEqual(addr_spec.local_part, 'example example')1157 self.assertEqual(addr_spec.domain, 'example.com')1158 self.assertEqual(addr_spec.addr_spec, '"example example"@example.com')1159 def test_get_addr_spec_dot_atom(self):1160 addr_spec = self._test_get_x(parser.get_addr_spec,1161 'star.a.star@example.com',1162 'star.a.star@example.com',1163 'star.a.star@example.com',1164 [],1165 '')1166 self.assertEqual(addr_spec.local_part, 'star.a.star')1167 self.assertEqual(addr_spec.domain, 'example.com')1168 self.assertEqual(addr_spec.addr_spec, 'star.a.star@example.com')1169 # get_obs_route1170 def test_get_obs_route_simple(self):1171 obs_route = self._test_get_x(parser.get_obs_route,1172 '@example.com, @two.example.com:',1173 '@example.com, @two.example.com:',1174 '@example.com, @two.example.com:',1175 [],1176 '')1177 self.assertEqual(obs_route.token_type, 'obs-route')1178 self.assertEqual(obs_route.domains, ['example.com', 'two.example.com'])1179 def test_get_obs_route_complex(self):1180 obs_route = self._test_get_x(parser.get_obs_route,1181 '(foo),, (blue)@example.com (bar),@two.(foo) example.com (bird):',1182 '(foo),, (blue)@example.com (bar),@two.(foo) example.com (bird):',1183 ' ,, @example.com ,@two. example.com :',1184 [errors.ObsoleteHeaderDefect], # This is the obs-domain1185 '')1186 self.assertEqual(obs_route.token_type, 'obs-route')1187 self.assertEqual(obs_route.domains, ['example.com', 'two.example.com'])1188 def test_get_obs_route_no_route_before_end_raises(self):1189 with self.assertRaises(errors.HeaderParseError):1190 parser.get_obs_route('(foo) @example.com,')1191 def test_get_obs_route_no_route_before_special_raises(self):1192 with self.assertRaises(errors.HeaderParseError):1193 parser.get_obs_route('(foo) [abc],')1194 def test_get_obs_route_no_route_before_special_raises2(self):1195 with self.assertRaises(errors.HeaderParseError):1196 parser.get_obs_route('(foo) @example.com [abc],')1197 # get_angle_addr1198 def test_get_angle_addr_simple(self):1199 angle_addr = self._test_get_x(parser.get_angle_addr,1200 '<dinsdale@example.com>',1201 '<dinsdale@example.com>',1202 '<dinsdale@example.com>',1203 [],1204 '')1205 self.assertEqual(angle_addr.token_type, 'angle-addr')1206 self.assertEqual(angle_addr.local_part, 'dinsdale')1207 self.assertEqual(angle_addr.domain, 'example.com')1208 self.assertIsNone(angle_addr.route)1209 self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')1210 def test_get_angle_addr_empty(self):1211 angle_addr = self._test_get_x(parser.get_angle_addr,1212 '<>',1213 '<>',1214 '<>',1215 [errors.InvalidHeaderDefect],1216 '')1217 self.assertEqual(angle_addr.token_type, 'angle-addr')1218 self.assertIsNone(angle_addr.local_part)1219 self.assertIsNone(angle_addr.domain)1220 self.assertIsNone(angle_addr.route)1221 self.assertEqual(angle_addr.addr_spec, '<>')1222 def test_get_angle_addr_with_cfws(self):1223 angle_addr = self._test_get_x(parser.get_angle_addr,1224 ' (foo) <dinsdale@example.com>(bar)',1225 ' (foo) <dinsdale@example.com>(bar)',1226 ' <dinsdale@example.com> ',1227 [],1228 '')1229 self.assertEqual(angle_addr.token_type, 'angle-addr')1230 self.assertEqual(angle_addr.local_part, 'dinsdale')1231 self.assertEqual(angle_addr.domain, 'example.com')1232 self.assertIsNone(angle_addr.route)1233 self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')1234 def test_get_angle_addr_qs_and_domain_literal(self):1235 angle_addr = self._test_get_x(parser.get_angle_addr,1236 '<"Fred Perfect"@[127.0.0.1]>',1237 '<"Fred Perfect"@[127.0.0.1]>',1238 '<"Fred Perfect"@[127.0.0.1]>',1239 [],1240 '')1241 self.assertEqual(angle_addr.local_part, 'Fred Perfect')1242 self.assertEqual(angle_addr.domain, '[127.0.0.1]')1243 self.assertIsNone(angle_addr.route)1244 self.assertEqual(angle_addr.addr_spec, '"Fred Perfect"@[127.0.0.1]')1245 def test_get_angle_addr_internal_cfws(self):1246 angle_addr = self._test_get_x(parser.get_angle_addr,1247 '<(foo) dinsdale@example.com(bar)>',1248 '<(foo) dinsdale@example.com(bar)>',1249 '< dinsdale@example.com >',1250 [],1251 '')1252 self.assertEqual(angle_addr.local_part, 'dinsdale')1253 self.assertEqual(angle_addr.domain, 'example.com')1254 self.assertIsNone(angle_addr.route)1255 self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')1256 def test_get_angle_addr_obs_route(self):1257 angle_addr = self._test_get_x(parser.get_angle_addr,1258 '(foo)<@example.com, (bird) @two.example.com: dinsdale@example.com> (bar) ',1259 '(foo)<@example.com, (bird) @two.example.com: dinsdale@example.com> (bar) ',1260 ' <@example.com, @two.example.com: dinsdale@example.com> ',1261 [errors.ObsoleteHeaderDefect],1262 '')1263 self.assertEqual(angle_addr.local_part, 'dinsdale')1264 self.assertEqual(angle_addr.domain, 'example.com')1265 self.assertEqual(angle_addr.route, ['example.com', 'two.example.com'])1266 self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')1267 def test_get_angle_addr_missing_closing_angle(self):1268 angle_addr = self._test_get_x(parser.get_angle_addr,1269 '<dinsdale@example.com',1270 '<dinsdale@example.com>',1271 '<dinsdale@example.com>',1272 [errors.InvalidHeaderDefect],1273 '')1274 self.assertEqual(angle_addr.local_part, 'dinsdale')1275 self.assertEqual(angle_addr.domain, 'example.com')1276 self.assertIsNone(angle_addr.route)1277 self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')1278 def test_get_angle_addr_missing_closing_angle_with_cfws(self):1279 angle_addr = self._test_get_x(parser.get_angle_addr,1280 '<dinsdale@example.com (foo)',1281 '<dinsdale@example.com (foo)>',1282 '<dinsdale@example.com >',1283 [errors.InvalidHeaderDefect],1284 '')1285 self.assertEqual(angle_addr.local_part, 'dinsdale')1286 self.assertEqual(angle_addr.domain, 'example.com')1287 self.assertIsNone(angle_addr.route)1288 self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')1289 def test_get_angle_addr_ends_at_special(self):1290 angle_addr = self._test_get_x(parser.get_angle_addr,1291 '<dinsdale@example.com> (foo), next',1292 '<dinsdale@example.com> (foo)',1293 '<dinsdale@example.com> ',1294 [],1295 ', next')1296 self.assertEqual(angle_addr.local_part, 'dinsdale')1297 self.assertEqual(angle_addr.domain, 'example.com')1298 self.assertIsNone(angle_addr.route)1299 self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')1300 def test_get_angle_addr_no_angle_raise(self):1301 with self.assertRaises(errors.HeaderParseError):1302 parser.get_angle_addr('(foo) ')1303 def test_get_angle_addr_no_angle_before_special_raises(self):1304 with self.assertRaises(errors.HeaderParseError):1305 parser.get_angle_addr('(foo) , next')1306 def test_get_angle_addr_no_angle_raises(self):1307 with self.assertRaises(errors.HeaderParseError):1308 parser.get_angle_addr('bar')1309 def test_get_angle_addr_special_after_angle_raises(self):1310 with self.assertRaises(errors.HeaderParseError):1311 parser.get_angle_addr('(foo) <, bar')1312 # get_display_name This is phrase but with a different value.1313 def test_get_display_name_simple(self):1314 display_name = self._test_get_x(parser.get_display_name,1315 'Fred A Johnson',1316 'Fred A Johnson',1317 'Fred A Johnson',1318 [],1319 '')1320 self.assertEqual(display_name.token_type, 'display-name')1321 self.assertEqual(display_name.display_name, 'Fred A Johnson')1322 def test_get_display_name_complex1(self):1323 display_name = self._test_get_x(parser.get_display_name,1324 '"Fred A. Johnson" is his name, oh.',1325 '"Fred A. Johnson" is his name',1326 '"Fred A. Johnson is his name"',1327 [],1328 ', oh.')1329 self.assertEqual(display_name.token_type, 'display-name')1330 self.assertEqual(display_name.display_name, 'Fred A. Johnson is his name')1331 def test_get_display_name_complex2(self):1332 display_name = self._test_get_x(parser.get_display_name,1333 ' (A) bird (in (my|your)) "hand " is messy\t<>\t',1334 ' (A) bird (in (my|your)) "hand " is messy\t',1335 ' "bird hand is messy" ',1336 [],1337 '<>\t')1338 self.assertEqual(display_name[0][0].comments, ['A'])1339 self.assertEqual(display_name[0][2].comments, ['in (my|your)'])1340 self.assertEqual(display_name.display_name, 'bird hand is messy')1341 def test_get_display_name_obsolete(self):1342 display_name = self._test_get_x(parser.get_display_name,1343 'Fred A.(weird).O Johnson',1344 'Fred A.(weird).O Johnson',1345 '"Fred A. .O Johnson"',1346 [errors.ObsoleteHeaderDefect]*3,1347 '')1348 self.assertEqual(len(display_name), 7)1349 self.assertEqual(display_name[3].comments, ['weird'])1350 self.assertEqual(display_name.display_name, 'Fred A. .O Johnson')1351 def test_get_display_name_pharse_must_start_with_word(self):1352 display_name = self._test_get_x(parser.get_display_name,1353 '(even weirder).name',1354 '(even weirder).name',1355 ' ".name"',1356 [errors.InvalidHeaderDefect] + [errors.ObsoleteHeaderDefect]*2,1357 '')1358 self.assertEqual(len(display_name), 3)1359 self.assertEqual(display_name[0].comments, ['even weirder'])1360 self.assertEqual(display_name.display_name, '.name')1361 def test_get_display_name_ending_with_obsolete(self):1362 display_name = self._test_get_x(parser.get_display_name,1363 'simple phrase.(with trailing comment):boo',1364 'simple phrase.(with trailing comment)',1365 '"simple phrase." ',1366 [errors.ObsoleteHeaderDefect]*2,1367 ':boo')1368 self.assertEqual(len(display_name), 4)1369 self.assertEqual(display_name[3].comments, ['with trailing comment'])1370 self.assertEqual(display_name.display_name, 'simple phrase.')1371 # get_name_addr1372 def test_get_name_addr_angle_addr_only(self):1373 name_addr = self._test_get_x(parser.get_name_addr,1374 '<dinsdale@example.com>',1375 '<dinsdale@example.com>',1376 '<dinsdale@example.com>',1377 [],1378 '')1379 self.assertEqual(name_addr.token_type, 'name-addr')1380 self.assertIsNone(name_addr.display_name)1381 self.assertEqual(name_addr.local_part, 'dinsdale')1382 self.assertEqual(name_addr.domain, 'example.com')1383 self.assertIsNone(name_addr.route)1384 self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')1385 def test_get_name_addr_atom_name(self):1386 name_addr = self._test_get_x(parser.get_name_addr,1387 'Dinsdale <dinsdale@example.com>',1388 'Dinsdale <dinsdale@example.com>',1389 'Dinsdale <dinsdale@example.com>',1390 [],1391 '')1392 self.assertEqual(name_addr.token_type, 'name-addr')1393 self.assertEqual(name_addr.display_name, 'Dinsdale')1394 self.assertEqual(name_addr.local_part, 'dinsdale')1395 self.assertEqual(name_addr.domain, 'example.com')1396 self.assertIsNone(name_addr.route)1397 self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')1398 def test_get_name_addr_atom_name_with_cfws(self):1399 name_addr = self._test_get_x(parser.get_name_addr,1400 '(foo) Dinsdale (bar) <dinsdale@example.com> (bird)',1401 '(foo) Dinsdale (bar) <dinsdale@example.com> (bird)',1402 ' Dinsdale <dinsdale@example.com> ',1403 [],1404 '')1405 self.assertEqual(name_addr.display_name, 'Dinsdale')1406 self.assertEqual(name_addr.local_part, 'dinsdale')1407 self.assertEqual(name_addr.domain, 'example.com')1408 self.assertIsNone(name_addr.route)1409 self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')1410 def test_get_name_addr_name_with_cfws_and_dots(self):1411 name_addr = self._test_get_x(parser.get_name_addr,1412 '(foo) Roy.A.Bear (bar) <dinsdale@example.com> (bird)',1413 '(foo) Roy.A.Bear (bar) <dinsdale@example.com> (bird)',1414 ' "Roy.A.Bear" <dinsdale@example.com> ',1415 [errors.ObsoleteHeaderDefect]*2,1416 '')1417 self.assertEqual(name_addr.display_name, 'Roy.A.Bear')1418 self.assertEqual(name_addr.local_part, 'dinsdale')1419 self.assertEqual(name_addr.domain, 'example.com')1420 self.assertIsNone(name_addr.route)1421 self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')1422 def test_get_name_addr_qs_name(self):1423 name_addr = self._test_get_x(parser.get_name_addr,1424 '"Roy.A.Bear" <dinsdale@example.com>',1425 '"Roy.A.Bear" <dinsdale@example.com>',1426 '"Roy.A.Bear" <dinsdale@example.com>',1427 [],1428 '')1429 self.assertEqual(name_addr.display_name, 'Roy.A.Bear')1430 self.assertEqual(name_addr.local_part, 'dinsdale')1431 self.assertEqual(name_addr.domain, 'example.com')1432 self.assertIsNone(name_addr.route)1433 self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')1434 def test_get_name_addr_with_route(self):1435 name_addr = self._test_get_x(parser.get_name_addr,1436 '"Roy.A.Bear" <@two.example.com: dinsdale@example.com>',1437 '"Roy.A.Bear" <@two.example.com: dinsdale@example.com>',1438 '"Roy.A.Bear" <@two.example.com: dinsdale@example.com>',1439 [errors.ObsoleteHeaderDefect],1440 '')1441 self.assertEqual(name_addr.display_name, 'Roy.A.Bear')1442 self.assertEqual(name_addr.local_part, 'dinsdale')1443 self.assertEqual(name_addr.domain, 'example.com')1444 self.assertEqual(name_addr.route, ['two.example.com'])1445 self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')1446 def test_get_name_addr_ends_at_special(self):1447 name_addr = self._test_get_x(parser.get_name_addr,1448 '"Roy.A.Bear" <dinsdale@example.com>, next',1449 '"Roy.A.Bear" <dinsdale@example.com>',1450 '"Roy.A.Bear" <dinsdale@example.com>',1451 [],1452 ', next')1453 self.assertEqual(name_addr.display_name, 'Roy.A.Bear')1454 self.assertEqual(name_addr.local_part, 'dinsdale')1455 self.assertEqual(name_addr.domain, 'example.com')1456 self.assertIsNone(name_addr.route)1457 self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')1458 def test_get_name_addr_no_content_raises(self):1459 with self.assertRaises(errors.HeaderParseError):1460 parser.get_name_addr(' (foo) ')1461 def test_get_name_addr_no_content_before_special_raises(self):1462 with self.assertRaises(errors.HeaderParseError):1463 parser.get_name_addr(' (foo) ,')1464 def test_get_name_addr_no_angle_after_display_name_raises(self):1465 with self.assertRaises(errors.HeaderParseError):1466 parser.get_name_addr('foo bar')1467 # get_mailbox1468 def test_get_mailbox_addr_spec_only(self):1469 mailbox = self._test_get_x(parser.get_mailbox,1470 'dinsdale@example.com',1471 'dinsdale@example.com',1472 'dinsdale@example.com',1473 [],1474 '')1475 self.assertEqual(mailbox.token_type, 'mailbox')1476 self.assertIsNone(mailbox.display_name)1477 self.assertEqual(mailbox.local_part, 'dinsdale')1478 self.assertEqual(mailbox.domain, 'example.com')1479 self.assertIsNone(mailbox.route)1480 self.assertEqual(mailbox.addr_spec, 'dinsdale@example.com')1481 def test_get_mailbox_angle_addr_only(self):1482 mailbox = self._test_get_x(parser.get_mailbox,1483 '<dinsdale@example.com>',1484 '<dinsdale@example.com>',1485 '<dinsdale@example.com>',1486 [],1487 '')1488 self.assertEqual(mailbox.token_type, 'mailbox')1489 self.assertIsNone(mailbox.display_name)1490 self.assertEqual(mailbox.local_part, 'dinsdale')1491 self.assertEqual(mailbox.domain, 'example.com')1492 self.assertIsNone(mailbox.route)1493 self.assertEqual(mailbox.addr_spec, 'dinsdale@example.com')1494 def test_get_mailbox_name_addr(self):1495 mailbox = self._test_get_x(parser.get_mailbox,1496 '"Roy A. Bear" <dinsdale@example.com>',1497 '"Roy A. Bear" <dinsdale@example.com>',1498 '"Roy A. Bear" <dinsdale@example.com>',1499 [],1500 '')1501 self.assertEqual(mailbox.token_type, 'mailbox')1502 self.assertEqual(mailbox.display_name, 'Roy A. Bear')1503 self.assertEqual(mailbox.local_part, 'dinsdale')1504 self.assertEqual(mailbox.domain, 'example.com')1505 self.assertIsNone(mailbox.route)1506 self.assertEqual(mailbox.addr_spec, 'dinsdale@example.com')1507 def test_get_mailbox_ends_at_special(self):1508 mailbox = self._test_get_x(parser.get_mailbox,1509 '"Roy A. Bear" <dinsdale@example.com>, rest',1510 '"Roy A. Bear" <dinsdale@example.com>',1511 '"Roy A. Bear" <dinsdale@example.com>',1512 [],1513 ', rest')1514 self.assertEqual(mailbox.token_type, 'mailbox')1515 self.assertEqual(mailbox.display_name, 'Roy A. Bear')1516 self.assertEqual(mailbox.local_part, 'dinsdale')1517 self.assertEqual(mailbox.domain, 'example.com')1518 self.assertIsNone(mailbox.route)1519 self.assertEqual(mailbox.addr_spec, 'dinsdale@example.com')1520 def test_get_mailbox_quoted_strings_in_atom_list(self):1521 mailbox = self._test_get_x(parser.get_mailbox,1522 '""example" example"@example.com',1523 '""example" example"@example.com',1524 'example example@example.com',1525 [errors.InvalidHeaderDefect]*3,1526 '')1527 self.assertEqual(mailbox.local_part, 'example example')1528 self.assertEqual(mailbox.domain, 'example.com')1529 self.assertEqual(mailbox.addr_spec, '"example example"@example.com')1530 # get_mailbox_list1531 def test_get_mailbox_list_single_addr(self):1532 mailbox_list = self._test_get_x(parser.get_mailbox_list,1533 'dinsdale@example.com',1534 'dinsdale@example.com',1535 'dinsdale@example.com',1536 [],1537 '')1538 self.assertEqual(mailbox_list.token_type, 'mailbox-list')1539 self.assertEqual(len(mailbox_list.mailboxes), 1)1540 mailbox = mailbox_list.mailboxes[0]1541 self.assertIsNone(mailbox.display_name)1542 self.assertEqual(mailbox.local_part, 'dinsdale')1543 self.assertEqual(mailbox.domain, 'example.com')1544 self.assertIsNone(mailbox.route)1545 self.assertEqual(mailbox.addr_spec, 'dinsdale@example.com')1546 self.assertEqual(mailbox_list.mailboxes,1547 mailbox_list.all_mailboxes)1548 def test_get_mailbox_list_two_simple_addr(self):1549 mailbox_list = self._test_get_x(parser.get_mailbox_list,1550 'dinsdale@example.com, dinsdale@test.example.com',1551 'dinsdale@example.com, dinsdale@test.example.com',1552 'dinsdale@example.com, dinsdale@test.example.com',1553 [],1554 '')1555 self.assertEqual(mailbox_list.token_type, 'mailbox-list')1556 self.assertEqual(len(mailbox_list.mailboxes), 2)1557 self.assertEqual(mailbox_list.mailboxes[0].addr_spec,1558 'dinsdale@example.com')1559 self.assertEqual(mailbox_list.mailboxes[1].addr_spec,1560 'dinsdale@test.example.com')1561 self.assertEqual(mailbox_list.mailboxes,1562 mailbox_list.all_mailboxes)1563 def test_get_mailbox_list_two_name_addr(self):1564 mailbox_list = self._test_get_x(parser.get_mailbox_list,1565 ('"Roy A. Bear" <dinsdale@example.com>,'1566 ' "Fred Flintstone" <dinsdale@test.example.com>'),1567 ('"Roy A. Bear" <dinsdale@example.com>,'1568 ' "Fred Flintstone" <dinsdale@test.example.com>'),1569 ('"Roy A. Bear" <dinsdale@example.com>,'1570 ' "Fred Flintstone" <dinsdale@test.example.com>'),1571 [],1572 '')1573 self.assertEqual(len(mailbox_list.mailboxes), 2)1574 self.assertEqual(mailbox_list.mailboxes[0].addr_spec,1575 'dinsdale@example.com')1576 self.assertEqual(mailbox_list.mailboxes[0].display_name,1577 'Roy A. Bear')1578 self.assertEqual(mailbox_list.mailboxes[1].addr_spec,1579 'dinsdale@test.example.com')1580 self.assertEqual(mailbox_list.mailboxes[1].display_name,1581 'Fred Flintstone')1582 self.assertEqual(mailbox_list.mailboxes,1583 mailbox_list.all_mailboxes)1584 def test_get_mailbox_list_two_complex(self):1585 mailbox_list = self._test_get_x(parser.get_mailbox_list,1586 ('(foo) "Roy A. Bear" <dinsdale@example.com>(bar),'1587 ' "Fred Flintstone" <dinsdale@test.(bird)example.com>'),1588 ('(foo) "Roy A. Bear" <dinsdale@example.com>(bar),'1589 ' "Fred Flintstone" <dinsdale@test.(bird)example.com>'),1590 (' "Roy A. Bear" <dinsdale@example.com> ,'1591 ' "Fred Flintstone" <dinsdale@test. example.com>'),1592 [errors.ObsoleteHeaderDefect],1593 '')1594 self.assertEqual(len(mailbox_list.mailboxes), 2)1595 self.assertEqual(mailbox_list.mailboxes[0].addr_spec,1596 'dinsdale@example.com')1597 self.assertEqual(mailbox_list.mailboxes[0].display_name,1598 'Roy A. Bear')1599 self.assertEqual(mailbox_list.mailboxes[1].addr_spec,1600 'dinsdale@test.example.com')1601 self.assertEqual(mailbox_list.mailboxes[1].display_name,1602 'Fred Flintstone')1603 self.assertEqual(mailbox_list.mailboxes,1604 mailbox_list.all_mailboxes)1605 def test_get_mailbox_list_unparseable_mailbox_null(self):1606 mailbox_list = self._test_get_x(parser.get_mailbox_list,1607 ('"Roy A. Bear"[] dinsdale@example.com,'1608 ' "Fred Flintstone" <dinsdale@test.(bird)example.com>'),1609 ('"Roy A. Bear"[] dinsdale@example.com,'1610 ' "Fred Flintstone" <dinsdale@test.(bird)example.com>'),1611 ('"Roy A. Bear"[] dinsdale@example.com,'1612 ' "Fred Flintstone" <dinsdale@test. example.com>'),1613 [errors.InvalidHeaderDefect, # the 'extra' text after the local part1614 errors.InvalidHeaderDefect, # the local part with no angle-addr1615 errors.ObsoleteHeaderDefect, # period in extra text (example.com)1616 errors.ObsoleteHeaderDefect], # (bird) in valid address.1617 '')1618 self.assertEqual(len(mailbox_list.mailboxes), 1)1619 self.assertEqual(len(mailbox_list.all_mailboxes), 2)1620 self.assertEqual(mailbox_list.all_mailboxes[0].token_type,1621 'invalid-mailbox')1622 self.assertIsNone(mailbox_list.all_mailboxes[0].display_name)1623 self.assertEqual(mailbox_list.all_mailboxes[0].local_part,1624 'Roy A. Bear')1625 self.assertIsNone(mailbox_list.all_mailboxes[0].domain)1626 self.assertEqual(mailbox_list.all_mailboxes[0].addr_spec,1627 '"Roy A. Bear"')1628 self.assertIs(mailbox_list.all_mailboxes[1],1629 mailbox_list.mailboxes[0])1630 self.assertEqual(mailbox_list.mailboxes[0].addr_spec,1631 'dinsdale@test.example.com')1632 self.assertEqual(mailbox_list.mailboxes[0].display_name,1633 'Fred Flintstone')1634 def test_get_mailbox_list_junk_after_valid_address(self):1635 mailbox_list = self._test_get_x(parser.get_mailbox_list,1636 ('"Roy A. Bear" <dinsdale@example.com>@@,'1637 ' "Fred Flintstone" <dinsdale@test.example.com>'),1638 ('"Roy A. Bear" <dinsdale@example.com>@@,'1639 ' "Fred Flintstone" <dinsdale@test.example.com>'),1640 ('"Roy A. Bear" <dinsdale@example.com>@@,'1641 ' "Fred Flintstone" <dinsdale@test.example.com>'),1642 [errors.InvalidHeaderDefect],1643 '')1644 self.assertEqual(len(mailbox_list.mailboxes), 1)1645 self.assertEqual(len(mailbox_list.all_mailboxes), 2)1646 self.assertEqual(mailbox_list.all_mailboxes[0].addr_spec,1647 'dinsdale@example.com')1648 self.assertEqual(mailbox_list.all_mailboxes[0].display_name,1649 'Roy A. Bear')1650 self.assertEqual(mailbox_list.all_mailboxes[0].token_type,1651 'invalid-mailbox')1652 self.assertIs(mailbox_list.all_mailboxes[1],1653 mailbox_list.mailboxes[0])1654 self.assertEqual(mailbox_list.mailboxes[0].addr_spec,1655 'dinsdale@test.example.com')1656 self.assertEqual(mailbox_list.mailboxes[0].display_name,1657 'Fred Flintstone')1658 def test_get_mailbox_list_empty_list_element(self):1659 mailbox_list = self._test_get_x(parser.get_mailbox_list,1660 ('"Roy A. Bear" <dinsdale@example.com>, (bird),,'1661 ' "Fred Flintstone" <dinsdale@test.example.com>'),1662 ('"Roy A. Bear" <dinsdale@example.com>, (bird),,'1663 ' "Fred Flintstone" <dinsdale@test.example.com>'),1664 ('"Roy A. Bear" <dinsdale@example.com>, ,,'1665 ' "Fred Flintstone" <dinsdale@test.example.com>'),1666 [errors.ObsoleteHeaderDefect]*2,1667 '')1668 self.assertEqual(len(mailbox_list.mailboxes), 2)1669 self.assertEqual(mailbox_list.all_mailboxes,1670 mailbox_list.mailboxes)1671 self.assertEqual(mailbox_list.all_mailboxes[0].addr_spec,1672 'dinsdale@example.com')1673 self.assertEqual(mailbox_list.all_mailboxes[0].display_name,1674 'Roy A. Bear')1675 self.assertEqual(mailbox_list.mailboxes[1].addr_spec,1676 'dinsdale@test.example.com')1677 self.assertEqual(mailbox_list.mailboxes[1].display_name,1678 'Fred Flintstone')1679 def test_get_mailbox_list_only_empty_elements(self):1680 mailbox_list = self._test_get_x(parser.get_mailbox_list,1681 '(foo),, (bar)',1682 '(foo),, (bar)',1683 ' ,, ',1684 [errors.ObsoleteHeaderDefect]*3,1685 '')1686 self.assertEqual(len(mailbox_list.mailboxes), 0)1687 self.assertEqual(mailbox_list.all_mailboxes,1688 mailbox_list.mailboxes)1689 # get_group_list1690 def test_get_group_list_cfws_only(self):1691 group_list = self._test_get_x(parser.get_group_list,1692 '(hidden);',1693 '(hidden)',1694 ' ',1695 [],1696 ';')1697 self.assertEqual(group_list.token_type, 'group-list')1698 self.assertEqual(len(group_list.mailboxes), 0)1699 self.assertEqual(group_list.mailboxes,1700 group_list.all_mailboxes)1701 def test_get_group_list_mailbox_list(self):1702 group_list = self._test_get_x(parser.get_group_list,1703 'dinsdale@example.org, "Fred A. Bear" <dinsdale@example.org>',1704 'dinsdale@example.org, "Fred A. Bear" <dinsdale@example.org>',1705 'dinsdale@example.org, "Fred A. Bear" <dinsdale@example.org>',1706 [],1707 '')1708 self.assertEqual(group_list.token_type, 'group-list')1709 self.assertEqual(len(group_list.mailboxes), 2)1710 self.assertEqual(group_list.mailboxes,1711 group_list.all_mailboxes)1712 self.assertEqual(group_list.mailboxes[1].display_name,1713 'Fred A. Bear')1714 def test_get_group_list_obs_group_list(self):1715 group_list = self._test_get_x(parser.get_group_list,1716 ', (foo),,(bar)',1717 ', (foo),,(bar)',1718 ', ,, ',1719 [errors.ObsoleteHeaderDefect],1720 '')1721 self.assertEqual(group_list.token_type, 'group-list')1722 self.assertEqual(len(group_list.mailboxes), 0)1723 self.assertEqual(group_list.mailboxes,1724 group_list.all_mailboxes)1725 def test_get_group_list_comment_only_invalid(self):1726 group_list = self._test_get_x(parser.get_group_list,1727 '(bar)',1728 '(bar)',1729 ' ',1730 [errors.InvalidHeaderDefect],1731 '')1732 self.assertEqual(group_list.token_type, 'group-list')1733 self.assertEqual(len(group_list.mailboxes), 0)1734 self.assertEqual(group_list.mailboxes,1735 group_list.all_mailboxes)1736 # get_group1737 def test_get_group_empty(self):1738 group = self._test_get_x(parser.get_group,1739 'Monty Python:;',1740 'Monty Python:;',1741 'Monty Python:;',1742 [],1743 '')1744 self.assertEqual(group.token_type, 'group')1745 self.assertEqual(group.display_name, 'Monty Python')1746 self.assertEqual(len(group.mailboxes), 0)1747 self.assertEqual(group.mailboxes,1748 group.all_mailboxes)1749 def test_get_group_null_addr_spec(self):1750 group = self._test_get_x(parser.get_group,1751 'foo: <>;',1752 'foo: <>;',1753 'foo: <>;',1754 [errors.InvalidHeaderDefect],1755 '')1756 self.assertEqual(group.display_name, 'foo')1757 self.assertEqual(len(group.mailboxes), 0)1758 self.assertEqual(len(group.all_mailboxes), 1)1759 self.assertEqual(group.all_mailboxes[0].value, '<>')1760 def test_get_group_cfws_only(self):1761 group = self._test_get_x(parser.get_group,1762 'Monty Python: (hidden);',1763 'Monty Python: (hidden);',1764 'Monty Python: ;',1765 [],1766 '')1767 self.assertEqual(group.token_type, 'group')1768 self.assertEqual(group.display_name, 'Monty Python')1769 self.assertEqual(len(group.mailboxes), 0)1770 self.assertEqual(group.mailboxes,1771 group.all_mailboxes)1772 def test_get_group_single_mailbox(self):1773 group = self._test_get_x(parser.get_group,1774 'Monty Python: "Fred A. Bear" <dinsdale@example.com>;',1775 'Monty Python: "Fred A. Bear" <dinsdale@example.com>;',1776 'Monty Python: "Fred A. Bear" <dinsdale@example.com>;',1777 [],1778 '')1779 self.assertEqual(group.token_type, 'group')1780 self.assertEqual(group.display_name, 'Monty Python')1781 self.assertEqual(len(group.mailboxes), 1)1782 self.assertEqual(group.mailboxes,1783 group.all_mailboxes)1784 self.assertEqual(group.mailboxes[0].addr_spec,1785 'dinsdale@example.com')1786 def test_get_group_mixed_list(self):1787 group = self._test_get_x(parser.get_group,1788 ('Monty Python: "Fred A. Bear" <dinsdale@example.com>,'1789 '(foo) Roger <ping@exampele.com>, x@test.example.com;'),1790 ('Monty Python: "Fred A. Bear" <dinsdale@example.com>,'1791 '(foo) Roger <ping@exampele.com>, x@test.example.com;'),1792 ('Monty Python: "Fred A. Bear" <dinsdale@example.com>,'1793 ' Roger <ping@exampele.com>, x@test.example.com;'),1794 [],1795 '')1796 self.assertEqual(group.token_type, 'group')1797 self.assertEqual(group.display_name, 'Monty Python')1798 self.assertEqual(len(group.mailboxes), 3)1799 self.assertEqual(group.mailboxes,1800 group.all_mailboxes)1801 self.assertEqual(group.mailboxes[0].display_name,1802 'Fred A. Bear')1803 self.assertEqual(group.mailboxes[1].display_name,1804 'Roger')1805 self.assertEqual(group.mailboxes[2].local_part, 'x')1806 def test_get_group_one_invalid(self):1807 group = self._test_get_x(parser.get_group,1808 ('Monty Python: "Fred A. Bear" <dinsdale@example.com>,'1809 '(foo) Roger ping@exampele.com, x@test.example.com;'),1810 ('Monty Python: "Fred A. Bear" <dinsdale@example.com>,'1811 '(foo) Roger ping@exampele.com, x@test.example.com;'),1812 ('Monty Python: "Fred A. Bear" <dinsdale@example.com>,'1813 ' Roger ping@exampele.com, x@test.example.com;'),1814 [errors.InvalidHeaderDefect, # non-angle addr makes local part invalid1815 errors.InvalidHeaderDefect], # and its not obs-local either: no dots.1816 '')1817 self.assertEqual(group.token_type, 'group')1818 self.assertEqual(group.display_name, 'Monty Python')1819 self.assertEqual(len(group.mailboxes), 2)1820 self.assertEqual(len(group.all_mailboxes), 3)1821 self.assertEqual(group.mailboxes[0].display_name,1822 'Fred A. Bear')1823 self.assertEqual(group.mailboxes[1].local_part, 'x')1824 self.assertIsNone(group.all_mailboxes[1].display_name)1825 # get_address1826 def test_get_address_simple(self):1827 address = self._test_get_x(parser.get_address,1828 'dinsdale@example.com',1829 'dinsdale@example.com',1830 'dinsdale@example.com',1831 [],1832 '')1833 self.assertEqual(address.token_type, 'address')1834 self.assertEqual(len(address.mailboxes), 1)1835 self.assertEqual(address.mailboxes,1836 address.all_mailboxes)1837 self.assertEqual(address.mailboxes[0].domain,1838 'example.com')1839 self.assertEqual(address[0].token_type,1840 'mailbox')1841 def test_get_address_complex(self):1842 address = self._test_get_x(parser.get_address,1843 '(foo) "Fred A. Bear" <(bird)dinsdale@example.com>',1844 '(foo) "Fred A. Bear" <(bird)dinsdale@example.com>',1845 ' "Fred A. Bear" < dinsdale@example.com>',1846 [],1847 '')1848 self.assertEqual(address.token_type, 'address')1849 self.assertEqual(len(address.mailboxes), 1)1850 self.assertEqual(address.mailboxes,1851 address.all_mailboxes)1852 self.assertEqual(address.mailboxes[0].display_name,1853 'Fred A. Bear')1854 self.assertEqual(address[0].token_type,1855 'mailbox')1856 def test_get_address_rfc2047_display_name(self):1857 address = self._test_get_x(parser.get_address,1858 '=?utf-8?q?=C3=89ric?= <foo@example.com>',1859 'Ãric <foo@example.com>',1860 'Ãric <foo@example.com>',1861 [],1862 '')1863 self.assertEqual(address.token_type, 'address')1864 self.assertEqual(len(address.mailboxes), 1)1865 self.assertEqual(address.mailboxes,1866 address.all_mailboxes)1867 self.assertEqual(address.mailboxes[0].display_name,1868 'Ãric')1869 self.assertEqual(address[0].token_type,1870 'mailbox')1871 def test_get_address_empty_group(self):1872 address = self._test_get_x(parser.get_address,1873 'Monty Python:;',1874 'Monty Python:;',1875 'Monty Python:;',1876 [],1877 '')1878 self.assertEqual(address.token_type, 'address')1879 self.assertEqual(len(address.mailboxes), 0)1880 self.assertEqual(address.mailboxes,1881 address.all_mailboxes)1882 self.assertEqual(address[0].token_type,1883 'group')1884 self.assertEqual(address[0].display_name,1885 'Monty Python')1886 def test_get_address_group(self):1887 address = self._test_get_x(parser.get_address,1888 'Monty Python: x@example.com, y@example.com;',1889 'Monty Python: x@example.com, y@example.com;',1890 'Monty Python: x@example.com, y@example.com;',1891 [],1892 '')1893 self.assertEqual(address.token_type, 'address')1894 self.assertEqual(len(address.mailboxes), 2)1895 self.assertEqual(address.mailboxes,1896 address.all_mailboxes)1897 self.assertEqual(address[0].token_type,1898 'group')1899 self.assertEqual(address[0].display_name,1900 'Monty Python')1901 self.assertEqual(address.mailboxes[0].local_part, 'x')1902 def test_get_address_quoted_local_part(self):1903 address = self._test_get_x(parser.get_address,1904 '"foo bar"@example.com',1905 '"foo bar"@example.com',1906 '"foo bar"@example.com',1907 [],1908 '')1909 self.assertEqual(address.token_type, 'address')1910 self.assertEqual(len(address.mailboxes), 1)1911 self.assertEqual(address.mailboxes,1912 address.all_mailboxes)1913 self.assertEqual(address.mailboxes[0].domain,1914 'example.com')1915 self.assertEqual(address.mailboxes[0].local_part,1916 'foo bar')1917 self.assertEqual(address[0].token_type, 'mailbox')1918 def test_get_address_ends_at_special(self):1919 address = self._test_get_x(parser.get_address,1920 'dinsdale@example.com, next',1921 'dinsdale@example.com',1922 'dinsdale@example.com',1923 [],1924 ', next')1925 self.assertEqual(address.token_type, 'address')1926 self.assertEqual(len(address.mailboxes), 1)1927 self.assertEqual(address.mailboxes,1928 address.all_mailboxes)1929 self.assertEqual(address.mailboxes[0].domain,1930 'example.com')1931 self.assertEqual(address[0].token_type, 'mailbox')1932 def test_get_address_invalid_mailbox_invalid(self):1933 address = self._test_get_x(parser.get_address,1934 'ping example.com, next',1935 'ping example.com',1936 'ping example.com',1937 [errors.InvalidHeaderDefect, # addr-spec with no domain1938 errors.InvalidHeaderDefect, # invalid local-part1939 errors.InvalidHeaderDefect, # missing .s in local-part1940 ],1941 ', next')1942 self.assertEqual(address.token_type, 'address')1943 self.assertEqual(len(address.mailboxes), 0)1944 self.assertEqual(len(address.all_mailboxes), 1)1945 self.assertIsNone(address.all_mailboxes[0].domain)1946 self.assertEqual(address.all_mailboxes[0].local_part, 'ping example.com')1947 self.assertEqual(address[0].token_type, 'invalid-mailbox')1948 def test_get_address_quoted_strings_in_atom_list(self):1949 address = self._test_get_x(parser.get_address,1950 '""example" example"@example.com',1951 '""example" example"@example.com',1952 'example example@example.com',1953 [errors.InvalidHeaderDefect]*3,1954 '')1955 self.assertEqual(address.all_mailboxes[0].local_part, 'example example')1956 self.assertEqual(address.all_mailboxes[0].domain, 'example.com')1957 self.assertEqual(address.all_mailboxes[0].addr_spec, '"example example"@example.com')1958 # get_address_list1959 def test_get_address_list_mailboxes_simple(self):1960 address_list = self._test_get_x(parser.get_address_list,1961 'dinsdale@example.com',1962 'dinsdale@example.com',1963 'dinsdale@example.com',1964 [],1965 '')1966 self.assertEqual(address_list.token_type, 'address-list')1967 self.assertEqual(len(address_list.mailboxes), 1)1968 self.assertEqual(address_list.mailboxes,1969 address_list.all_mailboxes)1970 self.assertEqual([str(x) for x in address_list.mailboxes],1971 [str(x) for x in address_list.addresses])1972 self.assertEqual(address_list.mailboxes[0].domain, 'example.com')1973 self.assertEqual(address_list[0].token_type, 'address')1974 self.assertIsNone(address_list[0].display_name)1975 def test_get_address_list_mailboxes_two_simple(self):1976 address_list = self._test_get_x(parser.get_address_list,1977 'foo@example.com, "Fred A. Bar" <bar@example.com>',1978 'foo@example.com, "Fred A. Bar" <bar@example.com>',1979 'foo@example.com, "Fred A. Bar" <bar@example.com>',1980 [],1981 '')1982 self.assertEqual(address_list.token_type, 'address-list')1983 self.assertEqual(len(address_list.mailboxes), 2)1984 self.assertEqual(address_list.mailboxes,1985 address_list.all_mailboxes)1986 self.assertEqual([str(x) for x in address_list.mailboxes],1987 [str(x) for x in address_list.addresses])1988 self.assertEqual(address_list.mailboxes[0].local_part, 'foo')1989 self.assertEqual(address_list.mailboxes[1].display_name, "Fred A. Bar")1990 def test_get_address_list_mailboxes_complex(self):1991 address_list = self._test_get_x(parser.get_address_list,1992 ('"Roy A. Bear" <dinsdale@example.com>, '1993 '(ping) Foo <x@example.com>,'1994 'Nobody Is. Special <y@(bird)example.(bad)com>'),1995 ('"Roy A. Bear" <dinsdale@example.com>, '1996 '(ping) Foo <x@example.com>,'1997 'Nobody Is. Special <y@(bird)example.(bad)com>'),1998 ('"Roy A. Bear" <dinsdale@example.com>, '1999 'Foo <x@example.com>,'2000 '"Nobody Is. Special" <y@example. com>'),2001 [errors.ObsoleteHeaderDefect, # period in Is.2002 errors.ObsoleteHeaderDefect], # cfws in domain2003 '')2004 self.assertEqual(address_list.token_type, 'address-list')2005 self.assertEqual(len(address_list.mailboxes), 3)2006 self.assertEqual(address_list.mailboxes,2007 address_list.all_mailboxes)2008 self.assertEqual([str(x) for x in address_list.mailboxes],2009 [str(x) for x in address_list.addresses])2010 self.assertEqual(address_list.mailboxes[0].domain, 'example.com')2011 self.assertEqual(address_list.mailboxes[0].token_type, 'mailbox')2012 self.assertEqual(address_list.addresses[0].token_type, 'address')2013 self.assertEqual(address_list.mailboxes[1].local_part, 'x')2014 self.assertEqual(address_list.mailboxes[2].display_name,2015 'Nobody Is. Special')2016 def test_get_address_list_mailboxes_invalid_addresses(self):2017 address_list = self._test_get_x(parser.get_address_list,2018 ('"Roy A. Bear" <dinsdale@example.com>, '2019 '(ping) Foo x@example.com[],'2020 'Nobody Is. Special <(bird)example.(bad)com>'),2021 ('"Roy A. Bear" <dinsdale@example.com>, '2022 '(ping) Foo x@example.com[],'2023 'Nobody Is. Special <(bird)example.(bad)com>'),2024 ('"Roy A. Bear" <dinsdale@example.com>, '2025 'Foo x@example.com[],'2026 '"Nobody Is. Special" < example. com>'),2027 [errors.InvalidHeaderDefect, # invalid address in list2028 errors.InvalidHeaderDefect, # 'Foo x' local part invalid.2029 errors.InvalidHeaderDefect, # Missing . in 'Foo x' local part2030 errors.ObsoleteHeaderDefect, # period in 'Is.' disp-name phrase2031 errors.InvalidHeaderDefect, # no domain part in addr-spec2032 errors.ObsoleteHeaderDefect], # addr-spec has comment in it2033 '')2034 self.assertEqual(address_list.token_type, 'address-list')2035 self.assertEqual(len(address_list.mailboxes), 1)2036 self.assertEqual(len(address_list.all_mailboxes), 3)2037 self.assertEqual([str(x) for x in address_list.all_mailboxes],2038 [str(x) for x in address_list.addresses])2039 self.assertEqual(address_list.mailboxes[0].domain, 'example.com')2040 self.assertEqual(address_list.mailboxes[0].token_type, 'mailbox')2041 self.assertEqual(address_list.addresses[0].token_type, 'address')2042 self.assertEqual(address_list.addresses[1].token_type, 'address')2043 self.assertEqual(len(address_list.addresses[0].mailboxes), 1)2044 self.assertEqual(len(address_list.addresses[1].mailboxes), 0)2045 self.assertEqual(len(address_list.addresses[1].mailboxes), 0)2046 self.assertEqual(2047 address_list.addresses[1].all_mailboxes[0].local_part, 'Foo x')2048 self.assertEqual(2049 address_list.addresses[2].all_mailboxes[0].display_name,2050 "Nobody Is. Special")2051 def test_get_address_list_group_empty(self):2052 address_list = self._test_get_x(parser.get_address_list,2053 'Monty Python: ;',2054 'Monty Python: ;',2055 'Monty Python: ;',2056 [],2057 '')2058 self.assertEqual(address_list.token_type, 'address-list')2059 self.assertEqual(len(address_list.mailboxes), 0)2060 self.assertEqual(address_list.mailboxes,2061 address_list.all_mailboxes)2062 self.assertEqual(len(address_list.addresses), 1)2063 self.assertEqual(address_list.addresses[0].token_type, 'address')2064 self.assertEqual(address_list.addresses[0].display_name, 'Monty Python')2065 self.assertEqual(len(address_list.addresses[0].mailboxes), 0)2066 def test_get_address_list_group_simple(self):2067 address_list = self._test_get_x(parser.get_address_list,2068 'Monty Python: dinsdale@example.com;',2069 'Monty Python: dinsdale@example.com;',2070 'Monty Python: dinsdale@example.com;',2071 [],2072 '')2073 self.assertEqual(address_list.token_type, 'address-list')2074 self.assertEqual(len(address_list.mailboxes), 1)2075 self.assertEqual(address_list.mailboxes,2076 address_list.all_mailboxes)2077 self.assertEqual(address_list.mailboxes[0].domain, 'example.com')2078 self.assertEqual(address_list.addresses[0].display_name,2079 'Monty Python')2080 self.assertEqual(address_list.addresses[0].mailboxes[0].domain,2081 'example.com')2082 def test_get_address_list_group_and_mailboxes(self):2083 address_list = self._test_get_x(parser.get_address_list,2084 ('Monty Python: dinsdale@example.com, "Fred" <flint@example.com>;, '2085 'Abe <x@example.com>, Bee <y@example.com>'),2086 ('Monty Python: dinsdale@example.com, "Fred" <flint@example.com>;, '2087 'Abe <x@example.com>, Bee <y@example.com>'),2088 ('Monty Python: dinsdale@example.com, "Fred" <flint@example.com>;, '2089 'Abe <x@example.com>, Bee <y@example.com>'),2090 [],2091 '')2092 self.assertEqual(address_list.token_type, 'address-list')2093 self.assertEqual(len(address_list.mailboxes), 4)2094 self.assertEqual(address_list.mailboxes,2095 address_list.all_mailboxes)2096 self.assertEqual(len(address_list.addresses), 3)2097 self.assertEqual(address_list.mailboxes[0].local_part, 'dinsdale')2098 self.assertEqual(address_list.addresses[0].display_name,2099 'Monty Python')2100 self.assertEqual(address_list.addresses[0].mailboxes[0].domain,2101 'example.com')2102 self.assertEqual(address_list.addresses[0].mailboxes[1].local_part,2103 'flint')2104 self.assertEqual(address_list.addresses[1].mailboxes[0].local_part,2105 'x')2106 self.assertEqual(address_list.addresses[2].mailboxes[0].local_part,2107 'y')2108 self.assertEqual(str(address_list.addresses[1]),2109 str(address_list.mailboxes[2]))2110@parameterize2111class Test_parse_mime_version(TestParserMixin, TestEmailBase):2112 def mime_version_as_value(self,2113 value,2114 tl_str,2115 tl_value,2116 major,2117 minor,2118 defects):2119 mime_version = self._test_parse_x(parser.parse_mime_version,2120 value, tl_str, tl_value, defects)2121 self.assertEqual(mime_version.major, major)2122 self.assertEqual(mime_version.minor, minor)2123 mime_version_params = {2124 'rfc_2045_1': (2125 '1.0',2126 '1.0',2127 '1.0',2128 1,2129 0,2130 []),2131 'RFC_2045_2': (2132 '1.0 (produced by MetaSend Vx.x)',2133 '1.0 (produced by MetaSend Vx.x)',2134 '1.0 ',2135 1,2136 0,2137 []),2138 'RFC_2045_3': (2139 '(produced by MetaSend Vx.x) 1.0',2140 '(produced by MetaSend Vx.x) 1.0',2141 ' 1.0',2142 1,2143 0,2144 []),2145 'RFC_2045_4': (2146 '1.(produced by MetaSend Vx.x)0',2147 '1.(produced by MetaSend Vx.x)0',2148 '1. 0',2149 1,2150 0,2151 []),2152 'empty': (2153 '',2154 '',2155 '',2156 None,2157 None,2158 [errors.HeaderMissingRequiredValue]),2159 }2160class TestFolding(TestEmailBase):2161 policy = policy.default2162 def _test(self, tl, folded, policy=policy):2163 self.assertEqual(tl.fold(policy=policy), folded, tl.ppstr())2164 def test_simple_unstructured_no_folds(self):2165 self._test(parser.get_unstructured("This is a test"),2166 "This is a test\n")2167 def test_simple_unstructured_folded(self):2168 self._test(parser.get_unstructured("This is also a test, but this "2169 "time there are enough words (and even some "2170 "symbols) to make it wrap; at least in theory."),2171 "This is also a test, but this time there are enough "2172 "words (and even some\n"2173 " symbols) to make it wrap; at least in theory.\n")2174 def test_unstructured_with_unicode_no_folds(self):2175 self._test(parser.get_unstructured("hübsch kleiner beiÃt"),2176 "=?utf-8?q?h=C3=BCbsch_kleiner_bei=C3=9Ft?=\n")2177 def test_one_ew_on_each_of_two_wrapped_lines(self):2178 self._test(parser.get_unstructured("Mein kleiner Kaktus ist sehr "2179 "hübsch. Es hat viele Stacheln "2180 "und oft beiÃt mich."),2181 "Mein kleiner Kaktus ist sehr =?utf-8?q?h=C3=BCbsch=2E?= "2182 "Es hat viele Stacheln\n"2183 " und oft =?utf-8?q?bei=C3=9Ft?= mich.\n")2184 def test_ews_combined_before_wrap(self):2185 self._test(parser.get_unstructured("Mein Kaktus ist hübsch. "2186 "Es beiÃt mich. "2187 "And that's all I'm sayin."),2188 "Mein Kaktus ist =?utf-8?q?h=C3=BCbsch=2E__Es_bei=C3=9Ft?= "2189 "mich. And that's\n"2190 " all I'm sayin.\n")2191 # XXX Need test of an encoded word so long that it needs to be wrapped2192 def test_simple_address(self):2193 self._test(parser.get_address_list("abc <xyz@example.com>")[0],2194 "abc <xyz@example.com>\n")2195 def test_address_list_folding_at_commas(self):2196 self._test(parser.get_address_list('abc <xyz@example.com>, '2197 '"Fred Blunt" <sharp@example.com>, '2198 '"J.P.Cool" <hot@example.com>, '2199 '"K<>y" <key@example.com>, '2200 'Firesale <cheap@example.com>, '2201 '<end@example.com>')[0],2202 'abc <xyz@example.com>, "Fred Blunt" <sharp@example.com>,\n'2203 ' "J.P.Cool" <hot@example.com>, "K<>y" <key@example.com>,\n'2204 ' Firesale <cheap@example.com>, <end@example.com>\n')2205 def test_address_list_with_unicode_names(self):2206 self._test(parser.get_address_list(2207 'Hübsch Kaktus <beautiful@example.com>, '2208 'beiÃt beiÃt <biter@example.com>')[0],2209 '=?utf-8?q?H=C3=BCbsch?= Kaktus <beautiful@example.com>,\n'2210 ' =?utf-8?q?bei=C3=9Ft_bei=C3=9Ft?= <biter@example.com>\n')2211 def test_address_list_with_unicode_names_in_quotes(self):2212 self._test(parser.get_address_list(2213 '"Hübsch Kaktus" <beautiful@example.com>, '2214 '"beiÃt" beiÃt <biter@example.com>')[0],2215 '=?utf-8?q?H=C3=BCbsch?= Kaktus <beautiful@example.com>,\n'2216 ' =?utf-8?q?bei=C3=9Ft_bei=C3=9Ft?= <biter@example.com>\n')2217 # XXX Need tests with comments on various sides of a unicode token,2218 # and with unicode tokens in the comments. Spaces inside the quotes2219 # currently don't do the right thing.2220 def test_initial_whitespace_splitting(self):2221 body = parser.get_unstructured(' ' + 'x'*77)2222 header = parser.Header([2223 parser.HeaderLabel([parser.ValueTerminal('test:', 'atext')]),2224 parser.CFWSList([parser.WhiteSpaceTerminal(' ', 'fws')]), body])2225 self._test(header, 'test: \n ' + 'x'*77 + '\n')2226 def test_whitespace_splitting(self):2227 self._test(parser.get_unstructured('xxx ' + 'y'*77),2228 'xxx \n ' + 'y'*77 + '\n')2229if __name__ == '__main__':...
test_getEstimatedSuitCounts.py
Source:test_getEstimatedSuitCounts.py
1#add case where pass then 3 level response means 1 more than min?2import helpers3import getEstimatedSuitCounts4import unittest, testCases5def getObject(biddingRelative = None):6 seatingRelative = {7 "top": "TopPlayer",8 "bottom": "BottomPlayer",9 "left": "LeftPlayer",10 "right": "RightPlayer",11 }12 biddingAbsolute = helpers.getBiddingAbsoluteFromBiddingObjAndSeatingRelative(biddingRelative, seatingRelative)13 obj = getEstimatedSuitCounts.EstimateSuitCounts(biddingRelative, biddingAbsolute, seatingRelative)14 return obj15class OneBidOpportunity(unittest.TestCase):16 def setUp(self) -> None:17 self.actual = {}18 self.expected = {}19 def tearDown(self) -> None:20 print('')21 print('biddingRelative ={0}'.format (self.biddingRelative))22 print('')23 print('actual:--------------------')24 for location, values in self.actual.items():25 print(location)26 print(f'\t{values}')27 print('')28 print('expected:--------------------')29 for location, values in self.expected.items():30 print(location)31 print(f'\t{values}')32 print('')33 def test_default(self):34 self.biddingRelative = {35 "left": [],36 "top": [],37 "right": [],38 "bottom": [],39 }40 self.obj = getObject(self.biddingRelative)41 print(self.obj)42 self.expected = {43 "left": {44 getEstimatedSuitCounts.suits["clubs"]: {45 "min": getEstimatedSuitCounts.minDefaultValue,46 "expected": getEstimatedSuitCounts.expectedValue,47 },48 getEstimatedSuitCounts.suits["diamonds"]: {49 "min": getEstimatedSuitCounts.minDefaultValue,50 "expected": getEstimatedSuitCounts.expectedValue,51 },52 getEstimatedSuitCounts.suits["hearts"]: {53 "min": getEstimatedSuitCounts.minDefaultValue,54 "expected": getEstimatedSuitCounts.expectedValue,55 },56 getEstimatedSuitCounts.suits["spades"]: {57 "min": getEstimatedSuitCounts.minDefaultValue,58 "expected": getEstimatedSuitCounts.expectedValue,59 },60 },61 "top": {62 getEstimatedSuitCounts.suits["clubs"]: {63 "min": getEstimatedSuitCounts.minDefaultValue,64 "expected": getEstimatedSuitCounts.expectedValue,65 },66 getEstimatedSuitCounts.suits["diamonds"]: {67 "min": getEstimatedSuitCounts.minDefaultValue,68 "expected": getEstimatedSuitCounts.expectedValue,69 },70 getEstimatedSuitCounts.suits["hearts"]: {71 "min": getEstimatedSuitCounts.minDefaultValue,72 "expected": getEstimatedSuitCounts.expectedValue,73 },74 getEstimatedSuitCounts.suits["spades"]: {75 "min": getEstimatedSuitCounts.minDefaultValue,76 "expected": getEstimatedSuitCounts.expectedValue,77 }, 78 },79 "right": {80 getEstimatedSuitCounts.suits["clubs"]: {81 "min": getEstimatedSuitCounts.minDefaultValue,82 "expected": getEstimatedSuitCounts.expectedValue,83 },84 getEstimatedSuitCounts.suits["diamonds"]: {85 "min": getEstimatedSuitCounts.minDefaultValue,86 "expected": getEstimatedSuitCounts.expectedValue,87 },88 getEstimatedSuitCounts.suits["hearts"]: {89 "min": getEstimatedSuitCounts.minDefaultValue,90 "expected": getEstimatedSuitCounts.expectedValue,91 },92 getEstimatedSuitCounts.suits["spades"]: {93 "min": getEstimatedSuitCounts.minDefaultValue,94 "expected": getEstimatedSuitCounts.expectedValue,95 },96 },97 }98 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts99 self.assertDictEqual(self.expected, self.actual)100 101 def test_open_minor(self):102 self.biddingRelative = {103 "left": ['One Diamond'],104 "top": ['pass'],105 "right": ['pass'],106 "bottom": [],107 }108 self.obj = getObject(self.biddingRelative)109 print(self.obj)110 self.expected = {111 "left": {112 getEstimatedSuitCounts.suits["clubs"]: {113 "min": getEstimatedSuitCounts.minDefaultValue,114 "expected": getEstimatedSuitCounts.expectedValue,115 },116 getEstimatedSuitCounts.suits["diamonds"]: {117 "min": getEstimatedSuitCounts.openMinorMinValue,118 "expected": getEstimatedSuitCounts.expectedValue,119 },120 getEstimatedSuitCounts.suits["hearts"]: {121 "min": getEstimatedSuitCounts.minDefaultValue,122 "expected": getEstimatedSuitCounts.expectedValue,123 },124 getEstimatedSuitCounts.suits["spades"]: {125 "min": getEstimatedSuitCounts.minDefaultValue,126 "expected": getEstimatedSuitCounts.expectedValue,127 },128 },129 "top": {130 getEstimatedSuitCounts.suits["clubs"]: {131 "min": getEstimatedSuitCounts.minDefaultValue,132 "expected": getEstimatedSuitCounts.expectedValue,133 },134 getEstimatedSuitCounts.suits["diamonds"]: {135 "min": getEstimatedSuitCounts.minDefaultValue,136 "expected": getEstimatedSuitCounts.expectedValue,137 },138 getEstimatedSuitCounts.suits["hearts"]: {139 "min": getEstimatedSuitCounts.minDefaultValue,140 "expected": getEstimatedSuitCounts.expectedValue,141 },142 getEstimatedSuitCounts.suits["spades"]: {143 "min": getEstimatedSuitCounts.minDefaultValue,144 "expected": getEstimatedSuitCounts.expectedValue,145 }, 146 },147 "right": {148 getEstimatedSuitCounts.suits["clubs"]: {149 "min": getEstimatedSuitCounts.minDefaultValue,150 "expected": getEstimatedSuitCounts.expectedValue,151 },152 getEstimatedSuitCounts.suits["diamonds"]: {153 "min": getEstimatedSuitCounts.minDefaultValue,154 "expected": getEstimatedSuitCounts.expectedValue,155 },156 getEstimatedSuitCounts.suits["hearts"]: {157 "min": getEstimatedSuitCounts.minDefaultValue,158 "expected": getEstimatedSuitCounts.expectedValue,159 },160 getEstimatedSuitCounts.suits["spades"]: {161 "min": getEstimatedSuitCounts.minDefaultValue,162 "expected": getEstimatedSuitCounts.expectedValue,163 },164 },165 }166 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts167 self.assertDictEqual(self.expected, self.actual)168 def test_open_major(self):169 self.biddingRelative = {170 "left": ['One Spade'],171 "top": ['pass'],172 "right": ['pass'],173 "bottom": [],174 }175 self.obj = getObject(self.biddingRelative)176 print(self.obj)177 self.expected = {178 "left": {179 getEstimatedSuitCounts.suits["clubs"]: {180 "min": getEstimatedSuitCounts.minDefaultValue,181 "expected": getEstimatedSuitCounts.expectedValue,182 },183 getEstimatedSuitCounts.suits["diamonds"]: {184 "min": getEstimatedSuitCounts.minDefaultValue,185 "expected": getEstimatedSuitCounts.expectedValue,186 },187 getEstimatedSuitCounts.suits["hearts"]: {188 "min": getEstimatedSuitCounts.minDefaultValue,189 "expected": getEstimatedSuitCounts.expectedValue,190 },191 getEstimatedSuitCounts.suits["spades"]: {192 "min": getEstimatedSuitCounts.openMajorMinValue,193 "expected": getEstimatedSuitCounts.expectedValue,194 },195 },196 "top": {197 getEstimatedSuitCounts.suits["clubs"]: {198 "min": getEstimatedSuitCounts.minDefaultValue,199 "expected": getEstimatedSuitCounts.expectedValue,200 },201 getEstimatedSuitCounts.suits["diamonds"]: {202 "min": getEstimatedSuitCounts.minDefaultValue,203 "expected": getEstimatedSuitCounts.expectedValue,204 },205 getEstimatedSuitCounts.suits["hearts"]: {206 "min": getEstimatedSuitCounts.minDefaultValue,207 "expected": getEstimatedSuitCounts.expectedValue,208 },209 getEstimatedSuitCounts.suits["spades"]: {210 "min": getEstimatedSuitCounts.minDefaultValue,211 "expected": getEstimatedSuitCounts.expectedValue,212 }, 213 },214 "right": {215 getEstimatedSuitCounts.suits["clubs"]: {216 "min": getEstimatedSuitCounts.minDefaultValue,217 "expected": getEstimatedSuitCounts.expectedValue,218 },219 getEstimatedSuitCounts.suits["diamonds"]: {220 "min": getEstimatedSuitCounts.minDefaultValue,221 "expected": getEstimatedSuitCounts.expectedValue,222 },223 getEstimatedSuitCounts.suits["hearts"]: {224 "min": getEstimatedSuitCounts.minDefaultValue,225 "expected": getEstimatedSuitCounts.expectedValue,226 },227 getEstimatedSuitCounts.suits["spades"]: {228 "min": getEstimatedSuitCounts.minDefaultValue,229 "expected": getEstimatedSuitCounts.expectedValue,230 },231 },232 }233 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts234 self.assertDictEqual(self.expected, self.actual)235 def test_respond_major_different_suit(self):236 self.biddingRelative = {237 "left": ['One Spade'],238 "top": ['pass'],239 "right": ['Two Heart'],240 "bottom": [],241 }242 self.obj = getObject(self.biddingRelative)243 print(self.obj)244 self.expected = {245 "left": {246 getEstimatedSuitCounts.suits["clubs"]: {247 "min": getEstimatedSuitCounts.minDefaultValue,248 "expected": getEstimatedSuitCounts.expectedValue,249 },250 getEstimatedSuitCounts.suits["diamonds"]: {251 "min": getEstimatedSuitCounts.minDefaultValue,252 "expected": getEstimatedSuitCounts.expectedValue,253 },254 getEstimatedSuitCounts.suits["hearts"]: {255 "min": getEstimatedSuitCounts.minDefaultValue,256 "expected": getEstimatedSuitCounts.expectedValue,257 },258 getEstimatedSuitCounts.suits["spades"]: {259 "min": getEstimatedSuitCounts.openMajorMinValue,260 "expected": getEstimatedSuitCounts.expectedValue,261 },262 },263 "top": {264 getEstimatedSuitCounts.suits["clubs"]: {265 "min": getEstimatedSuitCounts.minDefaultValue,266 "expected": getEstimatedSuitCounts.expectedValue,267 },268 getEstimatedSuitCounts.suits["diamonds"]: {269 "min": getEstimatedSuitCounts.minDefaultValue,270 "expected": getEstimatedSuitCounts.expectedValue,271 },272 getEstimatedSuitCounts.suits["hearts"]: {273 "min": getEstimatedSuitCounts.minDefaultValue,274 "expected": getEstimatedSuitCounts.expectedValue,275 },276 getEstimatedSuitCounts.suits["spades"]: {277 "min": getEstimatedSuitCounts.minDefaultValue,278 "expected": getEstimatedSuitCounts.expectedValue,279 }, 280 },281 "right": {282 getEstimatedSuitCounts.suits["clubs"]: {283 "min": getEstimatedSuitCounts.minDefaultValue,284 "expected": getEstimatedSuitCounts.expectedValue,285 },286 getEstimatedSuitCounts.suits["diamonds"]: {287 "min": getEstimatedSuitCounts.minDefaultValue,288 "expected": getEstimatedSuitCounts.expectedValue,289 },290 getEstimatedSuitCounts.suits["hearts"]: {291 "min": getEstimatedSuitCounts.openMajorMinValue,292 "expected": getEstimatedSuitCounts.expectedValue,293 },294 getEstimatedSuitCounts.suits["spades"]: {295 "min": getEstimatedSuitCounts.minDefaultValue,296 "expected": getEstimatedSuitCounts.expectedValue,297 },298 },299 }300 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts301 self.assertDictEqual(self.expected, self.actual)302 def test_respond_major_same_suit(self):303 self.biddingRelative = {304 "left": ['One Spade'],305 "top": ['pass'],306 "right": ['Two Spade'],307 "bottom": [],308 }309 self.obj = getObject(self.biddingRelative)310 print(self.obj)311 self.expected = {312 "left": {313 getEstimatedSuitCounts.suits["clubs"]: {314 "min": getEstimatedSuitCounts.minDefaultValue,315 "expected": getEstimatedSuitCounts.expectedValue,316 },317 getEstimatedSuitCounts.suits["diamonds"]: {318 "min": getEstimatedSuitCounts.minDefaultValue,319 "expected": getEstimatedSuitCounts.expectedValue,320 },321 getEstimatedSuitCounts.suits["hearts"]: {322 "min": getEstimatedSuitCounts.minDefaultValue,323 "expected": getEstimatedSuitCounts.expectedValue,324 },325 getEstimatedSuitCounts.suits["spades"]: {326 "min": getEstimatedSuitCounts.openMajorMinValue,327 "expected": getEstimatedSuitCounts.expectedValue,328 },329 },330 "top": {331 getEstimatedSuitCounts.suits["clubs"]: {332 "min": getEstimatedSuitCounts.minDefaultValue,333 "expected": getEstimatedSuitCounts.expectedValue,334 },335 getEstimatedSuitCounts.suits["diamonds"]: {336 "min": getEstimatedSuitCounts.minDefaultValue,337 "expected": getEstimatedSuitCounts.expectedValue,338 },339 getEstimatedSuitCounts.suits["hearts"]: {340 "min": getEstimatedSuitCounts.minDefaultValue,341 "expected": getEstimatedSuitCounts.expectedValue,342 },343 getEstimatedSuitCounts.suits["spades"]: {344 "min": getEstimatedSuitCounts.minDefaultValue,345 "expected": getEstimatedSuitCounts.expectedValue,346 }, 347 },348 "right": {349 getEstimatedSuitCounts.suits["clubs"]: {350 "min": getEstimatedSuitCounts.minDefaultValue,351 "expected": getEstimatedSuitCounts.expectedValue,352 },353 getEstimatedSuitCounts.suits["diamonds"]: {354 "min": getEstimatedSuitCounts.minDefaultValue,355 "expected": getEstimatedSuitCounts.expectedValue,356 },357 getEstimatedSuitCounts.suits["hearts"]: {358 "min": getEstimatedSuitCounts.minDefaultValue,359 "expected": getEstimatedSuitCounts.expectedValue,360 },361 getEstimatedSuitCounts.suits["spades"]: {362 "min": getEstimatedSuitCounts.respondingMinValue,363 "expected": getEstimatedSuitCounts.expectedValue,364 },365 },366 }367 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts368 self.assertDictEqual(self.expected, self.actual)369 def test_respond_minor_different_suit(self):370 self.biddingRelative = {371 "left": ['One Spade'],372 "top": ['pass'],373 "right": ['Two Club'],374 "bottom": [],375 }376 self.obj = getObject(self.biddingRelative)377 print(self.obj)378 self.expected = {379 "left": {380 getEstimatedSuitCounts.suits["clubs"]: {381 "min": getEstimatedSuitCounts.minDefaultValue,382 "expected": getEstimatedSuitCounts.expectedValue,383 },384 getEstimatedSuitCounts.suits["diamonds"]: {385 "min": getEstimatedSuitCounts.minDefaultValue,386 "expected": getEstimatedSuitCounts.expectedValue,387 },388 getEstimatedSuitCounts.suits["hearts"]: {389 "min": getEstimatedSuitCounts.minDefaultValue,390 "expected": getEstimatedSuitCounts.expectedValue,391 },392 getEstimatedSuitCounts.suits["spades"]: {393 "min": getEstimatedSuitCounts.openMajorMinValue,394 "expected": getEstimatedSuitCounts.expectedValue,395 },396 },397 "top": {398 getEstimatedSuitCounts.suits["clubs"]: {399 "min": getEstimatedSuitCounts.minDefaultValue,400 "expected": getEstimatedSuitCounts.expectedValue,401 },402 getEstimatedSuitCounts.suits["diamonds"]: {403 "min": getEstimatedSuitCounts.minDefaultValue,404 "expected": getEstimatedSuitCounts.expectedValue,405 },406 getEstimatedSuitCounts.suits["hearts"]: {407 "min": getEstimatedSuitCounts.minDefaultValue,408 "expected": getEstimatedSuitCounts.expectedValue,409 },410 getEstimatedSuitCounts.suits["spades"]: {411 "min": getEstimatedSuitCounts.minDefaultValue,412 "expected": getEstimatedSuitCounts.expectedValue,413 }, 414 },415 "right": {416 getEstimatedSuitCounts.suits["clubs"]: {417 "min": getEstimatedSuitCounts.openMinorMinValue,418 "expected": getEstimatedSuitCounts.expectedValue,419 },420 getEstimatedSuitCounts.suits["diamonds"]: {421 "min": getEstimatedSuitCounts.minDefaultValue,422 "expected": getEstimatedSuitCounts.expectedValue,423 },424 getEstimatedSuitCounts.suits["hearts"]: {425 "min": getEstimatedSuitCounts.minDefaultValue,426 "expected": getEstimatedSuitCounts.expectedValue,427 },428 getEstimatedSuitCounts.suits["spades"]: {429 "min": getEstimatedSuitCounts.minDefaultValue,430 "expected": getEstimatedSuitCounts.expectedValue,431 },432 },433 }434 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts435 self.assertDictEqual(self.expected, self.actual)436 def test_respond_minor_same_suit(self):437 self.biddingRelative = {438 "left": ['One Diamond'],439 "top": ['pass'],440 "right": ['Two Diamond'],441 "bottom": [],442 }443 self.obj = getObject(self.biddingRelative)444 print(self.obj)445 self.expected = {446 "left": {447 getEstimatedSuitCounts.suits["clubs"]: {448 "min": getEstimatedSuitCounts.minDefaultValue,449 "expected": getEstimatedSuitCounts.expectedValue,450 },451 getEstimatedSuitCounts.suits["diamonds"]: {452 "min": getEstimatedSuitCounts.openMinorMinValue,453 "expected": getEstimatedSuitCounts.expectedValue,454 },455 getEstimatedSuitCounts.suits["hearts"]: {456 "min": getEstimatedSuitCounts.minDefaultValue,457 "expected": getEstimatedSuitCounts.expectedValue,458 },459 getEstimatedSuitCounts.suits["spades"]: {460 "min": getEstimatedSuitCounts.minDefaultValue,461 "expected": getEstimatedSuitCounts.expectedValue,462 },463 },464 "top": {465 getEstimatedSuitCounts.suits["clubs"]: {466 "min": getEstimatedSuitCounts.minDefaultValue,467 "expected": getEstimatedSuitCounts.expectedValue,468 },469 getEstimatedSuitCounts.suits["diamonds"]: {470 "min": getEstimatedSuitCounts.minDefaultValue,471 "expected": getEstimatedSuitCounts.expectedValue,472 },473 getEstimatedSuitCounts.suits["hearts"]: {474 "min": getEstimatedSuitCounts.minDefaultValue,475 "expected": getEstimatedSuitCounts.expectedValue,476 },477 getEstimatedSuitCounts.suits["spades"]: {478 "min": getEstimatedSuitCounts.minDefaultValue,479 "expected": getEstimatedSuitCounts.expectedValue,480 }, 481 },482 "right": {483 getEstimatedSuitCounts.suits["clubs"]: {484 "min": getEstimatedSuitCounts.minDefaultValue,485 "expected": getEstimatedSuitCounts.expectedValue,486 },487 getEstimatedSuitCounts.suits["diamonds"]: {488 "min": getEstimatedSuitCounts.respondingMinValue,489 "expected": getEstimatedSuitCounts.expectedValue,490 },491 getEstimatedSuitCounts.suits["hearts"]: {492 "min": getEstimatedSuitCounts.minDefaultValue,493 "expected": getEstimatedSuitCounts.expectedValue,494 },495 getEstimatedSuitCounts.suits["spades"]: {496 "min": getEstimatedSuitCounts.minDefaultValue,497 "expected": getEstimatedSuitCounts.expectedValue,498 },499 },500 }501 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts502 self.assertDictEqual(self.expected, self.actual)503 def test_open_NT(self):504 self.biddingRelative = {505 "left": ['One No Trump'],506 "top": ['pass'],507 "right": ['pass'],508 "bottom": [],509 }510 self.obj = getObject(self.biddingRelative)511 print(self.obj)512 self.expected = {513 "left": {514 getEstimatedSuitCounts.suits["clubs"]: {515 "min": getEstimatedSuitCounts.openNoTrumpMinValue,516 "expected": getEstimatedSuitCounts.expectedValue,517 },518 getEstimatedSuitCounts.suits["diamonds"]: {519 "min": getEstimatedSuitCounts.openNoTrumpMinValue,520 "expected": getEstimatedSuitCounts.expectedValue,521 },522 getEstimatedSuitCounts.suits["hearts"]: {523 "min": getEstimatedSuitCounts.openNoTrumpMinValue,524 "expected": getEstimatedSuitCounts.expectedValue,525 },526 getEstimatedSuitCounts.suits["spades"]: {527 "min": getEstimatedSuitCounts.openNoTrumpMinValue,528 "expected": getEstimatedSuitCounts.expectedValue,529 },530 },531 "top": {532 getEstimatedSuitCounts.suits["clubs"]: {533 "min": getEstimatedSuitCounts.minDefaultValue,534 "expected": getEstimatedSuitCounts.expectedValue,535 },536 getEstimatedSuitCounts.suits["diamonds"]: {537 "min": getEstimatedSuitCounts.minDefaultValue,538 "expected": getEstimatedSuitCounts.expectedValue,539 },540 getEstimatedSuitCounts.suits["hearts"]: {541 "min": getEstimatedSuitCounts.minDefaultValue,542 "expected": getEstimatedSuitCounts.expectedValue,543 },544 getEstimatedSuitCounts.suits["spades"]: {545 "min": getEstimatedSuitCounts.minDefaultValue,546 "expected": getEstimatedSuitCounts.expectedValue,547 }, 548 },549 "right": {550 getEstimatedSuitCounts.suits["clubs"]: {551 "min": getEstimatedSuitCounts.minDefaultValue,552 "expected": getEstimatedSuitCounts.expectedValue,553 },554 getEstimatedSuitCounts.suits["diamonds"]: {555 "min": getEstimatedSuitCounts.minDefaultValue,556 "expected": getEstimatedSuitCounts.expectedValue,557 },558 getEstimatedSuitCounts.suits["hearts"]: {559 "min": getEstimatedSuitCounts.minDefaultValue,560 "expected": getEstimatedSuitCounts.expectedValue,561 },562 getEstimatedSuitCounts.suits["spades"]: {563 "min": getEstimatedSuitCounts.minDefaultValue,564 "expected": getEstimatedSuitCounts.expectedValue,565 },566 },567 }568 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts569 self.assertDictEqual(self.expected, self.actual)570 def test_open_one_club(self):571 self.biddingRelative = {572 "left": ['One Club'],573 "top": ['pass'],574 "right": ['pass'],575 "bottom": [],576 }577 self.obj = getObject(self.biddingRelative)578 print(self.obj)579 self.expected = {580 "left": {581 getEstimatedSuitCounts.suits["clubs"]: {582 "min": getEstimatedSuitCounts.openNoTrumpMinValue,583 "expected": getEstimatedSuitCounts.expectedValue,584 },585 getEstimatedSuitCounts.suits["diamonds"]: {586 "min": getEstimatedSuitCounts.openNoTrumpMinValue,587 "expected": getEstimatedSuitCounts.expectedValue,588 },589 getEstimatedSuitCounts.suits["hearts"]: {590 "min": getEstimatedSuitCounts.openNoTrumpMinValue,591 "expected": getEstimatedSuitCounts.expectedValue,592 },593 getEstimatedSuitCounts.suits["spades"]: {594 "min": getEstimatedSuitCounts.openNoTrumpMinValue,595 "expected": getEstimatedSuitCounts.expectedValue,596 },597 },598 "top": {599 getEstimatedSuitCounts.suits["clubs"]: {600 "min": getEstimatedSuitCounts.minDefaultValue,601 "expected": getEstimatedSuitCounts.expectedValue,602 },603 getEstimatedSuitCounts.suits["diamonds"]: {604 "min": getEstimatedSuitCounts.minDefaultValue,605 "expected": getEstimatedSuitCounts.expectedValue,606 },607 getEstimatedSuitCounts.suits["hearts"]: {608 "min": getEstimatedSuitCounts.minDefaultValue,609 "expected": getEstimatedSuitCounts.expectedValue,610 },611 getEstimatedSuitCounts.suits["spades"]: {612 "min": getEstimatedSuitCounts.minDefaultValue,613 "expected": getEstimatedSuitCounts.expectedValue,614 }, 615 },616 "right": {617 getEstimatedSuitCounts.suits["clubs"]: {618 "min": getEstimatedSuitCounts.minDefaultValue,619 "expected": getEstimatedSuitCounts.expectedValue,620 },621 getEstimatedSuitCounts.suits["diamonds"]: {622 "min": getEstimatedSuitCounts.minDefaultValue,623 "expected": getEstimatedSuitCounts.expectedValue,624 },625 getEstimatedSuitCounts.suits["hearts"]: {626 "min": getEstimatedSuitCounts.minDefaultValue,627 "expected": getEstimatedSuitCounts.expectedValue,628 },629 getEstimatedSuitCounts.suits["spades"]: {630 "min": getEstimatedSuitCounts.minDefaultValue,631 "expected": getEstimatedSuitCounts.expectedValue,632 },633 },634 }635 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts636 self.assertDictEqual(self.expected, self.actual)637 def test_open_weakTwo(self):638 self.biddingRelative = {639 "left": ['Two Spade'],640 "top": ['pass'],641 "right": ['pass'],642 "bottom": [],643 }644 self.obj = getObject(self.biddingRelative)645 print(self.obj)646 self.expected = {647 "left": {648 getEstimatedSuitCounts.suits["clubs"]: {649 "min": getEstimatedSuitCounts.minDefaultValue,650 "expected": getEstimatedSuitCounts.expectedValue,651 },652 getEstimatedSuitCounts.suits["diamonds"]: {653 "min": getEstimatedSuitCounts.minDefaultValue,654 "expected": getEstimatedSuitCounts.expectedValue,655 },656 getEstimatedSuitCounts.suits["hearts"]: {657 "min": getEstimatedSuitCounts.minDefaultValue,658 "expected": getEstimatedSuitCounts.expectedValue,659 },660 getEstimatedSuitCounts.suits["spades"]: {661 "min": getEstimatedSuitCounts.openWeakTwoMinValue,662 "expected": getEstimatedSuitCounts.expectedValue,663 },664 },665 "top": {666 getEstimatedSuitCounts.suits["clubs"]: {667 "min": getEstimatedSuitCounts.minDefaultValue,668 "expected": getEstimatedSuitCounts.expectedValue,669 },670 getEstimatedSuitCounts.suits["diamonds"]: {671 "min": getEstimatedSuitCounts.minDefaultValue,672 "expected": getEstimatedSuitCounts.expectedValue,673 },674 getEstimatedSuitCounts.suits["hearts"]: {675 "min": getEstimatedSuitCounts.minDefaultValue,676 "expected": getEstimatedSuitCounts.expectedValue,677 },678 getEstimatedSuitCounts.suits["spades"]: {679 "min": getEstimatedSuitCounts.minDefaultValue,680 "expected": getEstimatedSuitCounts.expectedValue,681 }, 682 },683 "right": {684 getEstimatedSuitCounts.suits["clubs"]: {685 "min": getEstimatedSuitCounts.minDefaultValue,686 "expected": getEstimatedSuitCounts.expectedValue,687 },688 getEstimatedSuitCounts.suits["diamonds"]: {689 "min": getEstimatedSuitCounts.minDefaultValue,690 "expected": getEstimatedSuitCounts.expectedValue,691 },692 getEstimatedSuitCounts.suits["hearts"]: {693 "min": getEstimatedSuitCounts.minDefaultValue,694 "expected": getEstimatedSuitCounts.expectedValue,695 },696 getEstimatedSuitCounts.suits["spades"]: {697 "min": getEstimatedSuitCounts.minDefaultValue,698 "expected": getEstimatedSuitCounts.expectedValue,699 },700 },701 }702 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts703 self.assertDictEqual(self.expected, self.actual)704 705 def test_open_maybe_weakTwo_(self):706 self.biddingRelative = {707 "bottom": ['One Spade'],708 "left": ['Two Heart'],709 "top": ['pass'],710 "right": ['pass'],711 }712 self.obj = getObject(self.biddingRelative)713 print(self.obj)714 self.expected = {715 "left": {716 getEstimatedSuitCounts.suits["clubs"]: {717 "min": getEstimatedSuitCounts.minDefaultValue,718 "expected": getEstimatedSuitCounts.expectedValue,719 },720 getEstimatedSuitCounts.suits["diamonds"]: {721 "min": getEstimatedSuitCounts.minDefaultValue,722 "expected": getEstimatedSuitCounts.expectedValue,723 },724 getEstimatedSuitCounts.suits["hearts"]: {725 "min": getEstimatedSuitCounts.openMajorMinValue,726 "expected": getEstimatedSuitCounts.expectedValue,727 },728 getEstimatedSuitCounts.suits["spades"]: {729 "min": getEstimatedSuitCounts.minDefaultValue,730 "expected": getEstimatedSuitCounts.expectedValue,731 },732 },733 "top": {734 getEstimatedSuitCounts.suits["clubs"]: {735 "min": getEstimatedSuitCounts.minDefaultValue,736 "expected": getEstimatedSuitCounts.expectedValue,737 },738 getEstimatedSuitCounts.suits["diamonds"]: {739 "min": getEstimatedSuitCounts.minDefaultValue,740 "expected": getEstimatedSuitCounts.expectedValue,741 },742 getEstimatedSuitCounts.suits["hearts"]: {743 "min": getEstimatedSuitCounts.minDefaultValue,744 "expected": getEstimatedSuitCounts.expectedValue,745 },746 getEstimatedSuitCounts.suits["spades"]: {747 "min": getEstimatedSuitCounts.minDefaultValue,748 "expected": getEstimatedSuitCounts.expectedValue,749 }, 750 },751 "right": {752 getEstimatedSuitCounts.suits["clubs"]: {753 "min": getEstimatedSuitCounts.minDefaultValue,754 "expected": getEstimatedSuitCounts.expectedValue,755 },756 getEstimatedSuitCounts.suits["diamonds"]: {757 "min": getEstimatedSuitCounts.minDefaultValue,758 "expected": getEstimatedSuitCounts.expectedValue,759 },760 getEstimatedSuitCounts.suits["hearts"]: {761 "min": getEstimatedSuitCounts.minDefaultValue,762 "expected": getEstimatedSuitCounts.expectedValue,763 },764 getEstimatedSuitCounts.suits["spades"]: {765 "min": getEstimatedSuitCounts.minDefaultValue,766 "expected": getEstimatedSuitCounts.expectedValue,767 },768 },769 }770 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts771 self.assertDictEqual(self.expected, self.actual)772 773 def test_open_weakTwo_2(self):774 self.biddingRelative = {775 "bottom": ['One Heart'],776 "left": ['Two Spade'],777 "top": ['pass'],778 "right": ['pass'],779 }780 self.obj = getObject(self.biddingRelative)781 print(self.obj)782 self.expected = {783 "left": {784 getEstimatedSuitCounts.suits["clubs"]: {785 "min": getEstimatedSuitCounts.minDefaultValue,786 "expected": getEstimatedSuitCounts.expectedValue,787 },788 getEstimatedSuitCounts.suits["diamonds"]: {789 "min": getEstimatedSuitCounts.minDefaultValue,790 "expected": getEstimatedSuitCounts.expectedValue,791 },792 getEstimatedSuitCounts.suits["hearts"]: {793 "min": getEstimatedSuitCounts.minDefaultValue,794 "expected": getEstimatedSuitCounts.expectedValue,795 },796 getEstimatedSuitCounts.suits["spades"]: {797 "min": getEstimatedSuitCounts.openWeakTwoMinValue,798 "expected": getEstimatedSuitCounts.expectedValue,799 },800 },801 "top": {802 getEstimatedSuitCounts.suits["clubs"]: {803 "min": getEstimatedSuitCounts.minDefaultValue,804 "expected": getEstimatedSuitCounts.expectedValue,805 },806 getEstimatedSuitCounts.suits["diamonds"]: {807 "min": getEstimatedSuitCounts.minDefaultValue,808 "expected": getEstimatedSuitCounts.expectedValue,809 },810 getEstimatedSuitCounts.suits["hearts"]: {811 "min": getEstimatedSuitCounts.minDefaultValue,812 "expected": getEstimatedSuitCounts.expectedValue,813 },814 getEstimatedSuitCounts.suits["spades"]: {815 "min": getEstimatedSuitCounts.minDefaultValue,816 "expected": getEstimatedSuitCounts.expectedValue,817 }, 818 },819 "right": {820 getEstimatedSuitCounts.suits["clubs"]: {821 "min": getEstimatedSuitCounts.minDefaultValue,822 "expected": getEstimatedSuitCounts.expectedValue,823 },824 getEstimatedSuitCounts.suits["diamonds"]: {825 "min": getEstimatedSuitCounts.minDefaultValue,826 "expected": getEstimatedSuitCounts.expectedValue,827 },828 getEstimatedSuitCounts.suits["hearts"]: {829 "min": getEstimatedSuitCounts.minDefaultValue,830 "expected": getEstimatedSuitCounts.expectedValue,831 },832 getEstimatedSuitCounts.suits["spades"]: {833 "min": getEstimatedSuitCounts.minDefaultValue,834 "expected": getEstimatedSuitCounts.expectedValue,835 },836 },837 }838 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts839 self.assertDictEqual(self.expected, self.actual)840 def test_open_weakThree(self):841 self.biddingRelative = {842 "left": ['Three Spade'],843 "top": ['pass'],844 "right": ['pass'],845 "bottom": [],846 }847 self.obj = getObject(self.biddingRelative)848 print(self.obj)849 self.expected = {850 "left": {851 getEstimatedSuitCounts.suits["clubs"]: {852 "min": getEstimatedSuitCounts.minDefaultValue,853 "expected": getEstimatedSuitCounts.expectedValue,854 },855 getEstimatedSuitCounts.suits["diamonds"]: {856 "min": getEstimatedSuitCounts.minDefaultValue,857 "expected": getEstimatedSuitCounts.expectedValue,858 },859 getEstimatedSuitCounts.suits["hearts"]: {860 "min": getEstimatedSuitCounts.minDefaultValue,861 "expected": getEstimatedSuitCounts.expectedValue,862 },863 getEstimatedSuitCounts.suits["spades"]: {864 "min": getEstimatedSuitCounts.openWeakThreeMinValue,865 "expected": getEstimatedSuitCounts.expectedValue,866 },867 },868 "top": {869 getEstimatedSuitCounts.suits["clubs"]: {870 "min": getEstimatedSuitCounts.minDefaultValue,871 "expected": getEstimatedSuitCounts.expectedValue,872 },873 getEstimatedSuitCounts.suits["diamonds"]: {874 "min": getEstimatedSuitCounts.minDefaultValue,875 "expected": getEstimatedSuitCounts.expectedValue,876 },877 getEstimatedSuitCounts.suits["hearts"]: {878 "min": getEstimatedSuitCounts.minDefaultValue,879 "expected": getEstimatedSuitCounts.expectedValue,880 },881 getEstimatedSuitCounts.suits["spades"]: {882 "min": getEstimatedSuitCounts.minDefaultValue,883 "expected": getEstimatedSuitCounts.expectedValue,884 }, 885 },886 "right": {887 getEstimatedSuitCounts.suits["clubs"]: {888 "min": getEstimatedSuitCounts.minDefaultValue,889 "expected": getEstimatedSuitCounts.expectedValue,890 },891 getEstimatedSuitCounts.suits["diamonds"]: {892 "min": getEstimatedSuitCounts.minDefaultValue,893 "expected": getEstimatedSuitCounts.expectedValue,894 },895 getEstimatedSuitCounts.suits["hearts"]: {896 "min": getEstimatedSuitCounts.minDefaultValue,897 "expected": getEstimatedSuitCounts.expectedValue,898 },899 getEstimatedSuitCounts.suits["spades"]: {900 "min": getEstimatedSuitCounts.minDefaultValue,901 "expected": getEstimatedSuitCounts.expectedValue,902 },903 },904 }905 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts906 self.assertDictEqual(self.expected, self.actual)907 def test_respond_takeout_double(self):908 self.biddingRelative = {909 "bottom": ['One Diamond'],910 "left": ['Double'],911 "top": ['pass'],912 "right": ['One Heart'],913 }914 self.obj = getObject(self.biddingRelative)915 print(self.obj)916 self.expected = {917 "left": {918 getEstimatedSuitCounts.suits["clubs"]: {919 "min": getEstimatedSuitCounts.minDefaultValue,920 "expected": getEstimatedSuitCounts.expectedValue,921 },922 getEstimatedSuitCounts.suits["diamonds"]: {923 "min": getEstimatedSuitCounts.minDefaultValue,924 "expected": getEstimatedSuitCounts.expectedValue,925 },926 getEstimatedSuitCounts.suits["hearts"]: {927 "min": getEstimatedSuitCounts.minDefaultValue,928 "expected": getEstimatedSuitCounts.expectedValue,929 },930 getEstimatedSuitCounts.suits["spades"]: {931 "min": getEstimatedSuitCounts.minDefaultValue,932 "expected": getEstimatedSuitCounts.expectedValue,933 },934 },935 "top": {936 getEstimatedSuitCounts.suits["clubs"]: {937 "min": getEstimatedSuitCounts.minDefaultValue,938 "expected": getEstimatedSuitCounts.expectedValue,939 },940 getEstimatedSuitCounts.suits["diamonds"]: {941 "min": getEstimatedSuitCounts.minDefaultValue,942 "expected": getEstimatedSuitCounts.expectedValue,943 },944 getEstimatedSuitCounts.suits["hearts"]: {945 "min": getEstimatedSuitCounts.minDefaultValue,946 "expected": getEstimatedSuitCounts.expectedValue,947 },948 getEstimatedSuitCounts.suits["spades"]: {949 "min": getEstimatedSuitCounts.minDefaultValue,950 "expected": getEstimatedSuitCounts.expectedValue,951 }, 952 },953 "right": {954 getEstimatedSuitCounts.suits["clubs"]: {955 "min": getEstimatedSuitCounts.minDefaultValue,956 "expected": getEstimatedSuitCounts.expectedValue,957 },958 getEstimatedSuitCounts.suits["diamonds"]: {959 "min": getEstimatedSuitCounts.minDefaultValue,960 "expected": getEstimatedSuitCounts.expectedValue,961 },962 getEstimatedSuitCounts.suits["hearts"]: {963 "min": getEstimatedSuitCounts.forcedResponseMinValue,964 "expected": getEstimatedSuitCounts.expectedValue,965 },966 getEstimatedSuitCounts.suits["spades"]: {967 "min": getEstimatedSuitCounts.minDefaultValue,968 "expected": getEstimatedSuitCounts.expectedValue,969 },970 },971 }972 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts973 self.assertDictEqual(self.expected, self.actual)974 def test_respond_partner_opening_NT(self):975 self.biddingRelative = {976 "bottom": ['pass'],977 "left": ['One No Trump'],978 "top": ['Pass'],979 "right": ['One Heart'],980 }981 self.obj = getObject(self.biddingRelative)982 print(self.obj)983 self.expected = {984 "left": {985 getEstimatedSuitCounts.suits["clubs"]: {986 "min": getEstimatedSuitCounts.openNoTrumpMinValue,987 "expected": getEstimatedSuitCounts.expectedValue,988 },989 getEstimatedSuitCounts.suits["diamonds"]: {990 "min": getEstimatedSuitCounts.openNoTrumpMinValue,991 "expected": getEstimatedSuitCounts.expectedValue,992 },993 getEstimatedSuitCounts.suits["hearts"]: {994 "min": getEstimatedSuitCounts.openNoTrumpMinValue,995 "expected": getEstimatedSuitCounts.expectedValue,996 },997 getEstimatedSuitCounts.suits["spades"]: {998 "min": getEstimatedSuitCounts.openNoTrumpMinValue,999 "expected": getEstimatedSuitCounts.expectedValue,1000 },1001 },1002 "top": {1003 getEstimatedSuitCounts.suits["clubs"]: {1004 "min": getEstimatedSuitCounts.minDefaultValue,1005 "expected": getEstimatedSuitCounts.expectedValue,1006 },1007 getEstimatedSuitCounts.suits["diamonds"]: {1008 "min": getEstimatedSuitCounts.minDefaultValue,1009 "expected": getEstimatedSuitCounts.expectedValue,1010 },1011 getEstimatedSuitCounts.suits["hearts"]: {1012 "min": getEstimatedSuitCounts.minDefaultValue,1013 "expected": getEstimatedSuitCounts.expectedValue,1014 },1015 getEstimatedSuitCounts.suits["spades"]: {1016 "min": getEstimatedSuitCounts.minDefaultValue,1017 "expected": getEstimatedSuitCounts.expectedValue,1018 }, 1019 },1020 "right": {1021 getEstimatedSuitCounts.suits["clubs"]: {1022 "min": getEstimatedSuitCounts.minDefaultValue,1023 "expected": getEstimatedSuitCounts.expectedValue,1024 },1025 getEstimatedSuitCounts.suits["diamonds"]: {1026 "min": getEstimatedSuitCounts.minDefaultValue,1027 "expected": getEstimatedSuitCounts.expectedValue,1028 },1029 getEstimatedSuitCounts.suits["hearts"]: {1030 "min": getEstimatedSuitCounts.openMajorMinValue,1031 "expected": getEstimatedSuitCounts.expectedValue,1032 },1033 getEstimatedSuitCounts.suits["spades"]: {1034 "min": getEstimatedSuitCounts.minDefaultValue,1035 "expected": getEstimatedSuitCounts.expectedValue,1036 },1037 },1038 }1039 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts1040 self.assertDictEqual(self.expected, self.actual)1041 def test_respond_two_club(self):1042 self.biddingRelative = {1043 "bottom": ['pass', 'pass'],1044 "left": ['Two Club', 'Two Spade'],1045 "top": ['Pass', 'pass'],1046 "right": ['Two Heart', 'Two Club'],1047 }1048 self.obj = getObject(self.biddingRelative)1049 print(self.obj)1050 self.expected = {1051 "left": {1052 getEstimatedSuitCounts.suits["clubs"]: {1053 "min": getEstimatedSuitCounts.minDefaultValue,1054 "expected": getEstimatedSuitCounts.expectedValue,1055 },1056 getEstimatedSuitCounts.suits["diamonds"]: {1057 "min": getEstimatedSuitCounts.minDefaultValue,1058 "expected": getEstimatedSuitCounts.expectedValue,1059 },1060 getEstimatedSuitCounts.suits["hearts"]: {1061 "min": getEstimatedSuitCounts.minDefaultValue,1062 "expected": getEstimatedSuitCounts.expectedValue,1063 },1064 getEstimatedSuitCounts.suits["spades"]: {1065 "min": getEstimatedSuitCounts.minDefaultValue,1066 "expected": getEstimatedSuitCounts.expectedValue,1067 },1068 },1069 "top": {1070 getEstimatedSuitCounts.suits["clubs"]: {1071 "min": getEstimatedSuitCounts.minDefaultValue,1072 "expected": getEstimatedSuitCounts.expectedValue,1073 },1074 getEstimatedSuitCounts.suits["diamonds"]: {1075 "min": getEstimatedSuitCounts.minDefaultValue,1076 "expected": getEstimatedSuitCounts.expectedValue,1077 },1078 getEstimatedSuitCounts.suits["hearts"]: {1079 "min": getEstimatedSuitCounts.minDefaultValue,1080 "expected": getEstimatedSuitCounts.expectedValue,1081 },1082 getEstimatedSuitCounts.suits["spades"]: {1083 "min": getEstimatedSuitCounts.minDefaultValue,1084 "expected": getEstimatedSuitCounts.expectedValue,1085 }, 1086 },1087 "right": {1088 getEstimatedSuitCounts.suits["clubs"]: {1089 "min": getEstimatedSuitCounts.forcedResponseMinValue,1090 "expected": getEstimatedSuitCounts.expectedValue,1091 },1092 getEstimatedSuitCounts.suits["diamonds"]: {1093 "min": getEstimatedSuitCounts.minDefaultValue,1094 "expected": getEstimatedSuitCounts.expectedValue,1095 },1096 getEstimatedSuitCounts.suits["hearts"]: {1097 "min": getEstimatedSuitCounts.minDefaultValue,1098 "expected": getEstimatedSuitCounts.expectedValue,1099 },1100 getEstimatedSuitCounts.suits["spades"]: {1101 "min": getEstimatedSuitCounts.minDefaultValue,1102 "expected": getEstimatedSuitCounts.expectedValue,1103 },1104 },1105 }1106 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts1107 self.assertDictEqual(self.expected, self.actual)1108class MultipleBidOpportunities(unittest.TestCase): 1109 def setUp(self) -> None:1110 self.actual = {}1111 self.expected = {}1112 def tearDown(self) -> None:1113 print('')1114 print('biddingRelative ={0}'.format (self.biddingRelative))1115 print('')1116 print('actual:--------------------')1117 for location, values in self.actual.items():1118 print(location)1119 print(f'\t{values}')1120 print('')1121 print('expected:--------------------')1122 for location, values in self.expected.items():1123 print(location)1124 print(f'\t{values}')1125 print('')1126 #TODO: need more 2nd suit or 3rd suit cases?1127 #what about if pass first, then bid second?1128 #Maybe we just need a function that gets if the player being analyzed was the first person on that team to say that suit/NT, if so then they are considered to have opening length in suit/NT?1129 #does right have more than 4 min or just more expected (5-6)?1130 def test_pass_then_bid(self):1131 self.biddingRelative = {1132 "right": ['One Club', 'Two Club', 'Three Club'],1133 "bottom": ['pass', 'pass'],1134 "top": ['pass', 'Two Heart'],1135 "left": ['One Diamond', 'Two Spade'],1136 }1137 self.obj = getObject(self.biddingRelative)1138 print(self.obj)1139 self.expected = {1140 "left": {1141 getEstimatedSuitCounts.suits["clubs"]: {1142 "min": getEstimatedSuitCounts.minDefaultValue,1143 "expected": getEstimatedSuitCounts.expectedValue,1144 },1145 getEstimatedSuitCounts.suits["diamonds"]: {1146 "min": getEstimatedSuitCounts.minDefaultValue,1147 "expected": getEstimatedSuitCounts.expectedValue,1148 },1149 getEstimatedSuitCounts.suits["hearts"]: {1150 "min": getEstimatedSuitCounts.minDefaultValue,1151 "expected": getEstimatedSuitCounts.expectedValue,1152 },1153 getEstimatedSuitCounts.suits["spades"]: {1154 "min": getEstimatedSuitCounts.minDefaultValue,1155 "expected": getEstimatedSuitCounts.expectedValue,1156 },1157 },1158 "top": {1159 getEstimatedSuitCounts.suits["clubs"]: {1160 "min": getEstimatedSuitCounts.minDefaultValue,1161 "expected": getEstimatedSuitCounts.expectedValue,1162 },1163 getEstimatedSuitCounts.suits["diamonds"]: {1164 "min": getEstimatedSuitCounts.minDefaultValue,1165 "expected": getEstimatedSuitCounts.expectedValue,1166 },1167 getEstimatedSuitCounts.suits["hearts"]: {1168 "min": getEstimatedSuitCounts.minDefaultValue,1169 "expected": getEstimatedSuitCounts.expectedValue,1170 },1171 getEstimatedSuitCounts.suits["spades"]: {1172 "min": getEstimatedSuitCounts.minDefaultValue,1173 "expected": getEstimatedSuitCounts.expectedValue,1174 }, 1175 },1176 "right": {1177 getEstimatedSuitCounts.suits["clubs"]: {1178 "min": getEstimatedSuitCounts.forcedResponseMinValue,1179 "expected": getEstimatedSuitCounts.expectedValue,1180 },1181 getEstimatedSuitCounts.suits["diamonds"]: {1182 "min": getEstimatedSuitCounts.minDefaultValue,1183 "expected": getEstimatedSuitCounts.expectedValue,1184 },1185 getEstimatedSuitCounts.suits["hearts"]: {1186 "min": getEstimatedSuitCounts.minDefaultValue,1187 "expected": getEstimatedSuitCounts.expectedValue,1188 },1189 getEstimatedSuitCounts.suits["spades"]: {1190 "min": getEstimatedSuitCounts.minDefaultValue,1191 "expected": getEstimatedSuitCounts.expectedValue,1192 },1193 },1194 }1195 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts1196 self.assertDictEqual(self.expected, self.actual)1197 1198 def test_responding_vs_opening(self):1199 self.biddingRelative = {1200 "right": ['One Diamond', 'Two Heart', 'pass'],1201 "bottom": ['pass', 'pass'],1202 "top": ['Two Diamond', 'Two Spade'],1203 "left": ['pass', 'pass'],1204 }1205 self.obj = getObject(self.biddingRelative)1206 print(self.obj)1207 self.expected = {1208 "left": {1209 getEstimatedSuitCounts.suits["clubs"]: {1210 "min": getEstimatedSuitCounts.minDefaultValue,1211 "expected": getEstimatedSuitCounts.expectedValue,1212 },1213 getEstimatedSuitCounts.suits["diamonds"]: {1214 "min": getEstimatedSuitCounts.minDefaultValue,1215 "expected": getEstimatedSuitCounts.expectedValue,1216 },1217 getEstimatedSuitCounts.suits["hearts"]: {1218 "min": getEstimatedSuitCounts.minDefaultValue,1219 "expected": getEstimatedSuitCounts.expectedValue,1220 },1221 getEstimatedSuitCounts.suits["spades"]: {1222 "min": getEstimatedSuitCounts.minDefaultValue,1223 "expected": getEstimatedSuitCounts.expectedValue,1224 },1225 },1226 "top": {1227 getEstimatedSuitCounts.suits["clubs"]: {1228 "min": getEstimatedSuitCounts.minDefaultValue,1229 "expected": getEstimatedSuitCounts.expectedValue,1230 },1231 getEstimatedSuitCounts.suits["diamonds"]: {1232 "min": getEstimatedSuitCounts.respondingMinValue,1233 "expected": getEstimatedSuitCounts.expectedValue,1234 },1235 getEstimatedSuitCounts.suits["hearts"]: {1236 "min": getEstimatedSuitCounts.minDefaultValue,1237 "expected": getEstimatedSuitCounts.expectedValue,1238 },1239 getEstimatedSuitCounts.suits["spades"]: {1240 "min": getEstimatedSuitCounts.openMajorMinValue,1241 "expected": getEstimatedSuitCounts.expectedValue,1242 }, 1243 },1244 "right": {1245 getEstimatedSuitCounts.suits["clubs"]: {1246 "min": getEstimatedSuitCounts.minDefaultValue,1247 "expected": getEstimatedSuitCounts.expectedValue,1248 },1249 getEstimatedSuitCounts.suits["diamonds"]: {1250 "min": getEstimatedSuitCounts.openMinorMinValue,1251 "expected": getEstimatedSuitCounts.expectedValue,1252 },1253 getEstimatedSuitCounts.suits["hearts"]: {1254 "min": getEstimatedSuitCounts.openMajorMinValue,1255 "expected": getEstimatedSuitCounts.expectedValue,1256 },1257 getEstimatedSuitCounts.suits["spades"]: {1258 "min": getEstimatedSuitCounts.minDefaultValue,1259 "expected": getEstimatedSuitCounts.expectedValue,1260 },1261 },1262 }1263 self.actual = getEstimatedSuitCounts.EstimateSuitCounts(self.biddingRelative, self.obj.biddingAbsolute, self.obj.seatingRelative).suitCounts1264 self.assertDictEqual(self.expected, self.actual)...
operating_system.py
Source:operating_system.py
1#!/usr/bin/python2#3#source of register info is from http://opensource.apple.com/source/gdb/gdb-962/src/gdb/arm-tdep.c4import lldb5import struct6osplugin_target_obj = None7class PluginValue(lldb.SBValue):8 def GetChildMemberWithName(val, name):9 val_type = val.GetType()10 if val_type.IsPointerType() == True:11 val_type = val_type.GetPointeeType()12 for i in range(val_type.GetNumberOfFields()):13 if name == val_type.GetFieldAtIndex(i).GetName():14 return PluginValue(val.GetChildAtIndex(i))15 return None16class Armv8_RegisterSet(object):17 """ register info set for armv8 64 bit architecture"""18 register_info = { 'sets' : ['GPR'],19 'registers': [20 {'name': 'x0' , 'bitsize':64, 'offset': 0, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 0, 'dwarf': 0, 'alt-name':'arg1', 'generic':'arg1'},21 {'name': 'x1' , 'bitsize':64, 'offset': 8, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 1, 'dwarf': 1, 'alt-name':'arg2', 'generic':'arg2'},22 {'name': 'x2' , 'bitsize':64, 'offset': 16, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 2, 'dwarf': 2, 'alt-name':'arg3', 'generic':'arg3'},23 {'name': 'x3' , 'bitsize':64, 'offset': 24, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 3, 'dwarf': 3, 'alt-name':'arg4', 'generic':'arg4'},24 {'name': 'x4' , 'bitsize':64, 'offset': 32, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 4, 'dwarf': 4, 'alt-name':'arg5', 'generic':'arg5'},25 {'name': 'x5' , 'bitsize':64, 'offset': 40, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 5, 'dwarf': 5, 'alt-name':'arg6', 'generic':'arg6'},26 {'name': 'x6' , 'bitsize':64, 'offset': 48, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 6, 'dwarf': 6, 'alt-name':'arg7', 'generic':'arg7'},27 {'name': 'x7' , 'bitsize':64, 'offset': 56, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 7, 'dwarf': 7, 'alt-name':'arg8', 'generic':'arg8'},28 {'name': 'x8' , 'bitsize':64, 'offset': 64, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 8, 'dwarf': 8},29 {'name': 'x9' , 'bitsize':64, 'offset': 72, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 9, 'dwarf': 9},30 {'name': 'x10' , 'bitsize':64, 'offset': 80, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':10, 'dwarf':10},31 {'name': 'x11' , 'bitsize':64, 'offset': 88, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':11, 'dwarf':11},32 {'name': 'x12' , 'bitsize':64, 'offset': 96, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':12, 'dwarf':12},33 {'name': 'x13' , 'bitsize':64, 'offset':104, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':13, 'dwarf':13},34 {'name': 'x14' , 'bitsize':64, 'offset':112, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':14, 'dwarf':14},35 {'name': 'x15' , 'bitsize':64, 'offset':120, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':15, 'dwarf':15},36 {'name': 'x16' , 'bitsize':64, 'offset':128, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':16, 'dwarf':16},37 {'name': 'x17' , 'bitsize':64, 'offset':136, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':17, 'dwarf':17},38 {'name': 'x18' , 'bitsize':64, 'offset':144, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':18, 'dwarf':18},39 {'name': 'x19' , 'bitsize':64, 'offset':152, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':19, 'dwarf':19},40 {'name': 'x20' , 'bitsize':64, 'offset':160, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':20, 'dwarf':20},41 {'name': 'x21' , 'bitsize':64, 'offset':168, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':21, 'dwarf':21},42 {'name': 'x22' , 'bitsize':64, 'offset':176, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':22, 'dwarf':22},43 {'name': 'x23' , 'bitsize':64, 'offset':184, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':23, 'dwarf':23},44 {'name': 'x24' , 'bitsize':64, 'offset':192, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':24, 'dwarf':24},45 {'name': 'x25' , 'bitsize':64, 'offset':200, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':25, 'dwarf':25},46 {'name': 'x26' , 'bitsize':64, 'offset':208, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':26, 'dwarf':26},47 {'name': 'x27' , 'bitsize':64, 'offset':216, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':27, 'dwarf':27},48 {'name': 'x28' , 'bitsize':64, 'offset':224, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':28, 'dwarf':28},49 {'name': 'fp' , 'bitsize':64, 'offset':232, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':29, 'dwarf':29, 'alt-name': 'fp', 'generic':'fp'},50 {'name': 'lr' , 'bitsize':64, 'offset':240, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':30, 'dwarf':30, 'alt-name': 'lr', 'generic':'lr'},51 {'name': 'sp' , 'bitsize':64, 'offset':248, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':31, 'dwarf':31, 'alt-name': 'sp', 'generic':'sp'},52 {'name': 'pc' , 'bitsize':64, 'offset':256, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':32, 'dwarf':32, 'alt-name': 'pc', 'generic':'pc'},53 {'name': 'far' , 'bitsize':64, 'offset':264, 'encoding':'uint', 'format':'hex', 'set':0},54 {'name': 'cpsr', 'bitsize':32, 'offset':272, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':33, 'dwarf':33, 'generic':'flags'},55 {'name': 'esr' , 'bitsize':32, 'offset':276, 'encoding':'uint', 'format':'hex', 'set':0},56 ]57 }58 def __init__(self):59 self.switch_context_address = osplugin_target_obj.FindSymbols('Switch_context')[0].GetSymbol().GetStartAddress().GetLoadAddress(osplugin_target_obj)60 self.ResetRegisterValues()61 def ResetRegisterValues(self):62 self.x0 = 063 self.x1 = 064 self.x2 = 065 self.x3 = 066 self.x4 = 067 self.x5 = 068 self.x6 = 069 self.x7 = 070 self.x8 = 071 self.x9 = 072 self.x10 = 073 self.x11 = 074 self.x12 = 075 self.x13 = 076 self.x14 = 077 self.x15 = 078 self.x16 = 079 self.x17 = 080 self.x18 = 081 self.x19 = 082 self.x20 = 083 self.x21 = 084 self.x22 = 085 self.x23 = 086 self.x24 = 087 self.x25 = 088 self.x26 = 089 self.x27 = 090 self.x28 = 091 self.fp = 092 self.lr = 093 self.sp = 094 self.pc = 095 self.far = 096 self.cpsr = 097 self.esr = 098 def __str__(self):99 return """ pc = """100 def GetPackedRegisterState(self):101 return struct.pack('34QII', self.x0, self.x1, self.x2, self.x3, self.x4, self.x5,102 self.x6, self.x7, self.x8, self.x9, self.x10, self.x11, self.x12, self.x13,103 self.x14, self.x15, self.x16, self.x17, self.x18, self.x19, self.x20, self.x21,104 self.x22, self.x23, self.x24, self.x25, self.x26, self.x27, self.x28, self.fp,105 self.lr, self.sp, self.pc, self.far, self.cpsr, self.esr)106 def ReadRegisterDataFromKDPSavedState(self, kdp_state, kernel_version):107 """ Setup register values from KDP saved information.108 """109 saved_state = kernel_version.CreateValueFromExpression(None, '(struct arm_saved_state64 *) ' + str(kdp_state.GetValueAsUnsigned()))110 saved_state = saved_state.Dereference()111 saved_state = PluginValue(saved_state)112 self.ResetRegisterValues()113 self.x0 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(0).GetValueAsUnsigned()114 self.x1 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(1).GetValueAsUnsigned()115 self.x2 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(2).GetValueAsUnsigned()116 self.x3 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(3).GetValueAsUnsigned()117 self.x4 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(4).GetValueAsUnsigned()118 self.x5 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(5).GetValueAsUnsigned()119 self.x6 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(6).GetValueAsUnsigned()120 self.x7 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(7).GetValueAsUnsigned()121 self.x8 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(8).GetValueAsUnsigned()122 self.x9 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(9).GetValueAsUnsigned()123 self.x10 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(10).GetValueAsUnsigned()124 self.x11 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(11).GetValueAsUnsigned()125 self.x12 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(12).GetValueAsUnsigned()126 self.x13 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(13).GetValueAsUnsigned()127 self.x14 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(14).GetValueAsUnsigned()128 self.x15 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(15).GetValueAsUnsigned()129 self.x16 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(16).GetValueAsUnsigned()130 self.x17 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(17).GetValueAsUnsigned()131 self.x18 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(18).GetValueAsUnsigned()132 self.x19 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(19).GetValueAsUnsigned()133 self.x20 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(20).GetValueAsUnsigned()134 self.x21 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(21).GetValueAsUnsigned()135 self.x22 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(22).GetValueAsUnsigned()136 self.x23 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(23).GetValueAsUnsigned()137 self.x24 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(24).GetValueAsUnsigned()138 self.x25 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(25).GetValueAsUnsigned()139 self.x26 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(26).GetValueAsUnsigned()140 self.x27 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(27).GetValueAsUnsigned()141 self.x28 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(28).GetValueAsUnsigned()142 self.fp = saved_state.GetChildMemberWithName('fp').GetValueAsUnsigned()143 self.lr = saved_state.GetChildMemberWithName('lr').GetValueAsUnsigned()144 self.sp = saved_state.GetChildMemberWithName('sp').GetValueAsUnsigned()145 self.pc = saved_state.GetChildMemberWithName('pc').GetValueAsUnsigned()146 self.far = saved_state.GetChildMemberWithName('far').GetValueAsUnsigned()147 self.cpsr = saved_state.GetChildMemberWithName('cpsr').GetValueAsUnsigned()148 self.esr = saved_state.GetChildMemberWithName('esr').GetValueAsUnsigned()149 return self150 def ReadRegisterDataFromKernelStack(self, kstack_saved_state_addr, kernel_version):151 saved_state = kernel_version.CreateValueFromExpression(None, '(struct arm_saved_state64 *) '+ str(kstack_saved_state_addr))152 saved_state = saved_state.Dereference()153 saved_state = PluginValue(saved_state)154 self.ResetRegisterValues()155 self.x0 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(0).GetValueAsUnsigned()156 self.x1 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(1).GetValueAsUnsigned()157 self.x2 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(2).GetValueAsUnsigned()158 self.x3 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(3).GetValueAsUnsigned()159 self.x4 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(4).GetValueAsUnsigned()160 self.x5 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(5).GetValueAsUnsigned()161 self.x6 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(6).GetValueAsUnsigned()162 self.x7 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(7).GetValueAsUnsigned()163 self.x8 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(8).GetValueAsUnsigned()164 self.x9 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(9).GetValueAsUnsigned()165 self.x10 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(10).GetValueAsUnsigned()166 self.x11 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(11).GetValueAsUnsigned()167 self.x12 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(12).GetValueAsUnsigned()168 self.x13 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(13).GetValueAsUnsigned()169 self.x14 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(14).GetValueAsUnsigned()170 self.x15 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(15).GetValueAsUnsigned()171 self.x16 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(16).GetValueAsUnsigned()172 self.x17 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(17).GetValueAsUnsigned()173 self.x18 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(18).GetValueAsUnsigned()174 self.x19 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(19).GetValueAsUnsigned()175 self.x20 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(20).GetValueAsUnsigned()176 self.x21 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(21).GetValueAsUnsigned()177 self.x22 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(22).GetValueAsUnsigned()178 self.x23 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(23).GetValueAsUnsigned()179 self.x24 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(24).GetValueAsUnsigned()180 self.x25 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(25).GetValueAsUnsigned()181 self.x26 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(26).GetValueAsUnsigned()182 self.x27 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(27).GetValueAsUnsigned()183 self.x28 = saved_state.GetChildMemberWithName('x').GetChildAtIndex(28).GetValueAsUnsigned()184 self.fp = saved_state.GetChildMemberWithName('fp').GetValueAsUnsigned()185 self.lr = saved_state.GetChildMemberWithName('lr').GetValueAsUnsigned()186 self.sp = saved_state.GetChildMemberWithName('sp').GetValueAsUnsigned()187 # pc for a blocked thread is treated to be the next instruction it would run after thread switch.188 self.pc = self.switch_context_address189 self.far = saved_state.GetChildMemberWithName('far').GetValueAsUnsigned()190 self.cpsr = saved_state.GetChildMemberWithName('cpsr').GetValueAsUnsigned()191 self.esr = saved_state.GetChildMemberWithName('esr').GetValueAsUnsigned()192 return self193 def ReadRegisterDataFromContinuation(self, continuation_ptr):194 self.ResetRegisterValues()195 self.pc = continuation_ptr196 return self197 @classmethod198 def GetRegisterInfo(cls, regnum):199 if regnum < 0 or regnum > len(cls.register_info['registers']):200 return ''201 202 reginfo = cls.register_info['registers'][regnum]203 retval = ''204 for i in reginfo.keys():205 v_str = str(reginfo[i])206 if i == 'set':207 v_str = 'General Purpose Registers'208 retval += "%s:%s;" % (str(i), v_str)209 return retval210class Armv7_RegisterSet(object):211 """ register info set for armv7 32 bit architecture """212 register_info = { 'sets' : ['GPR'],213 'registers': [214 { 'name':'r0' , 'bitsize' : 32, 'offset' : 0, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 0, 'dwarf' : 0},215 { 'name':'r1' , 'bitsize' : 32, 'offset' : 4, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 1, 'dwarf' : 1},216 { 'name':'r2' , 'bitsize' : 32, 'offset' : 8, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 2, 'dwarf' : 2},217 { 'name':'r3' , 'bitsize' : 32, 'offset' : 12, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 3, 'dwarf' : 3},218 { 'name':'r4' , 'bitsize' : 32, 'offset' : 16, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 4, 'dwarf' : 4},219 { 'name':'r5' , 'bitsize' : 32, 'offset' : 20, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 5, 'dwarf' : 5},220 { 'name':'r6' , 'bitsize' : 32, 'offset' : 24, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 6, 'dwarf' : 6},221 { 'name':'r7' , 'bitsize' : 32, 'offset' : 28, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 7, 'dwarf' : 7},222 { 'name':'r8' , 'bitsize' : 32, 'offset' : 32, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 8, 'dwarf' : 8},223 { 'name':'r9' , 'bitsize' : 32, 'offset' : 36, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc': 9, 'dwarf' : 9},224 { 'name':'r10' , 'bitsize' : 32, 'offset' : 40, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':10, 'dwarf' :10},225 { 'name':'r11' , 'bitsize' : 32, 'offset' : 44, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':11, 'dwarf' :11, 'alt-name': 'fp', 'generic': 'fp'},226 { 'name':'r12' , 'bitsize' : 32, 'offset' : 48, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':12, 'dwarf' :12},227 { 'name':'sp' , 'bitsize' : 32, 'offset' : 52, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':13, 'dwarf' :13, 'generic': 'sp'},228 { 'name':'lr' , 'bitsize' : 32, 'offset' : 56, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':14, 'dwarf' :14, 'generic': 'lr'},229 { 'name':'pc' , 'bitsize' : 32, 'offset' : 60, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':15, 'dwarf' :15, 'generic': 'pc'},230 { 'name':'cpsr' , 'bitsize' : 32, 'offset' : 64, 'encoding':'uint', 'format':'hex', 'set':0, 'gcc':16, 'dwarf' :16, 'generic':'flags'},231 { 'name':'fsr' , 'bitsize' : 32, 'offset' : 68, 'encoding':'uint', 'format':'hex', 'set':0},232 { 'name':'far' , 'bitsize' : 32, 'offset' : 72, 'encoding':'uint', 'format':'hex', 'set':0}233 ]234 }235 def __init__(self):236 self.switch_context_address = osplugin_target_obj.FindSymbols('load_reg')[0].GetSymbol().GetStartAddress().GetLoadAddress(osplugin_target_obj) + 8237 self.ResetRegisterValues()238 239 @classmethod240 def GetRegisterInfo(cls, regnum):241 if regnum < 0 or regnum > len(cls.register_info['registers']):242 return ''243 244 reginfo = cls.register_info['registers'][regnum]245 retval = ''246 for i in reginfo.keys():247 v_str = str(reginfo[i])248 if i == 'set':249 v_str = 'General Purpose Registers'250 retval += "%s:%s;" % (str(i), v_str)251 return retval252 def ResetRegisterValues(self):253 self.r0 = 0254 self.r1 = 0255 self.r2 = 0256 self.r3 = 0257 self.r4 = 0258 self.r5 = 0259 self.r6 = 0260 self.r7 = 0261 self.r8 = 0262 self.r9 = 0263 self.r10 = 0264 self.r11 = 0265 self.r12 = 0266 self.sp = 0267 self.lr = 0268 self.pc = 0269 self.cpsr = 0270 self.fsr = 0271 self.far = 0272 def __str__(self):273 return """274 r0 = {o.r0: <#010x}275 r1 = {o.r1: <#010x}276 r2 = {o.r2: <#010x}277 r3 = {o.r3: <#010x}278 r4 = {o.r4: <#010x}279 r5 = {o.r5: <#010x}280 r6 = {o.r6: <#010x}281 r7 = {o.r7: <#010x}282 r8 = {o.r8: <#010x}283 r9 = {o.r9: <#010x}284 r10 = {o.r10: <#010x}285 r11 = {o.r11: <#010x}286 r12 = {o.r12: <#010x}287 sp = {o.sp: <#010x}288 lr = {o.lr: <#010x}289 pc = {o.pc: <#010x}290 cpsr = {o.cpsr: <#010x}291 fsr = {o.fsr : <#010x}292 far = {o.far : <#010x}293 """.format(o=self)294 def GetPackedRegisterState(self):295 return struct.pack('19I', self.r0, self.r1, self.r2, self.r3,296 self.r4, self.r5, self.r6, self.r7,297 self.r8, self.r9, self.r10, self.r11,298 self.r12, self.sp, self.lr, self.pc,299 self.cpsr, self.fsr, self.far)300 def ReadRegisterDataFromKDPSavedState(self, kdp_state, kernel_version):301 saved_state = kernel_version.CreateValueFromExpression(None, '(struct arm_saved_state *) ' + str(kdp_state.GetValueAsUnsigned()))302 saved_state = saved_state.Dereference()303 saved_state = PluginValue(saved_state)304 self.ResetRegisterValues()305 self.r0 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(0).GetValueAsUnsigned()306 self.r1 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(1).GetValueAsUnsigned()307 self.r2 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(2).GetValueAsUnsigned()308 self.r3 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(3).GetValueAsUnsigned()309 self.r4 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(4).GetValueAsUnsigned()310 self.r5 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(5).GetValueAsUnsigned()311 self.r6 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(6).GetValueAsUnsigned()312 self.r7 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(7).GetValueAsUnsigned()313 self.r8 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(8).GetValueAsUnsigned()314 self.r9 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(9).GetValueAsUnsigned()315 self.r10 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(10).GetValueAsUnsigned()316 self.r11 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(11).GetValueAsUnsigned()317 self.r12 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(12).GetValueAsUnsigned()318 self.sp = saved_state.GetChildMemberWithName('sp').GetValueAsUnsigned()319 self.lr = saved_state.GetChildMemberWithName('lr').GetValueAsUnsigned()320 self.pc = saved_state.GetChildMemberWithName('pc').GetValueAsUnsigned()321 self.cpsr = saved_state.GetChildMemberWithName('cpsr').GetValueAsUnsigned()322 self.fsr = saved_state.GetChildMemberWithName('fsr').GetValueAsUnsigned()323 self.far = saved_state.GetChildMemberWithName('far').GetValueAsUnsigned()324 return self325 def ReadRegisterDataFromKernelStack(self, kstack_saved_state_addr, kernel_version):326 saved_state = kernel_version.CreateValueFromExpression(None, '(struct arm_saved_state *) '+ str(kstack_saved_state_addr))327 saved_state = saved_state.Dereference()328 saved_state = PluginValue(saved_state)329 self.ResetRegisterValues()330 self.r0 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(0).GetValueAsUnsigned()331 self.r1 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(1).GetValueAsUnsigned()332 self.r2 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(2).GetValueAsUnsigned()333 self.r3 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(3).GetValueAsUnsigned()334 self.r4 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(4).GetValueAsUnsigned()335 self.r5 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(5).GetValueAsUnsigned()336 self.r6 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(6).GetValueAsUnsigned()337 self.r7 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(7).GetValueAsUnsigned()338 self.r8 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(8).GetValueAsUnsigned()339 self.r9 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(9).GetValueAsUnsigned()340 self.r10 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(10).GetValueAsUnsigned()341 self.r11 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(11).GetValueAsUnsigned()342 self.r12 = saved_state.GetChildMemberWithName('r').GetChildAtIndex(12).GetValueAsUnsigned()343 self.sp = saved_state.GetChildMemberWithName('sp').GetValueAsUnsigned()344 self.lr = saved_state.GetChildMemberWithName('lr').GetValueAsUnsigned()345 # pc for a blocked thread is treated to be the next instruction it would run after thread switch.346 self.pc = self.switch_context_address347 self.cpsr = saved_state.GetChildMemberWithName('cpsr').GetValueAsUnsigned()348 self.fsr = saved_state.GetChildMemberWithName('fsr').GetValueAsUnsigned()349 self.far = saved_state.GetChildMemberWithName('far').GetValueAsUnsigned()350 return self351 def ReadRegisterDataFromContinuation(self, continuation_ptr):352 self.ResetRegisterValues()353 self.pc = continuation_ptr354 return self355class I386_RegisterSet(object):356 """ register info set for i386 architecture357 """358 register_info = { 'sets' : ['GPR'],359 'registers': [360 { 'name': 'eax' , 'bitsize': 32, 'offset' : 0, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 0, 'dwarf': 0},361 { 'name': 'ebx' , 'bitsize': 32, 'offset' : 4, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 3, 'dwarf': 3},362 { 'name': 'ecx' , 'bitsize': 32, 'offset' : 8, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 1, 'dwarf': 1},363 { 'name': 'edx' , 'bitsize': 32, 'offset' :12, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf': 2},364 { 'name': 'edi' , 'bitsize': 32, 'offset' :16, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 7, 'dwarf': 7},365 { 'name': 'esi' , 'bitsize': 32, 'offset' :20, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 6, 'dwarf': 6},366 { 'name': 'ebp' , 'bitsize': 32, 'offset' :24, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 4, 'dwarf': 5, 'generic': 'fp', 'alt-name': 'fp'},367 { 'name': 'esp' , 'bitsize': 32, 'offset' :28, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 5, 'dwarf': 4, 'generic': 'sp', 'alt-name': 'sp'},368 { 'name': 'ss' , 'bitsize': 32, 'offset' :32, 'encoding': 'uint' , 'format':'hex' , 'set': 0},369 { 'name': 'eflags', 'bitsize': 32, 'offset' :36, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' : 9, 'dwarf': 9, 'generic': 'flags'},370 { 'name': 'eip' , 'bitsize': 32, 'offset' :40, 'encoding': 'uint' , 'format':'hex' , 'set': 0, 'gcc' :8, 'dwarf':8, 'generic': 'pc', 'alt-name': 'pc'},371 { 'name': 'cs' , 'bitsize': 32, 'offset' :44, 'encoding': 'uint' , 'format':'hex' , 'set': 0},372 { 'name': 'ds' , 'bitsize': 32, 'offset' :48, 'encoding': 'uint' , 'format':'hex' , 'set': 0},373 { 'name': 'es' , 'bitsize': 32, 'offset' :52, 'encoding': 'uint' , 'format':'hex' , 'set': 0},374 { 'name': 'fs' , 'bitsize': 32, 'offset' :56, 'encoding': 'uint' , 'format':'hex' , 'set': 0},375 { 'name': 'gs' , 'bitsize': 32, 'offset' :60, 'encoding': 'uint' , 'format':'hex' , 'set': 0},376 ]377 }378 def __init__(self):379 self.ResetRegisterValues()380 381 @classmethod382 def GetRegisterInfo(cls, regnum):383 if regnum < 0 or regnum > len(cls.register_info['registers']):384 return ''385 386 reginfo = cls.register_info['registers'][regnum]387 retval = ''388 for i in reginfo.keys():389 v_str = str(reginfo[i])390 if i == 'set':391 v_str = 'General Purpose Registers'392 retval += "%s:%s;" % (str(i), v_str)393 return retval394 def ResetRegisterValues(self):395 """ set all registers to zero """396 self.eax = 0397 self.ebx = 0398 self.ecx = 0399 self.edx = 0400 self.edi = 0401 self.esi = 0402 self.ebp = 0403 self.esp = 0404 self.ss = 0405 self.eflags = 0406 self.eip = 0407 self.cs = 0408 self.ds = 0409 self.es = 0410 self.fs = 0411 self.gs = 0412 def __str__(self):413 return """414 eax = {o.eax: #010x}415 ebx = {o.ebx: #010x}416 ecx = {o.ecx: #010x}417 edx = {o.edx: #010x}418 edi = {o.edi: #010x}419 esi = {o.esi: #010x}420 ebp = {o.ebp: #010x}421 esp = {o.esp: #010x}422 ss = {o.ss: #010x}423 eflags = {o.eflags: #010x}424 eip = {o.eip: #010x}425 cs = {o.cs: #010x}426 ds = {o.ds: #010x}427 es = {o.es: #010x}428 fs = {o.fs: #010x}429 gs = {o.gs: #010x}430 """.format(o=self)431 def GetPackedRegisterState(self):432 """ get a struct.pack register data """433 return struct.pack('16I', self.eax, self.ebx, self.ecx,434 self.edx, self.edi, self.esi,435 self.ebp, self.esp, self.ss,436 self.eflags, self.eip, self.cs,437 self.ds, self.es, self.fs, self.gs438 )439 def ReadRegisterDataFromKDPSavedState(self, kdp_state, kernel_version):440 """ to be implemented"""441 return None442 def ReadRegisterDataFromKernelStack(self, kstack_saved_state_addr, kernel_version):443 """ to be implemented """444 return None445 def ReadRegisterDataFromContinuation(self, continuation_ptr):446 self.ResetRegisterValues()447 self.eip = continuation_ptr448 return self449class X86_64RegisterSet(object):450 """ register info set for x86_64 architecture """451 register_info = { 'sets' : ['GPR'],452 'registers': [453 { 'name':'rax' , 'bitsize' : 64, 'offset' : 0, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 0, 'dwarf' : 0},454 { 'name':'rbx' , 'bitsize' : 64, 'offset' : 8, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 3, 'dwarf' : 3},455 { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },456 { 'name':'rdx' , 'bitsize' : 64, 'offset' : 24, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 1, 'dwarf' : 1, 'generic':'arg3', 'alt-name':'arg3', },457 { 'name':'rdi' , 'bitsize' : 64, 'offset' : 32, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 5, 'dwarf' : 5, 'generic':'arg1', 'alt-name':'arg1', },458 { 'name':'rsi' , 'bitsize' : 64, 'offset' : 40, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 4, 'dwarf' : 4, 'generic':'arg2', 'alt-name':'arg2', },459 { 'name':'rbp' , 'bitsize' : 64, 'offset' : 48, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 6, 'dwarf' : 6, 'generic':'fp' , 'alt-name':'fp', },460 { 'name':'rsp' , 'bitsize' : 64, 'offset' : 56, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 7, 'dwarf' : 7, 'generic':'sp' , 'alt-name':'sp', },461 { 'name':'r8' , 'bitsize' : 64, 'offset' : 64, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 8, 'dwarf' : 8, 'generic':'arg5', 'alt-name':'arg5', },462 { 'name':'r9' , 'bitsize' : 64, 'offset' : 72, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 9, 'dwarf' : 9, 'generic':'arg6', 'alt-name':'arg6', },463 { 'name':'r10' , 'bitsize' : 64, 'offset' : 80, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 10, 'dwarf' : 10},464 { 'name':'r11' , 'bitsize' : 64, 'offset' : 88, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 11, 'dwarf' : 11},465 { 'name':'r12' , 'bitsize' : 64, 'offset' : 96, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 12, 'dwarf' : 12},466 { 'name':'r13' , 'bitsize' : 64, 'offset' : 104, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 13, 'dwarf' : 13},467 { 'name':'r14' , 'bitsize' : 64, 'offset' : 112, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 14, 'dwarf' : 14},468 { 'name':'r15' , 'bitsize' : 64, 'offset' : 120, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 15, 'dwarf' : 15},469 { 'name':'rip' , 'bitsize' : 64, 'offset' : 128, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 16, 'dwarf' : 16, 'generic':'pc', 'alt-name':'pc' },470 { 'name':'rflags' , 'bitsize' : 64, 'offset' : 136, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'generic':'flags', 'alt-name':'flags' },471 { 'name':'cs' , 'bitsize' : 64, 'offset' : 144, 'encoding':'uint' , 'format':'hex' , 'set': 0 },472 { 'name':'fs' , 'bitsize' : 64, 'offset' : 152, 'encoding':'uint' , 'format':'hex' , 'set': 0 },473 { 'name':'gs' , 'bitsize' : 64, 'offset' : 160, 'encoding':'uint' , 'format':'hex' , 'set': 0 },474 ]475 }476 def __init__(self):477 self.ResetRegisterValues()478 @classmethod479 def GetRegisterInfo(cls, regnum):480 if regnum < 0 or regnum > len(cls.register_info['registers']):481 return ''482 reginfo = cls.register_info['registers'][regnum]483 retval = ''484 for i in reginfo.keys():485 v_str = str(reginfo[i])486 if i == 'set':487 v_str = 'General Purpose Registers'488 retval += "%s:%s;" % (str(i), v_str)489 return retval490 def ResetRegisterValues(self):491 """ set all the registers to zero. """492 self.rax = 0493 self.rbx = 0494 self.rcx = 0495 self.rdx = 0496 self.rdi = 0497 self.rsi = 0498 self.rbp = 0499 self.rsp = 0500 self.r8 = 0501 self.r9 = 0502 self.r10 = 0503 self.r11 = 0504 self.r12 = 0505 self.r13 = 0506 self.r14 = 0507 self.r15 = 0508 self.rip = 0509 self.rflags = 0510 self.cs = 0511 self.fs = 0512 self.gs = 0513 def __str__(self):514 return """515 rax = {o.rax: <#018x}516 rbx = {o.rbx: <#018x}517 rcx = {o.rcx: <#018x}518 rdx = {o.rdx: <#018x}519 rdi = {o.rdi: <#018x}520 rsi = {o.rsi: <#018x}521 rbp = {o.rbp: <#018x}522 rsp = {o.rsp: <#018x}523 r8 = {o.r8: <#018x}524 r9 = {o.r9: <#018x}525 r10 = {o.r10: <#018x}526 r11 = {o.r11: <#018x}527 r12 = {o.r12: <#018x}528 r13 = {o.r13: <#018x}529 r14 = {o.r14: <#018x}530 r15 = {o.r15: <#018x}531 rip = {o.rip: <#018x}532 rflags = {o.rflags: <#018x}533 cs = {o.cs: <#018x}534 fs = {o.fs: <#018x}535 gs = {o.gs: <#018x}536 """.format(o=self)537 def GetPackedRegisterState(self):538 """ get a struct.pack register data for passing to C constructs """539 return struct.pack('21Q', self.rax, self.rbx, self.rcx, self.rdx, self.rdi,540 self.rsi, self.rbp, self.rsp, self.r8, self.r9,541 self.r10, self.r11, self.r12, self.r13, self.r14,542 self.r15, self.rip, self.rflags, self.cs, self.fs, self.gs)543 def ReadRegisterDataFromKDPSavedState(self, kdp_state, kernel_version):544 saved_state = kernel_version.CreateValueFromExpression(None, '(struct x86_saved_state64 *) '+ str(kdp_state.GetValueAsUnsigned()))545 saved_state = saved_state.Dereference()546 saved_state = PluginValue(saved_state)547 self.ResetRegisterValues()548 self.rdi = saved_state.GetChildMemberWithName('rdi').GetValueAsUnsigned()549 self.rsi = saved_state.GetChildMemberWithName('rsi').GetValueAsUnsigned()550 self.rdx = saved_state.GetChildMemberWithName('rdx').GetValueAsUnsigned()551 self.r10 = saved_state.GetChildMemberWithName('r10').GetValueAsUnsigned()552 self.r8 = saved_state.GetChildMemberWithName('r8').GetValueAsUnsigned()553 self.r9 = saved_state.GetChildMemberWithName('r9').GetValueAsUnsigned()554 self.r15 = saved_state.GetChildMemberWithName('r15').GetValueAsUnsigned()555 self.r14 = saved_state.GetChildMemberWithName('r14').GetValueAsUnsigned()556 self.r13 = saved_state.GetChildMemberWithName('r13').GetValueAsUnsigned()557 self.r12 = saved_state.GetChildMemberWithName('r12').GetValueAsUnsigned()558 self.r11 = saved_state.GetChildMemberWithName('r11').GetValueAsUnsigned()559 self.rbp = saved_state.GetChildMemberWithName('rbp').GetValueAsUnsigned()560 self.rbx = saved_state.GetChildMemberWithName('rbx').GetValueAsUnsigned()561 self.rcx = saved_state.GetChildMemberWithName('rcx').GetValueAsUnsigned()562 self.rax = saved_state.GetChildMemberWithName('rax').GetValueAsUnsigned()563 self.rip = saved_state.GetChildMemberWithName('isf').GetChildMemberWithName('rip').GetValueAsUnsigned()564 self.rflags = saved_state.GetChildMemberWithName('isf').GetChildMemberWithName('rflags').GetValueAsUnsigned()565 self.rsp = saved_state.GetChildMemberWithName('isf').GetChildMemberWithName('rsp').GetValueAsUnsigned()566 return self567 def ReadRegisterDataFromKernelStack(self, kstack_saved_state_addr, kernel_version):568 saved_state = kernel_version.CreateValueFromExpression(None, '(struct x86_kernel_state *) '+ str(kstack_saved_state_addr))569 saved_state = saved_state.Dereference()570 saved_state = PluginValue(saved_state)571 self.ResetRegisterValues()572 self.rbx = saved_state.GetChildMemberWithName('k_rbx').GetValueAsUnsigned()573 self.rsp = saved_state.GetChildMemberWithName('k_rsp').GetValueAsUnsigned()574 self.rbp = saved_state.GetChildMemberWithName('k_rbp').GetValueAsUnsigned()575 self.r12 = saved_state.GetChildMemberWithName('k_r12').GetValueAsUnsigned()576 self.r13 = saved_state.GetChildMemberWithName('k_r13').GetValueAsUnsigned()577 self.r14 = saved_state.GetChildMemberWithName('k_r14').GetValueAsUnsigned()578 self.r15 = saved_state.GetChildMemberWithName('k_r15').GetValueAsUnsigned()579 self.rip = saved_state.GetChildMemberWithName('k_rip').GetValueAsUnsigned()580 return self581 def ReadRegisterDataFromContinuation(self, continuation_ptr):582 self.ResetRegisterValues()583 self.rip = continuation_ptr584 return self585def IterateQueue(queue_head, element_ptr_type, element_field_name):586 """ iterate over a queue in kernel of type queue_head_t. refer to osfmk/kern/queue.h587 params:588 queue_head - lldb.SBValue : Value object for queue_head.589 element_type - lldb.SBType : a pointer type of the element 'next' points to. Typically its structs like thread, task etc..590 element_field_name - str : name of the field in target struct.591 returns:592 A generator does not return. It is used for iterating.593 SBValue : an object thats of type (element_type) queue_head->next. Always a pointer object594 """595 queue_head_addr = 0x0596 if queue_head.TypeIsPointerType():597 queue_head_addr = queue_head.GetValueAsUnsigned()598 else:599 queue_head_addr = queue_head.GetAddress().GetLoadAddress(osplugin_target_obj)600 cur_elt = queue_head.GetChildMemberWithName('next')601 while True:602 if not cur_elt.IsValid() or cur_elt.GetValueAsUnsigned() == 0 or cur_elt.GetValueAsUnsigned() == queue_head_addr:603 break604 elt = cur_elt.Cast(element_ptr_type)605 yield elt606 cur_elt = elt.GetChildMemberWithName(element_field_name).GetChildMemberWithName('next')607def GetUniqueSessionID(process_obj):608 """ Create a unique session identifier.609 params:610 process_obj: lldb.SBProcess object refering to connected process.611 returns:612 int - a unique number identified by processid and stopid.613 """614 session_key_str = ""615 if hasattr(process_obj, "GetUniqueID"):616 session_key_str += str(process_obj.GetUniqueID()) + ":"617 else:618 session_key_str += "0:"619 if hasattr(process_obj, "GetStopID"):620 session_key_str += str(process_obj.GetStopID())621 else:622 session_key_str +="1"623 return hash(session_key_str)624(archX86_64, archARMv7_family, archI386, archARMv8) = ("x86_64", ("armv7", "armv7s", "armv7k") , "i386", "arm64")625class OperatingSystemPlugIn(object):626 """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""627 def __init__(self, process):628 '''Initialization needs a valid.SBProcess object'''629 self.process = None630 self.registers = None631 self.threads = None632 self.thread_cache = {}633 self.current_session_id = 0634 self.kdp_thread = None635 if type(process) is lldb.SBProcess and process.IsValid():636 global osplugin_target_obj637 self.process = process638 self._target = process.target639 osplugin_target_obj = self._target640 self.current_session_id = GetUniqueSessionID(self.process)641 self.version = self._target.FindGlobalVariables('version', 1).GetValueAtIndex(0)642 self.kernel_stack_size = self._target.FindGlobalVariables('kernel_stack_size', 1).GetValueAtIndex(0).GetValueAsUnsigned()643 self.kernel_context_size = 0644 self.connected_over_kdp = False645 # connected_to_debugserver signifies if we are connected to astris or other gdbserver instance646 # that has the correct thread state for on core threads. For kdp and coredumps we rely on in memory647 # state of threads.648 self.connected_to_debugserver = True649 plugin_string = self.process.GetPluginName().lower()650 if plugin_string.find("kdp") >=0:651 self.connected_over_kdp = True652 self.connected_to_debugserver = False653 #print "version", self.version, "kernel_stack_size", self.kernel_stack_size, "context_size", self.kernel_context_size654 self.threads = None # Will be an dictionary containing info for each thread655 triple = self.process.target.triple656 arch = triple.split('-')[0].lower()657 self.target_arch = ""658 self.kernel_context_size = 0659 if arch == archX86_64 :660 self.target_arch = archX86_64661 print "Target arch: x86_64"662 self.register_set = X86_64RegisterSet()663 self.kernel_context_size = self._target.FindFirstType('x86_kernel_state').GetByteSize()664 elif arch in archARMv7_family :665 self.target_arch = arch666 print "Target arch: " + self.target_arch667 self.register_set = Armv7_RegisterSet()668 elif arch == archARMv8:669 self.target_arch = arch670 print "Target arch: " + self.target_arch671 self.register_set = Armv8_RegisterSet()672 # connection intel arm673 # kdp Memory Memory674 # gdb Server Server675 # coredump Memory Server676 if not self.connected_over_kdp :677 if plugin_string.find('core') >= 0 and self.target_arch == archX86_64:678 self.connected_to_debugserver = False679 self.registers = self.register_set.register_info680 if self.connected_to_debugserver:681 print "Connected to live debugserver or arm core. Will associate on-core threads to registers reported by server."682 else:683 print "Instantiating threads completely from saved state in memory."684 def create_thread(self, tid, context):685 # if tid is deadbeef means its a custom thread which kernel does not know of.686 if tid == 0xdeadbeef :687 # tid manipulation should be the same as in "switchtoregs" code in lldbmacros/process.py .688 tid = 0xdead0000 | (context & ~0xffff0000)689 tid = tid & 0xdeadffff690 thread_obj = { 'tid' : tid,691 'ptr' : context,692 'name' : 'switchtoregs' + hex(context),693 'queue' : 'None',694 'state' : 'stopped',695 'stop_reason' : 'none'696 }697 self.thread_cache[tid] = thread_obj698 return thread_obj699 700 th_ptr = context701 th = self.version.CreateValueFromExpression(str(th_ptr),'(struct thread *)' + str(th_ptr))702 thread_id = th.GetChildMemberWithName('thread_id').GetValueAsUnsigned()703 if tid != thread_id:704 print "FATAL ERROR: Creating thread from memory 0x%x with tid in mem=%d when requested tid = %d " % (context, thread_id, tid)705 return None706 thread_obj = { 'tid' : thread_id,707 'ptr' : th.GetValueAsUnsigned(),708 'name' : hex(th.GetValueAsUnsigned()).rstrip('L'),709 'queue' : hex(th.GetChildMemberWithName('wait_queue').GetValueAsUnsigned()).rstrip('L'),710 'state' : 'stopped',711 'stop_reason' : 'none'712 }713 if self.current_session_id != GetUniqueSessionID(self.process):714 self.thread_cache = {}715 self.current_session_id = GetUniqueSessionID(self.process)716 self.thread_cache[tid] = thread_obj717 return thread_obj718 def get_thread_info(self):719 self.kdp_thread = None720 self.kdp_state = None721 if self.connected_over_kdp :722 kdp = self._target.FindGlobalVariables('kdp',1).GetValueAtIndex(0)723 kdp_state = kdp.GetChildMemberWithName('saved_state')724 kdp_thread = kdp.GetChildMemberWithName('kdp_thread')725 if kdp_thread and kdp_thread.GetValueAsUnsigned() != 0:726 self.kdp_thread = kdp_thread727 self.kdp_state = kdp_state728 kdp_thid = kdp_thread.GetChildMemberWithName('thread_id').GetValueAsUnsigned()729 self.create_thread(kdp_thid, kdp_thread.GetValueAsUnsigned())730 self.thread_cache[kdp_thid]['core']=0731 retval = [self.thread_cache[kdp_thid]]732 return retval733 else:734 print "FATAL FAILURE: Unable to find kdp_thread state for this connection."735 return []736 num_threads = self._target.FindGlobalVariables('threads_count',1).GetValueAtIndex(0).GetValueAsUnsigned()737 #In case we are caught before threads are initialized. Fallback to threads known by astris/gdb server.738 if num_threads <=0 :739 return []740 self.current_session_id = GetUniqueSessionID(self.process)741 self.threads = []742 self.thread_cache = {}743 self.processors = []744 try:745 processor_list_val = PluginValue(self._target.FindGlobalVariables('processor_list',1).GetValueAtIndex(0))746 while processor_list_val.IsValid() and processor_list_val.GetValueAsUnsigned() !=0 :747 th = processor_list_val.GetChildMemberWithName('active_thread')748 th_id = th.GetChildMemberWithName('thread_id').GetValueAsUnsigned()749 cpu_id = processor_list_val.GetChildMemberWithName('cpu_id').GetValueAsUnsigned()750 self.processors.append({'active_thread': th.GetValueAsUnsigned(), 'cpu_id': cpu_id})751 self.create_thread(th_id, th.GetValueAsUnsigned())752 if self.connected_to_debugserver:753 self.thread_cache[th_id]['core'] = cpu_id754 self.thread_cache[th_id]['queue'] = "cpu-%d" % int(cpu_id)755 nth = self.thread_cache[th_id]756 self.threads.append(nth)757 self.thread_cache[nth['tid']] = nth758 processor_list_val = processor_list_val.GetChildMemberWithName('processor_list')759 except KeyboardInterrupt, ke:760 print "OS Plugin Interrupted during thread loading process. \nWARNING:Thread registers and backtraces may not be accurate."761 return self.threads762 if hasattr(self.process, 'CreateOSPluginThread'):763 return self.threads764 # FIXME remove legacy code765 try:766 thread_q_head = self._target.FindGlobalVariables('threads', 1).GetValueAtIndex(0)767 thread_type = self._target.FindFirstType('thread')768 thread_ptr_type = thread_type.GetPointerType()769 for th in IterateQueue(thread_q_head, thread_ptr_type, 'threads'):770 th_id = th.GetChildMemberWithName('thread_id').GetValueAsUnsigned()771 self.create_thread(th_id, th.GetValueAsUnsigned())772 nth = self.thread_cache[th_id]773 for cputhread in self.processors:774 if cputhread['active_thread'] == nth['ptr']:775 nth['core'] = cputhread['cpu_id']776 self.threads.append( nth )777 except KeyboardInterrupt, ke:778 print "OS Plugin Interrupted during thread loading process. \nWARNING:Thread registers and backtraces may not be accurate."779 return self.threads780 # end legacy code781 return self.threads782 def get_register_info(self):783 if self.registers == None:784 print "Register Information not found "785 return self.register_set.register_info786 def get_register_data(self, tid):787 thobj = None788 try:789 regs = self.register_set790 if self.current_session_id != GetUniqueSessionID(self.process):791 self.thread_cache = {}792 self.current_session_id = GetUniqueSessionID(self.process)793 if tid in self.thread_cache.keys():794 795 #Check if the thread is a fake one. Then create and return registers directly796 if self.thread_cache[tid]['name'].find('switchtoregs') == 0:797 savedstateobj = self.version.CreateValueFromExpression(None, '(uintptr_t *) ' + str(self.thread_cache[tid]['ptr']))798 regs.ReadRegisterDataFromKDPSavedState(savedstateobj, self.version)799 return regs.GetPackedRegisterState()800 thobj = self.version.CreateValueFromExpression(self.thread_cache[tid]['name'], '(struct thread *)' + str(self.thread_cache[tid]['ptr']))801 802 if thobj == None :803 print "FATAL ERROR: Could not find thread with id %d" % tid804 regs.ResetRegisterValues()805 return regs.GetPackedRegisterState()806 if self.kdp_thread and self.kdp_thread.GetValueAsUnsigned() == thobj.GetValueAsUnsigned():807 regs.ReadRegisterDataFromKDPSavedState(self.kdp_state, self.version)808 return regs.GetPackedRegisterState()809 if int(PluginValue(thobj).GetChildMemberWithName('kernel_stack').GetValueAsUnsigned()) != 0 :810 if self.target_arch == archX86_64 :811 # we do have a stack so lets get register information812 saved_state_addr = PluginValue(thobj).GetChildMemberWithName('kernel_stack').GetValueAsUnsigned() + self.kernel_stack_size - self.kernel_context_size813 regs.ReadRegisterDataFromKernelStack(saved_state_addr, self.version)814 return regs.GetPackedRegisterState()815 elif self.target_arch in archARMv7_family and int(PluginValue(thobj).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()) != 0:816 #we have stack on the machine.kstackptr.817 saved_state_addr = PluginValue(thobj).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()818 regs.ReadRegisterDataFromKernelStack(saved_state_addr, self.version)819 return regs.GetPackedRegisterState()820 elif self.target_arch == archARMv8 and int(PluginValue(thobj).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()) != 0:821 saved_state_addr = PluginValue(thobj).GetChildMemberWithName('machine').GetChildMemberWithName('kstackptr').GetValueAsUnsigned()822 arm_ctx = PluginValue(self.version.CreateValueFromExpression(None, '(struct arm_context *) ' + str(saved_state_addr)))823 ss_64_addr = arm_ctx.GetChildMemberWithName('ss').GetChildMemberWithName('uss').GetChildMemberWithName('ss_64').GetLoadAddress()824 regs.ReadRegisterDataFromKernelStack(ss_64_addr, self.version)825 return regs.GetPackedRegisterState()826 elif self.target_arch == archX86_64 or self.target_arch in archARMv7_family or self.target_arch == archARMv8:827 regs.ReadRegisterDataFromContinuation( PluginValue(thobj).GetChildMemberWithName('continuation').GetValueAsUnsigned())828 return regs.GetPackedRegisterState()829 #incase we failed very miserably830 except KeyboardInterrupt, ke:831 print "OS Plugin Interrupted during thread register load. \nWARNING:Thread registers and backtraces may not be accurate. for tid = %d" % tid832 regs.ResetRegisterValues()833 print "FATAL ERROR: Failed to get register state for thread id 0x%x " % tid834 print thobj...
sync_entries.py
Source:sync_entries.py
...18 get_payments_against_credit_entries(get_qb_payment)19def get_payment_dict(get_qb_payment):20 recived_payment = [] 21 for entries in get_qb_payment:22 if entries.get('DepositToAccountRef'):23 for line in entries['Line']:24 recived_payment.append({25 'Id': entries.get('Id')+"-"+'SI'+"-"+line.get('LinkedTxn')[0].get('TxnId'),26 'Type': line.get('LinkedTxn')[0].get('TxnType'),27 'ExchangeRate': entries.get('ExchangeRate'),28 'Amount': line.get('Amount')*entries.get('ExchangeRate'),29 'TxnDate': entries.get('TxnDate'),30 'qb_account_id': entries.get('DepositToAccountRef').get('value'),31 'qb_si_id':line.get('LinkedTxn')[0].get('TxnId'),32 'paid_amount': line.get('Amount'),33 "doc_no": entries.get("DocNumber")34 })35 return recived_payment36def get_payments_against_credit_entries(get_qb_payment):37 """Get payment entries against credit note"""38 try:39 payment_against_credit_note = []40 for entries in get_qb_payment:41 if not entries.get('DepositToAccountRef'):42 payment_against_credit_note.append(entries);43 if payment_against_credit_note:44 adjust_entries(payment_against_credit_note)45 except Exception, e:46 make_quickbooks_log(title=e.message, status="Error", method="get_payments_against_credit_entries", message=frappe.get_traceback(),47 request_data=get_qb_payment, exception=True)48def adjust_entries(payment_against_credit_note):49 try:50 for entries in payment_against_credit_note:51 payments, credit_notes = {}, [] 52 for line in entries['Line']:53 payment_dict = get_credit_note_dict(entries, line)54 if line.get('LinkedTxn')[0].get('TxnType') == "Invoice":55 payments[payment_dict.get("qb_si_id")] = payment_dict56 payments[payment_dict.get("qb_si_id")]["credit_notes"] = []57 else:58 credit_notes.append(payment_dict)59 60 for row in payments:61 payments[row]["credit_notes"].extend(credit_notes)62 63 if payments:64 adjust_je_against_cn(payments)65 except Exception, e:66 make_quickbooks_log(title=e.message, status="Error", method="adjust_entries", message=frappe.get_traceback(),67 request_data=payment_against_credit_note, exception=True)68def get_credit_note_dict(entries, line):69 return {70 'Id': entries.get('Id')+"-"+'SI'+"-"+line.get('LinkedTxn')[0].get('TxnId'),71 'Type': line.get('LinkedTxn')[0].get('TxnType'),72 'ExchangeRate': entries.get('ExchangeRate'),73 'Amount': flt(line.get('Amount')*entries.get('ExchangeRate'),2),74 'TxnDate': entries.get('TxnDate'),75 'qb_si_id': line.get('LinkedTxn')[0].get('TxnId') if line.get('LinkedTxn')[0].get('TxnType') == "Invoice" else None,76 'paid_amount': flt(line.get('Amount')),77 "doc_no": entries.get("DocNumber"),78 "credit_note_id" : line.get('LinkedTxn')[0].get('TxnId')+"CE" if line.get('LinkedTxn')[0].get('TxnType') == "CreditMemo" else None,79 "customer_name" : frappe.db.get_value("Customer",{"quickbooks_cust_id":entries['CustomerRef'].get('value')},"name")80 }81def adjust_je_against_cn(payments):82 try:83 """ Adjust Journal Entries against Credit Note """84 for si, value in payments.iteritems():85 if len(value['credit_notes']) == 1:86 for cn in value['credit_notes']:87 lst = []88 quickbooks_journal_entry_id = cn.get('credit_note_id')89 args = get_jv_voucher_detail_no(quickbooks_journal_entry_id)90 si_name =frappe.db.get_value("Sales Invoice", {"quickbooks_invoce_id": value.get('qb_si_id'),91 "outstanding_amount":['!=',0] }, "name")92 if args.get('voucher_detail_no') and args.get('unadjusted_amount') and si_name:93 invoice = frappe.get_doc("Sales Invoice", si_name)94 lst.append(frappe._dict(reconcile_entry(args, "Sales Invoice", si_name,95 invoice, paid_amt=value.get('paid_amount'))))96 if lst:97 from erpnext.accounts.utils import reconcile_against_document98 reconcile_against_document(lst)99 frappe.db.commit()100 elif len(value['credit_notes']) > 1:101 for cn in value['credit_notes']:102 lst1 = []103 quickbooks_journal_entry_id = cn.get('credit_note_id')104 args = get_jv_voucher_detail_no(quickbooks_journal_entry_id)105 si_name =frappe.db.get_value("Sales Invoice", {"quickbooks_invoce_id": value.get('qb_si_id'),106 "outstanding_amount":['!=',0] }, "name")107 if args.get('voucher_detail_no') and args.get('unadjusted_amount') and si_name:108 invoice = frappe.get_doc("Sales Invoice", si_name)109 lst1.append(frappe._dict(reconcile_entry(args, "Sales Invoice", si_name,110 invoice, paid_amt=cn.get('paid_amount'))))111 if lst1:112 from erpnext.accounts.utils import reconcile_against_document113 reconcile_against_document(lst1)114 frappe.db.commit()115 except Exception, e:116 make_quickbooks_log(title=e.message, status="Error", method="adjust_je_against_cn", message=frappe.get_traceback(),117 request_data=payments, exception=True)118 119def reconcile_entry(args, invoice_type , invoice_name, invoice, paid_amt=None):120 if invoice_type == "Purchase Invoice":121 dr_or_cr = "debit_in_account_currency"122 party_type = "Supplier"123 party = invoice.get('supplier_name')124 account = invoice.get("credit_to")125 elif invoice_type == "Sales Invoice":126 dr_or_cr = "credit_in_account_currency"127 party_type = "Customer"128 party = invoice.get('customer_name')129 account = invoice.get('debit_to')130 return {131 'voucher_type' : 'Journal Entry',132 'voucher_no' : args.get('voucher_no'),133 'voucher_detail_no' : args.get('voucher_detail_no'),134 'against_voucher_type' : invoice_type,135 'against_voucher' : invoice_name,136 'account' : account,137 'party_type': party_type,138 'party': party,139 'is_advance' : "Yes",140 'dr_or_cr' : dr_or_cr,141 'unadjusted_amount' : round(args.get('unadjusted_amount'),2),142 'allocated_amount' : round(paid_amt,2)143 }144def get_jv_voucher_detail_no(quickbooks_journal_entry_id):145 account_dict ={}146 jv_name = frappe.db.get_value("Journal Entry",147 {"quickbooks_journal_entry_id": quickbooks_journal_entry_id}, "name")148 jv = frappe.get_doc("Journal Entry", jv_name)149 if jv.get('voucher_type') == 'Credit Note':150 for row in jv.accounts:151 if row.get('credit_in_account_currency') and not row.get('reference_name'):152 account_dict['voucher_detail_no'] = row.get('name')153 account_dict['unadjusted_amount'] = row.get('credit_in_account_currency')154 account_dict['voucher_no'] = jv_name155 elif jv.get('voucher_type') == 'Debit Note':156 for row in jv.accounts:157 if row.get('debit_in_account_currency') and not row.get('reference_name'):158 account_dict['voucher_detail_no'] = row.get('name')159 account_dict['unadjusted_amount'] = row.get('debit_in_account_currency')160 account_dict['voucher_no'] = jv_name161 return frappe._dict(account_dict)162 163def sync_qb_journal_entry_against_si(get_payment_received):164 quickbooks_settings = frappe.get_doc("Quickbooks Settings", "Quickbooks Settings")165 for recived_payment in get_payment_received:166 try:167 if not frappe.db.get_value("Payment Entry", {"quickbooks_payment_id": recived_payment.get('Id')}, "name"):168 create_payment_entry_si(recived_payment, quickbooks_settings)169 except Exception, e:170 make_quickbooks_log(title=e.message, status="Error", method="sync_qb_journal_entry_against_si", message=frappe.get_traceback(),171 request_data=recived_payment, exception=True)172def create_payment_entry_si(recived_payment, quickbooks_settings):173 """ create payment entry against sales Invoice """174 invoice_name =frappe.db.get_value("Sales Invoice", {"quickbooks_invoce_id": recived_payment.get('qb_si_id')}, "name")175 account_ref = get_account_detail(recived_payment.get('qb_account_id'))176 if invoice_name:177 ref_doc = frappe.get_doc("Sales Invoice", invoice_name)178 si_pe = frappe.new_doc("Payment Entry")179 si_pe.naming_series = "SI-PE-QB-"180 si_pe.quickbooks_invoice_reference_no = ref_doc.get('quickbooks_invoice_no')181 si_pe.quickbooks_payment_reference_no = recived_payment.get('doc_no')182 si_pe.posting_date = recived_payment.get('TxnDate')183 si_pe.quickbooks_payment_id = recived_payment.get('Id')184 si_pe.payment_type = "Receive"185 si_pe.party_type = "Customer"186 si_pe.party = ref_doc.customer_name187 si_pe.paid_from = ref_doc.get("debit_to")188 # si_pe.paid_to = account_ref.get('name')189 si_pe.paid_amount= flt(recived_payment.get('paid_amount'), si_pe.precision('paid_amount'))190 si_pe.source_exchange_rate = recived_payment.get('ExchangeRate')191 si_pe.base_paid_amount = flt(recived_payment.get('paid_amount') * recived_payment.get('ExchangeRate'), si_pe.precision('base_paid_amount'))192 si_pe.base_received_amount = flt(recived_payment.get('paid_amount') * recived_payment.get('ExchangeRate'), si_pe.precision('base_received_amount'))193 si_pe.allocate_payment_amount = 1194 si_pe.reference_no = recived_payment.get('Type')195 si_pe.reference_date = recived_payment.get('TxnDate')196 get_accounts(si_pe, ref_doc, recived_payment, quickbooks_settings)197 get_reference(dt= "Sales Invoice", pay_entry_obj= si_pe, ref_doc= ref_doc, ref_pay= recived_payment, quickbooks_settings= quickbooks_settings)198 get_deduction(dt= "Sales Invoice", pay_entry_obj= si_pe, ref_doc= ref_doc, ref_pay= recived_payment, quickbooks_settings= quickbooks_settings)199 200 si_pe.flags.ignore_mandatory = True201 si_pe.save(ignore_permissions=True)202 si_pe.submit()203 frappe.db.commit()204def get_accounts(si_pe, ref_doc, recived_payment, quickbooks_settings):205 company_name = quickbooks_settings.select_company206 company_currency = frappe.db.get_value("Company", {"name": company_name}, "default_currency")207 account_ref = get_account_detail(recived_payment.get('qb_account_id'))208 si_pe.paid_to = account_ref.get('name')209 if account_ref.get('account_currency') == company_currency:210 si_pe.target_exchange_rate = 1211 si_pe.received_amount = flt(recived_payment.get('paid_amount') * recived_payment.get('ExchangeRate'), si_pe.precision('received_amount'))212 else:213 si_pe.target_exchange_rate = recived_payment.get('ExchangeRate')214 si_pe.received_amount = flt(recived_payment.get('paid_amount') , si_pe.precision('received_amount'))215""" Create Payment entry against Purchase Invoices""" 216def sync_pi_payment(quickbooks_obj):217 """Get all BillPayment(Payment Entry) from QuickBooks for all the paid Bills"""218 business_objects = "BillPayment"219 get_qb_billpayment = pagination(quickbooks_obj, business_objects)220 if get_qb_billpayment: 221 get_bill_pi = get_bill_payment_dict(get_qb_billpayment)222 if get_bill_pi:223 sync_qb_journal_entry_against_pi(get_bill_pi)224 get_payments_against_debit_entries(get_qb_billpayment)225def get_bill_payment_dict(get_qb_billpayment):226 paid_pi = []227 for entries in get_qb_billpayment:228 for linked_txn in entries['Line']:229 has_bank_ref = entries.get('CheckPayment').get('BankAccountRef') if entries.get('CheckPayment').get('BankAccountRef') else ''230 if has_bank_ref:231 paid_pi.append({232 "Id": entries.get('Id') + "-" +'PI'+"-"+ linked_txn.get('LinkedTxn')[0].get('TxnId'),233 "Type" : linked_txn.get('LinkedTxn')[0].get('TxnType'),234 "ExchangeRate" :entries.get('ExchangeRate'),235 "Amount": linked_txn.get('Amount')*entries.get('ExchangeRate'),236 "TxnDate" : entries.get('TxnDate'),237 "PayType" :entries.get('PayType'),238 "qb_account_id": entries.get('CheckPayment').get('BankAccountRef').get('value'),239 "qb_pi_id": linked_txn.get('LinkedTxn')[0].get('TxnId'),240 'paid_amount': linked_txn.get('Amount'),241 "doc_no": entries.get("DocNumber")242 })243 return paid_pi244def get_vendor_debit_dict(entries, line):245 return {246 'Id': entries.get('Id')+"-"+'PI'+"-"+line.get('LinkedTxn')[0].get('TxnId'),247 'Type': line.get('LinkedTxn')[0].get('TxnType'),248 'ExchangeRate': entries.get('ExchangeRate'),249 'Amount': flt(line.get('Amount')*entries.get('ExchangeRate'), 2),250 'TxnDate': entries.get('TxnDate'),251 'qb_pi_id': line.get('LinkedTxn')[0].get('TxnId') if line.get('LinkedTxn')[0].get('TxnType') == "Bill" else None,252 'paid_amount': flt(line.get('Amount')),253 "doc_no": entries.get("DocNumber"),254 "vendor_credit_id" : line.get('LinkedTxn')[0].get('TxnId')+"DE" if line.get('LinkedTxn')[0].get('TxnType') == "VendorCredit" else None,255 }256def adjust_debit_entries(payment_against_debit_note):257 for entries in payment_against_debit_note:258 payments, vendor_credit = {}, [] 259 for line in entries['Line']:260 payment_dict = get_vendor_debit_dict(entries, line)261 if line.get('LinkedTxn')[0].get('TxnType') == "Bill":262 payments[payment_dict.get("qb_pi_id")] = payment_dict263 payments[payment_dict.get("qb_pi_id")]["vendor_credit"] = []264 else:265 vendor_credit.append(payment_dict)266 267 for row in payments:268 payments[row]["vendor_credit"].extend(vendor_credit)269 270 if payments:271 adjust_je_against_dn(payments)272def get_payments_against_debit_entries(get_qb_payment):273 """Get payment entries against credit note"""274 try:275 payment_against_debit_note = []276 for entries in get_qb_payment:277 if not entries.get('CheckPayment').get('BankAccountRef'):278 payment_against_debit_note.append(entries);279 if payment_against_debit_note:280 adjust_debit_entries(payment_against_debit_note)281 except Exception, e:282 make_quickbooks_log(title=e.message, status= "Error", method="get_payments_against_debit_entries", message=frappe.get_traceback(),283 request_data= get_qb_payment, exception= True)284def adjust_je_against_dn(payments):285 """ Adjust Journal Entries against Debit Note """286 try :287 for pi, value in payments.iteritems():288 if len(value['vendor_credit']) == 1:289 for dn in value['vendor_credit']:290 lst = []291 quickbooks_journal_entry_id = dn.get('vendor_credit_id')292 args = get_jv_voucher_detail_no(quickbooks_journal_entry_id)293 pi_name =frappe.db.get_value("Purchase Invoice", {"quickbooks_purchase_invoice_id": value.get('qb_pi_id'),294 "outstanding_amount":['!=',0] }, "name")295 if args.get('voucher_detail_no') and args.get('unadjusted_amount') and pi_name:296 invoice = frappe.get_doc("Purchase Invoice", pi_name)297 lst.append(frappe._dict(reconcile_entry(args, "Purchase Invoice", pi_name,298 invoice, paid_amt=value.get('paid_amount'))))299 if lst:300 from erpnext.accounts.utils import reconcile_against_document301 reconcile_against_document(lst)302 frappe.db.commit()303 elif len(value['vendor_credit']) > 1:304 for dn in value['vendor_credit']:305 lst1 = []306 quickbooks_journal_entry_id = dn.get('vendor_credit_id')307 args = get_jv_voucher_detail_no(quickbooks_journal_entry_id)308 pi_name =frappe.db.get_value("Purchase Invoice", {"quickbooks_purchase_invoice_id": value.get('qb_pi_id'),309 "outstanding_amount":['!=',0] }, "name")310 if args.get('voucher_detail_no') and args.get('unadjusted_amount') and pi_name:311 invoice = frappe.get_doc("Purchase Invoice", pi_name)312 lst1.append(frappe._dict(reconcile_entry(args, "Purchase Invoice", pi_name,313 invoice, paid_amt=dn.get('paid_amount'))))314 if lst1:315 from erpnext.accounts.utils import reconcile_against_document316 reconcile_against_document(lst1)317 frappe.db.commit()318 except Exception, e:319 make_quickbooks_log(title=e.message, status="Error", method="adjust_je_against_dn", message=frappe.get_traceback(),320 request_data=payments, exception=True)321def sync_qb_journal_entry_against_pi(get_bill_pi):322 quickbooks_settings = frappe.get_doc("Quickbooks Settings", "Quickbooks Settings")323 for bill_payment in get_bill_pi:324 try:325 if not frappe.db.get_value("Payment Entry", {"quickbooks_payment_id": bill_payment.get('Id')}, "name"):326 create_payment_entry_pi(bill_payment, quickbooks_settings)327 except Exception, e:328 make_quickbooks_log(title=e.message, status="Error", method="sync_qb_journal_entry_against_pi", message=frappe.get_traceback(),329 request_data=bill_payment, exception=True)330def create_payment_entry_pi(bill_payment, quickbooks_settings):331 """ create payment entry against Purchase Invoice """332 invoice_name =frappe.db.get_value("Purchase Invoice", {"quickbooks_purchase_invoice_id": bill_payment.get('qb_pi_id')}, "name")333 account_ref = get_account_detail(bill_payment.get('qb_account_id'))334 if invoice_name:335 ref_doc = frappe.get_doc("Purchase Invoice", invoice_name)336 pi_pe = frappe.new_doc("Payment Entry")337 pi_pe.naming_series = "PI-PE-QB-"338 pi_pe.quickbooks_invoice_reference_no = ref_doc.get('quickbooks_bill_no')339 pi_pe.quickbooks_payment_reference_no = bill_payment.get('doc_no')340 pi_pe.posting_date = bill_payment.get('TxnDate')341 pi_pe.quickbooks_payment_id = bill_payment.get('Id')342 pi_pe.payment_type = "Pay"343 pi_pe.party_type = "Supplier"344 pi_pe.party = ref_doc.supplier_name345 pi_pe.paid_to = ref_doc.get("credit_to")346 pi_pe.received_amount = flt(bill_payment.get('paid_amount'), pi_pe.precision('received_amount'))347 pi_pe.target_exchange_rate = bill_payment.get('ExchangeRate')348 pi_pe.base_received_amount = flt(bill_payment.get('paid_amount') * bill_payment.get('ExchangeRate'), pi_pe.precision('base_received_amount'))349 pi_pe.base_paid_amount = flt(bill_payment.get('paid_amount') * bill_payment.get('ExchangeRate'), pi_pe.precision('base_paid_amount'))350 pi_pe.allocate_payment_amount = 1351 pi_pe.reference_no = bill_payment.get('Type')352 pi_pe.reference_date = bill_payment.get('TxnDate')353 get_accounts_pi(pi_pe, ref_doc, bill_payment, quickbooks_settings)354 get_reference(dt= "Purchase Invoice", pay_entry_obj= pi_pe, ref_doc= ref_doc, ref_pay= bill_payment, quickbooks_settings= quickbooks_settings)355 get_deduction(dt= "Purchase Invoice", pay_entry_obj= pi_pe, ref_doc= ref_doc, ref_pay= bill_payment, quickbooks_settings= quickbooks_settings)356 pi_pe.flags.ignore_mandatory = True357 pi_pe.save(ignore_permissions=True)358 pi_pe.submit()359 frappe.db.commit()360def get_accounts_pi(pi_pe, ref_doc, bill_payment, quickbooks_settings):361 """ set exchange rate and payment amount , when payment is done in multi currency, apart from system currency """362 company_name = quickbooks_settings.select_company363 company_currency = frappe.db.get_value("Company", {"name": company_name}, "default_currency")364 account_ref = get_account_detail(bill_payment.get('qb_account_id'))365 pi_pe.paid_from = account_ref.get('name')366 if account_ref.get('account_currency') == company_currency:367 pi_pe.source_exchange_rate = 1368 pi_pe.paid_amount = flt(bill_payment.get('paid_amount') * bill_payment.get('ExchangeRate'), pi_pe.precision('paid_amount'))369 else:370 pi_pe.source_exchange_rate = bill_payment.get('ExchangeRate')371 pi_pe.paid_amount = flt(bill_payment.get('paid_amount') , pi_pe.precision('paid_amount'))372def get_reference(dt= None, pay_entry_obj= None, ref_doc= None, ref_pay= None, quickbooks_settings= None):373 """ get reference of Invoices for which payment is done. """374 account = pay_entry_obj.append("references", {})375 account.reference_doctype = dt376 account.reference_name = ref_doc.get('name')377 account.total_amount = flt(ref_doc.get('grand_total'), account.precision('total_amount'))378 account.allocated_amount = flt(ref_pay.get('paid_amount'), account.precision('allocated_amount'))379def get_deduction(dt= None, pay_entry_obj= None, ref_doc= None, ref_pay= None, quickbooks_settings= None):380 """ calculate deduction for Multi currency gain and loss """381 if dt == "Purchase Invoice":382 total_allocated_amount = flt(ref_pay.get("paid_amount") * ref_doc.get('conversion_rate'))383 recevied_amount = flt(ref_pay.get("paid_amount") * ref_pay.get('ExchangeRate'))384 deduction_amount = recevied_amount - total_allocated_amount385 else:386 total_allocated_amount = flt(flt(ref_pay.get("paid_amount")) * flt(ref_doc.get('conversion_rate')))387 deduction_amount = total_allocated_amount - pay_entry_obj.base_received_amount388 if round(deduction_amount, 2):389 deduction = pay_entry_obj.append("deductions",{})390 deduction.account = quickbooks_settings.profit_loss_account391 deduction.cost_center = frappe.db.get_value("Company",{"name": quickbooks_settings.select_company },"cost_center")392 deduction.amount = flt(deduction_amount, deduction.precision('amount'))393def get_account_detail(quickbooks_account_id):394 """ account for payment """395 return frappe.db.get_value("Account", {"quickbooks_account_id": quickbooks_account_id}, ["name", "account_currency"], as_dict=1)396# def reconcile_entry(args, si_name, invoice, paid_amt=None):397# return {398# 'voucher_type' : 'Journal Entry',399# 'voucher_no' : args.get('voucher_no'),400# 'voucher_detail_no' : args.get('voucher_detail_no'),401# 'against_voucher_type' : 'Sales Invoice',402# 'against_voucher' : si_name,403# 'account' : invoice.get('debit_to'),404# 'party_type': "Customer",405# 'party': invoice.get('customer_name'),406# 'is_advance' : "Yes",407# 'dr_or_cr' : "credit_in_account_currency",408# 'unadjusted_amount' : round(args.get('unadjusted_amount'),2),409# 'allocated_amount' : round(paid_amount,2)...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!