Convert polygerrit to es6-modules

This change replace all HTML imports with es6-modules. The only exceptions are:
* gr-app.html file, which can be deleted only after updating the
  gerrit/httpd/raw/PolyGerritIndexHtml.soy file.
* dark-theme.html which is loaded via importHref. Must be updated manually
  later in a separate change.

This change was produced automatically by ./es6-modules-converter.sh script.
No manual changes were made.

Change-Id: I0c447dd8c05757741e2c940720652d01d9fb7d67
This commit is contained in:
Dmitrii Filippov
2020-03-17 11:27:28 +01:00
parent dbe954539d
commit daf0ec9543
600 changed files with 99000 additions and 99742 deletions

View File

@@ -1,21 +1,19 @@
<!--
@license
Copyright (C) 2017 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>
/**
* @license
* Copyright (C) 2017 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(window) {
'use strict';
@@ -63,4 +61,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -19,40 +19,42 @@ limitations under the License.
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>async-foreach-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="async-foreach-behavior.html">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module" src="./async-foreach-behavior.js"></script>
<script>
suite('async-foreach-behavior tests', async () => {
await readyToTest();
test('loops over each item', () => {
const fn = sinon.stub().returns(Promise.resolve());
return Gerrit.AsyncForeachBehavior.asyncForeach([1, 2, 3], fn)
.then(() => {
assert.isTrue(fn.calledThrice);
assert.equal(fn.getCall(0).args[0], 1);
assert.equal(fn.getCall(1).args[0], 2);
assert.equal(fn.getCall(2).args[0], 3);
});
});
test('halts on stop condition', () => {
const stub = sinon.stub();
const fn = (e, stop) => {
stub(e);
stop();
return Promise.resolve();
};
return Gerrit.AsyncForeachBehavior.asyncForeach([1, 2, 3], fn)
.then(() => {
assert.isTrue(stub.calledOnce);
assert.equal(stub.lastCall.args[0], 1);
});
});
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './async-foreach-behavior.js';
suite('async-foreach-behavior tests', () => {
test('loops over each item', () => {
const fn = sinon.stub().returns(Promise.resolve());
return Gerrit.AsyncForeachBehavior.asyncForeach([1, 2, 3], fn)
.then(() => {
assert.isTrue(fn.calledThrice);
assert.equal(fn.getCall(0).args[0], 1);
assert.equal(fn.getCall(1).args[0], 2);
assert.equal(fn.getCall(2).args[0], 3);
});
});
test('halts on stop condition', () => {
const stub = sinon.stub();
const fn = (e, stop) => {
stub(e);
stop();
return Promise.resolve();
};
return Gerrit.AsyncForeachBehavior.asyncForeach([1, 2, 3], fn)
.then(() => {
assert.isTrue(stub.calledOnce);
assert.equal(stub.lastCall.args[0], 1);
});
});
});
</script>

View File

@@ -1,21 +1,19 @@
<!--
@license
Copyright (C) 2017 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>
/**
* @license
* Copyright (C) 2017 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(window) {
'use strict';
@@ -46,4 +44,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -19,17 +19,20 @@ limitations under the License.
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>base-url-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<script>
/** @type {string} */
window.CANONICAL_PATH = '/r';
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './base-url-behavior.js';
/** @type {string} */
window.CANONICAL_PATH = '/r';
</script>
<link rel="import" href="base-url-behavior.html">
<script type="module" src="./base-url-behavior.js"></script>
<test-fixture id="basic">
<template>
@@ -45,30 +48,33 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('base-url-behavior tests', async () => {
await readyToTest();
let element;
// eslint-disable-next-line no-unused-vars
let overlay;
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './base-url-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('base-url-behavior tests', () => {
let element;
// eslint-disable-next-line no-unused-vars
let overlay;
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [
Gerrit.BaseUrlBehavior,
],
});
});
setup(() => {
element = fixture('basic');
overlay = fixture('within-overlay');
});
test('getBaseUrl', () => {
assert.deepEqual(element.getBaseUrl(), '/r');
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [
Gerrit.BaseUrlBehavior,
],
});
});
setup(() => {
element = fixture('basic');
overlay = fixture('within-overlay');
});
test('getBaseUrl', () => {
assert.deepEqual(element.getBaseUrl(), '/r');
});
});
</script>

View File

@@ -1,21 +1,21 @@
<!--
@license
Copyright (C) 2017 The Android Open Source Project
/**
* @license
* Copyright (C) 2017 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.
*/
import '../base-url-behavior/base-url-behavior.js';
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="../base-url-behavior/base-url-behavior.html">
<script>
(function(window) {
'use strict';
@@ -77,4 +77,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -15,17 +15,22 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Polymer included for the html import polyfill. -->
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<title>docs-url-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<link rel="import" href="docs-url-behavior.html">
<script type="module" src="./docs-url-behavior.js"></script>
<script>void(0);</script>
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './docs-url-behavior.js';
void(0);
</script>
<test-fixture id="basic">
<template>
@@ -33,71 +38,74 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('docs-url-behavior tests', async () => {
await readyToTest();
let element;
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './docs-url-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('docs-url-behavior tests', () => {
let element;
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'docs-url-behavior-element',
behaviors: [Gerrit.DocsUrlBehavior],
});
});
setup(() => {
element = fixture('basic');
element._clearDocsBaseUrlCache();
});
test('null config', () => {
const mockRestApi = {
probePath: sinon.stub().returns(Promise.resolve(true)),
};
return element.getDocsBaseUrl(null, mockRestApi)
.then(docsBaseUrl => {
assert.isTrue(
mockRestApi.probePath.calledWith('/Documentation/index.html'));
assert.equal(docsBaseUrl, '/Documentation');
});
});
test('no doc config', () => {
const mockRestApi = {
probePath: sinon.stub().returns(Promise.resolve(true)),
};
const config = {gerrit: {}};
return element.getDocsBaseUrl(config, mockRestApi)
.then(docsBaseUrl => {
assert.isTrue(
mockRestApi.probePath.calledWith('/Documentation/index.html'));
assert.equal(docsBaseUrl, '/Documentation');
});
});
test('has doc config', () => {
const mockRestApi = {
probePath: sinon.stub().returns(Promise.resolve(true)),
};
const config = {gerrit: {doc_url: 'foobar'}};
return element.getDocsBaseUrl(config, mockRestApi)
.then(docsBaseUrl => {
assert.isFalse(mockRestApi.probePath.called);
assert.equal(docsBaseUrl, 'foobar');
});
});
test('no probe', () => {
const mockRestApi = {
probePath: sinon.stub().returns(Promise.resolve(false)),
};
return element.getDocsBaseUrl(null, mockRestApi)
.then(docsBaseUrl => {
assert.isTrue(
mockRestApi.probePath.calledWith('/Documentation/index.html'));
assert.isNotOk(docsBaseUrl);
});
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'docs-url-behavior-element',
behaviors: [Gerrit.DocsUrlBehavior],
});
});
setup(() => {
element = fixture('basic');
element._clearDocsBaseUrlCache();
});
test('null config', () => {
const mockRestApi = {
probePath: sinon.stub().returns(Promise.resolve(true)),
};
return element.getDocsBaseUrl(null, mockRestApi)
.then(docsBaseUrl => {
assert.isTrue(
mockRestApi.probePath.calledWith('/Documentation/index.html'));
assert.equal(docsBaseUrl, '/Documentation');
});
});
test('no doc config', () => {
const mockRestApi = {
probePath: sinon.stub().returns(Promise.resolve(true)),
};
const config = {gerrit: {}};
return element.getDocsBaseUrl(config, mockRestApi)
.then(docsBaseUrl => {
assert.isTrue(
mockRestApi.probePath.calledWith('/Documentation/index.html'));
assert.equal(docsBaseUrl, '/Documentation');
});
});
test('has doc config', () => {
const mockRestApi = {
probePath: sinon.stub().returns(Promise.resolve(true)),
};
const config = {gerrit: {doc_url: 'foobar'}};
return element.getDocsBaseUrl(config, mockRestApi)
.then(docsBaseUrl => {
assert.isFalse(mockRestApi.probePath.called);
assert.equal(docsBaseUrl, 'foobar');
});
});
test('no probe', () => {
const mockRestApi = {
probePath: sinon.stub().returns(Promise.resolve(false)),
};
return element.getDocsBaseUrl(null, mockRestApi)
.then(docsBaseUrl => {
assert.isTrue(
mockRestApi.probePath.calledWith('/Documentation/index.html'));
assert.isNotOk(docsBaseUrl);
});
});
});
</script>

View File

