This is the front-end version of the Love Geometry assignment, which you may solve and present your solution in order to [[showcase relevant expertise]] in the context of our [[join us#The Process|recruitment process]].
We consider [[Love Geometry (front-end version)#Step 1. The Language of Love and Destruction|Step 1]] and [[Love Geometry (front-end version)#Step 2. Show Me Your Love|Step 2]] to be the bare minimum required to assess your expertise. The rest of the steps are optional. While each step allows to showcase some valuable traits, it's ok not to complete all of them.
Please ensure to carefully read through the [[solve an assignment#Submission Requirements|submission requirements]] and the [[showcase relevant expertise#HOW to showcase?|entire process]] of presenting and discussing the solution to this assignment.
---
## Intro
>Explore [PEG](https://en.wikipedia.org/wiki/Parsing_expression_grammar) and build a rich UX around love stories.
Humans love [GUIs](https://en.wikipedia.org/wiki/Graphical_user_interface) - all those buttons, layouts, images, and charts make computers look a lot less alien. While the world is waiting impatiently for the emergence of natural language interfaces, this time around we shall focus on a plain, old, but powerful tool: [domain specific language](https://en.wikipedia.org/wiki/Domain-specific_language).
Let’s find a way to build an interface that combines the best of two worlds: DSLs and GUIs.
This assignment invites you to create a dummy universe, where people fall in love and become enemies. You’ll mix DSL and graphical interface to explore and express these relations.
## Step 0. Pick Your Tools
The solution should be built a single page web application. Feel free to use any framework.
### Note on navigation
All exercises can be implemented as an evolution of one main page. If you would complete a lot of optional exercises, you may consider to break down the application into several sections. In that case don't forget about navigation and routing.
### Note on UX
While this assignment is mainly aimed at testing your engineering skills, we do care about design and usability. We do not introduce any additional restrictions because we want to know what completeness and usability means to you.
### Get Ready for PEG
Take a look at [peggy.js](https://peggyjs.org/). It's a Javascript parser for [parsing expression grammars](https://www.wikiwand.com/en/Parsing_expression_grammar), which is very similar to context-free grammars (aka regular expressions).
You are free to use something else, if you so desire.
## Step 1. The Language of Love and Destruction
>Bob has a crush on Alice. Is it mutual? Get acquainted with our concepts of PEG, and build a parser for love stories to find out.
Imagine a dummy language, describing relationships among people:
```
A loves B but B hates A.
A hates B, A loves D while B loves C and D hates A.
A loves B, B loves A and B loves D.
A loves B but B hates A
D loves B and C loves A.
```
We’ve just described a love dynamics among people. Each sentence represents a state in an evolving story.
Note that there are **multiline** sentences (like the last one)!
Let’s say we wanted to write a parser for this language, returning, for each line, a structure for the relationships of the people in it, e.g.:
```js
[
{
'A': { 'loves': ['B'] },
'B': { 'hates': ['A'] }
},
{
'A': { 'hates': ['B'], 'loves': ['D'] },
'B': { 'loves': ['C'] },
'D': { 'hates': 'A' }
}
]
```
This table represents the first two lines of our story.
Without giving you a formal definition of this language, we want you to design a grammar articulate enough to encapsulate its spirit.
At this stage, we do not ask for any user interface. Instead, we want the parser to be implemented as a module, and covered by test cases.
You can use any testing framework you’d like. If you lack testing experience, Node.js has a built-in `assert` module which may just do the trick.
You should also provide a description for each of your test cases.
### Completion Checklist
- [ ] PEG parser for the love story language
- [ ] Parser unit tests
- [ ] `README.md` including installation and running manuals
### On the Meaning of Love
Let’s shed some light on the terms used throughout this assignment.
A _state of love_, the _love case,_ or the _situation of love,_ is the order of things described in one sentence. We can think of it as a snapshot of relationships.
A _love story_ is a sequence of love states.
## Step 2. Show Me Your Love
>Create an ecosystem for your language. Build an API server to parse love stories.
Now that you have a parser, let's build a single page application around your love stories engine.
In order to complete the assignment, please provide an input text area for a love story, and the text field with the corresponding JavaScript/JSON structure. These stories should be parsed automatically, every time we have text edits from any given user (what’s usually referred to as "live edit").
There should be a minimal error reporting in case a user enters invalid love statements.
If needed, you may use code highlights tools such as [Code Mirror](https://codemirror.net/). Here is an example of it being used in one [pet projects](http://takorogo.github.io/#/).
### Completion Checklist
- [ ] SPA for love stories
- [ ] A set of sample love stories
- [ ] `README.md` including details on how to start and use the app
This part of the assignment, together with [[Love Geometry (front-end version)#Step 1. The Language of Love and Destruction|Step 1]], is the minimum requirement for us to [[showcase relevant expertise|evaluate your expertise]].
### More Summits Ahead
We do have a few more challenges for you, if you feel like going :)
There’s a chance your solution might contain some errors. One never really knows! Completing additional steps will grant higher confidence in your results.
## Step 3. Find the Cheater (optional)
>Sometimes people don’t know what they want. Sometimes they lie. Love is divine and dangerous at the same time. Analyse love stories and find their contradictions.
Although this assignment is optional, it may come in handy at later stages. It may also give you some perspective on the design of your DSL.
With reference to [[Love Geometry (front-end version)#Step 1. The Language of Love and Destruction|Step 1]], the syntax does not stop us from writing things like:
```
A loves B but A hates B.
A loves B, A loves B, A loves B.
A loves A.
```
What are some of the additional constrains we should apply to the language semantics? Define those constrains, and describe them, either in the [`README.md`](http://readme.md/) or inside your SPA.
Implement a validator that checks parsed structures and reports error messages when a user writes a meaningless state of love. You could also enrich the grammar with some checks, but the parser should not swallow errors (e.g. if users do something you consider to be wrong, they should receive an error).
### **Completion Checklist**
- [ ] Implement semantic validation at the parser and application level
- [ ] Cover your rule checker with tests
- [ ] Make the parser run without checks if needed
- [ ] Show errors to the client
- [ ] Document your decisions
## Step 4. Circles of Affection (optional)
>Have you ever been a part of a love triangle? How about a love pentagon? A love polytope? Anyone? Try out some graph theory and find circles of affection in love stories.
Consider a state of love with the following circles of affection:
```
A loves B, B loves C and C loves A.
A hates B while B hates A.
A loves A.
```
In the first sentence we have a traditional love triangle, while the second describes mutual loathing.
The third sentence represents high self-esteem. Have you, by any chance, forbidden that kind of relations in [[Love Geometry (front-end version)#Step 3. Find the Cheater (optional)|Step 3]]? You may want to reconsider your decision. Or not. Up to you really.
In order to complete this exercise, you have to design and implement an algorithm that finds all circles of affection in a graph representing a given state of love.
We want you to create a block on the page where you will list such circles for the given love story (in addition to the area with listed structures from the [[Love Geometry (front-end version)#Step 2. Show Me Your Love|Step 2]]).
### Completion Checklist
- [ ] Implement the algorithm that searches for affection circles
- [ ] Cover the algorithm with tests
- [ ] Add a page or a component that renders a list of circles
## Step 5. The Matrix of Love (optional)
>It’s time to talk about relationships. The mathematical ones, the ones that govern the relational databases. Transform your love stories into tables.
Let’s consider the following situation:
```
Lyubomyr loves Ron, Ron hates Lyubomyr
Vasyl hates Alice, Alice hates Vasyl
Ulices loves Alice, Alice loves Ulices
Mary loves Vasyl
Ulises hates Theodoric.
```
For this instance, the corresponding table would look like the following:
| | Ron | Alice | Mary | Theodoric |
|---------|-------|-------|-------|-----------|
| Vasyl | | - | ?/+ | |
| Lyubomyr | +/- | | | -/? |
| Ulises | | + | | |
The table is good, but the textual description is not elegant.
If we add a special keyword to describe mutual affection, the description becomes:
```
Lyubomyr loves Ron, Ron hates Lubomyr
Vasyl mutually hates Alice
Ulices mutually loves Alice
Mary loves Vasyl
Ulises hates Theodoric.
```
Much better!
To complete this assignment, create a component that renders a table like the one above, but following our newer version of the state of love.
Keep in mind that our page might contain multiple tables, depending on the number of love states of any given love story.
To earn all of the available credits, you will also have to introduce the `mutually` keyword to the love language parser.
### The Love Matrix Behaviour
To clarify how the table should work, let's look at some examples.
Say we added, in addition to the existing text, the following:
```
...
Ulises mutually loves Mike
...
```
That means we have to add a new column, e.g.:
| | Ron | Alice | Mary | Theodoric | Mike |
|---------|-----|-------|------|-----------|------|
| Vasyl | | - | ?/+ | | |
| Lyubomyr | +/- | | | -/? | |
| Ulises | | + | | | + |
Now, if we will strip away `Mary loves Vasyl` from the text, we will get:
```
Lyubomyr loves Ron, Ron hates Lyubomyr
Vasyl mutually hates Alice
Ulices mutually loves Alice
Ulises mutually loves Mike
Ulises hates Theodoric.
```
“Mary” disappears, and the corresponding column is removed from the table:
| | Ron | Alice | Theodoric | Mike |
| -------- | --- | ----- | --------- | ---- |
| Vasya | | - | | |
| Lyubomir | +/- | | -/? | |
| Ulises | | + | | + |
### Completion Checklist
- [ ] Create an additional page or component that renders the table related to the representation of love stories
- [ ] Cover your graph-table converter service with tests
- [ ] Render love representation tables for a submitted story
- [ ] Document your solution in the `README.md`
- [ ] (for the super bonus points!) Add the `mutual` keyword to the love story language
## Step 6. The End of Love (optional)
>Even the most exciting adventures come to an end. As a farewell to your dummy universe, cover it with end-to-end tests.
Write end-to-end tests for all the completed steps.
This exercise is not only about on the number of test cases, but also about their completeness.
You can use any testing solution you prefer. The tests should run on any reasonable environment and you should include installation manuals for all the used tools.
### Completion Checklist
- [ ] E2E tests for the cases of your choice
- [ ] Document how to run your tests in the `README.md`.
---
Than you for getting here 🙃
Please ensure to carefully read through the [[solve an assignment#Submission Requirements|submission requirements]] and the [[showcase relevant expertise#HOW to showcase?|entire process]] of presenting and discussing the solution to this assignment. Looking forward to the next step 🙌