浏览代码

draggable settings are covered by unittests

Ievgen Naida 5 年之前
父节点
当前提交
6a628a0933

+ 3 - 1
.eslintignore

@@ -7,4 +7,6 @@ tests/src
 ./tests/js/src
 ./tests/src
 ./tests/tests/
-tests/tests/
+tests/tests/
+tests/*.js
+tests/*.js.map

+ 74 - 26
lib/animation-timeline.js

@@ -516,21 +516,40 @@ var TimelineStyleUtils = /*#__PURE__*/function () {
      * @param row keyframe row.
      * @param propertyName property to get.
      * @param defaultValue default value to return
+     * @param reverseOrder reverse styling order: global, row, keyframe
      */
-    value: function getKeyframeStyle(keyframe, row, options, propertyName, defaultValue) {
-      if (keyframe && keyframe) {
-        var style = keyframe;
+    value: function getKeyframeStyle(keyframeStyle, rowStyle, options, propertyName, defaultValue) {
+      var reverseOrder = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
+      // Don't spawn new array for the normal order.
+      var styles = null;
+
+      if (keyframeStyle) {
+        var style = keyframeStyle;
 
         if (style[propertyName] !== undefined) {
-          return style[propertyName];
+          var value = style[propertyName];
+
+          if (!reverseOrder) {
+            return value;
+          }
+
+          styles = styles || [];
+          styles.push(value);
         }
       }
 
-      if (row && row.keyframesStyle) {
-        var _style = row.keyframesStyle;
+      if (rowStyle && rowStyle.keyframesStyle) {
+        var _style = rowStyle.keyframesStyle;
 
         if (_style[propertyName] !== undefined) {
-          return _style[propertyName];
+          var _value = _style[propertyName];
+
+          if (!reverseOrder) {
+            return _value;
+          }
+
+          styles = styles || [];
+          styles.push(_value);
         }
       }
 
@@ -540,11 +559,18 @@ var TimelineStyleUtils = /*#__PURE__*/function () {
         var _style2 = globalRowStyle.keyframesStyle;
 
         if (_style2[propertyName] !== undefined) {
-          return _style2[propertyName];
+          var _value2 = _style2[propertyName];
+
+          if (!reverseOrder) {
+            return _value2;
+          }
+
+          styles = styles || [];
+          styles.push(_value2);
         }
       }
 
-      return defaultValue;
+      return reverseOrder && styles && styles.length > 0 ? styles[styles.length - 1] : defaultValue;
     }
     /**
      * Get row style from default settings or overrides by a row settings.
@@ -553,11 +579,22 @@ var TimelineStyleUtils = /*#__PURE__*/function () {
   }, {
     key: "getRowStyle",
     value: function getRowStyle(rowStyle, options, propertyName, defaultValue) {
+      var reverseOrder = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
+      // Don't spawn new array for the normal order.
+      var styles = null;
+
       if (rowStyle) {
         var style = rowStyle;
 
         if (style[propertyName] !== undefined) {
-          return style[propertyName];
+          var results = style[propertyName];
+
+          if (!reverseOrder) {
+            return results;
+          }
+
+          styles = styles || [];
+          styles.push(results);
         }
       }
 
@@ -567,11 +604,18 @@ var TimelineStyleUtils = /*#__PURE__*/function () {
         var _style3 = globalRowStyle;
 
         if (_style3[propertyName] !== undefined) {
-          return _style3[propertyName];
+          var _results = _style3[propertyName];
+
+          if (!reverseOrder) {
+            return _results;
+          }
+
+          styles = styles || [];
+          styles.push(_results);
         }
       }
 
-      return defaultValue;
+      return reverseOrder && styles && styles.length > 0 ? styles[styles.length - 1] : defaultValue;
     }
     /**
      * Get current row height from styling
@@ -597,6 +641,18 @@ var TimelineStyleUtils = /*#__PURE__*/function () {
     value: function getRowMarginBottom(rowStyle, options) {
       return TimelineStyleUtils.getRowStyle(rowStyle, options, 'marginBottom', 0);
     }
+  }, {
+    key: "keyframeDraggable",
+    value: function keyframeDraggable(keyframe, rowStyle, options) {
+      var defaultValue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
+      return TimelineStyleUtils.getKeyframeStyle(keyframe, rowStyle, options, 'draggable', defaultValue, true);
+    }
+  }, {
+    key: "stripeDraggable",
+    value: function stripeDraggable(rowStyle, options) {
+      var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
+      return TimelineStyleUtils.getRowStyle(rowStyle, options, 'stripeDraggable', defaultValue, true);
+    }
   }]);
 
   return TimelineStyleUtils;
@@ -2977,24 +3033,16 @@ var timeline_Timeline = /*#__PURE__*/function (_TimelineEventsEmitte) {
       };
 
       var filteredElements = elements.filter(function (element) {
-        if (element.type === TimelineElementType.Keyframe) {
-          var draggable = true;
-
-          if (_this8._options) {
-            draggable = (_this8._options.keyframesDraggable === undefined ? true : !!_this8._options.keyframesDraggable) && (element.keyframe.draggable === undefined ? true : !!element.keyframe.draggable);
-          }
+        if (!element) {
+          return false;
+        }
 
-          if (!draggable) {
+        if (element.type === TimelineElementType.Keyframe) {
+          if (!TimelineStyleUtils.keyframeDraggable(element.keyframe, element.row, _this8._options)) {
             return false;
           }
         } else if (element.type === TimelineElementType.Stripe) {
-          var _draggable = true;
-
-          if (_this8._options) {
-            _draggable = (_this8._options.stripesDraggable === undefined ? true : !!_this8._options.stripesDraggable) && (element.row.stripeDraggable === undefined ? true : !!element.row.stripeDraggable);
-          }
-
-          if (!_draggable) {
+          if (!TimelineStyleUtils.stripeDraggable(element.row, _this8._options)) {
             return false;
           }
         } else if (element.type === TimelineElementType.Row) {

文件差异内容过多而无法显示
+ 0 - 0
lib/animation-timeline.min.js


+ 4 - 0
lib/settings/styles/TimelineRowStyle.d.ts

@@ -8,6 +8,10 @@ export interface TimelineRowStyle {
     color?: string;
     selectedColor?: string;
     marginBottom?: number;
+    /**
+     * keyframes stripe is draggable.
+     */
+    stripeDraggable?: boolean;
     /**
      * Keyframes bounds stripe height.
      * 'auto' to automatically calculate.

+ 3 - 0
lib/settings/styles/timelineStyle.d.ts

@@ -1,4 +1,7 @@
 import { TimelineCapShape } from '../../enums/timelineCapShape';
+/**
+ * Timeline indicator style
+ */
 export interface TimelineStyle {
     width?: number;
     marginTop?: number;

+ 0 - 8
lib/timelineRow.d.ts

@@ -2,12 +2,4 @@ import { TimelineKeyframe } from './timelineKeyframe';
 import { TimelineRowStyle } from './settings/styles/timelineRowStyle';
 export interface TimelineRow extends TimelineRowStyle {
     keyframes?: Array<TimelineKeyframe>;
-    /**
-     * keyframes stripe is draggable.
-     */
-    stripeDraggable?: boolean;
-    /**
-     * keyframes stripe is draggable.
-     */
-    keyframesDraggable?: boolean;
 }

+ 6 - 3
lib/utils/timelineStyleUtils.d.ts

@@ -1,7 +1,7 @@
 import { TimelineRow } from '../timelineRow';
-import { TimelineKeyframe } from '../timelineKeyframe';
 import { TimelineOptions } from '../settings/timelineOptions';
 import { TimelineRowStyle } from '../settings/styles/timelineRowStyle';
+import { TimelineKeyframeStyle } from '../settings/styles/timelineKeyframeStyle';
 export declare class TimelineStyleUtils {
     /**
      * Get keyframe style from a keyframe, than from a row, than from a global settings.
@@ -9,12 +9,13 @@ export declare class TimelineStyleUtils {
      * @param row keyframe row.
      * @param propertyName property to get.
      * @param defaultValue default value to return
+     * @param reverseOrder reverse styling order: global, row, keyframe
      */
-    static getKeyframeStyle<T>(keyframe: TimelineKeyframe | null, row: TimelineRow | null, options: TimelineOptions | null, propertyName: string, defaultValue?: T): T;
+    static getKeyframeStyle<T>(keyframeStyle: TimelineKeyframeStyle | null, rowStyle: TimelineRow | null, options: TimelineOptions | null, propertyName: string, defaultValue?: T, reverseOrder?: boolean): T;
     /**
      * Get row style from default settings or overrides by a row settings.
      */
-    static getRowStyle<T>(rowStyle: TimelineRow, options: TimelineOptions | null, propertyName: string, defaultValue?: T): T | undefined;
+    static getRowStyle<T>(rowStyle: TimelineRowStyle, options: TimelineOptions | null, propertyName: string, defaultValue?: T, reverseOrder?: boolean): T | undefined;
     /**
      * Get current row height from styling
      */
@@ -22,4 +23,6 @@ export declare class TimelineStyleUtils {
     static rowStripeHeight(rowStyle: TimelineRowStyle, options: TimelineOptions): number | string;
     static stripeFillColor(rowStyle: TimelineRowStyle, options: TimelineOptions): string;
     static getRowMarginBottom(rowStyle: TimelineRowStyle, options: TimelineOptions): number;
+    static keyframeDraggable(keyframe: TimelineKeyframeStyle | null, rowStyle: TimelineRowStyle | null, options: TimelineOptions | null, defaultValue?: boolean): boolean;
+    static stripeDraggable(rowStyle: TimelineRowStyle, options: TimelineOptions, defaultValue?: boolean): boolean;
 }

+ 4 - 0
src/settings/styles/timelineRowStyle.ts

@@ -8,6 +8,10 @@ export interface TimelineRowStyle {
   color?: string;
   selectedColor?: string;
   marginBottom?: number;
+  /**
+   * keyframes stripe is draggable.
+   */
+  stripeDraggable?: boolean;
   /**
    * Keyframes bounds stripe height.
    * 'auto' to automatically calculate.

+ 3 - 0
src/settings/styles/timelineStyle.ts

@@ -1,5 +1,8 @@
 import { TimelineCapShape } from '../../enums/timelineCapShape';
 
+/**
+ * Timeline indicator style
+ */
 export interface TimelineStyle {
   width?: number;
   marginTop?: number;

+ 5 - 11
src/timeline.ts

@@ -1758,21 +1758,15 @@ export class Timeline extends TimelineEventsEmitter {
       return -1;
     };
     const filteredElements = elements.filter((element) => {
+      if (!element) {
+        return false;
+      }
       if (element.type === TimelineElementType.Keyframe) {
-        let draggable = true;
-        if (this._options) {
-          draggable = (this._options.keyframesDraggable === undefined ? true : !!this._options.keyframesDraggable) && (element.keyframe.draggable === undefined ? true : !!element.keyframe.draggable);
-        }
-
-        if (!draggable) {
+        if (!TimelineStyleUtils.keyframeDraggable(element.keyframe, element.row, this._options)) {
           return false;
         }
       } else if (element.type === TimelineElementType.Stripe) {
-        let draggable = true;
-        if (this._options) {
-          draggable = (this._options.stripesDraggable === undefined ? true : !!this._options.stripesDraggable) && (element.row.stripeDraggable === undefined ? true : !!element.row.stripeDraggable);
-        }
-        if (!draggable) {
+        if (!TimelineStyleUtils.stripeDraggable(element.row, this._options)) {
           return false;
         }
       } else if (element.type === TimelineElementType.Row) {

+ 0 - 8
src/timelineRow.ts

@@ -3,12 +3,4 @@ import { TimelineRowStyle } from './settings/styles/timelineRowStyle';
 
 export interface TimelineRow extends TimelineRowStyle {
   keyframes?: Array<TimelineKeyframe>;
-  /**
-   * keyframes stripe is draggable.
-   */
-  stripeDraggable?: boolean;
-  /**
-   * keyframes stripe is draggable.
-   */
-  keyframesDraggable?: boolean;
 }

+ 60 - 14
src/utils/timelineStyleUtils.ts

@@ -1,8 +1,8 @@
 /* eslint-disable @typescript-eslint/no-explicit-any */
 import { TimelineRow } from '../timelineRow';
-import { TimelineKeyframe } from '../timelineKeyframe';
 import { TimelineOptions } from '../settings/timelineOptions';
 import { TimelineRowStyle } from '../settings/styles/timelineRowStyle';
+import { TimelineKeyframeStyle } from '../settings/styles/timelineKeyframeStyle';
 
 export class TimelineStyleUtils {
   /**
@@ -11,51 +11,89 @@ export class TimelineStyleUtils {
    * @param row keyframe row.
    * @param propertyName property to get.
    * @param defaultValue default value to return
+   * @param reverseOrder reverse styling order: global, row, keyframe
    */
-  static getKeyframeStyle<T>(keyframe: TimelineKeyframe | null, row: TimelineRow | null, options: TimelineOptions | null, propertyName: string, defaultValue?: T): T {
-    if (keyframe && keyframe) {
-      const style: any = keyframe;
+  static getKeyframeStyle<T>(
+    keyframeStyle: TimelineKeyframeStyle | null,
+    rowStyle: TimelineRow | null,
+    options: TimelineOptions | null,
+    propertyName: string,
+    defaultValue?: T,
+    reverseOrder = false,
+  ): T {
+    // Don't spawn new array for the normal order.
+    let styles: Array<any> = null;
+    if (keyframeStyle) {
+      const style: any = keyframeStyle;
       if (style[propertyName] !== undefined) {
-        return style[propertyName] as T;
+        const value = style[propertyName];
+        if (!reverseOrder) {
+          return value;
+        }
+        styles = styles || [];
+        styles.push(value);
       }
     }
 
-    if (row && row.keyframesStyle) {
-      const style: any = row.keyframesStyle;
+    if (rowStyle && rowStyle.keyframesStyle) {
+      const style: any = rowStyle.keyframesStyle;
       if (style[propertyName] !== undefined) {
-        return style[propertyName] as T;
+        const value = style[propertyName];
+        if (!reverseOrder) {
+          return value;
+        }
+        styles = styles || [];
+        styles.push(value);
       }
     }
     const globalRowStyle = options ? options.rowsStyle : null;
     if (globalRowStyle && globalRowStyle.keyframesStyle) {
       const style: any = globalRowStyle.keyframesStyle;
       if (style[propertyName] !== undefined) {
-        return style[propertyName] as T;
+        const value = style[propertyName];
+        if (!reverseOrder) {
+          return value;
+        }
+        styles = styles || [];
+        styles.push(value);
       }
     }
 
-    return defaultValue;
+    return reverseOrder && styles && styles.length > 0 ? styles[styles.length - 1] : defaultValue;
   }
 
   /**
    * Get row style from default settings or overrides by a row settings.
    */
-  static getRowStyle<T>(rowStyle: TimelineRow, options: TimelineOptions | null, propertyName: string, defaultValue?: T): T | undefined {
+  static getRowStyle<T>(rowStyle: TimelineRowStyle, options: TimelineOptions | null, propertyName: string, defaultValue?: T, reverseOrder = false): T | undefined {
+    // Don't spawn new array for the normal order.
+    let styles: Array<any> = null;
     if (rowStyle) {
       const style: any = rowStyle;
       if (style[propertyName] !== undefined) {
-        return style[propertyName] as T;
+        const results = style[propertyName] as T;
+        if (!reverseOrder) {
+          return results;
+        }
+        styles = styles || [];
+        styles.push(results);
       }
     }
     const globalRowStyle = options ? options.rowsStyle : null;
     if (globalRowStyle) {
       const style: any = globalRowStyle;
       if (style[propertyName] !== undefined) {
-        return style[propertyName] as T;
+        const results = style[propertyName] as T;
+        if (!reverseOrder) {
+          return results;
+        }
+
+        styles = styles || [];
+        styles.push(results);
       }
     }
 
-    return defaultValue;
+    return reverseOrder && styles && styles.length > 0 ? styles[styles.length - 1] : defaultValue;
   }
 
   /**
@@ -73,4 +111,12 @@ export class TimelineStyleUtils {
   static getRowMarginBottom(rowStyle: TimelineRowStyle, options: TimelineOptions): number {
     return TimelineStyleUtils.getRowStyle<number>(rowStyle, options, 'marginBottom', 0);
   }
+
+  static keyframeDraggable(keyframe: TimelineKeyframeStyle | null, rowStyle: TimelineRowStyle | null, options: TimelineOptions | null, defaultValue = true): boolean {
+    return TimelineStyleUtils.getKeyframeStyle<boolean>(keyframe, rowStyle, options, 'draggable', defaultValue, true);
+  }
+
+  static stripeDraggable(rowStyle: TimelineRowStyle, options: TimelineOptions, defaultValue = true): boolean {
+    return TimelineStyleUtils.getRowStyle<boolean>(rowStyle, options, 'stripeDraggable', defaultValue, true);
+  }
 }

+ 11 - 0
tests/asserts.ts

@@ -0,0 +1,11 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+export const assert = {
+  equal: (value: any, expected: any, message: string | null = null): void => {
+    if (expected !== value) {
+      if (!message) {
+        message = 'AssertionError:';
+      }
+      new Error(message + ' Expected: ' + expected + ' Result:' + value);
+    }
+  },
+};

+ 15 - 0
tests/js/asserts.js

@@ -0,0 +1,15 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+/* eslint-disable @typescript-eslint/no-explicit-any */
+exports.assert = {
+    equal: function (value, expected, message) {
+        if (message === void 0) { message = null; }
+        if (expected !== value) {
+            if (!message) {
+                message = 'AssertionError:';
+            }
+            new Error(message + ' Expected: ' + expected + ' Result:' + value);
+        }
+    },
+};
+//# sourceMappingURL=asserts.js.map

+ 1 - 0
tests/js/asserts.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"asserts.js","sourceRoot":"","sources":["../asserts.ts"],"names":[],"mappings":";;AAAA,uDAAuD;AAC1C,QAAA,MAAM,GAAG;IACpB,KAAK,EAAE,UAAC,KAAU,EAAE,QAAa,EAAE,OAA6B;QAA7B,wBAAA,EAAA,cAA6B;QAC9D,IAAI,QAAQ,KAAK,KAAK,EAAE;YACtB,IAAI,CAAC,OAAO,EAAE;gBACZ,OAAO,GAAG,iBAAiB,CAAC;aAC7B;YACD,IAAI,KAAK,CAAC,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,KAAK,CAAC,CAAC;SACpE;IACH,CAAC;CACF,CAAC"}

+ 105 - 0
tests/js/settingsTests.js

@@ -0,0 +1,105 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+/* eslint-disable @typescript-eslint/no-explicit-any */
+var animation_timeline_1 = require("../lib/animation-timeline");
+var asserts_1 = require("./asserts");
+describe('_findDraggable', function () {
+    it('Keyframe should be selected', function () {
+        var timeline = new animation_timeline_1.Timeline();
+        var elements = [
+            {
+                type: animation_timeline_1.TimelineElementType.Stripe,
+                val: 5,
+            },
+            {
+                type: animation_timeline_1.TimelineElementType.Keyframe,
+                val: 5,
+            },
+        ];
+        var element = timeline._findDraggable(elements, 5);
+        if (!element) {
+            throw new Error('element cannot be empty');
+        }
+        asserts_1.assert.equal(element.type, animation_timeline_1.TimelineElementType.Keyframe, animation_timeline_1.TimelineElementType.Keyframe + ' should be selected');
+    });
+    it('Timeline should be selected', function () {
+        var timeline = new animation_timeline_1.Timeline();
+        var elements = [
+            {
+                type: animation_timeline_1.TimelineElementType.Timeline,
+                val: 5,
+            },
+            {
+                type: animation_timeline_1.TimelineElementType.Stripe,
+                val: 5,
+            },
+        ];
+        var element = timeline._findDraggable(elements, 5);
+        if (!element) {
+            throw new Error('element cannot be empty');
+        }
+        asserts_1.assert.equal(element.type, animation_timeline_1.TimelineElementType.Timeline, animation_timeline_1.TimelineElementType.Timeline + ' should be selected');
+    });
+    it('Timeline should taken first', function () {
+        var timeline = new animation_timeline_1.Timeline();
+        var elements = [
+            {
+                type: animation_timeline_1.TimelineElementType.Timeline,
+                val: 5,
+            },
+            {
+                type: animation_timeline_1.TimelineElementType.Keyframe,
+                val: 4,
+            },
+            {
+                type: animation_timeline_1.TimelineElementType.Keyframe,
+                val: 5,
+            },
+            {
+                type: animation_timeline_1.TimelineElementType.Stripe,
+                val: 5,
+            },
+        ];
+        var element = timeline._findDraggable(elements, 5);
+        if (!element) {
+            throw new Error('element cannot be empty');
+        }
+        asserts_1.assert.equal(element.type, animation_timeline_1.TimelineElementType.Timeline, animation_timeline_1.TimelineElementType.Timeline + ' should be selected');
+        // Keyframe with value 5 should be selected
+        asserts_1.assert.equal(element.val, 5);
+    });
+    it('Stripe should be selected', function () {
+        var timeline = new animation_timeline_1.Timeline();
+        var elements = [
+            {
+                type: animation_timeline_1.TimelineElementType.Stripe,
+                val: 5,
+            },
+        ];
+        var element = timeline._findDraggable(elements, 5);
+        if (!element) {
+            throw new Error('element cannot be empty');
+        }
+        asserts_1.assert.equal(element.type, animation_timeline_1.TimelineElementType.Stripe, animation_timeline_1.TimelineElementType.Stripe + ' should be selected');
+    });
+    it('closest keyframe should be returned', function () {
+        var timeline = new animation_timeline_1.Timeline();
+        var elements = [
+            {
+                type: animation_timeline_1.TimelineElementType.Keyframe,
+                val: 0,
+            },
+            {
+                type: animation_timeline_1.TimelineElementType.Keyframe,
+                val: 4,
+            },
+            {
+                type: animation_timeline_1.TimelineElementType.Keyframe,
+                val: 9,
+            },
+        ];
+        var element = timeline._findDraggable(elements, 5);
+        asserts_1.assert.equal(element.val, elements[2].val);
+    });
+});
+//# sourceMappingURL=settingsTests.js.map

文件差异内容过多而无法显示
+ 0 - 0
tests/js/settingsTests.js.map


+ 103 - 0
tests/js/styleTests.js

@@ -0,0 +1,103 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+/* eslint-disable @typescript-eslint/no-explicit-any */
+var animation_timeline_1 = require("./../lib/animation-timeline");
+var asserts_1 = require("./asserts");
+describe('TimelineStyleUtils', function () {
+    it('Keyframe is draggable by default', function () {
+        var globalStyle = {
+            rowsStyle: {
+                keyframesStyle: {},
+            },
+        };
+        var keyframeStyle = { shape: animation_timeline_1.TimelineKeyframeShape.Rect };
+        asserts_1.assert.equal(animation_timeline_1.TimelineStyleUtils.keyframeDraggable(keyframeStyle, null, globalStyle), true);
+    });
+    it('Keyframe draggable', function () {
+        var globalStyle = {
+            rowsStyle: {
+                keyframesStyle: {},
+            },
+        };
+        var keyframeStyle = { draggable: true, shape: animation_timeline_1.TimelineKeyframeShape.Rect };
+        asserts_1.assert.equal(animation_timeline_1.TimelineStyleUtils.keyframeDraggable(keyframeStyle, null, globalStyle), true);
+    });
+    it('Keyframe is not draggable', function () {
+        var globalStyle = {
+            rowsStyle: {
+                keyframesStyle: {},
+            },
+        };
+        var keyframeStyle = { draggable: false, shape: animation_timeline_1.TimelineKeyframeShape.Rect };
+        asserts_1.assert.equal(animation_timeline_1.TimelineStyleUtils.keyframeDraggable(keyframeStyle, null, globalStyle), false);
+    });
+    it('Keyframe row is not draggable than keyframe is not draggable', function () {
+        var globalStyle = {
+            rowsStyle: {
+                keyframesStyle: {},
+            },
+        };
+        var rowStyle = { keyframesStyle: { draggable: false, shape: animation_timeline_1.TimelineKeyframeShape.Rect } };
+        var keyframeStyle = { draggable: true, shape: animation_timeline_1.TimelineKeyframeShape.Rect };
+        asserts_1.assert.equal(animation_timeline_1.TimelineStyleUtils.keyframeDraggable(keyframeStyle, rowStyle, globalStyle), false);
+    });
+    it('Keyframes are not draggable by general settings', function () {
+        var globalStyle = {
+            rowsStyle: {
+                keyframesStyle: {
+                    draggable: false,
+                },
+            },
+        };
+        var rowStyle = { keyframesStyle: { draggable: true, shape: animation_timeline_1.TimelineKeyframeShape.Rect } };
+        var keyframeStyle = { draggable: true, shape: animation_timeline_1.TimelineKeyframeShape.Rect };
+        asserts_1.assert.equal(animation_timeline_1.TimelineStyleUtils.keyframeDraggable(keyframeStyle, rowStyle, globalStyle), false);
+    });
+    it('Keyframes are draggable', function () {
+        var globalStyle = {
+            rowsStyle: {
+                keyframesStyle: {
+                    draggable: true,
+                },
+            },
+        };
+        var rowStyle = { keyframesStyle: { draggable: true, shape: animation_timeline_1.TimelineKeyframeShape.Rect } };
+        var keyframeStyle = { draggable: true, shape: animation_timeline_1.TimelineKeyframeShape.Rect };
+        asserts_1.assert.equal(animation_timeline_1.TimelineStyleUtils.keyframeDraggable(keyframeStyle, rowStyle, globalStyle), false);
+    });
+    it('Stripe is draggable by default', function () {
+        var globalStyle = {
+            rowsStyle: {
+                keyframesStyle: {
+                    draggable: true,
+                },
+            },
+        };
+        var rowStyle = { keyframesStyle: { draggable: true, shape: animation_timeline_1.TimelineKeyframeShape.Rect } };
+        asserts_1.assert.equal(animation_timeline_1.TimelineStyleUtils.stripeDraggable(rowStyle, globalStyle), true);
+    });
+    it('Stripe is not draggable by row settings', function () {
+        var globalStyle = {
+            rowsStyle: {
+                keyframesStyle: {
+                    draggable: true,
+                },
+            },
+        };
+        var rowStyle = { stripeDraggable: false, keyframesStyle: { draggable: true, shape: animation_timeline_1.TimelineKeyframeShape.Rect } };
+        asserts_1.assert.equal(animation_timeline_1.TimelineStyleUtils.stripeDraggable(rowStyle, globalStyle), false);
+    });
+    it('Stripe is not draggable by global settings', function () {
+        var globalStyle = {
+            rowsStyle: {
+                stripeDraggable: false,
+                keyframesStyle: {
+                    draggable: true,
+                },
+            },
+        };
+        var rowStyle = { stripeDraggable: false, keyframesStyle: { draggable: true, shape: animation_timeline_1.TimelineKeyframeShape.Rect } };
+        asserts_1.assert.equal(animation_timeline_1.TimelineStyleUtils.stripeDraggable(rowStyle, globalStyle), false);
+    });
+});
+//# sourceMappingURL=styleTests.js.map

文件差异内容过多而无法显示
+ 0 - 0
tests/js/styleTests.js.map


+ 7 - 15
tests/timelineTests.js → tests/js/timelineTests.js

@@ -2,15 +2,7 @@
 Object.defineProperty(exports, "__esModule", { value: true });
 /* eslint-disable @typescript-eslint/no-explicit-any */
 var animation_timeline_1 = require("./../lib/animation-timeline");
-function assertEquals(value, expected, message) {
-    if (message === void 0) { message = null; }
-    if (expected !== value) {
-        if (!message) {
-            message = 'Not equal!';
-        }
-        new Error(message + '. Expected: ' + expected + value);
-    }
-}
+var asserts_1 = require("./asserts");
 describe('_findDraggable', function () {
     it('Keyframe should be selected', function () {
         var timeline = new animation_timeline_1.Timeline();
@@ -28,7 +20,7 @@ describe('_findDraggable', function () {
         if (!element) {
             throw new Error('element cannot be empty');
         }
-        assertEquals(element.type, animation_timeline_1.TimelineElementType.Keyframe, animation_timeline_1.TimelineElementType.Keyframe + ' should be selected');
+        asserts_1.assert.equal(element.type, animation_timeline_1.TimelineElementType.Keyframe, animation_timeline_1.TimelineElementType.Keyframe + ' should be selected');
     });
     it('Timeline should be selected', function () {
         var timeline = new animation_timeline_1.Timeline();
@@ -46,7 +38,7 @@ describe('_findDraggable', function () {
         if (!element) {
             throw new Error('element cannot be empty');
         }
-        assertEquals(element.type, animation_timeline_1.TimelineElementType.Timeline, animation_timeline_1.TimelineElementType.Timeline + ' should be selected');
+        asserts_1.assert.equal(element.type, animation_timeline_1.TimelineElementType.Timeline, animation_timeline_1.TimelineElementType.Timeline + ' should be selected');
     });
     it('Timeline should taken first', function () {
         var timeline = new animation_timeline_1.Timeline();
@@ -72,9 +64,9 @@ describe('_findDraggable', function () {
         if (!element) {
             throw new Error('element cannot be empty');
         }
-        assertEquals(element.type, animation_timeline_1.TimelineElementType.Timeline, animation_timeline_1.TimelineElementType.Timeline + ' should be selected');
+        asserts_1.assert.equal(element.type, animation_timeline_1.TimelineElementType.Timeline, animation_timeline_1.TimelineElementType.Timeline + ' should be selected');
         // Keyframe with value 5 should be selected
-        assertEquals(element.val, 5);
+        asserts_1.assert.equal(element.val, 5);
     });
     it('Stripe should be selected', function () {
         var timeline = new animation_timeline_1.Timeline();
@@ -88,7 +80,7 @@ describe('_findDraggable', function () {
         if (!element) {
             throw new Error('element cannot be empty');
         }
-        assertEquals(element.type, animation_timeline_1.TimelineElementType.Stripe, animation_timeline_1.TimelineElementType.Stripe + ' should be selected');
+        asserts_1.assert.equal(element.type, animation_timeline_1.TimelineElementType.Stripe, animation_timeline_1.TimelineElementType.Stripe + ' should be selected');
     });
     it('closest keyframe should be returned', function () {
         var timeline = new animation_timeline_1.Timeline();
@@ -107,7 +99,7 @@ describe('_findDraggable', function () {
             },
         ];
         var element = timeline._findDraggable(elements, 5);
-        assertEquals(element.val, elements[2].val);
+        asserts_1.assert.equal(element.val, elements[2].val);
     });
 });
 //# sourceMappingURL=timelineTests.js.map

文件差异内容过多而无法显示
+ 0 - 0
tests/js/timelineTests.js.map


+ 103 - 0
tests/settingsTests.ts

@@ -0,0 +1,103 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import { Timeline, TimelineElementType, TimelineClickableElement } from '../lib/animation-timeline';
+import { assert } from './asserts';
+
+describe('_findDraggable', function () {
+  it('Keyframe should be selected', function () {
+    const timeline = new Timeline();
+    const elements = [
+      {
+        type: TimelineElementType.Stripe,
+        val: 5,
+      } as TimelineClickableElement,
+      {
+        type: TimelineElementType.Keyframe,
+        val: 5,
+      } as TimelineClickableElement,
+    ];
+    const element = timeline._findDraggable(elements, 5);
+    if (!element) {
+      throw new Error('element cannot be empty');
+    }
+    assert.equal(element.type, TimelineElementType.Keyframe, TimelineElementType.Keyframe + ' should be selected');
+  });
+  it('Timeline should be selected', function () {
+    const timeline = new Timeline();
+    const elements = [
+      {
+        type: TimelineElementType.Timeline,
+        val: 5,
+      } as TimelineClickableElement,
+      {
+        type: TimelineElementType.Stripe,
+        val: 5,
+      } as TimelineClickableElement,
+    ];
+    const element = timeline._findDraggable(elements, 5);
+    if (!element) {
+      throw new Error('element cannot be empty');
+    }
+    assert.equal(element.type, TimelineElementType.Timeline, TimelineElementType.Timeline + ' should be selected');
+  });
+  it('Timeline should taken first', function () {
+    const timeline = new Timeline();
+    const elements = [
+      {
+        type: TimelineElementType.Timeline,
+        val: 5,
+      } as TimelineClickableElement,
+      {
+        type: TimelineElementType.Keyframe,
+        val: 4,
+      },
+      {
+        type: TimelineElementType.Keyframe,
+        val: 5,
+      } as TimelineClickableElement,
+      {
+        type: TimelineElementType.Stripe,
+        val: 5,
+      } as TimelineClickableElement,
+    ];
+    const element = timeline._findDraggable(elements, 5);
+    if (!element) {
+      throw new Error('element cannot be empty');
+    }
+    assert.equal(element.type, TimelineElementType.Timeline, TimelineElementType.Timeline + ' should be selected');
+    // Keyframe with value 5 should be selected
+    assert.equal(element.val, 5);
+  });
+  it('Stripe should be selected', function () {
+    const timeline = new Timeline();
+    const elements = [
+      {
+        type: TimelineElementType.Stripe,
+        val: 5,
+      } as TimelineClickableElement,
+    ];
+    const element = timeline._findDraggable(elements, 5);
+    if (!element) {
+      throw new Error('element cannot be empty');
+    }
+    assert.equal(element.type, TimelineElementType.Stripe, TimelineElementType.Stripe + ' should be selected');
+  });
+  it('closest keyframe should be returned', function () {
+    const timeline = new Timeline();
+    const elements = [
+      {
+        type: TimelineElementType.Keyframe,
+        val: 0,
+      } as TimelineClickableElement,
+      {
+        type: TimelineElementType.Keyframe,
+        val: 4,
+      } as TimelineClickableElement,
+      {
+        type: TimelineElementType.Keyframe,
+        val: 9,
+      } as TimelineClickableElement,
+    ];
+    const element = timeline._findDraggable(elements, 5);
+    assert.equal(element.val, elements[2].val);
+  });
+});

+ 119 - 0
tests/styleTests.ts

@@ -0,0 +1,119 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import {
+  TimelineStyleUtils,
+  TimelineKeyframeShape,
+  TimelineOptions,
+  TimelineRowStyle,
+  Timeline,
+  TimelineKeyframeStyle,
+  TimelineElementType,
+  TimelineClickableElement,
+} from './../lib/animation-timeline';
+import { assert } from './asserts';
+
+describe('TimelineStyleUtils', function () {
+  it('Keyframe is draggable by default', function () {
+    const globalStyle = {
+      rowsStyle: {
+        keyframesStyle: {},
+      } as TimelineRowStyle,
+    } as TimelineOptions;
+
+    const keyframeStyle = { shape: TimelineKeyframeShape.Rect } as TimelineKeyframeStyle;
+    assert.equal(TimelineStyleUtils.keyframeDraggable(keyframeStyle, null, globalStyle), true);
+  });
+  it('Keyframe draggable', function () {
+    const globalStyle = {
+      rowsStyle: {
+        keyframesStyle: {},
+      } as TimelineRowStyle,
+    } as TimelineOptions;
+
+    const keyframeStyle = { draggable: true, shape: TimelineKeyframeShape.Rect } as TimelineKeyframeStyle;
+    assert.equal(TimelineStyleUtils.keyframeDraggable(keyframeStyle, null, globalStyle), true);
+  });
+
+  it('Keyframe is not draggable', function () {
+    const globalStyle = {
+      rowsStyle: {
+        keyframesStyle: {},
+      } as TimelineRowStyle,
+    } as TimelineOptions;
+
+    const keyframeStyle = { draggable: false, shape: TimelineKeyframeShape.Rect } as TimelineKeyframeStyle;
+    assert.equal(TimelineStyleUtils.keyframeDraggable(keyframeStyle, null, globalStyle), false);
+  });
+
+  it('Keyframe row is not draggable than keyframe is not draggable', function () {
+    const globalStyle = {
+      rowsStyle: {
+        keyframesStyle: {},
+      } as TimelineRowStyle,
+    } as TimelineOptions;
+    const rowStyle = { keyframesStyle: { draggable: false, shape: TimelineKeyframeShape.Rect } } as TimelineRowStyle;
+    const keyframeStyle = { draggable: true, shape: TimelineKeyframeShape.Rect } as TimelineKeyframeStyle;
+    assert.equal(TimelineStyleUtils.keyframeDraggable(keyframeStyle, rowStyle, globalStyle), false);
+  });
+
+  it('Keyframes are not draggable by general settings', function () {
+    const globalStyle = {
+      rowsStyle: {
+        keyframesStyle: {
+          draggable: false,
+        },
+      } as TimelineRowStyle,
+    } as TimelineOptions;
+    const rowStyle = { keyframesStyle: { draggable: true, shape: TimelineKeyframeShape.Rect } } as TimelineRowStyle;
+    const keyframeStyle = { draggable: true, shape: TimelineKeyframeShape.Rect } as TimelineKeyframeStyle;
+    assert.equal(TimelineStyleUtils.keyframeDraggable(keyframeStyle, rowStyle, globalStyle), false);
+  });
+  it('Keyframes are draggable', function () {
+    const globalStyle = {
+      rowsStyle: {
+        keyframesStyle: {
+          draggable: true,
+        },
+      } as TimelineRowStyle,
+    } as TimelineOptions;
+    const rowStyle = { keyframesStyle: { draggable: true, shape: TimelineKeyframeShape.Rect } } as TimelineRowStyle;
+    const keyframeStyle = { draggable: true, shape: TimelineKeyframeShape.Rect } as TimelineKeyframeStyle;
+    assert.equal(TimelineStyleUtils.keyframeDraggable(keyframeStyle, rowStyle, globalStyle), false);
+  });
+
+  it('Stripe is draggable by default', function () {
+    const globalStyle = {
+      rowsStyle: {
+        keyframesStyle: {
+          draggable: true,
+        },
+      } as TimelineRowStyle,
+    } as TimelineOptions;
+    const rowStyle = { keyframesStyle: { draggable: true, shape: TimelineKeyframeShape.Rect } } as TimelineRowStyle;
+    assert.equal(TimelineStyleUtils.stripeDraggable(rowStyle, globalStyle), true);
+  });
+
+  it('Stripe is not draggable by row settings', function () {
+    const globalStyle = {
+      rowsStyle: {
+        keyframesStyle: {
+          draggable: true,
+        },
+      } as TimelineRowStyle,
+    } as TimelineOptions;
+    const rowStyle = { stripeDraggable: false, keyframesStyle: { draggable: true, shape: TimelineKeyframeShape.Rect } } as TimelineRowStyle;
+    assert.equal(TimelineStyleUtils.stripeDraggable(rowStyle, globalStyle), false);
+  });
+
+  it('Stripe is not draggable by global settings', function () {
+    const globalStyle = {
+      rowsStyle: {
+        stripeDraggable: false,
+        keyframesStyle: {
+          draggable: true,
+        },
+      } as TimelineRowStyle,
+    } as TimelineOptions;
+    const rowStyle = { stripeDraggable: false, keyframesStyle: { draggable: true, shape: TimelineKeyframeShape.Rect } } as TimelineRowStyle;
+    assert.equal(TimelineStyleUtils.stripeDraggable(rowStyle, globalStyle), false);
+  });
+});

文件差异内容过多而无法显示
+ 0 - 0
tests/timelineTests.js.map


+ 7 - 16
tests/timelineTests.ts

@@ -1,15 +1,6 @@
 /* eslint-disable @typescript-eslint/no-explicit-any */
 import { Timeline, TimelineElementType, TimelineClickableElement } from './../lib/animation-timeline';
-
-function assertEquals(value: any, expected: any, message: string | null = null): void {
-  if (expected !== value) {
-    if (!message) {
-      message = 'Not equal!';
-    }
-    new Error(message + '. Expected: ' + expected + value);
-  }
-}
-
+import { assert } from './asserts';
 describe('_findDraggable', function () {
   it('Keyframe should be selected', function () {
     const timeline = new Timeline();
@@ -27,7 +18,7 @@ describe('_findDraggable', function () {
     if (!element) {
       throw new Error('element cannot be empty');
     }
-    assertEquals(element.type, TimelineElementType.Keyframe, TimelineElementType.Keyframe + ' should be selected');
+    assert.equal(element.type, TimelineElementType.Keyframe, TimelineElementType.Keyframe + ' should be selected');
   });
   it('Timeline should be selected', function () {
     const timeline = new Timeline();
@@ -45,7 +36,7 @@ describe('_findDraggable', function () {
     if (!element) {
       throw new Error('element cannot be empty');
     }
-    assertEquals(element.type, TimelineElementType.Timeline, TimelineElementType.Timeline + ' should be selected');
+    assert.equal(element.type, TimelineElementType.Timeline, TimelineElementType.Timeline + ' should be selected');
   });
   it('Timeline should taken first', function () {
     const timeline = new Timeline();
@@ -71,9 +62,9 @@ describe('_findDraggable', function () {
     if (!element) {
       throw new Error('element cannot be empty');
     }
-    assertEquals(element.type, TimelineElementType.Timeline, TimelineElementType.Timeline + ' should be selected');
+    assert.equal(element.type, TimelineElementType.Timeline, TimelineElementType.Timeline + ' should be selected');
     // Keyframe with value 5 should be selected
-    assertEquals(element.val, 5);
+    assert.equal(element.val, 5);
   });
   it('Stripe should be selected', function () {
     const timeline = new Timeline();
@@ -87,7 +78,7 @@ describe('_findDraggable', function () {
     if (!element) {
       throw new Error('element cannot be empty');
     }
-    assertEquals(element.type, TimelineElementType.Stripe, TimelineElementType.Stripe + ' should be selected');
+    assert.equal(element.type, TimelineElementType.Stripe, TimelineElementType.Stripe + ' should be selected');
   });
   it('closest keyframe should be returned', function () {
     const timeline = new Timeline();
@@ -106,6 +97,6 @@ describe('_findDraggable', function () {
       } as TimelineClickableElement,
     ];
     const element = timeline._findDraggable(elements, 5);
-    assertEquals(element.val, elements[2].val);
+    assert.equal(element.val, elements[2].val);
   });
 });

+ 17 - 4
tests/unittests.html

@@ -17,15 +17,28 @@
     <script src="https://unpkg.com/chai/chai.js"></script>
     <script src="https://unpkg.com/mocha/mocha.js"></script>
     <script src="../lib/animation-timeline.js"></script>
-    <script>var exports = {}; var require = function () {
-            return timelineModule;
-        };
+    <script>if (!window.exports) {
+            window.exports = {};
+        }
+    </script>
+    <script src="./js/asserts.js"></script>
+    <script>if (!window.require) {
+            window.require = function (moduleName) {
+                if (moduleName.indexOf('assert') > 0) {
+                    return exports;
+                } else {
+                    return timelineModule;
+                }
+            }
+        }
     </script>
     <script class="mocha-init">
         mocha.setup('bdd');
         mocha.checkLeaks();
     </script>
-    <script src="./timelineTests.js"></script>
+    <script src="./js/styleTests.js"></script>
+    <script src="./js/timelineTests.js"></script>
+    <script src="./js/settingsTests.js"></script>
     <script class="mocha-exec">
         mocha.run();
     </script>

+ 1 - 1
tsconfig.tests.json

@@ -1,7 +1,7 @@
 {
   "compilerOptions": {
     "module": "CommonJS",
-    "outDir": "./tests",
+    "outDir": "./tests/js",
     "lib": ["es2015", "dom"],
     "target": "es5",
     "allowJs": false,

部分文件因为文件数量过多而无法显示