@@ -1,20 +1,19 @@
<!--
@license
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>
/**
* @license
* 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(window) {
'use strict';
@@ -61,4 +60,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -19,13 +19,13 @@ limitations under the License.
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>dom-util-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="dom-util-behavior.html">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module" src="./dom-util-behavior.js"></script>
<test-fixture id="nested-structure">
<template>
@@ -40,34 +40,37 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('dom-util-behavior tests', async () => {
await readyToTest();
let element;
let divs;
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './dom-util-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('dom-util-behavior tests', () => {
let element;
let divs;
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.DomUtilBehavior],
});
});
setup(() => {
const testDom = fixture('nested-structure');
element = testDom[0];
divs = testDom[1];
});
test('descendedFromClass', () => {
// .c is a child of .a and not vice versa.
assert.isTrue(element.descendedFromClass(divs.querySelector('.c'), 'a'));
assert.isFalse(element.descendedFromClass(divs.querySelector('.a'), 'c'));
// Stops at stop element.
assert.isFalse(element.descendedFromClass(divs.querySelector('.c'), 'a',
divs.querySelector('.b')));
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.DomUtilBehavior],
});
});
setup(() => {
const testDom = fixture('nested-structure');
element = testDom[0];
divs = testDom[1];
});
test('descendedFromClass', () => {
// .c is a child of .a and not vice versa.
assert.isTrue(element.descendedFromClass(divs.querySelector('.c'), 'a'));
assert.isFalse(element.descendedFromClass(divs.querySelector('.a'), 'c'));
// Stops at stop element.
assert.isFalse(element.descendedFromClass(divs.querySelector('.c'), 'a',
divs.querySelector('.b')));
});
});
</script>

View File

@@ -1,21 +1,19 @@
<!--
@license
Copyright (C) 2019 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>
/**
* @license
* Copyright (C) 2019 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(window) {
'use strict';
@@ -69,4 +67,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -1,21 +1,19 @@
<!--
@license
Copyright (C) 2017 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>
/**
* @license
* Copyright (C) 2017 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(window) {
'use strict';
@@ -177,4 +175,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -19,13 +19,13 @@ limitations under the License.
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-access-behavior.html">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module" src="./gr-access-behavior.js"></script>
<test-fixture id="basic">
<template>
@@ -33,41 +33,44 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('gr-access-behavior tests', async () => {
await readyToTest();
let element;
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './gr-access-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('gr-access-behavior tests', () => {
let element;
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.AccessBehavior],
});
});
setup(() => {
element = fixture('basic');
});
test('toSortedArray', () => {
const rules = {
'global:Project-Owners': {
action: 'ALLOW', force: false,
},
'4c97682e6ce6b7247f3381b6f1789356666de7f': {
action: 'ALLOW', force: false,
},
};
const expectedResult = [
{id: '4c97682e6ce6b7247f3381b6f1789356666de7f', value: {
action: 'ALLOW', force: false,
}},
{id: 'global:Project-Owners', value: {
action: 'ALLOW', force: false,
}},
];
assert.deepEqual(element.toSortedArray(rules), expectedResult);
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.AccessBehavior],
});
});
setup(() => {
element = fixture('basic');
});
test('toSortedArray', () => {
const rules = {
'global:Project-Owners': {
action: 'ALLOW', force: false,
},
'4c97682e6ce6b7247f3381b6f1789356666de7f': {
action: 'ALLOW', force: false,
},
};
const expectedResult = [
{id: '4c97682e6ce6b7247f3381b6f1789356666de7f', value: {
action: 'ALLOW', force: false,
}},
{id: 'global:Project-Owners', value: {
action: 'ALLOW', force: false,
}},
];
assert.deepEqual(element.toSortedArray(rules), expectedResult);
});
});
</script>

View File

@@ -1,20 +1,19 @@
<!--
@license
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>
/**
* @license
* 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(window) {
'use strict';
@@ -220,4 +219,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -19,13 +19,13 @@ limitations under the License.
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-admin-nav-behavior.html">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module" src="./gr-admin-nav-behavior.js"></script>
<test-fixture id="basic">
<template>
@@ -33,338 +33,341 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('gr-admin-nav-behavior tests', async () => {
await readyToTest();
let element;
let sandbox;
let capabilityStub;
let menuLinkStub;
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './gr-admin-nav-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('gr-admin-nav-behavior tests', () => {
let element;
let sandbox;
let capabilityStub;
let menuLinkStub;
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [
Gerrit.AdminNavBehavior,
],
});
});
setup(() => {
element = fixture('basic');
sandbox = sinon.sandbox.create();
capabilityStub = sinon.stub();
menuLinkStub = sinon.stub().returns([]);
});
teardown(() => {
sandbox.restore();
});
const testAdminLinks = (account, options, expected, done) => {
element.getAdminLinks(account,
capabilityStub,
menuLinkStub,
options)
.then(res => {
assert.equal(expected.totalLength, res.links.length);
assert.equal(res.links[0].name, 'Repositories');
// Repos
if (expected.groupListShown) {
assert.equal(res.links[1].name, 'Groups');
}
if (expected.pluginListShown) {
assert.equal(res.links[2].name, 'Plugins');
assert.isNotOk(res.links[2].subsection);
}
if (expected.projectPageShown) {
assert.isOk(res.links[0].subsection);
assert.equal(res.links[0].subsection.children.length, 5);
} else {
assert.isNotOk(res.links[0].subsection);
}
// Groups
if (expected.groupPageShown) {
assert.isOk(res.links[1].subsection);
assert.equal(res.links[1].subsection.children.length,
expected.groupSubpageLength);
} else if ( expected.totalLength > 1) {
assert.isNotOk(res.links[1].subsection);
}
if (expected.pluginGeneratedLinks) {
for (const link of expected.pluginGeneratedLinks) {
const linkMatch = res.links
.find(l => (l.url === link.url && l.name === link.text));
assert.isTrue(!!linkMatch);
// External links should open in new tab.
if (link.url[0] !== '/') {
assert.equal(linkMatch.target, '_blank');
} else {
assert.isNotOk(linkMatch.target);
}
}
}
// Current section
if (expected.projectPageShown || expected.groupPageShown) {
assert.isOk(res.expandedSection);
assert.isOk(res.expandedSection.children);
} else {
assert.isNotOk(res.expandedSection);
}
if (expected.projectPageShown) {
assert.equal(res.expandedSection.name, 'my-repo');
assert.equal(res.expandedSection.children.length, 5);
} else if (expected.groupPageShown) {
assert.equal(res.expandedSection.name, 'my-group');
assert.equal(res.expandedSection.children.length,
expected.groupSubpageLength);
}
done();
});
};
suite('logged out', () => {
let account;
let expected;
setup(() => {
expected = {
groupListShown: false,
groupPageShown: false,
pluginListShown: false,
};
});
test('without a specific repo or group', done => {
let options;
expected = Object.assign(expected, {
totalLength: 1,
projectPageShown: false,
});
testAdminLinks(account, options, expected, done);
});
test('with a repo', done => {
const options = {repoName: 'my-repo'};
expected = Object.assign(expected, {
totalLength: 1,
projectPageShown: true,
});
testAdminLinks(account, options, expected, done);
});
test('with plugin generated links', done => {
let options;
const generatedLinks = [
{text: 'internal link text', url: '/internal/link/url'},
{text: 'external link text', url: 'http://external/link/url'},
];
menuLinkStub.returns(generatedLinks);
expected = Object.assign(expected, {
totalLength: 3,
projectPageShown: false,
pluginGeneratedLinks: generatedLinks,
});
testAdminLinks(account, options, expected, done);
});
});
suite('no plugin capability logged in', () => {
const account = {
name: 'test-user',
};
let expected;
setup(() => {
expected = {
totalLength: 2,
pluginListShown: false,
};
capabilityStub.returns(Promise.resolve({}));
});
test('without a specific project or group', done => {
let options;
expected = Object.assign(expected, {
projectPageShown: false,
groupListShown: true,
groupPageShown: false,
});
testAdminLinks(account, options, expected, done);
});
test('with a repo', done => {
const account = {
name: 'test-user',
};
const options = {repoName: 'my-repo'};
expected = Object.assign(expected, {
projectPageShown: true,
groupListShown: true,
groupPageShown: false,
});
testAdminLinks(account, options, expected, done);
});
});
suite('view plugin capability logged in', () => {
const account = {
name: 'test-user',
};
let expected;
setup(() => {
capabilityStub.returns(Promise.resolve({viewPlugins: true}));
expected = {
totalLength: 3,
groupListShown: true,
pluginListShown: true,
};
});
test('without a specific repo or group', done => {
let options;
expected = Object.assign(expected, {
projectPageShown: false,
groupPageShown: false,
});
testAdminLinks(account, options, expected, done);
});
test('with a repo', done => {
const options = {repoName: 'my-repo'};
expected = Object.assign(expected, {
projectPageShown: true,
groupPageShown: false,
});
testAdminLinks(account, options, expected, done);
});
test('admin with internal group', done => {
const options = {
groupId: 'a15262',
groupName: 'my-group',
groupIsInternal: true,
isAdmin: true,
groupOwner: false,
};
expected = Object.assign(expected, {
projectPageShown: false,
groupPageShown: true,
groupSubpageLength: 2,
});
testAdminLinks(account, options, expected, done);
});
test('group owner with internal group', done => {
const options = {
groupId: 'a15262',
groupName: 'my-group',
groupIsInternal: true,
isAdmin: false,
groupOwner: true,
};
expected = Object.assign(expected, {
projectPageShown: false,
groupPageShown: true,
groupSubpageLength: 2,
});
testAdminLinks(account, options, expected, done);
});
test('non owner or admin with internal group', done => {
const options = {
groupId: 'a15262',
groupName: 'my-group',
groupIsInternal: true,
isAdmin: false,
groupOwner: false,
};
expected = Object.assign(expected, {
projectPageShown: false,
groupPageShown: true,
groupSubpageLength: 1,
});
testAdminLinks(account, options, expected, done);
});
test('admin with external group', done => {
const options = {
groupId: 'a15262',
groupName: 'my-group',
groupIsInternal: false,
isAdmin: true,
groupOwner: true,
};
expected = Object.assign(expected, {
projectPageShown: false,
groupPageShown: true,
groupSubpageLength: 0,
});
testAdminLinks(account, options, expected, done);
});
});
suite('view plugin screen with plugin capability', () => {
const account = {
name: 'test-user',
};
let expected;
setup(() => {
capabilityStub.returns(Promise.resolve({pluginCapability: true}));
expected = {};
});
test('with plugin with capabilities', done => {
let options;
const generatedLinks = [
{text: 'without capability', url: '/without'},
{text: 'with capability',
url: '/with',
capability: 'pluginCapability'},
];
menuLinkStub.returns(generatedLinks);
expected = Object.assign(expected, {
totalLength: 4,
pluginGeneratedLinks: generatedLinks,
});
testAdminLinks(account, options, expected, done);
});
});
suite('view plugin screen without plugin capability', () => {
const account = {
name: 'test-user',
};
let expected;
setup(() => {
capabilityStub.returns(Promise.resolve({}));
expected = {};
});
test('with plugin with capabilities', done => {
let options;
const generatedLinks = [
{text: 'without capability', url: '/without'},
{text: 'with capability',
url: '/with',
capability: 'pluginCapability'},
];
menuLinkStub.returns(generatedLinks);
expected = Object.assign(expected, {
totalLength: 3,
pluginGeneratedLinks: [generatedLinks[0]],
});
testAdminLinks(account, options, expected, done);
});
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [
Gerrit.AdminNavBehavior,
],
});
});
setup(() => {
element = fixture('basic');
sandbox = sinon.sandbox.create();
capabilityStub = sinon.stub();
menuLinkStub = sinon.stub().returns([]);
});
teardown(() => {
sandbox.restore();
});
const testAdminLinks = (account, options, expected, done) => {
element.getAdminLinks(account,
capabilityStub,
menuLinkStub,
options)
.then(res => {
assert.equal(expected.totalLength, res.links.length);
assert.equal(res.links[0].name, 'Repositories');
// Repos
if (expected.groupListShown) {
assert.equal(res.links[1].name, 'Groups');
}
if (expected.pluginListShown) {
assert.equal(res.links[2].name, 'Plugins');
assert.isNotOk(res.links[2].subsection);
}
if (expected.projectPageShown) {
assert.isOk(res.links[0].subsection);
assert.equal(res.links[0].subsection.children.length, 5);
} else {
assert.isNotOk(res.links[0].subsection);
}
// Groups
if (expected.groupPageShown) {
assert.isOk(res.links[1].subsection);
assert.equal(res.links[1].subsection.children.length,
expected.groupSubpageLength);
} else if ( expected.totalLength > 1) {
assert.isNotOk(res.links[1].subsection);
}
if (expected.pluginGeneratedLinks) {
for (const link of expected.pluginGeneratedLinks) {
const linkMatch = res.links
.find(l => (l.url === link.url && l.name === link.text));
assert.isTrue(!!linkMatch);
// External links should open in new tab.
if (link.url[0] !== '/') {
assert.equal(linkMatch.target, '_blank');
} else {
assert.isNotOk(linkMatch.target);
}
}
}
// Current section
if (expected.projectPageShown || expected.groupPageShown) {
assert.isOk(res.expandedSection);
assert.isOk(res.expandedSection.children);
} else {
assert.isNotOk(res.expandedSection);
}
if (expected.projectPageShown) {
assert.equal(res.expandedSection.name, 'my-repo');
assert.equal(res.expandedSection.children.length, 5);
} else if (expected.groupPageShown) {
assert.equal(res.expandedSection.name, 'my-group');
assert.equal(res.expandedSection.children.length,
expected.groupSubpageLength);
}
done();
});
};
suite('logged out', () => {
let account;
let expected;
setup(() => {
expected = {
groupListShown: false,
groupPageShown: false,
pluginListShown: false,
};
});
test('without a specific repo or group', done => {
let options;
expected = Object.assign(expected, {
totalLength: 1,
projectPageShown: false,
});
testAdminLinks(account, options, expected, done);
});
test('with a repo', done => {
const options = {repoName: 'my-repo'};
expected = Object.assign(expected, {
totalLength: 1,
projectPageShown: true,
});
testAdminLinks(account, options, expected, done);
});
test('with plugin generated links', done => {
let options;
const generatedLinks = [
{text: 'internal link text', url: '/internal/link/url'},
{text: 'external link text', url: 'http://external/link/url'},
];
menuLinkStub.returns(generatedLinks);
expected = Object.assign(expected, {
totalLength: 3,
projectPageShown: false,
pluginGeneratedLinks: generatedLinks,
});
testAdminLinks(account, options, expected, done);
});
});
suite('no plugin capability logged in', () => {
const account = {
name: 'test-user',
};
let expected;
setup(() => {
expected = {
totalLength: 2,
pluginListShown: false,
};
capabilityStub.returns(Promise.resolve({}));
});
test('without a specific project or group', done => {
let options;
expected = Object.assign(expected, {
projectPageShown: false,
groupListShown: true,
groupPageShown: false,
});
testAdminLinks(account, options, expected, done);
});
test('with a repo', done => {
const account = {
name: 'test-user',
};
const options = {repoName: 'my-repo'};
expected = Object.assign(expected, {
projectPageShown: true,
groupListShown: true,
groupPageShown: false,
});
testAdminLinks(account, options, expected, done);
});
});
suite('view plugin capability logged in', () => {
const account = {
name: 'test-user',
};
let expected;
setup(() => {
capabilityStub.returns(Promise.resolve({viewPlugins: true}));
expected = {
totalLength: 3,
groupListShown: true,
pluginListShown: true,
};
});
test('without a specific repo or group', done => {
let options;
expected = Object.assign(expected, {
projectPageShown: false,
groupPageShown: false,
});
testAdminLinks(account, options, expected, done);
});
test('with a repo', done => {
const options = {repoName: 'my-repo'};
expected = Object.assign(expected, {
projectPageShown: true,
groupPageShown: false,
});
testAdminLinks(account, options, expected, done);
});
test('admin with internal group', done => {
const options = {
groupId: 'a15262',
groupName: 'my-group',
groupIsInternal: true,
isAdmin: true,
groupOwner: false,
};
expected = Object.assign(expected, {
projectPageShown: false,
groupPageShown: true,
groupSubpageLength: 2,
});
testAdminLinks(account, options, expected, done);
});
test('group owner with internal group', done => {
const options = {
groupId: 'a15262',
groupName: 'my-group',
groupIsInternal: true,
isAdmin: false,
groupOwner: true,
};
expected = Object.assign(expected, {
projectPageShown: false,
groupPageShown: true,
groupSubpageLength: 2,
});
testAdminLinks(account, options, expected, done);
});
test('non owner or admin with internal group', done => {
const options = {
groupId: 'a15262',
groupName: 'my-group',
groupIsInternal: true,
isAdmin: false,
groupOwner: false,
};
expected = Object.assign(expected, {
projectPageShown: false,
groupPageShown: true,
groupSubpageLength: 1,
});
testAdminLinks(account, options, expected, done);
});
test('admin with external group', done => {
const options = {
groupId: 'a15262',
groupName: 'my-group',
groupIsInternal: false,
isAdmin: true,
groupOwner: true,
};
expected = Object.assign(expected, {
projectPageShown: false,
groupPageShown: true,
groupSubpageLength: 0,
});
testAdminLinks(account, options, expected, done);
});
});
suite('view plugin screen with plugin capability', () => {
const account = {
name: 'test-user',
};
let expected;
setup(() => {
capabilityStub.returns(Promise.resolve({pluginCapability: true}));
expected = {};
});
test('with plugin with capabilities', done => {
let options;
const generatedLinks = [
{text: 'without capability', url: '/without'},
{text: 'with capability',
url: '/with',
capability: 'pluginCapability'},
];
menuLinkStub.returns(generatedLinks);
expected = Object.assign(expected, {
totalLength: 4,
pluginGeneratedLinks: generatedLinks,
});
testAdminLinks(account, options, expected, done);
});
});
suite('view plugin screen without plugin capability', () => {
const account = {
name: 'test-user',
};
let expected;
setup(() => {
capabilityStub.returns(Promise.resolve({}));
expected = {};
});
test('with plugin with capabilities', done => {
let options;
const generatedLinks = [
{text: 'without capability', url: '/without'},
{text: 'with capability',
url: '/with',
capability: 'pluginCapability'},
];
menuLinkStub.returns(generatedLinks);
expected = Object.assign(expected, {
totalLength: 3,
pluginGeneratedLinks: [generatedLinks[0]],
});
testAdminLinks(account, options, expected, done);
});
});
});
</script>

View File

@@ -1,20 +1,19 @@
<!--
@license
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.
-->
<script>
/**
* @license
* 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(window) {
'use strict';
@@ -105,4 +104,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -19,13 +19,13 @@ limitations under the License.
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-change-table-behavior.html">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module" src="./gr-change-table-behavior.js"></script>
<test-fixture id="basic">
<template>
@@ -41,87 +41,90 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('gr-change-table-behavior tests', async () => {
await readyToTest();
let element;
// eslint-disable-next-line no-unused-vars
let overlay;
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './gr-change-table-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('gr-change-table-behavior tests', () => {
let element;
// eslint-disable-next-line no-unused-vars
let overlay;
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.ChangeTableBehavior],
});
});
setup(() => {
element = fixture('basic');
overlay = fixture('within-overlay');
});
test('getComplementColumns', () => {
let columns = [
'Subject',
'Status',
'Owner',
'Assignee',
'Repo',
'Branch',
'Updated',
'Size',
];
assert.deepEqual(element.getComplementColumns(columns), []);
columns = [
'Subject',
'Status',
'Assignee',
'Repo',
'Branch',
'Size',
];
assert.deepEqual(element.getComplementColumns(columns),
['Owner', 'Updated']);
});
test('isColumnHidden', () => {
const columnToCheck = 'Repo';
let columnsToDisplay = [
'Subject',
'Status',
'Owner',
'Assignee',
'Repo',
'Branch',
'Updated',
'Size',
];
assert.isFalse(element.isColumnHidden(columnToCheck, columnsToDisplay));
columnsToDisplay = [
'Subject',
'Status',
'Owner',
'Assignee',
'Branch',
'Updated',
'Size',
];
assert.isTrue(element.isColumnHidden(columnToCheck, columnsToDisplay));
});
test('getVisibleColumns maps Project to Repo', () => {
const columns = [
'Subject',
'Status',
'Owner',
];
assert.deepEqual(element.getVisibleColumns(columns), columns.slice(0));
assert.deepEqual(
element.getVisibleColumns(columns.concat(['Project'])),
columns.slice(0).concat(['Repo']));
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.ChangeTableBehavior],
});
});
setup(() => {
element = fixture('basic');
overlay = fixture('within-overlay');
});
test('getComplementColumns', () => {
let columns = [
'Subject',
'Status',
'Owner',
'Assignee',
'Repo',
'Branch',
'Updated',
'Size',
];
assert.deepEqual(element.getComplementColumns(columns), []);
columns = [
'Subject',
'Status',
'Assignee',
'Repo',
'Branch',
'Size',
];
assert.deepEqual(element.getComplementColumns(columns),
['Owner', 'Updated']);
});
test('isColumnHidden', () => {
const columnToCheck = 'Repo';
let columnsToDisplay = [
'Subject',
'Status',
'Owner',
'Assignee',
'Repo',
'Branch',
'Updated',
'Size',
];
assert.isFalse(element.isColumnHidden(columnToCheck, columnsToDisplay));
columnsToDisplay = [
'Subject',
'Status',
'Owner',
'Assignee',
'Branch',
'Updated',
'Size',
];
assert.isTrue(element.isColumnHidden(columnToCheck, columnsToDisplay));
});
test('getVisibleColumns maps Project to Repo', () => {
const columns = [
'Subject',
'Status',
'Owner',
];
assert.deepEqual(element.getVisibleColumns(columns), columns.slice(0));
assert.deepEqual(
element.getVisibleColumns(columns.concat(['Project'])),
columns.slice(0).concat(['Repo']));
});
});
</script>

View File

@@ -1,23 +1,21 @@
<!--
@license
Copyright (C) 2017 The Android Open Source Project
/**
* @license
* Copyright (C) 2017 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.
*/
import '../../scripts/gr-display-name-utils/gr-display-name-utils.js';
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="../../scripts/gr-display-name-utils/gr-display-name-utils.js"></script>
<script>
(function(window) {
'use strict';
@@ -57,4 +55,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -19,13 +19,13 @@ limitations under the License.
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-display-name-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-display-name-behavior.html">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module" src="./gr-display-name-behavior.js"></script>
<test-fixture id="basic">
<template>
@@ -33,69 +33,72 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('gr-display-name-behavior tests', async () => {
await readyToTest();
let element;
// eslint-disable-next-line no-unused-vars
const config = {
user: {
anonymous_coward_name: 'Anonymous Coward',
},
};
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './gr-display-name-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('gr-display-name-behavior tests', () => {
let element;
// eslint-disable-next-line no-unused-vars
const config = {
user: {
anonymous_coward_name: 'Anonymous Coward',
},
};
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element-anon',
behaviors: [
Gerrit.DisplayNameBehavior,
],
});
});
setup(() => {
element = fixture('basic');
});
test('getUserName name only', () => {
const account = {
name: 'test-name',
};
assert.deepEqual(element.getUserName(config, account, true), 'test-name');
});
test('getUserName username only', () => {
const account = {
username: 'test-user',
};
assert.deepEqual(element.getUserName(config, account, true), 'test-user');
});
test('getUserName email only', () => {
const account = {
email: 'test-user@test-url.com',
};
assert.deepEqual(element.getUserName(config, account, true),
'test-user@test-url.com');
});
test('getUserName returns not Anonymous Coward as the anon name', () => {
assert.deepEqual(element.getUserName(config, null, true), 'Anonymous');
});
test('getUserName for the config returning the anon name', () => {
const config = {
user: {
anonymous_coward_name: 'Test Anon',
},
};
assert.deepEqual(element.getUserName(config, null, true), 'Test Anon');
});
test('getGroupDisplayName', () => {
assert.equal(element.getGroupDisplayName({name: 'Some user name'}),
'Some user name (group)');
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element-anon',
behaviors: [
Gerrit.DisplayNameBehavior,
],
});
});
setup(() => {
element = fixture('basic');
});
test('getUserName name only', () => {
const account = {
name: 'test-name',
};
assert.deepEqual(element.getUserName(config, account, true), 'test-name');
});
test('getUserName username only', () => {
const account = {
username: 'test-user',
};
assert.deepEqual(element.getUserName(config, account, true), 'test-user');
});
test('getUserName email only', () => {
const account = {
email: 'test-user@test-url.com',
};
assert.deepEqual(element.getUserName(config, account, true),
'test-user@test-url.com');
});
test('getUserName returns not Anonymous Coward as the anon name', () => {
assert.deepEqual(element.getUserName(config, null, true), 'Anonymous');
});
test('getUserName for the config returning the anon name', () => {
const config = {
user: {
anonymous_coward_name: 'Test Anon',
},
};
assert.deepEqual(element.getUserName(config, null, true), 'Test Anon');
});
test('getGroupDisplayName', () => {
assert.equal(element.getGroupDisplayName({name: 'Some user name'}),
'Some user name (group)');
});
});
</script>

