GithubHelp home page GithubHelp logo

feynman's People

Contributors

16sheep avatar jbpros avatar mattwynne avatar romaingweb avatar tooky avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

jdrew1303

feynman's Issues

Default `Task` argument names to []

This will avoid the noise when defining namespaces around tasks, like:

const CreateProject = Task('CreateProject', [], Task => Task('named', ['projectName']))

and instead you can just write

const CreateProject = Task('CreateProject', Task => Task('named', ['projectName']))

I know this is going to result in fiddly code that counts argument numbers but for readability of client code I think it's worth it.

Add tasks to exchange information between actors

We are currently using this in Cucumber Pro:

const tell = ({ listener, tellerItem, listenerItem }) => async ({
    actor,
  }) => {
    listenerItem = listenerItem || tellerItem
    const value = await actor.asks(Recall.about(tellerItem))
    await listener.attemptsTo(Remember.that(listenerItem).is(value))
  }
  handle(Tell.about, tell)
  handle(Tell.about.as, tell)

Allow for both a handler and nested interactions on a single interaction node

Consider the following:

interactions({
  ProjectInfoAboutProject: { named: (projectName) => { /* handler stuff */ } }
}) 

Say we also want a sub-interaction like this:

ProjectInfoAboutProject.named(projectName).hasCollaboratorNamed('Joe')

Is not feasible at the moment. It'd be good to have a similar API to tasks:

interactions({
  ProjectInfoAboutProject: { 
    named: interaction('projectName', ({ projectName }) => /* handler stuff */, { 
      hasCollaboratorNamed: interaction(
        'collaboratorName', 
        ({ projectName, collaboratorName }) => /* sub-handler */
      )
    })  
  }
}) 

Remember questions as well as concrete values

It should be possible to pass a question to the Remember.that action so as to avoid this sort of code:

Remember.that('my name').is(await actor.asks(WhatIsMyName))

and instead just be able to write:

Remember.that('my name').is(WhatIsMyName)

Add logging

@jbpros I wanted to start a conversation about logging.

I've been thinking we could configure a logger like this:

const { configure } = require('feynman')
configure(config => config.logger = console)

Then we should be able to see task descriptions coming out:

Given a user named Dave with email '[email protected]'
  Actor dave:
    Create a user named 'dave' with email '[email protected]'

Now that leaves us with how to log the bare (inter)action functions.

If you imagine defining an action like SignUp that then uses some browser interactions, it might look like this at the moment:

const SignUp = (
  as: name => ({ actor }) => 
    actor.attemptsTo(Follow.link("Sign up"), FillIn.fieldLabelled("Username").with(name))
}

We won't be able to log any of these, because (as far as I understand it) we can't ask the action function what the names of the wrapping functions / constants were that it was created by.

But we also want to keep the mechanism of defining these actions super lightweight, because the whole essence of this pattern, as I see it, is having lots and lots of these small compose-able actions, so we want to have minimal overhead on making new ones.

So could we make it possible to do this?

const { SignUp } = actions({ SignUp: ({
  as: name => ({ actor }) => 
    actor.attemptsTo(Follow.link("Sign up"), FillIn.fieldLabelled("Username").with(name))
  })
})

The actions method would return a proxy that decorated the action function with a description built from the calls that had been made through the proxy to access the builder functions. That way we'd then be able to log it nicely, and we'd minimise the barrier to building new actions.

WDYT? Am I making sense?

Declare code that only runs when a perspective is the default

e.g. we have this code for our "web" perspective:

let pool, server
Before(async function() {
  pool = new BrowserPool()
  abilities({
    createBrowser: pool.take.bind(pool),
  })
  server = abilities.server
  await server.start(webappHttpPort())
})

After(() => pool.closeAllBrowsers())
After(() => server.stop())

What we want is to be able to wrap that in something that only runs it when the web perspective is the default.

e.g.

perspective("web", { whenDefault: () => {
  let pool, server
  Before(async function() {
    pool = new BrowserPool()
    abilities({
      createBrowser: pool.take.bind(pool),
    })
    server = abilities.server
    await server.start(webappHttpPort())
  })
  
  After(() => pool.closeAllBrowsers())
  After(() => server.stop())
}})

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.