Is there a way to escape a keyword in a Gherkin feature or scenario description? - gherkin

In Gherkin, you can have free-form text that describes a scenario, a feature, etc. These descriptions are not used by, say, a test runner, but are for you to describe important additional information to another human.
The documentation for Gherkin says that these cannot start a line with one of the other keywords, such as Given, When or Then. Yet, sometimes the best description I could give would be to start with one of these keywords.
I'm sort of making this up as I go here, but here is an example of what I wish I could do:
Scenario: Many notifications at the same time get combined
When we have a lot of notifications being posted at once, it causes problems
for humans. They can't make sense of that much new information all at once.
So if we are ever in a situation where we are posting lots of
notifications in a short time period, we will take the one with the highest
severity and show it with the other notifications as "child" notifications,
accessible via a link that says, "And N other issues."
Given a notification posted today at 11:03:25
And a notification posted today at 11:03:26
And a notification posted today at 11:03:26
And a notification posted today at 11:03:27
When a notification is posted at 11:03.28
Then the notification list will contain 1 notification
And that notification should contain 4 child notifications
The problem I have is that because my description starts with a When, it the tools assume that I've started my specific steps, and blows up on the next line, which doesn't start with a keyword.
I've considered:
Commenting out the first line or the entire description (that seems more consistent to me) but to me, there is a semantic difference between a comment with # and a description.
Rewording the thing to not start with a "When". For example, if it started with, "In times where we have a lot of notifications..." but that's less readable, which is the point with Gherkin-style specifications.
If it wasn't the first word in the whole description, I might be able to get away with simply wrapping my lines differently so that the "When" starts in the middle of a line instead of the beginning, but in this case, I don't have that option.
Those options just seem like workarounds that feel sub-optimal.
Is there a way to "escape" these keywords to tell the system that some usage of "When" is really still just part of the description and not a keyword? If not, is there some sort of accepted best practice or guideline for how people should handle situations like this?

You could use # in the beginning of the line (it's used for writing comments).
Ex:
# When a notification is posted...

You are misinterpretting the the language spec. You can describe a feature and use keywords at the beginning of a line. The example you posted gets interpreted as steps in a scenario since the description appears after the scenario keyword.
Just as Mr Cas said in his answer, you need comments.
Feature: Given a feature title
When I use keywords up here
Then it is allowed
Scenario: When I use keywords after the title to describe a scenario
# Then I need to use comments

Related

Naming conventions for intents, events and contexts

I am wondering if there are any agreed upon naming conventions for intents, events and contexts in Dialogflow.
If there are none, then I would appreciate if you shared your own naming conventions!
I find that it's a bit of a contradiction to say 'it doesn’t really matter as long as it‘s easy to understand for others'. If there were naming conventions, it would be much easier for someone to understand a new Dialogflow bot.
Here's my take:
Intents
I use dots to group intents and imply a hierarchy. The first part of the intent name is ideally just one word that clearly indicates the main subject of the intent. For example
name would be an intent that receives a user's name as an input. name.confirm would be the follow-up intent that receives confirmation of the name. name.confirm.yes would be the intent where the user has given confirmation.
This is in the context of a bot which is gathering contact data so the input function is implied. In a more mixed-type chatbot, you could add the type of intent as a first word to categorize your intents better. E.g. input.name.confirm.yes or FAQ.shipping.overseas or smalltalk.agent.location ('Where are you?').
I use the same approach for fallback intents: fallback.name would be the fallback intent that is triggered when the bot is waiting for the user to input their name but doesn't understand the answer.
Contexts
For contexts I use snake case. For example awaiting_email would be the context that is set when the bot is waiting for the user to input their email address. After I have the email address I would set a context email to carry forward the information so that other intents can use it as a context. Or if I'm collecting several pieces of data about the user, I will set the context user and other intents can access certain parameters e.g. via user.email.
I made a video about the topic as well: https://youtu.be/kgKuS2RJcy4
It's obvious that everyone is coming from a slightly different angle because their area of application is different. I'm sure we'll get to a common standard eventually!
I am going to answer this from perspective of a service based company's project.
In my project, we have used similar naming convention for intents as in-built small-talk intents, because its easy to understand and categorize. like FAQ.Comapny.your_question, Buy.Drinks.coffee etc.
(for some unknown reasons we capitalize the first letter of main categories of intents, in small-talk all letters are lower case as it should be).
For the events we have used similar notation for universal constants, like INVOKE_EVENT.
For parameters and contexts, we used snake_case i.e coffee_cost.
Basically, it doesn't really matter as long as it's easy to understand and replicate. But you should always have a basic structure which you and your whole team follows throughout the project.
There aren't any, unfortunately, and the system is flexible enough that it doesn't matter too much. Pick names that make sense (duh).
Although most of the examples use it, I avoid using a space in the name. I treat them more like function names, so having a space in it breaks my aesthetics.
I tend to group Intents based around what part of the conversation they're working on, which is managed through the use of contexts that are set, and separate the part and subpart designations by dots, so it vaguely looks like package designations. I'll have Intents named something like
calculate.fallback
calculate.number
calculate.operation
fallback
welcome
Where the "calculate" ones all have an Input Context of "calculate".
Most of all, remember that Intents (and thus their names) represent what the user says and not what your code does with that. This is the big way that it differs from a function name.
Honestly, it really doesnt matter! As long as its easy to replicate in code and clear to see/understand for anyone else that might be working on your agent, then anything is fine. Generally though using typical coding notation such as CamelCase is probably not a bad idea.

