import set from '../set';

describe('Utils/Immutable/set', () => {
    test('throws error if the path is not a string or array', () => {
        expect(() => set({}, 0, undefined)).toThrowError();
    });
    test('if the obj argument is not an object, it uses an empty object', () => {
        expect(set('', 'foo', 'bar')).toEqual({ foo: 'bar' });
        expect(set(null, 'foo', 'bar')).toEqual({ foo: 'bar' });
        expect(set(0, 'foo', 'bar')).toEqual({ foo: 'bar' });
    });
    test('sets the correct prop at object level 1, does not touch the original', () => {
        const obj = {};
        const res = set(obj, 'foo', 'bar');
        expect(res).toEqual({ foo: 'bar' });
        expect(obj).toEqual({});
        expect(res).not.toBe(obj);
    });
    test('sets the correct prop at any deeper object level, does not touch the original', () => {
        const obj = {};
        const res = set(obj, 'a.much.deeper.level.than.before', 'bar');
        expect(res).toEqual({ a: { much: { deeper: { level: { than: { before: 'bar' } } } } } });
        expect(obj).toEqual({});
        expect(res).not.toBe(obj);
    });
    test('sets the correct prop at array level 1, does not touch the original', () => {
        const obj = [];
        const res = set(obj, '0', 'bar');
        expect(res).toEqual(['bar']);
        expect(obj).toEqual([]);
        expect(res).not.toBe(obj);
    });
    test('sets the correct prop at any deeper array level, does not touch the original', () => {
        const obj = [[[]]];
        const res = set(obj, '0.0.0', 'bar');
        expect(res).toEqual([[['bar']]]);
        expect(obj).toEqual([[[]]]);
        expect(res).not.toBe(obj);
    });
    test('sets the correct prop at any combination of object and array levels, does not touch the original', () => {
        const obj = ['test', { foo: [1, 2, [3, 4, { baz: '' }]] }];
        const res = set(obj, '1.foo.2.2.baz', 'bar');
        expect(res).toEqual(['test', { foo: [1, 2, [3, 4, { baz: 'bar' }]] }]);
        expect(obj).toEqual(['test', { foo: [1, 2, [3, 4, { baz: '' }]] }]);
        expect(res).not.toBe(obj);
    });
});
