` **class** The class of the button
215 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/docs/index.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | This [ember-cli](http://www.ember-cli.com) addon is based on the following
4 | excellent addons
5 |
6 | - [ember-changeset](https://github.com/DockYard/ember-changeset)
7 | - [ember-changeset-validations](https://github.com/DockYard/ember-changeset-validations/)
8 |
9 | and provides a handy out-of-the-box setup for user-friendly client-side
10 | validations, featuring
11 |
12 | - Hiding of validation errors until field has been interacted with (or submit button was pressed)
13 | - Preventing submit action until form is valid
14 | - Live-updating validation errors
15 | - Bootstrap integration
16 | - Loading class on submit button while async task is executed
17 | - Loading contextual template parameter set while async submit task is executed
18 |
19 | ## Why \*YAEFA?
20 |
21 | \*_Yet another ember form addon_
22 |
23 | There are many [existing ember
24 | addons](https://emberobserver.com/categories/forms) with this style of API,
25 | the most prominent probably being
26 | [ember-form-for](https://github.com/martndemus/ember-form-for). With this
27 | addon, we want to:
28 |
29 | - focus on forms that require client-side validations
30 | - provide good user experience out of the box
31 |
32 | For more information, see this [blog
33 | post](https://adfinis.com/en/blog/form-validation-with-ember-js/).
34 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/docs/migration-v6.md:
--------------------------------------------------------------------------------
1 | # Migration to v6
2 |
3 | ## Config
4 |
5 | `ember-validated-form` is heavily based on dynamic component invokation which
6 | needed alot of changes in order to make it work with embroider. For the
7 | consumers of the addon, the only thing that changes is the static configuration.
8 |
9 | Since we switched from runtime configuration to build time configuration, the
10 | current configuration of `ember-validated-form` needs to be moved from
11 | `config/environment.js` to the `ember-cli-build.js` file:
12 |
13 | **Before:**
14 |
15 | ```js
16 | // config/environment.js
17 | var ENV = {
18 | // ...
19 | "ember-validated-form": {
20 | theme: "bootstrap",
21 | features: {
22 | scrollErrorIntoView: true,
23 | },
24 | defaults: {
25 | error: "some-component",
26 | // ...
27 | },
28 | },
29 | // ...
30 | };
31 | ```
32 |
33 | **After:**
34 |
35 | ```js
36 | // ember-cli-build.js
37 | const app = new EmberAddon(defaults, {
38 | // ...
39 | "ember-validated-form": {
40 | theme: "bootstrap",
41 | features: {
42 | scrollErrorIntoView: true,
43 | },
44 | defaults: {
45 | error: "myapp/components/some-component",
46 | // ...
47 | },
48 | },
49 | // ...
50 | });
51 | ```
52 |
53 | As you can see above, the values in the section `defaults` changed as well.
54 | Previously the value was just the name of the component used as default, since
55 | v6 this needs to be an importable path (which allows static analysis).
56 |
57 | ## Removed deprecations
58 |
59 | The `includeBlank` argument for validated inputs has been removed in favor of
60 | `prompt`.
61 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/docs/quickstart.md:
--------------------------------------------------------------------------------
1 | # Quickstart
2 |
3 | You'll find a basic example in [this
4 | twiddle](https://ember-twiddle.com/95b040c96b7dc60dc4d0bb2dc5f5de26?openFiles=templates.application.hbs%2C)
--------------------------------------------------------------------------------
/tests/dummy/app/templates/docs/troubleshooting.md:
--------------------------------------------------------------------------------
1 | # Troubleshooting
2 |
3 | ## 'Proxy' is undefined (IE11)
4 |
5 | `ember-validated-form` installs `ember-changeset` and
6 | `ember-changeset-validations` **v3+** per default which relies heavily on
7 | `Proxy` which is not supported by IE11. If you need to support IE11 you'll
8 | need to [polyfill it](https://github.com/GoogleChrome/proxy-polyfill) or if
9 | you don't want to polyfill it, you can use `ember-changeset` and
10 | `ember-changeset-validations` **v2.x**.
11 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/docs/usage.md:
--------------------------------------------------------------------------------
1 | # Usage
2 |
3 | First, install the addon:
4 |
5 | ```bash
6 | $ ember install ember-validated-form
7 | ```
8 |
9 | This will also install `ember-changeset` and `ember-changeset-validations`.
10 | After, you'll need to set up
11 |
12 | - a template containing your form elements
13 | - a validations file (see [ember-changeset-validations](https://github.com/poteto/ember-changeset-validations))
14 | - a controller, route and/or component that provides your template with the validations and your model
15 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/index.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 | Built with ♥ by
11 | Adfinis
12 |
13 |
35 |
36 |
37 |
38 |
39 | {{! BEGIN-SNIPPET quickstart-template.hbs }}
40 | {{#if @model.saved}}
41 |
42 | Model was successfully saved!
43 |
44 | {{/if}}
45 |
46 |
51 |
58 |
59 |
60 |
61 |
62 |
63 |
70 |
71 |
80 |
81 |
82 |
83 |
89 |
90 |
96 |
97 |
103 |
104 |
108 |
109 | {{! END-SNIPPET }}
110 |
111 |
112 |
113 |
114 |
115 |
119 |
123 |
127 |
128 |
--------------------------------------------------------------------------------
/tests/dummy/app/templates/not-found.hbs:
--------------------------------------------------------------------------------
1 |
2 |
Not found
3 |
This page doesn't exist. Head home?
4 |
--------------------------------------------------------------------------------
/tests/dummy/app/validations/user.js:
--------------------------------------------------------------------------------
1 | // BEGIN-SNIPPET quickstart-validations.js
2 | import {
3 | validatePresence,
4 | validateLength,
5 | validateInclusion,
6 | } from "ember-changeset-validations/validators";
7 |
8 | export default {
9 | firstName: [validatePresence(true), validateLength({ min: 3, max: 40 })],
10 | lastName: [validatePresence(true), validateLength({ min: 3, max: 40 })],
11 | aboutMe: [validateLength({ allowBlank: true, max: 200 })],
12 | country: [validatePresence(true)],
13 | title: [validatePresence(true)],
14 | terms: [
15 | validateInclusion({
16 | list: [true],
17 | message: "Please accept the terms and conditions!",
18 | }),
19 | ],
20 | color: [validatePresence(true)],
21 | };
22 | // END-SNIPPET
23 |
--------------------------------------------------------------------------------
/tests/dummy/config/ember-cli-update.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": "1.0.0",
3 | "packages": [
4 | {
5 | "name": "ember-cli",
6 | "version": "5.7.0",
7 | "blueprints": [
8 | {
9 | "name": "addon",
10 | "outputRepo": "https://github.com/ember-cli/ember-addon-output",
11 | "codemodsSource": "ember-addon-codemods-manifest@1",
12 | "isBaseBlueprint": true,
13 | "options": ["--pnpm", "--no-welcome"]
14 | }
15 | ]
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/tests/dummy/config/ember-try.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const embroiderTestSetup = require("@embroider/test-setup");
4 | const getChannelURL = require("ember-source-channel-url");
5 |
6 | const config = {
7 | usePnpm: true,
8 | scenarios: [
9 | {
10 | name: "theme-default",
11 | env: { TEST_SCENARIO: "THEME_DEFAULT" },
12 | },
13 | {
14 | name: "theme-uikit",
15 | env: { TEST_SCENARIO: "THEME_UIKIT" },
16 | },
17 | {
18 | name: "theme-bootstrap",
19 | env: { TEST_SCENARIO: "THEME_BOOTSTRAP" },
20 | },
21 | {
22 | name: "custom-components",
23 | env: { TEST_SCENARIO: "CUSTOM_COMPONENTS" },
24 | },
25 | ],
26 | };
27 |
28 | function buildLTSScenario(version) {
29 | return {
30 | ...config,
31 | scenarios: config.scenarios.map((scenario) => ({
32 | ...scenario,
33 | name: `ember-lts-${version} (${scenario.name})`,
34 | npm: {
35 | devDependencies: { "ember-source": `~${version}.0` },
36 | },
37 | })),
38 | };
39 | }
40 |
41 | async function buildURLScenario(release) {
42 | const emberSourceURL = await getChannelURL(release);
43 |
44 | return {
45 | ...config,
46 | scenarios: config.scenarios.map((scenario) => ({
47 | ...scenario,
48 | name: `ember-${release} (${scenario.name})`,
49 | npm: {
50 | devDependencies: { "ember-source": emberSourceURL },
51 | },
52 | })),
53 | };
54 | }
55 |
56 | function buildEmbroiderScenario(type) {
57 | const embroiderScenario = embroiderTestSetup[type]();
58 |
59 | return {
60 | ...config,
61 | scenarios: config.scenarios.map((scenario) => ({
62 | ...scenario,
63 | ...embroiderScenario,
64 | env: { ...embroiderScenario.env, ...scenario.env },
65 | name: `${embroiderScenario.name} (${scenario.name})`,
66 | })),
67 | };
68 | }
69 |
70 | module.exports = function () {
71 | const scenario = process.env.EMBER_SCENARIO;
72 |
73 | if (/^ember-lts-\d+\.\d+/.test(scenario)) {
74 | return buildLTSScenario(scenario.replace(/^ember-lts-/, ""));
75 | } else if (/^ember-(release|beta|canary)$/.test(scenario)) {
76 | return buildURLScenario(scenario.replace(/^ember-/, ""));
77 | } else if (/^embroider-(safe|optimized)$/.test(scenario)) {
78 | // convert embroider-xy to embroiderXy
79 | const embroiderScenario = scenario
80 | .split("-")
81 | .map((part, i) =>
82 | i === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1),
83 | )
84 | .join("");
85 |
86 | return buildEmbroiderScenario(embroiderScenario);
87 | }
88 |
89 | return config;
90 | };
91 |
--------------------------------------------------------------------------------
/tests/dummy/config/environment.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = function (environment) {
4 | const ENV = {
5 | modulePrefix: "dummy",
6 | environment,
7 | rootURL: "/",
8 | locationType: "history",
9 | historySupportMiddleware: true,
10 | EmberENV: {
11 | EXTEND_PROTOTYPES: false,
12 | FEATURES: {
13 | // Here you can enable experimental features on an ember canary build
14 | // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
15 | },
16 | },
17 |
18 | APP: {
19 | // Here you can pass flags/options to your application instance
20 | // when it is created
21 | },
22 | };
23 |
24 | if (environment === "development") {
25 | // ENV.APP.LOG_RESOLVER = true;
26 | // ENV.APP.LOG_ACTIVE_GENERATION = true;
27 | // ENV.APP.LOG_TRANSITIONS = true;
28 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
29 | // ENV.APP.LOG_VIEW_LOOKUPS = true;
30 | }
31 |
32 | if (environment === "test") {
33 | // Testem prefers this...
34 | ENV.locationType = "none";
35 |
36 | // keep test console output quieter
37 | ENV.APP.LOG_ACTIVE_GENERATION = false;
38 | ENV.APP.LOG_VIEW_LOOKUPS = false;
39 |
40 | ENV.APP.rootElement = "#ember-testing";
41 | ENV.APP.autoboot = false;
42 | }
43 |
44 | if (environment === "production") {
45 | ENV.rootURL = "/ADDON_DOCS_ROOT_URL/";
46 | }
47 |
48 | return ENV;
49 | };
50 |
--------------------------------------------------------------------------------
/tests/dummy/config/optional-features.json:
--------------------------------------------------------------------------------
1 | {
2 | "application-template-wrapper": false,
3 | "default-async-observers": true,
4 | "jquery-integration": false,
5 | "template-only-glimmer-components": true
6 | }
7 |
--------------------------------------------------------------------------------
/tests/dummy/config/targets.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const browsers = [
4 | "last 1 Chrome versions",
5 | "last 1 Firefox versions",
6 | "last 1 Safari versions",
7 | ];
8 |
9 | module.exports = {
10 | browsers,
11 | };
12 |
--------------------------------------------------------------------------------
/tests/dummy/public/robots.txt:
--------------------------------------------------------------------------------
1 | # http://www.robotstxt.org
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/tests/helpers/index.js:
--------------------------------------------------------------------------------
1 | import {
2 | setupApplicationTest as upstreamSetupApplicationTest,
3 | setupRenderingTest as upstreamSetupRenderingTest,
4 | setupTest as upstreamSetupTest,
5 | } from "ember-qunit";
6 |
7 | // This file exists to provide wrappers around ember-qunit's
8 | // test setup functions. This way, you can easily extend the setup that is
9 | // needed per test type.
10 |
11 | function setupApplicationTest(hooks, options) {
12 | upstreamSetupApplicationTest(hooks, options);
13 |
14 | // Additional setup for application tests can be done here.
15 | //
16 | // For example, if you need an authenticated session for each
17 | // application test, you could do:
18 | //
19 | // hooks.beforeEach(async function () {
20 | // await authenticateSession(); // ember-simple-auth
21 | // });
22 | //
23 | // This is also a good place to call test setup functions coming
24 | // from other addons:
25 | //
26 | // setupIntl(hooks); // ember-intl
27 | // setupMirage(hooks); // ember-cli-mirage
28 | }
29 |
30 | function setupRenderingTest(hooks, options) {
31 | upstreamSetupRenderingTest(hooks, options);
32 |
33 | // Additional setup for rendering tests can be done here.
34 | }
35 |
36 | function setupTest(hooks, options) {
37 | upstreamSetupTest(hooks, options);
38 |
39 | // Additional setup for unit tests can be done here.
40 | }
41 |
42 | export { setupApplicationTest, setupRenderingTest, setupTest };
43 |
--------------------------------------------------------------------------------
/tests/helpers/scenarios.js:
--------------------------------------------------------------------------------
1 | import { getOwnConfig } from "@embroider/macros";
2 | import { test } from "qunit";
3 |
4 | const testScenario = getOwnConfig()?.testScenario;
5 |
6 | function buildScenarioTester(env) {
7 | return function (name, ...args) {
8 | if (testScenario === env) {
9 | return test(`${name} [${env}]`, ...args);
10 | }
11 | };
12 | }
13 |
14 | export const testUikit = buildScenarioTester("THEME_UIKIT");
15 | export const testBootstrap = buildScenarioTester("THEME_BOOTSTRAP");
16 | export const testDefault = buildScenarioTester("THEME_DEFAULT");
17 | export const testCustomComponents = buildScenarioTester("CUSTOM_COMPONENTS");
18 |
--------------------------------------------------------------------------------
/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Dummy Tests
6 |
7 |
8 |
9 | {{content-for "head"}}
10 | {{content-for "test-head"}}
11 |
12 |
13 |
14 |
15 |
16 | {{content-for "head-footer"}}
17 | {{content-for "test-head-footer"}}
18 |
19 |
20 | {{content-for "body"}}
21 | {{content-for "test-body"}}
22 |
23 |
24 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | {{content-for "body-footer"}}
37 | {{content-for "test-body-footer"}}
38 |
39 |
40 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-button-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import { testDefault } from "dummy/tests/helpers/scenarios";
7 |
8 | module("Integration | Component | validated button", function (hooks) {
9 | setupRenderingTest(hooks);
10 |
11 | hooks.beforeEach(function () {
12 | this.noop = () => {};
13 | });
14 |
15 | testDefault("it renders a button with a label", async function (assert) {
16 | await render(hbs` `);
17 | assert.dom("button").hasText("Test");
18 | });
19 |
20 | testDefault("it renders a button with block style", async function (assert) {
21 | await render(
22 | hbs`Test `,
23 | );
24 | assert.dom("button").hasText("Test");
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-button/button-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import {
7 | testDefault,
8 | testUikit,
9 | testBootstrap,
10 | } from "dummy/tests/helpers/scenarios";
11 |
12 | module("Integration | Component | validated-button/button", function (hooks) {
13 | setupRenderingTest(hooks);
14 |
15 | hooks.beforeEach(function () {
16 | this.noop = () => {};
17 | });
18 |
19 | testDefault("it renders", async function (assert) {
20 | await render(hbs` `);
21 |
22 | assert.dom("button").exists();
23 |
24 | await render(hbs`
25 | Test
26 | `);
27 |
28 | assert.dom("button").hasText("Test");
29 | });
30 |
31 | testUikit("it renders", async function (assert) {
32 | await render(
33 | hbs` `,
34 | );
35 |
36 | assert.dom("button").hasText("Test");
37 | assert.dom("button").hasClass("uk-button");
38 | assert.dom("button").hasClass("uk-button-default");
39 | });
40 |
41 | testUikit("it renders in block style", async function (assert) {
42 | await render(hbs`
43 | Test
44 | `);
45 |
46 | assert.dom("button").hasText("Test");
47 | });
48 |
49 | testUikit(
50 | "it renders a primary button for submit buttons",
51 | async function (assert) {
52 | await render(
53 | hbs` `,
54 | );
55 |
56 | assert.dom("button").hasClass("uk-button-primary");
57 | },
58 | );
59 |
60 | testBootstrap("it renders", async function (assert) {
61 | await render(
62 | hbs` `,
63 | );
64 |
65 | assert.dom("button").hasText("Test");
66 | assert.dom("button").hasClass("btn");
67 | assert.dom("button").hasClass("btn-default");
68 | });
69 |
70 | testBootstrap("it renders in block style", async function (assert) {
71 | await render(hbs`
72 | Test
73 | `);
74 |
75 | assert.dom("button").hasText("Test");
76 | });
77 |
78 | testBootstrap(
79 | "it renders a primary button for submit buttons",
80 | async function (assert) {
81 | await render(
82 | hbs` `,
83 | );
84 |
85 | assert.dom("button").hasClass("btn-primary");
86 | },
87 | );
88 | });
89 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-form-defaults-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import { testCustomComponents } from "dummy/tests/helpers/scenarios";
7 |
8 | module("Integration | Component | validated form defaults", function (hooks) {
9 | setupRenderingTest(hooks);
10 |
11 | testCustomComponents("renders custom components", async function (assert) {
12 | assert.expect(4);
13 |
14 | this.set("model", { error: { test1: { validation: ["Error"] } } });
15 |
16 | await render(hbs`
17 |
25 | `);
26 |
27 | assert.dom("custom-render").exists();
28 | assert.dom("custom-label").exists();
29 | assert.dom("custom-hint").exists();
30 | assert.dom("custom-error").exists();
31 | });
32 |
33 | testCustomComponents(
34 | "renders custom button components",
35 | async function (assert) {
36 | assert.expect(1);
37 |
38 | await render(hbs`
39 |
40 | `);
41 |
42 | assert.dom("custom-button").exists();
43 | },
44 | );
45 |
46 | testCustomComponents(
47 | "renders custom type components",
48 | async function (assert) {
49 | assert.expect(7);
50 |
51 | await render(hbs`
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | `);
60 |
61 | assert.dom("custom-checkbox").exists();
62 | assert.dom("custom-checkbox-group").exists();
63 | assert.dom("custom-input").exists();
64 | assert.dom("custom-radio-group").exists();
65 | assert.dom("custom-select").exists();
66 | assert.dom("custom-textarea").exists();
67 | assert.dom("custom-date").exists();
68 | },
69 | );
70 | });
71 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-form-test.js:
--------------------------------------------------------------------------------
1 | import EmberObject from "@ember/object";
2 | import { run } from "@ember/runloop";
3 | import { render, click, blur, fillIn, focus } from "@ember/test-helpers";
4 | import { validateLength } from "ember-changeset-validations/validators";
5 | import { setupRenderingTest } from "ember-qunit";
6 | import hbs from "htmlbars-inline-precompile";
7 | import { module } from "qunit";
8 | import { defer } from "rsvp";
9 |
10 | import { testDefault, testBootstrap } from "dummy/tests/helpers/scenarios";
11 | import UserValidations from "dummy/validations/user";
12 |
13 | module("Integration | Component | validated form", function (hooks) {
14 | setupRenderingTest(hooks);
15 |
16 | testDefault("it renders simple inputs", async function (assert) {
17 | await render(hbs`
18 |
19 | `);
20 |
21 | assert.dom("form label").hasText("First name");
22 | assert.dom("form input").hasAttribute("type", "text");
23 | });
24 |
25 | testDefault("it renders textareas", async function (assert) {
26 | await render(hbs`
27 |
28 | `);
29 |
30 | assert.dom("form label").hasText("my label");
31 | assert.dom("form textarea").exists({ count: 1 });
32 | });
33 |
34 | testBootstrap("it renders a radio group", async function (assert) {
35 | this.set("buttonGroupData", {
36 | options: [
37 | { key: "1", label: "Option 1" },
38 | { key: "2", label: "Option 2" },
39 | { key: "3", label: "Option 3" },
40 | ],
41 | });
42 |
43 | await render(hbs`
44 |
50 | `);
51 |
52 | assert.dom('input[type="radio"]').exists({ count: 3 });
53 | assert.dom("label:nth-of-type(1)").hasText("Options");
54 | assert.dom("div:nth-of-type(1) > input + label").hasText("Option 1");
55 | assert.dom("div:nth-of-type(2) > input + label").hasText("Option 2");
56 | assert.dom("div:nth-of-type(3) > input + label").hasText("Option 3");
57 | assert.dom("div > input + label").exists({ count: 3 });
58 | assert.dom('input[type="radio"][value="1"]').exists();
59 | assert.dom('input[type="radio"][value="2"]').exists();
60 | assert.dom('input[type="radio"][value="3"]').exists();
61 | });
62 |
63 | testDefault("it renders submit buttons", async function (assert) {
64 | this.set("stub", function () {});
65 |
66 | await render(hbs`
67 |
68 |
69 | `);
70 |
71 | assert.dom("form button").hasAttribute("type", "submit");
72 | assert.dom("form button").hasText("Save!");
73 | });
74 |
75 | testDefault("it renders an always-showing hint", async function (assert) {
76 | await render(hbs`
77 |
78 | `);
79 |
80 | assert.dom("input + div").doesNotExist();
81 | assert.dom("input + small").exists({ count: 1 });
82 | assert.dom("input + small").hasText("Not your middle name!");
83 |
84 | const hintId = this.element.querySelector("input + small").id;
85 |
86 | assert.dom("input").hasAria("describedby", hintId);
87 | });
88 |
89 | testDefault(
90 | "does not render a tag for buttons if no callbacks were passed",
91 | async function (assert) {
92 | await render(hbs`
93 |
94 | `);
95 |
96 | assert.dom("form > p").doesNotExist();
97 | },
98 | );
99 |
100 | testDefault("it supports default button labels", async function (assert) {
101 | this.set("stub", function () {});
102 |
103 | await render(hbs`
104 |
105 | `);
106 |
107 | assert.dom("form button[type=submit]").hasText("Save");
108 | });
109 |
110 | testBootstrap(
111 | "it performs basic validations on submit",
112 | async function (assert) {
113 | this.set("submit", function () {});
114 | this.set("UserValidations", UserValidations);
115 |
116 | run(() => {
117 | this.set(
118 | "model",
119 | EmberObject.create({
120 | firstName: "x",
121 | }),
122 | );
123 | });
124 |
125 | await render(hbs`
130 |
131 |
132 | `);
133 |
134 | assert.dom("span.invalid-feedback").doesNotExist();
135 | assert.dom("input").doesNotHaveAria("invalid");
136 |
137 | await click("button");
138 |
139 | assert.dom("input").hasValue("x");
140 | assert.dom("span.invalid-feedback").exists({ count: 1 });
141 | assert
142 | .dom("span.invalid-feedback")
143 | .hasText("First name must be between 3 and 40 characters");
144 |
145 | const errorId = this.element.querySelector("span.invalid-feedback").id;
146 |
147 | assert.dom("input").hasAria("invalid", "true");
148 | assert.dom("input").hasAria("describedby", errorId);
149 | },
150 | );
151 |
152 | testBootstrap(
153 | "it shows error message for custom buttons if (and only if) triggerValidations is passed",
154 | async function (assert) {
155 | this.set("UserValidations", UserValidations);
156 |
157 | run(() => {
158 | this.set(
159 | "model",
160 | EmberObject.create({
161 | firstName: "x",
162 | }),
163 | );
164 | });
165 |
166 | this.set("triggerValidations", false);
167 |
168 | await render(hbs`
169 |
170 |
171 | `);
172 |
173 | assert.dom("span.invalid-feedback").doesNotExist();
174 | await click("button");
175 | assert.dom("span.invalid-feedback").doesNotExist();
176 |
177 | this.set("triggerValidations", true);
178 | await click("button");
179 |
180 | assert.dom("input").hasValue("x");
181 | assert.dom("span.invalid-feedback").exists({ count: 1 });
182 | assert
183 | .dom("span.invalid-feedback")
184 | .hasText("First name must be between 3 and 40 characters");
185 | },
186 | );
187 |
188 | testDefault(
189 | "it calls on-invalid-submit after submit if changeset is invalid",
190 | async function (assert) {
191 | let invalidSubmitCalled;
192 | this.set("invalidSubmit", function () {
193 | invalidSubmitCalled = true;
194 | });
195 | this.set("UserValidations", UserValidations);
196 |
197 | run(() => {
198 | this.set(
199 | "model",
200 | EmberObject.create({
201 | firstName: "x",
202 | }),
203 | );
204 | });
205 |
206 | await render(hbs`
211 |
212 |
213 | `);
214 |
215 | await click("button");
216 |
217 | assert.true(invalidSubmitCalled);
218 | },
219 | );
220 |
221 | testDefault(
222 | "it does not call on-invalid-submit after submit if changeset is valid",
223 | async function (assert) {
224 | let invalidSubmitCalled;
225 | let submitCalled;
226 | this.set("submit", function () {
227 | submitCalled = true;
228 | });
229 | this.set("invalidSubmit", function () {
230 | invalidSubmitCalled = true;
231 | });
232 |
233 | run(() => {
234 | this.set("model", EmberObject.create({}));
235 | });
236 |
237 | await render(hbs`
243 |
244 |
245 | `);
246 |
247 | await click("button");
248 |
249 | assert.notOk(invalidSubmitCalled);
250 | assert.true(submitCalled);
251 | },
252 | );
253 |
254 | testDefault(
255 | "it performs validation and calls onInvalidClick function on custom buttons",
256 | async function (assert) {
257 | assert.expect(5);
258 |
259 | this.set("onClick", function () {
260 | assert.step("onClick");
261 | });
262 | this.set("onInvalidClick", function (model) {
263 | assert.step("onInvalidClick");
264 | assert.strictEqual(model.firstName, "x");
265 | });
266 | this.set("SimpleValidations", {
267 | firstName: [validateLength({ min: 3, max: 40 })],
268 | });
269 |
270 | run(() => {
271 | this.set(
272 | "model",
273 | EmberObject.create({
274 | firstName: "x",
275 | }),
276 | );
277 | });
278 |
279 | await render(hbs`
280 |
281 |
285 | `);
286 |
287 | await click("button");
288 | assert.verifySteps(["onInvalidClick"]);
289 | await fillIn("input[name=firstName]", "Some name");
290 | await click("button");
291 | assert.verifySteps(["onClick"]);
292 | },
293 | );
294 |
295 | testBootstrap(
296 | "it performs basic validations on focus out",
297 | async function (assert) {
298 | this.set("submit", function () {});
299 | this.set("UserValidations", UserValidations);
300 |
301 | run(() => {
302 | this.set("model", EmberObject.create({}));
303 | });
304 |
305 | await render(hbs`
310 |
311 |
312 | `);
313 |
314 | assert.dom("input + div").doesNotExist();
315 |
316 | await focus("input");
317 | await blur("input");
318 |
319 | assert.dom("span.invalid-feedback").exists({ count: 1 });
320 | assert.dom("span.invalid-feedback").hasText("First name can't be blank");
321 | },
322 | );
323 |
324 | testBootstrap(
325 | "it skips basic validations on focus out with validateBeforeSubmit=false set on the form",
326 | async function (assert) {
327 | this.set("submit", function () {});
328 | this.set("UserValidations", UserValidations);
329 |
330 | run(() => {
331 | this.set("model", EmberObject.create({}));
332 | });
333 |
334 | await render(hbs`
340 |
341 |
342 | `);
343 |
344 | assert.dom("span.invalid-feedback").doesNotExist();
345 |
346 | await focus("input");
347 | await blur("input");
348 |
349 | assert.dom("span.invalid-feedback").doesNotExist();
350 |
351 | await click("button");
352 |
353 | assert.dom("span.invalid-feedback").exists({ count: 1 });
354 | },
355 | );
356 |
357 | testDefault(
358 | "it skips basic validations on focus out with validateBeforeSubmit=false set on the input",
359 | async function (assert) {
360 | this.set("submit", function () {});
361 | this.set("UserValidations", UserValidations);
362 |
363 | run(() => {
364 | this.set("model", EmberObject.create({}));
365 | });
366 |
367 | await render(hbs`
372 |
377 | `);
378 |
379 | assert.dom("input + div").doesNotExist();
380 |
381 | await focus("input");
382 | await blur("input");
383 |
384 | assert.dom("input + div").doesNotExist();
385 | },
386 | );
387 |
388 | testDefault(
389 | "on-submit can be an action returning a promise",
390 | async function (assert) {
391 | const deferred = defer();
392 |
393 | this.set("submit", () => deferred.promise);
394 |
395 | run(() => {
396 | this.set("model", EmberObject.create({}));
397 | });
398 |
399 | await render(hbs`
404 |
405 | `);
406 |
407 | assert.dom("button").doesNotHaveClass("loading");
408 |
409 | await click("button");
410 |
411 | assert.dom("button").hasClass("loading");
412 |
413 | run(() => deferred.resolve());
414 |
415 | assert.dom("button").doesNotHaveClass("loading");
416 | },
417 | );
418 |
419 | testDefault(
420 | "on-submit can be an action returning a non-promise",
421 | async function (assert) {
422 | this.set("submit", () => undefined);
423 |
424 | run(() => {
425 | this.set("model", EmberObject.create({}));
426 | });
427 |
428 | await render(hbs`
433 |
434 | `);
435 |
436 | assert.dom("button").doesNotHaveClass("loading");
437 |
438 | await click("button");
439 |
440 | assert.dom("button").doesNotHaveClass("loading");
441 | },
442 | );
443 |
444 | testDefault("it yields the loading state", async function (assert) {
445 | const deferred = defer();
446 |
447 | this.set("submit", () => deferred.promise);
448 |
449 | run(() => {
450 | this.set("model", EmberObject.create({}));
451 | });
452 |
453 | await render(hbs`
458 | {{#if f.loading}}
459 | loading...
460 | {{/if}}
461 |
462 | `);
463 | assert.dom("span.loading").doesNotExist();
464 |
465 | await click("button");
466 |
467 | assert.dom("span.loading").exists();
468 |
469 | run(() => deferred.resolve());
470 |
471 | assert.dom("span.loading").doesNotExist();
472 | });
473 |
474 | testDefault(
475 | "it handles being removed from the DOM during sync submit",
476 | async function (assert) {
477 | this.set("show", true);
478 |
479 | this.set("submit", () => {
480 | this.set("show", false);
481 | });
482 |
483 | run(() => {
484 | this.set("model", EmberObject.create({}));
485 | });
486 |
487 | await render(hbs`{{#if this.show}}
488 |
493 | {{#if f.loading}}
494 | loading...
495 | {{/if}}
496 |
497 |
498 | {{/if}}`);
499 |
500 | await click("button");
501 | assert.ok(true);
502 | },
503 | );
504 |
505 | testDefault(
506 | "it handles being removed from the DOM during async submit",
507 | async function (assert) {
508 | this.set("show", true);
509 | const deferred = defer();
510 |
511 | this.set("submit", () => {
512 | return deferred.promise.then(() => {
513 | this.set("show", false);
514 | });
515 | });
516 |
517 | run(() => {
518 | this.set("model", EmberObject.create({}));
519 | });
520 |
521 | await render(hbs`{{#if this.show}}
522 |
527 | {{#if f.loading}}
528 | loading...
529 | {{/if}}
530 |
531 |
532 | {{/if}}`);
533 |
534 | await click("button");
535 | run(() => deferred.resolve());
536 | assert.ok(true);
537 | },
538 | );
539 |
540 | testDefault("it binds the autocomplete attribute", async function (assert) {
541 | await render(hbs` `);
542 |
543 | assert.dom("form").hasAttribute("autocomplete", "off");
544 | });
545 | });
546 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input-test.js:
--------------------------------------------------------------------------------
1 | import { render, click, fillIn, settled } from "@ember/test-helpers";
2 | import Changeset from "ember-changeset";
3 | import { hbs } from "ember-cli-htmlbars";
4 | import { setupRenderingTest } from "ember-qunit";
5 | import { module } from "qunit";
6 |
7 | import { testDefault, testBootstrap } from "dummy/tests/helpers/scenarios";
8 |
9 | module("Integration | Component | validated input", function (hooks) {
10 | setupRenderingTest(hooks);
11 |
12 | testDefault(
13 | "it renders simple text inputs with correct name",
14 | async function (assert) {
15 | await render(hbs` `);
16 |
17 | assert.dom("input").hasAttribute("type", "text");
18 | assert.dom("input").hasAttribute("name", "bar");
19 | },
20 | );
21 |
22 | testDefault("it renders email input", async function (assert) {
23 | await render(hbs` `);
24 |
25 | assert.dom("input").hasAttribute("type", "email");
26 | });
27 |
28 | testDefault("it renders tel input", async function (assert) {
29 | await render(hbs` `);
30 |
31 | assert.dom("input").hasAttribute("type", "tel");
32 | });
33 |
34 | testDefault("it renders disabled inputs", async function (assert) {
35 | await render(hbs` `);
36 |
37 | assert.dom("input").isDisabled();
38 | });
39 |
40 | testDefault("it renders inputs with placeholder", async function (assert) {
41 | await render(hbs` `);
42 |
43 | assert.dom("input").hasAttribute("placeholder", "foo");
44 | });
45 |
46 | testDefault("it renders inputs with value", async function (assert) {
47 | await render(hbs` `);
48 |
49 | assert.dom("input").hasValue("foo");
50 | });
51 |
52 | testDefault("it renders inputs with model", async function (assert) {
53 | this.set("model", new Changeset({ firstName: "Max" }));
54 |
55 | await render(
56 | hbs` `,
57 | );
58 |
59 | assert.dom("input").hasValue("Max");
60 | });
61 |
62 | testDefault("it calls on-update if given", async function (assert) {
63 | this.set("model", new Changeset({ firstName: "Max" }));
64 | this.set("update", (value, changeset) => {
65 | changeset.set("firstName", value.toUpperCase());
66 | });
67 | await render(
68 | hbs` `,
73 | );
74 |
75 | await fillIn("input", "foo");
76 |
77 | assert.dom("input").hasValue("FOO");
78 | });
79 |
80 | testDefault(
81 | "it renders inputs with value even if model is defined",
82 | async function (assert) {
83 | this.set("model", new Changeset({ firstName: "Max" }));
84 |
85 | await render(
86 | hbs` `,
87 | );
88 |
89 | assert.dom("input").hasValue("foobar");
90 | },
91 | );
92 |
93 | testDefault(
94 | "it renders textarea inputs with correct name",
95 | async function (assert) {
96 | await render(hbs` `);
97 |
98 | assert.dom("textarea").hasAttribute("name", "bar");
99 | },
100 | );
101 |
102 | testDefault("it renders disabled textareas", async function (assert) {
103 | await render(hbs` `);
104 |
105 | assert.dom("textarea").isDisabled();
106 | });
107 |
108 | testDefault("it renders textareas with placeholder", async function (assert) {
109 | await render(hbs` `);
110 |
111 | assert.dom("textarea").hasAttribute("placeholder", "foo");
112 | });
113 |
114 | testDefault("it renders textareas with value", async function (assert) {
115 | await render(hbs` `);
116 |
117 | assert.dom("textarea").hasValue("foo");
118 | });
119 |
120 | testDefault("it renders textareas with model", async function (assert) {
121 | this.set("model", new Changeset({ firstName: "Max" }));
122 |
123 | await render(
124 | hbs` `,
125 | );
126 |
127 | assert.dom("textarea").hasValue("Max");
128 | });
129 |
130 | testDefault(
131 | "it renders textareas autocomplete attribute",
132 | async function (assert) {
133 | await render(
134 | hbs` `,
135 | );
136 |
137 | assert.dom("textarea").hasAttribute("autocomplete", "given-name");
138 | },
139 | );
140 |
141 | testDefault(
142 | "it renders input autocomplete attribute",
143 | async function (assert) {
144 | await render(
145 | hbs` `,
150 | );
151 |
152 | assert.dom("input").hasAttribute("autocomplete", "new-password");
153 | },
154 | );
155 |
156 | testDefault("it renders the block if provided", async function (assert) {
157 | await render(
158 | hbs`
159 |
160 | `,
161 | );
162 |
163 | assert.dom("#custom-input").exists();
164 | });
165 |
166 | testDefault(
167 | "it yields the value provided to the block",
168 | async function (assert) {
169 | await render(
170 | hbs`
171 |
172 | `,
173 | );
174 |
175 | assert.dom("input").hasValue("my-value");
176 | },
177 | );
178 |
179 | testDefault(
180 | "it yields the name from the model as value",
181 | async function (assert) {
182 | this.set("model", new Changeset({ firstName: "Max" }));
183 |
184 | await render(
185 | hbs`
186 |
187 | `,
188 | );
189 |
190 | assert.dom("input").hasValue("Max");
191 | },
192 | );
193 |
194 | testDefault(
195 | "it yields the value as value if both model and value is provided",
196 | async function (assert) {
197 | this.set("model", new Changeset({ firstName: "Max" }));
198 |
199 | await render(
200 | hbs`
206 |
207 | `,
208 | );
209 |
210 | assert.dom("input").hasValue("Other Value");
211 | },
212 | );
213 |
214 | testDefault("it yields the provided name", async function (assert) {
215 | await render(
216 | hbs`
217 |
218 | `,
219 | );
220 |
221 | assert.dom("input").hasAttribute("name", "foobar");
222 | });
223 |
224 | testDefault("it yields the model", async function (assert) {
225 | this.set("model", new Changeset({ firstName: "Max" }));
226 |
227 | await render(
228 | hbs`
229 |
230 | `,
231 | );
232 |
233 | assert.dom("input").hasValue("Max");
234 | });
235 |
236 | testDefault(
237 | "it yields an action for updating the model",
238 | async function (assert) {
239 | const model = new Changeset({ firstName: "Max" });
240 | this.set("model", model);
241 |
242 | await render(
243 | hbs`
244 |
245 | `,
246 | );
247 |
248 | await click("button");
249 |
250 | assert.strictEqual(model.get("firstName"), "Merlin");
251 | },
252 | );
253 |
254 | testBootstrap(
255 | "it yields an action marking the input as dirty",
256 | async function (assert) {
257 | this.set("model", { error: { test: { validation: ["Error"] } } });
258 |
259 | await render(
260 | hbs`
261 |
262 | `,
263 | );
264 |
265 | assert.dom("span.invalid-feedback").doesNotExist();
266 |
267 | await click("button");
268 |
269 | assert.dom("span.invalid-feedback").exists();
270 | },
271 | );
272 |
273 | testDefault("it yields the input id to the block", async function (assert) {
274 | await render(
275 | hbs`
276 |
277 | `,
278 | );
279 |
280 | const label = this.element.querySelector("label");
281 | const input = this.element.querySelector("input");
282 | assert.strictEqual(label.getAttribute("for"), input.getAttribute("id"));
283 | });
284 |
285 | testDefault(
286 | "it can change the value from outside the input",
287 | async function (assert) {
288 | this.set("model", new Changeset({ firstName: "Max" }));
289 |
290 | await render(
291 | hbs` `,
292 | );
293 |
294 | assert.dom("input").hasValue("Max");
295 |
296 | this.set("model.firstName", "Hans");
297 |
298 | assert.dom("input").hasValue("Hans");
299 | },
300 | );
301 |
302 | testDefault("it can overwrite the input name", async function (assert) {
303 | this.set("model", new Changeset({ firstName: "Max" }));
304 |
305 | await render(
306 | hbs` `,
311 | );
312 |
313 | assert.dom("input").hasValue("Max");
314 | assert.dom("input").hasAttribute("name", "testFirstName");
315 | });
316 |
317 | testDefault("it updates _val on nested fields", async function (assert) {
318 | this.set("model", new Changeset({ nested: { name: "Max" } }));
319 |
320 | await render(
321 | hbs`{{this.model.nested.name}}
322 |
323 | {{Input.value}}
324 | `,
325 | );
326 |
327 | assert.dom("#raw").hasText("Max");
328 | assert.dom("#_val").hasText("Max");
329 |
330 | this.model.set("nested.name", "Tom");
331 | await settled();
332 |
333 | assert.dom("#raw").hasText("Tom");
334 | assert.dom("#_val").hasText("Tom");
335 | });
336 | });
337 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input/error-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import {
7 | testDefault,
8 | testUikit,
9 | testBootstrap,
10 | } from "dummy/tests/helpers/scenarios";
11 |
12 | module("Integration | Component | validated-input/error", function (hooks) {
13 | setupRenderingTest(hooks);
14 |
15 | testDefault("it renders", async function (assert) {
16 | this.set("errors", ["foo", "bar", "baz"]);
17 |
18 | await render(hbs` `);
19 |
20 | assert.dom("span").hasText("foo, bar, baz");
21 | });
22 |
23 | testUikit("it renders", async function (assert) {
24 | this.set("errors", ["foo", "bar", "baz"]);
25 |
26 | await render(hbs` `);
27 |
28 | assert.dom("small").hasClass("uk-text-danger");
29 | assert.dom("small").hasText("foo, bar, baz");
30 | });
31 |
32 | testBootstrap("it renders", async function (assert) {
33 | this.set("errors", ["foo", "bar", "baz"]);
34 |
35 | await render(hbs` `);
36 |
37 | assert.dom("span").hasClass("invalid-feedback");
38 | assert.dom("span").hasClass("d-block");
39 | assert.dom("span").hasText("foo, bar, baz");
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input/hint-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import {
7 | testDefault,
8 | testUikit,
9 | testBootstrap,
10 | } from "dummy/tests/helpers/scenarios";
11 |
12 | module("Integration | Component | validated-input/hint", function (hooks) {
13 | setupRenderingTest(hooks);
14 |
15 | testDefault("it renders", async function (assert) {
16 | await render(hbs` `);
17 |
18 | assert.dom("small").hasText("Test");
19 | });
20 |
21 | testUikit("it renders", async function (assert) {
22 | await render(hbs` `);
23 |
24 | assert.dom("small").hasClass("uk-text-muted");
25 | assert.dom("small").hasText("Test");
26 | });
27 |
28 | testBootstrap("it renders", async function (assert) {
29 | await render(hbs` `);
30 |
31 | assert.dom("small").hasClass("form-text");
32 | assert.dom("small").hasClass("text-muted");
33 | assert.dom("small").hasText("Test");
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input/label-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import {
7 | testDefault,
8 | testUikit,
9 | testBootstrap,
10 | } from "dummy/tests/helpers/scenarios";
11 |
12 | module("Integration | Component | validated-input/label", function (hooks) {
13 | setupRenderingTest(hooks);
14 |
15 | testDefault("it renders", async function (assert) {
16 | await render(hbs` `);
17 |
18 | assert.dom("label").hasText("Test");
19 | });
20 |
21 | testUikit("it renders", async function (assert) {
22 | await render(hbs` `);
23 |
24 | assert.dom("label").hasClass("uk-form-label");
25 | assert.dom("label").hasText("Test");
26 | });
27 |
28 | testBootstrap("it renders", async function (assert) {
29 | await render(hbs` `);
30 |
31 | assert.dom("label").hasText("Test");
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input/render-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import {
7 | testDefault,
8 | testUikit,
9 | testBootstrap,
10 | } from "dummy/tests/helpers/scenarios";
11 |
12 | module("Integration | Component | validated-input/render", function (hooks) {
13 | setupRenderingTest(hooks);
14 |
15 | testDefault("it renders", async function (assert) {
16 | await render(hbs` `);
23 |
24 | assert.dom("input[type=text]").exists();
25 | assert.dom("input[type=text]").hasAttribute("name", "test");
26 | assert.dom("label").hasText("Test");
27 | });
28 |
29 | testUikit("it renders", async function (assert) {
30 | await render(hbs` `);
37 |
38 | assert.dom(".uk-margin").exists();
39 | assert.dom(".uk-margin > .uk-form-label").exists();
40 | assert.dom(".uk-margin > .uk-form-controls").exists();
41 |
42 | assert.dom("input[type=text].uk-input").exists();
43 | assert.dom("input[type=text].uk-input").hasAttribute("name", "test");
44 | assert.dom("label").hasText("Test");
45 | });
46 |
47 | testBootstrap("it renders", async function (assert) {
48 | await render(hbs` `);
55 |
56 | assert.dom(".form-group").exists();
57 |
58 | assert.dom("input[type=text].form-control").exists();
59 | assert.dom("input[type=text].form-control").hasAttribute("name", "test");
60 | assert.dom("label").hasText("Test");
61 | });
62 | });
63 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input/render/wrapper-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { hbs } from "ember-cli-htmlbars";
3 | import { module } from "qunit";
4 |
5 | import { setupRenderingTest } from "dummy/tests/helpers";
6 | import {
7 | testDefault,
8 | testUikit,
9 | testBootstrap,
10 | } from "dummy/tests/helpers/scenarios";
11 |
12 | module(
13 | "Integration | Component | validated-input/render/wrapper",
14 | function (hooks) {
15 | setupRenderingTest(hooks);
16 |
17 | testDefault("it renders", async function (assert) {
18 | await render(
19 | hbs`Test `,
20 | );
21 |
22 | assert.dom(this.element).hasText("Test");
23 | });
24 |
25 | testBootstrap("it renders", async function (assert) {
26 | await render(
27 | hbs`Test `,
28 | );
29 |
30 | assert.dom(this.element).hasText("Test");
31 | });
32 |
33 | testUikit("it renders", async function (assert) {
34 | await render(
35 | hbs`Test `,
36 | );
37 |
38 | assert.dom("div.uk-form-controls").hasText("Test");
39 | });
40 | },
41 | );
42 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input/types/checkbox-group-test.js:
--------------------------------------------------------------------------------
1 | import { click, render } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import {
7 | testDefault,
8 | testUikit,
9 | testBootstrap,
10 | } from "dummy/tests/helpers/scenarios";
11 |
12 | module(
13 | "Integration | Component | validated-input/types/checkbox-group",
14 | function (hooks) {
15 | setupRenderingTest(hooks);
16 |
17 | testDefault("it renders", async function (assert) {
18 | this.set("options", [
19 | { key: 1, label: 1 },
20 | { key: 2, label: 2 },
21 | ]);
22 |
23 | await render(hbs` `);
27 |
28 | assert.dom("input[type=checkbox]").exists({ count: 2 });
29 | });
30 |
31 | testDefault("it can select multiple values", async function (assert) {
32 | this.options = [
33 | { key: 1, label: 1 },
34 | { key: 2, label: 2 },
35 | ];
36 | this.value = [];
37 |
38 | await render(hbs` `);
44 |
45 | await click('input[value="1"]');
46 | await click('input[value="2"]');
47 |
48 | assert.deepEqual(this.value, [1, 2]);
49 | assert.true(this.dirty);
50 | });
51 |
52 | testUikit("it renders", async function (assert) {
53 | this.set("options", [
54 | {
55 | key: "opt1",
56 | label: "Option 1",
57 | },
58 | {
59 | key: "opt2",
60 | label: "Option 2",
61 | },
62 | ]);
63 |
64 | await render(hbs` `);
68 |
69 | assert.dom("label > input").exists();
70 | assert.dom("input").hasClass("uk-checkbox");
71 | assert.dom("label").hasClass("uk-form-label");
72 | });
73 |
74 | testBootstrap("it renders", async function (assert) {
75 | await render(hbs` `);
82 |
83 | assert.dom("div.custom-control.custom-checkbox").exists();
84 | assert.dom("input").hasClass("custom-control-input");
85 | assert.dom("label").hasClass("custom-control-label");
86 | });
87 | },
88 | );
89 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input/types/checkbox-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import {
7 | testDefault,
8 | testUikit,
9 | testBootstrap,
10 | } from "dummy/tests/helpers/scenarios";
11 |
12 | module(
13 | "Integration | Component | validated-input/types/checkbox",
14 | function (hooks) {
15 | setupRenderingTest(hooks);
16 |
17 | testDefault("it renders", async function (assert) {
18 | await render(hbs` `);
22 |
23 | assert.dom("input[type=checkbox]").exists();
24 | });
25 |
26 | testUikit("it renders", async function (assert) {
27 | await render(hbs` `);
31 |
32 | assert.dom("label > input").exists();
33 | assert.dom("input").hasClass("uk-checkbox");
34 | assert.dom("label").hasClass("uk-form-label");
35 | });
36 |
37 | testBootstrap("it renders", async function (assert) {
38 | await render(hbs` `);
42 |
43 | assert.dom("div.custom-control.custom-checkbox").exists();
44 | assert.dom("input").hasClass("custom-control-input");
45 | assert.dom("label").hasClass("custom-control-label");
46 | });
47 | },
48 | );
49 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input/types/input-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import {
7 | testDefault,
8 | testUikit,
9 | testBootstrap,
10 | } from "dummy/tests/helpers/scenarios";
11 |
12 | module(
13 | "Integration | Component | validated-input/types/input",
14 | function (hooks) {
15 | setupRenderingTest(hooks);
16 |
17 | testDefault("it renders", async function (assert) {
18 | await render(hbs` `);
22 |
23 | assert.dom("input").exists();
24 | });
25 |
26 | testUikit("it renders", async function (assert) {
27 | await render(hbs` `);
31 |
32 | assert.dom("input").hasClass("uk-input");
33 | });
34 |
35 | testBootstrap("it renders", async function (assert) {
36 | await render(hbs` `);
40 |
41 | assert.dom("input").hasClass("form-control");
42 | });
43 | },
44 | );
45 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input/types/radio-group-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import {
7 | testDefault,
8 | testUikit,
9 | testBootstrap,
10 | } from "dummy/tests/helpers/scenarios";
11 |
12 | module(
13 | "Integration | Component | validated-input/types/radio-group",
14 | function (hooks) {
15 | setupRenderingTest(hooks);
16 |
17 | testDefault("it renders", async function (assert) {
18 | this.set("options", [
19 | { key: 1, label: 1 },
20 | { key: 2, label: 2 },
21 | ]);
22 |
23 | await render(hbs` `);
27 |
28 | assert.dom("input[type=radio]").exists({ count: 2 });
29 | });
30 |
31 | testUikit("it renders", async function (assert) {
32 | this.set("options", [
33 | {
34 | key: "opt1",
35 | label: "Option 1",
36 | },
37 | {
38 | key: "opt2",
39 | label: "Option 2",
40 | },
41 | ]);
42 |
43 | await render(hbs` `);
47 |
48 | assert.dom("label > input").exists({ count: 2 });
49 | assert.dom("input").hasClass("uk-radio");
50 | assert.dom("label").hasClass("uk-form-label");
51 | });
52 |
53 | testBootstrap("it renders", async function (assert) {
54 | this.set("options", [
55 | {
56 | key: "opt1",
57 | label: "Option 1",
58 | },
59 | {
60 | key: "opt2",
61 | label: "Option 2",
62 | },
63 | ]);
64 |
65 | await render(hbs` `);
69 |
70 | assert.dom("div.custom-control.custom-radio").exists({ count: 2 });
71 | assert.dom("input").hasClass("custom-control-input");
72 | assert.dom("label").hasClass("custom-control-label");
73 | });
74 | },
75 | );
76 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input/types/select-test.js:
--------------------------------------------------------------------------------
1 | import { render, select } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import {
7 | testDefault,
8 | testUikit,
9 | testBootstrap,
10 | } from "dummy/tests/helpers/scenarios";
11 |
12 | module(
13 | "Integration | Component | validated-input/types/select",
14 | function (hooks) {
15 | setupRenderingTest(hooks);
16 |
17 | testDefault("it renders", async function (assert) {
18 | this.set("options", [
19 | { id: 1, label: 1 },
20 | { id: 2, label: 2 },
21 | ]);
22 |
23 | await render(
24 | hbs` `,
25 | );
26 |
27 | assert.dom("select").exists();
28 | assert.dom("option").exists({ count: 2 });
29 | assert.dom("option:first-child").hasProperty("selected", true);
30 | });
31 |
32 | testDefault(
33 | "it supports plain (non-object) options",
34 | async function (assert) {
35 | assert.expect(6);
36 | this.set("options", ["foo", "bar"]);
37 |
38 | this.set("update", (value) => {
39 | assert.strictEqual(value, "bar");
40 | });
41 | await render(
42 | hbs` `,
46 | );
47 |
48 | assert.dom("select").exists();
49 | assert.dom("option").exists({ count: 2 });
50 | assert.dom("option:first-child").hasProperty("selected", true);
51 | await select("select", "bar");
52 | assert.dom("option:first-child").hasProperty("selected", false);
53 | assert.dom("option:last-child").hasProperty("selected", true);
54 | },
55 | );
56 |
57 | testDefault(
58 | "it works with solitary optionTargetPath property",
59 | async function (assert) {
60 | assert.expect(2);
61 | this.set("options", [
62 | { key: 111, label: "firstOption" },
63 | { key: 222, label: "secondOption" },
64 | ]);
65 |
66 | this.set("update", (value) => {
67 | assert.strictEqual(value, 222);
68 | });
69 |
70 | await render(
71 | hbs` `,
76 | );
77 |
78 | assert.dom("option:first-child").hasText("firstOption");
79 | await select("select", "222");
80 | },
81 | );
82 |
83 | testDefault(
84 | "it renders option groups via groupLabelPath",
85 | async function (assert) {
86 | this.set("options", [
87 | { key: 1, label: 1, group: "one" },
88 | { key: 2, label: 2, group: "two" },
89 | ]);
90 |
91 | await render(
92 | hbs` `,
98 | );
99 |
100 | assert.dom("select").exists();
101 | assert.dom("optgroup[label='one']").exists({ count: 1 });
102 | assert.dom("optgroup[label='two']").exists({ count: 1 });
103 | assert.dom("optgroup:first-child option:first-child").hasText("1");
104 | assert.dom("optgroup:last-child option:first-child").hasValue("2");
105 | },
106 | );
107 |
108 | testDefault(
109 | "it renders option groups pre grouped options",
110 | async function (assert) {
111 | this.set("options", [
112 | {
113 | groupName: "one",
114 | options: [
115 | { id: 1, label: "First", type: "group1" },
116 | { id: 2, label: "Second", type: "group1" },
117 | ],
118 | },
119 | {
120 | groupName: "two",
121 | options: [{ id: 3, label: "Third", type: "group2" }],
122 | },
123 | ]);
124 |
125 | await render(
126 | hbs` `,
131 | );
132 |
133 | assert.dom("select").exists();
134 | assert.dom("optgroup[label='one']").exists({ count: 1 });
135 | assert.dom("optgroup:first-child option:first-child").hasText("First");
136 | assert.dom("optgroup[label='two']").exists({ count: 1 });
137 | assert.dom("optgroup:last-child option:first-child").hasText("Third");
138 | assert.dom("optgroup:last-child option:first-child").hasValue("3");
139 | },
140 | );
141 |
142 | testDefault("it selects the pre-defined value", async function (assert) {
143 | this.set("value", "2");
144 | this.set("options", [
145 | { key: "1", label: 1 },
146 | { key: "2", label: 2 },
147 | ]);
148 |
149 | await render(
150 | hbs` `,
156 | );
157 |
158 | assert.dom("select").hasValue(this.options[1].key);
159 | assert.dom("option:first-child").hasProperty("selected", false);
160 | assert.dom("option:last-child").hasProperty("selected", true);
161 | });
162 |
163 | testDefault("prompt is present and disabled", async function (assert) {
164 | this.set("options", [
165 | { key: 1, label: 1 },
166 | { key: 2, label: 2 },
167 | ]);
168 |
169 | await render(
170 | hbs` `,
174 | );
175 |
176 | assert.dom("option:first-child").hasText("Choose this");
177 | assert.dom("option:first-child").hasProperty("disabled", true);
178 | });
179 |
180 | testDefault("prompt is selectable", async function (assert) {
181 | this.set("options", [
182 | { key: 1, label: 1 },
183 | { key: 2, label: 2 },
184 | ]);
185 |
186 | await render(
187 | hbs` `,
192 | );
193 |
194 | assert.dom("option:first-child").hasProperty("disabled", false);
195 | });
196 |
197 | testDefault("multiselect is working", async function (assert) {
198 | assert.expect(4);
199 | this.set("options", [
200 | { id: 1, label: "label 1" },
201 | { id: 2, label: "label 2" },
202 | { id: 3, label: "label 3" },
203 | ]);
204 | this.set("update", (values) => {
205 | assert.deepEqual(values, [
206 | { id: 1, label: "label 1" },
207 | { id: 3, label: "label 3" },
208 | ]);
209 | });
210 |
211 | await render(
212 | hbs` `,
217 | );
218 |
219 | await select("select", ["1", "3"]);
220 | assert.dom("option:first-child").hasProperty("selected", true);
221 | assert.dom("option:nth-child(2)").hasProperty("selected", false);
222 | assert.dom("option:last-child").hasProperty("selected", true);
223 | });
224 |
225 | testDefault(
226 | "multiselect is working with plain options",
227 | async function (assert) {
228 | assert.expect(4);
229 | this.set("options", ["1", "2", "3"]);
230 | this.set("update", (values) => {
231 | assert.deepEqual(values, ["1", "3"]);
232 | });
233 |
234 | await render(
235 | hbs` `,
240 | );
241 |
242 | await select("select", ["1", "3"]);
243 | assert.dom("option:first-child").hasProperty("selected", true);
244 | assert.dom("option:nth-child(2)").hasProperty("selected", false);
245 | assert.dom("option:last-child").hasProperty("selected", true);
246 | },
247 | );
248 |
249 | testDefault(
250 | "multiselect works with pre grouped options",
251 | async function (assert) {
252 | assert.expect(1);
253 | this.set("update", (values) => {
254 | assert.deepEqual(values, this.options[0].options);
255 | });
256 | this.set("options", [
257 | {
258 | groupName: "one",
259 | options: [
260 | { id: 1, label: "First", type: "group1" },
261 | { id: 2, label: "Second", type: "group1" },
262 | ],
263 | },
264 | {
265 | groupName: "two",
266 | options: [{ id: 3, label: "Third", type: "group2" }],
267 | },
268 | ]);
269 |
270 | await render(
271 | hbs` `,
278 | );
279 |
280 | await select("select", ["1", "2"]);
281 | },
282 | );
283 |
284 | testDefault(
285 | "multiselect works with pre grouped options and optionsTargetPath",
286 | async function (assert) {
287 | assert.expect(1);
288 | this.set("update", (values) => {
289 | assert.deepEqual(
290 | values,
291 | this.options[0].options.map((val) => val.id),
292 | );
293 | });
294 | this.set("options", [
295 | {
296 | groupName: "one",
297 | options: [
298 | { id: 1, label: "First", type: "group1" },
299 | { id: 2, label: "Second", type: "group1" },
300 | ],
301 | },
302 | {
303 | groupName: "two",
304 | options: [{ id: 3, label: "Third", type: "group2" }],
305 | },
306 | ]);
307 |
308 | await render(
309 | hbs` `,
317 | );
318 |
319 | await select("select", ["1", "2"]);
320 | },
321 | );
322 |
323 | testUikit("it renders", async function (assert) {
324 | this.set("options", [
325 | {
326 | key: "opt1",
327 | label: "Option 1",
328 | },
329 | {
330 | key: "opt2",
331 | label: "Option 2",
332 | },
333 | ]);
334 |
335 | await render(
336 | hbs` `,
337 | );
338 |
339 | assert.dom("select").hasClass("uk-select");
340 | assert.dom("option").exists({ count: 2 });
341 | });
342 |
343 | testBootstrap("it renders", async function (assert) {
344 | this.set("options", [
345 | {
346 | key: "opt1",
347 | label: "Option 1",
348 | },
349 | {
350 | key: "opt2",
351 | label: "Option 2",
352 | },
353 | ]);
354 |
355 | await render(
356 | hbs` `,
357 | );
358 |
359 | assert.dom("select").hasClass("form-control");
360 | assert.dom("option").exists({ count: 2 });
361 | });
362 |
363 | testDefault(
364 | "prompt is selectable in compination with optionTargetPath, optionValuePath and optionLabelPath",
365 | async function (assert) {
366 | assert.expect(3);
367 | const values = [2, undefined];
368 | this.set("options", [
369 | { value: 1, text: "one" },
370 | { value: 2, text: "two" },
371 | ]);
372 | this.set("update", (value) => {
373 | assert.strictEqual(value, values.shift());
374 | });
375 |
376 | await render(
377 | hbs` `,
386 | );
387 |
388 | await select("select", "2");
389 | await select("select", "option:first-child");
390 | assert.dom("option:first-child").hasProperty("disabled", false);
391 | },
392 | );
393 | },
394 | );
395 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-input/types/textarea-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { setupRenderingTest } from "ember-qunit";
3 | import hbs from "htmlbars-inline-precompile";
4 | import { module } from "qunit";
5 |
6 | import {
7 | testDefault,
8 | testUikit,
9 | testBootstrap,
10 | } from "dummy/tests/helpers/scenarios";
11 |
12 | module(
13 | "Integration | Component | validated-input/types/textarea",
14 | function (hooks) {
15 | setupRenderingTest(hooks);
16 |
17 | testDefault("it renders", async function (assert) {
18 | await render(hbs` `);
22 |
23 | assert.dom("textarea").exists();
24 | });
25 |
26 | testUikit("it renders", async function (assert) {
27 | await render(hbs` `);
31 |
32 | assert.dom("textarea").hasClass("uk-textarea");
33 | });
34 |
35 | testBootstrap("it renders", async function (assert) {
36 | await render(hbs` `);
40 |
41 | assert.dom("textarea").hasClass("form-control");
42 | });
43 | },
44 | );
45 |
--------------------------------------------------------------------------------
/tests/integration/components/validated-label-test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable ember/no-empty-glimmer-component-classes */
2 |
3 | import { setComponentTemplate } from "@ember/component";
4 | import { render } from "@ember/test-helpers";
5 | import Component from "@glimmer/component";
6 | import { setupRenderingTest } from "ember-qunit";
7 | import hbs from "htmlbars-inline-precompile";
8 | import { module } from "qunit";
9 |
10 | import { testDefault } from "dummy/tests/helpers/scenarios";
11 |
12 | module("Integration | Component | validated label", function (hooks) {
13 | setupRenderingTest(hooks);
14 |
15 | testDefault("it renders labels", async function (assert) {
16 | await render(
17 | hbs` `,
18 | );
19 |
20 | assert.dom("label").hasText("Default name");
21 | const input = this.element.querySelector("input");
22 | assert.dom("label").hasAttribute("for", input.getAttribute("id"));
23 | });
24 |
25 | testDefault("it renders custom label component", async function (assert) {
26 | class CustomLabel extends Component {}
27 | setComponentTemplate(
28 | hbs` `,
29 | CustomLabel,
30 | );
31 | this.CustomLabel = CustomLabel;
32 |
33 | await render(hbs` `);
34 |
35 | assert.dom("label").hasAttribute("style", "color: green;");
36 | });
37 |
38 | testDefault(
39 | "it passes original variables to custom component",
40 | async function (assert) {
41 | class CustomLabel extends Component {}
42 | setComponentTemplate(
43 | hbs`
44 | {{@label}}
45 | {{@inputId}}
46 | {{@required}}
47 | `,
48 | CustomLabel,
49 | );
50 | this.CustomLabel = CustomLabel;
51 |
52 | await render(hbs` `);
58 |
59 | assert.dom("label").hasAttribute("style", "color: green;");
60 | assert.dom("#orig-label").hasText("Name custom");
61 | assert.dom("#orig-input-required").hasText("true");
62 |
63 | const input = this.element.querySelector("input");
64 | assert.dom("#orig-input-id").hasText(input.getAttribute("id"));
65 | },
66 | );
67 |
68 | testDefault(
69 | "it passes custom variables to custom component",
70 | async function (assert) {
71 | class CustomLabel extends Component {}
72 | setComponentTemplate(
73 | hbs`{{@customVariable}} `,
74 | CustomLabel,
75 | );
76 | this.CustomLabel = CustomLabel;
77 |
78 | await render(hbs` `);
84 |
85 | assert.dom("label").hasAttribute("style", "color: green;");
86 | assert.dom("label").hasText("Awesome!");
87 | },
88 | );
89 | });
90 |
--------------------------------------------------------------------------------
/tests/integration/helpers/class-list-test.js:
--------------------------------------------------------------------------------
1 | import { render } from "@ember/test-helpers";
2 | import { hbs } from "ember-cli-htmlbars";
3 | import { setupRenderingTest } from "ember-qunit";
4 | import { module } from "qunit";
5 |
6 | import { testDefault } from "dummy/tests/helpers/scenarios";
7 |
8 | module("Integration | Helper | class-list", function (hooks) {
9 | setupRenderingTest(hooks);
10 |
11 | testDefault("it renders", async function (assert) {
12 | await render(hbs`{{class-list "foo" null undefined "bar" ""}}`);
13 |
14 | assert.dom(this.element).hasText("foo bar");
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/tests/test-helper.js:
--------------------------------------------------------------------------------
1 | import { setApplication } from "@ember/test-helpers";
2 | import { start } from "ember-qunit";
3 | import * as QUnit from "qunit";
4 | import { setup } from "qunit-dom";
5 |
6 | import Application from "dummy/app";
7 | import config from "dummy/config/environment";
8 |
9 | setApplication(Application.create(config.APP));
10 |
11 | setup(QUnit.assert);
12 |
13 | start();
14 |
--------------------------------------------------------------------------------
/tests/unit/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adfinis/ember-validated-form/4342564b7108d04900bffd0567780dcb5d72ed14/tests/unit/.gitkeep
--------------------------------------------------------------------------------
/tsconfig.declarations.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "declarations",
5 | "emitDeclarationOnly": true,
6 | "noEmit": false,
7 | "rootDir": "."
8 | },
9 | "include": ["addon", "addon-test-support"]
10 | }
11 |
--------------------------------------------------------------------------------