diff --git a/package.json b/package.json index c29524a5..3ab57960 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "babel-register": "^6.18.0", "cross-env": "^5.1.0", "css-loader": "^0.28.4", - "eslint": "^3.13.1", + "eslint": "^4.3.0", "eslint-config-ovh": "^0.1.1", "eslint-friendly-formatter": "^3.0.0", "eslint-loader": "^1.9.0", diff --git a/packages/oui-action-menu/src/index.spec.js b/packages/oui-action-menu/src/index.spec.js index f6dc1f13..c91e1f0d 100644 --- a/packages/oui-action-menu/src/index.spec.js +++ b/packages/oui-action-menu/src/index.spec.js @@ -25,11 +25,9 @@ describe("ouiActionMenu", () => { const element = TestUtils.compileTemplate( ` Action 1 - `, - { + `, { clickHandler: clickSpy - } - ); + }); const buttonElement = element[0].querySelector("button"); expect(buttonElement).toBeTruthy(); diff --git a/packages/oui-angular/src/index.js b/packages/oui-angular/src/index.js index 0c2c42ba..c76e14dc 100644 --- a/packages/oui-angular/src/index.js +++ b/packages/oui-angular/src/index.js @@ -23,8 +23,6 @@ import Pagination from "@oui-angular/oui-pagination/src"; import Popover from "@oui-angular/oui-popover/src"; import Progress from "@oui-angular/oui-progress/src"; import Radio from "@oui-angular/oui-radio/src"; -import RadioGroup from "@oui-angular/oui-radio-group/src"; -import RadioToggleGroup from "@oui-angular/oui-radio-toggle-group/src"; import Search from "@oui-angular/oui-search/src"; import Select from "@oui-angular/oui-select/src"; import SelectPicker from "@oui-angular/oui-select-picker/src"; @@ -64,8 +62,6 @@ export default angular Popover, Progress, Radio, - RadioGroup, - RadioToggleGroup, Search, Select, SelectPicker, diff --git a/packages/oui-angular/src/index.spec.js b/packages/oui-angular/src/index.spec.js index 3483b58a..4afdcd66 100644 --- a/packages/oui-angular/src/index.spec.js +++ b/packages/oui-angular/src/index.spec.js @@ -25,8 +25,6 @@ loadTests(require.context("../../oui-pagination/src/", true, /.*((\.spec)|(index loadTests(require.context("../../oui-popover/src/", true, /.*((\.spec)|(index))$/)); loadTests(require.context("../../oui-progress/src/", true, /.*((\.spec)|(index))$/)); loadTests(require.context("../../oui-radio/src/", true, /.*((\.spec)|(index))$/)); -loadTests(require.context("../../oui-radio-group/src/", true, /.*((\.spec)|(index))$/)); -loadTests(require.context("../../oui-radio-toggle-group/src/", true, /.*((\.spec)|(index))$/)); loadTests(require.context("../../oui-search/src/", true, /.*((\.spec)|(index))$/)); loadTests(require.context("../../oui-select/src/", true, /.*((\.spec)|(index))$/)); loadTests(require.context("../../oui-select-picker/src/", true, /.*((\.spec)|(index))$/)); diff --git a/packages/oui-checkbox/src/index.spec.js b/packages/oui-checkbox/src/index.spec.js index 3f443ede..98d9b4d1 100644 --- a/packages/oui-checkbox/src/index.spec.js +++ b/packages/oui-checkbox/src/index.spec.js @@ -219,8 +219,8 @@ describe("ouiCheckbox", () => { const element = TestUtils.compileTemplate(` `, { - isRequired: true - }); + isRequired: true + }); const checkboxElement = getCheckboxInputElement(element); expect(angular.element(checkboxElement).prop("required")).toBe(true); @@ -230,8 +230,8 @@ describe("ouiCheckbox", () => { const element = TestUtils.compileTemplate(` `, { - isRequired: false - }); + isRequired: false + }); const checkboxElement = getCheckboxInputElement(element); expect(angular.element(checkboxElement).prop("required")).toBe(false); @@ -242,8 +242,8 @@ describe("ouiCheckbox", () => { `, { - isRequired: true - }); + isRequired: true + }); const form = element.scope().form; const checkboxElement = getCheckboxInputElement(element); diff --git a/packages/oui-criteria-adder/src/index.spec.js b/packages/oui-criteria-adder/src/index.spec.js index 6c504fb9..ad693d49 100644 --- a/packages/oui-criteria-adder/src/index.spec.js +++ b/packages/oui-criteria-adder/src/index.spec.js @@ -73,13 +73,14 @@ describe("ouiCriteriaAdder", () => { const submitButton = component[0].querySelectorAll("[type=submit]"); const dropdown = component.find("oui-dropdown"); const fields = component.find("oui-field"); + const expectedLength = 3; expect(form.length).toBe(1); expect(triggerButton.length).toBe(1); expect(submitButton.length).toBe(1); expect(angular.element(triggerButton).attr("oui-dropdown-trigger")).toBeDefined(); expect(dropdown.length).toBe(1); - expect(fields.length).toBe(3); + expect(fields.length).toBe(expectedLength); }); it("should have an attribute id and name on the form and every inputs/selectors, and removed on the root component", () => { diff --git a/packages/oui-criteria-container/src/index.spec.js b/packages/oui-criteria-container/src/index.spec.js index b1f7bf1a..887fa7ef 100644 --- a/packages/oui-criteria-container/src/index.spec.js +++ b/packages/oui-criteria-container/src/index.spec.js @@ -66,7 +66,8 @@ describe("ouiCriteriaContainer", () => { it("should delete a criteria", () => { controller.criteria.push(criterion); controller.criteria.push(criterion2); - expect(controller.criteria.length).toEqual(2); + const expectedLength = 2; + expect(controller.criteria.length).toEqual(expectedLength); controller.remove(criterion); expect(controller.criteria.length).toEqual(1); @@ -87,13 +88,15 @@ describe("ouiCriteriaContainer", () => { expect(controller.criteria.length).toEqual(0); controller.set(criteria); - expect(controller.criteria.length).toEqual(2); + const expectedLength = 2; + expect(controller.criteria.length).toEqual(expectedLength); }); it("should delete all criteria", () => { controller.criteria.push(criterion); controller.criteria.push(criterion2); - expect(controller.criteria.length).toEqual(2); + const expectedLength = 2; + expect(controller.criteria.length).toEqual(expectedLength); controller.clear(); expect(controller.criteria.length).toEqual(0); diff --git a/packages/oui-datagrid/src/filter/filter.spec.js b/packages/oui-datagrid/src/filter/filter.spec.js index b049b6cc..5126ed53 100644 --- a/packages/oui-datagrid/src/filter/filter.spec.js +++ b/packages/oui-datagrid/src/filter/filter.spec.js @@ -83,7 +83,8 @@ describe("Filter", () => { it("should apply 1 filter", () => { filter = new Filter([textSearchCriterion], columns); const filtered = filter.applyFilter(fakeData); - expect(filtered.length).toBe(2); + const expectedLength = 2; + expect(filtered.length).toBe(expectedLength); }); }); @@ -92,7 +93,8 @@ describe("Filter", () => { it("should find text in object", () => { filter = new Filter([textSearchCriterion], columns); const filtered = filter.applyCriteria(fakeData, textSearchCriterion); - expect(filtered.length).toBe(2); + const expectedLength = 2; + expect(filtered.length).toBe(expectedLength); }); }); @@ -106,7 +108,8 @@ describe("Filter", () => { operator: "contains", value: "aaron" }); - expect(filtered.length).toBe(2); + const expectedLength = 2; + expect(filtered.length).toBe(expectedLength); }); it("should filter (negated)", () => { @@ -117,7 +120,8 @@ describe("Filter", () => { operator: "containsNot", value: "aaron" }); - expect(filtered.length).toBe(fakeData.length - 2); + const expectedLength = 2; + expect(filtered.length).toBe(fakeData.length - expectedLength); }); }); diff --git a/packages/oui-datagrid/src/parameters/datagrid-parameters.spec.js b/packages/oui-datagrid/src/parameters/datagrid-parameters.spec.js index b9d725c7..6cca86a7 100644 --- a/packages/oui-datagrid/src/parameters/datagrid-parameters.spec.js +++ b/packages/oui-datagrid/src/parameters/datagrid-parameters.spec.js @@ -66,7 +66,7 @@ describe("ouiDatagridParameters", () => { it("should display a disabled checkbox column when customization is prevented", () => { const columnsElements = getColumns(element); - const disabledColumn = getCheckbox(columnsElements, 3); + const disabledColumn = getCheckbox(columnsElements, 3); // eslint-disable-line no-magic-numbers expect(disabledColumn.prop("disabled")).toBe(true); }); }); @@ -91,7 +91,7 @@ describe("ouiDatagridParameters", () => { const columnsElements = getColumns(element); const $checkbox1 = getCheckbox(columnsElements, 0); const $checkbox2 = getCheckbox(columnsElements, 1); - const $checkbox3 = getCheckbox(columnsElements, 2); + const $checkbox3 = getCheckbox(columnsElements, 2); // eslint-disable-line no-magic-numbers const expected = angular.copy(columns); expected[0].hidden = true; diff --git a/packages/oui-dropdown/src/index.spec.js b/packages/oui-dropdown/src/index.spec.js index ac00cddc..f2fa14d1 100644 --- a/packages/oui-dropdown/src/index.spec.js +++ b/packages/oui-dropdown/src/index.spec.js @@ -190,8 +190,9 @@ describe("ouiDropdown", () => { `); const links = element.find("oui-dropdown-item").find("a"); + const expectedLength = 2; - expect(links.length).toBe(2); + expect(links.length).toBe(expectedLength); expect(links.hasClass("oui-dropdown-option")).toBeTruthy(); }); diff --git a/packages/oui-field/src/index.spec.js b/packages/oui-field/src/index.spec.js index 97c58652..ee391b5e 100644 --- a/packages/oui-field/src/index.spec.js +++ b/packages/oui-field/src/index.spec.js @@ -425,6 +425,7 @@ describe("ouiField", () => { describe("with radio buttons", () => { it("should detect all the radio buttons", () => { const name = "protocol"; + const expectedLength = 3; const element = TestUtils.compileTemplate(` @@ -454,7 +455,7 @@ describe("ouiField", () => { const controller = element.controller("ouiField"); // There is 3 HTML elements with the same name - expect(controller.controls[name].length).toEqual(3); + expect(controller.controls[name].length).toEqual(expectedLength); }); }); diff --git a/packages/oui-form-actions/src/index.spec.js b/packages/oui-form-actions/src/index.spec.js index e16ad21f..1336f894 100644 --- a/packages/oui-form-actions/src/index.spec.js +++ b/packages/oui-form-actions/src/index.spec.js @@ -114,8 +114,8 @@ describe("ouiFormActions", () => { on-submit="$ctrl.onSubmitTest()" on-cancel="$ctrl.onCancelTest()"> `, { - onSubmitTest: jasmine.createSpy("onSubmit") - }); + onSubmitTest: jasmine.createSpy("onSubmit") + }); component.find("button").eq(0).triggerHandler("click"); expect(component.scope().$ctrl.onSubmitTest).toHaveBeenCalled(); @@ -127,8 +127,8 @@ describe("ouiFormActions", () => { on-submit="$ctrl.onSubmitTest()" on-cancel="$ctrl.onCancelTest()"> `, { - onCancelTest: jasmine.createSpy("onCancel") - }); + onCancelTest: jasmine.createSpy("onCancel") + }); component.find("button").eq(1).triggerHandler("click"); expect(component.scope().$ctrl.onCancelTest).toHaveBeenCalled(); diff --git a/packages/oui-message/README.md b/packages/oui-message/README.md index 3a082ae9..40f1b7cc 100644 --- a/packages/oui-message/README.md +++ b/packages/oui-message/README.md @@ -4,28 +4,26 @@ ## Usage -### Information +### Basic ```html:preview Message -``` - -### Success - -```html:preview Message +Message +Message ``` -### Warning +**Note**: Messages of type `info` and `success` are dismissable by default. -```html:preview -Message -``` +### Dismissable -### Error +You can force the dismissable state by adding `dismissable` attribute. ```html:preview -Message +Message +Message +Message +Message ``` ### Accessibility @@ -39,5 +37,6 @@ | Attribute | Type | Binding | One-time binding | Values | Default | Description | ---- | ---- | ---- | ---- | ---- | ---- | ---- | `type` | string | @ | yes | `info`, `success`, `warning`, `error` | n/a | message type -| `aria-close-button-label` | function | @? | yes | n/a | n/a | accessibility label for close button +| `aria-close-button-label` | string | @? | yes | n/a | n/a | accessibility label for close button +| `dismissable` | boolean |
- +

+ + + + + +
+

active value: {{!!$ctrl.togglerActive | json}}

+
+``` + +**Note**: By using this mode, you disable the internal `oui-navbar-backdrop` and toggler navigation. + ## Aside Links ### With attribute `aside-links` diff --git a/packages/oui-navbar/src/index.spec.js b/packages/oui-navbar/src/index.spec.js index c3e67f15..d7d6db88 100644 --- a/packages/oui-navbar/src/index.spec.js +++ b/packages/oui-navbar/src/index.spec.js @@ -52,12 +52,12 @@ describe("ouiNavbar", () => { aside-links="$ctrl.asideLinks" toggler-links="$ctrl.togglerLinks"> `, { - brand: mockData.brand, - activeLink: mockData.mainLinks[0].name, - mainLinks: mockData.mainLinks, - asideLinks: mockData.asideLinks, - togglerLinks: mockData.togglerLinks - }); + brand: mockData.brand, + activeLink: mockData.mainLinks[0].name, + mainLinks: mockData.mainLinks, + asideLinks: mockData.asideLinks, + togglerLinks: mockData.togglerLinks + }); const controller = component.controller("ouiNavbar"); $timeout.flush(); @@ -238,8 +238,8 @@ describe("ouiNavbar", () => { icon-class="{{$ctrl.brand.iconClass}}"> `, { - brand: data - }); + brand: data + }); controller = component.find("oui-navbar-brand").controller("ouiNavbarBrand"); $timeout.flush(); @@ -287,13 +287,13 @@ describe("ouiNavbar", () => { `, { - name: "foo", - title: "bar", - label: "lorem", - badge: 5, - icon: "oui-icon oui-icon-help_circle", - text: "Lorem ipsum" - }); + name: "foo", + title: "bar", + label: "lorem", + badge: 5, + icon: "oui-icon oui-icon-help_circle", + text: "Lorem ipsum" + }); $timeout.flush(); }); @@ -332,13 +332,13 @@ describe("ouiNavbar", () => { `, { - name: "foo", - title: "bar", - label: "lorem", - badge: 5, - icon: "oui-icon oui-icon-help_circle", - text: "Lorem ipsum" - }); + name: "foo", + title: "bar", + label: "lorem", + badge: 5, + icon: "oui-icon oui-icon-help_circle", + text: "Lorem ipsum" + }); const dropdownMenu = component.find("oui-navbar-dropdown-menu"); $timeout.flush(); @@ -367,11 +367,11 @@ describe("ouiNavbar", () => { `, { - name: data.name, - title: data.title, - headerTitle: data.headerTitle, - subLinks: data.subLinks - }); + name: data.name, + title: data.title, + headerTitle: data.headerTitle, + subLinks: data.subLinks + }); $timeout.flush(); @@ -403,11 +403,11 @@ describe("ouiNavbar", () => { `, { - name: data.name, - title: data.title, - headerTitle: data.headerTitle, - subLinks: data.subLinks - }); + name: data.name, + title: data.title, + headerTitle: data.headerTitle, + subLinks: data.subLinks + }); $timeout.flush(); @@ -430,11 +430,11 @@ describe("ouiNavbar", () => { `, { - name: data.name, - title: data.title, - headerTitle: data.headerTitle, - subLinks: data.subLinks - }); + name: data.name, + title: data.title, + headerTitle: data.headerTitle, + subLinks: data.subLinks + }); $timeout.flush(); @@ -581,6 +581,47 @@ describe("ouiNavbar", () => { }); }); + describe("Toggler", () => { + it("should set the toggler active", () => { + const component = testUtils.compileTemplate(` + + `); + const scope = component.scope(); + const toggler = angular.element(component[0].querySelector(".oui-navbar-toggler")); + + expect(toggler.attr("aria-expanded")).toBe("false"); // Check when undefined + + scope.$ctrl.active = true; + scope.$apply(); + expect(toggler.attr("aria-expanded")).toBe("true"); + + scope.$ctrl.active = false; + scope.$apply(); + expect(toggler.attr("aria-expanded")).toBe("false"); + }); + + it("should set the toggler loading", () => { + const component = testUtils.compileTemplate(` + + `); + const scope = component.scope(); + const toggler = angular.element(component[0].querySelector(".oui-navbar-toggler_button")); + + expect(toggler.hasClass("ng-hide")).toBeFalsy(); // ngHide: Check when undefined + expect(angular.element(component[0].querySelector(".oui-navbar-toggler_loading")).length).toBe(0); // ngIf + + scope.$ctrl.loading = true; + scope.$apply(); + expect(toggler.hasClass("ng-hide")).toBeTruthy(); + expect(angular.element(component[0].querySelector(".oui-navbar-toggler_loading")).length).toBe(1); + + scope.$ctrl.loading = false; + scope.$apply(); + expect(toggler.hasClass("ng-hide")).toBeFalsy(); + expect(angular.element(component[0].querySelector(".oui-navbar-toggler_loading")).length).toBe(0); + }); + }); + describe("Backdrop", () => { const data = mockData.mainLinks; diff --git a/packages/oui-navbar/src/toggler/navbar-toggler.component.js b/packages/oui-navbar/src/toggler/navbar-toggler.component.js index 9a4cbff3..8a5833a7 100644 --- a/packages/oui-navbar/src/toggler/navbar-toggler.component.js +++ b/packages/oui-navbar/src/toggler/navbar-toggler.component.js @@ -6,7 +6,10 @@ export default { navbarCtrl: "^^ouiNavbar" }, bindings: { - links: "<" + links: " @@ -10,12 +10,12 @@ - + { it("should display an input with two buttons", () => { const elt = angular.element(''); const scope = $rootScope.$new(); + const expectedLength = 2; $compile(elt)(scope); scope.$digest(); expect(elt.find("input").length).toBe(1); - expect(elt.find("button").length).toBe(2); + expect(elt.find("button").length).toBe(expectedLength); }); it("should updates model when input changes", () => { const elt = angular.element(''); const scope = $rootScope.$new(); + const value = 5; $compile(elt)(scope); scope.$digest(); elt.find("input").controller("ngModel").$setViewValue("5"); - expect(scope.foo).toBe(5); + expect(scope.foo).toBe(value); elt.find("input").controller("ngModel").$setViewValue("1"); expect(scope.foo).toBe(1); }); @@ -49,36 +51,40 @@ describe("ouiNumeric", () => { it("should not updates model when input is given invalid value", () => { const elt = angular.element(''); const scope = $rootScope.$new(); + const value1 = 3; + const value2 = 7; $compile(elt)(scope); scope.$digest(); elt.find("input").controller("ngModel").$setViewValue("1"); expect(scope.foo).toBe(1); elt.find("input").controller("ngModel").$setViewValue("hello"); expect(scope.foo).toBe(1); - elt.find("input").controller("ngModel").$setViewValue(3); - expect(scope.foo).toBe(3); - elt.find("input").controller("ngModel").$setViewValue(7); - expect(scope.foo).toBe(3); + elt.find("input").controller("ngModel").$setViewValue(value1); + expect(scope.foo).toBe(value1); + elt.find("input").controller("ngModel").$setViewValue(value2); + expect(scope.foo).toBe(value1); }); it("should decrement value when clicking first button", () => { const elt = angular.element(''); const scope = $rootScope.$new(); + const foo = 10; $compile(elt)(scope); - scope.foo = 10; + scope.foo = foo; scope.$digest(); getDecrementBtn(elt).triggerHandler("click"); - expect(scope.foo).toBe(9); + expect(scope.foo).toBe(foo - 1); }); it("should increment value when clicking second button", () => { const elt = angular.element(''); const scope = $rootScope.$new(); + const foo = 10; $compile(elt)(scope); - scope.foo = 10; + scope.foo = foo; scope.$digest(); getIncrementBtn(elt).triggerHandler("click"); - expect(scope.foo).toBe(11); + expect(scope.foo).toBe(foo + 1); }); it("should disable left button is value is lower or equal to min", () => { @@ -146,7 +152,8 @@ describe("ouiNumeric", () => { $compile(elt)(scope); scope.$digest(); elt.find("input").controller("ngModel").$setViewValue("10"); - expect(scope.onChange).toHaveBeenCalledWith(10); + const value = 10; + expect(scope.onChange).toHaveBeenCalledWith(value); }); it("should not trigger onChange callback when value is updated with no changes", () => { diff --git a/packages/oui-pagination/src/index.spec.js b/packages/oui-pagination/src/index.spec.js index e1afc659..e222c276 100644 --- a/packages/oui-pagination/src/index.spec.js +++ b/packages/oui-pagination/src/index.spec.js @@ -2,7 +2,7 @@ describe("ouiPagination", () => { let TestUtils; const customPageSize = 50; - const customPageSizesList = [25, 50, 100, 200]; + const customPageSizesList = [25, 50, 100, 200]; // eslint-disable-line no-magic-numbers const getPagination = elt => elt[0].querySelector(".oui-pagination"); const getProgress = elt => elt[0].querySelector(".oui-pagination__progress"); @@ -70,9 +70,10 @@ describe("ouiPagination", () => { total-items="100"> `); + const pageSize = 50; const paginationController = element.controller("ouiPagination"); - expect(paginationController.pageSize).toEqual(50); + expect(paginationController.pageSize).toEqual(pageSize); }); it("should display 4 buttons for page selection", () => { @@ -83,8 +84,9 @@ describe("ouiPagination", () => { total-items="100"> `); + const expectedLength = 4; - expect(getSelector(element).querySelectorAll(".oui-button-group .oui-button").length).toEqual(4); + expect(getSelector(element).querySelectorAll(".oui-button-group .oui-button").length).toEqual(expectedLength); expect(getSelector(element).querySelector(".oui-pagination-menu")).toBeNull(); }); @@ -138,8 +140,8 @@ describe("ouiPagination", () => { on-change="$ctrl.clickHandler($event)"> `, { - clickHandler: clickSpy - }); + clickHandler: clickSpy + }); angular.element(getNextButton(element)).triggerHandler("click"); expect(clickSpy).toHaveBeenCalledWith({ @@ -159,8 +161,8 @@ describe("ouiPagination", () => { on-change="$ctrl.clickHandler($event)"> `, { - clickHandler: clickSpy - }); + clickHandler: clickSpy + }); angular.element(getPreviousButton(element)).triggerHandler("click"); expect(clickSpy).toHaveBeenCalledWith({ @@ -204,7 +206,8 @@ describe("ouiPagination", () => { expect(buttons[1].hasAttribute("disabled")).toBeTruthy(); clickSpy.calls.reset(); - angular.element(buttons[3]).triggerHandler("click"); + const index = 3; + angular.element(buttons[index]).triggerHandler("click"); expect(clickSpy).toHaveBeenCalledWith({ offset: 76, pageSize: 25 @@ -243,7 +246,9 @@ describe("ouiPagination", () => { expect(buttons[1].hasAttribute("disabled")).toBeTruthy(); clickSpy.calls.reset(); - angular.element(buttons[39]).triggerHandler("click"); + + const index = 39; + angular.element(buttons[index]).triggerHandler("click"); expect(clickSpy).toHaveBeenCalledWith(jasmine.objectContaining({ offset: 976 })); expect(clickSpy.calls.count()).toEqual(1); }); @@ -260,7 +265,8 @@ describe("ouiPagination", () => { `); const buttons = getProgress(element).querySelectorAll(".oui-pagination-menu__items-list .oui-pagination-menu__item"); - expect(buttons.length).toEqual(4); + const expectedLength = 4; + expect(buttons.length).toEqual(expectedLength); expect(buttons[0].hasAttribute("disabled")).toBeTruthy(); }); @@ -292,7 +298,8 @@ describe("ouiPagination", () => { // Count page buttons const pageButtons = getSelector(element).querySelectorAll(".oui-pagination-menu__items-list .oui-pagination-menu__item"); - expect(pageButtons.length).toEqual(20); + const length = 20; + expect(pageButtons.length).toEqual(length); }); it("should reset offset to 1 when page size is changed", () => { @@ -331,7 +338,8 @@ describe("ouiPagination", () => { // So, instead of displaying 4 values (see customPageSizesList = [25, 50, 100, 200]) the page size list // is limited to all values lower or equal to pageSizeMax: [25, 50] (length: 2). const pageSizesButtons = getProgress(element).querySelectorAll(".oui-pagination-menu__items-list .oui-pagination-menu__item"); - expect(pageSizesButtons.length).toEqual(2); + const expectedLength = 2; + expect(pageSizesButtons.length).toEqual(expectedLength); }); it("should have max page size limiting the page size list (and creating a new value in this list)", () => { @@ -343,16 +351,18 @@ describe("ouiPagination", () => { total-items="1000"> `, { - pageSizeMax: 80 - }); + pageSizeMax: 80 + }); // Page sizes list should not list page size above pageSizeMax (80). // So, instead of displaying 4 values (see customPageSizesList = [25, 50, 100, 200]) the page size list // is limited to all values lower or equal to pageSizeMax and pageSizeMax: [25, 50, 80] (length: 3). const pageSizesButtons = getPageSizeButtons(element); + const expectedLength = 3; + const index = 2; - expect(pageSizesButtons.length).toEqual(3); - expect(pageSizesButtons[2].innerHTML).toEqual("80"); + expect(pageSizesButtons.length).toEqual(expectedLength); + expect(pageSizesButtons[index].innerHTML).toEqual("80"); }); it("should be reinitilized", () => { @@ -364,8 +374,8 @@ describe("ouiPagination", () => { total-items="1000"> `, { - pageSizeMax: 80 - }); + pageSizeMax: 80 + }); const contextController = element.scope().$ctrl; let pageSizesButtons = getPageSizeButtons(element); diff --git a/packages/oui-progress/src/index.spec.js b/packages/oui-progress/src/index.spec.js index 77f6223f..daa0dabd 100644 --- a/packages/oui-progress/src/index.spec.js +++ b/packages/oui-progress/src/index.spec.js @@ -102,7 +102,7 @@ describe("ouiProgress", () => { it("should have the correct width when max-value is used", () => { const value = 10; - const expectedWidth = value / 2; + const expectedWidth = value / 2; // eslint-disable-line no-magic-numbers const element = TestUtils.compileTemplate(` @@ -145,7 +145,7 @@ describe("ouiProgress", () => { it("should have the correct position according to value", () => { const value = 10; const maxValue = 200; - const leftPosition = value / (maxValue / 100); + const leftPosition = value / (maxValue / 100); // eslint-disable-line no-magic-numbers const element = TestUtils.compileTemplate(` diff --git a/packages/oui-radio-group/README.md b/packages/oui-radio-group/README.md deleted file mode 100644 index b942764d..00000000 --- a/packages/oui-radio-group/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Radio-group - - - -## Usage - -### Default - -```html:preview -
- - First - Second - Third - -
-``` - -### Disabled - -```html:preview -
- - First - Second - Third - -
-``` - -### On change - -```html:preview -
- - First - Second - Third - -
-Last onChange value: {{ $ctrl.lastOnChangeValue }} -``` - -## API - -| Attribute | Type | Binding | One-time Binding | Values | Default | Description -| ---- | ---- | ---- | ---- | ---- | ---- | ---- -| `model` | Object | =? | no | n/a | n/a | current value of the radio -| `name` | string | @? | yes | n/a | n/a | name attribute of the radio -| `on-change` | function | & | no | n/a | n/a | handler triggered when model has changed diff --git a/packages/oui-radio-group/src/index.js b/packages/oui-radio-group/src/index.js deleted file mode 100644 index 8a055f7b..00000000 --- a/packages/oui-radio-group/src/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import "@oui-angular/oui-radio/src"; -import RadioGroup from "./radio-group.component.js"; - -export default angular - .module("oui.radio-group", [ - "oui.radio" - ]) - .component("ouiRadioGroup", RadioGroup) - .name; diff --git a/packages/oui-radio-group/src/index.spec.js b/packages/oui-radio-group/src/index.spec.js deleted file mode 100644 index e77b790d..00000000 --- a/packages/oui-radio-group/src/index.spec.js +++ /dev/null @@ -1,148 +0,0 @@ -describe("ouiRadioGroup", () => { - let TestUtils; - let $timeout; - let $rootScope; - - beforeEach(angular.mock.module("oui.radio")); - beforeEach(angular.mock.module("oui.radio-group")); - beforeEach(angular.mock.module("oui.test-utils")); - - beforeEach(inject((_TestUtils_, _$timeout_, _$rootScope_) => { - TestUtils = _TestUtils_; - $timeout = _$timeout_; - $rootScope = _$rootScope_; - })); - - const getRadioInputElement = (element) => angular.element(element[0].querySelector("input[type=radio]")); - const getElementByClass = (element, value) => angular.element(element[0].querySelector(value)); - const getRadioInputElementByValue = (element, value) => angular.element(element[0].querySelector(`input[type=radio][value=${value}]`)); - const getRadioGroupElement = (element) => angular.element(element[0]); - const clickRadio = (radioToCheck) => { - radioToCheck.prop("checked", true); - radioToCheck.triggerHandler("click"); // NG 1.6 - radioToCheck.triggerHandler("change"); // NG 1.7 - }; - - describe("Component", () => { - - describe("attributes", () => { - - it("should assign defined name to child radios when name attribute is defined", () => { - const name = "foo"; - - const element = TestUtils.compileTemplate(` - - - - `); - - expect(getRadioInputElement(element).prop("name")).toBe(name); - }); - - it("should assign a generated name to child radios when name attribute is undefined ", () => { - const element = TestUtils.compileTemplate(` - - - - `); - - expect(getRadioInputElement(element).prop("name")).toMatch(/^oui-radio-group-\d+$/); - }); - - it("should add radiogroup role", () => { - const element = TestUtils.compileTemplate(""); - $timeout.flush(); - - expect(getRadioGroupElement(element).attr("role")).toEqual("radiogroup"); - }); - }); - - describe("classes", () => { - - it("should set radio classes", () => { - const element = TestUtils.compileTemplate(` - - - - `); - - expect(getElementByClass(element, ".oui-radio").length).toEqual(1); - expect(getElementByClass(element, ".oui-radio__input").length).toEqual(1); - expect(getElementByClass(element, ".oui-radio__label-container").length).toEqual(1); - expect(getElementByClass(element, ".oui-radio__label").length).toEqual(1); - }); - }); - - describe("on radio group model change", () => { - - it("should update child radio models at initialization", () => { - const defaultRadioValue = "bValue"; - const otherRadioValue = "aValue"; - const element = TestUtils.compileTemplate(` - - - - - `, { - defaultValue: defaultRadioValue - }); - - expect(getRadioInputElementByValue(element, defaultRadioValue).prop("checked")).toEqual(true); - expect(getRadioInputElementByValue(element, otherRadioValue).prop("checked")).toEqual(false); - }); - - it("should update child radio models after initialization too", () => { - const defaultRadioValue = "bValue"; - const newRadioValue = "aValue"; - const element = TestUtils.compileTemplate(` - - - - - `, { - defaultValue: defaultRadioValue - }); - - TestUtils.getElementController(element).defaultValue = newRadioValue; - $rootScope.$digest(); - - expect(getRadioInputElementByValue(element, newRadioValue).prop("checked")).toEqual(true); - expect(getRadioInputElementByValue(element, defaultRadioValue).prop("checked")).toEqual(false); - }); - }); - - describe("on child radio click", () => { - - it("should update radio group model", () => { - const clickedRadioValue = "bValue"; - const element = TestUtils.compileTemplate(` - - - - - `); - - clickRadio(getRadioInputElementByValue(element, clickedRadioValue)); - - expect(TestUtils.getElementController(element).model).toEqual(clickedRadioValue); - }); - - it("should trigger on change callback", () => { - const clickedRadioValue = "bValue"; - const onChangeSpy = jasmine.createSpy("onChangeSpy"); - const element = TestUtils.compileTemplate(` - - - - - `, { - onChange: onChangeSpy - }); - - clickRadio(getRadioInputElementByValue(element, clickedRadioValue)); - $timeout.flush(); - expect(onChangeSpy).toHaveBeenCalledWith(clickedRadioValue); - }); - }); - }); -}); diff --git a/packages/oui-radio-toggle-group/README.md b/packages/oui-radio-toggle-group/README.md deleted file mode 100644 index 45c9d2ea..00000000 --- a/packages/oui-radio-toggle-group/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Radio-toggle-group - - - -## Usage - -### Default - -```html:preview -
- - First - Second - Third - -
-``` - -### Disabled - -```html:preview -
- - First - Second - Third - -
-``` - -### On change - -```html:preview -
- - First - Second - Third - -
-Last onChange value: {{ $ctrl.lastOnChangeValue }} -``` - -## API - -| Attribute | Type | Binding | One-time Binding | Values | Default | Description -| ---- | ---- | ---- | ---- | ---- | ---- | ---- -| `model` | Object | =? | no | n/a | n/a | current value of the radio -| `name` | string | @? | yes | n/a | n/a | name attribute of the radio -| `on-change` | function | & | no | n/a | n/a | handler triggered when model has changed diff --git a/packages/oui-radio-toggle-group/src/index.js b/packages/oui-radio-toggle-group/src/index.js deleted file mode 100644 index f89dd3c6..00000000 --- a/packages/oui-radio-toggle-group/src/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import "@oui-angular/oui-radio/src"; -import "@oui-angular/oui-radio-group/src"; -import RadioToggleGroup from "./radio-toggle-group.component.js"; - -export default angular - .module("oui.radio-toggle-group", [ - "oui.radio", - "oui.radio-group" - ]) - .component("ouiRadioToggleGroup", RadioToggleGroup) - .name; diff --git a/packages/oui-radio-toggle-group/src/index.spec.js b/packages/oui-radio-toggle-group/src/index.spec.js deleted file mode 100644 index 5751abd7..00000000 --- a/packages/oui-radio-toggle-group/src/index.spec.js +++ /dev/null @@ -1,149 +0,0 @@ -describe("ouiRadioToggleGroup", () => { - let TestUtils; - let $timeout; - let $rootScope; - - beforeEach(angular.mock.module("oui.radio")); - beforeEach(angular.mock.module("oui.radio-group")); - beforeEach(angular.mock.module("oui.radio-toggle-group")); - beforeEach(angular.mock.module("oui.test-utils")); - - beforeEach(inject((_TestUtils_, _$timeout_, _$rootScope_) => { - TestUtils = _TestUtils_; - $timeout = _$timeout_; - $rootScope = _$rootScope_; - })); - - const getRadioInputElement = (element) => angular.element(element[0].querySelector("input[type=radio]")); - const getElementByClass = (element, value) => angular.element(element[0].querySelector(value)); - const getRadioInputElementByValue = (element, value) => angular.element(element[0].querySelector(`input[type=radio][value=${value}]`)); - const getRadioGroupElement = (element) => angular.element(element[0]); - const clickRadio = (radioToCheck) => { - radioToCheck.prop("checked", true); - radioToCheck.triggerHandler("click"); // NG 1.6 - radioToCheck.triggerHandler("change"); // NG 1.7 - }; - - describe("Component", () => { - - describe("attributes", () => { - - it("should assign defined name to child radios when name attribute is defined", () => { - const name = "foo"; - - const element = TestUtils.compileTemplate(` - - - - `); - - expect(getRadioInputElement(element).prop("name")).toBe(name); - }); - - it("should assign a generated name to child radios when name attribute is undefined ", () => { - const element = TestUtils.compileTemplate(` - - - - `); - - expect(getRadioInputElement(element).prop("name")).toMatch(/^oui-radio-group-\d+$/); - }); - - it("should add radiogroup role", () => { - const element = TestUtils.compileTemplate(""); - $timeout.flush(); - - expect(getRadioGroupElement(element).attr("role")).toEqual("radiogroup"); - }); - }); - - describe("classes", () => { - - it("should set toggle classes", () => { - const element = TestUtils.compileTemplate(` - - - - `); - - expect(getElementByClass(element, ".oui-radio-toggle").length).toEqual(1); - expect(getElementByClass(element, ".oui-radio-toggle__input").length).toEqual(1); - expect(getElementByClass(element, ".oui-radio-toggle__label-container").length).toEqual(1); - expect(getElementByClass(element, ".oui-radio-toggle__label").length).toEqual(1); - }); - }); - - describe("on radio group model change", () => { - - it("should update child radio models at initialization", () => { - const defaultRadioValue = "bValue"; - const otherRadioValue = "aValue"; - const element = TestUtils.compileTemplate(` - - - - - `, { - defaultValue: defaultRadioValue - }); - - expect(getRadioInputElementByValue(element, defaultRadioValue).prop("checked")).toEqual(true); - expect(getRadioInputElementByValue(element, otherRadioValue).prop("checked")).toEqual(false); - }); - - it("should update child radio models after initialization too", () => { - const defaultRadioValue = "bValue"; - const newRadioValue = "aValue"; - const element = TestUtils.compileTemplate(` - - - - - `, { - defaultValue: defaultRadioValue - }); - - TestUtils.getElementController(element).defaultValue = newRadioValue; - $rootScope.$digest(); - - expect(getRadioInputElementByValue(element, newRadioValue).prop("checked")).toEqual(true); - expect(getRadioInputElementByValue(element, defaultRadioValue).prop("checked")).toEqual(false); - }); - }); - - describe("on child radio click", () => { - - it("should update radio group model", () => { - const clickedRadioValue = "bValue"; - const element = TestUtils.compileTemplate(` - - - - - `); - - clickRadio(getRadioInputElementByValue(element, clickedRadioValue)); - - expect(TestUtils.getElementController(element).model).toEqual(clickedRadioValue); - }); - - it("should trigger on change callback", () => { - const clickedRadioValue = "bValue"; - const onChangeSpy = jasmine.createSpy("onChangeSpy"); - const element = TestUtils.compileTemplate(` - - - - - `, { - onChange: onChangeSpy - }); - - clickRadio(getRadioInputElementByValue(element, clickedRadioValue)); - $timeout.flush(); - expect(onChangeSpy).toHaveBeenCalledWith(clickedRadioValue); - }); - }); - }); -}); diff --git a/packages/oui-radio/README.md b/packages/oui-radio/README.md index 2310ec1f..212e1fde 100644 --- a/packages/oui-radio/README.md +++ b/packages/oui-radio/README.md @@ -62,8 +62,88 @@ Last onChange value: {{ $ctrl.lastOnChangeValue }} ``` +## Group + +### Basic + +```html:preview +
+ + First + Second + Third + +
+``` + +### Disabled + +```html:preview +
+ + First + Second + Third + +
+``` + +### On change + +```html:preview +
+ + First + Second + Third + +
+Last onChange value: {{ $ctrl.lastOnChangeValue }} +``` + +## Toggle Group + +### Default + +```html:preview +
+ + First + Second + Third + +
+``` + +### Disabled + +```html:preview +
+ + First + Second + Third + +
+``` + +### On change + +```html:preview +
+ + First + Second + Third + +
+Last onChange value: {{ $ctrl.lastOnChangeValue }} +``` + ## API +### oui-radio + | Attribute | Type | Binding | One-time Binding | Values | Default | Description | ---- | ---- | ---- | ---- | ---- | ---- | ---- | `model` | object | =? | no | n/a | n/a | current value of the radio @@ -79,3 +159,19 @@ #### Deprecated * `text`: Replaced by transclude value + +### oui-radio-group + +| Attribute | Type | Binding | One-time Binding | Values | Default | Description +| ---- | ---- | ---- | ---- | ---- | ---- | ---- +| `model` | Object | =? | no | n/a | n/a | current value of the radio +| `name` | string | @? | yes | n/a | n/a | name attribute of the radio +| `on-change` | function | & | no | n/a | n/a | handler triggered when model has changed + +### oui-radio-toggle-group + +| Attribute | Type | Binding | One-time Binding | Values | Default | Description +| ---- | ---- | ---- | ---- | ---- | ---- | ---- +| `model` | Object | =? | no | n/a | n/a | current value of the radio +| `name` | string | @? | yes | n/a | n/a | name attribute of the radio +| `on-change` | function | & | no | n/a | n/a | handler triggered when model has changed diff --git a/packages/oui-radio-group/src/radio-group.component.js b/packages/oui-radio/src/group/radio-group.component.js similarity index 100% rename from packages/oui-radio-group/src/radio-group.component.js rename to packages/oui-radio/src/group/radio-group.component.js diff --git a/packages/oui-radio-group/src/radio-group.controller.js b/packages/oui-radio/src/group/radio-group.controller.js similarity index 100% rename from packages/oui-radio-group/src/radio-group.controller.js rename to packages/oui-radio/src/group/radio-group.controller.js diff --git a/packages/oui-radio/src/index.js b/packages/oui-radio/src/index.js index 566d134b..a48479b9 100644 --- a/packages/oui-radio/src/index.js +++ b/packages/oui-radio/src/index.js @@ -1,6 +1,10 @@ -import Radio from "./radio.component.js"; +import Radio from "./radio.component"; +import RadioGroup from "./group/radio-group.component"; +import RadioToggleGroup from "./toggle-group/radio-toggle-group.component"; export default angular .module("oui.radio", []) .component("ouiRadio", Radio) + .component("ouiRadioGroup", RadioGroup) + .component("ouiRadioToggleGroup", RadioToggleGroup) .name; diff --git a/packages/oui-radio/src/index.spec.js b/packages/oui-radio/src/index.spec.js index 95f7fe48..b4bf309a 100644 --- a/packages/oui-radio/src/index.spec.js +++ b/packages/oui-radio/src/index.spec.js @@ -1,261 +1,529 @@ describe("ouiRadio", () => { let TestUtils; + let $rootScope; let $timeout; beforeEach(angular.mock.module("oui.radio")); beforeEach(angular.mock.module("oui.test-utils")); - beforeEach(inject((_TestUtils_, _$timeout_) => { + beforeEach(inject((_TestUtils_, _$rootScope_, _$timeout_) => { TestUtils = _TestUtils_; + $rootScope = _$rootScope_; $timeout = _$timeout_; })); - const getRadioInputElement = (element) => element[0].querySelector("input[type=radio]"); - const getRadioLabelElement = (element) => element[0].querySelector("label"); - const getRadioTextContainerElement = (element) => element[0].querySelector(".oui-radio__label span:first-child"); - const getRadioDescriptionElement = (element) => element[0].querySelector(".oui-radio__description"); - describe("Component", () => { - describe("id attribute", () => { - it("should generate an id for the input and label when undefined", () => { - const element = TestUtils.compileTemplate(""); + describe("Radio", () => { + const getRadioInputElement = (element) => element[0].querySelector("input[type=radio]"); + const getRadioLabelElement = (element) => element[0].querySelector("label"); + const getRadioTextContainerElement = (element) => element[0].querySelector(".oui-radio__label span:first-child"); + const getRadioDescriptionElement = (element) => element[0].querySelector(".oui-radio__description"); + + describe("id attribute", () => { + it("should generate an id for the input and label when undefined", () => { + const element = TestUtils.compileTemplate(""); - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("id")).toMatch(/^ouiRadio\d+$/); + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("id")).toMatch(/^ouiRadio\d+$/); + + const radioLabelElement = getRadioLabelElement(element); + expect(angular.element(radioLabelElement).attr("for")).toMatch(/^ouiRadio\d+$/); + }); - const radioLabelElement = getRadioLabelElement(element); - expect(angular.element(radioLabelElement).attr("for")).toMatch(/^ouiRadio\d+$/); + it("should set the id for the input and label when defined", () => { + const element = TestUtils.compileTemplate(''); + + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("id")).toBe("test"); + + const radioLabelElement = getRadioLabelElement(element); + expect(angular.element(radioLabelElement).attr("for")).toBe("test"); + }); }); - it("should set the id for the input and label when defined", () => { - const element = TestUtils.compileTemplate(''); + describe("name attribute", () => { + it("should set the name attribute on input when defined", () => { + const element = TestUtils.compileTemplate(''); - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("id")).toBe("test"); + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("name")).toBe("test"); + }); + + it("should set the name attribute on input when defined with id", () => { + const element = TestUtils.compileTemplate(''); + + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("name")).toBe("test"); + }); - const radioLabelElement = getRadioLabelElement(element); - expect(angular.element(radioLabelElement).attr("for")).toBe("test"); + it("should set the name attribute to id when only id is defined", () => { + const element = TestUtils.compileTemplate(''); + + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("name")).toBe("test"); + }); }); - }); - describe("name attribute", () => { - it("should set the name attribute on input when defined", () => { - const element = TestUtils.compileTemplate(''); + describe("text attribute", () => { + it("should display a text inside the radio's text container", () => { + const element = TestUtils.compileTemplate(''); - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("name")).toBe("test"); + const textContainerRadioElement = getRadioTextContainerElement(element); + expect(angular.element(textContainerRadioElement).html()).toBe("test"); + }); }); - it("should set the name attribute on input when defined with id", () => { - const element = TestUtils.compileTemplate(''); + describe("description attribute", () => { + it("should display the radio's description container when empty", () => { + const element = TestUtils.compileTemplate(""); + + const descriptionRadioElement = getRadioDescriptionElement(element); + expect(angular.element(descriptionRadioElement).length).toBe(0); + }); + + it("should display a text inside the radio's description container", () => { + const element = TestUtils.compileTemplate(''); - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("name")).toBe("test"); + const descriptionRadioElement = getRadioDescriptionElement(element); + expect(angular.element(descriptionRadioElement).html()).toBe("test"); + }); }); - it("should set the name attribute to id when only id is defined", () => { - const element = TestUtils.compileTemplate(''); + describe("value attribute", () => { + it("should set the radio's value attribute", () => { + const element = TestUtils.compileTemplate(''); - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("name")).toBe("test"); + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).attr("value")).toEqual("aValue"); + }); }); - }); - describe("text attribute", () => { - it("should display a text inside the radio's text container", () => { - const element = TestUtils.compileTemplate(''); + describe("disabled attribute", () => { + it("should display an active radio when no attribute", () => { + const element = TestUtils.compileTemplate(""); - const textContainerRadioElement = getRadioTextContainerElement(element); - expect(angular.element(textContainerRadioElement).html()).toBe("test"); + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("disabled")).toBe(false); + }); + + it("should display a disabled radio when defined but no value", () => { + const element = TestUtils.compileTemplate(""); + + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("disabled")).toBe(true); + }); + + it("should display a disabled radio when true", () => { + const element = TestUtils.compileTemplate("", { + disabled: true + }); + + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("disabled")).toBe(true); + }); + + it("should display an active radio when false", () => { + const element = TestUtils.compileTemplate("", { + notDisabled: false + }); + + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("disabled")).toBe(false); + }); }); - }); - describe("description attribute", () => { - it("should display the radio's description container when empty", () => { - const element = TestUtils.compileTemplate(""); + describe("required attribute", () => { + it("should display an active radio when no attribute", () => { + const element = TestUtils.compileTemplate(""); + + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("required")).toBe(false); + }); + + it("should display a required radio when defined but no value", () => { + const element = TestUtils.compileTemplate(""); - const descriptionRadioElement = getRadioDescriptionElement(element); - expect(angular.element(descriptionRadioElement).length).toBe(0); + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("required")).toBe(true); + }); + + it("should display a required radio when true", () => { + const element = TestUtils.compileTemplate("", { + required: true + }); + + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("required")).toBe(true); + }); + + it("should display an active radio when false", () => { + const element = TestUtils.compileTemplate("", { + notRequired: false + }); + + const radioElement = getRadioInputElement(element); + expect(angular.element(radioElement).prop("required")).toBe(false); + }); }); - it("should display a text inside the radio's description container", () => { - const element = TestUtils.compileTemplate(''); - const descriptionRadioElement = getRadioDescriptionElement(element); - expect(angular.element(descriptionRadioElement).html()).toBe("test"); + describe("thumbnail attribute", () => { + it("should display a classic radio when no attribute", () => { + const element = TestUtils.compileTemplate(""); + expect(angular.element(element).hasClass("oui-radio_thumbnail")).toBe(false); + }); + + it("should display a thumbnail radio when defined but no value", () => { + const element = TestUtils.compileTemplate(""); + expect(angular.element(element).hasClass("oui-radio_thumbnail")).toBe(true); + }); + + it("should display a classic radio when false", () => { + const element = TestUtils.compileTemplate("", { + thumbnail: false + }); + + expect(angular.element(element).hasClass("oui-radio_thumbnail")).toBe(false); + }); + + it("should display a thumbnail radio when true", () => { + const element = TestUtils.compileTemplate("", { + thumbnail: true + }); + + expect(angular.element(element).hasClass("oui-radio_thumbnail")).toBe(true); + }); }); - }); - describe("value attribute", () => { - it("should set the radio's value attribute", () => { - const element = TestUtils.compileTemplate(''); + describe("default value", () => { + it("should select the default value on loading", () => { + const onChangeSpy = jasmine.createSpy("onChangeSpy"); + + const element = TestUtils.compileTemplate(` +
+ + +
+ `, { + onChange: onChangeSpy, + radioValue: "bValue" + }); + + const radioComponent1 = element.children()[0]; + const radioComponent2 = element.children()[1]; + const $radioElement1 = angular.element(radioComponent1).find("input"); + const $radioElement2 = angular.element(radioComponent2).find("input"); + + expect($radioElement1.prop("checked")).toEqual(false); + expect($radioElement2.prop("checked")).toEqual(true); + }); + }); - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).attr("value")).toEqual("aValue"); + describe("on-change attribute", () => { + it("should trigger callback when the radio is clicked", () => { + const onChangeSpy = jasmine.createSpy("onChangeSpy"); + + const element = TestUtils.compileTemplate(` +
+ + +
+ `, { + onChange: onChangeSpy + }); + + const radioComponent1 = element.children()[0]; + const radioComponent2 = element.children()[1]; + const $radioElement1 = angular.element(radioComponent1).find("input"); + const $radioElement2 = angular.element(radioComponent2).find("input"); + + $radioElement1.prop("checked", true); + $radioElement1.triggerHandler("click"); // NG 1.6 + $radioElement1.triggerHandler("change"); // NG 1.7 + $timeout.flush(); + expect(onChangeSpy).toHaveBeenCalledWith("aValue"); + + $radioElement1.prop("checked", false); + $radioElement2.prop("checked", true); + $radioElement2.triggerHandler("click"); // NG 1.6 + $radioElement2.triggerHandler("change"); // NG 1.7 + $timeout.flush(); + expect(onChangeSpy).toHaveBeenCalledWith("bValue"); + }); }); }); + }); + + describe("Radio Group", () => { + const getRadioInputElement = (element) => angular.element(element[0].querySelector("input[type=radio]")); + const getElementByClass = (element, value) => angular.element(element[0].querySelector(value)); + const getRadioInputElementByValue = (element, value) => angular.element(element[0].querySelector(`input[type=radio][value=${value}]`)); + const getRadioGroupElement = (element) => angular.element(element[0]); + const clickRadio = (radioToCheck) => { + radioToCheck.prop("checked", true); + radioToCheck.triggerHandler("click"); // NG 1.6 + radioToCheck.triggerHandler("change"); // NG 1.7 + }; - describe("disabled attribute", () => { - it("should display an active radio when no attribute", () => { - const element = TestUtils.compileTemplate(""); + describe("attributes", () => { - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("disabled")).toBe(false); + it("should assign defined name to child radios when name attribute is defined", () => { + const name = "foo"; + + const element = TestUtils.compileTemplate(` + + + + `); + + expect(getRadioInputElement(element).prop("name")).toBe(name); }); - it("should display a disabled radio when defined but no value", () => { - const element = TestUtils.compileTemplate(""); + it("should assign a generated name to child radios when name attribute is undefined ", () => { + const element = TestUtils.compileTemplate(` + + + + `); - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("disabled")).toBe(true); + expect(getRadioInputElement(element).prop("name")).toMatch(/^oui-radio-group-\d+$/); }); - it("should display a disabled radio when true", () => { - const element = TestUtils.compileTemplate("", { - disabled: true - }); + it("should add radiogroup role", () => { + const element = TestUtils.compileTemplate(""); + $timeout.flush(); - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("disabled")).toBe(true); + expect(getRadioGroupElement(element).attr("role")).toEqual("radiogroup"); }); + }); - it("should display an active radio when false", () => { - const element = TestUtils.compileTemplate("", { - notDisabled: false - }); + describe("classes", () => { - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("disabled")).toBe(false); + it("should set radio classes", () => { + const element = TestUtils.compileTemplate(` + + + + `); + + expect(getElementByClass(element, ".oui-radio").length).toEqual(1); + expect(getElementByClass(element, ".oui-radio__input").length).toEqual(1); + expect(getElementByClass(element, ".oui-radio__label-container").length).toEqual(1); + expect(getElementByClass(element, ".oui-radio__label").length).toEqual(1); }); }); - describe("required attribute", () => { - it("should display an active radio when no attribute", () => { - const element = TestUtils.compileTemplate(""); + describe("on radio group model change", () => { + + it("should update child radio models at initialization", () => { + const defaultRadioValue = "bValue"; + const otherRadioValue = "aValue"; + const element = TestUtils.compileTemplate(` + + + + + `, { + defaultValue: defaultRadioValue + }); - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("required")).toBe(false); + expect(getRadioInputElementByValue(element, defaultRadioValue).prop("checked")).toEqual(true); + expect(getRadioInputElementByValue(element, otherRadioValue).prop("checked")).toEqual(false); }); - it("should display a required radio when defined but no value", () => { - const element = TestUtils.compileTemplate(""); + it("should update child radio models after initialization too", () => { + const defaultRadioValue = "bValue"; + const newRadioValue = "aValue"; + const element = TestUtils.compileTemplate(` + + + + + `, { + defaultValue: defaultRadioValue + }); - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("required")).toBe(true); + TestUtils.getElementController(element).defaultValue = newRadioValue; + $rootScope.$digest(); + + expect(getRadioInputElementByValue(element, newRadioValue).prop("checked")).toEqual(true); + expect(getRadioInputElementByValue(element, defaultRadioValue).prop("checked")).toEqual(false); }); + }); - it("should display a required radio when true", () => { - const element = TestUtils.compileTemplate("", { - required: true - }); + describe("on child radio click", () => { + + it("should update radio group model", () => { + const clickedRadioValue = "bValue"; + const element = TestUtils.compileTemplate(` + + + + + `); - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("required")).toBe(true); + clickRadio(getRadioInputElementByValue(element, clickedRadioValue)); + + expect(TestUtils.getElementController(element).model).toEqual(clickedRadioValue); }); - it("should display an active radio when false", () => { - const element = TestUtils.compileTemplate("", { - notRequired: false - }); + it("should trigger on change callback", () => { + const clickedRadioValue = "bValue"; + const onChangeSpy = jasmine.createSpy("onChangeSpy"); + const element = TestUtils.compileTemplate(` + + + + + `, { + onChange: onChangeSpy + }); - const radioElement = getRadioInputElement(element); - expect(angular.element(radioElement).prop("required")).toBe(false); + clickRadio(getRadioInputElementByValue(element, clickedRadioValue)); + $timeout.flush(); + expect(onChangeSpy).toHaveBeenCalledWith(clickedRadioValue); }); }); + }); + describe("Radio Toggle Group", () => { + const getRadioInputElement = (element) => angular.element(element[0].querySelector("input[type=radio]")); + const getElementByClass = (element, value) => angular.element(element[0].querySelector(value)); + const getRadioInputElementByValue = (element, value) => angular.element(element[0].querySelector(`input[type=radio][value=${value}]`)); + const getRadioGroupElement = (element) => angular.element(element[0]); + const clickRadio = (radioToCheck) => { + radioToCheck.prop("checked", true); + radioToCheck.triggerHandler("click"); // NG 1.6 + radioToCheck.triggerHandler("change"); // NG 1.7 + }; - describe("thumbnail attribute", () => { - it("should display a classic radio when no attribute", () => { - const element = TestUtils.compileTemplate(""); - expect(angular.element(element).hasClass("oui-radio_thumbnail")).toBe(false); + describe("attributes", () => { + + it("should assign defined name to child radios when name attribute is defined", () => { + const name = "foo"; + + const element = TestUtils.compileTemplate(` + + + + `); + + expect(getRadioInputElement(element).prop("name")).toBe(name); }); - it("should display a thumbnail radio when defined but no value", () => { - const element = TestUtils.compileTemplate(""); - expect(angular.element(element).hasClass("oui-radio_thumbnail")).toBe(true); + it("should assign a generated name to child radios when name attribute is undefined ", () => { + const element = TestUtils.compileTemplate(` + + + + `); + + expect(getRadioInputElement(element).prop("name")).toMatch(/^oui-radio-group-\d+$/); }); - it("should display a classic radio when false", () => { - const element = TestUtils.compileTemplate("", { - thumbnail: false - }); + it("should add radiogroup role", () => { + const element = TestUtils.compileTemplate(""); + $timeout.flush(); - expect(angular.element(element).hasClass("oui-radio_thumbnail")).toBe(false); + expect(getRadioGroupElement(element).attr("role")).toEqual("radiogroup"); }); + }); - it("should display a thumbnail radio when true", () => { - const element = TestUtils.compileTemplate("", { - thumbnail: true - }); + describe("classes", () => { - expect(angular.element(element).hasClass("oui-radio_thumbnail")).toBe(true); + it("should set toggle classes", () => { + const element = TestUtils.compileTemplate(` + + + + `); + + expect(getElementByClass(element, ".oui-radio-toggle").length).toEqual(1); + expect(getElementByClass(element, ".oui-radio-toggle__input").length).toEqual(1); + expect(getElementByClass(element, ".oui-radio-toggle__label-container").length).toEqual(1); + expect(getElementByClass(element, ".oui-radio-toggle__label").length).toEqual(1); }); }); - describe("default value", () => { - it("should select the default value on loading", () => { - const onChangeSpy = jasmine.createSpy("onChangeSpy"); + describe("on radio group model change", () => { + it("should update child radio models at initialization", () => { + const defaultRadioValue = "bValue"; + const otherRadioValue = "aValue"; const element = TestUtils.compileTemplate(` -
- - -
+ + + + `, { - onChange: onChangeSpy, - radioValue: "bValue" - }); + defaultValue: defaultRadioValue + }); - const radioComponent1 = element.children()[0]; - const radioComponent2 = element.children()[1]; - const $radioElement1 = angular.element(radioComponent1).find("input"); - const $radioElement2 = angular.element(radioComponent2).find("input"); + expect(getRadioInputElementByValue(element, defaultRadioValue).prop("checked")).toEqual(true); + expect(getRadioInputElementByValue(element, otherRadioValue).prop("checked")).toEqual(false); + }); - expect($radioElement1.prop("checked")).toEqual(false); - expect($radioElement2.prop("checked")).toEqual(true); + it("should update child radio models after initialization too", () => { + const defaultRadioValue = "bValue"; + const newRadioValue = "aValue"; + const element = TestUtils.compileTemplate(` + + + + + `, { + defaultValue: defaultRadioValue + }); + + TestUtils.getElementController(element).defaultValue = newRadioValue; + $rootScope.$digest(); + + expect(getRadioInputElementByValue(element, newRadioValue).prop("checked")).toEqual(true); + expect(getRadioInputElementByValue(element, defaultRadioValue).prop("checked")).toEqual(false); }); }); - describe("on-change attribute", () => { - it("should trigger callback when the radio is clicked", () => { - const onChangeSpy = jasmine.createSpy("onChangeSpy"); + describe("on child radio click", () => { + it("should update radio group model", () => { + const clickedRadioValue = "bValue"; const element = TestUtils.compileTemplate(` -
- - -
- `, { - onChange: onChangeSpy - }); + + + + + `); - const radioComponent1 = element.children()[0]; - const radioComponent2 = element.children()[1]; - const $radioElement1 = angular.element(radioComponent1).find("input"); - const $radioElement2 = angular.element(radioComponent2).find("input"); + clickRadio(getRadioInputElementByValue(element, clickedRadioValue)); - $radioElement1.prop("checked", true); - $radioElement1.triggerHandler("click"); // NG 1.6 - $radioElement1.triggerHandler("change"); // NG 1.7 - $timeout.flush(); - expect(onChangeSpy).toHaveBeenCalledWith("aValue"); + expect(TestUtils.getElementController(element).model).toEqual(clickedRadioValue); + }); + + it("should trigger on change callback", () => { + const clickedRadioValue = "bValue"; + const onChangeSpy = jasmine.createSpy("onChangeSpy"); + const element = TestUtils.compileTemplate(` + + + + + `, { + onChange: onChangeSpy + }); - $radioElement1.prop("checked", false); - $radioElement2.prop("checked", true); - $radioElement2.triggerHandler("click"); // NG 1.6 - $radioElement2.triggerHandler("change"); // NG 1.7 + clickRadio(getRadioInputElementByValue(element, clickedRadioValue)); $timeout.flush(); - expect(onChangeSpy).toHaveBeenCalledWith("bValue"); + expect(onChangeSpy).toHaveBeenCalledWith(clickedRadioValue); }); }); }); diff --git a/packages/oui-radio-toggle-group/src/radio-toggle-group.component.js b/packages/oui-radio/src/toggle-group/radio-toggle-group.component.js similarity index 72% rename from packages/oui-radio-toggle-group/src/radio-toggle-group.component.js rename to packages/oui-radio/src/toggle-group/radio-toggle-group.component.js index 68c6b9c7..ee9c6011 100644 --- a/packages/oui-radio-toggle-group/src/radio-toggle-group.component.js +++ b/packages/oui-radio/src/toggle-group/radio-toggle-group.component.js @@ -1,4 +1,4 @@ -import controller from "@oui-angular/oui-radio-group/src/radio-group.controller"; +import controller from "../group/radio-group.controller"; export default { template: "
", diff --git a/packages/oui-search/src/index.spec.js b/packages/oui-search/src/index.spec.js index ea10e7f3..1d54b4ff 100644 --- a/packages/oui-search/src/index.spec.js +++ b/packages/oui-search/src/index.spec.js @@ -22,11 +22,12 @@ describe("ouiSearch", () => { const buttons = component.find("button"); const reset = buttons.eq(0); const submit = buttons.eq(1); + const length = 2; expect(form.length).toBe(1); expect(input.length).toBe(1); expect(input.attr("type")).toBe("text"); - expect(buttons.length).toBe(2); + expect(buttons.length).toBe(length); expect(reset.attr("type")).toBe("reset"); expect(submit.attr("type")).toBe("submit"); }); @@ -185,6 +186,7 @@ describe("ouiSearch", () => { `, { onChangeSpy }); + const delay = 850; setTimeout(() => { const input = element.find("input"); @@ -192,7 +194,7 @@ describe("ouiSearch", () => { input.triggerHandler("input"); expect(onChangeSpy).not.toHaveBeenCalled(); done(); - }, 850); + }, delay); }); it("should delete preview criterion if search becomes too short", done => { diff --git a/packages/oui-select-picker/src/index.spec.js b/packages/oui-select-picker/src/index.spec.js index 12a11be5..46e54e5d 100644 --- a/packages/oui-select-picker/src/index.spec.js +++ b/packages/oui-select-picker/src/index.spec.js @@ -146,8 +146,8 @@ describe("ouiSelectPicker", () => { model="$ctrl.selectValue"> `, { - selectValue: "bValue" - }); + selectValue: "bValue" + }); const selectPickerComponent1 = element.children()[0]; const selectPickerComponent2 = element.children()[1]; @@ -175,8 +175,8 @@ describe("ouiSelectPicker", () => { on-change="$ctrl.onChange(modelValue)"> `, { - onChange: onChangeSpy - }); + onChange: onChangeSpy + }); const selectPickerComponent1 = element.children()[0]; const selectPickerComponent2 = element.children()[1]; @@ -212,8 +212,8 @@ describe("ouiSelectPicker", () => { on-change="$ctrl.onChange(modelValue)"> `, { - onChange: onChangeSpy - }); + onChange: onChangeSpy + }); const selectPickerComponent1 = element.children()[0]; const selectPickerComponent2 = element.children()[1]; diff --git a/packages/oui-select/src/index.spec.js b/packages/oui-select/src/index.spec.js index f10e119f..a92a84bd 100644 --- a/packages/oui-select/src/index.spec.js +++ b/packages/oui-select/src/index.spec.js @@ -42,8 +42,8 @@ describe("ouiSelect", () => { data-align="start"> `, { - countries: data - }); + countries: data + }); expect(angular.element(getContainer(element)).attr("title")).toEqual(title); expect(angular.element(getDropdownButton(element)).text()).toContain(placeholder); @@ -62,8 +62,8 @@ describe("ouiSelect", () => { data-align="start"> `, { - countries: data - }); + countries: data + }); const $container = angular.element(getContainer(element)); const $triggerButton = angular.element(getDropdownButton(element)); @@ -93,8 +93,8 @@ describe("ouiSelect", () => { `, { - countries: data - }); + countries: data + }); const $container = angular.element(getContainer(element)); const $triggerButton = angular.element(getDropdownButton(element)); @@ -120,8 +120,8 @@ describe("ouiSelect", () => { data-align="start"> `, { - countries: data - }); + countries: data + }); const $container = angular.element(getContainer(element)); const $triggerButton = angular.element(getDropdownButton(element)); @@ -132,7 +132,7 @@ describe("ouiSelect", () => { $triggerButton.triggerHandler("click"); // Select 5th element and check if it's highlighted. - let $itemButton = angular.element(getDropdownItem(element, 4)); + let $itemButton = angular.element(getDropdownItem(element, 4)); // eslint-disable-line no-magic-numbers expect($itemButton.hasClass(selectedItemClass)).toBeFalsy(); $itemButton.triggerHandler("click"); expect($itemButton.hasClass(selectedItemClass)).toBeTruthy(); @@ -142,7 +142,7 @@ describe("ouiSelect", () => { // Reopen dropdown and check if the selected element is highlighted. // The element is retrieved again to be sure to not test on a detached element. - $itemButton = angular.element(getDropdownItem(element, 4)); + $itemButton = angular.element(getDropdownItem(element, 4)); // eslint-disable-line no-magic-numbers expect($itemButton.hasClass(selectedItemClass)).toBeTruthy(); }); }); @@ -159,8 +159,8 @@ describe("ouiSelect", () => { data-align="start"> `, { - countries: data - }); + countries: data + }); expect(getDropdownItems(element).length).toEqual(data.length); expect(angular.element(getDropdownItem(element, 0)).text()).toContain(data[0].name); @@ -178,8 +178,8 @@ describe("ouiSelect", () => { data-align="start"> `, { - array: stringArray - }); + array: stringArray + }); expect(getDropdownItems(element).length).toEqual(stringArray.length); expect(angular.element(getDropdownItem(element, 0)).text()).toContain(stringArray[0]); @@ -202,9 +202,9 @@ describe("ouiSelect", () => { data-align="start"> `, { - countries: data, - groupByFirstLetter - }); + countries: data, + groupByFirstLetter + }); const groups = uniq(data.map(groupByFirstLetter)); const firstGroupElement = getItemsGroup(element, 0); @@ -230,8 +230,8 @@ describe("ouiSelect", () => { on-blur="$ctrl.onBlur()"> `, { - onBlur - }); + onBlur + }); angular.element(getDropdownButton(element)).triggerHandler("blur"); expect(onBlur).toHaveBeenCalled(); @@ -251,8 +251,8 @@ describe("ouiSelect", () => { on-focus="$ctrl.onFocus()"> `, { - onFocus - }); + onFocus + }); angular.element(getDropdownButton(element)).triggerHandler("focus"); expect(onFocus).toHaveBeenCalled(); @@ -272,19 +272,21 @@ describe("ouiSelect", () => { on-change="$ctrl.onChange(modelValue)"> `, { - countries: data, - onChange - }); + countries: data, + onChange + }); - let $itemButton = angular.element(getDropdownItem(element, 4)); + const index1 = 4; + const index2 = 10; + let $itemButton = angular.element(getDropdownItem(element, index1)); $itemButton.triggerHandler("click"); $timeout.flush(); - expect(onChange).toHaveBeenCalledWith(data[4]); + expect(onChange).toHaveBeenCalledWith(data[index1]); - $itemButton = angular.element(getDropdownItem(element, 10)); + $itemButton = angular.element(getDropdownItem(element, index2)); $itemButton.triggerHandler("click"); $timeout.flush(); - expect(onChange).toHaveBeenCalledWith(data[10]); + expect(onChange).toHaveBeenCalledWith(data[index2]); }); }); }); diff --git a/packages/oui-stepper/src/index.spec.js b/packages/oui-stepper/src/index.spec.js index 4cd8b78b..b3d70a69 100644 --- a/packages/oui-stepper/src/index.spec.js +++ b/packages/oui-stepper/src/index.spec.js @@ -114,9 +114,9 @@ describe("ouiStepper", () => { `, { - onInit, - onFinish - }); + onInit, + onFinish + }); $timeout.flush(); // Initial condition diff --git a/packages/oui-switch/src/index.spec.js b/packages/oui-switch/src/index.spec.js index 85917108..343e3d08 100644 --- a/packages/oui-switch/src/index.spec.js +++ b/packages/oui-switch/src/index.spec.js @@ -154,8 +154,8 @@ describe("ouiSwitch", () => { const element = TestUtils.compileTemplate(` `, { - isRequired: true - }); + isRequired: true + }); $timeout.flush(); const checkboxElement = getSwitchInputElement(element); @@ -166,8 +166,8 @@ describe("ouiSwitch", () => { const element = TestUtils.compileTemplate(` `, { - isRequired: false - }); + isRequired: false + }); $timeout.flush(); const checkboxElement = getSwitchInputElement(element); @@ -179,8 +179,8 @@ describe("ouiSwitch", () => { `, { - isRequired: true - }); + isRequired: true + }); $timeout.flush(); const form = element.scope().form; diff --git a/yarn.lock b/yarn.lock index 8cfcaee9..4f938ca3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -259,16 +259,20 @@ acorn-jsx@^3.0.0: acorn@^3.0.4: version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + resolved "http://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" acorn@^4.0.3: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" -acorn@^5.0.0, acorn@^5.5.0: +acorn@^5.0.0: version "5.7.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" +acorn@^5.5.0: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + acorn@~2.6.4: version "2.6.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.6.4.tgz#eb1f45b4a43fa31d03701a5ec46f3b52673e90ee" @@ -291,22 +295,15 @@ agent-base@4, agent-base@^4.1.0, agent-base@^4.2.0, agent-base@~4.2.0: dependencies: es6-promisify "^5.0.0" -ajv-keywords@^1.0.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" +ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" ajv-keywords@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" -ajv@^4.7.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" - dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" - -ajv@^5.0.0, ajv@^5.1.0: +ajv@^5.0.0, ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" dependencies: @@ -376,6 +373,10 @@ ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + ansi-html@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" @@ -620,7 +621,7 @@ babel-cli@^6.18.0: optionalDependencies: chokidar "^1.6.1" -babel-code-frame@^6.16.0, babel-code-frame@^6.26.0: +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: @@ -1920,7 +1921,7 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@1.6.2, concat-stream@^1.4.7, concat-stream@^1.5.2: +concat-stream@1.6.2, concat-stream@^1.4.7, concat-stream@^1.6.0: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" dependencies: @@ -2174,7 +2175,7 @@ cross-env@^5.1.0: cross-spawn "^6.0.5" is-windows "^1.0.0" -cross-spawn@^5.0.1: +cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" dependencies: @@ -2384,7 +2385,7 @@ dateformat@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" -debug@2, debug@2.6.9, debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9, debug@~2.6.4, debug@~2.6.6: +debug@2, debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9, debug@~2.6.4, debug@~2.6.6: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: @@ -2532,7 +2533,7 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" -doctrine@^2.0.0: +doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" dependencies: @@ -2874,51 +2875,61 @@ eslint-scope@3.7.1: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^3.7.1: + version "3.7.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" -eslint@^3.13.1: - version "3.19.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" +eslint@^4.3.0: + version "4.19.1" + resolved "http://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" dependencies: - babel-code-frame "^6.16.0" - chalk "^1.1.3" - concat-stream "^1.5.2" - debug "^2.1.1" - doctrine "^2.0.0" - escope "^3.6.0" - espree "^3.4.0" + ajv "^5.3.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^3.1.0" + doctrine "^2.1.0" + eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" + espree "^3.5.4" esquery "^1.0.0" - estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" - glob "^7.0.3" - globals "^9.14.0" - ignore "^3.2.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.0.1" + ignore "^3.3.3" imurmurhash "^0.1.4" - inquirer "^0.12.0" - is-my-json-valid "^2.10.0" + inquirer "^3.0.6" is-resolvable "^1.0.0" - js-yaml "^3.5.1" - json-stable-stringify "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.0.0" - mkdirp "^0.5.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" - path-is-inside "^1.0.1" - pluralize "^1.2.1" - progress "^1.1.8" - require-uncached "^1.0.2" - shelljs "^0.7.5" - strip-bom "^3.0.0" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^1.0.1" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" strip-json-comments "~2.0.1" - table "^3.7.8" + table "4.0.2" text-table "~0.2.0" - user-home "^2.0.0" -espree@^3.4.0: +espree@^3.5.4: version "3.5.4" resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" dependencies: @@ -3118,9 +3129,9 @@ external-editor@^1.1.0: spawn-sync "^1.0.15" tmp "^0.0.29" -external-editor@^2.0.1: +external-editor@^2.0.1, external-editor@^2.0.4: version "2.2.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + resolved "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" dependencies: chardet "^0.4.0" iconv-lite "^0.4.17" @@ -3435,6 +3446,10 @@ function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -3609,11 +3624,11 @@ global-prefix@^0.1.4: is-windows "^0.2.0" which "^1.2.12" -globals@^11.1.0: +globals@^11.0.1, globals@^11.1.0: version "11.7.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673" -globals@^9.14.0, globals@^9.18.0: +globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -3970,7 +3985,7 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" -ignore@^3.2.0: +ignore@^3.3.3: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" @@ -4076,22 +4091,23 @@ inquirer@3.0.6: strip-ansi "^3.0.0" through "^2.3.6" -inquirer@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" +inquirer@^3.0.6: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" dependencies: - ansi-escapes "^1.1.0" - ansi-regex "^2.0.0" - chalk "^1.0.0" - cli-cursor "^1.0.1" + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" cli-width "^2.0.0" - figures "^1.3.5" + external-editor "^2.0.4" + figures "^2.0.0" lodash "^4.3.0" - readline2 "^1.0.1" - run-async "^0.1.0" - rx-lite "^3.1.2" - string-width "^1.0.1" - strip-ansi "^3.0.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" through "^2.3.6" interpret@^1.0.0: @@ -4256,7 +4272,7 @@ is-my-ip-valid@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824" -is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: +is-my-json-valid@^2.12.4: version "2.17.2" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz#6b2103a288e94ef3de5cf15d29dd85fc4b78d65c" dependencies: @@ -4478,7 +4494,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" -js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.5.1, js-yaml@^3.9.0: +js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.9.0, js-yaml@^3.9.1: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" dependencies: @@ -4528,11 +4544,9 @@ json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" -json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: +json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - dependencies: - jsonify "~0.0.0" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" json-stringify-safe@5.0.x, json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" @@ -4554,10 +4568,6 @@ jsonfile@^2.1.0: optionalDependencies: graceful-fs "^4.1.6" -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - jsonparse@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" @@ -5273,10 +5283,6 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -mute-stream@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" - mute-stream@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db" @@ -5920,7 +5926,7 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" @@ -6024,9 +6030,9 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" -pluralize@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" popper.js@^1.14.3: version "1.14.4" @@ -6343,6 +6349,10 @@ progress@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" +progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -6607,14 +6617,6 @@ readdirp@^2.0.0: readable-stream "^2.0.2" set-immediate-shim "^1.0.1" -readline2@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - mute-stream "0.0.5" - recast@~0.11.12: version "0.11.23" resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3" @@ -6707,6 +6709,10 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexpp@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + regexpu-core@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" @@ -6851,7 +6857,7 @@ require-package-name@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9" -require-uncached@^1.0.2, require-uncached@^1.0.3: +require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" dependencies: @@ -6942,21 +6948,21 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -run-async@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" - dependencies: - once "^1.3.0" - run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" dependencies: is-promise "^2.1.0" -rx-lite@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" rx@^4.1.0: version "4.1.0" @@ -7095,14 +7101,6 @@ shelljs@0.7.6: interpret "^1.0.0" rechoir "^0.6.2" -shelljs@^0.7.5: - version "0.7.8" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -7125,9 +7123,11 @@ slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" -slice-ansi@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + dependencies: + is-fullwidth-code-point "^2.0.0" smart-buffer@^1.0.13, smart-buffer@^1.0.4: version "1.1.15" @@ -7434,7 +7434,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: @@ -7544,16 +7544,16 @@ svgo@^0.7.0: sax "~1.2.1" whet.extend "~0.9.9" -table@^3.7.8: - version "3.8.3" - resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" +table@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" dependencies: - ajv "^4.7.0" - ajv-keywords "^1.0.0" - chalk "^1.1.1" - lodash "^4.0.0" - slice-ansi "0.0.4" - string-width "^2.0.0" + ajv "^5.2.3" + ajv-keywords "^2.1.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" tapable@^0.2.7: version "0.2.8" @@ -7860,12 +7860,6 @@ user-home@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" -user-home@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" - dependencies: - os-homedir "^1.0.0" - useragent@2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.2.1.tgz#cf593ef4f2d175875e8bb658ea92e18a4fd06d8e"