igniteui-angular 22.2.0-rc.0 → 22.2.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/button-group/README.md +42 -9
- package/calendar/README.md +30 -20
- package/card/README.md +1 -1
- package/fesm2022/igniteui-angular-accordion.mjs +7 -7
- package/fesm2022/igniteui-angular-action-strip.mjs +11 -22
- package/fesm2022/igniteui-angular-action-strip.mjs.map +1 -1
- package/fesm2022/igniteui-angular-avatar.mjs +7 -7
- package/fesm2022/igniteui-angular-badge.mjs +7 -7
- package/fesm2022/igniteui-angular-banner.mjs +10 -10
- package/fesm2022/igniteui-angular-bottom-nav.mjs +22 -22
- package/fesm2022/igniteui-angular-button-group.mjs +32 -35
- package/fesm2022/igniteui-angular-button-group.mjs.map +1 -1
- package/fesm2022/igniteui-angular-calendar.mjs +132 -180
- package/fesm2022/igniteui-angular-calendar.mjs.map +1 -1
- package/fesm2022/igniteui-angular-card.mjs +47 -58
- package/fesm2022/igniteui-angular-card.mjs.map +1 -1
- package/fesm2022/igniteui-angular-carousel.mjs +22 -22
- package/fesm2022/igniteui-angular-chat-extras.mjs +6 -6
- package/fesm2022/igniteui-angular-chat.mjs +12 -12
- package/fesm2022/igniteui-angular-checkbox.mjs +7 -7
- package/fesm2022/igniteui-angular-chips.mjs +10 -10
- package/fesm2022/igniteui-angular-combo.mjs +69 -67
- package/fesm2022/igniteui-angular-combo.mjs.map +1 -1
- package/fesm2022/igniteui-angular-core.mjs +139 -92
- package/fesm2022/igniteui-angular-core.mjs.map +1 -1
- package/fesm2022/igniteui-angular-date-picker.mjs +53 -70
- package/fesm2022/igniteui-angular-date-picker.mjs.map +1 -1
- package/fesm2022/igniteui-angular-dialog.mjs +13 -13
- package/fesm2022/igniteui-angular-directives.mjs +194 -194
- package/fesm2022/igniteui-angular-drop-down.mjs +29 -29
- package/fesm2022/igniteui-angular-expansion-panel.mjs +28 -28
- package/fesm2022/igniteui-angular-grids-core.mjs +737 -661
- package/fesm2022/igniteui-angular-grids-core.mjs.map +1 -1
- package/fesm2022/igniteui-angular-grids-grid.mjs +49 -49
- package/fesm2022/igniteui-angular-grids-hierarchical-grid.mjs +37 -37
- package/fesm2022/igniteui-angular-grids-lite.mjs +25 -17
- package/fesm2022/igniteui-angular-grids-lite.mjs.map +1 -1
- package/fesm2022/igniteui-angular-grids-pivot-grid.mjs +80 -80
- package/fesm2022/igniteui-angular-grids-pivot-grid.mjs.map +1 -1
- package/fesm2022/igniteui-angular-grids-tree-grid.mjs +55 -55
- package/fesm2022/igniteui-angular-icon.mjs +10 -10
- package/fesm2022/igniteui-angular-input-group.mjs +59 -55
- package/fesm2022/igniteui-angular-input-group.mjs.map +1 -1
- package/fesm2022/igniteui-angular-list.mjs +40 -40
- package/fesm2022/igniteui-angular-navbar.mjs +13 -13
- package/fesm2022/igniteui-angular-navigation-drawer.mjs +43 -38
- package/fesm2022/igniteui-angular-navigation-drawer.mjs.map +1 -1
- package/fesm2022/igniteui-angular-paginator.mjs +19 -19
- package/fesm2022/igniteui-angular-progressbar.mjs +19 -19
- package/fesm2022/igniteui-angular-query-builder.mjs +22 -22
- package/fesm2022/igniteui-angular-radio.mjs +25 -21
- package/fesm2022/igniteui-angular-radio.mjs.map +1 -1
- package/fesm2022/igniteui-angular-select.mjs +29 -33
- package/fesm2022/igniteui-angular-select.mjs.map +1 -1
- package/fesm2022/igniteui-angular-simple-combo.mjs +9 -9
- package/fesm2022/igniteui-angular-simple-combo.mjs.map +1 -1
- package/fesm2022/igniteui-angular-slider.mjs +28 -28
- package/fesm2022/igniteui-angular-snackbar.mjs +7 -7
- package/fesm2022/igniteui-angular-splitter.mjs +13 -13
- package/fesm2022/igniteui-angular-stepper.mjs +34 -34
- package/fesm2022/igniteui-angular-switch.mjs +7 -7
- package/fesm2022/igniteui-angular-tabs.mjs +34 -34
- package/fesm2022/igniteui-angular-time-picker.mjs +26 -36
- package/fesm2022/igniteui-angular-time-picker.mjs.map +1 -1
- package/fesm2022/igniteui-angular-toast.mjs +7 -7
- package/fesm2022/igniteui-angular-tree.mjs +28 -28
- package/fesm2022/igniteui-angular-virtual-scroll.mjs +497 -145
- package/fesm2022/igniteui-angular-virtual-scroll.mjs.map +1 -1
- package/migrations/common/UpdateChanges.d.ts +56 -0
- package/migrations/common/UpdateChanges.js +366 -38
- package/migrations/common/UpdateChanges.spec.js +829 -0
- package/migrations/migration-collection.json +1 -1
- package/migrations/update-22_2_0/index.js +145 -0
- package/migrations/update-22_2_0/index.spec.js +206 -0
- package/navigation-drawer/README.md +1 -1
- package/package.json +3 -3
- package/schematics/tsconfig.tsbuildinfo +1 -1
- package/skills/igniteui-angular-components/SKILL.md +9 -5
- package/skills/igniteui-angular-components/references/form-controls.md +1 -1
- package/skills/igniteui-angular-components/references/mcp-setup.md +14 -2
- package/skills/igniteui-angular-figma-to-app/SKILL.md +112 -525
- package/skills/igniteui-angular-figma-to-app/references/asset-extraction.md +49 -75
- package/skills/igniteui-angular-figma-to-app/references/design-provenance.md +201 -0
- package/skills/igniteui-angular-figma-to-app/references/design-token-bridge.md +175 -52
- package/skills/igniteui-angular-figma-to-app/references/figma-component-map.md +153 -99
- package/skills/igniteui-angular-figma-to-app/references/figma-exploration.md +226 -0
- package/skills/igniteui-angular-figma-to-app/references/mcp-setup.md +71 -105
- package/skills/igniteui-angular-figma-to-app/references/project-setup.md +63 -0
- package/skills/igniteui-angular-figma-to-app/references/theme-generation.md +120 -0
- package/skills/igniteui-angular-figma-to-app/references/validation-patterns.md +48 -50
- package/skills/igniteui-angular-generate-from-image-design/SKILL.md +11 -7
- package/skills/igniteui-angular-grids/SKILL.md +7 -3
- package/skills/igniteui-angular-grids/references/editing.md +1 -2
- package/skills/igniteui-angular-grids/references/grid-migration.md +1 -1
- package/skills/igniteui-angular-theming/SKILL.md +9 -5
- package/skills/igniteui-angular-theming/references/mcp-setup.md +12 -2
- package/types/igniteui-angular-button-group.d.ts +49 -34
- package/types/igniteui-angular-calendar.d.ts +33 -50
- package/types/igniteui-angular-card.d.ts +12 -17
- package/types/igniteui-angular-combo.d.ts +6 -0
- package/types/igniteui-angular-core.d.ts +25 -8
- package/types/igniteui-angular-grids-core.d.ts +48 -4
- package/types/igniteui-angular-grids-lite.d.ts +5 -1
- package/types/igniteui-angular-grids-pivot-grid.d.ts +1 -1
- package/types/igniteui-angular-input-group.d.ts +17 -3
- package/types/igniteui-angular-navigation-drawer.d.ts +1 -0
- package/types/igniteui-angular-radio.d.ts +5 -0
- package/types/igniteui-angular-time-picker.d.ts +0 -1
- package/types/igniteui-angular-virtual-scroll.d.ts +41 -13
- package/virtual-scroll/README.md +32 -1
|
@@ -567,6 +567,835 @@ $var3: igx-comp-theme(
|
|
|
567
567
|
expect(appTree.readContent('test.component.scss')).toEqual(`igx-theme-func($replaced: 10px, $old-prop: 3, $prop3: 2);`);
|
|
568
568
|
done();
|
|
569
569
|
});
|
|
570
|
+
it('should keep the brackets balanced for nested theme functions', done => {
|
|
571
|
+
const themeChangesJson = {
|
|
572
|
+
changes: [
|
|
573
|
+
{
|
|
574
|
+
name: '$remove-me', remove: true,
|
|
575
|
+
owner: 'igx-theme-func',
|
|
576
|
+
type: schema_1.ThemeType.Property
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
name: '$replace-me', replaceWith: '$replaced',
|
|
580
|
+
owner: 'igx-theme-func',
|
|
581
|
+
type: schema_1.ThemeType.Property
|
|
582
|
+
}
|
|
583
|
+
]
|
|
584
|
+
};
|
|
585
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
586
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
587
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
588
|
+
appTree.create('styles.scss', `@include igx-mixin(igx-theme-func($remove-me: 6px));
|
|
589
|
+
@include igx-mixin(igx-theme-func($prop1: red, $remove-me: 6px));
|
|
590
|
+
@include igx-mixin(igx-theme-func($remove-me: 6px, $prop1: red));
|
|
591
|
+
@include igx-mixin(igx-theme-func($replace-me: 6px));
|
|
592
|
+
$var: igx-theme-func($content: "not a ( bracket", $remove-me: 6px);
|
|
593
|
+
$var2: igx-theme-func($image: url(https://example.com/a.png), $remove-me: 6px);
|
|
594
|
+
$var3: igx-theme-func(
|
|
595
|
+
$remove-me: 6px, // not a ) bracket
|
|
596
|
+
$prop1: red
|
|
597
|
+
);`);
|
|
598
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
599
|
+
update.applyChanges();
|
|
600
|
+
expect(appTree.readContent('styles.scss')).toEqual(`@include igx-mixin(igx-theme-func());
|
|
601
|
+
@include igx-mixin(igx-theme-func($prop1: red));
|
|
602
|
+
@include igx-mixin(igx-theme-func( $prop1: red));
|
|
603
|
+
@include igx-mixin(igx-theme-func($replaced: 6px));
|
|
604
|
+
$var: igx-theme-func($content: "not a ( bracket");
|
|
605
|
+
$var2: igx-theme-func($image: url(https://example.com/a.png));
|
|
606
|
+
$var3: igx-theme-func( // not a ) bracket
|
|
607
|
+
$prop1: red
|
|
608
|
+
);`);
|
|
609
|
+
done();
|
|
610
|
+
});
|
|
611
|
+
it('should not treat a theme function mentioned in a comment or a string as a call', done => {
|
|
612
|
+
const themeChangesJson = {
|
|
613
|
+
changes: [
|
|
614
|
+
{
|
|
615
|
+
name: '$remove-me', remove: true,
|
|
616
|
+
owner: 'igx-theme-func',
|
|
617
|
+
type: schema_1.ThemeType.Property
|
|
618
|
+
}
|
|
619
|
+
]
|
|
620
|
+
};
|
|
621
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
622
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
623
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
624
|
+
appTree.create('styles.scss', `// igx-theme-func($remove-me: 1px) is gone, use the grid's own borders
|
|
625
|
+
/* igx-theme-func($remove-me: 2px */
|
|
626
|
+
$doc: "igx-theme-func($remove-me: 3px";
|
|
627
|
+
$var: igx-theme-func($remove-me: 4px, $prop1: red);`);
|
|
628
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
629
|
+
update.applyChanges();
|
|
630
|
+
expect(appTree.readContent('styles.scss')).toEqual(`// igx-theme-func($remove-me: 1px) is gone, use the grid's own borders
|
|
631
|
+
/* igx-theme-func($remove-me: 2px */
|
|
632
|
+
$doc: "igx-theme-func($remove-me: 3px";
|
|
633
|
+
$var: igx-theme-func( $prop1: red);`);
|
|
634
|
+
done();
|
|
635
|
+
});
|
|
636
|
+
it('should remove a theme property that has a comment in front of it and keep the comment', done => {
|
|
637
|
+
const themeChangesJson = {
|
|
638
|
+
changes: [
|
|
639
|
+
{
|
|
640
|
+
name: '$remove-me', remove: true,
|
|
641
|
+
owner: 'igx-theme-func',
|
|
642
|
+
type: schema_1.ThemeType.Property
|
|
643
|
+
}
|
|
644
|
+
]
|
|
645
|
+
};
|
|
646
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
647
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
648
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
649
|
+
appTree.create('styles.scss', `$var1: igx-theme-func(
|
|
650
|
+
$prop1: red, // brand color
|
|
651
|
+
$remove-me: 6px
|
|
652
|
+
);
|
|
653
|
+
$var2: igx-theme-func(
|
|
654
|
+
$prop1: red, // brand color
|
|
655
|
+
$remove-me: 6px,
|
|
656
|
+
$prop2: blue
|
|
657
|
+
);
|
|
658
|
+
$var3: igx-theme-func($prop1: red, /* legacy */ $remove-me: 6px);
|
|
659
|
+
$var4: igx-theme-func($prop1: red, // legacy
|
|
660
|
+
$remove-me: 6px, $prop2: blue);
|
|
661
|
+
$var5: igx-theme-func($prop1: red, // legacy
|
|
662
|
+
$remove-me: 6px);`);
|
|
663
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
664
|
+
update.applyChanges();
|
|
665
|
+
expect(appTree.readContent('styles.scss')).toEqual(`$var1: igx-theme-func(
|
|
666
|
+
$prop1: red // brand color
|
|
667
|
+
);
|
|
668
|
+
$var2: igx-theme-func(
|
|
669
|
+
$prop1: red, // brand color
|
|
670
|
+
$prop2: blue
|
|
671
|
+
);
|
|
672
|
+
$var3: igx-theme-func($prop1: red /* legacy */);
|
|
673
|
+
$var4: igx-theme-func($prop1: red, // legacy
|
|
674
|
+
$prop2: blue);
|
|
675
|
+
$var5: igx-theme-func($prop1: red // legacy
|
|
676
|
+
);`);
|
|
677
|
+
done();
|
|
678
|
+
});
|
|
679
|
+
it('should update a theme property that has whitespace before its colon', done => {
|
|
680
|
+
const themeChangesJson = {
|
|
681
|
+
changes: [
|
|
682
|
+
{
|
|
683
|
+
name: '$remove-me', remove: true,
|
|
684
|
+
owner: 'igx-theme-func',
|
|
685
|
+
type: schema_1.ThemeType.Property
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
name: '$replace-me', replaceWith: '$replaced',
|
|
689
|
+
owner: 'igx-theme-func',
|
|
690
|
+
type: schema_1.ThemeType.Property
|
|
691
|
+
}
|
|
692
|
+
]
|
|
693
|
+
};
|
|
694
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
695
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
696
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
697
|
+
appTree.create('styles.scss', `$var1: igx-theme-func($prop1 : red, $remove-me : 6px);
|
|
698
|
+
$var2: igx-theme-func(
|
|
699
|
+
$prop1 : red,
|
|
700
|
+
$remove-me : 6px
|
|
701
|
+
);
|
|
702
|
+
$var3: igx-theme-func($replace-me : 6px);`);
|
|
703
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
704
|
+
update.applyChanges();
|
|
705
|
+
expect(appTree.readContent('styles.scss')).toEqual(`$var1: igx-theme-func($prop1 : red);
|
|
706
|
+
$var2: igx-theme-func(
|
|
707
|
+
$prop1 : red
|
|
708
|
+
);
|
|
709
|
+
$var3: igx-theme-func($replaced : 6px);`);
|
|
710
|
+
done();
|
|
711
|
+
});
|
|
712
|
+
it('should not update a function or mixin the stylesheet declares itself', done => {
|
|
713
|
+
const themeChangesJson = {
|
|
714
|
+
changes: [
|
|
715
|
+
{
|
|
716
|
+
name: '$remove-me', remove: true,
|
|
717
|
+
owner: 'igx-theme-func',
|
|
718
|
+
type: schema_1.ThemeType.Property
|
|
719
|
+
}
|
|
720
|
+
]
|
|
721
|
+
};
|
|
722
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
723
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
724
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
725
|
+
const userCode = `@use "igniteui-angular/theming" as igx;
|
|
726
|
+
@mixin app-igx-theme-func($remove-me: 1px) {
|
|
727
|
+
border-width: $remove-me;
|
|
728
|
+
}
|
|
729
|
+
@include app-igx-theme-func($remove-me: 2px);
|
|
730
|
+
@function my_igx-theme-func($remove-me: 1px) {
|
|
731
|
+
@return $remove-me;
|
|
732
|
+
}
|
|
733
|
+
$var1: my_igx-theme-func($remove-me: 2px);
|
|
734
|
+
`;
|
|
735
|
+
appTree.create('styles.scss', userCode + `$var2: igx.igx-theme-func($remove-me: 2px, $prop1: red);`);
|
|
736
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
737
|
+
update.applyChanges();
|
|
738
|
+
// a namespaced call to the library function is still migrated
|
|
739
|
+
expect(appTree.readContent('styles.scss')).toEqual(userCode + `$var2: igx.igx-theme-func( $prop1: red);`);
|
|
740
|
+
done();
|
|
741
|
+
});
|
|
742
|
+
it('should not take a declaration in a comment or a string for one the stylesheet makes', done => {
|
|
743
|
+
const themeChangesJson = {
|
|
744
|
+
changes: [
|
|
745
|
+
{
|
|
746
|
+
name: '$remove-me', remove: true,
|
|
747
|
+
owner: 'igx-theme-func',
|
|
748
|
+
type: schema_1.ThemeType.Property
|
|
749
|
+
}
|
|
750
|
+
]
|
|
751
|
+
};
|
|
752
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
753
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
754
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
755
|
+
appTree.create('styles.scss', `// @function igx-theme-func($remove-me: 1px) {}
|
|
756
|
+
$var1: igx-theme-func($prop1: red, $remove-me: 6px);
|
|
757
|
+
$doc: "@mixin igx-theme-func($remove-me: 1px)";
|
|
758
|
+
$var2: igx-theme-func($remove-me: 6px);`);
|
|
759
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
760
|
+
update.applyChanges();
|
|
761
|
+
expect(appTree.readContent('styles.scss')).toEqual(`// @function igx-theme-func($remove-me: 1px) {}
|
|
762
|
+
$var1: igx-theme-func($prop1: red);
|
|
763
|
+
$doc: "@mixin igx-theme-func($remove-me: 1px)";
|
|
764
|
+
$var2: igx-theme-func();`);
|
|
765
|
+
done();
|
|
766
|
+
});
|
|
767
|
+
it('should update a namespaced Ignite UI call although the stylesheet declares the same name', done => {
|
|
768
|
+
const themeChangesJson = {
|
|
769
|
+
changes: [
|
|
770
|
+
{
|
|
771
|
+
name: '$remove-me', remove: true,
|
|
772
|
+
owner: 'igx-theme-func',
|
|
773
|
+
type: schema_1.ThemeType.Property
|
|
774
|
+
}
|
|
775
|
+
]
|
|
776
|
+
};
|
|
777
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
778
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
779
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
780
|
+
// the two are separate members under Sass's namespace rules
|
|
781
|
+
appTree.create('styles.scss', `@use "igniteui-angular/theming" as igx;
|
|
782
|
+
@mixin igx-theme-func($remove-me: 1px) {
|
|
783
|
+
border-width: $remove-me;
|
|
784
|
+
}
|
|
785
|
+
@include igx-theme-func($remove-me: 2px);
|
|
786
|
+
$var: igx.igx-theme-func($remove-me: 6px);`);
|
|
787
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
788
|
+
update.applyChanges();
|
|
789
|
+
expect(appTree.readContent('styles.scss')).toEqual(`@use "igniteui-angular/theming" as igx;
|
|
790
|
+
@mixin igx-theme-func($remove-me: 1px) {
|
|
791
|
+
border-width: $remove-me;
|
|
792
|
+
}
|
|
793
|
+
@include igx-theme-func($remove-me: 2px);
|
|
794
|
+
$var: igx.igx-theme-func();`);
|
|
795
|
+
done();
|
|
796
|
+
});
|
|
797
|
+
it('should tell a mixin the stylesheet declares from a function of the same name', done => {
|
|
798
|
+
const themeChangesJson = {
|
|
799
|
+
changes: [
|
|
800
|
+
{
|
|
801
|
+
name: '$remove-me', remove: true,
|
|
802
|
+
owner: 'igx-theme-func',
|
|
803
|
+
type: schema_1.ThemeType.Property
|
|
804
|
+
}
|
|
805
|
+
]
|
|
806
|
+
};
|
|
807
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
808
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
809
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
810
|
+
// the mixin does not shadow the library's function, and the function does not shadow a mixin
|
|
811
|
+
appTree.create('styles.scss', `@mixin igx-theme-func($remove-me: 1px) {
|
|
812
|
+
border-width: $remove-me;
|
|
813
|
+
}
|
|
814
|
+
@function app-igx-theme-func($remove-me: 1px) {
|
|
815
|
+
@return $remove-me;
|
|
816
|
+
}
|
|
817
|
+
@include igx-theme-func($remove-me: 2px);
|
|
818
|
+
$var1: igx-theme-func($remove-me: 6px);
|
|
819
|
+
$var2: app-igx-theme-func($remove-me: 6px);
|
|
820
|
+
@include app-igx-theme-func($remove-me: 2px);`);
|
|
821
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
822
|
+
update.applyChanges();
|
|
823
|
+
expect(appTree.readContent('styles.scss')).toEqual(`@mixin igx-theme-func($remove-me: 1px) {
|
|
824
|
+
border-width: $remove-me;
|
|
825
|
+
}
|
|
826
|
+
@function app-igx-theme-func($remove-me: 1px) {
|
|
827
|
+
@return $remove-me;
|
|
828
|
+
}
|
|
829
|
+
@include igx-theme-func($remove-me: 2px);
|
|
830
|
+
$var1: igx-theme-func();
|
|
831
|
+
$var2: app-igx-theme-func($remove-me: 6px);
|
|
832
|
+
@include app-igx-theme-func();`);
|
|
833
|
+
done();
|
|
834
|
+
});
|
|
835
|
+
it('should recognize equivalent underscore and hyphen names for local Sass members', () => {
|
|
836
|
+
const themeChangesJson = {
|
|
837
|
+
changes: [
|
|
838
|
+
{ name: '$remove-me', remove: true, owner: 'theme', type: schema_1.ThemeType.Property }
|
|
839
|
+
]
|
|
840
|
+
};
|
|
841
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
842
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
843
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
844
|
+
appTree.create('styles.scss', `@mixin app_theme($remove-me: 1px) { border-width: $remove-me; }
|
|
845
|
+
@mixin reverse-theme($remove-me: 1px) { border-width: $remove-me; }
|
|
846
|
+
@function custom_theme($remove-me: 1px) { @return $remove-me; }
|
|
847
|
+
@function reverse-function-theme($remove-me: 1px) { @return $remove-me; }
|
|
848
|
+
.calls {
|
|
849
|
+
@include app-theme($remove-me: 2px);
|
|
850
|
+
@include reverse_theme($remove-me: 2px);
|
|
851
|
+
$local: custom-theme($remove-me: 2px);
|
|
852
|
+
$reverse: reverse_function_theme($remove-me: 2px);
|
|
853
|
+
$library: app-theme($remove-me: 2px);
|
|
854
|
+
@include custom-theme($remove-me: 2px);
|
|
855
|
+
@include igx.app-theme($remove-me: 2px);
|
|
856
|
+
}`);
|
|
857
|
+
new UnitUpdateChanges(__dirname, appTree).applyChanges();
|
|
858
|
+
expect(appTree.readContent('styles.scss')).toEqual(`@mixin app_theme($remove-me: 1px) { border-width: $remove-me; }
|
|
859
|
+
@mixin reverse-theme($remove-me: 1px) { border-width: $remove-me; }
|
|
860
|
+
@function custom_theme($remove-me: 1px) { @return $remove-me; }
|
|
861
|
+
@function reverse-function-theme($remove-me: 1px) { @return $remove-me; }
|
|
862
|
+
.calls {
|
|
863
|
+
@include app-theme($remove-me: 2px);
|
|
864
|
+
@include reverse_theme($remove-me: 2px);
|
|
865
|
+
$local: custom-theme($remove-me: 2px);
|
|
866
|
+
$reverse: reverse_function_theme($remove-me: 2px);
|
|
867
|
+
$library: app-theme();
|
|
868
|
+
@include custom-theme();
|
|
869
|
+
@include igx.app-theme();
|
|
870
|
+
}`);
|
|
871
|
+
});
|
|
872
|
+
it('should recognize indented Sass shorthand declarations and includes within their scope', () => {
|
|
873
|
+
const themeChangesJson = {
|
|
874
|
+
changes: [
|
|
875
|
+
{ name: '$remove-me', remove: true, owner: 'theme', type: schema_1.ThemeType.Property }
|
|
876
|
+
]
|
|
877
|
+
};
|
|
878
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
879
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
880
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
881
|
+
const source = `= app-grid-summary-theme($remove-me: 1px)
|
|
882
|
+
border-width: $remove-me
|
|
883
|
+
@mixin long_theme($remove-me: 1px)
|
|
884
|
+
border-width: $remove-me
|
|
885
|
+
@function function-theme($remove-me: 1px)
|
|
886
|
+
@return $remove-me
|
|
887
|
+
.calls
|
|
888
|
+
+app-grid-summary-theme($remove-me: 2px)
|
|
889
|
+
@include app-grid-summary-theme($remove-me: 2px)
|
|
890
|
+
+long-theme($remove-me: 2px)
|
|
891
|
+
+function-theme($remove-me: 2px)
|
|
892
|
+
+igx.app-grid-summary-theme($remove-me: 2px)
|
|
893
|
+
$library: app-grid-summary-theme($remove-me: 2px)
|
|
894
|
+
$local: function-theme($remove-me: 2px)
|
|
895
|
+
@media screen
|
|
896
|
+
=scoped-theme($remove-me: 1px)
|
|
897
|
+
border-width: $remove-me
|
|
898
|
+
.local
|
|
899
|
+
+scoped-theme($remove-me: 2px)
|
|
900
|
+
.outside
|
|
901
|
+
+scoped-theme($remove-me: 2px)`;
|
|
902
|
+
const expected = `= app-grid-summary-theme($remove-me: 1px)
|
|
903
|
+
border-width: $remove-me
|
|
904
|
+
@mixin long_theme($remove-me: 1px)
|
|
905
|
+
border-width: $remove-me
|
|
906
|
+
@function function-theme($remove-me: 1px)
|
|
907
|
+
@return $remove-me
|
|
908
|
+
.calls
|
|
909
|
+
+app-grid-summary-theme($remove-me: 2px)
|
|
910
|
+
@include app-grid-summary-theme($remove-me: 2px)
|
|
911
|
+
+long-theme($remove-me: 2px)
|
|
912
|
+
+function-theme()
|
|
913
|
+
+igx.app-grid-summary-theme()
|
|
914
|
+
$library: app-grid-summary-theme()
|
|
915
|
+
$local: function-theme($remove-me: 2px)
|
|
916
|
+
@media screen
|
|
917
|
+
=scoped-theme($remove-me: 1px)
|
|
918
|
+
border-width: $remove-me
|
|
919
|
+
.local
|
|
920
|
+
+scoped-theme($remove-me: 2px)
|
|
921
|
+
.outside
|
|
922
|
+
+scoped-theme()`;
|
|
923
|
+
appTree.create('styles.sass', source);
|
|
924
|
+
appTree.create('windows.sass', source.replace(/\n/g, '\r\n'));
|
|
925
|
+
new UnitUpdateChanges(__dirname, appTree).applyChanges();
|
|
926
|
+
expect(appTree.readContent('styles.sass')).toEqual(expected);
|
|
927
|
+
expect(appTree.readContent('windows.sass')).toEqual(expected.replace(/\n/g, '\r\n'));
|
|
928
|
+
});
|
|
929
|
+
it('should distinguish indented Sass shorthand from operators in function expressions', () => {
|
|
930
|
+
const themeChangesJson = {
|
|
931
|
+
changes: [
|
|
932
|
+
{ name: '$remove-me', remove: true, owner: 'theme', type: schema_1.ThemeType.Property }
|
|
933
|
+
]
|
|
934
|
+
};
|
|
935
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
936
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
937
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
938
|
+
appTree.create('styles.sass', `=app-theme($remove-me: 1px)
|
|
939
|
+
border-width: $remove-me
|
|
940
|
+
@function function-theme($remove-me: 1px)
|
|
941
|
+
@return $remove-me
|
|
942
|
+
$direct: +app-theme($remove-me: 2px)
|
|
943
|
+
$equal: 1px == app-theme($remove-me: 2px)
|
|
944
|
+
$list: (
|
|
945
|
+
+app-theme($remove-me: 2px),
|
|
946
|
+
+function-theme($remove-me: 2px)
|
|
947
|
+
)
|
|
948
|
+
.calls
|
|
949
|
+
+app-theme($remove-me: 2px)
|
|
950
|
+
+function-theme($remove-me: 2px)`);
|
|
951
|
+
new UnitUpdateChanges(__dirname, appTree).applyChanges();
|
|
952
|
+
expect(appTree.readContent('styles.sass')).toEqual(`=app-theme($remove-me: 1px)
|
|
953
|
+
border-width: $remove-me
|
|
954
|
+
@function function-theme($remove-me: 1px)
|
|
955
|
+
@return $remove-me
|
|
956
|
+
$direct: +app-theme()
|
|
957
|
+
$equal: 1px == app-theme()
|
|
958
|
+
$list: (
|
|
959
|
+
+app-theme(),
|
|
960
|
+
+function-theme($remove-me: 2px)
|
|
961
|
+
)
|
|
962
|
+
.calls
|
|
963
|
+
+app-theme($remove-me: 2px)
|
|
964
|
+
+function-theme()`);
|
|
965
|
+
});
|
|
966
|
+
it('should classify mixin calls through comments without changing the comments', () => {
|
|
967
|
+
const themeChangesJson = {
|
|
968
|
+
changes: [
|
|
969
|
+
{ name: '$remove-me', remove: true, owner: 'theme', type: schema_1.ThemeType.Property }
|
|
970
|
+
]
|
|
971
|
+
};
|
|
972
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
973
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
974
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
975
|
+
const source = `@function theme($remove-me: false) { @return $remove-me; }
|
|
976
|
+
@mixin app-theme($remove-me: 1px) { border-width: $remove-me; }
|
|
977
|
+
@include /* brand */ theme($remove-me: true);
|
|
978
|
+
@include // brand
|
|
979
|
+
theme($remove-me: true);
|
|
980
|
+
@include /* keep */ app-theme($remove-me: 2px);
|
|
981
|
+
@include // keep
|
|
982
|
+
app-theme($remove-me: 2px);
|
|
983
|
+
$value: theme($remove-me: true);`;
|
|
984
|
+
const expected = `@function theme($remove-me: false) { @return $remove-me; }
|
|
985
|
+
@mixin app-theme($remove-me: 1px) { border-width: $remove-me; }
|
|
986
|
+
@include /* brand */ theme();
|
|
987
|
+
@include // brand
|
|
988
|
+
theme();
|
|
989
|
+
@include /* keep */ app-theme($remove-me: 2px);
|
|
990
|
+
@include // keep
|
|
991
|
+
app-theme($remove-me: 2px);
|
|
992
|
+
$value: theme($remove-me: true);`;
|
|
993
|
+
for (const eol of ['\n', '\r\n']) {
|
|
994
|
+
const file = eol === '\n' ? 'styles.scss' : 'windows.scss';
|
|
995
|
+
appTree.create(file, source.replace(/\n/g, eol));
|
|
996
|
+
}
|
|
997
|
+
new UnitUpdateChanges(__dirname, appTree).applyChanges();
|
|
998
|
+
expect(appTree.readContent('styles.scss')).toEqual(expected);
|
|
999
|
+
expect(appTree.readContent('windows.scss')).toEqual(expected.replace(/\n/g, '\r\n'));
|
|
1000
|
+
});
|
|
1001
|
+
it('should migrate immediate calls before local Sass declarations become available', () => {
|
|
1002
|
+
const themeChangesJson = {
|
|
1003
|
+
changes: [
|
|
1004
|
+
{ name: '$border-width', remove: true, owner: 'grid-summary-theme', type: schema_1.ThemeType.Property }
|
|
1005
|
+
]
|
|
1006
|
+
};
|
|
1007
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
1008
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
1009
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
1010
|
+
appTree.create('styles.scss', `$before: grid-summary-theme($border-width: 2px);
|
|
1011
|
+
.before { @include grid-summary-theme($border-width: 2px); }
|
|
1012
|
+
@function grid_summary_theme($border-width: 1px) { @return $border-width; }
|
|
1013
|
+
@mixin grid-summary-theme($border-width: 1px) { border-width: $border-width; }
|
|
1014
|
+
$after: grid-summary-theme($border-width: 2px);
|
|
1015
|
+
.after { @include grid-summary-theme($border-width: 2px); }
|
|
1016
|
+
@function grid-summary-theme($border-width: 3px) { @return $border-width; }
|
|
1017
|
+
@mixin grid_summary_theme($border-width: 3px) { border-width: $border-width; }
|
|
1018
|
+
@media screen {
|
|
1019
|
+
$before: app-grid-summary-theme($border-width: 2px);
|
|
1020
|
+
@function app-grid-summary-theme($border-width: 1px) { @return $border-width; }
|
|
1021
|
+
$after: app-grid-summary-theme($border-width: 2px);
|
|
1022
|
+
}
|
|
1023
|
+
$outside: app-grid-summary-theme($border-width: 2px);`);
|
|
1024
|
+
new UnitUpdateChanges(__dirname, appTree).applyChanges();
|
|
1025
|
+
expect(appTree.readContent('styles.scss')).toEqual(`$before: grid-summary-theme();
|
|
1026
|
+
.before { @include grid-summary-theme(); }
|
|
1027
|
+
@function grid_summary_theme($border-width: 1px) { @return $border-width; }
|
|
1028
|
+
@mixin grid-summary-theme($border-width: 1px) { border-width: $border-width; }
|
|
1029
|
+
$after: grid-summary-theme($border-width: 2px);
|
|
1030
|
+
.after { @include grid-summary-theme($border-width: 2px); }
|
|
1031
|
+
@function grid-summary-theme($border-width: 3px) { @return $border-width; }
|
|
1032
|
+
@mixin grid_summary_theme($border-width: 3px) { border-width: $border-width; }
|
|
1033
|
+
@media screen {
|
|
1034
|
+
$before: app-grid-summary-theme();
|
|
1035
|
+
@function app-grid-summary-theme($border-width: 1px) { @return $border-width; }
|
|
1036
|
+
$after: app-grid-summary-theme($border-width: 2px);
|
|
1037
|
+
}
|
|
1038
|
+
$outside: app-grid-summary-theme();`);
|
|
1039
|
+
});
|
|
1040
|
+
it('should respect declaration order for immediate indented Sass calls', () => {
|
|
1041
|
+
const themeChangesJson = {
|
|
1042
|
+
changes: [
|
|
1043
|
+
{ name: '$border-width', remove: true, owner: 'grid-summary-theme', type: schema_1.ThemeType.Property }
|
|
1044
|
+
]
|
|
1045
|
+
};
|
|
1046
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
1047
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
1048
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
1049
|
+
const source = `$before: grid-summary-theme($border-width: 2px)
|
|
1050
|
+
.before
|
|
1051
|
+
+grid-summary-theme($border-width: 2px)
|
|
1052
|
+
@function grid_summary_theme($border-width: 1px)
|
|
1053
|
+
@return $border-width
|
|
1054
|
+
=grid-summary-theme($border-width: 1px)
|
|
1055
|
+
border-width: $border-width
|
|
1056
|
+
$after: grid-summary-theme($border-width: 2px)
|
|
1057
|
+
.after
|
|
1058
|
+
@include grid-summary-theme($border-width: 2px)
|
|
1059
|
+
@media screen
|
|
1060
|
+
$before: app-grid-summary-theme($border-width: 2px)
|
|
1061
|
+
@function app-grid-summary-theme($border-width: 1px)
|
|
1062
|
+
@return $border-width
|
|
1063
|
+
$after: app-grid-summary-theme($border-width: 2px)
|
|
1064
|
+
$outside: app-grid-summary-theme($border-width: 2px)`;
|
|
1065
|
+
const expected = `$before: grid-summary-theme()
|
|
1066
|
+
.before
|
|
1067
|
+
+grid-summary-theme()
|
|
1068
|
+
@function grid_summary_theme($border-width: 1px)
|
|
1069
|
+
@return $border-width
|
|
1070
|
+
=grid-summary-theme($border-width: 1px)
|
|
1071
|
+
border-width: $border-width
|
|
1072
|
+
$after: grid-summary-theme($border-width: 2px)
|
|
1073
|
+
.after
|
|
1074
|
+
@include grid-summary-theme($border-width: 2px)
|
|
1075
|
+
@media screen
|
|
1076
|
+
$before: app-grid-summary-theme()
|
|
1077
|
+
@function app-grid-summary-theme($border-width: 1px)
|
|
1078
|
+
@return $border-width
|
|
1079
|
+
$after: app-grid-summary-theme($border-width: 2px)
|
|
1080
|
+
$outside: app-grid-summary-theme()`;
|
|
1081
|
+
appTree.create('styles.sass', source);
|
|
1082
|
+
appTree.create('windows.sass', source.replace(/\n/g, '\r\n'));
|
|
1083
|
+
new UnitUpdateChanges(__dirname, appTree).applyChanges();
|
|
1084
|
+
expect(appTree.readContent('styles.sass')).toEqual(expected);
|
|
1085
|
+
expect(appTree.readContent('windows.sass')).toEqual(expected.replace(/\n/g, '\r\n'));
|
|
1086
|
+
});
|
|
1087
|
+
it('should preserve forward references in Sass bodies and default arguments evaluated later', () => {
|
|
1088
|
+
const themeChangesJson = {
|
|
1089
|
+
changes: [
|
|
1090
|
+
{ name: '$border-width', remove: true, owner: 'grid-summary-theme', type: schema_1.ThemeType.Property }
|
|
1091
|
+
]
|
|
1092
|
+
};
|
|
1093
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
1094
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
1095
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
1096
|
+
const scss = `@function wrapper($value: grid-summary-theme($border-width: 2px)) {
|
|
1097
|
+
@return grid-summary-theme($border-width: $value);
|
|
1098
|
+
}
|
|
1099
|
+
@mixin wrapper($value: grid-summary-theme($border-width: 2px)) {
|
|
1100
|
+
@include grid-summary-theme($border-width: $value);
|
|
1101
|
+
}
|
|
1102
|
+
@function grid-summary-theme($border-width: 1px) { @return $border-width; }
|
|
1103
|
+
@mixin grid-summary-theme($border-width: 1px) { border-width: $border-width; }
|
|
1104
|
+
.calls { @include wrapper(); width: wrapper(); }`;
|
|
1105
|
+
const sass = `@function wrapper($value: grid-summary-theme($border-width: 2px))
|
|
1106
|
+
@return grid-summary-theme($border-width: $value)
|
|
1107
|
+
=wrapper($value: grid-summary-theme($border-width: 2px))
|
|
1108
|
+
+grid-summary-theme($border-width: $value)
|
|
1109
|
+
=empty($value: grid-summary-theme($border-width: 2px))
|
|
1110
|
+
@function grid-summary-theme($border-width: 1px)
|
|
1111
|
+
@return $border-width
|
|
1112
|
+
=grid-summary-theme($border-width: 1px)
|
|
1113
|
+
border-width: $border-width
|
|
1114
|
+
.calls
|
|
1115
|
+
+wrapper()
|
|
1116
|
+
+empty()
|
|
1117
|
+
width: wrapper()`;
|
|
1118
|
+
appTree.create('styles.scss', scss);
|
|
1119
|
+
appTree.create('styles.sass', sass);
|
|
1120
|
+
new UnitUpdateChanges(__dirname, appTree).applyChanges();
|
|
1121
|
+
expect(appTree.readContent('styles.scss')).toEqual(scss);
|
|
1122
|
+
expect(appTree.readContent('styles.sass')).toEqual(sass);
|
|
1123
|
+
});
|
|
1124
|
+
it('should limit local theme declarations to their enclosing Sass block', () => {
|
|
1125
|
+
const themeChangesJson = {
|
|
1126
|
+
changes: [
|
|
1127
|
+
{ name: '$remove-me', remove: true, owner: 'theme', type: schema_1.ThemeType.Property },
|
|
1128
|
+
{ name: '$old', replaceWith: '$new', owner: 'theme', type: schema_1.ThemeType.Property }
|
|
1129
|
+
]
|
|
1130
|
+
};
|
|
1131
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
1132
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
1133
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
1134
|
+
appTree.create('styles.scss', `$before: theme($remove-me: 2px, $old: red);
|
|
1135
|
+
@media screen {
|
|
1136
|
+
/* } @function theme() { */
|
|
1137
|
+
$text: "}";
|
|
1138
|
+
@function theme($remove-me: 1px, $old: red) { @return $old; }
|
|
1139
|
+
@mixin theme($remove-me: 1px, $old: red) { color: $old; }
|
|
1140
|
+
$local: theme($remove-me: 2px, $old: red);
|
|
1141
|
+
.nested { @include theme($remove-me: 2px, $old: red); }
|
|
1142
|
+
}
|
|
1143
|
+
@media print {
|
|
1144
|
+
$sibling: theme($remove-me: 2px, $old: red);
|
|
1145
|
+
@include theme($remove-me: 2px, $old: red);
|
|
1146
|
+
}
|
|
1147
|
+
$after: theme($remove-me: 2px, $old: red);`);
|
|
1148
|
+
new UnitUpdateChanges(__dirname, appTree).applyChanges();
|
|
1149
|
+
expect(appTree.readContent('styles.scss')).toEqual(`$before: theme( $new: red);
|
|
1150
|
+
@media screen {
|
|
1151
|
+
/* } @function theme() { */
|
|
1152
|
+
$text: "}";
|
|
1153
|
+
@function theme($remove-me: 1px, $old: red) { @return $old; }
|
|
1154
|
+
@mixin theme($remove-me: 1px, $old: red) { color: $old; }
|
|
1155
|
+
$local: theme($remove-me: 2px, $old: red);
|
|
1156
|
+
.nested { @include theme($remove-me: 2px, $old: red); }
|
|
1157
|
+
}
|
|
1158
|
+
@media print {
|
|
1159
|
+
$sibling: theme( $new: red);
|
|
1160
|
+
@include theme( $new: red);
|
|
1161
|
+
}
|
|
1162
|
+
$after: theme( $new: red);`);
|
|
1163
|
+
});
|
|
1164
|
+
it('should limit local theme declarations to their enclosing indented Sass block', () => {
|
|
1165
|
+
const themeChangesJson = {
|
|
1166
|
+
changes: [
|
|
1167
|
+
{ name: '$remove-me', remove: true, owner: 'theme', type: schema_1.ThemeType.Property }
|
|
1168
|
+
]
|
|
1169
|
+
};
|
|
1170
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
1171
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
1172
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
1173
|
+
appTree.create('styles.sass', `@media screen
|
|
1174
|
+
/* local function */
|
|
1175
|
+
@function theme($remove-me: 1px)
|
|
1176
|
+
@return red
|
|
1177
|
+
@mixin theme($remove-me: 1px)
|
|
1178
|
+
color: red
|
|
1179
|
+
$local: theme($remove-me: 2px)
|
|
1180
|
+
.nested
|
|
1181
|
+
@include theme($remove-me: 2px)
|
|
1182
|
+
@media print
|
|
1183
|
+
$sibling: theme($remove-me: 2px)
|
|
1184
|
+
$after: theme(
|
|
1185
|
+
$remove-me: 2px
|
|
1186
|
+
)
|
|
1187
|
+
@include theme($remove-me: 2px)`);
|
|
1188
|
+
new UnitUpdateChanges(__dirname, appTree).applyChanges();
|
|
1189
|
+
expect(appTree.readContent('styles.sass')).toEqual(`@media screen
|
|
1190
|
+
/* local function */
|
|
1191
|
+
@function theme($remove-me: 1px)
|
|
1192
|
+
@return red
|
|
1193
|
+
@mixin theme($remove-me: 1px)
|
|
1194
|
+
color: red
|
|
1195
|
+
$local: theme($remove-me: 2px)
|
|
1196
|
+
.nested
|
|
1197
|
+
@include theme($remove-me: 2px)
|
|
1198
|
+
@media print
|
|
1199
|
+
$sibling: theme()
|
|
1200
|
+
$after: theme(
|
|
1201
|
+
)
|
|
1202
|
+
@include theme()`);
|
|
1203
|
+
});
|
|
1204
|
+
it('should update a call another stylesheet of the app could have declared', done => {
|
|
1205
|
+
const themeChangesJson = {
|
|
1206
|
+
changes: [
|
|
1207
|
+
{
|
|
1208
|
+
name: '$remove-me', remove: true,
|
|
1209
|
+
owner: 'igx-theme-func',
|
|
1210
|
+
type: schema_1.ThemeType.Property
|
|
1211
|
+
}
|
|
1212
|
+
]
|
|
1213
|
+
};
|
|
1214
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
1215
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
1216
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
1217
|
+
// a stylesheet of the app can forward the library's own members, and can hide or rename
|
|
1218
|
+
// what it declares, so what another one holds says nothing about this call
|
|
1219
|
+
appTree.create('_themes.scss', `@forward "igniteui-angular/theming";`);
|
|
1220
|
+
appTree.create('_mixins.scss', `@function igx-theme-func($remove-me) {\n @return $remove-me;\n}`);
|
|
1221
|
+
appTree.create('styles.scss', `@use "themes" as theme;
|
|
1222
|
+
@use "mixins" as custom;
|
|
1223
|
+
$var1: theme.igx-theme-func($remove-me: 6px);
|
|
1224
|
+
$var2: igx-theme-func($remove-me: 6px);`);
|
|
1225
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
1226
|
+
update.applyChanges();
|
|
1227
|
+
expect(appTree.readContent('styles.scss')).toEqual(`@use "themes" as theme;
|
|
1228
|
+
@use "mixins" as custom;
|
|
1229
|
+
$var1: theme.igx-theme-func();
|
|
1230
|
+
$var2: igx-theme-func();`);
|
|
1231
|
+
done();
|
|
1232
|
+
});
|
|
1233
|
+
it('should not let another stylesheet of the app block a migration', done => {
|
|
1234
|
+
const themeChangesJson = {
|
|
1235
|
+
changes: [
|
|
1236
|
+
{
|
|
1237
|
+
name: '$remove-me', remove: true,
|
|
1238
|
+
owner: 'igx-theme-func',
|
|
1239
|
+
type: schema_1.ThemeType.Property
|
|
1240
|
+
}
|
|
1241
|
+
]
|
|
1242
|
+
};
|
|
1243
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
1244
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
1245
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
1246
|
+
const unrelated = `@mixin igx-theme-func($remove-me: 1px) {\n border-width: $remove-me;\n}`;
|
|
1247
|
+
appTree.create('unrelated.scss', unrelated);
|
|
1248
|
+
appTree.create('styles.scss', `$var: igx-theme-func($remove-me: 6px);`);
|
|
1249
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
1250
|
+
update.applyChanges();
|
|
1251
|
+
expect(appTree.readContent('unrelated.scss')).toEqual(unrelated);
|
|
1252
|
+
expect(appTree.readContent('styles.scss')).toEqual(`$var: igx-theme-func();`);
|
|
1253
|
+
done();
|
|
1254
|
+
});
|
|
1255
|
+
it('should update a theme function whose name the owner is only part of', done => {
|
|
1256
|
+
// migrations rely on this: `circular-theme` addresses `progress-circular-theme`,
|
|
1257
|
+
// and `theme` covers every `*-theme` mixin
|
|
1258
|
+
const themeChangesJson = {
|
|
1259
|
+
changes: [
|
|
1260
|
+
{
|
|
1261
|
+
name: '$progress-circle-color', replaceWith: '$fill-color-default',
|
|
1262
|
+
owner: 'circular-theme',
|
|
1263
|
+
type: schema_1.ThemeType.Property
|
|
1264
|
+
},
|
|
1265
|
+
{
|
|
1266
|
+
name: '$wc', remove: true,
|
|
1267
|
+
owner: 'theme',
|
|
1268
|
+
type: schema_1.ThemeType.Property
|
|
1269
|
+
}
|
|
1270
|
+
]
|
|
1271
|
+
};
|
|
1272
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
1273
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
1274
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
1275
|
+
appTree.create('styles.scss', `$var1: progress-circular-theme($progress-circle-color: red);
|
|
1276
|
+
@include theme($palette: $p, $wc: true);
|
|
1277
|
+
$var2: light-theme($palette: $p, $wc: true);`);
|
|
1278
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
1279
|
+
update.applyChanges();
|
|
1280
|
+
expect(appTree.readContent('styles.scss')).toEqual(`$var1: progress-circular-theme($fill-color-default: red);
|
|
1281
|
+
@include theme($palette: $p);
|
|
1282
|
+
$var2: light-theme($palette: $p);`);
|
|
1283
|
+
done();
|
|
1284
|
+
});
|
|
1285
|
+
it('should rename a theme property behind a comment that mentions it', done => {
|
|
1286
|
+
const themeChangesJson = {
|
|
1287
|
+
changes: [
|
|
1288
|
+
{
|
|
1289
|
+
name: '$replace-me', replaceWith: '$replaced',
|
|
1290
|
+
owner: 'igx-theme-func',
|
|
1291
|
+
type: schema_1.ThemeType.Property
|
|
1292
|
+
}
|
|
1293
|
+
]
|
|
1294
|
+
};
|
|
1295
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
1296
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
1297
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
1298
|
+
appTree.create('styles.scss', `$var1: igx-theme-func(/* $replace-me docs */ $replace-me: 6px);
|
|
1299
|
+
$var2: igx-theme-func(
|
|
1300
|
+
$prop1: red,
|
|
1301
|
+
// $replace-me: keep in sync with the brand color
|
|
1302
|
+
$replace-me: 6px
|
|
1303
|
+
);`);
|
|
1304
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
1305
|
+
update.applyChanges();
|
|
1306
|
+
expect(appTree.readContent('styles.scss')).toEqual(`$var1: igx-theme-func(/* $replace-me docs */ $replaced: 6px);
|
|
1307
|
+
$var2: igx-theme-func(
|
|
1308
|
+
$prop1: red,
|
|
1309
|
+
// $replace-me: keep in sync with the brand color
|
|
1310
|
+
$replaced: 6px
|
|
1311
|
+
);`);
|
|
1312
|
+
done();
|
|
1313
|
+
});
|
|
1314
|
+
it('should remove rather than rename a theme property the call already passes under its new name', done => {
|
|
1315
|
+
const themeChangesJson = {
|
|
1316
|
+
changes: [
|
|
1317
|
+
{
|
|
1318
|
+
name: '$replace-me', replaceWith: '$replaced',
|
|
1319
|
+
owner: 'igx-theme-func',
|
|
1320
|
+
type: schema_1.ThemeType.Property
|
|
1321
|
+
}
|
|
1322
|
+
]
|
|
1323
|
+
};
|
|
1324
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
1325
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
1326
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
1327
|
+
appTree.create('styles.scss', `$var1: igx-theme-func($replaced: red, $replace-me: 6px);
|
|
1328
|
+
$var2: igx-theme-func($replace-me: 6px, $replaced: red);
|
|
1329
|
+
$var3: igx-theme-func($not-replaced: red, $replace-me: 6px);
|
|
1330
|
+
$var4: igx-theme-func($prop1: igx-inner-func($replaced: red), $replace-me: 6px);`);
|
|
1331
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
1332
|
+
update.applyChanges();
|
|
1333
|
+
expect(appTree.readContent('styles.scss')).toEqual(`$var1: igx-theme-func($replaced: red);
|
|
1334
|
+
$var2: igx-theme-func( $replaced: red);
|
|
1335
|
+
$var3: igx-theme-func($not-replaced: red, $replaced: 6px);
|
|
1336
|
+
$var4: igx-theme-func($prop1: igx-inner-func($replaced: red), $replaced: 6px);`);
|
|
1337
|
+
done();
|
|
1338
|
+
});
|
|
1339
|
+
it('should keep the line endings of the stylesheet when carrying a comment over', done => {
|
|
1340
|
+
const themeChangesJson = {
|
|
1341
|
+
changes: [
|
|
1342
|
+
{
|
|
1343
|
+
name: '$remove-me', remove: true,
|
|
1344
|
+
owner: 'igx-theme-func',
|
|
1345
|
+
type: schema_1.ThemeType.Property
|
|
1346
|
+
}
|
|
1347
|
+
]
|
|
1348
|
+
};
|
|
1349
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
1350
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
1351
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
1352
|
+
appTree.create('styles.scss', `$var: igx-theme-func($prop1: red, // brand color\r\n $remove-me: 6px, $prop2: blue);`);
|
|
1353
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
1354
|
+
update.applyChanges();
|
|
1355
|
+
expect(appTree.readContent('styles.scss'))
|
|
1356
|
+
.toEqual(`$var: igx-theme-func($prop1: red, // brand color\r\n $prop2: blue);`);
|
|
1357
|
+
done();
|
|
1358
|
+
});
|
|
1359
|
+
it('should update theme properties in stylesheets outside sourceRoot', done => {
|
|
1360
|
+
appTree = (0, setup_spec_1.setupTestTree)({
|
|
1361
|
+
projects: {
|
|
1362
|
+
testProj: {
|
|
1363
|
+
projectType: 'application',
|
|
1364
|
+
root: '',
|
|
1365
|
+
sourceRoot: 'src',
|
|
1366
|
+
architect: { build: { options: {} } }
|
|
1367
|
+
}
|
|
1368
|
+
},
|
|
1369
|
+
schematics: {
|
|
1370
|
+
'@schematics/angular:component': {
|
|
1371
|
+
prefix: 'app'
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
});
|
|
1375
|
+
const themeChangesJson = {
|
|
1376
|
+
changes: [
|
|
1377
|
+
{
|
|
1378
|
+
name: '$remove-me', remove: true,
|
|
1379
|
+
owner: 'igx-theme-func',
|
|
1380
|
+
type: schema_1.ThemeType.Property
|
|
1381
|
+
}
|
|
1382
|
+
]
|
|
1383
|
+
};
|
|
1384
|
+
const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
|
|
1385
|
+
spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
|
|
1386
|
+
spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
|
|
1387
|
+
const call = `$var: igx-theme-func($remove-me: 1px);`;
|
|
1388
|
+
const migrated = `$var: igx-theme-func();`;
|
|
1389
|
+
const updated = ['src/app/app.scss', 'src/app/distribution/_summary.scss', 'styles/_theme.scss'];
|
|
1390
|
+
const skipped = ['node_modules/some-lib/_lib.scss', 'dist/app/styles.scss'];
|
|
1391
|
+
[...updated, ...skipped].forEach(file => appTree.create(file, call));
|
|
1392
|
+
const update = new UnitUpdateChanges(__dirname, appTree);
|
|
1393
|
+
update.applyChanges();
|
|
1394
|
+
updated.forEach(file => expect(appTree.readContent(file)).withContext(file).toEqual(migrated));
|
|
1395
|
+
// dependencies and build output are never touched
|
|
1396
|
+
skipped.forEach(file => expect(appTree.readContent(file)).withContext(file).toEqual(call));
|
|
1397
|
+
done();
|
|
1398
|
+
});
|
|
570
1399
|
it('should replace imports', done => {
|
|
571
1400
|
const importsJson = {
|
|
572
1401
|
changes: [
|