fix
This commit is contained in:
@@ -0,0 +1,915 @@
|
||||
import React, { PureComponent } from "react"
|
||||
import { fromJS } from "immutable"
|
||||
import { render, mount } from "enzyme"
|
||||
import { Provider } from "react-redux"
|
||||
|
||||
import System from "core/system"
|
||||
import ViewPlugin from "core/plugins/view/index.js"
|
||||
import filterPlugin from "core/plugins/filter/index.js"
|
||||
|
||||
describe("bound system", function(){
|
||||
|
||||
describe("wrapActions", function(){
|
||||
|
||||
it("should replace an action", function(){
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: {
|
||||
statePlugins: {
|
||||
josh: {
|
||||
actions: {
|
||||
simple: () => {
|
||||
return { type: "simple" }
|
||||
}
|
||||
},
|
||||
wrapActions: {
|
||||
simple: () => () => {
|
||||
return { type: "newSimple" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// When
|
||||
let action = system.getSystem().joshActions.simple(1)
|
||||
expect(action).toEqual({
|
||||
type: "newSimple"
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
it("should expose the original action, and the system as args", function(){
|
||||
// Given
|
||||
const simple = () => ({type: "simple" })
|
||||
const system = new System({
|
||||
plugins: {
|
||||
statePlugins: {
|
||||
josh: {
|
||||
actions: { simple },
|
||||
wrapActions: {
|
||||
simple: (oriAction, system) => (actionArg) => {
|
||||
return {
|
||||
type: "newSimple",
|
||||
oriActionResult: oriAction(),
|
||||
system: system.getSystem(),
|
||||
actionArg
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// When
|
||||
let action = system.getSystem().joshActions.simple(1)
|
||||
expect(action).toEqual({
|
||||
type: "newSimple",
|
||||
oriActionResult: { type: "simple" },
|
||||
system: system.getSystem(),
|
||||
actionArg: 1
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
it("should support multiple wraps of the same action", function(){
|
||||
const system = new System({
|
||||
plugins: [
|
||||
{
|
||||
statePlugins: {
|
||||
kyle: {
|
||||
actions: {
|
||||
simple: () => {
|
||||
return {
|
||||
type: "simple",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
statePlugins: {
|
||||
kyle: {
|
||||
wrapActions: {
|
||||
simple: (ori) => () => {
|
||||
return {
|
||||
...ori(),
|
||||
firstWrap: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
statePlugins: {
|
||||
kyle: {
|
||||
wrapActions: {
|
||||
simple: (ori) => () => {
|
||||
return {
|
||||
...ori(),
|
||||
secondWrap: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let action = system.getSystem().kyleActions.simple(1)
|
||||
expect(action).toEqual({
|
||||
type: "simple",
|
||||
firstWrap: true,
|
||||
secondWrap: true,
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
it("should execute wrapActions in the order they appear ( via plugins )", function(){
|
||||
const system = new System({
|
||||
plugins: [
|
||||
{
|
||||
statePlugins: {
|
||||
kyle: {
|
||||
actions: {
|
||||
simple: () => {
|
||||
return {
|
||||
type: "one",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
statePlugins: {
|
||||
kyle: {
|
||||
wrapActions: {
|
||||
simple: (ori) => () => {
|
||||
const obj = ori()
|
||||
obj.type += "-two"
|
||||
return obj
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
statePlugins: {
|
||||
kyle: {
|
||||
wrapActions: {
|
||||
simple: (ori) => () => {
|
||||
const obj = ori()
|
||||
obj.type += "-three"
|
||||
return obj
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let action = system.getSystem().kyleActions.simple(1)
|
||||
expect(action.type).toEqual("one-two-three")
|
||||
|
||||
})
|
||||
|
||||
it("should have a the latest system", function(){
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: [
|
||||
{
|
||||
statePlugins: {
|
||||
kyle: {
|
||||
actions: {
|
||||
simple: () => {
|
||||
return {
|
||||
type: "one",
|
||||
}
|
||||
}
|
||||
},
|
||||
wrapActions: {
|
||||
simple: (ori, {joshActions}) => () => {
|
||||
return joshActions.hello()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
const kyleActions = system.getSystem().kyleActions
|
||||
|
||||
system.register({
|
||||
statePlugins: {
|
||||
josh: {
|
||||
actions: {
|
||||
hello(){ return {type: "hello" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const action = kyleActions.simple()
|
||||
expect(action).toEqual({ type: "hello"})
|
||||
})
|
||||
|
||||
it.skip("should be able to create async actions", function(){
|
||||
const system = new System({
|
||||
plugins: [
|
||||
{
|
||||
statePlugins: {
|
||||
kyle: {
|
||||
actions: {
|
||||
simple: () => {
|
||||
return {
|
||||
type: "one",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
statePlugins: {
|
||||
kyle: {
|
||||
wrapActions: {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
simple: (ori) => (arg) => (sys) => {
|
||||
return { type: "called" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let action = system.getSystem().kyleActions.simple(1)
|
||||
expect(action.type).toEqual("called")
|
||||
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
|
||||
describe("fn", function() {
|
||||
|
||||
it("should return helper functions", function () {
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: [
|
||||
filterPlugin
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
const fn = system.getSystem().fn.opsFilter
|
||||
expect(typeof fn).toEqual("function")
|
||||
})
|
||||
})
|
||||
|
||||
describe("selectors", function(){
|
||||
|
||||
it("should have the first arg be the nested state, and all other args to follow", function(){
|
||||
|
||||
// Given
|
||||
const system = new System({
|
||||
state: {
|
||||
josh: {
|
||||
one: 1
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
statePlugins: {
|
||||
josh: {
|
||||
selectors: {
|
||||
simple: (state, arg1) => {
|
||||
return { state, arg1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// When
|
||||
let res = system.getSystem().joshSelectors.simple(1)
|
||||
expect(res).toEqual({
|
||||
state: fromJS({
|
||||
one: 1
|
||||
}),
|
||||
arg1: 1
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("when selector returns a function", function(){
|
||||
|
||||
it("should pass the system to that function", function(){
|
||||
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: {
|
||||
statePlugins: {
|
||||
josh: {
|
||||
selectors: {
|
||||
advanced: () => (mySystem) => {
|
||||
// Then
|
||||
expect(mySystem).toEqual(system.getSystem())
|
||||
return "hi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// When
|
||||
let res = system.getSystem().joshSelectors.advanced(1)
|
||||
expect(res).toEqual("hi")
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("wrapSelectors", () => {
|
||||
it("should wrap a selector and provide a reference to the original", function(){
|
||||
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: [
|
||||
{
|
||||
statePlugins: {
|
||||
doge: {
|
||||
selectors: {
|
||||
wow: () => (system) => {
|
||||
return "original"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
statePlugins: {
|
||||
doge: {
|
||||
wrapSelectors: {
|
||||
wow: (ori) => (system) => {
|
||||
// Then
|
||||
return ori() + " wrapper"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let res = system.getSystem().dogeSelectors.wow(1)
|
||||
expect(res).toEqual("original wrapper")
|
||||
|
||||
})
|
||||
|
||||
it("should provide a live reference to the system to a wrapper", function(done){
|
||||
|
||||
// Given
|
||||
const mySystem = new System({
|
||||
plugins: [
|
||||
{
|
||||
statePlugins: {
|
||||
doge: {
|
||||
selectors: {
|
||||
wow: () => (system) => {
|
||||
return "original"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
statePlugins: {
|
||||
doge: {
|
||||
wrapSelectors: {
|
||||
wow: (ori, system) => () => {
|
||||
// Then
|
||||
expect(mySystem.getSystem()).toEqual(system.getSystem())
|
||||
done()
|
||||
return ori() + " wrapper"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
mySystem.getSystem().dogeSelectors.wow(1)
|
||||
})
|
||||
|
||||
it("should provide the state as the first argument to the inner function", function(done){
|
||||
|
||||
// Given
|
||||
const mySystem = new System({
|
||||
state: {
|
||||
doge: {
|
||||
abc: "123"
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
{
|
||||
statePlugins: {
|
||||
doge: {
|
||||
selectors: {
|
||||
wow: () => (system) => {
|
||||
return "original"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
statePlugins: {
|
||||
doge: {
|
||||
wrapSelectors: {
|
||||
wow: (ori, system) => (dogeState) => {
|
||||
// Then
|
||||
expect(dogeState.toJS().abc).toEqual("123")
|
||||
done()
|
||||
return ori() + " wrapper"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
mySystem.getSystem().dogeSelectors.wow(1)
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("getComponent", function() {
|
||||
it("returns a component from the system", function() {
|
||||
const system = new System({
|
||||
plugins: [
|
||||
ViewPlugin,
|
||||
{
|
||||
components: {
|
||||
test: ({ name }) => <div>{name} component</div>
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let Component = system.getSystem().getComponent("test")
|
||||
const renderedComponent = render(<Component name="Test" />)
|
||||
expect(renderedComponent.text()).toEqual("Test component")
|
||||
})
|
||||
|
||||
it("allows container components to provide their own `mapStateToProps` function", function() {
|
||||
// Given
|
||||
class ContainerComponent extends PureComponent {
|
||||
mapStateToProps(nextState, props) {
|
||||
return {
|
||||
"fromMapState": "This came from mapStateToProps"
|
||||
}
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
"fromMapState" : ""
|
||||
}
|
||||
|
||||
render() {
|
||||
const { exampleSelectors, fromMapState, fromOwnProps } = this.props
|
||||
return (
|
||||
<div>{ fromMapState } {exampleSelectors.foo()} {fromOwnProps}</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
const system = new System({
|
||||
plugins: [
|
||||
ViewPlugin,
|
||||
{
|
||||
components: {
|
||||
ContainerComponent
|
||||
}
|
||||
},
|
||||
{
|
||||
statePlugins: {
|
||||
example: {
|
||||
selectors: {
|
||||
foo() { return "and this came from the system" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let Component = system.getSystem().getComponent("ContainerComponent", true)
|
||||
const renderedComponent = render(
|
||||
<Provider store={system.getStore()}>
|
||||
<Component fromOwnProps="and this came from my own props" />
|
||||
</Provider>
|
||||
)
|
||||
|
||||
// Then
|
||||
expect(renderedComponent.text()).toEqual("This came from mapStateToProps and this came from the system and this came from my own props")
|
||||
})
|
||||
|
||||
it("gives the system and own props as props to a container's `mapStateToProps` function", function() {
|
||||
// Given
|
||||
class ContainerComponent extends PureComponent {
|
||||
mapStateToProps(nextState, props) {
|
||||
const { exampleSelectors, fromMapState, fromOwnProps } = props
|
||||
return {
|
||||
"fromMapState": `This came from mapStateToProps ${exampleSelectors.foo()} ${fromOwnProps}`
|
||||
}
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
"fromMapState" : ""
|
||||
}
|
||||
|
||||
render() {
|
||||
const { fromMapState } = this.props
|
||||
return (
|
||||
<div>{ fromMapState }</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
const system = new System({
|
||||
plugins: [
|
||||
ViewPlugin,
|
||||
{
|
||||
components: {
|
||||
ContainerComponent
|
||||
}
|
||||
},
|
||||
{
|
||||
statePlugins: {
|
||||
example: {
|
||||
selectors: {
|
||||
foo() { return "and this came from the system" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let Component = system.getSystem().getComponent("ContainerComponent", true)
|
||||
const renderedComponent = render(
|
||||
<Provider store={system.getStore()}>
|
||||
<Component fromOwnProps="and this came from my own props" />
|
||||
</Provider>
|
||||
)
|
||||
|
||||
// Then
|
||||
expect(renderedComponent.text()).toEqual("This came from mapStateToProps and this came from the system and this came from my own props")
|
||||
})
|
||||
})
|
||||
|
||||
describe("afterLoad", function() {
|
||||
it("should call a plugin's `afterLoad` method after the plugin is loaded", function() {
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: [
|
||||
{
|
||||
afterLoad(system) {
|
||||
this.rootInjects.wow = system.dogeSelectors.wow
|
||||
},
|
||||
statePlugins: {
|
||||
doge: {
|
||||
selectors: {
|
||||
wow: () => (system) => {
|
||||
return "so selective"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let res = system.getSystem().wow()
|
||||
expect(res).toEqual("so selective")
|
||||
})
|
||||
it("should call a preset plugin's `afterLoad` method after the plugin is loaded", function() {
|
||||
// Given
|
||||
const MyPlugin = {
|
||||
afterLoad(system) {
|
||||
this.rootInjects.wow = system.dogeSelectors.wow
|
||||
},
|
||||
statePlugins: {
|
||||
doge: {
|
||||
selectors: {
|
||||
wow: () => (system) => {
|
||||
return "so selective"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const system = new System({
|
||||
plugins: [
|
||||
[MyPlugin]
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let res = system.getSystem().wow()
|
||||
expect(res).toEqual("so selective")
|
||||
})
|
||||
it("should call a function preset plugin's `afterLoad` method after the plugin is loaded", function() {
|
||||
// Given
|
||||
const MyPlugin = {
|
||||
afterLoad(system) {
|
||||
this.rootInjects.wow = system.dogeSelectors.wow
|
||||
},
|
||||
statePlugins: {
|
||||
doge: {
|
||||
selectors: {
|
||||
wow: () => (system) => {
|
||||
return "so selective"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const system = new System({
|
||||
plugins: [
|
||||
() => {
|
||||
return [MyPlugin]
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let res = system.getSystem().wow()
|
||||
expect(res).toEqual("so selective")
|
||||
})
|
||||
it("should call a registered plugin's `afterLoad` method after the plugin is loaded", function() {
|
||||
// Given
|
||||
const MyPlugin = {
|
||||
afterLoad(system) {
|
||||
this.rootInjects.wow = system.dogeSelectors.wow
|
||||
},
|
||||
statePlugins: {
|
||||
doge: {
|
||||
selectors: {
|
||||
wow: () => (system) => {
|
||||
return "so selective"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const system = new System({
|
||||
plugins: []
|
||||
})
|
||||
|
||||
system.register([MyPlugin])
|
||||
|
||||
// When
|
||||
let res = system.getSystem().wow()
|
||||
expect(res).toEqual("so selective")
|
||||
})
|
||||
})
|
||||
|
||||
describe("rootInjects", function() {
|
||||
it("should attach a rootInject function as an instance method", function() {
|
||||
// This is the same thing as the `afterLoad` tests, but is here for posterity
|
||||
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: [
|
||||
{
|
||||
afterLoad(system) {
|
||||
this.rootInjects.wow = system.dogeSelectors.wow
|
||||
},
|
||||
statePlugins: {
|
||||
doge: {
|
||||
selectors: {
|
||||
wow: () => (system) => {
|
||||
return "so selective"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let res = system.getSystem().wow()
|
||||
expect(res).toEqual("so selective")
|
||||
})
|
||||
})
|
||||
|
||||
describe("error catching", function() {
|
||||
it("should encapsulate thrown errors in an afterLoad method", function() {
|
||||
// Given
|
||||
const ThrowyPlugin = {
|
||||
afterLoad(system) {
|
||||
throw new Error("afterLoad BREAKS STUFF!")
|
||||
},
|
||||
statePlugins: {
|
||||
doge: {
|
||||
selectors: {
|
||||
wow: () => (system) => {
|
||||
return "so selective"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const system = new System({
|
||||
plugins: []
|
||||
})
|
||||
|
||||
|
||||
// When
|
||||
expect(() => {
|
||||
system.register([ThrowyPlugin])
|
||||
// let resSystem = system.getSystem()
|
||||
}).not.toThrow()
|
||||
})
|
||||
|
||||
it("should encapsulate thrown errors in an action creator", function(){
|
||||
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: {
|
||||
statePlugins: {
|
||||
throw: {
|
||||
actions: {
|
||||
func() {
|
||||
throw new Error("this action creator THROWS!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
expect(() => {
|
||||
// TODO: fix existing action error catcher that creates THROWN ERR actions
|
||||
system.getSystem().throwActions.func()
|
||||
}).not.toThrow()
|
||||
})
|
||||
|
||||
it("should encapsulate thrown errors in a reducer", function(){
|
||||
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: {
|
||||
statePlugins: {
|
||||
throw: {
|
||||
actions: {
|
||||
func: () => {
|
||||
return {
|
||||
type: "THROW_FUNC",
|
||||
payload: "BOOM!"
|
||||
}
|
||||
}
|
||||
},
|
||||
reducers: {
|
||||
"THROW_FUNC": (state, action) => {
|
||||
throw new Error("this reducer EXPLODES!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
expect(() => {
|
||||
system.getSystem().throwActions.func()
|
||||
}).not.toThrow()
|
||||
})
|
||||
|
||||
it("should encapsulate thrown errors in a selector", function(){
|
||||
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: {
|
||||
statePlugins: {
|
||||
throw: {
|
||||
selectors: {
|
||||
func: (state, arg1) => {
|
||||
throw new Error("this selector THROWS!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
expect(system.getSystem().throwSelectors.func).not.toThrow()
|
||||
})
|
||||
|
||||
it("should encapsulate thrown errors in a complex selector", function(){
|
||||
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: {
|
||||
statePlugins: {
|
||||
throw: {
|
||||
selectors: {
|
||||
func: (state, arg1) => system => {
|
||||
throw new Error("this selector THROWS!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
expect(system.getSystem().throwSelectors.func).not.toThrow()
|
||||
})
|
||||
|
||||
it("should encapsulate thrown errors in a wrapAction", function(){
|
||||
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: {
|
||||
statePlugins: {
|
||||
throw: {
|
||||
actions: {
|
||||
func: () => {
|
||||
return {
|
||||
type: "THROW_FUNC",
|
||||
payload: "this original action does NOT throw"
|
||||
}
|
||||
}
|
||||
},
|
||||
wrapActions: {
|
||||
func: (ori) => (...args) => {
|
||||
throw new Error("this wrapAction UNRAVELS EVERYTHING!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
expect(system.getSystem().throwActions.func).not.toThrow()
|
||||
})
|
||||
|
||||
it("should encapsulate thrown errors in a wrapSelector", function(){
|
||||
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: {
|
||||
statePlugins: {
|
||||
throw: {
|
||||
selectors: {
|
||||
func: (state, arg1) => {
|
||||
return 123
|
||||
}
|
||||
},
|
||||
wrapSelectors: {
|
||||
func: (ori) => (...props) => {
|
||||
return ori(...props)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
expect(system.getSystem().throwSelectors.func).not.toThrow()
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,307 @@
|
||||
import React from "react"
|
||||
|
||||
import { render } from "enzyme"
|
||||
import System from "core/system"
|
||||
|
||||
describe("wrapComponents", () => {
|
||||
describe("should wrap a component and provide a reference to the original", () => {
|
||||
it("with stateless components", function () {
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: [
|
||||
{
|
||||
components: {
|
||||
wow: ({ name }) => <div>{name} component</div>
|
||||
}
|
||||
},
|
||||
{
|
||||
wrapComponents: {
|
||||
wow: (OriginalComponent) => (props) => {
|
||||
return <container>
|
||||
<OriginalComponent {...props}></OriginalComponent>
|
||||
<OriginalComponent name="Wrapped"></OriginalComponent>
|
||||
</container>
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let Component = system.getSystem().getComponents("wow")
|
||||
const wrapper = render(<Component name="Normal" />)
|
||||
|
||||
expect(wrapper.get(0).name).toEqual("container")
|
||||
|
||||
const children = wrapper.children()
|
||||
expect(children.length).toEqual(2)
|
||||
expect(children.eq(0).text()).toEqual("Normal component")
|
||||
expect(children.eq(1).text()).toEqual("Wrapped component")
|
||||
})
|
||||
|
||||
it("with React classes", function () {
|
||||
class MyComponent extends React.Component {
|
||||
render() {
|
||||
return <div>{this.props.name} component</div>
|
||||
}
|
||||
}
|
||||
|
||||
// Given
|
||||
const system = new System({
|
||||
plugins: [
|
||||
{
|
||||
components: {
|
||||
wow: MyComponent
|
||||
}
|
||||
},
|
||||
{
|
||||
wrapComponents: {
|
||||
wow: (OriginalComponent) => {
|
||||
return class WrapperComponent extends React.Component {
|
||||
render() {
|
||||
return <container>
|
||||
<OriginalComponent {...this.props}></OriginalComponent>
|
||||
<OriginalComponent name="Wrapped"></OriginalComponent>
|
||||
</container>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// When
|
||||
let Component = system.getSystem().getComponents("wow")
|
||||
const wrapper = render(<Component name="Normal" />)
|
||||
|
||||
expect(wrapper.get(0).name).toEqual("container")
|
||||
|
||||
const children = wrapper.children()
|
||||
expect(children.length).toEqual(2)
|
||||
expect(children.eq(0).text()).toEqual("Normal component")
|
||||
expect(children.eq(1).text()).toEqual("Wrapped component")
|
||||
})
|
||||
})
|
||||
|
||||
it("should provide a reference to the system to the wrapper", function () {
|
||||
|
||||
// Given
|
||||
|
||||
const mySystem = new System({
|
||||
plugins: [
|
||||
{
|
||||
// Make a selector
|
||||
statePlugins: {
|
||||
doge: {
|
||||
selectors: {
|
||||
wow: () => () => {
|
||||
return "WOW much data"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
// Create a component
|
||||
components: {
|
||||
wow: () => <div>Original component</div>
|
||||
}
|
||||
},
|
||||
{
|
||||
// Wrap the component and use the system
|
||||
wrapComponents: {
|
||||
wow: (OriginalComponent, system) => (props) => {
|
||||
return <container>
|
||||
<OriginalComponent {...props}></OriginalComponent>
|
||||
<div>{system.dogeSelectors.wow()}</div>
|
||||
</container>
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// Then
|
||||
let Component = mySystem.getSystem().getComponents("wow")
|
||||
const wrapper = render(<Component name="Normal" />)
|
||||
|
||||
expect(wrapper.get(0).name).toEqual("container")
|
||||
|
||||
const children = wrapper.children()
|
||||
expect(children.length).toEqual(2)
|
||||
expect(children.eq(0).text()).toEqual("Original component")
|
||||
expect(children.eq(1).text()).toEqual("WOW much data")
|
||||
})
|
||||
|
||||
it("should wrap correctly when registering more plugins", function () {
|
||||
|
||||
// Given
|
||||
|
||||
const mySystem = new System({
|
||||
plugins: [
|
||||
() => {
|
||||
return {
|
||||
statePlugins: {
|
||||
doge: {
|
||||
selectors: {
|
||||
wow: () => () => {
|
||||
return "WOW much data"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
wow: () => <div>Original component</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
mySystem.register([
|
||||
function () {
|
||||
return {
|
||||
// Wrap the component and use the system
|
||||
wrapComponents: {
|
||||
wow: (OriginalComponent, system) => (props) => {
|
||||
return <container>
|
||||
<OriginalComponent {...props}></OriginalComponent>
|
||||
<div>{system.dogeSelectors.wow()}</div>
|
||||
</container>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
// Then
|
||||
let Component = mySystem.getSystem().getComponents("wow")
|
||||
const wrapper = render(<Component name="Normal" />)
|
||||
|
||||
expect(wrapper.get(0).name).toEqual("container")
|
||||
|
||||
const children = wrapper.children()
|
||||
expect(children.length).toEqual(2)
|
||||
expect(children.eq(0).text()).toEqual("Original component")
|
||||
expect(children.eq(1).text()).toEqual("WOW much data")
|
||||
})
|
||||
|
||||
it("should wrap correctly when registering multiple plugins targeting the same component", function () {
|
||||
|
||||
// Given
|
||||
|
||||
const mySystem = new System({
|
||||
pluginsOptions: {
|
||||
pluginLoadType: "chain"
|
||||
},
|
||||
plugins: [
|
||||
() => {
|
||||
return {
|
||||
components: {
|
||||
wow: () => <div>Original component</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
mySystem.register([
|
||||
() => {
|
||||
return {
|
||||
wrapComponents: {
|
||||
wow: (OriginalComponent, system) => (props) => {
|
||||
return <container1>
|
||||
<OriginalComponent {...props}></OriginalComponent>
|
||||
<div>Injected after</div>
|
||||
</container1>
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
() => {
|
||||
return {
|
||||
wrapComponents: {
|
||||
wow: (OriginalComponent, system) => (props) => {
|
||||
return <container2>
|
||||
<div>Injected before</div>
|
||||
<OriginalComponent {...props}></OriginalComponent>
|
||||
</container2>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
// Then
|
||||
let Component = mySystem.getSystem().getComponents("wow")
|
||||
const wrapper = render(<Component name="Normal" />)
|
||||
|
||||
expect(wrapper.get(0).name).toEqual("container2")
|
||||
|
||||
const children2 = wrapper.children()
|
||||
expect(children2.length).toEqual(2)
|
||||
expect(children2[0].name).toEqual("div")
|
||||
expect(children2.eq(0).text()).toEqual("Injected before")
|
||||
expect(children2[1].name).toEqual("container1")
|
||||
|
||||
const children1 = children2.children()
|
||||
expect(children1.length).toEqual(2)
|
||||
expect(children1.eq(0).text()).toEqual("Original component")
|
||||
expect(children1[0].name).toEqual("div")
|
||||
expect(children1.eq(1).text()).toEqual("Injected after")
|
||||
})
|
||||
|
||||
it("should wrap correctly when building a system twice", function () {
|
||||
|
||||
// Given
|
||||
|
||||
const pluginOne = {
|
||||
statePlugins: {
|
||||
doge: {
|
||||
selectors: {
|
||||
wow: () => () => {
|
||||
return "WOW much data"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
wow: () => <div>Original component</div>
|
||||
}
|
||||
}
|
||||
|
||||
const pluginTwo = {
|
||||
// Wrap the component and use the system
|
||||
wrapComponents: {
|
||||
wow: (OriginalComponent, system) => (props) => {
|
||||
return <container>
|
||||
<OriginalComponent {...props}></OriginalComponent>
|
||||
<div>{system.dogeSelectors.wow()}</div>
|
||||
</container>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bothPlugins = () => [pluginOne, pluginTwo]
|
||||
|
||||
new System({
|
||||
plugins: bothPlugins
|
||||
})
|
||||
|
||||
const secondSystem = new System({
|
||||
plugins: bothPlugins
|
||||
})
|
||||
|
||||
// Then
|
||||
let Component = secondSystem.getSystem().getComponents("wow")
|
||||
const wrapper = render(<Component name="Normal" />)
|
||||
|
||||
expect(wrapper.get(0).name).toEqual("container")
|
||||
|
||||
const children = wrapper.children()
|
||||
expect(children.length).toEqual(2)
|
||||
expect(children.eq(0).text()).toEqual("Original component")
|
||||
expect(children.eq(1).text()).toEqual("WOW much data")
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,45 @@
|
||||
import System from "core/system"
|
||||
|
||||
describe("wrapSelectors", () => {
|
||||
it("should wrap correctly when registering multiple plugins targeting the same selector", function() {
|
||||
const probeBase = {
|
||||
statePlugins: {
|
||||
probe: {
|
||||
selectors: {
|
||||
selectProbe: () => {
|
||||
return "base"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const probeWrap1 = {
|
||||
statePlugins: {
|
||||
probe: {
|
||||
wrapSelectors: {
|
||||
selectProbe: (oriSelector) => (state, ...args) => {
|
||||
const selectedValue = oriSelector(state, ...args)
|
||||
return `${selectedValue}wrap1`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const probeWrap2 = {
|
||||
statePlugins: {
|
||||
probe: {
|
||||
wrapSelectors: {
|
||||
selectProbe: (oriSelector) => (state, ...args) => {
|
||||
const selectedValue = oriSelector(state, ...args)
|
||||
return `${selectedValue}wrap2`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const system = new System({ plugins: [probeBase, probeWrap1, probeWrap2] })
|
||||
|
||||
expect(system.getSystem().probeSelectors.selectProbe()).toEqual("basewrap1wrap2")
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user