<commit_before>import { component } from 'flight';
import withState from '.';

describe('withState', function () {
    function makeComponent(Component) {
        return component(withState, Component);
    }

    function initializeComponent(Component, fixture, opts) {
        return (new Component()).initialize(fixture || document.body, opts);
    }

    var ComponentA;
    var ComponentB;
    var ComponentC;
    var instanceAofA;
    var instanceBofA;
    var instanceAofB;
    var instanceAofC;

    // Initialize a component and attach it to the DOM
    beforeEach(function () {
        ComponentA = makeComponent(function () {
            this.attributes({
                initialNumber: 10
            });

            this.initialState({
                alive: true,
                count: 0,
                fn: () => true,
                currentNumber: function () {
                    return this.attr.initialNumber;
                },
                arr: [1, 2, 3]
            });
        });

        ComponentB = makeComponent(function () {
            this.initialState(function (existingState) {
                return {
                    alive: true
                };
            });
        });

        ComponentC = makeComponent(function () {});

        instanceAofA = initializeComponent(ComponentA);
        instanceBofA = initializeComponent(ComponentA);
        instanceAofB = initializeComponent(ComponentB);
        instanceAofC = initializeComponent(ComponentC);
    });

    afterEach(function () {
        ComponentA && ComponentA.teardownAll();
        ComponentB && ComponentB.teardownAll();
        ComponentC && ComponentC.teardownAll();
    });

    describe('initialState', function () {
        it('should add this.state', function () {
            expect(instanceAofA).toBeDefined();
            expect(instanceAofA.state).toBeDefined();
        });

        it('should add empty state if initialState is not called', function () {
            expect(instanceAofC).toBeDefined();
            expect(instanceAofC.state).toEqual({});
        });

        it('propagates initialState to this.state', function () {
            expect(instanceAofA.state.alive).toBe(true);
        });

        it('calls functions defined on initialState to this.state', function () {
            expect(instanceAofA.state.fn).toBe(true);
        });

        it('should be able to access attrs', function () {
            expect(instanceAofA.state.currentNumber).toBe(10);
        });

        it('should take a function that returns a full initial state data', function () {
            expect(instanceAofB.state.alive).toBe(true);
        });

        it('should throw on multiple calls', function () {
            expect(function () {
                makeComponent(function () {
                    this.initialState({
                        alive: true
                    });
                    this.initialState({
                        dead: true
                    });
                });
            }).toThrow();
        });
    });

    describe('this.state', function () {
        it('should not be shared between instances', function () {
            expect(instanceAofA.state).not.toBe(instanceBofA.state);
            instanceAofA.state.alive = false;
            expect(instanceBofA.state.alive).toBe(true);
        });
    });

    describe('this.replaceState', function () {
        it('should replace this.state', function () {
            instanceAofA.replaceState({
                count: 2
            });
            expect(instanceAofA.state.count).toBe(2);
            expect(instanceAofA.state.alive).not.toBeDefined();
        });

        it('handles no data', function () {
            instanceAofA.replaceState();
            expect(instanceAofA.state.alive).toBe(true);
        });
    });

    describe('this.mergeState', function () {
        it('should merge onto this.state', function () {
            instanceAofA.mergeState({
                count: 2
            });
            expect(instanceAofA.state.count).toBe(2);
            expect(instanceAofA.state.alive).toBe(true);
        });

        it('handles no data', function () {
            instanceAofA.mergeState();
            expect(instanceAofA.state.alive).toBe(true);
        });

        it('should not deep merge', function () {
            instanceAofA.mergeState({
                arr: []
            });
            expect(instanceAofA.state.arr.length).toBe(0);
        });

        it('should produce different objects', function () {
            var prevState = instanceAofA.state;
            instanceAofA.mergeState({
                alive: false
            });
            expect(instanceAofA.state).not.toBe(prevState);
        });
    });

    describe('this.toState', function () {
        it('should make a function that mutates the specified key', function () {
            var fn = instanceAofA.toState('count');
            fn.call(instanceAofA, 3);
            expect(instanceAofA.state.count).toBe(3);
        });
    });

    describe('this.fromState', function () {
        it('should make a function that returns data from the specified key', function () {
            var fn = instanceAofA.fromState('alive');
            expect(fn.call(instanceAofA)).toBe(true);
        });
    });

    describe('this.fromAttr', function () {
        it('should make a function that returns data from the specified attr key', function () {
            var fn = instanceAofA.fromAttr('initialNumber');
            expect(fn.call(instanceAofA)).toBe(10);
        });
    });

    describe('this.stateChanged', function () {
        it('should be advice-able to react to state changes', function () {
            var data;
            instanceAofA.after('stateChanged', function (state) {
                data = state;
            });
            var newState = {};
            instanceAofA.replaceState(newState);
            expect(data).toBe(newState);
        });
    });
});
<commit_msg>test: add test for previous state argument<commit_after>import { component } from 'flight';
import withState from '.';

