EscposTest.php 32KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. <?php
  2. use Mike42\Escpos\Printer;
  3. use Mike42\Escpos\PrintConnectors\DummyPrintConnector;
  4. use Mike42\Escpos\EscposImage;
  5. use Mike42\Escpos\CapabilityProfile;
  6. class EscposTest extends PHPUnit\Framework\TestCase
  7. {
  8. protected $printer;
  9. protected $outputConnector;
  10. protected function setup()
  11. {
  12. /* Print to nowhere- for testing which inputs are accepted */
  13. $this -> outputConnector = new DummyPrintConnector();
  14. $this -> printer = new Printer($this -> outputConnector);
  15. }
  16. protected function checkOutput($expected = null)
  17. {
  18. /* Check those output strings */
  19. $outp = $this -> outputConnector -> getData();
  20. if ($expected === null) {
  21. echo "\nOutput was:\n\"" . friendlyBinary($outp) . "\"\n";
  22. }
  23. $this -> assertEquals($expected, $outp);
  24. }
  25. protected function tearDown()
  26. {
  27. $this -> outputConnector -> finalize();
  28. }
  29. protected function requireGraphicsLibrary()
  30. {
  31. if (!EscposImage::isGdLoaded() && !EscposImage::isImagickLoaded()) {
  32. // If the test is about to do something which requires a library,
  33. // something must throw an exception.
  34. $this -> expectException(Exception::class);
  35. }
  36. }
  37. public function testInitializeOutput()
  38. {
  39. $this -> checkOutput("\x1b\x40");
  40. }
  41. public function testTextStringOutput()
  42. {
  43. $this -> printer -> text("The quick brown fox jumps over the lazy dog\n");
  44. $this -> checkOutput("\x1b@The quick brown fox jumps over the lazy dog\n");
  45. }
  46. public function testTextChinese()
  47. {
  48. // Switch to chinese print mode, GBK output, switch back to alphanumeric.
  49. $this -> printer -> textChinese("示例文本打印机!\n");
  50. $this -> checkOutput("\x1b@\x1c&\xca\xbe\xc0\xfd\xce\xc4\xb1\xbe\xb4\xf2\xd3\xa1\xbb\xfa!\x0a\x1c.");
  51. }
  52. public function testTextRaw()
  53. {
  54. // Under raw output, the raw bytes are sent to the printer, so typing a UTF-8 euro literally causes \xE2 \x82 \xAC to be sent.
  55. // Under text(), this would cause a code-page change (to a page that contains a Euro symbol), and single byte.
  56. $this -> printer -> textRaw("€\n");
  57. $this -> checkOutput("\x1b@\xe2\x82\xac\x0a");
  58. }
  59. public function testTextString()
  60. {
  61. $this -> printer -> text("String");
  62. $this -> printer -> text(123);
  63. $this -> printer -> text(1.2);
  64. $this -> checkOutput("\x1b@String1231.2");
  65. }
  66. public function testFeedDefault()
  67. {
  68. $this -> printer -> feed();
  69. $this -> checkOutput("\x1b@\x0a");
  70. }
  71. public function testFeed3Lines()
  72. {
  73. $this -> printer -> feed(3);
  74. $this -> checkOutput("\x1b@\x1bd\x03");
  75. }
  76. public function testFeedZero()
  77. {
  78. $this -> expectException(InvalidArgumentException::class);
  79. $this -> printer -> feed(0);
  80. }
  81. public function testFeedTooLarge()
  82. {
  83. $this -> expectException(InvalidArgumentException::class);
  84. $this -> printer -> feed(256);
  85. }
  86. /* Print mode */
  87. public function testSelectPrintModeDefault()
  88. {
  89. $this -> printer -> selectPrintMode();
  90. $this -> checkOutput("\x1b@\x1b!\x00");
  91. }
  92. public function testSelectPrintModeAcceptedValues()
  93. {
  94. /* This iterates over a bunch of numbers, figures out which
  95. ones contain invalid flags, and checks that the driver
  96. rejects those, but accepts the good inputs */
  97. for ($i = -1; $i <= 256; $i++) {
  98. $invalid = ($i < 0) || ($i > 255) || (($i & 2) == 2) || (($i & 4) == 4) || (($i & 64) == 64);
  99. $failed = false;
  100. try {
  101. $this -> printer -> selectPrintMode($i);
  102. } catch (Exception $e) {
  103. $failed = true;
  104. }
  105. $this -> assertEquals($failed, $invalid);
  106. }
  107. }
  108. /* Underline */
  109. public function testSetUnderlineDefault()
  110. {
  111. $this -> printer -> setUnderline();
  112. $this -> checkOutput("\x1b@\x1b-\x01");
  113. }
  114. public function testSetUnderlineOff()
  115. {
  116. $this -> printer -> setUnderline(Printer::UNDERLINE_NONE);
  117. $this -> checkOutput("\x1b@\x1b-\x00");
  118. }
  119. public function testSetUnderlineOn()
  120. {
  121. $this -> printer -> setUnderline(Printer::UNDERLINE_SINGLE);
  122. $this -> checkOutput("\x1b@\x1b-\x01");
  123. }
  124. public function testSetUnderlineDbl()
  125. {
  126. $this -> printer -> setUnderline(Printer::UNDERLINE_DOUBLE);
  127. $this -> checkOutput("\x1b@\x1b-\x02");
  128. }
  129. public function testSetUnderlineAcceptedValues()
  130. {
  131. $this -> printer -> setUnderline(0);
  132. $this -> printer -> setUnderline(1);
  133. $this -> printer -> setUnderline(2);
  134. /* These map to 0 & 1 for interchangeability with setEmphasis */
  135. $this -> printer -> setUnderline(true);
  136. $this -> printer -> setUnderline(false);
  137. $this -> checkOutput("\x1b@\x1b-\x00\x1b-\x01\x1b-\x02\x1b-\x01\x1b-\x00");
  138. }
  139. public function testSetUnderlineTooLarge()
  140. {
  141. $this -> expectException(InvalidArgumentException::class);
  142. $this -> printer -> setUnderline(3);
  143. }
  144. public function testSetUnderlineNegative()
  145. {
  146. $this -> expectException(InvalidArgumentException::class);
  147. $this -> printer -> setUnderline(-1);
  148. }
  149. /* Emphasis */
  150. public function testSetEmphasisDefault()
  151. {
  152. $this -> printer -> setEmphasis();
  153. $this -> checkOutput("\x1b@\x1bE\x01");
  154. }
  155. public function testSetEmphasisOn()
  156. {
  157. $this -> printer -> setEmphasis(true);
  158. $this -> checkOutput("\x1b@\x1bE\x01");
  159. }
  160. public function testSetEmphasisOff()
  161. {
  162. $this -> printer -> setEmphasis(false);
  163. $this -> checkOutput("\x1b@\x1bE\x00");
  164. }
  165. /* Double strike */
  166. public function testSetDoubleStrikeDefault()
  167. {
  168. $this -> printer -> setDoubleStrike();
  169. $this -> checkOutput("\x1b@\x1bG\x01");
  170. }
  171. public function testSetDoubleStrikeOn()
  172. {
  173. $this -> printer -> setDoubleStrike(true);
  174. $this -> checkOutput("\x1b@\x1bG\x01");
  175. }
  176. public function testSetDoubleStrikeOff()
  177. {
  178. $this -> printer -> setDoubleStrike(false);
  179. $this -> checkOutput("\x1b@\x1bG\x00");
  180. }
  181. /* Font */
  182. public function testSetFontDefault()
  183. {
  184. $this -> printer -> setFont();
  185. $this -> checkOutput("\x1b@\x1bM\x00");
  186. }
  187. public function testSetFontAcceptedValues()
  188. {
  189. $this -> printer -> setFont(Printer::FONT_A);
  190. $this -> printer -> setFont(Printer::FONT_B);
  191. $this -> printer -> setFont(Printer::FONT_C);
  192. $this -> checkOutput("\x1b@\x1bM\x00\x1bM\x01\x1bM\x02");
  193. }
  194. public function testSetFontNegative()
  195. {
  196. $this -> expectException(InvalidArgumentException::class);
  197. $this -> printer -> setFont(-1);
  198. }
  199. public function testSetFontTooLarge()
  200. {
  201. $this -> expectException(InvalidArgumentException::class);
  202. $this -> printer -> setFont(3);
  203. }
  204. /* Justification */
  205. public function testSetJustificationDefault()
  206. {
  207. $this -> printer -> setJustification();
  208. $this -> checkOutput("\x1b@\x1ba\x00");
  209. }
  210. public function testSetJustificationLeft()
  211. {
  212. $this -> printer -> setJustification(Printer::JUSTIFY_LEFT);
  213. $this -> checkOutput("\x1b@\x1ba\x00");
  214. }
  215. public function testSetJustificationRight()
  216. {
  217. $this -> printer -> setJustification(Printer::JUSTIFY_RIGHT);
  218. $this -> checkOutput("\x1b@\x1ba\x02");
  219. }
  220. public function testSetJustificationCenter()
  221. {
  222. $this -> printer -> setJustification(Printer::JUSTIFY_CENTER);
  223. $this -> checkOutput("\x1b@\x1ba\x01");
  224. }
  225. public function testSetJustificationNegative()
  226. {
  227. $this -> expectException(InvalidArgumentException::class);
  228. $this -> printer -> setJustification(-1);
  229. }
  230. public function testSetJustificationTooLarge()
  231. {
  232. $this -> expectException(InvalidArgumentException::class);
  233. $this -> printer -> setFont(3);
  234. }
  235. /* Reverse feed */
  236. public function testFeedReverseDefault()
  237. {
  238. $this -> printer -> feedReverse();
  239. $this -> checkOutput("\x1b@\x1be\x01");
  240. }
  241. public function testFeedReverse3()
  242. {
  243. $this -> printer -> feedReverse(3);
  244. $this -> checkOutput("\x1b@\x1be\x03");
  245. }
  246. public function testFeedReverseNegative()
  247. {
  248. $this -> expectException(InvalidArgumentException::class);
  249. $this -> printer -> feedReverse(-1);
  250. }
  251. public function testFeedReverseTooLarge()
  252. {
  253. $this -> expectException(InvalidArgumentException::class);
  254. $this -> printer -> feedReverse(256);
  255. }
  256. /* Cut */
  257. public function testCutDefault()
  258. {
  259. // TODO check what the accepted range of values should be for $line
  260. // cut($mode = self::CUT_FULL, $lines = 3)
  261. $this -> printer -> cut();
  262. $this -> checkOutput("\x1b@\x1dVA\x03");
  263. }
  264. /* Set barcode height */
  265. public function testSetBarcodeHeightDefault()
  266. {
  267. $this -> printer -> setBarcodeHeight();
  268. $this -> checkOutput("\x1b@\x1dh\x08");
  269. }
  270. public function testBarcodeHeight10()
  271. {
  272. $this -> printer -> setBarcodeHeight(10);
  273. $this -> checkOutput("\x1b@\x1dh\x0a");
  274. }
  275. public function testSetBarcodeHeightNegative()
  276. {
  277. $this -> expectException(InvalidArgumentException::class);
  278. $this -> printer -> setBarcodeHeight(-1);
  279. }
  280. public function testSetBarcodeHeightTooLarge()
  281. {
  282. $this -> expectException(InvalidArgumentException::class);
  283. $this -> printer -> setBarcodeHeight(256);
  284. }
  285. /* Set barcode width */
  286. public function testSetBarcodeWidthDefault()
  287. {
  288. $this -> printer -> setBarcodeWidth();
  289. $this -> checkOutput("\x1b@\x1dw\x03");
  290. }
  291. public function testBarcodeWidth1()
  292. {
  293. $this -> printer -> setBarcodeWidth(1);
  294. $this -> checkOutput("\x1b@\x1dw\x01");
  295. }
  296. public function testSetBarcodeWidthNegative()
  297. {
  298. $this -> expectException(InvalidArgumentException::class);
  299. $this -> printer -> setBarcodeWidth(-1);
  300. }
  301. public function testSetBarcodeWidthTooLarge()
  302. {
  303. $this -> expectException(InvalidArgumentException::class);
  304. $this -> printer -> setBarcodeWidth(256);
  305. }
  306. /* Barcode text position */
  307. public function testSetBarcodeTextPositionDefault()
  308. {
  309. $this -> printer -> setBarcodeTextPosition();
  310. $this -> checkOutput("\x1b@\x1dH\x00");
  311. }
  312. public function testSetBarcodeTextPositionBelow()
  313. {
  314. $this -> printer -> setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW);
  315. $this -> checkOutput("\x1b@\x1dH\x02");
  316. }
  317. public function testSetBarcodeTextPositionBoth()
  318. {
  319. $this -> printer -> setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW | Printer::BARCODE_TEXT_ABOVE);
  320. $this -> checkOutput("\x1b@\x1dH\x03");
  321. }
  322. public function testSetBarcodeTextPositionNegative()
  323. {
  324. $this -> expectException(InvalidArgumentException::class);
  325. $this -> printer -> setBarcodeTextPosition(-1);
  326. }
  327. public function testSetBarcodeTextPositionTooLarge()
  328. {
  329. $this -> expectException(InvalidArgumentException::class);
  330. $this -> printer -> setBarcodeTextPosition(4);
  331. }
  332. public function tesSetBarcodeTextPositionNonInteger()
  333. {
  334. $this -> expectException(InvalidArgumentException::class);
  335. $this -> printer -> setBarcodeTextPosition('hello');
  336. }
  337. /* Barcode - UPC-A */
  338. public function testBarcodeUpcaNumeric11Char()
  339. {
  340. $this -> printer -> barcode("01234567890", Printer::BARCODE_UPCA);
  341. $this -> checkOutput("\x1b@\x1dkA\x0b01234567890");
  342. }
  343. public function testBarcodeUpcaNumeric12Char()
  344. {
  345. $this -> printer -> barcode("012345678901", Printer::BARCODE_UPCA);
  346. $this -> checkOutput("\x1b@\x1dkA\x0c012345678901");
  347. }
  348. public function testBarcodeUpcaNumeric13Char()
  349. {
  350. $this -> expectException(InvalidArgumentException::class);
  351. $this -> printer -> barcode("0123456789012", Printer::BARCODE_UPCA);
  352. }
  353. public function testBarcodeUpcaNonNumeric12Char()
  354. {
  355. $this -> expectException(InvalidArgumentException::class);
  356. $this -> printer -> barcode("A12345678901", Printer::BARCODE_UPCA);
  357. }
  358. /* Barcode - UPC-E */
  359. public function testBarcodeUpceNumeric6Char()
  360. {
  361. $this -> printer -> barcode("123456", Printer::BARCODE_UPCE);
  362. $this -> checkOutput("\x1b@\x1dkB\x06123456");
  363. }
  364. public function testBarcodeUpceNumeric7Char()
  365. {
  366. $this -> printer -> barcode("0123456", Printer::BARCODE_UPCE);
  367. $this -> checkOutput("\x1b@\x1dkB\x070123456");
  368. }
  369. public function testBarcodeUpceNumeric8Char()
  370. {
  371. $this -> printer -> barcode("01234567", Printer::BARCODE_UPCE);
  372. $this -> checkOutput("\x1b@\x1dkB\x0801234567");
  373. }
  374. public function testBarcodeUpceNumeric11Char()
  375. {
  376. $this -> printer -> barcode("01234567890", Printer::BARCODE_UPCE);
  377. $this -> checkOutput("\x1b@\x1dkB\x0b01234567890");
  378. }
  379. public function testBarcodeUpceNumeric12Char()
  380. {
  381. $this -> printer -> barcode("012345678901", Printer::BARCODE_UPCE);
  382. $this -> checkOutput("\x1b@\x1dkB\x0c012345678901");
  383. }
  384. public function testBarcodeUpceNumeric9Char()
  385. {
  386. $this -> expectException(InvalidArgumentException::class);
  387. $this -> printer -> barcode("012345678", Printer::BARCODE_UPCE);
  388. }
  389. public function testBarcodeUpceNonNumeric12Char()
  390. {
  391. $this -> expectException(InvalidArgumentException::class);
  392. $this -> printer -> barcode("A12345678901", Printer::BARCODE_UPCE);
  393. }
  394. /* Barcode - JAN13 */
  395. public function testBarcodeJan13Numeric12Char()
  396. {
  397. $this -> printer -> barcode("012345678901", Printer::BARCODE_JAN13);
  398. $this -> checkOutput("\x1b@\x1dkC\x0c012345678901");
  399. }
  400. public function testBarcodeJan13Numeric13Char()
  401. {
  402. $this -> printer -> barcode("0123456789012", Printer::BARCODE_JAN13);
  403. $this -> checkOutput("\x1b@\x1dkC\x0d0123456789012");
  404. }
  405. public function testBarcodeJan13Numeric11Char()
  406. {
  407. $this -> expectException(InvalidArgumentException::class);
  408. $this -> printer -> barcode("01234567890", Printer::BARCODE_JAN13);
  409. }
  410. public function testBarcodeJan13NonNumeric13Char()
  411. {
  412. $this -> expectException(InvalidArgumentException::class);
  413. $this -> printer -> barcode("A123456789012", Printer::BARCODE_JAN13);
  414. }
  415. /* Barcode - JAN8 */
  416. public function testBarcodeJan8Numeric7Char()
  417. {
  418. $this -> printer -> barcode("0123456", Printer::BARCODE_JAN8);
  419. $this -> checkOutput("\x1b@\x1dkD\x070123456");
  420. }
  421. public function testBarcodeJan8Numeric8Char()
  422. {
  423. $this -> printer -> barcode("01234567", Printer::BARCODE_JAN8);
  424. $this -> checkOutput("\x1b@\x1dkD\x0801234567");
  425. }
  426. public function testBarcodeJan8Numeric9Char()
  427. {
  428. $this -> expectException(InvalidArgumentException::class);
  429. $this -> printer -> barcode("012345678", Printer::BARCODE_JAN8);
  430. }
  431. public function testBarcodeJan8NonNumeric8Char()
  432. {
  433. $this -> expectException(InvalidArgumentException::class);
  434. $this -> printer -> barcode("A1234567", Printer::BARCODE_JAN8);
  435. }
  436. /* Barcode - Code39 */
  437. public function testBarcodeCode39AsDefault()
  438. {
  439. $this -> printer -> barcode("1234");
  440. $this -> checkOutput("\x1b@\x1dkE\x041234");
  441. }
  442. public function testBarcodeCode39Text()
  443. {
  444. $this -> printer -> barcode("ABC 012", Printer::BARCODE_CODE39);
  445. $this -> checkOutput("\x1b@\x1dkE\x07ABC 012");
  446. }
  447. public function testBarcodeCode39SpecialChars()
  448. {
  449. $this -> printer -> barcode("$%+-./", Printer::BARCODE_CODE39);
  450. $this -> checkOutput("\x1b@\x1dkE\x06$%+-./");
  451. }
  452. public function testBarcodeCode39Asterisks()
  453. {
  454. $this -> printer -> barcode("*TEXT*", Printer::BARCODE_CODE39);
  455. $this -> checkOutput("\x1b@\x1dkE\x06*TEXT*");
  456. }
  457. public function testBarcodeCode39AsterisksUnmatched()
  458. {
  459. $this -> expectException(InvalidArgumentException::class);
  460. $this -> printer -> barcode("*TEXT", Printer::BARCODE_CODE39);
  461. }
  462. public function testBarcodeCode39AsteriskInText()
  463. {
  464. $this -> expectException(InvalidArgumentException::class);
  465. $this -> printer -> barcode("12*34", Printer::BARCODE_CODE39);
  466. }
  467. public function testBarcodeCode39Lowercase()
  468. {
  469. $this -> expectException(InvalidArgumentException::class);
  470. $this -> printer -> barcode("abcd", Printer::BARCODE_CODE39);
  471. }
  472. public function testBarcodeCode39Empty()
  473. {
  474. $this -> expectException(InvalidArgumentException::class);
  475. $this -> printer -> barcode("**", Printer::BARCODE_CODE39);
  476. }
  477. /* Barcode - ITF */
  478. public function testBarcodeItfNumericEven()
  479. {
  480. $this -> printer -> barcode("1234", Printer::BARCODE_ITF);
  481. $this -> checkOutput("\x1b@\x1dkF\x041234");
  482. }
  483. public function testBarcodeItfNumericOdd()
  484. {
  485. $this -> expectException(InvalidArgumentException::class);
  486. $this -> printer -> barcode("123", Printer::BARCODE_ITF);
  487. }
  488. public function testBarcodeItfNonNumericEven()
  489. {
  490. $this -> expectException(InvalidArgumentException::class);
  491. $this -> printer -> barcode("A234", Printer::BARCODE_ITF);
  492. }
  493. /* Barcode - Codabar */
  494. public function testBarcodeCodabarNumeric()
  495. {
  496. $this -> printer -> barcode("A012345A", Printer::BARCODE_CODABAR);
  497. $this -> checkOutput("\x1b@\x1dkG\x08A012345A");
  498. }
  499. public function testBarcodeCodabarSpecialChars()
  500. {
  501. $this -> printer -> barcode("A012$+-./:A", Printer::BARCODE_CODABAR);
  502. $this -> checkOutput("\x1b@\x1dkG\x0bA012$+-./:A");
  503. }
  504. public function testBarcodeCodabarNotWrapped()
  505. {
  506. $this -> expectException(InvalidArgumentException::class);
  507. $this -> printer -> barcode("012345", Printer::BARCODE_CODABAR);
  508. }
  509. public function testBarcodeCodabarStartStopWrongPlace()
  510. {
  511. $this -> expectException(InvalidArgumentException::class);
  512. $this -> printer -> barcode("012A45", Printer::BARCODE_CODABAR);
  513. }
  514. /* Barcode - Code93 */
  515. public function testBarcodeCode93Valid()
  516. {
  517. $this -> printer -> barcode("012abcd", Printer::BARCODE_CODE93);
  518. $this -> checkOutput("\x1b@\x1dkH\x07012abcd");
  519. }
  520. public function testBarcodeCode93Empty()
  521. {
  522. $this -> expectException(InvalidArgumentException::class);
  523. $this -> printer -> barcode("", Printer::BARCODE_CODE93);
  524. }
  525. /* Barcode - Code128 */
  526. public function testBarcodeCode128ValidA()
  527. {
  528. $this -> printer -> barcode("{A" . "012ABCD", Printer::BARCODE_CODE128);
  529. $this -> checkOutput("\x1b@\x1dkI\x09{A012ABCD");
  530. }
  531. public function testBarcodeCode128ValidB()
  532. {
  533. $this -> printer -> barcode("{B" . "012ABCDabcd", Printer::BARCODE_CODE128);
  534. $this -> checkOutput("\x1b@\x1dkI\x0d{B012ABCDabcd");
  535. }
  536. public function testBarcodeCode128ValidC()
  537. {
  538. $this -> printer -> barcode("{C" . chr(21) . chr(32) . chr(43), Printer::BARCODE_CODE128);
  539. $this -> checkOutput("\x1b@\x1dkI\x05{C\x15 +");
  540. }
  541. public function testBarcodeCode128NoCodeSet()
  542. {
  543. $this -> expectException(InvalidArgumentException::class);
  544. $this -> printer -> barcode("ABCD", Printer::BARCODE_CODE128);
  545. }
  546. /* Pulse */
  547. function testPulseDefault()
  548. {
  549. $this -> printer -> pulse();
  550. $this -> checkOutput("\x1b@\x1bp0<x");
  551. }
  552. function testPulse1()
  553. {
  554. $this -> printer -> pulse(1);
  555. $this -> checkOutput("\x1b@\x1bp1<x");
  556. }
  557. function testPulseEvenMs()
  558. {
  559. $this -> printer -> pulse(0, 2, 2);
  560. $this -> checkOutput("\x1b@\x1bp0\x01\x01");
  561. }
  562. function testPulseOddMs()
  563. {
  564. $this -> printer -> pulse(0, 3, 3); // Should be rounded down and give same output
  565. $this -> checkOutput("\x1b@\x1bp0\x01\x01");
  566. }
  567. function testPulseTooHigh()
  568. {
  569. $this -> expectException(InvalidArgumentException::class);
  570. $this -> printer -> pulse(0, 512, 2);
  571. }
  572. function testPulseTooLow()
  573. {
  574. $this -> expectException(InvalidArgumentException::class);
  575. $this -> printer -> pulse(0, 0, 2);
  576. }
  577. /* Set reverse */
  578. public function testSetReverseColorsDefault()
  579. {
  580. $this -> printer -> setReverseColors();
  581. $this -> checkOutput("\x1b@\x1dB\x01");
  582. }
  583. public function testSetReverseColorsOn()
  584. {
  585. $this -> printer -> setReverseColors(true);
  586. $this -> checkOutput("\x1b@\x1dB\x01");
  587. }
  588. public function testSetReverseColorsOff()
  589. {
  590. $this -> printer -> setReverseColors(false);
  591. $this -> checkOutput("\x1b@\x1dB\x00");
  592. }
  593. /* Bit image print */
  594. public function testBitImageBlack()
  595. {
  596. $this -> requireGraphicsLibrary();
  597. $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_black.png");
  598. $this -> printer -> bitImage($img);
  599. $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x01\x00\x80");
  600. }
  601. public function testBitImageWhite()
  602. {
  603. $this -> requireGraphicsLibrary();
  604. $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_white.png");
  605. $this -> printer -> bitImage($img);
  606. $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x01\x00\x00");
  607. }
  608. public function testBitImageBoth()
  609. {
  610. $this -> requireGraphicsLibrary();
  611. $img = EscposImage::load(dirname(__FILE__)."/resources/black_white.png");
  612. $this -> printer -> bitImage($img);
  613. $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x02\x00\xc0\x00");
  614. }
  615. public function testBitImageTransparent()
  616. {
  617. $this -> requireGraphicsLibrary();
  618. $img = EscposImage::load(dirname(__FILE__)."/resources/black_transparent.png");
  619. $this -> printer -> bitImage($img);
  620. $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x02\x00\xc0\x00");
  621. }
  622. /* Bit image column format */
  623. public function testBitImageColumnFormatBlack()
  624. {
  625. $this -> requireGraphicsLibrary();
  626. $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_black.png");
  627. $this -> printer -> bitImageColumnFormat($img);
  628. $this -> checkOutput("\x1b@\x1b3\x10\x1b*!\x01\x00\x80\x00\x00\x0a\x1b2");
  629. }
  630. public function testBitImageColumnFormatWhite()
  631. {
  632. $this -> requireGraphicsLibrary();
  633. $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_white.png");
  634. $this -> printer -> bitImageColumnFormat($img);
  635. $this -> checkOutput("\x1b@\x1b3\x10\x1b*!\x01\x00\x00\x00\x00\x0a\x1b2");
  636. }
  637. public function testBitImageColumnFormatBoth()
  638. {
  639. $this -> requireGraphicsLibrary();
  640. $img = EscposImage::load(dirname(__FILE__)."/resources/black_white.png");
  641. $this -> printer -> bitImageColumnFormat($img);
  642. $this -> checkOutput("\x1b@\x1b3\x10\x1b*!\x02\x00\x80\x00\x00\x80\x00\x00\x0a\x1b2");
  643. }
  644. public function testBitImageColumnFormatTransparent()
  645. {
  646. $this -> requireGraphicsLibrary();
  647. $img = EscposImage::load(dirname(__FILE__)."/resources/black_transparent.png");
  648. $this -> printer -> bitImageColumnFormat($img);
  649. $this -> checkOutput("\x1b@\x1b3\x10\x1b*!\x02\x00\x80\x00\x00\x80\x00\x00\x0a\x1b2");
  650. }
  651. /* Graphics print */
  652. public function testGraphicsWhite()
  653. {
  654. $this -> requireGraphicsLibrary();
  655. $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_white.png");
  656. $this -> printer -> graphics($img);
  657. $this -> checkOutput("\x1b@\x1d(L\x0b\x000p0\x01\x011\x01\x00\x01\x00\x00\x1d(L\x02\x0002");
  658. }
  659. public function testGraphicsBlack()
  660. {
  661. $this -> requireGraphicsLibrary();
  662. $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_black.png");
  663. $this -> printer -> graphics($img);
  664. $this -> checkOutput("\x1b@\x1d(L\x0b\x000p0\x01\x011\x01\x00\x01\x00\x80\x1d(L\x02\x0002");
  665. }
  666. public function testGraphicsBoth()
  667. {
  668. $this -> requireGraphicsLibrary();
  669. $img = EscposImage::load(dirname(__FILE__)."/resources/black_white.png");
  670. $this -> printer -> graphics($img);
  671. $this -> checkOutput("\x1b@\x1d(L\x0c\x000p0\x01\x011\x02\x00\x02\x00\xc0\x00\x1d(L\x02\x0002");
  672. }
  673. public function testGraphicsTransparent()
  674. {
  675. $this -> requireGraphicsLibrary();
  676. $img = EscposImage::load(dirname(__FILE__)."/resources/black_transparent.png");
  677. $this -> printer -> graphics($img);
  678. $this -> checkOutput("\x1b@\x1d(L\x0c\x000p0\x01\x011\x02\x00\x02\x00\xc0\x00\x1d(L\x02\x0002");
  679. }
  680. /* PDF417 code */
  681. public function testPdf417CodeDefaults()
  682. {
  683. $this -> printer -> pdf417Code("1234");
  684. $this -> checkOutput("\x1b@\x1d(k\x03\x000F\x00\x1d(k\x03\x000A\x00\x1d(k\x03\x000C\x03\x1d(k\x03\x000D\x03\x1d(k\x04\x000E1\x01\x1d(k\x07\x000P01234\x1d(k\x03\x000Q0");
  685. }
  686. public function testPdf417CodeEmpty()
  687. {
  688. $this -> printer -> pdf417Code('');
  689. $this -> checkOutput("\x1b@"); // No commands actually sent
  690. }
  691. public function testPdf417CodeNotSupported()
  692. {
  693. $this -> expectException(Exception::class);
  694. $profile = CapabilityProfile::load("simple");
  695. $this -> printer = new Printer($this -> outputConnector, $profile);
  696. $this -> printer -> pdf417Code("1234");
  697. }
  698. public function testPdf417CodeChangeGeometry()
  699. {
  700. // 7-dot wide, 4-times height, 4 data columns
  701. $this -> printer -> pdf417Code("1234", 7, 4, 4);
  702. $this -> checkOutput("\x1b@\x1d(k\x03\x000F\x00\x1d(k\x03\x000A\x04\x1d(k\x03\x000C\x07\x1d(k\x03\x000D\x04\x1d(k\x04\x000E1\x01\x1d(k\x07\x000P01234\x1d(k\x03\x000Q0");
  703. }
  704. public function testPdf417CodeChangeErrorCorrection()
  705. {
  706. $this -> printer -> pdf417Code("1234", 3, 3, 0, 0.5);
  707. $this -> checkOutput("\x1b@\x1d(k\x03\x000F\x00\x1d(k\x03\x000A\x00\x1d(k\x03\x000C\x03\x1d(k\x03\x000D\x03\x1d(k\x04\x000E1\x05\x1d(k\x07\x000P01234\x1d(k\x03\x000Q0");
  708. }
  709. public function testPdf417CodeChangeErrorCorrectionOutOfRange()
  710. {
  711. $this -> expectException(InvalidArgumentException::class);
  712. $this -> printer -> pdf417Code("1234", 3, 3, 0, 5.0);
  713. }
  714. public function testPdf417CodeChangeOption()
  715. {
  716. // Use the alternate truncated format
  717. $this -> printer -> pdf417Code("1234", 3, 3, 0, 0.1, Printer::PDF417_TRUNCATED);
  718. $this -> checkOutput("\x1b@\x1d(k\x03\x000F\x01\x1d(k\x03\x000A\x00\x1d(k\x03\x000C\x03\x1d(k\x03\x000D\x03\x1d(k\x04\x000E1\x01\x1d(k\x07\x000P01234\x1d(k\x03\x000Q0");
  719. }
  720. /* QR code */
  721. public function testQRCodeDefaults()
  722. {
  723. // Test will fail if default values change
  724. $this -> printer -> qrCode("1234");
  725. $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0");
  726. }
  727. public function testQRCodeDefaultsAreCorrect()
  728. {
  729. // Below tests assume that defaults are as written here (output string should be same as above)
  730. $this -> printer -> qrCode("1234", Printer::QR_ECLEVEL_L, 3, Printer::QR_MODEL_2);
  731. $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0");
  732. }
  733. public function testQRCodeEmpty()
  734. {
  735. $this -> printer -> qrCode('');
  736. $this -> checkOutput("\x1b@"); // No commands actually sent
  737. }
  738. public function testQRCodeChangeEC()
  739. {
  740. $this -> printer -> qrCode("1234", Printer::QR_ECLEVEL_H);
  741. $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E3\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0");
  742. }
  743. public function testQRCodeChangeSize()
  744. {
  745. $this -> printer -> qrCode("1234", Printer::QR_ECLEVEL_L, 7);
  746. $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x07\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0");
  747. }
  748. public function testQRCodeChangeModel()
  749. {
  750. $this -> printer -> qrCode("1234", Printer::QR_ECLEVEL_L, 3, Printer::QR_MODEL_1);
  751. $this -> checkOutput("\x1b@\x1d(k\x04\x001A1\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0");
  752. }
  753. /* Feed form - Required on page-mode only printers */
  754. public function testFeedForm()
  755. {
  756. $this -> printer -> feedForm();
  757. $this -> checkOutput("\x1b@\x0c");
  758. }
  759. /* Release */
  760. public function testRelease()
  761. {
  762. $this -> printer -> release();
  763. $this -> checkOutput("\x1b@\x1b\x71");
  764. }
  765. /* Set text size */
  766. public function testSetTextSizeNormal()
  767. {
  768. $this -> printer -> setTextSize(1, 1);
  769. $this -> checkOutput("\x1b@\x1d!\x00");
  770. }
  771. public function testSetTextSizeWide()
  772. {
  773. $this -> printer -> setTextSize(4, 1);
  774. $this -> checkOutput("\x1b@\x1d!0");
  775. }
  776. public function testSetTextSizeNarrow()
  777. {
  778. $this -> printer -> setTextSize(1, 4);
  779. $this -> checkOutput("\x1b@\x1d!\x03");
  780. }
  781. public function testSetTextSizeLarge()
  782. {
  783. $this -> printer -> setTextSize(4, 4);
  784. $this -> checkOutput("\x1b@\x1d!3");
  785. }
  786. public function testSetTextSizeInvalid()
  787. {
  788. $this -> expectException(InvalidArgumentException::class);
  789. $this -> printer -> setTextSize(0, 9);
  790. }
  791. /* Set color */
  792. public function testSetColorDefault()
  793. {
  794. $this -> printer -> setColor(Printer::COLOR_1);
  795. $this -> checkOutput("\x1b@\x1br\x00");
  796. }
  797. public function testSetColorAlternative()
  798. {
  799. $this -> printer -> setColor(Printer::COLOR_2);
  800. $this -> checkOutput("\x1b@\x1br\x01");
  801. }
  802. public function testSetColorInvalid()
  803. {
  804. $this -> expectException(InvalidArgumentException::class);
  805. $this -> printer -> setColor(3);
  806. }
  807. /* Set line spacing */
  808. public function testSetLineSpacingDefault()
  809. {
  810. $this -> printer -> setLineSpacing();
  811. $this -> checkOutput("\x1b@\x1b2");
  812. }
  813. public function testSetLineSpacingInvalid()
  814. {
  815. $this -> expectException(InvalidArgumentException::class);
  816. $this -> printer -> setLineSpacing(300);
  817. }
  818. public function testSetLineSpacingSmaller()
  819. {
  820. $this -> printer -> setLineSpacing(16);
  821. $this -> checkOutput("\x1b@\x1b3\x10");
  822. }
  823. public function testSetLineSpacingLarger()
  824. {
  825. $this -> printer -> setLineSpacing(32);
  826. $this -> checkOutput("\x1b@\x1b3\x20");
  827. }
  828. /* Set print width */
  829. public function testSetPrintWidthDefault()
  830. {
  831. $this -> printer -> setPrintWidth();
  832. $this -> checkOutput("\x1b@\x1dW\x00\x02");
  833. }
  834. public function testSetPrintWidthNarrow()
  835. {
  836. $this -> printer -> setPrintWidth(400);
  837. $this -> checkOutput("\x1b@\x1dW\x90\x01");
  838. }
  839. public function testSetPrintWidthInvalid()
  840. {
  841. $this -> expectException(InvalidArgumentException::class);
  842. $this -> printer -> setPrintWidth(0);
  843. }
  844. /* Set print left margin */
  845. public function testSetPrintLeftMarginDefault()
  846. {
  847. $this -> printer -> setPrintLeftMargin();
  848. $this -> checkOutput("\x1b@\x1dL\x00\x00");
  849. }
  850. public function testSetPrintLeftMarginWide()
  851. {
  852. $this -> printer -> setPrintLeftMargin(32);
  853. $this -> checkOutput("\x1b@\x1dL\x20\x00");
  854. }
  855. public function testPrintLeftMarginInvalid()
  856. {
  857. $this -> expectException(InvalidArgumentException::class);
  858. $this -> printer -> setPrintLeftMargin(70000);
  859. $this -> checkOutput();
  860. }
  861. /* Upside-down print */
  862. public function testSetUpsideDown()
  863. {
  864. $this -> printer -> setUpsideDown(true);
  865. $this -> checkOutput("\x1b@\x1b{\x01");
  866. }
  867. }