View File

@@ -1,22 +1,22 @@
<!--
@license
Copyright (C) 2017 The Android Open Source Project
/**
* @license
* Copyright (C) 2017 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.
*/
import '../base-url-behavior/base-url-behavior.js';
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="../base-url-behavior/base-url-behavior.html">
<link rel="import" href="../gr-url-encoding-behavior/gr-url-encoding-behavior.html">
<script>
import '../gr-url-encoding-behavior/gr-url-encoding-behavior.js';
(function(window) {
'use strict';
@@ -80,5 +80,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -19,13 +19,13 @@ limitations under the License.
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-list-view-behavior.html">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module" src="./gr-list-view-behavior.js"></script>
<test-fixture id="basic">
<template>
@@ -33,62 +33,65 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('gr-list-view-behavior tests', async () => {
await readyToTest();
let element;
// eslint-disable-next-line no-unused-vars
let overlay;
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './gr-list-view-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('gr-list-view-behavior tests', () => {
let element;
// eslint-disable-next-line no-unused-vars
let overlay;
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.ListViewBehavior],
});
});
setup(() => {
element = fixture('basic');
});
test('computeLoadingClass', () => {
assert.equal(element.computeLoadingClass(true), 'loading');
assert.equal(element.computeLoadingClass(false), '');
});
test('computeShownItems', () => {
const myArr = new Array(26);
assert.equal(element.computeShownItems(myArr).length, 25);
});
test('getUrl', () => {
assert.equal(element.getUrl('/path/to/something/', 'item'),
'/path/to/something/item');
assert.equal(element.getUrl('/path/to/something/', 'item%test'),
'/path/to/something/item%2525test');
});
test('getFilterValue', () => {
let params;
assert.equal(element.getFilterValue(params), '');
params = {filter: null};
assert.equal(element.getFilterValue(params), '');
params = {filter: 'test'};
assert.equal(element.getFilterValue(params), 'test');
});
test('getOffsetValue', () => {
let params;
assert.equal(element.getOffsetValue(params), 0);
params = {offset: null};
assert.equal(element.getOffsetValue(params), 0);
params = {offset: 1};
assert.equal(element.getOffsetValue(params), 1);
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.ListViewBehavior],
});
});
setup(() => {
element = fixture('basic');
});
test('computeLoadingClass', () => {
assert.equal(element.computeLoadingClass(true), 'loading');
assert.equal(element.computeLoadingClass(false), '');
});
test('computeShownItems', () => {
const myArr = new Array(26);
assert.equal(element.computeShownItems(myArr).length, 25);
});
test('getUrl', () => {
assert.equal(element.getUrl('/path/to/something/', 'item'),
'/path/to/something/item');
assert.equal(element.getUrl('/path/to/something/', 'item%test'),
'/path/to/something/item%2525test');
});
test('getFilterValue', () => {
let params;
assert.equal(element.getFilterValue(params), '');
params = {filter: null};
assert.equal(element.getFilterValue(params), '');
params = {filter: 'test'};
assert.equal(element.getFilterValue(params), 'test');
});
test('getOffsetValue', () => {
let params;
assert.equal(element.getOffsetValue(params), 0);
params = {offset: null};
assert.equal(element.getOffsetValue(params), 0);
params = {offset: 1};
assert.equal(element.getOffsetValue(params), 1);
});
});
</script>

View File

