Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Commit 631def8

Browse files
author
george
committed
Merge branch 'js/utils-tests' into develop
2 parents 6f5a585 + 62dc35f commit 631def8

File tree

7 files changed

+295
-74
lines changed

7 files changed

+295
-74
lines changed

app/pages/Home/__tests__/markdownContent.spec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ describe("<StatusBadges />", () => {
1515
expect(wrapper).toMatchSnapshot()
1616
})
1717
})
18+
1819
describe("<InstallNpm />", () => {
1920
it("renders", () => {
2021
const wrapper = mount(<InstallNpm />)

src/js/__tests__/utils.spec.js

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
import ContextUtil, { dom, getFocusableElements } from "../utils"
2+
3+
const testDom = `<div data-tester="true" data-removable class="wrapper">
4+
<p>Hello world! <a href="#">this link is focusable</a> </p>
5+
<p style="height: 32px;" class="hello world test">Hello world again! <button type="button">I too, am focusable!</button></p>
6+
</div>\
7+
`
8+
9+
describe("dom", () => {
10+
describe(".addClass(element, ...classes)", () => {
11+
it("can add a class", () => {
12+
// Given
13+
document.body.innerHTML = testDom
14+
const element = document.querySelector(".hello.world")
15+
const newClass = "test-class"
16+
// When
17+
dom.addClass(element, newClass)
18+
// Then
19+
const received = Object.values(element.classList)
20+
expect(received).toContainEqual(newClass)
21+
})
22+
23+
it("can add multiple classes", () => {
24+
// Given
25+
document.body.innerHTML = testDom
26+
const element = document.querySelector(".hello.world")
27+
const newClass1 = "test-class-1"
28+
const newClass2 = "test-class-2"
29+
// When
30+
dom.addClass(element, newClass1, newClass2)
31+
// Then
32+
const received = Object.values(element.classList)
33+
expect(received).toEqual(expect.arrayContaining([newClass1, newClass2]))
34+
})
35+
})
36+
37+
describe(".removeClass(element, ...classes)", () => {
38+
it("can remove a class from an element", () => {
39+
// Given
40+
document.body.innerHTML = testDom
41+
const element = document.querySelector(".hello.world")
42+
const removedClass = "test"
43+
// When
44+
dom.removeClass(element, removedClass)
45+
// Then
46+
const received = Object.values(element.classList)
47+
expect(received).not.toContainEqual(removedClass)
48+
})
49+
50+
it("can remove multiple classes from an element", () => {
51+
// Given
52+
document.body.innerHTML = testDom
53+
const element = document.querySelector(".hello.world")
54+
const newClass1 = "hello"
55+
const newClass2 = "world"
56+
// When
57+
dom.removeClass(element, newClass1, newClass2)
58+
// Then
59+
const received = Object.values(element.classList)
60+
expect(received).not.toEqual(expect.arrayContaining([newClass1, newClass2]))
61+
})
62+
})
63+
64+
describe(".hasClass(element, ...classes)", () => {
65+
it("returns false if class can't be found", () => {
66+
// Given
67+
document.body.innerHTML = testDom
68+
const element = document.querySelector(".hello.world")
69+
const classNameToDetect = "test-class"
70+
// When
71+
const received = dom.hasClass(element, classNameToDetect)
72+
// Then
73+
expect(received).toEqual(false)
74+
})
75+
76+
it("returns true if class can be found", () => {
77+
// Given
78+
document.body.innerHTML = testDom
79+
const element = document.querySelector(".hello.world")
80+
const classNameToDetect = "hello"
81+
// When
82+
const received = dom.hasClass(element, classNameToDetect)
83+
// Then
84+
expect(received).toEqual(true)
85+
})
86+
87+
it("returns false if class can't be found among given classes", () => {
88+
// Given
89+
document.body.innerHTML = testDom
90+
const element = document.querySelector(".hello.world")
91+
const classNameToDetect1 = "hello"
92+
const classNameToDetect2 = "not-in-class-list"
93+
// When
94+
const received = dom.hasClass(element, classNameToDetect1, classNameToDetect2)
95+
// Then
96+
expect(received).toEqual(true)
97+
})
98+
99+
it("returns true if class can be found among given classes", () => {
100+
// Given
101+
document.body.innerHTML = testDom
102+
const element = document.querySelector(".hello.world")
103+
const classNameToDetect1 = "hello"
104+
const classNameToDetect2 = "not-in-class-list"
105+
// When
106+
const received = dom.hasClass(element, classNameToDetect1, classNameToDetect2)
107+
// Then
108+
expect(received).toEqual(true)
109+
})
110+
})
111+
112+
describe(".getAttr(element, attr)", () => {
113+
it("returns an attribute", () => {
114+
// Given
115+
document.body.innerHTML = testDom
116+
const wrapper = document.querySelector(".wrapper")
117+
// When
118+
const received = dom.getAttr(wrapper, "data-tester")
119+
// Then
120+
expect(received).toEqual("true")
121+
})
122+
})
123+
124+
describe(".setAttr(element, attr, value)", () => {
125+
it("can set an attribute", () => {
126+
// Given
127+
document.body.innerHTML = testDom
128+
const wrapper = document.querySelector(".wrapper")
129+
// When
130+
dom.setAttr(wrapper, "data-tester", "false")
131+
// Then
132+
const received = wrapper.dataset.tester
133+
expect(received).toEqual("false")
134+
})
135+
})
136+
137+
describe(".removeAttr(element, attr)", () => {
138+
it("can remove an attribute", () => {
139+
// Given
140+
document.body.innerHTML = testDom
141+
const wrapper = document.querySelector(".wrapper")
142+
// When
143+
dom.removeAttr(wrapper, "data-tester")
144+
// Then
145+
const received = wrapper.dataset.tester
146+
expect(received).toEqual(undefined)
147+
})
148+
})
149+
150+
describe(".hasAttr(element, attr)", () => {
151+
it("can detect an attribute", () => {
152+
// Given
153+
document.body.innerHTML = testDom
154+
const wrapper = document.querySelector(".wrapper")
155+
// When
156+
const received = dom.hasAttr(wrapper, "data-tester")
157+
// Then
158+
expect(received).toEqual(true)
159+
})
160+
})
161+
162+
describe(".find(element, parent = document)", () => {
163+
it("returns an element", () => {
164+
// Given
165+
document.body.innerHTML = testDom
166+
const element = document.querySelector(".hello.world")
167+
const received = dom.find(".hello.world")
168+
// Then
169+
expect(received).toEqual(element)
170+
})
171+
})
172+
173+
describe(".findAll(element, parent = document)", () => {
174+
it("returns a collection of elements", () => {
175+
// Given
176+
document.body.innerHTML = testDom
177+
const received = dom.findAll("p")
178+
// Then
179+
expect(received).toHaveLength(2)
180+
})
181+
})
182+
183+
describe(".css(element, property, value = undefined)", () => {
184+
it("returns css property value", () => {
185+
// Given
186+
document.body.innerHTML = testDom
187+
const element = document.querySelector(".hello.world")
188+
// When
189+
const received = dom.css(element, "height")
190+
// Then
191+
expect(received).toEqual("32px")
192+
})
193+
194+
it("can set css property as a string", () => {
195+
// Given
196+
document.body.innerHTML = testDom
197+
const element = document.querySelector(".hello.world")
198+
const newHeight = "60px"
199+
// When
200+
dom.css(element, "height", newHeight)
201+
// Then
202+
const received = element.style.height
203+
expect(received).toEqual(newHeight)
204+
})
205+
206+
it("can set css property as null", () => {
207+
// Given
208+
document.body.innerHTML = testDom
209+
const element = document.querySelector(".hello.world")
210+
const newHeight = null
211+
// When
212+
dom.css(element, "height", newHeight)
213+
// Then
214+
expect(element.style.height).toEqual("")
215+
})
216+
})
217+
})
218+
219+
describe("getFocusableElements(container)", () => {
220+
it("returns all focusable elements within a given element", () => {
221+
document.body.innerHTML = testDom
222+
const elements = getFocusableElements(".wrapper")
223+
expect(elements).toHaveLength(2)
224+
})
225+
})
226+
227+
describe("ContextUtil", () => {})

src/js/accordion.js

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ export default class Accordion {
8888
// private
8989

9090
_setup(instance) {
91-
const buttonTargetId = dom.attr(instance, Selectors.DATA_TARGET)
92-
const accordionId = dom.attr(instance, Selectors.DATA_PARENT)
91+
const buttonTargetId = dom.getAttr(instance, Selectors.DATA_TARGET)
92+
const accordionId = dom.getAttr(instance, Selectors.DATA_PARENT)
9393
const buttonContent = dom.find(`#${buttonTargetId}`)
9494

9595
if (!accordionId) {
@@ -115,29 +115,29 @@ export default class Accordion {
115115

116116
const buttonContentChildren = getFocusableElements(`#${buttonContent.id}`)
117117

118-
dom.attr(instance, Selectors.ARIA_CONTROLS, buttonTargetId)
119-
dom.attr(buttonContent, Selectors.ARIA_LABELLEDBY, buttonId)
118+
dom.setAttr(instance, Selectors.ARIA_CONTROLS, buttonTargetId)
119+
dom.setAttr(buttonContent, Selectors.ARIA_LABELLEDBY, buttonId)
120120

121-
const contentShouldExpand = dom.attr(accordionRow, Selectors.DATA_VISIBLE)
121+
const contentShouldExpand = dom.getAttr(accordionRow, Selectors.DATA_VISIBLE)
122122

123123
if (!contentShouldExpand) {
124124
throw new Error(Messages.NO_VISIBLE_ERROR(buttonTargetId))
125125
}
126126

127127
if (contentShouldExpand === "true") {
128128
dom.css(buttonContent, "maxHeight", `${buttonContent.scrollHeight}px`)
129-
dom.attr(instance, Selectors.ARIA_EXPANDED, "true")
130-
dom.attr(buttonContent, Selectors.ARIA_HIDDEN, "false")
129+
dom.setAttr(instance, Selectors.ARIA_EXPANDED, "true")
130+
dom.setAttr(buttonContent, Selectors.ARIA_HIDDEN, "false")
131131

132132
buttonContentChildren.forEach(element => {
133-
dom.attr(element, Selectors.TABINDEX, "0")
133+
dom.setAttr(element, Selectors.TABINDEX, "0")
134134
})
135135
} else {
136-
dom.attr(instance, Selectors.ARIA_EXPANDED, "false")
137-
dom.attr(buttonContent, Selectors.ARIA_HIDDEN, "true")
136+
dom.setAttr(instance, Selectors.ARIA_EXPANDED, "false")
137+
dom.setAttr(buttonContent, Selectors.ARIA_HIDDEN, "true")
138138

139139
buttonContentChildren.forEach(element => {
140-
dom.attr(element, Selectors.TABINDEX, "-1")
140+
dom.setAttr(element, Selectors.TABINDEX, "-1")
141141
})
142142
}
143143
}
@@ -170,14 +170,14 @@ export default class Accordion {
170170
}
171171

172172
_setVisibleState() {
173-
const accordionButtonState = dom.attr(this._activeRow, Selectors.DATA_VISIBLE)
173+
const accordionButtonState = dom.getAttr(this._activeRow, Selectors.DATA_VISIBLE)
174174
this._nextButtonExpandState = accordionButtonState === "true" ? "false" : "true"
175175
this._nextContentHiddenState = this._nextButtonExpandState === "false" ? "true" : "false"
176176
}
177177

178178
_setIds() {
179-
this._activeContainerId = dom.attr(this._activeButton, Selectors.DATA_PARENT)
180-
this._activeAccordionRowId = dom.attr(this._activeButton, Selectors.DATA_TARGET)
179+
this._activeContainerId = dom.getAttr(this._activeButton, Selectors.DATA_PARENT)
180+
this._activeAccordionRowId = dom.getAttr(this._activeButton, Selectors.DATA_TARGET)
181181
}
182182

183183
_setActiveContainer() {
@@ -223,13 +223,13 @@ export default class Accordion {
223223
}
224224

225225
_toggleSelectedAccordion() {
226-
dom.attr(this._activeRow, Selectors.DATA_VISIBLE, this._nextButtonExpandState)
227-
dom.attr(this._activeButton, Selectors.ARIA_EXPANDED, this._nextButtonExpandState)
228-
dom.attr(this._activeContent, Selectors.ARIA_HIDDEN, this._nextContentHiddenState)
226+
dom.setAttr(this._activeRow, Selectors.DATA_VISIBLE, this._nextButtonExpandState)
227+
dom.setAttr(this._activeButton, Selectors.ARIA_EXPANDED, this._nextButtonExpandState)
228+
dom.setAttr(this._activeContent, Selectors.ARIA_HIDDEN, this._nextContentHiddenState)
229229

230230
getFocusableElements(`#${this._activeAccordionRowId}`).forEach(element => {
231231
const value = this._nextButtonExpandState === "true" ? "0" : "-1"
232-
dom.attr(element, Selectors.TABINDEX, value)
232+
dom.setAttr(element, Selectors.TABINDEX, value)
233233
})
234234

235235
if (dom.css(this._activeContent, "maxHeight")) {
@@ -239,7 +239,7 @@ export default class Accordion {
239239
}
240240
}
241241

242-
_toggleAttributeInCollection(elements, attributeName, newValue) {
243-
elements.forEach(element => dom.attr(element, attributeName, newValue))
242+
_toggleAttributeInCollection(elements, attributeName, value) {
243+
elements.forEach(element => dom.setAttr(element, attributeName, value))
244244
}
245245
}

0 commit comments

Comments
 (0)