xaviergonz / mobx-keystone

A MobX powered state management solution based on data trees with first class support for Typescript, support for snapshots, patches and much more
https://mobx-keystone.js.org
MIT License
555 stars 25 forks source link

modelId, references and Jest Snapshots #165

Closed mikecann closed 4 years ago

mikecann commented 4 years ago

Hi,

Im trying to use Jest Snapshots for testing but when I use a rootReference I keep getting invalid snapshots because the modelId of the rootRef changes despite me explicitly setting the modelId to something.

Example:

import { Model, model, getSnapshot, rootRef, prop, modelAction, Ref } from "mobx-keystone";

@model("MyModel")
class MyModel extends Model({
  children: prop<MyChildModel[]>(() => []),
}) {
  @modelAction
  addChild(childId: string) {
    const child = new MyChildModel({
      $modelId: childId,
      parent: myModelRef(this),
    });
    this.children.push(child);
    return child;
  }
}

const myModelRef = rootRef<MyModel>("MyModel");

@model("MyChildModel")
class MyChildModel extends Model({
  parent: prop<Ref<MyModel>>(),
}) {}

test(`snapshot`, () => {
  const myModel = new MyModel({ $modelId: "aaa" });
  myModel.addChild("child0");

  expect(getSnapshot(myModel)).toMatchInlineSnapshot(`
    Object {
      "$modelId": "aaa",
      "$modelType": "MyModel",
      "children": Array [
        Object {
          "$modelId": "child0",
          "$modelType": "MyChildModel",
          "parent": Object {
            "$modelId": "0-w6DCozt8wrXDrUbCqsKewrHDicK5a8KOw48l",
            "$modelType": "MyModel",
            "id": "aaa",
          },
        },
      ],
    }
  `);
});

Note that the $modelId for the child's parent ref is 0-w6DCozt8wrXDrUbCqsKewrHDicK5a8KOw48l despite me explictly setting the parents $modelId to aaa..

When running JEST I get the warning:

    console.warn node_modules/mobx-keystone/dist/mobxkeystone.cjs.development.js:575
      [mobx-keystone] a model with name "MyModel" already exists (if you are using hot-reloading you may safely ignore this warning)

Does that have anything to do with it?

xaviergonz commented 4 years ago

I recommend you to use code like this to ensure ids are not randomly generated when doing tests:

import { setGlobalConfig } from "../src"

let id = 1

setGlobalConfig({
  modelIdGenerator() {
    return `id-${id++}`
  },
})

beforeEach(() => {
  id = 1
})
mikecann commented 4 years ago

Ah yes, I totally forgot about the global config! Thanks ill use that!