describe 'up.form', -> u = up.util describe 'Javascript functions', -> describe 'up.observe', -> changeEvents = if up.browser.canInputEvent() # Actually we only need `input`, but we want to notice # if another script manually triggers `change` on the element. ['input', 'change'] else # Actually we won't ever get `input` from the user in this browser, # but we want to notice if another script manually triggers `input` # on the element. ['input', 'change', 'keypress', 'paste', 'cut', 'click', 'propertychange'] u.each changeEvents, (eventName) -> describe 'when the first argument is a form field', -> it "runs the callback when the input receives a '#{eventName}' event and the value changed", (done) -> $input = affix('input[value="old-value"]') callback = jasmine.createSpy('change callback') up.observe($input, callback) $input.val('new-value') u.times 2, -> $input.trigger(eventName) u.nextFrame -> expect(callback).toHaveBeenCalledWith('new-value', $input) expect(callback.calls.count()).toEqual(1) done() it "does not run the callback when the input receives a '#{eventName}' event, but the value didn't change", (done) -> $input = affix('input[value="old-value"]') callback = jasmine.createSpy('change callback') up.observe($input, callback) $input.trigger(eventName) u.nextFrame -> expect(callback).not.toHaveBeenCalled() done() it "runs a callback in the same frame if the delay is 0 and it receives a '#{eventName}' event", -> $input = affix('input[value="old-value"]') callback = jasmine.createSpy('change callback') up.observe($input, { delay: 0 }, callback) $input.val('new-value') $input.trigger(eventName) expect(callback.calls.count()).toEqual(1) it "runs multiple callbacks in the same frame if the delay is 0 and it receives a '#{eventName}' event", -> $input = affix('input[value="old-value"]') callback = jasmine.createSpy('change callback') up.observe($input, { delay: 0 }, callback) $input.val('new-value') $input.trigger(eventName) $input.val('yet-another-value') $input.trigger(eventName) expect(callback.calls.count()).toEqual(2) describe 'when the first argument is a form', -> it "runs the callback when any of the form's inputs receives a '#{eventName}' event and the value changed", (done) -> $form = affix('form') $input = $form.affix('input[value="old-value"]') callback = jasmine.createSpy('change callback') up.observe($form, callback) $input.val('new-value') u.times 2, -> $input.trigger(eventName) u.nextFrame -> expect(callback).toHaveBeenCalledWith('new-value', $input) expect(callback.calls.count()).toEqual(1) done() it "does not run the callback when any of the form's inputs receives a '#{eventName}' event, but the value didn't change", (done) -> $form = affix('form') $input = $form.affix('input[value="old-value"]') callback = jasmine.createSpy('change callback') up.observe($form, callback) $input.trigger(eventName) u.nextFrame -> expect(callback).not.toHaveBeenCalled() done() describe 'up.submit', -> if up.browser.canPushState() beforeEach -> $form = affix('form[action="/path/to"][method="put"][up-target=".response"]') $form.append('') $form.append('') affix('.response').text('old-text') @promise = up.submit($form) @request = @lastRequest() expect(@request.url).toMatch /\/path\/to$/ expect(@request.method).toBe 'PUT' expect(@request.data()).toEqual field1: ['value1'] field2: ['value2'] it 'submits the given form and replaces the target with the response', (done) -> @respondWith """ text-before