This has come up more than once, and I think it would be a sweet feature in Cucumber. To implement it would involve making a change to gherkin[1], which is the library that parses your .feature files. Gherkin uses Ragel[2] to parse the files, so the change would be to alter this ragel code:
https://github.com/aslakhellesoy/gherkin/blob/master/ragel/lexer_common.rl.erb
So that it accepts either an inline table or a reference to a CSV file after the Examples: keyword.
Hacking on gherkin isn't entirely straightforward (see the readme), as it produces three versions (pure Ruby, C and Java) across all 40 spoken languages, but if you jump on #cucumber we could give you a hand getting up and running.
[1] https://github.com/aslakhellesoy/gherkin
[2] http://www.complang.org/ragel/
>
> --
> You received this message because you are subscribed to the Google Groups "Cukes" group.
> To post to this group, send email to cu...@googlegroups.com.
> To unsubscribe from this group, send email to cukes+un...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/cukes?hl=en.
>
cheers,
Matt
ma...@mattwynne.net
07974 430184
Whoah there! This doesn't need to be implemented in the Gherkin lexer.
If you place a URL or some other kind of identifier in the name of the
Examples section or in its description, Gherkin will gladly send that
straight on to Cucumber, where it can be retrieved, parsed and
inserted into the internal representation of the feature.
I spent some time myself on plugins for Cucumber that would allow
something like this, but gave up after a time because 1) it was
becoming very frustrating, and 2) realizing that having Cucumber read
streams of Gherkin-formatted text from STDIN was a more elegant
solution. I haven't had the time to implement #2, but I think it's a
better way to do this sort of thing.
$0.02
Mike
Don't you think it would be nice if either form surfaced out of Gherkin as a Table object though?
i.e.
Examples:
@foo/bar.csv
and
Examples:
| a | b |
| c | d |
Given /^I enter search <vehicle_id>, <start_date>, <end_date> criteria in "([^"]*)"$/ do |csv_file|File:
FasterCSV.foreach(File.dirname(__FILE__)+"/"+csv_file, {:headers => :first_row, :return_headers => true}) do |row|
puts "#{row["vehicle_id"]}: from #{row[1]} through #{row[2]}"
end
end
vehicle_id, start_date, end_dateOutput:
WAUBB1234, 11/15/10, 11/30/10
XZAUBB1234, 10/15/10, 11/01/10
jonsmac2-2:DART jon$ cucumber --tags @wip
Feature: Drive Search
As a user
I want to be able to search for drives by various properties
So that I can review the details of that drive...
Scenario: Search by multiple properties
vehicle_id: from start_date through end_date
WAUBB1234: from 11/15/10 through 11/30/10
XZAUBB1234: from 10/15/10 through 11/01/10
Given I enter search <vehicle_id>, <start_date>, <end_date> criteria in "drives.csv"
Searching
When I search
Drives found...
Then I should see the proper drives listed
jon blog: http://technicaldebt.com twitter: http://twitter.com/JonKernPA
Richard
I was at least partially confused about what was being proposed, so
let's see if I can't clear up some of that confusion. When I responded
I thought Gherkin already happily consumed an Examples section without
a table following it, or an Examples table with only a multiline
description, e.g.:
Examples: Blah
Here is the multiline description of examples
Turns out I was completely mistaken. That's not the case at all and
all you get is a lexing error. Seeing as how I like the ability to do
that so much that I implemented it in my head, I think modifying the
lexer to make this work is a wonderful idea! I'll give as much help as
I can to get this done.
The second lexer question is whether we're talking about adding
support for an include keyword or token into the language itself, or
just parsing the multiline description for it. I think the latter is
good enough for now. Adding something to the lexer is a real vote of
confidence that I don't think is warranted at the moment. This also
has shades of GivenScenario that I'm uncomfortable with.
This leaves where to assign the responsibility of parsing the
multiline description, fetching the CSV contents and turning that into
a Table of one kind or another. I think this belongs in Cucumber, at
least for the time being. Two reasons: 1) my impression is that it
would simply be easier to slap something into GherkinBuilder than to
do it even half-way well in Gherkin, and 2) Gherkin doesn't really do
any IO at the moment--it's remarkably shy about its environment--and I
think that's a *huge* plus. Having it grab the contents of a CSV is a
step in the wrong direction. I think a keyword indicating a hook or
callback of some sort might be a cool way to get around this--a way to
get Gherkin to relinquish control to whatever is calling it and then
resume later with updated input, but that will make the lexer
considerably more complex. It might be worth it, but it's a much
bigger job than inserting a CSV.
> If you feel confident, I'd just give it a crack, and we can see how it
> looks.
> As far as syntax, I think what you've suggested above looks fine. Bear in
> mind that each keyword in gherkin has space for a multiline description
> after it, so you could have...
> Examples: This is the example name
> This is the example's description
> and so it this
> because it can span over multiple lines.
> @file: my_values.csv
>
I don't think we should add this as an "official" part of the language
for the reasons mentioned above, but whatever is decided, I don't like
using @file because @ already means "tag", and this is not a tag.
There's no reason to overload our operators. If we do want some
special syntax I'd propose -> or a word like "include". Also, I think
we should use URLs to describe where something is. They're universal,
well understood, and supported everywhere. You would end up with
something like:
Examples: The Client Maintains these ones
-> file:///path/to/the.csv
or
Examples: Remotely Served
include(http://www.example.com/my_sweet_info.csv)
Hopefully this clarifies things from my end,
Mike
> cheers,
> Matt
> ma...@mattwynne.net
> 07974 430184
>
Also, would we need to put some kind of symbol in front of include,
like #include? If we just used a word, then I could see difficulties
parsing it or people getting confused and having the "include" end up
getting parsed as a multiline description.
Some other things to think of too...
- We would have to be able to parse file paths with spaces
- Would we want to support Windows file paths that use backslashes
instead of forward slashes? Lots of people are using cucumber on
Windows these days
- Would we support multiple #include directives in the same Examples section?
Jon
Hi Jon,
We can hash out all the syntax questions later. If this is ever going
to work, the first step is to make tableless Examples legal in
Gherkin. I've created a branch [0] that contains a pending spec in
spec/gherkin/shared/lexer_group.rb. If you can get that to pass, we'll
be on our way.
Mike
[0] https://github.com/msassak/gherkin/tree/tableless-examples
Sounds good, I'll take a look at your branch.
Jon
Mike, I don't mean to be a pain, but I would like to just re-iterate my preference for making this a change (or rather an extension) to the table syntax, rather than putting it into the name or description.
Right now, the name and description are all about human-readable stuff. We've recently made some changes so that the description can be in markdown format, but it doesn't have to be, and it's intended to be a free-text field.
What I'm suggesting is that change things so we can say: "there are two ways to declare a table in gherkin: you can either express it inline, using pipes, or you can reference an external place where the table data is to be read from".
As you say, the precise syntax isn't important right now, but I feel like this point is important. I feel like it would be a mistake to start putting machine-readable stuff into the name or description fields, but that it would be OK, in the specific case of a table, to just have two ways to define it.
So I'm not talking about a generic include mechanism - that's a lot more than we need here. I'm simply talking about an extension to the Gherkin language to allow you to declare a table whose data is read in from somewhere else.
Am I making sense?
I totally agree, that's what I had in mind too.
On 12/13/10 10:51 AM, Matt Wynne wrote:
> So I'm not talking about a generic include mechanism - that's a lot
> more than we need here. I'm simply talking about an extension to the
> Gherkin language to allow you to declare a table whose data is read
> in from somewhere else.
Perhaps something like this:
Scenario Outline: eating
Given there are <start> cucumbers
When I eat <eat> cucumbers
Then I should have <left> cucumbers
Examples in path/to/some/file
--
Dec. 14 - Agile Richmond in Glen Allen, VA
http://georgedinwiddie.eventbrite.com/
----------------------------------------------------------------------
* George Dinwiddie * http://blog.gdinwiddie.com
Software Development http://www.idiacomputing.com
Consultant and Coach http://www.agilemaryland.org
----------------------------------------------------------------------
> Agreeing with Matt...
>
> On 12/13/10 10:51 AM, Matt Wynne wrote:
>> So I'm not talking about a generic include mechanism - that's a lot
>> more than we need here. I'm simply talking about an extension to the
>> Gherkin language to allow you to declare a table whose data is read
>> in from somewhere else.
>
> Perhaps something like this:
>
> Scenario Outline: eating
> Given there are <start> cucumbers
> When I eat <eat> cucumbers
> Then I should have <left> cucumbers
>
> Examples in path/to/some/file
That's very nice and readable.
I still think it would be OK to have the same keyword, name and description as normal, but just instead of the inline table, have a reference to some external source, e.g.
Scenario Outline: eating
Given there are <start> cucumbers
When I eat <eat> cucumbers
Then I should have <left> cucumbers
Examples: Small Numbers of Cucumbers
These are just some simple examples:
| start | eat | left |
| 10 | 1 | 9 |
| 2 | 2 | 0 |
Examples: European Union Cucumber Quantities
These are the trade figures from 2009-2010.
|>> file://eu_figures.csv <<|
Here I've used two examples tables, one with an inline table, and one with an externally sourced table.
Even though the actual Gherkin source is a bit less readable than George's example, this still allows people to use the name and description for each table of examples, as they'll be familiar with, and the parsed Gherkin objects passed to Cucumber will have the same interfaces as before.
>
> --
> Dec. 14 - Agile Richmond in Glen Allen, VA
> http://georgedinwiddie.eventbrite.com/
> ----------------------------------------------------------------------
> * George Dinwiddie * http://blog.gdinwiddie.com
> Software Development http://www.idiacomputing.com
> Consultant and Coach http://www.agilemaryland.org
> ----------------------------------------------------------------------
>
Hi Matt,
I think defining conventions for multiline description formats is an
easy and effective way to prototype new behaviors without reaching too
deeply into Gherkin to make changes that we might not have the best
feel for, but that's a syntactical question, and it's far less
important to me than the question of how the loading and parsing of
CSVs will be implemented. Implementation, particularly the assignment
of responsibility, is 95% of my concern.
So for the sake of argument let's assume we settle on the syntax
above: |>> file://eu_figures.csv <<|. The lexer will not need to be
modified to lex the content of that cell. What class do you think
should be responsible for loading and parsing that CSV? My aim is to
keep that responsibility out of the lexer. I'm not convinced it should
live in Gherkin anywhere (as opposed to Cucumber), but I can see how
that might make sense. It's the Lexer "knowing" about CSVs that really
bothers me. I can't think of a sane way to implement that at the Lexer
level that doesn't involve significant changes to it.
Mike
I'm with you. So thinking about Aslak's idea of filters, can we imagine a layer of filters which Gherkin would throw that lexed single-cell table to, and allow the filter to transform it into another table, effectively expanding it by going and fetching the contents from somewhere and returning a new, populated Gherkin::Table?
That would mean we don't need to change the lexer, and we don't need to change Cucumber either, apart from perhaps configuring it to tell Gherkin to use the CsvTableExpander filter, which could be a totally independent library, or maybe come with gherkin.
WDYT?
I think I just opened my browser to write you an email along the lines
of "Wait a second I think I can write a filter in about twenty lines
of code." Heh. So, a filter it is. It would be nice if they were
configurable. :-)
cheers,Matt07974 430184
I thought of a pre-processor at first, but rejected the idea because
unless we're including gherkin source (a silly idea, I think), this
adds unnecessary translation and parsing steps to the process. The
external data would need to be retrieved, parsed in its native format,
converted into gherkin, then parsed by Gherkin and converted into a
series of events. The filter way allows you to synthesize gherkin
events from a native representation without needing to convert it to
gherkin first.
> Additionally an include directive could specify a translator in case the URL
> contains a MIME type that is not text/plain:
> #include file:foo.xls, xls2txt
> -where we could supply some simple converters ootb, and make it easy for
> people to write their own.
Why would we want to translate input for people? Seems easier to me to
just say, "Hey, if you point us at crap, everything will fail. Don't
point us at crap." The ability to insert a filter would side-step this
nicely. Sounds to me like a job for the much talked about but never
implemented stackable filters a la Rack API.
Mike
I think Aslak sent this before we came up with the filter idea. Assuming we're understanding each other correctly, Mike, it seems like a great genesis of our ideas.
The only concern is Tomáš' about the non-readability of it. I'm sure we can improve on the |>> file here <<| thing - it took me about 10 seconds to invent that.
#include:
1) retrieve CSV
2) parse CSV
3) convert to gherkin
4) parse gherkin
5) emit gherkin events
We'd have to do 1-3. 4-5 is already implemented.
> The filter way allows you to synthesize gherkin
> events from a native representation without needing to convert it to
> gherkin first.
>
filters:
1) parse gherkin
2) retrieve CSV
3) parse CSV
4) emit gherkin events
We'd have to do 2-4
Both approaches requires retrieving and parsing of CSV. They differ by
whether we turn the parsed CSV into gherkin text or emit events.
In terms of performance I suppose the #include approach would be a
little slower than the filter approach. However, I don't think the
overhead would be noticeable, so I don't think speed is a strong
argument here.
I think it's more important to compare how easy it will be to
implement either architecture. We could implement a CSV to gherkin
translator (as #source or as filter events) and bundle it with gherkin
or cucumber. However, I'm sure some people would want to use other
formats, such as Excel, Google Spreadsheets or some proprietary Wiki.
That means they'll have to implement their own translator.
Implementing a filter based translator requires knowledge of the
Gherkin API. Implementing an #include based translator only requires
knowledge of the output gherkin.
For this reason I'm leaning towards #include. It would also be useable
anywhere in a gherkin file, not only for tables. Who knows, maybe
somebody wants to suck in pystrings?
>> Additionally an include directive could specify a translator in case the URL
>> contains a MIME type that is not text/plain:
>> #include file:foo.xls, xls2txt
>> -where we could supply some simple converters ootb, and make it easy for
>> people to write their own.
>
> Why would we want to translate input for people? Seems easier to me to
> just say, "Hey, if you point us at crap, everything will fail.
I can imagine some people might want to use google docs or excel.
> Don't
> point us at crap." The ability to insert a filter would side-step this
> nicely. Sounds to me like a job for the much talked about but never
> implemented stackable filters a la Rack API.
>
The two approaches are not mutually exclusive - in theory we could
support both. I just think #include is simpler in this case...
Aslak
I agree they're not mutually exclusive, but I disagree about their
relative complexity and usefulness. :-)
If you're leaning toward #include though, why not side-step a lot of
the issues surrounding it (to start I think it's too hacky to be the
official way of doing this) and add a --stdin flag to Cucumber? Right
around the time I was getting really frustrated with the plugins I was
lucky to have a chat with Dan North about what I was working on, and
his suggestion was to forget about plugins entirely and just make it
easy to pipe content into Cucumber like this:
$ wget http://example.com/feature.html | html2gherkin | cucumber --stdin
I thought this was such a good idea I wrote something to split apart
features passed in via stdin and wired that up quick and dirty to a
--stdin flag in Cucumber, and it worked pretty darn great for a
night's work. Unfortunately I haven't had the time or inclination
since then to finish the job. I still have the feature scanner here
though: https://gist.github.com/460971. I'd do things a bit
differently now, but the core packs a wallop in very few lines of
code, in my opinion. This way we can easily let a thousand formats and
converters bloom, and if any of them prove to be indispensable, we can
fold the best stuff into Gherkin proper.
WDYT?
Mike
I think this sounds good in principle. Can you give me an example of how the OP will use it to get his CSV file into the Examples table?
$ my-csv-expander | cucumber --stdin
my-csv-expander could easily read in the features according to what
the OP would like and expand CSV references into Gherkin tables. To
process a subset of features he could filter on a tag and have
Cucumber run the others directly, or he could pass them through
unchanged. There's not going to be much of a speed difference either
way.
Best of all from my point of view is that we wouldn't need to decide
on an official way to do this. If the OP wanted to publish
my-csv-expander on Github and provide support for doing it his way, he
could without having to listen to all those loud mouths on the
Cucumber ML. ;-) If after a time my-csv-expander works so well
everyone who Cukes uses it, we can include it or the best parts of it
(and maybe include the best parts of some competing solutions) into
Cucumber/Gherkin proper. Like Rails does with plugins and what-not.
Named scope, nested attributes, and err... Merb were all developed
elsewhere but proved they were so good they should take their place
among the included batteries.
Gherkin then could have as one of its responsibilities making this
type of thing easy (with filter composer and builder APIs), but if
that never materializes, well so what? Munging streams of text by hand
is definitely the Bell Labs solution, but there are advantages to it
that MIT never dreamed of. I bet you could even do crazy stuff in
Windows PowerShell with this approach. :-)
Mike
I see. So my-csv-expander is a black box that reads the files in the features directory, looks for some placeholder in the .feature files and expands them into valid gherkin features, then spits them out of stdout?
This would work nicely for supporting George's syntax, I guess.
What does the OP think? Would you like this?
You're bringing up some good points Jon.
It looks like we have three directions that:
a) Can be used to solve the same problem of sucking in external content
b) Can be implemented independently without affecting the other
c) All have their value
I therefore propose we do them all. My suggestion:
* stdin: Mike, do it
* include: Aslak, do it
* filter: Matt, Mike or someone else, do it
Common for them all is that they require fairly little code, so I'm
not too worried about redundancy. I think they all have their own
merits.
One problem we have to be aware of with all solutions is line numbers.
As you all know, Cucumber reports gherkin files and line numbers, and
they still need to be correct. It would be unacceptable if cucumber
starts reporting incorrect line numbers and/or incorrect files. For
example, if an error happens in a file that came from a CSV, then the
error should point to that file, and (ideally) the right line within
it.
Aslak
I'm willing to do some of the work if someone can point me in the right direction.
Jon
I'm willing to do some of the work if someone can point me in the right direction.
Jon
On Dec 16, 2010 7:31 AM, "Matt Wynne" <ma...@mattwynne.net> wrote:
>
>
> On 14 Dec 2010, at 23:57, Jon Kruger wrote:
>
>> I'm willing to do some of the work if someone can point me in the right direction.
>>
>> Jon
>
> Good man! Which option would you prefer to work on?
I can do the filter option... are there any examples of filters in cucumber now?
Jon
Look in Gherkin. There are a few layers in there, and I'm not sure
where exactly Matt was thinking to put the filter in, but if you poke
around you should see how Gherkin works by composing classes that
send, receive and transform streams of events. Any filter will do
something very similar. I imagine we'll also need to modify the lexer,
unless we want to go with the special table cell syntax Matt used as
an example. I'm partial to using the multiline description to store
stuff like this, at least at first. It's a low-cost way to play around
with extensions to the core language and imposes few burdens on other
users of the library.
Mike
The big benefit as I see it is to make it easier for the business side
of the product team to contribute to the feature suite. One of the
major aims of Cucumber has always been for non-developers to
contribute to and write features on their own, but so far that's been
the exception to the rule. These additions address part of that
problem.
> Why can't we just delegate this to step definitions instead?
> This is based on the following ideas
> 1. Any table defined imperative feature can be expressed as a non-tabular
> declarative feature that encapsulates the table in a concept and can pass
> the processing of the table down to a step definition.
This is true in terms of computation, but it abstracts away from the
expressive possibilities of inline tables. Knowing when to inline a
table vs. when to encapsulate it in a step is something that every
team can decide on its own according to their own context and best
judgment. I see these additions in much the same light. These changes
will give product teams using Cucumber more choices for how they fit
it into their workflow. Right now Cucumber dictates more of a workflow
than it needs to, and for many teams a tool that makes you change your
workflow to fit the tool, rather than vice verse, is a flawed tool.
> 2. Any feature that needs to import a table into its examples will produce
> output that is unreadable by the business.
I don't think I understand your point. Can you elaborate on this? If
you pull in a CSV in the manner we're describing the pretty formatter
should inline the contents of that CSV, properly indented and
formatted, right into the output.
Mike
> All best
> Andrew
Mike
> All best
> Andrew
>
>
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Cukes" group.
> To post to this group, send email to cu...@googlegroups.com.
> To unsubscribe from this group, send email to
> cukes+un...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/cukes?hl=en.
>
--
You received this message because you are subscribed to the Google Groups "Cukes" group.
To post to this group, send email to cu...@googlegroups.com.
To unsubscribe from this group, send email to cukes+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cukes?hl=en.
--
You received this message because you are subscribed to the Google Groups "Cukes" group.
To post to this group, send email to cu...@googlegroups.com.
To unsubscribe from this group, send email to cukes+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cukes?hl=en.
On 18 Dec 2010, at 11:43, Andrew Premdas wrote:
> This is a real long thread that I've skipped through, and these questions might be a bit out of order, but anyhow here goes.
>
> What is the business benefit of doing this in cucumber?
>
> Why can't we just delegate this to step definitions instead?
>
> This is based on the following ideas
>
> 1. Any table defined imperative feature can be expressed as a non-tabular declarative feature that encapsulates the table in a concept and can pass the processing of the table down to a step definition.
I think you might not have noticed, but this thread is specifically about reading Scenario Outline Examples tables from an external file. If you have a bunch of different examples to pump through the same scenario (however declarative) I can see that it could be handy to store and edit those examples in a spreadsheet rather than a text file. We've been asked for it a few times, and it's something that other tools like Fit do really well, I believe.
> 2. Any feature that needs to import a table into its examples will produce output that is unreadable by the business.
Yeah there is a danger that you'd end up with e really wide table I suppose, but there doesn't seem too much harm in giving people enough rope to hang themselves with :)
>
> All best
>
> Andrew
Hi Andrew,
I think you might not have noticed, but this thread is specifically about reading Scenario Outline Examples tables from an external file. If you have a bunch of different examples to pump through the same scenario (however declarative) I can see that it could be handy to store and edit those examples in a spreadsheet rather than a text file. We've been asked for it a few times, and it's something that other tools like Fit do really well, I believe.
On 18 Dec 2010, at 11:43, Andrew Premdas wrote:
> This is a real long thread that I've skipped through, and these questions might be a bit out of order, but anyhow here goes.
>
> What is the business benefit of doing this in cucumber?
>
> Why can't we just delegate this to step definitions instead?
>
> This is based on the following ideas
>
> 1. Any table defined imperative feature can be expressed as a non-tabular declarative feature that encapsulates the table in a concept and can pass the processing of the table down to a step definition.
Yeah there is a danger that you'd end up with e really wide table I suppose, but there doesn't seem too much harm in giving people enough rope to hang themselves with :)
> 2. Any feature that needs to import a table into its examples will produce output that is unreadable by the business.
Are you assuming here that the main reason for storing a table
externally is that it's big?
-And by big, do you mean wide or tall?
I can think of at least one different reason than size: usability.
I know a bunch of people who'll happily edit a table in Excel, but
won't even go near a text editor.
Aslak
Yeah, I've seen that one a lot. Another reason is that the Excel table
already exists, and is actively maintained.
There's no one best way to reach satisfaction, and that makes our job
harder.
- George
--
----------------------------------------------------------------------
* George Dinwiddie * http://blog.gdinwiddie.com
Software Development http://www.idiacomputing.com
Consultant and Coach http://www.agilemaryland.org
----------------------------------------------------------------------
-And by big, do you mean wide or tall?
I can think of at least one different reason than size: usability.
I know a bunch of people who'll happily edit a table in Excel, but
won't even go near a text editor.
Here's an example: we want to make a spreadsheet (with help from the business) that says which roles are able to access a screen. Breaking that up into lots of individual step defs doesn't make sense (there's not much to say in each one), and if I create one step def that does all the work, then I lose the benefit of examples where it shows which ones pass and which ones fail.
Jon
Instead write
Given the products are loaded
When I check all the products
Then they should all have the correct descriptions
or
even
When I check all the products
Then there should be no product errors
You don't need cucumber to load a CSV and to loop. Cucumber is not
designed for this kind of stuff. However ruby is great at doing this,
so do the looping and loading in the step definitions. If you create a
module step helper you can do this no probs.
module ProductCheckHelper
def load_all_products
...
def visit_all_products
# produces a report
...
def report_product_errors
...
end
World(ProductCheckHelper)
implement the methods and call them from the appropriate steps and voila
HTH
Andrew
> --
> You received this message because you are subscribed to the Google Groups
> "Cukes" group.
> To post to this group, send email to cu...@googlegroups.com.
> To unsubscribe from this group, send email to
> cukes+un...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/cukes?hl=en.
--
------------------------
Andrew Premdas
blog.andrew.premdas.org
Scenario Outline:
When I do something with <x>
And I do something with <y>
Then the result should be <z>
Examples: import from messages if domain is "something"
| x | y | z |