phpBB3: is there any way to restrict visibility at the topic level?

My BB has an "archives" forum. I want to write a mod that will make it so that, if a topic is in the archives, then it can be viewed only by users who joined before the topic was posted. Is this feasible?
Yes it is feasible. Using the Topics Only Visible to OP mod, you even have a fairly close approximation of what you need to happen functionality wise.
From this mod, a few things would need to change
The viewtopic.php instructions would need to account for post creation date and user creation date instead of being for the original poster
The viewforum.php instructions would need to account for first post creation and user creation date instead of being for the original poster
After look through the installation instructions and changes you'd need to make, it seems those are the two biggest changes required. The ACP changes appear to be more wording, and the variable names could probably be slightly more appropriate since your mod won't be about only the OP seeing the post.

NSSpeechRecognizer with wildcard command elements

The docs for NSSpeechRecognizer state that complex, multi-step actions can be executed from single spoken commands, such as:
“schedule a meeting with Adam and John tomorrow at ten o’clock.”
I'm able to execute simple commands which are preprogrammed, but I don't see how the above could be interpreted using the class. It seems like
“schedule a * with * *”
should be a command. Any idea if something like this is possible? Or are we just supposed to pass an infinite number of possible commands to the recognizer?
It does not appear to me from the NSSpeechRecognizer documentation that it will support using complex phrases like the example you have given. To get the semantic meaning from a phrase like this you would use a system that supports multislot grammars like most IVR systems that support the VoiceXML standard. It looks to me that this speech recognition API only supports passing in simple commands as an array and not specifying complex grammar rules. With this type of system you would have to implement what is called a directed dialog, which might go something like this:
C: What would you like to do?
U: Schedule a meeting.
C: Tell me the first person that you would like to attend?
U: Adam.
C: Tell me the next person that will attend or say "done" if the attendee list is complete.
U: John.
C: Tell me the next person that will attend or say "done" if the attendee list is complete.
U: Done.
C: What day is this meeting?
U: Tomorrow.
C: What time is the meeting?
U: Ten O'Clock.
C: Thank you. Your meeting has been scheduled.
Using a directed dialog you can restrict the expected commands/utterances to a much more defined list. Although your list of possible names could be quite large unless you cull them from a users contact list.
My interpretation of the docs is that you would need to accumulate and operate on any compound state on your own. You provide NSSpeechRecognizer with a set of discrete words/phrases that it should recognize as 'commands', and it reports to you when it has recognized them.
For the example you've given, I think you'll run into problems when you get to the "Adam and John" part -- it's not an arbitrary dictation engine. But, for fun, let's try to imagine how we might do this:
You might tell it you want to recognize the following phrases as 'commands':
"schedule a"
"meeting" (and perhaps "appointment", "playdate", etc)
"with"
"Adam and John"
"tomorrow" (and probably other related things like "today", "two days from now", all the days of the week, etc)
"ten o'clock"
As words/phrases are recognized, you could create a stack of semantically related words/phrases based on previously recognized words/phrases. So, for instance, it recognizes the "schedule a" phrase, and you know that there should be more info coming to fill out the semantic context, so you push that phrase onto the stack. Next, it recognizes "meeting". Your app says 'sure, a meeting is something that can be scheduled' and pushes it onto the stack as well. If the next word it recognized wasn't germane to the previously-recognized "schedule a" command, then it would clear the stack. If, at any point, the elements on the stack satisfy some pre-defined criteria for a fully formed expression of semantic intent, then your app can take the appropriate action based on that intent. There's obviously a temporal element to this as well. If the next thing required to establish semantic context doesn't arrive in a reasonable amount of time, the semantic context stack should get cleared.
A similar system, conceptually, is the iOS/MacOS touch/trackpad gesture recognition system. When a tap touch happens, the OS has to recognize the single tap, and acknowledge the possibility that that is the entire user intent, but it also has to manage the possibility that it might receive another tap very shortly, turning the single tap into a double tap. It will have to accumulate this state over time, and infer the user intent by looking at the combination of discrete events.
You're not going to get such functionality from NSSpeechRecognizer for free, and being that it's not a dictation engine, you also won't get arbitrary 'tokens' from it (like "Adam and John", assuming you're not registering some giant list of names all as potential commands.) Even so, that doesn't mean it couldn't be leveraged to do some pretty neat stuff using a mechanism like I described. It's just that you're gonna have to write it yourself.
Good luck!

