@@ -6,23 +6,15 @@ import {
66 nextFrame ,
77} from '@open-wc/testing' ;
88import { defineComponents } from '../common/definitions/defineComponents.js' ;
9+ import { first } from '../common/util.js' ;
910import IgcLinearProgressComponent from './linear-progress.js' ;
1011
11- function createNonAnimatingProgress ( ) {
12- return html `< igc-linear-progress
13- animation-duration ="0 "
14- > </ igc-linear-progress > ` ;
15- }
16-
1712describe ( 'Linear progress component' , ( ) => {
1813 let progress : IgcLinearProgressComponent ;
1914
20- const queryShadowRoot = ( qs : string ) =>
21- progress . shadowRoot ! . querySelector ( qs ) ;
22-
23- const getFillPart = ( ) => queryShadowRoot ( `[part~='fill']` ) ;
24-
25- const updateProgress = async < T extends keyof IgcLinearProgressComponent > (
15+ const updateProgress = async <
16+ T extends keyof Omit < IgcLinearProgressComponent , keyof HTMLElement > ,
17+ > (
2618 prop : T ,
2719 value : IgcLinearProgressComponent [ T ]
2820 ) => {
@@ -31,21 +23,66 @@ describe('Linear progress component', () => {
3123 await nextFrame ( ) ;
3224 } ;
3325
34- before ( ( ) => defineComponents ( IgcLinearProgressComponent ) ) ;
26+ before ( ( ) => {
27+ defineComponents ( IgcLinearProgressComponent ) ;
28+ } ) ;
29+
30+ describe ( 'DOM' , ( ) => {
31+ beforeEach ( async ( ) => {
32+ progress = await fixture < IgcLinearProgressComponent > ( html `
33+ < igc-linear-progress > </ igc-linear-progress >
34+ ` ) ;
35+ } ) ;
36+
37+ it ( 'is accessible' , async ( ) => {
38+ await expect ( progress ) . to . be . accessible ( ) ;
39+ await expect ( progress ) . shadowDom . to . be . accessible ( ) ;
40+ } ) ;
41+
42+ it ( 'has correct initial property values' , ( ) => {
43+ const defaultProps : Partial <
44+ Record < keyof IgcLinearProgressComponent , any >
45+ > = {
46+ max : 100 ,
47+ value : 0 ,
48+ animationDuration : 500 ,
49+ striped : false ,
50+ indeterminate : false ,
51+ hideLabel : false ,
52+ variant : 'primary' ,
53+ labelFormat : undefined ,
54+ labelAlign : 'top-start' ,
55+ } ;
56+
57+ for ( const [ prop , value ] of Object . entries ( defaultProps ) ) {
58+ expect ( progress [ prop as keyof IgcLinearProgressComponent ] ) . to . equal (
59+ value
60+ ) ;
61+ }
62+ } ) ;
63+ } ) ;
3564
3665 describe ( 'Attributes and Properties' , ( ) => {
3766 beforeEach ( async ( ) => {
38- progress = await fixture < IgcLinearProgressComponent > (
39- createNonAnimatingProgress ( )
40- ) ;
67+ progress = await fixture < IgcLinearProgressComponent > ( html `
68+ < igc-linear-progress animation-duration ="0 "> </ igc-linear-progress >
69+ ` ) ;
70+ } ) ;
71+
72+ it ( 'toggles the default label based on `hideLabel`' , async ( ) => {
73+ await updateProgress ( 'hideLabel' , true ) ;
74+ expect ( getDOM ( progress ) . label ) . to . be . null ;
75+
76+ await updateProgress ( 'hideLabel' , false ) ;
77+ expect ( getDOM ( progress ) . label ) . to . exist ;
4178 } ) ;
4279
4380 it ( 'reflects the striped attribute' , async ( ) => {
4481 await updateProgress ( 'striped' , true ) ;
45- expect ( queryShadowRoot ( `[part~=' striped']` ) ) . not . to . be . null ;
82+ expect ( getDOM ( progress ) . striped ) . to . exist ;
4683
4784 await updateProgress ( 'striped' , false ) ;
48- expect ( queryShadowRoot ( `[part~='striped']` ) ) . to . be . null ;
85+ expect ( getDOM ( progress ) . striped ) . to . be . null ;
4986 } ) ;
5087
5188 it ( 'reflects the variant attribute' , async ( ) => {
@@ -81,18 +118,169 @@ describe('Linear progress component', () => {
81118
82119 it ( 'reflects the progress fill based on value' , async ( ) => {
83120 await updateProgress ( 'value' , 50 ) ;
84- const fill = getFillPart ( ) ;
85- expect ( fill ) . not . to . be . null ;
121+ expect ( getDOM ( progress ) . fill ) . to . exist ;
122+ } ) ;
123+
124+ it ( 'value is correctly reflected' , async ( ) => {
125+ await updateProgress ( 'value' , 50 ) ;
126+ expect ( getDOM ( progress ) . integerLabel ) . to . equal ( '50' ) ;
127+ } ) ;
128+
129+ it ( 'fractional values are correctly reflected' , async ( ) => {
130+ await updateProgress ( 'value' , 3.14 ) ;
131+
132+ expect ( getDOM ( progress ) . integerLabel ) . to . equal ( '3' ) ;
133+ expect ( getDOM ( progress ) . fractionLabel ) . to . equal ( '14' ) ;
134+ } ) ;
135+
136+ it ( 'clamps negative values' , async ( ) => {
137+ await updateProgress ( 'value' , - 100 ) ;
138+
139+ expect ( progress . value ) . to . equal ( 0 ) ;
140+ expect ( getDOM ( progress ) . integerLabel ) . to . equal ( '0' ) ;
141+ } ) ;
142+
143+ it ( 'clamps value larger than max' , async ( ) => {
144+ await updateProgress ( 'value' , 200 ) ;
145+
146+ expect ( progress . value ) . to . equal ( 100 ) ;
147+ expect ( getDOM ( progress ) . integerLabel ) . to . equal ( '100' ) ;
148+ } ) ;
149+
150+ it ( 'clamps value to new max when new max is less than current value' , async ( ) => {
151+ await updateProgress ( 'value' , 50 ) ;
152+ await updateProgress ( 'max' , 25 ) ;
153+
154+ expect ( progress . value ) . to . equal ( 25 ) ;
155+ expect ( getDOM ( progress ) . integerLabel ) . to . equal ( '100' ) ;
156+ } ) ;
157+
158+ it ( 'does not change value when max is changed and new max is greater than value' , async ( ) => {
159+ await updateProgress ( 'value' , 100 ) ;
160+ await updateProgress ( 'max' , 200 ) ;
161+
162+ expect ( progress . value ) . to . equal ( 100 ) ;
163+ expect ( getDOM ( progress ) . integerLabel ) . to . equal ( '50' ) ;
164+ } ) ;
165+
166+ it ( 'correctly reflects indeterminate attribute' , async ( ) => {
167+ await updateProgress ( 'indeterminate' , true ) ;
168+ expect ( getDOM ( progress ) . indeterminate ) . to . exist ;
169+
170+ await updateProgress ( 'indeterminate' , false ) ;
171+ expect ( getDOM ( progress ) . indeterminate ) . to . be . null ;
172+ } ) ;
173+
174+ it ( 'hides the default label when in indeterminate mode' , async ( ) => {
175+ await updateProgress ( 'indeterminate' , true ) ;
176+ expect ( getDOM ( progress ) . label ) . to . be . null ;
177+
178+ await updateProgress ( 'indeterminate' , false ) ;
179+ expect ( getDOM ( progress ) . label ) . to . exist ;
180+ } ) ;
181+
182+ it ( 'reflects updates to value in indeterminate mode and then switching to determinate' , async ( ) => {
183+ await updateProgress ( 'indeterminate' , true ) ;
184+ await updateProgress ( 'value' , 50 ) ;
185+ await updateProgress ( 'indeterminate' , false ) ;
186+
187+ expect ( progress . value ) . to . equal ( 50 ) ;
188+ expect ( getDOM ( progress ) . integerLabel ) . to . equal ( '50' ) ;
189+ } ) ;
190+
191+ it ( 'applies custom label format' , async ( ) => {
192+ expect ( getDOM ( progress ) . label . textContent ) . to . be . empty ;
193+
194+ await updateProgress ( 'labelFormat' , 'Task {0} of {1} completed' ) ;
195+ await updateProgress ( 'value' , 8 ) ;
196+ await updateProgress ( 'max' , 10 ) ;
197+
198+ expect ( getDOM ( progress ) . customLabel . textContent ) . to . equal (
199+ 'Task 8 of 10 completed'
200+ ) ;
86201 } ) ;
87202 } ) ;
88203
89204 describe ( 'Rendering' , ( ) => {
90- it ( 'renders default slot content' , async ( ) => {
205+ beforeEach ( async ( ) => {
91206 progress = await fixture < IgcLinearProgressComponent > (
92207 html `< igc-linear-progress > Custom Label</ igc-linear-progress > `
93208 ) ;
94- const slot = progress . shadowRoot ! . querySelector ( 'slot' ) ;
209+ } ) ;
210+
211+ it ( 'renders default slot content' , async ( ) => {
212+ const slot = getDOM ( progress ) . slot ;
213+
95214 expect ( slot ) . to . exist ;
215+ expect ( first ( slot . assignedNodes ( ) ) . textContent ) . to . equal ( 'Custom Label' ) ;
216+ } ) ;
217+
218+ it ( '`hideLabel` does not affect slotted label' , async ( ) => {
219+ await updateProgress ( 'hideLabel' , true ) ;
220+ expect ( first ( getDOM ( progress ) . slot . assignedNodes ( ) ) . textContent ) . to . equal (
221+ 'Custom Label'
222+ ) ;
223+ } ) ;
224+
225+ it ( 'indeterminate does not affect slotted label' , async ( ) => {
226+ await updateProgress ( 'indeterminate' , true ) ;
227+ expect ( first ( getDOM ( progress ) . slot . assignedNodes ( ) ) . textContent ) . to . equal (
228+ 'Custom Label'
229+ ) ;
230+ } ) ;
231+ } ) ;
232+
233+ describe ( 'Issues' , ( ) => {
234+ it ( '#1083 - setting value on initialization should not reset it' , async ( ) => {
235+ progress = document . createElement ( IgcLinearProgressComponent . tagName ) ;
236+ progress . value = 88 ;
237+
238+ document . body . append ( progress ) ;
239+ await elementUpdated ( progress ) ;
240+
241+ expect ( progress . value ) . to . equal ( 88 ) ;
242+ progress . remove ( ) ;
96243 } ) ;
97244 } ) ;
98245} ) ;
246+
247+ function getDOM ( progress : IgcLinearProgressComponent ) {
248+ return {
249+ get slot ( ) {
250+ return progress . renderRoot . querySelector ( 'slot' ) ! ;
251+ } ,
252+ get indeterminate ( ) {
253+ return progress . renderRoot . querySelector < HTMLElement > (
254+ '[part~="indeterminate"]'
255+ ) ! ;
256+ } ,
257+ get fill ( ) {
258+ return progress . renderRoot . querySelector < HTMLElement > ( '[part~="fill"]' ) ! ;
259+ } ,
260+ get striped ( ) {
261+ return progress . renderRoot . querySelector < HTMLElement > (
262+ '[part~="striped"]'
263+ ) ! ;
264+ } ,
265+ get customLabel ( ) {
266+ return progress . renderRoot . querySelector < HTMLElement > (
267+ '[part="label value"]'
268+ ) ! ;
269+ } ,
270+ get label ( ) {
271+ return progress . renderRoot . querySelector < HTMLElement > (
272+ '[part="label value counter"]'
273+ ) ! ;
274+ } ,
275+ get integerLabel ( ) {
276+ return getComputedStyle (
277+ progress . renderRoot . querySelector ( '[part~="counter"]' ) !
278+ ) . getPropertyValue ( '--_progress-integer' ) ;
279+ } ,
280+ get fractionLabel ( ) {
281+ return getComputedStyle (
282+ progress . renderRoot . querySelector ( '[part~="fraction"]' ) !
283+ ) . getPropertyValue ( '--_progress-fraction' ) ;
284+ } ,
285+ } ;
286+ }
0 commit comments