@@ -1,20 +1,19 @@
<!--
@license
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.
-->
<script>
/**
* @license
* 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(window) {
'use strict';
@@ -298,4 +297,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -15,313 +15,315 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Polymer included for the html import polyfill. -->
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<title>gr-patch-set-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<link rel="import" href="gr-patch-set-behavior.html">
<script type="module" src="./gr-patch-set-behavior.js"></script>
<script>
suite('gr-patch-set-behavior tests', async () => {
await readyToTest();
test('getRevisionByPatchNum', () => {
const get = Gerrit.PatchSetBehavior.getRevisionByPatchNum;
const revisions = [
{_number: 0},
{_number: 1},
{_number: 2},
];
assert.deepEqual(get(revisions, '1'), revisions[1]);
assert.deepEqual(get(revisions, 2), revisions[2]);
assert.equal(get(revisions, '3'), undefined);
});
test('fetchChangeUpdates on latest', done => {
const knownChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
status: 'NEW',
messages: [],
};
const mockRestApi = {
getChangeDetail() {
return Promise.resolve(knownChange);
},
};
Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
.then(result => {
assert.isTrue(result.isLatest);
assert.isNotOk(result.newStatus);
assert.isFalse(result.newMessages);
done();
});
});
test('fetchChangeUpdates not on latest', done => {
const knownChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
status: 'NEW',
messages: [],
};
const actualChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
sha3: {description: 'patch 3', _number: 3},
},
status: 'NEW',
messages: [],
};
const mockRestApi = {
getChangeDetail() {
return Promise.resolve(actualChange);
},
};
Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
.then(result => {
assert.isFalse(result.isLatest);
assert.isNotOk(result.newStatus);
assert.isFalse(result.newMessages);
done();
});
});
test('fetchChangeUpdates new status', done => {
const knownChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
status: 'NEW',
messages: [],
};
const actualChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
status: 'MERGED',
messages: [],
};
const mockRestApi = {
getChangeDetail() {
return Promise.resolve(actualChange);
},
};
Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
.then(result => {
assert.isTrue(result.isLatest);
assert.equal(result.newStatus, 'MERGED');
assert.isFalse(result.newMessages);
done();
});
});
test('fetchChangeUpdates new messages', done => {
const knownChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
status: 'NEW',
messages: [],
};
const actualChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
status: 'NEW',
messages: [{message: 'blah blah'}],
};
const mockRestApi = {
getChangeDetail() {
return Promise.resolve(actualChange);
},
};
Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
.then(result => {
assert.isTrue(result.isLatest);
assert.isNotOk(result.newStatus);
assert.isTrue(result.newMessages);
done();
});
});
test('_computeWipForPatchSets', () => {
// Compute patch sets for a given timeline on a change. The initial WIP
// property of the change can be true or false. The map of tags by
// revision is keyed by patch set number. Each value is a list of change
// message tags in the order that they occurred in the timeline. These
// indicate actions that modify the WIP property of the change and/or
// create new patch sets.
//
// Returns the actual results with an assertWip method that can be used
// to compare against an expected value for a particular patch set.
const compute = (initialWip, tagsByRevision) => {
const change = {
messages: [],
work_in_progress: initialWip,
};
const revs = Object.keys(tagsByRevision).sort((a, b) => a - b);
for (const rev of revs) {
for (const tag of tagsByRevision[rev]) {
change.messages.push({
tag,
_revision_number: rev,
});
}
}
let patchNums = revs.map(rev => { return {num: rev}; });
patchNums = Gerrit.PatchSetBehavior._computeWipForPatchSets(
change, patchNums);
const actualWipsByRevision = {};
for (const patchNum of patchNums) {
actualWipsByRevision[patchNum.num] = patchNum.wip;
}
const verifier = {
assertWip(revision, expectedWip) {
const patchNum = patchNums.find(patchNum => patchNum.num == revision);
if (!patchNum) {
assert.fail('revision ' + revision + ' not found');
}
assert.equal(patchNum.wip, expectedWip,
'wip state for ' + revision + ' is ' +
patchNum.wip + '; expected ' + expectedWip);
return verifier;
},
};
return verifier;
};
compute(false, {1: ['upload']}).assertWip(1, false);
compute(true, {1: ['upload']}).assertWip(1, true);
const setWip = 'autogenerated:gerrit:setWorkInProgress';
const uploadInWip = 'autogenerated:gerrit:newWipPatchSet';
const clearWip = 'autogenerated:gerrit:setReadyForReview';
compute(false, {
1: ['upload', setWip],
2: ['upload'],
3: ['upload', clearWip],
4: ['upload', setWip],
}).assertWip(1, false) // Change was created with PS1 ready for review
.assertWip(2, true) // PS2 was uploaded during WIP
.assertWip(3, false) // PS3 was marked ready for review after upload
.assertWip(4, false); // PS4 was uploaded ready for review
compute(false, {
1: [uploadInWip, null, 'addReviewer'],
2: ['upload'],
3: ['upload', clearWip, setWip],
4: ['upload'],
5: ['upload', clearWip],
6: [uploadInWip],
}).assertWip(1, true) // Change was created in WIP
.assertWip(2, true) // PS2 was uploaded during WIP
.assertWip(3, false) // PS3 was marked ready for review
.assertWip(4, true) // PS4 was uploaded during WIP
.assertWip(5, false) // PS5 was marked ready for review
.assertWip(6, true); // PS6 was uploaded with WIP option
});
test('patchNumEquals', () => {
const equals = Gerrit.PatchSetBehavior.patchNumEquals;
assert.isFalse(equals('edit', 'PARENT'));
assert.isFalse(equals('edit', NaN));
assert.isFalse(equals(1, '2'));
assert.isTrue(equals(1, '1'));
assert.isTrue(equals(1, 1));
assert.isTrue(equals('edit', 'edit'));
assert.isTrue(equals('PARENT', 'PARENT'));
});
test('isMergeParent', () => {
const isParent = Gerrit.PatchSetBehavior.isMergeParent;
assert.isFalse(isParent(1));
assert.isFalse(isParent(4321));
assert.isFalse(isParent('52'));
assert.isFalse(isParent('edit'));
assert.isFalse(isParent('PARENT'));
assert.isFalse(isParent(0));
assert.isTrue(isParent(-23));
assert.isTrue(isParent(-1));
assert.isTrue(isParent('-42'));
});
test('findEditParentRevision', () => {
const findParent = Gerrit.PatchSetBehavior.findEditParentRevision;
let revisions = [
{_number: 0},
{_number: 1},
{_number: 2},
];
assert.strictEqual(findParent(revisions), null);
revisions = [...revisions, {_number: 'edit', basePatchNum: 3}];
assert.strictEqual(findParent(revisions), null);
revisions = [...revisions, {_number: 3}];
assert.deepEqual(findParent(revisions), {_number: 3});
});
test('findEditParentPatchNum', () => {
const findNum = Gerrit.PatchSetBehavior.findEditParentPatchNum;
let revisions = [
{_number: 0},
{_number: 1},
{_number: 2},
];
assert.equal(findNum(revisions), -1);
revisions =
[...revisions, {_number: 'edit', basePatchNum: 3}, {_number: 3}];
assert.deepEqual(findNum(revisions), 3);
});
test('sortRevisions', () => {
const sort = Gerrit.PatchSetBehavior.sortRevisions;
const revisions = [
{_number: 0},
{_number: 2},
{_number: 1},
];
const sorted = [
{_number: 2},
{_number: 1},
{_number: 0},
];
assert.deepEqual(sort(revisions), sorted);
// Edit patchset should follow directly after its basePatchNum.
revisions.push({_number: 'edit', basePatchNum: 2});
sorted.unshift({_number: 'edit', basePatchNum: 2});
assert.deepEqual(sort(revisions), sorted);
revisions[0].basePatchNum = 0;
const edit = sorted.shift();
edit.basePatchNum = 0;
// Edit patchset should be at index 2.
sorted.splice(2, 0, edit);
assert.deepEqual(sort(revisions), sorted);
});
test('getParentIndex', () => {
assert.equal(Gerrit.PatchSetBehavior.getParentIndex('-13'), 13);
assert.equal(Gerrit.PatchSetBehavior.getParentIndex(-4), 4);
});
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './gr-patch-set-behavior.js';
suite('gr-patch-set-behavior tests', () => {
test('getRevisionByPatchNum', () => {
const get = Gerrit.PatchSetBehavior.getRevisionByPatchNum;
const revisions = [
{_number: 0},
{_number: 1},
{_number: 2},
];
assert.deepEqual(get(revisions, '1'), revisions[1]);
assert.deepEqual(get(revisions, 2), revisions[2]);
assert.equal(get(revisions, '3'), undefined);
});
test('fetchChangeUpdates on latest', done => {
const knownChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
status: 'NEW',
messages: [],
};
const mockRestApi = {
getChangeDetail() {
return Promise.resolve(knownChange);
},
};
Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
.then(result => {
assert.isTrue(result.isLatest);
assert.isNotOk(result.newStatus);
assert.isFalse(result.newMessages);
done();
});
});
test('fetchChangeUpdates not on latest', done => {
const knownChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
status: 'NEW',
messages: [],
};
const actualChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
sha3: {description: 'patch 3', _number: 3},
},
status: 'NEW',
messages: [],
};
const mockRestApi = {
getChangeDetail() {
return Promise.resolve(actualChange);
},
};
Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
.then(result => {
assert.isFalse(result.isLatest);
assert.isNotOk(result.newStatus);
assert.isFalse(result.newMessages);
done();
});
});
test('fetchChangeUpdates new status', done => {
const knownChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
status: 'NEW',
messages: [],
};
const actualChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
status: 'MERGED',
messages: [],
};
const mockRestApi = {
getChangeDetail() {
return Promise.resolve(actualChange);
},
};
Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
.then(result => {
assert.isTrue(result.isLatest);
assert.equal(result.newStatus, 'MERGED');
assert.isFalse(result.newMessages);
done();
});
});
test('fetchChangeUpdates new messages', done => {
const knownChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
status: 'NEW',
messages: [],
};
const actualChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
status: 'NEW',
messages: [{message: 'blah blah'}],
};
const mockRestApi = {
getChangeDetail() {
return Promise.resolve(actualChange);
},
};
Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
.then(result => {
assert.isTrue(result.isLatest);
assert.isNotOk(result.newStatus);
assert.isTrue(result.newMessages);
done();
});
});
test('_computeWipForPatchSets', () => {
// Compute patch sets for a given timeline on a change. The initial WIP
// property of the change can be true or false. The map of tags by
// revision is keyed by patch set number. Each value is a list of change
// message tags in the order that they occurred in the timeline. These
// indicate actions that modify the WIP property of the change and/or
// create new patch sets.
//
// Returns the actual results with an assertWip method that can be used
// to compare against an expected value for a particular patch set.
const compute = (initialWip, tagsByRevision) => {
const change = {
messages: [],
work_in_progress: initialWip,
};
const revs = Object.keys(tagsByRevision).sort((a, b) => a - b);
for (const rev of revs) {
for (const tag of tagsByRevision[rev]) {
change.messages.push({
tag,
_revision_number: rev,
});
}
}
let patchNums = revs.map(rev => { return {num: rev}; });
patchNums = Gerrit.PatchSetBehavior._computeWipForPatchSets(
change, patchNums);
const actualWipsByRevision = {};
for (const patchNum of patchNums) {
actualWipsByRevision[patchNum.num] = patchNum.wip;
}
const verifier = {
assertWip(revision, expectedWip) {
const patchNum = patchNums.find(patchNum => patchNum.num == revision);
if (!patchNum) {
assert.fail('revision ' + revision + ' not found');
}
assert.equal(patchNum.wip, expectedWip,
'wip state for ' + revision + ' is ' +
patchNum.wip + '; expected ' + expectedWip);
return verifier;
},
};
return verifier;
};
compute(false, {1: ['upload']}).assertWip(1, false);
compute(true, {1: ['upload']}).assertWip(1, true);
const setWip = 'autogenerated:gerrit:setWorkInProgress';
const uploadInWip = 'autogenerated:gerrit:newWipPatchSet';
const clearWip = 'autogenerated:gerrit:setReadyForReview';
compute(false, {
1: ['upload', setWip],
2: ['upload'],
3: ['upload', clearWip],
4: ['upload', setWip],
}).assertWip(1, false) // Change was created with PS1 ready for review
.assertWip(2, true) // PS2 was uploaded during WIP
.assertWip(3, false) // PS3 was marked ready for review after upload
.assertWip(4, false); // PS4 was uploaded ready for review
compute(false, {
1: [uploadInWip, null, 'addReviewer'],
2: ['upload'],
3: ['upload', clearWip, setWip],
4: ['upload'],
5: ['upload', clearWip],
6: [uploadInWip],
}).assertWip(1, true) // Change was created in WIP
.assertWip(2, true) // PS2 was uploaded during WIP
.assertWip(3, false) // PS3 was marked ready for review
.assertWip(4, true) // PS4 was uploaded during WIP
.assertWip(5, false) // PS5 was marked ready for review
.assertWip(6, true); // PS6 was uploaded with WIP option
});
test('patchNumEquals', () => {
const equals = Gerrit.PatchSetBehavior.patchNumEquals;
assert.isFalse(equals('edit', 'PARENT'));
assert.isFalse(equals('edit', NaN));
assert.isFalse(equals(1, '2'));
assert.isTrue(equals(1, '1'));
assert.isTrue(equals(1, 1));
assert.isTrue(equals('edit', 'edit'));
assert.isTrue(equals('PARENT', 'PARENT'));
});
test('isMergeParent', () => {
const isParent = Gerrit.PatchSetBehavior.isMergeParent;
assert.isFalse(isParent(1));
assert.isFalse(isParent(4321));
assert.isFalse(isParent('52'));
assert.isFalse(isParent('edit'));
assert.isFalse(isParent('PARENT'));
assert.isFalse(isParent(0));
assert.isTrue(isParent(-23));
assert.isTrue(isParent(-1));
assert.isTrue(isParent('-42'));
});
test('findEditParentRevision', () => {
const findParent = Gerrit.PatchSetBehavior.findEditParentRevision;
let revisions = [
{_number: 0},
{_number: 1},
{_number: 2},
];
assert.strictEqual(findParent(revisions), null);
revisions = [...revisions, {_number: 'edit', basePatchNum: 3}];
assert.strictEqual(findParent(revisions), null);
revisions = [...revisions, {_number: 3}];
assert.deepEqual(findParent(revisions), {_number: 3});
});
test('findEditParentPatchNum', () => {
const findNum = Gerrit.PatchSetBehavior.findEditParentPatchNum;
let revisions = [
{_number: 0},
{_number: 1},
{_number: 2},
];
assert.equal(findNum(revisions), -1);
revisions =
[...revisions, {_number: 'edit', basePatchNum: 3}, {_number: 3}];
assert.deepEqual(findNum(revisions), 3);
});
test('sortRevisions', () => {
const sort = Gerrit.PatchSetBehavior.sortRevisions;
const revisions = [
{_number: 0},
{_number: 2},
{_number: 1},
];
const sorted = [
{_number: 2},
{_number: 1},
{_number: 0},
];
assert.deepEqual(sort(revisions), sorted);
// Edit patchset should follow directly after its basePatchNum.
revisions.push({_number: 'edit', basePatchNum: 2});
sorted.unshift({_number: 'edit', basePatchNum: 2});
assert.deepEqual(sort(revisions), sorted);
revisions[0].basePatchNum = 0;
const edit = sorted.shift();
edit.basePatchNum = 0;
// Edit patchset should be at index 2.
sorted.splice(2, 0, edit);
assert.deepEqual(sort(revisions), sorted);
});
test('getParentIndex', () => {
assert.equal(Gerrit.PatchSetBehavior.getParentIndex('-13'), 13);
assert.equal(Gerrit.PatchSetBehavior.getParentIndex(-4), 4);
});
});
</script>

View File

@@ -1,21 +1,21 @@
<!--
@license
Copyright (C) 2016 The Android Open Source Project
/**
* @license
* 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.
*/
import '../../scripts/util.js';
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="../../scripts/util.js"></script>
<script>
(function(window) {
'use strict';
@@ -137,4 +137,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -15,89 +15,91 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Polymer included for the html import polyfill. -->
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<title>gr-path-list-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<link rel="import" href="gr-path-list-behavior.html">
<script type="module" src="./gr-path-list-behavior.js"></script>
<script>
suite('gr-path-list-behavior tests', async () => {
await readyToTest();
test('special sort', () => {
const sort = Gerrit.PathListBehavior.specialFilePathCompare;
const testFiles = [
'/a.h',
'/MERGE_LIST',
'/a.cpp',
'/COMMIT_MSG',
'/asdasd',
'/mrPeanutbutter.py',
];
assert.deepEqual(
testFiles.sort(sort),
[
'/COMMIT_MSG',
'/MERGE_LIST',
'/a.h',
'/a.cpp',
'/asdasd',
'/mrPeanutbutter.py',
]);
});
test('file display name', () => {
const name = Gerrit.PathListBehavior.computeDisplayPath;
assert.equal(name('/foo/bar/baz'), '/foo/bar/baz');
assert.equal(name('/foobarbaz'), '/foobarbaz');
assert.equal(name('/COMMIT_MSG'), 'Commit message');
assert.equal(name('/MERGE_LIST'), 'Merge list');
});
test('isMagicPath', () => {
const isMagic = Gerrit.PathListBehavior.isMagicPath;
assert.isFalse(isMagic(undefined));
assert.isFalse(isMagic('/foo.cc'));
assert.isTrue(isMagic('/COMMIT_MSG'));
assert.isTrue(isMagic('/MERGE_LIST'));
});
test('truncatePath with long path should add ellipsis', () => {
const truncatePath = Gerrit.PathListBehavior.truncatePath;
let path = 'level1/level2/level3/level4/file.js';
let shortenedPath = truncatePath(path);
// The expected path is truncated with an ellipsis.
const expectedPath = '\u2026/file.js';
assert.equal(shortenedPath, expectedPath);
path = 'level2/file.js';
shortenedPath = truncatePath(path);
assert.equal(shortenedPath, expectedPath);
});
test('truncatePath with opt_threshold', () => {
const truncatePath = Gerrit.PathListBehavior.truncatePath;
let path = 'level1/level2/level3/level4/file.js';
let shortenedPath = truncatePath(path, 2);
// The expected path is truncated with an ellipsis.
const expectedPath = '\u2026/level4/file.js';
assert.equal(shortenedPath, expectedPath);
path = 'level2/file.js';
shortenedPath = truncatePath(path, 2);
assert.equal(shortenedPath, path);
});
test('truncatePath with short path should not add ellipsis', () => {
const truncatePath = Gerrit.PathListBehavior.truncatePath;
const path = 'file.js';
const expectedPath = 'file.js';
const shortenedPath = truncatePath(path);
assert.equal(shortenedPath, expectedPath);
});
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './gr-path-list-behavior.js';
suite('gr-path-list-behavior tests', () => {
test('special sort', () => {
const sort = Gerrit.PathListBehavior.specialFilePathCompare;
const testFiles = [
'/a.h',
'/MERGE_LIST',
'/a.cpp',
'/COMMIT_MSG',
'/asdasd',
'/mrPeanutbutter.py',
];
assert.deepEqual(
testFiles.sort(sort),
[
'/COMMIT_MSG',
'/MERGE_LIST',
'/a.h',
'/a.cpp',
'/asdasd',
'/mrPeanutbutter.py',
]);
});
test('file display name', () => {
const name = Gerrit.PathListBehavior.computeDisplayPath;
assert.equal(name('/foo/bar/baz'), '/foo/bar/baz');
assert.equal(name('/foobarbaz'), '/foobarbaz');
assert.equal(name('/COMMIT_MSG'), 'Commit message');
assert.equal(name('/MERGE_LIST'), 'Merge list');
});
test('isMagicPath', () => {
const isMagic = Gerrit.PathListBehavior.isMagicPath;
assert.isFalse(isMagic(undefined));
assert.isFalse(isMagic('/foo.cc'));
assert.isTrue(isMagic('/COMMIT_MSG'));
assert.isTrue(isMagic('/MERGE_LIST'));
});
test('truncatePath with long path should add ellipsis', () => {
const truncatePath = Gerrit.PathListBehavior.truncatePath;
let path = 'level1/level2/level3/level4/file.js';
let shortenedPath = truncatePath(path);
// The expected path is truncated with an ellipsis.
const expectedPath = '\u2026/file.js';
assert.equal(shortenedPath, expectedPath);
path = 'level2/file.js';
shortenedPath = truncatePath(path);
assert.equal(shortenedPath, expectedPath);
});
test('truncatePath with opt_threshold', () => {
const truncatePath = Gerrit.PathListBehavior.truncatePath;
let path = 'level1/level2/level3/level4/file.js';
let shortenedPath = truncatePath(path, 2);
// The expected path is truncated with an ellipsis.
const expectedPath = '\u2026/level4/file.js';
assert.equal(shortenedPath, expectedPath);
path = 'level2/file.js';
shortenedPath = truncatePath(path, 2);
assert.equal(shortenedPath, path);
});
test('truncatePath with short path should not add ellipsis', () => {
const truncatePath = Gerrit.PathListBehavior.truncatePath;
const path = 'file.js';
const expectedPath = 'file.js';
const shortenedPath = truncatePath(path);
assert.equal(shortenedPath, expectedPath);
});
});
</script>

View File

@@ -1,20 +1,19 @@
<!--
@license
Copyright (C) 2019 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>
/**
* @license
* Copyright (C) 2019 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(window) {
'use strict';
@@ -52,4 +51,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -1,21 +0,0 @@
<!--
@license
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="../../elements/shared/gr-tooltip/gr-tooltip.html">
<script src="../../scripts/rootElement.js"></script>
<script src="gr-tooltip-behavior.js"></script>

View File

@@ -14,6 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import '../../scripts/bundled-polymer.js';
import '../../elements/shared/gr-tooltip/gr-tooltip.js';
import '../../scripts/rootElement.js';
import {flush} from '@polymer/polymer/lib/legacy/polymer.dom.js';
(function(window) {
'use strict';
@@ -135,7 +141,7 @@
_positionTooltip(tooltip) {
// This flush is needed for tooltips to be positioned correctly in Firefox
// and Safari.
Polymer.dom.flush();
flush();
const rect = this.getBoundingClientRect();
const boxRect = tooltip.getBoundingClientRect();
const parentRect = tooltip.parentElement.getBoundingClientRect();

View File

@@ -18,15 +18,20 @@ limitations under the License.
<title>tooltip-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-tooltip-behavior.html">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module" src="./gr-tooltip-behavior.js"></script>
<script>void(0);</script>
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './gr-tooltip-behavior.js';
void(0);
</script>
<test-fixture id="basic">
<template>
@@ -34,124 +39,127 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('gr-tooltip-behavior tests', async () => {
await readyToTest();
let element;
let sandbox;
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './gr-tooltip-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('gr-tooltip-behavior tests', () => {
let element;
let sandbox;
function makeTooltip(tooltipRect, parentRect) {
return {
getBoundingClientRect() { return tooltipRect; },
updateStyles: sinon.stub(),
style: {left: 0, top: 0},
parentElement: {
getBoundingClientRect() { return parentRect; },
},
};
}
function makeTooltip(tooltipRect, parentRect) {
return {
getBoundingClientRect() { return tooltipRect; },
updateStyles: sinon.stub(),
style: {left: 0, top: 0},
parentElement: {
getBoundingClientRect() { return parentRect; },
},
};
}
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'tooltip-behavior-element',
behaviors: [Gerrit.TooltipBehavior],
});
});
setup(() => {
sandbox = sinon.sandbox.create();
element = fixture('basic');
});
teardown(() => {
sandbox.restore();
});
test('normal position', () => {
sandbox.stub(element, 'getBoundingClientRect', () => {
return {top: 100, left: 100, width: 200};
});
const tooltip = makeTooltip(
{height: 30, width: 50},
{top: 0, left: 0, width: 1000});
element._positionTooltip(tooltip);
assert.isFalse(tooltip.updateStyles.called);
assert.equal(tooltip.style.left, '175px');
assert.equal(tooltip.style.top, '100px');
});
test('left side position', () => {
sandbox.stub(element, 'getBoundingClientRect', () => {
return {top: 100, left: 10, width: 50};
});
const tooltip = makeTooltip(
{height: 30, width: 120},
{top: 0, left: 0, width: 1000});
element._positionTooltip(tooltip);
assert.isTrue(tooltip.updateStyles.called);
const offset = tooltip.updateStyles
.lastCall.args[0]['--gr-tooltip-arrow-center-offset'];
assert.isBelow(parseFloat(offset.replace(/px$/, '')), 0);
assert.equal(tooltip.style.left, '0px');
assert.equal(tooltip.style.top, '100px');
});
test('right side position', () => {
sandbox.stub(element, 'getBoundingClientRect', () => {
return {top: 100, left: 950, width: 50};
});
const tooltip = makeTooltip(
{height: 30, width: 120},
{top: 0, left: 0, width: 1000});
element._positionTooltip(tooltip);
assert.isTrue(tooltip.updateStyles.called);
const offset = tooltip.updateStyles
.lastCall.args[0]['--gr-tooltip-arrow-center-offset'];
assert.isAbove(parseFloat(offset.replace(/px$/, '')), 0);
assert.equal(tooltip.style.left, '915px');
assert.equal(tooltip.style.top, '100px');
});
test('position to bottom', () => {
sandbox.stub(element, 'getBoundingClientRect', () => {
return {top: 100, left: 950, width: 50, height: 50};
});
const tooltip = makeTooltip(
{height: 30, width: 120},
{top: 0, left: 0, width: 1000});
element.positionBelow = true;
element._positionTooltip(tooltip);
assert.isTrue(tooltip.updateStyles.called);
const offset = tooltip.updateStyles
.lastCall.args[0]['--gr-tooltip-arrow-center-offset'];
assert.isAbove(parseFloat(offset.replace(/px$/, '')), 0);
assert.equal(tooltip.style.left, '915px');
assert.equal(tooltip.style.top, '157.2px');
});
test('hides tooltip when detached', () => {
sandbox.stub(element, '_handleHideTooltip');
element.remove();
flushAsynchronousOperations();
assert.isTrue(element._handleHideTooltip.called);
});
test('sets up listeners when has-tooltip is changed', () => {
const addListenerStub = sandbox.stub(element, 'addEventListener');
element.hasTooltip = true;
assert.isTrue(addListenerStub.called);
});
test('clean up listeners when has-tooltip changed to false', () => {
const removeListenerStub = sandbox.stub(element, 'removeEventListener');
element.hasTooltip = true;
element.hasTooltip = false;
assert.isTrue(removeListenerStub.called);
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'tooltip-behavior-element',
behaviors: [Gerrit.TooltipBehavior],
});
});
setup(() => {
sandbox = sinon.sandbox.create();
element = fixture('basic');
});
teardown(() => {
sandbox.restore();
});
test('normal position', () => {
sandbox.stub(element, 'getBoundingClientRect', () => {
return {top: 100, left: 100, width: 200};
});
const tooltip = makeTooltip(
{height: 30, width: 50},
{top: 0, left: 0, width: 1000});
element._positionTooltip(tooltip);
assert.isFalse(tooltip.updateStyles.called);
assert.equal(tooltip.style.left, '175px');
assert.equal(tooltip.style.top, '100px');
});
test('left side position', () => {
sandbox.stub(element, 'getBoundingClientRect', () => {
return {top: 100, left: 10, width: 50};
});
const tooltip = makeTooltip(
{height: 30, width: 120},
{top: 0, left: 0, width: 1000});
element._positionTooltip(tooltip);
assert.isTrue(tooltip.updateStyles.called);
const offset = tooltip.updateStyles
.lastCall.args[0]['--gr-tooltip-arrow-center-offset'];
assert.isBelow(parseFloat(offset.replace(/px$/, '')), 0);
assert.equal(tooltip.style.left, '0px');
assert.equal(tooltip.style.top, '100px');
});
test('right side position', () => {
sandbox.stub(element, 'getBoundingClientRect', () => {
return {top: 100, left: 950, width: 50};
});
const tooltip = makeTooltip(
{height: 30, width: 120},
{top: 0, left: 0, width: 1000});
element._positionTooltip(tooltip);
assert.isTrue(tooltip.updateStyles.called);
const offset = tooltip.updateStyles
.lastCall.args[0]['--gr-tooltip-arrow-center-offset'];
assert.isAbove(parseFloat(offset.replace(/px$/, '')), 0);
assert.equal(tooltip.style.left, '915px');
assert.equal(tooltip.style.top, '100px');
});
test('position to bottom', () => {
sandbox.stub(element, 'getBoundingClientRect', () => {
return {top: 100, left: 950, width: 50, height: 50};
});
const tooltip = makeTooltip(
{height: 30, width: 120},
{top: 0, left: 0, width: 1000});
element.positionBelow = true;
element._positionTooltip(tooltip);
assert.isTrue(tooltip.updateStyles.called);
const offset = tooltip.updateStyles
.lastCall.args[0]['--gr-tooltip-arrow-center-offset'];
assert.isAbove(parseFloat(offset.replace(/px$/, '')), 0);
assert.equal(tooltip.style.left, '915px');
assert.equal(tooltip.style.top, '157.2px');
});
test('hides tooltip when detached', () => {
sandbox.stub(element, '_handleHideTooltip');
element.remove();
flushAsynchronousOperations();
assert.isTrue(element._handleHideTooltip.called);
});
test('sets up listeners when has-tooltip is changed', () => {
const addListenerStub = sandbox.stub(element, 'addEventListener');
element.hasTooltip = true;
assert.isTrue(addListenerStub.called);
});
test('clean up listeners when has-tooltip changed to false', () => {
const removeListenerStub = sandbox.stub(element, 'removeEventListener');
element.hasTooltip = true;
element.hasTooltip = false;
assert.isTrue(removeListenerStub.called);
});
});
</script>

View File

@@ -1,20 +1,19 @@
<!--
@license
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.
-->
<script>
/**
* @license
* 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(window) {
'use strict';
@@ -73,4 +72,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -18,15 +18,20 @@ limitations under the License.
<title>gr-url-encoding-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-url-encoding-behavior.html">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module" src="./gr-url-encoding-behavior.js"></script>
<script>void(0);</script>
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './gr-url-encoding-behavior.js';
void(0);
</script>
<test-fixture id="basic">
<template>
@@ -34,62 +39,65 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('gr-url-encoding-behavior tests', async () => {
await readyToTest();
let element;
let sandbox;
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './gr-url-encoding-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('gr-url-encoding-behavior tests', () => {
let element;
let sandbox;
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.URLEncodingBehavior],
});
});
setup(() => {
sandbox = sinon.sandbox.create();
element = fixture('basic');
});
teardown(() => {
sandbox.restore();
});
suite('encodeURL', () => {
test('double encodes', () => {
assert.equal(element.encodeURL('abc?123'), 'abc%253F123');
assert.equal(element.encodeURL('def/ghi'), 'def%252Fghi');
assert.equal(element.encodeURL('jkl'), 'jkl');
assert.equal(element.encodeURL(''), '');
});
test('does not convert colons', () => {
assert.equal(element.encodeURL('mno:pqr'), 'mno:pqr');
});
test('converts spaces to +', () => {
assert.equal(element.encodeURL('words with spaces'), 'words+with+spaces');
});
test('does not convert slashes when configured', () => {
assert.equal(element.encodeURL('stu/vwx', true), 'stu/vwx');
});
test('does not convert slashes when configured', () => {
assert.equal(element.encodeURL('stu/vwx', true), 'stu/vwx');
});
});
suite('singleDecodeUrl', () => {
test('single decodes', () => {
assert.equal(element.singleDecodeURL('abc%3Fdef'), 'abc?def');
});
test('converts + to space', () => {
assert.equal(element.singleDecodeURL('ghi+jkl'), 'ghi jkl');
});
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.URLEncodingBehavior],
});
});
setup(() => {
sandbox = sinon.sandbox.create();
element = fixture('basic');
});
teardown(() => {
sandbox.restore();
});
suite('encodeURL', () => {
test('double encodes', () => {
assert.equal(element.encodeURL('abc?123'), 'abc%253F123');
assert.equal(element.encodeURL('def/ghi'), 'def%252Fghi');
assert.equal(element.encodeURL('jkl'), 'jkl');
assert.equal(element.encodeURL(''), '');
});
test('does not convert colons', () => {
assert.equal(element.encodeURL('mno:pqr'), 'mno:pqr');
});
test('converts spaces to +', () => {
assert.equal(element.encodeURL('words with spaces'), 'words+with+spaces');
});
test('does not convert slashes when configured', () => {
assert.equal(element.encodeURL('stu/vwx', true), 'stu/vwx');
});
test('does not convert slashes when configured', () => {
assert.equal(element.encodeURL('stu/vwx', true), 'stu/vwx');
});
});
suite('singleDecodeUrl', () => {
test('single decodes', () => {
assert.equal(element.singleDecodeURL('abc%3Fdef'), 'abc?def');
});
test('converts + to space', () => {
assert.equal(element.singleDecodeURL('ghi+jkl'), 'ghi jkl');
});
});
});
</script>

View File

@@ -1,21 +1,20 @@
<!--
@license
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.
-->
<!--
/**
* @license
* 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.
*/
/*
How to Add a Keyboard Shortcut
==============================
@@ -95,12 +94,17 @@ by gr-app, and actually implemented by gr-comment-thread.
NOTE: doc-only shortcuts will not be customizable in the same way that other
shortcuts are.
-->
<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="/bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
<script src="../../types/polymer-behaviors.js"></script>
*/
/*
FIXME(polymer-modulizer): the above comments were extracted
from HTML and may be out of place here. Review them and
then delete this comment!
*/
import '../../scripts/bundled-polymer.js';
<script>
import {IronA11yKeysBehavior} from '@polymer/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';
import '../../types/polymer-behaviors.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
(function(window) {
'use strict';
@@ -307,7 +311,7 @@ shortcuts are.
/** @return {!(Event|PolymerDomApi|PolymerEventApi)} */
const getKeyboardEvent = function(e) {
e = Polymer.dom(e.detail ? e.detail.keyboardEvent : e);
e = dom(e.detail ? e.detail.keyboardEvent : e);
// When e is a keyboardEvent, e.event is not null.
if (e.event) { e = e.event; }
return e;
@@ -482,7 +486,7 @@ shortcuts are.
/** @polymerBehavior Gerrit.KeyboardShortcutBehavior*/
Gerrit.KeyboardShortcutBehavior = [
Polymer.IronA11yKeysBehavior,
IronA11yKeysBehavior,
{
// Exports for convenience. Note: Closure compiler crashes when
// object-shorthand syntax is used here.
@@ -518,7 +522,7 @@ shortcuts are.
shouldSuppressKeyboardShortcut(e) {
e = getKeyboardEvent(e);
const tagName = Polymer.dom(e).rootTarget.tagName;
const tagName = dom(e).rootTarget.tagName;
if (tagName === 'INPUT' || tagName === 'TEXTAREA' ||
(e.keyCode === 13 && tagName === 'A')) {
// Suppress shortcuts if the key is 'enter' and target is an anchor.
@@ -542,7 +546,7 @@ shortcuts are.
},
getRootTarget(e) {
return Polymer.dom(getKeyboardEvent(e)).rootTarget;
return dom(getKeyboardEvent(e)).rootTarget;
},
bindShortcut(shortcut, ...bindings) {
@@ -671,4 +675,3 @@ shortcuts are.
};
}
})(window);
</script>

View File

@@ -19,13 +19,13 @@ limitations under the License.
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="keyboard-shortcut-behavior.html">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module" src="./keyboard-shortcut-behavior.js"></script>
<test-fixture id="basic">
<template>
@@ -41,403 +41,406 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('keyboard-shortcut-behavior tests', async () => {
await readyToTest();
const kb = window.Gerrit.KeyboardShortcutBinder;
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './keyboard-shortcut-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('keyboard-shortcut-behavior tests', () => {
const kb = window.Gerrit.KeyboardShortcutBinder;
let element;
let overlay;
let sandbox;
let element;
let overlay;
let sandbox;
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.KeyboardShortcutBehavior],
keyBindings: {
k: '_handleKey',
enter: '_handleKey',
},
_handleKey() {},
});
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [Gerrit.KeyboardShortcutBehavior],
keyBindings: {
k: '_handleKey',
enter: '_handleKey',
},
_handleKey() {},
});
});
setup(() => {
element = fixture('basic');
overlay = fixture('within-overlay');
sandbox = sinon.sandbox.create();
});
teardown(() => {
sandbox.restore();
});
suite('ShortcutManager', () => {
test('bindings management', () => {
const mgr = new kb.ShortcutManager();
const {NEXT_FILE} = kb.Shortcut;
assert.isUndefined(mgr.getBindingsForShortcut(NEXT_FILE));
mgr.bindShortcut(NEXT_FILE, ']', '}', 'right');
assert.deepEqual(
mgr.getBindingsForShortcut(NEXT_FILE),
[']', '}', 'right']);
});
setup(() => {
element = fixture('basic');
overlay = fixture('within-overlay');
sandbox = sinon.sandbox.create();
});
suite('binding descriptions', () => {
function mapToObject(m) {
const o = {};
m.forEach((v, k) => o[k] = v);
return o;
}
teardown(() => {
sandbox.restore();
});
suite('ShortcutManager', () => {
test('bindings management', () => {
test('single combo description', () => {
const mgr = new kb.ShortcutManager();
const {NEXT_FILE} = kb.Shortcut;
assert.isUndefined(mgr.getBindingsForShortcut(NEXT_FILE));
mgr.bindShortcut(NEXT_FILE, ']', '}', 'right');
assert.deepEqual(mgr.describeBinding('a'), ['a']);
assert.deepEqual(mgr.describeBinding('a:keyup'), ['a']);
assert.deepEqual(mgr.describeBinding('ctrl+a'), ['Ctrl', 'a']);
assert.deepEqual(
mgr.getBindingsForShortcut(NEXT_FILE),
[']', '}', 'right']);
mgr.describeBinding('ctrl+shift+up:keyup'),
['Ctrl', 'Shift', '']);
});
suite('binding descriptions', () => {
function mapToObject(m) {
const o = {};
m.forEach((v, k) => o[k] = v);
return o;
}
test('combo set description', () => {
const {GO_KEY, DOC_ONLY, ShortcutManager} = kb;
const {GO_TO_OPENED_CHANGES, NEXT_FILE, PREV_FILE} = kb.Shortcut;
test('single combo description', () => {
const mgr = new kb.ShortcutManager();
assert.deepEqual(mgr.describeBinding('a'), ['a']);
assert.deepEqual(mgr.describeBinding('a:keyup'), ['a']);
assert.deepEqual(mgr.describeBinding('ctrl+a'), ['Ctrl', 'a']);
assert.deepEqual(
mgr.describeBinding('ctrl+shift+up:keyup'),
['Ctrl', 'Shift', '↑']);
const mgr = new ShortcutManager();
assert.isNull(mgr.describeBindings(NEXT_FILE));
mgr.bindShortcut(GO_TO_OPENED_CHANGES, GO_KEY, 'o');
assert.deepEqual(
mgr.describeBindings(GO_TO_OPENED_CHANGES),
[['g', 'o']]);
mgr.bindShortcut(NEXT_FILE, DOC_ONLY, ']', 'ctrl+shift+right:keyup');
assert.deepEqual(
mgr.describeBindings(NEXT_FILE),
[[']'], ['Ctrl', 'Shift', '→']]);
mgr.bindShortcut(PREV_FILE, '[');
assert.deepEqual(mgr.describeBindings(PREV_FILE), [['[']]);
});
test('combo set description width', () => {
const mgr = new kb.ShortcutManager();
assert.strictEqual(mgr.comboSetDisplayWidth([['u']]), 1);
assert.strictEqual(mgr.comboSetDisplayWidth([['g', 'o']]), 2);
assert.strictEqual(mgr.comboSetDisplayWidth([['Shift', 'r']]), 6);
assert.strictEqual(mgr.comboSetDisplayWidth([['x'], ['y']]), 4);
assert.strictEqual(
mgr.comboSetDisplayWidth([['x'], ['y'], ['Shift', 'z']]),
12);
});
test('distribute shortcut help', () => {
const mgr = new kb.ShortcutManager();
assert.deepEqual(mgr.distributeBindingDesc([['o']]), [[['o']]]);
assert.deepEqual(
mgr.distributeBindingDesc([['g', 'o']]),
[[['g', 'o']]]);
assert.deepEqual(
mgr.distributeBindingDesc([['ctrl', 'shift', 'meta', 'enter']]),
[[['ctrl', 'shift', 'meta', 'enter']]]);
assert.deepEqual(
mgr.distributeBindingDesc([
['ctrl', 'shift', 'meta', 'enter'],
['o'],
]),
[
[['ctrl', 'shift', 'meta', 'enter']],
[['o']],
]);
assert.deepEqual(
mgr.distributeBindingDesc([
['ctrl', 'enter'],
['meta', 'enter'],
['ctrl', 's'],
['meta', 's'],
]),
[
[['ctrl', 'enter'], ['meta', 'enter']],
[['ctrl', 's'], ['meta', 's']],
]);
});
test('active shortcuts by section', () => {
const {NEXT_FILE, NEXT_LINE, GO_TO_OPENED_CHANGES, SEARCH} =
kb.Shortcut;
const {DIFFS, EVERYWHERE, NAVIGATION} = kb.ShortcutSection;
const mgr = new kb.ShortcutManager();
mgr.bindShortcut(NEXT_FILE, ']');
mgr.bindShortcut(NEXT_LINE, 'j');
mgr.bindShortcut(GO_TO_OPENED_CHANGES, 'g+o');
mgr.bindShortcut(SEARCH, '/');
assert.deepEqual(
mapToObject(mgr.activeShortcutsBySection()),
{});
mgr.attachHost({
keyboardShortcuts() {
return {
[NEXT_FILE]: null,
};
},
});
assert.deepEqual(
mapToObject(mgr.activeShortcutsBySection()),
{
[NAVIGATION]: [
{shortcut: NEXT_FILE, text: 'Go to next file'},
],
});
test('combo set description', () => {
const {GO_KEY, DOC_ONLY, ShortcutManager} = kb;
const {GO_TO_OPENED_CHANGES, NEXT_FILE, PREV_FILE} = kb.Shortcut;
const mgr = new ShortcutManager();
assert.isNull(mgr.describeBindings(NEXT_FILE));
mgr.bindShortcut(GO_TO_OPENED_CHANGES, GO_KEY, 'o');
assert.deepEqual(
mgr.describeBindings(GO_TO_OPENED_CHANGES),
[['g', 'o']]);
mgr.bindShortcut(NEXT_FILE, DOC_ONLY, ']', 'ctrl+shift+right:keyup');
assert.deepEqual(
mgr.describeBindings(NEXT_FILE),
[[']'], ['Ctrl', 'Shift', '→']]);
mgr.bindShortcut(PREV_FILE, '[');
assert.deepEqual(mgr.describeBindings(PREV_FILE), [['[']]);
mgr.attachHost({
keyboardShortcuts() {
return {
[NEXT_LINE]: null,
};
},
});
assert.deepEqual(
mapToObject(mgr.activeShortcutsBySection()),
{
[DIFFS]: [
{shortcut: NEXT_LINE, text: 'Go to next line'},
],
[NAVIGATION]: [
{shortcut: NEXT_FILE, text: 'Go to next file'},
],
});
test('combo set description width', () => {
const mgr = new kb.ShortcutManager();
assert.strictEqual(mgr.comboSetDisplayWidth([['u']]), 1);
assert.strictEqual(mgr.comboSetDisplayWidth([['g', 'o']]), 2);
assert.strictEqual(mgr.comboSetDisplayWidth([['Shift', 'r']]), 6);
assert.strictEqual(mgr.comboSetDisplayWidth([['x'], ['y']]), 4);
assert.strictEqual(
mgr.comboSetDisplayWidth([['x'], ['y'], ['Shift', 'z']]),
12);
mgr.attachHost({
keyboardShortcuts() {
return {
[SEARCH]: null,
[GO_TO_OPENED_CHANGES]: null,
};
},
});
assert.deepEqual(
mapToObject(mgr.activeShortcutsBySection()),
{
[DIFFS]: [
{shortcut: NEXT_LINE, text: 'Go to next line'},
],
[EVERYWHERE]: [
{shortcut: SEARCH, text: 'Search'},
{
shortcut: GO_TO_OPENED_CHANGES,
text: 'Go to Opened Changes',
},
],
[NAVIGATION]: [
{shortcut: NEXT_FILE, text: 'Go to next file'},
],
});
});
test('distribute shortcut help', () => {
const mgr = new kb.ShortcutManager();
assert.deepEqual(mgr.distributeBindingDesc([['o']]), [[['o']]]);
assert.deepEqual(
mgr.distributeBindingDesc([['g', 'o']]),
[[['g', 'o']]]);
assert.deepEqual(
mgr.distributeBindingDesc([['ctrl', 'shift', 'meta', 'enter']]),
[[['ctrl', 'shift', 'meta', 'enter']]]);
assert.deepEqual(
mgr.distributeBindingDesc([
['ctrl', 'shift', 'meta', 'enter'],
['o'],
]),
[
[['ctrl', 'shift', 'meta', 'enter']],
[['o']],
]);
assert.deepEqual(
mgr.distributeBindingDesc([
['ctrl', 'enter'],
['meta', 'enter'],
['ctrl', 's'],
['meta', 's'],
]),
[
[['ctrl', 'enter'], ['meta', 'enter']],
[['ctrl', 's'], ['meta', 's']],
]);
test('directory view', () => {
const {
NEXT_FILE, NEXT_LINE, GO_TO_OPENED_CHANGES, SEARCH,
SAVE_COMMENT,
} = kb.Shortcut;
const {DIFFS, EVERYWHERE, NAVIGATION} = kb.ShortcutSection;
const {GO_KEY, ShortcutManager} = kb;
const mgr = new ShortcutManager();
mgr.bindShortcut(NEXT_FILE, ']');
mgr.bindShortcut(NEXT_LINE, 'j');
mgr.bindShortcut(GO_TO_OPENED_CHANGES, GO_KEY, 'o');
mgr.bindShortcut(SEARCH, '/');
mgr.bindShortcut(
SAVE_COMMENT, 'ctrl+enter', 'meta+enter', 'ctrl+s', 'meta+s');
assert.deepEqual(mapToObject(mgr.directoryView()), {});
mgr.attachHost({
keyboardShortcuts() {
return {
[GO_TO_OPENED_CHANGES]: null,
[NEXT_FILE]: null,
[NEXT_LINE]: null,
[SAVE_COMMENT]: null,
[SEARCH]: null,
};
},
});
test('active shortcuts by section', () => {
const {NEXT_FILE, NEXT_LINE, GO_TO_OPENED_CHANGES, SEARCH} =
kb.Shortcut;
const {DIFFS, EVERYWHERE, NAVIGATION} = kb.ShortcutSection;
const mgr = new kb.ShortcutManager();
mgr.bindShortcut(NEXT_FILE, ']');
mgr.bindShortcut(NEXT_LINE, 'j');
mgr.bindShortcut(GO_TO_OPENED_CHANGES, 'g+o');
mgr.bindShortcut(SEARCH, '/');
assert.deepEqual(
mapToObject(mgr.activeShortcutsBySection()),
{});
mgr.attachHost({
keyboardShortcuts() {
return {
[NEXT_FILE]: null,
};
},
});
assert.deepEqual(
mapToObject(mgr.activeShortcutsBySection()),
{
[NAVIGATION]: [
{shortcut: NEXT_FILE, text: 'Go to next file'},
],
});
mgr.attachHost({
keyboardShortcuts() {
return {
[NEXT_LINE]: null,
};
},
});
assert.deepEqual(
mapToObject(mgr.activeShortcutsBySection()),
{
[DIFFS]: [
{shortcut: NEXT_LINE, text: 'Go to next line'},
],
[NAVIGATION]: [
{shortcut: NEXT_FILE, text: 'Go to next file'},
],
});
mgr.attachHost({
keyboardShortcuts() {
return {
[SEARCH]: null,
[GO_TO_OPENED_CHANGES]: null,
};
},
});
assert.deepEqual(
mapToObject(mgr.activeShortcutsBySection()),
{
[DIFFS]: [
{shortcut: NEXT_LINE, text: 'Go to next line'},
],
[EVERYWHERE]: [
{shortcut: SEARCH, text: 'Search'},
{
shortcut: GO_TO_OPENED_CHANGES,
text: 'Go to Opened Changes',
},
],
[NAVIGATION]: [
{shortcut: NEXT_FILE, text: 'Go to next file'},
],
});
});
test('directory view', () => {
const {
NEXT_FILE, NEXT_LINE, GO_TO_OPENED_CHANGES, SEARCH,
SAVE_COMMENT,
} = kb.Shortcut;
const {DIFFS, EVERYWHERE, NAVIGATION} = kb.ShortcutSection;
const {GO_KEY, ShortcutManager} = kb;
const mgr = new ShortcutManager();
mgr.bindShortcut(NEXT_FILE, ']');
mgr.bindShortcut(NEXT_LINE, 'j');
mgr.bindShortcut(GO_TO_OPENED_CHANGES, GO_KEY, 'o');
mgr.bindShortcut(SEARCH, '/');
mgr.bindShortcut(
SAVE_COMMENT, 'ctrl+enter', 'meta+enter', 'ctrl+s', 'meta+s');
assert.deepEqual(mapToObject(mgr.directoryView()), {});
mgr.attachHost({
keyboardShortcuts() {
return {
[GO_TO_OPENED_CHANGES]: null,
[NEXT_FILE]: null,
[NEXT_LINE]: null,
[SAVE_COMMENT]: null,
[SEARCH]: null,
};
},
});
assert.deepEqual(
mapToObject(mgr.directoryView()),
{
[DIFFS]: [
{binding: [['j']], text: 'Go to next line'},
{
binding: [['Ctrl', 'Enter'], ['Meta', 'Enter']],
text: 'Save comment',
},
{
binding: [['Ctrl', 's'], ['Meta', 's']],
text: 'Save comment',
},
],
[EVERYWHERE]: [
{binding: [['/']], text: 'Search'},
{binding: [['g', 'o']], text: 'Go to Opened Changes'},
],
[NAVIGATION]: [
{binding: [[']']], text: 'Go to next file'},
],
});
});
});
});
test('doesnt block kb shortcuts for non-whitelisted els', done => {
const divEl = document.createElement('div');
element.appendChild(divEl);
element._handleKey = e => {
assert.isFalse(element.shouldSuppressKeyboardShortcut(e));
done();
};
MockInteractions.keyDownOn(divEl, 75, null, 'k');
});
test('blocks kb shortcuts for input els', done => {
const inputEl = document.createElement('input');
element.appendChild(inputEl);
element._handleKey = e => {
assert.isTrue(element.shouldSuppressKeyboardShortcut(e));
done();
};
MockInteractions.keyDownOn(inputEl, 75, null, 'k');
});
test('blocks kb shortcuts for textarea els', done => {
const textareaEl = document.createElement('textarea');
element.appendChild(textareaEl);
element._handleKey = e => {
assert.isTrue(element.shouldSuppressKeyboardShortcut(e));
done();
};
MockInteractions.keyDownOn(textareaEl, 75, null, 'k');
});
test('blocks kb shortcuts for anything in a gr-overlay', done => {
const divEl = document.createElement('div');
const element = overlay.querySelector('test-element');
element.appendChild(divEl);
element._handleKey = e => {
assert.isTrue(element.shouldSuppressKeyboardShortcut(e));
done();
};
MockInteractions.keyDownOn(divEl, 75, null, 'k');
});
test('blocks enter shortcut on an anchor', done => {
const anchorEl = document.createElement('a');
const element = overlay.querySelector('test-element');
element.appendChild(anchorEl);
element._handleKey = e => {
assert.isTrue(element.shouldSuppressKeyboardShortcut(e));
done();
};
MockInteractions.keyDownOn(anchorEl, 13, null, 'enter');
});
test('modifierPressed returns accurate values', () => {
const spy = sandbox.spy(element, 'modifierPressed');
element._handleKey = e => {
element.modifierPressed(e);
};
MockInteractions.keyDownOn(element, 75, 'shift', 'k');
assert.isTrue(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, null, 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, 'ctrl', 'k');
assert.isTrue(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, null, 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, 'meta', 'k');
assert.isTrue(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, null, 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, 'alt', 'k');
assert.isTrue(spy.lastCall.returnValue);
});
test('isModifierPressed returns accurate value', () => {
const spy = sandbox.spy(element, 'isModifierPressed');
element._handleKey = e => {
element.isModifierPressed(e, 'shiftKey');
};
MockInteractions.keyDownOn(element, 75, 'shift', 'k');
assert.isTrue(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, null, 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, 'ctrl', 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, null, 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, 'meta', 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, null, 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, 'alt', 'k');
assert.isFalse(spy.lastCall.returnValue);
});
suite('GO_KEY timing', () => {
let handlerStub;
setup(() => {
element._shortcut_go_table.set('a', '_handleA');
handlerStub = element._handleA = sinon.stub();
sandbox.stub(Date, 'now').returns(10000);
});
test('success', () => {
const e = {detail: {key: 'a'}, preventDefault: () => {}};
sandbox.stub(element, 'shouldSuppressKeyboardShortcut').returns(false);
element._shortcut_go_key_last_pressed = 9000;
element._handleGoAction(e);
assert.isTrue(handlerStub.calledOnce);
assert.strictEqual(handlerStub.lastCall.args[0], e);
});
test('go key not pressed', () => {
const e = {detail: {key: 'a'}, preventDefault: () => {}};
sandbox.stub(element, 'shouldSuppressKeyboardShortcut').returns(false);
element._shortcut_go_key_last_pressed = null;
element._handleGoAction(e);
assert.isFalse(handlerStub.called);
});
test('go key pressed too long ago', () => {
const e = {detail: {key: 'a'}, preventDefault: () => {}};
sandbox.stub(element, 'shouldSuppressKeyboardShortcut').returns(false);
element._shortcut_go_key_last_pressed = 3000;
element._handleGoAction(e);
assert.isFalse(handlerStub.called);
});
test('should suppress', () => {
const e = {detail: {key: 'a'}, preventDefault: () => {}};
sandbox.stub(element, 'shouldSuppressKeyboardShortcut').returns(true);
element._shortcut_go_key_last_pressed = 9000;
element._handleGoAction(e);
assert.isFalse(handlerStub.called);
});
test('unrecognized key', () => {
const e = {detail: {key: 'f'}, preventDefault: () => {}};
sandbox.stub(element, 'shouldSuppressKeyboardShortcut').returns(false);
element._shortcut_go_key_last_pressed = 9000;
element._handleGoAction(e);
assert.isFalse(handlerStub.called);
assert.deepEqual(
mapToObject(mgr.directoryView()),
{
[DIFFS]: [
{binding: [['j']], text: 'Go to next line'},
{
binding: [['Ctrl', 'Enter'], ['Meta', 'Enter']],
text: 'Save comment',
},
{
binding: [['Ctrl', 's'], ['Meta', 's']],
text: 'Save comment',
},
],
[EVERYWHERE]: [
{binding: [['/']], text: 'Search'},
{binding: [['g', 'o']], text: 'Go to Opened Changes'},
],
[NAVIGATION]: [
{binding: [[']']], text: 'Go to next file'},
],
});
});
});
});
test('doesnt block kb shortcuts for non-whitelisted els', done => {
const divEl = document.createElement('div');
element.appendChild(divEl);
element._handleKey = e => {
assert.isFalse(element.shouldSuppressKeyboardShortcut(e));
done();
};
MockInteractions.keyDownOn(divEl, 75, null, 'k');
});
test('blocks kb shortcuts for input els', done => {
const inputEl = document.createElement('input');
element.appendChild(inputEl);
element._handleKey = e => {
assert.isTrue(element.shouldSuppressKeyboardShortcut(e));
done();
};
MockInteractions.keyDownOn(inputEl, 75, null, 'k');
});
test('blocks kb shortcuts for textarea els', done => {
const textareaEl = document.createElement('textarea');
element.appendChild(textareaEl);
element._handleKey = e => {
assert.isTrue(element.shouldSuppressKeyboardShortcut(e));
done();
};
MockInteractions.keyDownOn(textareaEl, 75, null, 'k');
});
test('blocks kb shortcuts for anything in a gr-overlay', done => {
const divEl = document.createElement('div');
const element = overlay.querySelector('test-element');
element.appendChild(divEl);
element._handleKey = e => {
assert.isTrue(element.shouldSuppressKeyboardShortcut(e));
done();
};
MockInteractions.keyDownOn(divEl, 75, null, 'k');
});
test('blocks enter shortcut on an anchor', done => {
const anchorEl = document.createElement('a');
const element = overlay.querySelector('test-element');
element.appendChild(anchorEl);
element._handleKey = e => {
assert.isTrue(element.shouldSuppressKeyboardShortcut(e));
done();
};
MockInteractions.keyDownOn(anchorEl, 13, null, 'enter');
});
test('modifierPressed returns accurate values', () => {
const spy = sandbox.spy(element, 'modifierPressed');
element._handleKey = e => {
element.modifierPressed(e);
};
MockInteractions.keyDownOn(element, 75, 'shift', 'k');
assert.isTrue(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, null, 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, 'ctrl', 'k');
assert.isTrue(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, null, 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, 'meta', 'k');
assert.isTrue(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, null, 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, 'alt', 'k');
assert.isTrue(spy.lastCall.returnValue);
});
test('isModifierPressed returns accurate value', () => {
const spy = sandbox.spy(element, 'isModifierPressed');
element._handleKey = e => {
element.isModifierPressed(e, 'shiftKey');
};
MockInteractions.keyDownOn(element, 75, 'shift', 'k');
assert.isTrue(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, null, 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, 'ctrl', 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, null, 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, 'meta', 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, null, 'k');
assert.isFalse(spy.lastCall.returnValue);
MockInteractions.keyDownOn(element, 75, 'alt', 'k');
assert.isFalse(spy.lastCall.returnValue);
});
suite('GO_KEY timing', () => {
let handlerStub;
setup(() => {
element._shortcut_go_table.set('a', '_handleA');
handlerStub = element._handleA = sinon.stub();
sandbox.stub(Date, 'now').returns(10000);
});
test('success', () => {
const e = {detail: {key: 'a'}, preventDefault: () => {}};
sandbox.stub(element, 'shouldSuppressKeyboardShortcut').returns(false);
element._shortcut_go_key_last_pressed = 9000;
element._handleGoAction(e);
assert.isTrue(handlerStub.calledOnce);
assert.strictEqual(handlerStub.lastCall.args[0], e);
});
test('go key not pressed', () => {
const e = {detail: {key: 'a'}, preventDefault: () => {}};
sandbox.stub(element, 'shouldSuppressKeyboardShortcut').returns(false);
element._shortcut_go_key_last_pressed = null;
element._handleGoAction(e);
assert.isFalse(handlerStub.called);
});
test('go key pressed too long ago', () => {
const e = {detail: {key: 'a'}, preventDefault: () => {}};
sandbox.stub(element, 'shouldSuppressKeyboardShortcut').returns(false);
element._shortcut_go_key_last_pressed = 3000;
element._handleGoAction(e);
assert.isFalse(handlerStub.called);
});
test('should suppress', () => {
const e = {detail: {key: 'a'}, preventDefault: () => {}};
sandbox.stub(element, 'shouldSuppressKeyboardShortcut').returns(true);
element._shortcut_go_key_last_pressed = 9000;
element._handleGoAction(e);
assert.isFalse(handlerStub.called);
});
test('unrecognized key', () => {
const e = {detail: {key: 'f'}, preventDefault: () => {}};
sandbox.stub(element, 'shouldSuppressKeyboardShortcut').returns(false);
element._shortcut_go_key_last_pressed = 9000;
element._handleGoAction(e);
assert.isFalse(handlerStub.called);
});
});
});
</script>

View File

@@ -1,22 +1,22 @@
<!--
@license
Copyright (C) 2016 The Android Open Source Project
/**
* @license
* 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.
*/
import '../../scripts/bundled-polymer.js';
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="../base-url-behavior/base-url-behavior.html">
<script>
import '../base-url-behavior/base-url-behavior.js';
(function(window) {
'use strict';
@@ -198,4 +198,3 @@ limitations under the License.
};
}
})(window);
</script>

View File

@@ -19,19 +19,23 @@ limitations under the License.
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<script>
/** @type {string} */
window.CANONICAL_PATH = '/r';
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import '../base-url-behavior/base-url-behavior.js';
import './rest-client-behavior.js';
/** @type {string} */
window.CANONICAL_PATH = '/r';
</script>
<link rel="import" href="../base-url-behavior/base-url-behavior.html">
<link rel="import" href="rest-client-behavior.html">
<script type="module" src="../base-url-behavior/base-url-behavior.js"></script>
<script type="module" src="./rest-client-behavior.js"></script>
<test-fixture id="basic">
<template>
@@ -47,191 +51,195 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('rest-client-behavior tests', async () => {
await readyToTest();
let element;
// eslint-disable-next-line no-unused-vars
let overlay;
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import '../base-url-behavior/base-url-behavior.js';
import './rest-client-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('rest-client-behavior tests', () => {
let element;
// eslint-disable-next-line no-unused-vars
let overlay;
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [
Gerrit.BaseUrlBehavior,
Gerrit.RESTClientBehavior,
],
});
});
setup(() => {
element = fixture('basic');
overlay = fixture('within-overlay');
});
test('changeBaseURL', () => {
assert.deepEqual(
element.changeBaseURL('test/project', '1', '2'),
'/r/changes/test%2Fproject~1/revisions/2'
);
});
test('changePath', () => {
assert.deepEqual(element.changePath('1'), '/r/c/1');
});
test('Open status', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'NEW',
labels: {},
mergeable: true,
};
let statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, []);
assert.equal(statusString, '');
change.submittable = false;
statuses = element.changeStatuses(change,
{includeDerived: true});
assert.deepEqual(statuses, ['Active']);
// With no missing labels but no submitEnabled option.
change.submittable = true;
statuses = element.changeStatuses(change,
{includeDerived: true});
assert.deepEqual(statuses, ['Active']);
// Without missing labels and enabled submit
statuses = element.changeStatuses(change,
{includeDerived: true, submitEnabled: true});
assert.deepEqual(statuses, ['Ready to submit']);
change.mergeable = false;
change.submittable = true;
statuses = element.changeStatuses(change,
{includeDerived: true});
assert.deepEqual(statuses, ['Merge Conflict']);
delete change.mergeable;
change.submittable = true;
statuses = element.changeStatuses(change,
{includeDerived: true, mergeable: true, submitEnabled: true});
assert.deepEqual(statuses, ['Ready to submit']);
change.submittable = true;
statuses = element.changeStatuses(change,
{includeDerived: true, mergeable: false});
assert.deepEqual(statuses, ['Merge Conflict']);
});
test('Merge conflict', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'NEW',
labels: {},
mergeable: false,
};
const statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, ['Merge Conflict']);
assert.equal(statusString, 'Merge Conflict');
});
test('mergeable prop undefined', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'NEW',
labels: {},
};
const statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, []);
assert.equal(statusString, '');
});
test('Merged status', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'MERGED',
labels: {},
};
const statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, ['Merged']);
assert.equal(statusString, 'Merged');
});
test('Abandoned status', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'ABANDONED',
labels: {},
};
const statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, ['Abandoned']);
assert.equal(statusString, 'Abandoned');
});
test('Open status with private and wip', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'NEW',
is_private: true,
work_in_progress: true,
labels: {},
mergeable: true,
};
const statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, ['WIP', 'Private']);
assert.equal(statusString, 'WIP, Private');
});
test('Merge conflict with private and wip', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'NEW',
is_private: true,
work_in_progress: true,
labels: {},
mergeable: false,
};
const statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, ['Merge Conflict', 'WIP', 'Private']);
assert.equal(statusString, 'Merge Conflict, WIP, Private');
suiteSetup(() => {
// Define a Polymer element that uses this behavior.
Polymer({
is: 'test-element',
behaviors: [
Gerrit.BaseUrlBehavior,
Gerrit.RESTClientBehavior,
],
});
});
setup(() => {
element = fixture('basic');
overlay = fixture('within-overlay');
});
test('changeBaseURL', () => {
assert.deepEqual(
element.changeBaseURL('test/project', '1', '2'),
'/r/changes/test%2Fproject~1/revisions/2'
);
});
test('changePath', () => {
assert.deepEqual(element.changePath('1'), '/r/c/1');
});
test('Open status', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'NEW',
labels: {},
mergeable: true,
};
let statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, []);
assert.equal(statusString, '');
change.submittable = false;
statuses = element.changeStatuses(change,
{includeDerived: true});
assert.deepEqual(statuses, ['Active']);
// With no missing labels but no submitEnabled option.
change.submittable = true;
statuses = element.changeStatuses(change,
{includeDerived: true});
assert.deepEqual(statuses, ['Active']);
// Without missing labels and enabled submit
statuses = element.changeStatuses(change,
{includeDerived: true, submitEnabled: true});
assert.deepEqual(statuses, ['Ready to submit']);
change.mergeable = false;
change.submittable = true;
statuses = element.changeStatuses(change,
{includeDerived: true});
assert.deepEqual(statuses, ['Merge Conflict']);
delete change.mergeable;
change.submittable = true;
statuses = element.changeStatuses(change,
{includeDerived: true, mergeable: true, submitEnabled: true});
assert.deepEqual(statuses, ['Ready to submit']);
change.submittable = true;
statuses = element.changeStatuses(change,
{includeDerived: true, mergeable: false});
assert.deepEqual(statuses, ['Merge Conflict']);
});
test('Merge conflict', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'NEW',
labels: {},
mergeable: false,
};
const statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, ['Merge Conflict']);
assert.equal(statusString, 'Merge Conflict');
});
test('mergeable prop undefined', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'NEW',
labels: {},
};
const statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, []);
assert.equal(statusString, '');
});
test('Merged status', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'MERGED',
labels: {},
};
const statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, ['Merged']);
assert.equal(statusString, 'Merged');
});
test('Abandoned status', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'ABANDONED',
labels: {},
};
const statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, ['Abandoned']);
assert.equal(statusString, 'Abandoned');
});
test('Open status with private and wip', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'NEW',
is_private: true,
work_in_progress: true,
labels: {},
mergeable: true,
};
const statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, ['WIP', 'Private']);
assert.equal(statusString, 'WIP, Private');
});
test('Merge conflict with private and wip', () => {
const change = {
change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
revisions: {
rev1: {_number: 1},
},
current_revision: 'rev1',
status: 'NEW',
is_private: true,
work_in_progress: true,
labels: {},
mergeable: false,
};
const statuses = element.changeStatuses(change);
const statusString = element.changeStatusString(change);
assert.deepEqual(statuses, ['Merge Conflict', 'WIP', 'Private']);
assert.equal(statusString, 'Merge Conflict, WIP, Private');
});
});
</script>