Source core repositories and sticky notes

An interesting problem occured recently, and I've been thinking of the "best" way (for a given value of "best") to implement this.
In essence, it's one of tracking notes against source code. The example that flagged this was getting a problem fixed in live within SLAs, and how to best achieve this. Without going into all the details, it came down to finding a function that's used in a number of places which may or may not be buggy, yet the problem was being reporting only in a single location.
The fix to meet the SLAs was simply to add a check into the location where the problem was reported, rather than tweaking the common code and having to test everything that touches that function.
The interesting issue is then for upstreaming. The "correct" method would then be to go back and check the original function, validate it's correct for everywhere it's called and then make the change "properly" if its determined the library function is wrong.
The problem is this takes time, so upstreaming may simply take the workaround, etc. However if the problem occurs again (say six months later) in another location calling the same library function, there isn't an easy way to link the two problems together. You can search the bug tracking database, but this isn't guranteed to help - it depends if a note's been added saying something along the lines of "this library function needs more thorough checking, but no time to investigate now".
So the question is this: within a large team of developers (30 plus, split into teams of both support and on-going development), what methods do you use to manage (what are effectively) "sticky notes" against source code, short of adding a comment to the suspicious function's source code saying "this might be a bit dodgy"?
The problem with the commiting a comment is one of process: a change is a change, so committing a zero-change change (i.e., one where just comments are added) is not ideal; developers can make mistakes even adding a comment (hit a stray key or something) so it's always (IMO) better to commit only where actual changes are made.
Now a wiki could be used to track per-file notes, but we've got a minimum of four branches and inexcess of a few hundred files (SQL objects, source code, XML files, etc), so a wiki will get unmangable quite quickly.
This is the sort of thing that it would be nice if SCM's could support - bits of metadata against files that are simply notes, but don't add to the SCM's version history - that can be displayed when doing (say) an svn update, or manually viewed.
There may already be solutions out there -- so how do you manage this type of knowledge sharing?
Well we're now using this method: in each folder checked into SVN, we've created a .url shortcut (this is Windows we're dev'ing on) that links to a page on our development wiki about that folder. Thus we can update the Wiki info freely, and on checkout/update everyone gets a link that will take them to the appropriate Wiki page for that folder/module.
We've not long instigated it so we'll have to see how well it works long term -- but it's better than what we had before (i.e., nothing :-) ).

Good Use Cases of Comments

