Create resemble diff mode for image diff plugin

Change-Id: I66a5c2758d4262b9658c3e26865208689ca562f6
diff --git a/gr-resemble-diff-mode/gr-resemble-diff-mode.html b/gr-resemble-diff-mode/gr-resemble-diff-mode.html
new file mode 100644
index 0000000..6ec3b16
--- /dev/null
+++ b/gr-resemble-diff-mode/gr-resemble-diff-mode.html
@@ -0,0 +1,33 @@
+<!--
+Copyright (C) 2018 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<script src="../node_modules/resemblejs/resemble.js"></script>
+<dom-module id="gr-resemble-diff-mode">
+  <template>
+    <style>
+      :host {
+        display: block;
+      }
+      #imageDiff {
+        border: 1px solid var(--border-color, #ddd);
+        display: block;
+        margin: 0 auto;
+      }
+    </style>
+    <img id="imageDiff">
+  </template>
+  <script src="gr-resemble-diff-mode.js"></script>
+</dom-module>
\ No newline at end of file
diff --git a/gr-resemble-diff-mode/gr-resemble-diff-mode.js b/gr-resemble-diff-mode/gr-resemble-diff-mode.js
new file mode 100644
index 0000000..1c9076e
--- /dev/null
+++ b/gr-resemble-diff-mode/gr-resemble-diff-mode.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+(function() {
+  'use strict';
+
+  Polymer({
+    is: 'gr-resemble-diff-mode',
+
+    properties: {
+      baseImage: Object,
+      revisonImage: Object,
+    },
+
+    observers: [
+      '_handleImageDiff(baseImage, revisionImage)',
+    ],
+
+    _handleImageDiff(base, revision) {
+      if (base && revision) {
+        const baseEncoded = this.getDataUrl(base);
+        const revisionEncoded = this.getDataUrl(revision);
+        return this.compareImages(baseEncoded, revisionEncoded).then(src => {
+          this.$.imageDiff.setAttribute('src', src);
+        });
+      }
+    },
+
+    compareImages(baseEncoded, revisionEncoded) {
+      return new Promise((resolve, reject) =>
+          resemble(baseEncoded).compareTo(revisionEncoded).onComplete(data => {
+            if (data.error) {
+              reject();
+            } else {
+              resolve(data.getImageDataUrl());
+            }
+          })
+      );
+    },
+
+    getDataUrl(image) {
+      return 'data:' + image['type'] + ';base64,' + image['body'];
+    },
+  });
+})();
\ No newline at end of file
diff --git a/gr-resemble-diff-mode/gr-resemble-diff-mode_test.html b/gr-resemble-diff-mode/gr-resemble-diff-mode_test.html
new file mode 100644
index 0000000..65460cc
--- /dev/null
+++ b/gr-resemble-diff-mode/gr-resemble-diff-mode_test.html
@@ -0,0 +1,83 @@
+<!--
+Copyright (C) 2018 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+<title>resemble-diff-mode</title>
+
+<link rel="import" href="../node_modules/polymer/polymer.html">
+<link rel="import" href="../node_modules/@polymer/test-fixture/test-fixture.html">
+<link rel="import" href="../node_modules/iron-test-helpers/iron-test-helpers.html">
+<link rel="import" href="./gr-resemble-diff-mode.html">
+
+<script>void(0);</script>
+
+<script src="../node_modules/webcomponents.js/webcomponents-lite.min.js"></script>
+<script src="../node_modules/web-component-tester/browser.js"></script>
+<script src="../node_modules/@polymer/sinonjs/sinon.js"></script>
+
+<test-fixture id="basicFixture">
+  <template>
+    <gr-resemble-diff-mode>
+    </gr-resemble-diff-mode>
+  </template>
+</test-fixture>
+
+<script>
+  suite('gr-resemble-diff-mode tests', () => {
+    let element;
+
+    setup(() => {
+      element = fixture('basicFixture');
+    });
+
+    test('test initialization', () => {
+      assert.notEqual(element, null);
+      assert.equal(element.baseImage, null);
+      assert.equal(element.revisionImage, null);
+    });
+
+    test('test getDataUrl', () => {
+      element.baseImage = {
+        type: 'image/png',
+        body: 'SGVsbG8=',
+      };
+      const desiredOutput = 'data:image/png;base64,SGVsbG8=';
+      assert.equal(element.getDataUrl(element.baseImage), desiredOutput);
+    });
+
+    test('test resemble mode image diff', () => {
+      const img = element.$.imageDiff;
+      const expected_result = 'data:image/png;base64,SGVsbG8V29ybGQ==';
+      assert.isFalse(img.hasAttribute('src'));
+      element.baseImage = {
+        type: 'image/png',
+        body: 'SGVsbG8=',
+      };
+      assert.isFalse(img.hasAttribute('src'));
+      element.revisionImage = {
+        type: 'image/png',
+        body: 'V29ybGQ=',
+      };
+      flushAsynchronousOperations();
+      sinon.stub(element, 'compareImages')
+          .returns(Promise.resolve(expected_result));
+      return element._handleImageDiff(element.baseImage, element.revisionImage)
+          .then(() => {
+            assert.equal(img.src, expected_result);
+          });
+    });
+  });
+</script>
\ No newline at end of file
diff --git a/test/index.html b/test/index.html
index 7a02c3f..181c106 100644
--- a/test/index.html
+++ b/test/index.html
@@ -19,13 +19,14 @@
 <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
 <title>Test Runner</title>
 <meta charset="utf-8">
-<script src="../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../bower_components/web-component-tester/browser.js"></script>
+<script src="../node_modules/webcomponents.js/webcomponents-lite.min.js"></script>
+<script src="../node_modules/web-component-tester/browser.js"></script>
+
 <script>
   const suites = [
-    // Insert test suites here.
+    '../gr-resemble-diff-mode/gr-resemble-diff-mode_test.html',
   ];
 
   WCT.loadSuites(suites);
-  WCT.loadSuites(suites.forEach(suite => `${suite}?dom=shadow`));
+  WCT.loadSuites(suites.map(suite => `${suite}?dom=shadow`));
 </script>
\ No newline at end of file