Skip to content

Commit

Permalink
fix(debugger): fix an infinite loop issue
Browse files Browse the repository at this point in the history
  • Loading branch information
solkimicreb committed Feb 14, 2018
1 parent b4eb801 commit adbf222
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 7 deletions.
20 changes: 14 additions & 6 deletions src/reactionRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
} from './store'

let runningReaction
let isDebugging = false

export function runAsReaction (reaction, fn, context, args) {
// do not build reactive relations, if the reaction is unobserved
Expand All @@ -30,9 +31,7 @@ export function runAsReaction (reaction, fn, context, args) {
// register the currently running reaction to be queued again on obj.key mutations
export function registerRunningReactionForOperation (operation) {
if (runningReaction) {
if (runningReaction.debugger) {
runningReaction.debugger(operation)
}
debugOperation(runningReaction, operation)
registerReactionForOperation(runningReaction, operation)
}
}
Expand All @@ -43,9 +42,7 @@ export function queueReactionsForOperation (operation) {
}

function queueReaction (reaction) {
if (reaction.debugger) {
reaction.debugger(this)
}
debugOperation(reaction, this)
// queue the reaction for later execution or run it immediately
if (typeof reaction.scheduler === 'function') {
reaction.scheduler(reaction)
Expand All @@ -56,6 +53,17 @@ function queueReaction (reaction) {
}
}

function debugOperation (reaction, operation) {
if (reaction.debugger && !isDebugging) {
try {
isDebugging = true
reaction.debugger(operation)
} finally {
isDebugging = false
}
}
}

export function hasRunningReaction () {
return runningReaction !== undefined
}
13 changes: 13 additions & 0 deletions tests/debug.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,17 @@ describe('debugger', () => {
}
])
})

it('should not cause infinite loops', () => {
let receiverDummy
const rawCounter = { num: 0 }
const counter = observable(rawCounter)
const debugSpy = spy(({ receiver }) => (receiverDummy = receiver.num))
observe(() => counter.num, {
debugger: debugSpy
})

expect(receiverDummy).to.equal(0)
expect(debugSpy.callCount).to.equal(1)
})
})
2 changes: 1 addition & 1 deletion tests/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export function spy (fn) {
function spyFn () {
fn()
fn.apply(this, arguments)
spyFn.callCount++
spyFn.lastArgs = Array.from(arguments)
spyFn.args.push(spyFn.lastArgs)
Expand Down

0 comments on commit adbf222

Please sign in to comment.