I've always hated comments that fill half the screen with asterisks just to tell you that the function returns a string, I never read those comments.
However, I do read comments that describe why something is done and how it's done (usually the single line comments in the code); those come in really handy when trying to understand someone else's code.
But when it comes to writing comments, I don't write that, rather, I use comments only when writing algorithms in programming contests, I'd think of how the algorithm will do what it does then I'd write each one in a comment, then write the code that corresponds to that comment.
An example would be:
//loop though all the names from n to j - 1
Other than that I can't imagine why anyone would waste valuable time writing comments when he could be writing code.
Am I right or wrong? Am I missing something? What other good use cases of comments am I not aware of?
Comments should express why you are doing something not what you are doing
It's an old adage, but a good metric to use is:
Comment why you're doing something, not how you're doing it.
Saying "loop through all the names from n to j-1" should be immediately clear to even a novice programmer from the code alone. Giving the reason why you're doing that can help with readability.
If you use something like Doxygen, you can fully document your return types, arguments, etc. and generate a nice "source code manual." I often do this for clients so that the team that inherits my code isn't entirely lost (or forced to review every header).
Documentation blocks are often overdone, especially is strongly typed languages. It makes a lot more sense to be verbose with something like Python or PHP than C++ or Java. That said, it's still nice to do for methods & members that aren't self explanatory (not named update, for instance).
I've been saved many hours of thinking, simply by commenting what I'd want to tell myself if I were reading my code for the first time. More narrative and less observation. Comments should not only help others, but yourself as well... especially if you haven't touched it in five years. I have some ten year old Perl that I wrote and I still don't know what it does anymore.
Something very dirty, that I've done in PHP & Python, is use reflection to retrieve comment blocks and label elements in the user interface. It's a use case, albeit nasty.
If using a bug tracker, I'll also drop the bug ID near my changes, so that I have a reference back to the tracker. This is in addition to a brief description of the change (inline change logs).
I also violate the "only comment why not what" rule when I'm doing something that my colleagues rarely see... or when subtlety is important. For instance:
for (int i = 50; i--; ) cout << i; // looping from 49..0 in reverse
for (int i = 50; --i; ) cout << i; // looping from 49..1 in reverse
I use comments in the following situations:
High-level API documentation comments, i.e. what is this class or function for?
Commenting the "why".
A short, high-level summary of what a much longer block of code does. The key word here is summary. If someone wants more detail, the code should be clear enough that they can get it from the code. The point here is to make it easy for someone browsing the code to figure out where some piece of logic is without having to wade through the details of how it's performed. Ideally these cases should be factored out into separate functions instead, but sometimes it's just not do-able because the function would have 15 parameters and/or not be nameable.
Pointing out subtleties that are visible from reading the code if you're really paying attention, but don't stand out as much as they should given their importance.
When I have a good reason why I need to do something in a hackish way (performance, etc.) and can't write the code more clearly instead of using a comment.
Comment everything that you think is not straightforward and you won't be able to understand the next time you see your code.
It's not a bad idea to record what you think your code should be achieving (especially if the code is non-intuitive, if you want to keep comments down to a minimum) so that someone reading it a later date, has an easier time when debugging/bugfixing. Although one of the most frustrating things to encounter in reading someone else's code is cases where the code has been updated, but not the comments....
I've always hated comments that fill half the screen with asterisks just to tell you that the function returns a string, I never read those comments.
Some comments in that vein, not usually with formatting that extreme, actually exist to help tools like JavaDoc and Doxygen generate documentation for your code. This, I think, is a good form of comment, because it has both a human- and machine-readable format for documentation (so the machine can translate it to other, more useful formats like HTML), puts the documentation close to the code that it documents (so that if the code changes, the documentation is more likely to be updated to reflect these changes), and generally gives a good (and immediate) explanation to someone new to a large codebase of why a particular function exists.
Otherwise, I agree with everything else that's been stated. Comment why, and only comment when it's not obvious. Other than Doxygen comments, my code generally has very few comments.
Another type of comment that is generally useless is:
// Commented out by Lumpy Cheetosian on 1/17/2009
...uh, OK, the source control system would have told me that. What it won't tell me is WHY Lumpy commented out this seemingly necessary piece of code. Since Lumpy is located in Elbonia, I won't be able to find out until Monday when they all return from the Snerkrumph holiday festival.
Consider your audience, and keep the noise level down. If your comments include too much irrelevant crap, developers will just ignore them in practice.
BTW: Javadoc (or Doxygen, or equiv.) is a Good Thing(tm), IMHO.
I also use comments to document where a specific requirement came from. That way the developer later can look at the requirement that caused the code to be like it was and, if the new requirement conflicts with the other requirment get that resolved before breaking an existing process. Where I work requirments can often come from different groups of people who may not be aware of other requirements then system must meet. We also get frequently asked why we are doing a certain thing a certain way for a particular client and it helps to be able to research to know what requests in our tracking system caused the code to be the way it is. This can also be done on saving the code in the source contol system, but I consider those notes to be comments as well.
Reminds me of
Real programmers don't write documentation
I wrote this comment a while ago, and it's saved me hours since:
// NOTE: the close-bracket above is NOT the class Items.
// There are multiple classes in this file.
// I've already wasted lots of time wondering,
// "why does this new method I added at the end of the class not exist?".