pmndrs / directed

A flexible, minimal scheduler written in TypeScript
MIT License
25 stars 1 forks source link

Create tags automatically when invoked #5

Open krispya opened 3 months ago

krispya commented 3 months ago

This is a simple PR that creates a tag if it is not found instead of erroring, making createTag unnecessary to call. This reduces the boilerplate on all the tag tests in alignment with how I expect to use it.

test('schedule a runnable with tag', () => {
    const group1 = Symbol();
    const schedule = create();

    // This call is no longer necessary
    // createTag(schedule, group1);

    add(schedule, aFn, tag(group1), id('A'));
    add(schedule, bFn, after('A'), tag(group1), id('B'));

    run(schedule, {});

    expect(aFn).toBeCalledTimes(1);
    expect(bFn).toBeCalledTimes(1);

    expect(order).toEqual(['A', 'B']);
});

Similarly, scheduling tags with each other no longer becomes necessary. It can be inherited, for lack of a better word, from scheduling the runnable itself.

// This boilerplate becomes...
test('schedule a tag before or after another tag', () => {
    const group1 = Symbol();
    const group2 = Symbol();
    const group3 = Symbol();

    const schedule = create();

    createTag(schedule, group1);
    createTag(schedule, group2, before(group1));
    createTag(schedule, group3, after(group1));

    add(schedule, aFn, tag(group1), id('A'));
    add(schedule, bFn, tag(group2), id('B'));
    add(schedule, cFn, tag(group3), id('C'));

    run(schedule, {});

    expect(aFn).toBeCalledTimes(1);
    expect(bFn).toBeCalledTimes(1);
    expect(cFn).toBeCalledTimes(1);

    expect(order).toEqual(['B', 'A', 'C']);
});

// This
test('schedule a tag before or after another tag', () => {
    const group1 = Symbol();
    const group2 = Symbol();
    const group3 = Symbol();

    const schedule = create();

    add(schedule, aFn, tag(group1), id('A'));
    add(schedule, bFn, tag(group2), id('B'), before(group1));
    add(schedule, cFn, tag(group3), id('C'), after(group1));

    run(schedule, {});

    expect(aFn).toBeCalledTimes(1);
    expect(bFn).toBeCalledTimes(1);
    expect(cFn).toBeCalledTimes(1);

    expect(order).toEqual(['B', 'A', 'C']);
});

To determine would be how "inheriting" dependencies works for tags. We will need to come up with more complicated tests for this. The way I see it is that tags are empty until they get a runnable and runnables themselves have dependencies. The tag then is a way to describe a collection of runnables with "before" meaning "before the first tagged runnable in the sort" and "after" meaning "after the last tagged runnable in the sort".