<commit_before>import { expect } from "chai";
import { shallow, mount } from "enzyme";
import { createElement, Component } from "react";

import "./utils/dom";
import defaultStyle from "../src/defaultStyle";
import createSubstyle from "../src/createSubstyle";
import {
  ENHANCER_CONTEXT_NAME,
  PROPS_DECORATOR_CONTEXT_NAME
} from "../src/types";

describe("`defaultStyle` higher-order component factory", () => {
  const MyComponent = ({ style, ...rest }) =>
    createElement(
      "div",
      { ...style, ...rest },
      createElement("span", { ...style("nested") })
    );

  it("should inject a substyle instance for the `style` prop", () => {
    const MyEnhancedComponent = defaultStyle({ color: "red" })(MyComponent);
    const wrapper = shallow(createElement(MyEnhancedComponent));
    const styleProp = wrapper.props().style;
    expect(styleProp).to.be.a.instanceOf(Function);
    expect(styleProp.style).to.deep.equal({ color: "red" });
  });

  it("should merge styles provided by the component user with default styles", () => {
    const MyEnhancedComponent = defaultStyle({ color: "red" })(MyComponent);
    const wrapper = shallow(
      createElement(MyEnhancedComponent, {
        style: { cursor: "pointer" }
      })
    );
    const styleProp = wrapper.props().style;
    expect(styleProp.style).to.deep.equal({
      color: "red",
      cursor: "pointer"
    });
  });

  it("should also work if a substyle instance is provided as `style`", () => {
    const MyEnhancedComponent = defaultStyle({ color: "red" })(MyComponent);
    const wrapper = shallow(
      createElement(MyEnhancedComponent, {
        style: createSubstyle({
          style: { cursor: "pointer" }
        })
      })
    );
    const styleProp = wrapper.props().style;
    expect(styleProp.style).to.deep.equal({
      color: "red",
      cursor: "pointer"
    });
  });

  it("should accept a function mapping props to default styles as first argument", () => {
    const MyEnhancedComponent = defaultStyle(props => ({ color: props.color }))(
      MyComponent
    );
    const wrapper = shallow(
      createElement(MyEnhancedComponent, {
        style: { cursor: "pointer" },
        color: "black"
      })
    );
    const styleProp = wrapper.props().style;
    expect(styleProp.style).to.deep.equal({
      color: "black",
      cursor: "pointer"
    });
  });

  it("should take a modifier selection function as second argument", () => {
    const MyEnhancedComponent = defaultStyle(
      {
        color: "red",

        "&readOnly": {
          opacity: 0.5
        }
      },
      props => ({
        "&readOnly": props.readOnly
      })
    )(MyComponent);
    const wrapper = shallow(
      createElement(MyEnhancedComponent, { readOnly: true })
    );
    const styleProp = wrapper.props().style;
    expect(styleProp.style).to.deep.equal({
      color: "red",
      opacity: 0.5
    });
  });

  it("should apply the selected modifiers also on the style supplied by the user", () => {
    const MyEnhancedComponent = defaultStyle({ color: "red" }, props => ({
      "&readOnly": props.readOnly
    }))(MyComponent);
    const wrapper = shallow(
      createElement(MyEnhancedComponent, {
        readOnly: true,
        style: {
          "&readOnly": {
            opacity: 0.5
          }
        }
      })
    );
    const styleProp = wrapper.props().style;
    expect(styleProp.style).to.deep.equal({
      color: "red",
      opacity: 0.5
    });
  });

  it("should give precendence to styles supplied by the user, regardless the modifiers specificity", () => {
    const MyEnhancedComponent = defaultStyle(
      {
        "&readOnly": {
          opacity: 0.5
        }
      },
      props => ({
        "&readOnly": props.readOnly
      })
    )(MyComponent);
    const wrapper = shallow(
      createElement(MyEnhancedComponent, {
        readOnly: true,
        style: {
          opacity: 0.7
        }
      })
    );
    const styleProp = wrapper.props().style;
    expect(styleProp.style).to.deep.equal({
      opacity: 0.7
    });
  });

  it("should support depency injection via context for additional HoC to wrap the component", () => {
    const MyStyledComponent = defaultStyle()(MyComponent);
    const wrapInSection = WrappedComponent => props =>
      createElement("section", {}, createElement(WrappedComponent, props));
    const wrapper = shallow(createElement(MyStyledComponent), {
      context: {
        [ENHANCER_CONTEXT_NAME]: wrapInSection
      }
    });
    expect(wrapper.get(0).type().type).to.equal("section");
  });

  it("should expose the wrapped component instance via `getWrappedInstance`", () => {
    class MyClassComponent extends Component {
      render() {
        return createElement("div");
      }
    }
    const MyEnhancedClassComponent = defaultStyle()(MyClassComponent);
    const instance = mount(createElement(MyEnhancedClassComponent)).instance();
    expect(instance.getWrappedInstance).to.be.a("function");
    expect(instance.getWrappedInstance()).to.be.an.instanceOf(MyClassComponent);

    const MyFunctionComponent = () => createElement("div");
    const MyEnhancedFunctionComponent = defaultStyle()(MyFunctionComponent);
    const instance2 = mount(
      createElement(MyEnhancedFunctionComponent)
    ).instance();
    expect(instance2.getWrappedInstance()).to.not.exist;
  });

  it("should support providing a props decorator function via context", () => {
    const MyStyledComponent = defaultStyle()(MyComponent);
    const decorateProps = props => ({
      mapped: "foobar"
    });
    const wrapper = mount(createElement(MyStyledComponent), {
      context: {
        [PROPS_DECORATOR_CONTEXT_NAME]: decorateProps
      }
    });
    const containerProps = wrapper.find("MyComponent").find("div").props();
    expect(containerProps).to.not.have.property("style");
    expect(containerProps).to.not.have.property("className");
    expect(containerProps).to.have.property("mapped", "foobar");
  });
});<commit_msg>added test for providing props decorator via context<commit_after>import { expect } from 'chai'
import { shallow, mount } from 'enzyme'
import { createElement, Component } from 'react'

