diff --git a/.gitignore b/.gitignore index 7a7bb3ec5b..d6f07f2888 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ node_modules/ #demo.js #demo.css .DS_Store -coverage \ No newline at end of file +coverage +unit.test.statistic.json \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js index 9f5ff5a10a..627531ffe2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,5 +1,14 @@ module.exports = function (grunt) { + const filterPath = function (patterns) { + return grunt.file.expand({ + filter: function (path) { + return !new RegExp(/__test__/g).test(path); + } + }, patterns); + }; + + // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON("package.json"), @@ -36,7 +45,7 @@ module.exports = function (grunt) { // 最基础的控件 baseJs: { - src: [ + src: filterPath([ "src/third/**/*.js", "src/base/pane.js", "src/base/single/single.js", @@ -53,7 +62,7 @@ module.exports = function (grunt) { "src/base/tree/ztree/list/listasynctree.js", "src/base/tree/ztree/list/listparttree.js", "src/base/**/*.js" - ], + ]), dest: "dist/base.js" }, // 实现好的一些基础实例 @@ -334,7 +343,7 @@ module.exports = function (grunt) { }, watch: { scripts: { - files: ["src/**/*.js", "src/**/*.less", "demo/js/**/*.js", "demo/app.js", "demo/version.js", "demo/config.js", "demo/less/**/*.less"], + files: ["src/**/*.js", "src/**/*.less", "demo/js/**/*.js", "demo/app.js", "demo/version.js", "demo/config.js", "demo/less/**/*.less", "!src/**/__test__/*.js"], tasks: ["less", "concat"], options: { spanw: true, @@ -345,7 +354,7 @@ module.exports = function (grunt) { options: { livereload: "<%= connect.options.livereload %>" }, - files: ["src/**/*.js", "src/**/*.less"] + files: ["src/**/*.js", "!src/**/__test__/*.js", "src/**/*.less"] } }, connect: { @@ -375,6 +384,45 @@ module.exports = function (grunt) { grunt.loadNpmTasks("grunt-contrib-clean"); grunt.loadNpmTasks("grunt-contrib-copy"); + grunt.registerTask("analyze", "code analysis", function () { + const authors = ["test_author_imp", "test_author_teller", "test_author_fay", "test_author_young", "test_author_windy", "test_author_lei.wang", "test_author_Kira", "test_author_Zhenfei.Li"]; + const info = []; + authors.forEach(function (auth) { + info.push({ + author: auth, + reg: new RegExp(auth, "g"), + count: 0 + }); + }); + const testFiles = grunt.file.expand(["src/**/*.test.js", "test/**/*.test.js"]); + testFiles.forEach(function (el) { + const fileStr = grunt.file.read(el); + authors.forEach(function (auth, idx) { + const res = fileStr.match(info[idx].reg); + if (res != null) { + info[idx].count += res.length; + } + }); + }); + + const todayStat = {}; + info.forEach(function (inf) { + todayStat[inf.author] = inf.count; + }); + const date = grunt.template.today("yyyy-mm-dd"); + const dest = "test/unit.test.statistic.json"; + let stat; + try { + stat = grunt.file.readJSON(dest); + } catch (e) { + stat = {}; + } + if (!stat.date || stat.date === {}) { + stat[date] = todayStat; + } + grunt.file.write(dest, JSON.stringify(stat)); + }); + var defaultTask = ["clean", "less", "concat", "connect", "watch"]; grunt.registerTask("default", defaultTask); grunt.registerTask("compile", function () { diff --git a/changelog.md b/changelog.md index 37f2cf76d1..a064e127d6 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,7 @@ # 更新日志 +2.0(2019-07) +- input及其派生编辑控件在PAUSE事件之前会触发CHANGE事件 + 2.0(2019-06) - 单选下拉树支持搜索与异步加载节点 - 提供了AES加密方法 @@ -9,7 +12,7 @@ - 时分秒控件支持自定义时间显示格式和是否可编辑 - 日期/时间/日期区间/时间区间支持自定义日期选择范围和是否可编辑 - 日期/时间/日期区间/时间区间支持自定义日期显示格式和是否可编辑 -- 增加less函数: 字体资源添加函数addFontRe和字体激活函数activeFont +- 增加less函数: 字体资源添加函数addFontRes和字体激活函数activeFont > @fontList: "dec", "report"; > .addFontRes("dec"); diff --git a/karma.conf.js b/karma.conf.js index c57e74c93c..a54a552bba 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -14,6 +14,9 @@ module.exports = function (config) { // list of files / patterns to load in the browser files: [ + "src/css/core/**/*.css", + "src/css/theme/**/*.css", + "src/css/base/**/*.css", "src/core/foundation.js", "src/core/lodash.js", "src/core/base.js", diff --git a/package.json b/package.json index 661572b6f5..fc541579d7 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,8 @@ "build": "grunt build", "compile": "grunt compile", "fake": "grunt fake-build", - "test": "karma start" + "test": "karma start", + "analyze": "grunt analyze" }, "repository": { "type": "git", diff --git a/src/base/__test__/button.test.js b/src/base/__test__/button.test.js new file mode 100644 index 0000000000..3687d98f94 --- /dev/null +++ b/src/base/__test__/button.test.js @@ -0,0 +1,139 @@ +/** + * Created by windy on 2018/01/23. + */ +describe("ButtonTest", function () { + + /** + * test_author_windy + */ + it("Click点击触发事件", function (done) { + var button = BI.Test.createWidget({ + type: "bi.button", + text: "CCC", + handler: function () { + this.setText("click"); + } + }); + BI.nextTick(function () { + button.element.click(); + expect(button.element.children(".bi-text").text()).to.equal("click"); + button.destroy(); + done(); + }); + + }); + + + /** + * test_author_windy + */ + it("MouseDown触发事件", function (done) { + var button = BI.Test.createWidget({ + type: "bi.button", + text: "CCC", + trigger: "mousedown", + handler: function () { + this.setText("click"); + } + }); + BI.nextTick(function () { + button.element.mousedown(); + expect(button.element.children(".bi-text").text()).to.equal("click"); + button.destroy(); + done(); + }); + + }); + + /** + * test_author_windy + */ + it("MouseUp触发事件", function (done) { + var button = BI.Test.createWidget({ + type: "bi.button", + text: "CCC", + trigger: "mouseup", + handler: function () { + this.setText("click"); + } + }); + BI.nextTick(function () { + button.element.mousedown(); + button.element.mouseup(); + expect(button.element.children(".bi-text").text()).to.equal("click"); + button.destroy(); + done(); + }); + + }); + + /** + * test_author_windy + */ + it("doubleClick触发事件", function (done) { + var button = BI.Test.createWidget({ + type: "bi.button", + text: "CCC", + trigger: "dblclick", + handler: function () { + this.setText("click"); + } + }); + BI.nextTick(function () { + button.element.dblclick(); + expect(button.element.children(".bi-text").text()).to.equal("click"); + button.destroy(); + done(); + }); + + }); + + /** + * test_author_windy + */ + it("LongClick触发事件", function (done) { + var clickNum = 0; + var button = BI.Test.createWidget({ + type: "bi.button", + text: "CCC", + trigger: "lclick", + listeners: [{ + eventName: BI.Button.EVENT_CHANGE, + action: function () { + clickNum++; + } + }] + }); + BI.nextTick(function () { + button.element.mousedown(); + BI.delay(function () { + expect(clickNum).to.equal(2); + button.destroy(); + done(); + }, 360); + }); + + }); + + it("LongClick触发事件", function (done) { + var clickNum = 0; + var button = BI.Test.createWidget({ + type: "bi.button", + text: "CCC", + trigger: "lclick", + listeners: [{ + eventName: BI.Button.EVENT_CHANGE, + action: function () { + clickNum++; + } + }] + }); + BI.nextTick(function () { + button.element.dblclick(); + expect(button.element.children(".bi-text").text()).to.equal("click"); + button.destroy(); + done(); + }); + + }); +}); diff --git a/src/base/__test__/text.test.js b/src/base/__test__/text.test.js new file mode 100644 index 0000000000..332caa8ab1 --- /dev/null +++ b/src/base/__test__/text.test.js @@ -0,0 +1,84 @@ +/** + * Created by windy on 2018/01/23. + */ +describe("TextTest", function () { + + /** + * test_author_windy + */ + it("setText", function () { + var text = BI.Test.createWidget({ + type: "bi.text" + }); + text.setText("AAA"); + expect(text.element.text()).to.equal("AAA"); + text.destroy(); + }); + + /** + * test_author_windy + */ + it("setStyle", function () { + var text = BI.Test.createWidget({ + type: "bi.text" + }); + text.setStyle({"color": "red"}); + expect(text.element.getStyle("color")).to.equal("rgb(255, 0, 0)"); + text.destroy(); + }); + + /** + * test_author_windy + */ + it("高亮doHighlight", function () { + var text = BI.Test.createWidget({ + type: "bi.text", + text: "AAA", + highLight: true + }); + expect(text.element.getStyle("color")).to.equal("rgb(54, 133, 242)"); + text.destroy(); + }); + + /** + * test_author_windy + */ + it("标红doRedMark", function () { + var text = BI.Test.createWidget({ + type: "bi.text", + text: "我是要标红的A", + keyword: "A" + }); + expect(text.element.children(".bi-keyword-red-mark").length).to.not.equal(0); + text.destroy(); + }); + + + /** + * test_author_windy + */ + it("取消高亮undoHighlight", function () { + var text = BI.Test.createWidget({ + type: "bi.text", + text: "AAA", + highLight: true + }); + text.unHighLight(); + expect(text.element.getStyle("color")).to.not.equal("rgb(54, 133, 242)"); + text.destroy(); + }); + + /** + * test_author_windy + */ + it("取消标红undoRedMark", function () { + var text = BI.Test.createWidget({ + type: "bi.text", + text: "我是要标红的A", + keyword: "A" + }); + text.unRedMark(); + expect(text.element.children(".bi-keyword-red-mark").length).to.equal(0); + text.destroy(); + }); +}); diff --git a/src/core/utils/chinesePY.js b/src/core/utils/chinesePY.js index 652ad3b2f3..de53fc1bf5 100644 --- a/src/core/utils/chinesePY.js +++ b/src/core/utils/chinesePY.js @@ -387,14 +387,14 @@ return (oMultiDiff[uni] ? oMultiDiff[uni] : (_ChineseFirstPY.charAt(uni - 19968))); }; - var _mkPYRslt = function (arr) { + var _mkPYRslt = function (arr, ignoreMulti) { var arrRslt = [""], k, multiLen = 0; for (var i = 0, len = arr.length; i < len; i++) { var str = arr[i]; var strlen = str.length; // 多音字过多的情况下,指数增长会造成浏览器卡死,超过20完全卡死,18勉强能用,考虑到不同性能最好是16或者14 // 超过14个多音字之后,后面的都用第一个拼音 - if (strlen == 1 || multiLen > 14) { + if (strlen == 1 || multiLen > 14 || ignoreMulti) { var tmpStr = str.substring(0, 1); for (k = 0; k < arrRslt.length; k++) { arrRslt[k] += tmpStr; @@ -419,7 +419,8 @@ }; _.extend(BI, { - makeFirstPY: function (str) { + makeFirstPY: function (str, options) { + options = options || {}; if (typeof (str) !== "string") {return "" + str;} var arrResult = []; // 保存中间结果的数组 for (var i = 0, len = str.length; i < len; i++) { @@ -429,7 +430,7 @@ arrResult.push(_checkPYCh(ch)); } // 处理arrResult,返回所有可能的拼音首字母串数组 - return _mkPYRslt(arrResult); + return _mkPYRslt(arrResult, options.ignoreMulti); } }); })(); \ No newline at end of file diff --git a/src/core/widget.js b/src/core/widget.js index d5d5dca552..3b9cbff344 100644 --- a/src/core/widget.js +++ b/src/core/widget.js @@ -193,17 +193,16 @@ * @private */ _mount: function (force, deep, lifeHook, predicate) { + var self = this; if (!force && (this._isMounted || !this.isVisible() || this.__asking === true || !(this._isRoot === true || (this._parent && this._parent._isMounted === true)))) { return false; } lifeHook !== false && this.beforeMount && this.beforeMount(); this._isMounted = true; this._mountChildren && this._mountChildren(); - if (BI.isNotNull(this._parent)) { - !this._parent.isEnabled() && this._setEnable(false); - !this._parent.isValid() && this._setValid(false); - } BI.each(this._children, function (i, widget) { + !self.isEnabled() && widget._setEnable(false); + !self.isValid() && widget._setValid(false); widget._mount && widget._mount(deep ? force : false, deep, lifeHook, predicate); }); lifeHook !== false && this.mounted && this.mounted(); diff --git a/test/widget/button.test.js b/test/widget/button.test.js deleted file mode 100644 index 18faf06db6..0000000000 --- a/test/widget/button.test.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Created by windy on 2018/01/23. - */ -describe("ButtonTest", function () { - - /** - * test_author_windy - */ - it("EventClickTest", function (done) { - var button = BI.Test.createWidget({ - type: "bi.button", - text: "CCC", - handler: function () { - this.setText("click"); - } - }); - BI.nextTick(function () { - button.element.click(); - expect(button.element.children(".bi-text").text()).to.equal("click"); - button.destroy(); - done(); - }); - - }); -}); diff --git a/test/widget/text.test.js b/test/widget/text.test.js deleted file mode 100644 index 6085f76720..0000000000 --- a/test/widget/text.test.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Created by windy on 2018/01/23. - */ -describe("TextTest", function () { - - /** - * test_author_windy - */ - it("setText", function () { - var text = BI.Test.createWidget({ - type: "bi.text" - }); - text.setText("AAA"); - expect(text.element.text()).to.equal("AAA"); - text.destroy(); - }); - - /** - * test_author_windy - */ - it("setStyle", function () { - var text = BI.Test.createWidget({ - type: "bi.text" - }); - text.setStyle({"color": "red"}); - expect(text.element.getStyle("color")).to.equal("rgb(255, 0, 0)"); - text.destroy(); - }); -});