mask.spec.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. import { haveValue, html, test } from '../../utils'
  2. test('x-mask',
  3. [html`<input x-data x-mask="(999) 999-9999">`],
  4. ({ get }) => {
  5. // Type a phone number:
  6. get('input').type('12').should(haveValue('(12'))
  7. get('input').type('3').should(haveValue('(123) '))
  8. get('input').type('4567890').should(haveValue('(123) 456-7890'))
  9. // Clear it & paste formatted version in:
  10. get('input').type('{selectAll}{backspace}')
  11. get('input').invoke('val', '(123) 456-7890').trigger('blur')
  12. get('input').should(haveValue('(123) 456-7890'))
  13. // Clear it & paste un-formatted version in:
  14. get('input').type('{selectAll}{backspace}')
  15. get('input').invoke('val', '1234567890').trigger('blur')
  16. get('input').should(haveValue('(123) 456-7890'))
  17. // Make sure backspace works.
  18. get('input').type('{backspace}').should(haveValue('(123) 456-789'))
  19. get('input').type('{backspace}').should(haveValue('(123) 456-78'))
  20. get('input').type('{backspace}').should(haveValue('(123) 456-7'))
  21. get('input').type('{backspace}').should(haveValue('(123) 456-'))
  22. get('input').type('{backspace}').should(haveValue('(123) 456'))
  23. get('input').type('{backspace}').should(haveValue('(123) 45'))
  24. // Make sure you can't type other characters.
  25. get('input').type('a').should(haveValue('(123) 45'))
  26. get('input').type('-').should(haveValue('(123) 45'))
  27. // Put cursor in other places in the input and make sure you can type.
  28. get('input').type('67890').should(haveValue('(123) 456-7890'))
  29. get('input').type('{leftArrow}{leftArrow}{leftArrow}{leftArrow}{leftArrow}')
  30. get('input').type('123456').should(haveValue('(123) 456-1234'))
  31. },
  32. )
  33. test('x-mask with x-model',
  34. [html`
  35. <div x-data="{ value: '' }">
  36. <input x-mask="(999) 999-9999" x-model="value" id="1">
  37. <input id="2" x-model="value">
  38. </div>
  39. `],
  40. ({ get }) => {
  41. // Type a phone number:
  42. get('#1').type('12').should(haveValue('(12'))
  43. get('#2').should(haveValue('(12'))
  44. get('#1').type('3').should(haveValue('(123) '))
  45. get('#2').should(haveValue('(123) '))
  46. get('#1').type('4567890').should(haveValue('(123) 456-7890'))
  47. get('#2').should(haveValue('(123) 456-7890'))
  48. // Clear it & paste formatted version in:
  49. get('#1').type('{selectAll}{backspace}')
  50. get('#1').invoke('val', '(123) 456-7890').trigger('input')
  51. get('#1').should(haveValue('(123) 456-7890'))
  52. get('#2').should(haveValue('(123) 456-7890'))
  53. // Clear it & paste un-formatted version in:
  54. get('#1').type('{selectAll}{backspace}')
  55. get('#1').invoke('val', '1234567890').trigger('input')
  56. get('#1').should(haveValue('(123) 456-7890'))
  57. get('#2').should(haveValue('(123) 456-7890'))
  58. },
  59. )
  60. // This passes locally but fails in CI...
  61. test.skip('x-mask with latently bound x-model',
  62. [html`
  63. <div x-data="{ value: '' }">
  64. <input x-mask="(999) 999-9999" x-bind="{ 'x-model': 'value' }" id="1">
  65. <input id="2" x-model="value">
  66. </div>
  67. `],
  68. ({ get }) => {
  69. get('#1').type('a').should(haveValue('('))
  70. get('#2').should(haveValue('('))
  71. get('#1').type('1').should(haveValue('(1'))
  72. get('#2').should(haveValue('(1'))
  73. },
  74. )
  75. test('x-mask with x-model with initial value',
  76. [html`
  77. <div x-data="{ value: '1234567890' }">
  78. <input x-mask="(999) 999-9999" x-model="value" id="1">
  79. <input id="2" x-model="value">
  80. </div>
  81. `],
  82. ({ get }) => {
  83. get('#1').should(haveValue('(123) 456-7890'))
  84. get('#2').should(haveValue('(123) 456-7890'))
  85. },
  86. )
  87. test('x-mask with x-model if initial value is null it should remain null',
  88. [html`
  89. <div x-data="{ value: null }">
  90. <input x-mask="(999) 999-9999" x-model="value" id="1">
  91. <input id="2" x-model="value">
  92. <span id="3" x-text="value === null ? 'NULL' : value"></span>
  93. </div>
  94. `],
  95. ({ get }) => {
  96. get('#1').should(haveValue(''))
  97. get('#2').should(haveValue(''))
  98. get('#3').contains('NULL')
  99. },
  100. )
  101. test('x-mask with a falsy input',
  102. [html`<input x-data x-mask="">`],
  103. ({ get }) => {
  104. get('input').type('1').should(haveValue('1'))
  105. get('input').type('2').should(haveValue('12'))
  106. get('input').type('ua').should(haveValue('12ua'))
  107. get('input').type('/').should(haveValue('12ua/'))
  108. get('input').type('cs').should(haveValue('12ua/cs'))
  109. get('input').type(' 3').should(haveValue('12ua/cs 3'))
  110. }
  111. )
  112. test('x-mask with a falsy string input',
  113. [html`<input x-data x-mask="false">`],
  114. ({ get }) => {
  115. get('input').type('1').should(haveValue('1'))
  116. get('input').type('2').should(haveValue('12'))
  117. get('input').type('ua').should(haveValue('12ua'))
  118. get('input').type('/').should(haveValue('12ua/'))
  119. get('input').type('cs').should(haveValue('12ua/cs'))
  120. get('input').type(' 3').should(haveValue('12ua/cs 3'))
  121. }
  122. )
  123. test('x-mask with non wildcard alpha-numeric characters (b)',
  124. [html`<input x-data x-mask="ba9*b">`],
  125. ({ get }) => {
  126. get('input').type('a').should(haveValue('ba'))
  127. get('input').type('a').should(haveValue('ba'))
  128. get('input').type('3').should(haveValue('ba3'))
  129. get('input').type('z').should(haveValue('ba3zb'))
  130. get('input').type('{backspace}{backspace}4').should(haveValue('ba34b'))
  131. }
  132. )
  133. test('x-mask:dynamic',
  134. [html`<input x-data x-mask:dynamic="'(999)'">`],
  135. ({ get }) => {
  136. get('input').type('123').should(haveValue('(123)'))
  137. }
  138. )
  139. test('$money',
  140. [html`<input x-data x-mask:function="$money">`],
  141. ({ get }) => {
  142. get('input').type('30.00').should(haveValue('30.00'))
  143. get('input').type('5').should(haveValue('30.00'))
  144. get('input').type('{backspace}').should(haveValue('30.0'))
  145. get('input').type('5').should(haveValue('30.05'))
  146. get('input').type('{selectAll}{backspace}').should(haveValue(''))
  147. get('input').type('123').should(haveValue('123'))
  148. get('input').type('4').should(haveValue('1,234'))
  149. get('input').type('567').should(haveValue('1,234,567'))
  150. get('input').type('.89').should(haveValue('1,234,567.89'))
  151. get('input').type('{leftArrow}7').should(haveValue('1,234,567.87'))
  152. get('input').type('{leftArrow}{leftArrow}{leftArrow}89').should(haveValue('123,456,789.87'))
  153. get('input').type('{leftArrow}{leftArrow}{leftArrow}{leftArrow}12').should(haveValue('12,345,612,789.87'))
  154. get('input').type('{leftArrow}3').should(haveValue('123,456,123,789.87'))
  155. // Clear it & paste formatted version in:
  156. get('input').type('{selectAll}{backspace}')
  157. get('input').invoke('val', '123,456,132,789.87').trigger('blur')
  158. get('input').should(haveValue('123,456,132,789.87'))
  159. // Clear it & paste un-formatted version in:
  160. get('input').type('{selectAll}{backspace}')
  161. get('input').invoke('val', '123456132789.87').trigger('blur')
  162. get('input').should(haveValue('123,456,132,789.87'))
  163. },
  164. )
  165. test('$money swapping commas and periods',
  166. [html`<input x-data x-mask:function="$money($input, ',')">`],
  167. ({ get }) => {
  168. get('input').type('30,00').should(haveValue('30,00'))
  169. get('input').type('5').should(haveValue('30,00'))
  170. get('input').type('{backspace}').should(haveValue('30,0'))
  171. get('input').type('5').should(haveValue('30,05'))
  172. get('input').type('{selectAll}{backspace}').should(haveValue(''))
  173. get('input').type('123').should(haveValue('123'))
  174. get('input').type('4').should(haveValue('1.234'))
  175. get('input').type('567').should(haveValue('1.234.567'))
  176. get('input').type(',89').should(haveValue('1.234.567,89'))
  177. },
  178. )
  179. test('$money with different thousands separator',
  180. [html`<input x-data x-mask:function="$money($input, '.', ' ')" />`],
  181. ({ get }) => {
  182. get('input').type('3000').should(haveValue('3 000'));
  183. get('input').type('{backspace}').blur().should(haveValue('300'));
  184. get('input').type('5').should(haveValue('3 005'));
  185. get('input').type('{selectAll}{backspace}').should(haveValue(''));
  186. get('input').type('123').should(haveValue('123'));
  187. get('input').type('4').should(haveValue('1 234'));
  188. get('input').type('567').should(haveValue('1 234 567'));
  189. get('input').type('.89').should(haveValue('1 234 567.89'));
  190. }
  191. );
  192. test('$money works with permanent inserted at beginning',
  193. [html`<input x-data x-mask:dynamic="$money">`],
  194. ({ get }) => {
  195. get('input').type('40.00').should(haveValue('40.00'))
  196. get('input').type('{leftArrow}{leftArrow}{leftArrow}{leftArrow}{leftArrow}')
  197. get('input').type('$')
  198. get('input').should(haveValue('40.00'))
  199. }
  200. )
  201. test('$money mask should remove letters or non numeric characters',
  202. [html`<input x-data x-mask:dynamic="$money">`],
  203. ({ get }) => {
  204. get('input').type('A').should(haveValue(''))
  205. get('input').type('ABC').should(haveValue(''))
  206. get('input').type('$').should(haveValue(''))
  207. get('input').type('/').should(haveValue(''))
  208. get('input').type('40').should(haveValue('40'))
  209. }
  210. )
  211. test('$money mask negative values',
  212. [html`
  213. <input id="1" x-data x-mask:dynamic="$money($input)" value="-1234.50" />
  214. <input id="2" x-data x-mask:dynamic="$money($input)" />
  215. `],
  216. ({ get }) => {
  217. get('#1').should(haveValue('-1,234.50'))
  218. get('#2').type('-12.509').should(haveValue('-12.50'))
  219. get('#2').type('{leftArrow}{leftArrow}{leftArrow}-').should(haveValue('-12.50'))
  220. get('#2').type('{leftArrow}{leftArrow}{backspace}').should(haveValue('12.50'))
  221. get('#2').type('{rightArrow}-').should(haveValue('12.50'))
  222. get('#2').type('{rightArrow}-').should(haveValue('12.50'))
  223. get('#2').type('{rightArrow}{rightArrow}{rightArrow}-').should(haveValue('12.50'))
  224. get('#2').type('{leftArrow}{leftArrow}{leftArrow}{leftArrow}{leftArrow}-').should(haveValue('-12.50'))
  225. }
  226. )
  227. test('$money with custom decimal precision',
  228. [html`
  229. <input id="0" x-data x-mask:dynamic="$money($input, '.', ',', 0)" />
  230. <input id="1" x-data x-mask:dynamic="$money($input, '.', ',', 1)" />
  231. <input id="2" x-data x-mask:dynamic="$money($input, '.', ',', 2)" />
  232. <input id="3" x-data x-mask:dynamic="$money($input, '.', ',', 3)" />
  233. `],
  234. ({ get }) => {
  235. get('#0').type('1234.5678').should(haveValue('12,345,678'))
  236. get('#1').type('1234.5678').should(haveValue('1,234.5'))
  237. get('#2').type('1234.5678').should(haveValue('1,234.56'))
  238. get('#3').type('1234.5678').should(haveValue('1,234.567'))
  239. }
  240. )