Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test cases to add. Mutating a reactive parent. #2

Open
Lee182 opened this issue Dec 1, 2020 · 3 comments
Open

Test cases to add. Mutating a reactive parent. #2

Lee182 opened this issue Dec 1, 2020 · 3 comments

Comments

@Lee182
Copy link

Lee182 commented Dec 1, 2020

Just added these test cases for when mutating a reactive parent. I ran into the second issue realising the ref which I created had been overwritten. Don't know if this warning should be added to the docs which "watchers to refs that have been overwritten at the parent level will not fire".

test('should work with mutating parent', (assert) => {
  let state = reactive({
    settings: {
      blocking: {
        isEnabled: false,
        isCosmetic: false,
        whitelist: []
      }
    }
  })

  let triggered = 0
  const stop = watch(() => {
    return state.settings.blocking
  }, () => {
    triggered += 1
  })

  state.settings = {
    blocking: {
      isEnabled: true,
      isCosmetic: true,
      whitelist: []
    }
  }

  assert.is(triggered, 1)
  stop()
})

test('should not trigger when mutating parent because watching a ref that has been destroyed by the parent mutation.', (assert) => {
  let state = reactive({
    settings: {
      blocking: {
        isEnabled: false,
        isCosmetic: false,
        whitelist: []
      }
    }
  })

  let triggered = 0
  const refBlocking = ref(state.settings.blocking)
  const stop = watch(refBlocking, () => {
    triggered += 1
  })

  state.settings = {
    blocking: {
      isEnabled: true,
      isCosmetic: true,
      whitelist: []
    }
  }

  assert.is(triggered, 0)
  stop()
})
@antfu
Copy link
Member

antfu commented Dec 1, 2020

@Lee182 This is not how you use it, instead of

const refBlocking = ref(state.settings.blocking)

You should do

const refBlocking = toRef(state.settings, 'blocking')

See more on Vue 3's caveat. Thanks

@antfu antfu closed this as completed Dec 1, 2020
@Lee182
Copy link
Author

Lee182 commented Dec 1, 2020

Tried const refBlocking = toRef(state.settings, 'blocking'). That fails.
As a point of discussion should there be some sort of deep to ref function like lodash.get.
_.get(state, 'settings.blocking'

watch on  master [!] is 📦 v0.1.6 via ⬢ v12.18.3 took 6s 
❯ pnpm run test

> @vue-reactivity/watch@0.1.6 test C:\me\dev\tabdeck\external_lib\watch
> c8 ava


  should not trigger when mutating parent because watching a ref that has been destroyed by the parent mutation.

  test\watch.spec.ts:128

   127:
   128:   assert.is(triggered, 1)
   129:   stop()

  Difference:

  - 0
  + 1

  » test/watch.spec.ts:128:10

  ─

  1 test failed
------------------|---------|----------|---------|---------|-------------------------
File              | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s       
------------------|---------|----------|---------|---------|-------------------------   
All files         |   94.18 |      100 |   88.46 |   94.18 |                         
 errorHandling.ts |   98.28 |      100 |   66.67 |   98.28 | 58                         
 index.ts         |   93.16 |      100 |    91.3 |   93.16 | 47-56,74-75,116-118,122    
------------------|---------|----------|---------|---------|-------------------------   
 ERROR  Test failed. See above for more details.

@Lee182
Copy link
Author

Lee182 commented Dec 1, 2020

In my project base I've got round it using watchEffect. I just then had to mannually track changes which I know from reading the docs which watch will track changes and call the callback only on change. lazy is what the docs call this behaviour.

    this.stopWatchSettings = watchEffect(() => {
      // const blocker = state.settings.blocker
      const blocker = _.get(state, 'settings.blocker')
      this.swapBlocker({})
    }, { flush: 'post' })

@antfu antfu reopened this Dec 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants