test_helper.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. # -*- test-case-name: twisted.conch.test.test_helper -*-
  2. # Copyright (c) Twisted Matrix Laboratories.
  3. # See LICENSE for details.
  4. from twisted.conch.insults import helper
  5. from twisted.conch.insults.insults import G0, G1, G2, G3
  6. from twisted.conch.insults.insults import modes, privateModes
  7. from twisted.conch.insults.insults import (
  8. NORMAL, BOLD, UNDERLINE, BLINK, REVERSE_VIDEO)
  9. from twisted.python.compat import _PY3
  10. from twisted.trial import unittest
  11. WIDTH = 80
  12. HEIGHT = 24
  13. class BufferTests(unittest.TestCase):
  14. def setUp(self):
  15. self.term = helper.TerminalBuffer()
  16. self.term.connectionMade()
  17. def testInitialState(self):
  18. self.assertEqual(self.term.width, WIDTH)
  19. self.assertEqual(self.term.height, HEIGHT)
  20. self.assertEqual(self.term.__bytes__(),
  21. b'\n' * (HEIGHT - 1))
  22. self.assertEqual(self.term.reportCursorPosition(), (0, 0))
  23. def test_initialPrivateModes(self):
  24. """
  25. Verify that only DEC Auto Wrap Mode (DECAWM) and DEC Text Cursor Enable
  26. Mode (DECTCEM) are initially in the Set Mode (SM) state.
  27. """
  28. self.assertEqual(
  29. {privateModes.AUTO_WRAP: True,
  30. privateModes.CURSOR_MODE: True},
  31. self.term.privateModes)
  32. def test_carriageReturn(self):
  33. """
  34. C{"\r"} moves the cursor to the first column in the current row.
  35. """
  36. self.term.cursorForward(5)
  37. self.term.cursorDown(3)
  38. self.assertEqual(self.term.reportCursorPosition(), (5, 3))
  39. self.term.insertAtCursor(b"\r")
  40. self.assertEqual(self.term.reportCursorPosition(), (0, 3))
  41. def test_linefeed(self):
  42. """
  43. C{"\n"} moves the cursor to the next row without changing the column.
  44. """
  45. self.term.cursorForward(5)
  46. self.assertEqual(self.term.reportCursorPosition(), (5, 0))
  47. self.term.insertAtCursor(b"\n")
  48. self.assertEqual(self.term.reportCursorPosition(), (5, 1))
  49. def test_newline(self):
  50. """
  51. C{write} transforms C{"\n"} into C{"\r\n"}.
  52. """
  53. self.term.cursorForward(5)
  54. self.term.cursorDown(3)
  55. self.assertEqual(self.term.reportCursorPosition(), (5, 3))
  56. self.term.write(b"\n")
  57. self.assertEqual(self.term.reportCursorPosition(), (0, 4))
  58. def test_setPrivateModes(self):
  59. """
  60. Verify that L{helper.TerminalBuffer.setPrivateModes} changes the Set
  61. Mode (SM) state to "set" for the private modes it is passed.
  62. """
  63. expected = self.term.privateModes.copy()
  64. self.term.setPrivateModes([privateModes.SCROLL, privateModes.SCREEN])
  65. expected[privateModes.SCROLL] = True
  66. expected[privateModes.SCREEN] = True
  67. self.assertEqual(expected, self.term.privateModes)
  68. def test_resetPrivateModes(self):
  69. """
  70. Verify that L{helper.TerminalBuffer.resetPrivateModes} changes the Set
  71. Mode (SM) state to "reset" for the private modes it is passed.
  72. """
  73. expected = self.term.privateModes.copy()
  74. self.term.resetPrivateModes([privateModes.AUTO_WRAP, privateModes.CURSOR_MODE])
  75. del expected[privateModes.AUTO_WRAP]
  76. del expected[privateModes.CURSOR_MODE]
  77. self.assertEqual(expected, self.term.privateModes)
  78. def testCursorDown(self):
  79. self.term.cursorDown(3)
  80. self.assertEqual(self.term.reportCursorPosition(), (0, 3))
  81. self.term.cursorDown()
  82. self.assertEqual(self.term.reportCursorPosition(), (0, 4))
  83. self.term.cursorDown(HEIGHT)
  84. self.assertEqual(self.term.reportCursorPosition(), (0, HEIGHT - 1))
  85. def testCursorUp(self):
  86. self.term.cursorUp(5)
  87. self.assertEqual(self.term.reportCursorPosition(), (0, 0))
  88. self.term.cursorDown(20)
  89. self.term.cursorUp(1)
  90. self.assertEqual(self.term.reportCursorPosition(), (0, 19))
  91. self.term.cursorUp(19)
  92. self.assertEqual(self.term.reportCursorPosition(), (0, 0))
  93. def testCursorForward(self):
  94. self.term.cursorForward(2)
  95. self.assertEqual(self.term.reportCursorPosition(), (2, 0))
  96. self.term.cursorForward(2)
  97. self.assertEqual(self.term.reportCursorPosition(), (4, 0))
  98. self.term.cursorForward(WIDTH)
  99. self.assertEqual(self.term.reportCursorPosition(), (WIDTH, 0))
  100. def testCursorBackward(self):
  101. self.term.cursorForward(10)
  102. self.term.cursorBackward(2)
  103. self.assertEqual(self.term.reportCursorPosition(), (8, 0))
  104. self.term.cursorBackward(7)
  105. self.assertEqual(self.term.reportCursorPosition(), (1, 0))
  106. self.term.cursorBackward(1)
  107. self.assertEqual(self.term.reportCursorPosition(), (0, 0))
  108. self.term.cursorBackward(1)
  109. self.assertEqual(self.term.reportCursorPosition(), (0, 0))
  110. def testCursorPositioning(self):
  111. self.term.cursorPosition(3, 9)
  112. self.assertEqual(self.term.reportCursorPosition(), (3, 9))
  113. def testSimpleWriting(self):
  114. s = b"Hello, world."
  115. self.term.write(s)
  116. self.assertEqual(
  117. self.term.__bytes__(),
  118. s + b'\n' +
  119. b'\n' * (HEIGHT - 2))
  120. def testOvertype(self):
  121. s = b"hello, world."
  122. self.term.write(s)
  123. self.term.cursorBackward(len(s))
  124. self.term.resetModes([modes.IRM])
  125. self.term.write(b"H")
  126. self.assertEqual(
  127. self.term.__bytes__(),
  128. (b"H" + s[1:]) + b'\n' +
  129. b'\n' * (HEIGHT - 2))
  130. def testInsert(self):
  131. s = b"ello, world."
  132. self.term.write(s)
  133. self.term.cursorBackward(len(s))
  134. self.term.setModes([modes.IRM])
  135. self.term.write(b"H")
  136. self.assertEqual(
  137. self.term.__bytes__(),
  138. (b"H" + s) + b'\n' +
  139. b'\n' * (HEIGHT - 2))
  140. def testWritingInTheMiddle(self):
  141. s = b"Hello, world."
  142. self.term.cursorDown(5)
  143. self.term.cursorForward(5)
  144. self.term.write(s)
  145. self.assertEqual(
  146. self.term.__bytes__(),
  147. b'\n' * 5 +
  148. (self.term.fill * 5) + s + b'\n' +
  149. b'\n' * (HEIGHT - 7))
  150. def testWritingWrappedAtEndOfLine(self):
  151. s = b"Hello, world."
  152. self.term.cursorForward(WIDTH - 5)
  153. self.term.write(s)
  154. self.assertEqual(
  155. self.term.__bytes__(),
  156. s[:5].rjust(WIDTH) + b'\n' +
  157. s[5:] + b'\n' +
  158. b'\n' * (HEIGHT - 3))
  159. def testIndex(self):
  160. self.term.index()
  161. self.assertEqual(self.term.reportCursorPosition(), (0, 1))
  162. self.term.cursorDown(HEIGHT)
  163. self.assertEqual(self.term.reportCursorPosition(), (0, HEIGHT - 1))
  164. self.term.index()
  165. self.assertEqual(self.term.reportCursorPosition(), (0, HEIGHT - 1))
  166. def testReverseIndex(self):
  167. self.term.reverseIndex()
  168. self.assertEqual(self.term.reportCursorPosition(), (0, 0))
  169. self.term.cursorDown(2)
  170. self.assertEqual(self.term.reportCursorPosition(), (0, 2))
  171. self.term.reverseIndex()
  172. self.assertEqual(self.term.reportCursorPosition(), (0, 1))
  173. def test_nextLine(self):
  174. """
  175. C{nextLine} positions the cursor at the beginning of the row below the
  176. current row.
  177. """
  178. self.term.nextLine()
  179. self.assertEqual(self.term.reportCursorPosition(), (0, 1))
  180. self.term.cursorForward(5)
  181. self.assertEqual(self.term.reportCursorPosition(), (5, 1))
  182. self.term.nextLine()
  183. self.assertEqual(self.term.reportCursorPosition(), (0, 2))
  184. def testSaveCursor(self):
  185. self.term.cursorDown(5)
  186. self.term.cursorForward(7)
  187. self.assertEqual(self.term.reportCursorPosition(), (7, 5))
  188. self.term.saveCursor()
  189. self.term.cursorDown(7)
  190. self.term.cursorBackward(3)
  191. self.assertEqual(self.term.reportCursorPosition(), (4, 12))
  192. self.term.restoreCursor()
  193. self.assertEqual(self.term.reportCursorPosition(), (7, 5))
  194. def testSingleShifts(self):
  195. self.term.singleShift2()
  196. self.term.write(b'Hi')
  197. ch = self.term.getCharacter(0, 0)
  198. self.assertEqual(ch[0], b'H')
  199. self.assertEqual(ch[1].charset, G2)
  200. ch = self.term.getCharacter(1, 0)
  201. self.assertEqual(ch[0], b'i')
  202. self.assertEqual(ch[1].charset, G0)
  203. self.term.singleShift3()
  204. self.term.write(b'!!')
  205. ch = self.term.getCharacter(2, 0)
  206. self.assertEqual(ch[0], b'!')
  207. self.assertEqual(ch[1].charset, G3)
  208. ch = self.term.getCharacter(3, 0)
  209. self.assertEqual(ch[0], b'!')
  210. self.assertEqual(ch[1].charset, G0)
  211. def testShifting(self):
  212. s1 = b"Hello"
  213. s2 = b"World"
  214. s3 = b"Bye!"
  215. self.term.write(b"Hello\n")
  216. self.term.shiftOut()
  217. self.term.write(b"World\n")
  218. self.term.shiftIn()
  219. self.term.write(b"Bye!\n")
  220. g = G0
  221. h = 0
  222. for s in (s1, s2, s3):
  223. for i in range(len(s)):
  224. ch = self.term.getCharacter(i, h)
  225. self.assertEqual(ch[0], s[i:i+1])
  226. self.assertEqual(ch[1].charset, g)
  227. g = g == G0 and G1 or G0
  228. h += 1
  229. def testGraphicRendition(self):
  230. self.term.selectGraphicRendition(BOLD, UNDERLINE, BLINK, REVERSE_VIDEO)
  231. self.term.write(b'W')
  232. self.term.selectGraphicRendition(NORMAL)
  233. self.term.write(b'X')
  234. self.term.selectGraphicRendition(BLINK)
  235. self.term.write(b'Y')
  236. self.term.selectGraphicRendition(BOLD)
  237. self.term.write(b'Z')
  238. ch = self.term.getCharacter(0, 0)
  239. self.assertEqual(ch[0], b'W')
  240. self.assertTrue(ch[1].bold)
  241. self.assertTrue(ch[1].underline)
  242. self.assertTrue(ch[1].blink)
  243. self.assertTrue(ch[1].reverseVideo)
  244. ch = self.term.getCharacter(1, 0)
  245. self.assertEqual(ch[0], b'X')
  246. self.assertFalse(ch[1].bold)
  247. self.assertFalse(ch[1].underline)
  248. self.assertFalse(ch[1].blink)
  249. self.assertFalse(ch[1].reverseVideo)
  250. ch = self.term.getCharacter(2, 0)
  251. self.assertEqual(ch[0], b'Y')
  252. self.assertTrue(ch[1].blink)
  253. self.assertFalse(ch[1].bold)
  254. self.assertFalse(ch[1].underline)
  255. self.assertFalse(ch[1].reverseVideo)
  256. ch = self.term.getCharacter(3, 0)
  257. self.assertEqual(ch[0], b'Z')
  258. self.assertTrue(ch[1].blink)
  259. self.assertTrue(ch[1].bold)
  260. self.assertFalse(ch[1].underline)
  261. self.assertFalse(ch[1].reverseVideo)
  262. def testColorAttributes(self):
  263. s1 = b"Merry xmas"
  264. s2 = b"Just kidding"
  265. self.term.selectGraphicRendition(helper.FOREGROUND + helper.RED,
  266. helper.BACKGROUND + helper.GREEN)
  267. self.term.write(s1 + b"\n")
  268. self.term.selectGraphicRendition(NORMAL)
  269. self.term.write(s2 + b"\n")
  270. for i in range(len(s1)):
  271. ch = self.term.getCharacter(i, 0)
  272. self.assertEqual(ch[0], s1[i:i+1])
  273. self.assertEqual(ch[1].charset, G0)
  274. self.assertFalse(ch[1].bold)
  275. self.assertFalse(ch[1].underline)
  276. self.assertFalse(ch[1].blink)
  277. self.assertFalse(ch[1].reverseVideo)
  278. self.assertEqual(ch[1].foreground, helper.RED)
  279. self.assertEqual(ch[1].background, helper.GREEN)
  280. for i in range(len(s2)):
  281. ch = self.term.getCharacter(i, 1)
  282. self.assertEqual(ch[0], s2[i:i+1])
  283. self.assertEqual(ch[1].charset, G0)
  284. self.assertFalse(ch[1].bold)
  285. self.assertFalse(ch[1].underline)
  286. self.assertFalse(ch[1].blink)
  287. self.assertFalse(ch[1].reverseVideo)
  288. self.assertEqual(ch[1].foreground, helper.WHITE)
  289. self.assertEqual(ch[1].background, helper.BLACK)
  290. def testEraseLine(self):
  291. s1 = b'line 1'
  292. s2 = b'line 2'
  293. s3 = b'line 3'
  294. self.term.write(b'\n'.join((s1, s2, s3)) + b'\n')
  295. self.term.cursorPosition(1, 1)
  296. self.term.eraseLine()
  297. self.assertEqual(
  298. self.term.__bytes__(),
  299. s1 + b'\n' +
  300. b'\n' +
  301. s3 + b'\n' +
  302. b'\n' * (HEIGHT - 4))
  303. def testEraseToLineEnd(self):
  304. s = b'Hello, world.'
  305. self.term.write(s)
  306. self.term.cursorBackward(5)
  307. self.term.eraseToLineEnd()
  308. self.assertEqual(
  309. self.term.__bytes__(),
  310. s[:-5] + b'\n' +
  311. b'\n' * (HEIGHT - 2))
  312. def testEraseToLineBeginning(self):
  313. s = b'Hello, world.'
  314. self.term.write(s)
  315. self.term.cursorBackward(5)
  316. self.term.eraseToLineBeginning()
  317. self.assertEqual(
  318. self.term.__bytes__(),
  319. s[-4:].rjust(len(s)) + b'\n' +
  320. b'\n' * (HEIGHT - 2))
  321. def testEraseDisplay(self):
  322. self.term.write(b'Hello world\n')
  323. self.term.write(b'Goodbye world\n')
  324. self.term.eraseDisplay()
  325. self.assertEqual(
  326. self.term.__bytes__(),
  327. b'\n' * (HEIGHT - 1))
  328. def testEraseToDisplayEnd(self):
  329. s1 = b"Hello world"
  330. s2 = b"Goodbye world"
  331. self.term.write(b'\n'.join((s1, s2, b'')))
  332. self.term.cursorPosition(5, 1)
  333. self.term.eraseToDisplayEnd()
  334. self.assertEqual(
  335. self.term.__bytes__(),
  336. s1 + b'\n' +
  337. s2[:5] + b'\n' +
  338. b'\n' * (HEIGHT - 3))
  339. def testEraseToDisplayBeginning(self):
  340. s1 = b"Hello world"
  341. s2 = b"Goodbye world"
  342. self.term.write(b'\n'.join((s1, s2)))
  343. self.term.cursorPosition(5, 1)
  344. self.term.eraseToDisplayBeginning()
  345. self.assertEqual(
  346. self.term.__bytes__(),
  347. b'\n' +
  348. s2[6:].rjust(len(s2)) + b'\n' +
  349. b'\n' * (HEIGHT - 3))
  350. def testLineInsertion(self):
  351. s1 = b"Hello world"
  352. s2 = b"Goodbye world"
  353. self.term.write(b'\n'.join((s1, s2)))
  354. self.term.cursorPosition(7, 1)
  355. self.term.insertLine()
  356. self.assertEqual(
  357. self.term.__bytes__(),
  358. s1 + b'\n' +
  359. b'\n' +
  360. s2 + b'\n' +
  361. b'\n' * (HEIGHT - 4))
  362. def testLineDeletion(self):
  363. s1 = b"Hello world"
  364. s2 = b"Middle words"
  365. s3 = b"Goodbye world"
  366. self.term.write(b'\n'.join((s1, s2, s3)))
  367. self.term.cursorPosition(9, 1)
  368. self.term.deleteLine()
  369. self.assertEqual(
  370. self.term.__bytes__(),
  371. s1 + b'\n' +
  372. s3 + b'\n' +
  373. b'\n' * (HEIGHT - 3))
  374. class FakeDelayedCall:
  375. called = False
  376. cancelled = False
  377. def __init__(self, fs, timeout, f, a, kw):
  378. self.fs = fs
  379. self.timeout = timeout
  380. self.f = f
  381. self.a = a
  382. self.kw = kw
  383. def active(self):
  384. return not (self.cancelled or self.called)
  385. def cancel(self):
  386. self.cancelled = True
  387. # self.fs.calls.remove(self)
  388. def call(self):
  389. self.called = True
  390. self.f(*self.a, **self.kw)
  391. class FakeScheduler:
  392. def __init__(self):
  393. self.calls = []
  394. def callLater(self, timeout, f, *a, **kw):
  395. self.calls.append(FakeDelayedCall(self, timeout, f, a, kw))
  396. return self.calls[-1]
  397. class ExpectTests(unittest.TestCase):
  398. def setUp(self):
  399. self.term = helper.ExpectableBuffer()
  400. self.term.connectionMade()
  401. self.fs = FakeScheduler()
  402. def testSimpleString(self):
  403. result = []
  404. d = self.term.expect(b"hello world", timeout=1, scheduler=self.fs)
  405. d.addCallback(result.append)
  406. self.term.write(b"greeting puny earthlings\n")
  407. self.assertFalse(result)
  408. self.term.write(b"hello world\n")
  409. self.assertTrue(result)
  410. self.assertEqual(result[0].group(), b"hello world")
  411. self.assertEqual(len(self.fs.calls), 1)
  412. self.assertFalse(self.fs.calls[0].active())
  413. def testBrokenUpString(self):
  414. result = []
  415. d = self.term.expect(b"hello world")
  416. d.addCallback(result.append)
  417. self.assertFalse(result)
  418. self.term.write(b"hello ")
  419. self.assertFalse(result)
  420. self.term.write(b"worl")
  421. self.assertFalse(result)
  422. self.term.write(b"d")
  423. self.assertTrue(result)
  424. self.assertEqual(result[0].group(), b"hello world")
  425. def testMultiple(self):
  426. result = []
  427. d1 = self.term.expect(b"hello ")
  428. d1.addCallback(result.append)
  429. d2 = self.term.expect(b"world")
  430. d2.addCallback(result.append)
  431. self.assertFalse(result)
  432. self.term.write(b"hello")
  433. self.assertFalse(result)
  434. self.term.write(b" ")
  435. self.assertEqual(len(result), 1)
  436. self.term.write(b"world")
  437. self.assertEqual(len(result), 2)
  438. self.assertEqual(result[0].group(), b"hello ")
  439. self.assertEqual(result[1].group(), b"world")
  440. def testSynchronous(self):
  441. self.term.write(b"hello world")
  442. result = []
  443. d = self.term.expect(b"hello world")
  444. d.addCallback(result.append)
  445. self.assertTrue(result)
  446. self.assertEqual(result[0].group(), b"hello world")
  447. def testMultipleSynchronous(self):
  448. self.term.write(b"goodbye world")
  449. result = []
  450. d1 = self.term.expect(b"bye")
  451. d1.addCallback(result.append)
  452. d2 = self.term.expect(b"world")
  453. d2.addCallback(result.append)
  454. self.assertEqual(len(result), 2)
  455. self.assertEqual(result[0].group(), b"bye")
  456. self.assertEqual(result[1].group(), b"world")
  457. def _cbTestTimeoutFailure(self, res):
  458. self.assertTrue(hasattr(res, 'type'))
  459. self.assertEqual(res.type, helper.ExpectationTimeout)
  460. def testTimeoutFailure(self):
  461. d = self.term.expect(b"hello world", timeout=1, scheduler=self.fs)
  462. d.addBoth(self._cbTestTimeoutFailure)
  463. self.fs.calls[0].call()
  464. def testOverlappingTimeout(self):
  465. self.term.write(b"not zoomtastic")
  466. result = []
  467. d1 = self.term.expect(b"hello world", timeout=1, scheduler=self.fs)
  468. d1.addBoth(self._cbTestTimeoutFailure)
  469. d2 = self.term.expect(b"zoom")
  470. d2.addCallback(result.append)
  471. self.fs.calls[0].call()
  472. self.assertEqual(len(result), 1)
  473. self.assertEqual(result[0].group(), b"zoom")
  474. class CharacterAttributeTests(unittest.TestCase):
  475. """
  476. Tests for L{twisted.conch.insults.helper.CharacterAttribute}.
  477. """
  478. def test_equality(self):
  479. """
  480. L{CharacterAttribute}s must have matching character attribute values
  481. (bold, blink, underline, etc) with the same values to be considered
  482. equal.
  483. """
  484. self.assertEqual(
  485. helper.CharacterAttribute(),
  486. helper.CharacterAttribute())
  487. self.assertEqual(
  488. helper.CharacterAttribute(),
  489. helper.CharacterAttribute(charset=G0))
  490. self.assertEqual(
  491. helper.CharacterAttribute(
  492. bold=True, underline=True, blink=False, reverseVideo=True,
  493. foreground=helper.BLUE),
  494. helper.CharacterAttribute(
  495. bold=True, underline=True, blink=False, reverseVideo=True,
  496. foreground=helper.BLUE))
  497. self.assertNotEqual(
  498. helper.CharacterAttribute(),
  499. helper.CharacterAttribute(charset=G1))
  500. self.assertNotEqual(
  501. helper.CharacterAttribute(bold=True),
  502. helper.CharacterAttribute(bold=False))
  503. def test_wantOneDeprecated(self):
  504. """
  505. L{twisted.conch.insults.helper.CharacterAttribute.wantOne} emits
  506. a deprecation warning when invoked.
  507. """
  508. # Trigger the deprecation warning.
  509. helper._FormattingState().wantOne(bold=True)
  510. warningsShown = self.flushWarnings([self.test_wantOneDeprecated])
  511. self.assertEqual(len(warningsShown), 1)
  512. self.assertEqual(warningsShown[0]['category'], DeprecationWarning)
  513. if _PY3:
  514. deprecatedClass = (
  515. "twisted.conch.insults.helper._FormattingState.wantOne")
  516. else:
  517. deprecatedClass = "twisted.conch.insults.helper.wantOne"
  518. self.assertEqual(
  519. warningsShown[0]['message'],
  520. '%s was deprecated in Twisted 13.1.0' % (deprecatedClass))