Merge pull request #110 from sgmap/fix-double-unfold-again
Corrige les doublons lors du unfoldpull/121/merge
commit
1bb596c99b
|
@ -8,7 +8,7 @@
|
|||
},
|
||||
"description": "Expérimentation sur les prélèvements sociaux en code",
|
||||
"engines": {
|
||||
"node": ">=6.2.0"
|
||||
"node": ">=6.2.0 <9.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.23.0",
|
||||
|
|
|
@ -133,6 +133,7 @@
|
|||
entreprise . association non lucrative: 1
|
||||
par défaut:
|
||||
contrat salarié . temps partiel: non
|
||||
contrat salarié . heures par semaine: 35
|
||||
contrat salarié . CDD . événement: non
|
||||
contrat salarié . CDD . congés non pris: 0
|
||||
contrat salarié . CDD . contrat jeune vacances: non
|
||||
|
|
|
@ -13,6 +13,7 @@ import './conversation/conversation.css'
|
|||
import './Simulateur.css'
|
||||
import {capitalise0} from '../utils'
|
||||
import Conversation from './conversation/Conversation'
|
||||
import {makeQuestion} from 'Engine/generateQuestions'
|
||||
|
||||
import ReactPiwik from './Tracker'
|
||||
|
||||
|
@ -22,8 +23,8 @@ let situationSelector = formValueSelector('conversation')
|
|||
@connect(
|
||||
state => ({
|
||||
situation: variableName => situationSelector(state, variableName),
|
||||
currentQuestion: state.currentQuestion,
|
||||
foldedSteps: state.foldedSteps,
|
||||
unfoldedSteps: state.unfoldedSteps,
|
||||
extraSteps: state.extraSteps,
|
||||
themeColours: state.themeColours,
|
||||
analysedSituation: state.analysedSituation,
|
||||
|
@ -62,7 +63,7 @@ export default class extends Component {
|
|||
|
||||
let
|
||||
{started} = this.state,
|
||||
{foldedSteps, extraSteps, unfoldedSteps, situation, situationGate, themeColours} = this.props,
|
||||
{foldedSteps, extraSteps, currentQuestion, situation, situationGate, themeColours} = this.props,
|
||||
sim = path =>
|
||||
R.path(R.unless(R.is(Array), R.of)(path))(this.rule.simulateur || {}),
|
||||
reinitalise = () => {
|
||||
|
@ -72,6 +73,20 @@ export default class extends Component {
|
|||
},
|
||||
title = sim('titre') || capitalise0(this.rule['titre'] || this.rule['nom'])
|
||||
|
||||
let buildAnyStep = unfolded => accessor => question => {
|
||||
let step = makeQuestion(rules)(question)
|
||||
return <step.component
|
||||
key={step.name}
|
||||
{...step}
|
||||
{...{unfolded}}
|
||||
step={step}
|
||||
answer={accessor(step.name)}
|
||||
/>
|
||||
}
|
||||
|
||||
let buildStep = buildAnyStep(false)
|
||||
let buildUnfoldedStep = buildAnyStep(true)
|
||||
|
||||
return (
|
||||
<div id="sim" className={classNames({started})}>
|
||||
<Helmet>
|
||||
|
@ -98,7 +113,12 @@ export default class extends Component {
|
|||
}
|
||||
{ (started || !sim(['introduction', 'notes'])) &&
|
||||
<Conversation initialValues={ R.pathOr({},['simulateur','par défaut'], sim) }
|
||||
{...{foldedSteps, unfoldedSteps, extraSteps, reinitalise, situation, situationGate, textColourOnWhite: themeColours.textColourOnWhite}}/>
|
||||
{...{
|
||||
reinitalise,
|
||||
currentQuestion: currentQuestion && buildUnfoldedStep(situation)(currentQuestion),
|
||||
foldedSteps: R.map(buildStep(situation), foldedSteps),
|
||||
extraSteps: R.map(buildStep(situationGate), extraSteps),
|
||||
textColourOnWhite: themeColours.textColourOnWhite}}/>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
|
|
@ -11,7 +11,7 @@ import Scroll from 'react-scroll'
|
|||
})
|
||||
export default class Conversation extends Component {
|
||||
render() {
|
||||
let {foldedSteps, unfoldedSteps, extraSteps, reinitalise, situation, situationGate, textColourOnWhite} = this.props
|
||||
let {foldedSteps, currentQuestion, extraSteps, reinitalise, textColourOnWhite} = this.props
|
||||
|
||||
Scroll.animateScroll.scrollToBottom()
|
||||
return (
|
||||
|
@ -26,49 +26,22 @@ export default class Conversation extends Component {
|
|||
Tout effacer
|
||||
</button>
|
||||
</div>
|
||||
{foldedSteps
|
||||
.map(step => (
|
||||
<step.component
|
||||
key={step.name}
|
||||
{...step}
|
||||
step={step}
|
||||
answer={situation(step.name)}
|
||||
/>
|
||||
))}
|
||||
{foldedSteps}
|
||||
</div>
|
||||
}
|
||||
{unfoldedSteps.length == 0 &&
|
||||
{!currentQuestion &&
|
||||
<Conclusion affiner={!R.isEmpty(extraSteps)}/>}
|
||||
{ !R.isEmpty(extraSteps) &&
|
||||
<div id="foldedSteps">
|
||||
<div className="header" >
|
||||
<h3>Affiner votre situation</h3>
|
||||
</div>
|
||||
{extraSteps
|
||||
.map(step => (
|
||||
<step.component
|
||||
key={step.name}
|
||||
{...step}
|
||||
step={step}
|
||||
answer={situationGate(step.name)}
|
||||
/>
|
||||
))}
|
||||
{extraSteps}
|
||||
</div>
|
||||
}
|
||||
<div id="unfoldedSteps">
|
||||
{ !R.isEmpty(unfoldedSteps) && do {
|
||||
let step = R.head(unfoldedSteps)
|
||||
;<step.component
|
||||
key={step.name}
|
||||
step={R.dissoc('component', step)}
|
||||
unfolded={true}
|
||||
answer={situation(step.name)}
|
||||
/>
|
||||
}}
|
||||
<div id="currentQuestion">
|
||||
{ currentQuestion || <Satisfaction simu={this.props.simu}/>}
|
||||
</div>
|
||||
{R.isEmpty(unfoldedSteps) &&
|
||||
<Satisfaction simu={this.props.simu}/>
|
||||
}
|
||||
</div>
|
||||
<Aide />
|
||||
</div>
|
||||
|
|
|
@ -48,8 +48,7 @@ export var FormDecorator = formType => RenderField =>
|
|||
human,
|
||||
helpText,
|
||||
suggestions,
|
||||
subquestion,
|
||||
objectives,
|
||||
subquestion
|
||||
} = this.props.step
|
||||
this.step = this.props.step
|
||||
|
||||
|
|
|
@ -78,16 +78,19 @@ export let collectMissingVariables = (groupMethod='groupByMissingVariable') => (
|
|||
}
|
||||
|
||||
export let buildNextSteps = (situationGate, flatRules, analysedSituation) => {
|
||||
let missingVariables = collectMissingVariables('groupByMissingVariable')(situationGate, analysedSituation),
|
||||
asPairs = R.toPairs(missingVariables)
|
||||
|
||||
let generate = R.map(R.curry(generateQuestion)(flatRules)),
|
||||
sort = R.sort((a,b) => b.impact - a.impact)
|
||||
|
||||
return R.pipe(generate,sort)(asPairs)
|
||||
let missing = nextSteps(situationGate, flatRules, analysedSituation)
|
||||
return R.map(makeQuestion(flatRules), missing)
|
||||
}
|
||||
|
||||
export let nextSteps = (situationGate, flatRules, analysedSituation) => {
|
||||
let impact = ([variable, objectives]) => R.length(objectives)
|
||||
|
||||
let missingVariables = collectMissingVariables('groupByMissingVariable')(situationGate, analysedSituation),
|
||||
pairs = R.toPairs(missingVariables),
|
||||
sortedPairs = R.sort((a,b) => impact(b) - impact(a), pairs)
|
||||
|
||||
return R.map(R.head, sortedPairs)
|
||||
}
|
||||
|
||||
export let constructStepMeta = ({
|
||||
titre,
|
||||
|
@ -134,14 +137,8 @@ let buildVariantTree = (allRules, path) => {
|
|||
return rec(path)
|
||||
}
|
||||
|
||||
export let generateQuestion = flatRules => ([dottedName, objectives]) => {
|
||||
let rule = findRuleByDottedName(flatRules, dottedName),
|
||||
guidance = {
|
||||
objectives,
|
||||
impact: objectives.length
|
||||
}
|
||||
|
||||
// console.log(isVariant(rule)?"variant":"generateQuestion",[dottedName, objectives.length])
|
||||
export let makeQuestion = flatRules => dottedName => {
|
||||
let rule = findRuleByDottedName(flatRules, dottedName)
|
||||
|
||||
let inputQuestion = rule => ({
|
||||
component: Input,
|
||||
|
@ -185,7 +182,5 @@ export let generateQuestion = flatRules => ([dottedName, objectives]) => {
|
|||
typeof rule.suggestions == 'string' ?
|
||||
(rule.suggestions == 'atmp-2017' ? selectAtmp(rule) : selectQuestion(rule)) :
|
||||
inputQuestion(rule)
|
||||
,
|
||||
guidance
|
||||
)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import reduceReducers from 'reduce-reducers'
|
|||
import {reducer as formReducer, formValueSelector} from 'redux-form'
|
||||
|
||||
import {rules, findRuleByName } from 'Engine/rules'
|
||||
import {buildNextSteps} from 'Engine/generateQuestions'
|
||||
import {nextSteps, makeQuestion} from 'Engine/generateQuestions'
|
||||
import computeThemeColours from 'Components/themeColours'
|
||||
import { STEP_ACTION, START_CONVERSATION, EXPLAIN_VARIABLE, CHANGE_THEME_COLOUR} from './actions'
|
||||
|
||||
|
@ -50,28 +50,28 @@ export let reduceSteps = (tracker, flatRules, answerSource) => (state, action) =
|
|||
}
|
||||
|
||||
if (action.type == START_CONVERSATION) {
|
||||
let unfoldedSteps = buildNextSteps(situationGate, flatRules, newState.analysedSituation)
|
||||
let next = nextSteps(situationGate, flatRules, newState.analysedSituation)
|
||||
|
||||
return {
|
||||
...newState,
|
||||
foldedSteps: [],
|
||||
unfoldedSteps
|
||||
currentQuestion: R.head(next)
|
||||
}
|
||||
}
|
||||
if (action.type == STEP_ACTION && action.name == 'fold') {
|
||||
tracker.push(['trackEvent', 'answer', action.step+": "+situationGate(action.step)]);
|
||||
|
||||
let foldedSteps = [...state.foldedSteps, R.head(state.unfoldedSteps)],
|
||||
unfoldedSteps = buildNextSteps(situationGate, flatRules, newState.analysedSituation),
|
||||
let foldedSteps = [...state.foldedSteps, state.currentQuestion],
|
||||
next = nextSteps(situationGate, flatRules, newState.analysedSituation),
|
||||
assumptionsMade = !R.isEmpty(softAssumptions),
|
||||
done = unfoldedSteps.length == 0
|
||||
done = next.length == 0
|
||||
|
||||
// The simulation is "over" - except we can now fill in extra questions
|
||||
// where the answers were previously given default reasonable assumptions
|
||||
if (done && assumptionsMade) {
|
||||
let newSituation = intermediateSituation(state),
|
||||
reanalyse = analyseTopDown(flatRules,rootVariable)(newSituation),
|
||||
extraSteps = buildNextSteps(newSituation, flatRules, reanalyse)
|
||||
extraSteps = nextSteps(newSituation, flatRules, reanalyse)
|
||||
|
||||
tracker.push(['trackEvent', 'done', 'extra questions: '+extraSteps.length]);
|
||||
|
||||
|
@ -79,7 +79,7 @@ export let reduceSteps = (tracker, flatRules, answerSource) => (state, action) =
|
|||
...newState,
|
||||
foldedSteps,
|
||||
extraSteps,
|
||||
unfoldedSteps: []
|
||||
currentQuestion: null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,21 +90,26 @@ export let reduceSteps = (tracker, flatRules, answerSource) => (state, action) =
|
|||
return {
|
||||
...newState,
|
||||
foldedSteps,
|
||||
unfoldedSteps
|
||||
currentQuestion: R.head(next)
|
||||
}
|
||||
}
|
||||
if (action.type == STEP_ACTION && action.name == 'unfold') {
|
||||
tracker.push(['trackEvent', 'unfold', action.step]);
|
||||
|
||||
let stepFinder = R.propEq('name', action.step),
|
||||
foldedSteps = R.reject(stepFinder)(state.foldedSteps).concat(state.unfoldedSteps),
|
||||
extraSteps = R.reject(stepFinder)(state.extraSteps)
|
||||
// We are possibly "refolding" a previously open question
|
||||
let previous = state.currentQuestion,
|
||||
// we fold it back into foldedSteps if it had been answered
|
||||
answered = previous && answerSource(state)(previous) != undefined,
|
||||
foldedSteps = answered ? R.concat(state.foldedSteps, [previous]) : state.foldedSteps,
|
||||
// we fold it back into "extra steps" if it came from there
|
||||
fromExtra = previous && softAssumptions[previous] != undefined,
|
||||
extraSteps = fromExtra ? R.concat(state.extraSteps, [previous]) : state.extraSteps
|
||||
|
||||
return {
|
||||
...newState,
|
||||
foldedSteps,
|
||||
extraSteps,
|
||||
unfoldedSteps: [R.find(stepFinder)(R.concat(state.foldedSteps,state.extraSteps))]
|
||||
foldedSteps: R.without([action.step], foldedSteps),
|
||||
extraSteps: R.without([action.step], extraSteps),
|
||||
currentQuestion: action.step
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +140,7 @@ export default reduceReducers(
|
|||
false means the user is reconsidering its previous input */
|
||||
foldedSteps: (steps = []) => steps,
|
||||
extraSteps: (steps = []) => steps,
|
||||
unfoldedSteps: (steps = []) => steps,
|
||||
currentQuestion: (state = null) => state,
|
||||
|
||||
analysedSituation: (state = []) => state,
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import R from 'ramda'
|
|||
import {expect} from 'chai'
|
||||
import {rules as realRules, enrichRule} from '../source/engine/rules'
|
||||
import {analyseSituation, analyseTopDown} from '../source/engine/traverse'
|
||||
import {buildNextSteps, collectMissingVariables, getObjectives} from '../source/engine/generateQuestions'
|
||||
import {nextSteps, collectMissingVariables, getObjectives} from '../source/engine/generateQuestions'
|
||||
|
||||
let stateSelector = (name) => null
|
||||
|
||||
|
@ -218,7 +218,7 @@ describe('collectMissingVariables', function() {
|
|||
|
||||
});
|
||||
|
||||
describe('buildNextSteps', function() {
|
||||
describe('nextSteps', function() {
|
||||
|
||||
it('should generate questions', function() {
|
||||
let rawRules = [
|
||||
|
@ -228,10 +228,10 @@ describe('buildNextSteps', function() {
|
|||
{nom: "ko", espace: "top . sum . evt"}],
|
||||
rules = rawRules.map(enrichRule),
|
||||
situation = analyseTopDown(rules,"sum")(stateSelector),
|
||||
result = buildNextSteps(stateSelector, rules, situation)
|
||||
result = nextSteps(stateSelector, rules, situation)
|
||||
|
||||
expect(result).to.have.lengthOf(1)
|
||||
expect(R.path(["question","props","label"])(result[0])).to.equal("?")
|
||||
expect(result[0]).to.equal("top . sum . evt")
|
||||
});
|
||||
|
||||
it('should generate questions from the real rules', function() {
|
||||
|
@ -239,7 +239,7 @@ describe('buildNextSteps', function() {
|
|||
situation = analyseTopDown(rules,"surcoût CDD")(stateSelector),
|
||||
objectives = getObjectives(stateSelector, situation.root, situation.parsedRules),
|
||||
missing = collectMissingVariables()(stateSelector,situation),
|
||||
result = buildNextSteps(stateSelector, rules, situation)
|
||||
result = nextSteps(stateSelector, rules, situation)
|
||||
|
||||
// expect(objectives).to.have.lengthOf(4)
|
||||
|
||||
|
@ -271,10 +271,10 @@ describe('buildNextSteps', function() {
|
|||
situation = analyseTopDown(rules,"Salaire")(stateSelector),
|
||||
objectives = getObjectives(stateSelector, situation.root, situation.parsedRules),
|
||||
missing = collectMissingVariables()(stateSelector,situation),
|
||||
result = buildNextSteps(stateSelector, rules, situation)
|
||||
result = nextSteps(stateSelector, rules, situation)
|
||||
|
||||
expect(R.path(["question","props","label"])(result[0])).to.equal("Quel est le salaire brut mensuel ?")
|
||||
expect(R.path(["question","props","label"])(result[1])).to.equal("Le contrat est-il à temps partiel ?")
|
||||
expect(result[0]).to.equal("contrat salarié . salaire de base")
|
||||
expect(result[1]).to.equal("contrat salarié . temps partiel")
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ import R from 'ramda'
|
|||
import {expect} from 'chai'
|
||||
import {rules as realRules, enrichRule} from '../source/engine/rules'
|
||||
import {analyseSituation, analyseTopDown} from '../source/engine/traverse'
|
||||
import {buildNextSteps, collectMissingVariables, getObjectives} from '../source/engine/generateQuestions'
|
||||
import {collectMissingVariables, getObjectives} from '../source/engine/generateQuestions'
|
||||
|
||||
import {reduceSteps} from '../source/reducers'
|
||||
|
||||
|
@ -12,7 +12,7 @@ let tracker = {push: array => null}
|
|||
|
||||
describe('fold', function() {
|
||||
|
||||
it('should start conversation with only unfolded questions', function() {
|
||||
it('should start conversation with the first missing variable', function() {
|
||||
let rawRules = [
|
||||
// TODO - this won't work without the indirection, figure out why
|
||||
{nom: "startHere", formule: {somme: ["a","b"]}, espace: "top"},
|
||||
|
@ -28,10 +28,8 @@ describe('fold', function() {
|
|||
// missing = collectMissingVariables()(stateSelector({}),situation),
|
||||
result = reducer({},action)
|
||||
|
||||
expect(result).to.have.property('unfoldedSteps')
|
||||
expect(result.unfoldedSteps).to.have.lengthOf(2)
|
||||
expect(result.unfoldedSteps[0]).to.have.deep.property("name","top . aa")
|
||||
expect(result.unfoldedSteps[1]).to.have.deep.property("name","top . bb")
|
||||
expect(result).to.have.property('currentQuestion')
|
||||
expect(result.currentQuestion).to.equal("top . aa")
|
||||
});
|
||||
|
||||
it('should deal with double unfold', function() {
|
||||
|
@ -40,11 +38,13 @@ describe('fold', function() {
|
|||
|
||||
let rawRules = [
|
||||
// TODO - this won't work without the indirection, figure out why
|
||||
{nom: "startHere", formule: {somme: ["a","b"]}, espace: "top"},
|
||||
{nom: "startHere", formule: {somme: ["a","b","c"]}, espace: "top"},
|
||||
{nom: "a", espace: "top", formule: "aa"},
|
||||
{nom: "b", espace: "top", formule: "bb"},
|
||||
{nom: "c", espace: "top", formule: "cc"},
|
||||
{nom: "aa", question: "?", titre: "a", espace: "top"},
|
||||
{nom: "bb", question: "?", titre: "b", espace: "top"}],
|
||||
{nom: "bb", question: "?", titre: "b", espace: "top"},
|
||||
{nom: "cc", question: "?", titre: "c", espace: "top"}],
|
||||
rules = rawRules.map(enrichRule),
|
||||
reducer = reduceSteps(tracker, rules, stateSelector)
|
||||
|
||||
|
@ -58,12 +58,80 @@ describe('fold', function() {
|
|||
|
||||
let result = step5
|
||||
|
||||
expect(result).to.have.property('unfoldedSteps')
|
||||
expect(result.unfoldedSteps).to.have.lengthOf(1)
|
||||
expect(result.unfoldedSteps[0]).to.have.deep.property("name","top . bb")
|
||||
expect(result).to.have.property('currentQuestion')
|
||||
expect(result.currentQuestion).to.equal("top . bb")
|
||||
expect(result).to.have.property('foldedSteps')
|
||||
expect(result.foldedSteps).to.have.lengthOf(1)
|
||||
expect(result.foldedSteps[0]).to.have.deep.property("name","top . aa")
|
||||
expect(result.foldedSteps[0]).to.equal("top . aa")
|
||||
});
|
||||
|
||||
it('should list questions with defaults as extra steps', function() {
|
||||
let fakeState = {}
|
||||
let stateSelector = state => name => fakeState[name]
|
||||
|
||||
let rawRules = [
|
||||
// TODO - this won't work without the indirection, figure out why
|
||||
{nom: "startHere", formule: {somme: ["a","b","c"]}, espace: "top",
|
||||
simulateur: {"par défaut": {"top . bb": 1, "top . cc":0}}},
|
||||
{nom: "a", espace: "top", formule: "aa"},
|
||||
{nom: "b", espace: "top", formule: "bb"},
|
||||
{nom: "c", espace: "top", formule: "cc"},
|
||||
{nom: "aa", question: "?", titre: "a", espace: "top"},
|
||||
{nom: "bb", question: "?", titre: "b", espace: "top"},
|
||||
{nom: "cc", question: "?", titre: "c", espace: "top"}],
|
||||
rules = rawRules.map(enrichRule),
|
||||
reducer = reduceSteps(tracker, rules, stateSelector)
|
||||
|
||||
var step1 = reducer({},{type:'START_CONVERSATION', rootVariable: 'startHere'})
|
||||
fakeState['top . aa'] = 1
|
||||
var step2 = reducer(step1,{type:'STEP_ACTION', name: 'fold', step: 'top . aa'})
|
||||
|
||||
let result = step2
|
||||
|
||||
expect(result).to.have.property('currentQuestion')
|
||||
expect(result.currentQuestion).to.be.an('null')
|
||||
expect(result).to.have.property('foldedSteps')
|
||||
expect(result.foldedSteps).to.have.lengthOf(1)
|
||||
expect(result.foldedSteps[0]).to.equal("top . aa")
|
||||
expect(result).to.have.property('extraSteps')
|
||||
expect(result.extraSteps).to.have.lengthOf(2)
|
||||
expect(result.extraSteps[0]).to.equal("top . bb")
|
||||
expect(result.extraSteps[1]).to.equal("top . cc")
|
||||
});
|
||||
|
||||
it('should return questions with a default to extra steps', function() {
|
||||
let fakeState = {}
|
||||
let stateSelector = state => name => fakeState[name]
|
||||
|
||||
let rawRules = [
|
||||
// TODO - this won't work without the indirection, figure out why
|
||||
{nom: "startHere", formule: {somme: ["a","b","c"]}, espace: "top",
|
||||
simulateur: {"par défaut": {"top . bb": 1, "top . cc":0}}},
|
||||
{nom: "a", espace: "top", formule: "aa"},
|
||||
{nom: "b", espace: "top", formule: "bb"},
|
||||
{nom: "c", espace: "top", formule: "cc"},
|
||||
{nom: "aa", question: "?", titre: "a", espace: "top"},
|
||||
{nom: "bb", question: "?", titre: "b", espace: "top"},
|
||||
{nom: "cc", question: "?", titre: "c", espace: "top"}],
|
||||
rules = rawRules.map(enrichRule),
|
||||
reducer = reduceSteps(tracker, rules, stateSelector)
|
||||
|
||||
var step1 = reducer({},{type:'START_CONVERSATION', rootVariable: 'startHere'})
|
||||
fakeState['top . aa'] = 1
|
||||
var step2 = reducer(step1,{type:'STEP_ACTION', name: 'fold', step: 'top . aa'})
|
||||
var step3 = reducer(step2,{type:'STEP_ACTION', name: 'unfold', step: 'top . bb'})
|
||||
var step4 = reducer(step3,{type:'STEP_ACTION', name: 'unfold', step: 'top . cc'})
|
||||
|
||||
let result = step4
|
||||
|
||||
expect(result).to.have.property('currentQuestion')
|
||||
expect(result.currentQuestion).to.equal("top . cc")
|
||||
expect(result).to.have.property('foldedSteps')
|
||||
expect(result.foldedSteps).to.have.lengthOf(1)
|
||||
expect(result.foldedSteps[0]).to.equal("top . aa")
|
||||
expect(result).to.have.property('extraSteps')
|
||||
expect(result.extraSteps).to.have.lengthOf(1)
|
||||
expect(result.extraSteps[0]).to.equal("top . bb")
|
||||
});
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue