Add gr-account-entry
This new element wraps the gr-autocomplete used by gr-reviewer-list. The default logic for suggesting accounts in the context of reviewers on a change now lives in gr-account-entry, and can be customized for other contexts (e.g., CCed accounts). Change-Id: I00fc48acc66a72fd93d3a45a2805e8b6908b2629
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
<!--
|
||||
Copyright (C) 2016 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.
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../shared/gr-autocomplete/gr-autocomplete.html">
|
||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
|
||||
<dom-module id="gr-account-entry">
|
||||
<template>
|
||||
<style>
|
||||
gr-autocomplete {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<gr-autocomplete
|
||||
id="input"
|
||||
borderless="[[borderless]]"
|
||||
placeholder="[[placeholder]]"
|
||||
threshold="[[suggestFrom]]"
|
||||
query="[[query]]"
|
||||
on-commit="_handleInputCommit"
|
||||
clear-on-commit>
|
||||
</gr-autocomplete>
|
||||
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
||||
</template>
|
||||
<script src="gr-account-entry.js"></script>
|
||||
</dom-module>
|
||||
@@ -0,0 +1,122 @@
|
||||
// Copyright (C) 2016 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-account-entry',
|
||||
|
||||
/**
|
||||
* Fired when an account is entered.
|
||||
*
|
||||
* @event add
|
||||
*/
|
||||
|
||||
properties: {
|
||||
borderless: Boolean,
|
||||
change: Object,
|
||||
placeholder: String,
|
||||
|
||||
suggestFrom: {
|
||||
type: Number,
|
||||
value: 3,
|
||||
},
|
||||
|
||||
filter: {
|
||||
type: Function,
|
||||
value: function() {
|
||||
return this.notOwnerOrReviewer.bind(this);
|
||||
},
|
||||
},
|
||||
|
||||
query: {
|
||||
type: Function,
|
||||
value: function() {
|
||||
return this._getReviewerSuggestions.bind(this);
|
||||
},
|
||||
},
|
||||
|
||||
_reviewers: {
|
||||
type: Array,
|
||||
value: function() { return []; },
|
||||
},
|
||||
},
|
||||
|
||||
observers: [
|
||||
'_reviewersChanged(change.reviewers.*, change.owner)',
|
||||
],
|
||||
|
||||
focus: function() {
|
||||
this.$.input.focus();
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
this.$.input.clear();
|
||||
},
|
||||
|
||||
_handleInputCommit: function(e) {
|
||||
this.fire('add', {value: e.detail.value});
|
||||
},
|
||||
|
||||
_reviewersChanged: function(changeRecord, owner) {
|
||||
var reviewerSet = {};
|
||||
reviewerSet[owner._account_id] = true;
|
||||
var addReviewers = function(reviewers) {
|
||||
if (!reviewers) {
|
||||
return;
|
||||
}
|
||||
reviewers.forEach(function(reviewer) {
|
||||
reviewerSet[reviewer._account_id] = true;
|
||||
});
|
||||
};
|
||||
|
||||
var reviewers = changeRecord.base;
|
||||
addReviewers(reviewers.CC);
|
||||
addReviewers(reviewers.REVIEWER);
|
||||
this._reviewers = reviewerSet;
|
||||
},
|
||||
|
||||
notOwnerOrReviewer: function(reviewer) {
|
||||
var account = reviewer.account;
|
||||
if (!account) { return true; }
|
||||
return !this._reviewers[reviewer.account._account_id];
|
||||
},
|
||||
|
||||
_makeSuggestion: function(reviewer) {
|
||||
if (reviewer.account) {
|
||||
return {
|
||||
name: reviewer.account.name + ' (' + reviewer.account.email + ')',
|
||||
value: reviewer,
|
||||
};
|
||||
} else if (reviewer.group) {
|
||||
return {
|
||||
name: reviewer.group.name + ' (group)',
|
||||
value: reviewer,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
_getReviewerSuggestions: function(input) {
|
||||
var xhr = this.$.restAPI.getChangeSuggestedReviewers(
|
||||
this.change._number, input);
|
||||
|
||||
return xhr.then(function(reviewers) {
|
||||
if (!reviewers) { return []; }
|
||||
return reviewers
|
||||
.filter(this.filter)
|
||||
.map(this._makeSuggestion);
|
||||
}.bind(this));
|
||||
},
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,146 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (C) 2016 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>gr-account-entry</title>
|
||||
|
||||
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
|
||||
<script src="../../../bower_components/web-component-tester/browser.js"></script>
|
||||
<script src="../../../scripts/util.js"></script>
|
||||
|
||||
<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
|
||||
<link rel="import" href="gr-account-entry.html">
|
||||
|
||||
<test-fixture id="basic">
|
||||
<template>
|
||||
<gr-account-entry></gr-account-entry>
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<script>
|
||||
suite('gr-account-entry tests', function() {
|
||||
var _nextAccountId = 0;
|
||||
var makeAccount = function() {
|
||||
var accountId = ++_nextAccountId;
|
||||
return {
|
||||
_account_id: accountId,
|
||||
name: 'name ' + accountId,
|
||||
email: 'email ' + accountId,
|
||||
};
|
||||
};
|
||||
|
||||
var owner;
|
||||
var existingReviewer1;
|
||||
var existingReviewer2;
|
||||
var suggestion1;
|
||||
var suggestion2;
|
||||
var suggestion3;
|
||||
var element;
|
||||
|
||||
setup(function() {
|
||||
owner = makeAccount();
|
||||
existingReviewer1 = makeAccount();
|
||||
existingReviewer2 = makeAccount();
|
||||
suggestion1 = {account: makeAccount()};
|
||||
suggestion2 = {account: makeAccount()};
|
||||
suggestion3 = {
|
||||
group: {
|
||||
id: 'suggested group id',
|
||||
name: 'suggested group',
|
||||
},
|
||||
};
|
||||
|
||||
element = fixture('basic');
|
||||
element.change = {
|
||||
owner: owner,
|
||||
reviewers: {
|
||||
CC: [existingReviewer1],
|
||||
REVIEWER: [existingReviewer2],
|
||||
},
|
||||
};
|
||||
|
||||
stub('gr-rest-api-interface', {
|
||||
getChangeSuggestedReviewers: function() {
|
||||
var redundantSuggestion1 = {account: existingReviewer1};
|
||||
var redundantSuggestion2 = {account: existingReviewer2};
|
||||
var redundantSuggestion3 = {account: owner};
|
||||
return Promise.resolve([redundantSuggestion1, redundantSuggestion2,
|
||||
redundantSuggestion3, suggestion1, suggestion2, suggestion3]);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('notOwnerOrReviewer', function() {
|
||||
var account = makeAccount();
|
||||
assert.isTrue(element.notOwnerOrReviewer({}));
|
||||
assert.isTrue(element.notOwnerOrReviewer({account: account}));
|
||||
assert.isFalse(element.notOwnerOrReviewer({account: owner}));
|
||||
assert.isFalse(element.notOwnerOrReviewer({account: existingReviewer1}));
|
||||
assert.isFalse(element.notOwnerOrReviewer({account: existingReviewer2}));
|
||||
});
|
||||
|
||||
test('_makeSuggestion formats account or group accordingly', function() {
|
||||
var account = makeAccount();
|
||||
var suggestion = element._makeSuggestion({account: account});
|
||||
assert.deepEqual(suggestion, {
|
||||
name: account.name + ' (' + account.email + ')',
|
||||
value: {account: account},
|
||||
});
|
||||
|
||||
var group = {name: 'test'};
|
||||
suggestion = element._makeSuggestion({group: group});
|
||||
assert.deepEqual(suggestion, {
|
||||
name: group.name + ' (group)',
|
||||
value: {group: group},
|
||||
});
|
||||
});
|
||||
|
||||
test('_getReviewerSuggestions excludes owner+reviewers', function(done) {
|
||||
element._getReviewerSuggestions().then(function(reviewers) {
|
||||
assert.deepEqual(reviewers, [
|
||||
element._makeSuggestion(suggestion1),
|
||||
element._makeSuggestion(suggestion2),
|
||||
element._makeSuggestion(suggestion3),
|
||||
]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('_updateReviewers', function() {
|
||||
// delete existingReviewer1
|
||||
element.splice('change.reviewers.CC', 0, 1);
|
||||
var expected = {};
|
||||
expected[owner._account_id] = true;
|
||||
expected[existingReviewer2._account_id] = true;
|
||||
assert.deepEqual(element._reviewers, expected);
|
||||
|
||||
// delete existingReviewer2
|
||||
element.splice('change.reviewers.REVIEWER', 0, 1);
|
||||
delete expected[existingReviewer2._account_id];
|
||||
assert.deepEqual(element._reviewers, expected);
|
||||
|
||||
// add two new reviewers
|
||||
var account1 = makeAccount();
|
||||
var account2 = makeAccount();
|
||||
element.push('change.reviewers.CC', account1);
|
||||
element.push('change.reviewers.REVIEWER', account2);
|
||||
expected[account1._account_id] = true;
|
||||
expected[account2._account_id] = true;
|
||||
assert.deepEqual(element._reviewers, expected);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -18,8 +18,8 @@ limitations under the License.
|
||||
<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
|
||||
<link rel="import" href="../../shared/gr-account-chip/gr-account-chip.html">
|
||||
<link rel="import" href="../../shared/gr-button/gr-button.html">
|
||||
<link rel="import" href="../../shared/gr-autocomplete/gr-autocomplete.html">
|
||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
<link rel="import" href="../gr-account-entry/gr-account-entry.html">
|
||||
|
||||
<dom-module id="gr-reviewer-list">
|
||||
<template>
|
||||
@@ -74,14 +74,14 @@ limitations under the License.
|
||||
<div class="controlsContainer" hidden$="[[!mutable]]">
|
||||
<div class="autocompleteContainer" hidden$="[[!_showInput]]">
|
||||
<div class="inputContainer">
|
||||
<gr-autocomplete
|
||||
id="input"
|
||||
threshold="[[suggestFrom]]"
|
||||
<gr-account-entry
|
||||
id="accountEntry"
|
||||
suggestFrom="[[suggestFrom]]"
|
||||
clear-on-commit
|
||||
query="[[_query]]"
|
||||
change="[[change]]"
|
||||
disabled="[[disabled]]"
|
||||
on-commit="_sendAddRequest"
|
||||
on-cancel="_handleCancelTap"></gr-autocomplete>
|
||||
on-cancel="_handleCancelTap"></gr-account-entry>
|
||||
<gr-button
|
||||
link
|
||||
class="cancel"
|
||||
|
||||
@@ -19,15 +19,15 @@
|
||||
|
||||
properties: {
|
||||
change: Object,
|
||||
mutable: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
reflectToAttribute: true,
|
||||
},
|
||||
mutable: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
suggestFrom: {
|
||||
type: Number,
|
||||
value: 3,
|
||||
@@ -42,13 +42,6 @@
|
||||
value: false,
|
||||
},
|
||||
|
||||
_query: {
|
||||
type: Function,
|
||||
value: function() {
|
||||
return this._getReviewerSuggestions.bind(this);
|
||||
},
|
||||
},
|
||||
|
||||
// Used for testing.
|
||||
_lastAutocompleteRequest: Object,
|
||||
_xhrPromise: Object,
|
||||
@@ -112,18 +105,18 @@
|
||||
_handleAddTap: function(e) {
|
||||
e.preventDefault();
|
||||
this._showInput = true;
|
||||
this.$.input.focus();
|
||||
this.$.accountEntry.focus();
|
||||
},
|
||||
|
||||
_handleCancelTap: function(e) {
|
||||
e.preventDefault();
|
||||
this.$.input.clear();
|
||||
this.$.accountEntry.clear();
|
||||
this._cancel();
|
||||
},
|
||||
|
||||
_cancel: function() {
|
||||
this._showInput = false;
|
||||
this.$.input.clear();
|
||||
this.$.accountEntry.clear();
|
||||
this.$.addReviewer.focus();
|
||||
},
|
||||
|
||||
@@ -147,7 +140,7 @@
|
||||
this.push('change.removable_reviewers', r);
|
||||
this.push('change.reviewers.CC', r);
|
||||
}, this);
|
||||
this.$.input.focus();
|
||||
this.$.accountEntry.focus();
|
||||
}.bind(this));
|
||||
}.bind(this)).catch(function(err) {
|
||||
this.disabled = false;
|
||||
@@ -162,47 +155,5 @@
|
||||
_removeReviewer: function(id) {
|
||||
return this.$.restAPI.removeChangeReviewer(this.change._number, id);
|
||||
},
|
||||
|
||||
_notInList: function(reviewer) {
|
||||
var account = reviewer.account;
|
||||
if (!account) { return true; }
|
||||
if (account._account_id === this.change.owner._account_id) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < this._reviewers.length; i++) {
|
||||
if (account._account_id === this._reviewers[i]._account_id) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
_makeSuggestion: function(reviewer) {
|
||||
if (reviewer.account) {
|
||||
return {
|
||||
name: reviewer.account.name + ' (' + reviewer.account.email + ')',
|
||||
value: reviewer,
|
||||
};
|
||||
} else if (reviewer.group) {
|
||||
return {
|
||||
name: reviewer.group.name + ' (group)',
|
||||
value: reviewer,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
_getReviewerSuggestions: function(input) {
|
||||
var xhr = this.$.restAPI.getChangeSuggestedReviewers(
|
||||
this.change._number, input);
|
||||
|
||||
this._lastAutocompleteRequest = xhr;
|
||||
|
||||
return xhr.then(function(reviewers) {
|
||||
if (!reviewers) { return []; }
|
||||
return reviewers
|
||||
.filter(this._notInList.bind(this))
|
||||
.map(this._makeSuggestion);
|
||||
}.bind(this));
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -38,7 +38,8 @@ limitations under the License.
|
||||
|
||||
setup(function() {
|
||||
element = fixture('basic');
|
||||
autocompleteInput = element.$.input.$.input;
|
||||
// TODO(logan): Rewrite this test to not delve so deeply into internals.
|
||||
autocompleteInput = element.$.accountEntry.$.input.$.input;
|
||||
stub('gr-rest-api-interface', {
|
||||
getChangeSuggestedReviewers: function() {
|
||||
return Promise.resolve([
|
||||
@@ -98,17 +99,24 @@ limitations under the License.
|
||||
});
|
||||
|
||||
function getActiveElement() {
|
||||
return document.activeElement.shadowRoot ?
|
||||
document.activeElement.shadowRoot.activeElement :
|
||||
document.activeElement;
|
||||
var root = document;
|
||||
while (root && root.activeElement.shadowRoot) {
|
||||
var shadowRoot = root.activeElement.shadowRoot;
|
||||
if (!shadowRoot.activeElement) {
|
||||
break;
|
||||
}
|
||||
root = shadowRoot;
|
||||
}
|
||||
return root.activeElement;
|
||||
}
|
||||
|
||||
test('show/hide input', function() {
|
||||
test('show/hide accountEntry', function() {
|
||||
element.mutable = true;
|
||||
assert.isFalse(element.$$('.addReviewer').hasAttribute('hidden'));
|
||||
assert.isTrue(
|
||||
element.$$('.autocompleteContainer').hasAttribute('hidden'));
|
||||
assert.notEqual(getActiveElement().id, 'input');
|
||||
|
||||
MockInteractions.tap(element.$$('.addReviewer'));
|
||||
assert.isTrue(element.$$('.addReviewer').hasAttribute('hidden'));
|
||||
assert.isFalse(
|
||||
@@ -184,7 +192,7 @@ limitations under the License.
|
||||
element._mutable = true;
|
||||
element.change = {_number: 123};
|
||||
|
||||
element.$.input.text = 'fo';
|
||||
element.$.accountEntry.text = 'fo';
|
||||
|
||||
flushAsynchronousOperations();
|
||||
|
||||
@@ -202,9 +210,10 @@ limitations under the License.
|
||||
element._mutable = true;
|
||||
MockInteractions.tap(element.$$('.addReviewer'));
|
||||
flushAsynchronousOperations();
|
||||
element.$.input.text = 'andy';
|
||||
element.$.accountEntry.$.input.text = 'andy';
|
||||
|
||||
element._lastAutocompleteRequest.then(function() {
|
||||
var stub = element.$.restAPI.getChangeSuggestedReviewers;
|
||||
stub.lastCall.returnValue.then(function() {
|
||||
flushAsynchronousOperations();
|
||||
|
||||
MockInteractions.pressAndReleaseKeyOn(autocompleteInput, 27); // 'esc'
|
||||
@@ -213,9 +222,8 @@ limitations under the License.
|
||||
|
||||
MockInteractions.tap(element.$$('.addReviewer'));
|
||||
|
||||
element.$.input.text = 'andyb';
|
||||
element._lastAutocompleteRequest.then(function() {
|
||||
|
||||
element.$.accountEntry.text = 'andyb';
|
||||
stub.lastCall.returnValue.then(function() {
|
||||
MockInteractions.pressAndReleaseKeyOn(
|
||||
autocompleteInput, 13); // 'enter'
|
||||
assert.isTrue(element.disabled);
|
||||
@@ -242,63 +250,5 @@ limitations under the License.
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('_makeSuggestion', function() {
|
||||
var account = {
|
||||
_account_id: 123456,
|
||||
name: 'name',
|
||||
email: 'email'
|
||||
};
|
||||
var group = {
|
||||
id: '123456',
|
||||
name: 'name',
|
||||
};
|
||||
|
||||
var suggestion = element._makeSuggestion({account: account});
|
||||
|
||||
assert.deepEqual(suggestion, {
|
||||
name: 'name (email)',
|
||||
value: {account: account},
|
||||
});
|
||||
|
||||
suggestion = element._makeSuggestion({group: group});
|
||||
|
||||
assert.deepEqual(suggestion, {
|
||||
name: 'name (group)',
|
||||
value: {group: group},
|
||||
});
|
||||
});
|
||||
|
||||
test('_notInList', function() {
|
||||
var group = {
|
||||
id: '123456',
|
||||
name: 'name',
|
||||
};
|
||||
var account = {
|
||||
_account_id: 123456,
|
||||
name: 'name',
|
||||
email: 'email',
|
||||
};
|
||||
|
||||
element.change = {owner: {_account_id: 123456}};
|
||||
|
||||
// Is true when passing a group.
|
||||
assert.isTrue(element._notInList({group: group}));
|
||||
|
||||
// Is false when passing the change owner.
|
||||
assert.isFalse(element._notInList({account: account}));
|
||||
|
||||
element.change.owner._account_id = 789;
|
||||
|
||||
// Is true when passing a different user than the change owner, and is not
|
||||
// in the reviewer list.
|
||||
assert.isTrue(element._notInList({account: account}));
|
||||
|
||||
element._reviewers = [{_account_id: 123456}];
|
||||
|
||||
// Is false when passing a different user than the change owner, but *is*
|
||||
// the reviewer list.
|
||||
assert.isFalse(element._notInList({account: account}));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -23,6 +23,11 @@ limitations under the License.
|
||||
input {
|
||||
font-size: 1em;
|
||||
}
|
||||
input.borderless,
|
||||
input.borderless:focus {
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
#suggestions {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
|
||||
@@ -42,6 +47,7 @@ limitations under the License.
|
||||
</style>
|
||||
<input
|
||||
id="input"
|
||||
class$="[[_computeClass(borderless)]]"
|
||||
is="iron-input"
|
||||
disabled$="[[disabled]]"
|
||||
bind-value="{{text}}"
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
value: 1,
|
||||
},
|
||||
|
||||
borderless: Boolean,
|
||||
disabled: Boolean,
|
||||
|
||||
text: {
|
||||
@@ -136,6 +137,10 @@
|
||||
return !suggestions.length;
|
||||
},
|
||||
|
||||
_computeClass: function(borderless) {
|
||||
return borderless ? 'borderless' : '';
|
||||
},
|
||||
|
||||
_getSuggestionElems: function() {
|
||||
Polymer.dom.flush();
|
||||
return this.$.suggestions.querySelectorAll('li');
|
||||
|
||||
@@ -208,5 +208,11 @@ limitations under the License.
|
||||
|
||||
assert.isTrue(queryStub.called);
|
||||
});
|
||||
|
||||
test('_computeClass respects border property', function() {
|
||||
assert.equal(element._computeClass(), '');
|
||||
assert.equal(element._computeClass(false), '');
|
||||
assert.equal(element._computeClass(true), 'borderless');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -27,6 +27,7 @@ limitations under the License.
|
||||
[
|
||||
'change-list/gr-change-list-item/gr-change-list-item_test.html',
|
||||
'change-list/gr-change-list/gr-change-list_test.html',
|
||||
'change/gr-account-entry/gr-account-entry_test.html',
|
||||
'change/gr-change-actions/gr-change-actions_test.html',
|
||||
'change/gr-change-metadata/gr-change-metadata_test.html',
|
||||
'change/gr-change-view/gr-change-view_test.html',
|
||||
|
||||
Reference in New Issue
Block a user