]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Extract Component config functionality to a separate class (#33872)
authorGeoSot <geo.sotis@gmail.com>
Fri, 10 Dec 2021 16:18:18 +0000 (18:18 +0200)
committerGitHub <noreply@github.com>
Fri, 10 Dec 2021 16:18:18 +0000 (18:18 +0200)
Co-authored-by: XhmikosR <xhmikosr@gmail.com>
18 files changed:
js/src/base-component.js
js/src/carousel.js
js/src/collapse.js
js/src/dropdown.js
js/src/modal.js
js/src/offcanvas.js
js/src/popover.js
js/src/scrollspy.js
js/src/toast.js
js/src/tooltip.js
js/src/util/backdrop.js
js/src/util/config.js [new file with mode: 0644]
js/src/util/focustrap.js
js/src/util/index.js
js/src/util/swipe.js
js/src/util/template-factory.js
js/tests/unit/util/config.spec.js [new file with mode: 0644]
js/tests/unit/util/index.spec.js

index 3c5eb460ab4c381fa92e27b13e47a93b29115cad..4140bf19475b480beb3c9f4a12d15d834e882f55 100644 (file)
@@ -6,11 +6,9 @@
  */
 
 import Data from './dom/data'
-import {
-  executeAfterTransition,
-  getElement
-} from './util/index'
+import { executeAfterTransition, getElement } from './util/index'
 import EventHandler from './dom/event-handler'
+import Config from './util/config'
 
 /**
  * Constants
@@ -22,15 +20,18 @@ const VERSION = '5.1.3'
  * Class definition
  */
 
-class BaseComponent {
-  constructor(element) {
-    element = getElement(element)
+class BaseComponent extends Config {
+  constructor(element, config) {
+    super()
 
+    element = getElement(element)
     if (!element) {
       return
     }
 
     this._element = element
+    this._config = this._getConfig(config)
+
     Data.set(this._element, this.constructor.DATA_KEY, this)
   }
 
@@ -48,6 +49,13 @@ class BaseComponent {
     executeAfterTransition(callback, element, isAnimated)
   }
 
+  _getConfig(config) {
+    config = this._mergeConfigObj(config, this._element)
+    config = this._configAfterMerge(config)
+    this._typeCheckConfig(config)
+    return config
+  }
+
   // Static
   static getInstance(element) {
     return Data.get(getElement(element), this.DATA_KEY)
@@ -61,10 +69,6 @@ class BaseComponent {
     return VERSION
   }
 
-  static get NAME() {
-    throw new Error('You have to implement the static method "NAME" for each component!')
-  }
-
   static get DATA_KEY() {
     return `bs.${this.NAME}`
   }
index 3589f220672557343009156f5cc0e19294daf0a7..e50894aa8103f568885e7d4993c4a5ce0d450875 100644 (file)
@@ -12,8 +12,7 @@ import {
   isRTL,
   isVisible,
   reflow,
-  triggerTransitionEnd,
-  typeCheckConfig
+  triggerTransitionEnd
 } from './util/index'
 import EventHandler from './dom/event-handler'
 import Manipulator from './dom/manipulator'
@@ -95,7 +94,7 @@ const DefaultType = {
 
 class Carousel extends BaseComponent {
   constructor(element, config) {
-    super(element)
+    super(element, config)
 
     this._items = null
     this._interval = null
@@ -105,7 +104,6 @@ class Carousel extends BaseComponent {
     this.touchTimeout = null
     this._swipeHelper = null
 
-    this._config = this._getConfig(config)
     this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element)
     this._addEventListeners()
   }
@@ -115,6 +113,10 @@ class Carousel extends BaseComponent {
     return Default
   }
 
+  static get DefaultType() {
+    return DefaultType
+  }
+
   static get NAME() {
     return NAME
   }
@@ -205,16 +207,6 @@ class Carousel extends BaseComponent {
   }
 
   // Private
-  _getConfig(config) {
-    config = {
-      ...Default,
-      ...Manipulator.getDataAttributes(this._element),
-      ...(typeof config === 'object' ? config : {})
-    }
-    typeCheckConfig(NAME, config, DefaultType)
-    return config
-  }
-
   _addEventListeners() {
     if (this._config.keyboard) {
       EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event))
index 642f7e840b1c02eadc754ef52be5794b2416df39..56d4f51c2d02c63ed8870d5274773c1c89834c20 100644 (file)
@@ -10,11 +10,9 @@ import {
   getElement,
   getElementFromSelector,
   getSelectorFromElement,
-  reflow,
-  typeCheckConfig
+  reflow
 } from './util/index'
 import EventHandler from './dom/event-handler'
-import Manipulator from './dom/manipulator'
 import SelectorEngine from './dom/selector-engine'
 import BaseComponent from './base-component'
 
@@ -62,10 +60,9 @@ const DefaultType = {
 
 class Collapse extends BaseComponent {
   constructor(element, config) {
-    super(element)
+    super(element, config)
 
     this._isTransitioning = false
-    this._config = this._getConfig(config)
     this._triggerArray = []
 
     const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE)
@@ -96,6 +93,10 @@ class Collapse extends BaseComponent {
     return Default
   }
 
+  static get DefaultType() {
+    return DefaultType
+  }
+
   static get NAME() {
     return NAME
   }
@@ -210,15 +211,9 @@ class Collapse extends BaseComponent {
   }
 
   // Private
-  _getConfig(config) {
-    config = {
-      ...Default,
-      ...Manipulator.getDataAttributes(this._element),
-      ...config
-    }
+  _configAfterMerge(config) {
     config.toggle = Boolean(config.toggle) // Coerce string values
     config.parent = getElement(config.parent)
-    typeCheckConfig(NAME, config, DefaultType)
     return config
   }
 
index c4e7baf295bd0c44069211ab90e8f4200fd378b8..674150e016d4de6d38e28c3ed0c31fe9dc30226a 100644 (file)
@@ -15,8 +15,7 @@ import {
   isElement,
   isRTL,
   isVisible,
-  noop,
-  typeCheckConfig
+  noop
 } from './util/index'
 import EventHandler from './dom/event-handler'
 import Manipulator from './dom/manipulator'
@@ -88,10 +87,9 @@ const DefaultType = {
 
 class Dropdown extends BaseComponent {
   constructor(element, config) {
-    super(element)
+    super(element, config)
 
     this._popper = null
-    this._config = this._getConfig(config)
     this._menu = this._getMenuElement()
     this._inNavbar = this._detectNavbar()
   }
@@ -205,13 +203,7 @@ class Dropdown extends BaseComponent {
   }
 
   _getConfig(config) {
-    config = {
-      ...this.constructor.Default,
-      ...Manipulator.getDataAttributes(this._element),
-      ...config
-    }
-
-    typeCheckConfig(NAME, config, this.constructor.DefaultType)
+    config = super._getConfig(config)
 
     if (typeof config.reference === 'object' && !isElement(config.reference) &&
       typeof config.reference.getBoundingClientRect !== 'function'
index b8b1447746b4fa80c75e535b7d75ac7a00665acc..569e6e59025e1dedf1803b870bde20e7aa386415 100644 (file)
@@ -5,16 +5,8 @@
  * --------------------------------------------------------------------------
  */
 
-import {
-  defineJQueryPlugin,
-  getElementFromSelector,
-  isRTL,
-  isVisible,
-  reflow,
-  typeCheckConfig
-} from './util/index'
+import { defineJQueryPlugin, getElementFromSelector, isRTL, isVisible, reflow } from './util/index'
 import EventHandler from './dom/event-handler'
-import Manipulator from './dom/manipulator'
 import SelectorEngine from './dom/selector-engine'
 import ScrollBarHelper from './util/scrollbar'
 import BaseComponent from './base-component'
@@ -70,9 +62,8 @@ const DefaultType = {
 
 class Modal extends BaseComponent {
   constructor(element, config) {
-    super(element)
+    super(element, config)
 
-    this._config = this._getConfig(config)
     this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element)
     this._backdrop = this._initializeBackDrop()
     this._focustrap = this._initializeFocusTrap()
@@ -86,6 +77,10 @@ class Modal extends BaseComponent {
     return Default
   }
 
+  static get DefaultType() {
+    return DefaultType
+  }
+
   static get NAME() {
     return NAME
   }
@@ -175,16 +170,6 @@ class Modal extends BaseComponent {
     })
   }
 
-  _getConfig(config) {
-    config = {
-      ...Default,
-      ...Manipulator.getDataAttributes(this._element),
-      ...(typeof config === 'object' ? config : {})
-    }
-    typeCheckConfig(NAME, config, DefaultType)
-    return config
-  }
-
   _showElement(relatedTarget) {
     // try to append dynamic modal
     if (!document.body.contains(this._element)) {
index 6878b1f628322789333fb4062562130bd530a541..acc0971fa256cfd307d3780c92b56bd78ca68bfa 100644 (file)
@@ -9,14 +9,12 @@ import {
   defineJQueryPlugin,
   getElementFromSelector,
   isDisabled,
-  isVisible,
-  typeCheckConfig
+  isVisible
 } from './util/index'
 import ScrollBarHelper from './util/scrollbar'
 import EventHandler from './dom/event-handler'
 import BaseComponent from './base-component'
 import SelectorEngine from './dom/selector-engine'
-import Manipulator from './dom/manipulator'
 import Backdrop from './util/backdrop'
 import FocusTrap from './util/focustrap'
 import { enableDismissTrigger } from './util/component-functions'
@@ -63,9 +61,8 @@ const DefaultType = {
 
 class Offcanvas extends BaseComponent {
   constructor(element, config) {
-    super(element)
+    super(element, config)
 
-    this._config = this._getConfig(config)
     this._isShown = false
     this._backdrop = this._initializeBackDrop()
     this._focustrap = this._initializeFocusTrap()
@@ -73,14 +70,18 @@ class Offcanvas extends BaseComponent {
   }
 
   // Getters
-  static get NAME() {
-    return NAME
-  }
-
   static get Default() {
     return Default
   }
 
+  static get DefaultType() {
+    return DefaultType
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
   // Public
   toggle(relatedTarget) {
     return this._isShown ? this.hide() : this.show(relatedTarget)
@@ -162,16 +163,6 @@ class Offcanvas extends BaseComponent {
   }
 
   // Private
-  _getConfig(config) {
-    config = {
-      ...Default,
-      ...Manipulator.getDataAttributes(this._element),
-      ...(typeof config === 'object' ? config : {})
-    }
-    typeCheckConfig(NAME, config, DefaultType)
-    return config
-  }
-
   _initializeBackDrop() {
     return new Backdrop({
       className: CLASS_NAME_BACKDROP,
index 77f847110c65f89c300ce7204976af8affe2cadc..375eb8b0ab208c93ddf2aa9cee57988b575ef691 100644 (file)
@@ -60,6 +60,10 @@ class Popover extends Tooltip {
     return Default
   }
 
+  static get DefaultType() {
+    return DefaultType
+  }
+
   static get NAME() {
     return NAME
   }
@@ -68,10 +72,6 @@ class Popover extends Tooltip {
     return Event
   }
 
-  static get DefaultType() {
-    return DefaultType
-  }
-
   // Overrides
   _isWithContent() {
     return this._getTitle() || this._getContent()
index 27bc0cd877dca0dbf75e1a851aa5f41f2adc6e1e..dc082a1b3a663adc0e06ff45436c9a0c10ae6ac4 100644 (file)
@@ -8,8 +8,7 @@
 import {
   defineJQueryPlugin,
   getElement,
-  getSelectorFromElement,
-  typeCheckConfig
+  getSelectorFromElement
 } from './util/index'
 import EventHandler from './dom/event-handler'
 import Manipulator from './dom/manipulator'
@@ -62,9 +61,8 @@ const DefaultType = {
 
 class ScrollSpy extends BaseComponent {
   constructor(element, config) {
-    super(element)
+    super(element, config)
     this._scrollElement = this._element.tagName === 'BODY' ? window : this._element
-    this._config = this._getConfig(config)
     this._offsets = []
     this._targets = []
     this._activeTarget = null
@@ -81,6 +79,10 @@ class ScrollSpy extends BaseComponent {
     return Default
   }
 
+  static get DefaultType() {
+    return DefaultType
+  }
+
   static get NAME() {
     return NAME
   }
@@ -135,17 +137,10 @@ class ScrollSpy extends BaseComponent {
   }
 
   // Private
-  _getConfig(config) {
-    config = {
-      ...Default,
-      ...Manipulator.getDataAttributes(this._element),
-      ...(typeof config === 'object' && config ? config : {})
-    }
 
+  _configAfterMerge(config) {
     config.target = getElement(config.target) || document.documentElement
 
-    typeCheckConfig(NAME, config, DefaultType)
-
     return config
   }
 
index ba376d05edb3e1fabaf2c7c73b641574f0fb6cf5..b85e20b6056bfa107b015db9ba5629306acf9863 100644 (file)
@@ -5,9 +5,8 @@
  * --------------------------------------------------------------------------
  */
 
-import { defineJQueryPlugin, reflow, typeCheckConfig } from './util/index'
+import { defineJQueryPlugin, reflow } from './util/index'
 import EventHandler from './dom/event-handler'
-import Manipulator from './dom/manipulator'
 import BaseComponent from './base-component'
 import { enableDismissTrigger } from './util/component-functions'
 
@@ -51,9 +50,8 @@ const Default = {
 
 class Toast extends BaseComponent {
   constructor(element, config) {
-    super(element)
+    super(element, config)
 
-    this._config = this._getConfig(config)
     this._timeout = null
     this._hasMouseInteraction = false
     this._hasKeyboardInteraction = false
@@ -61,14 +59,14 @@ class Toast extends BaseComponent {
   }
 
   // Getters
-  static get DefaultType() {
-    return DefaultType
-  }
-
   static get Default() {
     return Default
   }
 
+  static get DefaultType() {
+    return DefaultType
+  }
+
   static get NAME() {
     return NAME
   }
@@ -133,17 +131,6 @@ class Toast extends BaseComponent {
   }
 
   // Private
-  _getConfig(config) {
-    config = {
-      ...Default,
-      ...Manipulator.getDataAttributes(this._element),
-      ...(typeof config === 'object' && config ? config : {})
-    }
-
-    typeCheckConfig(NAME, config, this.constructor.DefaultType)
-
-    return config
-  }
 
   _maybeScheduleHide() {
     if (!this._config.autohide) {
index 19a9b316858486bf7316a6fb4e250299eca683cb..9c8e54c66b2d41c2597104a95156cb1ceeaa0876 100644 (file)
@@ -12,8 +12,7 @@ import {
   getElement,
   getUID,
   isRTL,
-  noop,
-  typeCheckConfig
+  noop
 } from './util/index'
 import { DefaultAllowlist } from './util/sanitizer'
 import EventHandler from './dom/event-handler'
@@ -140,6 +139,10 @@ class Tooltip extends BaseComponent {
     return Default
   }
 
+  static get DefaultType() {
+    return DefaultType
+  }
+
   static get NAME() {
     return NAME
   }
@@ -148,10 +151,6 @@ class Tooltip extends BaseComponent {
     return Event
   }
 
-  static get DefaultType() {
-    return DefaultType
-  }
-
   // Public
   enable() {
     this._isEnabled = true
@@ -571,11 +570,16 @@ class Tooltip extends BaseComponent {
     }
 
     config = {
-      ...this.constructor.Default,
       ...dataAttributes,
       ...(typeof config === 'object' && config ? config : {})
     }
+    config = this._mergeConfigObj(config)
+    config = this._configAfterMerge(config)
+    this._typeCheckConfig(config)
+    return config
+  }
 
+  _configAfterMerge(config) {
     config.container = config.container === false ? document.body : getElement(config.container)
 
     if (typeof config.delay === 'number') {
@@ -595,7 +599,6 @@ class Tooltip extends BaseComponent {
       config.content = config.content.toString()
     }
 
-    typeCheckConfig(NAME, config, this.constructor.DefaultType)
     return config
   }
 
index fb1b2776bcc103db57caee099817324fbaaa3ccf..63f2b581c6a6bf7fe12f2ed1afea04b1ed4069b7 100644 (file)
@@ -6,7 +6,8 @@
  */
 
 import EventHandler from '../dom/event-handler'
-import { execute, executeAfterTransition, getElement, reflow, typeCheckConfig } from './index'
+import { execute, executeAfterTransition, getElement, reflow } from './index'
+import Config from './config'
 
 /**
  * Constants
@@ -37,13 +38,27 @@ const DefaultType = {
  * Class definition
  */
 
-class Backdrop {
+class Backdrop extends Config {
   constructor(config) {
+    super()
     this._config = this._getConfig(config)
     this._isAppended = false
     this._element = null
   }
 
+  // Getters
+  static get Default() {
+    return Default
+  }
+
+  static get DefaultType() {
+    return DefaultType
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
   // Public
   show(callback) {
     if (!this._config.isVisible) {
@@ -104,15 +119,9 @@ class Backdrop {
     return this._element
   }
 
-  _getConfig(config) {
-    config = {
-      ...Default,
-      ...(typeof config === 'object' ? config : {})
-    }
-
+  _configAfterMerge(config) {
     // use getElement() with the default "body" to get a fresh Element on each instantiation
     config.rootElement = getElement(config.rootElement)
-    typeCheckConfig(NAME, config, DefaultType)
     return config
   }
 
diff --git a/js/src/util/config.js b/js/src/util/config.js
new file mode 100644 (file)
index 0000000..19d0295
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): util/config.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import { isElement, toType } from './index'
+import Manipulator from '../dom/manipulator'
+
+/**
+ * Class definition
+ */
+
+class Config {
+  // Getters
+  static get Default() {
+    return {}
+  }
+
+  static get DefaultType() {
+    return {}
+  }
+
+  static get NAME() {
+    throw new Error('You have to implement the static method "NAME", for each component!')
+  }
+
+  _getConfig(config) {
+    config = this._mergeConfigObj(config)
+    config = this._configAfterMerge(config)
+    this._typeCheckConfig(config)
+    return config
+  }
+
+  _configAfterMerge(config) {
+    return config
+  }
+
+  _mergeConfigObj(config, element) {
+    return {
+      ...this.constructor.Default,
+      ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),
+      ...(typeof config === 'object' ? config : {})
+    }
+  }
+
+  _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {
+    for (const property of Object.keys(configTypes)) {
+      const expectedTypes = configTypes[property]
+      const value = config[property]
+      const valueType = isElement(value) ? 'element' : toType(value)
+
+      if (!new RegExp(expectedTypes).test(valueType)) {
+        throw new TypeError(
+          `${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
+        )
+      }
+    }
+  }
+}
+
+export default Config
index a1975f4899fdaa11427b7751f793d608b42c558e..46727ecf8a88f405c9633c7548b9e4eb4b18266b 100644 (file)
@@ -7,7 +7,7 @@
 
 import EventHandler from '../dom/event-handler'
 import SelectorEngine from '../dom/selector-engine'
-import { typeCheckConfig } from './index'
+import Config from './config'
 
 /**
  * Constants
@@ -37,13 +37,27 @@ const DefaultType = {
  * Class definition
  */
 
-class FocusTrap {
+class FocusTrap extends Config {
   constructor(config) {
+    super()
     this._config = this._getConfig(config)
     this._isActive = false
     this._lastTabNavDirection = null
   }
 
+  // Getters
+  static get Default() {
+    return Default
+  }
+
+  static get DefaultType() {
+    return DefaultType
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
   // Public
   activate() {
     const { trapElement, autofocus } = this._config
@@ -99,15 +113,6 @@ class FocusTrap {
 
     this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD
   }
-
-  _getConfig(config) {
-    config = {
-      ...Default,
-      ...(typeof config === 'object' ? config : {})
-    }
-    typeCheckConfig(NAME, config, DefaultType)
-    return config
-  }
 }
 
 export default FocusTrap
index 0407100d8b9180195fdfe5994add772fbc72b368..8bd614d40c48b3ec0341d974cc0331e7b7ac2e8f 100644 (file)
@@ -123,20 +123,6 @@ const getElement = object => {
   return null
 }
 
-const typeCheckConfig = (componentName, config, configTypes) => {
-  for (const property of Object.keys(configTypes)) {
-    const expectedTypes = configTypes[property]
-    const value = config[property]
-    const valueType = value && isElement(value) ? 'element' : toType(value)
-
-    if (!new RegExp(expectedTypes).test(valueType)) {
-      throw new TypeError(
-        `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
-      )
-    }
-  }
-}
-
 const isVisible = element => {
   if (!isElement(element) || element.getClientRects().length === 0) {
     return false
@@ -327,5 +313,5 @@ export {
   onDOMContentLoaded,
   reflow,
   triggerTransitionEnd,
-  typeCheckConfig
+  toType
 }
index 87a5f7f5ae800146adf0447410b8bb9da385b2b3..ac09b6fa1399228fa6d9caa713d64b338dd2e460 100644 (file)
@@ -5,8 +5,9 @@
  * --------------------------------------------------------------------------
  */
 
+import Config from './config'
 import EventHandler from '../dom/event-handler'
-import { execute, typeCheckConfig } from './index'
+import { execute } from './index'
 
 /**
  * Constants
@@ -40,8 +41,9 @@ const DefaultType = {
  * Class definition
  */
 
-class Swipe {
+class Swipe extends Config {
   constructor(element, config) {
+    super()
     this._element = element
 
     if (!element || !Swipe.isSupported()) {
@@ -54,6 +56,19 @@ class Swipe {
     this._initEvents()
   }
 
+  // Getters
+  static get Default() {
+    return Default
+  }
+
+  static get DefaultType() {
+    return DefaultType
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
   // Public
   dispose() {
     EventHandler.off(this._element, EVENT_KEY)
@@ -118,15 +133,6 @@ class Swipe {
     }
   }
 
-  _getConfig(config) {
-    config = {
-      ...Default,
-      ...(typeof config === 'object' ? config : {})
-    }
-    typeCheckConfig(NAME, config, DefaultType)
-    return config
-  }
-
   _eventIsPointerPenTouch(event) {
     return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)
   }
index a9cee1086c20208235bcea95bc37e6194b03e47e..8a8d4da7984fa86e02b5a66b94014eed0ab904ea 100644 (file)
@@ -6,8 +6,9 @@
  */
 
 import { DefaultAllowlist, sanitizeHtml } from './sanitizer'
-import { getElement, isElement, typeCheckConfig } from '../util/index'
+import { getElement, isElement } from '../util/index'
 import SelectorEngine from '../dom/selector-engine'
+import Config from './config'
 
 /**
  * Constants
@@ -44,20 +45,25 @@ const DefaultContentType = {
  * Class definition
  */
 
-class TemplateFactory {
+class TemplateFactory extends Config {
   constructor(config) {
+    super()
     this._config = this._getConfig(config)
   }
 
   // Getters
-  static get NAME() {
-    return NAME
-  }
-
   static get Default() {
     return Default
   }
 
+  static get DefaultType() {
+    return DefaultType
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
   // Public
   getContent() {
     return Object.values(this._config.content)
@@ -94,21 +100,14 @@ class TemplateFactory {
   }
 
   // Private
-  _getConfig(config) {
-    config = {
-      ...Default,
-      ...(typeof config === 'object' ? config : {})
-    }
-
-    typeCheckConfig(NAME, config, DefaultType)
+  _typeCheckConfig(config) {
+    super._typeCheckConfig(config)
     this._checkContent(config.content)
-
-    return config
   }
 
   _checkContent(arg) {
     for (const [selector, content] of Object.entries(arg)) {
-      typeCheckConfig(NAME, { selector, entry: content }, DefaultContentType)
+      super._typeCheckConfig({ selector, entry: content }, DefaultContentType)
     }
   }
 
diff --git a/js/tests/unit/util/config.spec.js b/js/tests/unit/util/config.spec.js
new file mode 100644 (file)
index 0000000..a8f8962
--- /dev/null
@@ -0,0 +1,78 @@
+import Config from '../../../src/util/config'
+
+class DummyConfigClass extends Config {
+  static get NAME() {
+    return 'dummy'
+  }
+}
+
+describe('Config', () => {
+  const name = 'dummy'
+  describe('NAME', () => {
+    it('should return plugin NAME', () => {
+      expect(DummyConfigClass.NAME).toEqual(name)
+    })
+  })
+
+  describe('DefaultType', () => {
+    it('should return plugin default type', () => {
+      expect(DummyConfigClass.DefaultType).toEqual(jasmine.any(Object))
+    })
+  })
+
+  describe('Default', () => {
+    it('should return plugin defaults', () => {
+      expect(DummyConfigClass.Default).toEqual(jasmine.any(Object))
+    })
+  })
+
+  describe('typeCheckConfig', () => {
+    it('should check type of the config object', () => {
+      spyOnProperty(DummyConfigClass, 'DefaultType', 'get').and.returnValue({
+        toggle: 'boolean',
+        parent: '(string|element)'
+      })
+      const config = {
+        toggle: true,
+        parent: 777
+      }
+
+      const obj = new DummyConfigClass()
+      expect(() => {
+        obj._typeCheckConfig(config)
+      }).toThrowError(TypeError, obj.constructor.NAME.toUpperCase() + ': Option "parent" provided type "number" but expected type "(string|element)".')
+    })
+
+    it('should return null stringified when null is passed', () => {
+      spyOnProperty(DummyConfigClass, 'DefaultType', 'get').and.returnValue({
+        toggle: 'boolean',
+        parent: '(null|element)'
+      })
+
+      const obj = new DummyConfigClass()
+      const config = {
+        toggle: true,
+        parent: null
+      }
+
+      obj._typeCheckConfig(config)
+      expect().nothing()
+    })
+
+    it('should return undefined stringified when undefined is passed', () => {
+      spyOnProperty(DummyConfigClass, 'DefaultType', 'get').and.returnValue({
+        toggle: 'boolean',
+        parent: '(undefined|element)'
+      })
+
+      const obj = new DummyConfigClass()
+      const config = {
+        toggle: true,
+        parent: undefined
+      }
+
+      obj._typeCheckConfig(config)
+      expect().nothing()
+    })
+  })
+})
index ef6647e921a5e7b012f8ba10d7ad468fd1b775dc..52e64faa91aeac054316ffb0e24be0a17ac4f36b 100644 (file)
@@ -223,53 +223,6 @@ describe('Util', () => {
     })
   })
 
-  describe('typeCheckConfig', () => {
-    const namePlugin = 'collapse'
-
-    it('should check type of the config object', () => {
-      const defaultType = {
-        toggle: 'boolean',
-        parent: '(string|element)'
-      }
-      const config = {
-        toggle: true,
-        parent: 777
-      }
-
-      expect(() => {
-        Util.typeCheckConfig(namePlugin, config, defaultType)
-      }).toThrowError(TypeError, 'COLLAPSE: Option "parent" provided type "number" but expected type "(string|element)".')
-    })
-
-    it('should return null stringified when null is passed', () => {
-      const defaultType = {
-        toggle: 'boolean',
-        parent: '(null|element)'
-      }
-      const config = {
-        toggle: true,
-        parent: null
-      }
-
-      Util.typeCheckConfig(namePlugin, config, defaultType)
-      expect().nothing()
-    })
-
-    it('should return undefined stringified when undefined is passed', () => {
-      const defaultType = {
-        toggle: 'boolean',
-        parent: '(undefined|element)'
-      }
-      const config = {
-        toggle: true,
-        parent: undefined
-      }
-
-      Util.typeCheckConfig(namePlugin, config, defaultType)
-      expect().nothing()
-    })
-  })
-
   describe('isVisible', () => {
     it('should return false if the element is not defined', () => {
       expect(Util.isVisible(null)).toBeFalse()