View File

@@ -1,20 +1,19 @@
<!--
@license
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>
/**
* @license
* 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(window) {
'use strict';
@@ -74,4 +73,3 @@ limitations under the License.
throw new Error(`Refused to bind value as ${type}: ${value}`);
};
})(window);
</script>

View File

@@ -18,15 +18,20 @@ limitations under the License.
<title>safe-types-behavior</title>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../test/test-pre-setup.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="safe-types-behavior.html">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../test/test-pre-setup.js"></script>
<script type="module" src="../../test/common-test-setup.js"></script>
<script type="module" src="./safe-types-behavior.js"></script>
<script>void(0);</script>
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './safe-types-behavior.js';
void(0);
</script>
<test-fixture id="basic">
<template>
@@ -34,92 +39,95 @@ limitations under the License.
</template>
</test-fixture>
<script>
suite('gr-tooltip-behavior tests', async () => {
await readyToTest();
let element;
let sandbox;
<script type="module">
import '../../test/test-pre-setup.js';
import '../../test/common-test-setup.js';
import './safe-types-behavior.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
suite('gr-tooltip-behavior tests', () => {
let element;
let sandbox;
suiteSetup(() => {
Polymer({
is: 'safe-types-element',
behaviors: [Gerrit.SafeTypes],
});
});
setup(() => {
sandbox = sinon.sandbox.create();
element = fixture('basic');
});
teardown(() => {
sandbox.restore();
});
test('SafeUrl accepts valid urls', () => {
function accepts(url) {
const safeUrl = new element.SafeUrl(url);
assert.isOk(safeUrl);
assert.equal(url, safeUrl.asString());
}
accepts('http://www.google.com/');
accepts('https://www.google.com/');
accepts('HtTpS://www.google.com/');
accepts('//www.google.com/');
accepts('/c/1234/file/path.html@45');
accepts('#hash-url');
accepts('mailto:name@example.com');
});
test('SafeUrl rejects invalid urls', () => {
function rejects(url) {
assert.throws(() => { new element.SafeUrl(url); });
}
rejects('javascript://alert("evil");');
rejects('ftp:example.com');
rejects('data:text/html,scary business');
});
suite('safeTypesBridge', () => {
function acceptsString(value, type) {
assert.equal(Gerrit.SafeTypes.safeTypesBridge(value, type),
value);
}
function rejects(value, type) {
assert.throws(() => { Gerrit.SafeTypes.safeTypesBridge(value, type); });
}
test('accepts valid URL strings', () => {
acceptsString('/foo/bar', 'URL');
acceptsString('#baz', 'URL');
});
test('rejects invalid URL strings', () => {
rejects('javascript://void();', 'URL');
});
test('accepts SafeUrl values', () => {
const url = '/abc/123';
const safeUrl = new element.SafeUrl(url);
assert.equal(Gerrit.SafeTypes.safeTypesBridge(safeUrl, 'URL'), url);
});
test('rejects non-string or non-SafeUrl types', () => {
rejects(3.1415926, 'URL');
});
test('accepts any binding to STRING or CONSTANT', () => {
acceptsString('foo/bar/baz', 'STRING');
acceptsString('lorem ipsum dolor', 'CONSTANT');
});
test('rejects all other types', () => {
rejects('foo', 'JAVASCRIPT');
rejects('foo', 'HTML');
rejects('foo', 'RESOURCE_URL');
rejects('foo', 'STYLE');
});
suiteSetup(() => {
Polymer({
is: 'safe-types-element',
behaviors: [Gerrit.SafeTypes],
});
});
setup(() => {
sandbox = sinon.sandbox.create();
element = fixture('basic');
});
teardown(() => {
sandbox.restore();
});
test('SafeUrl accepts valid urls', () => {
function accepts(url) {
const safeUrl = new element.SafeUrl(url);
assert.isOk(safeUrl);
assert.equal(url, safeUrl.asString());
}
accepts('http://www.google.com/');
accepts('https://www.google.com/');
accepts('HtTpS://www.google.com/');
accepts('//www.google.com/');
accepts('/c/1234/file/path.html@45');
accepts('#hash-url');
accepts('mailto:name@example.com');
});
test('SafeUrl rejects invalid urls', () => {
function rejects(url) {
assert.throws(() => { new element.SafeUrl(url); });
}
rejects('javascript://alert("evil");');
rejects('ftp:example.com');
rejects('data:text/html,scary business');
});
suite('safeTypesBridge', () => {
function acceptsString(value, type) {
assert.equal(Gerrit.SafeTypes.safeTypesBridge(value, type),
value);
}
function rejects(value, type) {
assert.throws(() => { Gerrit.SafeTypes.safeTypesBridge(value, type); });
}
test('accepts valid URL strings', () => {
acceptsString('/foo/bar', 'URL');
acceptsString('#baz', 'URL');
});
test('rejects invalid URL strings', () => {
rejects('javascript://void();', 'URL');
});
test('accepts SafeUrl values', () => {
const url = '/abc/123';
const safeUrl = new element.SafeUrl(url);
assert.equal(Gerrit.SafeTypes.safeTypesBridge(safeUrl, 'URL'), url);
});
test('rejects non-string or non-SafeUrl types', () => {
rejects(3.1415926, 'URL');
});
test('accepts any binding to STRING or CONSTANT', () => {
acceptsString('foo/bar/baz', 'STRING');
acceptsString('lorem ipsum dolor', 'CONSTANT');
});
test('rejects all other types', () => {
rejects('foo', 'JAVASCRIPT');
rejects('foo', 'HTML');
rejects('foo', 'RESOURCE_URL');
rejects('foo', 'STYLE');
});
});
});
</script>