1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @flow
    
  8.  */
    
  9. 
    
  10. describe('Stylex plugin utils', () => {
    
  11.   let getStyleXData;
    
  12.   let styleElements;
    
  13. 
    
  14.   function defineStyles(style) {
    
  15.     const styleElement = document.createElement('style');
    
  16.     styleElement.type = 'text/css';
    
  17.     styleElement.appendChild(document.createTextNode(style));
    
  18. 
    
  19.     styleElements.push(styleElement);
    
  20. 
    
  21.     document.head.appendChild(styleElement);
    
  22.   }
    
  23. 
    
  24.   beforeEach(() => {
    
  25.     getStyleXData = require('../utils').getStyleXData;
    
  26. 
    
  27.     styleElements = [];
    
  28.   });
    
  29. 
    
  30.   afterEach(() => {
    
  31.     styleElements.forEach(styleElement => {
    
  32.       document.head.removeChild(styleElement);
    
  33.     });
    
  34.   });
    
  35. 
    
  36.   it('should gracefully handle empty values', () => {
    
  37.     expect(getStyleXData(null)).toMatchInlineSnapshot(`
    
  38.       {
    
  39.         "resolvedStyles": {},
    
  40.         "sources": [],
    
  41.       }
    
  42.     `);
    
  43. 
    
  44.     expect(getStyleXData(undefined)).toMatchInlineSnapshot(`
    
  45.       {
    
  46.         "resolvedStyles": {},
    
  47.         "sources": [],
    
  48.       }
    
  49.     `);
    
  50. 
    
  51.     expect(getStyleXData('')).toMatchInlineSnapshot(`
    
  52.       {
    
  53.         "resolvedStyles": {},
    
  54.         "sources": [],
    
  55.       }
    
  56.     `);
    
  57. 
    
  58.     expect(getStyleXData([undefined])).toMatchInlineSnapshot(`
    
  59.       {
    
  60.         "resolvedStyles": {},
    
  61.         "sources": [],
    
  62.       }
    
  63.     `);
    
  64.   });
    
  65. 
    
  66.   it('should support simple style objects', () => {
    
  67.     defineStyles(`
    
  68.       .foo {
    
  69.         display: flex;
    
  70.       }
    
  71.       .bar: {
    
  72.         align-items: center;
    
  73.       }
    
  74.       .baz {
    
  75.         flex-direction: center;
    
  76.       }
    
  77.     `);
    
  78. 
    
  79.     expect(
    
  80.       getStyleXData({
    
  81.         // The source/module styles are defined in
    
  82.         Example__style: 'Example__style',
    
  83. 
    
  84.         // Map of CSS style to StyleX class name, booleans, or nested structures
    
  85.         display: 'foo',
    
  86.         flexDirection: 'baz',
    
  87.         alignItems: 'bar',
    
  88.       }),
    
  89.     ).toMatchInlineSnapshot(`
    
  90.       {
    
  91.         "resolvedStyles": {
    
  92.           "alignItems": "center",
    
  93.           "display": "flex",
    
  94.           "flexDirection": "center",
    
  95.         },
    
  96.         "sources": [
    
  97.           "Example__style",
    
  98.         ],
    
  99.       }
    
  100.     `);
    
  101.   });
    
  102. 
    
  103.   it('should support multiple style objects', () => {
    
  104.     defineStyles(`
    
  105.       .foo {
    
  106.         display: flex;
    
  107.       }
    
  108.       .bar: {
    
  109.         align-items: center;
    
  110.       }
    
  111.       .baz {
    
  112.         flex-direction: center;
    
  113.       }
    
  114.     `);
    
  115. 
    
  116.     expect(
    
  117.       getStyleXData([
    
  118.         {Example1__style: 'Example1__style', display: 'foo'},
    
  119.         {
    
  120.           Example2__style: 'Example2__style',
    
  121.           flexDirection: 'baz',
    
  122.           alignItems: 'bar',
    
  123.         },
    
  124.       ]),
    
  125.     ).toMatchInlineSnapshot(`
    
  126.       {
    
  127.         "resolvedStyles": {
    
  128.           "alignItems": "center",
    
  129.           "display": "flex",
    
  130.           "flexDirection": "center",
    
  131.         },
    
  132.         "sources": [
    
  133.           "Example1__style",
    
  134.           "Example2__style",
    
  135.         ],
    
  136.       }
    
  137.     `);
    
  138.   });
    
  139. 
    
  140.   it('should filter empty rules', () => {
    
  141.     defineStyles(`
    
  142.       .foo {
    
  143.         display: flex;
    
  144.       }
    
  145.       .bar: {
    
  146.         align-items: center;
    
  147.       }
    
  148.       .baz {
    
  149.         flex-direction: center;
    
  150.       }
    
  151.     `);
    
  152. 
    
  153.     expect(
    
  154.       getStyleXData([
    
  155.         false,
    
  156.         {Example1__style: 'Example1__style', display: 'foo'},
    
  157.         false,
    
  158.         false,
    
  159.         {
    
  160.           Example2__style: 'Example2__style',
    
  161.           flexDirection: 'baz',
    
  162.           alignItems: 'bar',
    
  163.         },
    
  164.         false,
    
  165.       ]),
    
  166.     ).toMatchInlineSnapshot(`
    
  167.       {
    
  168.         "resolvedStyles": {
    
  169.           "alignItems": "center",
    
  170.           "display": "flex",
    
  171.           "flexDirection": "center",
    
  172.         },
    
  173.         "sources": [
    
  174.           "Example1__style",
    
  175.           "Example2__style",
    
  176.         ],
    
  177.       }
    
  178.     `);
    
  179.   });
    
  180. 
    
  181.   it('should support pseudo-classes', () => {
    
  182.     defineStyles(`
    
  183.       .foo {
    
  184.         color: black;
    
  185.       }
    
  186.       .bar: {
    
  187.         color: blue;
    
  188.       }
    
  189.       .baz {
    
  190.         text-decoration: none;
    
  191.       }
    
  192.     `);
    
  193. 
    
  194.     expect(
    
  195.       getStyleXData({
    
  196.         // The source/module styles are defined in
    
  197.         Example__style: 'Example__style',
    
  198. 
    
  199.         // Map of CSS style to StyleX class name, booleans, or nested structures
    
  200.         color: 'foo',
    
  201.         ':hover': {
    
  202.           color: 'bar',
    
  203.           textDecoration: 'baz',
    
  204.         },
    
  205.       }),
    
  206.     ).toMatchInlineSnapshot(`
    
  207.       {
    
  208.         "resolvedStyles": {
    
  209.           ":hover": {
    
  210.             "color": "blue",
    
  211.             "textDecoration": "none",
    
  212.           },
    
  213.           "color": "black",
    
  214.         },
    
  215.         "sources": [
    
  216.           "Example__style",
    
  217.         ],
    
  218.       }
    
  219.     `);
    
  220.   });
    
  221. 
    
  222.   it('should support nested selectors', () => {
    
  223.     defineStyles(`
    
  224.       .foo {
    
  225.         display: flex;
    
  226.       }
    
  227.       .bar: {
    
  228.         align-items: center;
    
  229.       }
    
  230.       .baz {
    
  231.         flex-direction: center;
    
  232.       }
    
  233.     `);
    
  234. 
    
  235.     expect(
    
  236.       getStyleXData([
    
  237.         {Example1__style: 'Example1__style', display: 'foo'},
    
  238.         false,
    
  239.         [
    
  240.           false,
    
  241.           {Example2__style: 'Example2__style', flexDirection: 'baz'},
    
  242.           {Example3__style: 'Example3__style', alignItems: 'bar'},
    
  243.         ],
    
  244.         false,
    
  245.       ]),
    
  246.     ).toMatchInlineSnapshot(`
    
  247.       {
    
  248.         "resolvedStyles": {
    
  249.           "alignItems": "center",
    
  250.           "display": "flex",
    
  251.           "flexDirection": "center",
    
  252.         },
    
  253.         "sources": [
    
  254.           "Example1__style",
    
  255.           "Example2__style",
    
  256.           "Example3__style",
    
  257.         ],
    
  258.       }
    
  259.     `);
    
  260.   });
    
  261. });