x-model.spec.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import { haveData, haveText, haveValue, html, test } from '../../utils'
  2. test('The name of the test',
  3. html`<h1 x-data x-text="'HEY'"></h1>`,
  4. ({ get }) => get('h1').should(haveText('HEY'))
  5. )
  6. test('x-model has value binding when initialized',
  7. html`
  8. <div x-data="{ foo: 'bar' }">
  9. <input x-model="foo"></input>
  10. </div>
  11. `,
  12. ({ get }) => { get('input').should(haveValue('bar')) }
  13. )
  14. test('x-model updates value when updated via input event',
  15. html`
  16. <div x-data="{ foo: 'bar' }">
  17. <input x-model="foo"></input>
  18. <span x-text="foo"></span>
  19. </div>
  20. `,
  21. ({ get }) => {
  22. get('span').should(haveText('bar'))
  23. get('input').type('baz')
  24. get('span').should(haveText('barbaz'))
  25. }
  26. )
  27. test('x-model has value binding when updated',
  28. html`
  29. <div x-data="{ foo: 'bar' }">
  30. <input x-model="foo"></input>
  31. <button x-on:click="foo = 'baz'">click me</button>
  32. </div>
  33. `,
  34. ({ get }) => {
  35. get('input').should(haveValue('bar'))
  36. get('button').click()
  37. get('input').should(haveValue('baz'))
  38. }
  39. )
  40. test('x-model casts value to number if number modifier is present',
  41. html`
  42. <div x-data="{ foo: null }">
  43. <input type="number" x-model.number="foo"></input>
  44. </div>
  45. `,
  46. ({ get }) => {
  47. get('input').type('123')
  48. get('div').should(haveData('foo', 123))
  49. }
  50. )
  51. test('x-model with number modifier returns: null if empty, original value if casting fails, numeric value if casting passes',
  52. html`
  53. <div x-data="{ foo: 0, bar: '' }">
  54. <input type="number" x-model.number="foo"></input>
  55. <input x-model.number="bar"></input>
  56. </div>
  57. `,
  58. ({ get }) => {
  59. get('input:nth-of-type(1)').clear()
  60. get('div').should(haveData('foo', null))
  61. get('input:nth-of-type(1)').clear().type('-')
  62. get('div').should(haveData('foo', null))
  63. get('input:nth-of-type(1)').clear().type('-123')
  64. get('div').should(haveData('foo', -123))
  65. get('input:nth-of-type(2)').type(123).clear()
  66. get('div').should(haveData('bar', null))
  67. get('input:nth-of-type(2)').clear().type('-')
  68. get('div').should(haveData('bar', '-'))
  69. get('input:nth-of-type(2)').clear().type('-123')
  70. get('div').should(haveData('bar', -123))
  71. }
  72. )
  73. test('x-model trims value if trim modifier is present',
  74. html`
  75. <div x-data="{ foo: '' }">
  76. <input x-model.trim="foo"></input>
  77. <span x-text="foo"></span>
  78. </div>
  79. `,
  80. ({ get }) => {
  81. get('input').type('bar ')
  82. get('div').should(haveData('foo', 'bar'))
  83. }
  84. )
  85. test('x-model can be accessed programmatically',
  86. html`
  87. <div x-data="{ foo: 'bar' }" x-model="foo">
  88. <input x-model="foo">
  89. <span x-text="$root._x_model.get()"></span>
  90. <button @click="$root._x_model.set('bob')">Set foo to bob</button>
  91. </div>
  92. `,
  93. ({ get }) => {
  94. get('span').should(haveText('bar'))
  95. get('input').type('baz')
  96. get('span').should(haveText('barbaz'))
  97. get('button').click()
  98. get('span').should(haveText('bob'))
  99. }
  100. )
  101. test('x-model updates value when the form is reset',
  102. html`
  103. <div x-data="{ foo: '' }">
  104. <form>
  105. <input x-model="foo"></input>
  106. <button type="reset">Reset</button>
  107. </form>
  108. <span x-text="foo"></span>
  109. </div>
  110. `,
  111. ({ get }) => {
  112. get('span').should(haveText(''))
  113. get('input').type('baz')
  114. get('span').should(haveText('baz'))
  115. get('button').click()
  116. get('span').should(haveText(''))
  117. }
  118. )
  119. test('x-model with fill modifier takes input value on null or empty string',
  120. html`
  121. <div x-data="{ a: 123, b: 0, c: '', d: null }">
  122. <input x-model.fill="a" value="123456" />
  123. <span id="a" x-text="a"></span>
  124. <input x-model.fill="b" value="123456" />
  125. <span id="b" x-text="b"></span>
  126. <input x-model.fill="c" value="123456" />
  127. <span id="c" x-text="c"></span>
  128. <input x-model.fill="d" value="123456" />
  129. <span id="d" x-text="d"></span>
  130. </div>
  131. `,
  132. ({ get }) => {
  133. get('#a').should(haveText('123'))
  134. get('#b').should(haveText('0'))
  135. get('#c').should(haveText('123456'))
  136. get('#d').should(haveText('123456'))
  137. }
  138. )
  139. test('x-model with fill modifier works with select/radio elements',
  140. html`
  141. <div x-data="{ a: null, b: null, c: null, d: null }">
  142. <select x-model.fill="a">
  143. <option value="123">123</option>
  144. <option value="456" selected>456</option>
  145. </select>
  146. <select x-model.fill="b" multiple>
  147. <option value="123" selected>123</option>
  148. <option value="456" selected>456</option>
  149. </select>
  150. </div>
  151. `,
  152. ({ get }) => {
  153. get('[x-data]').should(haveData('a', '456'));
  154. get('[x-data]').should(haveData('b', ['123', '456']));
  155. }
  156. );
  157. test('x-model with fill modifier respects number modifier',
  158. html`
  159. <div x-data="{ a: null, b: null, c: null, d: null }">
  160. <input type="text" x-model.fill.number="a" value="456" / >
  161. <select x-model.fill.number="b" multiple>
  162. <option value="123" selected>123</option>
  163. <option value="456" selected>456</option>
  164. </select>
  165. </div>
  166. `,
  167. ({ get }) => {
  168. get('[x-data]').should(haveData('a', 456));
  169. get('[x-data]').should(haveData('b', [123,456]));
  170. }
  171. );