SwiftTermTests.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. import XCTest
  2. @testable import SwiftTerm
  3. final class SwiftTermTests: XCTestCase {
  4. static var queue: DispatchQueue!
  5. class override func setUp() {
  6. queue = DispatchQueue(label: "Runner", qos: .userInteractive, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
  7. if !FileManager.default.fileExists(atPath: esctest) {
  8. esctest = "/Users/miguel/cvs/esctest/esctest/esctest.py"
  9. }
  10. // Ignore SIGCHLD
  11. signal (SIGCHLD, SIG_IGN)
  12. }
  13. static var esctest = "esctest/esctest/esctest.py"
  14. var termConfig = "--expected-terminal xterm --xterm-checksum=334"
  15. var logfile = NSTemporaryDirectory() + "log"
  16. func runTester (_ includeRegexp: String) -> String?
  17. {
  18. let psem = DispatchSemaphore(value: 0)
  19. let t = HeadlessTerminal (queue: SwiftTermTests.queue) { exitCode in
  20. Thread.sleep(forTimeInterval: 1)
  21. psem.signal ()
  22. }
  23. let python27 = "/Users/miguel/bin/python2.7"
  24. var args: [String] = ["--expected-terminal", "xterm", "--xterm-checksum=334", "--logfile", logfile]
  25. args += ["--include=\(includeRegexp)"]
  26. do {
  27. if FileManager.default.fileExists (atPath: logfile) {
  28. try FileManager.default.removeItem(atPath: logfile)
  29. }
  30. } catch {
  31. // Ignore
  32. }
  33. print ("Starting \(SwiftTermTests.esctest) with \(args)")
  34. args.insert(SwiftTermTests.esctest, at: 0)
  35. t.process.startProcess(executable: python27, args: args, environment: nil)
  36. psem.wait ()
  37. print ("Does the file exist? \(FileManager.default.fileExists (atPath: logfile))")
  38. do {
  39. let log = try String(contentsOf: URL(fileURLWithPath: logfile), encoding: .isoLatin1)
  40. if log.contains("0 tests failed ***") {
  41. return nil
  42. }
  43. if log.contains ("FAILED ***") {
  44. return log
  45. }
  46. } catch {
  47. return "Exception while loading \(logfile) \(error)"
  48. }
  49. return "Should have found test marker"
  50. }
  51. func testKnownGood() {
  52. let good = [
  53. "BS", "CAT", "CHA", "CHT", "CNL", "CPL", "CR", "CUB", "CUD", "CUF", "CUP", "CUU",
  54. "DCH", "DCS", "DECBI", "DECDC", "DECDSR", "DECERA", "DECFRA", "DECIC", "DECSTBM", "DECSTR", "DL",
  55. "FF", "HPR", "HTS", "HVP", "ICH", "IL", "LF",
  56. "PM", "REP", "ResetColor", "RM", "SD", "SM", "SOS", "SU", "TBC", "VPR", "VT",
  57. // These are partial successes, with known bugs, but let us not regress the ones that pass
  58. // DECALN, 2 pass, 2 fail
  59. "DECALN_FillsScreen", "DECALN_MovesCursorHome",
  60. // Failing:
  61. // test_DECALN_ClearsMargin
  62. // DECRQM, 19 pass
  63. "DECRQM_ANSI_FETM", "DECRQM_ANSI_GATM", "DECRQM_ANSI_HEM", "DECRQM_ANSI_IRM", "DECRQM_ANSI_LNM",
  64. "DECRQM_ANSI_MATM", "DECRQM_ANSI_PUM", "DECRQM_ANSI_SATM", "DECRQM_ANSI_SRTM", "DECRQM_ANSI_TSM",
  65. "DECRQM_ANSI_TTM", "DECRQM_ANSI_VEM", "DECRQM_DEC_DECAWM", "DECRQM_DEC_DECCKM", "DECRQM_DEC_DECCOLM",
  66. "DECRQM_DEC_DECLRMM", "DECRQM_DEC_DECNKM", "DECRQM_DEC_DECOM", "DECRQM_DEC_DECSCNM",
  67. "DECRQM_DEC_DECSCLM",
  68. // This test probes modes, and some of these modes fail due to the difference between
  69. // a value configured, versus a hardwired value, so they are mostly fine, but worth
  70. // submiting patches or just accepting defeat and changing the default
  71. // those that return 0 are definitly not handled
  72. // * DECRQM_ANSI_KAM expected 2,1 got 2,2
  73. // DECRQM_DEC_DECAAM 100,2 got 100,0
  74. // DECRQM_DEC_DECARM, 8, 2, got 8,1
  75. // DECRQM_DEC_DECARSM 98,2, got 98,0
  76. // * DECRQM_DEC_DECBKM, 67,2 got 67,4
  77. // DECRQM_DEC_DECCANSM 101,2 got 101,0
  78. // DECRQM_DEC_DECCRTSM 97,2 got 97,0
  79. // DECRQM_DEC_DECESKM 104,2 got 104,0
  80. // DECRQM_DEC_DECHCCM 60,4 got 60,0
  81. // DECRQM_DEC_DECHDPXM 103,2 got 103,0
  82. // * DECRQM_DEC_DECHEBM 35,2 got 35,0
  83. // DECRQM_DEC_DECHEM 36,2 got 36,0
  84. // DECRQM_DEC_DECKBUM 68,2 got 68,0
  85. // DECRQM_DEC_DECKPM 81,2 got 81,0
  86. // DECRQM_DEC_DECMCM 99,2, got 99,0
  87. // DECRQM_DEC_DECNAKB 57,2 got 57,0
  88. // * DECRQM_DEC_DECNRCM 42,2 got 42,4
  89. // DECRQM_DEC_DECNULM 102,2, got 102,0
  90. // DECRQM_DEC_DECOSCNM 106,2 got 106,0
  91. // DECRQM_DEC_DECPCCM 64,2 got 64,0
  92. // DECRQM_DEC_DECRLCM 96,2 got 96,0
  93. // DECRQM_DEC_DECRLM 34,2 got 34, 0
  94. // DECRQM_DEC_DECSCLM 4,2 got 4,4
  95. // DECRQM_DEC_DECVCCM 61,2 got 61,0
  96. // DECRQM_DEC_DECXRLM 73,2 got 73,0
  97. // DECRQM_ANSI_SRM, 12,2 got 12,1 (needs to track state)
  98. // DECRQM_DEC_DECNCSM, 95,2 got 95,1 (needs to track state)
  99. // DECRQM_DEC_DECPEX, needs to track state)
  100. // DECRQM_DEC_DECPFF, needs to track state)
  101. // DECCRA, 8 pass, 2 fail
  102. "DECCRA_cursorDoesNotMove", "DECCRA_defaultValuesInDest", "DECCRA_defaultValuesInSource",
  103. "DECCRA_destinationPartiallyOffscreen", "DECCRA_ignoresMargins", "DECCRA_invalidSourceRectDoesNothing",
  104. "DECCRA_nonOverlappingSourceAndDest", "DECCRA_overlappingSourceAndDest",
  105. // Failing:
  106. // test_DECCRA_overlyLargeSourceClippedToScreenSize
  107. // test_DECCRA_respectsOriginMode
  108. // DECFI, 4 pass, 1 fail
  109. "DECFI_NoWrapOnRightEdge",
  110. "DECFI_Basic",
  111. "DECFI_RightOfMargin",
  112. "DECFI_Scroll",
  113. // Failing:
  114. // test_DECFI_WholeScreenScroll
  115. // DECRQSS, 4 pass, 2 fail
  116. "DECRQSS_SGR",
  117. "DECRQSS_DECSTBM",
  118. "DECRQSS_DECSLRM",
  119. "DECRQSS_DECSCL",
  120. // Failing:
  121. // test_DECRQSS_DECSC
  122. // test_DECRQSS_DECSCUS
  123. // DECSET, 14 pass, 9 fail
  124. "DECSET_ALTBUF",
  125. "DECSET_DECAWM_NoLineWrapOnTabWithLeftRightMargin",
  126. "DECSET_DECAWM_OnRespectsLeftRightMargin",
  127. "DECSET_DECAWM_TabDoesNotWrapAround",
  128. "DECSET_DECCOLM",
  129. "DECSET_DECLRMM",
  130. "DECSET_DECLRMM_MarginsResetByDECSTR",
  131. "DECSET_DECLRMM_ModeNotResetByDECSTR",
  132. "DECSET_DECOM_DECRQCRA",
  133. "DECSET_DECOM_SoftReset",
  134. // "DECSET_OPT_ALTBUF", ALBUF works, but not ALTBUF_CURSOR
  135. "DECSET_ResetReverseWraparoundDisablesIt",
  136. "DECSET_ReverseWraparound_BS",
  137. "DECSET_SaveRestoreCursor",
  138. "DECSET_Allow80To132",
  139. // Failing:
  140. // test_DECSET_Allow80To132
  141. // test_DECSET_DECAWM_CursorAtRightMargin
  142. // test_DECSET_DECAWM_OffRespectsLeftRightMargin
  143. // test_DECSET_DECOM
  144. // test_DECSET_MoreFix
  145. // test_DECSET_OPT_ALTBUF_CURSOR
  146. // test_DECSET_ReverseWraparoundLastCol_BS
  147. // test_DECSET_ReverseWraparound_Multi
  148. // test_DECSET_ReverseWraparound_RequiresDECAWM
  149. // ECH, 4 pass, 2 failures
  150. "ECH_DefaultParam",
  151. "ECH_ExplicitParam",
  152. "ECH_IgnoresScrollRegion",
  153. "ECH_OutsideScrollRegion",
  154. // Failing:
  155. // test_ECH_doesNotRespectDECPRotection
  156. // test_ECH_respectsISOProtection
  157. // EL 6 pass, 1 failure
  158. "EL_0",
  159. "EL_1",
  160. "EL_2",
  161. "EL_Default",
  162. "EL_IgnoresScrollRegion",
  163. "EL_doesNotRespectDECProtection",
  164. // Failing:
  165. // test_EL_respectsISOProtection
  166. // HPA 3 pass, 1 fails
  167. "HPA_DefaultParams",
  168. "HPA_DoesNotChangeRow",
  169. "HPA_StopsAtRightEdge",
  170. // Failing:
  171. // test_HPA_IgnoresOriginMode - this is a problem with the mouse reporting, and not the actual position
  172. // IND 4 pass, 2 fail
  173. "IND_Basic",
  174. "IND_Scrolls",
  175. "IND_ScrollsInTopBottomRegionStartingAbove",
  176. "IND_ScrollsInTopBottomRegionStartingWithin",
  177. // Failing:
  178. // test_IND_MovesDoesNotScrollOutsideLeftRight
  179. // test_IND_StopsAtBottomLineWhenBegunBelowScrollRegion
  180. // NEL 4 pass, 2 fail
  181. "NEL_Basic",
  182. "NEL_Scrolls",
  183. "NEL_ScrollsInTopBottomRegionStartingAbove",
  184. "NEL_ScrollsInTopBottomRegionStartingWithin",
  185. // Failing: these are linked to the two previous IND failures
  186. // test_NEL_MovesDoesNotScrollOutsideLeftRight
  187. // test_NEL_StopsAtBottomLineWhenBegunBelowScrollRegion
  188. // ResetColor
  189. // RI 5 pass, 1 fail
  190. "RI_Basic",
  191. "RI_Scrolls",
  192. "RI_ScrollsInTopBottomRegionStartingBelow",
  193. "RI_ScrollsInTopBottomRegionStartingWithin",
  194. "RI_StopsAtTopLineWhenBegunAboveScrollRegion",
  195. // Failing:
  196. // test_RI_MovesDoesNotScrollOutsideLeftRight
  197. // RIS 6 pass, 1 expected
  198. "RIS_ClearsScreen",
  199. "RIS_CursorToOrigin",
  200. "RIS_RemoveMargins",
  201. "RIS_ResetDECOM",
  202. "RIS_ResetTabs",
  203. "RIS_ResetTitleMode",
  204. "RIS_ExitAltScreen",
  205. // Expected: this is because this assumes that if we are at 132 columns a reset (RIS) should
  206. // switch to 80 and that is just not the case for this terminal emultaor.
  207. // test_RIS_ResetDECCOLM
  208. // s8c1t?
  209. // VPA 3 pass, 1 fail
  210. "VPA_DefaultParams",
  211. "VPA_DoesNotChangeColumn",
  212. "VPA_StopsAtBottomEdge",
  213. // Failing:
  214. // test_VPA_IgnoresOriginMode
  215. // ChangeColor 4 pass, 9 fail
  216. "ChangeColor_Hash3",
  217. "ChangeColor_Hash6",
  218. "ChangeColor_Hash9",
  219. "ChangeColor_RGB$",
  220. "ChangeColor_Multiple",
  221. // Failing:
  222. // ChangeColor_Hash12 - I disagree with this test, it passes 16 bit 0xf000 red and expects back 0xf0f0
  223. //
  224. // These are additional color spaces, RGBI looks
  225. // ChangeColor_RGBI
  226. // ChangeColor_CIELab
  227. // ChangeColor_CIELuv
  228. // ChangeColor_CIEXYZ
  229. // ChangeColor_CIEuvY
  230. // ChangeColor_CIExyY
  231. // ChangeColor_TekHVC
  232. "ChangeDynamicColor_Multiple",
  233. "ChangeDynamicColor_RGB$",
  234. "ChangeDynamicColor_Hash3",
  235. "ChangeDynamicColor_Hash6",
  236. "ChangeDynamicColor_Hash9",
  237. // Failing:
  238. // ChangeDynamicColor_CIELab
  239. // ChangeDynamicColor_CIELuv
  240. // ChangeDynamicColor_CIEXYZ
  241. // ChangeDynamicColor_CIEuvY
  242. // ChangeDynamicColor_CIExyY
  243. // ChangeDynamicColor_Hash12
  244. // ChangeDynamicColor_RGBI
  245. // ChangeDynamicColor_TekHVC
  246. ]
  247. let expr = "test_(\(good.joined(separator: "|")))"
  248. XCTAssertNil(runTester (expr))
  249. }
  250. // Use this test to run a single test
  251. func testSingle ()
  252. {
  253. XCTAssertNil(runTester ("test_ChangeColor_Hash3"))
  254. }
  255. func xtestFailuresOnHeadless ()
  256. {
  257. XCTAssertNil(runTester ("test_DECCRA"))
  258. XCTAssertNil(runTester ("test_HPA"))
  259. }
  260. static var allTests = [
  261. ("testKnownGood", testKnownGood),
  262. //("testMarkerMissing", testFailuresOnHeadless),
  263. ]
  264. }