text: import system from '../../src/core/system';
  
  const defaultBreakpoints = [40, 52, 64].map(n => n + 'em');
  
  test('returns a style parser', () => {
    const parser = system({
      color: true,
      backgroundColor: {
        property: 'backgroundColor',
        scale: 'colors',
      },
      mx: {
        scale: 'space',
        properties: ['marginLeft', 'marginRight'],
      },
    });
    expect(typeof parser).toBe('function');
    const styles = parser({
      theme: {
        breakpoints: defaultBreakpoints,
        space: [0, 4, 8, 16, 32],
        colors: {
          primary: 'rebeccapurple',
        },
      },
      color: 'tomato',
      backgroundColor: 'primary',
      mx: [2, 3, 4],
    });
    expect(styles).toEqual({
      color: 'tomato',
      backgroundColor: 'rebeccapurple',
      marginLeft: 8,
      marginRight: 8,
      '@media screen and (min-width: 40em)': {
        marginLeft: 16,
        marginRight: 16,
      },
      '@media screen and (min-width: 52em)': {
        marginLeft: 32,
        marginRight: 32,
      },
    });
  });
  
  test('merges multiple responsive styles', () => {
    const parser = system({
      margin: true,
      padding: true,
      width: true,
    });
    const styles = parser({
      theme: {
        breakpoints: defaultBreakpoints,
      },
      margin: [0, 4, 8],
      padding: [16, 32, 64],
      width: ['100%', '50%'],
    });
    expect(styles).toEqual({
      margin: 0,
      padding: 16,
      width: '100%',
      '@media screen and (min-width: 40em)': {
        margin: 4,
        padding: 32,
        width: '50%',
      },
      '@media screen and (min-width: 52em)': {
        margin: 8,
        padding: 64,
      },
    });
  });
  
  test('merges multiple responsive object styles', () => {
    const parser = system({
      margin: true,
      padding: true,
      width: true,
    });
    const styles = parser({
      theme: {
        breakpoints: defaultBreakpoints,
      },
      margin: { _: 0, 0: 4, 1: 8 },
      padding: { _: 16, 0: 32, 1: 64 },
      width: { _: '100%', 0: '50%' },
    });
    expect(styles).toEqual({
      margin: 0,
      padding: 16,
      width: '100%',
      '@media screen and (min-width: 40em)': {
        margin: 4,
        padding: 32,
        width: '50%',
      },
      '@media screen and (min-width: 52em)': {
        margin: 8,
        padding: 64,
      },
    });
  });
  
  test('gets values from theme', () => {
    const parser = system({
      mx: {
        properties: ['marginLeft', 'marginRight'],
        scale: 'space',
      },
      color: {
        property: 'color',
        scale: 'colors',
      },
    });
    const style = parser({
      theme: {
        breakpoints: defaultBreakpoints,
        colors: {
          primary: 'tomato',
        },
        space: [0, 6, 12, 24, 48, 96],
      },
      mx: [0, 1, 2, 3],
      color: ['primary', 'black'],
    });
    expect(style).toEqual({
      color: 'tomato',
      marginLeft: 0,
      marginRight: 0,
      '@media screen and (min-width: 40em)': {
        color: 'black',
        marginLeft: 6,
        marginRight: 6,
      },
      '@media screen and (min-width: 52em)': {
        marginLeft: 12,
        marginRight: 12,
      },
      '@media screen and (min-width: 64em)': {
        marginLeft: 24,
        marginRight: 24,
      },
    });
  });
  
  test('gets 0 index values from theme', () => {
    const parser = system({
      width: {
        property: 'width',
        scale: 'sizes',
      }
    });
    const style = parser({
      theme: {
        breakpoints: defaultBreakpoints,
        sizes: [24, 48],
      },
      width: 0,
    });
    expect(style).toEqual({ width: 24 });
  });
  
  test('ignores null values', () => {
    const parser = system({
      color: true,
    });
    const style = parser({ color: null });
    expect(style).toEqual({});
  });
  
  test('returns a noop function with no arguments', () => {
    const parser = system();
    expect(typeof parser).toBe('function');
  });
  
  test('skips null values in arrays', () => {
    const parser = system({
      fontSize: {
        property: 'fontSize',
        scale: 'fontSizes',
      },
    });
    const style = parser({
      theme: {
        breakpoints: defaultBreakpoints,
      },
      fontSize: [16, null, null, 18],
    });
    expect(style).toEqual({
      fontSize: 16,
      // omitting these keys cause issues when using multiple
      // responsive props together #561 #551 #549
      '@media screen and (min-width: 40em)': {},
      '@media screen and (min-width: 52em)': {},
      '@media screen and (min-width: 64em)': {
        fontSize: 18,
      }
    });
  });
  
  test('includes single property functions', () => {
    const parser = system({
      color: true,
      backgroundColor: true,
      width: true,
    });
    const a = parser.color({ color: 'tomato', backgroundColor: 'nope' });
    const b = parser.width({ width: '100%', color: 'tomato', backgroundColor: 'nope' });
    expect(a).toEqual({ color: 'tomato' });
    expect(b).toEqual({ width: '100%' });
  });
  
  test('parser configs can be composed manually', () => {
    const color = system({ color: true, backgroundColor: true });
    const layout = system({ width: true, height: true });
    const composed = system({ ...color.config, ...layout.config });
    const style = composed({
      color: 'tomato',
      backgroundColor: 'black',
      width: '100%',
    });
    expect(style).toEqual({
      color: 'tomato',
      backgroundColor: 'black',
      width: '100%',
    });
  });
  
  test('supports non-array breakpoints object', () => {
    const parser = system({
      margin: true,
      padding: true,
      width: true,
    });
    const styles = parser({
      theme: {
        disableStyledSystemCache: true,
        breakpoints: {
          sm: '32em',
          md: '40em',
          lg: '64em',
        }
      },
      margin: { _: 0, sm: 4, md: 8 },
      padding: { _: 16, lg: 64 },
    });
    expect(styles).toEqual({
      margin: 0,
      padding: 16,
      '@media screen and (min-width: 32em)': {
        margin: 4,
      },
      '@media screen and (min-width: 40em)': {
        margin: 8,
      },
      '@media screen and (min-width: 64em)': {
        padding: 64,
      },
    });
  });
  
  test('sorts media queries when responsive object values are used', () => {
    const parser = system({
      margin: true,
      padding: true,
      color: true,
    });
    const styles = parser({
      theme: {
        disableStyledSystemCache: true,
        breakpoints: {
          sm: '32em',
          md: '40em',
          lg: '64em',
          xl: '128em',
        }
      },
      padding: { _: 16, lg: 64, xl: 128 },
      margin: { sm: 4, md: 8 },
      color: { lg: 'tomato' },
    });
    expect(Object.keys(styles)).toEqual([
      '@media screen and (min-width: 32em)',
      '@media screen and (min-width: 40em)',
      '@media screen and (min-width: 64em)',
      '@media screen and (min-width: 128em)',
      'padding',
    ]);
  });
  
  test('transforms values', () => {
    const parser = system({
      margin: {
        property: 'margin',
        transform: (n, scale, props) => {
          const m = props.multiply || 1;
          return m * n;
        }
      }
    });
    const a = parser({ margin: 8 });
    const b = parser({ margin: 12, multiply: 2 });
    expect(a).toEqual({ margin: 8 });
    expect(b).toEqual({ margin: 24 });
  });
  