diff options
| author | Brian Ford | 2013-08-09 10:02:48 -0700 | 
|---|---|---|
| committer | Igor Minar | 2013-08-09 11:54:35 -0700 | 
| commit | 94ec84e7b9c89358dc00e4039009af9e287bbd05 (patch) | |
| tree | b06c84f1329a8e4fd6ce75b6bbde64bdf4d0e60e /test/ngTouch/directive/ngClickSpec.js | |
| parent | 0d17838a0881376be3c226a68242b5d74dac208b (diff) | |
| download | angular.js-94ec84e7b9c89358dc00e4039009af9e287bbd05.tar.bz2 | |
chore(ngMobile): rename module ngTouch and file to angular-touch.js
BREAKING CHANGE: since all the code in the ngMobile module is touch related,
we are renaming the module to ngTouch.
To migrate, please replace all references to "ngMobile" with "ngTouch" and
"angular-mobile.js" to "angular-touch.js".
Closes #3526
Diffstat (limited to 'test/ngTouch/directive/ngClickSpec.js')
| -rw-r--r-- | test/ngTouch/directive/ngClickSpec.js | 380 | 
1 files changed, 380 insertions, 0 deletions
| diff --git a/test/ngTouch/directive/ngClickSpec.js b/test/ngTouch/directive/ngClickSpec.js new file mode 100644 index 00000000..2a11adee --- /dev/null +++ b/test/ngTouch/directive/ngClickSpec.js @@ -0,0 +1,380 @@ +'use strict'; + +describe('ngClick (touch)', function() { +  var element, time, orig_now; + +  // TODO(braden): Once we have other touch-friendly browsers on CI, allow them here. +  // Currently Firefox and IE refuse to fire touch events. +  var chrome = /chrome/.test(navigator.userAgent.toLowerCase()); +  if (!chrome) { +    return; +  } + +  function mockTime() { +    return time; +  } + + +  beforeEach(function() { +    module('ngTouch'); +    orig_now = Date.now; +    time = 0; +    Date.now = mockTime; +  }); + +  afterEach(function() { +    dealoc(element); +    Date.now = orig_now; +  }); + + +  it('should get called on a tap', inject(function($rootScope, $compile) { +    element = $compile('<div ng-click="tapped = true"></div>')($rootScope); +    $rootScope.$digest(); +    expect($rootScope.tapped).toBeUndefined(); + +    browserTrigger(element, 'touchstart'); +    browserTrigger(element, 'touchend'); +    expect($rootScope.tapped).toEqual(true); +  })); + + +  it('should pass event object', inject(function($rootScope, $compile) { +    element = $compile('<div ng-click="event = $event"></div>')($rootScope); +    $rootScope.$digest(); + +    browserTrigger(element, 'touchstart'); +    browserTrigger(element, 'touchend'); +    expect($rootScope.event).toBeDefined(); +  })); + + +  it('should not click if the touch is held too long', inject(function($rootScope, $compile, $rootElement) { +    element = $compile('<div ng-click="count = count + 1"></div>')($rootScope); +    $rootElement.append(element); +    $rootScope.count = 0; +    $rootScope.$digest(); + +    expect($rootScope.count).toBe(0); + +    time = 10; +    browserTrigger(element, 'touchstart', [], 10, 10); + +    time = 900; +    browserTrigger(element, 'touchend', [], 10, 10); + +    expect($rootScope.count).toBe(0); +  })); + + +  it('should not click if the touchend is too far away', inject(function($rootScope, $compile, $rootElement) { +    element = $compile('<div ng-click="tapped = true"></div>')($rootScope); +    $rootElement.append(element); +    $rootScope.$digest(); + +    expect($rootScope.tapped).toBeUndefined(); + +    browserTrigger(element, 'touchstart', [], 10, 10); +    browserTrigger(element, 'touchend', [], 400, 400); + +    expect($rootScope.tapped).toBeUndefined(); +  })); + + +  it('should not click if a touchmove comes before touchend', inject(function($rootScope, $compile, $rootElement) { +    element = $compile('<div ng-click="tapped = true"></div>')($rootScope); +    $rootElement.append(element); +    $rootScope.$digest(); + +    expect($rootScope.tapped).toBeUndefined(); + +    browserTrigger(element, 'touchstart', [], 10, 10); +    browserTrigger(element, 'touchmove'); +    browserTrigger(element, 'touchend', [], 400, 400); + +    expect($rootScope.tapped).toBeUndefined(); +  })); + +  it('should add the CSS class while the element is held down, and then remove it', inject(function($rootScope, $compile, $rootElement) { +    element = $compile('<div ng-click="tapped = true"></div>')($rootScope); +    $rootElement.append(element); +    $rootScope.$digest(); +    expect($rootScope.tapped).toBeUndefined(); + +    var CSS_CLASS = 'ng-click-active'; + +    expect(element.hasClass(CSS_CLASS)).toBe(false); +    browserTrigger(element, 'touchstart', 10, 10); +    expect(element.hasClass(CSS_CLASS)).toBe(true); +    browserTrigger(element, 'touchend', 10, 10); +    expect(element.hasClass(CSS_CLASS)).toBe(false); +    expect($rootScope.tapped).toBe(true); +  })); + + +  describe('the clickbuster', function() { +    var element1, element2; + +    beforeEach(inject(function($rootElement, $document) { +      $document.find('body').append($rootElement); +    })); + +    afterEach(inject(function($document) { +      $document.find('body').html(''); +    })); + + +    it('should cancel the following click event', inject(function($rootScope, $compile, $rootElement, $document) { +      element = $compile('<div ng-click="count = count + 1"></div>')($rootScope); +      $rootElement.append(element); + +      $rootScope.count = 0; +      $rootScope.$digest(); + +      expect($rootScope.count).toBe(0); + +      // Fire touchstart at 10ms, touchend at 50ms, the click at 300ms. +      time = 10; +      browserTrigger(element, 'touchstart', [], 10, 10); + +      time = 50; +      browserTrigger(element, 'touchend', [], 10, 10); + +      expect($rootScope.count).toBe(1); + +      time = 100; +      browserTrigger(element, 'click', [], 10, 10); + +      expect($rootScope.count).toBe(1); +    })); + + +    it('should cancel the following click event even when the element has changed', inject( +        function($rootScope, $compile, $rootElement) { +      $rootElement.append( +          '<div ng-show="!tapped" ng-click="count1 = count1 + 1; tapped = true">x</div>' + +          '<div ng-show="tapped" ng-click="count2 = count2 + 1">y</div>' +      ); +      $compile($rootElement)($rootScope); + +      element1 = $rootElement.find('div').eq(0); +      element2 = $rootElement.find('div').eq(1); + +      $rootScope.count1 = 0; +      $rootScope.count2 = 0; + +      $rootScope.$digest(); + +      expect($rootScope.count1).toBe(0); +      expect($rootScope.count2).toBe(0); + +      time = 10; +      browserTrigger(element1, 'touchstart', [], 10, 10); + +      time = 50; +      browserTrigger(element1, 'touchend', [], 10, 10); + +      expect($rootScope.count1).toBe(1); + +      time = 100; +      browserTrigger(element2, 'click', [], 10, 10); + +      expect($rootScope.count1).toBe(1); +      expect($rootScope.count2).toBe(0); +    })); + + +    it('should not cancel clicks on distant elements', inject(function($rootScope, $compile, $rootElement) { +      $rootElement.append( +          '<div ng-click="count1 = count1 + 1">x</div>' + +          '<div ng-click="count2 = count2 + 1">y</div>' +      ); +      $compile($rootElement)($rootScope); + +      element1 = $rootElement.find('div').eq(0); +      element2 = $rootElement.find('div').eq(1); + +      $rootScope.count1 = 0; +      $rootScope.count2 = 0; + +      $rootScope.$digest(); + +      expect($rootScope.count1).toBe(0); +      expect($rootScope.count2).toBe(0); + +      time = 10; +      browserTrigger(element1, 'touchstart', [], 10, 10); + +      time = 50; +      browserTrigger(element1, 'touchend', [], 10, 10); + +      expect($rootScope.count1).toBe(1); + +      time = 90; +      // Verify that it is blured so we don't get soft-keyboard +      element1[0].blur = jasmine.createSpy('blur'); +      browserTrigger(element1, 'click', [], 10, 10); +      expect(element1[0].blur).toHaveBeenCalled(); + +      expect($rootScope.count1).toBe(1); + +      time = 100; +      browserTrigger(element1, 'touchstart', [], 10, 10); + +      time = 130; +      browserTrigger(element1, 'touchend', [], 10, 10); + +      expect($rootScope.count1).toBe(2); + +      // Click on other element that should go through. +      time = 150; +      browserTrigger(element2, 'touchstart', [], 100, 120); +      browserTrigger(element2, 'touchend', [], 100, 120); +      browserTrigger(element2, 'click', [], 100, 120); + +      expect($rootScope.count2).toBe(1); + +      // Click event for the element that should be busted. +      time = 200; +      browserTrigger(element1, 'click', [], 10, 10); + +      expect($rootScope.count1).toBe(2); +      expect($rootScope.count2).toBe(1); +    })); + + +    it('should not cancel clicks that come long after', inject(function($rootScope, $compile) { +      element1 = $compile('<div ng-click="count = count + 1"></div>')($rootScope); + +      $rootScope.count = 0; + +      $rootScope.$digest(); + +      expect($rootScope.count).toBe(0); + +      time = 10; +      browserTrigger(element1, 'touchstart', [], 10, 10); + +      time = 50; +      browserTrigger(element1, 'touchend', [], 10, 10); +      expect($rootScope.count).toBe(1); + +      time = 2700; +      browserTrigger(element1, 'click', [], 10, 10); + +      expect($rootScope.count).toBe(2); +    })); + + +    it('should not cancel clicks that come long after', inject(function($rootScope, $compile) { +      element1 = $compile('<div ng-click="count = count + 1"></div>')($rootScope); + +      $rootScope.count = 0; + +      $rootScope.$digest(); + +      expect($rootScope.count).toBe(0); + +      time = 10; +      browserTrigger(element1, 'touchstart', [], 10, 10); + +      time = 50; +      browserTrigger(element1, 'touchend', [], 10, 10); + +      expect($rootScope.count).toBe(1); + +      time = 2700; +      browserTrigger(element1, 'click', [], 10, 10); + +      expect($rootScope.count).toBe(2); +    })); +  }); + + +  describe('click fallback', function() { + +    it('should treat a click as a tap on desktop', inject(function($rootScope, $compile) { +      element = $compile('<div ng-click="tapped = true"></div>')($rootScope); +      $rootScope.$digest(); +      expect($rootScope.tapped).toBeFalsy(); + +      browserTrigger(element, 'click'); +      expect($rootScope.tapped).toEqual(true); +    })); + + +    it('should pass event object', inject(function($rootScope, $compile) { +      element = $compile('<div ng-click="event = $event"></div>')($rootScope); +      $rootScope.$digest(); + +      browserTrigger(element, 'click'); +      expect($rootScope.event).toBeDefined(); +    })); +  }); + + +  describe('disabled state', function() { +    it('should not trigger click if ngDisabled is true', inject(function($rootScope, $compile) { +      element = $compile('<div ng-click="event = $event" ng-disabled="disabled"></div>')($rootScope); +      $rootScope.disabled = true; +      $rootScope.$digest(); + +      browserTrigger(element, 'touchstart', [], 10, 10); +      browserTrigger(element, 'touchend', [], 10, 10); + +      expect($rootScope.event).toBeUndefined(); +    })); +    it('should trigger click if ngDisabled is false', inject(function($rootScope, $compile) { +      element = $compile('<div ng-click="event = $event" ng-disabled="disabled"></div>')($rootScope); +      $rootScope.disabled = false; +      $rootScope.$digest(); + +      browserTrigger(element, 'touchstart', [], 10, 10); +      browserTrigger(element, 'touchend', [], 10, 10); + +      expect($rootScope.event).toBeDefined(); +    })); +    it('should not trigger click if regular disabled is true', inject(function($rootScope, $compile) { +      element = $compile('<div ng-click="event = $event" disabled="true"></div>')($rootScope); + +      browserTrigger(element, 'touchstart', [], 10, 10); +      browserTrigger(element, 'touchend', [], 10, 10); + +      expect($rootScope.event).toBeUndefined(); +    })); +    it('should not trigger click if regular disabled is present', inject(function($rootScope, $compile) { +      element = $compile('<button ng-click="event = $event" disabled ></button>')($rootScope); + +      browserTrigger(element, 'touchstart', [], 10, 10); +      browserTrigger(element, 'touchend', [], 10, 10); + +      expect($rootScope.event).toBeUndefined(); +    })); +    it('should trigger click if regular disabled is not present', inject(function($rootScope, $compile) { +      element = $compile('<div ng-click="event = $event" ></div>')($rootScope); + +      browserTrigger(element, 'touchstart', [], 10, 10); +      browserTrigger(element, 'touchend', [], 10, 10); + +      expect($rootScope.event).toBeDefined(); +    })); +  }); + + +  describe('the normal click event', function() { +    it('should be capturable by other handlers', inject(function($rootScope, $compile) { +      var called = false; + +      element = $compile('<div ng-click="event = $event" ></div>')($rootScope); + +      element.on('click', function() { +        called = true; +      }); + +      browserTrigger(element, 'touchstart', [], 10, 10); +      browserTrigger(element, 'touchend', [], 10, 10); + +      expect(called).toEqual(true); +    })); +  }); +}); | 
