mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-03 04:29:28 +01:00
- Fix including everything just for a unit test
- Start of some tests for Et2Button
This commit is contained in:
parent
d656eb0e69
commit
ef3848fd3c
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Test file for Etemplate webComponent base widget Et2Box
|
* Test file for Etemplate webComponent base widget Et2Box
|
||||||
*/
|
*/
|
||||||
import {assert, expect, fixture} from '@open-wc/testing';
|
import {assert, fixture} from '@open-wc/testing';
|
||||||
import {Et2Box} from "../Et2Box";
|
import {Et2Box} from "../Et2Box";
|
||||||
import {html} from "lit-element";
|
import {html} from "lit-element";
|
||||||
|
|
||||||
|
@ -9,12 +9,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import {css, html} from "../../../node_modules/@lion/core/index.js";
|
import {css, html} from "../../../../node_modules/@lion/core/index.js";
|
||||||
import {LionButton} from "../../../node_modules/@lion/button/index.js";
|
import {LionButton} from "../../../../node_modules/@lion/button/index.js";
|
||||||
import {SlotMixin} from "../../../node_modules/@lion/core/src/SlotMixin.js";
|
import {SlotMixin} from "../../../../node_modules/@lion/core/src/SlotMixin.js";
|
||||||
import {Et2InputWidget} from "./et2_core_inputWidget";
|
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
|
||||||
import {Et2Widget} from "./Et2Widget";
|
import {Et2Widget} from "../Et2Widget";
|
||||||
import {et2_compileLegacyJS} from "./et2_core_legacyJSFunctions";
|
|
||||||
|
|
||||||
export class Et2Button extends Et2InputWidget(Et2Widget(SlotMixin(LionButton)))
|
export class Et2Button extends Et2InputWidget(Et2Widget(SlotMixin(LionButton)))
|
||||||
{
|
{
|
||||||
@ -96,7 +95,10 @@ export class Et2Button extends Et2InputWidget(Et2Widget(SlotMixin(LionButton)))
|
|||||||
_handleClick(event : MouseEvent) : boolean
|
_handleClick(event : MouseEvent) : boolean
|
||||||
{
|
{
|
||||||
// ignore click on readonly button
|
// ignore click on readonly button
|
||||||
if(this.disabled || this.readonly) return false;
|
if(this.disabled || this.readonly)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
this.clicked = true;
|
this.clicked = true;
|
||||||
|
|
42
api/js/etemplate/Et2Button/test/Et2Button.test.ts
Normal file
42
api/js/etemplate/Et2Button/test/Et2Button.test.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Test file for Etemplate webComponent base widget Et2Box
|
||||||
|
*/
|
||||||
|
import {assert, fixture} from '@open-wc/testing';
|
||||||
|
import {Et2Button} from "../Et2Button";
|
||||||
|
import type {Et2Widget} from "../../Et2Widget";
|
||||||
|
import {html} from "lit-element";
|
||||||
|
import * as sinon from 'sinon';
|
||||||
|
|
||||||
|
describe("Button widget", () =>
|
||||||
|
{
|
||||||
|
// Reference to component under test
|
||||||
|
let element : Et2Button;
|
||||||
|
|
||||||
|
|
||||||
|
// Setup run before each test
|
||||||
|
beforeEach(async() =>
|
||||||
|
{
|
||||||
|
// Create an element to test with, and wait until it's ready
|
||||||
|
element = await fixture<Et2Button>(html`
|
||||||
|
<et2-button label="I'm a button"></et2-button>
|
||||||
|
`);
|
||||||
|
|
||||||
|
// Stub egw()
|
||||||
|
sinon.stub(element, "egw").returns({
|
||||||
|
tooltipUnbind: () => {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Make sure it works
|
||||||
|
it('is defined', () =>
|
||||||
|
{
|
||||||
|
assert.instanceOf(element, Et2Button);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has a label', () =>
|
||||||
|
{
|
||||||
|
element.set_label("Label set");
|
||||||
|
|
||||||
|
assert.equal(element.textContent, "Label set");
|
||||||
|
})
|
||||||
|
});
|
@ -12,7 +12,7 @@
|
|||||||
import {css, html} from "../../../node_modules/@lion/core/index.js";
|
import {css, html} from "../../../node_modules/@lion/core/index.js";
|
||||||
import {LionInputDatepicker} from "../../../node_modules/@lion/input-datepicker/index.js";
|
import {LionInputDatepicker} from "../../../node_modules/@lion/input-datepicker/index.js";
|
||||||
import {Unparseable} from "../../../node_modules/@lion/form-core/src/validate/Unparseable.js";
|
import {Unparseable} from "../../../node_modules/@lion/form-core/src/validate/Unparseable.js";
|
||||||
import {Et2InputWidget} from "./et2_core_inputWidget";
|
import {Et2InputWidget} from "./Et2InputWidget/Et2InputWidget";
|
||||||
import {Et2Widget} from "./Et2Widget";
|
import {Et2Widget} from "./Et2Widget";
|
||||||
|
|
||||||
|
|
||||||
|
115
api/js/etemplate/Et2InputWidget/Et2InputWidget.ts
Normal file
115
api/js/etemplate/Et2InputWidget/Et2InputWidget.ts
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import {et2_IInput, et2_IInputNode} from "../et2_core_interfaces";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This mixin will allow any LitElement to become an Et2InputWidget
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* export class Et2Button extends Et2InputWidget(Et2Widget(LitWidget)) {...}
|
||||||
|
*/
|
||||||
|
|
||||||
|
type Constructor<T = {}> = new (...args : any[]) => T;
|
||||||
|
export const Et2InputWidget = <T extends Constructor>(superClass : T) =>
|
||||||
|
{
|
||||||
|
class Et2InputWidgetClass extends superClass implements et2_IInput, et2_IInputNode
|
||||||
|
{
|
||||||
|
|
||||||
|
label : string = '';
|
||||||
|
protected value : string | number | Object;
|
||||||
|
protected _oldValue : string | number | Object;
|
||||||
|
|
||||||
|
/** WebComponent **/
|
||||||
|
static get properties()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
...super.properties,
|
||||||
|
// readOnly is what the property is in Lion, readonly is the attribute
|
||||||
|
readOnly: {
|
||||||
|
type: Boolean,
|
||||||
|
attribute: 'readonly',
|
||||||
|
reflect: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
set_value(new_value)
|
||||||
|
{
|
||||||
|
this.value = new_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_value()
|
||||||
|
{
|
||||||
|
return this.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue()
|
||||||
|
{
|
||||||
|
return typeof this.serializedValue !== "undefined" ? this.serializedValue : this.modalValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
isDirty()
|
||||||
|
{
|
||||||
|
let value = this.getValue();
|
||||||
|
if(typeof value !== typeof this._oldValue)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(this._oldValue === value)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch(typeof this._oldValue)
|
||||||
|
{
|
||||||
|
case "object":
|
||||||
|
if(typeof this._oldValue.length !== "undefined" &&
|
||||||
|
this._oldValue.length !== value.length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for(let key in this._oldValue)
|
||||||
|
{
|
||||||
|
if(this._oldValue[key] !== value[key])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return this._oldValue != value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resetDirty()
|
||||||
|
{
|
||||||
|
this._oldValue = this.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
isValid(messages)
|
||||||
|
{
|
||||||
|
var ok = true;
|
||||||
|
|
||||||
|
// Check for required
|
||||||
|
if(this.options && this.options.needed && !this.options.readonly && !this.disabled &&
|
||||||
|
(this.getValue() == null || this.getValue().valueOf() == ''))
|
||||||
|
{
|
||||||
|
messages.push(this.egw().lang('Field must not be empty !!!'));
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
getInputNode()
|
||||||
|
{
|
||||||
|
// From LionInput
|
||||||
|
return this._inputNode;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return Et2InputWidgetClass as unknown as Constructor<et2_IInput> & T;
|
||||||
|
}
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
import {css, html} from "../../../node_modules/@lion/core/index.js"
|
import {css, html} from "../../../node_modules/@lion/core/index.js"
|
||||||
import {LionTextarea} from "../../../node_modules/@lion/textarea/index.js"
|
import {LionTextarea} from "../../../node_modules/@lion/textarea/index.js"
|
||||||
import {Et2InputWidget} from "./et2_core_inputWidget";
|
import {Et2InputWidget} from "./Et2InputWidget/Et2InputWidget";
|
||||||
import {Et2Widget} from "./Et2Widget";
|
import {Et2Widget} from "./Et2Widget";
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
import {css, html} from "../../../node_modules/@lion/core/index.js"
|
import {css, html} from "../../../node_modules/@lion/core/index.js"
|
||||||
import {LionInput} from "../../../node_modules/@lion/input/index.js"
|
import {LionInput} from "../../../node_modules/@lion/input/index.js"
|
||||||
import {Et2InputWidget} from "./et2_core_inputWidget";
|
import {Et2InputWidget} from "./Et2InputWidget/Et2InputWidget";
|
||||||
import {Et2Widget} from "./Et2Widget";
|
import {Et2Widget} from "./Et2Widget";
|
||||||
|
|
||||||
export class Et2Textbox extends Et2InputWidget(Et2Widget(LionInput))
|
export class Et2Textbox extends Et2InputWidget(Et2Widget(LionInput))
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import {et2_IDOMNode, et2_implements_registry} from "./et2_core_interfaces";
|
import {et2_IDOMNode, et2_implements_registry} from "./et2_core_interfaces";
|
||||||
import {et2_arrayMgr} from "./et2_core_arrayMgr";
|
import {et2_arrayMgr} from "./et2_core_arrayMgr";
|
||||||
import {et2_attribute_registry, et2_registry, et2_widget} from "./et2_core_widget";
|
import {et2_attribute_registry, et2_registry, et2_widget} from "./et2_core_widget";
|
||||||
import {etemplate2} from "./etemplate2";
|
import type {etemplate2} from "./etemplate2";
|
||||||
import {et2_compileLegacyJS} from "./et2_core_legacyJSFunctions";
|
import {et2_compileLegacyJS} from "./et2_core_legacyJSFunctions";
|
||||||
import {et2_cloneObject, et2_csvSplit} from "./et2_core_common";
|
import {et2_cloneObject, et2_csvSplit} from "./et2_core_common";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import {IegwAppLocal} from "../jsapi/egw_global";
|
import type {IegwAppLocal} from "../jsapi/egw_global";
|
||||||
import {ClassWithAttributes, ClassWithInterfaces} from "./et2_core_inheritance";
|
import {ClassWithAttributes, ClassWithInterfaces} from "./et2_core_inheritance";
|
||||||
import {LitElement} from "@lion/core";
|
import {LitElement} from "@lion/core";
|
||||||
import {et2_container} from "./et2_core_baseWidget";
|
import type {et2_container} from "./et2_core_baseWidget";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This mixin will allow any LitElement to become an Et2Widget
|
* This mixin will allow any LitElement to become an Et2Widget
|
||||||
@ -117,7 +117,7 @@ export const Et2Widget = <T extends Constructor<LitElement>>(superClass : T) =>
|
|||||||
*
|
*
|
||||||
* @param value
|
* @param value
|
||||||
*/
|
*/
|
||||||
set_label(value)
|
set_label(value : string)
|
||||||
{
|
{
|
||||||
let oldValue = this.label;
|
let oldValue = this.label;
|
||||||
|
|
||||||
|
@ -391,114 +391,3 @@ export class et2_inputWidget extends et2_valueWidget implements et2_IInput, et2_
|
|||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This mixin will allow any LitElement to become an Et2InputWidget
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* export class Et2Button extends Et2InputWidget(Et2Widget(LitWidget)) {...}
|
|
||||||
*/
|
|
||||||
|
|
||||||
type Constructor<T = {}> = new (...args: any[]) => T;
|
|
||||||
export const Et2InputWidget = <T extends Constructor>(superClass: T) =>
|
|
||||||
{
|
|
||||||
class Et2InputWidgetClass extends superClass implements et2_IInput, et2_IInputNode
|
|
||||||
{
|
|
||||||
|
|
||||||
label: string = '';
|
|
||||||
protected value: string | number | Object;
|
|
||||||
protected _oldValue: string | number | Object;
|
|
||||||
|
|
||||||
/** WebComponent **/
|
|
||||||
static get properties()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
...super.properties,
|
|
||||||
// readOnly is what the property is in Lion, readonly is the attribute
|
|
||||||
readOnly: {
|
|
||||||
type: Boolean,
|
|
||||||
attribute: 'readonly',
|
|
||||||
reflect: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor()
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
set_value(new_value)
|
|
||||||
{
|
|
||||||
this.value = new_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_value()
|
|
||||||
{
|
|
||||||
return this.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
getValue()
|
|
||||||
{
|
|
||||||
return typeof this.serializedValue !== "undefined" ? this.serializedValue : this.modalValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
isDirty()
|
|
||||||
{
|
|
||||||
let value = this.getValue();
|
|
||||||
if(typeof value !== typeof this._oldValue)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if(this._oldValue === value)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
switch (typeof this._oldValue)
|
|
||||||
{
|
|
||||||
case "object":
|
|
||||||
if (typeof this._oldValue.length !== "undefined" &&
|
|
||||||
this._oldValue.length !== value.length
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (let key in this._oldValue)
|
|
||||||
{
|
|
||||||
if (this._oldValue[key] !== value[key]) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
return this._oldValue != value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resetDirty()
|
|
||||||
{
|
|
||||||
this._oldValue = this.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
isValid(messages)
|
|
||||||
{
|
|
||||||
var ok = true;
|
|
||||||
|
|
||||||
// Check for required
|
|
||||||
if (this.options && this.options.needed && !this.options.readonly && !this.disabled &&
|
|
||||||
(this.getValue() == null || this.getValue().valueOf() == ''))
|
|
||||||
{
|
|
||||||
messages.push(this.egw().lang('Field must not be empty !!!'));
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
getInputNode()
|
|
||||||
{
|
|
||||||
// From LionInput
|
|
||||||
return this._inputNode;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return Et2InputWidgetClass as unknown as Constructor<et2_IInput> & T;
|
|
||||||
}
|
|
@ -24,7 +24,7 @@ import {et2_tabbox} from "./et2_widget_tabs";
|
|||||||
import '../jsapi/egw_json.js';
|
import '../jsapi/egw_json.js';
|
||||||
import {egwIsMobile} from "../egw_action/egw_action_common.js";
|
import {egwIsMobile} from "../egw_action/egw_action_common.js";
|
||||||
import './Et2Box/Et2Box';
|
import './Et2Box/Et2Box';
|
||||||
import './Et2Button';
|
import './Et2Button/Et2Button';
|
||||||
import './Et2Date';
|
import './Et2Date';
|
||||||
import './Et2Textarea';
|
import './Et2Textarea';
|
||||||
import './Et2Textbox';
|
import './Et2Textbox';
|
||||||
|
7235
package-lock.json
generated
7235
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -32,6 +32,7 @@
|
|||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rollup": "^2.52.2",
|
"rollup": "^2.52.2",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
|
"sinon": "^11.1.2",
|
||||||
"terser": "^4.8.0",
|
"terser": "^4.8.0",
|
||||||
"typescript": "^3.9.7"
|
"typescript": "^3.9.7"
|
||||||
},
|
},
|
||||||
|
@ -2,22 +2,19 @@ import fs from 'fs';
|
|||||||
import {playwrightLauncher} from '@web/test-runner-playwright';
|
import {playwrightLauncher} from '@web/test-runner-playwright';
|
||||||
import {esbuildPlugin} from '@web/dev-server-esbuild';
|
import {esbuildPlugin} from '@web/dev-server-esbuild';
|
||||||
|
|
||||||
const packages =
|
// Get tests for web components (in their own directory)
|
||||||
// Get tests for web components (in their own directory)
|
const webComponents = fs.readdirSync('api/js/etemplate')
|
||||||
fs.readdirSync('api/js/etemplate')
|
|
||||||
.filter(
|
.filter(
|
||||||
dir => fs.statSync(`api/js/etemplate/${dir}`).isDirectory() && fs.existsSync(`api/js/etemplate/${dir}/test`),
|
dir => fs.statSync(`api/js/etemplate/${dir}`).isDirectory() && fs.existsSync(`api/js/etemplate/${dir}/test`),
|
||||||
)
|
)
|
||||||
.map(dir => `api/js/etemplate/${dir}/test`)
|
.map(dir => `api/js/etemplate/${dir}/test`);
|
||||||
|
|
||||||
// Add any test files in app/js/test/
|
// Add any test files in app/js/test/
|
||||||
.concat(
|
const appJS = fs.readdirSync('.')
|
||||||
fs.readdirSync('.')
|
|
||||||
.filter(
|
.filter(
|
||||||
dir => fs.existsSync(`${dir}/js`) && fs.existsSync(`${dir}/js/test`) && fs.statSync(`${dir}/js/test`).isDirectory(),
|
dir => fs.existsSync(`${dir}/js`) && fs.existsSync(`${dir}/js/test`) && fs.statSync(`${dir}/js/test`).isDirectory(),
|
||||||
)
|
)
|
||||||
.map(dir => `${dir}/js/test`)
|
|
||||||
)
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
nodeResolve: true,
|
nodeResolve: true,
|
||||||
@ -42,14 +39,23 @@ export default {
|
|||||||
// Dependant on specific versions of shared libraries (libicuuc.so.66, latest is .67)
|
// Dependant on specific versions of shared libraries (libicuuc.so.66, latest is .67)
|
||||||
//playwrightLauncher({ product: 'webkit' }),
|
//playwrightLauncher({ product: 'webkit' }),
|
||||||
],
|
],
|
||||||
groups: packages.map(pkg =>
|
groups:
|
||||||
|
webComponents.map(pkg =>
|
||||||
{
|
{
|
||||||
console.log(pkg);
|
|
||||||
return {
|
return {
|
||||||
name: pkg,
|
name: `${pkg}`,
|
||||||
files: `${pkg}/**/*.test.ts`,
|
files: `${pkg}/*.test.ts`
|
||||||
};
|
};
|
||||||
}),
|
}).concat(
|
||||||
|
appJS.map(app =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
name: app,
|
||||||
|
files: `${app}/js/**/*.test.ts`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
))
|
||||||
|
,
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
// Handles typescript
|
// Handles typescript
|
||||||
|
Loading…
Reference in New Issue
Block a user