Thought Cloud TDD #2: A new thought

I’m working on Thought Cloud for an upcoming demo. Join me, won’t you?

Last time we wrote a failing test about changing the text of the initial thought. Now let’s make it pass.

The view model doesn’t have a model backing it, so it can’t store the thought text. Even though we are doing the simplest thing to make the test pass, we must still obey the rules of the Correspondence architecture:

Rule #1: Never store state in the view model.

The view model layer exists only to interpret models for the view. If you have any state to store, it must find its way to a model. In this case, it must be stored in a Thought fact. So we define one in the Factual file model.fact.

fact Thought {
key:
    unique;

mutable:
    string text;
}

Be sure to hit “Transform all templates” whenever changing this file. Then build just to be sure the syntax is correct.

Every Thought is unique. It has a unique key (a GUID), so that every time you create a new Thought, you get a new instance. The key is immutable. The text, however, is mutable. It is not part of the key. So this can store the state to make our unit test pass. We just need to create a new Thought to give to the view model.

Thought thought = _community.AddFact(new Thought());
_cloudViewModel = new CloudViewModel(thought);
public class CloudViewModel
{
    private Thought _centralThought;

    public CloudViewModel(Thought centralThought)
    {
        _centralThought = centralThought;
    }

    public IEnumerable<ThoughtViewModel> Thoughts
    {
        get
        {
            yield return new ThoughtViewModel(_centralThought);
        }
    }
}
public class ThoughtViewModel
{
    private Thought _thought;

    public ThoughtViewModel(Thought thought)
    {
        _thought = thought;
    }

    public string Text
    {
        get { return _thought.Text.Value ?? "My thought"; }
        set { _thought.Text = value; }
    }
}

Now the tests pass. Notice that we aren’t setting the initial text of the Thought. We rely upon the fact that a mutable string is initially null, and interpret that as the initial value in the view model. This honors the second rule of Correspondence architecture.

Rule #2: Create one fact for each user action.

We could have assigned Text to “My thought” right after creating it, but that would have actually created two facts. Assigning a mutable field actually creates a new fact behind the scenes. If we received the Thought from a peer, there is no guarantee that we would receive both facts at the same time. So we must honor the state in which we have uninitialized text as valid.

Leave a Reply

You must be logged in to post a comment.