<|start_filename|>kao.js<|end_filename|>
module.exports = {
  root: "build",
  webpack: {
    umd: {
      entry: "./src/model.js",
      library: "Model",
      filename: './model.js',
    },
    externals: {
      "manba": "manba"
    }
  }
};


<|start_filename|>src/utils.js<|end_filename|>

export default {
  isObject(input) {
    return Object.prototype.toString.call(input) === '[object Object]';
  },
  isArray(input) {
    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
  },
  isDate(input) {
    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
  },
  isNumber(input) {
    return input instanceof Number || Object.prototype.toString.call(input) === '[object Number]';
  },
  isString(input) {
    return input instanceof String || Object.prototype.toString.call(input) === '[object String]';
  },
  isBoolean(input) {
    return typeof input == 'boolean';
  },
  isFunction(input) {
    return typeof input == 'function';
  },
  deepCopy(data) {
    let copyOne = null;
    if (this.isObject(data)) {
      copyOne = {};
      for (const key in data) {
        copyOne[key] = this.deepCopy(data[key]);
      }
    } else if (this.isArray(data)) {
      copyOne = [];
      for (const index of data) {
        copyOne.push(this.deepCopy(index));
      }
    } else {
      copyOne = data;
    }
    return copyOne;
  },
  deepFreeze(obj) {
    const that = this;
    Object.freeze(obj);
    Object.keys(obj).forEach((key, value) => {
      if (that.isObject(obj[key])) {
        this.deepFreeze(obj[key]);
      }
    });
    return obj;
  },
  mergeArray(arr1, arr2) {
    for (var i = 0; i < arr1.length; i++) {
      for (let j = 0; j < arr2.length; j++) {
        if (arr1[i] === arr2[j]) {
          arr1.splice(i, 1);
        }
      }
    }
    for (var i = 0; i < arr2.length; i++) {
      arr1.push(arr2[i]);
    }
    return arr1;
  },
  extend: function () {
    var options, name, src, copy, copyIsArray, clone,
      target = arguments[0] || {},
      i = 1,
      length = arguments.length,
      deep = false;
    if (typeof target === "boolean") {
      deep = target;
      target = arguments[1] || {};
      i = 2;
    }
    if (typeof target !== "object" && !this.isFunction(target)) {
      target = {};
    }
    if (length === i) {
      target = this;
      --i;
    }
    for (; i < length; i++) {
      if ((options = arguments[i]) != null) {
        for (name in options) {
          src = target[name];
          copy = options[name];
          if (target === copy) {
            continue;
          }
          if (deep && copy && (this.isPlainObject(copy) || (copyIsArray = this.isArray(copy)))) {
            if (copyIsArray) {
              copyIsArray = false;
              clone = src && this.isArray(src) ? src : [];
            } else {
              clone = src && this.isPlainObject(src) ? src : {};
            }
            target[name] = this.extend(deep, clone, copy);
          } else if (copy !== undefined) {
            target[name] = copy;
          }
        }
      }
    }
    return target;
  },
  add(arg1, arg2) {
    let s1 = arg1.toString();
    let s2 = arg2.toString();
    let arg1Arr = s1.split(".");
    let arg2Arr = s2.split(".");
    let d1 = arg1Arr.length == 2 ? arg1Arr[1] : "";
    let d2 = arg2Arr.length == 2 ? arg2Arr[1] : "";
    let maxLen = Math.max(d1.length, d2.length);
    let m = Math.pow(10, maxLen);
    return Number(((s1 * m + s2 * m) / m).toFixed(maxLen));
  },
  sub(arg1, arg2) {
    return this.add(arg1, -arg2);
  },
  mul(arg1, arg2) {
    let m = 0;
    let s1 = arg1.toString();
    let s2 = arg2.toString();
    try { m += s1.split(".")[1].length } catch (e) {}
    try { m += s2.split(".")[1].length } catch (e) {}
    return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
  },
  div(arg1, arg2) {
    let t1 = 0;
    let t2 = 0;
    try { t1 = arg1.toString().split(".")[1].length } catch (e) {}
    try { t2 = arg2.toString().split(".")[1].length } catch (e) {}
    let r1 = Number(arg1.toString().replace(".", ""));
    let r2 = Number(arg2.toString().replace(".", ""));
    return this.mul((r1 / r2) , Math.pow(10, t2 - t1));
  }
};


