Code Monkey home page Code Monkey logo

stories's People

Contributors

dargor avatar dependabot[bot] avatar gtors avatar maxhollmann avatar proofit404 avatar sashgorokhov avatar semantic-release-bot avatar sobolevn avatar thedrow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stories's Issues

Context repr shows when attributes were set.

Context variables shown in the class like view with story points by which they were set in the order of execution.

>>> print(self.ctx)
Context:
    foo = 1  # Set by Simple.one
    bar = 2  # Set by Simple.two

Expand context to the call arguments.

Instead of this:

User.objects.create(name=self.ctx.name, email=self.ctx.email, age=self.ctx.age)

How about this:

User.objects.create(**self.ctx('name', 'email', 'age'))

In case of different keyword arguments

User.objects.create(**self.ctx(username='name'))

Statistics contrib package.

While story executed we submit events to some event store.

We can look at some system UI and say: "this step will fail only in 12%"

We can show hit-map by storylines.

Parallel context manager in the DSL.

Syntax:

from stories import story, parallel

class Order:
    @story
    def purchase(I):
        I.one
        with parallel:
            I.two
            I.three
        I.four

Requirements:

  1. This feature should work both for sync and async stories. The semantic of execution and decision making should be the same. Or at least as close as possible.
  2. parallel should have at least two steps in it.
  3. Context changes made by two should not be visible to the three and wise versa. Context changes made by two and three should be visible by four.
  4. two, three or both of them could be a substory. Context restrictions continue to be the same independent from this detail.
  5. If some of the step returns Result this will be a result of the whole story. If other parallel steps are still running, their result should be ignored when they return. The story returns only after all the steps complete. If other running steps returns Failure or Result a warning of this clash should be reported.
  6. If some of the step returns Failure this will be a failure of the whole story. If other parallel steps are still running, their result should be ignored when they return. The story fails only after all the steps complete. If other running steps returns Failure or Result a warning of this clash should be reported.
  7. <parallel> should be present in the representation of the story.
  8. History representation should contain the execution of all steps in order of the actual execution even if it is mixed between parallel substories.
  9. The warning mentioned by items 5 and 6 of this list should be present in history representation as well.

Proxy repr shows executino point.

Source:

class Simple:

    @story
    def x(self):
        self.one()
        self.two()
        self.three()

    def one(self):
        return Success()

    def two(self):
        print(self)
        return Success()

    def three(self):
        return Result()

Result:

>>> Simple().x()
Simple.x
  one
  >> two
  three
>>> 

Write documentation.

  • Move execution rules to its own chapter (add code example and execution output to each line)
  • Add pdb up & ctx usage example in the debugging chapter.
  • Usage page.
  • Contrib page.
  • Django debug toolbar settings.
  • Sentry settings.

Improve pytest plugin.

  • Report in separate sections.
  • Show stories called from fixtures.
  • Show line of the test caused this story.

State contract.

Declarative context values validation.

Applies gradually as context fills in.

from stories import story, arguments

class Action:
    @story 
    @arguments("foo")
    def do(I):
        pass

Action.do.contract({
    "foo": lambda value: (None, 'integer required')
})
>>> Action().do(foo='5')
ContextContractError: foo variable is invalid (integer required)

Pass and apply context manager to each step.

Use should be able to:

  • Wrap each method of the story with one or more context manager/decorator
  • Wrap whole substory of this story
  • Wrap each method of the exact substory with one or more context manager/decorator.
  • It is unclear how to execute transaction.atomic around substory even if there were Skip, Result or even Failure.
  • It is unclear how to rollback this wrapper if Skip was returned. Probably Rollback(to=Skip()) will do the trick.

Sentry contrib package.

Submit proxy and context representation to the breadcrumbs the same way we do with py.test plugin.

Bind wrapper strategy.

from dependencies import Injector
from dependencies.contrib.rest_framework import model_view_set
from stories import story, argument


class CreateStory:

    @story
    @argument("user")
    @argument("text")
    def create(self):

        self.persist_poll()
        self.create_review()

@model_view_set
class Polls(Injector):
    # Take story arguments from the injector.
    # Take failure handlers (on method & for reason) from the injector.
    # Result value will be passed to the rest framework as usual.
    #
    # How to avoid rest framework in the failure handlers?
    create = CreatePoll.create.bind()
    update = ChangePoll.change.bind()

    text = serializer.data["text"]  # Story argument.

    def on_create_review_failure():
        return Response ({"detail": "Bad review", "error_code": 123})

Strict reason check for Failure class.

  • Strict check of the reason name in the Failure result class
  • When substory injected or inherited, error protocol should expand to the superset of definitions.

Delegates.

For example, we are running story in the Celery task.

But this task was delayed from somewhere.

It may be a different story with its own execution path and context.

Showing this path and context in the called task can be really helpful to debug problems.

Should be supported by #38

This is leading into the concept of Delegates. Canvas is an example of the Delegate.

Generally speaking, we are trying to solve this problem:

result = story1()
story2(result) # fails without knowing anything about story1 context.

If this code was written in this below, it will be way more easy to debug.

d = Delegate(story2)
story1(d)
d() # Takes arguments from story1 context.

GraphQL mutations are perfect candidates for delegates.

They are executed sequentially one after another.

If mutation number 10 fails, we would like to see the execution path of the previous 9.

Parallel execution

As always, composition is a superior pattern & I'm glad that this feature was designed around it.

Delegates could be used to execute nested stories in parallel or concurrently.

Specific delegates implementation like stories-asyncio or stories-celery could run delegates any way they like.

The best part of that decision, all implementation specific details will be moved to the composition (Injector) step.

For example, stories-asyncio could execute nested stories using gather function. Outer story will be continue it's execution after it was suspended to execute delegate.

In comparison, stories-celery could execute nested stories using group part of chore canvas. Outer story will be head part of the same chore and will be scheduled as a separate task and will restore its state the same way nested stories did.

Distributed execution

State object store not only normalized values, but also it store initial data for each value. Usually, it is entity and a dictionary of its arguments.

In that case, stories-celery would serialize initial data as task argument.

Before delegate continue it's execution on another machine, contract will apply normalization and restore entity classes the same way it did in the first story.

That way we would use instances of our classes traveling over network without pickle.

Assert messages.

  • Raise StoryError instead of failed assert
  • Show the name of the substory in the validate_substory_arguments message, given context, and required arguments.
  • Show context variable error instead of the key error. Show available context variables.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.