text: "use strict";
  
  const log = require("../../src/log");
  const expect = require("chai").expect;
  const stub = require("sinon").stub;
  const mergeConfig = require("../../src/helper").mergeConfig;
  const TestUtil = require("../util");
  
  describe("mergeConfig", function () {
  	it("should mutate object", function () {
  		const config = {
  			ip: "default",
  		};
  
  		expect(
  			mergeConfig(config, {
  				ip: "overridden",
  			})
  		).to.deep.equal({
  			ip: "overridden",
  		});
  
  		expect(config).to.deep.equal({
  			ip: "overridden",
  		});
  	});
  
  	it("should merge new properties", function () {
  		expect(
  			mergeConfig(
  				{
  					ip: "default",
  					newProp: "this should appear too",
  				},
  				{
  					ip: "overridden",
  				}
  			)
  		).to.deep.equal({
  			ip: "overridden",
  			newProp: "this should appear too",
  		});
  	});
  
  	it("should extend objects", function () {
  		expect(
  			mergeConfig(
  				{
  					tlsOptions: {},
  				},
  				{
  					tlsOptions: {
  						user: "test",
  						thing: 123,
  					},
  				}
  			)
  		).to.deep.equal({
  			tlsOptions: {
  				user: "test",
  				thing: 123,
  			},
  		});
  	});
  
  	it("should warn for unknown top level keys", function () {
  		let warning = "";
  		stub(log, "warn").callsFake(TestUtil.sanitizeLog((str) => (warning += str)));
  
  		expect(
  			mergeConfig(
  				{
  					optionOne: 123,
  				},
  				{
  					optionOne: 456,
  					optionTwo: 789,
  				}
  			)
  		).to.deep.equal({
  			optionOne: 456,
  			optionTwo: 789,
  		});
  
  		log.warn.restore();
  		expect(warning).to.equal('Unknown key "optionTwo", please verify your config.\n');
  	});
  
  	it("should not warn for unknown second level keys", function () {
  		expect(
  			mergeConfig(
  				{
  					optionOne: {
  						subOne: 123,
  					},
  				},
  				{
  					optionOne: {
  						subOne: 123,
  						subTwo: 123,
  					},
  				}
  			)
  		).to.deep.equal({
  			optionOne: {
  				subOne: 123,
  				subTwo: 123,
  			},
  		});
  	});
  
  	it("should allow changing nulls", function () {
  		expect(
  			mergeConfig(
  				{
  					oidentd: null,
  				},
  				{
  					oidentd: "some path",
  				}
  			)
  		).to.deep.equal({
  			oidentd: "some path",
  		});
  	});
  
  	it("should allow changing nulls with objects", function () {
  		expect(
  			mergeConfig(
  				{
  					webirc: null,
  				},
  				{
  					webirc: {
  						serverone: "password",
  						servertwo: "password2",
  					},
  				}
  			)
  		).to.deep.equal({
  			webirc: {
  				serverone: "password",
  				servertwo: "password2",
  			},
  		});
  	});
  
  	it("should allow changing nulls with objects that has function", function () {
  		const callbackFunction = () => ({});
  
  		expect(
  			mergeConfig(
  				{
  					webirc: null,
  				},
  				{
  					webirc: {
  						servercb: callbackFunction,
  					},
  				}
  			)
  		).to.deep.equal({
  			webirc: {
  				servercb: callbackFunction,
  			},
  		});
  	});
  
  	it("should keep new properties inside of objects", function () {
  		expect(
  			mergeConfig(
  				{
  					nestedOnce: {
  						ip: "default",
  					},
  					nestedTwice: {
  						thing: "default",
  						nested: {
  							otherThing: "also default",
  							newThing: "but also this",
  						},
  					},
  				},
  				{
  					nestedOnce: {},
  					nestedTwice: {
  						nested: {
  							otherThing: "overridden",
  						},
  					},
  				}
  			)
  		).to.deep.equal({
  			nestedOnce: {
  				ip: "default",
  			},
  			nestedTwice: {
  				thing: "default",
  				nested: {
  					otherThing: "overridden",
  					newThing: "but also this",
  				},
  			},
  		});
  	});
  
  	it("should not merge arrays", function () {
  		expect(
  			mergeConfig(
  				{
  					test: ["sqlite", "text"],
  				},
  				{
  					test: ["sqlite"],
  				}
  			)
  		).to.deep.equal({
  			test: ["sqlite"],
  		});
  
  		expect(
  			mergeConfig(
  				{
  					test: ["sqlite", "text"],
  				},
  				{
  					test: [],
  				}
  			)
  		).to.deep.equal({
  			test: [],
  		});
  	});
  
  	it("should change order in arrays", function () {
  		expect(
  			mergeConfig(
  				{
  					test: ["sqlite", "text"],
  				},
  				{
  					test: ["text", "sqlite"],
  				}
  			)
  		).to.deep.equal({
  			test: ["text", "sqlite"],
  		});
  	});
  
  	it("should only merge same type", function () {
  		stub(log, "warn");
  
  		expect(
  			mergeConfig(
  				{
  					shouldBeObject: {
  						thing: "yes",
  					},
  				},
  				{
  					shouldBeObject: "bad type",
  				}
  			)
  		).to.deep.equal({
  			shouldBeObject: {
  				thing: "yes",
  			},
  		});
  
  		expect(
  			mergeConfig(
  				{
  					shouldBeString: "string",
  				},
  				{
  					shouldBeString: 1234567,
  				}
  			)
  		).to.deep.equal({
  			shouldBeString: "string",
  		});
  
  		log.warn.restore();
  	});
  });
  