import './utils/dom'
import defaultStyle from '../src/defaultStyle'
import createSubstyle from '../src/createSubstyle'
import {
  ENHANCER_CONTEXT_NAME,
  PROPS_DECORATOR_CONTEXT_NAME,
} from '../src/types'

describe('`defaultStyle` higher-order component factory', () => {
  const MyComponent = ({ style, ...rest }) =>
    createElement(
      'div',
      { ...style, ...rest },
      createElement('span', { ...style('nested') })
    )

  it('should inject a substyle instance for the `style` prop', () => {
    const MyEnhancedComponent = defaultStyle({ color: 'red' })(MyComponent)
    const wrapper = shallow(createElement(MyEnhancedComponent))
    const styleProp = wrapper.props().style
    expect(styleProp).to.be.a.instanceOf(Function)
    expect(styleProp.style).to.deep.equal({ color: 'red' })
  })

  it('should merge styles provided by the component user with default styles', () => {
    const MyEnhancedComponent = defaultStyle({ color: 'red' })(MyComponent)
    const wrapper = shallow(
      createElement(MyEnhancedComponent, {
        style: { cursor: 'pointer' },
      })
    )
    const styleProp = wrapper.props().style
    expect(styleProp.style).to.deep.equal({
      color: 'red',
      cursor: 'pointer',
    })
  })

  it('should also work if a substyle instance is provided as `style`', () => {
    const MyEnhancedComponent = defaultStyle({ color: 'red' })(MyComponent)
    const wrapper = shallow(
      createElement(MyEnhancedComponent, {
        style: createSubstyle({
          style: { cursor: 'pointer' },
        }),
      })
    )
    const styleProp = wrapper.props().style
    expect(styleProp.style).to.deep.equal({
      color: 'red',
      cursor: 'pointer',
    })
  })

  it('should accept a function mapping props to default styles as first argument', () => {
    const MyEnhancedComponent = defaultStyle(props => ({ color: props.color }))(
      MyComponent
    )
    const wrapper = shallow(
      createElement(MyEnhancedComponent, {
        style: { cursor: 'pointer' },
        color: 'black',
      })
    )
    const styleProp = wrapper.props().style
    expect(styleProp.style).to.deep.equal({
      color: 'black',
      cursor: 'pointer',
    })
  })

  it('should take a modifier selection function as second argument', () => {
    const MyEnhancedComponent = defaultStyle(
      {
        color: 'red',

        '&readOnly': {
          opacity: 0.5,
        },
      },
      props => ({
        '&readOnly': props.readOnly,
      })
    )(MyComponent)
    const wrapper = shallow(
      createElement(MyEnhancedComponent, { readOnly: true })
    )
    const styleProp = wrapper.props().style
    expect(styleProp.style).to.deep.equal({
      color: 'red',
      opacity: 0.5,
    })
  })

  it('should apply the selected modifiers also on the style supplied by the user', () => {
    const MyEnhancedComponent = defaultStyle({ color: 'red' }, props => ({
      '&readOnly': props.readOnly,
    }))(MyComponent)
    const wrapper = shallow(
      createElement(MyEnhancedComponent, {
        readOnly: true,
        style: {
          '&readOnly': {
            opacity: 0.5,
          },
        },
      })
    )
    const styleProp = wrapper.props().style
    expect(styleProp.style).to.deep.equal({
      color: 'red',
      opacity: 0.5,
    })
  })

  it('should give precendence to styles supplied by the user, regardless the modifiers specificity', () => {
    const MyEnhancedComponent = defaultStyle(
      {
        '&readOnly': {
          opacity: 0.5,
        },
      },
      props => ({
        '&readOnly': props.readOnly,
      })
    )(MyComponent)
    const wrapper = shallow(
      createElement(MyEnhancedComponent, {
        readOnly: true,
        style: {
          opacity: 0.7,
        },
      })
    )
    const styleProp = wrapper.props().style
    expect(styleProp.style).to.deep.equal({
      opacity: 0.7,
    })
  })

  it('should support depency injection via context for additional HoC to wrap the component', () => {
    const MyStyledComponent = defaultStyle()(MyComponent)
    const wrapInSection = WrappedComponent => props =>
      createElement('section', {}, createElement(WrappedComponent, props))
    const wrapper = shallow(createElement(MyStyledComponent), {
      context: {
        [ENHANCER_CONTEXT_NAME]: wrapInSection,
      },
    })
    expect(wrapper.get(0).type().type).to.equal('section')
  })

  it('should expose the wrapped component instance via `getWrappedInstance`', () => {
    class MyClassComponent extends Component {
      render() {
        return createElement('div')
      }
    }
    const MyEnhancedClassComponent = defaultStyle()(MyClassComponent)
    const instance = mount(createElement(MyEnhancedClassComponent)).instance()
    expect(instance.getWrappedInstance).to.be.a('function')
    expect(instance.getWrappedInstance()).to.be.an.instanceOf(MyClassComponent)

    const MyFunctionComponent = () => createElement('div')
    const MyEnhancedFunctionComponent = defaultStyle()(MyFunctionComponent)
    const instance2 = mount(
      createElement(MyEnhancedFunctionComponent)
    ).instance()
    expect(instance2.getWrappedInstance()).to.not.exist
  })

  it('should support providing a props decorator function via context', () => {
    const MyStyledComponent = defaultStyle()(MyComponent)
    const decorateProps = props => ({
      mapped: 'foobar',
    })
    const wrapper = mount(createElement(MyStyledComponent), {
      context: {
        [PROPS_DECORATOR_CONTEXT_NAME]: decorateProps,
      },
    })
    const containerProps = wrapper.find('MyComponent').find('div').props()
    expect(containerProps).to.not.have.property('style')
    expect(containerProps).to.not.have.property('className')
    expect(containerProps).to.have.property('mapped', 'foobar')
  })
})
{'fraction_non_alphanumeric': 0.13922891164959614, 'fraction_numerical': 0.0028312099258889166, 'mean_word_length': 2.940288713910761, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7381058', 'n_tokens_mistral': 3474, 'n_tokens_neox': 3395, 'n_words': 761}