Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
6a84a85a
Commit
6a84a85a
authored
Jan 31, 2019
by
Hugo Häggmark
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added reducerTester, reducer tests and tests
parent
2f47b225
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
275 additions
and
1 deletions
+275
-1
public/app/features/datasources/state/reducers.test.ts
+137
-0
public/app/features/datasources/state/reducers.ts
+1
-1
public/test/core/redux/reducerTester.test.ts
+58
-0
public/test/core/redux/reducerTester.ts
+79
-0
No files found.
public/app/features/datasources/state/reducers.test.ts
0 → 100644
View file @
6a84a85a
import
{
reducerTester
}
from
'test/core/redux/reducerTester'
;
import
{
dataSourcesReducer
,
initialState
}
from
'./reducers'
;
import
{
dataSourcesLoaded
,
dataSourceLoaded
,
setDataSourcesSearchQuery
,
setDataSourcesLayoutMode
,
dataSourceTypesLoad
,
dataSourceTypesLoaded
,
setDataSourceTypeSearchQuery
,
dataSourceMetaLoaded
,
setDataSourceName
,
setIsDefault
,
}
from
'./actions'
;
import
{
getMockDataSources
,
getMockDataSource
}
from
'../__mocks__/dataSourcesMocks'
;
import
{
LayoutModes
}
from
'app/core/components/LayoutSelector/LayoutSelector'
;
import
{
DataSourcesState
}
from
'app/types'
;
import
{
PluginMetaInfo
}
from
'@grafana/ui'
;
const
mockPlugin
=
()
=>
({
defaultNavUrl
:
'defaultNavUrl'
,
enabled
:
true
,
hasUpdate
:
true
,
id
:
'id'
,
info
:
{}
as
PluginMetaInfo
,
latestVersion
:
'latestVersion'
,
name
:
'name'
,
pinned
:
true
,
state
:
'state'
,
type
:
'type'
,
module
:
{},
});
describe
(
'dataSourcesReducer'
,
()
=>
{
describe
(
'when dataSourcesLoaded is dispatched'
,
()
=>
{
it
(
'then state should be correct'
,
()
=>
{
const
dataSources
=
getMockDataSources
(
0
);
reducerTester
()
.
givenReducer
(
dataSourcesReducer
,
initialState
)
.
whenActionIsDispatched
(
dataSourcesLoaded
(
dataSources
))
.
thenStateShouldEqual
({
...
initialState
,
hasFetched
:
true
,
dataSources
,
dataSourcesCount
:
1
});
});
});
describe
(
'when dataSourceLoaded is dispatched'
,
()
=>
{
it
(
'then state should be correct'
,
()
=>
{
const
dataSource
=
getMockDataSource
();
reducerTester
()
.
givenReducer
(
dataSourcesReducer
,
initialState
)
.
whenActionIsDispatched
(
dataSourceLoaded
(
dataSource
))
.
thenStateShouldEqual
({
...
initialState
,
dataSource
});
});
});
describe
(
'when setDataSourcesSearchQuery is dispatched'
,
()
=>
{
it
(
'then state should be correct'
,
()
=>
{
reducerTester
()
.
givenReducer
(
dataSourcesReducer
,
initialState
)
.
whenActionIsDispatched
(
setDataSourcesSearchQuery
(
'some query'
))
.
thenStateShouldEqual
({
...
initialState
,
searchQuery
:
'some query'
});
});
});
describe
(
'when setDataSourcesLayoutMode is dispatched'
,
()
=>
{
it
(
'then state should be correct'
,
()
=>
{
const
layoutMode
:
LayoutModes
=
LayoutModes
.
Grid
;
reducerTester
()
.
givenReducer
(
dataSourcesReducer
,
initialState
)
.
whenActionIsDispatched
(
setDataSourcesLayoutMode
(
layoutMode
))
.
thenStateShouldEqual
({
...
initialState
,
layoutMode
:
LayoutModes
.
Grid
});
});
});
describe
(
'when dataSourceTypesLoad is dispatched'
,
()
=>
{
it
(
'then state should be correct'
,
()
=>
{
const
state
:
DataSourcesState
=
{
...
initialState
,
dataSourceTypes
:
[
mockPlugin
()]
};
reducerTester
()
.
givenReducer
(
dataSourcesReducer
,
state
)
.
whenActionIsDispatched
(
dataSourceTypesLoad
())
.
thenStateShouldEqual
({
...
initialState
,
dataSourceTypes
:
[],
isLoadingDataSources
:
true
});
});
});
describe
(
'when dataSourceTypesLoaded is dispatched'
,
()
=>
{
it
(
'then state should be correct'
,
()
=>
{
const
dataSourceTypes
=
[
mockPlugin
()];
const
state
:
DataSourcesState
=
{
...
initialState
,
isLoadingDataSources
:
true
};
reducerTester
()
.
givenReducer
(
dataSourcesReducer
,
state
)
.
whenActionIsDispatched
(
dataSourceTypesLoaded
(
dataSourceTypes
))
.
thenStateShouldEqual
({
...
initialState
,
dataSourceTypes
,
isLoadingDataSources
:
false
});
});
});
describe
(
'when setDataSourceTypeSearchQuery is dispatched'
,
()
=>
{
it
(
'then state should be correct'
,
()
=>
{
reducerTester
()
.
givenReducer
(
dataSourcesReducer
,
initialState
)
.
whenActionIsDispatched
(
setDataSourceTypeSearchQuery
(
'type search query'
))
.
thenStateShouldEqual
({
...
initialState
,
dataSourceTypeSearchQuery
:
'type search query'
});
});
});
describe
(
'when dataSourceMetaLoaded is dispatched'
,
()
=>
{
it
(
'then state should be correct'
,
()
=>
{
const
dataSourceMeta
=
mockPlugin
();
reducerTester
()
.
givenReducer
(
dataSourcesReducer
,
initialState
)
.
whenActionIsDispatched
(
dataSourceMetaLoaded
(
dataSourceMeta
))
.
thenStateShouldEqual
({
...
initialState
,
dataSourceMeta
});
});
});
describe
(
'when setDataSourceName is dispatched'
,
()
=>
{
it
(
'then state should be correct'
,
()
=>
{
reducerTester
()
.
givenReducer
(
dataSourcesReducer
,
initialState
)
.
whenActionIsDispatched
(
setDataSourceName
(
'some name'
))
.
thenStateShouldEqual
({
...
initialState
,
dataSource
:
{
name
:
'some name'
}
});
});
});
describe
(
'when setIsDefault is dispatched'
,
()
=>
{
it
(
'then state should be correct'
,
()
=>
{
reducerTester
()
.
givenReducer
(
dataSourcesReducer
,
initialState
)
.
whenActionIsDispatched
(
setIsDefault
(
true
))
.
thenStateShouldEqual
({
...
initialState
,
dataSource
:
{
isDefault
:
true
}
});
});
});
});
public/app/features/datasources/state/reducers.ts
View file @
6a84a85a
...
...
@@ -15,7 +15,7 @@ import {
import
{
LayoutModes
}
from
'app/core/components/LayoutSelector/LayoutSelector'
;
import
{
reducerFactory
}
from
'app/core/redux'
;
const
initialState
:
DataSourcesState
=
{
export
const
initialState
:
DataSourcesState
=
{
dataSources
:
[],
dataSource
:
{}
as
DataSourceSettings
,
layoutMode
:
LayoutModes
.
List
,
...
...
public/test/core/redux/reducerTester.test.ts
0 → 100644
View file @
6a84a85a
import
{
reducerFactory
,
actionCreatorFactory
}
from
'app/core/redux'
;
import
{
reducerTester
}
from
'./reducerTester'
;
interface
DummyState
{
data
:
string
[];
}
const
initialState
:
DummyState
=
{
data
:
[],
};
const
dummyAction
=
actionCreatorFactory
<
string
>
(
'dummyAction'
).
create
();
const
mutatingReducer
=
reducerFactory
(
initialState
)
.
addMapper
({
filter
:
dummyAction
,
mapper
:
(
state
,
action
)
=>
{
state
.
data
.
push
(
action
.
payload
);
return
state
;
},
})
.
create
();
const
okReducer
=
reducerFactory
(
initialState
)
.
addMapper
({
filter
:
dummyAction
,
mapper
:
(
state
,
action
)
=>
{
return
{
...
state
,
data
:
state
.
data
.
concat
(
action
.
payload
),
};
},
})
.
create
();
describe
(
'reducerTester'
,
()
=>
{
describe
(
'when reducer mutates state'
,
()
=>
{
it
(
'then it should throw'
,
()
=>
{
expect
(()
=>
{
reducerTester
()
.
givenReducer
(
mutatingReducer
,
initialState
)
.
whenActionIsDispatched
(
dummyAction
(
'some string'
))
.
thenStateShouldEqual
({
...
initialState
,
data
:
[
'some string'
]
});
}).
toThrow
();
});
});
describe
(
'when reducer does not mutate state'
,
()
=>
{
it
(
'then it should not throw'
,
()
=>
{
expect
(()
=>
{
reducerTester
()
.
givenReducer
(
okReducer
,
initialState
)
.
whenActionIsDispatched
(
dummyAction
(
'some string'
))
.
thenStateShouldEqual
({
...
initialState
,
data
:
[
'some string'
]
});
}).
not
.
toThrow
();
});
});
});
public/test/core/redux/reducerTester.ts
0 → 100644
View file @
6a84a85a
import
{
Reducer
}
from
'redux'
;
import
{
ActionOf
}
from
'app/core/redux/actionCreatorFactory'
;
export
interface
Given
<
State
>
{
givenReducer
:
(
reducer
:
Reducer
<
State
,
ActionOf
<
any
>>
,
state
:
State
)
=>
When
<
State
>
;
}
export
interface
When
<
State
>
{
whenActionIsDispatched
:
(
action
:
ActionOf
<
any
>
)
=>
Then
<
State
>
;
}
export
interface
Then
<
State
>
{
thenStateShouldEqual
:
(
state
:
State
)
=>
Then
<
State
>
;
}
interface
ObjectType
extends
Object
{
[
key
:
string
]:
any
;
}
const
deepFreeze
=
<
T
>
(
obj
:
T
):
T
=>
{
Object
.
freeze
(
obj
);
const
isNotException
=
(
object
:
any
,
propertyName
:
any
)
=>
typeof
object
===
'function'
?
propertyName
!==
'caller'
&&
propertyName
!==
'callee'
&&
propertyName
!==
'arguments'
:
true
;
const
hasOwnProp
=
Object
.
prototype
.
hasOwnProperty
;
if
(
obj
&&
obj
instanceof
Object
)
{
const
object
:
ObjectType
=
obj
;
Object
.
getOwnPropertyNames
(
object
).
forEach
(
propertyName
=>
{
const
objectProperty
:
any
=
object
[
propertyName
];
if
(
hasOwnProp
.
call
(
object
,
propertyName
)
&&
isNotException
(
object
,
propertyName
)
&&
objectProperty
&&
(
typeof
objectProperty
===
'object'
||
typeof
objectProperty
===
'function'
)
&&
Object
.
isFrozen
(
objectProperty
)
===
false
)
{
deepFreeze
(
objectProperty
);
}
});
}
return
obj
;
};
interface
ReducerTester
<
State
>
extends
Given
<
State
>
,
When
<
State
>
,
Then
<
State
>
{}
export
const
reducerTester
=
<
State
>
():
Given
<
State
>
=>
{
let
reducerUnderTest
:
Reducer
<
State
,
ActionOf
<
any
>>
=
null
;
let
resultingState
:
State
=
null
;
let
initialState
:
State
=
null
;
const
givenReducer
=
(
reducer
:
Reducer
<
State
,
ActionOf
<
any
>>
,
state
:
State
):
When
<
State
>
=>
{
reducerUnderTest
=
reducer
;
initialState
=
{
...
state
};
initialState
=
deepFreeze
(
initialState
);
return
instance
;
};
const
whenActionIsDispatched
=
(
action
:
ActionOf
<
any
>
):
Then
<
State
>
=>
{
resultingState
=
reducerUnderTest
(
initialState
,
action
);
return
instance
;
};
const
thenStateShouldEqual
=
(
state
:
State
):
Then
<
State
>
=>
{
expect
(
state
).
toEqual
(
resultingState
);
return
instance
;
};
const
instance
:
ReducerTester
<
State
>
=
{
thenStateShouldEqual
,
givenReducer
,
whenActionIsDispatched
};
return
instance
;
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment