Repository: angular/angular.js
File: test/jqLiteSpec.js (JavaScript)

Code before:
          var element = jqLite('<div></div>');

          container.append(element);
          element.append(jqLite(htmlString));

          window.setTimeout(function() {
            expect(window.xss).not.toHaveBeenCalledWith(index);
            donePartial();
          }, 1000);
        });
      });

      it('should allow to restore legacy insecure behavior', function() {
        // jQuery doesn't have this API.
        if (!_jqLiteMode) return;

        // eslint-disable-next-line new-cap
        angular.UNSAFE_restoreLegacyJqLiteXHTMLReplacement();

        var elem = jqLite('<div/><span/>');
        expect(elem.length).toBe(2);
        expect(elem[0].nodeName.toLowerCase()).toBe('div');
        expect(elem[1].nodeName.toLowerCase()).toBe('span');
      });
    });
  });

  describe('_data', function() {
    it('should provide access to the events present on the element', function() {
      var element = jqLite('<i>foo</i>');
      expect(angular.element._data(element[0]).events).toBeUndefined();

      element.on('click', function() { });
      expect(angular.element._data(element[0]).events.click).toBeDefined();
    });
  });

  describe('inheritedData', function() {

    it('should retrieve data attached to the current element', function() {
      var element = jqLite('<i>foo</i>');
      element.data('myData', 'abc');
      expect(element.inheritedData('myData')).toBe('abc');
      dealoc(element);
    });


    it('should walk up the dom to find data', function() {
      var element = jqLite('<ul><li><p><b>deep deep</b><p></li></ul>');
      var deepChild = jqLite(element[0].getElementsByTagName('b')[0]);
      element.data('myData', 'abc');

Review comment (security):
I think that the following test cases were useful for jQuery (which used a slightly different regex) but not for jqLite's [XHTML_TAG_REGEXP][1] (i.e. they would pass without the changes in this PR, so they don't add much value):

- `'<img alt="<x" title="/><img src=url404 onerror=xss(0)>">'`
- `'<img alt="\n<x" title="/>\n<img src=url404 onerror=xss(1)>">'`
- `'<foo" alt="" title="/><img src=url404 onerror=xss(8)>">'`
- `'<img alt="<x" title="" src="/><img src=url404 onerror=xss(9)>">'`

(That is because jQuery's tegex would match `"` as part of the tag name, while jqLite won't.)

[1]: https://github.com/angular/angular.js/blob/1e45057ae6a7f929a8e37ee7c5ff77f419390b51/src/jqLite.js#L180

Code after:
            delete window.xss;
            done();
          }
        }

        jqLite(document.body).append(container);
        window.xss = jasmine.createSpy('xss');

        // Thanks to Masato Kinugawa from Cure53 for providing the following test cases.
        // Note: below test cases need to invoke the xss function with consecutive
        // decimal parameters for the assertions to be correct.
        forEach([
          '<img alt="<x" title="/><img src=url404 onerror=xss(0)>">',
          '<img alt="\n<x" title="/>\n<img src=url404 onerror=xss(1)>">',
          '<style><style/><img src=url404 onerror=xss(2)>',
          '<xmp><xmp/><img src=url404 onerror=xss(3)>',
          '<title><title /><img src=url404 onerror=xss(4)>',
          '<iframe><iframe/><img src=url404 onerror=xss(5)>',
          '<noframes><noframes/><img src=url404 onerror=xss(6)>',
          '<noscript><noscript/><img src=url404 onerror=xss(7)>',
          '<foo" alt="" title="/><img src=url404 onerror=xss(8)>">',
          '<img alt="<x" title="" src="/><img src=url404 onerror=xss(9)>">',
          '<noscript/><img src=url404 onerror=xss(10)>',
          '<noembed><noembed/><img src=url404 onerror=xss(11)>',

          '<option><style></option></select><img src=url404 onerror=xss(12)></style>'
        ], function(htmlString, index) {
          var element = jqLite('<div></div>');

          container.append(element);
          element.append(jqLite(htmlString));

          window.setTimeout(function() {
            expect(window.xss).not.toHaveBeenCalledWith(index);
            donePartial();
          }, 1000);
        });
      });

      it('should allow to restore legacy insecure behavior', function() {
        // jQuery doesn't have this API.
        if (!_jqLiteMode) return;

        // eslint-disable-next-line new-cap
        angular.UNSAFE_restoreLegacyJqLiteXHTMLReplacement();

        var elem = jqLite('<div/><span/>');
        expect(elem.length).toBe(2);
        expect(elem[0].nodeName.toLowerCase()).toBe('div');
        expect(elem[1].nodeName.toLowerCase()).toBe('span');
      });