Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EDL: Expectation Definition Language #241

Merged
merged 52 commits into from
Jun 24, 2019
Merged

Conversation

flbulgarelli
Copy link
Member

@flbulgarelli flbulgarelli commented May 5, 2019

This PR provides the ability to mulang to parse more complex inspections using a more human-like language, and provides a new easier to handle expectations internally.

It looks like it is also easy to generate a syntax highlighter for this language with code mirror:

Screenshot (19)

Depends on #238

Pending Tasks:

  • Document the language
  • Provide a syntax highlighter
  • Support comments
  • Support anything matcher: returns with anything, calls with (0, anything)
  • Support nonliteral and literal matchers

@ghost ghost assigned flbulgarelli May 5, 2019
@ghost ghost added the pending-review label May 5, 2019
@flbulgarelli
Copy link
Member Author

flbulgarelli commented May 5, 2019

Here is a very - contrived - example that shows its full power:

intransitively
within program
calls `foo` 
  with self 
  and with `bar`
  and with logic
  and with self
  and with something that (not declares something like `baz`)
  and with something that (declares send something distinct from `foobar` at least 4 times)
  and with something that (returns with math)
at most 2 times

🆙 2019-06-03:

This is the updated syntax:

expectation "must call something":
  calls;

expectation "must call something":
  %% exactly the same as previous example
  calls something;

expectation "assignment operator must be used":
  assigns;

expectation "a class must be declared":
  ! declares class;
  
expectation "`System` must be used":
  uses `System`;

expectation "`exit` must be called":
  calls `exit`;
  
%% matches things like `amount`, `totalAmount` or `amountOfHouses`
expectation "assignment a variable similar to `amount`":
  assigns something like `amount`;

expectation "must declare something aside of `Pet`":
  declares something distinct of `Pet`;

expectation "must declare a class aside of `Dog`":
  declares class distinct of `Dog`;

expectation "must declare `feed` or `bark`":
  declares method in (`feed`, `bark`);

expectation "must call `feed` or `bark`":
  %% Notice: calls in (`feed`, `bark`) also works
  %% something is there just to make things more explicit
  calls something in (`feed`, `bark`);

 %% negation

expectation "must not call anything":
  ! calls;

expectation "must not call anything":
  %% exactly the same as previous example
  ! calls something;

%% or

expectation "must declare a class, enum or interface named `Pet`":
  declares enumeration `Pet` || declares class `Pet` || declares interface `Pet`;

%% and

expectation "must declare `Owner` and `Pet`":
  %% however in most cases, it is better to declare two different, separate
  %% expectations
  declares `Owner` && declares `Pet`;
  
expectation "`HouseBuilder` must raise something":
  %% this will work if within the lexical scope of
  %% HouseBuilder a raise statement is used
  within `HouseBuilder` raises something;

expectation "`HouseBuilder` must raise something":
  %% this will work if within the lexical scope of
  %% HouseBuilder a raise statement is used, or if any code outside
  %% the lexical scope of HouseBuilder raises an excepcion
  through `HouseBuilder` raises something;

expectation "`HouseBuilder.builder` must create a new `House`":
  within `HouseBuilder.builder` instantiates `House`;

expectation "`exit` must be called with value 0":
  calls `exit` with 0;

expectation "`tell` must be called with value 10 and true":
  calls `tell` with (10, true);

expectation "`tell` must be called with 10 as its first argument":
  calls `tell` with (10, anything);

expectation "`play` must be called with this":
  calls `play` with self;

expectation "`startEngine` must be declared in `Train` or `Motorman`": 
  (within `Train` declares method like `startEngine`) or (within `Motorman` declares method like `startEngine`);
  
expectation "must perform at least three calls":
  count(calls) >= 3;

expectation "must declare three instances of `Tax`":
  count(inherits `Tax`) = 3;

expectation "must declare three subclases of `Tax` and two subclases of `Product`":
  count(inherits `Tax`) = 3 && count(inherits `Product`) = 2;

expectation "must declare no more than 4 methods in class `Queue`":
  within `Queue` count(declares method) <= 4;

flbulgarelli added a commit to flbulgarelli/explang that referenced this pull request May 5, 2019
Code extracted from mumuki/mulang#241
@flbulgarelli flbulgarelli force-pushed the experiment-explang branch from 564dc48 to 3822a5a Compare May 5, 2019 22:15
@flbulgarelli flbulgarelli changed the title Experiment explang EDL: Expectation Definition Language Jun 3, 2019
@flbulgarelli
Copy link
Member Author

Some more new screenshots:

Screenshot (20)

@flbulgarelli flbulgarelli marked this pull request as ready for review June 3, 2019 16:20
@flbulgarelli
Copy link
Member Author

Copy link
Member

@julian-berbel julian-berbel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely 😍
Just gonna fix some typos in docs

@flbulgarelli
Copy link
Member Author

Document the language

I think this is not done but good enough. Also, we should place those doc on top of #207

@flbulgarelli flbulgarelli merged commit 956f888 into master Jun 24, 2019
@julian-berbel julian-berbel deleted the experiment-explang branch July 1, 2019 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants