{"action":"created","comment":{"url":"https://api.github.com/repos/ampproject/amphtml/pulls/comments/81577390","pull_request_review_id":2546632,"id":81577390,"diff_hunk":"@@ -0,0 +1,307 @@\n+/**\n+ * Copyright 2016 The AMP HTML Authors. All Rights Reserved.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *      http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS-IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+import {AmpAdLifecycleReporter} from '../performance';\n+import {EXPERIMENT_ATTRIBUTE} from '../traffic-experiments';\n+import {childElements} from '../../../../src/dom';\n+import {createIframePromise} from '../../../../testing/iframe';\n+import * as sinon from 'sinon';\n+\n+/**\n+ * Verify that `address` matches all of the patterns in `matchlist`.\n+ *\n+ * @param {!string} address\n+ * @param {!Array<!RegExp>} matchList\n+ */\n+function expectMatchesAll(address, matchList) {\n+  matchList.forEach(m => {\n+    expect(address).to.match(m);\n+  });\n+}\n+\n+/**\n+ * Whether `element` is an `img` DOM node.\n+ * @param {!Element} element\n+ * @returns {boolean}\n+ */\n+function isImgNode(element) {\n+  return element.tagName == 'IMG';\n+}\n+\n+/**\n+ * Verify that `element` has at least one sibling DOM node that is an\n+ * `img` tag whose `src` matches all of the patterns in `matchList`.\n+ *\n+ * @param {!Element} element\n+ * @param {!Array<!RegExp>} matchList\n+ */\n+function expectHasSiblingImgMatchingAll(element, matchList) {\n+  const imgSiblings = childElements(\n+      element.parentElement, e => isImgNode(e));\n+  expect(imgSiblings).to.not.be.empty;\n+  const result = imgSiblings.some(e => {\n+    const src = e.getAttribute('src');\n+    return matchList.map(m => m.test(src)).every(x => x);\n+  });\n+  expect(result, 'No element sibling of ' + element + ' matched all patterns')\n+      .to.be.true;\n+}\n+\n+// From\n+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FRegular_Expressions\n+/**\n+ * Escape a string for use as a literal inside a regular expression.\n+ * @param {!string} string\n+ * @returns {!string}\n+ * @private\n+ */\n+function escapeRegExp_(string) {\n+  return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n+}\n+\n+describe('AmpAdLifecycleReporter', () => {\n+  let sandbox;\n+  let emitPingSpy;\n+  beforeEach(() => {\n+    sandbox = sinon.sandbox.create();\n+    emitPingSpy = sandbox.spy(AmpAdLifecycleReporter.prototype, 'emitPing_');\n+  });\n+  afterEach(() => {\n+    sandbox.restore();\n+  });\n+\n+  describe('#sendPing', () => {\n+    it('should request a single ping and insert into DOM', () => {\n+      return createIframePromise(false).then(fixture => {\n+        const win = fixture.win;\n+        const doc = fixture.doc;\n+        const elem = doc.createElement('div');\n+        doc.body.appendChild(elem);\n+        const reporter = new AmpAdLifecycleReporter(win, elem, 'test_foo');","path":"ads/google/a4a/test/test-performance.js","position":93,"original_position":93,"commit_id":"e2c5ec845fe165e69f290277ae96989eb20beace","original_commit_id":"e2c5ec845fe165e69f290277ae96989eb20beace","user":{"login":"lannka","id":8496897,"avatar_url":"https://avatars.githubusercontent.com/u/8496897?v=3","gravatar_id":"","url":"https://api.github.com/users/lannka","html_url":"https://github.com/lannka","followers_url":"https://api.github.com/users/lannka/followers","following_url":"https://api.github.com/users/lannka/following{/other_user}","gists_url":"https://api.github.com/users/lannka/gists{/gist_id}","starred_url":"https://api.github.com/users/lannka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lannka/subscriptions","organizations_url":"https://api.github.com/users/lannka/orgs","repos_url":"https://api.github.com/users/lannka/repos","events_url":"https://api.github.com/users/lannka/events{/privacy}","received_events_url":"https://api.github.com/users/lannka/received_events","type":"User","site_admin":false},"body":"probably it's worth to extract the fixture logic into `beforeEach`. you can do return promise in `beforeEach`","created_at":"2016-10-03T15:42:28Z","updated_at":"2016-10-03T15:52:46Z","html_url":"https://github.com/ampproject/amphtml/pull/5373#discussion_r81577390","pull_request_url":"https://api.github.com/repos/ampproject/amphtml/pulls/5373","_links":{"self":{"href":"https://api.github.com/repos/ampproject/amphtml/pulls/comments/81577390"},"html":{"href":"https://github.com/ampproject/amphtml/pull/5373#discussion_r81577390"},"pull_request":{"href":"https://api.github.com/repos/ampproject/amphtml/pulls/5373"}}},"pull_request":{"url":"https://api.github.com/repos/ampproject/amphtml/pulls/5373","id":87716167,"html_url":"https://github.com/ampproject/amphtml/pull/5373","diff_url":"https://github.com/ampproject/amphtml/pull/5373.diff","patch_url":"https://github.com/ampproject/amphtml/pull/5373.patch","issue_url":"https://api.github.com/repos/ampproject/amphtml/issues/5373","number":5373,"state":"open","locked":false,"title":"Performance/profiling pings for A4A","user":{"login":"tdrl","id":17705064,"avatar_url":"https://avatars.githubusercontent.com/u/17705064?v=3","gravatar_id":"","url":"https://api.github.com/users/tdrl","html_url":"https://github.com/tdrl","followers_url":"https://api.github.com/users/tdrl/followers","following_url":"https://api.github.com/users/tdrl/following{/other_user}","gists_url":"https://api.github.com/users/tdrl/gists{/gist_id}","starred_url":"https://api.github.com/users/tdrl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tdrl/subscriptions","organizations_url":"https://api.github.com/users/tdrl/orgs","repos_url":"https://api.github.com/users/tdrl/repos","events_url":"https://api.github.com/users/tdrl/events{/privacy}","received_events_url":"https://api.github.com/users/tdrl/received_events","type":"User","site_admin":false},"body":"Includes a few pings in standard 3p amp-ad, to establish baselines.  Note that all pings are behind tests for `type == doubleclick` or `type == adsense`, so that no pings are generated for non-Google ad types.","created_at":"2016-10-03T13:28:09Z","updated_at":"2016-10-03T15:52:47Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1d7286563b4f0b3e1048b1dc5f07a2180302612b","assignee":{"login":"keithwrightbos","id":1766447,"avatar_url":"https://avatars.githubusercontent.com/u/1766447?v=3","gravatar_id":"","url":"https://api.github.com/users/keithwrightbos","html_url":"https://github.com/keithwrightbos","followers_url":"https://api.github.com/users/keithwrightbos/followers","following_url":"https://api.github.com/users/keithwrightbos/following{/other_user}","gists_url":"https://api.github.com/users/keithwrightbos/gists{/gist_id}","starred_url":"https://api.github.com/users/keithwrightbos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/keithwrightbos/subscriptions","organizations_url":"https://api.github.com/users/keithwrightbos/orgs","repos_url":"https://api.github.com/users/keithwrightbos/repos","events_url":"https://api.github.com/users/keithwrightbos/events{/privacy}","received_events_url":"https://api.github.com/users/keithwrightbos/received_events","type":"User","site_admin":false},"assignees":[{"login":"keithwrightbos","id":1766447,"avatar_url":"https://avatars.githubusercontent.com/u/1766447?v=3","gravatar_id":"","url":"https://api.github.com/users/keithwrightbos","html_url":"https://github.com/keithwrightbos","followers_url":"https://api.github.com/users/keithwrightbos/followers","following_url":"https://api.github.com/users/keithwrightbos/following{/other_user}","gists_url":"https://api.github.com/users/keithwrightbos/gists{/gist_id}","starred_url":"https://api.github.com/users/keithwrightbos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/keithwrightbos/subscriptions","organizations_url":"https://api.github.com/users/keithwrightbos/orgs","repos_url":"https://api.github.com/users/keithwrightbos/repos","events_url":"https://api.github.com/users/keithwrightbos/events{/privacy}","received_events_url":"https://api.github.com/users/keithwrightbos/received_events","type":"User","site_admin":false},{"login":"lannka","id":8496897,"avatar_url":"https://avatars.githubusercontent.com/u/8496897?v=3","gravatar_id":"","url":"https://api.github.com/users/lannka","html_url":"https://github.com/lannka","followers_url":"https://api.github.com/users/lannka/followers","following_url":"https://api.github.com/users/lannka/following{/other_user}","gists_url":"https://api.github.com/users/lannka/gists{/gist_id}","starred_url":"https://api.github.com/users/lannka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lannka/subscriptions","organizations_url":"https://api.github.com/users/lannka/orgs","repos_url":"https://api.github.com/users/lannka/repos","events_url":"https://api.github.com/users/lannka/events{/privacy}","received_events_url":"https://api.github.com/users/lannka/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/ampproject/amphtml/pulls/5373/commits","review_comments_url":"https://api.github.com/repos/ampproject/amphtml/pulls/5373/comments","review_comment_url":"https://api.github.com/repos/ampproject/amphtml/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ampproject/amphtml/issues/5373/comments","statuses_url":"https://api.github.com/repos/ampproject/amphtml/statuses/e2c5ec845fe165e69f290277ae96989eb20beace","head":{"label":"google:a4a-csi","ref":"a4a-csi","sha":"e2c5ec845fe165e69f290277ae96989eb20beace","user":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":51965089,"name":"amphtml","full_name":"google/amphtml","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/amphtml","description":"AMP HTML source code, samples, and documentation.  See below for more info.","fork":true,"url":"https://api.github.com/repos/google/amphtml","forks_url":"https://api.github.com/repos/google/amphtml/forks","keys_url":"https://api.github.com/repos/google/amphtml/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/amphtml/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/amphtml/teams","hooks_url":"https://api.github.com/repos/google/amphtml/hooks","issue_events_url":"https://api.github.com/repos/google/amphtml/issues/events{/number}","events_url":"https://api.github.com/repos/google/amphtml/events","assignees_url":"https://api.github.com/repos/google/amphtml/assignees{/user}","branches_url":"https://api.github.com/repos/google/amphtml/branches{/branch}","tags_url":"https://api.github.com/repos/google/amphtml/tags","blobs_url":"https://api.github.com/repos/google/amphtml/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/amphtml/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/amphtml/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/amphtml/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/amphtml/statuses/{sha}","languages_url":"https://api.github.com/repos/google/amphtml/languages","stargazers_url":"https://api.github.com/repos/google/amphtml/stargazers","contributors_url":"https://api.github.com/repos/google/amphtml/contributors","subscribers_url":"https://api.github.com/repos/google/amphtml/subscribers","subscription_url":"https://api.github.com/repos/google/amphtml/subscription","commits_url":"https://api.github.com/repos/google/amphtml/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/amphtml/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/amphtml/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/amphtml/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/amphtml/contents/{+path}","compare_url":"https://api.github.com/repos/google/amphtml/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/amphtml/merges","archive_url":"https://api.github.com/repos/google/amphtml/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/amphtml/downloads","issues_url":"https://api.github.com/repos/google/amphtml/issues{/number}","pulls_url":"https://api.github.com/repos/google/amphtml/pulls{/number}","milestones_url":"https://api.github.com/repos/google/amphtml/milestones{/number}","notifications_url":"https://api.github.com/repos/google/amphtml/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/amphtml/labels{/name}","releases_url":"https://api.github.com/repos/google/amphtml/releases{/id}","deployments_url":"https://api.github.com/repos/google/amphtml/deployments","created_at":"2016-02-18T00:04:16Z","updated_at":"2016-10-03T07:02:35Z","pushed_at":"2016-10-03T15:32:04Z","git_url":"git://github.com/google/amphtml.git","ssh_url":"git@github.com:google/amphtml.git","clone_url":"https://github.com/google/amphtml.git","svn_url":"https://github.com/google/amphtml","homepage":"https://ampproject.org","size":165778,"stargazers_count":39,"watchers_count":39,"language":"JavaScript","has_issues":false,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":9,"mirror_url":null,"open_issues_count":4,"forks":9,"open_issues":4,"watchers":39,"default_branch":"master"}},"base":{"label":"ampproject:master","ref":"master","sha":"1cf62887fa6febbd54eda0cb6b33343e1d0b48bf","user":{"login":"ampproject","id":14114390,"avatar_url":"https://avatars.githubusercontent.com/u/14114390?v=3","gravatar_id":"","url":"https://api.github.com/users/ampproject","html_url":"https://github.com/ampproject","followers_url":"https://api.github.com/users/ampproject/followers","following_url":"https://api.github.com/users/ampproject/following{/other_user}","gists_url":"https://api.github.com/users/ampproject/gists{/gist_id}","starred_url":"https://api.github.com/users/ampproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ampproject/subscriptions","organizations_url":"https://api.github.com/users/ampproject/orgs","repos_url":"https://api.github.com/users/ampproject/repos","events_url":"https://api.github.com/users/ampproject/events{/privacy}","received_events_url":"https://api.github.com/users/ampproject/received_events","type":"Organization","site_admin":false},"repo":{"id":41766002,"name":"amphtml","full_name":"ampproject/amphtml","owner":{"login":"ampproject","id":14114390,"avatar_url":"https://avatars.githubusercontent.com/u/14114390?v=3","gravatar_id":"","url":"https://api.github.com/users/ampproject","html_url":"https://github.com/ampproject","followers_url":"https://api.github.com/users/ampproject/followers","following_url":"https://api.github.com/users/ampproject/following{/other_user}","gists_url":"https://api.github.com/users/ampproject/gists{/gist_id}","starred_url":"https://api.github.com/users/ampproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ampproject/subscriptions","organizations_url":"https://api.github.com/users/ampproject/orgs","repos_url":"https://api.github.com/users/ampproject/repos","events_url":"https://api.github.com/users/ampproject/events{/privacy}","received_events_url":"https://api.github.com/users/ampproject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ampproject/amphtml","description":"AMP HTML source code, samples, and documentation.  See below for more info.","fork":false,"url":"https://api.github.com/repos/ampproject/amphtml","forks_url":"https://api.github.com/repos/ampproject/amphtml/forks","keys_url":"https://api.github.com/repos/ampproject/amphtml/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ampproject/amphtml/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ampproject/amphtml/teams","hooks_url":"https://api.github.com/repos/ampproject/amphtml/hooks","issue_events_url":"https://api.github.com/repos/ampproject/amphtml/issues/events{/number}","events_url":"https://api.github.com/repos/ampproject/amphtml/events","assignees_url":"https://api.github.com/repos/ampproject/amphtml/assignees{/user}","branches_url":"https://api.github.com/repos/ampproject/amphtml/branches{/branch}","tags_url":"https://api.github.com/repos/ampproject/amphtml/tags","blobs_url":"https://api.github.com/repos/ampproject/amphtml/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ampproject/amphtml/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ampproject/amphtml/git/refs{/sha}","trees_url":"https://api.github.com/repos/ampproject/amphtml/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ampproject/amphtml/statuses/{sha}","languages_url":"https://api.github.com/repos/ampproject/amphtml/languages","stargazers_url":"https://api.github.com/repos/ampproject/amphtml/stargazers","contributors_url":"https://api.github.com/repos/ampproject/amphtml/contributors","subscribers_url":"https://api.github.com/repos/ampproject/amphtml/subscribers","subscription_url":"https://api.github.com/repos/ampproject/amphtml/subscription","commits_url":"https://api.github.com/repos/ampproject/amphtml/commits{/sha}","git_commits_url":"https://api.github.com/repos/ampproject/amphtml/git/commits{/sha}","comments_url":"https://api.github.com/repos/ampproject/amphtml/comments{/number}","issue_comment_url":"https://api.github.com/repos/ampproject/amphtml/issues/comments{/number}","contents_url":"https://api.github.com/repos/ampproject/amphtml/contents/{+path}","compare_url":"https://api.github.com/repos/ampproject/amphtml/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ampproject/amphtml/merges","archive_url":"https://api.github.com/repos/ampproject/amphtml/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ampproject/amphtml/downloads","issues_url":"https://api.github.com/repos/ampproject/amphtml/issues{/number}","pulls_url":"https://api.github.com/repos/ampproject/amphtml/pulls{/number}","milestones_url":"https://api.github.com/repos/ampproject/amphtml/milestones{/number}","notifications_url":"https://api.github.com/repos/ampproject/amphtml/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ampproject/amphtml/labels{/name}","releases_url":"https://api.github.com/repos/ampproject/amphtml/releases{/id}","deployments_url":"https://api.github.com/repos/ampproject/amphtml/deployments","created_at":"2015-09-01T22:10:53Z","updated_at":"2016-10-03T14:05:29Z","pushed_at":"2016-10-03T13:47:50Z","git_url":"git://github.com/ampproject/amphtml.git","ssh_url":"git@github.com:ampproject/amphtml.git","clone_url":"https://github.com/ampproject/amphtml.git","svn_url":"https://github.com/ampproject/amphtml","homepage":"https://ampproject.org","size":205525,"stargazers_count":8708,"watchers_count":8708,"language":"JavaScript","has_issues":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":1289,"mirror_url":null,"open_issues_count":822,"forks":1289,"open_issues":822,"watchers":8708,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ampproject/amphtml/pulls/5373"},"html":{"href":"https://github.com/ampproject/amphtml/pull/5373"},"issue":{"href":"https://api.github.com/repos/ampproject/amphtml/issues/5373"},"comments":{"href":"https://api.github.com/repos/ampproject/amphtml/issues/5373/comments"},"review_comments":{"href":"https://api.github.com/repos/ampproject/amphtml/pulls/5373/comments"},"review_comment":{"href":"https://api.github.com/repos/ampproject/amphtml/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ampproject/amphtml/pulls/5373/commits"},"statuses":{"href":"https://api.github.com/repos/ampproject/amphtml/statuses/e2c5ec845fe165e69f290277ae96989eb20beace"}}}}
{"actor":{"display_login":"lannka"}}