@@ -996,6 +996,31 @@ describe('htmlbars-inline-precompile', function () {
996
996
expect ( transformed ) . toContain ( `window.define('my-app/components/thing', thing)` ) ;
997
997
} ) ;
998
998
999
+ it ( 'prevents inconsistent external manipulation of the locals array' , function ( ) {
1000
+ let compatTransform : ExtendedPluginBuilder = ( env ) => {
1001
+ return {
1002
+ name : 'compat-transform' ,
1003
+ visitor : {
1004
+ Template ( ) {
1005
+ ( env as any ) . locals . push ( 'NewThing' ) ;
1006
+ } ,
1007
+ } ,
1008
+ } ;
1009
+ } ;
1010
+
1011
+ plugins = [ [ HTMLBarsInlinePrecompile , { targetFormat : 'hbs' , transforms : [ compatTransform ] } ] ] ;
1012
+
1013
+ expect ( ( ) => {
1014
+ transform ( stripIndent `
1015
+ import { precompileTemplate } from '@ember/template-compilation';
1016
+ let NewThing = Thing;
1017
+ export default function() {
1018
+ const template = precompileTemplate('<Thing />');
1019
+ }
1020
+ ` ) ;
1021
+ } ) . toThrow ( / T h e o n l y s u p p o r t e d w a y t o m a n i p u l a t e l o c a l s i s v i a t h e j s u t i l s A P I / ) ;
1022
+ } ) ;
1023
+
999
1024
it ( 'can emit side-effectful import' , function ( ) {
1000
1025
let compatTransform : ExtendedPluginBuilder = ( env ) => {
1001
1026
return {
@@ -1529,7 +1554,7 @@ describe('htmlbars-inline-precompile', function () {
1529
1554
1530
1555
describe ( 'scope' , function ( ) {
1531
1556
it ( 'correctly handles scope function (non-block arrow function)' , function ( ) {
1532
- let source = 'hello ' ;
1557
+ let source = '<foo /><bar/> ' ;
1533
1558
let spy = sinon . spy ( compiler , 'precompile' ) ;
1534
1559
1535
1560
transform (
@@ -1539,7 +1564,7 @@ describe('htmlbars-inline-precompile', function () {
1539
1564
} ) ;
1540
1565
1541
1566
it ( 'correctly handles scope function (block arrow function)' , function ( ) {
1542
- let source = 'hello ' ;
1567
+ let source = '<foo /><bar/> ' ;
1543
1568
let spy = sinon . spy ( compiler , 'precompile' ) ;
1544
1569
1545
1570
transform (
@@ -1550,7 +1575,7 @@ describe('htmlbars-inline-precompile', function () {
1550
1575
} ) ;
1551
1576
1552
1577
it ( 'correctly handles scope function (normal function)' , function ( ) {
1553
- let source = 'hello ' ;
1578
+ let source = '<foo /><bar/> ' ;
1554
1579
let spy = sinon . spy ( compiler , 'precompile' ) ;
1555
1580
1556
1581
transform (
@@ -1561,7 +1586,7 @@ describe('htmlbars-inline-precompile', function () {
1561
1586
} ) ;
1562
1587
1563
1588
it ( 'correctly handles scope function (object method)' , function ( ) {
1564
- let source = 'hello ' ;
1589
+ let source = '<foo /><bar/> ' ;
1565
1590
let spy = sinon . spy ( compiler , 'precompile' ) ;
1566
1591
1567
1592
transform (
@@ -1571,7 +1596,7 @@ describe('htmlbars-inline-precompile', function () {
1571
1596
} ) ;
1572
1597
1573
1598
it ( 'correctly handles scope function with coverage' , function ( ) {
1574
- let source = 'hello ' ;
1599
+ let source = '<foo /><bar/> ' ;
1575
1600
let spy = sinon . spy ( compiler , 'precompile' ) ;
1576
1601
1577
1602
transform (
@@ -1626,6 +1651,26 @@ describe('htmlbars-inline-precompile', function () {
1626
1651
/ S c o p e o b j e c t s f o r ` p r e c o m p i l e T e m p l a t e ` m a y o n l y c o n t a i n d i r e c t r e f e r e n c e s t o i n - s c o p e v a l u e s , e .g . { b a r } o r { b a r : b a r } /
1627
1652
) ;
1628
1653
} ) ;
1654
+
1655
+ it ( 'correctly removes not used scope' , function ( ) {
1656
+ let spy = sinon . spy ( compiler , 'precompile' ) ;
1657
+ transform ( `
1658
+ import { precompileTemplate } from '@ember/template-compilation';
1659
+ let foo, bar;
1660
+ var compiled = precompileTemplate('<foo /><bar/>', { scope: () => ({ foo, bar, baz }) });
1661
+ ` ) ;
1662
+ expect ( spy . firstCall . lastArg ) . toHaveProperty ( 'locals' , [ 'foo' , 'bar' ] ) ;
1663
+ } ) ;
1664
+
1665
+ it ( 'does not automagically add to scope when not using implicit-scope-form' , function ( ) {
1666
+ let spy = sinon . spy ( compiler , 'precompile' ) ;
1667
+ transform ( `
1668
+ import { precompileTemplate } from '@ember/template-compilation';
1669
+ let foo, bar;
1670
+ var compiled = precompileTemplate('<foo /><bar/>', { scope: () => ({ bar }) });
1671
+ ` ) ;
1672
+ expect ( spy . firstCall . lastArg ) . toHaveProperty ( 'locals' , [ 'bar' ] ) ;
1673
+ } ) ;
1629
1674
} ) ;
1630
1675
1631
1676
describe ( 'implicit-scope-form' , function ( ) {
@@ -1660,9 +1705,7 @@ describe('htmlbars-inline-precompile', function () {
1660
1705
// that's what the lint rules are for. When it comes to correctness, we need
1661
1706
// our scope to behave like real Javascript, and Javascript doesn't care
1662
1707
// whether you've (for example) capitalized your variable identifier.
1663
- //
1664
- // needs https://github.com/glimmerjs/glimmer-vm/pull/1421
1665
- it . skip ( 'shadows html elements with locals' , function ( ) {
1708
+ it ( 'shadows html elements with locals' , function ( ) {
1666
1709
plugins = [
1667
1710
[
1668
1711
HTMLBarsInlinePrecompile ,
@@ -1681,9 +1724,9 @@ describe('htmlbars-inline-precompile', function () {
1681
1724
) ;
1682
1725
1683
1726
expect ( transformed ) . toEqualCode ( `
1684
- import templateOnly from "@ember/component/template-only";
1685
- import { setComponentTemplate } from "@ember/component";
1686
1727
import { precompileTemplate } from "@ember/template-compilation";
1728
+ import { setComponentTemplate } from "@ember/component";
1729
+ import templateOnly from "@ember/component/template-only";
1687
1730
let div = 1;
1688
1731
export default setComponentTemplate(precompileTemplate('<div></div>', { scope: () => ({ div }), strictMode: true }), templateOnly());
1689
1732
` ) ;
@@ -1716,8 +1759,7 @@ describe('htmlbars-inline-precompile', function () {
1716
1759
` ) ;
1717
1760
} ) ;
1718
1761
1719
- // needs https://github.com/glimmerjs/glimmer-vm/pull/1421
1720
- it . skip ( 'leaves ember keywords alone when no local is defined' , function ( ) {
1762
+ it ( 'leaves ember keywords alone when no local is defined' , function ( ) {
1721
1763
plugins = [
1722
1764
[
1723
1765
HTMLBarsInlinePrecompile ,
@@ -1735,9 +1777,9 @@ describe('htmlbars-inline-precompile', function () {
1735
1777
) ;
1736
1778
1737
1779
expect ( transformed ) . toEqualCode ( `
1738
- import templateOnly from "@ember/component/template-only";
1739
- import { setComponentTemplate } from "@ember/component";
1740
1780
import { precompileTemplate } from "@ember/template-compilation";
1781
+ import { setComponentTemplate } from "@ember/component";
1782
+ import templateOnly from "@ember/component/template-only";
1741
1783
export default setComponentTemplate(precompileTemplate('{{hasBlock "thing"}}', { strictMode: true }), templateOnly());
1742
1784
` ) ;
1743
1785
} ) ;
0 commit comments