<|start_filename|>test/test.js<|end_filename|>
// let Model = require("../build/model");
let Model = require("../src/model");
var expect = require('chai').expect;
(function () {
  'use strict';
  const FORMAT = {
    L: "l",
    LL: "ll",
    KK: "k",
    GET: function (data) {
      return "get" + data;
    }
  }

  let Basic = new Model({
    "source": Date,
    "description": {
      type: String,
      format: FORMAT.GET
    },
    "tags": [
      0
    ],
    "companyId": {
      type: Model.String,
      default: "测试"
    },
    "rate": {
      type: Model.Number,
      computed: function (data) {
        return data.rateFrom + 3;
      }
    },
    "id": 0
  });


  let Edu = new Model({
    "startTime": {
      type: Date,
      format: FORMAT.L
    },
    "degree": 0,
    "major": "",
    "school": "",
    "endTime": 0,
    "takeTime": "",
    "id": ""
  });


  let User = new Model({
    "basic": Basic,
    "bind": {},
    "edu": [Edu]
  });

  describe('judge type object', function () {

    let TypeModel = new Model({
      type: String,
      list: [{
        type: Number,
        default: 1
      }],
      object: {
        type: Boolean,
        id: 0,
      },
      normal: {
        type: Number
      }
    });

    it('judge type object parse', function () {
      expect(TypeModel.parse({list:["12"]})).to.be.deep.equal({
        type: null,
        list: [12],
        object: {
          type: null,
          id: null,
        },
        normal: null
      });
    });

    it('judge type object dispose', function () {
      expect(TypeModel.dispose({
        type: 123,
        list: ["12"],
        object: {
          type: false,
          id: "23"
        },
        normal: "123"
      })).to.be.deep.equal({
        type: "123",
        list: [12],
        object: {
          type: false,
          id: 23,
        },
        normal: 123
      });
    });

  });

  describe('basic model', function () {


    let value = User.parse({
      basic: {
        id: "123123",
        source: "Tue Apr 19 2016 21:46:11 GMT+0800 (CST)",
        tags: [
          "12", "32"
        ],
        rateFrom: 1
      }
    });



    it('parse full model', function () {
      expect(value).to.be.deep.equal({
        bind: null,
        edu: [],
        basic: {
          description: null,
          companyId: '测试',
          rate: null,
          id: 123123,
          source: '2016-04-19',
          tags: [12, 32],
          rateFrom: 1
        }
      });

    });

    it('parse empty value', function () {
      expect(User.parse({})).to.be.deep.equal({
        bind: null,
        edu: [],
        basic: {
          description: null,
          companyId: "测试",
          rate: null,
          id: null,
          source: null,
          tags: []
        }
      });

    });


    it('dispose post data', function () {
      expect(User.dispose(value)).to.be.deep.equal({
        edu: [],
        basic: {
          companyId: '测试',
          id: 123123,
          rate: 4,
          source: '2016-04-19T00:00:00+08:00',
          tags: [12, 32]
        }
      });
    });


    it('dispose post data2', function () {
      let Test = new Model({
        id:0
      });
      expect(Test.dispose([{id:null}])).to.be.deep.equal([{}]);
    });

    

    it('disposeDateFormat', function () {
      let Test1 = new Model({
        source: Model.DATE
      });

      Model.config({
        disposeDateFormat(date) {
          return new Date(date).getTime();
        }
      })
      expect(Test1.dispose({
        source: '2016-04-19'
      })).to.be.deep.equal({
        source: 1461024000000
      });

    });

    let Test2 = new Model({
      money: {
        type: Number,
        unit: Model.Q
      }
    });

    it('parseMoney', function () {
      expect(Test2.parse({
        money: 32209.99
      })).to.be.deep.equal({
        money: 32.20999
      });
    });

    it('disposeMoney', function () {
      expect(Test2.dispose({
        money: 32.200
      })).to.be.deep.equal({
        money: 32200
      });
    });

  });



  describe('parse, dispose function', function () {

    let pdModel = new Model({
      parse: {
        type: Number,
        parse(data) {
          return data.id + 1
        }
      },
      dispose: {
        type: Number,
        parse(data) {
          return data.dispose * 10
        },
        dispose(data) {
          return data.dispose / 10
        }
      },
      id: 0
    });

    it('judge type object parse', function () {
      expect(pdModel.parse({id: 1, dispose: 10})).to.be.deep.equal({
        parse: 2,
        dispose: 100,
        id: 1,
      });
    });

    it('judge type object dispose', function () {
      expect(pdModel.dispose({
        id: 1, dispose: 10
      })).to.be.deep.equal({
        dispose: 1,
        id: 1
      });
    });

  });

}());