describe('withState', function () {
    function makeComponent(Component) {
        return component(withState, Component);
    }

    function initializeComponent(Component, fixture, opts) {
        return (new Component()).initialize(fixture || document.body, opts);
    }

    var ComponentA;
    var ComponentB;
    var ComponentC;
    var instanceAofA;
    var instanceBofA;
    var instanceAofB;
    var instanceAofC;

    // Initialize a component and attach it to the DOM
    beforeEach(function () {
        ComponentA = makeComponent(function () {
            this.attributes({
                initialNumber: 10
            });

            this.initialState({
                alive: true,
                count: 0,
                fn: () => true,
                currentNumber: function () {
                    return this.attr.initialNumber;
                },
                arr: [1, 2, 3]
            });
        });

        ComponentB = makeComponent(function () {
            this.initialState(function (existingState) {
                return {
                    alive: true
                };
            });
        });

        ComponentC = makeComponent(function () {});

        instanceAofA = initializeComponent(ComponentA);
        instanceBofA = initializeComponent(ComponentA);
        instanceAofB = initializeComponent(ComponentB);
        instanceAofC = initializeComponent(ComponentC);
    });

    afterEach(function () {
        ComponentA && ComponentA.teardownAll();
        ComponentB && ComponentB.teardownAll();
        ComponentC && ComponentC.teardownAll();
    });

    describe('initialState', function () {
        it('should add this.state', function () {
            expect(instanceAofA).toBeDefined();
            expect(instanceAofA.state).toBeDefined();
        });

        it('should add empty state if initialState is not called', function () {
            expect(instanceAofC).toBeDefined();
            expect(instanceAofC.state).toEqual({});
        });

        it('propagates initialState to this.state', function () {
            expect(instanceAofA.state.alive).toBe(true);
        });

        it('calls functions defined on initialState to this.state', function () {
            expect(instanceAofA.state.fn).toBe(true);
        });

        it('should be able to access attrs', function () {
            expect(instanceAofA.state.currentNumber).toBe(10);
        });

        it('should take a function that returns a full initial state data', function () {
            expect(instanceAofB.state.alive).toBe(true);
        });

        it('should throw on multiple calls', function () {
            expect(function () {
                makeComponent(function () {
                    this.initialState({
                        alive: true
                    });
                    this.initialState({
                        dead: true
                    });
                });
            }).toThrow();
        });
    });

    describe('this.state', function () {
        it('should not be shared between instances', function () {
            expect(instanceAofA.state).not.toBe(instanceBofA.state);
            instanceAofA.state.alive = false;
            expect(instanceBofA.state.alive).toBe(true);
        });
    });

    describe('this.replaceState', function () {
        it('should replace this.state', function () {
            instanceAofA.replaceState({
                count: 2
            });
            expect(instanceAofA.state.count).toBe(2);
            expect(instanceAofA.state.alive).not.toBeDefined();
        });

        it('handles no data', function () {
            instanceAofA.replaceState();
            expect(instanceAofA.state.alive).toBe(true);
        });
    });

    describe('this.mergeState', function () {
        it('should merge onto this.state', function () {
            instanceAofA.mergeState({
                count: 2
            });
            expect(instanceAofA.state.count).toBe(2);
            expect(instanceAofA.state.alive).toBe(true);
        });

        it('handles no data', function () {
            instanceAofA.mergeState();
            expect(instanceAofA.state.alive).toBe(true);
        });

        it('should not deep merge', function () {
            instanceAofA.mergeState({
                arr: []
            });
            expect(instanceAofA.state.arr.length).toBe(0);
        });

        it('should produce different objects', function () {
            var prevState = instanceAofA.state;
            instanceAofA.mergeState({
                alive: false
            });
            expect(instanceAofA.state).not.toBe(prevState);
        });
    });

    describe('this.toState', function () {
        it('should make a function that mutates the specified key', function () {
            var fn = instanceAofA.toState('count');
            fn.call(instanceAofA, 3);
            expect(instanceAofA.state.count).toBe(3);
        });
    });

    describe('this.fromState', function () {
        it('should make a function that returns data from the specified key', function () {
            var fn = instanceAofA.fromState('alive');
            expect(fn.call(instanceAofA)).toBe(true);
        });
    });

    describe('this.fromAttr', function () {
        it('should make a function that returns data from the specified attr key', function () {
            var fn = instanceAofA.fromAttr('initialNumber');
            expect(fn.call(instanceAofA)).toBe(10);
        });
    });

    describe('this.stateChanged', function () {
        it('should be advice-able to react to state changes', function () {
            var data;
            instanceAofA.after('stateChanged', function (state) {
                data = state;
            });
            var newState = {};
            instanceAofA.replaceState(newState);
            expect(data).toBe(newState);
        });

        it('should recieve old state when state changes', function () {
            var result;
            var newState = {};
            instanceAofA.replaceState(newState);
            instanceAofA.after('stateChanged', function (state, oldState) {
                result = oldState;
            });
            instanceAofA.replaceState({});
            expect(result).toBe(newState);
        });
    });
});

{'fraction_non_alphanumeric': 0.12374929960778036, 'fraction_numerical': 0.0027215240534699432, 'mean_word_length': 1.805748933303391, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '7283471', 'n_tokens_mistral': 3262, 'n_tokens_neox': 3149, 'n_words': 641}